Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/Application/plugins/egmain.cpp
3203 views
1
/*
2
ElmerGrid - A simple mesh generation and manipulation utility
3
Copyright (C) 1995- , CSC - IT Center for Science Ltd.
4
5
Author: Peter Raback
6
Email: [email protected]
7
Address: CSC - IT Center for Science Ltd.
8
Keilaranta 14
9
02101 Espoo, Finland
10
11
This program is free software; you can redistribute it and/or
12
modify it under the terms of the GNU General Public License
13
as published by the Free Software Foundation; either version 2
14
of the License, or (at your option) any later version.
15
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
GNU General Public License for more details.
20
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software
23
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
*/
25
26
/****************************************************************************
27
* *
28
* Elmergrid *
29
* *
30
* This program creates very easily a structured 2D meshes with BCs. *
31
* The element types include 4, 5, 8, 9, 12 and 16-node rectangles and *
32
* 3, 6 and 10-node triangles. There is also limited 3D functionality *
33
* with 8, 20 and 27-node cubes and 6-node prisms. *
34
* *
35
* The program may also be used as a mesh import and export utility. It *
36
* is able to read several different formats and writes mainly Elmer input *
37
* and output formats. The meshes may also be given some simple operations. *
38
* *
39
* Note: this software was initially part of my first fem implementation *
40
* the Pirfem code, then later called Quickmesh, and finally renamed to *
41
* Elmergrid. The code has never been designed and with new features the *
42
* code has eventually become very dirty and does not present my view of *
43
* good programming. *
44
* *
45
****************************************************************************/
46
47
48
#include <stdio.h>
49
#include <stddef.h>
50
#include <stdlib.h>
51
#include <string.h>
52
#include <ctype.h>
53
#include <math.h>
54
#include <locale.h>
55
56
#define EXE_MODE 0
57
#define LIB_MODE 1
58
59
60
#include "egutils.h"
61
#include "egdef.h"
62
#include "egtypes.h"
63
#include "egmesh.h"
64
#include "egnative.h"
65
#include "egconvert.h"
66
67
68
#if EXE_MODE
69
#include "egoutput.h"
70
#else
71
#include "src/meshtype.h"
72
#endif
73
74
75
static struct GridType *grids;
76
static struct FemType data[MAXCASES];
77
static struct BoundaryType *boundaries[MAXCASES];
78
static struct ElmergridType eg;
79
static char Filename[MAXFILESIZE];
80
static int Inmethod;
81
82
83
int info=TRUE,nogrids=0,nomeshes=0,activemesh=0;
84
85
#if EXE_MODE
86
static int PartitionMesh(int nofile)
87
{
88
/* Partitioning related stuff */
89
90
int noopt = 0;
91
92
if(eg.partitions) {
93
if(eg.partopt % 2 == 0)
94
PartitionSimpleElements(&data[nofile],eg.partdim,eg.periodicdim,eg.partorder,eg.partcorder,info);
95
else
96
PartitionSimpleNodes(&data[nofile],eg.partdim,eg.periodicdim,eg.partorder,eg.partcorder,info);
97
noopt = eg.partopt / 2;
98
}
99
#if HAVE_METIS
100
if(eg.metis) {
101
if(eg.partopt % 5 <= 1)
102
PartitionMetisElements(&data[nofile],eg.metis,eg.partopt % 5,info);
103
else
104
PartitionMetisNodes(&data[nofile],eg.metis,eg.partopt % 5,info);
105
noopt = eg.partopt / 5;
106
}
107
#endif
108
if(eg.partitions || eg.metis )
109
OptimizePartitioning(&data[nofile],boundaries[nofile],noopt,info);
110
}
111
112
113
114
static int ExportMeshDefinition(int inmethod,int outmethod,int nofile,char *filename)
115
{
116
int i;
117
118
switch (outmethod) {
119
case 1:
120
SaveElmergrid(grids,nogrids,filename,info);
121
break;
122
123
case 2:
124
if(data[nofile].nopartitions > 1)
125
SaveElmerInputPartitioned(&data[nofile],boundaries[nofile],filename,eg.decimals,
126
eg.partitionhalo,eg.partitionindirect,info);
127
else
128
SaveElmerInput(&data[nofile],boundaries[nofile],filename,eg.decimals,info);
129
break;
130
131
case 22:
132
SaveElmerInputFemBem(&data[nofile],boundaries[nofile],filename,eg.decimals,info);
133
break;
134
135
case 3:
136
/* Create a variable so that when saving data in ElmerPost format there is something to visualize */
137
if(data[nofile].variables == 0) {
138
CreateVariable(&data[nofile],1,1,0.0,"Number",FALSE);
139
for(i=1;i<=data[nofile].alldofs[1];i++)
140
data[nofile].dofs[1][i] = (Real)(i);
141
}
142
SaveSolutionElmer(&data[nofile],boundaries[nofile],eg.saveboundaries ? MAXBOUNDARIES:0,
143
filename,eg.decimals,info=TRUE);
144
break;
145
146
default:
147
Instructions();
148
break;
149
}
150
Goodbye();
151
}
152
153
154
#else
155
156
157
int ConvertEgTypeToMeshType(struct FemType *dat,struct BoundaryType *bound,mesh_t *mesh)
158
{
159
int i,j,k,allocated,surfaces,elemdim;
160
int sideelemtype,ind[MAXNODESD1];
161
162
node_t *n;
163
surface_t *b;
164
element_t *e;
165
edge_t *s;
166
167
if(!dat->created) {
168
printf("Data is not created!\n");
169
return(1);
170
}
171
172
printf("Converting ElmerGrid data to ElmerGUI data\n");
173
174
elemdim = GetMaxElementDimension(dat);
175
printf("Setting elements of %ddim\n",elemdim);
176
177
/* for mapped surfaces elemdim and space dimension may differ! */
178
mesh->setDim(MAX(data->dim, elemdim));
179
mesh->setNodes(dat->noknots);
180
mesh->newNodeArray(mesh->getNodes());
181
182
printf("Setting number of nodes %d\n",mesh->getNodes());
183
for(i=0; i < mesh->getNodes(); i++) {
184
n = mesh->getNode(i);
185
n->setX(0, dat->x[i+1]);
186
n->setX(1, dat->y[i+1]);
187
n->setX(2, dat->z[i+1]);
188
n->setIndex(-1);
189
}
190
191
/* For 3D save bulk elements & boundary elements */
192
if(elemdim == 3) {
193
194
mesh->setElements(dat->noelements);
195
mesh->newElementArray(mesh->getElements());
196
197
printf("Setting number of 3d elements %d\n",mesh->getElements());
198
for(i = 0; i < mesh->getElements(); i++) {
199
e = mesh->getElement(i);
200
e->setCode(dat->elementtypes[i+1]);
201
e->setNodes(e->getCode() % 100);
202
e->newNodeIndexes(e->getNodes());
203
e->setNature(PDE_BULK);
204
205
for(j = 0; j < e->getNodes(); j++)
206
e->setNodeIndex(j, dat->topology[i+1][j]-1);
207
e->setIndex(dat->material[i+1]);
208
}
209
210
211
if(eg.saveboundaries) {
212
213
allocated = FALSE;
214
do_b: surfaces = 0;
215
216
217
for(j=0;j<MAXBOUNDARIES;j++) {
218
if(bound[j].created == FALSE) continue;
219
220
for(i=1;i<=bound[j].nosides;i++) {
221
GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],dat,ind,&sideelemtype);
222
223
if(sideelemtype / 100 < 3 || sideelemtype / 100 > 4) continue;
224
surfaces += 1;
225
226
if(allocated) {
227
b = mesh->getSurface(surfaces-1);
228
b->setElements(0);
229
b->newElementIndexes(2);
230
231
if(bound[j].parent[i]) {
232
b->setElements(b->getElements() + 1);
233
b->setElementIndex(0, bound[j].parent[i]-1);
234
}
235
else {
236
b->setElementIndex(0, -1);
237
}
238
239
if(bound[j].parent2[i]) {
240
b->setElements(b->getElements() + 1);
241
b->setElementIndex(1, bound[j].parent2[i]-1);
242
}
243
else {
244
b->setElementIndex(1, -1);
245
}
246
247
b->setNormal(0, 0.0);
248
b->setNormal(1, 0.0);
249
b->setNormal(2, -1.0);
250
251
b->setNature(PDE_BOUNDARY);
252
b->setCode(sideelemtype);
253
b->setNodes(b->getCode() % 100);
254
b->newNodeIndexes(b->getNodes());
255
for(k = 0; k < b->getNodes(); k++)
256
b->setNodeIndex(k, ind[k]-1);
257
b->setIndex(bound[j].types[i]);
258
259
b->setEdges(b->getNodes());
260
b->newEdgeIndexes(b->getEdges());
261
for(k=0; k < b->getEdges(); k++)
262
b->setEdgeIndex(k, -1);
263
}
264
}
265
}
266
267
if(!allocated) {
268
mesh->setSurfaces(surfaces);
269
mesh->newSurfaceArray(mesh->getSurfaces());
270
allocated = TRUE;
271
goto do_b;
272
}
273
}
274
}
275
276
else if(elemdim == 2) {
277
mesh->setElements(0);
278
279
mesh->setSurfaces(dat->noelements);
280
mesh->newSurfaceArray(mesh->getSurfaces());
281
282
printf("Setting number of 2d elements %d\n",mesh->getSurfaces());
283
for(i = 0; i < mesh->getSurfaces(); i++) {
284
b = mesh->getSurface(i);
285
286
b->setElements(0);
287
b->newElementIndexes(2);
288
b->setElementIndex(0, -1);
289
b->setElementIndex(1, -1);
290
291
b->setNormal(0, 0.0);
292
b->setNormal(1, 0.0);
293
b->setNormal(2, -1.0);
294
295
b->setCode(dat->elementtypes[i+1]);
296
b->setNodes(b->getCode() % 100);
297
b->newNodeIndexes(b->getNodes());
298
b->setNature(PDE_BULK);
299
300
for(j = 0; j < b->getNodes(); j++)
301
b->setNodeIndex(j, dat->topology[i+1][j]-1);
302
b->setIndex(dat->material[i+1]);
303
304
b->setEdges(b->getNodes());
305
b->newEdgeIndexes(b->getEdges());
306
for(k=0; k < b->getEdges(); k++)
307
b->setEdgeIndex(k, -1);
308
}
309
310
allocated = FALSE;
311
do_s: surfaces = 0;
312
313
for(j=0;j<MAXBOUNDARIES;j++) {
314
if(bound[j].created == FALSE) continue;
315
316
for(i=1;i<=bound[j].nosides;i++) {
317
GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],dat,ind,&sideelemtype);
318
319
if(sideelemtype / 100 != 2) continue;
320
surfaces += 1;
321
322
if(allocated) {
323
s = mesh->getEdge(surfaces-1);
324
s->setSurfaces(0);
325
s->newSurfaceIndexes(2);
326
327
if(bound[j].parent[i]) {
328
s->setSurfaces(s->getSurfaces() + 1);
329
s->setSurfaceIndex(0, bound[j].parent[i]-1);
330
}
331
else {
332
s->setSurfaceIndex(0, -1);
333
}
334
if(bound[j].parent2[i]) {
335
s->setSurfaces(s->getSurfaces() + 1);
336
s->setSurfaceIndex(1, bound[j].parent2[i]-1);
337
}
338
else {
339
s->setSurfaceIndex(1, -1);
340
}
341
s->setCode(sideelemtype);
342
s->setNodes(s->getCode() % 100);
343
s->newNodeIndexes(s->getNodes());
344
s->setNature(PDE_BOUNDARY);
345
346
for(k = 0; k < s->getNodes(); k++)
347
s->setNodeIndex(k, ind[k]-1);
348
s->setIndex(bound[j].types[i]);
349
}
350
}
351
}
352
353
if(!allocated) {
354
mesh->setEdges(surfaces);
355
mesh->newEdgeArray(mesh->getEdges());
356
allocated = TRUE;
357
goto do_s;
358
}
359
}
360
else {
361
printf("Implemented only for element dimensions 2 and 3 (not %d)\n",elemdim);
362
}
363
364
printf("Done converting mesh\n");
365
366
return(0);
367
}
368
#endif
369
370
371
static int DetermineFileType(const char *filename,int info)
372
{
373
int mode;
374
mode = -1;
375
376
if(!strstr(filename,".")) {
377
if(info) printf("There cannot be a filetype suffix without a dot: %s\n",filename);
378
return(mode);
379
}
380
else {
381
if(strstr(filename,".eg")) mode = 0;
382
else if(strstr(filename,".grd")) mode = 1;
383
else if(strstr(filename,".ep")) mode = 3;
384
else if(strstr(filename,".inp")) mode = 5;
385
else if(strstr(filename,".nas")) mode = 6;
386
else if(strstr(filename,".fdneut") || strstr(filename,".FDNEUT")) mode = 7;
387
else if(strstr(filename,".unv")) mode = 8;
388
else if(strstr(filename,".mphtxt")) mode = 9;
389
else if(strstr(filename,".msh")) mode = 14;
390
else if(strstr(filename,".plt")) mode = 16;
391
}
392
if(mode == -1) {
393
if(info) printf("Could not determine the filetype based on the suffix\n");
394
}
395
396
if(info) printf("Filetype determined by suffix: %d\n",mode);
397
398
return(mode);
399
}
400
401
402
403
static int ImportMeshDefinition(int inmethod,int nofile,char *filename,int *nogrids)
404
{
405
int i,k,errorstat = 0,dim;
406
static int visited = FALSE;
407
408
409
*nogrids = 0;
410
if(!visited) {
411
printf("Initializing structures for max. %d meshes\n",MAXCASES);
412
for(k=0;k<MAXCASES;k++) {
413
boundaries[k] = (struct BoundaryType*)
414
malloc((size_t) (MAXBOUNDARIES)*sizeof(struct BoundaryType));
415
for(i=0;i<MAXBOUNDARIES;i++) {
416
boundaries[k][i].created = FALSE;
417
boundaries[k][i].nosides = 0;
418
}
419
}
420
for(k=0;k<MAXCASES;k++) data[k].created=FALSE;
421
422
visited = TRUE;
423
}
424
425
/* Native format of ElmerGrid gets special treatment */
426
switch (inmethod) {
427
428
case 1:
429
printf("Loading ElmerGrid format file\n");
430
info = TRUE;
431
errorstat = LoadElmergrid(&grids,nogrids,eg.filesin[nofile],info);
432
if(errorstat == 1) {
433
dim = eg.dim;
434
CreateExampleGrid(dim,&grids,nogrids,info);
435
SaveElmergrid(grids,*nogrids,eg.filesin[nofile],info);
436
printf("Because file %s didn't exist, it was created for you.\n",eg.filesin[nofile]);
437
return(errorstat);
438
}
439
if(*nogrids) LoadCommands(eg.filesin[nofile],&eg,grids,2,info);
440
break;
441
442
#if EXE_MODE
443
case 2:
444
errorstat = LoadElmerInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
445
break;
446
447
case 3:
448
errorstat = LoadSolutionElmer(&(data[nofile]),TRUE,eg.filesin[nofile],info);
449
break;
450
#endif
451
452
case 4:
453
errorstat = LoadAnsysInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
454
break;
455
456
case 5:
457
errorstat = LoadAbaqusInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
458
break;
459
460
case 6:
461
errorstat = LoadNastranInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
462
break;
463
464
case 7:
465
errorstat = LoadFidapInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
466
eg.bulkorder = TRUE;
467
eg.boundorder = TRUE;
468
break;
469
470
case 8:
471
errorstat = LoadUniversalMesh(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
472
break;
473
474
case 9:
475
errorstat = LoadComsolMesh(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
476
break;
477
478
case 10:
479
errorstat = LoadFieldviewInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
480
break;
481
482
case 11:
483
errorstat = LoadTriangleInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
484
break;
485
486
case 12:
487
errorstat = LoadMeditInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
488
break;
489
490
case 13:
491
errorstat = LoadGidInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
492
break;
493
494
case 14:
495
data[nofile].dim = 3; /* default dim 3 with gmsh*/
496
eg.dim = 3;
497
errorstat = LoadGmshInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],
498
eg.multidim,eg.dim,info);
499
break;
500
501
502
case 16:
503
errorstat = LoadCGsimMesh(&(data[nofile]),eg.filesin[nofile],info);
504
break;
505
506
#if EXE_MODE
507
case 15:
508
if(info) printf("Partitioned solution is fused on-the-fly therefore no other operations may be performed.\n");
509
FuseSolutionElmerPartitioned(eg.filesin[nofile],eg.filesout[nofile],eg.decimals,
510
eg.saveinterval[0],eg.saveinterval[1],eg.saveinterval[2],info);
511
if(info) printf("Finishing with the fusion of partitioned Elmer solutions\n");
512
Goodbye();
513
break;
514
515
default:
516
errorstat = 1;
517
Instructions();
518
#endif
519
520
}
521
522
#if LIB_MODE
523
/* ElmerGrid cannot deal with three different dimensions or orphan nodes */
524
eg.removelowdim = TRUE;
525
eg.removeunused = TRUE;
526
#endif
527
528
if(!errorstat) *nogrids = MAX(*nogrids,1);
529
530
return(errorstat);
531
}
532
533
534
535
536
537
static int ManipulateMeshDefinition(int inmethod,int outmethod,Real relh)
538
{
539
static int visited = FALSE;
540
int i,j,k;
541
Real mergeeps;
542
543
printf("Manipulate mesh definition with formats: %d %d\n",inmethod,outmethod);
544
545
if(inmethod == 1 && outmethod != 1) {
546
if(visited) {
547
printf("Deallocating structures from previous call\n");
548
for(k=0;k<MAXCASES;k++) {
549
if(data[k].created) {
550
DestroyKnots(&data[k]);
551
for(i=0;i<MAXBOUNDARIES;i++) {
552
DestroyBoundary(&boundaries[k][i]);
553
}
554
}
555
}
556
}
557
printf("Starting to create ElmerGrid meshes\n");
558
for(k=0;k<nogrids;k++)
559
CreateElmerGridMesh(&(grids[k]),&(data[k]),boundaries[k],relh,info);
560
nomeshes = nogrids;
561
printf("Created %d ElmerGrid meshes\n",nomeshes);
562
563
/* Cancel the automatic effect of -autoclean flag for this input format */
564
eg.bulkorder = FALSE;
565
eg.boundorder = FALSE;
566
}
567
568
visited = TRUE;
569
570
/* At first instance perform operations that should rather be done before extrusion
571
or mesh union. */
572
for(k=0;k<nomeshes;k++) {
573
574
/* Make the discontinuous boundary needed, for example, in poor thermal conduction */
575
if(!eg.discont) {
576
for(j=0;j<grids[k].noboundaries;j++)
577
if(grids[k].boundsolid[j] == 2) {
578
eg.discontbounds[eg.discont] = grids[k].boundtype[j];
579
eg.discont++;
580
}
581
}
582
if(eg.discont) {
583
for(i=1;i<=eg.discont;i++)
584
SetDiscontinuousBoundary(&(data[k]),boundaries[k],eg.discontbounds[i-1],2,info);
585
}
586
587
/* Make a connected boundary (specific to Elmer format) needed in linear constraints */
588
/* No longer needed in serial at least!! */
589
/* for(i=1;i<=eg.connect;i++)
590
SetConnectedBoundary(&(data[k]),boundaries[k],eg.connectbounds[i-1],i,info); */
591
592
/* Divide quadrilateral meshes into triangular meshes */
593
if(eg.triangles || grids[k].triangles == TRUE) {
594
Real criticalangle;
595
criticalangle = MAX(eg.triangleangle, grids[k].triangleangle);
596
ElementsToTriangles(&data[k],boundaries[k],criticalangle,info);
597
}
598
599
/* Make a boundary layer with two different methods */
600
if(eg.layers > 0)
601
CreateBoundaryLayer(&data[k],boundaries[k],eg.layers,
602
eg.layerbounds, eg.layernumber, eg.layerratios, eg.layerthickness,
603
eg.layerparents, eg.layermove, eg.layereps, info);
604
else if(eg.layers < 0)
605
CreateBoundaryLayerDivide(&data[k],boundaries[k],abs(eg.layers),
606
eg.layerbounds, eg.layernumber, eg.layerratios, eg.layerthickness,
607
eg.layerparents, info);
608
}
609
610
/* Take up the infor on rotation */
611
for(k=0;k<nogrids;k++)
612
if( grids[k].rotatecurve ) {
613
eg.rotatecurve = TRUE;
614
eg.curvezet = grids[k].curvezet;
615
eg.curverad = grids[k].curverad;
616
eg.curveangle = grids[k].curveangle;
617
}
618
619
if(outmethod != 1 && eg.dim != 2) {
620
j = MAX(1,nogrids);
621
for(k=0;k<j;k++) {
622
if(grids[k].dimension == 3 || grids[k].rotate) {
623
CreateKnotsExtruded(&(data[k]),boundaries[k],&(grids[k]),
624
&(data[j]),boundaries[j],info);
625
#if LIB_MODE
626
activemesh = j;
627
nomeshes = j+1;
628
#endif
629
#if EXE_MODE
630
data[k] = data[j];
631
boundaries[k] = boundaries[j];
632
#endif
633
}
634
}
635
}
636
637
638
/* Unite meshes if there are several of them */
639
if(eg.unitemeshes) {
640
for(k=1;k<nomeshes;k++)
641
UniteMeshes(&data[0],&data[k],boundaries[0],boundaries[k],eg.unitenooverlap,info);
642
nomeshes = 1;
643
}
644
645
646
for(k=0;k<nomeshes;k++) {
647
648
/* If the original mesh was given in polar coordinates make the transformation into cartesian ones */
649
if(eg.polar || data[k].coordsystem == COORD_POLAR) {
650
if(!eg.polar) eg.polarradius = grids[k].polarradius;
651
PolarCoordinates(&data[k],eg.polarradius,info);
652
}
653
/* If the original mesh was given in cylindrical coordinates make the transformation into cartesian ones */
654
if(eg.cylinder || data[k].coordsystem == COORD_CYL) {
655
CylinderCoordinates(&data[k],info);
656
}
657
if(eg.clone[0] || eg.clone[1] || eg.clone[2]) {
658
CloneMeshes(&data[k],boundaries[k],eg.clone,eg.clonesize,FALSE,info);
659
mergeeps = fabs(eg.clonesize[0]+eg.clonesize[1]+eg.clonesize[2]) * 1.0e-8;
660
MergeElements(&data[k],boundaries[k],eg.order,eg.corder,mergeeps,TRUE,TRUE);
661
}
662
663
/* Reduce element order if requested */
664
if(nogrids && grids[k].reduceordermatmax) {
665
eg.reduce = TRUE;
666
eg.reducemat1 = grids[k].reduceordermatmin;
667
eg.reducemat2 = grids[k].reduceordermatmax;
668
}
669
if(eg.reduce)
670
ReduceElementOrder(&data[k],eg.reducemat1,eg.reducemat2);
671
672
/* Increase element order */
673
if(eg.increase)
674
IncreaseElementOrder(&data[k],TRUE);
675
676
if(eg.merge)
677
MergeElements(&data[k],boundaries[k],eg.order,eg.corder,eg.cmerge,FALSE,TRUE);
678
#if HAVE_METIS
679
else if(eg.order == 3)
680
ReorderElementsMetis(&data[k],TRUE);
681
#endif
682
else if(eg.order)
683
ReorderElements(&data[k],boundaries[k],eg.order,eg.corder,TRUE);
684
685
if(eg.bulkbounds || eg.boundbounds)
686
SideAndBulkBoundaries(&data[k],boundaries[k],&eg,info);
687
688
RotateTranslateScale(&data[k],&eg,info);
689
690
if(eg.rotatecurve)
691
CylindricalCoordinateCurve(&data[k],eg.curvezet,eg.curverad,eg.curveangle);
692
693
if(eg.removelowdim)
694
RemoveLowerDimensionalBoundaries(&data[k],boundaries[k],info);
695
696
if(eg.removeunused)
697
RemoveUnusedNodes(&data[k],info);
698
699
if(eg.sidemappings || eg.bulkmappings)
700
SideAndBulkMappings(&data[k],boundaries[k],&eg,info);
701
702
if(eg.boundorder || eg.bcoffset)
703
RenumberBoundaryTypes(&data[k],boundaries[k],eg.boundorder,eg.bcoffset,info);
704
705
if(eg.bulkorder)
706
RenumberMaterialTypes(&data[k],boundaries[k],info);
707
708
if(eg.periodicdim[0] || eg.periodicdim[1] || eg.periodicdim[2])
709
FindPeriodicNodes(&data[k],eg.periodicdim,info);
710
}
711
return 0;
712
}
713
714
715
716
717
#if LIB_MODE
718
int eg_loadmesh(const char *filename)
719
{
720
static int inmethod,errorstat,info;
721
722
setlocale(LC_ALL, "C");
723
724
strcpy(Filename,filename);
725
info = TRUE;
726
if(info) printf("\nElmerGrid checking filename suffix for file: %s\n",filename);
727
728
inmethod = DetermineFileType(filename,info);
729
Inmethod = inmethod;
730
731
if(inmethod < 0)
732
errorstat = 1;
733
else
734
errorstat = 0;
735
736
if(info) printf("Initialized the filetype\n");
737
return(errorstat);
738
}
739
740
741
742
int eg_transfermesh(mesh_t *mesh,const char *str)
743
{
744
int i,k,inmethod,outmethod,errorstat,nofile;
745
info = TRUE;
746
static char arguments[10][15],**argv;
747
int argc;
748
static int visited = FALSE;
749
char filename[MAXFILESIZE];
750
751
setlocale(LC_ALL, "C");
752
753
activemesh = 0;
754
nofile = 0;
755
nomeshes = 0;
756
nogrids = 0;
757
info = TRUE;
758
759
if(!visited) {
760
grids = (struct GridType*)malloc((size_t) (MAXCASES)*sizeof(struct GridType));
761
argv = (char**) malloc((size_t) 10*sizeof(char*));
762
}
763
visited++;
764
765
InitParameters(&eg);
766
InitGrid(grids);
767
768
strcpy(filename,Filename);
769
if(info) printf("\nElmerGrid loading data from file: %s\n",filename);
770
771
inmethod = Inmethod;
772
if(inmethod < 0) return(1);
773
774
if(inmethod == 0) {
775
errorstat = LoadCommands(filename,&eg,grids,1,info);
776
inmethod = eg.inmethod;
777
info = !eg.silent;
778
}
779
else {
780
eg.inmethod = inmethod;
781
}
782
strcpy(eg.filesin[0],filename);
783
784
printf("Import mesh definition\n");
785
errorstat = ImportMeshDefinition(inmethod,nofile,filename,&nogrids);
786
787
if(errorstat) return(errorstat);
788
nomeshes += nogrids;
789
790
if(info) printf("\nElmerGrid manipulating and importing data\n");
791
792
mesh->setNodes(0);
793
mesh->setPoints(0);
794
mesh->setEdges(0);
795
mesh->setSurfaces(0);
796
mesh->setElements(0);
797
798
if(nomeshes == 0) {
799
printf("No mesh to work with!\n");
800
return(1);
801
}
802
803
/* Checking in-line parameters */
804
argc = StringToStrings(str,arguments,10,' ');
805
for(i=0;i<argc;i++) argv[i] = &arguments[i][0];
806
807
printf("Number of inline arguments: %d\n",argc);
808
809
errorstat = InlineParameters(&eg,argc,argv,0,info);
810
if(errorstat) printf("Errorstat for inline parameters: %d\n",errorstat);
811
812
inmethod = eg.inmethod;
813
outmethod = 0;
814
815
printf("Input method: %d\n",inmethod);
816
817
ManipulateMeshDefinition(inmethod,outmethod,eg.relh);
818
819
errorstat = ConvertEgTypeToMeshType(&data[activemesh],boundaries[activemesh],mesh);
820
return(errorstat);
821
822
for(k=0;k<MAXCASES;k++) {
823
DestroyKnots(&data[k]);
824
for(i=0;i<MAXBOUNDARIES;i++)
825
DestroyBoundary(&boundaries[k][i]);
826
}
827
if(info) printf("Done destroying structures\n");
828
}
829
830
831
#if 0
832
int main(int argc, char *argv[])
833
{
834
char prefix[MAXFILESIZE];
835
class mesh_t mesh;
836
837
eg_loadmesh("apu.grd");
838
eg_transfermesh("test",&mesh);
839
}
840
#endif
841
#endif
842
843
844
#if EXE_MODE
845
int main(int argc, char *argv[])
846
{
847
char prefix[MAXFILESIZE],filename[MAXFILESIZE];
848
Real relh;
849
static int i,j,k,l,inmethod,outmethod,errorstat;
850
static int nofile,dim;
851
static Real mergeeps;
852
long ii;
853
854
if(info) printf("\nStarting program Elmergrid, compiled on %s\n", __DATE__ );
855
856
InitParameters(&eg);
857
grids = (struct GridType*)malloc((size_t) (MAXCASES)*sizeof(struct GridType));
858
InitGrid(grids);
859
info = TRUE;
860
861
if(argc <= 2) {
862
errorstat = LoadCommands(argv[1],&eg,grids,argc-1,info);
863
if(errorstat) {
864
if(argc <= 1) Instructions();
865
Goodbye();
866
}
867
}
868
else if(argc == 3) {
869
Instructions();
870
Goodbye();
871
}
872
else {
873
errorstat = InlineParameters(&eg,argc,argv,4,info);
874
if(errorstat) Goodbye();
875
}
876
inmethod = eg.inmethod;
877
outmethod = eg.outmethod;
878
info = !eg.silent;
879
dim = eg.dim;
880
relh = eg.relh;
881
if(!outmethod || !inmethod) {
882
printf("Please define the input and output formats\n");
883
Goodbye();
884
}
885
886
/**********************************/
887
if(info) printf("\nElmergrid loading data:\n");
888
889
nofile = 0;
890
nomeshes = 0;
891
nogrids = 0;
892
893
for(nofile=0;nofile<eg.nofilesin;nofile++) {
894
errorstat = ImportMeshDefinition(inmethod,nofile,eg.filesin[nofile],&nogrids);
895
if(errorstat) Goodbye();
896
nomeshes += nogrids;
897
}
898
899
/***********************************/
900
if(info) printf("\nElmergrid creating and manipulating meshes:\n");
901
ManipulateMeshDefinition(inmethod,outmethod,relh);
902
903
/* Partitioning related stuff */
904
for(k=0;k<nomeshes;k++)
905
PartitionMesh(nofile);
906
907
/********************************/
908
if(info) printf("\nElmergrid saving data:\n");
909
sprintf(prefix,"%s",eg.filesout[0]);
910
for(nofile=0;nofile<nomeshes;nofile++) {
911
if(nomeshes == 1)
912
sprintf(filename,"%s",prefix);
913
else
914
sprintf(filename,"%s%d",prefix,nofile+1);
915
ExportMeshDefinition(inmethod,outmethod,nofile,filename);
916
}
917
Goodbye();
918
}
919
#endif
920
921
922
923
924