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 <stdlib.h>
7 #include <string.h>
8 #include <string>
9 #include <set>
10 #include "GetDPConfig.h"
11 #include "ProData.h"
12 #include "ProDefine.h"
13 #include "ProParser.h"
14 #include "MacroManager.h"
15 #include "Message.h"
16 #include "MallocUtils.h"
17 #include "OS.h"
18 
19 #if defined(HAVE_KERNEL)
20 #include "Generate_Network.h"
21 #endif
22 
23 // Global problem structure: this is the only problem structure that
24 // is instanciated, and it is filled by the parser
25 struct Problem Problem_S;
26 
27 // Global run-time current data: this is the only current data
28 // structure that is instantiated
29 struct CurrentData Current;
30 
31 // Sorting functions
32 
fcmp_Integer(const void * a,const void * b)33 int fcmp_Integer(const void *a, const void *b)
34 {
35   return(*(int*)a - *(int*)b );
36 }
37 
fcmp_Integer2(const void * a,const void * b)38 int fcmp_Integer2(const void *a, const void *b)
39 {
40   static int result ;
41   if ( ( result = (*(int*)a - *(int*)b ) ) != 0 )  return result ;
42   return (*((int*)a+1) - *((int*)b+1) );
43 }
44 
fcmp_Constant(const void * a,const void * b)45 int fcmp_Constant (const void *a, const void *b)
46 {
47   return ( strcmp(((struct Constant *)a)->Name, ((struct Constant *)b)->Name));
48 }
49 
fcmp_Expression_Name(const void * a,const void * b)50 int fcmp_Expression_Name(const void *a, const void *b)
51 {
52   return ( strcmp((char *)a, ((struct Expression *)b)->Name ) );
53 }
54 
fcmp_Group_Name(const void * a,const void * b)55 int fcmp_Group_Name(const void *a, const void *b)
56 {
57   return ( strcmp((char *)a, ((struct Group *)b)->Name ) );
58 }
59 
fcmp_Constraint_Name(const void * a,const void * b)60 int fcmp_Constraint_Name(const void *a, const void *b)
61 {
62   return ( strcmp((char *)a, ((struct Constraint *)b)->Name ) );
63 }
64 
fcmp_JacobianMethod_Name(const void * a,const void * b)65 int fcmp_JacobianMethod_Name(const void *a, const void *b)
66 {
67   return ( strcmp((char *)a, ((struct JacobianMethod *)b)->Name ) );
68 }
69 
fcmp_IntegrationMethod_Name(const void * a,const void * b)70 int fcmp_IntegrationMethod_Name(const void *a, const void *b)
71 {
72   return ( strcmp((char *)a, ((struct IntegrationMethod *)b)->Name ) );
73 }
74 
fcmp_BasisFunction_Name(const void * a,const void * b)75 int fcmp_BasisFunction_Name(const void *a, const void *b)
76 {
77   return ( strcmp((char *)a, ((struct BasisFunction *)b)->Name ) );
78 }
79 
fcmp_FunctionSpace_Name(const void * a,const void * b)80 int fcmp_FunctionSpace_Name(const void *a, const void *b)
81 {
82   return ( strcmp((char *)a, ((struct FunctionSpace *)b)->Name ) );
83 }
84 
fcmp_BasisFunction_NameOfCoef(const void * a,const void * b)85 int fcmp_BasisFunction_NameOfCoef(const void *a, const void *b)
86 {
87   return ( strcmp((char *)a, ((struct BasisFunction *)b)->NameOfCoef ) );
88 }
89 
fcmp_SubSpace_Name(const void * a,const void * b)90 int fcmp_SubSpace_Name(const void *a, const void *b)
91 {
92   return ( strcmp((char *)a, ((struct SubSpace *)b)->Name ) );
93 }
94 
fcmp_GlobalQuantity_Name(const void * a,const void * b)95 int fcmp_GlobalQuantity_Name(const void *a, const void *b)
96 {
97   return ( strcmp((char *)a, ((struct GlobalQuantity *)b)->Name ) );
98 }
99 
fcmp_Formulation_Name(const void * a,const void * b)100 int fcmp_Formulation_Name(const void *a, const void *b)
101 {
102   return ( strcmp((char *)a, ((struct Formulation *)b)->Name ) );
103 }
104 
fcmp_DefineQuantity_Name(const void * a,const void * b)105 int fcmp_DefineQuantity_Name(const void *a, const void *b)
106 {
107   return ( strcmp((char *)a, ((struct DefineQuantity *)b)->Name ) );
108 }
109 
fcmp_DefineSystem_Name(const void * a,const void * b)110 int fcmp_DefineSystem_Name(const void *a, const void *b)
111 {
112   return ( strcmp((char *)a, ((struct DefineSystem *)b)->Name ) );
113 }
114 
fcmp_Resolution_Name(const void * a,const void * b)115 int fcmp_Resolution_Name(const void *a, const void *b)
116 {
117   return ( strcmp((char *)a, ((struct Resolution *)b)->Name ) );
118 }
119 
fcmp_PostProcessing_Name(const void * a,const void * b)120 int fcmp_PostProcessing_Name(const void *a, const void *b)
121 {
122   return ( strcmp((char *)a, ((struct PostProcessing *)b)->Name ) );
123 }
124 
fcmp_PostQuantity_Name(const void * a,const void * b)125 int fcmp_PostQuantity_Name(const void *a, const void *b)
126 {
127   return ( strcmp((char *)a, ((struct PostQuantity *)b)->Name ) );
128 }
129 
fcmp_PostOperation_Name(const void * a,const void * b)130 int fcmp_PostOperation_Name(const void *a, const void *b)
131 {
132   return ( strcmp((char *)a, ((struct PostOperation *)b)->Name ) );
133 }
134 
135 // I/O routines
136 
Init_ProblemStructure()137 void Init_ProblemStructure()
138 {
139   Problem_S.Group             = NULL ;
140   Problem_S.Expression        = NULL ;
141   Problem_S.FunctionSpace     = NULL ;
142   Problem_S.Constraint        = NULL ;
143   Problem_S.Formulation       = NULL ;
144   Problem_S.JacobianMethod    = NULL ;
145   Problem_S.IntegrationMethod = NULL ;
146   Problem_S.Resolution        = NULL ;
147   Problem_S.PostProcessing    = NULL ;
148   Problem_S.PostOperation     = NULL ;
149 
150   Current.Name = NULL;
151   Current.NbrSystem = 0;
152   Current.DefineSystem_P = NULL ;
153   Current.DofData_P0 = NULL;
154   Current.DofData = NULL;
155   Current.GeoData = NULL;
156   Current.PostOpData_L = NULL;
157   Current.PostOpDataIndex = 0;
158   Current.NbrHar = 0;
159   Current.Region = 0;
160   Current.SubRegion = 0;
161   Current.NumEntity = 0;
162   Current.NumEntityInElement = 0;
163   Current.NumEntities[0] = 0;
164   Current.Element = NULL;
165   Current.IntegrationSupportIndex = 0;
166   Current.ElementSource = 0;
167   Current.SourceIntegrationSupportIndex = 0;
168   Current.TypeTime = 0;
169   Current.TypeAssembly = 0;
170   Current.SubTimeStep = 0;
171   Current.flagAssDiag = 0;
172   Current.x = 0.0;
173   Current.y = 0.0;
174   Current.z = 0.0;
175   Current.u = 0.0;
176   Current.v = 0.0;
177   Current.w = 0.0;
178   Current.xs = 0.0;
179   Current.ys = 0.0;
180   Current.zs = 0.0;
181   Current.us = 0.0;
182   Current.vs = 0.0;
183   Current.ws = 0.0;
184   Current.a = 0.0;
185   Current.b = 0.0;
186   Current.c = 0.0;
187   Current.xp = 0.0;
188   Current.yp = 0.0;
189   Current.zp = 0.0;
190   Current.ut = 0.0;
191   Current.vt = 0.0;
192   Current.wt = 0.0;
193   Current.Val[0] = 0.0;
194   Current.QuadraturePointIndex = 0.0;
195   Current.Time = 0.0;
196   Current.TimeImag = 0.0;
197   Current.TimeStep = 0.0;
198   Current.DTime = 0.0;
199   Current.Theta = 0.0;
200   Current.Beta = 0.0;
201   Current.Gamma = 0.0;
202   Current.PredOrder = 0.0;
203   Current.CorrOrder = 0.0;
204   Current.aPredCoeff[0] = 0.0;
205   Current.aCorrCoeff[0] = 0.0;
206   Current.bCorrCoeff = 0.0;
207   Current.PredErrorConst = 0.0;
208   Current.CorrErrorConst = 0.0;
209   Current.Breakpoint = 0.0;
210   Current.Iteration = 0.0;
211   Current.Residual = 0.0;
212   Current.ResidualN = 0.0; //+++
213   Current.Residual_Iter1 = 1.0; //+++
214   Current.RelativeDifference = 0.0;
215   Current.RelativeDifferenceOld = 0.0;
216   Current.RelaxationFactor = 0.0;
217   Current.RelaxFac = 0.0; //+++
218   Current.NbrTestedFac = 0.0; //+++
219   Current.SolveJacAdaptFailed = 0.0; //+++
220   Current.KSPIterations = 0.0;
221   Current.KSPIteration = 0.0;
222   Current.KSPResidual = 0.0;
223   Current.KSPSystemSize = 0.0;
224 }
225 
226 // FIXME: TODO to remove parser memory leaks!
Free_Group(struct Group * a)227 void Free_Group(struct Group* a)
228 {
229   // we should convert all the structs into classes and add a default
230   // constructor with proper initializations ; cleanup the parser to make sure
231   // who owns what, so we can safely delete
232   //
233   // List_Delete(a->ExtendedList); List_Delete(a->ExtendedSuppList);
234 }
Free_Expression(struct Expression * a)235 void Free_Expression(struct Expression* a){}
Free_FunctinSpace(struct FunctionSpace * a)236 void Free_FunctinSpace(struct FunctionSpace* a){}
Free_Constraint(struct Constraint * a)237 void Free_Constraint(struct Constraint* a){}
Free_Formulation(struct Formuation * a)238 void Free_Formulation(struct Formuation* a){}
Free_JacobianMethod(struct JacobianMethod * a)239 void Free_JacobianMethod(struct JacobianMethod* a){}
Free_IntegrationMethod(struct IntegrationMethod * a)240 void Free_IntegrationMethod(struct IntegrationMethod* a){}
Free_Resolution(struct Resolution * a)241 void Free_Resolution(struct Resolution* a){}
Free_PostProcessing(struct PostProcessing * a)242 void Free_PostProcessing(struct PostProcessing* a){}
Free_PostOperation(struct PostOperation * a)243 void Free_PostOperation(struct PostOperation* a){}
244 
Free_ProblemStructure()245 void Free_ProblemStructure()
246 {
247   if(Problem_S.Group){
248     for(int i = 0; i < List_Nbr(Problem_S.Group); i++)
249       Free_Group((Group*)List_Pointer(Problem_S.Group, i));
250     List_Delete(Problem_S.Group);
251   }
252   if(Problem_S.Expression){
253     for(int i = 0; i < List_Nbr(Problem_S.Expression); i++)
254       Free_Expression((Expression*)List_Pointer(Problem_S.Expression, i));
255     List_Delete(Problem_S.Expression);
256   }
257   if(Problem_S.FunctionSpace){
258     for(int i = 0; i < List_Nbr(Problem_S.FunctionSpace); i++)
259       Free_FunctinSpace((FunctionSpace*)List_Pointer(Problem_S.FunctionSpace, i));
260     List_Delete(Problem_S.FunctionSpace);
261   }
262   if(Problem_S.Constraint){
263     for(int i = 0; i < List_Nbr(Problem_S.Constraint); i++)
264       Free_Constraint((Constraint*)List_Pointer(Problem_S.Constraint, i));
265     List_Delete(Problem_S.Constraint);
266   }
267   if(Problem_S.Formulation){
268     for(int i = 0; i < List_Nbr(Problem_S.Formulation); i++)
269       Free_Formulation((Formuation*)List_Pointer(Problem_S.Formulation, i));
270     List_Delete(Problem_S.Formulation);
271   }
272   if(Problem_S.JacobianMethod){
273     for(int i = 0; i < List_Nbr(Problem_S.JacobianMethod); i++)
274       Free_JacobianMethod((JacobianMethod*)List_Pointer(Problem_S.JacobianMethod, i));
275     List_Delete(Problem_S.JacobianMethod);
276   }
277   if(Problem_S.IntegrationMethod){
278     for(int i = 0; i < List_Nbr(Problem_S.IntegrationMethod); i++)
279       Free_IntegrationMethod((IntegrationMethod*)List_Pointer(Problem_S.IntegrationMethod, i));
280     List_Delete(Problem_S.IntegrationMethod);
281   }
282   if(Problem_S.Resolution){
283     for(int i = 0; i < List_Nbr(Problem_S.Resolution); i++)
284       Free_Resolution((Resolution*)List_Pointer(Problem_S.Resolution, i));
285     List_Delete(Problem_S.Resolution);
286   }
287   if(Problem_S.PostProcessing){
288     for(int i = 0; i < List_Nbr(Problem_S.PostProcessing); i++)
289       Free_PostProcessing((PostProcessing*)List_Pointer(Problem_S.PostProcessing, i));
290     List_Delete(Problem_S.PostProcessing);
291   }
292   if(Problem_S.PostOperation){
293     for(int i = 0; i < List_Nbr(Problem_S.PostOperation); i++)
294       Free_PostOperation((PostOperation*)List_Pointer(Problem_S.PostOperation, i));
295     List_Delete(Problem_S.PostOperation);
296   }
297   Init_ProblemStructure();
298 }
299 
Fix_RelativePath(const char * name,const char * reference)300 std::string Fix_RelativePath(const char *name, const char *reference)
301 {
302   if(!name || !strlen(name)) return "";
303 
304   std::string in(name);
305 
306   if(in[0] == '/' || in[0] == '\\' ||
307      (in.size() > 3 && in[1] == ':' && (in[2] == '/' || in[2] == '\\'))){
308     // do nothing: 'in' is an absolute path
309     return in;
310   }
311   else{
312     char AbsPath[2048];
313     strcpy(AbsPath, reference ? reference : getdp_yyname.c_str());
314     int i = strlen(AbsPath) - 1;
315     while(i >= 0 && AbsPath[i] != '/' && AbsPath[i] != '\\') i--;
316     AbsPath[i+1] = '\0';
317     return std::string(AbsPath) + in;
318   }
319 }
320 
321 #if !defined(HAVE_NX)
Read_ProblemPreamble()322 void Read_ProblemPreamble()
323 {
324   // no-op ; could be used to fill getdp_yystring in order to parse some
325   // definitions before the actuel .pro file processing starts.
326 }
327 #endif
328 
329 static std::vector<FILE*> openFiles;
330 
Read_ProblemStructure(const char * name)331 void Read_ProblemStructure(const char *name)
332 {
333   int Last_yylinenum = getdp_yylinenum;
334   std::string Last_yyname = getdp_yyname;
335   int Last_ErrorLevel = getdp_yyerrorlevel;
336   int Last_yyincludenum = getdp_yyincludenum;
337 
338   char AbsPath[4096];
339   int i;
340   bool absolute = false;
341 
342   if((strlen(name) > 0 && (name[0] == '/' || name[0] == '\\')) ||
343      (strlen(name) > 3 && name[1] == ':' && (name[2] == '\\' || name[2] == '/'))){
344     // name is an absolute path
345     absolute = true;
346     strcpy(AbsPath, name);
347   }
348   else{
349     strcpy(AbsPath, getdp_yyname.c_str());
350     i = getdp_yyname.size() - 1;
351     while(i >= 0 && getdp_yyname[i] != '/' && getdp_yyname[i] != '\\') i--;
352     AbsPath[i+1] = '\0';
353     strcat(AbsPath, name);
354   }
355 
356   Message::Info("Loading problem definition '%s'", AbsPath);
357 
358   Message::AddOnelabStringChoice(Message::GetOnelabClientName() + "/{Input files",
359                                  "file", AbsPath, true, true);
360 
361   // opening the file in text mode messes up the loops (they use
362   // fsetpos/fgetpos) on Windows without Cygwin; not sure why, but
363   // opening the file in binary mode fixes the problem
364   if(!(getdp_yyin = FOpen(AbsPath, "rb"))){
365     if(getdp_yyincludenum > 0 && !absolute){
366       // try to find included files in a standard directory
367       Message::Info("File `%s' not found, looking in $GETDP_TEMPLATES", AbsPath);
368       const char* template_dir = getenv("GETDP_TEMPLATES");
369       if(template_dir){
370         strcpy(AbsPath, template_dir);
371         strcat(AbsPath, "/");
372         strcat(AbsPath, name);
373         printf("trying to open %s\n", AbsPath);
374         if(!(getdp_yyin = FOpen(AbsPath, "rb"))){
375           Message::Error("Unable to open file '%s'", AbsPath);
376           return;
377         }
378       }
379       else{
380         Message::Error("No template directory defined");
381         return;
382       }
383     }
384     else{
385       Message::Error("Unable to open file '%s'", AbsPath);
386       return;
387     }
388   }
389 
390   getdp_yyerrorlevel = 0;  getdp_yylinenum = 1; getdp_yyincludenum = 0;
391   getdp_yyname = std::string(AbsPath);
392 
393   getdp_yyrestart(getdp_yyin); getdp_yyparse();
394   // don't close the file here: we'll need it if there is a Macro in it:
395   //fclose(getdp_yyin);
396   openFiles.push_back(getdp_yyin);
397 
398   if(getdp_yyerrorlevel) return;
399 
400   while(getdp_yyincludenum > 0){
401     Read_ProblemStructure(getdp_yyincludename);
402     getdp_yyin = FOpen(getdp_yyname.c_str(), "rb"); // same comment as above
403     getdp_yyrestart(getdp_yyin);
404     for(i = 0; i < getdp_yylinenum; i++){
405       if(!fgets(AbsPath, sizeof(AbsPath), getdp_yyin))
406         Message::Warning("Could not read line %d", getdp_yylinenum);
407     }
408     getdp_yylinenum++;
409     getdp_yyparse();
410     // don't close the file here: we'll need it if there is a Macro in it:
411     //fclose(getdp_yyin);
412     openFiles.push_back(getdp_yyin);
413     if(getdp_yyerrorlevel) return;
414   }
415 
416   level_include--;
417 
418   getdp_yylinenum = Last_yylinenum;
419   getdp_yyname = Last_yyname;
420   getdp_yyerrorlevel = Last_ErrorLevel;
421   getdp_yyincludenum = Last_yyincludenum;
422 }
423 
Finalize_ProblemStructure()424 void Finalize_ProblemStructure()
425 {
426   for(unsigned int i = 0; i < openFiles.size(); i++)
427     fclose(openFiles[i]);
428   openFiles.clear();
429   MacroManager::Instance()->clear();
430 }
431 
Get_ExpressionName(int Index)432 char *Get_ExpressionName(int Index)
433 {
434   return(((struct Expression *)List_Pointer(Problem_S.Expression, Index))->Name);
435 }
436 
Print_WholeQuantity(List_T * WholeQuantity,List_T * DQ_L)437 void Print_WholeQuantity(List_T *WholeQuantity, List_T *DQ_L)
438 {
439   int    j, k;
440   struct WholeQuantity *WQ;
441 
442   WQ = (struct WholeQuantity*)List_Pointer(WholeQuantity, 0);
443 
444   for (k = 0; k < List_Nbr(WholeQuantity); k++) {
445     switch ((WQ+k)->Type) {
446 
447     case WQ_OPERATORANDQUANTITY :
448       Message::Check(" {%s %s}",
449                      Get_StringForDefine
450                      (Operator_Type, (WQ+k)->Case.OperatorAndQuantity.TypeOperator),
451                      ((struct DefineQuantity *)
452                       List_Pointer(DQ_L, (WQ+k)->Case.OperatorAndQuantity.Index))
453                      ->Name);
454       break;
455 
456     case WQ_OPERATORANDQUANTITYEVAL :
457       Message::Check(" {%s %s} ExplicitEvaluation",
458                      Get_StringForDefine
459                      (Operator_Type, (WQ+k)->Case.OperatorAndQuantity.TypeOperator),
460                      ((struct DefineQuantity *)
461                       List_Pointer(DQ_L, (WQ+k)->Case.OperatorAndQuantity.Index))
462                      ->Name);
463       break;
464 
465     case WQ_BINARYOPERATOR :
466       switch ((WQ+k)->Case.Operator.TypeOperator) {
467       case OP_PLUS           : Message::Check(" +");  break;
468       case OP_MINUS          : Message::Check(" -");  break;
469       case OP_TIME           : Message::Check(" *");  break;
470       case OP_DIVIDE         : Message::Check(" /");  break;
471       case OP_MODULO         : Message::Check(" %%");  break;
472       case OP_POWER          : Message::Check(" ^");  break;
473       case OP_CROSSPRODUCT   : Message::Check(" x");  break;
474       case OP_LESS           : Message::Check(" <");  break;
475       case OP_GREATER        : Message::Check(" >");  break;
476       case OP_LESSOREQUAL    : Message::Check(" <=");  break;
477       case OP_GREATEROREQUAL : Message::Check(" >=");  break;
478       case OP_EQUAL          : Message::Check(" ==");  break;
479       case OP_NOTEQUAL       : Message::Check(" !=");  break;
480       case OP_APPROXEQUAL    : Message::Check(" ~=");  break;
481       case OP_AND            : Message::Check(" &&");  break;
482       case OP_OR             : Message::Check(" ||");  break;
483       default                : Message::Check(" UnknownBinaryOperator[]");  break;
484       }
485       break;
486 
487     case WQ_UNARYOPERATOR :
488       switch ((WQ+k)->Case.Operator.TypeOperator) {
489       case OP_NEG            : Message::Check(" -(unary)");  break;
490       case OP_NOT            : Message::Check(" !");  break;
491       default                : Message::Check(" UnknownUnaryOperator[]");  break;
492       }
493       break;
494 
495     case WQ_EXPRESSION :
496       Message::Check(" %s[]", ((struct Expression *)
497                                List_Pointer(Problem_S.Expression,
498                                             (WQ+k)->Case.Expression.Index))->Name);
499       break;
500 
501     case WQ_BUILTINFUNCTION :
502     case WQ_EXTERNBUILTINFUNCTION :
503       Message::Check(" %s", Get_StringForFunction2Nbr(F_Function,
504                                                       (WQ+k)->Case.Function.Fct));
505       if ((WQ+k)->Type == WQ_EXTERNBUILTINFUNCTION)  Message::Check("[.]");
506       if ((WQ+k)->Type == WQ_BUILTINFUNCTION)  Message::Check("[]");
507       if ((WQ+k)->Case.Function.NbrParameters) {
508 	Message::Check("{");
509 	for (j = 0; j < (WQ+k)->Case.Function.NbrParameters; j++) {
510 	  if (j)  Message::Check(",");
511 	  Message::Check(" %.10g", (WQ+k)->Case.Function.Para[j]);
512 	}  Message::Check(" }");
513       }
514       break;
515 
516     case WQ_CONSTANT :
517       Message::Check(" %.8g", (WQ+k)->Case.Constant);
518       break;
519 
520     case WQ_MHTRANSFORM :
521       Message::Check(" MHTransform[ ");
522       Message::Check("%s", Get_ExpressionName((WQ+k)->Case.MHTransform.Index));
523       Message::Check("[");
524       for(int i = 0; i < List_Nbr((WQ+k)->Case.MHTransform.WholeQuantity_L); i++){
525         List_T *wq; List_Read((WQ+k)->Case.MHTransform.WholeQuantity_L, i, &wq);
526         Print_WholeQuantity(wq, DQ_L);
527       }
528       Message::Check(" ] ]{ %d }", (WQ+k)->Case.MHTransform.NbrPoints);
529      break;
530 
531     case WQ_MHBILINEAR :
532       Message::Check(" MHBilinear[ ");
533       Message::Check("%s",
534                      Get_ExpressionName((WQ+k)->Case.MHBilinear.Index));
535       Message::Check("]{ %d, %d}", (WQ+k)->Case.MHBilinear.NbrPoints, (WQ+k)->Case.MHBilinear.FreqOffSet);
536       break;
537 
538     case WQ_TIMEDERIVATIVE :
539       Message::Check(" Dt[");
540       Print_WholeQuantity((WQ+k)->Case.TimeDerivative.WholeQuantity, DQ_L);
541       Message::Check(" ]");
542       break;
543 
544     case WQ_TRACE :
545       Message::Check(" Trace[");
546       Print_WholeQuantity((WQ+k)->Case.Trace.WholeQuantity, DQ_L);
547       Message::Check(" , %s ]", ((struct Group*)
548                                  List_Pointer(Problem_S.Group,
549                                               (WQ+k)->Case.Trace.InIndex))->Name);
550       break;
551 
552     case WQ_CAST :
553       if(!(WQ+k)->Case.Cast.NbrHar)
554 	Message::Check(" <%s>[",
555                        ((struct FunctionSpace *)
556                         List_Pointer(Problem_S.FunctionSpace,
557                                      (WQ+k)->Case.Cast.FunctionSpaceIndexForType))->Name);
558       else
559 	Message::Check(" <Real>[");
560       Print_WholeQuantity((WQ+k)->Case.Cast.WholeQuantity, DQ_L);
561       Message::Check(" ]");
562       break;
563 
564     case WQ_CURRENTVALUE :
565       Message::Check(" $%s",
566                      Get_StringForPointer(Current_Value,
567                                           (void *)((WQ+k)->Case.CurrentValue.Value)));
568       break;
569 
570     case WQ_ARGUMENT :
571       Message::Check(" $%d", (WQ+k)->Case.Argument.Index);
572       break;
573 
574     case WQ_TEST :
575       Message::Check(" ?");
576       Print_WholeQuantity((WQ+k)->Case.Test.WholeQuantity_True , DQ_L);
577       Message::Check(" :");
578       Print_WholeQuantity((WQ+k)->Case.Test.WholeQuantity_False, DQ_L);
579       break;
580 
581     case WQ_SAVEVALUE :
582       Message::Check(" ->#%d", (WQ+k)->Case.SaveValue.Index + 1);
583       break;
584 
585     case WQ_VALUESAVED :
586       Message::Check(" #%d", (WQ+k)->Case.ValueSaved.Index + 1);
587       break;
588 
589     case WQ_SAVENAMEDVALUE :
590       Message::Check(" ->$%s", (WQ+k)->Case.NamedValue.Name);
591       break ;
592 
593     case WQ_NAMEDVALUESAVED :
594       Message::Check(" $%s", (WQ+k)->Case.NamedValue.Name);
595       break ;
596 
597     case WQ_SHOWVALUE :
598       Message::Check(" ->show with prefix #%d", (WQ+k)->Case.ShowValue.Index + 1);
599       break;
600 
601     default :
602       Message::Check(" ???");
603       break;
604     }
605   }
606 }
607 
Print_Group()608 void Print_Group()
609 {
610   int    i, Nbr, j;
611   struct Group *GR;
612 
613   Nbr = List_Nbr(Problem_S.Group);
614 
615   Message::Check("Group {  /* nbr = %d */\n", Nbr);
616   Message::Check("\n");
617 
618   for (i = 0; i < Nbr; i++) {
619 
620     GR = (struct Group*)List_Pointer(Problem_S.Group, i);
621 
622     Message::Check("  %s = %s [", GR->Name,
623                    Get_StringForDefine(FunctionForGroup_Type, GR->FunctionType));
624 
625     if (GR->InitialList != NULL) {
626       Message::Check(" {");
627       for (j = 0; j < List_Nbr(GR->InitialList); j++)
628 	Message::Check(" %d", *((int *)List_Pointer(GR->InitialList, j)) );
629       Message::Check(" }");
630     }
631     else  Message::Check(" All");
632 
633     if (GR->InitialSuppList != NULL) {
634       if (GR->SuppListType != SUPPLIST_INSUPPORT) {
635 	Message::Check(", %s {",
636                        Get_StringForDefine(FunctionForGroup_SuppList, GR->SuppListType));
637 	for (j = 0; j < List_Nbr(GR->InitialSuppList); j++)
638 	  Message::Check(" %d", *((int *)List_Pointer(GR->InitialSuppList, j)) );
639 	Message::Check(" }");
640       }
641       else {
642 	Message::Check(", %s",
643                        Get_StringForDefine(FunctionForGroup_SuppList, GR->SuppListType));
644 	Message::Check(" %s",
645                        ((struct Group *)
646                         List_Pointer(Problem_S.Group,
647                                      *((int *)List_Pointer(GR->InitialSuppList, 0))))
648                        ->Name);
649       }
650     }
651 
652     if (GR->InitialSuppList2 != NULL) {
653       if (GR->SuppListType2 != SUPPLIST_INSUPPORT) {
654 	Message::Check(", %s {",
655                        Get_StringForDefine(FunctionForGroup_SuppList, GR->SuppListType2));
656 	for (j = 0; j < List_Nbr(GR->InitialSuppList2); j++)
657 	  Message::Check(" %d", *((int *)List_Pointer(GR->InitialSuppList2, j)) );
658 	Message::Check(" }");
659       }
660       else {
661 	Message::Check(", %s",
662                        Get_StringForDefine(FunctionForGroup_SuppList, GR->SuppListType2));
663 	Message::Check(" %s",
664                        ((struct Group *)
665                         List_Pointer(Problem_S.Group,
666                                      *((int *)List_Pointer(GR->InitialSuppList2, 0))))
667                        ->Name);
668       }
669     }
670 
671     Message::Check(" ]");
672 
673     if (GR->Type == MOVINGBAND2D) {
674       Message::Check("  = MovingBand2D [ {");
675 
676       for (j = 0; j < List_Nbr(GR->MovingBand2D->InitialList1); j++)
677 	Message::Check(" %d", *((int *)List_Pointer(GR->MovingBand2D->InitialList1, j)) );
678       Message::Check(" } , {");
679       for (j = 0; j < List_Nbr(GR->MovingBand2D->InitialList2); j++)
680 	Message::Check(" %d", *((int *)List_Pointer(GR->MovingBand2D->InitialList2, j)) );
681       Message::Check(" } ]");
682 
683     }
684 
685     Message::Check(";  /* Num %d */\n", i);
686   }
687 
688   Message::Check("\n");
689   Message::Check("}\n");
690 }
691 
Print_Expression()692 void Print_Expression()
693 {
694   int    i, Nbr, j;
695   struct Expression *EX;
696   struct ExpressionPerRegion *EXPR;
697 
698   Nbr = List_Nbr(Problem_S.Expression);
699 
700   Message::Check("Function {  /* nbr = %d */\n", Nbr);
701   Message::Check("\n");
702 
703   for (i = 0; i < Nbr; i++) {
704     EX = (struct Expression*)List_Pointer(Problem_S.Expression, i);
705 
706     switch (EX->Type) {
707     case CONSTANT :
708       Message::Check("  %s[] = %.10g;\n", EX->Name, EX->Case.Constant);
709       break;
710 
711     case WHOLEQUANTITY :
712       Message::Check("  %s[] = ", EX->Name);
713       Print_WholeQuantity(EX->Case.WholeQuantity, NULL);
714       Message::Check(";\n");
715       break;
716 
717     case PIECEWISEFUNCTION :
718       for (j = 0;
719 	   j < List_Nbr(EX->Case.PieceWiseFunction.ExpressionPerRegion); j++) {
720 	EXPR = (struct ExpressionPerRegion*)
721 	  List_Pointer(EX->Case.PieceWiseFunction.ExpressionPerRegion, j);
722 	Message::Check("  %s[%d] = Exp[%s];\n",
723                        EX->Name, EXPR->RegionIndex,
724                        Get_ExpressionName(EXPR->ExpressionIndex));
725       }
726       if (EX->Case.PieceWiseFunction.ExpressionIndex_Default >= 0) {
727 	Message::
728           Check("  %s[All] = Exp[%s];\n",
729                 EX->Name,
730                 Get_ExpressionName(EX->Case.PieceWiseFunction.ExpressionIndex_Default));
731       }
732       if (!List_Nbr(EX->Case.PieceWiseFunction.ExpressionPerRegion) &&
733           EX->Case.PieceWiseFunction.ExpressionIndex_Default < 0)
734 	Message::Check("  DefineFunction[ %s ];\n", EX->Name);
735       break;
736 
737     case PIECEWISEFUNCTION2 :
738       for (j = 0;
739 	   j < List_Nbr(EX->Case.PieceWiseFunction2.ExpressionPerRegion); j++) {
740         struct ExpressionPerRegion2 *EXPR;
741 	EXPR = (struct ExpressionPerRegion2*)
742 	  List_Pointer(EX->Case.PieceWiseFunction2.ExpressionPerRegion, j);
743 	Message::Check("  %s[%d,%d] = Exp[%s];\n",
744                        EX->Name, EXPR->RegionIndex[0], EXPR->RegionIndex[1],
745                        Get_ExpressionName(EXPR->ExpressionIndex));
746       }
747       if (EX->Case.PieceWiseFunction2.ExpressionIndex_Default >= 0) {
748 	Message::
749           Check("  %s[All,All] = Exp[%s];\n",
750                 EX->Name,
751                 Get_ExpressionName(EX->Case.PieceWiseFunction.ExpressionIndex_Default));
752       }
753       if (!List_Nbr(EX->Case.PieceWiseFunction2.ExpressionPerRegion) &&
754           EX->Case.PieceWiseFunction2.ExpressionIndex_Default < 0)
755 	Message::Check("  DefineFunction[ %s ];\n", EX->Name);
756       break;
757 
758     case UNDEFINED_EXP :
759       Message::Check("  DefineFunction[ %s ];\n", EX->Name);
760       break;
761 
762     default :
763       Message::Check("???;\n");
764       break;
765     }
766   }
767 
768   Message::Check("\n");
769   Message::Check("}\n");
770 }
771 
Print_Network(struct MultiConstraintPerRegion * MCPR_P)772 void Print_Network(struct MultiConstraintPerRegion *MCPR_P)
773 {
774   int    i, j;
775   struct ConstraintActive *CA;
776 
777   CA = MCPR_P->Active;
778 
779   Message::Check("NbrNode = %d, NbrBranch = %d\n",
780                  CA->Case.Network.NbrNode, CA->Case.Network.NbrBranch);
781   Message::Check("\n");
782 
783   Message::Check("MatNode (NbrNode x NbrBranch):\n");
784   for (i = 0; i < CA->Case.Network.NbrNode; i++) {
785     for (j = 0; j < CA->Case.Network.NbrBranch; j++) {
786       Message::Check("%2d ", CA->Case.Network.MatNode[i][j]);
787     }
788     Message::Check("\n");
789   }
790 
791   Message::Check("\n");
792 
793   Message::Check("MatLoop (NbrLoop x NbrBranch):\n");
794   for (i = 0; i < CA->Case.Network.NbrLoop; i++) {
795     for (j = 0; j < CA->Case.Network.NbrBranch; j++) {
796       Message::Check("%2d ", CA->Case.Network.MatLoop[i][j]);
797     }
798     Message::Check("\n");
799   }
800 }
801 
Print_Constraint()802 void Print_Constraint()
803 {
804   int    i, Nbr, j, Nbrj, k, Nbrk, index, index2;
805   struct Constraint *CO;
806   struct ConstraintPerRegion *CPR;
807   struct MultiConstraintPerRegion MCPR_S;
808 
809   Nbr = List_Nbr(Problem_S.Constraint);
810 
811   Message::Check("Constraint {  /* nbr = %d */\n", Nbr);
812   Message::Check("\n");
813 
814   for (i = 0; i < Nbr; i++) {
815     Message::Check(" /* Num : %d */\n", i);
816     CO = (struct Constraint*)List_Pointer(Problem_S.Constraint, i);
817     Message::Check("  { Name %s; Type %s;\n", CO->Name,
818                    Get_StringForDefine(Constraint_Type, CO->Type));
819 
820     if (CO->Type == NETWORK){
821       Nbrk = List_Nbr(CO->MultiConstraintPerRegion);
822       for (k = 0; k < Nbrk; k++) {
823 	List_Read(CO->MultiConstraintPerRegion, k, &MCPR_S);
824 	Message::Check("    Case %s {\n", MCPR_S.Name);
825 
826 	Nbrj = List_Nbr(MCPR_S.ConstraintPerRegion);
827 	for (j = 0; j < Nbrj; j++) {
828 	  CPR = (struct ConstraintPerRegion*)
829 	    List_Pointer(MCPR_S.ConstraintPerRegion, j);
830 	  Message::Check("      { Region %s;",
831                          ((struct Group *)
832                           List_Pointer(Problem_S.Group, CPR->RegionIndex))->Name);
833 	  Message::Check(" Branch { %d, %d };",
834                          CPR->Case.Network.Node1, CPR->Case.Network.Node2);
835 	  Message::Check(" }\n");
836 	}
837 #if defined(HAVE_KERNEL)
838 	if (!MCPR_S.Active)
839 	  MCPR_S.Active = Generate_Network(MCPR_S.Name, MCPR_S.ConstraintPerRegion);
840 #endif
841 	Print_Network(&MCPR_S);
842       }
843     }
844     else {
845       Message::Check("    Case {\n");
846       Nbrj = List_Nbr(CO->ConstraintPerRegion);
847       for (j = 0; j < Nbrj; j++) {
848 	CPR = (struct ConstraintPerRegion*)List_Pointer(CO->ConstraintPerRegion, j);
849 	Message::Check("      { Region %s;",
850                        ((struct Group *)
851                         List_Pointer(Problem_S.Group, CPR->RegionIndex))->Name);
852 	if (CPR->SubRegionIndex >= 0)
853 	  Message::Check(" SubRegion %s;",
854                          ((struct Group *)
855                           List_Pointer(Problem_S.Group, CPR->SubRegionIndex))->Name);
856 	if (CPR->Type != CO->Type)
857 	  Message::Check(" Type %s;", Get_StringForDefine(Constraint_Type, CPR->Type));
858 
859 	switch (CPR->Type) {
860 	case ASSIGN :
861 	case INIT :
862 	  Message::Check(" Value Exp[%s];",
863                          Get_ExpressionName(CPR->Case.Fixed.ExpressionIndex));
864 	  break;
865 	case ASSIGNFROMRESOLUTION :
866 	case INITFROMRESOLUTION :
867 	  Message::Check(" NameOfResolution %s;", CPR->Case.Solve.ResolutionName);
868 	  break;
869 	case CST_LINK :
870 	case CST_LINKCPLX :
871           if ( (index = CPR->Case.Link.RegionRefIndex) >= 0)
872             Message::Check(" RegionRef %s;",
873                            ((struct Group *)
874                             List_Pointer(Problem_S.Group, index))->Name);
875           if ( (index = CPR->Case.Link.SubRegionRefIndex) >= 0)
876             Message::Check(" SubRegionRef %s;",
877                            ((struct Group *)
878                             List_Pointer(Problem_S.Group, index))->Name);
879 
880           if ( (index = CPR->Case.Link.FilterIndex) >= 0) {
881             if ( (index2 = CPR->Case.Link.FilterIndex2) < 0)
882               Message::Check(" Filter Exp[%s];", Get_ExpressionName(index));
883             else
884               Message::Check(" Filter [ Exp[%s], Exp[%s] ];",
885                              Get_ExpressionName(index), Get_ExpressionName(index2));
886           }
887           if ( (index = CPR->Case.Link.FunctionIndex) >= 0) {
888             if ( (index2 = CPR->Case.Link.FunctionIndex2) < 0)
889               Message::Check(" Function Exp[%s];", Get_ExpressionName(index));
890             else
891               Message::Check(" Function [ Exp[%s], Exp[%s] ];",
892                              Get_ExpressionName(index), Get_ExpressionName(index2));
893           }
894           if ( (index = CPR->Case.Link.CoefIndex) >= 0) {
895             if ( (index2 = CPR->Case.Link.CoefIndex2) < 0)
896               Message::Check(" Coefficient Exp[%s];", Get_ExpressionName(index));
897             else
898               Message::Check(" Coefficient [ Exp[%s], Exp[%s] ];",
899                              Get_ExpressionName(index), Get_ExpressionName(index2));
900             }
901           Message::Check(" ToleranceFactor %g;",
902                          CPR->Case.Link.ToleranceFactor);
903 	  break;
904 	}
905 
906 	if (CPR->TimeFunctionIndex >= 0)
907 	  Message::Check(" TimeFunction Exp[%s];",
908                          Get_ExpressionName(CPR->TimeFunctionIndex));
909 
910 	Message::Check(" }\n");
911       }
912     }
913 
914     Message::Check("    }\n");
915     Message::Check("  }\n");
916 
917   }
918   Message::Check("\n");
919   Message::Check("}\n");
920 }
921 
Print_Jacobian()922 void Print_Jacobian()
923 {
924   int    i, Nbr, j, Nbrj, k;
925   struct JacobianMethod *JM;
926   struct JacobianCase *JC;
927 
928   Nbr = List_Nbr(Problem_S.JacobianMethod);
929 
930   Message::Check("Jacobian {  /* nbr = %d */\n", Nbr);
931   Message::Check("\n");
932 
933   for (i = 0; i < Nbr; i++) {
934     Message::Check(" /* Num : %d */\n", i);
935     JM = (struct JacobianMethod*)List_Pointer(Problem_S.JacobianMethod, i);
936     Message::Check("  { Name %s;\n", JM->Name);
937 
938     Message::Check("    Case {\n");
939     Nbrj = List_Nbr(JM->JacobianCase);
940     for (j = 0; j < Nbrj; j++) {
941       JC = (struct JacobianCase*)List_Pointer(JM->JacobianCase, j);
942 
943       Message::Check("      { Region ");
944       if (JC->RegionIndex >= 0)
945 	Message::Check("%s;", ((struct Group *)
946                                List_Pointer(Problem_S.Group, JC->RegionIndex))->Name);
947       else  Message::Check("All;");
948       Message::Check(" Jacobian %s",
949                      Get_StringForDefine1Nbr(Jacobian_Type, JC->TypeJacobian));
950       if (JC->NbrParameters) {
951 	for (k = 0; k < JC->NbrParameters; k++) {
952 	  if (k)  Message::Check(",");  else  Message::Check(" {");
953 	  Message::Check(" %.10g", JC->Para[k]);
954 	}  Message::Check(" }");
955       }
956       Message::Check(";");
957       if (JC->CoefficientIndex >= 0)
958 	Message::Check(" Coefficient Exp[%s];",
959                        Get_ExpressionName(JC->CoefficientIndex));
960       Message::Check(" }\n");
961     }
962     Message::Check("    }\n");
963     Message::Check("  }\n");
964 
965   }
966   Message::Check("\n");
967   Message::Check("}\n");
968 }
969 
Print_Integration()970 void Print_Integration()
971 {
972   int    i, j, k, Nbrm, Nbrc, Nbrq;
973   struct IntegrationMethod *IM;
974   struct IntegrationCase *IC;
975   struct Quadrature *Q;
976 
977   Nbrm = List_Nbr(Problem_S.IntegrationMethod);
978 
979   Message::Check("Integration {  /* nbr = %d */\n", Nbrm);
980   Message::Check("\n");
981 
982   for (i = 0; i < Nbrm; i++) {
983     Message::Check(" /* Num : %d */\n", i);
984     IM = (struct IntegrationMethod*)List_Pointer(Problem_S.IntegrationMethod, i);
985     Message::Check("  { Name %s; \n", IM->Name);
986     if(IM->CriterionIndex>=0)
987       Message::Check("    Criterion Exp[%s]; \n",
988                      Get_ExpressionName(IM->CriterionIndex));
989 
990     Nbrc = List_Nbr(IM->IntegrationCase);
991     Message::Check("    Case {");
992     Message::Check("   /* nbr = %d */\n", Nbrc);
993     for (j = 0; j < Nbrc; j++) {
994       IC = (struct IntegrationCase*)List_Pointer(IM->IntegrationCase, j);
995       Message::Check("       { Type %s;",
996                      Get_StringForDefine(Integration_Type, IC->Type));
997       switch (IC->Type) {
998       case GAUSS :
999 	Message::Check("\n");
1000 	Message::Check("         Case {\n");
1001 
1002 	Nbrq = List_Nbr(IC->Case);
1003 	for (k = 0; k < Nbrq; k++) {
1004 	  Q = (struct Quadrature*)List_Pointer(IC->Case, k);
1005 	  Message::Check("            { GeoElement %s; NumberOfPoints %d; }\n",
1006                          Get_StringForDefine(Element_Type, Q->ElementType),
1007                          Q->NumberOfPoints);
1008 	}
1009 	Message::Check("         }\n");
1010 	Message::Check("       }\n");  break;
1011 
1012       default :
1013 	Message::Check(" }\n");  break;
1014       }
1015     }
1016     Message::Check("    }\n");
1017     Message::Check("  }\n");
1018   }
1019   Message::Check("\n");
1020   Message::Check("}\n");
1021 }
1022 
Print_FunctionSpace()1023 void Print_FunctionSpace()
1024 {
1025   struct FunctionSpace *FS;
1026   struct BasisFunction *BF;
1027   struct SubSpace *SS;
1028   struct GlobalQuantity *GQ;
1029   struct ConstraintInFS *CO;
1030   List_T *BF_L, *SS_L, *GQ_L, *CO_L;
1031   int    i0, i, Nbr0, Nbr, j, Nbrj;
1032 
1033   Nbr0 = List_Nbr(Problem_S.FunctionSpace);
1034 
1035   Message::Check("FunctionSpace {  /* nbr = %d */\n", Nbr0);
1036   Message::Check("\n");
1037 
1038   for (i0=0; i0<Nbr0; i0++) {
1039 
1040     Message::Check(" /* Num : %d */\n", i0);
1041     FS = (struct FunctionSpace*)List_Pointer(Problem_S.FunctionSpace, i0);
1042     BF_L = FS->BasisFunction;  SS_L = FS->SubSpace;
1043     GQ_L = FS->GlobalQuantity;  CO_L = FS->Constraint;
1044 
1045     Message::Check("  { Name %s; Type %s;",
1046                    FS->Name, Get_StringForDefine(Field_Type, FS->Type));
1047     Message::Check("\n");
1048 
1049     Nbr = List_Nbr(BF_L);
1050     if (Nbr > 0) {
1051       Message::Check("    BasisFunction {\n");
1052       BF = (struct BasisFunction*)List_Pointer(BF_L, 0);
1053       for (i=0; i<Nbr; i++) {
1054 	Message::Check("    /* GlobalNum : %d */\n", BF->Num);
1055 	Message::Check("      Name %s; NameOfCoef %s; Function %s;\n",
1056                        BF->Name, BF->NameOfCoef,
1057                        Get_StringFor3Function3Nbr(BF_Function, BF->Function));
1058 	if (BF->SubFunction) {
1059 	  Message::Check("      SubFunction {");
1060 	  Nbrj = List_Nbr(BF->SubFunction);
1061 	  for (j=0; j<Nbrj; j++)
1062 	    Message::Check(" %s",
1063                            ((struct Expression *)
1064                             List_Pointer(Problem_S.Expression,
1065                                          *((int *)List_Pointer(BF->SubFunction, j))))->Name);
1066 	  Message::Check(" };\n");
1067 	}
1068 
1069 	if (BF->SubdFunction) {
1070 	  Message::Check("      SubdFunction {");
1071 	  Nbrj = List_Nbr(BF->SubdFunction);
1072 	  for (j=0; j<Nbrj; j++)
1073 	    Message::Check(" %s",
1074                            ((struct Expression *)
1075                             List_Pointer(Problem_S.Expression,
1076                                          *((int *)List_Pointer(BF->SubdFunction, j))))->Name);
1077 	  Message::Check(" };\n");
1078 	}
1079 
1080 	Message::Check("      Support %s;",
1081                        (BF->SupportIndex >=0)?
1082                        ((struct Group *)List_Pointer(Problem_S.Group, BF->SupportIndex))
1083                        ->Name : "?");
1084 	Message::Check(" Entity %s;\n",
1085                        (BF->EntityIndex >=0)?
1086                        ((struct Group *)List_Pointer(Problem_S.Group, BF->EntityIndex))
1087                        ->Name : "?");
1088 
1089 	BF += 1;
1090       }
1091       Message::Check("    }\n");
1092     }
1093 
1094     BF = (Nbr>0)? (struct BasisFunction*)List_Pointer(BF_L, 0) : NULL;
1095     Nbr = List_Nbr(SS_L);
1096     if (Nbr > 0) {
1097       Message::Check("    SubSpace {\n");
1098       SS = (struct SubSpace*)List_Pointer(SS_L, 0);
1099       for (i=0; i<Nbr; i++) {
1100 	Message::Check("      Name %s; NameOfBasisFunction {", SS->Name);
1101 	Nbrj = List_Nbr(SS->BasisFunction);
1102 	for (j=0; j<Nbrj; j++)
1103 	  Message::Check(" %s /* n%d */",
1104                          ((struct BasisFunction *)
1105                           List_Pointer(BF_L, *((int *)List_Pointer(SS->BasisFunction, j))))
1106                          ->Name, *((int *)List_Pointer(SS->BasisFunction, j)));
1107 	Message::Check(" };\n");
1108 	SS += 1;
1109       }
1110       Message::Check("    }\n");
1111     }
1112 
1113     Nbr = List_Nbr(GQ_L);
1114     if (Nbr > 0) {
1115       Message::Check("    GlobalQuantity {\n");
1116       GQ = (struct GlobalQuantity*)List_Pointer(GQ_L, 0);
1117       for (i=0; i<Nbr; i++) {
1118 	Message::Check("    /* GlobalNum : %d */\n", GQ->Num);
1119 	Message::Check("      Name %s; Type %s;",
1120                        GQ->Name,
1121                        Get_StringForDefine(GlobalQuantity_Type, GQ->Type));
1122 	Message::Check(" NameOfCoef %s;\n",
1123                        ((struct BasisFunction *)
1124                         List_Pointer(BF_L, GQ->ReferenceIndex))->NameOfCoef);
1125 	GQ += 1;
1126       }
1127       Message::Check("    }\n");
1128     }
1129 
1130     Nbr = List_Nbr(CO_L);
1131     if (Nbr > 0) {
1132       Message::Check("    Constraint {\n");
1133       CO = (struct ConstraintInFS*)List_Pointer(CO_L, 0);
1134       for (i=0; i<Nbr; i++) {
1135 	Message::Check("      NameOfCoef ");
1136 	if (CO->QuantityType == LOCALQUANTITY)
1137 	  Message::Check("%s;", ((struct BasisFunction *)
1138                                  List_Pointer(BF_L, CO->ReferenceIndex))->NameOfCoef);
1139 	else if (CO->QuantityType == GLOBALQUANTITY)
1140 	  Message::Check("%s;", ((struct GlobalQuantity *)
1141                                  List_Pointer(GQ_L, CO->ReferenceIndex))->Name);
1142 	else Message::Check("?;");
1143 
1144 	Message::Check(" // Entity %s;\n",
1145                        ((struct Group *)List_Pointer(Problem_S.Group, CO->EntityIndex))
1146                        ->Name );
1147 
1148 	switch(CO->ConstraintPerRegion->Type) {
1149 	case INIT :
1150 	  Message::Check("      // Type Init;");
1151 	case ASSIGN :
1152 	  Message::Check("      // Value Exp[%s];", Get_ExpressionName
1153                          (CO->ConstraintPerRegion->Case.Fixed.ExpressionIndex));
1154 	  break;
1155 	case ASSIGNFROMRESOLUTION :
1156 	case INITFROMRESOLUTION :
1157 	  Message::Check("      // Resolution %s;",
1158                          CO->ConstraintPerRegion->Case.Solve.ResolutionName);
1159 	  break;
1160 	}
1161 
1162 	if (CO->ConstraintPerRegion->TimeFunctionIndex >= 0)
1163 	  Message::Check(" TimeFunction Exp[%s];",
1164                          Get_ExpressionName(CO->ConstraintPerRegion->TimeFunctionIndex));
1165 
1166 	Message::Check("\n");
1167 	CO += 1;
1168       }
1169       Message::Check("    }\n");
1170     }
1171 
1172     Message::Check("  }\n");
1173   }
1174 
1175   Message::Check("\n");
1176   Message::Check("}\n");
1177 }
1178 
Print_Formulation()1179 void Print_Formulation()
1180 {
1181   struct Formulation *FO;
1182   struct DefineQuantity *DQ;
1183   struct EquationTerm *FE;
1184   struct GlobalEquationTerm *GET;
1185   List_T *DQ_L, *FE_L;
1186   int    i, Nbr, j, Nbrj, k, Nbrk;
1187 
1188   Nbr = List_Nbr(Problem_S.Formulation);
1189 
1190   Message::Check("Formulation {  /* nbr = %d */\n", Nbr);
1191   Message::Check("\n");
1192 
1193   for (i = 0; i < Nbr; i++) {
1194     Message::Check(" /* Num : %d */\n", i);
1195 
1196     FO = (struct Formulation*)List_Pointer(Problem_S.Formulation, i);
1197 
1198     Message::Check("  { Name %s; Type %s;\n", FO->Name,
1199                    Get_StringForDefine(Formulation_Type, FO->Type));
1200 
1201     DQ_L = FO->DefineQuantity;  FE_L = FO->Equation;
1202 
1203     Message::Check("    Quantity {\n");
1204     Nbrj = List_Nbr(DQ_L);
1205     for (j=0; j<Nbrj; j++) {
1206       DQ = (struct DefineQuantity*)List_Pointer(DQ_L, j);
1207 
1208       Message::Check("      { Name %s; Type %s; NameOfSpace %s",
1209                      DQ->Name,
1210                      Get_StringForDefine(DefineQuantity_Type, DQ->Type),
1211                      (DQ->FunctionSpaceIndex < 0) ? "?" :
1212                      ((struct FunctionSpace *)
1213                       List_Pointer(Problem_S.FunctionSpace, DQ->FunctionSpaceIndex))->Name);
1214       if (DQ->IndexInFunctionSpace) {
1215 	if (DQ->Type == GLOBALQUANTITY)
1216 	  Message::Check("[%s]",
1217                          ((struct GlobalQuantity *)
1218                           List_Pointer
1219                           (((struct FunctionSpace *)
1220                             List_Pointer(Problem_S.FunctionSpace, DQ->FunctionSpaceIndex))
1221                            ->GlobalQuantity,
1222                            *((int *)List_Pointer(DQ->IndexInFunctionSpace, 0))))->Name);
1223 	else if (DQ->Type == LOCALQUANTITY) {
1224 	  Message::Check("[");
1225 	  Nbrk = List_Nbr(DQ->IndexInFunctionSpace);
1226 	  for (k=0; k<Nbrk; k++)
1227 	    Message::Check(" %d", *((int *)List_Pointer(DQ->IndexInFunctionSpace, k)));
1228 	  Message::Check("]");
1229 	}
1230       }
1231       Message::Check(";");
1232 
1233       if (DQ->Type == INTEGRALQUANTITY) {
1234 	Message::Check("\n");
1235 	Message::Check("        Integration %s;\n",
1236                        ((struct IntegrationMethod *)
1237                         List_Pointer(Problem_S.IntegrationMethod,
1238                                      DQ->IntegralQuantity.IntegrationMethodIndex))->Name);
1239 	Message::Check("        Jacobian %s;",
1240                        ((struct JacobianMethod *)
1241                         List_Pointer(Problem_S.JacobianMethod,
1242                                      DQ->IntegralQuantity.JacobianMethodIndex))->Name);
1243       }
1244       Message::Check(" }\n");
1245     }
1246     Message::Check("    }\n");
1247 
1248     Message::Check("    Equation {\n");
1249 
1250     Nbrj = List_Nbr(FE_L);
1251     for (j=0; j<Nbrj; j++) {
1252       FE = (struct EquationTerm*)List_Pointer(FE_L, j);
1253       if      (FE->Type == GALERKIN || FE->Type == DERHAM) {
1254 	if(FE->Type == GALERKIN) Message::Check("      Galerkin { Density [ ... ];\n");
1255 	if(FE->Type == DERHAM)   Message::Check("      deRham   { Density [ ... ];\n");
1256 	Message::Check("                 In %s;\n",
1257                        ((struct Group *)
1258                         List_Pointer(Problem_S.Group, FE->Case.LocalTerm.InIndex))->Name );
1259 	Message::Check("                 Jacobian %s; \n",
1260                        ((struct JacobianMethod *)
1261                         List_Pointer(Problem_S.JacobianMethod,
1262                                      FE->Case.LocalTerm.JacobianMethodIndex))->Name );
1263 	Message::Check("                 Integration %s; }\n",
1264                        ((struct IntegrationMethod *)
1265                         List_Pointer(Problem_S.IntegrationMethod,
1266                                      FE->Case.LocalTerm.IntegrationMethodIndex))->Name );
1267 
1268 	Message::Check("      /* Inventaire des DQ (%d) [%d] :",
1269                        FE->Case.LocalTerm.Term.NbrQuantityIndex,
1270                        FE->Case.LocalTerm.Term.QuantityIndexPost);
1271 	for (k = 0; k < FE->Case.LocalTerm.Term.NbrQuantityIndex; k++)
1272 	  Message::Check(" {%s}",
1273                          ((struct DefineQuantity *)
1274                           List_Pointer
1275                           (DQ_L, FE->Case.LocalTerm.Term.QuantityIndexTable[k]))->Name);
1276 	Message::Check(" */\n");
1277 
1278 	Message::Check("      /* WholeQuantity (%d) :",
1279                        List_Nbr(FE->Case.LocalTerm.Term.WholeQuantity));
1280 	Print_WholeQuantity(FE->Case.LocalTerm.Term.WholeQuantity, DQ_L);
1281 	Message::Check(" */\n");
1282 
1283       }
1284       else if (FE->Type == GLOBALTERM     ) {
1285 	Message::Check("      GlobalTerm { [ ... ];\n");
1286 	Message::Check("                 In %s;\n",
1287                        ((struct Group *)
1288                         List_Pointer(Problem_S.Group, FE->Case.GlobalTerm.InIndex))->Name );
1289 
1290         if (FE->Case.GlobalTerm.SubType != EQ_ST_SELF)
1291           Message::Check("                 SubType %s;\n",
1292                          Get_StringForDefine(Equation_SubType, FE->Case.GlobalTerm.SubType));
1293 
1294 	Message::Check("      /* Inventaire des DQ (%d) [%d,%d] :",
1295                        FE->Case.GlobalTerm.Term.NbrQuantityIndex,
1296                        FE->Case.GlobalTerm.Term.DefineQuantityIndexDof,
1297                        FE->Case.GlobalTerm.Term.DefineQuantityIndexEqu);
1298 	for (k = 0; k < FE->Case.GlobalTerm.Term.NbrQuantityIndex; k++)
1299 	  Message::Check(" {%s}",
1300                          ((struct DefineQuantity *)
1301                           List_Pointer
1302                           (DQ_L, FE->Case.GlobalTerm.Term.QuantityIndexTable[k]))->Name);
1303 	Message::Check(" */\n");
1304 
1305 	Message::Check("      /* WholeQuantity (%d) :",
1306                        List_Nbr(FE->Case.GlobalTerm.Term.WholeQuantity));
1307 	Print_WholeQuantity(FE->Case.GlobalTerm.Term.WholeQuantity, DQ_L);
1308 	Message::Check(" */\n");
1309 
1310       }
1311       else if (FE->Type == GLOBALEQUATION) {
1312 	Message::Check("      GlobalEquation { Type %s; UsingConstraint %s;\n",
1313                        Get_StringForDefine(Constraint_Type, FE->Case.GlobalEquation.Type),
1314                        (FE->Case.GlobalEquation.ConstraintIndex >= 0)?
1315                        ((struct Constraint *)
1316                         List_Pointer(Problem_S.Constraint,
1317                                      FE->Case.GlobalEquation.ConstraintIndex))->Name
1318                        :
1319                        "undefined_constraint"
1320                        );
1321 	Nbrk = List_Nbr(FE->Case.GlobalEquation.GlobalEquationTerm);
1322 	for (k = 0; k < Nbrk; k++) {
1323 	  GET = (struct GlobalEquationTerm*)
1324 	    List_Pointer(FE->Case.GlobalEquation.GlobalEquationTerm, k);
1325 	  Message::Check("        { Node {%s}; Loop {%s}; Equation {%s};",
1326                          ((struct DefineQuantity *)
1327                           List_Pointer(DQ_L, GET->DefineQuantityIndexNode))->Name,
1328                          ((struct DefineQuantity *)
1329                           List_Pointer(DQ_L, GET->DefineQuantityIndexLoop))->Name,
1330                          ((struct DefineQuantity *)
1331                           List_Pointer(DQ_L, GET->DefineQuantityIndexEqu))->Name);
1332 	  Message::Check(" In %s; }\n",
1333                          ((struct Group *)
1334                           List_Pointer(Problem_S.Group, GET->InIndex))->Name);
1335 	}
1336       }
1337     }
1338     Message::Check("    }\n");
1339     Message::Check("  }\n");
1340   }
1341   Message::Check("\n");
1342   Message::Check("}\n");
1343 }
1344 
Print_Operation(struct Resolution * RE,List_T * Operation_L)1345 void Print_Operation(struct Resolution *RE, List_T *Operation_L)
1346 {
1347   struct Operation *OPE;
1348   int    i, j, Nbrj;
1349   static int NbrBlk = -1;
1350 
1351   NbrBlk++;
1352 
1353   Nbrj = List_Nbr(Operation_L);
1354 
1355 
1356   for (j=0; j<Nbrj; j++) {
1357     OPE = (struct Operation*)List_Pointer(Operation_L, j);
1358 
1359     switch (OPE->Type) {
1360 
1361     case OPERATION_GENERATE :
1362     case OPERATION_GENERATEONLY :
1363     case OPERATION_SOLVE :
1364     case OPERATION_GENERATEJAC :
1365     case OPERATION_SOLVEJAC :
1366     case OPERATION_SOLVENL :
1367     case OPERATION_GENERATESEPARATE :
1368     case OPERATION_INITSOLUTION :
1369     case OPERATION_SAVESOLUTION :
1370     case OPERATION_SAVESOLUTIONS :
1371     case OPERATION_READSOLUTION :
1372     case OPERATION_TRANSFERSOLUTION :
1373       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1374       Message::Check("      %s [%s];\n",
1375                      Get_StringForDefine(Operation_Type, OPE->Type),
1376                      ((struct DefineSystem *)
1377                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name);
1378       break;
1379 
1380     case OPERATION_UPDATE :
1381       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1382       Message::Check("      Update [ %s, Exp[%s] ];\n",
1383                      ((struct DefineSystem *)
1384                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1385                      Get_ExpressionName(OPE->Case.Update.ExpressionIndex));
1386       break;
1387 
1388     case OPERATION_SELECTCORRECTION :
1389       for (i=0 ; i<2*NbrBlk ; i++) Message::Check(" ");
1390       Message::Check("      SelectCorrection [ %s, %d ] ;\n",
1391                      ((struct DefineSystem *)
1392                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1393                      OPE->Case.SelectCorrection.Iteration) ;
1394       break ;
1395 
1396     case OPERATION_ADDCORRECTION :
1397       for (i=0 ; i<2*NbrBlk ; i++) Message::Check(" ");
1398       Message::Check("      AddCorrection [ %s, %g ] ;\n",
1399                      ((struct DefineSystem *)
1400                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1401                      OPE->Case.AddCorrection.Alpha) ;
1402       break ;
1403 
1404     case OPERATION_UPDATECONSTRAINT :
1405       for (i=0 ; i<2*NbrBlk ; i++) Message::Check(" ");
1406       Message::Check("      UpdateConstraint [ %s ] ;\n",
1407                      ((struct DefineSystem *)
1408                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name) ;
1409       break ;
1410 
1411     case OPERATION_FOURIERTRANSFORM :
1412       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1413       Message::Check("      FourierTransform [ %s, %s, {...} ];\n",
1414                      ((struct DefineSystem *)
1415                       List_Pointer(RE->DefineSystem,
1416                                    OPE->Case.FourierTransform.DefineSystemIndex[0]))->Name,
1417                      ((struct DefineSystem *)
1418                       List_Pointer(RE->DefineSystem,
1419                                    OPE->Case.FourierTransform.DefineSystemIndex[1]))->Name);
1420       break;
1421 
1422     case OPERATION_TIMELOOPTHETA :
1423       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1424       Message::Check("      TimeLoopTheta [ %.10g, %.10g, Exp[%s], Exp[%s] ] {\n",
1425                      OPE->Case.TimeLoopTheta.Time0, OPE->Case.TimeLoopTheta.TimeMax,
1426                      Get_ExpressionName(OPE->Case.TimeLoopTheta.DTimeIndex),
1427                      Get_ExpressionName(OPE->Case.TimeLoopTheta.ThetaIndex));
1428       Print_Operation(RE, OPE->Case.TimeLoopTheta.Operation);
1429       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1430       Message::Check("      }\n");
1431       break;
1432 
1433     case OPERATION_TIMELOOPNEWMARK :
1434       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1435       Message::Check("      TimeLoopNewmark [ %.10g, %.10g, Exp[%s], %.10g, %.10g ] {\n",
1436                      OPE->Case.TimeLoopNewmark.Time0, OPE->Case.TimeLoopNewmark.TimeMax,
1437                      Get_ExpressionName(OPE->Case.TimeLoopNewmark.DTimeIndex),
1438                      OPE->Case.TimeLoopNewmark.Beta, OPE->Case.TimeLoopNewmark.Gamma);
1439       Print_Operation(RE, OPE->Case.TimeLoopNewmark.Operation);
1440       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1441       Message::Check("      }\n");
1442       break;
1443 
1444     case OPERATION_ITERATIVELOOP :
1445       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1446       Message::Check("      IterativeLoop [ %d, %.10g, Exp[%s] ] {\n",
1447                      OPE->Case.IterativeLoop.NbrMaxIteration,
1448                      OPE->Case.IterativeLoop.Criterion,
1449                      Get_ExpressionName(OPE->Case.IterativeLoop.RelaxationFactorIndex));
1450       Print_Operation(RE, OPE->Case.IterativeLoop.Operation);
1451       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1452       Message::Check("      }\n");
1453       break;
1454 
1455     case OPERATION_LANCZOS :
1456       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1457       Message::Check("      Lanczos [ %s, %d, { ... } , %.10g ];\n",
1458                      ((struct DefineSystem *)
1459                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1460                      OPE->Case.Lanczos.Size,
1461                      OPE->Case.Lanczos.Shift);
1462       break;
1463 
1464     case OPERATION_EIGENSOLVE :
1465       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1466       Message::Check("      EigenSolve [ %s, %d, %.10g , %.10g ];\n",
1467                      ((struct DefineSystem *)
1468                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1469                      OPE->Case.EigenSolve.NumEigenvalues,
1470                      OPE->Case.EigenSolve.Shift_r, OPE->Case.EigenSolve.Shift_i);
1471       break;
1472 
1473     case OPERATION_POSTOPERATION :
1474       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1475       Message::Check("      PostOperation [ ... ];\n");
1476       break;
1477 
1478     case OPERATION_EVALUATE :
1479       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1480       Message::Check("      Evaluate [ ... ];\n");
1481       break;
1482 
1483     case OPERATION_SETTIME :
1484       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1485       Message::Check("      SetTime [ Exp[%s] ];\n",
1486                      Get_ExpressionName(OPE->Case.SetTime.ExpressionIndex));
1487       break;
1488 
1489     case OPERATION_SETFREQUENCY :
1490       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1491       Message::Check("      SetFrequency [ %s, Exp[%s] ];\n",
1492                      ((struct DefineSystem *)
1493                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1494                      Get_ExpressionName(OPE->Case.SetFrequency.ExpressionIndex));
1495       break;
1496 
1497     case OPERATION_BREAK :
1498       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1499       Message::Check("      Break;\n");
1500       break;
1501 
1502     case OPERATION_SYSTEMCOMMAND :
1503       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1504       Message::Check("      SystemCommand \" %s \";\n",
1505                      OPE->Case.SystemCommand.String);
1506       break;
1507 
1508     case OPERATION_TEST :
1509       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1510       Message::Check("      If [ Exp[%s] ] {\n",
1511                      Get_ExpressionName(OPE->Case.Test.ExpressionIndex));
1512       Print_Operation(RE, OPE->Case.Test.Operation_True);
1513       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1514       Message::Check("      }\n");
1515       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1516       if(OPE->Case.Test.Operation_False){
1517 	Message::Check("      Else {\n");
1518 	Print_Operation(RE, OPE->Case.Test.Operation_False);
1519 	Message::Check("      }\n");
1520       }
1521       break;
1522 
1523     case OPERATION_CHANGEOFCOORDINATES :
1524       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1525       Message::Check("      ChangeOfCoordinates [ %s, Exp[%s] ];\n",
1526                      ((struct Group *)
1527                       List_Pointer(Problem_S.Group,
1528                                    OPE->Case.ChangeOfCoordinates.GroupIndex))->Name,
1529                      Get_ExpressionName(OPE->Case.ChangeOfCoordinates.ExpressionIndex));
1530       break;
1531 
1532     case OPERATION_INIT_MOVINGBAND2D :
1533       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1534       Message::Check("      Init_MovingBand2D [ %s ];\n",
1535                      ((struct Group *)
1536                       List_Pointer(Problem_S.Group,
1537                                    OPE->Case.Init_MovingBand2D.GroupIndex))->Name);
1538       break;
1539 
1540     case OPERATION_MESH_MOVINGBAND2D :
1541       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1542       Message::Check("      Mesh_MovingBand2D [ %s ];\n",
1543                      ((struct Group *)
1544                       List_Pointer(Problem_S.Group,
1545                                    OPE->Case.Mesh_MovingBand2D.GroupIndex))->Name);
1546       break;
1547     case OPERATION_GENERATE_MH_MOVING :
1548       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1549       Message::Check("      GenerateMHMoving [ %s, %s, %g, %d ];\n",
1550                      ((struct DefineSystem *)
1551                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1552                      ((struct Group *)
1553                       List_Pointer(Problem_S.Group,
1554                                    OPE->Case.Generate_MH_Moving.GroupIndex))->Name,
1555                      OPE->Case.Generate_MH_Moving.Period,
1556                      OPE->Case.Generate_MH_Moving.NbrStep);
1557       break;
1558     case OPERATION_GENERATE_MH_MOVING_S :
1559       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1560       Message::Check("      GenerateMHMovingSeparate [ %s, %s, %g, %d ];\n",
1561                      ((struct DefineSystem *)
1562                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1563                      ((struct Group *)
1564                       List_Pointer(Problem_S.Group,
1565                                    OPE->Case.Generate_MH_Moving_S.GroupIndex))->Name,
1566                      OPE->Case.Generate_MH_Moving_S.Period,
1567                      OPE->Case.Generate_MH_Moving_S.NbrStep);
1568       break;
1569     case OPERATION_ADDMHMOVING :
1570       for (i=0; i<2*NbrBlk; i++) Message::Check(" ");
1571       Message::Check("      AddMHMoving [%s];\n",
1572                      ((struct DefineSystem *)
1573                       List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name);
1574       break;
1575 
1576     case OPERATION_DEFORMMESH :
1577       if(OPE->Case.DeformMesh.Quantity && OPE->Case.DeformMesh.Quantity2 &&
1578          OPE->Case.DeformMesh.Quantity3)
1579         Message::Check("      DeformMesh [%s, {%s, %s, %s}, '%s']; \n",
1580                        ((struct DefineSystem *)
1581                         List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1582                        OPE->Case.DeformMesh.Quantity, OPE->Case.DeformMesh.Quantity2,
1583                        OPE->Case.DeformMesh.Quantity3, OPE->Case.DeformMesh.Name_MshFile);
1584       else
1585         Message::Check("      DeformMesh [%s, %s, '%s']; \n",
1586                        ((struct DefineSystem *)
1587                         List_Pointer(RE->DefineSystem, OPE->DefineSystemIndex))->Name,
1588                        OPE->Case.DeformMesh.Quantity,
1589                        OPE->Case.DeformMesh.Name_MshFile);
1590       break;
1591 
1592     case OPERATION_GMSHREAD :
1593       Message::Check("      GmshRead [%s]; \n", OPE->Case.GmshRead.FileName);
1594       break;
1595 
1596     case OPERATION_GMSHMERGE :
1597       Message::Check("      GmshMerge [%s]; \n", OPE->Case.GmshRead.FileName);
1598       break;
1599 
1600     case OPERATION_GMSHOPEN :
1601       Message::Check("      GmshOpen [%s]; \n", OPE->Case.GmshRead.FileName);
1602       break;
1603 
1604     case OPERATION_GMSHWRITE :
1605       Message::Check("      GmshWrite [%s]; \n", OPE->Case.GmshRead.FileName);
1606       break;
1607 
1608     case OPERATION_GMSHCLEARALL :
1609       Message::Check("      GmshClearAll; \n");
1610       break;
1611 
1612     case OPERATION_DELETEFILE:
1613       Message::Check("      DeleteFile [%s]; \n", OPE->Case.DeleteFile.FileName);
1614       break;
1615 
1616     case OPERATION_RENAMEFILE:
1617       Message::Check("      RenameFile [%s, %s]; \n",
1618                      OPE->Case.RenameFile.OldFileName,
1619                      OPE->Case.RenameFile.NewFileName);
1620       break;
1621 
1622     case OPERATION_CREATEDIR:
1623       Message::Check("      CreateDir [%s]; \n",
1624                      OPE->Case.CreateDir.DirName);
1625       break;
1626 
1627     default :
1628       Message::Check("      ???;\n");
1629       break;
1630     }
1631   }
1632 
1633   NbrBlk--;
1634 }
1635 
Print_Resolution()1636 void Print_Resolution()
1637 {
1638   struct Resolution *RE;
1639   struct DefineSystem *DS;
1640   List_T *DS_L;
1641   int    i, Nbr, j, Nbrj, k;
1642 
1643   Nbr = List_Nbr(Problem_S.Resolution);
1644 
1645   Message::Check("Resolution {  /* nbr = %d */\n", Nbr);
1646   Message::Check("\n");
1647 
1648   for (i = 0; i < Nbr; i++) {
1649     Message::Check(" /* Num : %d */\n", i);
1650 
1651     RE = (struct Resolution*)List_Pointer(Problem_S.Resolution, i);
1652 
1653     Message::Check("  { Name %s\n", RE->Name);
1654 
1655     DS_L = RE->DefineSystem;
1656 
1657     Message::Check("    System {\n");
1658     Nbrj = List_Nbr(DS_L);
1659     for (j=0; j<Nbrj; j++) {
1660       DS = (struct DefineSystem*)List_Pointer(DS_L, j);
1661 
1662       Message::Check("      { Name %s; Type %s; ",
1663                      DS->Name,
1664                      Get_StringForDefine(DefineSystem_Type, DS->Type));
1665 
1666       Message::Check("NameOfFormulation {");
1667       for (k = 0; k < List_Nbr(DS->FormulationIndex); k++)
1668 	Message::Check(" %s",
1669                        ((struct Formulation *)
1670                         List_Pointer(Problem_S.Formulation,
1671                                      *((int *)List_Pointer(DS->FormulationIndex, k))))->Name);
1672       Message::Check(" }; ");
1673 
1674       if(DS->MeshName)
1675 	Message::Check("NameOfMesh %s; ", DS->MeshName);
1676 
1677       if(DS->OriginSystemIndex) {
1678 	Message::Check("OriginSystem {") ;
1679 
1680 	for (k = 0 ; k < List_Nbr(DS->OriginSystemIndex) ; k++) {
1681 	  if (k)  Message::Check(",") ;
1682 	  Message::Check(" %d", *((int *)List_Pointer(DS->OriginSystemIndex, k))) ;
1683 	}
1684 	Message::Check(" } ;") ;
1685       }
1686 
1687       if (DS->Type == VAL_COMPLEX) {
1688 	Message::Check("Frequency {");
1689 
1690 	for (k = 0; k < List_Nbr(DS->FrequencyValue); k++) {
1691 	  if (k)  Message::Check(",");
1692 	  Message::Check(" %.10g", *((double *)List_Pointer(DS->FrequencyValue, k)));
1693 	}
1694 	Message::Check(" };");
1695       }
1696 
1697       Message::Check(" }\n");
1698     }
1699     Message::Check("    }\n");
1700 
1701     Message::Check("    Operation {\n");
1702     Print_Operation(RE, RE->Operation);
1703     Message::Check("    }\n");
1704     Message::Check("  }\n");
1705   }
1706   Message::Check("\n");
1707   Message::Check("}\n");
1708 }
1709 
Print_PostProcessing()1710 void Print_PostProcessing()
1711 {
1712   struct PostProcessing   *PP;
1713   struct PostQuantity     *PQ;
1714   struct PostQuantityTerm *PQT;
1715   int   i, Nbr, j, Nbrj, k, Nbrk;
1716 
1717   Nbr = List_Nbr(Problem_S.PostProcessing);
1718 
1719   Message::Check("PostProcessing {  /* nbr = %d */\n", Nbr);
1720   Message::Check("\n");
1721 
1722   for (i = 0; i < Nbr; i++) {
1723     Message::Check(" /* Num : %d */\n", i);
1724 
1725     PP = (struct PostProcessing*)List_Pointer(Problem_S.PostProcessing, i);
1726 
1727     Message::Check("  { Name %s; NameOfFormulation %s; \n", PP->Name,
1728                    ((struct Formulation *)
1729                     List_Pointer(Problem_S.Formulation, PP->FormulationIndex))->Name);
1730 
1731     if(PP->NameOfSystem)
1732       Message::Check("NameOfSystem %s;", PP->NameOfSystem);
1733 
1734     Nbrj = List_Nbr(PP->PostQuantity);
1735     if (Nbrj > 0) {
1736       Message::Check("    Quantity {\n");
1737       for (j = 0; j < Nbrj; j++) {
1738 	PQ = (struct PostQuantity*)List_Pointer(PP->PostQuantity, j);
1739 	Message::Check("      { Name %s;\n", PQ->Name);
1740 	Message::Check("        Value {\n");
1741 	Nbrk = List_Nbr(PQ->PostQuantityTerm);
1742 	for (k = 0; k < Nbrk; k++) {
1743 	  PQT = (struct PostQuantityTerm*)List_Pointer(PQ->PostQuantityTerm, k);
1744 	  Message::Check("          { %s { ['",
1745                          Get_StringForDefine(PostQuantityTerm_EvaluationType,
1746                                              PQT->EvaluationType));
1747 	  Print_WholeQuantity
1748 	    (PQT->WholeQuantity,
1749 	     ((struct Formulation *)
1750 	      List_Pointer(Problem_S.Formulation, PP->FormulationIndex))
1751 	     ->DefineQuantity);
1752 	  Message::Check(" ']; /* DefineQuantityType %s */\n",
1753                          Get_StringForDefine(DefineQuantity_Type, PQT->Type));
1754 
1755 	  if(PQT->InIndex > 0)
1756 	    Message::Check("                    In %s;\n",
1757                            ((struct Group *)List_Pointer(Problem_S.Group, PQT->InIndex))->Name);
1758 	  if(PQT->IntegrationMethodIndex > 0)
1759 	    Message::Check("                    Integration %s;\n",
1760                            ((struct IntegrationMethod *)
1761                             List_Pointer(Problem_S.IntegrationMethod,
1762                                          PQT->IntegrationMethodIndex))->Name);
1763 	  if(PQT->JacobianMethodIndex > 0)
1764 	    Message::Check("                    Jacobian %s;\n",
1765                            ((struct JacobianMethod *)
1766                             List_Pointer(Problem_S.JacobianMethod,
1767                                          PQT->JacobianMethodIndex))->Name);
1768 
1769 	}
1770 	Message::Check("          } } }\n");  Message::Check("      }\n");
1771       }
1772       Message::Check("    }\n");
1773     }
1774     Message::Check("  }\n");
1775   }
1776   Message::Check("\n}");
1777   Message::Check("\n");
1778 }
1779 
Print_PostOperation()1780 void Print_PostOperation()
1781 {
1782   struct PostProcessing   *PP;
1783   struct PostOperation    *PO;
1784   struct PostSubOperation *PSO;
1785   int   i, Nbr, k, Nbrk;
1786 
1787   Nbr = List_Nbr(Problem_S.PostOperation);
1788 
1789   Message::Check("PostOperation {  /* nbr = %d */\n", Nbr);
1790   Message::Check("\n");
1791 
1792   for (i = 0; i < Nbr; i++) {
1793     PO = (struct PostOperation*)List_Pointer(Problem_S.PostOperation, i);
1794     PP = (struct PostProcessing*)List_Pointer(Problem_S.PostProcessing,
1795 					      PO->PostProcessingIndex);
1796 
1797     Message::Check("  { Name %s; NameOfPostProcessing %s;\n", PO->Name, PP->Name);
1798     Message::Check("    Operation {\n");
1799 
1800     Nbrk = List_Nbr(PO->PostSubOperation);
1801     for (k = 0; k < Nbrk; k++) {
1802       PSO = (struct PostSubOperation*)List_Pointer(PO->PostSubOperation, k);
1803       switch (PSO->Type) {
1804       case POP_PRINT :
1805 	Message::Check("      Print[%s",
1806                        ((struct PostQuantity *)
1807                         List_Pointer(PP->PostQuantity, PSO->PostQuantityIndex[0]))->Name);
1808         if(PSO->PostQuantitySupport[0] >= 0)
1809 	  Message::Check(" [%s]",
1810                          ((struct Group *)
1811                           List_Pointer(Problem_S.Group, PSO->PostQuantitySupport[0]))->Name);
1812 	if(PSO->PostQuantityIndex[1] >= 0) {
1813 	  Message::Check(" %s %s",
1814                          Get_StringForDefine(PostSubOperation_CombinationType,
1815                                              PSO->CombinationType),
1816                          ((struct PostQuantity *)
1817                           List_Pointer(PP->PostQuantity, PSO->PostQuantityIndex[1]))->Name);
1818 	  if(PSO->PostQuantitySupport[1] >= 0)
1819 	    Message::Check(" [%s]",
1820                            ((struct Group *)
1821                             List_Pointer(Problem_S.Group, PSO->PostQuantitySupport[1]))->Name);
1822 	}
1823         switch (PSO->SubType) {
1824 	case PRINT_ONREGION :
1825 	  if (PSO->Case.OnRegion.RegionIndex >=0)
1826 	    Message::Check(", OnRegion %s",
1827                            ((struct Group *)
1828                             List_Pointer(Problem_S.Group,
1829                                          PSO->Case.OnRegion.RegionIndex))->Name );
1830 	  else
1831 	    Message::Check(", OnGlobal");
1832 	  break;
1833 	case PRINT_ONELEMENTSOF :
1834 	  Message::Check(", OnElementsOf %s",
1835                          ((struct Group *)
1836                           List_Pointer(Problem_S.Group,
1837                                        PSO->Case.OnRegion.RegionIndex))->Name );
1838 	  break;
1839 	case PRINT_ONGRID :
1840 	  Message::Check(", OnGrid %s",
1841                          ((struct Group *)
1842                           List_Pointer(Problem_S.Group,
1843                                        PSO->Case.OnRegion.RegionIndex))->Name );
1844 	  break;
1845 	case PRINT_ONGRID_0D :
1846 	  Message::Check(", OnPoint {%.10g,%.10g,%.10g}",
1847                          PSO->Case.OnGrid.x[0], PSO->Case.OnGrid.y[0],
1848                          PSO->Case.OnGrid.z[0]);
1849 	  break;
1850 	case PRINT_ONGRID_1D :
1851 	  Message::Check(", OnLine {{%.10g,%.10g,%.10g}{%.10g,%.10g,%.10g}} {%d}",
1852                          PSO->Case.OnGrid.x[0], PSO->Case.OnGrid.y[0],
1853                          PSO->Case.OnGrid.z[0],
1854                          PSO->Case.OnGrid.x[1], PSO->Case.OnGrid.y[1],
1855                          PSO->Case.OnGrid.z[1], PSO->Case.OnGrid.n[0]);
1856 	  break;
1857 	case PRINT_ONGRID_2D :
1858 	  Message::Check(", OnPlane {{%.10g,%.10g,%.10g}{%.10g,%.10g,%.10g}"
1859                          "{%.10g,%.10g,%.10g}} {%d,%d}",
1860                          PSO->Case.OnGrid.x[0], PSO->Case.OnGrid.y[0],
1861                          PSO->Case.OnGrid.z[0],
1862                          PSO->Case.OnGrid.x[1], PSO->Case.OnGrid.y[1],
1863                          PSO->Case.OnGrid.z[1],
1864                          PSO->Case.OnGrid.x[2], PSO->Case.OnGrid.y[2],
1865                          PSO->Case.OnGrid.z[2],
1866                          PSO->Case.OnGrid.n[0], PSO->Case.OnGrid.n[1]);
1867 	  break;
1868 	default : /* parametric grid, ... */
1869 	  break;
1870 	}
1871 	break;
1872       default : /* POP_EXPRESSION, POP_GROUP, etc. */
1873 	break;
1874       }
1875 
1876       if(PSO->Depth != 1)
1877 	Message::Check(", Depth %d", PSO->Depth);
1878 
1879       if(PSO->Skin)
1880 	Message::Check(", Skin");
1881 
1882       if(PSO->NoNewLine)
1883 	Message::Check(", NoNewLine");
1884 
1885       if(PSO->Smoothing)
1886 	Message::Check(", Smoothing %d", PSO->Smoothing);
1887 
1888       if(PSO->Dimension != DIM_ALL)
1889 	Message::Check(", Dimension %d", PSO->Dimension);
1890 
1891       if(PSO->HarmonicToTime > 1)
1892 	Message::Check(", HarmonicToTime %d", PSO->HarmonicToTime);
1893 
1894       if(PSO->TimeToHarmonic)
1895 	Message::Check(", TimeToHarmonic %d", PSO->TimeToHarmonic);
1896 
1897       if(PSO->FourierTransform == 1)
1898 	Message::Check(", FourierTransform");
1899       if(PSO->FourierTransform == 2)
1900 	Message::Check(", CosineTransform");
1901 
1902       if(PSO->TimeInterval_Flag)
1903 	Message::Check(", TimeInterval {%g, %g}",
1904                        PSO->TimeInterval[0], PSO->TimeInterval[1]);
1905 
1906       if(PSO->Sort)
1907 	Message::Check(", Sort %s",
1908                        Get_StringForDefine(PostSubOperation_SortType, PSO->Adapt));
1909 
1910       if(PSO->Adapt)
1911 	Message::Check(", Adapt %s",
1912                        Get_StringForDefine(PostSubOperation_AdaptationType, PSO->Adapt));
1913 
1914       if(PSO->Target >= 0)
1915 	Message::Check(", Target %g", PSO->Target);
1916 
1917       if(PSO->Iso){
1918 	if(PSO->Iso < 0){
1919 	  Message::Check(", Iso {");
1920 	  for(i=0; i<List_Nbr(PSO->Iso_L); i++){
1921 	    if(i!=List_Nbr(PSO->Iso_L)-1)
1922 	      Message::Check("%g,", *(double*)List_Pointer(PSO->Iso_L,i));
1923 	    else
1924 	      Message::Check("%g}", *(double*)List_Pointer(PSO->Iso_L,i));
1925 	  }
1926 	}
1927 	else{
1928 	  Message::Check(", Iso %d", PSO->Iso);
1929 	}
1930       }
1931 
1932       /* todo: time steps, frequencies, values, changeofcoord, ... */
1933 
1934       Message::Check(", Format %s",
1935                      Get_StringForDefine(PostSubOperation_Format, PSO->Format));
1936 
1937       if(PSO->FileOut){
1938 	Message::Check(", File %s\"%s\"",
1939                        (PSO->CatFile==2)?">> ":(PSO->CatFile==1)?"> ":"", PSO->FileOut);
1940       }
1941 
1942       Message::Check("];\n");
1943     }
1944     Message::Check("    }\n ");
1945     Message::Check(" }\n");
1946   }
1947   Message::Check("\n");
1948   Message::Check("}\n");
1949 }
1950 
Print_Object(int ichoice)1951 int Print_Object(int ichoice)
1952 {
1953   switch (ichoice) {
1954   case  0 : Print_Constants     ();  break;
1955   case  1 : Print_Group         ();  break;
1956   case  2 : Print_Expression    ();  break;
1957   case  3 : Print_Constraint    ();  break;
1958   case  4 : Print_Jacobian      ();  break;
1959   case  5 : Print_Integration   ();  break;
1960   case  6 : Print_FunctionSpace ();  break;
1961   case  7 : Print_Formulation   ();  break;
1962   case  8 : Print_Resolution    ();  break;
1963   case  9 : Print_PostProcessing();  break;
1964   case 10 : Print_PostOperation ();  break;
1965   default : return 1;
1966   }
1967   return 0;
1968 }
1969 
Print_ProblemStructure()1970 void  Print_ProblemStructure()
1971 {
1972   char buff[128];
1973   int  ichoice;
1974 
1975   while (1) {
1976     Message::Info("Checking");
1977     Message::Direct("(1) Constants        (2) Groups          (3) Functions");
1978     Message::Direct("(4) Constraints      (5) Jacobians       (6) Integrations");
1979     Message::Direct("(7) FunctionSpaces   (8) Formulations    (9) Resolutions");
1980     Message::Direct("(10) PostProcessings (11) PostOperations (other) Quit");
1981     Message::Check("Choice: ");
1982     if(!fgets(buff, 128, stdin))
1983       break;
1984     ichoice = atoi(buff);
1985     if(Print_Object(ichoice ? ichoice - 1 : -1)){
1986       Message::Check("E n d C h e c k i n g\n");
1987       return;
1988     }
1989   }
1990 }
1991 
Print_ListResolution(int choose,int Flag_LRES,char ** name)1992 void Print_ListResolution(int choose, int Flag_LRES, char **name)
1993 {
1994   struct Resolution *RE;
1995   int    ichoice = 0;
1996   char   buff[128];
1997   bool   print = (!choose || (!Message::UseSocket() && !Message::UseOnelab()));
1998 
1999   std::vector<std::string> choices;
2000   for (int i = 0; i < List_Nbr(Problem_S.Resolution); i++) {
2001     RE = (struct Resolution*)List_Pointer(Problem_S.Resolution, i);
2002     if(!RE->Hidden) choices.push_back(RE->Name);
2003   }
2004 
2005   if(choices.size()){
2006     if(Flag_LRES < 0){
2007       ichoice = - Flag_LRES;
2008     }
2009     else{
2010       if(print) Message::Info("Available Resolutions");
2011       for (unsigned i = 0; i < choices.size(); i++) {
2012         if(print) Message::Direct("(%d) %s", i + 1, choices[i].c_str());
2013         if(Message::UseSocket()) Message::SendOptionOnSocket(1, choices[i].c_str());
2014       }
2015       if(Message::UseOnelab() && choices.size()){
2016         Constant c;
2017         c.Name = (char*)"ResolutionChoices";
2018         c.Type = VAR_CHAR;
2019         c.Value.Char = strSave(choices[0].c_str());
2020         std::map<std::string, std::vector<double> > floatOptions;
2021         // force *not* read-only here, in case the parameter already exists *as
2022         // read-only* in the DB, in which case we do want to keep the value
2023         // from the server
2024         floatOptions["ReadOnly"].push_back(0);
2025         std::map<std::string, std::vector<std::string> > charOptions;
2026         charOptions["Choices"] = choices;
2027         charOptions["Name"].push_back(Message::GetOnelabClientName() + "/1ResolutionChoices");
2028         charOptions["Label"].push_back("Resolution");
2029         Message::ExchangeOnelabParameter(&c, floatOptions, charOptions);
2030         if(choose){
2031           *name = c.Value.Char;
2032           return;
2033         }
2034       }
2035       if(choose){
2036 	Message::Check("Choice: ");
2037 	if(fgets(buff, 128, stdin))
2038           ichoice = atoi(buff);
2039       }
2040     }
2041     if(ichoice > 0 && ichoice < (int)choices.size() + 1){
2042       *name = strSave(choices[ichoice - 1].c_str());
2043       return;
2044     }
2045     else if(choose)
2046       Message::Error("Unknown Resolution");
2047   }
2048   else
2049     Message::Info("No Resolution available");
2050 }
2051 
removeWhiteSpace(const std::string & s)2052 static std::string removeWhiteSpace(const std::string &s)
2053 {
2054   std::string::size_type beg = s.find_first_not_of(' ');
2055   std::string::size_type end = s.find_last_not_of(' ');
2056   if(beg == std::string::npos || end == std::string::npos) return "";
2057   return s.substr(beg, end + 1 - beg);
2058 }
2059 
Print_ListPostOperation(int choose,int Flag_LPOS,char * name[NBR_MAX_POS])2060 void Print_ListPostOperation(int choose, int Flag_LPOS, char *name[NBR_MAX_POS])
2061 {
2062   struct PostOperation *PO;
2063   int    ichoice = 0;
2064   char   buff[128];
2065   bool   print = (!choose || (!Message::UseSocket() && !Message::UseOnelab()));
2066 
2067   std::vector<std::string> choices;
2068   for (int i = 0; i < List_Nbr(Problem_S.PostOperation); i++) {
2069     PO = (struct PostOperation*)List_Pointer(Problem_S.PostOperation, i);
2070     if(!PO->Hidden) choices.push_back(PO->Name);
2071   }
2072 
2073   if(choices.size()){
2074     if(Flag_LPOS < 0){
2075       ichoice = - Flag_LPOS;
2076     }
2077     else{
2078       if(print) Message::Info("Available PostOperations");
2079       for (unsigned i = 0; i < choices.size(); i++) {
2080 	if(print) Message::Direct("(%d) %s", i + 1, choices[i].c_str());
2081 	if(Message::UseSocket()) Message::SendOptionOnSocket(2, choices[i].c_str());
2082       }
2083 
2084       if(Message::UseOnelab() && choices.size()){
2085         Constant c;
2086         c.Name = (char*)"PostOperationChoices";
2087         c.Type = VAR_CHAR;
2088         c.Value.Char = strSave(choices[0].c_str());
2089         std::map<std::string, std::vector<double> > floatOptions;
2090         // force *not* read-only here, in case the parameter already exists *as
2091         // read-only* in the DB, in which case we do want to keep the value
2092         // from the server
2093         floatOptions["ReadOnly"].push_back(0);
2094         std::map<std::string, std::vector<std::string> > charOptions;
2095         charOptions["Choices"] = choices;
2096         charOptions["Name"].push_back(Message::GetOnelabClientName() + "/2PostOperationChoices");
2097         charOptions["Label"].push_back("Post-processing");
2098         charOptions["MultipleSelection"].push_back("0");
2099         Message::ExchangeOnelabParameter(&c, floatOptions, charOptions);
2100         if(choose){
2101           std::string str(c.Value.Char);
2102           int i = 0;
2103           std::string::size_type first = 0;
2104           while(1){
2105             std::string::size_type last = str.find_first_of(",", first);
2106             std::string next = str.substr(first, last - first);
2107             name[i++] = strSave(removeWhiteSpace(next).c_str());
2108             if(last == std::string::npos) break;
2109             first = last + 1;
2110             if(i == NBR_MAX_POS - 1) break;
2111           }
2112           name[i] = NULL;
2113           return;
2114         }
2115       }
2116 
2117       if(choose){
2118 	Message::Check("Choice: ");
2119 	if(fgets(buff, 128, stdin))
2120           ichoice = atoi(buff);
2121       }
2122     }
2123     if(ichoice > 0 && ichoice < (int)choices.size() + 1){
2124       name[0] = strSave(choices[ichoice - 1].c_str());
2125       name[1] = NULL;
2126       return;
2127     }
2128     else if(choose)
2129       Message::Error("Unknown PostOperation");
2130   }
2131   else
2132     Message::Info("No PostOperation available");
2133 }
2134