示例#1
0
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()));
}
示例#2
0
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;
}
示例#3
0
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());

}