LORENE
map_af_poisson2d.C
1 /*
2  * Method of the class Map_af for the resolution of the 2-D Poisson
3  * equation.
4  *
5  * (see file map.h for documentation).
6  */
7 
8 /*
9  * Copyright (c) 2000-2001 Eric Gourgoulhon
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: map_af_poisson2d.C,v 1.8 2026/03/04 15:47:04 j_novak Exp $
34  * $Log: map_af_poisson2d.C,v $
35  * Revision 1.8 2026/03/04 15:47:04 j_novak
36  * Added 'verbose' flag (true by default) to limit the output of poisson solvers.
37  *
38  * Revision 1.7 2016/12/05 16:17:57 j_novak
39  * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
40  *
41  * Revision 1.6 2014/10/13 08:53:02 j_novak
42  * Lorene classes and functions now belong to the namespace Lorene.
43  *
44  * Revision 1.5 2012/09/04 14:53:28 j_novak
45  * Replacement of the FORTRAN version of huntm by a C one.
46  *
47  * Revision 1.4 2012/08/12 17:48:36 p_cerda
48  * Magnetstar: New classes for magnetstar. Allowing for non-equatorial symmetry in Etoile et al. Adding B_phi in Et_rot_mag.
49  *
50  * Revision 1.3 2002/09/09 13:54:20 e_gourgoulhon
51  *
52  * Change of name of the Fortran subroutines
53  * poisson2d -> poiss2d
54  * poisson2di -> poiss2di
55  * to avoid any clash with Map::poisson2d and Map::poisson2di
56  *
57  * Revision 1.2 2002/09/09 13:00:39 e_gourgoulhon
58  * Modification of declaration of Fortran 77 prototypes for
59  * a better portability (in particular on IBM AIX systems):
60  * All Fortran subroutine names are now written F77_* and are
61  * defined in the new file C++/Include/proto_f77.h.
62  *
63  * Revision 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon
64  * LORENE
65  *
66  * Revision 2.1 2000/10/11 15:15:26 eric
67  * 1ere version operationnelle.
68  *
69  * Revision 2.0 2000/10/09 13:47:10 eric
70  * *** empty log message ***
71  *
72  *
73  * $Header: /cvsroot/Lorene/C++/Source/Map/map_af_poisson2d.C,v 1.8 2026/03/04 15:47:04 j_novak Exp $
74  *
75  */
76 
77 // Header Lorene:
78 #include "map.h"
79 #include "cmp.h"
80 #include "param.h"
81 #include "proto_f77.h"
82 
83 //*****************************************************************************
84 
85 namespace Lorene {
86 
87 void Map_af::poisson2d(const Cmp& source_mat, const Cmp& source_quad,
88  Param& par, Cmp& uu, bool) const {
89 
90  assert(source_mat.get_etat() != ETATNONDEF) ;
91  assert(source_quad.get_etat() != ETATNONDEF) ;
92  assert(source_mat.get_mp()->get_mg() == mg) ;
93  assert(source_quad.get_mp()->get_mg() == mg) ;
94  assert(uu.get_mp()->get_mg() == mg) ;
95 
96  assert( source_quad.check_dzpuis(4) ) ;
97 
98  int mpsymm = uu.get_mp()->get_mg()->get_type_t();
99 
100  double& lambda = par.get_double_mod(0) ;
101 
102  // Special case of a vanishing source
103  // ----------------------------------
104 
105  if ( (source_mat.get_etat() == ETATZERO)
106  && (source_quad.get_etat() == ETATZERO) ) {
107 
108  uu = 0 ;
109  lambda = 1 ;
110  return ;
111  }
112 
113  // ---------------------------------------------------------------------
114  // Preparation of the parameters for the Fortran subroutines F77_poisson2d
115  // and F77_poisson2di
116  // ---------------------------------------------------------------------
117 
118  int nz = mg->get_nzone() ;
119  int np1 = 1 ; // Axisymmetry enforced
120  int nt = mg->get_nt(0) ;
121  int nt2 = 0 ;
122 
123  switch ( mpsymm ){
124  case SYM: {
125  nt2 = 2*nt - 1 ; // Number of points for the theta sampling
126  break; // in [0,Pi], instead of [0,Pi/2]
127  }
128  case NONSYM: {
129  nt2 = nt;
130  break;
131  }
132  }
133 
134 
135  // Array NDL
136  // ---------
137  int* ndl = new int[nz+4] ;
138  ndl[0] = nz ;
139  for (int l=0; l<nz; l++) {
140  ndl[1+l] = mg->get_nr(l) ;
141  }
142  ndl[1+nz] = nt2 ;
143  ndl[2+nz] = np1 ;
144  ndl[3+nz] = nz ;
145 
146  // Array INDD
147  // ----------
148  int* indd = new int[nz] ;
149  for (int l=0; l<nz; l++) {
150  switch ( mg->get_type_r(l) ) {
151  case RARE : {
152  indd[l] = 0 ;
153  break ;
154  }
155  case FIN : {
156  indd[l] = 1 ;
157  break ;
158  }
159  case UNSURR : {
160  indd[l] = 2 ;
161  break ;
162  }
163  default : {
164  cerr << "Map_af::poisson2d: unknown type_r !" << endl ;
165  abort() ;
166  break ;
167  }
168  }
169  }
170 
171  // Parameters NDR, NDT, NDP and NDZ
172  // --------------------------------
173  int nrmax = 0 ;
174  for (int l=0; l<nz ; l++) {
175  nrmax = ( ndl[1+l] > nrmax ) ? ndl[1+l] : nrmax ;
176  }
177  int ndr = nrmax + 5 ; // Le +5 est impose par les routines de resolution
178  // de l'equation de Poisson du type gr2p3s_
179  int ndt = nt2 + 2 ;
180  int ndp = np1 + 2 ;
181  int ndz = nz ;
182 
183  // Array ERRE
184  // ----------
185 
186  double* erre = new double [ndz*ndr] ;
187 
188  for (int l=0; l<nz; l++) {
189  for (int i=0; i<ndl[1+l]; i++) {
190  double xr = mg->get_grille3d(l)->x[i] ;
191  erre[ ndr*l + i ] = alpha[l] * xr + beta[l] ;
192  }
193  }
194 
195  // Arrays containing the data
196  // --------------------------
197 
198  int ndrt = ndr*ndt ;
199  int ndrtp = ndr*ndt*ndp ;
200  int taille = ndrtp*ndz ;
201 
202  double* tsou_m = new double[ taille ] ;
203  double* tsou_q = new double[ taille ] ;
204  double* tuu = new double[ taille ] ;
205 
206  // Initialisation to zero :
207  for (int i=0; i<taille; i++) {
208  tsou_m[i] = 0 ;
209  tsou_q[i] = 0 ;
210  tuu[i] = 0 ;
211  }
212 
213  // Copy of source_mat into tsou_m
214  // ------------------------------
215  const Valeur& va_m = source_mat.va ;
216  assert(va_m.get_etat() == ETATQCQ) ;
217  va_m.coef_i() ;
218  const Mtbl* s_m = va_m.c ;
219  assert(s_m->get_etat() == ETATQCQ) ;
220 
221  Base_val base_s = va_m.base ;
222 
223  for (int l=0; l<nz; l++) {
224  int nr = mg->get_nr(l) ;
225  int nrt = nr*nt ;
226  if (s_m->t[l]->get_etat() == ETATZERO) {
227  for (int k=0; k<np1; k++) {
228  for (int j=0; j<nt; j++) {
229  for (int i=0; i<nr; i++) {
230  tsou_m[ndrtp*l + ndrt*k + ndr*j + i] = 0 ;
231  // point symetrique par rapport au plan theta = pi/2 :
232  if ( mpsymm == SYM ) tsou_m[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = 0 ;
233  }
234  }
235  }
236 
237  }
238  else {
239  assert( s_m->t[l]->get_etat() == ETATQCQ ) ;
240  for (int k=0; k<np1; k++) {
241  for (int j=0; j<nt; j++) {
242  for (int i=0; i<nr; i++) {
243  double xx = s_m->t[l]->t[nrt*k + nr*j + i] ;
244  tsou_m[ndrtp*l + ndrt*k + ndr*j + i] = xx ;
245  // point symetrique par rapport au plan theta = pi/2 :
246  if ( mpsymm == SYM ) tsou_m[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = xx ;
247  }
248  }
249  }
250  } // End of case etat != ETATZERO
251  }
252 
253  // Copy of source_quad into tsou_q
254  // -------------------------------
255 
256  if (source_quad.get_etat() != ETATZERO) {
257 
258  const Valeur& va_q = source_quad.va ;
259  assert(va_q.get_etat() == ETATQCQ) ;
260  va_q.coef_i() ;
261  const Mtbl* s_q = va_q.c ;
262 
263  assert( va_q.base == base_s ) ;
264 
265  assert(s_q->get_etat() == ETATQCQ) ;
266 
267  for (int l=0; l<nz; l++) {
268  int nr = mg->get_nr(l) ;
269  int nrt = nr*nt ;
270  if (s_q->t[l]->get_etat() == ETATZERO) {
271  for (int k=0; k<np1; k++) {
272  for (int j=0; j<nt; j++) {
273  for (int i=0; i<nr; i++) {
274  tsou_q[ndrtp*l + ndrt*k + ndr*j + i] = 0 ;
275  // point symetrique par rapport au plan theta = pi/2 :
276  if ( mpsymm == SYM ) tsou_q[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = 0 ;
277  }
278  }
279  }
280 
281  }
282  else {
283  assert( s_q->t[l]->get_etat() == ETATQCQ ) ;
284  for (int k=0; k<np1; k++) {
285  for (int j=0; j<nt; j++) {
286  for (int i=0; i<nr; i++) {
287  double xx = s_q->t[l]->t[nrt*k + nr*j + i] ;
288  tsou_q[ndrtp*l + ndrt*k + ndr*j + i] = xx ;
289  // point symetrique par rapport au plan theta = pi/2 :
290  if ( mpsymm == SYM ) tsou_q[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = xx ;
291  }
292  }
293  }
294  } // End of case s_q->t[l]->etat != ETATZERO
295  }
296 
297  } // End of case source_quad.etat != ETATZERO
298 
299  //-----------------------------------------------------------
300  // Call of the Fortran subroutine poisson2d_ or poisson2di_
301  //-----------------------------------------------------------
302 
303  int base_t = (va_m.base).get_base_t(0) ;
304 
305  Base_val base_uu(nz) ; // Output spectral bases
306 
307  switch (base_t) {
308 
309  case T_COS :
310  case T_COS_P : {
311 
312  double lambda0 ;
313 
314  F77_poiss2d(ndl, &ndr, &ndt, &ndp, indd, erre, tsou_m, tsou_q,
315  &lambda0, tuu) ;
316 
317  base_uu = base_s ; // output bases = input bases
318 
319  lambda = lambda0 ;
320  break ;
321  }
322  case T_SIN :
323  case T_SIN_I : {
324 
325  double* tsou = new double[taille] ;
326  for (int i=0; i<taille; i++) {
327  tsou[i] = tsou_m[i] + tsou_q[i] ;
328  }
329 
330  F77_poiss2di(ndl, &ndr, &ndt, &ndp, indd, erre, tsou, tuu) ;
331 
332  base_uu = base_s ; // output bases = input bases
333 
334  lambda = double(1) ;
335 
336  delete [] tsou ;
337  break ;
338  }
339 
340  default : {
341  cerr << "Map_af::poisson2d : unkown theta basis !" << endl ;
342  cerr << " basis : " << hex << base_t << endl ;
343  abort() ;
344  break ;
345  }
346  }
347 
348  //-------------------------------
349  // Copy of tuu into uu
350  //-------------------------------
351 
352  uu.allocate_all() ;
353  (uu.va).set_etat_c_qcq() ; // To make sure that the coefficients are
354  // deleted
355 
356  for (int l=0; l<nz; l++) {
357  int nr = mg->get_nr(l) ;
358  for (int k=0; k<mg->get_np(l); k++) {
359  for (int j=0; j<nt; j++) {
360  for (int i=0; i<nr; i++) {
361  uu.set(l, k, j, i) = tuu[ndrtp*l + ndr*j + i] ;
362  }
363  }
364  }
365  }
366 
367  (uu.va).set_base( base_uu ) ; // Bases for spectral expansions
368 
369  uu.set_dzpuis(0) ;
370 
371  // Cleaning
372  // --------
373 
374  delete [] ndl ;
375  delete [] indd ;
376  delete [] erre ;
377  delete [] tsou_m ;
378  delete [] tsou_q ;
379  delete [] tuu ;
380 
381 
382 }
383 
384 
385 }
const Map * get_mp() const
Returns the mapping.
Definition: cmp.h:904
const Grille3d * get_grille3d(int l) const
Returns a pointer on the 3D mono-grid for domain no. l.
Definition: grilles.h:519
double & get_double_mod(int position=0) const
Returns the reference of a stored modifiable double .
Definition: param.C:501
Component of a tensorial field *** DEPRECATED : use class Scalar instead ***.
Definition: cmp.h:449
int get_np(int l) const
Returns the number of points in the azimuthal direction ( ) in domain no. l.
Definition: grilles.h:481
Multi-domain array.
Definition: mtbl.h:118
double * alpha
Array (size: mg->nzone ) of the values of in each domain.
Definition: map.h:2108
Lorene prototypes.
Definition: app_hor.h:67
const Mg3d * get_mg() const
Gives the Mg3d on which the mapping is defined.
Definition: map.h:791
int get_etat() const
Returns the logical state.
Definition: cmp.h:902
void coef_i() const
Computes the physical value of *this.
int get_type_t() const
Returns the type of sampling in the direction: SYM : : symmetry with respect to the equatorial pl...
Definition: grilles.h:504
#define T_COS
dev. cos seulement
Definition: type_parite.h:196
Values and coefficients of a (real-value) function.
Definition: valeur.h:297
int get_etat() const
Gives the logical state.
Definition: tbl.h:414
double * x
Array of values of at the nr collocation points.
Definition: grilles.h:212
#define T_SIN
dev. sin seulement
Definition: type_parite.h:198
int get_etat() const
Gives the logical state.
Definition: mtbl.h:277
int get_etat() const
Returns the logical state.
Definition: valeur.h:760
#define T_COS_P
dev. cos seulement, harmoniques paires
Definition: type_parite.h:200
Base_val base
Bases on which the spectral expansion is performed.
Definition: valeur.h:315
double * t
The array of double.
Definition: tbl.h:176
Mtbl * c
Values of the function at the points of the multi-grid.
Definition: valeur.h:309
Parameter storage.
Definition: param.h:125
double * beta
Array (size: mg->nzone ) of the values of in each domain.
Definition: map.h:2110
int get_nzone() const
Returns the number of domains.
Definition: grilles.h:467
int get_nr(int l) const
Returns the number of points in the radial direction ( ) in domain no. l.
Definition: grilles.h:471
void allocate_all()
Sets the logical state to ETATQCQ (ordinary state) and performs the memory allocation of all the elem...
Definition: cmp.C:326
const Mg3d * mg
Pointer on the multi-grid Mgd3 on which this is defined.
Definition: map.h:702
Bases of the spectral expansions.
Definition: base_val.h:325
Tbl & set(int l)
Read/write of the value in a given domain.
Definition: cmp.h:727
bool check_dzpuis(int dzi) const
Returns false if the last domain is compactified and *this is not zero in this domain and dzpuis is n...
Definition: cmp.C:718
void set_dzpuis(int)
Set a value to dzpuis.
Definition: cmp.C:657
int get_nt(int l) const
Returns the number of points in the co-latitude direction ( ) in domain no. l.
Definition: grilles.h:476
virtual void poisson2d(const Cmp &source_mat, const Cmp &source_quad, Param &par, Cmp &uu, bool verbose=true) const
Computes the solution of a 2-D Poisson equation.
int get_type_r(int l) const
Returns the type of sampling in the radial direction in domain no.
Definition: grilles.h:493
Tbl ** t
Array (size nzone ) of pointers on the Tbl &#39;s.
Definition: mtbl.h:132
#define T_SIN_I
dev. sin seulement, harmoniques impaires
Definition: type_parite.h:206
Valeur va
The numerical value of the Cmp.
Definition: cmp.h:467