source: src/level/level_operator_fas.cpp@ ef94e7

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

vmg: Added license files and headers (GPLv3).

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

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * vmg - a versatile multigrid solver
3 * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
4 *
5 * vmg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * vmg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file level_operator_fas.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Mon Apr 18 13:00:23 2011
23 *
24 * @brief VMG::LevelOperatorFAS
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32#include "base/discretization.hpp"
33#include "base/index.hpp"
34#include "comm/comm.hpp"
35#include "grid/multigrid.hpp"
36#include "grid/tempgrid.hpp"
37#include "level/level_operator_fas.hpp"
38#include "mg.hpp"
39
40using namespace VMG;
41
42void LevelOperatorFAS::Restrict(Multigrid& sol, Multigrid& rhs)
43{
44 Grid::iterator iter_f, iter_c;
45 Stencil::iterator stencil_iter;
46
47 Comm& comm = *MG::GetComm();
48
49 Grid& sol_f = sol(sol.Level());
50 Grid& rhs_f = rhs(rhs.Level());
51
52 Grid& sol_c_dist = sol(sol.Level()-1);
53 Grid& rhs_c_dist = rhs(rhs.Level()-1);
54
55 Grid& sol_c_undist = comm.GetCoarserGrid(sol);
56 Grid& rhs_c_undist = comm.GetCoarserGrid(rhs);
57
58 Index begin_f = rhs_f.Local().Begin();
59 Index end_f = rhs_f.Local().End();
60
61 if (rhs_c_undist.Global().BoundaryType() == GlobalCoarsened) {
62 begin_f += rhs_f.Local().BoundarySize1();
63 end_f -= rhs_f.Local().BoundarySize2();
64 }
65
66 const GridIteratorSet bounds_f(begin_f, end_f);
67 const GridIteratorSet bounds_c(rhs_c_undist.Local().FinerBegin(), rhs_c_undist.Local().FinerEnd());
68
69 const Stencil& op_res = OperatorRestrict();
70 const Stencil& op_sol = OperatorSol();
71 const Stencil& op_pde = MG::GetDiscretization()->GetStencil();
72 const vmg_float prefactor = MG::GetDiscretization()->OperatorPrefactor(sol_c_undist);
73
74 // Communication step
75 comm.CommToGhosts(sol_f);
76 comm.CommSubgrid(sol_c_dist, sol_c_undist, 0);
77
78 MG::GetDiscretization()->SetInnerBoundary(sol_f, rhs_f, sol_c_undist);
79
80 // Compute residual
81 VMG::TempGrid *res_grid = MG::GetTempGrid();
82 res_grid->SetProperties(rhs_f);
83 res_grid->ImportFromResidual(sol_f, rhs_f);
84
85 for (iter_f=bounds_f.Begin(), iter_c=bounds_c.Begin(); iter_c!=bounds_c.End(); iter_f+=2, ++iter_c)
86 sol_c_undist(*iter_c) = op_sol.Apply(sol_f, *iter_f);
87
88 for (iter_f=bounds_f.Begin(), iter_c=bounds_c.Begin(); iter_c!=bounds_c.End(); iter_f+=2, ++iter_c)
89 rhs_c_undist(*iter_c) = op_res.Apply(*res_grid, *iter_f);
90
91 comm.CommSubgrid(sol_c_undist, sol_c_dist, 1);
92 comm.CommToGhosts(sol_c_dist);
93
94 comm.CommSubgrid(rhs_c_undist, rhs_c_dist, 1);
95
96 VMG::TempGrid* sol_old = this->GetTempGrid(sol_c_dist.Level());
97 sol_old->SetProperties(sol_c_dist);
98 sol_old->SetGrid(sol_c_dist);
99
100 for (iter_c=rhs_c_dist.Iterators().Local().Begin(); iter_c!=rhs_c_dist.Iterators().Local().End(); ++iter_c)
101 rhs_c_dist(*iter_c) += prefactor * op_pde.Apply(sol_c_dist, *iter_c);
102
103 comm.CommToGhosts(rhs_c_dist);
104
105 sol.ToCoarserLevel();
106 rhs.ToCoarserLevel();
107}
108
109void LevelOperatorFAS::Prolongate(Multigrid& sol, Multigrid& rhs)
110{
111 Grid::iterator iter_f, iter_c;
112 Stencil::iterator stencil_iter;
113 vmg_float val;
114
115 Comm& comm = *MG::GetComm();
116
117 Grid& sol_c = sol(sol.Level());
118 Grid& sol_f_dist = sol(sol.Level()+1);
119 Grid& rhs_f_dist = rhs(rhs.Level()+1);
120 Grid& sol_f_undist = comm.GetFinerGrid(sol);
121 Grid& rhs_f_undist = comm.GetFinerGrid(rhs);
122
123 const Stencil& op = OperatorProlongate();
124
125 TempGrid *sol_old = this->GetTempGrid(sol_c.Level());
126
127 Index begin_f = sol_f_undist.Local().Begin();
128 Index end_f = sol_f_undist.Local().End();
129
130 if (sol_c.Global().BoundaryType() == GlobalCoarsened) {
131 begin_f += rhs_f_undist.Local().BoundarySize1();
132 end_f -= rhs_f_undist.Local().BoundarySize2();
133 }
134
135 const GridIteratorSet bounds_f(begin_f, end_f);
136 const GridIteratorSet bounds_c(sol_c.Local().FinerBegin(), sol_c.Local().FinerEnd());
137
138 sol_f_undist.ClearHalo();
139
140 for (iter_f=bounds_f.Begin(), iter_c=bounds_c.Begin(); iter_f!=bounds_f.End(); iter_f+=2, ++iter_c) {
141 val = sol_c.GetVal(*iter_c) - sol_old->GetVal(*iter_c);
142 sol_f_undist(*iter_f) += op.GetDiag() * val;
143 for (stencil_iter = op.begin(); stencil_iter != op.end(); ++stencil_iter)
144 sol_f_undist(*iter_f + stencil_iter->Disp()) += stencil_iter->Val() * val;
145 }
146
147 comm.CommFromGhosts(sol_f_undist);
148 comm.CommSubgrid(sol_f_undist, sol_f_dist, 1);
149
150 if (sol_f_dist.Global().BoundaryType() == LocallyRefined)
151 MG::GetDiscretization()->SetInnerBoundary(sol_f_dist, rhs_f_dist, sol_c);
152
153 sol.ToFinerLevel();
154 rhs.ToFinerLevel();
155}
Note: See TracBrowser for help on using the repository browser.