10 #include "GmshConfig.h"
21 #if defined(COMPRESSED_UNV) && defined(HAVE_LIBZ)
24 #define gmshopen gzopen
25 #define gmshgets(a, b, c) gzgets((c), (a), (b))
26 #define gmshclose gzclose
30 #define gmshopen Fopen
31 #define gmshgets fgets
32 #define gmshclose fclose
40 Msg::Error(
"Unable to open file '%s'", name.c_str());
45 std::map<int, std::vector<MElement *> > elements[7];
46 std::map<int, std::map<int, std::string> > physicals[4];
47 std::map<int, MElement *> elementTags;
49 std::map<int, std::string> groupNames;
53 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
54 if(!strncmp(buffer,
" -1", 6)) {
55 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
56 if(!strncmp(buffer,
" -1", 6))
57 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
59 sscanf(buffer,
"%d", &record);
62 while(
gmshgets(buffer,
sizeof(buffer), fp)) {
63 if(!strncmp(buffer,
" -1", 6))
break;
65 if(sscanf(buffer,
"%d %d %d %d", &num, &dum, &dum, &dum) != 4)
break;
66 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
68 for(std::size_t i = 0; i < strlen(buffer); i++)
69 if(buffer[i] ==
'D') buffer[i] =
'E';
70 if(sscanf(buffer,
"%lf %lf %lf", &x, &y, &
z) != 3)
break;
74 else if(record == 2412) {
76 std::map<int, int> warn;
77 while(
gmshgets(buffer,
sizeof(buffer), fp)) {
78 if(strlen(buffer) < 3)
80 if(!strncmp(buffer,
" -1", 6))
break;
81 int num, type, elementary, physical, color, numNodes;
83 if(sscanf(buffer,
"%d %d %d %d %d %d", &num, &type, &elementary,
84 &physical, &color, &numNodes) != 6)
88 if(sscanf(buffer,
"%d %d %d %d %d %d", &num, &type, &physical,
89 &elementary, &color, &numNodes) != 6)
93 if(physical < 0) physical = 0;
96 Msg::Warning(
"No element type: guessing from number of nodes");
98 case 2: type = 11;
break;
99 case 3: type = 41;
break;
100 case 4: type = 111;
break;
113 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
115 if(sscanf(buffer,
"%d %d %d", &dum, &dum, &dum) != 3)
break;
118 std::vector<MVertex *>
vertices(numNodes);
119 for(
int i = 0; i < numNodes; i++) {
125 if(strlen(buffer) < 10)
130 if(!sscanf(buffer,
"%d", &n)) {
149 elements[0][elementary].push_back(e);
156 elements[0][elementary].push_back(e);
166 elements[1][elementary].push_back(e);
177 elements[1][elementary].push_back(e);
187 elements[2][elementary].push_back(e);
199 elements[2][elementary].push_back(e);
204 elements[3][elementary].push_back(e);
212 elements[3][elementary].push_back(e);
218 elements[4][elementary].push_back(e);
230 elements[4][elementary].push_back(e);
236 elements[5][elementary].push_back(e);
246 elements[5][elementary].push_back(e);
250 if(warn[type]++ == 1)
251 Msg::Warning(
"Skipping unknown type of element %d", type);
255 if(dim >= 0 && physical &&
256 (!physicals[dim].count(elementary) ||
257 !physicals[dim][elementary].count(physical)))
258 physicals[dim][elementary][physical] =
"unnamed";
261 elementTags[num] = e;
262 elementGroups[e].push_back(elementary);
263 elementGroups[e].push_back(physical);
267 else if(record == 2477 || record == 2452 || record == 2435) {
268 if(!readGroupsOfElements) {
269 Msg::Info(
"Ignoring groups (set Mesh.ReadGroupsOfElements to read "
270 "groups of elements)");
274 while(
gmshgets(buffer,
sizeof(buffer), fp)) {
275 if(strlen(buffer) < 3)
277 if(!strncmp(buffer,
" -1", 6))
break;
278 int num, constraint, restraint,
load, dof, temperature, contact, n;
279 if(sscanf(buffer,
"%d %d %d %d %d %d %d %d", &num, &constraint,
280 &restraint, &
load, &dof, &temperature, &contact, &n) != 8)
282 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
284 if(!sscanf(buffer,
"%s", name))
break;
285 groupNames[num] = name;
288 if(!
gmshgets(buffer,
sizeof(buffer), fp))
break;
289 int type, tag, leaf, comp, type2, tag2, leaf2, comp2;
290 int r = sscanf(buffer,
"%d %d %d %d %d %d %d %d", &type, &tag,
291 &leaf, &comp, &type2, &tag2, &leaf2, &comp2);
294 if(type == 8) elementGroups[elementTags[tag]].push_back(num);
298 if(type2 == 8) elementGroups[elementTags[tag2]].push_back(num);
300 if(r != 4 && r != 8)
break;
308 if(groupNames.size()) {
315 std::map<std::vector<int>,
int> entity;
316 std::map<int, std::vector<MElement *> > elementsNew[7];
319 for(
auto g : groupNames) maxgroup = std::max(g.first, maxgroup);
321 for(
auto &it : elementGroups) {
324 int elementaryNew = 0;
325 auto ent = entity.find(it.second);
326 if(ent == entity.end()) {
327 elementaryNew = entity.size() + 1;
328 entity[it.second] = elementaryNew;
331 elementaryNew = ent->second;
341 elementsNew[k][elementaryNew].push_back(e);
342 if(it.second.size() > 2) {
344 for(std::size_t g = 2; g < it.second.size(); g++) {
345 int physicalNew = it.second[g];
346 if(!physicals[dim].count(elementaryNew) ||
347 !physicals[dim][elementaryNew].count(physicalNew))
348 physicals[dim][elementaryNew][physicalNew] =
349 groupNames[physicalNew];
352 else if(it.second.size() > 1) {
354 it.second[0] : it.second[1];
358 if(groupNames.count(physicalNew)) physicalNew += maxgroup;
359 if(!physicals[dim].count(elementaryNew) ||
360 !physicals[dim][elementaryNew].count(physicalNew))
361 physicals[dim][elementaryNew][physicalNew] =
"unnamed";
366 for(
int i = 0; i < (int)(
sizeof(elements) /
sizeof(elements[0])); i++)
367 elements[i] = elementsNew[i];
370 for(
int i = 0; i < (int)(
sizeof(elements) /
sizeof(elements[0])); i++)
387 (dim == 3) ?
"PhysicalVolume" :
388 (dim == 2) ?
"PhysicalSurface" :
393 for(std::size_t i = 0; i < name.size(); i++)
394 if(name[i] ==
' ') name[i] =
'_';
399 int saveGroupsOfElements,
int saveGroupsOfNodes,
400 double scalingFactor)
402 FILE *fp =
Fopen(name.c_str(),
"w");
404 Msg::Error(
"Unable to open file '%s'", name.c_str());
412 std::vector<GEntity *> entities;
416 fprintf(fp,
"%6d\n", -1);
417 fprintf(fp,
"%6d\n", 2411);
418 for(std::size_t i = 0; i < entities.size(); i++)
419 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
420 entities[i]->mesh_vertices[j]->
writeUNV(
423 fprintf(fp,
"%6d\n", -1);
426 fprintf(fp,
"%6d\n", -1);
427 fprintf(fp,
"%6d\n", 2412);
428 for(std::size_t i = 0; i < entities.size(); i++) {
429 if(saveAll || entities[i]->physicals.size()) {
430 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
431 MElement *e = entities[i]->getMeshElement(j);
436 fprintf(fp,
"%6d\n", -1);
442 if(saveGroupsOfNodes || saveGroupsOfElements) {
443 std::map<int, std::vector<GEntity *> > groups[4];
446 fprintf(fp,
"%6d\n", -1);
447 fprintf(fp,
"%6d\n", 2477);
448 for(
int dim = 0; dim <= 3; dim++) {
450 (saveGroupsOfNodes > 0 ||
451 (saveGroupsOfNodes < 0 &&
452 ((-saveGroupsOfNodes / (int)std::pow(10, dim)) % 10) == 1));
454 (saveGroupsOfElements > 0 ||
455 (saveGroupsOfElements < 0 &&
456 ((-saveGroupsOfElements / (int)std::pow(10, dim)) % 10) == 1));
458 for(
auto it = groups[dim].begin(); it != groups[dim].end(); it++) {
459 std::vector<GEntity *> &entities = it->second;
461 std::set<MVertex *, MVertexPtrLessThan> nodes;
463 for(std::size_t i = 0; i < entities.size(); i++) {
464 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
465 MElement *e = entities[i]->getMeshElement(j);
474 for(std::size_t i = 0; i < entities.size(); i++)
478 fprintf(fp,
"%10d%10d%10d%10d%10d%10d%10d%10d\n", it->first, 0, 0, 0, 0,
479 0, 0, (
int)nodes.size() + nele);
480 fprintf(fp,
"%s\n",
physicalName(
this, dim, it->first).c_str());
484 for(
auto it2 = nodes.begin(); it2 != nodes.end(); it2++) {
489 fprintf(fp,
"%10d%10ld%10d%10d", 7, (*it2)->getIndex(), 0, 0);
503 for(std::size_t i = 0; i < entities.size(); i++) {
504 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
505 MElement *e = entities[i]->getMeshElement(j);
510 fprintf(fp,
"%10d%10lu%10d%10d", 8, e->
getNum(), 0, 0);
518 if(row == 1) { fprintf(fp,
"\n"); }
522 fprintf(fp,
"%6d\n", -1);