static void drawElementLabels(drawContext *ctx, GEntity *e, std::vector<T*> &elements, int forceColor=0, unsigned int color=0) { unsigned col = forceColor ? color : getColorByEntity(e); glColor4ubv((GLubyte *) & col); int labelStep = CTX::instance()->mesh.labelSampling; if(labelStep <= 0) labelStep = 1; for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; if(!isElementVisible(ele)) continue; if(i % labelStep == 0) { SPoint3 pc = ele->barycenter(); char str[256]; if(CTX::instance()->mesh.labelType == 4) sprintf(str, "(%g,%g,%g)", pc.x(), pc.y(), pc.z()); else if(CTX::instance()->mesh.labelType == 3) sprintf(str, "%d", ele->getPartition()); else if(CTX::instance()->mesh.labelType == 2){ int np = e->physicals.size(); int p = np ? e->physicals[np - 1] : 0; sprintf(str, "%d", p); } else if(CTX::instance()->mesh.labelType == 1) sprintf(str, "%d", e->tag()); else sprintf(str, "%d", ele->getNum()); glRasterPos3d(pc.x(), pc.y(), pc.z()); ctx->drawString(str); } } }
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 *elasticitySolver::buildElasticEnergyView(const std::string postFileName) { std::cout << "build Elastic Energy View"<< std::endl; std::map<int, std::vector<double> > data; GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad); for (unsigned int i = 0; i < elasticFields.size(); ++i) { if(elasticFields[i]._E == 0.) continue; SolverField<SVector3> Field(pAssembler, LagSpace); IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu); BilinearTermToScalarTerm Elastic_Energy_Term(Eterm); ScalarTermConstant<double> One(1.0); for (groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double energ; double vol; IntPt *GP; int npts=Integ_Bulk.getIntPoints(e,&GP); Elastic_Energy_Term.get(e,npts,GP,energ); One.get(e,npts,GP,vol); std::vector<double> vec; vec.push_back(energ/vol); data[e->getNum()]=vec; } } PView *pv = new PView (postFileName, "ElementData", pModel, data, 0.0); return pv; }
static void calcVertex2Elements(int dim, GEntity *entity, vertElVecMap &vertex2elements) { for (size_t i = 0; i < entity->getNumMeshElements(); ++i) { MElement *element = entity->getMeshElement(i); if (element->getDim() == dim) for (int j = 0; j < element->getNumPrimaryVertices(); ++j) vertex2elements[element->getVertex(j)].push_back(element); } }
static void getBoundaryFromMesh(GModel *m, int visible) { int dim = m->getDim(); std::vector<GEntity*> entities; m->getEntities(entities); std::set<MFace, Less_Face> bndFaces; std::set<MEdge, Less_Edge> bndEdges; for(unsigned int i = 0; i < entities.size(); i++){ GEntity *ge = entities[i]; if(ge->dim() != dim) continue; if(visible && !ge->getVisibility()) continue; for(unsigned int j = 0; j < ge->getNumMeshElements(); j++){ MElement *e = ge->getMeshElement(j); if(dim == 2){ for(int i = 0; i < e->getNumEdges(); i++){ MEdge f = e->getEdge(i); if(bndEdges.find(f) == bndEdges.end()) bndEdges.insert(f); else bndEdges.erase(f); } } else if(dim == 3){ for(int i = 0; i < e->getNumFaces(); i++){ MFace f = e->getFace(i); if(bndFaces.find(f) == bndFaces.end()) bndFaces.insert(f); else bndFaces.erase(f); } } } } if(dim == 2){ discreteEdge *e = new discreteEdge(m, m->getMaxElementaryNumber(1) + 1, 0, 0); m->add(e); for(std::set<MEdge, Less_Edge>::iterator it = bndEdges.begin(); it != bndEdges.end(); it++){ e->lines.push_back(new MLine(it->getVertex(0), it->getVertex(1))); } } else if(dim == 3){ discreteFace *f = new discreteFace(m, m->getMaxElementaryNumber(2) + 1); m->add(f); for(std::set<MFace, Less_Face>::iterator it = bndFaces.begin(); it != bndFaces.end(); it++){ if(it->getNumVertices() == 3) f->triangles.push_back(new MTriangle(it->getVertex(0), it->getVertex(1), it->getVertex(2))); else if(it->getNumVertices() == 4) f->quadrangles.push_back(new MQuadrangle(it->getVertex(0), it->getVertex(1), it->getVertex(2), it->getVertex(3))); } } }
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; }
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; }
static void _relocateVertexOfPyramid(MVertex *ver, const std::vector<MElement *> <, double relax) { if(ver->onWhat()->dim() != 3) return; double x = 0.0, y = 0.0, z = 0.0; int N = 0; MElement *pyramid = NULL; for(std::size_t i = 0; i < lt.size(); i++) { double XCG = 0.0, YCG = 0.0, ZCG = 0.0; if(lt[i]->getNumVertices() == 5) pyramid = lt[i]; else { for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) { XCG += lt[i]->getVertex(j)->x(); YCG += lt[i]->getVertex(j)->y(); ZCG += lt[i]->getVertex(j)->z(); } x += XCG; y += YCG; z += ZCG; N += lt[i]->getNumVertices(); } } x /= N; y /= N; z /= N; if(pyramid) { MFace q = pyramid->getFace(4); double A = q.approximateArea(); SVector3 n = q.normal(); n.normalize(); SPoint3 c = q.barycenter(); SVector3 d(x - c.x(), y - c.y(), z - c.z()); if(dot(n, d) < 0) n = n * (-1.0); double H = .5 * sqrt(fabs(A)); double XOPT = c.x() + relax * H * n.x(); double YOPT = c.y() + relax * H * n.y(); double ZOPT = c.z() + relax * H * n.z(); double FULL_MOVE_OBJ = objective_function(1.0, ver, XOPT, YOPT, ZOPT, lt, true); // printf("relax %g obj %g\n",relax,FULL_MOVE_OBJ); if(FULL_MOVE_OBJ > 0.1) { ver->x() = XOPT; ver->y() = YOPT; ver->z() = ZOPT; return; } } }
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); }
static void drawTangents(drawContext *ctx, std::vector<T*> &elements) { glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.tangents); for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; if(!isElementVisible(ele)) continue; SVector3 t = ele->getEdge(0).tangent(); for(int j = 0; j < 3; j++) t[j] *= CTX::instance()->mesh.tangents * ctx->pixel_equiv_x / ctx->s[j]; SPoint3 pc = ele->barycenter(); ctx->drawVector(CTX::instance()->vectorType, 0, pc.x(), pc.y(), pc.z(), t[0], t[1], t[2], CTX::instance()->mesh.light); } }
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; }
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 distanceFromElementsToGeometry(GModel *gm, int dim, std::map<MElement *, double> &distances) { std::map<MEdge, double, Less_Edge> dist2Edge; for(GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it) { if((*it)->geomType() == GEntity::Line) continue; for(unsigned int i = 0; i < (*it)->lines.size(); i++) { double d = taylorDistanceEdge((*it)->lines[i], *it); MEdge e = (*it)->lines[i]->getEdge(0); dist2Edge[e] = d; } } std::map<MFace, double, Less_Face> dist2Face; for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) { if((*it)->geomType() == GEntity::Plane) continue; for(unsigned int i = 0; i < (*it)->triangles.size(); i++) { double d = taylorDistanceFace((*it)->triangles[i], *it); MFace f = (*it)->triangles[i]->getFace(0); dist2Face[f] = d; } } std::vector<GEntity *> entities; gm->getEntities(entities); for(int iEnt = 0; iEnt < entities.size(); ++iEnt) { GEntity *&entity = entities[iEnt]; if(entity->dim() != dim) continue; for(int iEl = 0; iEl < entity->getNumMeshElements(); iEl++) { // Detect bad elements MElement *element = entity->getMeshElement(iEl); double d = 0.; for(int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) { MEdge e = element->getEdge(iEdge); std::map<MEdge, double, Less_Edge>::iterator it = dist2Edge.find(e); if(it != dist2Edge.end()) d += it->second; } for(int iFace = 0; iFace < element->getNumFaces(); ++iFace) { MFace f = element->getFace(iFace); std::map<MFace, double, Less_Face>::iterator it = dist2Face.find(f); if(it != dist2Face.end()) d += it->second; } distances[element] = d; } } }
PView *elasticitySolver::buildVolumeView(const std::string postFileName) { std::cout << "build Volume View"; std::map<int, std::vector<double> > data; double voltot = 0; double length = 0; GaussQuadrature Integ_Vol(GaussQuadrature::Val); for(std::size_t i = 0; i < elasticFields.size(); ++i) { ScalarTermConstant<double> One(1.0); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double vol; IntPt *GP; int npts = Integ_Vol.getIntPoints(e, &GP); One.get(e, npts, GP, vol); voltot += vol; std::vector<double> vec; vec.push_back(vol); data[e->getNum()] = vec; } } for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) { ScalarTermConstant<double> One(1.0); for(groupOfElements::elementContainer::const_iterator it = LagrangeMultiplierFields[i].g->begin(); it != LagrangeMultiplierFields[i].g->end(); ++it) { MElement *e = *it; double l; IntPt *GP; int npts = Integ_Vol.getIntPoints(e, &GP); One.get(e, npts, GP, l); length += l; } std::cout << " : length " << LagrangeMultiplierFields[i]._tag << " = " << length; length = 0; } PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0, 1); std::cout << " / total vol = " << voltot << std::endl; return pv; }
int multiscalePartition::assembleAllPartitions(std::vector<MElement*> & elements) { int iPart = 1; elements.clear(); for (unsigned i = 0; i< levels.size(); i++){ partitionLevel *iLevel = levels[i]; if(iLevel->elements.size() > 0){ for (unsigned j = 0; j < iLevel->elements.size(); j++){ MElement *e = iLevel->elements[j]; elements.push_back(e); e->setPartition(iPart); } iPart++; } } return iPart - 1; }
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); }
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; }
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); } }
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; }
double ComputeDistanceToGeometry (GEntity *ge , int distanceDefinition, double tolerance) { double maxd = 0.0; double sum = 0.0; int NUM = 0; for (int iEl = 0; iEl < ge->getNumMeshElements();iEl++) { MElement *el = ge->getMeshElement(iEl); if (ge->dim() == el->getDim()){ const double DISTE =computeBndDist(el,distanceDefinition, tolerance); if (DISTE != 0.0){ NUM++; // if(distanceDefinition == 1)printf("%d %12.5E\n",iEl,DISTE); maxd = std::max(maxd,DISTE); sum += DISTE; } } } if (distanceDefinition == 2) return sum; if (distanceDefinition == 6) return sum; return maxd; }
static void addOneLayer(const std::vector<MElement*> &v, std::vector<MElement*> &d, std::vector<MElement*> &layer) { std::set<MVertex*> all; for (unsigned int i = 0; i < d.size(); i++){ MElement *e = d[i]; int n = e->getNumPrimaryVertices(); for (int j = 0; j < n; j++){ all.insert(e->getVertex(j)); } } layer.clear(); std::sort(d.begin(), d.end()); for (unsigned int i = 0; i < v.size(); i++){ MElement *e = v[i]; bool found = std::binary_search(d.begin(), d.end(), e); // element is not yet there if (!found){ int n = e->getNumPrimaryVertices(); for (int j = 0; j < n; j++){ MVertex *vert = e->getVertex(j); if (all.find(vert) != all.end()){ layer.push_back(e); j = n; } } } } }
double thermicSolver::computeLagNorm(int tag, simpleFunction<double> *sol) { double val = 0.0, val2 = 0.0; SolverField<double> solField(pAssembler, LagrangeMultiplierSpace); for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) { if(tag != LagrangeMultiplierFields[i]._tag) continue; for(groupOfElements::elementContainer::const_iterator it = LagrangeMultiplierFields[i].g->begin(); it != LagrangeMultiplierFields[i].g->end(); ++it) { MElement *e = *it; // printf("element (%g,%g) // (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->getVertex(1)->x(),e->getVertex(1)->y()); int npts; IntPt *GP; double jac[3][3]; int integrationOrder = 2 * (e->getPolynomialOrder() + 1); e->getIntegrationPoints(integrationOrder, &npts, &GP); for(int j = 0; j < npts; j++) { double u = GP[j].pt[0]; double v = GP[j].pt[1]; double w = GP[j].pt[2]; double weight = GP[j].weight; double detJ = fabs(e->getJacobian(u, v, w, jac)); SPoint3 p; e->getParent()->pnt(u, v, w, p); double FEMVALUE; solField.f(e, u, v, w, FEMVALUE); double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE; val += diff * diff * detJ * weight; val2 += (*sol)(p.x(), p.y(), p.z()) * (*sol)(p.x(), p.y(), p.z()) * detJ * weight; // printf("(%g %g) : u,v=(%g,%g) detJ=%g we=%g FV=%g sol=%g // diff=%g\n",p.x(),p.y(),u,v,detJ,weight,FEMVALUE,(*sol)(p.x(), p.y(), // p.z()),diff); } } } printf("LagNorm = %g\n", sqrt(val / val2)); return sqrt(val / val2); }
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); } } } }
static void partitionRegions(std::vector<MElement*> &elements, std::vector<std::vector<MElement*> > ®ions) { for (unsigned int i = 0; i < elements.size(); ++i){ MElement *e = elements[i]; int part = e->getPartition(); regions[part-1].push_back(e); } std::vector<std::vector<MElement*> > allRegions; for (unsigned int k = 0; k < regions.size(); ++k){ std::vector<std::vector<MElement*> > conRegions; conRegions.clear(); connectedRegions (regions[k], conRegions); for (unsigned int j = 0; j < conRegions.size(); j++) allRegions.push_back(conRegions[j]); } regions.clear(); regions.resize(allRegions.size()); regions = allRegions; }
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; }
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; }
double elasticitySolver::computeL2Norm(simpleFunction<double> *f0, simpleFunction<double> *f1, simpleFunction<double> *f2) { double val = 0.0; SolverField<SVector3> solField(pAssembler, LagSpace); for(std::size_t i = 0; i < elasticFields.size(); ++i) { for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; int npts; IntPt *GP; double jac[3][3]; int integrationOrder = 2 * (e->getPolynomialOrder() + 5); e->getIntegrationPoints(integrationOrder, &npts, &GP); for(int j = 0; j < npts; j++) { double u = GP[j].pt[0]; double v = GP[j].pt[1]; double w = GP[j].pt[2]; double weight = GP[j].weight; double detJ = fabs(e->getJacobian(u, v, w, jac)); SPoint3 p; e->pnt(u, v, w, p); SVector3 FEMVALUE; solField.f(e, u, v, w, FEMVALUE); SVector3 sol((*f0)(p.x(), p.y(), p.z()), (*f1)(p.x(), p.y(), p.z()), (*f2)(p.x(), p.y(), p.z())); double diff = normSq(sol - FEMVALUE); val += diff * detJ * weight; } } } printf("L2Norm = %g\n", sqrt(val)); return sqrt(val); }
static void drawBarycentricDual(std::vector<T*> &elements) { glColor4ubv((GLubyte *) & CTX::instance()->color.fg); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x0F0F); gl2psEnable(GL2PS_LINE_STIPPLE); glBegin(GL_LINES); for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; if(!isElementVisible(ele)) continue; SPoint3 pc = ele->barycenter(); if(ele->getDim() == 2){ for(int j = 0; j < ele->getNumEdges(); j++){ MEdge e = ele->getEdge(j); SPoint3 p = e.barycenter(); glVertex3d(pc.x(), pc.y(), pc.z()); glVertex3d(p.x(), p.y(), p.z()); } } else if(ele->getDim() == 3){ for(int j = 0; j < ele->getNumFaces(); j++){ MFace f = ele->getFace(j); SPoint3 p = f.barycenter(); glVertex3d(pc.x(), pc.y(), pc.z()); glVertex3d(p.x(), p.y(), p.z()); for(int k = 0; k < f.getNumVertices(); k++){ MEdge e(f.getVertex(k), (k == f.getNumVertices() - 1) ? f.getVertex(0) : f.getVertex(k + 1)); SPoint3 pe = e.barycenter(); glVertex3d(p.x(), p.y(), p.z()); glVertex3d(pe.x(), pe.y(), pe.z()); } } } } glEnd(); glDisable(GL_LINE_STIPPLE); gl2psDisable(GL2PS_LINE_STIPPLE); }
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; }
PView *elasticitySolver::buildErrorView(const std::string postFileName, simpleFunction<double> *f0, simpleFunction<double> *f1, simpleFunction<double> *f2) { std::cout << "build Error View" << std::endl; std::map<int, std::vector<double> > data; SolverField<SVector3> solField(pAssembler, LagSpace); for(std::size_t i = 0; i < elasticFields.size(); ++i) { for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; int npts; IntPt *GP; double jac[3][3]; int integrationOrder = 2 * (e->getPolynomialOrder() + 5); e->getIntegrationPoints(integrationOrder, &npts, &GP); double val = 0.0; for(int j = 0; j < npts; j++) { double u = GP[j].pt[0]; double v = GP[j].pt[1]; double w = GP[j].pt[2]; double weight = GP[j].weight; double detJ = fabs(e->getJacobian(u, v, w, jac)); SPoint3 p; e->pnt(u, v, w, p); SVector3 FEMVALUE; solField.f(e, u, v, w, FEMVALUE); SVector3 sol((*f0)(p.x(), p.y(), p.z()), (*f1)(p.x(), p.y(), p.z()), (*f2)(p.x(), p.y(), p.z())); double diff = normSq(sol - FEMVALUE); val += diff * detJ * weight; } std::vector<double> vec; vec.push_back(sqrt(val)); data[e->getNum()] = vec; } } PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0, 1); return pv; }