-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathMultiLevelProblem.hpp
317 lines (233 loc) · 8.96 KB
/
MultiLevelProblem.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*=========================================================================
Program: FEMuS
Module: MultiLevelProblem
Authors: Eugenio Aulisa, Simone Bnà, Giorgio Bornia
Copyright (c) FEMuS
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#ifndef __femus_equations_MultiLevelProblem_hpp__
#define __femus_equations_MultiLevelProblem_hpp__
//----------------------------------------------------------------------------
// includes :
//----------------------------------------------------------------------------
#include "MultiLevelMesh.hpp"
#include "MultiLevelSolution.hpp"
#include "Solution.hpp"
#include "Parameters.hpp"
#include "ParallelObject.hpp"
#include "MgSmootherEnum.hpp"
#include <vector>
#include <map>
#include "GaussPoints.hpp"
#include "FemusInputParser.hpp"
namespace femus {
using std::map;
//------------------------------------------------------------------------------
// Forward declarations
//------------------------------------------------------------------------------
class System;
class MultiLevelMeshTwo;
class elem_type;
class QuantityMap;
typedef double (*initfunc) (const double &x, const double &y, const double &z);
/**
* This class is a black box container to handle multilevel problems.
*/
class MultiLevelProblem {
public:
/** Constructor */
//MultiLevelProblem(MultiLevelMesh *ml_msh, MultiLevelSolution *ml_sol);
MultiLevelProblem(MultiLevelSolution *ml_sol);
/** Destructor */
~MultiLevelProblem();
/** Multilevel solution pointer */
MultiLevelSolution *_ml_sol;
/** Multilevel mesh pointer */
MultiLevelMesh *_ml_msh;
/** Data structure holding arbitrary parameters. */
Parameters parameters;
/** Data structure holding the systems. */
std::map<std::string, System*> _systems;
/** Typedef for system iterators */
typedef std::map<std::string, System*>::iterator system_iterator;
/** Typedef for constatnt system iterators */
typedef std::map<std::string, System*>::const_iterator const_system_iterator;
/** Add the system of type \p system_type named \p name to the systems array. */
virtual System & add_system (const std::string& system_type, const std::string& name);
/** Add the system named \p name to the systems array. */
template <typename T_sys> T_sys & add_system (const std::string& name, const MgSmoother & smoother_type = GMRES_SMOOTHER);
/**
* @returns a constant reference to the system named \p name.
* The template argument defines the return type. For example,
* const SteadySystem& sys = eq.get_system<SteadySystem> ("sys");
* is an example of how the method might be used
*/
template <typename T_sys>
const T_sys & get_system (const std::string& name) const;
/**
* @returns a writeable referene to the system named \p name.
* The template argument defines the return type. For example,
* const SteadySystem& sys = eq.get_system<SteadySystem> ("sys");
* is an example of how the method might be used
*/
template <typename T_sys>
T_sys & get_system (const std::string& name);
/**
* @returns a constant reference to system number \p num.
* The template argument defines the return type. For example,
* const SteadySystem& sys = eq.get_system<SteadySystem> (0);
* is an example of how the method might be used
*/
template <typename T_sys>
const T_sys & get_system (const unsigned int num) const;
/**
* @returns a writeable referene to the system number \p num.
* The template argument defines the return type. For example,
* const SteadySystem& sys = eq.get_system<SteadySystem> (0);
* is an example of how the method might be used
*/
template <typename T_sys>
T_sys & get_system (const unsigned int num);
/**
* @returns a constant reference to the system named \p name.
*/
const System & get_system (const std::string& name) const;
/**
* @returns a writeable referene to the system named \p name.
*/
System & get_system (const std::string& name);
/**
* @returns a constant reference to system number \p num.
*/
const System & get_system (const unsigned int num) const;
/**
* @returns a writeable referene to the system number \p num.
*/
System & get_system (const unsigned int num);
/** @returns the number of equation systems. */
unsigned int n_systems() const;
/** Clear all the Sytems PDE structures */
void clear();
// /** init the system pde structures */
// void init();
/** Get the total number of grid, both totally refined and partial refined for DomainDecomposition */
const unsigned GetNumberOfLevels() const {
return _gridn;
};
/** Increase of one the number of levels */
void AddLevel(){
_gridn++;
};
/** returns the beginning of the systems map */
inline system_iterator begin() { return _systems.begin(); }
/** */
inline system_iterator end() { return _systems.end(); }
/** */
inline const_system_iterator begin() const { return _systems.begin(); }
/** */
inline const_system_iterator end() const { return _systems.end(); }
/** New get/set for new data */
inline void SetMeshTwo(const MultiLevelMeshTwo * mesh_in) { _mesh = mesh_in; return; }
inline const MultiLevelMeshTwo & GetMeshTwo() const { return *_mesh; }
/** Quantity Map */
inline void SetQtyMap(const QuantityMap * qtymap_in) { _qtymap = qtymap_in; return; }
inline const QuantityMap & GetQtyMap() const { return *_qtymap; }
/** ElemType and Quadrature rule */
inline const std::vector<const elem_type*> & GetElemType(const unsigned dim) const { return _elem_type[dim - 1]; }
inline const std::vector< std::vector<const elem_type*> > & GetElemType() const { return _elem_type; }
inline const Gauss & GetQrule(const unsigned dim) const { return _qrule[dim - 1]; }
void SetQruleAndElemType(const std::string quadr_order_in);
/** Input Parser */
inline const FemusInputParser<double> & GetInputParser() const { return *_phys; }
void SetInputParser(const FemusInputParser<double> * parser_in) { _phys = parser_in; return; }
private:
// member data
vector < map <unsigned,bool> > index;
unsigned short _gridn;
std::vector< std::vector<const elem_type*> > _elem_type;
std::vector<Gauss> _qrule;
const FemusInputParser<double> * _phys;
const QuantityMap * _qtymap;
const MultiLevelMeshTwo * _mesh;
};
template <typename T_sys>
inline
T_sys & MultiLevelProblem::add_system (const std::string& name,const MgSmoother & smoother_type )
{
T_sys* ptr = NULL;
if (!_systems.count(name))
{
ptr = new T_sys(*this, name, this->n_systems(),smoother_type);
_systems.insert (std::make_pair(name, ptr));
}
else
{
// We now allow redundant add_system calls, to make it
// easier to load data from files for user-derived system
// subclasses
std::cerr << "ERROR: There was already a system"
<< " named " << name
<< std::endl;
ptr = &(this->get_system<T_sys>(name));
}
// Return a dynamically casted reference to the newly added System.
return *ptr;
}
template <typename T_sys>
inline
const T_sys & MultiLevelProblem::get_system (const std::string& name) const
{
const_system_iterator pos = _systems.find(name);
// Check for errors
if (pos == _systems.end())
{
std::cerr << "ERROR: no system named \"" << name << "\" found!"
<< std::endl;
}
// Attempt dynamic cast
return *static_cast<T_sys*>(pos->second);
}
template <typename T_sys>
inline
T_sys & MultiLevelProblem::get_system (const std::string& name)
{
system_iterator pos = _systems.find(name);
// Check for errors
if (pos == _systems.end())
{
std::cerr << "ERROR: no system named " << name << " found!"
<< std::endl;
}
// Attempt dynamic cast
return *static_cast<T_sys*>(pos->second);
}
inline
const System & MultiLevelProblem::get_system (const std::string& name) const
{
return this->get_system<System>(name);
}
inline
System & MultiLevelProblem::get_system (const std::string& name)
{
return this->get_system<System>(name);
}
inline
const System & MultiLevelProblem::get_system (const unsigned int num) const
{
return this->get_system<System>(num);
}
inline
System & MultiLevelProblem::get_system (const unsigned int num)
{
return this->get_system<System>(num);
}
inline
unsigned int MultiLevelProblem::n_systems () const
{
return static_cast<unsigned int>(_systems.size()); //libmesh static_cast_int
}
} //end namespace femus
#endif