KADATH
eq_matching_non_std.cpp
1 /*
2  Copyright 2017 Philippe Grandclement
3 
4  This file is part of Kadath.
5 
6  Kadath 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 3 of the License, or
9  (at your option) any later version.
10 
11  Kadath is distributed 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.
15 
16  You should have received a copy of the GNU General Public License
17  along with Kadath. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "system_of_eqs.hpp"
21 #include "ope_eq.hpp"
22 #include "scalar.hpp"
23 #include "tensor_impl.hpp"
24 namespace Kadath {
25 Eq_matching_non_std::Eq_matching_non_std (const Domain* zedom, int dd, int bb, const Array<int>& ozers, int nused, Array<int>** pused) :
26  Equation(zedom, dd, ozers.get_size(1)+1, nused, pused), bound (bb),
27  other_doms(ozers.get_size(1)), other_bounds(ozers.get_size(1)), which_points(0x0) {
28 
29  for (int i=0 ; i<n_ope-1 ; i++) {
30  other_doms.set(i) = ozers(0, i) ;
31  other_bounds.set(i) = ozers(1, i) ;
32  }
33 }
34 
36  if (called) {
37  for (int i=0 ; i<n_cond_tot ; i++)
38  delete which_points[i] ;
39  delete [] which_points ;
40  }
41 }
42 
44 
45  int size = (n_cmp_used == -1) ? tt.get_n_comp() : n_cmp_used ;
46  Array<int> res (size) ;
47  if (n_cmp_used==-1) {
48  for (int i=0 ; i<tt.get_n_comp() ; i++)
49  res.set(i) = dom->nbr_points_boundary (bound, (*tt.cmp[i])(ndom).get_base()) ;
50  }
51  else {
52  for (int i=0 ; i<n_cmp_used ; i++)
53  res.set(i) = dom->nbr_points_boundary (bound, tt(*p_cmp_used[i])(ndom).get_base()) ;
54  }
55  return res ;
56 }
57 
60 }
61 
62 void Eq_matching_non_std::export_val(int& conte, Term_eq** residus, Array<double>& sec, int& pos_res) const {
63  for (int i=0 ; i<n_ope ; i++)
64  assert (residus[i]->get_type_data()==TERM_T) ;
65  assert (residus[conte+1]->get_type_data()==TERM_T) ;
66 
67  Tensor copie (residus[conte]->get_val_t()) ;
68 
69  // Loop on the components :
70  int start = pos_res ;
71  // Case for all the cmps :
72  if (n_cmp_used==-1) {
73  for (int comp=0 ; comp<n_comp ; comp++) {
74  Array<int> ind (copie.indices(comp)) ;
75  copie.set(ind).set_domain(ndom).coef_i() ; //Configuration space
76 
77  for (int j=0 ; j<(*n_cond)(comp) ; j++) {
78  // Value at the colocation point
79  sec.set(pos_res) = (copie(ind)(ndom).check_if_zero()) ? 0. : (*copie(ind)(ndom).c)(*which_points[pos_res-start]) ;
80 
81  // Get the absolute coordinates :
82  Point absol (dom->get_ndim()) ;
83  for (int i=1 ; i<=dom->get_ndim() ; i++)
84  absol.set(i) = (*dom->get_absol(i).c)(*which_points[pos_res-start]) ;
85 
86  bool loop = true ;
87  // Loop on the other domains :
88  int num_other = 0 ;
89  bool indic= false ;
90  while (loop) {
91  const Domain* zedom = residus[conte+num_other+1]->get_val_t().espace.get_domain(other_doms(num_other)) ;
92  int ozerbound = other_bounds(num_other) ;
93  bool found = zedom->is_in(absol, 1e-5) ;
94  if (found) {
95  Point num(zedom->absol_to_num_bound(absol, ozerbound)) ;
96  Val_domain other_copie
97  (residus[conte+num_other+1]->get_val_t()(ind)(other_doms(num_other))) ;
98  if (!other_copie.check_if_zero()) {
99  other_copie.coef() ;
100  sec.set(pos_res) -= other_copie.base.summation(num, *other_copie.cf) ;
101 
102  }
103  loop = false ;
104  indic = true ;
105  }
106  num_other ++ ;
107  if (num_other>=n_ope-1)
108  loop = false ;
109  }
110 
111  if (!indic) {
112  cerr << absol << endl ;
113  cerr << "not found in Eq_matching_non_std::export_val" << endl ;
114  abort() ;
115  }
116 
117  pos_res ++ ;
118  }
119  }
120  }
121  else {
122  for (int comp=0 ; comp<n_cmp_used ; comp++) {
123  copie.set(*p_cmp_used[comp]).set_domain(ndom).coef_i() ; //Configuration space
124 
125  for (int j=0 ; j<(*n_cond)(comp) ; j++) {
126  // Value at the colocation point
127  sec.set(pos_res) = (copie(*p_cmp_used[comp])(ndom).check_if_zero()) ? 0. :
128  (*copie(*p_cmp_used[comp])(ndom).c)(*which_points[pos_res-start]) ;
129 
130  // Get the absolute coordinates :
131  Point absol (dom->get_ndim()) ;
132  for (int i=1 ; i<=dom->get_ndim() ; i++)
133  absol.set(i) = (*dom->get_absol(i).c)(*which_points[pos_res-start]) ;
134 
135  bool loop = true ;
136  // Loop on the other domains :
137  int num_other = 0 ;
138  bool indic = false ;
139  while (loop) {
140  const Domain* zedom = residus[conte+num_other+1]->get_val_t().espace.get_domain(other_doms(num_other)) ;
141  int ozerbound = other_bounds(num_other) ;
142  bool found = zedom->is_in(absol, 1e-5) ;
143  if (found) {
144  Point num(zedom->absol_to_num_bound(absol, ozerbound)) ;
145  Val_domain other_copie
146  (residus[conte+num_other+1]->get_val_t()(*p_cmp_used[comp])(other_doms(num_other))) ;
147  if (!other_copie.check_if_zero()) {
148  other_copie.coef() ;
149  sec.set(pos_res) -= other_copie.base.summation(num, *other_copie.cf) ;
150  }
151  loop = false ;
152  indic= true ;
153  }
154  num_other ++ ;
155  if (num_other>=n_ope-1)
156  loop = false ;
157  }
158  if (!indic) {
159  cerr << absol << endl ;
160  cerr << "not found in Eq_matching_non_std::export_val" << endl ;
161  abort() ;
162  }
163 
164  pos_res ++ ;
165  }
166  }
167  }
168  conte +=n_ope ;
169 }
170 
171 void Eq_matching_non_std::export_der(int& conte, Term_eq** residus, Array<double>& sec, int& pos_res) const {
172 
173  for (int i=0 ; i<n_ope ; i++)
174  assert (residus[i]->get_type_data()==TERM_T) ;
175  assert (residus[conte+1]->get_type_data()==TERM_T) ;
176 
177  Tensor copie (residus[conte]->get_der_t()) ;
178 
179  // Loop on the components :
180  int start = pos_res ;
181  // Case for all the cmps :
182  if (n_cmp_used==-1) {
183  for (int comp=0 ; comp<n_comp ; comp++) {
184  Array<int> ind (copie.indices(comp)) ;
185  copie.set(ind).set_domain(ndom).coef_i() ; //Configuration space
186 
187  for (int j=0 ; j<(*n_cond)(comp) ; j++) {
188  // Value at the colocation point
189  sec.set(pos_res) = (copie(ind)(ndom).check_if_zero()) ? 0. : (*copie(ind)(ndom).c)(*which_points[pos_res-start]) ;
190 
191  // Get the absolute coordinates :
192  Point absol (dom->get_ndim()) ;
193  for (int i=1 ; i<=dom->get_ndim() ; i++)
194  absol.set(i) = (*dom->get_absol(i).c)(*which_points[pos_res-start]) ;
195 
196  bool loop = true ;
197  // Loop on the other domains :
198  int num_other = 0 ;
199  bool indic = false ;
200  while (loop) {
201  const Domain* zedom = residus[conte+num_other+1]->get_der_t().espace.get_domain(other_doms(num_other)) ;
202  int ozerbound = other_bounds(num_other) ;
203  bool found = zedom->is_in(absol, 1e-3) ;
204  if (found) {
205  Point num(zedom->absol_to_num_bound(absol, ozerbound)) ;
206  Val_domain other_copie
207  (residus[conte+num_other+1]->get_der_t()(ind)(other_doms(num_other))) ;
208  if (!other_copie.check_if_zero()) {
209  other_copie.coef() ;
210  sec.set(pos_res) -= other_copie.base.summation(num, *other_copie.cf) ;
211  }
212  loop = false ;
213  indic = true ;
214  }
215  num_other ++ ;
216  if (num_other>=n_ope-1)
217  loop = false ;
218  }
219  if (!indic) {
220  cerr << absol << endl ;
221  cerr << "not found in Eq_matching_non_std::export_der" << endl ;
222  abort() ;
223  }
224 
225  pos_res ++ ;
226  }
227  }
228  }
229  else {
230  for (int comp=0 ; comp<n_cmp_used ; comp++) {
231  copie.set(*p_cmp_used[comp]).set_domain(ndom).coef_i() ; //Configuration space
232 
233  for (int j=0 ; j<(*n_cond)(comp) ; j++) {
234  // Value at the colocation point
235  sec.set(pos_res) = (copie(*p_cmp_used[comp])(ndom).check_if_zero()) ? 0. :
236  (*copie(*p_cmp_used[comp])(ndom).c)(*which_points[pos_res-start]) ;
237 
238  // Get the absolute coordinates :
239  Point absol (dom->get_ndim()) ;
240  for (int i=1 ; i<=dom->get_ndim() ; i++)
241  absol.set(i) = (*dom->get_absol(i).c)(*which_points[pos_res-start]) ;
242 
243  bool loop = true ;
244  // Loop on the other domains :
245  int num_other = 0 ;
246  bool indic = false ;
247  while (loop) {
248  const Domain* zedom = residus[conte+num_other+1]->get_der_t().espace.get_domain(other_doms(num_other)) ;
249  int ozerbound = other_bounds(num_other) ;
250  bool found = zedom->is_in(absol, 1e-3) ;
251  if (found) {
252  Point num(zedom->absol_to_num_bound(absol, ozerbound)) ;
253  Val_domain other_copie
254  (residus[conte+num_other+1]->get_der_t()(*p_cmp_used[comp])(other_doms(num_other))) ;
255  if (!other_copie.check_if_zero()) {
256  other_copie.coef() ;
257  sec.set(pos_res) -= other_copie.base.summation(num, *other_copie.cf) ;
258  }
259  loop = false ;
260  indic= true ;
261  }
262  num_other ++ ;
263  if (num_other>=n_ope-1)
264  loop = false ;
265  }
266  if (!indic) {
267  cerr << absol << endl ;
268  cerr << "not found in Eq_matching_non_std::export_der" << endl ;
269  abort() ;
270  }
271 
272  pos_res ++ ;
273  }
274  }
275  }
276  conte +=n_ope ;
277 }
278 
279 
280 
281 bool Eq_matching_non_std::take_into_account (int target) const {
282  bool res = (target==ndom) ? true : false ;
283  for (int i=0 ; i<n_ope-1 ; i++)
284  if (target==other_doms(i))
285  res = true ;
286  return res ;
287 }
288 
289 void Eq_matching_non_std::apply(int& conte, Term_eq** res) {
290 
291  int old_conte = conte ;
292  for (int i=0 ; i<n_ope ; i++) {
293  if (res[conte]!=0x0)
294  *res[conte] = parts[i]->action() ;
295  else
296  res[conte] = new Term_eq (parts[i]->action()) ;
297 
298  assert (res[conte]->get_type_data()==TERM_T) ;
299  conte ++ ;
300  }
301 
302  if (!called) {
303  Tensor copie (res[old_conte]->get_val_t()) ;
304  n_cond = new Array<int> (do_nbr_conditions(copie)) ;
305  n_comp = n_cond->get_size(0) ;
306  n_cond_tot = 0 ;
307  if (n_cmp_used==-1)
308  for (int i=0 ; i<n_cond->get_size(0) ; i++)
309  n_cond_tot += (*n_cond)(i) ;
310  else
311  for (int i=0 ; i<n_cmp_used ; i++)
312  n_cond_tot += (*n_cond)(i) ;
313 
314  which_points = new Index* [n_cond_tot] ;
315  int start = 0 ;
316  if (n_cmp_used ==-1)
317  for (int comp=0 ; comp<n_comp ; comp++) {
318  Array<int> ind (copie.indices(comp)) ;
319  Base_spectral bb (copie(ind)(ndom).get_base()) ;
320  do_which_points (bb, start) ;
321  start += (*n_cond)(comp) ;
322  }
323  else
324  for (int comp=0 ; comp<n_cmp_used ; comp++) {
325  Base_spectral bb (copie(*p_cmp_used[comp])(ndom).get_base()) ;
326  do_which_points (bb, start) ;
327  start += (*n_cond)(comp) ;
328  }
329  called = true ;
330  }
331 }}
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
int get_size(int i) const
Returns the size of a given dimension.
Definition: array.hpp:331
Class for storing the basis of decompositions of a field.
double summation(const Point &num, const Array< double > &tab) const
Computes the spectral summation.
Abstract class that implements the fonctionnalities common to all the type of domains.
Definition: space.hpp:60
int get_ndim() const
Returns the number of dimensions.
Definition: space.hpp:96
Val_domain const & get_absol(int i) const
Returns the absolute coordinates.
Definition: space.hpp:1457
virtual int nbr_points_boundary(int bound, const Base_spectral &base) const
Computes the number of relevant collocation points on a boundary.
Definition: domain.cpp:1587
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
Definition: domain.cpp:942
virtual const Point absol_to_num_bound(const Point &xxx, int bound) const
Computes the numerical coordinates from the physical ones for a point lying on a boundary.
Definition: domain.cpp:954
virtual void do_which_points_boundary(int bound, const Base_spectral &base, Index **ind, int start) const
Lists all the indices corresponding to true collocation points on a boundary.
Definition: domain.cpp:1593
void export_val(int &, Term_eq **, Array< double > &, int &) const override
Generates the discretized errors, from the various Term_eq computed by the equation.
Array< int > do_nbr_conditions(const Tensor &tt) const override
Computes the number of conditions associated with the equation.
virtual ~Eq_matching_non_std()
Destructor.
Array< int > other_bounds
Names of the boundary, as seen in the other domains.
void do_which_points(const Base_spectral &base, int start)
Computes the collocation points used.
Array< int > other_doms
Array containing the number of the domains being on the other side of the surface.
int bound
Name of the boundary in the domain of the equation.
Eq_matching_non_std(const Domain *dom, int nd, int bb, const Array< int > &ozers, int n_cmp=-1, Array< int > **p_cmp=nullptr)
Constructor.
void apply(int &, Term_eq **) override
Computes the terms involved in computing the residual of the equations.
void export_der(int &, Term_eq **, Array< double > &, int &) const override
Generates the discretized variations, from the various Term_eq computed by the equation.
bool take_into_account(int) const override
Check whether the variation of the residual has to be taken into account when computing a given colum...
Index ** which_points
Lists the collocation points on the boundary (probably...)
Class implementing an equation.
bool called
Indicator checking whther the result has been computed already once.
const Domain * dom
Pointer on the Domain where the equation is defined.
Array< int > ** p_cmp_used
Array of pointer on the indices of the used components.
int ndom
Number of the domain.
int n_cmp_used
Number of components used (by default the same thing as n_comp).
int n_ope
Number of terms involved in the equation (one for bulk, two or more fot matching.....
int n_comp
Number of components of the residual (1 for a scalar, 6 for a symmetric rank-2 tensor etc).
Array< int > * n_cond
Number of discretized equations, component by component.
MMPtr_array< Ope_eq > parts
Array of pointers on the various terms.
int n_cond_tot
Total number of discretized equations (essentially the number of all coefficients of the residual).
Class that gives the position inside a multi-dimensional Array.
Definition: index.hpp:38
The class Point is used to store the coordinates of a point.
Definition: point.hpp:30
double & set(int i)
Read/write of a coordinate.
Definition: point.hpp:47
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
const Domain * get_domain(int i) const
returns a pointer on the domain.
Definition: space.hpp:1385
Tensor handling.
Definition: tensor.hpp:149
Memory_mapped_array< Scalar * > cmp
Array of size n_comp of pointers onto the components.
Definition: tensor.hpp:179
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
int get_n_comp() const
Returns the number of stored components.
Definition: tensor.hpp:514
virtual Array< int > indices(int pos) const
Gives the values of the indices corresponding to a location in the array used for storage of the comp...
Definition: tensor.hpp:484
const Space & espace
The Space.
Definition: tensor.hpp:154
This class is intended to describe the manage objects appearing in the equations.
Definition: term_eq.hpp:62
Tensor const & get_val_t() const
Definition: term_eq.hpp:355
Tensor const & get_der_t() const
Definition: term_eq.hpp:369
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
Base_spectral base
Spectral basis of the field.
Definition: val_domain.hpp:72
bool check_if_zero() const
Check whether the logical state is zero or not.
Definition: val_domain.hpp:142
Array< double > * cf
Pointer on the Array of the values in the coefficients space.
Definition: val_domain.hpp:77
void coef_i() const
Computes the values in the configuration space.
Definition: val_domain.cpp:637
void coef() const
Computes the coefficients.
Definition: val_domain.cpp:622
Array< double > * c
Pointer on the Array of the values in the configuration space.
Definition: val_domain.hpp:76