Пример #1
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;
}
Пример #2
0
static void getBoundaryFromMesh(GModel *m, int visible)
{
  int dim = m->getDim();
  std::vector<GEntity*> entities;
  m->getEntities(entities);
  std::set<MFace, Less_Face> bndFaces;
  std::set<MEdge, Less_Edge> bndEdges;
  for(unsigned int i = 0; i < entities.size(); i++){
    GEntity *ge = entities[i];
    if(ge->dim() != dim) continue;
    if(visible && !ge->getVisibility()) continue;
    for(unsigned int j = 0; j < ge->getNumMeshElements(); j++){
      MElement *e = ge->getMeshElement(j);
      if(dim == 2){
        for(int i = 0; i < e->getNumEdges(); i++){
          MEdge f = e->getEdge(i);
          if(bndEdges.find(f) == bndEdges.end())
            bndEdges.insert(f);
          else
            bndEdges.erase(f);
        }
      }
      else if(dim == 3){
        for(int i = 0; i < e->getNumFaces(); i++){
          MFace f = e->getFace(i);
          if(bndFaces.find(f) == bndFaces.end())
            bndFaces.insert(f);
          else
            bndFaces.erase(f);
        }
      }
    }
  }

  if(dim == 2){
    discreteEdge *e = new discreteEdge(m, m->getMaxElementaryNumber(1) + 1, 0, 0);
    m->add(e);
    for(std::set<MEdge, Less_Edge>::iterator it = bndEdges.begin();
        it != bndEdges.end(); it++){
      e->lines.push_back(new MLine(it->getVertex(0), it->getVertex(1)));
    }
  }
  else if(dim == 3){
    discreteFace *f = new discreteFace(m, m->getMaxElementaryNumber(2) + 1);
    m->add(f);
    for(std::set<MFace, Less_Face>::iterator it = bndFaces.begin();
        it != bndFaces.end(); it++){
      if(it->getNumVertices() == 3)
        f->triangles.push_back(new MTriangle(it->getVertex(0), it->getVertex(1),
                                             it->getVertex(2)));
      else if(it->getNumVertices() == 4)
        f->quadrangles.push_back(new MQuadrangle(it->getVertex(0), it->getVertex(1),
                                                 it->getVertex(2), it->getVertex(3)));
    }
  }
}
Пример #3
0
void distanceFromElementsToGeometry(GModel *gm, int dim,
                                    std::map<MElement *, double> &distances)
{
  std::map<MEdge, double, Less_Edge> dist2Edge;
  for(GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it) {
    if((*it)->geomType() == GEntity::Line) continue;
    for(unsigned int i = 0; i < (*it)->lines.size(); i++) {
      double d = taylorDistanceEdge((*it)->lines[i], *it);
      MEdge e = (*it)->lines[i]->getEdge(0);
      dist2Edge[e] = d;
    }
  }

  std::map<MFace, double, Less_Face> dist2Face;
  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) {
    if((*it)->geomType() == GEntity::Plane) continue;
    for(unsigned int i = 0; i < (*it)->triangles.size(); i++) {
      double d = taylorDistanceFace((*it)->triangles[i], *it);
      MFace f = (*it)->triangles[i]->getFace(0);
      dist2Face[f] = d;
    }
  }

  std::vector<GEntity *> entities;
  gm->getEntities(entities);
  for(int iEnt = 0; iEnt < entities.size(); ++iEnt) {
    GEntity *&entity = entities[iEnt];
    if(entity->dim() != dim) continue;
    for(int iEl = 0; iEl < entity->getNumMeshElements();
        iEl++) { // Detect bad elements
      MElement *element = entity->getMeshElement(iEl);
      double d = 0.;
      for(int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) {
        MEdge e = element->getEdge(iEdge);
        std::map<MEdge, double, Less_Edge>::iterator it = dist2Edge.find(e);
        if(it != dist2Edge.end()) d += it->second;
      }
      for(int iFace = 0; iFace < element->getNumFaces(); ++iFace) {
        MFace f = element->getFace(iFace);
        std::map<MFace, double, Less_Face>::iterator it = dist2Face.find(f);
        if(it != dist2Face.end()) d += it->second;
      }
      distances[element] = d;
    }
  }
}
Пример #4
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;

}
Пример #5
0
static void drawBarycentricDual(std::vector<T*> &elements)
{
  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
  glEnable(GL_LINE_STIPPLE);
  glLineStipple(1, 0x0F0F);
  gl2psEnable(GL2PS_LINE_STIPPLE);
  glBegin(GL_LINES);
  for(unsigned int i = 0; i < elements.size(); i++){
    MElement *ele = elements[i];
    if(!isElementVisible(ele)) continue;
    SPoint3 pc = ele->barycenter();
    if(ele->getDim() == 2){
      for(int j = 0; j < ele->getNumEdges(); j++){
        MEdge e = ele->getEdge(j);
        SPoint3 p = e.barycenter();
        glVertex3d(pc.x(), pc.y(), pc.z());
        glVertex3d(p.x(), p.y(), p.z());
      }
    }
    else if(ele->getDim() == 3){
      for(int j = 0; j < ele->getNumFaces(); j++){
        MFace f = ele->getFace(j);
        SPoint3 p = f.barycenter();
        glVertex3d(pc.x(), pc.y(), pc.z());
        glVertex3d(p.x(), p.y(), p.z());
        for(int k = 0; k < f.getNumVertices(); k++){
          MEdge e(f.getVertex(k), (k == f.getNumVertices() - 1) ?
                  f.getVertex(0) : f.getVertex(k + 1));
          SPoint3 pe = e.barycenter();
          glVertex3d(p.x(), p.y(), p.z());
          glVertex3d(pe.x(), pe.y(), pe.z());
        }
      }
    }
  }
  glEnd();
  glDisable(GL_LINE_STIPPLE);
  gl2psDisable(GL2PS_LINE_STIPPLE);
}