EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
egconvert.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file egconvert.cpp
1 /*
2  ElmerGrid - A simple mesh generation and manipulation utility
3  Copyright (C) 1995- , CSC - IT Center for Science Ltd.
4 
5  Author: Peter Råback
6  Email: Peter.Raback@csc.fi
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 
35 #include "egutils.h"
36 #include "egdef.h"
37 #include "egtypes.h"
38 #include "egmesh.h"
39 #include "egnative.h"
40 #include "egconvert.h"
41 
42 #define getline fgets(line,MAXLINESIZE,in)
43 
44 
45 static int Getrow(char *line1,FILE *io,int upper)
46 {
47  int i,isend;
48  char line0[MAXLINESIZE],*charend;
49 
50  for(i=0;i<MAXLINESIZE;i++)
51  line0[i] = ' ';
52 
53  newline:
54 
55  charend = fgets(line0,MAXLINESIZE,io);
56  isend = (charend == NULL);
57 
58  if(isend) return(1);
59 
60  if(line0[0] == '#' || line0[0] == '!') goto newline;
61  if(strstr(line0,"#")) goto newline;
62 
63  if(upper) {
64  for(i=0;i<MAXLINESIZE;i++)
65  line1[i] = toupper(line0[i]);
66  }
67  else {
68  for(i=0;i<MAXLINESIZE;i++)
69  line1[i] = line0[i];
70  }
71 
72  return(0);
73 }
74 
75 
76 
77 
78 static int GetrowDouble(char *line1,FILE *io)
79 {
80  int i,isend;
81  char line0[MAXLINESIZE],*charend;
82 
83  for(i=0;i<MAXLINESIZE;i++)
84  line0[i] = ' ';
85 
86  newline:
87 
88  charend = fgets(line0,MAXLINESIZE,io);
89  isend = (charend == NULL);
90 
91  if(isend) return(1);
92 
93  if(line0[0] == '#' || line0[0] == '!') goto newline;
94  if(strstr(line0,"#")) goto newline;
95 
96  for(i=0;i<MAXLINESIZE;i++) {
97 
98  /* The fortran double is not recognized by C string operators */
99  if( line0[i] == 'd' || line0[i] == 'D' ) {
100  line1[i] = 'e';
101  } else {
102  line1[i] = line0[i];
103  }
104  }
105 
106  return(0);
107 }
108 
109 
110 static int Comsolrow(char *line1,FILE *io)
111 {
112  int i,isend;
113  char line0[MAXLINESIZE],*charend;
114 
115  for(i=0;i<MAXLINESIZE;i++)
116  line0[i] = ' ';
117 
118  charend = fgets(line0,MAXLINESIZE,io);
119  isend = (charend == NULL);
120 
121  if(isend) return(1);
122 
123  for(i=0;i<MAXLINESIZE;i++) line1[i] = line0[i];
124 
125  return(0);
126 }
127 
128 
129 
130 static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
131  int boundarynodes,int *nodeindx,int *boundindx,int info)
132 {
133  int i,j,k,sideelemtype,elemind,*indx;
134  int boundarytype,minboundary,maxboundary,minnode,maxnode,sideelem,elemtype;
135  int sideind[MAXNODESD1],elemsides,side,sidenodes,hit,nohits;
136  int *elemhits;
137 
138  info = TRUE;
139 
140  sideelem = 0;
141  maxboundary = minboundary = boundindx[1];
142  minnode = maxnode = nodeindx[1];
143 
144  for(i=1;i<=boundarynodes;i++) {
145  if(maxboundary < boundindx[i]) maxboundary = boundindx[i];
146  if(minboundary > boundindx[i]) minboundary = boundindx[i];
147  if(maxnode < nodeindx[i]) maxnode = nodeindx[i];
148  if(minnode > nodeindx[i]) minnode = nodeindx[i];
149  }
150 
151  if(info) {
152  printf("Boundary types are in interval [%d, %d]\n",minboundary,maxboundary);
153  printf("Boundary nodes are in interval [%d, %d]\n",minnode,maxnode);
154  }
155  indx = Ivector(1,data->noknots);
156 
157  elemhits = Ivector(1,data->noknots);
158  for(i=1;i<=data->noknots;i++) elemhits[i] = 0;
159 
160  for(elemind=1;elemind<=data->noelements;elemind++) {
161  elemtype = data->elementtypes[elemind];
162  elemsides = elemtype % 100;
163 
164  for(i=0;i<elemsides;i++) {
165  elemhits[data->topology[elemind][i]] += 1;
166  }
167  }
168 
169 
170  for(boundarytype=minboundary;boundarytype <= maxboundary;boundarytype++) {
171  int boundfirst,bchits,bcsame,sideelemtype2;
172  int sideind2[MAXNODESD1];
173 
174  boundfirst = 0;
175 
176  for(i=1;i<=data->noknots;i++)
177  indx[i] = 0;
178 
179  for(i=1;i<=boundarynodes;i++) {
180  if(boundindx[i] == boundarytype)
181  indx[nodeindx[i]] = TRUE;
182  }
183 
184 
185  for(elemind=1;elemind<=data->noelements;elemind++) {
186  elemtype = data->elementtypes[elemind];
187  elemsides = elemtype / 100;
188  if(elemsides == 8) elemsides = 6;
189  else if(elemsides == 5) elemsides = 4;
190  else if(elemsides == 6) elemsides = 5;
191 
192  if(0) printf("ind=%d type=%d sides=%d\n",elemind,elemtype,elemsides);
193 
194  /* Check whether the bc nodes occupy every node in the selected side */
195  for(side=0;side<elemsides;side++) {
196  GetElementSide(elemind,side,1,data,&sideind[0],&sideelemtype);
197  sidenodes = sideelemtype%100;
198 
199  if(0) printf("sidenodes=%d side=%d\n",sidenodes,side);
200 
201  hit = TRUE;
202  nohits = 0;
203  for(i=0;i<sidenodes;i++) {
204  if(sideind[i] <= 0) {
205  if(0) printf("sideind[%d] = %d\n",i,sideind[i]);
206  hit = FALSE;
207  }
208  else if(sideind[i] > data->noknots) {
209  if(0) printf("sideind[%d] = %d (noknots=%d)\n",i,sideind[i],data->noknots);
210  hit = FALSE;
211  }
212  else if(!indx[sideind[i]]) {
213  hit = FALSE;
214  }
215  else {
216  nohits++;
217  }
218  }
219 
220 
221  if(hit == TRUE) {
222 
223  /* If all the points belong to more than one element there may be
224  another parent for the side element */
225  bcsame = FALSE;
226  bchits = TRUE;
227  for(i=0;i<sidenodes;i++)
228  if(elemhits[sideind[i]] < 2) bchits = FALSE;
229 
230  if(bchits && boundfirst) {
231  for(j=boundfirst;j<=sideelem;j++) {
232  if(bound->parent2[j]) continue;
233  GetElementSide(bound->parent[j],bound->side[j],1,data,&sideind2[0],&sideelemtype2);
234  if(sideelemtype != sideelemtype2) continue;
235  bcsame = 0;
236  for(i=0;i<sidenodes;i++)
237  for(k=0;k<sidenodes;k++)
238  if(sideind[i] == sideind2[k]) bcsame++;
239 
240  if(bcsame == sidenodes) {
241  if(data->material[bound->parent[j]] > data->material[elemind]) {
242  bound->parent2[j] = bound->parent[j];
243  bound->side2[j] = bound->side[j];
244  bound->parent[j] = elemind;
245  bound->side[j] = side;
246  }
247  else {
248  bound->parent2[j] = elemind;
249  bound->side2[j] = side;
250  }
251  goto bcset;
252  }
253  }
254  }
255 
256  sideelem += 1;
257  bound->parent[sideelem] = elemind;
258  bound->side[sideelem] = side;
259  bound->parent2[sideelem] = 0;
260  bound->side2[sideelem] = 0;
261  bound->types[sideelem] = boundarytype;
262 
263  if(!boundfirst) boundfirst = sideelem;
264 
265  bcset:
266  continue;
267  }
268  }
269  }
270  }
271 
272 
273  free_Ivector(indx,1,data->noknots);
274 
275  if(info) printf("Found %d side elements formed by %d points.\n",
276  sideelem,boundarynodes);
277 
278  bound->nosides = sideelem;
279 
280  return;
281 }
282 
283 
284 
285 
286 int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
287  char *prefix,int info)
288 /* Load the grid from a format that can be read by ABAQUS
289  program designed for sructural mechanics. The commands
290  understood are only those that IDEAS creates when saving
291  results in ABAQUS format.
292  */
293 {
294  int noknots,noelements,elemcode,maxnodes,material;
295  int mode,allocated,nvalue,nvalue2,maxknot,nosides;
296  int boundarytype,boundarynodes,elsetactive;
297  int *nodeindx = NULL,*boundindx = NULL;
298 
299  char filename[MAXFILESIZE];
300  char line[MAXLINESIZE];
301  int i,j,*ind = NULL;
302  FILE *in;
303  Real rvalues[MAXDOFS];
304  int ivalues[MAXDOFS],ivalues0[MAXDOFS];
305 
306 
307  strcpy(filename,prefix);
308  if ((in = fopen(filename,"r")) == NULL) {
309  AddExtension(prefix,filename,"inp");
310  if ((in = fopen(filename,"r")) == NULL) {
311  printf("LoadAbaqusInput: opening of the ABAQUS-file '%s' wasn't succesfull !\n",
312  filename);
313  return(1);
314  }
315  }
316 
317  printf("Reading input from ABAQUS input file %s.\n",filename);
318  InitializeKnots(data);
319 
320  allocated = FALSE;
321  maxknot = 0;
322  elsetactive = FALSE;
323 
324  /* Because the file format doesn't provide the number of elements
325  or nodes the results are read twice but registered only in the
326  second time. */
327 
328 omstart:
329 
330  mode = 0;
331  maxnodes = 0;
332  noknots = 0;
333  noelements = 0;
334  elemcode = 0;
335  boundarytype = 0;
336  boundarynodes = 0;
337  material = 0;
338  ivalues0[0] = ivalues0[1] = 0;
339 
340 
341  for(;;) {
342  /* getline; */
343 
344  if (Getrow(line,in,TRUE)) goto end;
345 
346  /* if(!line) goto end; */
347  /* if(strstr(line,"END")) goto end; */
348 
349  if(strstr(line,"**")) {
350  if(info && !allocated) printf("comment: %s",line);
351  }
352  else if(strrchr(line,'*')) {
353  if(strstr(line,"HEAD")) {
354  mode = 1;
355  }
356  else if(strstr(line,"NODE")) {
357  if(strstr(line,"SYSTEM=R")) data->coordsystem = COORD_CART2;
358  if(strstr(line,"SYSTEM=C")) data->coordsystem = COORD_AXIS;
359  if(strstr(line,"SYSTEM=P")) data->coordsystem = COORD_POLAR;
360  mode = 2;
361  }
362  else if(strstr(line,"ELEMENT")) {
363  if(!elsetactive) material++;
364  if(strstr(line,"S3R") || strstr(line,"STRI3"))
365  elemcode = 303;
366  else if(strstr(line,"2D4") || strstr(line,"SP4") || strstr(line,"AX4")
367  || strstr(line,"S4") || strstr(line,"CPE4"))
368  elemcode = 404;
369  else if(strstr(line,"2D8") || strstr(line,"AX8"))
370  elemcode = 408;
371  else if(strstr(line,"3D4"))
372  elemcode = 504;
373  else if(strstr(line,"3D5"))
374  elemcode = 605;
375  else if(strstr(line,"3D6"))
376  elemcode = 706;
377  else if(strstr(line,"3D8"))
378  elemcode = 808;
379  else if(strstr(line,"3D20"))
380  elemcode = 820;
381  else
382  printf("Unknown element code: %s\n",line);
383 
384  if(maxnodes < elemcode%100) maxnodes = elemcode%100;
385  mode = 3;
386  if(1) printf("Loading elements of type %d starting from element %d.\n",
387  elemcode,noelements);
388  }
389  else if(strstr(line,"BOUNDARY") || strstr(line,"CLOAD")) {
390  boundarytype++;
391  mode = 4;
392  }
393  else if(strstr(line,"NSET")) {
394  boundarytype++;
395  mode = 5;
396  }
397  else if(strstr(line,"ELSET")) {
398  elsetactive = TRUE;
399  material += 1;
400  mode = 6;
401  }
402  else {
403  if(!allocated) printf("unknown command: %s",line);
404  mode = 0;
405  }
406  }
407 
408  else if(mode) {
409  switch (mode) {
410 
411  case 1:
412  if(info) printf("Loading Abacus input file:\n%s",line);
413  break;
414 
415  case 2:
416  nvalue = StringToReal(line,rvalues,MAXNODESD2+1,',');
417  i = (int)(rvalues[0]+0.5);
418  if(i == 0) continue;
419  noknots++;
420  if(allocated) {
421  ind[i] = noknots;
422  data->x[noknots] = rvalues[1];
423  data->y[noknots] = rvalues[2];
424  data->z[noknots] = rvalues[3];
425  }
426  else {
427  if(maxknot < i) maxknot = i;
428  }
429  break;
430 
431  case 3:
432  noelements++;
433 
434  nvalue = StringToInteger(line,ivalues,MAXNODESD2+1,',');
435 
436  if(allocated) {
437  data->elementtypes[noelements] = elemcode;
438  data->material[noelements] = material;
439  for(i=0;i<nvalue-1;i++)
440  data->topology[noelements][i] = ivalues[i+1];
441  }
442 
443  if(nvalue < elemcode % 100) {
444  Getrow(line,in,TRUE);
445  if(allocated) {
446  if(ivalues[nvalue-1] == 0) nvalue--;
447  nvalue2 = StringToInteger(line,ivalues,MAXNODESD2+1,',');
448  for(i=0;i<nvalue2;i++)
449  data->topology[noelements][nvalue-1+i] = ivalues[i];
450  }
451  }
452  break;
453 
454  case 4:
455  nvalue = StringToInteger(line,ivalues,MAXNODESD2+1,',');
456 
457  if(ivalues[0] == ivalues0[0] & ivalues[1] != ivalues0[1]) continue;
458  ivalues0[0] = ivalues[0];
459  ivalues0[1] = ivalues[1];
460 
461  boundarynodes++;
462  if(allocated) {
463  nodeindx[boundarynodes] = ivalues[0];
464  boundindx[boundarynodes] = boundarytype;
465  }
466  break;
467 
468  case 5:
469  nvalue = StringToInteger(line,ivalues,10,',');
470 
471  if(allocated) {
472  for(i=0;i<nvalue;i++) {
473  boundarynodes += 1;
474  nodeindx[boundarynodes] = ivalues[i];
475  boundindx[boundarynodes] = boundarytype;
476  }
477  }
478  else
479  boundarynodes += nvalue;
480  break;
481 
482  case 6:
483  nvalue = StringToInteger(line,ivalues,10,',');
484 
485  if(allocated) {
486  for(i=0;i<nvalue;i++) {
487  j = ivalues[i];
488  data->material[j] = material;
489  }
490  }
491  break;
492 
493  default:
494  printf("Unknown case: %d\n",mode);
495  }
496  }
497 
498  }
499  end:
500 
501 
502  if(allocated == TRUE) {
503  if(info) printf("The mesh was loaded from file %s.\n",filename);
504 
505  FindPointParents(data,bound,boundarynodes,nodeindx,boundindx,info);
506 
507  /* ABAQUS format does not expect that all numbers are used
508  when numbering the elements. Therefore the nodes must
509  be renumberred from 1 to noknots. */
510 
511  if(noknots != maxknot) {
512  if(info) printf("There are %d nodes but maximum index is %d.\n",
513  noknots,maxknot);
514  if(info) printf("Renumbering elements\n");
515  for(j=1;j<=noelements;j++)
516  for(i=0;i < data->elementtypes[j]%100;i++)
517  data->topology[j][i] = ind[data->topology[j][i]];
518  }
519 
520  free_ivector(ind,1,maxknot);
521  free_Ivector(nodeindx,1,boundarynodes);
522  free_Ivector(boundindx,1,boundarynodes);
523 
524  fclose(in);
525  return(0);
526  }
527 
528  rewind(in);
529  data->noknots = noknots;
530  data->noelements = noelements;
531  data->maxnodes = maxnodes;
532  data->dim = 3;
533 
534  if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
535  noknots,noelements,maxnodes);
536  AllocateKnots(data);
537 
538  nosides = 2*boundarynodes;
539  printf("There are %d boundary nodes, thus allocating %d elements\n",
540  boundarynodes,nosides);
541  AllocateBoundary(bound,nosides);
542  nodeindx = Ivector(1,boundarynodes);
543  boundindx = Ivector(1,boundarynodes);
544 
545  ind = ivector(1,maxknot);
546  for(i=1;i<=maxknot;i++)
547  ind[i] = 0;
548 
549  allocated = TRUE;
550  goto omstart;
551 }
552 
553 
554 
555 
556 int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,
557  char *prefix,int info)
558 /* Load the grid from a format that in Nastran format
559  */
560 {
561  int noknots,noelements,elemcode,maxnodes,material;
562  int mode,allocated,maxknot,minknot;
563  int boundarytype,boundarynodes,nodes;
564 
565  char filename[MAXFILESIZE];
566  char line[MAXLINESIZE],*cp;
567  int j,k=0;
568  FILE *in;
569  int ivalues0[MAXDOFS];
570 
571 
572  strcpy(filename,prefix);
573  if ((in = fopen(filename,"r")) == NULL) {
574  AddExtension(prefix,filename,"nas");
575  if ((in = fopen(filename,"r")) == NULL) {
576  printf("LoadNastranInput: opening of the Nastran file '%s' wasn't succesfull !\n",
577  filename);
578  return(1);
579  }
580  }
581 
582  if(info) printf("Reading mesh from Nastran file %s.\n",filename);
583  InitializeKnots(data);
584 
585  allocated = FALSE;
586  maxknot = 0;
587  minknot = 10000;
588 
589  /* Because the file format doesn't provide the number of elements
590  or nodes the results are read twice but registered only in the
591  second time. */
592 omstart:
593 
594  mode = 0;
595  maxnodes = 0;
596  noknots = 0;
597  noelements = 0;
598  elemcode = 0;
599  boundarytype = 0;
600  boundarynodes = 0;
601  material = 0;
602  ivalues0[0] = ivalues0[1] = 0;
603 
604 
605  for(;;) {
606  /* getline; */
607 
608  if (Getrow(line,in,TRUE)) goto end;
609 
610  if(line[0] == '$') {
611  if(!allocated) printf("comment: %s",line);
612  }
613  else if(strstr(line,"GRID")) {
614  noknots++;
615  if(0) printf("line=%s\n",line);
616  cp = &line[5];
617  j = next_int(&cp);
618  if(0) printf("j=%d\n",j);
619 
620  if(allocated) {
621  k = next_int(&cp);
622  data->x[noknots] = next_real(&cp);
623  data->y[noknots] = next_real(&cp);
624  }
625  else {
626  if(j > maxknot) maxknot = j;
627  if(j < minknot) minknot = j;
628  }
629 
630  if(strstr(line,"*"))
631  Getrow(line,in,TRUE);
632 
633  if(allocated) {
634  cp = &line[4];
635  data->z[noknots] = next_real(&cp);
636  }
637 
638  }
639  else if(strstr(line,"TETRA")) {
640  noelements++;
641  nodes = 4;
642  if(nodes > maxnodes) maxnodes = nodes;
643  if(allocated) {
644  data->elementtypes[noelements] = 504;
645  cp = &line[6];
646  k = next_int(&cp);
647  data->material[noelements] = next_int(&cp) + 1;
648  for(j=0;j<nodes;j++)
649  data->topology[noelements][j] = next_int(&cp);
650  }
651  }
652  else if(strstr(line,"PYRAM")) {
653  noelements++;
654  nodes = 5;
655  if(nodes > maxnodes) maxnodes = nodes;
656  if(allocated) {
657  data->elementtypes[noelements] = 605;
658  cp = &line[6];
659  k = next_int(&cp);
660  data->material[noelements] = next_int(&cp) + 1;
661  for(j=0;j<nodes;j++)
662  data->topology[noelements][j] = next_int(&cp);
663  }
664  }
665  else if(strstr(line,"PENTA")) {
666  noelements++;
667  nodes = 6;
668  if(nodes > maxnodes) maxnodes = nodes;
669  if(allocated) {
670  data->elementtypes[noelements] = 706;
671  cp = &line[6];
672  k = next_int(&cp);
673  data->material[noelements] = next_int(&cp) + 1;
674  for(j=0;j<nodes;j++)
675  data->topology[noelements][j] = next_int(&cp);
676  }
677  }
678  else if(strstr(line,"CHEXA")) {
679  noelements++;
680  nodes = 8;
681  if(nodes > maxnodes) maxnodes = nodes;
682  if(allocated) {
683  data->elementtypes[noelements] = 808;
684  cp = &line[5];
685  k = next_int(&cp);
686  data->material[noelements] = next_int(&cp) + 1;
687  for(j=0;j<6;j++)
688  data->topology[noelements][j] = next_int(&cp);
689  }
690  Getrow(line,in,TRUE);
691  if(allocated) {
692  cp = &line[1];
693  for(j=6;j<8;j++)
694  data->topology[noelements][j] = k;
695  }
696  }
697  else if(strstr(line,"ENDDAT")) {
698  goto end;
699  }
700  else {
701  printf("unknown command: %s",line);
702  }
703  }
704 
705  end:
706 
707  if(allocated == TRUE) {
708  if(info) printf("The mesh was loaded from file %s.\n",filename);
709  fclose(in);
710  return(0);
711  }
712 
713  rewind(in);
714  data->noknots = noknots;
715  data->noelements = noelements;
716  data->maxnodes = maxnodes;
717  data->dim = 3;
718 
719  printf("maxknot = %d minknot = %d\n",maxknot,minknot);
720 
721  if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
722  noknots,noelements,maxnodes);
723  AllocateKnots(data);
724 
725  allocated = TRUE;
726  goto omstart;
727 }
728 
729 
730 
731 
732 static void ReorderFidapNodes(struct FemType *data,int element,int nodes,int typeflag)
733 {
734  int i,oldtopology[MAXNODESD2],*topology,dim;
735  int order203[]={1,3,2};
736  int order306[]={1,3,5,2,4,6};
737  int order408[]={1,3,5,7,2,4,6,8};
738  int order409[]={1,3,5,7,2,4,6,8,9};
739  int order510[]={1,3,6,10,2,5,4,7,8,9};
740  int order605[]={1,2,4,3,5};
741  int order808[]={1,2,4,3,5,6,8,7};
742  int order827[]={1,3,9,7,19,21,27,25,2,6,8,4,10,12,18,16,20,24,26,22,11,15,17,13,5,23,14};
743 
744  dim = data->dim;
745  if(typeflag > 10) dim -= 1;
746 
747  data->elementtypes[element] = 101*nodes;
748  topology = data->topology[element];
749 
750  if(dim == 1) {
751  if(nodes == 3) {
752  data->elementtypes[element] = 203;
753  for(i=0;i<nodes;i++)
754  oldtopology[i] = topology[i];
755  for(i=0;i<nodes;i++)
756  topology[i] = oldtopology[order203[i]-1];
757  }
758  }
759  else if(dim == 2) {
760  if(nodes == 6) {
761  data->elementtypes[element] = 306;
762  for(i=0;i<nodes;i++)
763  oldtopology[i] = topology[i];
764  for(i=0;i<nodes;i++)
765  topology[i] = oldtopology[order306[i]-1];
766  }
767  else if(nodes == 8) {
768  data->elementtypes[element] = 408;
769  for(i=0;i<nodes;i++)
770  oldtopology[i] = topology[i];
771  for(i=0;i<nodes;i++)
772  topology[i] = oldtopology[order408[i]-1];
773  }
774  else if(nodes == 9) {
775  data->elementtypes[element] = 409;
776  for(i=0;i<nodes;i++)
777  oldtopology[i] = topology[i];
778  for(i=0;i<nodes;i++)
779  topology[i] = oldtopology[order409[i]-1];
780  }
781  }
782  else if(dim == 3) {
783  if(nodes == 4) {
784  data->elementtypes[element] = 504;
785  }
786  else if(nodes == 10) {
787  data->elementtypes[element] = 510;
788  for(i=0;i<nodes;i++)
789  oldtopology[i] = topology[i];
790  for(i=0;i<nodes;i++)
791  topology[i] = oldtopology[order510[i]-1];
792  }
793  else if(nodes == 5) {
794  data->elementtypes[element] = 605;
795  for(i=0;i<nodes;i++)
796  oldtopology[i] = topology[i];
797  for(i=0;i<nodes;i++)
798  topology[i] = oldtopology[order605[i]-1];
799  }
800  else if(nodes == 6) {
801  data->elementtypes[element] = 706;
802  }
803  else if(nodes == 8) {
804  for(i=0;i<nodes;i++)
805  oldtopology[i] = topology[i];
806  for(i=0;i<nodes;i++)
807  topology[i] = oldtopology[order808[i]-1];
808  data->elementtypes[element] = 808;
809  }
810  else if(nodes == 27) {
811  for(i=0;i<nodes;i++)
812  oldtopology[i] = topology[i];
813  for(i=0;i<nodes;i++)
814  topology[i] = oldtopology[order827[i]-1];
815  data->elementtypes[element] = 827;
816  }
817  else {
818  printf("Unknown Fidap elementtype with %d nodes.\n",nodes);
819  }
820 
821  }
822  else printf("ReorderFidapNodes: unknown dimension (%d)\n",data->dim);
823  if(0) printf("dim = %d element = %d elemtype = %d\n",dim,element,data->elementtypes[element]);
824 }
825 
826 
827 
828 
829 int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *prefix,int info)
830 /* Load the grid from a format that can be read by FIDAP
831  program designed for fluid mechanics.
832 
833  Still under implementation
834  */
835 {
836  int noknots,noelements,dim,novel,elemcode,maxnodes;
837  int mode,maxknot,totelems,entity,maxentity;
838  char filename[MAXFILESIZE];
839  char line[MAXLINESIZE],entityname[MAXNAMESIZE];
840  int i,j,k,*ind,geoflag,typeflag;
841  int **topology;
842  FILE *in;
843  Real *vel,*temp;
844  int nogroups,knotno;
845  char *isio;
846 
847  AddExtension(prefix,filename,"fidap");
848 
849  if ((in = fopen(filename,"r")) == NULL) {
850  AddExtension(prefix,filename,"FDNEUT");
851  if ((in = fopen(filename,"r")) == NULL) {
852  printf("LoadFidapInput: opening of the Fidap-file '%s' wasn't succesfull !\n",
853  filename);
854  return(1);
855  }
856  }
857 
858  InitializeKnots(data);
859 
860  entity = 0;
861  mode = 0;
862  noknots = 0;
863  noelements = 0;
864  dim = 0;
865  elemcode = 0;
866  maxnodes = 4;
867  totelems = 0;
868  maxentity = 0;
869 
870  for(;;) {
871  isio = getline;
872 
873  if(!isio) goto end;
874  if(!line) goto end;
875  if(line=="") goto end;
876  if(strstr(line,"END")) goto end;
877 
878  /* Control information */
879  if(strstr(line,"FIDAP NEUTRAL FILE")) mode = 1;
880  else if(strstr(line,"NO. OF NODES")) mode = 2;
881  else if(strstr(line,"TEMPERATURE/SPECIES FLAGS")) mode = 3;
882  else if(strstr(line,"PRESSURE FLAGS")) mode = 4;
883  else if(strstr(line,"NODAL COORDINATES")) mode = 5;
884  else if(strstr(line,"BOUNDARY CONDITIONS")) mode = 6;
885  else if(strstr(line,"ELEMENT GROUPS")) mode = 7;
886  else if(strstr(line,"GROUP:")) mode = 8;
887  else if(strstr(line,"VELOCITY")) mode = 10;
888  else if(strstr(line,"TEMPERATURE")) mode = 11;
889  else if(0) printf("unknown: %s",line);
890 
891  switch (mode) {
892 
893  case 1:
894  if(info) printf("Loading FIDAP input file %s\n",filename);
895  getline;
896  if(info) printf("Name of the case: %s",line);
897  mode = 0;
898  break;
899 
900  case 2:
901  getline;
902  if(0) printf("Reading the header info\n");
903  sscanf(line,"%d%d%d%d%d",&noknots,&noelements,
904  &nogroups,&dim,&novel);
905  data->noknots = noknots;
906  data->noelements = noelements;
907  data->maxnodes = maxnodes;
908  data->dim = dim;
909 
910  mode = 0;
911  break;
912 
913  case 5:
914  if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
915  noknots,noelements,maxnodes);
916  AllocateKnots(data);
917  if(info) printf("Reading the nodes\n");
918  for(i=1;i<=noknots;i++) {
919  getline;
920  if (dim == 2)
921  sscanf(line,"%d%le%le",&knotno,
922  &(data->x[i]),&(data->y[i]));
923  else if(dim==3)
924  sscanf(line,"%d%le%le%le",&knotno,
925  &(data->x[i]),&(data->y[i]),&(data->z[i]));
926  }
927  break;
928 
929  case 8:
930  {
931  int val,group,elems,nodes;
932  char *cp;
933 
934  i=0;
935  do val=line[i++];
936  while(val!=':');i++;
937  sscanf(&line[i],"%d",&group);
938 
939  do val=line[i++];
940  while(val!=':');i++;
941  sscanf(&line[i],"%d",&elems);
942 
943  do val=line[i++];
944  while(val!=':');i++;
945  sscanf(&line[i],"%d",&nodes);
946 
947  do val=line[i++];
948  while(val!=':');i++;
949  sscanf(&line[i],"%d",&geoflag);
950 
951  do val=line[i++];
952  while(val!=':');i++;
953  sscanf(&line[i],"%d",&typeflag);
954 
955  getline;
956  i=0;
957  do val=line[i++];
958  while(val!=':');i++;
959  sscanf(&line[i],"%s",entityname);
960 
961  if(nodes > maxnodes) {
962  if(info) printf("Allocating a %d-node topology matrix\n",nodes);
963  topology = Imatrix(1,noelements,0,nodes-1);
964  if(totelems > 0) {
965  for(j=1;j<=totelems;j++)
966  for(i=0;i<data->elementtypes[j] % 100;i++)
967  topology[j][i] = data->topology[j][i];
968  }
969  free_Imatrix(data->topology,1,data->noelements,0,data->maxnodes-1);
970  data->maxnodes = maxnodes = nodes;
971  data->topology = topology;
972  }
973 
974  if(0) printf("Reading %d element topologies with %d nodes for %s\n",
975  elems,nodes,entityname);
976 
977  for(entity=1;entity<=maxentity;entity++) {
978  k = strcmp(entityname,data->bodyname[entity]);
979  if(k == 0) break;
980  }
981 
982  if(entity > maxentity) {
983  maxentity++;
984  strcpy(data->bodyname[entity],entityname);
985  if(info) printf("Found new entity: %s\n",entityname);
986  }
987 
988  for(i=totelems+1;i<=totelems+elems;i++) {
989  getline;
990 
991  cp = line;
992  j = next_int(&cp);
993  for(j=0;j<nodes;j++)
994  data->topology[i][j] = next_int(&cp);
995 
996  ReorderFidapNodes(data,i,nodes,typeflag);
997 
998  if(data->elementtypes[i] == 0) {
999  printf("Elementtype is zero!\n");
1000  }
1001 
1002  if(entity) data->material[i] = entity;
1003  else data->material[i] = group;
1004  }
1005  totelems += elems;
1006  }
1007  mode = 0;
1008  break;
1009 
1010  case 10:
1011  dim = 3;
1012  if(info) printf("Reading the velocity field\n");
1013  CreateVariable(data,2,dim,0.0,"Velocity",FALSE);
1014  vel = data->dofs[2];
1015  for(j=1;j<=noknots;j++) {
1016  getline;
1017  if(dim==2)
1018  sscanf(line,"%le%le",&(vel[2*j-1]),&(vel[2*j]));
1019  if(dim==3)
1020  sscanf(line,"%le%le%le",&(vel[3*j-2]),&(vel[3*j-1]),&(vel[3*j]));
1021  }
1022  mode = 0;
1023  break;
1024 
1025  case 11:
1026  if(info) printf("Reading the temperature field\n");
1027  CreateVariable(data,1,1,0.0,"Temperature",FALSE);
1028  temp = data->dofs[1];
1029  for(j=1;j<=noknots;j++) {
1030  getline;
1031  sscanf(line,"%le",&(temp[j]));
1032  }
1033  mode = 0;
1034  break;
1035 
1036  default:
1037  break;
1038  }
1039  }
1040 
1041 end:
1042 
1043  /* Renumber the nodes */
1044  maxknot = 0;
1045  for(i=1;i<=noelements;i++)
1046  for(j=0;j < data->elementtypes[i]%100;j++)
1047  if(data->topology[i][j] > maxknot) maxknot = data->topology[i][j];
1048 
1049  if(maxknot > noknots) {
1050  if(info) printf("Renumbering the nodes from 1 to %d\n",noknots);
1051 
1052  ind = ivector(1,maxknot);
1053  for(i=1;i<=maxknot;i++)
1054  ind[i] = 0;
1055 
1056  for(i=1;i<=noelements;i++)
1057  for(j=0;j < data->elementtypes[i]%100;j++)
1058  ind[data->topology[i][j]] = data->topology[i][j];
1059  i=0;
1060  for(j=1;j<=noknots;j++) {
1061  i++;
1062  while(ind[i]==0) i++;
1063  ind[i] = j;
1064  }
1065  for(i=1;i<=noelements;i++)
1066  for(j=0;j < data->elementtypes[i]%100;j++)
1067  data->topology[i][j] = ind[data->topology[i][j]];
1068  }
1069 
1070 
1071  if(maxentity > 0) data->bodynamesexist = TRUE;
1072 
1073  fclose(in);
1074 
1075  if(info) printf("Finished reading the Fidap neutral file\n");
1076 
1077 
1078  ElementsToBoundaryConditions(data,boundaries,FALSE,TRUE);
1079  RenumberBoundaryTypes(data,boundaries,TRUE,0,info);
1080 
1081  return(0);
1082 }
1083 
1084 
1085 
1086 static void ReorderAnsysNodes(struct FemType *data,int *oldtopology,
1087  int element,int dim,int nodes)
1088 {
1089  int i,*topology,elementtype = 0;
1090  int order820[]={1,2,3,4,5,6,7,8,9,10,11,12,17,18,19,20,13,14,15,16};
1091  int order504[]={1,2,3,5};
1092  int order306[]={1,2,3,5,6,8};
1093  int order510[]={1,2,3,5,9,10,12,17,18,19};
1094  int order613[]={1,2,3,4,5,9,10,11,12,17,18,19,20};
1095 
1096  if(dim == 3) {
1097  if(nodes == 20) {
1098  if(oldtopology[2] == oldtopology[3]) elementtype = 510;
1099  else if(oldtopology[4] == oldtopology[5]) elementtype = 613;
1100  else elementtype = 820;
1101  }
1102  if(nodes == 8) {
1103  if(oldtopology[2] == oldtopology[3]) elementtype = 504;
1104  else if(oldtopology[4] == oldtopology[5]) elementtype = 605;
1105  else elementtype = 808;
1106  }
1107  if(nodes == 4) elementtype = 504;
1108  if(nodes == 10) elementtype = 510;
1109  }
1110  else if(dim == 2) {
1111  if(nodes == 9) elementtype = 408;
1112  if(nodes == 8) {
1113  if(oldtopology[3] == oldtopology[6])
1114  elementtype = 306;
1115  else
1116  elementtype = 408;
1117  }
1118  if(nodes == 4) elementtype = 404;
1119  if(nodes == 10) elementtype = 310;
1120  if(nodes == 6) elementtype = 306;
1121  if(nodes == 3) elementtype = 303;
1122  }
1123  else if(dim == 1) {
1124  if(nodes == 4) elementtype = 204;
1125  if(nodes == 3) elementtype = 203;
1126  if(nodes == 2) elementtype = 202;
1127  }
1128 
1129  if(!elementtype) {
1130  printf("Unknown elementtype in element %d (%d nodes, %d dim).\n",
1131  element,nodes,dim);
1132  }
1133 
1134  data->elementtypes[element] = elementtype;
1135  topology = data->topology[element];
1136 
1137  switch (elementtype) {
1138 
1139  case 820:
1140  for(i=0;i<elementtype%100;i++)
1141  topology[i] = oldtopology[order820[i]-1];
1142  break;
1143 
1144  case 504:
1145  for(i=0;i<elementtype%100;i++)
1146  topology[i] = oldtopology[order504[i]-1];
1147  break;
1148 
1149 
1150  case 510:
1151  for(i=0;i<elementtype%100;i++) {
1152  if(oldtopology[2] == oldtopology[3])
1153  topology[i] = oldtopology[order510[i]-1];
1154  else
1155  topology[i] = oldtopology[i];
1156  }
1157  break;
1158 
1159  case 605:
1160  for(i=0;i<elementtype%100;i++) {
1161  topology[i] = oldtopology[i];
1162  }
1163  break;
1164 
1165  case 613:
1166  for(i=0;i<elementtype%100;i++) {
1167  if(oldtopology[4] == oldtopology[5])
1168  topology[i] = oldtopology[order613[i]-1];
1169  else
1170  topology[i] = oldtopology[i];
1171  }
1172  break;
1173 
1174  case 306:
1175  for(i=0;i<elementtype%100;i++) {
1176  if(oldtopology[3] == oldtopology[6])
1177  topology[i] = oldtopology[order306[i]-1];
1178  else
1179  topology[i] = oldtopology[i];
1180  }
1181  break;
1182 
1183  default:
1184  for(i=0;i<elementtype%100;i++)
1185  topology[i] = oldtopology[i];
1186 
1187  }
1188 }
1189 
1190 
1191 int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,
1192  char *prefix,int info)
1193 /* This procedure reads the FEM mesh as written by Ansys. */
1194 {
1195  int noknots = 0,noelements = 0,nosides,sidetype,currenttype;
1196  int maxindx,*indx,*revindx,topology[100],ind;
1197  int i,j,k,l,imax,*nodeindx,*boundindx,boundarynodes;
1198  int noansystypes,*ansysdim,*ansysnodes,*ansystypes,boundarytypes = 0;
1199  int namesexist,maxside,sides;
1200  Real x,y,z = 0;
1201  FILE *in;
1202  char *cp,line[MAXLINESIZE],filename[MAXFILESIZE],
1203  text[MAXNAMESIZE],text2[MAXNAMESIZE];
1204 
1205 
1206  /* ExportMesh.header */
1207 
1208  sprintf(filename,"%s.header",prefix);
1209  if ((in = fopen(filename,"r")) == NULL) {
1210  printf("LoadAnsysInput: The opening of the header-file %s failed!\n",
1211  filename);
1212  return(1);
1213  }
1214 
1215  if(info) printf("Calculating Ansys elementtypes from %s\n",filename);
1216  for(i=0;getline;i++);
1217 
1218  noansystypes = i-1;
1219  printf("There seems to be %d elementytypes in file %s.\n",noansystypes,filename);
1220 
1221  ansysdim = Ivector(1,noansystypes);
1222  ansysnodes = Ivector(1,noansystypes);
1223  ansystypes = Ivector(1,noansystypes);
1224 
1225  rewind(in);
1226  for(i=0;i<=noansystypes;i++) {
1227  Real dummy1,dummy2,dummy3;
1228  getline;
1229 
1230  /* Ansys writes decimal points also for integers and therefore these
1231  values are read in as real numbers. */
1232 
1233  sscanf(line,"%le %le %le",&dummy1,&dummy2,&dummy3);
1234 
1235  if(i==0) {
1236  noelements = (int) (dummy1+0.5);
1237  noknots = (int) (dummy2+0.5);
1238  boundarytypes = (int) (dummy3+0.5);
1239  }
1240  else {
1241  ansysdim[i] = (int) (dummy1+0.5);
1242  ansysnodes[i] = (int) (dummy2+0.5);
1243  ansystypes[i] = (int) (dummy3+0.5);
1244  }
1245  }
1246  fclose(in);
1247 
1248  printf("Ansys file has %d elements, %d nodes and %d boundary types.\n",
1249  noelements,noknots,boundarytypes);
1250 
1251  /* ExportMesh.names */
1252 
1253  sprintf(filename,"%s.names",prefix);
1254  in = fopen(filename,"r");
1255  if(in == NULL)
1256  namesexist = FALSE;
1257  else
1258  namesexist = TRUE;
1259 
1260  if(namesexist) printf("Using names of bodies and boundaries\n");
1261 
1262 
1263  /* ExportMesh.node */
1264 
1265  sprintf(filename,"%s.node",prefix);
1266  if ((in = fopen(filename,"r")) == NULL) {
1267  printf("LoadAnsysInput: The opening of the nodes-file %s failed!\n",
1268  filename);
1269  return(2);
1270  }
1271 
1272  if(info) printf("Calculating Ansys nodes from %s\n",filename);
1273  for(i=0;getline;i++);
1274 
1275  if(info) printf("There seems to be %d nodes in file %s.\n",i,filename);
1276  if(i != noknots) printf("Conflicting number of nodes %d vs %d!\n",i,noknots);
1277 
1278  /* Make room and initialize the mesh */
1279  InitializeKnots(data);
1280 
1281  /* Even 2D elements may form a 3D object! */
1282  data->dim = 3;
1283  data->maxnodes = 1;
1284 
1285  for(i=1;i<=noansystypes;i++) {
1286  if(ansysdim[i] > data->dim) data->dim = ansysdim[i];
1287  if(ansysnodes[i] > data->maxnodes) data->maxnodes = ansysnodes[i];
1288  }
1289  if(data->maxnodes < 8) data->maxnodes = 8;
1290 
1291  data->noknots = noknots;
1292  data->noelements = noelements;
1293 
1294  if(info) printf("Allocating for %d nodes and %d elements with max. %d nodes in %d-dim.\n",
1295  noknots,noelements,data->maxnodes,data->dim);
1296  AllocateKnots(data);
1297 
1298  indx = Ivector(1,noknots);
1299  for(i=1;i<=noknots;i++) indx[i] = 0;
1300 
1301  if(info) printf("Loading %d Ansys nodes from %s\n",noknots,filename);
1302  rewind(in);
1303  for(i=1;i<=noknots;i++) {
1304  getline; cp=line;
1305 
1306  indx[i] = next_int(&cp);
1307  if(cp[0] == '.') cp++;
1308 
1309  x = next_real(&cp);
1310  if(!cp) x = y = z = 0.0;
1311  else {
1312  y = next_real(&cp);
1313  if(!cp) y = z = 0.0;
1314  else if(data->dim == 3) {
1315  z = next_real(&cp);
1316  if(!cp) z = 0.0;
1317  }
1318  }
1319  data->x[i] = x;
1320  data->y[i] = y;
1321  if(data->dim == 3) data->z[i] = z;
1322  }
1323  fclose(in);
1324 
1325  /* reorder the indexes */
1326  maxindx = indx[1];
1327  for(i=1;i<=noknots;i++)
1328  if(indx[i] > maxindx) maxindx = indx[i];
1329  revindx = Ivector(0,maxindx);
1330 
1331  if(maxindx > noknots) {
1332  printf("There are %d nodes with indexes up to %d.\n",
1333  noknots,maxindx);
1334  for(i=1;i<=maxindx;i++)
1335  revindx[i] = 0;
1336  for(i=1;i<=noknots;i++)
1337  revindx[indx[i]] = i;
1338  }
1339  else {
1340  for(i=1;i<=noknots;i++)
1341  revindx[i] = i;
1342  }
1343 
1344  /* ExportMesh.elem */
1345 
1346  sprintf(filename,"%s.elem",prefix);
1347  if ((in = fopen(filename,"r")) == NULL) {
1348  printf("LoadAnsysInput: The opening of the element-file %s failed!\n",
1349  filename);
1350  return(4);
1351  }
1352 
1353  if(info) printf("Loading %d Ansys elements from %s\n",noelements,filename);
1354 
1355  for(j=1;j<=noelements;j++) {
1356 
1357  getline;
1358  cp=line;
1359 
1360  for(i=0;i<8;i++) {
1361  ind = next_int(&cp);
1362  if(cp[0] == '.') cp++;
1363  topology[i] = revindx[ind];
1364  }
1365 
1366  data->material[j] = next_int(&cp);
1367  currenttype = next_int(&cp);
1368 
1369  for(k=1;k<=noansystypes;k++)
1370  if(ansystypes[k] == currenttype) break;
1371  if(ansystypes[k] != currenttype) k=1;
1372 
1373  if(ansysnodes[k] > 8) {
1374  getline;
1375  cp=line;
1376 
1377  if(ansysnodes[k] == 10 && topology[2] != topology[3])
1378  imax = 10;
1379  else
1380  imax = 20;
1381 
1382  for(i=8;i<imax;i++) {
1383  ind = next_int(&cp);
1384  if(cp[0] == '.') cp++;
1385  topology[i] = revindx[ind];
1386  }
1387  }
1388 
1389  ReorderAnsysNodes(data,&topology[0],j,ansysdim[k],ansysnodes[k]);
1390  }
1391  fclose(in);
1392 
1393 
1394  /* ExportMesh.boundary */
1395 
1396  sprintf(filename,"%s.boundary",prefix);
1397  printf("Calculating nodes in file %s\n",filename);
1398  if ((in = fopen(filename,"r")) == NULL) {
1399  printf("LoadAnsysInput: The opening of the boundary-file %s failed!\n",
1400  filename);
1401  return(5);
1402  }
1403 
1404  j = 0;
1405  for(i=0;getline;i++)
1406  if(!strstr(line,"Boundary")) j++;
1407 
1408  boundarynodes = j;
1409  nosides = 2*boundarynodes;
1410 
1411  if(info) printf("There are %d boundary nodes, allocating %d elements\n",
1412  boundarynodes,nosides);
1413  AllocateBoundary(bound,nosides);
1414  nodeindx = Ivector(1,boundarynodes);
1415  boundindx = Ivector(1,boundarynodes);
1416 
1417  if(info) printf("Loading Ansys boundary from %s\n",filename);
1418 
1419  for(i=1;i<=boundarynodes;i++) nodeindx[i] = boundindx[i] = 0;
1420 
1421  rewind(in);
1422  maxside = 0;
1423  j = 0;
1424  for(i=0;getline;i++) {
1425  if(strstr(line,"Boundary")) {
1426  sscanf(line,"%d",&sidetype);
1427  maxside = MAX(sidetype,maxside);
1428  }
1429  else {
1430  j++;
1431  sscanf(line,"%d",&k);
1432  nodeindx[j] = revindx[k];
1433  if(!nodeindx[j]) printf("The boundary %dth node %d is not in index list\n",j,k);
1434  boundindx[j] = sidetype;
1435  }
1436  }
1437  printf("Found %d boundary nodes with %d as maximum side.\n",j,maxside);
1438  fclose(in);
1439 
1440  FindPointParents(data,bound,boundarynodes,nodeindx,boundindx,info);
1441 
1442  if(namesexist) {
1443  int bcind,*bctypes = NULL,*bctypeused = NULL,*bcused = NULL,newsides = 0;
1444 
1445  data->bodynamesexist = TRUE;
1446  if(bound[0].nosides) {
1447  newsides = 0;
1448  bctypes = Ivector(1,maxside);
1449  bctypeused = Ivector(1,maxside);
1450  bcused = Ivector(1,bound[0].nosides);
1451  for(i=1;i<=bound[0].nosides;i++) bcused[i] = FALSE;
1452  data->boundarynamesexist = TRUE;
1453  for(i=1;i<=maxside;i++)
1454  bctypeused[i] = FALSE;
1455  }
1456 
1457  sprintf(filename,"%s.names",prefix);
1458  in = fopen(filename,"r");
1459 
1460  for(;;) {
1461  if(Getrow(line,in,TRUE)) break;
1462  sscanf(line,"%d%s%s%d",&bcind,&text[0],&text2[0],&sides);
1463 
1464  if(strstr(text2,"BODY")) {
1465  getline;
1466  sscanf(line,"%d%d",&j,&bcind);
1467  strcpy(data->bodyname[bcind],text);
1468  }
1469  else if(strstr(text2,"BOUNDARY")) {
1470  /* Read the boundary groups belonging to a particular name */
1471  for(i=1;i<=maxside;i++)
1472  bctypes[i] = 0;
1473  for(i=1;i<=sides;i++) {
1474  getline;
1475  sscanf(line,"%d%d",&j,&bcind);
1476  bctypes[bcind] = TRUE;
1477  }
1478 
1479  /* Find 1st unsed boundarytype */
1480  for(i=1;i<=maxside;i++)
1481  if(bctypes[i] && !bctypeused[i]) break;
1482 
1483  bcind = i;
1484  bctypeused[bcind] = TRUE;
1485  if(0) printf("First unused boundary is of type %d\n",bcind);
1486  strcpy(data->boundaryname[bcind],text);
1487 
1488  /* Check which of the BCs have already been named */
1489  k = l = 0;
1490  for(i=1;i<=bound[0].nosides;i++) {
1491  j = bound[0].types[i];
1492 
1493  /* The bc is not given any name, hence it can't be a duplicate */
1494  if(!bctypes[j]) continue;
1495 
1496  if(!bcused[i]) {
1497  k++;
1498  bcused[i] = bcind;
1499  }
1500  else {
1501  l++;
1502  if(newsides == 0) AllocateBoundary(&bound[1],bound[0].nosides);
1503  newsides++;
1504  bound[1].types[newsides] = bcind;
1505  bound[1].parent[newsides] = bound[0].parent[i];
1506  bound[1].side[newsides] = bound[0].side[i];
1507  bound[1].parent2[newsides] = bound[0].parent2[i];
1508  bound[1].side2[newsides] = bound[0].side2[i];
1509  bound[1].normal[newsides] = bound[0].normal[i];
1510  }
1511  }
1512  if(info) printf("There are %d boundary elements with name %s.\n",k+l,data->boundaryname[bcind]);
1513  }
1514  }
1515 
1516  fclose(in);
1517 
1518  /* Put the indexes of all conditions with the same name to be same */
1519  if(bound[0].nosides) {
1520  for(i=1;i<=bound[0].nosides;i++)
1521  if(bcused[i]) bound[0].types[i] = bcused[i];
1522  if(newsides) {
1523  bound[1].nosides = newsides;
1524  if(info) printf("Created %d additional boundary elements to achieve unique naming.\n",newsides);
1525  }
1526  free_Ivector(bctypes,1,maxside);
1527  free_Ivector(bctypeused,1,maxside);
1528  free_Ivector(bcused,1,bound[0].nosides);
1529  }
1530  }
1531 
1532  free_Ivector(boundindx,1,boundarynodes);
1533  free_Ivector(nodeindx,1,boundarynodes);
1534 
1535  return(0);
1536 }
1537 
1538 
1539 
1540 
1541 static void ReorderFieldviewNodes(struct FemType *data,int *oldtopology,
1542  int element,int dim,int nodes)
1543 {
1544  int i,*topology,elementtype = 0;
1545  int order808[]={1,2,4,3,5,6,8,7};
1546  int order706[]={1,4,6,2,3,5};
1547  int order404[]={1,2,3,4};
1548 
1549  if(dim == 3) {
1550  if(nodes == 8) elementtype = 808;
1551  if(nodes == 6) elementtype = 706;
1552  if(nodes == 4) elementtype = 504;
1553  }
1554  else if(dim == 2) {
1555  if(nodes == 4) elementtype = 404;
1556  if(nodes == 3) elementtype = 303;
1557  }
1558 
1559  if(!elementtype) {
1560  printf("Unknown elementtype in element %d (%d nodes, %d dim).\n",
1561  element,nodes,dim);
1562  }
1563 
1564  data->elementtypes[element] = elementtype;
1565  topology = data->topology[element];
1566 
1567  for(i=0;i<elementtype%100;i++) {
1568  if(elementtype == 808) topology[i] = oldtopology[order808[i]-1];
1569  else if(elementtype == 706) topology[i] = oldtopology[order706[i]-1];
1570  else if(elementtype == 404) topology[i] = oldtopology[order404[i]-1];
1571  else topology[i] = oldtopology[i];
1572  }
1573 }
1574 
1575 
1576 
1577 
1578 int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info)
1579 /* Load the grid from a format that can be read by FieldView
1580  program by PointWise. This is a suitable format to read files created
1581  by GridGen. */
1582 {
1583  int noknots,noelements,elemcode,maxnodes;
1584  int mode,totelems,entity;
1585  char filename[MAXFILESIZE];
1586  char line[MAXLINESIZE],*cp;
1587  int i,j,k;
1588  FILE *in;
1589  Real x,y,z;
1590  int maxindx,sidenodes;
1591  char *isio;
1592  int nobound,nobulk = 0,maxsidenodes,*boundtypes = NULL,**boundtopos = NULL,*boundnodes = NULL,*origtopology;
1593 
1594  if ((in = fopen(prefix,"r")) == NULL) {
1595  AddExtension(prefix,filename,"dat");
1596  if ((in = fopen(filename,"r")) == NULL) {
1597  printf("LoadFieldviewInput: opening of the Fieldview-file '%s' wasn't succesfull !\n",
1598  filename);
1599  return(1);
1600  }
1601  }
1602 
1603  InitializeKnots(data);
1604  data->dim = 3;
1605  data->created = TRUE;
1606 
1607  entity = 0;
1608  mode = 0;
1609  noknots = 0;
1610  noelements = 0;
1611  elemcode = 0;
1612 
1613  maxnodes = 8;
1614  maxsidenodes = 4;
1615  maxindx = 0;
1616  sidenodes = 0;
1617 
1618  data->maxnodes = maxnodes;
1619 
1620  totelems = 0;
1621 
1622  for(;;) {
1623 
1624  if(mode == 0) {
1625  isio = getline;
1626 
1627  if(!isio) goto end;
1628  if(!line) goto end;
1629  if(line=="") goto end;
1630  if(strstr(line,"END")) goto end;
1631 
1632  /* Control information */
1633  if(strstr(line,"FIELDVIEW")) mode = 1;
1634  else if(strstr(line,"CONSTANTS")) mode = 2;
1635  else if(strstr(line,"GRIDS")) mode = 3;
1636  else if(strstr(line,"Boundary Table")) mode = 4;
1637  else if(strstr(line,"Variable Names")) mode = 5;
1638  else if(strstr(line,"Nodes")) mode = 6;
1639  else if(strstr(line,"Boundary Faces")) mode = 7;
1640  else if(strstr(line,"Elements")) mode = 8;
1641  else if(strstr(line,"Variables")) mode = 9;
1642  else if(0) printf("unknown: %s",line);
1643  }
1644 
1645  switch (mode) {
1646 
1647  case 1:
1648  printf("This is indeed a Fieldview input file.\n");
1649  mode = 0;
1650  break;
1651 
1652  case 2:
1653  if(0) printf("Constants block\n");
1654  mode = 0;
1655  break;
1656 
1657  case 3:
1658  if(0) printf("Grids block\n");
1659  mode = 0;
1660  break;
1661 
1662  case 4:
1663  if(0) printf("Boundary Table\n");
1664  mode = 0;
1665  break;
1666 
1667  case 5:
1668  if(0) printf("Variable names\n");
1669  mode = 0;
1670  break;
1671 
1672  case 6:
1673 
1674  getline;
1675  sscanf(line,"%d",&noknots);
1676  data->noknots = noknots;
1677 
1678  if(info) printf("Loading %d node coordinates\n",noknots);
1679 
1680  data->x = Rvector(1,noknots);
1681  data->y = Rvector(1,noknots);
1682  data->z = Rvector(1,noknots);
1683 
1684  for(i=1;i<=noknots;i++) {
1685  getline;
1686  sscanf(line,"%le%le%le",&x,&y,&z);
1687  data->x[i] = x;
1688  data->y[i] = y;
1689  data->z[i] = z;
1690  }
1691  mode = 0;
1692  break;
1693 
1694  case 7:
1695 
1696  getline;
1697  sscanf(line,"%d",&nobound);
1698 
1699  if(info) printf("Loading %d boundary element definitions\n",nobound);
1700 
1701  boundtypes = Ivector(1,nobound);
1702  boundtopos = Imatrix(1,nobound,0,maxsidenodes-1);
1703  boundnodes = Ivector(1,nobound);
1704 
1705  for(i=1;i<=nobound;i++) {
1706  getline; cp=line;
1707 
1708  boundtypes[i]= next_int(&cp);
1709  maxsidenodes = next_int(&cp);
1710 
1711  for(j=0;j<maxsidenodes && cp;j++)
1712  boundtopos[i][j] = next_int(&cp);
1713 
1714  boundnodes[i] = j;
1715  }
1716  mode = 0;
1717  break;
1718 
1719 
1720  case 8:
1721 
1722  if(info) printf("Loading bulk element definitions\n");
1723 
1724  if(maxsidenodes == 4) noelements = noknots + nobound;
1725  else noelements = 6*noknots + nobound;
1726 
1727  origtopology = Ivector(0,maxnodes-1);
1728  data->topology = Imatrix(1,noelements,0,maxnodes-1);
1729  data->material = Ivector(1,noelements);
1730  data->elementtypes = Ivector(1,noelements);
1731 
1732  for(i=0;;) {
1733  getline; cp=line;
1734 
1735  if(strstr(line,"Variables")) mode = 9;
1736  if(mode != 8) break;
1737 
1738  i++;
1739 
1740  k = next_int(&cp);
1741 
1742  if(k == 2) maxnodes = 8;
1743  else if(k == 1) maxnodes = 4;
1744 
1745  data->material[i]= next_int(&cp);
1746 
1747  for(j=0;j<maxnodes && cp;j++) {
1748  origtopology[j] = next_int(&cp);
1749  if(maxindx < origtopology[j]) maxindx = origtopology[j];
1750  }
1751 
1752  ReorderFieldviewNodes(data,origtopology,i,3,j);
1753 
1754  if(nobulk+nobound == noelements+1)
1755  printf("Too few elements (%d) were allocated!!\n",noelements);
1756 
1757  }
1758  nobulk = i;
1759 
1760  printf("Found %d bulk elements\n",nobulk);
1761  if(nobulk+nobound > noelements) printf("Too few elements (%d) were allocated!!\n",noelements);
1762  printf("Allocated %.4lg %% too many elements\n",
1763  noelements*100.0/(nobulk+nobound)-100.0);
1764 
1765 
1766  for(i=1;i<=nobound;i++) {
1767  ReorderFieldviewNodes(data,boundtopos[i],i+nobulk,2,boundnodes[i]);
1768  data->material[i+nobulk] = boundtypes[i];
1769  }
1770 
1771  data->noelements = noelements = nobulk + nobound;
1772 
1773  mode = 0;
1774  break;
1775 
1776 
1777  case 9:
1778 
1779  printf("Variables\n");
1780 
1781  mode = 0;
1782  break;
1783 
1784  default:
1785  break;
1786  }
1787  }
1788 
1789 end:
1790 
1791  if(maxindx != noknots)
1792  printf("The maximum index %d differs from the number of nodes %d !\n",maxindx,noknots);
1793 
1795 
1796  return(0);
1797 }
1798 
1799 
1800 
1801 
1802 int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
1803  char *prefix,int info)
1804 /* This procedure reads the mesh assuming Triangle format
1805  */
1806 {
1807  int noknots,noelements,maxnodes,elematts,nodeatts,dim;
1808  int elementtype,bcmarkers,sideelemtype;
1809  int i,j,k,*boundnodes;
1810  FILE *in;
1811  char *cp,line[MAXLINESIZE],elemfile[MAXFILESIZE],nodefile[MAXFILESIZE],
1812  polyfile[MAXLINESIZE];
1813 
1814 
1815  if(info) printf("Loading mesh in Triangle format from file %s.*\n",prefix);
1816 
1817  sprintf(nodefile,"%s.node",prefix);
1818  if ((in = fopen(nodefile,"r")) == NULL) {
1819  printf("LoadElmerInput: The opening of the nodes file %s failed!\n",nodefile);
1820  return(1);
1821  }
1822  else
1823  printf("Loading nodes from file %s\n",nodefile);
1824 
1825  getline;
1826  sscanf(line,"%d %d %d %d",&noknots,&dim,&nodeatts,&bcmarkers);
1827  fclose(in);
1828 
1829  if(dim != 2) {
1830  printf("LoadTriangleInput assumes that the space dimension is 2, not %d.\n",dim);
1831  return(2);
1832  }
1833 
1834  sprintf(elemfile,"%s.ele",prefix);
1835  if ((in = fopen(elemfile,"r")) == NULL) {
1836  printf("LoadElmerInput: The opening of the element file %s failed!\n",elemfile);
1837  return(3);
1838  }
1839  else
1840  printf("Loading elements from file %s\n",elemfile);
1841 
1842  getline;
1843  sscanf(line,"%d %d %d",&noelements,&maxnodes,&elematts);
1844  fclose(in);
1845 
1846 
1847  InitializeKnots(data);
1848  data->dim = dim;
1849  data->maxnodes = maxnodes;
1850  data->noelements = noelements;
1851  data->noknots = noknots;
1852  elementtype = 300 + maxnodes;
1853 
1854  if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
1855  AllocateKnots(data);
1856 
1857  boundnodes = Ivector(1,noknots);
1858  for(i=1;i<=noknots;i++)
1859  boundnodes[i] = 0;
1860 
1861  in = fopen(nodefile,"r");
1862  getline;
1863  for(i=1; i <= noknots; i++) {
1864  getline;
1865  cp = line;
1866  j = next_int(&cp);
1867  if(j != i) printf("LoadTriangleInput: nodes i=%d j=%d\n",i,j);
1868  data->x[i] = next_real(&cp);
1869  data->y[i] = next_real(&cp);
1870  for(j=0;j<nodeatts;j++) {
1871  next_real(&cp);
1872  }
1873  if(bcmarkers > 0)
1874  boundnodes[i] = next_int(&cp);
1875  }
1876  fclose(in);
1877 
1878  in = fopen(elemfile,"r");
1879  getline;
1880  for(i=1; i <= noelements; i++) {
1881  getline;
1882  cp = line;
1883  data->elementtypes[i] = elementtype;
1884  j = next_int(&cp);
1885  if(j != i) printf("LoadTriangleInput: elem i=%d j=%d\n",i,j);
1886  for(j=0;j<3;j++)
1887  data->topology[i][j] = next_int(&cp);
1888  if(maxnodes == 6) {
1889  data->topology[i][4] = next_int(&cp);
1890  data->topology[i][5] = next_int(&cp);
1891  data->topology[i][3] = next_int(&cp);
1892  }
1893  data->material[i] = 1;
1894  }
1895  fclose(in);
1896 
1897 
1898  sprintf(polyfile,"%s.poly",prefix);
1899  if ((in = fopen(polyfile,"r")) == NULL) {
1900  printf("LoadElmerInput: The opening of the poly file %s failed!\n",polyfile);
1901  return(1);
1902  }
1903  else
1904  printf("Loading nodes from file %s\n",polyfile);
1905 
1906  {
1907  int bcelems,markers,ind1,ind2,bctype,j2,k2,hit = 0;
1908  int elemsides,sideind[2],side,elemind = 0;
1909 
1910  bctype = 1;
1911  elemsides = 3;
1912 
1913  getline;
1914  getline;
1915  sscanf(line,"%d %d",&bcelems,&markers);
1916 
1917  CreateInverseTopology(data,info);
1918 
1919  AllocateBoundary(bound,bcelems);
1920 
1921  for(i=1;i<=bcelems;i++) {
1922 
1923  getline;
1924  if(markers)
1925  sscanf(line,"%d %d %d %d",&j,&ind1,&ind2,&bctype);
1926  else
1927  sscanf(line,"%d %d %d",&j,&ind1,&ind2);
1928 
1929  /* find an element which owns both the nodes */
1930  for(j=1;j<=data->maxinvtopo;j++) {
1931  hit = FALSE;
1932  k = data->invtopo[j][ind1];
1933  if(!k) break;
1934 
1935  for(j2=1;j2<=data->maxinvtopo;j2++) {
1936  k2 = data->invtopo[j2][ind2];
1937  if(!k2) break;
1938  if(k == k2) {
1939  hit = TRUE;
1940  elemind = k;
1941  break;
1942  }
1943  }
1944  if(hit) break;
1945  }
1946  if(!hit) return(1);
1947 
1948 
1949  /* Find the correct side of the triangular element */
1950  for(side=0;side<elemsides;side++) {
1951  GetElementSide(elemind,side,1,data,&sideind[0],&sideelemtype);
1952 
1953  hit = FALSE;
1954  if(sideind[0] == ind1 && sideind[1] == ind2) hit = TRUE;
1955  if(sideind[0] == ind2 && sideind[1] == ind1) hit = TRUE;
1956 
1957  if(hit) {
1958  bound->parent[i] = elemind;
1959  bound->side[i] = side;
1960  bound->parent2[i] = 0;
1961  bound->side2[i] = 0;
1962  bound->types[i] = bctype;
1963  }
1964  }
1965  }
1966  }
1967 
1968  printf("Successfully read the mesh from the Triangle input file.\n");
1969 
1970  return(0);
1971 }
1972 
1973 
1974 
1975 
1976 int LoadMeditInput(struct FemType *data,struct BoundaryType *bound,
1977  char *prefix,int info)
1978 /* This procedure reads the mesh assuming Medit format
1979  */
1980 {
1981  int noknots = 0,noelements = 0,maxnodes,dim = 0,elementtype;
1982  int i,j,allocated;
1983  FILE *in;
1984  char *cp,line[MAXLINESIZE],nodefile[MAXFILESIZE];
1985 
1986 
1987  sprintf(nodefile,"%s.mesh",prefix);
1988  if(info) printf("Loading mesh in Medit format from file %s\n",prefix);
1989 
1990  if ((in = fopen(nodefile,"r")) == NULL) {
1991  printf("LoadElmerInput: The opening of the mesh file %s failed!\n",nodefile);
1992  return(1);
1993  }
1994 
1995  allocated = FALSE;
1996  maxnodes = 0;
1997 
1998 allocate:
1999 
2000  if(allocated) {
2001  InitializeKnots(data);
2002  data->dim = dim;
2003  data->maxnodes = maxnodes;
2004  data->noelements = noelements;
2005  data->noknots = noknots;
2006  elementtype = 300 + maxnodes;
2007 
2008  if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
2009  AllocateKnots(data);
2010  in = fopen(nodefile,"r");
2011  }
2012 
2013 
2014  for(;;) {
2015  if(Getrow(line,in,TRUE)) goto end;
2016  if(!line) goto end;
2017  if(strstr(line,"END")) goto end;
2018 
2019  if(strstr(line,"DIMENSION")) {
2020  if(Getrow(line,in,TRUE)) goto end;
2021  cp = line;
2022  dim = next_int(&cp);
2023  printf("dim = %d %s",dim,line);
2024  }
2025  else if(strstr(line,"VERTICES")) {
2026  printf("verts: %s",line);
2027 
2028  if(Getrow(line,in,TRUE)) goto end;
2029  cp = line;
2030  noknots = next_int(&cp);
2031 
2032  printf("noknots = %d %s",noknots,line);
2033 
2034  for(i=1; i <= noknots; i++) {
2035  getline;
2036 #if 0
2037  printf("i=%d line=%s",i,line);
2038 #endif
2039  if(allocated) {
2040  cp = line;
2041 #if 0
2042  printf("cp = %s",cp);
2043 #endif
2044 
2045  data->x[i] = next_real(&cp);
2046  data->y[i] = next_real(&cp);
2047  if(dim > 2) data->z[i] = next_real(&cp);
2048  }
2049  }
2050  }
2051  else if(strstr(line,"TRIANGLES")) {
2052  if(Getrow(line,in,TRUE)) goto end;
2053  cp = line;
2054  noelements = next_int(&cp);
2055 
2056  printf("noelements = %d %s",noelements,line);
2057 
2058  elementtype = 303;
2059  if(maxnodes < 3) maxnodes = 3;
2060 
2061  for(i=1; i <= noelements; i++) {
2062  getline;
2063  if(allocated) {
2064  cp = line;
2065  data->elementtypes[i] = elementtype;
2066  for(j=0;j<3;j++)
2067  data->topology[i][j] = next_int(&cp);
2068  data->material[i] = next_int(&cp);
2069  }
2070  }
2071  }
2072 #if 0
2073  else printf("unknown command: %s",line);
2074 #endif
2075  }
2076 
2077 end:
2078  fclose(in);
2079 
2080 printf("ALLOCATED=%d\n",allocated);
2081 
2082  if(!allocated) {
2083  allocated = TRUE;
2084  goto allocate;
2085  }
2086 
2087  printf("Successfully read the mesh from the Medit input file.\n");
2088 
2089  return(0);
2090 }
2091 
2092 
2093 
2094 
2095 int LoadGidInput(struct FemType *data,struct BoundaryType *bound,
2096  char *prefix,int info)
2097 /* Load the grid from GID mesh format */
2098 {
2099  int noknots,noelements,elemcode,maxnodes,material,foundsame;
2100  int mode,allocated,maxknot,nosides,sideelemtype;
2101  int boundarytype,materialtype,boundarynodes,side,parent,elemsides;
2102  int dim = 0, elemnodes = 0, elembasis = 0, elemtype = 0, bulkdone, usedmax = 0,hits;
2103  int minbulk,maxbulk,minbound,maxbound,label,debug;
2104  int *usedno = NULL, **usedelem = NULL;
2105  char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
2106  int i,j,k,n,ind,inds[MAXNODESD2],sideind[MAXNODESD1];
2107  FILE *in;
2108  Real x,y,z = 0;
2109 
2110  debug = FALSE;
2111 
2112  strcpy(filename,prefix);
2113  if ((in = fopen(filename,"r")) == NULL) {
2114  AddExtension(prefix,filename,"msh");
2115  if ((in = fopen(filename,"r")) == NULL) {
2116  printf("LoadAbaqusInput: opening of the GID-file '%s' wasn't succesfull !\n",
2117  filename);
2118  return(1);
2119  }
2120  }
2121 
2122  printf("Reading mesh from GID file %s.\n",filename);
2123  InitializeKnots(data);
2124 
2125  allocated = FALSE;
2126  maxknot = 0;
2127 
2128  /* Because the file format doesn't provide the number of elements
2129  or nodes the results are read twice but registered only in the
2130  second time. */
2131 
2132  minbulk = minbound = 1000;
2133  maxbulk = maxbound = 0;
2134 
2135 omstart:
2136 
2137  mode = 0;
2138  maxnodes = 0;
2139  noknots = 0;
2140  noelements = 0;
2141  elemcode = 0;
2142  boundarytype = 0;
2143  boundarynodes = 0;
2144  material = 0;
2145  nosides = 0;
2146  bulkdone = FALSE;
2147 
2148  for(;;) {
2149 
2150  if(Getrow(line,in,FALSE)) goto end;
2151  if(!line) goto end;
2152 
2153  if(strstr(line,"MESH")) {
2154  if(debug) printf("MESH\n");
2155 
2156  if(strstr(line,"dimension 3"))
2157  dim = 3;
2158  else if(strstr(line,"dimension 2"))
2159  dim = 2;
2160  else printf("Unknown dimension\n");
2161 
2162  if(strstr(line,"ElemType Tetrahedra"))
2163  elembasis = 500;
2164  else if(strstr(line,"ElemType Triangle"))
2165  elembasis = 300;
2166  else if(strstr(line,"ElemType Linear"))
2167  elembasis = 200;
2168  else printf("Unknown elementtype: %s\n",line);
2169 
2170  if(strstr(line,"Nnode 4"))
2171  elemnodes = 4;
2172  else if(strstr(line,"Nnode 3"))
2173  elemnodes = 3;
2174  else if(strstr(line,"Nnode 2"))
2175  elemnodes = 2;
2176  else printf("Unknown elementnode: %s\n",line);
2177 
2178  if(elemnodes > maxnodes) maxnodes = elemnodes;
2179  elemtype = elembasis + elemnodes;
2180  mode = 0;
2181 
2182  if(debug) printf("dim=%d elemtype=%d\n",dim,elemtype);
2183  }
2184  else if(strstr(line,"Coordinates")) {
2185  if(debug) printf("Start coords\n");
2186  mode = 1;
2187  }
2188  else if(strstr(line,"end coordinates")) {
2189  if(debug) printf("End coords\n");
2190  mode = 0;
2191  }
2192  else if(strstr(line,"Elements")) {
2193  if(bulkdone) {
2194  if(debug) printf("Start boundary elems\n");
2195  mode = 3;
2196  boundarytype++;
2197  }
2198  else {
2199  if(debug) printf("Start bulk elems\n");
2200  mode = 2;
2201  }
2202  }
2203  else if(strstr(line,"end elements")) {
2204  if(debug) printf("End elems\n");
2205 
2206  mode = 0;
2207  if(!bulkdone && allocated) {
2208  usedno = Ivector(1,data->noknots);
2209 
2210  for(j=1;j<=data->noknots;j++)
2211  usedno[j] = 0;
2212 
2213  for(j=1;j<=data->noelements;j++) {
2214  n = data->elementtypes[j] % 100;
2215  for(i=0;i<n;i++) {
2216  ind = data->topology[j][i];
2217  usedno[data->topology[j][i]] += 1;
2218  }
2219  }
2220 
2221  usedmax = 0;
2222  for(i=1;i<=data->noknots;i++)
2223  if(usedno[i] > usedmax) usedmax = usedno[i];
2224 
2225  for(j=1;j<=data->noknots;j++)
2226  usedno[j] = 0;
2227 
2228  usedelem = Imatrix(1,data->noknots,1,usedmax);
2229  for(j=1;j<=data->noknots;j++)
2230  for(i=1;i<=usedmax;i++)
2231  usedelem[j][i] = 0;
2232 
2233  for(j=1;j<=data->noelements;j++) {
2234  n = data->elementtypes[j] % 100;
2235  for(i=0;i<n;i++) {
2236  ind = data->topology[j][i];
2237  usedno[ind] += 1;
2238  k = usedno[ind];
2239  usedelem[ind][k] = j;
2240  }
2241  }
2242  }
2243  bulkdone = TRUE;
2244  }
2245  else if(!mode) {
2246  if(debug) printf("mode: %d %s\n",mode,line);
2247  }
2248  else if(mode) {
2249  switch (mode) {
2250 
2251  case 1:
2252  cp = line;
2253  ind = next_int(&cp);
2254  if(ind > noknots) noknots = ind;
2255 
2256  x = next_real(&cp);
2257  y = next_real(&cp);
2258  if(dim == 3) z = next_real(&cp);
2259 
2260  if(allocated) {
2261  data->x[ind] = x;
2262  data->y[ind] = y;
2263  if(dim == 3) data->z[ind] = z;
2264  }
2265  break;
2266 
2267  case 2:
2268  cp = line;
2269  ind = next_int(&cp);
2270  if(ind > noelements) noelements = ind;
2271 
2272  for(i=0;i<elemnodes;i++) {
2273  k = next_int(&cp);
2274  if(allocated) {
2275  data->topology[ind][i] = k;
2276  data->elementtypes[ind] = elemtype;
2277  data->material[ind] = 1;
2278  }
2279  }
2280  label = next_int(&cp);
2281 
2282  if(allocated) {
2283  if(label) {
2284  materialtype = label-minbulk+1;
2285  }
2286  else if(maxbound) {
2287  materialtype = maxbulk-minbulk + 2;
2288  }
2289  else {
2290  materialtype = 1;
2291  }
2292  data->material[ind] = materialtype;
2293  }
2294  else {
2295  if(label > maxbulk) maxbulk = label;
2296  if(label < minbulk) minbulk = label;
2297  }
2298 
2299  break;
2300 
2301  case 3:
2302  cp = line;
2303  ind = next_int(&cp);
2304  nosides++;
2305 
2306  for(i=0;i<elemnodes;i++) {
2307  k = next_int(&cp);
2308  inds[i] = k;
2309  }
2310  label = next_int(&cp);
2311 
2312  if(!allocated) {
2313  if(label) {
2314  if(label > maxbound) maxbound = label;
2315  if(label < minbound) minbound = label;
2316  }
2317  }
2318 
2319  if(allocated) {
2320 
2321  if(label) {
2322  boundarytype = label-minbound+1;
2323  }
2324  else if(maxbound) {
2325  boundarytype = maxbound-minbound + 2;
2326  }
2327  else {
2328  boundarytype = 1;
2329  }
2330 
2331  foundsame = FALSE;
2332  for(i=1;i<=usedno[inds[0]];i++) {
2333  parent = usedelem[inds[0]][i];
2334 
2335  elemsides = data->elementtypes[parent] % 100;
2336 
2337  for(side=0;side<elemsides;side++) {
2338 
2339  GetElementSide(parent,side,1,data,&sideind[0],&sideelemtype);
2340 
2341  if(elemnodes != sideelemtype%100) printf("LoadGidMesh: bug?\n");
2342 
2343  hits = 0;
2344  for(j=0;j<elemnodes;j++)
2345  for(k=0;k<elemnodes;k++)
2346  if(sideind[j] == inds[k]) hits++;
2347 
2348  if(hits < elemnodes) continue;
2349 
2350  if(!foundsame) {
2351  foundsame++;
2352  bound->parent[nosides] = parent;
2353  bound->side[nosides] = side;
2354  bound->parent2[nosides] = 0;
2355  bound->side2[nosides] = 0;
2356  bound->types[nosides] = boundarytype;
2357  }
2358  else if(foundsame == 1) {
2359  if(parent == bound->parent[nosides]) continue;
2360  foundsame++;
2361  bound->parent2[nosides] = parent;
2362  bound->side2[nosides] = side;
2363  }
2364  else if(foundsame > 1) {
2365  printf("Boundary %d has more than 2 parents\n",nosides);
2366  }
2367  }
2368  }
2369  if(!foundsame) {
2370  printf("Did not find parent for side %d\n",nosides);
2371  nosides--;
2372  }
2373  else {
2374  if(debug) printf("Parent of side %d is %d\n",nosides,bound->parent[nosides]);
2375  }
2376  }
2377  }
2378  }
2379  }
2380 
2381 end:
2382 
2383  if(!allocated) {
2384  rewind(in);
2385  data->noknots = noknots;
2386  data->noelements = noelements;
2387  data->maxnodes = maxnodes;
2388  data->dim = dim;
2389 
2390  if(info) {
2391  printf("Allocating for %d knots and %d %d-node elements.\n",
2392  noknots,noelements,maxnodes);
2393  printf("Initial material indexes are at interval %d to %d.\n",minbulk,maxbulk);
2394  }
2395  AllocateKnots(data);
2396 
2397  if(info) {
2398  printf("Allocating %d boundary elements\n",nosides);
2399  printf("Initial boundary indexes are at interval %d to %d.\n",minbound,maxbound);
2400  }
2401  AllocateBoundary(bound,nosides);
2402 
2403  bound->nosides = nosides;
2404  bound->created = TRUE;
2405 
2406  nosides = 0;
2407  bulkdone = FALSE;
2408  boundarytype = 0;
2409 
2410  allocated = TRUE;
2411  goto omstart;
2412  }
2413 
2414  bound->nosides = nosides;
2415  free_Ivector(usedno,1,data->noknots);
2416  free_Imatrix(usedelem,1,data->noknots,1,usedmax);
2417 
2418  if(info) printf("The mesh was loaded from file %s.\n",filename);
2419  return(0);
2420 }
2421 
2422 
2423 
2424 static void ReorderComsolNodes(int elementtype,int *topo)
2425 {
2426  int i,tmptopo[MAXNODESD2];
2427  int order404[]={1,2,4,3};
2428  int order808[]={1,2,4,3,5,6,8,7};
2429 
2430 
2431  switch (elementtype) {
2432 
2433  case 404:
2434  for(i=0;i<elementtype%100;i++)
2435  tmptopo[i] = topo[i];
2436  for(i=0;i<elementtype%100;i++)
2437  topo[i] = tmptopo[order404[i]-1];
2438  break;
2439 
2440  case 808:
2441  for(i=0;i<elementtype%100;i++)
2442  tmptopo[i] = topo[i];
2443  for(i=0;i<elementtype%100;i++)
2444  topo[i] = tmptopo[order808[i]-1];
2445  break;
2446 
2447  default:
2448  break;
2449 
2450  }
2451 }
2452 
2453 
2454 
2455 int LoadComsolMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info)
2456 /* Load the grid in Comsol Multiphysics mesh format */
2457 {
2458  int noknots,noelements,elemcode,maxnodes,material,allocated;
2459 
2460  int dim = 0, elemnodes = 0, elembasis = 0, elemtype;
2461  int debug,offset,domains,mindom,minbc,elemdim = 0;
2462  char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
2463  int i,j,k;
2464  FILE *in;
2465 
2466  strcpy(filename,prefix);
2467  if ((in = fopen(filename,"r")) == NULL) {
2468  AddExtension(prefix,filename,"mphtxt");
2469  if ((in = fopen(filename,"r")) == NULL) {
2470  printf("LoadComsolMesh: opening of the Comsol mesh file '%s' wasn't succesfull !\n",
2471  filename);
2472  return(1);
2473  }
2474  }
2475 
2476  printf("Reading mesh from Comsol mesh file %s.\n",filename);
2477  InitializeKnots(data);
2478 
2479  debug = FALSE;
2480  allocated = FALSE;
2481 
2482  mindom = 1000;
2483  minbc = 1000;
2484  offset = 1;
2485 
2486 omstart:
2487 
2488  maxnodes = 0;
2489  noknots = 0;
2490  noelements = 0;
2491  elemcode = 0;
2492  material = 0;
2493  domains = 0;
2494 
2495 
2496  for(;;) {
2497 
2498  if(Comsolrow(line,in)) goto end;
2499  if(!line) goto end;
2500 
2501  if(strstr(line,"# sdim")) {
2502  cp = line;
2503  dim = next_int(&cp);
2504  if(debug) printf("dim=%d\n",dim);
2505  }
2506 
2507  else if(strstr(line,"# number of mesh points")) {
2508  cp = line;
2509  noknots = next_int(&cp);
2510  if(debug) printf("noknots=%d\n",noknots);
2511  }
2512 
2513  else if(strstr(line,"# lowest mesh point index")) {
2514  cp = line;
2515  offset = 1 - next_int(&cp);
2516  if(debug) printf("offset=%d\n",offset);
2517  }
2518 
2519  else if(strstr(line,"# type name")) {
2520  if(strstr(line,"vtx")) elembasis = 100;
2521  else if(strstr(line,"edg")) elembasis = 200;
2522  else if(strstr(line,"tri")) elembasis = 300;
2523  else if(strstr(line,"quad")) elembasis = 400;
2524  else if(strstr(line,"tet")) elembasis = 500;
2525  else if(strstr(line,"prism")) elembasis = 700;
2526  else if(strstr(line,"hex")) elembasis = 800;
2527  else printf("unknown element type = %s",line);
2528  }
2529 
2530  else if(strstr(line,"# number of nodes per element")) {
2531  cp = line;
2532  elemnodes = next_int(&cp);
2533  if(elemnodes > maxnodes) maxnodes = elemnodes;
2534  if(debug) printf("elemnodes=%d\n",elemnodes);
2535  }
2536 
2537  else if(strstr(line,"# Mesh point coordinates")) {
2538  printf("Loading %d coordinates\n",noknots);
2539 
2540  for(i=1;i<=noknots;i++) {
2541  Comsolrow(line,in);
2542 
2543  if(allocated) {
2544  cp = line;
2545  data->x[i] = next_real(&cp);
2546  data->y[i] = next_real(&cp);
2547  if(dim == 3) data->z[i] = next_real(&cp);
2548  }
2549  }
2550  }
2551 
2552  else if(strstr(line,"# number of elements")) {
2553 
2554  cp = line;
2555  k = next_int(&cp);
2556 
2557  Comsolrow(line,in);
2558  elemtype = elemnodes + elembasis;
2559  elemdim = GetElementDimension(elemtype);
2560 
2561  if(debug) printf("Loading %d elements of type %d\n",k,elemtype);
2562  domains = noelements;
2563 
2564  for(i=1;i<=k;i++) {
2565  Comsolrow(line,in);
2566 
2567  if(dim == 3 && elembasis < 300) continue;
2568  if(dim == 2 && elembasis < 200) continue;
2569 
2570  noelements = noelements + 1;
2571  if(allocated) {
2572  data->elementtypes[noelements] = elemtype;
2573  data->material[noelements] = 1;
2574  cp = line;
2575  for(j=0;j<elemnodes;j++)
2576  data->topology[noelements][j] = next_int(&cp) + offset;
2577 
2578  if(1) ReorderComsolNodes(elemtype,data->topology[noelements]);
2579 
2580  }
2581  }
2582  }
2583 
2584  else if(strstr(line,"# number of geometric entity indices") ||
2585  strstr(line,"# number of domains")) {
2586 
2587  cp = line;
2588  k = next_int(&cp);
2589 
2590  Comsolrow(line,in);
2591  if(debug) printf("Loading %d domains for the elements\n",k);
2592 
2593  for(i=1;i<=k;i++) {
2594  Comsolrow(line,in);
2595 
2596  if(dim == 3 && elembasis < 300) continue;
2597  if(dim == 2 && elembasis < 200) continue;
2598 
2599  domains = domains + 1;
2600  cp = line;
2601  material = next_int(&cp);
2602 
2603  if(allocated) {
2604  if(elemdim < dim)
2605  material = material - minbc + 1;
2606  else
2607  material = material - mindom + 1;
2608  data->material[domains] = material;
2609  }
2610  else {
2611  if(elemdim < dim) {
2612  if(minbc > material) minbc = material;
2613  }
2614  else {
2615  if(mindom > material) mindom = material;
2616  }
2617  }
2618 
2619  }
2620  }
2621 
2622  else if(strstr(line,"#")) {
2623  if(debug) printf("Unused command: %s",line);
2624  }
2625 
2626  }
2627 
2628 end:
2629 
2630  if(!allocated) {
2631 
2632  if(noknots == 0 || noelements == 0 || maxnodes == 0) {
2633  printf("Invalid mesh consits of %d knots and %d %d-node elements.\n",
2634  noknots,noelements,maxnodes);
2635  fclose(in);
2636  return(2);
2637  }
2638 
2639  rewind(in);
2640  data->noknots = noknots;
2641  data->noelements = noelements;
2642  data->maxnodes = maxnodes;
2643  data->dim = dim;
2644 
2645  if(info) {
2646  printf("Allocating for %d knots and %d %d-node elements.\n",
2647  noknots,noelements,maxnodes);
2648  }
2649  AllocateKnots(data);
2650  allocated = TRUE;
2651 
2652  goto omstart;
2653  }
2654  fclose(in);
2655 
2656  if(info) printf("The Comsol mesh was loaded from file %s.\n\n",filename);
2658 
2659  return(0);
2660 }
2661 
2662 
2663 static int GmshToElmerType(int gmshtype)
2664 {
2665  int elmertype = 0;
2666 
2667  switch (gmshtype) {
2668 
2669  case 1:
2670  elmertype = 202;
2671  break;
2672  case 2:
2673  elmertype = 303;
2674  break;
2675  case 3:
2676  elmertype = 404;
2677  break;
2678  case 4:
2679  elmertype = 504;
2680  break;
2681  case 5:
2682  elmertype = 808;
2683  break;
2684  case 6:
2685  elmertype = 706;
2686  break;
2687  case 7:
2688  elmertype = 605;
2689  break;
2690  case 8:
2691  elmertype = 203;
2692  break;
2693  case 9:
2694  elmertype = 306;
2695  break;
2696  case 10:
2697  elmertype = 409;
2698  break;
2699  case 11:
2700  elmertype = 510;
2701  break;
2702  case 12:
2703  elmertype = 827;
2704  break;
2705  case 15:
2706  elmertype = 101;
2707  break;
2708 
2709  case 16:
2710  elmertype = 408;
2711  break;
2712  case 17:
2713  elmertype = 820;
2714  break;
2715  case 18:
2716  elmertype = 715;
2717  break;
2718  case 19:
2719  elmertype = 613;
2720  break;
2721  case 21:
2722  elmertype = 310;
2723  break;
2724 
2725  default:
2726  printf("Gmsh element %d does not have an Elmer counterpart!\n",gmshtype);
2727  }
2728 
2729  return(elmertype);
2730 }
2731 
2732 
2733 static void GmshToElmerIndx(int elemtype,int *topology)
2734 {
2735  int i=0,nodes=0,oldtopology[MAXNODESD2];
2736  int reorder, *porder;
2737 
2738  int order510[]={0,1,2,3,4,5,6,7,9,8};
2739  int order613[]={0,1,2,3,4,5,8,10,6,7,9,11,12};
2740  int order715[]={0,1,2,3,4,5,6,9,7,8,10,11,12,14,13};
2741  int order820[]={0,1,2,3,4,5,6,7,8,11,12,9,10,12,14,15,16,18,19,17};
2742 
2743 
2744  reorder = FALSE;
2745 
2746  switch (elemtype) {
2747 
2748  case 510:
2749  reorder = TRUE;
2750  porder = &order510[0];
2751  break;
2752 
2753  case 613:
2754  reorder = TRUE;
2755  porder = &order613[0];
2756  break;
2757 
2758  case 715:
2759  reorder = TRUE;
2760  porder = &order715[0];
2761  break;
2762 
2763  case 820:
2764  reorder = TRUE;
2765  porder = &order820[0];
2766  break;
2767 
2768  }
2769 
2770  if( reorder ) {
2771  nodes = elemtype % 100;
2772  for(i=0;i<nodes;i++)
2773  oldtopology[i] = topology[i];
2774  for(i=0;i<nodes;i++)
2775  topology[i] = oldtopology[porder[i]];
2776  }
2777 }
2778 
2779 
2780 static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
2781  char *filename,int info)
2782 {
2783  int noknots = 0,noelements = 0,maxnodes,elematts,nodeatts,nosides,dim;
2784  int sideind[MAXNODESD1],elemind[MAXNODESD2],tottypes,elementtype,bcmarkers;
2785  int i,j,k,dummyint,*boundnodes,allocated,*revindx,maxindx;
2786  int elemno, gmshtype, regphys, regelem, elemnodes,maxelemtype,elemdim;
2787  FILE *in;
2788  char *cp,line[MAXLINESIZE];
2789 
2790 
2791  if ((in = fopen(filename,"r")) == NULL) {
2792  printf("LoadElmerInput: The opening of the mesh file %s failed!\n",filename);
2793  return(1);
2794  }
2795  if(info) printf("Loading mesh in Gmsh format 1.0 from file %s\n",filename);
2796 
2797  allocated = FALSE;
2798  dim = 3;
2799  maxnodes = 0;
2800  maxindx = 0;
2801  maxelemtype = 0;
2802 
2803 allocate:
2804 
2805  if(allocated) {
2806  InitializeKnots(data);
2807  data->dim = dim;
2808  data->maxnodes = maxnodes;
2809  data->noelements = noelements;
2810  data->noknots = noknots;
2811 
2812  if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
2813  AllocateKnots(data);
2814 
2815  if(maxindx > noknots) {
2816  revindx = Ivector(1,maxindx);
2817  for(i=1;i<=maxindx;i++) revindx[i] = 0;
2818  }
2819  in = fopen(filename,"r");
2820  }
2821 
2822 
2823  for(;;) {
2824  if(Getrow(line,in,TRUE)) goto end;
2825  if(!line) goto end;
2826  if(strstr(line,"END")) goto end;
2827 
2828  if(strstr(line,"$NOD")) {
2829 
2830  getline;
2831  cp = line;
2832  noknots = next_int(&cp);
2833 
2834  for(i=1; i <= noknots; i++) {
2835  getline;
2836  cp = line;
2837 
2838  j = next_int(&cp);
2839  if(allocated) {
2840  if(maxindx > noknots) revindx[j] = i;
2841  data->x[i] = next_real(&cp);
2842  data->y[i] = next_real(&cp);
2843  if(dim > 2) data->z[i] = next_real(&cp);
2844  }
2845  else {
2846  maxindx = MAX(j,maxindx);
2847  }
2848  }
2849  getline;
2850  if(!strstr(line,"$ENDNOD")) {
2851  printf("NOD section should end to string ENDNOD\n");
2852  printf("%s\n",line);
2853  }
2854  }
2855 
2856  if(strstr(line,"$ELM")) {
2857  getline;
2858  cp = line;
2859  noelements = next_int(&cp);
2860 
2861  for(i=1; i <= noelements; i++) {
2862  getline;
2863 
2864  cp = line;
2865  elemno = next_int(&cp);
2866  gmshtype = next_int(&cp);
2867  regphys = next_int(&cp);
2868  regelem = next_int(&cp);
2869  elemnodes = next_int(&cp);
2870 
2871  if(allocated) {
2872  elementtype = GmshToElmerType(gmshtype);
2873  maxelemtype = MAX(maxelemtype,elementtype);
2874  data->elementtypes[i] = elementtype;
2875  data->material[i] = regphys;
2876 
2877  if(elemnodes != elementtype%100) {
2878  printf("Conflict in elementtypes %d and number of nodes %d!\n",
2879  elementtype,elemnodes);
2880  }
2881  for(j=0;j<elemnodes;j++)
2882  elemind[j] = next_int(&cp);
2883 
2884  GmshToElmerIndx(elementtype,elemind);
2885 
2886  for(j=0;j<elemnodes;j++)
2887  data->topology[i][j] = elemind[j];
2888  }
2889  else {
2890  maxnodes = MAX(elemnodes,maxnodes);
2891  }
2892 
2893  }
2894  getline;
2895  if(!strstr(line,"$ENDELM"))
2896  printf("ELM section should end to string ENDELM\n");
2897  }
2898 
2899  }
2900 
2901  end:
2902 
2903  fclose(in);
2904 
2905  if(!allocated) {
2906  allocated = TRUE;
2907  goto allocate;
2908  }
2909 
2910 
2911  if(maxindx > noknots) {
2912  printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
2913 
2914  for(i=1; i <= noelements; i++) {
2915  elementtype = data->elementtypes[i];
2916  elemnodes = elementtype % 100;
2917 
2918  for(j=0;j<elemnodes;j++) {
2919  k = data->topology[i][j];
2920  if(k <= 0 || k > maxindx)
2921  printf("index out of bounds %d\n",k);
2922  else if(revindx[k] <= 0)
2923  printf("unkonwn node %d %d in element %d\n",k,revindx[k],i);
2924  else
2925  data->topology[i][j] = revindx[k];
2926  }
2927  }
2928  free_Ivector(revindx,1,maxindx);
2929  }
2930 
2931  ElementsToBoundaryConditions(data,bound,FALSE,info);
2932 
2933  printf("Successfully read the mesh from the Gmsh input file.\n");
2934 
2935  return(0);
2936 }
2937 
2938 
2939 static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
2940  char *filename,int info)
2941 {
2942  int noknots = 0,noelements = 0,maxnodes,elematts,nodeatts,nosides,dim,notags;
2943  int sideind[MAXNODESD1],elemind[MAXNODESD2],tottypes,elementtype,bcmarkers;
2944  int i,j,k,dummyint,*boundnodes,allocated,*revindx,maxindx;
2945  int elemno, gmshtype, tagphys, taggeom, tagpart, elemnodes,maxelemtype,elemdim;
2946  int usetaggeom,tagmat,verno;
2947  FILE *in;
2948  char *cp,line[MAXLINESIZE];
2949 
2950 
2951  if ((in = fopen(filename,"r")) == NULL) {
2952  printf("LoadElmerInput: The opening of the mesh file %s failed!\n",filename);
2953  return(1);
2954  }
2955  if(info) printf("Loading mesh in Gmsh format 2.0 from file %s\n",filename);
2956 
2957  allocated = FALSE;
2958  dim = 3;
2959  maxnodes = 0;
2960  maxindx = 0;
2961  maxelemtype = 0;
2962  usetaggeom = FALSE;
2963 
2964 omstart:
2965 
2966  for(;;) {
2967  if(Getrow(line,in,FALSE)) goto end;
2968  if(!line) goto end;
2969  if(strstr(line,"$End")) continue;
2970 
2971  if(strstr(line,"$MeshFormat")) {
2972  getline;
2973  cp = line;
2974  verno = next_int(&cp);
2975 
2976  if(verno != 2) {
2977  printf("Version number is not compatible with the parser: %d\n",verno);
2978  }
2979 
2980  getline;
2981  if(!strstr(line,"$EndMeshFormat")) {
2982  printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
2983  }
2984  }
2985 
2986  else if(strstr(line,"$Nodes")) {
2987  getline;
2988  cp = line;
2989  noknots = next_int(&cp);
2990 
2991  for(i=1; i <= noknots; i++) {
2992  getline;
2993  cp = line;
2994 
2995  j = next_int(&cp);
2996  if(allocated) {
2997  if(maxindx > noknots) revindx[j] = i;
2998  data->x[i] = next_real(&cp);
2999  data->y[i] = next_real(&cp);
3000  if(dim > 2) data->z[i] = next_real(&cp);
3001  }
3002  else {
3003  maxindx = MAX(j,maxindx);
3004  }
3005  }
3006  getline;
3007  if(!strstr(line,"$EndNodes")) {
3008  printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
3009  }
3010  }
3011 
3012  else if(strstr(line,"$Elements")) {
3013  getline;
3014  cp = line;
3015  noelements = next_int(&cp);
3016 
3017  for(i=1; i <= noelements; i++) {
3018  getline;
3019 
3020  cp = line;
3021  elemno = next_int(&cp);
3022  gmshtype = next_int(&cp);
3023  elementtype = GmshToElmerType(gmshtype);
3024 
3025  if(allocated) {
3026  elemnodes = elementtype % 100;
3027  data->elementtypes[i] = elementtype;
3028 
3029  /* Point does not seem to have physical properties */
3030  notags = next_int(&cp);
3031  if(notags > 0) tagphys = next_int(&cp);
3032  if(notags > 1) taggeom = next_int(&cp);
3033  if(notags > 2) tagpart = next_int(&cp);
3034  for(j=4;j<=notags;j++)
3035  next_int(&cp);
3036 
3037  if(tagphys) {
3038  tagmat = tagphys;
3039  }
3040  else {
3041  tagmat = taggeom;
3042  usetaggeom = TRUE;
3043  }
3044 
3045  data->material[i] = tagmat;
3046  for(j=0;j<elemnodes;j++)
3047  elemind[j] = next_int(&cp);
3048 
3049  GmshToElmerIndx(elementtype,elemind);
3050 
3051  for(j=0;j<elemnodes;j++)
3052  data->topology[i][j] = elemind[j];
3053  }
3054  else {
3055  maxelemtype = MAX(maxelemtype,elementtype);
3056  }
3057 
3058  }
3059  getline;
3060  if(!strstr(line,"$EndElements")) {
3061  printf("$Elements section should end to string $EndElements:\n%s\n",line);
3062  }
3063  }
3064  else if(strstr(line,"$PhysicalNames")) {
3065  if(info) printf("Physical names are not accounted for\n");
3066  getline;
3067  cp = line;
3068  i = next_int(&cp);
3069  for(;i>0;i--) getline;
3070 
3071  getline;
3072  if(!strstr(line,"$EndPhysicalNames")) {
3073  printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
3074  }
3075  }
3076  else {
3077  if(!allocated) printf("Untreated command: %s",line);
3078  }
3079 
3080  }
3081 
3082  end:
3083 
3084 
3085  if(!allocated) {
3086  maxnodes = maxelemtype % 100;
3087  InitializeKnots(data);
3088  data->dim = dim;
3089  data->maxnodes = maxnodes;
3090  data->noelements = noelements;
3091  data->noknots = noknots;
3092 
3093  if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
3094  AllocateKnots(data);
3095 
3096  if(maxindx > noknots) {
3097  revindx = Ivector(1,maxindx);
3098  for(i=1;i<=maxindx;i++) revindx[i] = 0;
3099  }
3100  rewind(in);
3101  allocated = TRUE;
3102  goto omstart;
3103  }
3104 
3105  if(maxindx > noknots) {
3106  printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
3107 
3108  for(i=1; i <= noelements; i++) {
3109  elementtype = data->elementtypes[i];
3110  elemnodes = elementtype % 100;
3111 
3112  for(j=0;j<elemnodes;j++) {
3113  k = data->topology[i][j];
3114  if(k <= 0 || k > maxindx)
3115  printf("index out of bounds %d\n",k);
3116  else if(revindx[k] <= 0)
3117  printf("unkonwn node %d %d in element %d\n",k,revindx[k],i);
3118  else
3119  data->topology[i][j] = revindx[k];
3120  }
3121  }
3122  free_Ivector(revindx,1,maxindx);
3123  }
3124 
3125  ElementsToBoundaryConditions(data,bound,FALSE,info);
3126 
3127  /* The geometric entities are rather randomly numbered */
3128  if( usetaggeom ) {
3129  RenumberBoundaryTypes(data,bound,TRUE,0,info);
3130  RenumberMaterialTypes(data,bound,info);
3131  }
3132 
3133  if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
3134 
3135  return(0);
3136 }
3137 
3138 
3139 
3140 int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,
3141  char *prefix,int info)
3142 {
3143  FILE *in;
3144  char line[MAXLINESIZE],filename[MAXFILESIZE];
3145  int errno;
3146 
3147  sprintf(filename,"%s",prefix);
3148  if ((in = fopen(filename,"r")) == NULL) {
3149  sprintf(filename,"%s.msh",prefix);
3150  if ((in = fopen(filename,"r")) == NULL) {
3151  printf("LoadElmerInput: The opening of the mesh file %s failed!\n",filename);
3152  return(1);
3153  }
3154  }
3155 
3156  Getrow(line,in,FALSE);
3157  fclose(in);
3158 
3159  if(info) {
3160  printf("Format chosen using the first line: %s",line);
3161  }
3162 
3163  if(strstr(line,"$MeshFormat"))
3164  errno = LoadGmshInput2(data,bound,filename,info);
3165  else {
3166  printf("*****************************************************\n");
3167  printf("The $MeshFormat was not given, assuming Gmsh 1 format\n");
3168  printf("This version of Gmsh format is no longer supported\n");
3169  printf("Please use Gsmh 2 version for output\n");
3170  printf("*****************************************************\n");
3171 
3172  errno = LoadGmshInput1(data,bound,filename,info);
3173  }
3174 
3175  return(errno);
3176 }
3177 
3178 
3179 
3180 
3181 static int UnvToElmerType(int unvtype)
3182 {
3183  int elmertype;
3184 
3185  switch (unvtype) {
3186 
3187  case 11:
3188  case 21:
3189  elmertype = 202;
3190  break;
3191 
3192  case 22:
3193  case 23:
3194  elmertype = 203;
3195  break;
3196 
3197  case 41:
3198  case 51:
3199  case 61:
3200  case 74:
3201  case 81:
3202  case 91:
3203  elmertype = 303;
3204  break;
3205 
3206  case 42:
3207  case 52:
3208  case 62:
3209  case 72:
3210  case 82:
3211  case 92:
3212  elmertype = 306;
3213  break;
3214 
3215  case 43:
3216  case 53:
3217  case 63:
3218  case 73:
3219  case 93:
3220  elmertype = 310;
3221  break;
3222 
3223  case 44:
3224  case 54:
3225  case 64:
3226  case 71:
3227  case 84:
3228  case 94:
3229  elmertype = 404;
3230  break;
3231 
3232  case 45:
3233  case 46:
3234  case 56:
3235  case 66:
3236  case 76:
3237  case 96:
3238  elmertype = 408;
3239  break;
3240 
3241  case 111:
3242  elmertype = 504;
3243  break;
3244 
3245  case 118:
3246  elmertype = 510;
3247  break;
3248 
3249  case 112:
3250  elmertype = 706;
3251  break;
3252 
3253  case 113:
3254  elmertype = 715;
3255  break;
3256 
3257  case 115:
3258  elmertype = 808;
3259  break;
3260 
3261  case 116:
3262  elmertype = 820;
3263  break;
3264 
3265  default:
3266  elmertype = 0;
3267  printf("Unknown elementtype in universal mesh format: %d\n",unvtype);
3268  }
3269 
3270  return(elmertype);
3271 }
3272 
3273 
3274 static int UnvRedundantIndexes(int nonodes,int *ind)
3275 {
3276  int i,j,redundant;
3277 
3278  redundant = FALSE;
3279  for(i=0;i<nonodes;i++) {
3280  if( ind[i] == 0 ) redundant = TRUE;
3281  for(j=i+1;j<nonodes;j++)
3282  if(ind[i] == ind[j]) redundant = TRUE;
3283  }
3284  if( redundant ) {
3285  printf("Redundant element %d: ",nonodes);
3286  for(i=0;i<nonodes;i++)
3287  printf(" %d ",ind[i]);
3288  printf("\n");
3289  }
3290 
3291  return(redundant);
3292 }
3293 
3294 
3295 static void UnvToElmerIndx(int elemtype,int *topology)
3296 {
3297  int i=0,nodes=0,oldtopology[MAXNODESD2];
3298  int reorder, *porder;
3299 
3300  int order510[]={1,3,5,10,2,4,6,7,8,9};
3301  int order408[]={1,3,5,7,2,4,6,8};
3302  int order820[]={1,3,5,7,13,15,17,19,2,4,6,8,9,10,11,12,14,16,18,20};
3303 
3304 
3305  reorder = FALSE;
3306 
3307  switch (elemtype) {
3308 
3309  case 510:
3310  reorder = TRUE;
3311  porder = &order510[0];
3312  break;
3313 
3314  case 408:
3315  reorder = TRUE;
3316  porder = &order408[0];
3317  break;
3318 
3319  case 820:
3320  reorder = TRUE;
3321  porder = &order820[0];
3322  break;
3323 
3324  }
3325 
3326  if( reorder ) {
3327  nodes = elemtype % 100;
3328  for(i=0;i<nodes;i++)
3329  oldtopology[i] = topology[i];
3330  for(i=0;i<nodes;i++)
3331  topology[i] = oldtopology[porder[i]-1];
3332  }
3333 }
3334 
3335 
3336 
3337 
3338 int LoadUniversalMesh(struct FemType *data,struct BoundaryType *bound,
3339  char *prefix,int info)
3340  /* Load the grid in universal file format */
3341 {
3342  int noknots,totknots,noelements,elemcode,maxnodes;
3343  int allocated,maxknot,dim,ind,lines;
3344  int reordernodes,reorderelements,nogroups,maxnodeind,maxelem,elid,unvtype,elmertype;
3345  int nonodes,group,grouptype,mode,nopoints,nodeind,matind,physind,colorind;
3346  int debug,mingroup,maxgroup,nogroup,noentities,dummy;
3347  int *u2eind,*u2eelem;
3348  int *elementtypes;
3349  char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
3350  int i,j,k,l,n;
3351  char entityname[MAXNAMESIZE];
3352  FILE *in;
3353 
3354 
3355  strcpy(filename,prefix);
3356  if ((in = fopen(filename,"r")) == NULL) {
3357  AddExtension(prefix,filename,"unv");
3358  if ((in = fopen(filename,"r")) == NULL) {
3359  printf("LoadUniversalMesh: opening of the universal mesh file '%s' wasn't succesfull !\n",
3360  filename);
3361  return(1);
3362  }
3363  }
3364 
3365  printf("Reading mesh from universal mesh file %s.\n",filename);
3366  InitializeKnots(data);
3367 
3368  dim = 3;
3369  allocated = FALSE;
3370  reordernodes = FALSE;
3371  reorderelements = FALSE;
3372 
3373  debug = FALSE;
3374  if( debug ){
3375  elementtypes = Ivector(0,820);
3376  for(i=0;i<=820;i++) elementtypes[i] = FALSE;
3377  }
3378 
3379  maxnodeind = 0;
3380  maxnodes = 0;
3381  maxelem = 0;
3382 
3383 
3384 omstart:
3385 
3386  if(info) {
3387  if(allocated)
3388  printf("Second round for reading data\n");
3389  else
3390  printf("First round for allocating data\n");
3391  }
3392 
3393  noknots = 0;
3394  noelements = 0;
3395  nogroups = 0;
3396  nopoints = 0;
3397  group = 0;
3398 
3399 
3400  for(;;) {
3401 
3402  if(0) printf("line: %d %s\n",mode,line);
3403 
3404  nextline:
3405  if( !strncmp(line," -1",6)) mode = 0;
3406  if( Getrow(line,in,FALSE)) goto end;
3407  if(!line) goto end;
3408 
3409  if( !strncmp(line," -1",6)) mode = 0;
3410  else if( !strncmp(line," 2411",6)) mode = 2411;
3411  else if( !strncmp(line," 2412",6)) mode = 2412;
3412  else if( !strncmp(line," 2467",6)) mode = 2467;
3413  else if( !strncmp(line," 2435",6)) mode = 2435;
3414  else if( !strncmp(line," 781",6)) mode = 781;
3415  else if( !strncmp(line," 780",6)) mode = 780;
3416  else if( allocated && strncmp(line," ",6)) printf("Unknown mode: %s",line);
3417 
3418 
3419  if(debug && mode) printf("Current mode is %d\n",mode);
3420 
3421  /* node definition */
3422  if( mode == 2411 || mode == 781 ) {
3423  if(debug) printf("Reading nodes in mode %d\n",mode);
3424  for(;;) {
3425  GetrowDouble(line,in);
3426  if( !strncmp(line," -1",6)) goto nextline;
3427 
3428  cp = line;
3429  nodeind = next_int(&cp);
3430  /* Three other fields omitted: two coordinate systems and color */
3431  noknots += 1;
3432  GetrowDouble(line,in);
3433 
3434  if(allocated) {
3435  if(reordernodes) {
3436  if(u2eind[nodeind])
3437  printf("Reordering node %d already set (%d vs. %d)\n",
3438  nodeind,u2eind[nodeind],noknots);
3439  else
3440  u2eind[nodeind] = noknots;
3441  }
3442 
3443  cp = line;
3444  data->x[noknots] = next_real(&cp);
3445  data->y[noknots] = next_real(&cp);
3446  data->z[noknots] = next_real(&cp);
3447  }
3448  else {
3449  if(nodeind != noknots) reordernodes = TRUE;
3450  maxnodeind = MAX(maxnodeind,nodeind);
3451  }
3452  }
3453  }
3454 
3455  if( mode == 2412 ) {
3456  if(debug) printf("Reading elements from field %d\n",mode);
3457  for(;;) {
3458  Getrow(line,in,FALSE);
3459  if( !strncmp(line," -1",6)) goto nextline;
3460 
3461  noelements += 1;
3462  cp = line;
3463  elid = next_int(&cp);
3464  unvtype = next_int(&cp);
3465  physind = next_int(&cp);
3466  matind = next_int(&cp);
3467  colorind = next_int(&cp);
3468  nonodes = next_int(&cp);
3469 
3470  if (!allocated) {
3471  maxnodes = MAX(maxnodes, nonodes);
3472  if(elid != noelements) reorderelements = TRUE;
3473  maxelem = MAX(maxelem, elid);
3474  }
3475 
3476  if(unvtype == 11 || unvtype == 21 || unvtype == 22 ) Getrow(line,in,FALSE);
3477  Getrow(line,in,FALSE);
3478  cp = line;
3479 
3480  elmertype = UnvToElmerType(unvtype);
3481  if(!elmertype) {
3482  printf("Unknown elementtype %d %d %d %d %d %d\n",
3483  elid,unvtype,physind,matind,colorind,nonodes);
3484  printf("line: %s\n",line);
3485  bigerror("done");
3486  }
3487 
3488  if(elmertype == 510 )
3489  lines = 1;
3490  else if(elmertype == 820 )
3491  lines = 2;
3492  else
3493  lines = 0;
3494 
3495  if(allocated) {
3496  if(reorderelements) u2eelem[elid] = noelements;
3497 
3498  if(debug && !elementtypes[elmertype]) {
3499  elementtypes[elmertype] = TRUE;
3500  printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
3501  }
3502 
3503  if(elmertype % 100 != nonodes) {
3504  printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
3505  nonodes = elmertype % 100;
3506  }
3507 
3508 
3509  data->elementtypes[noelements] = elmertype;
3510  for(i=0;i<nonodes;i++) {
3511  if( lines > 0 && i >= 8 ) {
3512  if( i%8 == 0 ) {
3513  Getrow(line,in,FALSE);
3514  cp = line;
3515  }
3516  }
3517  data->topology[noelements][i] = next_int(&cp);
3518  }
3519 
3520  UnvRedundantIndexes(nonodes,data->topology[noelements]);
3521 
3522  UnvToElmerIndx(elmertype,data->topology[noelements]);
3523 
3524  /* should this be physical property or material property? */
3525  data->material[noelements] = physind;
3526  }
3527  else {
3528  for(i=1;i<=lines;i++)
3529  Getrow(line,in,FALSE);
3530  }
3531  }
3532  }
3533 
3534 
3535  if( mode == 780 ) {
3536  int physind2,matind2;
3537 
3538  if(debug) printf("Reading elements from field %d\n",mode);
3539  for(;;) {
3540  Getrow(line,in,FALSE);
3541  if( !strncmp(line," -1",6)) goto nextline;
3542 
3543  noelements += 1;
3544  cp = line;
3545  elid = next_int(&cp);
3546  unvtype = next_int(&cp);
3547 
3548  physind = next_int(&cp);
3549  physind2 = next_int(&cp);
3550  matind = next_int(&cp);
3551  matind2 = next_int(&cp);
3552  colorind = next_int(&cp);
3553  nonodes = next_int(&cp);
3554 
3555  if (!allocated) {
3556  maxnodes = MAX(maxnodes, nonodes);
3557  if(elid != noelements) reorderelements = TRUE;
3558  maxelem = MAX(maxelem, elid);
3559  }
3560 
3561  if(unvtype == 11 || unvtype == 21) Getrow(line,in,FALSE);
3562  Getrow(line,in,FALSE);
3563  cp = line;
3564  if(allocated) {
3565  if(reorderelements) u2eelem[elid] = noelements;
3566 
3567  elmertype = UnvToElmerType(unvtype);
3568 
3569  if(debug && !elementtypes[elmertype]) {
3570  elementtypes[elmertype] = TRUE;
3571  printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
3572  }
3573 
3574  if(elmertype % 100 != nonodes) {
3575  printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
3576  nonodes = elmertype % 100;
3577  }
3578 
3579  data->elementtypes[noelements] = elmertype;
3580  for(i=0;i<nonodes;i++)
3581  data->topology[noelements][i] = next_int(&cp);
3582 
3583  UnvRedundantIndexes(nonodes,data->topology[noelements]);
3584 
3585  UnvToElmerIndx(elmertype,data->topology[noelements]);
3586 
3587  /* should this be physical property or material property? */
3588  data->material[noelements] = physind;
3589  }
3590  }
3591  }
3592 
3593  if( mode == 2467 || mode == 2435) {
3594  if(debug) printf("Reading groups in mode %d\n",mode);
3595 
3596  for(;;) {
3597  Getrow(line,in,FALSE);
3598  if( !strncmp(line," -1",6)) goto nextline;
3599 
3600  cp = line;
3601  nogroup = next_int(&cp);
3602  for(i=1;i<=6;i++)
3603  dummy = next_int(&cp);
3604  noentities = next_int(&cp);
3605 
3606  Getrow(line,in,FALSE);
3607  if( !strncmp(line," -1",6)) goto nextline;
3608 
3609  /* Used for the empty group created by salome */
3610  /* if( mode == 2467 && !strncmp(line," ",12)) continue; */
3611 
3612  group++;
3613  k = 0;
3614  if(allocated) {
3615  sscanf(line,"%s",entityname);
3616  strcpy(data->bodyname[group],entityname);
3617  data->bodynamesexist = TRUE;
3618  data->boundarynamesexist = TRUE;
3619 
3620  if(info) printf("Reading group %d with %d entities: %s\n",
3621  nogroup,noentities,entityname);
3622  }
3623  if(noentities == 0) Getrow(line,in,FALSE);
3624 
3625  for(i=0;i<noentities;i++) {
3626  if(i%2 == 0) {
3627  Getrow(line,in,FALSE);
3628  if( !strncmp(line," -1",6)) goto nextline;
3629  cp = line;
3630  }
3631 
3632  grouptype = next_int(&cp);
3633  ind = next_int(&cp);
3634  dummy = next_int(&cp);
3635  dummy = next_int(&cp);
3636 
3637  if(ind == 0) continue;
3638 
3639  if( grouptype == 8 ) {
3640  if(allocated) {
3641  if(reorderelements) ind = u2eelem[ind];
3642  elemcode = data->elementtypes[ind];
3643  data->material[ind] = group;
3644  }
3645  }
3646  else if(grouptype == 7) {
3647  nopoints += 1;
3648  if(allocated) {
3649  elemcode = 101;
3650  data->material[noelements+nopoints] = group;
3651  data->elementtypes[noelements+nopoints] = elemcode;
3652  data->topology[noelements+nopoints][0] = ind;
3653  }
3654  }
3655  else {
3656  }
3657  }
3658  if(k && allocated && info)
3659  printf("Found new group %d with elements %d: %s\n",group,elemcode,entityname);
3660 
3661  }
3662  }
3663 
3664  }
3665 
3666 end:
3667 
3668  exit;
3669  if(info) printf("Done reading\n");
3670 
3671 
3672  if(!allocated) {
3673 
3674  if(reordernodes) {
3675  if(info) printf("Reordering %d nodes with indexes up to %d\n",noknots,maxnodeind);
3676  u2eind = Ivector(1,maxnodeind);
3677  for(i=1;i<=maxnodeind;i++) u2eind[i] = 0;
3678  }
3679  if(reorderelements) {
3680  if(info) printf("Reordering %d elements with indexes up to %d\n",noelements,maxelem);
3681  u2eelem = Ivector(1,maxelem);
3682  for(i=1;i<=maxelem;i++) u2eelem[i] = 0;
3683  }
3684 
3685  if(noknots == 0 || noelements == 0 || maxnodes == 0) {
3686  printf("Invalid mesh consits of %d knots and %d %d-node elements.\n",
3687  noknots,noelements,maxnodes);
3688  fclose(in);
3689  return(2);
3690  }
3691 
3692  rewind(in);
3693  totknots = noknots;
3694  data->noknots = noknots;
3695  data->noelements = noelements + nopoints;
3696  data->maxnodes = maxnodes;
3697  data->dim = dim;
3698 
3699  if(info) {
3700  printf("Allocating for %d knots and %d %d-node elements in %d dims.\n",
3701  noknots,noelements,maxnodes,dim);
3702  }
3703  AllocateKnots(data);
3704  allocated = TRUE;
3705 
3706  goto omstart;
3707  }
3708  fclose(in);
3709 
3710 
3711  if(reordernodes) {
3712  for(j=1;j<=noelements;j++)
3713  for(i=0;i<data->elementtypes[j]%100;i++)
3714  data->topology[j][i] = u2eind[data->topology[j][i]];
3715  free_Ivector(u2eind,1,maxnodeind);
3716  }
3717  if(reorderelements) {
3718  free_Ivector(u2eelem,1,maxelem);
3719  }
3720 
3721 
3722  mingroup = maxgroup = data->material[1];
3723  for(i=1;i<=data->noelements;i++) {
3724  mingroup = MIN( mingroup, data->material[i]);
3725  maxgroup = MAX( maxgroup, data->material[i]);
3726  }
3727  if(info) printf("The group interval is [%d,%d]\n",mingroup,maxgroup);
3728  if(mingroup == 0) {
3729  if(info) {
3730  if(!maxgroup) printf("No material groups were successfully applied\n");
3731  printf("Unset elements were given material index %d\n",maxgroup+1);
3732  }
3733  for(i=1;i<=data->noelements;i++)
3734  if(data->material[i] == 0) data->material[i] = maxgroup + 1;
3735  }
3736 
3737  ElementsToBoundaryConditions(data,bound,TRUE,info);
3738 
3739  if(info) printf("The Universal mesh was loaded from file %s.\n\n",filename);
3740 
3741  return(0);
3742 }
3743 
3744 
3745 
3746 
3747 int LoadCGsimMesh(struct FemType *data,char *prefix,int info)
3748 /* Load the mesh from postprocessing format of CGsim */
3749 {
3750  int noknots,noelements,maxnodes,material,allocated,dim,debug,thismat,thisknots,thiselems;
3751  char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
3752  int i,j,inds[MAXNODESD2],savedofs;
3753  Real dummyreal;
3754  FILE *in;
3755 
3756 
3757  strcpy(filename,prefix);
3758  if ((in = fopen(filename,"r")) == NULL) {
3759  AddExtension(prefix,filename,"plt");
3760  if ((in = fopen(filename,"r")) == NULL) {
3761  printf("LoadCGsimMesh: opening of the CGsim mesh file '%s' wasn't succesfull !\n",
3762  filename);
3763  return(1);
3764  }
3765  }
3766 
3767  printf("Reading mesh from CGsim mesh file %s.\n",filename);
3768  InitializeKnots(data);
3769 
3770  debug = FALSE;
3771  allocated = FALSE;
3772  savedofs = FALSE;
3773 
3774 omstart:
3775 
3776  maxnodes = 4;
3777  noknots = 0;
3778  noelements = 0;
3779  material = 0;
3780  dim = 2;
3781  thismat = 0;
3782 
3783 
3784  for(;;) {
3785 
3786 
3787  if(Getrow(line,in,FALSE)) goto end;
3788  if(!line) goto end;
3789 
3790  cp = strstr(line,"ZONE");
3791  if(!cp) continue;
3792 
3793 
3794  thismat += 1;
3795  cp = strstr(line," N=");
3796  cp += 3;
3797  thisknots = next_int(&cp);
3798 
3799  cp = strstr(line,",E=");
3800  cp += 3;
3801  thiselems = next_int(&cp);
3802 
3803  if(debug) {
3804  printf("%s",line);
3805  printf("thismat = %d knots = %d elems = %d\n",thismat,thisknots,thiselems);
3806  }
3807 
3808  for(i=1;i<=thisknots;i++) {
3809  getline;
3810 
3811  if(allocated) {
3812  cp = line;
3813  data->x[noknots+i] = next_real(&cp);
3814  data->y[noknots+i] = next_real(&cp);
3815  data->z[noknots+i] = 0.0;
3816 
3817  if(savedofs == 1) {
3818  for(j=1;j<=4;j++)
3819  dummyreal = next_real(&cp);
3820  data->dofs[1][noknots+i] = next_real(&cp);
3821  }
3822  else if(savedofs == 5) {
3823  for(j=1;j<=5;j++)
3824  data->dofs[j][noknots+i] = next_real(&cp);
3825  }
3826 
3827  }
3828  }
3829 
3830  for(i=1;i<=thiselems;i++) {
3831  getline;
3832 
3833  if(allocated) {
3834  cp = line;
3835  for(j=0;j<4;j++)
3836  inds[j] = next_int(&cp);
3837  for(j=0;j<4;j++)
3838  data->topology[noelements+i][j] = inds[j]+noknots;
3839  if(inds[2] == inds[3])
3840  data->elementtypes[noelements+i] = 303;
3841  else
3842  data->elementtypes[noelements+i] = 404;
3843  data->material[noelements+i] = thismat;
3844  }
3845  }
3846 
3847  noknots += thisknots;
3848  noelements += thiselems;
3849  }
3850 
3851  end:
3852 
3853  if(!allocated) {
3854  if(noknots == 0 || noelements == 0 || maxnodes == 0) {
3855  printf("Invalid mesh consits of %d knots and %d %d-node elements.\n",
3856  noknots,noelements,maxnodes);
3857  fclose(in);
3858  return(2);
3859  }
3860 
3861  rewind(in);
3862  data->noknots = noknots;
3863  data->noelements = noelements;
3864  data->maxnodes = maxnodes;
3865  data->dim = dim;
3866 
3867 
3868  if(info) {
3869  printf("Allocating for %d knots and %d %d-node elements.\n",
3870  noknots,noelements,maxnodes);
3871  }
3872  AllocateKnots(data);
3873 
3874  if(savedofs == 1) {
3875  CreateVariable(data,1,1,0.0,"Temperature",FALSE);
3876  }
3877  else if(savedofs == 5) {
3878  CreateVariable(data,1,1,0.0,"dTdX",FALSE);
3879  CreateVariable(data,2,1,0.0,"dTdY",FALSE);
3880  CreateVariable(data,3,1,0.0,"Qx",FALSE);
3881  CreateVariable(data,4,1,0.0,"Qy",FALSE);
3882  CreateVariable(data,5,1,0.0,"Temperature",FALSE);
3883  }
3884 
3885  allocated = TRUE;
3886  goto omstart;
3887  }
3888  fclose(in);
3889 
3890  if(info) printf("The CGsim mesh was loaded from file %s.\n\n",filename);
3891  return(0);
3892 }
3893 
3894