1 /// \file
2 // -*- Mode : c++ -*-
3 //
4 // SUMMARY  :
5 // USAGE    :
6 // ORG      :
7 // AUTHOR   : Frederic Hecht
8 // E-MAIL   : hecht@ann.jussieu.fr
9 //
10 
11 /*
12 
13  This file is part of Freefem++
14 
15  Freefem++ is free software; you can redistribute it and/or modify
16  it under the terms of the GNU Lesser General Public License as published by
17  the Free Software Foundation; either version 2.1 of the License, or
18  (at your option) any later version.
19 
20  Freefem++  is distributed in the hope that it will be useful,
21  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  GNU Lesser General Public License for more details.
24 
25  You should have received a copy of the GNU Lesser General Public License
26  along with Freefem++; if not, write to the Free Software
27  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
29 #ifdef __MWERKS__
30 #pragma optimization_level 0
31 #endif
32 
33 #include <cmath>
34 #include <iostream>
35 #include <cfloat>
36 
37 #include "error.hpp"
38 #include "AFunction.hpp"
39 #include "rgraph.hpp"
40 #include <cstdio>
41 #include "fem.hpp"
42 #include "Mesh3dn.hpp"
43 
44 #include "HashMatrix.hpp"
45 
46 #include "SparseLinearSolver.hpp"
47 
48 #include "MeshPoint.hpp"
49 #include <complex>
50 #include "Operator.hpp"
51 
52 #include <set>
53 #include <map>
54 #include <vector>
55 
56 #include "lex.hpp"
57 #include "lgfem.hpp"
58 #include "lgmesh3.hpp"
59 #include "lgsolver.hpp"
60 #include "problem.hpp"
61 #include "CGNL.hpp"
62 #include "AddNewFE.h"
63 #include "array_resize.hpp"
64 #include "PlotStream.hpp"
65 
66 using namespace std;
67 
68 // add for the gestion of the endianness of the file.
69 // PlotStream::fBytes PlotStream::zott; //0123;
70 // PlotStream::hBytes PlotStream::zottffss; //012345678;
71 // ---- FH
72 namespace bamg {
73   class Triangles;
74 }
75 
76 namespace Fem2D {
77   void DrawIsoT(const R2 Pt[3], const R ff[3], const RN_ &Viso);
78   extern GTypeOfFE< Mesh3 > &P1bLagrange3d;
79   extern GTypeOfFE< Mesh3 > &RT03d;
80   extern GTypeOfFE< Mesh3 > &Edge03d;
81   extern GTypeOfFE< MeshS > &P1bLagrange_surf;
82   void Expandsetoflab(Stack stack, const CDomainOfIntegration &di, set< int > &setoflab, bool &all);
83 }    // namespace Fem2D
84 
85 #include "BamgFreeFem.hpp"
86 
87 static bool TheWait = false;
88 bool NoWait = false;
89 extern bool NoGraphicWindow;
90 
91 extern long verbosity;
92 extern FILE *ThePlotStream;    //  Add for new plot. FH oct 2008
93 void init_lgmesh( );
94 
95 namespace FreeFempp {
96   template< class R >
97   TypeVarForm< R > *TypeVarForm< R >::Global;
98 }
99 
100 basicAC_F0::name_and_type OpCall_FormBilinear_np::name_param[] = {
101   {"bmat", &typeid(Matrice_Creuse< R > *)}, LIST_NAME_PARM_MAT};
102 
103 basicAC_F0::name_and_type OpCall_FormLinear_np::name_param[] = {"tgv", &typeid(double)};
104 
Array(const C_F0 & a)105 const E_Array *Array(const C_F0 &a) {
106   if (a.left( ) == atype< E_Array >( ))
107     return dynamic_cast< const E_Array * >(a.LeftValue( ));
108   else
109     return 0;
110 }
111 
Box2(const C_F0 & bb,Expression * box)112 bool Box2(const C_F0 &bb, Expression *box) {
113   const E_Array *a = Array(bb);
114   if (a && a->size( ) == 2) {
115     box[0] = to< double >((*a)[0]);
116     box[1] = to< double >((*a)[1]);
117     return true;
118   } else
119     return false;
120 }
Box2x2(Expression bb,Expression * box)121 bool Box2x2(Expression bb, Expression *box) {
122   const E_Array *a = dynamic_cast< const E_Array * >(bb);
123   if (a && a->size( ) == 2)
124     return Box2((*a)[0], box) && Box2((*a)[1], box + 2);
125   else
126     return false;
127 }
128 
dump_table()129 void dump_table( ) {
130   cout << " dump the language's table " << endl;
131   cout << " ------------------------------ \n" << endl;
132   map< const string, basicForEachType * >::const_iterator i;
133   ;
134 
135   for (i = map_type.begin( ); i != map_type.end( ); i++) {
136     cout << " type : " << i->first << endl;
137     if (i->second)
138       i->second->ShowTable(cout);
139     else
140       cout << " Null \n";
141 
142     cout << "\n\n";
143   }
144 
145   for (i = map_type.begin( ); i != map_type.end( ); i++) {
146     cout << " type : " << i->first << endl;
147     if (i->second)
148       i->second->ShowTable(cout);
149     else
150       cout << " Null \n";
151 
152     cout << "\n\n";
153   }
154   cout << "--------------------- " << endl;
155   cout << *TheOperators << endl;
156   cout << "--------------------- " << endl;
157 }
158 
159 // bool In(long *viso, int n, long v)
160 // {
161 //   int i = 0;
162 //   int j = n;
163 //   int k;
164 
165 //   if (v < viso[0] || v > viso[j - 1])
166 //     return false;
167 //   while (i < j - 1) {
168 //     if (viso[k = (i + j) / 2] > v)
169 //       j = k;
170 //     else
171 //       i = k;
172 //   }
173 //   return (viso[i] = v);
174 // }
175 
176 class LinkToInterpreter {
177  public:
178   Type_Expr P;
179   Type_Expr N;
180   Type_Expr Nt;
181   Type_Expr x;
182   Type_Expr y;
183   Type_Expr z;
184   Type_Expr label;
185   Type_Expr region;
186   Type_Expr nu_triangle;
187   Type_Expr nu_face;
188   Type_Expr nu_edge;
189   Type_Expr lenEdge;
190   Type_Expr hTriangle;
191   Type_Expr area;
192   Type_Expr inside;
193   Type_Expr volume;
194   LinkToInterpreter( );
195 };
196 
197 LinkToInterpreter *l2interpreter;
198 
199 using namespace Fem2D;
200 using namespace EF23;
201 
202 template< class Result, class A >
203 class E_F_A_Ptr_o_R : public E_F0 {
204  public:
205   typedef Result A::*ptr;
206   Expression a0;
207   ptr p;
E_F_A_Ptr_o_R(Expression aa0,ptr pp)208   E_F_A_Ptr_o_R(Expression aa0, ptr pp) : a0(aa0), p(pp) {}
operator ( )(Stack s) const209   AnyType operator( )(Stack s) const { return SetAny< Result * >(&(GetAny< A * >((*a0)(s))->*p)); }
MeshIndependent() const210   bool MeshIndependent( ) const { return a0->MeshIndependent( ); }
211 };
212 
213 //  ----
214 //  remarque pas de template, cela ne marche pas encore ......
215 class E_P_Stack_P : public E_F0mps {
216  public:
operator ( )(Stack s) const217   AnyType operator( )(Stack s) const {
218     throwassert(*((long *)s));
219     return SetAny< R3 * >(&MeshPointStack(s)->P);
220   }
operator aType() const221   operator aType( ) const { return atype< R3 * >( ); }
222 };
223 class E_P_Stack_Px : public E_F0mps {
224  public:
operator ( )(Stack s) const225   AnyType operator( )(Stack s) const {
226     throwassert(*((long *)s));
227     return SetAny< R * >(&MeshPointStack(s)->P.x);
228   }
229 
operator aType() const230   operator aType( ) const { return atype< R * >( ); }
231 };
232 class E_P_Stack_Py : public E_F0mps {
233  public:
operator ( )(Stack s) const234   AnyType operator( )(Stack s) const {
235     throwassert(*((long *)s));
236     return SetAny< R * >(&MeshPointStack(s)->P.y);
237   }
238 
operator aType() const239   operator aType( ) const { return atype< R * >( ); }
240 };
241 class E_P_Stack_Pz : public E_F0mps {
242  public:
operator ( )(Stack s) const243   AnyType operator( )(Stack s) const {
244     throwassert(*((long *)s));
245     return SetAny< R * >(&MeshPointStack(s)->P.z);
246   }
247 
operator aType() const248   operator aType( ) const { return atype< R * >( ); }
249 };
250 
251 class E_P_Stack_N : public E_F0mps {
252  public:
operator ( )(Stack s) const253   AnyType operator( )(Stack s) const {
254     throwassert(*((long *)s));
255     return SetAny< R3 * >(&MeshPointStack(s)->N);
256   }
257 
operator aType() const258   operator aType( ) const { return atype< R3 * >( ); }
259 };
260 class E_P_Stack_Nx : public E_F0mps {
261  public:
operator ( )(Stack s) const262   AnyType operator( )(Stack s) const {
263     throwassert(*((long *)s));
264     return SetAny< R * >(&MeshPointStack(s)->N.x);
265   }
266 
operator aType() const267   operator aType( ) const { return atype< R * >( ); }
268 };
269 class E_P_Stack_Ny : public E_F0mps {
270  public:
operator ( )(Stack s) const271   AnyType operator( )(Stack s) const {
272     throwassert(*((long *)s));
273     return SetAny< R * >(&MeshPointStack(s)->N.y);
274   }
275 
operator aType() const276   operator aType( ) const { return atype< R * >( ); }
277 };
278 class E_P_Stack_Nz : public E_F0mps {
279  public:
operator ( )(Stack s) const280   AnyType operator( )(Stack s) const {
281     throwassert(*((long *)s));
282     return SetAny< R * >(&MeshPointStack(s)->N.z);
283   }
operator aType() const284     operator aType( ) const { return atype< R * >( ); }
285 };
286 
287 class E_P_Stack_Nt : public E_F0mps {
288  public:
operator ( )(Stack s) const289     AnyType operator( )(Stack s) const {
290         throwassert(*((long *)s));
291         return SetAny< R3 * >(&MeshPointStack(s)->Nt);
292     }
293 
operator aType() const294     operator aType( ) const { return atype< R3 * >( ); }
295 };
296 class E_P_Stack_Ntx : public E_F0mps {
297  public:
operator ( )(Stack s) const298     AnyType operator( )(Stack s) const {
299         throwassert(*((long *)s));
300         return SetAny< R * >(&MeshPointStack(s)->Nt.x);
301     }
302 
operator aType() const303     operator aType( ) const { return atype< R * >( ); }
304 };
305 class E_P_Stack_Nty : public E_F0mps {
306  public:
operator ( )(Stack s) const307     AnyType operator( )(Stack s) const {
308         throwassert(*((long *)s));
309         return SetAny< R * >(&MeshPointStack(s)->Nt.y);
310     }
311 
operator aType() const312     operator aType( ) const { return atype< R * >( ); }
313 };
314 class E_P_Stack_Ntz : public E_F0mps {
315  public:
operator ( )(Stack s) const316     AnyType operator( )(Stack s) const {
317         throwassert(*((long *)s));
318         return SetAny< R * >(&MeshPointStack(s)->Nt.z);
319     }
operator aType() const320     operator aType( ) const { return atype< R * >( ); }
321 };
322 
323 class E_P_Stack_Region : public E_F0mps {
324  public:
operator ( )(Stack s) const325   AnyType operator( )(Stack s) const {
326     throwassert(*((long *)s));
327     return SetAny< long * >(&MeshPointStack(s)->region);
328   }
329 
operator aType() const330   operator aType( ) const { return atype< long * >( ); }
331 };
332 class E_P_Stack_Label : public E_F0mps {
333  public:
operator ( )(Stack s) const334   AnyType operator( )(Stack s) const {
335     throwassert(*((long *)s));
336     return SetAny< long * >(&MeshPointStack(s)->label);
337   }
338 
operator aType() const339   operator aType( ) const { return atype< long * >( ); }
340 };
341 class E_P_Stack_Mesh : public E_F0mps {
342  public:
operator ( )(Stack s) const343   AnyType operator( )(Stack s) const {
344     throwassert(*((long *)s));
345     return SetAny< pmesh >(const_cast< pmesh >(MeshPointStack(s)->Th));
346   }
347 
operator aType() const348   operator aType( ) const { return atype< pmesh >( ); }
349 };
350 class E_P_Stack_Nu_Triangle : public E_F0mps {
351  public:
operator ( )(Stack s) const352   AnyType operator( )(Stack s) const {
353     throwassert(*((long *)s));
354     return SetAny< long >(MeshPointStack(s)->t);
355   }
356 
operator aType() const357   operator aType( ) const { return atype< long >( ); }
358 };
359 class E_P_Stack_Nu_Vertex : public E_F0mps {
360  public:
operator ( )(Stack s) const361   AnyType operator( )(Stack s) const {
362     throwassert(*((long *)s));
363     return SetAny< long >(MeshPointStack(s)->v);
364   }
365 
operator aType() const366   operator aType( ) const { return atype< long >( ); }
367 };
368 class E_P_Stack_Nu_Face : public E_F0mps {
369  public:
operator ( )(Stack s) const370   AnyType operator( )(Stack s) const {
371     throwassert(*((long *)s));
372     return SetAny< long >(MeshPointStack(s)->f);
373   }
374 
operator aType() const375   operator aType( ) const { return atype< long >( ); }
376 };
377 class E_P_Stack_Nu_Edge : public E_F0mps {
378  public:
operator ( )(Stack s) const379   AnyType operator( )(Stack s) const {
380     throwassert(*((long *)s));
381     return SetAny< long >(MeshPointStack(s)->e);
382   }
383 
operator aType() const384   operator aType( ) const { return atype< long >( ); }
385 };
386 class E_P_Stack_inside : public E_F0mps {
387  public:
operator ( )(Stack s) const388   AnyType operator( )(Stack s) const {
389     throwassert(*((long *)s));
390     return SetAny< double >(MeshPointStack(s)->outside ? 0.0 : 1.0);
391   }
392 
operator aType() const393   operator aType( ) const { return atype< double >( ); }
394 };
395 
396 class E_P_Stack_lenEdge : public E_F0mps {
397  public:
operator ( )(Stack s) const398   AnyType operator( )(Stack s) const {
399     throwassert(*((long *)s));
400     MeshPoint *mp = MeshPointStack(s);
401     ffassert(mp->T && mp->e >= 0 && mp->d == 2);
402     double l = mp->T->lenEdge(mp->e);
403     return SetAny< double >(l);
404   }
405 
operator aType() const406   operator aType( ) const { return atype< double >( ); }
407 };
408 
409 class E_P_Stack_hTriangle : public E_F0mps {
410  public:
operator ( )(Stack s) const411   AnyType operator( )(Stack s) const {
412     throwassert(*((long *)s));
413     MeshPoint *mp = MeshPointStack(s);
414     assert(mp->T);
415     double l = 1e100;
416     if (mp->d == 2)
417       l = mp->T->h( );
418     else if (mp->d == 3 && mp->dHat == 3)
419       l = mp->T3->lenEdgesmax( );
420     else if (mp->d == 3 && mp->dHat == 2)
421       l = mp->TS->lenEdgesmax( );
422     return SetAny< double >(l);
423   }
424 
operator aType() const425   operator aType( ) const { return atype< double >( ); }
426 };
427 
428 class E_P_Stack_nTonEdge : public E_F0mps {
429  public:
operator ( )(Stack s) const430   AnyType operator( )(Stack s) const {
431     throwassert(*((long *)s));
432     MeshPoint *mp = MeshPointStack(s);
433     assert(mp->T && mp->e > -1 && mp->d == 2);
434     long l = mp->Th->nTonEdge(mp->t, mp->e);
435     return SetAny< long >(l);
436   }
437 
operator aType() const438   operator aType( ) const { return atype< long >( ); }
439 };
440 
441 class E_P_Stack_nElementonB : public E_F0mps {
442  public:
operator ( )(Stack s) const443   AnyType operator( )(Stack s) const {
444     throwassert(*((long *)s));
445     MeshPoint *mp = MeshPointStack(s);
446     long l = 0;
447     if ((mp->T) && (mp->e > -1) && (mp->d == 2))
448       l = mp->Th->nTonEdge(mp->t, mp->e);
449     else if (mp->d == 3 && mp->dHat == 3 && mp->T3 && (mp->f >= 0))
450       l = mp->Th3->nElementonB(mp->t, mp->f);
451     else if (mp->d == 3 && mp->dHat == 2 && mp->TS && (mp->e >= 0))
452       l = mp->ThS->nElementonB(mp->t, mp->e);
453     return SetAny< long >(l);
454   }
455 
operator aType() const456   operator aType( ) const { return atype< long >( ); }
457 };
458 
459 template< int NBT >
460 class E_P_Stack_TypeEdge : public E_F0mps {
461  public:
operator ( )(Stack s) const462   AnyType operator( )(Stack s) const {
463     throwassert(*((long *)s));
464     MeshPoint *mp = MeshPointStack(s);
465     assert(mp->T && mp->e > -1 && mp->d == 2);
466     long l = mp->Th->nTonEdge(mp->t, mp->e) == NBT;
467     return SetAny< long >(l);
468   }
469 
operator aType() const470   operator aType( ) const { return atype< long >( ); }
471 };
472 
473 class E_P_Stack_areaTriangle : public E_F0mps {
474  public:
operator ( )(Stack s) const475   AnyType operator( )(Stack s) const {
476     throwassert(*((long *)s));
477     MeshPoint *mp = MeshPointStack(s);
478     assert(mp->T);
479     double l = -1;    // unset ...
480     if (mp->d == 2)
481       l = mp->T->area;
482     else if (mp->d == 3 && mp->dHat == 3 && mp->f >= 0) {
483       R3 NN = mp->T3->N(mp->f);
484       l = NN.norme( ) / 2.f;
485     } else if (mp->d == 3 && mp->dHat == 2)
486       l = mp->TS->mesure( );
487     else {
488       cout << "erreur : E_P_Stack_areaTriangle " << mp->d << " " << mp->f << endl;
489       ffassert(0);    // undef
490     }
491     return SetAny< double >(l);
492   }
493 
operator aType() const494   operator aType( ) const { return atype< double >( ); }
495 };
496 
497 class E_P_Stack_EdgeOrient : public E_F0mps {
498  public:
operator ( )(Stack s) const499   AnyType operator( )(Stack s) const {
500     throwassert(*((long *)s));
501     MeshPoint &mp = *MeshPointStack(s);    // the struct to get x,y, normal , value
502     double r = 1;
503     if (mp.d == 2) {
504       if (mp.T && mp.e >= 0) r = mp.T->EdgeOrientation(mp.e);
505     } else if (mp.d == 3 && mp.dHat == 3) {
506       if (mp.T3 && mp.f >= 0) r = mp.T3->faceOrient(mp.f);
507     } else if (mp.d == 3 && mp.dHat == 2) {
508       if (mp.TS && mp.e >= 0) r = mp.T3->EdgeOrientation(mp.e);
509     }
510     return r;
511   }
512 
operator aType() const513   operator aType( ) const { return atype< double >( ); }
514 };
515 
516 class E_P_Stack_VolumeTet : public E_F0mps {
517  public:
operator ( )(Stack s) const518   AnyType operator( )(Stack s) const {
519     throwassert(*((long *)s));
520     MeshPoint *mp = MeshPointStack(s);
521     assert(mp->T);
522     double l = -1;    // unset ...
523     if (mp->d == 3 && mp->dHat == 3 && mp->T3)
524       l = mp->T3->mesure( );
525     else {
526       cout << "erreur : E_P_Stack_VolumeTet " << mp->d << " " << mp->f << endl;
527       ffassert(0);    // undef
528     }
529     return SetAny< double >(l);
530   }
531 
operator aType() const532   operator aType( ) const { return atype< double >( ); }
533 };
534 
535 template< class R >
536 class E_StopGC : public StopGC< R > {
537  public:
538   typedef KN< R > Kn;
539   typedef KN_< R > Kn_;
540 
541   Stack s;
542   long n;
543   long iter;
544   KN_< R > xx, gg;
545   C_F0 citer, cxx, cgg;
546   C_F0 stop;
547 
E_StopGC(Stack ss,long nn,const Polymorphic * op)548   E_StopGC(Stack ss, long nn, const Polymorphic *op)
549     : s(ss), n(nn), iter(-1), xx(0, 0), gg(0, 0), citer(CConstant< long * >(&iter)),
550       cxx(dCPValue(&xx)), cgg(dCPValue(&gg)), stop(op, "(", citer, cxx, cgg) {}
551 
~E_StopGC()552   ~E_StopGC( ) {
553     delete (E_F0 *)cxx;
554     delete (E_F0 *)cgg;
555     delete (E_F0 *)citer;
556     delete (E_F0 *)stop;
557   }
558 
Stop(int iterr,R * x,R * g)559   bool Stop(int iterr, R *x, R *g) {
560     iter = iterr;
561     xx.set(x, n);
562     gg.set(g, n);
563     return GetAny< bool >(stop.eval(s));
564   }
565 };
566 
567 template< class R >
568 class LinearCG : public OneOperator {
569  public:
570   typedef KN< R > Kn;
571   typedef KN_< R > Kn_;
572   const int cas;
573 
574   class MatF_O : RNM_VirtualMatrix< R > {
575    public:
576     Stack stack;
577     mutable KN< R > x;
578     C_F0 c_x;
579 
580     Expression mat1, mat;
581     typedef typename RNM_VirtualMatrix< R >::plusAx plusAx;
582 
MatF_O(int n,Stack stk,const OneOperator * op)583     MatF_O(int n, Stack stk, const OneOperator *op)
584       : RNM_VirtualMatrix< R >(n), stack(stk), x(n), c_x(CPValue(x)),
585         mat1(op->code(basicAC_F0_wa(c_x))), mat(CastTo< Kn_ >(C_F0(mat1, (aType)*op))) {}
586 
~MatF_O()587     ~MatF_O( ) {
588       if (mat1 != mat) delete mat;
589       delete mat1;
590       Expression zzz = c_x;
591       delete zzz;
592     }
593 
addMatMul(const Kn_ & xx,Kn_ & Ax) const594     void addMatMul(const Kn_ &xx, Kn_ &Ax) const {
595       ffassert(xx.N( ) == Ax.N( ));
596       x = xx;
597       Ax += GetAny< KN_< R > >((*mat)(stack));
598       WhereStackOfPtr2Free(stack)->clean( );
599     }
600 
operator *(const Kn & x) const601     plusAx operator*(const Kn &x) const { return plusAx(this, x); }
ChecknbLine(int n) const602     virtual bool ChecknbLine(int n) const { return true; }
ChecknbColumn(int m) const603     virtual bool ChecknbColumn(int m) const { return true; }
604   };
605 
606   class E_LCG : public E_F0mps {
607    public:
608     const int cas;    // < 0 => Nolinear
609     static const int n_name_param = 6;
610 
611     static basicAC_F0::name_and_type name_param[];
612 
613     Expression nargs[n_name_param];
614 
615     const OneOperator *A, *C;
616     Expression X, B;
617 
E_LCG(const basicAC_F0 & args,int cc)618     E_LCG(const basicAC_F0 &args, int cc) : cas(cc) {
619       args.SetNameParam(n_name_param, name_param, nargs);
620       {
621         const Polymorphic *op = dynamic_cast< const Polymorphic * >(args[0].LeftValue( ));
622         ffassert(op);
623         A = op->Find("(", ArrayOfaType(atype< Kn * >( ), false));
624         ffassert(A);
625       }
626       if (nargs[2]) {
627         const Polymorphic *op = dynamic_cast< const Polymorphic * >(nargs[2]);
628         ffassert(op);
629         C = op->Find("(", ArrayOfaType(atype< Kn * >( ), false));
630         ffassert(C);
631       } else {
632         C = 0;
633       }
634       X = to< Kn * >(args[1]);
635       if (args.size( ) > 2) {
636         B = to< Kn * >(args[2]);
637       } else {
638         B = 0;
639       }
640     }
641 
operator ( )(Stack stack) const642     virtual AnyType operator( )(Stack stack) const {
643       int ret = -1;
644       E_StopGC< R > *stop = 0;
645       try {
646         Kn &x = *GetAny< Kn * >((*X)(stack));
647         int n = x.N( );
648         MatF_O AA(n, stack, A);
649         double eps = 1.0e-6;
650         double *veps = 0;
651         int nbitermax = 100;
652         long verb = verbosity;
653 
654         if (nargs[0]) eps = GetAny< double >((*nargs[0])(stack));
655         if (nargs[1]) nbitermax = GetAny< long >((*nargs[1])(stack));
656         if (nargs[3]) veps = GetAny< double * >((*nargs[3])(stack));
657         if (nargs[4]) verb = Abs(GetAny< long >((*nargs[4])(stack)));
658         if (nargs[5])
659           stop = new E_StopGC< R >(stack, n, dynamic_cast< const Polymorphic * >(nargs[5]));
660 
661         long gcverb = 51L - Min(Abs(verb), 50L);
662         if (verb == 0) gcverb = 1000000000;    // no print
663         if (veps) eps = *veps;
664         KN< R > bzero(B ? 1 : n);    // const array zero
665         bzero = R( );
666         KN< R > *bb = &bzero;
667         if (B) {
668           Kn &b = *GetAny< Kn * >((*B)(stack));
669           R p = (b, b);
670           // if (p == R()) {
671           //   // ExecError("Sorry LinearCG work only with nul right hand side, so put the right
672           //   hand in the function");
673           // }
674           bb = &b;
675         }
676         if (cas < 0) {
677           if (C) {
678             MatF_O CC(n, stack, C);
679             ret = NLCG(AA, CC, x, nbitermax, eps, gcverb, stop);
680           } else
681             ret = NLCG(AA, MatriceIdentite< R >(n), x, nbitermax, eps, gcverb, stop);
682         } else if (C) {
683           MatF_O CC(n, stack, C);
684           ret = ConjuguedGradient2(AA, CC, x, *bb, nbitermax, eps, gcverb, stop);
685         } else
686           ret =
687             ConjuguedGradient2(AA, MatriceIdentite< R >(n), x, *bb, nbitermax, eps, gcverb, stop);
688         if (veps) *veps = -(eps);
689       } catch (...) {
690         if (stop) delete stop;
691         throw;
692       }
693       if (stop) delete stop;
694       return SetAny< long >(ret);
695     }
696 
operator aType() const697     operator aType( ) const { return atype< long >( ); }
698   };
699 
code(const basicAC_F0 & args) const700   E_F0 *code(const basicAC_F0 &args) const { return new E_LCG(args, cas); }
701 
LinearCG()702   LinearCG( )
703     : OneOperator(atype< long >( ), atype< Polymorphic * >( ), atype< KN< R > * >( ),
704                   atype< KN< R > * >( )),
705       cas(2) {}
706 
LinearCG(int cc)707   LinearCG(int cc)
708     : OneOperator(atype< long >( ), atype< Polymorphic * >( ), atype< KN< R > * >( )), cas(cc) {}
709 };
710 
711 template< class R >
712 basicAC_F0::name_and_type LinearCG< R >::E_LCG::name_param[] = {
713   {"eps", &typeid(double)},    {"nbiter", &typeid(long)},    {"precon", &typeid(Polymorphic *)},
714   {"veps", &typeid(double *)}, {"verbosity", &typeid(long)}, {"stop", &typeid(Polymorphic *)}};
715 
716 template< class R >
717 class LinearGMRES : public OneOperator {
718  public:
719   typedef KN< R > Kn;
720   typedef KN_< R > Kn_;
721   const int cas;
722 
723   class MatF_O : RNM_VirtualMatrix< R > {
724    public:
725     Stack stack;
726     mutable KN< R > x;
727     C_F0 c_x;
728     KN< R > *b;
729     Expression mat1, mat;
730 
731     typedef typename RNM_VirtualMatrix< R >::plusAx plusAx;
MatF_O(int n,Stack stk,const OneOperator * op,KN<R> * bb)732     MatF_O(int n, Stack stk, const OneOperator *op, KN< R > *bb)
733       : RNM_VirtualMatrix< R >(n), stack(stk), x(n), c_x(CPValue(x)), b(bb),
734         mat1(op->code(basicAC_F0_wa(c_x))),
735         mat(CastTo< Kn_ >(C_F0(mat1, (aType)*op)) /*op->code(basicAC_F0_wa(c_x))*/) {}
736 
~MatF_O()737     ~MatF_O( ) {
738       if (mat1 != mat) delete mat;
739       delete mat1;
740       delete c_x.LeftValue( );
741     }
742 
addMatMul(const KN_<R> & xx,KN_<R> & Ax) const743     void addMatMul(const KN_< R > &xx, KN_< R > &Ax) const {
744       ffassert(xx.N( ) == Ax.N( ));
745       x = xx;
746       Ax += GetAny< KN_< R > >((*mat)(stack));
747       if (b && &Ax != b) Ax += *b;    // Ax -b => add b (not in cas of init. b c.a.d  &Ax == b
748       WhereStackOfPtr2Free(stack)->clean( );
749     }
750 
operator *(const Kn & x) const751     plusAx operator*(const Kn &x) const { return plusAx(this, x); }
ChecknbLine(int n) const752     virtual bool ChecknbLine(int n) const { return true; }
ChecknbColumn(int m) const753     virtual bool ChecknbColumn(int m) const { return true; }
754   };
755 
756   class E_LGMRES : public E_F0mps {
757    public:
758     const int cas;    // < 0 => Nolinear
759     static basicAC_F0::name_and_type name_param[];
760     static const int n_name_param = 7;
761     Expression nargs[n_name_param];
762     const OneOperator *A, *C;
763     Expression X, B;
764 
E_LGMRES(const basicAC_F0 & args,int cc)765     E_LGMRES(const basicAC_F0 &args, int cc) : cas(cc) {
766       args.SetNameParam(n_name_param, name_param, nargs);
767       {
768         const Polymorphic *op = dynamic_cast< const Polymorphic * >(args[0].LeftValue( ));
769         ffassert(op);
770         A = op->Find("(", ArrayOfaType(atype< Kn * >( ), false));
771         ffassert(A);
772       }
773       if (nargs[2]) {
774         const Polymorphic *op = dynamic_cast< const Polymorphic * >(nargs[2]);
775         ffassert(op);
776         C = op->Find("(", ArrayOfaType(atype< Kn * >( ), false));
777         ffassert(C);
778       } else
779         C = 0;
780       X = to< Kn * >(args[1]);
781       if (args.size( ) > 2)
782         B = to< Kn * >(args[2]);
783       else
784         B = 0;
785     }
786 
operator ( )(Stack stack) const787     virtual AnyType operator( )(Stack stack) const {
788       Kn &x = *GetAny< Kn * >((*X)(stack));
789       Kn b(x.n);
790       E_StopGC< R > *stop = 0;
791       if (B)
792         b = *GetAny< Kn * >((*B)(stack));
793       else
794         b = R( );
795       int n = x.N( );
796       int dKrylov = 50;
797       double eps = 1.0e-6;
798       int nbitermax = 100;
799       long verb = verbosity;
800       if (nargs[0]) eps = GetAny< double >((*nargs[0])(stack));
801       if (nargs[1]) nbitermax = GetAny< long >((*nargs[1])(stack));
802       if (nargs[3]) eps = *GetAny< double * >((*nargs[3])(stack));
803       if (nargs[4]) dKrylov = GetAny< long >((*nargs[4])(stack));
804       if (nargs[5]) verb = Abs(GetAny< long >((*nargs[5])(stack)));
805       if (nargs[6])
806         stop = new E_StopGC< R >(stack, n, dynamic_cast< const Polymorphic * >(nargs[6]));
807 
808       long gcverb = 51L - Min(Abs(verb), 50L);
809 
810       int ret = -1;
811       if (verbosity > 4)
812         cout << "  ..GMRES: eps= " << eps << " max iter " << nbitermax << " dim of Krylov space "
813              << dKrylov << endl;
814 
815       KNM< R > H(dKrylov + 1, dKrylov + 1);
816       int k = dKrylov;    //,nn=n;
817       double epsr = eps;
818       KN< R > bzero(B ? 1 : n);    // const array zero
819       bzero = R( );
820       KN< R > *bb = &bzero;
821       if (B) {
822         Kn &b = *GetAny< Kn * >((*B)(stack));
823         R p = (b, b);
824         // if (p)
825         // {
826         //   // ExecError("Sorry MPILinearCG work only with nul right hand side, so put the right
827         //   hand in the function");
828         // }
829         bb = &b;
830       }
831       KN< R > *bbgmres = 0;
832       if (!B) bbgmres = bb;    // none zero if gmres without B
833       MatF_O AA(n, stack, A, bbgmres);
834       if (bbgmres) {
835         AA.addMatMul(*bbgmres, *bbgmres);    // Ok Ax == b -> not translation of b .
836         *bbgmres = -(*bbgmres);
837         if (verbosity > 1)
838           cout << "  ** GMRES set b =  -A(0);  : max = " << bbgmres->max( )
839                << " min = " << bbgmres->min( ) << endl;
840       }
841       if (cas < 0) {
842         ErrorExec("NL GMRES:  to do! sorry ", 1);
843       } else {
844         if (C) {
845           MatF_O CC(n, stack, C, 0);
846           ret = GMRES(AA, (KN< R > &)x, *bb, CC, H, k, nbitermax, epsr, verb, stop);
847         } else
848           ret = GMRES(AA, (KN< R > &)x, *bb, MatriceIdentite< R >(n), H, k, nbitermax, epsr, verb,
849                       stop);
850       }
851       if (verbosity > 99) cout << " Sol GMRES :" << x << endl;
852       if (stop) delete stop;
853       return SetAny< long >(ret);
854     }
855 
operator aType() const856     operator aType( ) const { return atype< long >( ); }
857   };
858 
code(const basicAC_F0 & args) const859   E_F0 *code(const basicAC_F0 &args) const { return new E_LGMRES(args, cas); }
860 
LinearGMRES()861   LinearGMRES( )
862     : OneOperator(atype< long >( ), atype< Polymorphic * >( ), atype< KN< R > * >( ),
863                   atype< KN< R > * >( )),
864       cas(2) {}
865 
LinearGMRES(int cc)866   LinearGMRES(int cc)
867     : OneOperator(atype< long >( ), atype< Polymorphic * >( ), atype< KN< R > * >( )), cas(cc) {}
868 };
869 
870 template< class R >
871 basicAC_F0::name_and_type LinearGMRES< R >::E_LGMRES::name_param[] = {
872   {"eps", &typeid(double)},        {"nbiter", &typeid(long)},    {"precon", &typeid(Polymorphic *)},
873   {"veps", &typeid(double *)},     {"dimKrylov", &typeid(long)}, {"verbosity", &typeid(long)},
874   {"stop", &typeid(Polymorphic *)}};
875 
876 template< typename int2 >
closeto(map<int,int2> & m,int k)877 typename map< int, int2 >::iterator closeto(map< int, int2 > &m, int k) {
878   typename map< int, int2 >::iterator i = m.find(k);
879   if (i == m.end( )) {
880     i = m.find(k + 1);
881     if (i == m.end( )) i = m.find(k - 1);
882   }
883   return i;
884 }
885 
886 template< class T, int N >
887 class Smallvect {
888  public:
889   T v[N];
operator [](int i)890   T &operator[](int i) { return v[i]; }
operator [](int i) const891   const T &operator[](int i) const { return v[i]; }
892 };
893 
894 template< class T, int N >
operator <<(ostream & f,const Smallvect<T,N> & v)895 ostream &operator<<(ostream &f, const Smallvect< T, N > &v) {
896   for (int i = 0; i < N; ++i) f << v[i] << ' ';
897   return f;
898 }
899 
900 template< class T >
numeroteclink(KN_<T> & ndfv)901 int numeroteclink(KN_< T > &ndfv) {
902   int nbdfv = 0;
903   for (int i = 0; i < ndfv.N( ); i++) {
904     if (ndfv[i] >= i) {
905       int j = i;
906       int ii;
907       int kkk = 0;
908       do {
909         ii = ndfv[j];
910         ffassert(kkk++ < 10);
911         assert(nbdfv <= j);
912         ndfv[j] = nbdfv;
913         j = ii;
914       } while (j != nbdfv);
915       if (verbosity > 100)
916         cout << "    ndf: " << j << " " << ii << " <- " << nbdfv << " " << kkk << endl;
917       nbdfv++;
918     }
919   }
920   return nbdfv;
921 }
922 
923 //  find k in circular list:  i , p[i], p[p[i]], ...
InCircularList(const int * p,int i,int k)924 bool InCircularList(const int *p, int i, int k) {
925   int j = i;
926   int l = 0;
927   do {
928     if (j == k) return true;
929     ffassert(l++ < 10);
930     j = p[j];
931   } while (j != i);
932   return false;
933 }
934 
BuildPeriodic(int nbcperiodic,Expression * periodic,const Mesh & Th,Stack stack,int & nbdfv,KN<int> & ndfv,int & nbdfe,KN<int> & ndfe)935 bool BuildPeriodic(int nbcperiodic, Expression *periodic, const Mesh &Th, Stack stack, int &nbdfv,
936                    KN< int > &ndfv, int &nbdfe, KN< int > &ndfe) {
937   /*
938     build numbering of vertex form 0 to nbdfv-1
939     and build numbering  of  edge form 0 to nbdfe-1
940     we removing common vextex or common edge
941     --  we suppose one df by vertex
942         nbdfv number of df on vertex
943         ndfv[i]  given the numero of the df of the vertex
944     -- we suppose 1 df
945   */
946   typedef Smallvect< int, 2 > int2;
947   if (nbcperiodic) {
948     ffassert(ndfv.N( ) == Th.nv);
949     ffassert(ndfe.N( ) == Th.neb);
950 
951     MeshPoint *mp = MeshPointStack(stack);
952     MeshPoint smp = *mp;
953     int n = nbcperiodic;
954     if (verbosity > 2) cout << " Nb of pair of periodic conditions = " << n << endl;
955     int *link1 = 0;
956     int *link2 = 0;
957     KN< int * > plk1(n), plk2(n);
958     KN< int > nlk1(n), nlk2(n);
959     KN< int > lab1(n), lab2(n);
960 #ifndef HUGE_VAL
961     const double infty = numeric_limits< double >::infinity( );
962 #else
963     const double infty = HUGE_VAL;
964 #endif
965     int nblink1, nblink2;
966     int *plink1, *plink2;
967     for (int step = 0; step < 2; step++) {
968       nblink1 = 0, nblink2 = 0;
969       plink1 = link1, plink2 = link2;
970       for (int ip = 0, k = 0; ip < n; ip++, k += 4) {
971         int label1 = GetAny< long >((*periodic[k + 0])(stack));
972         int label2 = GetAny< long >((*periodic[k + 2])(stack));
973         lab1[ip] = label1;
974         lab2[ip] = label2;
975 
976         int l1 = nblink1;
977         int l2 = nblink2;
978         plk1[ip] = plink1;
979         plk2[ip] = plink2;
980 
981         for (int ke = 0; ke < Th.neb; ke++) {
982           if (Th.bedges[ke].lab == label1) {
983             if (plink1) *plink1++ = ke;
984             nblink1++;
985           } else if (Th.bedges[ke].lab == label2) {
986             if (plink2) *plink2++ = ke;
987             nblink2++;
988           }
989         }
990         nlk1[ip] = nblink1 - l1;
991         nlk2[ip] = nblink2 - l2;
992       }
993       if (step) break;    // no reallocl
994       if (verbosity > 3)
995         cout << "  Periodic = " << nblink1 << " " << nblink2 << " step=" << step << endl;
996       link1 = new int[nblink1];
997       link2 = new int[nblink2];
998       if (nblink1 != nblink2) {
999         ExecError("Periodic:  the both number of edges is not the same ");
1000       }
1001     }
1002     if (nblink1 > 0) {
1003       for (int ip = 0, k = 0; ip < n; ip++, k += 4) {
1004         map< int, int2 > m;
1005         const int kk1 = 1, kk2 = 3;
1006         int label1 = lab1[ip], label2 = lab2[ip];
1007         int n1 = nlk1[ip], n2 = nlk2[ip];
1008         int *pke1 = plk1[ip], *pke2 = plk2[ip];
1009         double xmn = infty, xmx = -infty, hmn = infty;
1010         if (verbosity > 1)
1011           cout << "  --Update: periodic  couple label1= " << label1 << ", n edges= " << n1 << "; "
1012                << ", label2= " << label2 << ", n edges= " << n2 << endl;
1013         if (n1 != n2) ExecError("periodic BC:  the number of edges is not the same");
1014         for (int i1 = 0; i1 < n1; i1++) {
1015           const BoundaryEdge &e = Th.bedges[pke1[i1]];
1016           if (e.lab == label1) {
1017             mp->set(e[0].x, e[0].y);
1018             double x0 = GetAny< double >((*periodic[k + kk1])(stack));
1019             mp->set(e[1].x, e[1].y);
1020             double x1 = GetAny< double >((*periodic[k + kk1])(stack));
1021             if (verbosity > 5)
1022               cout << "lab1:  e[" << pke1[i1] << "]  v0:   " << e[0].x << " " << e[0].y
1023                    << "  s = " << x0 << "\t v1 " << e[1].x << " " << e[1].y << "  s = " << x1
1024                    << endl;
1025             xmn = Min(x1, x0, xmn);
1026             xmx = Max(x1, x0, xmx);
1027             hmn = Min(hmn, Abs(x1 - x0));
1028           }
1029         }
1030         ffassert(hmn > 1.0e-20);
1031         double coef = 8 / hmn;
1032         double x0 = xmn;
1033         if (verbosity > 2)
1034           cout << "  --Update: periodic " << xmn << " " << xmx << " "
1035                << " h=" << hmn << endl;
1036         ffassert(!n1 || (coef > 1e-10 && (xmx - xmn) * coef < 1.e7));
1037 
1038         //  map construction ----
1039         for (int i1 = 0; i1 < n1; i1++) {
1040           int ie = pke1[i1];
1041           const BoundaryEdge &e = Th.bedges[pke1[i1]];
1042           if (e.lab == label1)
1043             for (int ne = 0; ne < 2; ne++) {
1044               int2 i2;
1045               i2[0] = ie;
1046               i2[1] = -1;
1047               mp->set(e[ne].x, e[ne].y);
1048               double xx = GetAny< double >((*periodic[k + kk1])(stack));
1049               int i0 = (int)((xx - x0) * coef);
1050               map< int, int2 >::iterator im = closeto(m, i0);
1051               if (im == m.end( )) {
1052                 if (verbosity > 50) cout << xx << " " << i0 << " " << ie << endl;
1053                 im = m.insert(pair< int, int2 >(i0, i2)).first;
1054               } else {
1055                 if (verbosity > 50)
1056                   cout << xx << " " << i0 << " " << ie << " :  " << im->second[0] << " "
1057                        << im->second[1] << endl;
1058                 assert((im->second[1] < 0) && (im->second[0] >= 0));
1059                 im->second[1] = ie;
1060               }
1061             }
1062         }
1063 
1064         for (int i2 = 0; i2 < n2; i2++) {
1065           int ie2 = pke2[i2];
1066           const BoundaryEdge &e = Th.bedges[ie2];
1067           if (e.lab == label2) {
1068             if (verbosity > 50) cout << i2 << " : " << Th(e[0]) << " " << Th(e[1]) << ":: ";
1069             mp->set(e[0].x, e[0].y);
1070             double xx0 = GetAny< double >((*periodic[k + kk2])(stack));
1071             mp->set(e[1].x, e[1].y);
1072             double xx1 = GetAny< double >((*periodic[k + kk2])(stack));
1073             if (verbosity > 5)
1074               cout << "lab2:  e[" << pke2[i2] << "]  v0:   " << e[0].x << " " << e[0].y
1075                    << "  s = " << xx0 << "\t v1 " << e[1].x << " " << e[1].y << "  s = " << xx1
1076                    << endl;
1077 
1078             int i0 = int((xx0 - x0) * coef);
1079             int i1 = int((xx1 - x0) * coef);
1080             map< int, int2 >::iterator im0 = closeto(m, i0);
1081             map< int, int2 >::iterator im1 = closeto(m, i1);
1082             if (im0 == m.end( ) || im1 == m.end( )) {
1083               cout << "Abscisse: s0 = " << xx0 << " <==> s1 " << xx1 << endl;
1084               ExecError("periodic: Sorry one vertex of edge is losted ");
1085             }
1086             int ie1 = -1;
1087             if (((ie1 = im0->second[0]) == im1->second[1]) && (ie1 >= 0))
1088               ;
1089             else if (((ie1 = im0->second[0]) == im1->second[1]) && (ie1 >= 0))
1090               ;
1091             else if (((ie1 = im0->second[1]) == im1->second[1]) && (ie1 >= 0))
1092               ;
1093             else if (((ie1 = im0->second[1]) == im1->second[0]) && (ie1 >= 0))
1094               ;
1095             else if (((ie1 = im0->second[0]) == im1->second[0]) && (ie1 >= 0))
1096               ;
1097             else {
1098               cout << ie2 << " ~ " << im0->second[0] << " " << im0->second[1] << ", "
1099                    << im1->second[0] << " " << im1->second[1] << endl;
1100               ExecError("periodic: Sorry one egde is losted ");
1101             }
1102             if (verbosity > 50) cout << " ( " << im0->second << " , " << im1->second << " ) .. ";
1103             ffassert(ie1 >= 0 && ie1 < Th.neb);
1104             const BoundaryEdge &ep = Th.bedges[ie1];
1105             mp->set(ep[0].x, ep[0].y);
1106             double yy0 = GetAny< double >((*periodic[k + kk1])(stack));
1107             mp->set(ep[1].x, ep[1].y);
1108             double yy1 = GetAny< double >((*periodic[k + kk1])(stack));
1109             if (verbosity > 50)
1110               cout << " e0: s  " << xx0 << " " << xx1 << "e1 s " << yy0 << " " << yy1;
1111 
1112             pke1[i2] = ie1 * 2 + (((yy1 - yy0) < 0) == ((xx1 - xx0) < 0));
1113 
1114             if (verbosity > 50)
1115               cout << " \t  edge " << ie1 << " <=> " << ie2 << " "
1116                    << (((yy1 - yy0) < 0) == ((xx1 - xx0) < 0)) << "; " << xx0 << " " << xx1
1117                    << " <=> " << yy0 << " " << yy1 << "  ::  " << Th(ep[0]) << " " << Th(ep[1])
1118                    << endl;
1119           }
1120         }
1121       }
1122 
1123       *mp = smp;
1124       for (int i = 0; i < Th.neb; i++) ndfe[i] = i;    // circular link
1125       for (int i = 0; i < Th.nv; i++) ndfv[i] = i;     // circular link
1126       for (int i = 0; i < nblink1; i++) {
1127         int ie1 = link1[i] / 2;
1128         int sens = link1[i] % 2;
1129         int ie2 = link2[i];
1130         assert(ie1 != ie2);
1131         if (!InCircularList(ndfe, ie1, ie2))    // merge of two list
1132           Exchange(ndfe[ie1], ndfe[ie2]);
1133         for (int ke2 = 0; ke2 < 2; ke2++) {
1134           int ke1 = ke2;
1135           if (!sens) ke1 = 1 - ke1;
1136           int iv1 = Th(Th.bedges[ie1][ke1]);
1137           int iv2 = Th(Th.bedges[ie2][ke2]);
1138           if (!InCircularList(ndfv, iv1, iv2)) {    // merge of two list
1139             Exchange(ndfv[iv2], ndfv[iv1]);
1140             if (verbosity > 50) {
1141               cout << "  vertex " << iv1 << "<==> " << iv2 << " list : " << iv1;
1142               int i = iv1, k = 0;
1143               while ((i = ndfv[i]) != iv1 && k++ < 10) cout << ", " << i;
1144               cout << endl;
1145             }
1146           }
1147         }
1148       }
1149       // generation de numero de dlt
1150 
1151       nbdfv = numeroteclink(ndfv);
1152       nbdfe = numeroteclink(ndfe);
1153       if (verbosity > 2) cout << "  -- nb df on vertices " << nbdfv << endl;
1154       delete[] link1;
1155       delete[] link2;
1156       return true;    // new FESpace(**ppTh,*tef,nbdfv,ndfv,nbdfe,ndfe);
1157     } else {
1158       delete[] link1;
1159       delete[] link2;
1160     }
1161   }
1162   return false;
1163 }
1164 
buildperiodic(Stack stack,int & nbdfv,KN<int> & ndfv,int & nbdfe,KN<int> & ndfe)1165 bool v_fes::buildperiodic(Stack stack, int &nbdfv, KN< int > &ndfv, int &nbdfe, KN< int > &ndfe) {
1166   return BuildPeriodic(nbcperiodic, periodic, **ppTh, stack, nbdfv, ndfv, nbdfe, ndfe);
1167 }
1168 #ifdef ZZZZZZZZ
update()1169 FESpace *pfes_tef::update( ) {
1170   typedef Smallvect< int, 2 > int2;
1171 
1172   if (nbcperiodic) {
1173     const Mesh &Th(**ppTh);
1174     KN< int > ndfv(Th.nv);
1175     KN< int > ndfe(Th.neb);
1176     int nbdfv, nbdfe;
1177     return new FESpace(**ppTh, *tef, nbdfv, ndfv, nbdfe, ndfe);
1178   } else
1179     return new FESpace(**ppTh, *tef);
1180 }
1181 #endif
1182 
1183 struct OpMake_pfes_np {
1184   static const int n_name_param = 1;
1185   static basicAC_F0::name_and_type name_param[];
1186 };
1187 
1188 basicAC_F0::name_and_type OpMake_pfes_np::name_param[] = {"periodic", &typeid(E_Array)};
1189 
1190 // by default, in DSL a FE is 2D, in the building of fespace, if mesh3-S used them associate the
1191 // corresponding FE mapping between TypeOfFE2 and TypeOfFES
1192 map< TypeOfFE *, TypeOfFE3 * > TEF2dto3d;
TypeOfFE3to2(Stack,const AnyType & b)1193 AnyType TypeOfFE3to2(Stack, const AnyType &b) {
1194   TypeOfFE3 *t3 = 0;
1195   TypeOfFE *t2 = GetAny< TypeOfFE * >(b);
1196   map< TypeOfFE *, TypeOfFE3 * >::const_iterator i = TEF2dto3d.find(t2);
1197   if (i != TEF2dto3d.end( )) t3 = i->second;
1198 
1199   if (t3 == 0) {
1200     cerr << " sorry no cast to this 3d finite element " << endl;
1201     ExecError(" sorry no cast to this 3d finite element ");
1202   }
1203   return t3;
1204 }
1205 
1206 // mapping between TypeOfFE2 and TypeOfFES
1207 map< TypeOfFE *, TypeOfFES * > TEF2dtoS;
TypeOfFESto2(Stack,const AnyType & b)1208 AnyType TypeOfFESto2(Stack, const AnyType &b) {
1209   TypeOfFES *tS = 0;
1210   TypeOfFE *t2 = GetAny< TypeOfFE * >(b);
1211   map< TypeOfFE *, TypeOfFES * >::const_iterator i = TEF2dtoS.find(t2);
1212   if (i != TEF2dtoS.end( )) tS = i->second;
1213 
1214   if (tS == 0) {
1215     cerr << " sorry no cast to this surface finite element " << endl;
1216     ExecError(" sorry no cast to this surface finite element ");
1217   }
1218   return tS;
1219 }
1220 
1221 // mapping between TypeOfFE2 and TypeOfFEL
1222 map< TypeOfFE *, TypeOfFEL * > TEF2dtoL;
TypeOfFELto2(Stack,const AnyType & b)1223 AnyType TypeOfFELto2(Stack, const AnyType &b) {
1224   TypeOfFEL *tL = 0;
1225   TypeOfFE *t2 = GetAny< TypeOfFE * >(b);
1226   map< TypeOfFE *, TypeOfFEL * >::const_iterator i = TEF2dtoL.find(t2);
1227   if (i != TEF2dtoL.end( )) tL = i->second;
1228 
1229   if (tL == 0) {
1230     cerr << " sorry no cast to this curve finite element " << endl;
1231     ExecError(" sorry no cast to this curve finite element ");
1232   }
1233   return tL;
1234 }
1235 
FindFE2(const char * s)1236 TypeOfFE *FindFE2(const char *s) {
1237   for (ListOfTFE *i = ListOfTFE::all; i; i = i->next)
1238     if (strcmp(i->name, s) == 0) return i->tfe;
1239   cout << " s =" << s << endl;
1240   lgerror("FindFE2 ");
1241   return 0;
1242 }
1243 
1244 typedef TypeOfFE TypeOfFE2;
1245 template< class pfes, class Mesh, class TypeOfFE, class pfes_tefk >
1246 struct OpMake_pfes : public OneOperator, public OpMake_pfes_np {
1247   struct Op : public E_F0mps {
1248    public:
1249     Expression eppTh;
1250     Expression eppfes;
1251     const E_Array &atef;
1252     int nb;
1253     int nbcperiodic;
1254     Expression *periodic;
1255     KN< int > tedim;
OpOpMake_pfes::Op1256     Op(Expression ppfes, Expression ppTh, const E_Array &aatef, int nbp, Expression *pr,
1257        KN< int > &ttedim)
1258       : eppTh(ppTh), eppfes(ppfes), atef(aatef), nbcperiodic(nbp), periodic(pr), tedim(ttedim) {}
~OpOpMake_pfes::Op1259     ~Op( ) {
1260       if (periodic) delete[] periodic;
1261     }
operator ( )OpMake_pfes::Op1262     AnyType operator( )(Stack s) const {
1263       const int d = Mesh::Rd::d;
1264       const int dHat = Mesh::RdHat::d;
1265       const Mesh **ppTh = GetAny< const Mesh ** >((*eppTh)(s));
1266       AnyType r = (*eppfes)(s);
1267       const TypeOfFE **tef = new const TypeOfFE *[atef.size( )];
1268         for (int i = 0; i < atef.size( ); i++)
1269         if (tedim[i] == d)
1270           tef[i] = GetAny< TypeOfFE * >(atef[i].eval(s));
1271         else if (tedim[i] == 2 && d==3 && dHat == 3)
1272           tef[i] = GetAny< TypeOfFE * >(TypeOfFE3to2(s, atef[i].eval(s)));
1273         else if (tedim[i] == 2 && d==3 && dHat == 2)
1274           tef[i] = GetAny< TypeOfFE * >(TypeOfFESto2(s, atef[i].eval(s)));
1275         else if (tedim[i] == 2 && d==3 && dHat == 1)
1276           tef[i] = GetAny< TypeOfFE * >(TypeOfFELto2(s, atef[i].eval(s)));
1277         else
1278           ffassert(0);
1279 
1280       pfes *ppfes = GetAny< pfes * >(r);
1281       bool same = true;
1282       for (int i = 1; i < atef.size( ); i++) same &= atef[i].LeftValue( ) == atef[1].LeftValue( );
1283       *ppfes = new pfes_tefk(ppTh, tef, atef.size( ), s, nbcperiodic, periodic);
1284       return r;
1285     }
1286   };
1287 
codeOpMake_pfes1288   E_F0 *code(const basicAC_F0 &args) const {
1289     int nbcperiodic = 0;
1290     Expression *periodic = 0;
1291     Expression nargs[n_name_param];
1292 
1293     args.SetNameParam(n_name_param, name_param, nargs);
1294     GetPeriodic(Mesh::Rd::d, nargs[0], nbcperiodic, periodic);
1295     aType t_tfe = atype< TypeOfFE * >( );
1296     aType t_tfe2 = atype< TypeOfFE2 * >( );
1297     int d = TypeOfFE::Rd::d;
1298     string sdim = d ? " 2d : " : " 3d : ";
1299     const E_Array *a2(dynamic_cast< const E_Array * >(args[2].LeftValue( )));
1300     ffassert(a2);
1301     int N = a2->size( );
1302     ;
1303     if (!N) CompileError(sdim + " We wait an array of Type of Element ");
1304     KN< int > tedim(N);
1305     for (int i = 0; i < N; i++)
1306       if ((*a2)[i].left( ) == t_tfe)
1307         tedim[i] = d;
1308       else if ((*a2)[i].left( ) == t_tfe2)
1309         tedim[i] = 2;
1310       else
1311         CompileError(sdim + " We wait an array of  Type of Element ");
1312     //    ffassert(0);
1313     return new Op(args[0], args[1], *a2, nbcperiodic, periodic, tedim);
1314   }
OpMake_pfesOpMake_pfes1315   OpMake_pfes( )
1316     : OneOperator(atype< pfes * >( ), atype< pfes * >( ), atype< const Mesh ** >( ),
1317                   atype< E_Array >( )) {}
1318 };
1319 
MakePtr2(pfes * const & p,pmesh * const & a,TypeOfFE * const & tef)1320 inline pfes *MakePtr2(pfes *const &p, pmesh *const &a, TypeOfFE *const &tef) {
1321   *p = new pfes_tef(a, tef);
1322   return p;
1323 }
1324 
MakePtr3(pfes3 * const & p,pmesh3 * const & a,TypeOfFE3 * const & tef)1325 inline pfes3 *MakePtr3(pfes3 *const &p, pmesh3 *const &a, TypeOfFE3 *const &tef) {
1326   *p = new pfes3_tef(a, tef);
1327   return p;
1328 }
1329 
MakePtrS(pfesS * const & p,pmeshS * const & a,TypeOfFES * const & tef)1330 inline pfesS *MakePtrS(pfesS *const &p, pmeshS *const &a, TypeOfFES *const &tef) {
1331   *p = new pfesS_tef(a, tef);
1332   return p;
1333 }
1334 
MakePtrL(pfesL * const & p,pmeshL * const & a,TypeOfFEL * const & tef)1335 inline pfesL *MakePtrL(pfesL *const &p, pmeshL *const &a, TypeOfFEL *const &tef) {
1336   *p = new pfesL_tef(a, tef);
1337   return p;
1338 }
1339 
1340 class OP_MakePtr2 {
1341  public:
1342   class Op : public E_F0mps {
1343    public:
1344     //  static int GetPeriodic(Expression  bb, Expression & b,Expression & f);
1345     static const int n_name_param = 1;
1346     static basicAC_F0::name_and_type name_param[];
1347     Expression nargs[n_name_param];
1348     typedef pfes *R;
1349     typedef pfes *A;
1350     typedef pmesh *B;
1351     typedef TypeOfFE *C;
1352     Expression a, b, c;
1353     int nbcperiodic;
1354     Expression *periodic;
1355     Op(const basicAC_F0 &args);
1356 
operator ( )(Stack s) const1357     AnyType operator( )(Stack s) const {
1358       A p = GetAny< A >((*a)(s));
1359       B th = GetAny< B >((*b)(s));
1360       C tef = GetAny< C >((*c)(s));
1361       *p = new pfes_tef(th, tef, s, nbcperiodic, periodic);
1362       return SetAny< R >(p);
1363     }
1364   };    // end Op class
1365 
1366   typedef Op::R Result;
f(const basicAC_F0 & args)1367   static E_F0 *f(const basicAC_F0 &args) { return new Op(args); }
typeargs()1368   static ArrayOfaType typeargs( ) {
1369     return ArrayOfaType(atype< Op::A >( ), atype< Op::B >( ), atype< Op::C >( ), false);
1370   }
1371 };
1372 
1373 class OP_MakePtr3 {
1374  public:
1375   class Op : public E_F0mps {
1376    public:
1377     static const int n_name_param = 1;
1378     static basicAC_F0::name_and_type name_param[];
1379     Expression nargs[n_name_param];
1380     typedef pfes3 *R;
1381     typedef pfes3 *A;
1382     typedef pmesh3 *B;
1383     typedef TypeOfFE3 *C;
1384     Expression a, b, c;
1385     int nbcperiodic;
1386     Expression *periodic;
1387     Op(const basicAC_F0 &args);
1388 
operator ( )(Stack s) const1389     AnyType operator( )(Stack s) const {
1390       A p = GetAny< A >((*a)(s));
1391       B th = GetAny< B >((*b)(s));
1392       C tef = GetAny< C >((*c)(s));
1393       *p = new pfes3_tef(th, tef, s, nbcperiodic, periodic);
1394       return SetAny< R >(p);
1395     }
1396   };    // end Op class
1397 
1398   typedef Op::R Result;
f(const basicAC_F0 & args)1399   static E_F0 *f(const basicAC_F0 &args) { return new Op(args); }
typeargs()1400   static ArrayOfaType typeargs( ) {
1401     return ArrayOfaType(atype< Op::A >( ), atype< Op::B >( ), atype< Op::C >( ), false);
1402   }
1403 };
1404 
1405 class OP_MakePtrS {
1406  public:
1407   class Op : public E_F0mps {
1408    public:
1409     //  static int GetPeriodic(Expression  bb, Expression & b,Expression & f);
1410     static const int n_name_param = 1;
1411     static basicAC_F0::name_and_type name_param[];
1412     Expression nargs[n_name_param];
1413     typedef pfesS *R;
1414     typedef pfesS *A;
1415     typedef pmeshS *B;
1416     typedef TypeOfFES *C;
1417     Expression a, b, c;
1418     int nbcperiodic;
1419     Expression *periodic;
1420     Op(const basicAC_F0 &args);
1421 
operator ( )(Stack s) const1422     AnyType operator( )(Stack s) const {
1423       A p = GetAny< A >((*a)(s));
1424       B th = GetAny< B >((*b)(s));
1425       C tef = GetAny< C >((*c)(s));
1426       *p = new pfesS_tef(th, tef, s, nbcperiodic, periodic);
1427       return SetAny< R >(p);
1428     }
1429   };    // end Op class
1430 
1431   typedef Op::R Result;
f(const basicAC_F0 & args)1432   static E_F0 *f(const basicAC_F0 &args) { return new Op(args); }
typeargs()1433   static ArrayOfaType typeargs( ) {
1434     return ArrayOfaType(atype< Op::A >( ), atype< Op::B >( ), atype< Op::C >( ), false);
1435   }
1436 };
1437 
1438 class OP_MakePtrL {
1439  public:
1440   class Op : public E_F0mps {
1441    public:
1442     //  static int GetPeriodic(Expression  bb, Expression & b,Expression & f);
1443     static const int n_name_param = 1;
1444     static basicAC_F0::name_and_type name_param[];
1445     Expression nargs[n_name_param];
1446     typedef pfesL *R;
1447     typedef pfesL *A;
1448     typedef pmeshL *B;
1449     typedef TypeOfFEL *C;
1450     Expression a, b, c;
1451     int nbcperiodic;
1452     Expression *periodic;
1453     Op(const basicAC_F0 &args);
1454 
operator ( )(Stack s) const1455     AnyType operator( )(Stack s) const {
1456       A p = GetAny< A >((*a)(s));
1457       B th = GetAny< B >((*b)(s));
1458       C tef = GetAny< C >((*c)(s));
1459       *p = new pfesL_tef(th, tef, s, nbcperiodic, periodic);
1460       return SetAny< R >(p);
1461     }
1462   };    // end Op class
1463 
1464   typedef Op::R Result;
f(const basicAC_F0 & args)1465   static E_F0 *f(const basicAC_F0 &args) { return new Op(args); }
typeargs()1466   static ArrayOfaType typeargs( ) {
1467     return ArrayOfaType(atype< Op::A >( ), atype< Op::B >( ), atype< Op::C >( ), false);
1468   }
1469 };
1470 
GetPeriodic(const int d,Expression perio,int & nbcperiodic,Expression * & periodic)1471 void GetPeriodic(const int d, Expression perio, int &nbcperiodic, Expression *&periodic) {
1472   ffassert(d == 2 || d == 3);
1473   if (perio) {
1474     if (verbosity > 1) cout << "  -- Periodical Condition to do" << endl;
1475     const E_Array *a = dynamic_cast< const E_Array * >(perio);
1476     ffassert(a);
1477     int n = a->size( );
1478     nbcperiodic = n / 2;
1479     if (verbosity > 1) cout << "    the number of periodicBC " << n << endl;
1480     if (2 * nbcperiodic != n) CompileError(" Sorry the number of periodicBC must by even");
1481     periodic = new Expression[n * d];
1482     for (int i = 0, j = 0; i < n; i++, j += d)
1483       if (d == 2) {
1484         if (GetPeriodic((*a)[i], periodic[j], periodic[j + 1]) == 0)
1485           CompileError(" a sub array of periodic BC must be [label, realfunction ]");
1486       } else if (d == 3) {
1487         if (GetPeriodic((*a)[i], periodic[j], periodic[j + 1], periodic[j + 2]) == 0)
1488           CompileError(" a sub array of periodic BC must be [label, realfunction , realfunction]");
1489       } else
1490         ffassert(0);
1491   }
1492 }
1493 
Op(const basicAC_F0 & args)1494 OP_MakePtr2::Op::Op(const basicAC_F0 &args)
1495   : a(to< A >(args[0])), b(to< B >(args[1])), c(to< C >(args[2])) {
1496   nbcperiodic = 0;
1497   periodic = 0;
1498   args.SetNameParam(n_name_param, name_param, nargs);
1499   GetPeriodic(2, nargs[0], nbcperiodic, periodic);
1500 }
1501 // 3D volume
Op(const basicAC_F0 & args)1502 OP_MakePtr3::Op::Op(const basicAC_F0 &args)
1503   : a(to< A >(args[0])), b(to< B >(args[1])), c(to< C >(args[2])) {
1504   nbcperiodic = 0;
1505   periodic = 0;
1506   args.SetNameParam(n_name_param, name_param, nargs);
1507   GetPeriodic(3, nargs[0], nbcperiodic, periodic);
1508 }
1509 // 3D surface
Op(const basicAC_F0 & args)1510 OP_MakePtrS::Op::Op(const basicAC_F0 &args)
1511   : a(to< A >(args[0])), b(to< B >(args[1])), c(to< C >(args[2])) {
1512   nbcperiodic = 0;
1513   periodic = 0;
1514   args.SetNameParam(n_name_param, name_param, nargs);
1515   GetPeriodic(3, nargs[0], nbcperiodic, periodic);
1516 }
1517 // 3D curve
Op(const basicAC_F0 & args)1518 OP_MakePtrL::Op::Op(const basicAC_F0 &args)
1519   : a(to< A >(args[0])), b(to< B >(args[1])), c(to< C >(args[2])) {
1520   nbcperiodic = 0;
1521   periodic = 0;
1522   args.SetNameParam(n_name_param, name_param, nargs);
1523   GetPeriodic(3, nargs[0], nbcperiodic, periodic);
1524 }
1525 
GetPeriodic(Expression bb,Expression & b,Expression & f)1526 int GetPeriodic(Expression bb, Expression &b, Expression &f) {
1527   const E_Array *a = dynamic_cast< const E_Array * >(bb);
1528   if (a && a->size( ) == 2) {
1529     b = to< long >((*a)[0]);
1530     f = to< double >((*a)[1]);
1531     return 1;
1532   } else
1533     return 0;
1534 }
GetPeriodic(Expression bb,Expression & b,Expression & f1,Expression & f2)1535 int GetPeriodic(Expression bb, Expression &b, Expression &f1, Expression &f2) {
1536   const E_Array *a = dynamic_cast< const E_Array * >(bb);
1537   if (a && a->size( ) == 3) {
1538     b = to< long >((*a)[0]);
1539     f1 = to< double >((*a)[1]);
1540     f2 = to< double >((*a)[2]);
1541     return 1;
1542   } else
1543     return 0;
1544 }
1545 
1546 basicAC_F0::name_and_type OP_MakePtr2::Op::name_param[] = {"periodic", &typeid(E_Array)};
1547 
1548 basicAC_F0::name_and_type OP_MakePtr3::Op::name_param[] = {"periodic", &typeid(E_Array)};
1549 
1550 basicAC_F0::name_and_type OP_MakePtrS::Op::name_param[] = {"periodic", &typeid(E_Array)};
1551 
1552 basicAC_F0::name_and_type OP_MakePtrL::Op::name_param[] = {"periodic", &typeid(E_Array)};
1553 
MakePtr2(pfes * const & p,pmesh * const & a)1554 inline pfes *MakePtr2(pfes *const &p, pmesh *const &a) {
1555   *p = new pfes_tef(a, &P1Lagrange);
1556   return p;
1557 }
1558 
MakePtr2(pfes * const & p,pfes * const & a,long const & n)1559 inline pfes *MakePtr2(pfes *const &p, pfes *const &a, long const &n) {
1560   *p = new pfes_fes(a, n);
1561   return p;
1562 }
1563 
FindTxy(Stack s,pmesh * const & ppTh,const double & x,const double & y)1564 long FindTxy(Stack s, pmesh *const &ppTh, const double &x, const double &y) {
1565   R2 P(x, y), PHat;
1566   bool outside;
1567   MeshPoint &mp = *MeshPointStack(s);
1568   const Mesh *pTh = *ppTh;
1569   if (pTh == 0) return 0;
1570   const Triangle *K = pTh->Find(mp.P.p2( ), PHat, outside);
1571   if (!outside)
1572     mp.set(*pTh, P, PHat, *K, K->lab);
1573   else
1574     return 0;
1575   return 1;
1576 }
1577 
1578 template< class K >
pfer2vect(pair<FEbase<K,v_fes> *,int> p)1579 KN< K > *pfer2vect(pair< FEbase< K, v_fes > *, int > p) {
1580   KN< K > *x = p.first->x( );
1581   if (!x) {                             // defined
1582     FESpace *Vh = p.first->newVh( );    // cout << "test 1" << endl;
1583     throwassert(Vh);
1584     *p.first = x = new KN< K >(Vh->NbOfDF);
1585     *x = K( );
1586   }
1587   return x;
1588 }
1589 
1590 template< class K >
pfer_Th(pair<FEbase<K,v_fes> *,int> p)1591 pmesh pfer_Th(pair< FEbase< K, v_fes > *, int > p) {
1592   if (!p.first->Vh) p.first->Vh = p.first->newVh( );
1593   throwassert(!!p.first->Vh);
1594   return &p.first->Vh->Th;
1595 }
1596 //  add to refesh Th in fespace oct 2018
1597 template< class K, class v_fes >
pfer_refresh(pair<FEbase<K,v_fes> *,int> p)1598 bool pfer_refresh(pair< FEbase< K, v_fes > *, int > p) {
1599   int n = 0;
1600   if (p.first->x( )) n = p.first->x( )->N( );
1601   const FESpace *Vho = p.first->Vh;
1602   p.first->Vh = p.first->newVh( );
1603   if (n && n != p.first->Vh->NbOfDF) *p.first = new KN< K >(p.first->Vh->NbOfDF, K( ));
1604   return Vho != (const FESpace *)p.first->Vh;    // FE change !!!
1605 }
1606 template< class K >
pfer_nbdf(pair<FEbase<K,v_fes> *,int> p)1607 long pfer_nbdf(pair< FEbase< K, v_fes > *, int > p) {
1608   if (!p.first->Vh) p.first->Vh = p.first->newVh( );
1609   throwassert(!!p.first->Vh);
1610   return p.first->Vh->NbOfDF;
1611 }
1612 
pmesh_area(pmesh * p)1613 double pmesh_area(pmesh *p) {
1614   throwassert(p);
1615   return *p ? (**p).area : 0.0;
1616 }
pmesh_bordermeasure(pmesh * p)1617 double pmesh_bordermeasure(pmesh *p) {
1618   throwassert(p);
1619   return *p ? (**p).lenbord : 0.0;
1620 }
1621 
pmesh_nt(pmesh * p)1622 long pmesh_nt(pmesh *p) {
1623   throwassert(p);
1624   return *p ? (**p).nt : 0;
1625 }
pmesh_nbe(pmesh * p)1626 long pmesh_nbe(pmesh *p) {
1627   throwassert(p);
1628   return *p ? (**p).neb : 0;
1629 }
pmesh_nv(pmesh * p)1630 long pmesh_nv(pmesh *p) {
1631   throwassert(p);
1632   return *p ? (**p).nv : 0;
1633 }
1634 
pmesh_hmax(pmesh * p)1635 double pmesh_hmax(pmesh *p) {
1636   if(p && *p) {
1637     double hmax2 = 0;
1638     const Mesh &Th = **p;
1639     for (int k = 0; k < Th.nt; ++k)
1640       for (int e = 0; e < 3; ++e) hmax2 = max(hmax2, Th[k].lenEdge2(e));
1641     return sqrt(hmax2);
1642   } else return 0.0;
1643 }
1644 
pmesh_hmin(pmesh * p)1645 double pmesh_hmin(pmesh *p) {
1646   if(p && *p) {
1647     double hmin2 = 1e100;
1648     const Mesh &Th = **p;
1649     for (int k = 0; k < Th.nt; ++k)
1650       for (int e = 0; e < 3; ++e) hmin2 = min(hmin2, Th[k].lenEdge2(e));
1651     return sqrt(hmin2);
1652   } else return 0.0;
1653 }
1654 
pVh_ndof(pfes * p)1655 long pVh_ndof(pfes *p) {
1656   throwassert(p && *p);
1657   FESpace *fes = **p;
1658   ;
1659   return fes->NbOfDF;
1660 }
pVh_Th(pfes * p)1661 pmesh pVh_Th(pfes *p) {
1662   throwassert(p && *p);
1663   FESpace *fes = **p;
1664   ;
1665   return &fes->Th;
1666 }
1667 
pVh_nt(pfes * p)1668 long pVh_nt(pfes *p) {
1669   throwassert(p && *p);
1670   FESpace *fes = **p;
1671   ;
1672   return fes->NbOfElements;
1673 }
pVh_ndofK(pfes * p)1674 long pVh_ndofK(pfes *p) {
1675   throwassert(p && *p);
1676   FESpace *fes = **p;
1677   return (*fes)[0].NbDoF( );
1678 }
1679 
mp_nuTriangle(MeshPoint * p)1680 long mp_nuTriangle(MeshPoint *p) {
1681   throwassert(p && p->Th && p->T);
1682   long nu = -1;
1683   if (p->d == 2)
1684     nu = (*p->Th)(p->T);
1685   else if (p->d == 3 && p->dHat == 3)
1686     nu = (*p->Th3)(p->T3);
1687   else if (p->d == 3 && p->dHat == 2)
1688     nu = (*p->ThS)(p->TS);
1689   else if (p->d == 3 && p->dHat == 1)
1690     nu = (*p->ThL)(p->TL);
1691   else
1692     ffassert(0);
1693   delete p;
1694   return nu;
1695 }
1696 
mp_region(MeshPoint * p)1697 long mp_region(MeshPoint *p) {
1698   long nu(p->region);
1699   delete p;
1700   return nu;
1701 }
1702 
1703 class pVh_ndf : public ternary_function< pfes *, long, long, long > {
1704  public:
1705   class Op : public E_F0mps {
1706    public:
1707     Expression a, b, c;
Op(Expression aa,Expression bb,Expression cc)1708     Op(Expression aa, Expression bb, Expression cc) : a(aa), b(bb), c(cc) {}
operator ( )(Stack s) const1709     AnyType operator( )(Stack s) const {
1710       pfes *p(GetAny< pfes * >((*a)(s)));
1711       long k(GetAny< long >((*b)(s)));
1712       long i(GetAny< long >((*c)(s)));
1713       throwassert(p && *p);
1714       FESpace *fes = **p;
1715       throwassert(fes && k >= 0 && k < fes->NbOfElements);
1716       FElement K = (*fes)[k];
1717       throwassert(i >= 0 && i < K.NbDoF( ));
1718       long ret(K(i));
1719       return ret;
1720     }
1721   };
1722 };
1723 
1724 class Op_CopyArray : public OneOperator {
1725  public:
Op_CopyArray()1726   Op_CopyArray( ) : OneOperator(atype< void >( ), atype< E_Array >( ), atype< E_Array >( )) {}
1727   E_F0 *code(const basicAC_F0 &args) const;
1728 };
1729 
1730 template< class R, int dd >
pfer2R(Stack s,const AnyType & a)1731 AnyType pfer2R(Stack s, const AnyType &a) {
1732   pair< FEbase< R, v_fes > *, int > ppfe = GetAny< pair< FEbase< R, v_fes > *, int > >(a);
1733   FEbase< R, v_fes > &fe(*ppfe.first);
1734   int componante = ppfe.second;
1735   if (!fe.x( )) {
1736     if (!fe.x( )) {
1737       return SetAny< R >(0.0);
1738     }
1739   }
1740 
1741   const FESpace &Vh(*fe.Vh);
1742   const Mesh &Th(Vh.Th);
1743   assert(Th.ntet == 0 && Th.volume == 0 && Th.triangles != 0);
1744   MeshPoint &mp = *MeshPointStack(s);
1745   const Triangle *K;
1746   R2 PHat;
1747   bool outside = false;
1748   bool qnu = true;
1749   if (mp.Th == &Th && mp.T) {
1750     qnu = false;
1751     K = mp.T;
1752     PHat = mp.PHat.p2( );
1753   } else if (mp.other.Th == &Th && mp.other.P.x == mp.P.x && mp.other.P.y == mp.P.y) {
1754     K = mp.other.T;
1755     PHat = mp.other.PHat.p2( );
1756     outside = mp.other.outside;
1757   } else {
1758     if (mp.isUnset( )) ExecError("Try to get unset x,y, ...");
1759     K = Th.Find(mp.P.p2( ), PHat, outside);
1760     mp.other.set(Th, mp.P.p2( ), PHat, *K, 0, outside);
1761   }
1762   const FElement KK(Vh[Th(K)]);
1763   if (outside && !KK.tfe->NbDfOnVertex && !KK.tfe->NbDfOnEdge) return SetAny< R >(0.0);
1764 
1765   const R rr = KK(PHat, *fe.x( ), componante, dd);
1766   return SetAny< R >(rr);
1767 }
1768 
1769 template< class R >
set_fe(Stack s,Expression ppfe,Expression e)1770 AnyType set_fe(Stack s, Expression ppfe, Expression e) {
1771   long kkff = Mesh::kfind, kkth = Mesh::kthrough;
1772   StackOfPtr2Free *sptr = WhereStackOfPtr2Free(s);
1773 
1774   MeshPoint *mps = MeshPointStack(s), mp = *mps;
1775   pair< FEbase< R, v_fes > *, int > pp = GetAny< pair< FEbase< R, v_fes > *, int > >((*ppfe)(s));
1776   FEbase< R, v_fes > &fe(*pp.first);
1777   const FESpace *pVh(fe.newVh( ));
1778 
1779   if (!pVh) ExecError("Unset FEspace (Null mesh ? ) on  uh= ");
1780   const FESpace &Vh = *pVh;
1781   KN< R > gg(Vh.MaximalNbOfDF( ));
1782   const Mesh &Th(Vh.Th);
1783   TabFuncArg tabexp(s, Vh.N);
1784   tabexp[0] = e;
1785 
1786   if (Vh.N != 1) {
1787     cerr << " Try to set a  vectorial  FE function  (nb  componant=" << Vh.N << ") with one scalar "
1788          << endl;
1789     ExecError(" Error interploation (set)  FE function (vectorial) with a scalar");
1790   }
1791   KN< R > *y = new KN< R >(Vh.NbOfDF);
1792   KN< R > &yy(*y);
1793   KN< R > Viso(100);
1794   for (int i = 0; i < Viso.N( ); i++) Viso[i] = 0.01 * i;
1795 
1796   FElement::aIPJ ipj(Vh[0].Pi_h_ipj( ));
1797   FElement::aR2 PtHat(Vh[0].Pi_h_R2( ));
1798   KN< double > Aipj(ipj.N( ));
1799   KN< R > Vp(PtHat.N( ));
1800   const E_F0 &ff(*(const E_F0 *)e);
1801 
1802   if (Vh.isFEMesh( )) {
1803     ffassert(Vh.NbOfDF == Th.nv && Vh.N == 1);
1804     for (int iv = 0; iv < Th.nv; iv++) {
1805       const Vertex &v(Th(iv));
1806       int ik = Th.Contening(&v);
1807       const Triangle &K(Th[ik]);
1808       int il = -1;
1809       if (&K[0] == &v) il = 0;
1810       if (&K[1] == &v) il = 1;
1811       if (&K[2] == &v) il = 2;
1812       assert(il >= 0);
1813       mps->set(Th, v, TriangleHat[il], K, v.lab);
1814       yy[iv] = GetAny< R >(ff(s));
1815       sptr->clean( );    // modif FH mars 2006  clean Ptr
1816     }
1817   } else
1818 
1819     for (int t = 0; t < Th.nt; t++) {
1820       FElement K(Vh[t]);
1821       int nbdf = K.NbDoF( );
1822       gg = R( );
1823 #ifdef OLDPih
1824       // old method
1825       K.Pi_h(gg, F_Pi_h, F, &tabexp);
1826 #else
1827       K.Pi_h(Aipj);
1828       for (int p = 0; p < PtHat.N( ); p++) {
1829         mps->set(K.T(PtHat[p]), PtHat[p], K);
1830         Vp[p] = GetAny< R >(ff(s));
1831       }
1832       for (int i = 0; i < Aipj.N( ); i++) {
1833         const FElement::IPJ &ipj_i(ipj[i]);
1834         assert(ipj_i.j == 0);    // car  Vh.N=0
1835         gg[ipj_i.i] += Aipj[i] * Vp[ipj_i.p];
1836       }
1837 #endif
1838       for (int df = 0; df < nbdf; df++) (*y)[K(df)] = gg[df];
1839       sptr->clean( );    // modif FH mars 2006  clean Ptr
1840     }
1841   *mps = mp;
1842   fe = y;
1843   kkff = Mesh::kfind - kkff;
1844   kkth = Mesh::kthrough - kkth;
1845 
1846   if (verbosity > 1)
1847     ShowBound(*y, cout) << " " << kkth << "/" << kkff << " =  "
1848                         << double(kkth) / Max< double >(1., kkff) << endl;
1849   return SetAny< FEbase< R, v_fes > * >(&fe);
1850 }
set_feoX_1(Stack s,Expression ppfeX_1,Expression e)1851 AnyType set_feoX_1(Stack s, Expression ppfeX_1, Expression e) {    // inutile
1852                                                                    // meme chose que  v(X1,X2);
1853   StackOfPtr2Free *sptr = WhereStackOfPtr2Free(s);
1854   typedef const interpolate_f_X_1< R >::CODE *code;
1855   MeshPoint mp = *MeshPointStack(s);
1856   code ipp = dynamic_cast< code >(ppfeX_1);
1857 
1858   pair< FEbase< R, v_fes > *, int > pp = GetAny< pair< FEbase< R, v_fes > *, int > >((*ipp->f)(s));
1859   FEbase< R, v_fes > &fe(*pp.first);
1860   const FESpace &Vh(*fe.newVh( ));
1861   KN< R > gg(Vh.MaximalNbOfDF( ));
1862   const Mesh &Th(Vh.Th);
1863   R F[100];    // buffer
1864   TabFuncArg tabexp(s, Vh.N + 2);
1865   tabexp[0] = e;
1866   tabexp[1] = ipp->x;
1867   tabexp[2] = ipp->y;
1868 
1869   throwassert(Vh.N == 1);
1870   KN< R > *y = new KN< R >(Vh.NbOfDF);
1871   for (int t = 0; t < Th.nt; t++) {
1872     FElement K(Vh[t]);
1873     int nbdf = K.NbDoF( );
1874 
1875     gg = R( );
1876 
1877     K.Pi_h(gg, FoX_1_Pi_h, F, &tabexp);
1878     for (int df = 0; df < nbdf; df++) (*y)[K(df)] = gg[df];
1879     sptr->clean( );    // modif FH mars 2006  clean Ptr
1880   }
1881   *MeshPointStack(s) = mp;
1882   fe = y;
1883   if (verbosity > 1)
1884     cout << "  -- interpole f= g*X^-1, function's bound:  " << y->min( ) << " " << y->max( )
1885          << endl;
1886   return SetAny< FEbase< R, v_fes > * >(&fe);
1887 }
1888 
1889 template< class K >
E_set_fev(const E_Array * a,Expression pp,int ddim)1890 E_set_fev< K >::E_set_fev(const E_Array *a, Expression pp, int ddim)
1891   : dim(ddim), aa(*a), ppfe(pp), optimize(true), where_in_stack_opt( ), optiexp0( ), optiexpK( ) {
1892   aa.map(to< K >);
1893   bool kdump = false;
1894   if (optimize) {    // new code Optimized  -------
1895     int n = aa.size( );
1896     deque< pair< Expression, int > > ll;
1897     MapOfE_F0 m;
1898     where_in_stack_opt.resize(n);
1899     size_t top = currentblock->OffSet(0), topbb = top;    // FH. bofbof ???
1900     for (int i = 0; i < n; i++) {
1901       Expression ee = aa[i].LeftValue( );
1902       if (kdump)
1903         cout << "Optimize OneOperatorMakePtrFE:  type exp: " << typeid(*ee).name( ) << " " << endl;
1904       where_in_stack_opt[i] = ee->Optimize(ll, m, top);
1905       if (kdump) cout << "\n\t\t" << i << ": " << where_in_stack_opt[i] << endl;
1906     }
1907 
1908     currentblock->OffSet(top - topbb);
1909     int k = ll.size( ), k0 = 0, k1 = 0;
1910     for (int i = 0; i < k; i++)
1911       if (ll[i].first->MeshIndependent( )) k0++;
1912     deque< pair< Expression, int > > l0(k0), l1(k - k0);
1913     k0 = 0, k1 = 0;
1914     for (int i = 0; i < k; i++)
1915       if (ll[i].first->MeshIndependent( )) {
1916         if (kdump) cout << " mi " << ll[i].second << " " << *(ll[i].first) << endl;
1917         l0[k0++] = ll[i];
1918       } else {
1919         if (kdump) cout << " md " << ll[i].second << " " << *(ll[i].first) << endl;
1920         l1[k1++] = ll[i];
1921       }
1922     if (k0) optiexp0 = new E_F0_Optimize(l0, m, 0);    // constant part
1923     if (k1) optiexpK = new E_F0_Optimize(l1, m, 0);    // none constant part
1924   }
1925 }
1926 
1927 template< class K >
operator ( )(Stack s) const1928 AnyType E_set_fev< K >::operator( )(Stack s) const {
1929   if (dim == 2)
1930     return Op2d(s);
1931   else if (dim == 3)
1932     return Op3d(s);
1933   else if (dim == 4)
1934     return OpS(s);
1935   return Nothing;
1936 }
1937 
1938 template< class K >
Op3d(Stack s) const1939 AnyType E_set_fev< K >::Op3d(Stack s) const {
1940   //  voir E_set_fev3  ( pb de consitance a revoir FH)
1941   ffassert(0);    // a faire
1942 }
1943 
1944 template< class K >
OpS(Stack s) const1945 AnyType E_set_fev< K >::OpS(Stack s) const {
1946   //  voir E_set_fevS  ( pb de consitance a revoir FH)
1947   ffassert(0);    // a faire
1948 }
1949 
1950 template< class K >
Op2d(Stack s) const1951 AnyType E_set_fev< K >::Op2d(Stack s) const {
1952   StackOfPtr2Free *sptr = WhereStackOfPtr2Free(s);
1953   MeshPoint *mps = MeshPointStack(s), mp = *mps;
1954   FEbase< K, v_fes > **pp = GetAny< FEbase< K, v_fes > ** >((*ppfe)(s));
1955   FEbase< K, v_fes > &fe(**pp);
1956   const FESpace &Vh(*fe.newVh( ));
1957   KN< K > gg(Vh.MaximalNbOfDF( ));
1958 
1959   const Mesh &Th(Vh.Th);
1960   const int dim = Vh.N;
1961   K **copt = 0;
1962   if (optimize) copt = new K *[dim];
1963   if (copt) {
1964     assert((size_t)dim == where_in_stack_opt.size( ));
1965     for (int i = 0; i < dim; i++) {
1966       int offset = where_in_stack_opt[i];
1967       assert(offset > 10);
1968       copt[i] = static_cast< K * >(static_cast< void * >((char *)s + offset));
1969       *(copt[i]) = 0;
1970     }
1971     if (optiexp0) (*optiexp0)(s);    // init
1972   }
1973 
1974 #ifdef OLDPih
1975   ffassert(dim < 100);
1976 #endif
1977 
1978   TabFuncArg tabexp(s, Vh.N);
1979   ffassert(aa.size( ) == Vh.N);
1980   for (int i = 0; i < dim; i++) tabexp[i] = aa[i];
1981 
1982   KN< K > *y = new KN< K >(Vh.NbOfDF);
1983   KN< K > &yy(*y);
1984 
1985   FElement::aIPJ ipj(Vh[0].Pi_h_ipj( ));
1986   FElement::aR2 PtHat(Vh[0].Pi_h_R2( ));
1987 
1988   KN< double > Aipj(ipj.N( ));
1989 
1990   KN< K > Vp1(dim * PtHat.N( ));
1991 
1992   if (Vh.isFEMesh( )) {
1993     ffassert(Vh.NbOfDF == Th.nv && dim == 1);
1994     for (int iv = 0; iv < Th.nv; iv++) {
1995       const E_F0 &ff(*(const E_F0 *)aa[0]);
1996       const Vertex &v(Th(iv));
1997       int ik = Th.Contening(&v);
1998       const Triangle &Kt(Th[ik]);
1999       int il = -1;
2000       if (&Kt[0] == &v) il = 0;
2001       if (&Kt[1] == &v) il = 1;
2002       if (&Kt[2] == &v) il = 2;
2003       assert(il >= 0);
2004       mps->set(Th, v, TriangleHat[il], Kt, v.lab);
2005       if (copt) {
2006         if (optiexpK) (*optiexpK)(s);
2007         yy[iv] = *(copt[0]);
2008       } else
2009         yy[iv] = GetAny< K >(ff(s));
2010       sptr->clean( );    // modif FH mars 2006  clean Ptr
2011     }
2012 
2013   } else
2014     for (int t = 0; t < Th.nt; t++) {
2015       FElement Kt(Vh[t]);
2016       int nbdf = Kt.NbDoF( );
2017 
2018       gg = K( );
2019 
2020 #ifdef OLDPih
2021       // old method
2022       Kt.Pi_h(gg, F_Pi_h, F, &tabexp);
2023 #else
2024       Kt.Pi_h(Aipj);
2025 
2026       for (int p = 0; p < PtHat.N( ); p++) {
2027         mps->set(Kt.T(PtHat[p]), PtHat[p], Kt);
2028 
2029         KN_< K > Vpp(Vp1, SubArray(dim, p * dim));    // a Change FHHHHHHHH
2030         if (copt) {                                   // optimize  version
2031           if (optiexpK) (*optiexpK)(s);
2032           for (int j = 0; j < dim; j++) Vpp[j] = *(copt[j]);
2033         } else    // old version
2034           for (int j = 0; j < dim; j++)
2035             if (tabexp[j])
2036               Vpp[j] = GetAny< K >((*tabexp[j])(s));
2037             else
2038               Vpp[j] = 0;
2039       }
2040 
2041       for (int i = 0; i < Aipj.N( ); i++) {
2042         const FElement::IPJ &ipj_i(ipj[i]);
2043         gg[ipj_i.i] += Aipj[i] * Vp1(ipj_i.j + ipj_i.p * dim);    // index a la main
2044         sptr->clean( );                                           // modif FH mars 2006  clean Ptr
2045       }
2046 #endif
2047 
2048       for (int df = 0; df < nbdf; df++) yy[Kt(df)] = gg[df];
2049     }
2050   fe = y;
2051   if (copt) delete[] copt;
2052   *MeshPointStack(s) = mp;
2053   if (verbosity > 1) ShowBound(*y, cout) << endl;
2054   return Nothing;
2055 }
2056 
2057 template< class K >
MakePtrFE(pfes * const & a)2058 inline FEbase< K, v_fes > *MakePtrFE(pfes *const &a) {
2059   FEbase< K, v_fes > *p = new FEbase< K, v_fes >(a);
2060   return p;
2061 }
2062 
2063 template< class K >
MakePtrFE2(FEbase<K,v_fes> ** const & p,pfes * const & a)2064 inline FEbase< K, v_fes > **MakePtrFE2(FEbase< K, v_fes > **const &p, pfes *const &a) {
2065   *p = new FEbase< K, v_fes >(a);
2066   return p;
2067 }
2068 
2069 template< class K >
MakePtrFE3(FEbaseArray<K,v_fes> ** const & p,pfes * const & a,const long & N)2070 inline FEbaseArray< K, v_fes > **MakePtrFE3(FEbaseArray< K, v_fes > **const &p, pfes *const &a,
2071                                             const long &N) {
2072   *p = new FEbaseArray< K, v_fes >(a, N);
2073   return p;
2074 }
2075 
2076 template< class K >
2077 class OneOperatorMakePtrFE : public OneOperator {
2078  public:
2079   typedef FEbase< K, v_fes > **R;
2080   typedef pfes *B;
2081   class CODE : public E_F0mps {
2082    public:
2083     Expression fer, fes;
2084     E_set_fev< K > *e_set_fev;
2085     const E_Array *v;
CODE(const basicAC_F0 & args)2086     CODE(const basicAC_F0 &args) : fer(to< R >(args[0])), fes(to< B >(args[1])), e_set_fev(0) {
2087       if (BCastTo< K >(args[2]))
2088         v = new E_Array(basicAC_F0_wa(to< K >(args[2])));
2089       else
2090         v = dynamic_cast< const E_Array * >(args[2].LeftValue( ));
2091       if (!v) {
2092         cout << "Error: type of arg :" << *args[2].left( ) << " in " << typeid(K).name( )
2093              << " case " << endl;
2094         ErrorCompile(" We wait  a double/complex expression or a array expression", 1);
2095       }
2096       e_set_fev = new E_set_fev< K >(v, fer, v_fes::dHat);
2097     }
2098 
operator ( )(Stack stack) const2099     AnyType operator( )(Stack stack) const {
2100       R p = GetAny< R >((*fer)(stack));
2101       B a = GetAny< B >((*fes)(stack));
2102       *p = new FEbase< K, v_fes >(a);
2103       (*e_set_fev)(stack);
2104       return SetAny< R >(p);
2105     }
operator aType() const2106     operator aType( ) const { return atype< R >( ); }
2107   };
2108 
code(const basicAC_F0 & args) const2109   E_F0 *code(const basicAC_F0 &args) const { return new CODE(args); }
OneOperatorMakePtrFE(aType tt)2110   OneOperatorMakePtrFE(aType tt)
2111     :    // tt= aType<double>() or aType<E_Array>()
2112       OneOperator(map_type[typeid(R).name( )], map_type[typeid(R).name( )],
2113                   map_type[typeid(B).name( )], tt) {}
2114 };
2115 
2116 template< class Result, class A >
2117 class OneOperator_Ptr_o_R : public OneOperator {
2118   typedef Result A::*ptr;
2119   ptr p;
2120 
2121  public:
code(const basicAC_F0 & args) const2122   E_F0 *code(const basicAC_F0 &args) const {
2123     return new E_F_A_Ptr_o_R< Result, A >(t[0]->CastTo(args[0]), p);
2124   }
OneOperator_Ptr_o_R(ptr pp)2125   OneOperator_Ptr_o_R(ptr pp) : OneOperator(atype< Result * >( ), atype< A * >( )), p(pp) {}
2126 };
2127 
2128 template< class K >
PAddition(const K * a,const K * b)2129 K *PAddition(const K *a, const K *b) {
2130   return new K(*a + *b);
2131 }
2132 
2133 class fCLD {
2134  public:
2135   typedef pair< int, Label > Key;
2136   typedef map< Key, Expression >::iterator iterator;
2137   map< Key, Expression > *l;
fCLD()2138   fCLD( ) { l = new map< Key, Expression >; }
operator =(const fCLD & a)2139   void operator=(const fCLD &a) { *l = *a.l; }
destroy()2140   void destroy( ) {
2141     delete l;
2142     l = 0;
2143   }
~fCLD()2144   ~fCLD( ) {
2145     delete l;
2146     l = 0;
2147   }
Add(finconnue * v,int lab,C_F0 f)2148   void Add(finconnue *v, int lab, C_F0 f) {
2149     const MGauche *pn = v->simple( );
2150     Check(pn, "Def CL Dirichet ");
2151 
2152     Label r(lab);
2153     Key k(make_pair(pn->first, r));
2154     iterator i = l->find(k);
2155     Check(i != l->end( ), "Def CL Dirichet already exists");
2156     l->insert(make_pair(k, CastTo< double >(f)));
2157   }
2158 };
2159 
2160 //  pour stocker des expression de compilation
2161 
2162 class Convect : public E_F0mps {
2163  public:
2164   typedef double Result;    // return type
2165   Expression u, v, w, ff, dt;
2166   long state;
2167   static Expression ou, ov, ow, odt;    // previous def
2168   static long count;
2169   int d;
Convect(const basicAC_F0 & args)2170   Convect(const basicAC_F0 &args) : u(0), v(0), w(0), ff(0), dt(0) {
2171     args.SetNameParam( );
2172     const E_Array *a = dynamic_cast< const E_Array * >(args[0].LeftValue( ));
2173     ffassert(a);
2174     d = a->size( );
2175     if (d == 3)
2176       w = CastTo< double >((*a)[2]);
2177     else if (d != 2) {
2178       CompileError("convect vector have only 2 or 3 componant");
2179     }
2180     u = CastTo< double >((*a)[0]);
2181     v = CastTo< double >((*a)[1]);
2182 
2183     dt = CastTo< double >(args[1]);
2184     ff = CastTo< double >(args[2]);
2185     // save previous  state
2186     if (!((ou && u->compare(ou) == 0) && (v->compare(ov) == 0) &&
2187           ((w == 0) || (w->compare(ov) == 0)) && (dt->compare(odt) == 0))) {
2188       count++;
2189     }
2190     state = count;    // use of optim of convect
2191     if (verbosity > 3) cout << "\n  -- Convert number of Convect case:  .... " << state << endl;
2192     ou = u;
2193     ov = v;
2194     ow = w;
2195     odt = dt;
2196   }
2197 
typeargs()2198   static ArrayOfaType typeargs( ) {
2199     return ArrayOfaType(atype< E_Array >( ), atype< double >( ), atype< double >( ));
2200   }
2201 
f(const basicAC_F0 & args)2202   static E_F0 *f(const basicAC_F0 &args) { return new Convect(args); }
2203   AnyType operator( )(Stack s) const;
2204   AnyType eval2(Stack s) const;
2205   AnyType eval3(Stack s) const;
2206   AnyType eval3old(Stack s) const;    // old version a supprime en  2017
operator aType() const2207   operator aType( ) const { return atype< Result >( ); }
2208 };
2209 Expression Convect::ou = 0;
2210 Expression Convect::ov = 0;
2211 Expression Convect::ow = 0;
2212 Expression Convect::odt = 0;
2213 long Convect::count = 0;
2214 /// <<Plot>> used for the [[plot_keyword]]
2215 
2216 class Plot : public E_F0mps /* [[file:AFunction.hpp::E_F0mps]] */ {
2217  public:
2218   typedef KN_< R > tab;
2219   typedef KN< KN< R > > *pttab;
2220   typedef pferbase sol;
2221   typedef pferbasearray asol;
2222   typedef pf3rbase sol3;
2223   typedef pf3rbasearray asol3;
2224   typedef pfSrbase solS;
2225   typedef pfSrbasearray asolS;
2226   typedef pfLrbase solL;
2227   typedef pfLrbasearray asolL;
2228 
2229   typedef pfecbase solc;
2230   typedef pfecbasearray asolc;
2231   typedef pf3cbase solc3;
2232   typedef pf3cbasearray asolc3;
2233   typedef pfScbase solcS;
2234   typedef pfScbasearray asolcS;
2235   typedef pfLcbase solcL;
2236   typedef pfLcbasearray asolcL;
2237 
2238   typedef long Result;
2239   struct ListWhat {
2240     int what, i;
2241     int cmp[4];
2242     int n;
2243     union {
2244       long l[4];
2245       void *v[4];           //  for
2246       const void *cv[4];    //  for
2247     };
thPlot::ListWhat2248     pmesh th( ) {
2249       assert(v[0] && what == 0);
2250       return static_cast< pmesh >(cv[0]);
2251     }
th3Plot::ListWhat2252     pmesh3 th3( ) {
2253       assert(v[0] && what == 5);
2254       return static_cast< pmesh3 >(cv[0]);
2255     }
thSPlot::ListWhat2256     pmeshS thS( ) {
2257       assert(v[0] && what == 50);
2258       return static_cast< pmeshS >(cv[0]);
2259     }
thLPlot::ListWhat2260     pmeshL thL( ) {
2261       assert(v[0] && what == 55);
2262       return static_cast< pmeshL >(cv[0]);
2263     }
2264 
SetPlot::ListWhat2265     void Set(int nn = 0, void **vv = 0, int *c = 0) {
2266       cmp[0] = cmp[1] = cmp[2] = cmp[3] = -1;
2267       v[0] = v[1] = v[2] = v[3] = 0;
2268       n = nn;
2269       for (int i = 0; i < nn; ++i) {
2270         if (c) cmp[i] = c[i];
2271         if (vv) v[i] = vv[i];
2272       }
2273     }
SetPlot::ListWhat2274     void Set(int nn, const void **vv, int *c = 0) {
2275       cmp[0] = cmp[1] = cmp[2] = cmp[3] = -1;
2276       v[0] = v[1] = v[2] = v[3] = 0;
2277       cv[0] = cv[1] = cv[2] = cv[3] = 0;
2278       n = nn;
2279       for (int i = 0; i < nn; ++i) {
2280         if (c) cmp[i] = c[i];
2281         if (vv) cv[i] = vv[i];
2282       }
2283     }
2284 
ListWhatPlot::ListWhat2285     ListWhat(int w = -1, int ii = -1) : what(w), i(ii) { Set( ); }
ListWhatPlot::ListWhat2286     ListWhat(int what, int ii, int n, void **f0, int *c) : what(what), i(ii) { Set(n, f0, c); }
ListWhatPlot::ListWhat2287     ListWhat(int what, int ii, int n, const void **f0, int *c) : what(what), i(ii) {
2288       Set(n, f0, c);
2289     }
2290 
ListWhatPlot::ListWhat2291     ListWhat(int what, int ii, void *f0) : what(what), i(ii) { Set(1, &f0, 0); }
ListWhatPlot::ListWhat2292     ListWhat(int what, int ii, const void *f0) : what(what), i(ii) { Set(1, &f0, 0); }
2293 
ListWhatPlot::ListWhat2294     ListWhat(int what, int ii, int nn, long *f0) : what(what), i(ii), n(nn) {
2295       cmp[0] = cmp[1] = cmp[2] = cmp[3] = -1;
2296       v[0] = v[1] = v[2] = v[3] = 0;
2297       for (int i = 0; i < n; ++i) l[i] = f0[i];
2298     }
2299 
2300     template< typename S >
evalPlot::ListWhat2301     void eval(S *f, int *c) {
2302       for (int i = 0; i < 3; ++i) {
2303         f[i] = static_cast< S >(v[i]);
2304         c[i] = cmp[i];
2305       }
2306     }
2307 
2308     template< typename M >
evalPlot::ListWhat2309     M eval( ) {
2310       assert(v[0]);
2311       return static_cast< M >(v[0]);
2312     }
evalPlot::ListWhat2313     void eval(sol &f0, int &cmp0, sol &f1, int &cmp1) {
2314       f0 = static_cast< sol >(v[0]);
2315       f1 = static_cast< sol >(v[1]);
2316       cmp0 = cmp[0];
2317       cmp1 = cmp[1];
2318     }
evalPlot::ListWhat2319     void eval(solS &f0, int &cmp0, solS &f1, int &cmp1)    // TODO a template func
2320     {
2321       f0 = static_cast< solS >(v[0]);
2322       f1 = static_cast< solS >(v[1]);
2323       cmp0 = cmp[0];
2324       cmp1 = cmp[1];
2325     }
2326   };
2327 
2328   /// <<Expression2>>
2329   struct Expression2 {    //  FH. change nov 2016  add one  expression  for  colored curve ...
2330     long what;            // 0 mesh, 1 iso, 2 vector, 3 curve , 4 border , 5  mesh3, 6 iso 3d,
2331     // 7: vector 3d  ( +10 -> complex visu ???? )
2332     // 101 array of iso 2d  , 106 array of iso 3d  , 100  array of meshes
2333     // 103  array of curves ...
2334     bool composant;
2335     Expression e[4];
Expression2Plot::Expression22336     Expression2( ) {
2337       e[0] = 0;
2338       e[1] = 0;
2339       e[2] = 0;
2340       e[3] = 0;
2341       composant = false;
2342       what = 0;
2343     }
operator []Plot::Expression22344     Expression &operator[](int i) { return e[i]; }
2345 
EvalandPushPlot::Expression22346     int EvalandPush(Stack s, int ii, vector< ListWhat > &ll,
2347                     vector< AnyType > &lat) const {    // add for curve ... and multi curve ...
2348       //  store date in lat..
2349       long f[4];
2350       for (int i = 0; i < 4; ++i) {
2351         f[i] = -1;
2352         if (e[i]) {    // eval ..
2353           f[i] = lat.size( );
2354           lat.push_back((*e[i])(s));
2355         }
2356       }
2357       ll.push_back(ListWhat(what, ii, 4, f));
2358       return 4;
2359     }
2360 
2361     template< class S >
EvalandPushPlot::Expression22362     int EvalandPush(Stack s, int ii, vector< ListWhat > &ll) const {
2363       int n = -1;
2364       S f[3] = {0, 0, 0};
2365       int cmp[3] = {-1, -1, -1};
2366 
2367       for (int i = 0; i < 3; ++i)
2368         if (e[i]) {
2369           if (!composant) {
2370             pair< S, int > p = GetAny< pair< S, int > >((*e[i])(s));
2371             n = i;
2372             cmp[i] = p.second;
2373             f[i] = p.first;
2374           } else {
2375             cmp[i] = 0;
2376             f[i] = GetAny< S >((*e[i])(s));
2377             n = i;
2378           }
2379         }
2380       ll.push_back(ListWhat(what, ii, n + 1, f, cmp));
2381       return n;
2382     }
2383 
AEvalandPushPlot::Expression22384     int AEvalandPush(Stack s, int ii, vector< ListWhat > &ll, vector< AnyType > &lat) const {
2385       pttab pt[4] = {0, 0, 0, 0};
2386       pt[0] = evalptt(0, s);
2387       pt[1] = evalptt(1, s);
2388       if (e[2]) pt[2] = evalptt(2, s);
2389       if (e[3]) pt[3] = evalptt(3, s);
2390       int kt = min(pt[0]->N( ), pt[1]->N( ));
2391 
2392       for (int j = 0; j < kt; ++j) {
2393         int what = 13;
2394         long f[4];
2395         if (verbosity > 99) cout << " plot : A curve " << j << " ";
2396         for (int k = 0; k < 4; ++k) {
2397           pttab ptk = pt[k];
2398           f[k] = -1;
2399           if (ptk) {
2400             KN_< double > t = (*ptk)[j];
2401             f[k] = lat.size( );
2402             if (verbosity > 99) cout << " (" << k << ") " << t.N( ) << " " << f[k];
2403 
2404             lat.push_back(SetAny< KN_< double > >(t));
2405           }
2406         }
2407         if (verbosity > 99) cout << endl;
2408 
2409         ll.push_back(ListWhat(what, ii, 4, f));
2410       }
2411       return 4;
2412     }
2413 
2414     template< class A, class S >    // ok of mesh too because composant=true;
AEvalandPushPlot::Expression22415     int AEvalandPush(Stack s, int ii, vector< ListWhat > &ll) const {
2416       typedef pair< A, int > PA;
2417       int nn = -1;
2418       A f[3];
2419       union {
2420         S fj[3];
2421         void *fv[3];
2422       };
2423       f[0] = f[1] = f[2] = 0;
2424       int cmp[3] = {-1, -1, -1};
2425 
2426       for (int i = 0; i < 3; ++i)
2427         if (e[i]) {
2428           if (!composant) {
2429             PA p = GetAny< PA >((*e[i])(s));
2430             cmp[i] = p.second;
2431             f[i] = p.first;
2432             nn = i;
2433           } else {
2434             f[i] = GetAny< A >((*e[i])(s));
2435             cmp[i] = 0;
2436             nn = i;
2437           }
2438         } else
2439           break;
2440       nn++;
2441       int n = f[0]->N;
2442       if (verbosity > 50)    // add 01/2011 FH ????
2443         cout << "add  N = " << n << " " << nn << " " << what << endl;
2444       for (int j = 0; j < n; ++j) {
2445         int m = -1;
2446         fj[0] = fj[1] = fj[2] = 0;    // clean
2447         for (int i = 0; i < nn; ++i) {
2448           fj[i] = *f[i]->operator[](j);
2449           if (fj[i] && fj[i]->x( ))
2450             m = i;
2451           else
2452             break;
2453         }
2454         if (m >= 0) {
2455           ll.push_back(ListWhat(what % 100, ii, m + 1, fv, cmp));
2456           if (verbosity > 100) cout << ".";
2457         }
2458       }
2459       if (verbosity > 100) cout << endl;
2460       return nn;
2461     }
2462     template< class S >
MEvalandPushPlot::Expression22463     int MEvalandPush(Stack s, int ii, vector< ListWhat > &ll) const {
2464       typedef KN< S > *A;
2465 
2466       A ath;
2467 
2468       ath = GetAny< A >((*e[0])(s));
2469       int n = 0;
2470       if (ath) n = ath->N( );
2471       S th;
2472 
2473       for (int j = 0; j < n; ++j) {
2474         th = ath->operator[](j);
2475         if (th) ll.push_back(ListWhat(what % 100, ii, static_cast< const void * >(th)));
2476       }
2477       return n;
2478     }
2479 
evalPlot::Expression22480     sol eval(int i, Stack s, int &cmp) const {
2481       cmp = -1;
2482       if (e[i]) {
2483         if (!composant) {
2484           pfer p = GetAny< pfer >((*e[i])(s));
2485           cmp = p.second;
2486           return p.first;
2487         } else {
2488           return GetAny< pferbase >((*e[i])(s));
2489         }
2490       } else
2491         return 0;
2492     }
eval3Plot::Expression22493     sol3 eval3(int i, Stack s, int &cmp) const {
2494       cmp = -1;
2495       if (e[i]) {
2496         if (!composant) {
2497           pf3r p = GetAny< pf3r >((*e[i])(s));
2498           cmp = p.second;
2499           return p.first;
2500         } else {
2501           return GetAny< pf3rbase >((*e[i])(s));
2502         }
2503       } else
2504         return 0;
2505     }
evalSPlot::Expression22506     solS evalS(int i, Stack s, int &cmp) const {
2507         cmp = -1;
2508         if (e[i]) {
2509           if (!composant) {
2510             pfSr p = GetAny< pfSr >((*e[i])(s));
2511             cmp = p.second;
2512             return p.first;
2513           } else {
2514             return GetAny< pfSrbase >((*e[i])(s));
2515           }
2516         } else
2517           return 0;
2518     }
evalLPlot::Expression22519     solL evalL(int i, Stack s, int &cmp) const {
2520         cmp = -1;
2521         if (e[i]) {
2522           if (!composant) {
2523             pfLr p = GetAny< pfLr >((*e[i])(s));
2524             cmp = p.second;
2525             return p.first;
2526           } else {
2527             return GetAny< pfLrbase >((*e[i])(s));
2528           }
2529         } else
2530           return 0;
2531     }
2532 
2533     // add FH Japon 2010 ..	for complex visu ...  to complex ....  try to uniformize ...
evalcPlot::Expression22534     solc evalc(int i, Stack s, int &cmp) const {
2535       cmp = -1;
2536       if (e[i]) {
2537         if (!composant) {
2538           pfec p = GetAny< pfec >((*e[i])(s));
2539           cmp = p.second;
2540           return p.first;
2541         } else {
2542           return GetAny< pfecbase >((*e[i])(s));
2543         }
2544       } else
2545         return 0;
2546     }
evalc3Plot::Expression22547     solc3 evalc3(int i, Stack s, int &cmp) const {
2548       cmp = -1;
2549       if (e[i]) {
2550         if (!composant) {
2551           pf3c p = GetAny< pf3c >((*e[i])(s));
2552           cmp = p.second;
2553           return p.first;
2554         } else {
2555           return GetAny< pf3cbase >((*e[i])(s));
2556         }
2557       } else
2558         return 0;
2559     }
evalcSPlot::Expression22560     solcS evalcS(int i, Stack s, int &cmp) const {
2561       cmp = -1;
2562       if (e[i]) {
2563         if (!composant) {
2564           pfSc p = GetAny< pfSc >((*e[i])(s));
2565           cmp = p.second;
2566           return p.first;
2567         } else {
2568           return GetAny< pfScbase >((*e[i])(s));
2569         }
2570       } else
2571         return 0;
2572     }
evalcLPlot::Expression22573     solcL evalcL(int i, Stack s, int &cmp) const {
2574       cmp = -1;
2575       if (e[i]) {
2576         if (!composant) {
2577           pfLc p = GetAny< pfLc >((*e[i])(s));
2578           cmp = p.second;
2579           return p.first;
2580         } else {
2581           return GetAny< pfLcbase >((*e[i])(s));
2582         }
2583       } else
2584         return 0;
2585     }
evalaPlot::Expression22586     asol evala(int i, Stack s, int &cmp) const {
2587       cmp = -1;
2588       if (e[i]) {
2589         pferarray p = GetAny< pferarray >((*e[i])(s));
2590         cmp = p.second;
2591         return p.first;
2592       } else
2593         return 0;
2594     }
evala3Plot::Expression22595     asol3 evala3(int i, Stack s, int &cmp) const {
2596       cmp = -1;
2597       if (e[i]) {
2598         pf3rarray p = GetAny< pf3rarray >((*e[i])(s));
2599         cmp = p.second;
2600         return p.first;
2601       } else
2602         return 0;
2603     }
evalaSPlot::Expression22604     asolS evalaS(int i, Stack s, int &cmp) const {
2605       cmp = -1;
2606       if (e[i]) {
2607         pfSrarray p = GetAny< pfSrarray >((*e[i])(s));
2608         cmp = p.second;
2609         return p.first;
2610       } else
2611         return 0;
2612     }
evalaLPlot::Expression22613     asolL evalaL(int i, Stack s, int &cmp) const {
2614       cmp = -1;
2615       if (e[i]) {
2616          pfLrarray p = GetAny< pfLrarray >((*e[i])(s));
2617          cmp = p.second;
2618          return p.first;
2619        } else
2620          return 0;
2621     }
evalcaPlot::Expression22622     asolc evalca(int i, Stack s, int &cmp) const {
2623       cmp = -1;
2624       if (e[i]) {
2625         pfecarray p = GetAny< pfecarray >((*e[i])(s));
2626         cmp = p.second;
2627         return p.first;
2628       } else
2629         return 0;
2630     }
evalca3Plot::Expression22631     asolc3 evalca3(int i, Stack s, int &cmp) const {
2632       cmp = -1;
2633       if (e[i]) {
2634         pf3carray p = GetAny< pf3carray >((*e[i])(s));
2635         cmp = p.second;
2636         return p.first;
2637       } else
2638         return 0;
2639     }
evalcaSPlot::Expression22640     asolcS evalcaS(int i, Stack s, int &cmp) const {
2641       cmp = -1;
2642       if (e[i]) {
2643         pfScarray p = GetAny< pfScarray >((*e[i])(s));
2644         cmp = p.second;
2645         return p.first;
2646       } else
2647         return 0;
2648     }
evalcaLPlot::Expression22649     asolcL evalcaL(int i, Stack s, int &cmp) const {
2650         cmp = -1;
2651         if (e[i]) {
2652           pfLcarray p = GetAny< pfLcarray >((*e[i])(s));
2653           cmp = p.second;
2654           return p.first;
2655         } else
2656           return 0;
2657      }
evalmPlot::Expression22658     const Mesh &evalm(int i, Stack s) const {
2659       throwassert(e[i]);
2660       return *GetAny< pmesh >((*e[i])(s));
2661     }
evalmaPlot::Expression22662     KN< pmesh > *evalma(int i, Stack s) const {
2663       throwassert(e[i]);
2664       return GetAny< KN< pmesh > * >((*e[i])(s));
2665     }
evalm3Plot::Expression22666     const Mesh3 &evalm3(int i, Stack s) const {
2667       throwassert(e[i]);
2668       return *GetAny< pmesh3 >((*e[i])(s));
2669     }
evalmSPlot::Expression22670     const MeshS &evalmS(int i, Stack s) const {
2671       throwassert(e[i]);
2672       return *GetAny< pmeshS >((*e[i])(s));
2673     }
evalmLPlot::Expression22674     const MeshL &evalmL(int i, Stack s) const {
2675       throwassert(e[i]);
2676       return *GetAny< pmeshL >((*e[i])(s));
2677     }
evalbPlot::Expression22678     const E_BorderN *evalb(int i, Stack s) const {
2679       throwassert(e[i]);
2680       return GetAny< const E_BorderN * >((*e[i])(s));
2681     }
evaltPlot::Expression22682     tab evalt(int i, Stack s) const {
2683       throwassert(e[i]);
2684       return GetAny< tab >((*e[i])(s));
2685     }
evalpttPlot::Expression22686     pttab evalptt(int i, Stack s) const {
2687       throwassert(e[i]);
2688       return GetAny< pttab >((*e[i])(s));
2689     }
2690   };
2691 
2692   // see [[Plot_name_param]]
2693   static basicAC_F0::name_and_type name_param[];
2694 
2695   /// <<number_of_distinct_named_parameters_for_plot>> FFCS: added new parameters for VTK graphics.
2696   /// See
2697   /// [[Plot_name_param]] for new parameter names
2698   static const int n_name_param = 44;
2699 
2700   Expression bb[4];
2701 
2702   /// [[Expression2]] is a description of an object to plot
2703   vector< Expression2 > l;
2704   typedef KN< KN< double > > *ptaboftab;
2705   Expression nargs[n_name_param];
2706 
Plot(const basicAC_F0 & args)2707   Plot(const basicAC_F0 &args) : l(args.size( )) {
2708     args.SetNameParam(n_name_param, name_param, nargs);
2709     if (nargs[8]) Box2x2(nargs[8], bb);
2710 
2711     // scan all the parameters of the plot() call
2712     for (size_t i = 0; i < l.size( ); i++)
2713 
2714       // argument is an [[file:AFunction.hpp::E_Array]] (= array of E_F0)
2715       if (args[i].left( ) == atype< E_Array >( )) {
2716         l[i].composant = false;
2717         const E_Array *a = dynamic_cast< const E_Array * >(args[i].LeftValue( ));
2718         ffassert(a);
2719         int asizea = a->size( );
2720         if (asizea == 0) CompileError("plot of vector with 0 of components(!= 2 or 3) ");
2721         bool bpfer = BCastTo< pfer >((*a)[0]);
2722         bool bpf3r = BCastTo< pf3r >((*a)[0]);
2723         bool bpfSr = BCastTo< pfSr >((*a)[0]);    // for 3D surface with reals
2724         bool bpfLr = BCastTo< pfLr >((*a)[0]);    // for 3D curve with reals
2725         bool bpfec = BCastTo< pfec >((*a)[0]);
2726         bool bpf3c = BCastTo< pf3c >((*a)[0]);
2727         bool bpfSc = BCastTo< pfSc >((*a)[0]);    // for 3D surface with complex
2728         bool bpfLc = BCastTo< pfLc >((*a)[0]);    // for 3D curve with complex
2729         bool bptab = BCastTo< tab >((*a)[0]);
2730         bool bpttab = BCastTo< pttab >((*a)[0]);
2731         bool bpferarray = BCastTo< pferarray >((*a)[0]);
2732         bool bpfecarray = BCastTo< pfecarray >((*a)[0]);
2733         if (bpfer && asizea < 3) {
2734           l[i].what = asizea;
2735           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfer >((*a)[j]);
2736         } else if (bpfec && asizea < 3) {
2737           l[i].what = 10 + asizea;
2738           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfec >((*a)[j]);
2739         } else if (bptab && asizea >= 2 && asizea <= 4)    // change nov 2016 FH  for color corve
2740         {
2741           l[i].what = 3;
2742           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< tab >((*a)[j]);
2743         } else if (bpttab && asizea >= 2 &&
2744                    asizea <= 4)    // change nov 2016 FH  for  arry of curve
2745         {
2746           l[i].what = 103;
2747           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pttab >((*a)[j]);
2748         } else if (asizea == 3 && bpf3r)    // 3d vector ...
2749         {
2750           l[i].what = 7;    // new 3d vector
2751           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pf3r >((*a)[j]);
2752 
2753         } else if (asizea == 3 && bpf3c)    // 3d vector ...
2754         {
2755           l[i].what = 17;    // new 3d vector
2756           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pf3c >((*a)[j]);
2757 
2758         } else if (asizea == 3 && bpfSr)    // 3D vector for surface...
2759         {
2760           l[i].what = 9;    // new 3d vector
2761           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfSr >((*a)[j]);
2762 
2763         } else if (asizea == 3 && bpfSc)    // 3D vector for surface...
2764         {
2765           l[i].what = 19;    // new 3d vector
2766           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfSc >((*a)[j]);
2767 
2768         } else if (asizea == 3 && bpfLr)    // 3D vector for curve...
2769         {
2770           l[i].what = 15;    // new 3d vector
2771           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfLr >((*a)[j]);
2772 
2773         } else if (asizea == 3 && bpfLc)    // 3D vector for curve...
2774         {
2775           l[i].what = 21;    // new 3d vector
2776           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfLc >((*a)[j]);
2777 
2778         } else if (bpferarray && asizea == 2) {
2779           l[i].what = 102;
2780           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pferarray >((*a)[j]);
2781         } else if (bpfecarray && asizea == 2) {
2782           l[i].what = 112;
2783           for (int j = 0; j < a->size( ); j++) l[i][j] = CastTo< pfecarray >((*a)[j]);
2784         } else {
2785           CompileError("plot of array with wrong  number of components (!= 2 or 3) ");
2786         }
2787       } else if (BCastTo< pferbase >(
2788                    args[i])) {    // [[file:problem.hpp::pferbase]] [[file:lgmesh3.hpp::BCastTo]]
2789         l[i].what = 1;            //  iso value 2d
2790         l[i].composant = true;
2791         l[i][0] = CastTo< pferbase >(args[i]);
2792       } else if (BCastTo< pfer >(args[i])) {    // [[file:problem.hpp::pfer]]
2793         l[i].composant = false;
2794         l[i].what = 1;    //  iso value 2d
2795         l[i][0] = CastTo< pfer >(args[i]);
2796       } else if (BCastTo< pfecbase >(args[i])) {    // [[file:problem.hpp::pfecbase]]
2797         l[i].what = 11;                             //  iso value 2d
2798         l[i].composant = true;
2799         l[i][0] = CastTo< pfecbase >(args[i]);
2800       } else if (BCastTo< pfec >(args[i])) {    // [[file:problem.hpp::pfec]]
2801         l[i].composant = false;
2802         l[i].what = 11;    //  iso value 2d
2803         l[i][0] = CastTo< pfec >(args[i]);
2804       }
2805 
2806       else if (BCastTo< pf3r >(args[i])) {    // [[file:lgmesh3.hpp::pf3r]]
2807         l[i].composant = false;
2808         l[i].what = 6;    //  real iso value 3D volume
2809         l[i][0] = CastTo< pf3r >(args[i]);
2810       } else if (BCastTo< pf3c >(args[i])) {    // [[file:lgmesh3.hpp::pf3c]]
2811         l[i].composant = false;
2812         l[i].what = 16;    //  complex iso value 3D volume
2813         l[i][0] = CastTo< pf3c >(args[i]);
2814       }
2815 
2816       else if (BCastTo< pfSr >(args[i])) {    // [[file:lgmesh3.hpp::pfSr]]
2817         l[i].composant = false;
2818         l[i].what = 8;    //  real iso value 3D surface
2819         l[i][0] = CastTo< pfSr >(args[i]);
2820       } else if (BCastTo< pfSc >(args[i])) {    // [[file:lgmesh3.hpp::pfSc]]
2821         l[i].composant = false;
2822         l[i].what = 18;    // complex iso value 3D surface
2823         l[i][0] = CastTo< pfSc >(args[i]);
2824       } else if (BCastTo< pfLr >(args[i])) {    // [[file:lgmesh3.hpp::pfSr]]
2825         l[i].composant = false;
2826         l[i].what = 14;    //  real iso value 3D curve
2827         l[i][0] = CastTo< pfLr >(args[i]);
2828       } else if (BCastTo< pfLc >(args[i])) {    // [[file:lgmesh3.hpp::pfSc]]
2829         l[i].composant = false;
2830         l[i].what = 20;    // complex iso value 3D curve
2831         l[i][0] = CastTo< pfLc >(args[i]);
2832       }
2833 
2834       else if (BCastTo< pferarray >(args[i])) {
2835         l[i].composant = false;
2836         l[i].what = 101;    //  iso value array iso value 2d
2837         l[i][0] = CastTo< pferarray >(args[i]);
2838       } else if (BCastTo< pfecarray >(args[i])) {
2839         l[i].composant = false;
2840         l[i].what = 111;    //  iso value array iso value 2d
2841         l[i][0] = CastTo< pfecarray >(args[i]);
2842       }
2843 
2844       else if (BCastTo< pf3rarray >(args[i])) {    // [[file:lgmesh3.hpp::pf3rarray]]
2845         l[i].composant = false;
2846         l[i].what = 106;    // iso value array iso value 3d
2847         l[i][0] = CastTo< pf3rarray >(args[i]);
2848       } else if (BCastTo< pf3carray >(args[i])) {    // [[file:lgmesh3.hpp::pf3carray]]
2849         l[i].composant = false;
2850         l[i].what = 116;    // iso value array iso value 3d
2851         l[i][0] = CastTo< pf3carray >(args[i]);
2852       }
2853 
2854       else if (BCastTo< pfSrarray >(args[i])) {    // [[file:lgmesh3.hpp::pfSrarray]]
2855         l[i].composant = false;
2856         l[i].what = 108;    // arry iso value array iso value 3d
2857         l[i][0] = CastTo< pfSrarray >(args[i]);
2858       } else if (BCastTo< pfScarray >(args[i])) {    // [[file:lgmesh3.hpp::pfScarray]]
2859         l[i].composant = false;
2860         l[i].what = 118;    // arry iso value array iso value 3d
2861         l[i][0] = CastTo< pfScarray >(args[i]);
2862       } else if (BCastTo< pfLrarray >(args[i])) {    // [[file:lgmesh3.hpp::pfSrarray]]
2863         l[i].composant = false;
2864         l[i].what = 114;    // arry iso value array iso value 3d
2865         l[i][0] = CastTo< pfLrarray >(args[i]);
2866       } else if (BCastTo< pfLcarray >(args[i])) {    // [[file:lgmesh3.hpp::pfScarray]]
2867         l[i].composant = false;
2868         l[i].what = 120;    // arry iso value array iso value 3d
2869         l[i][0] = CastTo< pfLcarray >(args[i]);
2870       } else if (BCastTo< pmesh >(args[i])) {
2871         l[i].composant = true;
2872         l[i].what = 0;    // mesh ...
2873         l[i][0] = CastTo< pmesh >(args[i]);
2874       } else if (BCastTo< pmesh3 >(args[i])) {
2875         l[i].composant = true;
2876         l[i].what = 5;    // 3d mesh (real volume or if contains a meshS pointer...
2877         l[i][0] = CastTo< pmesh3 >(args[i]);
2878       } else if (BCastTo< pmeshS >(args[i])) {
2879         l[i].composant = true;
2880         l[i].what = 50;    // 3d surface mesh
2881         l[i][0] = CastTo< pmeshS >(args[i]);
2882       } else if (BCastTo< pmeshL >(args[i])) {
2883         l[i].composant = true;
2884         l[i].what = 55;    // 3d line mesh
2885         l[i][0] = CastTo< pmeshL >(args[i]);
2886       } else if (BCastTo< const E_BorderN * >(args[i])) {
2887         l[i].what = 4;    // border 2d / 3d
2888         l[i].composant = true;
2889         l[i][0] = CastTo< const E_BorderN * >(args[i]);
2890       } else if (BCastTo< KN< pmesh > * >(args[i])) {
2891         l[i].composant = true;
2892         l[i].what = 100;    //  mesh 2d array
2893         l[i][0] = CastTo< KN< pmesh > * >(args[i]);
2894       }
2895 
2896       else {
2897         CompileError("Sorry no way to plot this kind of data");
2898       }
2899 
2900   }
2901 
typeargs()2902   static ArrayOfaType typeargs( ) { return ArrayOfaType(true); }    // all type
2903 
2904   /// <<Plot_f>> Creates a Plot object with the list of arguments obtained from the script during
2905   /// the grammatical analysis of the script (in lg.ypp)
2906 
f(const basicAC_F0 & args)2907   static E_F0 *f(const basicAC_F0 &args) {
2908     ;
2909     return new Plot(args);
2910   }
2911 
2912   /// Evaluates the contents of the Plot object during script evaluation. Implemented at
2913   /// [[Plot_operator_brackets]]
2914 
2915   AnyType operator( )(Stack s) const;
2916 };
2917 
2918 /// <<Plot_name_param>>
2919 
2920 basicAC_F0::name_and_type Plot::name_param[Plot::n_name_param] = {
2921   {"coef", &typeid(double)},
2922   {"cmm", &typeid(string *)},
2923   {"ps", &typeid(string *)},
2924   {"wait", &typeid(bool)},
2925   {"fill", &typeid(bool)},
2926   {"value", &typeid(bool)},
2927   {"clean", &typeid(bool)},
2928   {"aspectratio", &typeid(bool)},
2929   {"bb", &typeid(E_Array)},
2930   {"nbiso", &typeid(long)},
2931   {"nbarrow", &typeid(long)},
2932   {"viso", &typeid(KN_< double >)},
2933   {"varrow", &typeid(KN_< double >)},
2934   {"bw", &typeid(bool)},
2935   {"grey", &typeid(bool)},
2936   {"hsv", &typeid(KN_< double >)},
2937   {"boundary", &typeid(bool)},    // 16
2938   {"dim", &typeid(long)},         // 2 or 3
2939   {"add", &typeid(bool)},         // add to previous plot
2940   {"prev", &typeid(bool)},        // keep previou  view point
2941   {"ech", &typeid(double)},       // keep previou  view point
2942 
2943   // FFCS: more options for VTK graphics (numbers are required for processing)
2944 
2945   {"ZScale", &typeid(double)},                        // 21
2946   {"WhiteBackground", &typeid(bool)},                 // #2
2947   {"OpaqueBorders", &typeid(bool)},                   // #3
2948   {"BorderAsMesh", &typeid(bool)},                    // #4
2949   {"ShowMeshes", &typeid(bool)},                      // #5
2950   {"ColorScheme", &typeid(long)},                     // #6
2951   {"ArrowShape", &typeid(long)},                      // #7
2952   {"ArrowSize", &typeid(double)},                     // #8
2953   {"ComplexDisplay", &typeid(long)},                  // #9
2954   {"LabelColors", &typeid(bool)},                     // #10
2955   {"ShowAxes", &typeid(bool)},                        // #11
2956   {"CutPlane", &typeid(bool)},                        // #12
2957   {"CameraPosition", &typeid(KN_< double >)},         // #13
2958   {"CameraFocalPoint", &typeid(KN_< double >)},       // #14
2959   {"CameraViewUp", &typeid(KN_< double >)},           // #15
2960   {"CameraViewAngle", &typeid(double)},               // #16
2961   {"CameraClippingRange", &typeid(KN_< double >)},    // #17
2962   {"CutPlaneOrigin", &typeid(KN_< double >)},         // #18
2963   {"CutPlaneNormal", &typeid(KN_< double >)},         // #19
2964   {"WindowIndex", &typeid(long)},                     // #20
2965   {"NbColorTicks", &typeid(long)},                    // #21
2966   {"NbColors", &typeid(long)},                        // #22
2967   {"pNormalT", &typeid(bool)}                         //43
2968 };
2969 
2970 template< class K >
2971 class pb2mat : public E_F0 {
2972  public:
2973   typedef Matrice_Creuse< K > *Result;
2974   const Problem *pb;
pb2mat(const basicAC_F0 & args)2975   pb2mat(const basicAC_F0 &args) : pb(dynamic_cast< const Problem * >(args[0].left( ))) {
2976     ffassert(pb);
2977   }
typeargs()2978   static ArrayOfaType typeargs( ) { return ArrayOfaType(atype< const Problem * >( )); }
2979 
f(const basicAC_F0 & args)2980   static E_F0 *f(const basicAC_F0 &args) { return new Plot(args); }
2981 
operator ( )(Stack s) const2982   AnyType operator( )(Stack s) const {
2983     Problem::Data< FESpace > *data = pb->dataptr(this->stack);
2984     if (SameType< K, double >::OK) {
2985       ffassert(!!data->AR);
2986       return SetAny< Matrice_Creuse< K > * >(&data->AR);
2987     } else {
2988       ffassert(!!data->AC);
2989       return SetAny< Matrice_Creuse< K > * >(&data->AC);
2990     }
2991   }
2992 };
2993 
LinkToInterpreter()2994 LinkToInterpreter::LinkToInterpreter( ) {
2995   // P,N,x,y,z,label,region,nu_triangle;
2996   P = make_Type_Expr(atype< R3 * >( ), new E_P_Stack_P);
2997   x = make_Type_Expr(atype< R * >( ), new E_P_Stack_Px);
2998   y = make_Type_Expr(atype< R * >( ), new E_P_Stack_Py);
2999   z = make_Type_Expr(atype< R * >( ), new E_P_Stack_Pz);
3000   N = make_Type_Expr(atype< R3 * >( ), new E_P_Stack_N);
3001   Nt = make_Type_Expr(atype< R3 * >( ), new E_P_Stack_Nt);
3002   region = make_Type_Expr(new E_P_Stack_Region, atype< long * >( ));
3003   label = make_Type_Expr(new E_P_Stack_Label, atype< long * >( ));
3004   nu_triangle = make_Type_Expr(atype< long >( ), new E_P_Stack_Nu_Triangle);
3005   nu_edge = make_Type_Expr(atype< long >( ), new E_P_Stack_Nu_Edge);
3006   nu_face = make_Type_Expr(atype< long >( ), new E_P_Stack_Nu_Face);
3007   lenEdge = make_Type_Expr(atype< R >( ), new E_P_Stack_lenEdge);
3008   hTriangle = make_Type_Expr(atype< R >( ), new E_P_Stack_hTriangle);
3009   area = make_Type_Expr(atype< R >( ), new E_P_Stack_areaTriangle);
3010   volume = make_Type_Expr(atype< R >( ), new E_P_Stack_VolumeTet);
3011   inside = make_Type_Expr(atype< R >( ), new E_P_Stack_inside);
3012   Global.New("x", x);
3013   Global.New("y", y);
3014   Global.New("z", z);
3015   Global.New("label", label);
3016   Global.New("region", region);
3017   Global.New("notaregion", CConstant< long >(lnotaregion));
3018   Global.New("nuTriangle", nu_triangle);
3019   Global.New("nuTet", nu_triangle);
3020   Global.New("nuEdge", nu_edge);
3021   Global.New("nuFace", nu_face);
3022   Global.New("P", P);
3023   Global.New("N", N);
3024   Global.New("Nt", Nt);
3025   Global.New("lenEdge", lenEdge);
3026   Global.New("area", area);
3027   Global.New("volume", volume);
3028   Global.New("hTriangle", hTriangle);
3029   Global.New("inside", inside);
3030   Global.New("nTonEdge", make_Type_Expr(atype< long >( ), new E_P_Stack_nTonEdge));
3031   Global.New("nElementonB", make_Type_Expr(atype< long >( ), new E_P_Stack_nElementonB));
3032   Global.New("edgeOrientation",
3033              make_Type_Expr(atype< R >( ), new E_P_Stack_EdgeOrient));    // Add FH jan 2018
3034   Global.New("BoundaryEdge",
3035              make_Type_Expr(atype< long >( ), new E_P_Stack_TypeEdge< 1 >));    // Add FH jan 2018
3036   Global.New("InternalEdge",
3037              make_Type_Expr(atype< long >( ), new E_P_Stack_TypeEdge< 2 >));    // Add FH jan 2018
3038 }
3039 
3040 template< class K >
3041 struct set_eqmatrice_creuse_fbl
3042   : public binary_function< Matrice_Creuse< K > *, const Matrice_Creuse< K > *, const C_args * > {
fset_eqmatrice_creuse_fbl3043   static Matrice_Creuse< K > *f(Matrice_Creuse< K > *const &a, const C_args *const &b) {
3044     // 1  verif the FESpace
3045 
3046     // 2 set = or +=
3047 
3048     ffassert(0);
3049     return a;
3050   }
3051 };
3052 
3053 template< class K >
3054 struct set_eqvect_fl : public binary_function< KN< K > *, const FormLinear *, KN< K > * > {
fset_eqvect_fl3055   static KN< K > *f(KN< K > *const &a, const FormLinear *const &b) {
3056     ffassert(0);
3057     return a;
3058   }
3059 };
3060 
3061 template< class R >
operator ( )(Stack stack) const3062 AnyType IntFunction< R >::operator( )(Stack stack) const {
3063   MeshPoint mp = *MeshPointStack(stack);
3064   StackOfPtr2Free *wsptr2free = WhereStackOfPtr2Free(stack);
3065   size_t swsptr2free = wsptr2free->size( );
3066   R r = 0;
3067 
3068   SHOWVERB(cout << " int " << endl);
3069   const vector< Expression > &what(di->what);
3070   const int dim = di->d;
3071   const bool surface = di->isMeshS;
3072   const bool curve = di->isMeshL;
3073   const GQuadratureFormular< R1 > &FIE = di->FIE(stack);
3074   const GQuadratureFormular< R2 > &FIT = di->FIT(stack);
3075   const GQuadratureFormular< R3 > &FIV = di->FIV(stack);
3076 
3077   CDomainOfIntegration::typeofkind kind = di->kind;
3078   set< int > setoflab;
3079   bool all = true;
3080   if (di->withmap( )) {
3081     ExecError(" no map  in the case (1)??");
3082   }
3083   if (verbosity > 3) {
3084     if (dim == 2) {
3085       if (CDomainOfIntegration::int1d == kind)
3086         cout << "  -- boundary int border ( nQP: " << FIE.n << ") levelset: " << di->islevelset( )
3087              << " ,";
3088       else if (CDomainOfIntegration::intalledges == kind)
3089         cout << "  -- boundary int all edges ( nQP: " << FIE.n << "),";
3090       else if (CDomainOfIntegration::intallVFedges == kind)
3091         cout << "  -- boundary int all VF edges nQP: (" << FIE.n << "),";
3092       else
3093         cout << "  --  int 2d   (nQP: " << FIT.n << " ) in ";
3094     } else if (dim == 3 && !surface && !curve) {
3095       if (CDomainOfIntegration::int2d == kind)
3096         cout << "  -- boundary int border ( nQP: " << FIT.n << ") ,";
3097       else if (CDomainOfIntegration::intalledges == kind)
3098         cout << "  -- boundary int all faces ( nQP: " << FIT.n << "),";
3099       else if (CDomainOfIntegration::intallVFedges == kind)
3100         cout << "  -- boundary int all VF face nQP: (" << FIT.n << "),";
3101       else
3102         cout << "  --  int 3d volume  (nQP: " << FIV.n << " ) in ";
3103     } else if (dim == 3 && surface && !curve) {
3104       if (CDomainOfIntegration::int1d == kind)
3105         cout << "  -- boundary int border ( nQP: " << FIE.n << ") levelset: " << di->islevelset( )
3106              << " ,";
3107       else if (CDomainOfIntegration::intalledges == kind)
3108         cout << "  -- boundary int all edges ( nQP: " << FIE.n << "),";
3109       else if (CDomainOfIntegration::intallVFedges == kind)
3110         cout << "  -- boundary int all VF edges nQP: (" << FIE.n << "),";
3111       else
3112         cout << "  --  int 3d surface  (nQP: " << FIT.n << " ) in ";
3113     } else if (dim == 3 && !surface && curve) {
3114       if (CDomainOfIntegration::int0d==kind)
3115         cout << "  -- boundary int border ( nQP: "<< FIE.n << ") levelset: "<< di->islevelset() << " ,"  ;
3116       else  cout << "  --  int 3d curve  (nQP: " << FIT.n << " ) in ";
3117     }
3118   }
3119 
3120   Expandsetoflab(stack, *di, setoflab, all);
3121 
3122   if (dim == 2) {
3123     if (di->islevelset( ) && (CDomainOfIntegration::int1d != kind) &&
3124         (CDomainOfIntegration::int2d != kind))
3125       InternalError("So no levelset integration type  case (10 2d)");
3126     const Mesh &Th = *GetAny< pmesh >((*di->Th)(stack));
3127     ffassert(&Th);
3128 
3129     if (verbosity > 3) {
3130       if (all)
3131         cout << " all " << endl;
3132       else
3133         cout << endl;
3134     }
3135     if (kind == CDomainOfIntegration::int1d) {
3136       const QuadratureFormular1d &FI = FIE;
3137       if (di->islevelset( )) {
3138         double llevelset = 0;
3139         double uset = HUGE_VAL;
3140         R2 Q[3];
3141         KN< double > phi(Th.nv);
3142         phi = uset;
3143         double f[3];
3144         for (int t = 0; t < Th.nt; ++t) {
3145           double umx = -HUGE_VAL, umn = HUGE_VAL;
3146           for (int i = 0; i < 3; ++i) {
3147             int j = Th(t, i);
3148             if (phi[j] == uset) {
3149               MeshPointStack(stack)->setP(&Th, t, i);
3150               phi[j] = di->levelset(stack);    // zzzz
3151             }
3152             f[i] = phi[j];
3153             umx = std::max(umx, phi[j]);
3154             umn = std::min(umn, phi[j]);
3155           }
3156           if (umn <= 0 && umx >= 0) {
3157             int np = IsoLineK(f, Q, 1e-10);
3158             if (np == 2) {
3159               const Triangle &K(Th[t]);
3160               R2 PA(K(Q[0])), PB(K(Q[1]));
3161               R2 NAB(PA, PB);
3162               double lAB = sqrt((NAB, NAB));
3163               NAB = NAB.perp( ) / lAB;
3164               llevelset += lAB;
3165               for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3166               {
3167                 QuadratureFormular1dPoint pi(FI[npi]);
3168                 double sa = pi.x, sb = 1. - sa;
3169                 R2 Pt(Q[0] * sa + Q[1] * sb);    //
3170                 MeshPointStack(stack)->set(Th, K(Pt), Pt, K, -1, NAB, -1);
3171                 r += lAB * pi.a * GetAny< R >((*fonc)(stack));
3172               }
3173             }
3174           }
3175           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3176         }
3177         if (verbosity > 5) cout << " Lenght level set = " << llevelset << endl;
3178 
3179       }
3180 
3181       else
3182         for (int e = 0; e < Th.neb; e++) {
3183           if (all || setoflab.find(Th.bedges[e].lab) != setoflab.end( )) {
3184             int ie, i = Th.BoundaryElement(e, ie);
3185             const Triangle &K(Th[i]);
3186             R2 E = K.Edge(ie);
3187             double le = sqrt((E, E));
3188             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
3189               PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
3190 
3191             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3192             {
3193               QuadratureFormular1dPoint pi(FI[npi]);
3194               double sa = pi.x, sb = 1. - sa;
3195               R2 Pt(PA * sa + PB * sb);    //
3196               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, Th.bedges[e].lab, R2(E.y, -E.x) / le,
3197                                          ie);
3198               r += le * pi.a * GetAny< R >((*fonc)(stack));
3199             }
3200           }
3201           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3202         }
3203     } else if (kind == CDomainOfIntegration::int2d) {
3204       const QuadratureFormular &FI = FIT;
3205 
3206       if (di->islevelset( )) {    // add FH mars 2014 compute int2d  on phi < 0 ..
3207         double llevelset = 0;
3208         double uset = HUGE_VAL;
3209         R2 Q[3];
3210         KN< double > phi(Th.nv);
3211         phi = uset;
3212         double f[3], umx, umn;
3213         for (int t = 0; t < Th.nt; ++t) {
3214           if (all || setoflab.find(Th[t].lab) != setoflab.end( )) {
3215             const Triangle &K(Th[t]);
3216 
3217             double umx = -HUGE_VAL, umn = HUGE_VAL;
3218             for (int i = 0; i < 3; ++i) {
3219               int j = Th(t, i);
3220               if (phi[j] == uset) {
3221                 MeshPointStack(stack)->setP(&Th, t, i);
3222                 phi[j] = di->levelset(stack);    // zzzz
3223               }
3224               f[i] = phi[j];
3225               umx = std::max(umx, phi[j]);
3226               umn = std::min(umn, phi[j]);
3227             }
3228             double area = K.area;
3229             if (umn >= 0) continue;    //  all positif => nothing
3230             if (umx > 0) {             // coupe ..
3231               int i0 = 0, i1 = 1, i2 = 2;
3232 
3233               if (f[i0] > f[i1]) swap(i0, i1);
3234               if (f[i0] > f[i2]) swap(i0, i2);
3235               if (f[i1] > f[i2]) swap(i1, i2);
3236 
3237               double c = (f[i2] - f[i1]) / (f[i2] - f[i0]);    // coef Up Traing
3238               if (f[i1] < 0) {
3239                 double y = f[i2] / (f[i2] - f[i1]);
3240                 c *= y * y;
3241               } else {
3242                 double y = f[i0] / (f[i0] - f[i1]);
3243                 c = 1. - (1. - c) * y * y;
3244               };
3245               assert(c > 0 && c < 1);
3246               area *= 1 - c;
3247             }
3248             //  warning  quadrature  wrong just ok for constante FH, we must also change the
3249             //  quadaturer points ..
3250             // just order 1  here ???
3251             for (int npi = 0; npi < FI.n; npi++) {
3252               QuadraturePoint pi(FI[npi]);
3253               MeshPointStack(stack)->set(Th, K(pi), pi, K, K.lab);
3254               r += area * pi.a * GetAny< R >((*fonc)(stack));
3255             }
3256           }
3257           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3258         }
3259 
3260       } else
3261         for (int i = 0; i < Th.nt; i++) {
3262           const Triangle &K(Th[i]);
3263           if (all || setoflab.find(Th[i].lab) != setoflab.end( ))
3264             for (int npi = 0; npi < FI.n; npi++) {
3265               QuadraturePoint pi(FI[npi]);
3266               MeshPointStack(stack)->set(Th, K(pi), pi, K, K.lab);
3267               r += K.area * pi.a * GetAny< R >((*fonc)(stack));
3268             }
3269           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3270         }
3271     } else if (kind == CDomainOfIntegration::intalledges) {
3272       const QuadratureFormular1d &FI = FIE;
3273       for (int i = 0; i < Th.nt; i++)
3274         if (all || setoflab.find(Th[i].lab) != setoflab.end( )) {
3275           for (int ie = 0; ie < 3; ie++) {
3276             const Triangle &K(Th[i]);
3277             int e0 = VerticesOfTriangularEdge[ie][0];
3278             int e1 = VerticesOfTriangularEdge[ie][1];
3279             int i1 = Th(K[e0]), i2 = Th(K[e1]);
3280             BoundaryEdge *be = Th.TheBoundaryEdge(i1, i2);
3281             int lab = be ? be->lab : notaregion;
3282             R2 E = K.Edge(ie);
3283             double le = sqrt((E, E));
3284             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
3285               PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
3286 
3287             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3288             {
3289               QuadratureFormular1dPoint pi(FI[npi]);
3290               double sa = pi.x, sb = 1 - sa;
3291               R2 Pt(PA * sa + PB * sb);    //
3292               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, lab, R2(E.y, -E.x) / le,
3293                                          ie);    // correction FH 6/2/2014
3294               r += le * pi.a * GetAny< R >((*fonc)(stack));
3295             }
3296           }
3297           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3298         }
3299     } else if (kind == CDomainOfIntegration::intallVFedges) {
3300       double untier(1. / 3.);
3301       cerr << " a faire CDomainOfIntegration::intallVFedges " << endl;    //%%%%%%%%%
3302       ffassert(0);
3303       const QuadratureFormular1d &FI = FIE;
3304       for (int i = 0; i < Th.nt; i++)
3305         if (all || setoflab.find(Th[i].lab) != setoflab.end( )) {
3306           const Triangle &K(Th[i]);
3307           const R2 GH(untier, untier);
3308           const R2 G = K(GH);
3309           for (int ie = 0; ie < 3; ie++) {
3310             int ie0 = VerticesOfTriangularEdge[ie][0];
3311             int ie1 = VerticesOfTriangularEdge[ie][1];
3312             const R2 MH = (TriangleHat[ie0] + TriangleHat[ie1]) * 0.5;
3313             const R2 M(K(MH));
3314             R2 E(G, M);
3315             double le = sqrt((E, E));
3316 
3317             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3318             {
3319               QuadratureFormular1dPoint pi(FI[npi]);
3320               double sa = pi.x, sb = 1 - sa;
3321               R2 Pt(GH * sa + MH * sb);    //
3322               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, Th[ie].lab, R2(E.y, -E.x) / le, ie, 1);
3323               r += le * pi.a * GetAny< R >((*fonc)(stack));
3324             }
3325           }
3326           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3327         }
3328     } else {
3329       InternalError("CDomainOfIntegration kind unkown");
3330     }
3331   }
3332 
3333   // volume 3d
3334   else if (dim == 3 && !surface && !curve) {
3335     if (di->islevelset( ) && (CDomainOfIntegration::int2d != kind) &&
3336         (CDomainOfIntegration::int3d != kind))
3337       InternalError("So no levelset integration type on no int2d / int3d case (10 3d)");
3338 
3339     const Mesh3 &Th = *GetAny< pmesh3 >((*di->Th)(stack));
3340     ffassert(&Th);
3341 
3342     if (verbosity > 3) {
3343       if (all)
3344         cout << " all " << endl;
3345       else
3346         cout << endl;
3347     }
3348     if (kind == CDomainOfIntegration::int2d)
3349       if (di->islevelset( )) {
3350         const GQuadratureFormular< R2 > &FI = FIT;
3351         double llevelset = 0;
3352         const double uset = std::numeric_limits< double >::max( );
3353         R3 Q[4];
3354         KN< double > phi(Th.nv);
3355         phi = uset;
3356         double f[4];
3357 
3358         for (int t = 0; t < Th.nt; ++t) {
3359           double umx = std::numeric_limits< double >::min( ),
3360                  umn = std::numeric_limits< double >::max( );
3361           for (int i = 0; i < 4; ++i) {
3362             int j = Th(t, i);
3363             if (phi[j] == uset) {
3364               MeshPointStack(stack)->setP(&Th, t, i);
3365               phi[j] = di->levelset(stack);    // zzzz
3366             }
3367             f[i] = phi[j];
3368             umx = std::max(umx, f[i]);
3369             umn = std::min(umn, f[i]);
3370           }
3371           if (umn <= 0 && umx >= 0) {
3372             int np = IsoLineK(f, Q, 1e-10);
3373 
3374             double l[3];
3375             if (np > 2) {
3376               if (verbosity > 999)
3377                 cout << t << " int levelset : " << umn << " .. " << umx << " np " << np << " "
3378                      << f[0] << " " << f[1] << " " << f[2] << " " << f[3] << " " << endl;
3379 
3380               const Mesh3::Element &K(Th[t]);
3381               double epsmes3 = K.mesure( ) * K.mesure( ) * 1e-18;
3382               R3 PP[4];
3383               for (int i = 0; i < np; ++i) PP[i] = K(Q[i]);
3384               for (int i = 0; i + 1 < np; i += 2) {    // 0,1,, a and 2,3,0.
3385                 int i0 = i, i1 = i + 1, i2 = (i + 2) % np;
3386                 R3 NN = R3(PP[i0], PP[i1]) ^ R3(PP[i0], PP[i2]);
3387                 double mes2 = (NN, NN);
3388                 double mes = sqrt(mes2);
3389                 if (mes2 * mes < epsmes3) continue;    //  too small
3390                 NN /= mes;
3391                 mes *= 0.5;    //   warning correct FH 050109
3392                 llevelset += mes;
3393                 for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3394                 {
3395                   GQuadraturePoint< R2 > pi(FI[npi]);
3396                   pi.toBary(l);
3397                   R3 Pt(l[0] * Q[i0] + l[1] * Q[i1] + l[2] * Q[i2]);    //
3398                   MeshPointStack(stack)->set(Th, K(Pt), Pt, K, -1, NN, -1);
3399                   r += mes * pi.a * GetAny< R >((*fonc)(stack));
3400                 }
3401               }
3402             }
3403           }
3404           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3405         }
3406         if (verbosity > 5) cout << " Area level set = " << llevelset << endl;
3407 
3408       }
3409 
3410       else
3411 
3412       {
3413         const GQuadratureFormular< R2 > &FI = FIT;
3414         int lab;
3415         for (int e = 0; e < Th.nbe; e++) {
3416           if (all || setoflab.find(lab = Th.be(e).lab) != setoflab.end( )) {
3417             int ie, i = Th.BoundaryElement(e, ie);
3418             const Mesh3::Element &K(Th[i]);
3419             R3 NN = K.N(ie);
3420             double mes = sqrt((NN, NN));
3421             NN /= mes;
3422             mes *= 0.5;                             //   warning correct FH 050109
3423             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3424             {
3425               GQuadraturePoint< R2 > pi(FI[npi]);
3426               R3 Pt(K.PBord(ie, pi));    //
3427               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, lab, NN, ie);
3428               r += mes * pi.a * GetAny< R >((*fonc)(stack));
3429             }
3430             wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3431           }
3432         }
3433       }
3434     else if (kind == CDomainOfIntegration::int3d) {
3435       if (di->islevelset( )) {
3436         GQuadratureFormular< R3 > FI(FIV.n * 3);
3437         double llevelset = 0;
3438         const double uset = std::numeric_limits< double >::max( );
3439         R3 Q[3][4];
3440         double vol6[3];
3441         KN< double > phi(Th.nv);
3442         phi = uset;
3443         double f[4];
3444 
3445         for (int t = 0; t < Th.nt; t++) {
3446           const Mesh3::Element &K(Th[t]);
3447           if (all || setoflab.find(K.lab) != setoflab.end( )) {
3448             double umx = std::numeric_limits< double >::min( ),
3449                    umn = std::numeric_limits< double >::max( );
3450             for (int i = 0; i < 4; ++i) {
3451               int j = Th(t, i);
3452               if (phi[j] == uset) {
3453                 MeshPointStack(stack)->setP(&Th, t, i);
3454                 phi[j] = di->levelset(stack);    // zzzz
3455               }
3456               f[i] = phi[j];
3457             }
3458             int ntets = UnderIso(f, Q, vol6, 1e-14);
3459             setQF< R3 >(FI, FIV, QuadratureFormular_Tet_1, Q, vol6, ntets);
3460             for (int npi = 0; npi < FI.n; npi++) {
3461               GQuadraturePoint< R3 > pi(FI[npi]);
3462               MeshPointStack(stack)->set(Th, K(pi), pi, K, K.lab);
3463               r += K.mesure( ) * pi.a * GetAny< R >((*fonc)(stack));
3464             }
3465           }
3466           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3467         }
3468 
3469       } else {
3470         const GQuadratureFormular< R3 > &FI = FIV;
3471         for (int i = 0; i < Th.nt; i++) {
3472           const Mesh3::Element &K(Th[i]);
3473           if (all || setoflab.find(K.lab) != setoflab.end( ))
3474             for (int npi = 0; npi < FI.n; npi++) {
3475               GQuadraturePoint< R3 > pi(FI[npi]);
3476               MeshPointStack(stack)->set(Th, K(pi), pi, K, K.lab);
3477               r += K.mesure( ) * pi.a * GetAny< R >((*fonc)(stack));
3478             }
3479           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3480         }
3481       }
3482     } else if (kind == CDomainOfIntegration::intalledges) {
3483       const GQuadratureFormular< R2 > &FI = FIT;
3484       int lab;
3485       for (int i = 0; i < Th.nt; i++)
3486         if (all || setoflab.find(Th[i].lab) != setoflab.end( ))
3487           for (int ie = 0; ie < 4; ie++)    // Coorection mai 2018 FH ???????????????? never tested
3488           {
3489             const Mesh3::Element &K(Th[i]);
3490             R3 NN = K.N(ie);
3491             double mes = NN.norme( );
3492             NN /= mes;
3493             mes *= 0.5;
3494 
3495             //  correction 05/01/09 FH
3496             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3497             {
3498               GQuadraturePoint< R2 > pi(FI[npi]);
3499               R3 Pt(K.PBord(ie, pi));    //
3500               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, lab, NN, ie);
3501               r += mes * pi.a * GetAny< R >((*fonc)(stack));
3502             }
3503           }
3504       wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3505     }
3506 
3507   }
3508 
3509   else if (dim == 3 && surface && !curve) {
3510     if (di->islevelset( ) && (CDomainOfIntegration::int1d != kind) &&
3511         (CDomainOfIntegration::int2d != kind))
3512       InternalError("So no levelset integration type  case (10 3d)");
3513     const MeshS &Th = *GetAny< pmeshS >((*di->Th)(stack));
3514     ffassert(&Th);
3515 
3516     if (verbosity > 3) {
3517       if (all)
3518         cout << " all " << endl;
3519       else
3520         cout << endl;
3521     }
3522     if (kind == CDomainOfIntegration::int1d) {
3523       const QuadratureFormular1d &FI = FIE;
3524       if (di->islevelset( )) {
3525         double llevelset = 0;
3526         double uset = HUGE_VAL;
3527         R2 Q[3];
3528         KN< double > phi(Th.nv);
3529         phi = uset;
3530         double f[3];
3531         for (int t = 0; t < Th.nt; ++t) {
3532           double umx = -HUGE_VAL, umn = HUGE_VAL;
3533           for (int i = 0; i < 3; ++i) {
3534             int j = Th(t, i);
3535             if (phi[j] == uset) {
3536               MeshPointStack(stack)->setP(&Th, t, i);
3537               phi[j] = di->levelset(stack);
3538             }
3539             f[i] = phi[j];
3540             umx = std::max(umx, phi[j]);
3541             umn = std::min(umn, phi[j]);
3542           }
3543           if (umn <= 0 && umx >= 0) {
3544             int np = IsoLineK(f, Q, 1e-10);
3545             if (np == 2) {
3546               const TriangleS &K(Th[t]);
3547               double epsmes3 = K.mesure( ) * K.mesure( ) * 1e-18;
3548               R3 PA(K(Q[0])), PB(K(Q[1])), PC(K(Q[2]));
3549               R3 NN = R3(PB, PA) ^ R3(PC, PA);    // R3 NAB(PA,PB);
3550 
3551               double mes2 = (NN, NN);
3552               double mes = sqrt(mes2);
3553 
3554               if (mes2 * mes < epsmes3) continue;    //  too small
3555               NN /= mes;
3556               llevelset += mes;
3557               R3 NNt=K.NFrenetUnitaire();
3558               for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3559               {
3560                 QuadratureFormular1dPoint pi(FI[npi]);
3561                 double sa = pi.x, sb = 1. - sa;
3562                 R2 Pt(Q[0] * sa + Q[1] * sb);    //
3563                 MeshPointStack(stack)->set(Th, K(Pt), Pt, K, -1, NN, NNt, -1);
3564                 r += mes * pi.a * GetAny< R >((*fonc)(stack));
3565               }
3566             }
3567           }
3568           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3569         }
3570         if (verbosity > 5) cout << " Lenght level set = " << llevelset << endl;
3571 
3572       }
3573 
3574       else
3575         for (int e = 0; e < Th.nbe; e++) {
3576           if (all || setoflab.find(Th.be(e).lab) != setoflab.end( )) {
3577             int ie, i = Th.BoundaryElement(e, ie);
3578             const TriangleS &K(Th[i]);
3579             R3 E = K.Edge(ie);
3580             double le = sqrt((E, E));
3581             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
3582               PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
3583 
3584             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3585             {
3586               QuadratureFormular1dPoint pi(FI[npi]);
3587               double sa = pi.x, sb = 1. - sa;
3588               R2 Pt(PA * sa + PB * sb);    //
3589               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, Th.be(e).lab, R2(E.y, -E.x) / le, ie);
3590               r += le * pi.a * GetAny< R >((*fonc)(stack));
3591             }
3592           }
3593           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3594         }
3595     } else if (kind == CDomainOfIntegration::int2d) {
3596       const QuadratureFormular &FI = FIT;
3597 
3598       if (di->islevelset( )) {    // add FH mars 2014 compute int2d  on phi < 0 ..
3599         double llevelset = 0;
3600         double uset = HUGE_VAL;
3601         R2 Q[3];
3602         KN< double > phi(Th.nv);
3603         phi = uset;
3604         double f[3], umx, umn;
3605         for (int t = 0; t < Th.nt; ++t) {
3606           if (all || setoflab.find(Th[t].lab) != setoflab.end( )) {
3607             const TriangleS &K(Th[t]);
3608             R3 NNt=K.NFrenet();
3609             NNt/=NNt.norme();
3610             double umx = -HUGE_VAL, umn = HUGE_VAL;
3611             for (int i = 0; i < 3; ++i) {
3612               int j = Th(t, i);
3613               if (phi[j] == uset) {
3614                 MeshPointStack(stack)->setP(&Th, t, i);
3615                 phi[j] = di->levelset(stack);
3616               }
3617               f[i] = phi[j];
3618               umx = std::max(umx, phi[j]);
3619               umn = std::min(umn, phi[j]);
3620             }
3621             double area = K.mesure( );
3622             if (umn >= 0) continue;    //  all positif => nothing
3623             if (umx > 0) {             // coupe ..
3624               int i0 = 0, i1 = 1, i2 = 2;
3625 
3626               if (f[i0] > f[i1]) swap(i0, i1);
3627               if (f[i0] > f[i2]) swap(i0, i2);
3628               if (f[i1] > f[i2]) swap(i1, i2);
3629 
3630               double c = (f[i2] - f[i1]) / (f[i2] - f[i0]);    // coef Up Traing
3631               if (f[i1] < 0) {
3632                 double y = f[i2] / (f[i2] - f[i1]);
3633                 c *= y * y;
3634               } else {
3635                 double y = f[i0] / (f[i0] - f[i1]);
3636                 c = 1. - (1. - c) * y * y;
3637               };
3638               assert(c > 0 && c < 1);
3639               area *= 1 - c;
3640             }
3641             //  warning  quadrature  wrong just ok for constante FH, we must also change the
3642             //  quadaturer points ..
3643             // just order 1  here ???
3644             for (int npi = 0; npi < FI.n; npi++) {
3645               QuadraturePoint pi(FI[npi]);
3646               MeshPointStack(stack)->set(Th, K(pi), pi, K, NNt, K.lab);
3647               r += area * pi.a * GetAny< R >((*fonc)(stack));
3648             }
3649           }
3650           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3651         }
3652 
3653       } else
3654         for (int i = 0; i < Th.nt; i++) {
3655           const TriangleS &K(Th[i]);
3656           R3 NNt=K.NFrenetUnitaire();
3657           if (all || setoflab.find(Th[i].lab) != setoflab.end( ))
3658             for (int npi = 0; npi < FI.n; npi++) {
3659               QuadraturePoint pi(FI[npi]);
3660               MeshPointStack(stack)->set(Th, K(pi), pi, K, NNt, K.lab);
3661               r += K.mesure( ) * pi.a * GetAny< R >((*fonc)(stack));
3662             }
3663           wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3664         }
3665     } else if (kind == CDomainOfIntegration::intalledges) {
3666       const QuadratureFormular1d &FI = FIE;
3667       int lab;
3668       for (int i = 0; i < Th.nt; i++)
3669         if (all || setoflab.find(Th[i].lab) != setoflab.end( ))
3670           for (int ie = 0; ie < 3; ie++) {
3671             const MeshS::Element &K(Th[i]);
3672             R3 NN = K.N(ie);
3673             double mes = NN.norme( );
3674             NN /= mes;
3675             for (int npi = 0; npi < FI.n; npi++)    // loop on the integration point
3676             {
3677               QuadratureFormular1dPoint pi(FI[npi]);
3678               R2 Pt(K.PBord(ie, pi));    // cout
3679               MeshPointStack(stack)->set(Th, K(Pt), Pt, K, lab, NN, ie);
3680               r += mes * pi.a * GetAny< R >((*fonc)(stack));
3681             }
3682           }
3683       wsptr2free->clean(swsptr2free);    // ADD FH 11/2017
3684     } else if (kind == CDomainOfIntegration::intallVFedges) {
3685       ffassert(0);    // TODO AXEL
3686     } else {
3687       InternalError("CDomainOfIntegration kind unkown");
3688     }
3689   } else if (dim == 3 && !surface && curve)
3690   {
3691 
3692     if(di->islevelset() && (CDomainOfIntegration::int1d!=kind) &&
3693     (CDomainOfIntegration::int2d!=kind) )
3694          InternalError("So no levelset integration type  case (103d)");
3695     const MeshL  & Th = * GetAny<pmeshL>( (*di->Th)(stack) );
3696     ffassert(&Th);
3697 
3698     if (verbosity >3)
3699     {
3700         if (all) cout << " all " << endl ;
3701         else cout << endl;
3702     }
3703     if (kind==CDomainOfIntegration::int1d)
3704     {
3705         const QuadratureFormular1d & FI = FIE;
3706         if(di->islevelset())
3707         {
3708             ffassert(0); // Do do !!!
3709 
3710         }
3711 
3712         else
3713             for( int k=0;k<Th.nt;k++)
3714             {
3715                 if (all || setoflab.find(Th[k].lab) != setoflab.end())
3716                 {
3717                     const EdgeL & K(Th[k]);
3718                     double le = K.mesure();
3719 
3720                     for (int npi=0;npi<FI.n;npi++) // loop on the integration point
3721                     {
3722                         QuadratureFormular1dPoint pi( FI[npi]);
3723                         R1 Ph(pi.x); //,sb=1.-sa;
3724                         R3 Pt(K(Ph)); //
3725                         // void set(const  MeshL &aTh, const R3 &P2,const R1 & P_Hat,const EdgeL & aK,const int ll=notalabel,bool coutside=false)
3726                         MeshPointStack(stack)->set(Th,Pt,Ph,K,notalabel);
3727                         r += le*pi.a*GetAny<R>( (*fonc)(stack));
3728                     }
3729                 }
3730                 wsptr2free->clean(swsptr2free);// ADD FH 11/2017
3731             }
3732     }
3733     else
3734     {
3735         InternalError("int Curve CDomainOfIntegration kind unkown");
3736     }
3737 
3738 
3739   } else {
3740     InternalError("CDomainOfIntegration dim unkown");
3741   }
3742 
3743   *MeshPointStack(stack) = mp;
3744   return SetAny< R >(r);
3745 }
3746 
Show(const char * s,int k=1)3747 void Show(const char *s, int k = 1) {
3748   if (k) {
3749     couleur(1);
3750     float xmin, xmax, ymin, ymax;
3751     getcadre(xmin, xmax, ymin, ymax);
3752     rmoveto(xmin + (xmax - xmin) / 100, ymax - (k) * (ymax - ymin) / 30);
3753     plotstring(s);
3754   }
3755 }
3756 template< class K, class v_fes >
Send2d(PlotStream & theplot,Plot::ListWhat & lli,map<const typename v_fes::FESpace::Mesh *,long> & mapth)3757 int Send2d(PlotStream &theplot, Plot::ListWhat &lli,
3758            map< const typename v_fes::FESpace::Mesh *, long > &mapth) {
3759   typedef FEbase< K, v_fes > *pfek;
3760   pfek fe[3] = {0, 0, 0};
3761   int cmp[3] = {-1, -1, -1};
3762   int err = 1;
3763   long what = lli.what;
3764   int lg, nsb;
3765   lli.eval(fe, cmp);
3766   if (fe[0]->x( ) && what % 10 == 1) {
3767     err = 0;
3768     theplot << what;
3769     theplot << mapth[&(fe[0]->Vh->Th)];    // numero du maillage
3770 
3771     KN< K > V1 = fe[0]->Vh->newSaveDraw(*fe[0]->x( ), cmp[0], lg, nsb);
3772 
3773     // construction of the sub division ...
3774     int nsubT = NbOfSubTriangle(nsb);
3775     int nsubV = NbOfSubInternalVertices(nsb);
3776     KN< R2 > Psub(nsubV);
3777     KN< int > Ksub(nsubT * 3);
3778     for (int i = 0; i < nsubV; ++i) Psub[i] = SubInternalVertex(nsb, i);
3779     for (int sk = 0, p = 0; sk < nsubT; ++sk)
3780       for (int i = 0; i < 3; ++i, ++p) Ksub[p] = numSubTriangle(nsb, sk, i);
3781 
3782     if (verbosity > 9)
3783       cout << " Send plot:what: " << what << " " << nsb << " " << V1.N( ) << " Max " << V1.max( )
3784            << " min " << V1.min( ) << endl;
3785     theplot << Psub;
3786     theplot << Ksub;
3787     theplot << V1;
3788 
3789   } else if (fe[0]->x( ) && fe[1]->x( ) && what % 10 == 2) {
3790     {
3791       err = 0;
3792       theplot << what;
3793 
3794       KN< K > V1 = fe[0]->Vh->newSaveDraw(*fe[0]->x( ), *fe[1]->x( ), cmp[0], cmp[1], lg, nsb);
3795       // construction of the sub division ...
3796       int nsubT = NbOfSubTriangle(nsb);
3797       int nsubV = NbOfSubInternalVertices(nsb);
3798       KN< R2 > Psub(nsubV);
3799       KN< int > Ksub(nsubT * 3);
3800       for (int i = 0; i < nsubV; ++i) Psub[i] = SubInternalVertex(nsb, i);
3801       for (int sk = 0, p = 0; sk < nsubT; ++sk)
3802         for (int i = 0; i < 3; ++i, ++p) Ksub[p] = numSubTriangle(nsb, sk, i);
3803 
3804       theplot << mapth[&(fe[0]->Vh->Th)];    // numero du maillage
3805       theplot << Psub;
3806       theplot << Ksub;
3807       theplot << V1;
3808     }
3809   }
3810   return err;
3811 }
3812 
3813 template< class K, class v_fes >
Send3d(PlotStream & theplot,Plot::ListWhat & lli,map<const typename v_fes::FESpace::Mesh *,long> & mapth3)3814 int Send3d(PlotStream &theplot, Plot::ListWhat &lli,
3815            map< const typename v_fes::FESpace::Mesh *, long > &mapth3) {
3816   typedef FEbase< K, v_fes > *pfek3;
3817   pfek3 fe3[3] = {0, 0, 0};
3818   int cmp[3] = {-1, -1, -1};
3819   int err = 1;
3820   long what = lli.what;
3821   int lg, nsb;
3822   if (what % 10 == 6) {
3823     int lg, nsb;
3824     lli.eval(fe3, cmp);
3825     // FFCS is able to display 3d complex data
3826     {
3827       if (fe3[0]->x( )) {
3828         err = 0;
3829         theplot << what;
3830         theplot << mapth3[&(fe3[0]->Vh->Th)];    // numero du maillage
3831         KN< R3 > Psub;
3832         KN< int > Ksub;
3833         KN< K > V1 = fe3[0]->Vh->newSaveDraw(*fe3[0]->x( ), cmp[0], lg, Psub, Ksub, 0);
3834         if (verbosity > 9)
3835           cout << " Send plot:what: " << what << " " << nsb << " " << V1.N( ) << " " << V1.max( )
3836                << " " << V1.min( ) << endl;
3837         theplot << Psub;
3838         theplot << Ksub;
3839         theplot << V1;
3840       }
3841     }
3842   } else if (what % 10 == 7) {
3843     int lg, nsb;
3844     lli.eval(fe3, cmp);
3845     // FFCS is able to display 3d complex data
3846     {
3847       if (fe3[0]->x( ) && fe3[1]->x( ) && fe3[2]->x( )) {
3848         err = 0;
3849         theplot << what;
3850         theplot << mapth3[&(fe3[0]->Vh->Th)];    // numero du maillage
3851         KN< R3 > Psub1, Psub2, Psub3;            // bf Bof ...
3852         KN< int > Ksub1, Ksub2, Ksub3;
3853         KN< K > V1 = fe3[0]->Vh->newSaveDraw(*fe3[0]->x( ), cmp[0], lg, Psub1, Ksub1, 0);
3854         KN< K > V2 = fe3[1]->Vh->newSaveDraw(*fe3[1]->x( ), cmp[1], lg, Psub2, Ksub2, 0);
3855         KN< K > V3 = fe3[2]->Vh->newSaveDraw(*fe3[2]->x( ), cmp[2], lg, Psub3, Ksub3, 0);
3856         if (verbosity > 9)
3857           cout << " Send plot:what: " << what << " " << nsb << " " << V1.N( ) << " " << V1.max( )
3858                << " " << V1.min( ) << endl;
3859         theplot << Psub1;
3860         theplot << Ksub1;
3861         ffassert(V1.N( ) == V2.N( ) && V1.N( ) == V3.N( ));
3862         KNM< K > V123(3, V1.N( ));    // warning fortran numbering ...
3863         V123(0, '.') = V1;
3864         V123(1, '.') = V2;
3865         V123(2, '.') = V3;
3866         // FFCS: should be able to deal with complex as well
3867         theplot << (KN_< K > &)V123;
3868       }
3869     }
3870   }
3871   return err;
3872 }
3873 
3874 template< class K, class v_fes >
SendS(PlotStream & theplot,Plot::ListWhat & lli,map<const MeshS *,long> & mapthS)3875 int SendS(PlotStream &theplot, Plot::ListWhat &lli, map< const MeshS *, long > &mapthS) {
3876   typedef FEbase< K, v_fes > *pfekS;
3877   pfekS feS[3] = {0, 0, 0};
3878   int cmp[3] = {-1, -1, -1};
3879   int err = 1;
3880   long what = lli.what;
3881   int lg, nsb = 0;
3882   lli.eval(feS, cmp);
3883 
3884   if (what % 10 == 8) {
3885     err = 0;
3886     theplot << what;
3887     theplot << mapthS[&(feS[0]->Vh->Th)];    // numero du maillage
3888     KN< R2 > Psub;
3889     KN< int > Ksub;
3890     KN< K > V1 = feS[0]->Vh->newSaveDraw(*feS[0]->x( ), cmp[0], lg, Psub, Ksub, 0);
3891 
3892     if (verbosity > 9)
3893       cout << " Send plot:what: " << what << " " << nsb << " " << V1.N( ) << " Max " << V1.max( )
3894            << " min " << V1.min( ) << endl;
3895     theplot << Psub;
3896     theplot << Ksub;
3897     theplot << V1;
3898   }
3899   else if (what % 10 == 9) {
3900     int lg, nsb;
3901     lli.eval(feS, cmp);
3902     // FFCS is able to display 3d complex data
3903 
3904     if (feS[0]->x( ) && feS[1]->x( ) && feS[2]->x( )) {
3905       err = 0;
3906       theplot << what;
3907       theplot << mapthS[&(feS[0]->Vh->Th)];
3908       KN< R2 > Psub1, Psub2, Psub3;
3909       KN< int > Ksub1, Ksub2, Ksub3;
3910       KN< K > V1 = feS[0]->Vh->newSaveDraw(*feS[0]->x( ), cmp[0], lg, Psub1, Ksub1, 0);
3911       KN< K > V2 = feS[1]->Vh->newSaveDraw(*feS[1]->x( ), cmp[1], lg, Psub2, Ksub2, 0);
3912       KN< K > V3 = feS[2]->Vh->newSaveDraw(*feS[2]->x( ), cmp[2], lg, Psub3, Ksub3, 0);
3913       if (verbosity > 9)
3914         cout << " Send plot:what: " << what << " " << nsb << " " << V1.N( ) << " " << V1.max( )<< " " << V1.min( ) << endl;
3915       theplot << Psub1;
3916       theplot << Ksub1;
3917       ffassert(V1.N( ) == V2.N( ) && V1.N( ) == V3.N( ));
3918       KNM< K > V123(3, V1.N( ));    // warning fortran numbering ...
3919       V123(0, '.') = V1;
3920       V123(1, '.') = V2;
3921       V123(2, '.') = V3;
3922       theplot << (KN_< K > &)V123;
3923     }
3924  }
3925   return err;
3926 }
3927 
3928 template< class K, class v_fes >
SendL(PlotStream & theplot,Plot::ListWhat & lli,map<const MeshL *,long> & mapthS)3929 int SendL(PlotStream &theplot, Plot::ListWhat &lli, map< const MeshL *, long > &mapthS) {
3930   typedef FEbase< K, v_fes > *pfekS;
3931   pfekS feL[3] = {0, 0, 0};
3932   int cmp[3] = {-1, -1, -1};
3933   int err = 1;
3934   long what = lli.what;
3935   int lg, nsb = 0;
3936   lli.eval(feL, cmp);
3937 
3938   if( what == 14 || what == 20 || what == 114 || what == 120) {
3939     err = 0;
3940     theplot << what;
3941     theplot << mapthS[&(feL[0]->Vh->Th)];    // numero du maillage
3942     KN< R1 > Psub;
3943     KN< int > Ksub;
3944     KN< K > V1 = feL[0]->Vh->newSaveDraw(*feL[0]->x( ), cmp[0], lg, Psub, Ksub, 0);
3945 
3946     if (verbosity > 9)
3947       cout << " Send plot:what: " << what << " " << nsb << " " << V1.N( ) << " Max " << V1.max( )
3948            << " min " << V1.min( ) << endl;
3949     theplot << Psub;
3950     theplot << Ksub;
3951     theplot << V1;
3952 
3953   } else if (what == 15 || what == 21 ) {
3954     ffassert(0);
3955   }
3956   return err;
3957 }
3958 //  missing function
NewSetColorTable(int nb,float * colors=0,int nbcolors=0,bool hsv=true)3959 inline void NewSetColorTable(int nb, float *colors = 0, int nbcolors = 0, bool hsv = true) {
3960   if (colors && nbcolors)
3961     SetColorTable1(nb, hsv, nbcolors, colors);
3962   else
3963     SetColorTable(nb);
3964 }
3965 
3966 /// <<Plot_operator_brackets>> from class [[Plot]]
operator ( )(Stack s) const3967 AnyType Plot::operator( )(Stack s) const {
3968   // remap  case 107 and 108 , 109  for array of FE.
3969   vector< ListWhat > ll;
3970   vector< AnyType > lat;
3971   ll.reserve(l.size( ));
3972   // generation de la list de plot ...
3973   for (size_t i = 0; i < l.size( ); i++) {
3974     switch (l[i].what) {
3975       case 0:
3976         l[i].EvalandPush< void * >(s, i, ll);
3977         break;
3978       case 1:
3979         l[i].EvalandPush< void * >(s, i, ll);
3980         break;
3981       case 2:
3982         l[i].EvalandPush< void * >(s, i, ll);
3983         break;
3984       case 3:
3985         l[i].EvalandPush(s, i, ll, lat);
3986         break;
3987       case 5:
3988         l[i].EvalandPush< void * >(s, i, ll);
3989         break;
3990       case 6:
3991         l[i].EvalandPush< void * >(s, i, ll);
3992         break;
3993       case 7:
3994         l[i].EvalandPush< void * >(s, i, ll);
3995         break;
3996       case 8:
3997         l[i].EvalandPush< void * >(s, i, ll);
3998         break;
3999       case 9:
4000         l[i].EvalandPush< void * >(s, i, ll);
4001         break;
4002       case 11:
4003         l[i].EvalandPush< void * >(s, i, ll);
4004         break;
4005       case 12:
4006         l[i].EvalandPush< void * >(s, i, ll);
4007         break;
4008       case 14:
4009         l[i].EvalandPush< void * >(s, i, ll);
4010         break;
4011       case 15:
4012         l[i].EvalandPush< void * >(s, i, ll);
4013         break;
4014       case 16:
4015         l[i].EvalandPush< void * >(s, i, ll);
4016         break;
4017       case 17:
4018         l[i].EvalandPush< void * >(s, i, ll);
4019         break;
4020       case 18:
4021         l[i].EvalandPush< void * >(s, i, ll);
4022         break;
4023       case 19:
4024         l[i].EvalandPush< void * >(s, i, ll);
4025         break;
4026       case 20:
4027         l[i].EvalandPush< void * >(s, i, ll);
4028         break;
4029       case 21:
4030         l[i].EvalandPush< void * >(s, i, ll);
4031         break;
4032       case 50:
4033         l[i].EvalandPush< void * >(s, i, ll);
4034         break;
4035       case 55:
4036         l[i].EvalandPush< void * >(s, i, ll);
4037         break;
4038       case 100:
4039         l[i].MEvalandPush< pmesh >(s, i, ll);
4040         break;
4041       case 101:
4042         l[i].AEvalandPush< asol, sol >(s, i, ll);
4043         break;
4044       case 102:
4045         l[i].AEvalandPush< asol, sol >(s, i, ll);
4046         break;
4047       case 103:
4048         l[i].AEvalandPush(s, i, ll, lat);
4049         break;
4050       case 105:
4051         l[i].MEvalandPush< pmesh3 >(s, i, ll);
4052         break;
4053       case 106:
4054         l[i].AEvalandPush< asol3, sol3 >(s, i, ll);
4055         break;
4056       case 108:
4057         l[i].AEvalandPush< asolS, solS >(s, i, ll);
4058         break;
4059       case 114:
4060         l[i].AEvalandPush< asolL, solL >(s, i, ll);
4061         break;
4062       case 111:
4063         l[i].AEvalandPush< asolc, solc >(s, i, ll);
4064         break;
4065       case 112:
4066         l[i].AEvalandPush< asolc, solc >(s, i, ll);
4067         break;
4068       case 116:
4069         l[i].AEvalandPush< asolc3, solc3 >(s, i, ll);
4070         break;
4071       case 118:
4072         l[i].AEvalandPush< asolcS, solcS >(s, i, ll);
4073         break;
4074       case 120:
4075         l[i].AEvalandPush< asolcL, solcL >(s, i, ll);
4076         break;
4077 
4078       default:
4079         ffassert(l[i].what < 100);    // missing piece of code FH (jan 2010) ...
4080         ll.push_back(ListWhat(l[i].what, i));
4081         break;
4082     }
4083   }
4084 
4085   if (ThePlotStream) {
4086     /*
4087      les different item of the plot are given by the number what:
4088      what = 0 -> mesh
4089      what = 1 -> real scalar field (FE function  2d)
4090      what = 2 -> 2d vector field (two FE function  2d)
4091      what = 3 -> curve def by 2,.., 4 array
4092      what = 4 -> border 2d
4093      what = 5 -> 3d mesh, real volume or if contains a surface mesh
4094      what = 6 -> real FE function 3D volume
4095      what = 7 -> real 3d vector field (tree FE function  3d) volume
4096      what = 8 -> real FE function 3D surface
4097      what = 9 -> real 3d vector field (tree FE function  3d) surface
4098      what = 11 -> complex scalar field (FE function  2d) real
4099      what = 13 -> curve def by 4  array : x,y,z,  value for color ...
4100      what = 14 -> real FE function 3D curve
4101      what = 15 -> real 3d vector field (tree FE function  3d) curve
4102      what = 16 -> complex FE function 3D volume
4103      what = 17 -> complex 3d vector field (tree FE function  3d) volume
4104      what = 18 -> complex FE function 3D surface
4105      what = 19 -> complex 3d vector field (tree FE function  3d) surface
4106      what = 20 -> complex FE function 3D curve
4107      what = 21 -> complex 3d vector field (tree FE function  3d) curve
4108      what = 50 -> 3D surface mesh
4109      what = 55 -> 3D line mesh
4110      what = 100,101,106,109,114 ->   remap with real ... 2d, 3D volume, 3D surface, 3D curve
4111      what = 111, 116, 117 ,120 ->  remap with complex ... 2d, 3D volume, 3D surface, 3D curve
4112      what = -1 -> error, item empty
4113      */
4114     PlotStream theplot(ThePlotStream);
4115     pferbase fe[3] = {0, 0, 0};
4116     pf3rbase fe3[3] = {0, 0, 0};
4117     pfSrbase feS[3] = {0, 0, 0};
4118     pfLrbase feL[3] = {0, 0, 0};
4119     double echelle = 1;
4120     int cmp[3] = {-1, -1, -1};
4121     theplot.SendNewPlot( );
4122     if (nargs[0]) (theplot << 0L) <= GetAny< double >((*nargs[0])(s));
4123     if (nargs[1]) (theplot << 1L) <= GetAny< string * >((*nargs[1])(s));
4124     if (nargs[2]) (theplot << 2L) <= GetAny< string * >((*nargs[2])(s));
4125     if (nargs[3])
4126       (theplot << 3L) <= (bool)(!NoWait && GetAny< bool >((*nargs[3])(s)));
4127     else
4128       (theplot << 3L) <= (bool)(TheWait && !NoWait);
4129     if (nargs[4]) (theplot << 4L) <= GetAny< bool >((*nargs[4])(s));
4130     if (nargs[5]) (theplot << 5L) <= GetAny< bool >((*nargs[5])(s));
4131     if (nargs[6]) (theplot << 6L) <= GetAny< bool >((*nargs[6])(s));
4132     if (nargs[7]) (theplot << 7L) <= GetAny< bool >((*nargs[7])(s));
4133     if (nargs[8]) {
4134       KN< double > bbox(4);
4135       for (int i = 0; i < 4; i++) bbox[i] = GetAny< double >((*bb[i])(s));
4136 
4137       (theplot << 8L) <= bbox;
4138     }
4139     if (nargs[9]) (theplot << 9L) <= GetAny< long >((*nargs[9])(s));
4140     if (nargs[10]) (theplot << 10L) <= GetAny< long >((*nargs[10])(s));
4141     if (nargs[11]) {
4142       KN_< double > v = GetAny< KN_< double > >((*nargs[11])(s));
4143       (theplot << 11L) <= v;
4144     }
4145 
4146     if (nargs[12]) (theplot << 12L) <= GetAny< KN_< double > >((*nargs[12])(s));
4147 
4148     if (nargs[13]) (theplot << 13L) <= GetAny< bool >((*nargs[13])(s));
4149     if (nargs[14]) (theplot << 14L) <= GetAny< bool >((*nargs[14])(s));
4150     if (nargs[15]) (theplot << 15L) <= GetAny< KN_< double > >((*nargs[15])(s));
4151     if (nargs[16]) (theplot << 16L) <= GetAny< bool >((*nargs[16])(s));
4152     // add frev 2008 FH for 3d plot ...
4153     if (nargs[17]) (theplot << 17L) <= GetAny< long >((*nargs[17])(s));
4154     if (nargs[18]) (theplot << 18L) <= GetAny< bool >((*nargs[18])(s));
4155     if (nargs[19]) (theplot << 19L) <= GetAny< bool >((*nargs[19])(s));
4156     if (nargs[20]) (theplot << 20L) <= (echelle = GetAny< double >((*nargs[20])(s)));
4157 
4158       // FFCS: extra plot options for VTK (indexed from 1 to keep these lines unchanged even if the
4159       // number of standard FF parameters above changes) received in
4160       // [[file:../ffcs/src/visudata.cpp::receiving_plot_parameters]]. When adding a parameter here,
4161       // do _NOT_ forget to change the size of the array at
4162       // [[number_of_distinct_named_parameters_for_plot]] and to name the new parameters at
4163       // [[Plot_name_param]]. Also update the list of displayed values at
4164       // [[file:../ffcs/src/plot.cpp::Plotparam_listvalues]] and read the parameter value from the
4165       // pipe at [[file:../ffcs/src/visudata.cpp::receiving_plot_parameters]].
4166 
4167 #define VTK_START 20
4168 #define SEND_VTK_PARAM(index, type) \
4169   if (nargs[VTK_START + index])     \
4170     (theplot << (long)(VTK_START + index)) <= GetAny< type >((*nargs[VTK_START + index])(s));
4171 
4172     SEND_VTK_PARAM(1, double);            // ZScale
4173     SEND_VTK_PARAM(2, bool);              // WhiteBackground
4174     SEND_VTK_PARAM(3, bool);              // OpaqueBorders
4175     SEND_VTK_PARAM(4, bool);              // BorderAsMesh
4176     SEND_VTK_PARAM(5, bool);              // ShowMeshes
4177     SEND_VTK_PARAM(6, long);              // ColorScheme
4178     SEND_VTK_PARAM(7, long);              // ArrowShape
4179     SEND_VTK_PARAM(8, double);            // ArrowSize
4180     SEND_VTK_PARAM(9, long);              // ComplexDisplay
4181     SEND_VTK_PARAM(10, bool);             // LabelColors
4182     SEND_VTK_PARAM(11, bool);             // ShowAxes
4183     SEND_VTK_PARAM(12, bool);             // CutPlane
4184     SEND_VTK_PARAM(13, KN_< double >);    // CameraPosition
4185     SEND_VTK_PARAM(14, KN_< double >);    // CameraFocalPoint
4186     SEND_VTK_PARAM(15, KN_< double >);    // CameraViewUp
4187     SEND_VTK_PARAM(16, double);           // CameraViewAngle
4188     SEND_VTK_PARAM(17, KN_< double >);    // CameraClippingRange
4189     SEND_VTK_PARAM(18, KN_< double >);    // CutPlaneOrigin
4190     SEND_VTK_PARAM(19, KN_< double >);    // CutPlaneNormal
4191     SEND_VTK_PARAM(20, long);             // WindowIndex
4192     SEND_VTK_PARAM(21, long);             // NbColorTicks
4193     SEND_VTK_PARAM(22, long);             // NbColors
4194     SEND_VTK_PARAM(23, bool);             // pNormalT
4195     theplot.SendEndArgPlot( );
4196     map< const Mesh *, long > mapth;
4197     map< const Mesh3 *, long > mapth3;
4198     map< const MeshS *, long > mapthS;
4199     map< const MeshL *, long > mapthL;
4200 
4201     long kth = 0, kth3 = 0, kthS = 0, kthL = 0;
4202     //  send all the mesh:
4203     for (size_t ii = 0; ii < ll.size( ); ii++) {
4204       int i = ll[ii].i;
4205       long what = ll[i].what;
4206       const Mesh *th = 0;
4207       const Mesh3 *th3 = 0;
4208       const MeshS *thS = 0;
4209       const MeshL *thL = 0;
4210       // Prepare for the sending mesh 2d
4211       if (what == 0) th = ll[ii].th( );
4212       // Prepare for the sending mesh 3d with differenciation 3D line / surface / volumuic /
4213       // volum+surfac / line+volum+surfac
4214       if (what == 5)
4215         th3 = &(l[i].evalm3(0, s));    // 3d mesh3 -> if contains a meshS or meshL pointer, send
4216                                        // only the principal mesh: the mesh3
4217       if (what == 50) thS = (&(l[i].evalmS(0, s)));    // 3d meshS
4218       if (what == 55) thL = (&(l[i].evalmL(0, s)));    // 3d  meshL
4219       // Prepare for the sending 2d iso values for ffglut
4220       else if (what == 1 || what == 2 || what == 11 || what == 12) {
4221         ll[ii].eval(fe, cmp);
4222         if (fe[0]->x( )) th = &fe[0]->Vh->Th;
4223         if (fe[1] && fe[1]->x( )) ffassert(th == &fe[1]->Vh->Th);
4224       }
4225       // Prepare for the sending 3D volume iso values for ffglut
4226       else if (what == 6 || what == 7 || what == 16 || what == 17) {
4227         ll[ii].eval(fe3, cmp);
4228         if (fe3[0]->x( )) th3 = &fe3[0]->Vh->Th;
4229         if (fe3[1]) ffassert(th3 == &fe3[1]->Vh->Th);
4230         if (fe3[2]) ffassert(th3 == &fe3[2]->Vh->Th);
4231 
4232       }
4233       // Prepare for the sending 3D surface iso values for ffglut
4234       else if (what == 8 || what == 9 || what == 18 || what == 19) {
4235         ll[ii].eval(feS, cmp);
4236         if (feS[0]->x( )) thS = &feS[0]->Vh->Th;
4237         if (feS[1] && feS[1]->x( )) ffassert(thS == &feS[1]->Vh->Th);
4238         if (feS[2] && feS[2]->x( )) ffassert(thS == &feS[2]->Vh->Th);
4239       }
4240       // Prepare for the sending 3D curve iso values for ffglut
4241       else if (what == 14 || what == 15 || what == 20 || what == 21) {
4242         ll[ii].eval(feL, cmp);
4243         if (feL[0]->x( )) thL = &feL[0]->Vh->Th;
4244         if (feL[1] && feL[1]->x( )) ffassert(thL == &feL[1]->Vh->Th);
4245         if (feL[2] && feL[2]->x( )) ffassert(thL == &feL[2]->Vh->Th);
4246       }
4247       // test on the type meshes --- 2D, 3D volume and 3D surface
4248       if (th && mapth.find(th) == mapth.end( )) mapth[th] = ++kth;
4249       if (th3 && (mapth3.find(th3) == mapth3.end( ))) mapth3[th3] = ++kth3;
4250       if (thS && (mapthS.find(thS) == mapthS.end( ))) mapthS[thS] = ++kthS;
4251       if (thL && (mapthL.find(thL) == mapthL.end( ))) mapthL[thL] = ++kthL;
4252     }
4253     // send of meshes 2d
4254     theplot.SendMeshes( );
4255     theplot << kth;
4256 
4257     for (map< const Mesh *, long >::const_iterator i = mapth.begin( ); i != mapth.end( ); ++i)
4258       theplot << i->second << *i->first;
4259 
4260     // only send of volume meshes 3D if completed mesh3 (meshS!=NULL or/and !=meshL!=NULL)
4261     if (kth3) {
4262       theplot.SendMeshes3( );
4263       theplot << kth3;
4264       for (map< const Mesh3 *, long >::const_iterator i = mapth3.begin( ); i != mapth3.end( ); ++i)
4265         theplot << i->second << *i->first;
4266     }
4267     if (kthS) {
4268       theplot.SendMeshesS( );
4269       theplot << kthS;
4270       for (map< const MeshS *, long >::const_iterator i = mapthS.begin( ); i != mapthS.end( ); ++i)
4271         theplot << i->second << *i->first;
4272     }
4273     if (kthL) {
4274       theplot.SendMeshesL( );
4275       theplot << kthL;
4276       for (map< const MeshL *, long >::const_iterator i = mapthL.begin( ); i != mapthL.end( ); ++i)
4277         theplot << i->second << *i->first;
4278     }
4279 
4280     // end of what ploting for meshes
4281     theplot.SendPlots( );
4282 
4283     theplot << (long)ll.size( );
4284     for (size_t ii = 0; ii < ll.size( ); ii++) {
4285       int i = ll[ii].i;
4286       long what = ll[ii].what;
4287       int err = 1;    //  by default we are in error
4288       const Mesh *pTh = 0;
4289       const Mesh3 *pTh3 = 0;
4290       const MeshS *pThS = 0;
4291       const MeshL *pThL = 0;
4292 
4293       // send 2d meshes for ffglut
4294       if (what == 0) {
4295         pTh = ll[ii].th( );
4296         if (pTh) {
4297           err = 0;
4298           theplot << what;
4299           theplot << mapth[ll[ii].th( )];    // numero du maillage 2d
4300         }
4301       }
4302       // send 2d iso values for ffglut
4303       else if (what == 1 || what == 2)
4304         err = Send2d< R, v_fes >(theplot, ll[ii], mapth);
4305       else if (what == 11 || what == 12)
4306         err = Send2d< Complex, v_fes >(theplot, ll[ii], mapth);
4307 
4308       else if (what == 3 || what == 13) {
4309         what = 13;
4310         theplot << what;    //
4311         KN< double > z0;
4312         if (verbosity > 99) cout << " sendplot curve " << what << " " << ii;
4313 
4314         for (int k = 0; k < 4; ++k) {
4315           int ilat = ll[ii].l[k];
4316           if (ilat >= 0) {
4317             KN_< double > t = GetAny< KN_< double > >(lat[ilat]);
4318             theplot << t;
4319             if (verbosity > 99) cout << " (" << k << " " << ilat << ") " << t.N( );
4320           } else
4321             theplot << z0;    // empty arry ...
4322         }
4323         if (verbosity > 99) cout << endl;
4324         err = 0;
4325       }
4326 
4327       else if (l[i].what == 4) {
4328         err = 0;
4329         theplot << what;
4330         const E_BorderN *Bh = l[i].evalb(0, s);
4331         Bh->SavePlot(s, theplot);
4332       }
4333       // send volume 3d meshes for ffglut
4334       else if (what == 5) {
4335         pTh3 = &l[i].evalm3(0, s);
4336         if (pTh3) {
4337           err = 0;
4338           theplot << what;
4339           theplot << mapth3[&l[i].evalm3(0, s)];    // numero du maillage 3D volume
4340         }
4341       }
4342       else if (what == 50) {
4343         pThS = &(l[i].evalmS(0, s));
4344         if (pThS) {
4345           err = 0;
4346           theplot << what;
4347           theplot << mapthS[&(l[i].evalmS(0, s))];    // numero du maillage 3D surface
4348         }
4349       } else if (what == 55) {
4350         pThL = &(l[i].evalmL(0, s));
4351         if (pThL) {
4352           err = 0;
4353           theplot << what;
4354           theplot << mapthL[&(l[i].evalmL(0, s))];    // numero du maillage 3D line
4355         }
4356       }
4357 
4358       // send 3D volume iso values for ffglut
4359       else if (what == 6 || what == 7)
4360         err = Send3d< R, v_fes3 >(theplot, ll[ii], mapth3);
4361       else if (what == 16 || what == 17)
4362         err = Send3d< Complex, v_fes3 >(theplot, ll[ii], mapth3);
4363       // send 3D surface iso values for ffglut
4364       else if (what == 8 || what == 9)
4365         err = SendS< R, v_fesS >(theplot, ll[ii], mapthS);
4366       else if (what == 18 || what == 19)
4367         err = SendS< Complex, v_fesS >(theplot, ll[ii], mapthS);
4368       // send 3D curve iso values for ffglut
4369       else if (what == 14 || what == 15)
4370         err = SendL< R, v_fesL >(theplot, ll[ii], mapthL);
4371       else if (what == 20 || what == 21)
4372         err = SendL< Complex, v_fesL >(theplot, ll[ii], mapthL);
4373       else
4374         ffassert(0);    // erreur type theplot inconnue
4375       if (err == 1) {
4376         if (verbosity)
4377           cerr << "Warning: May be a bug in your script, \n"
4378                << " a part of the plot is wrong t (mesh or FE function, curve)  => skip the item  "
4379                << i + 1 << " in plot command " << endl;
4380         theplot << -1L << (long)i;
4381       }
4382     }
4383     theplot.SendEndPlot( );
4384   }
4385 
4386   // begin to the post scrit procedure
4387   if (!withrgraphique) {
4388     initgraphique( );
4389     withrgraphique = true;
4390   }
4391   viderbuff( );
4392   MeshPoint *mps = MeshPointStack(s), mp = *mps;
4393   int nbcolors = 0;
4394   float *colors = 0;
4395   bool hsv = true;    // hsv  type
4396   R boundingbox[4];
4397   double coeff = 1;
4398   bool wait = TheWait;
4399   bool value = false;
4400   bool fill = false;
4401   bool aspectratio = false;
4402   bool clean = true;
4403   bool uaspectratio = false;
4404   bool pViso = false, pVarrow = false;
4405   int Niso = 20, Narrow = 20;
4406   double ArrowSize = -1;
4407   // PPPPP
4408   KN< R > Viso, Varrow;
4409 
4410   bool bw = false;
4411   string *psfile = 0;
4412   string *cm = 0;
4413   pferbase fe = 0, fe1 = 0;
4414   int cmp0, cmp1;
4415   bool grey = getgrey( );
4416   bool greyo = grey;
4417   bool drawborder = true;
4418   if (nargs[0]) coeff = GetAny< double >((*nargs[0])(s));
4419   if (nargs[1]) cm = GetAny< string * >((*nargs[1])(s));
4420   if (nargs[2]) psfile = GetAny< string * >((*nargs[2])(s));
4421   if (nargs[3]) wait = GetAny< bool >((*nargs[3])(s));
4422   if (nargs[4]) fill = GetAny< bool >((*nargs[4])(s));
4423   if (nargs[5]) value = GetAny< bool >((*nargs[5])(s));
4424   if (nargs[6]) clean = GetAny< bool >((*nargs[6])(s));
4425   if (nargs[7]) uaspectratio = true, uaspectratio = GetAny< bool >((*nargs[7])(s));
4426   if (nargs[8])
4427     for (int i = 0; i < 4; i++) boundingbox[i] = GetAny< double >((*bb[i])(s));
4428   if (nargs[9]) Niso = GetAny< long >((*nargs[9])(s));
4429   if (nargs[10]) Narrow = GetAny< long >((*nargs[10])(s));
4430   if (nargs[11]) {
4431     KN_< double > v = GetAny< KN_< double > >((*nargs[11])(s));
4432     Niso = v.N( );
4433     Viso.init(Niso);
4434     Viso = v;
4435     pViso = true;
4436   }
4437 
4438   if (nargs[12]) {
4439     KN_< double > v = GetAny< KN_< double > >((*nargs[12])(s));
4440     Niso = v.N( );
4441     Varrow.init(Niso);
4442     Varrow = v;
4443     pVarrow = true;
4444   }
4445 
4446   if (nargs[13]) bw = GetAny< bool >((*nargs[13])(s));
4447   if (nargs[14]) grey = GetAny< bool >((*nargs[14])(s));
4448   if (nargs[15]) {
4449     KN_< double > cc = GetAny< KN_< double > >((*nargs[15])(s));
4450     nbcolors = cc.N( ) / 3;
4451     if (nbcolors > 1 && nbcolors < 100) {
4452       colors = new float[nbcolors * 3];
4453       for (int i = 0; i < 3 * nbcolors; i++) colors[i] = cc[i];
4454     } else
4455       nbcolors = 0;
4456   }
4457   if (nargs[16]) drawborder = GetAny< bool >((*nargs[16])(s));
4458   int dimplot = 2;
4459   if (nargs[17]) dimplot = GetAny< long >((*nargs[17])(s));
4460   bool addtoplot = false, keepPV = false, pNormalT = false;
4461   if (nargs[18]) addtoplot = GetAny< bool >((*nargs[18])(s));
4462   if (nargs[19]) keepPV = GetAny< bool >((*nargs[19])(s));
4463   if (nargs[VTK_START + 23]) pNormalT = GetAny< bool >((*nargs[VTK_START + 23])(s));
4464   if (nargs[VTK_START + 8]) ArrowSize = GetAny< double >((*nargs[VTK_START + 8])(s));
4465   //  for the gestion of the PTR.
4466   WhereStackOfPtr2Free(s) = new StackOfPtr2Free(s);    // FH aout 2007
4467 
4468   setgrey(grey);
4469   if (Viso.unset( )) Viso.init(Niso);
4470   if (Varrow.unset( )) Varrow.init(Narrow);
4471 
4472   const Mesh *cTh = 0;
4473   bool vecvalue = false, isovalue = false;
4474   bool ops = psfile;
4475   bool drawmeshes = false;
4476   if (clean) {
4477     // ALH - 28/3/15 - Open PS file before blanking the current picture because Javascript needs to
4478     // know any "ps=" parameter to send the graphical commands to the right canvas.
4479 
4480     if (psfile) {
4481       // [[file:../Graphics/sansrgraph.cpp::openPS]]
4482       openPS(psfile->c_str( ));
4483     }
4484 
4485     reffecran( );
4486 
4487     if (bw) NoirEtBlanc(1);
4488     R2 Pmin, Pmax;
4489     R2 uminmax(1e100, -1e100);
4490     R2 Vminmax(1e100, -1e100);
4491     bool first = true;
4492     for (size_t ii = 0; ii < ll.size( ); ii++) {
4493       int i = ll[ii].i;
4494       long what = ll[ii].what;
4495       R2 P1(1e100,1e100), P2(-1e100,-1e100);
4496   //    R3 P11(1e100,1e100,1e100), P22(-1e100,-1e100,-1e100);
4497       if (what == 1 || what == 2) {
4498         if (!uaspectratio) aspectratio = true;
4499         ll[ii].eval(fe, cmp0, fe1, cmp1);
4500 
4501         if (!fe->x( )) continue;
4502 
4503         fe->Vh->cmesh->BoundingBox(P1, P2);
4504         cTh = fe->Vh->cmesh;
4505         if (fe1 == 0)
4506           uminmax = minmax(uminmax, fe->Vh->MinMax(*fe->x( ), cmp0));
4507         else {
4508           if (fe1) {
4509             if (fe->Vh == fe1->Vh) {
4510               KN_< R > u(*fe->x( )), v(*fe1->x( ));
4511               Vminmax = minmax(Vminmax, fe->Vh->MinMax(u, v, cmp0, cmp1));
4512             } else
4513               cerr << " On ne sait tracer que de vecteur sur un meme type element finite. " << endl;
4514           }
4515         }
4516       } else if (l[i].what == 0) {
4517         if (!uaspectratio) aspectratio = true;
4518         const Mesh &Th = *ll[ii].th( );
4519         Th.BoundingBox(P1, P2);
4520         cTh = &Th;
4521       } else if (l[i].what == 4) {
4522         if (!uaspectratio) aspectratio = true;
4523         const E_BorderN *Bh = l[i].evalb(0, s);
4524         double pminz=1e100,pmaxz=-1e100;
4525         Bh->BoundingBox(s, P1.x, P2.x, P1.y, P2.y, pminz, pmaxz);
4526 
4527       } else if (l[i].what == 3) {
4528         tab ttx = l[i].evalt(0, s);
4529         tab tty = l[i].evalt(1, s);
4530         tab *tx = &ttx, *ty = &tty;
4531         P1 = R2(tx->min( ), ty->min( ));
4532         P2 = R2(tx->max( ), ty->max( ));
4533         if (verbosity > 2) cout << "Plot: bound  Pmin=" << P1 << ",  Pmax=" << P2 << endl;
4534       } else
4535         continue;
4536 
4537       if (first) {
4538         first = false;
4539         Pmin = P1;
4540         Pmax = P2;
4541       } else {
4542         Pmin.x = Min(Pmin.x, P1.x);
4543         Pmin.y = Min(Pmin.y, P1.y);
4544         Pmax.x = Max(Pmax.x, P2.x);
4545         Pmax.y = Max(Pmax.y, P2.y);
4546       }
4547     }
4548 
4549     {
4550       R umx = uminmax.y, umn = uminmax.x;
4551       if (verbosity > 5) cout << " u bound " << uminmax << "  V : " << Vminmax << endl;
4552 
4553       if (verbosity > 1) cout << "Plot bound [x,y] " << Pmin << " max [x,y] " << Pmax << endl;
4554       int N = Viso.N( );
4555       int Na = Varrow.N( );
4556       R2 O((Pmin + Pmax) / 2);
4557       R rx(Pmax.x - Pmin.x), ry(Pmax.y - Pmin.y);
4558       // bug   version 1.41 correct FH to remove div by zero.
4559       rx = Max(rx, 1e-30);
4560       ry = Max(ry, 1e-30);
4561       // -- end correction
4562       R r = (Max(rx, ry) * 0.55);
4563       showgraphic( );
4564       if (aspectratio)
4565         cadreortho((float)O.x, (float)(O.y + r * 0.05), (float)r);
4566       else
4567         cadre((float)(O.x - rx * .55), (float)(O.x + rx * 0.55), (float)(O.y - ry * .55),
4568               (float)(O.y + ry * .55));
4569       R d = fill ? (umx - umn) / (N - 1) : (umx - umn) / (N);
4570       R x = fill ? umn - d / 2 : umn + d / 2;
4571       if (!pViso)
4572         for (int i = 0; i < N; i++) {
4573           Viso[i] = x;
4574           x += d;
4575         }
4576       if (fill && !pViso) {
4577         Viso[0] = umn - d;
4578         Viso[N - 1] = umx + d;
4579       }
4580       x = 0;
4581       d = sqrt(Vminmax.y) / (Na - 1.001);
4582       if (!pVarrow)
4583         for (int i = 0; i < Na; i++) {
4584           Varrow[i] = x;
4585           x += d;
4586         }
4587 
4588       SetColorTable(Max(N, Na) + 4);
4589     }
4590   }    // clean
4591   float xx0, xx1, yy0, yy1;
4592   if (nargs[8]) {
4593     xx0 = min(boundingbox[0], boundingbox[2]);
4594     xx1 = max(boundingbox[0], boundingbox[2]);
4595     yy0 = min(boundingbox[1], boundingbox[3]);
4596     yy1 = max(boundingbox[1], boundingbox[3]);
4597     if (verbosity > 2)
4598       cout << "bb=  xmin =" << xx0 << ", max =" << xx1 << ", ymin = " << yy0 << ", ymax = " << yy1
4599            << endl;
4600     if (aspectratio)
4601       cadreortho((xx0 + xx1) * 0.5, (yy0 + yy1) * 0.5, max(xx1 - xx0, yy1 - yy0) * 0.5);
4602     else
4603       cadre(xx0, xx1, yy0, yy1);
4604   }
4605   getcadre(xx0, xx1, yy0, yy1);
4606   const R ccoeff = coeff;
4607   bool plotting = true;
4608   //  drawing part  ------------------------------
4609   while (plotting) {
4610     if (verbosity > 99) cout << "plot::operator() Drawing part \n";
4611     plotting = false;
4612     bool thfill = fill;
4613     for (size_t ii = 0; ii < ll.size( ); ii++) {
4614       int i = ll[ii].i;
4615       long what = ll[i].what;
4616 
4617       if (l[i].what == 0)
4618         if (fill)
4619           ll[ii].th( )->Draw(0, thfill);
4620         else
4621           ll[ii].th( )->Draw(0, thfill);
4622       else if (what == 1 || what == 2) {
4623         ll[ii].eval(fe, cmp0, fe1, cmp1);
4624         if (!fe->x( )) continue;
4625 #ifdef VVVVVVV
4626         cout << "   Min = " << fe->x->min( ) << " max = " << fe->x->max( );
4627         if (fe1 && verbosity > 1)
4628           cout << " Min = " << fe1->x->min( ) << " max = " << fe1->x->max( );
4629         cout << endl;
4630 #endif
4631         if (fe1) {
4632           if (fe->Vh == fe1->Vh)
4633             vecvalue = true, fe->Vh->Draw(*fe->x( ), *fe1->x( ), Varrow, coeff, cmp0, cmp1, colors,
4634                                           nbcolors, hsv, drawborder, ArrowSize);
4635           else
4636             cerr << " Draw only vector field on same Finites Element , Sorry. " << endl;
4637           if (drawmeshes) fe->Vh->Th.Draw(0, fill);
4638         } else
4639 
4640           if (fill)
4641           isovalue = true,
4642           fe->Vh->Drawfill(*fe->x( ), Viso, cmp0, 1., colors, nbcolors, hsv, drawborder);
4643         else
4644           isovalue = true, fe->Vh->Draw(*fe->x( ), Viso, cmp0, colors, nbcolors, hsv, drawborder);
4645 
4646         if (drawmeshes) fe->Vh->Th.Draw(0, fill);
4647 
4648       } else if (l[i].what == 4) {
4649         const E_BorderN *Bh = l[i].evalb(0, s);
4650         Bh->Plot(s);
4651       } else if (l[i].what == 3) {
4652         penthickness(6);
4653         tab x = l[i].evalt(0, s);
4654         tab y = l[i].evalt(1, s);
4655         KN< double > pz0;
4656         KN_< double > z(pz0), v(pz0);
4657         if (l[i].e[2]) {
4658           z.set(l[i].evalt(2, s));
4659         }
4660         if (l[i].e[3]) {
4661           v.set(l[i].evalt(3, s));
4662         }
4663         long k = Min(x.N( ), y.N( ));
4664         NewSetColorTable(Viso.N( ) + 4, colors, nbcolors, hsv);
4665         rmoveto(x[0], y[0]);
4666         couleur(2 + i);
4667         for (int i = 1; i < k; i++) rlineto(x[i], y[i]);
4668       } else {
4669         if (verbosity)
4670           cout << "  Plot::  Sorry no ps version for this type of plot " << l[i].what << endl;
4671       }
4672       thfill = false;
4673     }
4674     if (value) {
4675       int k = 0;
4676       if (isovalue) {
4677         PlotValue(Viso, k, "IsoValue");
4678         k += Viso.N( ) + 3;
4679       }
4680       if (vecvalue) {
4681         PlotValue(Varrow, k, "Vec Value");
4682         k += Varrow.N( ) + 3;
4683       }
4684     }
4685 
4686     if (cm) {
4687       couleur(1);
4688       DrawCommentaire(cm->c_str( ), 0.1, 0.97);
4689     }
4690     if (ops) {
4691       ops = false;
4692       closePS( );
4693     }
4694     if (wait && !NoWait) {
4695     next:
4696       float x, y, x0, y0, x1, y1, dx, dy, coef = 1.5;
4697       getcadre(x0, x1, y0, y1);
4698       char c = Getxyc(x, y);
4699       dx = (x1 - x0) / 2.;
4700       dy = (y1 - y0) / 2.;
4701 
4702       switch (c) {
4703         case '+':
4704           plotting = true;
4705           cadre(x - dx / coef, x + dx / coef, y - dy / coef, y + dy / coef);
4706           reffecran( );
4707           break;
4708         case '-':
4709           plotting = true;
4710           cadre(x - dx * coef, x + dx * coef, y - dy * coef, y + dy * coef);
4711           ;
4712           reffecran( );
4713           break;
4714         case '=':
4715           plotting = true;
4716           coeff = ccoeff;
4717           cadre(xx0, xx1, yy0, yy1);
4718           ;
4719           reffecran( );
4720           break;
4721         case 'r':
4722           plotting = true;
4723           reffecran( );
4724           break;
4725         case 'a':
4726         case 'c':
4727           coeff /= 1.5;
4728           plotting = true;
4729           reffecran( );
4730           reffecran( );
4731           break;
4732         case 'A':
4733         case 'C':
4734           coeff *= 1.5;
4735           plotting = true;
4736           reffecran( );
4737           break;
4738         case 'b':
4739           bw = !bw;
4740           NoirEtBlanc(bw);
4741           plotting = true;
4742           reffecran( );
4743           break;
4744         case 'v':
4745           value = !value;
4746           plotting = true;
4747           reffecran( );
4748           break;
4749         case 'f':
4750           fill = !fill;
4751           plotting = true;
4752           reffecran( );
4753           break;
4754         case 'g':
4755           setgrey(grey = !getgrey( ));
4756           plotting = true;
4757           reffecran( );
4758           break;
4759 
4760         case 'm':
4761           reffecran( );
4762           drawmeshes = !drawmeshes;
4763           plotting = true;
4764           break;
4765         case 'p':
4766           plotting = true;
4767           reffecran( );
4768           ops = true;
4769           openPS(0);
4770           plotting = true;
4771           break;
4772         case 'q':
4773           couleur(8);
4774 #ifdef DRAWING
4775           if (cTh) cTh->quadtree->Draw( );
4776 #endif
4777           couleur(1);
4778           goto next;
4779         case 's':
4780           if (cTh) {
4781             R2 P(x, y), PF(P), Phat;
4782             bool outside;
4783             const Vertex *v = cTh->quadtree->NearestVertexWithNormal(P);
4784             if (!v)
4785               v = cTh->quadtree->NearestVertex(P);
4786             else {
4787               couleur(2);
4788               const Triangle *t = cTh->Find(PF, Phat, outside, &(*cTh)[cTh->Contening(v)]);
4789               t->Draw(0.8);
4790               couleur(2);
4791               PF = (*t)(Phat);
4792               DrawMark(PF, 0.003);
4793             }
4794             couleur(5);
4795             DrawMark(P, 0.0015);
4796 
4797             couleur(1);
4798             if (v) DrawMark(*v, 0.005);
4799 
4800             goto next;
4801           }
4802         case '?':
4803           int i = 2;
4804           reffecran( );
4805           Show("Enter a keyboard character in the FreeFem Graphics window in order to:", i++);
4806 
4807           i += 2;
4808           Show("+)  zoom in around the cursor 3/2 times ", i++);
4809           Show("-)  zoom out around the cursor 3/2 times  ", i++);
4810           Show("=)  reset zooming  ", i++);
4811           Show("r)  refresh plot ", i++);
4812           Show("ac) increase   the size arrow ", i++);
4813           Show("AC) decrease the size arrow  ", i++);
4814           Show("b)  switch between black and white or color plotting ", i++);
4815           Show("g)  switch between grey or color plotting ", i++);
4816           Show("f)  switch between filling iso or not  ", i++);
4817           Show("v)  switch between show  the numerical value of iso or not", i++);
4818           Show("p)   save  plot in a Postscprit file", i++);
4819           Show("m)  switch between show  meshes or not", i++);
4820           Show("p)  switch between show  quadtree or not (for debuging)", i++);
4821           Show("t)  find  Triangle ", i++);
4822           Show("?)  show this help window", i++);
4823           Show("any other key : continue ", ++i);
4824           goto next;
4825       }
4826       if (!pViso || !pVarrow) {    //  recompute the iso bound
4827         R2 uminmax(1e100, -1e100);
4828         R2 Vminmax(1e100, -1e100);
4829         for (size_t i = 0; i < l.size( ); i++) {
4830           R2 P1, P2;
4831           if (l[i].what == 1 || l[i].what == 2) {
4832             fe = l[i].eval(0, s, cmp0);
4833             fe1 = l[i].eval(1, s, cmp1);
4834 
4835             if (!fe->x( )) continue;
4836 
4837             if (fe1 == 0)
4838               uminmax = minmax(uminmax, fe->Vh->MinMax(*fe->x( ), cmp0, false));
4839             else {
4840               if (fe1)
4841                 if (fe->Vh == fe1->Vh) {
4842                   KN_< R > u(*fe->x( )), v(*fe1->x( ));
4843                   Vminmax = minmax(uminmax, fe->Vh->MinMax(u, v, cmp0, cmp1, false));
4844                 }
4845             }
4846           } else
4847             continue;
4848         }
4849         if (verbosity > 5) cout << " u bound " << uminmax << endl;
4850         R umx = uminmax.y, umn = uminmax.x;
4851         int N = Viso.N( );
4852         int Na = Varrow.N( );
4853         R d = fill ? (umx - umn) / (N - 1) : (umx - umn) / (N);
4854         R x = fill ? umn - d / 2 : umn + d / 2;
4855         if (!pViso)
4856           for (int i = 0; i < N; i++) {
4857             Viso[i] = x;
4858             x += d;
4859           }
4860         if (fill && !pViso) {
4861           Viso[0] = umn - d;
4862           Viso[N - 1] = umx + d;
4863         }
4864         x = 0;
4865         d = sqrt(Vminmax.y) / Na;
4866         if (!pVarrow)
4867           for (int i = 0; i < Na; i++) {
4868             Varrow[i] = x;
4869             x += d;
4870           }
4871       }
4872     }
4873     *mps = mp;
4874   }    //  end plotting
4875   NoirEtBlanc(0);
4876   setgrey(greyo);
4877   if (colors) delete[] colors;
4878   viderbuff( );
4879 
4880   return 0L;
4881 }
4882 
operator ( )(Stack s) const4883 AnyType Convect::operator( )(Stack s) const {
4884   if (d == 2)
4885     return eval2(s);
4886   else
4887     return eval3(s);
4888 }
4889 
eval2(Stack s) const4890 AnyType Convect::eval2(Stack s) const {
4891   MeshPoint *mp(MeshPointStack(s)), mpc(*mp);
4892   MeshPointStack(s, &mpc);    // P  ptr on  variable mpc ...
4893 
4894   static MeshPoint mpp, mps;
4895   static int stateold = 0;
4896   static int count = 0;
4897   static R ddtp = 0;
4898   R ddt = GetAny< double >((*dt)(s));
4899   if (ddt) {
4900     if ((stateold == state) && (ddt == ddtp) &&
4901         (*mp == mpp))    // optim same convect at same point nov/2015
4902     {
4903       if (verbosity > 3 && count++ < 10)
4904         cout << " -- optim convect " << stateold << "  P= " << mp->P << ", " << mp->T
4905              << " chi(P) = " << mps.P << "," << mps.T << endl;
4906       mpc = mps;
4907     } else {
4908       if (verbosity > 3 && count++ < 10 * 10)
4909         cout << " -- no optim convect " << stateold << " " << state << " P= " << mp->P
4910              << " PP= " << mpp.P << endl;
4911       stateold = state;    // correction FH..
4912       ddtp = ddt;
4913       const Mesh &Th(*mp->Th);
4914       ffassert(mp->Th && mp->T);
4915       R l[3];
4916       l[1] = mpc.PHat.x;
4917       l[2] = mpc.PHat.y;
4918       l[0] = 1 - l[1] - l[2];
4919 
4920       int k = 0;
4921       int j;
4922       int it = Th(mpc.T);
4923       while ((j = WalkInTriangle(Th, it, l, GetAny< double >((*u)(s)), GetAny< double >((*v)(s)),
4924                                  ddt)) >= 0) {
4925         ffassert(l[j] == 0);
4926         // int jj  = j;
4927         R a = l[(j + 1) % 3], b = l[(j + 2) % 3];
4928         int itt = Th.ElementAdj(it, j);
4929         if (itt == it || itt < 0) break;    // le bord
4930         it = itt;
4931         l[j] = 0;
4932         l[(j + 1) % 3] = b;
4933         l[(j + 2) % 3] = a;
4934         mpc.change(R2(l[1], l[2]), Th[it], 0);
4935         if (k++ > 1000) {
4936           cerr << "Fatal  error  in Convect (R2) operator: loop  => velocity too high ???? or NaN "
4937                   "F. Hecht  "
4938                << endl;
4939           ffassert(0);
4940         }
4941       }
4942 
4943       mpc.change(R2(l[1], l[2]), Th[it], 0);
4944       mpp = *mp;    // previous value
4945       mps = mpc;    // convect value
4946     }
4947   }
4948   // warning use poit on &mpc .. bug correct in dec 2015 F.H.
4949   AnyType r = (*ff)(s);
4950   if (verbosity > 3 && count++ < 10 * 10)
4951     cout << "  %%%r= " << GetAny< double >(r) << "  P= " << mp->P << ", " << mp->T << endl;
4952   MeshPointStack(s, mp);    // restor old pointeur ..
4953 
4954   return r;
4955 }
4956 
FindandAdd(set<int> * st,vector<int> & lst,int k)4957 inline int FindandAdd(set< int > *st, vector< int > &lst, int k) {
4958   if (lst.size( ) < 10) {
4959   }
4960   return 0;
4961 }
4962 
eval3old(Stack s) const4963 AnyType Convect::eval3old(Stack s) const {
4964   extern long newconvect3;
4965   if (newconvect3) return eval3(s);    //  New Convect in test
4966   MeshPoint *mp(MeshPointStack(s)), mpc(*mp);
4967   MeshPointStack(s, &mpc);    // P  ptr on  variable mpc ...
4968 
4969   static MeshPoint mpp, mps;    // previous state ..
4970   static int stateold = 0;
4971   static int count = 0;
4972   static R ddtp = 0;
4973 
4974   randwalk(-1);    // init randwalk
4975 
4976   R ddt = GetAny< double >((*dt)(s));
4977   if (ddt) {
4978     bool ddd = verbosity > 1000;
4979     if ((stateold == state) && (ddt == ddtp) &&
4980         (*mp == mpp))    // optim same convect at same point nov/2015
4981     {
4982       if (verbosity > 3 && count++ < 10) cout << " -- optim convect3 " << stateold << endl;
4983       mpc = mps;
4984     } else {
4985       if (verbosity > 3 && count++ < 10 * 10)
4986         cout << " -- no optim3 convect " << stateold << " " << state << " P= " << mp->P
4987              << " PP= " << mpp.P << endl;
4988       const Mesh3 &Th3(*mp->Th3);
4989       ffassert(mp->Th3 && mp->T3);
4990       R3 PHat = mpc.PHat;
4991 
4992       int k = 0;
4993       int j;
4994       int it = Th3(mpc.T3);
4995       if (ddd) cout << " IN: " << (*mpc.T3)(PHat) << " ; " << mpc.P << " : " << ddt << endl;
4996       while ((j = WalkInTet(
4997                 Th3, it, PHat,
4998                 R3(GetAny< double >((*u)(s)), GetAny< double >((*v)(s)), GetAny< double >((*w)(s))),
4999                 ddt)) >= 0)
5000         if (j > 3) {
5001           it = j - 4;
5002           mpc.change(PHat, Th3[it], 0);
5003           if (ddd)
5004             cout << "   **P= " << (*mpc.T3)(PHat) << " ,  Ph " << PHat << " : j = " << j
5005                  << " it:  " << it << "ddt=" << ddt;
5006           if (ddt == 0) break;    // finish ...
5007 
5008         } else {
5009           if (ddd)
5010             cout << "P= " << (*mpc.T3)(PHat) << " ,  Ph " << PHat << " : j = " << j
5011                  << " it:  " << it;
5012 #ifdef DEBUG
5013           R3 Po = (*mpc.T3)(PHat), Pho = PHat;
5014           int ito = it;
5015 #endif
5016           int itt = Th3.ElementAdj(it, j, PHat);
5017           if (ddd && itt >= 0)
5018             cout << "  -> " << itt << " " << j << "  : Pn " << Th3[itt](PHat) << " PHn " << PHat
5019                  << " , " << ddt << endl;
5020           if (itt < 0) break;
5021           it = itt;
5022           mpc.change(PHat, Th3[it], 0);
5023 #ifdef DEBUG
5024           if (((Po - mpc.P).norme2( ) > 1e-10)) {
5025             cout << ito << " " << &Th3[ito][0] << " " << &Th3[ito][1] << " " << &Th3[ito][2] << " "
5026                  << &Th3[ito][3] << " " << endl;
5027             cout << it << " " << &Th3[it][0] << " " << &Th3[it][1] << " " << &Th3[it][2] << " "
5028                  << &Th3[it][3] << endl;
5029             cout << Pho << "o Hat " << PHat << endl;
5030             cout << Po << " o != " << mpc.P << " diff= " << (Po - mpc.P).norme2( ) << endl;
5031             assert(0);
5032           }
5033 #endif
5034           ffassert(k++ < 2000);
5035         }
5036 
5037       mpc.change(PHat, Th3[it], 0);
5038       mpp = *mp;
5039       mps = mpc;
5040     }
5041   }
5042   AnyType r = (*ff)(s);
5043   MeshPointStack(s, mp);
5044   return r;
5045 }
5046 
eval3(Stack s) const5047 AnyType Convect::eval3(
5048   Stack s) const {    // nouvelle version de convect 3d Feb 2015  version 3.44-01
5049   MeshPoint *mp(MeshPointStack(s)), mpc(*mp);
5050   MeshPointStack(s, &mpc);    // P  ptr on  variable mpc ...
5051   static MeshPoint mpp, mps;
5052   static R ddts;
5053   randwalk(-1);    // init randwalk
5054   R3 offset;
5055   R ddt = GetAny< double >((*dt)(s));
5056   if (ddt) {
5057     bool ddd = verbosity > 1000;
5058 
5059     if (*mp == mpp && ddt == ddts)
5060       mpc = mps;
5061     else {
5062       const Mesh3 &Th3(*mp->Th3);
5063       ffassert(mp->Th3 && mp->T3);
5064       R3 PHat = mpc.PHat;
5065 
5066       int k = 0;
5067       int j;
5068       int it = Th3(mpc.T3);
5069       if (ddd) cout << " IN: " << (*mpc.T3)(PHat) << " ; " << mpc.P << " : " << ddt << endl;
5070       while ((j = WalkInTetn(
5071                 Th3, it, PHat,
5072                 R3(GetAny< double >((*u)(s)), GetAny< double >((*v)(s)), GetAny< double >((*w)(s))),
5073                 ddt, offset)) >= 0)
5074         if (j > 3) {
5075           it = j - 4;
5076           mpc.change(PHat, Th3[it], 0);
5077           if (ddd)
5078             cout << "   **P= " << (*mpc.T3)(PHat) << " ,  Ph " << PHat << " : j = " << j
5079                  << " it:  " << it << "ddt=" << ddt;
5080           if (ddt == 0) break;    // finish ...
5081 
5082         } else {
5083           if (ddd)
5084             cout << "P= " << (*mpc.T3)(PHat) << " ,  Ph " << PHat << " : j = " << j
5085                  << " it:  " << it;
5086 #ifdef DEBUG
5087           R3 Po = (*mpc.T3)(PHat), Pho = PHat;
5088           int ito = it;
5089 #endif
5090           int itt = Th3.ElementAdj(it, j, PHat);
5091           if (ddd && itt >= 0)
5092             cout << "  -> " << itt << " " << j << "  : Pn " << Th3[itt](PHat) << " PHn " << PHat
5093                  << " , " << ddt << endl;
5094           if (itt < 0) break;
5095           it = itt;
5096           mpc.change(PHat, Th3[it], 0);
5097 #ifdef DEBUG
5098           if (((Po - mpc.P).norme2( ) > 1e-10)) {
5099             cout << ito << " " << &Th3[ito][0] << " " << &Th3[ito][1] << " " << &Th3[ito][2] << " "
5100                  << &Th3[ito][3] << " " << endl;
5101             cout << it << " " << &Th3[it][0] << " " << &Th3[it][1] << " " << &Th3[it][2] << " "
5102                  << &Th3[it][3] << endl;
5103             cout << Pho << "o Hat " << PHat << endl;
5104             cout << Po << " o != " << mpc.P << " diff= " << (Po - mpc.P).norme2( ) << endl;
5105             assert(0);
5106           }
5107 #endif
5108           ffassert(k++ < 2000);
5109         }
5110 
5111       mpc.change(PHat, Th3[it], 0);
5112       mpp = *mp;
5113       mps = mpc;
5114     }
5115   }
5116   ddts = ddt;
5117   AnyType r = (*ff)(s);
5118   MeshPointStack(s, mp);
5119   return r;
5120 }
5121 
5122 template< class K >
5123 class Op3_pfe2K : public ternary_function< pair< FEbase< K, v_fes > *, int >, R, R, K > {
5124  public:
5125   class Op : public E_F0mps {
5126    public:
5127     Expression a, b, c;
Op(Expression aa,Expression bb,Expression cc)5128     Op(Expression aa, Expression bb, Expression cc)
5129       : a(aa), b(bb), c(cc) { /*cout << "Op3_pfe2K" << endl;*/
5130     }
operator ( )(Stack s) const5131     AnyType operator( )(Stack s) const {
5132       R xx(GetAny< R >((*b)(s)));
5133       R yy(GetAny< R >((*c)(s)));
5134       MeshPoint &mp = *MeshPointStack(s), mps = mp;
5135       mp.set(xx, yy, 0.0);
5136       AnyType ret = pfer2R< K, 0 >(s, (*a)(s));
5137       mp = mps;
5138       return ret;
5139     }
5140   };
5141 };
5142 
5143 
5144 // Add  FH 16032005
5145 class Op3_Mesh2mp : public ternary_function< pmesh *, R, R, MeshPoint * > {
5146  public:
5147   class Op : public E_F0mps {
5148    public:
5149     Expression a, b, c;
Op(Expression aa,Expression bb,Expression cc)5150     Op(Expression aa, Expression bb, Expression cc) : a(aa), b(bb), c(cc) {}
operator ( )(Stack s) const5151     AnyType operator( )(Stack s) const {
5152       R xx(GetAny< R >((*b)(s)));
5153       R yy(GetAny< R >((*c)(s)));
5154       pmesh *ppTh(GetAny< pmesh * >((*a)(s)));
5155       if (!ppTh || !*ppTh) ExecError("Op3_Mesh2mp unset mesh ??");
5156       pmesh pTh(*ppTh);
5157       MeshPoint *mp = new MeshPoint( );
5158       mp->set(xx, yy, 0.0);
5159       R2 PHat;
5160       bool outside;
5161       const Triangle *K = pTh->Find(mp->P.p2( ), PHat, outside);
5162       mp->set(*pTh, (R2)mp->P.p2( ), PHat, *K, 0, outside);
5163       return mp;
5164     }
5165   };
5166 };
5167 
5168 template< class RR, class AA = RR >
5169 class JumpOp : public E_F0mps {
5170  public:
5171   typedef RR R;
5172   typedef AA A;
5173   typedef RR result_type;
5174   typedef AA argument_type;
5175 
5176   Expression a;
5177 
5178  public:
operator ( )(Stack stack) const5179   AnyType operator( )(Stack stack) const {    // a faire
5180     A rd, rg;
5181     MeshPoint *mp = MeshPointStack(stack), smp = *mp;
5182     rg = GetAny< A >((*a)(stack));
5183     rd = 0.;    // to be compatible with varf def... FH april 2014 ... v 3.31.
5184     if (mp->SetAdj( )) rd = GetAny< A >((*a)(stack));
5185     *mp = smp;
5186     return SetAny< R >(rd - rg);    //  external - internal
5187   }
JumpOp(Expression aa)5188   JumpOp(Expression aa) : a(aa) {}
5189 };
5190 
5191 template< class RR, class AA = RR >
5192 class MeanOp : public E_F0mps {
5193  public:
5194   typedef RR R;
5195   typedef AA A;
5196   typedef RR result_type;
5197   typedef AA argument_type;
5198 
5199   Expression a;
5200 
5201  public:
operator ( )(Stack stack) const5202   AnyType operator( )(Stack stack) const {    // a faire
5203     A rd, rg;
5204     MeshPoint *mp = MeshPointStack(stack), smp = *mp;
5205     rg = GetAny< A >((*a)(stack));
5206     rd = rg;
5207     if (mp->SetAdj( )) rd = GetAny< A >((*a)(stack));
5208     *mp = smp;
5209     return SetAny< R >((rg + rd) * 0.5);
5210   }
MeanOp(Expression aa)5211   MeanOp(Expression aa) : a(aa) {}
5212 };
5213 
5214 template< class RR, class AA = RR >
5215 class OthersideOp : public E_F0mps {
5216  public:
5217   typedef RR R;
5218   typedef AA A;
5219   typedef RR result_type;
5220   typedef AA argument_type;
5221 
5222   Expression a;
5223 
5224  public:
operator ( )(Stack stack) const5225   AnyType operator( )(Stack stack) const {    // a faire
5226     A rd, rg;
5227     MeshPoint *mp = MeshPointStack(stack), smp = *mp;
5228     rd = 0.;
5229     if (mp->SetAdj( )) rd = GetAny< A >((*a)(stack));
5230     *mp = smp;
5231     return SetAny< R >(rd);
5232   }
OthersideOp(Expression aa)5233   OthersideOp(Expression aa) : a(aa) {}
5234 };
5235 
get_size(pferarray const & a)5236 long get_size(pferarray const &a) { return a.first->N; }
get_size(pfecarray const & a)5237 long get_size(pfecarray const &a) { return a.first->N; }
get_size(pferbasearray * const & a)5238 long get_size(pferbasearray *const &a) { return (**a).N; }
get_size(pfecbasearray * const & a)5239 long get_size(pfecbasearray *const &a) { return (**a).N; }
get_size(pf3rarray const & a)5240 long get_size(pf3rarray const &a) { return a.first->N; }
get_size(pf3rbasearray * const & a)5241 long get_size(pf3rbasearray *const &a) { return (**a).N; }
get_size(pf3carray const & a)5242 long get_size(pf3carray const &a) { return a.first->N; }
get_size(pf3cbasearray * const & a)5243 long get_size(pf3cbasearray *const &a) { return (**a).N; }
resize(pferbasearray * const & a,long const & n)5244 long resize(pferbasearray *const &a, long const &n) {
5245   (**a).resize(n);
5246   return n;
5247 }
5248 
resize(pfecbasearray * const & a,long const & n)5249 long resize(pfecbasearray *const &a, long const &n) {
5250   (**a).resize(n);
5251   return n;
5252 }
5253 
get_element(pferbasearray * const & a,long const & n)5254 pferbase *get_element(pferbasearray *const &a, long const &n) { return (**a)[n]; }
5255 
get_element(pferarray const & a,long const & n)5256 pfer get_element(pferarray const &a, long const &n) { return pfer(*(*a.first)[n], a.second); }
5257 
5258 //  complex case
get_element(pfecbasearray * const & a,long const & n)5259 pfecbase *get_element(pfecbasearray *const &a, long const &n) { return (**a)[n]; }
get_element(pfecarray const & a,long const & n)5260 pfec get_element(pfecarray const &a, long const &n) { return pfec(*(*a.first)[n], a.second); }
5261 //  end complex case
5262 
get_element(pmesh const & a,long const & n)5263 lgElement get_element(pmesh const &a, long const &n) { return lgElement(a, n); }
get_element(pmesh * const & a,long const & n)5264 lgElement get_element(pmesh *const &a, long const &n) { return lgElement(*a, n); }
5265 
get_belement(lgBoundaryEdge::BE const & a,long const & n)5266 lgBoundaryEdge get_belement(lgBoundaryEdge::BE const &a, long const &n) {
5267   return lgBoundaryEdge(a, n);
5268 }
5269 
get_adj(lgElement::Adj const & a,long * const & n)5270 lgElement get_adj(lgElement::Adj const &a, long *const &n) { return a.adj(*n); }
5271 
get_vertex(pmesh const & a,long const & n)5272 lgVertex get_vertex(pmesh const &a, long const &n) { return lgVertex(a, n); }
get_vertex(pmesh * const & a,long const & n)5273 lgVertex get_vertex(pmesh *const &a, long const &n) { return lgVertex(*a, n); }
get_element(lgElement const & a,long const & n)5274 lgVertex get_element(lgElement const &a, long const &n) { return a[n]; }
get_belement(lgBoundaryEdge const & a,long const & n)5275 lgVertex get_belement(lgBoundaryEdge const &a, long const &n) { return a[n]; }
5276 
getx(lgVertex const & a)5277 R getx(lgVertex const &a) { return a.x( ); }
5278 
gety(lgVertex const & a)5279 R gety(lgVertex const &a) { return a.y( ); }
getlab(lgVertex const & a)5280 long getlab(lgVertex const &a) { return a.lab( ); }
getlab(lgElement const & a)5281 long getlab(lgElement const &a) { return a.lab( ); }
getlab(lgBoundaryEdge const & a)5282 long getlab(lgBoundaryEdge const &a) { return a.lab( ); }
5283 
getarea(lgElement const & a)5284 double getarea(lgElement const &a) { return a.area( ); }
getlength(lgBoundaryEdge const & a)5285 double getlength(lgBoundaryEdge const &a) { return a.length( ); }
getElement(lgBoundaryEdge const & a)5286 lgElement getElement(lgBoundaryEdge const &a) { return a.Element( ); }
EdgeElement(lgBoundaryEdge const & a)5287 long EdgeElement(lgBoundaryEdge const &a) { return a.EdgeElement( ); }
5288 
5289 template< class A >
DestroyKN(Stack,const AnyType & x)5290 inline AnyType DestroyKN(Stack, const AnyType &x) {
5291   KN< A > *a = GetAny< KN< A > * >(x);
5292   for (int i = 0; i < a->N( ); i++) (*a)[i]->destroy( );
5293   a->destroy( );
5294   return Nothing;
5295 }
5296 template< class RR, class A, class B >
5297 RR *get_elementp_(const A &a, const B &b) {
5298   if (b < 0 || a->N( ) <= b) {
5299     cerr << " Out of bound  0 <=" << b << " < " << a->N( ) << " array type = " << typeid(A).name( )
5300          << endl;
5301     ExecError("Out of bound in operator []");
5302   }
5303   return &((*a)[b]);
5304 }
5305 
5306 template< class R >
set_initinit(R * const & a,const long & n)5307 R *set_initinit(R *const &a, const long &n) {
5308   SHOWVERB(cout << " set_init " << typeid(R).name( ) << " " << n << endl);
5309   a->init(n);
5310   for (int i = 0; i < n; i++) (*a)[i] = 0;
5311   return a;
5312 }
5313 
5314 template< class A >
DestroyKNmat(Stack,const AnyType & x)5315 inline AnyType DestroyKNmat(Stack, const AnyType &x) {
5316   KN< A > *a = GetAny< KN< A > * >(x);
5317   for (int i = 0; i < a->N( ); i++) (*a)[i].destroy( );
5318   a->destroy( );
5319   return Nothing;
5320 }
5321 
5322 template< class R >
set_initmat(R * const & a,const long & n)5323 R *set_initmat(R *const &a, const long &n) {
5324   SHOWVERB(cout << " set_init " << typeid(R).name( ) << " " << n << endl);
5325   a->init(n);
5326   for (int i = 0; i < n; i++) (*a)[i].init( );
5327   return a;
5328 }
5329 
init_mesh_array()5330 void init_mesh_array( ) {
5331   Dcl_Type< KN< pmesh > * >(0, ::DestroyKN< pmesh >);
5332   atype< KN< pmesh > * >( )->Add(
5333     "[", "",
5334     new OneOperator2_< pmesh *, KN< pmesh > *, long >(get_elementp_< pmesh, KN< pmesh > *, long >));
5335   TheOperators->Add("<-", new OneOperator2_< KN< pmesh > *, KN< pmesh > *, long >(&set_initinit));
5336   map_type_of_map[make_pair(atype< long >( ), atype< pmesh >( ))] =
5337     atype< KN< pmesh > * >( );    // vector
5338 
5339   // resize mars 2006 v2.4-1
5340   Dcl_Type< Resize< KN< pmesh > > >( );
5341   Add< KN< pmesh > * >("resize", ".",
5342                        new OneOperator1< Resize< KN< pmesh > >, KN< pmesh > * >(to_Resize));
5343   Add< Resize< KN< pmesh > > >(
5344     "(", "", new OneOperator2_< KN< pmesh > *, Resize< KN< pmesh > >, long >(resizeandclean1));
5345 }
5346 template< class RR, class A, class B >
5347 RR get_elementp(const A &a, const B &b) {
5348   if (b < 0 || a->N( ) <= b) {
5349     cerr << " Out of bound  0 <=" << b << " < " << a->N( ) << " array type = " << typeid(A).name( )
5350          << endl;
5351     ExecError("Out of bound in operator []");
5352   }
5353   return ((*a)[b]);
5354 }
5355 
5356 template< class T >
resizeandclean2(const Resize<T> & t,const long & n)5357 T *resizeandclean2(const Resize< T > &t, const long &n) {    // resizeandclean1
5358   int nn = t.v->N( );                                        // old size
5359 
5360   for (int i = n; i < nn; i++) {
5361     (*t.v)[i].destroy( );
5362     ;
5363   }    // clean
5364   t.v->resize(n);
5365   for (int i = nn; i < n; i++) {
5366     (*t.v)[i].init( );
5367   }
5368   return t.v;
5369 }
5370 
5371 template< class PMat >
ClearReturn(Stack stack,const AnyType & a)5372 AnyType ClearReturn(Stack stack, const AnyType &a) {
5373   // a ne faire que pour les variables local au return...
5374   //  pour l'instant on copie pour fqire mqrche
5375   // a repense  FH  mqi 20014....
5376   PMat *m = GetAny< PMat * >(a);
5377   m->increment( );
5378   Add2StackOfPtr2FreeRC(stack, m);
5379   return m;
5380 }
5381 
5382 template< class R >
DclTypeMatrix()5383 void DclTypeMatrix( ) {
5384   Dcl_Type< RNM_VirtualMatrix< R > * >( );    // ???????  ZZZZZZ
5385 
5386   Dcl_Type< Matrice_Creuse< R > * >(InitP< Matrice_Creuse< R > >, Destroy< Matrice_Creuse< R > >,
5387                                     ClearReturn< Matrice_Creuse< R > >);
5388   // newpMatrice_Creuse
5389   Dcl_Type< newpMatrice_Creuse< R > >( );          // to def new Matrice_Creuse
5390   Dcl_Type< Matrice_Creuse_Transpose< R > >( );    // matrice^t   (A')
5391 
5392   Dcl_Type< Matrice_Creuse_Transpose< R > >( );                   // matrice^t   (A')
5393   Dcl_Type< Matrice_Creuse_inv< R > >( );                         // matrice^-1   A^{-1}
5394   Dcl_Type< Matrice_Creuse_inv_trans< R > >( );                   // matrice^-1   A'^{-1}
5395   Dcl_Type< typename RNM_VirtualMatrix< R >::plusAx >( );         // A*x (A'*x)
5396   Dcl_Type< typename RNM_VirtualMatrix< R >::plusAtx >( );        // A^t*x (A'*x)
5397   Dcl_Type< typename RNM_VirtualMatrix< R >::solveAxeqb >( );     // A^-1*x (
5398   Dcl_Type< typename RNM_VirtualMatrix< R >::solveAtxeqb >( );    // A^t^-1*x
5399   Dcl_Type< Matrix_Prod< R, R > >( );
5400   Dcl_Type< list< tuple< R, MatriceCreuse< R > *, bool > > * >( );
5401 
5402   // resize mars 2006 v2.4-1
5403 
5404   // array of matrix   matrix[int] A(n);
5405   typedef Matrice_Creuse< R > Mat;
5406   typedef Mat *PMat;
5407   typedef KN< Mat > AMat;
5408   Dcl_Type< AMat * >(0, ::DestroyKNmat< Mat >);
5409 
5410   // init array
5411   TheOperators->Add("<-", new OneOperator2_< AMat *, AMat *, long >(&set_initmat));
5412   //  A[i]
5413   atype< AMat * >( )->Add(
5414     "[", "", new OneOperator2_< PMat, AMat *, long >(get_elementp_< Mat, AMat *, long >));
5415 
5416   // resize
5417   Dcl_Type< Resize< AMat > >( );
5418   Add< AMat * >("resize", ".", new OneOperator1< Resize< AMat >, AMat * >(to_Resize));
5419   Add< Resize< AMat > >("(", "",
5420                         new OneOperator2_< AMat *, Resize< AMat >, long >(resizeandclean2));
5421 
5422   // to declare matrix[int]
5423   map_type_of_map[make_pair(atype< long >( ), atype< PMat >( ))] = atype< AMat * >( );
5424 }
5425 
5426 template< class A, class B >
First(Stack,const AnyType & b)5427 AnyType First(Stack, const AnyType &b) {
5428   return SetAny< A >(GetAny< B >(b).first);
5429 }
5430 
5431 template< class K >
AddIncrement(Stack stack,const AnyType & a)5432 AnyType AddIncrement(Stack stack, const AnyType &a) {
5433   K m = GetAny< K >(a);
5434   m->increment( );
5435   Add2StackOfPtr2FreeRC(stack, m);
5436   if (verbosity > 1) cout << "AddIncrement:: increment + Add2StackOfPtr2FreeRC " << endl;
5437   return a;
5438 }
5439 
5440 // FE 3D volume
CConstantTFE3(const EConstantTypeOfFE3::T & v)5441 Type_Expr CConstantTFE3(const EConstantTypeOfFE3::T &v) {
5442   throwassert(map_type[typeid(EConstantTypeOfFE3::T).name( )]);
5443   return make_pair(map_type[typeid(EConstantTypeOfFE3::T).name( )], new EConstantTypeOfFE3(v));
5444 }
5445 
5446 // FE 3D surface
CConstantTFES(const EConstantTypeOfFES::T & v)5447 Type_Expr CConstantTFES(const EConstantTypeOfFES::T &v) {
5448   throwassert(map_type[typeid(EConstantTypeOfFES::T).name( )] != 0);
5449   return make_pair(map_type[typeid(EConstantTypeOfFES::T).name( )], new EConstantTypeOfFES(v));
5450 }
5451 
5452 // FE 3D curve
CConstantTFEL(const EConstantTypeOfFEL::T & v)5453 Type_Expr CConstantTFEL(const EConstantTypeOfFEL::T &v) {
5454   throwassert(map_type[typeid(EConstantTypeOfFEL::T).name( )] != 0);
5455   return make_pair(map_type[typeid(EConstantTypeOfFEL::T).name( )], new EConstantTypeOfFEL(v));
5456 }
5457 
5458 //  end --- call meth be ..
5459 // 2013 resize of array of fe function..
5460 template< typename T >
fepresize(const Resize1<T> & rt,const long & n)5461 T fepresize(const Resize1< T > &rt, const long &n) {
5462   (**(rt.v)).resize(n);
5463   return rt.v;
5464 }
5465 template< typename T >
feresize(const Resize1<T> & rt,const long & n)5466 T feresize(const Resize1< T > &rt, const long &n) {
5467   rt.v.first->resize(n);
5468   return rt.v;
5469 }
get_R3(R3 * p,long i)5470 double get_R3(R3 *p, long i) { return (*p)[i]; }
set_eqp(R3 * a,R3 * b)5471 R3 *set_eqp(R3 *a, R3 *b) {
5472   *a = *b;
5473   return a;
5474 }
5475         class opDotR3 : public OneOperator{
5476         public:
operator ()(Stack s) const5477             AnyType operator()(Stack s)  const {ffassert(0);return 0L;}
MeshIndependent() const5478             bool MeshIndependent() const { return false;}
5479 
opDotR3(aType A,aType B)5480             opDotR3(aType A, aType B): OneOperator(atype<C_F0>(),A,B) {}
opDotR3()5481             opDotR3(): OneOperator(atype<C_F0>(),atype<TransE_Array >(),atype<R3 *>()  ) {}
5482 
code(const basicAC_F0 &) const5483             E_F0 *  code(const basicAC_F0 & ) const {ffassert(0);}
5484             C_F0  code2(const basicAC_F0 &args) const;
5485         };
code2(const basicAC_F0 & args) const5486         C_F0  opDotR3::code2(const basicAC_F0 &args) const
5487         {
5488             bool ta =args[0].left()==atype<TransE_Array>();
5489             bool tb =args[1].left()==atype<E_Array>();
5490             ffassert(ta == !tb);
5491             const TransE_Array * tea=0;
5492             const E_Array * ea=0;
5493             C_F0 b= ta ? args[1] : args[0] ; // N
5494             if( ta)  tea = dynamic_cast<const TransE_Array*>((Expression) args[0]);
5495             if( tb)  ea = dynamic_cast<const E_Array*>((Expression) args[1]);
5496 
5497             ffassert( ea || tea );
5498             const E_Array & a=  ta ? *tea->v : *ea;
5499             int na=a.size();
5500             int nb=na;
5501             if(na <1 || na > 3 ) CompileError(" bad array  [ ...]'  ");
5502 
5503             KN<CC_F0> A(na), B(nb);
5504 
5505 
5506             for (int i=0;i<na;++i)
5507                 if(!ta)  A(i) = a[i];
5508                 else     A(i) = TryConj(a[i]);
5509 
5510             const char * xyz[] = { "x","y","z"};
5511             for (int i=0;i<nb;++i)
5512                 B[i] = C_F0(b,xyz[i]);
5513 
5514 
5515             CC_F0 ab;
5516             ab = C_F0(TheOperators,"*",A[0],B[0]);
5517             for (int i=1;i<na;++i)
5518                 ab = C_F0(TheOperators,"+",ab,C_F0(TheOperators,"*",A(i),B(i)));
5519 
5520             return ab;
5521 
5522 
5523         }
5524         // Add FH ...  mars 2020 for N'.x
5525 
5526 template< class Result, class A >
5527         class E_F_trans_A_Ptr_o_R : public E_F0 {
5528         public:
5529             typedef Result A::*ptr;
5530             Expression a0;
5531             ptr p;
E_F_trans_A_Ptr_o_R(Expression aa0,ptr pp)5532             E_F_trans_A_Ptr_o_R(Expression aa0, ptr pp) : a0(aa0), p(pp) {}
operator ( )(Stack s) const5533             AnyType operator( )(Stack s) const {
5534                 return SetAny< Result * >(&(GetAny< Transpose<A * > >((*a0)(s)).t->*p)); }
MeshIndependent() const5535             bool MeshIndependent( ) const { return a0->MeshIndependent( ); }
5536         };
5537 template<  class A >
5538         class OneOperator_trans_Ptr_o_R : public OneOperator {
5539             typedef double Result ;
5540             typedef double A::*ptr;
5541             ptr p;
5542 
5543         public:
code(const basicAC_F0 & args) const5544             E_F0 *code(const basicAC_F0 &args) const {
5545                 return new E_F_trans_A_Ptr_o_R< Result , A >(t[0]->CastTo(args[0]), p);
5546             }
OneOperator_trans_Ptr_o_R(ptr pp)5547             OneOperator_trans_Ptr_o_R(ptr pp) : OneOperator(atype< Result * >( ), atype< Transpose<A *> >( )), p(pp) {}
5548         };
5549 
init_lgfem()5550 void init_lgfem( ) {
5551   if (verbosity && (mpirank == 0)) cout << "lg_fem ";
5552 #ifdef HAVE_CADNA
5553   cout << "cadna ";
5554   cadna_init(-1);    // pas de fichier
5555 #endif
5556 
5557   Dcl_Type< MeshPoint * >( );
5558   Dcl_Type< R3 * >(::Initialize< R3 >);
5559   Dcl_Type< R2 * >(::Initialize< R2 >);
5560   Dcl_Type< Transpose<R3 *> >();
5561 
5562   map_type[typeid(R3 *).name( )] = new ForEachType< R3 * >(Initialize< R3 >);
5563   Dcl_TypeandPtr< pmesh >(0, 0, ::InitializePtr< pmesh >, ::DestroyPtr< pmesh >,
5564                           AddIncrement< pmesh >, NotReturnOfthisType);
5565   Dcl_TypeandPtr< pmesh3 >(0, 0, ::InitializePtr< pmesh3 >, ::DestroyPtr< pmesh3 >,
5566                            AddIncrement< pmesh3 >, NotReturnOfthisType);
5567   Dcl_TypeandPtr< pmeshS >(0, 0, ::InitializePtr< pmeshS >, ::DestroyPtr< pmeshS >,
5568                            AddIncrement< pmeshS >, NotReturnOfthisType);
5569   Dcl_TypeandPtr< pmeshL >(0, 0, ::InitializePtr< pmeshL >, ::DestroyPtr< pmeshL >,
5570                            AddIncrement< pmeshL >, NotReturnOfthisType);
5571   Dcl_Type< lgVertex >( );
5572   Dcl_Type< lgElement >( );
5573   Dcl_Type< lgElement::Adj >( );
5574 
5575   Dcl_Type< lgBoundaryEdge::BE >( );
5576   Dcl_Type< lgBoundaryEdge >( );
5577 
5578   atype< long >( )->AddCast(new E_F1_funcT< long, lgVertex >(Cast< long, lgVertex >),
5579                             new E_F1_funcT< long, lgElement >(Cast< long, lgElement >),
5580                             new E_F1_funcT< long, lgBoundaryEdge >(Cast< long, lgBoundaryEdge >));
5581 
5582   Dcl_Type< TypeOfFE * >( );
5583   Dcl_Type< TypeOfFE3 * >( );    // 3D volume
5584   Dcl_Type< TypeOfFES * >( );    // 3D surface
5585   Dcl_Type< TypeOfFEL * >( );    // 3D curve
5586   map_type[typeid(TypeOfFE3 *).name( )]->AddCast(
5587     new E_F1_funcT< TypeOfFE3 *, TypeOfFE * >(TypeOfFE3to2));
5588   map_type[typeid(TypeOfFES *).name( )]->AddCast(
5589     new E_F1_funcT< TypeOfFES *, TypeOfFE * >(TypeOfFESto2));
5590   map_type[typeid(TypeOfFEL *).name( )]->AddCast(
5591     new E_F1_funcT< TypeOfFEL *, TypeOfFE * >(TypeOfFELto2));
5592 
5593   DclTypeMatrix< R >( );
5594   DclTypeMatrix< Complex >( );
5595 
5596   Dcl_TypeandPtr< pferbase >( );         // il faut le 2 pour pourvoir initialiser
5597   Dcl_TypeandPtr< pferbasearray >( );    // il faut le 2 pour pourvoir initialiser
5598   Dcl_Type< pfer >( );
5599   Dcl_Type< pferarray >( );
5600   Dcl_Type< pferarray >( );
5601 
5602   //  pour des Func FE complex   // FH  v 1.43
5603   Dcl_TypeandPtr< pfecbase >( );         // il faut le 2 pour pourvoir initialiser
5604   Dcl_TypeandPtr< pfecbasearray >( );    // il faut le 2 pour pourvoir initialiser
5605   Dcl_Type< pfec >( );
5606   Dcl_Type< pfecarray >( );
5607   //  FH v 1.43
5608   // add  mai 2009 FH for 3d eigen value.
5609   Dcl_Type< FEbaseArrayKn< double > * >( );
5610   Dcl_Type< FEbaseArrayKn< Complex > * >( );
5611 
5612   // Dcl_Type< pmesharray *>(); // il faut le 2 pour pourvoir initialiser
5613 
5614   map_type[typeid(pfes).name( )] = new ForEachType< pfes >( );
5615   map_type[typeid(pfes *).name( )] = new ForEachTypePtrfspace< pfes, 2 >( );
5616 
5617   // Dcl type for 3D volume FE
5618   Dcl_TypeandPtr< pf3rbase >( );         // il faut le 2 pour pourvoir initialiser
5619   Dcl_TypeandPtr< pf3rbasearray >( );    // il faut le 2 pour pourvoir initialiser
5620   Dcl_Type< pf3r >( );
5621   Dcl_Type< pf3rarray >( );
5622 
5623   //  pour des Func FE complex   // FH  v 1.43
5624   Dcl_TypeandPtr< pf3cbase >( );         // il faut le 2 pour pourvoir initialiser
5625   Dcl_TypeandPtr< pf3cbasearray >( );    // il faut le 2 pour pourvoir initialiser
5626   Dcl_Type< pf3c >( );
5627   Dcl_Type< pf3carray >( );
5628 
5629   // Dcl type for 3D surface FE v 4.00
5630   Dcl_TypeandPtr< pfSrbase >( );         // il faut le 2 pour pourvoir initialiser
5631   Dcl_TypeandPtr< pfSrbasearray >( );    // il faut le 2 pour pourvoir initialiser
5632   Dcl_Type< pfSr >( );
5633   Dcl_Type< pfSrarray >( );
5634 
5635   //  pour des Func FE complex   // FH  v 4.00
5636   Dcl_TypeandPtr< pfScbase >( );         // il faut le 2 pour pourvoir initialiser
5637   Dcl_TypeandPtr< pfScbasearray >( );    // il faut le 2 pour pourvoir initialiser
5638   Dcl_Type< pfSc >( );
5639   Dcl_Type< pfScarray >( );
5640 
5641   // Dcl type for 3D curve FE v 4.5
5642   Dcl_TypeandPtr< pfLrbase >( );         // il faut le 2 pour pourvoir initialiser
5643   Dcl_TypeandPtr< pfLrbasearray >( );    // il faut le 2 pour pourvoir initialiser
5644   Dcl_Type< pfLr >( );
5645   Dcl_Type< pfLrarray >( );
5646 
5647   //  pour des Func FE complex
5648   Dcl_TypeandPtr< pfLcbase >( );         // il faut le 2 pour pourvoir initialiser
5649   Dcl_TypeandPtr< pfLcbasearray >( );    // il faut le 2 pour pourvoir initialiser
5650   Dcl_Type< pfLc >( );
5651   Dcl_Type< pfLcarray >( );
5652 
5653   //  cast of eigen value  mai 2009 ...
5654   map_type[typeid(FEbaseArrayKn< double > *).name( )]->AddCast
5655   (
5656     new E_F1_funcT< FEbaseArrayKn< double > *, pferbasearray >
5657      ( Cast< FEbaseArrayKn< double > *, pferbasearray >),
5658     new E_F1_funcT< FEbaseArrayKn< double > *, pferarray >
5659      ( First< FEbaseArrayKn< double > *, pferarray >),
5660 
5661    new E_F1_funcT< FEbaseArrayKn< double > *, pfSrbasearray >
5662    ( Cast< FEbaseArrayKn< double > *, pfSrbasearray >),
5663    new E_F1_funcT< FEbaseArrayKn< double > *, pfSrarray >
5664    ( First< FEbaseArrayKn< double > *, pfSrarray >),
5665 
5666    new E_F1_funcT< FEbaseArrayKn< double > *, pfLrbasearray >
5667    ( Cast< FEbaseArrayKn< double > *, pfLrbasearray >),
5668    new E_F1_funcT< FEbaseArrayKn< double > *, pfLrarray >
5669    ( First< FEbaseArrayKn< double > *, pfLrarray >),
5670 
5671     new E_F1_funcT< FEbaseArrayKn< double > *, pf3rbasearray >
5672      ( Cast< FEbaseArrayKn< double > *, pf3rbasearray >),
5673     new E_F1_funcT< FEbaseArrayKn< double > *, pf3rarray >
5674      ( First< FEbaseArrayKn< double > *, pf3rarray >)
5675 
5676   );
5677   map_type[typeid(FEbaseArrayKn< Complex > *).name( )]->AddCast
5678     (
5679     new E_F1_funcT< FEbaseArrayKn< Complex > *, pfecbasearray >
5680       (Cast< FEbaseArrayKn< Complex > *, pfecbasearray >),
5681     new E_F1_funcT< FEbaseArrayKn< Complex > *, pfecarray >
5682       (First< FEbaseArrayKn< Complex > *, pfecarray >),
5683 
5684      new E_F1_funcT< FEbaseArrayKn< Complex > *, pfScbasearray >
5685      (Cast< FEbaseArrayKn< Complex > *, pfScbasearray >),
5686      new E_F1_funcT< FEbaseArrayKn< Complex > *, pfScarray >
5687      (First< FEbaseArrayKn< Complex > *, pfScarray >),
5688 
5689      new E_F1_funcT< FEbaseArrayKn< Complex > *, pfLcbasearray >
5690      (Cast< FEbaseArrayKn< Complex > *, pfLcbasearray >),
5691      new E_F1_funcT< FEbaseArrayKn< Complex > *, pfLcarray >
5692      (First< FEbaseArrayKn< Complex > *, pfLcarray >),
5693 
5694     new E_F1_funcT< FEbaseArrayKn< Complex > *, pf3cbasearray >
5695       (Cast< FEbaseArrayKn< Complex > *, pf3cbasearray >),
5696     new E_F1_funcT< FEbaseArrayKn< Complex > *, pf3carray >
5697       (First< FEbaseArrayKn< Complex > *, pf3carray >));
5698 
5699   map_type[typeid(pfes3).name( )] = new ForEachType< pfes3 >( );                  // 3D volume
5700   map_type[typeid(pfes3 *).name( )] = new ForEachTypePtrfspace< pfes3, 3 >( );    // // 3D volume
5701 
5702   map_type[typeid(pfesS).name( )] = new ForEachType< pfesS >( );                  // 3D surface
5703   map_type[typeid(pfesS *).name( )] = new ForEachTypePtrfspace< pfesS, 4 >( );    // 3D surface
5704 
5705   map_type[typeid(pfesL).name( )] = new ForEachType< pfesL >( );                  // 3D curve
5706   map_type[typeid(pfesL *).name( )] = new ForEachTypePtrfspace< pfesL, 5 >( );    // 3D curve
5707 
5708   //
5709   Dcl_Type< const QuadratureFormular * >( );
5710   Dcl_Type< const QuadratureFormular1d * >( );
5711   Dcl_Type< const GQuadratureFormular< R3 > * >( );
5712   TheOperators->Add("\'",   new OneOperator1<Transpose<R3* >,R3* >(&Build<Transpose<R3* >,R3* >));
5713   TheOperators->Add("*",new opDotR3(atype<TransE_Array >(),atype< R3* >() )   );  // "N" a faire mais dur
5714   TheOperators->Add("*",new opDotR3(atype< Transpose<R3* > >(),atype<E_Array >() )   );  // "N" a faire mais dur
5715 
5716   Global.New("qf1pT", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_1));
5717   Global.New("qf1pTlump", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_1lump));
5718   Global.New("qf2pT", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_2));
5719   Global.New("qf2pT4P1", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_2_4P1));
5720   Global.New("qf5pT", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_5));
5721 
5722   Global.New("qf7pT", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_7));
5723   Global.New("qf9pT", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_9));
5724 
5725   Global.New("qf1pE", CConstant< const QuadratureFormular1d * >(&QF_GaussLegendre1));
5726   Global.New("qf2pE", CConstant< const QuadratureFormular1d * >(&QF_GaussLegendre2));
5727   Global.New("qf3pE", CConstant< const QuadratureFormular1d * >(&QF_GaussLegendre3));
5728   Global.New("qf4pE", CConstant< const QuadratureFormular1d * >(&QF_GaussLegendre4));
5729   Global.New("qf5pE", CConstant< const QuadratureFormular1d * >(&QF_GaussLegendre5));
5730   Global.New("qf1pElump", CConstant< const QuadratureFormular1d * >(&QF_LumpP1_1D));
5731 
5732   Global.New("qfV1", CConstant< const GQuadratureFormular< R3 > * >(&QuadratureFormular_Tet_1));
5733   Global.New("qfV2", CConstant< const GQuadratureFormular< R3 > * >(&QuadratureFormular_Tet_2));
5734   Global.New("qfV5", CConstant< const GQuadratureFormular< R3 > * >(&QuadratureFormular_Tet_5));
5735   Global.New("qfV1lump",
5736              CConstant< const GQuadratureFormular< R3 > * >(&QuadratureFormular_Tet_1lump));
5737 
5738   //  juste du code genere
5739 
5740   Global.New("wait", CConstant< bool * >(&TheWait));
5741   Global.New("NoUseOfWait", CConstant< bool * >(&NoWait));
5742   Global.New("NoGraphicWindow", CConstant< bool * >(&NoGraphicWindow));
5743 
5744   Dcl_Type< MeshPoint * >( );
5745   Dcl_Type< finconnue * >( );
5746   Dcl_Type< ftest * >( );
5747 
5748   Dcl_Type< foperator * >( );
5749   Dcl_Type< const BC_set * >( );                         // a set of boundary condition
5750   Dcl_Type< const Call_FormLinear< v_fes > * >( );       //   to set Vector
5751   Dcl_Type< const Call_FormBilinear< v_fes > * >( );     // to set Matrix
5752   Dcl_Type< const Call_FormLinear< v_fes3 > * >( );      //   to set Vector 3D volume
5753   Dcl_Type< const Call_FormBilinear< v_fes3 > * >( );    // to set Matrix 3D volume
5754   Dcl_Type< const Call_FormLinear< v_fesS > * >( );      //   to set Vector 3D surface
5755   Dcl_Type< const Call_FormBilinear< v_fesS > * >( );    // to set Matrix 3D surface
5756   Dcl_Type< const Call_FormLinear< v_fesL > * >( );      //   to set Vector 3D curve
5757   Dcl_Type< const Call_FormBilinear< v_fesL > * >( );    // to set Matrix 3D curve
5758   Dcl_Type< interpolate_f_X_1< double >::type >( );      // to make  interpolation x=f o X^1 ;
5759 
5760   map_type[typeid(const FormBilinear *).name( )] = new TypeFormBilinear;
5761   map_type[typeid(const FormLinear *).name( )] = new TypeFormLinear;
5762 
5763   aType t_C_args = map_type[typeid(const C_args *).name( )] = new TypeFormOperator;
5764   map_type[typeid(const Problem *).name( )] = new TypeSolve< false, Problem >;
5765   map_type[typeid(const Solve *).name( )] = new TypeSolve< true, Solve >;
5766   Dcl_Type< const IntFunction< double > * >( );
5767   Dcl_Type< const IntFunction< complex< double > > * >( );
5768   basicForEachType *t_solve = atype< const Solve * >( );
5769   basicForEachType *t_problem = atype< const Problem * >( );
5770   basicForEachType *t_fbilin = atype< const FormBilinear * >( );
5771 
5772   basicForEachType *t_flin = atype< const FormLinear * >( );
5773   basicForEachType *t_BC = atype< const BC_set * >( );
5774 
5775   /// Doxygen doc
5776   basicForEachType *t_form = atype< const C_args * >( );
5777 
5778   Dcl_Type< const CDomainOfIntegration * >( );
5779 
5780   atype< pmesh >( )->AddCast(new E_F1_funcT< pmesh, pmesh * >(UnRef< pmesh >));
5781   atype< pfes >( )->AddCast(new E_F1_funcT< pfes, pfes * >(UnRef< pfes >));
5782 
5783   atype< pferbase >( )->AddCast(new E_F1_funcT< pferbase, pferbase >(UnRef< pferbase >));
5784   atype< pfecbase >( )->AddCast(new E_F1_funcT< pfecbase, pfecbase >(UnRef< pfecbase >));
5785 
5786   Add< pfer >("[]", ".", new OneOperator1< KN< double > *, pfer >(pfer2vect< R >));
5787   Add< pfec >("[]", ".", new OneOperator1< KN< Complex > *, pfec >(pfer2vect< Complex >));
5788 
5789   Add< pfer >("(", "", new OneTernaryOperator< Op3_pfe2K< R >, Op3_pfe2K< R >::Op >);
5790   Add< pfec >("(", "", new OneTernaryOperator< Op3_pfe2K< Complex >, Op3_pfe2K< Complex >::Op >);
5791   Add< double >("(", "", new OneTernaryOperator< Op3_K2R< R >, Op3_K2R< R >::Op >);
5792   Add< Complex >("(", "", new OneTernaryOperator< Op3_K2R< Complex >, Op3_K2R< Complex >::Op >);
5793   Add< pmesh * >("(", "", new OneTernaryOperator< Op3_Mesh2mp, Op3_Mesh2mp::Op >);
5794 
5795   Add< MeshPoint * >("nuTriangle", ".", new OneOperator1< long, MeshPoint * >(mp_nuTriangle));
5796   Add< MeshPoint * >("region", ".", new OneOperator1< long, MeshPoint * >(mp_region));
5797 
5798   Add< pfer >("refresh", ".", new OneOperator1< bool, pfer >(pfer_refresh< R, v_fes >));
5799   Add< pfec >("refresh", ".", new OneOperator1< bool, pfec >(pfer_refresh< Complex, v_fes >));
5800 
5801   Add< pfer >("n", ".", new OneOperator1< long, pfer >(pfer_nbdf< R >));
5802   Add< pfec >("n", ".", new OneOperator1< long, pfec >(pfer_nbdf< Complex >));
5803   Add< pfer >("Th", ".", new OneOperator1< pmesh, pfer >(pfer_Th< R >));
5804   Add< pfec >("Th", ".", new OneOperator1< pmesh, pfec >(pfer_Th< Complex >));
5805 
5806   Add< pmesh * >("area", ".", new OneOperator1< double, pmesh * >(pmesh_area));
5807   Add< pmesh * >("mesure", ".", new OneOperator1< double, pmesh * >(pmesh_area));
5808   Add< pmesh * >("measure", ".", new OneOperator1< double, pmesh * >(pmesh_area));
5809   Add< pmesh * >("bordermeasure", ".",
5810                  new OneOperator1< double, pmesh * >(pmesh_bordermeasure));    // add june 2017 F.H
5811   Add< pmesh * >("nt", ".", new OneOperator1< long, pmesh * >(pmesh_nt));
5812   Add< pmesh * >("nbe", ".", new OneOperator1< long, pmesh * >(pmesh_nbe));
5813 
5814   Add< pmesh * >("nv", ".", new OneOperator1< long, pmesh * >(pmesh_nv));
5815 
5816   Add< pmesh * >("hmax", ".", new OneOperator1< double, pmesh * >(pmesh_hmax));
5817   Add< pmesh * >("hmin", ".", new OneOperator1< double, pmesh * >(pmesh_hmin));
5818 
5819   Add< pfes * >("ndof", ".", new OneOperator1< long, pfes * >(pVh_ndof));
5820   Add< pfes * >("Th", ".", new OneOperator1< pmesh, pfes * >(pVh_Th));
5821   Add< pfes * >("nt", ".", new OneOperator1< long, pfes * >(pVh_nt));
5822   Add< pfes * >("ndofK", ".", new OneOperator1< long, pfes * >(pVh_ndofK));
5823   Add< pfes * >("(", "", new OneTernaryOperator< pVh_ndf, pVh_ndf::Op >);
5824   /* FH: ne peux pas marcher, il faut passer aussi le nouveau Vh
5825    Add<pfes*>("(","", new OneBinaryOperator_st<pVh_renumber>  );
5826    */
5827 
5828   atype< Matrice_Creuse< R > * >( )->AddCast(new OneOperatorCode< pb2mat< R > >);
5829   atype< Matrice_Creuse< Complex > * >( )->AddCast(new OneOperatorCode< pb2mat< Complex > >);
5830 
5831   //   Add all Finite Element "P0","P1","P2","RT0", ...
5832   for (ListOfTFE *i = ListOfTFE::all; i; i = i->next) {
5833     ffassert(i->tfe);    // check
5834     AddNewFE(i->name, i->tfe);
5835   }
5836   static string LU = "LU";
5837   static string CG = "CG";
5838   static string GMRES = "GMRES";
5839   static string Crout = "CROUT";
5840   static string Cholesky = "Cholesky";
5841   static string UMFPACK = "UMFPACK";
5842   static string sparsesolver = "sparsesolver";
5843   static string sparsesolverSym = "sparsesolverSym";
5844   Global.New("LU", CConstant< string * >(&LU));
5845   Global.New(CG.c_str( ), CConstant< string * >(&CG));
5846   Global.New(GMRES.c_str( ), CConstant< string * >(&GMRES));
5847   Global.New("Crout", CConstant< string * >(&Crout));
5848   Global.New("Cholesky", CConstant< string * >(&Cholesky));
5849   Global.New(UMFPACK.c_str( ), CConstant< string * >(&UMFPACK));
5850   Global.New(sparsesolver.c_str( ), CConstant< string * >(&sparsesolver));
5851   Global.New(sparsesolverSym.c_str( ), CConstant< string * >(&sparsesolverSym));
5852 
5853   // old --
5854   //  init FESpace
5855   TheOperators->Add(
5856     "<-", new OneOperator2_< pfes *, pfes *, pmesh * >(&MakePtr2),
5857     new OneOperatorCode< OP_MakePtr2 >, new OneOperatorCode< OP_MakePtr3 >,
5858     new OneOperatorCode< OP_MakePtrS >, new OneOperatorCode< OP_MakePtrL >,
5859     new OpMake_pfes< pfes, Mesh, TypeOfFE, pfes_tefk >,
5860     new OpMake_pfes< pfes3, Mesh3, TypeOfFE3, pfes3_tefk >,
5861     new OpMake_pfes< pfesS, MeshS, TypeOfFES, pfesS_tefk >,    // add for 3D surface  FEspace
5862     new OpMake_pfes< pfesL, MeshL, TypeOfFEL, pfesL_tefk >);
5863   TheOperators->Add("=", new OneOperator2< R3 *, R3 *, R3 * >(&set_eqp));
5864 
5865   Add< MeshPoint * >("P", ".", new OneOperator_Ptr_o_R< R3, MeshPoint >(&MeshPoint::P));
5866   Add< MeshPoint * >("N", ".", new OneOperator_Ptr_o_R< R3, MeshPoint >(&MeshPoint::N));
5867   Add< R3 * >("x", ".", new OneOperator_Ptr_o_R< R, R3 >(&R3::x));
5868   Add< R3 * >("y", ".", new OneOperator_Ptr_o_R< R, R3 >(&R3::y));
5869   Add< R3 * >("z", ".", new OneOperator_Ptr_o_R< R, R3 >(&R3::z));
5870   Add< Transpose<R3 *> >("x", ".", new OneOperator_trans_Ptr_o_R< R3 >(&R3::x));
5871   Add< Transpose<R3 *> >("y", ".", new OneOperator_trans_Ptr_o_R< R3 >(&R3::y));
5872   Add< Transpose<R3 *> >("z", ".", new OneOperator_trans_Ptr_o_R< R3 >(&R3::z));
5873 
5874   Add< R2 * >("x", ".", new OneOperator_Ptr_o_R< R, R2 >(&R2::x));
5875   Add< R2 * >("y", ".", new OneOperator_Ptr_o_R< R, R2 >(&R2::y));
5876 
5877   Add< R3 * >("[", "", new OneOperator2< double, R3 *, long >(get_R3));
5878 
5879   Add< pmesh >("[", "", new OneOperator2_< lgElement, pmesh, long >(get_element));
5880   Add< pmesh * >("be", ".", new OneOperator1_< lgBoundaryEdge::BE, pmesh * >(Build));
5881   Add< lgElement >("adj", ".", new OneOperator1_< lgElement::Adj, lgElement >(Build));
5882   Add< lgBoundaryEdge::BE >(
5883     "(", "", new OneOperator2_< lgBoundaryEdge, lgBoundaryEdge::BE, long >(get_belement));
5884   Add< lgElement::Adj >("(", "", new OneOperator2_< lgElement, lgElement::Adj, long * >(get_adj));
5885   TheOperators->Add("==", new OneBinaryOperator< Op2_eq< lgElement, lgElement > >);
5886   TheOperators->Add("!=", new OneBinaryOperator< Op2_ne< lgElement, lgElement > >);
5887   TheOperators->Add("<", new OneBinaryOperator< Op2_lt< lgElement, lgElement > >);
5888   TheOperators->Add("<=", new OneBinaryOperator< Op2_le< lgElement, lgElement > >);
5889 
5890   Add< pmesh * >("[", "", new OneOperator2_< lgElement, pmesh *, long >(get_element));
5891   Add< pmesh >("(", "", new OneOperator2_< lgVertex, pmesh, long >(get_vertex));
5892   Add< pmesh * >("(", "", new OneOperator2_< lgVertex, pmesh *, long >(get_vertex));
5893 
5894   Add< lgElement >("[", "", new OneOperator2_< lgVertex, lgElement, long >(get_element));
5895   Add< lgBoundaryEdge >("[", "", new OneOperator2_< lgVertex, lgBoundaryEdge, long >(get_belement));
5896 
5897   Add< lgVertex >("x", ".", new OneOperator1_< R, lgVertex >(getx));
5898   Add< lgVertex >("y", ".", new OneOperator1_< R, lgVertex >(gety));
5899   Add< lgVertex >("label", ".", new OneOperator1_< long, lgVertex >(getlab));
5900   Add< lgElement >("label", ".", new OneOperator1_< long, lgElement >(getlab));
5901   Add< lgElement >("region", ".", new OneOperator1_< long, lgElement >(getlab));
5902   Add< lgElement >("area", ".", new OneOperator1_< double, lgElement >(getarea));
5903   Add< lgElement >("mesure", ".", new OneOperator1_< double, lgElement >(getarea));
5904   Add< lgElement >("measure", ".", new OneOperator1_< double, lgElement >(getarea));
5905   Add< lgBoundaryEdge >("length", ".", new OneOperator1_< double, lgBoundaryEdge >(getlength));
5906   Add< lgBoundaryEdge >("label", ".", new OneOperator1_< long, lgBoundaryEdge >(getlab));
5907   Add< lgBoundaryEdge >("Element", ".", new OneOperator1_< lgElement, lgBoundaryEdge >(getElement));
5908   Add< lgBoundaryEdge >("whoinElement", ".", new OneOperator1_< long, lgBoundaryEdge >(EdgeElement));
5909 
5910   // New FF language types. zzzfff is defined at [[file:lex.hpp::zzzfff]] as a pointer to an object
5911   // of class mylex
5912   // [[file:lex.hpp::class mylex]]. zzzfff->Add() is at [[file:lex.cpp::void mylex Add Key k aType
5913   // t]]. The lexer will then be called from the parser via [[file:../lglib/lg.ypp::yylex]]
5914 
5915   zzzfff->Add("R3", atype< R3 * >( ));
5916 
5917   // <<mesh_keyword>> pmesh is a pointer to Mesh [[file:../femlib/fem.hpp::class Mesh]] defined at
5918   // [[file:lgfem.hpp::typedef Mesh pmesh]]
5919   // pmesh is a pointer to Mesh
5920   zzzfff->Add("mesh", atype< pmesh * >( ));
5921   // pmesh3 is a pointer to Mesh3 defined at [[file:lgfem.hpp::typedef Mesh3 pmesh3]]
5922   zzzfff->Add("mesh3", atype< pmesh3 * >( ));
5923   // pmeshS is a pointer to MeshS defined at [[file:lgfem.hpp::typedef MeshS pmeshS]]
5924   zzzfff->Add("meshS", atype< pmeshS * >( ));
5925   // pmeshL is a pointer to MeshL defined at [[file:lgfem.hpp::typedef MeshL pmeshL]]
5926   zzzfff->Add("meshL", atype< pmeshL * >( ));
5927 
5928   zzzfff->Add("element", atype< lgElement >( ));
5929   zzzfff->Add("vertex", atype< lgVertex >( ));
5930   zzzfff->Add("matrix", atype< Matrice_Creuse< R > * >( ));
5931   zzzfff->Add("Cmatrix", atype< Matrice_Creuse< Complex > * >( ));    // a voir
5932 
5933   Global.Add("LinearCG", "(", new LinearCG< R >( ));          // old form  with rhs (must be zer
5934   Global.Add("LinearGMRES", "(", new LinearGMRES< R >( ));    // old form
5935   Global.Add("LinearGMRES", "(", new LinearGMRES< R >(1));    // old form  without rhs
5936   Global.Add("AffineGMRES", "(", new LinearGMRES< R >(1));    // New  better
5937   Global.Add("LinearCG", "(", new LinearCG< R >(1));          //  without right handsize
5938   Global.Add("AffineCG", "(", new LinearCG< R >(1));          //  without right handsize
5939   Global.Add("NLCG", "(", new LinearCG< R >(-1));             //  without right handsize
5940 
5941   zzzfff->AddF("varf", t_form);    //  var. form ~  <<varf>>
5942   zzzfff->AddF("solve", t_solve);
5943   zzzfff->AddF("problem", t_problem);
5944 
5945   Global.Add("jump", "(", new OneOperatorCode< Code_VF< Ftest, Code_Jump > >);
5946   Global.Add("jump", "(", new OneOperatorCode< Code_VF< Finconnue, Code_Jump > >);
5947   Global.Add("average", "(", new OneOperatorCode< Code_VF< Ftest, Code_Mean > >);
5948   Global.Add("average", "(", new OneOperatorCode< Code_VF< Finconnue, Code_Mean > >);
5949   Global.Add("mean", "(", new OneOperatorCode< Code_VF< Ftest, Code_Mean > >);
5950   Global.Add("mean", "(", new OneOperatorCode< Code_VF< Finconnue, Code_Mean > >);
5951   Global.Add("otherside", "(", new OneOperatorCode< Code_VF< Ftest, Code_OtherSide > >);
5952   Global.Add("otherside", "(", new OneOperatorCode< Code_VF< Finconnue, Code_OtherSide > >);
5953 
5954   Global.Add("conj", "(", new OneOperatorCode< CODE_conj< Finconnue > >);
5955   Global.Add("conj", "(", new OneOperatorCode< CODE_conj< Ftest > >);
5956   Global.Add("conj", "(", new OneOperatorCode< CODE_conj< Foperator > >);
5957   TheOperators->Add("\'", new OneOperatorCode< CODE_conj< Finconnue > >);
5958   TheOperators->Add("\'", new OneOperatorCode< CODE_conj< Ftest > >);
5959   TheOperators->Add("\'", new OneOperatorCode< CODE_conj< Foperator > >);
5960 
5961   Global.Add("dx", "(", new OneOperatorCode< CODE_Diff< Ftest, op_dx > >);
5962   Global.Add("dy", "(", new OneOperatorCode< CODE_Diff< Ftest, op_dy > >);
5963   Global.Add("dx", "(", new OneOperatorCode< CODE_Diff< Finconnue, op_dx > >);
5964   Global.Add("dy", "(", new OneOperatorCode< CODE_Diff< Finconnue, op_dy > >);
5965 
5966   Global.Add("dxx", "(", new OneOperatorCode< CODE_Diff< Ftest, op_dxx > >);
5967   Global.Add("dxy", "(", new OneOperatorCode< CODE_Diff< Ftest, op_dxy > >);
5968   Global.Add("dyx", "(", new OneOperatorCode< CODE_Diff< Ftest, op_dyx > >);
5969   Global.Add("dyy", "(", new OneOperatorCode< CODE_Diff< Ftest, op_dyy > >);
5970 
5971   Global.Add("dxx", "(", new OneOperatorCode< CODE_Diff< Finconnue, op_dxx > >);
5972   Global.Add("dyy", "(", new OneOperatorCode< CODE_Diff< Finconnue, op_dyy > >);
5973   Global.Add("dxy", "(", new OneOperatorCode< CODE_Diff< Finconnue, op_dxy > >);
5974   Global.Add("dyx", "(", new OneOperatorCode< CODE_Diff< Finconnue, op_dyx > >);
5975 
5976   Global.Add("on", "(", new OneOperatorCode< BC_set >);
5977 
5978   /// <<plot_keyword>> uses [[Plot]] and [[file:AFunction.hpp::OneOperatorCode]] and
5979   /// [[file:AFunction.hpp::Global]]
5980   Global.Add("plot", "(", new OneOperatorCode< Plot >);
5981   Global.Add("convect", "(", new OneOperatorCode< Convect >);
5982 
5983   TheOperators->Add("+", new OneOperatorCode< CODE_L_Add< Foperator > >,
5984                     new OneOperatorCode< CODE_L_Add< Ftest > >,
5985                     new OneOperatorCode< CODE_L_Add< Finconnue > >,
5986                     new OneOperatorCode< C_args >(t_C_args, t_C_args, t_C_args)
5987   );
5988   TheOperators->Add("-", new OneOperatorCode< CODE_L_Minus< Foperator > >,
5989     new OneOperatorCode< CODE_L_Minus< Ftest > >,
5990     new OneOperatorCode< CODE_L_Minus< Finconnue > >,
5991     new OneOperatorCode< CODE_L_Sub< Foperator > >,
5992     new OneOperatorCode< CODE_L_Sub< Ftest > >,
5993     new OneOperatorCode< CODE_L_Sub< Finconnue > >,
5994     new OneOperatorCode< C_args_minus >(t_C_args, t_C_args, t_fbilin),
5995     new OneOperatorCode< C_args_minus >(t_C_args, t_C_args, t_flin),
5996     new OneOperatorCode< Minus_Form< FormBilinear > >,
5997     new OneOperatorCode< Minus_Form< FormLinear > >
5998 
5999   );
6000 
6001   atype< const C_args * >( )->AddCast(new OneOperatorCode< C_args >(t_C_args, t_fbilin),
6002     new OneOperatorCode< C_args >(t_C_args, t_flin),
6003     new OneOperatorCode< C_args >(t_C_args, t_BC)
6004   );
6005 
6006   atype< const C_args * >( )->AddCast(
6007     new OneOperatorCode< C_args >(t_C_args, atype< DotSlash_KN_< R > >( )),
6008     new OneOperatorCode< C_args >(t_C_args, atype< KN< R > * >( )),
6009     new OneOperatorCode< C_args >(t_C_args, atype< DotStar_KN_< R > >( )),
6010     new OneOperatorCode< C_args >(t_C_args, atype< Matrice_Creuse< R > * >( )),
6011     new OneOperatorCode< C_args >(t_C_args, atype< RNM_VirtualMatrix< R >::plusAx >( )),
6012     new OneOperatorCode< C_args >(t_C_args, atype< RNM_VirtualMatrix< R >::plusAtx >( ))
6013 
6014   );
6015 
6016   atype< const C_args * >( )->AddCast(
6017     new OneOperatorCode< C_args >(t_C_args, atype< DotSlash_KN_< Complex > >( )),
6018     new OneOperatorCode< C_args >(t_C_args, atype< KN< Complex > * >( )),
6019     new OneOperatorCode< C_args >(t_C_args, atype< DotStar_KN_< Complex > >( )),
6020     new OneOperatorCode< C_args >(t_C_args, atype< Matrice_Creuse< Complex > * >( )),
6021     new OneOperatorCode< C_args >(t_C_args, atype< RNM_VirtualMatrix< Complex >::plusAx >( )),
6022     new OneOperatorCode< C_args >(t_C_args, atype< RNM_VirtualMatrix< Complex >::plusAtx >( ))
6023 
6024   );
6025 
6026   TheOperators->Add("*", new OneOperatorCode< CODE_L_Mul< Foperator, Ftest, Finconnue > >,
6027                     new OneOperatorCode< CODE_L_Mul< Foperator, Finconnue, Ftest > >);
6028 
6029   // Warning just double or complex in following operator
6030   // ----------------------------------------------------
6031   //   in case of  ambiguity we take the double version
6032   //   case    long -> double
6033   //           long -> complex
6034   TheOperators->Add("*", new OneOperatorCode< CODE_L_MulLR< Finconnue, double >, 20 >,
6035                     new OneOperatorCode< CODE_L_MulLR< Foperator, double >, 20 >,
6036                     new OneOperatorCode< CODE_L_MulLR< Ftest, double >, 20 >,
6037                     new OneOperatorCode< CODE_L_MulRL< double, Finconnue >, 20 >,
6038                     new OneOperatorCode< CODE_L_MulRL< double, Foperator >, 20 >,
6039                     new OneOperatorCode< CODE_L_MulRL< double, Ftest >, 20 >);
6040   TheOperators->Add("*", new OneOperatorCode< CODE_L_MulLR< Finconnue, Complex >, 10 >,
6041                     new OneOperatorCode< CODE_L_MulLR< Foperator, Complex >, 10 >,
6042                     new OneOperatorCode< CODE_L_MulLR< Ftest, Complex >, 10 >,
6043                     new OneOperatorCode< CODE_L_MulRL< Complex, Finconnue >, 10 >,
6044                     new OneOperatorCode< CODE_L_MulRL< Complex, Foperator >, 10 >,
6045                     new OneOperatorCode< CODE_L_MulRL< Complex, Ftest >, 10 >);
6046 
6047   TheOperators->Add("/", new OneOperatorCode< CODE_L_DivLR< Finconnue, double >, 20 >,
6048                     new OneOperatorCode< CODE_L_DivLR< Foperator, double >, 20 >,
6049                     new OneOperatorCode< CODE_L_DivLR< Ftest, double >, 20 >);
6050 
6051   TheOperators->Add("/", new OneOperatorCode< CODE_L_DivLR< Finconnue, Complex >, 10 >,
6052                     new OneOperatorCode< CODE_L_DivLR< Foperator, Complex >, 10 >,
6053                     new OneOperatorCode< CODE_L_DivLR< Ftest, Complex >, 10 >);
6054 
6055   // Warning just double or complex in previous operator
6056   // ----------------------------------------------------
6057 
6058   // TheOperators->Add("=",new OneOperatorCode<BC_set1<double> >);
6059 
6060   TheOperators->Add(
6061     "=", new OneOperator2< pmesh *, pmesh *, pmesh >(&set_eqdestroy_incr),
6062 
6063     new OneBinaryOperator< set_eq_array< KN_< double >, RNM_VirtualMatrix< R >::plusAx > >,
6064     new OneBinaryOperator<
6065       set_eq_array< KN_< double >, RNM_VirtualMatrix< R >::plusAtx > >,    // ZZ set_eq_array
6066     new OneBinaryOperator< set_eq_array< KN_< double >, RNM_VirtualMatrix< R >::solveAxeqb > >,
6067     new OneBinaryOperator< set_eq_array< KN_< double >, RNM_VirtualMatrix< R >::solveAtxeqb > >,
6068 
6069     new OpArraytoLinearForm< double, v_fes >(atype< KN_< double > >( ), false, false),
6070     new OpMatrixtoBilinearForm< double, v_fes >);
6071 
6072   TheOperators->Add("=",
6073                     new OpArraytoLinearForm< double, v_fes3 >(atype< KN_< double > >( ), false, false),    // 3D volume
6074                     new OpMatrixtoBilinearForm< double, v_fes3 >,        // 3D volume
6075                     new OpArraytoLinearForm< double, v_fesS >(atype< KN_< double > >( ), false, false),    // 3D surface
6076                     new OpMatrixtoBilinearForm< double, v_fesS >,        // 3D surface
6077                     new OpArraytoLinearForm< double, v_fesL >(atype< KN_< double > >( ), false, false),    // 3D curve
6078                     new OpMatrixtoBilinearForm< double, v_fesL >);       // 3D curve
6079 
6080   TheOperators->Add(
6081     "<-", new OpArraytoLinearForm< double, v_fes >(atype< KN< double > * >( ), true, true),
6082     new OpArraytoLinearForm< Complex, v_fes >(atype< KN< Complex > * >( ), true, true),
6083     new OpArraytoLinearForm< double, v_fes3 >(atype< KN< double > * >( ), true, true),    // 3D volume
6084     new OpArraytoLinearForm< Complex, v_fes3 >(atype< KN< Complex > * >( ), true, true),    // 3D volume
6085     new OpArraytoLinearForm< double, v_fesS >(atype< KN< double > * >( ), true, true),    // 3D surface
6086     new OpArraytoLinearForm< Complex, v_fesS >(atype< KN< Complex > * >( ), true, true),    // 3D surface
6087     new OpArraytoLinearForm< double, v_fesL >(atype< KN< double > * >( ), true, true),    // 3D curve
6088     new OpArraytoLinearForm< Complex, v_fesL >(atype< KN< Complex > * >( ), true, true)    // 3D curve
6089   );
6090 
6091   TheOperators->Add(
6092     "=",
6093     new OneBinaryOperator< set_eq_array< KN_< Complex >, RNM_VirtualMatrix< Complex >::plusAx > >,
6094     new OneBinaryOperator< set_eq_array< KN_< Complex >, RNM_VirtualMatrix< Complex >::plusAtx > >,
6095     new OneBinaryOperator<
6096       set_eq_array< KN_< Complex >, RNM_VirtualMatrix< Complex >::solveAxeqb > >,
6097     new OneBinaryOperator<
6098       set_eq_array< KN_< Complex >, RNM_VirtualMatrix< Complex >::solveAtxeqb > >,
6099 
6100     new OpArraytoLinearForm< Complex, v_fes >(atype< KN_< Complex >  >( ), false, false),
6101         // KN* -> KN_ FH Jan 2015 (Thank  PJolivet)
6102     new OpMatrixtoBilinearForm< Complex, v_fes >);
6103 
6104   TheOperators->Add("=",
6105                     new OpArraytoLinearForm< Complex, v_fes3 >(atype< KN_< Complex > >( ), false, false),    // 3D volume
6106                     new OpMatrixtoBilinearForm< Complex, v_fes3 >,        // 3D volume
6107                     new OpArraytoLinearForm< Complex, v_fesS >(atype< KN_< Complex > >( ), false, false),    // 3D surface
6108                     new OpMatrixtoBilinearForm< Complex, v_fesS >,        // 3D surface
6109                     new OpArraytoLinearForm< Complex, v_fesL >(atype< KN_< Complex > >( ), false, false),    // 3D curve
6110                     new OpMatrixtoBilinearForm< Complex, v_fesL >);       // 3D surface
6111 
6112   // add august 2007
6113   TheOperators->Add(
6114     "<-",
6115     new OneBinaryOperator< init_eqarray< KN< double >, RNM_VirtualMatrix< double >::plusAx > >,
6116     new OneBinaryOperator< init_eqarray< KN< double >, RNM_VirtualMatrix< double >::plusAtx > >,
6117     new OneBinaryOperator< init_eqarray< KN< double >, RNM_VirtualMatrix< double >::solveAxeqb > >,
6118     new OneBinaryOperator< init_eqarray< KN< double >, RNM_VirtualMatrix< double >::solveAtxeqb > >,
6119 
6120     new OneBinaryOperator< init_eqarray< KN< Complex >, RNM_VirtualMatrix< Complex >::plusAx > >,
6121     new OneBinaryOperator< init_eqarray< KN< Complex >, RNM_VirtualMatrix< Complex >::plusAtx > >,
6122     new OneBinaryOperator<
6123       init_eqarray< KN< Complex >, RNM_VirtualMatrix< Complex >::solveAxeqb > >,
6124     new OneBinaryOperator<
6125       init_eqarray< KN< Complex >, RNM_VirtualMatrix< Complex >::solveAtxeqb > >
6126 
6127   );
6128   // Jan 2018  FH  Vh uh=yu[]; //  A FAIRE FH POUR F NATAF FFFFFFFF
6129   TheOperators->Add(
6130     "<-", new init_FE_eqarray< FFset3< R, v_fes, RNM_VirtualMatrix< R >::plusAx > >(10),
6131     new init_FE_eqarray< FFset3< R, v_fes, RNM_VirtualMatrix< R >::solveAxeqb > >(10),
6132     new init_FE_eqarray< FFset3< R, v_fes, RNM_VirtualMatrix< R >::solveAtxeqb > >(10),
6133     new init_FE_eqarray< FFset3< R, v_fes, RNM_VirtualMatrix< R >::plusAtx > >(10),
6134     new init_FE_eqarray< FFset3< R, v_fes, KN_< R > > >(10),
6135     new init_FE_eqarray< FF_L_args< R, v_fes, Call_FormLinear< v_fes > > >(10)
6136 
6137   );
6138   TheOperators->Add(
6139     "<-", new init_FE_eqarray< FFset3< Complex, v_fes, RNM_VirtualMatrix< Complex >::plusAx > >(10),
6140     new init_FE_eqarray< FFset3< Complex, v_fes, RNM_VirtualMatrix< Complex >::solveAxeqb > >(10),
6141     new init_FE_eqarray< FFset3< Complex, v_fes, RNM_VirtualMatrix< Complex >::solveAtxeqb > >(10),
6142     new init_FE_eqarray< FFset3< Complex, v_fes, RNM_VirtualMatrix< Complex >::plusAtx > >(10),
6143     new init_FE_eqarray< FFset3< Complex, v_fes, KN_< Complex > > >(10),
6144     new init_FE_eqarray< FF_L_args< Complex, v_fes, Call_FormLinear< v_fes > > >(10));
6145   TheOperators->Add(
6146     "<-",
6147     new init_FE_eqarray< FFset3< R, v_fes3, RNM_VirtualMatrix< R >::plusAx > >(10)    // 3D volume
6148     ,
6149     new init_FE_eqarray< FFset3< R, v_fes3, RNM_VirtualMatrix< R >::solveAxeqb > >(
6150       10)    // 3D volume
6151     ,
6152     new init_FE_eqarray< FFset3< R, v_fes3, RNM_VirtualMatrix< R >::plusAtx > >(10)    // 3D volume
6153     ,
6154     new init_FE_eqarray< FFset3< R, v_fes3, KN_< R > > >(10)    // 3D volume
6155     ,
6156     new init_FE_eqarray< FF_L_args< R, v_fes3, Call_FormLinear< v_fes3 > > >(10)    // 3D volume
6157 
6158   );
6159   TheOperators->Add(
6160     "<-",
6161     new init_FE_eqarray< FFset3< Complex, v_fes3, RNM_VirtualMatrix< Complex >::plusAx > >(
6162       10)    // 3D volume
6163     ,
6164     new init_FE_eqarray< FFset3< Complex, v_fes3, RNM_VirtualMatrix< Complex >::solveAxeqb > >(
6165       10)    // 3D volume
6166     ,
6167     new init_FE_eqarray< FFset3< Complex, v_fes3, RNM_VirtualMatrix< Complex >::plusAtx > >(
6168       10)    // 3D volume
6169     ,
6170     new init_FE_eqarray< FFset3< Complex, v_fes3, KN_< Complex > > >(10)    // 3D volume
6171     ,
6172     new init_FE_eqarray< FF_L_args< Complex, v_fes3, Call_FormLinear< v_fes3 > > >(
6173       10)    // 3D volume
6174   );
6175 
6176   // Fin
6177   // Fin
6178   TheOperators->Add(
6179     "+=",
6180 
6181     new OneBinaryOperator< set_eq_array_add< KN_< double >, RNM_VirtualMatrix< double >::plusAx > >,
6182     new OneBinaryOperator<
6183       set_eq_array_add< KN_< double >, RNM_VirtualMatrix< double >::plusAtx > >,
6184 
6185     new OpArraytoLinearForm< double, v_fes >(atype< KN_< double > >( ), false, false, false),
6186     new OpArraytoLinearForm< double, v_fes3 >(atype< KN_< double > >( ), false, false,
6187                                               false),    // 3D volume
6188     new OpArraytoLinearForm< double, v_fesS >(atype< KN_< double > >( ), false, false,
6189                                               false),    // 3D surface
6190     new OpArraytoLinearForm< double, v_fesL >(atype< KN_< double > >( ), false, false,
6191                                               false)    // 3D surface
6192   );
6193 
6194   TheOperators->Add(
6195     "+=",
6196 
6197     new OneBinaryOperator<
6198       set_eq_array_add< KN_< Complex >, RNM_VirtualMatrix< Complex >::plusAx > >,
6199     new OneBinaryOperator<
6200       set_eq_array_add< KN_< Complex >, RNM_VirtualMatrix< Complex >::plusAtx > >,
6201 
6202     new OpArraytoLinearForm< Complex, v_fes >(atype< KN_< Complex > >( ), false, false, false),
6203 
6204     new OpArraytoLinearForm< Complex, v_fes3 >(atype< KN_< Complex > >( ), false, false,
6205                                                false),    // 3D volume
6206     new OpArraytoLinearForm< Complex, v_fesS >(atype< KN_< Complex > >( ), false, false,
6207                                                false),    // 3D surface
6208     new OpArraytoLinearForm< Complex, v_fesL >(atype< KN_< Complex > >( ), false, false,
6209                                                false)    // 3D curve
6210   );
6211 
6212   TheOperators->Add("<-", new OpMatrixtoBilinearForm< double, v_fes >(1));
6213   TheOperators->Add("<-", new OpMatrixtoBilinearForm< Complex, v_fes >(1));
6214 
6215   TheOperators->Add("<-", new OpMatrixtoBilinearForm< double, v_fes3 >(1));     // 3D volume
6216   TheOperators->Add("<-", new OpMatrixtoBilinearForm< Complex, v_fes3 >(1));    // 3D volume
6217 
6218   TheOperators->Add("<-", new OpMatrixtoBilinearForm< double, v_fesS >(1));     // 3D surface
6219   TheOperators->Add("<-", new OpMatrixtoBilinearForm< Complex, v_fesS >(1));    // 3D surface
6220 
6221   TheOperators->Add("<-", new OpMatrixtoBilinearForm< double, v_fesL >(1));     // 3D curve
6222   TheOperators->Add("<-", new OpMatrixtoBilinearForm< Complex, v_fesL >(1));    // 3D curve
6223 
6224   Add< const FormLinear * >("(", "", new OpCall_FormLinear< FormLinear, v_fes >);
6225   Add< const FormBilinear * >("(", "", new OpCall_FormBilinear< FormBilinear, v_fes >);
6226   Add< const FormBilinear * >("(", "", new OpCall_FormLinear2< FormBilinear, v_fes >);
6227   Add< const C_args * >("(", "", new OpCall_FormLinear2< C_args, v_fes >);
6228   Add< const C_args * >("(", "", new OpCall_FormBilinear< C_args, v_fes >);
6229 
6230   Add< const FormLinear * >("(", "", new OpCall_FormLinear< FormLinear, v_fes3 >);    // 3D volume
6231   Add< const FormBilinear * >("(", "", new OpCall_FormBilinear< FormBilinear, v_fes3 >); // 3D volume
6232   Add< const FormBilinear * >("(", "", new OpCall_FormLinear2< FormBilinear, v_fes3 >);    // 3D volume
6233   Add< const C_args * >("(", "", new OpCall_FormLinear2< C_args, v_fes3 >);       // 3D volume
6234   Add< const C_args * >("(", "", new OpCall_FormBilinear< C_args, v_fes3 >);      // 3D volume
6235 
6236   Add< const FormLinear * >("(", "", new OpCall_FormLinear< FormLinear, v_fesS >);    // 3D surface
6237   Add< const FormBilinear * >("(", "", new OpCall_FormBilinear< FormBilinear, v_fesS >);    // 3D surface
6238   Add< const FormBilinear * >("(", "", new OpCall_FormLinear2< FormBilinear, v_fesS >);    // 3D surface
6239   Add< const C_args * >("(", "", new OpCall_FormLinear2< C_args, v_fesS >);       // 3D surface
6240   Add< const C_args * >("(", "", new OpCall_FormBilinear< C_args, v_fesS >);      // 3D surface
6241 
6242   Add< const FormLinear * >("(", "", new OpCall_FormLinear< FormLinear, v_fesL >);    // 3D curve
6243   Add< const FormBilinear * >("(", "", new OpCall_FormBilinear< FormBilinear, v_fesL >);    // 3D curve
6244   Add< const FormBilinear * >("(", "", new OpCall_FormLinear2< FormBilinear, v_fesL >);    // 3D curve
6245   Add< const C_args * >("(", "", new OpCall_FormLinear2< C_args, v_fesL >);       // 3D curve
6246   Add< const C_args * >("(", "", new OpCall_FormBilinear< C_args, v_fesL >);      // 3D curve
6247 
6248 
6249 
6250 
6251   //  correction du bug morale
6252   //  Attention il y a moralement un bug
6253   //  les initialisation   x = y   ( passe par l'operateur binaire <-  dans TheOperators
6254   //   les initialisation   x(y)   ( passe par l'operateur unaire <-  de typedebase de x (inutile
6255   //   2007).
6256   //  x(y1,..,yn) est un operator n+1   (x,y1,..,yn)
6257   // on passe toujours par x(y) maintenant.
6258   //   -------
6259 
6260   TheOperators->Add("<-", new OneOperator2_< pferbase *, pferbase *, pfes * >(MakePtrFE2),
6261                     new OneOperator3_< pferbasearray *, pferbasearray *, pfes *, long >(MakePtrFE3),
6262 
6263                     new OneOperator2_< pfecbase *, pfecbase *, pfes * >(MakePtrFE2),
6264                     new OneOperator3_< pfecbasearray *, pfecbasearray *, pfes *, long >(MakePtrFE3)
6265 
6266   );
6267   TheOperators->Add(
6268     "<-",
6269     new OneOperatorMakePtrFE< double >(atype< double >( )),      //  scalar case
6270     new OneOperatorMakePtrFE< double >(atype< E_Array >( )),     //  vect case
6271     new OneOperatorMakePtrFE< Complex >(atype< Complex >( )),    //  scalar complex  case
6272     new OneOperatorMakePtrFE< Complex >(atype< E_Array >( ))     //  vect complex case
6273   );
6274   //  interpolation   operator
6275   TheOperators->Add(
6276     "=", new OneOperator2_< pfer, pfer, double, E_F_StackF0F0opt2< double > >(set_fe< double >),
6277     new OneOperator2_< pfec, pfec, Complex, E_F_StackF0F0opt2< Complex > >(set_fe< Complex >)
6278 
6279   );
6280 
6281   //  Attention il y a moralement un bug
6282   //  les initialisation   x = y   ( passe par l'operateur binaire <-  dans TheOperators
6283   //   les initialisation   x(y)   ( passe par l'operateur unaire <-  de typedebase de x
6284   //   -------  corrige
6285 
6286   TheOperators->Add("=", new OneOperator2< pfes *, pfes *, pfes >(&set_eqdestroy_incr),
6287                     new Op_CopyArray( ));
6288 
6289   TheOperators->Add("<-", new OneOperator2_< pfes *, pfes *, pfes >(&set_copy_incr));
6290 
6291   TheOperators->Add("<<", new OneBinaryOperator< PrintPnd< R3 * > >,
6292                     new OneBinaryOperator< PrintPnd< Matrice_Creuse< R > * > >,
6293                     new OneBinaryOperator< PrintPnd< Matrice_Creuse< Complex > * > >
6294 
6295   );
6296 
6297   TheOperators->Add(">>", new OneBinaryOperator< Op_Read< Matrice_Creuse< R > > >,
6298                     new OneBinaryOperator< Op_Read< Matrice_Creuse< Complex > > >
6299 
6300   );
6301 
6302   Global.Add("int2d", "(", new OneOperatorCode< CDomainOfIntegration >);
6303   Global.Add("int1d", "(", new OneOperatorCode< CDomainOfIntegrationBorder >);
6304   Global.Add("intalledges", "(", new OneOperatorCode< CDomainOfIntegrationAllEdges >);
6305   Global.Add("intallVFedges", "(", new OneOperatorCode< CDomainOfIntegrationVFEdges >);
6306   Global.Add("jump", "(", new OneUnaryOperator< JumpOp< R >, JumpOp< R > >);
6307   Global.Add("mean", "(", new OneUnaryOperator< MeanOp< R >, MeanOp< R > >);
6308   Global.Add("average", "(", new OneUnaryOperator< MeanOp< R >, MeanOp< R > >);
6309   Global.Add("otherside", "(", new OneUnaryOperator< OthersideOp< R >, OthersideOp< R > >);
6310 
6311   Global.Add("jump", "(", new OneUnaryOperator< JumpOp< Complex >, JumpOp< Complex > >);
6312   Global.Add("mean", "(", new OneUnaryOperator< MeanOp< Complex >, MeanOp< Complex > >);
6313   Global.Add("average", "(", new OneUnaryOperator< MeanOp< Complex >, MeanOp< Complex > >);
6314   Global.Add("otherside", "(",new OneUnaryOperator< OthersideOp< Complex >, OthersideOp< Complex > >);
6315 
6316   Add< const CDomainOfIntegration * >("(", "", new OneOperatorCode< FormBilinear >);
6317   Add< const CDomainOfIntegration * >("(", "", new OneOperatorCode< FormLinear >);
6318 
6319   Add< const CDomainOfIntegration * >("(", "", new OneOperatorCode< IntFunction< double >, 1 >);
6320   Add< const CDomainOfIntegration * >("(", "", new OneOperatorCode< IntFunction< complex< double > >, 0 >);
6321 
6322   map_type[typeid(double).name( )]->AddCast(new E_F1_funcT< double, pfer >(pfer2R< R, 0 >));
6323 
6324   map_type[typeid(Complex).name( )]->AddCast(new E_F1_funcT< Complex, pfec >(pfer2R< Complex, 0 >));
6325 
6326   // bof
6327   Global.Add("dx", "(", new E_F1_funcT< double, pfer >(pfer2R< R, op_dx >));
6328   Global.Add("dy", "(", new E_F1_funcT< double, pfer >(pfer2R< R, op_dy >));
6329   Global.Add("dxx", "(", new E_F1_funcT< double, pfer >(pfer2R< R, op_dxx >));
6330   Global.Add("dyy", "(", new E_F1_funcT< double, pfer >(pfer2R< R, op_dyy >));
6331   Global.Add("dxy", "(", new E_F1_funcT< double, pfer >(pfer2R< R, op_dxy >));
6332   Global.Add("dyx", "(", new E_F1_funcT< double, pfer >(pfer2R< R, op_dyx >));
6333 
6334   Global.Add("dx", "(", new E_F1_funcT< Complex, pfec >(pfer2R< Complex, op_dx >));
6335   Global.Add("dy", "(", new E_F1_funcT< Complex, pfec >(pfer2R< Complex, op_dy >));
6336   Global.Add("dxx", "(", new E_F1_funcT< Complex, pfec >(pfer2R< Complex, op_dxx >));
6337   Global.Add("dyy", "(", new E_F1_funcT< Complex, pfec >(pfer2R< Complex, op_dyy >));
6338   Global.Add("dxy", "(", new E_F1_funcT< Complex, pfec >(pfer2R< Complex, op_dxy >));
6339   Global.Add("dyx", "(", new E_F1_funcT< Complex, pfec >(pfer2R< Complex, op_dyx >));
6340 
6341   Add< pfecbasearray * >(
6342     "[", "",
6343     new OneOperator2_< pfecbase *, pfecbasearray *, long >(get_element));    // use FH sep. 2009
6344   Add< pferbasearray * >("[", "",
6345                          new OneOperator2_< pferbase *, pferbasearray *, long >(
6346                            get_element));    //  use ???? FH sep. 2009
6347   // bof bof ..
6348   // resize of array of Finite element ..  a little hard 2013 FH
6349   Dcl_Type< Resize1< pfecbasearray * > >( );
6350   Dcl_Type< Resize1< pferbasearray * > >( );
6351   Dcl_Type< Resize1< pfecarray > >( );
6352   Dcl_Type< Resize1< pferarray > >( );
6353   Add< pfecbasearray * >(
6354     "resize", ".",
6355     new OneOperator1< Resize1< pfecbasearray * >, pfecbasearray * >(to_Resize1));    //  FH fev 2013
6356   Add< pferbasearray * >("resize", ".",
6357                          new OneOperator1< Resize1< pferbasearray * >, pferbasearray * >(
6358                            to_Resize1));    //   FH fev. 2013
6359   Add< pferarray >(
6360     "resize", ".",
6361     new OneOperator1< Resize1< pferarray >, pferarray >(to_Resize1));    //  FH fev 2013
6362   Add< pfecarray >(
6363     "resize", ".",
6364     new OneOperator1< Resize1< pfecarray >, pfecarray >(to_Resize1));    //   FH fev. 2013
6365   new OneOperator2_< pferbasearray *, Resize1< pferbasearray * >, long >(
6366     fepresize< pferbasearray * >);
6367   Add< Resize1< pferbasearray * > >(
6368     "(", "", new OneOperator2_< pferbasearray *, Resize1< pferbasearray * >, long >(fepresize));
6369   Add< Resize1< pfecbasearray * > >(
6370     "(", "", new OneOperator2_< pfecbasearray *, Resize1< pfecbasearray * >, long >(fepresize));
6371   Add< Resize1< pferarray > >("(", "",
6372                               new OneOperator2_< pferarray, Resize1< pferarray >, long >(feresize));
6373   Add< Resize1< pfecarray > >("(", "",
6374                               new OneOperator2_< pfecarray, Resize1< pfecarray >, long >(feresize));
6375 
6376   Dcl_Type< Resize1< pf3rbasearray * > >( );
6377   Dcl_Type< Resize1< pf3rarray > >( );
6378   Dcl_Type< Resize1< pf3cbasearray * > >( );    //   FH oct. 2016
6379   Dcl_Type< Resize1< pf3carray > >( );          //   FH oct. 2016
6380   Add< pf3rbasearray * >("resize", ".",
6381                          new OneOperator1< Resize1< pf3rbasearray * >, pf3rbasearray * >(
6382                            to_Resize1));    //   FH fev. 2013
6383   Add< pf3rarray >(
6384     "resize", ".",
6385     new OneOperator1< Resize1< pf3rarray >, pf3rarray >(to_Resize1));    //  FH fev 2013
6386   Add< pf3cbasearray * >("resize", ".",
6387                          new OneOperator1< Resize1< pf3cbasearray * >, pf3cbasearray * >(
6388                            to_Resize1));    //   FH oct. 2016
6389   Add< pf3carray >(
6390     "resize", ".",
6391     new OneOperator1< Resize1< pf3carray >, pf3carray >(to_Resize1));    //  FH Oct 2016
6392 
6393   Add< Resize1< pf3rbasearray * > >(
6394     "(", "", new OneOperator2_< pf3rbasearray *, Resize1< pf3rbasearray * >, long >(fepresize));
6395   Add< Resize1< pf3rarray > >("(", "",
6396                               new OneOperator2_< pf3rarray, Resize1< pf3rarray >, long >(feresize));
6397   Add< Resize1< pf3cbasearray * > >(
6398     "(", "",
6399     new OneOperator2_< pf3cbasearray *, Resize1< pf3cbasearray * >, long >(
6400       fepresize));    //  FH Oct 2016
6401   Add< Resize1< pf3carray > >(
6402     "(", "",
6403     new OneOperator2_< pf3carray, Resize1< pf3carray >, long >(feresize));    //  FH Oct 2016
6404 
6405   Dcl_Type< Resize1< pfSrbasearray * > >( );
6406   Dcl_Type< Resize1< pfSrarray > >( );
6407   Dcl_Type< Resize1< pfScbasearray * > >( );
6408   Dcl_Type< Resize1< pfScarray > >( );
6409   Add< pfSrbasearray * >(
6410     "resize", ".", new OneOperator1< Resize1< pfSrbasearray * >, pfSrbasearray * >(to_Resize1));
6411   Add< pfSrarray >("resize", ".", new OneOperator1< Resize1< pfSrarray >, pfSrarray >(to_Resize1));
6412   Add< pfScbasearray * >(
6413     "resize", ".", new OneOperator1< Resize1< pfScbasearray * >, pfScbasearray * >(to_Resize1));
6414   Add< pfScarray >("resize", ".", new OneOperator1< Resize1< pfScarray >, pfScarray >(to_Resize1));
6415 
6416   Add< Resize1< pfSrbasearray * > >(
6417     "(", "", new OneOperator2_< pfSrbasearray *, Resize1< pfSrbasearray * >, long >(fepresize));
6418   Add< Resize1< pfSrarray > >("(", "",
6419                               new OneOperator2_< pfSrarray, Resize1< pfSrarray >, long >(feresize));
6420   Add< Resize1< pfScbasearray * > >(
6421     "(", "", new OneOperator2_< pfScbasearray *, Resize1< pfScbasearray * >, long >(fepresize));
6422   Add< Resize1< pfScarray > >("(", "",
6423                               new OneOperator2_< pfScarray, Resize1< pfScarray >, long >(feresize));
6424 
6425   Dcl_Type< Resize1< pfLrbasearray * > >( );
6426   Dcl_Type< Resize1< pfLrarray > >( );
6427   Dcl_Type< Resize1< pfLcbasearray * > >( );
6428   Dcl_Type< Resize1< pfLcarray > >( );
6429   Add< pfLrbasearray * >(
6430     "resize", ".", new OneOperator1< Resize1< pfLrbasearray * >, pfLrbasearray * >(to_Resize1));
6431   Add< pfLrarray >("resize", ".", new OneOperator1< Resize1< pfLrarray >, pfLrarray >(to_Resize1));
6432   Add< pfLcbasearray * >(
6433     "resize", ".", new OneOperator1< Resize1< pfLcbasearray * >, pfLcbasearray * >(to_Resize1));
6434   Add< pfLcarray >("resize", ".", new OneOperator1< Resize1< pfLcarray >, pfLcarray >(to_Resize1));
6435 
6436   Add< Resize1< pfLrbasearray * > >(
6437     "(", "", new OneOperator2_< pfLrbasearray *, Resize1< pfLrbasearray * >, long >(fepresize));
6438   Add< Resize1< pfLrarray > >("(", "",
6439                               new OneOperator2_< pfLrarray, Resize1< pfLrarray >, long >(feresize));
6440   Add< Resize1< pfLcbasearray * > >(
6441     "(", "", new OneOperator2_< pfLcbasearray *, Resize1< pfLcbasearray * >, long >(fepresize));
6442   Add< Resize1< pfLcarray > >("(", "",
6443                               new OneOperator2_< pfLcarray, Resize1< pfLcarray >, long >(feresize));
6444   // end of resize ...
6445 
6446   Add< pfecbasearray * >("n", ".",
6447                          new OneOperator1_< long, pfecbasearray * >(get_size));    //  FH fev 2013
6448   Add< pferbasearray * >("n", ".",
6449                          new OneOperator1_< long, pferbasearray * >(get_size));    //   FH fev. 2013
6450   Add< pferarray >("n", ".", new OneOperator1_< long, pferarray >(get_size));      //  FH fev 2013
6451   Add< pfecarray >("n", ".", new OneOperator1_< long, pfecarray >(get_size));      //   FH fev. 2013
6452 
6453   Add< pf3rbasearray * >("n", ".",
6454                          new OneOperator1_< long, pf3rbasearray * >(get_size));    //   FH fev. 2013
6455   Add< pf3rarray >("n", ".", new OneOperator1_< long, pf3rarray >(get_size));      //  FH fev 2013
6456   Add< pf3cbasearray * >("n", ".",
6457                          new OneOperator1_< long, pf3cbasearray * >(get_size));    //   FH  Oct 2016
6458   Add< pf3carray >("n", ".", new OneOperator1_< long, pf3carray >(get_size));      //  FH Oct 2016
6459 
6460   Add< pferarray >("[", "",
6461                    new OneOperator2_FE_get_elmnt< double, v_fes >( ));    // new version FH sep 2009
6462   Add< pfecarray >("[", "", new OneOperator2_FE_get_elmnt< Complex, v_fes >( ));
6463 
6464   Add< pf3rarray >("[", "",
6465                    new OneOperator2_FE_get_elmnt< double, v_fes >( ));    // new version FH sep 2009
6466   Add< pf3carray >("[", "", new OneOperator2_FE_get_elmnt< Complex, v_fes >( ));    // FH Oct 2016
6467 
6468   TheOperators->Add(
6469     "\'",
6470     new OneOperator1< Matrice_Creuse_Transpose< R >, Matrice_Creuse< R > * >(
6471       &Build< Matrice_Creuse_Transpose< R >, Matrice_Creuse< R > * >),
6472     new OneOperator1< Matrice_Creuse_Transpose< Complex >, Matrice_Creuse< Complex > * >(
6473       &Build< Matrice_Creuse_Transpose< Complex >, Matrice_Creuse< Complex > * >));
6474 
6475   Add< pfer >("(", "", new interpolate_f_X_1< R >);
6476   TheOperators->Add(
6477     "=",
6478     new OneOperator2_< void, interpolate_f_X_1< R >::type, double, E_F_StackF0F0 >(set_feoX_1));
6479   init_lgmat( );
6480   init_mesh_array( );
6481 
6482   l2interpreter = new LinkToInterpreter;
6483   using namespace FreeFempp;
6484   FreeFempp::TypeVarForm< double >::Global = new TypeVarForm< double >( );
6485   FreeFempp::TypeVarForm< Complex >::Global = new TypeVarForm< Complex >( );
6486 
6487   Global.New("P13d", CConstantTFE3(&DataFE< Mesh3 >::P1));
6488   Global.New("P23d", CConstantTFE3(&DataFE< Mesh3 >::P2));
6489   Global.New("P03d", CConstantTFE3(&DataFE< Mesh3 >::P0));
6490   Global.New("RT03d", CConstantTFE3(&RT03d));
6491   Global.New("Edge03d", CConstantTFE3(&Edge03d));
6492   Global.New("P1b3d", CConstantTFE3(&P1bLagrange3d));
6493 
6494   Global.New("RT0S", CConstantTFES(&DataFE< MeshS >::RT0));
6495   Global.New("P2S", CConstantTFES(&DataFE< MeshS >::P2));
6496   Global.New("P1S", CConstantTFES(&DataFE< MeshS >::P1));
6497   Global.New("P0S", CConstantTFES(&DataFE< MeshS >::P0));
6498   Global.New("P1bS", CConstantTFES(&P1bLagrange_surf));
6499 
6500   Global.New("P2L", CConstantTFEL(&DataFE< MeshL >::P2));
6501   Global.New("P1L", CConstantTFEL(&DataFE< MeshL >::P1));
6502   Global.New("P0L", CConstantTFEL(&DataFE< MeshL >::P0));
6503 
6504   TEF2dtoS[FindFE2("P0")] = &DataFE< MeshS >::P0;
6505   TEF2dtoS[FindFE2("P1")] = &DataFE< MeshS >::P1;
6506   TEF2dtoS[FindFE2("P2")] = &DataFE< MeshS >::P2;
6507   TEF2dtoS[FindFE2("P1b")] = &P1bLagrange_surf;
6508   TEF2dtoS[FindFE2("RT0")] = &DataFE< MeshS >::RT0;
6509   TEF2dtoS[FindFE2("P1dc")] = &DataFE< MeshS >::RT0;
6510 
6511   TEF2dtoL[FindFE2("P0")] = &DataFE< MeshL >::P0;
6512   TEF2dtoL[FindFE2("P1")] = &DataFE< MeshL >::P1;
6513   TEF2dtoL[FindFE2("P2")] = &DataFE< MeshL >::P2;
6514 
6515   TEF2dto3d[FindFE2("P1")] = &DataFE< Mesh3 >::P1;
6516   TEF2dto3d[FindFE2("P2")] = &DataFE< Mesh3 >::P2;
6517   TEF2dto3d[FindFE2("P0")] = &DataFE< Mesh3 >::P0;
6518   TEF2dto3d[FindFE2("P1b")] = &P1bLagrange3d;
6519   TEF2dto3d[FindFE2("RT0")] = &RT03d;
6520 }
6521 
clean_lgfem()6522 void clean_lgfem( ) {
6523   delete l2interpreter;
6524   delete FreeFempp::TypeVarForm< double >::Global;
6525   delete FreeFempp::TypeVarForm< Complex >::Global;
6526 }
6527 template< class K, class v_fes >
IsFEcomp(const C_F0 & c,int i,Expression & rrr,Expression & iii)6528 Expression IsFEcomp(const C_F0 &c, int i, Expression &rrr, Expression &iii) {
6529   Expression r = 0;
6530   if (!i) rrr = 0, iii = 0;
6531   if (atype< typename E_FEcomp< K, v_fes >::Result >( ) == c.left( )) {
6532     const E_FEcomp< K, v_fes > *e = dynamic_cast< const E_FEcomp< K, v_fes > * >(c.LeftValue( ));
6533     if (!e) {
6534       const E_FEcomp_get_elmnt_array< K, v_fes > *ee =
6535         dynamic_cast< const E_FEcomp_get_elmnt_array< K, v_fes > * >(c.LeftValue( ));
6536 
6537       if (!ee) {
6538         cerr << " Fatal error Copy array .." << *c.left( ) << " composante : " << i << endl;
6539         ffassert(ee);
6540       } else {
6541         if (ee->comp == i) {
6542           if (i && ee->a00->a0 != rrr)
6543             cerr << " error composante arry vect. incompatible " << ee->comp << " " << ee->a00->a0
6544                  << " != " << rrr << endl;
6545           else {
6546             r = ee->a0;
6547             rrr = ee->a00->a0;
6548             iii = ee->a1;
6549           }
6550 
6551         } else
6552           cerr << " erreur composante " << ee->comp << " != " << i << endl;
6553       }
6554     } else {
6555       if (e->comp == i) {
6556         if (i && e->a0 != rrr)
6557           cerr << " error composante incompatible " << e->comp << endl;
6558         else
6559           rrr = r = e->a0;
6560       } else
6561         cerr << " erreur composante " << e->comp << " != " << endl;
6562     }
6563   }
6564   return r;
6565 }
6566 
6567 template< class K, class v_fes >
Op_CopyArrayT(const E_Array & a,const E_Array & b)6568 Expression Op_CopyArrayT(const E_Array &a, const E_Array &b) {
6569   typedef FEbaseArray< K, v_fes > FEba;
6570 
6571   int nb = b.size( );
6572   Expression r = 0, rr = 0, rrr, iii;
6573   //  try real voctor value FE interpolation
6574   rr = IsFEcomp< K, v_fes >(a[0], 0, rrr, iii);
6575   if (rr != 0) {
6576     for (int i = 1; i < nb; i++)
6577       if (!IsFEcomp< K, v_fes >(a[i], i, rrr, iii))
6578         CompileError("Copy of Array with incompatible K  vector value FE function () !");
6579     ;
6580     if (iii) {
6581       C_F0 aa(rrr, atype< FEba ** >( )), ii(iii, atype< long >( ));
6582       C_F0 aa_ii(aa, "[", ii);
6583       rr = aa_ii.LeftValue( );
6584     }
6585     if (v_fes::dHat == 2 && v_fes::d == 2)
6586       r = new E_set_fev< K >(&b, rr, 2);
6587     else if (v_fes::dHat == 3 && v_fes::d == 3)
6588       r = new E_set_fev3< K, v_fes3 >(&b, rr);
6589     else if (v_fes::dHat == 2 && v_fes::d == 3)
6590       r = new E_set_fev3< K, v_fesS >(&b, rr);
6591     else if (v_fes::dHat == 1 && v_fes::d == 3)
6592       r = new E_set_fev3< K, v_fesL >(&b, rr);
6593   }
6594   //  try complex vector value FE interpolation
6595   return r;
6596 }
6597 
code(const basicAC_F0 & args) const6598 E_F0 *Op_CopyArray::code(const basicAC_F0 &args) const {
6599   E_F0 *ret = 0;
6600   const E_Array &a = *dynamic_cast< const E_Array * >(args[0].LeftValue( ));
6601   const E_Array &b = *dynamic_cast< const E_Array * >(args[1].LeftValue( ));
6602   int na = a.size( );
6603   int nb = b.size( );
6604   if (na != nb) CompileError("Copy of Array with incompatible size!");
6605   if (0) {    // old code !!!!!!! before removing FH sept. 2009
6606     Expression rr = 0, rrr, iii;
6607     //  try real voctor value FE interpolation
6608     rr = IsFEcomp< double, v_fes >(a[0], 0, rrr, iii);
6609     if (rr != 0) {
6610       for (int i = 1; i < nb; i++)
6611         if (!IsFEcomp< double, v_fes >(a[i], i, rrr, iii))
6612           CompileError("Copy of Array with incompatible real vector value FE function () !");
6613       ;
6614       return new E_set_fev< double >(&b, rr, 2);
6615     }
6616     //  try complex vector value FE interpolation
6617 
6618     rr = IsFEcomp< Complex, v_fes >(a[0], 0, rrr, iii);
6619     if (rr != 0) {
6620       for (int i = 1; i < nb; i++)
6621         if (!IsFEcomp< Complex, v_fes >(a[i], i, rrr, iii))
6622           CompileError("Copy of Array with incompatible complex vector value FE function () !");
6623       ;
6624       return new E_set_fev< Complex >(&b, rr, 2);
6625     }
6626 
6627     rr = IsFEcomp< double, v_fes3 >(a[0], 0, rrr, iii);
6628     if (rr != 0) {
6629       for (int i = 1; i < nb; i++)
6630         if (!IsFEcomp< double, v_fes3 >(a[i], i, rrr, iii))
6631           CompileError("Copy of Array with incompatible real vector value FE function () !");
6632       ;
6633       return new E_set_fev3< double, v_fes3 >(&b, rr);
6634     }
6635     //  try complex vector value FE interpolation
6636 
6637     rr = IsFEcomp< Complex, v_fes3 >(a[0], 0, rrr, iii);
6638     if (rr != 0) {
6639       for (int i = 1; i < nb; i++)
6640         if (!IsFEcomp< Complex, v_fes3 >(a[i], i, rrr, iii))
6641           CompileError("Copy of Array with incompatible complex vector value FE function () !");
6642       ;
6643       return new E_set_fev3< Complex, v_fes3 >(&b, rr);
6644     }
6645 
6646         rr = IsFEcomp< double, v_fesS >(a[0], 0, rrr, iii);
6647         if (rr != 0) {
6648         for (int i = 1; i < nb; i++)
6649         if (!IsFEcomp< double, v_fesS >(a[i], i, rrr, iii))
6650         CompileError("Copy of Array with incompatible real vector value FE function () !");
6651         ;
6652         return new E_set_fev3< double, v_fesS >(&b, rr);
6653         }
6654         //  try complex vector value FE interpolation
6655 
6656         rr = IsFEcomp< Complex, v_fesS >(a[0], 0, rrr, iii);
6657         if (rr != 0) {
6658         for (int i = 1; i < nb; i++)
6659         if (!IsFEcomp< Complex, v_fesS >(a[i], i, rrr, iii))
6660         CompileError("Copy of Array with incompatible complex vector value FE function () !");
6661         ;
6662         return new E_set_fev3< Complex, v_fesS >(&b, rr);
6663         }
6664 
6665         rr = IsFEcomp< double, v_fesL >(a[0], 0, rrr, iii);
6666         if (rr != 0) {
6667         for (int i = 1; i < nb; i++)
6668         if (!IsFEcomp< double, v_fesL >(a[i], i, rrr, iii))
6669         CompileError("Copy of Array with incompatible real vector value FE function () !");
6670         ;
6671         return new E_set_fev3< double, v_fesL >(&b, rr);
6672         }
6673         //  try complex vector value FE interpolation
6674 
6675         rr = IsFEcomp< Complex, v_fesL >(a[0], 0, rrr, iii);
6676         if (rr != 0) {
6677         for (int i = 1; i < nb; i++)
6678         if (!IsFEcomp< Complex, v_fesL >(a[i], i, rrr, iii))
6679         CompileError("Copy of Array with incompatible complex vector value FE function () !");
6680         ;
6681         return new E_set_fev3< Complex, v_fesL >(&b, rr);
6682         }
6683         }
6684 
6685 
6686 
6687         else {
6688     Expression r = 0;    // new code FH sep 2009.
6689     if (!r) r = Op_CopyArrayT< double, v_fes >(a, b);
6690     if (!r) r = Op_CopyArrayT< Complex, v_fes >(a, b);
6691     if (!r) r = Op_CopyArrayT< double, v_fes3 >(a, b);
6692     if (!r) r = Op_CopyArrayT< Complex, v_fes3 >(a, b);
6693     if (!r) r = Op_CopyArrayT< double, v_fesS >(a, b);
6694     if (!r) r = Op_CopyArrayT< Complex, v_fesS >(a, b);
6695     if (!r) r = Op_CopyArrayT< double, v_fesL >(a, b);
6696     if (!r) r = Op_CopyArrayT< Complex, v_fesL >(a, b);
6697     if (r) return r;
6698   }
6699   CompileError("Internal Error: General Copy of Array : to do ");
6700   return ret;
6701 }
6702 
6703 template< class v_fes, int DIM >
NewFEvariableT(ListOfId * pids,Block * currentblock,C_F0 & fespacetype,CC_F0 init,bool cplx,int dim)6704 C_F0 NewFEvariableT(ListOfId *pids, Block *currentblock, C_F0 &fespacetype, CC_F0 init, bool cplx,
6705                     int dim) {
6706   ffassert(dim == DIM);
6707   typedef FEbase< double, v_fes > FE;
6708   typedef E_FEcomp< R, v_fes > FEi;
6709   typedef typename FEi::Result FEiR;
6710 
6711   typedef FEbase< Complex, v_fes > CFE;
6712   typedef E_FEcomp< Complex, v_fes > CFEi;
6713   typedef typename CFEi::Result CFEiR;
6714 
6715   Expression fes = fespacetype;
6716 
6717   aType dcltype = atype< FE ** >( );
6718   aType cf0type = atype< C_F0 >( );
6719   aType rtype = atype< FEiR >( );
6720 
6721   if (cplx) {
6722     dcltype = atype< CFE ** >( );
6723     rtype = atype< CFEiR >( );
6724   }
6725   ffassert(pids);
6726   ListOfId &ids(*pids);
6727 
6728   string str("[");
6729 
6730   const int n = ids.size( );
6731   ffassert(n > 0);
6732   if (fes->nbitem( ) != (size_t)n) {
6733     cerr << " the array size must be " << fes->nbitem( ) << " not " << n << endl;
6734     CompileError("Invalide array size  for  vectorial fespace function");
6735   }
6736   for (int i = 0; i < n; i++) {
6737     str += ids[i].id;
6738     if (i < n - 1) str += ",";
6739   }
6740   str += "]";
6741   bool binit = !init.Empty( );
6742   char *name = strcpy(CodeAllocT< char >::New(str.size( ) + 1), str.c_str( ));
6743   C_F0 ret;
6744   // modif  100109 (add Block::  before NewVar for g++ 3.3.3 on Suse 9)
6745   ret = binit
6746           ? currentblock->Block::NewVar< LocalVariable >(name, dcltype,
6747                                                          basicAC_F0_wa(fespacetype, init))
6748           : currentblock->Block::NewVar< LocalVariable >(name, dcltype, basicAC_F0_wa(fespacetype));
6749   C_F0 base = currentblock->Find(name);
6750   if (cplx)
6751     for (int i = 0; i < n; i++)
6752       currentblock->NewID(cf0type, ids[i].id, C_F0(new CFEi(base, i, n), rtype));
6753   else
6754     for (int i = 0; i < n; i++)
6755       currentblock->NewID(cf0type, ids[i].id, C_F0(new FEi(base, i, n), rtype));
6756   delete pids;    // add FH 25032005
6757 
6758   return ret;
6759 }
6760 
NewFEvariable(ListOfId * pids,Block * currentblock,C_F0 & fespacetype,CC_F0 init,bool cplx,int dim)6761 C_F0 NewFEvariable(ListOfId *pids, Block *currentblock, C_F0 &fespacetype, CC_F0 init, bool cplx,
6762                    int dim) {
6763   if (dim == 2)
6764     return NewFEvariableT< v_fes, 2 >(pids, currentblock, fespacetype, init, cplx, dim);
6765   else if (dim == 3)
6766     return NewFEvariableT< v_fes3, 3 >(pids, currentblock, fespacetype, init, cplx, dim);
6767   else if (dim == 4)
6768     return NewFEvariableT< v_fesS, 4 >(pids, currentblock, fespacetype, init, cplx, dim);
6769   else if (dim == 5)
6770     return NewFEvariableT< v_fesL, 5 >(pids, currentblock, fespacetype, init, cplx, dim);
6771   else
6772     CompileError("Invalide fespace on Rd  ( d != 2 or 3) ");
6773   return C_F0( );
6774 }
NewFEvariable(const char * id,Block * currentblock,C_F0 & fespacetype,CC_F0 init,bool cplx,int dim)6775 C_F0 NewFEvariable(const char *id, Block *currentblock, C_F0 &fespacetype, CC_F0 init, bool cplx,
6776                    int dim) {
6777   ListOfId *lid = new ListOfId;
6778   lid->push_back(UnId(id));
6779   return NewFEvariable(lid, currentblock, fespacetype, init, cplx, dim);
6780 }
6781 
dimFESpaceImage(const basicAC_F0 & args)6782 size_t dimFESpaceImage(const basicAC_F0 &args) {
6783   aType t_tfe = atype< TypeOfFE * >( );
6784   aType t_tfe3 = atype< TypeOfFE3 * >( );
6785   aType t_tfeS = atype< TypeOfFES * >( );
6786   aType t_tfeL = atype< TypeOfFEL * >( );
6787   aType t_a = atype< E_Array >( );
6788   size_t dim23 = 0;
6789 
6790   for (int i = 0; i < args.size( ); i++)
6791     if (args[i].left( ) == t_tfe || args[i].left( ) == t_tfe3 || args[i].left( ) == t_tfeS ||
6792         args[i].left( ) == t_tfeL)
6793       dim23 += args[i].LeftValue( )->nbitem( );
6794     else if (args[i].left( ) == t_a) {
6795       const E_Array &ea = *dynamic_cast< const E_Array * >(args[i].LeftValue( ));
6796       ffassert(&ea);
6797       for (int i = 0; i < ea.size( ); i++)
6798         if (ea[i].left( ) == t_tfe || ea[i].left( ) == t_tfe3 || ea[i].left( ) == t_tfeS ||
6799             ea[i].left( ) == t_tfeL)
6800           dim23 += ea[i].nbitem( );
6801         else
6802           ffassert(0);    // bug
6803     }
6804   dim23 = dim23 ? dim23 : 1;
6805   return dim23;
6806 }
6807 
typeFESpace(const basicAC_F0 & args)6808 aType typeFESpace(const basicAC_F0 &args) {
6809   aType t_m2 = atype< pmesh * >( );
6810   aType t_m3 = atype< pmesh3 * >( );
6811   aType t_mS = atype< pmeshS * >( );
6812   aType t_mL = atype< pmeshL * >( );
6813 
6814   aType t_tfe = atype< TypeOfFE * >( );
6815   aType t_tfe3 = atype< TypeOfFE3 * >( );
6816   aType t_tfeS = atype< TypeOfFES * >( );
6817   aType t_tfeL = atype< TypeOfFEL * >( );
6818 
6819   aType atfe[] = {t_tfe, t_tfe3, t_tfeS, t_tfeL};
6820   aType atfs[] = {atype< pfes * >( ), atype< pfes3 * >( ), atype< pfesS * >( ),
6821                   atype< pfesL * >( )};
6822   aType t_a = atype< E_Array >( );
6823   aType ret = 0, tl = 0;
6824   aType tMesh = 0;
6825   int dm = -1, id = -2;
6826 
6827   for (int i = 0; i < args.size( ); i++) {
6828     tl = args[i].left( );
6829     if (tl == t_m2) {
6830       ffassert(dm == 2 || dm < 0);
6831       dm = 2;
6832     } else if (tl == t_m3) {
6833       ffassert(dm == 3 || dm < 0);
6834       dm = 3;
6835     } else if (tl == t_mS) {
6836       ffassert(dm == 4 || dm < 0);
6837       dm = 4;
6838     } else if (tl == t_mL) {
6839       ffassert(dm == 5 || dm < 0);
6840       dm = 5;
6841     }
6842     // array
6843     else if (tl == t_a) {
6844       const E_Array &ea = *dynamic_cast< const E_Array * >(args[i].LeftValue( ));
6845       ffassert(&ea);
6846       for (int i = 0; i < ea.size( ); i++) {
6847         tl = ea[i].left( );
6848         for (int it = 0; it < 4; ++it)
6849           if (atfe[it]->CastingFrom(tl))    // Warning  P1 can be cast in 2d or 3d FE ...
6850             id = it;
6851       }
6852     } else
6853       for (int it = 0; it < 4; ++it)
6854         if (atfe[it]->CastingFrom(tl)) id = it;
6855   }
6856 
6857   if (dm == 2)
6858     ret = atfs[0];    // 2D fespace
6859   else if (dm == 3)
6860     ret = atfs[1];    // 3D fespace (Volume)
6861   else if (dm == 4)
6862     ret = atfs[2];    // 3D fespace (surface)
6863   else if (dm == 5)
6864     ret = atfs[3];    // 3D fespace (curve)
6865   else {
6866     cerr << " typeFESpace:: bug dim: maes/EZFv mesh dim :" << dm << " type FE " << id + 2 << endl;
6867     ffassert(0);
6868   }
6869   if (verbosity > 99) cout << " typeFESpace " << id << " " << ret->name( ) << endl;
6870   return ret;
6871 }
6872 
6873 template< class v_fes, int DIM >
NewFEarrayT(ListOfId * pids,Block * currentblock,C_F0 & fespacetype,CC_F0 sizeofarray,bool cplx,int dim)6874 C_F0 NewFEarrayT(ListOfId *pids, Block *currentblock, C_F0 &fespacetype, CC_F0 sizeofarray,
6875                  bool cplx, int dim) {
6876   ffassert(dim == DIM || dim != 4);    // TODO
6877   typedef FEbaseArray< double, v_fes > FE;
6878   typedef E_FEcomp< R, v_fes, FE > FEi;
6879   typedef typename FEi::Result FEiR;
6880 
6881   typedef FEbaseArray< Complex, v_fes > CFE;
6882   typedef E_FEcomp< Complex, v_fes, CFE > CFEi;
6883   typedef typename CFEi::Result CFEiR;
6884 
6885   Expression fes = fespacetype;
6886   aType dcltype = atype< FE ** >( );
6887   aType cf0type = atype< C_F0 >( );
6888   aType rtype = atype< FEiR >( );
6889   ffassert(pids);
6890   ListOfId &ids(*pids);
6891   if (cplx) {
6892     dcltype = atype< CFE ** >( );
6893     rtype = atype< CFEiR >( );
6894   }
6895 
6896   string str("[");
6897 
6898   const int n = ids.size( );
6899   ffassert(n > 0);
6900   if (fes->nbitem( ) != (size_t)n) {
6901     cerr << " the array size must be " << fes->nbitem( ) << " not " << n << endl;
6902     CompileError("Invalid array size  for  vectorial fespace function");
6903   }
6904   for (int i = 0; i < n; i++) {
6905     str += ids[i].id;
6906     if (i < n - 1) str += ",";
6907   }
6908   str += "]";
6909   char *name = strcpy(CodeAllocT< char >::New(str.size( ) + 1), str.c_str( ));
6910   C_F0 ret = currentblock->Block::NewVar< LocalVariable >(name, dcltype,
6911                                                           basicAC_F0_wa(fespacetype, sizeofarray));
6912   C_F0 base = currentblock->Find(name);
6913   if (cplx)
6914     for (int i = 0; i < n; i++)
6915       currentblock->NewID(cf0type, ids[i].id, C_F0(new CFEi(base, i, n), rtype));
6916   else
6917     for (int i = 0; i < n; i++)
6918       currentblock->NewID(cf0type, ids[i].id, C_F0(new FEi(base, i, n), rtype));
6919 
6920   delete pids;    // add FH 25032005
6921   return ret;
6922 }
6923 
NewFEarray(ListOfId * pids,Block * currentblock,C_F0 & fespacetype,CC_F0 sizeofarray,bool cplx,int dim)6924 C_F0 NewFEarray(ListOfId *pids, Block *currentblock, C_F0 &fespacetype, CC_F0 sizeofarray,
6925                 bool cplx, int dim) {
6926   if (dim == 2)
6927     return NewFEarrayT< v_fes, 2 >(pids, currentblock, fespacetype, sizeofarray, cplx, dim);
6928   else if (dim == 3)
6929     return NewFEarrayT< v_fes3, 3 >(pids, currentblock, fespacetype, sizeofarray, cplx, dim);
6930   else if (dim == 4)
6931     return NewFEarrayT< v_fesS, 4 >(pids, currentblock, fespacetype, sizeofarray, cplx, dim);
6932   else if  (dim==5)
6933     return NewFEarrayT<v_fesL, 5 >(pids,currentblock,fespacetype,sizeofarray,cplx,dim);
6934   else
6935     CompileError("Invalid vectorial fespace on Rd  ( d != 2 or 3) ");
6936   return C_F0( );
6937 }
NewFEarray(const char * id,Block * currentblock,C_F0 & fespacetype,CC_F0 sizeofarray,bool cplx,int dim)6938 C_F0 NewFEarray(const char *id, Block *currentblock, C_F0 &fespacetype, CC_F0 sizeofarray,
6939                 bool cplx, int dim) {
6940   ListOfId *lid = new ListOfId;
6941   lid->push_back(UnId(id));
6942   return NewFEarray(lid, currentblock, fespacetype, sizeofarray, cplx, dim);
6943 }
6944 
6945 namespace Fem2D {
Expandsetoflab(Stack stack,const BC_set & bc,set<long> & setoflab)6946   void Expandsetoflab(Stack stack, const BC_set &bc, set< long > &setoflab) {
6947     for (size_t i = 0; i < bc.on.size( ); i++)
6948       if (bc.onis[i] == 0) {
6949         long lab = GetAny< long >((*bc.on[i])(stack));
6950         setoflab.insert(lab);
6951         if (verbosity > 99) cout << lab << " ";
6952 
6953       } else {
6954         KN< long > labs(GetAny< KN_< long > >((*bc.on[i])(stack)));
6955         for (long j = 0; j < labs.N( ); ++j) {
6956           setoflab.insert(labs[j]);
6957           if (verbosity > 99) cout << labs[j] << " ";
6958         }
6959       }
6960     if (verbosity > 99) cout << endl;
6961   }
6962 
Expandsetoflab(Stack stack,const CDomainOfIntegration & di,set<int> & setoflab,bool & all)6963   void Expandsetoflab(Stack stack, const CDomainOfIntegration &di, set< int > &setoflab,
6964                       bool &all) {
6965     for (size_t i = 0; i < di.what.size( ); i++)
6966       if (di.whatis[i] == 0) {
6967         long lab = GetAny< long >((*di.what[i])(stack));
6968         setoflab.insert(lab);
6969         if (verbosity > 3) cout << lab << " ";
6970         all = false;
6971       } else {
6972         KN< long > labs(GetAny< KN_< long > >((*di.what[i])(stack)));
6973         for (long j = 0; j < labs.N( ); ++j) {
6974           setoflab.insert(labs[j]);
6975           if (verbosity > 3) cout << labs[j] << " ";
6976         }
6977         all = false;
6978       }
6979   }
6980 }    // namespace Fem2D
6981 
6982 #include "InitFunct.hpp"
6983 
6984 static addingInitFunct TheaddingInitFunct(-20, init_lgfem);
6985