Пример #1
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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);
}
Пример #5
0
static void delete_edge_cb(Fl_Widget *w, void *data)
{
  classificationEditor *e = (classificationEditor*)data;

  if(!e->selected) return;

  CTX::instance()->pickElements = 1;
  std::vector<MLine*> ele;

  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->getType() == TYPE_LIN && me->getVisibility() != 2){
          me->setVisibility(2);
          ele.push_back((MLine*)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)
          ele.erase(std::find(ele.begin(), ele.end(), me));
        me->setVisibility(1);
      }
    }
    if(ib == 'e') {
      GModel::current()->setSelection(0);
      break;
    }
    if(ib == 'q') {
      GModel::current()->setSelection(0);
      ele.clear();
      break;
    }
  }

  std::sort(ele.begin(), ele.end());

  // look in all selected edges if a deleted one is present and delete it
  std::vector<MLine*> temp = e->selected->lines;
  e->selected->lines.clear();
  for(unsigned int i = 0; i < temp.size(); i++){
    std::vector<MLine*>::iterator it = std::find(ele.begin(), ele.end(), temp[i]);
    if(it != ele.end())
      delete temp[i];
    else
      e->selected->lines.push_back(temp[i]);
  }

  CTX::instance()->mesh.changed = ENT_ALL;
  CTX::instance()->pickElements = 0;
  drawContext::global()->draw();
  Msg::StatusGl("");

  e->elements.clear();
  e->edges_detected.clear();
}