LORENE
map_et_radius.C
1/*
2 * Methods of the class Map_et relative to the function
3 * r = R_l(xi, theta', phi')
4 */
5
6/*
7 * Copyright (c) 1999-2001 Eric Gourgoulhon
8 *
9 * This file is part of LORENE.
10 *
11 * LORENE is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * LORENE is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with LORENE; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28
29
30/*
31 * $Id: map_et_radius.C,v 1.7 2016/12/05 16:17:58 j_novak Exp $
32 * $Log: map_et_radius.C,v $
33 * Revision 1.7 2016/12/05 16:17:58 j_novak
34 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
35 *
36 * Revision 1.6 2014/10/13 08:53:05 j_novak
37 * Lorene classes and functions now belong to the namespace Lorene.
38 *
39 * Revision 1.5 2013/06/05 15:10:42 j_novak
40 * Suppression of FINJAC sampling in r. This Jacobi(0,2) base is now
41 * available by setting colloc_r to BASE_JAC02 in the Mg3d constructor.
42 *
43 * Revision 1.4 2008/08/27 08:49:16 jl_cornou
44 * Added R_JACO02 case
45 *
46 * Revision 1.3 2004/01/26 16:58:35 j_novak
47 * Added initialization to avoid compiler warning.
48 *
49 * Revision 1.2 2003/12/19 16:21:43 j_novak
50 * Shadow hunt
51 *
52 * Revision 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon
53 * LORENE
54 *
55 * Revision 1.5 2000/10/20 13:14:47 eric
56 * Map_et::val_lx : la valeur par defaut de precis est desormais 1e-14
57 * (et non plus 1e-15).
58 *
59 * Revision 1.4 2000/01/04 13:05:47 eric
60 * \Corrections dans val_lx et val_lx_jk : initialisation de ftp/gtp
61 * par double(0) dans les cas ou il ne sont pas calcules.
62 *
63 * Revision 1.3 1999/12/17 11:03:36 eric
64 * Fonctions val_r_jk et val_lx_jk operationnelles.
65 *
66 * Revision 1.2 1999/12/17 09:29:22 eric
67 * val_lx : initialisation de niter a 0.
68 *
69 * Revision 1.1 1999/12/16 14:19:39 eric
70 * Initial revision
71 *
72 *
73 * $Header: /cvsroot/Lorene/C++/Source/Map/map_et_radius.C,v 1.7 2016/12/05 16:17:58 j_novak Exp $
74 *
75 */
76
77
78// Headers Lorene
79#include "map.h"
80#include "param.h"
81#include "nbr_spx.h"
82#include "utilitaires.h"
83
84// Local prototypes
85namespace Lorene {
86double fonc_invr_map_et_noyau(double, const Param&) ;
87double fonc_invr_map_et_coq(double, const Param&) ;
88double fonc_invr_map_et_zec(double, const Param&) ;
89
90 //------------------------------//
91 // val_r //
92 //------------------------------//
93
94
95double Map_et::val_r(int l, double xi, double theta, double pphi) const {
96
97 assert( l>=0 ) ;
98 assert( l<mg->get_nzone() ) ;
99
100 double resu ;
101 double ftp = ff.val_point(l, 0, theta, pphi) ; // value of F_l(theta,phi)
102
103 switch( mg->get_type_r(l) ) {
104
105 case RARE: {
106 double gtp = gg.val_point(l, 0, theta, pphi) ;
107 double xi_2 = xi * xi ;
108 double xi_3 = xi * xi_2 ;
109 double a = xi_2 * xi_2 * (3. - 2.*xi_2) ;
110 double b = ( 2.5 - 1.5 * xi_2 ) * xi_3 ;
111 resu = alpha[l] * ( xi + a * ftp + b * gtp ) + beta[l] ;
112 break ;
113 }
114
115 case FIN: {
116 double gtp = gg.val_point(l, 0, theta, pphi) ;
117 double xm1 = xi - 1. ;
118 double xp1 = xi + 1. ;
119 double a = 0.25* xm1 * xm1 * (xi + 2.) ;
120 double b = 0.25* xp1 * xp1 * (2. - xi) ;
121 resu = alpha[l] * ( xi + a * ftp + b * gtp ) + beta[l] ;
122 break ;
123 }
124
125 case UNSURR: {
126 double xm1 = xi - 1. ;
127 double a = 0.25* xm1 * xm1 * (xi + 2.) ;
128 resu = double(1) / ( alpha[l] * ( xi + a * ftp ) + beta[l] ) ;
129 break ;
130 }
131
132 default: {
133 cout << "Map_et::val_r: unknown type_r ! " << endl ;
134 abort () ;
135 }
136 }
137
138 return resu ;
139}
140
141 //------------------------------//
142 // val_lx //
143 //------------------------------//
144
145//-------------------------------
146// Version with default precision
147//-------------------------------
148
149void Map_et::val_lx(double rr, double theta, double pphi,
150 int& lz, double& xi) const {
151
152 int nitermax = 100 ; // Maximum number of iteration in the secant method
153 int niter ;
154 double precis = 1e-14 ; // Absolute precision in the secant method
155
156 Param par ;
157 par.add_int(nitermax) ;
158 par.add_int_mod(niter) ;
159 par.add_double(precis) ;
160
161 // Call of the version with precision parameters
162
163 val_lx(rr, theta, pphi, par, lz, xi) ;
164
165}
166
167
168//---------------------------------
169// Version with specified precision
170//---------------------------------
171
172void Map_et::val_lx(double rr, double theta, double pphi,
173 const Param& par, int& lz, double& xi) const {
174
175 int nz = mg->get_nzone() ;
176
177 // Precision in the secant method :
178 // ------------------------------
179
180 int nitermax = par.get_int() ;
181 int& niter = par.get_int_mod() ;
182 niter = 0 ; // initialisation
183 double precis = par.get_double() ;
184
185 // Particular case of r = infinity
186 //--------------------------------
187 if (rr == __infinity) {
188 if ( (mg->get_type_r(nz-1) == UNSURR) &&
189 (alpha[nz-1] == - beta[nz-1]) ) {
190 lz = nz - 1 ;
191 xi = 1 ;
192 }
193 else {
194 cout.precision(16);
195 cout.setf(ios::showpoint);
196 cout << "Map_et::val_lx: the domain containing r = " << rr <<
197 " has not been found ! "
198 << endl ;
199 abort () ;
200 }
201 return ;
202 }
203
204
205 // In which domain is located r ?
206 // ----------------------------
207 lz = - 1 ;
208 double rmax = 0. ;
209 double ftp = double(0) ;
210 double gtp = double(0) ;
211 for (int l=0; l<nz; l++) {
212
213 switch( mg->get_type_r(l) ) {
214
215 case RARE: {
216 ftp = ff.val_point(l, 0, theta, pphi) ; // value of F_l(theta,phi)
217 gtp = gg.val_point(l, 0, theta, pphi) ; // value of G_l(theta,phi)
218 rmax = alpha[l] * ( double(1) + ftp + gtp ) + beta[l] ;
219 break ;
220 }
221
222 case FIN: {
223 ftp = double(0) ;
224 gtp = gg.val_point(l, 0, theta, pphi) ;
225 rmax = alpha[l] * ( double(1) + gtp ) + beta[l] ;
226 break ;
227 }
228
229 case UNSURR: {
230 ftp = double(0) ;
231 gtp = double(0) ;
232 rmax = double(1) / ( alpha[l] + beta[l] ) ;
233 break ;
234 }
235
236 default: {
237 cout << "Map_et::val_lx: unknown type_r ! " << endl ;
238 abort() ;
239 }
240 } // end of switch on type_r
241
242
243 if ( rr <= rmax + 1.e-14 ) {
244 lz = l ;
245 if (ftp == double(0)) ftp = ff.val_point(l, 0, theta, pphi) ;
246 if (gtp == double(0)) gtp = gg.val_point(l, 0, theta, pphi) ;
247 break ;
248 }
249 } // End of loop onto the domains
250
251 if (lz == -1) { // The domain has not been found
252 cout.precision(16);
253 cout.setf(ios::showpoint);
254 cout << "Map_et::val_lx: the domain containing r = " << rr <<
255 " has not been found ! "
256 << endl ;
257 for (int l=0; l<nz; l++) {
258 ftp = ff.val_point(l, 0, theta, pphi) ;
259 gtp = gg.val_point(l, 0, theta, pphi) ;
260 switch( mg->get_type_r(l) ) {
261 case RARE: {
262 rmax = alpha[l] * ( double(1) + ftp + gtp ) + beta[l] ;
263 break ;
264 }
265 case FIN: {
266 rmax = alpha[l] * ( double(1) + gtp ) + beta[l] ;
267 break ;
268 }
269 case UNSURR: {
270 rmax = double(1) / ( alpha[l] + beta[l] ) ;
271 break ;
272 }
273 default: {
274 cout << "Map_et::val_lx: unknown type_r ! " << endl ;
275 abort () ;
276 }
277 } // end of switch on type_r
278
279 cout << "domain: " << l << " theta = " << theta << " phi = "
280 << pphi << " : rmax = " << rmax << endl ;
281 }
282 abort() ;
283 }
284
285 // Computation of xi
286 // -----------------
287
288 if ( (rr >= rmax) && ( rr <= rmax + 1.e-14) ) {
289 xi = double(1) ;
290 }
291 else {
292
293 // Search of xi by the secant method
294 // ---------------------------------
295
296 Param parzerosec ;
297 parzerosec.add_double(rr, 0) ;
298 parzerosec.add_double(ftp, 1) ;
299 parzerosec.add_double(gtp, 2) ;
300 parzerosec.add_double(alpha[lz], 3) ;
301 parzerosec.add_double(beta[lz], 4) ;
302
303
304 switch( mg->get_type_r(lz) ) {
305
306 case RARE: {
307 if ( (ff.get_etat()==ETATZERO) && (gg.get_etat()==ETATZERO) ) {
308 xi = ( rr - beta[lz] ) / alpha[lz] ;
309 }
310 else {
311 double xmin = 0 ;
312 double xmax = 1 ;
313 xi = zerosec(fonc_invr_map_et_noyau, parzerosec, xmin, xmax,
314 precis, nitermax, niter) ;
315 }
316 break ;
317 }
318
319 case FIN: {
320 if ( (ff.get_etat()==ETATZERO) && (gg.get_etat()==ETATZERO) ) {
321 xi = ( rr - beta[lz] ) / alpha[lz] ;
322 }
323 else {
324 double xmin = -1 ;
325 double xmax = 1 ;
326 xi = zerosec(fonc_invr_map_et_coq, parzerosec, xmin, xmax,
327 precis, nitermax, niter) ;
328 }
329 break ;
330 }
331
332 case UNSURR: {
333 if ( (ff.get_etat()==ETATZERO) ) {
334 xi = ( double(1)/rr - beta[lz] ) / alpha[lz] ;
335 }
336 else {
337 assert(ff.get_etat()==ETATQCQ) ;
338 if ( ff.c->t[lz]->get_etat() == ETATZERO) {
339 xi = ( double(1) / rr - beta[lz] ) / alpha[lz] ;
340 }
341 else {
342 double xmin = -1 ;
343 double xmax = 1 ;
344 xi = zerosec(fonc_invr_map_et_zec, parzerosec, xmin, xmax,
345 precis, nitermax, niter) ;
346 }
347 }
348 break ;
349 }
350
351 default: {
352 cout << "Map_et::val_lx: unknown type_r ! " << endl ;
353 abort () ;
354 }
355 }
356
357
358 } // End of search by the secant method
359
360}
361
362
363
364
365 //------------------------------//
366 // val_r_jk //
367 //------------------------------//
368
369
370double Map_et::val_r_jk(int l, double xi, int j, int k) const {
371
372 assert( l>=0 ) ;
373 assert( l<mg->get_nzone() ) ;
374
375 double resu ;
376 double ftp = ff(l, k, j, 0) ; // value of F_l(theta_j, phi_k)
377
378 switch( mg->get_type_r(l) ) {
379
380 case RARE: {
381 double gtp = gg(l, k, j, 0) ; // value of G_l(theta_j, phi_k)
382 double xi_2 = xi * xi ;
383 double xi_3 = xi * xi_2 ;
384 double a = xi_2 * xi_2 * (3. - 2.*xi_2) ;
385 double b = ( 2.5 - 1.5 * xi_2 ) * xi_3 ;
386 resu = alpha[l] * ( xi + a * ftp + b * gtp ) + beta[l] ;
387 break ;
388 }
389
390 case FIN: {
391 double gtp = gg(l, k, j, 0) ; // value of G_l(theta_j, phi_k)
392 double xm1 = xi - 1. ;
393 double xp1 = xi + 1. ;
394 double a = 0.25* xm1 * xm1 * (xi + 2.) ;
395 double b = 0.25* xp1 * xp1 * (2. - xi) ;
396 resu = alpha[l] * ( xi + a * ftp + b * gtp ) + beta[l] ;
397 break ;
398 }
399
400 case UNSURR: {
401 double xm1 = xi - 1. ;
402 double a = 0.25* xm1 * xm1 * (xi + 2.) ;
403 resu = double(1) / ( alpha[l] * ( xi + a * ftp ) + beta[l] ) ;
404 break ;
405 }
406
407 default: {
408 cout << "Map_et::val_r_jk: unknown type_r ! " << endl ;
409 abort () ;
410 }
411 }
412
413 return resu ;
414
415}
416
417 //------------------------------//
418 // val_lx_jk //
419 //------------------------------//
420
421void Map_et::val_lx_jk(double rr, int j, int k, const Param& par,
422 int& lz, double& xi) const {
423
424 int nz = mg->get_nzone() ;
425
426 // Precision in the secant method :
427 // ------------------------------
428
429 int nitermax = par.get_int() ;
430 int& niter = par.get_int_mod() ;
431 niter = 0 ; // initialisation
432 double precis = par.get_double() ;
433
434 // Particular case of r = infinity
435 //--------------------------------
436 if (rr == __infinity) {
437 if ( (mg->get_type_r(nz-1) == UNSURR) &&
438 (alpha[nz-1] == - beta[nz-1]) ) {
439 lz = nz - 1 ;
440 xi = 1 ;
441 }
442 else {
443 cout.precision(16);
444 cout.setf(ios::showpoint);
445 cout << "Map_et::val_lx_jk: the domain containing r = " << rr <<
446 " has not been found ! "
447 << endl ;
448 abort () ;
449 }
450 return ;
451 }
452
453
454 // In which domain is located r ?
455 // ----------------------------
456 lz = - 1 ;
457 double rmax = 0 ;
458 double ftp = double(0) ;
459 double gtp = double(0) ;
460 for (int l=0; l<nz; l++) {
461
462 switch( mg->get_type_r(l) ) {
463
464 case RARE: {
465 ftp = ff(l, k, j, 0) ; // value of F_l(theta_j, phi_k)
466 gtp = gg(l, k, j, 0) ; // value of G_l(theta_j, phi_k)
467 rmax = alpha[l] * ( double(1) + ftp + gtp ) + beta[l] ;
468 break ;
469 }
470
471 case FIN: {
472 ftp = double(0) ;
473 gtp = gg(l, k, j, 0) ; // value of G_l(theta_j, phi_k)
474 rmax = alpha[l] * ( double(1) + gtp ) + beta[l] ;
475 break ;
476 }
477
478 case UNSURR: {
479 ftp = double(0) ;
480 gtp = double(0) ;
481 rmax = double(1) / ( alpha[l] + beta[l] ) ;
482 break ;
483 }
484
485 default: {
486 cout << "Map_et::val_lx_jk: unknown type_r ! " << endl ;
487 abort() ;
488 }
489 } // end of switch on type_r
490
491
492 if ( rr <= rmax + 1.e-14 ) {
493 lz = l ;
494 if (ftp == double(0)) ftp = ff(l, k, j, 0) ;
495 if (gtp == double(0)) gtp = gg(l, k, j, 0) ;
496 break ;
497 }
498 } // End of loop onto the domains
499
500 if (lz == -1) { // The domain has not been found
501 cout.precision(16);
502 cout.setf(ios::showpoint);
503 cout << "Map_et::val_lx_jk: the domain containing r = " << rr <<
504 " has not been found ! "
505 << endl ;
506 for (int l=0; l<nz; l++) {
507 ftp = ff(l, k, j, 0) ;
508 gtp = gg(l, k, j, 0) ;
509 switch( mg->get_type_r(l) ) {
510 case RARE: {
511 rmax = alpha[l] * ( double(1) + ftp + gtp ) + beta[l] ;
512 break ;
513 }
514 case FIN: {
515 rmax = alpha[l] * ( double(1) + gtp ) + beta[l] ;
516 break ;
517 }
518 case UNSURR: {
519 rmax = double(1) / ( alpha[l] + beta[l] ) ;
520 break ;
521 }
522 default: {
523 cout << "Map_et::val_lx_jk: unknown type_r ! " << endl ;
524 abort () ;
525 }
526 } // end of switch on type_r
527
528 cout << "domain: " << l << " j = " << j << " k = " << k
529 << " : rmax = " << rmax << endl ;
530 }
531 abort() ;
532 }
533
534 // Computation of xi
535 // -----------------
536
537 if ( (rr >= rmax) && ( rr <= rmax + 1.e-14) ) {
538 xi = double(1) ;
539 }
540 else {
541
542 // Search of xi by the secant method
543 // ---------------------------------
544
545 Param parzerosec ;
546 parzerosec.add_double(rr, 0) ;
547 parzerosec.add_double(ftp, 1) ;
548 parzerosec.add_double(gtp, 2) ;
549 parzerosec.add_double(alpha[lz], 3) ;
550 parzerosec.add_double(beta[lz], 4) ;
551
552
553 switch( mg->get_type_r(lz) ) {
554
555 case RARE: {
556 if ( (ff.get_etat()==ETATZERO) && (gg.get_etat()==ETATZERO) ) {
557 xi = ( rr - beta[lz] ) / alpha[lz] ;
558 }
559 else {
560 double xmin = 0 ;
561 double xmax = 1 ;
562 xi = zerosec(fonc_invr_map_et_noyau, parzerosec, xmin, xmax,
563 precis, nitermax, niter) ;
564 }
565 break ;
566 }
567
568 case FIN: {
569 if ( (ff.get_etat()==ETATZERO) && (gg.get_etat()==ETATZERO) ) {
570 xi = ( rr - beta[lz] ) / alpha[lz] ;
571 }
572 else {
573 double xmin = -1 ;
574 double xmax = 1 ;
575 xi = zerosec(fonc_invr_map_et_coq, parzerosec, xmin, xmax,
576 precis, nitermax, niter) ;
577 }
578 break ;
579 }
580
581 case UNSURR: {
582 if ( (ff.get_etat()==ETATZERO) ) {
583 xi = ( double(1)/rr - beta[lz] ) / alpha[lz] ;
584 }
585 else {
586 assert(ff.get_etat()==ETATQCQ) ;
587 if ( ff.c->t[lz]->get_etat() == ETATZERO) {
588 xi = ( double(1) / rr - beta[lz] ) / alpha[lz] ;
589 }
590 else {
591 double xmin = -1 ;
592 double xmax = 1 ;
593 xi = zerosec(fonc_invr_map_et_zec, parzerosec, xmin, xmax,
594 precis, nitermax, niter) ;
595 }
596 }
597 break ;
598 }
599
600 default: {
601 cout << "Map_et::val_lx_jk: unknown type_r ! " << endl ;
602 abort () ;
603 }
604 }
605
606
607 } // End of search by the secant method
608}
609
610
611//=============================================================================//
612// Auxilary functions //
613//=============================================================================//
614
615double fonc_invr_map_et_noyau(double x, const Param& par) {
616
617 double r = par.get_double(0) ;
618 double f = par.get_double(1) ;
619 double g = par.get_double(2) ;
620 double alp = par.get_double(3) ;
621 double bet = par.get_double(4) ;
622 double x_2 = x * x ;
623 double x_3 = x_2 * x ;
624 double a = x_2 * x_2 * (3. - 2.*x_2) ;
625 double b = ( 2.5 - 1.5 * x_2 ) * x_3 ;
626
627 return alp * ( x + a * f + b * g ) + bet - r ;
628
629}
630
631//****************************************************************************
632
633double fonc_invr_map_et_coq(double x, const Param& par) {
634
635 double r = par.get_double(0) ;
636 double f = par.get_double(1) ;
637 double g = par.get_double(2) ;
638 double alp = par.get_double(3) ;
639 double bet = par.get_double(4) ;
640 double xm1 = x - 1. ;
641 double xp1 = x + 1. ;
642 double a = 0.25* xm1 * xm1 * (x + 2.) ;
643 double b = 0.25* xp1 * xp1 * (2. - x) ;
644
645 return alp * ( x + a * f + b * g ) + bet - r ;
646
647}
648
649//****************************************************************************
650
651double fonc_invr_map_et_zec(double x, const Param& par) {
652
653 double r = par.get_double(0) ;
654 double f = par.get_double(1) ;
655 double alp = par.get_double(3) ;
656 double bet = par.get_double(4) ;
657 double xm1 = x - 1. ;
658 double a = 0.25* xm1 * xm1 * (x + 2.) ;
659
660 return alp * ( x + a * f ) + bet - double(1) / r ;
661
662}
663
664}
double * beta
Array (size: mg->nzone ) of the values of in each domain.
Definition map.h:2778
virtual void val_lx_jk(double rr, int j, int k, const Param &par, int &l, double &xi) const
Computes the domain index l and the value of corresponding to a point of arbitrary r but collocation...
virtual double val_r(int l, double xi, double theta, double pphi) const
Returns the value of the radial coordinate r for a given in a given domain.
Valeur ff
Values of the function at the nt*np angular collocation points in each domain.
Definition map.h:2837
virtual void val_lx(double rr, double theta, double pphi, int &l, double &xi) const
Computes the domain index l and the value of corresponding to a point given by its physical coordina...
double * alpha
Array (size: mg->nzone ) of the values of in each domain.
Definition map.h:2776
Valeur gg
Values of the function at the nt*np angular collocation points in each domain.
Definition map.h:2844
virtual double val_r_jk(int l, double xi, int j, int k) const
Returns the value of the radial coordinate r for a given and a given collocation point in in a give...
Parameter storage.
Definition param.h:125
void add_double(const double &x, int position=0)
Adds the the address of a new double to the list.
Definition param.C:318
const int & get_int(int position=0) const
Returns the reference of a int stored in the list.
Definition param.C:295
const double & get_double(int position=0) const
Returns the reference of a double stored in the list.
Definition param.C:364
void add_int_mod(int &n, int position=0)
Adds the address of a new modifiable int to the list.
Definition param.C:388
int & get_int_mod(int position=0) const
Returns the reference of a modifiable int stored in the list.
Definition param.C:433
void add_int(const int &n, int position=0)
Adds the address of a new int to the list.
Definition param.C:249
double zerosec(double(*f)(double, const Param &), const Param &par, double a, double b, double precis, int nitermax, int &niter, bool abort=true)
Finding the zero a function.
Definition zerosec.C:92
Lorene prototypes.
Definition app_hor.h:67
Coord x
x coordinate centered on the grid
Definition map.h:738
Coord r
r coordinate centered on the grid
Definition map.h:730