5#ifndef SGRUN_MATRIXVECTORHOMOGENH_H
6#define SGRUN_MATRIXVECTORHOMOGENH_H
8#include "../extemp/vector.h"
9#include "../tests/old_versions/MatrixVectorMultiplicationPrewavelets.h"
10#include "../sgrid/multiDepthHashGrid.h"
11#include "../BasisTransformations/BasisTransformations.h"
12#include "../stencils/PoissonStencil.h"
13#include "../stencils/Stencil.h"
14#include "../iterator/depthIterator.h"
15#include "../cells/CellStructure.h"
16#include "../applications/norms.h"
18#include "../localStiffnessMatrices/LocalStiffnessMatrices.h"
34 std::vector<Depth> depths;
45 u_old(grid), P(mgrid), Ax_neu(grid), nodal_test(mgrid), Ax_solution(grid),
46 depthList(grid), cellData(grid){};
62 u_old(grid), P(mgrid), Ax_neu(grid), nodal_test(mgrid), Ax_solution(grid),
64 symmetry),cellData(grid){};
75 u_old(grid), P(mgrid), Ax_neu(grid), nodal_test(mgrid), Ax_solution(grid),
91 template<
class StencilClass>
92 void multiplication(VectorSparseG &prew, VectorSparseG &Ax, StencilClass &stencilClass);
95 void multiplication_LocalStiffnessMatrix(VectorSparseG &prew, VectorSparseG& Ax, LocalStiffnessMatrices& localStiffnessMatrixAllDepths_){
107 grid->WorkOnHangingNodes =
true;
115 MultiDepthHashGrid MultiDepthHashGrid = *grid->getMultiDepthHashGrid();
116 VectorSparseG u_nodal(u.getSparseGrid());
119 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
121 if (i % omp_get_num_threads() == omp_get_thread_num()) {
126 nodal.setMultiLevelValuesOMP(u_nodal, T, MultiDepthHashGrid);
136 grid->WorkOnHangingNodes =
false;
143 for (CasesIterator iter2; iter2.goon(); ++iter2) {
147 bool *restrictions = iter2.getcase();
148 grid->WorkOnHangingNodes =
true;
159 grid->WorkOnHangingNodes =
false;
169 template<
class Problem>
170 void multiplication_LocalStiffnessMatrix_mpi(VectorSparseG &prew, VectorSparseG& Ax, Problem& localStiffnessMatrixAllDepths_){
172 localStiffnessMatrixAllDepths_.resetActiveWorkers();
175 MPI_Barrier(MPI_COMM_WORLD);
186 grid->WorkOnHangingNodes =
true;
194 MultiDepthHashGrid MultiDepthHashGrid = *grid->getMultiDepthHashGrid();
195 VectorSparseG u_nodal(u.getSparseGrid());
198 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
200 if (i % omp_get_num_threads() == omp_get_thread_num()) {
205 nodal.setMultiLevelValuesOMP(u_nodal, T, MultiDepthHashGrid);
215 grid->WorkOnHangingNodes =
false;
221 MPI_Barrier(MPI_COMM_WORLD);
222 casefunction_mpi_onlyCases_LocalStiffnessMatrix(prew,Ax,localStiffnessMatrixAllDepths_);
225 MPI_Barrier(MPI_COMM_WORLD);
230 for (CasesIterator iter2; iter2.goon(); ++iter2) {
234 bool *restrictions = iter2.getcase();
235 grid->WorkOnHangingNodes =
true;
246 grid->WorkOnHangingNodes =
false;
254 MPI_Barrier(MPI_COMM_WORLD);
260 int mpi_per_worker=1;
261 template<
class StencilClass>
262 void casefunction_mpi(VectorSparseG &prew, VectorSparseG &Ax, StencilClass &stencilClass);
266 template<
class StencilClass>
267 void casefunction_mpi_onlyCases(VectorSparseG &prew, VectorSparseG &Ax, StencilClass &stencilClass);
270 template<
class Problem>
271 void casefunction_mpi_onlyCases_LocalStiffnessMatrix(VectorSparseG &prew, VectorSparseG &Ax, Problem& localStiffnessMatrices);
286 MultiLevelVector nodal;
288 VectorSparseG Ax_neu;
294 MultiLevelVector nodal_test;
295 VectorSparseG Ax_solution;
308 void calcNodal(VectorSparseG &prew, Depth &depth);
315 void calcNodal(VectorSparseG &nodal_u,VectorSparseG &prew, Depth &depth);
318 double time_sortdepth;
330 template<
class StencilClass>
331 void caseFunction(VectorSparseG &prew,
bool *restrictions, StencilClass &stencil);
344 template<
class Problem>
359 template<
class StencilClass>
360 void applyStencilGlobal(
const VectorSparseG &input, VectorSparseG &output, StencilClass &stencil, Depth &T);
372 template<
class StencilClass>
385 template<
class StencilClass>
399 template<
class StencilClass>
413 template<
class StencilClass>
432 template<
class StencilClass>
433 double applyStencilLocal(
const IndexDimension &Index,
const VectorSparseG &input, StencilClass &stencil, Depth &T);
450 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it){
452 if (Tlocal.at(d) == t) {
453 SingleDepthHashGrid& depthGrid = grid->getMultiDepthHashGrid()->getGridForDepth(Tlocal);
454 const auto& mapping = depthGrid._mapPosToGridPos;
455 if(depthGrid.getNumberOfEntries()>0) {
456 #pragma omp parallel for
457 for (
size_t i = 0; i < mapping.size(); i++) {
459 IndexDimension Index = depthGrid._map.getIndexOfTable(i);
461 unsigned long j = mapping[i];
462 double value = values.getValue(j);
463 if ((!Index.isAtRightBoundary(d)) && (!Index.isAtLeftBoundary(d)))
464 value = value + 0.5 * (values.getValue(Index.nextRight(d)) + values.getValue(Index.nextLeft(d)));
466 values.setValue(j, value);
493 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
497 if (Tlocal.at(d) == t + 1 && Tlocal > 0) {
498 SingleDepthHashGrid &depthGrid = grid->getMultiDepthHashGrid()->getGridForDepth(Tlocal);
499 const auto &mapping = depthGrid._mapPosToGridPos;
500 if (depthGrid.getNumberOfEntries() > 0) {
502 for (
size_t i = 0; i < mapping.size(); i++) {
503 IndexDimension Index = depthGrid._map.getIndexOfTable(i);
505 unsigned long j = mapping[i];
506 double value = 0.5 * values.getValue(j);
509 IndexDimension rightIndex = Index.nextRight(d);
510 if (!rightIndex.isAtRightBoundary(d)) {
513 values.addToValue(rightIndex, value);
517 IndexDimension leftIndex = Index.nextLeft(d);
518 if (!leftIndex.isAtRightBoundary(d)) {
521 values.addToValue(leftIndex, value);
541 SingleDepthHashGrid& depthGrid = Ax_nodal.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(T);
542 const auto& mapping = depthGrid._mapPosToGridPos;
544#pragma omp parallel for schedule(runtime)
545 for (
size_t i = 0; i < mapping.size(); i++)
547 if(Ax_nodal.getSparseGrid()->getActiveTable()[mapping[i]]) {
548 IndexDimension I = depthGrid._map.getIndexOfTable(i);
553 double basis_coeff = 1.0;
554 J = I.nextFiveP(&mc, T, &basis_coeff);
556 coeff = coeff + Ax_nodal.getValue(J) * basis_coeff;
559 Ax.setValue(mapping[i], coeff);
571 void master(
int num_workers,
int total_tasks);
574 int MPI_task_index=0;
575 int MPI_total_tasks=PowerOfTwo<DimensionSparseGrid>::value;
576 int MPI_num_workers=0;
588 void master_start_onlyCases(
int num_workers);
590 template<
class Problem>
591 void master_start_onlyCases_LS(
int num_workers,Problem &localStiffnessMatrices);
604 void master_distribute_onlyCases();
606 template<
class Problem>
607 void master_distribute_onlyCases_LS(Problem& localStiffnessMatrices);
616 template<
class LS_Matrix>
617 void master_end_distribute_LocalStiffnessMatrix(LS_Matrix& localStiffnessMatrices);
620 void distributeAndApplyLocalStiffnessMatrix(LocalStiffnessMatrices &localStiffnessMatrices);
631 template<
class StencilClass>
632 void worker(VectorSparseG &prew, VectorSparseG &Ax,StencilClass &stencilClass);
634 template<
class Problem>
635 void worker_localStiffnessMatrices(VectorSparseG &prew, VectorSparseG &Ax,Problem &localStiffnessMatrices);
646 for (
int i = DimensionSparseGrid - 1; i >= 0; --i) {
659template<
class Problem>
663if(matrixProblem.getTypeMatrixVectorMultiplication()==StencilOnTheFly) {
678 int num_cases = POW(2,DimensionSparseGrid);
681 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
684 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
686 MPI_Barrier(MPI_COMM_WORLD);
691 grid->WorkOnHangingNodes =
true;
697 MultiDepthHashGrid MultiDepthHashGrid = *grid->getMultiDepthHashGrid();
698 VectorSparseG u_nodal(u.getSparseGrid());
701 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
703 if (i % omp_get_num_threads() == omp_get_thread_num()) {
708 nodal.setMultiLevelValuesOMP(u_nodal, T, MultiDepthHashGrid);
717 grid->WorkOnHangingNodes =
false;
722 casefunction_mpi_onlyCases(prew,Ax,matrixProblem);
730 for (CasesIterator iter2; iter2.goon(); ++iter2) {
734 bool *restrictions = iter2.getcase();
735 grid->WorkOnHangingNodes =
true;
746 grid->WorkOnHangingNodes =
false;
755 multiplication_LocalStiffnessMatrix_mpi(prew, Ax,matrixProblem);
756 MPI_Barrier(MPI_COMM_WORLD);
771template<
class Problem>
772void MatrixVectorHomogen::casefunction_mpi(VectorSparseG &prew, VectorSparseG &Ax, Problem &stencilClass) {
777 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
779 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
780 MPI_Barrier(MPI_COMM_WORLD);
784 if (rank < mpi_per_worker) {
794 while(MPI_task_index<MPI_total_tasks) {
797 for(
int j=1; j < mpi_per_worker; j++){
798 MPI_Send(&MPI_task_index, 1, MPI_INT, j, TAG_TASK, MPI_COMM_WORLD);
802 prew.getSparseGrid()->WorkOnHangingNodes =
true;
805 bool restrictions[DimensionSparseGrid];
810 prew.getSparseGrid()->WorkOnHangingNodes =
false;
814 for(
int j=1; j < mpi_per_worker; j++){
817 MPI_Recv(&old_index, 1, MPI_INT, j, TAG_TASK, MPI_COMM_WORLD,&status);
823 for(
int j=1; j < mpi_per_worker; j++){
825 MPI_Send(&MPI_task_index, 1, MPI_INT, j, TAG_TERMINATE, MPI_COMM_WORLD);
833 MPI_Recv(&MPI_task_index, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
836 if (TAG_TERMINATE == status.MPI_TAG) {
842 prew.getSparseGrid()->WorkOnHangingNodes =
true;
845 bool restrictions[DimensionSparseGrid];
849 prew.getSparseGrid()->WorkOnHangingNodes =
false;
852 MPI_Send(&MPI_task_index, 1, MPI_INT, 0, TAG_TASK, MPI_COMM_WORLD);
869 worker(prew, Ax, stencilClass);
875 if(rank%mpi_per_worker==0 && rank > 0 ){
877 MPI_Send(Ax.getDatatableVector(), Ax.getSparseGrid()->getMaximalOccupiedSecondTable(),MPI_DOUBLE, 0, tag, MPI_COMM_WORLD);
882 for(
int rank_j=mpi_per_worker; rank_j< num_procs; rank_j+=mpi_per_worker){
884 MPI_Recv(Ax_neu.getDatatableVector(), Ax_neu.getSparseGrid()->getMaximalOccupiedSecondTable(),MPI_DOUBLE, rank_j, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
896template<
class Problem>
897void MatrixVectorHomogen::casefunction_mpi_onlyCases(VectorSparseG &prew, VectorSparseG &Ax, Problem &stencilClass) {
902 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
904 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
905 MPI_Barrier(MPI_COMM_WORLD);
908 MPI_num_workers=min(num_procs,MPI_total_tasks);
918 master_start_onlyCases(num_procs);
923 while(MPI_task_index<MPI_total_tasks) {
925 prew.getSparseGrid()->WorkOnHangingNodes =
true;
928 bool restrictions[DimensionSparseGrid];
934 prew.getSparseGrid()->WorkOnHangingNodes =
false;
943 }
else if(rank<MPI_num_workers){
947 worker(prew, Ax, stencilClass);
952 MPI_Barrier(MPI_COMM_WORLD);
953 MPI_Allreduce(MPI_IN_PLACE, Ax.getDatatableVector(),Ax.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
964template<
class StencilClass>
973 grid->WorkOnHangingNodes =
true;
982 depthList.sortDepths(restrictions);
986 std::list<Depth>* sortedDepths = depthList.getSortierteTiefen();
987 if(depthList.getSortierteTiefen()->size()==0)
return;
997 for(
int d=0; d < DimensionSparseGrid; d++) {
998 if(restrictions[d]==0){
999 for (Depth T: *sortedDepths) {
1001 int t = T.at(d) + 1;
1006 if(depthList.isIncluded(T_fine)){
1010 u_new.setMultiLevelValues2(P,T);
1014 P.addMultiLevelValues(u_new, T_fine);
1023 for (Depth T: *sortedDepths){
1025 grid->WorkOnHangingNodes =
true;
1029 u.setMultiLevelValues2(P,T);
1034 stencil.initialize(T);
1053 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1055 master_distribute_onlyCases();
1060 z.addMultiLevelValues2(gM,T);
1065 for (
int d = 0; d < DimensionSparseGrid; d++) {
1066 if (restrictions[d]) {
1067 Tcoarse.set(T.at(d) - 1, d);
1068 if(depthList.isIncluded(Tcoarse)){
1071 z.addMultiLevelValues2(gM,Tcoarse);
1072 gM.setMultiLevelValues2(g, Tcoarse);
1079 grid->WorkOnHangingNodes=
false;
1097template<
class Problem>
1103 for(
unsigned long i=0;i<grid->getMaximalOccupiedSecondTable();i++){
1110 output.setValue(i, val);
1156template<
class Problem>
1172 const SingleDepthHashCellStructure &depthGrid = cellData.getGridForDepth(Tlocal);
1173 const auto &map = depthGrid._map;
1174 const auto end = depthGrid.getNumberOfEntries();
1177#pragma omp parallel for schedule(dynamic)
1178 for (
size_t i = 0; i < end; i++) {
1180 CellDimension cellDimension = map.getIndexOfTable(i);
1182 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1191template<
class Problem>
1198 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1203 int case_size = mpi_per_worker;
1204 int case_rank = rank%mpi_per_worker;
1209 const SingleDepthHashCellStructure &depthGrid = cellData.getGridForDepth(Tlocal);
1210 const auto &map = depthGrid._map;
1211 const auto end_grid = depthGrid.getNumberOfEntries();
1213 for (
size_t i = 0; i < end_grid; i++) {
1217 if (i % case_size == case_rank) {
1221 CellDimension cellDimension = map.getIndexOfTable(i);
1222 matrixProblem.applyStencilOnCell_MPI_OMP(cellDimension, input, output);
1239 VectorSparseG output_sum(output.getSparseGrid());
1242 for(
int j=1;j<case_size;j++){
1247 MPI_Recv(output_sum.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, rank+j, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1249 output = output+output_sum;
1253 for(
int j=1;j<case_size;j++){
1257 MPI_Send(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE,rank+j, tag, MPI_COMM_WORLD);
1268 int sendTo = rank-case_rank;
1273 MPI_Send(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE,sendTo, tag, MPI_COMM_WORLD);
1275 MPI_Recv(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, sendTo, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1292template<
class Problem>
1299 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1304 int case_size = mpi_per_worker;
1305 if(mpi_per_worker!=2){
1306 cout <<
"only 2 mpi workers are allowed " << endl;
1309 int case_rank = rank%mpi_per_worker;
1311 cout <<
"THIS CAN ONLY USED WITH MPI! " << endl;
1317 const SingleDepthHashCellStructure &depthGrid = cellData.getGridForDepth(Tlocal);
1318 const auto &map = depthGrid._map;
1319 const auto end_grid = depthGrid.getNumberOfEntries();
1324 #pragma omp parallel for schedule(runtime)
1325 for (
size_t i = 0; i < end_grid/2; i++) {
1326 CellDimension cellDimension = map.getIndexOfTable(i);
1327 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1331 #pragma omp parallel for schedule(runtime)
1332 for(
size_t i=end_grid/2; i < end_grid; i++){
1333 CellDimension cellDimension = map.getIndexOfTable(i);
1334 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1341 #pragma omp parallel for schedule(runtime)
1342 for (
size_t i = 0; i < (end_grid-1)/2; i++) {
1343 CellDimension cellDimension = map.getIndexOfTable(i);
1344 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1348 #pragma omp parallel for schedule(runtime)
1349 for(
size_t i=(end_grid-1)/2; i < end_grid; i++){
1350 CellDimension cellDimension = map.getIndexOfTable(i);
1351 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1370 VectorSparseG output_sum(output.getSparseGrid());
1372 MPI_Recv(output_sum.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, rank+1, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1373 output = output+output_sum;
1375 MPI_Send(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE,rank+1, tag, MPI_COMM_WORLD);
1378 int sendTo = rank-1;
1381 MPI_Send(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE,sendTo, tag, MPI_COMM_WORLD);
1382 MPI_Recv(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, sendTo, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1399template<
class Problem>
1406 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1411 int case_size = mpi_per_worker;
1413 int case_rank = rank%mpi_per_worker;
1415 cout <<
"THIS CAN ONLY USED WITH MPI! " << endl;
1421 const SingleDepthHashCellStructure &depthGrid = cellData.getGridForDepth(Tlocal);
1422 const auto &map = depthGrid._map;
1423 const auto end_grid = depthGrid.getNumberOfEntries();
1425 if(end_grid%mpi_per_worker==0) {
1428 for(
int j=0; j<mpi_per_worker; j++){
1430#pragma omp parallel for schedule(runtime)
1431 for (
size_t i = j*(end_grid/mpi_per_worker); i < end_grid/mpi_per_worker; i++) {
1432 CellDimension cellDimension = map.getIndexOfTable(i);
1433 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1441 int modulo = end_grid%mpi_per_worker;
1442 int end_grid_new = end_grid-modulo;
1443 for(
int j=0; j<mpi_per_worker; j++){
1445 #pragma omp parallel for schedule(runtime)
1446 for (
size_t i = j*(end_grid_new/mpi_per_worker); i < end_grid_new/mpi_per_worker; i++) {
1447 CellDimension cellDimension = map.getIndexOfTable(i);
1448 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1453 for(
int j=0; j<modulo; j++){
1455 CellDimension cellDimension = map.getIndexOfTable(j+end_grid_new);
1456 matrixProblem.applyStencilOnCell(cellDimension, input, output);
1479 VectorSparseG output_sum(output.getSparseGrid());
1482 for(
int j=1;j<case_size;j++){
1487 MPI_Recv(output_sum.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, rank+j, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1489 output = output+output_sum;
1493 for(
int j=1;j<case_size;j++){
1497 MPI_Send(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE,rank+j, tag, MPI_COMM_WORLD);
1508 int sendTo = rank-case_rank;
1513 MPI_Send(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE,sendTo, tag, MPI_COMM_WORLD);
1515 MPI_Recv(output.getDatatableVector(), output.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, sendTo, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1533template<
class Problem>
1536 IndexDimension NextIndex;
1541 NextIndex = Index.nextThree2(&mc, T.returnTiefen());
1545 if(mc.goon()&&input.getSparseGrid()->occupied(k,NextIndex)) {
1550 value = matrixProblem.returnValue(
const_cast<IndexDimension &
>(Index), mc);
1556 val = val + value * input.getValue(k);
1572template<
class Problem>
1576 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1582 MPI_Recv(&task_index, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1585 if (TAG_TERMINATE == status.MPI_TAG) {
1590 prew.getSparseGrid()->WorkOnHangingNodes =
true;
1594 bool restrictions[DimensionSparseGrid];
1600 prew.getSparseGrid()->WorkOnHangingNodes =
false;
1604 MPI_Send(&task_index, 1, MPI_INT, 0, TAG_TASK, MPI_COMM_WORLD);
1618template <
class Problem>
1628 grid->WorkOnHangingNodes =
true;
1637 depthList.sortDepths(restrictions);
1641 std::list<Depth>* sortedDepths = depthList.getSortierteTiefen();
1642 if(depthList.getSortierteTiefen()->size()==0)
return;
1654 for(
int d=0; d < DimensionSparseGrid; d++) {
1655 if(restrictions[d]==0){
1656 for (Depth T: *sortedDepths) {
1658 int t = T.at(d) + 1;
1662 if(depthList.isIncluded(T_fine)){
1665 u_new.setMultiLevelValues2(P,T);
1669 P.addMultiLevelValues(u_new, T_fine);
1676 for (Depth T: *sortedDepths) {
1678 grid->WorkOnHangingNodes =
true;
1682 u.setMultiLevelValues2(P,T);
1689 localStiffnessMatrixAllDepths.applyLocalStiffnessMatricesDepth(u,z,T);
1695 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1699 master_distribute_onlyCases_LS(localStiffnessMatrixAllDepths);
1707 z.addMultiLevelValues2(gM,T);
1712 for (
int d = 0; d < DimensionSparseGrid; d++) {
1713 if (restrictions[d]) {
1714 Tcoarse.set(T.at(d) - 1, d);
1715 if(depthList.isIncluded(Tcoarse)){
1718 z.addMultiLevelValues2(gM,Tcoarse);
1719 gM.setMultiLevelValues2(g, Tcoarse);
1726 grid->WorkOnHangingNodes=
false;
1741template <
class Problem>
1742void MatrixVectorHomogen::master_start_onlyCases_LS(
int num_workers,Problem &localStiffnessMatrices) {
1752 MPI_Comm_size(MPI_COMM_WORLD, &num_tasks);
1758 for (
int worker_rank = 1; (worker_rank < num_workers-localStiffnessMatrices.getNumberProcesses()) && (MPI_task_index < MPI_total_tasks); worker_rank++) {
1760 MPI_Send(&MPI_task_index, 1, MPI_INT, worker_rank, TAG_TASK, MPI_COMM_WORLD);
1773template <
class Problem>
1774void MatrixVectorHomogen::worker_localStiffnessMatrices(VectorSparseG &prew, VectorSparseG &Ax,
1775 Problem &localStiffnessMatrices) {
1780 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1781 MPI_Comm_size(MPI_COMM_WORLD, &num_tasks);
1788 if(rank<num_tasks-localStiffnessMatrices.getNumberProcesses()){
1793 MPI_Iprobe(0,MPI_ANY_TAG,MPI_COMM_WORLD,&flag, &status);
1796 MPI_Recv(&task_index, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1798 if (TAG_TERMINATE == status.MPI_TAG) {
1804 prew.getSparseGrid()->WorkOnHangingNodes =
true;
1808 bool restrictions[DimensionSparseGrid];
1814 prew.getSparseGrid()->WorkOnHangingNodes =
false;
1818 MPI_Send(&task_index, 1, MPI_INT, 0, TAG_TASK, MPI_COMM_WORLD);
1824 for (
int n = num_tasks-localStiffnessMatrices.getNumberProcesses(); n < num_tasks; n++) {
1826 MPI_Send(&MPI_task_index, 1, MPI_INT, n, TAG_LOCALSTIFFNESS_END, MPI_COMM_WORLD);
1831 while(localStiffnessMatrices.active_worker.size()>0){
1833 localStiffnessMatrices.receiveApplySendOnActiveWorkers();
1844template <
class Problem>
1845void MatrixVectorHomogen::casefunction_mpi_onlyCases_LocalStiffnessMatrix(VectorSparseG &prew, VectorSparseG &Ax, Problem &localStiffnessMatrices) {
1848 int rank, num_procs;
1850 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1853 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
1854 MPI_Barrier(MPI_COMM_WORLD);
1857 MPI_num_workers=num_procs;
1869 master_start_onlyCases_LS(num_procs,localStiffnessMatrices);
1875 while(MPI_task_index<MPI_total_tasks) {
1878 prew.getSparseGrid()->WorkOnHangingNodes =
true;
1881 bool restrictions[DimensionSparseGrid];
1887 prew.getSparseGrid()->WorkOnHangingNodes =
false;
1893 master_end_distribute_LocalStiffnessMatrix(localStiffnessMatrices);
1900 worker_localStiffnessMatrices(prew, Ax, localStiffnessMatrices);
1909 MPI_Barrier(MPI_COMM_WORLD);
1911 MPI_Allreduce(MPI_IN_PLACE, Ax.getDatatableVector(),Ax.getSparseGrid()->getMaximalOccupiedSecondTable(), MPI_DOUBLE, MPI_SUM,MPI_COMM_WORLD);
1934 MPI_Barrier(MPI_COMM_WORLD);
1942template <
class Problem>
1943void MatrixVectorHomogen::master_distribute_onlyCases_LS(Problem& localStiffnessMatrices) {
1947 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1958 for (
int worker =1;
worker < MPI_num_workers-localStiffnessMatrices.getNumberProcesses() && MPI_task_index < MPI_total_tasks;
worker++) {
1960 MPI_Iprobe(
worker, TAG_TASK, MPI_COMM_WORLD, &flag, &status);
1964 MPI_Recv(&old_index, 1, MPI_INT,
worker, TAG_TASK, MPI_COMM_WORLD, &status);
1966 MPI_Send(&MPI_task_index, 1, MPI_INT,
worker, TAG_TASK, MPI_COMM_WORLD);
1985template <
class LS_Matrix>
1986void MatrixVectorHomogen::master_end_distribute_LocalStiffnessMatrix(LS_Matrix &localStiffnessMatrices){
1998 for (
int n = MPI_num_workers-localStiffnessMatrices.getNumberProcesses(); n < MPI_num_workers; n++) {
2000 MPI_Send(&MPI_task_index, 1, MPI_INT, n, TAG_LOCALSTIFFNESS_END, MPI_COMM_WORLD);
2006 for (
int worker_rank = 1; worker_rank < MPI_num_workers-localStiffnessMatrices.getNumberProcesses(); worker_rank++) {
2009 MPI_Recv(&old_index, 1, MPI_INT, worker_rank, TAG_TASK, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
2013 MPI_Send(&MPI_task_index, 1, MPI_INT, worker_rank, TAG_TERMINATE, MPI_COMM_WORLD);
Definition sparseGrid.h:86
IndexDimension getIndexOfTable(unsigned long i)
Definition sparseGrid.h:566
Definition sparseGrid.h:277
Definition MatrixVectorHomogen.h:32
void master_start(int num_workers)
Definition MatrixVectorHomogen.cpp:122
void applyStencilGlobal(const VectorSparseG &input, VectorSparseG &output, StencilClass &stencil, Depth &T)
void intToBinary(int num, bool binary[])
Definition MatrixVectorHomogen.h:645
MatrixVectorHomogen(AdaptiveSparseGrid &grid, MultiLevelAdaptiveSparseGrid &mgrid, bool symmetry)
Constructor for MatrixVectorHomogen.
Definition MatrixVectorHomogen.h:59
MatrixVectorHomogen(AdaptiveSparseGrid &grid, MultiLevelAdaptiveSparseGrid &mgrid, bool symmetry, bool mpi_on)
Constructor for MatrixVectorHomogen.
Definition MatrixVectorHomogen.h:72
void ConvertToPrewavelet2(VectorSparseG &Ax_nodal, VectorSparseG &Ax, Depth &T)
Definition MatrixVectorHomogen.h:540
MatrixVectorHomogen(AdaptiveSparseGrid &grid, MultiLevelAdaptiveSparseGrid &mgrid)
Constructor for MatrixVectorHomogen.
Definition MatrixVectorHomogen.h:42
void caseFunction(VectorSparseG &prew, bool *restrictions, StencilClass &stencil)
Definition MatrixVectorHomogen.h:965
void applyStencilGlobal_MPI(VectorSparseG &input, VectorSparseG &output, StencilClass &stencil, Depth &T)
int stencil_count
Definition MatrixVectorHomogen.h:80
void master(int num_workers, int total_tasks)
Definition MatrixVectorHomogen.cpp:76
void multiplication(VectorSparseG &prew, VectorSparseG &Ax, StencilClass &stencilClass)
void master_distribute()
Definition MatrixVectorHomogen.cpp:181
bool option_mpi
Definition MatrixVectorHomogen.h:50
void applyStencilGlobal_MPI_3(VectorSparseG &input, VectorSparseG &output, StencilClass &stencil, Depth &T)
void master_end_distribute()
Definition MatrixVectorHomogen.cpp:237
void caseFunction_LocalStiffnessMatrix(VectorSparseG &prew, bool *restrictions, Problem &localStiffnessMatrixAllDepths)
Definition MatrixVectorHomogen.h:1619
void prolongation1D_inplace(VectorSparseG &values, int &t, int &d)
Definition MatrixVectorHomogen.h:444
void calcNodal(VectorSparseG &prew, Depth &depth)
Definition MatrixVectorHomogen.cpp:10
void worker(VectorSparseG &prew, VectorSparseG &Ax, StencilClass &stencilClass)
double applyStencilLocal(const IndexDimension &Index, const VectorSparseG &input, StencilClass &stencil, Depth &T)
bool option_symmetry
Definition MatrixVectorHomogen.h:49
void restriction1D_inverted_inplace(const VectorSparseG &values, int t, int d)
Definition MatrixVectorHomogen.h:485
void applyStencilGlobal_symmetry(VectorSparseG &input, VectorSparseG &output, StencilClass &stencil, Depth &T)
void applyStencilGlobal_MPI_2(VectorSparseG &input, VectorSparseG &output, StencilClass &stencil, Depth &T)