Metric Filler::get_metric(double x,double y,double z,GEntity* ge){ Metric m; SMetric3 temp; SVector3 v1,v2,v3; Field* field; FieldManager* manager; v1 = SVector3(1.0,0.0,0.0); v2 = SVector3(0.0,1.0,0.0); v3 = SVector3(0.0,0.0,1.0); manager = ge->model()->getFields(); if(manager->getBackgroundField()>0){ field = manager->get(manager->getBackgroundField()); if(field){ (*field)(x,y,z,temp,ge); } } m.set_m11(v1.x()); m.set_m21(v1.y()); m.set_m31(v1.z()); m.set_m12(v2.x()); m.set_m22(v2.y()); m.set_m32(v2.z()); m.set_m13(v3.x()); m.set_m23(v3.y()); m.set_m33(v3.z()); return m; }
double Filler::get_size(double x,double y,double z,GEntity* ge){ double h; Field* field; FieldManager* manager; h = 1.0; manager = ge->model()->getFields(); if(manager->getBackgroundField()>0){ field = manager->get(manager->getBackgroundField()); if(field){ h = (*field)(x,y,z,ge); } } return h; }
// anisotropic version of the background field SMetric3 BGM_MeshMetric(GEntity *ge, double U, double V, double X, double Y, double Z) { // Metrics based on element size // Element size = min. between default lc and lc from point (if applicable), // constrained by lcMin and lcMax double lc = CTX::instance()->lc; if(CTX::instance()->mesh.lcFromPoints && ge->dim() < 2) lc = std::min(lc, LC_MVertex_PNTS(ge, U, V)); lc = std::min(lc, ge->getMeshSize()); lc = std::max(lc, CTX::instance()->mesh.lcMin); lc = std::min(lc, CTX::instance()->mesh.lcMax); if(lc <= 0.){ Msg::Error("Wrong mesh element size lc = %g (lcmin = %g, lcmax = %g)", lc, CTX::instance()->mesh.lcMin, CTX::instance()->mesh.lcMax); lc = CTX::instance()->lc; } SMetric3 m0(1./(lc*lc)); // Intersect with metrics from fields if applicable FieldManager *fields = ge->model()->getFields(); SMetric3 m1 = m0; if(fields->getBackgroundField() > 0){ Field *f = fields->get(fields->getBackgroundField()); if(f) { SMetric3 l4; if (!f->isotropic()) (*f)(X, Y, Z, l4, ge); else { const double L = (*f)(X, Y, Z, ge); l4 = SMetric3(1/(L*L)); } m1 = intersection(l4, m0); } } // Intersect with metrics from curvature if applicable SMetric3 m = (CTX::instance()->mesh.lcFromCurvature && ge->dim() < 3) ? intersection(m1, LC_MVertex_CURV_ANISO(ge, U, V)) : m1; return m; }
// This is the only function that is used by the meshers double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z) { // default lc (mesh size == size of the model) double l1 = CTX::instance()->lc; // lc from points double l2 = MAX_LC; if(CTX::instance()->mesh.lcFromPoints && ge->dim() < 2) l2 = LC_MVertex_PNTS(ge, U, V); // lc from curvature double l3 = MAX_LC; if(CTX::instance()->mesh.lcFromCurvature && ge->dim() < 3) l3 = LC_MVertex_CURV(ge, U, V); // lc from fields double l4 = MAX_LC; FieldManager *fields = ge->model()->getFields(); if(fields->getBackgroundField() > 0){ Field *f = fields->get(fields->getBackgroundField()); if(f) l4 = (*f)(X, Y, Z, ge); } // global lc from entity double l5 = ge->getMeshSize(); // take the minimum, then constrain by lcMin and lcMax double lc = std::min(std::min(std::min(std::min(l1, l2), l3), l4), l5); lc = std::max(lc, CTX::instance()->mesh.lcMin); lc = std::min(lc, CTX::instance()->mesh.lcMax); if(lc <= 0.){ Msg::Error("Wrong mesh element size lc = %g (lcmin = %g, lcmax = %g)", lc, CTX::instance()->mesh.lcMin, CTX::instance()->mesh.lcMax); lc = l1; } return lc * CTX::instance()->mesh.lcFactor; }
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos) { // check if point is in domain if (!inDomain(u,v)) return false; // get stored angle double angle_current = angle(u,v); // compute t1,t2: cross field directions // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return false; } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); // get metric double L = size(u,v); infos.metricField = SMetric3(1./(L*L)); FieldManager *fields = gf->model()->getFields(); if(fields->getBackgroundField() > 0) { Field *f = fields->get(fields->getBackgroundField()); if (!f->isotropic()) { (*f)(x,y,z, infos.metricField,gf); } else { L = (*f)(x,y,z,gf); infos.metricField = SMetric3(1./(L*L)); } } double M = dot(s1,s1); double N = dot(s2,s2); double E = dot(s1,s2); // compute the first fundamental form i.e. the metric tensor at the point // M_{ij} = s_i \cdot s_j double metric[2][2] = {{M,E},{E,N}}; // get sizes double size_1 = sqrt(1. / dot(t1,infos.metricField,t1)); double size_2 = sqrt(1. / dot(t2,infos.metricField,t2)); // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain double covar1[2],covar2[2]; // t1 = a s1 + b s2 --> // t1 . s1 = a M + b E // t1 . s2 = a E + b N --> solve the 2 x 2 system // and get covariant coordinates a and b double rhs1[2] = {dot(t1,s1),dot(t1,s2)}; bool singular = false; if (!sys2x2(metric,rhs1,covar1)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2); covar1[1] = 1.0; covar1[0] = 0.0; singular = true; } double rhs2[2] = {dot(t2,s1),dot(t2,s2)}; if (!sys2x2(metric,rhs2,covar2)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z()); covar2[0] = 1.0; covar2[1] = 0.0; singular = true; } // transform the sizes with respect to the metric // consider a vector v of size 1 in the parameter plane // its length is sqrt (v^T M v) --> if I want a real size // of size1 in direction v, it should be sqrt(v^T M v) * size1 double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]); double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]); covar1[0] /= l1; covar1[1] /= l1; covar2[0] /= l2; covar2[1] /= l2; double size_param_1 = size_1 / sqrt ( M*covar1[0]*covar1[0]+ 2*E*covar1[1]*covar1[0]+ N*covar1[1]*covar1[1]); double size_param_2 = size_2 / sqrt ( M*covar2[0]*covar2[0]+ 2*E*covar2[1]*covar2[0]+ N*covar2[1]*covar2[1]); if (singular) { size_param_1 = size_param_2 = std::min (size_param_1,size_param_2); } // filling form... infos.t1 = t1; infos.h.first = size_1; infos.h.second = size_2; infos.paramh.first = size_param_1; infos.paramh.second = size_param_2; infos.paramt1 = SPoint2(covar1[0],covar1[1]); infos.paramt2 = SPoint2(covar2[0],covar2[1]); infos.angle = angle_current; infos.localsize = L; infos.normal = n; return true; }
bool gmshFace::buildSTLTriangulation(bool force) { return false; if(va_geom_triangles){ if(force) delete va_geom_triangles; else return true; } stl_vertices.clear(); stl_triangles.clear(); #if defined(HAVE_MESH) if (!triangles.size()){ contextMeshOptions _temp = CTX::instance()->mesh; FieldManager *fields = model()->getFields(); int BGM = fields->getBackgroundField(); fields->setBackgroundField(0); CTX::instance()->mesh.lcFromPoints = 0; CTX::instance()->mesh.lcFromCurvature = 1; CTX::instance()->mesh.lcExtendFromBoundary = 0; CTX::instance()->mesh.scalingFactor = 1; CTX::instance()->mesh.lcFactor = 1; CTX::instance()->mesh.order = 1; CTX::instance()->mesh.lcIntegrationPrecision = 1.e-3; // CTX::instance()->mesh.Algorithm = 5; model()->mesh(2); CTX::instance()->mesh = _temp; fields->setBackgroundField(fields->get(BGM)); } #endif std::map<MVertex*,int> _v; int COUNT =0; for (unsigned int j = 0; j < triangles.size(); j++){ for (int i = 0; i < 3; i++){ std::map<MVertex*,int>::iterator it = _v.find(triangles[j]->getVertex(j)); if (it != _v.end()){ stl_triangles.push_back(COUNT); _v[triangles[j]->getVertex(j)] = COUNT++; } else stl_triangles.push_back(it->second); } } std::map<MVertex*,int>::iterator itv = _v.begin(); for ( ; itv != _v.end() ; ++itv){ MVertex *v = itv->first; SPoint2 param; reparamMeshVertexOnFace(v, this, param); stl_vertices.push_back(param); } va_geom_triangles = new VertexArray(3, stl_triangles.size() / 3); unsigned int c = CTX::instance()->color.geom.surface; unsigned int col[4] = {c, c, c, c}; for (unsigned int i = 0; i < stl_triangles.size(); i += 3){ SPoint2 &p1(stl_vertices[stl_triangles[i]]); SPoint2 &p2(stl_vertices[stl_triangles[i + 1]]); SPoint2 &p3(stl_vertices[stl_triangles[i + 2]]); GPoint gp1 = GFace::point(p1); GPoint gp2 = GFace::point(p2); GPoint gp3 = GFace::point(p3); double x[3] = {gp1.x(), gp2.x(), gp3.x()}; double y[3] = {gp1.y(), gp2.y(), gp3.y()}; double z[3] = {gp1.z(), gp2.z(), gp3.z()}; SVector3 n[3] = {normal(p1), normal(p2), normal(p3)}; va_geom_triangles->add(x, y, z, n, col); } va_geom_triangles->finalize(); return true; }