13 std::map<int, MVertex *> &map,
14 std::vector<MVertex *> &vertices)
16 for(
int i = 0; i < num; i++) {
17 if(!map.count(indices[i])) {
22 vertices.push_back(map[indices[i]]);
28 std::vector<MVertex *> &vertices,
int minVertex = 0)
30 for(
int i = 0; i < num; i++) {
31 if(indices[i] < minVertex ||
32 indices[i] > (
int)(vec.size() - 1 + minVertex)) {
37 vertices.push_back(vec[indices[i]]);
44 FILE *fp =
Fopen(name.c_str(),
"r");
46 Msg::Error(
"Unable to open file '%s'", name.c_str());
50 char str[256] =
"XXX";
51 std::map<int, std::vector<MElement *> > elements[10];
52 std::map<int, std::map<int, std::string> > physicals[4];
53 std::map<int, MVertex *> vertexMap;
54 std::vector<MVertex *> vertexVector;
57 while(strstr(str,
"Number of space dim. =") ==
nullptr) {
58 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
62 if(sscanf(str,
"%*s %*s %*s %*s %*s %d", &dim) != 1) {
69 if(!fgets(str,
sizeof(str), fp) || feof(fp)) {
73 while(strstr(str,
"Number of elements =") ==
nullptr) {
74 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
76 if(sscanf(str,
"%*s %*s %*s %*s %d", &numElements) != 1) {
83 if(!fgets(str,
sizeof(str), fp) || feof(fp)) {
87 while(strstr(str,
"Number of nodes =") ==
nullptr) {
88 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
90 if(sscanf(str,
"%*s %*s %*s %*s %d", &numVertices) != 1) {
96 int numVerticesPerElement;
97 if(!fgets(str,
sizeof(str), fp) || feof(fp)) {
101 while(strstr(str,
"Max number of nodes in an element:") ==
nullptr) {
102 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
104 if(sscanf(str,
"%*s %*s %*s %*s %*s %*s %*s %d", &numVerticesPerElement) !=
109 Msg::Info(
"numVerticesPerElement %d", numVerticesPerElement);
111 bool several_subdomains;
112 if(!fgets(str,
sizeof(str), fp) || feof(fp)) {
116 if(!strncmp(&str[2],
"Only one material", 17) ||
117 !strncmp(&str[2],
"Only one subdomain", 18)) {
118 if(!strncmp(&str[37],
"dpTRUE", 6) || !strncmp(&str[37],
"true", 4) ||
119 !strncmp(&str[36],
"dpTRUE", 6) || !strncmp(&str[36],
"true", 4)) {
120 several_subdomains =
false;
123 several_subdomains =
true;
125 Msg::Info(
"several_subdomains %x %s", several_subdomains, str);
130 if(!fgets(str,
sizeof(str), fp) || feof(fp)) {
134 while(strstr(str,
"Boundary indicators:") ==
nullptr &&
135 strstr(str,
"boundary indicators:") ==
nullptr) {
136 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
138 if(sscanf(str,
"%d %*s %*s", &nbi) != 1) {
143 if(nbi != 0) bi.resize(nbi);
144 std::string format_read_bi =
"%*d %*s %*s";
145 for(
int i = 0; i < nbi; i++) {
146 if(format_read_bi[format_read_bi.size() - 1] ==
'd') {
147 format_read_bi[format_read_bi.size() - 1] =
'*';
148 format_read_bi +=
"d %d";
151 format_read_bi +=
" %d";
152 if(sscanf(str, format_read_bi.c_str(), &bi[i]) != 1) {
159 while(str[0] !=
'#') {
160 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
162 vertexVector.clear();
164 int minVertex = numVertices + 1, maxVertex = -1;
166 std::vector<std::vector<int> > elementary(numVertices);
169 for(
int i = 0; i < numVertices; i++) {
170 if(!fgets(str,
sizeof(str), fp)) {
176 if(sscanf(str,
"%d ( %lf , %lf , %lf ) [%d]", &num, &xyz[0], &xyz[1],
177 &xyz[2], &tmp) != 5) {
181 elementary[i].resize(tmp + 1);
182 elementary[i][0] = tmp;
183 minVertex = std::min(minVertex, num);
184 maxVertex = std::max(maxVertex, num);
185 if(vertexMap.count(num))
188 vertexMap[num] =
new MVertex(xyz[0], xyz[1], xyz[2],
nullptr, num);
192 if((
int)vertexMap.size() == numVertices &&
193 ((minVertex == 1 && maxVertex == numVertices) ||
194 (minVertex == 0 && maxVertex == numVertices - 1))) {
196 vertexVector.resize(vertexMap.size() + 1);
198 vertexVector[0] =
nullptr;
200 vertexVector[numVertices] =
nullptr;
201 for(
auto it = vertexMap.begin(); it != vertexMap.end(); ++it)
202 vertexVector[it->first] = it->second;
205 Msg::Info(
"%d ( %lf , %lf , %lf ) [%d]", i, xyz[0], xyz[1], xyz[2],
207 std::string format_read_bi =
"%*d ( %*lf , %*lf , %*lf ) [%*d]";
208 for(
int j = 0; j < elementary[i][0]; j++) {
209 if(format_read_bi[format_read_bi.size() - 1] ==
'd') {
210 format_read_bi[format_read_bi.size() - 1] =
'*';
211 format_read_bi +=
"d %d";
214 format_read_bi +=
" %d";
215 if(sscanf(str, format_read_bi.c_str(), &(elementary[i][j + 1])) != 1) {
219 Msg::Info(
"elementary[%d][%d]=%d", i + 1, j + 1, elementary[i][j + 1]);
224 while(str[0] !=
'#') {
225 if(!fgets(str,
sizeof(str), fp) || feof(fp))
break;
227 std::vector<int> material(numElements);
228 std::vector<std::vector<int> > ElementsNodes(numElements);
229 for(
int i = 0; i < numElements; i++) {
230 ElementsNodes[i].resize(numVerticesPerElement);
232 char eleTypec[20] =
"";
234 std::vector<int> mapping;
237 for(
int i = 1; i <= numElements; i++) {
238 if(!fgets(str,
sizeof(str), fp)) {
242 int num = 0, type, physical = 0;
243 unsigned int partition = 0;
245 if(sscanf(str,
"%*d %s %d", eleTypec, &material[i - 1]) != 2) {
249 eleType = std::string(eleTypec);
252 if(eleType ==
"ElmT3n2D") {
254 static int map[3] = {0, 1, 2};
255 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
258 else if(eleType ==
"ElmT6n2D") {
260 static int map[6] = {0, 1, 2, 3, 4, 5};
261 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
264 else if(eleType ==
"ElmB4n2D") {
266 static int map[4] = {0, 1, 3, 2};
267 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
270 else if(eleType ==
"ElmB8n2D") {
272 static int map[8] = {0, 1, 3, 2, 4, 6, 7, 5};
273 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
276 else if(eleType ==
"ElmB9n2D") {
278 static int map[9] = {0, 4, 1, 7, 8, 5, 3, 6, 2};
279 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
282 else if(eleType ==
"ElmT4n3D") {
284 static int map[4] = {0, 1, 2, 3};
285 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
288 else if(eleType ==
"ElmT10n3D") {
290 static int map[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
291 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
294 else if(eleType ==
"ElmB8n3D") {
296 static int map[8] = {4, 5, 0, 1, 7, 6, 3, 2};
297 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
300 else if(eleType ==
"ElmB20n3D") {
302 static int map[20] = {4, 5, 0, 1, 7, 6, 3, 2, 16, 8,
303 19, 13, 15, 12, 14, 17, 18, 9, 11};
304 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
307 else if(eleType ==
"ElmB27n3D") {
309 static int map[27] = {4, 16, 5, 10, 21, 12, 0, 8, 1,
310 17, 25, 18, 22, 26, 23, 9, 20, 11,
311 7, 19, 6, 15, 24, 14, 3, 13, 2};
312 mapping = std::vector<int>(map, map +
sizeof(map) /
sizeof(
int));
319 std::string format_read_vertices =
"%*d %*s %*d";
320 for(
int k = 0; k < NoVertices; k++) {
321 if(format_read_vertices[format_read_vertices.size() - 2] !=
'*') {
322 format_read_vertices[format_read_vertices.size() - 1] =
'*';
323 format_read_vertices +=
"d %d";
326 format_read_vertices +=
" %d";
328 if(sscanf(str, format_read_vertices.c_str(),
329 &ElementsNodes[i - 1][k2]) != 1) {
335 for(
int j = 0; j < NoVertices; j++) indices[j] = ElementsNodes[i - 1][j];
337 if(vertexVector.size()) {
355 Msg::Error(
"Unknown type of element %d", type);
359 int reg = elementary[i - 1][1];
361 case TYPE_PNT: elements[0][reg].push_back(e);
break;
362 case TYPE_LIN: elements[1][reg].push_back(e);
break;
363 case TYPE_TRI: elements[2][reg].push_back(e);
break;
364 case TYPE_QUA: elements[3][reg].push_back(e);
break;
365 case TYPE_TET: elements[4][reg].push_back(e);
break;
366 case TYPE_HEX: elements[5][reg].push_back(e);
break;
367 case TYPE_PRI: elements[6][reg].push_back(e);
break;
368 case TYPE_PYR: elements[7][reg].push_back(e);
break;
376 (!physicals[dim].count(reg) || !physicals[dim][reg].count(physical)))
377 physicals[dim][reg][physical] =
"unnamed";
380 if(numElements > 100000)
388 for(
int i = 0; i < (int)(
sizeof(elements) /
sizeof(elements[0])); i++)
395 if(vertexVector.size())
408 double scalingFactor)
411 Msg::Error(
"Binary DIFF output is not implemented");
415 FILE *fp =
Fopen(name.c_str(), binary ?
"wb" :
"w");
417 Msg::Error(
"Unable to open file '%s'", name.c_str());
422 bool usePhysicalTags =
true;
426 usePhysicalTags =
false;
433 std::vector<GEntity *> entities;
438 for(std::size_t i = 0; i < entities.size(); i++) {
439 if((entities[i]->physicals.size() || saveAll) &&
440 entities[i]->getNumMeshElements()) {
441 dim = std::max(dim, entities[i]->dim());
448 std::vector<std::list<int> > vertexTags(numVertices);
449 std::list<int> boundaryIndicators;
450 for(std::size_t ient = 0; ient < entities.size(); ient++) {
452 if(ge->
dim() != dim - 1)
continue;
454 if(usePhysicalTags) {
455 for(
auto p : ge->
physicals) boundaryIndicators.push_back(p);
458 boundaryIndicators.push_back(ge->
tag());
465 if(usePhysicalTags) {
467 vertexTags[v->
getIndex() - 1].push_back(p);
470 vertexTags[v->
getIndex() - 1].push_back(ge->
tag());
476 boundaryIndicators.sort();
477 boundaryIndicators.unique();
478 for(
int i = 0; i < numVertices; i++) {
479 vertexTags[i].sort();
480 vertexTags[i].unique();
484 std::size_t numElements = 0;
485 std::size_t maxNumNodesPerElement = 0, minNumNodesPerElement = 1000;
486 for(std::size_t i = 0; i < entities.size(); i++) {
487 if(entities[i]->physicals.size() || saveAll) {
488 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
489 MElement *e = entities[i]->getMeshElement(j);
492 maxNumNodesPerElement =
494 minNumNodesPerElement =
502 fprintf(fp,
" Finite element mesh (GridFE):\n\n");
503 fprintf(fp,
" Number of space dim. = 3\n");
504 fprintf(fp,
" Number of elements = %lu\n", numElements);
505 fprintf(fp,
" Number of nodes = %d\n\n", numVertices);
506 fprintf(fp,
" All elements are of the same type: %s\n",
507 (maxNumNodesPerElement != minNumNodesPerElement) ?
"dpFALSE" :
"dpTRUE");
508 fprintf(fp,
" Max number of nodes in an element: %lu \n",
509 maxNumNodesPerElement);
510 fprintf(fp,
" Only one subdomain : dpFALSE\n");
511 fprintf(fp,
" Lattice data ? 0\n\n\n\n");
512 fprintf(fp,
" %d Boundary indicators: ", (
int)boundaryIndicators.size());
513 for(
auto it = boundaryIndicators.begin(); it != boundaryIndicators.end();
515 fprintf(fp,
" %d", *it);
517 fprintf(fp,
"\n\n\n");
518 fprintf(fp,
" Nodal coordinates and nodal boundary indicators,\n");
519 fprintf(fp,
" the columns contain:\n");
520 fprintf(fp,
" - node number\n");
521 fprintf(fp,
" - coordinates\n");
522 fprintf(fp,
" - no of boundary indicators that are set (ON)\n");
523 fprintf(fp,
" - the boundary indicators that are set (ON) if any.\n");
527 for(std::size_t i = 0; i < entities.size(); i++) {
528 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++) {
529 MVertex *v = entities[i]->mesh_vertices[j];
532 fprintf(fp,
" [%d] ", (
int)vertexTags[v->
getIndex() - 1].size());
533 for(
auto it = vertexTags[v->
getIndex() - 1].begin();
534 it != vertexTags[v->
getIndex() - 1].end(); it++)
535 fprintf(fp,
" %d ", *it);
543 fprintf(fp,
" Element types and connectivity\n");
544 fprintf(fp,
" the columns contain:\n");
545 fprintf(fp,
" - element number\n");
546 fprintf(fp,
" - element type\n");
547 fprintf(fp,
" - subdomain number \n");
548 fprintf(fp,
" - the global node numbers of the nodes in the element.\n");
553 for(std::size_t i = 0; i < entities.size(); i++) {
554 if(entities[i]->physicals.size() || saveAll) {
555 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
556 MElement *e = entities[i]->getMeshElement(j);
558 if(usePhysicalTags) {
559 for(
auto p : entities[i]->physicals)
563 e->
writeDIFF(fp, ++num, binary, entities[i]->tag());