source: src/solver/solver_singular.cpp@ ac6d04

Last change on this file since ac6d04 was ac6d04, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Merge recent changes of the vmg library into ScaFaCos.

Includes a fix for the communication problems on Jugene.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1666 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/**
2 * @file solver_singular.cpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Mon Apr 18 13:12:02 2011
5 *
6 * @brief VMG::SolverSingular
7 *
8 */
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#include <cmath>
15#include <cassert>
16#include <iostream>
17#include <limits>
18
19#include "base/discretization.hpp"
20#include "base/stencil.hpp"
21#include "comm/comm.hpp"
22#include "grid/multigrid.hpp"
23#include "solver/solver_singular.hpp"
24#include "mg.hpp"
25
26using namespace VMG;
27
28//TODO: Implement global MPI communication here
29
30void SolverSingular::AssembleMatrix(const Grid& rhs)
31{
32 Grid::iterator grid_iter;
33 Stencil::iterator stencil_iter;
34 Index i;
35 int index, index2;
36 vmg_float row_sum;
37
38 Comm* comm = MG::GetComm();
39
40 const vmg_float prefactor = MG::GetDiscretization()->OperatorPrefactor(rhs);
41 const Stencil& A = MG::GetDiscretization()->GetStencil();
42
43 // Make sure that arrays are big enough to hold expanded system of equations
44 this->Realloc(rhs.Global().GlobalSize().Product() + 1);
45
46 for (grid_iter = rhs.Iterators().Local().Begin(); grid_iter != rhs.Iterators().Local().End(); ++grid_iter) {
47
48 // Compute 1-dimensional index from 3-dimensional grid
49 index = rhs.GlobalLinearIndex(*grid_iter - rhs.Local().Begin() + rhs.Global().LocalBegin());
50
51 // Check if we computed the index correctly
52 assert(index >= 0 && index < this->Size()-1);
53
54 // Set solution and right hand side vectors
55 this->Sol(index) = 0.0;
56 this->Rhs(index) = rhs.GetVal(*grid_iter);
57
58 // Initialize matrix with zeros and then set entries according to the stencil
59 for (int l=0; l<this->Size(); l++)
60 this->Mat(index,l) = 0.0;
61
62 this->Mat(index,index) = prefactor * A.GetDiag();
63
64 for (stencil_iter = A.begin(); stencil_iter != A.end(); ++stencil_iter) {
65
66 i = *grid_iter - rhs.Local().Begin() + rhs.Global().LocalBegin() + stencil_iter->Disp();
67
68 for (int j=0; j<3; ++j)
69 if (comm->BoundaryConditions()[j] == Periodic) {
70 if (i[j] < 0)
71 i[j] += rhs.Global().GlobalSize()[j];
72 else if (i[j] >= rhs.Global().GlobalSize()[j])
73 i[j] -= rhs.Global().GlobalSize()[j];
74 }
75
76 // Compute global 1-dimensional index
77 index2 = rhs.GlobalLinearIndex(i);
78
79 // Set matrix entry
80 this->Mat(index,index2) += prefactor * stencil_iter->Val();
81 }
82 }
83
84 // Check if matrix has zero row sum (i.e. (1,1,...,1) is an Eigenvector to the Eigenvalue 0)
85 row_sum = A.GetDiag();
86 for (Stencil::iterator iter=A.begin(); iter!=A.end(); iter++)
87 row_sum += iter->Val();
88
89 if (std::abs(row_sum) <= (A.size()+1) * std::numeric_limits<vmg_float>::epsilon()) {
90
91 // Expand equation system in order to make the system regular.
92 // The last entry of the solution vector will hold a correction to the right hand side,
93 // ensuring that the discrete compatibility condition holds. (Compare Trottenberg)
94 for (int i=0; i<this->Size()-1; i++)
95 this->Mat(this->Size()-1, i) = this->Mat(i, this->Size()-1) = 1.0;
96
97 this->Mat(this->Size()-1, this->Size()-1) = 0.0;
98 this->Sol(this->Size()-1) = 0.0;
99 this->Rhs(this->Size()-1) = 0.0;
100
101 }else {
102 //TODO: Implement this
103 assert(0 == "At the first glance your stencil does not seem to be singular. Try SolverRegular instead.");
104 }
105}
106
107void SolverSingular::ExportSol(Grid& sol, Grid& rhs)
108{
109 int index;
110 const vmg_float correction = this->Sol(this->Size()-1);
111
112 for (int i=0; i<sol.Local().Size().X(); i++)
113 for (int j=0; j<sol.Local().Size().Y(); j++)
114 for (int k=0; k<sol.Local().Size().Z(); k++) {
115
116 // Compute global 1-dimensional index
117 index = sol.GlobalLinearIndex(sol.Global().LocalBegin().X()+i,
118 sol.Global().LocalBegin().Y()+j,
119 sol.Global().LocalBegin().Z()+k);
120
121 // Set solution
122 sol(sol.Local().Begin().X()+i, sol.Local().Begin().Y()+j, sol.Local().Begin().Z()+k) = this->Sol(index) - correction;
123
124 }
125
126 // Set correction
127 Grid::Correction() = this->Sol(this->Size()-1);
128}
Note: See TracBrowser for help on using the repository browser.