source: src/mg.cpp@ d6a338

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

Save the whole domain decomposition instead of just the part for the current process.

  • Property mode set to 100644
File size: 7.4 KB
RevLine 
[fcf7f6]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
[48b662]19/**
20 * @file mg.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Sat Jun 12 20:36:24 2010
23 *
24 * @brief A multigrid solver
25 *
26 * This file contains the implementation of the main class for
27 * a multigrid solver.
28 *
29 */
30
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
[d13e27]35#ifdef OUTPUT_TIMING
[76e019]36#ifdef HAVE_MPI
37#include <mpi.h>
[ac6d04]38#ifdef HAVE_MARMOT
39#include <enhancempicalls.h>
40#include <sourceinfompicalls.h>
41#endif
[76e019]42#endif
43#endif
44
[48b662]45#include <cmath>
46#include <cstdio>
47#include <cfloat>
48#include <ctime>
49#include <string>
50#include <fstream>
51#include <sstream>
52
53#include "base/command_list.hpp"
54#include "base/discretization.hpp"
55#include "base/factory.hpp"
[f003a9]56#include "base/interface.hpp"
[dfed1c]57#include "base/timer.hpp"
[48b662]58#include "comm/comm.hpp"
[b57b9b]59#include "cycles/cycle.hpp"
[dfed1c]60#include "grid/grid.hpp"
[48b662]61#include "grid/tempgrid.hpp"
62#include "level/level_operator.hpp"
63#include "smoother/smoother.hpp"
64#include "solver/solver.hpp"
65#include "mg.hpp"
66
67using namespace VMG;
68
69#define REGISTER_COMMAND(a) extern void Initialize##a();Initialize##a();
70
[dfed1c]71VMG::CommandFactory MG::command_factory;
[48b662]72
73static void VMGRegisterBuiltinCommands()
74{
75 REGISTER_COMMAND(VMGCommandCheckConsistency);
76 REGISTER_COMMAND(VMGCommandCheckIterationCounter);
77 REGISTER_COMMAND(VMGCommandCheckRelativeResidual);
78 REGISTER_COMMAND(VMGCommandCheckResidual);
79 REGISTER_COMMAND(VMGCommandClearCoarseLevels);
80 REGISTER_COMMAND(VMGCommandClearGrid);
[dfed1c]81 REGISTER_COMMAND(VMGCommandComputeResidualNorm);
[48b662]82 REGISTER_COMMAND(VMGCommandCopyBoundary);
83 REGISTER_COMMAND(VMGCommandExecuteCycle);
84 REGISTER_COMMAND(VMGCommandExecuteCycleLoop);
85 REGISTER_COMMAND(VMGCommandExecuteFullCycle);
86 REGISTER_COMMAND(VMGCommandExecuteFullCycleLoop);
87 REGISTER_COMMAND(VMGCommandExportSolution);
88 REGISTER_COMMAND(VMGCommandForceDiscreteCompatibility);
89 REGISTER_COMMAND(VMGCommandImportRightHandSide);
90 REGISTER_COMMAND(VMGCommandInterpolateFMG);
[dfed1c]91 REGISTER_COMMAND(VMGCommandInitializeIterationCounter);
[48b662]92 REGISTER_COMMAND(VMGCommandInitializeResidualNorm);
[dfed1c]93 REGISTER_COMMAND(VMGCommandNOP);
94 REGISTER_COMMAND(VMGCommandPrintAllSettings);
[48b662]95 REGISTER_COMMAND(VMGCommandPrintDefect);
96 REGISTER_COMMAND(VMGCommandPrintGridStructure);
97 REGISTER_COMMAND(VMGCommandPrintGrid);
98 REGISTER_COMMAND(VMGCommandPrintResidualNorm);
[dfed1c]99 REGISTER_COMMAND(VMGCommandPrintRunningTime);
[48b662]100 REGISTER_COMMAND(VMGCommandProlongate);
101 REGISTER_COMMAND(VMGCommandRestrict);
102 REGISTER_COMMAND(VMGCommandSetAverageToZero);
103 REGISTER_COMMAND(VMGCommandSetCoarserDirichletValues);
104 REGISTER_COMMAND(VMGCommandSetLevel);
105 REGISTER_COMMAND(VMGCommandSmooth);
106 REGISTER_COMMAND(VMGCommandSolve);
107}
108
109MG::MG()
110{
[dfed1c]111 state = 0;
[48b662]112 VMGRegisterBuiltinCommands();
113}
114
115MG::~MG()
116{
117 MG::Destroy();
118}
119
120// Brings Multigrid back to starting state.
121void MG::Destroy()
122{
[dfed1c]123 MG::Instance()->factories.clear();
124 MG::Instance()->state = 0;
125 Timer::Clear();
[48b662]126}
127
[a24b80]128/*
129 * Post init communication class
130 */
131void MG::PostInit()
[48b662]132{
[b57b9b]133 if (GetFactory().TestObject("COMM") && GetFactory().TestObject("INTERFACE")) {
[a24b80]134
[d6a338]135 GetComm()->ComputeDomainDecomposition(*GetInterface());
136
137 Multigrid* sol = new Multigrid(*GetComm(), *GetInterface());
[b57b9b]138 sol->Register("SOL");
[a24b80]139
[d6a338]140 Multigrid* rhs = new Multigrid(*GetComm(), *GetInterface());
[b57b9b]141 rhs->Register("RHS");
[48b662]142
[b57b9b]143 TempGrid* temp = new TempGrid();
144 temp->Register("TEMPGRID");
[48b662]145
[b57b9b]146 new ObjectStorage<int>("GLOBAL_MAXLEVEL", sol->GlobalMaxLevel());
147 new ObjectStorage<int>("MINLEVEL", sol->MinLevel());
148 new ObjectStorage<int>("MAXLEVEL", sol->MaxLevel());
149
150 if (GetFactory().TestObject("CYCLE"))
151 GetCycle()->Generate();
152
[d6a338]153 GetComm()->PostInit(*GetSol(), *GetRhs());
[b57b9b]154
155 }
[894a5f]156}
157
[48b662]158/**
159 * Solves a given system with a multigrid method
160 *
161 */
162void MG::Solve()
163{
[d13e27]164#ifdef OUTPUT_TIMING
[2a5451]165 GetComm()->Barrier();
[ac6d04]166 Timer::Start("CompleteRunningTime");
[dfed1c]167#endif
168
169 CommandList* cl_init = MG::GetFactory().Get("COMMANDLIST_INIT")->Cast<CommandList>();
170 CommandList* cl_loop = MG::GetFactory().Get("COMMANDLIST_LOOP")->Cast<CommandList>();
171 CommandList* cl_finalize = MG::GetFactory().Get("COMMANDLIST_FINALIZE")->Cast<CommandList>();
[48b662]172
173 cl_init->ExecuteList();
174
175 while (cl_loop->ExecuteList() == Continue);
176
177 cl_finalize->ExecuteList();
[dfed1c]178
[d13e27]179#ifdef OUTPUT_TIMING
[2a5451]180 GetComm()->Barrier();
[dfed1c]181 Timer::Stop("CompleteRunningTime");
[ac6d04]182#ifdef HAVE_MPI
183 Timer::PrintGlobal();
184#else
185 Timer::Print();
186#endif
[dfed1c]187#endif
188}
189
190void MG::SetState(const int& state_)
191{
192 MG::Instance()->state = state_;
193}
194
195VMG::Factory& MG::GetFactory()
196{
197 std::map<int, VMG::Factory>::iterator iter = MG::Instance()->factories.find(MG::Instance()->state);
198
199 if (iter == MG::Instance()->factories.end())
200 iter = MG::Instance()->factories.insert(std::make_pair(MG::Instance()->state, Factory())).first;
201
202 assert(iter != MG::Instance()->factories.end());
203
204 return iter->second;
205}
206
207VMG::CommandFactory& MG::GetCommands()
208{
209 return MG::command_factory;
[48b662]210}
211
212Comm* MG::GetComm()
213{
[dfed1c]214 return MG::GetFactory().Get("COMM")->Cast<VMG::Comm>();
[48b662]215}
216
[b57b9b]217Cycle* MG::GetCycle()
218{
219 return MG::GetFactory().Get("CYCLE")->Cast<VMG::Cycle>();
220}
221
[48b662]222Discretization* MG::GetDiscretization()
223{
[dfed1c]224 return MG::GetFactory().Get("DISCRETIZATION")->Cast<VMG::Discretization>();
[48b662]225}
226
227LevelOperator* MG::GetLevelOperator()
228{
[dfed1c]229 return MG::GetFactory().Get("LEVEL_OPERATOR")->Cast<VMG::LevelOperator>();
[48b662]230}
231
232Multigrid* MG::GetRhs()
233{
[dfed1c]234 return MG::GetFactory().Get("RHS")->Cast<VMG::Multigrid>();
[48b662]235}
236
237Multigrid* MG::GetSol()
238{
[dfed1c]239 return MG::GetFactory().Get("SOL")->Cast<VMG::Multigrid>();
[48b662]240}
241
[4571da]242VMG::Grid& MG::GetRhsMaxLevel()
243{
244 return (*MG::GetRhs())(MG::GetRhs()->MaxLevel());
245}
246
247VMG::Grid& MG::GetSolMaxLevel()
248{
249 return (*MG::GetSol())(MG::GetSol()->MaxLevel());
250}
251
[48b662]252Smoother* MG::GetSmoother()
253{
[dfed1c]254 return MG::GetFactory().Get("SMOOTHER")->Cast<VMG::Smoother>();
[48b662]255}
256
257Solver* MG::GetSolver()
258{
[dfed1c]259 return MG::GetFactory().Get("SOLVER")->Cast<VMG::Solver>();
[48b662]260}
261
262TempGrid* MG::GetTempGrid()
263{
[dfed1c]264 return MG::GetFactory().Get("TEMPGRID")->Cast<VMG::TempGrid>();
[48b662]265}
266
267Interface* MG::GetInterface()
268{
[dfed1c]269 return MG::GetFactory().Get("INTERFACE")->Cast<VMG::Interface>();
[48b662]270}
271
272bool MG::IsInitialized()
273{
[b57b9b]274 const Factory& f = GetFactory();
275
[48b662]276 bool init = true;
277
[b57b9b]278 init &= f.TestObject("COMM");
279 init &= f.TestObject("LEVEL_OPERATOR");
280 init &= f.TestObject("RHS");
281 init &= f.TestObject("SOL");
282 init &= f.TestObject("SOLVER");
283 init &= f.TestObject("SMOOTHER");
284 init &= f.TestObject("DISCRETIZATION");
285 init &= f.TestObject("MAX_ITERATION");
286 init &= f.TestObject("PRECISION");
287 init &= f.TestObject("PRESMOOTHSTEPS");
288 init &= f.TestObject("POSTSMOOTHSTEPS");
289 init &= f.TestObject("COMMANDLIST_INIT");
290 init &= f.TestObject("COMMANDLIST_LOOP");
291 init &= f.TestObject("COMMANDLIST_FINALIZE");
292 init &= f.TestObject("MINLEVEL");
293 init &= f.TestObject("MAXLEVEL");
294 init &= f.TestObject("GLOBAL_MAXLEVEL");
295 init &= f.TestObject("INTERFACE");
[48b662]296
297 return init;
298}
Note: See TracBrowser for help on using the repository browser.