LoAdSG
curvedPoissonIntegrator.h
1/**********************************************************************************
2 * Author: Christoph Pflaum, Riccarda Scherner-Griesshammer
3 * Department Informatik Lehrstuhl 10 - Systemsimulation
4 * Friedrich-Alexander Universität Erlangen-Nürnberg
5 *
6*********************************************/
7
8#ifndef INTERATORPOISSONCURVED_H
9#define INTERATORPOISSONCURVED_H
10
11#include "../math_lib.h"
12#include "../abbrevi_common.h"
13#include "matrix.h"
14
20 public:
26 IntegratorPoissonCurved(D3vector (*transformEdge_[12])(double), D3vector (*transDerivs_[12])(double),D3vector corner_[8]){
27 //Transformation functions for the edges
28 for(int i=0;i<12;++i){
29 transformEdge[i] = transformEdge_[i];
30 transDerivs[i] = transDerivs_[i];
31 }
32
33 //Corners of the curvilinear block
34 for(int i=0;i<8;++i){
35 corner[i] = corner_[i];
36 }
37 }
38
39 //The mapping function that maps a unit cube to the curvilinear block.....(Old version)
40 D3vector Map1(double eta, double xi, double phi) const;
41
42 //The mapping function that maps a unit cube to the curvilinear block.....(New version)
43 D3vector Map2(double s, double t, double u) const;
44
45 //(Bit interpolation )Return x when bit = 1, else return 1-x
46 double bitInterp(int bit,double x) const;
47
48 //Return the index of the edge, given the dimension index and 2 bits
49 int edIndex(int dim_ind, int b1, int b2) const;
50
51 //Return the index of the corner given the 3 bits
52 int coIndex(int b1, int b2, int b3) const;
53
54 //If dim_ref == dim, then call bitSign, else call bitInterp
55 double interpOrSign(int b,int dim, int dim_ref,D3vector& x);
56
57 //Return -1.0 or 1.0 depending on sign
58 double bitSign(int b);
59
60 //Needed inside MapDeriv() for computation of edge indices
61 int edIndexDeriv(int edge_ref, int b1, int b2, int dim_ref);
62
63 //Functions that describe the problem
64 double A(D3vector& x_,int i, int j);
65
66 double b(D3vector& x_,int i);
67
68 double c(D3vector& x_);
69
70 //RHS for the solution u(x,y,z) = xyz(z-0.5)*cos(0.5*pi*(x²+y²))*sin(0.5*(x²+y²))
71 double f1(D3vector& x_);
72
73 //evaluate A at x and store it in mat
74 void evalA(Matrix& mat, D3vector& x);
75
76 //Evaluate the transpose of the jacobian at x and store in J
77 void evalJ(Matrix& J, D3vector& x);
78
79 //Evaluate the basis function u at x
80 double evalU(D3vector& x, BasisFunctionType *state);
81
82 //Evaluate the gradient of u at x
83 void evaldel(Matrix& delu, D3vector& x, BasisFunctionType *state);
84
85 //Used to compute one column of the transpose of jacobian. eg: dim = 0 means d_phi/d_s at x
86 D3vector MapDeriv(int dim, D3vector& x);
87
88 //Compute the LHS of the integration to fill in the entries of the local stiffness matrix
89 double stencil_integration(double p_left[3], double p_right[3], BasisFunctionType u[3], BasisFunctionType v[3]);
90
91 //Functions that describe the the variational formulation. Will go as input to the sparse grid integrator
92 double uAv(D3vector& x);
93
94 double ubv(D3vector& x_);
95
96 double cuv(D3vector& x_);
97
98 double fv(D3vector& x_);
99
100 //if U = true, modify state_u, else modify state_v
101 void setState(BasisFunctionType *state, bool U);
102
103 //set the limits of integration
104 void setLimits(D3vector &lim1_, D3vector& lim2_){
105 lim1 = lim1_;
106 lim2 = lim2_;
107 }
108
109 private:
110 D3vector (*transformEdge[12])(double);
111 D3vector (*transDerivs[12])(double);
112 D3vector corner[8];
113
114 D3vector lim1;
115 D3vector lim2;
116
117 BasisFunctionType state_u[3];
118 BasisFunctionType state_v[3];
119
120};
121
122//Functions that describe the problem
123double IntegratorPoissonCurved::A(D3vector& x_,int i, int j){
124 if(i == j){
125 return 1.0;
126 }
127 else{
128 return 0.0;
129 }
130}
131
132double IntegratorPoissonCurved::b(D3vector& x_,int i){
133 return 0.0;
134}
135
136double IntegratorPoissonCurved::c(D3vector& x_){
137 return 0.0;
138}
139
140//RHS for the solution u(x,y,z) = xyz(z-0.5)*cos(0.5*pi*(x²+y²))*sin(0.5*(x²+y²))
141double IntegratorPoissonCurved::f1(D3vector& x_){
142 double x = x_[0], y = x_[1], z = x_[2];
143
144 double pi = M_PI;
145
146 double sin_b = sin(0.5*pi*(x*x+y*y));
147 double cos_b = cos(0.5*pi*(x*x+y*y));
148 double z_b = (z-0.5);
149
150 double result = 0.0;
151
152 result += 6.0*pi*x*y*z*z_b*sin_b*sin_b - \
153 6.0*pi*x*y*z*z_b*cos_b*cos_b - \
154 2.0*x*y*sin_b*cos_b + \
155 4.0*pi*pi*x*y*y*y*z*z_b*sin_b*cos_b +\
156 4.0*pi*pi*x*x*x*y*z*z_b*sin_b*cos_b;
157
158 return result;
159}
160
161//Functions that describe the the variational formulation. Will go as input to the sparse grid integrator
162double IntegratorPoissonCurved::uAv(D3vector& x){
163 D3vector x_new = Map2(x[0],x[1],x[2]);
164
165 Matrix AoPhi(3,3),A_star(3,3),Jt(3,3),J_in(3,3),Jt_in(3,3),delU(1,3),delV(1,3),delVt(3,1);
166 double dJ;
167
168 evalA(AoPhi,x_new);
169 evalJ(Jt,x);
170
171 //dJ = fabs(Jt.det());
172 dJ = Jt.det();
173 if(dJ == 0.0 ){
174 std::cerr<<"Non invertible Jacobian encountered"<<std::endl;
175 return 0.0;
176 }
177
178 Jt_in = Jt.invert();
179 J_in = Jt_in.transpose();
180
181 A_star = J_in*AoPhi*Jt_in;
182 A_star.scale(dJ);
183
184 evaldel(delU,x,state_u);
185 evaldel(delV,x,state_v);
186 delVt = delV.transpose();
187
188 double result = (delU*A_star*delVt).value(0,0);
189 return result;
190 //return 2.0;
191}
192
193double IntegratorPoissonCurved::ubv(D3vector& x_){
194 return 0.0;
195}
196
197double IntegratorPoissonCurved::cuv(D3vector& x_){
198 return 0.0;
199}
200
201double IntegratorPoissonCurved::fv(D3vector& x_){
202 D3vector x_new = Map2(x_[0],x_[1],x_[2]);
203
204 Matrix Jt(3,3);
205 evalJ(Jt,x_);
206
207 //double result = f1(x_new)*fabs(Jt.det())*evalU(x_,state_v);
208 double result = f1(x_new)*Jt.det()*evalU(x_,state_v);
209
210 return result;
211}
212
213double IntegratorPoissonCurved::bitInterp(int bit, double x) const{
214 if(bit == 0){
215 return 1-x;
216 }
217 else if(bit == 1){
218 return x;
219 }
220 else{
221 std::cerr<<"Incorrect bit value. Can be either 0 or 1"<<std::endl;
222 return 0;
223 }
224}
225
226int IntegratorPoissonCurved::edIndex(int dim_ind, int b1, int b2) const{
227 int offset = b2*2+b1;
228
229 return (dim_ind*4+offset);
230
231}
232
233int IntegratorPoissonCurved::coIndex(int b1, int b2, int b3) const{
234 return (4*b3+2*b2+b1);
235}
236
237
238double IntegratorPoissonCurved::interpOrSign(int b,int dim, int dim_ref,D3vector& x){
239 if(dim == dim_ref){
240 return bitSign(b);
241 }
242 else{
243 return bitInterp(b,x[dim]);
244 }
245}
246
247double IntegratorPoissonCurved::bitSign(int b){
248 double ret = (b == 0)?-1.0:1.0;
249 return ret;
250}
251
252
253int IntegratorPoissonCurved::edIndexDeriv(int edge_ref, int b1, int b2, int dim_ref){
254 if(dim_ref == 0){
255 return edIndex(edge_ref/4,b1,b2);
256 }
257 else if(dim_ref == 1 && edge_ref == 0){
258 return edIndex(edge_ref/4,b1,b2);
259 }
260 else if(dim_ref == 2 && edge_ref == 8){
261 return edIndex(edge_ref/4,b1,b2);
262 }
263 else{
264 return edIndex(edge_ref/4,b2,b1);
265 }
266}
267
268
269D3vector IntegratorPoissonCurved::Map2(double s, double t, double u) const{
270 D3vector ret(0.0,0.0,0.0);
271
272 //Interpolation along the edges of the domain
273 for(int b1 = 0; b1 <=1; b1 ++){
274 for(int b2 = 0; b2 <= 1; b2 ++){
275 ret = ret + bitInterp(b1,t)*bitInterp(b2,u)*transformEdge[edIndex(0,b1,b2)](s);
276 ret = ret + bitInterp(b1,s)*bitInterp(b2,u)*transformEdge[edIndex(1,b1,b2)](t);
277 ret = ret + bitInterp(b1,s)*bitInterp(b2,t)*transformEdge[edIndex(2,b1,b2)](u);
278 }
279 }
280
281 //Interpolation along the corners of the domain
282 for(int b1 = 0; b1 <=1; b1 ++){
283 for(int b2 = 0; b2 <= 1; b2 ++){
284 for(int b3 = 0; b3 <= 1; b3 ++){
285 ret = ret - 2*bitInterp(b1,s)*bitInterp(b2,t)*bitInterp(b3,u)*corner[coIndex(b1,b2,b3)];
286 }
287 }
288 }
289
290 return ret;
291}
292
293void IntegratorPoissonCurved::evalA(Matrix& mat, D3vector& x){
294 for(int i = 0; i<3; i++){
295 for(int j = 0; j<3; j++){
296 mat.value(i,j) = A(x,i,j);
297 }
298 }
299}
300
301D3vector IntegratorPoissonCurved::MapDeriv(int dim,D3vector& x){
302
303 D3vector ret(0.0,0.0,0.0);
304
305 double s1 = x[dim], s2 = x[(dim+1)%3], s3 = x[(dim+2)%3];
306 int ed1 = dim*4, ed2 = ((dim+1)%3)*4, ed3 = ((dim+2)%3)*4;
307
308 //Terms related to edge interpolation
309 for(int b1=0; b1<=1; b1++){
310 for(int b2=0; b2<=1; b2++){
311 ret = ret + bitInterp(b1,s2)*bitInterp(b2,s3)*transDerivs[edIndexDeriv(ed1,b1,b2,dim)](s1);
312
313 ret = ret + bitSign(b1)*bitInterp(b2,s3)*transformEdge[edIndexDeriv(ed2,b1,b2,dim)](s2);
314
315 ret = ret + bitSign(b1)*bitInterp(b2,s2)*transformEdge[edIndexDeriv(ed3,b1,b2,dim)](s3);
316 }
317 }
318
319 //Terms related to corner interpolation
320 for(int b1 = 0; b1 <=1; b1 ++){
321 for(int b2 = 0; b2 <= 1; b2 ++){
322 for(int b3 = 0; b3 <= 1; b3 ++){
323 ret = ret - 2*interpOrSign(b1,0,dim,x)*interpOrSign(b2,1,dim,x)*interpOrSign(b3,2,dim,x)*corner[coIndex(b1,b2,b3)];
324 }
325 }
326 }
327
328 return ret;
329}
330
331void IntegratorPoissonCurved::evalJ(Matrix& J, D3vector& x){
332 D3vector cols[3];
333 cols[0] = MapDeriv(0,x);
334 cols[1] = MapDeriv(1,x);
335 cols[2] = MapDeriv(2,x);
336
337 for(int i=0;i<3;i++){
338 for(int j=0;j<3;j++){
339 J.value(i,j) = (cols[i])[j];
340 }
341 }
342}
343
344double IntegratorPoissonCurved::evalU(D3vector& x, BasisFunctionType *state){
345 double result = 1.0;
346 for(int i=0;i<3;i++){
347 if(state[i] == leftBasis){
348 result *= (lim2[i]-x[i])/(lim2[i]-lim1[i]);
349 }
350 else{
351 result *= (x[i]-lim1[i])/(lim2[i]-lim1[i]);
352 }
353 }
354
355 return result;
356}
357
358//Evaluate the gradient of u at x
359void IntegratorPoissonCurved::evaldel(Matrix& delu, D3vector& x, BasisFunctionType *state){
360 double prod[3];
361 int ind1,ind2;
362
363 for(int i=0;i<3;i++){
364 if(state[i] == leftBasis){
365 delu.value(0,i) = -1.0/(lim2[i]-lim1[i]);
366 prod[i] = (lim2[i]-x[i])/(lim2[i]-lim1[i]);
367 }
368 else{
369 delu.value(0,i) = 1.0/(lim2[i]-lim1[i]);
370 prod[i] = (x[i]-lim1[i])/(lim2[i]-lim1[i]);
371 }
372 }
373
374 for(int i=0;i<3;i++){
375 ind1 = (i+1)%3;
376 ind2 = (i+2)%3;
377 delu.value(0,i) *= prod[ind1]*prod[ind2];
378 }
379}
380
381double IntegratorPoissonCurved::stencil_integration(double p_left[3], double p_right[3],
382 BasisFunctionType u[3], BasisFunctionType v[3]) {
383
384 lim1 = D3vector(p_left[0],p_left[1],p_left[2]);
385 lim2 = D3vector(p_right[0],p_right[1],p_right[2]);
386
387 //Modifying state_u and state_v lets the functions uAv(), ubv() and cuv() know which types of u and v we are dealing with
388 for(int i=0;i<3;i++){
389 state_u[i] = u[i];
390 state_v[i] = v[i];
391 }
392
393 //Divide the variational formulation into 3 parts
394 //double integral1 = IG.smolyakIntegrate(*this,this->uAv,lim1,lim2,10);//Integrate grad(u_tilda)*A*grad(v_tilda)
395 // double integral2 = IG.smolyakIntegrate(&this->ubv,lim1,lim2,10);//Integrate <grad(v_tilda)*b*>v_tilda
396 // double integral3 = IG.smolyakIntegrate(&this->cuv,lim1,lim2,10);//Integrate c*u_tilda*v_tilda
397
398 return 0;
399}
400
401void IntegratorPoissonCurved::setState(BasisFunctionType *state, bool U){
402 if(U){
403 for(int i=0;i<3;i++){
404 state_u[i] = state[i];
405 }
406 }
407 else{
408 for(int i=0;i<3;i++){
409 state_v[i] = state[i];
410 }
411 }
412}
413
414D3vector IntegratorPoissonCurved::Map1(double eta, double xi, double phi) const {
415 D3vector Psi[12];
416 D3vector PL, PR;
417 D3vector PSW, PSE, PNW, PNE;
418 D3vector Pres, PT, PD;
419 double p_EW, p_NS;
420 double p;
421
422 for ( int ed = 0; ed < 12; ++ed ) {
423 p = find_p ( ( Edges_cell ) ed,eta,xi,phi ); //p is either eta, phi or xi
424 Psi[ed] = transformEdge[ed]( p );
425 PL = corner[ Transform ( ( Edges_cell ) ed,Ldir1D ) ]; // has to be implemeted to give corner[...]
426 PR = corner[ Transform ( ( Edges_cell ) ed,Rdir1D ) ];
427 Psi[ed] = Psi[ed] + PL + ( PR-PL ) * p;
428 }
429
430 Pres = D3vector ( 0.0,0.0,0.0 );
431 for ( int md = 0; md < 3; ++md )
432 {
433 if ( md==0 ) // EW
434 {
435 PSW = Psi[SDed];
436 PSE = Psi[NDed];
437 PNW = Psi[STed];
438 PNE = Psi[NTed];
439
440 p_EW = xi;
441 p_NS = phi;
442 }
443 if ( md==1 ) // NS
444 {
445 PSW = Psi[WDed];
446 PSE = Psi[EDed];
447 PNW = Psi[WTed];
448 PNE = Psi[ETed];
449
450 p_EW = eta;
451 p_NS = phi;
452 }
453 if ( md==2 ) // TD
454 {
455 PSW = Psi[SWed];
456 PSE = Psi[SEed];
457 PNW = Psi[NWed];
458 PNE = Psi[NEed];
459
460 p_EW = eta;
461 p_NS = xi;
462 }
463 Pres = Pres + PSW +
464 ( PSE - PSW ) * p_EW +
465 ( PNW - PSW ) * p_NS +
466 ( PNE - PSE - PNW + PSW ) * p_EW * p_NS;
467 }
468
469 PD = corner[WSDdir3D] +
470 ( corner[ESDdir3D] - corner[WSDdir3D] ) * eta +
471 ( corner[WNDdir3D] - corner[WSDdir3D]) * xi +
472 ( corner[ENDdir3D] - corner[ESDdir3D] - corner[WNDdir3D] + corner[WSDdir3D]) * eta * xi;//remove all Hs and add corner[...dir3D] to compile
473
474 PT = corner[WSTdir3D] +
475 ( corner[ESTdir3D] - corner[WSTdir3D] ) * eta +
476 ( corner[WNTdir3D] - corner[WSTdir3D] ) * xi +
477 ( corner[ENTdir3D] - corner[ESTdir3D] - corner[WNTdir3D] + corner[WSTdir3D] ) * eta * xi;
478
479 Pres = Pres -
480 2.0 * ( PD + ( PT-PD ) * phi );
481
482 return Pres;
483}
484
485
486
487
488
489
490
491
492
493#endif
Definition curvedPoissonIntegrator.h:19
IntegratorPoissonCurved(D3vector(*transformEdge_[12])(double), D3vector(*transDerivs_[12])(double), D3vector corner_[8])
Definition curvedPoissonIntegrator.h:26
Definition interfaceMatrices.h:21