LORENE
grille_val_interp.C
1/*
2 * Methods for interpolating with class Grille_val, and its derivative classes.
3 *
4 * See the file grille_val.h for documentation
5 *
6 */
7
8/*
9 * Copyright (c) 2001 Jerome Novak
10 *
11 * This file is part of LORENE.
12 *
13 * LORENE is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * LORENE is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with LORENE; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29
30
31
32/*
33 * $Id: grille_val_interp.C,v 1.15 2019/05/29 08:56:53 j_novak Exp $
34 * $Log: grille_val_interp.C,v $
35 * Revision 1.15 2019/05/29 08:56:53 j_novak
36 * New interpolation using monotonic cubic algorithm from Steffen (1980)
37 *
38 * Revision 1.14 2016/12/05 16:18:20 j_novak
39 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
40 *
41 * Revision 1.13 2014/10/13 08:53:48 j_novak
42 * Lorene classes and functions now belong to the namespace Lorene.
43 *
44 * Revision 1.12 2010/02/04 16:44:35 j_novak
45 * Reformulation of the parabolic interpolation, to have better accuracy
46 *
47 * Revision 1.11 2005/06/23 13:40:08 j_novak
48 * The tests on the number of dimensions have been changed to handle better the
49 * axisymmetric case.
50 *
51 * Revision 1.10 2005/06/22 09:11:17 lm_lin
52 *
53 * Grid wedding: convert from the old C++ object "Cmp" to "Scalar".
54 *
55 * Revision 1.9 2004/05/07 12:32:13 j_novak
56 * New summation from spectral to FD grid. Much faster!
57 *
58 * Revision 1.8 2004/03/25 14:52:33 j_novak
59 * Suppressed some documentation/
60 *
61 * Revision 1.7 2003/12/19 15:05:14 j_novak
62 * Trying to avoid shadowed variables
63 *
64 * Revision 1.6 2003/12/05 14:51:54 j_novak
65 * problem with new SGI compiler
66 *
67 * Revision 1.5 2003/10/03 16:17:17 j_novak
68 * Corrected some const qualifiers
69 *
70 * Revision 1.4 2002/11/13 11:22:57 j_novak
71 * Version "provisoire" de l'interpolation (sommation depuis la grille
72 * spectrale) aux interfaces de la grille de Valence.
73 *
74 * Revision 1.3 2002/09/09 13:00:40 e_gourgoulhon
75 * Modification of declaration of Fortran 77 prototypes for
76 * a better portability (in particular on IBM AIX systems):
77 * All Fortran subroutine names are now written F77_* and are
78 * defined in the new file C++/Include/proto_f77.h.
79 *
80 * Revision 1.2 2001/11/23 16:03:07 j_novak
81 *
82 * minor modifications on the grid check.
83 *
84 * Revision 1.1 2001/11/22 13:41:54 j_novak
85 * Added all source files for manipulating Valencia type objects and making
86 * interpolations to and from Meudon grids.
87 *
88 *
89 * $Header: /cvsroot/Lorene/C++/Source/Valencia/grille_val_interp.C,v 1.15 2019/05/29 08:56:53 j_novak Exp $
90 *
91 */
92
93// Fichier includes
94#include "grille_val.h"
95#include "proto_f77.h"
96
97 //------------------
98 // Compatibilite
99 //------------------
100
101//Compatibilite entre une grille valencienne cartesienne et une meudonaise
102namespace Lorene {
103bool Gval_cart::compatible(const Map* mp, const int lmax, const int lmin)
104 const {
105
106 //Seulement avec des mappings du genre affine
107 assert( dynamic_cast<const Map_af*>(mp) != 0x0) ;
108
109 const Mg3d* mgrid = mp->get_mg() ;
110 assert(lmin >= 0 && lmax <= mgrid->get_nzone()) ;
111 int dim_spec = 1 ;
112 for (int i=lmin; i<lmax; i++) {
113 if ((mgrid->get_nt(i) > 1)&&(dim_spec==1)) dim_spec = 2;
114 if (mgrid->get_np(i) > 1) dim_spec = 3;
115 }
116 if (dim_spec != dim.ndim) {
117 cout << "Grille_val::compatibilite: the number of dimensions" << endl ;
118 cout << "of both grids do not coincide!" << endl;
119 abort() ;
120 }
121 if (type_t != mgrid->get_type_t()) {
122 cout << "Grille_val::compatibilite: the symmetries in theta" << endl ;
123 cout << "of both grids do not coincide!" << endl;
124 abort() ;
125 }
126 if (type_p != mgrid->get_type_p()) {
127 cout << "Grille_val::compatibilite: the symmetries in phi" << endl ;
128 cout << "of both grids do not coincide!" << endl;
129 abort() ;
130 }
131
132 bool dimension = true ;
133 const Coord& rr = mp->r ;
134
135 double rout = (+rr)(lmax-1, 0, 0, mgrid->get_nr(lmax-1) - 1) ;
136
137 dimension &= (rout <= *zrmax) ;
138 switch (dim_spec) {
139 case 1:{
140 dimension &= ((+rr)(lmin,0,0,0) >= *zrmin) ;
141 break ;
142 }
143 case 2: {
144 if (mgrid->get_type_t() == SYM)
145 {dimension &= (*zrmin <= 0.) ;}
146 else {
147 dimension &= (*zrmin <= -rout ) ;}
148 dimension &= (*xmin <= 0.) ;
149 dimension &= (*xmax >= rout ) ;
150 break ;
151 }
152 case 3: {
153 if (mgrid->get_type_t() == SYM)
154 {dimension &= (*zrmin <= 0.) ;}
155 else {
156 dimension &= (*zrmin <= -rout) ;}
157 if (mgrid->get_type_p() == SYM) {
158 dimension &= (*ymin <= 0.) ;
159 dimension &= (*xmin <= -rout) ;
160 }
161 else {
162 dimension &= (*xmin <= -rout ) ;
163 dimension &= (*ymin <= -rout ) ;
164 }
165 dimension &= (*xmax >= rout) ;
166 dimension &= (*ymax >= rout) ;
167 break ;
168 }
169 }
170 return dimension ;
171
172}
173//Compatibilite entre une grille valencienne spherique et une meudonaise
174bool Gval_spher::compatible(const Map* mp, const int lmax, const int lmin)
175 const {
176
177 //Seulement avec des mappings du genre affine.
178 assert( dynamic_cast<const Map_af*>(mp) != 0x0) ;
179
180 int dim_spec = 1 ;
181
182 const Mg3d* mgrid = mp->get_mg() ;
183 for (int i=lmin; i<lmax; i++) {
184 if ((mgrid->get_nt(i) > 1)&&(dim_spec==1)) dim_spec = 2;
185 if (mgrid->get_np(i) > 1) dim_spec = 3;
186 }
187 if (dim_spec > dim.ndim) {
188 cout << "Grille_val::compatibilite: the number of dimensions" << endl ;
189 cout << "of both grids do not coincide!" << endl;
190 cout << "Spectral : " << dim_spec << "D, FD: " << dim.ndim << "D" << endl ;
191 abort() ;
192 }
193 if (type_t != mgrid->get_type_t()) {
194 cout << "Grille_val::compatibilite: the symmetries in theta" << endl ;
195 cout << "of both grids do not coincide!" << endl;
196 abort() ;
197 }
198 if (type_p != mgrid->get_type_p()) {
199 cout << "Grille_val::compatibilite: the symmetries in phi" << endl ;
200 cout << "of both grids do not coincide!" << endl;
201 abort() ;
202 }
203
204 const Coord& rr = mp->r ;
205
206 int i_b = mgrid->get_nr(lmax-1) - 1 ;
207
208 double rmax = (+rr)(lmax-1, 0, 0, i_b) ;
209 double rmin = (+rr)(lmin, 0, 0, 0) ;
210 double valmax = get_zr(dim.dim[0]+nfantome - 1) ;
211 double valmin = get_zr(-nfantome) ;
212
213 bool dimension = ((rmax <= (valmax)) && (rmin>= (valmin))) ;
214
215 return dimension ;
216}
217
218// Teste si la grille valencienne cartesienne est contenue dans le mapping
219// de Meudon (pour le passage Meudon->Valence )
220bool Gval_cart::contenue_dans(const Map& mp, const int lmax, const int lmin)
221 const {
222 //Seulement avec des mappings du genre affine
223 assert( dynamic_cast<const Map_af*>(&mp) != 0x0) ;
224
225 const Mg3d* mgrid = mp.get_mg() ;
226 assert(lmin >= 0 && lmax <= mgrid->get_nzone()) ;
227 int dim_spec = 1 ;
228 for (int i=lmin; i<lmax; i++) {
229 if ((mgrid->get_nt(i) > 1)&&(dim_spec==1)) dim_spec = 2;
230 if (mgrid->get_np(i) > 1) dim_spec = 3;
231 }
232 if (dim_spec != dim.ndim) {
233 cout << "Grille_val::contenue_dans: the number of dimensions" << endl ;
234 cout << "of both grids do not coincide!" << endl;
235 abort() ;
236 }
237 if (type_t != mgrid->get_type_t()) {
238 cout << "Grille_val::contenue_dans: the symmetries in theta" << endl ;
239 cout << "of both grids do not coincide!" << endl;
240 abort() ;
241 }
242 if (type_p != mgrid->get_type_p()) {
243 cout << "Grille_val::contenue_dans: the symmetries in phi" << endl ;
244 cout << "of both grids do not coincide!" << endl;
245 abort() ;
246 }
247
248 bool dimension = true ;
249 const Coord& rr = mp.r ;
250
251 //For an affine mapping:
252 double radius = (+rr)(lmax-1,0,0,mgrid->get_nr(lmax-1)-1) ;
253 double radius2 = radius*radius ;
254
255 if (dim_spec ==1) {
256 dimension &= ((+rr)(lmin,0,0,0) <= *zrmin) ;
257 dimension &= (radius >= *zrmax) ;
258 }
259 if (dim_spec ==2) { //## a transformer en switch...
260 dimension &= ((+rr)(lmin,0,0,0)/radius < 1.e-6) ;
261 dimension &= (*xmin >= 0.) ;
262 if (mgrid->get_type_t() == SYM) dimension &= (*zrmin >= 0.) ;
263 double x1 = *xmax ;
264 double z1 = (fabs(*zrmax)>fabs(*zrmin)? *zrmax : *zrmin) ;
265 dimension &= (x1*x1+z1*z1 <= radius2) ;
266 }
267 if (dim_spec == 3) {
268 if (mgrid->get_type_t() == SYM) dimension &= (*zrmin >= 0.) ;
269 if (mgrid->get_type_p() == SYM) dimension &= (*ymin >= 0.) ;
270 double x1 = (fabs(*xmax)>fabs(*xmin)? *xmax : *xmin) ;
271 double y1 = (fabs(*ymax)>fabs(*ymin)? *ymax : *ymin) ;
272 double z1 = (fabs(*zrmax)>fabs(*zrmin)? *zrmax : *zrmin) ;
273 dimension &= (x1*x1+y1*y1+z1*z1 <= radius2) ;
274 }
275 return dimension ;
276}
277
278// Teste si la grille valencienne spherique est contenue dans le mapping
279// de Meudon (pour le passage Meudon->Valence )
280bool Gval_spher::contenue_dans(const Map& mp, const int lmax, const int lmin)
281 const {
282
283 //Seulement avec des mappings du genre affine.
284 assert( dynamic_cast<const Map_af*>(&mp) != 0x0) ;
285
286 const Mg3d* mgrid = mp.get_mg() ;
287
288 if (type_t != mgrid->get_type_t()) {
289 cout << "Grille_val::contenue_dans: the symmetries in theta" << endl ;
290 cout << "of both grids do not coincide!" << endl;
291 abort() ;
292 }
293 if (type_p != mgrid->get_type_p()) {
294 cout << "Grille_val::contenue_dans: the symmetries in phi" << endl ;
295 cout << "of both grids do not coincide!" << endl;
296 abort() ;
297 }
298
299 const Coord& rr = mp.r ;
300
301 int i_b = mgrid->get_nr(lmax-1) - 1 ;
302
303 double rmax = (+rr)(lmax-1, 0, 0, i_b) ;
304 double rmin = (+rr)(lmin, 0, 0, 0) ;
305 double valmin = get_zr(0) ;
306 double valmax = get_zr(dim.dim[0] - 1) ;
307
308 bool dimension = ((rmax >= valmax) && (rmin<= valmin)) ;
309
310 return dimension ;
311}
312
313 //------------------
314 // Interpolation 1D
315 //------------------
316
317// Interpolation pour la classe de base
318Tbl Grille_val::interpol1(const Tbl& rdep, const Tbl& rarr, const Tbl& fdep,
319 int flag, const int type_inter) const {
320 assert(rdep.get_ndim() == 1) ;
321 assert(rarr.get_ndim() == 1) ;
322 assert(rdep.dim == fdep.dim) ;
323
324 Tbl farr(rarr.dim) ;
325 farr.set_etat_qcq() ;
326
327 int ndep = rdep.get_dim(0) ;
328 int narr = rarr.get_dim(0) ;
329
330 switch (type_inter) {
331 case 0: { // Minization of second derivative using Silvano's routine insmts
332 int ndeg[4] ;
333 ndeg[0] = ndep ;
334 ndeg[1] = narr ;
335 double* err0 = new double[ndep+narr] ;
336 double* err1 = new double[ndep+narr] ;
337 double* den0 = new double[ndep+narr] ;
338 double* den1 = new double[ndep+narr] ;
339 for (int i=0; i<ndep; i++) {
340 err0[i] = rdep(i) ;
341 den0[i] = fdep(i) ;
342 }
343 for (int i=0; i<narr; i++) err1[i] = rarr(i) ;
344 F77_insmts(ndeg, &flag, err0, err1, den0, den1) ;
345 for (int i=0; i<narr; i++) farr.set(i) = den1[i] ;
346 delete[] err0 ;
347 delete[] den0 ;
348 delete[] err1 ;
349 delete[] den1 ;
350 break ;
351 }
352 case 1: { // Piecewise linear ...
353 int ip = 0 ;
354 int is = 1 ;
355 assert(ndep > 1);
356 for (int i=0; i<narr; i++) {
357 while(rdep(is) < rarr(i)) is++ ;
358 assert(is<ndep) ;
359 ip = is - 1 ;
360 farr.t[i] = (fdep(is)*(rdep(ip)-rarr(i)) +
361 fdep(ip)*(rarr(i)-rdep(is))) /
362 (rdep(ip)-rdep(is)) ;
363 }
364 break ;
365 }
366
367 case 2: { // Piecewise parabolic
368 int i1, i2, i3 ;
369 double xr, x1, x2, x3, y1, y2, y3 ;
370 i2 = 0 ;
371 i3 = 1 ;
372 assert(ndep > 2) ;
373 for (int i=0; i<narr; i++) {
374 xr = rarr(i) ;
375 while(rdep.t[i3] < xr) i3++ ;
376 assert(i3<ndep) ;
377 if (i3 == 1) {
378 i1 = 0 ;
379 i2 = 1 ;
380 i3 = 2 ;
381 }
382 else {
383 i2 = i3 - 1 ;
384 i1 = i2 - 1 ;
385 }
386 x1 = rdep(i1) ;
387 x2 = rdep(i2) ;
388 x3 = rdep(i3) ;
389 y1 = fdep(i1) ;
390 y2 = fdep(i2) ;
391 y3 = fdep(i3) ;
392 double c = y1 ;
393 double b = (y2 - y1) / (x2 - x1) ;
394 double a = ( (y3 - y2)/(x3 - x2) - (y2 - y1)/(x2 - x1) ) / (x3 - x1) ;
395 farr.t[i] = c + b*(xr - x1) + a*(xr - x1)*(xr - x2) ;
396 }
397 break ;
398 }
399 // Monotone cubic interpolation from M. Steffen A&A vol. 239, pp.443-450 (1980)
400 case 3: {
401 int ndm1 = ndep - 1 ;
402 double ai(0), bi(0), ci(0), di(0) ;
403 Tbl hi(ndep) ; hi.set_etat_qcq() ;
404 Tbl si(ndep) ; si.set_etat_qcq() ;
405 Tbl yprime(ndep) ; yprime.set_etat_qcq() ;
406 Tbl pi(ndep) ; pi.set_etat_qcq() ;
407 hi.set(0) = rdep(1) - rdep(0) ;
408 si.set(0) = (fdep(1) - fdep(0)) / hi(0) ;
409 for (int i=1; i<ndm1; i++) {
410 hi.set(i) = rdep(i+1) - rdep(i) ;
411 si.set(i) = ( fdep(i+1) - fdep(i) ) / hi(i) ;
412 pi.set(i) = (si(i-1)*hi(i) + si(i)*hi(i-1)) / (hi(i-1) + hi(i)) ;
413 if ( si(i-1) * si(i) <= 0) yprime.set(i) = 0. ;
414 else {
415 yprime.set(i) = pi(i) ;
416 double fsi = fabs(si(i)) ;
417 double fsim1 = fabs(si(i-1)) ;
418 if ( (fabs(pi(i)) > 2*fsim1) || (fabs(pi(i)) > 2*fsi) )
419 { int a = (si(i) > 0 ? 1 : -1 ) ;
420 yprime.set(i) = 2*a* ( fsim1 < fsi ? fsim1 : fsi ) ;
421 }
422 }
423 }
424
425 // Special cases at the boundaries
426 pi.set(0) = si(0)* ( 1 + hi(0)/(hi(0) + hi(1)) )
427 - si(1) * ( hi(0) / (hi(0) + hi(1)) ) ;
428 if ( pi(0) * si(0) <= 0 ) yprime.set(0) = 0. ;
429 else {
430 yprime.set(0) = pi(0) ;
431 if ( fabs(pi(0)) > 2*fabs(si(0)) ) yprime.set(0) = 2*si(0) ;
432 }
433 int ndm2 = ndep - 2 ;
434 int ndm3 = ndep - 3 ;
435 pi.set(ndm1) = si(ndm2)* ( 1 + hi(ndm2)/(hi(ndm2) + hi(ndm3)) )
436 - si(ndm3) * ( hi(ndm2) / (hi(ndm2) + hi(ndm3)) ) ;
437 if ( pi(ndm1) * si(ndm2) <= 0 ) yprime.set(ndm1) = 0. ;
438 else {
439 yprime.set(ndm1) = pi(ndm1) ;
440 if ( fabs(pi(ndm1)) > 2*fabs(si(ndm2)) ) yprime.set(ndm1) = 2*si(ndm2) ;
441 }
442
443
444 int ispec = 0 ; // index of spectral point
445 bool still_points = true ;
446 for (int i=0; i<ndm1; i++) {
447 if (still_points) {
448 if ( rarr(ispec) < rdep(i+1) ) {
449 ai = (yprime(i) + yprime(i+1) - 2*si(i)) / (hi(i)*hi(i)) ;
450 bi = (3*si(i) - 2*yprime(i) - yprime(i+1)) / hi(i) ;
451 ci = yprime(i) ;
452 di = fdep(i) ;
453 }
454 while ( (rarr(ispec) < rdep(i+1)) && still_points ) {
455 double hh = rarr(ispec) - rdep(i) ;
456 farr.t[ispec] = di + hh*(ci + hh*(bi + hh*ai)) ;
457 if (ispec < narr -1) ispec++ ;
458 else still_points = false ;
459 }
460 }
461 }
462 break ;
463 }
464
465 default: {
466 cout << "Unknown type of interpolation!" << endl ;
467 abort() ;
468 break ;
469 }
470 }
471 return farr ;
472}
473
474 //------------------
475 // Interpolation 2D
476 //------------------
477
478// Interpolation pour les classes derivees
479Tbl Gval_spher::interpol2(const Tbl& fdep, const Tbl& rarr,
480 const Tbl& tarr, const int type_inter) const
481{
482 assert(dim.ndim >= 2) ;
483 assert(fdep.get_ndim() == 2) ;
484 assert(rarr.get_ndim() == 1) ;
485 assert(tarr.get_ndim() == 1) ;
486
487 int ntv = tet->get_dim(0) ;
488 int nrv = zr->get_dim(0) ;
489 int ntm = tarr.get_dim(0) ;
490 int nrm = rarr.get_dim(0) ;
491
492 Tbl *fdept = new Tbl(nrv) ;
493 fdept->set_etat_qcq() ;
494 Tbl intermediaire(ntv, nrm) ;
495 intermediaire.set_etat_qcq() ;
496
497 Tbl farr(ntm, nrm) ;
498 farr.set_etat_qcq() ;
499
500 int job = 1 ;
501 for (int i=0; i<ntv; i++) {
502 for (int j=0; j<nrv; j++) fdept->t[j] = fdep.t[i*nrv+j] ;
503 Tbl fr(interpol1(*zr, rarr, *fdept, job, type_inter)) ;
504 job = 0 ;
505 for (int j=0; j<nrm; j++) intermediaire.t[i*nrm+j] = fr.t[j] ;
506 }
507 delete fdept ;
508
509 fdept = new Tbl(ntv) ;
510 fdept->set_etat_qcq() ;
511 job = 1 ;
512 for (int i=0; i<nrm; i++) {
513 for (int j=0; j<ntv; j++) fdept->t[j] = intermediaire.t[j*nrm+i] ;
514 Tbl fr(interpol1(*tet, tarr, *fdept, job, type_inter)) ;
515 job = 0 ;
516 for (int j=0; j<ntm; j++) farr.set(j,i) = fr(j) ;
517 }
518 delete fdept ;
519 return farr ;
520}
521
522#ifndef DOXYGEN_SHOULD_SKIP_THIS
523
524struct Point {
525 double x ;
526 int l ;
527 int k ;
528};
529
530#endif /* DOXYGEN_SHOULD_SKIP_THIS */
531
532int copar(const void* a, const void* b) {
533 double x = (reinterpret_cast<const Point*>(a))->x ;
534 double y = (reinterpret_cast<const Point*>(b))->x ;
535 return x > y ? 1 : -1 ;
536}
537
538Tbl Gval_cart::interpol2(const Tbl& fdep, const Tbl& rarr,
539 const Tbl& tetarr, const int type_inter) const
540{
541 return interpol2c(*zr, *x, fdep, rarr, tetarr, type_inter) ;
542}
543
544Tbl Gval_cart::interpol2c(const Tbl& zdep, const Tbl& xdep, const Tbl& fdep,
545 const Tbl& rarr, const Tbl& tarr, const int inter_type) const {
546
547 assert(fdep.get_ndim() == 2) ;
548 assert(zdep.get_ndim() == 1) ;
549 assert(xdep.get_ndim() == 1) ;
550 assert(rarr.get_ndim() == 1) ;
551 assert(tarr.get_ndim() == 1) ;
552
553 int nz = zdep.get_dim(0) ;
554 int nx = xdep.get_dim(0) ;
555 int nr = rarr.get_dim(0) ;
556 int nt = tarr.get_dim(0) ;
557
558 Tbl farr(nt, nr) ;
559 farr.set_etat_qcq() ;
560
561 int narr = nt*nr ;
562 Point* zlk = new Point[narr] ;
563 int inum = 0 ;
564 int ir, it ;
565 for (it=0; it < nt; it++) {
566 for (ir=0; ir < nr; ir++) {
567 zlk[inum].x = rarr(ir)*cos(tarr(it)) ;
568 zlk[inum].l = ir ;
569 zlk[inum].k = it ;
570 inum++ ;
571 }
572 }
573
574 void* base = reinterpret_cast<void*>(zlk) ;
575 size_t nel = size_t(narr) ;
576 size_t width = sizeof(Point) ;
577 qsort (base, nel, width, copar) ;
578
579 Tbl effdep(nz) ; effdep.set_etat_qcq() ;
580
581 double x12 = 1e-6*(zdep(nz-1) - zdep(0)) ;
582 // Attention!! x12 doit etre compatible avec son equivalent dans insmts
583 int ndistz = 0;
584 inum = 0 ;
585 do {
586 inum++ ;
587 if (inum < narr) {
588 if ( (zlk[inum].x - zlk[inum-1].x) > x12 ) {ndistz++ ; }
589 }
590 } while (inum < narr) ;
591 ndistz++ ;
592 Tbl errarr(ndistz) ;
593 errarr.set_etat_qcq() ;
594 Tbl effarr(ndistz) ;
595 ndistz = 0 ;
596 inum = 0 ;
597 do {
598 errarr.set(ndistz) = zlk[inum].x ;
599 inum ++ ;
600 if (inum < narr) {
601 if ( (zlk[inum].x - zlk[inum-1].x) > x12 ) {ndistz++ ; }
602 }
603 } while (inum < narr) ;
604 ndistz++ ;
605
606 int ijob = 1 ;
607
608 Tbl tablo(nx, ndistz) ;
609 tablo.set_etat_qcq() ;
610 for (int j=0; j<nx; j++) {
611 for (int i=0; i<nz; i++) effdep.set(i) = fdep(j,i) ;
612 effarr = interpol1(zdep, errarr, effdep, ijob, inter_type) ;
613 ijob = 0 ;
614 for (int i=0; i<ndistz; i++) tablo.set(j,i) = effarr(i) ;
615 }
616
617 inum = 0 ;
618 int indz = 0 ;
619 Tbl effdep2(nx) ;
620 effdep2.set_etat_qcq() ;
621 while (inum < narr) {
622 Point* xlk = new Point[3*nr] ;
623 int nxline = 0 ;
624 int inum1 ;
625 do {
626 ir = zlk[inum].l ;
627 it = zlk[inum].k ;
628 xlk[nxline].x = rarr(ir)*sin(tarr(it)) ;
629 xlk[nxline].l = ir ;
630 xlk[nxline].k = it ;
631 nxline ++ ; inum ++ ;
632 inum1 = (inum < narr ? inum : 0) ;
633 } while ( ( (zlk[inum1].x - zlk[inum-1].x) < x12 ) && (inum < narr)) ;
634 void* bas2 = reinterpret_cast<void*>(xlk) ;
635 size_t ne2 = size_t(nxline) ;
636 qsort (bas2, ne2, width, copar) ;
637
638 int inum2 = 0 ;
639 int ndistx = 0 ;
640 do {
641 inum2 ++ ;
642 if (inum2 < nxline) {
643 if ( (xlk[inum2].x - xlk[inum2-1].x) > x12 ) {ndistx++ ; }
644 }
645 } while (inum2 < nxline) ;
646 ndistx++ ;
647
648 Tbl errarr2(ndistx) ;
649 errarr2.set_etat_qcq() ;
650 Tbl effarr2(ndistx) ;
651 inum2 = 0 ;
652 ndistx = 0 ;
653 do {
654 errarr2.set(ndistx) = xlk[inum2].x ;
655 inum2 ++ ;
656 if (inum2 < nxline) {
657 if ( (xlk[inum2].x - xlk[inum2-1].x) > x12 ) {ndistx++ ; }
658 }
659 } while (inum2 < nxline) ;
660 ndistx++ ;
661
662 for (int j=0; j<nx; j++) {
663 effdep2.set(j) = tablo(j,indz) ;
664 }
665 indz++ ;
666 ijob = 1 ;
667 effarr2 = interpol1(xdep, errarr2, effdep2, ijob, inter_type) ;
668 int iresu = 0 ;
669 if (ijob == -1) {
670 for (int i=0; i<nxline; i++) {
671 while (fabs(xlk[i].x - xdep(iresu)) > x12 ) {
672 iresu++ ;
673 }
674 ir = xlk[i].l ;
675 it = xlk[i].k ;
676 farr.set(it,ir) = effdep2(iresu) ;
677 }
678 }
679 else {
680 double resu ;
681 for (int i=0; i<nxline; i++) {
682 resu = effarr2(iresu) ;
683 if (i<nxline-1) {
684 if ((xlk[i+1].x-xlk[i].x) > x12) {
685 iresu++ ;
686 }
687 }
688 ir = xlk[i].l ;
689 it = xlk[i].k ;
690 farr.set(it,ir) = resu ;
691 }
692 }
693 delete [] xlk ;
694 }
695
696 delete [] zlk ;
697 return farr ;
698}
699
700
701 //------------------
702 // Interpolation 3D
703 //------------------
704
705// Interpolation pour les classes derivees
706Tbl Gval_spher::interpol3(const Tbl& fdep, const Tbl& rarr, const Tbl& tarr,
707 const Tbl& parr, const int type_inter) const {
708 assert(dim.ndim == 3) ;
709 assert(fdep.get_ndim() == 3) ;
710 assert(rarr.get_ndim() == 1) ;
711 assert(tarr.get_ndim() == 1) ;
712 assert(parr.get_ndim() == 1) ;
713
714 int npv = phi->get_dim(0) ;
715 int ntv = tet->get_dim(0) ;
716 int nrv = zr->get_dim(0) ;
717 int npm = parr.get_dim(0) ;
718 int ntm = tarr.get_dim(0) ;
719 int nrm = rarr.get_dim(0) ;
720
721 Tbl *fdept = new Tbl(ntv, nrv) ;
722 fdept->set_etat_qcq() ;
723 Tbl intermediaire(npv, ntm, nrm) ;
724 intermediaire.set_etat_qcq() ;
725
726 Tbl farr(npm, ntm, nrm) ;
727 farr.set_etat_qcq() ;
728
729 for (int i=0; i<npv; i++) {
730 for (int j=0; j<ntv; j++)
731 for (int k=0; k<nrv; k++) fdept->t[j*nrv+k] = fdep.t[(i*ntv+j)*nrv+k] ;
732 Tbl fr(interpol2(*fdept, rarr, tarr, type_inter)) ;
733 for (int j=0; j<ntm; j++)
734 for (int k=0; k<nrm; k++) intermediaire.set(i,j,k) = fr(j,k) ;
735 }
736 delete fdept ;
737
738 int job = 1 ;
739 fdept = new Tbl(npv) ;
740 fdept->set_etat_qcq() ;
741 for (int i=0; i<ntm; i++) {
742 for (int j=0; j<nrm; j++) {
743 for (int k=0; k<npv; k++) fdept->set(k) = intermediaire(k,i,j) ;
744 Tbl fr(interpol1(*phi, parr, *fdept, job, type_inter)) ;
745 job = 0 ;
746 for (int k=0; k<npm; k++) farr.set(k,i,j) = fr(k) ;
747 }
748 }
749 delete fdept ;
750 return farr ;
751}
752
753Tbl Gval_cart::interpol3(const Tbl& fdep, const Tbl& rarr,
754 const Tbl& tarr, const Tbl& parr, const
755 int inter_type) const {
756
757 assert(fdep.get_ndim() == 3) ;
758 assert(rarr.get_ndim() == 1) ;
759 assert(tarr.get_ndim() == 1) ;
760 assert(parr.get_ndim() == 1) ;
761
762 int nz = zr->get_dim(0) ;
763 int nx = x->get_dim(0) ;
764 int ny = y->get_dim(0) ;
765 int nr = rarr.get_dim(0) ;
766 int nt = tarr.get_dim(0) ;
767 int np = parr.get_dim(0) ;
768 Tbl farr(np, nt, nr) ;
769 farr.set_etat_qcq() ;
770
771 bool coq = (rarr(0)/rarr(nr-1) > 1.e-6) ;
772 Tbl* rarr2(0x0);
773 if (coq) { // If the spectral grid is only made of shells
774 rarr2 = new Tbl(2*nr) ;
775 rarr2->set_etat_qcq() ;
776 double dr = rarr(0)/nr ;
777 for (int i=0; i<nr; i++) rarr2->set(i) = i*dr ;
778 for (int i=nr; i<2*nr; i++) rarr2->set(i) = rarr(i-nr) ;
779 }
780
781 int nr2 = coq ? 2*nr : nr ;
782
783 Tbl cylindre(nz, np, nr2) ;
784 cylindre.set_etat_qcq() ;
785 for(int iz=0; iz<nz; iz++) {
786 Tbl carre(ny,nx) ;
787 carre.set_etat_qcq() ;
788 Tbl cercle(np, nr2) ;
789 for (int iy=0; iy<ny; iy++)
790 for (int ix=0; ix<nx; ix++)
791 carre.set(iy,ix) = fdep(iy,ix,iz) ; // This should be optimized...
792 cercle = interpol2c(*x, *y, carre, coq ? *rarr2 : rarr, parr, inter_type) ;
793
794 for (int ip=0; ip<np; ip++)
795 for (int ir=0; ir<nr2; ir++)
796 cylindre.set(iz,ip,ir) = cercle(ip,ir) ;
797 }
798
799 for (int ip=0; ip<np; ip++) {
800 Tbl carre(nr2, nz) ;
801 carre.set_etat_qcq() ;
802 Tbl cercle(nt, nr) ;
803 for (int ir=0; ir<nr2; ir++)
804 for (int iz=0; iz<nz; iz++)
805 carre.set(ir,iz) = cylindre(iz,ip,ir) ;
806 cercle = interpol2c(*zr, coq ? *rarr2 : rarr , carre, rarr, tarr,
807 inter_type) ;
808 for (int it=0; it<nt; it++)
809 for (int ir=0; ir<nr; ir++)
810 farr.set(ip,it,ir) = cercle(it,ir) ;
811 }
812
813 if (coq) delete rarr2 ;
814 return farr ;
815
816}
817
818
819}
Active physical coordinates and mapping derivatives.
Definition coord.h:90
int type_p
Type of symmetry in :
Definition grille_val.h:114
int nfantome
The number of hidden cells (same on each side).
Definition grille_val.h:104
double * zrmin
Lower boundary for z (or r ) direction.
Definition grille_val.h:117
Dim_tbl dim
The dimensions of the grid.
Definition grille_val.h:102
Tbl * zr
Arrays containing the values of coordinate z (or r) on the nodes.
Definition grille_val.h:124
double get_zr(const int i) const
Read-only of a particular value of the coordinate z (or r ) at the nodes.
Definition grille_val.h:199
int type_t
Type of symmetry in :
Definition grille_val.h:109
Tbl interpol1(const Tbl &rdep, const Tbl &rarr, const Tbl &fdep, int flag, const int type_inter) const
Performs 1D interpolation.
double * zrmax
Higher boundary for z (or r ) direction.
Definition grille_val.h:120
double * xmax
Higher boundary for x dimension.
Definition grille_val.h:335
double * xmin
Lower boundary for x dimension.
Definition grille_val.h:333
double * ymin
Lower boundary for y dimension.
Definition grille_val.h:337
double * ymax
Higher boundary for y dimension.
Definition grille_val.h:339
Tbl interpol2c(const Tbl &xdep, const Tbl &zdep, const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const int type_inter) const
Same as before, but the coordinates of source points are passed explicitly (xdep, zdep).
virtual Tbl interpol3(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const Tbl &phiarr, const int type_inter) const
Performs 3D interpolation.
Tbl * y
Arrays containing the values of coordinate y on the nodes.
Definition grille_val.h:347
virtual Tbl interpol2(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const int type_inter) const
Performs 2D interpolation.
virtual bool compatible(const Map *mp, const int lmax, const int lmin=0) const
Checks if the spectral grid and mapping are compatible with the Grille_val caracteristics for the int...
Tbl * x
Arrays containing the values of coordinate x on the nodes.
Definition grille_val.h:343
virtual bool contenue_dans(const Map &mp, const int lmax, const int lmin=0) const
Checks if Gval_cart is contained inside the spectral grid/mapping within the domains [lmin,...
virtual bool compatible(const Map *mp, const int lmax, const int lmin=0) const
Checks if the spectral grid and mapping are compatible with the Grille_val caracteristics for the int...
virtual bool contenue_dans(const Map &mp, const int lmax, const int lmin=0) const
Checks if Gval_spher is contained inside the spectral grid/mapping within the domains [lmin,...
Tbl * phi
Arrays containing the values of coordinate on the nodes.
Definition grille_val.h:591
virtual Tbl interpol3(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const Tbl &phiarr, const int type_inter) const
Performs 3D interpolation.
virtual Tbl interpol2(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const int type_inter) const
Performs 2D interpolation.
Tbl * tet
Arrays containing the values of coordinate on the nodes.
Definition grille_val.h:587
Affine radial mapping.
Definition map.h:2042
Multi-domain grid.
Definition grilles.h:279
int get_type_t() const
Returns the type of sampling in the direction: SYM : : symmetry with respect to the equatorial pl...
Definition grilles.h:502
int get_np(int l) const
Returns the number of points in the azimuthal direction ( ) in domain no. l.
Definition grilles.h:479
int get_type_p() const
Returns the type of sampling in the direction: SYM : : symmetry with respect to the transformatio...
Definition grilles.h:512
int get_nt(int l) const
Returns the number of points in the co-latitude direction ( ) in domain no. l.
Definition grilles.h:474
int get_nr(int l) const
Returns the number of points in the radial direction ( ) in domain no. l.
Definition grilles.h:469
Basic array class.
Definition tbl.h:161
Dim_tbl dim
Number of dimensions, size,...
Definition tbl.h:172
int get_ndim() const
Gives the number of dimensions (ie dim.ndim).
Definition tbl.h:400
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition tbl.C:364
double & set(int i)
Read/write of a particular element (index i) (1D case).
Definition tbl.h:281
double * t
The array of double.
Definition tbl.h:173
int get_dim(int i) const
Gives the i-th dimension (ie dim.dim[i]).
Definition tbl.h:403
Cmp sin(const Cmp &)
Sine.
Definition cmp_math.C:72
Cmp cos(const Cmp &)
Cosine.
Definition cmp_math.C:97
Lorene prototypes.
Definition app_hor.h:67
Coord y
y coordinate centered on the grid
Definition map.h:739
Map(const Mg3d &)
Constructor from a multi-domain 3D grid.
Definition map.C:142
Coord x
x coordinate centered on the grid
Definition map.h:738