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