예제 #1
0
파일: drawMesh.cpp 프로젝트: cycheung/gmsh
static void drawElementLabels(drawContext *ctx, GEntity *e,
                              std::vector<T*> &elements, int forceColor=0,
                              unsigned int color=0)
{
  unsigned col = forceColor ? color : getColorByEntity(e);
  glColor4ubv((GLubyte *) & col);

  int labelStep = CTX::instance()->mesh.labelSampling;
  if(labelStep <= 0) labelStep = 1;

  for(unsigned int i = 0; i < elements.size(); i++){
    MElement *ele = elements[i];
    if(!isElementVisible(ele)) continue;
    if(i % labelStep == 0) {
      SPoint3 pc = ele->barycenter();
      char str[256];
      if(CTX::instance()->mesh.labelType == 4)
        sprintf(str, "(%g,%g,%g)", pc.x(), pc.y(), pc.z());
      else if(CTX::instance()->mesh.labelType == 3)
        sprintf(str, "%d", ele->getPartition());
      else if(CTX::instance()->mesh.labelType == 2){
        int np = e->physicals.size();
        int p = np ? e->physicals[np - 1] : 0;
        sprintf(str, "%d", p);
      }
      else if(CTX::instance()->mesh.labelType == 1)
        sprintf(str, "%d", e->tag());
      else
        sprintf(str, "%d", ele->getNum());
      glRasterPos3d(pc.x(), pc.y(), pc.z());
      ctx->drawString(str);
    }
  }
}
예제 #2
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;
}
예제 #3
0
PView *elasticitySolver::buildElasticEnergyView(const std::string postFileName)
{
  std::cout <<  "build Elastic Energy View"<< std::endl;
  std::map<int, std::vector<double> > data;
  GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad);
  for (unsigned int i = 0; i < elasticFields.size(); ++i)
  {
    if(elasticFields[i]._E == 0.) continue;
    SolverField<SVector3> Field(pAssembler, LagSpace);
    IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu);
    BilinearTermToScalarTerm Elastic_Energy_Term(Eterm);
    ScalarTermConstant<double> One(1.0);
    for (groupOfElements::elementContainer::const_iterator it =
           elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it)
    {
      MElement *e = *it;
      double energ;
      double vol;
      IntPt *GP;
      int npts=Integ_Bulk.getIntPoints(e,&GP);
      Elastic_Energy_Term.get(e,npts,GP,energ);
      One.get(e,npts,GP,vol);
      std::vector<double> vec;
      vec.push_back(energ/vol);
      data[e->getNum()]=vec;
    }
  }
  PView *pv = new PView (postFileName, "ElementData", pModel, data, 0.0);
  return pv;
}
예제 #4
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);
  }
}
예제 #5
0
파일: Skin.cpp 프로젝트: iyer-arvind/gmsh
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)));
    }
  }
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
0
static void _relocateVertexOfPyramid(MVertex *ver,
                                     const std::vector<MElement *> &lt,
                                     double relax)
{
  if(ver->onWhat()->dim() != 3) return;
  double x = 0.0, y = 0.0, z = 0.0;
  int N = 0;
  MElement *pyramid = NULL;

  for(std::size_t i = 0; i < lt.size(); i++) {
    double XCG = 0.0, YCG = 0.0, ZCG = 0.0;
    if(lt[i]->getNumVertices() == 5)
      pyramid = lt[i];
    else {
      for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) {
        XCG += lt[i]->getVertex(j)->x();
        YCG += lt[i]->getVertex(j)->y();
        ZCG += lt[i]->getVertex(j)->z();
      }
      x += XCG;
      y += YCG;
      z += ZCG;
      N += lt[i]->getNumVertices();
    }
  }
  x /= N;
  y /= N;
  z /= N;

  if(pyramid) {
    MFace q = pyramid->getFace(4);
    double A = q.approximateArea();
    SVector3 n = q.normal();
    n.normalize();
    SPoint3 c = q.barycenter();
    SVector3 d(x - c.x(), y - c.y(), z - c.z());
    if(dot(n, d) < 0) n = n * (-1.0);
    double H = .5 * sqrt(fabs(A));
    double XOPT = c.x() + relax * H * n.x();
    double YOPT = c.y() + relax * H * n.y();
    double ZOPT = c.z() + relax * H * n.z();
    double FULL_MOVE_OBJ =
      objective_function(1.0, ver, XOPT, YOPT, ZOPT, lt, true);
    // printf("relax %g obj %g\n",relax,FULL_MOVE_OBJ);
    if(FULL_MOVE_OBJ > 0.1) {
      ver->x() = XOPT;
      ver->y() = YOPT;
      ver->z() = ZOPT;
      return;
    }
  }
}
예제 #9
0
double BGMBase::get_field_value(double u, double v, double w,
                                const DoubleStorageType &data)
{
  // TODO C++11 Remove const_cast
  MElement *e = const_cast<MElement *>(findElement(u, v, w));
  if(!e) return -1000.;
  std::vector<double> val = get_nodal_values(e, data);
  std::vector<double> element_uvw = get_element_uvw_from_xyz(e, u, v, w);
  std::vector<double> values(e->getNumVertices());
  for(std::size_t i = 0; i < e->getNumVertices(); i++) values[i] = val[i];

  return e->interpolate(&values[0], element_uvw[0], element_uvw[1],
                        element_uvw[2], 1, order);
}
예제 #10
0
파일: drawMesh.cpp 프로젝트: cycheung/gmsh
static void drawTangents(drawContext *ctx, std::vector<T*> &elements)
{
  glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.tangents);
  for(unsigned int i = 0; i < elements.size(); i++){
    MElement *ele = elements[i];
    if(!isElementVisible(ele)) continue;
    SVector3 t = ele->getEdge(0).tangent();
    for(int j = 0; j < 3; j++)
      t[j] *= CTX::instance()->mesh.tangents * ctx->pixel_equiv_x / ctx->s[j];
    SPoint3 pc = ele->barycenter();
    ctx->drawVector(CTX::instance()->vectorType, 0, pc.x(), pc.y(), pc.z(),
                    t[0], t[1], t[2], CTX::instance()->mesh.light);
  }
}
예제 #11
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;
}
예제 #12
0
double frameFieldBackgroundMesh2D::angle(double u, double v)
{
    MElement *e = const_cast<MElement*>(findElement(u, v));
    if (!e) return -1000.0;
    std::vector<double> val = get_nodal_values(e,angles);
    std::vector<double> element_uvw = get_element_uvw_from_xyz(e,u,v,0.);
    std::vector<double> cosvalues(e->getNumVertices()), sinvalues(e->getNumVertices());
    for (int i=0; i<e->getNumVertices(); i++) {
        cosvalues[i]=cos(4*val[i]);
        sinvalues[i]=sin(4*val[i]);
    }
    double cos4 = e->interpolate(&cosvalues[0], element_uvw[0], element_uvw[1], element_uvw[2], 1, order);
    double sin4 = e->interpolate(&sinvalues[0], element_uvw[0], element_uvw[1], element_uvw[2], 1, order);
    double a = atan2(sin4,cos4)/4.0;
    normalizeAngle (a);
    return a;
}
예제 #13
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;
    }
  }
}
예제 #14
0
PView *elasticitySolver::buildVolumeView(const std::string postFileName)
{
  std::cout << "build Volume View";
  std::map<int, std::vector<double> > data;
  double voltot = 0;
  double length = 0;
  GaussQuadrature Integ_Vol(GaussQuadrature::Val);
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    ScalarTermConstant<double> One(1.0);
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      double vol;
      IntPt *GP;
      int npts = Integ_Vol.getIntPoints(e, &GP);
      One.get(e, npts, GP, vol);
      voltot += vol;
      std::vector<double> vec;
      vec.push_back(vol);
      data[e->getNum()] = vec;
    }
  }
  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) {
    ScalarTermConstant<double> One(1.0);
    for(groupOfElements::elementContainer::const_iterator it =
          LagrangeMultiplierFields[i].g->begin();
        it != LagrangeMultiplierFields[i].g->end(); ++it) {
      MElement *e = *it;
      double l;
      IntPt *GP;
      int npts = Integ_Vol.getIntPoints(e, &GP);
      One.get(e, npts, GP, l);
      length += l;
    }
    std::cout << " : length " << LagrangeMultiplierFields[i]._tag << " = "
              << length;
    length = 0;
  }
  PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0, 1);
  std::cout << " / total vol = " << voltot << std::endl;
  return pv;
}
예제 #15
0
int multiscalePartition::assembleAllPartitions(std::vector<MElement*> & elements)
{
  int iPart =  1;

  elements.clear();
  for (unsigned i = 0; i< levels.size(); i++){
    partitionLevel *iLevel = levels[i];
    if(iLevel->elements.size() > 0){
      for (unsigned j = 0; j < iLevel->elements.size(); j++){
        MElement *e = iLevel->elements[j];
	elements.push_back(e);
        e->setPartition(iPart);
      }
      iPart++;
    }
  }

  return iPart - 1;
}
예제 #16
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);
}
예제 #17
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;

}
예제 #18
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);
    }
}
예제 #19
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;
}
예제 #20
0
double ComputeDistanceToGeometry (GEntity *ge , int distanceDefinition, double tolerance)
{
  double maxd = 0.0;
  double sum = 0.0;
  int NUM = 0;
  for (int iEl = 0; iEl < ge->getNumMeshElements();iEl++) {
    MElement *el = ge->getMeshElement(iEl);
    if (ge->dim() == el->getDim()){
      const double DISTE =computeBndDist(el,distanceDefinition, tolerance);
      if (DISTE != 0.0){
	NUM++;
	//	if(distanceDefinition == 1)printf("%d %12.5E\n",iEl,DISTE);
	maxd = std::max(maxd,DISTE);
	sum += DISTE;
      }
    }
  }
  if (distanceDefinition == 2) return sum;
  if (distanceDefinition == 6) return sum;
  return maxd;
}
예제 #21
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;
        }
      }
    }
  }
}
예제 #22
0
double thermicSolver::computeLagNorm(int tag, simpleFunction<double> *sol)
{
  double val = 0.0, val2 = 0.0;
  SolverField<double> solField(pAssembler, LagrangeMultiplierSpace);
  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) {
    if(tag != LagrangeMultiplierFields[i]._tag) continue;
    for(groupOfElements::elementContainer::const_iterator it =
          LagrangeMultiplierFields[i].g->begin();
        it != LagrangeMultiplierFields[i].g->end(); ++it) {
      MElement *e = *it;
      // printf("element (%g,%g)
      // (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->getVertex(1)->x(),e->getVertex(1)->y());
      int npts;
      IntPt *GP;
      double jac[3][3];
      int integrationOrder = 2 * (e->getPolynomialOrder() + 1);
      e->getIntegrationPoints(integrationOrder, &npts, &GP);
      for(int j = 0; j < npts; j++) {
        double u = GP[j].pt[0];
        double v = GP[j].pt[1];
        double w = GP[j].pt[2];
        double weight = GP[j].weight;
        double detJ = fabs(e->getJacobian(u, v, w, jac));
        SPoint3 p;
        e->getParent()->pnt(u, v, w, p);
        double FEMVALUE;
        solField.f(e, u, v, w, FEMVALUE);
        double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE;
        val += diff * diff * detJ * weight;
        val2 += (*sol)(p.x(), p.y(), p.z()) * (*sol)(p.x(), p.y(), p.z()) *
                detJ * weight;
        // printf("(%g %g) : u,v=(%g,%g) detJ=%g we=%g FV=%g sol=%g
        // diff=%g\n",p.x(),p.y(),u,v,detJ,weight,FEMVALUE,(*sol)(p.x(), p.y(),
        // p.z()),diff);
      }
    }
  }
  printf("LagNorm = %g\n", sqrt(val / val2));
  return sqrt(val / val2);
}
예제 #23
0
파일: drawMesh.cpp 프로젝트: cycheung/gmsh
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);
      }
    }
  }
}
예제 #24
0
static void partitionRegions(std::vector<MElement*> &elements,
                             std::vector<std::vector<MElement*> > &regions)
{

  for (unsigned int i = 0; i < elements.size(); ++i){
    MElement *e = elements[i];
    int part = e->getPartition();
    regions[part-1].push_back(e);
  }

  std::vector<std::vector<MElement*> > allRegions;
  for (unsigned int k = 0; k < regions.size(); ++k){
    std::vector<std::vector<MElement*> >  conRegions;
    conRegions.clear();
    connectedRegions (regions[k], conRegions);
    for (unsigned int j = 0; j < conRegions.size(); j++)
      allRegions.push_back(conRegions[j]);
  }
  regions.clear();
  regions.resize(allRegions.size());
  regions = allRegions;

}
예제 #25
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;
}
예제 #26
0
std::vector<double> BGMBase::get_field_value(double u, double v, double w,
                                             const VectorStorageType &data)
{
  // TODO C++11 remove const_cast and enforce const-correctness otherwise
  MElement *e = const_cast<MElement *>(findElement(u, v, w));

  if(!e) return std::vector<double>(3, -1000.);

  std::vector<std::vector<double> > val = get_nodal_values(e, data);
  std::vector<double> element_uvw = get_element_uvw_from_xyz(e, u, v, w);

  std::vector<double> res(3);

  for(int j = 0; j < 3; j++) {
    std::vector<double> values(e->getNumVertices());

    for(std::size_t i = 0; i < e->getNumVertices(); i++) {
      values[i] = val[i][j];
    }
    res[j] = e->interpolate(&values[0], element_uvw[0], element_uvw[1],
                            element_uvw[2], 1, order);
  }
  return res;
}
예제 #27
0
double elasticitySolver::computeL2Norm(simpleFunction<double> *f0,
                                       simpleFunction<double> *f1,
                                       simpleFunction<double> *f2)
{
  double val = 0.0;
  SolverField<SVector3> solField(pAssembler, LagSpace);
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      int npts;
      IntPt *GP;
      double jac[3][3];
      int integrationOrder = 2 * (e->getPolynomialOrder() + 5);
      e->getIntegrationPoints(integrationOrder, &npts, &GP);
      for(int j = 0; j < npts; j++) {
        double u = GP[j].pt[0];
        double v = GP[j].pt[1];
        double w = GP[j].pt[2];
        double weight = GP[j].weight;
        double detJ = fabs(e->getJacobian(u, v, w, jac));
        SPoint3 p;
        e->pnt(u, v, w, p);
        SVector3 FEMVALUE;
        solField.f(e, u, v, w, FEMVALUE);
        SVector3 sol((*f0)(p.x(), p.y(), p.z()), (*f1)(p.x(), p.y(), p.z()),
                     (*f2)(p.x(), p.y(), p.z()));
        double diff = normSq(sol - FEMVALUE);
        val += diff * detJ * weight;
      }
    }
  }
  printf("L2Norm = %g\n", sqrt(val));
  return sqrt(val);
}
예제 #28
0
파일: drawMesh.cpp 프로젝트: cycheung/gmsh
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);
}
예제 #29
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;
}
예제 #30
0
PView *elasticitySolver::buildErrorView(const std::string postFileName,
                                        simpleFunction<double> *f0,
                                        simpleFunction<double> *f1,
                                        simpleFunction<double> *f2)
{
  std::cout << "build Error View" << std::endl;
  std::map<int, std::vector<double> > data;

  SolverField<SVector3> solField(pAssembler, LagSpace);
  for(std::size_t i = 0; i < elasticFields.size(); ++i) {
    for(groupOfElements::elementContainer::const_iterator it =
          elasticFields[i].g->begin();
        it != elasticFields[i].g->end(); ++it) {
      MElement *e = *it;
      int npts;
      IntPt *GP;
      double jac[3][3];
      int integrationOrder = 2 * (e->getPolynomialOrder() + 5);
      e->getIntegrationPoints(integrationOrder, &npts, &GP);
      double val = 0.0;
      for(int j = 0; j < npts; j++) {
        double u = GP[j].pt[0];
        double v = GP[j].pt[1];
        double w = GP[j].pt[2];
        double weight = GP[j].weight;
        double detJ = fabs(e->getJacobian(u, v, w, jac));
        SPoint3 p;
        e->pnt(u, v, w, p);
        SVector3 FEMVALUE;
        solField.f(e, u, v, w, FEMVALUE);
        SVector3 sol((*f0)(p.x(), p.y(), p.z()), (*f1)(p.x(), p.y(), p.z()),
                     (*f2)(p.x(), p.y(), p.z()));
        double diff = normSq(sol - FEMVALUE);
        val += diff * detJ * weight;
      }
      std::vector<double> vec;
      vec.push_back(sqrt(val));
      data[e->getNum()] = vec;
    }
  }

  PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0, 1);
  return pv;
}