KADATH
space_bbh.cpp
1 /*
2  Copyright 2020 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 "headcpp.hpp"
21 #include "bbh.hpp"
22 #include "utilities.hpp"
23 #include "point.hpp"
24 #include "scalar.hpp"
25 #include "system_of_eqs.hpp"
26 #include "name_tools.hpp"
27 namespace Kadath {
28 double eta_lim_chi (double chi, double rext, double a, double eta_c) ;
29 double chi_lim_eta (double chi, double rext, double a, double chi_c) ;
30 
31 double zerosec(double (*f)(double, const Param&), const Param& parf,
32  double x1, double x2, double precis, int nitermax, int& niter) ;
33 
34 
35 double func_ab (double aa, const Param& par) {
36  double r1 = par.get_double(0) ;
37  double r2 = par.get_double(1) ;
38  double d = par.get_double(2) ;
39  return (sqrt(aa*aa+r1*r1)+sqrt(aa*aa+r2*r2)-d) ;
40 }
41 
42 Space_bbh::Space_bbh (int ttype, double dist, double rbh1, double rbh2, double rbi, double rext, int nr) {
43 
44  ndim = 3 ;
45 
46  nbr_domains = 10 ;
47  type_base = ttype ;
48  domains = new Domain* [nbr_domains] ;
49 
50  Dim_array res (ndim) ;
51  res.set(0) = nr ; res.set(1) = nr ; res.set(2) = nr-1 ;
52  Dim_array res_bi(ndim) ;
53  res_bi.set(0) = nr ; res_bi.set(1) = nr ; res_bi.set(2) = nr ;
54 
55  // Bispheric :
56  // Computation of aa
57  Param par_a ;
58  par_a.add_double(2*rbh1,0) ;
59  par_a.add_double(2*rbh2,1) ;
60  par_a.add_double(dist,2) ;
61  double a_min = 0 ;
62  double a_max = dist/2. ;
63  double precis = PRECISION ;
64  int nitermax = 500 ;
65  int niter ;
66  double aa = zerosec(func_ab, par_a, a_min, a_max, precis, nitermax, niter) ;
67  double eta_plus = asinh(aa/2/rbh2) ;
68  double eta_minus = -asinh(aa/2/rbh1) ;
69 
70  double chi_c = 2*atan(aa/rbi) ;
71  double eta_c = log((1+rbi/aa)/(rbi/aa-1)) ;
72  double eta_lim = eta_c/2. ;
73  double chi_lim = chi_lim_eta (eta_lim, rbi, aa, chi_c) ;
74 
75  // First BH
76  Point center_minus (ndim) ;
77  center_minus.set(1) = aa*cosh(eta_minus)/sinh(eta_minus) ;
78  domains[0] = new Domain_shell_outer_adapted (*this, 0, ttype, rbh1/2., rbh1, center_minus, res) ;
79  domains[1] = new Domain_shell_inner_adapted (*this, 1, ttype, rbh1, rbh1*2., center_minus, res) ;
80 
81  // Second bh
82  Point center_plus (ndim) ;
83  center_plus.set(1) = aa*cosh(eta_plus)/sinh(eta_plus) ;
84  domains[2] = new Domain_shell_outer_adapted (*this, 2, ttype, rbh2/2., rbh2, center_plus, res) ;
85  domains[3] = new Domain_shell_inner_adapted (*this, 3, ttype, rbh2, rbh2*2., center_plus, res) ;
86 
87  // Bispheric part
88  domains[4] = new Domain_bispheric_chi_first(4, ttype, aa, eta_minus, rbi, chi_lim, res_bi) ;
89  domains[5] = new Domain_bispheric_rect(5, ttype, aa, rbi, eta_minus, -eta_lim, chi_lim, res_bi) ;
90  domains[6] = new Domain_bispheric_eta_first(6, ttype, aa, rbi, -eta_lim, eta_lim, res_bi) ;
91  domains[7] = new Domain_bispheric_rect(7, ttype, aa, rbi, eta_plus, eta_lim, chi_lim, res_bi) ;
92  domains[8] = new Domain_bispheric_chi_first(8, ttype, aa, eta_plus, rbi, chi_lim, res_bi) ;
93 
94  // Compactified domain
95  Point center(3) ;
96  domains[9] = new Domain_shell (9, ttype, rbi, rext, center, res) ;
97 
98  const Domain_shell_outer_adapted* pouter_1 = dynamic_cast<const Domain_shell_outer_adapted*> (domains[0]) ;
99  pouter_1->vars_to_terms() ;
100  pouter_1->update() ;
101  const Domain_shell_inner_adapted* pinner_1 = dynamic_cast<const Domain_shell_inner_adapted*> (domains[1]) ;
102  pinner_1->vars_to_terms() ;
103  pinner_1->update() ;
104  const Domain_shell_outer_adapted* pouter_2 = dynamic_cast<const Domain_shell_outer_adapted*> (domains[2]) ;
105  pouter_2->vars_to_terms() ;
106  pouter_2->update() ;
107  const Domain_shell_inner_adapted* pinner_2 = dynamic_cast<const Domain_shell_inner_adapted*> (domains[3]) ;
108  pinner_2->vars_to_terms() ;
109  pinner_2->update() ;
110 }
111 
112 
114  fread_be (&nbr_domains, sizeof(int), 1, fd) ;
115  fread_be (&ndim, sizeof(int), 1, fd) ;
116  fread_be (&type_base, sizeof(int), 1, fd) ;
117  domains = new Domain* [nbr_domains] ;
118  //First BH :
119  domains[0] = new Domain_shell_outer_adapted (*this, 0, fd) ;
120  domains[1] = new Domain_shell_inner_adapted (*this, 1, fd) ;
121 
122  //second BH :
123  domains[2] = new Domain_shell_outer_adapted (*this, 2, fd) ;
124  domains[3] = new Domain_shell_inner_adapted (*this, 3, fd) ;
125 
126  // Bispheric
127  domains[4] = new Domain_bispheric_chi_first(4, fd) ;
128  domains[5] = new Domain_bispheric_rect(5, fd) ;
129  domains[6] = new Domain_bispheric_eta_first(6, fd) ;
130  domains[7] = new Domain_bispheric_rect(7, fd) ;
131  domains[8] = new Domain_bispheric_chi_first(8, fd) ;
132 
133  // Compactified
134  domains[9] = new Domain_shell(9, fd) ;
135 
136  const Domain_shell_outer_adapted* pouter_1 = dynamic_cast<const Domain_shell_outer_adapted*> (domains[0]) ;
137  pouter_1->vars_to_terms() ;
138  pouter_1->update() ;
139  const Domain_shell_inner_adapted* pinner_1 = dynamic_cast<const Domain_shell_inner_adapted*> (domains[1]) ;
140  pinner_1->vars_to_terms() ;
141  pinner_1->update() ;
142  const Domain_shell_outer_adapted* pouter_2 = dynamic_cast<const Domain_shell_outer_adapted*> (domains[2]) ;
143  pouter_2->vars_to_terms() ;
144  pouter_2->update() ;
145  const Domain_shell_inner_adapted* pinner_2 = dynamic_cast<const Domain_shell_inner_adapted*> (domains[3]) ;
146  pinner_2->vars_to_terms() ;
147  pinner_2->update() ;
148 }
149 
151  Domain_shell_outer_adapted* pouter_1 = dynamic_cast<Domain_shell_outer_adapted*> (domains[0]) ;
152  pouter_1->del_deriv() ;
153  Domain_shell_inner_adapted* pinner_1 = dynamic_cast<Domain_shell_inner_adapted*> (domains[1]) ;
154  pinner_1->del_deriv() ;
155  Domain_shell_outer_adapted* pouter_2 = dynamic_cast<Domain_shell_outer_adapted*> (domains[2]) ;
156  pouter_2->del_deriv() ;
157  Domain_shell_inner_adapted* pinner_2 = dynamic_cast<Domain_shell_inner_adapted*> (domains[3]) ;
158  pinner_2->del_deriv() ;
159 }
160 
161 void Space_bbh::save (FILE* fd) const {
162  fwrite_be (&nbr_domains, sizeof(int), 1, fd) ;
163  fwrite_be (&ndim, sizeof(int), 1, fd) ;
164  fwrite_be (&type_base, sizeof(int), 1, fd) ;
165  for (int i=0 ; i<nbr_domains ; i++)
166  domains[i]->save(fd) ;
167 }
168 
170 
171  return (domains[1]->nbr_unknowns_from_adapted() + domains[3]->nbr_unknowns_from_adapted()) ;
172 }
173 
174 void Space_bbh::affecte_coef_to_variable_domains (int& pos, int cc, Array<int>& zedoms) const {
175 
176  // In BH 1 ?
177  bool found_outer_1 = false ;
178  int old_pos = pos ;
179  domains[0]->affecte_coef(pos, cc, found_outer_1) ;
180  pos = old_pos ;
181  bool found_inner_1 = false ;
182  domains[1]->affecte_coef(pos, cc, found_inner_1) ;
183  assert (found_outer_1 == found_inner_1) ;
184  if (found_outer_1) {
185  zedoms.set(0) = 0 ;
186  zedoms.set(1) = 1 ;
187  }
188  else {
189  zedoms.set(0) = -1 ;
190  zedoms.set(1) = -1 ;
191  }
192 
193  // In BH 2 ?
194  bool found_outer_2 = false ;
195  old_pos = pos ;
196  domains[2]->affecte_coef(pos, cc, found_outer_2) ;
197  pos = old_pos ;
198  bool found_inner_2 = false ;
199  domains[3]->affecte_coef(pos, cc, found_inner_2) ;
200  assert (found_outer_2 == found_inner_2) ;
201  if (found_outer_2) {
202  zedoms.set(0) = 2 ;
203  zedoms.set(1) = 3 ;
204  }
205 }
206 
207 void Space_bbh::xx_to_ders_variable_domains (const Array<double>& xx, int& conte) const {
208  // BH 1
209  int old_conte = conte ;
210  domains[0]->xx_to_ders_from_adapted(xx, conte) ;
211  conte = old_conte ;
212  domains[1]->xx_to_ders_from_adapted(xx, conte) ;
213  // bh2 2
214  old_conte = conte ;
215  domains[2]->xx_to_ders_from_adapted(xx, conte) ;
216  conte = old_conte ;
217  domains[3]->xx_to_ders_from_adapted(xx, conte) ;
218 }
219 
221 
222  // First get the corrections :
223  // BH 1
224  int old_pos = pos ;
225  Val_domain cor_outer_1 (domains[0]) ;
226  domains[0]->xx_to_vars_from_adapted(cor_outer_1, xx, pos) ;
227  pos = old_pos ;
228  Val_domain cor_inner_1 (domains[1]) ;
229  domains[1]->xx_to_vars_from_adapted(cor_inner_1, xx, pos) ;
230 
231  // BH 2
232  old_pos = pos ;
233  Val_domain cor_outer_2 (domains[2]) ;
234  domains[2]->xx_to_vars_from_adapted(cor_outer_2, xx, pos) ;
235  pos = old_pos ;
236  Val_domain cor_inner_2 (domains[3]) ;
237  domains[3]->xx_to_vars_from_adapted(cor_inner_2, xx, pos) ;
238 
239  // Now update the variables :
240  for (int i=0 ; i<sys->nvar ; i++) {
241  for (int n=0 ; n<sys->var[i]->get_n_comp() ; n++) {
242  Scalar res(*this) ;
243  domains[0]->update_variable(cor_outer_1, *sys->var[i]->cmp[n], res) ;
244  domains[1]->update_variable(cor_inner_1, *sys->var[i]->cmp[n], res) ;
245  domains[2]->update_variable(cor_outer_2, *sys->var[i]->cmp[n], res) ;
246  domains[3]->update_variable(cor_inner_2, *sys->var[i]->cmp[n], res) ;
247 
248 
249  sys->var[i]->cmp[n]->set_domain(0) = res(0) ;
250  sys->var[i]->cmp[n]->set_domain(1) = res(1) ;
251  sys->var[i]->cmp[n]->set_domain(2) = res(2) ;
252  sys->var[i]->cmp[n]->set_domain(3) = res(3) ;
253  }
254  }
255 
256  // Now the constants :
257  for (int i=0 ; i<sys->ncst ; i++)
258  if (sys->cst[i*(sys->dom_max-sys->dom_min+1)]->get_type_data()==TERM_T)
259  for (int n=0 ; n<sys->cst[i*(sys->dom_max-sys->dom_min+1)]->val_t->get_n_comp() ; n++) {
260 
261  Scalar so (*this) ;
262  so = 0 ;
263  for (int d=0 ; d<=3 ; d++)
264  so.set_domain(d) = (*sys->cst[i*(sys->dom_max-sys->dom_min+1)+d]->val_t->cmp[n])(d) ;
265 
266  Scalar res(*this) ;
267  res = 0 ;
268  domains[0]->update_constante(cor_outer_1, so, res) ;
269  domains[1]->update_constante(cor_inner_1, so, res) ;
270  domains[2]->update_constante(cor_outer_2, so, res) ;
271  domains[3]->update_constante(cor_inner_2, so, res) ;
272 
273  sys->cst[i*(sys->dom_max-sys->dom_min+1)]->val_t->cmp[n]->set_domain(0) = res(0) ;
274  sys->cst[i*(sys->dom_max-sys->dom_min+1)+1]->val_t->cmp[n]->set_domain(1) = res(1) ;
275  sys->cst[i*(sys->dom_max-sys->dom_min+1)+2]->val_t->cmp[n]->set_domain(2) = res(2) ;
276  sys->cst[i*(sys->dom_max-sys->dom_min+1)+3]->val_t->cmp[n]->set_domain(3) = res(3) ;
277  }
278 
279  // Update the mapping :
280  domains[0]->update_mapping(cor_outer_1) ;
281  domains[1]->update_mapping(cor_inner_1) ;
282  domains[2]->update_mapping(cor_outer_2) ;
283  domains[3]->update_mapping(cor_inner_2) ;
284 
285 }
286 
287 
289 
290  if (dom==1) {
291  // First BH ;
292  Array<int> res (2,2) ;
293  switch (bound) {
294  case OUTER_BC :
295  res.set(0,0) = 4 ; // Matching with chi first
296  res.set(1,0) = INNER_BC ;
297  res.set(0,1) = 5 ; // Matching with rect
298  res.set(1,1) = INNER_BC ;
299  break ;
300  default :
301  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
302  abort() ;
303  }
304  return res ;
305  }
306 
307  if (dom==3) {
308  // second bh ;
309  Array<int> res(2, 2) ;
310  switch (bound) {
311  case OUTER_BC :
312  res.set(0,0) = 7 ; // Matching with rect
313  res.set(1,0) = INNER_BC ;
314  res.set(0,1) = 8 ; // Matching with chi_first
315  res.set(1,1) = INNER_BC ;
316  break ;
317  default :
318  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
319  abort() ;
320  }
321  return res ;
322  }
323 
324  if (dom== 4) {
325  // first chi first :
326  Array<int> res(2,1) ;
327  switch (bound) {
328  case INNER_BC :
329  res.set(0,0) = 1 ; // First bh
330  res.set(1,0) = OUTER_BC ;
331  break ;
332  case OUTER_BC :
333  res.set(0,0) = 9 ; // Shell
334  res.set(1,0) = INNER_BC ;
335  break ;
336  default :
337  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
338  abort() ;
339  }
340  return res ;
341  }
342 
343  if (dom==5) {
344  // first rect :
345  Array<int> res(2, 1) ;
346  switch (bound) {
347  case INNER_BC :
348  res.set(0,0) = 1 ; // First bh
349  res.set(1,0) = OUTER_BC ;
350  break ;
351  case OUTER_BC :
352  res.set(0,0) = 9 ; // Shell
353  res.set(1,0) = INNER_BC ;
354  break ;
355  default :
356  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
357  abort() ;
358  }
359  return res ;
360  }
361 
362 
363  if (dom==6) {
364  // eta first
365  Array<int> res(2, 1) ;
366  switch (bound) {
367  case OUTER_BC :
368  res.set(0, 0) = 9 ; // Shell
369  res.set(1, 0) = INNER_BC ;
370  break ;
371  default :
372  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
373  abort() ;
374  }
375  return res ;
376  }
377 
378  if (dom==7) {
379  // second rect :
380  Array<int> res(2, 1) ;
381  switch (bound) {
382  case INNER_BC :
383  res.set(0, 0) = 3 ; // Second bh
384  res.set(1, 0) = OUTER_BC ;
385  break ;
386  case OUTER_BC :
387  res.set(0, 0) = 9 ; // Shell
388  res.set(1, 0) = INNER_BC ;
389  break ;
390  default :
391  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
392  abort() ;
393  }
394  return res ;
395  }
396 
397  if (dom==8) {
398  // second chi first :
399  Array<int> res(2, 1) ;
400  switch (bound) {
401  case INNER_BC :
402  res.set(0,0) = 3 ; // second nucleus
403  res.set(1,0) = OUTER_BC ;
404  break ;
405  case OUTER_BC :
406  res.set(0,0) = 9 ; // Shell
407  res.set(1,0) = INNER_BC ;
408  break ;
409  default :
410  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
411  abort() ;
412  }
413  return res ;
414  }
415 
416  if (dom==9) {
417  // Shell :
418  Array<int> res(2,5) ;
419  switch (bound) {
420  case INNER_BC :
421  res.set(0,0) = 4 ; // first chi first
422  res.set(0,1) = 5 ; // first rect
423  res.set(0,2) = 6 ; // eta first
424  res.set(0,3) = 7 ; // second rect
425  res.set(0,4) = 8 ; // second chi first
426  // Outer BC for all :
427  for (int i=0 ; i<5 ; i++)
428  res.set(1,i) = OUTER_BC ;
429  break ;
430  default :
431  cerr << "Bad bound in Space_bbh::get_indices_matching_non_std" << endl ;
432  abort() ;
433  }
434  return res ;
435  }
436 
437  cerr << "Bad domain in Space_bbh::get_indices_matching_non_std" << endl ;
438  abort() ;
439 }
440 
441 }
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
Class for storing the dimensions of an array.
Definition: dim_array.hpp:34
int & set(int i)
Read/write of the size of a given dimension.
Definition: dim_array.hpp:54
Class for bispherical coordinates with a symmetry with respect to the plane .
Definition: bispheric.hpp:460
Class for bispherical coordinates with a symmetry with respect to the plane .
Definition: bispheric.hpp:878
Class for bispherical coordinates with a symmetry with respect to the plane .
Definition: bispheric.hpp:64
Class for a spherical-like domain, having a symmetry with respect to the plane .
Definition: adapted.hpp:51
void update() const
Updates all the quantities that depend on the inner radius (like the normal vectors).
void del_deriv() override
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
virtual void vars_to_terms() const
The Term_eq describing the variable shape of the Domain are updated.
Class for a spherical-like domain, having a symmetry with respect to the plane .
Definition: adapted.hpp:367
void update() const
Updates all the quantities that depend on the inner radius (like the normal vectors).
void del_deriv() override
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
virtual void vars_to_terms() const
The Term_eq describing the variable shape of the Domain are updated.
Class for a spherical shell and a symmetry with respect to the plane .
Definition: spheric.hpp:555
Abstract class that implements the fonctionnalities common to all the type of domains.
Definition: space.hpp:60
virtual void xx_to_ders_from_adapted(const Array< double > &xx, int &conte) const
Affects the derivative part of variable a Domain from a set of values.
Definition: space.hpp:928
virtual void affecte_coef(int &conte, int cc, bool &found) const
The variation of the functions describing the shape of the Domain are affected from the unknowns of t...
Definition: space.hpp:906
virtual void update_variable(const Val_domain &shape, const Scalar &oldval, Scalar &newval) const
Update the value of a scalar, after the shape of the Domain has been changed by the system.
Definition: space.hpp:942
virtual void xx_to_vars_from_adapted(Val_domain &shape, const Array< double > &xx, int &conte) const
Computes the new boundary of a Domain from a set of values.
Definition: space.hpp:913
virtual void update_mapping(const Val_domain &shape)
Updates the variables parts of the Domain.
Definition: space.hpp:977
virtual void update_constante(const Val_domain &shape, const Scalar &oldval, Scalar &newval) const
Update the value of a scalar, after the shape of the Domain has been changed by the system.
Definition: space.hpp:961
Parameter storage.
Definition: param.hpp:30
void add_double(double x, int position=0)
Adds the the address of a new double to the list.
Definition: param.cpp:115
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
The class Scalar does not really implements scalars in the mathematical sense but rather tensorial co...
Definition: scalar.hpp:67
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
virtual void affecte_coef_to_variable_domains(int &, int, Array< int > &) const
The variation of the functions describing the shape of the Domain are affected from the unknowns of t...
Definition: space_bbh.cpp:174
Space_bbh(int ttype, double dist, double rbh1, double rbh2, double rbi, double rext, int nr)
Standard constructor
Definition: space_bbh.cpp:42
virtual ~Space_bbh()
Destructor.
Definition: space_bbh.cpp:150
virtual void xx_to_vars_variable_domains(System_of_eqs *, const Array< double > &, int &) const
Update the variables of a system, from the variation of the shape of the domains.
Definition: space_bbh.cpp:220
virtual Array< int > get_indices_matching_non_std(int dom, int bound) const
Gives the number of the other domains, touching a given boundary.
Definition: space_bbh.cpp:288
virtual int nbr_unknowns_from_variable_domains() const
Gives the number of unknowns coming from the variable shape of the domain.
Definition: space_bbh.cpp:169
virtual void save(FILE *) const
Saving function.
Definition: space_bbh.cpp:161
virtual void xx_to_ders_variable_domains(const Array< double > &, int &) const
Update the vairable domains from a set of values.
Definition: space_bbh.cpp:207
int type_base
Type of basis used (i.e. using either Chebyshev or Legendre polynomials).
Definition: space.hpp:1367
int ndim
Number of dimensions (should be the same for all the Domains).
Definition: space.hpp:1366
Domain ** domains
Pointers on the various Domains.
Definition: space.hpp:1368
int nbr_domains
Number od Domains.
Definition: space.hpp:1365
Class used to describe and solve a system of equations.
MMPtr_array< Tensor > var
Pointer on the unknown fields.
MMPtr_array< Term_eq > cst
Pointers on the Term_eq coming from the constants passed by the user.
int dom_max
Highest domain number.
int ncst
Number of constants passed by the user.
int dom_min
Smallest domain number.
int nvar
Number of unknown fields.
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69