5#ifndef GRUN_CG_METHOD_H
6#define GRUN_CG_METHOD_H
10#include <unordered_set>
11#include "../MatrixVectorMultiplication/MatrixVectorHomogen.h"
12#include "../MatrixVectorMultiplication/MatrixVectorInhomogen.h"
16 static bool solveNeumann(
int maxIteration,
25 MatrixVectorInhomogen& matrix);
27 template<
class Stencil>
28 static bool solveHomogen(
double eps,
35 static const int maxIteration = 500;
36 static double error[MaximumDepth][maxIteration];
40 static void printError() {
42 Datei.open(
"../results/error_CG.gnu", std::ios::out);
44 for (
int i = 0; i < MaximumDepth; i++) {
45 if (error[i][0] != 0) {
46 Datei <<
"\t" << error[i][0];
47 cout <<
"\t" << error[i][0];
52 for (
int i = 1; i < maxIteration; i++) {
55 for (
int j = 0; j < MaximumDepth; j++) {
56 if (error[j][0] != 0) {
57 Datei <<
"\t" << error[j][i];
58 cout <<
"\t " << error[j][i];
76 static void apply(VectorSparseG &input, VectorSparseG &output);
78 static void applyTranspose(VectorSparseG &input, VectorSparseG &output);
81template<
class StencilClass>
84 Preconditioning(VectorSparseG& z_, StencilClass stencilClass) : z(z_), boundary(false) {
86 if(stencilClass.getTypeMatrixVectorMultiplication()==StencilOnTheFly) precond3(stencilClass);
88 precondLocalStiffnessMatrix(stencilClass);
91 MPI_Barrier(MPI_COMM_WORLD);
95 void precondMV(StencilClass stencilClass){
100 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
102 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
107 VectorSparseG v(*z.getSparseGrid());
108 VectorSparseG Av(*z.getSparseGrid());
109 MultiLevelAdaptiveSparseGrid mgrid(z.getSparseGrid());
112 for (
size_t i = 0; i < z.getSparseGrid()->getMaximalOccupiedSecondTable(); i++) {
113 if (z.getSparseGrid()->getActiveTable()[i]) {
115 IndexDimension Index = z.getSparseGrid()->getIndexOfTable(i);
119 matrixVectorHomogen.multiplication(v,Av,stencilClass);
125 double coeff=Av.getValue(i);
128 cout <<
" " << coeff << endl;
130 z.setValue(i, coeff);
141 void precond1(StencilClass stencilClass){
144 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
146 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
151 VectorSparseG v(*z.getSparseGrid());
153 for (
size_t i = 0; i < z.getSparseGrid()->getMaximalOccupiedSecondTable(); i++) {
154 if (z.getSparseGrid()->getActiveTable()[i]) {
156 if (world_rank == i % world_size ) {
159 IndexDimension Index = z.getSparseGrid()->getIndexOfTable(i);
162 bool todo[mc_outer.getMaxShift()];
164 IndexDimension index_mc[mc_outer.getMaxShift()];
165 double basis_coeff_mc[mc_outer.getMaxShift()];
167 for (
int i = 0; i < mc_outer.getMaxShift(); i++) {
171 stencilClass.initialize(T);
175 double basis_coeff = 1.0;
178 J = Index.nextFive(&mc, T, &basis_coeff, &next);
182 todo[mc.getShiftNumber()] =
true;
183 index_mc[mc.getShiftNumber()] = J;
184 basis_coeff_mc[mc.getShiftNumber()] = basis_coeff;
186 v.setValue(J, basis_coeff);
196 #pragma omp parallel for schedule(dynamic)
197 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
202 IndexDimension J = index_mc[j];
203 double stencil = applyStencilLocal(J, v, T, stencilClass);
207 stencil *= basis_coeff_mc[j];
220 z.setValue(i, coeff);
230 MPI_Allreduce(MPI_IN_PLACE,z.getDatatableVector(),z.getSparseGrid()->getMaximalOccupiedSecondTable(),MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
236 void precond2(StencilClass stencilClass){
240 VectorSparseG v(*z.getSparseGrid());
241 #pragma omp for schedule(runtime)
242 for (
size_t i = 0; i < z.getSparseGrid()->getMaximalOccupiedSecondTable(); i++) {
243 if (z.getSparseGrid()->getActiveTable()[i]) {
245 IndexDimension Index = z.getSparseGrid()->getIndexOfTable(i);
248 bool todo[mc_outer.getMaxShift()];
251 IndexDimension index_mc[mc_outer.getMaxShift()];
252 double basis_coeff_mc[mc_outer.getMaxShift()];
254 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
261 double basis_coeff = 1.0;
264 J = Index.nextFive(&mc, T, &basis_coeff, &next);
269 todo[mc.getShiftNumber()] =
true;
270 index_mc[mc.getShiftNumber()] = J;
271 basis_coeff_mc[mc.getShiftNumber()] = basis_coeff;
273 v.setValue(J, basis_coeff);
284 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
289 IndexDimension J = index_mc[j];
290 double stencil = applyStencilLocal(J, v, T, stencilClass);
293 stencil *= basis_coeff_mc[j];
307 z.setValue(i, coeff);
322 void precond3(StencilClass stencilClass){
325 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
327 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
333 DepthList depthList(*z.getSparseGrid());
338 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
343 SingleDepthHashGrid &depthGrid = z.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(T);
344 const auto &mapping = depthGrid._mapPosToGridPos;
345 const auto mapping_size = mapping.size();
348 if (depthGrid.getNumberOfEntries() > 0) {
352 if (world_rank == iter_i % world_size ) {
355 stencilClass.initialize(T);
358 VectorSparseG v(*z.getSparseGrid());
359 #pragma omp for schedule(dynamic)
360 for (
size_t i = 0; i < mapping_size; i++) {
364 if (z.getSparseGrid()->getActiveTable()[mapping[i]]) {
365 IndexDimension Index = depthGrid._map.getIndexOfTable(i);
368 bool todo[mc_outer.getMaxShift()];
370 IndexDimension index_mc[mc_outer.getMaxShift()];
371 double basis_coeff_mc[mc_outer.getMaxShift()];
373 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
379 double basis_coeff = 1.0;
383 J = Index.nextFive_Neumann(&mc, T, &basis_coeff, &next);
385 J = Index.nextFive(&mc, T, &basis_coeff, &next);
389 todo[mc.getShiftNumber()] =
true;
390 index_mc[mc.getShiftNumber()] = J;
391 basis_coeff_mc[mc.getShiftNumber()] = basis_coeff;
393 v.setValue(J, basis_coeff);
404 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
409 IndexDimension J = index_mc[j];
410 double stencil = applyStencilLocal(J, v, T, stencilClass);
411 stencil *= basis_coeff_mc[j];
424 z.setValue(mapping[i], coeff);
446 MPI_Allreduce(MPI_IN_PLACE,z.getDatatableVector(),z.getSparseGrid()->getMaximalOccupiedSecondTable(),MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
454 void precond4(StencilClass stencilClass){
457 VectorSparseG v(z.getSparseGrid());
458 VectorSparseG u(z.getSparseGrid());
459#pragma omp for schedule(dynamic)
460 for (
unsigned long k = 0; k < z.getSparseGrid()->getMaximalOccupiedSecondTable(); k++) {
462 if (z.getSparseGrid()->getActiveTable()[k]) {
465 IndexDimension Index = z.getSparseGrid()->getIndexOfTable(k);
467 stencilClass.initialize(Tneu);
471 double basis_coeff = 1.0;
475 J = Index.nextFive_Neumann(&mc, Tneu, &basis_coeff, &next);
477 J = Index.nextFive(&mc, Tneu, &basis_coeff, &next);
481 v.setValue(J, basis_coeff);
491 double basis_coeff = 1.0;
495 J = Index.nextFive_Neumann(&mc, Tneu, &basis_coeff, &next);
497 J = Index.nextFive(&mc, Tneu, &basis_coeff, &next);
504 basis_coeff = applyStencilLocal(J,v,Tneu,stencilClass);
506 u.setValue(J, basis_coeff);
514 double basis_coeff = 1.0;
518 J = Index.nextFive_Neumann(&mc, Tneu, &basis_coeff, &next);
520 J = Index.nextFive(&mc, Tneu, &basis_coeff, &next);
523 coeff = coeff + u.getValue(J) * basis_coeff;
533 z.setValue(k, coeff);
544 void precondLocalStiffnessMatrix(StencilClass stencilClass){
548 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
550 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
556 DepthList depthList(*z.getSparseGrid());
561 for (
auto it = depthList.begin_all(); it != depthList.end_all(); ++it) {
565 int node = stencilClass.getNodeForDepth(T);
566 if(world_rank==node){
568 SingleDepthHashGrid &depthGrid = z.getSparseGrid()->getMultiDepthHashGrid()->getGridForDepth(T);
569 const auto &mapping = depthGrid._mapPosToGridPos;
570 const auto mapping_size = mapping.size();
573 if (depthGrid.getNumberOfEntries() > 0) {
578 VectorSparseG v(*z.getSparseGrid());
579 VectorSparseG v_output(*z.getSparseGrid());
581#pragma omp for schedule(dynamic)
582 for (
size_t i = 0; i < mapping_size; i++) {
585 if (z.getSparseGrid()->getActiveTable()[mapping[i]]) {
586 IndexDimension Index = depthGrid._map.getIndexOfTable(i);
590 bool todo[mc_outer.getMaxShift()];
592 IndexDimension index_mc[mc_outer.getMaxShift()];
593 double basis_coeff_mc[mc_outer.getMaxShift()];
595 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
599 std::vector<IndexDimension> IndicesVector;
601 double basis_coeff = 1.0;
605 J = Index.nextFive_Neumann(&mc, T, &basis_coeff, &next);
607 J = Index.nextFive(&mc, T, &basis_coeff, &next);
611 todo[mc.getShiftNumber()] =
true;
612 index_mc[mc.getShiftNumber()] = J;
613 basis_coeff_mc[mc.getShiftNumber()] = basis_coeff;
615 v.setValue(J, basis_coeff);
616 IndicesVector.push_back(J);
624 stencilClass.applyLocalStiffnessMatricesOnIndices_onNode(v, v_output, T, IndicesVector);
629 for (
int j = 0; j < mc_outer.getMaxShift(); j++) {
634 IndexDimension J = index_mc[j];
638 stencil = v_output.getValue(J);
641 stencil *= basis_coeff_mc[j];
656 z.setValue(mapping[i], coeff);
677 MPI_Allreduce(MPI_IN_PLACE,z.getDatatableVector(),z.getSparseGrid()->getMaximalOccupiedSecondTable(),MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
691 double applyStencilLocal(IndexDimension &Index,
const VectorSparseG &input,Depth &T, StencilClass stencilClass) {
693 IndexDimension NextIndex;
696 NextIndex = Index.nextThree2(&mc, T.returnTiefen());
700 value = stencilClass.returnValue(Index, mc);
702 val = val + value * input.getValue(NextIndex);
713 void apply(VectorSparseG* u){
717 void apply_inverse(VectorSparseG* u){
718 for (
unsigned long k = 0; k < z.getSparseGrid()->getMaximalOccupiedSecondTable(); k++) {
719 if(z.getSparseGrid()->getActiveTable()[k]) {
720 double val1 = u->getValue(k);
721 double val2 = z.getValue(k);
722 u->setValue(k,
double(val1/val2));
729 void apply_NEU(VectorSparseG* u){
730 for (
unsigned long k = 0; k < z.getSparseGrid()->getMaximalOccupiedSecondTable(); k++) {
731 if(z.getSparseGrid()->getActiveTable()[k]) {
732 double val1 = u->getValue(k);
733 double val2 = z.getValue(k);
734 u->setValue(k,
double(val1/ sqrt(val2)));
739 double getValue(
unsigned long k){
740 return z.getValue(k);
743 VectorSparseG* getZ(){
759template<
class Stencil>
761CG::solveHomogen(
double eps, VectorSparseG &x,VectorSparseG &f,
int *iterations,
767 double delta_prime=1.0;
774 if(!(x.getSparseGrid()->getKey()==f.getSparseGrid()->getKey()))exit(1);
778 VectorSparseG z(grid);
779 VectorSparseG r(grid);
780 VectorSparseG g(grid);
781 VectorSparseG d(grid);
786 VectorSparseG h(grid);
795 struct timeval begin_all, end_all;
796 gettimeofday(&begin_all, 0);
802 struct timeval begin, end;
803 gettimeofday(&begin, 0);
805 Preconditioning<Stencil> P(z,stencil);
808 gettimeofday(&end, 0);
809 long seconds = end.tv_sec - begin.tv_sec;
810 long microseconds = end.tv_usec - begin.tv_usec;
811 double duration_def = seconds + microseconds*1e-6;
812 *time_precon = duration_def;
845 delta = product(r, h);
852 for (
int i = 1; i <= maxIteration && delta > eps; ++i) {
853 grid->WorkOnHangingNodes =
false;
862 tau = double(delta / product(d, g));
870 delta_prime = product(r, h);
871 if (delta_prime < eps*eps)
break;
874 beta = delta_prime / delta;
876 d = -1.0*h + beta * d;
Definition sparseGrid.h:277
Definition ListOfDepthOrderedGrids.h:115
Definition MatrixVectorHomogen.h:32
void multiplication(VectorSparseG &prew, VectorSparseG &Ax, StencilClass &stencilClass)