8#include "../indices/index.h"
13#include "InterfaceIntegration/interfaceMatrices.h"
14#include "InterfaceIntegration/constantIntegrators.h"
15#include "InterfaceIntegration/interatorBasisFunction.h"
16#include "InterfaceIntegration/HelmholtzIntegrator/helmIntegrator.h"
18#include "../cells/celldimension.h"
19#include "../cells/iterator_neu.h"
20#include "../applications/norms.h"
21#include "../iterator/RectangularIterator.h"
22#include "PoissonStencil.h"
36template <
class Stencil
class>
37double getLocalStencilBoundary(IndexDimension Index, Depth &T, VectorSparseG &u, Stencilclass stencilclass) {
40 stencilclass.initialize(T);
43 IndexDimension NextTest;
46 NextTest = Index.nextThree_boundary(&mc, T.returnTiefen());
50 value = stencilclass.returnValue(Index, mc);
51 val = val + value * u.getValue(NextTest);
65 for(
int d=0; d<DimensionSparseGrid; d++){
66 if(mc.getRichtung(d)==Mitte&¢er.isNotAtBoundary(d))val=2*val;
67 if(mc.getRichtung(d)==Links&¢er.isAtLeftBoundary(d)) val=0.0;
68 if(mc.getRichtung(d)==Rechts&¢er.isAtRightBoundary(d)) val=0.0;
72 Indices =
new IndexDimension[maxShift];
73 recursive(center,0,mc,T);
80 for(
int j=0; j<maxShift;j++){
81 Indices[j].PrintCoord();
88 return (shiftNumber<maxShift);
95 IndexDimension getCell(){
96 return Indices[shiftNumber];
105 IndexDimension* Indices;
110 if(d == DimensionSparseGrid) {
115 if (mc.getRichtung(d) == Mitte) {
117 recursive(I, D, mc,T);
119 if(!I.isAtLeftBoundary(d)){
120 I = I.nextLeft(d, T.at(d));
121 recursive(I, D, mc, T);
124 if (mc.getRichtung(d) == Links && !I.isAtLeftBoundary(d)) {
125 I = I.nextLeft(d, T.at(d));
126 recursive(I, D, mc,T);
128 if (mc.getRichtung(d) == Rechts &&!I.isAtRightBoundary(d)) {
129 recursive(I, D, mc,T);
138class StencilTemplate{
140 template<
class StencilA,
class StencilB>
146 virtual void resetActiveWorkers(){};
147 virtual void receiveApplySendOnActiveWorkers(){};
148 virtual int getNumberProcesses(){
return 0;};
149 virtual int size(){
return 0;};
150 std::vector<int> active_worker;
151 virtual void applyLocalStiffnessMatricesDepth(VectorSparseG& u,VectorSparseG& z,Depth& depth){};
152 virtual double applyLocalStiffnessMatricesFixedDepthIndex_onNode(VectorSparseG& input, VectorSparseG& output, Depth& D, IndexDimension& Index){
return 0.0;};
153 virtual int getNodeForDepth(Depth& T){
return 0;};
154 void applyLocalStiffnessMatricesOnIndices_onNode(VectorSparseG& input, VectorSparseG& output, Depth& D, std::vector<IndexDimension>& Indices){};
159 virtual inline void initialize(Depth &T_) {
162 for (
int d = 0; d < DimensionSparseGrid; d++) {
164 if (exp == 0) meshwidth[d] = 1.0;
167 int value2 = 1 << exp;
168 exponent[d] = double(value2);
169 meshwidth[d] = 1.0 / double(value2);
175 inline void copyInitialization(StencilTemplate& stencil){
178 for (
int d = 0; d < DimensionSparseGrid; d++) {
179 meshwidth[d]=stencil.meshwidth[d];
180 exponent[d]=stencil.exponent[d];
187 virtual inline void applyStencilOnCell(CellDimension& cell,VectorSparseG& input, VectorSparseG& output){
189 for(CellIndexIterator outerIter(&cell); outerIter.goon(); ++outerIter) {
192 IndexDimension p = outerIter.getIndex();
195 bool occP = output.getSparseGrid()->occupied(kp, p);
196 CellIndexDirection dirP = outerIter.getCellIndexDirection();
201 for (CellIndexIterator innerIter(outerIter); innerIter.goon(); ++innerIter) {
204 IndexDimension q = innerIter.getIndex();
205 if (q.isNotAtBoundary()) {
207 CellIndexDirection dirQ = innerIter.getCellIndexDirection();
211 bool occQ = output.getSparseGrid()->occupied(kq, q);
214 double val = integration(cell, dirP, dirQ);
216 val = val * input.getValue(kp);
219 output.addToValue(kq, val);
221 double val_p = val * input.getValue(kp);
223 output.addToValue(kq, val_p);
225 double val_q = val * input.getValue(kq);
227 output.addToValue(kp, val_q);
248 virtual inline void applyStencilOnCell_BinaryIterator(CellDimension& cell,VectorSparseG& input, VectorSparseG& output){
252 int iterend = PowerOfTwo<DimensionSparseGrid>::value;
254 CellIndexIterator outerIter(&cell);
255 for(
int iteri=0; iteri<iterend ; iteri++) {
256 IndexDimension p = outerIter.getIndexByBinary(iteri);
258 bool occP = output.getSparseGrid()->occupied(kp, p);
259 CellIndexDirection dirP = outerIter.getCellIndexDirection();
261 for (
int iterj = iteri; iterj < iterend; iterj++) {
262 IndexDimension q = outerIter.getIndexByBinary(iterj);
263 if (q.isNotAtBoundary()) {
264 CellIndexDirection dirQ = outerIter.getCellIndexDirection();
267 bool occQ = output.getSparseGrid()->occupied(kq, q);
270 double val = integration(cell, dirP, dirQ);
272 val = val * input.getValue(kp);
275 output.addToValue(kq, val);
277 double val_p = val * input.getValue(kp);
279 output.addToValue(kq, val_p);
281 double val_q = val * input.getValue(kq);
283 output.addToValue(kp, val_q);
294 virtual inline void applyStencilOnCell_nosymmetry(CellDimension& cell,VectorSparseG& input, VectorSparseG& output) {
297 for (CellIndexIterator outerIter(&cell); outerIter.goon(); ++outerIter) {
300 IndexDimension p = outerIter.getIndex();
303 bool occP = output.getSparseGrid()->occupied(kp, p);
304 CellIndexDirection dirP = outerIter.getCellIndexDirection();
311 for (CellIndexIterator innerIter(&cell); innerIter.goon(); ++innerIter) {
313 IndexDimension q = innerIter.getIndex();
314 if(q.isNotAtBoundary()){
315 CellIndexDirection dirQ = innerIter.getCellIndexDirection();
319 bool occQ= output.getSparseGrid()->occupied(kq,q);
323 double val = integration(cell, dirP, dirQ);
324 val =val*input.getValue(kp);
325 output.addToValue(kq, val);
334 virtual inline void applyStencilOnCellMPI(CellDimension& cell,VectorSparseG& input, VectorSparseG& output) {
337 int iterend = POW2(DimensionSparseGrid);
341 CellIndexIterator outerIter(&cell);
343 for (
int iteri = 0; iteri < iterend; iteri++) {
346 IndexDimension p = outerIter.getIndex();
349 bool occP = output.getSparseGrid()->occupied(kp, p);
350 CellIndexDirection dirP = outerIter.getCellIndexDirection();
354 for (CellIndexIterator innerIter(outerIter); innerIter.goon(); ++innerIter) {
355 IndexDimension q = innerIter.getIndex();
356 if (q.isNotAtBoundary()) {
357 CellIndexDirection dirQ = innerIter.getCellIndexDirection();
361 bool occQ = output.getSparseGrid()->occupied(kq, q);
363 double val = integration(cell, dirP, dirQ);
365 val =val*input.getValue(kp);
367 output.addToValue(kq, val);
369 double val_p =val*input.getValue(kp);
371 output.addToValue(kq, val_p);
373 double val_q =val*input.getValue(kq);
375 output.addToValue(kp, val_q);
391 virtual inline void applyStencilOnCell_MPI_OMP(CellDimension& cell,VectorSparseG& input, VectorSparseG& output) {
394 int iterend = POW2(DimensionSparseGrid);
395 CellIndexIterator outerIter(&cell);
397 int entries = iterend*(iterend+1)/2;
398 CellIndexDirection pCellIndexDirection[2][entries];
399 bool calcIntgral[entries];
400 bool diagonalEntry[entries];
401 unsigned long occupied[2][entries];
402 double values[2][entries];
406 for (CellIndexIterator outerIter2(&cell); outerIter2.goon(); ++outerIter2){
408 IndexDimension p = outerIter2.getIndex();
410 bool occP = output.getSparseGrid()->occupied(kp, p);
411 CellIndexDirection dirP = outerIter2.getCellIndexDirection();
414 for (CellIndexIterator innerIter(outerIter2); innerIter.goon(); ++innerIter) {
415 IndexDimension q = innerIter.getIndex();
417 if (q.isNotAtBoundary()) {
419 CellIndexDirection dirQ = innerIter.getCellIndexDirection();
423 bool occQ = output.getSparseGrid()->occupied(kq, q);
425 calcIntgral[j] =
true;
426 pCellIndexDirection[0][j] = dirP;
427 pCellIndexDirection[1][j] = dirQ;
431 diagonalEntry[j] =
true;
435 diagonalEntry[j] =
false;
438 calcIntgral[j] =
false;
442 calcIntgral[j] =
false;
449#pragma omp parallel for schedule(dynamic)
450 for (
int i = 0; i < entries; i++) {
451 if (calcIntgral[i]) {
452 double val = integration(cell, pCellIndexDirection[0][i], pCellIndexDirection[1][i]);
453 unsigned long kp = occupied[0][i];
454 unsigned long kq = occupied[1][i];
455 if (diagonalEntry[i]) {
456 val = val * input.getValue(kp);
460 double val_p = val * input.getValue(kp);
461 values[1][i] = val_p;
464 double val_q = val * input.getValue(kq);
466 values[0][i] = val_q;
477 for (
int i = 0; i < entries; i++) {
478 if (calcIntgral[i]) {
479 unsigned long kp = occupied[0][i];
480 unsigned long kq = occupied[1][i];
481 if (diagonalEntry[i]) {
483 double val =values[0][i];
485 output.addToValue(kq, val);
488 double val_p =values[1][i];
491 output.addToValue(kq, val_p);
493 double val_q= values[0][i];
494 output.addToValue(kp, val_q);
503 virtual inline void applyStencilOnCell_MPI_OMP_nosymmetry(CellDimension& cell,VectorSparseG& input, VectorSparseG& output) {
507 int iterend = POW2(DimensionSparseGrid);
509 CellIndexIterator outerIter(&cell);
511 int entries = iterend*iterend;
512 CellIndexDirection pCellIndexDirection[2][entries];
513 bool calcIntgral[entries];
515 unsigned long occupied[2][entries];
516 double values[entries];
520 for (CellIndexIterator outerIter2(&cell); outerIter2.goon(); ++outerIter2){
522 IndexDimension p = outerIter2.getIndex();
524 bool occP = output.getSparseGrid()->occupied(kp, p);
525 CellIndexDirection dirP = outerIter2.getCellIndexDirection();
549 for (CellIndexIterator innerIter(&cell); innerIter.goon(); ++innerIter) {
550 IndexDimension q = innerIter.getIndex();
552 if (q.isNotAtBoundary() && p.isNotAtBoundary()){
553 CellIndexDirection dirQ = innerIter.getCellIndexDirection();
557 bool occQ = output.getSparseGrid()->occupied(kq, q);
559 calcIntgral[j] =
true;
560 pCellIndexDirection[0][j] = dirP;
561 pCellIndexDirection[1][j] = dirQ;
565 calcIntgral[j] =
false;
569 calcIntgral[j] =
false;
577#pragma omp parallel for schedule(runtime)
578 for (
int i = 0; i < entries; i++) {
579 if (calcIntgral[i]) {
580 double val = integration(cell, pCellIndexDirection[0][i], pCellIndexDirection[1][i]);
581 unsigned long kp = occupied[0][i];
584 double val_p = val * input.getValue(kp);
591 for (
int i = 0; i < entries; i++) {
592 if (calcIntgral[i]) {
594 unsigned long kq = occupied[1][i];
595 double val_p =values[i];
596 output.addToValue(kq, val_p);
667 virtual inline double returnValue(
const IndexDimension &Index,
const MultiDimCompass &mc){
674 CellIterator cells(mc,T,Index);
677 for(cells.start(); cells.goon();++cells){
678 IndexDimension cell = cells.getCell();
679 if(cellInGrid(cell)) {
682 val += localValue(Index, cell, mc);
703 bool cellInGrid(IndexDimension cell)
const{
704 IndexDimension Imin = cell;
705 IndexDimension Imax = cell;
707 for(
int d=0; d<DimensionSparseGrid; d++){
708 Imax = Imax.nextRight(d,T.at(d));
712 for(;iterator.goon();++iterator){
713 IndexDimension I = iterator.getIndex();
715 if(I.isNotAtBoundary() && !(grid.occupied(k,I)))
return false;
735 virtual inline double localValue(
const IndexDimension ¢er ,
const IndexDimension& cell,
const MultiDimCompass &mc)
const{
740 virtual inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
742 cout <<
"not implemented yet! " << endl;
748 virtual TypeMatrixVectorMultiplication getTypeMatrixVectorMultiplication(){
return typeMatrixVectorMultiplication;};
757 inline double integral_left(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
759 double p=center.coordinate(d);
760 double h=meshwidth[d];
761 double x = cell.coordinate(d);
762 double val1=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
765 double val2=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
770 inline double integral_right(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
771 double p=center.coordinate(d);
772 double h=meshwidth[d];
773 double x = cell.coordinate(d);
775 double val1=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
778 double val2=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
785 inline double integral_CenterR(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
788 double p =center.coordinate(d);
789 double h =meshwidth[d];
790 double x = cell.coordinate(d);
794 double val1= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
798 double val2= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
807 inline double integral_CenterL(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
808 double p = center.coordinate(d);
809 double h=meshwidth[d];
810 double x = cell.coordinate(d);
811 double val1=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
815 double val2=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
823 virtual inline double integral_RR(CellDimension& cell,
int d){
824 double b = cell.getRightBoundary(d);
825 double a = cell.getLeftBoundary(d);
829 double val1=(1.0/3.0)*h*h*h;
835 virtual inline double integral_LL(CellDimension& cell,
int d){
836 double b = cell.getRightBoundary(d);
837 double a = cell.getLeftBoundary(d);
842 double val1=(1.0/3.0)*h*h*h;
847 virtual inline double integral_LR(CellDimension& cell,
int d){
848 double b = cell.getRightBoundary(d);
849 double a = cell.getLeftBoundary(d);
852 double val1=(1.0/6.0)*h*h*h;
859 double meshwidth[DimensionSparseGrid];
860 double exponent[DimensionSparseGrid];
866 TypeMatrixVectorMultiplication typeMatrixVectorMultiplication = StencilOnTheFly;
873class HelmHoltz:
public StencilTemplate{
878 inline double localValue(
const IndexDimension ¢er ,
const IndexDimension& cell,
const MultiDimCompass &mc)
const{
882 for(
int d=0; d<DimensionSparseGrid; d++) {
883 if (mc.getRichtung(d) == Mitte && cell.getIndex(d) == center.getIndex(d))
884 value *= integral_CenterR(center,cell, d);
885 if (mc.getRichtung(d) == Mitte && !(cell.getIndex(d) == center.getIndex(d)))
886 value *= integral_CenterL(center,cell, d);
887 if (mc.getRichtung(d) == Links && !(cell.getIndex(d) == center.getIndex(d)))
888 value *= integral_left(center,cell, d);
889 if (mc.getRichtung(d) == Rechts && cell.getIndex(d) == center.getIndex(d))
890 value *= integral_right(center,cell, d);
892 value = exponent[d]*exponent[d]*value;
900 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
903 for(
int d=0; d<DimensionSparseGrid; d++) {
906 if (dirP.getDirection(d)==dirQ.getDirection(d)){
907 value *= integral_RR(cell, d);
908 value = exponent[d] * exponent[d] * value;
912 value *= integral_LR(cell,d);
913 value = exponent[d] * exponent[d] * value;
924 inline double integral_left(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
926 double p =center.coordinate(d);
927 double h=meshwidth[d];
928 double x = cell.coordinate(d);
929 double val1=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
932 double val2=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
937 inline double integral_right(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
938 double p =center.coordinate(d);
939 double h=meshwidth[d];
940 double x = cell.coordinate(d);
942 double val1=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
945 double val2=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
951 inline double integral_CenterR(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
953 double p =center.coordinate(d);
954 double h=meshwidth[d];
955 double x = cell.coordinate(d);
959 double val1= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
963 double val2= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
970 inline double integral_CenterL(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
971 double p = center.coordinate(d);
972 double h=meshwidth[d];
973 double x = cell.coordinate(d);
974 double val1=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
978 double val2=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
991class StencilInterface:
public StencilTemplate {
994 StencilInterface(
AdaptiveSparseGrid& grid_,
const F &varCoeff) : StencilTemplate(grid_), localStiffnessHelm(
995 varCoeff, 1e-8, 0, 8, 1.0e8) {
999 localValue(
const IndexDimension ¢er,
const IndexDimension &cell,
const MultiDimCompass &mc)
const {
1001 BasisFunctionType u[DimensionSparseGrid];
1002 BasisFunctionType v[DimensionSparseGrid];
1003 double p_left[DimensionSparseGrid];
1004 double p_right[DimensionSparseGrid];
1009 bool integrate =
true;
1010 for (
int d = 0; d < DimensionSparseGrid; d++) {
1011 p_left[d] = cell.coordinate(d);
1012 p_right[d] = cell.coordinate(d) + meshwidth[d];
1014 if (mc.getRichtung(d) == Mitte && cell.getIndex(d) == center.getIndex(d)) {
1017 }
else if (mc.getRichtung(d) == Mitte && cell.getIndex(d) != center.getIndex(d)) {
1021 }
else if (mc.getRichtung(d) == Links && cell.getIndex(d) != center.getIndex(d)) {
1024 }
else if (mc.getRichtung(d) == Rechts && cell.getIndex(d) == center.getIndex(d)) {
1037 value = localStiffnessHelm.stencil_integration(p_left, p_right, u, v);
1046 static int stencil_count;
1048 inline double integration(CellDimension &cell, CellIndexDirection &dirP, CellIndexDirection &dirQ) {
1050 BasisFunctionType u[DimensionSparseGrid];
1051 BasisFunctionType v[DimensionSparseGrid];
1052 double p_left[DimensionSparseGrid];
1053 double p_right[DimensionSparseGrid];
1057 for (
int d = 0; d < DimensionSparseGrid; d++) {
1058 p_left[d] = cell.getLeftBoundary(d);
1059 p_right[d] = cell.getRightBoundary(d);
1062 if (dirP.getDirection(d) == Left) {
1068 if (dirQ.getDirection(d) == Left) {
1076 value = localStiffnessHelm.stencil_integration(p_left, p_right, u, v);
1120int StencilInterface<F>::stencil_count=0;
1135 inline double localValue(
const IndexDimension ¢er ,
const IndexDimension& cell,
const MultiDimCompass &mc)
const{
1139 for(
int d=0; d<DimensionSparseGrid; d++) {
1140 if (mc.getRichtung(d) == Mitte && cell.getIndex(d) == center.getIndex(d))
1141 value *= integral_CenterR(center,cell, d);
1142 if (mc.getRichtung(d) == Mitte && !(cell.getIndex(d) == center.getIndex(d)))
1143 value *= integral_CenterL(center,cell, d);
1144 if (mc.getRichtung(d) == Links && !(cell.getIndex(d) == center.getIndex(d)))
1145 value *= integral_left(center,cell, d);
1146 if (mc.getRichtung(d) == Rechts && cell.getIndex(d) == center.getIndex(d))
1149 value = exponent[d]*exponent[d]*value;
1155 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
1158 for(
int d=0; d<DimensionSparseGrid; d++) {
1161 if (dirP.getDirection(d)==dirQ.getDirection(d)){
1162 if(dirP.getDirection(d)==Right) {
1163 value *= integral_LL(cell, d);
1166 value = exponent[d] * exponent[d] * value;
1168 if(dirP.getDirection(d)==Left) {
1169 value *= integral_RR(cell, d);
1171 value = exponent[d] * exponent[d] * value;
1175 value *= integral_LR(cell,d);
1177 value = exponent[d] * exponent[d] * value;
1191 inline double integral_left(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1193 double p =center.coordinate(d);
1194 double h=meshwidth[d];
1196 double x = cell.coordinate(d);
1197 double val1=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
1198 double val12=-(1.0/5.0)*x*x*x*x*x+(1.0/4.0)*p*x*x*x*x+(1.0/4.0)*(p-h)*x*x*x*x-(1.0/3.0)*p*(p-h)*x*x*x;
1200 val1 = val1 - val12;
1202 double val2=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
1203 double val22=-(1.0/5.0)*x*x*x*x*x+(1.0/4.0)*p*x*x*x*x+(1.0/4.0)*(p-h)*x*x*x*x-(1.0/3.0)*p*(p-h)*x*x*x;
1211 inline double integral_CenterL(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1212 double p =center.coordinate(d);
1213 double h=meshwidth[d];
1214 double x = cell.coordinate(d);
1216 double val1=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
1217 double val12=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p-h)*x*x*x*x+(1.0/3.0)*(p-h)*(p-h)*x*x*x;
1218 val1 = val1 - val12;
1222 double val2=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
1223 double val22=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p-h)*x*x*x*x+(1.0/3.0)*(p-h)*(p-h)*x*x*x;
1231 inline double integral_CenterR(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1233 double p =center.coordinate(d);
1234 double h=meshwidth[d];
1235 double x = cell.coordinate(d);
1238 double val1= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
1239 double val12=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*(p+h)*(p+h)*x*x*x;
1240 val1 = val1 - val12;
1243 double val2= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
1244 double val22=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*(p+h)*(p+h)*x*x*x;
1255 inline double integral_right(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1256 double p =center.coordinate(d);
1257 double h=meshwidth[d];
1258 double x = cell.coordinate(d);
1260 double val1=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
1261 double val12=(1.0/5.0)*x*x*x*x*x-(1.0/4.0)*p*x*x*x*x-(1.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*p*(p+h)*x*x*x;
1262 val1 = val1 + val12;
1265 double val2=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
1266 double val22=(1.0/5.0)*x*x*x*x*x-(1.0/4.0)*p*x*x*x*x-(1.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*p*(p+h)*x*x*x;
1273 inline double integral_RR(CellDimension& cell,
int d){
1274 double b = cell.getRightBoundary(d);
1275 double a = cell.getLeftBoundary(d);
1279 double val1=(-1.0*h*h*h*(-10.0 + 6.0*a*a + 3.0*a*b + b*b))/30.0;
1284 inline double integral_LL(CellDimension& cell,
int d){
1285 double b = cell.getRightBoundary(d);
1286 double a = cell.getLeftBoundary(d);
1290 double val1=(-1.0*h*h*h*(-10.0 + 6.0*b*b + 3.0*a*b + a*a))/30.0;
1294 inline double integral_LR(CellDimension& cell,
int d){
1295 double b = cell.getRightBoundary(d);
1296 double a = cell.getLeftBoundary(d);
1300 double val1=(-1.0*h*h*h*(-10.0 + 3.0*a*a + 4.0*a*b + 3.0*b*b))/60.0;
1321 inline double localValue(
const IndexDimension ¢er ,
const IndexDimension& cell,
const MultiDimCompass &mc)
const{
1325 for(
int d=0; d<DimensionSparseGrid; d++) {
1326 if (mc.getRichtung(d) == Mitte && cell.getIndex(d) == center.getIndex(d))
1327 value *= integral_CenterR(center,cell, d);
1328 if (mc.getRichtung(d) == Mitte && !(cell.getIndex(d) == center.getIndex(d)))
1329 value *= integral_CenterL(center,cell, d);
1330 if (mc.getRichtung(d) == Links && !(cell.getIndex(d) == center.getIndex(d)))
1331 value *= integral_left(center,cell, d);
1332 if (mc.getRichtung(d) == Rechts && cell.getIndex(d) == center.getIndex(d))
1333 value *= integral_right(center,cell, d);
1335 value = exponent[d]*exponent[d]*value;
1343 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
1346 for(
int d=0; d<DimensionSparseGrid; d++) {
1349 if (dirP.getDirection(d)==dirQ.getDirection(d)){
1350 value *= integral_RR(cell, d);
1351 value = exponent[d] * exponent[d] * value;
1355 value *= integral_LR(cell,d);
1356 value = exponent[d] * exponent[d] * value;
1367 inline double integral_left(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1369 double p =center.coordinate(d);
1370 double h=meshwidth[d];
1371 double x = cell.coordinate(d);
1372 double val1=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
1375 double val2=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
1380 inline double integral_right(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1381 double p =center.coordinate(d);
1382 double h=meshwidth[d];
1383 double x = cell.coordinate(d);
1385 double val1=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
1388 double val2=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
1394 inline double integral_CenterR(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1396 double p =center.coordinate(d);
1397 double h=meshwidth[d];
1398 double x = cell.coordinate(d);
1402 double val1= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
1406 double val2= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
1413 inline double integral_CenterL(
const IndexDimension& center,
const IndexDimension& cell,
int d)
const{
1414 double p = center.coordinate(d);
1415 double h=meshwidth[d];
1416 double x = cell.coordinate(d);
1417 double val1=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
1421 double val2=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
1433class StencilVariableCoeff{
1435 inline void initialize(Depth &T_) {
1438 poisson.initialize(T);
1440 for (
int d = 0; d < DimensionSparseGrid; d++) {
1442 if (exp == 0) meshwidth[d] = 1.0;
1445 int value2 = 1 << exp;
1446 exponent[d] = value2;
1447 meshwidth[d] = 1 / double(value2);
1456 inline double returnValue(
const IndexDimension &Index,
const MultiDimCompass &mc){
1460 for(
int d=0; d<DimensionSparseGrid; d++)
1461 coord[d]=Index.coordinate(d);
1463 CellIterator cells(mc,T,Index);
1466 for(cells.start(); cells.goon();++cells){
1467 IndexDimension cell = cells.getCell();
1468 val+= localValue(Index,cell,mc);
1475 val += poisson.returnValue(Index,mc);
1482 double integral_left(IndexDimension& cell,
int d)
const{
1484 double p = coord[d];
1485 double h=meshwidth[d];
1487 double x = cell.coordinate(d);
1488 double val1=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
1489 double val12=-(1.0/5.0)*x*x*x*x*x+(1.0/4.0)*p*x*x*x*x+(1.0/4.0)*(p-h)*x*x*x*x-(1.0/3.0)*p*(p-h)*x*x*x;
1491 val1 = val1 - val12;
1493 double val2=-(1.0/3.0)*x*x*x+0.5*(p-h)*x*x+0.5*p*x*x-p*(p-h)*x;
1494 double val22=-(1.0/5.0)*x*x*x*x*x+(1.0/4.0)*p*x*x*x*x+(1.0/4.0)*(p-h)*x*x*x*x-(1.0/3.0)*p*(p-h)*x*x*x;
1502 double integral_CenterL(IndexDimension& cell,
int d)
const{
1503 double p = coord[d];
1504 double h=meshwidth[d];
1505 double x = cell.coordinate(d);
1507 double val1=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
1508 double val12=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p-h)*x*x*x*x+(1.0/3.0)*(p-h)*(p-h)*x*x*x;
1509 val1 = val1 - val12;
1513 double val2=(1.0/3.0)*x*x*x-(p-h)*x*x+(p-h)*(p-h)*x;
1514 double val22=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p-h)*x*x*x*x+(1.0/3.0)*(p-h)*(p-h)*x*x*x;
1522 double integral_CenterR(IndexDimension& cell,
int d)
const{
1524 double p = coord[d];
1525 double h=meshwidth[d];
1526 double x = cell.coordinate(d);
1529 double val1= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
1530 double val12=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*(p+h)*(p+h)*x*x*x;
1531 val1 = val1 - val12;
1534 double val2= (1.0/3.0)*x*x*x-(p+h)*x*x+(p+h)*(p+h)*x;
1535 double val22=(1.0/5.0)*x*x*x*x*x-(2.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*(p+h)*(p+h)*x*x*x;
1543 double integral_right(IndexDimension& cell,
int d)
const{
1544 double p = coord[d];
1545 double h=meshwidth[d];
1546 double x = cell.coordinate(d);
1548 double val1=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
1549 double val12=(1.0/5.0)*x*x*x*x*x-(1.0/4.0)*p*x*x*x*x-(1.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*p*(p+h)*x*x*x;
1550 val1 = val1 + val12;
1553 double val2=-(1.0/3.0)*x*x*x+(1.0/2.0)*p*x*x+(1.0/2.0)*(p+h)*x*x-p*(p+h)*x;
1554 double val22=(1.0/5.0)*x*x*x*x*x-(1.0/4.0)*p*x*x*x*x-(1.0/4.0)*(p+h)*x*x*x*x+(1.0/3.0)*p*(p+h)*x*x*x;
1562 double localValue(
const IndexDimension ¢er ,IndexDimension& cell,
const MultiDimCompass& mc)
const{
1566 for(
int d=0; d<DimensionSparseGrid; d++) {
1567 if (mc.getRichtung(d) == Mitte && cell.getIndex(d) == center.getIndex(d))
1568 value *= integral_CenterR(cell, d);
1569 if (mc.getRichtung(d) == Mitte && !(cell.getIndex(d) == center.getIndex(d)))
1570 value *= integral_CenterL(cell, d);
1571 if (mc.getRichtung(d) == Links && !(cell.getIndex(d) == center.getIndex(d)))
1572 value *= integral_left(cell, d);
1573 if (mc.getRichtung(d) == Rechts && cell.getIndex(d) == center.getIndex(d))
1574 value *= integral_right(cell, d);
1576 value = exponent[d]*exponent[d]*value;
1595 double meshwidth[DimensionSparseGrid];
1596 double exponent[DimensionSparseGrid];
1597 double coord[DimensionSparseGrid];
1599 PoissonStencil poisson;
1605class Poisson :
public StencilTemplate{
1609 TypeMatrixVectorMultiplication getTypeMatrixVectorMultiplication(){
1610 return StencilOnTheFly;
1614 inline double localValue(
const IndexDimension ¢er ,
const IndexDimension& cell,
const MultiDimCompass &mc)
const{
1619 for(
int dx=0; dx < DimensionSparseGrid; dx++) {
1621 if (mc.getRichtung(dx) == Mitte && cell.getIndex(dx) == center.getIndex(dx)){
1623 ddx *= exponent[dx];
1624 ddx *= Integral_Mass(center,cell,mc,dx);
1630 if (mc.getRichtung(dx) == Mitte && !(cell.getIndex(dx) == center.getIndex(dx))){
1632 ddx *= exponent[dx];
1633 ddx *= Integral_Mass(center,cell,mc,dx);
1639 if (mc.getRichtung(dx) == Links && !(cell.getIndex(dx) == center.getIndex(dx))){
1641 ddx *= -1.0*exponent[dx];
1642 ddx *= Integral_Mass(center,cell,mc,dx);
1648 if (mc.getRichtung(dx) == Rechts && cell.getIndex(dx) == center.getIndex(dx)){
1650 ddx *= -1.0*exponent[dx];
1651 ddx *= Integral_Mass(center,cell,mc,dx);
1662 inline double Integral_Mass(
const IndexDimension ¢er ,
const IndexDimension& cell,
const MultiDimCompass &mc,
int D)
const{
1666 for(
int d=0; d<DimensionSparseGrid; d++) {
1669 if (mc.getRichtung(d) == Mitte && cell.getIndex(d) == center.getIndex(d)){
1672 value *= integral_CenterR(center,cell, d);
1675 value = exponent[d] * exponent[d] * value;
1678 else if (mc.getRichtung(d) == Mitte && (cell.getIndex(d) != center.getIndex(d))){
1679 value *= integral_CenterL(center,cell, d);
1682 value = exponent[d] * exponent[d] * value;
1686 else if (mc.getRichtung(d) == Links && (cell.getIndex(d) != center.getIndex(d))){
1687 value *= integral_left(center,cell, d);
1690 value = exponent[d] * exponent[d] * value;
1694 else if (mc.getRichtung(d) == Rechts && cell.getIndex(d) == center.getIndex(d)){
1695 value *= integral_right(center,cell, d);
1696 value = exponent[d] * exponent[d] * value;
1713 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
1715 double h[DimensionSparseGrid];
1717 for(
int i=0;i<DimensionSparseGrid;++i) h[i] =cell.getRightBoundary(i) - cell.getLeftBoundary(i);
1737 for(
int dx=0; dx < DimensionSparseGrid; dx++) {
1739 if (dirP.getDirection(dx)==dirQ.getDirection(dx)){
1742 ddx *= exponent[dx];
1743 ddx *= Integral_Mass(cell,dirP,dirQ,dx);
1752 ddx *= -1.0*exponent[dx];
1753 ddx *= Integral_Mass(cell,dirP,dirQ,dx);
1767 inline double Integral_Mass(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ,
int D) {
1771 for(
int d=0; d<DimensionSparseGrid; d++) {
1774 if (dirP.getDirection(d)==dirQ.getDirection(d)){
1775 if(dirP.getDirection(d)==Right) value *= integral_RR(cell, d);
1776 if(dirP.getDirection(d)==Left) value *= integral_LL(cell,d);
1779 value = exponent[d] * exponent[d] * value;
1783 value *= integral_LR(cell,d);
1784 value = exponent[d] * exponent[d] * value;
1798template<
class StencilA,
class StencilB>
1799class ADD:
public StencilTemplate{
1801 ADD(StencilA stencilA, StencilB stencilB,
AdaptiveSparseGrid& grid_):StencilTemplate(grid_),stencilP(stencilA), stencilM(stencilB) {};
1802 virtual inline double returnValue(
const IndexDimension &Index,
const MultiDimCompass &mc){
1806 CellIterator cells(mc,stencilM.T,Index);
1809 for(cells.start(); cells.goon();++cells){
1810 IndexDimension cell = cells.getCell();
1811 if(stencilM.cellInGrid(cell)) {
1814 val += stencilM.localValue(Index, cell, mc);
1815 val += stencilP.localValue(Index, cell, mc);
1833 inline void initialize(Depth &T_) {
1835 stencilP.initialize(T_);
1836 stencilM.copyInitialization(stencilP);
1850 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
1852 return stencilP.integration(cell,dirP,dirQ)+stencilM.integration(cell,dirP,dirQ);
Definition sparseGrid.h:277
Definition Stencil.h:1315
Integrator for the Helmholtz operator with variable coefficients.
Definition helmIntegrator.h:27
Definition RectangularIterator.h:13
Definition Stencil.h:1127
double integral_right(const IndexDimension ¢er, const IndexDimension &cell, int d) const
Definition Stencil.h:1255