SPoint3 gmshParametricSurface::point(double par1, double par2) const { if(_f){ std::vector<double> values(2), res(3); values[0] = par1; values[1] = par2; if(_f->eval(values, res)) return SPoint3(res[0], res[1], res[2]); } return SPoint3(0., 0., 0.); }
bool reparamMeshVertexOnFace(MVertex *v, const GFace *gf, SPoint2 ¶m, bool onSurface) { if (gf->geomType() == GEntity::CompoundSurface ){ GFaceCompound *gfc = (GFaceCompound*) gf; param = gfc->parFromVertex(v); return true; } if(v->onWhat()->geomType() == GEntity::DiscreteCurve || v->onWhat()->geomType() == GEntity::BoundaryLayerCurve){ param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); return true; } if(v->onWhat()->dim() == 0){ GVertex *gv = (GVertex*)v->onWhat(); // hack for bug in periodic curves if (gv->getNativeType() == GEntity::GmshModel && gf->geomType() == GEntity::Plane) param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); else param = gv->reparamOnFace(gf, 1); // shout, we could be on a seam std::list<GEdge*> ed = gv->edges(); for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++) if((*it)->isSeam(gf)) return false; } else if(v->onWhat()->dim() == 1){ GEdge *ge = (GEdge*)v->onWhat(); double t; v->getParameter(0, t); param = ge->reparamOnFace(gf, t, 1); if(!v->getParameter(0,t)) { Msg::Error("Vertex %p not MEdgeVertex", v); return false; //param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); } // shout, we are on a seam if(ge->isSeam(gf)) return false; } else{ double uu, vv; if(v->onWhat() == gf && v->getParameter(0, uu) && v->getParameter(1, vv)){ param = SPoint2(uu, vv); } else { // brute force! param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); } } return true; }
bool reparamMeshEdgeOnFace(MVertex *v1, MVertex *v2, GFace *gf, SPoint2 ¶m1, SPoint2 ¶m2) { std::vector<SPoint2> p1, p2; getAllParameters(v1, gf, p1); getAllParameters(v2, gf, p2); if (p1.size() == 1 && p2.size() == 1){ param1 = p1[0]; param2 = p2[0]; } else if(p1.size() >= 1 && p2.size() >= 1){ int imin = 0; int jmin = 0; { double d = (p2[0].x() - p1[0].x()) * (p2[0].x() - p1[0].x()) + (p2[0].y() - p1[0].y()) * (p2[0].y() - p1[0].y()); for (unsigned int i=0;i<p2.size();i++){ double d1 = (p2[i].x() - p1[0].x()) * (p2[i].x() - p1[0].x()) + (p2[i].y() - p1[0].y()) * (p2[i].y() - p1[0].y()); if (d1 < d){ imin = i; d = d1; } } } { double d = (p2[0].x() - p1[0].x()) * (p2[0].x() - p1[0].x()) + (p2[0].y() - p1[0].y()) * (p2[0].y() - p1[0].y()); for (unsigned int i=0;i<p1.size();i++){ double d1 = (p2[0].x() - p1[i].x()) * (p2[0].x() - p1[i].x()) + (p2[0].y() - p1[i].y()) * (p2[0].y() - p1[i].y()); if (d1 < d){ jmin = i; d = d1; } } } param1 = p1[jmin]; param2 = p2[imin]; } else{ // brute force! param1 = gf->parFromPoint(SPoint3(v1->x(), v1->y(), v1->z())); param2 = gf->parFromPoint(SPoint3(v2->x(), v2->y(), v2->z())); } return true; }
void PView::_init(int tag) { _removeInnerBorders = false; if(tag >= 0){ _tag = tag; _globalTag = std::max(_globalTag, _tag) + 1; } else{ _tag = _globalTag++; } _changed = true; _aliasOf = -1; _eye = SPoint3(0., 0., 0.); va_points = va_lines = va_triangles = va_vectors = va_ellipses = 0; normals = 0; for(unsigned int i = 0; i < list.size(); i++){ if(list[i]->getTag() == _tag){ // in normal operation this should not happen, but we allow it when // programmatically forcing view tags (e.g. when using the views from // within getdp's post-processing operations); this is dangerous, as it // breaks aliases Msg::Info("Removing existing View[%d] (tag = %d)", i, _tag); delete list[i]; // warning: this changes the list } } list.push_back(this); for(unsigned int i = 0; i < list.size(); i++) list[i]->setIndex(i); }
void PView::setChanged(bool val) { _changed = val; // reset the eye position everytime we change the view so that the // arrays get resorted for transparency if(_changed) _eye = SPoint3(0., 0., 0.); }
// use real space + projection at the end static double _relocateVertex2(GFace *gf, MVertex *ver, const std::vector<MElement *> <, double tol) { SPoint3 p1(0, 0, 0); std::size_t counter = 0; for(std::size_t i = 0; i < lt.size(); i++) { for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) { MVertex *v = lt[i]->getVertex(j); p1 += SPoint3(v->x(), v->y(), v->z()); counter++; } } p1 *= 1.0 / (double)counter; SPoint3 p2(ver->x(), ver->y(), ver->z()); double worst; double xi = Maximize_Quality_Golden_Section(ver, gf, p1, p2, lt, tol, worst); SPoint3 p = p1 * (1 - xi) + p2 * xi; double initialGuess[2] = {0, 0}; GPoint pp = gf->closestPoint(p, initialGuess); if(!pp.succeeded()) return 2.0; ver->x() = pp.x(); ver->y() = pp.y(); ver->z() = pp.z(); return worst; }
SPoint3 gmshSphere::point(double par1, double par2) const { par2 += M_PI*.5; const double x = xc + r * sin(par2) * cos(par1); const double y = yc + r * sin(par2) * sin(par1); const double z = zc - r * cos(par2); return SPoint3(x, y, z); }
SOrientedBoundingBox GRegion::getOBB() { if (!_obb) { std::vector<SPoint3> vertices; std::list<GFace*> b_faces = faces(); for (std::list<GFace*>::iterator b_face = b_faces.begin(); b_face != b_faces.end(); b_face++) { if((*b_face)->getNumMeshVertices() > 0) { int N = (*b_face)->getNumMeshVertices(); for (int i = 0; i < N; i++) { MVertex* mv = (*b_face)->getMeshVertex(i); vertices.push_back(mv->point()); } std::list<GEdge*> eds = (*b_face)->edges(); for(std::list<GEdge*>::iterator ed = eds.begin(); ed != eds.end(); ed++) { int N2 = (*ed)->getNumMeshVertices(); for (int i = 0; i < N2; i++) { MVertex* mv = (*ed)->getMeshVertex(i); vertices.push_back(mv->point()); } // Don't forget to add the first and last vertices... SPoint3 pt1((*ed)->getBeginVertex()->x(), (*ed)->getBeginVertex()->y(), (*ed)->getBeginVertex()->z()); SPoint3 pt2((*ed)->getEndVertex()->x(), (*ed)->getEndVertex()->y(), (*ed)->getEndVertex()->z()); vertices.push_back(pt1); vertices.push_back(pt2); } } else if ((*b_face)->buildSTLTriangulation()) { for (unsigned int i = 0; i < (*b_face)->stl_vertices.size(); i++){ GPoint p = (*b_face)->point((*b_face)->stl_vertices[i]); vertices.push_back(SPoint3(p.x(), p.y(), p.z())); } } else { int N = 10; std::list<GEdge*> b_edges = (*b_face)->edges(); for (std::list<GEdge*>::iterator b_edge = b_edges.begin(); b_edge != b_edges.end(); b_edge++) { Range<double> tr = (*b_edge)->parBounds(0); for (int j = 0; j < N; j++) { double t = tr.low() + (double)j / (double)(N - 1) * (tr.high() - tr.low()); GPoint p = (*b_edge)->point(t); SPoint3 pt(p.x(), p.y(), p.z()); vertices.push_back(pt); } } } } _obb = SOrientedBoundingBox::buildOBB(vertices); } return SOrientedBoundingBox(_obb); }
void Mesh::scaledJacAndGradients(int iEl, std::vector<double> &sJ, std::vector<double> &gSJ) { const JacobianBasis *jacBasis = _el[iEl]->getJacobianFuncSpace(); const int &numJacNodes = _nBezEl[iEl]; const int &numMapNodes = _nNodEl[iEl]; fullMatrix<double> JDJ(numJacNodes,3*numMapNodes+1), BDB(numJacNodes,3*numMapNodes+1); // Coordinates of nodes fullMatrix<double> nodesXYZ(numMapNodes,3), normals(_dim,3); for (int i = 0; i < numMapNodes; i++) { int &iVi = _el2V[iEl][i]; nodesXYZ(i,0) = _xyz[iVi].x(); nodesXYZ(i,1) = _xyz[iVi].y(); nodesXYZ(i,2) = _xyz[iVi].z(); } // Calculate Jacobian and gradients, scale if 3D (already scaled by // regularization normals in 2D) if (_fastJacEval) jacBasis->getSignedJacAndGradientsFast(nodesXYZ,_scaledNormEl[iEl],JDJ); else jacBasis->getSignedJacAndGradients(nodesXYZ,_scaledNormEl[iEl],JDJ); if (_dim == 3) JDJ.scale(_invStraightJac[iEl]); // Transform Jacobian and gradients from Lagrangian to Bezier basis if (_fastJacEval) BDB = JDJ; else jacBasis->lag2Bez(JDJ,BDB); // Scaled jacobian for (int l = 0; l < numJacNodes; l++) sJ [l] = BDB (l,3*numMapNodes); // Gradients of the scaled jacobian int iPC = 0; std::vector<SPoint3> gXyzV(numJacNodes); std::vector<SPoint3> gUvwV(numJacNodes); for (int i = 0; i < numMapNodes; i++) { int &iFVi = _el2FV[iEl][i]; if (iFVi >= 0) { for (int l = 0; l < numJacNodes; l++) gXyzV [l] = SPoint3(BDB(l,i+0*numMapNodes), BDB(l,i+1*numMapNodes), BDB(l,i+2*numMapNodes)); _paramFV[iFVi]->gXyz2gUvw(_uvw[iFVi],gXyzV,gUvwV); for (int l = 0; l < numJacNodes; l++) { gSJ[indGSJ(iEl,l,iPC)] = gUvwV[l][0]; if (_nPCFV[iFVi] >= 2) gSJ[indGSJ(iEl,l,iPC+1)] = gUvwV[l][1]; if (_nPCFV[iFVi] == 3) gSJ[indGSJ(iEl,l,iPC+2)] = gUvwV[l][2]; } iPC += _nPCFV[iFVi]; } } }
void Mesh::metricMinAndGradients(int iEl, std::vector<double> &lambda, std::vector<double> &gradLambda) { const JacobianBasis *jacBasis = _el[iEl]->getJacobianFuncSpace(); const int &numJacNodes = jacBasis->getNumJacNodes(); const int &numMapNodes = jacBasis->getNumMapNodes(); const int &numPrimMapNodes = jacBasis->getNumPrimMapNodes(); fullVector<double> lambdaJ(numJacNodes), lambdaB(numJacNodes); fullMatrix<double> gradLambdaJ(numJacNodes, 2 * numMapNodes); fullMatrix<double> gradLambdaB(numJacNodes, 2 * numMapNodes); // Coordinates of nodes fullMatrix<double> nodesXYZ(numMapNodes,3), nodesXYZStraight(numPrimMapNodes,3); for (int i = 0; i < numMapNodes; i++) { int &iVi = _el2V[iEl][i]; nodesXYZ(i,0) = _xyz[iVi].x(); nodesXYZ(i,1) = _xyz[iVi].y(); nodesXYZ(i,2) = _xyz[iVi].z(); if (i < numPrimMapNodes) { nodesXYZStraight(i,0) = _ixyz[iVi].x(); nodesXYZStraight(i,1) = _ixyz[iVi].y(); nodesXYZStraight(i,2) = _ixyz[iVi].z(); } } jacBasis->getMetricMinAndGradients(nodesXYZ,nodesXYZStraight,lambdaJ,gradLambdaJ); //l2b.mult(lambdaJ, lambdaB); //l2b.mult(gradLambdaJ, gradLambdaB); lambdaB = lambdaJ; gradLambdaB = gradLambdaJ; int iPC = 0; std::vector<SPoint3> gXyzV(numJacNodes); std::vector<SPoint3> gUvwV(numJacNodes); for (int l = 0; l < numJacNodes; l++) { lambda[l] = lambdaB(l); } for (int i = 0; i < numMapNodes; i++) { int &iFVi = _el2FV[iEl][i]; if (iFVi >= 0) { for (int l = 0; l < numJacNodes; l++) { gXyzV [l] = SPoint3(gradLambdaB(l,i+0*numMapNodes), gradLambdaB(l,i+1*numMapNodes),/*BDB(l,i+2*nbNod)*/ 0.); } _paramFV[iFVi]->gXyz2gUvw(_uvw[iFVi],gXyzV,gUvwV); for (int l = 0; l < numJacNodes; l++) { gradLambda[indGSJ(iEl,l,iPC)] = gUvwV[l][0]; if (_nPCFV[iFVi] >= 2) gradLambda[indGSJ(iEl,l,iPC+1)] = gUvwV[l][1]; if (_nPCFV[iFVi] == 3) gradLambda[indGSJ(iEl,l,iPC+2)] = gUvwV[l][2]; } iPC += _nPCFV[iFVi]; } } }
void Centerline::importFile(std::string fileName) { current = GModel::current(); std::vector<GFace*> currentFaces(current->firstFace(), current->lastFace()); for (unsigned int i = 0; i < currentFaces.size(); i++){ GFace *gf = currentFaces[i]; if (gf->geomType() == GEntity::DiscreteSurface){ for(unsigned int j = 0; j < gf->triangles.size(); j++) triangles.push_back(gf->triangles[j]); if (is_cut){ gf->triangles.clear(); gf->deleteVertexArrays(); current->remove(gf); } } } if(triangles.empty()){ Msg::Error("Current GModel has no triangles ..."); return; } mod = new GModel(); mod->load(fileName); mod->removeDuplicateMeshVertices(1.e-8); current->setAsCurrent(); current->setVisibility(1); int maxN = 0.0; std::vector<GEdge*> modEdges(mod->firstEdge(), mod->lastEdge()); MVertex *vin = modEdges[0]->lines[0]->getVertex(0); ptin = SPoint3(vin->x(), vin->y(), vin->z()); for (unsigned int i = 0; i < modEdges.size(); i++){ GEdge *ge = modEdges[i]; for(unsigned int j = 0; j < ge->lines.size(); j++){ MLine *l = ge->lines[j]; MVertex *v0 = l->getVertex(0); MVertex *v1 = l->getVertex(1); std::map<MVertex*, int>::iterator it0 = colorp.find(v0); std::map<MVertex*, int>::iterator it1 = colorp.find(v1); if (it0 == colorp.end() || it1 == colorp.end()){ lines.push_back(l); colorl.insert(std::make_pair(l, ge->tag())); maxN = std::max(maxN, ge->tag()); } if (it0 == colorp.end()) colorp.insert(std::make_pair(v0, ge->tag())); if (it1 == colorp.end()) colorp.insert(std::make_pair(v1, ge->tag())); } } createBranches(maxN); }
static void fillPointCloud(GEdge *ge, double sampling, std::vector<SPoint3> &points) { Range<double> t_bounds = ge->parBounds(0); double t_min = t_bounds.low(); double t_max = t_bounds.high(); double length = ge->length(t_min, t_max, 20); int N = length / sampling; for(int i = 0; i < N; i++) { double t = t_min + (double)i / (double)(N - 1) * (t_max - t_min); GPoint p = ge->point(t); points.push_back(SPoint3(p.x(), p.y(), p.z())); } }
void Mesh::getGEntityPositions(std::vector<SPoint3> &xyz, std::vector<SPoint3> &uvw) { xyz.resize(nVert()); uvw.resize(nFV()); for (int iV = 0; iV < nVert(); iV++) xyz[iV] = SPoint3(_vert[iV]->x(),_vert[iV]->y(),_vert[iV]->z()); for (int iFV = 0; iFV < nFV(); iFV++){ MVertex *v = _freeVert[iFV]; if (v->onWhat()->dim() == 1){ double t; v->getParameter(0,t); uvw[iFV] = SPoint3(t,0,0); } if (v->onWhat()->dim() == 2){ double uu,vv; v->getParameter(0,uu); v->getParameter(1,vv); uvw[iFV] = SPoint3(uu,vv,0); } } }
void Filler::create_spawns(GEntity* ge,MElementOctree* octree,Node* node,std::vector<Node*>& spawns){ double x,y,z; double x1,y1,z1; double x2,y2,z2; double x3,y3,z3; double x4,y4,z4; double x5,y5,z5; double x6,y6,z6; double h; double h1,h2,h3,h4,h5,h6; Metric m; SPoint3 point; point = node->get_point(); x = point.x(); y = point.y(); z = point.z(); h = node->get_size(); m = node->get_metric(); h1 = improvement(ge,octree,point,h,SVector3(m.get_m11(),m.get_m21(),m.get_m31())); x1 = x + h1*m.get_m11(); y1 = y + h1*m.get_m21(); z1 = z + h1*m.get_m31(); h2 = improvement(ge,octree,point,h,SVector3(-m.get_m11(),-m.get_m21(),-m.get_m31())); x2 = x - h2*m.get_m11(); y2 = y - h2*m.get_m21(); z2 = z - h2*m.get_m31(); h3 = improvement(ge,octree,point,h,SVector3(m.get_m12(),m.get_m22(),m.get_m32())); x3 = x + h3*m.get_m12(); y3 = y + h3*m.get_m22(); z3 = z + h3*m.get_m32(); h4 = improvement(ge,octree,point,h,SVector3(-m.get_m12(),-m.get_m22(),-m.get_m32())); x4 = x - h4*m.get_m12(); y4 = y - h4*m.get_m22(); z4 = z - h4*m.get_m32(); h5 = improvement(ge,octree,point,h,SVector3(m.get_m13(),m.get_m23(),m.get_m33())); x5 = x + h5*m.get_m13(); y5 = y + h5*m.get_m23(); z5 = z + h5*m.get_m33(); h6 = improvement(ge,octree,point,h,SVector3(-m.get_m13(),-m.get_m23(),-m.get_m33())); x6 = x - h6*m.get_m13(); y6 = y - h6*m.get_m23(); z6 = z - h6*m.get_m33(); *spawns[0] = Node(SPoint3(x1,y1,z1)); *spawns[1] = Node(SPoint3(x2,y2,z2)); *spawns[2] = Node(SPoint3(x3,y3,z3)); *spawns[3] = Node(SPoint3(x4,y4,z4)); *spawns[4] = Node(SPoint3(x5,y5,z5)); *spawns[5] = Node(SPoint3(x6,y6,z6)); }
bool reparamMeshVertexOnEdge(MVertex *v, const GEdge *ge, double ¶m) { param = 1.e6; Range<double> bounds = ge->parBounds(0); bool ok = true; if(ge->getBeginVertex() && ge->getBeginVertex()->mesh_vertices[0] == v) param = bounds.low(); else if(ge->getEndVertex() && ge->getEndVertex()->mesh_vertices[0] == v) param = bounds.high(); else ok = v->getParameter(0, param); if(!ok || param == 1.e6) param = ge->parFromPoint(SPoint3(v->x(), v->y(), v->z())); if(param < 1.e6) return true; return false; }
SBoundingBox3d GEdge::bounds() const { SBoundingBox3d bbox; if(geomType() != DiscreteCurve && geomType() != BoundaryLayerCurve){ Range<double> tr = parBounds(0); const int N = 10; for(int i = 0; i < N; i++){ double t = tr.low() + (double)i / (double)(N - 1) * (tr.high() - tr.low()); GPoint p = point(t); bbox += SPoint3(p.x(), p.y(), p.z()); } } else{ for(unsigned int i = 0; i < mesh_vertices.size(); i++) bbox += mesh_vertices[i]->point(); } return bbox; }
void PViewDataList::_stat(std::vector<double> &D, std::vector<char> &C, int nb) { // compute statistics for text lists for(std::size_t i = 0; i < D.size(); i += nb) { double beg = D[i + nb - 1]; double end; if(i + 2 * nb > D.size()) end = C.size(); else end = D[i + nb + nb - 1]; char *c = &C[(int)beg]; int nbtime = 0; for(int j = 0; j < (int)(end - beg); j++) if(c[j] == '\0') nbtime++; if(nbtime > NbTimeStep) NbTimeStep = nbtime; } if(nb == 5) { for(std::size_t i = 0; i < D.size(); i += nb) BBox += SPoint3(D[i], D[i + 1], D[i + 2]); } }
void PViewDataList::_stat(std::vector<double> &list, int nbcomp, int nbelm, int nbnod, int type) { // compute statistics for element lists if(!nbelm) return; int nbval = nbcomp * nbnod; if(haveInterpolationMatrices()) { std::vector<fullMatrix<double> *> im; int nim = getInterpolationMatrices(type, im); if(nim == 4) nbnod = im[2]->size1(); if(nim) nbval = nbcomp * im[0]->size1(); } int nb = list.size() / nbelm; for(int ele = 0; ele < nbelm; ele++) { int i = ele * nb; if(type == TYPE_POLYG || type == TYPE_POLYH) { int t = (type == TYPE_POLYG) ? 0 : 1; nbnod = polyNumNodes[t][ele]; nb = list.size() / polyTotNumNodes[t] * nbnod; i = polyAgNumNodes[t][ele] * nb / nbnod; nbval = nbcomp * nbnod; } int N = nb - 3 * nbnod; double *X = &list[i]; double *Y = &list[i + 1 * nbnod]; double *Z = &list[i + 2 * nbnod]; double *V = &list[i + 3 * nbnod]; // update bounding box for(int j = 0; j < nbnod; j++) BBox += SPoint3(X[j], Y[j], Z[j]); // update num time steps if(Min == VAL_INF || Max == -VAL_INF) { NbTimeStep = N / nbval; TimeStepMin.clear(); TimeStepMax.clear(); for(int j = 0; j < NbTimeStep; j++) { TimeStepMin.push_back(VAL_INF); TimeStepMax.push_back(-VAL_INF); } } else if(N / nbval < NbTimeStep) { // if some elts have less steps, reduce the total number! NbTimeStep = N / nbval; } // update min/max int tensorRep = 0; // Von-Mises: we could/should be able to choose this for(int j = 0; j < N; j += nbcomp) { double l0 = ComputeScalarRep(nbcomp, &V[j], tensorRep); Min = std::min(l0, Min); Max = std::max(l0, Max); int ts = j / nbval; if(ts < NbTimeStep) { // security TimeStepMin[ts] = std::min(l0, TimeStepMin[ts]); TimeStepMax[ts] = std::max(l0, TimeStepMax[ts]); } } } }
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 }
SuperEl::SuperEl(int type, int order, const std::vector<MVertex*> &baseVert, const std::vector<MVertex*> &topPrimVert) : _superEl(0), _superEl0(0) { // Get useful info on meta-element type if not already there std::map<int,SuperEl::superInfoType>::iterator itSInfo = _superInfo.find(type); if (itSInfo == _superInfo.end()) itSInfo = _superInfo.insert(std::pair<int,superInfoType>(type,superInfoType(type, order))).first; SuperEl::superInfoType &sInfo = itSInfo->second; // Exit if unknown type if (sInfo.nV == 0) return; // References for easier writing const int &nV = sInfo.nV; const fullMatrix<double> &points = sInfo.points; const std::vector<int> &baseInd = sInfo.baseInd; const std::vector<int> &topInd = sInfo.topInd; const std::vector<int> &otherInd = sInfo.otherInd; // Add copies of vertices in base & top faces (only first-order vertices for top face) _superVert.resize(nV); for (int i=0; i<baseInd.size(); ++i) _superVert[baseInd[i]] = new MVertex(*baseVert[i]); for (int i=0; i<topPrimVert.size(); ++i) _superVert[topInd[i]] = new MVertex(*topPrimVert[i]); // Create first-order meta-element switch (type) { case TYPE_QUA: _superEl0 = new MQuadrangle(_superVert); break; case TYPE_PRI: _superEl0 = new MPrism(_superVert); break; case TYPE_HEX: _superEl0 = new MHexahedron(_superVert); break; default: Msg::Error("SuperEl not implemented for element of type %d", type); return; } // Add HO vertices in top face for (int i=topPrimVert.size(); i<topInd.size(); ++i) { SPoint3 p; const int ind = topInd[i]; _superEl0->pnt(points(ind,0),points(ind,1),points(ind,2),p); _superVert[ind] = new MVertex(p.x(),p.y(),p.z()); } // Add vertices not in base & top faces for (int i=0; i<otherInd.size(); ++i) { SPoint3 p; const int ind = otherInd[i]; _superEl0->pnt(points(ind,0),points(ind,1),points(ind,2),p); _superVert[ind] = new MVertex(p.x(),p.y(),p.z()); } // Create high-order meta-element switch (type) { case TYPE_QUA: _superEl = new MQuadrangleN(_superVert, order); break; case TYPE_PRI: _superEl = new MPrismN(_superVert, order); break; case TYPE_HEX: _superEl = new MHexahedronN(_superVert, order); break; } // Scale meta-element if not valid // TODO: Scale depending on target Jmin? // TODO: Could be improved by using complete meta-element and use optimization for (int iter = 0; iter < 10; iter++) { if (_superEl->distoShapeMeasure() > 0) break; if (iter == 0) Msg::Warning("A meta-element has a negative distortion, trying to scale"); for (int i=0; i<topPrimVert.size(); ++i) { // Move top primary vert. MVertex *&vb = _superVert[baseInd[i]], *&vt = _superVert[topInd[i]]; SPoint3 pb = vb->point(), pt = vt->point(); pt += SPoint3(0.25*(pt-pb)); vt->setXYZ(pt.x(), pt.y(), pt.z()); } for (int i=topPrimVert.size(); i<topInd.size(); ++i) { // Recompute HO vert. in top face SPoint3 p; const int ind = topInd[i]; _superEl0->pnt(points(ind,0),points(ind,1),points(ind,2),p); _superVert[ind]->setXYZ(p.x(),p.y(),p.z()); } for (int i=0; i<otherInd.size(); ++i) { // Recompute vert. not in base & top faces SPoint3 p; const int ind = otherInd[i]; _superEl0->pnt(points(ind,0),points(ind,1),points(ind,2),p); _superVert[ind]->setXYZ(p.x(),p.y(),p.z()); } } }
PView *GMSH_DistancePlugin::execute(PView *v) { int id_pt = (int) DistanceOptions_Number[0].def; int id_line = (int) DistanceOptions_Number[1].def; int id_face = (int) DistanceOptions_Number[2].def; double type = (double) DistanceOptions_Number[3].def; int ortho = (int) DistanceOptions_Number[6].def; PView *view = new PView(); _data = getDataList(view); #if defined(HAVE_SOLVER) #if defined(HAVE_TAUCS) linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; #else linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>; lsys->setNoisy(1); lsys->setGmres(1); lsys->setPrec(5.e-8); #endif dofManager<double> * dofView = new dofManager<double>(lsys); #endif std::vector<GEntity*> _entities; GModel::current()->getEntities(_entities); if (!_entities.size() || !_entities[_entities.size()-1]->getMeshElement(0)) { Msg::Error("This plugin needs a mesh !"); return view; } GEntity* ge = _entities[_entities.size()-1]; int integrationPointTetra[2] = {0,0}; int numnodes = 0; for (unsigned int i = 0; i < _entities.size()-1; i++) numnodes += _entities[i]->mesh_vertices.size(); int totNodes = numnodes + _entities[_entities.size()-1]->mesh_vertices.size(); int order = ge->getMeshElement(0)->getPolynomialOrder(); int totNumNodes = totNodes + ge->getNumMeshElements()*integrationPointTetra[order-1]; std::vector<SPoint3> pts; std::vector<double> distances; std::vector<MVertex* > pt2Vertex; pts.clear(); distances.clear(); pt2Vertex.clear(); pts.reserve(totNumNodes); distances.reserve(totNumNodes); pt2Vertex.reserve(totNumNodes); std::map<MVertex*,double> _distanceE_map; std::map<MVertex*,int> _isInYarn_map; std::vector<int> index; std::vector<double> distancesE; std::vector<double> distances2; std::vector<double> distancesE2; std::vector<int> isInYarn; std::vector<int> isInYarn2; std::vector<SPoint3> closePts; std::vector<SPoint3> closePts2; for (int i=0; i<totNumNodes; i++) { distances.push_back(1.e22); } int k = 0; for (unsigned int i=0; i<_entities.size(); i++){ GEntity* ge = _entities[i]; _maxDim = std::max(_maxDim, ge->dim()); for (unsigned int j=0; j<ge->mesh_vertices.size(); j++) { MVertex *v = ge->mesh_vertices[j]; pts.push_back(SPoint3(v->x(), v->y(), v->z())); _distance_map.insert(std::make_pair(v, 0.0)); /* TO DO (by AM) SPoint3 p_empty(); _closePts_map.insert(std::make_pair(v, p_empty)); */ pt2Vertex[k] = v; k++; } } // Compute geometrical distance to mesh boundaries //------------------------------------------------------ if (type < 0.0 ) { bool existEntity = false; for (unsigned int i=0; i<_entities.size(); i++) { GEntity* g2 = _entities[i]; int gDim = g2->dim(); std::vector<int> phys = g2->getPhysicalEntities(); bool computeForEntity = false; for(unsigned int k = 0; k<phys.size(); k++) { int tagp = phys[k]; if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1) computeForEntity = true; else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) || (tagp == id_face && gDim == 2)) computeForEntity = true; } if (computeForEntity) { existEntity = true; for (unsigned int k = 0; k < g2->getNumMeshElements(); k++) { std::vector<double> iDistances; std::vector<SPoint3> iClosePts; std::vector<double> iDistancesE; std::vector<int> iIsInYarn; MElement *e = g2->getMeshElement(k); MVertex *v1 = e->getVertex(0); MVertex *v2 = e->getVertex(1); SPoint3 p1(v1->x(), v1->y(), v1->z()); SPoint3 p2(v2->x(), v2->y(), v2->z()); if ((e->getNumVertices() == 2 && order == 1) || (e->getNumVertices() == 3 && order == 2)) { signedDistancesPointsLine(iDistances, iClosePts, pts, p1, p2); } else if ((e->getNumVertices() == 3 && order == 1) || (e->getNumVertices() == 6 && order == 2)) { MVertex *v3 = e->getVertex(2); SPoint3 p3 (v3->x(),v3->y(),v3->z()); signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1, p2, p3); } for (unsigned int kk=0; kk<pts.size(); kk++) { if (std::abs(iDistances[kk]) < distances[kk]) { distances[kk] = std::abs(iDistances[kk]); MVertex *v = pt2Vertex[kk]; _distance_map[v] = distances[kk]; /* TO DO (by AM) _closePts_map[v] = iClosePts[kk]; */ } } } } } if (!existEntity){ if (id_pt != 0) Msg::Error("The Physical Point does not exist !"); if (id_line != 0) Msg::Error("The Physical Line does not exist !"); if (id_face != 0) Msg::Error("The Physical Surface does not exist !"); return view; } printView(_entities, _distance_map); /* TO DO (by AM) printView(_entities, _closePts_map); */ } // Compute PDE for distance function //----------------------------------- else if (type > 0.0) { #if defined(HAVE_SOLVER) bool existEntity = false; SBoundingBox3d bbox; for(unsigned int i = 0; i < _entities.size(); i++){ GEntity* ge = _entities[i]; int gDim = ge->dim(); bool fixForEntity = false; std::vector<int> phys = ge->getPhysicalEntities(); for(unsigned int k = 0; k < phys.size(); k++) { int tagp = phys[k]; if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1) fixForEntity = true; else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) || (tagp == id_face && gDim == 2) ) fixForEntity = true; } if (fixForEntity) { existEntity = true; for (unsigned int i = 0; i < ge->getNumMeshElements(); ++i) { MElement *t = ge->getMeshElement(i); for (int k=0; k<t->getNumVertices(); k++) { MVertex *v = t->getVertex(k); dofView->fixVertex(v, 0, 1, 0.); bbox += SPoint3(v->x(), v->y(), v->z()); } } } } if (!existEntity){ if (id_pt != 0) Msg::Error("The Physical Point does not exist !"); if (id_line != 0) Msg::Error("The Physical Line does not exist !"); if (id_face != 0) Msg::Error("The Physical Surface does not exist !"); return view; } std::vector<MElement *> allElems; for(unsigned int ii = 0; ii < _entities.size(); ii++){ if(_entities[ii]->dim() == _maxDim) { GEntity *ge = _entities[ii]; for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i) { MElement *t = ge->getMeshElement(i); allElems.push_back(t); for (int k = 0; k < t->getNumVertices(); k++) dofView->numberVertex(t->getVertex(k), 0, 1); } } } double L = norm(SVector3(bbox.max(), bbox.min())); double mu = type*L; simpleFunction<double> DIFF(mu*mu), ONE(1.0); distanceTerm distance(GModel::current(), 1, &DIFF, &ONE); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ SElement se((*it)); distance.addToMatrix(*dofView, &se); } groupOfElements gr(allElems); distance.addToRightHandSide(*dofView, gr); Msg::Info("Distance Computation: Assembly done"); lsys->systemSolve(); Msg::Info("Distance Computation: System solved"); for (std::map<MVertex*,double >::iterator itv = _distance_map.begin(); itv != _distance_map.end() ; ++itv) { MVertex *v = itv->first; double value; dofView->getDofValue(v, 0, 1, value); value = std::min(0.9999, value); double dist = -mu * log(1. - value); itv->second = dist; } printView(_entities, _distance_map); #endif } _data->setName("distance"); _data->Time.push_back(0); _data->setFileName(_fileName.c_str()); _data->finalize(); // compute also orthogonal vector to distance field // A Uortho = -C DIST //------------------------------------------------ if (ortho > 0) { #if defined(HAVE_SOLVER) #ifdef HAVE_TAUCS linearSystemCSRTaucs<double> *lsys2 = new linearSystemCSRTaucs<double>; #else linearSystemCSRGmm<double> *lsys2 = new linearSystemCSRGmm<double>; lsys->setNoisy(1); lsys->setGmres(1); lsys->setPrec(5.e-8); #endif dofManager<double> myAssembler(lsys2); simpleFunction<double> ONE(1.0); double dMax = 1.0; //EMI TO CHANGE std::vector<MElement *> allElems; for(unsigned int ii = 0; ii < _entities.size(); ii++){ if (_entities[ii]->dim() == _maxDim) { GEntity *ge = _entities[ii]; for (unsigned int i=0; i<ge->getNumMeshElements(); ++i) { MElement *t = ge->getMeshElement(i); double vMean = 0.0; for (int k = 0; k < t->getNumVertices(); k++) { std::map<MVertex*, double>::iterator it = _distance_map.find(t->getVertex(k)); vMean += it->second; } vMean /= t->getNumVertices(); if (vMean < dMax) allElems.push_back(ge->getMeshElement(i)); } } } int mid = (int)floor(allElems.size() / 2.); MElement *e = allElems[mid]; MVertex *vFIX = e->getVertex(0); myAssembler.fixVertex(vFIX, 0, 1, 0.0); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ MElement *t = *it; for(int k = 0; k < t->getNumVertices(); k++) myAssembler.numberVertex(t->getVertex(k), 0, 1); } orthogonalTerm *ortho; ortho = new orthogonalTerm(GModel::current(), 1, &ONE, &_distance_map); // if (type < 0) // ortho = new orthogonalTerm(GModel::current(), 1, &ONE, view); // else // ortho = new orthogonalTerm(GModel::current(), 1, &ONE, dofView); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ SElement se((*it)); ortho->addToMatrix(myAssembler, &se); } groupOfElements gr(allElems); ortho->addToRightHandSide(myAssembler, gr); Msg::Info("Orthogonal Computation: Assembly done"); lsys2->systemSolve(); Msg::Info("Orthogonal Computation: System solved"); PView *view2 = new PView(); PViewDataList *data2 = getDataList(view2); data2->setName("ortogonal field"); Msg::Info("Writing orthogonal.pos"); FILE * f5 = Fopen("orthogonal.pos","w"); fprintf(f5,"View \"orthogonal\"{\n"); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ MElement *e = *it; int numNodes = e->getNumVertices(); if (e->getType() == TYPE_POLYG) numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices(); std::vector<double> x(numNodes), y(numNodes), z(numNodes); std::vector<double> *out2 = data2->incrementList(1, e->getType(), numNodes); std::vector<MVertex*> nods; std::vector<double> orth; if(!e->getNumChildren()) for(int i=0; i<numNodes; i++) nods.push_back(e->getVertex(i)); else for(int i = 0; i < e->getNumChildren(); i++) for(int j = 0; j < e->getChild(i)->getNumVertices(); j++) nods.push_back(e->getChild(i)->getVertex(j)); for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->x()); for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->y()); for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->z()); if (_maxDim == 2) switch (numNodes) { case 2: fprintf(f5,"SL("); break; case 3: fprintf(f5,"ST("); break; case 4: fprintf(f5,"SQ("); break; default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break; } else if (_maxDim == 3) switch (numNodes) { case 4: fprintf(f5,"SS("); break; case 8: fprintf(f5,"SH("); break; case 6: fprintf(f5,"SI("); break; case 5: fprintf(f5,"SY("); break; default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break; } for (int j=0; j<numNodes; j++) { MVertex *v = nods[j]; if (j) fprintf(f5, ",%g,%g,%g", v->x(), v->y(), v->z()); else fprintf(f5, "%g,%g,%g", v->x(), v->y(), v->z()); double value; myAssembler.getDofValue(v, 0, 1, value); orth.push_back(value); } fprintf(f5,"){"); for (unsigned int i=0; i<orth.size(); i++) { out2->push_back(orth[i]); if (i) fprintf(f5,",%g", orth[i]); else fprintf(f5,"%g", orth[i]); } fprintf(f5,"};\n"); } fprintf(f5,"};\n"); fclose(f5); lsys->clear(); lsys2->clear(); data2->Time.push_back(0); data2->setFileName("orthogonal.pos"); data2->finalize(); #endif } return view; }
void Filler::print_node(Node* node,std::ofstream& file){ double x,y,z; double x1,y1,z1; double x2,y2,z2; double x3,y3,z3; double x4,y4,z4; double x5,y5,z5; double x6,y6,z6; double h; Metric m; SPoint3 point; point = node->get_point(); x = point.x(); y = point.y(); z = point.z(); h = node->get_size(); m = node->get_metric(); x1 = x + k1*h*m.get_m11(); y1 = y + k1*h*m.get_m21(); z1 = z + k1*h*m.get_m31(); x2 = x - k1*h*m.get_m11(); y2 = y - k1*h*m.get_m21(); z2 = z - k1*h*m.get_m31(); x3 = x + k1*h*m.get_m12(); y3 = y + k1*h*m.get_m22(); z3 = z + k1*h*m.get_m32(); x4 = x - k1*h*m.get_m12(); y4 = y - k1*h*m.get_m22(); z4 = z - k1*h*m.get_m32(); x5 = x + k1*h*m.get_m13(); y5 = y + k1*h*m.get_m23(); z5 = z + k1*h*m.get_m33(); x6 = x - k1*h*m.get_m13(); y6 = y - k1*h*m.get_m23(); z6 = z - k1*h*m.get_m33(); print_segment(SPoint3(x,y,z),SPoint3(x1,y1,z1),file); print_segment(SPoint3(x,y,z),SPoint3(x2,y2,z2),file); print_segment(SPoint3(x,y,z),SPoint3(x3,y3,z3),file); print_segment(SPoint3(x,y,z),SPoint3(x4,y4,z4),file); print_segment(SPoint3(x,y,z),SPoint3(x5,y5,z5),file); print_segment(SPoint3(x,y,z),SPoint3(x6,y6,z6),file); }
SBoundingBox3d GRegionCompound::bounds() const { Msg::Error("Cannot evaluate bounds on GRegion Compound"); return SBoundingBox3d(SPoint3()); }
void Filler::treat_region(GRegion* gr){ int NumSmooth = CTX::instance()->mesh.smoothCrossField; std::cout << "NumSmooth = " << NumSmooth << std::endl ; if(NumSmooth && (gr->dim() == 3)){ double scale = gr->bounds().diag()*1e-2; Frame_field::initRegion(gr,NumSmooth); Frame_field::saveCrossField("cross0.pos",scale); Frame_field::smoothRegion(gr,NumSmooth); Frame_field::saveCrossField("cross1.pos",scale); } #if defined(HAVE_RTREE) unsigned int i; int j; int count; int limit; bool ok2; double x,y,z; SPoint3 point; Node *node,*individual,*parent; MVertex* vertex; MElement* element; MElementOctree* octree; deMeshGRegion deleter; Wrapper wrapper; GFace* gf; std::queue<Node*> fifo; std::vector<Node*> spawns; std::vector<Node*> garbage; std::vector<MVertex*> boundary_vertices; std::set<MVertex*> temp; std::list<GFace*> faces; std::map<MVertex*,int> limits; std::set<MVertex*>::iterator it; std::list<GFace*>::iterator it2; std::map<MVertex*,int>::iterator it3; RTree<Node*,double,3,double> rtree; Frame_field::init_region(gr); Size_field::init_region(gr); Size_field::solve(gr); octree = new MElementOctree(gr->model()); garbage.clear(); boundary_vertices.clear(); temp.clear(); new_vertices.clear(); faces.clear(); limits.clear(); faces = gr->faces(); for(it2=faces.begin();it2!=faces.end();it2++){ gf = *it2; limit = code(gf->tag()); for(i=0;i<gf->getNumMeshElements();i++){ element = gf->getMeshElement(i); for(j=0;j<element->getNumVertices();j++){ vertex = element->getVertex(j); temp.insert(vertex); limits.insert(std::pair<MVertex*,int>(vertex,limit)); } } } /*for(i=0;i<gr->getNumMeshElements();i++){ element = gr->getMeshElement(i); for(j=0;j<element->getNumVertices();j++){ vertex = element->getVertex(j); temp.insert(vertex); } }*/ for(it=temp.begin();it!=temp.end();it++){ if((*it)->onWhat()->dim()==0){ boundary_vertices.push_back(*it); } } for(it=temp.begin();it!=temp.end();it++){ if((*it)->onWhat()->dim()==1){ boundary_vertices.push_back(*it); } } for(it=temp.begin();it!=temp.end();it++){ if((*it)->onWhat()->dim()==2){ boundary_vertices.push_back(*it); } } /*for(it=temp.begin();it!=temp.end();it++){ if((*it)->onWhat()->dim()<3){ boundary_vertices.push_back(*it); } }*/ //std::ofstream file("nodes.pos"); //file << "View \"test\" {\n"; for(i=0;i<boundary_vertices.size();i++){ x = boundary_vertices[i]->x(); y = boundary_vertices[i]->y(); z = boundary_vertices[i]->z(); node = new Node(SPoint3(x,y,z)); compute_parameters(node,gr); node->set_layer(0); it3 = limits.find(boundary_vertices[i]); node->set_limit(it3->second); rtree.Insert(node->min,node->max,node); fifo.push(node); //print_node(node,file); } count = 1; while(!fifo.empty()){ parent = fifo.front(); fifo.pop(); garbage.push_back(parent); if(parent->get_limit()!=-1 && parent->get_layer()>=parent->get_limit()){ continue; } spawns.clear(); spawns.resize(6); for(i=0;i<6;i++){ spawns[i] = new Node(); } create_spawns(gr,octree,parent,spawns); for(i=0;i<6;i++){ ok2 = 0; individual = spawns[i]; point = individual->get_point(); x = point.x(); y = point.y(); z = point.z(); if(inside_domain(octree,x,y,z)){ compute_parameters(individual,gr); individual->set_layer(parent->get_layer()+1); individual->set_limit(parent->get_limit()); if(far_from_boundary(octree,individual)){ wrapper.set_ok(1); wrapper.set_individual(individual); wrapper.set_parent(parent); rtree.Search(individual->min,individual->max,rtree_callback,&wrapper); if(wrapper.get_ok()){ fifo.push(individual); rtree.Insert(individual->min,individual->max,individual); vertex = new MVertex(x,y,z,gr,0); new_vertices.push_back(vertex); ok2 = 1; //print_segment(individual->get_point(),parent->get_point(),file); } } } if(!ok2) delete individual; } if(count%100==0){ printf("%d\n",count); } count++; } //file << "};\n"; int option = CTX::instance()->mesh.algo3d; CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY; deleter(gr); std::vector<GRegion*> regions; regions.push_back(gr); meshGRegion mesher(regions); //? mesher(gr); //? MeshDelaunayVolume(regions); CTX::instance()->mesh.algo3d = option; for(i=0;i<garbage.size();i++) delete garbage[i]; for(i=0;i<new_vertices.size();i++) delete new_vertices[i]; new_vertices.clear(); delete octree; rtree.RemoveAll(); Size_field::clear(); Frame_field::clear(); #endif }
static inline SPoint3 curveGetPoint(Curve *c, int i) { Vertex *v; List_Read(c->Control_Points, i , &v); return SPoint3(v->Pos.X, v->Pos.Y, v->Pos.Z); }
void gmshEdge::discretize(double tol, std::vector<SPoint3> &pts, std::vector<double> &ts) { switch(c->Typ) { case MSH_SEGM_LINE : { int NPt = List_Nbr(c->Control_Points); pts.resize(NPt); ts.resize(NPt); for (int i = 0; i < NPt; ++i) { pts[i]= curveGetPoint(c, i); ts[i] = i / (double) (NPt - 1); } return; } case MSH_SEGM_BEZIER : { int NbCurves = (List_Nbr(c->Control_Points) - 1) / 3; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); SPoint3 pt[4]; for(int i = 0; i < 4; i++) { pt[i] = curveGetPoint(c, iCurve * 3 + i); } std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, pt[0], pt[1], pt[2], pt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } case MSH_SEGM_BSPLN: { bool periodic = (c->end == c->beg); int NbControlPoints = List_Nbr(c->Control_Points); int NbCurves = NbControlPoints + (periodic ? -1 : 1); SPoint3 pt[4]; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); for(int i = 0; i < 4; i++) { int k; if (periodic) { k = (iCurve - 1 + i) % (NbControlPoints - 1); if (k < 0) k += NbControlPoints - 1; } else { k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints -1)); } pt[i] = curveGetPoint(c, k); } SPoint3 bpt[4] = { (pt[0] + pt[1] * 4 + pt[2]) * (1./6.), (pt[1] * 2 + pt[2]) * (1./3.), (pt[1] + pt[2] * 2) * (1./3.), (pt[1] + pt[2] * 4 + pt[3]) * (1./6.) }; std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } case MSH_SEGM_SPLN: { int NbCurves = List_Nbr(c->Control_Points) - 1; SPoint3 pt[4]; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); pt[1] = curveGetPoint(c, iCurve); pt[2] = curveGetPoint(c, iCurve + 1); if(iCurve == 0) { if(c->beg == c->end) pt[0] = curveGetPoint(c, NbCurves - 1); else pt[0] = SPoint3(pt[1] * 2 - pt[2]); } else pt[0] = curveGetPoint(c, iCurve - 1); if(iCurve == NbCurves - 1) { if(c->beg == c->end) pt[3] = curveGetPoint(c, 1); else pt[3] = SPoint3(2 * pt[2] - pt[1]); } else pt[3] = curveGetPoint(c, iCurve + 2); SPoint3 bpt[4] = { pt[1], (pt[1] * 6 + pt[2] - pt[0]) * (1./6.), (pt[2] * 6 - pt[3] + pt[1]) * (1./6.), pt[2] }; std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } default : GEdge::discretize(tol, pts, ts); } }
void Mesh::approximationErrorAndGradients(int iEl, double &f, std::vector<double> &gradF, double eps, simpleFunction<double> &fct) { std::vector<SPoint3> _xyz_temp; for (int iV = 0; iV < nVert(); iV++){ _xyz_temp.push_back(SPoint3( _vert[iV]->x(), _vert[iV]->y(), _vert[iV]->z())); _vert[iV]->setXYZ(_xyz[iV].x(),_xyz[iV].y(),_xyz[iV].z()); } MElement *element = _el[iEl]; f = approximationError (fct, element); // FIME // if (iEl < 1)printf("approx error elem %d = %g\n",iEl,f); int currentId = 0; // compute the size of the gradient // depends on how many dofs exist per vertex (0,1,2 or 3) for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) {// some free coordinates currentId += _nPCFV[_el2FV[iEl][i]]; } } gradF.clear(); gradF.resize(currentId, 0.); currentId = 0; for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) {// some free coordinates MVertex *v = element->getVertex(i); // vertex classified on a model edge if (_nPCFV[_el2FV[iEl][i]] == 1){ double t = _uvw[_el2FV[iEl][i]].x(); GEdge *ge = (GEdge*)v->onWhat(); SPoint3 p (v->x(),v->y(),v->z()); GPoint d = ge->point(t+eps); v->setXYZ(d.x(),d.y(),d.z()); double f_d = approximationError (fct, element); gradF[currentId++] = (f_d-f)/eps; if (iEl < 1)printf("df = %g\n",(f_d-f)/eps); v->setXYZ(p.x(),p.y(),p.z()); } else if (_nPCFV[_el2FV[iEl][i]] == 2){ double uu = _uvw[_el2FV[iEl][i]].x(); double vv = _uvw[_el2FV[iEl][i]].y(); GFace *gf = (GFace*)v->onWhat(); SPoint3 p (v->x(),v->y(),v->z()); GPoint d = gf->point(uu+eps,vv); v->setXYZ(d.x(),d.y(),d.z()); double f_u = approximationError (fct, element); gradF[currentId++] = (f_u-f)/eps; d = gf->point(uu,vv+eps); v->setXYZ(d.x(),d.y(),d.z()); double f_v = approximationError (fct, element); gradF[currentId++] = (f_v-f)/eps; v->setXYZ(p.x(),p.y(),p.z()); // if (iEl < 1)printf("df = %g %g\n",(f_u-f)/eps,(f_v-f)/eps); } } } for (int iV = 0; iV < nVert(); iV++) _vert[iV]->setXYZ(_xyz_temp[iV].x(),_xyz_temp[iV].y(),_xyz_temp[iV].z()); }
PView *GMSH_BubblesPlugin::execute(PView *v) { double shrink = (double)BubblesOptions_Number[0].def; std::string fileName = BubblesOptions_String[0].def; FILE *fp = Fopen(fileName.c_str(), "w"); if(!fp){ Msg::Error("Could not open output file '%s'", fileName.c_str()); return v; } GModel *m = GModel::current(); int p = m->getMaxElementaryNumber(0) + 1; int l = m->getMaxElementaryNumber(1) + 1; int s = m->getMaxElementaryNumber(2) + 1; int ll = s, ps = 1; SBoundingBox3d bbox = m->bounds(); double lc = norm(SVector3(bbox.max(), bbox.min())) / 100; fprintf(fp, "lc = %g;\n", lc); for(GModel::viter vit = m->firstVertex(); vit != m->lastVertex(); vit++) (*vit)->writeGEO(fp, "lc"); for(GModel::eiter eit = m->firstEdge(); eit != m->lastEdge(); eit++) (*eit)->writeGEO(fp); for(GModel::fiter fit = m->firstFace(); fit != m->lastFace(); fit++){ (*fit)->writeGEO(fp); fprintf(fp, "Delete { Surface {%d}; }\n", (*fit)->tag()); int sbeg = s; int llbeg = ll; // compute vertex-to-triangle_barycenter map std::map<MVertex*, std::vector<SPoint3> > v2t; for(unsigned int i = 0; i < (*fit)->triangles.size(); i++) for(int j = 0; j < 3; j++) v2t[(*fit)->triangles[i]->getVertex(j)].push_back((*fit)->triangles[i]->barycenter()); // add boundary vertices in map to get cells "closer" to the boundary for(std::map<MVertex*, std::vector<SPoint3> >::iterator it = v2t.begin(); it != v2t.end(); it++){ MVertex *v = it->first; if(v->onWhat() && v->onWhat()->dim() < 2) it->second.push_back(SPoint3(it->first->x(), it->first->y(), it->first->z())); } for(std::map<MVertex*, std::vector<SPoint3> >::iterator it = v2t.begin(); it != v2t.end(); it++){ if(it->second.size() > 2){ // get barycenter of cell boundary points and order them SPoint3 bc; for(unsigned int i = 0; i < it->second.size(); i++) bc += it->second[i]; bc *= 1. / (double)it->second.size(); compareAngle comp(bc); std::sort(it->second.begin(), it->second.end(), comp); // shrink cells if(shrink){ for(unsigned int i = 0; i < it->second.size(); i++){ double dir[3] = {it->second[i].x() - bc.x(), it->second[i].y() - bc.y(), it->second[i].z() - bc.z()}; it->second[i][0] -= shrink * dir[0]; it->second[i][1] -= shrink * dir[1]; it->second[i][2] -= shrink * dir[2]; } } // create b-spline bounded surface for each cell int nump = it->second.size(); for(int i = 0; i < nump; i++){ SPoint3 &b(it->second[i]); fprintf(fp, "Point(%d) = {%.16g, %.16g, %.16g, lc};\n", p++, b.x(), b.y(), b.z()); } fprintf(fp, "BSpline(%d) = {", l++); for(int i = nump - 1; i >= 0; i--) fprintf(fp, "%d,", p - i - 1); fprintf(fp, "%d};\n", p - nump); fprintf(fp, "Line Loop(%d) = {%d};\n", ll++, l - 1); fprintf(fp, "Plane Surface(%d) = {%d};\n", s++, ll - 1); } } fprintf(fp, "Physical Surface(%d) = {%d:%d};\n", ps++, sbeg, s - 1); fprintf(fp, "Plane Surface(%d) = {%d, %d:%d};\n", s++, (*fit)->tag(), llbeg, ll - 1); fprintf(fp, "Physical Surface(%d) = {%d};\n", ps++, s - 1); } fclose(fp); return v; }