boundfree_tensBC.C

00001 
00002 // Header Lorene:
00003 #include "nbr_spx.h"
00004 #include "utilitaires.h"
00005 #include "graphique.h"
00006 #include "math.h"
00007 #include "metric.h"
00008 #include "param.h"
00009 #include "param_elliptic.h"
00010 #include "tensor.h"
00011 #include "diff.h"
00012 #include "proto.h"
00013 
00014 // Resolution of tensorial equation (N^2/Psi^4)Delta(hij) - LbLbhij = Sij, using degenerate elliptic solver.
00015 // Here assumption is made that no boundary condition has to be enforced, mainly Beta^i*s_i = N/psi^2
00016 
00017 Sym_tensor boundfree_tensBC ( Sym_tensor source, Vector Beta, Scalar Psi, Scalar Nn, Sym_tensor hij_guess, double precision, int loopmax) {
00018   cout << "================================================================" << endl;
00019     cout << "STARTING THE SUBITERATION FOR THE CONFORMAL METRIC" << endl;
00020     cout << "        iteration parameters are the following:        " << endl;
00021     cout << "        convergence precision required:" << precision << endl;
00022     cout << "        max number of global steps    :" << loopmax << endl;
00023     cout << "================================================================" << endl;
00024 
00025   // Construction of a multi-grid (Mg3d)
00026   // -----------------------------------
00027   const int nz = (*source.get_mp().get_mg()).get_nzone();   // Number of domains
00028   int nr = (*source.get_mp().get_mg()).get_nr(1);   // Number of collocation points in r in each domain
00029   const Coord& rr = source.get_mp().r;
00030    Scalar rrr (source.get_mp()) ; 
00031   rrr = rr ; 
00032   rrr.std_spectral_base();  
00033  
00034   const Metric_flat& mets = (source.get_mp()).flat_met_spher() ;
00035  
00037 
00038   Sym_tensor hij  = hij_guess;    
00039   Sym_tensor hij_new = hij;
00040 
00041   Scalar n2sp4 = (Nn/(Psi*Psi))*(Nn/(Psi*Psi)) ; // Scale factor in front of Poisson Equation.
00042   n2sp4.std_spectral_base();
00043 
00044   // Resolution variables
00045   Scalar khi = hij(1,1);
00046    if (khi.get_etat() == ETATZERO) {
00047     khi.annule_hard() ;
00048     khi.set_dzpuis(4) ;
00049     khi.std_spectral_base() ;
00050       }
00051       khi.set_spectral_va().ylm();
00052   khi.mult_r();
00053   khi.mult_r_dzpuis(1);
00054   Scalar mmu = hij.mu();
00055    if (mmu.get_etat() == ETATZERO) {
00056     mmu.annule_hard() ;
00057     mmu.std_spectral_base() ;
00058       }
00059       mmu.set_spectral_va().ylm();
00060   Scalar etta = hij.eta();
00061    if (etta.get_etat() == ETATZERO) {
00062     etta.annule_hard() ;
00063     etta.std_spectral_base() ;
00064       }
00065       etta.set_spectral_va().ylm();
00066   Scalar Aa = hij.compute_A();
00067    if (Aa.get_etat() == ETATZERO) {
00068     Aa.annule_hard() ;
00069     Aa.std_spectral_base() ;
00070       }
00071       Aa.set_spectral_va().ylm();
00072   Scalar Bt = hij.compute_tilde_B();
00073    if (Bt.get_etat() == ETATZERO) {
00074     Bt.annule_hard() ;
00075     Bt.std_spectral_base() ;
00076       }
00077       Bt.set_spectral_va().ylm();
00078   Scalar hh = hij.trace(mets);
00079    if (hh.get_etat() == ETATZERO) {
00080     hh.annule_hard() ;
00081     hh.std_spectral_base() ;
00082       }
00083 
00084   //Fitting scalar
00085   Scalar fit1(source.get_mp()); fit1.set_etat_qcq(); 
00086 
00087   // For storing the result of inversion
00088   Scalar Aanew (source.get_mp()); Aanew.annule_hard(); Aanew.std_spectral_base();
00089   Scalar Btnew (source.get_mp()); Btnew.annule_hard(); Btnew.std_spectral_base();
00090 
00091 
00092   // Construction of sources for the next iteration
00093 
00094   Sym_tensor  LbLbhij = (hij.derive_lie(Beta)).derive_lie(Beta);
00095   hij.annule_domain(0);
00096   LbLbhij.annule_domain(0);
00097   LbLbhij.inc_dzpuis(1);
00098 
00099   Sym_tensor source_hij = source/n2sp4;
00100   Scalar sourcetrace = source_hij.trace(mets);
00101   Scalar Bttrace = source_hij.compute_tilde_B(); 
00102         
00103   Sym_tensor source_hij2 = LbLbhij/n2sp4;
00104 
00105   Scalar Btsource2 = source_hij2.compute_tilde_B();
00106 
00107   Scalar source_Bt2 = Bttrace + Btsource2;
00108 
00109   source_hij = source_hij + source_hij2;
00110 
00111   Scalar r2LbLbrr = LbLbhij(1,1);
00112   r2LbLbrr.mult_r();
00113   r2LbLbrr.mult_r();
00114   Scalar LbLbmu = LbLbhij.mu();
00115 
00116   Scalar source_khi2 = source_hij(1,1);
00117   source_khi2.mult_r();
00118   source_khi2.mult_r();
00119  
00120   Scalar source_mu2 = source_hij.mu();
00121   Scalar source_eta2 = source_hij.eta();
00122 
00123   Scalar source_A2 = source_hij.compute_A();
00124  
00125 
00126   source_khi2.annule_domain(0);
00127   source_mu2.annule_domain(0);
00128   source_A2.annule_domain(0);
00129   source_Bt2.annule_domain(0);
00130   source_eta2.annule_domain(0);
00131   
00132   //  source_A2.set_spectral_va().set_base( Aa.set_spectral_va().get_base());
00133   //  source_Bt2.set_spectral_va().set_base( Bt.set_spectral_va().get_base());
00134 
00135  
00136 
00138   Scalar Betacarre = (Beta(1)*Beta(1))/n2sp4 ;
00139 
00140   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)) ;
00141 
00142 //   double error = 0.; // Voluntary error on fit.  
00143 //   fitd1 += error;
00144   
00145 
00146    int nrint = (nr-1)/2 ;
00147   double ampl_r = (rrr.val_grid_point(1,0,0, nr -1) - rrr.val_grid_point(1,0,0 ,0))/2.;
00148   
00149   Scalar approx(source.get_mp());
00150   approx.annule_hard();
00151   approx.std_spectral_base();
00152   
00153 
00154 
00155   fit1 = fitd1*(rrr-1.) +1.;
00156  // First order approximation
00157   approx.set_domain(1)= fit1.set_domain(1); // MAKE PARTICULAR FOR ETATUN; DECLARE FIT1?2?3 FIRST TO BE CLEAN.
00158 
00159  
00160  
00161   //Second order approximation
00162   Scalar firststep = Betacarre - approx;
00163   
00164   double ampli = firststep.val_grid_point(1,0,0,nrint);
00165   double  fit2d1 = - ampli/(ampl_r* ampl_r);
00166  
00167 
00168  
00169   approx.set_domain(1) += (fit2d1*(rrr - 1.)*(rrr - rrr.val_grid_point(1,0,0,nr-1))).set_domain(1);
00170 
00171 
00172   double fit0d2 = approx.val_grid_point(1,0,0,nr -1); 
00173   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));
00174   double fit0d3 = Betacarre.val_grid_point(3,0,0,0);
00175   double fit1d3 = ( - fit0d3)/(rrr.val_grid_point(3,0,0,nr-1)- rrr.val_grid_point(3,0,0,0));
00176   
00177   approx.set_domain(2) = (fit0d2 + fit1d2*(rrr - rrr.val_grid_point(2,0,0,0))).set_domain(2);
00178   approx.set_domain(3) = (fit0d3 + fit1d3*(rrr - rrr.val_grid_point(3,0,0,0))).set_domain(3);
00179   
00180 
00181 
00182   for(int ii=1; ii<=3; ii++){
00183 
00184    source_khi2.set_domain(ii) += (-approx*(khi.dsdr().dsdr())).set_domain(ii);
00185 
00186    source_mu2.set_domain(ii) += (-approx*(mmu.dsdr().dsdr())).set_domain(ii);
00187 
00188    source_eta2.set_domain(ii) += (-approx*(etta.dsdr().dsdr())).set_domain(ii);
00189 
00190    source_A2.set_domain(ii) += (-approx*(Aa.dsdr().dsdr())).set_domain(ii);
00191 
00192    source_Bt2.set_domain(ii) += (-approx*(Bt.dsdr().dsdr())).set_domain(ii);
00193 
00194   } 
00195   
00196 
00197 
00198   // Convergence markers
00199     Scalar Aa_old(source.get_mp());
00200     Scalar Bt_old(source.get_mp());
00201  
00202        
00203   // Parameters for the iteration
00204     cout <<"==================================================================================" << endl;
00205     cout << "amplitude for the tensor equation source (used as scaling for convergence marker)" << endl;
00206    cout <<"==================================================================================" << endl;
00207   double scale = max(maxabs(source));
00208   double diff_ent = 0.15 ; // Initialisation of the difference marker between two iterations on some value
00209 
00214   
00215   for (int mer = 0; (diff_ent>precision) && (mer< loopmax) ; mer++) {
00216     double relax = 0.15; // Global relaxation parameter
00217 
00218 // Résolution for variables A and tilde(B)
00219     tensorelliptic (source_A2, Aanew , fitd1, fit2d1, fit0d2, fit1d2, fit0d3, fit1d3);
00220     tensorellipticBt (source_Bt2, Btnew, fitd1, fit2d1, fit0d2, fit1d2, fit0d3, fit1d3);
00221  
00222 
00223     Aa = Aanew ;
00224     Bt = Btnew ; // No relaxation on these variables; it will be done globally on the tensor.
00225  
00228 
00229       Scalar essaiA = Aanew.laplacian() - approx*(Aanew.dsdr().dsdr());
00230       essaiA.annule_domain(0);
00231       Scalar bobofA = essaiA -source_A2 ;
00232       bobofA.set_spectral_va().ylm() ;
00233       //    maxabs (bobofA);
00234       //      bobofA.spectral_display();
00235       bobofA.set_spectral_va().ylm_i();
00236      
00238 
00239       //-------------------------------------------
00240      // Retrieving the tensor hij by Dirac inversion
00241       //------------------------------------------
00242 
00244     // Magnetic part
00245 
00246      Scalar mmuA = mmu;
00247      Scalar mmuAsr = mmuA; mmuAsr.div_r();
00248      Scalar xxA(source.get_mp()); xxA.annule_hard(); xxA.std_spectral_base(); 
00249   
00250      const Scalar AA = Aa;
00251      Param* par_bc = 0x0;
00252      Sym_tensor_trans hijt(source.get_mp(), source.get_mp().get_bvect_spher(), mets);
00253      hijt = hij;
00254      hijt.sol_Dirac_A2 ( AA , mmuAsr, xxA, source_mu2, par_bc);
00255 
00256 
00257      // Monitoring  A and Hmu;
00258       Scalar musrsr = mmuAsr; musrsr.div_r_dzpuis(2);
00259       Aanew = xxA.dsdr() - musrsr;
00260       Scalar xxsr = xxA; xxsr.div_r_dzpuis(2);     
00261       //  Scalar Hmut = 3.*musrsr + mmuAsr.dsdr() + 2.*xxsr + xxsr.lapang(); 
00262 
00264     //Electric part
00265 
00266      Scalar hrrBC (source.get_mp()); hrrBC.annule_hard();
00267      Scalar wwBC(source.get_mp()); wwBC.annule_hard();
00268      Scalar tilde_etaBC(source.get_mp()); tilde_etaBC.annule_hard();
00269 
00270      Scalar source_khi3 = source_khi2;
00271      source_khi3.annule_domain(nz-1);
00272      source_khi3 += 2*hh;
00273      source_khi3.set_spectral_va().ylm();
00274 
00275       hijt.sol_Dirac_BC3( Bt, hh, hrrBC , tilde_etaBC , wwBC , source_khi3, source_eta2, par_bc, par_bc)  ;
00276   
00277       // Tensor reconstruction
00278       hij_new.set_auxiliary(hrrBC, tilde_etaBC, mmuAsr, wwBC, xxA, hh -hrrBC);
00279       
00280       hij= relax*hij_new + (1 - relax)*hij ; // Global relaxation (opposite to relaxation on resolution variables).
00281       
00282       // Calculation of updated trace.
00283     hh = (1 + hij(1,1))*( hij(2,3)*hij(2,3) - hij(2,2)*hij(3,3) )
00284         + hij(1,2)*hij(1,2)*(1 + hij(3,3)) 
00285         + hij(1,3)*hij(1,3)*(1 + hij(2,2)) 
00286         - hij(1,1)*(hij(2,2) + hij(3,3)) - 2*hij(1,2)*hij(1,3)*hij(2,3) ;
00287 
00288       khi = hij(1,1);
00289       khi.mult_r();
00290       khi.mult_r_dzpuis(0);    
00291       mmu = hij.mu();
00292       etta = hij.eta();
00293          
00294       Aa = hij.compute_A();  
00295       Bt = hij.compute_tilde_B();
00296  
00297       if (mer >=1){
00298     Aa.set_spectral_va().ylm();
00299     Bt.set_spectral_va().ylm();
00300     Aa_old.set_spectral_va().ylm();
00301     Bt_old.set_spectral_va().ylm();
00302     
00303     diff_ent = max(maxabs (Bt - Bt_old))/scale; // Convergence marker
00304       }
00305       Aa_old = Aa;
00306       Bt_old = Bt;
00307       
00308 
00309     // Update of sources for the next loop
00310      LbLbhij = (hij.derive_lie(Beta)).derive_lie(Beta);
00311      LbLbhij.inc_dzpuis(1);
00312      r2LbLbrr = LbLbhij(1,1);
00313      r2LbLbrr.mult_r();
00314      r2LbLbrr.mult_r();
00315      LbLbmu = LbLbhij.mu();
00316    
00317          
00318   source_hij = source/n2sp4;
00319 
00320   Bttrace = source_hij.compute_tilde_B();
00321   
00322   source_hij2 = LbLbhij/n2sp4;
00323 
00324   Btsource2 = source_hij2.compute_tilde_B();
00325 
00326   source_Bt2 = Bttrace + Btsource2;
00327   
00328   source_hij = source_hij + source_hij2;
00329 
00330   source_khi2 = source_hij(1,1);
00331   source_khi2.mult_r();
00332   source_khi2.mult_r();
00333   source_mu2 = source_hij.mu();
00334   source_eta2 = source_hij.eta();
00335   source_A2= source_hij.compute_A();
00336  
00337   
00338   source_A2.set_spectral_va().set_base( Aa.set_spectral_va().get_base());
00339   source_Bt2.set_spectral_va().set_base( Bt.set_spectral_va().get_base());
00340   
00341   for(int ii=1; ii<=3; ii++){
00342     source_khi2.set_domain(ii) += (-approx*(khi.dsdr().dsdr())).set_domain(ii);
00343     source_mu2.set_domain(ii) += (-approx*(mmu.dsdr().dsdr())).set_domain(ii);
00344     source_eta2.set_domain(ii) += (-approx*(etta.dsdr().dsdr())).set_domain(ii);
00345     source_A2.set_domain(ii) += (-approx*(Aa.dsdr().dsdr())).set_domain(ii);
00346     source_Bt2.set_domain(ii) += (-approx*(Bt.dsdr().dsdr())).set_domain(ii);
00347   } 
00348   source_khi2.annule_domain(0);  
00349   source_mu2.annule_domain(0);
00350   source_eta2.annule_domain(0);
00351   source_A2.annule_domain(0);
00352   source_Bt2.annule_domain(0);
00353   
00354   
00355   
00356 //   cout << "real A resolution?" << endl;
00357 //   Sym_tensor mucorrect  = LbLbhij + source;
00358 //   mucorrect = mucorrect/n2sp4;
00359 //   Scalar AAs = mucorrect.compute_A();
00360 //   AAs.annule_domain(nz-1);
00361 //   Aa.annule_domain(nz-1);
00362 //   Scalar Aa2 = Aa.laplacian();
00363 //   Scalar voirA = AAs - Aa2;
00364   
00365 //   voirA.set_spectral_va().ylm_i();
00366 //   //  des_meridian(voirA, 1.00001*Rhor, Rout,"diffA", 1); 
00367 //   voirA.set_spectral_va().ylm();
00368   
00369   
00370 //   maxabs (voirA);
00371 //   voirA.spectral_display("voirA", 1.e-9);
00372   
00373   
00374   cout << "diff_ent" << diff_ent << endl;
00375   cout << mer << endl;
00376   
00377   
00378   }
00379   
00380   return hij;
00381  }
00382 
00383 
00384 
00385 
00386 
00387     

Generated on Tue Feb 7 01:35:15 2012 for LORENE by  doxygen 1.4.6