source: src/solver/solver_periodic.cpp@ 48b662

Last change on this file since 48b662 was 48b662, checked in by Olaf Lenz <olenz@…>, 14 years ago

Moved files in scafacos_fcs one level up.

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

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