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= ¶mmatElement_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= ¶mmatElement_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= ¶mmatElement_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= ¶mmatElement_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