1 // -*- Mode : c++ -*-
2 //
3 // SUMMARY  :
4 // USAGE    :
5 // ORG      :
6 // AUTHOR   : Frederic Hecht
7 // E-MAIL   : hecht@ann.jussieu.fr
8 //
9 
10 /*
11 
12  This file is part of Freefem++
13 
14  Freefem++ is free software; you can redistribute it and/or modify
15  it under the terms of the GNU Lesser General Public License as published by
16  the Free Software Foundation; either version 2.1 of the License, or
17  (at your option) any later version.
18 
19  Freefem++  is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  GNU Lesser General Public License for more details.
23 
24  You should have received a copy of the GNU Lesser General Public License
25  along with Freefem++; if not, write to the Free Software
26  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27  */
28 #include  <iostream>
29 using namespace std;
30 
31 #include "rgraph.hpp"
32 #include "error.hpp"
33 #include "AFunction.hpp"
34 
35 //#include "lex.hpp"
36 #include "HashMatrix.hpp"
37 
38 #include "SparseLinearSolver.hpp"
39 #include "Mesh3dn.hpp"
40 #include "MeshPoint.hpp"
41 #include "lgfem.hpp"
42 #include "lgmesh3.hpp"
43 #include "lgsolver.hpp"
44 #include "problem.hpp"
45 #include <set>
46 
47 
48 
49 basicAC_F0::name_and_type  CDomainOfIntegration::name_param[]= {
50     { "qft", &typeid(const Fem2D::QuadratureFormular *)},
51     { "qfe", &typeid(const Fem2D::QuadratureFormular1d *)},
52     { "qforder",&typeid(long)},
53     { "qfnbpT",&typeid(long)},
54     { "qfnbpE",&typeid(long)},
55     { "optimize",&typeid(long)},
56     { "binside",&typeid(double)},
57     { "mortar",&typeid(bool)},
58     { "qfV", &typeid(const Fem2D::GQuadratureFormular<R3> *)},
59     { "levelset",&typeid(double)},
60     { "mapt",&typeid(E_Array)},
61     { "mapu",&typeid(E_Array)}
62 
63 
64 };
65 
66 basicAC_F0::name_and_type  Problem::name_param[]= {
67     {  "save",&typeid(string* )},
68     {  "cadna",&typeid(KN<double>*)},
69     {  "bmat",&typeid(Matrice_Creuse<R>* )},
70     LIST_NAME_PARM_MAT
71     /*
72      {  "init", &typeid(bool)},
73      {  "solver", &typeid(TypeSolveMat*)},
74      {  "eps", &typeid(double) },
75      {  "precon",&typeid(Polymorphic*)},
76      {  "dimKrylov",&typeid(long)},
77      {  "bmat",&typeid(Matrice_Creuse<R>* )},
78      {  "tgv",&typeid(double )},
79      {  "strategy",&typeid(long )},
80      {  "save",&typeid(string* )},
81      {  "cadna",&typeid(KN<double>*)},
82      {  "tolpivot", &typeid(double)},
83      {  "tolpivotsym", &typeid(double)},
84      {  "nbiter", &typeid(long)}, // 12
85      {   "paramint",&typeid(KN_<long>)}, // Add J. Morice 02/09
86      {   "paramdouble",&typeid(KN_<double>)},
87      {   "paramstring",&typeid(string *)},
88      {   "permrow",&typeid(KN_<long>)},
89      {   "permcol",&typeid(KN_<long>)},
90      {   "fileparamint",&typeid(string*)}, // Add J. Morice 02/09
91      {   "fileparamdouble",&typeid(string*)},
92      {   "fileparamstring",&typeid(string* )},
93      {   "filepermrow",&typeid(string*)},
94      {   "filepermcol",&typeid(string*)} //22
95      */
96 };
97 
98 struct pair_stack_double
99 {
100     Stack first;
101     double *second;
pair_stack_doublepair_stack_double102     pair_stack_double(Stack ss,double* bb) : first(ss),second(bb) {};
103 
104 };
105 
106 namespace Fem2D {
107 
108     void  Expandsetoflab(Stack stack,const CDomainOfIntegration & di,set<int> & setoflab,bool &all);
109     void  Expandsetoflab(Stack stack,const BC_set & bc,set<long> & setoflab);
110 
Check(const Opera & Op,int N,int M)111     void Check(const Opera &Op,int N,int  M)
112     {
113         int err=0;
114         for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++)
115         {  // attention la fonction test donne la ligne
116             //  et la fonction test est en second
117             BilinearOperator::K ll(*l);
118             pair<int,int> jj(ll.first.first),ii(ll.first.second);
119             if (ii.first <0 || ii.first >= M) err++;
120             if (jj.first <0 || jj.first >= N) err++;
121 
122         }
123         if (err) {
124             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++)
125             {  // attention la fonction test donne la ligne
126                 //  et la fonction test est en second
127                 BilinearOperator::K ll(*l);
128                 pair<int,int> jj(ll.first.first),ii(ll.first.second);
129                 cout << " +  " << jj.first << " " << jj.second << "*" << ii.first << " " << ii.second << endl;
130             }
131             ExecError("Check BilinearOperator N M");
132         }
133     }
Check(const BC_set * bc,int N)134     void Check(const  BC_set * bc,int N)
135     {
136         int err=0;
137         int kk=bc->bc.size();
138         for (int k=0;k<kk;k++)
139         {
140             pair<int,Expression> xx=bc->bc[k];
141             if (xx.first >= N) {
142                 err++;
143                 cerr << " Sorry : just " << N << " componant in FE space \n"
144                 << "   and Boundary condition refere to " << xx.first << "+1 componant " << endl;
145             }
146         }
147         if (err)
148         ExecError("Incompatibility beetwen  boundary condition  and FE space");
149     }
150 
Check(const Ftest * fl,int N)151     void Check(const  Ftest * fl,int N)
152     {
153         assert(fl);
154         int err=0;
155         Ftest::const_iterator kk= fl->v.end(),k;
156         int ii=0;
157         for (k=fl->v.begin();k<kk;k++)
158         {
159             ii++;
160             int j=k->first.first;
161             if (  j >= N) {
162                 err++;
163                 cerr << " Sorry : just " << N << " componant in FE space \n"
164                 << " and linear var form  refere to " << j << "+1 componant (part " << ii << ")" << endl;
165             }
166         }
167         if (err)
168         ExecError("Incompatibility beetwen linear varf  and FE space");
169     }
170   template<class R>
CheckErrorOptimisation(const R & ccc,const R & cc,const char * cmm)171   inline void  CheckErrorOptimisation(const R& ccc,const R& cc,const char * cmm)
172     {
173         if ( ccc != cc) {
174              if( (abs(ccc-cc) >1e-8*(abs(cc)+abs(ccc)) ) // test for round off err
175                  || (cc !=cc) ||  (ccc !=ccc) ) {// test for NaN
176                 cerr << cc << " != " << ccc <<  " diff "<< cc-ccc <<" => ";
177                 cerr << cmm << endl;
178                  cerr << " remark if you add  (..  ,   optimize=2) then  you remove this check (be carefull); "<< endl;
179                 ExecError("In Optimized version "); }}
180    }
CheckErrorOptimisation(const Complex ccc,const Complex & cc,const char * cmm)181     inline void  CheckErrorOptimisation(const Complex ccc,const Complex& cc,const char * cmm)
182     {
183         if ( ccc != cc) {
184             if( (abs(ccc.real()-ccc.real())+ abs(cc.imag()-cc.imag())  >0.5e-8*( abs(cc.real())+abs(cc.imag())+abs(ccc.real())+abs(ccc.imag()) ) )
185                 ||  (cc !=cc) ||  (ccc !=ccc) )
186             {
187                 cerr << cc << " != " << ccc <<  " diff "<< cc-ccc <<" => ";
188                 cerr << cmm << endl;
189                 cerr << " remark if you add  (..  ,   optimize=2) then  you remove this check (be carefull); " <<endl;
190 
191                 ExecError("In Optimized version "); }}
192     }
193 
194     //---------------------------------------------------------------------------------------
195     template<class R>
Element_OpVF(MatriceElementairePleine<R,FESpace3> & mat,const FElement3 & Ku,const FElement3 & KKu,const FElement3 & Kv,const FElement3 & KKv,double * p,int ie,int iie,int label,void * bstack,R3 * B)196     void  Element_OpVF(MatriceElementairePleine<R,FESpace3> & mat,
197                        const FElement3 & Ku,const FElement3 & KKu,
198                        const FElement3 & Kv,const FElement3 & KKv,
199                        double * p,int ie,int iie, int label,void *bstack,R3 *B)
200     {
201         ffassert(0);
202     }
203 
204     template<class R>
Element_OpVF(MatriceElementairePleine<R,FESpaceS> & mat,const FElementS & Ku,const FElementS & KKu,const FElementS & Kv,const FElementS & KKv,double * p,int ie,int iie,int label,void * bstack,R3 * B)205     void  Element_OpVF(MatriceElementairePleine<R,FESpaceS> & mat,
206                        const FElementS & Ku,const FElementS & KKu,
207                        const FElementS & Kv,const FElementS & KKv,
208                        double * p,int ie,int iie, int label,void *bstack,R3 *B)
209     {
210         ffassert(0);
211     }
212 
213     template<class R>
Element_OpVF(MatriceElementairePleine<R,FESpaceL> & mat,const FElementL & Ku,const FElementL & KKu,const FElementL & Kv,const FElementL & KKv,double * p,int ie,int iie,int label,void * bstack,R3 * B)214     void  Element_OpVF(MatriceElementairePleine<R,FESpaceL> & mat,
215                        const FElementL & Ku,const FElementL & KKu,
216                        const FElementL & Kv,const FElementL & KKv,
217                        double * p,int ie,int iie, int label,void *bstack,R3 *B)
218     {
219         ffassert(0);
220     }
221 
222     template<class R>
Element_OpVF(MatriceElementairePleine<R,FESpace> & mat,const FElement & Ku,const FElement & KKu,const FElement & Kv,const FElement & KKv,double * p,int ie,int iie,int label,void * bstack,R2 * B)223     void  Element_OpVF(MatriceElementairePleine<R,FESpace> & mat,
224                        const FElement & Ku,const FElement & KKu,
225                        const FElement & Kv,const FElement & KKv,
226                        double * p,int ie,int iie, int label,void *bstack,R2 *B)
227     {
228         ffassert(B==0);
229         pair_stack_double * bs=static_cast<pair_stack_double *>(bstack);
230         Stack stack= bs->first;
231         double binside = *bs->second; // truc FH pour fluide de grad2 (decentrage bizard)
232         assert(mat.onFace); //   Finite Volume or discontinous Galerkine
233         assert(ie>=0 && ie < 3); //  int on edge
234         MeshPoint mp= *MeshPointStack(stack);
235         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
236 
237         bool same = &Ku == & Kv;
238         assert(same);
239         const Triangle & T  = Ku.T;
240         int nTonEdge =  &Ku == &KKu ? 1 : 2;
241         double cmean = 1./nTonEdge;
242 
243         throwassert(&T == &Kv.T);
244         // const QuadratureFormular & FI = mat.FIT;
245         const QuadratureFormular1d & FIb = mat.FIE;
246         long npi;
247         R *a=mat.a;
248         R *pa=a;
249         long i,j;
250         long n= mat.n,m=mat.m,nx=n*m;
251         assert(nx<=mat.lga);
252         long N= Kv.N;
253         long M= Ku.N;
254 
255         long mu=Ku.NbDoF();
256         long mmu=KKu.NbDoF();
257         long nv=Kv.NbDoF();
258         long nnv=Kv.NbDoF();
259         assert(mu==mmu && nv == nnv) ;
260 
261 
262 
263         const Opera &Op(*mat.bilinearform);
264         bool classoptm = copt && Op.optiexpK;
265         //  if (Ku.number<1 && verbosity/100 && verbosity % 10 == 2)
266         if (Ku.number<1 && ( verbosity > 1 ) )
267         cout << "Element_OpVF P: copt = " << copt << " " << classoptm << " binside (For FH) =" << binside << " opt: " << mat.optim << endl;
268 
269 
270         KN<bool> Dop(last_operatortype); //  sinon ca plate bizarre
271         Op.DiffOp(Dop);
272         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
273         //assert(lastop<=3);
274         int lffv = nv*N*last_operatortype;
275         int lffu = mu*M*last_operatortype;
276         int loffset =  same ? 0 :  (nv+nnv)*N*last_operatortype;
277 
278         RNMK_ fv(p,nv,N,lastop); //  the value for basic fonction in K
279         RNMK_ ffv(p + lffv ,nnv,N,lastop); //  the value for basic fonction in KK
280         RNMK_ fu(  (double*) fv   + loffset  ,mu,M,lastop); //  the value for basic fonction
281         RNMK_ ffu( (double*) fu  + lffu  ,mmu,M,lastop); //  the value for basic fonction
282 
283         R2 E=T.Edge(ie);
284         double le = sqrt((E,E));
285         R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
286         PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]),
287         PC(TriangleHat[OppositeVertex[ie]]);
288         // warning the to edge are in opposite sens
289         R2 PP_A(TriangleHat[VerticesOfTriangularEdge[iie][1]]),
290         PP_B(TriangleHat[VerticesOfTriangularEdge[iie][0]]),
291         PP_C(TriangleHat[OppositeVertex[ie]]);
292         R2 Normal(E.perp()/-le);
293         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
294         {
295             pa =a;
296             QuadratureFormular1dPoint pi( FIb[npi]);
297             double coef = le*pi.a;
298             double sa=pi.x,sb=1-sa;
299             R2 Pt(PA*sa+PB*sb ); //
300             R2 PP_t(PP_A*sa+PP_B*sb ); //
301             if (binside) {
302                 Pt   = (1-binside)*Pt + binside*PC;
303                 PP_t  = (1-binside)*PP_t + binside*PP_C; }
304             Ku.BF(Dop,Pt,fu);
305             KKu.BF(Dop,PP_t,ffu);
306             if (!same) { Kv.BF(Dop,Pt,fv); KKv.BF(Dop,PP_t,ffv); }
307             // int label=-999999; // a passer en argument
308             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label, Normal,ie);
309             if (classoptm) (*Op.optiexpK)(stack); // call optim version
310 
311 
312             for ( i=0;  i<n;   i++ )
313             {
314                 int ik= mat.nik[i];
315                 int ikk=mat.nikk[i];
316 
317                 RNM_ wi(fv(Max(ik,0),'.','.'));
318                 RNM_ wwi(ffv(Max(ikk,0),'.','.'));
319 
320                 for ( j=0;  j<m;   j++,pa++ )
321                 {
322                     int jk= mat.njk[j];
323                     int jkk=mat.njkk[j];
324 
325                     RNM_ wj(fu(Max(jk,0),'.','.'));
326                     RNM_ wwj(ffu(Max(jkk,0),'.','.'));
327 
328                     int il=0;
329                     for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
330                     {
331                         BilinearOperator::K ll(*l);
332                         pair<int,int> jj(ll.first.first),ii(ll.first.second);
333                         int iis = ii.second, jjs=jj.second;
334 
335                         int iicase  = iis / last_operatortype;
336                         int jjcase  = jjs / last_operatortype;
337 
338                         iis %= last_operatortype;
339                         jjs %= last_operatortype;
340                         double w_i=0,w_j=0,ww_i=0,ww_j=0;
341 
342                         if(ik>=0) w_i =   wi(ii.first,iis );
343                         if(jk>=0) w_j =   wj(jj.first,jjs );
344 
345                         if( iicase>0 && ikk>=0) ww_i =  wwi(ii.first,iis );
346                         if( jjcase>0 && jkk>=0) ww_j =  wwj(jj.first,jjs );
347 
348 
349                         if       (iicase==Code_Jump) w_i = ww_i-w_i; // jump
350                         else  if (iicase==Code_Mean) {
351 
352                             w_i = cmean*  (w_i + ww_i );} // average
353                         else  if (iicase==Code_OtherSide) w_i = ww_i;  // valeur de autre cote
354 
355                         if      (jjcase==Code_Jump) w_j = ww_j-w_j; // jump
356                         else if (jjcase==Code_Mean) w_j = cmean*  (w_j +ww_j ); // average
357                         else if (jjcase==Code_OtherSide) w_j = ww_j;  //  valeur de l'autre cote
358 
359                         // R ccc = GetAny<R>(ll.second.eval(stack));
360 
361                         R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
362                         if ( copt && ( mat.optim==1) && Kv.number <1)
363                         {
364                             R cc  =  GetAny<R>(ll.second.eval(stack));
365                             CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization Element_OpVF2d  (b) add:   int2d(Th,optimize=0)(...)");
366                            /* if ( ccc != cc) {
367                                 cerr << cc << " != " << ccc << " => ";
368                                 cerr << "Sorry error in Optimization Element_OpVF2d  (b) add:  int2d(Th,optimize=0)(...)" << endl;
369                                 ExecError("In Optimized version "); }*/
370                         }
371                         *pa += coef * ccc * w_i*w_j;
372                     }
373                 }
374             }
375             // else pa += m;
376         }
377 
378 
379         pa=a;
380         if ( (verbosity > 9999) ||( (verbosity > 55) && (Ku.number <=0 || KKu.number <=0 )))  {
381             cout <<endl  << " edge between " << Ku.number << " , " <<  KKu.number   << " =  "<<  T[0] << ", " << T[1] << ", " << T[2] << " " << nx << endl;
382             cout << " K u, uu =  " << Ku.number << " " << KKu.number << " " <<  " K v, vv =  " << Kv.number << " " << KKv.number << " " <<endl;
383             for (int i=0;i<n;i++)
384             {
385                 cout << setw(2) << i << setw(4) << mat.ni[i] <<  setw(4) << mat.nik[i] << setw(4) << mat.nikk[i]  <<  " :";
386                 for (int j=0;j<m;j++)
387                 cout << setw(5)  << (*pa++) << " ";
388                 cout << endl;
389             } }
390 
391         *MeshPointStack(stack) = mp;
392     }
393 
394     //--------------------------------------------------------------------------------------
395 
396 
397 
398 
399     // creating an instance of AssembleBilinearForm with MatriceCreuse
400     // case 2d
401     // --------- FH 120105
402     template<class R>
AssembleBilinearForm(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,MatriceCreuse<R> & A,const FormBilinear * b)403     void AssembleBilinearForm(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
404                               MatriceCreuse<R>  & A, const  FormBilinear * b  )
405 
406     {
407         /*FH:  case ..in 2D
408          in varf ...
409          standard case ..
410          */
411         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
412         bool sptrclean=true;
413         const CDomainOfIntegration & di= *b->di;
414         const Mesh * pThdi = GetAny<pmesh>( (* di.Th)(stack));
415         if ( pThdi != &Th || &Uh.Th !=&Th || &Vh.Th !=&Th) {
416             cout << " --Use matrix formulation ---" << endl;
417             ExecError("No way to compute bilinear form with integrale of on mesh \n"
418                       "  test  or unkown function  defined on an other mesh! sorry to hard.   ");
419         }
420         SHOWVERB(cout << " FormBilinear " << endl);
421         double CPU0 = CPUtime();
422         MatriceElementaireSymetrique<R,FESpace> *mates =0;
423         MatriceElementairePleine<R,FESpace> *matep =0;
424         const int useopt=di.UseOpt(stack);
425         double binside=di.binside(stack);
426 
427         //const vector<Expression>  & what(di.what);
428         CDomainOfIntegration::typeofkind  kind = di.kind;
429         set<int> setoflab;
430         bool all=true;
431 
432         const Mesh & ThI = Th;// * GetAny<pmesh>( (* di.Th)(stack));
433         bool sameMesh = &ThI == &Vh.Th &&  &ThI == &Uh.Th;
434 
435         //    const QuadratureFormular1d & FIE = di.FIE(stack);
436         //    const QuadratureFormular & FIT = di.FIT(stack);
437         const QuadratureFormular1d & FIEo = di.FIE(stack);
438         const QuadratureFormular & FITo = di.FIT(stack);
439         // const GQuadratureFormular<R3> & FIVo = di.FIV(stack);
440         //  to change the quadrature on element ... may 2014 FH ..
441         QuadratureFormular1d  FIE(FIEo,3);
442         QuadratureFormular FIT(FITo,3);
443         // GQuadratureFormular<R3>  FIV(FIVo,3);
444 
445         bool VF=b->VF();  // finite Volume or discontinous Galerkin
446         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
447         if (verbosity>3)
448         {
449             if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ,"  ;
450             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
451             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
452             else cout << "  --  int    (nQP: "<< FIT.n << " ) in "  ;
453         }
454         //if(di.islevelset()) InternalError("So no levelset integration type on this case (6)");
455         if( di.withmap()) { ExecError(" no map  in the case (2)??");}
456         if(di.islevelset() && ( (CDomainOfIntegration::int1d!=kind) && (CDomainOfIntegration::int2d!=kind) )  )
457         InternalError("So no levelset integration type on no int1d case (6)");
458 
459         Expandsetoflab(stack,di, setoflab,all);
460         /*
461          for (size_t i=0;i<what.size();i++)
462          {
463          long  lab  = GetAny<long>( (*what[i])(stack));
464          setoflab.insert(lab);
465          if ( verbosity>3) cout << lab << " ";
466          all=false;
467          }*/
468         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
469         const E_F0 * poptiexp0=b->b->optiexp0;
470 
471         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
472         R** where_in_stack =0;
473         if (n_where_in_stack_opt && useopt)
474         where_in_stack = new R * [n_where_in_stack_opt];
475         if (where_in_stack)
476         {
477             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
478             for (int i=0;i<n_where_in_stack_opt;i++)
479             {
480                 int offset=b->b->where_in_stack_opt[i];
481                 assert(offset>10);
482                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
483                 *(where_in_stack[i])=0;
484             }
485 
486 
487             if(poptiexp0)
488             (*poptiexp0)(stack);
489             KN<bool> ok(b->b->v.size());
490             {  //   remove the zero coef in the liste
491                 // R zero=R();
492                 int il=0;
493                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
494                 ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
495             }
496             BilinearOperator b_nozer(*b->b,ok);
497             if (verbosity % 10 > 3 )
498             cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
499             << "  total " << n_where_in_stack_opt << endl;
500 
501             if ( (verbosity/100) % 10 >= 2)
502             {
503                 int il=0;
504 
505                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
506                 cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
507                 << " offset=" << b->b->where_in_stack_opt[il]
508                 << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
509             }
510         }
511         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
512         void *paramate=stack;
513         pair_stack_double parammatElement_OpVF(stack,& binside);
514         // parammatElement_OpVF.first = stack;
515         // parammatElement_OpVF.second= & binside;
516 
517         if (verbosity >3)
518         {
519             if (all) cout << " all " << endl ;
520             else cout << endl;
521         }
522         if(VF) {
523             if(&Uh != &Vh || sym)
524             cout << ("To Day in bilinear form with discontinous Galerkin (2d):   \n"
525                      "  test or unkown function must be  defined on the same FEspace, \n"
526                      "  and the matrix is not symmetric. \n"
527                      " To do other case in a future (F. Hecht) dec. 2003 ");
528             if(&Uh == &Vh)
529             matep= new MatriceElementairePleine<R,FESpace>(Uh,VF,FIT,FIE,useopt);
530             else
531             matep= new MatriceElementairePleine<R,FESpace>(Uh,Vh,VF,FIT,FIE,useopt);
532 
533 
534 
535             //      matep= new MatriceElementairePleine<R,FESpace>(Uh,Vh,VF,FIT,FIE);
536             matep->faceelement = Element_OpVF;
537             paramate= &parammatElement_OpVF;
538         }
539         else if (sym) {
540             mates= new MatriceElementaireSymetrique<R,FESpace>(Uh,FIT,FIE,useopt);
541             mates->element = Element_Op<R>;
542         }
543         else {
544             matep= new MatriceElementairePleine<R,FESpace>(Uh,Vh,FIT,FIE,useopt);
545             matep->element = Element_Op<R>;
546         }
547         MatriceElementaireFES<R,FESpace> & mate(*( sym? (MatriceElementaireFES<R,FESpace> *)mates : (MatriceElementaireFES<R,FESpace> *) matep));
548 
549 
550         mate.bilinearform=b->b;
551 
552         Check(*mate.bilinearform,mate.Uh.N,mate.Vh.N);
553         if(verbosity>9) cout << "  -- CPU init assemble mat " <<  CPUtime()-CPU0 << " s\n";
554 
555         if (di.kind == CDomainOfIntegration::int1d )
556         {
557             if(di.islevelset())
558             {
559                 double uset = HUGE_VAL;
560                 R2 Q[3];
561                 KN<double> phi(Th.nv);phi=uset;
562                 double f[3];
563                 for(int t=0; t< Th.nt;++t)
564                 {
565                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
566                     {
567                         double umx=-HUGE_VAL,umn=HUGE_VAL;
568                         for(int i=0;i<3;++i)
569                         {
570                             int j= ThI(t,i);
571                             if( phi[j]==uset)
572                             {
573                                 MeshPointStack(stack)->setP(&ThI,t,i);
574                                 phi[j]= di.levelset(stack);//zzzz
575                             }
576                             f[i]=phi[j];
577                             umx = std::max(umx,phi[j]);
578                             umn = std::min(umn,phi[j]);
579 
580                         }
581                         if( umn <=0 && umx >= 0)
582                         {
583 
584                             int np= IsoLineK(f,Q,1e-10);
585                             if(np==2)
586                             {
587                                 /* if ( sameMesh)
588                                  {
589 
590                                  Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIE,Q[0],Q[1]);
591                                  }
592                                  else*/
593                                 //   InternalError(" No levelSet on Diff mesh :    to day  int1d of Matrix");
594                                 A += mate(t,10,Th[t].lab,stack,Q);
595                             }
596                             if(sptrclean) sptrclean=sptr->clean();
597                         }
598                     }
599                 }
600             }
601             else for( int e=0;e<Th.neb;e++)
602             {
603                 if (all || setoflab.find(Th.bedges[e].lab) != setoflab.end())
604                 {
605                     int ie,i =Th.BoundaryElement(e,ie);
606                     A += mate(i,ie,Th.bedges[e].lab,stack);
607                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
608 
609                 }
610             }
611         }
612         else if (di.kind == CDomainOfIntegration::intalledges)
613         {
614             for (int i=0;i< Th.nt; i++)
615             {
616                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
617                 for (int ie=0;ie<3;ie++)
618                 { // modif F.H to get the correct label in intalledges
619                     int e0=VerticesOfTriangularEdge[ie][0];
620                     int e1=VerticesOfTriangularEdge[ie][1];
621                     int i1 = Th(Th[i][e0]),i2 = Th(Th[i][e1]);
622                     BoundaryEdge * be = Th.TheBoundaryEdge(i1,i2);
623                     int lab = be ? be->lab :  notalabel;
624 
625                     A += mate(i,ie,lab,paramate);
626                 }
627                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
628 
629             }
630 
631         }
632         else if (di.kind == CDomainOfIntegration::intallVFedges)
633         {
634             cerr << " a faire intallVFedges " << endl;
635             ffassert(0);
636             for (int i=0;i< Th.nt; i++)
637             {
638                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
639                 for (int ie=0;ie<3;ie++)
640                 A += mate(i,ie,Th[i].lab,paramate);
641                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
642 
643             }
644 
645         }
646         else if (di.kind == CDomainOfIntegration::int2d )
647         {
648 
649             if(di.islevelset())
650             {
651                 double uset = HUGE_VAL;
652                 R2 Q[2][3];
653                 double vol6[2];
654                 KN<double> phi(Th.nv);phi=uset;
655                 double f[3];
656                 for(int t=0; t< Th.nt;++t)
657                 {
658                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
659                     {
660                         double umx=-HUGE_VAL,umn=HUGE_VAL;
661                         for(int i=0;i<3;++i)
662                         {
663                             int j= ThI(t,i);
664                             if( phi[j]==uset)
665                             {
666                                 MeshPointStack(stack)->setP(&ThI,t,i);
667                                 phi[j]= di.levelset(stack);//zzzz
668                             }
669                             f[i]=phi[j];
670                             umx = std::max(umx,phi[j]);
671                             umn = std::min(umn,phi[j]);
672 
673                         }
674                         int nt= UnderIso(f,Q, vol6,1e-14);
675                         setQF<R2>(FIT,FITo,QuadratureFormular_T_1, Q,vol6,nt);
676                         if(FIT.n)
677                         A += mate(t,-1,Th[t].lab,stack);
678                         if(sptrclean) sptrclean=sptr->clean();
679                     }
680                 }
681                 FIT =FITo;
682             }
683             else
684 
685 
686             for (int i=0;i< Th.nt; i++)
687             {
688                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
689                 A += mate(i,-1,Th[i].lab,stack);
690                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
691 
692                 // AA += mate;
693             }
694         }
695         else
696         InternalError(" kind of CDomainOfIntegration unkown");
697 
698         if (where_in_stack) delete [] where_in_stack;
699         delete &mate;
700         if(verbosity>9) cout << "  -- CPU assemble mat " <<  CPUtime()-CPU0 << " s\n";
701     }
702 
703     // creating an instance of AssembleBilinearForm with MatriceCreuse
704     // case 3D volume
705     // --------- FH 120105
706     template<class R>
AssembleBilinearForm(Stack stack,const FESpace3::Mesh & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,MatriceCreuse<R> & A,const FormBilinear * b)707     void AssembleBilinearForm(Stack stack,const FESpace3::Mesh & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
708                               MatriceCreuse<R>  & A, const  FormBilinear * b  )
709 
710     {
711         /*FH:  case ..in 3D
712          in varf ...
713          standard case ..
714          */
715 
716 
717         typedef FESpace3 FESpace;
718         typedef FESpace3::Mesh Mesh;
719         typedef Mesh *pmesh ;
720         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
721         Fem2D::MeshPoint & mp (*Fem2D::MeshPointStack(stack)), mps = mp;
722 
723         bool sptrclean=true;
724         const CDomainOfIntegration & di= *b->di;
725         ffassert(di.d==3);
726         const Mesh * pThdi = GetAny<pmesh>( (* di.Th)(stack));
727         if ( pThdi != &Th || &Uh.Th !=&Th || &Vh.Th !=&Th) {
728             cout << " Use matrix formulation .... " << endl;
729             ExecError("No way to compute bilinear form with integrale of on mesh \n"
730                       "  test  or unkown function  defined on an other mesh! sorry to hard.   ");
731         }
732         SHOWVERB(cout << " FormBilinear " << endl);
733         MatriceElementaireSymetrique<R,FESpace> *mates =0;
734         MatriceElementairePleine<R,FESpace> *matep =0;
735         const int useopt=di.UseOpt(stack);
736         double binside=di.binside(stack);
737         if( di.withmap()) { ExecError(" no map  in the case (3)??");}
738 
739         //const vector<Expression>  & what(di.what);
740         CDomainOfIntegration::typeofkind  kind = di.kind;
741         set<int> setoflab;
742         bool all=true;
743         const QuadratureFormular1d & FIEo = di.FIE(stack);
744         const QuadratureFormular & FITo = di.FIT(stack);
745         const GQuadratureFormular<R3> & FIVo = di.FIV(stack);
746         //  to change the quadrature on element ... may 2014 FH ..
747         QuadratureFormular1d  FIE(FIEo,3);
748         QuadratureFormular FIT(FITo,3);
749         GQuadratureFormular<R3>  FIV(FIVo,3);
750 
751         bool VF=b->VF();  // finite Volume or discontinous Galerkin
752         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
753         if (verbosity>3)
754         {
755             if (CDomainOfIntegration::int2d==kind) cout << "  -- boundary int border ( nQP: "<< FIT.n << ") ,"  ;
756             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIT.n << "),"  ;
757             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
758             else cout << "  --  int3d   (nQP: "<< FIV.n << " ) in "  ;
759             if(di.islevelset()) cout << " ( int on Levelset) " << endl;
760 
761         }
762         if(di.islevelset() && (CDomainOfIntegration::int2d!=kind) && (CDomainOfIntegration::int3d!=kind))
763         InternalError("Sorry no levelset integration type on no int[2|3]d case");
764 
765         Expandsetoflab(stack,di, setoflab,all);
766         /*
767          for (size_t i=0;i<what.size();i++)
768          {
769          long  lab  = GetAny<long>( (*what[i])(stack));
770          setoflab.insert(lab);
771          if ( verbosity>3) cout << lab << " ";
772          all=false;
773          }*/
774         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
775         const E_F0 * poptiexp0=b->b->optiexp0;
776 
777         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
778         R** where_in_stack =0;
779         if (n_where_in_stack_opt && useopt)
780         where_in_stack = new R * [n_where_in_stack_opt];
781         if (where_in_stack)
782         {
783             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
784             for (int i=0;i<n_where_in_stack_opt;i++)
785             {
786                 int offset=b->b->where_in_stack_opt[i];
787                 assert(offset>10);
788                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
789                 *(where_in_stack[i])=0;
790             }
791 
792 
793             if(poptiexp0)
794             (*poptiexp0)(stack);
795             KN<bool> ok(b->b->v.size());
796             {  //   remove the zero coef in the liste
797                 // R zero=R();
798                 int il=0;
799                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
800                 ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
801             }
802             BilinearOperator b_nozer(*b->b,ok);
803             if (verbosity % 10 > 3 )
804             cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
805             << "  total " << n_where_in_stack_opt << endl;
806 
807             if ( (verbosity/100) % 10 >= 2)
808             {
809                 int il=0;
810 
811                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
812                 cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
813                 << " offset=" << b->b->where_in_stack_opt[il]
814                 << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
815             }
816         }
817         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
818         void *paramate=stack;
819         pair_stack_double parammatElement_OpVF(stack, & binside);
820         parammatElement_OpVF.first = stack;
821         parammatElement_OpVF.second= & binside;
822 
823         if (verbosity >3)
824         {
825             if (all) cout << " all " << endl ;
826             else cout << endl;
827         }
828         if(VF) {
829             if(&Uh != &Vh || sym)
830             cout <<  ("To Day in bilinear form with discontinous Galerkin (3d):   \n"
831                       "  test or unkown function must be  defined on the same FEspace, \n"
832                       "  and the matrix is not symmetric. \n"
833                       " To do other case in a future (F. Hecht) dec. 2014 ");
834             if(&Uh == &Vh)
835             matep= new MatriceElementairePleine<R,FESpace>(Uh,VF,FIV,FIT,useopt);
836             else
837             matep= new MatriceElementairePleine<R,FESpace>(Uh,Vh,VF,FIV,FIT,useopt);
838             matep->faceelement = Element_OpVF;
839             paramate= &parammatElement_OpVF;
840         }
841         else if (sym) {
842             mates= new MatriceElementaireSymetrique<R,FESpace>(Uh,FIV,FIT,useopt);
843             mates->element = Element_Op<R>;
844         }
845         else {
846             matep= new MatriceElementairePleine<R,FESpace>(Uh,Vh,FIV,FIT,useopt);
847             matep->element = Element_Op<R>;
848         }
849         MatriceElementaireFES<R,FESpace> & mate(*( sym? (MatriceElementaireFES<R,FESpace> *)mates : (MatriceElementaireFES<R,FESpace> *) matep));
850 
851 
852         mate.bilinearform=b->b;
853 
854         Check(*mate.bilinearform,mate.Uh.N,mate.Vh.N);
855 
856         if (di.kind == CDomainOfIntegration::int2d )
857         {
858 
859             if(di.islevelset())
860             {
861                 if(verbosity>99) cout << " int2d on levelset in 3d " << endl;
862                 double uset = HUGE_VAL;
863                 R3 Q[4];
864                 KN<double> phi(Th.nv);phi=uset;
865                 double f[4];
866                 for(int t=0; t< Th.nt;++t)
867                 {
868                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
869                     {
870                         double umx=-HUGE_VAL,umn=HUGE_VAL;
871                         for(int i=0;i<4;++i)
872                         {
873                             int j= Th(t,i);
874                             if( phi[j]==uset)
875                             {
876                                 MeshPointStack(stack)->setP(&Th,t,i);
877                                 phi[j]= di.levelset(stack);//zzzz
878                             }
879                             f[i]=phi[j];
880                             umx = std::max(umx,phi[j]);
881                             umn = std::min(umn,phi[j]);
882 
883                         }
884                         if( umn <=0 && umx >= 0)
885                         {
886                             int np= IsoLineK(f,Q,1e-10);// ca code ...
887                             //  cout <<umn << " " << umx << " " << np << endl;
888 
889                             if(np>2 )
890                             {
891                                 if( verbosity > 999 ) cout << " -- int " << np << " on:  " << Q[0] << " " << Q[1] << " " << Q[2] << " " << Q[3] << endl;
892                                 A += mate(t,10+np,Th[t].lab,stack,Q);
893                             }
894                             if(sptrclean) sptrclean=sptr->clean();
895                         }
896                     }}
897 
898             }
899             else
900             for( int e=0;e<Th.nbe;e++)
901             {
902                 if (all || setoflab.find(Th.be(e).lab) != setoflab.end())
903                 {
904                     int ie,i =Th.BoundaryElement(e,ie);
905                     A += mate(i,ie,Th.be(e).lab,stack);
906                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
907 
908                 }
909             }
910         }
911         else if (di.kind == CDomainOfIntegration::intallfaces  )
912         {
913             for (int i=0;i< Th.nt; i++)
914             {
915                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
916                 for (int ie=0;ie<3;ie++)
917                 A += mate(i,ie,Th[i].lab,paramate);
918                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
919 
920             }
921 
922         }
923         else if (di.kind == CDomainOfIntegration::intallVFedges)
924         {
925             cerr << " a faire intallVFedges " << endl;
926             ffassert(0);
927             for (int i=0;i< Th.nt; i++)
928             {
929                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
930                 for (int ie=0;ie<3;ie++)
931                 A += mate(i,ie,Th[i].lab,paramate);
932                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
933 
934             }
935 
936         }
937         else if (di.kind == CDomainOfIntegration::int3d )
938         {
939             if(di.islevelset())  //  may 2014 FH ...
940             {   // int3d levelset < 0
941                 double llevelset = 0;
942                 const double uset = std::numeric_limits<double>::max();
943                 // cout << " uset ="<<uset << endl;
944                 R3 Q[3][4];
945                 double vol6[3];
946                 KN<double> phi(Th.nv);
947                 phi=uset;
948                 double f[4];
949 
950                 for (int t=0;t< Th.nt; t++)
951                 {
952 
953                     const Mesh3::Element & K(Th[t]);
954                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
955 
956                     {
957                         double umx=std::numeric_limits<double>::min(),umn=std::numeric_limits<double>::max();
958                         for(int i=0;i<4;++i)
959                         {
960                             int j= Th(t,i);
961                             if( phi[j]==uset)
962                             {
963                                 MeshPointStack(stack)->setP(&Th,t,i);
964                                 phi[j]= di.levelset(stack);//zzzz
965                             }
966                             f[i]=phi[j];
967                         }
968                         int ntets= UnderIso(f,Q, vol6,1e-14);
969                         setQF<R3>(FIV,FIVo,QuadratureFormular_Tet_1, Q,vol6,ntets);
970                         if(FIV.n)
971                         {
972                             A += mate(t,-1,Th[t].lab,stack);
973                             if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
974 
975                         }
976                     }
977                 }
978                 FIV=FIVo;
979             }
980             else
981             for (int i=0;i< Th.nt; i++)
982             {
983                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
984                 A += mate(i,-1,Th[i].lab,stack);
985                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
986 
987                 // AA += mate;
988             }
989 
990         }
991         else
992         {
993             cerr << " kind of CDomainOfIntegration unkown ?? " << di.kind << endl;
994             InternalError(" kind of CDomainOfIntegration unkown");
995         }
996 
997         if (where_in_stack) delete [] where_in_stack;
998         delete &mate;
999         mp = mps;// restore data x,yz
1000     }
1001 
1002 
1003 
1004     // template struct to obtain the original type mesh - particular case for meshS FEM
1005   /*  template<class FE>    struct Trait_MESHO {
1006         // By default Mesh == MeshO
1007         typedef typename FE::Mesh MeshO;//   Mesh origin for Mesh S
1008         typedef typename FE::Mesh Mesh; //   Mesh Mesh S
1009         static Mesh * topmesh(MeshO *p) {return p;}
1010     };*/
1011    /* template<>    struct Trait_MESHO<FESpaceS> {
1012         // By default Mesh == MeshS and MeshO == Mesh3
1013         typedef  Mesh3 MeshO;
1014         typedef typename FESpaceS::Mesh Mesh;
1015         static Mesh * topmesh(MeshO *p) {return p->getMeshS();}
1016     };*/
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1025     // creating an instance of AssembleBilinearForm with MatriceCreuse
1026     // case 3D surface
1027     template<class R>
AssembleBilinearForm(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,MatriceCreuse<R> & A,const FormBilinear * b)1028     void AssembleBilinearForm(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
1029                               MatriceCreuse<R>  & A, const  FormBilinear * b  )
1030 
1031     {
1032         /*FH:  case ..in 2D
1033          in varf ...
1034          standard case ..
1035          */
1036 
1037         typedef typename  Mesh::RdHat RdHat;
1038         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
1039         bool sptrclean=true;
1040         const CDomainOfIntegration & di= *b->di;
1041          ffassert(di.d==3);
1042 
1043         SHOWVERB(cout << " FormBilinear " << endl);
1044         double CPU0 = CPUtime();
1045         MatriceElementaireSymetrique<R,FESpaceS> *mates =0;
1046         MatriceElementairePleine<R,FESpaceS> *matep =0;
1047         const int useopt=di.UseOpt(stack);
1048         double binside=di.binside(stack);
1049 
1050         //const vector<Expression>  & what(di.what);
1051         CDomainOfIntegration::typeofkind  kind = di.kind;
1052         set<int> setoflab;
1053         bool all=true;
1054 
1055         const MeshS & ThI = Th;// * GetAny<pmesh>( (* di.Th)(stack));
1056         bool sameMesh = &ThI == &Vh.Th &&  &ThI == &Uh.Th;
1057 
1058         //    const QuadratureFormular1d & FIE = di.FIE(stack);
1059         //    const QuadratureFormular & FIT = di.FIT(stack);
1060         const QuadratureFormular1d & FIEo = di.FIE(stack);
1061         const QuadratureFormular & FITo = di.FIT(stack);
1062         // const GQuadratureFormular<R3> & FIVo = di.FIV(stack);
1063         //  to change the quadrature on element ... may 2014 FH ..
1064         QuadratureFormular1d  FIE(FIEo,3);
1065         QuadratureFormular FIT(FITo,3);
1066         // GQuadratureFormular<R3>  FIV(FIVo,3);
1067 
1068         bool VF=b->VF();  // finite Volume or discontinous Galerkin
1069         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
1070         if (verbosity>3)
1071         {
1072             if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ,"  ;
1073             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
1074             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
1075             else cout << "  --  int    (nQP: "<< FIT.n << " ) in "  ;
1076         }
1077         //if(di.islevelset()) InternalError("So no levelset integration type on this case (6)");
1078         if( di.withmap()) { ExecError(" no map  in the case (2)??");}
1079         if(di.islevelset() && ( (CDomainOfIntegration::int1d!=kind) && (CDomainOfIntegration::int2d!=kind) )  )
1080         InternalError("So no levelset integration type on no int1d case (6)");
1081 
1082         Expandsetoflab(stack,di, setoflab,all);
1083         /*
1084          for (size_t i=0;i<what.size();i++)
1085          {
1086          long  lab  = GetAny<long>( (*what[i])(stack));
1087          setoflab.insert(lab);
1088          if ( verbosity>3) cout << lab << " ";
1089          all=false;
1090          }*/
1091         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
1092         const E_F0 * poptiexp0=b->b->optiexp0;
1093 
1094         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
1095         R** where_in_stack =0;
1096         if (n_where_in_stack_opt && useopt)
1097         where_in_stack = new R * [n_where_in_stack_opt];
1098         if (where_in_stack)
1099         {
1100             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
1101             for (int i=0;i<n_where_in_stack_opt;i++)
1102             {
1103                 int offset=b->b->where_in_stack_opt[i];
1104                 assert(offset>10);
1105                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
1106                 *(where_in_stack[i])=0;
1107             }
1108 
1109 
1110             if(poptiexp0)
1111             (*poptiexp0)(stack);
1112             KN<bool> ok(b->b->v.size());
1113             {  //   remove the zero coef in the liste
1114                 // R zero=R();
1115                 int il=0;
1116                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
1117                 ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
1118             }
1119             BilinearOperator b_nozer(*b->b,ok);
1120             if (verbosity % 10 > 3 )
1121             cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
1122             << "  total " << n_where_in_stack_opt << endl;
1123 
1124             if ( (verbosity/100) % 10 >= 2)
1125             {
1126                 int il=0;
1127 
1128                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
1129                 cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
1130                 << " offset=" << b->b->where_in_stack_opt[il]
1131                 << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
1132             }
1133         }
1134         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
1135         void *paramate=stack;
1136         pair_stack_double parammatElement_OpVF(stack,& binside);
1137         // parammatElement_OpVF.first = stack;
1138         // parammatElement_OpVF.second= & binside;
1139 
1140         if (verbosity >3)
1141         {
1142             if (all) cout << " all " << endl ;
1143             else cout << endl;
1144         }
1145         if(VF) {
1146             if(&Uh != &Vh || sym)
1147             cout << ("To Day in bilinear form with discontinous Galerkin (2d):   \n"
1148                      "  test or unkown function must be  defined on the same FEspace, \n"
1149                      "  and the matrix is not symmetric. \n"
1150                      " To do other case in a future (F. Hecht) dec. 2003 ");
1151             if(&Uh == &Vh)
1152             matep= new MatriceElementairePleine<R,FESpaceS>(Uh,VF,FIT,FIE,useopt);
1153             else
1154             matep= new MatriceElementairePleine<R,FESpaceS>(Uh,Vh,VF,FIT,FIE,useopt);
1155 
1156 
1157             //      matep= new MatriceElementairePleine<R,FESpace>(Uh,Vh,VF,FIT,FIE);
1158             matep->faceelement = Element_OpVF;
1159             paramate= &parammatElement_OpVF;
1160         }
1161         else if (sym) {
1162             mates= new MatriceElementaireSymetrique<R,FESpaceS>(Uh,FIT,FIE,useopt);
1163             mates->element = Element_Op<R>;
1164         }
1165         else {
1166             matep= new MatriceElementairePleine<R,FESpaceS>(Uh,Vh,FIT,FIE,useopt);
1167             matep->element = Element_Op<R>;
1168         }
1169         MatriceElementaireFES<R,FESpaceS> & mate(*( sym? (MatriceElementaireFES<R,FESpaceS> *)mates : (MatriceElementaireFES<R,FESpaceS> *) matep));
1170 
1171 
1172         mate.bilinearform=b->b;
1173 
1174         Check(*mate.bilinearform,mate.Uh.N,mate.Vh.N);
1175         if(verbosity>9) cout << "  -- CPU init assemble mat " <<  CPUtime()-CPU0 << " s\n";
1176 
1177         if (di.kind == CDomainOfIntegration::int1d )
1178         {
1179             if(di.islevelset())
1180             {
1181                 double uset = HUGE_VAL;
1182                 R2 Q[3];
1183                 KN<double> phi(Th.nv);phi=uset;
1184                 double f[3];
1185                 for(int t=0; t< Th.nt;++t)
1186                 {
1187                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
1188                     {
1189                         double umx=-HUGE_VAL,umn=HUGE_VAL;
1190                         for(int i=0;i<3;++i)
1191                         {
1192                             int j= ThI(t,i);
1193                             if( phi[j]==uset)
1194                             {
1195                                 MeshPointStack(stack)->setP(&ThI,t,i);
1196                                 phi[j]= di.levelset(stack);//zzzz
1197                             }
1198                             f[i]=phi[j];
1199                             umx = std::max(umx,phi[j]);
1200                             umn = std::min(umn,phi[j]);
1201 
1202                         }
1203                         if( umn <=0 && umx >= 0)
1204                         {
1205 
1206                             int np= IsoLineK(f,Q,1e-10);
1207                             if(np==2)
1208                             {
1209                                 /* if ( sameMesh)
1210                                  {
1211 
1212                                  Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIE,Q[0],Q[1]);
1213                                  }
1214                                  else*/
1215                                 //   InternalError(" No levelSet on Diff mesh :    to day  int1d of Matrix");
1216                                 A += mate(t,10,Th[t].lab,stack,Q);
1217                             }
1218                             if(sptrclean) sptrclean=sptr->clean();
1219                         }
1220                     }
1221                 }
1222             }
1223             else for( int e=0;e<Th.nbe;e++)
1224             {
1225                 if (all || setoflab.find(Th.be(e).lab) != setoflab.end())
1226                 {
1227                     int ie,i =Th.BoundaryElement(e,ie);
1228                     A += mate(i,ie,Th.be(e).lab,stack);
1229                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
1230 
1231                 }
1232             }
1233         }
1234         else if (di.kind == CDomainOfIntegration::intalledges)
1235         {
1236             ffassert(0);
1237            /* for (int i=0;i< Th.nt; i++)
1238             {
1239                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
1240                 for (int ie=0;ie<3;ie++)
1241                 { // modif F.H to get the correct label in intalledges
1242                     int e0=VerticesOfTriangularEdge[ie][0];
1243                     int e1=VerticesOfTriangularEdge[ie][1];
1244                     int i1 = Th(Th[i][e0]),i2 = Th(Th[i][e1]);
1245                     BoundaryEdge * be = Th.TheBoundaryEdge(i1,i2);
1246 
1247                     int lab = be ? be->lab :  notalabel;
1248 
1249                     A += mate(i,ie,lab,paramate);
1250                 }
1251                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
1252 
1253             }
1254            */
1255         }
1256        else if (di.kind == CDomainOfIntegration::intallVFedges)
1257         {
1258             ffassert(0);
1259            /* cerr << " a faire intallVFedges " << endl;
1260             ffassert(0);
1261             for (int i=0;i< Th.nt; i++)
1262             {
1263                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
1264                 for (int ie=0;ie<3;ie++)
1265                 A += mate(i,ie,Th[i].lab,paramate);
1266                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
1267 
1268             }
1269            */
1270         }
1271         else if (di.kind == CDomainOfIntegration::int2d )
1272         {
1273             if(di.islevelset())
1274             {
1275                 double uset = HUGE_VAL;
1276                 R2 Q[2][3];
1277                 double vol6[2];
1278                 KN<double> phi(Th.nv);phi=uset;
1279                 double f[3];
1280                 for(int t=0; t< Th.nt;++t)
1281                 {
1282                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
1283                     {
1284                         double umx=-HUGE_VAL,umn=HUGE_VAL;
1285                         for(int i=0;i<3;++i)
1286                         {
1287                             int j= ThI(t,i);
1288                             if( phi[j]==uset)
1289                             {
1290                                 MeshPointStack(stack)->setP(&ThI,t,i);
1291                                 phi[j]= di.levelset(stack);//zzzz
1292                             }
1293                             f[i]=phi[j];
1294                             umx = std::max(umx,phi[j]);
1295                             umn = std::min(umn,phi[j]);
1296 
1297                         }
1298                         int nt= UnderIso(f,Q, vol6,1e-14);
1299                         setQF<R2>(FIT,FITo,QuadratureFormular_T_1, Q,vol6,nt);
1300                         if(FIT.n)
1301                         A += mate(t,-1,Th[t].lab,stack);
1302                         if(sptrclean) sptrclean=sptr->clean();
1303                     }
1304                 }
1305                 FIT =FITo;
1306             }
1307             else
1308 
1309 
1310             for (int i=0;i< Th.nt; i++)
1311             {
1312                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
1313                 A += mate(i,-1,Th[i].lab,stack);
1314                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
1315 
1316                 // AA += mate;
1317             }
1318         }
1319         else
1320         InternalError(" kind of CDomainOfIntegration unkown");
1321 
1322         if (where_in_stack) delete [] where_in_stack;
1323         delete &mate;
1324         if(verbosity>9) cout << "  -- CPU assemble mat " <<  CPUtime()-CPU0 << " s\n";
1325     }
1326 
1327 
1328     // creating an instance of AssembleBilinearForm with MatriceCreuse
1329     // case 3D curve
1330     template<class R>
AssembleBilinearForm(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,MatriceCreuse<R> & A,const FormBilinear * b)1331     void AssembleBilinearForm(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
1332                               MatriceCreuse<R>  & A, const  FormBilinear * b  )
1333 
1334     {
1335 
1336         typedef typename  Mesh::RdHat RdHat;
1337         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
1338         bool sptrclean=true;
1339         const CDomainOfIntegration & di= *b->di;
1340         ffassert(di.d==3);
1341 
1342         SHOWVERB(cout << " FormBilinear " << endl);
1343         double CPU0 = CPUtime();
1344         MatriceElementaireSymetrique<R,FESpaceL> *mates =0;
1345         MatriceElementairePleine<R,FESpaceL> *matep =0;
1346         const int useopt=di.UseOpt(stack);
1347         double binside=di.binside(stack);
1348 
1349         //const vector<Expression>  & what(di.what);
1350         CDomainOfIntegration::typeofkind  kind = di.kind;
1351         set<int> setoflab;
1352         bool all=true;
1353 
1354         const MeshL & ThI = Th;// * GetAny<pmesh>( (* di.Th)(stack));
1355         bool sameMesh = &ThI == &Vh.Th &&  &ThI == &Uh.Th;
1356 
1357         const GQuadratureFormular<R1> & FITo = di.FIE(stack);
1358         GQuadratureFormular<R1>  FIT(FITo,3);
1359 
1360         bool VF=b->VF();  // finite Volume or discontinous Galerkin
1361         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
1362 
1363         if( di.withmap()) { ExecError(" no map  in the case (2)??");}
1364         if(di.islevelset() && ( (CDomainOfIntegration::int1d!=kind) && (CDomainOfIntegration::int2d!=kind) )  )
1365             InternalError("So no levelset integration type on no int1d case (6)");
1366 
1367         Expandsetoflab(stack,di, setoflab,all);
1368 
1369         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
1370         const E_F0 * poptiexp0=b->b->optiexp0;
1371 
1372         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
1373         R** where_in_stack =0;
1374         if (n_where_in_stack_opt && useopt)
1375             where_in_stack = new R * [n_where_in_stack_opt];
1376         if (where_in_stack)
1377         {
1378             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
1379             for (int i=0;i<n_where_in_stack_opt;i++)
1380             {
1381                 int offset=b->b->where_in_stack_opt[i];
1382                 assert(offset>10);
1383                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
1384                 *(where_in_stack[i])=0;
1385             }
1386 
1387 
1388             if(poptiexp0)
1389                 (*poptiexp0)(stack);
1390             KN<bool> ok(b->b->v.size());
1391             {  //   remove the zero coef in the liste
1392                 // R zero=R();
1393                 int il=0;
1394                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
1395                     ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
1396             }
1397             BilinearOperator b_nozer(*b->b,ok);
1398             if (verbosity % 10 > 3 )
1399                 cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
1400                 << "  total " << n_where_in_stack_opt << endl;
1401 
1402             if ( (verbosity/100) % 10 >= 2)
1403             {
1404                 int il=0;
1405 
1406                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
1407                     cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
1408                     << " offset=" << b->b->where_in_stack_opt[il]
1409                     << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
1410             }
1411         }
1412         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
1413         void *paramate=stack;
1414         pair_stack_double parammatElement_OpVF(stack,& binside);
1415         // parammatElement_OpVF.first = stack;
1416         // parammatElement_OpVF.second= & binside;
1417 
1418         if (verbosity >3)
1419         {
1420             if (all) cout << " all " << endl ;
1421             else cout << endl;
1422         }
1423         if(VF) {
1424             if(&Uh != &Vh || sym)
1425                 cout << ("To Day in bilinear form with discontinous Galerkin (2d):   \n"
1426                          "  test or unkown function must be  defined on the same FEspace, \n"
1427                          "  and the matrix is not symmetric. \n"
1428                          " To do other case in a future (F. Hecht) dec. 2003 ");
1429             if(&Uh == &Vh)
1430                 matep= new MatriceElementairePleine<R,FESpaceL>(Uh,VF,FIT,0,useopt);
1431             else
1432                 matep= new MatriceElementairePleine<R,FESpaceL>(Uh,Vh,VF,FIT,0,useopt);
1433 
1434             matep->faceelement = Element_OpVF;
1435             paramate= &parammatElement_OpVF;
1436         }
1437         else if (sym) {
1438             mates= new MatriceElementaireSymetrique<R,FESpaceL>(Uh,FIT,0,useopt);
1439             mates->element = Element_Op<R>;
1440         }
1441         else {
1442             matep= new MatriceElementairePleine<R,FESpaceL>(Uh,Vh,FIT,0,useopt);
1443             matep->element = Element_Op<R>;
1444         }
1445         MatriceElementaireFES<R,FESpaceL> & mate(*( sym? (MatriceElementaireFES<R,FESpaceL> *)mates : (MatriceElementaireFES<R,FESpaceL> *) matep));
1446 
1447 
1448         mate.bilinearform=b->b;
1449 
1450         Check(*mate.bilinearform,mate.Uh.N,mate.Vh.N);
1451         if(verbosity>9) cout << "  -- CPU init assemble mat " <<  CPUtime()-CPU0 << " s\n";
1452 
1453         if (di.kind == CDomainOfIntegration::int1d ) {
1454             for (int i=0;i< Th.nt; i++) {
1455                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
1456                         A += mate(i,-1,Th[i].lab,stack);
1457                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
1458             }
1459         }
1460 
1461         else if (di.kind == CDomainOfIntegration::int0d ) {
1462             for( int e=0;e<Th.nbe;e++) {
1463                 if (all || setoflab.find(Th.be(e).lab) != setoflab.end()) {
1464                     int ie,i =Th.BoundaryElement(e,ie);
1465                     A += mate(i,ie,Th.be(e).lab,stack);
1466                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
1467                 }
1468             }
1469         }
1470 
1471 
1472         else
1473             InternalError(" kind of CDomainOfIntegration unkown");
1474 
1475         if (where_in_stack) delete [] where_in_stack;
1476         delete &mate;
1477         if(verbosity>9) cout << "  -- CPU assemble mat " <<  CPUtime()-CPU0 << " s\n";
1478     }
1479 
1480 
1481     // end 3d
1482 
1483 
1484 
1485     ////////////////////////////////////////////////
1486     // AddMatElem
1487     ////////////////////////////////////////////////
1488 
1489     // case 2d
1490     // --------- FH 170605
1491 
1492     template<class R>
AddMatElem(MatriceMap<R> & A,const Mesh & Th,const BilinearOperator & Op,bool sym,int it,int ie,int label,const FESpace & Uh,const FESpace & Vh,const QuadratureFormular & FI,const QuadratureFormular1d & FIb,double * p,void * vstack,bool intmortar=false,R2 * Q=0)1493     void  AddMatElem(MatriceMap<R> & A,const Mesh & Th,const BilinearOperator & Op,bool sym,int it,  int ie,int label,
1494                      const FESpace & Uh,const FESpace & Vh,
1495                      const QuadratureFormular & FI,
1496                      const QuadratureFormular1d & FIb,
1497                      double *p,   void *vstack, bool intmortar=false,R2 *Q=0)
1498     {
1499         //cout << "AddMatElem" << Q << " "  << ie << endl;
1500         Stack stack=pvoid2Stack(vstack);
1501         MeshPoint mp= *MeshPointStack(stack);
1502         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
1503         const Mesh & Thu(Uh.Th);
1504         const Mesh & Thv(Vh.Th);
1505 
1506         bool same = &Uh == & Vh;
1507         const Triangle & T  = Th[it];
1508         long npi;
1509         long i,j;
1510         bool classoptm = copt && Op.optiexpK;
1511         assert(Op.MaxOp() <last_operatortype);
1512         //
1513 
1514 
1515         KN<bool> Dop(last_operatortype);
1516         Op.DiffOp(Dop);
1517         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
1518         //assert(lastop<=3);
1519 
1520         if (ie<0)
1521         {
1522             for (npi=0;npi<FI.n;npi++) // loop on the integration point
1523             {
1524                 QuadraturePoint pi(FI[npi]);
1525                 double coef = T.area*pi.a;
1526                 R2 Pt(pi),Ptu,Ptv;
1527                 R2 P(T(Pt));
1528                 bool outsideu,outsidev;
1529                 // ici trouve le T
1530                 int iut=0,ivt=0;
1531                 const Triangle * tu,*tv;
1532                 if(&Th == & Thu )
1533                 {
1534                     tu =&T;
1535                     Ptu=Pt;
1536                 }
1537                 else
1538                 {
1539                     tu= Thu.Find(P,Ptu,outsideu);
1540                     if( !tu ||  outsideu) {
1541                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " << endl;
1542                         continue;}}
1543                 if(same)
1544                 {
1545                     tv=tu;
1546                     outsidev=outsideu;
1547                     Ptv=Ptu;
1548                 }
1549                 else
1550                 {
1551                     if(&Th == & Thv )
1552                     {
1553                         tv =&T;
1554                         Ptv=Pt;
1555                     }
1556                     else
1557                     {
1558                         tv= Thv.Find(P,Ptv,outsidev);
1559                         if( !tv || outsidev) {
1560                             if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
1561                             continue;
1562                         }}
1563                 }
1564                 iut = Thu(tu);
1565                 ivt = Thv(tv);
1566                 if( verbosity>1000) cout << " T " << it  << "  iut " << iut << " ivt " << ivt  <<  endl ;
1567                 FElement Ku(Uh[iut]);
1568                 FElement Kv(Vh[ivt]);
1569                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
1570                 long N= Kv.N;
1571                 long M= Ku.N;
1572                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
1573                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
1574 
1575 
1576                 Ku.BF(Dop,Ptu,fu);
1577                 MeshPointStack(stack)->set(Th,P,Pt,T,label);
1578                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
1579                 if (!same) Kv.BF(Dop,Ptv,fv);
1580                 for ( i=0;  i<n;   i++ )
1581                 {
1582 
1583                     // attention la fonction test donne la ligne
1584                     //  et la fonction test est en second
1585                     int ig = Kv(i);
1586                     RNM_ wi(fv(i,'.','.'));
1587                     for ( j=0;  j<m;   j++ )
1588                     {
1589                         RNM_ wj(fu(j,'.','.'));
1590                         int il=0;
1591                         int jg(Ku(j));
1592                         if ( !sym ||  ig <= jg )
1593                         for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
1594                         {  // attention la fonction test donne la ligne
1595                             //  et la fonction test est en second
1596                             BilinearOperator::K ll(*l);
1597                             pair<int,int> jj(ll.first.first),ii(ll.first.second);
1598                             double w_i =  wi(ii.first,ii.second);
1599                             double w_j =  wj(jj.first,jj.second);
1600                             R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack))   ;
1601                             if( verbosity>1000) cout << ig << " " << jg << " "  <<  " " << ccc << " " <<  coef * ccc * w_i*w_j << " on T \n"   ;
1602                             double wij =  w_i*w_j;
1603                             if (abs(wij)>= 1e-10)
1604                             A[make_pair(ig,jg)] += coef * ccc * wij;
1605                         }
1606                     }
1607                 }
1608             }
1609         }
1610         else // int on edge ie
1611         {
1612             R2 PA,PB,E;
1613             if(Q)
1614             {
1615                 PA=Q[0];
1616                 PB=Q[1];
1617                 E=T(PB)-T(PA);
1618                 // cout << " AddMAtElem " <<  PA <<  " " << PB << " "<< sqrt((E,E))<< endl;
1619             }
1620             else
1621             {
1622                 PA=TriangleHat[VerticesOfTriangularEdge[ie][0]];
1623                 PB=TriangleHat[VerticesOfTriangularEdge[ie][1]];
1624                 E=T.Edge(ie);
1625             }
1626             double le = sqrt((E,E));
1627 
1628             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
1629             {
1630                 QuadratureFormular1dPoint pi( FIb[npi]);
1631                 double sa=pi.x,sb=1-sa;
1632                 double coef = le*pi.a;
1633 
1634                 R2 Pt(PA*sa+PB*sb ); //
1635 
1636                 R2 Ptu,Ptv;
1637                 R2 P(T(Pt));
1638                 bool outsideu,outsidev;
1639                 // ici trouve le T
1640                 int iut=0,ivt=0;
1641                 const Triangle * tu, *tv;
1642                 if(&Th == & Thu )
1643                 {
1644                     tu =&T;
1645                     Ptu=Pt;
1646                 }
1647                 else
1648                 {
1649                     tu= Thu.Find(P,Ptu,outsideu);
1650                     if( !tu ||  (outsideu && !intmortar) )  {
1651                         //R dd=-1;
1652                         //if(tu) { R2 PP((*tu)(Ptu)),PPP(P,PP) ; cout << PP << " " << sqrt( (PPP,PPP) ) <<"    "; }
1653                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " <<Ptu << " " << tu <<   endl;
1654                         continue;}}
1655                 iut = Thu(tu);
1656                 if(same)
1657                 {
1658                     tv=tu;
1659                     outsidev=outsideu;
1660                     Ptv=Ptu;
1661                     ivt=iut;
1662                 }
1663                 else
1664                 {
1665                     if(&Th == & Thv )
1666                     {
1667                         tv =&T;
1668                         Ptv=Pt;
1669                     }
1670                     else {
1671                         tv= Thv.Find(P,Ptv,outsidev);
1672                         if( !tv || (outsidev&& !intmortar))  {
1673                             if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
1674                             continue;}}
1675                     ivt = Thv(tv);
1676                 }
1677                 FElement Ku(Uh[iut]);
1678                 FElement Kv(Vh[ivt]);
1679                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
1680                 long N= Kv.N;
1681                 long M= Ku.N;
1682                 //  cout << P << " " <<  Pt << " " <<  iut << " " << ivt  << "  Ptu : " << Ptu << " Ptv: " << Ptv << " n:" << n << " m:" << m << endl;
1683                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
1684                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
1685 
1686                 Ku.BF(Dop,Ptu,fu);
1687                 if( !same)
1688                 Kv.BF(Dop,Ptv,fv);
1689 
1690 
1691                 // int label=-999999; // a passer en argument
1692                 MeshPointStack(stack)->set(Th,P,Pt,T,label,R2(E.y,-E.x)/le,ie);
1693                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
1694 
1695 
1696                 for ( i=0;  i<n;   i++ )
1697                 // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
1698                 {
1699                     RNM_ wi(fv(i,'.','.'));
1700                     int ig=Kv(i);
1701                     for ( j=0;  j<m;   j++ )
1702                     {
1703                         RNM_ wj(fu(j,'.','.'));
1704                         int il=0;
1705                         int jg=Ku(j);
1706                         if( ! sym || ig <= jg )
1707                         for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
1708                         {
1709                             BilinearOperator::K ll(*l);
1710                             pair<int,int> jj(ll.first.first),ii(ll.first.second);
1711                             double w_i =  wi(ii.first,ii.second);
1712                             double w_j =  wj(jj.first,jj.second);
1713                             // R ccc = GetAny<R>(ll.second.eval(stack));
1714 
1715                             R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
1716                             double wij =  w_i*w_j;
1717                             if (abs(wij)>= 1e-10&& (verbosity>1000))
1718                             cout << " \t\t\t" << ig << " " << jg << " "  <<  ccc <<  " " <<  coef * ccc * w_i*w_j << " on edge \n" ;
1719                             if (abs(wij)>= 1e-10)
1720                             A[make_pair(ig,jg)] += wij*coef*ccc ;
1721                         }
1722                     }
1723                 }
1724             }
1725         }
1726 
1727         *MeshPointStack(stack) = mp;
1728     }
1729 
1730 
1731 
1732     template<class R>
AddMatElem(Expression const * const mapu,Expression const * const mapt,MatriceMap<R> & A,const Mesh & Th,const BilinearOperator & Op,bool sym,int it,int ie,int label,const FESpace & Uh,const FESpace & Vh,const QuadratureFormular & FI,const QuadratureFormular1d & FIb,double * p,void * vstack,bool intmortar=false,R2 * Q=0)1733     void  AddMatElem(Expression const *const  mapu,Expression const * const mapt, MatriceMap<R> & A,const Mesh & Th,const BilinearOperator & Op,bool sym,int it,  int ie,int label,
1734                      const FESpace & Uh,const FESpace & Vh,
1735                      const QuadratureFormular & FI,
1736                      const QuadratureFormular1d & FIb,
1737                      double *p,   void *vstack, bool intmortar=false,R2 *Q=0)
1738     {
1739         //cout << "AddMatElem" << Q << " "  << ie << endl;
1740         Stack stack=pvoid2Stack(vstack);
1741         MeshPoint mp= *MeshPointStack(stack);
1742         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
1743         const Mesh & Thu(Uh.Th);
1744         const Mesh & Thv(Vh.Th);
1745 
1746         bool same = (&Uh == & Vh) && !mapu && !mapt;
1747         bool sameu =  &Th == & Thu && !mapu ;
1748         bool samev =  &Th == & Thv && !mapt ;
1749         const Triangle & T  = Th[it];
1750         long npi;
1751         long i,j;
1752         bool classoptm = copt && Op.optiexpK;
1753         assert(Op.MaxOp() <last_operatortype);
1754         //
1755 
1756 
1757         KN<bool> Dop(last_operatortype);
1758         Op.DiffOp(Dop);
1759         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
1760         //assert(lastop<=3);
1761 
1762         if (ie<0)
1763         {
1764             for (npi=0;npi<FI.n;npi++) // loop on the integration point
1765             {
1766                 QuadraturePoint pi(FI[npi]);
1767                 double coef = T.area*pi.a;
1768                 R2 Pt(pi),Ptu,Ptv;
1769                 R2 P(T(Pt)),Pu(P),Pv(P);
1770                 MeshPointStack(stack)->set(Th,P,Pt,T,label);
1771 
1772                 if(mapu)
1773                 Pu = R2( GetAny<double>((*mapu[0])(vstack)), GetAny<double>((*mapu[1])(vstack)));
1774                 if(mapt)
1775                 Pv = R2( GetAny<double>((*mapt[0])(vstack)), GetAny<double>((*mapt[1])(vstack)));
1776                 if(verbosity>9999 && (mapu || mapt) )
1777                 cout << " mapinng: " << P << " AddMatElem + map  -> (u) " << Pu << "  (t) ->"<< Pv << endl;
1778                 bool outsideu,outsidev;
1779                 // ici trouve le T
1780                 int iut=0,ivt=0;
1781                 const Triangle * tu,*tv;
1782                 if(sameu )
1783                 {
1784                     tu =&T;
1785                     Ptu=Pt;
1786                 }
1787                 else
1788                 {
1789                     tu= Thu.Find(Pu,Ptu,outsideu);
1790                     if( !tu ||  outsideu) {
1791                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " << endl;
1792                         continue;}}
1793                 if(same )
1794                 {
1795                     tv=tu;
1796                     outsidev=outsideu;
1797                     Ptv=Ptu;
1798                 }
1799                 else if(samev)
1800                 {
1801                     tv =&T;
1802                     Ptv=Pt;
1803 
1804                 }
1805                 else
1806                 {
1807                     tv= Thv.Find(Pv,Ptv,outsidev);
1808                     if( !tv || outsidev) {
1809                         if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
1810                         continue;
1811                     }
1812                 }
1813                 iut = Thu(tu);
1814                 ivt = Thv(tv);
1815                 if( verbosity>1000) cout << " T " << it  << "  iut " << iut << " ivt " << ivt  <<  endl ;
1816                 FElement Ku(Uh[iut]);
1817                 FElement Kv(Vh[ivt]);
1818                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
1819                 long N= Kv.N;
1820                 long M= Ku.N;
1821                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
1822                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
1823 
1824 
1825                 Ku.BF(Dop,Ptu,fu);
1826                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
1827                 if (!same) Kv.BF(Dop,Ptv,fv);
1828                 for ( i=0;  i<n;   i++ )
1829                 {
1830 
1831                     // attention la fonction test donne la ligne
1832                     //  et la fonction test est en second
1833                     int ig = Kv(i);
1834                     RNM_ wi(fv(i,'.','.'));
1835                     for ( j=0;  j<m;   j++ )
1836                     {
1837                         RNM_ wj(fu(j,'.','.'));
1838                         int il=0;
1839                         int jg(Ku(j));
1840                         if ( !sym ||  ig <= jg )
1841                         for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
1842                         {  // attention la fonction test donne la ligne
1843                             //  et la fonction test est en second
1844                             BilinearOperator::K ll(*l);
1845                             pair<int,int> jj(ll.first.first),ii(ll.first.second);
1846                             double w_i =  wi(ii.first,ii.second);
1847                             double w_j =  wj(jj.first,jj.second);
1848                             R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack))   ;
1849                             if( verbosity>1000) cout << ig << " " << jg << " "  <<  " " << ccc << " " <<  coef * ccc * w_i*w_j << " on T \n"   ;
1850                             double wij =  w_i*w_j;
1851                             if (abs(wij)>= 1e-10)
1852                             A[make_pair(ig,jg)] += coef * ccc * wij;
1853                         }
1854                     }
1855                 }
1856             }
1857         }
1858         else // int on edge ie
1859         {
1860             R2 PA,PB,E;
1861             if(Q)
1862             {
1863                 PA=Q[0];
1864                 PB=Q[1];
1865                 E=T(PB)-T(PA);
1866                 // cout << " AddMAtElem " <<  PA <<  " " << PB << " "<< sqrt((E,E))<< endl;
1867             }
1868             else
1869             {
1870                 PA=TriangleHat[VerticesOfTriangularEdge[ie][0]];
1871                 PB=TriangleHat[VerticesOfTriangularEdge[ie][1]];
1872                 E=T.Edge(ie);
1873             }
1874             double le = sqrt((E,E));
1875 
1876             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
1877             {
1878                 QuadratureFormular1dPoint pi( FIb[npi]);
1879                 double sa=pi.x,sb=1-sa;
1880                 double coef = le*pi.a;
1881 
1882                 R2 Pt(PA*sa+PB*sb ); //
1883 
1884                 R2 Ptu,Ptv;
1885                 R2 P(T(Pt)),Pu(P),Pv(P);
1886                 MeshPointStack(stack)->set(Th,P,Pt,T,label,R2(E.y,-E.x)/le,ie);
1887                 if(mapu)
1888                 Pu = R2( GetAny<double>((*mapu[0])(vstack)), GetAny<double>((*mapu[1])(vstack)));
1889                 if(mapt)
1890                 Pv = R2( GetAny<double>((*mapt[0])(vstack)), GetAny<double>((*mapt[1])(vstack)));
1891 
1892                 bool outsideu,outsidev;
1893                 // ici trouve le T
1894                 int iut=0,ivt=0;
1895                 const Triangle * tu, *tv;
1896                 if(sameu )
1897                 {
1898                     tu =&T;
1899                     Ptu=Pt;
1900                 }
1901                 else
1902                 {
1903                     tu= Thu.Find(Pu,Ptu,outsideu);
1904                     if( !tu ||  (outsideu && !intmortar) )  {
1905                         //R dd=-1;
1906                         //if(tu) { R2 PP((*tu)(Ptu)),PPP(P,PP) ; cout << PP << " " << sqrt( (PPP,PPP) ) <<"    "; }
1907                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " <<Ptu << " " << tu <<   endl;
1908                         continue;}}
1909                 iut = Thu(tu);
1910 
1911 
1912                 if(samev)
1913                 {
1914                     tv =&T;
1915                     Ptv=Pt;
1916                 }
1917                 else {
1918                     tv= Thv.Find(Pv,Ptv,outsidev);
1919                     if( !tv || (outsidev&& !intmortar))  {
1920                         if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
1921                         continue;}}
1922                 ivt = Thv(tv);
1923 
1924                 FElement Ku(Uh[iut]);
1925                 FElement Kv(Vh[ivt]);
1926                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
1927                 long N= Kv.N;
1928                 long M= Ku.N;
1929                 //  cout << P << " " <<  Pt << " " <<  iut << " " << ivt  << "  Ptu : " << Ptu << " Ptv: " << Ptv << " n:" << n << " m:" << m << endl;
1930                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
1931                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
1932 
1933                 Ku.BF(Dop,Ptu,fu);
1934                 if( !same)
1935                 Kv.BF(Dop,Ptv,fv);
1936 
1937 
1938                 // int label=-999999; // a passer en argument
1939 
1940                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
1941 
1942 
1943                 for ( i=0;  i<n;   i++ )
1944                 // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
1945                 {
1946                     RNM_ wi(fv(i,'.','.'));
1947                     int ig=Kv(i);
1948                     for ( j=0;  j<m;   j++ )
1949                     {
1950                         RNM_ wj(fu(j,'.','.'));
1951                         int il=0;
1952                         int jg=Ku(j);
1953                         if( ! sym || ig <= jg )
1954                         for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
1955                         {
1956                             BilinearOperator::K ll(*l);
1957                             pair<int,int> jj(ll.first.first),ii(ll.first.second);
1958                             double w_i =  wi(ii.first,ii.second);
1959                             double w_j =  wj(jj.first,jj.second);
1960                             // R ccc = GetAny<R>(ll.second.eval(stack));
1961 
1962                             R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
1963                             double wij =  w_i*w_j;
1964                             if (abs(wij)>= 1e-10&& (verbosity>1000))
1965                             cout << " \t\t\t" << ig << " " << jg << " "  <<  ccc <<  " " <<  coef * ccc * w_i*w_j << " on edge \n" ;
1966                             if (abs(wij)>= 1e-10)
1967                             A[make_pair(ig,jg)] += wij*coef*ccc ;
1968                         }
1969                     }
1970                 }
1971             }
1972         }
1973 
1974         *MeshPointStack(stack) = mp;
1975     }
1976 
1977 
1978     //3D volume
1979     template<class R>
AddMatElem(MatriceMap<R> & A,const Mesh3 & Th,const BilinearOperator & Op,bool sym,int it,int ie,int label,const FESpace3 & Uh,const FESpace3 & Vh,const Fem2D::GQuadratureFormular<R3> & FI,const QuadratureFormular & FIb,double * p,void * vstack,bool intmortar=false)1980     void  AddMatElem(MatriceMap<R> & A,const Mesh3 & Th,const BilinearOperator & Op,bool sym,int it,  int ie,int label,
1981                      const FESpace3 & Uh,const FESpace3 & Vh,
1982                      const Fem2D::GQuadratureFormular<R3>  & FI,
1983                      const  QuadratureFormular & FIb,
1984                      double *p,   void *vstack, bool intmortar=false)
1985     {
1986 
1987         Stack stack=pvoid2Stack(vstack);
1988         MeshPoint mp= *MeshPointStack(stack);
1989         static int count =0; // non test FH .........................
1990         if(count++ < 1) {
1991             cout << " Warning : Assemble Matrix with incompatible 3d meshes in test (FH)  " << endl;
1992             cout << " ------------------------------------------------------------- " << endl;
1993         }
1994         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
1995         const Mesh3 & Thu(Uh.Th);
1996         const Mesh3 & Thv(Vh.Th);
1997 
1998         bool same = &Uh == & Vh;
1999         const Tet & T  = Th[it];
2000         long npi;
2001         long i,j;
2002         bool classoptm = copt && Op.optiexpK;
2003         assert(Op.MaxOp() <last_operatortype);
2004         //
2005         int lastop=0;
2006         lastop = 0;
2007         What_d Dop = Op.DiffOp(lastop);
2008 
2009 
2010         //assert(lastop<=3);
2011 
2012         if (ie<0)
2013         for (npi=0;npi<FI.n;npi++) // loop on the integration point
2014         {
2015             GQuadraturePoint<R3> pi(FI[npi]);
2016             double coef = T.mesure()*pi.a;
2017             R3 Pt(pi),Ptu,Ptv;
2018             R3 P(T(Pt));
2019             bool outsideu,outsidev;
2020             // ici trouve le T
2021             int iut=0,ivt=0;
2022             const Tet * tu,*tv;
2023             if(&Th == & Thu )
2024             {
2025                 tu =&T;
2026                 Ptu=Pt;
2027             }
2028             else
2029             {
2030                 tu= Thu.Find(P,Ptu,outsideu);
2031                 if( !tu ||  outsideu) {
2032                     if(verbosity>100) cout << " On a pas trouver (u) " << P << " " << endl;
2033                     continue;}}
2034             if(same)
2035             {
2036                 tv=tu;
2037                 outsidev=outsideu;
2038                 Ptv=Ptu;
2039             }
2040             else
2041             {
2042                 if(&Th == & Thv )
2043                 {
2044                     tv =&T;
2045                     Ptv=Pt;
2046                 }
2047                 else
2048                 {
2049                     tv= Thv.Find(P,Ptv,outsidev);
2050                     if( !tv || outsidev) {
2051                         if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
2052                         continue;
2053                     }}
2054             }
2055             iut = Thu(tu);
2056             ivt = Thv(tv);
2057             if( verbosity>1000) cout << " T " << it  << "  iut " << iut << " ivt " << ivt  <<  endl ;
2058             FElement3 Ku(Uh[iut]);
2059             FElement3 Kv(Vh[ivt]);
2060             long n= Kv.NbDoF() ,m=Ku.NbDoF();
2061             long N= Kv.N;
2062             long M= Ku.N;
2063             RNMK_ fv(p,n,N,(long) lastop); //  the value for basic fonction
2064             RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,(long) lastop); //  the value for basic fonction
2065 
2066 
2067             Ku.BF(Dop,Ptu,fu);
2068             MeshPointStack(stack)->set(Th,P,Pt,T,label);
2069             if (classoptm) (*Op.optiexpK)(stack); // call optim version
2070             if (!same) Kv.BF(Dop,Ptv,fv);
2071             for ( i=0;  i<n;   i++ )
2072             {
2073 
2074                 // attention la fonction test donne la ligne
2075                 //  et la fonction test est en second
2076                 int ig = Kv(i);
2077                 RNM_ wi(fv(i,'.','.'));
2078                 for ( j=0;  j<m;   j++ )
2079                 {
2080                     RNM_ wj(fu(j,'.','.'));
2081                     int il=0;
2082                     int jg(Ku(j));
2083                     if ( !sym ||  ig <= jg )
2084                     for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
2085                     {  // attention la fonction test donne la ligne
2086                         //  et la fonction test est en second
2087                         BilinearOperator::K ll(*l);
2088                         pair<int,int> jj(ll.first.first),ii(ll.first.second);
2089                         double w_i =  wi(ii.first,ii.second);
2090                         double w_j =  wj(jj.first,jj.second);
2091                         R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack))   ;
2092                         if( verbosity>1000) cout << ig << " " << jg << " "  <<  " " << ccc << " " <<  coef * ccc * w_i*w_j << " on T \n"   ;
2093                         double wij =  w_i*w_j;
2094                         if (abs(wij)>= 1e-10)
2095                         A[make_pair(ig,jg)] += coef * ccc * wij;
2096                     }
2097                 }
2098             }
2099         }
2100         else // int on edge ie
2101         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
2102         {
2103 
2104             GQuadraturePoint<R2> pi( FIb[npi]);
2105             R3 NN= T.N(ie);
2106             double mes=NN.norme();
2107             NN/=mes;
2108             double coef = 0.5*mes*pi.a; // correction 0.5 050109 FH
2109             R3 Pt(T.PBord(ie,pi));
2110             //Ku.BF(Dop,Pt,fu);
2111 
2112 
2113 
2114             R3 Ptu,Ptv;
2115             R3 P(T(Pt));
2116             bool outsideu,outsidev;
2117             // ici trouve le T
2118             int iut=0,ivt=0;
2119             const Tet * tu, *tv;
2120             if(&Th == & Thu )
2121             {
2122                 tu =&T;
2123                 Ptu=Pt;
2124             }
2125             else
2126             {
2127                 tu= Thu.Find(P,Ptu,outsideu);
2128                 if( !tu ||  (outsideu && !intmortar) )  {
2129                     //R dd=-1;
2130                     //if(tu) { R2 PP((*tu)(Ptu)),PPP(P,PP) ; cout << PP << " " << sqrt( (PPP,PPP) ) <<"    "; }
2131                     if(verbosity>100) cout << " On a pas trouver (u) " << P << " " <<Ptu << " " << tu <<   endl;
2132                     continue;}}
2133             iut = Thu(tu);
2134             if(same)
2135             {
2136                 tv=tu;
2137                 outsidev=outsideu;
2138                 Ptv=Ptu;
2139                 ivt=iut;
2140             }
2141             else
2142             {
2143                 if(&Th == & Thv )
2144                 {
2145                     tv =&T;
2146                     Ptv=Pt;
2147                 }
2148                 else {
2149                     tv= Thv.Find(P,Ptv,outsidev);
2150                     if( !tv || (outsidev&& !intmortar))  {
2151                         if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
2152                         continue;}}
2153                 ivt = Thv(tv);
2154             }
2155             FElement3 Ku(Uh[iut]);
2156             FElement3 Kv(Vh[ivt]);
2157             long n= Kv.NbDoF() ,m=Ku.NbDoF();
2158             long N= Kv.N;
2159             long M= Ku.N;
2160             //  cout << P << " " <<  Pt << " " <<  iut << " " << ivt  << "  Ptu : " << Ptu << " Ptv: " << Ptv << " n:" << n << " m:" << m << endl;
2161             RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
2162             RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
2163 
2164             Ku.BF(Dop,Ptu,fu);
2165             if( !same)
2166             Kv.BF(Dop,Ptv,fv);
2167 
2168 
2169             // int label=-999999; // a passer en argument
2170             MeshPointStack(stack)->set(Th,P,Pt,T,label,NN,ie);
2171             if (classoptm) (*Op.optiexpK)(stack); // call optim version
2172 
2173 
2174             for ( i=0;  i<n;   i++ )
2175             // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
2176             {
2177                 RNM_ wi(fv(i,'.','.'));
2178                 int ig=Kv(i);
2179                 for ( j=0;  j<m;   j++ )
2180                 {
2181                     RNM_ wj(fu(j,'.','.'));
2182                     int il=0;
2183                     int jg=Ku(j);
2184                     if( ! sym || ig <= jg )
2185                     for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
2186                     {
2187                         BilinearOperator::K ll(*l);
2188                         pair<int,int> jj(ll.first.first),ii(ll.first.second);
2189                         double w_i =  wi(ii.first,ii.second);
2190                         double w_j =  wj(jj.first,jj.second);
2191                         // R ccc = GetAny<R>(ll.second.eval(stack));
2192 
2193                         R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
2194                         double wij =  w_i*w_j;
2195                         if (abs(wij)>= 1e-10&& (verbosity>1000))
2196                         cout << " \t\t\t" << ig << " " << jg << " "  <<  ccc <<  " " <<  coef * ccc * w_i*w_j << " on edge \n" ;
2197                         if (abs(wij)>= 1e-10)
2198                         A[make_pair(ig,jg)] += wij*coef*ccc ;
2199                     }
2200                 }
2201             }
2202         }
2203 
2204 
2205         *MeshPointStack(stack) = mp;
2206     }
2207 
2208 
2209  // 3D surface case
2210     template<class R>
AddMatElem(MatriceMap<R> & A,const MeshS & Th,const BilinearOperator & Op,bool sym,int it,int ie,int label,const FESpaceS & Uh,const FESpaceS & Vh,const QuadratureFormular & FI,const QuadratureFormular1d & FIb,double * p,void * vstack,bool intmortar=false)2211     void  AddMatElem(MatriceMap<R> & A,const MeshS & Th,const BilinearOperator & Op,bool sym,int it,  int ie,int label,
2212                      const FESpaceS & Uh,const FESpaceS & Vh,
2213                      const QuadratureFormular & FI,
2214                      const QuadratureFormular1d & FIb,
2215                      double *p,   void *vstack, bool intmortar=false)
2216     {
2217        // ffassert(0);
2218 
2219         Stack stack=pvoid2Stack(vstack);
2220         MeshPoint mp= *MeshPointStack(stack);
2221         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
2222         const MeshS & Thu(Uh.Th);
2223         const MeshS & Thv(Vh.Th);
2224 
2225         bool same = &Uh == & Vh;
2226         const TriangleS & T  = Th[it];
2227         long npi;
2228         long i,j;
2229         bool classoptm = copt && Op.optiexpK;
2230         assert(Op.MaxOp() <last_operatortype);
2231         //
2232 
2233         //KN<bool> Dop(last_operatortype);
2234         //Op.DiffOp(Dop);
2235         //int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
2236         //assert(lastop<=3);
2237 
2238         int lastop=0;
2239         What_d Dop = Op.DiffOp(lastop);
2240 
2241         if (ie<0)
2242         {
2243             for (npi=0;npi<FI.n;npi++) // loop on the integration point
2244             {
2245                 QuadraturePoint pi(FI[npi]);
2246                 double coef = T.mesure()*pi.a;
2247                 R2 Pt(pi),Ptu,Ptv;
2248                 R3 P(T(Pt));
2249                 bool outsideu,outsidev;
2250                 // ici trouve le T
2251                 int iut=0,ivt=0;
2252                 const TriangleS * tu,*tv;
2253                 if(&Th == & Thu )
2254                 {
2255                     tu =&T;
2256                     Ptu=Pt;
2257                 }
2258                 /*else
2259                 {
2260                     tu= Thu.Find(P,Ptu,outsideu);           // problem find
2261                     if( !tu ||  outsideu) {
2262                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " << endl;
2263                         continue;}}*/
2264                 if(same)
2265                 {
2266                     tv=tu;
2267                     outsidev=outsideu;
2268                     Ptv=Ptu;
2269                 }
2270                 else
2271                 {
2272                     if(&Th == & Thv )
2273                     {
2274                         tv =&T;
2275                         Ptv=Pt;
2276                     }
2277                    /* else       // problem find
2278                     {
2279                         tv= Thv.Find(P,Ptv,outsidev);
2280                         if( !tv || outsidev) {
2281                             if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
2282                             continue;
2283                         }}*/
2284                 }
2285                 iut = Thu(tu);
2286                 ivt = Thv(tv);
2287                 if( verbosity>1000) cout << " T " << it  << "  iut " << iut << " ivt " << ivt  <<  endl ;
2288                 FElementS Ku(Uh[iut]);
2289                 FElementS Kv(Vh[ivt]);
2290                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
2291                 long N= Kv.N;
2292                 long M= Ku.N;
2293                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
2294                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
2295 
2296 
2297                 Ku.BF(Dop,Ptu,fu);
2298                 MeshPointStack(stack)->set(Th,P,Pt,T,label);
2299                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
2300                 if (!same) Kv.BF(Dop,Ptv,fv);
2301                 for ( i=0;  i<n;   i++ )
2302                 {
2303 
2304                     // attention la fonction test donne la ligne
2305                     //  et la fonction test est en second
2306                     int ig = Kv(i);
2307                     RNM_ wi(fv(i,'.','.'));
2308                     for ( j=0;  j<m;   j++ )
2309                     {
2310                         RNM_ wj(fu(j,'.','.'));
2311                         int il=0;
2312                         int jg(Ku(j));
2313                         if ( !sym ||  ig <= jg )
2314                             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
2315                             {  // attention la fonction test donne la ligne
2316                                 //  et la fonction test est en second
2317                                 BilinearOperator::K ll(*l);
2318                                 pair<int,int> jj(ll.first.first),ii(ll.first.second);
2319                                 double w_i =  wi(ii.first,ii.second);
2320                                 double w_j =  wj(jj.first,jj.second);
2321                                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack))   ;
2322                                 if( verbosity>1000) cout << ig << " " << jg << " "  <<  " " << ccc << " " <<  coef * ccc * w_i*w_j << " T \n"   ;
2323                                 double wij =  w_i*w_j;
2324                                 if (abs(wij)>= 1e-10)
2325                                 A[make_pair(ig,jg)] += coef * ccc * wij;
2326                             }
2327                     }
2328                 }
2329             }
2330         }
2331         else // int on edge ie
2332         //{
2333             ffassert(0);
2334             /*R2 PA,PB;
2335             PA=TriangleHat[VerticesOfTriangularEdge[ie][0]];
2336             PB=TriangleHat[VerticesOfTriangularEdge[ie][1]];
2337             R3 E=T.Edge(ie);
2338             double le = sqrt((E,E));
2339             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
2340             {
2341                 QuadratureFormular1dPoint pi( FIb[npi]);
2342                 double sa=pi.x,sb=1-sa;
2343                 double coef = le*pi.a;
2344                 R2 Pt(PA*sa+PB*sb );
2345                 R2 Ptu,Ptv;
2346                 R3 P(T(Pt));
2347 
2348                 bool outsideu,outsidev;
2349                 // ici trouve le T
2350                 int iut=0,ivt=0;
2351                 const TriangleS* tu, *tv;
2352                 if(&Th == & Thu )
2353                 {
2354                     tu =&T;
2355                     Ptu=Pt;
2356                 }
2357                 else
2358                 {
2359                     tu= Thu.Find(P,Ptu,outsideu);        ////// probleme
2360                     if( !tu ||  (outsideu && !intmortar) )  {
2361                         //R dd=-1;
2362                         //if(tu) { R2 PP((*tu)(Ptu)),PPP(P,PP) ; cout << PP << " " << sqrt( (PPP,PPP) ) <<"    "; }
2363                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " <<Ptu << " " << tu <<   endl;
2364                         continue;}}
2365 
2366                 iut = Thu(tu);
2367 
2368                 if(same)
2369                 {
2370                     tv=tu;
2371                     outsidev=outsideu;
2372                     Ptv=Ptu;
2373                     ivt=iut;
2374                 }
2375                 else
2376                 {
2377                     if(&Th == & Thv )
2378                     {
2379                         tv =&T;
2380                         Ptv=Pt;
2381                     }
2382                     else {
2383                         tv= Thv.Find(P,Ptv,outsidev);
2384                         if( !tv || (outsidev&& !intmortar))  {
2385                             if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
2386                             continue;}}
2387                     ivt = Thv(tv);
2388                 }
2389 
2390                 FElementS Ku(Uh[iut]);
2391                 FElementS Kv(Vh[ivt]);
2392                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
2393                 long N= Kv.N;
2394                 long M= Ku.N;
2395                 //  cout << P << " " <<  Pt << " " <<  iut << " " << ivt  << "  Ptu : " << Ptu << " Ptv: " << Ptv << " n:" << n << " m:" << m << endl;
2396                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
2397                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
2398 
2399                 Ku.BF(Dop,Ptu,fu);
2400                 if( !same)
2401                     Kv.BF(Dop,Ptv,fv);
2402 
2403                 R3 NN= T.N(ie); //dHat=2
2404                 // int label=-999999; // a passer en argument
2405                 MeshPointStack(stack)->set(Th,P,Pt,T,label,NN,ie);
2406                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
2407 
2408 
2409                 for ( i=0;  i<n;   i++ )
2410                     // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
2411                 {
2412                     RNM_ wi(fv(i,'.','.'));
2413                     int ig=Kv(i);
2414                     for ( j=0;  j<m;   j++ )
2415                     {
2416                         RNM_ wj(fu(j,'.','.'));
2417                         int il=0;
2418                         int jg=Ku(j);
2419                         if( ! sym || ig <= jg )
2420                             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
2421                             {
2422                                 BilinearOperator::K ll(*l);
2423                                 pair<int,int> jj(ll.first.first),ii(ll.first.second);
2424                                 double w_i =  wi(ii.first,ii.second);
2425                                 double w_j =  wj(jj.first,jj.second);
2426                                 // R ccc = GetAny<R>(ll.second.eval(stack));
2427 
2428                                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
2429                                 double wij =  w_i*w_j;
2430                                 if (abs(wij)>= 1e-10&& (verbosity>1000))
2431                                     cout << " \t\t\t" << ig << " " << jg << " "  <<  ccc <<  " " <<  coef * ccc * w_i*w_j << " on edge \n" ;
2432                                 if (abs(wij)>= 1e-10)
2433                                     A[make_pair(ig,jg)] += wij*coef*ccc ;
2434                             }
2435                     }
2436                 }}
2437             }*/
2438 
2439 
2440         *MeshPointStack(stack) = mp;
2441     }
2442 
2443 
2444 
2445 
2446     // 3D curve case
2447     template<class R>
AddMatElem(MatriceMap<R> & A,const MeshL & Th,const BilinearOperator & Op,bool sym,int it,int ie,int label,const FESpaceL & Uh,const FESpaceL & Vh,const GQuadratureFormular<R1> & FI,const QuadratureFormular1d & FIb,double * p,void * vstack,bool intmortar=false)2448     void  AddMatElem(MatriceMap<R> & A,const MeshL & Th,const BilinearOperator & Op,bool sym,int it,  int ie,int label,
2449                      const FESpaceL & Uh,const FESpaceL & Vh,
2450                      const GQuadratureFormular<R1> & FI,
2451                      const QuadratureFormular1d & FIb,
2452                      double *p,   void *vstack, bool intmortar=false)
2453     {
2454         // ffassert(0);
2455 
2456         Stack stack=pvoid2Stack(vstack);
2457         MeshPoint mp= *MeshPointStack(stack);
2458         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
2459         const MeshL & Thu(Uh.Th);
2460         const MeshL & Thv(Vh.Th);
2461 
2462         bool same = &Uh == & Vh;
2463         const EdgeL & T  = Th[it];
2464         long npi;
2465         long i,j;
2466         bool classoptm = copt && Op.optiexpK;
2467         assert(Op.MaxOp() <last_operatortype);
2468 
2469         int lastop=0;
2470         What_d Dop = Op.DiffOp(lastop);
2471 
2472         if (ie<0)
2473         {
2474             for (npi=0;npi<FI.n;npi++) // loop on the integration point
2475             {
2476                 GQuadraturePoint<R1> pi(FI[npi]);
2477                 double coef = T.mesure()*pi.a;
2478                 R1 Pt(pi),Ptu,Ptv;
2479                 R3 P(T(Pt));
2480                 bool outsideu,outsidev;
2481                 // ici trouve le T
2482                 int iut=0,ivt=0;
2483                 const EdgeL * tu,*tv;
2484                 if(&Th == & Thu ) {
2485                     tu =&T;
2486                     Ptu=Pt;
2487                 }
2488 
2489                 if(same) {
2490                     tv=tu;
2491                     outsidev=outsideu;
2492                     Ptv=Ptu;
2493                 }
2494                 else if(&Th == & Thv ) {
2495                         tv =&T;
2496                         Ptv=Pt;
2497                 }
2498 
2499                 iut = Thu(tu);
2500                 ivt = Thv(tv);
2501                 if( verbosity>1000) cout << " T " << it  << "  iut " << iut << " ivt " << ivt  <<  endl ;
2502                 FElementL Ku(Uh[iut]), Kv(Vh[ivt]);
2503                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
2504                 long N= Kv.N;
2505                 long M= Ku.N;
2506                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
2507                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
2508 
2509 
2510                 Ku.BF(Dop,Ptu,fu);
2511                 MeshPointStack(stack)->set(Th,P,Pt,T,label);
2512                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
2513                 if (!same) Kv.BF(Dop,Ptv,fv);
2514                 for ( i=0;  i<n;   i++ ) {
2515                     // attention la fonction test donne la ligne
2516                     //  et la fonction test est en second
2517                     int ig = Kv(i);
2518                     RNM_ wi(fv(i,'.','.'));
2519                     for ( j=0;  j<m;   j++ ) {
2520                         RNM_ wj(fu(j,'.','.'));
2521                         int il=0;
2522                         int jg(Ku(j));
2523                         if ( !sym ||  ig <= jg )
2524                             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++) {
2525                                 // attention la fonction test donne la ligne
2526                                 //  et la fonction test est en second
2527                                 BilinearOperator::K ll(*l);
2528                                 pair<int,int> jj(ll.first.first),ii(ll.first.second);
2529                                 double w_i =  wi(ii.first,ii.second);
2530                                 double w_j =  wj(jj.first,jj.second);
2531                                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack))   ;
2532                                 if( verbosity>1000) cout << ig << " " << jg << " "  <<  " " << ccc << " " <<  coef * ccc * w_i*w_j << " T \n"   ;
2533                                 double wij =  w_i*w_j;
2534                                 if (abs(wij)>= 1e-10)
2535                                     A[make_pair(ig,jg)] += coef * ccc * wij;
2536                             }
2537                     }
2538                 }
2539             }
2540         }
2541         else // int on point ie
2542         //{
2543             ffassert(0);
2544             /*R2 PA,PB;
2545             PA=TriangleHat[VerticesOfTriangularEdge[ie][0]];
2546             PB=TriangleHat[VerticesOfTriangularEdge[ie][1]];
2547             R3 E=T.Edge(ie);
2548             double le = sqrt((E,E));
2549             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
2550             {
2551                 QuadratureFormular1dPoint pi( FIb[npi]);
2552                 double sa=pi.x,sb=1-sa;
2553                 double coef = le*pi.a;
2554                 R2 Pt(PA*sa+PB*sb );
2555                 R2 Ptu,Ptv;
2556                 R3 P(T(Pt));
2557 
2558                 bool outsideu,outsidev;
2559                 // ici trouve le T
2560                 int iut=0,ivt=0;
2561                 const TriangleS* tu, *tv;
2562                 if(&Th == & Thu )
2563                 {
2564                     tu =&T;
2565                     Ptu=Pt;
2566                 }
2567                 else
2568                 {
2569                     tu= Thu.Find(P,Ptu,outsideu);        ////// probleme
2570                     if( !tu ||  (outsideu && !intmortar) )  {
2571                         //R dd=-1;
2572                         //if(tu) { R2 PP((*tu)(Ptu)),PPP(P,PP) ; cout << PP << " " << sqrt( (PPP,PPP) ) <<"    "; }
2573                         if(verbosity>100) cout << " On a pas trouver (u) " << P << " " <<Ptu << " " << tu <<   endl;
2574                         continue;}}
2575 
2576                 iut = Thu(tu);
2577 
2578                 if(same)
2579                 {
2580                     tv=tu;
2581                     outsidev=outsideu;
2582                     Ptv=Ptu;
2583                     ivt=iut;
2584                 }
2585                 else
2586                 {
2587                     if(&Th == & Thv )
2588                     {
2589                         tv =&T;
2590                         Ptv=Pt;
2591                     }
2592                     else {
2593                         tv= Thv.Find(P,Ptv,outsidev);
2594                         if( !tv || (outsidev&& !intmortar))  {
2595                             if(verbosity>100) cout << " On a pas trouver (v) " << P << " " << endl;
2596                             continue;}}
2597                     ivt = Thv(tv);
2598                 }
2599 
2600                 FElementS Ku(Uh[iut]);
2601                 FElementS Kv(Vh[ivt]);
2602                 long n= Kv.NbDoF() ,m=Ku.NbDoF();
2603                 long N= Kv.N;
2604                 long M= Ku.N;
2605                 //  cout << P << " " <<  Pt << " " <<  iut << " " << ivt  << "  Ptu : " << Ptu << " Ptv: " << Ptv << " n:" << n << " m:" << m << endl;
2606                 RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
2607                 RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
2608 
2609                 Ku.BF(Dop,Ptu,fu);
2610                 if( !same)
2611                     Kv.BF(Dop,Ptv,fv);
2612 
2613                 R3 NN= T.N(ie); //dHat=2
2614                 // int label=-999999; // a passer en argument
2615                 MeshPointStack(stack)->set(Th,P,Pt,T,label,NN,ie);
2616                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
2617 
2618 
2619                 for ( i=0;  i<n;   i++ )
2620                     // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
2621                 {
2622                     RNM_ wi(fv(i,'.','.'));
2623                     int ig=Kv(i);
2624                     for ( j=0;  j<m;   j++ )
2625                     {
2626                         RNM_ wj(fu(j,'.','.'));
2627                         int il=0;
2628                         int jg=Ku(j);
2629                         if( ! sym || ig <= jg )
2630                             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
2631                             {
2632                                 BilinearOperator::K ll(*l);
2633                                 pair<int,int> jj(ll.first.first),ii(ll.first.second);
2634                                 double w_i =  wi(ii.first,ii.second);
2635                                 double w_j =  wj(jj.first,jj.second);
2636                                 // R ccc = GetAny<R>(ll.second.eval(stack));
2637 
2638                                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
2639                                 double wij =  w_i*w_j;
2640                                 if (abs(wij)>= 1e-10&& (verbosity>1000))
2641                                     cout << " \t\t\t" << ig << " " << jg << " "  <<  ccc <<  " " <<  coef * ccc * w_i*w_j << " on edge \n" ;
2642                                 if (abs(wij)>= 1e-10)
2643                                     A[make_pair(ig,jg)] += wij*coef*ccc ;
2644                             }
2645                     }
2646                 }}
2647         }*/
2648 
2649 
2650         *MeshPointStack(stack) = mp;
2651     }
2652 
2653 
2654 
2655 
2656 
2657 
2658 
2659    ////////////////////////////////////////////////
2660    // AssembleBilinearForm
2661    ////////////////////////////////////////////////
2662 
2663 
2664     // creating an instance of AssembleBilinearForm with map
2665     // case 2d
2666     template<class R>
AssembleBilinearForm(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,MatriceMap<R> & A,const FormBilinear * b)2667     void AssembleBilinearForm(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
2668                               MatriceMap<R>  & A, const  FormBilinear * b  )
2669 
2670     {
2671         /*FH:  case ..in 2D
2672          in varf ...
2673          all mesh can can be different ....
2674          */
2675         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
2676         bool sptrclean=true;
2677         //     sptr->clean(); // modif FH mars 2006  clean Ptr
2678 
2679         const CDomainOfIntegration & di= *b->di;
2680         const Mesh * pThdi = GetAny<pmesh>( (* di.Th)(stack));
2681         SHOWVERB(cout << " FormBilinear () " << endl);
2682         //MatriceElementaireSymetrique<R> *mates =0;
2683         // MatriceElementairePleine<R> *matep =0;
2684         const int useopt=di.UseOpt(stack);
2685         //double binside=di.binside(stack);
2686         const bool intmortar=di.intmortar(stack);
2687 
2688         if ( verbosity >1)
2689         {
2690             cout << " Integral   on Th "<< &Th << " nv :  " << Th.nv << " nt : " << Th.nt << endl;
2691             cout << "        Th/ u "<< &Uh.Th << " nv : " << Uh.Th.nv << "   nt : " << Uh.Th.nt << endl;
2692             cout << "        Th/ v "<< &Vh.Th << " nv : " << Vh.Th.nv << "   nt : " << Vh.Th.nt << endl;
2693             cout << "        suppose in mortar " << intmortar << "   levelset=  " << di.islevelset() << " withmap: " << di.withmap() << endl;
2694         }
2695         Expression  const * const mapt=*di.mapt?di.mapt:0 ;
2696         Expression  const * const mapu=*di.mapu?di.mapu:0 ;
2697         bool withmap =di.withmap();
2698         //   ExecError(" no map  in the case (4) ??");}
2699         ffassert(pThdi == & Th);
2700         //const vector<Expression>  & what(di.what);
2701         CDomainOfIntegration::typeofkind  kind = di.kind;
2702         set<int> setoflab;
2703         bool all=true;
2704         const QuadratureFormular1d & FIE = di.FIE(stack);
2705         const QuadratureFormular & FITo = di.FIT(stack);
2706         QuadratureFormular FIT(FITo,3);
2707         bool VF=b->VF();  // finite Volume or discontinous Galerkin
2708         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
2709         if (verbosity>3)
2710         {
2711             if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ,"  ;
2712             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
2713             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
2714             else cout << "  --  int 2d   (nQP: "<< FIT.n << " ) in "  ;
2715         }
2716         // if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (1)");
2717         if(di.islevelset() && (CDomainOfIntegration::int1d!=kind) &&  (CDomainOfIntegration::int2d!=kind) )
2718         InternalError("Sorry no levelset integration type on no int1d case");
2719 
2720         /*
2721          if (verbosity>3)
2722          if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border  " ;
2723          else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges, "   ;
2724          else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges, "   ;
2725          else cout << "  --  int  in  " ; */
2726         Expandsetoflab(stack,di, setoflab,all);
2727         /*
2728          for (size_t i=0;i<what.size();i++)
2729          {long  lab  = GetAny<long>( (*what[i])(stack));
2730          setoflab.insert(lab);
2731          if ( verbosity>3) cout << lab << " ";
2732          all=false;
2733          }*/
2734         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
2735         const E_F0 * poptiexp0=b->b->optiexp0;
2736         // const E_F0 & optiexpK=*b->b->optiexpK;
2737         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
2738         R** where_in_stack =0;
2739         if (n_where_in_stack_opt && useopt)
2740         where_in_stack = new R * [n_where_in_stack_opt];
2741         if (where_in_stack)
2742         {
2743             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
2744             for (int i=0;i<n_where_in_stack_opt;i++)
2745             {
2746                 int offset=b->b->where_in_stack_opt[i];
2747                 assert(offset>10);
2748                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
2749                 *(where_in_stack[i])=0;
2750             }
2751 
2752 
2753             if(poptiexp0)
2754             (*poptiexp0)(stack);
2755             KN<bool> ok(b->b->v.size());
2756             {  //   remove the zero coef in the liste
2757                 // R zero=R();
2758                 int il=0;
2759                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
2760                 ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
2761             }
2762             BilinearOperator b_nozer(*b->b,ok);
2763             if (verbosity % 10 > 3 )
2764             cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
2765             << "  total " << n_where_in_stack_opt << endl;
2766 
2767             if ( (verbosity/100) % 10 >= 2)
2768             {
2769                 int il=0;
2770 
2771                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
2772                 cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
2773                 << " offset=" << b->b->where_in_stack_opt[il]
2774                 << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
2775             }
2776         }
2777         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
2778 
2779         KN<double>  p(Vh.esize()+ Uh.esize() );
2780 
2781 
2782         if (verbosity >3)
2783         {
2784             if (all) cout << " all " << endl ;
2785             else cout << endl;
2786         }
2787 
2788         if (di.kind == CDomainOfIntegration::int1d )
2789         {
2790 
2791             if(di.islevelset())
2792             {
2793                 double uset = HUGE_VAL;
2794                 R2 Q[2];
2795                 double vol6[2];
2796                 KN<double> phi(Th.nv);phi=uset;
2797                 double f[3], ll=0;
2798                 for(int t=0; t< Th.nt;++t)
2799                 {
2800                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
2801                     {
2802                         double umx=-HUGE_VAL,umn=HUGE_VAL;
2803                         for(int i=0;i<3;++i)
2804                         {
2805                             int j= Th(t,i);
2806                             if( phi[j]==uset)
2807                             {
2808                                 MeshPointStack(stack)->setP(&Th,t,i);
2809                                 phi[j]= di.levelset(stack);//zzzz
2810                             }
2811                             f[i]=phi[j];
2812                             umx = std::max(umx,phi[j]);
2813                             umn = std::min(umn,phi[j]);
2814 
2815                         }
2816                         int ntp= IsoLineK(f,Q,1e-10);
2817                         if(verbosity>999 && ntp==2)
2818                         {
2819                             const Triangle &T = Th[t];
2820                             R2 E(T(Q[0]),T(Q[1]));
2821                             double le=sqrt((E,E));
2822                             ll += le;
2823                             cout << "\t\t" << ntp <<" :  " << Q[0] << " " << Q[1] << " ;  "
2824                             << f[0] << " " << f[1] << " " << f[2] << "  " << le << " / " << ll<<endl;
2825                         }
2826                         if( ntp==2)
2827                         { if( withmap)
2828                             AddMatElem(mapu,mapt,A,Th,*b->b,sym,t,10,Th[t].lab,Uh,Vh,FIT,FIE,p,stack,intmortar,Q);
2829                             else
2830                             AddMatElem(A,Th,*b->b,sym,t,10,Th[t].lab,Uh,Vh,FIT,FIE,p,stack,intmortar,Q);
2831                             if(sptrclean) sptrclean=sptr->clean();
2832                         }
2833                     }
2834                 }
2835                 FIT =FITo;
2836             }
2837 
2838 
2839             else
2840             {
2841                 for( int e=0;e<Th.neb;e++)
2842                 {
2843                     if (all || setoflab.find(Th.bedges[e].lab) != setoflab.end())
2844                     {
2845                         int ie,i =Th.BoundaryElement(e,ie);
2846                         if( withmap)
2847                         AddMatElem(mapu,mapt,A,Th,*b->b,sym,i,ie,Th.bedges[e].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
2848                         else
2849                         AddMatElem(A,Th,*b->b,sym,i,ie,Th.bedges[e].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
2850                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
2851                     }
2852                 }
2853             }}
2854         else if (di.kind == CDomainOfIntegration::intalledges)
2855         {
2856             cerr << " Sorry no implement to hard  "<< endl;
2857             ExecError("FH: no intalledges on diff mesh ???");
2858             ffassert(0); // a faire
2859             if(withmap)
2860             for (int i=0;i< Th.nt; i++)
2861             {
2862                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
2863                 for (int ie=0;ie<3;ie++)
2864                 AddMatElem(mapu,mapt,A,Th,*b->b,sym,i,ie,Th[i].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
2865                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
2866 
2867 
2868             }
2869 
2870             else
2871             for (int i=0;i< Th.nt; i++)
2872             {
2873                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
2874                 for (int ie=0;ie<3;ie++)
2875                 AddMatElem(A,Th,*b->b,sym,i,ie,Th[i].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
2876                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
2877 
2878 
2879             }
2880 
2881         }
2882         else if (di.kind == CDomainOfIntegration::intallVFedges)
2883         {
2884 
2885             cerr << " a faire intallVFedges " << endl;
2886             ffassert(0);
2887 
2888         }
2889         else if (di.kind == CDomainOfIntegration::int2d )
2890         {
2891             // cerr << " a faire CDomainOfIntegration::int2d  " << endl;
2892             if(di.islevelset())
2893             {
2894                 double uset = HUGE_VAL;
2895                 R2 Q[2][3];
2896                 double vol6[2];
2897                 KN<double> phi(Th.nv);phi=uset;
2898                 double f[3];
2899                 for(int t=0; t< Th.nt;++t)
2900                 {
2901                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
2902                     {
2903                         double umx=-HUGE_VAL,umn=HUGE_VAL;
2904                         for(int i=0;i<3;++i)
2905                         {
2906                             int j= Th(t,i);
2907                             if( phi[j]==uset)
2908                             {
2909                                 MeshPointStack(stack)->setP(&Th,t,i);
2910                                 phi[j]= di.levelset(stack);//zzzz
2911                             }
2912                             f[i]=phi[j];
2913                             umx = std::max(umx,phi[j]);
2914                             umn = std::min(umn,phi[j]);
2915 
2916                         }
2917                         int nt= UnderIso(f,Q, vol6,1e-14);
2918                         setQF<R2>(FIT,FITo,QuadratureFormular_T_1, Q,vol6,nt);
2919                         if(FIT.n)
2920                         {
2921                             if(withmap)
2922                             AddMatElem(mapu,mapt,A,Th,*b->b,sym,t,-1,Th[t].lab,Uh,Vh,FIT,FIE,p,stack);
2923                             else
2924                             AddMatElem(A,Th,*b->b,sym,t,-1,Th[t].lab,Uh,Vh,FIT,FIE,p,stack);
2925                         }
2926                         if(sptrclean) sptrclean=sptr->clean();
2927                     }
2928                 }
2929                 FIT =FITo;
2930             }
2931             else
2932 
2933             {
2934                 if(withmap)
2935                 for (int i=0;i< Th.nt; i++)
2936                 {
2937                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
2938                     AddMatElem(mapu,mapt,A,Th,*b->b,sym,i,-1,Th[i].lab,Uh,Vh,FIT,FIE,p,stack);
2939                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
2940                 }
2941 
2942                 else
2943                 for (int i=0;i< Th.nt; i++)
2944                 {
2945                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
2946                     AddMatElem(A,Th,*b->b,sym,i,-1,Th[i].lab,Uh,Vh,FIT,FIE,p,stack);
2947                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
2948                 }
2949 
2950             }}
2951         else
2952         InternalError(" kind of CDomainOfIntegration unkown");
2953 
2954         if (where_in_stack) delete [] where_in_stack;
2955     }
2956 
2957     // creating an instance of AssembleBilinearForm with map
2958     // case 3D volume
2959     template<class R>
AssembleBilinearForm(Stack stack,const Mesh3 & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,MatriceMap<R> & A,const FormBilinear * b)2960     void AssembleBilinearForm(Stack stack,const Mesh3 & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
2961                               MatriceMap<R>  & A, const  FormBilinear * b  )
2962 
2963     {
2964         /*FH:  case ..in 3D
2965          in varf ...
2966          all mesh can can be different ....
2967          */
2968 
2969         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
2970         bool sptrclean=true;
2971         //     sptr->clean(); // modif FH mars 2006  clean Ptr
2972         Fem2D::MeshPoint & mp (*Fem2D::MeshPointStack(stack)), mps = mp;
2973 
2974         const CDomainOfIntegration & di= *b->di;
2975         const Mesh3 * pThdi = GetAny<pmesh3>( (* di.Th)(stack));
2976         SHOWVERB(cout << " FormBilinear () " << endl);
2977         //MatriceElementaireSymetrique<R> *mates =0;
2978         // MatriceElementairePleine<R> *matep =0;
2979         const int useopt=di.UseOpt(stack);
2980         //double binside=di.binside(stack);
2981         const bool intmortar=di.intmortar(stack);
2982         if ( verbosity >1)
2983         {
2984             cout << " Integral   on Th "<< &Th << " nv :  " << Th.nv << " nt : " << Th.nt << endl;
2985             cout << "        Th/ u "<< &Uh.Th << " nv : " << Uh.Th.nv << "   nt : " << Uh.Th.nt << endl;
2986             cout << "        Th/ v "<< &Vh.Th << " nv : " << Vh.Th.nv << "   nt : " << Vh.Th.nt << endl;
2987             cout << "        suppose in mortar " << intmortar << endl;
2988         }
2989         assert(pThdi == & Th);
2990         //const vector<Expression>  & what(di.what);
2991         CDomainOfIntegration::typeofkind  kind = di.kind;
2992 
2993         set<int> setoflab;
2994         bool all=true;
2995         // const QuadratureFormular1d & FIEo = di.FIE(stack);
2996         const QuadratureFormular & FITo = di.FIT(stack);
2997         const GQuadratureFormular<R3> & FIVo = di.FIV(stack);
2998         //  to change the quadrature on element ... may 2014 FH ..
2999         // QuadratureFormular1d  FIE(FIEo,3);
3000         QuadratureFormular FIT(FITo,3);
3001         GQuadratureFormular<R3>  FIV(FIVo,3);
3002 
3003 
3004 
3005         //    const QuadratureFormular & FIT = di.FIT(stack);
3006         //    const Fem2D::GQuadratureFormular<R3> & FIV = di.FIV(stack);
3007         bool VF=b->VF();  // finite Volume or discontinous Galerkin
3008         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
3009         if (verbosity>3)
3010         {
3011             if (CDomainOfIntegration::int2d==kind) cout << "  -- boundary int border ( nQP: "<< FIT.n << ") ,"  ;
3012             else  if (CDomainOfIntegration::intallfaces==kind) cout << "  -- boundary int all edges ( nQP: "<< FIT.n << "),"  ;
3013             //else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIT.n << ")," ;
3014             else cout << "  --  int 3d   (nQP: "<< FIV.n << " ) in "  ;
3015         }
3016         if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (2)");
3017         if(di.islevelset() && (CDomainOfIntegration::int2d!=kind) && (CDomainOfIntegration::int3d!=kind) ) InternalError("Sorry no levelset integration type on no int2d case");
3018 
3019         Expandsetoflab(stack,di, setoflab,all);
3020         /*
3021          for (size_t i=0;i<what.size();i++)
3022          {long  lab  = GetAny<long>( (*what[i])(stack));
3023          setoflab.insert(lab);
3024          if ( verbosity>3) cout << lab << " ";
3025          all=false;
3026          }*/
3027         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
3028         const E_F0 *poptiexp0=b->b->optiexp0;
3029         // const E_F0 & optiexpK=*b->b->optiexpK;
3030         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
3031         R** where_in_stack =0;
3032         if (n_where_in_stack_opt && useopt)
3033         where_in_stack = new R * [n_where_in_stack_opt];
3034         if (where_in_stack)
3035         {
3036             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
3037             for (int i=0;i<n_where_in_stack_opt;i++)
3038             {
3039                 int offset=b->b->where_in_stack_opt[i];
3040                 assert(offset>10);
3041                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
3042                 *(where_in_stack[i])=0;
3043             }
3044 
3045 
3046             if(poptiexp0)
3047             (*poptiexp0)(stack);
3048             KN<bool> ok(b->b->v.size());
3049             {  //   remove the zero coef in the liste
3050                 // R zero=R();
3051                 int il=0;
3052                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
3053                 ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
3054             }
3055             BilinearOperator b_nozer(*b->b,ok);
3056             if (verbosity % 10 > 3 )
3057             cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
3058             << "  total " << n_where_in_stack_opt << endl;
3059 
3060             if ( (verbosity/100) % 10 >= 2)
3061             {
3062                 int il=0;
3063 
3064                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
3065                 cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
3066                 << " offset=" << b->b->where_in_stack_opt[il]
3067                 << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
3068             }
3069         }
3070         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
3071 
3072         KN<double>  p(Vh.esize()+ Uh.esize() );
3073 
3074 
3075         if (verbosity >3)
3076         {
3077             if (all) cout << " all " << endl ;
3078             else cout << endl;
3079         }
3080 
3081         if (di.kind == CDomainOfIntegration::int2d )
3082         {
3083             for( int e=0;e<Th.nbe;e++)
3084             {
3085                 if (all || setoflab.find(Th.be(e).lab) != setoflab.end())
3086                 {
3087                     int ie,i =Th.BoundaryElement(e,ie);
3088                     AddMatElem(A,Th,*b->b,sym,i,ie,Th.be(e).lab,Uh,Vh,FIV,FIT,p,stack,intmortar);
3089                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3090                 }
3091             }
3092         }
3093         else if (di.kind == CDomainOfIntegration::intallfaces)
3094         {
3095             ffassert(0); // a faire
3096 
3097             for (int i=0;i< Th.nt; i++)
3098             {
3099                 if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3100                 for (int ie=0;ie<3;ie++)
3101                 AddMatElem(A,Th,*b->b,sym,i,ie,Th[i].lab,Uh,Vh,FIV,FIT,p,stack,intmortar);
3102 
3103                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3104 
3105 
3106             }
3107 
3108         }
3109         /* else if (di.kind == CDomainOfIntegration::intallVFedges)
3110          {
3111 
3112          cerr << " a faire intallVFedges " << endl;
3113          ffassert(0);
3114 
3115          }  */
3116         else if (di.kind == CDomainOfIntegration::int3d )
3117         {
3118             if(di.islevelset())  //  may 2014 FH ...
3119             {   // int3d levelset < 0
3120                 double llevelset = 0;
3121                 const double uset = std::numeric_limits<double>::max();
3122                 // cout << " uset ="<<uset << endl;
3123                 R3 Q[3][4];
3124                 double vol6[3];
3125                 KN<double> phi(Th.nv);
3126                 phi=uset;
3127                 double f[4];
3128 
3129                 for (int t=0;t< Th.nt; t++)
3130                 {
3131 
3132                     const Mesh3::Element & K(Th[t]);
3133                     if (all || setoflab.find(Th[t].lab) != setoflab.end())
3134 
3135                     {
3136                         double umx=std::numeric_limits<double>::min(),umn=std::numeric_limits<double>::max();
3137                         for(int i=0;i<4;++i)
3138                         {
3139                             int j= Th(t,i);
3140                             if( phi[j]==uset)
3141                             {
3142                                 MeshPointStack(stack)->setP(&Th,t,i);
3143                                 phi[j]= di.levelset(stack);//zzzz
3144                             }
3145                             f[i]=phi[j];
3146                         }
3147                         int ntets= UnderIso(f,Q, vol6,1e-14);
3148                         setQF<R3>(FIV,FIVo,QuadratureFormular_Tet_1, Q,vol6,ntets);
3149                         if(FIV.n)
3150                         {
3151                             AddMatElem(A,Th,*b->b,sym,t,-1,Th[t].lab,Uh,Vh,FIV,FIT,p,stack);
3152                             if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3153 
3154                         }
3155 
3156                     }
3157                 }
3158                 FIV = FIVo;
3159 
3160             }
3161             else
3162 
3163             {
3164                 // cerr << " a faire CDomainOfIntegration::int3d  " << endl;
3165                 for (int i=0;i< Th.nt; i++)
3166                 {
3167                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3168                     AddMatElem(A,Th,*b->b,sym,i,-1,Th[i].lab,Uh,Vh,FIV,FIT,p,stack);
3169                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3170                 }
3171 
3172             } }
3173         else
3174         InternalError(" kind of CDomainOfIntegration unkown");
3175 
3176         if (where_in_stack) delete [] where_in_stack;
3177         mp=mps;// restore x,y,z
3178 
3179     }
3180 
3181     // creating an instance of AssembleBilinearForm with map
3182     // case 3D surface
3183     template<class R>
AssembleBilinearForm(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,MatriceMap<R> & A,const FormBilinear * b)3184     void AssembleBilinearForm(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
3185                               MatriceMap<R>  & A, const  FormBilinear * b  )
3186 
3187     {
3188         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
3189         bool sptrclean=true;
3190         //     sptr->clean(); // modif FH mars 2006  clean Ptr
3191 
3192         const CDomainOfIntegration & di= *b->di;
3193         ///typedef typename Trait_MESHO<FESpaceS>::MeshO * pmeshO;
3194        // pmeshO  ThbfO = GetAny<pmeshO>((*b->di->Th)(stack)); // case 3D surface ThbfO =
3195         pmeshS  pThdi = GetAny<pmeshS>((*b->di->Th)(stack)); //Trait_MESHO<FESpaceS>::topmesh(ThbfO);  //
3196 
3197         SHOWVERB(cout << " FormBilinear () " << endl);
3198         //MatriceElementaireSymetrique<R> *mates =0;
3199         // MatriceElementairePleine<R> *matep =0;
3200         const int useopt=di.UseOpt(stack);
3201         //double binside=di.binside(stack);
3202         const bool intmortar=di.intmortar(stack);
3203         if ( verbosity >1)
3204         {
3205             cout << " Integral   on Th "<< &Th << " nv :  " << Th.nv << " nt : " << Th.nt << endl;
3206             cout << "        Th/ u "<< &Uh.Th << " nv : " << Uh.Th.nv << "   nt : " << Uh.Th.nt << endl;
3207             cout << "        Th/ v "<< &Vh.Th << " nv : " << Vh.Th.nv << "   nt : " << Vh.Th.nt << endl;
3208             cout << "        suppose in mortar " << intmortar << "   levelset=  " << di.islevelset() << " withmap: " << di.withmap() << endl;
3209         }
3210         Expression  const * const mapt=*di.mapt?di.mapt:0 ;
3211         Expression  const * const mapu=*di.mapu?di.mapu:0 ;
3212         bool withmap =di.withmap();
3213         //   ExecError(" no map  in the case (4) ??");}
3214         assert(pThdi == & Th);
3215         //const vector<Expression>  & what(di.what);
3216         CDomainOfIntegration::typeofkind  kind = di.kind;
3217         set<int> setoflab;
3218         bool all=true;
3219         const QuadratureFormular1d & FIE = di.FIE(stack);
3220         const QuadratureFormular & FITo = di.FIT(stack);
3221         QuadratureFormular FIT(FITo,3);
3222         bool VF=b->VF();  // finite Volume or discontinous Galerkin
3223         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
3224         if (verbosity>3)
3225         {
3226             if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ,"  ;
3227             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
3228             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
3229             else cout << "  --  int 2d   (nQP: "<< FIT.n << " ) in "  ;
3230         }
3231         // if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (1)");
3232         if(di.islevelset() && (CDomainOfIntegration::int1d!=kind) &&  (CDomainOfIntegration::int2d!=kind) )
3233             InternalError("Sorry no levelset integration type on no int1d case");
3234 
3235         /*
3236          if (verbosity>3)
3237          if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border  " ;
3238          else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges, "   ;
3239          else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges, "   ;
3240          else cout << "  --  int  in  " ; */
3241         Expandsetoflab(stack,di, setoflab,all);
3242         /*
3243          for (size_t i=0;i<what.size();i++)
3244          {long  lab  = GetAny<long>( (*what[i])(stack));
3245          setoflab.insert(lab);
3246          if ( verbosity>3) cout << lab << " ";
3247          all=false;
3248          }*/
3249         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
3250         const E_F0 * poptiexp0=b->b->optiexp0;
3251         // const E_F0 & optiexpK=*b->b->optiexpK;
3252         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
3253         R** where_in_stack =0;
3254         if (n_where_in_stack_opt && useopt)
3255             where_in_stack = new R * [n_where_in_stack_opt];
3256         if (where_in_stack)
3257         {
3258             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
3259             for (int i=0;i<n_where_in_stack_opt;i++)
3260             {
3261                 int offset=b->b->where_in_stack_opt[i];
3262                 assert(offset>10);
3263                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
3264                 *(where_in_stack[i])=0;
3265             }
3266 
3267 
3268             if(poptiexp0)
3269                 (*poptiexp0)(stack);
3270             KN<bool> ok(b->b->v.size());
3271             {  //   remove the zero coef in the liste
3272                 // R zero=R();
3273                 int il=0;
3274                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
3275                     ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
3276             }
3277             BilinearOperator b_nozer(*b->b,ok);
3278             if (verbosity % 10 > 3 )
3279                 cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
3280                 << "  total " << n_where_in_stack_opt << endl;
3281 
3282             if ( (verbosity/100) % 10 >= 2)
3283             {
3284                 int il=0;
3285 
3286                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
3287                     cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
3288                     << " offset=" << b->b->where_in_stack_opt[il]
3289                     << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
3290             }
3291         }
3292         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
3293 
3294         KN<double>  p(Vh.esize()+ Uh.esize() );
3295 
3296 
3297         if (verbosity >3)
3298         {
3299             if (all) cout << " all " << endl ;
3300             else cout << endl;
3301         }
3302 
3303         if (di.kind == CDomainOfIntegration::int1d )
3304         {
3305 
3306             if(di.islevelset())
3307             {
3308                 double uset = HUGE_VAL;
3309                 R2 Q[2];
3310                 double vol6[2];
3311                 KN<double> phi(Th.nv);phi=uset;
3312                 double f[3], ll=0;
3313                 for(int t=0; t< Th.nt;++t)
3314                 {
3315                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
3316                     {
3317                         double umx=-HUGE_VAL,umn=HUGE_VAL;
3318                         for(int i=0;i<3;++i)
3319                         {
3320                             int j= Th(t,i);
3321                             if( phi[j]==uset)
3322                             {
3323                                 MeshPointStack(stack)->setP(&Th,t,i);
3324                                 phi[j]= di.levelset(stack);//zzzz
3325                             }
3326                             f[i]=phi[j];
3327                             umx = std::max(umx,phi[j]);
3328                             umn = std::min(umn,phi[j]);
3329 
3330                         }
3331                         int ntp= IsoLineK(f,Q,1e-10);
3332                         if(verbosity>999 && ntp==2)
3333                         {
3334                             const TriangleS &T = Th[t];
3335                             R3 E(T(Q[0]),T(Q[1]));
3336                             double le=sqrt((E,E));
3337                             ll += le;
3338                             cout << "\t\t" << ntp <<" :  " << Q[0] << " " << Q[1] << " ;  "
3339                             << f[0] << " " << f[1] << " " << f[2] << "  " << le << " / " << ll<<endl;
3340                         }
3341                         if( ntp==2)
3342                         { //if( withmap)
3343                            // AddMatElem(mapu,mapt,A,Th,*b->b,sym,t,10,Th[t].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
3344                         //else
3345                             AddMatElem(A,Th,*b->b,sym,t,10,Th[t].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
3346                             if(sptrclean) sptrclean=sptr->clean();
3347                         }
3348                     }
3349                 }
3350                 FIT =FITo;
3351             }
3352 
3353 
3354             else
3355             {
3356                 for( int e=0;e<Th.nbe;e++)
3357                 {
3358                     if (all || setoflab.find(Th.be(e).lab) != setoflab.end())
3359                     {
3360                         int ie,i =Th.BoundaryElement(e,ie);
3361                         //if( withmap)
3362                         //    AddMatElem(mapu,mapt,A,Th,*b->b,sym,i,ie,Th.be(e).lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
3363                         //else
3364                             AddMatElem(A,Th,*b->b,sym,i,ie,Th.be(e).lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
3365                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3366                     }
3367                 }
3368             }}
3369         /*else if (di.kind == CDomainOfIntegration::intalledges)
3370         {
3371             cerr << " Sorry no implement to hard  "<< endl;
3372             ExecError("FH: no intalledges on diff mesh ???");
3373             ffassert(0); // a faire
3374             if(withmap)
3375                 for (int i=0;i< Th.nt; i++)
3376                 {
3377                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3378                         for (int ie=0;ie<3;ie++)
3379                             AddMatElem(mapu,mapt,A,Th,*b->b,sym,i,ie,Th[i].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
3380                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3381 
3382 
3383                 }
3384 
3385             else
3386                 for (int i=0;i< Th.nt; i++)
3387                 {
3388                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3389                         for (int ie=0;ie<3;ie++)
3390                             AddMatElem(A,Th,*b->b,sym,i,ie,Th[i].lab,Uh,Vh,FIT,FIE,p,stack,intmortar);
3391                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3392 
3393 
3394                 }
3395 
3396         }*/
3397         else if (di.kind == CDomainOfIntegration::intallVFedges)
3398         {
3399 
3400             cerr << " a faire intallVFedges " << endl;
3401             ffassert(0);
3402 
3403         }
3404         else if (di.kind == CDomainOfIntegration::int2d ) {
3405             // cerr << " a faire CDomainOfIntegration::int2d  " << endl;
3406             if(di.islevelset())
3407             {
3408                 double uset = HUGE_VAL;
3409                 R2 Q[2][3];
3410                 double vol6[2];
3411                 KN<double> phi(Th.nv);phi=uset;
3412                 double f[3];
3413                 for(int t=0; t< Th.nt;++t)
3414                 {
3415                     if ( all || setoflab.find(Th[t].lab) != setoflab.end())
3416                     {
3417                         double umx=-HUGE_VAL,umn=HUGE_VAL;
3418                         for(int i=0;i<3;++i)
3419                         {
3420                             int j= Th(t,i);
3421                             if( phi[j]==uset)
3422                             {
3423                                 MeshPointStack(stack)->setP(&Th,t,i);
3424                                 phi[j]= di.levelset(stack);//zzzz
3425                             }
3426                             f[i]=phi[j];
3427                             umx = std::max(umx,phi[j]);
3428                             umn = std::min(umn,phi[j]);
3429 
3430                         }
3431                         int nt= UnderIso(f,Q, vol6,1e-14);
3432                         setQF<R2>(FIT,FITo,QuadratureFormular_T_1, Q,vol6,nt);
3433                         if(FIT.n)
3434                         {
3435                             //if(withmap)
3436                              //   AddMatElem(mapu,mapt,A,Th,*b->b,sym,t,-1,Th[t].lab,Uh,Vh,FIT,FIE,p,stack);
3437                             //else
3438                                 AddMatElem(A,Th,*b->b,sym,t,-1,Th[t].lab,Uh,Vh,FIT,FIE,p,stack);
3439                         }
3440                         if(sptrclean) sptrclean=sptr->clean();
3441                     }
3442                 }
3443                 FIT =FITo;
3444             }
3445             else
3446 
3447             {
3448                 //if(withmap)
3449                  //   for (int i=0;i< Th.nt; i++)
3450                   //  {
3451                    //     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3452                     //        AddMatElem(mapu,mapt,A,Th,*b->b,sym,i,-1,Th[i].lab,Uh,Vh,FIT,FIE,p,stack);
3453                     //    if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3454                    // }
3455 
3456                 //else
3457                     for (int i=0;i< Th.nt; i++)
3458                     {
3459                         if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3460                             AddMatElem(A,Th,*b->b,sym,i,-1,Th[i].lab,Uh,Vh,FIT,FIE,p,stack);
3461                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3462                     }
3463 
3464             }
3465 
3466         }
3467         else
3468             InternalError(" kind of CDomainOfIntegration unkown");
3469 
3470         if (where_in_stack) delete [] where_in_stack;
3471             }
3472 
3473 
3474 
3475     // creating an instance of AssembleBilinearForm with map
3476     // case 3D curve
3477     template<class R>
AssembleBilinearForm(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,MatriceMap<R> & A,const FormBilinear * b)3478     void AssembleBilinearForm(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
3479                               MatriceMap<R>  & A, const  FormBilinear * b  )
3480 
3481     {
3482         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
3483         bool sptrclean=true;
3484         //     sptr->clean(); // modif FH mars 2006  clean Ptr
3485 
3486         const CDomainOfIntegration & di= *b->di;
3487         pmeshL  pThdi = GetAny<pmeshL>((*b->di->Th)(stack));
3488 
3489         SHOWVERB(cout << " FormBilinear () " << endl);
3490 
3491         const int useopt=di.UseOpt(stack);
3492         //double binside=di.binside(stack);
3493         const bool intmortar=di.intmortar(stack);
3494         if ( verbosity >1)
3495         {
3496             cout << " Integral   on Th "<< &Th << " nv :  " << Th.nv << " nt : " << Th.nt << endl;
3497             cout << "        Th/ u "<< &Uh.Th << " nv : " << Uh.Th.nv << "   nt : " << Uh.Th.nt << endl;
3498             cout << "        Th/ v "<< &Vh.Th << " nv : " << Vh.Th.nv << "   nt : " << Vh.Th.nt << endl;
3499             cout << "        suppose in mortar " << intmortar << "   levelset=  " << di.islevelset() << " withmap: " << di.withmap() << endl;
3500         }
3501         Expression  const * const mapt=*di.mapt?di.mapt:0 ;
3502         Expression  const * const mapu=*di.mapu?di.mapu:0 ;
3503         bool withmap =di.withmap();
3504         assert(pThdi == & Th);
3505         CDomainOfIntegration::typeofkind  kind = di.kind;
3506         set<int> setoflab;
3507         bool all=true;
3508 
3509         const GQuadratureFormular<R1> & FITo = di.FIE(stack);
3510         GQuadratureFormular<R1> FIT(FITo,3);
3511 
3512         bool VF=b->VF();  // finite Volume or discontinous Galerkin
3513         if (verbosity>2) cout << "  -- discontinous Galerkin  =" << VF << " size of Mat =" << A.size()<< " Bytes\n";
3514 
3515         // if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (1)");
3516         if(di.islevelset() && (CDomainOfIntegration::int1d!=kind))
3517             InternalError("Sorry no levelset integration type on no int1d case");
3518 
3519         Expandsetoflab(stack,di, setoflab,all);
3520 
3521         if (verbosity>3) cout <<" Optimized = "<< useopt << ", ";
3522         const E_F0 * poptiexp0=b->b->optiexp0;
3523         // const E_F0 & optiexpK=*b->b->optiexpK;
3524         int n_where_in_stack_opt=b->b->where_in_stack_opt.size();
3525         R** where_in_stack =0;
3526         if (n_where_in_stack_opt && useopt)
3527             where_in_stack = new R * [n_where_in_stack_opt];
3528         if (where_in_stack) {
3529             assert(b->b->v.size()==(size_t) n_where_in_stack_opt);
3530             for (int i=0;i<n_where_in_stack_opt;i++) {
3531                 int offset=b->b->where_in_stack_opt[i];
3532                 assert(offset>10);
3533                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
3534                 *(where_in_stack[i])=0;
3535             }
3536 
3537 
3538             if(poptiexp0)
3539                 (*poptiexp0)(stack);
3540             KN<bool> ok(b->b->v.size());
3541             {  //   remove the zero coef in the liste
3542                 // R zero=R();
3543                 int il=0;
3544                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
3545                     ok[il] =  ! (b->b->mesh_indep_stack_opt[il] && ( std::norm(*(where_in_stack[il])) < 1e-100 ) );
3546             }
3547             BilinearOperator b_nozer(*b->b,ok);
3548             if (verbosity % 10 > 3 )
3549                 cout << "   -- nb term in bilinear form  (!0) : " << b_nozer.v.size()
3550                 << "  total " << n_where_in_stack_opt << endl;
3551 
3552             if ( (verbosity/100) % 10 >= 2) {
3553                 int il=0;
3554 
3555                 for (BilinearOperator::const_iterator l=b->b->v.begin();l!=b->b->v.end();l++,il++)
3556                     cout << il << " coef (" << l->first << ") = " << *(where_in_stack[il])
3557                     << " offset=" << b->b->where_in_stack_opt[il]
3558                     << " dep mesh " << l->second.MeshIndependent() << b->b->mesh_indep_stack_opt[il] << endl;
3559             }
3560         }
3561         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
3562 
3563         KN<double>  p(Vh.esize()+ Uh.esize() );
3564 
3565 
3566         if (verbosity >3) {
3567             if (all) cout << " all " << endl ;
3568             else cout << endl;
3569         }
3570 
3571         if (di.kind == CDomainOfIntegration::int1d ) {
3572             if(di.islevelset())   ////// must be check
3573                 ffassert(0);
3574             else {
3575                  for (int i=0;i< Th.nt; i++) {
3576                     if ( all || setoflab.find(Th[i].lab) != setoflab.end())
3577                         AddMatElem(A,Th,*b->b,sym,i,-1,Th[i].lab,Uh,Vh,FIT,0,p,stack);
3578                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
3579                 }
3580               }
3581         }
3582         else
3583             InternalError(" kind of CDomainOfIntegration unkown");
3584 
3585         if (where_in_stack) delete [] where_in_stack;
3586     }
3587 
3588 
3589 
3590 
3591     // --------- FH 170605
3592     ////////////////////////////////////////////////
3593     // Element_Op for MatriceElementairePleine
3594     ////////////////////////////////////////////////
3595 
3596 
3597     // xxxxxxxxxxxxxxxxx  modif a faire
3598     // creating an instance of Element_Op with MatriceElementairePleine
3599     // case 2d
3600     template<class R>
Element_Op(MatriceElementairePleine<R,FESpace> & mat,const FElement & Ku,const FElement & Kv,double * p,int ie,int label,void * vstack,R2 * B)3601     void  Element_Op(MatriceElementairePleine<R,FESpace> & mat,const FElement & Ku,const FElement & Kv,double * p,int ie,int label,void *vstack,R2 *B)
3602     {
3603         Stack stack=pvoid2Stack(vstack);
3604         typedef  FElement::Element Element;
3605         MeshPoint mp= *MeshPointStack(stack);
3606         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
3607 
3608         bool same = &Ku == & Kv;
3609         const Element & T  = Ku.T;
3610         throwassert(&T == &Kv.T);
3611         const QuadratureFormular & FI = mat.FIT;
3612         const QuadratureFormular1d & FIb = mat.FIE;
3613         long npi;
3614         R *a=mat.a;
3615         R *pa=a;
3616         long i,j;
3617         long n= mat.n,m=mat.m,nx=n*m;
3618         long N= Kv.N;
3619         long M= Ku.N;
3620 
3621 
3622 
3623 
3624 
3625         const Opera &Op(*mat.bilinearform);
3626         bool classoptm = copt && Op.optiexpK;
3627         bool oldopt=1;  // juin 2007 FH ???? a voir
3628         int  iloop=0;
3629         KN<bool> unvarexp(classoptm ? Op.optiexpK->sizevar() : 1);
3630         if (Ku.number<1 && verbosity/100 && verbosity % 10 == 2)
3631         cout << "Element_Op P: copt = " << copt << " " << classoptm << " opt: " << mat.optim << endl;
3632         assert(Op.MaxOp() <last_operatortype);
3633 
3634 
3635         KN<bool> Dop(last_operatortype);
3636         Op.DiffOp(Dop);
3637         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
3638         //assert(lastop<=3);
3639         RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
3640         RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
3641 
3642         for (i=0;i< nx;i++)
3643         *pa++ = 0.;
3644         if (ie<0 )//&& B==0)
3645         for (npi=0;npi<FI.n;npi++) // loop on the integration point
3646         {
3647             QuadraturePoint pi(FI[npi]);
3648             R mes = B ? B->x : T.area;
3649             R coef = mes *pi.a;
3650             R2 Pt(pi);
3651             pa =a;
3652             Ku.BF(Dop,Pt,fu);
3653             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
3654             if (classoptm) {
3655                 if( oldopt) (*Op.optiexpK)(stack); // call old optim version
3656                 else Op.optiexpK->eval(stack,iloop++,unvarexp); // new optim version
3657             }
3658             if (!same) Kv.BF(Dop,Pt,fv);
3659             int il=0;
3660             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
3661             {  // attention la fonction test donne la ligne
3662                 //  et la fonction test est en second
3663                 BilinearOperator::K ll(*l);
3664                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
3665                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
3666                 long icomp= ll.first.second.first,iop=ll.first.second.second;
3667 
3668                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
3669                 if ( copt && ( mat.optim==1) && Kv.number <1)
3670                 {
3671                     R cc  =  GetAny<R>(ll.second.eval(stack));
3672                     //cout << *(copt[il]) << " == " <<  cc << endl;
3673                     CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization (e) add:  int2d(Th,optimize=0)(...)");
3674                    /* if ( ccc != cc) {
3675                         cerr << cc << " != " << ccc << " => ";
3676                         cerr << "Sorry error in Optimization (e) add:  int2d(Th,optimize=0)(...)" << endl;
3677                         ExecError("In Optimized version "); }*/
3678                 }
3679                 int fi=Kv.dfcbegin(icomp);
3680                 int li=Kv.dfcend(icomp);
3681                 int fj=Ku.dfcbegin(jcomp);
3682                 int lj=Ku.dfcend(jcomp);
3683                 ccc *= coef;
3684 
3685                 // attention la fonction test donne la ligne
3686                 //  et la fonction test est en second
3687                 for ( i=fi;  i<li;   i++ )
3688                 {
3689                     for ( j=fj;  j<lj;   j++ )
3690                     {
3691                         R w_i =  fv(i,icomp,iop);
3692                         R w_j =  fu(j,jcomp,jop);
3693                         mat(i,j) += ccc * w_i*w_j;
3694                     }
3695                 }
3696             }
3697         }
3698         else if(B)
3699         {  // int on isovalue ...
3700             R2 PA(B[0]),PB(B[1]);
3701             R2 A=T(PA),B=T(PB);
3702             R2 E(A,B);
3703             double le = sqrt((E,E));
3704             //  cout << " xxxx "<< le << " "<< A << " " << B << endl;
3705             if(le > 1e-15) // bofbof ????
3706             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
3707             {
3708                 pa =a;
3709                 QuadratureFormular1dPoint pi( FIb[npi]);
3710                 double coef = le*pi.a;
3711                 double sa=pi.x,sb=1-sa;
3712                 R2 Pt(PA*sa+PB*sb ); //
3713                 Ku.BF(Dop,Pt,fu);
3714                 if (!same) Kv.BF(Dop,Pt,fv);
3715                 // int label=-999999; // a passer en argument
3716                 MeshPointStack(stack)->set(T(Pt),Pt,Kv,-1,R2(E.y,-E.x)/le,-1);
3717                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
3718                 int il=0;
3719                 for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
3720                 {  // attention la fonction test donne la ligne
3721                     //  et la fonction test est en second
3722                     BilinearOperator::K ll(*l);
3723                     //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
3724                     long jcomp= ll.first.first.first,jop=ll.first.first.second;
3725                     long icomp= ll.first.second.first,iop=ll.first.second.second;
3726 
3727 
3728                     R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
3729                     if ( copt && ( mat.optim==1) && Kv.number <1)
3730                     {
3731                         R cc  =  GetAny<R>(ll.second.eval(stack));
3732                         //cout << *(copt[il]) << " == " <<  cc << endl;
3733                         CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization (f) add:  int2d(Th,optimize=0)(...)");
3734                        /* if ( ccc != cc) {
3735                             cerr << cc << " != " << ccc << " => ";
3736                             cerr << "Sorry error in Optimization (f) add:  int2d(Th,optimize=0)(...)" << endl;
3737                             ExecError("In Optimized version "); }*/
3738                     }
3739                     int fi=Kv.dfcbegin(icomp);
3740                     int li=Kv.dfcend(icomp);
3741                     int fj=Ku.dfcbegin(jcomp);
3742                     int lj=Ku.dfcend(jcomp);
3743                     ccc *= coef;
3744 
3745                     // attention la fonction test donne la ligne
3746                     //  et la fonction test est en second
3747 
3748                     for ( i=fi;  i<li;   i++ )
3749                     {
3750                         for ( j=fj;  j<lj;   j++ )
3751                         {
3752                             R w_i =  fv(i,icomp,iop);
3753                             R w_j =  fu(j,jcomp,jop);
3754                             mat(i,j) += ccc * w_i*w_j;
3755                         }
3756                     }
3757                 }
3758             }
3759         }
3760         else // int on edge ie
3761         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
3762         {
3763             pa =a;
3764             QuadratureFormular1dPoint pi( FIb[npi]);
3765             R2 E=T.Edge(ie);
3766             double le = sqrt((E,E));
3767             double coef = le*pi.a;
3768             double sa=pi.x,sb=1-sa;
3769             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
3770             PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
3771             R2 Pt(PA*sa+PB*sb ); //
3772             Ku.BF(Dop,Pt,fu);
3773             if (!same) Kv.BF(Dop,Pt,fv);
3774             // int label=-999999; // a passer en argument
3775             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label,R2(E.y,-E.x)/le,ie);
3776             if (classoptm) (*Op.optiexpK)(stack); // call optim version
3777             int il=0;
3778             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
3779             {  // attention la fonction test donne la ligne
3780                 //  et la fonction test est en second
3781                 BilinearOperator::K ll(*l);
3782                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
3783                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
3784                 long icomp= ll.first.second.first,iop=ll.first.second.second;
3785 
3786 
3787                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
3788                 if ( copt && ( mat.optim==1) && Kv.number <1)
3789                 {
3790                     R cc  =  GetAny<R>(ll.second.eval(stack));
3791                     //cout << *(copt[il]) << " == " <<  cc << endl;
3792                     CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization (g) add:  int2d(Th,optimize=0)(...)");
3793                    /* if ( ccc != cc) {
3794                         cerr << cc << " != " << ccc << " => ";
3795                         cerr << "Sorry error in Optimization (g) add:  int2d(Th,optimize=0)(...)" << endl;
3796                         ExecError("In Optimized version "); }*/
3797                 }
3798                 int fi=Kv.dfcbegin(icomp);
3799                 int li=Kv.dfcend(icomp);
3800                 int fj=Ku.dfcbegin(jcomp);
3801                 int lj=Ku.dfcend(jcomp);
3802                 ccc *= coef;
3803 
3804                 // attention la fonction test donne la ligne
3805                 //  et la fonction test est en second
3806 
3807                 for ( i=fi;  i<li;   i++ )
3808                 {
3809                     for ( j=fj;  j<lj;   j++ )
3810                     {
3811                         R w_i =  fv(i,icomp,iop);
3812                         R w_j =  fu(j,jcomp,jop);
3813                         mat(i,j) += ccc * w_i*w_j;
3814                     }
3815                 }
3816             }
3817 
3818             /*
3819              for ( i=0;  i<n;   i++ )
3820              // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
3821              {
3822              RNM_ wi(fv(i,'.','.'));
3823              for ( j=0;  j<m;   j++,pa++ )
3824              {
3825              RNM_ wj(fu(j,'.','.'));
3826              int il=0;
3827              for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
3828              // if (onWhatIsEdge[ie][Kv.DFOnWhat(j)]) // juste the df on edge bofbof generaly wrong FH dec 2003
3829              {
3830              BilinearOperator::K ll(*l);
3831              pair<int,int> jj(ll.first.first),ii(ll.first.second);
3832 
3833              double w_i =  wi(ii.first,ii.second);
3834              double w_j =  wj(jj.first,jj.second);
3835              // R ccc = GetAny<R>(ll.second.eval(stack));
3836 
3837              R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
3838              if ( copt && ( mat.optim==1) && Kv.number <1)
3839              {
3840              R cc  =  GetAny<R>(ll.second.eval(stack));
3841              if ( ccc != cc) {
3842              cerr << cc << " != " << ccc << " => ";
3843              cerr << "Sorry error in Optimization (h) add:  int2d(Th,optimize=0)(...)" << endl;
3844              ExecError("In Optimized version "); }
3845              }
3846              *pa += coef * ccc * w_i*w_j;
3847              }
3848              }
3849              }
3850              // else pa += m;  FH dec 2003
3851              */
3852         }
3853 
3854 
3855         /*  pa=a;
3856          if (Ku.Vh.Th(T) >=0 ) {
3857          cout <<endl  << " Triangle " << Ku.Vh.Th(T) << " =  "<<  T[0] << ", " << T[1] << ", " << T[2] << " " << nx << endl;
3858          for (int i=0;i<n;i++)
3859          {
3860          cout << setw(2) << i << setw(4) << mat.ni[i] << " :";
3861          for (int j=0;j<m;j++)
3862          cout << setw(5)  << (*pa++) << " ";
3863          cout << endl;
3864          } }
3865          */
3866         *MeshPointStack(stack) = mp;
3867     }
3868 
3869 
3870 
3871     // creating an instance of Element_Op with MatriceElementairePleine
3872     // case 3D volume
3873     template<class R>
Element_Op(MatriceElementairePleine<R,FESpace3> & mat,const FElement3 & Ku,const FElement3 & Kv,double * p,int ie,int label,void * vstack,R3 * B)3874     void  Element_Op(MatriceElementairePleine<R,FESpace3> & mat,const FElement3 & Ku,const FElement3 & Kv,double * p,int ie,int label,void *vstack,R3 *B)
3875     {
3876         //  ffassert(B==0);
3877         Stack stack=pvoid2Stack(vstack);
3878         //    ffassert(0);
3879         typedef  FElement3::Element Element;
3880         MeshPoint mp= *MeshPointStack(stack);
3881         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
3882 
3883         bool same = &Ku == & Kv;
3884         const Element & T  = Ku.T;
3885         throwassert(&T == &Kv.T);
3886         const GQuadratureFormular<R3> & FI = mat.FIT;
3887         const GQuadratureFormular<R2> & FIb = mat.FIE;
3888         long npi;
3889         R *a=mat.a;
3890         R *pa=a;
3891         long i,j;
3892         long n= mat.n,m=mat.m,nx=n*m;
3893         long N= Kv.N;
3894         long M= Ku.N;
3895 
3896 
3897 
3898 
3899 
3900         const Opera &Op(*mat.bilinearform);
3901         bool classoptm = copt && Op.optiexpK;
3902         bool oldopt=1;  // juin 2007 FH ???? a voir
3903         int  iloop=0;
3904         KN<bool> unvarexp(classoptm ? Op.optiexpK->sizevar() : 1);
3905         if (Ku.number<1 && verbosity/100 && verbosity % 10 == 2)
3906         cout << "Element_Op 3d P: copt = " << copt << " " << classoptm << " opt: " << mat.optim << endl;
3907         assert(Op.MaxOp() <last_operatortype);
3908         //
3909         int lastop;
3910         lastop = 0;
3911         What_d Dop = Op.DiffOp(lastop);
3912         //KN<bool> Dop(last_operatortype);
3913         //p.DiffOp(Dop);
3914         //int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
3915         //assert(lastop<=3);
3916         RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
3917         RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
3918 
3919         for (i=0;i< nx;i++)
3920         *pa++ = 0.;
3921         if (ie<0)
3922         for (npi=0;npi<FI.n;npi++) // loop on the integration point
3923         {
3924             GQuadraturePoint<R3> pi(FI[npi]);
3925             R coef = T.mesure()*pi.a;
3926             R3 Pt(pi);
3927             pa =a;
3928             Ku.BF(Dop,Pt,fu);
3929             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
3930             if (classoptm) {
3931                 if( oldopt) (*Op.optiexpK)(stack); // call old optim version
3932                 else Op.optiexpK->eval(stack,iloop++,unvarexp); // new optim version
3933             }
3934             if (!same) Kv.BF(Dop,Pt,fv);
3935             int il=0;
3936             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
3937             {  // attention la fonction test donne la ligne
3938                 //  et la fonction test est en second
3939                 BilinearOperator::K ll(*l);
3940                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
3941                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
3942                 long icomp= ll.first.second.first,iop=ll.first.second.second;
3943 
3944                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
3945                 if ( copt && ( mat.optim==1) && Kv.number <1)
3946                 {
3947                     R cc  =  GetAny<R>(ll.second.eval(stack));
3948                     //cout << *(copt[il]) << " == " <<  cc << endl;
3949                     CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization Element_Op plein 3d (a) add:  int2d(Th,optimize=0)(...)");
3950                      /*   if ( ccc != cc) {
3951                             cerr << cc << " != " << ccc << " => ";
3952                             cerr << "Sorry error in Optimization Element_Op plein 3d (a) add:  int2d(Th,optimize=0)(...)" << endl;
3953                             ExecError("In Optimized version "); }*/
3954                     }
3955                 int fi=Kv.dfcbegin(icomp);
3956                 int li=Kv.dfcend(icomp);
3957                 int fj=Ku.dfcbegin(jcomp);
3958                 int lj=Ku.dfcend(jcomp);
3959                 ccc *= coef;
3960 
3961                 // attention la fonction test donne la ligne
3962                 //  et la fonction test est en second
3963 
3964                 for ( i=fi;  i<li;   i++ )
3965                 {
3966                     for ( j=fj;  j<lj;   j++ )
3967                     {
3968                         R w_i =  fv(i,icomp,iop);
3969                         R w_j =  fu(j,jcomp,jop);
3970                         mat(i,j) += ccc * w_i*w_j;
3971                     }
3972                 }
3973             }
3974         }
3975         else if(B)
3976         {  // int on leveset
3977             int np = ie-10; //= (B[0].x == B[3].x ) && (B[0].y == B[3].y ) && (B[0].z == B[3].z ) ? 3 : 4;
3978             if(verbosity>999) cout << "    Ass mat pleine /"<< np << endl;
3979             assert( np==3 || np==4);
3980             // XXXXXXX
3981             double epsmes3=T.mesure()*T.mesure()*1e-18;
3982             R3 PP[4];
3983             double l[3];
3984             for(int i=0; i< np; ++i)
3985             PP[i]= T(B[i]);
3986 
3987             for( int i =0; i+1 < np; i+=2)
3988             { // 0,1,, a and 2,3,0.
3989                 int i0=i,i1=i+1,i2=(i+2)%np;
3990                 R3 NN= R3(PP[i0],PP[i1])^R3(PP[i0],PP[i2]);
3991                 double mes2 = (NN,NN);
3992                 double mes = sqrt(mes2);
3993 
3994                 if(mes2*mes <epsmes3) continue; //  too small
3995                 NN /= mes;
3996                 mes *= 0.5;
3997                 if(verbosity>999)
3998                 cout << " --int on leveset3d " << np << " " << mes << " " << i0<<i1<<i2 <<endl;
3999                 double asum=0;
4000                 for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4001                 {
4002                     GQuadraturePoint<R2>  pi( FIb[npi]);
4003                     // cout << " %% " << npi << " " << pi.a << " " << pi.x << " " << pi.y << endl;
4004                     asum+= pi.a;
4005                     pi.toBary(l);
4006                     R3 Pt( l[0]*B[i0]+l[1]*B[i1]+l[2]*B[i2]); //
4007                     double coef = mes*pi.a; // correction 0.5 050109 FH
4008                     Ku.BF(Dop,Pt,fu);
4009                     if (!same) Kv.BF(Dop,Pt,fv);
4010                     MeshPointStack(stack)->set(T(Pt),Pt,Ku,label,NN,ie);
4011                     if (classoptm) (*Op.optiexpK)(stack); // call optim version
4012 
4013                     pa=a;
4014                     for (int i=0;  i<n;   i++ )
4015                     {
4016                         RNM_ wi(fv(i,'.','.'));
4017                         for (int  j=0;  j<m;   j++,pa++ )
4018                         {
4019                             RNM_ wj(fu(j,'.','.'));
4020                             int il=0;
4021                             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4022                             {
4023                                 BilinearOperator::K ll(*l);
4024                                 pair<int,int> jj(ll.first.first),ii(ll.first.second);
4025 
4026                                 double w_i =  wi(ii.first,ii.second);
4027                                 double w_j =  wj(jj.first,jj.second);
4028 
4029                                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
4030                                 if ( copt && ( mat.optim==1) && Kv.number <1)
4031                                 {
4032                                     R cc  =  GetAny<R>(ll.second.eval(stack));
4033                                     CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization  Element_Op plein 3d (b) add:  int2d(Th,optimize=0)(...)");
4034                                    /* if ( ccc != cc) {
4035                                         cerr << cc << " != " << ccc << " => ";
4036                                         cerr << "Sorry error in Optimization  Element_Op plein 3d (b) add:  int2d(Th,optimize=0)(...)" << endl;
4037                                         ExecError("In Optimized version "); }*/
4038                                 }
4039                                 if(verbosity>999)
4040                                 cout << " -- int on leveset3d  aij = "<< pi.a* ccc * w_i*w_j <<" " << ccc << " " << w_i*w_j <<endl;
4041                                 *pa += coef * ccc * w_i*w_j;
4042                             }
4043                         }
4044                     }
4045                     if(verbosity>999) cout << " ++\n";
4046                 }
4047 
4048                 if(verbosity>999) cout << " @@ "<< asum << endl;;
4049 
4050             }
4051 
4052         }// end int level set ...
4053         else // int on edge ie
4054         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4055         {
4056             pa =a;
4057             GQuadraturePoint<R2> pi( FIb[npi]);
4058             R3 NN= T.N(ie);
4059             double mes=NN.norme();
4060             NN/=mes;
4061             double coef = 0.5*mes*pi.a; // correction 0.5 050109 FH
4062             R3 Pt(T.PBord(ie,pi));
4063             Ku.BF(Dop,Pt,fu);
4064             if (!same) Kv.BF(Dop,Pt,fv);
4065             MeshPointStack(stack)->set(T(Pt),Pt,Ku,label,NN,ie);
4066             if (classoptm) (*Op.optiexpK)(stack); // call optim version
4067 
4068 
4069             for ( i=0;  i<n;   i++ )
4070             {
4071                 RNM_ wi(fv(i,'.','.'));
4072                 for ( j=0;  j<m;   j++,pa++ )
4073                 {
4074                     RNM_ wj(fu(j,'.','.'));
4075                     int il=0;
4076                     for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4077                     {
4078                         BilinearOperator::K ll(*l);
4079                         pair<int,int> jj(ll.first.first),ii(ll.first.second);
4080 
4081                         double w_i =  wi(ii.first,ii.second);
4082                         double w_j =  wj(jj.first,jj.second);
4083 
4084                         R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
4085                         if ( copt && ( mat.optim==1) && Kv.number <1)
4086                         {
4087                             R cc  =  GetAny<R>(ll.second.eval(stack));
4088                             CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization Element_Op plein 3d (c) add:  int2d(Th,optimize=0)(...)");
4089                             /*
4090                             if ( ccc != cc) {
4091                                 cerr << cc << " != " << ccc << " => ";
4092                                 cerr << "Sorry error in Optimization  Element_Op plein 3d (c) add:  int2d(Th,optimize=0)(...)" << endl;
4093                                 ExecError("In Optimized version "); }*/
4094                         }
4095                         *pa += coef * ccc * w_i*w_j;
4096                     }
4097                 }
4098             }
4099         }
4100 
4101 
4102         if (Ku.Vh.Th(T) <1 && verbosity>100) {
4103             pa=mat.a;
4104             cout <<endl  << " Tet " << Ku.Vh.Th(T) << " =  " << T  << " " << nx << endl;
4105             for (int i=0;i<n;i++)
4106             {
4107                 cout << setw(2) << i << setw(4) << mat.ni[i] << " :";
4108                 for (int j=0;j<m;j++)
4109                 cout << setw(5)  << (*pa++) << " ";
4110                 cout << endl;
4111             } }
4112 
4113 
4114     }
4115 
4116 
4117     // creating an instance of Element_Op with MatriceElementairePleine
4118     // case 3D surface
4119     template<class R>
Element_Op(MatriceElementairePleine<R,FESpaceS> & mat,const FElementS & Ku,const FElementS & Kv,double * p,int ie,int label,void * vstack,R3 * B)4120     void  Element_Op(MatriceElementairePleine<R,FESpaceS> & mat,const FElementS & Ku,const FElementS & Kv,double * p,int ie,int label,void *vstack,R3 *B)
4121     {
4122         Stack stack=pvoid2Stack(vstack);
4123         typedef  FElementS::Element Element;
4124 
4125         MeshPoint mp= *MeshPointStack(stack);
4126         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
4127 
4128         bool same = &Ku == & Kv;
4129         const Element & T  = Ku.T;
4130         throwassert(&T == &Kv.T);
4131         const QuadratureFormular & FI = mat.FIT;
4132         const QuadratureFormular1d & FIb = mat.FIE;
4133         long npi;
4134         R *a=mat.a;
4135         R *pa=a;
4136         long i,j;
4137         long n= mat.n,m=mat.m,nx=n*m;
4138         long N= Kv.N;
4139         long M= Ku.N;
4140 
4141 
4142         const Opera &Op(*mat.bilinearform);
4143         bool classoptm = copt && Op.optiexpK;
4144         bool oldopt=1;  // juin 2007 FH ???? a voir
4145         int  iloop=0;
4146         KN<bool> unvarexp(classoptm ? Op.optiexpK->sizevar() : 1);
4147         if (Ku.number<1 && verbosity/100 && verbosity % 10 == 2)
4148         cout << "Element_Op 3d P: copt = " << copt << " " << classoptm << " opt: " << mat.optim << endl;
4149         assert(Op.MaxOp() <last_operatortype);
4150 
4151         int lastop;
4152         lastop = 0;
4153         What_d Dop = Op.DiffOp(lastop);
4154 
4155         //assert(lastop<=3);
4156         RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
4157         RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
4158 
4159         for (i=0;i< nx;i++)
4160         *pa++ = 0.;
4161         if (ie<0 )//&& B==0)
4162         for (npi=0;npi<FI.n;npi++) // loop on the integration point
4163         {
4164             QuadraturePoint pi(FI[npi]);
4165             R mes = B ? B->x : T.mesure();
4166             R coef = mes *pi.a;
4167             R2 Pt(pi);
4168             pa =a;
4169             Ku.BF(Dop,Pt,fu);
4170             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
4171             if (classoptm) {
4172                 if( oldopt) (*Op.optiexpK)(stack); // call old optim version
4173                 else Op.optiexpK->eval(stack,iloop++,unvarexp); // new optim version
4174             }
4175             if (!same) Kv.BF(Dop,Pt,fv);
4176             int il=0;
4177             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4178             {  // attention la fonction test donne la ligne
4179                 //  et la fonction test est en second
4180                 BilinearOperator::K ll(*l);
4181                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4182                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
4183                 long icomp= ll.first.second.first,iop=ll.first.second.second;
4184 
4185                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
4186                 if ( copt && ( mat.optim==1) && Kv.number <1)
4187                 {
4188                     R cc  =  GetAny<R>(ll.second.eval(stack));
4189                     //cout << *(copt[il]) << " == " <<  cc << endl;
4190                     CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization (e) add:  int2d(Th,optimize=0)(...)");
4191                     /*if ( ccc != cc) {
4192                         cerr << cc << " != " << ccc << " => ";
4193                         cerr << "Sorry error in Optimization (e) add:  int2d(Th,optimize=0)(...)" << endl;
4194                         ExecError("In Optimized version "); }*/
4195                 }
4196                 int fi=Kv.dfcbegin(icomp);
4197                 int li=Kv.dfcend(icomp);
4198                 int fj=Ku.dfcbegin(jcomp);
4199                 int lj=Ku.dfcend(jcomp);
4200                 ccc *= coef;
4201 
4202                 // attention la fonction test donne la ligne
4203                 //  et la fonction test est en second
4204                 for ( i=fi;  i<li;   i++ )
4205                 {
4206                     for ( j=fj;  j<lj;   j++ )
4207                     {
4208                         R w_i =  fv(i,icomp,iop);
4209                         R w_j =  fu(j,jcomp,jop);
4210                         mat(i,j) += ccc * w_i*w_j;
4211                     }
4212                 }
4213             }
4214         }
4215         else if(B)
4216          ffassert(0);
4217         else // int on edge ie
4218         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4219         {
4220             pa =a;
4221             QuadratureFormular1dPoint pi( FIb[npi]);
4222             R3 E=T.Edge(ie);
4223             double le = sqrt((E,E));
4224             double coef = le*pi.a;
4225             double sa=pi.x,sb=1-sa;
4226             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
4227             PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
4228             R2 Pt(PA*sa+PB*sb ); //
4229             Ku.BF(Dop,Pt,fu);
4230             // surface normal
4231             R3 NNt=T.NFrenetUnitaire();
4232             // exterior normal (flux)
4233             R3 NN=T.N(ie);
4234             NN /= NN.norme();
4235             if (!same) Kv.BF(Dop,Pt,fv);
4236             // int label=-999999; // a passer en argument
4237             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label,NN,NNt,ie);
4238             if (classoptm) (*Op.optiexpK)(stack); // call optim version
4239             int il=0;
4240             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4241             {  // attention la fonction test donne la ligne
4242                 //  et la fonction test est en second
4243                 BilinearOperator::K ll(*l);
4244                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4245                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
4246                 long icomp= ll.first.second.first,iop=ll.first.second.second;
4247 
4248 
4249                 R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
4250                 if ( copt && ( mat.optim==1) && Kv.number <1)
4251                 {
4252                     R cc  =  GetAny<R>(ll.second.eval(stack));
4253                     //cout << *(copt[il]) << " == " <<  cc << endl;
4254                     CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization (g) add:  int2d(Th,optimize=0)(...)");
4255                     /*
4256                     if ( ccc != cc) {
4257                         cerr << cc << " != " << ccc << " => ";
4258                         cerr << "Sorry error in Optimization (g) add:  int2d(Th,optimize=0)(...)" << endl;
4259                         ExecError("In Optimized version "); }*/
4260                 }
4261                 int fi=Kv.dfcbegin(icomp);
4262                 int li=Kv.dfcend(icomp);
4263                 int fj=Ku.dfcbegin(jcomp);
4264                 int lj=Ku.dfcend(jcomp);
4265                 ccc *= coef;
4266 
4267                 // attention la fonction test donne la ligne
4268                 //  et la fonction test est en second
4269 
4270                 for ( i=fi;  i<li;   i++ )
4271                 {
4272                     for ( j=fj;  j<lj;   j++ )
4273                     {
4274                         R w_i =  fv(i,icomp,iop);
4275                         R w_j =  fu(j,jcomp,jop);
4276                         mat(i,j) += ccc * w_i*w_j;
4277                     }
4278                 }
4279             }
4280 
4281             /*
4282              for ( i=0;  i<n;   i++ )
4283              // if (onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // juste the df on edge bofbof generaly wrong FH dec 2003
4284              {
4285              RNM_ wi(fv(i,'.','.'));
4286              for ( j=0;  j<m;   j++,pa++ )
4287              {
4288              RNM_ wj(fu(j,'.','.'));
4289              int il=0;
4290              for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4291              // if (onWhatIsEdge[ie][Kv.DFOnWhat(j)]) // juste the df on edge bofbof generaly wrong FH dec 2003
4292              {
4293              BilinearOperator::K ll(*l);
4294              pair<int,int> jj(ll.first.first),ii(ll.first.second);
4295 
4296              double w_i =  wi(ii.first,ii.second);
4297              double w_j =  wj(jj.first,jj.second);
4298              // R ccc = GetAny<R>(ll.second.eval(stack));
4299 
4300              R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
4301              if ( copt && ( mat.optim==1) && Kv.number <1)
4302              {
4303              R cc  =  GetAny<R>(ll.second.eval(stack));
4304              if ( ccc != cc) {
4305              cerr << cc << " != " << ccc << " => ";
4306              cerr << "Sorry error in Optimization (h) add:  int2d(Th,optimize=0)(...)" << endl;
4307              ExecError("In Optimized version "); }
4308              }
4309              *pa += coef * ccc * w_i*w_j;
4310              }
4311              }
4312              }
4313              // else pa += m;  FH dec 2003
4314              */
4315         }
4316 
4317 
4318         /*  pa=a;
4319          if (Ku.Vh.Th(T) >=0 ) {
4320          cout <<endl  << " Triangle " << Ku.Vh.Th(T) << " =  "<<  T[0] << ", " << T[1] << ", " << T[2] << " " << nx << endl;
4321          for (int i=0;i<n;i++)
4322          {
4323          cout << setw(2) << i << setw(4) << mat.ni[i] << " :";
4324          for (int j=0;j<m;j++)
4325          cout << setw(5)  << (*pa++) << " ";
4326          cout << endl;
4327          } }
4328          */
4329         *MeshPointStack(stack) = mp;
4330     }
4331 
4332     // creating an instance of Element_Op with MatriceElementairePleine
4333     // case 3D curve
4334     template<class R>
Element_Op(MatriceElementairePleine<R,FESpaceL> & mat,const FElementL & Ku,const FElementL & Kv,double * p,int ie,int label,void * vstack,R3 * B)4335     void  Element_Op(MatriceElementairePleine<R,FESpaceL> & mat,const FElementL & Ku,const FElementL & Kv,double * p,int ie,int label,void *vstack,R3 *B)
4336     {
4337         Stack stack=pvoid2Stack(vstack);
4338         typedef  FElementL::Element Element;
4339 
4340         MeshPoint mp= *MeshPointStack(stack);
4341         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
4342 
4343         bool same = &Ku == & Kv;
4344         const Element & T  = Ku.T;
4345         throwassert(&T == &Kv.T);
4346         //const QuadratureFormular & FI = mat.FIT;
4347         const GQuadratureFormular<R1> & FI = mat.FIT;
4348         long npi;
4349         R *a=mat.a;
4350         R *pa=a;
4351         long i,j;
4352         long n= mat.n,m=mat.m,nx=n*m;
4353         long N= Kv.N;
4354         long M= Ku.N;
4355 
4356 
4357         const Opera &Op(*mat.bilinearform);
4358         bool classoptm = copt && Op.optiexpK;
4359         bool oldopt=1;  // juin 2007 FH ???? a voir
4360         int  iloop=0;
4361         KN<bool> unvarexp(classoptm ? Op.optiexpK->sizevar() : 1);
4362         if (Ku.number<1 && verbosity/100 && verbosity % 10 == 2)
4363             cout << "Element_Op 3d P: copt = " << copt << " " << classoptm << " opt: " << mat.optim << endl;
4364         assert(Op.MaxOp() <last_operatortype);
4365 
4366         int lastop;
4367         lastop = 0;
4368         What_d Dop = Op.DiffOp(lastop);
4369 
4370         //assert(lastop<=3);
4371         RNMK_ fv(p,n,N,lastop); //  the value for basic fonction
4372         RNMK_ fu(p+ (same ?0:n*N*lastop) ,m,M,lastop); //  the value for basic fonction
4373 
4374         for (i=0;i< nx;i++)
4375             *pa++ = 0.;
4376         if (ie<0 )//&& B==0)
4377             for (npi=0;npi<FI.n;npi++) // loop on the integration point
4378             {
4379                 GQuadraturePoint<R1> pi(FI[npi]);
4380                 R mes = B ? B->x : T.mesure();
4381                 R coef = mes *pi.a;
4382                 R1 Pt(pi);
4383                 pa =a;
4384                 Ku.BF(Dop,Pt,fu);
4385                 MeshPointStack(stack)->set(T(Pt),Pt,Kv);
4386                 if (classoptm) {
4387                     if( oldopt) (*Op.optiexpK)(stack); // call old optim version
4388                     else Op.optiexpK->eval(stack,iloop++,unvarexp); // new optim version
4389                 }
4390                 if (!same) Kv.BF(Dop,Pt,fv);
4391                 int il=0;
4392                 for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4393                 {  // attention la fonction test donne la ligne
4394                     //  et la fonction test est en second
4395                     BilinearOperator::K ll(*l);
4396                     //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4397                     long jcomp= ll.first.first.first,jop=ll.first.first.second;
4398                     long icomp= ll.first.second.first,iop=ll.first.second.second;
4399 
4400                     R ccc = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
4401                     if ( copt && ( mat.optim==1) && Kv.number <1)
4402                     {
4403                         R cc  =  GetAny<R>(ll.second.eval(stack));
4404                         //cout << *(copt[il]) << " == " <<  cc << endl;
4405                         CheckErrorOptimisation(cc,ccc,"Sorry error in Optimization (e) add:  int2d(Th,optimize=0)(...)");
4406                         /*if ( ccc != cc) {
4407                          cerr << cc << " != " << ccc << " => ";
4408                          cerr << "Sorry error in Optimization (e) add:  int2d(Th,optimize=0)(...)" << endl;
4409                          ExecError("In Optimized version "); }*/
4410                     }
4411                     int fi=Kv.dfcbegin(icomp);
4412                     int li=Kv.dfcend(icomp);
4413                     int fj=Ku.dfcbegin(jcomp);
4414                     int lj=Ku.dfcend(jcomp);
4415                     ccc *= coef;
4416 
4417                     // attention la fonction test donne la ligne
4418                     //  et la fonction test est en second
4419                     for ( i=fi;  i<li;   i++ )
4420                     {
4421                         for ( j=fj;  j<lj;   j++ )
4422                         {
4423                             R w_i =  fv(i,icomp,iop);
4424                             R w_j =  fu(j,jcomp,jop);
4425                             mat(i,j) += ccc * w_i*w_j;
4426                         }
4427                     }
4428                 }
4429             }
4430         else if(B)
4431             ffassert(0);
4432         else // int on edge ie
4433             ffassert(0);
4434 
4435         *MeshPointStack(stack) = mp;
4436     }
4437 
4438 
4439 
4440     ////////////////////////////////////////////////
4441     // Element_Op for MatriceElementaireSymetrique
4442     ////////////////////////////////////////////////
4443     // using to define new solver
4444 
4445     // creating an instance of Element_Op with MatriceElementaireSymetrique
4446     // case 2d
4447     // xxxxxxxxxxxxxxxxx  modif a faire
4448     template<class R>
Element_Op(MatriceElementaireSymetrique<R,FESpace> & mat,const FElement & Ku,double * p,int ie,int label,void * vstack,R2 * B)4449     void  Element_Op(MatriceElementaireSymetrique<R,FESpace> & mat,const FElement & Ku,double * p,int ie,int label, void * vstack,R2*B)
4450     {
4451         Stack stack=pvoid2Stack(vstack);
4452         MeshPoint mp= *MeshPointStack(stack);
4453         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
4454         const Triangle & T  = Ku.T;
4455         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
4456         //  const QuadratureFormular1d & FIb = QF_GaussLegendre2;
4457         const QuadratureFormular & FI = mat.FIT;
4458         const QuadratureFormular1d & FIb = mat.FIE;
4459         long npi;
4460         R *a=mat.a;
4461         R *pa=a;
4462         long i,j;
4463         long n= mat.n,m=mat.m,nx=n*(m+1)/2;
4464         long N= Ku.N;
4465         //long M=N;
4466         // bool show = Ku.Vh.Th(T)==0;
4467         //    char * xxx[] ={" u"," v"," p"," q"," r"};
4468         //char * xxxx[] ={" u'"," v'"," p'"," q'"," r'"};
4469         //char * yyy[] ={" ","_x ","_y "};
4470 
4471 
4472         throwassert(mat.bilinearform);
4473 
4474         const Opera &Op(*mat.bilinearform);
4475         bool classoptm = copt && Op.optiexpK;
4476         // assert(  (copt !=0) ||  (Op.where_in_stack_opt.size() !=0) );
4477         if (Ku.number<1  && verbosity/100 && verbosity % 10 == 2 )
4478         cout << "Element_Op S: copt = " << copt << " " << classoptm << " opt "<< mat.optim << endl;
4479         assert(Op.MaxOp() <last_operatortype);
4480 
4481 
4482         KN<bool> Dop(last_operatortype);
4483         Op.DiffOp(Dop);
4484         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
4485         // assert(lastop<=3);
4486 
4487         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
4488 
4489         pa =a;
4490         for (i=0;i< nx;i++)
4491         *pa++ = 0.;
4492 
4493         if (ie<0)
4494         for (npi=0;npi<FI.n;npi++) // loop on the integration point
4495         {
4496             QuadraturePoint pi(FI[npi]);
4497             double mes= B ? B->x :T.area;
4498             double coef = mes*pi.a;
4499             R2 Pt(pi);
4500             pa =a;
4501             Ku.BF(Dop,Pt,fu);
4502             MeshPointStack(stack)->set(T(pi),pi,Ku);
4503             if (classoptm) (*Op.optiexpK)(stack); // call optim version
4504             int il=0;
4505             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4506             {  // attention la fonction test donne la ligne
4507                 //  et la fonction test est en second
4508                 BilinearOperator::K ll(*l);
4509                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4510                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
4511                 long icomp= ll.first.second.first,iop=ll.first.second.second;
4512 
4513                 R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4514                 if ( copt && Ku.number <1)
4515                 {
4516                     R cc  =  GetAny<R>(ll.second.eval(stack));
4517                     // cout << *(copt[il]) << " == " <<  cc << endl;
4518                     CheckErrorOptimisation(c,cc,"Sorry error in Optimization (l) add:  int2d(Th,optimize=0)(...)");
4519                     /*
4520                     if ( c != cc) {
4521                         cerr << c << " != " << cc << " => ";
4522                         cerr << "Sorry error in Optimization (l) add:  int2d(Th,optimize=0)(...)" << endl;
4523                         ExecError("In Optimized version "); }*/
4524                 }
4525                 c *= coef ;
4526                 long fi=Ku.dfcbegin(icomp);
4527                 long li=Ku.dfcend(icomp);
4528                 long fj=Ku.dfcbegin(jcomp);
4529                 long lj=Ku.dfcend(jcomp);
4530                 if (verbosity>10 && Ku.Vh.Th(T) < 1 && npi < 1)
4531                 cout << " ic "<< icomp << fi<< " "<< lj << " "<< " c "<< jcomp << " " <<fj << " "<< lj << endl;
4532                 for ( i=fi;  i<li;   i++ )
4533                 for ( j=fj;  j<min(lj,i+1);  j++ ) //
4534                 {
4535                     R w_i =  fu(i,icomp,iop);
4536                     R w_j =  fu(j,jcomp,jop);
4537 
4538                     mat(i,j)  +=  c * w_i*w_j;
4539 
4540                 }
4541 
4542             }
4543 
4544             /*
4545              for ( i=0;  i<n;   i++ )
4546              {
4547              RNM_ wi(fu(i,'.','.'));
4548              //    if (Ku.Vh.Th(T) < 1) cout << i <<" " <<Pt<< "wi =" << wi ;
4549              for ( j=0;  j<=i;  j++,pa++ ) //
4550              {
4551 
4552              RNM_ wj(fu(j,'.','.'));
4553              //   if (Ku.Vh.Th(T) < 1) cout << j <<" " <<Pt<< "wj =" << wj ;
4554              int il=0;
4555              for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4556              {
4557              const  BilinearOperator::K & ll(*l);
4558              pair<int,int> ii(ll.first.first),jj(ll.first.second);
4559              double w_i =  wi(ii.first,ii.second);
4560              double w_j =  wj(jj.first,jj.second);
4561 
4562              R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4563              if ( copt && Ku.number <1)
4564              {
4565              R cc  =  GetAny<R>(ll.second.eval(stack));
4566              // cout << *(copt[il]) << " == " <<  cc << endl;
4567              if ( c != cc) {
4568              cerr << c << " != " << cc << " => ";
4569              cerr << "Sorry error in Optimization (m) add:  int2d(Th,optimize=0)(...)" << endl;
4570              ExecError("In Optimized version "); }
4571              }
4572 
4573              *pa += coef * c * w_i*w_j;
4574              }
4575              }
4576 
4577              }*/
4578 
4579         }
4580         else if(B)
4581         {
4582             R2 PA(B[0]),PB(B[1]);
4583             R2 A=T(PA),B=T(PB);
4584             R2 E(A,B);
4585             double le = sqrt((E,E));
4586             if(le > 1e-15)
4587             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4588             {
4589 
4590                 pa =a;
4591                 QuadratureFormular1dPoint pi( FIb[npi]);
4592 
4593                 double coef = le*pi.a;
4594                 double sa=pi.x,sb=1-sa;
4595                 R2 Pt(PA*sa+PB*sb ); //
4596                 Ku.BF(Dop,Pt,fu);
4597                 // int label=-999999; // a passer en argument
4598                 MeshPointStack(stack)->set(T(Pt),Pt,Ku,0,R2(E.y,-E.x)/le,0);
4599                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
4600 
4601                 int il=0;
4602                 for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4603                 {  // attention la fonction test donne la ligne
4604                     //  et la fonction test est en second
4605                     BilinearOperator::K ll(*l);
4606                     //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4607                     long jcomp= ll.first.first.first,jop=ll.first.first.second;
4608                     long icomp= ll.first.second.first,iop=ll.first.second.second;
4609 
4610                     R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4611                     if ( copt && Ku.number <1)
4612                     {
4613                         R cc  =  GetAny<R>(ll.second.eval(stack));
4614                         // cout << *(copt[il]) << " == " <<  cc << endl;
4615                         CheckErrorOptimisation(c,cc,"Sorry error in Optimization (n) add:  int2d(Th,optimize=0)(...)");
4616                         /*
4617                         if ( c != cc) {
4618                             cerr << c << " != " << cc << " => ";
4619                             cerr << "Sorry error in Optimization (n) add:  int2d(Th,optimize=0)(...)" << endl;
4620                             ExecError("In Optimized version "); }*/
4621                     }
4622                     c *= coef ;
4623                     long fi=Ku.dfcbegin(icomp);
4624                     long li=Ku.dfcend(icomp);
4625                     long fj=Ku.dfcbegin(jcomp);
4626                     long lj=Ku.dfcend(jcomp);
4627 
4628                     for ( i=fi;  i<li;   i++ )
4629                     for ( j=fj;  j<min(lj,i+1);  j++,pa++ ) //
4630                     {
4631                         R w_i =  fu(i,icomp,iop);
4632                         R w_j =  fu(j,jcomp,jop);
4633 
4634                         mat(i,j)  +=  c * w_i*w_j;
4635                         /*
4636                          if (Ku.Vh.Th(T) < 1 && npi < 1 && i < 1 && j < 1 )
4637                          cout <<" + " << c << " (" <<coef << " " << w_i << " " << w_j << " " << jj.first << " " << jj.second << ") " ;
4638                          */
4639                     }
4640 
4641                 }
4642             }
4643         }
4644         else    // int on edge ie
4645         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4646         {
4647 
4648             pa =a;
4649             QuadratureFormular1dPoint pi( FIb[npi]);
4650             R2 E=T.Edge(ie);
4651             double le = sqrt((E,E));
4652             double coef = le*pi.a;
4653             double sa=pi.x,sb=1-sa;
4654             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
4655             PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
4656             R2 Pt(PA*sa+PB*sb ); //
4657             Ku.BF(Dop,Pt,fu);
4658             // int label=-999999; // a passer en argument
4659             MeshPointStack(stack)->set(T(Pt),Pt,Ku,label,R2(E.y,-E.x)/le,ie);
4660             if (classoptm) (*Op.optiexpK)(stack); // call optim version
4661 
4662             int il=0;
4663             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4664             {  // attention la fonction test donne la ligne
4665                 //  et la fonction test est en second
4666                 BilinearOperator::K ll(*l);
4667                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4668                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
4669                 long icomp= ll.first.second.first,iop=ll.first.second.second;
4670 
4671                 R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4672                 if ( copt && Ku.number <1)
4673                 {
4674                     R cc  =  GetAny<R>(ll.second.eval(stack));
4675                     // cout << *(copt[il]) << " == " <<  cc << endl;
4676                     CheckErrorOptimisation(c,cc,"Sorry error in Optimization (o) add:  int2d(Th,optimize=0)(...)");
4677                     /*
4678                     if ( c != cc) {
4679                         cerr << c << " != " << cc << " => ";
4680                         cerr << "Sorry error in Optimization (o) add:  int2d(Th,optimize=0)(...)" << endl;
4681                         ExecError("In Optimized version "); }*/
4682                 }
4683                 c *= coef ;
4684                 long fi=Ku.dfcbegin(icomp);
4685                 long li=Ku.dfcend(icomp);
4686                 long fj=Ku.dfcbegin(jcomp);
4687                 long lj=Ku.dfcend(jcomp);
4688 
4689                 for ( i=fi;  i<li;   i++ )
4690                 for ( j=fj;  j<min(lj,i+1);  j++,pa++ ) //
4691                 {
4692                     R w_i =  fu(i,icomp,iop);
4693                     R w_j =  fu(j,jcomp,jop);
4694 
4695                     mat(i,j)  +=  c * w_i*w_j;
4696                     /*
4697                      if (Ku.Vh.Th(T) < 1 && npi < 1 && i < 1 && j < 1 )
4698                      cout <<" + " << c << " (" <<coef << " " << w_i << " " << w_j << " " << jj.first << " " << jj.second << ") " ;
4699                      */
4700                 }
4701 
4702             }
4703 
4704             /*
4705              for ( i=0;  i<n;   i++ )
4706              // if ( onWhatIsEdge[ie][Ku.DFOnWhat(i)]) // generaly wrong FH dec 2003
4707              {
4708              RNM_ wi(fu(i,'.','.'));
4709              for ( j=0;  j<=i;   j++,pa++ )
4710              {
4711              RNM_ wj(fu(j,'.','.'));
4712              int il=0;
4713              for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4714              // if (onWhatIsEdge[ie][Ku.DFOnWhat(j)]) // generaly wrong FH dec 2003
4715              {
4716              BilinearOperator::K ll(*l);
4717              pair<int,int> ii(ll.first.first),jj(ll.first.second);
4718              double w_i =  wi(ii.first,ii.second);
4719              double w_j =  wj(jj.first,jj.second);
4720              // R ccc = GetAny<R>(ll.second.eval(stack));
4721              R ccc = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4722              if ( copt && Ku.number <1)
4723              {
4724              R cc  =  GetAny<R>(ll.second.eval(stack));
4725              if ( ccc != cc) {
4726              cerr << ccc << " != " << cc << ", xy = "<< T(Pt) << " => ";
4727              cerr << "Sorry error in Optimization (d)  add:  int2d(Th,optimize=0)(...)" << endl;
4728              ExecError("In Optimized version "); }
4729              }
4730 
4731              *pa += coef * ccc * w_i*w_j;
4732              }
4733              }
4734              } //else pa+= i+1;
4735              */
4736         }
4737 
4738         /*
4739          pa=a;
4740          if (Ku.Vh.Th(T) <=0 ) {
4741          cout <<endl  << " Triangle " << Ku.Vh.Th(T) << " =  "<<  T[0] << ", " << T[1] << ", " << T[2] << " " << nx << endl;
4742          for (int i=0;i<n;i++)
4743          {
4744          cout << setw(2) << i << setw(4) << mat.ni[i] << " :";
4745          for (int j=0;j<=i;j++)
4746          cout << setw(5)  << (*pa++) << " ";
4747          cout << endl;
4748          } }
4749          pa=a;
4750          for (int i=0;i<n;i++)
4751          cout << mat.ni[i] << " " ;
4752          for (int i=0;i<n;i++)
4753          for (int j=0;j<n;j++,pa++)
4754          if ( mat.ni[i]==150 && mat.nj[j] == 150)
4755          cout << "a_150,150 = "<< *pa ;
4756          cout << endl;
4757          */
4758 
4759         *MeshPointStack(stack) = mp;
4760 
4761     }
4762 
4763 
4764 
4765     // creating an instance of Element_Op MatriceElementaireSymetrique
4766     // case 3D volume
4767     template<class R>
Element_Op(MatriceElementaireSymetrique<R,FESpace3> & mat,const FElement3 & Ku,double * p,int ie,int label,void * vstack,R3 * B)4768     void  Element_Op(MatriceElementaireSymetrique<R,FESpace3> & mat,const FElement3 & Ku,double * p,int ie,int label, void * vstack,R3 *B)
4769     {
4770         //    ffassert(B==0);
4771         Stack stack=pvoid2Stack(vstack);
4772         typedef FESpace3 FESpace;
4773         typedef typename FESpace3::Mesh Mesh;
4774         typedef Mesh *pmesh ;
4775         typedef typename Mesh::Element Element;
4776         MeshPoint mp= *MeshPointStack(stack);
4777         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
4778         const Element & T  = Ku.T;
4779 
4780         const GQuadratureFormular<R3> & FI = mat.FIT;
4781         const GQuadratureFormular<R2> & FIb = mat.FIE;
4782 
4783         long npi;
4784         R *a=mat.a;
4785         R *pa=a;
4786         long i,j;
4787         long n= mat.n,m=mat.m,nx=n*(m+1)/2;
4788         long N= Ku.N;
4789 
4790         assert(mat.bilinearform);
4791 
4792         const Opera &Op(*mat.bilinearform);
4793         bool classoptm = copt && Op.optiexpK;
4794         // assert(  (copt !=0) ||  (Op.where_in_stack_opt.size() !=0) );
4795         int lastop;
4796         What_d Dop = Op.DiffOp(lastop);
4797 
4798         if (Ku.number<1  && verbosity/100 && verbosity % 10 == 2 )
4799         cout << "Element_Op S 3d: copt = " << copt << " " << classoptm << " lastop = "<< lastop << " Dop " << Dop << " opt: " << mat.optim << endl;
4800         assert(Op.MaxOp() <last_operatortype);
4801 
4802         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
4803 
4804 
4805         pa =a;
4806         for (i=0;i< nx;i++)
4807         *pa++ = 0.;
4808 
4809         if (ie<0)
4810         for (npi=0;npi<FI.n;npi++) // loop on the integration point
4811         {
4812             GQuadraturePoint<R3> pi(FI[npi]);
4813             double coef = T.mesure()*pi.a;
4814             //R3 Pt(pi);
4815             pa =a;
4816             Ku.BF(Dop,pi,fu);
4817             MeshPointStack(stack)->set(T(pi),pi,Ku);
4818             if (classoptm) (*Op.optiexpK)(stack); // call optim version
4819             int il=0;
4820             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4821             {  // attention la fonction test donne la ligne
4822                 //  et la fonction test est en second
4823                 BilinearOperator::K ll(*l);
4824                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4825                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
4826                 long icomp= ll.first.second.first,iop=ll.first.second.second;
4827 
4828 
4829                 R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4830                 if ( copt && Ku.number <1)
4831                 {
4832                     R cc  =  GetAny<R>(ll.second.eval(stack));
4833                     // cout << *(copt[il]) << " == " <<  cc << endl;
4834                     CheckErrorOptimisation(c,cc,"Sorry error in Optimization (i) add:  int2d(Th,optimize=0)(...)");
4835                     /*
4836                     if ( c != cc) {
4837                         cerr << c << " != " << cc << " => ";
4838                         cerr << "Sorry error in Optimization (i) add:  int2d(Th,optimize=0)(...)" << endl;
4839                         ExecError("In Optimized version "); }*/
4840                 }
4841                 c *= coef ;
4842                 long fi=Ku.dfcbegin(icomp);
4843                 long li=Ku.dfcend(icomp);
4844                 long fj=Ku.dfcbegin(jcomp);
4845                 long lj=Ku.dfcend(jcomp);
4846 
4847                 for ( i=fi;  i<li;   i++ )
4848                 for ( j=fj;  j<min(lj,i+1);  j++,pa++ ) //
4849                 {
4850                     R w_i =  fu(i,icomp,iop);
4851                     R w_j =  fu(j,jcomp,jop);
4852 
4853                     mat(i,j)  +=  c * w_i*w_j;
4854 
4855                     /*
4856                      if (Ku.Vh.Th(T) < 1 && npi < 1 && i < 1 && j < 1 )
4857                      cout <<" + " << c << " (" <<coef << " " << w_i << " " << w_j << " " << jj.first << " " << jj.second << ") " ;
4858                      */
4859                 }
4860 
4861             }
4862 
4863         }
4864         else if(B)
4865         {  // int on leveset
4866             int np = ie-10; //= (B[0].x == B[3].x ) && (B[0].y == B[3].y ) && (B[0].z == B[3].z ) ? 3 : 4;
4867             if(verbosity>999) cout << "    Ass mat pleine /"<< np << endl;
4868             assert( np==3 || np==4);
4869             // XXXXXXX
4870             double epsmes3=T.mesure()*T.mesure()*1e-18;
4871             R3 PP[4];
4872             double l[3];
4873             for(int i=0; i< np; ++i)
4874             PP[i]= T(B[i]);
4875 
4876             for( int i =0; i+1 < np; i+=2)
4877             { // 0,1,, a and 2,3,0.
4878                 int i0=i,i1=i+1,i2=(i+2)%np;
4879                 R3 NN= R3(PP[i0],PP[i1])^R3(PP[i0],PP[i2]);
4880                 double mes2 = (NN,NN);
4881                 double mes = sqrt(mes2);
4882 
4883                 if(mes2*mes <epsmes3) continue; //  too small
4884                 NN /= mes;
4885                 mes *= 0.5;
4886                 if(verbosity>999)
4887                 cout << " --int on leveset3d " << np << " " << mes << " " << i0<<i1<<i2 <<endl;
4888                 double asum=0;
4889                 for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4890                 {
4891                     GQuadraturePoint<R2>  pi( FIb[npi]);
4892                     // cout << " %% " << npi << " " << pi.a << " " << pi.x << " " << pi.y << endl;
4893                     asum+= pi.a;
4894                     pi.toBary(l);
4895                     R3 Pt( l[0]*B[i0]+l[1]*B[i1]+l[2]*B[i2]); //
4896                     double coef = mes*pi.a; // correction 0.5 050109 FH
4897                     Ku.BF(Dop,Pt,fu);
4898                     MeshPointStack(stack)->set(T(Pt),Pt,Ku,label,NN,ie);
4899                     if (classoptm) (*Op.optiexpK)(stack); // call optim version
4900 
4901                     pa=a;
4902                     int il=0;
4903                     for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4904                     {  // attention la fonction test donne la ligne
4905                         //  et la fonction test est en second
4906                         BilinearOperator::K ll(*l);
4907                         //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4908                         long jcomp= ll.first.first.first,jop=ll.first.first.second;
4909                         long icomp= ll.first.second.first,iop=ll.first.second.second;
4910 
4911                         R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4912                         if ( copt && Ku.number <1)
4913                         {
4914                             R cc  =  GetAny<R>(ll.second.eval(stack));
4915                             // cout << *(copt[il]) << " == " <<  cc << endl;
4916                             CheckErrorOptimisation(c,cc,"Sorry error in Optimization (j) add:  int2d(Th,optimize=0)(...)");
4917                             /*
4918                             if ( c != cc) {
4919                                 cerr << c << " != " << cc << " => ";
4920                                 cerr << "Sorry error in Optimization (j) add:  int2d(Th,optimize=0)(...)" << endl;
4921                                 ExecError("In Optimized version "); }*/
4922                         }
4923                         c *= coef ;
4924                         long fi=Ku.dfcbegin(icomp);
4925                         long li=Ku.dfcend(icomp);
4926                         long  fj=Ku.dfcbegin(jcomp);
4927                         long  lj=Ku.dfcend(jcomp);
4928 
4929                         for (long i=fi;  i<li;   i++ )
4930                         for (long j=fj;  j<min(lj,i+1);  j++,pa++ ) //
4931                         {
4932                             R w_i =  fu(i,icomp,iop);
4933                             R w_j =  fu(j,jcomp,jop);
4934 
4935                             mat(i,j)  +=  c * w_i*w_j;
4936 
4937                             /*
4938                              if (Ku.Vh.Th(T) < 1 && npi < 1 && i < 1 && j < 1 )
4939                              cout <<" + " << c << " (" <<coef << " " << w_i << " " << w_j << " " << jj.first << " " << jj.second << ") " ;
4940                              */
4941                         }
4942 
4943                     }
4944 
4945 
4946 
4947                 }
4948 
4949 
4950             }
4951 
4952         }// end int level set ...
4953         else
4954         // int on edge ie
4955         for (npi=0;npi<FIb.n;npi++) // loop on the integration point
4956         {
4957 
4958             pa =a;
4959             GQuadraturePoint<R2> pi( FIb[npi]);
4960             R3 NN= T.N(ie);
4961             double mes=NN.norme();
4962             NN/=mes;
4963             mes *=0.5;
4964             double coef = mes*pi.a; // correction 0.5 050109 FH
4965             R3 Pt(T.PBord(ie,pi));
4966             Ku.BF(Dop,Pt,fu);
4967             // int label=-999999; // a passer en argument
4968             MeshPointStack(stack)->set(T(Pt),Pt,Ku,label,NN,ie);
4969             if (classoptm) (*Op.optiexpK)(stack); // call optim version
4970             int il=0;
4971             for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
4972             {  // attention la fonction test donne la ligne
4973                 //  et la fonction test est en second
4974                 BilinearOperator::K ll(*l);
4975                 //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
4976                 long jcomp= ll.first.first.first,jop=ll.first.first.second;
4977                 long icomp= ll.first.second.first,iop=ll.first.second.second;
4978 
4979                 R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
4980                 if ( copt && Ku.number <1)
4981                 {
4982                     R cc  =  GetAny<R>(ll.second.eval(stack));
4983                     // cout << *(copt[il]) << " == " <<  cc << endl;
4984                     CheckErrorOptimisation(c,cc,"Sorry error in Optimization (k) add:  int2d(Th,optimize=0)(...)");
4985                     /*
4986                     if ( c != cc) {
4987                         cerr << c << " != " << cc << " => ";
4988                         cerr << "Sorry error in Optimization (k) add:  int2d(Th,optimize=0)(...)" << endl;
4989                         ExecError("In Optimized version "); }*/
4990                 }
4991                 c *= coef ;
4992                 long fi=Ku.dfcbegin(icomp);
4993                 long li=Ku.dfcend(icomp);
4994                 long  fj=Ku.dfcbegin(jcomp);
4995                 long  lj=Ku.dfcend(jcomp);
4996 
4997                 for (long i=fi;  i<li;   i++ )
4998                 for (long j=fj;  j<min(lj,i+1);  j++,pa++ ) //
4999                 {
5000                     R w_i =  fu(i,icomp,iop);
5001                     R w_j =  fu(j,jcomp,jop);
5002 
5003                     mat(i,j)  +=  c * w_i*w_j;
5004 
5005                     /*
5006                      if (Ku.Vh.Th(T) < 1 && npi < 1 && i < 1 && j < 1 )
5007                      cout <<" + " << c << " (" <<coef << " " << w_i << " " << w_j << " " << jj.first << " " << jj.second << ") " ;
5008                      */
5009                 }
5010 
5011             }
5012 
5013 
5014         }
5015 
5016 
5017         pa=a;
5018         if (Ku.Vh.Th(T) <0 & verbosity>100) {
5019             cout <<endl  << " Tet " << Ku.Vh.Th(T) << " =  "<<  T << "  nx= " << nx << endl;
5020             for (int i=0;i<n;i++)
5021             {
5022                 cout << setw(2) << i << setw(4) << mat.ni[i] << " :";
5023                 for (int j=0;j<=i;j++)
5024                 cout << setw(5)  << (*pa++) << " ";
5025                 cout << endl;
5026             } }
5027         /*
5028          pa=a;
5029          for (int i=0;i<n;i++)
5030          cout << mat.ni[i] << " " ;
5031          for (int i=0;i<n;i++)
5032          for (int j=0;j<n;j++,pa++)
5033          if ( mat.ni[i]==150 && mat.nj[j] == 150)
5034          cout << "a_150,150 = "<< *pa ;
5035          cout << endl;
5036          */
5037 
5038         *MeshPointStack(stack) = mp;
5039 
5040     }
5041 
5042     // creating an instance of Element_Op with MatriceElementaireSymetrique
5043     // case 3D surface
5044     // xxxxxxxxxxxxxxxxx  modif a faire
5045     template<class R>
Element_Op(MatriceElementaireSymetrique<R,FESpaceS> & mat,const FElementS & Ku,double * p,int ie,int label,void * vstack,R3 * B)5046     void  Element_Op(MatriceElementaireSymetrique<R,FESpaceS> & mat,const FElementS & Ku,double * p,int ie,int label, void * vstack,R3 *B)
5047     {
5048         Stack stack=pvoid2Stack(vstack);
5049         MeshPoint mp= *MeshPointStack(stack);
5050         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5051         const TriangleS & T  = Ku.T;
5052         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5053         //  const QuadratureFormular1d & FIb = QF_GaussLegendre2;
5054         const QuadratureFormular & FI = mat.FIT;
5055         const QuadratureFormular1d & FIb = mat.FIE;
5056         long npi;
5057         R *a=mat.a;
5058         R *pa=a;
5059         long i,j;
5060         long n= mat.n,m=mat.m,nx=n*(m+1)/2;
5061         long N= Ku.N;
5062         //long M=N;
5063         // bool show = Ku.Vh.Th(T)==0;
5064         //    char * xxx[] ={" u"," v"," p"," q"," r"};
5065         //char * xxxx[] ={" u'"," v'"," p'"," q'"," r'"};
5066         //char * yyy[] ={" ","_x ","_y "};
5067 
5068 
5069         throwassert(mat.bilinearform);
5070 
5071         const Opera &Op(*mat.bilinearform);
5072         bool classoptm = copt && Op.optiexpK;
5073         // assert(  (copt !=0) ||  (Op.where_in_stack_opt.size() !=0) );
5074         if (Ku.number<1  && verbosity/100 && verbosity % 10 == 2 )
5075             cout << "Element_Op S: copt = " << copt << " " << classoptm << " opt "<< mat.optim << endl;
5076         assert(Op.MaxOp() <last_operatortype);
5077 
5078         int lastop=0;
5079         What_d Dop = Op.DiffOp(lastop);
5080 
5081         // assert(lastop<=3);
5082 
5083         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5084 
5085         pa =a;
5086         for (i=0;i< nx;i++)
5087             *pa++ = 0.;
5088 
5089         if (ie<0)
5090             for (npi=0;npi<FI.n;npi++) // loop on the integration point
5091             {
5092                 QuadraturePoint pi(FI[npi]);
5093                 double mes= B ? B->x :T.mesure();
5094                 double coef = mes*pi.a;
5095                 R2 Pt(pi);
5096                 pa =a;
5097                 Ku.BF(Dop,Pt,fu);
5098                 MeshPointStack(stack)->set(T(pi),pi,Ku);
5099                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
5100                 int il=0;
5101                 for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5102                 {  // attention la fonction test donne la ligne
5103                     //  et la fonction test est en second
5104                     BilinearOperator::K ll(*l);
5105                     //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
5106                     long jcomp= ll.first.first.first,jop=ll.first.first.second;
5107                     long icomp= ll.first.second.first,iop=ll.first.second.second;
5108 
5109                     R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
5110                     if ( copt && Ku.number <1)
5111                     {
5112                         R cc  =  GetAny<R>(ll.second.eval(stack));
5113                         // cout << *(copt[il]) << " == " <<  cc << endl;
5114                         CheckErrorOptimisation(c,cc,"Sorry error in Optimization (l) add:  int2d(Th,optimize=0)(...)");
5115                         /*
5116                         if ( c != cc) {
5117                             cerr << c << " != " << cc << " => ";
5118                             cerr << "Sorry error in Optimization (l) add:  int2d(Th,optimize=0)(...)" << endl;
5119                             ExecError("In Optimized version "); }*/
5120                     }
5121                     c *= coef ;
5122                     long fi=Ku.dfcbegin(icomp);
5123                     long li=Ku.dfcend(icomp);
5124                     long fj=Ku.dfcbegin(jcomp);
5125                     long lj=Ku.dfcend(jcomp);
5126                     if (verbosity>10 && Ku.Vh.Th(T) < 1 && npi < 1)
5127                         cout << " ic "<< icomp << fi<< " "<< lj << " "<< " c "<< jcomp << " " <<fj << " "<< lj << endl;
5128                     for ( i=fi;  i<li;   i++ )
5129                         for ( j=fj;  j<min(lj,i+1);  j++ ) //
5130                         {
5131                             R w_i =  fu(i,icomp,iop);
5132                             R w_j =  fu(j,jcomp,jop);
5133 
5134                             mat(i,j)  +=  c * w_i*w_j;
5135 
5136                         }
5137 
5138                 }
5139 
5140                 /*
5141                  for ( i=0;  i<n;   i++ )
5142                  {
5143                  RNM_ wi(fu(i,'.','.'));
5144                  //    if (Ku.Vh.Th(T) < 1) cout << i <<" " <<Pt<< "wi =" << wi ;
5145                  for ( j=0;  j<=i;  j++,pa++ ) //
5146                  {
5147 
5148                  RNM_ wj(fu(j,'.','.'));
5149                  //   if (Ku.Vh.Th(T) < 1) cout << j <<" " <<Pt<< "wj =" << wj ;
5150                  int il=0;
5151                  for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5152                  {
5153                  const  BilinearOperator::K & ll(*l);
5154                  pair<int,int> ii(ll.first.first),jj(ll.first.second);
5155                  double w_i =  wi(ii.first,ii.second);
5156                  double w_j =  wj(jj.first,jj.second);
5157 
5158                  R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
5159                  if ( copt && Ku.number <1)
5160                  {
5161                  R cc  =  GetAny<R>(ll.second.eval(stack));
5162                  // cout << *(copt[il]) << " == " <<  cc << endl;
5163                  if ( c != cc) {
5164                  cerr << c << " != " << cc << " => ";
5165                  cerr << "Sorry error in Optimization (m) add:  int2d(Th,optimize=0)(...)" << endl;
5166                  ExecError("In Optimized version "); }
5167                  }
5168 
5169                  *pa += coef * c * w_i*w_j;
5170                  }
5171                  }
5172 
5173                  }*/
5174 
5175             }
5176         else if(B)
5177 
5178             ffassert(0);
5179 
5180         else    // int on edge ie
5181             for (npi=0;npi<FIb.n;npi++) // loop on the integration point
5182             {
5183 
5184                 pa =a;
5185                 QuadratureFormular1dPoint pi( FIb[npi]);
5186                 R3 E=T.Edge(ie);
5187                 double le = sqrt((E,E));
5188                 double coef = le*pi.a;
5189                 double sa=pi.x,sb=1-sa;
5190                 R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
5191                 PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
5192                 R2 Pt(PA*sa+PB*sb ); //
5193                 Ku.BF(Dop,Pt,fu);
5194                 // int label=-999999; // a passer en argument
5195                 MeshPointStack(stack)->set(T(Pt),Pt,Ku,label,R2(E.y,-E.x)/le,ie);
5196                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
5197 
5198                 int il=0;
5199                 for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5200                 {  // attention la fonction test donne la ligne
5201                     //  et la fonction test est en second
5202                     BilinearOperator::K ll(*l);
5203                     //          pair<int,int> jj(ll.first.first),ii(ll.first.second);
5204                     long jcomp= ll.first.first.first,jop=ll.first.first.second;
5205                     long icomp= ll.first.second.first,iop=ll.first.second.second;
5206 
5207                     R c = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
5208                     if ( copt && Ku.number <1)
5209                     {
5210                         R cc  =  GetAny<R>(ll.second.eval(stack));
5211                         // cout << *(copt[il]) << " == " <<  cc << endl;
5212                         CheckErrorOptimisation(c,cc,"Sorry error in Optimization (o) add:  int2d(Th,optimize=0)(...)");
5213                         /*
5214                         if ( c != cc) {
5215                             cerr << c << " != " << cc << " => ";
5216                             cerr << "Sorry error in Optimization (o) add:  int2d(Th,optimize=0)(...)" << endl;
5217                             ExecError("In Optimized version "); }*/
5218                     }
5219                     c *= coef ;
5220                     long fi=Ku.dfcbegin(icomp);
5221                     long li=Ku.dfcend(icomp);
5222                     long fj=Ku.dfcbegin(jcomp);
5223                     long lj=Ku.dfcend(jcomp);
5224 
5225                     for ( i=fi;  i<li;   i++ )
5226                         for ( j=fj;  j<min(lj,i+1);  j++,pa++ ) //
5227                         {
5228                             R w_i =  fu(i,icomp,iop);
5229                             R w_j =  fu(j,jcomp,jop);
5230 
5231                             mat(i,j)  +=  c * w_i*w_j;
5232                             /*
5233                              if (Ku.Vh.Th(T) < 1 && npi < 1 && i < 1 && j < 1 )
5234                              cout <<" + " << c << " (" <<coef << " " << w_i << " " << w_j << " " << jj.first << " " << jj.second << ") " ;
5235                              */
5236                         }
5237 
5238                 }
5239 
5240                 /*
5241                  for ( i=0;  i<n;   i++ )
5242                  // if ( onWhatIsEdge[ie][Ku.DFOnWhat(i)]) // generaly wrong FH dec 2003
5243                  {
5244                  RNM_ wi(fu(i,'.','.'));
5245                  for ( j=0;  j<=i;   j++,pa++ )
5246                  {
5247                  RNM_ wj(fu(j,'.','.'));
5248                  int il=0;
5249                  for (BilinearOperator::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5250                  // if (onWhatIsEdge[ie][Ku.DFOnWhat(j)]) // generaly wrong FH dec 2003
5251                  {
5252                  BilinearOperator::K ll(*l);
5253                  pair<int,int> ii(ll.first.first),jj(ll.first.second);
5254                  double w_i =  wi(ii.first,ii.second);
5255                  double w_j =  wj(jj.first,jj.second);
5256                  // R ccc = GetAny<R>(ll.second.eval(stack));
5257                  R ccc = copt ? *(copt[il]): GetAny<R>(ll.second.eval(stack));
5258                  if ( copt && Ku.number <1)
5259                  {
5260                  R cc  =  GetAny<R>(ll.second.eval(stack));
5261                  if ( ccc != cc) {
5262                  cerr << ccc << " != " << cc << ", xy = "<< T(Pt) << " => ";
5263                  cerr << "Sorry error in Optimization (d)  add:  int2d(Th,optimize=0)(...)" << endl;
5264                  ExecError("In Optimized version "); }
5265                  }
5266 
5267                  *pa += coef * ccc * w_i*w_j;
5268                  }
5269                  }
5270                  } //else pa+= i+1;
5271                  */
5272             }
5273 
5274         /*
5275          pa=a;
5276          if (Ku.Vh.Th(T) <=0 ) {
5277          cout <<endl  << " Triangle " << Ku.Vh.Th(T) << " =  "<<  T[0] << ", " << T[1] << ", " << T[2] << " " << nx << endl;
5278          for (int i=0;i<n;i++)
5279          {
5280          cout << setw(2) << i << setw(4) << mat.ni[i] << " :";
5281          for (int j=0;j<=i;j++)
5282          cout << setw(5)  << (*pa++) << " ";
5283          cout << endl;
5284          } }
5285          pa=a;
5286          for (int i=0;i<n;i++)
5287          cout << mat.ni[i] << " " ;
5288          for (int i=0;i<n;i++)
5289          for (int j=0;j<n;j++,pa++)
5290          if ( mat.ni[i]==150 && mat.nj[j] == 150)
5291          cout << "a_150,150 = "<< *pa ;
5292          cout << endl;
5293          */
5294 
5295         *MeshPointStack(stack) = mp;
5296 
5297 
5298     }
5299 
5300     // creating an instance of Element_Op with MatriceElementaireSymetrique
5301     // case 3D surface
5302     // xxxxxxxxxxxxxxxxx  modif a faire
5303     template<class R>
Element_Op(MatriceElementaireSymetrique<R,FESpaceL> & mat,const FElementL & Ku,double * p,int ie,int label,void * vstack,R3 * B)5304     void  Element_Op(MatriceElementaireSymetrique<R,FESpaceL> & mat,const FElementL & Ku,double * p,int ie,int label, void * vstack,R3 *B)
5305     {
5306         ffassert(0);
5307     }
5308 
5309 
5310    //////////////////////////////////
5311    // Element_rhs
5312    //////////////////////////////////
5313 
5314     // #pragma optimization_level 0
5315     // creating an instance of Element_rhs
5316     // case 2d
5317     template<class R>
Element_rhs(const FElement & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5318     void  Element_rhs(const FElement & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5319                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5320     {
5321         Stack stack=pvoid2Stack(vstack);
5322         MeshPoint mp=*MeshPointStack(stack) ;
5323         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5324         const Triangle & T  = Kv.T;
5325         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5326         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5327         long npi;
5328         long i,n=Kv.NbDoF(),N=Kv.N;
5329 
5330         //  bool show = Kv.Vh.Th(T)==0;
5331         //  char * xxx[] ={" u"," v,"," p"," q"," r"};
5332         // char * xxxx[] ={" u'"," v',"," p'"," q'"," r'"};
5333         // char * yyy[] ={" ","_x ","_y "};
5334 
5335         bool classoptm = copt && Op.optiexpK;
5336         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5337         if (Kv.number<1  && verbosity/100 && verbosity % 10 == 2)
5338         cout << "Element_rhs S0: copt = " << copt << " " << classoptm << " opt " << optim << endl;
5339 
5340 
5341         KN<bool> Dop(last_operatortype);
5342         Op.DiffOp(Dop);
5343         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
5344         assert(Op.MaxOp() <last_operatortype);
5345 
5346         //  assert(lastop<=3);
5347 
5348 
5349         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5350 
5351         for (npi=0;npi<FI.n;npi++) // loop on the integration point
5352         {
5353             QuadraturePoint pi(FI[npi]);
5354             double coef = T.area*pi.a;
5355             R2 Pt(pi);
5356             Kv.BF(Dop,Pt,fu);
5357             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
5358             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5359             for ( i=0;  i<n;   i++ )
5360             {
5361                 RNM_ wi(fu(i,'.','.'));
5362                 int il=0;
5363                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5364                 {
5365                     LOperaD::K ll(*l);
5366                     pair<int,int> ii(ll.first);
5367                     double w_i =  wi(ii.first,ii.second);
5368                     //copt=0;
5369                     R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack)); //GetAny<double>(ll.second.eval(stack));
5370                     if ( copt && ( optim==1) && Kv.number <1)
5371                     {
5372                         R cc  =  GetAny<R>(ll.second.eval(stack));
5373                         CheckErrorOptimisation(c,cc, "Sorry error in Optimization add:  (p) int2d(Th,optimize=0)(...)" );
5374                         /*
5375                         if ( c != cc) {
5376                             cerr << c << " != " << cc << " => ";
5377                             cerr << "Sorry error in Optimization add:  (p) int2d(Th,optimize=0)(...)" << endl;
5378                             ExecError("In Optimized version "); }*/
5379                     }
5380                     //if (Kv.number<5) cout << il<< " " << i << "  c== " <<  c << endl;
5381                     R a = coef * c * w_i;
5382                     B[Kv(i)] += a;
5383                 }
5384             }
5385 
5386 
5387         }
5388         *MeshPointStack(stack) = mp;
5389 
5390 
5391     }
5392 
5393     // creating an instance of Element_rhs
5394     // case 3D volume
5395     template<class R>
Element_rhs(const FElement3 & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const GQuadratureFormular<R3> & FI=QuadratureFormular_Tet_2,int optim=1)5396     void  Element_rhs(const FElement3 & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5397                       const GQuadratureFormular<R3> & FI = QuadratureFormular_Tet_2,int optim=1)
5398     {
5399         Stack stack=pvoid2Stack(vstack);
5400         typedef  FElement3::Element Element;
5401         MeshPoint mp=*MeshPointStack(stack) ;
5402         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5403         const Element & T  = Kv.T;
5404         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5405         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5406         long npi;
5407         long i,n=Kv.NbDoF(),N=Kv.N;
5408 
5409 
5410         bool classoptm = copt && Op.optiexpK;
5411         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5412         if (Kv.number<1  && verbosity/100 && verbosity % 10 == 2)
5413         cout << "Element_rhs S0: copt = " << copt << " " << classoptm << " opt: " << optim << endl;
5414 
5415 
5416         int lastop;
5417         What_d Dop = Op.DiffOp(lastop);
5418         assert(Op.MaxOp() <last_operatortype);
5419 
5420         //  assert(lastop<=3);
5421 
5422 
5423         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5424 
5425         for (npi=0;npi<FI.n;npi++) // loop on the integration point
5426         {
5427             GQuadraturePoint<R3> pi(FI[npi]);
5428             double coef = T.mesure()*pi.a;
5429             R3 Pt(pi);
5430             Kv.BF(Dop,Pt,fu);
5431             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
5432             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5433             for ( i=0;  i<n;   i++ )
5434             {
5435                 RNM_ wi(fu(i,'.','.'));
5436                 int il=0;
5437                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5438                 {
5439                     LOperaD::K ll(*l);
5440                     pair<int,int> ii(ll.first);
5441                     double w_i =  wi(ii.first,ii.second);
5442                     //copt=0;
5443                     R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack)); //GetAny<double>(ll.second.eval(stack));
5444                     if ( copt && ( optim==1) && Kv.number <1)
5445                     {
5446                         R cc  =  GetAny<R>(ll.second.eval(stack));
5447                         CheckErrorOptimisation(c,cc,"Sorry error in Optimization (q) add:  int2d(Th,optimize=0)(...)");
5448                         /*
5449                         if ( c != cc) {
5450                             cerr << c << " != " << cc << " => ";
5451                             cerr << "Sorry error in Optimization (q) add:  int2d(Th,optimize=0)(...)" << endl;
5452                             ExecError("In Optimized version "); }*/
5453                     }
5454                     //if (Kv.number<5) cout << il<< " " << i << "  c== " <<  c << endl;
5455                     R a = coef * c * w_i;
5456                     B[Kv(i)] += a;
5457                 }
5458             }
5459 
5460 
5461         }
5462         *MeshPointStack(stack) = mp;
5463 
5464     }
5465 
5466 
5467     // creating an instance of Element_rhs
5468     // case 3D surface
5469     template<class R>
Element_rhs(const FElementS & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5470     void  Element_rhs(const FElementS & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5471                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5472     {
5473         Stack stack=pvoid2Stack(vstack);
5474         MeshPoint mp=*MeshPointStack(stack) ;
5475         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5476         const TriangleS & T  = Kv.T;
5477         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5478         //  const QuadratureFormular & FI = QuadratureFormular_T_2;
5479         long npi;
5480         long i,n=Kv.NbDoF(),N=Kv.N;
5481 
5482         //  bool show = Kv.Vh.Th(T)==0;
5483         //  char * xxx[] ={" u"," v,"," p"," q"," r"};
5484         // char * xxxx[] ={" u'"," v',"," p'"," q'"," r'"};
5485         // char * yyy[] ={" ","_x ","_y "};
5486 
5487         bool classoptm = copt && Op.optiexpK;
5488         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5489         if (Kv.number<1  && verbosity/100 && verbosity % 10 == 2)
5490             cout << "Element_rhs S0: copt = " << copt << " " << classoptm << " opt " << optim << endl;
5491 
5492         int lastop=0;
5493         What_d Dop = Op.DiffOp(lastop);
5494 
5495         //  assert(lastop<=3);
5496 
5497 
5498         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5499 
5500         for (npi=0;npi<FI.n;npi++) // loop on the integration point
5501         {
5502             QuadraturePoint pi(FI[npi]);
5503             double coef = T.mesure()*pi.a;
5504             R2 Pt(pi);
5505             Kv.BF(Dop,Pt,fu);
5506             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
5507             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5508             for ( i=0;  i<n;   i++ )
5509             {
5510                 RNM_ wi(fu(i,'.','.'));
5511                 int il=0;
5512                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5513                 {
5514                     LOperaD::K ll(*l);
5515                     pair<int,int> ii(ll.first);
5516                     double w_i =  wi(ii.first,ii.second);
5517                     //copt=0;
5518                     R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack)); //GetAny<double>(ll.second.eval(stack));
5519                     if ( copt && ( optim==1) && Kv.number <1)
5520                     {
5521                         R cc  =  GetAny<R>(ll.second.eval(stack));
5522                         CheckErrorOptimisation(c,cc,"Sorry error in Optimization Element_OpVF2d  (b) add:  int2d(Th,optimize=0)(...)");
5523                         /*
5524                         if ( c != cc) {
5525                             cerr << c << " != " << cc << " => ";
5526                             cerr << "Sorry error in Optimization add:  (p) int2d(Th,optimize=0)(...)" << endl;
5527                             ExecError("In Optimized version "); }*/
5528                     }
5529                     //if (Kv.number<5) cout << il<< " " << i << "  c== " <<  c << endl;
5530                     R a = coef * c * w_i;
5531                     B[Kv(i)] += a;
5532                 }
5533             }
5534 
5535 
5536         }
5537         *MeshPointStack(stack) = mp;
5538     }
5539 
5540     // case 3D curve
5541     template<class R>
Element_rhs(const FElementL & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const GQuadratureFormular<R1> & FI=QF_GaussLegendre2,int optim=1)5542     void  Element_rhs(const FElementL & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5543                       const GQuadratureFormular<R1> & FI = QF_GaussLegendre2,int optim=1)
5544     {
5545         Stack stack=pvoid2Stack(vstack);
5546         MeshPoint mp=*MeshPointStack(stack) ;
5547         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5548         const EdgeL & T  = Kv.T;
5549         long npi;
5550         long i,n=Kv.NbDoF(),N=Kv.N;
5551 
5552         bool classoptm = copt && Op.optiexpK;
5553         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5554         if (Kv.number<1  && verbosity/100 && verbosity % 10 == 2)
5555             cout << "Element_rhs S0: copt = " << copt << " " << classoptm << " opt " << optim << endl;
5556 
5557         int lastop=0;
5558         What_d Dop = Op.DiffOp(lastop);
5559 
5560         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5561 
5562         for (npi=0;npi<FI.n;npi++) // loop on the integration point
5563         {
5564             GQuadraturePoint<R1> pi(FI[npi]);
5565             double coef = T.mesure()*pi.a;
5566             R1 Pt(pi);
5567             Kv.BF(Dop,Pt,fu);
5568             MeshPointStack(stack)->set(T(Pt),Pt,Kv);
5569             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5570             for ( i=0;  i<n;   i++ )
5571             {
5572                 RNM_ wi(fu(i,'.','.'));
5573                 int il=0;
5574                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5575                 {
5576                     LOperaD::K ll(*l);
5577                     pair<int,int> ii(ll.first);
5578                     double w_i =  wi(ii.first,ii.second);
5579                     //copt=0;
5580                     R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack)); //GetAny<double>(ll.second.eval(stack));
5581                     if ( copt && ( optim==1) && Kv.number <1)
5582                     {
5583                         R cc  =  GetAny<R>(ll.second.eval(stack));
5584                         CheckErrorOptimisation(c,cc,"Sorry error in Optimization Element_OpVF3dcurve  (b) add:  int2d(Th,optimize=0)(...)");
5585                     }
5586                     R a = coef * c * w_i;
5587                     B[Kv(i)] += a;
5588                 }
5589             }
5590 
5591 
5592         }
5593         *MeshPointStack(stack) = mp;
5594     }
5595 
5596     // #pragma optimization_level 0
5597 
5598     // creating an instance of Element_rhs
5599     // case 2d
5600     template<class R>
Element_rhs(const Mesh & ThI,const Triangle & KI,const FESpace & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5601     void  Element_rhs(const  Mesh & ThI,const Triangle & KI,
5602                       const FESpace & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5603                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5604     {
5605         Stack stack=pvoid2Stack(vstack);
5606         MeshPoint mp=*MeshPointStack(stack) ;
5607         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5608         //    int maxd = Op.MaxOp();
5609         //    assert(maxd<last_operatortype);
5610         const Triangle * Kp=0;
5611 
5612         bool classoptm = copt && Op.optiexpK;
5613         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5614         if (ThI(KI)<1 && verbosity/100 && verbosity % 10 == 2)
5615 
5616         cout << "Element_rhs 3: copt = " << copt << " " << classoptm <<" opt " << optim<< endl;
5617 
5618         KN<bool> Dop(last_operatortype);
5619         Op.DiffOp(Dop);
5620         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
5621         assert(Op.MaxOp() <last_operatortype);
5622 
5623         // assert(lastop<=3);
5624 
5625         for (long npi=0;npi<FI.n;npi++) // loop on the integration point
5626         {
5627             QuadraturePoint pi(FI[npi]);
5628             R2 PI(KI(pi));
5629             double coef = KI.area*pi.a;
5630             MeshPointStack(stack)->set(ThI,PI,pi,KI,KI.lab);
5631             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5632             bool outside;
5633             R2 Pt;
5634             const Triangle & K  = *Vh.Th.Find(PI,Pt,outside,Kp);
5635             if ( ! outside)
5636             {
5637                 const  FElement  Kv= Vh[K];
5638                 long i,n=Kv.NbDoF(),N=Kv.N;
5639                 RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5640                 Kv.BF(Dop,Pt,fu);
5641 
5642                 for ( i=0;  i<n;   i++ )
5643                 {
5644                     RNM_ wi(fu(i,'.','.'));
5645                     int il=0;
5646                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5647                     {
5648                         LOperaD::K ll(*l);
5649                         pair<int,int> ii(ll.first);
5650 
5651                         double w_i =  wi(ii.first,ii.second);
5652 
5653                         R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));;//GetAny<double>(ll.second.eval(stack));
5654                         if ( copt && ThI(KI) <1)
5655                         {
5656                             R cc  =  GetAny<R>(ll.second.eval(stack));
5657                             CheckErrorOptimisation(c,cc,"Sorry error in Optimization (s) add:  int2d(Th,optimize=0)(...)");
5658                             /*
5659                             if ( c != cc) {
5660                                 cerr << c << " != " << cc << " => ";
5661                                 cerr << "Sorry error in Optimization (s) add:  int2d(Th,optimize=0)(...)" << endl;
5662                                 ExecError("In Optimized version "); }*/
5663                         }
5664 
5665                         R a = coef * c * w_i;
5666                         B[Kv(i)] += a;
5667                     }
5668                 }
5669             }
5670             Kp = & K;
5671         }
5672         *MeshPointStack(stack) = mp;
5673 
5674 
5675     }
5676 
5677 
5678     // creating an instance of Element_rhs
5679     // case 3D volume
5680     template<class R>
Element_rhs(const Mesh3 & ThI,const Mesh3::Element & KI,const FESpace3 & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const GQuadratureFormular<R3> & FI,int optim)5681     void  Element_rhs(const  Mesh3 & ThI,const Mesh3::Element & KI,
5682                       const FESpace3 & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5683                       const GQuadratureFormular<R3> & FI,int optim)
5684     {
5685         Stack stack=pvoid2Stack(vstack);
5686         // AFAIRE("Element_rhs 3d diff meshes");
5687         static int count=0;
5688         if(count++<1)
5689         {
5690             cout << "Warning:  Element_rhs 3 3d diff meshes in test (FH) " << endl;
5691             cout << "--------------------------------------------------- " << endl;
5692         }
5693         MeshPoint mp=*MeshPointStack(stack) ;
5694         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5695         //    int maxd = Op.MaxOp();
5696         //    assert(maxd<last_operatortype);
5697         const Tet * Kp=0;
5698 
5699         bool classoptm = copt && Op.optiexpK;
5700         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5701         if (ThI(KI)<1 && verbosity/100 && verbosity % 10 == 2)
5702 
5703         cout << "Element_rhs 3d  3: copt = " << copt << " " << classoptm <<" opt " <<optim << endl;
5704 
5705         assert(Op.MaxOp() <last_operatortype);
5706         //
5707         int lastop=0;
5708         lastop = 0;
5709         What_d Dop = Op.DiffOp(lastop);
5710         assert(Op.MaxOp() <last_operatortype);
5711 
5712         // assert(lastop<=3);
5713 
5714         for (long npi=0;npi<FI.n;npi++) // loop on the integration point
5715         {
5716             GQuadraturePoint<R3> pi(FI[npi]);
5717             R3 PI(KI(pi));
5718             double coef = KI.mesure()*pi.a;
5719             MeshPointStack(stack)->set(ThI,PI,pi,KI,KI.lab);
5720             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5721             bool outside;
5722             R3 Pt;
5723             const Tet & K  = *Vh.Th.Find(PI,Pt,outside,Kp);
5724             if ( ! outside)
5725             {
5726                 const  FElement3  Kv= Vh[K];
5727                 long i,n=Kv.NbDoF(),N=Kv.N;
5728                 RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5729                 Kv.BF(Dop,Pt,fu);
5730 
5731                 for ( i=0;  i<n;   i++ )
5732                 {
5733                     RNM_ wi(fu(i,'.','.'));
5734                     int il=0;
5735                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5736                     {
5737                         LOperaD::K ll(*l);
5738                         pair<int,int> ii(ll.first);
5739 
5740                         double w_i =  wi(ii.first,ii.second);
5741 
5742                         R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));;//GetAny<double>(ll.second.eval(stack));
5743                         if ( copt && ThI(KI) <1 && optim==1)
5744                         {
5745                             R cc  =  GetAny<R>(ll.second.eval(stack));
5746                             if ( c != cc) {
5747                                 cerr << c << " != " << cc << " => ";
5748                                 cerr << "Sorry error in Optimization (r) add:  int2d(Th,optimize=0)(...)" << endl;
5749                                 ExecError("In Optimized version "); }
5750                         }
5751 
5752                         R a = coef * c * w_i;
5753                         B[Kv(i)] += a;
5754                     }
5755                 }
5756             }
5757             Kp = & K;
5758         }
5759         *MeshPointStack(stack) = mp;
5760 
5761 
5762     }
5763 
5764     // creating an instance of Element_rhs
5765     // case 3D surface
5766     template<class R>
Element_rhs(const MeshS & ThI,const TriangleS & KI,const FESpaceS & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5767     void  Element_rhs(const  MeshS & ThI,const TriangleS & KI,
5768                       const FESpaceS & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5769                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5770     {
5771         ffassert(0);
5772     }
5773 
5774     // creating an instance of Element_rhs
5775     // case 3D curve
5776     template<class R>
Element_rhs(const MeshL & ThI,const EdgeL & KI,const FESpaceL & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const GQuadratureFormular<R1> & FI=QF_GaussLegendre2,int optim=1)5777     void  Element_rhs(const  MeshL & ThI,const EdgeL & KI,
5778                       const FESpaceL & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5779                       const GQuadratureFormular<R1> & FI = QF_GaussLegendre2,int optim=1)
5780     {
5781         ffassert(0);
5782     }
5783 
5784     // creating an instance of Element_rhs
5785     // case 2d
5786     template<class R>
Element_rhs(Expression const * const mapt,const Mesh & ThI,const Triangle & KI,const FESpace & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5787     void  Element_rhs(Expression const * const mapt,const  Mesh & ThI,const Triangle & KI,
5788                       const FESpace & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5789                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5790     {
5791 
5792         Stack stack=pvoid2Stack(vstack);
5793         MeshPoint mp=*MeshPointStack(stack) ;
5794         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5795         //    int maxd = Op.MaxOp();
5796         //    assert(maxd<last_operatortype);
5797         const Triangle * Kp=0;
5798 
5799         bool classoptm = copt && Op.optiexpK;
5800         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5801         if (ThI(KI)<1 && verbosity/100 && verbosity % 10 == 2)
5802 
5803         cout << "Element_rhs 3: copt = " << copt << " " << classoptm <<" opt " << optim<< endl;
5804 
5805         KN<bool> Dop(last_operatortype);
5806         Op.DiffOp(Dop);
5807         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
5808         assert(Op.MaxOp() <last_operatortype);
5809 
5810         // assert(lastop<=3);
5811 
5812         for (long npi=0;npi<FI.n;npi++) // loop on the integration point
5813         {
5814             QuadraturePoint pi(FI[npi]);
5815             R2 PIo(KI(pi)),PI(PIo);
5816             double coef = KI.area*pi.a;
5817             MeshPointStack(stack)->set(ThI,PI,pi,KI,KI.lab);
5818             if(mapt)
5819             { // move poit
5820                 PI= R2( GetAny<double>((*mapt[0])(vstack)), GetAny<double>((*mapt[1])(vstack)));
5821                 if(verbosity>9999) cout << "  Element_rhs mapt =" << PIo << " -> " <<PI << endl;
5822             }
5823             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5824             bool outside;
5825             R2 Pt;
5826             const Triangle & K  = *Vh.Th.Find(PI,Pt,outside,Kp);
5827             if ( ! outside)
5828             {
5829                 const  FElement  Kv= Vh[K];
5830                 long i,n=Kv.NbDoF(),N=Kv.N;
5831                 RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5832                 Kv.BF(Dop,Pt,fu);
5833 
5834                 for ( i=0;  i<n;   i++ )
5835                 {
5836                     RNM_ wi(fu(i,'.','.'));
5837                     int il=0;
5838                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5839                     {
5840                         LOperaD::K ll(*l);
5841                         pair<int,int> ii(ll.first);
5842 
5843                         double w_i =  wi(ii.first,ii.second);
5844 
5845                         R c = copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));;//GetAny<double>(ll.second.eval(stack));
5846                         if ( copt && ThI(KI) <1)
5847                         {
5848                             R cc  =  GetAny<R>(ll.second.eval(stack));
5849                             if ( c != cc) {
5850                                 cerr << c << " != " << cc << " => ";
5851                                 cerr << "Sorry error in Optimization (s) add:  int2d(Th,optimize=0)(...)" << endl;
5852                                 ExecError("In Optimized version "); }
5853                         }
5854 
5855                         R a = coef * c * w_i;
5856                         B[Kv(i)] += a;
5857                     }
5858                 }
5859             }
5860             Kp = & K;
5861         }
5862         *MeshPointStack(stack) = mp;
5863 
5864 
5865     }
5866     // creating an instance of Element_rhs
5867     // case 3D volume
5868     template<class R>
Element_rhs(const FElement3 & Kv,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI,bool alledges=false,int optim=1)5869     void  Element_rhs(const FElement3 & Kv,int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5870                       const QuadratureFormular & FI ,bool alledges=false,int optim=1)
5871     {
5872         //   AFAIRE("Element_rhs on border");
5873         Stack stack=pvoid2Stack(vstack);
5874         typedef  FElement3::Element Element;
5875         MeshPoint mp=*MeshPointStack(stack) ;
5876         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5877         const Element & T  = Kv.T;
5878         long npi;
5879         long i,n=Kv.NbDoF(),N=Kv.N;
5880 
5881         bool classoptm = copt && Op.optiexpK;
5882         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5883         if (Kv.number<1 && verbosity/100 && verbosity % 10 == 2)
5884         cout << "Element_rhs 3d S: copt = " << copt << " " << classoptm <<" opt " << optim << endl;
5885         int lastop;
5886         What_d Dop = Op.DiffOp(lastop);
5887 
5888         assert(Op.MaxOp() <last_operatortype);
5889         // assert(lastop<=3);
5890 
5891         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5892 
5893         for (npi=0;npi<FI.n;npi++) // loop on the integration point
5894         {
5895             GQuadraturePoint<R2> pi( FI[npi]);
5896             R3 NN=T.N(ie);
5897             double le= NN.norme();
5898             NN /= le;
5899             double coef = le*pi.a*0.5;// correction 050109 FH
5900             R3 Pt(T.PBord(ie,pi));
5901             //
5902             Kv.BF(Dop,Pt,fu);
5903             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label,NN,ie);
5904             if (classoptm) (*Op.optiexpK)(stack); // call optim version
5905 
5906             for ( i=0;  i<n;   i++ )
5907             // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
5908             {
5909                 RNM_ wi(fu(i,'.','.'));
5910                 int il=0;
5911                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
5912                 {
5913                     LOperaD::K ll(*l);
5914                     pair<int,int> ii(ll.first);
5915                     double w_i =  wi(ii.first,ii.second);
5916                     R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
5917                     // FFCS - removing what is probably a small glitch
5918                     if ( copt && ( optim==1) && Kv.number<1)
5919                     {
5920                         R cc  =  GetAny<R>(ll.second.eval(stack));
5921                         if ( c != cc) {
5922                             cerr << c << " =! " << cc << endl;
5923                             cerr << "Sorry error in Optimization (t) add:  int2d(Th,optimize=0)(...)" << endl;
5924                             ExecError("In Optimized version "); }
5925                     }
5926 
5927 
5928                     //= GetAny<double>(ll.second.eval(stack));
5929 
5930                     B[Kv(i)] += coef * c * w_i;
5931                 }
5932             }
5933 
5934 
5935         }
5936         *MeshPointStack(stack) = mp;
5937 
5938     }
5939 
5940     // creating an instance of Element_rhs
5941     // case 3D surface
5942     template<class R>
Element_rhs(Expression const * const mapt,const MeshS & ThI,const TriangleS & KI,const FESpaceS & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5943     void  Element_rhs(Expression const * const mapt,const  MeshS & ThI,const TriangleS & KI,
5944                       const FESpaceS & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5945                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5946     {
5947         ffassert(0);
5948     }
5949     // creating an instance of Element_rhs
5950     // case 3D curve
5951     template<class R>
Element_rhs(Expression const * const mapt,const MeshL & ThI,const EdgeL & KI,const FESpaceL & Vh,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI=QuadratureFormular_T_2,int optim=1)5952     void  Element_rhs(Expression const * const mapt,const  MeshL & ThI,const EdgeL & KI,
5953                       const FESpaceL & Vh,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5954                       const QuadratureFormular & FI = QuadratureFormular_T_2,int optim=1)
5955     {
5956         ffassert(0);
5957     }
5958 
5959 
5960     // creating an instance of Element_rhs
5961     // case 2d
5962     template<class R>
Element_rhs(const FElement & Kv,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,int optim=1)5963     void  Element_rhs(const FElement & Kv,int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
5964                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,int optim=1)
5965     {
5966         Stack stack=pvoid2Stack(vstack);
5967         MeshPoint mp=*MeshPointStack(stack) ;
5968         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
5969         const Triangle & T  = Kv.T;
5970         // const QuadratureFormular1d & FI = QF_GaussLegendre2;
5971         long npi;
5972         long i,n=Kv.NbDoF(),N=Kv.N;
5973 
5974         //  bool show = Kv.Vh.Th(T)==0;
5975         // char * xxx[] ={" u"," v,"," p"," q"," r"};
5976         // char * xxxx[] ={" u'"," v',"," p'"," q'"," r'"};
5977         // char * yyy[] ={" ","_x ","_y "};
5978 
5979         bool classoptm = copt && Op.optiexpK;
5980         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
5981         if (Kv.number<1 && verbosity/100 && verbosity % 10 == 2)
5982         cout << "Element_rhs S: copt = " << copt << " " << classoptm << "opt " << optim << endl;
5983         KN<bool> Dop(last_operatortype);
5984         Op.DiffOp(Dop);
5985         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
5986         assert(Op.MaxOp() <last_operatortype);
5987         // assert(lastop<=3);
5988 
5989         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
5990 
5991         for (npi=0;npi<FI.n;npi++) // loop on the integration point
5992         {
5993             QuadratureFormular1dPoint pi( FI[npi]);
5994             R2 E=T.Edge(ie);
5995             double le = sqrt((E,E));
5996             double coef = le*pi.a;
5997             double sa=pi.x,sb=1-sa;
5998             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
5999             PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
6000             R2 Pt(PA*sa+PB*sb ); //
6001             Kv.BF(Dop,Pt,fu);
6002             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label,R2(E.y,-E.x)/le,ie);
6003             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6004 
6005             for ( i=0;  i<n;   i++ )
6006             // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6007             {
6008                 RNM_ wi(fu(i,'.','.'));
6009                 int il=0;
6010                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6011                 {
6012                     LOperaD::K ll(*l);
6013                     pair<int,int> ii(ll.first);
6014                     double w_i =  wi(ii.first,ii.second);
6015                     R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6016                     // FFCS - removing what is probably a small glitch
6017                     if ( copt && ( optim==1) && Kv.number<1)
6018                     {
6019                         R cc  =  GetAny<R>(ll.second.eval(stack));
6020                         if ( c != cc) {
6021                             cerr << c << " =! " << cc << endl;
6022                             cerr << "Sorry error in Optimization (v) add:  int2d(Th,optimize=0)(...)" << endl;
6023                             ExecError("In Optimized version "); }
6024                     }
6025 
6026 
6027                     //= GetAny<double>(ll.second.eval(stack));
6028 
6029                     B[Kv(i)] += coef * c * w_i;
6030                 }
6031             }
6032 
6033 
6034         }
6035         *MeshPointStack(stack) = mp;
6036 
6037     }
6038 
6039 
6040     // creating an instance of Element_rhs
6041     // case 3D volume isoline ... levelset ...
6042     template<class R>
Element_rhs(const FElement3 & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI,int np,R3 * Q,int optim)6043     void  Element_rhs(const FElement3 & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6044                       const QuadratureFormular & FI ,int np, R3 *Q,int optim)
6045     {
6046         //   AFAIRE("Element_rhs on border");
6047         Stack stack=pvoid2Stack(vstack);
6048         typedef  FElement3::Element Element;
6049 
6050         MeshPoint mp=*MeshPointStack(stack) ;
6051         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6052         const Element & K  = Kv.T;
6053         const Mesh3 & Th= Kv.Vh.Th;
6054         double epsmes3=K.mesure()*K.mesure()*1e-18;
6055         long npi;
6056         long n=Kv.NbDoF(),N=Kv.N;
6057         double l[3];
6058 
6059         bool classoptm = copt && Op.optiexpK;
6060         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6061         if (Kv.number<1 && verbosity/100 && verbosity % 10 == 2)
6062         cout << "Element_rhs 3d S(levelset): copt = " << copt << " " << classoptm << " opt " << optim << endl;
6063         int lastop;
6064         What_d Dop = Op.DiffOp(lastop);
6065 
6066         assert(Op.MaxOp() <last_operatortype);
6067         // assert(lastop<=3);
6068 
6069         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
6070         R3 PP[4];
6071         for(int i=0; i< np; ++i)
6072         PP[i]= K(Q[i]);
6073 
6074         for( int iii =0; iii+1 < np; iii+=2)
6075         { // 0,1,, a and 2,3,0.
6076             int i0=iii,i1=iii+1,i2=(iii+2)%np;
6077             R3 NN= R3(PP[i0],PP[i1])^R3(PP[i0],PP[i2]);
6078             double mes2 = (NN,NN);
6079             double mes = sqrt(mes2);
6080             if(mes2*mes <epsmes3) continue; //  too small
6081             NN /= mes;
6082             mes *= 0.5;
6083             // cout << " Element_rhs::mes " << mes << " " << iii << endl;
6084 
6085             for (npi=0;npi<FI.n;npi++) // loop on the integration point
6086             {
6087                 GQuadraturePoint<R2>  pi( FI[npi]);
6088                 pi.toBary(l);
6089                 R3 Pt( l[0]*Q[i0]+l[1]*Q[i1]+l[2]*Q[i2]); //
6090                 MeshPointStack(stack)->set(Th,K(Pt),Pt,K,-1,NN,-1);
6091                 //
6092                 Kv.BF(Dop,Pt,fu);
6093                 //        MeshPointStack(stack)->set(K(Pt),Pt,Kv,label,NN,ie);
6094                 if (classoptm) (*Op.optiexpK)(stack); // call optim version
6095                 double coef = mes*pi.a;
6096                 for (int  i=0;  i<n;   i++ )
6097                 // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6098                 {
6099                     RNM_ wi(fu(i,'.','.'));
6100                     int il=0;
6101                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6102                     {
6103                         LOperaD::K ll(*l);
6104                         pair<int,int> ii(ll.first);
6105                         double w_i =  wi(ii.first,ii.second);
6106                         R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6107                         // FFCS - removing what is probably a small glitch
6108                         if ( copt && ( optim==1) && Kv.number<1)
6109                         {
6110                             R cc  =  GetAny<R>(ll.second.eval(stack));
6111                             if ( c != cc) {
6112                                 cerr << c << " =! " << cc << endl;
6113                                 cerr << "Sorry error in Optimization (u) add:  int2d(Th,optimize=0)(...)" << endl;
6114                                 ExecError("In Optimized version "); }
6115                         }
6116 
6117 
6118                         //= GetAny<double>(ll.second.eval(stack));
6119 
6120                         B[Kv(i)] += coef * c * w_i;
6121                     }
6122                 }
6123 
6124 
6125             }
6126         }
6127         *MeshPointStack(stack) = mp;
6128 
6129     }
6130 
6131     // creating an instance of Element_rhs
6132     // case 3D surface
6133     template<class R>
Element_rhs(const FElementS & Kv,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,int optim=1)6134     void  Element_rhs(const FElementS & Kv,int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6135                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,int optim=1)
6136     {
6137         Stack stack=pvoid2Stack(vstack);
6138         MeshPoint mp=*MeshPointStack(stack) ;
6139         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6140         const TriangleS & T  = Kv.T;
6141         // const QuadratureFormular1d & FI = QF_GaussLegendre2;
6142         long npi;
6143         long i,n=Kv.NbDoF(),N=Kv.N;
6144 
6145         //  bool show = Kv.Vh.Th(T)==0;
6146         // char * xxx[] ={" u"," v,"," p"," q"," r"};
6147         // char * xxxx[] ={" u'"," v',"," p'"," q'"," r'"};
6148         // char * yyy[] ={" ","_x ","_y "};
6149 
6150         bool classoptm = copt && Op.optiexpK;
6151         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6152         if (Kv.number<1 && verbosity/100 && verbosity % 10 == 2)
6153             cout << "Element_rhs S: copt = " << copt << " " << classoptm << "opt " << optim << endl;
6154 
6155         int lastop=0;
6156         What_d Dop = Op.DiffOp(lastop);
6157         assert(Op.MaxOp() <last_operatortype);
6158 
6159         // assert(lastop<=3);
6160 
6161         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
6162 
6163         for (npi=0;npi<FI.n;npi++) // loop on the integration point
6164         {
6165             QuadratureFormular1dPoint pi( FI[npi]);
6166             R3 E=T.Edge(ie);
6167             double le = sqrt((E,E));
6168             double coef = le*pi.a;
6169             double sa=pi.x,sb=1-sa;
6170             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
6171             PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
6172             R2 Pt(PA*sa+PB*sb );
6173             Kv.BF(Dop,Pt,fu);
6174             // surface normal
6175             R3 NNt=T.NFrenetUnitaire();
6176             // exterior normal (flux)
6177             R3 NN=T.N(ie);
6178             NN /= NN.norme();
6179             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label,NN,NNt,ie);
6180             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6181 
6182             for ( i=0;  i<n;   i++ )
6183                 // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6184             {
6185                 RNM_ wi(fu(i,'.','.'));
6186                 int il=0;
6187                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6188                 {
6189                     LOperaD::K ll(*l);
6190                     pair<int,int> ii(ll.first);
6191                     double w_i =  wi(ii.first,ii.second);
6192                     R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6193                     // FFCS - removing what is probably a small glitch
6194                     if ( copt && ( optim==1) && Kv.number<1)
6195                     {
6196                         R cc  =  GetAny<R>(ll.second.eval(stack));
6197                         if ( c != cc) {
6198                             cerr << c << " =! " << cc << endl;
6199                             cerr << "Sorry error in Optimization (v) add:  int2d(Th,optimize=0)(...)" << endl;
6200                             ExecError("In Optimized version "); }
6201                     }
6202 
6203 
6204                     //= GetAny<double>(ll.second.eval(stack));
6205 
6206                     B[Kv(i)] += coef * c * w_i;
6207                 }
6208             }
6209 
6210 
6211         }
6212         *MeshPointStack(stack) = mp;
6213     }
6214 
6215     // creating an instance of Element_rhs
6216     // case 3D curve
6217     template<class R>
Element_rhs(const FElementL & Kv,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,int optim=1)6218     void  Element_rhs(const FElementL & Kv,int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6219                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,int optim=1)
6220     {
6221         ffassert(0);
6222     }
6223 
6224 
6225     // end 3d
6226 
6227 
6228     // creating an instance of Element_rhs
6229     // case 2d
6230     template<class R>
Element_rhs(const FElement & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI,const R2 & PPA,const R2 & PPB,int optim)6231     void  Element_rhs(const FElement & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6232                       const QuadratureFormular1d & FI ,const R2 & PPA,const R2 &PPB,int optim)
6233     {
6234         Stack stack=pvoid2Stack(vstack);
6235         MeshPoint mp=*MeshPointStack(stack) ;
6236         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6237         const Triangle & T  = Kv.T;
6238         R2 PA=T(PPA),PB=T(PPB);
6239         // const QuadratureFormular1d & FI = QF_GaussLegendre2;
6240         long npi;
6241         long i,n=Kv.NbDoF(),N=Kv.N;
6242 
6243         //  bool show = Kv.Vh.Th(T)==0;
6244         // char * xxx[] ={" u"," v,"," p"," q"," r"};
6245         // char * xxxx[] ={" u'"," v',"," p'"," q'"," r'"};
6246         // char * yyy[] ={" ","_x ","_y "};
6247 
6248         bool classoptm = copt && Op.optiexpK;
6249         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6250         if (Kv.number<1 && verbosity/100 && verbosity % 10 == 2)
6251         cout << "Element_rhs(levelset) S: copt = " << copt << " " << classoptm <<" opt " << optim << endl;
6252         KN<bool> Dop(last_operatortype);
6253         Op.DiffOp(Dop);
6254         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
6255         assert(Op.MaxOp() <last_operatortype);
6256         // assert(lastop<=3);
6257 
6258         RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
6259 
6260         R2 E(PA,PB);
6261         double le = sqrt((E,E));
6262 
6263         //cout << " Element_rhs 2d " << PA << " " << PB << " " << le << " " << Kv.number <<  endl;
6264         for (npi=0;npi<FI.n;npi++) // loop on the integration point
6265         {
6266             QuadratureFormular1dPoint pi( FI[npi]);
6267             double coef = le*pi.a;
6268             double sa=pi.x,sb=1-sa;
6269             R2 Pt(PPA*sa+PPB*sb ); //
6270             Kv.BF(Dop,Pt,fu);
6271             MeshPointStack(stack)->set(T(Pt),Pt,Kv,0,R2(E.y,-E.x)/le,0);
6272             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6273 
6274             for ( i=0;  i<n;   i++ )
6275             // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6276             {
6277                 RNM_ wi(fu(i,'.','.'));
6278                 int il=0;
6279                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6280                 {
6281                     LOperaD::K ll(*l);
6282                     pair<int,int> ii(ll.first);
6283                     double w_i =  wi(ii.first,ii.second);
6284                     R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6285                     // FFCS - removing what is probably a small glitch
6286                     if ( copt && ( optim==1) && Kv.number<1)
6287                     {
6288                         R cc  =  GetAny<R>(ll.second.eval(stack));
6289                         if ( c != cc) {
6290                             cerr << c << " =! " << cc << endl;
6291                             cerr << "Sorry error in Optimization (w)  add:  int2d(Th,optimize=0)(...)" << endl;
6292                             ExecError("In Optimized version "); }
6293                     }
6294 
6295 
6296                     //= GetAny<double>(ll.second.eval(stack));
6297                   //  cout << "         " << coef<< " " << c << " " << w_i << " " << Kv(i) << " | " << Pt <<  endl;
6298                     B[Kv(i)] += coef * c * w_i;
6299                 }
6300             }
6301 
6302 
6303         }
6304         *MeshPointStack(stack) = mp;
6305 
6306     }
6307 
6308 
6309     // case 3D surface
6310     template<class R>
Element_rhs(const FElementS & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI,const R3 & PPA,const R3 & PPB,int optim)6311     void  Element_rhs(const FElementS & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6312                       const QuadratureFormular1d & FI ,const R3 & PPA,const R3 &PPB,int optim)
6313     {
6314         ffassert(0);
6315     }
6316 
6317     // case 3D curve
6318     template<class R>
Element_rhs(const FElementL & Kv,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI,const R3 & PPA,const R3 & PPB,int optim)6319     void  Element_rhs(const FElementL & Kv,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6320                       const QuadratureFormular1d & FI ,const R3 & PPA,const R3 &PPB,int optim)
6321     {
6322         ffassert(0);
6323     }
6324 
6325 
6326 
6327     // creating an instance of Element_rhsVF
6328     // case 2d
6329     template<class R>
Element_rhsVF(const FElement & Kv,const FElement & KKv,int ie,int iie,int label,const LOperaD & Op,double * p,int * ip,void * bstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,int optim=1)6330     void  Element_rhsVF(const FElement & Kv,const FElement & KKv,int ie,int iie,int label,const LOperaD &Op,double * p,int *ip,void  * bstack,KN_<R> & B,
6331                         const QuadratureFormular1d & FI = QF_GaussLegendre2,int optim=1)
6332     // sier of ip
6333     //  version correct the  29 april 2015 by. FH
6334     //  missing before in case of jump, mean , .. in test functions
6335     //  Thank to Lucas Franceschini <lucas.franceschini@ensta-paristech.fr>
6336     {
6337         pair_stack_double * bs=static_cast<pair_stack_double *>(bstack);
6338         Stack stack= bs->first;
6339         double binside = *bs->second; // truc FH pour fluide de grad2 (decentrage bizard)
6340         bool onborder= &Kv.T == &KKv.T;
6341         const FElement *pKKv= !onborder ?  & KKv : 0;
6342         MeshPoint mp=*MeshPointStack(stack) ;
6343         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6344         const Triangle & T  = Kv.T;
6345         // const QuadratureFormular1d & FI = QF_GaussLegendre2;
6346         long npi;
6347         long i,nv=Kv.NbDoF(),N=Kv.N;
6348         long nnv=KKv.NbDoF();
6349         assert(nv==nnv);
6350         //  bool show = Kv.Vh.Th(T)==0;
6351         // char * xxx[] ={" u"," v,"," p"," q"," r"};
6352         // char * xxxx[] ={" u'"," v',"," p'"," q'"," r'"};
6353         // char * yyy[] ={" ","_x ","_y "};
6354 
6355         bool classoptm = copt && Op.optiexpK;
6356         // assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6357         if (Kv.number<1 && verbosity/100 && verbosity % 10 == 2)
6358         cout << "Element_rhs S: copt = " << copt << " " << classoptm << " opt " << optim << endl;
6359         KN<bool> Dop(last_operatortype);
6360         Op.DiffOp(Dop);
6361         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
6362         //assert(Op.MaxOp() <last_operatortype);
6363         // assert(lastop<=3);
6364         int lffv = nv*N*last_operatortype;
6365         int lp =nv*2;
6366         KN_<int> pp(ip,lp),pk(ip+lp,lp),pkk(ip+2*lp,lp);
6367         int n = BuildMEK_KK(lp,pp,pk,pkk,&Kv,pKKv);
6368         RNMK_ fu(p,nv,N,lastop); //  the value for basic fonction
6369         RNMK_ ffu( (double*) p  + lffv  ,nv,N,lastop); //  the value for basic fonction
6370 
6371         R2 E=T.Edge(ie);
6372         double le = sqrt((E,E));
6373         R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
6374         PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]),
6375         PC(TriangleHat[OppositeVertex[ie]]);
6376         // warning the to edge are in opposite sens
6377         R2 PP_A(TriangleHat[VerticesOfTriangularEdge[iie][1]]),
6378         PP_B(TriangleHat[VerticesOfTriangularEdge[iie][0]]),
6379         PP_C(TriangleHat[OppositeVertex[ie]]);
6380         R2 Normal(E.perp()/-le);
6381         double cmean = onborder ? 1. : 0.5;
6382         for (npi=0;npi<FI.n;npi++) // loop on the integration point
6383         {
6384             QuadratureFormular1dPoint pi( FI[npi]);
6385             R2 E=T.Edge(ie);
6386             double le = sqrt((E,E));
6387             double coef = le*pi.a;
6388             double sa=pi.x,sb=1-sa;
6389             R2 PA(TriangleHat[VerticesOfTriangularEdge[ie][0]]),
6390             PB(TriangleHat[VerticesOfTriangularEdge[ie][1]]);
6391             R2 Pt(PA*sa+PB*sb ); //
6392             R2 PP_t(PP_A*sa+PP_B*sb ); //
6393             if (binside) {
6394                 Pt   = (1-binside)*Pt + binside*PC;
6395                 PP_t  = (1-binside)*PP_t + binside*PP_C; }
6396             Kv.BF(Dop,Pt,fu);
6397             if(onborder)
6398             ffu=0;
6399             else
6400             KKv.BF(Dop,PP_t,ffu);
6401 
6402             MeshPointStack(stack)->set(T(Pt),Pt,Kv,label,R2(E.y,-E.x)/le,ie);
6403             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6404 
6405             for ( i=0;  i<n;   i++ )
6406             // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6407             {
6408                 int ik= pk[i];
6409                 int ikk=pkk[i];
6410 
6411                 RNM_ wi(fu(Max(ik,0),'.','.'));
6412                 RNM_ wwi(ffu(Max(ikk,0),'.','.'));
6413                 int il=0;
6414                 int dofik=ik>=0? Kv(ik):-1;
6415                 int dofikk=ikk>=0? KKv(ikk):-1;
6416 
6417                 for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6418                 {
6419 
6420 
6421                     LOperaD::K ll(*l);
6422                     pair<int,int> ii(ll.first);
6423                     int iis = ii.second;
6424                     int iicase  = iis / last_operatortype;
6425                     iis %= last_operatortype;
6426                     double w_i=0,ww_i=0;
6427                     if(ik>=0) w_i =   wi(ii.first,iis );
6428                     if( iicase>0 )
6429                     {
6430                         if( ikk>=0) ww_i =  wwi(ii.first,iis );
6431                         if       (iicase==Code_Jump)      w_i = -w_i; ///(w_i = ww_i-w_i); // jump
6432                         else  if (iicase==Code_Mean)      ww_i=w_i = cmean*  (w_i + ww_i ); // average
6433                         else  if (iicase==Code_OtherSide) std::swap(w_i,ww_i);  // valeur de autre cote
6434                         else ffassert(0);
6435                     }
6436                     R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6437                     // FFCS - removing what is probably a small glitch
6438                     if ( copt && ( optim==1) && Kv.number<1)
6439                     {
6440                         R cc  =  GetAny<R>(ll.second.eval(stack));
6441                         if ( c != cc) {
6442                             cerr << c << " =! " << cc << endl;
6443                             cerr << "Sorry error in Optimization (x) add:  int2d(Th,optimize=0)(...)" << endl;
6444                             ExecError("In Optimized version "); }
6445                     }
6446 
6447 
6448                     //= GetAny<double>(ll.second.eval(stack));
6449 
6450                     if(dofik>=0) B[dofik] += coef * c * w_i;
6451                     if(dofikk>=0) B[dofikk] += coef * c * ww_i;
6452 
6453                 }
6454             }
6455 
6456 
6457         }
6458         *MeshPointStack(stack) = mp;
6459 
6460     }
6461 
6462     // creating an instance of Element_rhs
6463     // case 3D volume
6464     template<class R>
Element_rhs(const Mesh3 & ThI,const Mesh3::Element & KI,const FESpace3 & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular & FI,bool alledges=false,int optim=1)6465     void  Element_rhs(const  Mesh3 & ThI,const Mesh3::Element & KI, const FESpace3 & Vh,
6466                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6467                       const QuadratureFormular & FI,bool alledges=false,int optim=1)
6468     {
6469         Stack stack=pvoid2Stack(vstack);
6470         int intmortar=0;
6471         //  AFAIRE("Element_rhs 3d on surface  2 diff mesh ");
6472         static int count =0;
6473         if(count++<1)
6474         {
6475             cout << " Element_rhs 3d on surface  2 diff mesh int test (FH)" << endl;
6476             cout << " -----------------------------------------------------" << endl;
6477         }
6478         // integration 1d on 2 diff mesh
6479 
6480 
6481         MeshPoint mp=*MeshPointStack(stack) ;
6482         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6483 
6484 
6485         bool classoptm = copt && Op.optiexpK;
6486         //assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6487         if (ThI(KI)<1 && verbosity/100 && verbosity % 10 == 2)
6488         cout << "Element_rhs S: copt = " << copt << " " << classoptm << " opt "<< optim <<endl;
6489         assert(Op.MaxOp() <last_operatortype);
6490         //
6491         int lastop=0;
6492         lastop = 0;
6493         What_d Dop = Op.DiffOp(lastop);
6494         // assert(lastop<=3);
6495         const Tet & T  = KI;
6496         long npi;
6497 
6498         const Tet * Kp=0;
6499 
6500         for (npi=0;npi<FI.n;npi++) // loop on the integration point
6501         {
6502 
6503             GQuadraturePoint<R2> pi(FI[npi]);
6504             R3 NN= T.N(ie);
6505             double mes=NN.norme();
6506             NN/=mes;
6507             double coef = 0.5*mes*pi.a; //
6508             R3 Pt(T.PBord(ie,pi)),PI(T(Pt));
6509 
6510 
6511 
6512             MeshPointStack(stack)->set(ThI,PI,Pt,KI,label,NN,ie);
6513             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6514             bool outside;
6515             R3 PIt;
6516             const Tet & K  = *Vh.Th.Find(PI,PIt,outside,Kp);
6517             if ( ! outside || intmortar) //  FH march 2009 ???
6518             {
6519                 const  FElement3  Kv= Vh[K];
6520                 long i,n=Kv.NbDoF(),N=Kv.N;
6521                 RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
6522                 Kv.BF(Dop,PIt,fu);
6523 
6524                 for ( i=0;  i<n;   i++ )
6525                 //   if (alledges || onWhatIsFace[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6526                 {
6527                     RNM_ wi(fu(i,'.','.'));
6528                     int il=0;
6529                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6530                     {
6531                         LOperaD::K ll(*l);
6532                         pair<int,int> ii(ll.first);
6533                         double w_i =  wi(ii.first,ii.second);
6534                         R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6535                         // FFCS - removing what is probably a small glitch
6536                         if ( copt && ( optim==1) && Kv.number<1)
6537                         {
6538                             R cc  =  GetAny<R>(ll.second.eval(stack));
6539                             if ( c != cc) {
6540                                 cerr << c << " =! " << cc << endl;
6541                                 cerr << "Sorry error in Optimization (y) add:  int1d(Th,optimize=0)(...)" << endl;
6542                                 ExecError("In Optimized version "); }
6543                         }
6544 
6545 
6546                         //= GetAny<double>(ll.second.eval(stack));
6547 
6548                         B[Kv(i)] += coef * c * w_i;
6549                     }
6550                 }
6551 
6552             }
6553         }
6554         *MeshPointStack(stack) = mp;
6555 
6556     }
6557 
6558     // creating an instance of Element_rhs
6559     // case 3D surface
6560     template<class R>
Element_rhs(const MeshS & ThI,const TriangleS & KI,const FESpaceS & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,bool intmortar=false,R2 * Q=0,int optim=1)6561     void  Element_rhs(const  MeshS & ThI,const TriangleS & KI, const FESpaceS & Vh,
6562                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6563                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,bool intmortar=false,
6564                       R2 *Q=0,int optim=1)
6565     {
6566         ffassert(0);
6567     }
6568 
6569     // creating an instance of Element_rhs
6570     // case 3D curve
6571     template<class R>
Element_rhs(const MeshL & ThI,const EdgeL & KI,const FESpaceL & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,bool intmortar=false,R2 * Q=0,int optim=1)6572     void  Element_rhs(const  MeshL & ThI,const EdgeL & KI, const FESpaceL & Vh,
6573                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6574                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,bool intmortar=false,
6575                       R2 *Q=0,int optim=1)
6576     {
6577         ffassert(0);
6578     }
6579 
6580     // creating an instance of Element_rhs
6581     // case 2d
6582     template<class R>
Element_rhs(const Mesh & ThI,const Triangle & KI,const FESpace & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,bool intmortar=false,R2 * Q=0,int optim=1)6583     void  Element_rhs(const  Mesh & ThI,const Triangle & KI, const FESpace & Vh,
6584                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6585                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,bool intmortar=false,
6586                       R2 *Q=0,int optim=1)
6587     {
6588         // integration 1d on 2 diff mesh
6589 
6590         Stack stack=pvoid2Stack(vstack);
6591         MeshPoint mp=*MeshPointStack(stack) ;
6592         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6593 
6594 
6595         bool classoptm = copt && Op.optiexpK;
6596         //assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6597         if (ThI.number(KI)<1 && verbosity/100 && verbosity % 10 == 2)
6598         cout << "Element_rhs S: copt = " << copt << " " << classoptm << " opt " << optim << endl;
6599         KN<bool> Dop(last_operatortype);
6600         Op.DiffOp(Dop);
6601         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
6602         assert(Op.MaxOp() <last_operatortype);
6603         // assert(lastop<=3);
6604         const Triangle & T  = KI;
6605         long npi;
6606 
6607         const Triangle * Kp=0;
6608         R2 PA,PB,E;
6609         if( Q==0)
6610         {
6611             PA=TriangleHat[VerticesOfTriangularEdge[ie][0]];
6612             PB=TriangleHat[VerticesOfTriangularEdge[ie][1]];
6613             E=T.Edge(ie);
6614         }
6615         else
6616         {
6617             PA=Q[0];
6618             PB=Q[1];
6619             E=T(PB)-T(PA);
6620         }
6621         double le = sqrt((E,E));
6622 
6623         for (npi=0;npi<FI.n;npi++) // loop on the integration point
6624         {
6625             QuadratureFormular1dPoint pi( FI[npi]);
6626 
6627 
6628             double coef = le*pi.a;
6629             double sa=pi.x,sb=1-sa;
6630             R2 Pt(PA*sa+PB*sb ); //
6631             R2 PI(KI(Pt));
6632             //   Kv.BF(Dop,Pt,fu);
6633             MeshPointStack(stack)->set(ThI,PI,Pt,KI,label,R2(E.y,-E.x)/le,ie);
6634             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6635             bool outside;
6636             R2 PIt;
6637             const Triangle & K  = *Vh.Th.Find(PI,PIt,outside,Kp);
6638             if ( ! outside || intmortar) //  FH march 2009 ???
6639             {
6640                 const  FElement  Kv= Vh[K];
6641                 long i,n=Kv.NbDoF(),N=Kv.N;
6642                 RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
6643                 Kv.BF(Dop,PIt,fu);
6644 
6645                 for ( i=0;  i<n;   i++ )
6646                 // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6647                 {
6648                     RNM_ wi(fu(i,'.','.'));
6649                     int il=0;
6650                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6651                     {
6652                         LOperaD::K ll(*l);
6653                         pair<int,int> ii(ll.first);
6654                         double w_i =  wi(ii.first,ii.second);
6655                         R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6656                         // FFCS - removing what is probably a small glitch
6657                         if ( copt && ( optim==1) && Kv.number<1)
6658                         {
6659                             R cc  =  GetAny<R>(ll.second.eval(stack));
6660                             if ( c != cc) {
6661                                 cerr << c << " =! " << cc << endl;
6662                                 cerr << "Sorry error in Optimization (z) add:  int1d(Th,optimize=0)(...)" << endl;
6663                                 ExecError("In Optimized version "); }
6664                         }
6665 
6666 
6667                         //= GetAny<double>(ll.second.eval(stack));
6668 
6669                         B[Kv(i)] += coef * c * w_i;
6670                     }
6671                 }
6672 
6673             }
6674         }
6675         *MeshPointStack(stack) = mp;
6676 
6677     }
6678     // creating an instance of Element_rhs
6679     // case 2d
6680     template<class R>
Element_rhs(Expression const * const mapt,const Mesh & ThI,const Triangle & KI,const FESpace & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,bool intmortar=false,R2 * Q=0,int optim=1)6681     void  Element_rhs(Expression const * const mapt,const  Mesh & ThI,const Triangle & KI, const FESpace & Vh,
6682                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6683                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,bool intmortar=false,
6684                       R2 *Q=0,int optim=1)
6685     {
6686         // integration 1d on 2 diff mesh
6687         //  ffassert(0);
6688         Stack stack=pvoid2Stack(vstack);
6689         MeshPoint mp=*MeshPointStack(stack) ;
6690         R ** copt = Stack_Ptr<R*>(stack,ElemMatPtrOffset);
6691 
6692 
6693         bool classoptm = copt && Op.optiexpK;
6694         //assert(  (copt !=0) ==  (Op.where_in_stack_opt.size() !=0) );
6695         if (ThI.number(KI)<1 && verbosity/100 && verbosity % 10 == 2)
6696         cout << "Element_rhs S: copt = " << copt << " " << classoptm << " opt " << optim << endl;
6697         KN<bool> Dop(last_operatortype);
6698         Op.DiffOp(Dop);
6699         int lastop=1+Dop.last(binder1st<equal_to<bool> >(equal_to<bool>(),true));
6700         assert(Op.MaxOp() <last_operatortype);
6701         // assert(lastop<=3);
6702         const Triangle & T  = KI;
6703         long npi;
6704 
6705         const Triangle * Kp=0;
6706         R2 PA,PB,E;
6707         if( Q==0)
6708         {
6709             PA=TriangleHat[VerticesOfTriangularEdge[ie][0]];
6710             PB=TriangleHat[VerticesOfTriangularEdge[ie][1]];
6711             E=T.Edge(ie);
6712         }
6713         else
6714         {
6715             PA=Q[0];
6716             PB=Q[1];
6717             E=T(PB)-T(PA);
6718         }
6719         double le = sqrt((E,E));
6720 
6721         for (npi=0;npi<FI.n;npi++) // loop on the integration point
6722         {
6723             QuadratureFormular1dPoint pi( FI[npi]);
6724 
6725 
6726             double coef = le*pi.a;
6727             double sa=pi.x,sb=1-sa;
6728             R2 Pt(PA*sa+PB*sb ); //
6729             R2 PIo(KI(Pt)),PI(PIo);
6730             //   Kv.BF(Dop,Pt,fu);
6731             MeshPointStack(stack)->set(ThI,PI,Pt,KI,label,R2(E.y,-E.x)/le,ie);
6732             if(mapt)
6733             { // move poit
6734                 PI= R2( GetAny<double>((*mapt[0])(vstack)), GetAny<double>((*mapt[1])(vstack)));
6735                 if(verbosity>9999) cout << "  Element_rhs(2) mapt =" << PIo << " -> " <<PI << endl;
6736             }
6737 
6738             if (classoptm) (*Op.optiexpK)(stack); // call optim version
6739             bool outside;
6740             R2 PIt;
6741             const Triangle & K  = *Vh.Th.Find(PI,PIt,outside,Kp);
6742             if ( ! outside || intmortar) //  FH march 2009 ???
6743             {
6744                 const  FElement  Kv= Vh[K];
6745                 long i,n=Kv.NbDoF(),N=Kv.N;
6746                 RNMK_ fu(p,n,N,lastop); //  the value for basic fonction
6747                 Kv.BF(Dop,PIt,fu);
6748 
6749                 for ( i=0;  i<n;   i++ )
6750                 // if (alledges || onWhatIsEdge[ie][Kv.DFOnWhat(i)]) // bofbof faux si il y a des derives ..
6751                 {
6752                     RNM_ wi(fu(i,'.','.'));
6753                     int il=0;
6754                     for (LOperaD::const_iterator l=Op.v.begin();l!=Op.v.end();l++,il++)
6755                     {
6756                         LOperaD::K ll(*l);
6757                         pair<int,int> ii(ll.first);
6758                         double w_i =  wi(ii.first,ii.second);
6759                         R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
6760                         // FFCS - removing what is probably a small glitch
6761                         if ( copt && ( optim==1) && Kv.number<1)
6762                         {
6763                             R cc  =  GetAny<R>(ll.second.eval(stack));
6764                             if ( c != cc) {
6765                                 cerr << c << " =! " << cc << endl;
6766                                 cerr << "Sorry error in Optimization (z) add:  int1d(Th,optimize=0)(...)" << endl;
6767                                 ExecError("In Optimized version "); }
6768                         }
6769 
6770 
6771                         //= GetAny<double>(ll.second.eval(stack));
6772 
6773                         B[Kv(i)] += coef * c * w_i;
6774                     }
6775                 }
6776 
6777             }
6778         }
6779         *MeshPointStack(stack) = mp;
6780 
6781     }
6782 
6783 
6784     // creating an instance of Element_rhs
6785     // case 3D surface
6786     template<class R>
Element_rhs(Expression const * const mapt,const MeshS & ThI,const TriangleS & KI,const FESpaceS & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,bool intmortar=false,R2 * Q=0,int optim=1)6787     void  Element_rhs(Expression const * const mapt,const  MeshS & ThI,const TriangleS & KI, const FESpaceS & Vh,
6788                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6789                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,bool intmortar=false,
6790                       R2 *Q=0,int optim=1)
6791     {
6792      ffassert(0);
6793     }
6794     // creating an instance of Element_rhs
6795     // case 3D curve
6796     template<class R>
Element_rhs(Expression const * const mapt,const MeshL & ThI,const EdgeL & KI,const FESpaceL & Vh,int ie,int label,const LOperaD & Op,double * p,void * vstack,KN_<R> & B,const QuadratureFormular1d & FI=QF_GaussLegendre2,bool alledges=false,bool intmortar=false,R1 * Q=0,int optim=1)6797     void  Element_rhs(Expression const * const mapt,const  MeshL & ThI,const EdgeL & KI, const FESpaceL & Vh,
6798                       int ie,int label,const LOperaD &Op,double * p,void * vstack,KN_<R> & B,
6799                       const QuadratureFormular1d & FI = QF_GaussLegendre2,bool alledges=false,bool intmortar=false,
6800                       R1 *Q=0,int optim=1)
6801     {
6802         ffassert(0);
6803     }
6804 
6805     // generic template for AssembleVarForm
6806     template<class R,typename MC,class FESpace >
AssembleVarForm(Stack stack,const typename FESpace::Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,MC * A,KN_<R> * B,const list<C_F0> & largs)6807     bool AssembleVarForm(Stack stack,const typename FESpace::Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
6808                          MC  * A,KN_<R> * B,const list<C_F0> &largs)
6809     { // return true if BC
6810         typedef typename FESpace::Mesh Mesh ;
6811         typedef Mesh * pmesh;
6812         ///typedef typename Trait_MESHO<FESpace>::MeshO * pmeshO;
6813         bool ret=false;
6814         typedef DotStar_KN_<R> DotStar;
6815         typedef DotSlash_KN_<R> DotSlash;
6816         list<C_F0>::const_iterator ii,ib=largs.begin(),
6817         ie=largs.end();
6818         using namespace FreeFempp;
6819         TypeVarForm<R> *tvf=TypeVarForm<R>::Global;
6820         assert( tvf);
6821         for (ii=ib;ii != ie;ii++)
6822         {
6823             Expression e=ii->LeftValue();
6824             aType r = ii->left();
6825             //  if(A)        cout << "AssembleVarForm " <<  * r << " " <<  (*A)(0,3) << endl;
6826             if (r==  tvf->tFB)
6827             { if (A)
6828                 {
6829                     const  FormBilinear * bf =dynamic_cast<const  FormBilinear *>(e);
6830                     // integration mesh type
6831                     ///pmeshO  ThbfO = GetAny<pmeshO>((*bf->di->Th)(stack)); // case 3D surface ThbfO =
6832                     pmesh  Thbf= GetAny<pmesh>((*bf->di->Th)(stack));///Trait_MESHO<FESpace>::topmesh(ThbfO);  //
6833                     if(Thbf) AssembleBilinearForm<R>( stack,*Thbf,Uh,Vh,sym,*A,bf);
6834                 }
6835             }
6836             else if (r==tvf->tMat)
6837             {
6838                 if (A)
6839                 InternalError(" Add sparse matrice; to do, sorry");
6840             }
6841             else if (r==tvf->tFL)
6842             {
6843                 if (B) {
6844                     const  FormLinear * bf =dynamic_cast<const  FormLinear *>(e);
6845                     ///pmeshO  ThbfO = GetAny<pmeshO>((*bf->di->Th)(stack)); // case 3D surface ThbfO =
6846                     pmesh  Thbf= GetAny<pmesh>((*bf->di->Th)(stack)); //Trait_MESHO<FESpace>::topmesh(ThbfO);  //
6847                     if(Thbf) AssembleLinearForm<R>( stack,*Thbf, Vh, B,bf);
6848                 }
6849             }
6850             else if (r==tvf->tTab)
6851             {
6852                 if ( B)
6853                 *B += *GetAny<KN<R> *>( (*e)(stack) );
6854             }
6855             else if (r==tvf->tDotStar)
6856             {
6857                 if ( B)
6858                 {
6859                     DotStar ab=GetAny<DotStar>( (*e)(stack) );
6860                     *B += ab;
6861                 }
6862             }
6863             else if (r==tvf->tMatX)
6864             {
6865                 if ( B)
6866                 {
6867                     *B += GetAny<typename RNM_VirtualMatrix<R>::plusAx >( (*e)(stack) )  ;
6868                 }
6869             }
6870             else if (r==tvf->tMatTX)
6871             {
6872                 if ( B)
6873                 {
6874                     *B += GetAny<typename RNM_VirtualMatrix<R>::plusAtx >( (*e)(stack) )  ;
6875                 }
6876             }
6877             else if (r== tvf->tBC)
6878             ret=true;
6879             else
6880             {
6881                 cerr << "AssembleVarForm  invalid type : " << * r <<  endl;
6882                 throw(ErrorExec("AssembleVarForm invalid type in varf",1));
6883             }
6884         }
6885         return ret;
6886     }
6887 
6888     template<class R,class FESpace>
AssembleBC(Stack stack,const typename FESpace::Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,MatriceCreuse<R> * A,KN_<R> * B,KN_<R> * X,const list<C_F0> & largs,double tgv)6889     void AssembleBC(Stack stack,const typename FESpace::Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
6890                     MatriceCreuse<R>  * A,KN_<R> * B,KN_<R> * X, const list<C_F0> &largs , double tgv  )
6891     {
6892         list<C_F0>::const_iterator ii,ib=largs.begin(),
6893         ie=largs.end();
6894         aType tBC( atype<const  BC_set  *>()) ;
6895         for (ii=ib;ii != ie;ii++)
6896         {
6897             Expression e=ii->LeftValue();
6898             aType r = ii->left();
6899             if (r==tBC)
6900             AssembleBC(stack,Th,Uh,Vh,sym,A,B,X, dynamic_cast<const  BC_set *>(e),tgv);
6901         }
6902 
6903     }
6904 
6905    //////////////////////////////////
6906    // AssembleBC
6907    //////////////////////////////////
6908 
6909   // creating an instance of AssembleBC
6910     // case 2d
6911     template<class R>
AssembleBC(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,MatriceCreuse<R> * A,KN_<R> * B,KN_<R> * X,const BC_set * bc,double tgv)6912     void AssembleBC(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
6913                     MatriceCreuse<R>  * A,KN_<R> * B,KN_<R> * X, const  BC_set * bc, double tgv  )
6914 
6915     {
6916         MeshPoint *mps= MeshPointStack(stack),mp=*mps;
6917         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
6918         bool sptrclean=true;
6919         //     sptr->clean(); // modif FH mars 2006  clean Ptr
6920 
6921         int ktbc=0, nbon =0;
6922         bool Aii = A && A->n == A->m;
6923 
6924         int Nbcomp=Vh.N;
6925         Check(bc,Nbcomp);
6926         ffassert(Vh.N == Uh.N);
6927         TabFuncArg tabexp(stack,Vh.N);
6928         KN<double> buf((long int)Vh.MaximalNbOfDF() * (long int)last_operatortype * (long int)Vh.N);
6929         int ndofBC = Aii ?  A->n : 1;
6930         KN<char> onBC(ndofBC);
6931         onBC= '\0';
6932 
6933         KN<R> gg(buf);
6934         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleBC size rhs and nb of DF of Vh");
6935         if(verbosity>99) cout << " Problem : BC_set "<< typeid(R).name() << " " ;
6936         nbon =bc->on.size();
6937         set<long> on;
6938         Expandsetoflab(stack,*bc, on);
6939         /*
6940          for (int i=0;i<nbon;i++)
6941          {
6942          long  lab  = GetAny<long>( (*bc->on[i])(stack));
6943          if(verbosity>99) cout << lab << " " ;
6944          on.insert(lab);
6945          }
6946          if(verbosity>99)
6947          cout << endl;
6948          */
6949         int kk=bc->bc.size();
6950 
6951         const int dim=Vh.N;
6952         FElement::aIPJ ipj(Vh[0].Pi_h_ipj());
6953         FElement::aR2  PtHat(Vh[0].Pi_h_R2());
6954 
6955         KN<int> PtonB(PtHat.N());
6956 
6957         KN<double>   Aipj(ipj.N());
6958         KNM<R>  Vp(dim,PtHat.N());
6959 
6960         double tgv1=tgv <0? 1: tgv; // change 21 dec 2010 FH (Hack of ILU)
6961         for (int ib=0;ib<Th.neb;ib++)
6962         {
6963             int ie;
6964             int it = Th.BoundaryElement(ib,ie);
6965             int r =Th.bedges[ib].lab;
6966             if (on.find(r) != on.end() )
6967             {
6968                 const FElement K(Uh[it]);
6969                 R2 E=K.T.Edge(ie);
6970                 double le = sqrt((E,E));
6971 
6972                 ktbc++;
6973                 if(verbosity>99)   cout << "BC " << it << " " << ie << " lab=" << r <<  ":\t"
6974                 << K.T[VerticesOfTriangularEdge[ie][0]] << "; "
6975                 << K.T[VerticesOfTriangularEdge[ie][1]] << " E=" << K.T.Edge(ie) << endl;
6976 
6977                 for (int k=0;k<kk;k++)
6978                 {
6979                     gg=R();
6980                     pair<int,Expression> xx=bc->bc[k];
6981                     tabexp=0;
6982                     int comp = xx.first;
6983                     tabexp[comp]=xx.second;
6984                     // while  (comp+1 <Nbcomp && which_uh[comp+1] == which_uh[comp])
6985                     while  (comp+1 <Nbcomp && Uh.dim_which_sub_fem[comp+1] == Uh.dim_which_sub_fem[comp])
6986                     {  // the right
6987                         k++; // NEXT COMP
6988                         comp++;
6989                         if (k<kk && (comp == bc->bc[k].first) )
6990                         tabexp[comp]=bc->bc[k].second;
6991                         else
6992                         CompileError("In Boundary condition the vector FESpace , we must have:"
6993                                      " all componant, in the right order");
6994 
6995                     }
6996                     // cout << " k "<< k << " " << comp << " " << " Nbcomp=" << Nbcomp << " " << Uh.dim_which_sub_fem[comp] << " " << Uh.dim_which_sub_fem[comp+1] <<  endl;
6997 #ifdef OLDPih
6998                     K.Pi_h(gg,F_Pi_h,buf,&tabexp);
6999 
7000 #else
7001                     K.Pi_h(Aipj);
7002                     PtonB = 0;
7003                     for (int i=0;i<Aipj.N();i++)
7004                     PtonB[ipj[i].p] += onWhatIsEdge[ie][K.DFOnWhat(ipj[i].i)] ;
7005                     // cout << "   bc->complextype:  " << bc->complextype << endl;
7006                     for (int p=0;p<PtHat.N();p++)
7007                     if (PtonB[p]) // in on boundary
7008                     {
7009                         mps->set(K.T(PtHat[p]),PtHat[p],K,r,R2(E.y,-E.x)/le,ie); // la normal bofbof ?
7010                         KN_<R> Vpp(Vp('.',p));
7011                         Vpp=R();
7012                         for (int j=0;j<dim;j++)
7013                         if (tabexp[j])
7014                         {
7015                             if(bc->complextype) // FH may 2007  MatriceCreuse
7016                             Vpp[j]=GetAny<R>( (*tabexp[j])(stack) );
7017                             else
7018                             Vpp[j]=GetAny<double>( (*tabexp[j])(stack) );
7019                         }
7020                         else Vpp[j]=0.;
7021                     }
7022                     //cout << " ..... Vp " << Vp << " " << bc->complextype << " " << bc << endl;
7023                     for (int i=0;i<Aipj.N();i++)
7024                     {
7025                         const FElement::IPJ &ipj_i(ipj[i]);
7026                         gg[ipj_i.i] += Aipj[i]*Vp(ipj_i.j,ipj_i.p);
7027                     }
7028 #endif
7029                     int nbdf = K.NbDoF();
7030                     for (int df=0;df<nbdf;df++)
7031                     // if (K.FromFE(df)==which_uh[xx.first] && onWhatIsEdge[ie][K.DFOnWhat(df)] )
7032                     {
7033                         //  cout << df << " from = " << K.FromFE(df) << "   dim .. " << Uh.dim_which_sub_fem[xx.first] << "  first " << xx.first << " " << onWhatIsEdge[ie][K.DFOnWhat(df)] << endl;
7034                         if (K.FromASubFE(df)==Uh.dim_which_sub_fem[xx.first] && onWhatIsEdge[ie][K.DFOnWhat(df)] )
7035                         {
7036                             // cout << k << " df=" << df <<  " g= " << gg[df] <<" " << gg(FromTo(0,2)) << endl;
7037                             int ddf=K(df);
7038                             // AA(ddf,ddf) =tgv;
7039                             if (Aii)  onBC[ddf]='1'; ;//A->SetBC(ddf, tgv);// change 21 dec 2010 FH (Hack of ILU)
7040                             if (B) (*B)[ddf]=  tgv1*gg[df];
7041                             if (X) (*X)[ddf]=gg[df];
7042                         }
7043                     }
7044                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7045                 }
7046             }
7047         }
7048         if( Aii) A->SetBC(onBC,tgv);
7049         if (! ktbc  && nbon && verbosity )
7050         {
7051             cout << " Warning: -- Your set of boundary condition is incompatible with the mesh label." << endl;
7052         }
7053         *mps =mp;
7054     }
7055 
7056     // creating an instance of AssembleBC
7057     // case 3D volume
7058     template<class R>
AssembleBC(Stack stack,const Mesh3 & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,MatriceCreuse<R> * A,KN_<R> * B,KN_<R> * X,const BC_set * bc,double tgv)7059     void AssembleBC(Stack stack,const Mesh3 & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
7060                     MatriceCreuse<R>  * A,KN_<R> * B,KN_<R> * X, const  BC_set * bc, double tgv  )
7061 
7062     {
7063         typedef Mesh3 Mesh;
7064         typedef typename FESpace3::FElement FElement;
7065         typedef typename Mesh::BorderElement BorderElement;
7066         typedef typename Mesh::Rd Rd;
7067         typedef typename Mesh::Element Element;
7068         typedef typename Mesh::RdHat RdHat;
7069 
7070         MeshPoint *mps= MeshPointStack(stack),mp=*mps;
7071         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
7072         bool sptrclean=true;
7073         //     sptr->clean(); // modif FH mars 2006  clean Ptr
7074 
7075         int ktbc=0, nbon =0;
7076         bool Aii = A && A->n == A->m;
7077         int ndofBC = Aii ?  A->n : 1;
7078         KN<char> onBC(ndofBC);
7079         onBC= '\0';
7080 
7081         int Nbcomp=Vh.N;
7082         Check(bc,Nbcomp);
7083         assert(Vh.N == Uh.N);
7084         TabFuncArg tabexp(stack,Vh.N);
7085         KN<double> buf((long int)Vh.MaximalNbOfDF() * (long int)last_operatortype * (long int)Vh.N);
7086         KN<R> gg(buf);
7087         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleBC size rhs and nb of DF of Vh");
7088         if(verbosity>99) cout << " Problem : BC_set "<< typeid(R).name() << " " ;
7089         nbon =bc->on.size();
7090         set<long> on;
7091         Expandsetoflab(stack,*bc, on);
7092         /*
7093          for (int i=0;i<nbon;i++)
7094          {
7095          long  lab  = GetAny<long>( (*bc->on[i])(stack));
7096          if(verbosity>99) cout << lab << " " ;
7097          on.insert(lab);
7098          }
7099          if(verbosity>99)
7100          cout << endl;*/
7101         int kk=bc->bc.size();
7102 
7103         const int dim=Vh.N;
7104 
7105         InterpolationMatrix<RdHat> ipmat(Vh);
7106         int npPh = Vh.maxNbPtforInterpolation;
7107         KN<int> PtonB(npPh);
7108         KNM<R>   Vp(npPh,dim);
7109         Vp=R();
7110         KN<R>  Vdf(Vh.MaxNbDFPerElement);
7111         double tgv1=tgv <0? 1: tgv;
7112         map<int,int> lll;
7113         for (int ib=0;ib<Th.nbe;ib++)
7114         {
7115             int ie;
7116             int it = Th.BoundaryElement(ib,ie);
7117 
7118             //const BorderElement &be=Th.be(ib);
7119             int r =Th.be(ib).lab;
7120             lll[r]++;
7121             if (on.find(r) != on.end() )
7122             {
7123                 const FElement K(Uh[it]);
7124                 ipmat.set(K);
7125 
7126                 //R2 E=K.T.Edge(ie);
7127                 //double le = be.mesure();
7128 
7129                 ktbc++;
7130                 /*
7131                  if(verbosity>99)   cout << "BC " << it << " " << ie << " lab=" << r <<  ":\t"
7132                  << K.T[VerticesOfTriangularEdge[ie][0]] << "; "
7133                  << K.T[VerticesOfTriangularEdge[ie][1]] << " E=" << K.T.Edge(ie) << endl;
7134                  */
7135                 for (int k=0;k<kk;k++)
7136                 {
7137                     gg=R();
7138                     pair<int,Expression> xx=bc->bc[k];
7139                     tabexp=0;
7140                     int comp = xx.first;
7141                     tabexp[comp]=xx.second;
7142                     // while  (comp+1 <Nbcomp && which_uh[comp+1] == which_uh[comp])
7143                     while  (comp+1 <Nbcomp && Uh.dim_which_sub_fem[comp+1] == Uh.dim_which_sub_fem[comp])
7144                     {  // the right
7145                         k++; // NEXT COMP
7146                         comp++;
7147                         if (k<kk && (comp == bc->bc[k].first) )
7148                         tabexp[comp]=bc->bc[k].second;
7149                         else
7150                         CompileError("In Boundary condition the vector FESpace , we must have:"
7151                                      " all componant, in the right order");
7152 
7153                     }
7154                     int nbdf=K.NbDoF() ;
7155                     //ipmat.set(it);
7156                     PtonB = 0;
7157                     Rd NN=K.T.N(ie);
7158                     NN /= NN.norme();
7159                     for (int i=0;i<ipmat.ncoef;i++)
7160                     PtonB[ipmat.p[i]] +=  Element::onWhatBorder[ie][K.DFOnWhat(ipmat.dofe[i])] ;
7161 
7162 
7163                     for (int p=0;p<ipmat.np;p++)
7164                     if (PtonB[p]) // in on boundary
7165                     {
7166                         const RdHat & PtHat(ipmat.P[p]);
7167                         mps->set(K.T(PtHat),PtHat,K,r,NN,ie); // la normal bofbof ?
7168                         KN_<R> Vpp(Vp(p,'.'));
7169                         for (int j=0;j<dim;j++)
7170                         if (tabexp[j])
7171                         if(bc->complextype) // FH may 2007
7172                         Vpp[j]=GetAny<R>( (*tabexp[j])(stack) );
7173                         else
7174                         Vpp[j]=GetAny<double>( (*tabexp[j])(stack) );
7175 
7176                         else Vpp[j]=0.;
7177                     }
7178                     // cout << " Vp:  " << Vp << endl;
7179                     K.Pi_h(Vp,Vdf,ipmat);
7180                     for (int df=0;df<nbdf;df++)
7181                     {
7182                         if (K.FromASubFE(df)==Uh.dim_which_sub_fem[xx.first] && Element::onWhatBorder[ie][K.DFOnWhat(df)] )
7183                         {
7184                             int ddf=K(df);
7185                             // cout << ddf << " " << df << " " << Vdf[df] << " " << it << " ib = " << ib  << " == " << Th(Th[it][df]) <<  endl;
7186                             //if (Aii)  A->SetBC(ddf,tgv);// change 21 dec 2010 FH (Hack of ILU)
7187                             if (Aii)  onBC[ddf]='1'; ;//   april 2018 FH
7188                             if (B) (*B)[ddf]=tgv1*Vdf[df];
7189                             if (X) (*X)[ddf]=Vdf[df];
7190                         }
7191                     }
7192                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7193                 }
7194             }
7195         }
7196         if( Aii) A->SetBC(onBC,tgv);
7197         if (! ktbc  && nbon && verbosity>1 )
7198         {
7199             cout << " Warning: -- Your set of boundary condition is incompatible with the mesh label." << endl;
7200             if(verbosity>4)
7201             for (map<int,int>::const_iterator i=lll.begin();i!=lll.end();i++)
7202                 if( on.find(i->first) != on.end() )
7203                     cout << " on: missing lab " << i-> first << "  nb " << i->second  << endl;
7204         }
7205         *mps =mp;
7206     }
7207 
7208     // creating an instance of AssembleBC
7209     // case 3D surface
7210     template<class R>
AssembleBC(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,MatriceCreuse<R> * A,KN_<R> * B,KN_<R> * X,const BC_set * bc,double tgv)7211     void AssembleBC(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
7212                     MatriceCreuse<R>  * A,KN_<R> * B,KN_<R> * X, const  BC_set * bc, double tgv  )
7213     {
7214         typedef MeshS Mesh;
7215         typedef typename FESpaceS::FElement FElement;
7216         typedef typename Mesh::BorderElement BorderElement;
7217         typedef typename Mesh::Rd Rd;
7218         typedef typename Mesh::Element Element;
7219         typedef typename Mesh::RdHat RdHat;
7220 
7221         MeshPoint *mps= MeshPointStack(stack),mp=*mps;
7222         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
7223         bool sptrclean=true;
7224         //     sptr->clean(); // modif FH mars 2006  clean Ptr
7225 
7226         int ktbc=0, nbon =0;
7227         bool Aii = A && A->n == A->m;
7228         int ndofBC = Aii ?  A->n : 1;
7229         KN<char> onBC(ndofBC);
7230         onBC= '\0';
7231 
7232         int Nbcomp=Vh.N;
7233         Check(bc,Nbcomp);
7234         assert(Vh.N == Uh.N);
7235         TabFuncArg tabexp(stack,Vh.N);
7236         KN<double> buf((long int)Vh.MaximalNbOfDF() * (long int)last_operatortype * (long int)Vh.N);
7237         KN<R> gg(buf);
7238         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleBC size rhs and nb of DF of Vh");
7239         if(verbosity>99) cout << " Problem : BC_set "<< typeid(R).name() << " " ;
7240         nbon =bc->on.size();
7241         set<long> on;
7242         Expandsetoflab(stack,*bc, on);
7243         /*
7244          for (int i=0;i<nbon;i++)
7245          {
7246          long  lab  = GetAny<long>( (*bc->on[i])(stack));
7247          if(verbosity>99) cout << lab << " " ;
7248          on.insert(lab);
7249          }
7250          if(verbosity>99)
7251          cout << endl;*/
7252         int kk=bc->bc.size();
7253 
7254         const int dim=Vh.N;
7255 
7256         InterpolationMatrix<RdHat> ipmat(Vh);
7257         int npPh = Vh.maxNbPtforInterpolation;
7258         KN<int> PtonB(npPh);
7259         KNM<R>   Vp(npPh,dim);
7260         Vp=R();
7261         KN<R>  Vdf(Vh.MaxNbDFPerElement);
7262         double tgv1=tgv <0? 1: tgv;
7263         map<int,int> lll;
7264         for (int ib=0;ib<Th.nbe;ib++)
7265         {
7266             int ie;
7267             int it = Th.BoundaryElement(ib,ie);
7268 
7269             //const BorderElement &be=Th.be(ib);
7270             int r =Th.be(ib).lab;
7271             lll[r]++;
7272             if (on.find(r) != on.end() )
7273             {
7274                 const FElement K(Uh[it]);
7275                 ipmat.set(K);
7276 
7277                 //R2 E=K.T.Edge(ie);
7278                 //double le = be.mesure();
7279 
7280                 ktbc++;
7281                 /*
7282                  if(verbosity>99)   cout << "BC " << it << " " << ie << " lab=" << r <<  ":\t"
7283                  << K.T[VerticesOfTriangularEdge[ie][0]] << "; "
7284                  << K.T[VerticesOfTriangularEdge[ie][1]] << " E=" << K.T.Edge(ie) << endl;
7285                  */
7286                 for (int k=0;k<kk;k++)
7287                 {
7288                     gg=R();
7289                     pair<int,Expression> xx=bc->bc[k];
7290                     tabexp=0;
7291                     int comp = xx.first;
7292                     tabexp[comp]=xx.second;
7293                     // while  (comp+1 <Nbcomp && which_uh[comp+1] == which_uh[comp])
7294                     while  (comp+1 <Nbcomp && Uh.dim_which_sub_fem[comp+1] == Uh.dim_which_sub_fem[comp])
7295                     {  // the right
7296                         k++; // NEXT COMP
7297                         comp++;
7298                         if (k<kk && (comp == bc->bc[k].first) )
7299                             tabexp[comp]=bc->bc[k].second;
7300                         else
7301                             CompileError("In Boundary condition the vector FESpace , we must have:"
7302                                          " all componant, in the right order");
7303 
7304                     }
7305                     int nbdf=K.NbDoF() ;
7306                     //ipmat.set(it);
7307                     PtonB = 0;
7308 
7309                     R3 E=K.T.Edge(ie);
7310                     double le = sqrt((E,E));
7311                     // surface normal
7312                     Rd NNt=K.T.NFrenetUnitaire();
7313                     // exterior normal (flux)
7314                     Rd NN=K.T.N(ie);
7315                     NN /= NN.norme();
7316 
7317                     for (int i=0;i<ipmat.ncoef;i++)
7318                         PtonB[ipmat.p[i]] +=  Element::onWhatBorder[ie][K.DFOnWhat(ipmat.dofe[i])] ;
7319 
7320 
7321                     for (int p=0;p<ipmat.np;p++)
7322                         if (PtonB[p]) // in on boundary
7323                         {
7324                             const RdHat & PtHat(ipmat.P[p]);
7325                             mps->set(K.T(PtHat),PtHat,K,r,NN,NNt,ie); // la normal bofbof ?
7326                             KN_<R> Vpp(Vp(p,'.'));
7327                             for (int j=0;j<dim;j++)
7328                                 if (tabexp[j])
7329                                     if(bc->complextype) // FH may 2007
7330                                         Vpp[j]=GetAny<R>( (*tabexp[j])(stack) );
7331                                     else
7332                                         Vpp[j]=GetAny<double>( (*tabexp[j])(stack) );
7333 
7334                                     else Vpp[j]=0.;
7335                         }
7336                     // cout << " Vp:  " << Vp << endl;
7337                     K.Pi_h(Vp,Vdf,ipmat);
7338                     for (int df=0;df<nbdf;df++)
7339                     {
7340                         if (K.FromASubFE(df)==Uh.dim_which_sub_fem[xx.first] && Element::onWhatBorder[ie][K.DFOnWhat(df)] )
7341                         {
7342                             int ddf=K(df);
7343                             // cout << ddf << " " << df << " " << Vdf[df] << " " << it << " ib = " << ib  << " == " << Th(Th[it][df]) <<  endl;
7344                             //if (Aii)  A->SetBC(ddf,tgv);// change 21 dec 2010 FH (Hack of ILU)
7345                             if (Aii)  onBC[ddf]='1'; ;//   april 2018 FH
7346                             if (B) (*B)[ddf]=tgv1*Vdf[df];
7347                             if (X) (*X)[ddf]=Vdf[df];
7348                         }
7349                     }
7350                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7351                 }
7352             }
7353         }
7354         if( Aii) A->SetBC(onBC,tgv);
7355         if (! ktbc  && nbon && verbosity>1 )
7356         {
7357             cout << " Warning: -- Your set of boundary condition is incompatible with the mesh label." << endl;
7358             if(verbosity>9)
7359             for (map<int,int>::const_iterator i=lll.begin();i!=lll.end();i++)
7360               if( on.find(i->first) != on.end() )
7361                   cout << " on: missing lab " << i-> first << "  nb " << i->second  << endl;
7362         }
7363         *mps =mp;
7364     }
7365 
7366     // creating an instance of AssembleBC
7367     // case 3D curve
7368     template<class R>
AssembleBC(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,MatriceCreuse<R> * A,KN_<R> * B,KN_<R> * X,const BC_set * bc,double tgv)7369     void AssembleBC(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
7370                     MatriceCreuse<R>  * A,KN_<R> * B,KN_<R> * X, const  BC_set * bc, double tgv  )
7371     {
7372         typedef MeshL Mesh;
7373         typedef typename FESpaceL::FElement FElement;
7374         typedef typename Mesh::BorderElement BorderElement;
7375         typedef typename Mesh::Rd Rd;
7376         typedef typename Mesh::Element Element;
7377         typedef typename Mesh::RdHat RdHat;
7378 
7379         MeshPoint *mps= MeshPointStack(stack),mp=*mps;
7380         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
7381         bool sptrclean=true;
7382         //     sptr->clean(); // modif FH mars 2006  clean Ptr
7383 
7384         int ktbc=0, nbon =0;
7385         bool Aii = A && A->n == A->m;
7386         int ndofBC = Aii ?  A->n : 1;
7387         KN<char> onBC(ndofBC);
7388         onBC= '\0';
7389 
7390         int Nbcomp=Vh.N;
7391         Check(bc,Nbcomp);
7392         assert(Vh.N == Uh.N);
7393         TabFuncArg tabexp(stack,Vh.N);
7394         KN<double> buf((long int)Vh.MaximalNbOfDF() * (long int)last_operatortype * (long int)Vh.N);
7395         KN<R> gg(buf);
7396         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleBC size rhs and nb of DF of Vh");
7397         if(verbosity>99) cout << " Problem : BC_set "<< typeid(R).name() << " " ;
7398         nbon =bc->on.size();
7399         set<long> on;
7400         Expandsetoflab(stack,*bc, on);
7401 
7402         int kk=bc->bc.size();
7403 
7404         const int dim=Vh.N;
7405 
7406         InterpolationMatrix<RdHat> ipmat(Vh);
7407         int npPh = Vh.maxNbPtforInterpolation;
7408         KN<int> PtonB(npPh);
7409         KNM<R>   Vp(npPh,dim);
7410         Vp=R();
7411         KN<R>  Vdf(Vh.MaxNbDFPerElement);
7412         double tgv1=tgv <0? 1: tgv;
7413         map<int,int> lll;
7414         for (int ib=0;ib<Th.nbe;ib++) {
7415             int ie;
7416             int it = Th.BoundaryElement(ib,ie);
7417 
7418             int r =Th.be(ib).lab;
7419             lll[r]++;
7420             if (on.find(r) != on.end() ) {
7421                 const FElement K(Uh[it]);
7422                 ipmat.set(K);
7423                  ktbc++;
7424 
7425                 for (int k=0;k<kk;k++) {
7426                     gg=R();
7427                     pair<int,Expression> xx=bc->bc[k];
7428                     tabexp=0;
7429                     int comp = xx.first;
7430                     tabexp[comp]=xx.second;
7431                     // while  (comp+1 <Nbcomp && which_uh[comp+1] == which_uh[comp])
7432                     while  (comp+1 <Nbcomp && Uh.dim_which_sub_fem[comp+1] == Uh.dim_which_sub_fem[comp])
7433                     {  // the right
7434                         k++; // NEXT COMP
7435                         comp++;
7436                         if (k<kk && (comp == bc->bc[k].first) )
7437                             tabexp[comp]=bc->bc[k].second;
7438                         else
7439                             CompileError("In Boundary condition the vector FESpace , we must have:"
7440                                          " all componant, in the right order");
7441 
7442                     }
7443                     int nbdf=K.NbDoF() ;
7444                     //ipmat.set(it);
7445                     PtonB = 0;
7446                     R3 NNt=K.T.NFrenetUnitaire();
7447                     // exterior normal (flux)
7448                     Rd NN=K.T.N(ie);
7449                     NN /= NN.norme();
7450 
7451                     for (int i=0;i<ipmat.ncoef;i++)
7452                         PtonB[ipmat.p[i]] +=  Element::onWhatBorder[ie][K.DFOnWhat(ipmat.dofe[i])] ;
7453 
7454 
7455                     for (int p=0;p<ipmat.np;p++)
7456                         if (PtonB[p]) // in on boundary
7457                         {
7458                             const RdHat & PtHat(ipmat.P[p]);
7459                             mps->set(K.T(PtHat),PtHat,K,r,NN,NNt,ie);
7460                             KN_<R> Vpp(Vp(p,'.'));
7461                             for (int j=0;j<dim;j++)
7462                                 if (tabexp[j])
7463                                     if(bc->complextype) // FH may 2007
7464                                         Vpp[j]=GetAny<R>( (*tabexp[j])(stack) );
7465                                     else
7466                                         Vpp[j]=GetAny<double>( (*tabexp[j])(stack) );
7467 
7468                                     else Vpp[j]=0.;
7469                         }
7470                     K.Pi_h(Vp,Vdf,ipmat);
7471                     for (int df=0;df<nbdf;df++)
7472                     {
7473                         if (K.FromASubFE(df)==Uh.dim_which_sub_fem[xx.first] && Element::onWhatBorder[ie][K.DFOnWhat(df)] )
7474                         {
7475                             int ddf=K(df);
7476                             if (Aii)  onBC[ddf]='1'; ;//   april 2018 FH
7477                             if (B) (*B)[ddf]=tgv1*Vdf[df];
7478                             if (X) (*X)[ddf]=Vdf[df];
7479                         }
7480                     }
7481                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7482                 }
7483             }
7484         }
7485         if( Aii) A->SetBC(onBC,tgv);
7486         if (! ktbc  && nbon && verbosity )
7487         {
7488             cout << " Warning: -- Your set of boundary condition is incompatible with the mesh label." << endl;
7489             for (map<int,int>::const_iterator i=lll.begin();i!=lll.end();i++)
7490                 cout << " lab " << i-> first << "  nb " << i->second  << endl;
7491         }
7492         *mps =mp;
7493     }
7494 
7495     void  Expandsetoflab(Stack stack,const BC_set & bc,set<long> & setoflab);
7496     void  Expandsetoflab(Stack stack,const CDomainOfIntegration & di,set<int> & setoflab,bool &all);
7497 
7498     //////////////////////////////////
7499     // AssembleLinearForm
7500     //////////////////////////////////
7501 
7502     // creating an instance of AssembleLinearForm
7503     // case 2d
7504     template<class R>
AssembleLinearForm(Stack stack,const Mesh & Th,const FESpace & Vh,KN_<R> * B,const FormLinear * l)7505     void AssembleLinearForm(Stack stack,const Mesh & Th,const FESpace & Vh,KN_<R> * B,const  FormLinear * l )
7506     {
7507         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
7508         bool sptrclean=true;
7509         //     sptr->clean(); // modif FH mars 2006  clean Ptr
7510         Check(l->l,Vh.N);
7511         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleLinearForm size rhs and nb of DF of Vh");
7512         // if ( & Th != &Vh.Th ) ExecError("AssembleLinearForm on different meshes  ( not implemented FH).");
7513         KN<double> buf(Vh.MaximalNbOfDF()*last_operatortype*Vh.N*2);
7514 
7515         //            const  FormLinear * l=dynamic_cast<const  FormLinear *>(e);
7516         const CDomainOfIntegration & di= *l->di;
7517         const Mesh & ThI = Th;// * GetAny<pmesh>( (* di.Th)(stack));
7518         bool sameMesh = &ThI == &Vh.Th;
7519         const bool intmortar=di.intmortar(stack);
7520 
7521         SHOWVERB(cout << " FormLinear " << endl);
7522         // const vector<Expression>  & what(di.what);
7523 
7524         CDomainOfIntegration::typeofkind  kind = di.kind;
7525         const QuadratureFormular1d & FIE = di.FIE(stack);
7526         const QuadratureFormular & FIT = di.FIT(stack);
7527         const int useopt=di.UseOpt(stack);
7528         double binside=di.binside(stack);  // truc FH pour fluide de grad2 (decentrage bizard)
7529         //  cout << "AssembleLinearForm " << l->l->v.size() << endl;
7530         set<int> setoflab;
7531         bool all=true;
7532         bool VF=l->VF();  // finite Volume or discontinous Galerkin
7533         if (verbosity>2) cout << "  -- AssembleLinearForm 2, discontinous Galerkin  =" << VF << " binside = "<< binside
7534         << " levelset integration " <<di.islevelset()<< " withmap: "<<  di.withmap() << "\n";
7535         //  if( di.withmap()) { ExecError(" no map  in the case (6)??");}
7536         Expression  const * const mapt=di.mapt[0] ? di.mapt:0;
7537         sameMesh = sameMesh && !mapt; //
7538 
7539         if (verbosity>3)
7540         {
7541 
7542             if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ";
7543             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
7544             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
7545             else cout << "  --  int 2d  (nQP: "<< FIT.n << " ) in "  ;
7546             cout << ", samemesh :"<< sameMesh<< " int mortar: " << intmortar ;
7547         }
7548         /*
7549          if ( verbosity>3)
7550          if (kind==CDomainOfIntegration::int1d) cout << "  -- boundary int border " ;
7551          else if (kind==CDomainOfIntegration::intalledges) cout << "  -- boundary int all edges " ;
7552          else if (kind==CDomainOfIntegration::intallVFedges) cout << "  -- boundary int all edges " ;
7553          else cout << "  -- boundary int  " ;
7554          */
7555         if(di.islevelset() && ( (CDomainOfIntegration::int1d!=kind) && (CDomainOfIntegration::int2d!=kind) )  )
7556         InternalError("So no levelset integration type on no int1d/int2d case (4)");
7557         Expandsetoflab(stack,di, setoflab,all);
7558         /*
7559          for (size_t i=0;i<what.size();i++)
7560          {long  lab  = GetAny<long>( (*what[i])(stack));
7561          setoflab.insert(lab);
7562          if ( verbosity>3) cout << lab << " ";
7563          all=false;
7564          } */
7565         if (verbosity>3) cout << " Optimized = "<< useopt << ", ";
7566 
7567         const E_F0 * poptiexp0=l->l->optiexp0;
7568         // const E_F0 & optiexpK=*l->l->optiexpK;
7569         int n_where_in_stack_opt=l->l->where_in_stack_opt.size();
7570         R** where_in_stack =0;
7571         if (n_where_in_stack_opt && useopt)
7572         where_in_stack = new R * [n_where_in_stack_opt];
7573         if (where_in_stack)
7574         {
7575             assert(l->l->v.size()==(size_t) n_where_in_stack_opt);
7576             for (int i=0;i<n_where_in_stack_opt;i++)
7577             {
7578                 int offset=l->l->where_in_stack_opt[i];
7579                 assert(offset>10);
7580                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
7581                 *(where_in_stack[i])=0;
7582             }
7583             if(poptiexp0) (*poptiexp0)(stack);
7584 
7585             if( (verbosity/100) && verbosity % 10 == 2)
7586             {
7587                 int il=0;
7588 
7589                 for (LinearOperatorD::const_iterator ll=l->l->v.begin();ll!=l->l->v.end();ll++,il++)
7590                 cout << il << " coef (" << ll->first << ") = " << *(where_in_stack[il]) << " offset=" << l->l->where_in_stack_opt[il] <<endl;
7591 
7592                 for (int i=0;i<n_where_in_stack_opt;i++)
7593                 cout << "const coef " << i << " = " << *(where_in_stack[i]) << endl;
7594             }
7595         }
7596         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
7597 
7598         KN<int>   ip(Vh.MaxNbDFPerElement*6);
7599         if (verbosity >3)
7600         {
7601             if (all) cout << " all " << endl ;
7602             else cout << endl;
7603         }
7604         if(di.islevelset() && (kind !=CDomainOfIntegration::int1d)&& (kind !=CDomainOfIntegration::int2d))
7605         InternalError(" Sorry No levelSet integral for is case ..(5)");
7606 
7607 
7608         if (kind==CDomainOfIntegration::int1d)
7609         {
7610 
7611 
7612             if(VF) InternalError(" no jump or average in int1d of RHS");
7613             if(di.islevelset())
7614             {
7615                 double uset = HUGE_VAL;
7616                 R2 Q[3];
7617                 KN<double> phi(ThI.nv);phi=uset;
7618                 double f[3];
7619                 for(int t=0; t< ThI.nt;++t)
7620                 {
7621                     double umx=-HUGE_VAL,umn=HUGE_VAL;
7622                     for(int i=0;i<3;++i)
7623                     {
7624                         int j= ThI(t,i);
7625                         if( phi[j]==uset)
7626                         {
7627                             MeshPointStack(stack)->setP(&ThI,t,i);
7628                             phi[j]= di.levelset(stack);//zzzz
7629                         }
7630                         f[i]=phi[j];
7631                         umx = std::max(umx,phi[j]);
7632                         umn = std::min(umn,phi[j]);
7633 
7634                     }
7635                     if( umn <=0 && umx >= 0)
7636                     {
7637 
7638                         int np= IsoLineK(f,Q,1e-10);
7639                         if(np==2)
7640                         {
7641                             if ( sameMesh )
7642                             {/*
7643                               void  Element_rhs(const FElement & Kv,const LOperaD &Op,double * p,void * stack,KN_<R> & B,
7644                               const QuadratureFormular1d & FI ,const R2 & PA,const R2 &PB)
7645 
7646                               */
7647                                 Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIE,Q[0],Q[1],useopt);
7648                             }
7649                             else if(!mapt)
7650                             Element_rhs<R>(ThI,ThI[t],Vh,0,ThI[t].lab,*l->l,buf,stack,*B,FIE,false,intmortar,Q,useopt);
7651                             else
7652                             Element_rhs<R>(mapt,ThI,ThI[t],Vh,0,ThI[t].lab,*l->l,buf,stack,*B,FIE,false,intmortar,Q,useopt);
7653 
7654                             //InternalError(" No levelSet on Diff mesh :    to day  int1d of RHS");
7655                         }
7656                         if(sptrclean) sptrclean=sptr->clean();
7657                     }
7658                 }
7659 
7660             }
7661             else
7662             for( int e=0;e<ThI.neb;e++)
7663             {
7664                 if (all || setoflab.find(ThI.bedges[e].lab) != setoflab.end())
7665                 {
7666                     int ie,i =ThI.BoundaryElement(e,ie);
7667                     if ( sameMesh )
7668                     Element_rhs<R>(Vh[i],ie,Th.bedges[e].lab,*l->l,buf,stack,*B,FIE,false,useopt);
7669                     else if(!mapt)
7670                     Element_rhs<R>(ThI,ThI[i],Vh,ie,Th.bedges[e].lab,*l->l,buf,stack,*B,FIE,false,intmortar,0,useopt);
7671                     else
7672                     Element_rhs<R>(mapt,ThI,ThI[i],Vh,ie,Th.bedges[e].lab,*l->l,buf,stack,*B,FIE,false,intmortar,0,useopt);
7673                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7674                 }
7675             }
7676         }
7677         else if (kind==CDomainOfIntegration::intalledges)
7678         {
7679             ffassert(mapt==0);
7680             if(VF)
7681             {
7682                 pair_stack_double bstack(stack,& binside);
7683 
7684                 //bstack.first = stack;
7685                 //bstack.second= & binside;
7686 
7687                 //InternalError(" Today no jump or average in intalledges of RHS ");
7688                 for (int i=0;i< ThI.nt; i++)
7689                 if (all || setoflab.find(ThI[i].lab) != setoflab.end())
7690                 {
7691 
7692                     for (int ie=0;ie<3;ie++)
7693                     if ( sameMesh)
7694                     {
7695                         int iie=ie,ii=Th.ElementAdj(i,iie);
7696                         if(ii<0) ii=i;//  sur le bord
7697                         const Triangle & K(ThI[i]);
7698                         int e0=VerticesOfTriangularEdge[ie][0];
7699                         int e1=VerticesOfTriangularEdge[ie][1];
7700                         int i1 = ThI(K[e0]),i2 = ThI(K[e1]);
7701                         BoundaryEdge * be = ThI.TheBoundaryEdge(i1,i2);
7702                         int lab = be ? be->lab :  notalabel;
7703 
7704                         Element_rhsVF<R>(Vh[i],Vh[ii],ie,iie,lab,*l->l,buf,ip,&bstack,*B,FIE,useopt);
7705                     }
7706                     else
7707                     InternalError("To Do") ;
7708                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7709                 }
7710 
7711             }
7712             else
7713             for (int i=0;i< ThI.nt; i++)
7714             if (all || setoflab.find(ThI[i].lab) != setoflab.end())
7715             {
7716                 for (int ie=0;ie<3;ie++)
7717                 if ( sameMesh)
7718                 Element_rhs<R>(Vh[i],ie,Th[i].lab,*l->l,buf,stack,*B,FIE,true,useopt);
7719                 else
7720                 InternalError("To Do") ;
7721                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7722             }
7723         }
7724         else if (kind==CDomainOfIntegration::intallVFedges)
7725         {
7726             cerr << " intallVFedges a faire" << endl;
7727 
7728             InternalError(" intallVFedges a faire ");
7729 
7730             ffassert(0);
7731             for (int i=0;i< ThI.nt; i++)
7732             {
7733                 if (all || setoflab.find(ThI[i].lab) != setoflab.end())
7734                 for (int ie=0;ie<3;ie++)
7735                 {
7736                     if ( sameMesh)
7737                     Element_rhs<R>(Vh[i],ie,Th[i].lab,*l->l,buf,stack,*B,FIE,true,useopt);
7738                     else
7739                     InternalError("To Do") ;
7740                 }
7741                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7742             }
7743         }
7744 
7745         else if (kind==CDomainOfIntegration::int2d){
7746             if(di.islevelset())
7747             {
7748                 QuadratureFormular FITM(FIT);
7749                 double uset = HUGE_VAL;
7750                 R2 Q[4];
7751                 KN<double> phi(Th.nv);phi=uset;
7752                 double f[3];
7753                 for(int t=0; t< Th.nt;++t)
7754                 {
7755                     if ( all || setoflab.find(ThI[t].lab) != setoflab.end())
7756                     {
7757                         double umx=-HUGE_VAL,umn=HUGE_VAL;
7758                         for(int i=0;i<3;++i)
7759                         {
7760                             int j= ThI(t,i);
7761                             if( phi[j]==uset)
7762                             {
7763                                 MeshPointStack(stack)->setP(&ThI,t,i);
7764                                 phi[j]= di.levelset(stack);//zzzz
7765                             }
7766                             f[i]=phi[j];
7767                             umx = std::max(umx,phi[j]);
7768                             umn = std::min(umn,phi[j]);
7769 
7770                         }
7771                         if( umx <=0 )
7772                         Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIT,useopt);
7773                         else if( umn <0 )
7774                         { // coupe ..
7775                             int i0 = 0, i1 = 1, i2 =2;
7776 
7777                             if( f[i0] > f[i1] ) swap(i0,i1) ;
7778                             if( f[i0] > f[i2] ) swap(i0,i2) ;
7779                             if( f[i1] > f[i2] ) swap(i1,i2) ;
7780 
7781                             double c = (f[i2]-f[i1])/(f[i2]-f[i0]); // coef Up Traing
7782                             if( f[i1] < 0 ) {double y=f[i2]/(f[i2]-f[i1]); c *=y*y; }
7783                             else {double y=f[i0]/(f[i0]-f[i1]) ; c = 1.- (1.-c)*y*y; };
7784                             assert( c > 0 && c < 1);
7785                             double arean = (1-c)*Th[t].area;
7786                             FITM=FIT;
7787                             FITM*=1-c;
7788                             ffassert(mapt==0);
7789                             Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FITM,useopt);
7790                         }
7791                         if(sptrclean) sptrclean=sptr->clean();
7792                     }
7793                 }
7794             }
7795             else
7796             for (int i=0;i< ThI.nt; i++)
7797             if (all || setoflab.find(ThI[i].lab) != setoflab.end())
7798             {
7799                 if ( sameMesh )
7800                 Element_rhs<R>(Vh[i],*l->l,buf,stack,*B,FIT,useopt);
7801                 else if(!mapt)
7802                 Element_rhs<R>(ThI,ThI[i],Vh,*l->l,buf,stack,*B,FIT,useopt);
7803                 else
7804                 Element_rhs<R>(mapt,ThI,ThI[i],Vh,*l->l,buf,stack,*B,FIT,useopt);
7805                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
7806             }
7807         }
7808 
7809         if (n_where_in_stack_opt) delete [] where_in_stack;
7810 
7811     }
7812 
7813 
7814     // creating an instance of AssembleLinearForm
7815     // case 3D volume
7816     template<class R>
AssembleLinearForm(Stack stack,const Mesh3 & Th,const FESpace3 & Vh,KN_<R> * B,const FormLinear * l)7817     void AssembleLinearForm(Stack stack,const Mesh3 & Th,const FESpace3 & Vh,KN_<R> * B,const  FormLinear * l )
7818     {
7819         typedef FESpace3 FESpace;
7820         typedef FESpace3::Mesh Mesh;
7821         typedef Mesh *pmesh ;
7822 
7823         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
7824         bool sptrclean=true;
7825         //     sptr->clean(); // modif FH mars 2006  clean Ptr
7826         Check(l->l,Vh.N);
7827         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleLinearForm size rhs and nb of DF of Vh");
7828         // if ( & Th != &Vh.Th ) ExecError("AssembleLinearForm on different meshes  ( not implemented FH).");
7829         KN<double> buf(Vh.MaximalNbOfDF()*last_operatortype*Vh.N*2);
7830 
7831         //            const  FormLinear * l=dynamic_cast<const  FormLinear *>(e);
7832         const CDomainOfIntegration & di= *l->di;
7833         ffassert(di.d==3);
7834         // const Mesh * pThdi = GetAny<pmesh>( (* di.Th)(stack));
7835 
7836         const Mesh & ThI = Th;// * GetAny<pmesh>( (* di.Th)(stack));
7837         bool sameMesh = &ThI == &Vh.Th;
7838 
7839         SHOWVERB(cout << " FormLinear " << endl);
7840         //const vector<Expression>  & what(di.what);
7841 
7842         CDomainOfIntegration::typeofkind  kind = di.kind;
7843         //const QuadratureFormular1d & FIE = di.FIE(stack);
7844         //  const QuadratureFormular & FIT = di.FIT(stack);
7845         // const GQuadratureFormular<R3> & FIV = di.FIV(stack);
7846 
7847         // const QuadratureFormular1d & FIEo = di.FIE(stack);
7848         const QuadratureFormular & FITo = di.FIT(stack);
7849         const GQuadratureFormular<R3> & FIVo = di.FIV(stack);
7850         //  to change the quadrature on element ... may 2014 FH ..
7851         // QuadratureFormular1d  FIE(FIEo,3);
7852         QuadratureFormular FIT(FITo,3);
7853         GQuadratureFormular<R3>  FIV(FIVo,3);
7854 
7855         const int useopt=di.UseOpt(stack);
7856         double binside=di.binside(stack);  // truc FH pour fluide de grad2 (decentrage bizard)
7857         //  cout << "AssembleLinearForm " << l->l->v.size() << endl;
7858         set<int> setoflab;
7859         bool all=true;
7860         bool VF=l->VF();  // finite Volume or discontinous Galerkin
7861         if (verbosity>2) cout << "  -- AssembleLinearForm 1,  discontinous Galerkin  =" << VF << " binside = "<< binside <<"\n";
7862 
7863         if (verbosity>3)
7864         {
7865             if (CDomainOfIntegration::int2d==kind) cout << "  -- boundary int border ( nQP: "<< FIT.n << ") , samemesh: " << sameMesh << " "   ;
7866             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIT.n << "),"  ;
7867             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIT.n << ")," ;
7868             else cout << "  --  int 3d   (nQP: "<< FIV.n << " ) in "  ;
7869         }
7870         if( di.withmap()) { ExecError(" no map  in the case (5)??");}
7871 
7872         //  if(di.islevelset()) InternalError("So no levelset integration type on this case (3)");
7873         if(di.islevelset() && (CDomainOfIntegration::int2d!=kind) && (CDomainOfIntegration::int3d!=kind) )
7874         InternalError("So no levelset intgeration type on no int2d/3d case");
7875         /*
7876          if ( verbosity>3)
7877          if (kind==CDomainOfIntegration::int1d) cout << "  -- boundary int border " ;
7878          else if (kind==CDomainOfIntegration::intalledges) cout << "  -- boundary int all edges " ;
7879          else if (kind==CDomainOfIntegration::intallVFedges) cout << "  -- boundary int all edges " ;
7880          else cout << "  -- boundary int  " ;
7881          */
7882 
7883         Expandsetoflab(stack,di, setoflab,all);
7884         /*
7885          for (size_t i=0;i<what.size();i++)
7886          if(di.whatis[i] ==0)
7887          {
7888          long  lab  = GetAny<long>( (*what[i])(stack));
7889          setoflab.insert(lab);
7890          if ( verbosity>3) cout << lab << " ";
7891          all=false;
7892          }
7893          else
7894          {
7895          KN<long>  labs( GetAny<KN_<long> >( (*what[i])(stack)));
7896          for (long j=0; j<labs.N(); ++j) {
7897          setoflab.insert(labs[j]);
7898          if ( verbosity>3) cout << labs[j] << " ";
7899          }
7900          all=false;
7901          }*/
7902 
7903         if (verbosity>3) cout << " Optimized = "<< useopt << ", ";
7904 
7905         const E_F0 * poptiexp0=l->l->optiexp0;
7906         // const E_F0 & optiexpK=*l->l->optiexpK;
7907         int n_where_in_stack_opt=l->l->where_in_stack_opt.size();
7908         R** where_in_stack =   0;
7909         if (n_where_in_stack_opt && useopt)
7910         where_in_stack = new R * [n_where_in_stack_opt];
7911         if (where_in_stack)
7912         {
7913             assert(l->l->v.size()==(size_t) n_where_in_stack_opt);
7914             for (int i=0;i<n_where_in_stack_opt;i++)
7915             {
7916                 int offset=l->l->where_in_stack_opt[i];
7917                 assert(offset>10);
7918                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
7919                 *(where_in_stack[i])=0;
7920             }
7921             if(poptiexp0) (*poptiexp0)(stack);
7922 
7923             if( (verbosity/100) && verbosity % 10 == 2)
7924             {
7925                 int il=0;
7926 
7927                 for (LinearOperatorD::const_iterator ll=l->l->v.begin();ll!=l->l->v.end();ll++,il++)
7928                 cout << il << " coef (" << ll->first << ") = " << *(where_in_stack[il]) << " offset=" << l->l->where_in_stack_opt[il] <<endl;
7929 
7930                 for (int i=0;i<n_where_in_stack_opt;i++)
7931                 cout << "const coef " << i << " = " << *(where_in_stack[i]) << endl;
7932             }
7933         }
7934         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
7935 
7936         KN<int>   ip(Vh.MaxNbDFPerElement*6);
7937         if (verbosity >3)
7938         {
7939             if (all) cout << " all " << endl ;
7940             else cout << endl;
7941         }
7942         if (kind==CDomainOfIntegration::int2d)
7943         { //AFAIRE("3D Elment RHS CDomainOfIntegration::int2d");
7944             double  ss =0;
7945             if(VF) InternalError(" no jump or average in int1d of RHS");
7946             if(di.islevelset()) // init on level set (of RHS)
7947             {
7948                 double uset = HUGE_VAL;
7949                 R3 Q[4];
7950                 KN<double> phi(ThI.nv);phi=uset;
7951                 double f[4];
7952                 for(int t=0; t< ThI.nt;++t)
7953                 {
7954 
7955                     double umx=-HUGE_VAL,umn=HUGE_VAL;
7956                     for(int i=0;i<4;++i)
7957                     {
7958                         int j= ThI(t,i);
7959                         if( phi[j]==uset)
7960                         {
7961                             MeshPointStack(stack)->setP(&ThI,t,i);
7962                             phi[j]= di.levelset(stack);//zzzz
7963                         }
7964                         f[i]=phi[j];
7965                         umx = std::max(umx,phi[j]);
7966                         umn = std::min(umn,phi[j]);
7967 
7968                     }
7969                     if( umn <=0 && umx >= 0)
7970                     {
7971 
7972                         int np= IsoLineK(f,Q,1e-10);// ca code ...
7973                         if(np==3 || np==4)
7974                         {  //  if(np==3) Q[3]=Q[0]; // same 0 == 3 bofbof ??? FH
7975                             //   cout << " Q[0]" << Q[0] << endl;
7976                             if( verbosity> 99)
7977                             {
7978                                 R3 PP[4];
7979                                 const Tet  &K(ThI[t]);
7980                                 for(int i=0; i< np; ++i)
7981                                 PP[i]= K(Q[i]);
7982                                 for( int i =0; i+1 < np; i+=2)
7983                                 {
7984                                     int i0=i,i1=i+1,i2=(i+2)%np;
7985                                     R3 NN= R3(PP[i0],PP[i1])^R3(PP[i0],PP[i2]);
7986                                     double mes2 = (NN,NN);
7987                                     double mes = sqrt(mes2)/2;
7988                                     ss+= mes;
7989                                     //cout << "mes " << mes << " " << i << " , ";
7990                                 }
7991                             }
7992 
7993                             if ( sameMesh)
7994                             Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIT,np,Q,useopt);
7995                             else
7996                             //    else
7997                             InternalError(" No levelSet on Diff mesh3 :    to day  int2d of RHS");
7998                             //    Element_rhs<R>(ThI,ThI[t],Vh,-1,lab,*l->l,buf,stack,*B,FIT,false);
7999                         }
8000                         if(sptrclean) sptrclean=sptr->clean();
8001                     }
8002                 }
8003                 if( verbosity> 99)
8004                 cout << "          surf levelset = " << ss << endl;
8005 
8006             }
8007             else
8008             for( int e=0;e<ThI.nbe;e++)
8009             {
8010                 if (all || setoflab.find(ThI.be(e).lab) != setoflab.end())
8011                 {
8012                     int ie,i =ThI.BoundaryElement(e,ie);
8013                     if ( sameMesh)
8014                     Element_rhs<R>(Vh[i],ie,Th.be(e).lab,*l->l,buf,stack,*B,FIT,false,useopt);
8015                     else
8016                     Element_rhs<R>(ThI,ThI[i],Vh,ie,Th.be(e).lab,*l->l,buf,stack,*B,FIT,false,useopt);
8017                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8018                 }
8019             }
8020         }
8021         else if (kind==CDomainOfIntegration::intalledges)
8022         {     AFAIRE("3D Elment RHS CDomainOfIntegration::intalledges");
8023             /*
8024              if(VF)
8025              {
8026              pair_stack_double bstack;
8027 
8028              bstack.first = stack;
8029              bstack.second= & binside;
8030 
8031              //InternalError(" Today no jump or average in intalledges of RHS ");
8032              for (int i=0;i< ThI.nt; i++)
8033              if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8034              {
8035 
8036              for (int ie=0;ie<3;ie++)
8037              if ( sameMesh)
8038              {
8039              int iie=ie,ii=Th.ElementAdj(i,iie);
8040              if(ii<0) ii=i;//  sur le bord
8041              Element_rhsVF<R>(Vh[i],Vh[ii],ie,iie,Th[i].lab,*l->l,buf,ip,&bstack,*B,FIE);
8042              }
8043              else
8044              InternalError("To Do") ;
8045              if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8046              }
8047 
8048              }
8049              else
8050              for (int i=0;i< ThI.nt; i++)
8051              if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8052              {
8053              for (int ie=0;ie<3;ie++)
8054              if ( sameMesh)
8055              Element_rhs<R>(Vh[i],ie,Th[i].lab,*l->l,buf,stack,*B,FIE,true);
8056              else
8057              InternalError("To Do") ;
8058              if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8059              }*/
8060         }
8061         else if (kind==CDomainOfIntegration::intallVFedges)
8062         {
8063             cerr << " intallVFedges a faire" << endl;
8064 
8065             InternalError(" intallVFedges a faire ");
8066 
8067             ffassert(0);/*
8068                          for (int i=0;i< ThI.nt; i++)
8069                          {
8070                          if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8071                          for (int ie=0;ie<3;ie++)
8072                          if ( sameMesh)
8073                          Element_rhs<R>(Vh[i],ie,Th[i].lab,*l->l,buf,stack,*B,FIE,true);
8074                          else
8075                          InternalError("To Do") ;
8076                          if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8077 
8078                          }*/
8079         }
8080 
8081         else if(kind==CDomainOfIntegration::int3d) {
8082             if(di.islevelset())  //  may 2014 FH ...
8083             {   // int3d levelset < 0
8084                 double llevelset = 0;
8085                 const double uset = std::numeric_limits<double>::max();
8086                 // cout << " uset ="<<uset << endl;
8087                 R3 Q[3][4];
8088                 double vol6[3];
8089                 KN<double> phi(Th.nv);
8090                 phi=uset;
8091                 double f[4];
8092 
8093                 for (int t=0;t< Th.nt; t++)
8094                 {
8095 
8096                     const Mesh3::Element & K(ThI[t]);
8097                     if (all || setoflab.find(ThI[t].lab) != setoflab.end())
8098 
8099                     {
8100                         double umx=std::numeric_limits<double>::min(),umn=std::numeric_limits<double>::max();
8101                         for(int i=0;i<4;++i)
8102                         {
8103                             int j= ThI(t,i);
8104                             if( phi[j]==uset)
8105                             {
8106                                 MeshPointStack(stack)->setP(&ThI,t,i);
8107                                 phi[j]= di.levelset(stack);//zzzz
8108                             }
8109                             f[i]=phi[j];
8110                         }
8111                         int ntets= UnderIso(f,Q, vol6,1e-14);
8112                         setQF<R3>(FIV,FIVo,QuadratureFormular_Tet_1, Q,vol6,ntets);
8113                         if(FIV.n)
8114                         {
8115                             if ( sameMesh )
8116                             Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIV,useopt);
8117                             else
8118                             Element_rhs<R>(ThI,ThI[t],Vh,*l->l,buf,stack,*B,FIV,useopt);
8119                             if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8120 
8121                         }
8122                     }
8123                 }
8124                 FIV=FIVo;
8125             }
8126             else
8127             {
8128 
8129                 for (int i=0;i< ThI.nt; i++)
8130                 if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8131                 {
8132                     if ( sameMesh )
8133                     Element_rhs<R>(Vh[i],*l->l,buf,stack,*B,FIV,useopt);
8134                     else
8135                     Element_rhs<R>(ThI,ThI[i],Vh,*l->l,buf,stack,*B,FIV,useopt);
8136                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8137                 }}
8138         }
8139         else  if(kind==CDomainOfIntegration::intallfaces    ) {
8140 
8141             if(VF) InternalError(" no jump or average in intallfaces of RHS");
8142 
8143             for(int i=0;i<ThI.nt; i++)
8144             for(int ie=0;ie<Mesh3::nea; ie++)
8145             {
8146                 int lab=0;
8147                 // if face on bord get the lab ???
8148                 if ( sameMesh)
8149                 Element_rhs<R>(Vh[i],ie,lab,*l->l,buf,stack,*B,FIT,false,useopt);
8150                 else
8151                 Element_rhs<R>(ThI,ThI[i],Vh,ie,lab,*l->l,buf,stack,*B,FIT,false,useopt);
8152                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8153 
8154             }
8155         }
8156         else
8157         {
8158             cout << " Strange (unknows) kind = " << kind << endl;
8159             ffassert(0);
8160         }
8161         if (n_where_in_stack_opt) delete [] where_in_stack;
8162 
8163     }
8164 
8165 
8166 
8167 
8168 
8169 
8170 
8171 // creating an instance of AssembleLinearForm
8172 // case surface 3d
8173 template<class R>
AssembleLinearForm(Stack stack,const MeshS & Th,const FESpaceS & Vh,KN_<R> * B,const FormLinear * l)8174 void AssembleLinearForm(Stack stack,const MeshS & Th,const FESpaceS & Vh,KN_<R> * B,const  FormLinear * l )
8175     {
8176 
8177         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
8178         bool sptrclean=true;
8179         //     sptr->clean(); // modif FH mars 2006  clean Ptr
8180         Check(l->l,Vh.N);
8181         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleLinearForm size rhs and nb of DF of Vh");
8182         // if ( & Th != &Vh.Th ) ExecError("AssembleLinearForm on different meshes  ( not implemented FH).");
8183         KN<double> buf(Vh.MaximalNbOfDF()*last_operatortype*Vh.N*2);
8184 
8185         //            const  FormLinear * l=dynamic_cast<const  FormLinear *>(e);
8186         const CDomainOfIntegration & di= *l->di;
8187         ffassert(di.d==3);
8188 
8189         const MeshS & ThI = Th;// * GetAny<pmesh>( (* di.Th)(stack));
8190         bool sameMesh = &ThI == &Vh.Th;
8191 
8192         const bool intmortar=di.intmortar(stack);
8193 
8194         SHOWVERB(cout << " FormLinear " << endl);
8195         // const vector<Expression>  & what(di.what);
8196 
8197         CDomainOfIntegration::typeofkind  kind = di.kind;
8198         const QuadratureFormular1d & FIE = di.FIE(stack);
8199         const QuadratureFormular & FIT = di.FIT(stack);
8200         const int useopt=di.UseOpt(stack);
8201         double binside=di.binside(stack);  // truc FH pour fluide de grad2 (decentrage bizard)
8202         //  cout << "AssembleLinearForm " << l->l->v.size() << endl;
8203         set<int> setoflab;
8204         bool all=true;
8205         bool VF=l->VF();  // finite Volume or discontinous Galerkin
8206 
8207         if (verbosity>2) cout << "  -- AssembleLinearForm S, discontinous Galerkin  =" << VF << " binside = "<< binside
8208             << " levelset integration " <<di.islevelset()<< " withmap: "<<  di.withmap() << "\n";
8209         //  if( di.withmap()) { ExecError(" no map  in the case (6)??");}
8210         Expression  const * const mapt=di.mapt[0] ? di.mapt:0;
8211         sameMesh = sameMesh && !mapt; //
8212 
8213         if (verbosity>3)
8214         {
8215 
8216             if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ";
8217             else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
8218             else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
8219             else cout << "  --  int 2d  (nQP: "<< FIT.n << " ) in "  ;
8220             cout << ", samemesh :"<< sameMesh<< " int mortar: " << intmortar ;
8221         }
8222          if(di.islevelset() && ( (CDomainOfIntegration::int1d!=kind) && (CDomainOfIntegration::int2d!=kind) )  )
8223             InternalError("So no levelset integration type on no int1d/int2d case (4)");
8224         Expandsetoflab(stack,di, setoflab,all);
8225          if (verbosity>3) cout << " Optimized = "<< useopt << ", ";
8226         const E_F0 * poptiexp0=l->l->optiexp0;
8227         // const E_F0 & optiexpK=*l->l->optiexpK;
8228         int n_where_in_stack_opt=l->l->where_in_stack_opt.size();
8229         R** where_in_stack =0;
8230         if (n_where_in_stack_opt && useopt)
8231             where_in_stack = new R * [n_where_in_stack_opt];
8232         if (where_in_stack)
8233         {
8234             assert(l->l->v.size()==(size_t) n_where_in_stack_opt);
8235             for (int i=0;i<n_where_in_stack_opt;i++)
8236             {
8237                 int offset=l->l->where_in_stack_opt[i];
8238                 assert(offset>10);
8239                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
8240                 *(where_in_stack[i])=0;
8241             }
8242             if(poptiexp0) (*poptiexp0)(stack);
8243 
8244             if( (verbosity/100) && verbosity % 10 == 2)
8245             {
8246                 int il=0;
8247 
8248                 for (LinearOperatorD::const_iterator ll=l->l->v.begin();ll!=l->l->v.end();ll++,il++)
8249                     cout << il << " coef (" << ll->first << ") = " << *(where_in_stack[il]) << " offset=" << l->l->where_in_stack_opt[il] <<endl;
8250 
8251                 for (int i=0;i<n_where_in_stack_opt;i++)
8252                     cout << "const coef " << i << " = " << *(where_in_stack[i]) << endl;
8253             }
8254         }
8255         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
8256 
8257         KN<int>   ip(Vh.MaxNbDFPerElement*6);
8258         if (verbosity >3)
8259         {
8260             if (all) cout << " all " << endl ;
8261             else cout << endl;
8262         }
8263         if(di.islevelset() && (kind !=CDomainOfIntegration::int1d)&& (kind !=CDomainOfIntegration::int2d))
8264             InternalError(" Sorry No levelSet integral for is case ..(5)");
8265 
8266 
8267         if (kind==CDomainOfIntegration::int1d)
8268         {
8269 
8270 
8271             if(VF) InternalError(" no jump or average in int1d of RHS");
8272             if(di.islevelset())
8273             {
8274                 double uset = HUGE_VAL;
8275                 R2 Q[3];
8276                 KN<double> phi(ThI.nv);phi=uset;
8277                 double f[3];
8278                 for(int t=0; t< ThI.nt;++t)
8279                 {
8280                     double umx=-HUGE_VAL,umn=HUGE_VAL;
8281                     for(int i=0;i<3;++i)
8282                     {
8283                         int j= ThI(t,i);
8284                         if( phi[j]==uset)
8285                         {
8286                             MeshPointStack(stack)->setP(&ThI,t,i);
8287                             phi[j]= di.levelset(stack);//zzzz
8288                         }
8289                         f[i]=phi[j];
8290                         umx = std::max(umx,phi[j]);
8291                         umn = std::min(umn,phi[j]);
8292 
8293                     }
8294                     if( umn <=0 && umx >= 0)
8295                     {
8296 
8297                         int np= IsoLineK(f,Q,1e-10);
8298                         if(np==2)
8299                         {
8300                             if ( sameMesh )
8301                             {/*
8302                               void  Element_rhs(const FElement & Kv,const LOperaD &Op,double * p,void * stack,KN_<R> & B,
8303                               const QuadratureFormular1d & FI ,const R2 & PA,const R2 &PB)
8304 
8305                               */
8306                                 Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIE,Q[0],Q[1],useopt);
8307                             }
8308                             else if(!mapt)
8309                             Element_rhs<R>(ThI,ThI[t],Vh,0,ThI[t].lab,*l->l,buf,stack,*B,FIE,false,intmortar,Q,useopt);
8310                             else
8311                             ffassert(0); //Element_rhs<R>(mapt,ThI,ThI[t],Vh,0,ThI[t].lab,*l->l,buf,stack,*B,FIE,false,intmortar,Q,useopt);
8312 
8313                             //InternalError(" No levelSet on Diff mesh :    to day  int1d of RHS");
8314                         }
8315                         if(sptrclean) sptrclean=sptr->clean();
8316                     }
8317                 }
8318 
8319             }
8320             else
8321                 for( int e=0;e<ThI.nbe;e++)
8322                 {
8323                     if (all || setoflab.find(ThI.be(e).lab) != setoflab.end())
8324                     {
8325                         int ie,i =ThI.BoundaryElement(e,ie);
8326                         if ( sameMesh )
8327                         Element_rhs<R>(Vh[i],ie,Th.be(e).lab,*l->l,buf,stack,*B,FIE,false,useopt);
8328                         else if(!mapt)
8329                         Element_rhs<R>(ThI,ThI[i],Vh,ie,Th.be(e).lab,*l->l,buf,stack,*B,FIE,false,intmortar,0,useopt);
8330                         else
8331                             ffassert(0);//Element_rhs<R>(mapt,ThI,ThI[i],Vh,ie,Th.be(e).lab,*l->l,buf,stack,*B,FIE,false,intmortar,0,useopt);
8332                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8333                     }
8334                 }
8335         }
8336         else if (kind==CDomainOfIntegration::intalledges)
8337         {
8338             ffassert(mapt==0);
8339             cerr << " intalledges on fespaceS (to do) " << endl;
8340             InternalError(" intalledges (to do) ");
8341             ffassert(0);
8342 
8343             /*if(VF)   code 2d .... ici
8344             {
8345                 pair_stack_double bstack(stack,& binside);
8346 
8347                 //bstack.first = stack;
8348                 //bstack.second= & binside;
8349 
8350                 //InternalError(" Today no jump or average in intalledges of RHS ");
8351                 for (int i=0;i< ThI.nt; i++)
8352                     if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8353                     {
8354 
8355                         for (int ie=0;ie<3;ie++)
8356                             if ( sameMesh)
8357                             {
8358                                 int iie=ie,ii=Th.ElementAdj(i,iie);
8359                                 if(ii<0) ii=i;//  sur le bord
8360                                 const TriangleS & K(ThI[i]);
8361                                 int e0=VerticesOfTriangularEdge[ie][0];
8362                                 int e1=VerticesOfTriangularEdge[ie][1];
8363                                 int i1 = ThI(K[e0]),i2 = ThI(K[e1]);
8364                                 BoundaryEdge * be = ThI.TheBoundaryEdge(i1,i2);
8365                                 int lab = be ? be->lab :  notalabel;
8366 
8367                                 Element_rhsVF<R>(Vh[i],Vh[ii],ie,iie,lab,*l->l,buf,ip,&bstack,*B,FIE,useopt);
8368                             }
8369                             else
8370                                 InternalError("To Do") ;
8371                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8372                 }
8373 
8374             }
8375             else
8376                 for (int i=0;i< ThI.nt; i++)
8377                     if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8378                     {
8379                         for (int ie=0;ie<3;ie++)
8380                             if ( sameMesh)
8381                             Element_rhs<R>(Vh[i],ie,Th[i].lab,*l->l,buf,stack,*B,FIE,true,useopt);
8382                             else
8383                                 InternalError("To Do") ;
8384                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8385                     }*/
8386         }
8387         else if (kind==CDomainOfIntegration::intallVFedges)
8388         {
8389             cerr << " intallVFedges a faire" << endl;
8390 
8391             InternalError(" intallVFedges a faire ");
8392 
8393             ffassert(0);
8394             for (int i=0;i< ThI.nt; i++)
8395             {
8396                 if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8397                     for (int ie=0;ie<3;ie++)
8398                     {
8399                         if ( sameMesh)
8400                         Element_rhs<R>(Vh[i],ie,Th[i].lab,*l->l,buf,stack,*B,FIE,true,useopt);
8401                         else
8402                             InternalError("To Do") ;
8403                     }
8404                 if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8405             }
8406         }
8407 
8408         else if (kind==CDomainOfIntegration::int2d){
8409             if(di.islevelset())
8410             {
8411                 QuadratureFormular FITM(FIT);
8412                 double uset = HUGE_VAL;
8413                 R2 Q[4];
8414                 KN<double> phi(Th.nv);phi=uset;
8415                 double f[3];
8416                 for(int t=0; t< Th.nt;++t)
8417                 {
8418                     if ( all || setoflab.find(ThI[t].lab) != setoflab.end())
8419                     {
8420                         double umx=-HUGE_VAL,umn=HUGE_VAL;
8421                         for(int i=0;i<3;++i)
8422                         {
8423                             int j= ThI(t,i);
8424                             if( phi[j]==uset)
8425                             {
8426                                 MeshPointStack(stack)->setP(&ThI,t,i);
8427                                 phi[j]= di.levelset(stack);//zzzz
8428                             }
8429                             f[i]=phi[j];
8430                             umx = std::max(umx,phi[j]);
8431                             umn = std::min(umn,phi[j]);
8432 
8433                         }
8434                         if( umx <=0 )
8435                         {Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIT,useopt);}
8436                         else if( umn <0 )
8437                         { // coupe ..
8438                             int i0 = 0, i1 = 1, i2 =2;
8439 
8440                             if( f[i0] > f[i1] ) swap(i0,i1) ;
8441                             if( f[i0] > f[i2] ) swap(i0,i2) ;
8442                             if( f[i1] > f[i2] ) swap(i1,i2) ;
8443 
8444                             double c = (f[i2]-f[i1])/(f[i2]-f[i0]); // coef Up Traing
8445                             if( f[i1] < 0 ) {double y=f[i2]/(f[i2]-f[i1]); c *=y*y; }
8446                             else {double y=f[i0]/(f[i0]-f[i1]) ; c = 1.- (1.-c)*y*y; };
8447                             assert( c > 0 && c < 1);
8448                             double arean = (1-c)*Th[t].mesure();
8449                             FITM=FIT;
8450                             FITM*=1-c;
8451                             ffassert(mapt==0);
8452                             Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FITM,useopt);
8453                         }
8454                         if(sptrclean) sptrclean=sptr->clean();
8455                     }
8456                 }
8457             }
8458             else {
8459                 for (int i=0;i< ThI.nt; i++)
8460                     if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8461                     {
8462                         if ( sameMesh )
8463                         Element_rhs<R>(Vh[i],*l->l,buf,stack,*B,FIT,useopt);
8464                         else
8465                         Element_rhs<R>(ThI,ThI[i],Vh,*l->l,buf,stack,*B,FIT,useopt);
8466 
8467                         if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8468                     } }
8469         }
8470 
8471         if (n_where_in_stack_opt) delete [] where_in_stack;
8472 
8473     }
8474 
8475     // creating an instance of AssembleLinearForm
8476     // case 3d curve
8477     template<class R>
AssembleLinearForm(Stack stack,const MeshL & Th,const FESpaceL & Vh,KN_<R> * B,const FormLinear * l)8478     void AssembleLinearForm(Stack stack,const MeshL & Th,const FESpaceL & Vh,KN_<R> * B,const  FormLinear * l )
8479     {
8480 
8481         StackOfPtr2Free * sptr = WhereStackOfPtr2Free(stack);
8482         bool sptrclean=true;
8483         //     sptr->clean(); // modif FH mars 2006  clean Ptr
8484         Check(l->l,Vh.N);
8485         if ( B && B->N() != Vh.NbOfDF) ExecError("AssembleLinearForm size rhs and nb of DF of Vh");
8486         // if ( & Th != &Vh.Th ) ExecError("AssembleLinearForm on different meshes  ( not implemented FH).");
8487         KN<double> buf(Vh.MaximalNbOfDF()*last_operatortype*Vh.N*2);
8488         const CDomainOfIntegration & di= *l->di;
8489         ffassert(di.d==3);
8490 
8491         const MeshL & ThI = Th;
8492         bool sameMesh = &ThI == &Vh.Th;
8493 
8494         const bool intmortar=di.intmortar(stack);
8495 
8496         SHOWVERB(cout << " FormLinear " << endl);
8497         // const vector<Expression>  & what(di.what);
8498 
8499         CDomainOfIntegration::typeofkind  kind = di.kind;
8500         const GQuadratureFormular<R1> & FIT = di.FIE(stack);
8501         //const QuadratureFormular & FIT = di.FIT(stack);
8502         const int useopt=di.UseOpt(stack);
8503         double binside=di.binside(stack);  // truc FH pour fluide de grad2 (decentrage bizard)
8504         //  cout << "AssembleLinearForm " << l->l->v.size() << endl;
8505         set<int> setoflab;
8506         bool all=true;
8507         bool VF=l->VF();  // finite Volume or discontinous Galerkin
8508 
8509         if (verbosity>2) cout << "  -- AssembleLinearForm S, discontinous Galerkin  =" << VF << " binside = "<< binside
8510             << " levelset integration " <<di.islevelset()<< " withmap: "<<  di.withmap() << "\n";
8511         //  if( di.withmap()) { ExecError(" no map  in the case (6)??");}
8512         Expression  const * const mapt=di.mapt[0] ? di.mapt:0;
8513         sameMesh = sameMesh && !mapt; //
8514 
8515         if(di.islevelset() && CDomainOfIntegration::int1d!=kind   )
8516             InternalError("So no levelset integration type on no int1d/int2d case (4)");
8517         Expandsetoflab(stack,di, setoflab,all);
8518         if (verbosity>3) cout << " Optimized = "<< useopt << ", ";
8519         const E_F0 * poptiexp0=l->l->optiexp0;
8520         // const E_F0 & optiexpK=*l->l->optiexpK;
8521         int n_where_in_stack_opt=l->l->where_in_stack_opt.size();
8522         R** where_in_stack =0;
8523         if (n_where_in_stack_opt && useopt)
8524             where_in_stack = new R * [n_where_in_stack_opt];
8525         if (where_in_stack)
8526         {
8527             assert(l->l->v.size()==(size_t) n_where_in_stack_opt);
8528             for (int i=0;i<n_where_in_stack_opt;i++)
8529             {
8530                 int offset=l->l->where_in_stack_opt[i];
8531                 assert(offset>10);
8532                 where_in_stack[i]= static_cast<R *>(static_cast<void *>((char*)stack+offset));
8533                 *(where_in_stack[i])=0;
8534             }
8535             if(poptiexp0) (*poptiexp0)(stack);
8536 
8537             if( (verbosity/100) && verbosity % 10 == 2)
8538             {
8539                 int il=0;
8540 
8541                 for (LinearOperatorD::const_iterator ll=l->l->v.begin();ll!=l->l->v.end();ll++,il++)
8542                     cout << il << " coef (" << ll->first << ") = " << *(where_in_stack[il]) << " offset=" << l->l->where_in_stack_opt[il] <<endl;
8543 
8544                 for (int i=0;i<n_where_in_stack_opt;i++)
8545                     cout << "const coef " << i << " = " << *(where_in_stack[i]) << endl;
8546             }
8547         }
8548         Stack_Ptr<R*>(stack,ElemMatPtrOffset) =where_in_stack;
8549 
8550         KN<int>   ip(Vh.MaxNbDFPerElement*6);
8551         if (verbosity >3)
8552         {
8553             if (all) cout << " all " << endl ;
8554             else cout << endl;
8555         }
8556         if(di.islevelset() && (kind !=CDomainOfIntegration::int1d))
8557             InternalError(" Sorry No levelSet integral for is case ..(5)");
8558 
8559         if (kind==CDomainOfIntegration::int1d){
8560 
8561             if(VF) InternalError(" no jump or average in int1d of RHS");
8562             if(di.islevelset())
8563             {cout << " ok di.islevelset() " << di.islevelset() << endl;}
8564                /* double uset = HUGE_VAL;
8565                 R1 Q[2];
8566                 KN<double> phi(ThI.nv);phi=uset;
8567                 double f[2];
8568                 for(int t=0; t< ThI.nt;++t)
8569                 {
8570                     double umx=-HUGE_VAL,umn=HUGE_VAL;
8571                     for(int i=0;i<3;++i)
8572                     {
8573                         int j= ThI(t,i);
8574                         if( phi[j]==uset)
8575                         {
8576                             MeshPointStack(stack)->setP(&ThI,t,i);
8577                             phi[j]= di.levelset(stack);//zzzz
8578                         }
8579                         f[i]=phi[j];
8580                         umx = std::max(umx,phi[j]);
8581                         umn = std::min(umn,phi[j]);
8582 
8583                     }
8584                     if( umn <=0 && umx >= 0)
8585                     {
8586 
8587                         int np= IsoLineK(f,Q,1e-10);
8588                         if(np==2)
8589                         {
8590                             if ( sameMesh )
8591                             {
8592                            Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIE,Q[0],Q[1],useopt);
8593                             }
8594                             else if(!mapt)
8595                                 Element_rhs<R>(ThI,ThI[t],Vh,0,ThI[t].lab,*l->l,buf,stack,*B,FIE,false,intmortar,Q,useopt);
8596                             else
8597                                 ffassert(0); //Element_rhs<R>(mapt,ThI,ThI[t],Vh,0,ThI[t].lab,*l->l,buf,stack,*B,FIE,false,intmortar,Q,useopt);
8598 
8599                             //InternalError(" No levelSet on Diff mesh :    to day  int1d of RHS");
8600                         }
8601                         if(sptrclean) sptrclean=sptr->clean();
8602                     }
8603                 }
8604 
8605             }
8606             else*/
8607 
8608             for (int i=0;i< ThI.nt; i++)
8609                 if (all || setoflab.find(ThI[i].lab) != setoflab.end())
8610                 {
8611                     if ( sameMesh )
8612                         Element_rhs<R>(Vh[i],*l->l,buf,stack,*B,FIT,useopt);
8613                     else
8614                         Element_rhs<R>(ThI,ThI[i],Vh,*l->l,buf,stack,*B,FIT,useopt);
8615 
8616                     if(sptrclean) sptrclean=sptr->clean(); // modif FH mars 2006  clean Ptr
8617                 }
8618 
8619 
8620         }
8621 
8622         if (n_where_in_stack_opt) delete [] where_in_stack;
8623 
8624     }
8625 
8626 
8627 }// END of NameSpace Fem2D
8628 
8629 
isVF(const list<C_F0> & largs)8630 bool isVF(const list<C_F0> & largs)  // true => VF type of Matrix
8631 {
8632     list<C_F0>::const_iterator ii,ib=largs.begin(),
8633     ie=largs.end();
8634 
8635     bool VVF =false;
8636     int kk=0,err=0;
8637 
8638     for (ii=ib;ii != ie;ii++)
8639     {
8640         kk++;
8641         Expression e=ii->LeftValue();
8642         aType r = ii->left();
8643         if (r==atype<const  FormBilinear *>())
8644         {
8645             const  FormBilinear * bb=dynamic_cast<const  FormBilinear *>(e);
8646             bool vvf  = bb->VF();
8647             if( vvf &&  (bb->di->kind != CDomainOfIntegration::intalledges && bb->di->kind != CDomainOfIntegration::intallVFedges  )
8648                &&  (bb->di->kind != CDomainOfIntegration::intallfaces ))
8649             {
8650                 if(err==0) cerr << "\n\n";
8651                 cerr << " ** Fatal error in term "<< kk << " of the varf form (integral, on , ... ) " << endl;
8652                 err++;
8653             }
8654             VVF = vvf || VVF;
8655         }
8656     }
8657     if(err)
8658     {
8659         cerr << " ** number  " << err << " of  error the varf form, with " << kk << " terms "<< endl;
8660         CompileError("Sorry, no  jump, mean, otherside in bilinear term must be in integral of type  intalledges,  intallVFedges or intallfaces");
8661     }
8662     return VVF;
8663 }
8664 
8665 
isSameMesh(const list<C_F0> & largs,const void * Thu,const void * Thv,Stack stack)8666 bool isSameMesh(const list<C_F0> & largs,const void * Thu,const void * Thv,Stack stack)  // true => VF type of Matrix
8667 {
8668     if( Thv != Thu ) return false;
8669     list<C_F0>::const_iterator ii,ib=largs.begin(),
8670     ie=largs.end();
8671 
8672     // bool VVF =false;
8673     for (ii=ib;ii != ie;ii++)
8674     {
8675         Expression e=ii->LeftValue();
8676         aType r = ii->left();
8677         if (r==atype<const  FormBilinear *>())
8678         {
8679             const  FormBilinear * bb=dynamic_cast<const  FormBilinear *>(e);
8680             const void *  Thbf = GetAny<const void *>((*bb->di->Th)(stack));
8681             if (Thbf != Thu) return false;
8682         }
8683         else if (r==atype<const  FormLinear *>())
8684         {
8685             const  FormLinear * bb=dynamic_cast<const  FormLinear *>(e);
8686             const void * Thbf = GetAny<const void *>((*bb->di->Th)(stack));
8687             if (Thbf != Thu) return false;
8688         }
8689     }
8690     return true;
8691 }
8692 
8693 template<class R,class FESpace,class v_fes>
InitProblem(int Nb,const FESpace & Uh,const FESpace & Vh,KN<R> * & B,KN<R> * & X,vector<pair<FEbase<R,v_fes> *,int>> & u_hh,Data_Sparse_Solver * ds,vector<FEbase<R,v_fes> * > & u_h,const FESpace ** LL,bool initx)8694 void InitProblem( int Nb, const FESpace & Uh,
8695                  const FESpace & Vh,
8696                  KN<R> *&B,KN<R> *&X,vector<  pair< FEbase<R,v_fes> * ,int> > &u_hh,
8697                  Data_Sparse_Solver    *ds ,//    *typemat ,
8698                  vector<  FEbase<R,v_fes> *  > & u_h,const FESpace ** LL, bool initx )
8699 {
8700     typedef typename  FESpace::Mesh Mesh;
8701     typedef typename  FESpace::FElement FElement;
8702     typedef typename  Mesh::Element Element;
8703     typedef typename  Mesh::Vertex Vertex;
8704     typedef typename  Mesh::RdHat RdHat;
8705     typedef typename  Mesh::Rd Rd;
8706 
8707     *B=R();
8708 
8709     //  bool initx = typemat->t==TypeSolveMat::GC;
8710 
8711     const  Mesh & Th(Uh.Th);
8712 
8713     if (initx)
8714     {
8715         if (!X || (X =B) )
8716         X=new KN<R>(B->N());
8717         const FEbase<R,v_fes> & u_h0 = *(u_h[0]);
8718         const FESpace  * u_Vh = u_h0.Vh ;
8719 
8720         if ( u_Vh==0  || &((u_h[0])->Vh->Th) != &Th )
8721         {
8722             *X=R();
8723             if(verbosity>1)
8724             cout << "   -- Change of Mesh " << (u_Vh ? & (*(u_h[0])).Vh->Th: 0 )
8725             << "  " << &Th <<  endl;
8726         }
8727         else
8728         { //  copy the previous soluton to initialize CG, GMRES, etc ...
8729             if (Nb==1)
8730             {  // modif  FH 0701/2005 + april 2006
8731                 if(u_h[0]->x()->N() != X->N() )
8732                 cout << " bug ???? " << endl;
8733                 if (u_h[0]->x() && u_h[0]->x()->N() == X->N() )
8734                 *X= * u_h[0]->x();
8735                 else
8736                 *X=R();
8737             }
8738             else { // dispatch the solution
8739                 const FElement ** sK= new const FElement * [Nb];
8740                 KN<R> ** sol= new KN<R> * [Nb];
8741                 for (int i=0;i<Nb;i++) {
8742 
8743                     sol[i] = (*(u_h[i])).x() ;
8744                 }
8745 
8746                 for (int it=0;it<Th.nt;it++)
8747                 {
8748                     const FElement K(Uh[it]);
8749                     const int nbdf=K.NbDoF();
8750                     for (int i=0;i<Nb;i++)
8751                     sK[i]= new FElement( (*LL[i])[it]) ;
8752                     for (int df=0;df< nbdf;df++)
8753                     {  int kfe=K.FromFE(df);
8754                         int kdf=K.FromDF(df);
8755                         if (sol[kfe]) {
8756                             const FElement & SK(*sK[kfe]);
8757                             (*X)[K(df)]= (*sol[kfe])[SK(kdf)] ;
8758                         }
8759                         else (*X)[K(df)]= R();
8760                     }
8761                     for (int i=0;i<Nb;i++)
8762                     delete sK[i];
8763                 }
8764                 delete [] sol;
8765                 delete [] sK;
8766             }}
8767     }
8768 
8769 
8770 }
8771 
8772 
8773 
8774 template<class R>
DefSolverCadna(Stack stack,MatriceCreuse<R> & A,Data_Sparse_Solver & ds)8775  MatriceCreuse<typename CadnaType<R>::Scalaire> * DefSolverCadna(
8776   Stack stack,
8777   MatriceCreuse<R>  & A,
8778   Data_Sparse_Solver & ds
8779 /*  long NbSpace ,
8780   long itmax,
8781   double & eps,
8782   bool initmat,
8783   int strategy,
8784   const OneOperator *precon,
8785   double tgv,
8786   double tol_pivot, double tol_pivot_sym
8787 */
8788 )
8789 {
8790    typedef typename CadnaType<R>::Scalaire R_st;
8791     /*
8792  //  MatriceCreuse<R_st> *CadnaMat;
8793     if (ds.typemat->profile)
8794       {
8795         if(verbosity>5) cout << " Matrix skyline type:" << ds.typemat->t <<endl;
8796         MatriceProfile<R> & AAA(dynamic_cast<MatriceProfile<R> &>(A));
8797         MatriceProfile<R_st> &AA(*new MatriceProfile<R_st>(AAA)); //
8798 
8799         throwassert(&AA);
8800         double tol_pivot1= (ds.tol_pivot>0) ? ds.tol_pivot : EPSILON/8.;
8801        // cout << " tol_pivot1 " <<tol_pivot1 <<  endl;
8802         switch (ds.typemat->t) {
8803         case TypeSolveMat::LU       : AA.LU(tol_pivot1); break;
8804         case TypeSolveMat::CROUT    : AA.crout(tol_pivot1); break;
8805         case TypeSolveMat::CHOLESKY : AA.cholesky(tol_pivot1); break;
8806         default:
8807           cerr << " type resolution " << ds.typemat->t << endl;
8808           CompileError("type resolution profile inconnue"); break;
8809         }
8810         return &AA;
8811       }
8812     else */
8813       {
8814          ExecError("matrix HMAT & CADNA are incompatible today, sorry!");
8815          return 0;
8816       }
8817    return 0;
8818   }
8819 
8820 template<class R,class FESpace,class v_fes>
DispatchSolution(const typename FESpace::Mesh & Th,int Nb,vector<FEbase<R,v_fes> * > & u_h,KN<R> * X,KN<R> * B,const FESpace ** LL,const FESpace & Uh)8821 void   DispatchSolution(const typename FESpace::Mesh & Th,int Nb, vector<  FEbase<R,v_fes> * > & u_h,KN<R> * X,KN<R> * B,const FESpace **  LL,const FESpace &  Uh)
8822 {
8823     typedef typename  FESpace::Mesh Mesh;
8824     typedef typename  FESpace::FElement FElement;
8825     typedef typename  Mesh::Element Element;
8826     typedef typename  Mesh::Vertex Vertex;
8827     typedef typename  Mesh::RdHat RdHat;
8828     typedef typename  Mesh::Rd Rd;
8829 
8830     // dispatch the solution
8831     if (Nb==1)  {
8832         *(u_h[0])=X;
8833         if (X != B ) delete B;  }
8834     else {
8835         const FElement ** sK= new const FElement * [Nb];
8836 
8837         KN<R> ** sol= new KN<R> * [Nb];
8838         for (int i=0;i<Nb;i++) {
8839             sol[i]= new KN<R>( LL[i]->NbOfDF) ;
8840             *(u_h[i]) = sol[i];
8841         }
8842 
8843         for (int it=0;it<Th.nt;it++)
8844         {
8845             const FElement K(Uh[it]);
8846             const int nbdf=K.NbDoF();
8847             for (int i=0;i<Nb;i++)
8848             sK[i]= new FElement( (*LL[i])[it]) ;
8849             for (int df=0;df< nbdf;df++)
8850             {  int kfe=K.FromFE(df);
8851                 int kdf=K.FromDF(df);
8852                 const FElement & SK(*sK[kfe]);
8853                 (*sol[kfe])[SK(kdf)] = (*X)[K(df)];
8854             }
8855             for (int i=0;i<Nb;i++)
8856             delete sK[i];
8857 
8858         }
8859 
8860         delete [] sK;
8861         delete [] sol;
8862         if (X != B && X ) delete X;
8863         delete B;
8864     }
8865 }
8866 /*
8867 #ifdef HAVE_LIBUMFPACK
8868 TypeSolveMat::TSolveMat  TypeSolveMat::defaultvalue=TypeSolveMat::SparseSolver;
8869 #else
8870 TypeSolveMat::TSolveMat  TypeSolveMat::defaultvalue=TypeSolveMat::LU;
8871 #endif
8872 */
8873 
8874 template<class R,class FESpace,class v_fes>
eval(Stack stack,Data<FESpace> * data,CountPointer<MatriceCreuse<R>> & dataA,MatriceCreuse<typename CadnaType<R>::Scalaire> * & cadnamat) const8875 AnyType Problem::eval(Stack stack,Data<FESpace> * data,CountPointer<MatriceCreuse<R> > & dataA,
8876                       MatriceCreuse< typename CadnaType<R>::Scalaire >   * & cadnamat ) const
8877 {
8878     typedef typename  FESpace::Mesh Mesh;
8879     typedef typename  FESpace::FElement FElement;
8880     typedef typename  Mesh::Element Element;
8881     typedef typename  Mesh::Vertex Vertex;
8882     typedef typename  Mesh::RdHat RdHat;
8883     typedef typename  Mesh::Rd Rd;
8884 
8885     using namespace Fem2D;
8886     typedef typename CadnaType<R>::Scalaire R_st;
8887     MeshPoint *mps= MeshPointStack(stack),mp=*mps;
8888     Data_Sparse_Solver ds;
8889     /* long NbSpace = 50;
8890      long itmax=0;
8891      double epsilon=1e-6;*/
8892     string save;
8893 
8894      KN<double>* cadna=0;
8895 
8896     if (nargs[0]) save = *GetAny<string*>((*nargs[0])(stack));
8897     if (nargs[1]) cadna= GetAny<KN<double>* >((*nargs[1])(stack));
8898 
8899     SetEnd_Data_Sparse_Solver<R>(stack,ds,nargs,n_name_param);
8900 
8901 
8902     //  for the gestion of the PTR.
8903     WhereStackOfPtr2Free(stack)=new StackOfPtr2Free(stack);// FH aout 2007
8904 
8905     bool sym = ds.sym;
8906 
8907     list<C_F0>::const_iterator ii,ib=op->largs.begin(),
8908     ie=op->largs.end();
8909     int Nbcomp2=var.size(),Nbcomp=Nbcomp2/2; // nb de composante
8910     throwassert(Nbcomp2==2*Nbcomp);
8911     //  Data *data= dataptr(stack);
8912     //   data->init();
8913     KN<int>  which_comp(Nbcomp2),which_uh(Nbcomp2);
8914 
8915     TabFuncArg tabexp(stack,Nbcomp);
8916     typedef pair< FEbase<R,v_fes> *,int> pfer;
8917     vector< pair< FEbase<R,v_fes> *,int> > u_hh(Nbcomp2);
8918     for (size_t i=0;i<var.size();i++)
8919     u_hh[i] = GetAny< pfer  >( (*(var[i]))(stack));
8920     for (size_t i=0;i<var.size();i++)
8921     u_hh[i].first->newVh();
8922     //   compression pour les cas vectoriel
8923     int kkk=0;
8924     for (int i=0;i<Nbcomp2;i++)
8925     {
8926         if ( u_hh[i].second==0)
8927         kkk++;
8928         else {
8929             throwassert(u_hh[i].second==(u_hh[i-1].second+1));}
8930         which_uh[i]=kkk-1;
8931         which_comp[i]=u_hh[i].second;
8932     }
8933 
8934     vector<  FEbase<R,v_fes> * > u_h(kkk);
8935     kkk= 0;
8936     for (int i=0;i<Nbcomp2;i++)
8937     if ( u_hh[i].second==0) u_h[kkk++]=u_hh[i].first;
8938     const int  Nb2 = kkk, Nb=Nb2/2; // nb of FESpace
8939     throwassert(Nb2==2*Nb);
8940 
8941     //const FESpace ** LL = new  const FESpace *[var.size()];
8942     KN<const FESpace *> LL(var.size());
8943     for (int i=0;i<Nb2;i++)
8944     LL[i]= (*(u_h[i])).newVh();
8945     SHOWVERB(cout << "Problem  " << Nb << endl);
8946 
8947     //   const de
8948 
8949     //  const FESpace * Uhh , *Vhh;
8950     const Mesh * pTh= &LL[0]->Th;
8951     for (int i=0;i<Nb2;i++)
8952     if ( &LL[i]->Th != pTh)
8953     ExecError("all the finites elements spaces must be defined on the same mesh in solve");
8954     if ( pTh != data->pTh )
8955     {
8956         ds.initmat = true;
8957         data->pTh=pTh;
8958         if (Nb==1)
8959         { //  cas scalaire
8960             data->Uh=LL[0];
8961             data->Vh=LL[1]; }
8962         else
8963         { //  cas vectoriel
8964             bool same=true;
8965             for (int i=0;i<Nb;i++)
8966             if ( LL[i] != LL[Nb+i] )
8967             {
8968                 same = false;
8969                 break;
8970             }
8971             if(!same)
8972             InternalError("Methode de Galerkine (a faire)");
8973             else
8974             {
8975 
8976                 bool unique=true;
8977                 for (int i=1;i<Nb;i++)
8978                 if ( LL[0] != LL[i])
8979                 {
8980                     unique = false;
8981                     break;
8982                 }
8983                 else if(LL[i]->FirstDfOfNodeData)// Correct jan 2015 not FE product this case
8984                 {
8985                     unique = false;
8986                     break;
8987                 }
8988 
8989                 if (unique)
8990                 data->Uh.master( new FESpace(*LL[0],Nb));
8991                 else
8992                 data->Uh.master(new FESpace(LL,Nb));
8993                 data->Vh=data->Uh;
8994             }
8995 
8996         }
8997     }
8998 
8999     const FESpace & Uh(*data->Uh);
9000     const FESpace & Vh(*data->Vh);
9001     throwassert(Nbcomp==Uh.N && Nbcomp==Vh.N);
9002     KN<R> *B=new KN<R>(Vh.NbOfDF);
9003     KN<R> *X=B; //
9004     const  Mesh & Th(Uh.Th);
9005     bool initx = true; //typemat->t==TypeSolveMat::GC ; //  make x and b different in all case
9006     // more safe for the future ( 4 days lose with is optimization FH )
9007 
9008     InitProblem<R,FESpace,v_fes>(  Nb,  Uh, Vh, B, X,u_hh,&ds , u_h,  LL,  initx);
9009 
9010     if(verbosity>2) cout << "   Problem(): initmat " << ds.initmat << " VF (discontinuous Galerkin) = " << VF << endl;
9011 
9012 
9013 
9014     if (ds.initmat)
9015      {
9016        {
9017           if ( &Uh == & Vh )
9018             dataA.master(new MatriceMorse<R>( sym,Vh.NbOfDF));
9019           else
9020             dataA.master(new MatriceMorse<R>(Vh.NbOfDF,Uh.NbOfDF));
9021         }
9022         MatriceCreuse<R>  & AA(dataA);
9023        if(verbosity>1) cout <<  "   -- size of Matrix " << AA.size()<< " Bytes" <</* " skyline =" <<ds.typemat->profile <<*/ endl;
9024       }
9025     MatriceCreuse<R>  & A(dataA);
9026     if  (AssembleVarForm( stack,Th,Uh,Vh,sym, ds.initmat ? &A:0 , B, op->largs))
9027     {
9028         *B = - *B;
9029         // hach FH
9030         for (int i=0, n= B->N(); i< n; i++)
9031         if( abs((*B)[i]) < 1.e-60 ) (*B)[i]=0;
9032 
9033         AssembleBC<R,FESpace>     ( stack,Th,Uh,Vh,sym, ds.initmat ? &A:0 , B, initx ? X:0,  op->largs, ds.tgv );
9034     }
9035     else
9036     *B = - *B;
9037     MatriceCreuse<R_st>  * ACadna = 0;
9038 
9039 
9040     try {
9041 
9042         if (ds.initmat)
9043         {
9044          //   if(cadna)
9045          //   ACadna = DefSolverCadna( stack,A, ds);
9046          //   else
9047             DefSolver(stack,  A, ds);
9048         }
9049 
9050 
9051 
9052         // if(verbosity>3) cout << "   B  min " << B->min() << " ,  max = " << B->max() << endl;
9053         if( save.length() )
9054         {
9055             string savem=save+".matrix";
9056             string saveb=save+".b";
9057             {
9058                 ofstream outmtx( savem.c_str());
9059                 A.dump(outmtx)  << endl;
9060             }
9061             {
9062                 ofstream outb(saveb.c_str());
9063                 outb<< *B << endl;
9064             }
9065 
9066         }
9067         if (verbosity>99)
9068         {
9069             cout << " X= " << *X << endl;
9070             cout << " B= " << *B << endl;
9071         }
9072 
9073         if(ACadna)
9074         {
9075             KN<R_st> XX(*X);
9076             KN<R_st> BB(*B);
9077             ACadna->Solve(XX,BB);
9078             *X=XX;
9079             *cadna =-1.;
9080 
9081 #ifdef HAVE_CADNA
9082             R_st xxmin = XX.min();
9083             R_st xxmax = XX.max();
9084             cout  << "    cadna:      min " <<  xxmin << "/ nd " << cestac(xxmin)
9085             << " ,   max " << xxmax << " / nd " << cestac(xxmax)   << endl ;
9086             int nn= XX.N();
9087             if ( cadna->N() == nn )
9088             for (int i=0;i<nn;++i)
9089             (*cadna)[i] = cestac(XX[i]);
9090             else
9091             cerr << "Warning: Sorry array is incorrect size to store cestac "
9092             << nn << " != " << cadna->N() << endl;
9093 #endif
9094         }
9095         else
9096 
9097         A.Solve(*X,*B);
9098 
9099         if (verbosity>99)
9100         {
9101             cout << " X= " << *X << endl;
9102         }
9103     }
9104     catch (...)
9105     {
9106         if(verbosity) cout << " catch an erreur in  solve  =>  set  sol = 0 !!!!!!! "   <<  endl;
9107         *X=R(); // erreur set the sol of zero ????
9108         DispatchSolution<R,FESpace,v_fes>(Th,Nb,u_h,X,B,LL,Uh);
9109         throw ;
9110     }
9111     DispatchSolution<R,FESpace,v_fes>(Th,Nb,u_h,X,B,LL,Uh);
9112 
9113 
9114     if (verbosity)
9115     {cout << "  -- Solve : \n" ;
9116         for (int i=0;i<Nb;i++)
9117         cout  << "          min " << (u_h[i])->x()->min() << "  max " << (u_h[i])->x()->max() << endl ;
9118     }
9119 
9120     // delete [] LL;
9121     // if (save) delete save; // clean memory
9122     *mps=mp;
9123     return SetAny<const Problem *>(this);
9124 }
9125 
9126 
9127 // dimProblem read the number of arguments of problem ex: problem a(u,v) or a([u1,u2], [v1,v2])
dimProblem(const ListOfId & l)9128 int dimProblem(const ListOfId &l)
9129 {
9130     int dim=0;
9131     int nb=l.size();//,nbarray=0;//,n=0,
9132     //const UnId *p1;
9133     for(int i=0; i<nb; ++i)
9134     {
9135         if(l[i].e ==0)// to miss name parameter solver=ddd
9136         {
9137         if (l[i].array)
9138         {
9139             ListOfId * array=l[i].array;
9140             for(int j=0; j<array->size(); ++j)
9141             {
9142                 const UnId & idi( (*array)[j]);
9143                 if (idi.r == 0 && idi.re  == 0 && idi.array==0 )
9144                 {
9145                     C_F0 c=::Find( idi.id);
9146                     if(BCastTo<pfec>(c) ) ffassert(dim==0 || dim==2),dim=2;
9147                     if(BCastTo<pfer>(c) ) ffassert(dim==0 || dim==2),dim=2;
9148                     if(BCastTo<pf3c>(c) ) ffassert(dim==0 || dim==3),dim=3;
9149                     if(BCastTo<pf3r>(c) ) ffassert(dim==0 || dim==3),dim=3;
9150                     if(BCastTo<pfSr>(c) ) ffassert(dim==0 || dim==4),dim=4;
9151                     if(BCastTo<pfSc>(c) ) ffassert(dim==0 || dim==4),dim=4;
9152                     if(BCastTo<pfLr>(c) ) ffassert(dim==0 || dim==5),dim=5;
9153                     if(BCastTo<pfLc>(c) ) ffassert(dim==0 || dim==5),dim=5;
9154                 }
9155             }
9156 
9157         }
9158         else
9159         {
9160             C_F0 c=::Find(l[i].id);
9161             if(BCastTo<pfec>(c) ) ffassert(dim==0 || dim==2),dim=2;
9162             if(BCastTo<pfer>(c) ) ffassert(dim==0 || dim==2),dim=2;
9163             if(BCastTo<pf3c>(c) ) ffassert(dim==0 || dim==3),dim=3;
9164             if(BCastTo<pf3r>(c) ) ffassert(dim==0 || dim==3),dim=3;
9165             if(BCastTo<pfSr>(c) ) ffassert(dim==0 || dim==4),dim=4;
9166             if(BCastTo<pfSc>(c) ) ffassert(dim==0 || dim==4),dim=4;
9167             if(BCastTo<pfLr>(c) ) ffassert(dim==0 || dim==5),dim=5;
9168             if(BCastTo<pfLc>(c) ) ffassert(dim==0 || dim==5),dim=5;
9169         }
9170         }
9171     }
9172     ffassert(dim);
9173     return dim;
9174 
9175 }
9176 
operator ()(Stack stack) const9177 AnyType Problem::operator()(Stack stack) const
9178 {
9179     if(dim==2) {
9180         Data<FESpace> *data= dataptr(stack);
9181         if (complextype)
9182             return eval<Complex,FESpace,v_fes>(stack,data,data->AC,data->AcadnaC);
9183         else
9184             return eval<double,FESpace,v_fes>(stack,data,data->AR,data->AcadnaR);
9185     }
9186     else if(dim==3) {
9187         Data<FESpace3> *data= dataptr3(stack);
9188         if (complextype)
9189             return eval<Complex,FESpace3,v_fes3>(stack,data,data->AC,data->AcadnaC);
9190         else
9191             return eval<double,FESpace3,v_fes3>(stack,data,data->AR,data->AcadnaR);
9192     }
9193     else if(dim==4) {
9194         Data<FESpaceS> *data= dataptrS(stack);
9195         if (complextype)
9196             return eval<Complex,FESpaceS,v_fesS>(stack,data,data->AC,data->AcadnaC);
9197         else
9198             return eval<double,FESpaceS,v_fesS>(stack,data,data->AR,data->AcadnaR);
9199     }
9200     else if(dim==5) {
9201         Data<FESpaceL> *data= dataptrL(stack);
9202         if (complextype)
9203             return eval<Complex,FESpaceL,v_fesL>(stack,data,data->AC,data->AcadnaC);
9204         else
9205             return eval<double,FESpaceL,v_fesL>(stack,data,data->AR,data->AcadnaR);
9206     }
9207 
9208     else ffassert(0);
9209 }
9210 
9211 template<class pfer,class pfec>
GetBilinearParam(const ListOfId & l,basicAC_F0::name_and_type * name_param,int n_name_param,Expression * nargs,int & N,int & M,vector<Expression> & var)9212 bool GetBilinearParam(const ListOfId &l,basicAC_F0::name_and_type *name_param,int n_name_param,
9213                       Expression *nargs,int & N,int & M,  vector<Expression> & var )
9214 {
9215     bool unset=true,complextype=false;
9216 
9217     for (int i=0;i<n_name_param;i++)
9218     nargs[i]=0;
9219     int nb=l.size(),n=0,nbarray=0;
9220     ListOfId * array[2];
9221     for (int i=0;i<nb;i++)
9222     if (l[i].r == 0 && l[i].re  == 0 && l[i].array == 0)
9223     n++;
9224     else if (l[i].array) array[Min(nbarray++,1)] = l[i].array;
9225     else
9226     {
9227         bool ok=false;
9228         for (int j=0;j<n_name_param;j++)
9229         if (!strcmp(l[i].id,name_param[j].name))
9230         {
9231             ok = !nargs[j];
9232             nargs[j]= map_type[name_param[j].type->name()]->CastTo(C_F0(l[i].e,l[i].re));
9233             break;
9234         }
9235         if (!ok)
9236         {
9237             cerr << " Error name argument " << l[i].id << " the kown arg : ";
9238             for (int k=0;k<n_name_param;k++)
9239             cerr << name_param[k].name << " ";
9240             cerr << endl;
9241             CompileError("Unkown name argument or two times same name argument ");
9242         }
9243     }
9244 
9245     if (nbarray)
9246     { // new version ok
9247         if(nbarray!=2)
9248         CompileError(" Must have 2 array, one for unknow functions, one for test functions");
9249         N = array[0]->size();
9250         M = array[1]->size();
9251         var.resize(N+M);
9252         for (size_t k=0,j=0;k<2;k++)
9253         for  (size_t i=0;i<array[k]->size();i++)
9254         {
9255             const UnId & idi((*array[k])[i]);
9256             if (idi.r == 0 && idi.re  == 0 && idi.array==0 )
9257             { C_F0 c=::Find( idi.id);
9258                 if (unset)
9259                 complextype =  BCastTo<pfec>(c) , unset=false;
9260 
9261                 if(complextype)
9262                 var[j++]=CastTo<pfec>(c);
9263                 else
9264                 var[j++]=CastTo<pfer>(c);
9265             }
9266             else
9267             CompileError(" Just Variable in array parameter ");
9268         }
9269     }
9270     else
9271     { // old version
9272         assert(n%2==0);
9273         N=n/2;
9274         M=N;
9275         var.resize(N+M);
9276         for  (size_t i=0,j=0;i<l.size();i++)
9277         if (l[i].r == 0 && l[i].re  == 0 && l[i].array==0 )
9278         {
9279             C_F0 c=::Find(l[i].id);
9280             if (unset)
9281             complextype =  BCastTo<pfec>(c) , unset=false;
9282             if(complextype)
9283             var[j++]=CastTo<pfec>(c);
9284             else
9285             var[j++]=CastTo<pfer>(c);
9286         }
9287 
9288     }
9289     return complextype;
9290 }
9291 
9292 
9293 /*
9294  int DimForm( list<C_F0> & largs)
9295  {
9296  int dim=0;
9297  list<C_F0>::iterator ii,ib=largs.begin(),
9298  ie=largs.end();
9299  for (ii=ib;ii != ie;ii++)
9300  {
9301  Expression e=ii->LeftValue();
9302  aType r = ii->left();
9303  if (r==atype<const  FormBilinear *>())
9304  {
9305  const  FormBilinear * bb=dynamic_cast<const  FormBilinear *>(e);
9306  if(dim) ffassert(bb->d==dim);
9307  else
9308  dim=bb->d;
9309  }
9310  else if (r==atype<const  FormLinear *>())
9311  {
9312  const  FormLinear * ll=dynamic_cast<const  FormLinear *>(e);
9313  if(dim) ffassert(bb->d==dim);
9314  else
9315  dim=bb->d;
9316  }
9317  else if (r == atype<const  BC_set *>())
9318  {
9319  const  BC_set * bc=dynamic_cast<const  BC_set *>(e);
9320  if (bc->complextype)  complextype=true;
9321  }
9322  }
9323  }*/
FieldOfForm(list<C_F0> & largs,bool complextype)9324 bool FieldOfForm( list<C_F0> & largs ,bool complextype)  // true => complex problem
9325 {
9326     //  bool   iscomplextype=complextype;
9327     list<C_F0>::iterator ii,ib=largs.begin(),
9328     ie=largs.end();
9329     // bool complextype =false;
9330     for (ii=ib;ii != ie;ii++)
9331     {
9332         Expression e=ii->LeftValue();
9333         aType r = ii->left();
9334         if (r==atype<const  FormBilinear *>())
9335         {
9336             const  FormBilinear * bb=dynamic_cast<const  FormBilinear *>(e);
9337             if (! bb->b->mappable(BCastToR))
9338             complextype=true;
9339         }
9340         else if (r==atype<const  FormLinear *>())
9341         {
9342             const  FormLinear * ll=dynamic_cast<const  FormLinear *>(e);
9343             if (! ll->l->mappable(BCastToR))
9344             complextype=true;
9345         }
9346         else if (r == atype<const  BC_set *>())
9347         {
9348             const  BC_set * bc=dynamic_cast<const  BC_set *>(e);
9349             if (bc->complextype)  complextype=true;
9350 
9351         }
9352     }
9353 
9354     for (ii=ib;ii != ie;ii++)
9355     {
9356         Expression e=ii->LeftValue();
9357         aType r = ii->left();
9358         if (r==atype<const  FormBilinear *>())
9359         {
9360             FormBilinear * bb=new FormBilinear(*dynamic_cast<const FormBilinear *>(e));
9361             Foperator * b=const_cast<  Foperator *>(bb->b);
9362             // const Foperator * b=bb->b;
9363             //cout << b <<  " bb->b " <<  bb->b << " " <<  bb->b <<  " " << bb->b->isoptimize <<endl;
9364             assert(b->isoptimize==false);
9365             if (complextype)  b->mapping(&CCastToC);
9366             else b->mapping(&CCastToR) ;
9367             Foperator * bn = b->Optimize(currentblock);
9368             *bb->b = *bn;
9369             *ii=C_F0(bb,r);
9370         }
9371         else if (r==atype<const  FormLinear *>())
9372         {
9373             FormLinear * ll=new FormLinear(*dynamic_cast<const  FormLinear *>(e));
9374             Ftest * l= const_cast<Ftest *>(ll->l);
9375             if (complextype)  l->mapping(&CCastToC) ;
9376             else l->mapping(&CCastToR) ;
9377             Ftest * ln = l->Optimize(currentblock);
9378             *ll->l=*ln;
9379             *ii=C_F0(ll,r);
9380             //cout << l <<   " ll->l " <<  ll->l << " " << ll->l->isoptimize <<endl;
9381         }
9382         else if (r==atype<const  BC_set *>())
9383         {// modif FH  mai 2007  A FAIRE il y a un bug ici XXXXXXXXXXXXX
9384 
9385             BC_set * bc= new BC_set(*dynamic_cast<const  BC_set *>(e));
9386             if (complextype && !bc->complextype) {
9387                 bc->CastToK<Complex>() ;
9388                 if(verbosity > 10) cout << " Bc to complex " << endl;
9389             }
9390             //else bc->mapping(&CCastToR) ;
9391             //cout << l <<   " ll->l " <<  ll->l << " " << ll->l->isoptimize <<endl;
9392             *ii=C_F0(bc,r);
9393         }
9394 
9395     }
9396     return complextype;
9397 }
9398 
9399 
Problem(const C_args * ca,const ListOfId & l,size_t & top)9400 Problem::Problem(const C_args * ca,const ListOfId &l,size_t & top) :
9401 op(new C_args(*ca)),
9402 var(l.size()),
9403 VF(false),
9404 offset(align8(top)),
9405 dim(dimProblem(l))
9406 {
9407     if( verbosity > 999)  cout << "Problem : ----------------------------- " << top << " dim = " << dim<<" " << nargs <<  endl;
9408     top = offset + max(sizeof(Data<FESpace>),sizeof(Data<FESpace>));
9409 
9410     bool iscomplex;
9411     if(dim==2)
9412     iscomplex=GetBilinearParam<pfer,pfec>(l,name_param,n_name_param,nargs, Nitem,Mitem,var);
9413     else if (dim==3)
9414     iscomplex=GetBilinearParam<pf3r,pf3c>(l,name_param,n_name_param,nargs, Nitem,Mitem,var);
9415     else if (dim==4)  // dim = 4 for a 3D surface problem
9416     iscomplex=GetBilinearParam<pfSr,pfSc>(l,name_param,n_name_param,nargs, Nitem,Mitem,var);
9417     else if (dim==5)  // dim = 5 for a 3D curve problem
9418         iscomplex=GetBilinearParam<pfLr,pfLc>(l,name_param,n_name_param,nargs, Nitem,Mitem,var);
9419     else ffassert(0); // bug
9420 
9421     precon = 0; //  a changer
9422     if ( nargs[3+3])
9423     {
9424         const  Polymorphic * op=  dynamic_cast<const  Polymorphic *>(nargs[3+3]);
9425         assert(op);
9426         precon = op->Find("(",ArrayOfaType(atype<KN<R>* >(),false));
9427         ffassert(precon);
9428     }
9429 
9430     VF=isVF(op->largs);
9431     // cout << " Problem ) VF = " << VF << endl;
9432     complextype =  FieldOfForm(op->largs,iscomplex)  ;  // Warning do the casting of all expression in double or complex
9433     if( complextype && !iscomplex)
9434     CompileError("Error: Problem  a complex problem with no complex FE function ");
9435     if( verbosity > 1)
9436     cout << "  -- Problem type  ( complex : " << complextype << " )  "  <<endl;
9437 }
9438 
IsFebaseArray(Expression f)9439 Expression IsFebaseArray(Expression f)
9440 {
9441     assert(f);
9442     size_t N=f->nbitem();
9443     E_Array * vvi(dynamic_cast< E_Array *>(f));
9444     if ( ! vvi) return 0;
9445     E_Array & vi(*vvi);
9446     Expression febase=0;
9447     for (size_t i=0;i<N;i++)
9448     {
9449         assert(vi[i].left() == atype<pfer>() );
9450         const E_FEcomp<R,v_fes> * comp=dynamic_cast<const E_FEcomp<R,v_fes> *>( vi[i].LeftValue()) ;
9451         if (!(comp && comp->comp == (int) i  && comp->N == (int) N)) return 0;
9452         if (!febase) febase = comp->a0;
9453         else if(comp->a0 != febase) return 0;
9454     }
9455     return febase;
9456 }
9457 template<class VFES>
Call_FormBilinear(int dd,Expression * na,Expression BB,Expression fi,Expression fj)9458 Call_FormBilinear<VFES>::Call_FormBilinear(int dd,Expression * na,Expression  BB,Expression fi, Expression fj)
9459 : d(dd),nargs(na),largs(),N(fi->nbitem()),M(fj->nbitem()),
9460 euh(fi), evh(fj)
9461 {
9462     assert(nargs );
9463     const C_args * LLL=dynamic_cast<const C_args *>(BB);
9464     if (!LLL)
9465     CompileError("Sorry the variationnal form (varf)  is not a the variationnal form (type const C_args *)");
9466     largs=LLL->largs;
9467 }
9468 template<class VFES>
Call_FormLinear(int dd,Expression * na,Expression LL,Expression ft)9469 Call_FormLinear<VFES>::Call_FormLinear(int dd,Expression *na,Expression  LL, Expression ft)
9470 : d(dd),largs(),nargs(na),N(ft->nbitem()),
9471 ppfes(ft)//IsFebaseArray(ft))
9472 {
9473     const C_args * LLL=dynamic_cast<const C_args *>(LL);
9474     if ( !LLL) CompileError("The parameter of a LinearForm must be a array of all componate of FE function");
9475     largs=LLL->largs;
9476 }
IsLinearOperator() const9477 bool C_args::IsLinearOperator() const {
9478     //  int n=largs.size();
9479     aType tRn =atype<KN<R>* >();
9480     aType tCn =atype<KN<Complex>* >();
9481     for (const_iterator i=largs.begin(); i != largs.end();i++)
9482     {
9483         C_F0  c= *i;
9484         // Expression e=c;
9485         aType r=c.left();
9486         if (     ( r != atype<const  FormLinear *>() )
9487  	       &&  ( r != atype<const  BC_set *>() )
9488  	       &&  ( r != atype<RNM_VirtualMatrix<R>::plusAx >() )
9489  	       &&  ( r != atype<RNM_VirtualMatrix<R>::plusAtx >() )
9490  	       &&  ( r != atype<RNM_VirtualMatrix<Complex>::plusAx >() )
9491  	       &&  ( r != atype<RNM_VirtualMatrix<Complex>::plusAtx >() )
9492  	       &&  ( r != tRn)
9493  	       &&  ( r != tCn)
9494             ) return false;
9495     }
9496     return true;}
9497 
IsBilinearOperator() const9498 bool C_args::IsBilinearOperator() const {
9499     //int n=largs.size();
9500     aType tRn =atype<Matrice_Creuse<R>* >();
9501     aType tCn =atype<Matrice_Creuse<Complex>* >();
9502     for (const_iterator i=largs.begin(); i != largs.end();i++)
9503     {
9504         C_F0  c= *i;
9505         //Expression e=c;
9506         aType r=c.left();
9507         if (     ( r!= atype<const  FormBilinear *>() )
9508             &&  ( r != atype<const  BC_set *>() )
9509             &&  ( r != tRn)
9510             &&  ( r != tCn)
9511             ) return false;
9512     }
9513     return true;}
9514 
9515 
SetArgsFormLinear(const ListOfId * lid,int ordre)9516 void SetArgsFormLinear(const ListOfId *lid,int ordre)
9517 {
9518     //  the local parameter are
9519     //  ordre ==2 => bilinear form  unknown (newU_) and test function (newV_)
9520     //  ordre ==1 =>   linear form just  test function (newV_)
9521     // ---------------------
9522     throwassert(ordre >0 && ordre <=2 && (lid || lid->size()>0 ) );
9523     const ListOfId & l(*lid);
9524     int nb=l.size();
9525     int n=0;
9526     C_F0 type,init;
9527     int nbarray=0;
9528     ListOfId * array[2];
9529     aType uh=atype<const finconnue*>(),vh=atype<const ftest*>();
9530 
9531     for (int i=0;i<nb;i++)
9532     if (l[i].r == 0 &&  l[i].re == 0 && l[i].id  ) n++;
9533     else if (l[i].array)
9534     array[Min(nbarray++,2)] = l[i].array;
9535     if (nbarray && n==0)
9536     {  //
9537 
9538         if(nbarray!=ordre)
9539         { cerr << " form " << ordre << " == " << nbarray << " Nb of Array "<<endl;
9540             CompileError(" Must have 1 or 2 array, one for unknow functions, one for test functions");
9541         }
9542         for (int k=0;k<ordre;k++)
9543         for  (int i=0,iend=array[k]->size();i<iend;i++)
9544         {
9545             const UnId & idi((*array[k])[i].id);
9546             if (idi.r == 0 && idi.re  == 0 && idi.array==0 )
9547             {
9548                 if (k==ordre-2)  //  unknow function just in case of bilinear form
9549                 currentblock->NewID(uh,idi.id,C_F0(newU_(i),uh));
9550                 else   //  test function
9551                 currentblock->NewID(vh,idi.id,C_F0(newV_(i),vh));
9552             }
9553             else
9554             CompileError(" Just Variable in array parameter ");
9555         }
9556     }
9557     else if (nbarray==0)
9558     {    // a supprimer  to remove   in case of bilinear
9559 
9560         SHOWVERB(cout << "SetArgs:: form  set parameter " << endl);
9561         if( ! ( ordre==1 || n%2==0) )
9562         CompileError(" Error in test or unkwon function (odd number of function) ");
9563         ffassert( ordre==1 || n%2==0);
9564         int nn=ordre==1 ? 0 : n/2; // ordre == 1 => no unknown function just test function
9565 
9566         for (int i=0,j=0;i<nb;i++)
9567         if (l[i].r == 0 && l[i].re  == 0 && l[i].array==0)
9568         {
9569             SHOWVERB(cout <<"  " <<  l[i].id  << " " << (j<nn) << endl);
9570             if (j<nn)
9571             currentblock->NewID(uh,l[i].id,C_F0(newU_(j%nn),uh));
9572             else
9573             currentblock->NewID(vh,l[i].id,C_F0(newV_(j%nn),vh));
9574             j++;
9575         }
9576     }
9577     else
9578     {
9579         CompileError(" Sorry you mixte formulation with and without array ");
9580     }
9581 }
9582 
FIV(Stack stack) const9583 const Fem2D::GQuadratureFormular<R3> & CDomainOfIntegration::FIV(Stack stack) const
9584 {
9585     using namespace Fem2D;
9586     if (nargs[8]) return  *GetAny<const Fem2D::GQuadratureFormular<R3> *>((*nargs[8])(stack));
9587     int exact = 5;
9588     if (nargs[2]) exact=  GetAny<long>((*nargs[2])(stack))-1;
9589     GQuadratureFormular<R3> *qf=QF_Simplex<R3>(exact);//QF_Tria_exact(exact);
9590     if(verbosity>99 && qf ) cout << "   QF Tet  n:" << qf->n << " exact = " << exact <<  endl;
9591     if(qf) return *qf;
9592     /*
9593      if( QuadratureFormular_T_1.exact >= exact ) return QuadratureFormular_T_1;
9594      if( QuadratureFormular_T_2.exact >= exact ) return QuadratureFormular_T_2;
9595      if( QuadratureFormular_T_5.exact >= exact ) return QuadratureFormular_T_5;
9596      if( QuadratureFormular_T_7.exact >= exact ) return QuadratureFormular_T_7;
9597      if( QuadratureFormular_T_9.exact >= exact ) return QuadratureFormular_T_9;
9598      */
9599     static long count = 0;
9600     if(verbosity > 1 && count++ < 5)
9601     cerr << "Warning :  Max Order of the Quadrature Formular Tet  is 6 and expect: " << exact+1
9602     <<  endl;
9603     //  ExecError(" We find  no Quadrature Formular on Tet for this  order: too high");
9604     return QuadratureFormular_Tet_5;
9605 }
9606 
FIT(Stack stack) const9607 const Fem2D::QuadratureFormular & CDomainOfIntegration::FIT(Stack stack) const
9608 {
9609     using namespace Fem2D;
9610     if (nargs[0]) return  *GetAny<const Fem2D::QuadratureFormular *>((*nargs[0])(stack));
9611     int exact = 5;
9612     if (nargs[2]) exact=  GetAny<long>((*nargs[2])(stack))-1;
9613     QuadratureFormular *qf=QF_Simplex<R2>(exact);//QF_Tria_exact(exact);
9614     if(verbosity>99 && qf ) cout << "   QF Tria  n:" << qf->n << " exact = " << exact <<  endl;
9615     if(qf) return *qf;
9616     /*
9617      if( QuadratureFormular_T_1.exact >= exact ) return QuadratureFormular_T_1;
9618      if( QuadratureFormular_T_2.exact >= exact ) return QuadratureFormular_T_2;
9619      if( QuadratureFormular_T_5.exact >= exact ) return QuadratureFormular_T_5;
9620      if( QuadratureFormular_T_7.exact >= exact ) return QuadratureFormular_T_7;
9621      if( QuadratureFormular_T_9.exact >= exact ) return QuadratureFormular_T_9;
9622      */
9623     cerr << " Order of the Quadature Formular: order = " << exact+1 << " exact = " << exact << endl;
9624     ExecError("Sorry,  we find  no Quadrature Formular on Triangle for this  order: too high.");
9625     return QuadratureFormular_T_1;
9626 }
FIE(Stack stack) const9627 const Fem2D::QuadratureFormular1d & CDomainOfIntegration::FIE(Stack stack) const
9628 {
9629     using namespace Fem2D;
9630     if (nargs[1]) return  *GetAny<const Fem2D::QuadratureFormular1d *>((*nargs[1])(stack));
9631     int exact = 5;
9632     if (nargs[2]) exact=  GetAny<long>((*nargs[2])(stack))-1;
9633     QuadratureFormular1d *qf=QF_Simplex<R1>(exact);//QF_1d_exact(exact);
9634     if(verbosity>99 && qf ) cout << "   QF 1d  n:" << qf->n << " exact = " << exact <<  endl;
9635     if(qf) return *qf;
9636     /*
9637      if( 1 >= exact ) return QF_GaussLegendre1;
9638      if( 3 >= exact ) return QF_GaussLegendre2;
9639      if( 5 >= exact ) return QF_GaussLegendre3;
9640      if( 7 >= exact ) return QF_GaussLegendre4;
9641      if( 9 >= exact ) return QF_GaussLegendre5;
9642      */
9643     cerr << " Ordre of the Integration Formular on Edge, order = " << exact+1 << " exact = " << exact << endl;
9644     ExecError(" We find  no Quadrature Formular on Edge  for this  order:  too high.");
9645     return QF_GaussLegendre1;
9646 }
9647 
9648 
9649 namespace Fem2D {
9650 
9651 
9652     // general template
9653     template  void AssembleLinearForm<double>(Stack stack,const Mesh & Th,const FESpace & Vh,KN_<double> * B,const  FormLinear * const l);
9654 
9655     template   void AssembleBilinearForm<double>(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
9656                                                  MatriceCreuse<double>  & A, const  FormBilinear * b  );
9657 
9658     template   void AssembleBilinearForm<double>(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
9659                                                  MatriceMap<double> & A, const  FormBilinear * b  );
9660 
9661     template  void AssembleLinearForm<Complex>(Stack stack,const Mesh & Th,const FESpace & Vh,KN_<Complex> * B,const  FormLinear * const l);
9662 
9663     template   void AssembleBilinearForm<Complex>(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
9664                                                   MatriceCreuse<Complex>  & A, const  FormBilinear * b  );
9665 
9666     template   void AssembleBilinearForm<Complex>(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
9667                                                   MatriceMap<Complex> & A, const  FormBilinear * b  );
9668 
9669 
9670 
9671     /////// 2d case
9672     // instantation for type double
9673     template  bool AssembleVarForm<double,MatriceCreuse<double>,FESpace >(Stack stack,const FESpace::Mesh & Th,
9674                                                                           const FESpace & Uh,const FESpace & Vh,bool sym,
9675                                                                           MatriceCreuse<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9676     template  bool AssembleVarForm<double,MatriceMap<double>,FESpace >(Stack stack,const  FESpace::Mesh & Th,
9677                                                                                 const FESpace & Uh,const FESpace & Vh,bool sym,
9678                                                                                 MatriceMap<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9679     template   void AssembleBC<double,FESpace>(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
9680                                                MatriceCreuse<double>  * A,KN_<double> * B,KN_<double> * X, const list<C_F0> &largs , double tgv  );
9681     // instantation for type complex
9682     template  bool AssembleVarForm<Complex,MatriceCreuse<Complex>,FESpace >(Stack stack,const FESpace::Mesh & Th,
9683                                                                             const FESpace & Uh,const FESpace & Vh,bool sym,
9684                                                                             MatriceCreuse<Complex>  * A,KN_<Complex> * B,const list<C_F0> &largs );
9685 
9686     template  bool AssembleVarForm<Complex,MatriceMap<Complex>,FESpace >(Stack stack,const FESpace::Mesh & Th,
9687                                                                                   const FESpace & Uh,const FESpace & Vh,bool sym,
9688                                                                                   MatriceMap<Complex> * A,KN_<Complex> * B,const list<C_F0> &largs );
9689 
9690     template   void AssembleBC<Complex,FESpace>(Stack stack,const Mesh & Th,const FESpace & Uh,const FESpace & Vh,bool sym,
9691                                                 MatriceCreuse<Complex>  * A,KN_<Complex> * B,KN_<Complex> * X, const list<C_F0> &largs , double tgv  );
9692 
9693 
9694     /////// 3D volume case
9695     // instantation for type double
9696     template  bool AssembleVarForm<double,MatriceCreuse<double>,FESpace3 >(Stack stack,const  FESpace3::Mesh & Th,
9697                                                                            const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
9698                                                                            MatriceCreuse<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9699     template  bool AssembleVarForm<double,MatriceMap<double>,FESpace3 >(Stack stack,const  FESpace3::Mesh & Th,
9700                                                                                  const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
9701                                                                                  MatriceMap<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9702     template   void AssembleBC<double,FESpace3>(Stack stack,const Mesh3 & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
9703                                                 MatriceCreuse<double>  * A,KN_<double> * B,KN_<double> * X, const list<C_F0> &largs , double tgv  );
9704 
9705     // instantation for type complex
9706     template  bool AssembleVarForm<Complex,MatriceCreuse<Complex>,FESpace3 >(Stack stack,const FESpace3::Mesh & Th,
9707                                                                              const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
9708                                                                              MatriceCreuse<Complex>  * A,KN_<Complex> * B,const list<C_F0> &largs );
9709     template  bool AssembleVarForm<Complex,MatriceMap<Complex>,FESpace3 >(Stack stack,const FESpace3::Mesh & Th,
9710                                                                                    const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
9711                                                                                    MatriceMap<Complex> * A,KN_<Complex> * B,const list<C_F0> &largs );
9712     template   void AssembleBC<Complex,FESpace3>(Stack stack,const Mesh3 & Th,const FESpace3 & Uh,const FESpace3 & Vh,bool sym,
9713                                                  MatriceCreuse<Complex>  * A,KN_<Complex> * B,KN_<Complex> * X, const list<C_F0> &largs , double tgv  );
9714 
9715 
9716 
9717 
9718 
9719 
9720     /////// 3D surface case
9721     // instantation for type double
9722 
9723     template  bool AssembleVarForm<double,MatriceCreuse<double>,FESpaceS >(Stack stack,const  FESpaceS::Mesh & Th,
9724                                                                            const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
9725                                                                            MatriceCreuse<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9726     template  bool AssembleVarForm<double,MatriceMap<double>,FESpaceS >(Stack stack,const  FESpaceS::Mesh & Th,
9727                                                                                  const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
9728                                                                                  MatriceMap<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9729     template   void AssembleBC<double,FESpaceS>(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
9730                                                 MatriceCreuse<double>  * A,KN_<double> * B,KN_<double> * X, const list<C_F0> &largs , double tgv  );
9731 
9732     // instantation for type complex
9733     template  bool AssembleVarForm<Complex,MatriceCreuse<Complex>,FESpaceS >(Stack stack,const FESpaceS::Mesh & Th,
9734                                                                              const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
9735                                                                              MatriceCreuse<Complex>  * A,KN_<Complex> * B,const list<C_F0> &largs );
9736     template  bool AssembleVarForm<Complex,MatriceMap<Complex>,FESpaceS >(Stack stack,const FESpaceS::Mesh & Th,
9737                                                                                    const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
9738                                                                                    MatriceMap<Complex> * A,KN_<Complex> * B,const list<C_F0> &largs );
9739     template   void AssembleBC<Complex,FESpaceS>(Stack stack,const MeshS & Th,const FESpaceS & Uh,const FESpaceS & Vh,bool sym,
9740                                                 MatriceCreuse<Complex>  * A,KN_<Complex> * B,KN_<Complex> * X, const list<C_F0> &largs , double tgv
9741                                                 );
9742 
9743 
9744     /////// 3D  curve
9745     // instantation for type double
9746 
9747     template  bool AssembleVarForm<double,MatriceCreuse<double>,FESpaceL >(Stack stack,const  FESpaceL::Mesh & Th,
9748                                                                            const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
9749                                                                            MatriceCreuse<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9750     template  bool AssembleVarForm<double,MatriceMap<double>,FESpaceL >(Stack stack,const  FESpaceL::Mesh & Th,
9751                                                                         const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
9752                                                                         MatriceMap<double>  * A,KN_<double> * B,const list<C_F0> &largs );
9753     template   void AssembleBC<double,FESpaceL>(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
9754                                                 MatriceCreuse<double>  * A,KN_<double> * B,KN_<double> * X, const list<C_F0> &largs , double tgv  );
9755 
9756     // instantation for type complex
9757     template  bool AssembleVarForm<Complex,MatriceCreuse<Complex>,FESpaceL >(Stack stack,const FESpaceL::Mesh & Th,
9758                                                                              const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
9759                                                                              MatriceCreuse<Complex>  * A,KN_<Complex> * B,const list<C_F0> &largs );
9760     template  bool AssembleVarForm<Complex,MatriceMap<Complex>,FESpaceL >(Stack stack,const FESpaceL::Mesh & Th,
9761                                                                           const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
9762                                                                           MatriceMap<Complex> * A,KN_<Complex> * B,const list<C_F0> &largs );
9763     template   void AssembleBC<Complex,FESpaceL>(Stack stack,const MeshL & Th,const FESpaceL & Uh,const FESpaceL & Vh,bool sym,
9764                                                  MatriceCreuse<Complex>  * A,KN_<Complex> * B,KN_<Complex> * X, const list<C_F0> &largs , double tgv
9765                                                  );
9766 
9767 }
9768 
9769 template class Call_FormLinear<v_fes>;
9770 template class Call_FormLinear<v_fes3>;
9771 template class Call_FormLinear<v_fesS>;
9772 template class Call_FormLinear<v_fesL>;
9773 template class Call_FormBilinear<v_fes>;
9774 template class Call_FormBilinear<v_fes3>;
9775 template class Call_FormBilinear<v_fesS>;
9776 template class Call_FormBilinear<v_fesL>;
9777