Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/Application/plugins/egconvert.cpp
5179 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
/* --------------------: egconvert.c :-------------------------- */
27
28
#include <stdio.h>
29
#include <math.h>
30
#include <stdarg.h>
31
#include <stdlib.h>
32
#include <ctype.h>
33
#include <string.h>
34
#include <limits.h>
35
36
#include "egutils.h"
37
#include "egdef.h"
38
#include "egtypes.h"
39
#include "egmesh.h"
40
#include "egconvert.h"
41
42
#define GETLINE (ioptr=fgets(line,MAXLINESIZE,in))
43
#define GETLONGLINE (ioptr=fgets(longline,LONGLINESIZE,in))
44
45
static int linenumber;
46
static char *ioptr;
47
48
static int Getrow(char *line1,FILE *io,int upper)
49
{
50
int i,isend;
51
char line0[MAXLINESIZE],*charend;
52
53
for(i=0;i<MAXLINESIZE;i++)
54
line0[i] = ' ';
55
56
newline:
57
charend = fgets(line0,MAXLINESIZE,io);
58
linenumber += 1;
59
60
isend = (charend == NULL);
61
62
if(isend) return(1);
63
64
if(line0[0] == '#' || line0[0] == '!') goto newline;
65
if(strstr(line0,"#")) goto newline;
66
67
if(upper) {
68
for(i=0;i<MAXLINESIZE;i++)
69
line1[i] = toupper(line0[i]);
70
}
71
else {
72
for(i=0;i<MAXLINESIZE;i++)
73
line1[i] = line0[i];
74
}
75
76
return(0);
77
}
78
79
static int GetrowDouble(char *line1,FILE *io)
80
{
81
int i,isend;
82
char line0[MAXLINESIZE],*charend;
83
84
for(i=0;i<MAXLINESIZE;i++)
85
line0[i] = ' ';
86
87
newline:
88
charend = fgets(line0,MAXLINESIZE,io);
89
linenumber += 1;
90
91
isend = (charend == NULL);
92
93
if(isend) return(1);
94
95
if(line0[0] == '#' || line0[0] == '!') goto newline;
96
if(strstr(line0,"#")) goto newline;
97
98
for(i=0;i<MAXLINESIZE;i++) {
99
100
/* The Fortran double is not recognized by C string operators */
101
if( line0[i] == 'd' || line0[i] == 'D' ) {
102
line1[i] = 'e';
103
} else {
104
line1[i] = line0[i];
105
}
106
}
107
108
return(0);
109
}
110
111
112
static int Comsolrow(char *line1,FILE *io)
113
{
114
int i,isend;
115
char line0[MAXLINESIZE],*charend;
116
117
for(i=0;i<MAXLINESIZE;i++)
118
line0[i] = ' ';
119
120
charend = fgets(line0,MAXLINESIZE,io);
121
linenumber += 1;
122
123
isend = (charend == NULL);
124
125
if(isend) return(1);
126
127
for(i=0;i<MAXLINESIZE;i++) line1[i] = line0[i];
128
129
return(0);
130
}
131
132
static int LinearNodes(int elemtype)
133
{
134
int elemfamily,nonodes;
135
int fam2nodemap[] = {0, 1, 2, 3, 4, 4, 5, 6, 8 };
136
137
elemfamily = elemtype / 100;
138
nonodes = fam2nodemap[elemfamily];
139
140
return(nonodes);
141
}
142
143
144
static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
145
int boundarynodes,int *nodeindx,int *boundindx,int info)
146
{
147
int i,j,k,sideelemtype,elemind,*indx;
148
int boundarytype,minboundary,maxboundary,minnode,maxnode,sideelem,elemtype;
149
int sideind[MAXNODESD1],elemsides,side,sidenodes,hit,nohits;
150
int *elemhits;
151
152
if(!boundarynodes) return;
153
154
for(j=0;j < MAXBOUNDARIES;j++)
155
bound[j].created = FALSE;
156
for(j=0;j < MAXBOUNDARIES;j++)
157
bound[j].nosides = 0;
158
159
AllocateBoundary(bound,boundarynodes);
160
161
info = TRUE;
162
163
sideelem = 0;
164
maxboundary = minboundary = boundindx[1];
165
minnode = maxnode = nodeindx[1];
166
167
for(i=1;i<=boundarynodes;i++) {
168
if(maxboundary < boundindx[i]) maxboundary = boundindx[i];
169
if(minboundary > boundindx[i]) minboundary = boundindx[i];
170
if(maxnode < nodeindx[i]) maxnode = nodeindx[i];
171
if(minnode > nodeindx[i]) minnode = nodeindx[i];
172
}
173
174
if(info) {
175
printf("Boundary types are in interval [%d, %d]\n",minboundary,maxboundary);
176
printf("Boundary nodes are in interval [%d, %d]\n",minnode,maxnode);
177
}
178
179
indx = Ivector(1,data->noknots);
180
181
printf("Allocating hit table of size: %d\n",data->noknots);
182
elemhits = Ivector(1,data->noknots);
183
for(i=1;i<=data->noknots;i++) elemhits[i] = 0;
184
185
186
for(elemind=1;elemind<=data->noelements;elemind++) {
187
elemtype = data->elementtypes[elemind];
188
elemsides = elemtype % 100;
189
190
for(i=0;i<elemsides;i++) {
191
j = data->topology[elemind][i];
192
elemhits[j] += 1;
193
}
194
}
195
196
for(boundarytype=minboundary;boundarytype <= maxboundary;boundarytype++) {
197
int boundfirst,bchits,bcsame,sideelemtype2;
198
int sideind2[MAXNODESD1];
199
int minhits;
200
201
boundfirst = 0;
202
203
for(i=1;i<=data->noknots;i++)
204
indx[i] = 0;
205
206
for(i=1;i<=boundarynodes;i++) {
207
if(boundindx[i] == boundarytype)
208
indx[nodeindx[i]] = TRUE;
209
}
210
211
212
for(elemind=1;elemind<=data->noelements;elemind++) {
213
elemtype = data->elementtypes[elemind];
214
215
j = LinearNodes(elemtype);
216
nohits = 0;
217
for(i=0;i<j;i++)
218
if(indx[data->topology[elemind][i]]) nohits++;
219
if(!nohits) continue;
220
221
if(elemtype > 800 )
222
minhits = 4;
223
else if( elemtype > 500 )
224
minhits = 3;
225
else if( elemtype > 300 )
226
minhits = 2;
227
else
228
minhits = 1;
229
230
if(nohits < minhits) continue;
231
232
elemsides = elemtype / 100;
233
if(elemsides == 8) elemsides = 6;
234
else if(elemsides == 5) elemsides = 4;
235
else if(elemsides == 6 || elemsides == 7) elemsides = 5;
236
237
if(0) printf("elemtype = %d %d %d %d %d\n",elemind,elemtype,elemsides,nohits,minhits);
238
239
/* Check whether the bc nodes occupy every node in the selected side */
240
for(side=0;side<elemsides;side++) {
241
GetElementSide(elemind,side,1,data,&sideind[0],&sideelemtype);
242
sidenodes = sideelemtype%100;
243
244
if(0) printf("sideelemtype = %d %d %d\n",side,sideelemtype,sidenodes);
245
246
hit = TRUE;
247
nohits = 0;
248
for(i=0;i<sidenodes;i++) {
249
if(sideind[i] <= 0) {
250
if(0) printf("sideind[%d] = %d\n",i,sideind[i]);
251
hit = FALSE;
252
}
253
else if(sideind[i] > data->noknots) {
254
if(0) printf("sideind[%d] = %d (noknots=%d)\n",i,sideind[i],data->noknots);
255
hit = FALSE;
256
}
257
else if(!indx[sideind[i]]) {
258
hit = FALSE;
259
}
260
else {
261
nohits++;
262
}
263
}
264
265
if(0) {
266
printf("******\n");
267
printf("hits=%d ind=%d type=%d sides=%d\n",nohits,elemind,elemtype,elemsides);
268
printf("sidenodes=%d side=%d\n",sidenodes,side);
269
270
for(i=0;i<sidenodes;i++)
271
printf("%d ",sideind[i]);
272
273
printf("\neleminds %d %d\n",elemtype,elemind);
274
for(i=0;i<elemtype%100;i++)
275
printf("%d ",data->topology[elemind][i]);
276
printf("\n");
277
278
hit = TRUE;
279
}
280
281
if(hit == TRUE) {
282
/* If all the points belong to more than one element there may be
283
another parent for the side element */
284
bcsame = FALSE;
285
bchits = TRUE;
286
for(i=0;i<sidenodes;i++)
287
if(elemhits[sideind[i]] < 2) bchits = FALSE;
288
289
if(bchits && boundfirst) {
290
for(j=boundfirst;j<=sideelem;j++) {
291
if(bound->parent2[j]) continue;
292
GetElementSide(bound->parent[j],bound->side[j],1,data,&sideind2[0],&sideelemtype2);
293
if(sideelemtype != sideelemtype2) continue;
294
bcsame = 0;
295
for(i=0;i<sidenodes;i++)
296
for(k=0;k<sidenodes;k++)
297
if(sideind[i] == sideind2[k]) bcsame++;
298
299
if(bcsame == sidenodes) {
300
if(data->material[bound->parent[j]] > data->material[elemind]) {
301
bound->parent2[j] = bound->parent[j];
302
bound->side2[j] = bound->side[j];
303
bound->parent[j] = elemind;
304
bound->side[j] = side;
305
}
306
else {
307
bound->parent2[j] = elemind;
308
bound->side2[j] = side;
309
}
310
goto bcset;
311
}
312
}
313
}
314
315
sideelem += 1;
316
317
if( sideelem > bound->nosides ) {
318
printf("There are more side elements than allocated for (%d vs. %d)\n",sideelem,bound->nosides);
319
}
320
bound->parent[sideelem] = elemind;
321
bound->side[sideelem] = side;
322
bound->parent2[sideelem] = 0;
323
bound->side2[sideelem] = 0;
324
bound->types[sideelem] = boundarytype;
325
326
if(!boundfirst) boundfirst = sideelem;
327
328
bcset:
329
continue;
330
}
331
}
332
}
333
}
334
335
free_Ivector(indx,1,data->noknots);
336
337
if(info) printf("Found %d side elements formed by %d points.\n",
338
sideelem,boundarynodes);
339
340
if(sideelem) {
341
bound->nosides = MIN( sideelem, bound->nosides );
342
}
343
else {
344
if(info) printf("Adding the points as 101 elements to the mesh instead!\n");
345
346
bound->topology = Imatrix(1,boundarynodes,0,0);
347
bound->elementtypes =Ivector(1,boundarynodes);
348
349
for(i=1;i<=boundarynodes;i++) {
350
bound->types[i] = boundindx[i];
351
bound->elementtypes[i] = 101;
352
bound->topology[i][0] = nodeindx[i];
353
}
354
}
355
356
return;
357
}
358
359
360
static void AbaqusSideInfoToBoundary(struct FemType *data,struct BoundaryType *bound,
361
int nosides,int *sides,int *parent,int *bctypes,int info)
362
{
363
int i,j,k,l,n,noelements,noknots,elemside,elemfamily;
364
int minelemdim,maxelemdim,elemtype,sideelemtype,minelemtype,maxelemtype;
365
int sideind2[MAXNODESD2];
366
int order8[]={4,5,0,1,2,3};
367
int order7[]={3,4,0,1,2};
368
int order6[]={4,0,1,2,3};
369
int order5[]={3,0,1,2};
370
int order4[]={0,1,2,3};
371
int order3[]={0,1,2};
372
int *faceorder;
373
int zeroparent,zerosides;
374
375
376
if(info) printf("Making side info of size %d to boundary elements\n",nosides);
377
378
for(j=0;j < MAXBOUNDARIES;j++)
379
bound[j].created = FALSE;
380
for(j=0;j < MAXBOUNDARIES;j++)
381
bound[j].nosides = 0;
382
if(!nosides) return;
383
384
noelements = data->noelements;
385
noknots = data->noknots;
386
387
maxelemtype = GetMaxElementType(data);
388
if(info) printf("Leading bulk elementtype is %d\n",maxelemtype);
389
390
minelemtype = GetMinElementType(data);
391
if(info) printf("Trailing bulk elementtype is %d\n",minelemtype);
392
393
if(0) maxelemdim = GetElementDimension(maxelemtype);
394
if(0) minelemdim = GetElementDimension(minelemtype);
395
396
AllocateBoundary(bound,nosides);
397
398
bound->topology = Imatrix(1,nosides,0,MAXNODESD2-1);
399
for(i=1;i<=nosides;i++)
400
for(j=0;j<MAXNODESD2;j++)
401
bound->topology[i][j] = 0;
402
403
j = 0;
404
zeroparent = 0;
405
zerosides = 0;
406
407
for(i=0;i<nosides;i++) {
408
409
if(!sides[i]) continue;
410
411
if(parent[i] <= 0) {
412
zeroparent++;
413
continue;
414
}
415
416
if(sides[i] <= 0) {
417
zerosides++;
418
continue;
419
}
420
421
j += 1;
422
bound->parent[j] = parent[i];
423
424
elemtype = data->elementtypes[parent[i]];
425
elemfamily = elemtype / 100;
426
427
if(elemfamily == 8 )
428
faceorder = &order8[0];
429
else if(elemfamily == 7 )
430
faceorder = &order7[0];
431
else if(elemfamily == 6 )
432
faceorder = &order6[0];
433
else if(elemfamily == 5 )
434
faceorder = &order5[0];
435
else if(elemfamily == 4 )
436
faceorder = &order4[0];
437
else if(elemfamily == 3 )
438
faceorder = &order3[0];
439
else {
440
printf("Face order not implemented for family: %d\n",elemfamily);
441
j--;
442
continue;
443
}
444
445
elemside = faceorder[sides[i]-1];
446
447
bound->side[j] = elemside;
448
bound->parent2[j] = 0;
449
bound->side2[j] = 0;
450
bound->types[j] = bctypes[i];
451
452
GetElementSide(parent[i],elemside,1,data,&sideind2[0],&sideelemtype);
453
454
if(!sideelemtype) {
455
printf("sideele = %d %d\n",sideelemtype,sideelemtype % 100);
456
j--;
457
}
458
else {
459
for(k=0;k<sideelemtype % 100;k++)
460
bound->topology[j][k] = sideind2[k];
461
}
462
}
463
if(zeroparent) printf("Number of zero parents: %d\n",zeroparent);
464
if(zerosides) printf("Number of zero sides: %d\n",zerosides);
465
466
if(info) printf("Setting side %d elements to be BCs finished!\n",j);
467
468
bound->nosides = j;
469
470
return;
471
}
472
473
static void InpUntreated(char *cmd)
474
{
475
printf("Untreated: %s",cmd);
476
bigerror("Could not read mesh from Abaqus inp file!");
477
}
478
479
static void InpIgnored(char *cmd)
480
{
481
printf("Ignored: %s",cmd);
482
}
483
484
static void InpComment(char *cmd)
485
{
486
printf("Comment: %s",cmd);
487
}
488
489
490
491
492
int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
493
char *prefix,int info)
494
/* Load the grid from a format that can be read by ABAQUS
495
program designed for structural mechanics. The commands
496
understood are only those that IDEAS creates when saving
497
results in ABAQUS format.
498
*/
499
{
500
int noknots,noelements,elemcode,maxnodes,bodyid,maxelem,nodeoffset;
501
int mode,allocated,nvalue,nvalue2,maxknot,nosides,elemnodes,ncum;
502
int boundarytype,boundarynodes,cont,bcind;
503
int *nodeindx=NULL,*boundindx=NULL,*elemindx=NULL;
504
char *pstr,*pstr2;
505
char filename[MAXFILESIZE];
506
char line[MAXLINESIZE];
507
int i,j,k,l,*ind=NULL;
508
FILE *in;
509
Real rvalues[MAXDOFS];
510
int *ivalues,ivalues0[MAXDOFS];
511
int ivaluessize;
512
int setmaterial;
513
int debug,firstline,generate;
514
char entityname[MAXNAMESIZE];
515
int side,type,newsurface;
516
int *bcsides,*bctypes,*bcparent;
517
518
strcpy(filename,prefix);
519
if ((in = fopen(filename,"r")) == NULL) {
520
AddExtension(prefix,filename,"inp");
521
if ((in = fopen(filename,"r")) == NULL) {
522
printf("LoadAbaqusInput: opening of the ABAQUS-file '%s' wasn't successful !\n",
523
filename);
524
return(1);
525
}
526
}
527
528
printf("Reading input from ABAQUS input file %s.\n",filename);
529
InitializeKnots(data);
530
531
allocated = FALSE;
532
maxknot = 0;
533
maxelem = 0;
534
ivaluessize = MAXDOFS;
535
ivalues = Ivector(0,ivaluessize-1);
536
for(i=0;i<ivaluessize;i++)
537
ivalues[i] = 0;
538
539
540
/* Because the file format doesn't provide the number of elements
541
or nodes the results are read twice but registered only in the
542
second time. */
543
544
debug = FALSE;
545
546
omstart:
547
548
mode = 0;
549
maxnodes = 0;
550
noknots = 0;
551
noelements = 0;
552
nodeoffset = 0;
553
elemcode = 0;
554
boundarytype = 0;
555
boundarynodes = 0;
556
bodyid = 0;
557
nosides = 0;
558
bcind = 0;
559
ivalues0[0] = ivalues0[1] = 0;
560
newsurface = 0;
561
562
for(;;) {
563
/* GETLINE; */
564
565
if (Getrow(line,in,TRUE)) goto end;
566
567
/* if(!line) goto end; */
568
/* if(strstr(line,"END")) goto end; */
569
570
571
if(strrchr(line,'*')) {
572
/* There result to errors hence no "else" needed! */
573
if(strstr(line,"NEWSET")) InpUntreated(line);
574
if(strstr(line,"NGEN")) InpUntreated(line);
575
if(strstr(line,"NFILL")) InpUntreated(line);
576
577
if( mode == 2 ) {
578
if(!allocated) printf("Number of nodes so far: %d\n",noknots);
579
}
580
else if( mode == 3 ) {
581
if(!allocated) printf("Number of elements so far: %d\n",noelements);
582
/* if(elmatactive) {
583
nodeoffset = noknots;
584
if(!allocated) printf("Node offset is %d\n",nodeoffset);
585
} */
586
}
587
588
if( strstr(line,"**") ) {
589
if(info && !allocated) InpComment(line);
590
mode = 0;
591
}
592
else if(strstr(line,"HEAD")) {
593
mode = 1;
594
}
595
else if(strstr(line,"*NODE")) {
596
if( ( pstr = strstr(line,"NODE OUTPUT")) ) {
597
mode = 10;
598
}
599
else {
600
if(strstr(line,"SYSTEM=R")) data->coordsystem = COORD_CART2;
601
if(strstr(line,"SYSTEM=C")) data->coordsystem = COORD_AXIS;
602
if(strstr(line,"SYSTEM=P")) data->coordsystem = COORD_POLAR;
603
mode = 2;
604
}
605
}
606
else if(strstr(line,"*ELEMENT")) {
607
if( ( pstr = strstr(line,"ELEMENT OUTPUT")) ) {
608
mode = 10;
609
}
610
else {
611
if(strstr(line,"S3") || strstr(line,"STRI3") || strstr(line,"M3D3"))
612
elemcode = 303;
613
else if(strstr(line,"2D4") || strstr(line,"SP4") || strstr(line,"AX4")
614
|| strstr(line,"S4") || strstr(line,"CPE4"))
615
elemcode = 404;
616
else if(strstr(line,"2D8") || strstr(line,"AX8") || strstr(line,"DS8") )
617
elemcode = 408;
618
else if(strstr(line,"3D4"))
619
elemcode = 504;
620
else if(strstr(line,"3D10"))
621
elemcode = 510;
622
else if(strstr(line,"3D5"))
623
elemcode = 605;
624
else if(strstr(line,"3D6"))
625
elemcode = 706;
626
else if(strstr(line,"3D15"))
627
elemcode = 715;
628
else if(strstr(line,"3D8"))
629
elemcode = 808;
630
else if(strstr(line,"3D20"))
631
elemcode = 820;
632
else {
633
printf("Unknown element code: %s\n",line);
634
bigerror("Cannot continue without all elements!");
635
}
636
637
elemnodes = elemcode % 100;
638
maxnodes = MAX( maxnodes, elemnodes);
639
640
641
mode = 3;
642
643
if(allocated) {
644
if(info) printf("Loading elements of type %d starting from element %d to body %d.\n",
645
elemcode,noelements,bodyid);
646
}
647
648
if( ( pstr = strstr(line,"ELSET=")) ) {
649
bodyid++;
650
if(allocated) {
651
if(info) printf("Loading elements to body %d from ELSET %s",bodyid,pstr+6);
652
sscanf(pstr+6,"%s",entityname);
653
if(!data->bodyname[bodyid]) data->bodyname[bodyid] = Cvector(0,MAXNAMESIZE);
654
strcpy(data->bodyname[bodyid],entityname);
655
data->bodynamesexist = TRUE;
656
data->boundarynamesexist = TRUE;
657
}
658
}
659
660
firstline = TRUE;
661
}
662
}
663
else if( strstr(line,"BOUNDARY") ) {
664
boundarytype++;
665
mode = 4;
666
if(allocated && info) printf("Treating keyword BOUNDARY for bc %d\n",boundarytype);
667
}
668
else if( strstr(line,"SOLID SECTION") ) {
669
/* Have this here since solid section may include ELSET */
670
mode = 10;
671
}
672
else if( strstr(line,"MEMBRANE SECTION") ) {
673
/* Have this here since solid section may include ELSET */
674
mode = 10;
675
}
676
else if( strstr(line,"CLOAD") ) {
677
boundarytype++;
678
mode = 4;
679
if(allocated && info) printf("Treating keyword CLOAD for bc %d\n",boundarytype);
680
}
681
else if( (pstr = strstr(line,"NSET=")) ) {
682
683
if( strstr(line,"ELSET=") ) {
684
/* Skipping association of ELSET to NSET */
685
mode = 10;
686
}
687
else {
688
boundarytype++;
689
mode = 5;
690
if(allocated && info) printf("Treating keyword NSET for bc %d from: %s",boundarytype,pstr+5);
691
}
692
}
693
else if( (pstr = strstr(line,"ELSET=")) ) {
694
mode = 6;
695
696
generate = FALSE;
697
if( strstr(pstr,"GENERATE") ) generate = TRUE;
698
side = 0;
699
700
pstr += 6;
701
if( strstr( line,"ELSET=_")) {
702
pstr += 1;
703
704
/* This numbering is true for Abaqus-to-Elmer hexas only! */
705
if( ( pstr2 = strstr(pstr,"_S1") ) )
706
side = 1;
707
else if( ( pstr2 = strstr(pstr,"_S2") ) )
708
side = 2;
709
else if( ( pstr2 = strstr(pstr,"_S3") ) )
710
side = 3;
711
else if( ( pstr2 = strstr(pstr,"_S4") ) )
712
side = 4;
713
else if( ( pstr2 = strstr(pstr,"_S5") ) )
714
side = 5;
715
else if( ( pstr2 = strstr(pstr,"_S6") ) )
716
side = 6;
717
718
if(!side ) printf("Could not determine side!\n");
719
}
720
721
if( side > 0 ) {
722
if(1)
723
newsurface = TRUE;
724
else
725
bcind += 1;
726
pstr2[0] = '\n';
727
sscanf(pstr,"%s",entityname);
728
if(allocated) {
729
if(info) printf("Loading boundary set %d for side %d of %s\n",bcind+newsurface,side,entityname);
730
k = bcind+newsurface;
731
if(k>MAXBCS) bigerror("Boundary set larger than MAXBCS!");
732
if(!data->boundaryname[k]) data->boundaryname[k] = Cvector(0,MAXNAMESIZE);
733
strcpy(data->boundaryname[k],entityname);
734
data->boundarynamesexist = TRUE;
735
}
736
}
737
else {
738
bodyid++;
739
sscanf(pstr,"%s",entityname);
740
if(allocated) {
741
if(info) printf("Loading element to body %d from %s\n",bodyid,entityname);
742
if(bodyid>MAXBODIES) bigerror("Body set larger than MAXBODIES!");
743
if(!data->bodyname[bodyid]) data->bodyname[bodyid] = Cvector(0,MAXNAMESIZE);
744
strcpy(data->bodyname[bodyid],entityname);
745
data->bodynamesexist = TRUE;
746
}
747
}
748
749
}
750
else if( ( pstr = strstr(line,"SURFACE")) ) {
751
bcind = bcind + newsurface;
752
newsurface = FALSE;
753
mode = 0;
754
}
755
else if( ( pstr = strstr(line,"PART, NAME=")) ) {
756
bodyid += 1;
757
mode = 6;
758
generate = FALSE;
759
760
if(allocated) {
761
if(info) printf("Loading part to body %d from %s",bodyid,pstr+11);
762
sscanf(pstr+6,"%s",entityname);
763
if(!data->bodyname[bodyid]) data->bodyname[bodyid] = Cvector(0,MAXNAMESIZE);
764
strcpy(data->bodyname[bodyid],entityname);
765
data->bodynamesexist = TRUE;
766
data->boundarynamesexist = TRUE;
767
}
768
}
769
else if( ( pstr = strstr(line,"HWCOLOR")) ) {
770
/* unused command */
771
mode = 0;
772
}
773
else {
774
if(!allocated) InpIgnored(line);
775
mode = 0;
776
}
777
}
778
779
else if(mode) {
780
switch (mode) {
781
782
case 1:
783
if(info) printf("Loading Abaqus input file:\n%s",line);
784
break;
785
786
case 2: /* NODE */
787
nvalue = StringToReal(line,rvalues,MAXNODESD2+1,',');
788
789
if(nvalue > 4 || nvalue < 2 ) {
790
printf("line: %s\n",line);
791
printf("Invalid nvalue = %d\n",nvalue);
792
}
793
794
i = (int)(rvalues[0]+0.5);
795
noknots++;
796
797
if(allocated) {
798
if( debug && (i==1 || i==maxknot) ) {
799
printf("debug node: %i %d %.3le %.3le %.3le\n",i,noknots,rvalues[1],rvalues[2],rvalues[3]);
800
}
801
802
i = MAX( i, noknots );
803
if(i <= 0 || i > maxknot) {
804
printf("Invalid node index = %d\n",i);
805
}
806
else {
807
ind[i] = noknots;
808
if(nvalue>=2) data->x[noknots] = rvalues[1];
809
if(nvalue>=3) data->y[noknots] = rvalues[2];
810
if(nvalue>=4) data->z[noknots] = rvalues[3];
811
}
812
}
813
else {
814
if(maxknot < i) maxknot = i;
815
}
816
break;
817
818
case 3: /* ELEMENT */
819
noelements++;
820
821
nvalue = StringToIntegerNoZero(line,ivalues,elemnodes+1,',');
822
823
if(allocated) {
824
if( debug && firstline ) {
825
printf("debug elem: %d %d %d %d\n",noelements,ivalues[0],elemcode,bodyid);
826
printf(" topo:");
827
for(i=0;i<nvalue-1;i++)
828
printf(" %d",ivalues[i+1]);
829
printf("\n");
830
firstline = FALSE;
831
}
832
833
elemindx[ivalues[0]] = noelements;
834
data->elementtypes[noelements] = elemcode;
835
836
data->material[noelements] = bodyid;
837
for(i=0;i<nvalue-1;i++)
838
data->topology[noelements][i] = ivalues[i+1];
839
840
if( nodeoffset ) {
841
for(i=0;i<nvalue-1;i++)
842
data->topology[noelements][i] += nodeoffset;
843
}
844
845
}
846
else {
847
if( maxelem < ivalues[0] ) maxelem = ivalues[0];
848
}
849
850
ncum = nvalue-1;
851
852
/* Read 2nd line if needed */
853
if(ncum < elemnodes ) {
854
Getrow(line,in,TRUE);
855
nvalue = StringToIntegerNoZero(line,ivalues,elemnodes-ncum,',');
856
if(allocated) {
857
for(i=0;i<nvalue;i++)
858
data->topology[noelements][ncum+i] = ivalues[i];
859
}
860
ncum = ncum + nvalue;
861
}
862
863
/* Be prepared for 3rd line as well */
864
if(ncum < elemnodes ) {
865
Getrow(line,in,TRUE);
866
nvalue = StringToIntegerNoZero(line,ivalues,elemnodes-ncum,',');
867
if(allocated) {
868
for(i=0;i<nvalue;i++)
869
data->topology[noelements][ncum+i] = ivalues[i];
870
}
871
ncum = ncum + nvalue;
872
}
873
if(ncum != elemnodes) printf("ncum = %d vs. %d\n",ncum,elemnodes);
874
875
if( allocated ) {
876
j = FALSE;
877
for(i=0;i<elemnodes;i++)
878
if(!data->topology[noelements][i]) j = TRUE;
879
880
if(j) {
881
printf("zero in this element\n");
882
printf("element = %d %d\n",noelements,elemnodes);
883
for(i=0;i<elemnodes;i++)
884
printf("%d ",data->topology[noelements][i]);
885
printf("\n");
886
}
887
}
888
889
break;
890
891
case 4:
892
nvalue = StringToInteger(line,ivalues,2,',');
893
894
if(ivalues[0] == ivalues0[0] && ivalues[1] != ivalues0[1]) continue;
895
ivalues0[0] = ivalues[0];
896
ivalues0[1] = ivalues[1];
897
898
boundarynodes++;
899
if(allocated) {
900
nodeindx[boundarynodes] = ivalues[0];
901
boundindx[boundarynodes] = boundarytype;
902
}
903
break;
904
905
case 5: /* NSET */
906
nvalue = StringToIntegerNoZero(line,ivalues,ivaluessize,',');
907
908
if(allocated) {
909
for(i=0;i<nvalue;i++) {
910
boundarynodes += 1;
911
nodeindx[boundarynodes] = ivalues[i];
912
boundindx[boundarynodes] = boundarytype;
913
if(0) printf("bc: %d % d %d\n",boundarynodes,ivalues[i],boundarytype);
914
}
915
}
916
else
917
boundarynodes += nvalue;
918
919
break;
920
921
case 6: /* ELSET */
922
nvalue = StringToIntegerNoZero(line,ivalues,ivaluessize,',');
923
924
if(generate) {
925
nvalue = (ivalues[1]-ivalues[0])/ivalues[2]+1;
926
if(0) printf("generate: %d %d %d %d\n",ivalues[0],ivalues[1],ivalues[2],nvalue);
927
}
928
929
if(allocated) {
930
if(generate) {
931
i=0;
932
for(j=ivalues[0];j<=ivalues[1];j+=ivalues[2]) {
933
if( side ) {
934
bcsides[nosides+i] = side;
935
bctypes[nosides+i] = bcind+newsurface;
936
bcparent[nosides+i] = elemindx[j];
937
i++;
938
}
939
else {
940
data->material[elemindx[j]] = bodyid;
941
}
942
}
943
}
944
else {
945
for(i=0;i<nvalue;i++) {
946
if( side ) {
947
bcsides[nosides+i] = side;
948
bctypes[nosides+i] = bcind+newsurface;
949
bcparent[nosides+i] = elemindx[ivalues[i]];
950
}
951
else {
952
j = elemindx[ivalues[i]];
953
data->material[j] = bodyid;
954
}
955
}
956
}
957
}
958
959
if(side) nosides += nvalue;
960
break;
961
962
case 10:
963
/* Doing nothing */
964
break;
965
966
967
default:
968
printf("Unknown case: %d\n",mode);
969
}
970
}
971
972
}
973
end:
974
975
if(!allocated) {
976
977
rewind(in);
978
979
data->noknots = noknots;
980
data->noelements = noelements;
981
data->maxnodes = maxnodes;
982
data->dim = 3;
983
984
if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
985
noknots,noelements,maxnodes);
986
AllocateKnots(data);
987
988
if(info) printf("Number of boundary nodes: %d\n",boundarynodes);
989
if( boundarynodes > 0 ) {
990
nodeindx = Ivector(1,boundarynodes);
991
boundindx = Ivector(1,boundarynodes);
992
}
993
994
if(info) printf("Maximum temporal index array size: %d\n",ivaluessize);
995
free_Ivector(ivalues,0,ivaluessize-1);
996
997
if(info) printf("Maximum element index in file: %d\n",maxelem);
998
maxelem = MAX( maxelem, noelements );
999
1000
elemindx = Ivector(1,maxelem);
1001
for(i=1;i<=maxelem;i++)
1002
elemindx[i] = 0;
1003
1004
if(info) printf("Maximum node index in file: %d\n",maxknot);
1005
maxknot = MAX( maxknot, noknots );
1006
ind = ivector(1,maxknot);
1007
for(i=1;i<=maxknot;i++)
1008
ind[i] = 0;
1009
1010
if(nosides > 0 ) {
1011
bcsides = Ivector(0,nosides-1);
1012
bctypes = Ivector(0,nosides-1);
1013
bcparent = Ivector(0,nosides-1);
1014
}
1015
1016
allocated = TRUE;
1017
goto omstart;
1018
}
1019
1020
1021
if(info) printf("The mesh was loaded from file %s.\n",filename);
1022
1023
/* ABAQUS format does not expect that all numbers are used
1024
when numbering the elements. Therefore the nodes must
1025
be renumbered from 1 to noknots. */
1026
1027
if(noknots != maxknot) {
1028
int errcount,okcount;
1029
if(info) printf("There are %d nodes but maximum index is %d.\n",noknots,maxknot);
1030
if(info) printf("Renumbering %d elements\n",noelements);
1031
errcount = 0;
1032
okcount = 0;
1033
for(j=1;j<=noelements;j++) {
1034
elemcode = data->elementtypes[j];
1035
elemnodes = elemcode % 100;
1036
for(i=0;i < elemnodes;i++) {
1037
k = data->topology[j][i];
1038
if(k<=0) {
1039
printf("err elem ind: %d %d %d %d\n",j,elemcode,i,k);
1040
errcount++;
1041
}
1042
else {
1043
data->topology[j][i] = ind[k];
1044
okcount++;
1045
}
1046
}
1047
}
1048
if(info) printf("There are %d positive and %d non-positive indexes in elements!\n",okcount,errcount);
1049
1050
if(info) printf("Renumbering %d nodes in node sets\n",boundarynodes);
1051
errcount = 0;
1052
okcount = 0;
1053
for(j=1;j<=boundarynodes;j++) {
1054
k = nodeindx[j];
1055
if(k<=0 || k > maxknot) {
1056
printf("err node set ind: %d %d\n",j,k);
1057
errcount++;
1058
}
1059
else {
1060
nodeindx[j] = ind[k];
1061
okcount++;
1062
}
1063
}
1064
printf("There are %d positive and %d non-positive indexes in node sets!\n",okcount,errcount);
1065
}
1066
1067
1068
{
1069
int maxid,mincnt;
1070
maxid = data->material[1];
1071
mincnt = 0;
1072
for(i=1;i<=noelements;i++) {
1073
maxid = MAX(maxid,data->material[i]);
1074
if(!data->material[i]) mincnt++;
1075
}
1076
if(mincnt) {
1077
maxid +=1;
1078
if(info) printf("Setting %d unset elements to body index %d and name 'DefaulBody'\n",mincnt,maxid);
1079
for(i=1;i<=noelements;i++)
1080
if(!data->material[i]) data->material[i] = maxid;
1081
if(!data->bodyname[maxid]) data->bodyname[maxid] = Cvector(0,MAXNAMESIZE);
1082
strcpy(data->bodyname[maxid],"DefaultBody");
1083
data->bodynamesexist = TRUE;
1084
data->boundarynamesexist = TRUE;
1085
}
1086
1087
/* The underscore suggest some special Abaqus commands. Scrap that. */
1088
for(i=1;i<=maxid;i++) {
1089
if(data->bodyname[i])
1090
if( ( pstr = strstr(data->bodyname[i],",") ) ) pstr[0] = '\0';
1091
}
1092
}
1093
1094
1095
if(nosides) {
1096
if(info) printf("Creating boundary elements from side pointers!\n");
1097
AbaqusSideInfoToBoundary(data,bound,nosides,bcsides,bcparent,bctypes,info);
1098
}
1099
else if(boundarynodes) {
1100
if(info) printf("Creating boundary elements from node set!\n");
1101
FindPointParents(data,bound,boundarynodes,nodeindx,boundindx,info);
1102
if(0) ElementsToBoundaryConditions(data,bound,FALSE,info);
1103
}
1104
1105
free_ivector(ind,1,maxknot);
1106
free_Ivector(elemindx,1,maxelem);
1107
1108
if( boundarynodes > 0 ) {
1109
if(info) printf("Number of nodes in boundary sets: %d\n",boundarynodes);
1110
/* Temporarily suppress the deallocation while trying to find a bug */
1111
free_Ivector(nodeindx,1,boundarynodes);
1112
free_Ivector(boundindx,1,boundarynodes);
1113
}
1114
fclose(in);
1115
1116
if(info) printf("Finished reading ABAQUS input file\n");
1117
1118
1119
return(0);
1120
}
1121
1122
1123
static int ReadAbaqusField(FILE *in,char *buffer,int *argtype,int *argno)
1124
/* This subroutine reads the Abaqus file format and tries to make
1125
sense out of it.
1126
*/
1127
{
1128
int i,val,digits;
1129
static int maxargno=0,mode=0;
1130
1131
val = fgetc(in);
1132
1133
if(val==EOF) return(-1);
1134
if(val=='\n') val = fgetc(in);
1135
1136
if(val=='*') {
1137
if(0) printf("start field\n");
1138
if((*argno) != maxargno)
1139
printf("The previous field was of wrong length, debugging time!\n");
1140
(*argno) = 0;
1141
mode = 0;
1142
val = fgetc(in);
1143
if(val=='\n') val = fgetc(in);
1144
}
1145
1146
if(val=='I') {
1147
for(i=0;i<2;i++) {
1148
val = fgetc(in);
1149
if(val=='\n') val = fgetc(in);
1150
buffer[i] = val;
1151
}
1152
buffer[2] = '\0';
1153
digits = atoi(buffer);
1154
for(i=0;i<digits;i++) {
1155
val = fgetc(in);
1156
if(val=='\n') val = fgetc(in);
1157
buffer[i] = val;
1158
}
1159
buffer[digits] = '\0';
1160
(*argno)++;
1161
(*argtype) = 1;
1162
if((*argno) == 1) maxargno = atoi(buffer);
1163
if((*argno) == 2) mode = atoi(buffer);
1164
}
1165
else if(val=='D') {
1166
for(i=0;i<22;i++) {
1167
val = fgetc(in);
1168
if(val=='\n') val = fgetc(in);
1169
if(val=='D') val = 'E';
1170
buffer[i] = val;
1171
}
1172
buffer[22] = '\0';
1173
(*argno)++;
1174
(*argtype) = 2;
1175
}
1176
else if(val=='A') {
1177
for(i=0;i<8;i++) {
1178
val = fgetc(in);
1179
if(val=='\n') val = fgetc(in);
1180
buffer[i] = val;
1181
}
1182
buffer[8] = '\0';
1183
(*argno)++;
1184
(*argtype) = 3;
1185
}
1186
else {
1187
buffer[0] = val;
1188
buffer[1] = '\0';
1189
(*argtype) = 0;
1190
}
1191
return(mode);
1192
}
1193
1194
1195
1196
int LoadAbaqusOutput(struct FemType *data,char *prefix,int info)
1197
/* Load the grid from a format that can be read by ABAQUS
1198
program designed for structural mechanics.
1199
*/
1200
{
1201
int knotno,elemno,elset,secno;
1202
int argtype,argno;
1203
int mode,allocated;
1204
char filename[MAXFILESIZE];
1205
char buffer[MAXLINESIZE];
1206
int i,j,prevdog,nodogs;
1207
int ignored;
1208
FILE *in=NULL;
1209
int *indx=NULL;
1210
1211
1212
AddExtension(prefix,filename,"fil");
1213
1214
if ((in = fopen(filename,"r")) == NULL) {
1215
printf("LoadAbaqusOutput: opening of the Abaqus-file '%s' wasn't successful !\n",
1216
filename);
1217
return(1);
1218
}
1219
if(info) printf("Reading input from ABAQUS output file %s.\n",filename);
1220
InitializeKnots(data);
1221
1222
allocated = FALSE;
1223
mode = 0;
1224
knotno = 0;
1225
elemno = 0;
1226
nodogs = 0;
1227
prevdog = 0;
1228
argno = 0;
1229
elset = 0;
1230
secno = 0;
1231
ignored = 0;
1232
data->maxnodes = 9;
1233
data->dim = 3;
1234
1235
for(;;) {
1236
1237
mode = ReadAbaqusField(in,buffer,&argtype,&argno);
1238
if(0) printf("%d %d: buffer: %s\n",argtype,argno,buffer);
1239
1240
switch (mode) {
1241
1242
case -1:
1243
goto jump;
1244
1245
case 0:
1246
break;
1247
1248
case 1921:
1249
/* General info */
1250
if(argno == 3) printf("Reading output file for Abaqus %s\n",buffer);
1251
else if(argno == 4) printf("Created on %s",buffer);
1252
else if(argno == 5) printf("%s",buffer);
1253
else if(argno == 6) printf("%s\n",buffer);
1254
else if(argno == 7) data->noelements = atoi(buffer);
1255
else if(argno == 8 && allocated == FALSE) {
1256
data->noknots = atoi(buffer);
1257
allocated = TRUE;
1258
AllocateKnots(data);
1259
indx = Ivector(0,2 * data->noknots);
1260
for(i=1;i<=2*data->noknots;i++)
1261
indx[i] = 0;
1262
}
1263
break;
1264
1265
case 1900:
1266
/* Element definition */
1267
if(argno == 3) elemno = atoi(buffer);
1268
else if(argno == 4) {
1269
if(strstr(buffer,"2D4") || strstr(buffer,"SP4") || strstr(buffer,"AX4"))
1270
data->elementtypes[elemno] = 404;
1271
else if(strstr(buffer,"2D8") || strstr(buffer,"AX8") || strstr(buffer,"S8R5"))
1272
data->elementtypes[elemno] = 408;
1273
else if(strstr(buffer,"3D8"))
1274
data->elementtypes[elemno] = 808;
1275
else printf("Unknown element code: %s\n",buffer);
1276
}
1277
else if(argno >= 5)
1278
data->topology[elemno][argno-5] = atoi(buffer);
1279
break;
1280
1281
case 1901:
1282
/* Node definition */
1283
if(argno == 3) {
1284
knotno++;
1285
if(atoi(buffer) > 2*data->noknots)
1286
printf("LoadAbaqusOutput: allocate more space for indx.\n");
1287
else
1288
indx[atoi(buffer)] = knotno;
1289
}
1290
if(argno == 4) sscanf(buffer,"%le",&(data->x[knotno]));
1291
if(argno == 5) sscanf(buffer,"%le",&(data->y[knotno]));
1292
if(argno == 6) sscanf(buffer,"%le",&(data->z[knotno]));
1293
break;
1294
1295
case 1933:
1296
/* Element set */
1297
if(argno == 3) {
1298
elset++;
1299
if(!data->bodyname[elset]) data->bodyname[elset] = Cvector(0,MAXNAMESIZE);
1300
strcpy(data->bodyname[elset],buffer);
1301
}
1302
case 1934:
1303
/* Element set continuation */
1304
if(argno > 3) {
1305
elemno = atoi(buffer);
1306
data->material[elemno] = elset;
1307
}
1308
break;
1309
1310
case 2001:
1311
/* Just ignore */
1312
break;
1313
1314
case 1:
1315
if(argno == 3) knotno = indx[atoi(buffer)];
1316
if(argno == 5) secno = atoi(buffer);
1317
break;
1318
1319
case 2:
1320
if(prevdog != mode) {
1321
prevdog = mode;
1322
nodogs++;
1323
CreateVariable(data,nodogs,1,0.0,"Temperature",FALSE);
1324
}
1325
break;
1326
1327
/* Read vectors in nodes in elements */
1328
case 11:
1329
if(prevdog != mode) {
1330
prevdog = mode;
1331
nodogs++;
1332
CreateVariable(data,nodogs,3,0.0,"Stress",FALSE);
1333
}
1334
case 12:
1335
if(prevdog != mode) {
1336
prevdog = mode;
1337
nodogs++;
1338
CreateVariable(data,nodogs,3,0.0,"Invariants",FALSE);
1339
}
1340
if(secno==1 && argno == 3) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-2]));
1341
if(secno==1 && argno == 4) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-1]));
1342
if(secno==1 && argno == 5) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno]));
1343
break;
1344
1345
/* Read vectors in nodes. */
1346
case 101:
1347
if(prevdog != mode) {
1348
prevdog = mode;
1349
nodogs++;
1350
CreateVariable(data,nodogs,3,0.0,"Displacement",FALSE);
1351
}
1352
case 102:
1353
if(prevdog != mode) {
1354
prevdog = mode;
1355
nodogs++;
1356
CreateVariable(data,nodogs,3,0.0,"Velocity",FALSE);
1357
}
1358
if(argno == 3) knotno = indx[atoi(buffer)];
1359
if(argno == 4) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-2]));
1360
if(argno == 5) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-1]));
1361
if(argno == 6) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno]));
1362
break;
1363
1364
default:
1365
if(ignored != mode) {
1366
printf("Record %d was ignored!\n",mode);
1367
ignored = mode;
1368
}
1369
break;
1370
}
1371
}
1372
1373
jump:
1374
1375
if(info) printf("Renumbering elements\n");
1376
for(j=1;j<=data->noelements;j++)
1377
for(i=0;i < data->elementtypes[j]%100;i++)
1378
data->topology[j][i] = indx[data->topology[j][i]];
1379
1380
free_ivector(indx,0,2*data->noknots);
1381
1382
fclose(in);
1383
1384
if(info) printf("LoadAbacusInput: results were loaded from file %s.\n",filename);
1385
1386
return(0);
1387
}
1388
1389
1390
1391
1392
int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,
1393
char *prefix,int info)
1394
/* Load the grid from a format that in Nastran format
1395
*/
1396
{
1397
int noknots,noelements,maxnodes;
1398
int allocated,maxknot,minknot,nodes;
1399
char filename[MAXFILESIZE];
1400
char line[MAXLINESIZE],*cp;
1401
int j,k;
1402
FILE *in;
1403
1404
1405
strcpy(filename,prefix);
1406
if ((in = fopen(filename,"r")) == NULL) {
1407
AddExtension(prefix,filename,"nas");
1408
if ((in = fopen(filename,"r")) == NULL) {
1409
printf("LoadNastranInput: opening of the Nastran file '%s' wasn't successful !\n",
1410
filename);
1411
return(1);
1412
}
1413
}
1414
1415
if(info) printf("Reading mesh from Nastran file %s.\n",filename);
1416
InitializeKnots(data);
1417
1418
allocated = FALSE;
1419
maxknot = 0;
1420
minknot = 10000;
1421
1422
/* Because the file format doesn't provide the number of elements
1423
or nodes the results are read twice but registered only in the
1424
second time. */
1425
omstart:
1426
1427
maxnodes = 0;
1428
noknots = 0;
1429
noelements = 0;
1430
1431
for(;;) {
1432
/* GETLINE; */
1433
1434
if (Getrow(line,in,TRUE)) goto end;
1435
1436
if(line[0] == '$') {
1437
if(!allocated) InpComment(line);
1438
}
1439
else if(strstr(line,"GRID")) {
1440
noknots++;
1441
if(0) printf("line=%s\n",line);
1442
cp = &line[5];
1443
j = next_int(&cp);
1444
if(0) printf("j=%d\n",j);
1445
1446
if(allocated) {
1447
k = next_int(&cp);
1448
data->x[noknots] = next_real(&cp);
1449
data->y[noknots] = next_real(&cp);
1450
}
1451
else {
1452
if(j > maxknot) maxknot = j;
1453
if(j < minknot) minknot = j;
1454
}
1455
1456
if(strstr(line,"*"))
1457
Getrow(line,in,TRUE);
1458
1459
if(allocated) {
1460
cp = &line[4];
1461
data->z[noknots] = next_real(&cp);
1462
}
1463
1464
}
1465
else if(strstr(line,"TETRA")) {
1466
noelements++;
1467
nodes = 4;
1468
if(nodes > maxnodes) maxnodes = nodes;
1469
if(allocated) {
1470
data->elementtypes[noelements] = 504;
1471
cp = &line[6];
1472
k = next_int(&cp);
1473
data->material[noelements] = next_int(&cp) + 1;
1474
for(j=0;j<nodes;j++)
1475
data->topology[noelements][j] = next_int(&cp);
1476
}
1477
}
1478
else if(strstr(line,"PYRAM")) {
1479
noelements++;
1480
nodes = 5;
1481
if(nodes > maxnodes) maxnodes = nodes;
1482
if(allocated) {
1483
data->elementtypes[noelements] = 605;
1484
cp = &line[6];
1485
k = next_int(&cp);
1486
data->material[noelements] = next_int(&cp) + 1;
1487
for(j=0;j<nodes;j++)
1488
data->topology[noelements][j] = next_int(&cp);
1489
}
1490
}
1491
else if(strstr(line,"PENTA")) {
1492
noelements++;
1493
nodes = 6;
1494
if(nodes > maxnodes) maxnodes = nodes;
1495
if(allocated) {
1496
data->elementtypes[noelements] = 706;
1497
cp = &line[6];
1498
k = next_int(&cp);
1499
data->material[noelements] = next_int(&cp) + 1;
1500
for(j=0;j<nodes;j++)
1501
data->topology[noelements][j] = next_int(&cp);
1502
}
1503
}
1504
else if(strstr(line,"CHEXA")) {
1505
noelements++;
1506
nodes = 8;
1507
if(nodes > maxnodes) maxnodes = nodes;
1508
if(allocated) {
1509
data->elementtypes[noelements] = 808;
1510
cp = &line[5];
1511
k = next_int(&cp);
1512
data->material[noelements] = next_int(&cp) + 1;
1513
for(j=0;j<6;j++)
1514
data->topology[noelements][j] = next_int(&cp);
1515
}
1516
Getrow(line,in,TRUE);
1517
if(allocated) {
1518
cp = &line[1];
1519
for(j=6;j<8;j++)
1520
data->topology[noelements][j] = k;
1521
}
1522
}
1523
else if(strstr(line,"ENDDAT")) {
1524
goto end;
1525
}
1526
else {
1527
if(!allocated) InpIgnored(line);
1528
}
1529
}
1530
1531
end:
1532
1533
if(allocated == TRUE) {
1534
if(info) printf("The mesh was loaded from file %s.\n",filename);
1535
fclose(in);
1536
return(0);
1537
}
1538
1539
rewind(in);
1540
data->noknots = noknots;
1541
data->noelements = noelements;
1542
data->maxnodes = maxnodes;
1543
data->dim = 3;
1544
1545
printf("maxknot = %d minknot = %d\n",maxknot,minknot);
1546
1547
if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
1548
noknots,noelements,maxnodes);
1549
AllocateKnots(data);
1550
1551
allocated = TRUE;
1552
goto omstart;
1553
}
1554
1555
1556
1557
1558
static void ReorderFidapNodes(struct FemType *data,int element,int nodes,int typeflag)
1559
{
1560
int i,oldtopology[MAXNODESD2],*topology,dim;
1561
int order808[]={1,2,4,3,5,6,8,7};
1562
int order408[]={1,3,5,7,2,4,6,8};
1563
int order306[]={1,3,5,2,4,6};
1564
int order203[]={1,3,2};
1565
int order605[]={1,2,4,3,5};
1566
1567
dim = data->dim;
1568
if(typeflag > 10) dim -= 1;
1569
1570
data->elementtypes[element] = 101*nodes;
1571
topology = data->topology[element];
1572
1573
if(dim == 1) {
1574
if(nodes == 3) {
1575
data->elementtypes[element] = 203;
1576
for(i=0;i<nodes;i++)
1577
oldtopology[i] = topology[i];
1578
for(i=0;i<nodes;i++)
1579
topology[i] = oldtopology[order203[i]-1];
1580
}
1581
}
1582
else if(dim == 2) {
1583
if(nodes == 6) {
1584
data->elementtypes[element] = 306;
1585
for(i=0;i<nodes;i++)
1586
oldtopology[i] = topology[i];
1587
for(i=0;i<nodes;i++)
1588
topology[i] = oldtopology[order306[i]-1];
1589
}
1590
else if(nodes == 8) {
1591
data->elementtypes[element] = 408;
1592
for(i=0;i<nodes;i++)
1593
oldtopology[i] = topology[i];
1594
for(i=0;i<nodes;i++)
1595
topology[i] = oldtopology[order408[i]-1];
1596
}
1597
}
1598
else if(dim == 3) {
1599
if(nodes == 4) {
1600
data->elementtypes[element] = 504;
1601
}
1602
else if(nodes == 5) {
1603
data->elementtypes[element] = 605;
1604
for(i=0;i<nodes;i++)
1605
oldtopology[i] = topology[i];
1606
for(i=0;i<nodes;i++)
1607
topology[i] = oldtopology[order605[i]-1];
1608
}
1609
else if(nodes == 6) {
1610
data->elementtypes[element] = 706;
1611
}
1612
else if(nodes == 8) {
1613
for(i=0;i<nodes;i++)
1614
oldtopology[i] = topology[i];
1615
for(i=0;i<nodes;i++)
1616
topology[i] = oldtopology[order808[i]-1];
1617
}
1618
else {
1619
printf("Unknown Fidap elementtype with %d nodes.\n",nodes);
1620
}
1621
1622
}
1623
else printf("ReorderFidapNodes: unknown dimension (%d)\n",data->dim);
1624
}
1625
1626
1627
1628
1629
int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *prefix,int info)
1630
/* Load the grid from a format that can be read by FIDAP
1631
program designed for fluid mechanics.
1632
1633
Still under implementation
1634
*/
1635
{
1636
int noknots,noelements,dim,novel,maxnodes;
1637
int mode,maxknot,totelems,entity,maxentity;
1638
char filename[MAXFILESIZE];
1639
char line[MAXLINESIZE],entityname[MAXNAMESIZE];
1640
int i,j,k,*ind,geoflag,typeflag;
1641
int **topology;
1642
FILE *in;
1643
Real *vel,*temp;
1644
int nogroups,knotno;
1645
char *isio;
1646
1647
AddExtension(prefix,filename,"fidap");
1648
1649
if ((in = fopen(filename,"r")) == NULL) {
1650
AddExtension(prefix,filename,"FDNEUT");
1651
if ((in = fopen(filename,"r")) == NULL) {
1652
printf("LoadFidapInput: opening of the Fidap-file '%s' wasn't successful !\n",
1653
filename);
1654
return(1);
1655
}
1656
}
1657
1658
InitializeKnots(data);
1659
1660
entity = 0;
1661
mode = 0;
1662
noknots = 0;
1663
noelements = 0;
1664
dim = 0;
1665
maxnodes = 4;
1666
totelems = 0;
1667
maxentity = 0;
1668
1669
for(;;) {
1670
isio = GETLINE;
1671
1672
if(!isio) goto end;
1673
if(strstr(line,"END")) goto end;
1674
1675
/* Control information */
1676
if(strstr(line,"FIDAP NEUTRAL FILE")) mode = 1;
1677
else if(strstr(line,"NO. OF NODES")) mode = 2;
1678
else if(strstr(line,"TEMPERATURE/SPECIES FLAGS")) mode = 3;
1679
else if(strstr(line,"PRESSURE FLAGS")) mode = 4;
1680
else if(strstr(line,"NODAL COORDINATES")) mode = 5;
1681
else if(strstr(line,"BOUNDARY CONDITIONS")) mode = 6;
1682
else if(strstr(line,"ELEMENT GROUPS")) mode = 7;
1683
else if(strstr(line,"GROUP:")) mode = 8;
1684
else if(strstr(line,"VELOCITY")) mode = 10;
1685
else if(strstr(line,"TEMPERATURE")) mode = 11;
1686
else if(0) printf("unknown: %s",line);
1687
1688
switch (mode) {
1689
1690
case 1:
1691
if(info) printf("Loading FIDAP input file %s\n",filename);
1692
GETLINE;
1693
if(info) printf("Name of the case: %s",line);
1694
mode = 0;
1695
break;
1696
1697
case 2:
1698
GETLINE;
1699
if(0) printf("reading the header info\n");
1700
sscanf(line,"%d%d%d%d%d",&noknots,&noelements,
1701
&nogroups,&dim,&novel);
1702
data->noknots = noknots;
1703
data->noelements = noelements;
1704
data->maxnodes = maxnodes;
1705
data->dim = dim;
1706
1707
mode = 0;
1708
break;
1709
1710
case 5:
1711
if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
1712
noknots,noelements,maxnodes);
1713
AllocateKnots(data);
1714
if(info) printf("Reading the nodes\n");
1715
for(i=1;i<=noknots;i++) {
1716
GETLINE;
1717
if (dim == 2)
1718
sscanf(line,"%d%le%le",&knotno,
1719
&(data->x[i]),&(data->y[i]));
1720
else if(dim==3)
1721
sscanf(line,"%d%le%le%le",&knotno,
1722
&(data->x[i]),&(data->y[i]),&(data->z[i]));
1723
}
1724
break;
1725
1726
case 8:
1727
{
1728
int val,group,elems,nodes;
1729
char *cp;
1730
1731
i=0;
1732
do val=line[i++];
1733
while(val!=':');i++;
1734
sscanf(&line[i],"%d",&group);
1735
1736
do val=line[i++];
1737
while(val!=':');i++;
1738
sscanf(&line[i],"%d",&elems);
1739
1740
do val=line[i++];
1741
while(val!=':');i++;
1742
sscanf(&line[i],"%d",&nodes);
1743
1744
do val=line[i++];
1745
while(val!=':');i++;
1746
sscanf(&line[i],"%d",&geoflag);
1747
1748
do val=line[i++];
1749
while(val!=':');i++;
1750
sscanf(&line[i],"%d",&typeflag);
1751
1752
GETLINE;
1753
i=0;
1754
do val=line[i++];
1755
while(val!=':');i++;
1756
sscanf(&line[i],"%s",entityname);
1757
1758
if(nodes > maxnodes) {
1759
if(info) printf("Allocating a %d-node topology matrix\n",nodes);
1760
topology = Imatrix(1,noelements,0,nodes-1);
1761
if(totelems > 0) {
1762
for(j=1;j<=totelems;j++)
1763
for(i=0;i<data->elementtypes[j] % 100;i++)
1764
topology[j][i] = data->topology[j][i];
1765
}
1766
free_Imatrix(data->topology,1,data->noelements,0,data->maxnodes-1);
1767
data->maxnodes = maxnodes = nodes;
1768
data->topology = topology;
1769
}
1770
1771
if(info) printf("reading %d element topologies with %d nodes for %s\n",
1772
elems,nodes,entityname);
1773
1774
for(entity=1;entity<=maxentity;entity++) {
1775
if(!data->bodyname[entity]) break;
1776
k = strcmp(entityname,data->bodyname[entity]);
1777
if(k == 0) break;
1778
}
1779
1780
if(entity > maxentity) {
1781
maxentity++;
1782
if(!data->bodyname[entity]) data->bodyname[entity] = Cvector(0,MAXNAMESIZE);
1783
strcpy(data->bodyname[entity],entityname);
1784
if(info) printf("Found new entity: %s\n",entityname);
1785
}
1786
1787
for(i=totelems+1;i<=totelems+elems;i++) {
1788
GETLINE;
1789
1790
cp = line;
1791
j = next_int(&cp);
1792
for(j=0;j<nodes;j++)
1793
data->topology[i][j] = next_int(&cp);
1794
1795
ReorderFidapNodes(data,i,nodes,typeflag);
1796
1797
if(data->elementtypes[i] == 0) {
1798
printf("Elementtype is zero!\n");
1799
}
1800
1801
if(entity) data->material[i] = entity;
1802
else data->material[i] = group;
1803
}
1804
totelems += elems;
1805
}
1806
mode = 0;
1807
break;
1808
1809
case 10:
1810
dim = 3;
1811
if(info) printf("Reading the velocity field\n");
1812
CreateVariable(data,2,dim,0.0,"Velocity",FALSE);
1813
vel = data->dofs[2];
1814
for(j=1;j<=noknots;j++) {
1815
GETLINE;
1816
if(dim==2)
1817
sscanf(line,"%le%le",&(vel[2*j-1]),&(vel[2*j]));
1818
if(dim==3)
1819
sscanf(line,"%le%le%le",&(vel[3*j-2]),&(vel[3*j-1]),&(vel[3*j]));
1820
}
1821
mode = 0;
1822
break;
1823
1824
case 11:
1825
if(info) printf("Reading the temperature field\n");
1826
CreateVariable(data,1,1,0.0,"Temperature",FALSE);
1827
temp = data->dofs[1];
1828
for(j=1;j<=noknots;j++) {
1829
GETLINE;
1830
sscanf(line,"%le",&(temp[j]));
1831
}
1832
mode = 0;
1833
break;
1834
1835
default:
1836
break;
1837
}
1838
}
1839
1840
end:
1841
1842
/* Renumber the nodes */
1843
maxknot = 0;
1844
for(i=1;i<=noelements;i++)
1845
for(j=0;j < data->elementtypes[i]%100;j++)
1846
if(data->topology[i][j] > maxknot) maxknot = data->topology[i][j];
1847
1848
if(maxknot > noknots) {
1849
if(info) printf("Renumbering the nodes from 1 to %d\n",noknots);
1850
1851
ind = ivector(1,maxknot);
1852
for(i=1;i<=maxknot;i++)
1853
ind[i] = 0;
1854
1855
for(i=1;i<=noelements;i++)
1856
for(j=0;j < data->elementtypes[i]%100;j++)
1857
ind[data->topology[i][j]] = data->topology[i][j];
1858
i=0;
1859
for(j=1;j<=noknots;j++) {
1860
i++;
1861
while(ind[i]==0) i++;
1862
ind[i] = j;
1863
}
1864
for(i=1;i<=noelements;i++)
1865
for(j=0;j < data->elementtypes[i]%100;j++)
1866
data->topology[i][j] = ind[data->topology[i][j]];
1867
}
1868
1869
1870
if(maxentity > 0) data->bodynamesexist = TRUE;
1871
1872
fclose(in);
1873
1874
if(info) printf("Finished reading the Fidap neutral file\n");
1875
1876
ElementsToBoundaryConditions(data,boundaries,FALSE,TRUE);
1877
/* RenumberBoundaryTypes(data,boundaries,TRUE,0,info); */
1878
1879
return(0);
1880
}
1881
1882
1883
1884
static void ReorderAnsysNodes(struct FemType *data,int *oldtopology,
1885
int element,int dim,int nodes)
1886
{
1887
int i,*topology,elementtype;
1888
int order820[]={1,2,3,4,5,6,7,8,9,10,11,12,17,18,19,20,13,14,15,16};
1889
int order504[]={1,2,3,5};
1890
int order306[]={1,2,3,5,6,8};
1891
int order510[]={1,2,3,5,9,10,12,17,18,19};
1892
int order613[]={1,2,3,4,5,9,10,11,12,17,18,19,20};
1893
int order706[]={1,2,3,5,6,7};
1894
int order715[]={1,2,3,5,6,7,9,10,12,17,18,19,13,14,16};
1895
1896
elementtype = 0;
1897
if(dim == 3) {
1898
if(nodes == 20) {
1899
if(oldtopology[2] == oldtopology[3] &&
1900
oldtopology[4] == oldtopology[5]) elementtype = 510;
1901
else if(oldtopology[2] == oldtopology[3] &&
1902
oldtopology[4] != oldtopology[5]) elementtype = 715;
1903
else if(oldtopology[4] == oldtopology[5]) elementtype = 613;
1904
else elementtype = 820;
1905
}
1906
if(nodes == 8) {
1907
if(oldtopology[2] == oldtopology[3] &&
1908
oldtopology[4] == oldtopology[7] &&
1909
oldtopology[5] == oldtopology[7] &&
1910
oldtopology[6] == oldtopology[7]) elementtype = 504;
1911
else if(oldtopology[2] == oldtopology[3] &&
1912
oldtopology[6] == oldtopology[7]) elementtype = 706;
1913
else if(oldtopology[4] == oldtopology[5]) elementtype = 605;
1914
else elementtype = 808;
1915
}
1916
if(nodes == 4) elementtype = 504;
1917
if(nodes == 10) elementtype = 510;
1918
}
1919
else if(dim == 2) {
1920
if(nodes == 9) elementtype = 408;
1921
if(nodes == 8) {
1922
if(oldtopology[3] == oldtopology[6])
1923
elementtype = 306;
1924
else
1925
elementtype = 408;
1926
}
1927
if(nodes == 4) elementtype = 404;
1928
if(nodes == 10) elementtype = 310;
1929
if(nodes == 6) elementtype = 306;
1930
if(nodes == 3) elementtype = 303;
1931
}
1932
else if(dim == 1) {
1933
if(nodes == 4) elementtype = 204;
1934
if(nodes == 3) elementtype = 203;
1935
if(nodes == 2) elementtype = 202;
1936
}
1937
1938
if(!elementtype) {
1939
printf("Unknown elementtype in element %d (%d nodes, %d dim).\n",
1940
element,nodes,dim);
1941
}
1942
1943
data->elementtypes[element] = elementtype;
1944
topology = data->topology[element];
1945
1946
switch (elementtype) {
1947
1948
case 820:
1949
for(i=0;i<elementtype%100;i++)
1950
topology[i] = oldtopology[order820[i]-1];
1951
break;
1952
1953
case 504:
1954
if(nodes == 4)
1955
for(i=0;i<elementtype%100;i++)
1956
topology[i] = oldtopology[i];
1957
else
1958
for(i=0;i<elementtype%100;i++)
1959
topology[i] = oldtopology[order504[i]-1];
1960
break;
1961
1962
1963
case 510:
1964
for(i=0;i<elementtype%100;i++) {
1965
if(oldtopology[2] == oldtopology[3])
1966
topology[i] = oldtopology[order510[i]-1];
1967
else
1968
topology[i] = oldtopology[i];
1969
}
1970
break;
1971
1972
case 605:
1973
for(i=0;i<elementtype%100;i++) {
1974
topology[i] = oldtopology[i];
1975
}
1976
break;
1977
1978
case 613:
1979
for(i=0;i<elementtype%100;i++) {
1980
if(oldtopology[4] == oldtopology[5])
1981
topology[i] = oldtopology[order613[i]-1];
1982
else
1983
topology[i] = oldtopology[i];
1984
}
1985
break;
1986
1987
case 306:
1988
for(i=0;i<elementtype%100;i++) {
1989
if(oldtopology[3] == oldtopology[6])
1990
topology[i] = oldtopology[order306[i]-1];
1991
else
1992
topology[i] = oldtopology[i];
1993
}
1994
break;
1995
1996
case 706:
1997
for(i=0;i<elementtype%100;i++) {
1998
topology[i] = oldtopology[order706[i]-1];
1999
}
2000
break;
2001
2002
case 715:
2003
for(i=0;i<elementtype%100;i++) {
2004
topology[i] = oldtopology[order715[i]-1];
2005
}
2006
break;
2007
2008
default:
2009
for(i=0;i<elementtype%100;i++)
2010
topology[i] = oldtopology[i];
2011
2012
}
2013
}
2014
2015
2016
int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,
2017
char *prefix,int info)
2018
/* This procedure reads the FEM mesh as written by Ansys. */
2019
{
2020
int noknots=0,noelements=0,nosides,sidetype,currenttype;
2021
int maxindx,*indx,*revindx,topology[100],ind;
2022
int i,j,k,l,imax,*nodeindx,*boundindx,boundarynodes=0;
2023
int noansystypes,*ansysdim,*ansysnodes,*ansystypes,boundarytypes=0;
2024
int namesexist,maxside,sides;
2025
Real x,y,z;
2026
FILE *in;
2027
char *cp,line[MAXLINESIZE],filename[MAXFILESIZE],
2028
text[MAXNAMESIZE],text2[MAXNAMESIZE];
2029
2030
2031
/* ExportMesh.header */
2032
2033
sprintf(filename,"%s.header",prefix);
2034
if ((in = fopen(filename,"r")) == NULL) {
2035
printf("LoadAnsysInput: The opening of the header-file %s failed!\n",
2036
filename);
2037
return(1);
2038
}
2039
2040
if(info) printf("Calculating Ansys elementtypes from %s\n",filename);
2041
for(i=0;GETLINE;i++);
2042
2043
noansystypes = i-1;
2044
printf("There seems to be %d element types in file %s.\n",noansystypes,filename);
2045
2046
ansysdim = Ivector(1,noansystypes);
2047
ansysnodes = Ivector(1,noansystypes);
2048
ansystypes = Ivector(1,noansystypes);
2049
2050
rewind(in);
2051
for(i=0;i<=noansystypes;i++) {
2052
Real dummy1,dummy2,dummy3;
2053
GETLINE;
2054
2055
/* Ansys writes decimal points also for integers and therefore these
2056
values are read in as real numbers. */
2057
2058
sscanf(line,"%le %le %le",&dummy1,&dummy2,&dummy3);
2059
2060
if(i==0) {
2061
noelements = (int) (dummy1+0.5);
2062
noknots = (int) (dummy2+0.5);
2063
boundarytypes = (int) (dummy3+0.5);
2064
}
2065
else {
2066
ansysdim[i] = (int) (dummy1+0.5);
2067
ansysnodes[i] = (int) (dummy2+0.5);
2068
ansystypes[i] = (int) (dummy3+0.5);
2069
}
2070
}
2071
fclose(in);
2072
2073
printf("Ansys file has %d elements, %d nodes and %d boundary types.\n",
2074
noelements,noknots,boundarytypes);
2075
2076
/* ExportMesh.names */
2077
2078
sprintf(filename,"%s.names",prefix);
2079
in = fopen(filename,"r");
2080
if(in == NULL)
2081
namesexist = FALSE;
2082
else
2083
namesexist = TRUE;
2084
2085
if(namesexist) printf("Using names of bodies and boundaries\n");
2086
2087
2088
/* ExportMesh.node */
2089
2090
sprintf(filename,"%s.node",prefix);
2091
if ((in = fopen(filename,"r")) == NULL) {
2092
printf("LoadAnsysInput: The opening of the nodes-file %s failed!\n",
2093
filename);
2094
return(2);
2095
}
2096
2097
if(info) printf("Calculating Ansys nodes from %s\n",filename);
2098
for(i=0;GETLINE;i++);
2099
2100
if(info) printf("There seems to be %d nodes in file %s.\n",i,filename);
2101
if(i != noknots) printf("Conflicting number of nodes %d vs %d!\n",i,noknots);
2102
2103
/* Make room and initialize the mesh */
2104
InitializeKnots(data);
2105
2106
/* Even 2D elements may form a 3D object! */
2107
data->dim = 3;
2108
data->maxnodes = 1;
2109
2110
for(i=1;i<=noansystypes;i++) {
2111
if(ansysdim[i] > data->dim) data->dim = ansysdim[i];
2112
if(ansysnodes[i] > data->maxnodes) data->maxnodes = ansysnodes[i];
2113
}
2114
if(data->maxnodes < 8) data->maxnodes = 8;
2115
2116
data->noknots = noknots;
2117
data->noelements = noelements;
2118
2119
if(info) printf("Allocating for %d nodes and %d elements with max. %d nodes in %d-dim.\n",
2120
noknots,noelements,data->maxnodes,data->dim);
2121
AllocateKnots(data);
2122
2123
indx = Ivector(1,noknots);
2124
for(i=1;i<=noknots;i++) indx[i] = 0;
2125
2126
if(info) printf("Loading %d Ansys nodes from %s\n",noknots,filename);
2127
rewind(in);
2128
for(i=1;i<=noknots;i++) {
2129
GETLINE; cp=line;
2130
2131
indx[i] = next_int(&cp);
2132
if(cp[0] == '.') cp++;
2133
2134
x = next_real(&cp);
2135
if(!cp) x = y = z = 0.0;
2136
else {
2137
y = next_real(&cp);
2138
if(!cp) y = z = 0.0;
2139
else if(data->dim == 3) {
2140
z = next_real(&cp);
2141
if(!cp) z = 0.0;
2142
}
2143
}
2144
data->x[i] = x;
2145
data->y[i] = y;
2146
if(data->dim == 3) data->z[i] = z;
2147
}
2148
fclose(in);
2149
2150
/* reorder the indexes */
2151
maxindx = indx[1];
2152
for(i=1;i<=noknots;i++)
2153
if(indx[i] > maxindx) maxindx = indx[i];
2154
revindx = Ivector(0,maxindx);
2155
2156
if(maxindx > noknots) {
2157
printf("There are %d nodes with indexes up to %d.\n",
2158
noknots,maxindx);
2159
for(i=1;i<=maxindx;i++)
2160
revindx[i] = 0;
2161
for(i=1;i<=noknots;i++)
2162
revindx[indx[i]] = i;
2163
}
2164
else {
2165
for(i=1;i<=noknots;i++)
2166
revindx[i] = i;
2167
}
2168
2169
/* ExportMesh.elem */
2170
2171
sprintf(filename,"%s.elem",prefix);
2172
if ((in = fopen(filename,"r")) == NULL) {
2173
printf("LoadAnsysInput: The opening of the element-file %s failed!\n",
2174
filename);
2175
return(4);
2176
}
2177
2178
if(info) printf("Loading %d Ansys elements from %s\n",noelements,filename);
2179
2180
for(j=1;j<=noelements;j++) {
2181
2182
GETLINE;
2183
cp=line;
2184
2185
for(i=0;i<8;i++) {
2186
if (noknots < 1000000) {
2187
ind = next_int(&cp);
2188
}
2189
else if (noknots < 100000000) {
2190
ind = next_int_n(&cp,8);
2191
}
2192
else {
2193
ind = next_int_n(&cp,10);
2194
}
2195
if(cp[0] == '.') cp++;
2196
topology[i] = revindx[ind];
2197
}
2198
2199
data->material[j] = next_int(&cp);
2200
currenttype = next_int(&cp);
2201
2202
for(k=1;k<=noansystypes;k++)
2203
if(ansystypes[k] == currenttype) break;
2204
if(ansystypes[k] != currenttype) k=1;
2205
2206
if(ansysnodes[k] > 8) {
2207
GETLINE;
2208
cp=line;
2209
2210
if(ansysnodes[k] == 10 && topology[2] != topology[3])
2211
imax = 10;
2212
else
2213
imax = 20;
2214
2215
for(i=8;i<imax;i++) {
2216
if (noknots < 1000000) {
2217
ind = next_int(&cp);
2218
}
2219
else if (noknots < 100000000) {
2220
ind = next_int_n(&cp,8);
2221
}
2222
else {
2223
ind = next_int_n(&cp,10);
2224
}
2225
if(cp[0] == '.') cp++;
2226
topology[i] = revindx[ind];
2227
}
2228
}
2229
2230
ReorderAnsysNodes(data,&topology[0],j,ansysdim[k],ansysnodes[k]);
2231
}
2232
fclose(in);
2233
2234
2235
/* ExportMesh.boundary */
2236
2237
sprintf(filename,"%s.boundary",prefix);
2238
printf("Calculating nodes in file %s\n",filename);
2239
if ((in = fopen(filename,"r")) == NULL) {
2240
printf("LoadAnsysInput: The opening of the boundary-file %s failed!\n",
2241
filename);
2242
return(5);
2243
}
2244
2245
j = 0;
2246
for(i=0;GETLINE;i++)
2247
if(!strstr(line,"Boundary")) j++;
2248
2249
boundarynodes = j;
2250
nosides = 6*boundarynodes;
2251
2252
if(info) printf("There are %d boundary nodes, allocating %d elements\n",
2253
boundarynodes,nosides);
2254
AllocateBoundary(bound,nosides);
2255
nodeindx = Ivector(1,boundarynodes);
2256
boundindx = Ivector(1,boundarynodes);
2257
2258
if(info) printf("Loading Ansys boundary from %s\n",filename);
2259
2260
for(i=1;i<=boundarynodes;i++) nodeindx[i] = boundindx[i] = 0;
2261
2262
rewind(in);
2263
maxside = 0;
2264
j = 0;
2265
for(i=0;GETLINE;i++) {
2266
if(strstr(line,"Boundary")) {
2267
sscanf(line,"%d",&sidetype);
2268
maxside = MAX(sidetype,maxside);
2269
}
2270
else {
2271
j++;
2272
sscanf(line,"%d",&k);
2273
nodeindx[j] = revindx[k];
2274
if(!nodeindx[j]) printf("The boundary %dth node %d is not in index list\n",j,k);
2275
boundindx[j] = sidetype;
2276
}
2277
}
2278
printf("Found %d boundary nodes with %d as maximum side.\n",j,maxside);
2279
fclose(in);
2280
2281
FindPointParents(data,bound,boundarynodes,nodeindx,boundindx,info);
2282
2283
if(namesexist) {
2284
int bcind=0,*bctypes=NULL,*bctypeused=NULL,*bcused=NULL,newsides=0;
2285
2286
data->bodynamesexist = TRUE;
2287
if(bound[0].nosides) {
2288
newsides = 0;
2289
bctypes = Ivector(1,maxside);
2290
bctypeused = Ivector(1,maxside);
2291
bcused = Ivector(1,bound[0].nosides);
2292
for(i=1;i<=bound[0].nosides;i++) bcused[i] = FALSE;
2293
data->boundarynamesexist = TRUE;
2294
for(i=1;i<=maxside;i++)
2295
bctypeused[i] = FALSE;
2296
}
2297
2298
sprintf(filename,"%s.names",prefix);
2299
in = fopen(filename,"r");
2300
2301
for(;;) {
2302
if(Getrow(line,in,TRUE)) break;
2303
sscanf(line,"%d%s%s%d",&bcind,&text[0],&text2[0],&sides);
2304
2305
if(strstr(text2,"BODY")) {
2306
GETLINE;
2307
sscanf(line,"%d%d",&j,&bcind);
2308
if(!data->bodyname[bcind]) data->bodyname[bcind] = Cvector(0,MAXNAMESIZE);
2309
strcpy(data->bodyname[bcind],text);
2310
}
2311
else if(strstr(text2,"BOUNDARY")) {
2312
/* Read the boundary groups belonging to a particular name */
2313
for(i=1;i<=maxside;i++)
2314
bctypes[i] = 0;
2315
for(i=1;i<=sides;i++) {
2316
GETLINE;
2317
sscanf(line,"%d%d",&j,&bcind);
2318
bctypes[bcind] = TRUE;
2319
}
2320
2321
/* Find 1st unused boundarytype */
2322
for(i=1;i<=maxside;i++)
2323
if(bctypes[i] && !bctypeused[i]) break;
2324
2325
bcind = i;
2326
bctypeused[bcind] = TRUE;
2327
if(0) printf("First unused boundary is of type %d\n",bcind);
2328
if(bcind>MAXBCS) bigerror("bcind larger than MAXBCS!");
2329
if(!data->boundaryname[bcind]) data->boundaryname[bcind] = Cvector(0,MAXNAMESIZE);
2330
strcpy(data->boundaryname[bcind],text);
2331
2332
/* Check which of the BCs have already been named */
2333
k = l = 0;
2334
for(i=1;i<=bound[0].nosides;i++) {
2335
j = bound[0].types[i];
2336
2337
/* The bc is not given any name, hence it can't be a duplicate */
2338
if(!bctypes[j]) continue;
2339
2340
if(!bcused[i]) {
2341
k++;
2342
bcused[i] = bcind;
2343
}
2344
else {
2345
l++;
2346
if(newsides == 0) AllocateBoundary(&bound[1],bound[0].nosides);
2347
newsides++;
2348
bound[1].types[newsides] = bcind;
2349
bound[1].parent[newsides] = bound[0].parent[i];
2350
bound[1].side[newsides] = bound[0].side[i];
2351
bound[1].parent2[newsides] = bound[0].parent2[i];
2352
bound[1].side2[newsides] = bound[0].side2[i];
2353
bound[1].normal[newsides] = bound[0].normal[i];
2354
}
2355
}
2356
if(info) {
2357
if(data->boundaryname[bcind])
2358
printf("There are %d boundary elements with name %s.\n",k+l,data->boundaryname[bcind]);
2359
}
2360
}
2361
}
2362
2363
fclose(in);
2364
2365
/* Put the indexes of all conditions with the same name to be same */
2366
if(bound[0].nosides) {
2367
for(i=1;i<=bound[0].nosides;i++)
2368
if(bcused[i]) bound[0].types[i] = bcused[i];
2369
if(newsides) {
2370
bound[1].nosides = newsides;
2371
if(info) printf("Created %d additional boundary elements to achieve unique naming.\n",newsides);
2372
}
2373
free_Ivector(bctypes,1,maxside);
2374
free_Ivector(bctypeused,1,maxside);
2375
free_Ivector(bcused,1,bound[0].nosides);
2376
}
2377
}
2378
2379
free_Ivector(boundindx,1,boundarynodes);
2380
free_Ivector(nodeindx,1,boundarynodes);
2381
2382
if(info) printf("Ansys mesh loaded successfully\n");
2383
2384
return(0);
2385
}
2386
2387
2388
static void ReorderFieldviewNodes(struct FemType *data,int *oldtopology,
2389
int element,int dim,int nodes)
2390
{
2391
int i,*topology,elementtype;
2392
int order808[]={1,2,4,3,5,6,8,7};
2393
int order706[]={1,4,6,2,3,5};
2394
int order404[]={1,2,3,4};
2395
2396
elementtype = 0;
2397
if(dim == 3) {
2398
if(nodes == 8) elementtype = 808;
2399
if(nodes == 6) elementtype = 706;
2400
if(nodes == 4) elementtype = 504;
2401
}
2402
else if(dim == 2) {
2403
if(nodes == 4) elementtype = 404;
2404
if(nodes == 3) elementtype = 303;
2405
}
2406
2407
if(!elementtype) {
2408
printf("Unknown elementtype in element %d (%d nodes, %d dim).\n",
2409
element,nodes,dim);
2410
bigerror("Cannot continue");
2411
}
2412
2413
data->elementtypes[element] = elementtype;
2414
topology = data->topology[element];
2415
2416
for(i=0;i<elementtype%100;i++) {
2417
if(elementtype == 808) topology[i] = oldtopology[order808[i]-1];
2418
else if(elementtype == 706) topology[i] = oldtopology[order706[i]-1];
2419
else if(elementtype == 404) topology[i] = oldtopology[order404[i]-1];
2420
else topology[i] = oldtopology[i];
2421
}
2422
}
2423
2424
2425
2426
2427
int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info)
2428
/* Load the grid from a format that can be read by FieldView
2429
program by PointWise. This is a suitable format to read files created
2430
by GridGen. */
2431
{
2432
int noknots,noelements,maxnodes,mode;
2433
char filename[MAXFILESIZE];
2434
char line[MAXLINESIZE],*cp;
2435
int i,j,k;
2436
FILE *in;
2437
Real x,y,z;
2438
int maxindx;
2439
char *isio;
2440
int nobound=0,nobulk=0,maxsidenodes;
2441
int *boundtypes=NULL,**boundtopos=NULL,*boundnodes=NULL,*origtopology=NULL;
2442
2443
if ((in = fopen(prefix,"r")) == NULL) {
2444
AddExtension(prefix,filename,"dat");
2445
if ((in = fopen(filename,"r")) == NULL) {
2446
printf("LoadFieldviewInput: opening of the Fieldview-file '%s' wasn't successful !\n",
2447
filename);
2448
return(1);
2449
}
2450
}
2451
2452
InitializeKnots(data);
2453
data->dim = 3;
2454
data->created = TRUE;
2455
2456
mode = 0;
2457
noknots = 0;
2458
noelements = 0;
2459
maxnodes = 8;
2460
maxsidenodes = 4;
2461
maxindx = 0;
2462
2463
data->maxnodes = maxnodes;
2464
2465
for(;;) {
2466
2467
if(mode == 0) {
2468
isio = GETLINE;
2469
2470
if(!isio) goto end;
2471
if(strstr(line,"END")) goto end;
2472
2473
/* Control information */
2474
if(strstr(line,"FIELDVIEW")) mode = 1;
2475
else if(strstr(line,"CONSTANTS")) mode = 2;
2476
else if(strstr(line,"GRIDS")) mode = 3;
2477
else if(strstr(line,"Boundary Table")) mode = 4;
2478
else if(strstr(line,"Variable Names")) mode = 5;
2479
else if(strstr(line,"Nodes")) mode = 6;
2480
else if(strstr(line,"Boundary Faces")) mode = 7;
2481
else if(strstr(line,"Elements")) mode = 8;
2482
else if(strstr(line,"Variables")) mode = 9;
2483
else if(0) printf("unknown: %s",line);
2484
}
2485
2486
switch (mode) {
2487
2488
case 1:
2489
printf("This is indeed a Fieldview input file.\n");
2490
mode = 0;
2491
break;
2492
2493
case 2:
2494
if(0) printf("Constants block\n");
2495
mode = 0;
2496
break;
2497
2498
case 3:
2499
if(0) printf("Grids block\n");
2500
mode = 0;
2501
break;
2502
2503
case 4:
2504
if(0) printf("Boundary Table\n");
2505
mode = 0;
2506
break;
2507
2508
case 5:
2509
if(0) printf("Variable names\n");
2510
mode = 0;
2511
break;
2512
2513
case 6:
2514
2515
GETLINE;
2516
sscanf(line,"%d",&noknots);
2517
data->noknots = noknots;
2518
2519
if(info) printf("Loading %d node coordinates\n",noknots);
2520
2521
data->x = Rvector(1,noknots);
2522
data->y = Rvector(1,noknots);
2523
data->z = Rvector(1,noknots);
2524
2525
for(i=1;i<=noknots;i++) {
2526
GETLINE;
2527
sscanf(line,"%le%le%le",&x,&y,&z);
2528
data->x[i] = x;
2529
data->y[i] = y;
2530
data->z[i] = z;
2531
}
2532
mode = 0;
2533
break;
2534
2535
case 7:
2536
2537
GETLINE;
2538
sscanf(line,"%d",&nobound);
2539
2540
if(info) printf("Loading %d boundary element definitions\n",nobound);
2541
2542
boundtypes = Ivector(1,nobound);
2543
boundtopos = Imatrix(1,nobound,0,maxsidenodes-1);
2544
boundnodes = Ivector(1,nobound);
2545
2546
for(i=1;i<=nobound;i++) {
2547
GETLINE; cp=line;
2548
2549
boundtypes[i]= next_int(&cp);
2550
maxsidenodes = next_int(&cp);
2551
2552
for(j=0;j<maxsidenodes && cp;j++)
2553
boundtopos[i][j] = next_int(&cp);
2554
2555
boundnodes[i] = j;
2556
}
2557
mode = 0;
2558
break;
2559
2560
2561
case 8:
2562
2563
if(info) printf("Loading bulk element definitions\n");
2564
2565
if(maxsidenodes == 4) noelements = noknots + nobound;
2566
else noelements = 6*noknots + nobound;
2567
2568
origtopology = Ivector(0,maxnodes-1);
2569
data->topology = Imatrix(1,noelements,0,maxnodes-1);
2570
data->material = Ivector(1,noelements);
2571
data->elementtypes = Ivector(1,noelements);
2572
2573
for(i=0;;) {
2574
GETLINE; cp=line;
2575
2576
if(strstr(line,"Variables")) mode = 9;
2577
if(mode != 8) break;
2578
2579
i++;
2580
2581
k = next_int(&cp);
2582
2583
if(k == 2) maxnodes = 8;
2584
else if(k == 1) maxnodes = 4;
2585
2586
data->material[i]= next_int(&cp);
2587
2588
for(j=0;j<maxnodes && cp;j++) {
2589
origtopology[j] = next_int(&cp);
2590
if(maxindx < origtopology[j]) maxindx = origtopology[j];
2591
}
2592
2593
ReorderFieldviewNodes(data,origtopology,i,3,j);
2594
2595
if(nobulk+nobound == noelements+1)
2596
printf("Too few elements (%d) were allocated!!\n",noelements);
2597
2598
}
2599
nobulk = i;
2600
2601
printf("Found %d bulk elements\n",nobulk);
2602
if(nobulk+nobound > noelements) printf("Too few elements (%d) were allocated!!\n",noelements);
2603
printf("Allocated %.4lg %% too many elements\n",
2604
noelements*100.0/(nobulk+nobound)-100.0);
2605
2606
2607
for(i=1;i<=nobound;i++) {
2608
ReorderFieldviewNodes(data,boundtopos[i],i+nobulk,2,boundnodes[i]);
2609
data->material[i+nobulk] = boundtypes[i];
2610
}
2611
2612
data->noelements = noelements = nobulk + nobound;
2613
2614
mode = 0;
2615
break;
2616
2617
2618
case 9:
2619
2620
printf("Variables\n");
2621
2622
mode = 0;
2623
break;
2624
2625
default:
2626
break;
2627
}
2628
}
2629
2630
end:
2631
2632
if(maxindx != noknots)
2633
printf("The maximum index %d differs from the number of nodes %d !\n",maxindx,noknots);
2634
2635
ElementsToBoundaryConditions(data,bound,FALSE,TRUE);
2636
2637
return(0);
2638
}
2639
2640
2641
2642
2643
int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
2644
char *prefix,int info)
2645
/* This procedure reads the mesh assuming Triangle format
2646
*/
2647
{
2648
int noknots,noelements,maxnodes,elematts,nodeatts,dim;
2649
int elementtype,bcmarkers,sideelemtype,offset,bcinds;
2650
int i,ii,j,k,jmin,jmax,kmin,kmax,*boundnodes;
2651
FILE *in;
2652
char *cp,line[MAXLINESIZE],elemfile[MAXFILESIZE],nodefile[MAXFILESIZE],
2653
polyfile[MAXLINESIZE];
2654
int *invrow,*invcol;
2655
2656
2657
if(info) printf("Loading mesh in Triangle format from file %s.*\n",prefix);
2658
2659
sprintf(nodefile,"%s.node",prefix);
2660
if ((in = fopen(nodefile,"r")) == NULL) {
2661
printf("LoadTriangleInput: The opening of the nodes file %s failed!\n",nodefile);
2662
return(1);
2663
}
2664
else
2665
printf("Loading nodes from file %s\n",nodefile);
2666
2667
GETLINE;
2668
sscanf(line,"%d %d %d %d",&noknots,&dim,&nodeatts,&bcmarkers);
2669
fclose(in);
2670
2671
if(dim != 2) {
2672
printf("LoadTriangleInput assumes that the space dimension is 2, not %d.\n",dim);
2673
return(2);
2674
}
2675
2676
sprintf(elemfile,"%s.ele",prefix);
2677
if ((in = fopen(elemfile,"r")) == NULL) {
2678
printf("LoadTriangleInput: The opening of the element file %s failed!\n",elemfile);
2679
return(3);
2680
}
2681
else
2682
printf("Loading elements from file %s\n",elemfile);
2683
2684
GETLINE;
2685
sscanf(line,"%d %d %d",&noelements,&maxnodes,&elematts);
2686
fclose(in);
2687
2688
2689
InitializeKnots(data);
2690
data->dim = dim;
2691
data->maxnodes = maxnodes;
2692
data->noelements = noelements;
2693
data->noknots = noknots;
2694
elementtype = 300 + maxnodes;
2695
bcinds = FALSE;
2696
2697
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
2698
AllocateKnots(data);
2699
2700
boundnodes = Ivector(1,noknots);
2701
for(i=1;i<=noknots;i++)
2702
boundnodes[i] = 0;
2703
2704
k = 0;
2705
jmax = 0;
2706
jmin = noknots;
2707
in = fopen(nodefile,"r");
2708
GETLINE;
2709
for(i=1; i <= noknots; i++) {
2710
GETLINE;
2711
cp = line;
2712
j = next_int(&cp);
2713
if(j != i) k++;
2714
jmax = MAX(jmax,j);
2715
jmin = MIN(jmin,j);
2716
2717
data->x[i] = next_real(&cp);
2718
data->y[i] = next_real(&cp);
2719
for(j=0;j<nodeatts;j++) {
2720
next_real(&cp);
2721
}
2722
if(bcmarkers > 0)
2723
boundnodes[i] = next_int(&cp);
2724
}
2725
fclose(in);
2726
if(info) {
2727
printf("LoadTriangleInput: Node index different from order index for %d nodes\n",k);
2728
printf("LoadTriangleInput: Node index ranged was [%d %d]\n",jmin,jmax);
2729
}
2730
2731
offset = 0;
2732
if(jmin==0) {
2733
printf("LoadTriangleInput: Using offset 1 to because of C-type indexing!\n");
2734
offset = 1;
2735
}
2736
2737
2738
k = 0;
2739
jmax = 0;
2740
jmin = noelements;
2741
kmax = 0;
2742
kmin = noknots;
2743
in = fopen(elemfile,"r");
2744
GETLINE;
2745
for(i=1; i <= noelements; i++) {
2746
GETLINE;
2747
cp = line;
2748
data->elementtypes[i] = elementtype;
2749
j = next_int(&cp);
2750
if(j != i) k++;
2751
jmin = MIN(jmin,j);
2752
jmax = MAX(jmax,j);
2753
for(j=0;j<3;j++)
2754
data->topology[i][j] = next_int(&cp);
2755
if(maxnodes == 6) {
2756
data->topology[i][4] = next_int(&cp);
2757
data->topology[i][5] = next_int(&cp);
2758
data->topology[i][3] = next_int(&cp);
2759
}
2760
if(offset) {
2761
for(j=0;j<maxnodes;j++) data->topology[i][j] = data->topology[i][j]+offset;
2762
}
2763
for(j=0;j<maxnodes;j++) kmax = MAX(kmax,data->topology[i][j]);
2764
for(j=0;j<maxnodes;j++) kmin = MIN(kmin,data->topology[i][j]);
2765
j = next_int(&cp);
2766
data->material[i] = MAX(1,j);
2767
}
2768
fclose(in);
2769
if(info) {
2770
printf("LoadTriangleInput: Element index different from order index for %d nodes\n",k);
2771
printf("LoadTriangleInput: Element index ranged was [%d %d]\n",jmin,jmax);
2772
printf("LoadTriangleInput: Node indexes in elements range [%d %d] (with offset)\n",kmin,kmax);
2773
}
2774
2775
2776
sprintf(polyfile,"%s.edge",prefix);
2777
if ((in = fopen(polyfile,"r")) == NULL) {
2778
printf("LoadTriangleInput: The opening of the poly file %s failed!\n",polyfile);
2779
return(1);
2780
}
2781
else
2782
printf("Loading boundaries from file %s\n",polyfile);
2783
2784
{
2785
int bcelems,markers,ind1,ind2,bctype,j2,k2,hit;
2786
int elemsides,sideind[2],side,elemind=0;
2787
2788
bctype = 1;
2789
elemsides = 3;
2790
hit = FALSE;
2791
2792
GETLINE;
2793
sscanf(line,"%d %d",&bcelems,&markers);
2794
2795
if(bcelems == 0) goto finish;
2796
2797
if(info) printf("Allocating for %d boundary elements.\n",bcelems);
2798
2799
CreateInverseTopology(data,info);
2800
invrow = data->invtopo.rows;
2801
invcol = data->invtopo.cols;
2802
2803
AllocateBoundary(bound,bcelems);
2804
2805
jmin = noknots;
2806
jmax = 0;
2807
2808
i = 0;
2809
for(ii=1;ii<=bcelems;ii++) {
2810
GETLINE;
2811
if(markers)
2812
sscanf(line,"%d %d %d %d",&j,&ind1,&ind2,&bctype);
2813
else
2814
sscanf(line,"%d %d %d",&j,&ind1,&ind2);
2815
2816
if(!bctype) continue;
2817
i += 1;
2818
2819
bctype = abs(bctype);
2820
2821
ind1 += offset;
2822
ind2 += offset;
2823
2824
jmin = MIN(jmin,MIN(ind1,ind2));
2825
jmax = MAX(jmax,MAX(ind1,ind2));
2826
2827
/* find an element which owns both the nodes */
2828
for(j=invrow[ind1-1];j<invrow[ind1];j++) {
2829
k = invcol[j]+1;
2830
hit = FALSE;
2831
2832
for(j2=invrow[ind2-1];j2<invrow[ind2];j2++) {
2833
k2 = invcol[j2]+1;
2834
if(k == k2) {
2835
hit = TRUE;
2836
elemind = k;
2837
break;
2838
}
2839
}
2840
if(hit) break;
2841
}
2842
2843
/* Find the correct side of the triangular element */
2844
if(hit) {
2845
k = 0;
2846
for(side=0;side<elemsides;side++) {
2847
GetElementSide(elemind,side,1,data,&sideind[0],&sideelemtype);
2848
2849
hit = FALSE;
2850
if(sideind[0] == ind1 && sideind[1] == ind2) hit = TRUE;
2851
if(sideind[0] == ind2 && sideind[1] == ind1) hit = TRUE;
2852
2853
if(hit) break;
2854
}
2855
}
2856
2857
if(hit) {
2858
bound->parent[i] = elemind;
2859
bound->side[i] = side;
2860
} else {
2861
bound->parent[i] = 0;
2862
bound->side[i] = 0;
2863
if(!bcinds) {
2864
bound->topology = Imatrix(1,bcelems,0,1);
2865
bcinds = TRUE;
2866
}
2867
bound->topology[i][0] = ind1;
2868
bound->topology[i][1] = ind2;
2869
}
2870
bound->parent2[i] = 0;
2871
bound->side2[i] = 0;
2872
bound->types[i] = bctype;
2873
k++;
2874
2875
if(0) printf("LoadTriangleInput: %d boundary elements found correctly out of %d\n",k,elemsides);
2876
2877
}
2878
bound->nosides = i;
2879
printf("LoadTriangleInput: Node indexes in boundary range [%d %d] (with offset)\n",jmin,jmax);
2880
2881
}
2882
2883
finish:
2884
printf("Successfully read the mesh from the Triangle input file.\n");
2885
2886
return(0);
2887
}
2888
2889
2890
2891
2892
int LoadMeditInput(struct FemType *data,struct BoundaryType *bound,
2893
char *prefix,int info)
2894
/* This procedure reads the mesh assuming Medit format
2895
*/
2896
{
2897
int noknots=0,noelements=0,maxnodes,dim=0,elementtype=0;
2898
int i,j,allocated;
2899
FILE *in;
2900
char *cp,line[MAXLINESIZE],nodefile[MAXFILESIZE];
2901
2902
2903
sprintf(nodefile,"%s.mesh",prefix);
2904
if(info) printf("Loading mesh in Medit format from file %s\n",prefix);
2905
2906
if ((in = fopen(nodefile,"r")) == NULL) {
2907
printf("LoadMeditInput: The opening of the mesh file %s failed!\n",nodefile);
2908
return(1);
2909
}
2910
2911
allocated = FALSE;
2912
maxnodes = 0;
2913
2914
allocate:
2915
2916
if(allocated) {
2917
InitializeKnots(data);
2918
data->dim = dim;
2919
data->maxnodes = maxnodes;
2920
data->noelements = noelements;
2921
data->noknots = noknots;
2922
elementtype = 300 + maxnodes;
2923
2924
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
2925
AllocateKnots(data);
2926
in = fopen(nodefile,"r");
2927
}
2928
2929
2930
for(;;) {
2931
if(Getrow(line,in,TRUE)) goto end;
2932
if(strstr(line,"END")) goto end;
2933
2934
if(strstr(line,"DIMENSION")) {
2935
if(Getrow(line,in,TRUE)) goto end;
2936
cp = line;
2937
dim = next_int(&cp);
2938
printf("dim = %d %s",dim,line);
2939
}
2940
else if(strstr(line,"VERTICES")) {
2941
printf("verts: %s",line);
2942
2943
if(Getrow(line,in,TRUE)) goto end;
2944
cp = line;
2945
noknots = next_int(&cp);
2946
2947
printf("noknots = %d %s",noknots,line);
2948
2949
for(i=1; i <= noknots; i++) {
2950
GETLINE;
2951
if(allocated) {
2952
cp = line;
2953
data->x[i] = next_real(&cp);
2954
data->y[i] = next_real(&cp);
2955
if(dim > 2) data->z[i] = next_real(&cp);
2956
}
2957
}
2958
}
2959
else if(strstr(line,"TRIANGLES")) {
2960
if(Getrow(line,in,TRUE)) goto end;
2961
cp = line;
2962
noelements = next_int(&cp);
2963
2964
printf("noelements = %d %s",noelements,line);
2965
2966
elementtype = 303;
2967
if(maxnodes < 3) maxnodes = 3;
2968
2969
for(i=1; i <= noelements; i++) {
2970
GETLINE;
2971
if(allocated) {
2972
cp = line;
2973
data->elementtypes[i] = elementtype;
2974
for(j=0;j<3;j++)
2975
data->topology[i][j] = next_int(&cp);
2976
data->material[i] = next_int(&cp);
2977
}
2978
}
2979
}
2980
#if 0
2981
else printf("unknown command: %s",line);
2982
#endif
2983
}
2984
2985
end:
2986
fclose(in);
2987
2988
printf("ALLOCATED=%d\n",allocated);
2989
2990
if(!allocated) {
2991
allocated = TRUE;
2992
goto allocate;
2993
}
2994
2995
printf("Successfully read the mesh from the Medit input file.\n");
2996
2997
return(0);
2998
}
2999
3000
3001
3002
3003
int LoadGidInput(struct FemType *data,struct BoundaryType *bound,
3004
char *prefix,int info)
3005
/* Load the grid from GID mesh format */
3006
{
3007
int noknots,noelements,maxnodes,foundsame;
3008
int mode,allocated,nosides,sideelemtype;
3009
int boundarytype,side,parent,elemsides,materialtype=0;
3010
int dim=0, elemnodes=0, elembasis=0, elemtype=0, bulkdone, usedmax=0,hits;
3011
int minbulk,maxbulk,minbound,maxbound,label,debug;
3012
int *usedno=NULL, **usedelem=NULL;
3013
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
3014
int i,j,k,n,ind,inds[MAXNODESD2],sideind[MAXNODESD1];
3015
FILE *in;
3016
Real x,y,z;
3017
3018
debug = FALSE;
3019
3020
strcpy(filename,prefix);
3021
if ((in = fopen(filename,"r")) == NULL) {
3022
AddExtension(prefix,filename,"msh");
3023
if ((in = fopen(filename,"r")) == NULL) {
3024
printf("LoadGidInput: opening of the GID-file '%s' wasn't successful !\n",
3025
filename);
3026
return(1);
3027
}
3028
}
3029
3030
printf("Reading mesh from GID file %s.\n",filename);
3031
InitializeKnots(data);
3032
3033
allocated = FALSE;
3034
3035
/* Because the file format doesn't provide the number of elements
3036
or nodes the results are read twice but registered only in the
3037
second time. */
3038
3039
minbulk = minbound = 1000;
3040
maxbulk = maxbound = 0;
3041
3042
omstart:
3043
3044
mode = 0;
3045
maxnodes = 0;
3046
noknots = 0;
3047
noelements = 0;
3048
boundarytype = 0;
3049
nosides = 0;
3050
bulkdone = FALSE;
3051
3052
for(;;) {
3053
3054
if(Getrow(line,in,FALSE)) goto end;
3055
3056
if(strstr(line,"MESH")) {
3057
if(debug) printf("MESH\n");
3058
3059
if(strstr(line,"dimension 3"))
3060
dim = 3;
3061
else if(strstr(line,"dimension 2"))
3062
dim = 2;
3063
else printf("Unknown dimension\n");
3064
3065
if(strstr(line,"ElemType Tetrahedra"))
3066
elembasis = 500;
3067
else if(strstr(line,"ElemType Triangle"))
3068
elembasis = 300;
3069
else if(strstr(line,"ElemType Linear"))
3070
elembasis = 200;
3071
else printf("Unknown elementtype: %s\n",line);
3072
3073
if(strstr(line,"Nnode 4"))
3074
elemnodes = 4;
3075
else if(strstr(line,"Nnode 3"))
3076
elemnodes = 3;
3077
else if(strstr(line,"Nnode 2"))
3078
elemnodes = 2;
3079
else printf("Unknown elementnode: %s\n",line);
3080
3081
if(elemnodes > maxnodes) maxnodes = elemnodes;
3082
elemtype = elembasis + elemnodes;
3083
mode = 0;
3084
3085
if(debug) printf("dim=%d elemtype=%d\n",dim,elemtype);
3086
}
3087
else if(strstr(line,"Coordinates")) {
3088
if(debug) printf("Start coords\n");
3089
mode = 1;
3090
}
3091
else if(strstr(line,"end coordinates")) {
3092
if(debug) printf("End coords\n");
3093
mode = 0;
3094
}
3095
else if(strstr(line,"Elements")) {
3096
if(bulkdone) {
3097
if(debug) printf("Start boundary elems\n");
3098
mode = 3;
3099
boundarytype++;
3100
}
3101
else {
3102
if(debug) printf("Start bulk elems\n");
3103
mode = 2;
3104
}
3105
}
3106
else if(strstr(line,"end elements")) {
3107
if(debug) printf("End elems\n");
3108
3109
mode = 0;
3110
if(!bulkdone && allocated) {
3111
usedno = Ivector(1,data->noknots);
3112
3113
for(j=1;j<=data->noknots;j++)
3114
usedno[j] = 0;
3115
3116
for(j=1;j<=data->noelements;j++) {
3117
n = data->elementtypes[j] % 100;
3118
for(i=0;i<n;i++) {
3119
ind = data->topology[j][i];
3120
usedno[data->topology[j][i]] += 1;
3121
}
3122
}
3123
3124
usedmax = 0;
3125
for(i=1;i<=data->noknots;i++)
3126
if(usedno[i] > usedmax) usedmax = usedno[i];
3127
3128
for(j=1;j<=data->noknots;j++)
3129
usedno[j] = 0;
3130
3131
usedelem = Imatrix(1,data->noknots,1,usedmax);
3132
for(j=1;j<=data->noknots;j++)
3133
for(i=1;i<=usedmax;i++)
3134
usedelem[j][i] = 0;
3135
3136
for(j=1;j<=data->noelements;j++) {
3137
n = data->elementtypes[j] % 100;
3138
for(i=0;i<n;i++) {
3139
ind = data->topology[j][i];
3140
usedno[ind] += 1;
3141
k = usedno[ind];
3142
usedelem[ind][k] = j;
3143
}
3144
}
3145
}
3146
bulkdone = TRUE;
3147
}
3148
else if(!mode) {
3149
if(debug) printf("mode: %d %s\n",mode,line);
3150
}
3151
else if(mode) {
3152
switch (mode) {
3153
3154
case 1:
3155
cp = line;
3156
ind = next_int(&cp);
3157
if(ind > noknots) noknots = ind;
3158
3159
x = next_real(&cp);
3160
y = next_real(&cp);
3161
if(dim == 3) z = next_real(&cp);
3162
3163
if(allocated) {
3164
data->x[ind] = x;
3165
data->y[ind] = y;
3166
if(dim == 3) data->z[ind] = z;
3167
}
3168
break;
3169
3170
case 2:
3171
cp = line;
3172
ind = next_int(&cp);
3173
if(ind > noelements) noelements = ind;
3174
3175
for(i=0;i<elemnodes;i++) {
3176
k = next_int(&cp);
3177
if(allocated) {
3178
data->topology[ind][i] = k;
3179
data->elementtypes[ind] = elemtype;
3180
data->material[ind] = 1;
3181
}
3182
}
3183
label = next_int(&cp);
3184
3185
if(allocated) {
3186
if(label) {
3187
materialtype = label-minbulk+1;
3188
}
3189
else if(maxbound) {
3190
materialtype = maxbulk-minbulk + 2;
3191
}
3192
else {
3193
materialtype = 1;
3194
}
3195
data->material[ind] = materialtype;
3196
}
3197
else {
3198
if(label > maxbulk) maxbulk = label;
3199
if(label < minbulk) minbulk = label;
3200
}
3201
3202
break;
3203
3204
case 3:
3205
cp = line;
3206
ind = next_int(&cp);
3207
nosides++;
3208
3209
for(i=0;i<elemnodes;i++) {
3210
k = next_int(&cp);
3211
inds[i] = k;
3212
}
3213
label = next_int(&cp);
3214
3215
if(!allocated) {
3216
if(label) {
3217
if(label > maxbound) maxbound = label;
3218
if(label < minbound) minbound = label;
3219
}
3220
}
3221
3222
if(allocated) {
3223
3224
if(label) {
3225
boundarytype = label-minbound+1;
3226
}
3227
else if(maxbound) {
3228
boundarytype = maxbound-minbound + 2;
3229
}
3230
else {
3231
boundarytype = 1;
3232
}
3233
3234
foundsame = FALSE;
3235
for(i=1;i<=usedno[inds[0]];i++) {
3236
parent = usedelem[inds[0]][i];
3237
3238
elemsides = data->elementtypes[parent] % 100;
3239
3240
for(side=0;side<elemsides;side++) {
3241
3242
GetElementSide(parent,side,1,data,&sideind[0],&sideelemtype);
3243
3244
if(elemnodes != sideelemtype%100) printf("LoadGidMesh: bug?\n");
3245
3246
hits = 0;
3247
for(j=0;j<elemnodes;j++)
3248
for(k=0;k<elemnodes;k++)
3249
if(sideind[j] == inds[k]) hits++;
3250
3251
if(hits < elemnodes) continue;
3252
3253
if(!foundsame) {
3254
foundsame++;
3255
bound->parent[nosides] = parent;
3256
bound->side[nosides] = side;
3257
bound->parent2[nosides] = 0;
3258
bound->side2[nosides] = 0;
3259
bound->types[nosides] = boundarytype;
3260
}
3261
else if(foundsame == 1) {
3262
if(parent == bound->parent[nosides]) continue;
3263
foundsame++;
3264
bound->parent2[nosides] = parent;
3265
bound->side2[nosides] = side;
3266
}
3267
else if(foundsame > 1) {
3268
printf("Boundary %d has more than 2 parents\n",nosides);
3269
}
3270
}
3271
}
3272
if(!foundsame) {
3273
printf("Did not find parent for side %d\n",nosides);
3274
nosides--;
3275
}
3276
else {
3277
if(debug) printf("Parent of side %d is %d\n",nosides,bound->parent[nosides]);
3278
}
3279
}
3280
}
3281
}
3282
}
3283
3284
end:
3285
3286
if(!allocated) {
3287
rewind(in);
3288
data->noknots = noknots;
3289
data->noelements = noelements;
3290
data->maxnodes = maxnodes;
3291
data->dim = dim;
3292
3293
if(info) {
3294
printf("Allocating for %d knots and %d %d-node elements.\n",
3295
noknots,noelements,maxnodes);
3296
printf("Initial material indexes are at interval %d to %d.\n",minbulk,maxbulk);
3297
}
3298
AllocateKnots(data);
3299
3300
if(info) {
3301
printf("Allocating %d boundary elements\n",nosides);
3302
printf("Initial boundary indexes are at interval %d to %d.\n",minbound,maxbound);
3303
}
3304
AllocateBoundary(bound,nosides);
3305
3306
bound->nosides = nosides;
3307
bound->created = TRUE;
3308
3309
nosides = 0;
3310
bulkdone = FALSE;
3311
boundarytype = 0;
3312
3313
allocated = TRUE;
3314
goto omstart;
3315
}
3316
3317
bound->nosides = nosides;
3318
free_Ivector(usedno,1,data->noknots);
3319
free_Imatrix(usedelem,1,data->noknots,1,usedmax);
3320
3321
if(info) printf("The mesh was loaded from file %s.\n",filename);
3322
return(0);
3323
}
3324
3325
3326
3327
static void ReorderComsolNodes(int elementtype,int *topo)
3328
{
3329
int i,tmptopo[MAXNODESD2];
3330
int order404[]={1,2,4,3};
3331
int order808[]={1,2,4,3,5,6,8,7};
3332
int order605[]={1,2,4,3,5};
3333
3334
3335
switch (elementtype) {
3336
3337
case 404:
3338
for(i=0;i<elementtype%100;i++)
3339
tmptopo[i] = topo[i];
3340
for(i=0;i<elementtype%100;i++)
3341
topo[i] = tmptopo[order404[i]-1];
3342
break;
3343
3344
case 808:
3345
for(i=0;i<elementtype%100;i++)
3346
tmptopo[i] = topo[i];
3347
for(i=0;i<elementtype%100;i++)
3348
topo[i] = tmptopo[order808[i]-1];
3349
break;
3350
3351
case 605:
3352
for(i=0;i<elementtype%100;i++)
3353
tmptopo[i] = topo[i];
3354
for(i=0;i<elementtype%100;i++)
3355
topo[i] = tmptopo[order605[i]-1];
3356
break;
3357
3358
3359
default:
3360
break;
3361
3362
}
3363
}
3364
3365
3366
3367
int LoadComsolMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info)
3368
/* Load the grid in Comsol Multiphysics mesh format */
3369
{
3370
int noknots,noelements,maxnodes,material;
3371
int allocated,dim=0, elemnodes=0, elembasis=0, elemtype;
3372
int debug,domains,mindom,minbc,maxdom,maxbc,maxlabel,elemdim=0,entitylen,entitydim;
3373
int *bclabel, *domlabel, n_label=0, offset, bcoffset, domoffset, *bcinfo;
3374
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
3375
char entityname[MAXNAMESIZE];
3376
int i,j,k;
3377
FILE *in;
3378
3379
strcpy(filename,prefix);
3380
if ((in = fopen(filename,"r")) == NULL) {
3381
AddExtension(prefix,filename,"mphtxt");
3382
if ((in = fopen(filename,"r")) == NULL) {
3383
if(info) printf("LoadComsolMesh: opening of the Comsol mesh file '%s' wasn't successful !\n",
3384
filename);
3385
return(1);
3386
}
3387
}
3388
3389
if(info) printf("Reading mesh from Comsol mesh file %s.\n",filename);
3390
InitializeKnots(data);
3391
3392
debug = FALSE;
3393
allocated = FALSE;
3394
3395
mindom = 1000;
3396
minbc = 1000;
3397
maxdom = 0;
3398
maxlabel = 0;
3399
maxbc = 0;
3400
offset = 1;
3401
3402
omstart:
3403
3404
maxnodes = 0;
3405
noknots = 0;
3406
noelements = 0;
3407
material = 0;
3408
domains = 0;
3409
3410
3411
for(;;) {
3412
3413
if(Comsolrow(line,in)) goto end;
3414
3415
if(strstr(line,"# sdim")) {
3416
cp = line;
3417
dim = next_int(&cp);
3418
if(info && !allocated) printf("Dimension of mesh is: %d\n",dim);
3419
}
3420
3421
else if(strstr(line,"# number of mesh points") || strstr(line, "# number of mesh vertices")) {
3422
cp = line;
3423
noknots = next_int(&cp);
3424
if(debug) printf("noknots=%d\n",noknots);
3425
}
3426
3427
else if(strstr(line,"# lowest mesh point index") || strstr(line, "# lowest mesh vertex index")) {
3428
cp = line;
3429
offset = 1 - next_int(&cp);
3430
if(debug) printf("offset=%d\n",offset);
3431
}
3432
3433
else if(strstr(line,"# type name")) {
3434
if(strstr(line,"vtx")) elembasis = 100;
3435
else if(strstr(line,"edg")) elembasis = 200;
3436
else if(strstr(line,"tri")) elembasis = 300;
3437
else if(strstr(line,"quad")) elembasis = 400;
3438
else if(strstr(line,"tet")) elembasis = 500;
3439
else if(strstr(line,"pyr")) elembasis = 600;
3440
else if(strstr(line,"prism")) elembasis = 700;
3441
else if(strstr(line,"hex")) elembasis = 800;
3442
else {
3443
printf("unknown element type = %s",line);
3444
bigerror("Cannot continue!\n");
3445
}
3446
}
3447
3448
else if(strstr(line,"# number of nodes per element") || strstr(line, "# number of vertices per element")) {
3449
cp = line;
3450
elemnodes = next_int(&cp);
3451
if(elemnodes > maxnodes) maxnodes = elemnodes;
3452
if(debug) printf("elemnodes=%d\n",elemnodes);
3453
}
3454
3455
else if(strstr(line,"# Mesh point coordinates") || strstr(line, "# Mesh vertex coordinates" )) {
3456
for(i=1;i<=noknots;i++) {
3457
Comsolrow(line,in);
3458
3459
if(allocated) {
3460
cp = line;
3461
data->x[i] = next_real(&cp);
3462
data->y[i] = next_real(&cp);
3463
if(dim == 3) data->z[i] = next_real(&cp);
3464
}
3465
}
3466
}
3467
3468
else if(strstr(line,"# number of elements")) {
3469
3470
cp = line;
3471
k = next_int(&cp);
3472
3473
Comsolrow(line,in);
3474
elemtype = elemnodes + elembasis;
3475
elemdim = GetElementDimension(elemtype);
3476
3477
if(debug) printf("Loading %d elements of type %d\n",k,elemtype);
3478
domains = noelements;
3479
3480
for(i=1;i<=k;i++) {
3481
Comsolrow(line,in);
3482
3483
if(dim == 3 && elembasis < 300) continue;
3484
if(dim == 2 && elembasis < 200) continue;
3485
3486
noelements = noelements + 1;
3487
if(allocated) {
3488
data->elementtypes[noelements] = elemtype;
3489
data->material[noelements] = 1;
3490
cp = line;
3491
for(j=0;j<elemnodes;j++)
3492
data->topology[noelements][j] = next_int(&cp) + offset;
3493
3494
if(1) ReorderComsolNodes(elemtype,data->topology[noelements]);
3495
3496
}
3497
}
3498
}
3499
3500
else if(strstr(line,"# number of geometric entity indices") ||
3501
strstr(line,"# number of domains")) {
3502
3503
cp = line;
3504
k = next_int(&cp);
3505
3506
Comsolrow(line,in);
3507
if(debug) printf("Loading %d domains for the elements\n",k);
3508
3509
for(i=1;i<=k;i++) {
3510
Comsolrow(line,in);
3511
3512
if(dim == 3 && elembasis < 300) continue;
3513
if(dim == 2 && elembasis < 200) continue;
3514
3515
domains = domains + 1;
3516
cp = line;
3517
material = next_int(&cp);
3518
3519
if(allocated) {
3520
if( elemdim < dim ) {
3521
if(maxlabel>0) bcinfo[domains] = TRUE;
3522
data->material[domains] = material + bcoffset;
3523
}
3524
else {
3525
data->material[domains] = material + domoffset;
3526
}
3527
}
3528
else {
3529
if(elemdim < dim) {
3530
minbc = MIN(minbc,material);
3531
maxbc = MAX(maxbc,material);
3532
}
3533
else {
3534
mindom = MIN(mindom,material);
3535
maxdom = MAX(maxdom,material);
3536
}
3537
}
3538
3539
}
3540
}
3541
3542
else if(strstr(line,"# Label") && !strstr(line,"Union Selection")) {
3543
int ind, ind1, n_ent = 0;
3544
3545
n_label += 1;
3546
maxlabel = MAX(maxlabel,n_label);
3547
3548
if(debug) printf("Reading Label %d\n",n_label);
3549
3550
if(allocated) {
3551
/* Read the length of the label and proceed over the empty space*/
3552
cp = line;
3553
entitylen = next_int(&cp);
3554
cp += 1;
3555
strncpy(entityname,cp,entitylen);
3556
entityname[entitylen] = '\0';
3557
if(debug) printf("BoundaryName %d is: %s\n",n_label,entityname);
3558
}
3559
3560
j = 0;
3561
for(i=1;i<=4;i++) {
3562
Comsolrow(line,in);
3563
if(strstr(line,"# Geometry/mesh tag")) j++;
3564
if(strstr(line,"# Dimension")) {
3565
cp = line;
3566
entitydim = next_int(&cp);
3567
if(debug) printf("Dimension of entity: %d\n",entitydim);
3568
j++;
3569
}
3570
if(strstr(line,"# Number of entities")) {
3571
j++;
3572
cp = line;
3573
n_ent = next_int(&cp);
3574
if(debug) printf("Number of entities: %d\n",n_ent);
3575
}
3576
if(strstr(line,"# Entities")) {
3577
if(debug) printf("Reading %d entities\n",n_ent);
3578
j++;
3579
for(k=1;k<=n_ent;k++) {
3580
Comsolrow(line,in);
3581
if(allocated) {
3582
cp = line;
3583
if(entitydim == dim ) {
3584
ind = next_int(&cp)+domoffset;
3585
if(k==1) {
3586
/* Use the first entity to represent all entities. */
3587
ind1 = ind;
3588
data->bodyname[ind1] = Cvector(0,MAXNAMESIZE);
3589
strncpy(data->bodyname[ind1],entityname,entitylen);
3590
}
3591
domlabel[ind] = ind1;
3592
if(debug) printf("Mapping bulk: %d %d %d\n",n_label,ind,ind1);
3593
}
3594
else if(entitydim == dim-1 ) {
3595
ind = next_int(&cp)+bcoffset;
3596
if(k==1) {
3597
ind1 = ind;
3598
data->boundaryname[ind1] = Cvector(0,MAXNAMESIZE);
3599
strncpy(data->boundaryname[ind1],entityname,entitylen);
3600
}
3601
bclabel[ind] = ind1;
3602
if(debug) printf("Mapping bc: %d %d %d\n",n_label,ind,ind1);
3603
}
3604
}
3605
}
3606
}
3607
}
3608
if(j<4) {
3609
if(debug) printf("We should have number 4 keywords after label so something might be off!");
3610
break;
3611
}
3612
}
3613
else if(strstr(line,"#")) {
3614
if(debug) printf("Unused command: %s",line);
3615
}
3616
3617
}
3618
3619
end:
3620
3621
if(!allocated) {
3622
3623
if(noknots == 0 || noelements == 0 || maxnodes == 0) {
3624
printf("Invalid mesh consists of %d knots and %d %d-node elements.\n",
3625
noknots,noelements,maxnodes);
3626
fclose(in);
3627
return(2);
3628
}
3629
3630
rewind(in);
3631
3632
if(info) {
3633
printf("Comsol mesh consists of %d nodes and %d elements\n",noknots,noelements);
3634
}
3635
3636
data->noknots = noknots;
3637
data->noelements = noelements;
3638
data->maxnodes = maxnodes;
3639
data->dim = dim;
3640
n_label = 0;
3641
3642
bcoffset = 1 - minbc;
3643
domoffset = 1 - mindom;
3644
3645
if(info) {
3646
printf("Original body index range is [%d,%d]\n",mindom,maxdom);
3647
printf("Original bc index range is [%d,%d]\n",minbc,maxbc);
3648
if(domoffset) printf("Offset of body indexing set to start from one!\n");
3649
if(bcoffset) printf("Offset of BC indexing set to start from one!\n");
3650
}
3651
3652
if(maxlabel>0) {
3653
if(info) printf("Mesh has %d labels with physical names.\n",maxlabel);
3654
3655
/* Allocate for the tables that renumbers geometric entities to physical ones. */
3656
maxbc++;
3657
maxdom++;
3658
bclabel = Ivector(minbc,maxbc);
3659
for(i=minbc;i<=maxbc;i++)
3660
bclabel[i] = -1;
3661
domlabel = Ivector(mindom,maxdom);
3662
for(i=mindom;i<=maxdom;i++)
3663
domlabel[i] = -1;
3664
3665
bcinfo = Ivector(1,noelements);
3666
for(i=1;i<=noelements;i++)
3667
bcinfo[i] = FALSE;
3668
3669
/* The code may think bodies are boundaries unless both names are set to exist even if they don't. */
3670
data->bodynamesexist = TRUE;
3671
data->boundarynamesexist = TRUE;
3672
}
3673
3674
if(info) {
3675
printf("Allocating for %d knots and %d %d-node elements.\n",
3676
noknots,noelements,maxnodes);
3677
}
3678
AllocateKnots(data);
3679
allocated = TRUE;
3680
3681
goto omstart;
3682
}
3683
fclose(in);
3684
3685
/* Perform remapping of entities */
3686
if(maxlabel > 0 ) {
3687
3688
if(debug) {
3689
for(i=minbc;i<=maxbc;i++)
3690
if(bclabel[i] > 0) printf("bc map: %d %d\n",i,bclabel[i]);
3691
for(i=mindom;i<=maxdom;i++)
3692
if(domlabel[i] > 0) printf("bulk map: %d %d\n",i,domlabel[i]);
3693
}
3694
3695
for(i=1;i<=data->noelements;i++) {
3696
j = data->material[i];
3697
if(bcinfo[i]) {
3698
if(bclabel[j]>-1) data->material[i] = bclabel[j];
3699
}
3700
else {
3701
if(domlabel[j]>-1)
3702
data->material[i] = domlabel[j];
3703
}
3704
}
3705
free_Ivector(bclabel,minbc,maxbc);
3706
free_Ivector(domlabel,mindom,maxdom);
3707
free_Ivector(bcinfo,1,noelements);
3708
}
3709
3710
if(info) printf("Comsol mesh was loaded from file %s.\n\n",filename);
3711
ElementsToBoundaryConditions(data,bound,FALSE,TRUE);
3712
3713
return(0);
3714
}
3715
3716
3717
3718
static int GmshToElmerType(int gmshtype)
3719
{
3720
int elmertype = 0;
3721
3722
switch (gmshtype) {
3723
3724
case 1:
3725
elmertype = 202;
3726
break;
3727
case 2:
3728
elmertype = 303;
3729
break;
3730
case 3:
3731
elmertype = 404;
3732
break;
3733
case 4:
3734
elmertype = 504;
3735
break;
3736
case 5:
3737
elmertype = 808;
3738
break;
3739
case 6:
3740
elmertype = 706;
3741
break;
3742
case 7:
3743
elmertype = 605;
3744
break;
3745
case 8:
3746
elmertype = 203;
3747
break;
3748
case 9:
3749
elmertype = 306;
3750
break;
3751
case 10:
3752
elmertype = 409;
3753
break;
3754
case 11:
3755
elmertype = 510;
3756
break;
3757
case 12:
3758
elmertype = 827;
3759
break;
3760
case 15:
3761
elmertype = 101;
3762
break;
3763
case 16:
3764
elmertype = 408;
3765
break;
3766
case 17:
3767
elmertype = 820;
3768
break;
3769
case 18:
3770
elmertype = 715;
3771
break;
3772
case 19:
3773
elmertype = 613;
3774
break;
3775
case 21:
3776
elmertype = 310;
3777
break;
3778
case 26:
3779
elmertype = 204;
3780
break;
3781
case 36:
3782
elmertype = 416;
3783
break;
3784
3785
/* These are supported by Gmsh but not by ElmerSolver */
3786
case 13:
3787
elmertype = 718;
3788
break;
3789
case 14:
3790
elmertype = 614;
3791
break;
3792
case 20:
3793
elmertype = 309;
3794
break;
3795
case 22:
3796
elmertype = 312;
3797
break;
3798
case 24:
3799
elmertype = 315;
3800
break;
3801
case 25:
3802
elmertype = 320;
3803
break;
3804
case 27:
3805
elmertype = 205;
3806
break;
3807
case 28:
3808
elmertype = 206;
3809
break;
3810
case 29:
3811
elmertype = 520;
3812
break;
3813
3814
default:
3815
printf("Gmsh element %d does not have an Elmer counterpart!\n",gmshtype);
3816
}
3817
3818
return(elmertype);
3819
}
3820
3821
3822
static void GmshToElmerIndx(int elemtype,int *topology)
3823
{
3824
int i=0,nodes=0,oldtopology[MAXNODESD2];
3825
int reorder, *porder;
3826
3827
int order510[]={0,1,2,3,4,5,6,7,9,8};
3828
int order614[]={0,1,2,3,4,5,8,10,6,7,9,11,12,13};
3829
int order718[]={0,1,2,3,4,5,6,9,7,8,10,11,12,14,13,15,17,16};
3830
int order820[]={0,1,2,3,4,5,6,7,8,11,13,9,10,12,14,15,16,18,19,17};
3831
int order827[]={0,1,2,3,4,5,6,7,8,11,13,9,10,12,14,15,16,18,19,17,21,23,24,22,20,25,26};
3832
/* {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}; */
3833
3834
3835
reorder = FALSE;
3836
3837
switch (elemtype) {
3838
3839
case 510:
3840
reorder = TRUE;
3841
porder = &order510[0];
3842
break;
3843
3844
case 613:
3845
case 614:
3846
reorder = TRUE;
3847
porder = &order614[0];
3848
break;
3849
3850
case 715:
3851
case 718:
3852
reorder = TRUE;
3853
porder = &order718[0];
3854
break;
3855
3856
case 820:
3857
reorder = TRUE;
3858
porder = &order820[0];
3859
break;
3860
3861
case 827:
3862
reorder = TRUE;
3863
porder = &order827[0];
3864
break;
3865
}
3866
3867
if( reorder ) {
3868
nodes = elemtype % 100;
3869
for(i=0;i<nodes;i++)
3870
oldtopology[i] = topology[i];
3871
for(i=0;i<nodes;i++)
3872
topology[i] = oldtopology[porder[i]];
3873
}
3874
}
3875
3876
3877
static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
3878
char *filename,int info)
3879
{
3880
int noknots = 0,noelements = 0,maxnodes,dim;
3881
int elemind[MAXNODESD2],elementtype;
3882
int i,j,k,allocated,*revindx=NULL,maxindx;
3883
int elemno, gmshtype, regphys, regelem, elemnodes,maxelemtype;
3884
FILE *in;
3885
char *cp,line[MAXLINESIZE];
3886
3887
3888
if ((in = fopen(filename,"r")) == NULL) {
3889
printf("LoadGmshInput: The opening of the mesh file %s failed!\n",filename);
3890
return(1);
3891
}
3892
if(info) printf("Loading mesh in Gmsh format 1.0 from file %s\n",filename);
3893
3894
allocated = FALSE;
3895
dim = data->dim;
3896
maxnodes = 0;
3897
maxindx = 0;
3898
maxelemtype = 0;
3899
3900
allocate:
3901
3902
if(allocated) {
3903
InitializeKnots(data);
3904
data->dim = dim;
3905
data->maxnodes = maxnodes;
3906
data->noelements = noelements;
3907
data->noknots = noknots;
3908
3909
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
3910
AllocateKnots(data);
3911
3912
if(maxindx > noknots) {
3913
revindx = Ivector(1,maxindx);
3914
for(i=1;i<=maxindx;i++) revindx[i] = 0;
3915
}
3916
in = fopen(filename,"r");
3917
}
3918
3919
3920
for(;;) {
3921
if(Getrow(line,in,TRUE)) goto end;
3922
if(strstr(line,"END")) goto end;
3923
3924
if(strstr(line,"$NOD")) {
3925
3926
GETLINE;
3927
cp = line;
3928
noknots = next_int(&cp);
3929
3930
for(i=1; i <= noknots; i++) {
3931
GETLINE;
3932
cp = line;
3933
3934
j = next_int(&cp);
3935
if(allocated) {
3936
if(maxindx > noknots) revindx[j] = i;
3937
data->x[i] = next_real(&cp);
3938
data->y[i] = next_real(&cp);
3939
if(dim > 2) data->z[i] = next_real(&cp);
3940
}
3941
else {
3942
maxindx = MAX(j,maxindx);
3943
}
3944
}
3945
GETLINE;
3946
if(!strstr(line,"$ENDNOD")) {
3947
printf("NOD section should end to string ENDNOD\n");
3948
printf("%s\n",line);
3949
}
3950
}
3951
3952
if(strstr(line,"$ELM")) {
3953
GETLINE;
3954
cp = line;
3955
noelements = next_int(&cp);
3956
3957
for(i=1; i <= noelements; i++) {
3958
GETLINE;
3959
3960
cp = line;
3961
elemno = next_int(&cp);
3962
gmshtype = next_int(&cp);
3963
regphys = next_int(&cp);
3964
regelem = next_int(&cp);
3965
elemnodes = next_int(&cp);
3966
3967
if(allocated) {
3968
elementtype = GmshToElmerType(gmshtype);
3969
maxelemtype = MAX(maxelemtype,elementtype);
3970
data->elementtypes[i] = elementtype;
3971
data->material[i] = regphys;
3972
3973
if(elemnodes != elementtype%100) {
3974
printf("Conflict in elementtypes %d and number of nodes %d!\n",
3975
elementtype,elemnodes);
3976
}
3977
for(j=0;j<elemnodes;j++)
3978
elemind[j] = next_int(&cp);
3979
3980
GmshToElmerIndx(elementtype,elemind);
3981
3982
for(j=0;j<elemnodes;j++)
3983
data->topology[i][j] = elemind[j];
3984
}
3985
else {
3986
maxnodes = MAX(elemnodes,maxnodes);
3987
}
3988
3989
}
3990
GETLINE;
3991
if(!strstr(line,"$ENDELM"))
3992
printf("ELM section should end to string ENDELM\n");
3993
}
3994
3995
}
3996
3997
end:
3998
3999
fclose(in);
4000
4001
if(!allocated) {
4002
allocated = TRUE;
4003
goto allocate;
4004
}
4005
4006
4007
if(maxindx > noknots) {
4008
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
4009
4010
for(i=1; i <= noelements; i++) {
4011
elementtype = data->elementtypes[i];
4012
elemnodes = elementtype % 100;
4013
4014
for(j=0;j<elemnodes;j++) {
4015
k = data->topology[i][j];
4016
if(k <= 0 || k > maxindx)
4017
printf("index out of bounds %d\n",k);
4018
else if(revindx[k] <= 0)
4019
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
4020
else
4021
data->topology[i][j] = revindx[k];
4022
}
4023
}
4024
free_Ivector(revindx,1,maxindx);
4025
}
4026
4027
ModifyUnsupportedElements(data);
4028
4029
ElementsToBoundaryConditions(data,bound,FALSE,info);
4030
4031
printf("Successfully read the mesh from the Gmsh input file.\n");
4032
4033
return(0);
4034
}
4035
4036
4037
static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
4038
char *filename,int usetaggeom, int keeporphans, int info)
4039
{
4040
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
4041
int elemind[MAXNODESD2],elementtype;
4042
int i,j,k,allocated,*revindx=NULL,maxindx;
4043
int elemno, gmshtype, tagphys=0, taggeom=0, tagpart, elemnodes,maxelemtype;
4044
int tagmat,verno;
4045
int physvolexist, physsurfexist;
4046
FILE *in;
4047
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
4048
char *cp,line[MAXLINESIZE];
4049
4050
if ((in = fopen(filename,"r")) == NULL) {
4051
printf("LoadGmshInput2: The opening of the mesh file %s failed!\n",filename);
4052
return(1);
4053
}
4054
if(info) printf("Loading mesh in Gmsh format 2.0 from file %s\n",filename);
4055
4056
allocated = FALSE;
4057
dim = data->dim;
4058
maxnodes = 0;
4059
maxindx = 0;
4060
maxelemtype = 0;
4061
physvolexist = FALSE;
4062
physsurfexist = FALSE;
4063
usetaggeom = FALSE;
4064
4065
omstart:
4066
4067
for(;;) {
4068
if(Getrow(line,in,FALSE)) goto end;
4069
if(strstr(line,"$End")) continue;
4070
4071
if(strstr(line,"$MeshFormat")) {
4072
GETLINE;
4073
cp = line;
4074
verno = next_int(&cp);
4075
4076
if(verno != 2) {
4077
printf("Version number is not compatible with the parser: %d\n",verno);
4078
}
4079
4080
GETLINE;
4081
if(!strstr(line,"$EndMeshFormat")) {
4082
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
4083
}
4084
}
4085
4086
else if(strstr(line,"$Nodes")) {
4087
GETLINE;
4088
cp = line;
4089
noknots = next_int(&cp);
4090
4091
for(i=1; i <= noknots; i++) {
4092
GETLINE;
4093
cp = line;
4094
4095
j = next_int(&cp);
4096
if(allocated) {
4097
if(maxindx > noknots) revindx[j] = i;
4098
data->x[i] = next_real(&cp);
4099
data->y[i] = next_real(&cp);
4100
if(dim > 2) data->z[i] = next_real(&cp);
4101
}
4102
else {
4103
maxindx = MAX(j,maxindx);
4104
}
4105
}
4106
GETLINE;
4107
if(!strstr(line,"$EndNodes")) {
4108
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
4109
}
4110
}
4111
4112
else if(strstr(line,"$Elements")) {
4113
GETLINE;
4114
cp = line;
4115
noelements = next_int(&cp);
4116
4117
for(i=1; i <= noelements; i++) {
4118
GETLINE;
4119
4120
cp = line;
4121
elemno = next_int(&cp);
4122
gmshtype = next_int(&cp);
4123
elementtype = GmshToElmerType(gmshtype);
4124
4125
if(allocated) {
4126
elemnodes = elementtype % 100;
4127
data->elementtypes[i] = elementtype;
4128
4129
/* Point does not seem to have physical properties */
4130
notags = next_int(&cp);
4131
if(notags > 0) tagphys = next_int(&cp);
4132
if(notags > 1) taggeom = next_int(&cp);
4133
if(notags > 2) tagpart = next_int(&cp);
4134
for(j=4;j<=notags;j++)
4135
next_int(&cp);
4136
4137
if(tagphys) {
4138
tagmat = tagphys;
4139
}
4140
else {
4141
tagmat = taggeom;
4142
usetaggeom = TRUE;
4143
}
4144
4145
data->material[i] = tagmat;
4146
for(j=0;j<elemnodes;j++)
4147
elemind[j] = next_int(&cp);
4148
4149
GmshToElmerIndx(elementtype,elemind);
4150
4151
for(j=0;j<elemnodes;j++)
4152
data->topology[i][j] = elemind[j];
4153
}
4154
else {
4155
maxelemtype = MAX(maxelemtype,elementtype);
4156
}
4157
4158
}
4159
GETLINE;
4160
if(!strstr(line,"$EndElements")) {
4161
printf("$Elements section should end to string $EndElements:\n%s\n",line);
4162
}
4163
}
4164
else if(strstr(line,"$PhysicalNames")) {
4165
int entdim;
4166
entdim = dim;
4167
GETLINE;
4168
cp = line;
4169
nophysical = next_int(&cp);
4170
for(i=0;i<nophysical;i++) {
4171
GETLINE;
4172
if(allocated) {
4173
cp = line;
4174
gmshtype = next_int(&cp);
4175
if(gmshtype < entdim-1) {
4176
printf("Assuming maximum entity dim to be %d\n",dim-1);
4177
entdim--;
4178
}
4179
tagphys = next_int(&cp);
4180
if(gmshtype == entdim-1) {
4181
physsurfexist = TRUE;
4182
if(tagphys < MAXBCS) {
4183
if(!data->boundaryname[tagphys]) data->boundaryname[tagphys] = Cvector(0,MAXNAMESIZE);
4184
sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys]);
4185
}
4186
else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4187
}
4188
else if(gmshtype == entdim) {
4189
physvolexist = TRUE;
4190
4191
if(tagphys < MAXBODIES) {
4192
if(!data->bodyname[tagphys]) data->bodyname[tagphys] = Cvector(0,MAXNAMESIZE);
4193
sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
4194
}
4195
else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4196
}
4197
else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
4198
"ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
4199
}
4200
}
4201
4202
GETLINE;
4203
if(!strstr(line,"$EndPhysicalNames")) {
4204
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
4205
}
4206
}
4207
else {
4208
if(!allocated) printf("Untreated command: %s",line);
4209
}
4210
4211
}
4212
4213
end:
4214
4215
4216
if(!allocated) {
4217
maxnodes = maxelemtype % 100;
4218
InitializeKnots(data);
4219
data->dim = dim;
4220
data->maxnodes = maxnodes;
4221
data->noelements = noelements;
4222
data->noknots = noknots;
4223
4224
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
4225
AllocateKnots(data);
4226
4227
if(maxindx > noknots) {
4228
revindx = Ivector(1,maxindx);
4229
for(i=1;i<=maxindx;i++) revindx[i] = 0;
4230
}
4231
rewind(in);
4232
allocated = TRUE;
4233
goto omstart;
4234
}
4235
4236
if(maxindx > noknots) {
4237
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
4238
4239
for(i=1; i <= noelements; i++) {
4240
elementtype = data->elementtypes[i];
4241
elemnodes = elementtype % 100;
4242
4243
for(j=0;j<elemnodes;j++) {
4244
k = data->topology[i][j];
4245
if(k <= 0 || k > maxindx)
4246
printf("index out of bounds %d\n",k);
4247
else if(revindx[k] <= 0)
4248
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
4249
else
4250
data->topology[i][j] = revindx[k];
4251
}
4252
}
4253
free_Ivector(revindx,1,maxindx);
4254
}
4255
4256
ModifyUnsupportedElements(data);
4257
4258
ElementsToBoundaryConditions(data,bound,keeporphans,info);
4259
4260
data->bodynamesexist = physvolexist;
4261
data->boundarynamesexist = physsurfexist;
4262
4263
if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
4264
4265
return(0);
4266
}
4267
4268
4269
static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
4270
char *filename,int usetaggeom, int keeporphans, int info)
4271
{
4272
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
4273
int elemind[MAXNODESD2],elementtype;
4274
int i,j,k,l,allocated,*revindx=NULL,maxindx;
4275
int elemno, gmshtype, tagphys=0, tagpart, elemnodes,maxelemtype;
4276
int tagmat,verno;
4277
int physvolexist, physsurfexist,**tagmap,tagsize,maxtag[4];
4278
FILE *in;
4279
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
4280
char *cp,line[MAXLINESIZE],longline[LONGLINESIZE];
4281
4282
if ((in = fopen(filename,"r")) == NULL) {
4283
printf("LoadGmshInput4: The opening of the mesh file %s failed!\n",filename);
4284
return(1);
4285
}
4286
if(info) printf("Loading mesh in Gmsh format 4.0 from file %s\n",filename);
4287
4288
allocated = FALSE;
4289
dim = data->dim;
4290
maxnodes = 0;
4291
maxindx = 0;
4292
maxelemtype = 0;
4293
physvolexist = FALSE;
4294
physsurfexist = FALSE;
4295
usetaggeom = TRUE; /* The default */
4296
for(i=0;i<4;i++) maxtag[i] = 0;
4297
4298
4299
omstart:
4300
4301
for(;;) {
4302
if(Getrow(line,in,FALSE)) goto end;
4303
if(strstr(line,"$End")) continue;
4304
4305
if(strstr(line,"$MeshFormat")) {
4306
GETLINE;
4307
cp = line;
4308
verno = next_int(&cp);
4309
4310
if(verno != 4) {
4311
printf("Version number is not compatible with the parser: %d\n",verno);
4312
}
4313
4314
GETLINE;
4315
if(!strstr(line,"$EndMeshFormat")) {
4316
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
4317
}
4318
}
4319
4320
else if(strstr(line,"$Nodes")) {
4321
int numEntityBlocks,tagEntity,dimEntity,parEntity,numNodes,ind;
4322
4323
GETLINE;
4324
cp = line;
4325
4326
numEntityBlocks = next_int(&cp);
4327
noknots = next_int(&cp);
4328
4329
if(allocated && info) printf("Reading %d nodes in %d blocks.\n",noknots,numEntityBlocks);
4330
4331
k = 0;
4332
4333
for(j=1; j <= numEntityBlocks; j++) {
4334
GETLINE;
4335
cp = line;
4336
4337
tagEntity = next_int(&cp);
4338
dimEntity = next_int(&cp);
4339
parEntity = next_int(&cp);
4340
numNodes = next_int(&cp);
4341
4342
for(i=1; i <= numNodes; i++) {
4343
GETLINE;
4344
cp = line;
4345
k += 1;
4346
4347
ind = next_int(&cp);
4348
if(allocated) {
4349
if(maxindx > noknots) revindx[ind] = k;
4350
data->x[k] = next_real(&cp);
4351
data->y[k] = next_real(&cp);
4352
if(dim > 2) data->z[k] = next_real(&cp);
4353
}
4354
else {
4355
maxindx = MAX(ind,maxindx);
4356
}
4357
}
4358
}
4359
GETLINE;
4360
4361
if(!strstr(line,"$EndNodes")) {
4362
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
4363
}
4364
}
4365
4366
else if(strstr(line,"$Entities")) {
4367
int numPoints, numCurves, numSurfaces, numVolumes, numEnt;
4368
int tag,tagdim,nophys,phystag;
4369
int nobound, idum;
4370
Real rdum;
4371
4372
usetaggeom = FALSE;
4373
4374
GETLINE;
4375
cp = line;
4376
numPoints = next_int(&cp);
4377
numCurves = next_int(&cp);
4378
numSurfaces = next_int(&cp);
4379
numVolumes = next_int(&cp);
4380
4381
if(allocated) {
4382
tagsize = 0;
4383
for(tagdim=0;tagdim<=3;tagdim++)
4384
tagsize = MAX( tagsize, maxtag[tagdim]);
4385
if( tagsize > 0 ) {
4386
tagmap = Imatrix(0,3,1,tagsize);
4387
for(i=0;i<=3;i++)
4388
for(j=1;j<=tagsize;j++)
4389
tagmap[i][j] = 0;
4390
}
4391
}
4392
4393
for(tagdim=0;tagdim<=3;tagdim++) {
4394
4395
if( tagdim == 0 )
4396
numEnt = numPoints;
4397
else if( tagdim == 1 )
4398
numEnt = numCurves;
4399
else if( tagdim == 2 )
4400
numEnt = numSurfaces;
4401
else if( tagdim == 3 )
4402
numEnt = numVolumes;
4403
4404
if(!allocated)
4405
maxtag[tagdim] = 0;
4406
else if( maxtag[tagdim] > 0 )
4407
printf("Tag range for %d %dDIM entities is [%d %d]\n",numEnt,tagdim,0,maxtag[tagdim]);
4408
4409
if(numEnt > 0 && !allocated) {
4410
printf("Reading %d entities in %dD\n",numEnt,tagdim);
4411
}
4412
4413
for(i=1; i <= numEnt; i++) {
4414
GETLONGLINE;
4415
4416
// if( i==1 ) printf("1st line of dim %d with %d entries: %s\n",tagdim,numEnt,line);
4417
4418
if( tagdim == 0 ) continue;
4419
4420
cp = longline;
4421
tag = next_int(&cp);
4422
4423
if(!allocated)
4424
maxtag[tagdim] = MAX( maxtag[tagdim], tag );
4425
4426
for(j=1;j<=6;j++) rdum = next_real(&cp);
4427
nophys = next_int(&cp);
4428
4429
phystag = 0;
4430
if( nophys > 0 ) phystag = next_int(&cp);
4431
4432
if(allocated) tagmap[tagdim][tag] = phystag;
4433
4434
4435
// The lines may be too long. So fill the string buffer until we get a newline.
4436
j = k = 0;
4437
for(;;) {
4438
for(l=0;l<LONGLINESIZE;l++) {
4439
if( longline[l] == '\n') {
4440
j = l+1;
4441
break;
4442
}
4443
}
4444
if(j) {
4445
j--;
4446
break;
4447
}
4448
k += LONGLINESIZE;
4449
GETLONGLINE;
4450
}
4451
if( k > 0 && !allocated) printf("Entity line %d has length %d.\n",i,k+j);
4452
4453
//for(j=2;j<=nophys;j++)
4454
// idum = next_int(&cp);
4455
4456
//// if( tagdim == 0 ) continue;
4457
4458
//nobound = next_int(&cp);
4459
// for(j=1;j<=nobound;j++)
4460
// idum = next_int(&cp);
4461
}
4462
}
4463
4464
GETLONGLINE;
4465
if(!strstr(longline,"$EndEntities")) {
4466
printf("$Entities section should end to string $EndEntities:\n%s\n",longline);
4467
}
4468
}
4469
4470
else if(strstr(line,"$Elements")) {
4471
int numEntityBlocks, numElements, tagEntity, dimEntity, typeEle, NumElements;
4472
4473
GETLINE;
4474
cp = line;
4475
4476
k = 0;
4477
numEntityBlocks = next_int(&cp);
4478
noelements = next_int(&cp);
4479
4480
if(allocated) printf("Reading %d elements in %d blocks.\n",noelements,numEntityBlocks);
4481
4482
4483
for(j=1; j<= numEntityBlocks; j++ ) {
4484
4485
GETLINE;
4486
cp = line;
4487
4488
tagEntity = next_int(&cp);
4489
dimEntity = next_int(&cp);
4490
4491
typeEle = next_int(&cp);
4492
numElements = next_int(&cp);
4493
4494
elementtype = GmshToElmerType(typeEle);
4495
elemnodes = elementtype % 100;
4496
maxelemtype = MAX(maxelemtype,elementtype);
4497
4498
if( allocated && tagsize > 0 ) {
4499
printf("Reading %d elements with tag %d of type %d\n", numElements, tagEntity, elementtype);
4500
if( tagsize > 0 ) {
4501
if( tagmap[dimEntity][tagEntity] ) {
4502
printf(" Mapping mesh tag %d to physical tag %d in %dDIM\n",tagEntity,tagmap[dimEntity][tagEntity],dimEntity);
4503
tagEntity = tagmap[dimEntity][tagEntity];
4504
}
4505
else {
4506
printf(" Mesh tag %d is not associated to any physical tag!\n",tagEntity);
4507
}
4508
}
4509
}
4510
4511
for(i=1; i <= numElements; i++) {
4512
GETLINE;
4513
cp = line;
4514
4515
k += 1;
4516
4517
elemno = next_int(&cp);
4518
4519
if(allocated) {
4520
data->elementtypes[k] = elementtype;
4521
data->material[k] = tagEntity;
4522
for(l=0;l<elemnodes;l++)
4523
elemind[l] = next_int(&cp);
4524
4525
GmshToElmerIndx(elementtype,elemind);
4526
4527
for(l=0;l<elemnodes;l++)
4528
data->topology[k][l] = elemind[l];
4529
}
4530
}
4531
}
4532
4533
GETLINE;
4534
if(!strstr(line,"$EndElements")) {
4535
printf("$Elements section should end to string $EndElements:\n%s\n",line);
4536
}
4537
}
4538
4539
else if(strstr(line,"$PhysicalNames")) {
4540
int entdim;
4541
entdim = dim;
4542
GETLINE;
4543
cp = line;
4544
nophysical = next_int(&cp);
4545
for(i=0;i<nophysical;i++) {
4546
GETLINE;
4547
if(allocated) {
4548
cp = line;
4549
gmshtype = next_int(&cp);
4550
if(gmshtype < entdim-1) {
4551
printf("Assuming maximum entity dim to be %d\n",dim-1);
4552
entdim--;
4553
}
4554
tagphys = next_int(&cp);
4555
if(gmshtype == entdim-1) {
4556
physsurfexist = TRUE;
4557
if(tagphys < MAXBCS) {
4558
if(!data->boundaryname[tagphys]) data->boundaryname[tagphys] = Cvector(0,MAXNAMESIZE);
4559
sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys]);
4560
printf("Boundary name for physical group %d is: %s\n",tagphys,data->boundaryname[tagphys]);
4561
}
4562
else {
4563
printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4564
}
4565
}
4566
else if(gmshtype == entdim) {
4567
physvolexist = TRUE;
4568
if(tagphys < MAXBODIES) {
4569
if(!data->bodyname[tagphys]) data->bodyname[tagphys] = Cvector(0,MAXNAMESIZE);
4570
sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
4571
printf("Body name for physical group %d is: %s\n",tagphys,data->bodyname[tagphys]);
4572
}
4573
else {
4574
printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4575
}
4576
}
4577
else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
4578
"ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
4579
}
4580
}
4581
4582
GETLINE;
4583
if(!strstr(line,"$EndPhysicalNames")) {
4584
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
4585
}
4586
}
4587
else if(strstr(line,"$Periodic")) {
4588
int numPeriodicLinks;
4589
if(allocated) printf("Reading periodic links but doing nothing with them!\n");
4590
4591
GETLINE;
4592
cp = line;
4593
numPeriodicLinks = next_int(&cp);
4594
for(i=1; i <= numPeriodicLinks; i++) {
4595
GETLINE;
4596
}
4597
GETLINE;
4598
if(!strstr(line,"$EndPeriodic")) {
4599
printf("$Periodic section should end to string $EndPeriodic:\n%s\n",line);
4600
}
4601
}
4602
4603
else if(strstr(line,"$PartitionedEntities")) {
4604
if(allocated) printf("Reading partitioned entities but doing nothing with them!\n");
4605
for(;;) {
4606
GETLINE;
4607
if(strstr(line,"$EndPartitionedEntities")) break;
4608
}
4609
}
4610
else if(strstr(line,"$NodeData")) {
4611
if(allocated) printf("Reading node data but doing nothing with them!\n");
4612
for(;;) {
4613
GETLINE;
4614
if(strstr(line,"$EndNodeData")) break;
4615
}
4616
}
4617
else if(strstr(line,"$ElementData")) {
4618
if(allocated) printf("Reading element data but doing nothing with them!\n");
4619
for(;;) {
4620
GETLINE;
4621
if(strstr(line,"$EndElementData")) break;
4622
}
4623
}
4624
else if(strstr(line,"$ElementNodeData")) {
4625
if(allocated) printf("Reading element node data but doing nothing with them!\n");
4626
for(;;) {
4627
GETLINE;
4628
if(strstr(line,"$EndElementNodeData")) break;
4629
}
4630
}
4631
else if(strstr(line,"$GhostElements")) {
4632
if(allocated) printf("Reading ghost elements data but doing nothing with them!\n");
4633
for(;;) {
4634
GETLINE;
4635
if(strstr(line,"$EndGhostElements")) break;
4636
}
4637
}
4638
else if(strstr(line,"$InterpolationScheme")) {
4639
if(allocated) printf("Reading interpolation scheme but doing nothing with them!\n");
4640
for(;;) {
4641
GETLINE;
4642
if(strstr(line,"$EndInterpolationScheme")) break;
4643
}
4644
}
4645
else {
4646
if(allocated) printf("Untreated command: %s",line);
4647
}
4648
4649
}
4650
4651
end:
4652
4653
4654
if(!allocated) {
4655
if( noelements == 0 ) bigerror("No elements to load in Gmsh file!");
4656
if( noknots == 0 ) bigerror("No nodes to load in Gmsh file!");
4657
4658
maxnodes = maxelemtype % 100;
4659
InitializeKnots(data);
4660
data->dim = dim;
4661
data->maxnodes = maxnodes;
4662
data->noelements = noelements;
4663
data->noknots = noknots;
4664
4665
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
4666
AllocateKnots(data);
4667
4668
if(maxindx > noknots) {
4669
revindx = Ivector(1,maxindx);
4670
for(i=1;i<=maxindx;i++) revindx[i] = 0;
4671
}
4672
rewind(in);
4673
allocated = TRUE;
4674
goto omstart;
4675
}
4676
4677
if(maxindx > noknots) {
4678
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
4679
4680
for(i=1; i <= noelements; i++) {
4681
elementtype = data->elementtypes[i];
4682
elemnodes = elementtype % 100;
4683
4684
for(j=0;j<elemnodes;j++) {
4685
k = data->topology[i][j];
4686
if(k <= 0 || k > maxindx)
4687
printf("index out of bounds %d\n",k);
4688
else if(revindx[k] <= 0)
4689
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
4690
else
4691
data->topology[i][j] = revindx[k];
4692
}
4693
}
4694
free_Ivector(revindx,1,maxindx);
4695
}
4696
4697
ModifyUnsupportedElements(data);
4698
4699
ElementsToBoundaryConditions(data,bound,keeporphans,info);
4700
4701
data->bodynamesexist = physvolexist;
4702
data->boundarynamesexist = physsurfexist;
4703
4704
if( tagsize > 0 ) free_Imatrix(tagmap,0,3,1,tagsize);
4705
4706
if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
4707
4708
return(0);
4709
}
4710
4711
4712
static int LoadGmshInput41(struct FemType *data,struct BoundaryType *bound,
4713
char *filename,int usetaggeom, int keeporphans, int gmshbinary, int info)
4714
{
4715
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
4716
int elemind[MAXNODESD2],elementtype;
4717
int i,j,k,l,allocated,*revindx=NULL,maxindx;
4718
int elemno, gmshtype, tagphys=0, tagpart, elemnodes,maxelemtype;
4719
int tagmat,verno,meshdim,tagdim,frcount;
4720
int physvolexist, physsurfexist,**tagmap,tagsize;
4721
int maxtag[4],mintag[4],maxreadtag[4],minreadtag[4];
4722
int maxphystag[4],minphystag[4],tagoffset[4],phystagoffset[4];
4723
FILE *in;
4724
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
4725
char *cp,line[MAXLINESIZE],longline[LONGLINESIZE];
4726
4727
if ((in = fopen(filename,"rb")) == NULL) {
4728
printf("The opening of the mesh file %s failed!\n",filename);
4729
return(1);
4730
}
4731
if(info) printf("Loading mesh in Gmsh format 4.1 from file %s\n",filename);
4732
4733
allocated = FALSE;
4734
dim = data->dim;
4735
meshdim = 0;
4736
maxnodes = 0;
4737
maxindx = 0;
4738
maxelemtype = 0;
4739
physvolexist = FALSE;
4740
physsurfexist = FALSE;
4741
usetaggeom = TRUE; /* The default */
4742
for(i=0;i<4;i++) {
4743
maxtag[i] = mintag[i] = -1;
4744
minreadtag[i] = maxreadtag[i] = -1;
4745
maxphystag[i] = minphystag[i] = -1;
4746
tagoffset[i] = phystagoffset[i] = 0;
4747
}
4748
4749
omstart:
4750
4751
if(allocated) printf("Leading element dimension is %d\n",meshdim);
4752
4753
for(;;) {
4754
if(Getrow(line,in,FALSE)) goto end;
4755
if(strstr(line,"$End")) continue;
4756
4757
if(strstr(line,"$MeshFormat")) {
4758
GETLINE;
4759
if(gmshbinary){
4760
int one;
4761
frcount = fread(&one, sizeof(int), 1, in);
4762
if(one != 1) {
4763
printf("Gmsh binary file needs to swap bytes, not implemented in ElmerGrid. Exiting!\n");
4764
bigerror("Gmsh binary file needs to swap bytes, not implemented in ElmerGrid. Exiting!");
4765
}
4766
GETLINE;
4767
}
4768
GETLINE;
4769
if(!strstr(line,"$EndMeshFormat"))
4770
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
4771
}
4772
4773
else if(strstr(line,"$Nodes")) {
4774
int numEntityBlocks,tagEntity,dimEntity,parEntity,numNodes;
4775
int minNodeTag, maxNodeTag, parTag;
4776
size_t tagNode;
4777
4778
if(gmshbinary) {
4779
size_t inputData[4];
4780
frcount = fread(inputData, sizeof(size_t), 4, in);
4781
if(frcount != 4)
4782
printf("1 fread error, frcount = %d, not equal to %d\n",frcount,4);
4783
numEntityBlocks = (int) inputData[0];
4784
noknots = (int) inputData[1];
4785
minNodeTag = (int) inputData[2];
4786
maxNodeTag = (int) inputData[3];
4787
}
4788
else {
4789
GETLINE;
4790
cp = line;
4791
numEntityBlocks = next_int(&cp);
4792
noknots = next_int(&cp);
4793
minNodeTag = next_int(&cp);
4794
maxNodeTag = next_int(&cp);
4795
}
4796
if(allocated && info) printf("Reading %d nodes in %d blocks.\n",
4797
noknots,numEntityBlocks);
4798
4799
k = 0;
4800
4801
for(j=1; j <= numEntityBlocks; j++) {
4802
if(gmshbinary) {
4803
int inputData[3];
4804
size_t numNodesInBlock;
4805
frcount = fread(inputData, sizeof(int), 3, in);
4806
if(frcount != 3)
4807
printf("2 fread error, frcount = %d, not equal to %d\n",frcount,3);
4808
dimEntity = inputData[0];
4809
tagEntity = inputData[1];
4810
parTag = inputData[2];
4811
4812
frcount = fread(&numNodesInBlock, sizeof(size_t), 1, in);
4813
if(frcount != 1)
4814
printf("3 fread error, frcount = %d, not equal to %d\n",frcount,1);
4815
numNodes = (int) numNodesInBlock;
4816
}
4817
else {
4818
GETLINE;
4819
cp = line;
4820
dimEntity = next_int(&cp);
4821
tagEntity = next_int(&cp);
4822
parTag = next_int(&cp);
4823
numNodes = next_int(&cp);
4824
}
4825
4826
if( 0 && numNodes > 1 ) printf("Reading node block %d with %d nodes\n",j,numNodes);
4827
4828
for(i=1; i <= numNodes; i++) {
4829
if(gmshbinary) {
4830
frcount = fread(&tagNode, sizeof(size_t), 1, in);
4831
if(frcount != 1)
4832
printf("4 fread error, frcount = %d, not equal to %d\n",frcount,1);
4833
}
4834
else {
4835
GETLINE;
4836
cp = line;
4837
tagNode = next_int(&cp);
4838
}
4839
4840
if( 0 && numNodes > 1 ) printf("block %d node %d tagNode %lu %d\n",j,i,(unsigned long)tagNode,k+i);
4841
4842
if(allocated) {
4843
if(maxindx > noknots) revindx[tagNode] = k+i;
4844
}
4845
else {
4846
maxindx = MAX(tagNode,maxindx);
4847
}
4848
}
4849
4850
for(i=1; i <= numNodes; i++) {
4851
if(gmshbinary) {
4852
double inputData[3];
4853
frcount = fread(inputData, sizeof(double), 3, in);
4854
if(frcount != 3)
4855
printf("5 fread error, frcount = %d, not equal to %d\n",frcount,3);
4856
if(allocated) {
4857
data->x[k+i] = inputData[0];
4858
data->y[k+i] = inputData[1];
4859
data->z[k+i] = inputData[2];
4860
}
4861
}
4862
else {
4863
double x,y,z;
4864
GETLINE;
4865
cp = line;
4866
if(allocated) {
4867
data->x[k+i] = next_real(&cp);
4868
data->y[k+i] = next_real(&cp);
4869
data->z[k+i] = next_real(&cp);
4870
}
4871
}
4872
}
4873
k += numNodes;
4874
}
4875
if(gmshbinary) GETLINE;
4876
GETLINE;
4877
if(!strstr(line,"$EndNodes"))
4878
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
4879
}
4880
4881
else if(strstr(line,"$Entities")) {
4882
int numPoints, numCurves, numSurfaces, numVolumes, numEnt;
4883
int tag,phystag;
4884
size_t nophys,nobound;
4885
int idum;
4886
Real rdum;
4887
4888
usetaggeom = FALSE;
4889
4890
if(gmshbinary) {
4891
size_t data[4];
4892
frcount = fread(data, sizeof(size_t), 4, in);
4893
if(frcount != 4)
4894
printf("6 fread error, frcount = %d, not equal to %d\n",frcount,4);
4895
numPoints = (int) data[0];
4896
numCurves = (int) data[1];
4897
numSurfaces = (int) data[2];
4898
numVolumes = (int) data[3];
4899
}
4900
else {
4901
GETLINE;
4902
cp = line;
4903
numPoints = next_int(&cp);
4904
numCurves = next_int(&cp);
4905
numSurfaces = next_int(&cp);
4906
numVolumes = next_int(&cp);
4907
}
4908
4909
if(allocated) {
4910
tagsize = 0;
4911
for(tagdim=0; tagdim<=meshdim; tagdim++)
4912
tagsize = MAX( tagsize, maxtag[tagdim]);
4913
if(info) printf("Allocating lookup table for tags of size %d\n",tagsize);
4914
if( tagsize > 0 ) {
4915
tagmap = Imatrix(0,3,1,tagsize);
4916
for(i=0; i<=3; i++)
4917
for(j=1; j<=tagsize; j++)
4918
tagmap[i][j] = 0;
4919
}
4920
}
4921
for(tagdim=0; tagdim<=3; tagdim++) {
4922
4923
if( tagdim == 0 )
4924
numEnt = numPoints;
4925
else if( tagdim == 1 )
4926
numEnt = numCurves;
4927
else if( tagdim == 2 )
4928
numEnt = numSurfaces;
4929
else if( tagdim == 3 )
4930
numEnt = numVolumes;
4931
4932
if(allocated && numEnt > 0 ) {
4933
if( maxtag[tagdim] > 0 ) {
4934
if( mintag[tagdim] == -1 ) mintag[tagdim] = maxtag[tagdim];
4935
if( minphystag[tagdim] == -1) minphystag[tagdim] = maxphystag[tagdim];
4936
printf("Defined %d %dDIM entities with geometric tag range [%d %d]\n",
4937
numEnt,tagdim,mintag[tagdim],maxtag[tagdim]);
4938
if( maxphystag[tagdim] > 0 || maxreadtag[tagdim] > 0 ) {
4939
printf(" Physical given tag range is [%d %d]\n",minphystag[tagdim],maxphystag[tagdim]);
4940
if( maxreadtag[tagdim] != maxphystag[tagdim] || minreadtag[tagdim] != minphystag[tagdim]) {
4941
if(maxreadtag[tagdim] > 0 )
4942
printf(" Physical read tag range is [%d %d]\n",minreadtag[tagdim],maxreadtag[tagdim]);
4943
else
4944
printf(" No physical tags read for real!\n");
4945
if(0) smallerror("Physical names not used consistently!");
4946
}
4947
} else {
4948
if(0) printf("No physical tags defined, using geometric entities!\n");
4949
}
4950
4951
}
4952
if( tagdim > meshdim ) {
4953
printf("We have %d %dDIM tags that are beyond mesh dimension %d!\n",
4954
numEnt, tagdim, meshdim );
4955
}
4956
}
4957
4958
if(numEnt > 0 && !allocated) printf("Reading %d entities in %dD\n",numEnt,tagdim);
4959
4960
for(i=1; i <= numEnt; i++) {
4961
if(gmshbinary) {
4962
frcount = fread(&tag, sizeof(int), 1, in);
4963
if(frcount != 1)
4964
printf("7 fread error, frcount = %d, not equal to %d\n",frcount,1);
4965
4966
if(tagdim == 0) {
4967
double inputData3[3];
4968
// read away the bounding box data that we do not need for anything
4969
frcount = fread(&inputData3, sizeof(double), 3, in);
4970
if(frcount != 3)
4971
printf("8 fread error, frcount = %d, not equal to %d\n",frcount,3);
4972
frcount = fread(&nophys, sizeof(size_t), 1, in);
4973
if(frcount != 1)
4974
printf("9 fread error, frcount = %d, not equal to %d\n",frcount,1);
4975
if(nophys > 0) {
4976
frcount = fread(&phystag, sizeof(int), nophys, in);
4977
if(frcount != (int) nophys)
4978
printf("9 fread error, frcount = %d, not equal to %lu\n",
4979
frcount,(unsigned long) nophys);
4980
}
4981
} else {
4982
double inputData6[6];
4983
// read away the bounding box data that we do not need for anything
4984
frcount = fread(&inputData6, sizeof(double), 6, in);
4985
if(frcount != 6)
4986
printf("10 fread error, frcount = %d, not equal to %d\n",frcount,6);
4987
frcount = fread(&nophys, sizeof(size_t), 1, in);
4988
if(frcount != 1)
4989
printf("11 fread error, frcount = %d, not equal to %d\n",frcount,1);
4990
if(nophys > 0) {
4991
frcount = fread(&phystag, sizeof(int), nophys, in);
4992
if(frcount != (int) nophys)
4993
printf("12 fread error, frcount = %d, not equal to %lu\n",
4994
frcount,(unsigned long) nophys);
4995
}
4996
frcount = fread(&nobound, sizeof(size_t), 1, in);
4997
if(frcount != 1)
4998
printf("13 fread error, frcount = %d, not equal to %d\n",frcount,1);
4999
5000
int noboundint = (int) nobound;
5001
if(noboundint > 0) {
5002
for( k= 0; k < noboundint; k++) {
5003
frcount = fread(&idum, sizeof(int), 1, in);
5004
if(frcount != 1)
5005
printf("14 fread error, frcount = %d, not equal to %d\n",frcount,1);
5006
}
5007
}
5008
}
5009
// Read the first physical tag if there are any
5010
if( nophys > 0 ) {
5011
if(!allocated) {
5012
maxreadtag[tagdim] = MAX( maxreadtag[tagdim], phystag );
5013
if( minreadtag[tagdim] == -1 ) {
5014
minreadtag[tagdim] = phystag;
5015
}
5016
else {
5017
minreadtag[tagdim] = MIN( minreadtag[tagdim], phystag );
5018
}
5019
}
5020
else {
5021
tagmap[tagdim][tag] = phystag;
5022
}
5023
}
5024
}
5025
else {
5026
GETLONGLINE;
5027
// printf("%d line of dim %d with %d entries: %s\n",i,tagdim,numEnt,line);
5028
5029
//if( tagdim == 0 ) continue;
5030
5031
cp = longline;
5032
tag = next_int(&cp);
5033
5034
if(!allocated) {
5035
maxtag[tagdim] = MAX( maxtag[tagdim], tag );
5036
if( mintag[tagdim] == -1 ) {
5037
mintag[tagdim] = tag;
5038
}
5039
else {
5040
mintag[tagdim] = MIN( mintag[tagdim], tag );
5041
}
5042
}
5043
5044
// read away the bounding box data that we do not need for anything
5045
if(tagdim == 0)
5046
k = 3;
5047
else
5048
k = 6;
5049
for(j=1; j<=k; j++) rdum = next_real(&cp);
5050
5051
// Number of physical tags
5052
nophys = next_int(&cp);
5053
5054
// Read the first physical tag if there are any
5055
if( nophys > 0 ) {
5056
if(0) printf("Reading number of physical tags: %lu\n",(unsigned long) nophys);
5057
phystag = next_int(&cp);
5058
if(!allocated) {
5059
if(0) printf("Phystag: %d %d %d %d\n",tagdim,tag,i,phystag);
5060
maxreadtag[tagdim] = MAX( maxreadtag[tagdim], phystag );
5061
if( minreadtag[tagdim] == -1 ) {
5062
minreadtag[tagdim] = phystag;
5063
}
5064
else {
5065
minreadtag[tagdim] = MIN( minreadtag[tagdim], phystag );
5066
}
5067
}
5068
else {
5069
tagmap[tagdim][tag] = phystag;
5070
}
5071
}
5072
}
5073
5074
if(!allocated) {
5075
maxtag[tagdim] = MAX( maxtag[tagdim], tag );
5076
if( mintag[tagdim] == -1 ) {
5077
mintag[tagdim] = tag;
5078
}
5079
else {
5080
mintag[tagdim] = MIN( mintag[tagdim], tag );
5081
}
5082
}
5083
if(!gmshbinary) {
5084
// The lines may be too long. So fill the string buffer until we get a newline.
5085
j = k = 0;
5086
for(;;) {
5087
for(l=0; l<LONGLINESIZE; l++) {
5088
if( longline[l] == '\n') {
5089
// we should have positive j even when the newline is the 0th entry!
5090
j = l+1;
5091
break;
5092
}
5093
}
5094
if(j) {
5095
j--;
5096
break;
5097
}
5098
k += LONGLINESIZE;
5099
GETLONGLINE;
5100
if(0) printf("extra getlongline: %s\n",longline);
5101
fflush(stdout);
5102
}
5103
if( k > 0 && !allocated) printf("Entity line %d has length %d.\n",i,k+j);
5104
}
5105
}
5106
}
5107
5108
for(tagdim=meshdim-2;tagdim>=0;tagdim--) {
5109
phystagoffset[tagdim] = phystagoffset[tagdim+1]+MAX(0,maxphystag[tagdim+1]);
5110
printf("Physical tag offset for %dD is %d\n",tagdim,phystagoffset[tagdim]);
5111
}
5112
5113
if(meshdim>0) {
5114
tagoffset[meshdim] = maxphystag[meshdim];
5115
tagoffset[meshdim-1] = phystagoffset[0];
5116
}
5117
for(tagdim=meshdim-2;tagdim>=0;tagdim--) {
5118
tagoffset[tagdim] = tagoffset[tagdim+1]+MAX(0,maxtag[tagdim+1]);
5119
printf("Geometric tag offset for %dD is %d\n",tagdim,tagoffset[tagdim]);
5120
}
5121
5122
if(gmshbinary) GETLONGLINE;
5123
GETLONGLINE;
5124
if(!strstr(longline,"$EndEntities"))
5125
printf("$Entities section should end to string $EndEntities:\n%s\n",longline);
5126
}
5127
5128
else if(strstr(line,"$Elements")) {
5129
size_t numEntityBlocks, minElementTag, maxElementTag;
5130
size_t numElementsInBlock;
5131
int dimEntity, tagEntity, typeEle, numElements;
5132
5133
k = 0;
5134
5135
if(gmshbinary) {
5136
size_t data[4], totalNumElements;
5137
frcount = fread(data, sizeof(size_t), 4, in);
5138
if(frcount != 4)
5139
printf("17 fread error, frcount = %d, not equal to %d\n",frcount,4);
5140
numEntityBlocks = data[0];
5141
totalNumElements = data[1];
5142
noelements = (int) totalNumElements;
5143
minElementTag = data[2];
5144
maxElementTag = data[3];
5145
}
5146
else {
5147
GETLINE;
5148
cp = line;
5149
numEntityBlocks = next_int(&cp);
5150
noelements = next_int(&cp);
5151
minElementTag = next_int(&cp);
5152
maxElementTag = next_int(&cp);
5153
}
5154
5155
if(allocated) printf("Reading %d elements in %lu blocks.\n",noelements,(unsigned long) numEntityBlocks);
5156
5157
for(j=1; j<= (int) numEntityBlocks; j++ ) {
5158
5159
if(gmshbinary) {
5160
int data[3];
5161
frcount = fread(data, sizeof(int), 3, in);
5162
if(frcount != 3)
5163
printf("18 fread error, frcount = %d, not equal to %d\n",frcount,3);
5164
dimEntity = data[0];
5165
tagEntity = data[1];
5166
typeEle = data[2];
5167
frcount = fread(&numElementsInBlock, sizeof(size_t), 1, in);
5168
if(frcount != 1)
5169
printf("19 fread error, frcount = %d, not equal to %d\n",frcount,1);
5170
numElements = (int) numElementsInBlock;
5171
}
5172
else {
5173
GETLINE;
5174
cp = line;
5175
dimEntity = next_int(&cp);
5176
tagEntity = next_int(&cp);
5177
typeEle = next_int(&cp);
5178
numElements = next_int(&cp);
5179
}
5180
5181
elementtype = GmshToElmerType(typeEle);
5182
if(!elementtype)
5183
bigerror("Gmsh element type does not have an Elmer counterpart!\n");
5184
elemnodes = elementtype % 100;
5185
maxelemtype = MAX(maxelemtype,elementtype);
5186
5187
if(!allocated) meshdim = MAX(meshdim, GetElementDimension(elementtype));
5188
5189
if( allocated ) {
5190
if( tagsize > 0 ) {
5191
if( tagmap[dimEntity][tagEntity] ) {
5192
printf(" Mapping mesh tag %d to physical tag %d in %dDIM\n",
5193
tagEntity,tagmap[dimEntity][tagEntity],dimEntity);
5194
tagEntity = tagmap[dimEntity][tagEntity] + phystagoffset[dimEntity];
5195
}
5196
else {
5197
tagEntity += tagoffset[dimEntity];
5198
}
5199
}
5200
else {
5201
tagEntity += tagoffset[dimEntity];
5202
}
5203
}
5204
5205
size_t elementTag, nodeTag[126];
5206
// nodeTag size is based on gmsh element type 93, 125-node fourth order hexahedron
5207
// if newer and larger elements are added, then increase nodeTag size to match
5208
if(elemnodes > 125) {
5209
printf("error: number of nodes per element of %d, exceeds 125\n",elemnodes);
5210
printf("increase size of nodeTag and recompile. Exiting!\n");
5211
bigerror("number of nodes per element exceeds 125. Exiting!");
5212
}
5213
5214
for(int m=1; m <= numElements; m++) {
5215
if(gmshbinary) {
5216
frcount = fread(&elementTag, sizeof(size_t), 1, in);
5217
if(frcount != 1)
5218
printf("20 fread error, frcount = %d, not equal to %d\n",frcount,1);
5219
elemno = (int) elementTag;
5220
5221
k += 1;
5222
5223
if(allocated) {
5224
data->elementtypes[k] = elementtype;
5225
data->material[k] = tagEntity;
5226
frcount = fread(nodeTag, sizeof(size_t), elemnodes, in);
5227
if(frcount != elemnodes)
5228
printf("21 fread error, frcount = %d, not equal to %d\n",frcount,elemnodes);
5229
5230
for(l=0; l<elemnodes; l++){
5231
elemind[l] = (int) nodeTag[l];
5232
}
5233
5234
GmshToElmerIndx(elementtype,elemind);
5235
5236
for(l=0; l<elemnodes; l++)
5237
data->topology[k][l] = elemind[l];
5238
}
5239
else {
5240
frcount = fread(nodeTag, sizeof(size_t), elemnodes, in);
5241
if(frcount != elemnodes)
5242
printf("22 fread error, frcount = %d, not equal to %d\n",frcount,elemnodes);
5243
}
5244
}
5245
else {
5246
GETLINE;
5247
cp = line;
5248
elemno = next_int(&cp);
5249
5250
k += 1;
5251
5252
if(allocated) {
5253
data->elementtypes[k] = elementtype;
5254
data->material[k] = tagEntity;
5255
for(l=0; l<elemnodes; l++)
5256
elemind[l] = next_int(&cp);
5257
5258
GmshToElmerIndx(elementtype,elemind);
5259
5260
for(l=0; l<elemnodes; l++)
5261
data->topology[k][l] = elemind[l];
5262
}
5263
}
5264
}
5265
}
5266
5267
if(gmshbinary) GETLINE;
5268
GETLINE;
5269
if(!strstr(line,"$EndElements"))
5270
printf("$Elements section should end to string $EndElements:\n%s\n",line);
5271
}
5272
5273
else if(strstr(line,"$PhysicalNames")) {
5274
int entdim;
5275
entdim = dim;
5276
5277
GETLINE;
5278
cp = line;
5279
nophysical = next_int(&cp);
5280
for(i=0; i<nophysical; i++) {
5281
GETLINE;
5282
cp = line;
5283
tagdim = next_int(&cp);
5284
tagphys = next_int(&cp);
5285
5286
if(!allocated) {
5287
maxphystag[tagdim] = MAX( maxphystag[tagdim], tagphys );
5288
if( minphystag[tagdim] == -1 ) {
5289
minphystag[tagdim] = tagphys;
5290
}
5291
else {
5292
minphystag[tagdim] = MIN( minphystag[tagdim], tagphys );
5293
}
5294
}
5295
else if(allocated) {
5296
// We must not let different tags be overrun
5297
l = phystagoffset[tagdim];
5298
5299
if(tagdim < meshdim) {
5300
physsurfexist = TRUE;
5301
if(tagphys+l < MAXBCS) {
5302
data->boundarynamesexist = TRUE;
5303
if(!data->boundaryname[tagphys+l]) data->boundaryname[tagphys+l] = Cvector(0,MAXNAMESIZE);
5304
sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys+l]);
5305
printf("BC name for physical group %d is: %s\n",tagphys,data->boundaryname[tagphys+l]);
5306
}
5307
else {
5308
printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[tagdim],cp+1);
5309
}
5310
}
5311
else if(tagdim == meshdim) {
5312
physvolexist = TRUE;
5313
if(tagphys < MAXBODIES) {
5314
data->bodynamesexist = TRUE;
5315
if(!data->bodyname[tagphys]) data->bodyname[tagphys] = Cvector(0,MAXNAMESIZE);
5316
sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
5317
printf("Body name for physical group %d is: %s\n",tagphys,data->bodyname[tagphys]);
5318
}
5319
else {
5320
printf("Index %d too large: ignoring physical %s %s",tagphys,manifoldname[tagdim],cp+1);
5321
}
5322
}
5323
}
5324
}
5325
5326
GETLINE;
5327
if(!strstr(line,"$EndPhysicalNames"))
5328
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
5329
}
5330
else if(strstr(line,"$Periodic")) {
5331
int numPeriodicLinks;
5332
if(allocated) printf("Reading periodic links but doing nothing with them!\n");
5333
5334
if(1) {
5335
numPeriodicLinks = 0;
5336
for(;;) {
5337
GETLINE;
5338
if(strstr(line,"$EndPeriodic")) {
5339
if(allocated) printf("Number of lines for periodic stuff: %d\n",numPeriodicLinks);
5340
break;
5341
}
5342
numPeriodicLinks++;
5343
}
5344
}
5345
else {
5346
GETLINE;
5347
cp = line;
5348
numPeriodicLinks = next_int(&cp);
5349
for(i=1; i <= numPeriodicLinks; i++) {
5350
GETLINE;
5351
}
5352
GETLINE;
5353
if(!strstr(line,"$EndPeriodic")) {
5354
printf("$Periodic section should end to string $EndPeriodic:\n%s\n",line);
5355
}
5356
}
5357
}
5358
5359
else if(strstr(line,"$PartitionedEntities")) {
5360
if(allocated) printf("Reading partitioned entities but doing nothing with them!\n");
5361
for(;;) {
5362
GETLINE;
5363
if(strstr(line,"$EndPartitionedEntities")) break;
5364
}
5365
}
5366
else if(strstr(line,"$NodeData")) {
5367
if(allocated) printf("Reading node data but doing nothing with them!\n");
5368
for(;;) {
5369
GETLINE;
5370
if(strstr(line,"$EndNodeData")) break;
5371
}
5372
}
5373
else if(strstr(line,"$ElementData")) {
5374
if(allocated) printf("Reading element data but doing nothing with them!\n");
5375
for(;;) {
5376
GETLINE;
5377
if(strstr(line,"$EndElementData")) break;
5378
}
5379
}
5380
else if(strstr(line,"$ElementNodeData")) {
5381
if(allocated) printf("Reading element node data but doing nothing with them!\n");
5382
for(;;) {
5383
GETLINE;
5384
if(strstr(line,"$EndElementNodeData")) break;
5385
}
5386
}
5387
else if(strstr(line,"$GhostElements")) {
5388
if(allocated) printf("Reading ghost elements data but doing nothing with them!\n");
5389
for(;;){
5390
GETLINE;
5391
if(strstr(line,"$EndGhostElements")) break;
5392
}
5393
}
5394
else if(strstr(line,"$InterpolationScheme")) {
5395
if(allocated) printf("Reading interpolation scheme but doing nothing with them!\n");
5396
for(;;) {
5397
GETLINE;
5398
if(strstr(line,"$EndInterpolationScheme")) break;
5399
}
5400
}
5401
else {
5402
if(allocated) printf("Untreated command: %s",line);
5403
}
5404
}
5405
5406
end:
5407
5408
5409
if(!allocated) {
5410
if( noelements == 0 ) bigerror("No elements to load in Gmsh file!");
5411
if( noknots == 0 ) bigerror("No nodes to load in Gmsh file!");
5412
5413
maxnodes = maxelemtype % 100;
5414
InitializeKnots(data);
5415
data->dim = dim;
5416
data->maxnodes = maxnodes;
5417
data->noelements = noelements;
5418
data->noknots = noknots;
5419
5420
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
5421
AllocateKnots(data);
5422
5423
if(maxindx > noknots) {
5424
revindx = Ivector(1,maxindx);
5425
for(i=1;i<=maxindx;i++) revindx[i] = 0;
5426
}
5427
rewind(in);
5428
allocated = TRUE;
5429
goto omstart;
5430
}
5431
5432
if(maxindx > noknots) {
5433
int cnt1,cnt2,cnt3,cnt4;
5434
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
5435
5436
cnt1 = cnt2 = cnt3 = cnt4 = 0;
5437
5438
for(i=1;i<=maxindx;i++)
5439
if(revindx[i]) cnt1++;
5440
printf(" Number of tagged nodes in reverse index table (out of %d): %d\n",maxindx,cnt1);
5441
5442
5443
for(i=1; i <= noelements; i++) {
5444
elementtype = data->elementtypes[i];
5445
elemnodes = elementtype % 100;
5446
5447
for(j=0; j<elemnodes; j++) {
5448
k = data->topology[i][j];
5449
if(k <= 0 || k > maxindx) {
5450
if(cnt2<10) printf(" index out of bounds %d\n",k);
5451
if(cnt2==10) printf(" ...\n");
5452
cnt2++;
5453
}
5454
else if(revindx[k] <= 0) {
5455
if(cnt3<10) printf(" node %d (local node %d in element %d of type %d) not found in revindx!\n",k,j+1,i,elementtype);
5456
if(cnt3==10) printf(" ...\n");
5457
cnt3++;
5458
}
5459
else {
5460
cnt4++;
5461
data->topology[i][j] = revindx[k];
5462
}
5463
}
5464
}
5465
if(cnt2) printf(" Number of node indexes out of bounds [0 %d]: %d\n",maxindx,cnt2);
5466
if(cnt3) printf(" Number of node indexes not found in inverse index table: %d\n",cnt3);
5467
if(cnt4) printf(" Number of node indexes found in inverse index table: %d\n",cnt4);
5468
5469
free_Ivector(revindx,1,maxindx);
5470
}
5471
5472
ModifyUnsupportedElements(data);
5473
5474
ElementsToBoundaryConditions(data,bound,keeporphans,info);
5475
5476
data->bodynamesexist = physvolexist;
5477
data->boundarynamesexist = physsurfexist;
5478
5479
if( tagsize > 0 ) free_Imatrix(tagmap,0,3,1,tagsize);
5480
5481
if(info) printf("Successfully read the mesh from the Gmsh input file %s\n",filename);
5482
5483
return(0);
5484
}
5485
5486
int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,
5487
char *prefix,int keeporphans,int dim,int info)
5488
{
5489
FILE *in;
5490
char line[MAXLINESIZE],filename[MAXFILESIZE];
5491
int errnum,usetaggeom,i;
5492
5493
/* keeprophans - Should we keep lower order elements not associated to any
5494
higher order entity? ElmerGUI certainly does not like it. */
5495
5496
sprintf(filename,"%s",prefix);
5497
if ((in = fopen(filename,"r")) == NULL) {
5498
sprintf(filename,"%s.msh",prefix);
5499
if ((in = fopen(filename,"r")) == NULL) {
5500
printf("LoadGmshInput: The opening of the mesh file %s failed!\n",filename);
5501
return(1);
5502
}
5503
}
5504
5505
Getrow(line,in,FALSE);
5506
5507
if(info) printf("Format chosen using the first line: %s",line);
5508
5509
if(strstr(line,"$MeshFormat")) {
5510
// gmsh uses floating point for the version number, so let's also use floating point.
5511
// using the gmsh method with a double, actually works better and
5512
// is able to detect types 1 and 3 formats.
5513
double gmshversion;
5514
int gmshbinary,gmshsize;
5515
5516
Getrow(line,in,FALSE);
5517
fclose(in);
5518
5519
if(sscanf(line, "%lf %d %d", &gmshversion, &gmshbinary, &gmshsize) != 3) {
5520
printf("Gmsh input line: %s, expected but didn't receive three items on line. Exiting!\n",line);
5521
printf("Input line: %s\n",line);
5522
bigerror("Gmsh input line didn't receive the expected three items!");
5523
}
5524
5525
// gmshversion is a float, hence the ugly decimal points to insure proper comparisons
5526
if(gmshversion < 2.99) {
5527
if(gmshbinary) {
5528
printf("Gmsh input file format is type %5.1f, binary is not supported.\n",gmshversion);
5529
printf("If binary is needed, use Gmsh format 4.1 for output from Gmsh\n");
5530
bigerror("Gmsh input file in format 2.x, binary is not supported!");
5531
} else {
5532
printf("Gmsh input file format is type %5.1f in ASCII.\n",gmshversion);
5533
errnum = LoadGmshInput2(data,bound,filename,usetaggeom,keeporphans,info);
5534
}
5535
} else if(gmshversion < 3.99) {
5536
printf("Gmsh input file of format type %5.1f, is not supported. Exiting!\n",gmshversion);
5537
printf("Please use Gmsh 4 versions for output from Gmsh\n");
5538
bigerror("Gmsh input file format is not supported!");
5539
} else if(gmshversion < 4.09) {
5540
printf("Gmsh input file format is type %5.1f in ASCII.\n",gmshversion);
5541
errnum = LoadGmshInput4(data,bound,filename,usetaggeom,keeporphans,info);
5542
} else if(gmshversion < 5.0) {
5543
if(gmshbinary) {
5544
printf("Gmsh input file format is type %5.1f in binary.\n",gmshversion);
5545
} else {
5546
printf("Gmsh input file format is type %5.1f in ASCII.\n",gmshversion);
5547
}
5548
errnum = LoadGmshInput41(data,bound,filename,usetaggeom,keeporphans,gmshbinary,info);
5549
} else {
5550
printf("Gmsh input file of format type %5.1f, is not supported. Exiting!\n",gmshversion);
5551
printf("Please use Gmsh 4 versions for output from Gmsh\n");
5552
bigerror("Gmsh input file format is not supported!");
5553
}
5554
} else {
5555
printf("*****************************************************\n");
5556
printf("The first line did not start with $MeshFormat, assuming Gmsh 1 format\n");
5557
printf("This version of Gmsh format is no longer supported\n");
5558
printf("Please use Gmsh 4 versions for output from Gmsh\n");
5559
printf("*****************************************************\n");
5560
5561
errnum = LoadGmshInput1(data,bound,filename,info);
5562
}
5563
5564
if( info ) {
5565
if( usetaggeom )
5566
printf("Using geometric numbering of entities\n");
5567
else
5568
printf("Using physical numbering of entities\n");
5569
}
5570
5571
if(dim < 3)
5572
for(i=1;i<=data->noknots;i++) data->z[i] = 0.0;
5573
if(dim < 2)
5574
for(i=1;i<=data->noknots;i++) data->y[i] = 0.0;
5575
5576
return(errnum);
5577
}
5578
5579
5580
5581
int LoadFvcomMesh(struct FemType *data,struct BoundaryType *bound,
5582
char *filename,int info)
5583
{
5584
int noknots = 0,noelements = 0,maxnodes,dim;
5585
int elemind[MAXNODESD2],elementtype;
5586
int i,j,k,allocated,*revindx=NULL,maxindx;
5587
int elemnodes,maxelemtype,elemtype0,bclines;
5588
int tagmat,bccount;
5589
int *bcinds,*bctags,nbc,nbc0,bc_id;
5590
FILE *in;
5591
char *cp,line[MAXLINESIZE];
5592
5593
5594
if ((in = fopen(filename,"r")) == NULL) {
5595
printf("LoadFVCOMInput: The opening of the FVCOM mesh file %s failed!\n",filename);
5596
return(1);
5597
}
5598
if(info) printf("Loading mesh in FVCOM format from file %s\n",filename);
5599
5600
allocated = FALSE;
5601
dim = 2;
5602
maxnodes = 0;
5603
maxindx = 0;
5604
maxelemtype = 303;
5605
5606
noelements = 0;
5607
bclines = 0;
5608
5609
5610
omstart:
5611
5612
noelements = 0;
5613
noknots = 0;
5614
nbc = 0;
5615
nbc0 = 1;
5616
bclines = 0;
5617
bccount = 0;
5618
5619
for(;;) {
5620
if(Getrow(line,in,FALSE)) goto end;
5621
if(line[0]=='\0') goto end;
5622
5623
if(memcmp(line,"E3T",3) == 0 ) {
5624
noelements += 1;
5625
if(allocated) {
5626
cp = line+4;
5627
i = next_int(&cp);
5628
if(i != noelements ) printf("Invalid element number: %d %d\n",noelements,i);
5629
5630
data->elementtypes[i] = 303;
5631
for(k=0;k<3;k++)
5632
data->topology[i][k] = next_int(&cp);
5633
data->material[i] = next_int(&cp);
5634
}
5635
}
5636
else if(memcmp(line,"ND",2) == 0 ) {
5637
noknots += 1;
5638
if(allocated) {
5639
cp = line+3;
5640
i = next_int(&cp);
5641
if(i != noknots ) printf("Invalid node number: %d %d\n",noknots,i);
5642
data->x[i] = next_real(&cp);
5643
data->y[i] = next_real(&cp);
5644
if(dim > 2) data->z[i] = next_real(&cp);
5645
}
5646
}
5647
else if(memcmp(line,"NS",2) == 0 ) {
5648
bclines += 1;
5649
5650
if(allocated){
5651
cp = line+3;
5652
5653
for(i=0;i<10;i++) {
5654
j = next_int(&cp);
5655
5656
nbc += 1;
5657
bcinds[nbc] = abs(j);
5658
5659
if( j < 0 ) {
5660
bccount += 1;
5661
bc_id = next_int(&cp);
5662
5663
for(k=nbc0;k<=nbc;k++)
5664
bctags[k] = bc_id;
5665
5666
nbc0 = nbc+1;
5667
break;
5668
}
5669
}
5670
}
5671
}
5672
else if(memcmp(line,"MESH2D",6) == 0 ) {
5673
if(!allocated) printf("Yes, we have MESH2D as we should\n");
5674
}
5675
else if(memcmp(line,"MESHNAME",8) == 0 ) {
5676
if(!allocated) printf("Mesh name found but not used: %s\n",line+9);
5677
}
5678
}
5679
5680
end:
5681
5682
5683
if(!allocated) {
5684
maxnodes = maxelemtype % 100;
5685
InitializeKnots(data);
5686
data->dim = dim;
5687
data->maxnodes = maxnodes;
5688
data->noelements = noelements;
5689
data->noknots = noknots;
5690
5691
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
5692
AllocateKnots(data);
5693
5694
printf("Number of BC lines: %d\n",bclines);
5695
bcinds = Ivector(1,10*bclines);
5696
bctags = Ivector(1,10*bclines);
5697
for(i=1;i<=10*bclines;i++) bcinds[i] = bctags[i] = 0;
5698
5699
rewind(in);
5700
allocated = TRUE;
5701
goto omstart;
5702
}
5703
5704
printf("Number of different BCs: %d\n",bccount);
5705
printf("Number of BC nodes: %d\n",nbc);
5706
5707
NodesToBoundaryChain(data,bound,bcinds,bctags,nbc,bccount,info);
5708
5709
free_Ivector(bcinds,1,10*bclines);
5710
free_Ivector(bctags,1,10*bclines);
5711
5712
if(info) printf("Successfully read the mesh from the FVCOM file!\n");
5713
5714
return(0);
5715
}
5716
5717
5718
int LoadGeoInput(struct FemType *data,struct BoundaryType *bound,
5719
char *filename,int info)
5720
{
5721
int noknots = 0,noelements = 0,maxnodes,dim;
5722
int elemind[MAXNODESD2],elementtype;
5723
int i,j,k,allocated,*revindx=NULL,maxindx;
5724
int elemnodes,maxelemtype,elemtype0;
5725
int tagmat;
5726
FILE *in;
5727
char *cp,line[MAXLINESIZE];
5728
5729
5730
if ((in = fopen(filename,"r")) == NULL) {
5731
printf("LoadGeoInput: The opening of the mesh file %s failed!\n",filename);
5732
return(1);
5733
}
5734
if(info) printf("Loading mesh in geo format from file %s\n",filename);
5735
5736
allocated = FALSE;
5737
dim = 3;
5738
maxnodes = 0;
5739
maxindx = 0;
5740
maxelemtype = 0;
5741
5742
omstart:
5743
5744
5745
for(;;) {
5746
if(Getrow(line,in,FALSE)) goto end;
5747
if(line[0]=='\0') goto end;
5748
if(strstr(line,"$End")) continue;
5749
5750
if(strstr(line,"TYPES")) {
5751
if(!strstr(line,"ALL=TET04")) {
5752
printf("Only all tets implemented at the moment!\n");
5753
return(1);
5754
}
5755
elemtype0 = 504;
5756
GETLINE;
5757
}
5758
else if(strstr(line,"COORDINATES")) {
5759
i = 0;
5760
for(;;) {
5761
GETLINE;
5762
if( strstr(line,"END_COORDINATES")) break;
5763
cp = line;
5764
j = next_int(&cp);
5765
i = i + 1;
5766
if(allocated) {
5767
if(maxindx > noknots) revindx[j] = i;
5768
data->x[i] = next_real(&cp);
5769
data->y[i] = next_real(&cp);
5770
if(dim > 2) data->z[i] = next_real(&cp);
5771
}
5772
else {
5773
maxindx = MAX(j,maxindx);
5774
}
5775
}
5776
noknots = i;
5777
}
5778
else if(strstr(line,"ELEMENTS")) {
5779
i = 0;
5780
elementtype = elemtype0;
5781
tagmat = 1;
5782
5783
for(;;) {
5784
GETLINE;
5785
if( strstr(line,"END_ELEMENTS")) break;
5786
cp = line;
5787
j = next_int(&cp);
5788
i = i + 1;
5789
5790
if(allocated) {
5791
elemnodes = elementtype % 100;
5792
data->elementtypes[i] = elementtype;
5793
data->material[i] = tagmat;
5794
for(k=0;k<elemnodes;k++)
5795
elemind[k] = next_int(&cp);
5796
for(k=0;k<elemnodes;k++)
5797
data->topology[i][k] = elemind[k];
5798
}
5799
else {
5800
maxelemtype = MAX(maxelemtype,elementtype);
5801
}
5802
}
5803
noelements = i;
5804
}
5805
else if ( strstr(line,"BOUNDARIES")) {
5806
for(;;) {
5807
GETLINE;
5808
if( strstr(line,"END_BOUNDARIES")) break;
5809
5810
printf("Implement boundaries!\n");
5811
}
5812
}
5813
}
5814
5815
end:
5816
5817
5818
if(!allocated) {
5819
maxnodes = maxelemtype % 100;
5820
InitializeKnots(data);
5821
data->dim = dim;
5822
data->maxnodes = maxnodes;
5823
data->noelements = noelements;
5824
data->noknots = noknots;
5825
5826
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
5827
AllocateKnots(data);
5828
5829
if(maxindx > noknots) {
5830
revindx = Ivector(1,maxindx);
5831
for(i=1;i<=maxindx;i++) revindx[i] = 0;
5832
}
5833
rewind(in);
5834
allocated = TRUE;
5835
goto omstart;
5836
}
5837
5838
if(maxindx > noknots) {
5839
printf("Renumbering the Geo nodes from %d to %d\n",maxindx,noknots);
5840
5841
for(i=1; i <= noelements; i++) {
5842
elementtype = data->elementtypes[i];
5843
elemnodes = elementtype % 100;
5844
5845
for(j=0;j<elemnodes;j++) {
5846
k = data->topology[i][j];
5847
if(k <= 0 || k > maxindx)
5848
printf("index out of bounds %d\n",k);
5849
else if(revindx[k] <= 0)
5850
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
5851
else
5852
data->topology[i][j] = revindx[k];
5853
}
5854
}
5855
free_Ivector(revindx,1,maxindx);
5856
}
5857
5858
if(0) ElementsToBoundaryConditions(data,bound,FALSE,info);
5859
5860
if(info) printf("Successfully read the mesh from the Geo input file.\n");
5861
5862
return(0);
5863
}
5864
5865
5866
/* Mapping between the element type of Universal file format and
5867
ElmerSolver element type. */
5868
static int UnvToElmerType(int unvtype)
5869
{
5870
int elmertype;
5871
5872
switch (unvtype) {
5873
5874
case 11:
5875
case 21:
5876
elmertype = 202;
5877
break;
5878
5879
case 22:
5880
case 23:
5881
case 24:
5882
elmertype = 203;
5883
break;
5884
5885
case 41:
5886
case 51:
5887
case 61:
5888
case 74:
5889
case 81:
5890
case 91:
5891
elmertype = 303;
5892
break;
5893
5894
case 42:
5895
case 52:
5896
case 62:
5897
case 72:
5898
case 82:
5899
case 92:
5900
elmertype = 306;
5901
break;
5902
5903
case 43:
5904
case 53:
5905
case 63:
5906
case 73:
5907
case 93:
5908
elmertype = 310;
5909
break;
5910
5911
case 44:
5912
case 54:
5913
case 64:
5914
case 71:
5915
case 84:
5916
case 94:
5917
elmertype = 404;
5918
break;
5919
5920
case 45:
5921
case 46:
5922
case 56:
5923
case 66:
5924
case 76:
5925
case 96:
5926
elmertype = 408;
5927
break;
5928
5929
case 111:
5930
elmertype = 504;
5931
break;
5932
5933
case 118:
5934
elmertype = 510;
5935
break;
5936
5937
case 101:
5938
case 112:
5939
elmertype = 706;
5940
break;
5941
5942
case 102:
5943
case 113:
5944
elmertype = 715;
5945
break;
5946
5947
case 104:
5948
case 115:
5949
elmertype = 808;
5950
break;
5951
5952
case 105:
5953
case 116:
5954
elmertype = 820;
5955
break;
5956
5957
default:
5958
elmertype = 0;
5959
if(0) printf("Unknown elementtype in universal mesh format: %d\n",unvtype);
5960
}
5961
5962
return(elmertype);
5963
}
5964
5965
5966
/* The Universal format supports something as "degenerated" elements.
5967
This means that the same node is given multiple times in the element
5968
topology */
5969
static int UnvRedundantIndexes(int nonodes,int *ind)
5970
{
5971
int i,j,redundant;
5972
5973
redundant = FALSE;
5974
for(i=0;i<nonodes;i++) {
5975
if( ind[i] == 0 ) redundant = TRUE;
5976
for(j=i+1;j<nonodes;j++)
5977
if(ind[i] == ind[j]) redundant = TRUE;
5978
}
5979
if( redundant ) {
5980
printf("Redundant element %d: ",nonodes);
5981
for(i=0;i<nonodes;i++)
5982
printf(" %d ",ind[i]);
5983
printf("\n");
5984
}
5985
5986
return(redundant);
5987
}
5988
5989
5990
/* Mapping between the elemental node order of Universal file format to
5991
Elmer file format. */
5992
static void UnvToElmerIndx(int elemtype,int *topology)
5993
{
5994
int i=0,nodes=0,oldtopology[MAXNODESD2];
5995
int reorder, *porder;
5996
5997
int order203[]={1,3,2};
5998
int order306[]={1,3,5,2,4,6};
5999
int order510[]={1,3,5,10,2,4,6,7,8,9};
6000
int order408[]={1,3,5,7,2,4,6,8};
6001
int order820[]={1,3,5,7,13,15,17,19,2,4,6,8,9,10,11,12,14,16,18,20};
6002
6003
6004
reorder = FALSE;
6005
6006
switch (elemtype) {
6007
6008
case 203:
6009
reorder = TRUE;
6010
porder = &order203[0];
6011
break;
6012
6013
case 306:
6014
reorder = TRUE;
6015
porder = &order306[0];
6016
break;
6017
6018
case 510:
6019
reorder = TRUE;
6020
porder = &order510[0];
6021
break;
6022
6023
case 408:
6024
reorder = TRUE;
6025
porder = &order408[0];
6026
break;
6027
6028
case 820:
6029
reorder = TRUE;
6030
porder = &order820[0];
6031
break;
6032
6033
}
6034
6035
if( reorder ) {
6036
nodes = elemtype % 100;
6037
for(i=0;i<nodes;i++)
6038
oldtopology[i] = topology[i];
6039
for(i=0;i<nodes;i++)
6040
topology[i] = oldtopology[porder[i]-1];
6041
}
6042
}
6043
6044
6045
6046
6047
int LoadUniversalMesh(struct FemType *data,struct BoundaryType *bound,
6048
char *prefix,int info)
6049
/* Load the grid in universal file format. This format includes thousands of possible
6050
fields and hence the parser can never be exhaustive. Just the mostly common used
6051
fields in FE community are treated. */
6052
{
6053
int noknots,totknots,noelements,elemcode,maxnodes;
6054
int allocated,dim,ind,lines,groupset,goffset,poffset,noconf1,noconf2;
6055
int reordernodes,reorderelements,nogroups,maxnodeind,maxelem,elid,unvtype,elmertype;
6056
int nonodes,group,grouptype,mode,nopoints,nodeind,matind,physind,colorind;
6057
int minelemtype,maxelemtype,doscaling=FALSE;
6058
int debug,mingroup,maxgroup,minphys,maxphys,nogroup,noentities,dummy,isbeam;
6059
int *u2eind=NULL,*u2eelem=NULL;
6060
int *elementtypes,*physmap;
6061
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
6062
int i,j,k;
6063
char entityname[MAXNAMESIZE];
6064
Real scaling[4];
6065
FILE *in;
6066
6067
6068
strcpy(filename,prefix);
6069
if ((in = fopen(filename,"r")) == NULL) {
6070
AddExtension(prefix,filename,"unv");
6071
if ((in = fopen(filename,"r")) == NULL) {
6072
printf("LoadUniversalMesh: opening of the universal mesh file '%s' wasn't successful !\n",
6073
filename);
6074
return(1);
6075
}
6076
}
6077
6078
printf("Reading mesh from universal mesh file %s.\n",filename);
6079
InitializeKnots(data);
6080
6081
dim = 3;
6082
allocated = FALSE;
6083
reordernodes = FALSE;
6084
reorderelements = FALSE;
6085
6086
debug = FALSE;
6087
if( debug ){
6088
elementtypes = Ivector(0,820);
6089
for(i=0;i<=820;i++) elementtypes[i] = FALSE;
6090
}
6091
6092
maxnodeind = 0;
6093
maxnodes = 0;
6094
maxelem = 0;
6095
mingroup = INT_MAX;
6096
maxgroup = 0;
6097
minphys = INT_MAX;
6098
maxphys = 0;
6099
groupset = 0;
6100
goffset = 0;
6101
poffset = 0;
6102
noconf1 = 0;
6103
noconf2 = 0;
6104
6105
omstart:
6106
6107
/* this is a global variable in the module */
6108
linenumber = 0;
6109
6110
if(info) {
6111
if(allocated)
6112
printf("Second round for reading data\n");
6113
else
6114
printf("First round for allocating data\n");
6115
}
6116
6117
noknots = 0;
6118
noelements = 0;
6119
nogroups = 0;
6120
nopoints = 0;
6121
group = 0;
6122
mode = 0;
6123
6124
6125
for(;;) {
6126
6127
if(0) printf("line: %d %s\n",mode,line);
6128
6129
nextline:
6130
if( !strncmp(line," -1",6)) mode = 0;
6131
if( Getrow(line,in,FALSE)) {
6132
goto end;
6133
}
6134
if(line[0]=='\0') goto end;
6135
6136
if( !strncmp(line," -1",6)) mode = 0;
6137
else if( !strncmp(line," 2411",6)) mode = 2411;
6138
else if( !strncmp(line," 2412",6)) mode = 2412;
6139
else if( !strncmp(line," 2420",6)) mode = 2420;
6140
else if( !strncmp(line," 2467",6)) mode = 2467;
6141
else if( !strncmp(line," 2435",6)) mode = 2435;
6142
else if( !strncmp(line," 781",6)) mode = 781;
6143
else if( !strncmp(line," 780",6)) mode = 780;
6144
else if( !strncmp(line," 164",6)) mode = 164;
6145
else if( allocated && strncmp(line," ",6)) printf("Unknown mode line %d: %s",linenumber,line);
6146
6147
6148
if(debug && mode) printf("Current mode is %d\n",mode);
6149
6150
/* node definition */
6151
if( mode == 2411 || mode == 781 ) {
6152
if(allocated && info) printf("Reading node coordinates\n");
6153
for(;;) {
6154
GetrowDouble(line,in);
6155
if( !strncmp(line," -1",6)) {
6156
if(!allocated && info) printf("There are %d nodes in the mesh\n",noknots);
6157
goto nextline;
6158
}
6159
6160
cp = line;
6161
nodeind = next_int(&cp);
6162
/* Three other fields omitted: two coordinate systems and color */
6163
noknots += 1;
6164
GetrowDouble(line,in);
6165
6166
if(allocated) {
6167
if(reordernodes) {
6168
if(u2eind[nodeind])
6169
printf("Reordering node %d already set (%d vs. %d)\n",
6170
nodeind,u2eind[nodeind],noknots);
6171
else
6172
u2eind[nodeind] = noknots;
6173
}
6174
6175
cp = line;
6176
data->x[noknots] = next_real(&cp);
6177
data->y[noknots] = next_real(&cp);
6178
data->z[noknots] = next_real(&cp);
6179
}
6180
else {
6181
if(nodeind != noknots) reordernodes = TRUE;
6182
maxnodeind = MAX(maxnodeind,nodeind);
6183
}
6184
}
6185
}
6186
6187
if( mode == 2412 ) {
6188
minelemtype = INT_MAX;
6189
maxelemtype = 0;
6190
6191
if(allocated && info) printf("Reading element topologies\n");
6192
for(;;) {
6193
Getrow(line,in,FALSE);
6194
if( strstr(line,"-1")) {
6195
if(info && !allocated) printf("Element type range in mesh [%d,%d]\n",minelemtype,maxelemtype);
6196
goto nextline;
6197
}
6198
6199
noelements += 1;
6200
cp = line;
6201
elid = next_int(&cp);
6202
unvtype = next_int(&cp);
6203
physind = next_int(&cp);
6204
matind = next_int(&cp);
6205
colorind = next_int(&cp);
6206
nonodes = next_int(&cp);
6207
6208
if(!allocated ) {
6209
if(0) printf("elem = %d %d %d %d\n",noelements,unvtype,physind,matind);
6210
}
6211
6212
elmertype = UnvToElmerType(unvtype);
6213
if(!elmertype) {
6214
printf("Unknown elementtype %d %d %d %d %d %d %d\n",
6215
noelements,elid,unvtype,physind,matind,colorind,nonodes);
6216
printf("line %d: %s\n",linenumber,line);
6217
bigerror("done");
6218
}
6219
6220
if (!allocated) {
6221
minphys = MIN( minphys, physind );
6222
maxphys = MAX( maxphys, physind );
6223
maxnodes = MAX(maxnodes, nonodes);
6224
if(elid != noelements) reorderelements = TRUE;
6225
maxelem = MAX(maxelem, elid);
6226
}
6227
else {
6228
physind += poffset;
6229
}
6230
6231
/* For beam elements there is a stupid additional row filled with zeros? */
6232
isbeam = ( elmertype / 100 == 2);
6233
if(isbeam)Getrow(line,in,FALSE);
6234
6235
Getrow(line,in,FALSE);
6236
cp = line;
6237
6238
if(elmertype == 510 )
6239
lines = 1;
6240
else if(elmertype == 820 )
6241
lines = 2;
6242
else
6243
lines = 0;
6244
6245
if(allocated) {
6246
if(reorderelements) u2eelem[elid] = noelements;
6247
6248
if(debug && !elementtypes[elmertype]) {
6249
elementtypes[elmertype] = TRUE;
6250
printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
6251
}
6252
6253
if(elmertype % 100 != nonodes) {
6254
printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
6255
nonodes = elmertype % 100;
6256
}
6257
6258
data->elementtypes[noelements] = elmertype;
6259
for(i=0;i<nonodes;i++) {
6260
if( lines > 0 && i >= 8 ) {
6261
if( i%8 == 0 ) {
6262
Getrow(line,in,FALSE);
6263
cp = line;
6264
}
6265
}
6266
data->topology[noelements][i] = next_int(&cp);
6267
}
6268
6269
UnvRedundantIndexes(nonodes,data->topology[noelements]);
6270
6271
UnvToElmerIndx(elmertype,data->topology[noelements]);
6272
6273
/* should this be physical property or material property? */
6274
data->material[noelements] = physind;
6275
}
6276
else {
6277
minelemtype = MIN( minelemtype, elmertype );
6278
maxelemtype = MAX( maxelemtype, elmertype );
6279
for(i=1;i<=lines;i++) {
6280
Getrow(line,in,FALSE);
6281
}
6282
}
6283
}
6284
if(info) {
6285
printf("Element type range in whole mesh is [%d %d]\n",minelemtype,maxelemtype);
6286
}
6287
}
6288
6289
if( mode == 2420 ) {
6290
int partuid,coordlabel,coordtype;
6291
Real coeff;
6292
if(allocated && info) printf("Reading Coordinate system information\n");
6293
6294
Getrow(line,in,FALSE);
6295
if( !allocated ) {
6296
cp = line;
6297
partuid = next_int(&cp);
6298
printf("Part UID = %d\n",partuid);
6299
}
6300
Getrow(line,in,FALSE);
6301
if(!allocated ) {
6302
sscanf(line,"%s",entityname);
6303
printf("Part name = %s\n",entityname);
6304
}
6305
Getrow(line,in,FALSE);
6306
if( !allocated ) {
6307
cp = line;
6308
coordlabel = next_int(&cp);
6309
coordtype = next_int(&cp);
6310
if( coordtype != 0 ) {
6311
printf("Coordinate system is not cartesian: %d\n",coordtype);
6312
printf("Code some more if you want to consider this!\n");
6313
}
6314
}
6315
6316
Getrow(line,in,FALSE);
6317
if(!allocated ) {
6318
sscanf(line,"%s",entityname);
6319
printf("Coord system name = %s\n",entityname);
6320
}
6321
for(i=1;i<=4;i++) {
6322
Getrow(line,in,FALSE);
6323
if( !allocated ) {
6324
cp = line;
6325
if(!cp) printf("Problem reading line %d for coordinate system\n",i);
6326
for(j=1;j<= 3;j++) {
6327
coeff = next_real(&cp);
6328
if( i == j ) {
6329
scaling[i] = coeff;
6330
if( fabs(coeff) < 1.0e-20) {
6331
printf("Scaling for component %d too small %le\n",i,coeff);
6332
}
6333
else if( fabs(coeff-1.0) ) {
6334
doscaling = TRUE;
6335
printf("Scaling component %d by %le\n",i,coeff);
6336
}
6337
}
6338
else {
6339
if(fabs(coeff) > 1.0e-20 ) {
6340
printf("Transformation matrix is not diagonal %d%d: %e\n",i,j,coeff);
6341
smallerror("Code some more...");
6342
}
6343
}
6344
}
6345
}
6346
}
6347
Getrow(line,in,FALSE);
6348
if( strncmp(line," -1",6))
6349
printf("Field 2420 should already be ending: %s\n",line);
6350
goto nextline;
6351
}
6352
6353
if( mode == 780 ) {
6354
int physind2,matind2;
6355
maxelemtype = 0;
6356
minelemtype = 1000;
6357
6358
if(allocated && info) printf("Reading element groups in mode %d\n",mode);
6359
for(;;) {
6360
Getrow(line,in,FALSE);
6361
if( !strncmp(line," -1",6)) goto nextline;
6362
6363
noelements += 1;
6364
cp = line;
6365
elid = next_int(&cp);
6366
unvtype = next_int(&cp);
6367
6368
physind = next_int(&cp);
6369
physind2 = next_int(&cp);
6370
matind = next_int(&cp);
6371
matind2 = next_int(&cp);
6372
colorind = next_int(&cp);
6373
nonodes = next_int(&cp);
6374
6375
if (!allocated) {
6376
maxnodes = MAX(maxnodes, nonodes);
6377
if(elid != noelements) reorderelements = TRUE;
6378
maxelem = MAX(maxelem, elid);
6379
minphys = MIN( minphys, physind );
6380
maxphys = MAX( maxphys, physind );
6381
}
6382
else {
6383
physind += poffset;
6384
}
6385
6386
6387
if(unvtype == 11 || unvtype == 21) Getrow(line,in,FALSE);
6388
Getrow(line,in,FALSE);
6389
cp = line;
6390
if(allocated) {
6391
if(reorderelements) u2eelem[elid] = noelements;
6392
6393
elmertype = UnvToElmerType(unvtype);
6394
maxelemtype = MAX( maxelemtype, elmertype );
6395
minelemtype = MIN( minelemtype, elmertype );
6396
6397
if(debug && !elementtypes[elmertype]) {
6398
elementtypes[elmertype] = TRUE;
6399
printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
6400
}
6401
6402
if(elmertype % 100 != nonodes) {
6403
printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
6404
nonodes = elmertype % 100;
6405
}
6406
6407
data->elementtypes[noelements] = elmertype;
6408
for(i=0;i<nonodes;i++)
6409
data->topology[noelements][i] = next_int(&cp);
6410
6411
UnvRedundantIndexes(nonodes,data->topology[noelements]);
6412
6413
UnvToElmerIndx(elmertype,data->topology[noelements]);
6414
6415
/* should this be physical property or material property? */
6416
data->material[noelements] = physind;
6417
}
6418
}
6419
}
6420
6421
if( mode == 2467 || mode == 2435) {
6422
if(allocated && info) printf("Reading element groups in mode %d\n",mode);
6423
6424
for(;;) {
6425
Getrow(line,in,FALSE);
6426
if( !strncmp(line," -1",6)) goto nextline;
6427
6428
cp = line;
6429
nogroup = next_int(&cp);
6430
maxelemtype = 0;
6431
minelemtype = 1000;
6432
for(i=1;i<=6;i++)
6433
dummy = next_int(&cp);
6434
noentities = next_int(&cp);
6435
6436
if(!allocated) {
6437
mingroup = MIN( mingroup, nogroup );
6438
maxgroup = MAX( maxgroup, nogroup );
6439
}
6440
else {
6441
nogroup += goffset;
6442
}
6443
6444
Getrow(line,in,FALSE);
6445
if( !strncmp(line," -1",6)) goto nextline;
6446
6447
/* Used for the empty group created by salome */
6448
/* if( mode == 2467 && !strncmp(line," ",12)) continue; */
6449
6450
group++;
6451
k = 0;
6452
if(allocated) {
6453
sscanf(line,"%s",entityname);
6454
if(!data->bodyname[nogroup]) data->bodyname[nogroup] = Cvector(0,MAXNAMESIZE);
6455
strcpy(data->bodyname[nogroup],entityname);
6456
data->bodynamesexist = TRUE;
6457
if(0) data->boundarynamesexist = TRUE;
6458
6459
if(info) printf("Reading %d:th group with index %d with %d entities: %s\n",
6460
group,nogroup,noentities,entityname);
6461
}
6462
if(noentities == 0) Getrow(line,in,FALSE);
6463
6464
for(i=0;i<noentities;i++) {
6465
if(i%2 == 0) {
6466
Getrow(line,in,FALSE);
6467
if( !strncmp(line," -1",6)) goto nextline;
6468
cp = line;
6469
}
6470
6471
grouptype = next_int(&cp);
6472
ind = next_int(&cp);
6473
dummy = next_int(&cp);
6474
dummy = next_int(&cp);
6475
6476
if(ind == 0) continue;
6477
6478
if( grouptype == 8 ) {
6479
if(allocated) {
6480
if(reorderelements) ind = u2eelem[ind];
6481
elemcode = data->elementtypes[ind];
6482
maxelemtype = MAX( maxelemtype, elemcode );
6483
minelemtype = MIN( minelemtype, elemcode );
6484
6485
if(data->material[ind] < 0 ) {
6486
if(data->material[ind] == -nogroup)
6487
noconf1++;
6488
else
6489
noconf2++;
6490
}
6491
6492
data->material[ind] = -nogroup;
6493
groupset++;
6494
}
6495
}
6496
else if(grouptype == 7) {
6497
nopoints += 1;
6498
6499
if(allocated) {
6500
elemcode = 101;
6501
if(data->material[noelements+nopoints] < 0 ) {
6502
if(data->material[noelements+nopoints] == -nogroup)
6503
noconf1++;
6504
else
6505
noconf2++;
6506
}
6507
6508
data->material[noelements+nopoints] = -nogroup;
6509
maxelemtype = MAX( maxelemtype, elemcode );
6510
minelemtype = MIN( minelemtype, elemcode );
6511
data->elementtypes[noelements+nopoints] = elemcode;
6512
data->topology[noelements+nopoints][0] = ind;
6513
groupset++;
6514
}
6515
}
6516
else {
6517
printf("unknown group type %d\n",grouptype);
6518
}
6519
}
6520
if(allocated && info) {
6521
printf("Element type range in group is [%d %d]\n",minelemtype,maxelemtype);
6522
}
6523
6524
}
6525
}
6526
6527
if( mode == 164 ) {
6528
if(!allocated) printf("Units dataset content is currently omitted!\n");
6529
for(;;) {
6530
Getrow(line,in,FALSE);
6531
if( !strncmp(line," -1",6))
6532
goto nextline;
6533
}
6534
}
6535
6536
}
6537
6538
end:
6539
6540
exit;
6541
if(0) printf("Done reading mesh\n");
6542
6543
6544
if(!allocated) {
6545
6546
if(reordernodes) {
6547
if(info) printf("Reordering %d nodes with indexes up to %d\n",noknots,maxnodeind);
6548
u2eind = Ivector(1,maxnodeind);
6549
for(i=1;i<=maxnodeind;i++) u2eind[i] = 0;
6550
}
6551
if(reorderelements) {
6552
if(info) printf("Reordering %d elements with indexes up to %d\n",noelements,maxelem);
6553
u2eelem = Ivector(1,maxelem);
6554
for(i=1;i<=maxelem;i++) u2eelem[i] = 0;
6555
}
6556
6557
if(noknots == 0 || noelements == 0 || maxnodes == 0) {
6558
printf("Invalid mesh consists of %d nodes and %d %d-node elements.\n",
6559
noknots,noelements,maxnodes);
6560
fclose(in);
6561
return(2);
6562
}
6563
6564
rewind(in);
6565
totknots = noknots;
6566
data->noknots = noknots;
6567
data->noelements = noelements + nopoints;
6568
data->maxnodes = maxnodes;
6569
data->dim = dim;
6570
6571
if(info) {
6572
printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
6573
noknots,noelements,maxnodes,dim);
6574
}
6575
AllocateKnots(data);
6576
allocated = TRUE;
6577
6578
/* Set an offset for physical indexes so that the defined groups and
6579
existing physical indexes won't mix confusingly */
6580
if(info) {
6581
printf("Physical index interval is [%d,%d]\n",minphys,maxphys);
6582
if( maxgroup ) printf("Group index interval is [%d,%d]\n",mingroup,maxgroup);
6583
}
6584
if(!mingroup) {
6585
printf("Applying group offset to 1!\n");
6586
goffset = 1;
6587
mingroup += 1;
6588
maxgroup += 1;
6589
}
6590
if(!minphys) {
6591
printf("Applying physical entity offset to 1!\n");
6592
poffset = 1;
6593
minphys += 1;
6594
maxphys += 1;
6595
}
6596
6597
goto omstart;
6598
}
6599
fclose(in);
6600
6601
if(noconf1) printf("Group given multiple times with same group: %d\n",noconf1);
6602
if(noconf2) printf("Group given multiple times but with different group index: %d\n",noconf2);
6603
6604
/* Rorder materials if there is an overlap between groups and physical entities, or
6605
if numbering uses also zero. */
6606
if( groupset) {
6607
int i1,i2,k2,ioffset;
6608
6609
if(info) printf("Group given for %d elements out of %d\n",groupset,noelements);
6610
i1=MIN(minphys,mingroup);
6611
i2=MAX(maxphys,maxgroup);
6612
6613
/* Give plenty of room for new indexes */
6614
i2=2*i2;
6615
6616
physmap = Ivector(i1,i2);
6617
for(i=i1;i<=i2;i++) physmap[i] = 0;
6618
6619
/* Give priority to group (negative index) */
6620
for(i=1;i<=data->noelements;i++) {
6621
j = data->material[i];
6622
if(j<0) physmap[-j] = -1;
6623
}
6624
/* Now check the physical index */
6625
for(i=1;i<=data->noelements;i++) {
6626
j = data->material[i];
6627
if(j>0) {
6628
if(physmap[j]==0) physmap[j] = -2;
6629
if(physmap[j]==-1) {
6630
if(info) printf("Physical index and group index collide: %d\n",j);
6631
physmap[j] = -3;
6632
}
6633
}
6634
}
6635
6636
for(i=i1;i<=i2;i++) {
6637
/* For tag -3 we need to find new index */
6638
if(physmap[i]==-3) {
6639
/* Find a free index and tag it with -4 when it has been used */
6640
for(j=i1;j<=i2;j++)
6641
if(!physmap[j]) break;
6642
physmap[i] = j;
6643
physmap[j] = -4;
6644
if(info) printf("Replacing physical index %d with free index %d\n",i,j);
6645
/* We may have some remnants that we remove since physical entity is not named */
6646
if(data->bodyname[j]) {
6647
printf("Removing name of an empty group: %s\n",data->bodyname[j]);
6648
free_Cvector(data->bodyname[j],0,MAXNAMESIZE);
6649
data->bodyname[j] = NULL;
6650
}
6651
}
6652
}
6653
/* Finally do the renumbering */
6654
k = 0;
6655
k2 = 0;
6656
for(i=1;i<=data->noelements;i++) {
6657
j = data->material[i];
6658
if(j<0)
6659
data->material[i] = -j;
6660
else {
6661
if(physmap[j] > 0) {
6662
data->material[i] = physmap[j];
6663
k2++;
6664
}
6665
else k++;
6666
}
6667
}
6668
if(k) printf("Using original physical entity index for %d elements\n",k);
6669
if(k2) printf("Using mapped physical entity index for %d elements\n",k2);
6670
6671
for(i=i1;i<=i2;i++) physmap[i] = 0;
6672
for(i=1;i<=data->noelements;i++)
6673
physmap[data->material[i]] += 1;
6674
for(i=i1;i<=i2;i++) {
6675
j = physmap[i];
6676
if(j) {
6677
if(data->bodyname[i])
6678
printf("Entity %d (%s) count is %d\n",i,data->bodyname[i],j);
6679
else
6680
printf("Entity %d count is %d\n",i,j);
6681
}
6682
}
6683
free_Ivector(physmap,i1,i2);
6684
}
6685
6686
/* Elmer likes that node indexes are given so that no integers are missed.
6687
If this is not the case we need to do renumbering of nodes. */
6688
if(reordernodes) {
6689
printf("Reordering nodes continuously\n");
6690
for(j=1;j<=noelements;j++)
6691
for(i=0;i<data->elementtypes[j]%100;i++)
6692
data->topology[j][i] = u2eind[data->topology[j][i]];
6693
free_Ivector(u2eind,1,maxnodeind);
6694
}
6695
if(reorderelements) {
6696
free_Ivector(u2eelem,1,maxelem);
6697
}
6698
6699
/* Do scaling if requested */
6700
if( doscaling ) {
6701
Real *coord;
6702
for(j=1;j<=3;j++) {
6703
if( j == 1 )
6704
coord = data->x;
6705
else if( j == 2 )
6706
coord = data->y;
6707
else
6708
coord = data->z;
6709
6710
if( fabs(scaling[j]-1.0) >= 1.0e-20 ) {
6711
for(i=1;i<=noknots;i++)
6712
coord[i] *= scaling[j];
6713
}
6714
}
6715
}
6716
6717
/* This is here for debugging of the nodal order */
6718
if(FALSE) for(j=1;j<=noelements;j++) {
6719
int elemtype = data->elementtypes[j];
6720
printf("element = %d\n",j);
6721
for(i=0;elemtype%100;i++) {
6722
k = data->topology[j][i];
6723
printf("node i=%d %.3le %.3le %.3le\n",i,data->x[k],data->z[k],data->y[k]);
6724
}
6725
}
6726
6727
6728
/* Until this far all elements have been listed as bulk elements.
6729
Now separate the lower dimensional elements to be boundary elements. */
6730
ElementsToBoundaryConditions(data,bound,TRUE,info);
6731
6732
if(info) printf("The Universal mesh was loaded from file %s.\n",filename);
6733
6734
return(0);
6735
}
6736
6737
6738
6739
6740
6741
int LoadCGsimMesh(struct FemType *data,char *prefix,int info)
6742
/* Load the mesh from postprocessing format of CGsim */
6743
{
6744
int noknots,noelements,maxnodes,material,allocated,dim,debug,thismat,thisknots,thiselems;
6745
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
6746
int i,j,inds[MAXNODESD2],savedofs;
6747
Real dummyreal;
6748
FILE *in;
6749
6750
6751
strcpy(filename,prefix);
6752
if ((in = fopen(filename,"r")) == NULL) {
6753
AddExtension(prefix,filename,"plt");
6754
if ((in = fopen(filename,"r")) == NULL) {
6755
printf("LoadCGsimMesh: opening of the CGsim mesh file '%s' wasn't successful !\n",
6756
filename);
6757
return(1);
6758
}
6759
}
6760
6761
printf("Reading mesh from CGsim mesh file %s.\n",filename);
6762
InitializeKnots(data);
6763
6764
debug = FALSE;
6765
allocated = FALSE;
6766
savedofs = FALSE;
6767
6768
omstart:
6769
6770
maxnodes = 4;
6771
noknots = 0;
6772
noelements = 0;
6773
material = 0;
6774
dim = 2;
6775
thismat = 0;
6776
6777
6778
for(;;) {
6779
6780
if(Getrow(line,in,FALSE)) goto end;
6781
if(line[0]=='\0') goto end;
6782
6783
cp = strstr(line,"ZONE");
6784
if(!cp) continue;
6785
6786
thismat += 1;
6787
cp = strstr(line," N=");
6788
cp += 3;
6789
thisknots = next_int(&cp);
6790
6791
cp = strstr(line,",E=");
6792
cp += 3;
6793
thiselems = next_int(&cp);
6794
6795
if(debug) {
6796
printf("%s",line);
6797
printf("thismat = %d knots = %d elems = %d\n",thismat,thisknots,thiselems);
6798
}
6799
6800
for(i=1;i<=thisknots;i++) {
6801
GETLINE;
6802
6803
if(allocated) {
6804
cp = line;
6805
data->x[noknots+i] = next_real(&cp);
6806
data->y[noknots+i] = next_real(&cp);
6807
data->z[noknots+i] = 0.0;
6808
6809
if(savedofs == 1) {
6810
for(j=1;j<=4;j++)
6811
dummyreal = next_real(&cp);
6812
data->dofs[1][noknots+i] = next_real(&cp);
6813
}
6814
else if(savedofs == 5) {
6815
for(j=1;j<=5;j++)
6816
data->dofs[j][noknots+i] = next_real(&cp);
6817
}
6818
6819
}
6820
}
6821
6822
for(i=1;i<=thiselems;i++) {
6823
GETLINE;
6824
6825
if(allocated) {
6826
cp = line;
6827
for(j=0;j<4;j++)
6828
inds[j] = next_int(&cp);
6829
for(j=0;j<4;j++)
6830
data->topology[noelements+i][j] = inds[j]+noknots;
6831
if(inds[2] == inds[3])
6832
data->elementtypes[noelements+i] = 303;
6833
else
6834
data->elementtypes[noelements+i] = 404;
6835
data->material[noelements+i] = thismat;
6836
}
6837
}
6838
6839
noknots += thisknots;
6840
noelements += thiselems;
6841
}
6842
6843
end:
6844
6845
if(!allocated) {
6846
if(noknots == 0 || noelements == 0 || maxnodes == 0) {
6847
printf("Invalid mesh consists of %d knots and %d %d-node elements.\n",
6848
noknots,noelements,maxnodes);
6849
fclose(in);
6850
return(2);
6851
}
6852
6853
rewind(in);
6854
data->noknots = noknots;
6855
data->noelements = noelements;
6856
data->maxnodes = maxnodes;
6857
data->dim = dim;
6858
6859
6860
if(info) {
6861
printf("Allocating for %d knots and %d %d-node elements.\n",
6862
noknots,noelements,maxnodes);
6863
}
6864
AllocateKnots(data);
6865
6866
if(savedofs == 1) {
6867
CreateVariable(data,1,1,0.0,"Temperature",FALSE);
6868
}
6869
else if(savedofs == 5) {
6870
CreateVariable(data,1,1,0.0,"dTdX",FALSE);
6871
CreateVariable(data,2,1,0.0,"dTdY",FALSE);
6872
CreateVariable(data,3,1,0.0,"Qx",FALSE);
6873
CreateVariable(data,4,1,0.0,"Qy",FALSE);
6874
CreateVariable(data,5,1,0.0,"Temperature",FALSE);
6875
}
6876
6877
allocated = TRUE;
6878
goto omstart;
6879
}
6880
fclose(in);
6881
6882
if(info) printf("The CGsim mesh was loaded from file %s.\n\n",filename);
6883
return(0);
6884
}
6885
6886
6887
int FluxToElmerType(int nonodes, int dim) {
6888
int elmertype;
6889
6890
elmertype = 0;
6891
6892
if( dim == 2 ) {
6893
switch( nonodes ) {
6894
case 3:
6895
elmertype = 203;
6896
break;
6897
case 6:
6898
elmertype = 306;
6899
break;
6900
case 8:
6901
elmertype = 408;
6902
break;
6903
}
6904
}
6905
6906
if( !elmertype ) printf("FluxToElmerType could not deduce element type! (%d %d)\n",nonodes,dim);
6907
6908
return(elmertype);
6909
}
6910
6911
6912
6913
6914
6915
int LoadFluxMesh(struct FemType *data,struct BoundaryType *bound,
6916
char *prefix,int info)
6917
/* Load the mesh from format of Flux Cedrat in TRA format. */
6918
{
6919
int noknots,noelements,maxnodes,dim,elmertype;
6920
int nonodes,matind,noregions,mode;
6921
int debug;
6922
int *elementtypes;
6923
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
6924
int i,j,k;
6925
char entityname[MAXNAMESIZE];
6926
FILE *in;
6927
6928
6929
strcpy(filename,prefix);
6930
if ((in = fopen(filename,"r")) == NULL) {
6931
AddExtension(prefix,filename,"TRA");
6932
if ((in = fopen(filename,"r")) == NULL) {
6933
printf("LoadFluxMesh: opening of the Flux mesh file '%s' wasn't successful !\n",
6934
filename);
6935
return(1);
6936
}
6937
}
6938
6939
printf("Reading 2D mesh from Flux mesh file %s.\n",filename);
6940
InitializeKnots(data);
6941
6942
debug = FALSE;
6943
linenumber = 0;
6944
dim = 2;
6945
noknots = 0;
6946
noelements = 0;
6947
mode = 0;
6948
maxnodes = 8;
6949
6950
6951
6952
for(;;) {
6953
6954
if(0) printf("line: %d %s\n",mode,line);
6955
6956
if( Getrow(line,in,FALSE)) goto end;
6957
if(line[0]=='\0') goto end;
6958
6959
if( strstr(line,"Number of nodes")) mode = 1;
6960
else if( strstr(line,"Total number of elements")) mode = 2;
6961
else if( strstr(line,"Total number of regions")) mode = 3;
6962
6963
else if( strstr(line,"Description of elements")) mode = 10;
6964
else if( strstr(line,"Coordinates of the nodes")) mode = 11;
6965
else if( strstr(line,"Names of the regions")) mode = 12;
6966
6967
else if( strstr(line,"Neighbouring element table")) mode = 13;
6968
else if( strstr(line,"List of boundary nodes")) mode = 14;
6969
else if( strstr(line,"Physical properties")) mode = 15;
6970
else if( strstr(line,"Boundary conditions")) mode = 16;
6971
else {
6972
if(debug) printf("Unknown mode line %d: %s",linenumber,line);
6973
mode = 0;
6974
}
6975
6976
if(debug && mode) printf("Current mode is %d\n",mode);
6977
6978
switch( mode ) {
6979
case 1:
6980
noknots = atoi(line);
6981
break;
6982
6983
case 2:
6984
noelements = atoi(line);
6985
break;
6986
6987
case 3:
6988
noregions = atoi(line);
6989
break;
6990
6991
6992
case 10:
6993
if(info) {
6994
printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
6995
noknots,noelements,maxnodes,dim);
6996
}
6997
6998
data->noknots = noknots;
6999
data->noelements = noelements;
7000
data->maxnodes = maxnodes;
7001
data->dim = dim;
7002
AllocateKnots(data);
7003
7004
if(info) printf("Reading %d element topologies\n",noelements);
7005
for(i=1;i<=noelements;i++) {
7006
Getrow(line,in,FALSE);
7007
cp = line;
7008
j = next_int(&cp);
7009
if( i != j ) {
7010
printf("It seems that reordering of elements should be performed! (%d %d)\n",i,j);
7011
}
7012
nonodes = next_int(&cp);
7013
matind = abs( next_int(&cp) );
7014
7015
elmertype = FluxToElmerType( nonodes, dim );
7016
data->elementtypes[i] = elmertype;
7017
data->material[i] = matind;
7018
7019
Getrow(line,in,FALSE);
7020
cp = line;
7021
for(k=0;k<nonodes;k++) {
7022
data->topology[i][k] = next_int(&cp);
7023
}
7024
}
7025
break;
7026
7027
case 11:
7028
if(info) printf("Reading %d element nodes\n",noknots);
7029
for(i=1;i<=noknots;i++) {
7030
Getrow(line,in,FALSE);
7031
cp = line;
7032
j = next_int(&cp);
7033
if( i != j ) {
7034
printf("It seems that reordering of nodes should be performed! (%d %d)\n",i,j);
7035
}
7036
data->x[i] = next_real(&cp);
7037
data->y[i] = next_real(&cp);
7038
if(dim == 3) data->z[i] = next_real(&cp);
7039
}
7040
break;
7041
7042
7043
case 12:
7044
if(info) printf("Reading %d names of regions\n",noregions);
7045
for(i=1;i<=noregions;i++) {
7046
Getrow(line,in,FALSE);
7047
cp = line;
7048
j = next_int(&cp);
7049
if( i != j ) {
7050
printf("It seems that reordering of regions should be performed! (%d %d)\n",i,j);
7051
}
7052
sscanf(cp,"%s",entityname);
7053
if(!data->bodyname[i]) data->bodyname[i] = Cvector(0,MAXNAMESIZE);
7054
strcpy(data->bodyname[i],entityname);
7055
}
7056
data->bodynamesexist = TRUE;
7057
data->boundarynamesexist = TRUE;
7058
break;
7059
7060
7061
default:
7062
if(debug) printf("unimplemented mode: %d\n",mode );
7063
mode = 0;
7064
break;
7065
}
7066
}
7067
7068
end:
7069
fclose(in);
7070
7071
/* Until this far all elements have been listed as bulk elements.
7072
Now separate the lower dimensional elements to be boundary elements. */
7073
ElementsToBoundaryConditions(data,bound,TRUE,info);
7074
7075
if(info) printf("The Flux mesh was loaded from file %s.\n\n",filename);
7076
7077
return(0);
7078
}
7079
7080
7081
7082
/* Mapping between the elemental node order of PF3 file format to
7083
Elmer file format. */
7084
static void PF3ToElmerPermuteNodes(int elemtype,int *topology)
7085
{
7086
int i=0, nodes=0, oldtopology[MAXNODESD2];
7087
int reorder, *porder;
7088
int debug;
7089
7090
int order303[] = {3,1,2}; //tri
7091
int order306[] = {3,1,2,6,4,5}; //tri^2
7092
int order404[] = {3,4,1,2}; //quad
7093
int order408[] = {3,4,1,2,7,8,5,6}; //quad^2
7094
int order504[] = {1,2,3,4}; //tetra
7095
int order510[] = {1,2,3,4,5,8,6,7,10,9};//tetra^2
7096
int order605[] = {3,2,1,4,5}; //pyramid
7097
int order613[] = {3,2,1,4,5,7,6,9,8,12,11,10,13}; //pyramid^2
7098
int order706[] = {6,4,5,3,1,2}; //wedge (prism)
7099
int order715[] = {6,4,5,3,1,2,12,10,11,9,7,8,15,13,14}; //wedge^2 (prism^2)
7100
int order808[] = {7,8,5,6,3,4,1,2}; //hexa
7101
int order820[] = {7,8,5,6,3,4,1,2,15,16,13,14,19,20,17,18,11,12,9,10}; //hexa^2
7102
7103
debug = TRUE;
7104
7105
reorder = FALSE;
7106
7107
switch (elemtype) {
7108
7109
case 101:
7110
//nothing to change here
7111
break;
7112
7113
case 202:
7114
//nothing to change here
7115
break;
7116
7117
case 203:
7118
//nothing to change here
7119
break;
7120
7121
case 303:
7122
reorder = TRUE;
7123
porder = &order303[0];
7124
break;
7125
7126
case 306:
7127
reorder = TRUE;
7128
porder = &order306[0];
7129
break;
7130
7131
case 404:
7132
reorder = TRUE;
7133
porder = &order404[0];
7134
break;
7135
7136
case 408:
7137
reorder = TRUE;
7138
porder = &order408[0];
7139
break;
7140
7141
case 504:
7142
reorder = TRUE;
7143
porder = &order504[0];
7144
break;
7145
7146
case 510:
7147
reorder = TRUE;
7148
porder = &order510[0];
7149
break;
7150
7151
case 605:
7152
reorder = TRUE;
7153
porder = &order605[0];
7154
break;
7155
7156
case 613:
7157
reorder = TRUE;
7158
porder = &order613[0];
7159
break;
7160
7161
case 706:
7162
reorder = TRUE;
7163
porder = &order706[0];
7164
break;
7165
7166
case 715:
7167
reorder = TRUE;
7168
porder = &order715[0];
7169
break;
7170
7171
case 808:
7172
reorder = TRUE;
7173
porder = &order808[0];
7174
break;
7175
7176
case 820:
7177
reorder = TRUE;
7178
porder = &order820[0];
7179
break;
7180
7181
default:
7182
if(debug) printf("Warning : Unknown element type: %d\n",elemtype );
7183
break;
7184
}
7185
7186
if( reorder ) {
7187
nodes = elemtype % 100;
7188
for(i=0;i<nodes;i++)
7189
oldtopology[i] = topology[i];
7190
for(i=0;i<nodes;i++)
7191
topology[i] = oldtopology[porder[i]-1];
7192
}
7193
}
7194
7195
7196
int FluxToElmerType3D(int nonodes, int dim) {
7197
int elmertype;
7198
7199
elmertype = 0;
7200
7201
if( dim == 2 ) {
7202
switch( nonodes ) {
7203
case 3:
7204
elmertype = 303;
7205
break;
7206
case 4:
7207
elmertype = 404;
7208
break;
7209
case 6:
7210
elmertype = 306;
7211
break;
7212
case 8:
7213
elmertype = 408;
7214
break;
7215
}
7216
}
7217
7218
if( dim == 3 ) {
7219
switch( nonodes ) {
7220
case 4:
7221
elmertype = 504;
7222
break;
7223
case 5:
7224
elmertype = 605;
7225
break;
7226
case 6:
7227
elmertype = 706;
7228
break;
7229
case 8:
7230
elmertype = 808;
7231
break;
7232
case 10:
7233
elmertype = 510;
7234
break;
7235
case 13:
7236
elmertype = 613;
7237
break;
7238
case 15:
7239
elmertype = 715;
7240
break;
7241
case 20:
7242
elmertype = 820;
7243
break;
7244
}
7245
}
7246
7247
if( !elmertype ) printf("FluxToElmerType3D could not deduce element type! (%d %d)\n",nonodes,dim);
7248
7249
return(elmertype);
7250
}
7251
7252
7253
int LoadFluxMesh3D(struct FemType *data,struct BoundaryType *bound,
7254
char *prefix,int info)
7255
/* Load the mesh from format of Flux Cedrat in PF3 format. */
7256
{
7257
int noknots,noelements,maxnodes,dim,elmertype;
7258
int nonodes,matind,noregions,mode;
7259
int dimplusone, maxlinenodes, nodecnt;
7260
int debug;
7261
int *elementtypes;
7262
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
7263
int i,j,k;
7264
char entityname[MAXNAMESIZE];
7265
FILE *in;
7266
7267
strcpy(filename,prefix);
7268
if ((in = fopen(filename,"r")) == NULL) {
7269
AddExtension(prefix,filename,"PF3");
7270
if ((in = fopen(filename,"r")) == NULL) {
7271
printf("LoadFluxMesh3D: opening of the Flux mesh file '%s' wasn't successful !\n",
7272
filename);
7273
return(1);
7274
}
7275
}
7276
7277
printf("Reading 3D mesh from Flux mesh file %s.\n",filename);
7278
InitializeKnots(data);
7279
7280
debug = FALSE;
7281
linenumber = 0;
7282
dim = 3;
7283
noknots = 0;
7284
noelements = 0;
7285
mode = 0;
7286
maxnodes = 20; // 15?
7287
maxlinenodes = 12; //nodes can be located at several lines
7288
7289
for(;;) {
7290
7291
if(0) printf("line: %d %s\n",mode,line);
7292
7293
if( Getrow(line,in,FALSE)) goto end;
7294
if(line[0]=='\0') goto end;
7295
if( strstr(line,"==== DECOUPAGE TERMINE")) goto end;
7296
7297
if( strstr(line,"NOMBRE DE DIMENSIONS DU DECOUPAGE")) mode = 1;
7298
else if( strstr(line,"NOMBRE D'ELEMENTS")) mode = 3;
7299
else if( strstr(line,"NOMBRE DE POINTS")) mode = 2;
7300
else if( strstr(line,"NOMBRE DE REGIONS")) mode = 4;
7301
7302
else if( strstr(line,"DESCRIPTEUR DE TOPOLOGIE DES ELEMENTS")) mode = 10;
7303
else if( strstr(line,"COORDONNEES DES NOEUDS")) mode = 11;
7304
else if( strstr(line,"NOMS DES REGIONS")) mode = 12;
7305
else {
7306
if(debug) printf("Unknown mode line %d: %s",linenumber,line);
7307
mode = 0;
7308
}
7309
7310
if(debug && mode) printf("Current mode is %d\n",mode);
7311
7312
switch( mode ) {
7313
case 1:
7314
dim = atoi(line);
7315
break;
7316
7317
case 2:
7318
if( strstr(line,"NOMBRE DE POINTS D'INTEGRATION")) break;/* We are looking for the total number of nodes */
7319
noknots = atoi(line);
7320
break;
7321
7322
case 3:
7323
i = atoi(line);
7324
noelements = MAX(i,noelements); /* We are looking for the total number of elements */
7325
break;
7326
7327
case 4:
7328
i = atoi(line);
7329
noregions = MAX(i,noregions); /* We are looking for the total number of regions */
7330
break;
7331
7332
7333
case 10:
7334
if(info) {
7335
printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
7336
noknots,noelements,maxnodes,dim);
7337
}
7338
7339
data->noknots = noknots;
7340
data->noelements = noelements;
7341
data->maxnodes = maxnodes;
7342
data->dim = dim;
7343
AllocateKnots(data);
7344
7345
if(info) printf("Reading %d element topologies\n",noelements);
7346
for(i=1;i<=noelements;i++)
7347
{
7348
Getrow(line,in,FALSE);
7349
cp = line;
7350
j = next_int(&cp);
7351
if( i != j ) {
7352
printf("It seems that reordering of elements should be performed! (%d %d)\n",i,j);
7353
}
7354
next_int(&cp); //2 internal element type description
7355
next_int(&cp); //3 internal element type description
7356
matind = next_int(&cp); //4 number of the belonging region
7357
dimplusone = next_int(&cp); //5 dimensionality 4-3D 3-2D
7358
next_int(&cp); //6 zero here always
7359
next_int(&cp); //7 internal element type description
7360
nonodes = next_int(&cp); //8 number of nodes
7361
7362
elmertype = FluxToElmerType3D( nonodes, dimplusone-1 );
7363
data->elementtypes[i] = elmertype;
7364
data->material[i] = matind;
7365
7366
Getrow(line,in,FALSE);
7367
cp = line;
7368
nodecnt = 0;
7369
for(k=0;k<nonodes;k++) {
7370
7371
if(nodecnt >= maxlinenodes) {
7372
nodecnt = 0;
7373
Getrow(line,in,FALSE);
7374
cp = line;
7375
}
7376
data->topology[i][k] = next_int(&cp);
7377
nodecnt+=1;
7378
}
7379
7380
PF3ToElmerPermuteNodes(elmertype,data->topology[noelements]);
7381
7382
}
7383
break;
7384
7385
case 11:
7386
if(info) printf("Reading %d element nodes\n",noknots);
7387
for(i=1;i<=noknots;i++) {
7388
Getrow(line,in,FALSE);
7389
cp = line;
7390
j = next_int(&cp);
7391
if( i != j ) {
7392
printf("It seems that reordering of nodes should be performed! (%d %d)\n",i,j);
7393
}
7394
data->x[i] = next_real(&cp);
7395
data->y[i] = next_real(&cp);
7396
data->z[i] = next_real(&cp);
7397
}
7398
break;
7399
7400
7401
case 12:
7402
if(info) printf("Reading %d names of regions\n",noregions);
7403
for(i=1;i<=noregions;i++) {
7404
Getrow(line,in,FALSE);
7405
7406
/* currently we just cycle through this and get a new row */
7407
if( strstr(line,"REGIONS SURFACIQUES")) Getrow(line,in,FALSE);
7408
if( strstr(line,"REGIONS VOLUMIQUES")) Getrow(line,in,FALSE);
7409
7410
sscanf(line,"%s",entityname);
7411
if(!data->bodyname[i]) data->bodyname[i] = Cvector(0,MAXNAMESIZE);
7412
strcpy(data->bodyname[i],entityname);
7413
}
7414
data->bodynamesexist = TRUE;
7415
data->boundarynamesexist = TRUE;
7416
break;
7417
7418
7419
default:
7420
if(debug) printf("unimplemented mode: %d\n",mode );
7421
mode = 0;
7422
break;
7423
}
7424
}
7425
7426
end:
7427
fclose(in);
7428
7429
/* Until this far all elements have been listed as bulk elements.
7430
Now separate the lower dimensional elements to be boundary elements. */
7431
ElementsToBoundaryConditions(data,bound,TRUE,info);
7432
7433
if(info) printf("The Flux 3D mesh was loaded from file %s.\n\n",filename);
7434
7435
return(0);
7436
}
7437
7438