Beispiel #1
0
Metric Filler::get_metric(double x,double y,double z,GEntity* ge){
  Metric m;
  SMetric3 temp;
  SVector3 v1,v2,v3;
  Field* field;
  FieldManager* manager;
	
  v1 = SVector3(1.0,0.0,0.0);
  v2 = SVector3(0.0,1.0,0.0);
  v3 = SVector3(0.0,0.0,1.0);
	
  manager = ge->model()->getFields();
  if(manager->getBackgroundField()>0){
    field = manager->get(manager->getBackgroundField());
    if(field){
      (*field)(x,y,z,temp,ge);
    }
  }
	
  m.set_m11(v1.x());
  m.set_m21(v1.y());
  m.set_m31(v1.z());
	
  m.set_m12(v2.x());
  m.set_m22(v2.y());
  m.set_m32(v2.z());
	
  m.set_m13(v3.x());
  m.set_m23(v3.y());
  m.set_m33(v3.z());
	
  return m;
}
Beispiel #2
0
double Filler::get_size(double x,double y,double z,GEntity* ge){
  double h;
  Field* field;
  FieldManager* manager;

  h = 1.0;
  manager = ge->model()->getFields();
  if(manager->getBackgroundField()>0){
    field = manager->get(manager->getBackgroundField());
	if(field){
	  h = (*field)(x,y,z,ge);
	}
  }

  return h;
}
// anisotropic version of the background field
SMetric3 BGM_MeshMetric(GEntity *ge,
                        double U, double V,
                        double X, double Y, double Z)
{

  // Metrics based on element size

  // Element size = min. between default lc and lc from point (if applicable),
  // constrained by lcMin and lcMax
  double lc = CTX::instance()->lc;
  if(CTX::instance()->mesh.lcFromPoints && ge->dim() < 2)
    lc = std::min(lc, LC_MVertex_PNTS(ge, U, V));
  lc = std::min(lc, ge->getMeshSize());
  lc = std::max(lc, CTX::instance()->mesh.lcMin);
  lc = std::min(lc, CTX::instance()->mesh.lcMax);
  if(lc <= 0.){
    Msg::Error("Wrong mesh element size lc = %g (lcmin = %g, lcmax = %g)",
               lc, CTX::instance()->mesh.lcMin, CTX::instance()->mesh.lcMax);
    lc = CTX::instance()->lc;
  }
  SMetric3 m0(1./(lc*lc));

  // Intersect with metrics from fields if applicable
  FieldManager *fields = ge->model()->getFields();
  SMetric3 m1 = m0;
  if(fields->getBackgroundField() > 0){
    Field *f = fields->get(fields->getBackgroundField());
    if(f) {
      SMetric3 l4;
      if (!f->isotropic()) (*f)(X, Y, Z, l4, ge);
      else {
        const double L = (*f)(X, Y, Z, ge);
        l4 = SMetric3(1/(L*L));
      }
      m1 = intersection(l4, m0);
    }
  }

  // Intersect with metrics from curvature if applicable
  SMetric3 m = (CTX::instance()->mesh.lcFromCurvature && ge->dim() < 3) ?
      intersection(m1, LC_MVertex_CURV_ANISO(ge, U, V)) : m1;

  return m;
}
// This is the only function that is used by the meshers
double BGM_MeshSize(GEntity *ge, double U, double V,
                    double X, double Y, double Z)
{
  // default lc (mesh size == size of the model)
  double l1 = CTX::instance()->lc;

  // lc from points
  double l2 = MAX_LC;
  if(CTX::instance()->mesh.lcFromPoints && ge->dim() < 2)
    l2 = LC_MVertex_PNTS(ge, U, V);

  // lc from curvature
  double l3 = MAX_LC;
  if(CTX::instance()->mesh.lcFromCurvature && ge->dim() < 3)
    l3 = LC_MVertex_CURV(ge, U, V);

  // lc from fields
  double l4 = MAX_LC;
  FieldManager *fields = ge->model()->getFields();
  if(fields->getBackgroundField() > 0){
    Field *f = fields->get(fields->getBackgroundField());
    if(f) l4 = (*f)(X, Y, Z, ge);
  }

  // global lc from entity
  double l5 = ge->getMeshSize();

  // take the minimum, then constrain by lcMin and lcMax
  double lc = std::min(std::min(std::min(std::min(l1, l2), l3), l4), l5);
  lc = std::max(lc, CTX::instance()->mesh.lcMin);
  lc = std::min(lc, CTX::instance()->mesh.lcMax);

  if(lc <= 0.){
    Msg::Error("Wrong mesh element size lc = %g (lcmin = %g, lcmax = %g)",
               lc, CTX::instance()->mesh.lcMin, CTX::instance()->mesh.lcMax);
    lc = l1;
  }

  return lc * CTX::instance()->mesh.lcFactor;
}
Beispiel #5
0
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos)
{
    // check if point is in domain
    if (!inDomain(u,v)) return false;

    // get stored angle

    double angle_current = angle(u,v);

    // compute t1,t2: cross field directions

    // get the unit normal at that point
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return false;
    }

    Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v));
    SVector3 s1 = der.first();
    SVector3 s2 = der.second();
    SVector3 n = crossprod(s1,s2);
    n.normalize();
    SVector3 basis_u = s1;
    basis_u.normalize();
    SVector3 basis_v = crossprod(n,basis_u);
    // normalize vector t1 that is tangent to gf at uv
    SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ;
    t1.normalize();
    // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
    SVector3 t2 = crossprod(n,t1);
    t2.normalize();

    // get metric

    double L = size(u,v);
    infos.metricField = SMetric3(1./(L*L));
    FieldManager *fields = gf->model()->getFields();
    if(fields->getBackgroundField() > 0) {
        Field *f = fields->get(fields->getBackgroundField());
        if (!f->isotropic()) {
            (*f)(x,y,z, infos.metricField,gf);
        }
        else {
            L = (*f)(x,y,z,gf);
            infos.metricField = SMetric3(1./(L*L));
        }
    }
    double M = dot(s1,s1);
    double N = dot(s2,s2);
    double E = dot(s1,s2);
    // compute the first fundamental form i.e. the metric tensor at the point
    // M_{ij} = s_i \cdot s_j
    double metric[2][2] = {{M,E},{E,N}};

    // get sizes

    double size_1 = sqrt(1. / dot(t1,infos.metricField,t1));
    double size_2 = sqrt(1. / dot(t2,infos.metricField,t2));

    // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain
    double covar1[2],covar2[2];
    // t1 = a s1 + b s2 -->
    // t1 . s1 = a M + b E
    // t1 . s2 = a E + b N --> solve the 2 x 2 system
    // and get covariant coordinates a and b
    double rhs1[2] = {dot(t1,s1),dot(t1,s2)};
    bool singular = false;
    if (!sys2x2(metric,rhs1,covar1)) {
        Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2);
        covar1[1] = 1.0;
        covar1[0] = 0.0;
        singular = true;
    }
    double rhs2[2] = {dot(t2,s1),dot(t2,s2)};
    if (!sys2x2(metric,rhs2,covar2)) {
        Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z());
        covar2[0] = 1.0;
        covar2[1] = 0.0;
        singular = true;
    }

    // transform the sizes with respect to the metric
    // consider a vector v of size 1 in the parameter plane
    // its length is sqrt (v^T M v) --> if I want a real size
    // of size1 in direction v, it should be sqrt(v^T M v) * size1
    double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]);
    double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]);

    covar1[0] /= l1;
    covar1[1] /= l1;
    covar2[0] /= l2;
    covar2[1] /= l2;

    double size_param_1  = size_1 / sqrt (  M*covar1[0]*covar1[0]+
                                            2*E*covar1[1]*covar1[0]+
                                            N*covar1[1]*covar1[1]);
    double size_param_2  = size_2 / sqrt (  M*covar2[0]*covar2[0]+
                                            2*E*covar2[1]*covar2[0]+
                                            N*covar2[1]*covar2[1]);
    if (singular) {
        size_param_1 = size_param_2 = std::min (size_param_1,size_param_2);
    }


    // filling form...

    infos.t1 = t1;
    infos.h.first  = size_1;
    infos.h.second = size_2;
    infos.paramh.first  = size_param_1;
    infos.paramh.second = size_param_2;
    infos.paramt1 = SPoint2(covar1[0],covar1[1]);
    infos.paramt2 = SPoint2(covar2[0],covar2[1]);
    infos.angle = angle_current;
    infos.localsize = L;
    infos.normal = n;

    return true;
}
Beispiel #6
0
bool gmshFace::buildSTLTriangulation(bool force)
{
  return false;

  if(va_geom_triangles){
    if(force)
      delete va_geom_triangles;
    else
      return true;
  }

  stl_vertices.clear();
  stl_triangles.clear();

#if defined(HAVE_MESH)
  if (!triangles.size()){
    contextMeshOptions _temp = CTX::instance()->mesh;
    FieldManager *fields = model()->getFields();
    int BGM  = fields->getBackgroundField();
    fields->setBackgroundField(0);
    CTX::instance()->mesh.lcFromPoints = 0;
    CTX::instance()->mesh.lcFromCurvature = 1;
    CTX::instance()->mesh.lcExtendFromBoundary = 0;
    CTX::instance()->mesh.scalingFactor = 1;
    CTX::instance()->mesh.lcFactor = 1;
    CTX::instance()->mesh.order = 1;
    CTX::instance()->mesh.lcIntegrationPrecision = 1.e-3;
    //  CTX::instance()->mesh.Algorithm = 5;
    model()->mesh(2);
    CTX::instance()->mesh = _temp;
    fields->setBackgroundField(fields->get(BGM));
  }
#endif

  std::map<MVertex*,int> _v;
  int COUNT =0;
  for (unsigned int j = 0; j < triangles.size(); j++){
    for (int i = 0; i < 3; i++){
      std::map<MVertex*,int>::iterator it =
        _v.find(triangles[j]->getVertex(j));
      if (it != _v.end()){
        stl_triangles.push_back(COUNT);
        _v[triangles[j]->getVertex(j)] = COUNT++;
      }
      else stl_triangles.push_back(it->second);
    }
  }
  std::map<MVertex*,int>::iterator itv = _v.begin();
  for ( ; itv != _v.end() ; ++itv){
    MVertex *v = itv->first;
    SPoint2 param;
    reparamMeshVertexOnFace(v, this, param);
    stl_vertices.push_back(param);
  }

  va_geom_triangles = new VertexArray(3, stl_triangles.size() / 3);
  unsigned int c = CTX::instance()->color.geom.surface;
  unsigned int col[4] = {c, c, c, c};
  for (unsigned int i = 0; i < stl_triangles.size(); i += 3){
    SPoint2 &p1(stl_vertices[stl_triangles[i]]);
    SPoint2 &p2(stl_vertices[stl_triangles[i + 1]]);
    SPoint2 &p3(stl_vertices[stl_triangles[i + 2]]);
    GPoint gp1 = GFace::point(p1);
    GPoint gp2 = GFace::point(p2);
    GPoint gp3 = GFace::point(p3);
    double x[3] = {gp1.x(), gp2.x(), gp3.x()};
    double y[3] = {gp1.y(), gp2.y(), gp3.y()};
    double z[3] = {gp1.z(), gp2.z(), gp3.z()};
    SVector3 n[3] = {normal(p1), normal(p2), normal(p3)};
    va_geom_triangles->add(x, y, z, n, col);
  }
  va_geom_triangles->finalize();
  return true;
}