GPoint backgroundMesh2D::get_GPoint_from_MVertex(const MVertex *v)const { GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return GPoint(); } return face->point(SPoint2(v->x(),v->y())); }
bool computeFourNeighbors (frameFieldBackgroundMesh2D *bgm, MVertex *v_center, // the vertex for which we want to // generate 4 neighbors (real // vertex (xyz), not parametric!) SPoint2 &midpoint, bool goNonLinear, // do we compute the position in // the real surface which is // nonlinear SPoint2 newP[4][NUMDIR], // look into other directions SMetric3 &metricField) // the mesh metric { // we assume that v is on surface gf, and backgroundMesh2D has been created based on gf // get BGM and GFace GFace *gf = dynamic_cast<GFace*>(bgm->getBackgroundGEntity()); // get the parametric coordinates of the point on the surface reparamMeshVertexOnFace(v_center, gf, midpoint); // get RK info on midpoint (infos in two directions...) RK_form infos; bgm->compute_RK_infos(midpoint[0],midpoint[1],v_center->x(), v_center->y(), v_center->z(), infos); metricField = infos.metricField; // shoot in four directions SPoint2 param_vec; double h; for (int i=0;i<4;i++){// in four directions switch (i){ case 0: param_vec = infos.paramt1; h = infos.paramh.first; break; case 1: param_vec = infos.paramt2; h = infos.paramh.second; break; case 2: param_vec = infos.paramt1 * -1.; h = infos.paramh.first; break; case 3: param_vec = infos.paramt2 * -1.; h = infos.paramh.second; break; } shoot(midpoint,param_vec,h,newP[i][0]); // cout << "(" << midpoint[0] << "," <<midpoint[1] << ") -> (" << // newP[i][0][0] << "," << newP[i][0][1] << ") " << endl; } // the following comes from surfaceFiller.cpp... const double EPS = 1.e-7; for (int j=0;j<2;j++){ for (int i=0;i<4;i++){ newP[i][0][j] += (EPS* (double)rand() / RAND_MAX); } } // We could stop here. Yet, if the metric varies a lot, we can solve a // nonlinear problem in order to find a better approximation in the real // surface if (1 && goNonLinear){ double L = infos.localsize; double newPoint[4][2]; for (int j=0;j<2;j++){ for (int i=0;i<4;i++){ newPoint[i][j] = newP[i][0][j]; } } double ERR[4]; for (int i=0;i<4;i++){ // // if (newPoint[i][0] < rangeU.low())newPoint[i][0] = rangeU.low(); // if (newPoint[i][0] > rangeU.high())newPoint[i][0] = rangeU.high(); // if (newPoint[i][1] < rangeV.low())newPoint[i][1] = rangeV.low(); // if (newPoint[i][1] > rangeV.high())newPoint[i][1] = rangeV.high(); GPoint pp = gf->point(newP[i][0]); double D = sqrt ((pp.x() - v_center->x())*(pp.x() - v_center->x()) + (pp.y() - v_center->y())*(pp.y() - v_center->y()) + (pp.z() - v_center->z())*(pp.z() - v_center->z()) ); ERR[i] = 100*fabs(D-L)/(D+L); // printf("L = %12.5E D = %12.5E ERR = %12.5E\n",L,D,100*fabs(D-L)/(D+L)); } surfaceFunctorGFace ss (gf); SVector3 dirs[4] = {infos.t1*(-1.0),infos.t2*(-1.0),infos.t1*(1.0),infos.t2*(1.0)}; for (int i=0;i<4;i++){ if (ERR[i] > 12){ double uvt[3] = {newPoint[i][0],newPoint[i][1],0.0}; // printf("Intersecting with circle N = %g %g %g dir = %g %g %g R // = %g p = %g %g // %g\n",n.x(),n.y(),n.z(),dirs[i].x(),dirs[i].y(),dirs[i].z(),L, // v_center->x(),v_center->y(),v_center->z()); curveFunctorCircle cf (dirs[i],infos.normal, SVector3(v_center->x(),v_center->y(),v_center->z()), L); if (intersectCurveSurface (cf,ss,uvt,infos.paramh.first*1.e-3)){ GPoint pp = gf->point(SPoint2(uvt[0],uvt[1])); double D = sqrt ((pp.x() - v_center->x())*(pp.x() - v_center->x()) + (pp.y() - v_center->y())*(pp.y() - v_center->y()) + (pp.z() - v_center->z())*(pp.z() - v_center->z()) ); double DP = sqrt ((newPoint[i][0]-uvt[0])*(newPoint[i][0]-uvt[0]) + (newPoint[i][1]-uvt[1])*(newPoint[i][1]-uvt[1])); double newErr = 100*fabs(D-L)/(D+L); // if (v_center->onWhat() != gf && gf->tag() == 3){ // crossField2d::normalizeAngle (uvt[2]); // printf("INTERSECT angle = %g DP %g\n",uvt[2],DP); // } if (newErr < 1 && DP < .1){ // printf("%12.5E vs %12.5E : %12.5E %12.5E vs %12.5E %12.5E // \n",ERR[i],newErr,newPoint[i][0],newPoint[i][1],uvt[0],uvt[1]); newPoint[i][0] = uvt[0]; newPoint[i][1] = uvt[1]; } // printf("OK\n"); } else{ Msg::Debug("Cannot put a new point on Surface %d",gf->tag()); // printf("NOT OK\n"); } } } // return the four new vertices for (int i=0;i<4;i++){ newP[i][0] = SPoint2(newPoint[i][0],newPoint[i][1]); } } return true; }
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()); }