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