KADATH
domain_shell_surr.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 "headcpp.hpp"
21 
22 #include "utilities.hpp"
23 #include "spheric.hpp"
24 #include "point.hpp"
25 #include "val_domain.hpp"
26 namespace Kadath {
27 // Standard constructor
28 Domain_shell_surr::Domain_shell_surr (int num, int ttype, double rint, double rext, const Point& cr, const Dim_array& nbr) : Domain_shell(num, ttype, rint, rext, cr, nbr) {
29  alpha = (1./rext-1./rint)/2. ;
30  beta = (1./rext+1./rint)/2. ;
31  assert (nbr.get_ndim()==3) ;
32  assert (cr.get_ndim()==3) ; // Affectation de type_point :
33  do_coloc() ;
34 
35 }
36 
37 
38 // Constructor by copy
39 Domain_shell_surr::Domain_shell_surr (const Domain_shell_surr& so) : Domain_shell(so) {
40 
41  // Update the alpha and beta
42  double rint = (beta - alpha) ;
43  double rext = (beta+alpha) ;
44  alpha = (1./rext-1./rint)/2. ;
45  beta = (1./rext+1./rint)/2. ;
46 }
47 
48 Domain_shell_surr::Domain_shell_surr (int num, FILE* fd) : Domain_shell(num, fd) {
49  do_coloc() ;
50 }
51 
52 // Destructor
53 Domain_shell_surr::~Domain_shell_surr() {}
54 
55 void Domain_shell_surr::save (FILE* fd) const {
56  nbr_points.save(fd) ;
57  nbr_coefs.save(fd) ;
58  fwrite_be (&ndim, sizeof(int), 1, fd) ;
59  fwrite_be (&type_base, sizeof(int), 1, fd) ;
60  center.save(fd) ;
61  fwrite_be (&alpha, sizeof(double), 1, fd) ;
62  fwrite_be (&beta, sizeof(double), 1, fd) ;
63 }
64 
65 ostream& Domain_shell_surr::print (ostream& o) const {
66  o << "Shell surr" << endl ;
67  o << 1./(beta - alpha) << " < r < " << 1./(beta+alpha) << endl ;
68  o << "Center = " << center << endl ;
69  o << "Nbr pts = " << nbr_points << endl ;
70  o << endl ;
71  return o ;
72 }
73 
74 
75 
76 Val_domain Domain_shell_surr::der_normal (const Val_domain& so, int bound) const {
77 
78  if ((bound!=OUTER_BC) && (bound!=INNER_BC)) {
79  cerr << "Unknown boundary case in Domain_shell_surr::der_normal" << endl ;
80  abort() ;
81  }
82  return der_r (so) ;
83 }
84 
85 // Computes the Cartesian coordinates
87  for (int i=0 ; i<3 ; i++)
88  assert (coloc[i] != 0x0) ;
89  for (int i=0 ; i<3 ; i++)
90  assert (absol[i] == 0x0) ;
91  for (int i=0 ; i<3 ; i++) {
92  absol[i] = new Val_domain(this) ;
93  absol[i]->allocate_conf() ;
94  }
95  Index index (nbr_points) ;
96 
97  do {
98  absol[0]->set(index) = 1./(alpha* ((*coloc[0])(index(0))) +beta)*
99  sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) + center(1) ;
100  absol[1]->set(index) = 1./(alpha* ((*coloc[0])(index(0))) +beta) *
101  sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) + center(2) ;
102  absol[2]->set(index) = 1./(alpha* ((*coloc[0])(index(0))) + beta) * cos((*coloc[1])(index(1))) + center(3) ;
103  }
104  while (index.inc()) ;
105 }
106 
107 // Computes the radius
109  for (int i=0 ; i<3 ; i++)
110  assert (coloc[i] != 0x0) ;
111  assert (radius == 0x0) ;
112  radius = new Val_domain(this) ;
113  radius->allocate_conf() ;
114  Index index (nbr_points) ;
115  do
116  radius->set(index) = 1./(alpha* ((*coloc[0])(index(0))) + beta) ;
117  while (index.inc()) ;
118  radius->std_base() ;
119 }
120 
121 // Computes the Cartesian coordinates
123  for (int i=0 ; i<3 ; i++)
124  assert (coloc[i] != 0x0) ;
125  for (int i=0 ; i<3 ; i++)
126  assert (cart[i] == 0x0) ;
127  for (int i=0 ; i<3 ; i++) {
128  cart[i] = new Val_domain(this) ;
129  cart[i]->allocate_conf() ;
130  }
131  Index index (nbr_points) ;
132 
133  do {
134  cart[0]->set(index) = 1./(alpha* ((*coloc[0])(index(0))) +beta)*
135  sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) + center(1) ;
136  cart[1]->set(index) = 1./(alpha* ((*coloc[0])(index(0))) +beta) *
137  sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) + center(2) ;
138  cart[2]->set(index) = 1./(alpha* ((*coloc[0])(index(0))) + beta) * cos((*coloc[1])(index(1))) + center(3) ;
139  }
140  while (index.inc()) ;
141 }
142 
143 // Check if a point is inside this domain
144 bool Domain_shell_surr::is_in (const Point& xx, double prec) const {
145 
146  assert (xx.get_ndim()==3) ;
147 
148  double x_loc = xx(1) - center(1) ;
149  double y_loc = xx(2) - center(2) ;
150  double z_loc = xx(3) - center(3) ;
151  double air_loc = sqrt (x_loc*x_loc + y_loc*y_loc + z_loc*z_loc) ;
152 
153  bool res = ((air_loc*(alpha+beta) -1 <= +prec) && (air_loc * (beta-alpha) -1 >= -prec)) ? true : false ;
154  return res ;
155 }
156 
157 //Computes the numerical coordinates, as a function of the absolute ones.
158 const Point Domain_shell_surr::absol_to_num(const Point& abs) const {
159 
160  assert (is_in(abs)) ;
161  Point num(3) ;
162 
163  double x_loc = abs(1) - center(1) ;
164  double y_loc = abs(2) - center(2) ;
165  double z_loc = abs(3) - center(3) ;
166  double air = sqrt(x_loc*x_loc+y_loc*y_loc+z_loc*z_loc) ;
167  num.set(1) = (1./air-beta)/alpha ;
168  double rho = sqrt(x_loc*x_loc+y_loc*y_loc) ;
169 
170  if (rho==0) {
171  // On the axis ?
172  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
173  num.set(3) = 0 ;
174  }
175  else {
176  num.set(2) = atan(rho/z_loc) ;
177  num.set(3) = atan2 (y_loc, x_loc) ;
178  }
179 
180  if (num(2) <0)
181  num.set(2) = M_PI + num(2) ;
182 
183  return num ;
184 }
185 
186 
187 // Convert absolute coordinates to numerical ones
188 const Point Domain_shell_surr::absol_to_num_bound(const Point& abs, int bound) const {
189 
190  assert ((bound==OUTER_BC) || (bound==INNER_BC)) ;
191  assert (is_in(abs, 1e-3)) ;
192  Point num(3) ;
193 
194  double x_loc = abs(1) - center(1) ;
195  double y_loc = abs(2) - center(2) ;
196  double z_loc = abs(3) - center(3) ;
197 
198  switch (bound) {
199  case INNER_BC:
200  num.set(1) = -1 ;
201  break ;
202  case OUTER_BC:
203  num.set(1) = 1 ;
204  break ;
205  default:
206  cerr << "unknown boundary in Domain_shell::absol_to_num" << endl ;
207  abort() ;
208  }
209 
210  double rho = sqrt(x_loc*x_loc+y_loc*y_loc) ;
211 
212  if (rho==0) {
213  // Sur l'axe
214  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
215  num.set(3) = 0 ;
216  }
217  else {
218  num.set(2) = atan(rho/z_loc) ;
219  num.set(3) = atan2 (y_loc, x_loc) ;
220  }
221 
222  if (num(2) <0)
223  num.set(2) = M_PI + num(2) ;
224 
225  return num ;
226 }
227 
228 // Computes the derivatives with respect to XYZ as a function of the numerical ones.
229 void Domain_shell_surr::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
230 
231  // d/dx :
232  Val_domain sintdr (-der_var[0]->mult_sin_theta()/alpha/get_radius()/get_radius()) ;
233  Val_domain dtsr (*der_var[1]/get_radius()) ;
234  dtsr.set_base() = der_var[1]->get_base() ;
235  Val_domain dpsr (*der_var[2]/get_radius()) ;
236  dpsr.set_base() = der_var[2]->get_base() ;
237  Val_domain costdtsr (dtsr.mult_cos_theta()) ;
238 
239  Val_domain dpsrssint (dpsr.div_sin_theta()) ;
240  der_abs[0] = new Val_domain ((sintdr+costdtsr).mult_cos_phi() - dpsrssint.mult_sin_phi()) ;
241 
242  // d/dy :
243  der_abs[1] = new Val_domain ((sintdr+costdtsr).mult_sin_phi() + dpsrssint.mult_cos_phi()) ;
244  // d/dz :
245  der_abs[2] = new Val_domain (-der_var[0]->mult_cos_theta()/alpha/get_radius()/get_radius() - dtsr.mult_sin_theta()) ;
246 }
247 
248 }
Class for storing the dimensions of an array.
Definition: dim_array.hpp:34
int get_ndim() const
Returns the number of dimensions.
Definition: dim_array.hpp:63
void save(FILE *) const
Save function.
Definition: dim_array.cpp:32
Class for a spherical shell and a symmetry with respect to the plane .
Definition: spheric.hpp:1597
virtual void do_cart() const
Computes the Cartesian coordinates.
virtual const Point absol_to_num(const Point &xxx) const
Computes the numerical coordinates from the physical ones.
virtual const Point absol_to_num_bound(const Point &, int) const
Computes the numerical coordinates from the physical ones for a point lying on a boundary.
virtual Val_domain der_r(const Val_domain &) const
Compute the radial derivative of a scalar field.
virtual void do_absol() const
Computes the absolute coordinates.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
virtual void save(FILE *) const
Saving function.
virtual void do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const
Computes the derivative with respect to the absolute Cartesian coordinates from the derivative with r...
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
virtual void do_radius() const
Computes the generalized radius.
Class for a spherical shell and a symmetry with respect to the plane .
Definition: spheric.hpp:555
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
double beta
Relates the numerical to the physical radii.
Definition: spheric.hpp:559
double alpha
Relates the numerical to the physical radii.
Definition: spheric.hpp:558
virtual void do_coloc()
Computes the colocation points.
virtual Val_domain mult_cos_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
Point center
Absolute coordinates of the center.
Definition: spheric.hpp:560
virtual Val_domain mult_sin_theta(const Val_domain &) const
Multiplication by .
Val_domain * radius
The generalized radius.
Definition: space.hpp:78
Memory_mapped_array< Val_domain * > cart
Cartesian coordinates.
Definition: space.hpp:77
Memory_mapped_array< Val_domain * > absol
Asbolute coordinates (if defined ; usually Cartesian-like)
Definition: space.hpp:76
int ndim
Number of dimensions.
Definition: space.hpp:64
Dim_array nbr_coefs
Number of coefficients.
Definition: space.hpp:66
Val_domain const & get_radius() const
Returns the generalized radius.
Definition: space.hpp:1465
Dim_array nbr_points
Number of colocation points.
Definition: space.hpp:65
int type_base
Type of colocation point :
Definition: space.hpp:73
Memory_mapped_array< Array< double > * > coloc
Colocation points in each dimension (stored in ndim 1d- arrays)
Definition: space.hpp:75
Class that gives the position inside a multi-dimensional Array.
Definition: index.hpp:38
bool inc(int increm, int var=0)
Increments the position of the Index.
Definition: index.hpp:99
The class Point is used to store the coordinates of a point.
Definition: point.hpp:30
void save(FILE *) const
Saving function.
Definition: point.cpp:33
const int & get_ndim() const
Returns the number of dimensions.
Definition: point.hpp:51
double & set(int i)
Read/write of a coordinate.
Definition: point.hpp:47
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
Val_domain mult_sin_phi() const
Multiplication by .
Val_domain mult_sin_theta() const
Multiplication by .
Val_domain mult_cos_phi() const
Multiplication by .
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Definition: val_domain.cpp:171
void std_base()
Sets the standard basis of decomposition.
Definition: val_domain.cpp:246
Val_domain div_sin_theta() const
Division by .
Val_domain mult_cos_theta() const
Multiplication by .
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122