20 #include "headcpp.hpp"
22 #include "utilities.hpp"
23 #include "spheric.hpp"
25 #include "tensor_impl.hpp"
27 #include "term_eq.hpp"
29 void coef_1d (
int, Array<double>&) ;
30 double integral_1d (
int,
const Array<double>&) ;
34 Array<double> legendre_norme (
int mm,
int nt) {
37 Array<double> res (nt2-mm, nt2) ;
39 Array<double> theta (nt2) ;
40 Array<double> sintheta (nt2) ;
41 Array<double> costheta (nt2) ;
42 Array<double> coloc (nt2) ;
43 for (
int i=0 ; i<nt2 ; i++) {
44 theta.set(i) = M_PI*i/2./(nt2-1) ;
45 sintheta.set(i) = sin(theta(i)) ;
46 costheta.set(i) = cos(theta(i)) ;
49 for (
int i=0 ; i<nt2 ; i++)
50 res.set(0, i) = pow(-sintheta(i), mm) ;
51 for (
int i=0 ; i<nt2 ; i++)
52 res.set(1, i) = res(0, i)*costheta(i)*(2*mm+1) ;
55 for (
int j=0; j<nt2-mm-2 ; j++) {
56 for (
int i=0 ; i<nt2 ; i++)
57 res.set(j+2, i) = ((2*ll+3)*costheta(i)*res(j+1, i) - (ll+1+mm)*res(j, i))/(ll-mm+2) ;
61 for (
int j=0 ; j<nt2-mm ; j++) {
62 for (
int i=0 ; i<nt2 ; i++)
63 coloc.set(nt2-i-1) = res(j,i) * res(j,i) ;
64 coef_1d (CHEB_EVEN, coloc) ;
65 double norme = 2*integral_1d (CHEB_EVEN, coloc) ;
66 for (
int i=0 ; i<nt2 ; i++)
67 res.set(j,i) /= sqrt(norme) ;
74 Array<double> mat_leg_even (
int nt,
int np) {
76 int nm = int(np/2)+1 ;
81 Array<double> mat (dims) ;
84 Array<double> coloc (nt2) ;
89 for (
int m=0 ; m<nm ; m++) {
91 Array<double> leg (legendre_norme(m, nt)) ;
95 for (
int l=
int(m/2) ; l<nt ; l++) {
99 for (
int j=0 ; j<nt ; j++) {
101 for (
int nn=0 ; nn<nt2 ; nn++)
102 coloc.set(nt2-nn-1) = cos(2*j*M_PI*nn/(nt2-1)/2.) * leg(ll-m, nn) ;
103 coef_1d (CHEB_EVEN, coloc) ;
104 mat.set(pos) = 2*integral_1d (CHEB_EVEN, coloc) ;
111 for (
int l=
int((m-1)/2) ; l<nt-1 ; l++) {
115 for (
int j=0 ; j<nt-1 ; j++) {
117 for (
int nn=0 ; nn<nt2 ; nn++)
118 coloc.set(nt2-nn-1) = sin((2*j+1)*M_PI*nn/(nt2-1)/2.) * leg(ll-m, nn) ;
119 coef_1d (CHEB_EVEN, coloc) ;
120 mat.set(pos) = 2*integral_1d (CHEB_EVEN, coloc) ;
128 Array<double> mat_leg_odd (
int nt,
int np) {
130 int nm = int(np/2)+1 ;
135 Array<double> mat (dims) ;
138 Array<double> coloc (nt2) ;
143 for (
int m=0 ; m<nm ; m++) {
145 Array<double> leg (legendre_norme(m, nt)) ;
149 for (
int l=
int(m/2) ; l<nt-1 ; l++) {
153 for (
int j=0 ; j<nt-1 ; j++) {
155 for (
int nn=0 ; nn<nt2 ; nn++)
156 coloc.set(nt2-nn-1) = cos((2*j+1)*M_PI*nn/(nt2-1)/2.) * leg(ll-m, nn) ;
158 coef_1d (CHEB_EVEN, coloc) ;
159 mat.set(pos) = 2*integral_1d (CHEB_EVEN, coloc) ;
166 for (
int l=
int((m+1)/2) ; l<nt-1 ; l++) {
170 for (
int j=0 ; j<nt-1 ; j++) {
172 for (
int nn=0 ; nn<nt2 ; nn++)
173 coloc.set(nt2-nn-1) = sin(2*j*M_PI*nn/(nt2-1)/2.) * leg(ll-m, nn) ;
174 coef_1d (CHEB_EVEN, coloc) ;
175 mat.set(pos) = 2*integral_1d (CHEB_EVEN, coloc) ;
183 Array<double> mat_inv_leg_even (
int nt,
int np) {
185 int nm = int(np/2)+1 ;
190 Array<double> mat (dims) ;
193 Array<double> coloc (nt2) ;
198 for (
int m=0 ; m<nm ; m++) {
200 Array<double> leg (legendre_norme(m, nt)) ;
204 for (
int l=
int(m/2) ; l<nt ; l++) {
208 for (
int j=0 ; j<nt ; j++) {
210 for (
int nn=0 ; nn<nt2 ; nn++)
211 coloc.set(nn) = leg(ll-m, nn) ;
212 coef_1d (COS_EVEN, coloc) ;
213 mat.set(pos) = coloc(j) ;
220 for (
int l=
int((m-1)/2) ; l<nt-1 ; l++) {
224 for (
int j=0 ; j<nt ; j++) {
226 for (
int nn=0 ; nn<nt2 ; nn++)
227 coloc.set(nn) = leg(ll-m, nn) ;
228 coef_1d (SIN_ODD, coloc) ;
229 mat.set(pos) = coloc(j) ;
237 Array<double> mat_inv_leg_odd (
int nt,
int np) {
239 int nm = int(np/2)+1 ;
244 Array<double> mat (dims) ;
247 Array<double> coloc (nt2) ;
252 for (
int m=0 ; m<nm ; m++) {
254 Array<double> leg (legendre_norme(m, nt)) ;
258 for (
int l=
int(m/2) ; l<nt-1 ; l++) {
262 for (
int j=0 ; j<nt ; j++) {
264 for (
int nn=0 ; nn<nt2 ; nn++)
265 coloc.set(nn) = leg(ll-m, nn) ;
266 coef_1d (COS_ODD, coloc) ;
267 mat.set(pos) = coloc(j) ;
274 for (
int l=
int((m+1)/2) ; l<nt-1 ; l++) {
278 for (
int j=0 ; j<nt ; j++) {
280 for (
int nn=0 ; nn<nt2 ; nn++)
281 coloc.set(nn) = leg(ll-m, nn) ;
282 coef_1d (SIN_EVEN, coloc) ;
283 mat.set(pos) = coloc(j) ;
295 cerr <<
"Domain_shell::multipoles_sym only defined for a tensor" << endl ;
300 cerr <<
"Domain_shell::multipoles_sym only defined with respect to a component (i.e. valence must be 0)" << endl ;
303 assert ((bound==INNER_BC) || (bound==OUTER_BC)) ;
305 bool doder = (so.
der_t==0x0) ?
false :
true ;
314 int mm = (k%2==0) ?
int(k/2) : int((k-1)/2) ;
316 pos_bound.
set(2) = k ;
322 pos_bound.
set(1) = i ;
333 pos_bound.
set(1) = i ;
354 res.
set(pp) = (k%2==0) ? alm*cos(mm*phi(pp(2)))*leg(2*(j-
int(mm/2)), 2*pp(1)) :
355 alm*sin(mm*phi(pp(2)))*leg(2*(j-
int(mm/2)), 2*pp(1)) ;
357 der.
set(pp) = (k%2==0) ? alm_der*cos(mm*phi(pp(2)))*leg(2*(j-
int(mm/2)), 2*pp(1)) :
358 alm_der*sin(mm*phi(pp(2)))*leg(2*(j-
int(mm/2)), 2*pp(1)) ;
366 res.
set(pp) = (k%2==0) ? alm*cos(mm*phi(pp(2)))*leg(2*(j-
int((mm-1)/2)), 2*pp(1)) :
367 alm*sin(mm*phi(pp(2)))*leg(2*(j-
int((mm-1)/2)), 2*pp(1)) ;
369 der.
set(pp) = (k%2==0) ? alm_der*cos(mm*phi(pp(2)))*leg(2*(j-
int((mm-1)/2)), 2*pp(1)) :
370 alm_der*sin(mm*phi(pp(2)))*leg(2*(j-
int((mm-1)/2)), 2*pp(1)) ;
380 if (fabs(alm)<PRECISION)
382 if (fabs(alm_der)<PRECISION)
391 return Term_eq (dom, res_scal, der_scal) ;
394 return Term_eq (dom, res_scal) ;
406 cerr <<
"Domain_shell::multipoles_asym only defined for a tensor" << endl ;
411 cerr <<
"Domain_shell::multipoles_asym only defined with respect to a component (i.e. valence must be 0)" << endl ;
414 assert ((bound==INNER_BC) || (bound==OUTER_BC)) ;
416 bool doder = (so.
der_t==0x0) ?
false :
true ;
425 int mm = (k%2==0) ?
int(k/2) : int((k-1)/2) ;
427 pos_bound.
set(2) = k ;
433 pos_bound.
set(1) = i ;
444 pos_bound.
set(1) = i ;
465 res.
set(pp) = (k%2==0) ? alm*cos(mm*phi(pp(2)))*leg(2*(j-
int(mm/2))+1, 2*pp(1)) :
466 alm*sin(mm*phi(pp(2)))*leg(2*(j-
int(mm/2))+1, 2*pp(1)) ;
468 der.
set(pp) = (k%2==0) ? alm_der*cos(mm*phi(pp(2)))*leg(2*(j-
int(mm/2))+1, 2*pp(1)) :
469 alm_der*sin(mm*phi(pp(2)))*leg(2*(j-
int(mm/2))+1, 2*pp(1)) ;
477 res.
set(pp) = (k%2==0) ? alm*cos(mm*phi(pp(2)))*leg(2*(j-
int((mm+1)/2))+1, 2*pp(1)) :
478 alm*sin(mm*phi(pp(2)))*leg(2*(j-
int((mm+1)/2))+1, 2*pp(1)) ;
480 der.
set(pp) = (k%2==0) ? alm_der*cos(mm*phi(pp(2)))*leg(2*(j-
int((mm+1)/2))+1, 2*pp(1)) :
481 alm_der*sin(mm*phi(pp(2)))*leg(2*(j-
int((mm+1)/2))+1, 2*pp(1)) ;
491 if (fabs(alm)<PRECISION)
493 if (fabs(alm_der)<PRECISION)
503 return Term_eq (dom, res_scal, der_scal) ;
506 return Term_eq (dom, res_scal) ;
514 cerr <<
"Omega must be a double in Domain_harmonics::sym" << endl ;
519 int mm = (k%2==0) ?
int(k/2) : int((k-1)/2) ;
520 int ll = (mm%2==0) ? 2*j : 2*j+1 ;
521 return fit(space, mm, ll, ome, parfit) ;
528 cerr <<
"Omega must be a double in Domain_harmonics::sym" << endl ;
533 int mm = (k%2==0) ?
int(k/2) : int((k-1)/2) ;
534 int ll = (mm%2==0) ? 2*j+1 : 2*j ;
535 return fit(space, mm, ll, ome, parfit) ;
547 int mm = (k%2==0) ?
int(k/2) : int((k-1)/2) ;
549 for (
int j=
int(mm/2) ; j<
nbr_coefs(1) ; j++) {
561 for (
int j=
int((mm-1)/2) ; j<
nbr_coefs(1)-1 ; j++) {
587 int mm = (k%2==0) ?
int(k/2) : int((k-1)/2) ;
589 for (
int j=
int(mm/2) ; j<
nbr_coefs(1)-1 ; j++) {
601 for (
int j=
int((mm+1)/2) ; j<
nbr_coefs(1)-1 ; j++) {
Dim_array dimensions
Dimensions of the Array.
virtual double multipoles_asym(int, int, int, const Val_domain &, const Array< double > &) const
Extraction of a given multipole, at some boundary, for a anti-symmetric scalar function.
virtual Term_eq harmonics_sym(const Term_eq &, const Term_eq &, int, Term_eq(*f)(const Space &, int, int, const Term_eq &, const Param &), const Param &, const Array< double > &) const
Fit, spherical harmonic by spherical harmonic, for a symmetric function.
virtual double multipoles_sym(int, int, int, const Val_domain &, const Array< double > &) const
Extraction of a given multipole, at some boundary, for a symmetric scalar function.
virtual Term_eq radial_part_asym(const Space &, int, int, const Term_eq &, Term_eq(*f)(const Space &, int, int, const Term_eq &, const Param &), const Param &) const
Gives some radial fit for a given multipole, intended for anti-symmetric scalar function.
virtual Term_eq harmonics_asym(const Term_eq &, const Term_eq &, int, Term_eq(*f)(const Space &, int, int, const Term_eq &, const Param &), const Param &, const Array< double > &) const
Fit, spherical harmonic by spherical harmonic, for an anti-symmetric function.
virtual double val_boundary(int, const Val_domain &, const Index &) const
Computes the value of a field at a boundary.
virtual Term_eq radial_part_sym(const Space &, int, int, const Term_eq &, Term_eq(*f)(const Space &, int, int, const Term_eq &, const Param &), const Param &) const
Gives some radial fit for a given multipole, intended for symmetric scalar function.
Dim_array nbr_coefs
Number of coefficients.
Dim_array nbr_points
Number of colocation points.
Array< double > const & get_coloc(int) const
Returns the colocation points for a given variable.
Class that gives the position inside a multi-dimensional Array.
int & set(int i)
Read/write of the position in a given dimension.
bool inc(int increm, int var=0)
Increments the position of the Index.
The class Scalar does not really implements scalars in the mathematical sense but rather tensorial co...
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
The Space class is an ensemble of domains describing the whole space of the computation.
int get_valence() const
Returns the valence.
const Space & get_space() const
Returns the Space.
This class is intended to describe the manage objects appearing in the equations.
Tensor * der_t
Pointer on the variation, if the Term_eq is a Tensor.
const int type_data
Flag describing the type of data :
Tensor * val_t
Pointer on the value, if the Term_eq is a Tensor.
Class for storing the basis of decompositions of a field and its values on both the configuration and...
void set_zero()
Sets the Val_domain to zero (logical state to zero and arrays destroyed).
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Base_spectral & set_base()
Sets the basis of decomposition.
Array< double > * c
Pointer on the Array of the values in the configuration space.
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.