Пример #1
0
static void addOneLayer(const std::vector<MElement*> &v,
                        std::vector<MElement*> &d,
                        std::vector<MElement*> &layer)
{
  std::set<MVertex*> all;
  for (unsigned int i = 0; i < d.size(); i++){
    MElement *e = d[i];
    int n = e->getNumPrimaryVertices();
    for (int j = 0; j < n; j++){
      all.insert(e->getVertex(j));
    }
  }
  layer.clear();
  std::sort(d.begin(), d.end());

  for (unsigned int i = 0; i < v.size(); i++){
    MElement *e = v[i];
    bool found = std::binary_search(d.begin(), d.end(), e);
    // element is not yet there
    if (!found){
      int n = e->getNumPrimaryVertices();
      for (int j = 0; j < n; j++){
        MVertex *vert = e->getVertex(j);
        if (all.find(vert) != all.end()){
          layer.push_back(e);
          j = n;
        }
      }
    }
  }
}
Пример #2
0
bool Mesh::bndDistAndGradients(int iEl, double &f , std::vector<double> &gradF, double eps)
{
  MElement *element = _el[iEl];
  f = 0.;
  // dommage ;-)
  if (element->getDim() != 2)
    return false;

  int currentId = 0;
  std::vector<int> vertex2param(element->getNumVertices());
  for (size_t i = 0; i < element->getNumVertices(); ++i) {
    if (_el2FV[iEl][i] >= 0) {
      vertex2param[i] = currentId;
      currentId += _nPCFV[_el2FV[iEl][i]];
    }
    else
      vertex2param[i] = -1;
  }
  gradF.clear();
  gradF.resize(currentId, 0.);

  const nodalBasis &elbasis = *element->getFunctionSpace();
  bool edgeFound = false;
  for (int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) {
    int clId = elbasis.getClosureId(iEdge, 1);
    const std::vector<int> &closure = elbasis.closures[clId];
    std::vector<MVertex *> vertices;
    GEdge *edge = NULL;
    for (size_t i = 0; i < closure.size(); ++i) {
      MVertex *v = element->getVertex(closure[i]);
      vertices.push_back(v);
      // only valid in 2D
      if ((int)i >= 2 && v->onWhat() && v->onWhat()->dim() == 1) {
        edge = v->onWhat()->cast2Edge();
      }
    }
    if (edge) {
      edgeFound = true;
      std::vector<double> localgrad;
      std::vector<SPoint3> nodes(closure.size());
      std::vector<double> params(closure.size());
      std::vector<bool> onedge(closure.size());
      for (size_t i = 0; i < closure.size(); ++i) {
        nodes[i] = _xyz[_el2V[iEl][closure[i]]];
        onedge[i] = element->getVertex(closure[i])->onWhat() == edge && _el2FV[iEl][closure[i]] >= 0;
        if (onedge[i]) {
          params[i] = _uvw[_el2FV[iEl][closure[i]]].x();
        }else
          reparamMeshVertexOnEdge(element->getVertex(closure[i]), edge, params[i]);
      }
      f += computeBndDistAndGradient(edge, params, vertices, *BasisFactory::getNodalBasis(elbasis.getClosureType(clId)), nodes, onedge, localgrad, eps);
      for (size_t i = 0; i < closure.size(); ++i) {
        if (onedge[i])
	  gradF[vertex2param[closure[i]]] += localgrad[i];
      }
    }
  }
  return edgeFound;
}
Пример #3
0
double elasticitySolver::computeDisplacementError(simpleFunction<double> *f0,
                                                  simpleFunction<double> *f1,
                                                  simpleFunction<double> *f2)
{
  std::cout << "compute displacement error" << std::endl;
  double err = 0.;
  std::set<MVertex *> v;
  std::map<MVertex *, MElement *> vCut;
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    if(elasticFields[i]._e == 0.) continue;
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      if(e->getParent()) {
        for(std::size_t j = 0; j < e->getNumVertices(); ++j) {
          if(vCut.find(e->getVertex(j)) == vCut.end())
            vCut[e->getVertex(j)] = e->getParent();
        }
      }
      else {
        for(std::size_t j = 0; j < e->getNumVertices(); ++j)
          v.insert(e->getVertex(j));
      }
    }
  }
  SolverField<SVector3> Field(pAssembler, LagSpace);
  for(std::set<MVertex *>::iterator it = v.begin(); it != v.end(); ++it) {
    SVector3 val;
    MPoint p(*it);
    Field.f(&p, 0, 0, 0, val);
    SVector3 sol((*f0)((*it)->x(), (*it)->y(), (*it)->z()),
                 (*f1)((*it)->x(), (*it)->y(), (*it)->z()),
                 (*f2)((*it)->x(), (*it)->y(), (*it)->z()));
    double diff = normSq(sol - val);
    err += diff;
  }
  for(std::map<MVertex *, MElement *>::iterator it = vCut.begin();
      it != vCut.end(); ++it) {
    SVector3 val;
    double uvw[3];
    double xyz[3] = {it->first->x(), it->first->y(), it->first->z()};
    it->second->xyz2uvw(xyz, uvw);
    Field.f(it->second, uvw[0], uvw[1], uvw[2], val);
    SVector3 sol((*f0)(xyz[0], xyz[1], xyz[2]), (*f1)(xyz[0], xyz[1], xyz[2]),
                 (*f2)(xyz[0], xyz[1], xyz[2]));
    double diff = normSq(sol - val);
    err += diff;
  }
  printf("Displacement Error = %g\n", sqrt(err));
  return sqrt(err);
}
Пример #4
0
PView *elasticitySolver::buildDisplacementView(const std::string postFileName)
{
  std::cout << "build Displacement View" << std::endl;
  std::set<MVertex *> v;
  std::map<MVertex *, MElement *> vCut;
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    if(elasticFields[i]._e == 0.) continue;
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      if(e->getParent()) {
        for(std::size_t j = 0; j < e->getNumVertices(); ++j) {
          if(vCut.find(e->getVertex(j)) == vCut.end())
            vCut[e->getVertex(j)] = e->getParent();
        }
      }
      else {
        for(std::size_t j = 0; j < e->getNumVertices(); ++j)
          v.insert(e->getVertex(j));
      }
    }
  }
  std::map<int, std::vector<double> > data;
  SolverField<SVector3> Field(pAssembler, LagSpace);
  for(std::set<MVertex *>::iterator it = v.begin(); it != v.end(); ++it) {
    SVector3 val;
    MPoint p(*it);
    Field.f(&p, 0, 0, 0, val);
    std::vector<double> vec(3);
    vec[0] = val(0);
    vec[1] = val(1);
    vec[2] = val(2);
    data[(*it)->getNum()] = vec;
  }
  for(std::map<MVertex *, MElement *>::iterator it = vCut.begin();
      it != vCut.end(); ++it) {
    SVector3 val;
    double uvw[3];
    double xyz[3] = {it->first->x(), it->first->y(), it->first->z()};
    it->second->xyz2uvw(xyz, uvw);
    Field.f(it->second, uvw[0], uvw[1], uvw[2], val);
    std::vector<double> vec(3);
    vec[0] = val(0);
    vec[1] = val(1);
    vec[2] = val(2);
    data[it->first->getNum()] = vec;
  }
  PView *pv = new PView(postFileName, "NodeData", pModel, data, 0.0);
  return pv;
}
Пример #5
0
PView* elasticitySolver::buildLagrangeMultiplierView (const std::string postFileName)
{
  std::cout <<  "build Lagrange Multiplier View"<< std::endl;
  if(!LagrangeMultiplierSpace) return new PView();
  std::set<MVertex*> v;
  for (unsigned int i = 0; i < LagrangeMultiplierFields.size(); ++i)
  {
    for(groupOfElements::elementContainer::const_iterator it =
          LagrangeMultiplierFields[i].g->begin();
        it != LagrangeMultiplierFields[i].g->end(); ++it)
    {
      MElement *e = *it;
      for (int j = 0; j < e->getNumVertices(); ++j) v.insert(e->getVertex(j));
    }
  }
  std::map<int, std::vector<double> > data;
  SolverField<double> Field(pAssembler, LagrangeMultiplierSpace);
  for(std::set<MVertex*>::iterator it = v.begin(); it != v.end(); ++it)
  {
    double val;
    MPoint p(*it);
    Field.f(&p, 0, 0, 0, val);
    std::vector<double> vec;
    vec.push_back(val);
    data[(*it)->getNum()] = vec;
  }
  PView *pv = new PView (postFileName, "NodeData", pModel, data, 0.0);
  return pv;
}
Пример #6
0
PView *thermicSolver::buildTemperatureView(const std::string postFileName)
{
  std::cout << "build Temperature View" << std::endl;
  std::set<MVertex *> v;
  std::map<MVertex *, MElement *> vCut;
  for(std::size_t i = 0; i < thermicFields.size(); ++i) {
    for(groupOfElements::elementContainer::const_iterator it =
          thermicFields[i].g->begin();
        it != thermicFields[i].g->end(); ++it) {
      MElement *e = *it;
      if(e->getParent()) {
        for(std::size_t j = 0; j < e->getNumVertices(); ++j) {
          if(vCut.find(e->getVertex(j)) == vCut.end())
            vCut[e->getVertex(j)] = e->getParent();
        }
      }
      else {
        for(std::size_t j = 0; j < e->getNumVertices(); ++j)
          v.insert(e->getVertex(j));
      }
    }
  }
  std::map<int, std::vector<double> > data;
  SolverField<double> Field(pAssembler, LagSpace);
  for(std::set<MVertex *>::iterator it = v.begin(); it != v.end(); ++it) {
    double val;
    MPoint p(*it);
    Field.f(&p, 0, 0, 0, val); // printf("valv=%g\n",val);
    std::vector<double> vec;
    vec.push_back(val);
    data[(*it)->getNum()] = vec;
  }
  for(std::map<MVertex *, MElement *>::iterator it = vCut.begin();
      it != vCut.end(); ++it) {
    double val;
    double uvw[3];
    double xyz[3] = {it->first->x(), it->first->y(), it->first->z()};
    it->second->xyz2uvw(xyz, uvw);
    Field.f(it->second, uvw[0], uvw[1], uvw[2],
            val); // printf("valvc=%g\n",val);
    std::vector<double> vec;
    vec.push_back(val);
    data[it->first->getNum()] = vec;
  }
  PView *pv = new PView(postFileName, "NodeData", pModel, data, 0.0, 1);
  return pv;
}
Пример #7
0
void elasticitySolver::computeEffectiveStiffness(std::vector<double> stiff)
{
  double st[6] = {0., 0., 0., 0., 0., 0.};
  double volTot = 0.;
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    double E = elasticFields[i]._e;
    double nu = elasticFields[i]._nu;
    SolverField<SVector3> Field(pAssembler, LagSpace);
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      double vol = e->getVolume() * e->getVolumeSign();
      int nbVertex = e->getNumVertices();
      std::vector<SVector3> val(nbVertex);

      double valx[256];
      double valy[256];
      double valz[256];
      for(int k = 0; k < nbVertex; k++) {
        MVertex *v = e->getVertex(k);
        MPoint p(v);
        Field.f(&p, 0, 0, 0, val[k]);
        valx[k] = val[k](0);
        valy[k] = val[k](1);
        valz[k] = val[k](2);
      }

      double gradux[3];
      double graduy[3];
      double graduz[3];
      SPoint3 center = e->barycenterUVW();
      double u = center.x(), v = center.y(), w = center.z();
      e->interpolateGrad(valx, u, v, w, gradux);
      e->interpolateGrad(valy, u, v, w, graduy);
      e->interpolateGrad(valz, u, v, w, graduz);

      double eps[6] = {gradux[0],
                       graduy[1],
                       graduz[2],
                       0.5 * (gradux[1] + graduy[0]),
                       0.5 * (gradux[2] + graduz[0]),
                       0.5 * (graduy[2] + graduz[1])};

      double A = E / (1. + nu);
      double B = A * (nu / (1. - 2 * nu));
      double trace = eps[0] + eps[1] + eps[2];
      st[0] += (A * eps[0] + B * trace) * vol;
      st[1] += (A * eps[1] + B * trace) * vol;
      st[2] += (A * eps[2] + B * trace) * vol;
      st[3] += (A * eps[3]) * vol;
      st[4] += (A * eps[4]) * vol;
      st[5] += (A * eps[5]) * vol;
      volTot += vol;
    }
  }
  for(int i = 0; i < 6; i++) stiff[i] = st[i] / volTot;
}
Пример #8
0
static void calcVertex2Elements(int dim, GEntity *entity, vertElVecMap &vertex2elements)
{
  for (size_t i = 0; i < entity->getNumMeshElements(); ++i) {
    MElement *element = entity->getMeshElement(i);
    if (element->getDim() == dim)
      for (int j = 0; j < element->getNumPrimaryVertices(); ++j)
        vertex2elements[element->getVertex(j)].push_back(element);
  }
}
Пример #9
0
void frameFieldBackgroundMesh2D::computeSmoothness()
{
    smoothness.clear();

    // build vertex -> neighbors table
    std::multimap<MVertex*,MVertex*> vertex2vertex;
    for (std::vector<MElement*>::iterator it = beginelements(); it!=endelements(); it++) {
        MElement *e = *it;
        for (int i=0; i<e->getNumVertices(); i++) {
            MVertex *current = e->getVertex(i);
            for (int j=0; j<e->getNumVertices(); j++) {
                if (i==j) continue;
                MVertex *neighbor = e->getVertex(j);
                vertex2vertex.insert(make_pair(current,neighbor));
            }
        }
    }

    // compute smoothness
    for (std::vector<MVertex*>::iterator it = beginvertices(); it!=endvertices(); it++) {
        MVertex *v = *it;
        double angle_current = angle(v);
        // compare to all neighbors...
        std::pair<std::multimap<MVertex*,MVertex*>::iterator, std::multimap<MVertex*,MVertex*>::iterator> range = vertex2vertex.equal_range(v);
        double minangle,totalangle=0.;
        int N=0;
        for (std::multimap<MVertex*,MVertex*>::iterator itneighbor = range.first; itneighbor!=range.second; itneighbor++) {
            N++;
            minangle=M_PI/2;
            MVertex *v_nb = itneighbor->second;
            double angle_nb = angle(v_nb);
            // angle comparison...
            minangle = std::min(minangle, fabs(angle_current-angle_nb));
            minangle = std::min(minangle, fabs(angle_current-(angle_nb+M_PI/2.)));
            minangle = std::min(minangle, fabs(angle_current-(angle_nb-M_PI/2.)));
            totalangle += minangle;
        }
        totalangle /= N;
        smoothness[v] = 1. - (totalangle/M_PI*2);
    }
}
Пример #10
0
std::set<MVertex *> BGMBase::get_vertices_of_maximum_dim(int dim)
{
  std::set<MVertex *> bnd_vertices;
  for(unsigned int i = 0; i < gf->getNumMeshElements(); i++) {
    MElement *element = gf->getMeshElement(i);
    for(std::size_t j = 0; j < element->getNumVertices(); j++) {
      MVertex *vertex = element->getVertex(j);
      if(vertex->onWhat()->dim() <= dim) bnd_vertices.insert(vertex);
    }
  }
  return bnd_vertices;
}
Пример #11
0
PView *elasticitySolver::buildStrainView(const std::string postFileName)
{
  std::cout << "build strain view" << std::endl;
  std::map<int, std::vector<double> > data;
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    SolverField<SVector3> Field(pAssembler, LagSpace);
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      int nbVertex = e->getNumVertices();
      std::vector<SVector3> val(nbVertex);

      double valx[256];
      double valy[256];
      double valz[256];
      for(int k = 0; k < nbVertex; k++) {
        MVertex *v = e->getVertex(k);
        MPoint p(v);
        Field.f(&p, 0, 0, 0, val[k]);
        valx[k] = val[k](0);
        valy[k] = val[k](1);
        valz[k] = val[k](2);
      }

      double gradux[3];
      double graduy[3];
      double graduz[3];
      double u = 0.33, v = 0.33, w = 0.0;
      e->interpolateGrad(valx, u, v, w, gradux);
      e->interpolateGrad(valy, u, v, w, graduy);
      e->interpolateGrad(valz, u, v, w, graduz);

      std::vector<double> vec(9);
      vec[0] = gradux[0];
      vec[4] = graduy[1];
      vec[8] = graduy[2];
      vec[1] = vec[3] = 0.5 * (gradux[0] + graduy[1]);
      vec[2] = vec[6] = 0.5 * (gradux[0] + graduz[2]);
      vec[5] = vec[7] = 0.5 * (gradux[1] + graduz[2]);

      data[e->getNum()] = vec;
    }
  }
  PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0);
  return pv;
}
Пример #12
0
static int getGenus (std::vector<MElement *> &elements,
                     std::vector<std::vector<MEdge> > &boundaries)
{

  //We suppose MElements are simply connected

  std::set<MEdge, Less_Edge> es;
  std::set<MVertex*> vs;
  int N = 0;
  for(unsigned int i = 0; i < elements.size(); i++){
    N++;
    MElement *e = elements[i];
    for(int j = 0; j < e->getNumVertices(); j++){
      vs.insert(e->getVertex(j));
    }
    for(int j = 0; j < e->getNumEdges(); j++){
      es.insert(e->getEdge(j));
    }
  }

  int poincare = vs.size() - es.size() + N;

  //compute connected boundaries
  int nbBounds = 0;
  std::vector<MEdge> bEdges;
  for(unsigned int i = 0; i < elements.size(); i++){
    for(int j = 0; j < elements[i]->getNumEdges(); j++){
      MEdge me =  elements[i]->getEdge(j);
      if(std::find(bEdges.begin(), bEdges.end(), me) == bEdges.end())
         bEdges.push_back(me);
      else
         bEdges.erase(std::find(bEdges.begin(), bEdges.end(),me));
    }
  }
  nbBounds = connected_bounds(bEdges, boundaries);
  int genus = (int)(-poincare + 2 - nbBounds)/2;

  //printf("************** partition has %d boundaries and genus =%d \n", nbBounds, genus);

  return genus;

}
Пример #13
0
static void drawVerticesPerElement(drawContext *ctx, GEntity *e,
                                   std::vector<T*> &elements)
{
  for(unsigned int i = 0; i < elements.size(); i++){
    MElement *ele = elements[i];
    for(int j = 0; j < ele->getNumVertices(); j++){
      MVertex *v = ele->getVertex(j);
      // FIXME isElementVisible() can be slow: we should also use a
      // vertex array for drawing vertices...
      if(isElementVisible(ele) && v->getVisibility()){
        if(CTX::instance()->mesh.points) {
          if(CTX::instance()->mesh.colorCarousel == 0 ||
             CTX::instance()->mesh.volumesFaces ||
             CTX::instance()->mesh.surfacesFaces){ // by element type
            if(v->getPolynomialOrder() > 1)
              glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertexSup);
            else
              glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex);
          }
          else{
            unsigned int col = getColorByEntity(e);
            glColor4ubv((GLubyte *) & col);
          }
          if(CTX::instance()->mesh.pointType)
            ctx->drawSphere(CTX::instance()->mesh.pointSize, v->x(), v->y(), v->z(),
                            CTX::instance()->mesh.light);
          else{
            glBegin(GL_POINTS);
            glVertex3d(v->x(), v->y(), v->z());
            glEnd();
          }
        }
        if(CTX::instance()->mesh.pointsNum)
          drawVertexLabel(ctx, v->onWhat() ? v->onWhat() : e, v);
      }
    }
  }
}
Пример #14
0
PView *elasticitySolver::buildStressesView(const std::string postFileName)
{
  double sti[6] = {0., 0., 0., 0., 0., 0.};
  double str[6] = {0., 0., 0., 0., 0., 0.};
  double volTot = 0.;
  std::cout << "build stresses view" << std::endl;
  std::map<int, std::vector<double> > data;
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    double E = elasticFields[i]._e;
    double nu = elasticFields[i]._nu;
    SolverField<SVector3> Field(pAssembler, LagSpace);
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      double vol = e->getVolume() * e->getVolumeSign();
      int nbVertex = e->getNumVertices();
      std::vector<SVector3> val(nbVertex);

      double valx[256];
      double valy[256];
      double valz[256];
      for(int k = 0; k < nbVertex; k++) {
        MVertex *v = e->getVertex(k);
        MPoint p(v);
        Field.f(&p, 0, 0, 0, val[k]);
        valx[k] = val[k](0);
        valy[k] = val[k](1);
        valz[k] = val[k](2);
      }

      double gradux[3];
      double graduy[3];
      double graduz[3];
      SPoint3 center = e->barycenterUVW();
      double u = center.x(), v = center.y(), w = center.z();
      e->interpolateGrad(valx, u, v, w, gradux);
      e->interpolateGrad(valy, u, v, w, graduy);
      e->interpolateGrad(valz, u, v, w, graduz);

      double eps[6] = {gradux[0],
                       graduy[1],
                       graduz[2],
                       0.5 * (gradux[1] + graduy[0]),
                       0.5 * (gradux[2] + graduz[0]),
                       0.5 * (graduy[2] + graduz[1])};

      double A = E / (1. + nu);
      double B = A * (nu / (1. - 2 * nu));
      double trace = eps[0] + eps[1] + eps[2];
      double sxx = A * eps[0] + B * trace;
      double syy = A * eps[1] + B * trace;
      double szz = A * eps[2] + B * trace;
      double sxy = A * eps[3];
      double sxz = A * eps[4];
      double syz = A * eps[5];

      std::vector<double> vec(9);
      vec[0] = sxx;
      vec[1] = sxy;
      vec[2] = sxz;
      vec[3] = sxy;
      vec[4] = syy;
      vec[5] = syz;
      vec[6] = sxz;
      vec[7] = syz;
      vec[8] = szz;

      data[e->getNum()] = vec;

      for(int k = 0; k < 6; k++) str[k] += eps[k] * vol;
      sti[0] += sxx * vol;
      sti[1] += syy * vol;
      sti[2] += szz * vol;
      sti[3] += sxy * vol;
      sti[4] += sxz * vol;
      sti[5] += syz * vol;
      volTot += vol;
    }
  }
  for(int i = 0; i < 6; i++) {
    str[i] = str[i] / volTot;
    sti[i] = sti[i] / volTot;
  }
  printf("effective stiffn = ");
  for(int i = 0; i < 6; i++) printf("%g ", sti[i]);
  printf("\n");
  printf("effective strain = ");
  for(int i = 0; i < 6; i++) printf("%g ", str[i]);
  printf("\n");

  PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0);
  return pv;
}
Пример #15
0
static int getAspectRatio(std::vector<MElement *> &elements,
                          std::vector<std::vector<MEdge> > &boundaries)
{

  double area3D = 0.0;
  for(unsigned int i = 0; i <elements.size(); ++i){
    MElement *t = elements[i];
    std::vector<MVertex *> v(3);
    for(int k = 0; k < 3; k++) v[k] = t->getVertex(k);
    double p0[3] = {v[0]->x(), v[0]->y(), v[0]->z()};
    double p1[3] = {v[1]->x(), v[1]->y(), v[1]->z()};
    double p2[3] = {v[2]->x(), v[2]->y(), v[2]->z()};
    double a_3D = fabs(triangle_area(p0, p1, p2));
    area3D += a_3D;
  }

  double tot_length = 0.0;
  for(unsigned int i = 0; i <boundaries.size(); ++i){
    std::vector<MEdge> iBound = boundaries[i];
    double iLength = 0.0;
    for( unsigned int j = 0; j <iBound.size(); ++j){
      MVertex *v0 = iBound[j].getVertex(0);
      MVertex *v1 = iBound[j].getVertex(1);
      const double length = sqrt((v0->x() - v1->x()) * (v0->x() - v1->x()) +
                                 (v0->y() - v1->y()) * (v0->y() - v1->y()) +
                                 (v0->z() - v1->z()) * (v0->z() - v1->z()));
      iLength += length;
    }
    tot_length += iLength;
  }
  int AR = 1;
  if (boundaries.size() > 0){
    tot_length /= boundaries.size();
    AR = (int) ceil(2*3.14*area3D/(tot_length*tot_length));
  }

  //compute AR also with Bounding box
  std::set<MVertex*> vs;
  for(unsigned int i = 0; i < elements.size(); i++){
    MElement *e = elements[i];
    for(int j = 0; j < e->getNumVertices(); j++){
      vs.insert(e->getVertex(j));
    }
  }
  SBoundingBox3d bb;
  std::vector<SPoint3> vertices;
  for (std::set<MVertex* >::iterator it = vs.begin(); it != vs.end(); it++){
    SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z());
    vertices.push_back(pt);
    bb += pt;
  }
  double H = norm(SVector3(bb.max(), bb.min()));

  //SOrientedBoundingBox obbox =  SOrientedBoundingBox::buildOBB(vertices);
  //double H = obbox.getMaxSize();

  double D = H;
  if (boundaries.size()  > 0 ) D = 10e4;
  for (unsigned int i = 0; i < boundaries.size(); i++){
    std::set<MVertex*> vb;
    std::vector<MEdge> iBound = boundaries[i];
    for (unsigned int j = 0; j < iBound.size(); j++){
      MEdge e = iBound[j];
      vb.insert(e.getVertex(0));
      vb.insert(e.getVertex(1));
    }
    std::vector<SPoint3> vBounds;
    SBoundingBox3d bb;
    for (std::set<MVertex* >::iterator it = vb.begin(); it != vb.end(); it++){
      SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z());
      vBounds.push_back(pt);
      bb +=pt;
    }
    double iD = norm(SVector3(bb.max(), bb.min()));
    D = std::min(D, iD);

    //SOrientedBoundingBox obboxD = SOrientedBoundingBox::buildOBB(vBounds);
    //D = std::max(D, obboxD.getMaxSize());
  }
  int AR2 = (int)ceil(H/D);

  return std::max(AR, AR2);
}
Пример #16
0
// This function meshes the top surface of a QuadToTri extrusion.  It returns 0 if it is given a
// non-quadToTri extrusion or if it fails.
// Args:
//       'GFace *to' is the top surface to mesh, 'from' is the source surface, 'pos' is a std::set
//       of vertex positions for the top surface.
int MeshQuadToTriTopSurface( GFace *from, GFace *to, std::set<MVertex*,
                             MVertexLessThanLexicographic> &pos )
{
  if( !to->meshAttributes.extrude || !to->meshAttributes.extrude->mesh.QuadToTri  )
   return 0;

  // if the source is all triangles, then just let this function is not needed. Return 1.
  if( from->triangles.size() && !from->quadrangles.size() )
    return 1;

  // in weird case of NO quads and NO tri
  if( !from->triangles.size() && !from->quadrangles.size() )
    return 0;


  ExtrudeParams *ep = to->meshAttributes.extrude;
  if( !ep || !ep->mesh.ExtrudeMesh || !(ep->geo.Mode == COPIED_ENTITY) ){
    Msg::Error("In MeshQuadToTriTopSurface(), incomplete or no "
		"extrude information for top face %d.", to->tag() );
    return 0;
  }
  
  // is this a quadtri extrusion with added vertices?
  bool is_addverts = false;
  if( ep && (ep->mesh.QuadToTri == QUADTRI_ADDVERTS_1 || ep->mesh.QuadToTri == QUADTRI_ADDVERTS_1_RECOMB) )
    is_addverts = true;

  // execute this section if 
  // IF this is a 'no new vertices' quadToTri, mesh the surfaces according to this modified
  // least point value method: if a 3 boundary point quad, draw diagonals from middle corner toward
  // interior.  If a a 2- or 1- point boundary quad, draw toward lowest pointer number NOT on boundary.
  // All interior quad, draw diagonal to vertex with lowest pointer number.

  if( !is_addverts ){
    std::set<MVertex*, MVertexLessThanLexicographic> pos_src_edge;
    QuadToTriInsertFaceEdgeVertices(from, pos_src_edge);
    std::set<MVertex*, MVertexLessThanLexicographic>::iterator itp;

    // loop through each element source quadrangle and extrude
    for(unsigned int i = 0; i < from->quadrangles.size(); i++){
      std::vector<MVertex*> verts;
      for(int j = 0; j < from->quadrangles[i]->getNumVertices(); j++){
        MVertex *v = from->quadrangles[i]->getVertex(j);
        MVertex tmp(v->x(), v->y(), v->z(), 0, -1);
        ExtrudeParams *ep = to->meshAttributes.extrude;
        ep->Extrude(ep->mesh.NbLayer - 1, ep->mesh.NbElmLayer[ep->mesh.NbLayer - 1],
                    tmp.x(), tmp.y(), tmp.z());
        itp = pos.find(&tmp);
        if(itp == pos.end()){ // FIXME: workaround
          Msg::Info("Linear search for (%.16g, %.16g, %.16g)", tmp.x(), tmp.y(), tmp.z());
          itp = tmp.linearSearch(pos);
        }
        if(itp == pos.end()) {
          Msg::Error("In MeshQuadToTriTopSurface(), Could not find "
                     "extruded vertex (%.16g, %.16g, %.16g) in surface %d",
              tmp.x(), tmp.y(), tmp.z(), to->tag());
          to->triangles.reserve(to->triangles.size()+1);
          return 0;
        }
        verts.push_back(*itp);
      }


      if( verts.size() != 4 ){
        Msg::Error("During mesh of QuadToTri surface %d, %d vertices found "
                   "in quad of source surface %d.", to->tag(), verts.size(),
                   from->tag() );
        return 0;
      }

      // make the element
      MElement *element = from->quadrangles[i];

      // count vertices that are on a boundary edge
      int edge_verts_count = 0;
      //int skip_index = 0;
      int bnd_indices[4];
      for( int p = 0; p < element->getNumVertices(); p++ ){
        if( pos_src_edge.find( element->getVertex(p) ) != pos_src_edge.end() ){
          edge_verts_count++;
          bnd_indices[p] = 1;
        }
        else{
          //skip_index = p;
          bnd_indices[p] = 0;
        }
      }

      // Apply modified lowest vertex pointer diagonalization
      int low_index = -1;
      if( edge_verts_count == 3 || edge_verts_count == 2 || edge_verts_count == 1 ){
        for( int p = 0; p < 4; p++ ){
          if( !bnd_indices[p] && verts[p] != element->getVertex(p) ){
            if( low_index < 0 )
              low_index = p;
            else if( verts[p] < verts[low_index] )
              low_index = p;
          }
        }
        if( low_index < 0 ) // what if they are all degenerate?  Avoid the out-of-bounds error.
          low_index = 0;
      }

      // lowest possible vertex pointer, regardless of if on edge or not
      else if( edge_verts_count == 4 || edge_verts_count == 0 )
        low_index = getIndexForLowestVertexPointer(verts);

      addTriangle( verts[low_index],verts[(low_index+1)%verts.size()],
                   verts[(low_index+2)%verts.size()],to);
      addTriangle( verts[low_index],verts[(low_index+2)%verts.size()],
                   verts[(low_index+3)%verts.size()],to);
    }
    return 1;
  }


  // AFTER THIS POINT IN FUNCTION, CODE IS ALL FOR 'ADD INTERNAL VERTEX' EXTRUSIONS (Less restrictive).

  // if source face is unstructured, can try to make the top mesh a little neater
  GFace *root_source = findRootSourceFaceForFace( from );
  ExtrudeParams *ep_src = root_source->meshAttributes.extrude;
  bool struct_root = false;
  if( root_source &&
      ( (ep_src && ep_src->mesh.ExtrudeMesh && ep_src->geo.Mode == EXTRUDED_ENTITY) ||
        root_source->meshAttributes.method == MESH_TRANSFINITE ) )
    struct_root = true;

  if( !struct_root && MeshQuadToTriTopUnstructured(from, to, pos) )
    return 1;

  // And top surface for the 'added internal vertex' method can be meshed quite easily
  else{
    std::set<MVertex *, MVertexLessThanLexicographic >::iterator itp;
    // loop through each element source quadrangle and extrude
    for(unsigned int i = 0; i < from->quadrangles.size(); i++){
      std::vector<MVertex*> verts;
      for(int j = 0; j < from->quadrangles[i]->getNumVertices(); j++){
        MVertex *v = from->quadrangles[i]->getVertex(j);
        MVertex tmp(v->x(), v->y(), v->z(), 0, -1);
        ExtrudeParams *ep = to->meshAttributes.extrude;
        ep->Extrude(ep->mesh.NbLayer - 1, ep->mesh.NbElmLayer[ep->mesh.NbLayer - 1],
                    tmp.x(), tmp.y(), tmp.z());
        itp = pos.find(&tmp);
        if(itp == pos.end()){ // FIXME: workaround
          Msg::Info("Linear search for (%.16g, %.16g, %.16g)", tmp.x(), tmp.y(), tmp.z());
          itp = tmp.linearSearch(pos);
        }
        if(itp == pos.end()) {
          Msg::Error("In MeshQuadToTriTopSurface(), Could not find "
                     "extruded vertex (%.16g, %.16g, %.16g) in surface %d",
              tmp.x(), tmp.y(), tmp.z(), to->tag());
          to->triangles.reserve(to->triangles.size()+1);
          return 0;
        }
        verts.push_back(*itp);
      }


      if( verts.size() != 4 ){
        Msg::Error("During mesh of QuadToTri surface %d, %d vertices found "
                   "in quad of source surface %d.", to->tag(), verts.size(),
                   from->tag() );
        return 0;
      }

      // make the elements
      addTriangle( verts[0],verts[2], verts[3],to);
      addTriangle( verts[0],verts[1], verts[2],to);
    }
    return 1;
  }

  return 0;

}
Пример #17
0
int GModel::writeDIFF(const std::string &name, bool binary, bool saveAll,
                      double scalingFactor)
{
  if(binary){
    Msg::Error("Binary DIFF output is not implemented");
    return 0;
  }

  FILE *fp = Fopen(name.c_str(), binary ? "wb" : "w");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  // get the number of vertices and index the vertices in a continuous
  // sequence
  int numVertices = indexMeshVertices(saveAll);

  // tag the vertices according to which surface they belong to (Note
  // that we use a brute force approach here, so that we can deal with
  // models with incomplete topology. For example, when we merge 2 STL
  // triangulations we don't have the boundary information between the
  // faces, and the vertices would end up categorized on either one.)
  std::vector<std::list<int> > vertexTags(numVertices);
  std::list<int> boundaryIndicators;
  for(riter it = firstRegion(); it != lastRegion(); it++){
    std::list<GFace*> faces = (*it)->faces();
    for(std::list<GFace*>::iterator itf = faces.begin(); itf != faces.end(); itf++){
      GFace *gf = *itf;
      boundaryIndicators.push_back(gf->tag());
      for(unsigned int i = 0; i < gf->getNumMeshElements(); i++){
        MElement *e = gf->getMeshElement(i);
        for(int j = 0; j < e->getNumVertices(); j++){
          MVertex *v = e->getVertex(j);
          if(v->getIndex() > 0)
            vertexTags[v->getIndex() - 1].push_back(gf->tag());
        }
      }
    }
  }
  boundaryIndicators.sort();
  boundaryIndicators.unique();
  for(int i = 0; i < numVertices; i++){
    vertexTags[i].sort();
    vertexTags[i].unique();
  }

  // get all the entities in the model
  std::vector<GEntity*> entities;
  getEntities(entities);

  // find max dimension of mesh elements we need to save
  int dim = 0;
  for(unsigned int i = 0; i < entities.size(); i++)
    if(entities[i]->physicals.size() || saveAll)
      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++)
        dim = std::max(dim, entities[i]->getMeshElement(j)->getDim());

  // loop over all elements we need to save
  int numElements = 0, maxNumNodesPerElement = 0;
  for(unsigned int i = 0; i < entities.size(); i++){
    if(entities[i]->physicals.size() || saveAll){
      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
        MElement *e = entities[i]->getMeshElement(j);
        if(e->getStringForDIFF() && e->getDim() == dim){
          numElements++;
          maxNumNodesPerElement = std::max(maxNumNodesPerElement, e->getNumVertices());
        }
      }
    }
  }

  fprintf(fp, "\n\n");
  fprintf(fp, " Finite element mesh (GridFE):\n\n");
  fprintf(fp, " Number of space dim. =   3\n");
  fprintf(fp, " Number of elements   =  %d\n", numElements);
  fprintf(fp, " Number of nodes      =  %d\n\n", numVertices);
  fprintf(fp, " All elements are of the same type : dpTRUE\n");
  fprintf(fp, " Max number of nodes in an element: %d \n", maxNumNodesPerElement);
  fprintf(fp, " Only one subdomain               : dpFALSE\n");
  fprintf(fp, " Lattice data                     ? 0\n\n\n\n");
  fprintf(fp, " %d Boundary indicators:  ", (int)boundaryIndicators.size());
  for(std::list<int>::iterator it = boundaryIndicators.begin();
      it != boundaryIndicators.end(); it++)
    fprintf(fp, " %d", *it);

  fprintf(fp, "\n\n\n");
  fprintf(fp,"  Nodal coordinates and nodal boundary indicators,\n");
  fprintf(fp,"  the columns contain:\n");
  fprintf(fp,"   - node number\n");
  fprintf(fp,"   - coordinates\n");
  fprintf(fp,"   - no of boundary indicators that are set (ON)\n");
  fprintf(fp,"   - the boundary indicators that are set (ON) if any.\n");
  fprintf(fp,"#\n");

  // write mesh vertices
  for(unsigned int i = 0; i < entities.size(); i++){
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
      MVertex *v = entities[i]->mesh_vertices[j];
      if(v->getIndex() > 0){
        v->writeDIFF(fp, binary, scalingFactor);
        fprintf(fp, " [%d] ", (int)vertexTags[v->getIndex() - 1].size());
        for(std::list<int>::iterator it = vertexTags[v->getIndex() - 1].begin();
            it != vertexTags[v->getIndex() - 1].end(); it++)
          fprintf(fp," %d ", *it);
        fprintf(fp,"\n");
      }
    }
  }

  fprintf(fp, "\n");
  fprintf(fp, "\n");
  fprintf(fp,     "  Element types and connectivity\n");
  fprintf(fp,     "  the columns contain:\n");
  fprintf(fp,     "   - element number\n");
  fprintf(fp,     "   - element type\n");
  fprintf(fp,     "   - subdomain number \n");
  fprintf(fp,     "   - the global node numbers of the nodes in the element.\n");
  fprintf(fp,     "#\n");

  // write mesh elements
  int num = 0;
  for(unsigned int i = 0; i < entities.size(); i++){
    if(entities[i]->physicals.size() || saveAll){
      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
        MElement *e = entities[i]->getMeshElement(j);
        if(e->getStringForDIFF() && e->getDim() == dim)
          e->writeDIFF(fp, ++num, binary, entities[i]->tag());
      }
    }
  }
  fprintf(fp, "\n");

  fclose(fp);
  return 1;
}
Пример #18
0
int GModel::writeINP(const std::string &name, bool saveAll, bool saveGroupsOfNodes,
                     double scalingFactor)
{
  FILE *fp = Fopen(name.c_str(), "w");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  indexMeshVertices(saveAll);
  std::vector<GEntity*> entities;
  getEntities(entities);

  fprintf(fp, "*Heading\n");
  fprintf(fp, " %s\n", name.c_str());

  fprintf(fp, "*Node\n");
  for(unsigned int i = 0; i < entities.size(); i++)
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++)
      entities[i]->mesh_vertices[j]->writeINP(fp, scalingFactor);

  for(viter it = firstVertex(); it != lastVertex(); ++it){
    writeElementsINP(fp, *it, (*it)->points, saveAll);
  }
  for(eiter it = firstEdge(); it != lastEdge(); ++it){
    writeElementsINP(fp, *it, (*it)->lines, saveAll);
  }
  for(fiter it = firstFace(); it != lastFace(); ++it){
    writeElementsINP(fp, *it, (*it)->triangles, saveAll);
    writeElementsINP(fp, *it, (*it)->quadrangles, saveAll);
  }
  for(riter it = firstRegion(); it != lastRegion(); ++it){
    writeElementsINP(fp, *it, (*it)->tetrahedra, saveAll);
    writeElementsINP(fp, *it, (*it)->hexahedra, saveAll);
    writeElementsINP(fp, *it, (*it)->prisms, saveAll);
    writeElementsINP(fp, *it, (*it)->pyramids, saveAll);
  }

  std::map<int, std::vector<GEntity*> > groups[4];
  getPhysicalGroups(groups);

  // save elements sets for each physical group
  for(int dim = 0; dim <= 3; dim++){
    for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin();
        it != groups[dim].end(); it++){
      std::vector<GEntity *> &entities = it->second;
      fprintf(fp, "*ELSET,ELSET=%s\n", physicalName(this, dim, it->first).c_str());
      int n = 0;
      for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
          MElement *e = entities[i]->getMeshElement(j);
          if(n && !(n % 10)) fprintf(fp, "\n");
          fprintf(fp, "%d, ", e->getNum());
          n++;
        }
      }
      fprintf(fp, "\n");
    }
  }

  // save node sets for each physical group
  if(saveGroupsOfNodes){
    for(int dim = 1; dim <= 3; dim++){
      for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin();
          it != groups[dim].end(); it++){
        std::set<MVertex*> nodes;
        std::vector<GEntity *> &entities = it->second;
        for(unsigned int i = 0; i < entities.size(); i++){
          for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
            MElement *e = entities[i]->getMeshElement(j);
            for (int k = 0; k < e->getNumVertices(); k++)
              nodes.insert(e->getVertex(k));
          }
        }
        fprintf(fp, "*NSET,NSET=%s\n", physicalName(this, dim, it->first).c_str());
        int n = 0;
        for(std::set<MVertex*>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++){
          if(n && !(n % 10)) fprintf(fp, "\n");
          fprintf(fp, "%d, ", (*it2)->getIndex());
          n++;
        }
        fprintf(fp, "\n");
      }
    }
  }

  fclose(fp);
  return 1;
}
Пример #19
0
PView *GMSH_DistancePlugin::execute(PView *v)
{
  int id_pt   = (int) DistanceOptions_Number[0].def;
  int id_line = (int) DistanceOptions_Number[1].def;
  int id_face = (int) DistanceOptions_Number[2].def;
  double type = (double) DistanceOptions_Number[3].def;
  int ortho   = (int) DistanceOptions_Number[6].def;

  PView *view = new PView();
  _data = getDataList(view);
#if defined(HAVE_SOLVER)
#if defined(HAVE_TAUCS)
  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
#else
  linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>;
  lsys->setNoisy(1);
  lsys->setGmres(1);
  lsys->setPrec(5.e-8);
#endif
  dofManager<double> * dofView = new dofManager<double>(lsys);
#endif

  std::vector<GEntity*> _entities;
  GModel::current()->getEntities(_entities);
  if (!_entities.size() || !_entities[_entities.size()-1]->getMeshElement(0)) {
    Msg::Error("This plugin needs a mesh !");
    return view;
  }

  GEntity* ge = _entities[_entities.size()-1];
  int integrationPointTetra[2] = {0,0};

  int numnodes = 0;
  for (unsigned int i = 0; i < _entities.size()-1; i++)
    numnodes += _entities[i]->mesh_vertices.size();
  int totNodes = numnodes + _entities[_entities.size()-1]->mesh_vertices.size();
  int order = ge->getMeshElement(0)->getPolynomialOrder();
  int totNumNodes = totNodes + ge->getNumMeshElements()*integrationPointTetra[order-1];

  std::vector<SPoint3> pts;
  std::vector<double> distances;
  std::vector<MVertex* > pt2Vertex;
  pts.clear();
  distances.clear();
  pt2Vertex.clear();
  pts.reserve(totNumNodes);
  distances.reserve(totNumNodes);
  pt2Vertex.reserve(totNumNodes);

  std::map<MVertex*,double> _distanceE_map;
  std::map<MVertex*,int> _isInYarn_map;
  std::vector<int> index;
  std::vector<double> distancesE;
  std::vector<double> distances2;
  std::vector<double> distancesE2;
  std::vector<int> isInYarn;
  std::vector<int> isInYarn2;
  std::vector<SPoint3> closePts;
  std::vector<SPoint3> closePts2;

  for (int i=0; i<totNumNodes; i++) {
    distances.push_back(1.e22);
  }

  int k = 0;
  for (unsigned int i=0; i<_entities.size(); i++){
    GEntity* ge = _entities[i];
    _maxDim = std::max(_maxDim, ge->dim());
    for (unsigned int j=0; j<ge->mesh_vertices.size(); j++) {
      MVertex *v = ge->mesh_vertices[j];
      pts.push_back(SPoint3(v->x(), v->y(), v->z()));
      _distance_map.insert(std::make_pair(v, 0.0));
/* TO DO (by AM)
      SPoint3 p_empty();
      _closePts_map.insert(std::make_pair(v, p_empty));
*/
      pt2Vertex[k] = v;
      k++;
    }
  }

  // Compute geometrical distance to mesh boundaries
  //------------------------------------------------------
  if (type < 0.0 ) {

    bool existEntity = false;

    for (unsigned int i=0; i<_entities.size(); i++) {
      GEntity* g2 = _entities[i];
      int gDim = g2->dim();
      std::vector<int> phys = g2->getPhysicalEntities();
      bool computeForEntity = false;
      for(unsigned int k = 0; k<phys.size(); k++) {
        int tagp = phys[k];
        if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1)
          computeForEntity = true;
        else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) ||
                 (tagp == id_face && gDim == 2))
          computeForEntity = true;
      }
      if (computeForEntity) {
        existEntity = true;
        for (unsigned int k = 0; k < g2->getNumMeshElements(); k++) {
          std::vector<double> iDistances;
          std::vector<SPoint3> iClosePts;
          std::vector<double> iDistancesE;
          std::vector<int> iIsInYarn;
          MElement *e = g2->getMeshElement(k);
          MVertex *v1 = e->getVertex(0);
          MVertex *v2 = e->getVertex(1);
          SPoint3 p1(v1->x(), v1->y(), v1->z());
          SPoint3 p2(v2->x(), v2->y(), v2->z());
          if ((e->getNumVertices() == 2 && order == 1) ||
              (e->getNumVertices() == 3 && order == 2)) {
            signedDistancesPointsLine(iDistances, iClosePts, pts, p1, p2);
          }
          else if ((e->getNumVertices() == 3 && order == 1) ||
                   (e->getNumVertices() == 6 && order == 2)) {
            MVertex *v3 = e->getVertex(2);
            SPoint3 p3 (v3->x(),v3->y(),v3->z());
            signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1, p2, p3);
          }
          for (unsigned int kk=0; kk<pts.size(); kk++) {
            if (std::abs(iDistances[kk]) < distances[kk]) {
              distances[kk] = std::abs(iDistances[kk]);
              MVertex *v = pt2Vertex[kk];
              _distance_map[v] = distances[kk];
              /* TO DO (by AM)
              _closePts_map[v] = iClosePts[kk];
              */
            }
          }
        }
      }
    }
    if (!existEntity){
      if (id_pt != 0)   Msg::Error("The Physical Point does not exist !");
      if (id_line != 0) Msg::Error("The Physical Line does not exist !");
      if (id_face != 0) Msg::Error("The Physical Surface does not exist !");
      return view;
    }

    printView(_entities, _distance_map);

    /* TO DO (by AM)
    printView(_entities, _closePts_map);
    */
  }

  // Compute PDE for distance function
  //-----------------------------------
  else if (type > 0.0) {

#if defined(HAVE_SOLVER)

    bool existEntity = false;
    SBoundingBox3d bbox;
    for(unsigned int i = 0; i < _entities.size(); i++){
      GEntity* ge = _entities[i];
      int gDim = ge->dim();
      bool fixForEntity = false;
      std::vector<int> phys = ge->getPhysicalEntities();
      for(unsigned int k = 0; k < phys.size(); k++) {
        int tagp = phys[k];
        if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1)
          fixForEntity = true;
        else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) ||
                 (tagp == id_face && gDim == 2) )
          fixForEntity = true;
      }
      if (fixForEntity) {
        existEntity = true;
        for (unsigned int i = 0; i < ge->getNumMeshElements(); ++i) {
          MElement *t = ge->getMeshElement(i);
          for (int k=0; k<t->getNumVertices(); k++) {
            MVertex *v = t->getVertex(k);
            dofView->fixVertex(v, 0, 1, 0.);
            bbox += SPoint3(v->x(), v->y(), v->z());
          }
        }
      }
    }

    if (!existEntity){
      if (id_pt != 0)   Msg::Error("The Physical Point does not exist !");
      if (id_line != 0) Msg::Error("The Physical Line does not exist !");
      if (id_face != 0) Msg::Error("The Physical Surface does not exist !");
      return view;
    }

    std::vector<MElement *> allElems;
    for(unsigned int ii = 0; ii < _entities.size(); ii++){
      if(_entities[ii]->dim() == _maxDim) {
        GEntity *ge = _entities[ii];
        for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i) {
          MElement *t = ge->getMeshElement(i);
          allElems.push_back(t);
          for (int k = 0; k < t->getNumVertices(); k++)
            dofView->numberVertex(t->getVertex(k), 0, 1);
        }
      }
    }

    double L = norm(SVector3(bbox.max(), bbox.min()));
    double mu = type*L;

    simpleFunction<double> DIFF(mu*mu), ONE(1.0);
    distanceTerm distance(GModel::current(), 1, &DIFF, &ONE);

    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      SElement se((*it));
      distance.addToMatrix(*dofView, &se);
    }
    groupOfElements gr(allElems);
    distance.addToRightHandSide(*dofView, gr);

    Msg::Info("Distance Computation: Assembly done");
    lsys->systemSolve();
    Msg::Info("Distance Computation: System solved");

    for (std::map<MVertex*,double >::iterator itv = _distance_map.begin();
         itv != _distance_map.end() ; ++itv) {
      MVertex *v = itv->first;
      double value;
      dofView->getDofValue(v, 0, 1, value);
      value = std::min(0.9999, value);
      double dist = -mu * log(1. - value);
      itv->second = dist;
    }

    printView(_entities, _distance_map);

#endif
  }

  _data->setName("distance");
  _data->Time.push_back(0);
  _data->setFileName(_fileName.c_str());
  _data->finalize();

  // compute also orthogonal vector to distance field
  // A Uortho = -C DIST
  //------------------------------------------------
  if (ortho > 0) {
#if defined(HAVE_SOLVER)

#ifdef HAVE_TAUCS
    linearSystemCSRTaucs<double> *lsys2 = new linearSystemCSRTaucs<double>;
#else
    linearSystemCSRGmm<double> *lsys2 = new linearSystemCSRGmm<double>;
    lsys->setNoisy(1);
    lsys->setGmres(1);
    lsys->setPrec(5.e-8);
#endif
    dofManager<double> myAssembler(lsys2);
    simpleFunction<double> ONE(1.0);

    double dMax = 1.0; //EMI TO CHANGE

    std::vector<MElement *> allElems;
    for(unsigned int ii = 0; ii < _entities.size(); ii++){
      if (_entities[ii]->dim() == _maxDim) {
        GEntity *ge = _entities[ii];
        for (unsigned int i=0; i<ge->getNumMeshElements(); ++i) {
          MElement *t = ge->getMeshElement(i);
          double vMean = 0.0;
          for (int k = 0; k < t->getNumVertices(); k++) {
            std::map<MVertex*, double>::iterator it = _distance_map.find(t->getVertex(k));
            vMean += it->second;
          }
          vMean /= t->getNumVertices();
          if (vMean < dMax)
            allElems.push_back(ge->getMeshElement(i));
        }
      }
    }

    int mid = (int)floor(allElems.size() / 2.);
    MElement *e = allElems[mid];
    MVertex *vFIX = e->getVertex(0);
    myAssembler.fixVertex(vFIX, 0, 1, 0.0);

    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      MElement *t = *it;
      for(int k = 0; k < t->getNumVertices(); k++)
        myAssembler.numberVertex(t->getVertex(k), 0, 1);
    }

    orthogonalTerm *ortho;
    ortho  = new orthogonalTerm(GModel::current(), 1, &ONE, &_distance_map);
    // if (type  < 0)
    //   ortho  = new orthogonalTerm(GModel::current(), 1, &ONE, view);
    // else
    //   ortho  = new orthogonalTerm(GModel::current(), 1, &ONE, dofView);

    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      SElement se((*it));
      ortho->addToMatrix(myAssembler, &se);
    }
    groupOfElements gr(allElems);
    ortho->addToRightHandSide(myAssembler, gr);

    Msg::Info("Orthogonal Computation: Assembly done");
    lsys2->systemSolve();
    Msg::Info("Orthogonal Computation: System solved");

    PView *view2 = new PView();
    PViewDataList *data2 = getDataList(view2);
    data2->setName("ortogonal field");

    Msg::Info("Writing  orthogonal.pos");
    FILE * f5 = Fopen("orthogonal.pos","w");
    fprintf(f5,"View \"orthogonal\"{\n");
    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      MElement *e = *it;

    int numNodes = e->getNumVertices();
    if (e->getType() == TYPE_POLYG)
      numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices();
    std::vector<double> x(numNodes), y(numNodes), z(numNodes);
    std::vector<double> *out2 = data2->incrementList(1, e->getType(), numNodes);
    std::vector<MVertex*> nods;
    std::vector<double> orth;

    if(!e->getNumChildren())
      for(int i=0; i<numNodes; i++)
        nods.push_back(e->getVertex(i));
    else
      for(int i = 0; i < e->getNumChildren(); i++)
        for(int j = 0; j < e->getChild(i)->getNumVertices(); j++)
          nods.push_back(e->getChild(i)->getVertex(j));

    for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->x());
    for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->y());
    for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->z());

    if (_maxDim == 2)
      switch (numNodes) {
        case 2: fprintf(f5,"SL("); break;
        case 3: fprintf(f5,"ST("); break;
        case 4: fprintf(f5,"SQ("); break;
        default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break;
      }
    else if (_maxDim == 3)
      switch (numNodes) {
        case 4: fprintf(f5,"SS("); break;
        case 8: fprintf(f5,"SH("); break;
        case 6: fprintf(f5,"SI("); break;
        case 5: fprintf(f5,"SY("); break;
        default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break;
      }

    for (int j=0; j<numNodes; j++) {
      MVertex *v =  nods[j];
      if (j)
        fprintf(f5, ",%g,%g,%g", v->x(), v->y(), v->z());
      else
        fprintf(f5, "%g,%g,%g", v->x(), v->y(), v->z());
      double value;
      myAssembler.getDofValue(v, 0, 1, value);
      orth.push_back(value);
    }
    fprintf(f5,"){");
    for (unsigned int i=0; i<orth.size(); i++) {
      out2->push_back(orth[i]);
      if (i)
        fprintf(f5,",%g", orth[i]);
      else
        fprintf(f5,"%g", orth[i]);
    }
    fprintf(f5,"};\n");

  }
  fprintf(f5,"};\n");
  fclose(f5);

  lsys->clear();
  lsys2->clear();

  data2->Time.push_back(0);
  data2->setFileName("orthogonal.pos");
  data2->finalize();

#endif
  }

  return view;
}
Пример #20
0
void Centerline::extrudeBoundaryLayerWall(GEdge* gin, std::vector<GEdge*> boundEdges)
{
  Msg::Info("Centerline: extrude boundary layer wall (%d, %g%%R) ", nbElemLayer,  hLayer);

  //orient extrude direction outward
  int dir = 0;
  MElement *e = current->getFaceByTag(1)->getMeshElement(0);
  SVector3 ne = e->getFace(0).normal();
  SVector3 ps(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z());
  double xyz[3] = {ps.x(), ps.y(), ps.z()};
  ANNidx index[1];
  ANNdist dist[1];
  kdtree->annkSearch(xyz, 1, index, dist);
  ANNpointArray nodes = kdtree->thePoints();
  SVector3 pc(nodes[index[0]][0], nodes[index[0]][1], nodes[index[0]][2]);
  SVector3 nc = ps-pc;
  if (dot(ne,nc) < 0) dir = 1;
  if (dir == 1 && hLayer > 0 ) hLayer *= -1.0;

  //int shift = 0;
  //if(is_cut) shift = NE;
  for (int i= 0; i< NF; i++){
    GFace *gfc ;
    if (is_cut) gfc = current->getFaceByTag(NF+i+1);
    else gfc = current->getFaceByTag(i+1);
    current->setFactory("Gmsh");
    //view -5 to scale hLayer by radius in BoundaryLayers.cpp
    std::vector<GEntity*> extrudedE = current->extrudeBoundaryLayer
      (gfc, nbElemLayer,  hLayer, dir, -5);
    GFace *eFace = (GFace*) extrudedE[0];
    eFace->addPhysicalEntity(5);
    current->setPhysicalName("outerWall", 2, 5);//dim 2 tag 5
    GRegion *eRegion = (GRegion*) extrudedE[1];
    eRegion->addPhysicalEntity(6);
    current->setPhysicalName("wallVolume", 3, 6);//dim 3 tag 6

    //if double extruded layer
    if (nbElemSecondLayer > 0){
      std::vector<GEntity*> extrudedESec = current->extrudeBoundaryLayer
      	(eFace, nbElemSecondLayer,  hSecondLayer, dir, -5);
      GFace *eFaceSec = (GFace*) extrudedESec[0];
      eFaceSec->addPhysicalEntity(9);                    //tag 9
      current->setPhysicalName("outerSecondWall", 2, 9);//dim 2 tag 9
      GRegion *eRegionSec = (GRegion*) extrudedESec[1];
      eRegionSec->addPhysicalEntity(10);             //tag 10
      current->setPhysicalName("wallVolume", 3, 10);//dim 3 tag 10
    }
    //end double extrusion

    for (unsigned int j = 2; j < extrudedE.size(); j++){
      GFace *elFace = (GFace*) extrudedE[j];
      std::list<GEdge*> l_edges = elFace->edges();
      for(std::list<GEdge*>::iterator it = l_edges.begin(); it != l_edges.end(); it++){
	GEdge *myEdge = *it;
	if (is_cut) myEdge = current->getEdgeByTag((*it)->tag()-NE);
	if( std::find(boundEdges.begin(), boundEdges.end(), myEdge) != boundEdges.end() ){
	  if (myEdge==gin){
	    elFace->addPhysicalEntity(7);
	    current->setPhysicalName("inletRing", 2, 7);//tag 7
	  }
	  else{
	    elFace->addPhysicalEntity(8);
	    current->setPhysicalName("outletRings", 2, 8);//tag 8
	  }
	}
      }
    }
  }

}
Пример #21
0
void GMSH_DistancePlugin::printView(std::vector<GEntity*> _entities,
                                    std::map<MVertex*, double > _distance_map)
{
  _fileName = DistanceOptions_String[0].def;
  _minScale = (double) DistanceOptions_Number[4].def;
  _maxScale = (double) DistanceOptions_Number[5].def;

  double minDist=1.e4;
  double maxDist=0.0;
  for (std::map<MVertex*,double >::iterator itv=_distance_map.begin();
       itv != _distance_map.end(); ++itv){
    double dist = itv->second;
    if (dist>maxDist) maxDist = dist;
    if (dist<minDist) minDist = dist;
    itv->second = dist;
  }

  Msg::Info("Writing %s", _fileName.c_str());
  FILE *fName = Fopen(_fileName.c_str(),"w");
  fprintf(fName, "View \"distance \"{\n");

  for (unsigned int ii=0; ii<_entities.size(); ii++) {
    if (_entities[ii]->dim() == _maxDim) {
      for (unsigned int i=0; i<_entities[ii]->getNumMeshElements(); i++) {
        MElement *e = _entities[ii]->getMeshElement(i);
        int numNodes = e->getNumVertices();
        if (e->getNumChildren())
          numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices();
        std::vector<double> x(numNodes), y(numNodes), z(numNodes);
        std::vector<double> *out = _data->incrementList(1, e->getType(), numNodes);
        std::vector<MVertex*> nods;

        if (!e->getNumChildren())
          for(int i = 0; i < numNodes; i++)
            nods.push_back(e->getVertex(i));
        else
          for(int i = 0; i < e->getNumChildren(); i++)
            for(int j = 0; j < e->getChild(i)->getNumVertices(); j++)
              nods.push_back(e->getChild(i)->getVertex(j));

        for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->x());
        for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->y());
        for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->z());

        if (_maxDim == 2)
          switch (numNodes) {
            case 2: fprintf(fName,"SL("); break;
            case 3: fprintf(fName,"ST("); break;
            case 4: fprintf(fName,"SQ("); break;
            default: Msg::Error("Error in Plugin 'Distance' (numNodes=%d)",
                                numNodes); break;
          }
        else if (_maxDim == 3)
          switch (numNodes) {
            case 4: fprintf(fName,"SS("); break;
            case 8: fprintf(fName,"SH("); break;
            case 6: fprintf(fName,"SI("); break;
            case 5: fprintf(fName,"SY("); break;
            default: Msg::Error("Error in Plugin 'Distance' (numNodes=%d)",
                                numNodes); break;
          }

        std::vector<double> dist;
        for (int j=0; j<numNodes; j++) {
          MVertex *v =  nods[j];
          if (j)
            fprintf(fName, ",%.16g,%.16g,%.16g", v->x(), v->y(), v->z());
          else
            fprintf(fName, "%.16g,%.16g,%.16g", v->x(), v->y(), v->z());
          std::map<MVertex*, double>::iterator it = _distance_map.find(v);
          dist.push_back(it->second);
        }

        fprintf(fName,"){");
        for (unsigned int i=0; i<dist.size(); i++) {
          if (_minScale>0 && _maxScale>0)
            dist[i] = _minScale + ((dist[i] - minDist) / (maxDist - minDist)) *
              (_maxScale - _minScale);
          else if (_minScale>0 && _maxScale<0)
            dist[i] = _minScale + dist[i];
          out->push_back(dist[i]);
          if (i)
            fprintf(fName, ",%.16g", dist[i]);
          else
            fprintf(fName, "%.16g", dist[i]);
        }
        fprintf(fName,"};\n");

      }
    }
  }
  fprintf(fName,"};\n");

  fclose(fName);
}
Пример #22
0
bool Filler3D::treat_region(GRegion *gr)
{
  BGMManager::set_use_cross_field(true);

  bool use_vectorial_smoothness;
  bool use_fifo;
  string algo;

  // readValue("param.dat","SMOOTHNESSALGO",algo);
  algo.assign("SCALAR");

  if (!algo.compare("SCALAR")){
    use_vectorial_smoothness = false;
    use_fifo = false;
  }
  else if (!algo.compare("FIFO")){
    use_vectorial_smoothness = false;
    use_fifo = true;
  }
  else{
    cout << "unknown SMOOTHNESSALGO !" << endl;
    throw;
  }

  const bool debug=false;
  const bool export_stuff=true;
  double a;

  cout << "ENTERING POINTINSERTION3D" << endl;

  // acquire background mesh
  cout << "pointInsertion3D: recover BGM" << endl;
  a = Cpu();
  frameFieldBackgroundMesh3D *bgm =
    dynamic_cast<frameFieldBackgroundMesh3D*>(BGMManager::get(gr));
  time_smoothing += (Cpu() - a);

  if (!bgm){
    cout << "pointInsertion3D:: BGM dynamic cast failed ! " << endl;
    throw;
  }

  // export BGM fields
  if(export_stuff){
    cout << "pointInsertion3D: export size field " << endl;
    stringstream ss;
    ss << "bg3D_sizefield_" << gr->tag() << ".pos";
    bgm->exportSizeField(ss.str());

    cout << "pointInsertion3D : export crossfield " << endl;
    stringstream sscf;
    sscf << "bg3D_crossfield_" << gr->tag() << ".pos";
    bgm->exportCrossField(sscf.str());

    cout << "pointInsertion3D : export smoothness " << endl;
    stringstream sss;
    sss << "bg3D_smoothness_" << gr->tag() << ".pos";
    bgm->exportSmoothness(sss.str());

    if (use_vectorial_smoothness){
      cout << "pointInsertion3D : export vectorial smoothness " << endl;
      stringstream ssvs;
      ssvs << "bg3D_vectorial_smoothness_" << gr->tag() << ".pos";
      bgm->exportVectorialSmoothness(ssvs.str());
    }
  }

  // ---------------- START FILLING NEW POINTS ----------------
  cout << "pointInsertion3D : inserting points in region " << gr->tag()  << endl;

  //ProfilerStart("/home/bernard/profile");
  a = Cpu();

  // ----- initialize fifo list -----

  RTree<MVertex*,double,3,double> rtree;
  listOfPoints *fifo;
  if (use_fifo)
    fifo = new listOfPointsFifo();
  else if (use_vectorial_smoothness)
    fifo = new listOfPointsVectorialSmoothness();
  else
    fifo = new listOfPointsScalarSmoothness();

  set<MVertex*> temp;
  vector<MVertex*> boundary_vertices;
  map<MVertex*,int> vert_priority;
  map<MVertex*,double> smoothness_forplot;
  MElement *element;
  MVertex *vertex;
  list<GFace*> faces = gr->faces();
  for(list<GFace*>::iterator it=faces.begin();it!=faces.end();it++){// for all faces
    GFace *gf = *it;
    // int limit = code_kesskessai(gf->tag());
    for(unsigned int i=0;i<gf->getNumMeshElements();i++){
      element = gf->getMeshElement(i);
      for(int j=0;j<element->getNumVertices();j++){// for all vertices
        vertex = element->getVertex(j);
        temp.insert(vertex);
        // limits.insert(make_pair(vertex,limit));
      }
    }
  }

  int geodim;
  for(set<MVertex*>::iterator it=temp.begin();it!=temp.end();it++){
    geodim = (*it)->onWhat()->dim();
    if ((geodim==0) || (geodim==1) || (geodim==2)) boundary_vertices.push_back(*it);
  }

  double min[3],max[3],x,y,z,h;
  for(unsigned int i=0;i<boundary_vertices.size();i++){

    x = boundary_vertices[i]->x();
    y = boundary_vertices[i]->y();
    z = boundary_vertices[i]->z();

    // "on boundary since working on boundary_vertices ...
    MVertex *closest = bgm->get_nearest_neighbor_on_boundary(boundary_vertices[i]);
    h = bgm->size(closest);// get approximate size, closest vertex, faster ?!

    fill_min_max(x,y,z,h,min,max);

    rtree.Insert(min,max,boundary_vertices[i]);

    if (!use_vectorial_smoothness){
      smoothness_vertex_pair *svp = new smoothness_vertex_pair();
      svp->v = boundary_vertices[i];
      svp->rank = bgm->get_smoothness(x,y,z);
      svp->dir = 0;
      svp->layer = 0;
      svp->size = h;
      bgm->eval_approximate_crossfield(closest, svp->cf);

      fifo->insert(svp);
      if (debug){
        smoothness_forplot[svp->v] = svp->rank;
      }
    }
    else{
      STensor3 temp;
      bgm->eval_approximate_crossfield(closest, temp);
      for (int idir=0;idir<3;idir++){
        smoothness_vertex_pair *svp = new smoothness_vertex_pair();
        svp->v = boundary_vertices[i];
        svp->rank = bgm->get_vectorial_smoothness(idir,x,y,z);
        svp->dir = idir;
        svp->layer = 0;
        svp->size = h;
        svp->cf = temp;
        for (int k=0;k<3;k++) svp->direction(k) = temp(k,idir);

        // cout << "fifo size=" << fifo->size() << " inserting   "  ;
        fifo->insert(svp);
        // cout << " ->  fifo size=" << fifo->size() << endl;
      }
    }
  }

  // TODO: si fifo était list of *PTR -> pas de copies, gain temps ?
  Wrapper3D wrapper;
  wrapper.set_bgm(bgm);
  MVertex *parent,*individual;
  new_vertices.clear();
  bool spawn_created;
  int priority_counter=0;
  STensor3 crossfield;
  int parent_layer;

  while(!fifo->empty()){

    parent =  fifo->get_first_vertex();
    //    parent_limit = fifo->get_first_limit();
    parent_layer = fifo->get_first_layer();

    //    if(parent_limit!=-1 && parent_layer>=parent_limit()){
    //      continue;
    //    }

    vector<MVertex*> spawns;
    if (!use_vectorial_smoothness){
      spawns.resize(6);
      computeSixNeighbors(bgm,parent,spawns,fifo->get_first_crossfield(),
                          fifo->get_first_size());
    }
    else{
      spawns.resize(2);
      computeTwoNeighbors(bgm,parent,spawns,fifo->get_first_direction(),
                          fifo->get_first_size());
    }
    fifo->erase_first();

    //    cout << "while, fifo->size()=" << fifo->size() << " parent=(" <<
    //    parent->x() << "," << parent->y() << "," << parent->z() << ")" <<
    //    endl;

    for(unsigned int i=0;i<spawns.size();i++){
      spawn_created = false;
      individual = spawns[i];
      x = individual->x();
      y = individual->y();
      z = individual->z();
      //      cout << " working on candidate " << "(" << individual->x() << ","
      //      << individual->y() << "," << individual->z() << ")" << endl;

      if(bgm->inDomain(x,y,z)){
        //        cout << "   spawn " << i << " in domain" << endl;

        MVertex *closest = bgm->get_nearest_neighbor(individual);
        h = bgm->size(closest);// get approximate size, closest vertex, faster ?!

        if(far_from_boundary_3D(bgm,individual,h)){
          //        cout << "   spawn " << i << " far from bnd" << endl;
          bgm->eval_approximate_crossfield(closest, crossfield);
          wrapper.set_ok(true);
          wrapper.set_individual(individual);
          wrapper.set_parent(parent);
          wrapper.set_size(&h);
          wrapper.set_crossfield(&crossfield);

          fill_min_max(x,y,z,h,min,max);

          rtree.Search(min,max,rtree_callback_3D,&wrapper);

          if(wrapper.get_ok()){
            //        cout << "   spawn " << i << " wrapper OK" << endl;

            if (!use_vectorial_smoothness){
              smoothness_vertex_pair *svp = new smoothness_vertex_pair();
              svp->v = individual;
              svp->rank=bgm->get_smoothness(individual->x(),individual->y(),individual->z());
              svp->dir = 0;
              svp->layer = parent_layer+1;
              svp->size = h;
              svp->cf = crossfield;
              fifo->insert(svp);
              if (debug){
                smoothness_forplot[svp->v] = svp->rank;
                vert_priority[individual] = priority_counter++;
              }

            }
            else{
              if (debug) vert_priority[individual] = priority_counter++;
              for (int idir=0;idir<3;idir++){
                smoothness_vertex_pair *svp = new smoothness_vertex_pair();
                svp->v = individual;
                svp->rank = bgm->get_vectorial_smoothness(idir,x,y,z);
                svp->dir = idir;
                svp->layer = parent_layer+1;
                svp->size = h;
                for (int k=0;k<3;k++) svp->direction(k) = crossfield(k,idir);
                svp->cf = crossfield;
                fifo->insert(svp);
              }
            }

            rtree.Insert(min,max,individual);
            new_vertices.push_back(individual);
            spawn_created = true;

          }
        }
      }
      if(!spawn_created){
        delete individual;
      }
    }// end loop on spawns
  }

  //ProfilerStop();

  time_insert_points += (Cpu() - a);

  // --- output ---
  if (debug){
    stringstream ss;
    ss << "priority_3D_" << gr->tag() << ".pos";
    print_nodal_info(ss.str().c_str(),vert_priority);
    ss.clear();

    stringstream sss;
    sss << "smoothness_3D_" << gr->tag() << ".pos";
    print_nodal_info(sss.str().c_str(),smoothness_forplot);
    sss.clear();
  }

  // ------- meshing using new points
  cout << "tets in gr before= " << gr->tetrahedra.size() << endl;
  cout << "nb new vertices= " << new_vertices.size() << endl;
  a=Cpu();

  int option = CTX::instance()->mesh.algo3d;
  CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY;

  deMeshGRegion deleter;
  deleter(gr);
  std::vector<GRegion*> regions;
  regions.push_back(gr);
  meshGRegion mesher(regions); //?
  mesher(gr); //?
  MeshDelaunayVolume(regions);
  time_meshing += (Cpu() - a);

  cout << "tets in gr after= " << gr->tetrahedra.size() << endl;
  cout << "gr tag=" << gr->tag() << endl;

  CTX::instance()->mesh.algo3d = option;

  delete fifo;
  for(unsigned int i=0;i<new_vertices.size();i++) delete new_vertices[i];
  new_vertices.clear();
  rtree.RemoveAll();

  return true;
}
Пример #23
0
int GModel::readPLY(const std::string &name)
{
  // this is crazy!?
  replaceCommaByDot(name);

  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  std::vector<MVertex*> vertexVector;
  std::map<int, std::vector<MElement*> > elements[5];
  std::map<int, std::vector<double> > properties;

  char buffer[256], str[256], str2[256], str3[256];
  std::string s1;
  int elementary = getMaxElementaryNumber(-1) + 1;
  int nbv = 0, nbf = 0;
  int nbprop = 0;
  int nbView = 0;
  std::vector<std::string> propName;
  while(!feof(fp)) {
    if(!fgets(buffer, sizeof(buffer), fp)) break;
    if(buffer[0] != '#'){ // skip comments
      sscanf(buffer, "%s %s", str, str2);
      if(!strcmp(str, "element") && !strcmp(str2, "vertex")){
	sscanf(buffer, "%s %s %d", str, str2, &nbv);
      }
      if(!strcmp(str, "format") && strcmp(str2, "ascii")){
	Msg::Error("Only reading of ascii PLY files implemented");
        fclose(fp);
	return 0;
      }
      if(!strcmp(str, "property") && strcmp(str2, "list")){
	nbprop++;
	sscanf(buffer, "%s %s %s", str, str2, str3);
	if (nbprop > 3) propName.push_back(s1+str3);
      }
      if(!strcmp(str, "element") && !strcmp(str2, "face")){
	sscanf(buffer, "%s %s %d", str, str2, &nbf);
      }
      if(!strcmp(str, "end_header")){
	nbView = nbprop -3;
	Msg::Info("%d elements", nbv);
	Msg::Info("%d triangles", nbf);
	Msg::Info("%d properties", nbView);

	vertexVector.resize(nbv);
	for(int i = 0; i < nbv; i++) {
	  double x,y,z;
	  char line[10000], *pEnd, *pEnd2, *pEnd3;
	  if(!fgets(line, sizeof(line), fp)){ fclose(fp); return 0; }
	  x = strtod(line, &pEnd);
	  y = strtod(pEnd, &pEnd2);
	  z = strtod(pEnd2, &pEnd3);
	  vertexVector[i] = new MVertex(x, y, z);

	  pEnd = pEnd3;
          std::vector<double> prop(nbView);
	  for (int k = 0; k < nbView; k++){
	    prop[k]=strtod(pEnd, &pEnd2);
	    pEnd = pEnd2;
	    properties[k].push_back(prop[k]);
	  }
	}

	for(int i = 0; i < nbf; i++) {
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  int n[3], nbe;
	  sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]);
	  std::vector<MVertex*> vertices;
	  if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; }
	  elements[0][elementary].push_back(new MTriangle(vertices));
	}

      }

    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertexVector);

#if defined(HAVE_POST)
  // create PViews here
  std::vector<GEntity*> _entities;
  getEntities(_entities);
  for (int iV=0; iV< nbView; iV++){
    PView *view = new PView();
    PViewDataList *data = dynamic_cast<PViewDataList*>(view->getData());
    for(unsigned int ii = 0; ii < _entities.size(); ii++){
	for(unsigned int i = 0; i < _entities[ii]->getNumMeshElements(); i++){
	  MElement *e = _entities[ii]->getMeshElement(i);
	  int numNodes = e->getNumVertices();
	  std::vector<double> x(numNodes), y(numNodes), z(numNodes);
	  std::vector<double> *out = data->incrementList(1, e->getType());
	  for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->x());
	  for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->y());
	  for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->z());
	  std::vector<double> props;
	  int n[3];
	  n[0] = e->getVertex(0)->getNum()-1;
	  n[1] = e->getVertex(1)->getNum()-1;
	  n[2] = e->getVertex(2)->getNum()-1;
	  if(!getProperties(3, n, properties[iV], props)){ fclose(fp); return 0; }
	  for(int nod = 0; nod < numNodes; nod++) out->push_back(props[nod]);
	}
    }
    data->setName(propName[iV]);
    data->Time.push_back(0);
    data->setFileName("property.pos");
    data->finalize();
  }
#endif

  fclose(fp);

  return 1;
}
Пример #24
0
void Filler::treat_region(GRegion* gr){

  int NumSmooth = CTX::instance()->mesh.smoothCrossField;
  std::cout << "NumSmooth = " << NumSmooth << std::endl ;
  if(NumSmooth && (gr->dim() == 3)){
    double scale = gr->bounds().diag()*1e-2;
    Frame_field::initRegion(gr,NumSmooth);
    Frame_field::saveCrossField("cross0.pos",scale);

    Frame_field::smoothRegion(gr,NumSmooth);
    Frame_field::saveCrossField("cross1.pos",scale);
  }

#if defined(HAVE_RTREE)
  unsigned int i;
  int j;
  int count;
  int limit;
  bool ok2;
  double x,y,z;
  SPoint3 point;
  Node *node,*individual,*parent;
  MVertex* vertex;
  MElement* element;
  MElementOctree* octree;
  deMeshGRegion deleter;
  Wrapper wrapper;
  GFace* gf;
  std::queue<Node*> fifo;
  std::vector<Node*> spawns;
  std::vector<Node*> garbage;
  std::vector<MVertex*> boundary_vertices;
  std::set<MVertex*> temp;
  std::list<GFace*> faces;
  std::map<MVertex*,int> limits;
  std::set<MVertex*>::iterator it;
  std::list<GFace*>::iterator it2;
  std::map<MVertex*,int>::iterator it3;
  RTree<Node*,double,3,double> rtree;
  
  Frame_field::init_region(gr);
  Size_field::init_region(gr);
  Size_field::solve(gr);
  octree = new MElementOctree(gr->model());
  garbage.clear();
  boundary_vertices.clear();
  temp.clear();
  new_vertices.clear();
  faces.clear();
  limits.clear();

  faces = gr->faces();	
  for(it2=faces.begin();it2!=faces.end();it2++){
    gf = *it2;
	limit = code(gf->tag());
	for(i=0;i<gf->getNumMeshElements();i++){
	  element = gf->getMeshElement(i);
      for(j=0;j<element->getNumVertices();j++){
	    vertex = element->getVertex(j);
		temp.insert(vertex);
		limits.insert(std::pair<MVertex*,int>(vertex,limit));
	  }
	}
  }
		
  /*for(i=0;i<gr->getNumMeshElements();i++){
    element = gr->getMeshElement(i);
    for(j=0;j<element->getNumVertices();j++){
      vertex = element->getVertex(j);
      temp.insert(vertex);
    }
  }*/

  for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()==0){
	  boundary_vertices.push_back(*it);
	}
  }
	
  for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()==1){
	  boundary_vertices.push_back(*it);
	}
  }
	
  for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()==2){
	  boundary_vertices.push_back(*it);
	}
  }
	
  /*for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()<3){
      boundary_vertices.push_back(*it);
    }
  }*/
  //std::ofstream file("nodes.pos");
  //file << "View \"test\" {\n";	

  for(i=0;i<boundary_vertices.size();i++){
    x = boundary_vertices[i]->x();
    y = boundary_vertices[i]->y();
    z = boundary_vertices[i]->z();
    
    node = new Node(SPoint3(x,y,z));
    compute_parameters(node,gr);
	node->set_layer(0);
	
	it3 = limits.find(boundary_vertices[i]);
	node->set_limit(it3->second);
	
	rtree.Insert(node->min,node->max,node);
	fifo.push(node);
    //print_node(node,file);
  }
  
  count = 1;
  while(!fifo.empty()){
    parent = fifo.front();
	fifo.pop();
	garbage.push_back(parent);
	  
	if(parent->get_limit()!=-1 && parent->get_layer()>=parent->get_limit()){
	  continue;
	}
	  
	spawns.clear();
	spawns.resize(6);
	  
	for(i=0;i<6;i++){
	  spawns[i] = new Node();
	}
	
	create_spawns(gr,octree,parent,spawns);
	
	for(i=0;i<6;i++){
	  ok2 = 0;
	  individual = spawns[i];
	  point = individual->get_point();
	  x = point.x();
	  y = point.y();
	  z = point.z();
	  
	  if(inside_domain(octree,x,y,z)){
		compute_parameters(individual,gr);
		individual->set_layer(parent->get_layer()+1);
		individual->set_limit(parent->get_limit());
		
		if(far_from_boundary(octree,individual)){
		  wrapper.set_ok(1);
		  wrapper.set_individual(individual);
		  wrapper.set_parent(parent);
		  rtree.Search(individual->min,individual->max,rtree_callback,&wrapper);
			
		  if(wrapper.get_ok()){
		    fifo.push(individual);
		    rtree.Insert(individual->min,individual->max,individual);
			vertex = new MVertex(x,y,z,gr,0);
			new_vertices.push_back(vertex);
			ok2 = 1;
			//print_segment(individual->get_point(),parent->get_point(),file);
		  }
	    }
	  }
		
	  if(!ok2) delete individual;
	}
	
	if(count%100==0){
	  printf("%d\n",count);
	}
	count++;
  }
  
  //file << "};\n";

  int option = CTX::instance()->mesh.algo3d;
  CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY;

  deleter(gr);
  std::vector<GRegion*> regions;
  regions.push_back(gr);
  meshGRegion mesher(regions); //?
  mesher(gr); //?
  MeshDelaunayVolume(regions);

  CTX::instance()->mesh.algo3d = option;
	
  for(i=0;i<garbage.size();i++) delete garbage[i];
  for(i=0;i<new_vertices.size();i++) delete new_vertices[i];
  new_vertices.clear();
  delete octree;
  rtree.RemoveAll();
  Size_field::clear();
  Frame_field::clear();
#endif
}
Пример #25
0
int GModel::writeKEY(const std::string &name, int saveAll,
                     int saveGroupsOfNodes, double scalingFactor)
{
  FILE *fp = Fopen(name.c_str(), "w");
  if(!fp) {
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  if(noPhysicalGroups()) saveAll = 0x51;

  indexMeshVertices(saveAll & 0x51);
  std::vector<GEntity *> entities;
  getEntities(entities);

  fprintf(fp, "$# LS-DYNA Keyword file created by Gmsh\n*KEYWORD\n*TITLE\n");
  fprintf(fp, " %s\n", name.c_str());

  fprintf(fp, "*NODE\n");
  for(std::size_t i = 0; i < entities.size(); i++)
    for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
      entities[i]->mesh_vertices[j]->writeKEY(fp, scalingFactor);

  if(!(saveAll & 0x2)) // save or ignore Vertex, not in GUI
    for(viter it = firstVertex(); it != lastVertex(); ++it) {
      writeElementsKEY(fp, *it, (*it)->points, saveAll & 0x1);
    }
  if(!(saveAll & 0x8)) // save or ignore line
    for(eiter it = firstEdge(); it != lastEdge(); ++it) {
      writeElementsKEY(fp, *it, (*it)->lines, saveAll & 0x4);
    }
  if(!(saveAll & 0x20)) // save or ignore surface
    for(fiter it = firstFace(); it != lastFace(); ++it) {
      writeElementsKEY(fp, *it, (*it)->triangles, saveAll & 0x10);
      writeElementsKEY(fp, *it, (*it)->quadrangles, saveAll & 0x10);
    }
  if(!(saveAll & 0x80)) // save or ignore surface
    for(riter it = firstRegion(); it != lastRegion(); ++it) {
      writeElementsKEY(fp, *it, (*it)->tetrahedra, saveAll & 0x40);
      writeElementsKEY(fp, *it, (*it)->hexahedra, saveAll & 0x40);
      writeElementsKEY(fp, *it, (*it)->prisms, saveAll & 0x40);
      writeElementsKEY(fp, *it, (*it)->pyramids, saveAll & 0x40);
    }

  std::map<int, std::vector<GEntity *> > groups[4];
  getPhysicalGroups(groups);

  int setid = 0;
  // save elements sets for each physical group
  if(saveGroupsOfNodes & 0x2) {
    for(int dim = 0; dim <= 3; dim++) {
      if(saveAll & (0x2 << (2 * dim))) continue; // elements are ignored
      for(std::map<int, std::vector<GEntity *> >::iterator it =
            groups[dim].begin();
          it != groups[dim].end(); it++) {
        std::vector<GEntity *> &entities = it->second;
        int n = 0;
        for(std::size_t i = 0; i < entities.size(); i++) {
          for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
            MElement *e = entities[i]->getMeshElement(j);
            if(!n) {
              const char *str = (e->getDim() == 3) ?
                                  "SOLID" :
                                  (e->getDim() == 2) ?
                                  "SHELL" :
                                  (e->getDim() == 1) ? "BEAM" : "NODE";
              fprintf(fp, "*SET_%s_LIST\n$# %s\n%d", str,
                      physicalName(this, dim, it->first).c_str(), ++setid);
            }
            if(!(n % 8))
              fprintf(fp, "\n%lu", e->getNum());
            else
              fprintf(fp, ", %lu", e->getNum());
            n++;
          }
        }
        if(n) fprintf(fp, "\n");
      }
    }
  }

  // save node sets for each physical group, for easier load/b.c.
  if(saveGroupsOfNodes & 0x1) {
    for(int dim = 1; dim <= 3; dim++) {
      for(std::map<int, std::vector<GEntity *> >::iterator it =
            groups[dim].begin();
          it != groups[dim].end(); it++) {
        std::set<MVertex *> nodes;
        std::vector<GEntity *> &entities = it->second;
        for(std::size_t i = 0; i < entities.size(); i++) {
          for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
            MElement *e = entities[i]->getMeshElement(j);
            for(std::size_t k = 0; k < e->getNumVertices(); k++)
              nodes.insert(e->getVertex(k));
          }
        }
        fprintf(fp, "*SET_NODE_LIST\n$# %s\n%d",
                physicalName(this, dim, it->first).c_str(), ++setid);
        int n = 0;
        for(std::set<MVertex *>::iterator it2 = nodes.begin();
            it2 != nodes.end(); it2++) {
          if(!(n % 8))
            fprintf(fp, "\n%ld", (*it2)->getIndex());
          else
            fprintf(fp, ", %ld", (*it2)->getIndex());
          n++;
        }
        if(n) fprintf(fp, "\n");
      }
    }
  }

  fprintf(fp, "*END\n");
  fclose(fp);
  return 1;
}
Пример #26
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());

}