1 // GetDP - Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege
2 //
3 // See the LICENSE.txt file for license information. Please report all
4 // issues on https://gitlab.onelab.info/getdp/getdp/issues.
5
6 #include <sstream>
7 #include <vector>
8 #include <string>
9 #include <string.h>
10 #include "GetDPConfig.h"
11 #include "GetDPVersion.h"
12 #include "onelab.h"
13 #include "ProData.h"
14 #include "ProParser.h"
15 #include "SolvingAnalyse.h"
16 #include "LinAlg.h"
17 #include "OS.h"
18 #include "MallocUtils.h"
19 #include "Message.h"
20
21 #if defined(HAVE_GMSH)
22 #include <gmsh.h>
23 // these will disappear
24 #include <gmsh/GmshGlobal.h>
25 #include <gmsh/GmshVersion.h>
26 #include <gmsh/GmshConfig.h>
27 #include <gmsh/PView.h>
28 #endif
29
30 int Flag_PRE = 0, Flag_CAL = 0, Flag_POS = 0, Flag_RESTART = 0;
31 int Flag_XDATA = 0, Flag_BIN = 0, Flag_SPLIT = 0, Flag_GMSH_VERSION = 1;
32 int Flag_NETWORK_CACHE = 0, Flag_CALLED_WITH_ONELAB_SERVER = 0;
33 int Flag_SLEPC = 0;
34 double Flag_ORDER = -1., Flag_MSH_SCALING = 1.;
35 char *Name_Generic = 0, *Name_Path = 0;
36 char *Name_Resolution = 0;
37 char *Name_MshFile = 0, *Name_AdaptFile = 0;
38 char *Name_PostOperation[NBR_MAX_POS] = {0};
39 char *Name_ResFile[NBR_MAX_RES] = {0};
40 char *Name_GmshReadFile[NBR_MAX_RES] = {0};
41 int Tag_GmshReadFile[NBR_MAX_RES] = {-1};
42
Info(int level,char * arg0)43 static void Info(int level, char *arg0)
44 {
45 switch(level){
46 case 0 :
47 fprintf(stderr,
48 "GetDP, a General environment for the treatment of Discrete Problems\n"
49 "Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege\n"
50 "Usage: %s [file] [options]\n"
51 "Processing options:\n"
52 " -pre 'Resolution' pre-processing\n"
53 " -cal processing\n"
54 " -pos 'PostOperation(s)' post-processing\n"
55 " -msh file read mesh (in msh format) from file\n"
56 " -msh_scaling value scale the input mesh by the given value\n"
57 " -gmshread file(s) read gmsh data (same as GmshRead in resolution)\n"
58 " -gmshtag tag(s) tag(s) associated to GmshRead data\n"
59 " -restart resume processing from where it stopped\n"
60 " -solve 'Resolution' same as -pre 'Resolution' -cal\n"
61 " -split save processing results in separate files\n"
62 " -res file(s) load processing results from file(s)\n"
63 " -name string use string as generic file name\n"
64 " -adapt file read adaptation constraints from file\n"
65 " -order num restrict maximum interpolation order\n"
66 " -cache cache network computations to disk\n"
67 "Linear solver options:\n"
68 #if defined(HAVE_PETSC)
69 " -solver file specify parameter file (default: .petscrc)\n"
70 " [PETsc options] PETSc options (must be listed after [file])\n"
71 #endif
72 #if defined(HAVE_SLEPC)
73 " -slepc use SLEPc instead of Arpack as eigensolver\n"
74 #endif
75 #if defined(HAVE_SPARSKIT)
76 " -solver file specify parameter file (default: solver.par)\n"
77 " -'Parameter' num override value of solver parameter 'Parameter'\n"
78 #endif
79 "Output options:\n"
80 " -bin create binary output files\n"
81 " -v2 create mesh-based Gmsh output files when possible\n"
82 "Other options:\n"
83 " -check interactive check of problem structure\n"
84 " -v num set verbosity level (default: 5)\n"
85 " -cpu report CPU times for all operations\n"
86 " -p num set progress indicator update (default: 10)\n"
87 " -onelab name [address] communicate with ONELAB (file or server address)\n"
88 " -setnumber name value set constant number name=value (or -sn)\n"
89 " -setstring name value set constant string name=value (or -ss)\n"
90 " -version show version number\n"
91 " -info show detailed version information\n"
92 " -help show this message\n", arg0);
93 break;
94 case 1:
95 fprintf(stderr, "%s\n", GETDP_VERSION);
96 break;
97 case 2:
98 fprintf(stderr, "Version : %s\n", GETDP_VERSION);
99 fprintf(stderr, "License : %s\n", GETDP_SHORT_LICENSE);
100 fprintf(stderr, "Build OS : %s\n", GETDP_OS);
101 fprintf(stderr, "Build date : %s\n", GETDP_DATE);
102 fprintf(stderr, "Build host : %s\n", GETDP_HOST);
103 fprintf(stderr, "Build options :%s\n", GETDP_CONFIG_OPTIONS);
104 #if defined(HAVE_PETSC)
105 fprintf(stderr, "PETSc version : %d.%d.%d (%s arithmetic)\n", PETSC_VERSION_MAJOR,
106 PETSC_VERSION_MINOR, PETSC_VERSION_SUBMINOR,
107 #if defined(PETSC_USE_COMPLEX)
108 "complex"
109 #else
110 "real"
111 #endif
112 );
113 #endif
114 #if defined(HAVE_GMSH)
115 fprintf(stderr, "Gmsh lib version : %s%s (%s)\n",
116 GMSH_VERSION, GMSH_EXTRA_VERSION, GMSH_DATE);
117 fprintf(stderr, "Gmsh lib options :%s\n", GMSH_CONFIG_OPTIONS);
118 #endif
119 fprintf(stderr, "Packaged by : %s\n", GETDP_PACKAGER);
120 fprintf(stderr, "Web site : http://getdp.info\n");
121 fprintf(stderr, "Issue tracker : https://gitlab.onelab.info/getdp/getdp/issues\n");
122 break;
123 }
124 Message::Exit(0);
125 }
126
127 /* ------------------------------------------------------------------------ */
128 /* G e t _ O p t i o n s */
129 /* ------------------------------------------------------------------------ */
130
Get_Options(int argc,char * argv[],int * sargc,char ** sargv,char * pro,int * lres,int * lpos,int * check)131 static void Get_Options(int argc, char *argv[], int *sargc, char **sargv, char *pro,
132 int *lres, int *lpos, int *check)
133 {
134 strcpy(pro, "");
135
136 int i = *sargc = 1, j = 0;
137
138 while (i < argc) {
139
140 if (argv[i][0] == '-') {
141
142 if (!strcmp(argv[i]+1, "cal")) { Flag_CAL = 1; i++; }
143 else if (!strcmp(argv[i]+1, "check")) { *check = 1; i++; }
144 else if (!strcmp(argv[i]+1, "xdata")) { Flag_XDATA = 1; i++; }
145 else if (!strcmp(argv[i]+1, "cache")) { Flag_NETWORK_CACHE = 1; i++; }
146 else if (!strcmp(argv[i]+1, "bin")) { Flag_BIN = 1; i++; }
147 else if (!strcmp(argv[i]+1, "v2")) { Flag_GMSH_VERSION = 2; i++; }
148 else if (!strcmp(argv[i]+1, "ascii")) { Flag_BIN = 0; i++; }
149 else if (!strcmp(argv[i]+1, "split")) { Flag_SPLIT = 1; i++; }
150
151 else if (!strcmp(argv[i]+1, "socket")) {
152 i++;
153 if (i < argc && argv[i][0] != '-') {
154 Message::InitializeSocket(argv[i]); i++;
155 }
156 else {
157 Message::Error("Missing socket name");
158 }
159 }
160
161 else if (!strcmp(argv[i]+1, "onelab")) {
162 i++;
163 if (i + 1 < argc && argv[i][0] != '-' && argv[i + 1][0] != '-') {
164 Message::InitializeOnelab(argv[i], argv[i + 1]);
165 i += 2;
166 }
167 else if (i < argc && argv[i][0] != '-') {
168 Message::InitializeOnelab(argv[i], "");
169 i += 1;
170 }
171 else {
172 Message::Error("Missing client name and/or address of ONELAB server");
173 }
174 }
175
176 else if (!strcmp(argv[i]+1, "setnumber") ||
177 !strcmp(argv[i]+1, "sn")) {
178 i++;
179 if (i + 1 < argc && argv[i][0] != '-') {
180 CommandLineNumbers[argv[i]] = std::vector<double>(1, atof(argv[i + 1]));
181 i += 2;
182 }
183 else{
184 Message::Error("Missing name and/or value for number definition");
185 }
186 }
187
188 else if (!strcmp(argv[i]+1, "setstring") ||
189 !strcmp(argv[i]+1, "ss")) {
190 i++;
191 if (i + 1 < argc && argv[i][0] != '-' && argv[i + 1][0] != '-') {
192 CommandLineStrings[argv[i]] = std::vector<std::string>(1, argv[i + 1]);
193 i += 2;
194 }
195 else{
196 Message::Error("Missing name and/or value for string definition");
197 }
198 }
199
200 else if (!strcmp(argv[i]+1, "setlist") ||
201 !strcmp(argv[i]+1, "setlistofnumbers")) {
202 i++;
203 if (i + 1 < argc && argv[i][0] != '-') {
204 std::string n(argv[i]);
205 std::vector<double> v;
206 int s = atoi(argv[i + 1]), j = 0;
207 i += 2;
208 while(j < s && i < argc){
209 v.push_back(atof(argv[i]));
210 i++; j++;
211 }
212 if(j < s)
213 Message::Error("Missing values in list (got %d instead of %d)", j, s);
214 CommandLineNumbers[n] = v;
215 }
216 else{
217 Message::Error("Missing name and/or value for definition of list of numbers");
218 }
219 }
220
221 else if (!strcmp(argv[i]+1, "restart")){
222 Flag_CAL = Flag_RESTART = 1; i++;
223 }
224
225 else if (!strcmp(argv[i]+1, "verbose") ||
226 !strcmp(argv[i]+1, "v")) {
227 i++;
228 if (i < argc && argv[i][0] != '-') {
229 Message::SetVerbosity(atoi(argv[i])); i++;
230 }
231 else {
232 Message::Error("Missing number");
233 }
234 }
235
236 else if (!strcmp(argv[i]+1, "cpu")) {
237 Message::SetInfoCpu(true); i++;
238 }
239
240 else if(!strcmp(argv[i] + 1, "nt")) {
241 i++;
242 if(argv[i])
243 Message::SetNumThreads(atoi(argv[i++]));
244 else
245 Message::Error("Missing number");
246 }
247
248 else if (!strcmp(argv[i]+1, "help") || !strcmp(argv[i]+1, "h") ||
249 !strcmp(argv[i]+1, "-help") || !strcmp(argv[i]+1, "-h")) {
250 Info(0, argv[0]);
251 }
252
253 else if (!strcmp(argv[i]+1, "version") ||
254 !strcmp(argv[i]+1, "-version")) {
255 Info(1, argv[0]);
256 }
257
258 else if (!strcmp(argv[i]+1, "info") ||
259 !strcmp(argv[i]+1, "-info")) {
260 Info(2, argv[0]);
261 }
262
263 else if (!strcmp(argv[i]+1, "progress") ||
264 !strcmp(argv[i]+1, "p")) {
265 i++;
266 if (i < argc && argv[i][0] != '-') {
267 Message::SetProgressMeterStep(atoi(argv[i])); i++;
268 }
269 else {
270 Message::Error("Missing number");
271 }
272 }
273
274 else if (!strcmp(argv[i]+1, "pre")) {
275 i++;
276 if (i < argc && argv[i][0] == '#') {
277 Flag_PRE = 1; *lres = -atoi(argv[i]+1); i++;
278 }
279 else if (i < argc && argv[i][0] != '-') {
280 Flag_PRE = 1; Name_Resolution = strSave(argv[i]); i++;
281 }
282 else {
283 Flag_PRE = *lres = 1;
284 }
285 }
286
287 else if (!strcmp(argv[i]+1, "order") ||
288 !strcmp(argv[i]+1, "ord")) {
289 i++;
290 if (i < argc && argv[i][0] != '-') {
291 Flag_ORDER = atof(argv[i]); i++;
292 }
293 else {
294 Message::Error("Missing interpolation order");
295 }
296 }
297
298 else if (!strcmp(argv[i]+1, "solver")) {
299 // fix when calling getdp from gmsh (since the GUI forces us
300 // to put the -solver option before the .pro file!)
301 sargv[(*sargc)++] = argv[i++];
302 if (i < argc && argv[i][0] != '-') {
303 sargv[(*sargc)++] = argv[i++];
304 }
305 else {
306 Message::Error("Missing solver option file name");
307 }
308 }
309
310 else if (!strcmp(argv[i]+1, "slepc")) {
311 Flag_SLEPC = 1; i++;
312 }
313
314 else if (!strcmp(argv[i]+1, "solve") ||
315 !strcmp(argv[i]+1, "sol")) {
316 i++;
317 if (i < argc && argv[i][0] == '#') {
318 Flag_PRE = Flag_CAL = 1; *lres = -atoi(argv[i]+1); i++;
319 }
320 else if (i < argc && argv[i][0] != '-') {
321 Flag_PRE = Flag_CAL = 1; Name_Resolution = strSave(argv[i]); i++;
322 }
323 else {
324 Flag_PRE = Flag_CAL = *lres = 1;
325 }
326 }
327
328 else if (!strcmp(argv[i]+1, "post") ||
329 !strcmp(argv[i]+1, "pos")) {
330 i++; j = 0;
331 if (i < argc && argv[i][0] == '#') {
332 Flag_POS = 1; *lpos = -atoi(argv[i]+1); i++;
333 } /* Only one numbered (#) PostOperation allowed */
334 else {
335 while (i < argc && argv[i][0] != '-') {
336 Name_PostOperation[j] = strSave(argv[i]); i++; j++;
337 if(j == NBR_MAX_POS){
338 Message::Error("Too many PostOperations");
339 break;
340 }
341 }
342 if(!j){
343 Flag_POS = *lpos = 1;
344 }
345 else{
346 Flag_POS = 1;
347 Name_PostOperation[j] = NULL;
348 }
349 }
350 }
351
352 else if (!strcmp(argv[i]+1, "mesh") ||
353 !strcmp(argv[i]+1, "msh") ||
354 !strcmp(argv[i]+1, "m")) {
355 i++;
356 if (i < argc && argv[i][0] != '-') {
357 Name_MshFile = strSave(argv[i]); i++;
358 }
359 else {
360 Message::Error("Missing file name");
361 }
362 }
363
364 else if (!strcmp(argv[i]+1, "msh_scaling")) {
365 i++;
366 if (i < argc && argv[i][0] != '-') {
367 Flag_MSH_SCALING = atof(argv[i]); i++;
368 }
369 else {
370 Message::Error("Missing scaling value");
371 }
372 }
373
374 else if (!strcmp(argv[i]+1, "adapt") ||
375 !strcmp(argv[i]+1, "adap") ||
376 !strcmp(argv[i]+1, "ada")) {
377 i++;
378 if (i < argc && argv[i][0] != '-') {
379 Name_AdaptFile = strSave(argv[i]); i++;
380 }
381 else {
382 Message::Error("Missing file name");
383 }
384 }
385
386 else if (!strcmp(argv[i]+1, "res")) {
387 i++; j = 0;
388 while (i < argc && argv[i][0] != '-') {
389 Name_ResFile[j] = strSave(argv[i]); i++; j++;
390 if(j == NBR_MAX_RES){
391 Message::Error("Too many '.res' files");
392 break;
393 }
394 }
395 if(!j)
396 Message::Error("Missing file name");
397 else{
398 Name_ResFile[j] = NULL;
399 }
400 }
401
402 else if (!strcmp(argv[i]+1, "gmshread")) {
403 for(int k = 0; k < NBR_MAX_RES; k++) Tag_GmshReadFile[k] = -1;
404 i++; j = 0;
405 while (i < argc && argv[i][0] != '-') {
406 Name_GmshReadFile[j] = strSave(argv[i]); i++; j++;
407 if(j == NBR_MAX_RES){
408 Message::Error("Too many GmshRead files");
409 break;
410 }
411 }
412 if(!j)
413 Message::Error("Missing file name");
414 else{
415 Name_GmshReadFile[j] = NULL;
416 }
417 }
418
419 else if (!strcmp(argv[i]+1, "gmshtag")) {
420 for(int k = 0; k < NBR_MAX_RES; k++) Tag_GmshReadFile[k] = -1;
421 i++; j = 0;
422 while (i < argc && argv[i][0] != '-') {
423 Tag_GmshReadFile[j] = atoi(argv[i]); i++; j++;
424 if(j == NBR_MAX_RES){
425 Message::Error("Too many tags");
426 break;
427 }
428 }
429 if(!j)
430 Message::Error("Missing tag");
431 }
432
433 else if (!strcmp(argv[i]+1, "name")) {
434 i++;
435 if (i < argc && argv[i][0] != '-') {
436 Name_Generic = strSave(argv[i]); i++;
437 }
438 else {
439 Message::Error("Missing string");
440 }
441 }
442
443 else if (!strcmp(argv[i]+1, "petscinfo") ||
444 !strcmp(argv[i]+1, "-petscinfo")) {
445 sargv[(*sargc)++] = (char*)"-info";
446 i++;
447 }
448
449 else {
450 sargv[(*sargc)++] = argv[i++];
451 }
452
453 }
454 else{
455 if (!strlen(pro)) {
456 sargv[0] = argv[i];
457 strcpy(pro, argv[i++]);
458 }
459 else{
460 sargv[(*sargc)++] = argv[i++];
461 }
462 }
463
464 }
465
466 if(!strlen(pro)){
467 Message::Error("Missing input file name");
468 Name_Generic = strSave("");
469 *sargc = 0;
470 }
471 else{
472 if(!Name_Generic){
473 Name_Generic = strSave(pro);
474 if(strcmp(pro+(strlen(pro)-4), ".pro") &&
475 strcmp(pro+(strlen(pro)-4), ".PRO"))
476 strcat(pro,".pro");
477 else
478 Name_Generic[strlen(pro)-4] = '\0';
479 }
480 else{
481 std::string fix = Fix_RelativePath(Name_Generic, pro);
482 Free(Name_Generic);
483 Name_Generic = strSave(fix.c_str());
484 if(strcmp(pro+(strlen(pro)-4), ".pro") &&
485 strcmp(pro+(strlen(pro)-4), ".PRO"))
486 strcat(pro,".pro");
487 }
488
489 Name_Path = strSave(Name_Generic);
490 i = strlen(Name_Path)-1;
491 while(i >= 0 && Name_Path[i] != '/' && Name_Path[i] != '\\') i--;
492 Name_Path[i+1] = '\0';
493 }
494 }
495
496 #if defined(HAVE_GMSH)
497 class GmshMsg : public GmshMessage{
498 public:
operator ()(std::string level,std::string msg)499 void operator()(std::string level, std::string msg)
500 {
501 if(level == "Fatal")
502 Message::Fatal("%s", msg.c_str());
503 else if(level == "Error")
504 Message::Error("%s", msg.c_str());
505 else if(level == "Warning")
506 Message::Warning("%s", msg.c_str());
507 else if(level == "Progress"){
508 }
509 else
510 Message::Info("%s", msg.c_str());
511 }
512 };
513 #endif
514
Free_GlobalVariables()515 static void Free_GlobalVariables()
516 {
517 Flag_PRE = 0; Flag_CAL = 0; Flag_POS = 0; Flag_RESTART = 0;
518 Flag_XDATA = 0; Flag_BIN = 0; Flag_SPLIT = 0; Flag_GMSH_VERSION = 1;
519 Flag_NETWORK_CACHE = 0;
520 Flag_ORDER = -1.;
521 Free(Name_Generic); Name_Generic = 0;
522 Free(Name_Path); Name_Path = 0;
523 Free(Name_Resolution); Name_Resolution = 0;
524 Free(Name_MshFile); Name_MshFile = 0;
525 Free(Name_AdaptFile); Name_AdaptFile = 0;
526 int i = 0;
527 while(Name_PostOperation[i]){
528 Free(Name_PostOperation[i]); Name_PostOperation[i] = 0; i++;
529 }
530 i = 0;
531 while(Name_ResFile[i]){
532 Free(Name_ResFile[i]); Name_ResFile[i] = 0; i++;
533 }
534 i = 0;
535 while(Name_GmshReadFile[i]){
536 Free(Name_GmshReadFile[i]); Name_GmshReadFile[i] = 0; i++;
537 }
538 Free_ProblemStructure();
539 Free_ParserVariables();
540 }
541
getdpPrintNumbers()542 void getdpPrintNumbers()
543 {
544 for(std::map<std::string, std::vector<double> >::iterator
545 it = GetDPNumbers.begin(); it != GetDPNumbers.end(); it++){
546 printf("%s() = {", it->first.c_str());
547 for(unsigned int i = 0; i < it->second.size(); i++){
548 if(i) printf(", ");
549 printf("%g", it->second[i]);
550 }
551 printf("};\n");
552 }
553 }
554
getdpPrintStrings()555 void getdpPrintStrings()
556 {
557 for(std::map<std::string, std::vector<std::string> >::iterator
558 it = GetDPStrings.begin(); it != GetDPStrings.end(); it++){
559 printf("%s() = {", it->first.c_str());
560 for(unsigned int i = 0; i < it->second.size(); i++){
561 if(i) printf(", ");
562 printf("%s", it->second[i].c_str());
563 }
564 printf("};\n");
565 }
566 }
567
getdpClearNumbers()568 void getdpClearNumbers()
569 {
570 GetDPNumbers.clear();
571 }
572
getdpSetNumber(const std::string & name,double value)573 void getdpSetNumber(const std::string &name, double value)
574 {
575 GetDPNumbers[name] = std::vector<double>(1, value);
576 CommandLineNumbers[name] = std::vector<double>(1, value);
577 }
578
getdpSetNumber(const std::string & name,const std::vector<double> & value)579 void getdpSetNumber(const std::string &name, const std::vector<double> &value)
580 {
581 GetDPNumbers[name] = value;
582 CommandLineNumbers[name] = value;
583 }
584
getdpGetNumber(const std::string & name)585 std::vector<double> &getdpGetNumber(const std::string &name)
586 {
587 return GetDPNumbers[name];
588 }
589
getdpClearStrings()590 void getdpClearStrings()
591 {
592 GetDPStrings.clear();
593 }
594
getdpSetString(const std::string & name,const std::string & value)595 void getdpSetString(const std::string &name, const std::string &value)
596 {
597 GetDPStrings[name] = std::vector<std::string>(1, value);
598 CommandLineStrings[name] = std::vector<std::string>(1, value);
599 }
600
getdpSetString(const std::string & name,const std::vector<std::string> & value)601 void getdpSetString(const std::string &name, const std::vector<std::string> &value)
602 {
603 GetDPStrings[name] = value;
604 CommandLineStrings[name] = value;
605 }
606
getdpGetString(const std::string & name)607 std::vector<std::string> &getdpGetString(const std::string &name)
608 {
609 return GetDPStrings[name];
610 }
611
MainKernel(int argc,char * argv[])612 int MainKernel(int argc, char *argv[])
613 {
614 if(argc < 2) Info(0, argv[0]);
615
616 std::string cmdline("");
617 for(int i = 0; i < argc; i++){
618 if(i) cmdline += " ";
619 cmdline += argv[i];
620 }
621
622 Message::Initialize(argc, argv);
623
624 char pro[256];
625 char **sargv = (char**)Malloc(256 * sizeof(char*));
626 int sargc, lres = 0, lpos = 0, check = 0;
627 Get_Options(argc, argv, &sargc, sargv, pro, &lres, &lpos, &check);
628
629 if(Message::GetErrorCount()){
630 Message::Finalize();
631 return Message::GetErrorCount();
632 }
633 Message::Info("Running '%s' [GetDP %s, %d node%s, max. %d thread%s]",
634 cmdline.c_str(), GETDP_VERSION,
635 Message::GetCommSize(), Message::GetCommSize() > 1 ? "s" : "",
636 Message::GetMaxThreads(), Message::GetMaxThreads() > 1 ? "s" : "");
637 Message::Cpu(3, true, true, true, true, true, "Started");
638
639 if(sargc > 1){
640 std::string solveropt("");
641 for(int i = 1; i < sargc; i++){
642 if(i > 1) solveropt += " ";
643 solveropt += sargv[i];
644 }
645 Message::Debug("Passing unused options to solver: '%s'", solveropt.c_str());
646 }
647
648 if(!Name_ResFile[0]){
649 Name_ResFile[0] = (char*)Malloc((strlen(Name_Generic)+5)*sizeof(char));
650 strcpy(Name_ResFile[0], Name_Generic);
651 strcat(Name_ResFile[0], ".res");
652 Name_ResFile[1] = 0;
653 }
654
655 if(!Name_MshFile){
656 std::string name = Message::GetOnelabString("Gmsh/MshFileName");
657 if(name.size()){
658 Name_MshFile = strSave(name.c_str());
659 Message::Info("Got mesh name from Onelab: '%s'", Name_MshFile);
660 }
661 }
662 if(!Name_MshFile){
663 Name_MshFile = (char*)Malloc((strlen(Name_Generic)+5)*sizeof(char));
664 strcpy(Name_MshFile, Name_Generic);
665 strcat(Name_MshFile, ".msh");
666 }
667
668 #if defined(HAVE_GMSH)
669 Message::Info("Initializing Gmsh");
670 gmsh::initialize();
671 gmsh::option::setNumber("General.Terminal", 0);
672 GmshMsg *msg = 0;
673 if(!GmshGetMessageHandler() && !Flag_CALLED_WITH_ONELAB_SERVER){
674 // do not set msg handler if one is provided (e.g. on Android/iOS)
675 msg = new GmshMsg;
676 GmshSetMessageHandler(msg);
677 }
678 int j = 0;
679 while(Name_GmshReadFile[j]){
680 if(Tag_GmshReadFile[j] >= 0){
681 PView::setGlobalTag(Tag_GmshReadFile[j]);
682 Message::Info("GmshRead[%s] -> View[%d]", Name_GmshReadFile[j], Tag_GmshReadFile[j]);
683 }
684 else{
685 Message::Info("GmshRead[%s]", Name_GmshReadFile[j]);
686 }
687 GmshMergePostProcessingFile(Name_GmshReadFile[j]);
688 j++;
689 }
690 #endif
691
692 IncreaseStackSize();
693 LinAlg_InitializeSolver(&sargc, &sargv);
694
695 Init_ProblemStructure();
696 Read_ProblemPreamble();
697 Read_ProblemStructure(pro);
698 Finalize_ProblemStructure();
699
700 int choose = 1;
701 if (!Flag_PRE && !Flag_CAL && !Flag_POS && !check){
702 lres = lpos = 1;
703 choose = 0;
704 }
705
706 if(lres)
707 Print_ListResolution(choose, lres, &Name_Resolution);
708
709 if(lpos)
710 Print_ListPostOperation(choose, lpos, Name_PostOperation);
711
712 if(check){
713 Print_ProblemStructure();
714 }
715 else{
716 check = Message::GetOnelabNumber
717 (Message::GetOnelabClientName() + "/}ModelCheck");
718 if(check) Print_Object(check - 1);
719 }
720
721 if(Flag_PRE || Flag_CAL || Flag_POS)
722 SolvingAnalyse();
723
724 // PETSc cannot be finalized if it will be re-initialized again in the same
725 // process - so just don't finalize it if we use getdp as a library with a
726 // provided onelab server (e.g. for the mobile apps)
727 if(!Flag_CALLED_WITH_ONELAB_SERVER)
728 LinAlg_FinalizeSolver();
729
730 Message::PrintErrorCounter("Run");
731 Message::Cpu(3, true, true, true, true, true, "Stopped");
732
733 if(Message::GetVerbosity() == 99){ // debug
734 getdpPrintNumbers();
735 getdpPrintStrings();
736 }
737
738 #if defined(HAVE_GMSH)
739 if(!Flag_CALLED_WITH_ONELAB_SERVER) GmshFinalize();
740 if(msg) delete msg;
741 #endif
742
743 Free_GlobalVariables();
744 Free(sargv);
745 Message::Finalize();
746 return Message::GetErrorCount();
747 }
748
getdp(const std::vector<std::string> & args,void * ptr)749 int getdp(const std::vector<std::string> &args, void *ptr)
750 {
751 onelab::server *onelabServer = (onelab::server*) ptr;
752 if(onelabServer != NULL){
753 onelab::server::setInstance(onelabServer);
754 Flag_CALLED_WITH_ONELAB_SERVER = 1;
755 Message::SetExitOnError(2); // throw exception on error
756 }
757 int argc = args.size();
758 std::vector<char*> argv(argc + 1, (char*)0);
759 for(int i = 0; i < argc; i++) argv[i] = (char*)args[i].c_str();
760 return MainKernel(argc, &argv[0]);
761 }
762