| [48b662] | 1 | /**
|
|---|
| 2 | * @file solver_dirichlet.cpp
|
|---|
| 3 | * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
|
|---|
| 4 | * @date Mon Apr 18 13:11:32 2011
|
|---|
| 5 | *
|
|---|
| 6 | * @brief VMG::SolverDirichlet
|
|---|
| 7 | *
|
|---|
| 8 | */
|
|---|
| 9 |
|
|---|
| 10 | #ifdef HAVE_CONFIG_H
|
|---|
| 11 | #include <config.h>
|
|---|
| 12 | #endif
|
|---|
| 13 |
|
|---|
| 14 | #include <iostream>
|
|---|
| 15 |
|
|---|
| 16 | #include "base/discretization.hpp"
|
|---|
| 17 | #include "base/stencil.hpp"
|
|---|
| 18 | #include "grid/multigrid.hpp"
|
|---|
| 19 | #include "solver/solver_dirichlet.hpp"
|
|---|
| 20 | #include "mg.hpp"
|
|---|
| 21 |
|
|---|
| 22 | using namespace VMG;
|
|---|
| 23 |
|
|---|
| 24 | // TODO: Implement global communication here
|
|---|
| 25 | // TODO: Implement this more efficiently
|
|---|
| 26 | // TODO: This has to be reviewed for parallelization
|
|---|
| 27 |
|
|---|
| 28 | void SolverDirichlet::AssembleMatrix(const Grid& rhs)
|
|---|
| 29 | {
|
|---|
| 30 | Index i;
|
|---|
| 31 | int mat_index, mat_index2;
|
|---|
| 32 | vmg_float prefactor_inv = 1.0 / MG::GetDiscretization()->OperatorPrefactor(rhs);
|
|---|
| 33 | const Stencil& A = MG::GetDiscretization()->GetStencil();
|
|---|
| 34 |
|
|---|
| 35 | #ifdef DEBUG
|
|---|
| 36 | rhs.IsConsistent();
|
|---|
| 37 | #endif
|
|---|
| 38 |
|
|---|
| 39 | this->Realloc(rhs.Global().Size().Product());
|
|---|
| 40 |
|
|---|
| 41 | for (i.X()=rhs.Local().Begin().X(); i.X()<rhs.Local().End().X(); i.X()++)
|
|---|
| 42 | for (i.Y()=rhs.Local().Begin().Y(); i.Y()<rhs.Local().End().Y(); i.Y()++)
|
|---|
| 43 | for (i.Z()=rhs.Local().Begin().Z(); i.Z()<rhs.Local().End().Z(); i.Z()++) {
|
|---|
| 44 |
|
|---|
| 45 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 46 |
|
|---|
| 47 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 48 |
|
|---|
| 49 | this->Sol(mat_index) = 0.0;
|
|---|
| 50 | this->Rhs(mat_index) = prefactor_inv * rhs.GetVal(i);
|
|---|
| 51 |
|
|---|
| 52 | for (int l=0; l<this->Size(); l++)
|
|---|
| 53 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 54 |
|
|---|
| 55 | this->Mat(mat_index, mat_index) = A.GetDiag();
|
|---|
| 56 |
|
|---|
| 57 | for (Stencil::iterator iter = A.begin(); iter != A.end(); iter++) {
|
|---|
| 58 | mat_index2 = rhs.GlobalLinearIndex(i + rhs.Global().Begin() + iter);
|
|---|
| 59 | assert(mat_index2 >= 0 && mat_index2<this->Size());
|
|---|
| 60 | this->Mat(mat_index, mat_index2) += iter->val;
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | for (i.X()=rhs.Local().BoundaryBegin1().X(); i.X()<rhs.Local().BoundaryEnd1().X(); i.X()++)
|
|---|
| 66 | for (i.Y()=rhs.Local().Begin().Y(); i.Y()<rhs.Local().End().Y(); i.Y()++)
|
|---|
| 67 | for (i.Z()=rhs.Local().Begin().Z(); i.Z()<rhs.Local().End().Z(); i.Z()++) {
|
|---|
| 68 |
|
|---|
| 69 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 70 |
|
|---|
| 71 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 72 |
|
|---|
| 73 | this->Sol(mat_index) = this->Rhs(mat_index) = rhs.GetVal(i);
|
|---|
| 74 |
|
|---|
| 75 | for (int l=0; l<this->Size(); l++)
|
|---|
| 76 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 77 |
|
|---|
| 78 | this->Mat(mat_index, mat_index) = 1.0;
|
|---|
| 79 |
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | for (i.X()=rhs.Local().BoundaryBegin2().X(); i.X()<rhs.Local().BoundaryEnd2().X(); i.X()++)
|
|---|
| 83 | for (i.Y()=rhs.Local().Begin().Y(); i.Y()<rhs.Local().End().Y(); i.Y()++)
|
|---|
| 84 | for (i.Z()=rhs.Local().Begin().Z(); i.Z()<rhs.Local().End().Z(); i.Z()++) {
|
|---|
| 85 |
|
|---|
| 86 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 87 |
|
|---|
| 88 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 89 |
|
|---|
| 90 | this->Sol(mat_index) = this->Rhs(mat_index) = rhs.GetVal(i);
|
|---|
| 91 |
|
|---|
| 92 | for (int l=0; l<this->Size(); l++)
|
|---|
| 93 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 94 |
|
|---|
| 95 | this->Mat(mat_index, mat_index) = 1.0;
|
|---|
| 96 |
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | for (i.X()=0; i.X()<rhs.Local().SizeTotal().X(); i.X()++)
|
|---|
| 100 | for (i.Y()=rhs.Local().BoundaryBegin1().Y(); i.Y()<rhs.Local().BoundaryEnd1().Y(); i.Y()++)
|
|---|
| 101 | for (i.Z()=rhs.Local().Begin().Z(); i.Z()<rhs.Local().End().Z(); i.Z()++) {
|
|---|
| 102 |
|
|---|
| 103 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 104 |
|
|---|
| 105 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 106 |
|
|---|
| 107 | this->Sol(mat_index) = this->Rhs(mat_index) = rhs.GetVal(i);
|
|---|
| 108 |
|
|---|
| 109 | for (int l=0; l<this->Size(); l++)
|
|---|
| 110 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 111 |
|
|---|
| 112 | this->Mat(mat_index, mat_index) = 1.0;
|
|---|
| 113 |
|
|---|
| 114 | }
|
|---|
| 115 |
|
|---|
| 116 | for (i.X()=0; i.X()<rhs.Local().SizeTotal().X(); i.X()++)
|
|---|
| 117 | for (i.Y()=rhs.Local().BoundaryBegin2().Y(); i.Y()<rhs.Local().BoundaryEnd2().Y(); i.Y()++)
|
|---|
| 118 | for (i.Z()=rhs.Local().Begin().Z(); i.Z()<rhs.Local().End().Z(); i.Z()++) {
|
|---|
| 119 |
|
|---|
| 120 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 121 |
|
|---|
| 122 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 123 |
|
|---|
| 124 | this->Sol(mat_index) = this->Rhs(mat_index) = rhs.GetVal(i);
|
|---|
| 125 |
|
|---|
| 126 | for (int l=0; l<this->Size(); l++)
|
|---|
| 127 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 128 |
|
|---|
| 129 | this->Mat(mat_index, mat_index) = 1.0;
|
|---|
| 130 |
|
|---|
| 131 | }
|
|---|
| 132 |
|
|---|
| 133 | for (i.X()=0; i.X()<rhs.Local().SizeTotal().X(); i.X()++)
|
|---|
| 134 | for (i.Y()=0; i.Y()<rhs.Local().SizeTotal().Y(); i.Y()++)
|
|---|
| 135 | for (i.Z()=rhs.Local().BoundaryBegin1().Z(); i.Z()<rhs.Local().BoundaryEnd1().Z(); i.Z()++) {
|
|---|
| 136 |
|
|---|
| 137 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 138 |
|
|---|
| 139 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 140 |
|
|---|
| 141 | this->Sol(mat_index) = this->Rhs(mat_index) = rhs.GetVal(i);
|
|---|
| 142 |
|
|---|
| 143 | for (int l=0; l<this->Size(); l++)
|
|---|
| 144 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 145 |
|
|---|
| 146 | this->Mat(mat_index, mat_index) = 1.0;
|
|---|
| 147 |
|
|---|
| 148 | }
|
|---|
| 149 |
|
|---|
| 150 | for (i.X()=0; i.X()<rhs.Local().SizeTotal().X(); i.X()++)
|
|---|
| 151 | for (i.Y()=0; i.Y()<rhs.Local().SizeTotal().Y(); i.Y()++)
|
|---|
| 152 | for (i.Z()=rhs.Local().BoundaryBegin2().Z(); i.Z()<rhs.Local().BoundaryEnd2().Z(); i.Z()++) {
|
|---|
| 153 |
|
|---|
| 154 | mat_index = rhs.GlobalLinearIndex(i + rhs.Global().Begin());
|
|---|
| 155 |
|
|---|
| 156 | assert(mat_index >= 0 && mat_index<this->Size());
|
|---|
| 157 |
|
|---|
| 158 | this->Sol(mat_index) = this->Rhs(mat_index) = rhs.GetVal(i);
|
|---|
| 159 |
|
|---|
| 160 | for (int l=0; l<this->Size(); l++)
|
|---|
| 161 | this->Mat(mat_index, l) = 0.0;
|
|---|
| 162 |
|
|---|
| 163 | this->Mat(mat_index, mat_index) = 1.0;
|
|---|
| 164 |
|
|---|
| 165 | }
|
|---|
| 166 | }
|
|---|
| 167 |
|
|---|
| 168 | void SolverDirichlet::ExportSol(Grid& sol, Grid& rhs)
|
|---|
| 169 | {
|
|---|
| 170 | int index;
|
|---|
| 171 |
|
|---|
| 172 | for (int i=0; i<sol.Local().SizeTotal().X(); i++)
|
|---|
| 173 | for (int j=0; j<sol.Local().SizeTotal().Y(); j++)
|
|---|
| 174 | for (int k=0; k<sol.Local().SizeTotal().Z(); k++) {
|
|---|
| 175 |
|
|---|
| 176 | index = sol.GlobalLinearIndex(sol.Global().Begin().X() + i,
|
|---|
| 177 | sol.Global().Begin().Y() + j,
|
|---|
| 178 | sol.Global().Begin().Z() + k);
|
|---|
| 179 | sol(i,j,k) = this->Sol(index);
|
|---|
| 180 |
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | #ifdef DEBUG
|
|---|
| 184 | sol.IsConsistent();
|
|---|
| 185 | rhs.IsConsistent();
|
|---|
| 186 | #endif
|
|---|
| 187 | }
|
|---|