Пример #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 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);
  }
}
Пример #3
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);
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
0
int GModel::readDIFF(const std::string &name)
{
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  char str[256] = "XXX";
  std::map<int, std::vector<MElement*> > elements[10];
  std::map<int, std::map<int, std::string> > physicals[4];
  std::map<int, MVertex*> vertexMap;
  std::vector<MVertex*> vertexVector;

  {
    while(strstr(str, "Number of space dim. =") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }

    int dim;
    if(sscanf(str, "%*s %*s %*s %*s %*s %d", &dim) != 1){ fclose(fp); return 0; }
    Msg::Info("dimension %d", dim);

    int numElements;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Number of elements   =") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%*s %*s %*s %*s %d", &numElements) != 1){ fclose(fp); return 0; }
    Msg::Info("%d elements", numElements);

    int numVertices;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Number of nodes      =") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%*s %*s %*s %*s %d", &numVertices) != 1){ fclose(fp); return 0; }
    Msg::Info("%d vertices", numVertices);

    int numVerticesPerElement;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Max number of nodes in an element:")==NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%*s %*s %*s %*s %*s %*s %*s %d", &numVerticesPerElement) != 1){
      fclose(fp);
      return 0;
    }
    Msg::Info("numVerticesPerElement %d", numVerticesPerElement);

    bool several_subdomains;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    if(!strncmp(&str[2], "Only one material", 17) ||
       !strncmp(&str[2], "Only one subdomain", 18)){
      if(!strncmp(&str[37], "dpTRUE", 6) || !strncmp(&str[37], "true", 4) ||
         !strncmp(&str[36], "dpTRUE", 6) || !strncmp(&str[36], "true", 4)){
        several_subdomains = false;
      }
      else{
        several_subdomains = true;
      }
      Msg::Info("several_subdomains %x %s", several_subdomains, str);
    }

    int nbi;
    std::vector<int> bi;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Boundary indicators:") == NULL &&
          strstr(str, "boundary indicators:") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%d %*s %*s", &nbi) != 1){ fclose(fp); return 0; }
    Msg::Info("nbi %d", nbi);
    if(nbi != 0)
      bi.resize(nbi);
    std::string format_read_bi = "%*d %*s %*s";
    for(int i = 0; i < nbi; i++){
      if(format_read_bi[format_read_bi.size()-1] == 'd') {
        format_read_bi[format_read_bi.size()-1] = '*';
        format_read_bi += "d %d";
      }
      else
        format_read_bi += " %d";
      if(sscanf(str, format_read_bi.c_str(), &bi[i]) != 1){ fclose(fp); return 0; }
      Msg::Info("bi[%d]=%d", i, bi[i]);
    }

    while(str[0] != '#'){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    vertexVector.clear();
    vertexMap.clear();
    int minVertex = numVertices + 1, maxVertex = -1;
    int num = 0;
    std::vector<std::vector<int> > elementary(numVertices);

    Msg::ResetProgressMeter();
    for(int i = 0; i < numVertices; i++){
      if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; }
      double xyz[3];
      int tmp;
      if(sscanf(str, "%d ( %lf , %lf , %lf ) [%d]", &num,
                &xyz[0], &xyz[1], &xyz[2], &tmp) != 5){ fclose(fp); return 0; }
      elementary[i].resize(tmp + 1);
      elementary[i][0] = tmp;
      minVertex = std::min(minVertex, num);
      maxVertex = std::max(maxVertex, num);
      if(vertexMap.count(num))
        Msg::Warning("Skipping duplicate vertex %d", num);
      else
        vertexMap[num] = new MVertex(xyz[0], xyz[1], xyz[2], 0, num);
      if(numVertices > 100000)
        Msg::ProgressMeter(i + 1, numVertices, true, "Reading nodes");
      // If the vertex numbering is dense, tranfer the map into a
      // vector to speed up element creation
      if((int)vertexMap.size() == numVertices &&
         ((minVertex == 1 && maxVertex == numVertices) ||
          (minVertex == 0 && maxVertex == numVertices - 1))){
        Msg::Info("Vertex numbering is dense");
        vertexVector.resize(vertexMap.size() + 1);
        if(minVertex == 1)
          vertexVector[0] = 0;
        else
          vertexVector[numVertices] = 0;
        std::map<int, MVertex*>::const_iterator it = vertexMap.begin();
        for(; it != vertexMap.end(); ++it)
          vertexVector[it->first] = it->second;
        vertexMap.clear();
      }
      Msg::Info("%d ( %lf , %lf , %lf ) [%d]",i, xyz[0], xyz[1], xyz[2],
                elementary[i][0]);
      std::string format_read_bi = "%*d ( %*lf , %*lf , %*lf ) [%*d]";
      for(int j = 0; j < elementary[i][0]; j++){
        if(format_read_bi[format_read_bi.size() - 1] == 'd') {
          format_read_bi[format_read_bi.size() - 1] = '*';
          format_read_bi += "d %d";
        }
        else
          format_read_bi += " %d";
        if(sscanf(str, format_read_bi.c_str(), &(elementary[i][j + 1])) != 1){
          fclose(fp);
          return 0;
        }
        Msg::Info("elementary[%d][%d]=%d", i + 1, j + 1, elementary[i][j + 1]);
      }
    }
    while(str[0] != '#'){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    std::vector<int> material(numElements);
    std::vector<std::vector<int> > ElementsNodes(numElements);
    for(int i = 0; i < numElements; i++){
      ElementsNodes[i].resize(numVerticesPerElement);
    }
    char eleTypec[20]="";
    std::string eleType;
    Msg::ResetProgressMeter();
    std::vector<int> mapping;
    for(int i = 1; i <= numElements; i++){
      if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; }
      int num = 0, type, physical = 0, partition = 0;
      int indices[60];
      if(sscanf(str, "%*d %s %d", eleTypec, &material[i-1]) != 2){ fclose(fp); return 0; }
      eleType = std::string(eleTypec);
      int k2; // local number for the element
      int NoVertices; // number of vertices per element
      if(eleType == "ElmT3n2D"){
        NoVertices = 3;
        static int map[3] = {0, 1, 2}; // identical to gmsh
        mapping=std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TRI_3;
      }
      else if(eleType == "ElmT6n2D"){
        NoVertices = 6;
        static int map[6] = {0, 1, 2, 3, 4, 5}; // identical to gmsh
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TRI_6;
      }
      else if(eleType == "ElmB4n2D"){
        NoVertices = 4;
        static int map[4] = {0, 1, 3, 2}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_QUA_4;
      }
      else if(eleType == "ElmB8n2D"){
        NoVertices = 8;
        static int map[8] = {0, 1, 3, 2, 4, 6, 7, 5}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_QUA_8;
      }
      else if(eleType == "ElmB9n2D"){
        NoVertices = 9;
        static int map[9] = {0, 4, 1, 7, 8, 5, 3, 6, 2}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_QUA_9;
      }
      else if(eleType == "ElmT4n3D"){
        NoVertices = 4;
        static int map[4] = {0, 1, 2, 3}; // identical to gmsh
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TET_4;
      }
      else if(eleType == "ElmT10n3D"){
        NoVertices = 10;
        static int map[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TET_10;
      }
      else if(eleType == "ElmB8n3D"){
        NoVertices = 8;
        static int map[8] = {4, 5, 0, 1, 7, 6, 3, 2};
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_HEX_8;
      }
      else if(eleType == "ElmB20n3D"){
        NoVertices = 20;
        static int map[20] = {4, 5, 0, 1, 7, 6, 3, 2, 16, 8, 19, 13, 15, 12,
                              14, 17, 18, 9, 11};
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_HEX_20;
      }
      else if(eleType == "ElmB27n3D"){
        NoVertices = 27;
        static int map[27] = {4, 16, 5, 10, 21, 12, 0, 8, 1, 17, 25, 18, 22,
                              26, 23, 9, 20, 11, 7, 19, 6, 15, 24, 14, 3, 13, 2};
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_HEX_27;
      }
      else{
        fclose(fp);
        return 0;
      }
      std::string format_read_vertices = "%*d %*s %*d";
      for(int k = 0; k < NoVertices; k++){
        if(format_read_vertices[format_read_vertices.size()-2] != '*') {
          format_read_vertices[format_read_vertices.size()-1] = '*';
          format_read_vertices += "d %d";
        }
        else
          format_read_vertices += " %d";
        k2 = mapping[k];
        if(sscanf(str, format_read_vertices.c_str(), &ElementsNodes[i-1][k2]) != 1){
          fclose(fp);
          return 0;
        }
      }
      mapping.clear();
      for(int j = 0; j < NoVertices; j++)
        indices[j] = ElementsNodes[i - 1][j];
      std::vector<MVertex*> vertices;
      if(vertexVector.size()){
        if(!getVertices(numVerticesPerElement, indices, vertexVector, vertices)){
          fclose(fp);
          return 0;
        }
      }
      else{
        if(!getVertices(numVerticesPerElement, indices, vertexMap, vertices)){
          fclose(fp);
          return 0;
        }
      }

      MElementFactory f;
      MElement *e = f.create(type, vertices, num, partition);
      if(!e){
        Msg::Error("Unknown type of element %d", type);
        fclose(fp);
        return 0;
      }
      int reg = elementary[i-1][1];
      switch(e->getType()){
      case TYPE_PNT : elements[0][reg].push_back(e); break;
      case TYPE_LIN : elements[1][reg].push_back(e); break;
      case TYPE_TRI : elements[2][reg].push_back(e); break;
      case TYPE_QUA : elements[3][reg].push_back(e); break;
      case TYPE_TET : elements[4][reg].push_back(e); break;
      case TYPE_HEX : elements[5][reg].push_back(e); break;
      case TYPE_PRI : elements[6][reg].push_back(e); break;
      case TYPE_PYR : elements[7][reg].push_back(e); break;
      default : Msg::Error("Wrong type of element"); fclose(fp); return 0;
      }
      int dim = e->getDim();
      if(physical && (!physicals[dim].count(reg) ||
                      !physicals[dim][reg].count(physical)))
        physicals[dim][reg][physical] = "unnamed";
      if(partition) getMeshPartitions().insert(partition);

      if(numElements > 100000)
        Msg::ProgressMeter(i + 1, numElements, true, "Reading elements");
    }
  }

  // store the elements in their associated elementary entity. If the
  // entity does not exist, create a new (discrete) one.
  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);

  // associate the correct geometrical entity with each mesh vertex
  _associateEntityWithMeshVertices();

  // store the vertices in their associated geometrical entity
  if(vertexVector.size())
    _storeVerticesInEntities(vertexVector);
  else
    _storeVerticesInEntities(vertexMap);

  // store the physical tags
  for(int i = 0; i < 4; i++)
    _storePhysicalTagsInEntities(i, physicals[i]);

  fclose(fp);
  return 1;
}
Пример #7
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;
}
Пример #8
0
void HighOrderMeshOptimizer(GModel *gm, OptHomParameters &p)
{
#if defined(HAVE_BFGS)
  double t1 = Cpu();

  int samples = 30;

  double tf1 = Cpu();

  Msg::StatusBar(true, "Optimizing high order mesh...");
  std::vector<GEntity*> entities;
  gm->getEntities(entities);

  std::map<MVertex*, std::vector<MElement *> > vertex2elements;
  std::map<MElement*,GEntity*> element2entity;
  elSet badasses;
  double maxdist = 0.;                                                  // TODO: To be cleaned?

  std::map<MElement*,double> distances;
  distanceFromElementsToGeometry(gm, p.dim,distances);

  for (int iEnt = 0; iEnt < entities.size(); ++iEnt) {
    GEntity* &entity = entities[iEnt];
    if (entity->dim() != p.dim || (p.onlyVisible && !entity->getVisibility())) continue;
    Msg::Info("Computing connectivity and bad elements for entity %d...",
              entity->tag());
    calcVertex2Elements(p.dim,entity,vertex2elements);
    if (p.optPrimSurfMesh) calcElement2Entity(entity,element2entity);
    for (int iEl = 0; iEl < entity->getNumMeshElements();iEl++) {       // Detect bad elements
      double jmin, jmax;
      MElement *el = entity->getMeshElement(iEl);
      if (el->getDim() == p.dim) {
	// FIXME TEST
	//        badasses.insert(el);
        if (p.optCAD) {
	  //          const double DISTE =computeBndDist(el,2,fabs(p.discrTolerance));
	  const double DISTE =distances[el];
	  //	  if (DISTE > 0)printf("El %d dist %12.5E vs %12.5E\n",iEl,DISTE,p.optCADDistMax);
          maxdist = std::max(DISTE, maxdist);
          if (DISTE > p.optCADDistMax) badasses.insert(el);
        }
        el->scaledJacRange(jmin, jmax, p.optPrimSurfMesh ? entity : 0);
        if (p.BARRIER_MIN_METRIC > 0) jmax = jmin;
        if (jmin < p.BARRIER_MIN || jmax > p.BARRIER_MAX) badasses.insert(el);
      }
    }
  }
  printf("maxdist = %g badasses size = %lu\n", maxdist, badasses.size());

  if (p.strategy == 0)
    optimizeConnectedBlobs(vertex2elements, element2entity, badasses, p, samples, false);
  else if (p.strategy == 2)
    optimizeConnectedBlobs(vertex2elements, element2entity, badasses, p, samples, true);
  else
    optimizeOneByOne(vertex2elements, element2entity, badasses, p, samples);

  if (p.SUCCESS == 1)
    Msg::Info("Optimization succeeded");
  else if (p.SUCCESS == 0)
    Msg::Warning("All jacobians positive but not all in the range");
  else if (p.SUCCESS == -1)
    Msg::Error("Still negative jacobians");

  double t2 = Cpu();
  p.CPU = t2-t1;

  Msg::StatusBar(true, "Done optimizing high order mesh (%g s)", p.CPU);
#else
  Msg::Error("High-order mesh optimizer requires BFGS");
#endif
}
Пример #9
0
static void select_elements_cb(Fl_Widget *w, void *data)
{
  classificationEditor *e = (classificationEditor*)data;
  bool all = (w == e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]);

  // allocate discrete edge to hold the selected mesh segments
  if(!e->selected){
    e->selected = new discreteEdge
      (GModel::current(), GModel::current()->getMaxElementaryNumber(1) + 1, 0, 0);
    GModel::current()->add(e->selected);
  }

  if(all){
    for(GModel::fiter it = GModel::current()->firstFace();
        it != GModel::current()->lastFace(); ++it){
      e->elements.insert(e->elements.end(), (*it)->triangles.begin(),
                         (*it)->triangles.end());
      e->elements.insert(e->elements.end(), (*it)->quadrangles.begin(),
                         (*it)->quadrangles.end());
    }
  }
  else{
    CTX::instance()->pickElements = 1;
    while(1) {
      CTX::instance()->mesh.changed = ENT_ALL;
      drawContext::global()->draw();
      Msg::StatusGl("Select elements\n"
                    "[Press 'e' to end selection or 'q' to abort]");

      char ib = FlGui::instance()->selectEntity(ENT_ALL);
      if(ib == 'l') {
        for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
          MElement *me = FlGui::instance()->selectedElements[i];
          if(me->getDim() == 2 && me->getVisibility() != 2){
            me->setVisibility(2);
            e->elements.push_back(me);
          }
        }
      }
      if(ib == 'r') {
        for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
          MElement *me = FlGui::instance()->selectedElements[i];
          if(me->getVisibility() == 2)
            e->elements.erase(std::find(e->elements.begin(), e->elements.end(), me));
          me->setVisibility(1);
        }
      }
      if(ib == 'e') { // ok, compute the edges
        GModel::current()->setSelection(0);
        break;
      }
      if(ib == 'q') { // do nothing
        GModel::current()->setSelection(0);
        e->elements.clear();
        break;
      }
    }
    CTX::instance()->pickElements = 0;
  }

  e2t_cont adj;
  buildEdgeToElements(e->elements, adj);
  buildListOfEdgeAngle(adj, e->edges_detected, e->edges_lonly);
  ElementsSelectedMode(e);
  update_edges_cb(0, data);
  Msg::StatusGl("");
}
Пример #10
0
void meshOptimizer(GModel *gm, MeshOptParameters &par)
{
#if defined(HAVE_BFGS)
  if (par.nCurses)
    mvinit();
  redirectMessage _logWriter(par.logFileName, !par.nCurses);
  if (par.logFileName.compare("") != 0 || par.nCurses)
    Msg::SetCallback(&_logWriter);

    
  double startTime = Cpu();
  if (par.nCurses) {
    mvbold(true);
    mvprintCenter(0, "OPTIMIZING MESH");
    mvfillRow(1,'-');
    mvfillRow(10,'-');
    mvfillRow(20,'-');
    mvfillRow(27,'-');
    mvbold(false);
  }
  if (par.verbose > 0) Msg::StatusBar(true, "Optimizing mesh...");

  std::vector<GEntity*> entities;
  gm->getEntities(entities);

  vertElVecMap vertex2elements;
  elEntMap element2entity, bndEl2Ent;
  elElMap el2BndEl;
  elSet badElts;
  for (int iEnt = 0; iEnt < entities.size(); ++iEnt) {
    GEntity* &entity = entities[iEnt];
    if (entity->dim() != par.dim ||
        (par.onlyVisible && !entity->getVisibility())) continue;
    if (par.nCurses) {
      mvprintCenter(15, "Computing connectivity and bad elements for entity %3d...", entity->tag());
    }
    Msg::Info("Computing connectivity and bad elements for entity %d...",
              entity->tag());
    calcVertex2Elements(par.dim, entity, vertex2elements);
    if ((par.useGeomForPatches) || (par.useGeomForOpt))
      calcElement2Entity(entity, element2entity);
    if (par.useBoundaries) calcBndInfo(entity, el2BndEl, bndEl2Ent);
    for (int iEl = 0; iEl < entity->getNumMeshElements(); iEl++) {                               // Detect bad elements
      MElement *el = entity->getMeshElement(iEl);
      if (el->getDim() == par.dim) {
        if (par.patchDef->elBadness(el, entity) < 0.) badElts.insert(el);
        else if (par.useBoundaries) {
          elElMap::iterator bndElIt = el2BndEl.find(el);
          if (bndElIt != el2BndEl.end()) {
            MElement* &bndEl = bndElIt->second;
            if (par.patchDef->bndElBadness(bndEl, bndEl2Ent[bndEl]) < 0.) badElts.insert(el);
          }
        }
      }
    }
  }

  if (par.patchDef->strategy == MeshOptPatchDef::STRAT_DISJOINT)
    optimizeDisjointPatches(vertex2elements, element2entity,
                            el2BndEl, bndEl2Ent, badElts, par);
  else if (par.patchDef->strategy == MeshOptPatchDef::STRAT_ONEBYONE)
    optimizeOneByOne(vertex2elements, element2entity,
                     el2BndEl, bndEl2Ent, badElts, par);
  else {
    if (par.nCurses){
      mvcolor(2,true);
      mvbold(true);
      mvprintCenter(-2, " ERROR: Unknown strategy %d for mesh optimization ", par.patchDef->strategy);
      mvcolor(2,false);
      mvbold(false);    
    }
    else
      Msg::Error("Unknown strategy %d for mesh optimization", par.patchDef->strategy);
  }

  if (par.verbose > 0) {
    if (par.success == 1){
      if (par.nCurses){
        mvcolor(4,true);
        mvbold(true);
        mvprintCenter(-2, " Optimization succeeded ");
        mvcolor(4,false);
        mvbold(false);    
      }
      else
        Msg::Info("Optimization succeeded");
    }
    else if (par.success == 0){
      if (par.nCurses){
        mvcolor(5,true);
        mvbold(true);
        mvprintCenter(-2, " Optimization partially failed (all measures above critical value, but some below target) ");
        mvcolor(5,false);
        mvbold(false);    
      }
      else
        Msg::Warning("Optimization partially failed (all measures above critical "
                     "value, but some below target)");
    }
    else if (par.success == -1){
      if (par.nCurses){
        mvcolor(3,true);
        mvbold(true);
        mvprintCenter(-2, "Optimization Failed");
        mvcolor(3,false);
        mvbold(false);    
      }
      else
        Msg::Error("Optimization failed (some measures below critical value)");
    }
    par.CPU = Cpu()-startTime;
    Msg::StatusBar(true, "Done optimizing mesh (%g s)", par.CPU);
  }
  if (par.nCurses){
    mvpause();
    mvterminate();
  }
  if (par.logFileName.compare("") != 0 || par.nCurses)
    Msg::SetCallback(NULL);
  
#else
  Msg::Error("Mesh optimizer requires BFGS");
#endif
}
Пример #11
0
void meshOptimizer(GModel *gm, MeshOptParameters &par)
{
#if defined(HAVE_BFGS)

  double startTime = Cpu();
  if (par.verbose > 0) Msg::StatusBar(true, "Optimizing mesh...");

  std::vector<GEntity*> entities;
  gm->getEntities(entities);

  vertElVecMap vertex2elements;
  elEntMap element2entity, bndEl2Ent;
  elElMap el2BndEl;
  elSet badElts;
  for (int iEnt = 0; iEnt < entities.size(); ++iEnt) {
    GEntity* &entity = entities[iEnt];
    if (entity->dim() != par.dim ||
        (par.onlyVisible && !entity->getVisibility())) continue;
    Msg::Info("Computing connectivity and bad elements for entity %d...",
              entity->tag());
    calcVertex2Elements(par.dim, entity, vertex2elements);
    if ((par.useGeomForPatches) || (par.useGeomForOpt))
      calcElement2Entity(entity, element2entity);
    if (par.useBoundaries) calcBndInfo(entity, el2BndEl, bndEl2Ent);
    for (int iEl = 0; iEl < entity->getNumMeshElements(); iEl++) {                               // Detect bad elements
      MElement *el = entity->getMeshElement(iEl);
      if (el->getDim() == par.dim) {
        if (par.patchDef->elBadness(el, entity) < 0.) badElts.insert(el);
        else if (par.useBoundaries) {
          elElMap::iterator bndElIt = el2BndEl.find(el);
          if (bndElIt != el2BndEl.end()) {
            MElement* &bndEl = bndElIt->second;
            if (par.patchDef->bndElBadness(bndEl, bndEl2Ent[bndEl]) < 0.) badElts.insert(el);
          }
        }
      }
    }
  }

  if (par.patchDef->strategy == MeshOptPatchDef::STRAT_DISJOINT)
    optimizeDisjointPatches(vertex2elements, element2entity,
                            el2BndEl, bndEl2Ent, badElts, par);
  else if (par.patchDef->strategy == MeshOptPatchDef::STRAT_ONEBYONE)
    optimizeOneByOne(vertex2elements, element2entity,
                     el2BndEl, bndEl2Ent, badElts, par);
  else
    Msg::Error("Unknown strategy %d for mesh optimization", par.patchDef->strategy);

  if (par.verbose > 0) {
    if (par.success == 1)
      Msg::Info("Optimization succeeded");
    else if (par.success == 0)
      Msg::Warning("Optimization partially failed (all measures above critical "
                    "value, but some below target)");
    else if (par.success == -1)
      Msg::Error("Optimization failed (some measures below critical value)");
    par.CPU = Cpu()-startTime;
    Msg::StatusBar(true, "Done optimizing mesh (%g s)", par.CPU);
  }

#else
  Msg::Error("Mesh optimizer requires BFGS");
#endif
}