diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 363ea7ad1ac917264d166513ca557682ebcf1f1d..227b996a0d9a979fe2f81e5d2c0d3193c9cc9c4c 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -998,7 +998,7 @@ StringXNumber MeshOptions_Number[] = { { F|O, "RemeshAlgorithm" , opt_mesh_remesh_algo , 0 , "Remeshing algorithm (0=no split, 1=automatic, 2=automatic only with metis)" }, { F|O, "RemeshParametrization" , opt_mesh_remesh_param , 0 , - "Remsh Parametrization (0=harmonic, 1=conformal, 2=rbf harmonic, 3=harmonicplane, 4=convex)" }, + "Remeshing using discrete parametrization (0=harmonic_circle, 1=conformal, 2=rbf, 3=harmonic_plane, 4=convex_circle, 5=convex_plane, 6=harmonic square" }, { F|O, "RefineSteps" , opt_mesh_refine_steps , 10 , "Number of refinement steps in the MeshAdapt-based 2D algorithms" }, diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp index 4338608e1554f64cd3c2be56df3aa4269521b364..7b37ae4ed62e7759b0fa184c340710595ec7a3b6 100644 --- a/Geo/GFaceCompound.cpp +++ b/Geo/GFaceCompound.cpp @@ -644,11 +644,12 @@ bool GFaceCompound::parametrize() const if(!success) {Msg::Error("Could not order vertices on boundary");exit(1);} // Convex parametrization - if (_mapping == CONVEXCOMBINATION){ + if (_mapping == CONVEX){ Msg::Info("Parametrizing surface %d with 'convex map'", tag()); fillNeumannBCS(); - parametrize(ITERU,CONVEXCOMBINATION); - parametrize(ITERV,CONVEXCOMBINATION); + parametrize(ITERU,CONVEX); + parametrize(ITERV,CONVEX); + printStuff(111); } // Laplace parametrization else if (_mapping == HARMONIC){ @@ -707,8 +708,8 @@ bool GFaceCompound::parametrize() const coordinates.clear(); Octree_Delete(oct); fillNeumannBCS(); - parametrize(ITERU,CONVEXCOMBINATION); - parametrize(ITERV,CONVEXCOMBINATION); + parametrize(ITERU,CONVEX); + parametrize(ITERV,CONVEX); checkOrientation(0); buildOct(); } @@ -895,11 +896,11 @@ void GFaceCompound::computeALoop(std::set<GEdge*> &_unique, std::list<GEdge*> &l } GFaceCompound::GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, - std::list<GEdge*> &U0, typeOfMapping mpg, + std::list<GEdge*> &U0, typeOfCompound toc, int allowPartition, linearSystem<double>* lsys) : GFace(m, tag), _compound(compound), oct(0), _U0(U0), - _mapping(mpg), _allowPartition(allowPartition), _lsys(lsys) + _toc(toc), _allowPartition(allowPartition), _lsys(lsys) { ONE = new simpleFunction<double>(1.0); MONE = new simpleFunction<double>(-1.0); @@ -912,9 +913,16 @@ GFaceCompound::GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, } getBoundingEdges(); + + _mapping = HARMONIC; _type = UNITCIRCLE; - if (_mapping == HARMONICPLANE){ - _mapping = HARMONIC; + if (toc == HARMONIC_CIRCLE) _mapping = HARMONIC; + else if(toc == CONFORMAL) _mapping = CONFORMAL; + else if(toc == RBF) _mapping = RBF; + else if (toc == HARMONIC_PLANE) _type = MEANPLANE; + else if (toc == CONVEX_CIRCLE) _mapping = CONVEX; + else if (toc == CONVEX_PLANE){ + _mapping = CONVEX; _type = MEANPLANE; } @@ -922,14 +930,14 @@ GFaceCompound::GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, fillTris.clear(); } GFaceCompound::GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, - std::list<GEdge*> &U0, std::list<GEdge*> &V0, - std::list<GEdge*> &U1, std::list<GEdge*> &V1, - typeOfMapping mpg, - int allowPartition, - linearSystem<double>* lsys) + std::list<GEdge*> &U0, std::list<GEdge*> &V0, + std::list<GEdge*> &U1, std::list<GEdge*> &V1, + typeOfCompound toc, + int allowPartition, + linearSystem<double>* lsys) : GFace(m, tag), _compound(compound), oct(0), _U0(U0), _V0(V0), _U1(U1), _V1(V1), - _mapping(mpg), _allowPartition(allowPartition), _lsys(lsys) + _toc(toc), _allowPartition(allowPartition), _lsys(lsys) { ONE = new simpleFunction<double>(1.0); MONE = new simpleFunction<double>(-1.0); @@ -942,12 +950,19 @@ GFaceCompound::GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, } getBoundingEdges(); + + _mapping = HARMONIC; _type = UNITCIRCLE; - if (_mapping == HARMONICPLANE){ - _mapping = HARMONIC; + if (toc == HARMONIC_CIRCLE) _mapping = HARMONIC; + else if(toc == CONFORMAL) _mapping = CONFORMAL; + else if(toc == RBF) _mapping = RBF; + else if (toc == HARMONIC_PLANE) _type = MEANPLANE; + else if (toc == CONVEX_CIRCLE) _mapping = CONVEX; + else if (toc == CONVEX_PLANE){ + _mapping = CONVEX; _type = MEANPLANE; } - else if(_mapping == HARMONIC && _U0.size() && _V0.size() && _U1.size() && _V1.size()) { + else if(toc == HARMONIC_SQUARE && _U0.size() && _V0.size() && _U1.size() && _V1.size()) { _type = SQUARE; } @@ -1053,20 +1068,34 @@ SPoint2 GFaceCompound::getCoordinates(MVertex *v) const void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const { + linearSystem<double> *lsys = 0; if (_lsys) lsys = _lsys; else{ -#if defined(HAVE_PETSC) && !defined(HAVE_TAUCS) + if (tom==HARMONIC){ +#if defined(HAVE_TAUCS) + lsys = new linearSystemCSRTaucs<double>; +#elif defined(HAVE_PETSC) && !defined(HAVE_TAUCS) lsys = new linearSystemPETSc<double>; #elif defined(HAVE_GMM) && !defined(HAVE_TAUCS) linearSystemGmm<double> *lsysb = new linearSystemGmm<double>; lsysb->setGmres(1); lsys = lsysb; -#elif defined(HAVE_TAUCS) - lsys = new linearSystemCSRTaucs<double>; #else lsys = new linearSystemFull<double>; #endif + } + else if (tom==CONVEX){ +#if defined(HAVE_PETSC) + lsys = new linearSystemPETSc<double>; +#elif (defined(HAVE_GMM) + linearSystemGmm<double> *lsysb = new linearSystemGmm<double>; + lsysb->setGmres(1); + lsys = lsysb; +#else + lsys = new linearSystemFull<double>; +#endif + } } dofManager<double> myAssembler(lsys); @@ -1154,9 +1183,9 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const femTerm<double> *mapping; if (tom == HARMONIC) mapping = new laplaceTerm(0, 1, ONE); - else + else mapping = new convexCombinationTerm(0, 1, ONE); - + it = _compound.begin(); for( ; it != _compound.end() ; ++it){ for(unsigned int i = 0; i < (*it)->triangles.size(); ++i){ diff --git a/Geo/GFaceCompound.h b/Geo/GFaceCompound.h index 7684deb6e12b33b937e91503b241b1333dc597c3..17a093b7f9cbf94c9d9e51537ae6d98282b10c78 100644 --- a/Geo/GFaceCompound.h +++ b/Geo/GFaceCompound.h @@ -26,17 +26,14 @@ template <class scalar> class simpleFunction; /* A GFaceCompound is a model face that is the compound of model faces. -The user selects 4 corners to the compound, which are mmapped to -points (0,0), (1,0), (1,1) and (0,1) of the compound parametric plane. - It is assumed that all the faces of the compound have been meshed -first. We use this discretization to solve 2 elliptic problems on the -compound. Those 2 problems enables to compute the parametric +first. We use this discretization to solve elliptic problems on the +compound. Those problems enable to compute the parametric coordinates of the mesh points. The parametrization of the compound consist in a triangulation in the (u,v) space with parameter values at nodes. -The compound can therefore be re-meshed using any surface mesh +The compound can therefore be (re)-meshed using any surface mesh generator of gmsh! */ @@ -56,7 +53,9 @@ class GRbf; class GFaceCompound : public GFace { public: typedef enum {ITERU=0,ITERV=1,ITERD=2} iterationStep; - typedef enum {HARMONIC=1,CONFORMAL=2, RBF=3, HARMONICPLANE=4, CONVEXCOMBINATION=5} typeOfMapping; + typedef enum {HARMONIC_CIRCLE=0, CONFORMAL_SPECTRAL=1, RADIAL_BASIS=2, HARMONIC_PLANE=3, + CONVEX_CIRCLE=4,CONVEX_PLANE=5, HARMONIC_SQUARE=6} typeOfCompound; + typedef enum {HARMONIC=0,CONFORMAL=1, RBF=2, CONVEX=3} typeOfMapping; typedef enum {UNITCIRCLE, MEANPLANE, SQUARE} typeOfIsomorphism; void computeNormals(std::map<MVertex*, SVector3> &normals) const; protected: @@ -108,20 +107,20 @@ class GFaceCompound : public GFace { public: GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, - std::list<GEdge*> &U0, typeOfMapping typ = HARMONIC, + std::list<GEdge*> &U0, typeOfCompound typ = HARMONIC_CIRCLE, int allowPartition=1, linearSystem<double>* lsys =0); GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, std::list<GEdge*> &U0, std::list<GEdge*> &V0, std::list<GEdge*> &U1, std::list<GEdge*> &V1, - typeOfMapping typ = HARMONIC, + typeOfCompound typ = HARMONIC_CIRCLE, int allowPartition=1, linearSystem<double>* lsys =0); virtual ~GFaceCompound(); Range<double> parBounds(int i) const { return trivial() ? (*(_compound.begin()))->parBounds(i) : Range<double>(-1, 1); } virtual GPoint point(double par1, double par2) const; - typeOfMapping getTypeOfMapping() { return _mapping;} + typeOfCompound getTypeOfCompound() { return _toc;} SPoint2 parFromPoint(const SPoint3 &p, bool onSurface=true) const; virtual Pair<SVector3,SVector3> firstDer(const SPoint2 ¶m) const; virtual void secondDer(const SPoint2 &, SVector3 *, SVector3 *, SVector3 *) const; @@ -143,18 +142,22 @@ class GFaceCompound : public GFace { int allowPartition() const{ return _allowPartition; } void setType(typeOfIsomorphism type){ _type=type;} private: - typeOfIsomorphism _type; + mutable typeOfCompound _toc; mutable typeOfMapping _mapping; + typeOfIsomorphism _type; int _allowPartition; }; #else +//define empty class ifndef HAVE_SOLVER template<class scalar> class linearSystem; class GFaceCompound : public GFace { public: typedef enum {ITERU=0,ITERV=1,ITERD=2} iterationStep; - typedef enum {HARMONIC=1,CONFORMAL=2, RBF=3, HARMONICPLANE=4, CONVEXCOMBINATION=5} typeOfMapping; + typedef enum {HARMONIC_CIRCLE=0, CONFORMAL_SPECTRAL=1, RADIAL_BASIS=2, HARMONIC_PLANE=3, + CONVEX_CIRCLE=4,CONVEX_PLANE=5, HARMONIC_SQUARE=6} typeOfCompound; + typedef enum {HARMONIC=0,CONFORMAL=1, RBF=2, CONVEX=3} typeOfMapping; typedef enum {UNITCIRCLE, MEANPLANE, SQUARE} typeOfIsomorphism; GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, std::list<GEdge*> &U0, typeOfMapping typ = HARMONIC, @@ -167,7 +170,7 @@ class GFaceCompound : public GFace { GFaceCompound(GModel *m, int tag, std::list<GFace*> &compound, std::list<GEdge*> &U0, std::list<GEdge*> &V0, std::list<GEdge*> &U1, std::list<GEdge*> &V1, - typeOfMapping typ = HARMONIC, + typeOfCompound typ = HARMONIC_CIRCLE, int allowPartition=1, linearSystem<double>* lsys =0) : GFace(m, tag) diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index ce1a2e9d45809943d8ed1b825562107049e09bac..3d443e936e809f8212ceb000875da5c1fd6cabf6 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -2066,7 +2066,7 @@ void GModel::save(std::string fileName) GModel::setCurrent(temp); } -GFaceCompound* GModel::addCompoundFace(std::vector<GFace*> faces, int typeP, int typeS) +GFaceCompound* GModel::addCompoundFace(std::vector<GFace*> faces, int param, int typeS) { int num = getMaxElementaryNumber(2) + 1; @@ -2074,9 +2074,13 @@ GFaceCompound* GModel::addCompoundFace(std::vector<GFace*> faces, int typeP, int std::list<GFace*> comp(faces.begin(), faces.end()); std::list<GEdge*> U0; - GFaceCompound::typeOfMapping typ = GFaceCompound::HARMONIC; - if (typeP == 1) typ = GFaceCompound::CONFORMAL; - if (typeP == 2) typ = GFaceCompound::RBF; + GFaceCompound::typeOfCompound typ = GFaceCompound::HARMONIC_CIRCLE; + if (param == 1) typ = GFaceCompound::CONFORMAL_SPECTRAL; + if (param == 2) typ = GFaceCompound::RADIAL_BASIS; + if (param == 3) typ = GFaceCompound::HARMONIC_PLANE; + if (param == 4) typ = GFaceCompound::CONVEX_CIRCLE; + if (param == 5) typ = GFaceCompound::CONVEX_PLANE; + if (param == 6) typ = GFaceCompound::HARMONIC_SQUARE; GFaceCompound *gfc = new GFaceCompound(this, num, comp, U0, typ, typeS); diff --git a/Geo/GModelIO_Geo.cpp b/Geo/GModelIO_Geo.cpp index f3b8fab3fad80280068ac500d231a85f92ec8113..b78cd64679b9ff41378d177c4f76a1144e94bccc 100644 --- a/Geo/GModelIO_Geo.cpp +++ b/Geo/GModelIO_Geo.cpp @@ -191,11 +191,14 @@ int GModel::importGEOInternals() } } int param = CTX::instance()->mesh.remeshParam; - GFaceCompound::typeOfMapping typ = GFaceCompound::HARMONIC; - if (param == 1) typ = GFaceCompound::CONFORMAL; - if (param == 2) typ = GFaceCompound::RBF; - if (param == 3) typ = GFaceCompound::HARMONICPLANE; - if (param == 4) typ = GFaceCompound::CONVEXCOMBINATION; + + GFaceCompound::typeOfCompound typ = GFaceCompound::HARMONIC_CIRCLE; + if (param == 1) typ = GFaceCompound::CONFORMAL_SPECTRAL; + if (param == 2) typ = GFaceCompound::RADIAL_BASIS; + if (param == 3) typ = GFaceCompound::HARMONIC_PLANE; + if (param == 4) typ = GFaceCompound::CONVEX_CIRCLE; + if (param == 5) typ = GFaceCompound::CONVEX_PLANE; + if (param == 6) typ = GFaceCompound::HARMONIC_SQUARE; int algo = CTX::instance()->mesh.remeshAlgo; f = new GFaceCompound(this, s->Num, comp, b[0], b[1], b[2], b[3], typ, algo); diff --git a/Mesh/CenterlineField.cpp b/Mesh/CenterlineField.cpp index 67f524934745798842800d8f25cb631b5c60fbb2..ab3b5ebf246294d4c4953a80d9b1913ccdf5b6fa 100644 --- a/Mesh/CenterlineField.cpp +++ b/Mesh/CenterlineField.cpp @@ -634,8 +634,8 @@ void Centerline::createSplitCompounds(){ int num_gfc = NF+i+1; Msg::Info("Parametrize Compound Surface (%d) = %d discrete face", num_gfc, pf->tag()); - GFaceCompound::typeOfMapping typ = GFaceCompound::HARMONICPLANE; - //GFaceCompound::typeOfMapping typ = GFaceCompound::CONFORMAL; + GFaceCompound::typeOfCompound typ = GFaceCompound::HARMONIC_PLANE; + //GFaceCompound::typeOfMapping typ = GFaceCompound::CONFORMAL_SPECTRAL; GFaceCompound *gfc = new GFaceCompound(current, num_gfc, f_compound, U0, typ, 0); gfc->meshAttributes.recombine = recombine; diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 22f503a820749f56a2372258eb82ed0cc556d637..d1a9771d51ff1c455e60436f7b6145ee849cf7b0 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -1952,7 +1952,7 @@ void partitionAndRemesh(GFaceCompound *gf) num_gfc, pf->tag()); GFaceCompound *gfc = new GFaceCompound(gf->model(), num_gfc, f_compound, U0, - gf->getTypeOfMapping()); + gf->getTypeOfCompound()); gfc->meshAttributes.recombine = gf->meshAttributes.recombine; gf->model()->add(gfc); diff --git a/Solver/convexCombinationTerm.h b/Solver/convexCombinationTerm.h index d999a2182c1e894c1ef23ba213775c8127d322ff..cb64fb86c6f8039930e5aff619e465b872446c07 100644 --- a/Solver/convexCombinationTerm.h +++ b/Solver/convexCombinationTerm.h @@ -42,31 +42,32 @@ class convexCombinationTerm : public femTerm<double> { MElement *e = se->getMeshElement(); m.setAll(0.); const int nbSF = e->getNumShapeFunctions(); - const double _diff = 1.0; for (int j = 0; j < nbSF; j++){ + MVertex *vj = e->getShapeFunctionNode(j); + double diag = 0.0; for (int k = 0; k < nbSF; k++){ - m(j, k) = -1. * _diff; + MVertex *vk = e->getShapeFunctionNode(k); + MVertex *vl = NULL; + SVector3 a, b; + double tan = 0.0; + if ( k!=j && 3-j-k >= 0 && 3-j-k <=2) { + vl = e->getShapeFunctionNode(3-j-k); + a = SVector3(vk->x()-vj->x(),vk->y()-vj->y(),vk->z()-vj->z()); + b = SVector3(vl->x()-vj->x(),vl->y()-vj->y(),vl->z()-vj->z()); + double angle = myacos(dot(a,b)/(norm(a)*norm(b))); + tan = sin(angle*0.5)/cos(angle*0.5); + } + double length = vj->distance(vk); + m(j, k) = -tan/length; + //m(j, k) = -1; } - m(j, j) = (nbSF - 1) * _diff; + for (int k = 0; k < nbSF; k++){ + if (k != j) diag += (-m(j,k)); + } + m(j, j) = diag; } } -//diag matrix -/* virtual void elementMatrix(SElement *se, fullMatrix<double> &m) const */ -/* { */ - -/* MElement *e = se->getMeshElement(); */ -/* m.setAll(0.); */ -/* const int nbSF = e->getNumShapeFunctions(); */ -/* for (int j = 0; j < nbSF; j++){ */ -/* for (int k = 0; k < nbSF; k++) m(j,k) = 0.0; */ -/* MVertex *v = e->getShapeFunctionNode(j); */ -/* if( v->onWhat()->dim() < 2) m(j,j) = (nbSF - 1) ; */ -/* else m(j,j) = 0.0; */ -/* } */ -/* } */ - - }; #endif