7#include "../extemp/vector.h"
8#include "../extemp/multilevelvector.h"
9#include "../stencils/MassStencil.h"
10#include "MatrixVectorInhomogen.h"
11#include "../iterator/RectangularIterator.h"
12#include "../stencils/InterfaceIntegration/IntegratorRHS/integratorRHS.h"
16void CalcHierarchicalBasisForRHS(VectorSparseG &u);
19class InHomoBoundaryRHS{
21 InHomoBoundaryRHS(
AdaptiveSparseGrid& grid, MultiLevelAdaptiveSparseGrid& mgrid): depthList(grid), nodalMultiLevel(mgrid), nodal(grid){
22 bool prolongations[DimensionSparseGrid]={0};
23 depthList.sortDepthsNeumann(prolongations);
26 void dualTransform(VectorSparseG& neumann, VectorSparseG& dirichlet){
31 std::list<Depth>* sortedDepths = depthList.getSortierteTiefen();
32 for(Depth T: *sortedDepths) nodalMultiLevel.setMultiLevelValues2(neumann, T);
35 for(
int d=0; d < DimensionSparseGrid; d++) {
37 for (Depth T: *sortedDepths) {
45 if(depthList.isIncluded(T_fine)) {
51 for (
int dd = 0; dd < DimensionSparseGrid; dd++) {
57 double PNeumann[M.size_all];
58 double PNodal[M.size_all];
59 unsigned long indices[M.size_all];
65 for (
int i = 0; i < M.size_all; i++) {
69 nodalMultiLevel.getSparseGrid()->occupied(k, I, T_fine);
72 nodalMultiLevel.getSparseGrid()->occupied(k, I, T);
73 PNeumann[i]=nodalMultiLevel.getValue(k);
75 PNeumann[i]=nodalMultiLevel.getValue(indices[i]);
78 I = I.nextRight(d, T_fine.at(d));
81 M.solve(PNodal,PNeumann);
83 for (
int i = 0; i < M.size_all; i++) {
85 nodalMultiLevel.setValue(indices[i], PNodal[i]);
97 for(Depth T: *sortedDepths){
99 nodal.setMultiLevelValues(nodalMultiLevel, T);
100 ConvertDualNodalToPrewavelet(nodal, dirichlet, T);
111 size_all = POW2(t)+1;
112 if (size_all < 6 && size_all >= 1) {
113 size = size_all*size_all;
118 M =
new double[size];
119 L =
new double[size];
120 R =
new double[size];
123 for(
int k=0; k<size; k++){
131 for (
int k = 2; k < size_all - 1; k += 2) {
132 M[convert(k, k, size_all)] = 1.0;
133 M[convert(k, k - 1, size_all)] = 0.5;
134 M[convert(k, k + 1, size_all)] = 0.5;
136 for (
int k = 3; k < size_all - 2; k += 2) {
137 M[convert(k, k, size_all)] = 1.0;
138 M[convert(k, k - 1, size_all)] = -0.6;
139 M[convert(k, k - 2, size_all)] = 0.1;
140 M[convert(k, k + 1, size_all)] = -0.6;
141 M[convert(k, k + 2, size_all)] = 0.1;
144 M[convert(0, 0, size_all)] = 1.0;
145 M[convert(0, 1, size_all)] = 0.5;
146 M[convert(1, 0, size_all)] = -1.2;
147 M[convert(1, 1, size_all)] = 1.1;
148 M[convert(1, 2, size_all)] = -0.6;
149 M[convert(1, 3, size_all)] = 0.1;
151 M[convert(size_all - 1, size_all - 1, size_all)] = 1.0;
152 M[convert(size_all - 1, size_all - 2, size_all)] = 0.5;
153 M[convert(size_all - 2, size_all - 1, size_all)] = -1.2;
154 M[convert(size_all - 2, size_all - 2, size_all)] = 1.1;
155 M[convert(size_all - 2, size_all - 3, size_all)] = -0.6;
156 M[convert(size_all - 2, size_all - 4, size_all)] = 0.1;
159 M[convert(0,0,size_all)]=1.0;
160 M[convert(0,1,size_all)]=0.5;
161 M[convert(1,0,size_all)]=-1.0;
162 M[convert(1,1,size_all)]=1.0;
163 M[convert(1,2,size_all)]=-1.0;
164 M[convert(2,1,size_all)]=0.5;
165 M[convert(2,2,size_all)]=1.0;
168 if(t==0){ M[convert(0,0,size_all)]=1.0; M[convert(1,1,size_all)]=1.0;}
182 for (
int i = 0; i < I; i++) {
183 for (
int j = 0; j < I; j++) {
184 if (i <= j + 2 && j <= i + 2) {
185 cout <<
"\t" << M[convert(i, j, I)];
186 }
else { cout <<
"\t"; }
194 void solve(
double *x,
double *b) {
199 if (!LRcreated) createLR();
201 for (
int i = 0; i < size_all; i++) {
205 forward(y, b, L, size_all);
206 backward(x, y, R, size_all);
213 for (
int i = 0; i < size_all; i++) {
214 for (
int j = 0; j < size_all; j++) {
215 if (abs(i - j) < 3) {
216 R[convert(i, j, size_all)] = M[convert(i, j, size_all)];
225 int convert(
int i,
int j,
int I){
229 if (I < 6) {
return i * I + j; }
230 if (j > 2 && j < I - 2) {
231 i = i - ((j - 3) + 1);
233 if (j == I - 2) i = i - j + 3;
234 if (j == I - 1) i = i - j + 4;
237 if (i > 4 || i < 0) {
238 cout <<
"error" << endl;
239 cout <<
" i " << i <<
" j " << j << endl;
240 cout <<
"save i " << savei <<
" I " << I << endl;
264 MultiLevelVector nodalMultiLevel;
278class InHomoBoundaryRHSHierarchical{
282 void multiply(VectorSparseG& hierarchical, VectorSparseG& dirichlet);
284 void multiply_mass(VectorSparseG& hierarchical, VectorSparseG& dirichlet);
286 void multiply_mass_coeff(VectorSparseG &hierarchical, VectorSparseG &dirichlet);
289 void multiply_mass_coeff_interface(VectorSparseG &hierarchical, VectorSparseG &dirichlet,
const F& var_coeff) {
292 DepthList depthList(*dirichlet.getSparseGrid());
293 DepthList depthList1(*hierarchical.getSparseGrid());
295 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
297 auto iter = GetNextSmallerDepthsIterator(T);
299 Depth Tlocal = *iter;
302 SingleDepthHashGrid &depthGrid = dirichlet.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(
304 const auto &mapping = depthGrid._mapPosToGridPos;
306 if (depthGrid.getNumberOfEntries() > 0) {
309 for (
size_t i = 0; i < mapping.size(); i++) {
311 IndexDimension INodal = depthGrid._map.getIndexOfTable(i);
314 double sum_omp = 0.0;
318 for (
auto it_inner = depthList1.begin_all();
319 it_inner != depthList1.end_all(); ++it_inner) {
321 Depth THier = *it_inner;
324 SingleDepthHashGrid &depthGrid_hier = hierarchical.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(
326 const auto &mapping_hier = depthGrid_hier._mapPosToGridPos;
327 const auto &map_hier = depthGrid_hier._map;
328 auto end = mapping_hier.size();
331 if (depthGrid_hier.getNumberOfEntries() > 0){
332 #pragma omp parallel reduction(+:sum_omp)
335 #pragma omp for schedule(runtime)
336 for (
size_t j = 0; j < end; j++) {
338 IndexDimension IHier = map_hier.getIndexOfTable(j);
340 array<double, DimensionSparseGrid> p_u{}, p_v{}, l_b{}, r_b{}, h_u{}, h_v{};
341 array<int, DimensionSparseGrid> d_u{}, d_v{};
343 for (
int d = 0; d < DimensionSparseGrid; d++) {
344 p_u[d] = INodal.coordinate(d);
345 p_v[d] = IHier.coordinate(d);
346 h_u[d] = 1.0 / double(POW2(T.at(d)));
347 h_v[d] = 1.0 / double(POW2(THier.at(d)));
348 l_b[d] = max(p_u[d] - h_u[d], p_v[d] - h_v[d]);
349 l_b[d] = max(l_b[d], 0.0);
350 r_b[d] = min(p_u[d] + h_u[d], p_v[d] + h_v[d]);
351 r_b[d] = min(r_b[d], 1.0);
353 d_v[d] = THier.at(d);
358 double val = integratorRhs.integration(l_b, r_b,
366 hierarchical.getValue(mapping_hier[j]);
382 nodal.setValue(mapping[i], sum_omp);
389 }
while (iter.next());
391 ConvertToPrewavelet2(nodal, dirichlet, T);
397 inline void ConvertToPrewavelet2(VectorSparseG &Ax_hier, VectorSparseG &Ax, Depth &T) {
398 SingleDepthHashGrid& depthGrid = Ax_hier.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(T);
399 const auto& mapping = depthGrid._mapPosToGridPos;
401 for (
size_t i = 0; i < mapping.size(); i++)
403 if(Ax_hier.getSparseGrid()->getActiveTable()[mapping[i]]) {
404 IndexDimension I = depthGrid._map.getIndexOfTable(i);
409 double basis_coeff = 1.0;
410 J = I.nextFiveP(&mc, T, &basis_coeff);
412 coeff = coeff + Ax_hier.getValue(J) * basis_coeff;
415 Ax.setValue(mapping[i], coeff);
Definition sparseGrid.h:277
Integrator for the Helmholtz operator with variable coefficients.
Definition integratorRHS.h:26
Definition RectangularIterator.h:13