Ejemplo n.º 1
0
// build the BDS from a list of GFace
// This is a TRUE copy
BDS_Mesh *gmsh2BDS(std::list<GFace*> &l)
{
  BDS_Mesh *m = new BDS_Mesh;
  for (std::list<GFace*>::iterator it = l.begin(); it != l.end(); ++it){
    GFace *gf = *it;
    m->add_geom(gf->tag(), 2);
    BDS_GeomEntity *g2 = m->get_geom(gf->tag(), 2);
    for (unsigned int i = 0; i < gf->triangles.size(); i++){
      MTriangle *e = gf->triangles[i];
      BDS_Point *p[3];
      for (int j = 0; j < 3; j++){
        p[j] = m->find_point(e->getVertex(j)->getNum());
        if (!p[j]) {
          p[j] = m->add_point(e->getVertex(j)->getNum(), e->getVertex(j)->x(),
                              e->getVertex(j)->y(), e->getVertex(j)->z());
          SPoint2 param;
          reparamMeshVertexOnFace(e->getVertex(j), gf, param);
          p[j]->u = param[0];
          p[j]->v = param[1];
          m->add_geom(e->getVertex(j)->onWhat()->tag(),
                      e->getVertex(j)->onWhat()->dim());
          BDS_GeomEntity *g = m->get_geom(e->getVertex(j)->onWhat()->tag(),
                                          e->getVertex(j)->onWhat()->dim());
          p[j]->g = g;
        }
      }
      BDS_Face *f = m->add_triangle(p[0]->iD, p[1]->iD, p[2]->iD);
      f->g = g2;
    }
  }
  return m;
}
Ejemplo n.º 2
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]));
    }
}
Ejemplo n.º 3
0
void frameFieldBackgroundMesh2D::eval_crossfield(MVertex *vert, STensor3 &cf)
{
    SPoint2 parampoint;
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return;
    }
    reparamMeshVertexOnFace(vert, face, parampoint);
    return eval_crossfield(parampoint[0], parampoint[1], cf);
}
Ejemplo n.º 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);
        }
    }
}
Ejemplo n.º 5
0
static double _relocateVertex(GFace *gf, MVertex *ver,
                              const std::vector<MElement *> &lt, double tol)
{
  if(ver->onWhat()->dim() != 2) return 2.0;

  SPoint2 p1(0, 0);
  SPoint2 p2;
  if(ver->getParameter(0, p2[0])) {
    ver->getParameter(1, p2[1]);
  }
  else {
    return _relocateVertex2(gf, ver, lt, tol);
  }

  std::size_t counter = 0;
  for(std::size_t i = 0; i < lt.size(); i++) {
    for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) {
      MVertex *v = lt[i]->getVertex(j);
      SPoint2 pp;
      reparamMeshVertexOnFace(v, gf, pp);
      counter++;
      if(v->onWhat()->dim() == 1) {
        GEdge *ge = dynamic_cast<GEdge *>(v->onWhat());
        // do not take any chance
        if(ge->isSeam(gf)) return 2.0;
      }
      p1 += pp;
    }
  }
  p1 *= 1. / (double)counter;
  double worst;
  double xi = Maximize_Quality_Golden_Section(ver, gf, p1, p2, lt, tol, worst);
  // if (xi != 0) printf("xi = %g\n",xi);
  SPoint2 p = p1 * (1 - xi) + p2 * xi;
  GPoint pp = gf->point(p);
  if(!pp.succeeded()) return 2.0;
  ver->x() = pp.x();
  ver->y() = pp.y();
  ver->z() = pp.z();
  ver->setParameter(0, pp.u());
  ver->setParameter(1, pp.v());
  return worst;
}
Ejemplo n.º 6
0
void highOrderTools::computeMetricInfo(GFace *gf,
                                       MElement *e,
                                       fullMatrix<double> &J,
                                       fullMatrix<double> &JT,
                                       fullVector<double> &D)
{
  int nbNodes = e->getNumVertices();
  //  printf("ELEMENT --\n");
  for (int j = 0; j < nbNodes; j++){
    SPoint2 param;
    reparamMeshVertexOnFace(e->getVertex(j), gf, param);
    //    printf("%g %g vs %g %g %g\n",param.x(),param.y(),
    //	   e->getVertex(j)->x(),e->getVertex(j)->y(),e->getVertex(j)->z());

    Pair<SVector3,SVector3> der = gf->firstDer(param);

    int XJ = j;
    int YJ = j + nbNodes;
    int ZJ = j + 2 * nbNodes;
    int UJ = j;
    int VJ = j + nbNodes;
    J(XJ,UJ) = der.first().x();
    J(YJ,UJ) = der.first().y();
    J(ZJ,UJ) = der.first().z();
    J(XJ,VJ) = der.second().x();
    J(YJ,VJ) = der.second().y();
    J(ZJ,VJ) = der.second().z();

    JT(UJ,XJ) = der.first().x();
    JT(UJ,YJ) = der.first().y();
    JT(UJ,ZJ) = der.first().z();
    JT(VJ,XJ) = der.second().x();
    JT(VJ,YJ) = der.second().y();
    JT(VJ,ZJ) = der.second().z();

    SVector3 ss = getSSL(e->getVertex(j));
    GPoint gp = gf->point(param);
    D(XJ) = (gp.x() - ss.x());
    D(YJ) = (gp.y() - ss.y());
    D(ZJ) = (gp.z() - ss.z());
  }
}
Ejemplo n.º 7
0
double taylorDistanceFace(MElement *el, GFace *gf)
{
  const int nV = el->getNumVertices();
  const GradientBasis *gb = BasisFactory::getGradientBasis(FuncSpaceData(el));

  // Coordinates of vertices
  fullMatrix<double> nodesXYZ(nV, 3);
  el->getNodesCoord(nodesXYZ);

  // Normal to CAD at vertices
  std::vector<SVector3> normCAD(nV);
  for (int i=0; i<nV; i++) {
    SPoint2 pCAD;
    reparamMeshVertexOnFace(el->getVertex(i), gf, pCAD);
    normCAD[i] = gf->normal(pCAD);
    normCAD[i].normalize();
  }

  // Compute distance
  return sqrt(taylorDistanceSq2D(gb, nodesXYZ, normCAD));
}
Ejemplo n.º 8
0
void highOrderTools::applySmoothingTo(std::vector<MElement*> &all, GFace *gf)
{
#ifdef HAVE_TAUCS
  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
#else
  linearSystemPETSc<double> *lsys = new  linearSystemPETSc<double>;
#endif
  // compute the straight sided positions of high order nodes that are
  // on the edges of the face in the UV plane
  dofManager<double> myAssembler(lsys);
  elasticityTerm El(0, 1.0, CTX::instance()->mesh.hoPoissonRatio, _tag);
  std::vector<MElement*> layer, v;
  double minD;
  getDistordedElements(all, CTX::instance()->mesh.hoThresholdMin, v, minD);
  int numBad = v.size();
  const int nbLayers = CTX::instance()->mesh.hoNLayers;
  for (int i = 0; i < nbLayers; i++){
    addOneLayer(all, v, layer);
    v.insert(v.end(), layer.begin(), layer.end());
  }

  if (!v.size()) return;
  Msg::Info("Smoothing high order mesh : model face %d (%d elements considered in "
            "the elastic analogy, worst mapping %12.5E, %3d bad elements)", gf->tag(),
            v.size(),minD,numBad);

  addOneLayer(all, v, layer);
  std::set<MVertex*>::iterator it;
  std::set<MVertex*> verticesToMove;

  // on the last layer, fix displacement to 0
  for (unsigned int i = 0; i < layer.size(); i++){
    for (int j = 0; j < layer[i]->getNumVertices(); j++){
      MVertex *vert = layer[i]->getVertex(j);
      myAssembler.fixVertex(vert, 0, _tag, 0);
      myAssembler.fixVertex(vert, 1, _tag, 0);
    }
  }

  // fix all vertices that cannot move
  for (unsigned int i = 0; i < v.size(); i++){
    moveToStraightSidedLocation(v[i]);
    for (int j = 0; j < v[i]->getNumVertices(); j++){
      MVertex *vert = v[i]->getVertex(j);
      if (vert->onWhat()->dim() < 2){
	double du = 0, dv = 0;
        myAssembler.fixVertex(vert, 0, _tag, du);
        myAssembler.fixVertex(vert, 1, _tag, dv);
      }
    }
  }

  // number the other DOFs
  for (unsigned int i = 0; i < v.size(); i++){
    for (int j = 0; j < v[i]->getNumVertices(); j++){
      MVertex *vert = v[i]->getVertex(j);
      myAssembler.numberVertex(vert, 0, _tag);
      myAssembler.numberVertex(vert, 1, _tag);
      verticesToMove.insert(vert);
    }
  }

  double dx0 = smooth_metric_(v, gf, myAssembler, verticesToMove, El);
  double dx = dx0;
  Msg::Debug(" dx0 = %12.5E", dx0);
  int iter = 0;
  while(0){
    double dx2 = smooth_metric_(v, gf, myAssembler, verticesToMove, El);
    Msg::Debug(" dx2  = %12.5E", dx2);
    if (fabs(dx2 - dx) < 1.e-4 * dx0)break;
    if (iter++ > 2)break;
    dx = dx2;
  }

  for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
    SPoint2 param;
    if ((*it)->onWhat()->dim() == 2){
      reparamMeshVertexOnFace(*it, gf, param);
      GPoint gp = gf->point(param);
      (*it)->x() = gp.x();
      (*it)->y() = gp.y();
      (*it)->z() = gp.z();
      _targetLocation[*it] = SVector3(gp.x(), gp.y(), gp.z());
    }
    else{
      SVector3 p =  getTL(*it);
      (*it)->x() = p.x();
      (*it)->y() = p.y();
      (*it)->z() = p.z();
    }
  }
  delete lsys;
}
Ejemplo n.º 9
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
}
Ejemplo n.º 10
0
void updateBoVec<3, MFace>(
  const int normalSource, const MVertex *const vertex, const int zoneIndex,
  const int vertIndex,
  const CCon::FaceVector<MZoneBoundary<3>::GlobalVertexData<MFace>::FaceDataB>
    &faces,
  ZoneBoVec &zoneBoVec, BCPatchIndex &patch, bool &warnNormFromElem)
{
  GEntity *ent;
  if(normalSource == NormalSourceElement) goto getNormalFromElements;
  ent = vertex->onWhat();
  if(ent == 0) {
    goto getNormalFromElements;
    // No entity: try to find a normal from the faces
  }
  else {
    switch(ent->dim()) {
    case 0:
    case 1:

      /*--------------------------------------------------------------------*
       * In this case, there are possibly multiple GFaces from this zone
       * connected to the vertex.  One patch for each GFace will be written.
       *--------------------------------------------------------------------*/

      {
        //--Get a list of face entities connected to 'ent'

        std::list<GFace *> gFaceList;
        switch(ent->dim()) {
        case 0: {
          std::vector<GEdge *> gEdgeList = ent->edges();
          std::list<GFace *> gFaceList;
          for(std::vector<GEdge *>::const_iterator gEIt = gEdgeList.begin();
              gEIt != gEdgeList.end(); ++gEIt) {
            std::vector<GFace *> alist = (*gEIt)->faces();
            gFaceList.insert(gFaceList.end(), alist.begin(), alist.end());
          }
          // Remove duplicates
          gFaceList.sort();
          gFaceList.unique();
        } break;
        case 1: {
          std::vector<GFace *> fac = ent->faces();
          gFaceList.insert(gFaceList.end(), fac.begin(), fac.end());
        } break;
        }

        //--Get a list of face entities connected to the 'vertex' that are also
        // in the
        //--zone

        std::list<const GFace *> useGFace;
        std::vector<GEdge *> gEdgeList;
        const int nFace = faces.size();
        for(int iFace = 0; iFace != nFace; ++iFace) {
          if(zoneIndex == faces[iFace].zoneIndex) {
            bool matchedFace = false;
            MFace mFace =
              faces[iFace].parentElement->getFace(faces[iFace].parentFace);
            const int nVOnF = mFace.getNumVertices();
            int vertexOnF = 0; // The index of 'vertex' in the face
            for(int iVOnF = 0; iVOnF != nVOnF; ++iVOnF) {
              const MVertex *const vertex2 = mFace.getVertex(iVOnF);
              if(vertex == vertex2)
                vertexOnF = iVOnF;
              else {
                const GEntity *const ent2 = vertex2->onWhat();
                if(ent2->dim() == 2) {
                  matchedFace = true;
                  useGFace.push_back(static_cast<const GFace *>(ent2));
                  break;
                }
              }
            }
            // Triangle MElements are a total P.I.T.A.:
            // - If the original 'ent' is a vertex, one MVertex can be on the
            //   GVertex, and the other two on GEdges, and then the MElement is
            //   still on the GFace.
            // - If the original 'ent' is an edge, one MVertex can be on the
            //   original GEdge, another on a GVertex, and the final on another
            //   GEdge, and then the MElement is still on the GFace.  There is
            //   also the unlikely case where the two other MVertex are both on
            //   edges ... and the MElement is still on the GFace.
            if(!matchedFace && (3 == nVOnF)) {
              const MVertex *vertex2 = 0;
              const MVertex *vertex3 = 0;
              switch(vertexOnF) {
              case 0:
                vertex2 = mFace.getVertex(1);
                vertex3 = mFace.getVertex(2);
                break;
              case 1:
                vertex2 = mFace.getVertex(0);
                vertex3 = mFace.getVertex(2);
                break;
              case 2:
                vertex2 = mFace.getVertex(0);
                vertex3 = mFace.getVertex(1);
                break;
              }
              if(vertex2 && vertex3) {
                const GEntity *const ent2 = vertex2->onWhat();
                const GEntity *const ent3 = vertex3->onWhat();
                if(ent2 && ent3) {
                  if(ent2->dim() == 1 && ent3->dim() == 1) {
                    // Which GFace is bounded by edges ent2 and ent3?
                    for(std::list<GFace *>::const_iterator gFIt =
                          gFaceList.begin();
                        gFIt != gFaceList.end(); ++gFIt) {
                      gEdgeList = (*gFIt)->edges();
                      if((std::find(gEdgeList.begin(), gEdgeList.end(), ent2) !=
                          gEdgeList.end()) &&
                         (std::find(gEdgeList.begin(), gEdgeList.end(), ent3) !=
                          gEdgeList.end())) {
                        // Edges ent2 and ent3 bound this face
                        useGFace.push_back(*gFIt);
                        break;
                      }
                    }
                  }
                  else if(ent->dim() == 1 && (ent2->dim() + ent3->dim() == 1)) {
                    const GEntity *entCmp;
                    if(ent2->dim() == 1)
                      entCmp = ent2;
                    else
                      entCmp = ent3;
                    // Which GFace is bounded by entCmp
                    for(std::list<GFace *>::const_iterator gFIt =
                          gFaceList.begin();
                        gFIt != gFaceList.end(); ++gFIt) {
                      gEdgeList = (*gFIt)->edges();
                      if(std::find(gEdgeList.begin(), gEdgeList.end(),
                                   entCmp) != gEdgeList.end()) {
                        // Edge entCmp and the original edge bound this face
                        useGFace.push_back(*gFIt);
                        break;
                      }
                    }
                  }
                }
              }
            } // Stupid triangles
          } // End if face in zone
        } // End loop over faces
        // Duplicates are a possibility, remove
        useGFace.sort();
        useGFace.unique();

        //--'useGFace' now contains the face entities that connect to vertex.  A
        // BC
        //--patch will be written for each of them.

        for(std::list<const GFace *>::const_iterator gFIt = useGFace.begin();
            gFIt != useGFace.end(); ++gFIt) {
          SPoint2 par;
          if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), *gFIt,
                                      par))
            goto getNormalFromElements; // :P  After all that!

          SVector3 boNormal = (*gFIt)->normal(par);
          SPoint3 interior(0., 0., 0.);
          int cFace = 0;
          const int nFace = faces.size();
          for(int iFace = 0; iFace != nFace; ++iFace) {
            if(faces[iFace].zoneIndex == zoneIndex) {
              ++cFace;
              interior += faces[iFace].parentElement->barycenter();
            }
          }
          interior /= cFace;
          if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.)
            boNormal.negate();

          zoneBoVec.push_back(
            VertexBoundary(zoneIndex, (*gFIt)->tag(), boNormal,
                           const_cast<MVertex *>(vertex), vertIndex));
          patch.add((*gFIt)->tag());
        }
      }
      break;
    case 2:

      /*--------------------------------------------------------------------*
       * The vertex exists on a face and belongs to only 1 BC patch.
       *--------------------------------------------------------------------*/

      {
        const GFace *const gFace = static_cast<const GFace *>(ent);
        SPoint2 par;
        if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), gFace, par))
          goto getNormalFromElements;

        SVector3 boNormal = static_cast<const GFace *>(ent)->normal(par);
        SPoint3 interior(0., 0., 0.);
        int cFace = 0;
        const int nFace = faces.size();
        for(int iFace = 0; iFace != nFace; ++iFace) {
          if(faces[iFace].zoneIndex == zoneIndex) {
            ++cFace;
            interior += faces[iFace].parentElement->barycenter();
          }
        }
        interior /= cFace;
        if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.)
          boNormal.negate();

        zoneBoVec.push_back(VertexBoundary(zoneIndex, gFace->tag(), boNormal,
                                           const_cast<MVertex *>(vertex),
                                           vertIndex));
        patch.add(gFace->tag());
      }
      break;
    default: goto getNormalFromElements;
    }
  }
  return;

getNormalFromElements:;

  /*--------------------------------------------------------------------*
   * Geometry information cannot be used - generate normals from the
   * elements
   *--------------------------------------------------------------------*/

  {
    if(warnNormFromElem && normalSource == 1) {
      Msg::Warning("Some or all boundary normals were determined from mesh "
                   "elements instead of from the geometry");
      warnNormFromElem = false;
    }
    // Sum the normals from each element connected to the vertex and in the
    // zone.  Each normal has to be converted independently into an inwards-
    // pointing normal.
    //**Weight each normal by the area of the boundary element?
    SVector3 boNormal(0.);
    const int nFace = faces.size();
    for(int iFace = 0; iFace != nFace; ++iFace) {
      if(faces[iFace].zoneIndex == zoneIndex) {
        // Normal to the boundary (unknown direction)
        SVector3 bnt =
          faces[iFace].parentElement->getFace(faces[iFace].parentFace).normal();
        // Inwards normal
        const SVector3 inwards(vertex->point(),
                               faces[iFace].parentElement->barycenter());
        if(dot(bnt, inwards) < 0.) bnt.negate();
        boNormal += bnt;
      }
    }
    boNormal.normalize();
    zoneBoVec.push_back(VertexBoundary(
      zoneIndex, 0, boNormal, const_cast<MVertex *>(vertex), vertIndex));
    patch.add(0);
  }
}
Ejemplo n.º 11
0
int GModel::writeCELUM(const std::string &name, bool saveAll,
                       double scalingFactor)
{
  std::string namef = name + "_f";
  FILE *fpf = Fopen(namef.c_str(), "w");
  if(!fpf) {
    Msg::Error("Unable to open file '%s'", namef.c_str());
    return 0;
  }

  std::string names = name + "_s";
  FILE *fps = Fopen(names.c_str(), "w");
  if(!fps) {
    Msg::Error("Unable to open file '%s'", names.c_str());
    fclose(fpf);
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  // count faces and vertices; the CELUM format duplicates vertices on the
  // boundary of CAD patches
  int numf = 0, nums = 0;
  for(fiter it = firstFace(); it != lastFace(); it++) {
    GFace *f = *it;
    if(!saveAll && f->physicals.empty()) continue;
    numf += f->triangles.size();
    std::set<MVertex *> vset;
    for(std::size_t i = 0; i < f->triangles.size(); i++) {
      for(int j = 0; j < 3; j++) vset.insert(f->triangles[i]->getVertex(j));
    }
    nums += vset.size();
  }

  Msg::Info("Writing %d triangles and %d vertices", numf, nums);

  int idf = 1, ids = 1;
  /*
   * a file with faces
     - number of faces
     - empty line
     ... for each face
     - number of the face (starts at 1 : used for read errors)
     - char string (name of geom part, material,... )
     - list of 3 vertex nums
     - empty line
     ...
   * a file with vertices
     - number of vertices
     - conversion factor
     - empty line
     ... for each vertex
     - number of the vertex (starts at 1 : used for read errors)
     - cartesian coordinates of the vertex
     - componants of the exterior oriented normal
     - value of 1st principal curvature
     - value of second princpal curvature
     - components of 1st principal direction
     - components of 2nd principal direction
     - empty line
     ...
  */
  fprintf(fpf, "%d\n\n", numf);
  fprintf(fps, "%d %g\n\n", nums, 1.0);
  for(fiter it = firstFace(); it != lastFace(); it++) {
    GFace *f = *it;
    if(!saveAll && f->physicals.empty()) continue;
    std::vector<MVertex *> vvec;
    std::map<MVertex *, CelumInfo> vmap;
    for(std::size_t i = 0; i < f->triangles.size(); i++) {
      fprintf(fpf, "%d \"face %d\"", idf++, f->tag());
      for(int j = 0; j < 3; j++) {
        MVertex *v = f->triangles[i]->getVertex(j);
        if(!vmap.count(v)) {
          v->setIndex(ids++);
          SPoint2 param;
          bool ok = reparamMeshVertexOnFace(v, f, param);
          if(!ok)
            Msg::Warning("Could not reparamtrize vertex %d on face %d",
                         v->getNum(), f->tag());
          CelumInfo info;
          info.normal = f->normal(param);
          f->curvatures(param, info.dirMax, info.dirMin, info.curvMax,
                        info.curvMin);
          vmap[v] = info;
          vvec.push_back(v);
        }
        fprintf(fpf, " %ld", v->getIndex());
      }
      fprintf(fpf, "\n\n");
    }
    for(std::size_t i = 0; i < vvec.size(); i++) {
      MVertex *v = vvec[i];
      std::map<MVertex *, CelumInfo>::iterator it = vmap.find(v);
      fprintf(fps, "%ld %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n\n",
              it->first->getIndex(), it->first->x(), it->first->y(),
              it->first->z(), it->second.normal.x(), it->second.normal.y(),
              it->second.normal.z(), it->second.curvMin, it->second.curvMax,
              it->second.dirMin.x(), it->second.dirMin.y(),
              it->second.dirMin.z(), it->second.dirMax.x(),
              it->second.dirMax.y(), it->second.dirMax.z());
    }
  }

  fclose(fpf);
  fclose(fps);
  return 1;
}
Ejemplo n.º 12
0
bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gradObj)
{
  // set the mesh to its present position
  std::vector<SPoint3> xyz,uvw;
  mesh.getGEntityPositions(xyz,uvw);
  mesh.updateGEntityPositions();

  //could be better (e.g. store the model in the Mesh:: datastrucure)

  GModel *gm = GModel::current();

  // for all model edges, compute the error between the geometry and the mesh

  maxDistCAD = 0.0;
  double distCAD = 0.0;

  for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
    // do not do straight lines
    if ((*it)->geomType() == GEntity::Line)continue;
    // look at all mesh lines

    std::vector<bool> doWeCompute((*it)->lines.size());
    for (unsigned int i=0;i<(*it)->lines.size(); i++){
      doWeCompute[i] = false;
      for (unsigned int j=0;j<(*it)->lines[i]->getNumVertices(); j++){
        int index = mesh.getFreeVertexStartIndex((*it)->lines[i]->getVertex(j));
        if (index >=0){
          doWeCompute[i] = true;
          continue;
        }
      }
    }

    std::vector<double> dist((*it)->lines.size());
    for (unsigned int i=0;i<(*it)->lines.size(); i++){
      if (doWeCompute[i]){
        // compute the distance from the geometry to the mesh
        dist[i] = MLineGEdgeDistance ( (*it)->lines[i] , *it );
        maxDistCAD = std::max(maxDistCAD,dist[i]);
        distCAD += dist [i] * factor;
      }
    }
    // be clever to compute the derivative : iterate on all
    // Distance = \sum_{lines} Distance (line, GEdge)
    // For a high order vertex, we compute the derivative only by
    // recomputing the distance to one only line
    const double eps = 1.e-6;
    for (unsigned int i=0;i<(*it)->lines.size(); i++){
      if (doWeCompute[i]){
        for (int j=2 ; j<(*it)->lines[i]->getNumVertices()  ; j++){
          MVertex *v = (*it)->lines[i]->getVertex(j);
          int index = mesh.getFreeVertexStartIndex(v);
          //	printf("%d %d (%d %d)\n",v->getNum(),index,v->onWhat()->tag(),v->onWhat()->dim());
          if (index >= 0){
            double t;
            v->getParameter(0,t);
            SPoint3 pp (v->x(),v->y(),v->z());
            GPoint gp = (*it)->point(t+eps);
            v->setParameter(0,t+eps);
            v->setXYZ(gp.x(),gp.y(),gp.z());
            double dist2 = MLineGEdgeDistance ( (*it)->lines[i] , *it );
            double deriv = (dist2 - dist[i])/eps;
            v->setXYZ(pp.x(),pp.y(),pp.z());
            v->setParameter(0,t);
            //	  printf("%g %g %g\n",dist[i],dist2, MLineGEdgeDistance ( (*it)->lines[i] , *it ));
            // get the index of the vertex
            gradObj[index] += deriv * factor;
          }
        }
      }
      //    printf("done\n");
      // For a low order vertex classified on the GEdge, we recompute
    // two distances for the two MLines connected to the vertex
      for (unsigned int i=0;i<(*it)->lines.size()-1; i++){
        MVertex *v =  (*it)->lines[i]->getVertex(1);
        int index = mesh.getFreeVertexStartIndex(v);
        if (index >= 0){
          double t;
          v->getParameter(0,t);
          SPoint3 pp (v->x(),v->y(),v->z());
          GPoint gp = (*it)->point(t+eps);
          v->setParameter(0,t+eps);
          v->setXYZ(gp.x(),gp.y(),gp.z());
          MLine *l1 = (*it)->lines[i];
          MLine *l2 = (*it)->lines[i+1];
          //	printf("%d %d -- %d %d\n",l1->getVertex(0)->getNum(),l1->getVertex(1)->getNum(),l2->getVertex(0)->getNum(),l2->getVertex(1)->getNum());
          double deriv =
            (MLineGEdgeDistance ( l1 , *it ) - dist[i])  /eps +
            (MLineGEdgeDistance ( l2 , *it ) - dist[i+1])/eps;
          v->setXYZ(pp.x(),pp.y(),pp.z());
          v->setParameter(0,t);
          gradObj[index] += deriv * factor;
        }
      }
    }
  }
  //  printf("computing distance : 1D part %12.5E\n",distCAD);

  // now the 3D part !

  std::vector<std::vector<SVector3> > gsfT;
  computeGradSFAtNodes ( (*gm->firstFace())->triangles[0],gsfT);

  std::map<MVertex*,SVector3> normalsToCAD;


  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
    // do not do plane surfaces
    if ((*it)->geomType() == GEntity::Plane)continue;
    std::map<MTriangle*,double> dist;

    std::vector<bool> doWeCompute((*it)->triangles.size());
    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
      doWeCompute[i] = false;
      for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
        int index = mesh.getFreeVertexStartIndex((*it)->triangles[i]->getVertex(j));
        if (index >=0){
          doWeCompute[i] = true;
        }
      }
      if (doWeCompute[i]){
        for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
          MVertex *v = (*it)->triangles[i]->getVertex(j);
          if (normalsToCAD.find(v) == normalsToCAD.end()){
            SPoint2 p_cad;
            reparamMeshVertexOnFace(v, *it, p_cad);
            SVector3 tg_cad = (*it)->normal(p_cad);
            tg_cad.normalize();
            normalsToCAD[v] = tg_cad;
          }
        }
      }
    }

    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
      // compute the distance from the geometry to the mesh
      if(doWeCompute[i]){
        const double d = MFaceGFaceDistanceOld((*it)->triangles[i], *it, &gsfT, &normalsToCAD);
        dist[(*it)->triangles[i]] = d;
        maxDistCAD = std::max(maxDistCAD,d);
        distCAD += d * factor;
      }
    }

    // be clever again to compute the derivatives
    const double eps = 1.e-6;
    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
      if(doWeCompute[i]){
        for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
          //    for (; itm !=v2t.end(); ++itm){
          MVertex   *v = (*it)->triangles[i]->getVertex(j);
          if(v->onWhat()->dim() == 1){
            int index = mesh.getFreeVertexStartIndex(v);
            if (index >= 0){
              MTriangle *t = (*it)->triangles[i];
              GEdge *ge = v->onWhat()->cast2Edge();
              double t_;
              v->getParameter(0,t_);
              SPoint3 pp (v->x(),v->y(),v->z());
              GPoint gp = ge->point(t_+eps);
              v->setParameter(0,t_+eps);
              v->setXYZ(gp.x(),gp.y(),gp.z());
              const double distT = dist[t];
              double deriv =  (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps;
              v->setXYZ(pp.x(),pp.y(),pp.z());
              v->setParameter(0,t_);
              gradObj[index] += deriv * factor;
            }
          }

          if(v->onWhat() == *it){
            int index = mesh.getFreeVertexStartIndex(v);
            if (index >= 0){
              MTriangle *t = (*it)->triangles[i];
              double uu,vv;
              v->getParameter(0,uu);
              v->getParameter(1,vv);
              SPoint3 pp (v->x(),v->y(),v->z());

              const double distT = dist[t];

              GPoint gp = (*it)->point(uu+eps,vv);
              v->setParameter(0,uu+eps);
              v->setXYZ(gp.x(),gp.y(),gp.z());
              double deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps;
              v->setXYZ(pp.x(),pp.y(),pp.z());
              v->setParameter(0,uu);
              gradObj[index] += deriv * factor;

              gp = (*it)->point(uu,vv+eps);
              v->setParameter(1,vv+eps);
              v->setXYZ(gp.x(),gp.y(),gp.z());
              deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps;
              v->setXYZ(pp.x(),pp.y(),pp.z());
              v->setParameter(1,vv);
              gradObj[index+1] += deriv * factor;
            }
          }
        }
      }
    }
  }
  mesh.updateGEntityPositions(xyz,uvw);
  Obj +=distCAD;
  //  printf("computing distance : 2D part %12.5E\n",distCAD);
  //  printf("%22.15E\n",distCAD);
  return true;
}
Ejemplo n.º 13
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]);
    //    std::cout << "(" << midpoint[0] << "," <<midpoint[1] << ") -> (" <<
    //    newP[i][0][0] << "," << newP[i][0][1] << ") " << std::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;
}
Ejemplo n.º 14
0
void Filler2D::pointInsertion2D(GFace *gf, std::vector<MVertex *> &packed,
                                std::vector<SMetric3> &metrics)
{
  // NB/ do not use the mesh in GFace, use the one in backgroundMesh2D!

  //  if(debug) std::cout << " ------------------   OLD -------------------" <<
  //  std::endl; stringstream ssa;
  ////  ssa << "oldbgm_angles_" << gf->tag() << ".pos";
  ////  backgroundMesh::current()->print(ssa.str(),gf,1);
  //  ssa << "oldbgm_sizes_" << gf->tag() << ".pos";
  //  backgroundMesh::current()->print(ssa.str(),gf,0);
  //
  //
  //
  //
  //  if(debug) std::cout << " ------------------   NEW -------------------" <<
  //  std::endl; backgroundMesh2D *bgm2 =
  //  dynamic_cast<backgroundMesh2D*>(BGMManager::get(gf)); stringstream ss2;
  //  ss2 << "basebg_sizefield_" << gf->tag() << ".pos";
  //  bgm2->exportSizeField(ss2.str());
  //
  //
  //
  //  return;
  //

  BGMManager::set_use_cross_field(true);

  const bool goNonLinear = true;
  const bool debug = false;
  const bool export_stuff = true;

  if(debug) std::cout << "ENTERING POINTINSERTION2D" << std::endl;

  double a;

  // acquire background mesh
  if(debug) std::cout << "pointInsertion2D: recover BGM" << std::endl;
  a = Cpu();
  frameFieldBackgroundMesh2D *bgm =
    dynamic_cast<frameFieldBackgroundMesh2D *>(BGMManager::get(gf));
  time_bgm_and_smoothing += (Cpu() - a);

  if(!bgm) {
    Msg::Error("BGM dynamic cast failed in filler2D::pointInsertion2D");
    return;
  }

  // export BGM size field
  if(export_stuff) {
    std::cout << "pointInsertion2D: export size field " << std::endl;
    std::stringstream ss;
    ss << "bg2D_sizefield_" << gf->tag() << ".pos";
    bgm->exportSizeField(ss.str());

    std::cout << "pointInsertion2D : export crossfield " << std::endl;
    std::stringstream sscf;
    sscf << "bg2D_crossfield_" << gf->tag() << ".pos";
    bgm->exportCrossField(sscf.str());

    std::cout << "pointInsertion2D : export smoothness " << std::endl;
    std::stringstream sss;
    sss << "bg2D_smoothness_" << gf->tag() << ".pos";
    bgm->exportSmoothness(sss.str());
  }

  // point insertion algorithm:
  a = Cpu();

  // for debug check...
  int priority_counter = 0;
  std::map<MVertex *, int> vert_priority;

  // get all the boundary vertices
  if(debug) std::cout << "pointInsertion2D : get bnd vertices " << std::endl;
  std::set<MVertex *> bnd_vertices = bgm->get_vertices_of_maximum_dim(1);

  // put boundary vertices in a fifo queue
  std::set<smoothness_point_pair,
           compareSurfacePointWithExclusionRegionPtr_Smoothness>
    fifo;
  std::vector<surfacePointWithExclusionRegion *> vertices;

  // initiate the rtree
  if(debug) std::cout << "pointInsertion2D : initiate RTree " << std::endl;
  RTree<surfacePointWithExclusionRegion *, double, 2, double> rtree;
  SMetric3 metricField(1.0);
  SPoint2 newp[4][NUMDIR];
  std::set<MVertex *>::iterator it = bnd_vertices.begin();

  for(; it != bnd_vertices.end(); ++it) {
    SPoint2 midpoint;
    computeFourNeighbors(bgm, *it, midpoint, goNonLinear, newp, metricField);
    surfacePointWithExclusionRegion *sp =
      new surfacePointWithExclusionRegion(*it, newp, midpoint, metricField);

    smoothness_point_pair mp;
    mp.ptr = sp;
    mp.rank = (1. - bgm->get_smoothness(midpoint[0], midpoint[1]));
    fifo.insert(mp);

    vertices.push_back(sp);
    double _min[2], _max[2];
    sp->minmax(_min, _max);
    rtree.Insert(_min, _max, sp);
  }

  // ---------- main loop -----------------
  while(!fifo.empty()) {
    if(debug)
      std::cout << " -------- fifo.size() = " << fifo.size() << std::endl;
    int count_nbaddedpt = 0;

    surfacePointWithExclusionRegion *parent = (*fifo.begin()).ptr;
    fifo.erase(fifo.begin());

    for(int dir = 0; dir < NUMDIR; dir++) {
      for(int i = 0; i < 4; i++) {
        if(!inExclusionZone(parent->_p[i][dir], rtree, vertices)) {
          GPoint gp = gf->point(parent->_p[i][dir]);
          MFaceVertex *v =
            new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, gp.u(), gp.v());
          SPoint2 midpoint;
          computeFourNeighbors(bgm, v, midpoint, goNonLinear, newp,
                               metricField);
          surfacePointWithExclusionRegion *sp =
            new surfacePointWithExclusionRegion(v, newp, midpoint, metricField,
                                                parent);
          smoothness_point_pair mp;
          mp.ptr = sp;
          mp.rank = (1. - bgm->get_smoothness(gp.u(), gp.v()));

          if(debug) vert_priority[v] = priority_counter++;

          fifo.insert(mp);
          vertices.push_back(sp);
          double _min[2], _max[2];
          sp->minmax(_min, _max);
          rtree.Insert(_min, _max, sp);

          if(debug) {
            std::cout << "  adding node (" << sp->_v->x() << "," << sp->_v->y()
                      << "," << sp->_v->z() << ")" << std::endl;
            std::cout
              << "    ----------------------------- sub --- fifo.size() = "
              << fifo.size() << std::endl;
          }
          count_nbaddedpt++;
        }
      }
    }
    if(debug)
      std::cout << "////////// nbre of added point: " << count_nbaddedpt
                << std::endl;
  }
  time_insertion += (Cpu() - a);

  if(debug) {
    std::stringstream ss;
    ss << "priority_" << gf->tag() << ".pos";
    print_nodal_info(ss.str().c_str(), vert_priority);
    ss.clear();
  }

  // add the vertices as additional vertices in the
  // surface mesh
  char ccc[256];
  sprintf(ccc, "points%d.pos", gf->tag());
  FILE *f = Fopen(ccc, "w");
  if(f) {
    fprintf(f, "View \"\"{\n");
    for(unsigned int i = 0; i < vertices.size(); i++) {
      vertices[i]->print(f, i);
      if(vertices[i]->_v->onWhat() == gf) {
        packed.push_back(vertices[i]->_v);
        metrics.push_back(vertices[i]->_meshMetric);
        SPoint2 midpoint;
        reparamMeshVertexOnFace(vertices[i]->_v, gf, midpoint);
      }
      delete vertices[i];
    }
    fprintf(f, "};");
    fclose(f);
  }
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
static void Subdivide(GFace *gf, bool splitIntoQuads, bool splitIntoHexas,
                      faceContainer &faceVertices)
{

  if(!splitIntoQuads && !splitIntoHexas){
    std::vector<MTriangle*> triangles2;
    for(unsigned int i = 0; i < gf->triangles.size(); i++){
      MTriangle *t = gf->triangles[i];
      if(t->getNumVertices() == 6){
        triangles2.push_back
          (new MTriangle(t->getVertex(0), t->getVertex(3), t->getVertex(5)));
        triangles2.push_back
          (new MTriangle(t->getVertex(3), t->getVertex(4), t->getVertex(5)));
        triangles2.push_back
          (new MTriangle(t->getVertex(3), t->getVertex(1), t->getVertex(4)));
        triangles2.push_back
          (new MTriangle(t->getVertex(5), t->getVertex(4), t->getVertex(2)));
      }
      delete t;
    }
    gf->triangles = triangles2;
  }

  std::vector<MQuadrangle*> quadrangles2;
  for(unsigned int i = 0; i < gf->quadrangles.size(); i++){
    MQuadrangle *q = gf->quadrangles[i];
    if(q->getNumVertices() == 9){
      quadrangles2.push_back
        (new MQuadrangle(q->getVertex(0), q->getVertex(4), q->getVertex(8), q->getVertex(7)));
      quadrangles2.push_back
        (new MQuadrangle(q->getVertex(4), q->getVertex(1), q->getVertex(5), q->getVertex(8)));
      quadrangles2.push_back
        (new MQuadrangle(q->getVertex(8), q->getVertex(5), q->getVertex(2), q->getVertex(6)));
      quadrangles2.push_back
        (new MQuadrangle(q->getVertex(7), q->getVertex(8), q->getVertex(6), q->getVertex(3)));
    }
    delete q;
  }
  if(splitIntoQuads || splitIntoHexas){
    for(unsigned int i = 0; i < gf->triangles.size(); i++){
      MTriangle *t = gf->triangles[i];
      if(t->getNumVertices() == 6){
        SPoint2 pt;
        SPoint3 ptx; t->pnt(0.5, 0.5, 0, ptx);
        bool reparamOK = true;
        for(int k = 0; k < 6; k++){
          SPoint2 temp;
          reparamOK &= reparamMeshVertexOnFace(t->getVertex(k), gf, temp);
          pt[0] += temp[0] / 6.;
          pt[1] += temp[1] / 6.;
        }
        MVertex *newv;
        if (reparamOK){
          GPoint gp = gf->point(pt);
          newv = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, pt[0], pt[1]);
        }
        else {
          newv = new MVertex(ptx.x(), ptx.y(), ptx.z(), gf);
        }
        gf->mesh_vertices.push_back(newv);
        if(splitIntoHexas) faceVertices[t->getFace(0)].push_back(newv);
        quadrangles2.push_back
          (new MQuadrangle(t->getVertex(0), t->getVertex(3), newv, t->getVertex(5)));
        quadrangles2.push_back
          (new MQuadrangle(t->getVertex(3), t->getVertex(1), t->getVertex(4), newv));
        quadrangles2.push_back
          (new MQuadrangle(t->getVertex(5), newv,t->getVertex(4), t->getVertex(2)));
        delete t;
      }
    }
    gf->triangles.clear();
  }
  gf->quadrangles = quadrangles2;

  for(unsigned int i = 0; i < gf->mesh_vertices.size(); i++)
    gf->mesh_vertices[i]->setPolynomialOrder(1);
  gf->deleteVertexArrays();
}