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; }
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); } }
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); }
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; }
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; }
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; }
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; }
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 }
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(""); }
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 }
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 }