bool Mesh::bndDistAndGradients(int iEl, double &f , std::vector<double> &gradF, double eps) { MElement *element = _el[iEl]; f = 0.; // dommage ;-) if (element->getDim() != 2) return false; int currentId = 0; std::vector<int> vertex2param(element->getNumVertices()); for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) { vertex2param[i] = currentId; currentId += _nPCFV[_el2FV[iEl][i]]; } else vertex2param[i] = -1; } gradF.clear(); gradF.resize(currentId, 0.); const nodalBasis &elbasis = *element->getFunctionSpace(); bool edgeFound = false; for (int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) { int clId = elbasis.getClosureId(iEdge, 1); const std::vector<int> &closure = elbasis.closures[clId]; std::vector<MVertex *> vertices; GEdge *edge = NULL; for (size_t i = 0; i < closure.size(); ++i) { MVertex *v = element->getVertex(closure[i]); vertices.push_back(v); // only valid in 2D if ((int)i >= 2 && v->onWhat() && v->onWhat()->dim() == 1) { edge = v->onWhat()->cast2Edge(); } } if (edge) { edgeFound = true; std::vector<double> localgrad; std::vector<SPoint3> nodes(closure.size()); std::vector<double> params(closure.size()); std::vector<bool> onedge(closure.size()); for (size_t i = 0; i < closure.size(); ++i) { nodes[i] = _xyz[_el2V[iEl][closure[i]]]; onedge[i] = element->getVertex(closure[i])->onWhat() == edge && _el2FV[iEl][closure[i]] >= 0; if (onedge[i]) { params[i] = _uvw[_el2FV[iEl][closure[i]]].x(); }else reparamMeshVertexOnEdge(element->getVertex(closure[i]), edge, params[i]); } f += computeBndDistAndGradient(edge, params, vertices, *BasisFactory::getNodalBasis(elbasis.getClosureType(clId)), nodes, onedge, localgrad, eps); for (size_t i = 0; i < closure.size(); ++i) { if (onedge[i]) gradF[vertex2param[closure[i]]] += localgrad[i]; } } } return edgeFound; }
double elasticitySolver::computeDisplacementError(simpleFunction<double> *f0, simpleFunction<double> *f1, simpleFunction<double> *f2) { std::cout << "compute displacement error" << std::endl; double err = 0.; std::set<MVertex *> v; std::map<MVertex *, MElement *> vCut; for(std::size_t i = 0; i < elasticFields.size(); ++i) { if(elasticFields[i]._e == 0.) continue; for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; if(e->getParent()) { for(std::size_t j = 0; j < e->getNumVertices(); ++j) { if(vCut.find(e->getVertex(j)) == vCut.end()) vCut[e->getVertex(j)] = e->getParent(); } } else { for(std::size_t j = 0; j < e->getNumVertices(); ++j) v.insert(e->getVertex(j)); } } } SolverField<SVector3> Field(pAssembler, LagSpace); for(std::set<MVertex *>::iterator it = v.begin(); it != v.end(); ++it) { SVector3 val; MPoint p(*it); Field.f(&p, 0, 0, 0, val); SVector3 sol((*f0)((*it)->x(), (*it)->y(), (*it)->z()), (*f1)((*it)->x(), (*it)->y(), (*it)->z()), (*f2)((*it)->x(), (*it)->y(), (*it)->z())); double diff = normSq(sol - val); err += diff; } for(std::map<MVertex *, MElement *>::iterator it = vCut.begin(); it != vCut.end(); ++it) { SVector3 val; double uvw[3]; double xyz[3] = {it->first->x(), it->first->y(), it->first->z()}; it->second->xyz2uvw(xyz, uvw); Field.f(it->second, uvw[0], uvw[1], uvw[2], val); SVector3 sol((*f0)(xyz[0], xyz[1], xyz[2]), (*f1)(xyz[0], xyz[1], xyz[2]), (*f2)(xyz[0], xyz[1], xyz[2])); double diff = normSq(sol - val); err += diff; } printf("Displacement Error = %g\n", sqrt(err)); return sqrt(err); }
PView *elasticitySolver::buildDisplacementView(const std::string postFileName) { std::cout << "build Displacement View" << std::endl; std::set<MVertex *> v; std::map<MVertex *, MElement *> vCut; for(std::size_t i = 0; i < elasticFields.size(); ++i) { if(elasticFields[i]._e == 0.) continue; for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; if(e->getParent()) { for(std::size_t j = 0; j < e->getNumVertices(); ++j) { if(vCut.find(e->getVertex(j)) == vCut.end()) vCut[e->getVertex(j)] = e->getParent(); } } else { for(std::size_t j = 0; j < e->getNumVertices(); ++j) v.insert(e->getVertex(j)); } } } std::map<int, std::vector<double> > data; SolverField<SVector3> Field(pAssembler, LagSpace); for(std::set<MVertex *>::iterator it = v.begin(); it != v.end(); ++it) { SVector3 val; MPoint p(*it); Field.f(&p, 0, 0, 0, val); std::vector<double> vec(3); vec[0] = val(0); vec[1] = val(1); vec[2] = val(2); data[(*it)->getNum()] = vec; } for(std::map<MVertex *, MElement *>::iterator it = vCut.begin(); it != vCut.end(); ++it) { SVector3 val; double uvw[3]; double xyz[3] = {it->first->x(), it->first->y(), it->first->z()}; it->second->xyz2uvw(xyz, uvw); Field.f(it->second, uvw[0], uvw[1], uvw[2], val); std::vector<double> vec(3); vec[0] = val(0); vec[1] = val(1); vec[2] = val(2); data[it->first->getNum()] = vec; } PView *pv = new PView(postFileName, "NodeData", pModel, data, 0.0); return pv; }
PView* elasticitySolver::buildLagrangeMultiplierView (const std::string postFileName) { std::cout << "build Lagrange Multiplier View"<< std::endl; if(!LagrangeMultiplierSpace) return new PView(); std::set<MVertex*> v; for (unsigned int i = 0; i < LagrangeMultiplierFields.size(); ++i) { for(groupOfElements::elementContainer::const_iterator it = LagrangeMultiplierFields[i].g->begin(); it != LagrangeMultiplierFields[i].g->end(); ++it) { MElement *e = *it; for (int j = 0; j < e->getNumVertices(); ++j) v.insert(e->getVertex(j)); } } std::map<int, std::vector<double> > data; SolverField<double> Field(pAssembler, LagrangeMultiplierSpace); for(std::set<MVertex*>::iterator it = v.begin(); it != v.end(); ++it) { double val; MPoint p(*it); Field.f(&p, 0, 0, 0, val); std::vector<double> vec; vec.push_back(val); data[(*it)->getNum()] = vec; } PView *pv = new PView (postFileName, "NodeData", pModel, data, 0.0); return pv; }
PView *thermicSolver::buildTemperatureView(const std::string postFileName) { std::cout << "build Temperature View" << std::endl; std::set<MVertex *> v; std::map<MVertex *, MElement *> vCut; for(std::size_t i = 0; i < thermicFields.size(); ++i) { for(groupOfElements::elementContainer::const_iterator it = thermicFields[i].g->begin(); it != thermicFields[i].g->end(); ++it) { MElement *e = *it; if(e->getParent()) { for(std::size_t j = 0; j < e->getNumVertices(); ++j) { if(vCut.find(e->getVertex(j)) == vCut.end()) vCut[e->getVertex(j)] = e->getParent(); } } else { for(std::size_t j = 0; j < e->getNumVertices(); ++j) v.insert(e->getVertex(j)); } } } std::map<int, std::vector<double> > data; SolverField<double> Field(pAssembler, LagSpace); for(std::set<MVertex *>::iterator it = v.begin(); it != v.end(); ++it) { double val; MPoint p(*it); Field.f(&p, 0, 0, 0, val); // printf("valv=%g\n",val); std::vector<double> vec; vec.push_back(val); data[(*it)->getNum()] = vec; } for(std::map<MVertex *, MElement *>::iterator it = vCut.begin(); it != vCut.end(); ++it) { double val; double uvw[3]; double xyz[3] = {it->first->x(), it->first->y(), it->first->z()}; it->second->xyz2uvw(xyz, uvw); Field.f(it->second, uvw[0], uvw[1], uvw[2], val); // printf("valvc=%g\n",val); std::vector<double> vec; vec.push_back(val); data[it->first->getNum()] = vec; } PView *pv = new PView(postFileName, "NodeData", pModel, data, 0.0, 1); return pv; }
double frameFieldBackgroundMesh2D::angle(double u, double v) { MElement *e = const_cast<MElement*>(findElement(u, v)); if (!e) return -1000.0; std::vector<double> val = get_nodal_values(e,angles); std::vector<double> element_uvw = get_element_uvw_from_xyz(e,u,v,0.); std::vector<double> cosvalues(e->getNumVertices()), sinvalues(e->getNumVertices()); for (int i=0; i<e->getNumVertices(); i++) { cosvalues[i]=cos(4*val[i]); sinvalues[i]=sin(4*val[i]); } double cos4 = e->interpolate(&cosvalues[0], element_uvw[0], element_uvw[1], element_uvw[2], 1, order); double sin4 = e->interpolate(&sinvalues[0], element_uvw[0], element_uvw[1], element_uvw[2], 1, order); double a = atan2(sin4,cos4)/4.0; normalizeAngle (a); return a; }
void elasticitySolver::computeEffectiveStiffness(std::vector<double> stiff) { double st[6] = {0., 0., 0., 0., 0., 0.}; double volTot = 0.; for(std::size_t i = 0; i < elasticFields.size(); ++i) { double E = elasticFields[i]._e; double nu = elasticFields[i]._nu; SolverField<SVector3> Field(pAssembler, LagSpace); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double vol = e->getVolume() * e->getVolumeSign(); int nbVertex = e->getNumVertices(); std::vector<SVector3> val(nbVertex); double valx[256]; double valy[256]; double valz[256]; for(int k = 0; k < nbVertex; k++) { MVertex *v = e->getVertex(k); MPoint p(v); Field.f(&p, 0, 0, 0, val[k]); valx[k] = val[k](0); valy[k] = val[k](1); valz[k] = val[k](2); } double gradux[3]; double graduy[3]; double graduz[3]; SPoint3 center = e->barycenterUVW(); double u = center.x(), v = center.y(), w = center.z(); e->interpolateGrad(valx, u, v, w, gradux); e->interpolateGrad(valy, u, v, w, graduy); e->interpolateGrad(valz, u, v, w, graduz); double eps[6] = {gradux[0], graduy[1], graduz[2], 0.5 * (gradux[1] + graduy[0]), 0.5 * (gradux[2] + graduz[0]), 0.5 * (graduy[2] + graduz[1])}; double A = E / (1. + nu); double B = A * (nu / (1. - 2 * nu)); double trace = eps[0] + eps[1] + eps[2]; st[0] += (A * eps[0] + B * trace) * vol; st[1] += (A * eps[1] + B * trace) * vol; st[2] += (A * eps[2] + B * trace) * vol; st[3] += (A * eps[3]) * vol; st[4] += (A * eps[4]) * vol; st[5] += (A * eps[5]) * vol; volTot += vol; } } for(int i = 0; i < 6; i++) stiff[i] = st[i] / volTot; }
void frameFieldBackgroundMesh2D::computeSmoothness() { smoothness.clear(); // build vertex -> neighbors table std::multimap<MVertex*,MVertex*> vertex2vertex; for (std::vector<MElement*>::iterator it = beginelements(); it!=endelements(); it++) { MElement *e = *it; for (int i=0; i<e->getNumVertices(); i++) { MVertex *current = e->getVertex(i); for (int j=0; j<e->getNumVertices(); j++) { if (i==j) continue; MVertex *neighbor = e->getVertex(j); vertex2vertex.insert(make_pair(current,neighbor)); } } } // compute smoothness for (std::vector<MVertex*>::iterator it = beginvertices(); it!=endvertices(); it++) { MVertex *v = *it; double angle_current = angle(v); // compare to all neighbors... std::pair<std::multimap<MVertex*,MVertex*>::iterator, std::multimap<MVertex*,MVertex*>::iterator> range = vertex2vertex.equal_range(v); double minangle,totalangle=0.; int N=0; for (std::multimap<MVertex*,MVertex*>::iterator itneighbor = range.first; itneighbor!=range.second; itneighbor++) { N++; minangle=M_PI/2; MVertex *v_nb = itneighbor->second; double angle_nb = angle(v_nb); // angle comparison... minangle = std::min(minangle, fabs(angle_current-angle_nb)); minangle = std::min(minangle, fabs(angle_current-(angle_nb+M_PI/2.))); minangle = std::min(minangle, fabs(angle_current-(angle_nb-M_PI/2.))); totalangle += minangle; } totalangle /= N; smoothness[v] = 1. - (totalangle/M_PI*2); } }
std::set<MVertex *> BGMBase::get_vertices_of_maximum_dim(int dim) { std::set<MVertex *> bnd_vertices; for(unsigned int i = 0; i < gf->getNumMeshElements(); i++) { MElement *element = gf->getMeshElement(i); for(std::size_t j = 0; j < element->getNumVertices(); j++) { MVertex *vertex = element->getVertex(j); if(vertex->onWhat()->dim() <= dim) bnd_vertices.insert(vertex); } } return bnd_vertices; }
double BGMBase::get_field_value(double u, double v, double w, const DoubleStorageType &data) { // TODO C++11 Remove const_cast MElement *e = const_cast<MElement *>(findElement(u, v, w)); if(!e) return -1000.; std::vector<double> val = get_nodal_values(e, data); std::vector<double> element_uvw = get_element_uvw_from_xyz(e, u, v, w); std::vector<double> values(e->getNumVertices()); for(std::size_t i = 0; i < e->getNumVertices(); i++) values[i] = val[i]; return e->interpolate(&values[0], element_uvw[0], element_uvw[1], element_uvw[2], 1, order); }
std::vector<double> BGMBase::get_field_value(double u, double v, double w, const VectorStorageType &data) { // TODO C++11 remove const_cast and enforce const-correctness otherwise MElement *e = const_cast<MElement *>(findElement(u, v, w)); if(!e) return std::vector<double>(3, -1000.); std::vector<std::vector<double> > val = get_nodal_values(e, data); std::vector<double> element_uvw = get_element_uvw_from_xyz(e, u, v, w); std::vector<double> res(3); for(int j = 0; j < 3; j++) { std::vector<double> values(e->getNumVertices()); for(std::size_t i = 0; i < e->getNumVertices(); i++) { values[i] = val[i][j]; } res[j] = e->interpolate(&values[0], element_uvw[0], element_uvw[1], element_uvw[2], 1, order); } return res; }
PView *elasticitySolver::buildStrainView(const std::string postFileName) { std::cout << "build strain view" << std::endl; std::map<int, std::vector<double> > data; for(std::size_t i = 0; i < elasticFields.size(); ++i) { SolverField<SVector3> Field(pAssembler, LagSpace); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; int nbVertex = e->getNumVertices(); std::vector<SVector3> val(nbVertex); double valx[256]; double valy[256]; double valz[256]; for(int k = 0; k < nbVertex; k++) { MVertex *v = e->getVertex(k); MPoint p(v); Field.f(&p, 0, 0, 0, val[k]); valx[k] = val[k](0); valy[k] = val[k](1); valz[k] = val[k](2); } double gradux[3]; double graduy[3]; double graduz[3]; double u = 0.33, v = 0.33, w = 0.0; e->interpolateGrad(valx, u, v, w, gradux); e->interpolateGrad(valy, u, v, w, graduy); e->interpolateGrad(valz, u, v, w, graduz); std::vector<double> vec(9); vec[0] = gradux[0]; vec[4] = graduy[1]; vec[8] = graduy[2]; vec[1] = vec[3] = 0.5 * (gradux[0] + graduy[1]); vec[2] = vec[6] = 0.5 * (gradux[0] + graduz[2]); vec[5] = vec[7] = 0.5 * (gradux[1] + graduz[2]); data[e->getNum()] = vec; } } PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0); return pv; }
static int getGenus (std::vector<MElement *> &elements, std::vector<std::vector<MEdge> > &boundaries) { //We suppose MElements are simply connected std::set<MEdge, Less_Edge> es; std::set<MVertex*> vs; int N = 0; for(unsigned int i = 0; i < elements.size(); i++){ N++; MElement *e = elements[i]; for(int j = 0; j < e->getNumVertices(); j++){ vs.insert(e->getVertex(j)); } for(int j = 0; j < e->getNumEdges(); j++){ es.insert(e->getEdge(j)); } } int poincare = vs.size() - es.size() + N; //compute connected boundaries int nbBounds = 0; std::vector<MEdge> bEdges; for(unsigned int i = 0; i < elements.size(); i++){ for(int j = 0; j < elements[i]->getNumEdges(); j++){ MEdge me = elements[i]->getEdge(j); if(std::find(bEdges.begin(), bEdges.end(), me) == bEdges.end()) bEdges.push_back(me); else bEdges.erase(std::find(bEdges.begin(), bEdges.end(),me)); } } nbBounds = connected_bounds(bEdges, boundaries); int genus = (int)(-poincare + 2 - nbBounds)/2; //printf("************** partition has %d boundaries and genus =%d \n", nbBounds, genus); return genus; }
static void drawVerticesPerElement(drawContext *ctx, GEntity *e, std::vector<T*> &elements) { for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; for(int j = 0; j < ele->getNumVertices(); j++){ MVertex *v = ele->getVertex(j); // FIXME isElementVisible() can be slow: we should also use a // vertex array for drawing vertices... if(isElementVisible(ele) && v->getVisibility()){ if(CTX::instance()->mesh.points) { if(CTX::instance()->mesh.colorCarousel == 0 || CTX::instance()->mesh.volumesFaces || CTX::instance()->mesh.surfacesFaces){ // by element type if(v->getPolynomialOrder() > 1) glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertexSup); else glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex); } else{ unsigned int col = getColorByEntity(e); glColor4ubv((GLubyte *) & col); } if(CTX::instance()->mesh.pointType) ctx->drawSphere(CTX::instance()->mesh.pointSize, v->x(), v->y(), v->z(), CTX::instance()->mesh.light); else{ glBegin(GL_POINTS); glVertex3d(v->x(), v->y(), v->z()); glEnd(); } } if(CTX::instance()->mesh.pointsNum) drawVertexLabel(ctx, v->onWhat() ? v->onWhat() : e, v); } } } }
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 GMSH_DistancePlugin::printView(std::vector<GEntity*> _entities, std::map<MVertex*, double > _distance_map) { _fileName = DistanceOptions_String[0].def; _minScale = (double) DistanceOptions_Number[4].def; _maxScale = (double) DistanceOptions_Number[5].def; double minDist=1.e4; double maxDist=0.0; for (std::map<MVertex*,double >::iterator itv=_distance_map.begin(); itv != _distance_map.end(); ++itv){ double dist = itv->second; if (dist>maxDist) maxDist = dist; if (dist<minDist) minDist = dist; itv->second = dist; } Msg::Info("Writing %s", _fileName.c_str()); FILE *fName = Fopen(_fileName.c_str(),"w"); fprintf(fName, "View \"distance \"{\n"); for (unsigned int ii=0; ii<_entities.size(); ii++) { if (_entities[ii]->dim() == _maxDim) { for (unsigned int i=0; i<_entities[ii]->getNumMeshElements(); i++) { MElement *e = _entities[ii]->getMeshElement(i); int numNodes = e->getNumVertices(); if (e->getNumChildren()) numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices(); std::vector<double> x(numNodes), y(numNodes), z(numNodes); std::vector<double> *out = _data->incrementList(1, e->getType(), numNodes); std::vector<MVertex*> nods; 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++) out->push_back((nods[nod])->x()); for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->y()); for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->z()); if (_maxDim == 2) switch (numNodes) { case 2: fprintf(fName,"SL("); break; case 3: fprintf(fName,"ST("); break; case 4: fprintf(fName,"SQ("); break; default: Msg::Error("Error in Plugin 'Distance' (numNodes=%d)", numNodes); break; } else if (_maxDim == 3) switch (numNodes) { case 4: fprintf(fName,"SS("); break; case 8: fprintf(fName,"SH("); break; case 6: fprintf(fName,"SI("); break; case 5: fprintf(fName,"SY("); break; default: Msg::Error("Error in Plugin 'Distance' (numNodes=%d)", numNodes); break; } std::vector<double> dist; for (int j=0; j<numNodes; j++) { MVertex *v = nods[j]; if (j) fprintf(fName, ",%.16g,%.16g,%.16g", v->x(), v->y(), v->z()); else fprintf(fName, "%.16g,%.16g,%.16g", v->x(), v->y(), v->z()); std::map<MVertex*, double>::iterator it = _distance_map.find(v); dist.push_back(it->second); } fprintf(fName,"){"); for (unsigned int i=0; i<dist.size(); i++) { if (_minScale>0 && _maxScale>0) dist[i] = _minScale + ((dist[i] - minDist) / (maxDist - minDist)) * (_maxScale - _minScale); else if (_minScale>0 && _maxScale<0) dist[i] = _minScale + dist[i]; out->push_back(dist[i]); if (i) fprintf(fName, ",%.16g", dist[i]); else fprintf(fName, "%.16g", dist[i]); } fprintf(fName,"};\n"); } } } fprintf(fName,"};\n"); fclose(fName); }
PView *elasticitySolver::buildStressesView(const std::string postFileName) { double sti[6] = {0., 0., 0., 0., 0., 0.}; double str[6] = {0., 0., 0., 0., 0., 0.}; double volTot = 0.; std::cout << "build stresses view" << std::endl; std::map<int, std::vector<double> > data; for(std::size_t i = 0; i < elasticFields.size(); ++i) { double E = elasticFields[i]._e; double nu = elasticFields[i]._nu; SolverField<SVector3> Field(pAssembler, LagSpace); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double vol = e->getVolume() * e->getVolumeSign(); int nbVertex = e->getNumVertices(); std::vector<SVector3> val(nbVertex); double valx[256]; double valy[256]; double valz[256]; for(int k = 0; k < nbVertex; k++) { MVertex *v = e->getVertex(k); MPoint p(v); Field.f(&p, 0, 0, 0, val[k]); valx[k] = val[k](0); valy[k] = val[k](1); valz[k] = val[k](2); } double gradux[3]; double graduy[3]; double graduz[3]; SPoint3 center = e->barycenterUVW(); double u = center.x(), v = center.y(), w = center.z(); e->interpolateGrad(valx, u, v, w, gradux); e->interpolateGrad(valy, u, v, w, graduy); e->interpolateGrad(valz, u, v, w, graduz); double eps[6] = {gradux[0], graduy[1], graduz[2], 0.5 * (gradux[1] + graduy[0]), 0.5 * (gradux[2] + graduz[0]), 0.5 * (graduy[2] + graduz[1])}; double A = E / (1. + nu); double B = A * (nu / (1. - 2 * nu)); double trace = eps[0] + eps[1] + eps[2]; double sxx = A * eps[0] + B * trace; double syy = A * eps[1] + B * trace; double szz = A * eps[2] + B * trace; double sxy = A * eps[3]; double sxz = A * eps[4]; double syz = A * eps[5]; std::vector<double> vec(9); vec[0] = sxx; vec[1] = sxy; vec[2] = sxz; vec[3] = sxy; vec[4] = syy; vec[5] = syz; vec[6] = sxz; vec[7] = syz; vec[8] = szz; data[e->getNum()] = vec; for(int k = 0; k < 6; k++) str[k] += eps[k] * vol; sti[0] += sxx * vol; sti[1] += syy * vol; sti[2] += szz * vol; sti[3] += sxy * vol; sti[4] += sxz * vol; sti[5] += syz * vol; volTot += vol; } } for(int i = 0; i < 6; i++) { str[i] = str[i] / volTot; sti[i] = sti[i] / volTot; } printf("effective stiffn = "); for(int i = 0; i < 6; i++) printf("%g ", sti[i]); printf("\n"); printf("effective strain = "); for(int i = 0; i < 6; i++) printf("%g ", str[i]); printf("\n"); PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0); return pv; }
static int getAspectRatio(std::vector<MElement *> &elements, std::vector<std::vector<MEdge> > &boundaries) { double area3D = 0.0; for(unsigned int i = 0; i <elements.size(); ++i){ MElement *t = elements[i]; std::vector<MVertex *> v(3); for(int k = 0; k < 3; k++) v[k] = t->getVertex(k); double p0[3] = {v[0]->x(), v[0]->y(), v[0]->z()}; double p1[3] = {v[1]->x(), v[1]->y(), v[1]->z()}; double p2[3] = {v[2]->x(), v[2]->y(), v[2]->z()}; double a_3D = fabs(triangle_area(p0, p1, p2)); area3D += a_3D; } double tot_length = 0.0; for(unsigned int i = 0; i <boundaries.size(); ++i){ std::vector<MEdge> iBound = boundaries[i]; double iLength = 0.0; for( unsigned int j = 0; j <iBound.size(); ++j){ MVertex *v0 = iBound[j].getVertex(0); MVertex *v1 = iBound[j].getVertex(1); const double length = sqrt((v0->x() - v1->x()) * (v0->x() - v1->x()) + (v0->y() - v1->y()) * (v0->y() - v1->y()) + (v0->z() - v1->z()) * (v0->z() - v1->z())); iLength += length; } tot_length += iLength; } int AR = 1; if (boundaries.size() > 0){ tot_length /= boundaries.size(); AR = (int) ceil(2*3.14*area3D/(tot_length*tot_length)); } //compute AR also with Bounding box std::set<MVertex*> vs; for(unsigned int i = 0; i < elements.size(); i++){ MElement *e = elements[i]; for(int j = 0; j < e->getNumVertices(); j++){ vs.insert(e->getVertex(j)); } } SBoundingBox3d bb; std::vector<SPoint3> vertices; for (std::set<MVertex* >::iterator it = vs.begin(); it != vs.end(); it++){ SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z()); vertices.push_back(pt); bb += pt; } double H = norm(SVector3(bb.max(), bb.min())); //SOrientedBoundingBox obbox = SOrientedBoundingBox::buildOBB(vertices); //double H = obbox.getMaxSize(); double D = H; if (boundaries.size() > 0 ) D = 10e4; for (unsigned int i = 0; i < boundaries.size(); i++){ std::set<MVertex*> vb; std::vector<MEdge> iBound = boundaries[i]; for (unsigned int j = 0; j < iBound.size(); j++){ MEdge e = iBound[j]; vb.insert(e.getVertex(0)); vb.insert(e.getVertex(1)); } std::vector<SPoint3> vBounds; SBoundingBox3d bb; for (std::set<MVertex* >::iterator it = vb.begin(); it != vb.end(); it++){ SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z()); vBounds.push_back(pt); bb +=pt; } double iD = norm(SVector3(bb.max(), bb.min())); D = std::min(D, iD); //SOrientedBoundingBox obboxD = SOrientedBoundingBox::buildOBB(vBounds); //D = std::max(D, obboxD.getMaxSize()); } int AR2 = (int)ceil(H/D); return std::max(AR, AR2); }
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; }
int GModel::writeINP(const std::string &name, bool saveAll, bool saveGroupsOfNodes, double scalingFactor) { FILE *fp = Fopen(name.c_str(), "w"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } if(noPhysicalGroups()) saveAll = true; indexMeshVertices(saveAll); std::vector<GEntity*> entities; getEntities(entities); fprintf(fp, "*Heading\n"); fprintf(fp, " %s\n", name.c_str()); fprintf(fp, "*Node\n"); for(unsigned int i = 0; i < entities.size(); i++) for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++) entities[i]->mesh_vertices[j]->writeINP(fp, scalingFactor); for(viter it = firstVertex(); it != lastVertex(); ++it){ writeElementsINP(fp, *it, (*it)->points, saveAll); } for(eiter it = firstEdge(); it != lastEdge(); ++it){ writeElementsINP(fp, *it, (*it)->lines, saveAll); } for(fiter it = firstFace(); it != lastFace(); ++it){ writeElementsINP(fp, *it, (*it)->triangles, saveAll); writeElementsINP(fp, *it, (*it)->quadrangles, saveAll); } for(riter it = firstRegion(); it != lastRegion(); ++it){ writeElementsINP(fp, *it, (*it)->tetrahedra, saveAll); writeElementsINP(fp, *it, (*it)->hexahedra, saveAll); writeElementsINP(fp, *it, (*it)->prisms, saveAll); writeElementsINP(fp, *it, (*it)->pyramids, saveAll); } std::map<int, std::vector<GEntity*> > groups[4]; getPhysicalGroups(groups); // save elements sets for each physical group for(int dim = 0; dim <= 3; dim++){ for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++){ std::vector<GEntity *> &entities = it->second; fprintf(fp, "*ELSET,ELSET=%s\n", physicalName(this, dim, it->first).c_str()); int n = 0; for(unsigned int i = 0; i < entities.size(); i++){ for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ MElement *e = entities[i]->getMeshElement(j); if(n && !(n % 10)) fprintf(fp, "\n"); fprintf(fp, "%d, ", e->getNum()); n++; } } fprintf(fp, "\n"); } } // save node sets for each physical group if(saveGroupsOfNodes){ for(int dim = 1; dim <= 3; dim++){ for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++){ std::set<MVertex*> nodes; std::vector<GEntity *> &entities = it->second; for(unsigned int i = 0; i < entities.size(); i++){ for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ MElement *e = entities[i]->getMeshElement(j); for (int k = 0; k < e->getNumVertices(); k++) nodes.insert(e->getVertex(k)); } } fprintf(fp, "*NSET,NSET=%s\n", physicalName(this, dim, it->first).c_str()); int n = 0; for(std::set<MVertex*>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++){ if(n && !(n % 10)) fprintf(fp, "\n"); fprintf(fp, "%d, ", (*it2)->getIndex()); n++; } fprintf(fp, "\n"); } } } fclose(fp); return 1; }
int GModel::writeDIFF(const std::string &name, bool binary, bool saveAll, double scalingFactor) { if(binary){ Msg::Error("Binary DIFF output is not implemented"); return 0; } FILE *fp = Fopen(name.c_str(), binary ? "wb" : "w"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } if(noPhysicalGroups()) saveAll = true; // get the number of vertices and index the vertices in a continuous // sequence int numVertices = indexMeshVertices(saveAll); // tag the vertices according to which surface they belong to (Note // that we use a brute force approach here, so that we can deal with // models with incomplete topology. For example, when we merge 2 STL // triangulations we don't have the boundary information between the // faces, and the vertices would end up categorized on either one.) std::vector<std::list<int> > vertexTags(numVertices); std::list<int> boundaryIndicators; for(riter it = firstRegion(); it != lastRegion(); it++){ std::list<GFace*> faces = (*it)->faces(); for(std::list<GFace*>::iterator itf = faces.begin(); itf != faces.end(); itf++){ GFace *gf = *itf; boundaryIndicators.push_back(gf->tag()); for(unsigned int i = 0; i < gf->getNumMeshElements(); i++){ MElement *e = gf->getMeshElement(i); for(int j = 0; j < e->getNumVertices(); j++){ MVertex *v = e->getVertex(j); if(v->getIndex() > 0) vertexTags[v->getIndex() - 1].push_back(gf->tag()); } } } } boundaryIndicators.sort(); boundaryIndicators.unique(); for(int i = 0; i < numVertices; i++){ vertexTags[i].sort(); vertexTags[i].unique(); } // get all the entities in the model std::vector<GEntity*> entities; getEntities(entities); // find max dimension of mesh elements we need to save int dim = 0; for(unsigned int i = 0; i < entities.size(); i++) if(entities[i]->physicals.size() || saveAll) for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++) dim = std::max(dim, entities[i]->getMeshElement(j)->getDim()); // loop over all elements we need to save int numElements = 0, maxNumNodesPerElement = 0; for(unsigned int i = 0; i < entities.size(); i++){ if(entities[i]->physicals.size() || saveAll){ for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ MElement *e = entities[i]->getMeshElement(j); if(e->getStringForDIFF() && e->getDim() == dim){ numElements++; maxNumNodesPerElement = std::max(maxNumNodesPerElement, e->getNumVertices()); } } } } fprintf(fp, "\n\n"); fprintf(fp, " Finite element mesh (GridFE):\n\n"); fprintf(fp, " Number of space dim. = 3\n"); fprintf(fp, " Number of elements = %d\n", numElements); fprintf(fp, " Number of nodes = %d\n\n", numVertices); fprintf(fp, " All elements are of the same type : dpTRUE\n"); fprintf(fp, " Max number of nodes in an element: %d \n", maxNumNodesPerElement); fprintf(fp, " Only one subdomain : dpFALSE\n"); fprintf(fp, " Lattice data ? 0\n\n\n\n"); fprintf(fp, " %d Boundary indicators: ", (int)boundaryIndicators.size()); for(std::list<int>::iterator it = boundaryIndicators.begin(); it != boundaryIndicators.end(); it++) fprintf(fp, " %d", *it); fprintf(fp, "\n\n\n"); fprintf(fp," Nodal coordinates and nodal boundary indicators,\n"); fprintf(fp," the columns contain:\n"); fprintf(fp," - node number\n"); fprintf(fp," - coordinates\n"); fprintf(fp," - no of boundary indicators that are set (ON)\n"); fprintf(fp," - the boundary indicators that are set (ON) if any.\n"); fprintf(fp,"#\n"); // write mesh vertices for(unsigned int i = 0; i < entities.size(); i++){ for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){ MVertex *v = entities[i]->mesh_vertices[j]; if(v->getIndex() > 0){ v->writeDIFF(fp, binary, scalingFactor); fprintf(fp, " [%d] ", (int)vertexTags[v->getIndex() - 1].size()); for(std::list<int>::iterator it = vertexTags[v->getIndex() - 1].begin(); it != vertexTags[v->getIndex() - 1].end(); it++) fprintf(fp," %d ", *it); fprintf(fp,"\n"); } } } fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, " Element types and connectivity\n"); fprintf(fp, " the columns contain:\n"); fprintf(fp, " - element number\n"); fprintf(fp, " - element type\n"); fprintf(fp, " - subdomain number \n"); fprintf(fp, " - the global node numbers of the nodes in the element.\n"); fprintf(fp, "#\n"); // write mesh elements int num = 0; for(unsigned int i = 0; i < entities.size(); i++){ if(entities[i]->physicals.size() || saveAll){ for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ MElement *e = entities[i]->getMeshElement(j); if(e->getStringForDIFF() && e->getDim() == dim) e->writeDIFF(fp, ++num, binary, entities[i]->tag()); } } } fprintf(fp, "\n"); fclose(fp); return 1; }
// This function meshes the top surface of a QuadToTri extrusion. It returns 0 if it is given a // non-quadToTri extrusion or if it fails. // Args: // 'GFace *to' is the top surface to mesh, 'from' is the source surface, 'pos' is a std::set // of vertex positions for the top surface. int MeshQuadToTriTopSurface( GFace *from, GFace *to, std::set<MVertex*, MVertexLessThanLexicographic> &pos ) { if( !to->meshAttributes.extrude || !to->meshAttributes.extrude->mesh.QuadToTri ) return 0; // if the source is all triangles, then just let this function is not needed. Return 1. if( from->triangles.size() && !from->quadrangles.size() ) return 1; // in weird case of NO quads and NO tri if( !from->triangles.size() && !from->quadrangles.size() ) return 0; ExtrudeParams *ep = to->meshAttributes.extrude; if( !ep || !ep->mesh.ExtrudeMesh || !(ep->geo.Mode == COPIED_ENTITY) ){ Msg::Error("In MeshQuadToTriTopSurface(), incomplete or no " "extrude information for top face %d.", to->tag() ); return 0; } // is this a quadtri extrusion with added vertices? bool is_addverts = false; if( ep && (ep->mesh.QuadToTri == QUADTRI_ADDVERTS_1 || ep->mesh.QuadToTri == QUADTRI_ADDVERTS_1_RECOMB) ) is_addverts = true; // execute this section if // IF this is a 'no new vertices' quadToTri, mesh the surfaces according to this modified // least point value method: if a 3 boundary point quad, draw diagonals from middle corner toward // interior. If a a 2- or 1- point boundary quad, draw toward lowest pointer number NOT on boundary. // All interior quad, draw diagonal to vertex with lowest pointer number. if( !is_addverts ){ std::set<MVertex*, MVertexLessThanLexicographic> pos_src_edge; QuadToTriInsertFaceEdgeVertices(from, pos_src_edge); std::set<MVertex*, MVertexLessThanLexicographic>::iterator itp; // loop through each element source quadrangle and extrude for(unsigned int i = 0; i < from->quadrangles.size(); i++){ std::vector<MVertex*> verts; for(int j = 0; j < from->quadrangles[i]->getNumVertices(); j++){ MVertex *v = from->quadrangles[i]->getVertex(j); MVertex tmp(v->x(), v->y(), v->z(), 0, -1); ExtrudeParams *ep = to->meshAttributes.extrude; ep->Extrude(ep->mesh.NbLayer - 1, ep->mesh.NbElmLayer[ep->mesh.NbLayer - 1], tmp.x(), tmp.y(), tmp.z()); itp = pos.find(&tmp); if(itp == pos.end()){ // FIXME: workaround Msg::Info("Linear search for (%.16g, %.16g, %.16g)", tmp.x(), tmp.y(), tmp.z()); itp = tmp.linearSearch(pos); } if(itp == pos.end()) { Msg::Error("In MeshQuadToTriTopSurface(), Could not find " "extruded vertex (%.16g, %.16g, %.16g) in surface %d", tmp.x(), tmp.y(), tmp.z(), to->tag()); to->triangles.reserve(to->triangles.size()+1); return 0; } verts.push_back(*itp); } if( verts.size() != 4 ){ Msg::Error("During mesh of QuadToTri surface %d, %d vertices found " "in quad of source surface %d.", to->tag(), verts.size(), from->tag() ); return 0; } // make the element MElement *element = from->quadrangles[i]; // count vertices that are on a boundary edge int edge_verts_count = 0; //int skip_index = 0; int bnd_indices[4]; for( int p = 0; p < element->getNumVertices(); p++ ){ if( pos_src_edge.find( element->getVertex(p) ) != pos_src_edge.end() ){ edge_verts_count++; bnd_indices[p] = 1; } else{ //skip_index = p; bnd_indices[p] = 0; } } // Apply modified lowest vertex pointer diagonalization int low_index = -1; if( edge_verts_count == 3 || edge_verts_count == 2 || edge_verts_count == 1 ){ for( int p = 0; p < 4; p++ ){ if( !bnd_indices[p] && verts[p] != element->getVertex(p) ){ if( low_index < 0 ) low_index = p; else if( verts[p] < verts[low_index] ) low_index = p; } } if( low_index < 0 ) // what if they are all degenerate? Avoid the out-of-bounds error. low_index = 0; } // lowest possible vertex pointer, regardless of if on edge or not else if( edge_verts_count == 4 || edge_verts_count == 0 ) low_index = getIndexForLowestVertexPointer(verts); addTriangle( verts[low_index],verts[(low_index+1)%verts.size()], verts[(low_index+2)%verts.size()],to); addTriangle( verts[low_index],verts[(low_index+2)%verts.size()], verts[(low_index+3)%verts.size()],to); } return 1; } // AFTER THIS POINT IN FUNCTION, CODE IS ALL FOR 'ADD INTERNAL VERTEX' EXTRUSIONS (Less restrictive). // if source face is unstructured, can try to make the top mesh a little neater GFace *root_source = findRootSourceFaceForFace( from ); ExtrudeParams *ep_src = root_source->meshAttributes.extrude; bool struct_root = false; if( root_source && ( (ep_src && ep_src->mesh.ExtrudeMesh && ep_src->geo.Mode == EXTRUDED_ENTITY) || root_source->meshAttributes.method == MESH_TRANSFINITE ) ) struct_root = true; if( !struct_root && MeshQuadToTriTopUnstructured(from, to, pos) ) return 1; // And top surface for the 'added internal vertex' method can be meshed quite easily else{ std::set<MVertex *, MVertexLessThanLexicographic >::iterator itp; // loop through each element source quadrangle and extrude for(unsigned int i = 0; i < from->quadrangles.size(); i++){ std::vector<MVertex*> verts; for(int j = 0; j < from->quadrangles[i]->getNumVertices(); j++){ MVertex *v = from->quadrangles[i]->getVertex(j); MVertex tmp(v->x(), v->y(), v->z(), 0, -1); ExtrudeParams *ep = to->meshAttributes.extrude; ep->Extrude(ep->mesh.NbLayer - 1, ep->mesh.NbElmLayer[ep->mesh.NbLayer - 1], tmp.x(), tmp.y(), tmp.z()); itp = pos.find(&tmp); if(itp == pos.end()){ // FIXME: workaround Msg::Info("Linear search for (%.16g, %.16g, %.16g)", tmp.x(), tmp.y(), tmp.z()); itp = tmp.linearSearch(pos); } if(itp == pos.end()) { Msg::Error("In MeshQuadToTriTopSurface(), Could not find " "extruded vertex (%.16g, %.16g, %.16g) in surface %d", tmp.x(), tmp.y(), tmp.z(), to->tag()); to->triangles.reserve(to->triangles.size()+1); return 0; } verts.push_back(*itp); } if( verts.size() != 4 ){ Msg::Error("During mesh of QuadToTri surface %d, %d vertices found " "in quad of source surface %d.", to->tag(), verts.size(), from->tag() ); return 0; } // make the elements addTriangle( verts[0],verts[2], verts[3],to); addTriangle( verts[0],verts[1], verts[2],to); } return 1; } return 0; }
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 }
int GModel::readPLY(const std::string &name) { // this is crazy!? replaceCommaByDot(name); FILE *fp = Fopen(name.c_str(), "r"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } std::vector<MVertex*> vertexVector; std::map<int, std::vector<MElement*> > elements[5]; std::map<int, std::vector<double> > properties; char buffer[256], str[256], str2[256], str3[256]; std::string s1; int elementary = getMaxElementaryNumber(-1) + 1; int nbv = 0, nbf = 0; int nbprop = 0; int nbView = 0; std::vector<std::string> propName; while(!feof(fp)) { if(!fgets(buffer, sizeof(buffer), fp)) break; if(buffer[0] != '#'){ // skip comments sscanf(buffer, "%s %s", str, str2); if(!strcmp(str, "element") && !strcmp(str2, "vertex")){ sscanf(buffer, "%s %s %d", str, str2, &nbv); } if(!strcmp(str, "format") && strcmp(str2, "ascii")){ Msg::Error("Only reading of ascii PLY files implemented"); fclose(fp); return 0; } if(!strcmp(str, "property") && strcmp(str2, "list")){ nbprop++; sscanf(buffer, "%s %s %s", str, str2, str3); if (nbprop > 3) propName.push_back(s1+str3); } if(!strcmp(str, "element") && !strcmp(str2, "face")){ sscanf(buffer, "%s %s %d", str, str2, &nbf); } if(!strcmp(str, "end_header")){ nbView = nbprop -3; Msg::Info("%d elements", nbv); Msg::Info("%d triangles", nbf); Msg::Info("%d properties", nbView); vertexVector.resize(nbv); for(int i = 0; i < nbv; i++) { double x,y,z; char line[10000], *pEnd, *pEnd2, *pEnd3; if(!fgets(line, sizeof(line), fp)){ fclose(fp); return 0; } x = strtod(line, &pEnd); y = strtod(pEnd, &pEnd2); z = strtod(pEnd2, &pEnd3); vertexVector[i] = new MVertex(x, y, z); pEnd = pEnd3; std::vector<double> prop(nbView); for (int k = 0; k < nbView; k++){ prop[k]=strtod(pEnd, &pEnd2); pEnd = pEnd2; properties[k].push_back(prop[k]); } } for(int i = 0; i < nbf; i++) { if(!fgets(buffer, sizeof(buffer), fp)) break; int n[3], nbe; sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]); std::vector<MVertex*> vertices; if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; } elements[0][elementary].push_back(new MTriangle(vertices)); } } } } for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++) _storeElementsInEntities(elements[i]); _associateEntityWithMeshVertices(); _storeVerticesInEntities(vertexVector); #if defined(HAVE_POST) // create PViews here std::vector<GEntity*> _entities; getEntities(_entities); for (int iV=0; iV< nbView; iV++){ PView *view = new PView(); PViewDataList *data = dynamic_cast<PViewDataList*>(view->getData()); for(unsigned int ii = 0; ii < _entities.size(); ii++){ for(unsigned int i = 0; i < _entities[ii]->getNumMeshElements(); i++){ MElement *e = _entities[ii]->getMeshElement(i); int numNodes = e->getNumVertices(); std::vector<double> x(numNodes), y(numNodes), z(numNodes); std::vector<double> *out = data->incrementList(1, e->getType()); for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->x()); for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->y()); for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->z()); std::vector<double> props; int n[3]; n[0] = e->getVertex(0)->getNum()-1; n[1] = e->getVertex(1)->getNum()-1; n[2] = e->getVertex(2)->getNum()-1; if(!getProperties(3, n, properties[iV], props)){ fclose(fp); return 0; } for(int nod = 0; nod < numNodes; nod++) out->push_back(props[nod]); } } data->setName(propName[iV]); data->Time.push_back(0); data->setFileName("property.pos"); data->finalize(); } #endif fclose(fp); return 1; }
bool Filler3D::treat_region(GRegion *gr) { BGMManager::set_use_cross_field(true); bool use_vectorial_smoothness; bool use_fifo; string algo; // readValue("param.dat","SMOOTHNESSALGO",algo); algo.assign("SCALAR"); if (!algo.compare("SCALAR")){ use_vectorial_smoothness = false; use_fifo = false; } else if (!algo.compare("FIFO")){ use_vectorial_smoothness = false; use_fifo = true; } else{ cout << "unknown SMOOTHNESSALGO !" << endl; throw; } const bool debug=false; const bool export_stuff=true; double a; cout << "ENTERING POINTINSERTION3D" << endl; // acquire background mesh cout << "pointInsertion3D: recover BGM" << endl; a = Cpu(); frameFieldBackgroundMesh3D *bgm = dynamic_cast<frameFieldBackgroundMesh3D*>(BGMManager::get(gr)); time_smoothing += (Cpu() - a); if (!bgm){ cout << "pointInsertion3D:: BGM dynamic cast failed ! " << endl; throw; } // export BGM fields if(export_stuff){ cout << "pointInsertion3D: export size field " << endl; stringstream ss; ss << "bg3D_sizefield_" << gr->tag() << ".pos"; bgm->exportSizeField(ss.str()); cout << "pointInsertion3D : export crossfield " << endl; stringstream sscf; sscf << "bg3D_crossfield_" << gr->tag() << ".pos"; bgm->exportCrossField(sscf.str()); cout << "pointInsertion3D : export smoothness " << endl; stringstream sss; sss << "bg3D_smoothness_" << gr->tag() << ".pos"; bgm->exportSmoothness(sss.str()); if (use_vectorial_smoothness){ cout << "pointInsertion3D : export vectorial smoothness " << endl; stringstream ssvs; ssvs << "bg3D_vectorial_smoothness_" << gr->tag() << ".pos"; bgm->exportVectorialSmoothness(ssvs.str()); } } // ---------------- START FILLING NEW POINTS ---------------- cout << "pointInsertion3D : inserting points in region " << gr->tag() << endl; //ProfilerStart("/home/bernard/profile"); a = Cpu(); // ----- initialize fifo list ----- RTree<MVertex*,double,3,double> rtree; listOfPoints *fifo; if (use_fifo) fifo = new listOfPointsFifo(); else if (use_vectorial_smoothness) fifo = new listOfPointsVectorialSmoothness(); else fifo = new listOfPointsScalarSmoothness(); set<MVertex*> temp; vector<MVertex*> boundary_vertices; map<MVertex*,int> vert_priority; map<MVertex*,double> smoothness_forplot; MElement *element; MVertex *vertex; list<GFace*> faces = gr->faces(); for(list<GFace*>::iterator it=faces.begin();it!=faces.end();it++){// for all faces GFace *gf = *it; // int limit = code_kesskessai(gf->tag()); for(unsigned int i=0;i<gf->getNumMeshElements();i++){ element = gf->getMeshElement(i); for(int j=0;j<element->getNumVertices();j++){// for all vertices vertex = element->getVertex(j); temp.insert(vertex); // limits.insert(make_pair(vertex,limit)); } } } int geodim; for(set<MVertex*>::iterator it=temp.begin();it!=temp.end();it++){ geodim = (*it)->onWhat()->dim(); if ((geodim==0) || (geodim==1) || (geodim==2)) boundary_vertices.push_back(*it); } double min[3],max[3],x,y,z,h; for(unsigned int i=0;i<boundary_vertices.size();i++){ x = boundary_vertices[i]->x(); y = boundary_vertices[i]->y(); z = boundary_vertices[i]->z(); // "on boundary since working on boundary_vertices ... MVertex *closest = bgm->get_nearest_neighbor_on_boundary(boundary_vertices[i]); h = bgm->size(closest);// get approximate size, closest vertex, faster ?! fill_min_max(x,y,z,h,min,max); rtree.Insert(min,max,boundary_vertices[i]); if (!use_vectorial_smoothness){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = boundary_vertices[i]; svp->rank = bgm->get_smoothness(x,y,z); svp->dir = 0; svp->layer = 0; svp->size = h; bgm->eval_approximate_crossfield(closest, svp->cf); fifo->insert(svp); if (debug){ smoothness_forplot[svp->v] = svp->rank; } } else{ STensor3 temp; bgm->eval_approximate_crossfield(closest, temp); for (int idir=0;idir<3;idir++){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = boundary_vertices[i]; svp->rank = bgm->get_vectorial_smoothness(idir,x,y,z); svp->dir = idir; svp->layer = 0; svp->size = h; svp->cf = temp; for (int k=0;k<3;k++) svp->direction(k) = temp(k,idir); // cout << "fifo size=" << fifo->size() << " inserting " ; fifo->insert(svp); // cout << " -> fifo size=" << fifo->size() << endl; } } } // TODO: si fifo était list of *PTR -> pas de copies, gain temps ? Wrapper3D wrapper; wrapper.set_bgm(bgm); MVertex *parent,*individual; new_vertices.clear(); bool spawn_created; int priority_counter=0; STensor3 crossfield; int parent_layer; while(!fifo->empty()){ parent = fifo->get_first_vertex(); // parent_limit = fifo->get_first_limit(); parent_layer = fifo->get_first_layer(); // if(parent_limit!=-1 && parent_layer>=parent_limit()){ // continue; // } vector<MVertex*> spawns; if (!use_vectorial_smoothness){ spawns.resize(6); computeSixNeighbors(bgm,parent,spawns,fifo->get_first_crossfield(), fifo->get_first_size()); } else{ spawns.resize(2); computeTwoNeighbors(bgm,parent,spawns,fifo->get_first_direction(), fifo->get_first_size()); } fifo->erase_first(); // cout << "while, fifo->size()=" << fifo->size() << " parent=(" << // parent->x() << "," << parent->y() << "," << parent->z() << ")" << // endl; for(unsigned int i=0;i<spawns.size();i++){ spawn_created = false; individual = spawns[i]; x = individual->x(); y = individual->y(); z = individual->z(); // cout << " working on candidate " << "(" << individual->x() << "," // << individual->y() << "," << individual->z() << ")" << endl; if(bgm->inDomain(x,y,z)){ // cout << " spawn " << i << " in domain" << endl; MVertex *closest = bgm->get_nearest_neighbor(individual); h = bgm->size(closest);// get approximate size, closest vertex, faster ?! if(far_from_boundary_3D(bgm,individual,h)){ // cout << " spawn " << i << " far from bnd" << endl; bgm->eval_approximate_crossfield(closest, crossfield); wrapper.set_ok(true); wrapper.set_individual(individual); wrapper.set_parent(parent); wrapper.set_size(&h); wrapper.set_crossfield(&crossfield); fill_min_max(x,y,z,h,min,max); rtree.Search(min,max,rtree_callback_3D,&wrapper); if(wrapper.get_ok()){ // cout << " spawn " << i << " wrapper OK" << endl; if (!use_vectorial_smoothness){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = individual; svp->rank=bgm->get_smoothness(individual->x(),individual->y(),individual->z()); svp->dir = 0; svp->layer = parent_layer+1; svp->size = h; svp->cf = crossfield; fifo->insert(svp); if (debug){ smoothness_forplot[svp->v] = svp->rank; vert_priority[individual] = priority_counter++; } } else{ if (debug) vert_priority[individual] = priority_counter++; for (int idir=0;idir<3;idir++){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = individual; svp->rank = bgm->get_vectorial_smoothness(idir,x,y,z); svp->dir = idir; svp->layer = parent_layer+1; svp->size = h; for (int k=0;k<3;k++) svp->direction(k) = crossfield(k,idir); svp->cf = crossfield; fifo->insert(svp); } } rtree.Insert(min,max,individual); new_vertices.push_back(individual); spawn_created = true; } } } if(!spawn_created){ delete individual; } }// end loop on spawns } //ProfilerStop(); time_insert_points += (Cpu() - a); // --- output --- if (debug){ stringstream ss; ss << "priority_3D_" << gr->tag() << ".pos"; print_nodal_info(ss.str().c_str(),vert_priority); ss.clear(); stringstream sss; sss << "smoothness_3D_" << gr->tag() << ".pos"; print_nodal_info(sss.str().c_str(),smoothness_forplot); sss.clear(); } // ------- meshing using new points cout << "tets in gr before= " << gr->tetrahedra.size() << endl; cout << "nb new vertices= " << new_vertices.size() << endl; a=Cpu(); int option = CTX::instance()->mesh.algo3d; CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY; deMeshGRegion deleter; deleter(gr); std::vector<GRegion*> regions; regions.push_back(gr); meshGRegion mesher(regions); //? mesher(gr); //? MeshDelaunayVolume(regions); time_meshing += (Cpu() - a); cout << "tets in gr after= " << gr->tetrahedra.size() << endl; cout << "gr tag=" << gr->tag() << endl; CTX::instance()->mesh.algo3d = option; delete fifo; for(unsigned int i=0;i<new_vertices.size();i++) delete new_vertices[i]; new_vertices.clear(); rtree.RemoveAll(); return true; }
int GModel::writeKEY(const std::string &name, int saveAll, int saveGroupsOfNodes, double scalingFactor) { FILE *fp = Fopen(name.c_str(), "w"); if(!fp) { Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } if(noPhysicalGroups()) saveAll = 0x51; indexMeshVertices(saveAll & 0x51); std::vector<GEntity *> entities; getEntities(entities); fprintf(fp, "$# LS-DYNA Keyword file created by Gmsh\n*KEYWORD\n*TITLE\n"); fprintf(fp, " %s\n", name.c_str()); fprintf(fp, "*NODE\n"); for(std::size_t i = 0; i < entities.size(); i++) for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++) entities[i]->mesh_vertices[j]->writeKEY(fp, scalingFactor); if(!(saveAll & 0x2)) // save or ignore Vertex, not in GUI for(viter it = firstVertex(); it != lastVertex(); ++it) { writeElementsKEY(fp, *it, (*it)->points, saveAll & 0x1); } if(!(saveAll & 0x8)) // save or ignore line for(eiter it = firstEdge(); it != lastEdge(); ++it) { writeElementsKEY(fp, *it, (*it)->lines, saveAll & 0x4); } if(!(saveAll & 0x20)) // save or ignore surface for(fiter it = firstFace(); it != lastFace(); ++it) { writeElementsKEY(fp, *it, (*it)->triangles, saveAll & 0x10); writeElementsKEY(fp, *it, (*it)->quadrangles, saveAll & 0x10); } if(!(saveAll & 0x80)) // save or ignore surface for(riter it = firstRegion(); it != lastRegion(); ++it) { writeElementsKEY(fp, *it, (*it)->tetrahedra, saveAll & 0x40); writeElementsKEY(fp, *it, (*it)->hexahedra, saveAll & 0x40); writeElementsKEY(fp, *it, (*it)->prisms, saveAll & 0x40); writeElementsKEY(fp, *it, (*it)->pyramids, saveAll & 0x40); } std::map<int, std::vector<GEntity *> > groups[4]; getPhysicalGroups(groups); int setid = 0; // save elements sets for each physical group if(saveGroupsOfNodes & 0x2) { for(int dim = 0; dim <= 3; dim++) { if(saveAll & (0x2 << (2 * dim))) continue; // elements are ignored for(std::map<int, std::vector<GEntity *> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++) { std::vector<GEntity *> &entities = it->second; int n = 0; for(std::size_t i = 0; i < entities.size(); i++) { for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) { MElement *e = entities[i]->getMeshElement(j); if(!n) { const char *str = (e->getDim() == 3) ? "SOLID" : (e->getDim() == 2) ? "SHELL" : (e->getDim() == 1) ? "BEAM" : "NODE"; fprintf(fp, "*SET_%s_LIST\n$# %s\n%d", str, physicalName(this, dim, it->first).c_str(), ++setid); } if(!(n % 8)) fprintf(fp, "\n%lu", e->getNum()); else fprintf(fp, ", %lu", e->getNum()); n++; } } if(n) fprintf(fp, "\n"); } } } // save node sets for each physical group, for easier load/b.c. if(saveGroupsOfNodes & 0x1) { for(int dim = 1; dim <= 3; dim++) { for(std::map<int, std::vector<GEntity *> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++) { std::set<MVertex *> nodes; std::vector<GEntity *> &entities = it->second; for(std::size_t i = 0; i < entities.size(); i++) { for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) { MElement *e = entities[i]->getMeshElement(j); for(std::size_t k = 0; k < e->getNumVertices(); k++) nodes.insert(e->getVertex(k)); } } fprintf(fp, "*SET_NODE_LIST\n$# %s\n%d", physicalName(this, dim, it->first).c_str(), ++setid); int n = 0; for(std::set<MVertex *>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++) { if(!(n % 8)) fprintf(fp, "\n%ld", (*it2)->getIndex()); else fprintf(fp, ", %ld", (*it2)->getIndex()); n++; } if(n) fprintf(fp, "\n"); } } } fprintf(fp, "*END\n"); fclose(fp); return 1; }
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()); }