SMetric3 max_edge_curvature_metric(const GVertex *gv) { SMetric3 val (1.e-12); std::list<GEdge*> l_edges = gv->edges(); for (std::list<GEdge*>::const_iterator ite = l_edges.begin(); ite != l_edges.end(); ++ite){ GEdge *_myGEdge = *ite; Range<double> range = _myGEdge->parBounds(0); SMetric3 cc; if (gv == _myGEdge->getBeginVertex()) { SVector3 t = _myGEdge->firstDer(range.low()); t.normalize(); double l_t = ((2 * M_PI) /( fabs(_myGEdge->curvature(range.low())) * CTX::instance()->mesh.minCircPoints )); double l_n = 1.e12; cc = buildMetricTangentToCurve(t,l_t,l_n); } else { SVector3 t = _myGEdge->firstDer(range.high()); t.normalize(); double l_t = ((2 * M_PI) /( fabs(_myGEdge->curvature(range.high())) * CTX::instance()->mesh.minCircPoints )); double l_n = 1.e12; cc = buildMetricTangentToCurve(t,l_t,l_n); } val = intersection(val,cc); } return val; }
SMetric3 max_edge_curvature_metric(const GEdge *ge, double u) { SVector3 t = ge->firstDer(u); t.normalize(); double l_t = ((2 * M_PI) /( fabs(ge->curvature(u)) * CTX::instance()->mesh.minCircPoints )); double l_n = 1.e12; return buildMetricTangentToCurve(t,l_t,l_n); }
void Centerline::operator() (double x, double y, double z, SMetric3 &metr, GEntity *ge) { if (update_needed){ std::ifstream input; input.open(fileName.c_str()); if(StatFile(fileName)) Msg::Fatal("Centerline file '%s' does not exist", fileName.c_str()); importFile(fileName); buildKdTree(); update_needed = false; } //take xyz = closest point on boundary in case we are on //the planar IN/OUT FACES or in VOLUME double xyz[3] = {x,y,z}; bool onTubularSurface = true; double ds = 0.0; bool isCompound = (ge->dim() == 2 && ge->geomType() == GEntity::CompoundSurface) ? true : false; bool onInOutlets = (ge->geomType() == GEntity::Plane) ? true: false; std::list<GFace*> cFaces; if (isCompound) cFaces = ((GFaceCompound*)ge)->getCompounds(); if ( ge->dim() == 3 || (ge->dim() == 2 && ge->geomType() == GEntity::Plane) || (isCompound && (*cFaces.begin())->geomType() == GEntity::Plane) ){ onTubularSurface = false; } ANNidx index[1]; ANNdist dist[1]; kdtreeR->annkSearch(xyz, 1, index, dist); if (! onTubularSurface){ ANNpointArray nodesR = kdtreeR->thePoints(); ds = sqrt(dist[0]); xyz[0] = nodesR[index[0]][0]; xyz[1] = nodesR[index[0]][1]; xyz[2] = nodesR[index[0]][2]; } ANNidx index2[2]; ANNdist dist2[2]; kdtree->annkSearch(xyz, 2, index2, dist2); double radMax = sqrt(dist2[0]); ANNpointArray nodes = kdtree->thePoints(); SVector3 p0(nodes[index2[0]][0], nodes[index2[0]][1], nodes[index2[0]][2]); SVector3 p1(nodes[index2[1]][0], nodes[index2[1]][1], nodes[index2[1]][2]); //dir_a = direction along the centerline //dir_n = normal direction of the disk //dir_t = tangential direction of the disk SVector3 dir_a = p1-p0; dir_a.normalize(); SVector3 dir_n(xyz[0]-p0.x(), xyz[1]-p0.y(), xyz[2]-p0.z()); dir_n.normalize(); SVector3 dir_cross = crossprod(dir_a,dir_n); dir_cross.normalize(); // if (ge->dim()==3){ // printf("coucou dim ==3 !!!!!!!!!!!!!!! \n"); // SVector3 d1,d2,d3; // computeCrossField(x,y,z,d1,d2,d3); // exit(1); // } //find discrete curvature at closest vertex Curvature& curvature = Curvature::getInstance(); if( !Curvature::valueAlreadyComputed() ) { Msg::Info("Need to compute discrete curvature"); Curvature::typeOfCurvature type = Curvature::RUSIN; curvature.computeCurvature(current, type); } double curv, cMin, cMax; SVector3 dMin, dMax; int isAbs = 1.0; curvature.vertexNodalValuesAndDirections(vertices[index[0]],&dMax, &dMin, &cMax, &cMin, isAbs); curvature.vertexNodalValues(vertices[index[0]], curv, 1); if (cMin == 0) cMin =1.e-12; if (cMax == 0) cMax =1.e-12; double rhoMin = 1./cMin; double rhoMax = 1./cMax; //double signMin = (rhoMin > 0.0) ? -1.0: 1.0; //double signMax = (rhoMax > 0.0) ? -1.0: 1.0; //user-defined parameters //define h_n, h_t1, and h_t2 double thickness = radMax/3.; double h_far = radMax/5.; double beta = (ds <= thickness) ? 1.2 : 2.1; //CTX::instance()->mesh.smoothRatio; double ddist = (ds <= thickness) ? ds: thickness; double h_n_0 = thickness/20.; double h_n = std::min( (h_n_0+ds*log(beta)), h_far); double betaMin = 10.0; double betaMax = 3.1; double oneOverD2_min = 1./(2.*rhoMin*rhoMin*(betaMin*betaMin-1)) * (sqrt(1+ (4.*rhoMin*rhoMin*(betaMin*betaMin-1))/(h_n*h_n))-1.); double oneOverD2_max = 1./(2.*rhoMax*rhoMax*(betaMax*betaMax-1)) * (sqrt(1+ (4.*rhoMax*rhoMax*(betaMax*betaMax-1))/(h_n*h_n))-1.); double h_t1_0 = sqrt(1./oneOverD2_min); double h_t2_0 = sqrt(1./oneOverD2_max); //double h_t1 = h_t1_0*(rhoMin+signMin*ddist)/rhoMin ; //double h_t2 = h_t2_0*(rhoMax+signMax*ddist)/rhoMax ; double h_t1 = std::min( (h_t1_0+(ddist*log(beta))), radMax); double h_t2 = std::min( (h_t2_0+(ddist*log(beta))), h_far); double dCenter = radMax-ds; double h_a_0 = 0.5*radMax; double h_a = h_a_0 - (h_a_0-h_t1_0)/(radMax)*dCenter; //length between min and max double lcMin = ((2 * M_PI *radMax) /( 50*nbPoints )); //CTX::instance()->mesh.lcMin; double lcMax = lcMin*2000.; //CTX::instance()->mesh.lcMax; h_n = std::max(h_n, lcMin); h_n = std::min(h_n, lcMax); h_t1 = std::max(h_t1, lcMin); h_t1 = std::min(h_t1, lcMax); h_t2 = std::max(h_t2, lcMin); h_t2 = std::min(h_t2, lcMax); //curvature metric SMetric3 curvMetric, curvMetric1, curvMetric2; SMetric3 centMetric1, centMetric2, centMetric; if (onInOutlets){ metr = buildMetricTangentToCurve(dir_n,h_n,h_t2); } else { //on surface and in volume boundary layer if ( ds < thickness ){ metr = metricBasedOnSurfaceCurvature(dMin, dMax, cMin, cMax, h_n, h_t1, h_t2); } //in volume else { //curvMetric = metricBasedOnSurfaceCurvature(dMin, dMax, cMin, cMax, h_n, h_t1, h_t2); metr = SMetric3( 1./(h_a*h_a), 1./(h_n*h_n), 1./(h_n*h_n), dir_a, dir_n, dir_cross); //metr = intersection_conserveM1_bis(metr, curvMetric); //metr = intersection_conserveM1(metr,curvMetric); //metr = intersection_conserve_mostaniso(metr, curvMetric); //metr = intersection(metr,curvMetric); } } return; }