LORENE
boundfree_tensBC.C
1 
2 // Header Lorene:
3 #include "nbr_spx.h"
4 #include "utilitaires.h"
5 #include "graphique.h"
6 #include "math.h"
7 #include "metric.h"
8 #include "param.h"
9 #include "param_elliptic.h"
10 #include "tensor.h"
11 #include "diff.h"
12 #include "proto.h"
13 
14 namespace Lorene {
15 // Resolution of tensorial equation (N^2/Psi^4)Delta(hij) - LbLbhij = Sij, using degenerate elliptic solver.
16 // Here assumption is made that no boundary condition has to be enforced, mainly Beta^i*s_i = N/psi^2
17 
18 Sym_tensor boundfree_tensBC ( Sym_tensor source, Vector Beta, Scalar Psi, Scalar Nn, Sym_tensor hij_guess, double precision, int loopmax) {
19  cout << "================================================================" << endl;
20  cout << "STARTING THE SUBITERATION FOR THE CONFORMAL METRIC" << endl;
21  cout << " iteration parameters are the following: " << endl;
22  cout << " convergence precision required:" << precision << endl;
23  cout << " max number of global steps :" << loopmax << endl;
24  cout << "================================================================" << endl;
25 
26  // Construction of a multi-grid (Mg3d)
27  // -----------------------------------
28  const int nz = (*source.get_mp().get_mg()).get_nzone(); // Number of domains
29  int nr = (*source.get_mp().get_mg()).get_nr(1); // Number of collocation points in r in each domain
30  const Coord& rr = source.get_mp().r;
31  Scalar rrr (source.get_mp()) ;
32  rrr = rr ;
33  rrr.std_spectral_base();
34 
35  const Metric_flat& mets = (source.get_mp()).flat_met_spher() ;
36 
38 
39  Sym_tensor hij = hij_guess;
40  Sym_tensor hij_new = hij;
41 
42  Scalar n2sp4 = (Nn/(Psi*Psi))*(Nn/(Psi*Psi)) ; // Scale factor in front of Poisson Equation.
43  n2sp4.std_spectral_base();
44 
45  // Resolution variables
46  Scalar khi = hij(1,1);
47  if (khi.get_etat() == ETATZERO) {
48  khi.annule_hard() ;
49  khi.set_dzpuis(4) ;
50  khi.std_spectral_base() ;
51  }
52  khi.set_spectral_va().ylm();
53  khi.mult_r();
54  khi.mult_r_dzpuis(1);
55  Scalar mmu = hij.mu();
56  if (mmu.get_etat() == ETATZERO) {
57  mmu.annule_hard() ;
58  mmu.std_spectral_base() ;
59  }
60  mmu.set_spectral_va().ylm();
61  Scalar etta = hij.eta();
62  if (etta.get_etat() == ETATZERO) {
63  etta.annule_hard() ;
64  etta.std_spectral_base() ;
65  }
66  etta.set_spectral_va().ylm();
67  Scalar Aa = hij.compute_A();
68  if (Aa.get_etat() == ETATZERO) {
69  Aa.annule_hard() ;
70  Aa.std_spectral_base() ;
71  }
72  Aa.set_spectral_va().ylm();
73  Scalar Bt = hij.compute_tilde_B();
74  if (Bt.get_etat() == ETATZERO) {
75  Bt.annule_hard() ;
76  Bt.std_spectral_base() ;
77  }
78  Bt.set_spectral_va().ylm();
79  Scalar hh = hij.trace(mets);
80  if (hh.get_etat() == ETATZERO) {
81  hh.annule_hard() ;
82  hh.std_spectral_base() ;
83  }
84 
85  //Fitting scalar
86  Scalar fit1(source.get_mp()); fit1.set_etat_qcq();
87 
88  // For storing the result of inversion
89  Scalar Aanew (source.get_mp()); Aanew.annule_hard(); Aanew.std_spectral_base();
90  Scalar Btnew (source.get_mp()); Btnew.annule_hard(); Btnew.std_spectral_base();
91 
92 
93  // Construction of sources for the next iteration
94 
95  Sym_tensor LbLbhij = (hij.derive_lie(Beta)).derive_lie(Beta);
96  hij.annule_domain(0);
97  LbLbhij.annule_domain(0);
98  LbLbhij.inc_dzpuis(1);
99 
100  Sym_tensor source_hij = source/n2sp4;
101  Scalar sourcetrace = source_hij.trace(mets);
102  Scalar Bttrace = source_hij.compute_tilde_B();
103 
104  Sym_tensor source_hij2 = LbLbhij/n2sp4;
105 
106  Scalar Btsource2 = source_hij2.compute_tilde_B();
107 
108  Scalar source_Bt2 = Bttrace + Btsource2;
109 
110  source_hij = source_hij + source_hij2;
111 
112  Scalar r2LbLbrr = LbLbhij(1,1);
113  r2LbLbrr.mult_r();
114  r2LbLbrr.mult_r();
115  Scalar LbLbmu = LbLbhij.mu();
116 
117  Scalar source_khi2 = source_hij(1,1);
118  source_khi2.mult_r();
119  source_khi2.mult_r();
120 
121  Scalar source_mu2 = source_hij.mu();
122  Scalar source_eta2 = source_hij.eta();
123 
124  Scalar source_A2 = source_hij.compute_A();
125 
126 
127  source_khi2.annule_domain(0);
128  source_mu2.annule_domain(0);
129  source_A2.annule_domain(0);
130  source_Bt2.annule_domain(0);
131  source_eta2.annule_domain(0);
132 
133  // source_A2.set_spectral_va().set_base( Aa.set_spectral_va().get_base());
134  // source_Bt2.set_spectral_va().set_base( Bt.set_spectral_va().get_base());
135 
136 
137 
139  Scalar Betacarre = (Beta(1)*Beta(1))/n2sp4 ;
140 
141  double fitd1 = (Betacarre.val_grid_point(1,0,0,nr-1) - Betacarre.val_grid_point(1,0,0,0))/(rrr.val_grid_point(1,0,0,nr-1) - rrr.val_grid_point(1,0,0,0)) ;
142 
143 // double error = 0.; // Voluntary error on fit.
144 // fitd1 += error;
145 
146 
147  int nrint = (nr-1)/2 ;
148  double ampl_r = (rrr.val_grid_point(1,0,0, nr -1) - rrr.val_grid_point(1,0,0 ,0))/2.;
149 
150  Scalar approx(source.get_mp());
151  approx.annule_hard();
152  approx.std_spectral_base();
153 
154 
155 
156  fit1 = fitd1*(rrr-1.) +1.;
157  // First order approximation
158  approx.set_domain(1)= fit1.set_domain(1); // MAKE PARTICULAR FOR ETATUN; DECLARE FIT1?2?3 FIRST TO BE CLEAN.
159 
160 
161 
162  //Second order approximation
163  Scalar firststep = Betacarre - approx;
164 
165  double ampli = firststep.val_grid_point(1,0,0,nrint);
166  double fit2d1 = - ampli/(ampl_r* ampl_r);
167 
168 
169 
170  approx.set_domain(1) += (fit2d1*(rrr - 1.)*(rrr - rrr.val_grid_point(1,0,0,nr-1))).set_domain(1);
171 
172 
173  double fit0d2 = approx.val_grid_point(1,0,0,nr -1);
174  double fit1d2 = (Betacarre.val_grid_point(2,0,0,nr-1) - fit0d2)/(rrr.val_grid_point(2,0,0,nr-1)- rrr.val_grid_point(2,0,0,0));
175  double fit0d3 = Betacarre.val_grid_point(3,0,0,0);
176  double fit1d3 = ( - fit0d3)/(rrr.val_grid_point(3,0,0,nr-1)- rrr.val_grid_point(3,0,0,0));
177 
178  approx.set_domain(2) = (fit0d2 + fit1d2*(rrr - rrr.val_grid_point(2,0,0,0))).set_domain(2);
179  approx.set_domain(3) = (fit0d3 + fit1d3*(rrr - rrr.val_grid_point(3,0,0,0))).set_domain(3);
180 
181 
182 
183  for(int ii=1; ii<=3; ii++){
184 
185  source_khi2.set_domain(ii) += (-approx*(khi.dsdr().dsdr())).set_domain(ii);
186 
187  source_mu2.set_domain(ii) += (-approx*(mmu.dsdr().dsdr())).set_domain(ii);
188 
189  source_eta2.set_domain(ii) += (-approx*(etta.dsdr().dsdr())).set_domain(ii);
190 
191  source_A2.set_domain(ii) += (-approx*(Aa.dsdr().dsdr())).set_domain(ii);
192 
193  source_Bt2.set_domain(ii) += (-approx*(Bt.dsdr().dsdr())).set_domain(ii);
194 
195  }
196 
197 
198 
199  // Convergence markers
200  Scalar Aa_old(source.get_mp());
201  Scalar Bt_old(source.get_mp());
202 
203 
204  // Parameters for the iteration
205  cout <<"==================================================================================" << endl;
206  cout << "amplitude for the tensor equation source (used as scaling for convergence marker)" << endl;
207  cout <<"==================================================================================" << endl;
208  double scale = max(maxabs(source));
209  double diff_ent = 0.15 ; // Initialisation of the difference marker between two iterations on some value
210 
215 
216  for (int mer = 0; (diff_ent>precision) && (mer< loopmax) ; mer++) {
217  double relax = 0.15; // Global relaxation parameter
218 
219 // Résolution for variables A and tilde(B)
220  tensorelliptic (source_A2, Aanew , fitd1, fit2d1, fit0d2, fit1d2, fit0d3, fit1d3);
221  tensorellipticBt (source_Bt2, Btnew, fitd1, fit2d1, fit0d2, fit1d2, fit0d3, fit1d3);
222 
223 
224  Aa = Aanew ;
225  Bt = Btnew ; // No relaxation on these variables; it will be done globally on the tensor.
226 
229 
230  Scalar essaiA = Aanew.laplacian() - approx*(Aanew.dsdr().dsdr());
231  essaiA.annule_domain(0);
232  Scalar bobofA = essaiA -source_A2 ;
233  bobofA.set_spectral_va().ylm() ;
234  // maxabs (bobofA);
235  // bobofA.spectral_display();
236  bobofA.set_spectral_va().ylm_i();
237 
239 
240  //-------------------------------------------
241  // Retrieving the tensor hij by Dirac inversion
242  //------------------------------------------
243 
245  // Magnetic part
246 
247  Scalar mmuA = mmu;
248  Scalar mmuAsr = mmuA; mmuAsr.div_r();
249  Scalar xxA(source.get_mp()); xxA.annule_hard(); xxA.std_spectral_base();
250 
251  const Scalar AA = Aa;
252  Param* par_bc = 0x0;
253  Sym_tensor_trans hijt(source.get_mp(), source.get_mp().get_bvect_spher(), mets);
254  hijt = hij;
255  hijt.sol_Dirac_A2 ( AA , mmuAsr, xxA, source_mu2, par_bc);
256 
257 
258  // Monitoring A and Hmu;
259  Scalar musrsr = mmuAsr; musrsr.div_r_dzpuis(2);
260  Aanew = xxA.dsdr() - musrsr;
261  Scalar xxsr = xxA; xxsr.div_r_dzpuis(2);
262  // Scalar Hmut = 3.*musrsr + mmuAsr.dsdr() + 2.*xxsr + xxsr.lapang();
263 
265  //Electric part
266 
267  Scalar hrrBC (source.get_mp()); hrrBC.annule_hard();
268  Scalar wwBC(source.get_mp()); wwBC.annule_hard();
269  Scalar tilde_etaBC(source.get_mp()); tilde_etaBC.annule_hard();
270 
271  Scalar source_khi3 = source_khi2;
272  source_khi3.annule_domain(nz-1);
273  source_khi3 += 2*hh;
274  source_khi3.set_spectral_va().ylm();
275 
276  hijt.sol_Dirac_BC3( Bt, hh, hrrBC , tilde_etaBC , wwBC , source_khi3, source_eta2, par_bc, par_bc) ;
277 
278  // Tensor reconstruction
279  hij_new.set_auxiliary(hrrBC, tilde_etaBC, mmuAsr, wwBC, xxA, hh -hrrBC);
280 
281  hij= relax*hij_new + (1 - relax)*hij ; // Global relaxation (opposite to relaxation on resolution variables).
282 
283  // Calculation of updated trace.
284  hh = (1 + hij(1,1))*( hij(2,3)*hij(2,3) - hij(2,2)*hij(3,3) )
285  + hij(1,2)*hij(1,2)*(1 + hij(3,3))
286  + hij(1,3)*hij(1,3)*(1 + hij(2,2))
287  - hij(1,1)*(hij(2,2) + hij(3,3)) - 2*hij(1,2)*hij(1,3)*hij(2,3) ;
288 
289  khi = hij(1,1);
290  khi.mult_r();
291  khi.mult_r_dzpuis(0);
292  mmu = hij.mu();
293  etta = hij.eta();
294 
295  Aa = hij.compute_A();
296  Bt = hij.compute_tilde_B();
297 
298  if (mer >=1){
299  Aa.set_spectral_va().ylm();
300  Bt.set_spectral_va().ylm();
301  Aa_old.set_spectral_va().ylm();
302  Bt_old.set_spectral_va().ylm();
303 
304  diff_ent = max(maxabs (Bt - Bt_old))/scale; // Convergence marker
305  }
306  Aa_old = Aa;
307  Bt_old = Bt;
308 
309 
310  // Update of sources for the next loop
311  LbLbhij = (hij.derive_lie(Beta)).derive_lie(Beta);
312  LbLbhij.inc_dzpuis(1);
313  r2LbLbrr = LbLbhij(1,1);
314  r2LbLbrr.mult_r();
315  r2LbLbrr.mult_r();
316  LbLbmu = LbLbhij.mu();
317 
318 
319  source_hij = source/n2sp4;
320 
321  Bttrace = source_hij.compute_tilde_B();
322 
323  source_hij2 = LbLbhij/n2sp4;
324 
325  Btsource2 = source_hij2.compute_tilde_B();
326 
327  source_Bt2 = Bttrace + Btsource2;
328 
329  source_hij = source_hij + source_hij2;
330 
331  source_khi2 = source_hij(1,1);
332  source_khi2.mult_r();
333  source_khi2.mult_r();
334  source_mu2 = source_hij.mu();
335  source_eta2 = source_hij.eta();
336  source_A2= source_hij.compute_A();
337 
338 
339  source_A2.set_spectral_va().set_base( Aa.set_spectral_va().get_base());
340  source_Bt2.set_spectral_va().set_base( Bt.set_spectral_va().get_base());
341 
342  for(int ii=1; ii<=3; ii++){
343  source_khi2.set_domain(ii) += (-approx*(khi.dsdr().dsdr())).set_domain(ii);
344  source_mu2.set_domain(ii) += (-approx*(mmu.dsdr().dsdr())).set_domain(ii);
345  source_eta2.set_domain(ii) += (-approx*(etta.dsdr().dsdr())).set_domain(ii);
346  source_A2.set_domain(ii) += (-approx*(Aa.dsdr().dsdr())).set_domain(ii);
347  source_Bt2.set_domain(ii) += (-approx*(Bt.dsdr().dsdr())).set_domain(ii);
348  }
349  source_khi2.annule_domain(0);
350  source_mu2.annule_domain(0);
351  source_eta2.annule_domain(0);
352  source_A2.annule_domain(0);
353  source_Bt2.annule_domain(0);
354 
355 
356 
357 // cout << "real A resolution?" << endl;
358 // Sym_tensor mucorrect = LbLbhij + source;
359 // mucorrect = mucorrect/n2sp4;
360 // Scalar AAs = mucorrect.compute_A();
361 // AAs.annule_domain(nz-1);
362 // Aa.annule_domain(nz-1);
363 // Scalar Aa2 = Aa.laplacian();
364 // Scalar voirA = AAs - Aa2;
365 
366 // voirA.set_spectral_va().ylm_i();
367 // // des_meridian(voirA, 1.00001*Rhor, Rout,"diffA", 1);
368 // voirA.set_spectral_va().ylm();
369 
370 
371 // maxabs (voirA);
372 // voirA.spectral_display("voirA", 1.e-9);
373 
374 
375  cout << "diff_ent" << diff_ent << endl;
376  cout << mer << endl;
377 
378 
379  }
380 
381  return hij;
382  }
383 
384 
385 
386 
387 
388 
389 }
Tbl maxabs(const Tensor &aa, const char *comment=0x0, ostream &ost=cout, bool verb=true)
Maxima in each domain of the absolute values of the tensor components.
Lorene prototypes.
Definition: app_hor.h:67
Tbl max(const Cmp &)
Maximum values of a Cmp in each domain.
Definition: cmp_math.C:438
const Map & get_mp() const
Returns the mapping.
Definition: tensor.h:874
Coord r
r coordinate centered on the grid
Definition: map.h:730