source: src/level/level_operator_fas.cpp@ 884223

Last change on this file since 884223 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: 5.3 KB
RevLine 
[48b662]1/**
2 * @file level_operator_fas.cpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Mon Apr 18 13:00:23 2011
5 *
6 * @brief VMG::LevelOperatorFAS
7 *
8 */
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#include "base/discretization.hpp"
15#include "base/index.hpp"
16#include "comm/comm.hpp"
17#include "grid/multigrid.hpp"
18#include "grid/tempgrid.hpp"
19#include "level/level_operator_fas.hpp"
20#include "mg.hpp"
21
22using namespace VMG;
23
24void LevelOperatorFAS::Restrict(Multigrid& sol, Multigrid& rhs)
25{
26#ifdef DEBUG
27 sol().IsConsistent();
28 rhs().IsConsistent();
29 sol().IsCompatible(rhs());
30#endif
31
32 Index i_c, i_f;
33 Stencil::iterator iter;
34 vmg_float val;
35
36 Grid& sol_c = MG::GetComm()->GetCoarserGrid(sol);
37 Grid& rhs_c = MG::GetComm()->GetCoarserGrid(rhs);
38
39 Index begin_f = rhs().Local().Begin();
40 const Index end_f = rhs().Local().End();
41 const Index begin_c = rhs_c.Local().AlignmentBegin();
42
43 if (sol_c.Global().BoundaryType() == GlobalCoarsened &&
44 (MG::GetComm()->BoundaryConditions() == Dirichlet || MG::GetComm()->BoundaryConditions() == Quasiperiodic))
45 begin_f += 1;
46
47 const Stencil& op_res = OperatorRestrict();
48 const Stencil& op_sol = OperatorSol();
49 const Stencil& op_pde = MG::GetDiscretization()->GetStencil();
50
51 // Communication step
52 MG::GetComm()->CommToGhosts(sol());
53
54 MG::GetDiscretization()->SetInnerBoundary(sol(), rhs(), sol_c);
55
56 // Compute residual
57 VMG::TempGrid *res_grid = MG::GetTempGrid();
58 res_grid->SetProperties(rhs());
59 res_grid->ImportFromResidual(sol(), rhs());
60
61 VMG::TempGrid* sol_old = this->GetTempGrid(sol.Level()-1);
62 sol_old->SetProperties(sol_c);
63 sol_old->Clear();
64
65 for (i_c.X()=begin_c.X(), i_f.X()=begin_f.X(); i_f.X()<end_f.X(); ++i_c.X(), i_f.X()+=2)
66 for (i_c.Y()=begin_c.Y(), i_f.Y()=begin_f.Y(); i_f.Y()<end_f.Y(); ++i_c.Y(), i_f.Y()+=2)
67 for (i_c.Z()=begin_c.Z(), i_f.Z()=begin_f.Z(); i_f.Z()<end_f.Z(); ++i_c.Z(), i_f.Z()+=2) {
68
69 val = op_sol.GetDiag() * sol().GetVal(i_f);
70
71 for (iter=op_sol.begin(); iter!=op_sol.end(); ++iter)
72 val += iter->val * sol().GetVal(i_f + iter);
73
74 sol_c(i_c) = (*sol_old)(i_c) = val;
75
76 }
77
78 MG::GetComm()->CommToGhosts(sol_c);
79
80 const vmg_float prefactor = MG::GetDiscretization()->OperatorPrefactor(sol_c);
81
82 for (i_c.X()=begin_c.X(), i_f.X()=begin_f.X(); i_f.X()<end_f.X(); ++i_c.X(), i_f.X()+=2)
83 for (i_c.Y()=begin_c.Y(), i_f.Y()=begin_f.Y(); i_f.Y()<end_f.Y(); ++i_c.Y(), i_f.Y()+=2)
84 for (i_c.Z()=begin_c.Z(), i_f.Z()=begin_f.Z(); i_f.Z()<end_f.Z(); ++i_c.Z(), i_f.Z()+=2)
85 rhs_c(i_c) = op_res.Apply(*res_grid, i_f) + prefactor * op_pde.Apply(sol_c, i_c);
86
87 // Bring grids to the next coarser level
88 rhs.ToCoarserLevel();
89 sol.ToCoarserLevel();
90
91#ifdef DEBUG
92 sol().IsConsistent();
93 rhs().IsConsistent();
94 sol().IsCompatible(rhs());
95#endif
96}
97
98void LevelOperatorFAS::Prolongate(Multigrid& sol, Multigrid& rhs)
99{
100#ifdef DEBUG
101 sol().IsConsistent();
102 rhs().IsConsistent();
103 sol().IsCompatible(rhs());
104#endif
105
106 Index i_c, i_f;
107 Stencil::iterator iter;
108 vmg_float val;
109
110 Grid& sol_f = MG::GetComm()->GetFinerGrid(sol);
111
112 const Stencil& op = OperatorProlongate();
113
114 const Index begin_c = sol().Local().AlignmentBegin();
115 Index begin_f = sol_f.Local().Begin();
116 const Index end_f = sol_f.Local().End();
117
118 if (sol().Global().BoundaryType() == GlobalCoarsened &&
119 (MG::GetComm()->BoundaryConditions() == Dirichlet || MG::GetComm()->BoundaryConditions() == Quasiperiodic))
120 begin_f += 1;
121
122 VMG::TempGrid *sol_old = this->GetTempGrid(sol.Level());
123
124 if (sol().Global().BoundaryType() == LocallyRefined)
125 MG::GetDiscretization()->SetInnerBoundary(sol(), rhs(), MG::GetComm()->GetCoarserGrid(sol));
126
127 if (MG::GetComm()->BoundaryConditions() == Periodic) {
128
129 sol_f.ClearHalo();
130
131 for (i_c.X()=begin_c.X(), i_f.X()=begin_f.X(); i_f.X()<end_f.X(); ++i_c.X(), i_f.X()+=2)
132 for (i_c.Y()=begin_c.Y(), i_f.Y()=begin_f.Y(); i_f.Y()<end_f.Y(); ++i_c.Y(), i_f.Y()+=2)
133 for (i_c.Z()=begin_c.Z(), i_f.Z()=begin_f.Z(); i_f.Z()<end_f.Z(); ++i_c.Z(), i_f.Z()+=2) {
134
135 val = sol().GetVal(i_c) - sol_old->GetVal(i_c);
136
137 sol_f(i_f) += op.GetDiag() * val;
138
139 for (iter=op.begin(); iter!=op.end(); ++iter)
140 sol_f(i_f + iter) += iter->val * val;
141
142 }
143
144 MG::GetComm()->CommFromGhosts(sol_f);
145
146 }else if (MG::GetComm()->BoundaryConditions() == Dirichlet ||
147 MG::GetComm()->BoundaryConditions() == Quasiperiodic) {
148
149 for (i_c.X()=begin_c.X(), i_f.X()=begin_f.X(); i_f.X()<end_f.X(); ++i_c.X(), i_f.X()+=2)
150 for (i_c.Y()=begin_c.Y(), i_f.Y()=begin_f.Y(); i_f.Y()<end_f.Y(); ++i_c.Y(), i_f.Y()+=2)
151 for (i_c.Z()=begin_c.Z(), i_f.Z()=begin_f.Z(); i_f.Z()<end_f.Z(); ++i_c.Z(), i_f.Z()+=2) {
152
153 val = sol().GetVal(i_c) - sol_old->GetVal(i_c);
154
155 sol_f(i_f) += op.GetDiag() * val;
156
157 //TODO: This does not work in parallel
158 for (iter=op.begin(); iter!=op.end(); ++iter)
159 if (i_f.X()+iter->m >= sol_f.Local().Begin().X() && i_f.X()+iter->m < sol_f.Local().End().X() &&
160 i_f.Y()+iter->n >= sol_f.Local().Begin().Y() && i_f.Y()+iter->n < sol_f.Local().End().Y() &&
161 i_f.Z()+iter->o >= sol_f.Local().Begin().Z() && i_f.Z()+iter->o < sol_f.Local().End().Z()) {
162 sol_f(i_f + iter) += iter->val * val;
163 }
164 }
165 }
166
167 sol.ToFinerLevel();
168 rhs.ToFinerLevel();
169
170#ifdef DEBUG
171 sol_f.IsConsistent();
172#endif
173}
Note: See TracBrowser for help on using the repository browser.