Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmergrid/src/egconvert.c
3204 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
ElementsToBoundaryConditions(data,bound,FALSE,info);
4028
4029
printf("Successfully read the mesh from the Gmsh input file.\n");
4030
4031
return(0);
4032
}
4033
4034
4035
static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
4036
char *filename,int usetaggeom, int keeporphans, int info)
4037
{
4038
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
4039
int elemind[MAXNODESD2],elementtype;
4040
int i,j,k,allocated,*revindx=NULL,maxindx;
4041
int elemno, gmshtype, tagphys=0, taggeom=0, tagpart, elemnodes,maxelemtype;
4042
int tagmat,verno;
4043
int physvolexist, physsurfexist;
4044
FILE *in;
4045
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
4046
char *cp,line[MAXLINESIZE];
4047
4048
if ((in = fopen(filename,"r")) == NULL) {
4049
printf("LoadGmshInput2: The opening of the mesh file %s failed!\n",filename);
4050
return(1);
4051
}
4052
if(info) printf("Loading mesh in Gmsh format 2.0 from file %s\n",filename);
4053
4054
allocated = FALSE;
4055
dim = data->dim;
4056
maxnodes = 0;
4057
maxindx = 0;
4058
maxelemtype = 0;
4059
physvolexist = FALSE;
4060
physsurfexist = FALSE;
4061
usetaggeom = FALSE;
4062
4063
omstart:
4064
4065
for(;;) {
4066
if(Getrow(line,in,FALSE)) goto end;
4067
if(strstr(line,"$End")) continue;
4068
4069
if(strstr(line,"$MeshFormat")) {
4070
GETLINE;
4071
cp = line;
4072
verno = next_int(&cp);
4073
4074
if(verno != 2) {
4075
printf("Version number is not compatible with the parser: %d\n",verno);
4076
}
4077
4078
GETLINE;
4079
if(!strstr(line,"$EndMeshFormat")) {
4080
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
4081
}
4082
}
4083
4084
else if(strstr(line,"$Nodes")) {
4085
GETLINE;
4086
cp = line;
4087
noknots = next_int(&cp);
4088
4089
for(i=1; i <= noknots; i++) {
4090
GETLINE;
4091
cp = line;
4092
4093
j = next_int(&cp);
4094
if(allocated) {
4095
if(maxindx > noknots) revindx[j] = i;
4096
data->x[i] = next_real(&cp);
4097
data->y[i] = next_real(&cp);
4098
if(dim > 2) data->z[i] = next_real(&cp);
4099
}
4100
else {
4101
maxindx = MAX(j,maxindx);
4102
}
4103
}
4104
GETLINE;
4105
if(!strstr(line,"$EndNodes")) {
4106
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
4107
}
4108
}
4109
4110
else if(strstr(line,"$Elements")) {
4111
GETLINE;
4112
cp = line;
4113
noelements = next_int(&cp);
4114
4115
for(i=1; i <= noelements; i++) {
4116
GETLINE;
4117
4118
cp = line;
4119
elemno = next_int(&cp);
4120
gmshtype = next_int(&cp);
4121
elementtype = GmshToElmerType(gmshtype);
4122
4123
if(allocated) {
4124
elemnodes = elementtype % 100;
4125
data->elementtypes[i] = elementtype;
4126
4127
/* Point does not seem to have physical properties */
4128
notags = next_int(&cp);
4129
if(notags > 0) tagphys = next_int(&cp);
4130
if(notags > 1) taggeom = next_int(&cp);
4131
if(notags > 2) tagpart = next_int(&cp);
4132
for(j=4;j<=notags;j++)
4133
next_int(&cp);
4134
4135
if(tagphys) {
4136
tagmat = tagphys;
4137
}
4138
else {
4139
tagmat = taggeom;
4140
usetaggeom = TRUE;
4141
}
4142
4143
data->material[i] = tagmat;
4144
for(j=0;j<elemnodes;j++)
4145
elemind[j] = next_int(&cp);
4146
4147
GmshToElmerIndx(elementtype,elemind);
4148
4149
for(j=0;j<elemnodes;j++)
4150
data->topology[i][j] = elemind[j];
4151
}
4152
else {
4153
maxelemtype = MAX(maxelemtype,elementtype);
4154
}
4155
4156
}
4157
GETLINE;
4158
if(!strstr(line,"$EndElements")) {
4159
printf("$Elements section should end to string $EndElements:\n%s\n",line);
4160
}
4161
}
4162
else if(strstr(line,"$PhysicalNames")) {
4163
int entdim;
4164
entdim = dim;
4165
GETLINE;
4166
cp = line;
4167
nophysical = next_int(&cp);
4168
for(i=0;i<nophysical;i++) {
4169
GETLINE;
4170
if(allocated) {
4171
cp = line;
4172
gmshtype = next_int(&cp);
4173
if(gmshtype < entdim-1) {
4174
printf("Assuming maximum entity dim to be %d\n",dim-1);
4175
entdim--;
4176
}
4177
tagphys = next_int(&cp);
4178
if(gmshtype == entdim-1) {
4179
physsurfexist = TRUE;
4180
if(tagphys < MAXBCS) {
4181
if(!data->boundaryname[tagphys]) data->boundaryname[tagphys] = Cvector(0,MAXNAMESIZE);
4182
sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys]);
4183
}
4184
else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4185
}
4186
else if(gmshtype == entdim) {
4187
physvolexist = TRUE;
4188
4189
if(tagphys < MAXBODIES) {
4190
if(!data->bodyname[tagphys]) data->bodyname[tagphys] = Cvector(0,MAXNAMESIZE);
4191
sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
4192
}
4193
else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4194
}
4195
else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
4196
"ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
4197
}
4198
}
4199
4200
GETLINE;
4201
if(!strstr(line,"$EndPhysicalNames")) {
4202
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
4203
}
4204
}
4205
else {
4206
if(!allocated) printf("Untreated command: %s",line);
4207
}
4208
4209
}
4210
4211
end:
4212
4213
4214
if(!allocated) {
4215
maxnodes = maxelemtype % 100;
4216
InitializeKnots(data);
4217
data->dim = dim;
4218
data->maxnodes = maxnodes;
4219
data->noelements = noelements;
4220
data->noknots = noknots;
4221
4222
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
4223
AllocateKnots(data);
4224
4225
if(maxindx > noknots) {
4226
revindx = Ivector(1,maxindx);
4227
for(i=1;i<=maxindx;i++) revindx[i] = 0;
4228
}
4229
rewind(in);
4230
allocated = TRUE;
4231
goto omstart;
4232
}
4233
4234
if(maxindx > noknots) {
4235
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
4236
4237
for(i=1; i <= noelements; i++) {
4238
elementtype = data->elementtypes[i];
4239
elemnodes = elementtype % 100;
4240
4241
for(j=0;j<elemnodes;j++) {
4242
k = data->topology[i][j];
4243
if(k <= 0 || k > maxindx)
4244
printf("index out of bounds %d\n",k);
4245
else if(revindx[k] <= 0)
4246
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
4247
else
4248
data->topology[i][j] = revindx[k];
4249
}
4250
}
4251
free_Ivector(revindx,1,maxindx);
4252
}
4253
4254
ElementsToBoundaryConditions(data,bound,keeporphans,info);
4255
4256
data->bodynamesexist = physvolexist;
4257
data->boundarynamesexist = physsurfexist;
4258
4259
if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
4260
4261
return(0);
4262
}
4263
4264
4265
static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
4266
char *filename,int usetaggeom, int keeporphans, int info)
4267
{
4268
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
4269
int elemind[MAXNODESD2],elementtype;
4270
int i,j,k,l,allocated,*revindx=NULL,maxindx;
4271
int elemno, gmshtype, tagphys=0, tagpart, elemnodes,maxelemtype;
4272
int tagmat,verno;
4273
int physvolexist, physsurfexist,**tagmap,tagsize,maxtag[4];
4274
FILE *in;
4275
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
4276
char *cp,line[MAXLINESIZE],longline[LONGLINESIZE];
4277
4278
if ((in = fopen(filename,"r")) == NULL) {
4279
printf("LoadGmshInput4: The opening of the mesh file %s failed!\n",filename);
4280
return(1);
4281
}
4282
if(info) printf("Loading mesh in Gmsh format 4.0 from file %s\n",filename);
4283
4284
allocated = FALSE;
4285
dim = data->dim;
4286
maxnodes = 0;
4287
maxindx = 0;
4288
maxelemtype = 0;
4289
physvolexist = FALSE;
4290
physsurfexist = FALSE;
4291
usetaggeom = TRUE; /* The default */
4292
for(i=0;i<4;i++) maxtag[i] = 0;
4293
4294
4295
omstart:
4296
4297
for(;;) {
4298
if(Getrow(line,in,FALSE)) goto end;
4299
if(strstr(line,"$End")) continue;
4300
4301
if(strstr(line,"$MeshFormat")) {
4302
GETLINE;
4303
cp = line;
4304
verno = next_int(&cp);
4305
4306
if(verno != 4) {
4307
printf("Version number is not compatible with the parser: %d\n",verno);
4308
}
4309
4310
GETLINE;
4311
if(!strstr(line,"$EndMeshFormat")) {
4312
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
4313
}
4314
}
4315
4316
else if(strstr(line,"$Nodes")) {
4317
int numEntityBlocks,tagEntity,dimEntity,parEntity,numNodes,ind;
4318
4319
GETLINE;
4320
cp = line;
4321
4322
numEntityBlocks = next_int(&cp);
4323
noknots = next_int(&cp);
4324
4325
if(allocated && info) printf("Reading %d nodes in %d blocks.\n",noknots,numEntityBlocks);
4326
4327
k = 0;
4328
4329
for(j=1; j <= numEntityBlocks; j++) {
4330
GETLINE;
4331
cp = line;
4332
4333
tagEntity = next_int(&cp);
4334
dimEntity = next_int(&cp);
4335
parEntity = next_int(&cp);
4336
numNodes = next_int(&cp);
4337
4338
for(i=1; i <= numNodes; i++) {
4339
GETLINE;
4340
cp = line;
4341
k += 1;
4342
4343
ind = next_int(&cp);
4344
if(allocated) {
4345
if(maxindx > noknots) revindx[ind] = k;
4346
data->x[k] = next_real(&cp);
4347
data->y[k] = next_real(&cp);
4348
if(dim > 2) data->z[k] = next_real(&cp);
4349
}
4350
else {
4351
maxindx = MAX(ind,maxindx);
4352
}
4353
}
4354
}
4355
GETLINE;
4356
4357
if(!strstr(line,"$EndNodes")) {
4358
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
4359
}
4360
}
4361
4362
else if(strstr(line,"$Entities")) {
4363
int numPoints, numCurves, numSurfaces, numVolumes, numEnt;
4364
int tag,tagdim,nophys,phystag;
4365
int nobound, idum;
4366
Real rdum;
4367
4368
usetaggeom = FALSE;
4369
4370
GETLINE;
4371
cp = line;
4372
numPoints = next_int(&cp);
4373
numCurves = next_int(&cp);
4374
numSurfaces = next_int(&cp);
4375
numVolumes = next_int(&cp);
4376
4377
if(allocated) {
4378
tagsize = 0;
4379
for(tagdim=0;tagdim<=3;tagdim++)
4380
tagsize = MAX( tagsize, maxtag[tagdim]);
4381
if( tagsize > 0 ) {
4382
tagmap = Imatrix(0,3,1,tagsize);
4383
for(i=0;i<=3;i++)
4384
for(j=1;j<=tagsize;j++)
4385
tagmap[i][j] = 0;
4386
}
4387
}
4388
4389
for(tagdim=0;tagdim<=3;tagdim++) {
4390
4391
if( tagdim == 0 )
4392
numEnt = numPoints;
4393
else if( tagdim == 1 )
4394
numEnt = numCurves;
4395
else if( tagdim == 2 )
4396
numEnt = numSurfaces;
4397
else if( tagdim == 3 )
4398
numEnt = numVolumes;
4399
4400
if(!allocated)
4401
maxtag[tagdim] = 0;
4402
else if( maxtag[tagdim] > 0 )
4403
printf("Tag range for %d %dDIM entities is [%d %d]\n",numEnt,tagdim,0,maxtag[tagdim]);
4404
4405
if(numEnt > 0 && !allocated) {
4406
printf("Reading %d entities in %dD\n",numEnt,tagdim);
4407
}
4408
4409
for(i=1; i <= numEnt; i++) {
4410
GETLONGLINE;
4411
4412
// if( i==1 ) printf("1st line of dim %d with %d entries: %s\n",tagdim,numEnt,line);
4413
4414
if( tagdim == 0 ) continue;
4415
4416
cp = longline;
4417
tag = next_int(&cp);
4418
4419
if(!allocated)
4420
maxtag[tagdim] = MAX( maxtag[tagdim], tag );
4421
4422
for(j=1;j<=6;j++) rdum = next_real(&cp);
4423
nophys = next_int(&cp);
4424
4425
phystag = 0;
4426
if( nophys > 0 ) phystag = next_int(&cp);
4427
4428
if(allocated) tagmap[tagdim][tag] = phystag;
4429
4430
4431
// The lines may be too long. So fill the string buffer until we get a newline.
4432
j = k = 0;
4433
for(;;) {
4434
for(l=0;l<LONGLINESIZE;l++) {
4435
if( longline[l] == '\n') {
4436
j = l+1;
4437
break;
4438
}
4439
}
4440
if(j) {
4441
j--;
4442
break;
4443
}
4444
k += LONGLINESIZE;
4445
GETLONGLINE;
4446
}
4447
if( k > 0 && !allocated) printf("Entity line %d has length %d.\n",i,k+j);
4448
4449
//for(j=2;j<=nophys;j++)
4450
// idum = next_int(&cp);
4451
4452
//// if( tagdim == 0 ) continue;
4453
4454
//nobound = next_int(&cp);
4455
// for(j=1;j<=nobound;j++)
4456
// idum = next_int(&cp);
4457
}
4458
}
4459
4460
GETLONGLINE;
4461
if(!strstr(longline,"$EndEntities")) {
4462
printf("$Entities section should end to string $EndEntities:\n%s\n",longline);
4463
}
4464
}
4465
4466
else if(strstr(line,"$Elements")) {
4467
int numEntityBlocks, numElements, tagEntity, dimEntity, typeEle, NumElements;
4468
4469
GETLINE;
4470
cp = line;
4471
4472
k = 0;
4473
numEntityBlocks = next_int(&cp);
4474
noelements = next_int(&cp);
4475
4476
if(allocated) printf("Reading %d elements in %d blocks.\n",noelements,numEntityBlocks);
4477
4478
4479
for(j=1; j<= numEntityBlocks; j++ ) {
4480
4481
GETLINE;
4482
cp = line;
4483
4484
tagEntity = next_int(&cp);
4485
dimEntity = next_int(&cp);
4486
4487
typeEle = next_int(&cp);
4488
numElements = next_int(&cp);
4489
4490
elementtype = GmshToElmerType(typeEle);
4491
elemnodes = elementtype % 100;
4492
maxelemtype = MAX(maxelemtype,elementtype);
4493
4494
if( allocated && tagsize > 0 ) {
4495
printf("Reading %d elements with tag %d of type %d\n", numElements, tagEntity, elementtype);
4496
if( tagsize > 0 ) {
4497
if( tagmap[dimEntity][tagEntity] ) {
4498
printf(" Mapping mesh tag %d to physical tag %d in %dDIM\n",tagEntity,tagmap[dimEntity][tagEntity],dimEntity);
4499
tagEntity = tagmap[dimEntity][tagEntity];
4500
}
4501
else {
4502
printf(" Mesh tag %d is not associated to any physical tag!\n",tagEntity);
4503
}
4504
}
4505
}
4506
4507
for(i=1; i <= numElements; i++) {
4508
GETLINE;
4509
cp = line;
4510
4511
k += 1;
4512
4513
elemno = next_int(&cp);
4514
4515
if(allocated) {
4516
data->elementtypes[k] = elementtype;
4517
data->material[k] = tagEntity;
4518
for(l=0;l<elemnodes;l++)
4519
elemind[l] = next_int(&cp);
4520
4521
GmshToElmerIndx(elementtype,elemind);
4522
4523
for(l=0;l<elemnodes;l++)
4524
data->topology[k][l] = elemind[l];
4525
}
4526
}
4527
}
4528
4529
GETLINE;
4530
if(!strstr(line,"$EndElements")) {
4531
printf("$Elements section should end to string $EndElements:\n%s\n",line);
4532
}
4533
}
4534
4535
else if(strstr(line,"$PhysicalNames")) {
4536
int entdim;
4537
entdim = dim;
4538
GETLINE;
4539
cp = line;
4540
nophysical = next_int(&cp);
4541
for(i=0;i<nophysical;i++) {
4542
GETLINE;
4543
if(allocated) {
4544
cp = line;
4545
gmshtype = next_int(&cp);
4546
if(gmshtype < entdim-1) {
4547
printf("Assuming maximum entity dim to be %d\n",dim-1);
4548
entdim--;
4549
}
4550
tagphys = next_int(&cp);
4551
if(gmshtype == entdim-1) {
4552
physsurfexist = TRUE;
4553
if(tagphys < MAXBCS) {
4554
if(!data->boundaryname[tagphys]) data->boundaryname[tagphys] = Cvector(0,MAXNAMESIZE);
4555
sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys]);
4556
printf("Boundary name for physical group %d is: %s\n",tagphys,data->boundaryname[tagphys]);
4557
}
4558
else {
4559
printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4560
}
4561
}
4562
else if(gmshtype == entdim) {
4563
physvolexist = TRUE;
4564
if(tagphys < MAXBODIES) {
4565
if(!data->bodyname[tagphys]) data->bodyname[tagphys] = Cvector(0,MAXNAMESIZE);
4566
sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
4567
printf("Body name for physical group %d is: %s\n",tagphys,data->bodyname[tagphys]);
4568
}
4569
else {
4570
printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[gmshtype],cp+1);
4571
}
4572
}
4573
else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
4574
"ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
4575
}
4576
}
4577
4578
GETLINE;
4579
if(!strstr(line,"$EndPhysicalNames")) {
4580
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
4581
}
4582
}
4583
else if(strstr(line,"$Periodic")) {
4584
int numPeriodicLinks;
4585
if(allocated) printf("Reading periodic links but doing nothing with them!\n");
4586
4587
GETLINE;
4588
cp = line;
4589
numPeriodicLinks = next_int(&cp);
4590
for(i=1; i <= numPeriodicLinks; i++) {
4591
GETLINE;
4592
}
4593
GETLINE;
4594
if(!strstr(line,"$EndPeriodic")) {
4595
printf("$Periodic section should end to string $EndPeriodic:\n%s\n",line);
4596
}
4597
}
4598
4599
else if(strstr(line,"$PartitionedEntities")) {
4600
if(allocated) printf("Reading partitioned entities but doing nothing with them!\n");
4601
for(;;) {
4602
GETLINE;
4603
if(strstr(line,"$EndPartitionedEntities")) break;
4604
}
4605
}
4606
else if(strstr(line,"$NodeData")) {
4607
if(allocated) printf("Reading node data but doing nothing with them!\n");
4608
for(;;) {
4609
GETLINE;
4610
if(strstr(line,"$EndNodeData")) break;
4611
}
4612
}
4613
else if(strstr(line,"$ElementData")) {
4614
if(allocated) printf("Reading element data but doing nothing with them!\n");
4615
for(;;) {
4616
GETLINE;
4617
if(strstr(line,"$EndElementData")) break;
4618
}
4619
}
4620
else if(strstr(line,"$ElementNodeData")) {
4621
if(allocated) printf("Reading element node data but doing nothing with them!\n");
4622
for(;;) {
4623
GETLINE;
4624
if(strstr(line,"$EndElementNodeData")) break;
4625
}
4626
}
4627
else if(strstr(line,"$GhostElements")) {
4628
if(allocated) printf("Reading ghost elements data but doing nothing with them!\n");
4629
for(;;) {
4630
GETLINE;
4631
if(strstr(line,"$EndGhostElements")) break;
4632
}
4633
}
4634
else if(strstr(line,"$InterpolationScheme")) {
4635
if(allocated) printf("Reading interpolation scheme but doing nothing with them!\n");
4636
for(;;) {
4637
GETLINE;
4638
if(strstr(line,"$EndInterpolationScheme")) break;
4639
}
4640
}
4641
else {
4642
if(allocated) printf("Untreated command: %s",line);
4643
}
4644
4645
}
4646
4647
end:
4648
4649
4650
if(!allocated) {
4651
if( noelements == 0 ) bigerror("No elements to load in Gmsh file!");
4652
if( noknots == 0 ) bigerror("No nodes to load in Gmsh file!");
4653
4654
maxnodes = maxelemtype % 100;
4655
InitializeKnots(data);
4656
data->dim = dim;
4657
data->maxnodes = maxnodes;
4658
data->noelements = noelements;
4659
data->noknots = noknots;
4660
4661
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
4662
AllocateKnots(data);
4663
4664
if(maxindx > noknots) {
4665
revindx = Ivector(1,maxindx);
4666
for(i=1;i<=maxindx;i++) revindx[i] = 0;
4667
}
4668
rewind(in);
4669
allocated = TRUE;
4670
goto omstart;
4671
}
4672
4673
if(maxindx > noknots) {
4674
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
4675
4676
for(i=1; i <= noelements; i++) {
4677
elementtype = data->elementtypes[i];
4678
elemnodes = elementtype % 100;
4679
4680
for(j=0;j<elemnodes;j++) {
4681
k = data->topology[i][j];
4682
if(k <= 0 || k > maxindx)
4683
printf("index out of bounds %d\n",k);
4684
else if(revindx[k] <= 0)
4685
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
4686
else
4687
data->topology[i][j] = revindx[k];
4688
}
4689
}
4690
free_Ivector(revindx,1,maxindx);
4691
}
4692
4693
ElementsToBoundaryConditions(data,bound,keeporphans,info);
4694
4695
data->bodynamesexist = physvolexist;
4696
data->boundarynamesexist = physsurfexist;
4697
4698
if( tagsize > 0 ) free_Imatrix(tagmap,0,3,1,tagsize);
4699
4700
if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
4701
4702
return(0);
4703
}
4704
4705
4706
static int LoadGmshInput41(struct FemType *data,struct BoundaryType *bound,
4707
char *filename,int usetaggeom, int keeporphans, int gmshbinary, int info)
4708
{
4709
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
4710
int elemind[MAXNODESD2],elementtype;
4711
int i,j,k,l,allocated,*revindx=NULL,maxindx;
4712
int elemno, gmshtype, tagphys=0, tagpart, elemnodes,maxelemtype;
4713
int tagmat,verno,meshdim,tagdim,frcount;
4714
int physvolexist, physsurfexist,**tagmap,tagsize;
4715
int maxtag[4],mintag[4],maxreadtag[4],minreadtag[4];
4716
int maxphystag[4],minphystag[4],tagoffset[4],phystagoffset[4];
4717
FILE *in;
4718
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
4719
char *cp,line[MAXLINESIZE],longline[LONGLINESIZE];
4720
4721
if ((in = fopen(filename,"rb")) == NULL) {
4722
printf("The opening of the mesh file %s failed!\n",filename);
4723
return(1);
4724
}
4725
if(info) printf("Loading mesh in Gmsh format 4.1 from file %s\n",filename);
4726
4727
allocated = FALSE;
4728
dim = data->dim;
4729
meshdim = 0;
4730
maxnodes = 0;
4731
maxindx = 0;
4732
maxelemtype = 0;
4733
physvolexist = FALSE;
4734
physsurfexist = FALSE;
4735
usetaggeom = TRUE; /* The default */
4736
for(i=0;i<4;i++) {
4737
maxtag[i] = mintag[i] = -1;
4738
minreadtag[i] = maxreadtag[i] = -1;
4739
maxphystag[i] = minphystag[i] = -1;
4740
tagoffset[i] = phystagoffset[i] = 0;
4741
}
4742
4743
omstart:
4744
4745
if(allocated) printf("Leading element dimension is %d\n",meshdim);
4746
4747
for(;;) {
4748
if(Getrow(line,in,FALSE)) goto end;
4749
if(strstr(line,"$End")) continue;
4750
4751
if(strstr(line,"$MeshFormat")) {
4752
GETLINE;
4753
if(gmshbinary){
4754
int one;
4755
frcount = fread(&one, sizeof(int), 1, in);
4756
if(one != 1) {
4757
printf("Gmsh binary file needs to swap bytes, not implemented in ElmerGrid. Exiting!\n");
4758
bigerror("Gmsh binary file needs to swap bytes, not implemented in ElmerGrid. Exiting!");
4759
}
4760
GETLINE;
4761
}
4762
GETLINE;
4763
if(!strstr(line,"$EndMeshFormat"))
4764
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
4765
}
4766
4767
else if(strstr(line,"$Nodes")) {
4768
int numEntityBlocks,tagEntity,dimEntity,parEntity,numNodes;
4769
int minNodeTag, maxNodeTag, parTag;
4770
size_t tagNode;
4771
4772
if(gmshbinary) {
4773
size_t inputData[4];
4774
frcount = fread(inputData, sizeof(size_t), 4, in);
4775
if(frcount != 4)
4776
printf("1 fread error, frcount = %d, not equal to %d\n",frcount,4);
4777
numEntityBlocks = (int) inputData[0];
4778
noknots = (int) inputData[1];
4779
minNodeTag = (int) inputData[2];
4780
maxNodeTag = (int) inputData[3];
4781
}
4782
else {
4783
GETLINE;
4784
cp = line;
4785
numEntityBlocks = next_int(&cp);
4786
noknots = next_int(&cp);
4787
minNodeTag = next_int(&cp);
4788
maxNodeTag = next_int(&cp);
4789
}
4790
if(allocated && info) printf("Reading %d nodes in %d blocks.\n",
4791
noknots,numEntityBlocks);
4792
4793
k = 0;
4794
4795
for(j=1; j <= numEntityBlocks; j++) {
4796
if(gmshbinary) {
4797
int inputData[3];
4798
size_t numNodesInBlock;
4799
frcount = fread(inputData, sizeof(int), 3, in);
4800
if(frcount != 3)
4801
printf("2 fread error, frcount = %d, not equal to %d\n",frcount,3);
4802
dimEntity = inputData[0];
4803
tagEntity = inputData[1];
4804
parTag = inputData[2];
4805
4806
frcount = fread(&numNodesInBlock, sizeof(size_t), 1, in);
4807
if(frcount != 1)
4808
printf("3 fread error, frcount = %d, not equal to %d\n",frcount,1);
4809
numNodes = (int) numNodesInBlock;
4810
}
4811
else {
4812
GETLINE;
4813
cp = line;
4814
dimEntity = next_int(&cp);
4815
tagEntity = next_int(&cp);
4816
parTag = next_int(&cp);
4817
numNodes = next_int(&cp);
4818
}
4819
4820
if( 0 && numNodes > 1 ) printf("Reading node block %d with %d nodes\n",j,numNodes);
4821
4822
for(i=1; i <= numNodes; i++) {
4823
if(gmshbinary) {
4824
frcount = fread(&tagNode, sizeof(size_t), 1, in);
4825
if(frcount != 1)
4826
printf("4 fread error, frcount = %d, not equal to %d\n",frcount,1);
4827
}
4828
else {
4829
GETLINE;
4830
cp = line;
4831
tagNode = next_int(&cp);
4832
}
4833
4834
if( 0 && numNodes > 1 ) printf("block %d node %d tagNode %lu %d\n",j,i,(unsigned long)tagNode,k+i);
4835
4836
if(allocated) {
4837
if(maxindx > noknots) revindx[tagNode] = k+i;
4838
}
4839
else {
4840
maxindx = MAX(tagNode,maxindx);
4841
}
4842
}
4843
4844
for(i=1; i <= numNodes; i++) {
4845
if(gmshbinary) {
4846
double inputData[3];
4847
frcount = fread(inputData, sizeof(double), 3, in);
4848
if(frcount != 3)
4849
printf("5 fread error, frcount = %d, not equal to %d\n",frcount,3);
4850
if(allocated) {
4851
data->x[k+i] = inputData[0];
4852
data->y[k+i] = inputData[1];
4853
data->z[k+i] = inputData[2];
4854
}
4855
}
4856
else {
4857
double x,y,z;
4858
GETLINE;
4859
cp = line;
4860
if(allocated) {
4861
data->x[k+i] = next_real(&cp);
4862
data->y[k+i] = next_real(&cp);
4863
data->z[k+i] = next_real(&cp);
4864
}
4865
}
4866
}
4867
k += numNodes;
4868
}
4869
if(gmshbinary) GETLINE;
4870
GETLINE;
4871
if(!strstr(line,"$EndNodes"))
4872
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
4873
}
4874
4875
else if(strstr(line,"$Entities")) {
4876
int numPoints, numCurves, numSurfaces, numVolumes, numEnt;
4877
int tag,phystag;
4878
size_t nophys,nobound;
4879
int idum;
4880
Real rdum;
4881
4882
usetaggeom = FALSE;
4883
4884
if(gmshbinary) {
4885
size_t data[4];
4886
frcount = fread(data, sizeof(size_t), 4, in);
4887
if(frcount != 4)
4888
printf("6 fread error, frcount = %d, not equal to %d\n",frcount,4);
4889
numPoints = (int) data[0];
4890
numCurves = (int) data[1];
4891
numSurfaces = (int) data[2];
4892
numVolumes = (int) data[3];
4893
}
4894
else {
4895
GETLINE;
4896
cp = line;
4897
numPoints = next_int(&cp);
4898
numCurves = next_int(&cp);
4899
numSurfaces = next_int(&cp);
4900
numVolumes = next_int(&cp);
4901
}
4902
4903
if(allocated) {
4904
tagsize = 0;
4905
for(tagdim=0; tagdim<=meshdim; tagdim++)
4906
tagsize = MAX( tagsize, maxtag[tagdim]);
4907
if(info) printf("Allocating lookup table for tags of size %d\n",tagsize);
4908
if( tagsize > 0 ) {
4909
tagmap = Imatrix(0,3,1,tagsize);
4910
for(i=0; i<=3; i++)
4911
for(j=1; j<=tagsize; j++)
4912
tagmap[i][j] = 0;
4913
}
4914
}
4915
for(tagdim=0; tagdim<=3; tagdim++) {
4916
4917
if( tagdim == 0 )
4918
numEnt = numPoints;
4919
else if( tagdim == 1 )
4920
numEnt = numCurves;
4921
else if( tagdim == 2 )
4922
numEnt = numSurfaces;
4923
else if( tagdim == 3 )
4924
numEnt = numVolumes;
4925
4926
if(allocated && numEnt > 0 ) {
4927
if( maxtag[tagdim] > 0 ) {
4928
if( mintag[tagdim] == -1 ) mintag[tagdim] = maxtag[tagdim];
4929
if( minphystag[tagdim] == -1) minphystag[tagdim] = maxphystag[tagdim];
4930
printf("Defined %d %dDIM entities with geometric tag range [%d %d]\n",
4931
numEnt,tagdim,mintag[tagdim],maxtag[tagdim]);
4932
if( maxphystag[tagdim] > 0 || maxreadtag[tagdim] > 0 ) {
4933
printf(" Physical given tag range is [%d %d]\n",minphystag[tagdim],maxphystag[tagdim]);
4934
if( maxreadtag[tagdim] != maxphystag[tagdim] || minreadtag[tagdim] != minphystag[tagdim]) {
4935
if(maxreadtag[tagdim] > 0 )
4936
printf(" Physical read tag range is [%d %d]\n",minreadtag[tagdim],maxreadtag[tagdim]);
4937
else
4938
printf(" No physical tags read for real!\n");
4939
if(0) smallerror("Physical names not used consistently!");
4940
}
4941
} else {
4942
if(0) printf("No physical tags defined, using geometric entities!\n");
4943
}
4944
4945
}
4946
if( tagdim > meshdim ) {
4947
printf("We have %d %dDIM tags that are beyond mesh dimension %d!\n",
4948
numEnt, tagdim, meshdim );
4949
}
4950
}
4951
4952
if(numEnt > 0 && !allocated) printf("Reading %d entities in %dD\n",numEnt,tagdim);
4953
4954
for(i=1; i <= numEnt; i++) {
4955
if(gmshbinary) {
4956
frcount = fread(&tag, sizeof(int), 1, in);
4957
if(frcount != 1)
4958
printf("7 fread error, frcount = %d, not equal to %d\n",frcount,1);
4959
4960
if(tagdim == 0) {
4961
double inputData3[3];
4962
// read away the bounding box data that we do not need for anything
4963
frcount = fread(&inputData3, sizeof(double), 3, in);
4964
if(frcount != 3)
4965
printf("8 fread error, frcount = %d, not equal to %d\n",frcount,3);
4966
frcount = fread(&nophys, sizeof(size_t), 1, in);
4967
if(frcount != 1)
4968
printf("9 fread error, frcount = %d, not equal to %d\n",frcount,1);
4969
if(nophys > 0) {
4970
frcount = fread(&phystag, sizeof(int), nophys, in);
4971
if(frcount != (int) nophys)
4972
printf("9 fread error, frcount = %d, not equal to %lu\n",
4973
frcount,(unsigned long) nophys);
4974
}
4975
} else {
4976
double inputData6[6];
4977
// read away the bounding box data that we do not need for anything
4978
frcount = fread(&inputData6, sizeof(double), 6, in);
4979
if(frcount != 6)
4980
printf("10 fread error, frcount = %d, not equal to %d\n",frcount,6);
4981
frcount = fread(&nophys, sizeof(size_t), 1, in);
4982
if(frcount != 1)
4983
printf("11 fread error, frcount = %d, not equal to %d\n",frcount,1);
4984
if(nophys > 0) {
4985
frcount = fread(&phystag, sizeof(int), nophys, in);
4986
if(frcount != (int) nophys)
4987
printf("12 fread error, frcount = %d, not equal to %lu\n",
4988
frcount,(unsigned long) nophys);
4989
}
4990
frcount = fread(&nobound, sizeof(size_t), 1, in);
4991
if(frcount != 1)
4992
printf("13 fread error, frcount = %d, not equal to %d\n",frcount,1);
4993
4994
int noboundint = (int) nobound;
4995
if(noboundint > 0) {
4996
for( k= 0; k < noboundint; k++) {
4997
frcount = fread(&idum, sizeof(int), 1, in);
4998
if(frcount != 1)
4999
printf("14 fread error, frcount = %d, not equal to %d\n",frcount,1);
5000
}
5001
}
5002
}
5003
// Read the first physical tag if there are any
5004
if( nophys > 0 ) {
5005
if(!allocated) {
5006
maxreadtag[tagdim] = MAX( maxreadtag[tagdim], phystag );
5007
if( minreadtag[tagdim] == -1 ) {
5008
minreadtag[tagdim] = phystag;
5009
}
5010
else {
5011
minreadtag[tagdim] = MIN( minreadtag[tagdim], phystag );
5012
}
5013
}
5014
else {
5015
tagmap[tagdim][tag] = phystag;
5016
}
5017
}
5018
}
5019
else {
5020
GETLONGLINE;
5021
// printf("%d line of dim %d with %d entries: %s\n",i,tagdim,numEnt,line);
5022
5023
//if( tagdim == 0 ) continue;
5024
5025
cp = longline;
5026
tag = next_int(&cp);
5027
5028
if(!allocated) {
5029
maxtag[tagdim] = MAX( maxtag[tagdim], tag );
5030
if( mintag[tagdim] == -1 ) {
5031
mintag[tagdim] = tag;
5032
}
5033
else {
5034
mintag[tagdim] = MIN( mintag[tagdim], tag );
5035
}
5036
}
5037
5038
// read away the bounding box data that we do not need for anything
5039
if(tagdim == 0)
5040
k = 3;
5041
else
5042
k = 6;
5043
for(j=1; j<=k; j++) rdum = next_real(&cp);
5044
5045
// Number of physical tags
5046
nophys = next_int(&cp);
5047
5048
// Read the first physical tag if there are any
5049
if( nophys > 0 ) {
5050
if(0) printf("Reading number of physical tags: %lu\n",(unsigned long) nophys);
5051
phystag = next_int(&cp);
5052
if(!allocated) {
5053
if(0) printf("Phystag: %d %d %d %d\n",tagdim,tag,i,phystag);
5054
maxreadtag[tagdim] = MAX( maxreadtag[tagdim], phystag );
5055
if( minreadtag[tagdim] == -1 ) {
5056
minreadtag[tagdim] = phystag;
5057
}
5058
else {
5059
minreadtag[tagdim] = MIN( minreadtag[tagdim], phystag );
5060
}
5061
}
5062
else {
5063
tagmap[tagdim][tag] = phystag;
5064
}
5065
}
5066
}
5067
5068
if(!allocated) {
5069
maxtag[tagdim] = MAX( maxtag[tagdim], tag );
5070
if( mintag[tagdim] == -1 ) {
5071
mintag[tagdim] = tag;
5072
}
5073
else {
5074
mintag[tagdim] = MIN( mintag[tagdim], tag );
5075
}
5076
}
5077
if(!gmshbinary) {
5078
// The lines may be too long. So fill the string buffer until we get a newline.
5079
j = k = 0;
5080
for(;;) {
5081
for(l=0; l<LONGLINESIZE; l++) {
5082
if( longline[l] == '\n') {
5083
// we should have positive j even when the newline is the 0th entry!
5084
j = l+1;
5085
break;
5086
}
5087
}
5088
if(j) {
5089
j--;
5090
break;
5091
}
5092
k += LONGLINESIZE;
5093
GETLONGLINE;
5094
if(0) printf("extra getlongline: %s\n",longline);
5095
fflush(stdout);
5096
}
5097
if( k > 0 && !allocated) printf("Entity line %d has length %d.\n",i,k+j);
5098
}
5099
}
5100
}
5101
5102
for(tagdim=meshdim-2;tagdim>=0;tagdim--) {
5103
phystagoffset[tagdim] = phystagoffset[tagdim+1]+MAX(0,maxphystag[tagdim+1]);
5104
printf("Physical tag offset for %dD is %d\n",tagdim,phystagoffset[tagdim]);
5105
}
5106
5107
if(meshdim>0) {
5108
tagoffset[meshdim] = maxphystag[meshdim];
5109
tagoffset[meshdim-1] = phystagoffset[0];
5110
}
5111
for(tagdim=meshdim-2;tagdim>=0;tagdim--) {
5112
tagoffset[tagdim] = tagoffset[tagdim+1]+MAX(0,maxtag[tagdim+1]);
5113
printf("Geometric tag offset for %dD is %d\n",tagdim,tagoffset[tagdim]);
5114
}
5115
5116
if(gmshbinary) GETLONGLINE;
5117
GETLONGLINE;
5118
if(!strstr(longline,"$EndEntities"))
5119
printf("$Entities section should end to string $EndEntities:\n%s\n",longline);
5120
}
5121
5122
else if(strstr(line,"$Elements")) {
5123
size_t numEntityBlocks, minElementTag, maxElementTag;
5124
size_t numElementsInBlock;
5125
int dimEntity, tagEntity, typeEle, numElements;
5126
5127
k = 0;
5128
5129
if(gmshbinary) {
5130
size_t data[4], totalNumElements;
5131
frcount = fread(data, sizeof(size_t), 4, in);
5132
if(frcount != 4)
5133
printf("17 fread error, frcount = %d, not equal to %d\n",frcount,4);
5134
numEntityBlocks = data[0];
5135
totalNumElements = data[1];
5136
noelements = (int) totalNumElements;
5137
minElementTag = data[2];
5138
maxElementTag = data[3];
5139
}
5140
else {
5141
GETLINE;
5142
cp = line;
5143
numEntityBlocks = next_int(&cp);
5144
noelements = next_int(&cp);
5145
minElementTag = next_int(&cp);
5146
maxElementTag = next_int(&cp);
5147
}
5148
5149
if(allocated) printf("Reading %d elements in %lu blocks.\n",noelements,(unsigned long) numEntityBlocks);
5150
5151
for(j=1; j<= (int) numEntityBlocks; j++ ) {
5152
5153
if(gmshbinary) {
5154
int data[3];
5155
frcount = fread(data, sizeof(int), 3, in);
5156
if(frcount != 3)
5157
printf("18 fread error, frcount = %d, not equal to %d\n",frcount,3);
5158
dimEntity = data[0];
5159
tagEntity = data[1];
5160
typeEle = data[2];
5161
frcount = fread(&numElementsInBlock, sizeof(size_t), 1, in);
5162
if(frcount != 1)
5163
printf("19 fread error, frcount = %d, not equal to %d\n",frcount,1);
5164
numElements = (int) numElementsInBlock;
5165
}
5166
else {
5167
GETLINE;
5168
cp = line;
5169
dimEntity = next_int(&cp);
5170
tagEntity = next_int(&cp);
5171
typeEle = next_int(&cp);
5172
numElements = next_int(&cp);
5173
}
5174
5175
elementtype = GmshToElmerType(typeEle);
5176
if(!elementtype)
5177
bigerror("Gmsh element type does not have an Elmer counterpart!\n");
5178
elemnodes = elementtype % 100;
5179
maxelemtype = MAX(maxelemtype,elementtype);
5180
5181
if(!allocated) meshdim = MAX(meshdim, GetElementDimension(elementtype));
5182
5183
if( allocated ) {
5184
if( tagsize > 0 ) {
5185
if( tagmap[dimEntity][tagEntity] ) {
5186
printf(" Mapping mesh tag %d to physical tag %d in %dDIM\n",
5187
tagEntity,tagmap[dimEntity][tagEntity],dimEntity);
5188
tagEntity = tagmap[dimEntity][tagEntity] + phystagoffset[dimEntity];
5189
}
5190
else {
5191
tagEntity += tagoffset[dimEntity];
5192
}
5193
}
5194
else {
5195
tagEntity += tagoffset[dimEntity];
5196
}
5197
}
5198
5199
size_t elementTag, nodeTag[126];
5200
// nodeTag size is based on gmsh element type 93, 125-node fourth order hexahedron
5201
// if newer and larger elements are added, then increase nodeTag size to match
5202
if(elemnodes > 125) {
5203
printf("error: number of nodes per element of %d, exceeds 125\n",elemnodes);
5204
printf("increase size of nodeTag and recompile. Exiting!\n");
5205
bigerror("number of nodes per element exceeds 125. Exiting!");
5206
}
5207
5208
for(int m=1; m <= numElements; m++) {
5209
if(gmshbinary) {
5210
frcount = fread(&elementTag, sizeof(size_t), 1, in);
5211
if(frcount != 1)
5212
printf("20 fread error, frcount = %d, not equal to %d\n",frcount,1);
5213
elemno = (int) elementTag;
5214
5215
k += 1;
5216
5217
if(allocated) {
5218
data->elementtypes[k] = elementtype;
5219
data->material[k] = tagEntity;
5220
frcount = fread(nodeTag, sizeof(size_t), elemnodes, in);
5221
if(frcount != elemnodes)
5222
printf("21 fread error, frcount = %d, not equal to %d\n",frcount,elemnodes);
5223
5224
for(l=0; l<elemnodes; l++){
5225
elemind[l] = (int) nodeTag[l];
5226
}
5227
5228
GmshToElmerIndx(elementtype,elemind);
5229
5230
for(l=0; l<elemnodes; l++)
5231
data->topology[k][l] = elemind[l];
5232
}
5233
else {
5234
frcount = fread(nodeTag, sizeof(size_t), elemnodes, in);
5235
if(frcount != elemnodes)
5236
printf("22 fread error, frcount = %d, not equal to %d\n",frcount,elemnodes);
5237
}
5238
}
5239
else {
5240
GETLINE;
5241
cp = line;
5242
elemno = next_int(&cp);
5243
5244
k += 1;
5245
5246
if(allocated) {
5247
data->elementtypes[k] = elementtype;
5248
data->material[k] = tagEntity;
5249
for(l=0; l<elemnodes; l++)
5250
elemind[l] = next_int(&cp);
5251
5252
GmshToElmerIndx(elementtype,elemind);
5253
5254
for(l=0; l<elemnodes; l++)
5255
data->topology[k][l] = elemind[l];
5256
}
5257
}
5258
}
5259
}
5260
5261
if(gmshbinary) GETLINE;
5262
GETLINE;
5263
if(!strstr(line,"$EndElements"))
5264
printf("$Elements section should end to string $EndElements:\n%s\n",line);
5265
}
5266
5267
else if(strstr(line,"$PhysicalNames")) {
5268
int entdim;
5269
entdim = dim;
5270
5271
GETLINE;
5272
cp = line;
5273
nophysical = next_int(&cp);
5274
for(i=0; i<nophysical; i++) {
5275
GETLINE;
5276
cp = line;
5277
tagdim = next_int(&cp);
5278
tagphys = next_int(&cp);
5279
5280
if(!allocated) {
5281
maxphystag[tagdim] = MAX( maxphystag[tagdim], tagphys );
5282
if( minphystag[tagdim] == -1 ) {
5283
minphystag[tagdim] = tagphys;
5284
}
5285
else {
5286
minphystag[tagdim] = MIN( minphystag[tagdim], tagphys );
5287
}
5288
}
5289
else if(allocated) {
5290
// We must not let different tags be overrun
5291
l = phystagoffset[tagdim];
5292
5293
if(tagdim < meshdim) {
5294
physsurfexist = TRUE;
5295
if(tagphys+l < MAXBCS) {
5296
data->boundarynamesexist = TRUE;
5297
if(!data->boundaryname[tagphys+l]) data->boundaryname[tagphys+l] = Cvector(0,MAXNAMESIZE);
5298
sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys+l]);
5299
printf("BC name for physical group %d is: %s\n",tagphys,data->boundaryname[tagphys+l]);
5300
}
5301
else {
5302
printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[tagdim],cp+1);
5303
}
5304
}
5305
else if(tagdim == meshdim) {
5306
physvolexist = TRUE;
5307
if(tagphys < MAXBODIES) {
5308
data->bodynamesexist = TRUE;
5309
if(!data->bodyname[tagphys]) data->bodyname[tagphys] = Cvector(0,MAXNAMESIZE);
5310
sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
5311
printf("Body name for physical group %d is: %s\n",tagphys,data->bodyname[tagphys]);
5312
}
5313
else {
5314
printf("Index %d too large: ignoring physical %s %s",tagphys,manifoldname[tagdim],cp+1);
5315
}
5316
}
5317
}
5318
}
5319
5320
GETLINE;
5321
if(!strstr(line,"$EndPhysicalNames"))
5322
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
5323
}
5324
else if(strstr(line,"$Periodic")) {
5325
int numPeriodicLinks;
5326
if(allocated) printf("Reading periodic links but doing nothing with them!\n");
5327
5328
if(1) {
5329
numPeriodicLinks = 0;
5330
for(;;) {
5331
GETLINE;
5332
if(strstr(line,"$EndPeriodic")) {
5333
if(allocated) printf("Number of lines for periodic stuff: %d\n",numPeriodicLinks);
5334
break;
5335
}
5336
numPeriodicLinks++;
5337
}
5338
}
5339
else {
5340
GETLINE;
5341
cp = line;
5342
numPeriodicLinks = next_int(&cp);
5343
for(i=1; i <= numPeriodicLinks; i++) {
5344
GETLINE;
5345
}
5346
GETLINE;
5347
if(!strstr(line,"$EndPeriodic")) {
5348
printf("$Periodic section should end to string $EndPeriodic:\n%s\n",line);
5349
}
5350
}
5351
}
5352
5353
else if(strstr(line,"$PartitionedEntities")) {
5354
if(allocated) printf("Reading partitioned entities but doing nothing with them!\n");
5355
for(;;) {
5356
GETLINE;
5357
if(strstr(line,"$EndPartitionedEntities")) break;
5358
}
5359
}
5360
else if(strstr(line,"$NodeData")) {
5361
if(allocated) printf("Reading node data but doing nothing with them!\n");
5362
for(;;) {
5363
GETLINE;
5364
if(strstr(line,"$EndNodeData")) break;
5365
}
5366
}
5367
else if(strstr(line,"$ElementData")) {
5368
if(allocated) printf("Reading element data but doing nothing with them!\n");
5369
for(;;) {
5370
GETLINE;
5371
if(strstr(line,"$EndElementData")) break;
5372
}
5373
}
5374
else if(strstr(line,"$ElementNodeData")) {
5375
if(allocated) printf("Reading element node data but doing nothing with them!\n");
5376
for(;;) {
5377
GETLINE;
5378
if(strstr(line,"$EndElementNodeData")) break;
5379
}
5380
}
5381
else if(strstr(line,"$GhostElements")) {
5382
if(allocated) printf("Reading ghost elements data but doing nothing with them!\n");
5383
for(;;){
5384
GETLINE;
5385
if(strstr(line,"$EndGhostElements")) break;
5386
}
5387
}
5388
else if(strstr(line,"$InterpolationScheme")) {
5389
if(allocated) printf("Reading interpolation scheme but doing nothing with them!\n");
5390
for(;;) {
5391
GETLINE;
5392
if(strstr(line,"$EndInterpolationScheme")) break;
5393
}
5394
}
5395
else {
5396
if(allocated) printf("Untreated command: %s",line);
5397
}
5398
}
5399
5400
end:
5401
5402
5403
if(!allocated) {
5404
if( noelements == 0 ) bigerror("No elements to load in Gmsh file!");
5405
if( noknots == 0 ) bigerror("No nodes to load in Gmsh file!");
5406
5407
maxnodes = maxelemtype % 100;
5408
InitializeKnots(data);
5409
data->dim = dim;
5410
data->maxnodes = maxnodes;
5411
data->noelements = noelements;
5412
data->noknots = noknots;
5413
5414
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
5415
AllocateKnots(data);
5416
5417
if(maxindx > noknots) {
5418
revindx = Ivector(1,maxindx);
5419
for(i=1;i<=maxindx;i++) revindx[i] = 0;
5420
}
5421
rewind(in);
5422
allocated = TRUE;
5423
goto omstart;
5424
}
5425
5426
if(maxindx > noknots) {
5427
int cnt1,cnt2,cnt3,cnt4;
5428
printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
5429
5430
cnt1 = cnt2 = cnt3 = cnt4 = 0;
5431
5432
for(i=1;i<=maxindx;i++)
5433
if(revindx[i]) cnt1++;
5434
printf(" Number of tagged nodes in reverse index table (out of %d): %d\n",maxindx,cnt1);
5435
5436
5437
for(i=1; i <= noelements; i++) {
5438
elementtype = data->elementtypes[i];
5439
elemnodes = elementtype % 100;
5440
5441
for(j=0; j<elemnodes; j++) {
5442
k = data->topology[i][j];
5443
if(k <= 0 || k > maxindx) {
5444
if(cnt2<10) printf(" index out of bounds %d\n",k);
5445
if(cnt2==10) printf(" ...\n");
5446
cnt2++;
5447
}
5448
else if(revindx[k] <= 0) {
5449
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);
5450
if(cnt3==10) printf(" ...\n");
5451
cnt3++;
5452
}
5453
else {
5454
cnt4++;
5455
data->topology[i][j] = revindx[k];
5456
}
5457
}
5458
}
5459
if(cnt2) printf(" Number of node indexes out of bounds [0 %d]: %d\n",maxindx,cnt2);
5460
if(cnt3) printf(" Number of node indexes not found in inverse index table: %d\n",cnt3);
5461
if(cnt4) printf(" Number of node indexes found in inverse index table: %d\n",cnt4);
5462
5463
free_Ivector(revindx,1,maxindx);
5464
}
5465
5466
ElementsToBoundaryConditions(data,bound,keeporphans,info);
5467
5468
data->bodynamesexist = physvolexist;
5469
data->boundarynamesexist = physsurfexist;
5470
5471
if( tagsize > 0 ) free_Imatrix(tagmap,0,3,1,tagsize);
5472
5473
if(info) printf("Successfully read the mesh from the Gmsh input file %s\n",filename);
5474
5475
return(0);
5476
}
5477
5478
int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,
5479
char *prefix,int keeporphans,int dim,int info)
5480
{
5481
FILE *in;
5482
char line[MAXLINESIZE],filename[MAXFILESIZE];
5483
int errnum,usetaggeom,i;
5484
5485
/* keeprophans - Should we keep lower order elements not associated to any
5486
higher order entity? ElmerGUI certainly does not like it. */
5487
5488
sprintf(filename,"%s",prefix);
5489
if ((in = fopen(filename,"r")) == NULL) {
5490
sprintf(filename,"%s.msh",prefix);
5491
if ((in = fopen(filename,"r")) == NULL) {
5492
printf("LoadGmshInput: The opening of the mesh file %s failed!\n",filename);
5493
return(1);
5494
}
5495
}
5496
5497
Getrow(line,in,FALSE);
5498
5499
if(info) printf("Format chosen using the first line: %s",line);
5500
5501
if(strstr(line,"$MeshFormat")) {
5502
// gmsh uses floating point for the version number, so let's also use floating point.
5503
// using the gmsh method with a double, actually works better and
5504
// is able to detect types 1 and 3 formats.
5505
double gmshversion;
5506
int gmshbinary,gmshsize;
5507
5508
Getrow(line,in,FALSE);
5509
fclose(in);
5510
5511
if(sscanf(line, "%lf %d %d", &gmshversion, &gmshbinary, &gmshsize) != 3) {
5512
printf("Gmsh input line: %s, expected but didn't receive three items on line. Exiting!\n",line);
5513
printf("Input line: %s\n",line);
5514
bigerror("Gmsh input line didn't receive the expected three items!");
5515
}
5516
5517
// gmshversion is a float, hence the ugly decimal points to insure proper comparisons
5518
if(gmshversion < 2.99) {
5519
if(gmshbinary) {
5520
printf("Gmsh input file format is type %5.1f, binary is not supported.\n",gmshversion);
5521
printf("If binary is needed, use Gmsh format 4.1 for output from Gmsh\n");
5522
bigerror("Gmsh input file in format 2.x, binary is not supported!");
5523
} else {
5524
printf("Gmsh input file format is type %5.1f in ASCII.\n",gmshversion);
5525
errnum = LoadGmshInput2(data,bound,filename,usetaggeom,keeporphans,info);
5526
}
5527
} else if(gmshversion < 3.99) {
5528
printf("Gmsh input file of format type %5.1f, is not supported. Exiting!\n",gmshversion);
5529
printf("Please use Gmsh 4 versions for output from Gmsh\n");
5530
bigerror("Gmsh input file format is not supported!");
5531
} else if(gmshversion < 4.09) {
5532
printf("Gmsh input file format is type %5.1f in ASCII.\n",gmshversion);
5533
errnum = LoadGmshInput4(data,bound,filename,usetaggeom,keeporphans,info);
5534
} else if(gmshversion < 5.0) {
5535
if(gmshbinary) {
5536
printf("Gmsh input file format is type %5.1f in binary.\n",gmshversion);
5537
} else {
5538
printf("Gmsh input file format is type %5.1f in ASCII.\n",gmshversion);
5539
}
5540
errnum = LoadGmshInput41(data,bound,filename,usetaggeom,keeporphans,gmshbinary,info);
5541
} else {
5542
printf("Gmsh input file of format type %5.1f, is not supported. Exiting!\n",gmshversion);
5543
printf("Please use Gmsh 4 versions for output from Gmsh\n");
5544
bigerror("Gmsh input file format is not supported!");
5545
}
5546
} else {
5547
printf("*****************************************************\n");
5548
printf("The first line did not start with $MeshFormat, assuming Gmsh 1 format\n");
5549
printf("This version of Gmsh format is no longer supported\n");
5550
printf("Please use Gmsh 4 versions for output from Gmsh\n");
5551
printf("*****************************************************\n");
5552
5553
errnum = LoadGmshInput1(data,bound,filename,info);
5554
}
5555
5556
if( info ) {
5557
if( usetaggeom )
5558
printf("Using geometric numbering of entities\n");
5559
else
5560
printf("Using physical numbering of entities\n");
5561
}
5562
5563
if(dim < 3)
5564
for(i=1;i<=data->noknots;i++) data->z[i] = 0.0;
5565
if(dim < 2)
5566
for(i=1;i<=data->noknots;i++) data->y[i] = 0.0;
5567
5568
return(errnum);
5569
}
5570
5571
5572
5573
int LoadFvcomMesh(struct FemType *data,struct BoundaryType *bound,
5574
char *filename,int info)
5575
{
5576
int noknots = 0,noelements = 0,maxnodes,dim;
5577
int elemind[MAXNODESD2],elementtype;
5578
int i,j,k,allocated,*revindx=NULL,maxindx;
5579
int elemnodes,maxelemtype,elemtype0,bclines;
5580
int tagmat,bccount;
5581
int *bcinds,*bctags,nbc,nbc0,bc_id;
5582
FILE *in;
5583
char *cp,line[MAXLINESIZE];
5584
5585
5586
if ((in = fopen(filename,"r")) == NULL) {
5587
printf("LoadFVCOMInput: The opening of the FVCOM mesh file %s failed!\n",filename);
5588
return(1);
5589
}
5590
if(info) printf("Loading mesh in FVCOM format from file %s\n",filename);
5591
5592
allocated = FALSE;
5593
dim = 2;
5594
maxnodes = 0;
5595
maxindx = 0;
5596
maxelemtype = 303;
5597
5598
noelements = 0;
5599
bclines = 0;
5600
5601
5602
omstart:
5603
5604
noelements = 0;
5605
noknots = 0;
5606
nbc = 0;
5607
nbc0 = 1;
5608
bclines = 0;
5609
bccount = 0;
5610
5611
for(;;) {
5612
if(Getrow(line,in,FALSE)) goto end;
5613
if(line[0]=='\0') goto end;
5614
5615
if(memcmp(line,"E3T",3) == 0 ) {
5616
noelements += 1;
5617
if(allocated) {
5618
cp = line+4;
5619
i = next_int(&cp);
5620
if(i != noelements ) printf("Invalid element number: %d %d\n",noelements,i);
5621
5622
data->elementtypes[i] = 303;
5623
for(k=0;k<3;k++)
5624
data->topology[i][k] = next_int(&cp);
5625
data->material[i] = next_int(&cp);
5626
}
5627
}
5628
else if(memcmp(line,"ND",2) == 0 ) {
5629
noknots += 1;
5630
if(allocated) {
5631
cp = line+3;
5632
i = next_int(&cp);
5633
if(i != noknots ) printf("Invalid node number: %d %d\n",noknots,i);
5634
data->x[i] = next_real(&cp);
5635
data->y[i] = next_real(&cp);
5636
if(dim > 2) data->z[i] = next_real(&cp);
5637
}
5638
}
5639
else if(memcmp(line,"NS",2) == 0 ) {
5640
bclines += 1;
5641
5642
if(allocated){
5643
cp = line+3;
5644
5645
for(i=0;i<10;i++) {
5646
j = next_int(&cp);
5647
5648
nbc += 1;
5649
bcinds[nbc] = abs(j);
5650
5651
if( j < 0 ) {
5652
bccount += 1;
5653
bc_id = next_int(&cp);
5654
5655
for(k=nbc0;k<=nbc;k++)
5656
bctags[k] = bc_id;
5657
5658
nbc0 = nbc+1;
5659
break;
5660
}
5661
}
5662
}
5663
}
5664
else if(memcmp(line,"MESH2D",6) == 0 ) {
5665
if(!allocated) printf("Yes, we have MESH2D as we should\n");
5666
}
5667
else if(memcmp(line,"MESHNAME",8) == 0 ) {
5668
if(!allocated) printf("Mesh name found but not used: %s\n",line+9);
5669
}
5670
}
5671
5672
end:
5673
5674
5675
if(!allocated) {
5676
maxnodes = maxelemtype % 100;
5677
InitializeKnots(data);
5678
data->dim = dim;
5679
data->maxnodes = maxnodes;
5680
data->noelements = noelements;
5681
data->noknots = noknots;
5682
5683
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
5684
AllocateKnots(data);
5685
5686
printf("Number of BC lines: %d\n",bclines);
5687
bcinds = Ivector(1,10*bclines);
5688
bctags = Ivector(1,10*bclines);
5689
for(i=1;i<=10*bclines;i++) bcinds[i] = bctags[i] = 0;
5690
5691
rewind(in);
5692
allocated = TRUE;
5693
goto omstart;
5694
}
5695
5696
printf("Number of different BCs: %d\n",bccount);
5697
printf("Number of BC nodes: %d\n",nbc);
5698
5699
NodesToBoundaryChain(data,bound,bcinds,bctags,nbc,bccount,info);
5700
5701
free_Ivector(bcinds,1,10*bclines);
5702
free_Ivector(bctags,1,10*bclines);
5703
5704
if(info) printf("Successfully read the mesh from the FVCOM file!\n");
5705
5706
return(0);
5707
}
5708
5709
5710
int LoadGeoInput(struct FemType *data,struct BoundaryType *bound,
5711
char *filename,int info)
5712
{
5713
int noknots = 0,noelements = 0,maxnodes,dim;
5714
int elemind[MAXNODESD2],elementtype;
5715
int i,j,k,allocated,*revindx=NULL,maxindx;
5716
int elemnodes,maxelemtype,elemtype0;
5717
int tagmat;
5718
FILE *in;
5719
char *cp,line[MAXLINESIZE];
5720
5721
5722
if ((in = fopen(filename,"r")) == NULL) {
5723
printf("LoadGeoInput: The opening of the mesh file %s failed!\n",filename);
5724
return(1);
5725
}
5726
if(info) printf("Loading mesh in geo format from file %s\n",filename);
5727
5728
allocated = FALSE;
5729
dim = 3;
5730
maxnodes = 0;
5731
maxindx = 0;
5732
maxelemtype = 0;
5733
5734
omstart:
5735
5736
5737
for(;;) {
5738
if(Getrow(line,in,FALSE)) goto end;
5739
if(line[0]=='\0') goto end;
5740
if(strstr(line,"$End")) continue;
5741
5742
if(strstr(line,"TYPES")) {
5743
if(!strstr(line,"ALL=TET04")) {
5744
printf("Only all tets implemented at the moment!\n");
5745
return(1);
5746
}
5747
elemtype0 = 504;
5748
GETLINE;
5749
}
5750
else if(strstr(line,"COORDINATES")) {
5751
i = 0;
5752
for(;;) {
5753
GETLINE;
5754
if( strstr(line,"END_COORDINATES")) break;
5755
cp = line;
5756
j = next_int(&cp);
5757
i = i + 1;
5758
if(allocated) {
5759
if(maxindx > noknots) revindx[j] = i;
5760
data->x[i] = next_real(&cp);
5761
data->y[i] = next_real(&cp);
5762
if(dim > 2) data->z[i] = next_real(&cp);
5763
}
5764
else {
5765
maxindx = MAX(j,maxindx);
5766
}
5767
}
5768
noknots = i;
5769
}
5770
else if(strstr(line,"ELEMENTS")) {
5771
i = 0;
5772
elementtype = elemtype0;
5773
tagmat = 1;
5774
5775
for(;;) {
5776
GETLINE;
5777
if( strstr(line,"END_ELEMENTS")) break;
5778
cp = line;
5779
j = next_int(&cp);
5780
i = i + 1;
5781
5782
if(allocated) {
5783
elemnodes = elementtype % 100;
5784
data->elementtypes[i] = elementtype;
5785
data->material[i] = tagmat;
5786
for(k=0;k<elemnodes;k++)
5787
elemind[k] = next_int(&cp);
5788
for(k=0;k<elemnodes;k++)
5789
data->topology[i][k] = elemind[k];
5790
}
5791
else {
5792
maxelemtype = MAX(maxelemtype,elementtype);
5793
}
5794
}
5795
noelements = i;
5796
}
5797
else if ( strstr(line,"BOUNDARIES")) {
5798
for(;;) {
5799
GETLINE;
5800
if( strstr(line,"END_BOUNDARIES")) break;
5801
5802
printf("Implement boundaries!\n");
5803
}
5804
}
5805
}
5806
5807
end:
5808
5809
5810
if(!allocated) {
5811
maxnodes = maxelemtype % 100;
5812
InitializeKnots(data);
5813
data->dim = dim;
5814
data->maxnodes = maxnodes;
5815
data->noelements = noelements;
5816
data->noknots = noknots;
5817
5818
if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
5819
AllocateKnots(data);
5820
5821
if(maxindx > noknots) {
5822
revindx = Ivector(1,maxindx);
5823
for(i=1;i<=maxindx;i++) revindx[i] = 0;
5824
}
5825
rewind(in);
5826
allocated = TRUE;
5827
goto omstart;
5828
}
5829
5830
if(maxindx > noknots) {
5831
printf("Renumbering the Geo nodes from %d to %d\n",maxindx,noknots);
5832
5833
for(i=1; i <= noelements; i++) {
5834
elementtype = data->elementtypes[i];
5835
elemnodes = elementtype % 100;
5836
5837
for(j=0;j<elemnodes;j++) {
5838
k = data->topology[i][j];
5839
if(k <= 0 || k > maxindx)
5840
printf("index out of bounds %d\n",k);
5841
else if(revindx[k] <= 0)
5842
printf("unknown node %d %d in element %d\n",k,revindx[k],i);
5843
else
5844
data->topology[i][j] = revindx[k];
5845
}
5846
}
5847
free_Ivector(revindx,1,maxindx);
5848
}
5849
5850
if(0) ElementsToBoundaryConditions(data,bound,FALSE,info);
5851
5852
if(info) printf("Successfully read the mesh from the Geo input file.\n");
5853
5854
return(0);
5855
}
5856
5857
5858
/* Mapping between the element type of Universal file format and
5859
ElmerSolver element type. */
5860
static int UnvToElmerType(int unvtype)
5861
{
5862
int elmertype;
5863
5864
switch (unvtype) {
5865
5866
case 11:
5867
case 21:
5868
elmertype = 202;
5869
break;
5870
5871
case 22:
5872
case 23:
5873
case 24:
5874
elmertype = 203;
5875
break;
5876
5877
case 41:
5878
case 51:
5879
case 61:
5880
case 74:
5881
case 81:
5882
case 91:
5883
elmertype = 303;
5884
break;
5885
5886
case 42:
5887
case 52:
5888
case 62:
5889
case 72:
5890
case 82:
5891
case 92:
5892
elmertype = 306;
5893
break;
5894
5895
case 43:
5896
case 53:
5897
case 63:
5898
case 73:
5899
case 93:
5900
elmertype = 310;
5901
break;
5902
5903
case 44:
5904
case 54:
5905
case 64:
5906
case 71:
5907
case 84:
5908
case 94:
5909
elmertype = 404;
5910
break;
5911
5912
case 45:
5913
case 46:
5914
case 56:
5915
case 66:
5916
case 76:
5917
case 96:
5918
elmertype = 408;
5919
break;
5920
5921
case 111:
5922
elmertype = 504;
5923
break;
5924
5925
case 118:
5926
elmertype = 510;
5927
break;
5928
5929
case 101:
5930
case 112:
5931
elmertype = 706;
5932
break;
5933
5934
case 102:
5935
case 113:
5936
elmertype = 715;
5937
break;
5938
5939
case 104:
5940
case 115:
5941
elmertype = 808;
5942
break;
5943
5944
case 105:
5945
case 116:
5946
elmertype = 820;
5947
break;
5948
5949
default:
5950
elmertype = 0;
5951
if(0) printf("Unknown elementtype in universal mesh format: %d\n",unvtype);
5952
}
5953
5954
return(elmertype);
5955
}
5956
5957
5958
/* The Universal format supports something as "degenerated" elements.
5959
This means that the same node is given multiple times in the element
5960
topology */
5961
static int UnvRedundantIndexes(int nonodes,int *ind)
5962
{
5963
int i,j,redundant;
5964
5965
redundant = FALSE;
5966
for(i=0;i<nonodes;i++) {
5967
if( ind[i] == 0 ) redundant = TRUE;
5968
for(j=i+1;j<nonodes;j++)
5969
if(ind[i] == ind[j]) redundant = TRUE;
5970
}
5971
if( redundant ) {
5972
printf("Redundant element %d: ",nonodes);
5973
for(i=0;i<nonodes;i++)
5974
printf(" %d ",ind[i]);
5975
printf("\n");
5976
}
5977
5978
return(redundant);
5979
}
5980
5981
5982
/* Mapping between the elemental node order of Universal file format to
5983
Elmer file format. */
5984
static void UnvToElmerIndx(int elemtype,int *topology)
5985
{
5986
int i=0,nodes=0,oldtopology[MAXNODESD2];
5987
int reorder, *porder;
5988
5989
int order203[]={1,3,2};
5990
int order306[]={1,3,5,2,4,6};
5991
int order510[]={1,3,5,10,2,4,6,7,8,9};
5992
int order408[]={1,3,5,7,2,4,6,8};
5993
int order820[]={1,3,5,7,13,15,17,19,2,4,6,8,9,10,11,12,14,16,18,20};
5994
5995
5996
reorder = FALSE;
5997
5998
switch (elemtype) {
5999
6000
case 203:
6001
reorder = TRUE;
6002
porder = &order203[0];
6003
break;
6004
6005
case 306:
6006
reorder = TRUE;
6007
porder = &order306[0];
6008
break;
6009
6010
case 510:
6011
reorder = TRUE;
6012
porder = &order510[0];
6013
break;
6014
6015
case 408:
6016
reorder = TRUE;
6017
porder = &order408[0];
6018
break;
6019
6020
case 820:
6021
reorder = TRUE;
6022
porder = &order820[0];
6023
break;
6024
6025
}
6026
6027
if( reorder ) {
6028
nodes = elemtype % 100;
6029
for(i=0;i<nodes;i++)
6030
oldtopology[i] = topology[i];
6031
for(i=0;i<nodes;i++)
6032
topology[i] = oldtopology[porder[i]-1];
6033
}
6034
}
6035
6036
6037
6038
6039
int LoadUniversalMesh(struct FemType *data,struct BoundaryType *bound,
6040
char *prefix,int info)
6041
/* Load the grid in universal file format. This format includes thousands of possible
6042
fields and hence the parser can never be exhaustive. Just the mostly common used
6043
fields in FE community are treated. */
6044
{
6045
int noknots,totknots,noelements,elemcode,maxnodes;
6046
int allocated,dim,ind,lines,groupset,goffset,poffset,noconf1,noconf2;
6047
int reordernodes,reorderelements,nogroups,maxnodeind,maxelem,elid,unvtype,elmertype;
6048
int nonodes,group,grouptype,mode,nopoints,nodeind,matind,physind,colorind;
6049
int minelemtype,maxelemtype,doscaling=FALSE;
6050
int debug,mingroup,maxgroup,minphys,maxphys,nogroup,noentities,dummy,isbeam;
6051
int *u2eind=NULL,*u2eelem=NULL;
6052
int *elementtypes,*physmap;
6053
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
6054
int i,j,k;
6055
char entityname[MAXNAMESIZE];
6056
Real scaling[4];
6057
FILE *in;
6058
6059
6060
strcpy(filename,prefix);
6061
if ((in = fopen(filename,"r")) == NULL) {
6062
AddExtension(prefix,filename,"unv");
6063
if ((in = fopen(filename,"r")) == NULL) {
6064
printf("LoadUniversalMesh: opening of the universal mesh file '%s' wasn't successful !\n",
6065
filename);
6066
return(1);
6067
}
6068
}
6069
6070
printf("Reading mesh from universal mesh file %s.\n",filename);
6071
InitializeKnots(data);
6072
6073
dim = 3;
6074
allocated = FALSE;
6075
reordernodes = FALSE;
6076
reorderelements = FALSE;
6077
6078
debug = FALSE;
6079
if( debug ){
6080
elementtypes = Ivector(0,820);
6081
for(i=0;i<=820;i++) elementtypes[i] = FALSE;
6082
}
6083
6084
maxnodeind = 0;
6085
maxnodes = 0;
6086
maxelem = 0;
6087
mingroup = INT_MAX;
6088
maxgroup = 0;
6089
minphys = INT_MAX;
6090
maxphys = 0;
6091
groupset = 0;
6092
goffset = 0;
6093
poffset = 0;
6094
noconf1 = 0;
6095
noconf2 = 0;
6096
6097
omstart:
6098
6099
/* this is a global variable in the module */
6100
linenumber = 0;
6101
6102
if(info) {
6103
if(allocated)
6104
printf("Second round for reading data\n");
6105
else
6106
printf("First round for allocating data\n");
6107
}
6108
6109
noknots = 0;
6110
noelements = 0;
6111
nogroups = 0;
6112
nopoints = 0;
6113
group = 0;
6114
mode = 0;
6115
6116
6117
for(;;) {
6118
6119
if(0) printf("line: %d %s\n",mode,line);
6120
6121
nextline:
6122
if( !strncmp(line," -1",6)) mode = 0;
6123
if( Getrow(line,in,FALSE)) {
6124
goto end;
6125
}
6126
if(line[0]=='\0') goto end;
6127
6128
if( !strncmp(line," -1",6)) mode = 0;
6129
else if( !strncmp(line," 2411",6)) mode = 2411;
6130
else if( !strncmp(line," 2412",6)) mode = 2412;
6131
else if( !strncmp(line," 2420",6)) mode = 2420;
6132
else if( !strncmp(line," 2467",6)) mode = 2467;
6133
else if( !strncmp(line," 2435",6)) mode = 2435;
6134
else if( !strncmp(line," 781",6)) mode = 781;
6135
else if( !strncmp(line," 780",6)) mode = 780;
6136
else if( !strncmp(line," 164",6)) mode = 164;
6137
else if( allocated && strncmp(line," ",6)) printf("Unknown mode line %d: %s",linenumber,line);
6138
6139
6140
if(debug && mode) printf("Current mode is %d\n",mode);
6141
6142
/* node definition */
6143
if( mode == 2411 || mode == 781 ) {
6144
if(allocated && info) printf("Reading node coordinates\n");
6145
for(;;) {
6146
GetrowDouble(line,in);
6147
if( !strncmp(line," -1",6)) {
6148
if(!allocated && info) printf("There are %d nodes in the mesh\n",noknots);
6149
goto nextline;
6150
}
6151
6152
cp = line;
6153
nodeind = next_int(&cp);
6154
/* Three other fields omitted: two coordinate systems and color */
6155
noknots += 1;
6156
GetrowDouble(line,in);
6157
6158
if(allocated) {
6159
if(reordernodes) {
6160
if(u2eind[nodeind])
6161
printf("Reordering node %d already set (%d vs. %d)\n",
6162
nodeind,u2eind[nodeind],noknots);
6163
else
6164
u2eind[nodeind] = noknots;
6165
}
6166
6167
cp = line;
6168
data->x[noknots] = next_real(&cp);
6169
data->y[noknots] = next_real(&cp);
6170
data->z[noknots] = next_real(&cp);
6171
}
6172
else {
6173
if(nodeind != noknots) reordernodes = TRUE;
6174
maxnodeind = MAX(maxnodeind,nodeind);
6175
}
6176
}
6177
}
6178
6179
if( mode == 2412 ) {
6180
minelemtype = INT_MAX;
6181
maxelemtype = 0;
6182
6183
if(allocated && info) printf("Reading element topologies\n");
6184
for(;;) {
6185
Getrow(line,in,FALSE);
6186
if( strstr(line,"-1")) {
6187
if(info && !allocated) printf("Element type range in mesh [%d,%d]\n",minelemtype,maxelemtype);
6188
goto nextline;
6189
}
6190
6191
noelements += 1;
6192
cp = line;
6193
elid = next_int(&cp);
6194
unvtype = next_int(&cp);
6195
physind = next_int(&cp);
6196
matind = next_int(&cp);
6197
colorind = next_int(&cp);
6198
nonodes = next_int(&cp);
6199
6200
if(!allocated ) {
6201
if(0) printf("elem = %d %d %d %d\n",noelements,unvtype,physind,matind);
6202
}
6203
6204
elmertype = UnvToElmerType(unvtype);
6205
if(!elmertype) {
6206
printf("Unknown elementtype %d %d %d %d %d %d %d\n",
6207
noelements,elid,unvtype,physind,matind,colorind,nonodes);
6208
printf("line %d: %s\n",linenumber,line);
6209
bigerror("done");
6210
}
6211
6212
if (!allocated) {
6213
minphys = MIN( minphys, physind );
6214
maxphys = MAX( maxphys, physind );
6215
maxnodes = MAX(maxnodes, nonodes);
6216
if(elid != noelements) reorderelements = TRUE;
6217
maxelem = MAX(maxelem, elid);
6218
}
6219
else {
6220
physind += poffset;
6221
}
6222
6223
/* For beam elements there is a stupid additional row filled with zeros? */
6224
isbeam = ( elmertype / 100 == 2);
6225
if(isbeam)Getrow(line,in,FALSE);
6226
6227
Getrow(line,in,FALSE);
6228
cp = line;
6229
6230
if(elmertype == 510 )
6231
lines = 1;
6232
else if(elmertype == 820 )
6233
lines = 2;
6234
else
6235
lines = 0;
6236
6237
if(allocated) {
6238
if(reorderelements) u2eelem[elid] = noelements;
6239
6240
if(debug && !elementtypes[elmertype]) {
6241
elementtypes[elmertype] = TRUE;
6242
printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
6243
}
6244
6245
if(elmertype % 100 != nonodes) {
6246
printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
6247
nonodes = elmertype % 100;
6248
}
6249
6250
data->elementtypes[noelements] = elmertype;
6251
for(i=0;i<nonodes;i++) {
6252
if( lines > 0 && i >= 8 ) {
6253
if( i%8 == 0 ) {
6254
Getrow(line,in,FALSE);
6255
cp = line;
6256
}
6257
}
6258
data->topology[noelements][i] = next_int(&cp);
6259
}
6260
6261
UnvRedundantIndexes(nonodes,data->topology[noelements]);
6262
6263
UnvToElmerIndx(elmertype,data->topology[noelements]);
6264
6265
/* should this be physical property or material property? */
6266
data->material[noelements] = physind;
6267
}
6268
else {
6269
minelemtype = MIN( minelemtype, elmertype );
6270
maxelemtype = MAX( maxelemtype, elmertype );
6271
for(i=1;i<=lines;i++) {
6272
Getrow(line,in,FALSE);
6273
}
6274
}
6275
}
6276
if(info) {
6277
printf("Element type range in whole mesh is [%d %d]\n",minelemtype,maxelemtype);
6278
}
6279
}
6280
6281
if( mode == 2420 ) {
6282
int partuid,coordlabel,coordtype;
6283
Real coeff;
6284
if(allocated && info) printf("Reading Coordinate system information\n");
6285
6286
Getrow(line,in,FALSE);
6287
if( !allocated ) {
6288
cp = line;
6289
partuid = next_int(&cp);
6290
printf("Part UID = %d\n",partuid);
6291
}
6292
Getrow(line,in,FALSE);
6293
if(!allocated ) {
6294
sscanf(line,"%s",entityname);
6295
printf("Part name = %s\n",entityname);
6296
}
6297
Getrow(line,in,FALSE);
6298
if( !allocated ) {
6299
cp = line;
6300
coordlabel = next_int(&cp);
6301
coordtype = next_int(&cp);
6302
if( coordtype != 0 ) {
6303
printf("Coordinate system is not cartesian: %d\n",coordtype);
6304
printf("Code some more if you want to consider this!\n");
6305
}
6306
}
6307
6308
Getrow(line,in,FALSE);
6309
if(!allocated ) {
6310
sscanf(line,"%s",entityname);
6311
printf("Coord system name = %s\n",entityname);
6312
}
6313
for(i=1;i<=4;i++) {
6314
Getrow(line,in,FALSE);
6315
if( !allocated ) {
6316
cp = line;
6317
if(!cp) printf("Problem reading line %d for coordinate system\n",i);
6318
for(j=1;j<= 3;j++) {
6319
coeff = next_real(&cp);
6320
if( i == j ) {
6321
scaling[i] = coeff;
6322
if( fabs(coeff) < 1.0e-20) {
6323
printf("Scaling for component %d too small %le\n",i,coeff);
6324
}
6325
else if( fabs(coeff-1.0) ) {
6326
doscaling = TRUE;
6327
printf("Scaling component %d by %le\n",i,coeff);
6328
}
6329
}
6330
else {
6331
if(fabs(coeff) > 1.0e-20 ) {
6332
printf("Transformation matrix is not diagonal %d%d: %e\n",i,j,coeff);
6333
smallerror("Code some more...");
6334
}
6335
}
6336
}
6337
}
6338
}
6339
Getrow(line,in,FALSE);
6340
if( strncmp(line," -1",6))
6341
printf("Field 2420 should already be ending: %s\n",line);
6342
goto nextline;
6343
}
6344
6345
if( mode == 780 ) {
6346
int physind2,matind2;
6347
maxelemtype = 0;
6348
minelemtype = 1000;
6349
6350
if(allocated && info) printf("Reading element groups in mode %d\n",mode);
6351
for(;;) {
6352
Getrow(line,in,FALSE);
6353
if( !strncmp(line," -1",6)) goto nextline;
6354
6355
noelements += 1;
6356
cp = line;
6357
elid = next_int(&cp);
6358
unvtype = next_int(&cp);
6359
6360
physind = next_int(&cp);
6361
physind2 = next_int(&cp);
6362
matind = next_int(&cp);
6363
matind2 = next_int(&cp);
6364
colorind = next_int(&cp);
6365
nonodes = next_int(&cp);
6366
6367
if (!allocated) {
6368
maxnodes = MAX(maxnodes, nonodes);
6369
if(elid != noelements) reorderelements = TRUE;
6370
maxelem = MAX(maxelem, elid);
6371
minphys = MIN( minphys, physind );
6372
maxphys = MAX( maxphys, physind );
6373
}
6374
else {
6375
physind += poffset;
6376
}
6377
6378
6379
if(unvtype == 11 || unvtype == 21) Getrow(line,in,FALSE);
6380
Getrow(line,in,FALSE);
6381
cp = line;
6382
if(allocated) {
6383
if(reorderelements) u2eelem[elid] = noelements;
6384
6385
elmertype = UnvToElmerType(unvtype);
6386
maxelemtype = MAX( maxelemtype, elmertype );
6387
minelemtype = MIN( minelemtype, elmertype );
6388
6389
if(debug && !elementtypes[elmertype]) {
6390
elementtypes[elmertype] = TRUE;
6391
printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
6392
}
6393
6394
if(elmertype % 100 != nonodes) {
6395
printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
6396
nonodes = elmertype % 100;
6397
}
6398
6399
data->elementtypes[noelements] = elmertype;
6400
for(i=0;i<nonodes;i++)
6401
data->topology[noelements][i] = next_int(&cp);
6402
6403
UnvRedundantIndexes(nonodes,data->topology[noelements]);
6404
6405
UnvToElmerIndx(elmertype,data->topology[noelements]);
6406
6407
/* should this be physical property or material property? */
6408
data->material[noelements] = physind;
6409
}
6410
}
6411
}
6412
6413
if( mode == 2467 || mode == 2435) {
6414
if(allocated && info) printf("Reading element groups in mode %d\n",mode);
6415
6416
for(;;) {
6417
Getrow(line,in,FALSE);
6418
if( !strncmp(line," -1",6)) goto nextline;
6419
6420
cp = line;
6421
nogroup = next_int(&cp);
6422
maxelemtype = 0;
6423
minelemtype = 1000;
6424
for(i=1;i<=6;i++)
6425
dummy = next_int(&cp);
6426
noentities = next_int(&cp);
6427
6428
if(!allocated) {
6429
mingroup = MIN( mingroup, nogroup );
6430
maxgroup = MAX( maxgroup, nogroup );
6431
}
6432
else {
6433
nogroup += goffset;
6434
}
6435
6436
Getrow(line,in,FALSE);
6437
if( !strncmp(line," -1",6)) goto nextline;
6438
6439
/* Used for the empty group created by salome */
6440
/* if( mode == 2467 && !strncmp(line," ",12)) continue; */
6441
6442
group++;
6443
k = 0;
6444
if(allocated) {
6445
sscanf(line,"%s",entityname);
6446
if(!data->bodyname[nogroup]) data->bodyname[nogroup] = Cvector(0,MAXNAMESIZE);
6447
strcpy(data->bodyname[nogroup],entityname);
6448
data->bodynamesexist = TRUE;
6449
if(0) data->boundarynamesexist = TRUE;
6450
6451
if(info) printf("Reading %d:th group with index %d with %d entities: %s\n",
6452
group,nogroup,noentities,entityname);
6453
}
6454
if(noentities == 0) Getrow(line,in,FALSE);
6455
6456
for(i=0;i<noentities;i++) {
6457
if(i%2 == 0) {
6458
Getrow(line,in,FALSE);
6459
if( !strncmp(line," -1",6)) goto nextline;
6460
cp = line;
6461
}
6462
6463
grouptype = next_int(&cp);
6464
ind = next_int(&cp);
6465
dummy = next_int(&cp);
6466
dummy = next_int(&cp);
6467
6468
if(ind == 0) continue;
6469
6470
if( grouptype == 8 ) {
6471
if(allocated) {
6472
if(reorderelements) ind = u2eelem[ind];
6473
elemcode = data->elementtypes[ind];
6474
maxelemtype = MAX( maxelemtype, elemcode );
6475
minelemtype = MIN( minelemtype, elemcode );
6476
6477
if(data->material[ind] < 0 ) {
6478
if(data->material[ind] == -nogroup)
6479
noconf1++;
6480
else
6481
noconf2++;
6482
}
6483
6484
data->material[ind] = -nogroup;
6485
groupset++;
6486
}
6487
}
6488
else if(grouptype == 7) {
6489
nopoints += 1;
6490
6491
if(allocated) {
6492
elemcode = 101;
6493
if(data->material[noelements+nopoints] < 0 ) {
6494
if(data->material[noelements+nopoints] == -nogroup)
6495
noconf1++;
6496
else
6497
noconf2++;
6498
}
6499
6500
data->material[noelements+nopoints] = -nogroup;
6501
maxelemtype = MAX( maxelemtype, elemcode );
6502
minelemtype = MIN( minelemtype, elemcode );
6503
data->elementtypes[noelements+nopoints] = elemcode;
6504
data->topology[noelements+nopoints][0] = ind;
6505
groupset++;
6506
}
6507
}
6508
else {
6509
printf("unknown group type %d\n",grouptype);
6510
}
6511
}
6512
if(allocated && info) {
6513
printf("Element type range in group is [%d %d]\n",minelemtype,maxelemtype);
6514
}
6515
6516
}
6517
}
6518
6519
if( mode == 164 ) {
6520
if(!allocated) printf("Units dataset content is currently omitted!\n");
6521
for(;;) {
6522
Getrow(line,in,FALSE);
6523
if( !strncmp(line," -1",6))
6524
goto nextline;
6525
}
6526
}
6527
6528
}
6529
6530
end:
6531
6532
exit;
6533
if(0) printf("Done reading mesh\n");
6534
6535
6536
if(!allocated) {
6537
6538
if(reordernodes) {
6539
if(info) printf("Reordering %d nodes with indexes up to %d\n",noknots,maxnodeind);
6540
u2eind = Ivector(1,maxnodeind);
6541
for(i=1;i<=maxnodeind;i++) u2eind[i] = 0;
6542
}
6543
if(reorderelements) {
6544
if(info) printf("Reordering %d elements with indexes up to %d\n",noelements,maxelem);
6545
u2eelem = Ivector(1,maxelem);
6546
for(i=1;i<=maxelem;i++) u2eelem[i] = 0;
6547
}
6548
6549
if(noknots == 0 || noelements == 0 || maxnodes == 0) {
6550
printf("Invalid mesh consists of %d nodes and %d %d-node elements.\n",
6551
noknots,noelements,maxnodes);
6552
fclose(in);
6553
return(2);
6554
}
6555
6556
rewind(in);
6557
totknots = noknots;
6558
data->noknots = noknots;
6559
data->noelements = noelements + nopoints;
6560
data->maxnodes = maxnodes;
6561
data->dim = dim;
6562
6563
if(info) {
6564
printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
6565
noknots,noelements,maxnodes,dim);
6566
}
6567
AllocateKnots(data);
6568
allocated = TRUE;
6569
6570
/* Set an offset for physical indexes so that the defined groups and
6571
existing physical indexes won't mix confusingly */
6572
if(info) {
6573
printf("Physical index interval is [%d,%d]\n",minphys,maxphys);
6574
if( maxgroup ) printf("Group index interval is [%d,%d]\n",mingroup,maxgroup);
6575
}
6576
if(!mingroup) {
6577
printf("Applying group offset to 1!\n");
6578
goffset = 1;
6579
mingroup += 1;
6580
maxgroup += 1;
6581
}
6582
if(!minphys) {
6583
printf("Applying physical entity offset to 1!\n");
6584
poffset = 1;
6585
minphys += 1;
6586
maxphys += 1;
6587
}
6588
6589
goto omstart;
6590
}
6591
fclose(in);
6592
6593
if(noconf1) printf("Group given multiple times with same group: %d\n",noconf1);
6594
if(noconf2) printf("Group given multiple times but with different group index: %d\n",noconf2);
6595
6596
/* Rorder materials if there is an overlap between groups and physical entities, or
6597
if numbering uses also zero. */
6598
if( groupset) {
6599
int i1,i2,k2,ioffset;
6600
6601
if(info) printf("Group given for %d elements out of %d\n",groupset,noelements);
6602
i1=MIN(minphys,mingroup);
6603
i2=MAX(maxphys,maxgroup);
6604
6605
/* Give plenty of room for new indexes */
6606
i2=2*i2;
6607
6608
physmap = Ivector(i1,i2);
6609
for(i=i1;i<=i2;i++) physmap[i] = 0;
6610
6611
/* Give priority to group (negative index) */
6612
for(i=1;i<=data->noelements;i++) {
6613
j = data->material[i];
6614
if(j<0) physmap[-j] = -1;
6615
}
6616
/* Now check the physical index */
6617
for(i=1;i<=data->noelements;i++) {
6618
j = data->material[i];
6619
if(j>0) {
6620
if(physmap[j]==0) physmap[j] = -2;
6621
if(physmap[j]==-1) {
6622
if(info) printf("Physical index and group index collide: %d\n",j);
6623
physmap[j] = -3;
6624
}
6625
}
6626
}
6627
6628
for(i=i1;i<=i2;i++) {
6629
/* For tag -3 we need to find new index */
6630
if(physmap[i]==-3) {
6631
/* Find a free index and tag it with -4 when it has been used */
6632
for(j=i1;j<=i2;j++)
6633
if(!physmap[j]) break;
6634
physmap[i] = j;
6635
physmap[j] = -4;
6636
if(info) printf("Replacing physical index %d with free index %d\n",i,j);
6637
/* We may have some remnants that we remove since physical entity is not named */
6638
if(data->bodyname[j]) {
6639
printf("Removing name of an empty group: %s\n",data->bodyname[j]);
6640
free_Cvector(data->bodyname[j],0,MAXNAMESIZE);
6641
data->bodyname[j] = NULL;
6642
}
6643
}
6644
}
6645
/* Finally do the renumbering */
6646
k = 0;
6647
k2 = 0;
6648
for(i=1;i<=data->noelements;i++) {
6649
j = data->material[i];
6650
if(j<0)
6651
data->material[i] = -j;
6652
else {
6653
if(physmap[j] > 0) {
6654
data->material[i] = physmap[j];
6655
k2++;
6656
}
6657
else k++;
6658
}
6659
}
6660
if(k) printf("Using original physical entity index for %d elements\n",k);
6661
if(k2) printf("Using mapped physical entity index for %d elements\n",k2);
6662
6663
for(i=i1;i<=i2;i++) physmap[i] = 0;
6664
for(i=1;i<=data->noelements;i++)
6665
physmap[data->material[i]] += 1;
6666
for(i=i1;i<=i2;i++) {
6667
j = physmap[i];
6668
if(j) {
6669
if(data->bodyname[i])
6670
printf("Entity %d (%s) count is %d\n",i,data->bodyname[i],j);
6671
else
6672
printf("Entity %d count is %d\n",i,j);
6673
}
6674
}
6675
free_Ivector(physmap,i1,i2);
6676
}
6677
6678
/* Elmer likes that node indexes are given so that no integers are missed.
6679
If this is not the case we need to do renumbering of nodes. */
6680
if(reordernodes) {
6681
printf("Reordering nodes continuously\n");
6682
for(j=1;j<=noelements;j++)
6683
for(i=0;i<data->elementtypes[j]%100;i++)
6684
data->topology[j][i] = u2eind[data->topology[j][i]];
6685
free_Ivector(u2eind,1,maxnodeind);
6686
}
6687
if(reorderelements) {
6688
free_Ivector(u2eelem,1,maxelem);
6689
}
6690
6691
/* Do scaling if requested */
6692
if( doscaling ) {
6693
Real *coord;
6694
for(j=1;j<=3;j++) {
6695
if( j == 1 )
6696
coord = data->x;
6697
else if( j == 2 )
6698
coord = data->y;
6699
else
6700
coord = data->z;
6701
6702
if( fabs(scaling[j]-1.0) >= 1.0e-20 ) {
6703
for(i=1;i<=noknots;i++)
6704
coord[i] *= scaling[j];
6705
}
6706
}
6707
}
6708
6709
/* This is here for debugging of the nodal order */
6710
if(FALSE) for(j=1;j<=noelements;j++) {
6711
int elemtype = data->elementtypes[j];
6712
printf("element = %d\n",j);
6713
for(i=0;elemtype%100;i++) {
6714
k = data->topology[j][i];
6715
printf("node i=%d %.3le %.3le %.3le\n",i,data->x[k],data->z[k],data->y[k]);
6716
}
6717
}
6718
6719
6720
/* Until this far all elements have been listed as bulk elements.
6721
Now separate the lower dimensional elements to be boundary elements. */
6722
ElementsToBoundaryConditions(data,bound,TRUE,info);
6723
6724
if(info) printf("The Universal mesh was loaded from file %s.\n",filename);
6725
6726
return(0);
6727
}
6728
6729
6730
6731
6732
6733
int LoadCGsimMesh(struct FemType *data,char *prefix,int info)
6734
/* Load the mesh from postprocessing format of CGsim */
6735
{
6736
int noknots,noelements,maxnodes,material,allocated,dim,debug,thismat,thisknots,thiselems;
6737
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
6738
int i,j,inds[MAXNODESD2],savedofs;
6739
Real dummyreal;
6740
FILE *in;
6741
6742
6743
strcpy(filename,prefix);
6744
if ((in = fopen(filename,"r")) == NULL) {
6745
AddExtension(prefix,filename,"plt");
6746
if ((in = fopen(filename,"r")) == NULL) {
6747
printf("LoadCGsimMesh: opening of the CGsim mesh file '%s' wasn't successful !\n",
6748
filename);
6749
return(1);
6750
}
6751
}
6752
6753
printf("Reading mesh from CGsim mesh file %s.\n",filename);
6754
InitializeKnots(data);
6755
6756
debug = FALSE;
6757
allocated = FALSE;
6758
savedofs = FALSE;
6759
6760
omstart:
6761
6762
maxnodes = 4;
6763
noknots = 0;
6764
noelements = 0;
6765
material = 0;
6766
dim = 2;
6767
thismat = 0;
6768
6769
6770
for(;;) {
6771
6772
if(Getrow(line,in,FALSE)) goto end;
6773
if(line[0]=='\0') goto end;
6774
6775
cp = strstr(line,"ZONE");
6776
if(!cp) continue;
6777
6778
thismat += 1;
6779
cp = strstr(line," N=");
6780
cp += 3;
6781
thisknots = next_int(&cp);
6782
6783
cp = strstr(line,",E=");
6784
cp += 3;
6785
thiselems = next_int(&cp);
6786
6787
if(debug) {
6788
printf("%s",line);
6789
printf("thismat = %d knots = %d elems = %d\n",thismat,thisknots,thiselems);
6790
}
6791
6792
for(i=1;i<=thisknots;i++) {
6793
GETLINE;
6794
6795
if(allocated) {
6796
cp = line;
6797
data->x[noknots+i] = next_real(&cp);
6798
data->y[noknots+i] = next_real(&cp);
6799
data->z[noknots+i] = 0.0;
6800
6801
if(savedofs == 1) {
6802
for(j=1;j<=4;j++)
6803
dummyreal = next_real(&cp);
6804
data->dofs[1][noknots+i] = next_real(&cp);
6805
}
6806
else if(savedofs == 5) {
6807
for(j=1;j<=5;j++)
6808
data->dofs[j][noknots+i] = next_real(&cp);
6809
}
6810
6811
}
6812
}
6813
6814
for(i=1;i<=thiselems;i++) {
6815
GETLINE;
6816
6817
if(allocated) {
6818
cp = line;
6819
for(j=0;j<4;j++)
6820
inds[j] = next_int(&cp);
6821
for(j=0;j<4;j++)
6822
data->topology[noelements+i][j] = inds[j]+noknots;
6823
if(inds[2] == inds[3])
6824
data->elementtypes[noelements+i] = 303;
6825
else
6826
data->elementtypes[noelements+i] = 404;
6827
data->material[noelements+i] = thismat;
6828
}
6829
}
6830
6831
noknots += thisknots;
6832
noelements += thiselems;
6833
}
6834
6835
end:
6836
6837
if(!allocated) {
6838
if(noknots == 0 || noelements == 0 || maxnodes == 0) {
6839
printf("Invalid mesh consists of %d knots and %d %d-node elements.\n",
6840
noknots,noelements,maxnodes);
6841
fclose(in);
6842
return(2);
6843
}
6844
6845
rewind(in);
6846
data->noknots = noknots;
6847
data->noelements = noelements;
6848
data->maxnodes = maxnodes;
6849
data->dim = dim;
6850
6851
6852
if(info) {
6853
printf("Allocating for %d knots and %d %d-node elements.\n",
6854
noknots,noelements,maxnodes);
6855
}
6856
AllocateKnots(data);
6857
6858
if(savedofs == 1) {
6859
CreateVariable(data,1,1,0.0,"Temperature",FALSE);
6860
}
6861
else if(savedofs == 5) {
6862
CreateVariable(data,1,1,0.0,"dTdX",FALSE);
6863
CreateVariable(data,2,1,0.0,"dTdY",FALSE);
6864
CreateVariable(data,3,1,0.0,"Qx",FALSE);
6865
CreateVariable(data,4,1,0.0,"Qy",FALSE);
6866
CreateVariable(data,5,1,0.0,"Temperature",FALSE);
6867
}
6868
6869
allocated = TRUE;
6870
goto omstart;
6871
}
6872
fclose(in);
6873
6874
if(info) printf("The CGsim mesh was loaded from file %s.\n\n",filename);
6875
return(0);
6876
}
6877
6878
6879
int FluxToElmerType(int nonodes, int dim) {
6880
int elmertype;
6881
6882
elmertype = 0;
6883
6884
if( dim == 2 ) {
6885
switch( nonodes ) {
6886
case 3:
6887
elmertype = 203;
6888
break;
6889
case 6:
6890
elmertype = 306;
6891
break;
6892
case 8:
6893
elmertype = 408;
6894
break;
6895
}
6896
}
6897
6898
if( !elmertype ) printf("FluxToElmerType could not deduce element type! (%d %d)\n",nonodes,dim);
6899
6900
return(elmertype);
6901
}
6902
6903
6904
6905
6906
6907
int LoadFluxMesh(struct FemType *data,struct BoundaryType *bound,
6908
char *prefix,int info)
6909
/* Load the mesh from format of Flux Cedrat in TRA format. */
6910
{
6911
int noknots,noelements,maxnodes,dim,elmertype;
6912
int nonodes,matind,noregions,mode;
6913
int debug;
6914
int *elementtypes;
6915
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
6916
int i,j,k;
6917
char entityname[MAXNAMESIZE];
6918
FILE *in;
6919
6920
6921
strcpy(filename,prefix);
6922
if ((in = fopen(filename,"r")) == NULL) {
6923
AddExtension(prefix,filename,"TRA");
6924
if ((in = fopen(filename,"r")) == NULL) {
6925
printf("LoadFluxMesh: opening of the Flux mesh file '%s' wasn't successful !\n",
6926
filename);
6927
return(1);
6928
}
6929
}
6930
6931
printf("Reading 2D mesh from Flux mesh file %s.\n",filename);
6932
InitializeKnots(data);
6933
6934
debug = FALSE;
6935
linenumber = 0;
6936
dim = 2;
6937
noknots = 0;
6938
noelements = 0;
6939
mode = 0;
6940
maxnodes = 8;
6941
6942
6943
6944
for(;;) {
6945
6946
if(0) printf("line: %d %s\n",mode,line);
6947
6948
if( Getrow(line,in,FALSE)) goto end;
6949
if(line[0]=='\0') goto end;
6950
6951
if( strstr(line,"Number of nodes")) mode = 1;
6952
else if( strstr(line,"Total number of elements")) mode = 2;
6953
else if( strstr(line,"Total number of regions")) mode = 3;
6954
6955
else if( strstr(line,"Description of elements")) mode = 10;
6956
else if( strstr(line,"Coordinates of the nodes")) mode = 11;
6957
else if( strstr(line,"Names of the regions")) mode = 12;
6958
6959
else if( strstr(line,"Neighbouring element table")) mode = 13;
6960
else if( strstr(line,"List of boundary nodes")) mode = 14;
6961
else if( strstr(line,"Physical properties")) mode = 15;
6962
else if( strstr(line,"Boundary conditions")) mode = 16;
6963
else {
6964
if(debug) printf("Unknown mode line %d: %s",linenumber,line);
6965
mode = 0;
6966
}
6967
6968
if(debug && mode) printf("Current mode is %d\n",mode);
6969
6970
switch( mode ) {
6971
case 1:
6972
noknots = atoi(line);
6973
break;
6974
6975
case 2:
6976
noelements = atoi(line);
6977
break;
6978
6979
case 3:
6980
noregions = atoi(line);
6981
break;
6982
6983
6984
case 10:
6985
if(info) {
6986
printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
6987
noknots,noelements,maxnodes,dim);
6988
}
6989
6990
data->noknots = noknots;
6991
data->noelements = noelements;
6992
data->maxnodes = maxnodes;
6993
data->dim = dim;
6994
AllocateKnots(data);
6995
6996
if(info) printf("Reading %d element topologies\n",noelements);
6997
for(i=1;i<=noelements;i++) {
6998
Getrow(line,in,FALSE);
6999
cp = line;
7000
j = next_int(&cp);
7001
if( i != j ) {
7002
printf("It seems that reordering of elements should be performed! (%d %d)\n",i,j);
7003
}
7004
nonodes = next_int(&cp);
7005
matind = abs( next_int(&cp) );
7006
7007
elmertype = FluxToElmerType( nonodes, dim );
7008
data->elementtypes[i] = elmertype;
7009
data->material[i] = matind;
7010
7011
Getrow(line,in,FALSE);
7012
cp = line;
7013
for(k=0;k<nonodes;k++) {
7014
data->topology[i][k] = next_int(&cp);
7015
}
7016
}
7017
break;
7018
7019
case 11:
7020
if(info) printf("Reading %d element nodes\n",noknots);
7021
for(i=1;i<=noknots;i++) {
7022
Getrow(line,in,FALSE);
7023
cp = line;
7024
j = next_int(&cp);
7025
if( i != j ) {
7026
printf("It seems that reordering of nodes should be performed! (%d %d)\n",i,j);
7027
}
7028
data->x[i] = next_real(&cp);
7029
data->y[i] = next_real(&cp);
7030
if(dim == 3) data->z[i] = next_real(&cp);
7031
}
7032
break;
7033
7034
7035
case 12:
7036
if(info) printf("Reading %d names of regions\n",noregions);
7037
for(i=1;i<=noregions;i++) {
7038
Getrow(line,in,FALSE);
7039
cp = line;
7040
j = next_int(&cp);
7041
if( i != j ) {
7042
printf("It seems that reordering of regions should be performed! (%d %d)\n",i,j);
7043
}
7044
sscanf(cp,"%s",entityname);
7045
if(!data->bodyname[i]) data->bodyname[i] = Cvector(0,MAXNAMESIZE);
7046
strcpy(data->bodyname[i],entityname);
7047
}
7048
data->bodynamesexist = TRUE;
7049
data->boundarynamesexist = TRUE;
7050
break;
7051
7052
7053
default:
7054
if(debug) printf("unimplemented mode: %d\n",mode );
7055
mode = 0;
7056
break;
7057
}
7058
}
7059
7060
end:
7061
fclose(in);
7062
7063
/* Until this far all elements have been listed as bulk elements.
7064
Now separate the lower dimensional elements to be boundary elements. */
7065
ElementsToBoundaryConditions(data,bound,TRUE,info);
7066
7067
if(info) printf("The Flux mesh was loaded from file %s.\n\n",filename);
7068
7069
return(0);
7070
}
7071
7072
7073
7074
/* Mapping between the elemental node order of PF3 file format to
7075
Elmer file format. */
7076
static void PF3ToElmerPermuteNodes(int elemtype,int *topology)
7077
{
7078
int i=0, nodes=0, oldtopology[MAXNODESD2];
7079
int reorder, *porder;
7080
int debug;
7081
7082
int order303[] = {3,1,2}; //tri
7083
int order306[] = {3,1,2,6,4,5}; //tri^2
7084
int order404[] = {3,4,1,2}; //quad
7085
int order408[] = {3,4,1,2,7,8,5,6}; //quad^2
7086
int order504[] = {1,2,3,4}; //tetra
7087
int order510[] = {1,2,3,4,5,8,6,7,10,9};//tetra^2
7088
int order605[] = {3,2,1,4,5}; //pyramid
7089
int order613[] = {3,2,1,4,5,7,6,9,8,12,11,10,13}; //pyramid^2
7090
int order706[] = {6,4,5,3,1,2}; //wedge (prism)
7091
int order715[] = {6,4,5,3,1,2,12,10,11,9,7,8,15,13,14}; //wedge^2 (prism^2)
7092
int order808[] = {7,8,5,6,3,4,1,2}; //hexa
7093
int order820[] = {7,8,5,6,3,4,1,2,15,16,13,14,19,20,17,18,11,12,9,10}; //hexa^2
7094
7095
debug = TRUE;
7096
7097
reorder = FALSE;
7098
7099
switch (elemtype) {
7100
7101
case 101:
7102
//nothing to change here
7103
break;
7104
7105
case 202:
7106
//nothing to change here
7107
break;
7108
7109
case 203:
7110
//nothing to change here
7111
break;
7112
7113
case 303:
7114
reorder = TRUE;
7115
porder = &order303[0];
7116
break;
7117
7118
case 306:
7119
reorder = TRUE;
7120
porder = &order306[0];
7121
break;
7122
7123
case 404:
7124
reorder = TRUE;
7125
porder = &order404[0];
7126
break;
7127
7128
case 408:
7129
reorder = TRUE;
7130
porder = &order408[0];
7131
break;
7132
7133
case 504:
7134
reorder = TRUE;
7135
porder = &order504[0];
7136
break;
7137
7138
case 510:
7139
reorder = TRUE;
7140
porder = &order510[0];
7141
break;
7142
7143
case 605:
7144
reorder = TRUE;
7145
porder = &order605[0];
7146
break;
7147
7148
case 613:
7149
reorder = TRUE;
7150
porder = &order613[0];
7151
break;
7152
7153
case 706:
7154
reorder = TRUE;
7155
porder = &order706[0];
7156
break;
7157
7158
case 715:
7159
reorder = TRUE;
7160
porder = &order715[0];
7161
break;
7162
7163
case 808:
7164
reorder = TRUE;
7165
porder = &order808[0];
7166
break;
7167
7168
case 820:
7169
reorder = TRUE;
7170
porder = &order820[0];
7171
break;
7172
7173
default:
7174
if(debug) printf("Warning : Unknown element type: %d\n",elemtype );
7175
break;
7176
}
7177
7178
if( reorder ) {
7179
nodes = elemtype % 100;
7180
for(i=0;i<nodes;i++)
7181
oldtopology[i] = topology[i];
7182
for(i=0;i<nodes;i++)
7183
topology[i] = oldtopology[porder[i]-1];
7184
}
7185
}
7186
7187
7188
int FluxToElmerType3D(int nonodes, int dim) {
7189
int elmertype;
7190
7191
elmertype = 0;
7192
7193
if( dim == 2 ) {
7194
switch( nonodes ) {
7195
case 3:
7196
elmertype = 303;
7197
break;
7198
case 4:
7199
elmertype = 404;
7200
break;
7201
case 6:
7202
elmertype = 306;
7203
break;
7204
case 8:
7205
elmertype = 408;
7206
break;
7207
}
7208
}
7209
7210
if( dim == 3 ) {
7211
switch( nonodes ) {
7212
case 4:
7213
elmertype = 504;
7214
break;
7215
case 5:
7216
elmertype = 605;
7217
break;
7218
case 6:
7219
elmertype = 706;
7220
break;
7221
case 8:
7222
elmertype = 808;
7223
break;
7224
case 10:
7225
elmertype = 510;
7226
break;
7227
case 13:
7228
elmertype = 613;
7229
break;
7230
case 15:
7231
elmertype = 715;
7232
break;
7233
case 20:
7234
elmertype = 820;
7235
break;
7236
}
7237
}
7238
7239
if( !elmertype ) printf("FluxToElmerType3D could not deduce element type! (%d %d)\n",nonodes,dim);
7240
7241
return(elmertype);
7242
}
7243
7244
7245
int LoadFluxMesh3D(struct FemType *data,struct BoundaryType *bound,
7246
char *prefix,int info)
7247
/* Load the mesh from format of Flux Cedrat in PF3 format. */
7248
{
7249
int noknots,noelements,maxnodes,dim,elmertype;
7250
int nonodes,matind,noregions,mode;
7251
int dimplusone, maxlinenodes, nodecnt;
7252
int debug;
7253
int *elementtypes;
7254
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
7255
int i,j,k;
7256
char entityname[MAXNAMESIZE];
7257
FILE *in;
7258
7259
strcpy(filename,prefix);
7260
if ((in = fopen(filename,"r")) == NULL) {
7261
AddExtension(prefix,filename,"PF3");
7262
if ((in = fopen(filename,"r")) == NULL) {
7263
printf("LoadFluxMesh3D: opening of the Flux mesh file '%s' wasn't successful !\n",
7264
filename);
7265
return(1);
7266
}
7267
}
7268
7269
printf("Reading 3D mesh from Flux mesh file %s.\n",filename);
7270
InitializeKnots(data);
7271
7272
debug = FALSE;
7273
linenumber = 0;
7274
dim = 3;
7275
noknots = 0;
7276
noelements = 0;
7277
mode = 0;
7278
maxnodes = 20; // 15?
7279
maxlinenodes = 12; //nodes can be located at several lines
7280
7281
for(;;) {
7282
7283
if(0) printf("line: %d %s\n",mode,line);
7284
7285
if( Getrow(line,in,FALSE)) goto end;
7286
if(line[0]=='\0') goto end;
7287
if( strstr(line,"==== DECOUPAGE TERMINE")) goto end;
7288
7289
if( strstr(line,"NOMBRE DE DIMENSIONS DU DECOUPAGE")) mode = 1;
7290
else if( strstr(line,"NOMBRE D'ELEMENTS")) mode = 3;
7291
else if( strstr(line,"NOMBRE DE POINTS")) mode = 2;
7292
else if( strstr(line,"NOMBRE DE REGIONS")) mode = 4;
7293
7294
else if( strstr(line,"DESCRIPTEUR DE TOPOLOGIE DES ELEMENTS")) mode = 10;
7295
else if( strstr(line,"COORDONNEES DES NOEUDS")) mode = 11;
7296
else if( strstr(line,"NOMS DES REGIONS")) mode = 12;
7297
else {
7298
if(debug) printf("Unknown mode line %d: %s",linenumber,line);
7299
mode = 0;
7300
}
7301
7302
if(debug && mode) printf("Current mode is %d\n",mode);
7303
7304
switch( mode ) {
7305
case 1:
7306
dim = atoi(line);
7307
break;
7308
7309
case 2:
7310
if( strstr(line,"NOMBRE DE POINTS D'INTEGRATION")) break;/* We are looking for the total number of nodes */
7311
noknots = atoi(line);
7312
break;
7313
7314
case 3:
7315
i = atoi(line);
7316
noelements = MAX(i,noelements); /* We are looking for the total number of elements */
7317
break;
7318
7319
case 4:
7320
i = atoi(line);
7321
noregions = MAX(i,noregions); /* We are looking for the total number of regions */
7322
break;
7323
7324
7325
case 10:
7326
if(info) {
7327
printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
7328
noknots,noelements,maxnodes,dim);
7329
}
7330
7331
data->noknots = noknots;
7332
data->noelements = noelements;
7333
data->maxnodes = maxnodes;
7334
data->dim = dim;
7335
AllocateKnots(data);
7336
7337
if(info) printf("Reading %d element topologies\n",noelements);
7338
for(i=1;i<=noelements;i++)
7339
{
7340
Getrow(line,in,FALSE);
7341
cp = line;
7342
j = next_int(&cp);
7343
if( i != j ) {
7344
printf("It seems that reordering of elements should be performed! (%d %d)\n",i,j);
7345
}
7346
next_int(&cp); //2 internal element type description
7347
next_int(&cp); //3 internal element type description
7348
matind = next_int(&cp); //4 number of the belonging region
7349
dimplusone = next_int(&cp); //5 dimensionality 4-3D 3-2D
7350
next_int(&cp); //6 zero here always
7351
next_int(&cp); //7 internal element type description
7352
nonodes = next_int(&cp); //8 number of nodes
7353
7354
elmertype = FluxToElmerType3D( nonodes, dimplusone-1 );
7355
data->elementtypes[i] = elmertype;
7356
data->material[i] = matind;
7357
7358
Getrow(line,in,FALSE);
7359
cp = line;
7360
nodecnt = 0;
7361
for(k=0;k<nonodes;k++) {
7362
7363
if(nodecnt >= maxlinenodes) {
7364
nodecnt = 0;
7365
Getrow(line,in,FALSE);
7366
cp = line;
7367
}
7368
data->topology[i][k] = next_int(&cp);
7369
nodecnt+=1;
7370
}
7371
7372
PF3ToElmerPermuteNodes(elmertype,data->topology[noelements]);
7373
7374
}
7375
break;
7376
7377
case 11:
7378
if(info) printf("Reading %d element nodes\n",noknots);
7379
for(i=1;i<=noknots;i++) {
7380
Getrow(line,in,FALSE);
7381
cp = line;
7382
j = next_int(&cp);
7383
if( i != j ) {
7384
printf("It seems that reordering of nodes should be performed! (%d %d)\n",i,j);
7385
}
7386
data->x[i] = next_real(&cp);
7387
data->y[i] = next_real(&cp);
7388
data->z[i] = next_real(&cp);
7389
}
7390
break;
7391
7392
7393
case 12:
7394
if(info) printf("Reading %d names of regions\n",noregions);
7395
for(i=1;i<=noregions;i++) {
7396
Getrow(line,in,FALSE);
7397
7398
/* currently we just cycle through this and get a new row */
7399
if( strstr(line,"REGIONS SURFACIQUES")) Getrow(line,in,FALSE);
7400
if( strstr(line,"REGIONS VOLUMIQUES")) Getrow(line,in,FALSE);
7401
7402
sscanf(line,"%s",entityname);
7403
if(!data->bodyname[i]) data->bodyname[i] = Cvector(0,MAXNAMESIZE);
7404
strcpy(data->bodyname[i],entityname);
7405
}
7406
data->bodynamesexist = TRUE;
7407
data->boundarynamesexist = TRUE;
7408
break;
7409
7410
7411
default:
7412
if(debug) printf("unimplemented mode: %d\n",mode );
7413
mode = 0;
7414
break;
7415
}
7416
}
7417
7418
end:
7419
fclose(in);
7420
7421
/* Until this far all elements have been listed as bulk elements.
7422
Now separate the lower dimensional elements to be boundary elements. */
7423
ElementsToBoundaryConditions(data,bound,TRUE,info);
7424
7425
if(info) printf("The Flux 3D mesh was loaded from file %s.\n\n",filename);
7426
7427
return(0);
7428
}
7429
7430