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
102 namespace Lorene {
103 bool 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
174 bool 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 )
220 bool 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 )
280 bool 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
318 Tbl 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
479 Tbl 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 
524 struct Point {
525  double x ;
526  int l ;
527  int k ;
528 };
529 
530 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
531 
532 int 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 
538 Tbl 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 
544 Tbl 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
706 Tbl 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 
753 Tbl 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 }
int get_type_p() const
Returns the type of sampling in the direction: SYM : : symmetry with respect to the transformatio...
Definition: grilles.h:512
double * xmax
Higher boundary for x dimension.
Definition: grille_val.h:335
virtual Tbl interpol2(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const int type_inter) const
Performs 2D interpolation.
int get_np(int l) const
Returns the number of points in the azimuthal direction ( ) in domain no. l.
Definition: grilles.h:479
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...
Lorene prototypes.
Definition: app_hor.h:67
const Mg3d * get_mg() const
Gives the Mg3d on which the mapping is defined.
Definition: map.h:783
Tbl * y
Arrays containing the values of coordinate y on the nodes.
Definition: grille_val.h:347
double & set(int i)
Read/write of a particular element (index i) (1D case)
Definition: tbl.h:301
Base class for coordinate mappings.
Definition: map.h:688
Tbl * tet
Arrays containing the values of coordinate on the nodes.
Definition: grille_val.h:587
double * zrmax
Higher boundary for z (or r ) direction.
Definition: grille_val.h:120
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
double * zrmin
Lower boundary for z (or r ) direction.
Definition: grille_val.h:117
Cmp cos(const Cmp &)
Cosine.
Definition: cmp_math.C:97
double * ymax
Higher boundary for y dimension.
Definition: grille_val.h:339
int type_t
Type of symmetry in :
Definition: grille_val.h:109
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...
double * xmin
Lower boundary for x dimension.
Definition: grille_val.h:333
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition: tbl.C:364
double * ymin
Lower boundary for y dimension.
Definition: grille_val.h:337
int get_ndim() const
Gives the number of dimensions (ie dim.ndim)
Definition: tbl.h:420
Tbl * x
Arrays containing the values of coordinate x on the nodes.
Definition: grille_val.h:343
Dim_tbl dim
Number of dimensions, size,...
Definition: tbl.h:175
double * t
The array of double.
Definition: tbl.h:176
Tbl * zr
Arrays containing the values of coordinate z (or r) on the nodes.
Definition: grille_val.h:124
int get_dim(int i) const
Gives the i-th dimension (ie dim.dim[i])
Definition: tbl.h:423
virtual Tbl interpol2(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const int type_inter) const
Performs 2D interpolation.
Active physical coordinates and mapping derivatives.
Definition: coord.h:90
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
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.
int ndim
Number of dimensions of the Tbl: can be 1, 2 or 3.
Definition: dim_tbl.h:101
int nfantome
The number of hidden cells (same on each side)
Definition: grille_val.h:104
int get_nr(int l) const
Returns the number of points in the radial direction ( ) in domain no. l.
Definition: grilles.h:469
Multi-domain grid.
Definition: grilles.h:279
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...
Dim_tbl dim
The dimensions of the grid.
Definition: grille_val.h:102
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 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)...
Cmp sin(const Cmp &)
Sine.
Definition: cmp_math.C:72
Basic array class.
Definition: tbl.h:164
int get_nt(int l) const
Returns the number of points in the co-latitude direction ( ) in domain no. l.
Definition: grilles.h:474
Tbl interpol1(const Tbl &rdep, const Tbl &rarr, const Tbl &fdep, int flag, const int type_inter) const
Performs 1D interpolation.
int type_p
Type of symmetry in :
Definition: grille_val.h:114
int * dim
Array of dimensions (size: ndim).
Definition: dim_tbl.h:102
Coord r
r coordinate centered on the grid
Definition: map.h:736
virtual Tbl interpol3(const Tbl &fdep, const Tbl &rarr, const Tbl &tetarr, const Tbl &phiarr, const int type_inter) const
Performs 3D interpolation.