void backgroundMesh2D::create_mesh_copy() { // TODO: useful to extend it to other elements ??? //std::set<SPoint2> myBCNodes; GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return; } for (unsigned int i = 0; i < face->triangles.size(); i++) { MTriangle *e = face->triangles[i]; MVertex *news[3]; for (int j=0; j<3; j++) { MVertex *v = e->getVertex(j); std::map<MVertex*,MVertex*>::iterator it = _3Dto2D.find(v); MVertex *newv =0; if (it == _3Dto2D.end()) { SPoint2 p; reparamMeshVertexOnFace(v, face, p); newv = new MVertex (p.x(), p.y(), 0.0);// creates new vertex with xyz= u,v,0. vertices.push_back(newv); _3Dto2D[v] = newv; _2Dto3D[newv] = v; //if(v->onWhat()->dim()<2) myBCNodes.insert(p); } else newv = it->second; news[j] = newv; } elements.push_back(new MTriangle(news[0],news[1],news[2])); } }
Pair<SVector3,SVector3> fourierProjectionFace::firstDer(const SPoint2 ¶m) const { SVector3 du; SVector3 dv; ps_->Dfdu(param.x(), param.y(), du[0], du[1], du[2]); ps_->Dfdv(param.x(), param.y(), dv[0], dv[1], dv[2]); return Pair<SVector3,SVector3>(du, dv); }
SVector3 gmshFace::normal(const SPoint2 ¶m) const { if(s->Typ != MSH_SURF_PLAN){ Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1); Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2); Vertex n = vu % vv; n.norme(); return SVector3(n.Pos.X, n.Pos.Y, n.Pos.Z); } else{ // We cannot use InterpolateSurface() for plane surfaces since it // relies on the mean plane, which does not respect the // orientation // FIXME: move this test at the end of the MeanPlane computation // routine--and store the correct normal, damn it! double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c}; norme(n); GPoint pt = point(param.x(), param.y()); double v[3] = {pt.x(), pt.y(), pt.z()}; int NP = 10, tries = 0; while(1){ tries++; double angle = 0.; for(int i = 0; i < List_Nbr(s->Generatrices); i++) { Curve *c; List_Read(s->Generatrices, i, &c); int N = (c->Typ == MSH_SEGM_LINE) ? 1 : NP; for(int j = 0; j < N; j++) { double u1 = (double)j / (double)N; double u2 = (double)(j + 1) / (double)N; Vertex p1 = InterpolateCurve(c, u1, 0); Vertex p2 = InterpolateCurve(c, u2, 0); double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z}; double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z}; angle += angle_plan(v, v1, v2, n); } } if(fabs(angle) < 0.5){ // we're outside NP *= 2; Msg::Debug("Could not compute normal of surface %d - retrying with %d points", tag(), NP); if(tries > 10){ Msg::Warning("Could not orient normal of surface %d", tag()); return SVector3(n[0], n[1], n[2]); } } else if(angle > 0) return SVector3(n[0], n[1], n[2]); else return SVector3(-n[0], -n[1], -n[2]); } } }
void backgroundMesh2D::updateSizes() { DoubleStorageType::iterator itv = sizeField.begin(); for ( ; itv != sizeField.end(); ++itv) { SPoint2 p; MVertex *v = _2Dto3D[itv->first]; double lc; if (v->onWhat()->dim() == 0) { lc = sizeFactor * BGM_MeshSize(v->onWhat(), 0,0,v->x(),v->y(),v->z()); } else if (v->onWhat()->dim() == 1) { double u; v->getParameter(0, u); lc = sizeFactor * BGM_MeshSize(v->onWhat(), u, 0, v->x(), v->y(), v->z()); } else { GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return; } reparamMeshVertexOnFace(v, face, p); lc = sizeFactor * BGM_MeshSize(face, p.x(), p.y(), v->x(), v->y(), v->z()); } // printf("2D -- %g %g 3D -- %g %g\n",p.x(),p.y(),v->x(),v->y()); itv->second = min(lc,itv->second); itv->second = max(itv->second, sizeFactor * CTX::instance()->mesh.lcMin); itv->second = min(itv->second, sizeFactor * CTX::instance()->mesh.lcMax); } // do not allow large variations in the size field // (Int. J. Numer. Meth. Engng. 43, 1143-1165 (1998) MESH GRADATION // CONTROL, BOROUCHAKI, HECHT, FREY) std::set<MEdge,Less_Edge> edges; for (unsigned int i = 0; i < getNumMeshElements(); i++) { for (int j = 0; j < getElement(i)->getNumEdges(); j++) { edges.insert(getElement(i)->getEdge(j)); } } const double _beta = 1.3; for (int i=0; i<0; i++) { std::set<MEdge,Less_Edge>::iterator it = edges.begin(); for ( ; it != edges.end(); ++it) { MVertex *v0 = it->getVertex(0); MVertex *v1 = it->getVertex(1); MVertex *V0 = _2Dto3D[v0]; MVertex *V1 = _2Dto3D[v1]; DoubleStorageType::iterator s0 = sizeField.find(V0); DoubleStorageType::iterator s1 = sizeField.find(V1); if (s0->second < s1->second)s1->second = min(s1->second,_beta*s0->second); else s0->second = min(s0->second,_beta*s1->second); } } }
static SMetric3 metric_based_on_surface_curvature(const GEdge *ge, double u, bool iso_surf) { const GEdgeCompound* ptrCompoundEdge = dynamic_cast<const GEdgeCompound*>(ge); if (ptrCompoundEdge){ double cmax, cmin; SVector3 dirMax,dirMin; cmax = ptrCompoundEdge->curvatures(u,&dirMax, &dirMin, &cmax,&cmin); if (cmin == 0)cmin =1.e-12; if (cmax == 0)cmax =1.e-12; double lambda2 = ((2 * M_PI) /( fabs(cmax) * CTX::instance()->mesh.minCircPoints ) ); double lambda1 = ((2 * M_PI) /( fabs(cmin) * CTX::instance()->mesh.minCircPoints ) ); SVector3 Z = crossprod(dirMax,dirMin); lambda1 = std::max(lambda1, CTX::instance()->mesh.lcMin); lambda2 = std::max(lambda2, CTX::instance()->mesh.lcMin); lambda1 = std::min(lambda1, CTX::instance()->mesh.lcMax); lambda2 = std::min(lambda2, CTX::instance()->mesh.lcMax); SMetric3 curvMetric (1. / (lambda1 * lambda1), 1. / (lambda2 * lambda2), 1.e-12, dirMin, dirMax, Z); return curvMetric; } else{ SMetric3 mesh_size(1.e-12); std::list<GFace *> faces = ge->faces(); std::list<GFace *>::iterator it = faces.begin(); // we choose the metric eigenvectors to be the ones // related to the edge ... SMetric3 curvMetric = max_edge_curvature_metric(ge, u); while(it != faces.end()){ if (((*it)->geomType() != GEntity::CompoundSurface) && ((*it)->geomType() != GEntity::DiscreteSurface)){ SPoint2 par = ge->reparamOnFace((*it), u, 1); SMetric3 m = metric_based_on_surface_curvature (*it, par.x(), par.y(), iso_surf); curvMetric = intersection_conserveM1(curvMetric,m); } ++it; } return curvMetric; } }
bool inExclusionZone( SPoint2 &p, RTree<surfacePointWithExclusionRegion *, double, 2, double> &rtree, std::vector<surfacePointWithExclusionRegion *> &all) { // should assert that the point is inside the domain // OLD BGM if(old_algo_hexa()) { if(!backgroundMesh::current()->inDomain(p.x(), p.y(), 0)) return true; } else { // NEW BGM if(!BGMManager::current2D()->inDomain(p.x(), p.y(), 0)) return true; } my_wrapper w(p); double _min[2] = {p.x() - 1.e-1, p.y() - 1.e-1}, _max[2] = {p.x() + 1.e-1, p.y() + 1.e-1}; rtree.Search(_min, _max, rtree_callback, &w); return w._tooclose; for(unsigned int i = 0; i < all.size(); ++i) { if(all[i]->inExclusionZone(p)) { // printf("%g %g is in exclusion zone of %g // %g\n",p.x(),p.y(),all[i]._center.x(),all[i]._center.y()); return true; } } return false; }
bool surfacePointWithExclusionRegion::inExclusionZone(const SPoint2 &p) { double mat[2][2]; double b[2], uv[2]; mat[0][0] = _q[1].x() - _q[0].x(); mat[0][1] = _q[2].x() - _q[0].x(); mat[1][0] = _q[1].y() - _q[0].y(); mat[1][1] = _q[2].y() - _q[0].y(); b[0] = p.x() - _q[0].x(); b[1] = p.y() - _q[0].y(); sys2x2(mat, b, uv); // printf("inversion 1 : %g %g \n",uv[0],uv[1]); if(uv[0] >= 0 && uv[1] >= 0 && 1. - uv[0] - uv[1] >= 0) return true; mat[0][0] = _q[3].x() - _q[2].x(); mat[0][1] = _q[0].x() - _q[2].x(); mat[1][0] = _q[3].y() - _q[2].y(); mat[1][1] = _q[0].y() - _q[2].y(); b[0] = p.x() - _q[2].x(); b[1] = p.y() - _q[2].y(); sys2x2(mat, b, uv); // printf("inversion 2 : %g %g \n",uv[0],uv[1]); if(uv[0] >= 0 && uv[1] >= 0 && 1. - uv[0] - uv[1] >= 0) return true; return false; }
SVector3 fourierProjectionFace::normal(const SPoint2 ¶m) const { double x, y, z; ps_->GetUnitNormal(param.x(), param.y(), x, y, z); return SVector3(x, y, z); }
double highOrderTools::smooth_metric_(std::vector<MElement*> & v, GFace *gf, dofManager<double> &myAssembler, std::set<MVertex*> &verticesToMove, elasticityTerm &El) { std::set<MVertex*>::iterator it; double dx = 0.0; if (myAssembler.sizeOfR()){ // while convergence for (unsigned int i = 0; i < v.size(); i++){ MElement *e = v[i]; int nbNodes = e->getNumVertices(); const int n2 = 2 * nbNodes; const int n3 = 3 * nbNodes; fullMatrix<double> K33(n3, n3); fullMatrix<double> K22(n2, n2); fullMatrix<double> J32(n3, n2); fullMatrix<double> J23(n2, n3); fullVector<double> D3(n3); fullVector<double> R2(n2); fullMatrix<double> J23K33(n2, n3); K33.setAll(0.0); SElement se(e); El.elementMatrix(&se, K33); computeMetricInfo(gf, e, J32, J23, D3); J23K33.gemm(J23, K33, 1, 0); K22.gemm(J23K33, J32, 1, 0); J23K33.mult(D3, R2); for (int j = 0; j < n2; j++){ Dof RDOF = El.getLocalDofR(&se, j); myAssembler.assemble(RDOF, -R2(j)); for (int k = 0; k < n2; k++){ Dof CDOF = El.getLocalDofC(&se, k); myAssembler.assemble(RDOF, CDOF, K22(j, k)); } } } myAssembler.systemSolve(); // for all element, compute detJ at integration points --> material law end // while convergence for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){ if ((*it)->onWhat()->dim() == 2){ SPoint2 param; reparamMeshVertexOnFace((*it), gf, param); SPoint2 dparam; myAssembler.getDofValue((*it), 0, _tag, dparam[0]); myAssembler.getDofValue((*it), 1, _tag, dparam[1]); SPoint2 newp = param+dparam; dx += newp.x() * newp.x() + newp.y() * newp.y(); (*it)->setParameter(0, newp.x()); (*it)->setParameter(1, newp.y()); } } myAssembler.systemClear(); } return dx; }
void backgroundMesh2D::propagateValues(DoubleStorageType &dirichlet, simpleFunction<double> &eval_diffusivity, bool in_parametric_plane) { #if defined(HAVE_SOLVER) linearSystem<double> *_lsys = 0; #if 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 dofManager<double> myAssembler(_lsys); // fix boundary conditions DoubleStorageType::iterator itv = dirichlet.begin(); for ( ; itv != dirichlet.end(); ++itv) { myAssembler.fixVertex(itv->first, 0, 1, itv->second); } // Number vertices std::set<MVertex*> vs; GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); delete _lsys; return; } for (unsigned int k = 0; k < face->triangles.size(); k++) for (int j=0; j<3; j++)vs.insert(face->triangles[k]->getVertex(j)); for (unsigned int k = 0; k < face->quadrangles.size(); k++) for (int j=0; j<4; j++)vs.insert(face->quadrangles[k]->getVertex(j)); std::map<MVertex*,SPoint3> theMap; if ( in_parametric_plane) { for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) { SPoint2 p; reparamMeshVertexOnFace ( *it, face, p); theMap[*it] = SPoint3((*it)->x(),(*it)->y(),(*it)->z()); (*it)->setXYZ(p.x(),p.y(),0.0); } } for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) myAssembler.numberVertex(*it, 0, 1); // Assemble laplaceTerm l(0, 1, &eval_diffusivity); for (unsigned int k = 0; k < face->triangles.size(); k++) { MTriangle *t = face->triangles[k]; SElement se(t); l.addToMatrix(myAssembler, &se); } // Solve if (myAssembler.sizeOfR()) { _lsys->systemSolve(); } // save solution for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) { myAssembler.getDofValue(*it, 0, 1, dirichlet[*it]); } if ( in_parametric_plane) { for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) { SPoint3 p = theMap[(*it)]; (*it)->setXYZ(p.x(),p.y(),p.z()); } } delete _lsys; #endif }