Exemple #1
0
void backgroundMesh2D::create_mesh_copy()
{
    // TODO: useful to extend it to other elements ???
    //std::set<SPoint2> myBCNodes;
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return;
    }
    for (unsigned int i = 0; i < face->triangles.size(); i++) {
        MTriangle *e = face->triangles[i];
        MVertex *news[3];
        for (int j=0; j<3; j++) {
            MVertex *v = e->getVertex(j);
            std::map<MVertex*,MVertex*>::iterator it = _3Dto2D.find(v);
            MVertex *newv =0;
            if (it == _3Dto2D.end()) {
                SPoint2 p;
                reparamMeshVertexOnFace(v, face, p);
                newv = new MVertex (p.x(), p.y(), 0.0);// creates new vertex with xyz= u,v,0.
                vertices.push_back(newv);
                _3Dto2D[v] = newv;
                _2Dto3D[newv] = v;
                //if(v->onWhat()->dim()<2) myBCNodes.insert(p);
            }
            else newv = it->second;
            news[j] = newv;
        }
        elements.push_back(new MTriangle(news[0],news[1],news[2]));
    }
}
Pair<SVector3,SVector3> fourierProjectionFace::firstDer(const SPoint2 &param) const
{
  SVector3 du;
  SVector3 dv;
  ps_->Dfdu(param.x(), param.y(), du[0], du[1], du[2]);
  ps_->Dfdv(param.x(), param.y(), dv[0], dv[1], dv[2]);
  return Pair<SVector3,SVector3>(du, dv);
} 
Exemple #3
0
SVector3 gmshFace::normal(const SPoint2 &param) const
{
  if(s->Typ != MSH_SURF_PLAN){
    Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1);
    Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2);
    Vertex n = vu % vv;
    n.norme();
    return SVector3(n.Pos.X, n.Pos.Y, n.Pos.Z);
  }
  else{
    // We cannot use InterpolateSurface() for plane surfaces since it
    // relies on the mean plane, which does not respect the
    // orientation

    // FIXME: move this test at the end of the MeanPlane computation
    // routine--and store the correct normal, damn it!

    double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c};
    norme(n);
    GPoint pt = point(param.x(), param.y());
    double v[3] = {pt.x(), pt.y(), pt.z()};
    int NP = 10, tries = 0;
    while(1){
      tries++;
      double angle = 0.;
      for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
        Curve *c;
        List_Read(s->Generatrices, i, &c);
        int N = (c->Typ == MSH_SEGM_LINE) ? 1 : NP;
        for(int j = 0; j < N; j++) {
          double u1 = (double)j / (double)N;
          double u2 = (double)(j + 1) / (double)N;
          Vertex p1 = InterpolateCurve(c, u1, 0);
          Vertex p2 = InterpolateCurve(c, u2, 0);
          double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z};
          double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z};
          angle += angle_plan(v, v1, v2, n);
        }
      }
      if(fabs(angle) < 0.5){ // we're outside
        NP *= 2;
        Msg::Debug("Could not compute normal of surface %d - retrying with %d points",
                   tag(), NP);
        if(tries > 10){
          Msg::Warning("Could not orient normal of surface %d", tag());
          return SVector3(n[0], n[1], n[2]);
        }
      }
      else if(angle > 0)
        return SVector3(n[0], n[1], n[2]);
      else
        return SVector3(-n[0], -n[1], -n[2]);
    }
  }
}
Exemple #4
0
void backgroundMesh2D::updateSizes()
{
    DoubleStorageType::iterator itv = sizeField.begin();
    for ( ; itv != sizeField.end(); ++itv) {
        SPoint2 p;
        MVertex *v = _2Dto3D[itv->first];
        double lc;
        if (v->onWhat()->dim() == 0) {
            lc = sizeFactor * BGM_MeshSize(v->onWhat(), 0,0,v->x(),v->y(),v->z());
        }
        else if (v->onWhat()->dim() == 1) {
            double u;
            v->getParameter(0, u);
            lc = sizeFactor * BGM_MeshSize(v->onWhat(), u, 0, v->x(), v->y(), v->z());
        }
        else {
            GFace *face = dynamic_cast<GFace*>(gf);
            if(!face) {
                Msg::Error("Entity is not a face in background mesh");
                return;
            }
            reparamMeshVertexOnFace(v, face, p);
            lc = sizeFactor * BGM_MeshSize(face, p.x(), p.y(), v->x(), v->y(), v->z());
        }
        // printf("2D -- %g %g 3D -- %g %g\n",p.x(),p.y(),v->x(),v->y());
        itv->second = min(lc,itv->second);
        itv->second = max(itv->second,  sizeFactor * CTX::instance()->mesh.lcMin);
        itv->second = min(itv->second,  sizeFactor * CTX::instance()->mesh.lcMax);
    }
    // do not allow large variations in the size field
    // (Int. J. Numer. Meth. Engng. 43, 1143-1165 (1998) MESH GRADATION
    // CONTROL, BOROUCHAKI, HECHT, FREY)
    std::set<MEdge,Less_Edge> edges;
    for (unsigned int i = 0; i < getNumMeshElements(); i++) {
        for (int j = 0; j < getElement(i)->getNumEdges(); j++) {
            edges.insert(getElement(i)->getEdge(j));
        }
    }
    const double _beta = 1.3;
    for (int i=0; i<0; i++) {
        std::set<MEdge,Less_Edge>::iterator it = edges.begin();
        for ( ; it != edges.end(); ++it) {
            MVertex *v0 = it->getVertex(0);
            MVertex *v1 = it->getVertex(1);
            MVertex *V0 = _2Dto3D[v0];
            MVertex *V1 = _2Dto3D[v1];
            DoubleStorageType::iterator s0 = sizeField.find(V0);
            DoubleStorageType::iterator s1 = sizeField.find(V1);
            if (s0->second < s1->second)s1->second = min(s1->second,_beta*s0->second);
            else s0->second = min(s0->second,_beta*s1->second);
        }
    }
}
static SMetric3 metric_based_on_surface_curvature(const GEdge *ge, double u, bool iso_surf)
{
  const GEdgeCompound* ptrCompoundEdge = dynamic_cast<const GEdgeCompound*>(ge);
  if (ptrCompoundEdge){
    double cmax, cmin;
    SVector3 dirMax,dirMin;
    cmax = ptrCompoundEdge->curvatures(u,&dirMax, &dirMin, &cmax,&cmin);
    if (cmin == 0)cmin =1.e-12;
    if (cmax == 0)cmax =1.e-12;
    double lambda2 =  ((2 * M_PI) /( fabs(cmax) *  CTX::instance()->mesh.minCircPoints ) );
    double lambda1 =  ((2 * M_PI) /( fabs(cmin) *  CTX::instance()->mesh.minCircPoints ) );
    SVector3 Z = crossprod(dirMax,dirMin);

    lambda1 = std::max(lambda1, CTX::instance()->mesh.lcMin);
    lambda2 = std::max(lambda2, CTX::instance()->mesh.lcMin);
    lambda1 = std::min(lambda1, CTX::instance()->mesh.lcMax);
    lambda2 = std::min(lambda2, CTX::instance()->mesh.lcMax);

    SMetric3 curvMetric (1. / (lambda1 * lambda1), 1. / (lambda2 * lambda2),
                         1.e-12, dirMin, dirMax, Z);
    return curvMetric;
  }
  else{
    SMetric3 mesh_size(1.e-12);
    std::list<GFace *> faces = ge->faces();
    std::list<GFace *>::iterator it = faces.begin();
    // we choose the metric eigenvectors to be the ones
    // related to the edge ...
    SMetric3 curvMetric = max_edge_curvature_metric(ge, u);
    while(it != faces.end()){
      if (((*it)->geomType() != GEntity::CompoundSurface) &&
          ((*it)->geomType() != GEntity::DiscreteSurface)){
        SPoint2 par = ge->reparamOnFace((*it), u, 1);
        SMetric3 m = metric_based_on_surface_curvature (*it, par.x(), par.y(), iso_surf);
        curvMetric = intersection_conserveM1(curvMetric,m);
      }
      ++it;
    }

    return curvMetric;
  }
}
bool inExclusionZone(
  SPoint2 &p,
  RTree<surfacePointWithExclusionRegion *, double, 2, double> &rtree,
  std::vector<surfacePointWithExclusionRegion *> &all)
{
  // should assert that the point is inside the domain
  // OLD BGM
  if(old_algo_hexa()) {
    if(!backgroundMesh::current()->inDomain(p.x(), p.y(), 0)) return true;
  }
  else {
    // NEW BGM
    if(!BGMManager::current2D()->inDomain(p.x(), p.y(), 0)) return true;
  }

  my_wrapper w(p);
  double _min[2] = {p.x() - 1.e-1, p.y() - 1.e-1},
         _max[2] = {p.x() + 1.e-1, p.y() + 1.e-1};
  rtree.Search(_min, _max, rtree_callback, &w);

  return w._tooclose;

  for(unsigned int i = 0; i < all.size(); ++i) {
    if(all[i]->inExclusionZone(p)) {
      // printf("%g %g is in exclusion zone of %g
      //        %g\n",p.x(),p.y(),all[i]._center.x(),all[i]._center.y());
      return true;
    }
  }
  return false;
}
bool surfacePointWithExclusionRegion::inExclusionZone(const SPoint2 &p)
{
  double mat[2][2];
  double b[2], uv[2];
  mat[0][0] = _q[1].x() - _q[0].x();
  mat[0][1] = _q[2].x() - _q[0].x();
  mat[1][0] = _q[1].y() - _q[0].y();
  mat[1][1] = _q[2].y() - _q[0].y();
  b[0] = p.x() - _q[0].x();
  b[1] = p.y() - _q[0].y();
  sys2x2(mat, b, uv);
  //    printf("inversion 1 : %g %g \n",uv[0],uv[1]);
  if(uv[0] >= 0 && uv[1] >= 0 && 1. - uv[0] - uv[1] >= 0) return true;
  mat[0][0] = _q[3].x() - _q[2].x();
  mat[0][1] = _q[0].x() - _q[2].x();
  mat[1][0] = _q[3].y() - _q[2].y();
  mat[1][1] = _q[0].y() - _q[2].y();
  b[0] = p.x() - _q[2].x();
  b[1] = p.y() - _q[2].y();
  sys2x2(mat, b, uv);
  //    printf("inversion 2 : %g %g \n",uv[0],uv[1]);
  if(uv[0] >= 0 && uv[1] >= 0 && 1. - uv[0] - uv[1] >= 0) return true;
  return false;
}
SVector3 fourierProjectionFace::normal(const SPoint2 &param) const
{       
  double x, y, z;
  ps_->GetUnitNormal(param.x(), param.y(), x, y, z);
  return SVector3(x, y, z);
}
Exemple #9
0
double highOrderTools::smooth_metric_(std::vector<MElement*>  & v,
                                      GFace *gf,
                                      dofManager<double> &myAssembler,
                                      std::set<MVertex*> &verticesToMove,
                                      elasticityTerm &El)
{
  std::set<MVertex*>::iterator it;
  double dx = 0.0;

  if (myAssembler.sizeOfR()){

    // while convergence
    for (unsigned int i = 0; i < v.size(); i++){
      MElement *e = v[i];
      int nbNodes = e->getNumVertices();
      const int n2 = 2 * nbNodes;
      const int n3 = 3 * nbNodes;

      fullMatrix<double> K33(n3, n3);
      fullMatrix<double> K22(n2, n2);
      fullMatrix<double> J32(n3, n2);
      fullMatrix<double> J23(n2, n3);
      fullVector<double> D3(n3);
      fullVector<double> R2(n2);
      fullMatrix<double> J23K33(n2, n3);
      K33.setAll(0.0);
      SElement se(e);
      El.elementMatrix(&se, K33);
      computeMetricInfo(gf, e, J32, J23, D3);
      J23K33.gemm(J23, K33, 1, 0);
      K22.gemm(J23K33, J32, 1, 0);
      J23K33.mult(D3, R2);
      for (int j = 0; j < n2; j++){
        Dof RDOF = El.getLocalDofR(&se, j);
        myAssembler.assemble(RDOF, -R2(j));
        for (int k = 0; k < n2; k++){
          Dof CDOF = El.getLocalDofC(&se, k);
          myAssembler.assemble(RDOF, CDOF, K22(j, k));
        }
      }
    }
    myAssembler.systemSolve();
    // for all element, compute detJ at integration points --> material law end
    // while convergence

    for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
      if ((*it)->onWhat()->dim() == 2){
	SPoint2 param;
	reparamMeshVertexOnFace((*it), gf, param);
	SPoint2 dparam;
	myAssembler.getDofValue((*it), 0, _tag, dparam[0]);
	myAssembler.getDofValue((*it), 1, _tag, dparam[1]);
	SPoint2 newp = param+dparam;
	dx += newp.x() * newp.x() + newp.y() * newp.y();
	(*it)->setParameter(0, newp.x());
	(*it)->setParameter(1, newp.y());
      }
    }
    myAssembler.systemClear();
  }

  return dx;
}
Exemple #10
0
void backgroundMesh2D::propagateValues(DoubleStorageType &dirichlet,
                                       simpleFunction<double> &eval_diffusivity,
                                       bool in_parametric_plane)
{
#if defined(HAVE_SOLVER)
    linearSystem<double> *_lsys = 0;
#if defined(HAVE_PETSC) && !defined(HAVE_TAUCS)
    _lsys = new linearSystemPETSc<double>;
#elif defined(HAVE_GMM) && !defined(HAVE_TAUCS)
    linearSystemGmm<double> *_lsysb = new linearSystemGmm<double>;
    _lsysb->setGmres(1);
    _lsys = _lsysb;
#elif defined(HAVE_TAUCS)
    _lsys = new linearSystemCSRTaucs<double>;
#else
    _lsys = new linearSystemFull<double>;
#endif

    dofManager<double> myAssembler(_lsys);

    // fix boundary conditions
    DoubleStorageType::iterator itv = dirichlet.begin();
    for ( ; itv != dirichlet.end(); ++itv) {
        myAssembler.fixVertex(itv->first, 0, 1, itv->second);
    }

    // Number vertices
    std::set<MVertex*> vs;
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        delete _lsys;
        return;
    }
    for (unsigned int k = 0; k < face->triangles.size(); k++)
        for (int j=0; j<3; j++)vs.insert(face->triangles[k]->getVertex(j));
    for (unsigned int k = 0; k < face->quadrangles.size(); k++)
        for (int j=0; j<4; j++)vs.insert(face->quadrangles[k]->getVertex(j));

    std::map<MVertex*,SPoint3> theMap;
    if ( in_parametric_plane) {
        for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) {
            SPoint2 p;
            reparamMeshVertexOnFace ( *it, face, p);
            theMap[*it] = SPoint3((*it)->x(),(*it)->y(),(*it)->z());
            (*it)->setXYZ(p.x(),p.y(),0.0);
        }
    }

    for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it)
        myAssembler.numberVertex(*it, 0, 1);

    // Assemble
    laplaceTerm l(0, 1, &eval_diffusivity);
    for (unsigned int k = 0; k < face->triangles.size(); k++) {
        MTriangle *t = face->triangles[k];
        SElement se(t);
        l.addToMatrix(myAssembler, &se);
    }

    // Solve
    if (myAssembler.sizeOfR()) {
        _lsys->systemSolve();
    }

    // save solution
    for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) {
        myAssembler.getDofValue(*it, 0, 1, dirichlet[*it]);
    }

    if ( in_parametric_plane) {
        for (std::set<MVertex*>::iterator it = vs.begin(); it != vs.end(); ++it) {
            SPoint3 p = theMap[(*it)];
            (*it)->setXYZ(p.x(),p.y(),p.z());
        }
    }
    delete _lsys;
#endif
}