1
#ifndef _RHEOLEF_FIELD_COMPONENT_H
2
#define _RHEOLEF_FIELD_COMPONENT_H
4
/// This file is part of Rheolef.
6
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
8
/// Rheolef is free software; you can redistribute it and/or modify
9
/// it under the terms of the GNU General Public License as published by
10
/// the Free Software Foundation; either version 2 of the License, or
11
/// (at your option) any later version.
13
/// Rheolef is distributed in the hope that it will be useful,
14
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
/// GNU General Public License for more details.
18
/// You should have received a copy of the GNU General Public License
19
/// along with Rheolef; if not, write to the Free Software
20
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
/// =========================================================================
24
/* TODO: when slip B.C. or Raviart-Thomas RT H(div) approx :
25
uh[0] values are computed on the fly in a temporary
27
struct field_component {
29
field_basic<T,M>::iterator _start, _last;
30
const space_constit& _constit; // a ce niveau
31
field* _tmp_comp_ptr; // si necesite un temporaire
33
field_component (field& uh, i_comp) {
34
constit = uh.get_space().get_constitution();
35
_constit = constit[i_comp]);
36
if (! constit.has_slip_bc() && ! constit.has_hdiv()) {
38
_star & _last : pointe dans le field uh
41
_tmp_comp_ptr = new field (Vi);
42
uh.compute_slip_comp (i_comp, *_tmp_comp_ptr);
43
_star & _last : pointe dans *_tmp_comp_ptr
47
if (_tmp_comp_ptr) delete _tmp_comp_ptr;
52
#include "rheolef/field.h"
53
#include "rheolef/field_indirect.h"
57
template<class Expr> class field_expr; // forward declaration
59
// =========================================================================
61
// =========================================================================
62
template<class T, class M>
63
class field_component {
68
typedef typename field_basic<T,M>::size_type size_type;
70
typedef typename field_basic<T,M>::iterator iterator;
71
typedef typename field_basic<T,M>::const_iterator const_iterator;
76
field_component (field_basic<T,M>& uh, size_type i_comp);
77
field_component (field_component<T,M>& uh, size_type i_comp);
78
field_component<T,M>& operator= (const field_component<T,M>& uh_comp);
79
field_component<T,M>& operator= (const field_basic<T,M>& uh);
81
field_component<T,M>& operator= (const field_expr<Expr>& expr);
82
const T& operator= (const T& alpha);
84
// high-level accessors & modifiers:
86
field_indirect<T,M> operator[] (const geo_basic<T,M>& dom);
87
field_indirect<T,M> operator[] (const std::string& dom_name);
91
field_component<T,M> operator[] (size_t i_comp);
93
// low-level accessors & modifiers:
95
const space_constitution<T,M>& get_constitution() const { return _constit; }
96
std::string stamp() const { return _constit.stamp(); }
97
geo_basic<T,M> get_geo() const { return _constit.get_geo(); }
98
space_basic<T,M> get_space() const { return space_basic<T,M>(_constit); }
99
const distributor& ownership() const { return _constit.ownership(); }
100
const communicator& comm() const { return ownership().comm(); }
101
size_type ndof() const { return ownership().size(); }
102
size_type dis_ndof() const { return ownership().dis_size(); }
103
T& dof (size_type idof) { return _start [idof]; }
104
const T& dof (size_type idof) const { return _start [idof]; }
105
iterator begin_dof() { return _start; }
106
iterator end_dof() { return _last; }
107
const_iterator begin_dof() const { return const_iterator(_start); }
108
const_iterator end_dof() const { return const_iterator(_last); }
112
space_constitution<T,M> _constit; // at this level
116
// =========================================================================
117
// field_component_const
118
// =========================================================================
119
template<class T, class M>
120
class field_component_const {
125
typedef typename field_basic<T,M>::size_type size_type;
126
typedef T value_type;
127
typedef typename field_basic<T,M>::const_iterator const_iterator;
131
field_component_const ();
132
field_component_const (const field_basic<T,M>& uh, size_type i_comp);
133
field_component_const (const field_component<T,M>& uh_comp);
134
field_component_const<T,M>& operator= (const field_component_const<T,M>& uh_comp);
135
const space_constitution<T,M>& get_constitution() const { return _constit; }
136
std::string stamp() const { return _constit.stamp(); }
137
const distributor& ownership() const { return _constit.ownership(); }
138
const communicator& comm() const { return ownership().comm(); }
139
geo_basic<T,M> get_geo() const { return _constit.get_geo(); }
140
space_basic<T,M> get_space() const { return space_basic<T,M>(_constit); }
141
size_type ndof() const { return ownership().size(); }
142
size_type dis_ndof() const { return ownership().dis_size(); }
143
const T& dof (size_type idof) const { return _start [idof]; }
144
const_iterator begin_dof() const { return const_iterator(_start); }
145
const_iterator end_dof() const { return const_iterator(_last); }
148
space_constitution<T,M> _constit; // at this level
149
const_iterator _start;
150
const_iterator _last;
152
// =========================================================================
154
// =========================================================================
155
template<class T, class M>
157
field_component<T,M>::field_component()
163
template<class T, class M>
165
field_component_const<T,M>::field_component_const()
171
template<class T, class M>
172
field_component<T,M>::field_component (field_basic<T,M>& uh, size_type i_comp)
173
: _constit (uh.get_space().get_constitution() [i_comp]),
174
_start(uh.begin_dof()),
175
_last(uh.begin_dof())
177
check_macro (i_comp < uh.size(),
178
"field component index "<<i_comp<<" is out of range [0:"<<uh.size()<<"[");
179
const space_constitution<T,M>& sup_constit = uh.get_space().get_constitution();
181
for (size_type j_comp = 0; j_comp < i_comp; j_comp++) {
182
shift += sup_constit [j_comp].ndof();
184
size_type sz = sup_constit [i_comp].ndof();
188
template<class T, class M>
189
field_component_const<T,M>::field_component_const (const field_basic<T,M>& uh, size_type i_comp)
190
: _constit (uh.get_space().get_constitution() [i_comp]),
191
_start(uh.begin_dof()),
192
_last(uh.begin_dof())
194
check_macro (i_comp < uh.size(),
195
"field component index "<<i_comp<<" is out of range [0:"<<uh.size()<<"[");
196
const space_constitution<T,M>& sup_constit = uh.get_space().get_constitution();
198
for (size_type j_comp = 0; j_comp < i_comp; j_comp++) {
199
shift += sup_constit [j_comp].ndof();
201
size_type sz = sup_constit [i_comp].ndof();
205
template<class T, class M>
206
field_component<T,M>::field_component (field_component<T,M>& uh, size_type i_comp)
211
const space_constitution<T,M>& sup_constit = uh._constit;
212
check_macro (i_comp < sup_constit.size(),
213
"field component index "<<i_comp<<" is out of range [0:"<<sup_constit.size()<<"[");
215
for (size_type j_comp = 0; j_comp < i_comp; j_comp++) {
216
shift += sup_constit [j_comp].ndof();
218
_constit = sup_constit [i_comp];
219
size_type sz = _constit.ndof();
223
template<class T, class M>
225
field_component_const<T,M>::field_component_const (const field_component<T,M>& uh_comp)
226
: _constit (uh_comp.get_constitution()),
227
_start(uh_comp.begin_dof()),
228
_last(uh_comp.end_dof())
231
template<class T, class M>
233
field_component<T,M>&
234
field_component<T,M>::operator= (const field_component<T,M>& uh_comp)
236
_constit = uh_comp._constit;
237
_start = uh_comp._start;
238
_last = uh_comp._last;
241
template<class T, class M>
243
field_component_const<T,M>&
244
field_component_const<T,M>::operator= (const field_component_const<T,M>& uh_comp)
246
_constit = uh_comp._constit;
247
_start = uh_comp._start;
248
_last = uh_comp._last;
251
template<class T, class M>
254
field_basic<T,M>::operator[] (size_type i_comp)
256
dis_dof_update_needed();
257
return field_component<T,M> (*this, i_comp);
259
template<class T, class M>
262
field_component<T,M>::operator[] (size_t i_comp)
264
return field_component<T,M> (*this, i_comp);
266
template<class T, class M>
268
field_component_const<T,M>
269
field_basic<T,M>::operator[] (size_type i_comp) const
271
return field_component_const<T,M> (*this, i_comp);
273
template<class T, class M>
276
field_basic<T,M>::operator= (const field_component_const<T,M>& uh_comp)
279
resize (uh_comp.get_space());
281
check_macro (stamp() == uh_comp.stamp(), "incompatible spaces "
282
<< stamp() << " and " << uh_comp.stamp()
283
<< " in field = field[i_comp]");
285
dis_dof_update_needed();
286
std::copy (uh_comp.begin_dof(), uh_comp.end_dof(), begin_dof());
289
template<class T, class M>
291
field_component<T,M>&
292
field_component<T,M>::operator= (const field_basic<T,M>& uh)
294
check_macro (stamp() == uh.stamp(), "incompatible spaces "
295
<< stamp() << " and " << uh.stamp()
296
<< " in field[i_comp] = field");
297
std::copy (uh.begin_dof(), uh.end_dof(), begin_dof());
300
template<class T, class M>
303
field_component<T,M>::operator= (const T& alpha)
305
std::fill (begin_dof(), end_dof(), alpha);
308
template<class T, class M>
311
field_basic<T,M>::operator= (const field_component<T,M>& uh_comp)
313
return operator= (field_component_const<T,M>(uh_comp));
315
template<class T, class M>
317
field_basic<T,M>::field_basic (const field_component<T,M>& uh_comp)
321
_dis_dof_update_needed(true)
325
template<class T, class M>
327
field_basic<T,M>::field_basic (const field_component_const<T,M>& uh_comp)
331
_dis_dof_update_needed(true)
336
// TODO: as: field vh; din >> vh ; uh[i_comp] = vh;
337
template <class T, class M>
339
idiststream& operator >> (odiststream& ids, field_basic<T,M>& u);
342
template <class T, class M>
343
odiststream& operator << (odiststream& ods, const field_component<T,M>& uh_comp)
345
return ods << field_basic<T,M>(uh_comp);
347
template <class T, class M>
349
odiststream& operator << (odiststream& ods, const field_component_const<T,M>& uh_comp)
351
return ods << field_basic<T,M>(uh_comp);
353
// =========================================================================
354
// uh[0]["boundary"] = alpha;
355
// => field_component & field_indirect together
356
// =========================================================================
357
template <class T, class M>
359
field_indirect<T,M>::field_indirect (field_component<T,M>& uh_comp, const geo_basic<T,M>& dom)
360
: _V(uh_comp.get_space()),
361
_W(dom, _V.get_numbering().name()),
363
_indirect(_V.build_indirect_array (_W, _dom.name())),
364
_val(uh_comp.begin_dof())
367
template <class T, class M>
370
field_component<T,M>::operator[] (const geo_basic<T,M>& dom)
372
return field_indirect<T,M> (*this, dom);
374
template <class T, class M>
377
field_component<T,M>::operator[] (const std::string& dom_name)
379
return field_indirect<T,M> (*this, get_geo().operator[](dom_name));
382
} // namespace rheolef
383
#endif // _RHEOLEF_FIELD_COMPONENT_H