source: src/level/level_operator_fas.cpp@ ae05b4

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

Fix energy calculation.

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

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