EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
egmain.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file egmain.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 /****************************************************************************
27 * *
28 * Elmergrid *
29 * *
30 * This program creates very easily a structured 2D meshes with BCs. *
31 * The element types include 4, 5, 8, 9, 12 and 16-node rectangles and *
32 * 3, 6 and 10-node triangles. There is also limited 3D functionality *
33 * with 8, 20 and 27-node cubes and 6-node prisms. *
34 * *
35 * The program may also be used as a mesh import and export utility. It *
36 * is able to read several different formats and writes mainly Elmer input *
37 * and output formats. The meshes may also be given some simple operations. *
38 * *
39 * Note: this software was initially part of my first fem implementation *
40 * the Pirfem code, then later called Quickmesh, and finally renamed to *
41 * Elmergrid. The code has never been designed and with new features the *
42 * code has eventually become very dirty and does not present my view of *
43 * good programming. *
44 * *
45 ****************************************************************************/
46 
47 
48 #include <stdio.h>
49 #include <stddef.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <ctype.h>
53 #include <math.h>
54 
55 #define EXE_MODE 0
56 #define LIB_MODE 1
57 
58 
59 #include "egutils.h"
60 #include "egdef.h"
61 #include "egtypes.h"
62 #include "egmesh.h"
63 #include "egnative.h"
64 #include "egconvert.h"
65 
66 
67 #if EXE_MODE
68 #include "egoutput.h"
69 #else
70 #include "src/meshtype.h"
71 #endif
72 
73 
74 static struct GridType *grids;
75 static struct FemType data[MAXCASES];
77 static struct ElmergridType eg;
78 static char Filename[MAXFILESIZE];
79 static int Inmethod;
80 
81 
83 
84 const char *IOmethods[] = {
85  /*0*/ "EG",
86  /*1*/ "ELMERGRID",
87  /*2*/ "ELMERSOLVER",
88  /*3*/ "ELMERPOST",
89  /*4*/ "ANSYS",
90  /*5*/ "IDEAS",
91  /*6*/ "NASTRAN",
92  /*7*/ "FIDAP",
93  /*8*/ "UNV",
94  /*9*/ "COMSOL",
95  /*10*/ "FIELDVIEW",
96  /*11*/ "TRIANGLE",
97  /*12*/ "MEDIT",
98  /*13*/ "GID",
99  /*14*/ "GMSH",
100  /*15*/ "PARTITIONED",
101  /*16*/ "CGSIM",
102 };
103 
104 
105 
106 int InlineParameters(struct ElmergridType *eg,int argc,char *argv[],const char *IOmethods[],int first,int info)
107 {
108  int arg,i,dim;
109  char command[MAXLINESIZE];
110 
111  dim = eg->dim;
112 
113  /* Type of input file */
114  if(first > 3) {
115  for(i=0;i<MAXLINESIZE;i++) command[i] = ' ';
116 
117  strcpy(command,argv[1]);
118  for(i=0;i<MAXLINESIZE;i++) command[i] = toupper(command[i]);
119  for(i=0;i<=MAXFORMATS;i++) {
120  if(strstr(command,IOmethods[i])) {
121  eg->inmethod = i;
122  break;
123  }
124  }
125  if(i>MAXFORMATS) eg->inmethod = atoi(argv[1]);
126 
127 
128  /* Type of output file (fewer options) */
129  strcpy(command,argv[2]);
130  for(i=0;i<MAXLINESIZE;i++) command[i] = toupper(command[i]);
131  for(i=1;i<=MAXFORMATS;i++) {
132  if(strstr(command,IOmethods[i])) {
133  eg->outmethod = i;
134  break;
135  }
136  }
137  if(i>MAXFORMATS) eg->outmethod = atoi(argv[2]);
138 
139  /* Name of output file */
140  strcpy(eg->filesin[0],argv[3]);
141  strcpy(eg->filesout[0],eg->filesin[0]);
142  strcpy(eg->mapfile,eg->filesin[0]);
143  }
144 
145 
146  /* The optional inline parameters */
147 
148  for(arg=first;arg <argc; arg++) {
149 
150  if(strcmp(argv[arg],"-silent") == 0) {
151  eg->silent = TRUE;
152  info = FALSE;
153  }
154 
155  if(strcmp(argv[arg],"-in") ==0 ) {
156  if(arg+1 >= argc) {
157  printf("The secondary input file name is required as a parameter\n");
158  return(1);
159  }
160  else {
161  strcpy(eg->filesin[eg->nofilesin],argv[arg+1]);
162  printf("A secondary input file %s will be loaded.\n",eg->filesin[eg->nofilesin]);
163  eg->nofilesin++;
164  }
165  }
166 
167  if(strcmp(argv[arg],"-out") == 0) {
168  if(arg+1 >= argc) {
169  printf("The output name is required as a parameter\n");
170  return(2);
171  }
172  else {
173  strcpy(eg->filesout[0],argv[arg+1]);
174  }
175  }
176 
177  if(strcmp(argv[arg],"-decimals") == 0) {
178  eg->decimals = atoi(argv[arg+1]);
179  }
180 
181  if(strcmp(argv[arg],"-triangles") ==0) {
182  eg->triangles = TRUE;
183  printf("The rectangles will be split to triangles.\n");
184  if(arg+1 < argc) {
185  if(strcmp(argv[arg+1],"-")) {
186  eg->triangleangle = atof(argv[arg+1]);
187  }
188  }
189  }
190 
191  if(strcmp(argv[arg],"-merge") == 0) {
192  if(arg+1 >= argc) {
193  printf("Give a parameter for critical distance.\n");
194  return(3);
195  }
196  else {
197  eg->merge = TRUE;
198  eg->cmerge = atof(argv[arg+1]);
199  }
200  }
201 
202  if(strcmp(argv[arg],"-relh") == 0) {
203  if(arg+1 >= argc) {
204  printf("Give a relative mesh density related to the specifications\n");
205  return(3);
206  }
207  else {
208  eg->relh = atof(argv[arg+1]);
209  }
210  }
211 
212  if(strcmp(argv[arg],"-order") == 0) {
213  if(arg+dim >= argc) {
214  printf("Give %d parameters for the order vector.\n",dim);
215  return(4);
216  }
217  else {
218  eg->order = TRUE;
219  eg->corder[0] = atof(argv[arg+1]);
220  eg->corder[1] = atof(argv[arg+2]);
221  if(dim==3) eg->corder[2] = atof(argv[arg+3]);
222  }
223  }
224 
225  if(strcmp(argv[arg],"-autoorder") == 0) {
226  eg->order = 2;
227  }
228 
229  if(strcmp(argv[arg],"-halo") == 0) {
230  eg->partitionhalo = TRUE;
231  }
232  if(strcmp(argv[arg],"-indirect") == 0) {
233  eg->partitionindirect = TRUE;
234  }
235  if(strcmp(argv[arg],"-metisorder") == 0) {
236  eg->order = 3;
237  }
238  if(strcmp(argv[arg],"-centralize") == 0) {
239  eg->center = TRUE;
240  }
241  if(strcmp(argv[arg],"-scale") == 0) {
242  if(arg+dim >= argc) {
243  printf("Give %d parameters for the scaling.\n",dim);
244  return(5);
245  }
246  else {
247  eg->scale = TRUE;
248  eg->cscale[0] = atof(argv[arg+1]);
249  eg->cscale[1] = atof(argv[arg+2]);
250  if(dim==3) eg->cscale[2] = atof(argv[arg+3]);
251  }
252  }
253 
254  if(strcmp(argv[arg],"-translate") == 0) {
255  if(arg+dim >= argc) {
256  printf("Give %d parameters for the translate vector.\n",dim);
257  return(6);
258  }
259  else {
260  eg->translate = TRUE;
261  eg->ctranslate[0] = atof(argv[arg+1]);
262  eg->ctranslate[1] = atof(argv[arg+2]);
263  if(dim == 3) eg->ctranslate[2] = atof(argv[arg+3]);
264  }
265  }
266 
267  if(strcmp(argv[arg],"-saveinterval") == 0) {
268  if(arg+dim >= argc) {
269  printf("Give min, max and step for the interval.\n");
270  return(7);
271  }
272  else {
273  eg->saveinterval[0] = atoi(argv[arg+1]);
274  eg->saveinterval[1] = atoi(argv[arg+2]);
275  eg->saveinterval[2] = atoi(argv[arg+3]);
276  }
277  }
278 
279  if(strcmp(argv[arg],"-rotate") == 0 || strcmp(argv[arg],"-rotate") == 0) {
280  if(arg+dim >= argc) {
281  printf("Give three parameters for the rotation angles.\n");
282  return(8);
283  }
284  else {
285  eg->rotate = TRUE;
286  eg->crotate[0] = atof(argv[arg+1]);
287  eg->crotate[1] = atof(argv[arg+2]);
288  eg->crotate[2] = atof(argv[arg+3]);
289  }
290  }
291 
292  if(strcmp(argv[arg],"-clone") == 0) {
293  if(arg+dim >= argc) {
294  printf("Give the number of clones in each %d directions.\n",dim);
295  return(9);
296  }
297  else {
298  eg->clone[0] = atoi(argv[arg+1]);
299  eg->clone[1] = atoi(argv[arg+2]);
300  if(dim == 3) eg->clone[2] = atoi(argv[arg+3]);
301  }
302  }
303  if(strcmp(argv[arg],"-clonesize") == 0) {
304  if(arg+dim >= argc) {
305  printf("Give the clone size in each %d directions.\n",dim);
306  return(10);
307  }
308  else {
309  eg->clonesize[0] = atof(argv[arg+1]);
310  eg->clonesize[1] = atof(argv[arg+2]);
311  if(dim == 3) eg->clonesize[2] = atof(argv[arg+3]);
312  }
313  }
314 
315  if(strcmp(argv[arg],"-unite") == 0) {
316  eg->unitemeshes = TRUE;
317  printf("The meshes will be united.\n");
318  }
319 
320  if(strcmp(argv[arg],"-names") == 0) {
321  eg->usenames = TRUE;
322  printf("Names will be conserved when possible\n");
323  }
324 
325  if(strcmp(argv[arg],"-removelowdim") == 0) {
326  eg->removelowdim = TRUE;
327  printf("Lower dimensional boundaries will be removed\n");
328  }
329 
330  if(strcmp(argv[arg],"-removeunused") == 0) {
331  eg->removeunused = TRUE;
332  printf("Nodes that do not appear in any element will be removed\n");
333  }
334 
335  if(strcmp(argv[arg],"-autoclean") == 0) {
336  eg->removelowdim = TRUE;
337  eg->bulkorder = TRUE;
338  eg->boundorder = TRUE;
339  eg->removeunused = TRUE;
340  printf("Lower dimensional boundaries will be removed\n");
341  printf("Materials and boundaries will be renumbered\n");
342  printf("Nodes that do not appear in any element will be removed\n");
343  }
344 
345  if(strcmp(argv[arg],"-polar") == 0) {
346  eg->polar = TRUE;
347  printf("Making transformation to polar coordinates.\n");
348  if(arg+1 >= argc) {
349  printf("The preferred radius is required as a parameter\n");
350  eg->polarradius = 1.0;
351  }
352  else {
353  eg->polarradius = atoi(argv[arg+1]);
354  }
355  }
356 
357  if(strcmp(argv[arg],"-cylinder") == 0) {
358  eg->cylinder = TRUE;
359  printf("Making transformation from cylindrical to cartesian coordinates.\n");
360  }
361 
362  if(strcmp(argv[arg],"-reduce") == 0) {
363  if(arg+2 >= argc) {
364  printf("Give two material for the interval.\n");
365  return(12);
366  }
367  else {
368  eg->reduce = TRUE;
369  eg->reducemat1 = atoi(argv[arg+1]);
370  eg->reducemat2 = atoi(argv[arg+2]);
371  }
372  }
373  if(strcmp(argv[arg],"-increase") == 0) {
374  eg->increase = TRUE;
375  }
376  if(strcmp(argv[arg],"-bulkorder") == 0) {
377  eg->bulkorder = TRUE;
378  }
379  if(strcmp(argv[arg],"-boundorder") == 0) {
380  eg->boundorder = TRUE;
381  }
382  if(strcmp(argv[arg],"-pelem") == 0) {
383  for(i=arg+1;i<argc && strncmp(argv[i],"-",1); i++)
384  eg->pelemmap[3*eg->pelems+i-1-arg] = atoi(argv[i]);
385  eg->pelems++;
386  }
387  if(strcmp(argv[arg],"-belem") == 0) {
388  for(i=arg+1;i<argc && strncmp(argv[i],"-",1); i++)
389  eg->belemmap[3*eg->belems+i-1-arg] = atoi(argv[i]);
390  eg->belems++;
391  }
392  if(strcmp(argv[arg],"-partition") == 0) {
393  if(arg+dim >= argc) {
394  printf("The number of partitions in %d dims is required as parameters.\n",dim);
395  return(13);
396  }
397  else {
398  eg->partitions = 1;
399  eg->partdim[0] = atoi(argv[arg+1]);
400  eg->partdim[1] = atoi(argv[arg+2]);
401  if(dim == 3) eg->partdim[2] = atoi(argv[arg+3]);
402  eg->partitions = 1;
403  for(i=0;i<3;i++) {
404  if(eg->partdim[i] == 0) eg->partdim[i] = 1;
405  eg->partitions *= eg->partdim[i];
406  }
407  eg->partopt = 0;
408  if(arg+4 < argc)
409  if(argv[arg+4][0] != '-') eg->partopt = atoi(argv[arg+4]);
410 
411  printf("The mesh will be partitioned with simple division to %d partitions.\n",
412  eg->partitions);
413  }
414  }
415  if(strcmp(argv[arg],"-partorder") == 0) {
416  if(arg+dim >= argc) {
417  printf("Give %d parameters for the order vector.\n",dim);
418  return(14);
419  }
420  else {
421  eg->partorder = 1;
422  eg->partcorder[0] = atof(argv[arg+1]);
423  eg->partcorder[1] = atof(argv[arg+2]);
424  if(dim==3) eg->partcorder[2] = atof(argv[arg+3]);
425  }
426  }
427 
428  if(strcmp(argv[arg],"-metis") == 0) {
429 #if HAVE_METIS
430  if(arg+1 >= argc) {
431  printf("The number of partitions is required as a parameter\n");
432  return(15);
433  }
434  else {
435  eg->metis = atoi(argv[arg+1]);
436  printf("The mesh will be partitioned with Metis to %d partitions.\n",eg->metis);
437  eg->partopt = 0;
438  if(arg+2 < argc)
439  if(argv[arg+2][0] != '-') eg->partopt = atoi(argv[arg+2]);
440  }
441 #else
442  printf("This version of ElmerGrid was compiled without Metis library!\n");
443 #endif
444  }
445 
446  if(strcmp(argv[arg],"-periodic") == 0) {
447  if(arg+dim >= argc) {
448  printf("Give the periodic coordinate directions (e.g. 1 1 0)\n");
449  return(16);
450  }
451  else {
452  eg->periodicdim[0] = atoi(argv[arg+1]);
453  eg->periodicdim[1] = atoi(argv[arg+2]);
454  if(dim == 3) eg->periodicdim[2] = atoi(argv[arg+3]);
455  }
456  }
457 
458  if(strcmp(argv[arg],"-discont") == 0) {
459  if(arg+1 >= argc) {
460  printf("Give the discontinuous boundary conditions.\n");
461  return(17);
462  }
463  else {
464  eg->discontbounds[eg->discont] = atoi(argv[arg+1]);
465  eg->discont++;
466  }
467  }
468 
469  if(strcmp(argv[arg],"-connect") == 0) {
470  if(arg+1 >= argc) {
471  printf("Give the connected boundary conditions.\n");
472  return(10);
473  }
474  else {
475  eg->connectbounds[eg->connect] = atoi(argv[arg+1]);
476  eg->connect++;
477  }
478  }
479 
480  if(strcmp(argv[arg],"-boundbound") == 0) {
481  for(i=arg+1;i<=arg+3 && i<argc; i++) {
482  eg->boundbound[3*eg->boundbounds+i-(1+arg)] = atoi(argv[i]);
483  if((i-arg)%3 == 0) eg->boundbounds++;
484  }
485  }
486  if(strcmp(argv[arg],"-bulkbound") == 0) {
487  for(i=arg+1;i<=arg+3 && i<argc; i++) {
488  eg->bulkbound[3*eg->bulkbounds+i-(1+arg)] = atoi(argv[i]);
489  if((i-arg)%3 == 0) eg->bulkbounds++;
490  }
491  }
492  if(strcmp(argv[arg],"-boundtype") == 0) {
493  for(i=arg+1;i<argc && strncmp(argv[i],"-",1); i++)
494  eg->sidemap[3*eg->sidemappings+i-1-arg] = atoi(argv[i]);
495  eg->sidemappings++;
496  }
497  if(strcmp(argv[arg],"-bulktype") == 0) {
498  for(i=arg+1;i<argc && strncmp(argv[i],"-",1); i++)
499  eg->bulkmap[3*eg->bulkmappings+i-1-arg] = atoi(argv[i]);
500  eg->bulkmappings++;
501  }
502 
503  if(strcmp(argv[arg],"-layer") == 0) {
504  if(arg+4 >= argc) {
505  printf("Give four parameters for the layer: boundary, elements, thickness, ratio.\n");
506  return(18);
507  }
508  else if(eg->layers == MAXBOUNDARIES) {
509  printf("There can only be %d layers, sorry.\n",MAXBOUNDARIES);
510  return(19);
511  }
512  else {
513  eg->layerbounds[eg->layers] = atoi(argv[arg+1]);
514  eg->layernumber[eg->layers] = atoi(argv[arg+2]);
515  eg->layerthickness[eg->layers] = atof(argv[arg+3]);
516  eg->layerratios[eg->layers] = atof(argv[arg+4]);
517  eg->layerparents[eg->layers] = 0;
518  eg->layers++;
519  }
520  }
521 
522  if(strcmp(argv[arg],"-layermove") == 0) {
523  if(arg+1 >= argc) {
524  printf("Give maximum number of Jacobi filters.\n");
525  return(20);
526  }
527  else {
528  eg->layermove = atoi(argv[arg+1]);
529  }
530  }
531 
532  /* This uses a very dirty trick where the variables related to argument -layer are used
533  with a negative indexing */
534  if(strcmp(argv[arg],"-divlayer") == 0) {
535  if(arg+4 >= argc) {
536  printf("Give four parameters for the layer: boundary, elements, relative thickness, ratio.\n");
537  return(21);
538  }
539  else if(abs(eg->layers) == MAXBOUNDARIES) {
540  printf("There can only be %d layers, sorry.\n",MAXBOUNDARIES);
541  return(22);
542  }
543  else {
544  eg->layerbounds[abs(eg->layers)] = atoi(argv[arg+1]);
545  eg->layernumber[abs(eg->layers)] = atoi(argv[arg+2]);
546  eg->layerthickness[abs(eg->layers)] = atof(argv[arg+3]);
547  eg->layerratios[abs(eg->layers)] = atof(argv[arg+4]);
548  eg->layerparents[abs(eg->layers)] = 0;
549  eg->layers--;
550  }
551  }
552 
553  if(strcmp(argv[arg],"-3d") == 0) {
554  eg->dim = dim = 3;
555  }
556  if(strcmp(argv[arg],"-2d") == 0) {
557  eg->dim = dim = 2;
558  }
559  if(strcmp(argv[arg],"-1d") == 0) {
560  eg->dim = dim = 1;
561  }
562 
563  if(strcmp(argv[arg],"-isoparam") == 0) {
564  eg->isoparam = TRUE;
565  }
566  if(strcmp(argv[arg],"-nobound") == 0) {
567  eg->saveboundaries = FALSE;
568  }
569 
570  /* The following keywords are not actively used */
571 
572  if(strcmp(argv[arg],"-map") ==0) {
573  if(arg+1 >= argc) {
574  printf("Give the name of the mapping file\n");
575  return(23);
576  }
577  else {
578  strcpy(eg->mapfile,argv[arg+1]);
579  printf("Mapping file is %s\n",eg->mapfile);
580  }
581  }
582  if(strcmp(argv[arg],"-bcoffset") == 0) {
583  eg->bcoffset = atoi(argv[arg+1]);
584  }
585  if(strcmp(argv[arg],"-noelements") == 0) {
586  eg->elements3d = atoi(argv[arg+1]);
587  }
588  if(strcmp(argv[arg],"-nonodes") == 0) {
589  eg->nodes3d = atoi(argv[arg+1]);
590  }
591 
592  if(strcmp(argv[arg],"-sidefind") == 0) {
593  eg->findsides = 0;
594  for(i=arg+1;i<argc && strncmp(argv[i],"-",1); i++) {
595  eg->sidebulk[i-1-arg] = atoi(argv[i]);
596  eg->findsides++;
597  }
598  }
599  if(strcmp(argv[arg],"-findbound") == 0) {
600  eg->findsides = 0;
601  for(i=arg+1;i+1<argc && strncmp(argv[i],"-",1); i += 2) {
602  eg->sidebulk[i-1-arg] = atoi(argv[i]);
603  eg->sidebulk[i-arg] = atoi(argv[i+1]);
604  eg->findsides++;
605  }
606  }
607  }
608 
609  {
610  char *ptr1;
611  ptr1 = strchr(eg->filesout[0], '.');
612  if (ptr1) *ptr1 = '\0';
613  ptr1 = strchr(eg->mapfile, '.');
614  if (ptr1) *ptr1 = '\0';
615  }
616 
617  return(0);
618 }
619 
620 
621 #if EXE_MODE
622 static void Goodbye()
623 {
624  printf("\nThank you for using Elmergrid!\n");
625  printf("Send bug reports and feature wishes to peter.raback@csc.fi\n");
626  exit(0);
627 }
628 
629 static void Instructions()
630 {
631  printf("****************** Elmergrid ************************\n");
632  printf("This program can create simple 2D structured meshes consisting of\n");
633  printf("linear, quadratic or cubic rectangles or triangles. The meshes may\n");
634  printf("also be extruded and revolved to create 3D forms. In addition many\n");
635  printf("mesh formats may be imported into Elmer software. Some options have\n");
636  printf("not been properly tested. Contact the author if you face problems.\n\n");
637 
638  printf("The program has two operation modes\n");
639  printf("A) Command file mode which has the command file as the only argument\n");
640  printf(" 'ElmerGrid commandfile.eg'\n\n");
641 
642  printf("B) Inline mode which expects at least three input parameters\n");
643  printf(" 'ElmerGrid 1 3 test'\n\n");
644  printf("The first parameter defines the input file format:\n");
645  printf("1) .grd : Elmergrid file format\n");
646  printf("2) .mesh.* : Elmer input format\n");
647  printf("3) .ep : Elmer output format\n");
648  printf("4) .ansys : Ansys input format\n");
649  printf("5) .inp : Abaqus input format by Ideas\n");
650  printf("6) .msh : Nastran format\n");
651  printf("7) .FDNEUT : Gambit (Fidap) neutral file\n");
652  printf("8) .unv : Universal mesh file format\n");
653  printf("9) .mphtxt : Comsol Multiphysics mesh format\n");
654  printf("10) .dat : Fieldview format\n");
655  printf("11) .node,.ele: Triangle 2D mesh format\n");
656  printf("12) .mesh : Medit mesh format\n");
657  printf("13) .msh : GID mesh format\n");
658  printf("14) .msh : Gmsh mesh format\n");
659  printf("15) .ep.i : Partitioned ElmerPost format\n");
660 
661  printf("\nThe second parameter defines the output file format:\n");
662  printf("1) .grd : ElmerGrid file format\n");
663  printf("2) .mesh.* : ElmerSolver format (also partitioned .part format)\n");
664  printf("3) .ep : ElmerPost format\n");
665 
666  printf("\nThe third parameter is the name of the input file.\n");
667  printf("If the file does not exist, an example with the same name is created.\n");
668  printf("The default output file name is the same with a different suffix.\n\n");
669 
670  printf("There are several additional in-line parameters that are\n");
671  printf("taken into account only when applicable to the given format.\n");
672 
673  printf("-out str : name of the output file\n");
674  printf("-in str : name of a secondary input file\n");
675  printf("-silent : do not echo run time information\n");
676  printf("-decimals : number of decimals in the saved mesh (eg. 8)\n");
677  printf("-triangles : rectangles will be divided to triangles\n");
678  printf("-relh real : give relative mesh density parameter for ElmerGrid meshing\n");
679  printf("-merge real : merges nodes that are close to each other\n");
680  printf("-order real[3] : reorder elements and nodes using c1*x+c2*y+c3*z\n");
681  printf("-centralize : set the center of the mesh to origin\n");
682  printf("-scale real[3] : scale the coordinates with vector real[3]\n");
683  printf("-translate real[3] : translate the nodes with vector real[3]\n");
684  printf("-rotate real[3] : rotate around the main axis with angles real[3]\n");
685  printf("-clone int[3] : make ideantilcal copies of the mesh\n");
686  printf("-clonesize real[3] : the size of the mesh to be cloned if larger to the original\n");
687  printf("-unite : the meshes will be united\n");
688  printf("-polar real : map 2D mesh to a cylindrical shell with given radius\n");
689  printf("-cylinder : map 2D/3D cylindrical mesh to a cartesian mesh\n");
690  printf("-reduce int[2] : reduce element order at material interval [int1 int2]\n");
691  printf("-increase : increase element order from linear to quadratic\n");
692  printf("-bcoffset int : add an offset to the boundary conditions\n");
693  printf("-discont int : make the boundary to have secondary nodes\n");
694  printf("-connect int : make the boundary to have internal connection among its elements\n");
695  printf("-removelowdim : remove boundaries that are two ranks lower than highest dim\n");
696  printf("-removeunused : remove nodes that are not used in any element\n");
697  printf("-bulkorder : renumber materials types from 1 so that every number is used\n");
698  printf("-boundorder : renumber boundary types from 1 so that every number is used\n");
699  printf("-autoclean : this performs the united action of the three above\n");
700  printf("-bulkbound int[3] : set the union of materials [int1 int2] to be boundary int3\n");
701  printf("-boundbound int[3] : set the union of boundaries [int1 int2] to be boundary int3\n");
702  printf("-bulktype int[3] : set material types in interval [int1 int2] to type int3\n");
703  printf("-boundtype int[3] : set sidetypes in interval [int1 int2] to type int3\n");
704  printf("-layer int[2] real[2]: make a boundary layer for given boundary\n");
705  printf("-layermove int : apply Jacobi filter int times to move the layered mesh\n");
706  printf("-divlayer int[2] real[2]: make a boundary layer for given boundary\n");
707  printf("-3d / -2d / -1d : mesh is 3, 2 or 1-dimensional (applies to examples)\n");
708  printf("-isoparam : ensure that higher order elements are convex\n");
709  printf("-nobound : disable saving of boundary elements in ElmerPost format\n");
710 
711  printf("\nThe following keywords are related only to the parallel Elmer computations.\n");
712  printf("-partition int[4] : the mesh will be partitioned in main directions\n");
713  printf("-partorder real[3] : in the above method, the direction of the ordering\n");
714 #if HAVE_METIS
715  printf("-metis int[2] : the mesh will be partitioned with Metis\n");
716 #endif
717  printf("-halo : create halo for the partitioning\n");
718  printf("-indirect : create indirect connections in the partitioning\n");
719  printf("-periodic int[3] : decleare the periodic coordinate directions for parallel meshes\n");
720  printf("-saveinterval int[3] : the first, last and step for fusing parallel data\n");
721 
722  if(0) printf("-names : conserve name information where applicable\n");
723 }
724 
725 
726 
727 
728 
729 
730 
731 static int PartitionMesh(int nofile)
732 {
733  /* Partititioning related stuff */
734 
735  int noopt = 0;
736 
737  if(eg.partitions) {
738  if(eg.partopt % 2 == 0)
739  PartitionSimpleElements(&data[nofile],eg.partdim,eg.periodicdim,eg.partorder,eg.partcorder,info);
740  else
741  PartitionSimpleNodes(&data[nofile],eg.partdim,eg.periodicdim,eg.partorder,eg.partcorder,info);
742  noopt = eg.partopt / 2;
743  }
744 #if HAVE_METIS
745  if(eg.metis) {
746  if(eg.partopt % 5 <= 1)
747  PartitionMetisElements(&data[nofile],eg.metis,eg.partopt % 5,info);
748  else
749  PartitionMetisNodes(&data[nofile],eg.metis,eg.partopt % 5,info);
750  noopt = eg.partopt / 5;
751  }
752 #endif
753  if(eg.partitions || eg.metis )
754  OptimizePartitioning(&data[nofile],boundaries[nofile],noopt,info);
755 }
756 
757 
758 
759 static int ExportMeshDefinition(int inmethod,int outmethod,int nofile,char *filename)
760 {
761  int i;
762 
763  switch (outmethod) {
764  case 1:
765  SaveElmergrid(grids,nogrids,filename,info);
766  break;
767 
768  case 2:
769  if(data[nofile].nopartitions > 1)
770  SaveElmerInputPartitioned(&data[nofile],boundaries[nofile],filename,eg.decimals,
772  else
773  SaveElmerInput(&data[nofile],boundaries[nofile],filename,eg.decimals,info);
774  break;
775 
776  case 22:
777  SaveElmerInputFemBem(&data[nofile],boundaries[nofile],filename,eg.decimals,info);
778  break;
779 
780  case 3:
781  /* Create a variable so that when saving data in ElmerPost format there is something to visualize */
782  if(data[nofile].variables == 0) {
783  CreateVariable(&data[nofile],1,1,0.0,"Number",FALSE);
784  for(i=1;i<=data[nofile].alldofs[1];i++)
785  data[nofile].dofs[1][i] = (Real)(i);
786  }
787  SaveSolutionElmer(&data[nofile],boundaries[nofile],eg.saveboundaries ? MAXBOUNDARIES:0,
788  filename,eg.decimals,info=TRUE);
789  break;
790 
791  default:
792  Instructions();
793  break;
794  }
795  Goodbye();
796 }
797 
798 
799 #else
800 
801 
802 int ConvertEgTypeToMeshType(struct FemType *dat,struct BoundaryType *bound,mesh_t *mesh)
803 {
804  int i,j,k,allocated,surfaces,elemdim;
805  int sideelemtype,ind[MAXNODESD1];
806 
807  node_t *n;
808  surface_t *b;
809  element_t *e;
810  edge_t *s;
811 
812  if(!dat->created) {
813  printf("Data is not created!\n");
814  return(1);
815  }
816 
817  elemdim = GetMaxElementDimension(dat);
818  printf("Setting elements of %ddim\n",elemdim);
819 
820  /* for mapped surfaces elemdim and space dimension may differ! */
821  mesh->setDim(MAX(data->dim, elemdim));
822  mesh->setNodes(dat->noknots);
823  mesh->newNodeArray(mesh->getNodes());
824 
825  for(i=0; i < mesh->getNodes(); i++) {
826  n = mesh->getNode(i);
827  n->setX(0, dat->x[i+1]);
828  n->setX(1, dat->y[i+1]);
829  n->setX(2, dat->z[i+1]);
830  n->setIndex(-1);
831  }
832 
833  /* For 3D save bulk elements & boundary elements */
834  if(elemdim == 3) {
835 
836  mesh->setElements(dat->noelements);
837  mesh->newElementArray(mesh->getElements());
838 
839  for(i = 0; i < mesh->getElements(); i++) {
840  e = mesh->getElement(i);
841  e->setCode(dat->elementtypes[i+1]);
842  e->setNodes(e->getCode() % 100);
843  e->newNodeIndexes(e->getNodes());
844  e->setNature(PDE_BULK);
845 
846  for(j = 0; j < e->getNodes(); j++)
847  e->setNodeIndex(j, dat->topology[i+1][j]-1);
848  e->setIndex(dat->material[i+1]);
849  }
850 
851 
852  if(eg.saveboundaries) {
853 
854  allocated = FALSE;
855  do_b: surfaces = 0;
856 
857 
858  for(j=0;j<MAXBOUNDARIES;j++) {
859  if(bound[j].created == FALSE) continue;
860 
861  for(i=1;i<=bound[j].nosides;i++) {
862  GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],dat,ind,&sideelemtype);
863 
864  if(sideelemtype / 100 < 3 || sideelemtype / 100 > 4) continue;
865  surfaces += 1;
866 
867  if(allocated) {
868  b = mesh->getSurface(surfaces-1);
869  b->setElements(0);
870  b->newElementIndexes(2);
871 
872  if(bound[j].parent[i]) {
873  b->setElements(b->getElements() + 1);
874  b->setElementIndex(0, bound[j].parent[i]-1);
875  }
876  else {
877  b->setElementIndex(0, -1);
878  }
879 
880  if(bound[j].parent2[i]) {
881  b->setElements(b->getElements() + 1);
882  b->setElementIndex(1, bound[j].parent2[i]-1);
883  }
884  else {
885  b->setElementIndex(1, -1);
886  }
887 
888  b->setNormal(0, 0.0);
889  b->setNormal(1, 0.0);
890  b->setNormal(2, -1.0);
891 
893  b->setCode(sideelemtype);
894  b->setNodes(b->getCode() % 100);
895  b->newNodeIndexes(b->getNodes());
896  for(k = 0; k < b->getNodes(); k++)
897  b->setNodeIndex(k, ind[k]-1);
898  b->setIndex(bound[j].types[i]);
899 
900  b->setEdges(b->getNodes());
901  b->newEdgeIndexes(b->getEdges());
902  for(k=0; k < b->getEdges(); k++)
903  b->setEdgeIndex(k, -1);
904  }
905  }
906  }
907 
908  if(!allocated) {
909  mesh->setSurfaces(surfaces);
910  mesh->newSurfaceArray(mesh->getSurfaces());
911  allocated = TRUE;
912  goto do_b;
913  }
914  }
915  }
916 
917  else if(elemdim == 2) {
918  mesh->setElements(0);
919 
920  mesh->setSurfaces(dat->noelements);
921  mesh->newSurfaceArray(mesh->getSurfaces());
922 
923  for(i = 0; i < mesh->getSurfaces(); i++) {
924  b = mesh->getSurface(i);
925 
926  b->setElements(0);
927  b->newElementIndexes(2);
928  b->setElementIndex(0, -1);
929  b->setElementIndex(1, -1);
930 
931  b->setNormal(0, 0.0);
932  b->setNormal(1, 0.0);
933  b->setNormal(2, -1.0);
934 
935  b->setCode(dat->elementtypes[i+1]);
936  b->setNodes(b->getCode() % 100);
937  b->newNodeIndexes(b->getNodes());
938  b->setNature(PDE_BULK);
939 
940  for(j = 0; j < b->getNodes(); j++)
941  b->setNodeIndex(j, dat->topology[i+1][j]-1);
942  b->setIndex(dat->material[i+1]);
943 
944  b->setEdges(b->getNodes());
945  b->newEdgeIndexes(b->getEdges());
946  for(k=0; k < b->getEdges(); k++)
947  b->setEdgeIndex(k, -1);
948  }
949 
950  allocated = FALSE;
951  do_s: surfaces = 0;
952 
953  for(j=0;j<MAXBOUNDARIES;j++) {
954  if(bound[j].created == FALSE) continue;
955 
956  for(i=1;i<=bound[j].nosides;i++) {
957  GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],dat,ind,&sideelemtype);
958 
959  if(sideelemtype / 100 != 2) continue;
960  surfaces += 1;
961 
962  if(allocated) {
963  s = mesh->getEdge(surfaces-1);
964  s->setSurfaces(0);
965  s->newSurfaceIndexes(2);
966 
967  if(bound[j].parent[i]) {
968  s->setSurfaces(s->getSurfaces() + 1);
969  s->setSurfaceIndex(0, bound[j].parent[i]-1);
970  }
971  else {
972  s->setSurfaceIndex(0, -1);
973  }
974  if(bound[j].parent2[i]) {
975  s->setSurfaces(s->getSurfaces() + 1);
976  s->setSurfaceIndex(1, bound[j].parent2[i]-1);
977  }
978  else {
979  s->setSurfaceIndex(1, -1);
980  }
981  s->setCode(sideelemtype);
982  s->setNodes(s->getCode() % 100);
983  s->newNodeIndexes(s->getNodes());
985 
986  for(k = 0; k < s->getNodes(); k++)
987  s->setNodeIndex(k, ind[k]-1);
988  s->setIndex(bound[j].types[i]);
989  }
990  }
991  }
992 
993  if(!allocated) {
994  mesh->setEdges(surfaces);
995  mesh->newEdgeArray(mesh->getEdges());
996  allocated = TRUE;
997  goto do_s;
998  }
999  }
1000  else {
1001  printf("Implemented only for element dimensions 2 and 3 (not %d)\n",elemdim);
1002  }
1003 
1004  return(0);
1005 }
1006 #endif
1007 
1008 
1009 static int DetermineFileType(const char *filename,int info)
1010 {
1011  int mode;
1012  mode = -1;
1013 
1014  if(!strstr(filename,".")) {
1015  if(info) printf("There cannot be a filetype suffix without a dot: %s\n",filename);
1016  return(mode);
1017  }
1018  else {
1019  if(strstr(filename,".eg")) mode = 0;
1020  else if(strstr(filename,".grd")) mode = 1;
1021  else if(strstr(filename,".ep")) mode = 3;
1022  else if(strstr(filename,".inp")) mode = 5;
1023  else if(strstr(filename,".nas")) mode = 6;
1024  else if(strstr(filename,".fdneut") || strstr(filename,".FDNEUT")) mode = 7;
1025  else if(strstr(filename,".unv")) mode = 8;
1026  else if(strstr(filename,".mphtxt")) mode = 9;
1027  else if(strstr(filename,".msh")) mode = 14;
1028  else if(strstr(filename,".plt")) mode = 16;
1029  }
1030  if(mode == -1) {
1031  if(info) printf("Could not determine the filetype based on the suffix\n");
1032  }
1033 
1034  if(info) printf("Filetype determined by suffix: %d\n",mode);
1035 
1036  return(mode);
1037 }
1038 
1039 
1040 
1041 static int ImportMeshDefinition(int inmethod,int nofile,char *filename,int *nogrids)
1042 {
1043  int i,k,errorstat = 0,dim;
1044  static int visited = FALSE;
1045 
1046 
1047  *nogrids = 0;
1048  if(!visited) {
1049  for(k=0;k<MAXCASES;k++) {
1050  boundaries[k] = (struct BoundaryType*)
1051  malloc((size_t) (MAXBOUNDARIES)*sizeof(struct BoundaryType));
1052  for(i=0;i<MAXBOUNDARIES;i++) {
1053  boundaries[k][i].created = FALSE;
1054  boundaries[k][i].nosides = 0;
1055  }
1056  }
1057  visited = TRUE;
1058  }
1059 
1060  /* Native format of ElmerGrid gets specieal treatment */
1061  switch (inmethod) {
1062 
1063  case 1:
1064  errorstat = LoadElmergrid(&grids,nogrids,eg.filesin[nofile],info);
1065  if(errorstat == 1) {
1066  dim = eg.dim;
1067  CreateExampleGrid(dim,&grids,nogrids,info);
1068  SaveElmergrid(grids,*nogrids,eg.filesin[nofile],info);
1069  printf("Because file %s didn't exist, it was created for you.\n",eg.filesin[nofile]);
1070  return(errorstat);
1071  }
1072  if(*nogrids) LoadCommands(eg.filesin[nofile],&eg,grids,2,IOmethods,info);
1073  break;
1074 
1075 #if EXE_MODE
1076  case 2:
1077  errorstat = LoadElmerInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1078  break;
1079 
1080  case 3:
1081  errorstat = LoadSolutionElmer(&(data[nofile]),TRUE,eg.filesin[nofile],info);
1082  break;
1083 #endif
1084 
1085  case 4:
1086  errorstat = LoadAnsysInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1087  break;
1088 
1089  case 5:
1090  errorstat = LoadAbaqusInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1091  break;
1092 
1093  case 6:
1094  errorstat = LoadNastranInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1095  break;
1096 
1097  case 7:
1098  errorstat = LoadFidapInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1099  break;
1100 
1101  case 8:
1102  errorstat = LoadUniversalMesh(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1103  break;
1104 
1105  case 9:
1106  errorstat = LoadComsolMesh(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1107  break;
1108 
1109  case 10:
1110  errorstat = LoadFieldviewInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1111  break;
1112 
1113  case 11:
1114  errorstat = LoadTriangleInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1115  break;
1116 
1117  case 12:
1118  errorstat = LoadMeditInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1119  break;
1120 
1121  case 13:
1122  errorstat = LoadGidInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1123  break;
1124 
1125  case 14:
1126  errorstat = LoadGmshInput(&(data[nofile]),boundaries[nofile],eg.filesin[nofile],info);
1127  break;
1128 
1129  case 16:
1130  errorstat = LoadCGsimMesh(&(data[nofile]),eg.filesin[nofile],info);
1131  break;
1132 
1133 #if EXE_MODE
1134  case 15:
1135  if(info) printf("Partitioned solution is fused on-the-fly therefore no other operations may be performed.\n");
1136  FuseSolutionElmerPartitioned(eg.filesin[nofile],eg.filesout[nofile],eg.decimals,
1138  if(info) printf("Finishing with the fusion of partitioned Elmer solutions\n");
1139  Goodbye();
1140  break;
1141 
1142  default:
1143  errorstat = 1;
1144  Instructions();
1145 #endif
1146 
1147  }
1148 
1149  if(!errorstat) *nogrids = MAX(*nogrids,1);
1150 
1151  return(errorstat);
1152 }
1153 
1154 
1155 
1156 
1157 
1158 static int ManipulateMeshDefinition(int inmethod,int outmethod,Real relh)
1159 {
1160  static int visited = FALSE;
1161  int i,j,k;
1162  Real mergeeps;
1163 
1164  if(inmethod == 1 && outmethod != 1) {
1165  if(visited) {
1166  for(k=0;k<MAXCASES;k++) {
1167  if(data[k].created) {
1168  DestroyKnots(&data[k]);
1169  for(i=0;i<MAXBOUNDARIES;i++)
1170  DestroyBoundary(&boundaries[k][i]);
1171  }
1172  }
1173  }
1174  for(k=0;k<nogrids;k++)
1175  CreateElmerGridMesh(&(grids[k]),&(data[k]),boundaries[k],relh,info);
1176  nomeshes = nogrids;
1177  }
1178 
1179  visited = TRUE;
1180 
1181  /* At first instance perform operations that should rather be done before extrusion
1182  or mesh union. */
1183  for(k=0;k<nomeshes;k++) {
1184 
1185  /* Make the discontinous boundary needed, for example, in poor thermal conduction */
1186  if(!eg.discont) {
1187  for(j=0;j<grids[k].noboundaries;j++)
1188  if(grids[k].boundsolid[j] == 2) {
1189  eg.discontbounds[eg.discont] = grids[k].boundtype[j];
1190  eg.discont++;
1191  }
1192  }
1193  if(eg.discont) {
1194  for(i=1;i<=eg.discont;i++)
1195  SetDiscontinuousBoundary(&(data[k]),boundaries[k],eg.discontbounds[i-1],2,info);
1196  }
1197 
1198  /* Make a connected boundary (specific to Elmer format) needed in linear constraints */
1199  for(i=1;i<=eg.connect;i++)
1200  SetConnectedBoundary(&(data[k]),boundaries[k],eg.connectbounds[i-1],i,info);
1201 
1202  /* Divide quadrilateral meshes into triangular meshes */
1203  if(eg.triangles || grids[k].triangles == TRUE) {
1204  Real criticalangle;
1205  criticalangle = MAX(eg.triangleangle, grids[k].triangleangle);
1206  ElementsToTriangles(&data[k],boundaries[k],criticalangle,info);
1207  }
1208 
1209  /* Make a boundary layer with two different methods */
1210  if(eg.layers > 0)
1211  CreateBoundaryLayer(&data[k],boundaries[k],eg.layers,
1214  else if(eg.layers < 0)
1215  CreateBoundaryLayerDivide(&data[k],boundaries[k],abs(eg.layers),
1217  eg.layerparents, info);
1218  }
1219 
1220  if(outmethod != 1 && eg.dim != 2) {
1221  j = MAX(1,nogrids);
1222  for(k=0;k<j;k++) {
1223  if(grids[k].dimension == 3 || grids[k].rotate) {
1224  CreateKnotsExtruded(&(data[k]),boundaries[k],&(grids[k]),
1225  &(data[j]),boundaries[j],info);
1226 #if LIB_MODE
1227  activemesh = j;
1228  nomeshes = j+1;
1229 #endif
1230 #if EXE_MODE
1231  data[k] = data[j];
1232  boundaries[k] = boundaries[j];
1233 #endif
1234  }
1235  }
1236  }
1237 
1238  /* Unite meshes if there are several of them */
1239  if(eg.unitemeshes) {
1240  for(k=1;k<nomeshes;k++)
1241  UniteMeshes(&data[0],&data[k],boundaries[0],boundaries[k],info);
1242  nomeshes = 1;
1243  }
1244 
1245  for(k=0;k<nomeshes;k++) {
1246  /* If the original mesh was given in polar coordinates make the transformation into cartesian ones */
1247  if(eg.polar || data[k].coordsystem == COORD_POLAR) {
1248  if(!eg.polar) eg.polarradius = grids[k].polarradius;
1250  }
1251  /* If the original mesh was given in cylindrical coordinates make the transformation into cartesian ones */
1252  if(eg.cylinder || data[k].coordsystem == COORD_CYL) {
1254  }
1255  if(eg.clone[0] || eg.clone[1] || eg.clone[2]) {
1256  CloneMeshes(&data[k],boundaries[k],eg.clone,eg.clonesize,FALSE,info);
1257  mergeeps = fabs(eg.clonesize[0]+eg.clonesize[1]+eg.clonesize[2]) * 1.0e-8;
1258  MergeElements(&data[k],boundaries[k],eg.order,eg.corder,mergeeps,TRUE,TRUE);
1259  }
1260 
1261  /* Reduce element order if requested */
1262  if(nogrids && grids[k].reduceordermatmax) {
1263  eg.reduce = TRUE;
1264  eg.reducemat1 = grids[k].reduceordermatmin;
1265  eg.reducemat2 = grids[k].reduceordermatmax;
1266  }
1267  if(eg.reduce)
1269 
1270  /* Increase element order */
1271  if(eg.increase)
1273 
1274  if(eg.merge)
1275  MergeElements(&data[k],boundaries[k],eg.order,eg.corder,eg.cmerge,FALSE,TRUE);
1276 #if HAVE_METIS
1277  else if(eg.order == 3)
1278  ReorderElementsMetis(&data[k],TRUE);
1279 #endif
1280  else if(eg.order)
1281  ReorderElements(&data[k],boundaries[k],eg.order,eg.corder,TRUE);
1282 
1283  if(eg.bulkbounds || eg.boundbounds)
1284  SideAndBulkBoundaries(&data[k],boundaries[k],&eg,info);
1285 
1287 
1288  if(eg.removelowdim)
1289  RemoveLowerDimensionalBoundaries(&data[k],boundaries[k],info);
1290 
1291  if(eg.removeunused)
1293 
1294  if(eg.sidemappings || eg.bulkmappings)
1295  SideAndBulkMappings(&data[k],boundaries[k],&eg,info);
1296 
1297  if(eg.boundorder || eg.bcoffset)
1298  RenumberBoundaryTypes(&data[k],boundaries[k],eg.boundorder,eg.bcoffset,info);
1299 
1300  if(eg.bulkorder)
1301  RenumberMaterialTypes(&data[k],boundaries[k],info);
1302 
1303  if(eg.periodicdim[0] || eg.periodicdim[1] || eg.periodicdim[2])
1305  }
1306  return 0;
1307 }
1308 
1309 
1310 
1311 
1312 #if LIB_MODE
1313 int eg_loadmesh(const char *filename)
1314 {
1315  static int inmethod,errorstat,info;
1316 
1317  strcpy(Filename,filename);
1318  info = TRUE;
1319  if(info) printf("\nElmerGrid checking filename suffix for file: %s\n",filename);
1320 
1321  inmethod = DetermineFileType(filename,info);
1322  Inmethod = inmethod;
1323 
1324  if(inmethod < 0)
1325  errorstat = 1;
1326  else
1327  errorstat = 0;
1328 
1329  if(info) printf("Initialized the filetype\n");
1330  return(errorstat);
1331 }
1332 
1333 
1334 
1335 int eg_transfermesh(mesh_t *mesh,const char *str)
1336 {
1337  int i,k,inmethod,outmethod,errorstat,nofile;
1338  info = TRUE;
1339  static char arguments[10][10],**argv;
1340  int argc;
1341  static int visited = FALSE;
1342  char filename[MAXFILESIZE];
1343 
1344  activemesh = 0;
1345  nofile = 0;
1346  nomeshes = 0;
1347  nogrids = 0;
1348  info = TRUE;
1349 
1350  if(!visited) {
1351  grids = (struct GridType*)malloc((size_t) (MAXCASES)*sizeof(struct GridType));
1352  argv = (char**) malloc((size_t) 10*sizeof(char*));
1353  }
1354  visited++;
1355 
1356  InitParameters(&eg);
1357  InitGrid(grids);
1358 
1359  strcpy(filename,Filename);
1360  if(info) printf("\nElmerGrid loading data from file: %s\n",filename);
1361 
1362  inmethod = Inmethod;
1363  if(inmethod < 0) return(1);
1364 
1365  if(inmethod == 0) {
1366  errorstat = LoadCommands(filename,&eg,grids,1,IOmethods,info);
1367  inmethod = eg.inmethod;
1368  info = !eg.silent;
1369  }
1370  else {
1371  eg.inmethod = inmethod;
1372  }
1373  strcpy(eg.filesin[0],filename);
1374 
1375  errorstat = ImportMeshDefinition(inmethod,nofile,filename,&nogrids);
1376 
1377  if(errorstat) return(errorstat);
1378  nomeshes += nogrids;
1379 
1380  if(info) printf("\nElmerGrid manipulating and importing data\n");
1381 
1382  mesh->setNodes(0);
1383  mesh->setPoints(0);
1384  mesh->setEdges(0);
1385  mesh->setSurfaces(0);
1386  mesh->setElements(0);
1387 
1388  if(nomeshes == 0) {
1389  printf("No mesh to work with!\n");
1390  return(1);
1391  }
1392 
1393  /* Checking in-line parameters */
1394  argc = StringToStrings(str,arguments,10,' ');
1395  for(i=0;i<argc;i++) argv[i] = &arguments[i][0];
1396 
1397  errorstat = InlineParameters(&eg,argc,argv,IOmethods,0,info);
1398 
1399  inmethod = eg.inmethod;
1400  outmethod = 0;
1401 
1402  ManipulateMeshDefinition(inmethod,outmethod,eg.relh);
1403 
1404  errorstat = ConvertEgTypeToMeshType(&data[activemesh],boundaries[activemesh],mesh);
1405 
1406  if(info) printf("Done converting mesh\n");
1407  return(errorstat);
1408 
1409  for(k=0;k<MAXCASES;k++) {
1410  DestroyKnots(&data[k]);
1411  for(i=0;i<MAXBOUNDARIES;i++)
1412  DestroyBoundary(&boundaries[k][i]);
1413  }
1414  if(info) printf("Done destroying structures\n");
1415 }
1416 
1417 
1418 #if 0
1419 int main(int argc, char *argv[])
1420 {
1421  char prefix[MAXFILESIZE];
1422  class mesh_t mesh;
1423 
1424  eg_loadmesh("apu.grd");
1425  eg_transfermesh("test",&mesh);
1426 }
1427 #endif
1428 #endif
1429 
1430 
1431 #if EXE_MODE
1432 int main(int argc, char *argv[])
1433 {
1434  char prefix[MAXFILESIZE],filename[MAXFILESIZE];
1435  Real relh;
1436  static int i,j,k,l,inmethod,outmethod,errorstat;
1437  static int nofile,dim;
1438  static Real mergeeps;
1439  long ii;
1440 
1441  if(info) printf("\nStarting program Elmergrid\n");
1442 
1443  InitParameters(&eg);
1444  grids = (struct GridType*)malloc((size_t) (MAXCASES)*sizeof(struct GridType));
1445  InitGrid(grids);
1446  info = TRUE;
1447 
1448  if(argc <= 2) {
1449  errorstat = LoadCommands(argv[1],&eg,grids,argc-1,IOmethods,info);
1450  if(errorstat) {
1451  if(argc <= 1) Instructions();
1452  Goodbye();
1453  }
1454  }
1455  else if(argc == 3) {
1456  Instructions();
1457  Goodbye();
1458  }
1459  else {
1460  errorstat = InlineParameters(&eg,argc,argv,IOmethods,4,info);
1461  if(errorstat) Goodbye();
1462  }
1463  inmethod = eg.inmethod;
1464  outmethod = eg.outmethod;
1465  info = !eg.silent;
1466  dim = eg.dim;
1467  relh = eg.relh;
1468  if(!outmethod || !inmethod) {
1469  printf("Please define the input and output formats\n");
1470  Goodbye();
1471  }
1472 
1473  /**********************************/
1474  if(info) printf("\nElmergrid loading data:\n");
1475 
1476  nofile = 0;
1477  nomeshes = 0;
1478  nogrids = 0;
1479 
1480  for(nofile=0;nofile<eg.nofilesin;nofile++) {
1481  errorstat = ImportMeshDefinition(inmethod,nofile,eg.filesin[nofile],&nogrids);
1482  if(errorstat) Goodbye();
1483  nomeshes += nogrids;
1484  }
1485 
1486  /***********************************/
1487  if(info) printf("\nElmergrid creating and manipulating meshes:\n");
1488  ManipulateMeshDefinition(inmethod,outmethod,relh);
1489 
1490  /* Partititioning related stuff */
1491  for(k=0;k<nomeshes;k++)
1492  PartitionMesh(nofile);
1493 
1494  /********************************/
1495  if(info) printf("\nElmergrid saving data:\n");
1496  sprintf(prefix,"%s",eg.filesout[0]);
1497  for(nofile=0;nofile<nomeshes;nofile++) {
1498  if(nomeshes == 1)
1499  sprintf(filename,"%s",prefix);
1500  else
1501  sprintf(filename,"%s%d",prefix,nofile+1);
1502  ExportMeshDefinition(inmethod,outmethod,nofile,filename);
1503  }
1504  Goodbye();
1505 }
1506 #endif
1507 
1508 
1509