5#ifndef SGRUN_MATRIXVECTORINHOMOGEN_H_H
6#define SGRUN_MATRIXVECTORINHOMOGEN_H_H
7#include "../extemp/vector.h"
8#include "../tests/old_versions/MatrixVectorMultiplicationPrewavelets.h"
9#include "../sgrid/multiDepthHashGrid.h"
10#include "../BasisTransformations/BasisTransformations.h"
11#include "../stencils/PoissonStencil.h"
12#include "../iterator/depthIterator.h"
15class MatrixVectorInhomogen { ;
17 MatrixVectorInhomogen(
AdaptiveSparseGrid& grid, MultiLevelAdaptiveSparseGrid& mgrid) : gM(mgrid), g(grid), z(grid), u(grid),
20 u_old(grid), Ax_neu(grid), list(grid), P(mgrid){
28 template<
class Problem>
29 void multiplication(VectorSparseG &prew, VectorSparseG &Ax, Problem &matrixProblem);
41 template<
class Problem>
42 void multiplicationRHSHomogen(VectorSparseG &prew, VectorSparseG &Ax, Problem &matrixProblem);
56 MultiLevelVector nodal;
67 template<
class Problem>
68 void CaseFunction(VectorSparseG &prew,
bool *restrictions, Problem &matrixProblem);
70 template<
class Problem>
71 void CaseFunctionTransformation(VectorSparseG &prew,
bool *restrictions, Problem &matrixProblem);
73 inline void calcU(VectorSparseG &prew, Depth &Tiefe,
bool *restrictions);
75 inline void calcNodal(VectorSparseG &prew, Depth &Tiefe);
77 template<
class Problem>
78 void applyProblemGlobal(VectorSparseG &input, VectorSparseG &output, Problem &matrixProblem, Depth &T) {
80 int maxocc = grid->getMaximalOccupiedSecondTable();
81 for (
unsigned long i = 0; i < maxocc; i++) {
86 double val = applyProblemLocal(Index, input, matrixProblem, T);
88 output.setValue(i, val);
93 template<
class Problem>
94 double applyProblemLocal(IndexDimension &Index, VectorSparseG &input, Problem &matrixProblem, Depth &T) {
97 IndexDimension NextTest;
100 NextTest = Index.nextThree_boundary(&mc, T.returnTiefen());
104 value = matrixProblem.returnValue(Index, mc);
105 val = val + value * input.getValue(NextTest);
111 inline void prolongation1D(VectorSparseG &coarse, VectorSparseG &fine,
int &t,
int &d) {
113 unsigned long maxocc = grid->getMaximalOccupiedSecondTable();
116 for (
unsigned long i = 0; i < maxocc; i++) {
119 if (Index.getDepth(d) == t) {
120 double value = fine.getValue(i);
129 if ((!Index.isAtRightBoundary(d)) && (!Index.isAtLeftBoundary(d))) {
130 value = value + 0.5 * (fine.getValue(Index.nextRight(d)) + fine.getValue(Index.nextLeft(d)));
134 coarse = value | Index;
145 void prolongation1D_inplace(VectorSparseG &vec,
int &t,
int &d) {
149 ListOfDepthOrderedSubgrids::iterator iter(list);
152 Depth Tlocal = iter.getDepth();
153 if (Tlocal.at(d) == t) {
155 inneriter.gotobegin();
157 IndexDimension Index = inneriter.getPoint();
158 unsigned long i = inneriter.geti();
159 double value = vec.getValue(i);
160 if ((!Index.isAtRightBoundary(d)) && (!Index.isAtLeftBoundary(d)))
161 value = value + 0.5 * (vec.getValue(Index.nextRight(d)) + vec.getValue(Index.nextLeft(d)));
163 vec.setValue(i, value);
165 }
while (inneriter.next());
168 }
while (iter.next());
173 inline void prolongation(VectorSparseG &coarse, VectorSparseG &fine, Depth &Tcoarse, Depth &Tfine) {
178 VectorSparseG testvec(*coarse.getSparseGrid());
180 VectorSparseG testvec2(*coarse.getSparseGrid());
182 for (
int d = 0; d < DimensionSparseGrid; d++) {
184 tcoarse = Tcoarse.at(d) + 1;
186 for (
int t = tcoarse; t <= tfine; ++t) {
189 prolongation1D_inplace_singleHash(list,fine,t,d);
207 static void prolongation1D_inplace_singleHash(
ListOfDepthOrderedSubgrids& list, VectorSparseG &vec,
const int &t,
const int &d) {
211 ListOfDepthOrderedSubgrids::iterator iter(list);
215 Depth Tlocal = iter.getDepth();
218 if (Tlocal.at(d) == t) {
221 vector<SingleDepthHashGrid*> fineDepthGrids = grid->getMultiDepthHashGrid()->getGridsForDepthInDirection(Tlocal,d);
223 inneriter.gotobegin();
225 IndexDimension Index = inneriter.getPoint();
226 unsigned long i = inneriter.geti();
227 double value = vec.getValue(i);
228 if ((!Index.isAtRightBoundary(d)) && (!Index.isAtLeftBoundary(d))){
229 auto right = Index.nextRight(d);
230 auto left = Index.nextLeft(d);
235 value = value + 0.5 * (vec.getValue(right,fineDepthGrids[right.getDepth(d)]) + vec.getValue(left,fineDepthGrids[left.getDepth(d)]));
241 vec.setValue(i, value);
248 }
while (inneriter.next());
254 }
while (iter.next());
260 inline void restriction1D(VectorSparseG &fine, VectorSparseG &coarse,
int t,
int d) {
263 unsigned long maxocc = grid->getMaximalOccupiedSecondTable();
267 for (
unsigned long i = 0; i < maxocc; i++) {
270 if (Index.getDepth(d) <= t) {
272 value = fine.getValue(i);
276 if (!(Index.isAtRightBoundary(d))) valueL = 0.5 * fine.getValue(Index.nextRight(d, t + 1));
277 if (!(Index.isAtLeftBoundary(d))) valueR = 0.5 * fine.getValue(Index.nextLeft(d, t + 1));
281 value = value + valueL + valueR;
283 coarse.setValue(i, value);
293 inline void restriction1D_inverted_inplace(
const VectorSparseG &fine,
const VectorSparseG &coarse,
int t,
int d) {
297 ListOfDepthOrderedSubgrids::iterator iter(list);
300 Depth Tlocal = iter.getDepth();
305 inneriter.gotobegin();
310 unsigned long i = inneriter.geti();
311 double value = fine.getValue(i);
312 coarse.setValue(i,value);
314 }
while (inneriter.next());
318 if (Tlocal.at(d) == t + 1) {
321 inneriter.gotobegin();
326 IndexDimension Index = inneriter.getPoint();
327 unsigned long i = inneriter.geti();
328 value = 0.5 * fine.getValue(i);
332 IndexDimension rightIndex = Index.nextRight(d);
333 if (!Index.isAtRightBoundary(d)){
335 coarse.addToValue(rightIndex,value);
340 IndexDimension leftIndex = Index.nextLeft(d);
341 if (!Index.isAtLeftBoundary(d)){
343 coarse.addToValue(leftIndex,value);
347 }
while (inneriter.next());
349 }
while (iter.next());
354 inline void restriction1D_inverted_inplace(
const VectorSparseG &vec,
int t,
int d) {
358 ListOfDepthOrderedSubgrids::iterator iter(list);
361 Depth Tlocal = iter.getDepth();
362 if (Tlocal.at(d) == t + 1) {
365 inneriter.gotobegin();
370 IndexDimension Index = inneriter.getPoint();
371 unsigned long i = inneriter.geti();
372 value = 0.5 * vec.getValue(i);
376 IndexDimension rightIndex = Index.nextRight(d);
377 if (!Index.isAtRightBoundary(d)){
379 vec.addToValue(rightIndex,value);
384 IndexDimension leftIndex = Index.nextLeft(d);
385 if (!Index.isAtLeftBoundary(d)){
387 vec.addToValue(leftIndex,value);
391 }
while (inneriter.next());
393 }
while (iter.next());
398 inline void DualSpaceTransformationNeumann(VectorSparseG &Ax_hier, VectorSparseG &Ax, Depth &T) {
399 SingleDepthHashGrid& depthGrid = Ax_hier.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(T);
400 const auto& mapping = depthGrid._mapPosToGridPos;
402 for (
size_t i = 0; i < mapping.size(); i++)
405 IndexDimension I = depthGrid._map.getIndexOfTable(i);
408 if(Ax_hier.getSparseGrid()->getActiveTable()[mapping[i]]) {
410 double basis_coeff = 1.0;
411 J = I.nextFive_Neumann(&mc, T, &basis_coeff);
413 coeff = coeff + Ax_hier.getValue(J) * basis_coeff;
416 Ax.setValue(mapping[i], coeff);
422 inline void DualSpaceTransformationDirichlet(VectorSparseG &g, VectorSparseG &Ax, Depth &T) {
423 SingleDepthHashGrid& depthGrid = g.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(T);
424 const auto& mapping = depthGrid._mapPosToGridPos;
426 for (
size_t i = 0; i < mapping.size(); i++)
429 IndexDimension I = depthGrid._map.getIndexOfTable(i);
430 Richtung richtung[DimensionSparseGrid];
431 if(I.isRandnah(richtung)){
436 if(g.getSparseGrid()->getActiveTable()[mapping[i]]) {
438 double basis_coeff = 1.0;
439 J = I.nextThree_boundary(&mc, T);
441 coeff = coeff + g.getValue(J) * basis_coeff;
444 Ax.setValue(mapping[i], coeff);
452 iterator(Richtung* richtung_){
454 for(
int d=0; d<DimensionSparseGrid; d++){
455 richtung[d]=richtung_[d];
456 if(richtung[d]!=Mitte)
465 Richtung richtung[DimensionSparseGrid];
474template<
class Problem>
475void MatrixVectorInhomogen::multiplication(VectorSparseG &prew, VectorSparseG &Ax, Problem &matrixProblem) {
483 grid->WorkOnHangingNodes =
true;
485 ListOfDepthOrderedSubgrids::iterator iter(list);
488 Depth T = iter.getDepth();
491 nodal.setMultiLevelValues(u, T);
492 }
while (iter.next());
494 grid->WorkOnHangingNodes =
false;
497 for (CasesIterator iter; iter.goon(); ++iter) {
499 bool *restrictions = iter.getcase();
501 grid->WorkOnHangingNodes =
true;
507 CaseFunction(prew, restrictions, matrixProblem);
511 grid->WorkOnHangingNodes =
false;
520template<
class Problem>
521void MatrixVectorInhomogen::multiplicationRHSHomogen(VectorSparseG &prew, VectorSparseG &Ax, Problem &matrixProblem) {
528 grid->WorkOnHangingNodes =
true;
531 ListOfDepthOrderedSubgrids::iterator iter(list);
534 Depth T = iter.getDepth();
537 nodal.setMultiLevelValues2(u, T);
538 }
while (iter.next());
540 grid->WorkOnHangingNodes =
false;
543 for (CasesIterator iter; iter.goon(); ++iter) {
545 bool *restrictions = iter.getcase();
547 grid->WorkOnHangingNodes =
true;
556 CaseFunctionTransformation(prew, restrictions, matrixProblem);
558 grid->WorkOnHangingNodes =
false;
566template<
class Problem>
567void MatrixVectorInhomogen::CaseFunction(VectorSparseG &prew,
bool *restrictions, Problem &matrixProblem) {
569 list.SortiereTiefenBoundary(restrictions);
570 ListOfDepthOrderedSubgrids::iterator iter(list);
572 std::list<Depth>* sortedDepths = list.getSortierteTiefen();
574 if (sortedDepths->size() == 0)
return;
580 for(
int d=0; d < DimensionSparseGrid; d++) {
581 if(restrictions[d]==0)
582 for (Depth T: *sortedDepths) {
587 if(list.isIncluded(T_fine)) {
589 u_new.setMultiLevelValues2(P, T);
591 prolongation1D_inplace(u_new, t, d);
592 P.addMultiLevelValues(u_new, T_fine);
599 for (Depth T: *sortedDepths) {
600 grid->WorkOnHangingNodes =
true;
604 u.setMultiLevelValues2(P,T);
610 matrixProblem.initialize(T);
611 applyProblemGlobal(u, z, matrixProblem, T);
614 g.setMultiLevelValues(gM, T);
625 for (
int d = 0; d < DimensionSparseGrid; d++) {
626 if (restrictions[d]) {
629 Tcoarse.set(T.at(d) - 1, d);
630 if (list.isIncluded(Tcoarse)) {
634 restriction1D_inverted_inplace(z, g, Tcoarse.at(d), d);
638 z.setMultiLevelValues(gM, Tcoarse);
640 gM.setMultiLevelValues(g, Tcoarse);
650 if (list.isIncluded(Tcoarse)) {
651 grid->WorkOnHangingNodes =
false;
653 DualSpaceTransformationNeumann(g, Ax_neu, Tcoarse);
661template<
class Problem>
662void MatrixVectorInhomogen::CaseFunctionTransformation(VectorSparseG &prew,
bool *restrictions, Problem &matrixProblem) {
664 list.SortiereTiefenBoundary(restrictions);
665 ListOfDepthOrderedSubgrids::iterator iter(list);
667 std::list<Depth>* sortedDepths = list.getSortierteTiefen();
669 if (sortedDepths->size() == 0)
return;
674 for (Depth T: *sortedDepths) {
676 for (
int d = 0; d < DimensionSparseGrid; d++) {
677 if (restrictions[d] == 0) {
685 for(
int d=0; d < DimensionSparseGrid; d++) {
686 if(restrictions[d]==0)
687 for (Depth T: *sortedDepths) {
692 if(list.isIncluded(T_fine)) {
694 u_new.setMultiLevelValues2(P, T);
696 prolongation1D_inplace(u_new, t, d);
697 P.addMultiLevelValues(u_new, T_fine);
704 for (Depth T: *sortedDepths) {
705 grid->WorkOnHangingNodes =
true;
709 u.setMultiLevelValues2(P,T);
715 matrixProblem.initialize(T);
716 applyProblemGlobal(u, z, matrixProblem, T);
718 z.addMultiLevelValues2(gM,T);
726 for (
int d = 0; d < DimensionSparseGrid; d++) {
727 if (restrictions[d]) {
729 Tcoarse.set(T.at(d) - 1, d);
730 if (list.isIncluded(Tcoarse)) {
732 restriction1D_inverted_inplace(z,Tcoarse.at(d), d);
734 z.addMultiLevelValues2(gM,Tcoarse);
735 gM.setMultiLevelValues2(g, Tcoarse);
744 if (list.isIncluded(Tcoarse)) {
745 grid->WorkOnHangingNodes =
false;
747 DualSpaceTransformationNeumann(z, g, Tcoarse);
748 DualSpaceTransformationDirichlet(g,Ax_neu,Tcoarse);
756void MatrixVectorInhomogen::calcNodal(VectorSparseG &prew, Depth &Tiefe) {
761 IndexDimension Index = iter.getPoint();
762 double coeff = prew.getValue(Index);
764 double basis_coeff = 1.0;
768 IndexDimension J = Index.nextFive_Neumann(&mc, Tiefe.returnTiefen(), &basis_coeff);
770 double val = u.getValue(J) + coeff * basis_coeff;
780 }
while (iter.next());
Definition sparseGrid.h:86
IndexDimension getIndexOfTable(unsigned long i)
Definition sparseGrid.h:566
Definition sparseGrid.h:277
Definition ListOfDepthOrderedGrids.h:115
Definition ListOfDepthOrderedGrids.h:82