diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h index 874b15a4d25e809c33454429269a9e7dd0ca1091..8770d1b851ed929e06e3cddd3ca0907946cfc867 100644 --- a/Common/GmshDefines.h +++ b/Common/GmshDefines.h @@ -198,7 +198,12 @@ // Additional types #define MSH_PYR_1 132 -#define MSH_NUM_TYPE 132 +#define MSH_PNT_SUB 133 +#define MSH_LIN_SUB 134 +#define MSH_TRI_SUB 135 +#define MSH_TET_SUB 136 + +#define MSH_NUM_TYPE 136 // Geometric entities #define ENT_NONE 0 diff --git a/Geo/CMakeLists.txt b/Geo/CMakeLists.txt index 17466e538b478fe9b6692012ab3ae94ce84100b8..275e064e0d6e4b528339ee6e99486789eba426d1 100644 --- a/Geo/CMakeLists.txt +++ b/Geo/CMakeLists.txt @@ -39,7 +39,7 @@ set(SRC MFace.cpp MElement.cpp MElementOctree.cpp MLine.cpp MTriangle.cpp MQuadrangle.cpp MTetrahedron.cpp - MHexahedron.cpp MPrism.cpp MPyramid.cpp MElementCut.cpp + MHexahedron.cpp MPrism.cpp MPyramid.cpp MElementCut.cpp MSubElement.cpp MZone.cpp MZoneBoundary.cpp Cell.cpp CellComplex.cpp ChainComplex.cpp Homology.cpp Chain.cpp Curvature.cpp diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp index a66072fa4cd23fc9a4b86c789994b4a2dd91f6ea..3ba8a89fdc2b6bc84fb24af6c65491ea86db368b 100644 --- a/Geo/GModelIO_Mesh.cpp +++ b/Geo/GModelIO_Mesh.cpp @@ -816,41 +816,61 @@ static int getNumElementsMSH(GModel *m, bool saveAll, int saveSinglePartition) int n = 0; for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); ++it) + { n += getNumElementsMSH(*it, saveAll, saveSinglePartition); - for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it){ + if(!CTX::instance()->mesh.saveTri){ + for(unsigned int i = 0; i < (*it)->points.size(); i++) + if((*it)->points[i]->ownsParent()) + n += (saveAll ? 1 : (*it)->physicals.size()); + } + } + for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it) + { n += getNumElementsMSH(*it, saveAll, saveSinglePartition); if(!CTX::instance()->mesh.saveTri){ for(unsigned int i = 0; i < (*it)->lines.size(); i++) - if((*it)->lines[i]->ownsParent()) - n += (saveAll ? 1 : (*it)->physicals.size()); + if((*it)->lines[i]->ownsParent()) + n += (saveAll ? 1 : (*it)->physicals.size()); } } - for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){ + for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) + { n += getNumElementsMSH(*it, saveAll, saveSinglePartition); if(CTX::instance()->mesh.saveTri){ - for(unsigned int i = 0; i < (*it)->polygons.size(); i++){ + for(unsigned int i = 0; i < (*it)->polygons.size(); i++) + { int nbC = (*it)->polygons[i]->getNumChildren()-1; - n += (saveAll ? nbC : nbC * (*it)->physicals.size()); + n += (saveAll ? nbC : nbC * (*it)->physicals.size()); } } - else{ + else + { + for(unsigned int i = 0; i < (*it)->triangles.size(); i++) + if((*it)->triangles[i]->ownsParent()) + n += (saveAll ? 1 : (*it)->physicals.size()); for(unsigned int i = 0; i < (*it)->polygons.size(); i++) - if((*it)->polygons[i]->ownsParent()) - n += (saveAll ? 1 : (*it)->physicals.size()); + if((*it)->polygons[i]->ownsParent()) + n += (saveAll ? 1 : (*it)->physicals.size()); } } - for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it){ + for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it) + { n += getNumElementsMSH(*it, saveAll, saveSinglePartition); if(CTX::instance()->mesh.saveTri){ - for(unsigned int i = 0; i < (*it)->polyhedra.size(); i++){ + for(unsigned int i = 0; i < (*it)->polyhedra.size(); i++) + { int nbC = (*it)->polyhedra[i]->getNumChildren()-1; - n += (saveAll ? nbC : nbC * (*it)->physicals.size()); + n += (saveAll ? nbC : nbC * (*it)->physicals.size()); } } - else{ + else + { + for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++) + if((*it)->tetrahedra[i]->ownsParent()) + n += (saveAll ? 1 : (*it)->physicals.size()); for(unsigned int i = 0; i < (*it)->polyhedra.size(); i++) - if((*it)->polyhedra[i]->ownsParent()) - n += (saveAll ? 1 : (*it)->physicals.size()); + if((*it)->polyhedra[i]->ownsParent()) + n += (saveAll ? 1 : (*it)->physicals.size()); } } return n; @@ -939,11 +959,26 @@ int GModel::writeMSH(const std::string &name, double version, bool binary, //parents if (!CTX::instance()->mesh.saveTri){ + for(viter it = firstVertex(); it != lastVertex(); ++it) + for(unsigned int i = 0; i < (*it)->points.size(); i++) + if((*it)->points[i]->ownsParent()) + writeElementMSH(fp, this, (*it)->points[i]->getParent(), + saveAll, version, binary, num, (*it)->tag(), (*it)->physicals); for(eiter it = firstEdge(); it != lastEdge(); ++it) for(unsigned int i = 0; i < (*it)->lines.size(); i++) if((*it)->lines[i]->ownsParent()) writeElementMSH(fp, this, (*it)->lines[i]->getParent(), saveAll, version, binary, num, (*it)->tag(), (*it)->physicals); + for(fiter it = firstFace(); it != lastFace(); ++it) + for(unsigned int i = 0; i < (*it)->triangles.size(); i++) + if((*it)->triangles[i]->ownsParent()) + writeElementMSH(fp, this, (*it)->triangles[i]->getParent(), + saveAll, version, binary, num, (*it)->tag(), (*it)->physicals); + for(riter it = firstRegion(); it != lastRegion(); ++it) + for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++) + if((*it)->tetrahedra[i]->ownsParent()) + writeElementMSH(fp, this, (*it)->tetrahedra[i]->getParent(), + saveAll, version, binary, num, (*it)->tag(), (*it)->physicals); for(fiter it = firstFace(); it != lastFace(); ++it) for(unsigned int i = 0; i < (*it)->polygons.size(); i++) if((*it)->polygons[i]->ownsParent()) diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index ca89017d999ce28202f23ecb2b1998a87e3f3dc7..6190fd8c989fbbc8fc1fc5dc8a753009807ba3ec 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -17,6 +17,7 @@ #include "MPrism.h" #include "MPyramid.h" #include "MElementCut.h" +#include "MSubElement.h" #include "GEntity.h" #include "StringUtils.h" #include "Numeric.h" @@ -734,18 +735,30 @@ void MElement::writeMSH(FILE *fp, double version, bool binary, int num, } return; } - if(type == MSH_LIN_B || type == MSH_LIN_C){ - MLine *l = new MLine(getVertex(0), getVertex(1)); - l->writeMSH(fp, version, binary, num++, elementary, physical, 0, 0, 0, ghosts); - delete l; + if(type == MSH_TET_SUB){ + MTetrahedron *tt = new MTetrahedron(getVertex(0), getVertex(1), getVertex(2), getVertex(3)); + tt->writeMSH(fp, version, binary, num++, elementary, physical, 0, 0, 0, ghosts); + delete tt; return; } - if(type == MSH_TRI_B){ + if(type == MSH_TRI_B || type == MSH_TRI_SUB){ MTriangle *t = new MTriangle(getVertex(0), getVertex(1), getVertex(2)); t->writeMSH(fp, version, binary, num++, elementary, physical, 0, 0, 0, ghosts); delete t; return; } + if(type == MSH_LIN_B || type == MSH_LIN_C || type == MSH_LIN_SUB){ + MLine *l = new MLine(getVertex(0), getVertex(1)); + l->writeMSH(fp, version, binary, num++, elementary, physical, 0, 0, 0, ghosts); + delete l; + return; + } + if(type == MSH_PNT_SUB){ + MPoint *p = new MPoint(getVertex(0)); + p->writeMSH(fp, version, binary, num++, elementary, physical, 0, 0, 0, ghosts); + delete p; + return; + } } if(!binary){ @@ -1171,6 +1184,10 @@ int MElement::getInfoMSH(const int typeMSH, const char **const name) case MSH_PYR_13 : if(name) *name = "Pyramid 13"; return 5 + 8; case MSH_PYR_14 : if(name) *name = "Pyramid 14"; return 5 + 8 + 1; case MSH_POLYH_ : if(name) *name = "Polyhedron"; return 0; + case MSH_PNT_SUB: if(name) *name = "Point Xfem"; return 1; + case MSH_LIN_SUB: if(name) *name = "Line Xfem"; return 2; + case MSH_TRI_SUB: if(name) *name = "Triangle Xfem"; return 3; + case MSH_TET_SUB: if(name) *name = "Tetrahedron Xfem";return 4; default: Msg::Error("Unknown type of element %d", typeMSH); if(name) *name = "Unknown"; @@ -1332,6 +1349,10 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, case MSH_HEX_512: return new MHexahedronN(v, 7, num, part); case MSH_HEX_729: return new MHexahedronN(v, 8, num, part); case MSH_HEX_1000:return new MHexahedronN(v, 9, num, part); + case MSH_PNT_SUB:return new MSubPoint(v, num, part, owner, parent); + case MSH_LIN_SUB:return new MSubLine(v, num, part, owner, parent); + case MSH_TRI_SUB:return new MSubTriangle(v, num, part, owner, parent); + case MSH_TET_SUB:return new MSubTetrahedron(v, num, part, owner, parent); default: return 0; } } diff --git a/Geo/MSubElement.cpp b/Geo/MSubElement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2f83347f8f911e32658e22e7b542d872c119cc8 --- /dev/null +++ b/Geo/MSubElement.cpp @@ -0,0 +1,341 @@ +#include "MSubElement.h" + + + +//-------------------------------------------------------------------------- +// MSubTetrahedron +//-------------------------------------------------------------------------- + +MSubTetrahedron::~MSubTetrahedron() +{ + if(_owner) + delete _orig; +} + +const polynomialBasis* MSubTetrahedron::getFunctionSpace(int order) const +{ + if(_orig) return _orig->getFunctionSpace(order); + return 0; +} +const JacobianBasis* MSubTetrahedron::getJacobianFuncSpace(int order) const +{ + if(_orig) return _orig->getJacobianFuncSpace(order); + return 0; +} +void MSubTetrahedron::getShapeFunctions(double u, double v, double w, double s[], int o) +{ + if(_orig) _orig->getShapeFunctions(u, v, w, s, o); +} +void MSubTetrahedron::getGradShapeFunctions(double u, double v, double w, double s[][3], int o) +{ + if(_orig) _orig->getGradShapeFunctions(u, v, w, s, o); +} +void MSubTetrahedron::getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o) +{ + if(_orig) _orig->getHessShapeFunctions(u, v, w, s, o); +} + +bool MSubTetrahedron::isInside(double u, double v, double w) +{ + if(!_orig) return false; + double uvw[3] = {u, v, w}; + double v_uvw[4][3]; + for(int i=0; i<4; ++i) + { + MVertex *vi = getVertex(i); + double v_xyz[3] = {vi->x(), vi->y(), vi->z()}; + _orig->xyz2uvw(v_xyz, v_uvw[i]); + } + MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]); + MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]); + MVertex v2(v_uvw[2][0], v_uvw[2][1], v_uvw[2][2]); + MVertex v3(v_uvw[3][0], v_uvw[3][1], v_uvw[3][2]); + MTetrahedron t(&v0, &v1, &v2, &v3); + double ksi[3]; + t.xyz2uvw(uvw, ksi); + if(t.isInside(ksi[0], ksi[1], ksi[2])) + return true; + return false; +} +void MSubTetrahedron::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) +{ + *npts=0; + if(_intpt) delete [] _intpt; + if(!_orig) return; + _intpt = new IntPt[getNGQTetPts(pOrder)]; + int nptsi; + IntPt *ptsi; + + double v_uvw[4][3]; + for(int i=0; i<4; ++i) + { + MVertex *vi = getVertex(i); + double v_xyz[3] = {vi->x(), vi->y(), vi->z()}; + _orig->xyz2uvw(v_xyz, v_uvw[i]); + } + MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]); + MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]); + MVertex v2(v_uvw[2][0], v_uvw[2][1], v_uvw[2][2]); + MVertex v3(v_uvw[3][0], v_uvw[3][1], v_uvw[3][2]); + MTetrahedron tt(&v0, &v1, &v2, &v3); + tt.getIntegrationPoints(pOrder, &nptsi, &ptsi); + double jac[3][3]; + for(int ip=0; ip<nptsi; ++ip) + { + const double u = ptsi[ip].pt[0]; + const double v = ptsi[ip].pt[1]; + const double w = ptsi[ip].pt[2]; + tt.getJacobian(u, v, w, jac); + SPoint3 p; tt.pnt(u, v, w, p); + _intpt[*npts + ip].pt[0] = p.x(); + _intpt[*npts + ip].pt[1] = p.y(); + _intpt[*npts + ip].pt[2] = p.z(); + _intpt[*npts + ip].weight = ptsi[ip].weight; + } + *npts = nptsi; + *pts = _intpt; +} + + +//-------------------------------------------------------------------------- +// MSubTriangle +//-------------------------------------------------------------------------- + +MSubTriangle::~MSubTriangle() +{ + if(_owner) + delete _orig; +} + +const polynomialBasis* MSubTriangle::getFunctionSpace(int order) const +{ + if(_orig) return _orig->getFunctionSpace(order); + return 0; +} +const JacobianBasis* MSubTriangle::getJacobianFuncSpace(int order) const +{ + if(_orig) return _orig->getJacobianFuncSpace(order); + return 0; +} +void MSubTriangle::getShapeFunctions(double u, double v, double w, double s[], int o) +{ + if(_orig) _orig->getShapeFunctions(u, v, w, s, o); +} +void MSubTriangle::getGradShapeFunctions(double u, double v, double w, double s[][3], int o) +{ + if(_orig) _orig->getGradShapeFunctions(u, v, w, s, o); +} +void MSubTriangle::getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o) +{ + if(_orig) _orig->getHessShapeFunctions(u, v, w, s, o); +} + +bool MSubTriangle::isInside(double u, double v, double w) +{ + if(!_orig) return false; + double uvw[3] = {u, v, w}; + double v_uvw[3][3]; + for(int i=0; i<3; ++i) + { + MVertex *vi = getVertex(i); + double v_xyz[3] = {vi->x(), vi->y(), vi->z()}; + _orig->xyz2uvw(v_xyz, v_uvw[i]); + } + MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]); + MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]); + MVertex v2(v_uvw[2][0], v_uvw[2][1], v_uvw[2][2]); + MTriangle t(&v0, &v1, &v2); + double ksi[3]; + t.xyz2uvw(uvw, ksi); + if(t.isInside(ksi[0], ksi[1], ksi[2])) + return true; + return false; +} +void MSubTriangle::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) +{ + *npts=0; + if(_intpt) delete [] _intpt; + if(!_orig) return; + _intpt = new IntPt[getNGQTPts(pOrder)]; + int nptsi; + IntPt *ptsi; + + double v_uvw[3][3]; + for(int i=0; i<3; ++i) + { + MVertex *vi = getVertex(i); + double v_xyz[3] = {vi->x(), vi->y(), vi->z()}; + _orig->xyz2uvw(v_xyz, v_uvw[i]); + } + MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]); + MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]); + MVertex v2(v_uvw[2][0], v_uvw[2][1], v_uvw[2][2]); + MTriangle t(&v0, &v1, &v2); + t.getIntegrationPoints(pOrder, &nptsi, &ptsi); + double jac[3][3]; + for(int ip=0; ip<nptsi; ++ip) + { + const double u = ptsi[ip].pt[0]; + const double v = ptsi[ip].pt[1]; + const double w = ptsi[ip].pt[2]; + t.getJacobian(u, v, w, jac); + SPoint3 p; t.pnt(u, v, w, p); + _intpt[*npts + ip].pt[0] = p.x(); + _intpt[*npts + ip].pt[1] = p.y(); + _intpt[*npts + ip].pt[2] = p.z(); + _intpt[*npts + ip].weight = ptsi[ip].weight; + } + *npts = nptsi; + *pts = _intpt; +} + + +//-------------------------------------------------------------------------- +// MSubLine +//-------------------------------------------------------------------------- + +MSubLine::~MSubLine() +{ + if(_owner) + delete _orig; +} + +const polynomialBasis* MSubLine::getFunctionSpace(int order) const +{ + if(_orig) return _orig->getFunctionSpace(order); + return 0; +} +const JacobianBasis* MSubLine::getJacobianFuncSpace(int order) const +{ + if(_orig) return _orig->getJacobianFuncSpace(order); + return 0; +} +void MSubLine::getShapeFunctions(double u, double v, double w, double s[], int o) +{ + if(_orig) _orig->getShapeFunctions(u, v, w, s, o); +} +void MSubLine::getGradShapeFunctions(double u, double v, double w, double s[][3], int o) +{ + if(_orig) _orig->getGradShapeFunctions(u, v, w, s, o); +} +void MSubLine::getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o) +{ + if(_orig) _orig->getHessShapeFunctions(u, v, w, s, o); +} + +bool MSubLine::isInside(double u, double v, double w) +{ + if(!_orig) return false; + double uvw[3] = {u, v, w}; + double v_uvw[2][3]; + for(int i=0; i<2; ++i) + { + MVertex *vi = getVertex(i); + double v_xyz[3] = {vi->x(), vi->y(), vi->z()}; + _orig->xyz2uvw(v_xyz, v_uvw[i]); + } + MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]); + MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]); + MLine l(&v0, &v1); + double ksi[3]; + l.xyz2uvw(uvw, ksi); + if(l.isInside(ksi[0], ksi[1], ksi[2])) + return true; + return false; +} +void MSubLine::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) +{ + *npts=0; + if(_intpt) delete [] _intpt; + if(!_orig) return; + _intpt = new IntPt[getNGQLPts(pOrder)]; + int nptsi; + IntPt *ptsi; + double v_uvw[2][3]; + for(int i=0; i<2; ++i) + { + MVertex *vi = getVertex(i); + double v_xyz[3] = {vi->x(), vi->y(), vi->z()}; + _orig->xyz2uvw(v_xyz, v_uvw[i]); + } + MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]); + MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]); + MLine l(&v0, &v1); + l.getIntegrationPoints(pOrder, &nptsi, &ptsi); + for(int ip=0; ip<nptsi; ++ip) + { + const double u = ptsi[ip].pt[0]; + const double v = ptsi[ip].pt[1]; + const double w = ptsi[ip].pt[2]; + SPoint3 p; l.pnt(u, v, w, p); + _intpt[*npts + ip].pt[0] = p.x(); + _intpt[*npts + ip].pt[1] = p.y(); + _intpt[*npts + ip].pt[2] = p.z(); + _intpt[*npts + ip].weight = ptsi[ip].weight; + } + *npts = nptsi; + *pts = _intpt; +} + +//-------------------------------------------------------------------------- +// MSubPoint +//-------------------------------------------------------------------------- + +MSubPoint::~MSubPoint() +{ + if(_owner) + delete _orig; +} + +const polynomialBasis* MSubPoint::getFunctionSpace(int order) const +{ + if(_orig) return _orig->getFunctionSpace(order); + return 0; +} +const JacobianBasis* MSubPoint::getJacobianFuncSpace(int order) const +{ + if(_orig) return _orig->getJacobianFuncSpace(order); + return 0; +} +void MSubPoint::getShapeFunctions(double u, double v, double w, double s[], int o) +{ + if(_orig) _orig->getShapeFunctions(u, v, w, s, o); +} +void MSubPoint::getGradShapeFunctions(double u, double v, double w, double s[][3], int o) +{ + if(_orig) _orig->getGradShapeFunctions(u, v, w, s, o); +} +void MSubPoint::getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o) +{ + if(_orig) _orig->getHessShapeFunctions(u, v, w, s, o); +} + +bool MSubPoint::isInside(double u, double v, double w) +{ + if(!_orig) return false; + MVertex *v0 = getVertex(0); + double v_xyz[3] = {v0->x(), v0->y(), v0->z()}; + double v_uvw[3]; + _orig->xyz2uvw(v_xyz, v_uvw); + + double p_xyz[3] = {u, v, w}; + double p_uvw[3]; + _orig->xyz2uvw(p_xyz, p_uvw); + + double d_xyz[3] = {p_uvw[0]-v_uvw[0], p_uvw[1]-v_uvw[1], p_uvw[2]-v_uvw[2]}; + double tol = _isInsideTolerance; + + if (d_xyz[0]*d_xyz[0]+d_xyz[1]*d_xyz[1]+d_xyz[2]*d_xyz[2]<tol*tol) + return true; + return false; +} +void MSubPoint::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) +{ + static IntPt GQL[1]; + GQL[0].pt[0] = 0; + GQL[0].pt[1] = 0; + GQL[0].pt[2] = 0; + GQL[0].weight = 1; + *npts = 1; + *pts = GQL; +} diff --git a/Geo/MSubElement.h b/Geo/MSubElement.h new file mode 100644 index 0000000000000000000000000000000000000000..6bf5646e666eb5a2a1778d695cbddae648a90053 --- /dev/null +++ b/Geo/MSubElement.h @@ -0,0 +1,144 @@ +// +// C++ Interface: MSubElement +// +// Description: +// +// +// Authors: <Frederic Duboeuf>, (C) 2012 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef _MSUBELEMENT_H_ +#define _MSUBELEMENT_H_ + +#include "GmshMessage.h" +#include "MElement.h" +#include "MTetrahedron.h" +#include "MTriangle.h" +#include "MLine.h" +#include "MPoint.h" + + +class MSubTetrahedron : public MTetrahedron +{ + protected: + bool _owner; + MElement* _orig; + std::vector<MElement*> _parents; + IntPt *_intpt; + public: + MSubTetrahedron(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MTetrahedron(v0, v1, v2, v3, num, part), _owner(owner), _orig(orig), _intpt(0) {} + MSubTetrahedron(std::vector<MVertex*> v, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MTetrahedron(v, num, part), _owner(owner), _orig(orig), _intpt(0) {} + ~MSubTetrahedron(); + virtual int getTypeForMSH() const { return MSH_TET_SUB; } + virtual const polynomialBasis* getFunctionSpace(int order=-1) const; + virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const; + virtual void getShapeFunctions(double u, double v, double w, double s[], int o); + virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o); + virtual void getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o); + // the parametric coordinates of the LineChildren are + // the coordinates in the local parent element. + virtual bool isInside(double u, double v, double w); + virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts); + virtual MElement *getParent() const { return _orig; } + virtual void setParent(MElement *p, bool owner = false) { _orig = p; _owner = owner; } + virtual bool ownsParent() const { return _owner; } + virtual std::vector<MElement*> getMultiParents() const { return _parents; } + virtual void setMultiParent(std::vector<MElement*> &parents, bool owner = false) { _parents = parents; _orig = _parents[0]; _owner = owner; } +}; + +class MSubTriangle : public MTriangle +{ + protected: + bool _owner; + MElement* _orig; + std::vector<MElement*> _parents; + IntPt *_intpt; + public: + MSubTriangle(MVertex *v0, MVertex *v1, MVertex *v2, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MTriangle(v0, v1, v2, num, part), _owner(owner), _orig(orig), _intpt(0) {} + MSubTriangle(std::vector<MVertex*> v, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MTriangle(v, num, part), _owner(owner), _orig(orig), _intpt(0) {} + ~MSubTriangle(); + virtual int getTypeForMSH() const { return MSH_TRI_SUB; } + virtual const polynomialBasis* getFunctionSpace(int order=-1) const; + virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const; + virtual void getShapeFunctions(double u, double v, double w, double s[], int o); + virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o); + virtual void getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o); + // the parametric coordinates of the LineChildren are + // the coordinates in the local parent element. + virtual bool isInside(double u, double v, double w); + virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts); + virtual MElement *getParent() const { return _orig; } + virtual void setParent(MElement *p, bool owner = false) { _orig = p; _owner = owner; } + virtual bool ownsParent() const { return _owner; } + virtual std::vector<MElement*> getMultiParents() const { return _parents; } + virtual void setMultiParent(std::vector<MElement*> &parents, bool owner = false) { _parents = parents; _orig = _parents[0]; _owner = owner; } +}; + +class MSubLine : public MLine +{ + protected: + bool _owner; + MElement* _orig; + std::vector<MElement*> _parents; + IntPt *_intpt; + public: + MSubLine(MVertex *v0, MVertex *v1, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MLine(v0, v1, num, part), _owner(owner), _orig(orig), _intpt(0) {} + MSubLine(std::vector<MVertex*> v, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MLine(v, num, part), _owner(owner), _orig(orig), _intpt(0) {} + ~MSubLine(); + virtual int getTypeForMSH() const { return MSH_LIN_SUB; } + virtual const polynomialBasis* getFunctionSpace(int order=-1) const; + virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const; + virtual void getShapeFunctions(double u, double v, double w, double s[], int o); + virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o); + virtual void getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o); + // the parametric coordinates of the LineChildren are + // the coordinates in the local parent element. + virtual bool isInside(double u, double v, double w); + virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts); + virtual MElement *getParent() const { return _orig; } + virtual void setParent(MElement *p, bool owner = false) { _orig = p; _owner = owner; } + virtual bool ownsParent() const { return _owner; } + virtual std::vector<MElement*> getMultiParents() const { return _parents; } + virtual void setMultiParent(std::vector<MElement*> &parents, bool owner = false) { _parents = parents; _orig = _parents[0]; _owner = owner; } +}; + +class MSubPoint : public MPoint +{ + protected: + bool _owner; + MElement* _orig; + std::vector<MElement*> _parents; + IntPt *_intpt; + public: + MSubPoint(MVertex *v0, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MPoint(v0, num, part), _owner(owner), _orig(orig), _intpt(0) {} + MSubPoint(std::vector<MVertex*> v, int num=0, int part=0, bool owner=false, MElement* orig=NULL) + : MPoint(v, num, part), _owner(owner), _orig(orig), _intpt(0) {} + ~MSubPoint(); + virtual int getTypeForMSH() const { return MSH_PNT_SUB; } + virtual const polynomialBasis* getFunctionSpace(int order=-1) const; + virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const; + virtual void getShapeFunctions(double u, double v, double w, double s[], int o); + virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o); + virtual void getHessShapeFunctions(double u, double v, double w, double s[][3][3], int o); + // the parametric coordinates of the PointChildren are + // the coordinates in the local parent element. + virtual bool isInside(double u, double v, double w); + virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts); + virtual MElement *getParent() const { return _orig; } + virtual void setParent(MElement *p, bool owner = false) { _orig = p; _owner = owner; } + virtual bool ownsParent() const { return _owner; } + virtual std::vector<MElement*> getMultiParents() const { return _parents; } + virtual void setMultiParent(std::vector<MElement*> &parents, bool owner = false) { _parents = parents; _orig = _parents[0]; _owner = owner; } +}; + +#endif // _MSUBELEMENT_H_ \ No newline at end of file