2
/// This file is part of Rheolef.
4
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
6
/// Rheolef is free software; you can redistribute it and/or modify
7
/// it under the terms of the GNU General Public License as published by
8
/// the Free Software Foundation; either version 2 of the License, or
9
/// (at your option) any later version.
11
/// Rheolef is sequential in the hope that it will be useful,
12
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
/// GNU General Public License for more details.
16
/// You should have received a copy of the GNU General Public License
17
/// along with Rheolef; if not, write to the Free Software
18
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
/// =========================================================================
21
#include "rheolef/geo.h"
22
#include "rheolef/geo_domain.h"
23
#include "rheolef/rheostream.h"
24
#include "rheolef/iorheo.h"
26
#include "geo_header.h"
30
// =========================================================================
31
// geo_base_rep members
32
// =========================================================================
33
template <class T, class M>
34
geo_base_rep<T,M>::~geo_base_rep()
37
trace_macro ("dstor geo_base_rep: name="<<name()<<", dim="<<dimension()<<", map_dim="<<map_dimension()<<" size="<<size());
40
template <class T, class M>
42
geo_base_rep<T,M>::name() const
44
if (_serial_number == 0) return _name;
45
return _name + "-" + itos(_serial_number);
47
template <class T, class M>
49
geo_base_rep<T,M>::have_domain_indirect (const std::string& name) const
51
for (typename std::vector<domain_indirect_basic<M> >::const_iterator
52
iter = _domains.begin(), last = _domains.end(); iter != last; iter++) {
53
const domain_indirect_basic<M>& dom = *iter;
54
if (name == dom.name()) return true;
58
template <class T, class M>
59
const domain_indirect_basic<M>&
60
geo_base_rep<T,M>::get_domain_indirect (const std::string& name) const
62
for (typename std::vector<domain_indirect_basic<M> >::const_iterator
63
iter = _domains.begin(), last = _domains.end(); iter != last; iter++) {
64
const domain_indirect_basic<M>& dom = *iter;
65
if (name == dom.name()) return dom;
67
error_macro ("undefined domain \""<<name<<"\" in mesh \"" << _name << "\"");
68
return *(_domains.begin()); // not reached
70
template <class T, class M>
72
geo_base_rep<T,M>::insert_domain_indirect (const domain_indirect_basic<M>& dom) const
74
for (typename std::vector<domain_indirect_basic<M> >::iterator
75
iter = _domains.begin(), last = _domains.end(); iter != last; iter++) {
76
domain_indirect_basic<M>& curr_dom = *iter;
77
if (dom.name() == curr_dom.name()) {
78
// a domain with the same name already exists: replace it
83
// insert a new domain:
84
_domains.push_back (dom);
86
template <class T, class M>
87
typename geo_base_rep<T,M>::size_type
88
geo_base_rep<T,M>::size (size_type dim) const
91
for (size_type variant = reference_element::first_variant_by_dimension(dim);
92
variant < reference_element:: last_variant_by_dimension(dim); variant++) {
93
sz += _geo_element [variant].size();
97
template <class T, class M>
98
typename geo_base_rep<T,M>::size_type
99
geo_base_rep<T,M>::dis_size (size_type dim) const
102
for (size_type variant = reference_element::first_variant_by_dimension(dim);
103
variant < reference_element:: last_variant_by_dimension(dim); variant++) {
104
sz += _geo_element [variant].dis_size();
108
template <class T, class M>
110
geo_base_rep<T,M>::compute_bbox()
112
// first, compute bbox sequentialy:
113
for (size_type j = 0; j < _dimension; j++) {
114
_xmin[j] = std::numeric_limits<T>::max();
115
_xmax[j] = -std::numeric_limits<T>::max();
117
for (size_type j = _dimension+1; j < 3; j++) {
118
_xmin [j] = _xmax [j] = 0;
120
for (size_type inod = 0, nnod = _node.size(); inod < nnod; inod++) {
121
const point_basic<T>& x = _node [inod];
122
for (size_type j = 0 ; j < _dimension; j++) {
123
_xmin[j] = min(x[j], _xmin[j]);
124
_xmax[j] = max(x[j], _xmax[j]);
127
// distributed case: min & max are grouped accross procs
128
#ifdef _RHEOLEF_HAVE_MPI
129
if (is_distributed<M>::value) {
130
for (size_type j = 0 ; j < _dimension; j++) {
131
_xmin[j] = mpi::all_reduce (comm(), _xmin[j], mpi::minimum<T>());
132
_xmax[j] = mpi::all_reduce (comm(), _xmax[j], mpi::maximum<T>());
135
#endif // _RHEOLEF_HAVE_MPI
137
template <class T, class M>
138
typename geo_base_rep<T,M>::const_reference
139
geo_base_rep<T,M>::get_geo_element (size_type dim, size_type ige) const
141
size_type first_ige = 0, last_ige = 0;
142
for (size_type variant = reference_element::first_variant_by_dimension(dim);
143
variant < reference_element:: last_variant_by_dimension(dim); variant++) {
144
last_ige += _geo_element [variant].size();
145
if (ige < last_ige) return _geo_element [variant] [ige - first_ige];
146
first_ige = last_ige;
148
error_macro ("geo_element index " << ige << " out of range [0:"<< last_ige << "[");
149
return _geo_element [0][0]; // not reached
151
template <class T, class M>
152
typename geo_base_rep<T,M>::reference
153
geo_base_rep<T,M>::get_geo_element (size_type dim, size_type ige)
155
size_type first_ige = 0, last_ige = 0;
156
for (size_type variant = reference_element::first_variant_by_dimension(dim);
157
variant < reference_element:: last_variant_by_dimension(dim); variant++) {
158
last_ige += _geo_element [variant].size();
159
if (ige < last_ige) return _geo_element [variant] [ige - first_ige];
160
first_ige = last_ige;
162
error_macro ("geo_element index " << ige << " out of range [0:"<< last_ige << "[");
163
return _geo_element [0][0]; // not reached
165
template <class T, class M>
166
typename geo_base_rep<T,M>::node_type
167
geo_base_rep<T,M>::piola (const geo_element& K, const node_type& hat_x) const
169
// TODO: use basis_on_lattice [K.variant] instead of values[]
170
std::vector<T> values;
171
reference_element hat_K (K.variant());
172
_numbering.get_basis().eval (hat_K, hat_x, values);
174
std::vector<size_type> dis_inod;
175
_numbering.dis_idof (_gs, K, dis_inod);
177
for (size_type loc_inod = 0, loc_nnod = values.size(); loc_inod < loc_nnod; loc_inod++) {
178
const node_type& xnod = dis_node(dis_inod[loc_inod]);
179
const T& coeff = values[loc_inod];
180
for (size_type i = 0, d = dimension(); i < d; i++) {
181
x[i] += coeff*xnod[i];
186
// ----------------------------------------------------------------------------
187
// set order & resize node array ; internal node are not computed
188
// since they depend on the curved boundary information (cad data)
189
// that is not aivailable here
190
// ----------------------------------------------------------------------------
191
#define _RHEOLEF_reset_order(M) \
194
geo_rep<T,M>::reset_order (size_type new_order) \
196
if (new_order == base::_numbering.degree()) return; \
197
base::_numbering.set_degree (new_order); \
198
size_type dis_nnod = base::_numbering.dis_ndof (base::_gs, base::_map_dimension); \
199
size_type nnod = base::_numbering.ndof (base::_gs, base::_map_dimension); \
200
base::_gs.node_ownership = distributor (nnod, base::comm(), nnod); \
201
array<point_basic<T>, M> new_node (base::_gs.node_ownership); \
202
for (size_type iv = 0, nv = base::_gs.ownership_by_dimension[0].size(); iv < nv; iv++) { \
203
new_node [iv] = base::_node [iv]; \
205
base::_node = new_node; \
206
build_external_entities (); \
208
_RHEOLEF_reset_order(sequential)
209
#ifdef _RHEOLEF_HAVE_MPI
210
_RHEOLEF_reset_order(distributed)
211
#endif // _RHEOLEF_HAVE_MPI
212
#undef _RHEOLEF_reset_order
213
// ----------------------------------------------------------------------------
214
// instanciation in library
215
// ----------------------------------------------------------------------------
216
template class geo_base_rep<Float,sequential>;
217
template class geo_rep<Float,sequential>;
218
#ifdef _RHEOLEF_HAVE_MPI
219
template class geo_base_rep<Float,distributed>;
220
template class geo_rep<Float,distributed>;
221
#endif // _RHEOLEF_HAVE_MPI
223
template geo_basic<Float,sequential> compact (const geo_basic<Float,sequential>&);
225
} // namespace rheolef