diff --git a/Geo/GModel.h b/Geo/GModel.h index 6bf05e1046fcfe8002c171df132157df964c38b3..7039a68b7a069f75fc62d885a1f537c1d7179098 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -364,7 +364,7 @@ class GModel // mesh the model int mesh(int dimension); - // adapt the mesh anisotropically using a metric that is computed from a function f(x,y,z). + // adapt the mesh anisotropically using a metric that is computed from a scalar function f(x,y,z). // One can either // For all algorithms // parameters[1] = lcmin (default : in global gmsh options CTX::instance()->mesh.lcMin) diff --git a/Geo/gmshLevelset.cpp b/Geo/gmshLevelset.cpp index b110564b82a08c21d24fe1ea82709db501e03685..7a2ca832ba8b90ca87ab73ec81deb944c64a4103 100644 --- a/Geo/gmshLevelset.cpp +++ b/Geo/gmshLevelset.cpp @@ -302,6 +302,12 @@ gLevelset::gLevelset(const gLevelset &lv) tag_ = lv.tag_; } +gLevelsetPlane::gLevelsetPlane(const std::vector<double> &pt, const std::vector<double> &norm, int tag) : gLevelsetPrimitive(tag) { + a = norm[0]; + b = norm[1]; + c = norm[2]; + d = -a * pt[0] - b * pt[1] - c * pt[2]; +} gLevelsetPlane::gLevelsetPlane(const double * pt, const double *norm, int tag) : gLevelsetPrimitive(tag) { a = norm[0]; b = norm[1]; @@ -322,7 +328,6 @@ gLevelsetPlane::gLevelsetPlane(const gLevelsetPlane &lv) : gLevelsetPrimitive(lv } //level set defined by points (RBF interpolation) - fullMatrix<double> gLevelsetPoints::generateRbfMat(int p, int index, const fullMatrix<double> &nodes1, const fullMatrix<double> &nodes2) const { @@ -675,13 +680,14 @@ double gLevelsetMathEval::operator() (const double x, const double y, const doub return 1.; } -gLevelsetDistGeom::gLevelsetDistGeom(std::string geomBox, std::string name, int tag) : gLevelsetPrimitive(tag) { +gLevelsetDistGeom::gLevelsetDistGeom(std::string box, std::string geom, int tag) : gLevelsetPrimitive(tag), _box(NULL) { - GModel *gmg = new GModel(); - gmg->load(geomBox+std::string(".msh")); - GModel *gm = new GModel(); - gm->load(name); + modelBox = new GModel(); + modelBox->load(box+std::string(".msh")); + modelGeom = new GModel(); + modelGeom->load(geom); + //EMI FIXME THIS double lx = 0.5, ly = 0.5, lz = 0.5; int levels = 3; int refineCurvedSurfaces = 0; @@ -693,14 +699,14 @@ gLevelsetDistGeom::gLevelsetDistGeom(std::string geomBox, std::string name, int //FILLING POINTS FROM GEOMBOX std::vector<SPoint3> points; std::vector<SPoint3> refinePoints; - for(GModel::viter vit = gmg->firstVertex(); vit != gmg->lastVertex(); vit++){ + for(GModel::viter vit = modelBox->firstVertex(); vit != modelBox->lastVertex(); vit++){ for(unsigned int k = 0; k < (*vit)->getNumMeshVertices(); k++){ MVertex *v = (*vit)->getMeshVertex(k); SPoint3 p(v->x(), v->y(), v->z()); points.push_back(p); } } - for (GModel::eiter eit = gmg->firstEdge(); eit != gmg->lastEdge(); eit++){ + for (GModel::eiter eit = modelBox->firstEdge(); eit != modelBox->lastEdge(); eit++){ for(unsigned int k = 0; k < (*eit)->getNumMeshVertices(); k++){ MVertex *ve = (*eit)->getMeshVertex(k); SPoint3 pe(ve->x(), ve->y(), ve->z()); @@ -709,7 +715,7 @@ gLevelsetDistGeom::gLevelsetDistGeom(std::string geomBox, std::string name, int } //FILLING POINTS FROM STL - for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++){ + for (GModel::fiter fit = modelGeom->firstFace(); fit != modelGeom->lastFace(); fit++){ for(unsigned int k = 0; k < (*fit)->getNumMeshVertices(); k++){ MVertex *vf = (*fit)->getMeshVertex(k); SPoint3 pf(vf->x(), vf->y(), vf->z()); @@ -718,18 +724,18 @@ gLevelsetDistGeom::gLevelsetDistGeom(std::string geomBox, std::string name, int for(unsigned int k = 0; k < (*fit)->getNumMeshElements(); k++){ MElement *e = (*fit)->getMeshElement(k); if (e->getType() == TYPE_TRI){ - MVertex *v1 = e->getVertex(0); - MVertex *v2 = e->getVertex(1); - MVertex *v3 = e->getVertex(2); - SPoint3 cg( (v1->x()+v2->x()+v3->x())/3., - (v1->y()+v2->y()+v3->y())/3., - (v1->z()+v2->z()+v3->z())/3.); - refinePoints.push_back(cg); + MVertex *v1 = e->getVertex(0); + MVertex *v2 = e->getVertex(1); + MVertex *v3 = e->getVertex(2); + SPoint3 cg( (v1->x()+v2->x()+v3->x())/3., + (v1->y()+v2->y()+v3->y())/3., + (v1->z()+v2->z()+v3->z())/3.); + refinePoints.push_back(cg); } } } //FOR CAD - //for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++) + //for (GModel::fiter fit = modelGeom->firstFace(); fit != modelGeom->lastFace(); fit++) // (*fit)->fillPointCloud(sampling, &points); if (points.size() == 0) {Msg::Fatal("No points on surfaces \n"); }; @@ -751,48 +757,46 @@ gLevelsetDistGeom::gLevelsetDistGeom(std::string geomBox, std::string name, int // bb.max().x(), bb.max().y(), bb.max().z()); // Msg::Info(" Nx=%d Ny=%d Nz=%d", NX, NY, NZ); - _box = new cartesianBox<double>(bb.min().x(), bb.min().y(), bb.min().z(), - SVector3(range.x(), 0, 0), - SVector3(0, range.y(), 0), - SVector3(0, 0, range.z()), - NX, NY, NZ, levels); - for (int i = 0; i < NX; i++) - for (int j = 0; j < NY; j++) - for (int k = 0; k < NZ; k++) - _box->insertActiveCell(_box->getCellIndex(i, j, k)); - - cartesianBox<double> *parent = _box, *child; - while((child = parent->getChildBox())){ - //Msg::Info(" level %d ", child->getLevel()); - for(unsigned int i = 0; i < refinePoints.size(); i++) - insertActiveCells(refinePoints[i].x(), refinePoints[i].y(), refinePoints[i].z(), - rtube / pow(2., (levels - child->getLevel())), *child); - parent = child; - } - - //Msg::Info("Removing cells to match mesh topology constraints"); - removeBadChildCells(_box); - removeParentCellsWithChildren(_box); - - //Msg::Info("Initializing nodal values in the cartesian grid"); - _box->createNodalValues(); - - //Msg::Info("Computing levelset on the cartesian grid"); - computeLevelset(gm, *_box); - - //Msg::Info("Renumbering mesh vertices across levels"); - _box->renumberNodes(); + // _box = new cartesianBox<double>(bb.min().x(), bb.min().y(), bb.min().z(), + // SVector3(range.x(), 0, 0), + // SVector3(0, range.y(), 0), + // SVector3(0, 0, range.z()), + // NX, NY, NZ, levels); + // for (int i = 0; i < NX; i++) + // for (int j = 0; j < NY; j++) + // for (int k = 0; k < NZ; k++) + // _box->insertActiveCell(_box->getCellIndex(i, j, k)); + + // cartesianBox<double> *parent = _box, *child; + // while((child = parent->getChildBox())){ + // //Msg::Info(" level %d ", child->getLevel()); + // for(unsigned int i = 0; i < refinePoints.size(); i++) + // insertActiveCells(refinePoints[i].x(), refinePoints[i].y(), refinePoints[i].z(), + // rtube / pow(2., (levels - child->getLevel())), *child); + // parent = child; + // } + + // //Msg::Info("Removing cells to match mesh topology constraints"); + // removeBadChildCells(_box); + // removeParentCellsWithChildren(_box); + + // //Msg::Info("Initializing nodal values in the cartesian grid"); + // _box->createNodalValues(); + + // //Msg::Info("Computing levelset on the cartesian grid"); + // computeLevelset(gm, *_box); + + // //Msg::Info("Renumbering mesh vertices across levels"); + // _box->renumberNodes(); - _box->writeMSH("yeah.msh", false); + // _box->writeMSH("yeah.msh", false); - delete gm; - delete gmg; - + } double gLevelsetDistGeom::operator() (const double x, const double y, const double z) const { - double dist = _box->getValueContainingPoint(x,y,z); + double dist = 0.0 ; //_box->getValueContainingPoint(x,y,z); return dist; } @@ -920,6 +924,19 @@ gLevelsetBox::gLevelsetBox(const double *pt1, const double *pt2, const double *p gLevelsetBox::gLevelsetBox(const gLevelsetBox &lv) : gLevelsetImproved(lv){} +gLevelsetCylinder::gLevelsetCylinder(const std::vector<double> &pt, const std::vector<double> &dir, const double &R, const double &H, int tag) : gLevelsetImproved() { + double pt1[3]={pt[0], pt[1], pt[2]}; + double dir1[3] = {dir[0], dir[1], dir[2]}; + double dir2[3] = {-dir1[0], -dir1[1], -dir1[2]}; + double n[3]; norm(dir1, n); + double pt2[3] = {pt1[0] + H * n[0], pt1[1] + H * n[1], pt1[2] + H * n[2]}; + std::vector<gLevelset *> p; + p.push_back(new gLevelsetGenCylinder(pt1, dir1, R, tag++)); + p.push_back(new gLevelsetPlane(pt1, dir2, tag++)); + p.push_back(new gLevelsetPlane(pt2, dir1, tag)); + Ls = new gLevelsetIntersection(p); +} + gLevelsetCylinder::gLevelsetCylinder(const double *pt, const double *dir, const double &R, const double &H, int tag) : gLevelsetImproved() { double dir2[3] = {-dir[0], -dir[1], -dir[2]}; double n[3]; norm(dir, n); diff --git a/Geo/gmshLevelset.h b/Geo/gmshLevelset.h index 7ce2a06cfda44e94154069d8d57e861e5527d0f9..838115cb60c0b73dbafc43656e711ec7d1d0285a 100644 --- a/Geo/gmshLevelset.h +++ b/Geo/gmshLevelset.h @@ -46,6 +46,7 @@ #define UNION 13 #define INTER 14 #define CRACK 15 +#define DISK 16 class gLevelset : public simpleFunction<double> { @@ -143,6 +144,7 @@ public: // define the plane _a*x+_b*y+_c*z+_d, with outward normal (a,b,c) gLevelsetPlane (const double _a, const double _b, const double _c, const double _d, int tag=1) : gLevelsetPrimitive(tag), a(_a), b(_b), c(_c), d(_d) {} // define the plane passing through the point pt and with outward normal norm + gLevelsetPlane (const std::vector<double> &pt, const std::vector<double> &norm, int tag=1); gLevelsetPlane (const double *pt, const double *norm, int tag=1); // define the plane passing through the 3 points pt1,pt2,pt3 and with outward normal (pt1,pt2)x(pt1,pt3) gLevelsetPlane (const double *pt1, const double *pt2, const double *pt3, int tag=1); @@ -155,6 +157,8 @@ public: int type() const {return PLANE;} }; + + class gLevelsetPoints : public gLevelsetPrimitive { protected: @@ -276,9 +280,14 @@ public: class gLevelsetDistGeom: public gLevelsetPrimitive { cartesianBox<double> *_box; + GModel *modelBox, *modelGeom; public: gLevelsetDistGeom(std::string g, std::string f, int tag=1); - ~gLevelsetDistGeom(){if (_box) delete _box; } + ~gLevelsetDistGeom(){ + delete modelBox; + delete modelGeom; + if (_box) delete _box; + } double operator () (const double x, const double y, const double z) const; int type() const { return UNKNOWN; } }; @@ -404,12 +413,13 @@ public: class gLevelsetCrack : public gLevelsetTools { public: - gLevelsetCrack (std::vector<gLevelset *> p) { + gLevelsetCrack (std::vector<gLevelset *> p, bool delC=false) { if (p.size() != 2) printf("Error : gLevelsetCrack needs 2 levelsets\n"); children.push_back(p[0]); children.push_back(new gLevelsetReverse(p[0])); if(p[1]) children.push_back(p[1]); + _delChildren = delC; } double choose (double d1, double d2) const { return (d1 > d2) ? d1 : d2; // greater of d1 and d2 @@ -417,6 +427,7 @@ public: int type2() const {return CRACK;} }; + // -------------------------------------------------------------------------------------------------------------- // IMPROVED LEVELSET class gLevelsetImproved : public gLevelset @@ -476,6 +487,7 @@ public: // tags of the faces are : exterior face : tag+0 // plane face including pt : tag+1 // plane face opposite to pt : tag+2 + gLevelsetCylinder (const std::vector<double> &pt, const std::vector<double> &dir, const double &R, const double &H, int tag=1); gLevelsetCylinder (const double *pt, const double *dir, const double &R, const double &H, int tag=1); // create a cylinder : pt is the point in the middle of the cylinder base, // dir is the direction of the cylinder axis, @@ -529,5 +541,32 @@ public: int type() const {return CONROD;} }; +/* class gLevelsetDisk : public gLevelsetTools */ +/* { */ +/* public: */ +/* // define the disk of given radius centered at a point pt and with outward normal norm */ +/* gLevelsetDisk (std::vector<double> pt, std::vector<double> dir, const double R, bool delC=false) { */ +/* double *ptP, *normP; */ +/* ptP[0] = pt[0]; ptP[1] = pt[1]; ptP[2] = pt[2]; */ +/* normP[0] = dir[0];normP[1] = dir[1]; normP[2] = dir[2]; */ +/* gLevelsetPlane *plane = new gLevelsetPlane(ptP, normP); */ +/* children.push_back(plane); */ +/* children.push_back(new gLevelsetReverse(plane)); */ +/* double H = 4.*R; */ +/* double *ptC, *normC; */ +/* double val = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]); */ +/* normC[0] = dir[0]/val; normC[1] = dir[1]/val; normC[2] = dir[2]/val; */ +/* ptC[0] = pt[0]-2.*R*normC[0]; */ +/* ptC[1] = pt[1]-2.*R*normC[1]; */ +/* ptC[2] = pt[2]-2.*R*normC[2]; */ +/* gLevelsetCylinder *cyl = new gLevelsetCylinder(ptC, normC, R, H); */ +/* children.push_back(cyl); */ +/* _delChildren = delC; */ +/* } */ +/* double choose (double d1, double d2) const { */ +/* return (d1 > d2) ? d1 : d2; // greater of d1 and d2 */ +/* } */ +/* int type2() const {return DISK;} */ +/* }; */ #endif diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp index 876f3a7e301be420d82d04f6064ea5cd757978f2..ed2b0353f818cbb3e95c4c4b536014016e97e521 100644 --- a/Mesh/BackgroundMesh.cpp +++ b/Mesh/BackgroundMesh.cpp @@ -723,7 +723,7 @@ double backgroundMesh::operator() (double u, double v, double w) const double uv2[3]; MElement *e = _octree->find(u, v, w, 2, true); if (!e) { - Msg::Error("cannot find %g %g %g", u, v, w); + Msg::Error("BGM octree: cannot find %g %g %g", u, v, w); return -1000.0;//0.4; } e->xyz2uvw(uv, uv2); @@ -739,7 +739,7 @@ double backgroundMesh::getAngle(double u, double v, double w) const double uv2[3]; MElement *e = _octree->find(u, v, w, 2, true); if (!e) { - Msg::Error("cannot find %g %g %g", u, v, w); + Msg::Error("BGM octree : cannot find %g %g %g", u, v, w); return 0.0; } e->xyz2uvw(uv, uv2); diff --git a/contrib/DiscreteIntegration/recurCut.h b/contrib/DiscreteIntegration/recurCut.h index 0bb3799810bff3ba114fdda8c3608d12517c3602..8633ed879ce385e3f8503530b64c23e31f1af637 100644 --- a/contrib/DiscreteIntegration/recurCut.h +++ b/contrib/DiscreteIntegration/recurCut.h @@ -3,8 +3,8 @@ #ifndef _RECUR_H_ #define _RECUR_H_ -#include "gmshLevelset.h" #include "Integration3D.h" +class gLevelset; class RecurElement {