source: src/level/level_operator_fas.cpp@ 06e153

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

Fixed some warnings.

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

  • Property mode set to 100644
File size: 4.2 KB
Line 
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 Grid::iterator iter_f, iter_c;
27 Stencil::iterator stencil_iter;
28
29 Comm& comm = *MG::GetComm();
30
31 Grid& sol_f = sol(sol.Level());
32 Grid& rhs_f = rhs(rhs.Level());
33
34 Grid& sol_c_dist = sol(sol.Level()-1);
35 Grid& rhs_c_dist = rhs(rhs.Level()-1);
36
37 Grid& sol_c_undist = comm.GetCoarserGrid(sol);
38 Grid& rhs_c_undist = comm.GetCoarserGrid(rhs);
39
40 Index begin_f = rhs_f.Local().Begin();
41 Index end_f = rhs_f.Local().End();
42
43 if (rhs_c_undist.Global().BoundaryType() == GlobalCoarsened) {
44 begin_f += rhs_f.Local().BoundarySize1();
45 end_f -= rhs_f.Local().BoundarySize2();
46 }
47
48 const GridIteratorSet bounds_f(begin_f, end_f);
49 const GridIteratorSet bounds_c(rhs_c_undist.Local().FinerBegin(), rhs_c_undist.Local().FinerEnd());
50
51 const Stencil& op_res = OperatorRestrict();
52 const Stencil& op_sol = OperatorSol();
53 const Stencil& op_pde = MG::GetDiscretization()->GetStencil();
54 const vmg_float prefactor = MG::GetDiscretization()->OperatorPrefactor(sol_c_undist);
55
56 // Communication step
57 comm.CommToGhosts(sol_f);
58 comm.CommSubgrid(sol_c_dist, sol_c_undist, 0);
59
60 MG::GetDiscretization()->SetInnerBoundary(sol_f, rhs_f, sol_c_undist);
61
62 // Compute residual
63 VMG::TempGrid *res_grid = MG::GetTempGrid();
64 res_grid->SetProperties(rhs_f);
65 res_grid->ImportFromResidual(sol_f, rhs_f);
66
67 for (iter_f=bounds_f.Begin(), iter_c=bounds_c.Begin(); iter_c!=bounds_c.End(); iter_f+=2, ++iter_c)
68 sol_c_undist(*iter_c) = op_sol.Apply(sol_f, *iter_f);
69
70 for (iter_f=bounds_f.Begin(), iter_c=bounds_c.Begin(); iter_c!=bounds_c.End(); iter_f+=2, ++iter_c)
71 rhs_c_undist(*iter_c) = op_res.Apply(*res_grid, *iter_f);
72
73 comm.CommSubgrid(sol_c_undist, sol_c_dist, 1);
74 comm.CommToGhosts(sol_c_dist);
75
76 comm.CommSubgrid(rhs_c_undist, rhs_c_dist, 1);
77
78 VMG::TempGrid* sol_old = this->GetTempGrid(sol_c_dist.Level());
79 sol_old->SetProperties(sol_c_dist);
80 sol_old->SetGrid(sol_c_dist);
81
82 for (iter_c=rhs_c_dist.Iterators().Local().Begin(); iter_c!=rhs_c_dist.Iterators().Local().End(); ++iter_c)
83 rhs_c_dist(*iter_c) += prefactor * op_pde.Apply(sol_c_dist, *iter_c);
84
85 comm.CommToGhosts(rhs_c_dist);
86
87 sol.ToCoarserLevel();
88 rhs.ToCoarserLevel();
89}
90
91void LevelOperatorFAS::Prolongate(Multigrid& sol, Multigrid& rhs)
92{
93 Grid::iterator iter_f, iter_c;
94 Stencil::iterator stencil_iter;
95 vmg_float val;
96
97 Comm& comm = *MG::GetComm();
98
99 Grid& sol_c = sol(sol.Level());
100 Grid& sol_f_dist = sol(sol.Level()+1);
101 Grid& rhs_f_dist = rhs(rhs.Level()+1);
102 Grid& sol_f_undist = comm.GetFinerGrid(sol);
103 Grid& rhs_f_undist = comm.GetFinerGrid(rhs);
104
105 const Stencil& op = OperatorProlongate();
106
107 TempGrid *sol_old = this->GetTempGrid(sol_c.Level());
108
109 Index begin_f = sol_f_undist.Local().Begin();
110 Index end_f = sol_f_undist.Local().End();
111
112 if (sol_c.Global().BoundaryType() == GlobalCoarsened) {
113 begin_f += rhs_f_undist.Local().BoundarySize1();
114 end_f -= rhs_f_undist.Local().BoundarySize2();
115 }
116
117 const GridIteratorSet bounds_f(begin_f, end_f);
118 const GridIteratorSet bounds_c(sol_c.Local().FinerBegin(), sol_c.Local().FinerEnd());
119
120 sol_f_undist.ClearHalo();
121
122 for (iter_f=bounds_f.Begin(), iter_c=bounds_c.Begin(); iter_f!=bounds_f.End(); iter_f+=2, ++iter_c) {
123 val = sol_c.GetVal(*iter_c) - sol_old->GetVal(*iter_c);
124 sol_f_undist(*iter_f) += op.GetDiag() * val;
125 for (stencil_iter = op.begin(); stencil_iter != op.end(); ++stencil_iter)
126 sol_f_undist(*iter_f + stencil_iter->Disp()) += stencil_iter->Val() * val;
127 }
128
129 comm.CommFromGhosts(sol_f_undist);
130 comm.CommSubgrid(sol_f_undist, sol_f_dist, 1);
131
132 if (sol_f_dist.Global().BoundaryType() == LocallyRefined)
133 MG::GetDiscretization()->SetInnerBoundary(sol_f_dist, rhs_f_dist, sol_c);
134
135 sol.ToFinerLevel();
136 rhs.ToFinerLevel();
137}
Note: See TracBrowser for help on using the repository browser.