et_bin_equilibrium.C

00001 /*
00002  *  Method of class Etoile_bin to compute an equilibrium configuration
00003  *
00004  *  (see file etoile.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2000-2001 Eric Gourgoulhon
00010  *   Copyright (c) 2000-2001 Keisuke Taniguchi
00011  *
00012  *   This file is part of LORENE.
00013  *
00014  *   LORENE is free software; you can redistribute it and/or modify
00015  *   it under the terms of the GNU General Public License as published by
00016  *   the Free Software Foundation; either version 2 of the License, or
00017  *   (at your option) any later version.
00018  *
00019  *   LORENE is distributed in the hope that it will be useful,
00020  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *   GNU General Public License for more details.
00023  *
00024  *   You should have received a copy of the GNU General Public License
00025  *   along with LORENE; if not, write to the Free Software
00026  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  *
00028  */
00029 
00030 
00031 char et_bin_equilibrium_C[] = "$Header: /cvsroot/Lorene/C++/Source/Etoile/et_bin_equilibrium.C,v 1.12 2009/06/15 09:25:18 k_taniguchi Exp $" ;
00032 
00033 /*
00034  * $Id: et_bin_equilibrium.C,v 1.12 2009/06/15 09:25:18 k_taniguchi Exp $
00035  * $Log: et_bin_equilibrium.C,v $
00036  * Revision 1.12  2009/06/15 09:25:18  k_taniguchi
00037  * Improved the rescaling of the domains.
00038  *
00039  * Revision 1.11  2008/11/14 13:48:06  e_gourgoulhon
00040  * Added parameter pent_limit to force the enthalpy values at the
00041  * boundaries between the domains, in case of more than one domain inside
00042  * the star.
00043  *
00044  * Revision 1.10  2004/09/28 15:49:23  f_limousin
00045  * Improve the rescaling of the domains for nzone = 4 and nzone = 5.
00046  *
00047  * Revision 1.9  2004/05/13 08:47:01  f_limousin
00048  * Decomment the procedure resize.
00049  *
00050  * Revision 1.8  2004/05/10 10:15:57  f_limousin
00051  * Change to avoid a warning in the compilation of Lorene
00052  *
00053  * Revision 1.7  2004/05/07 12:36:34  f_limousin
00054  * Add new member ssjm1_psi in order to have only one function
00055  * equilibrium (the same for strange stars and neutron stars)
00056  *
00057  * Revision 1.6  2004/05/07 08:32:44  k_taniguchi
00058  * Introduction of the version without ssjm1_psi.
00059  *
00060  * Revision 1.5  2004/04/19 11:06:36  f_limousin
00061  * Differents call of Etoile_bin::velocity_potential depending on
00062  * the equation of state.
00063  *
00064  * Revision 1.4  2004/03/25 10:29:04  j_novak
00065  * All LORENE's units are now defined in the namespace Unites (in file unites.h).
00066  *
00067  * Revision 1.3  2003/01/17 13:31:13  f_limousin
00068  * Add comments
00069  *
00070  * Revision 1.2  2002/12/10 13:28:03  k_taniguchi
00071  * Change the multiplication "*" to "%"
00072  *   and flat_scalar_prod to flat_scalar_prod_desal.
00073  *
00074  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00075  * LORENE
00076  *
00077  * Revision 2.23  2001/08/07  09:43:02  keisuke
00078  * Change of the method to set the longest radius of a star
00079  *  on the first domain.
00080  * Addition of a new argument in Etoile_bin::equilibrium : Tbl fact.
00081  *
00082  * Revision 2.22  2001/06/22  08:54:19  keisuke
00083  * Set the inner values of the second domain of ent
00084  *   by using the outer ones of the first domain.
00085  *
00086  * Revision 2.21  2001/06/18  12:50:49  keisuke
00087  * Addition of the filter for the source of shift vector.
00088  *
00089  * Revision 2.20  2001/05/17  12:18:47  keisuke
00090  * Change of the method to calculate chi from setting position in map
00091  *  to val_point.
00092  *
00093  * Revision 2.19  2001/01/16  17:01:53  keisuke
00094  * Change the method to set the values on the surface.
00095  *
00096  * Revision 2.18  2001/01/10  16:42:51  keisuke
00097  * Set the inner values of the second domain of logn_auto
00098  *   by using the outer ones of the first domain.
00099  *
00100  * Revision 2.17  2000/12/22  13:08:04  eric
00101  * precis_adapt = 1e-14 au lieu de 1e-15.
00102  * Sorties graphiques commentees.
00103  *
00104  * Revision 2.16  2000/12/20  10:32:44  eric
00105  * Changement important : nz_search = nzet ---> nz_search = nzet + 1
00106  *
00107  * Revision 2.15  2000/10/23  14:02:16  eric
00108  * Modif de Map_et::adapt: on y rentre desormais avec nz_search
00109  *  (dans le cas present nz_search = nzet).
00110  *
00111  * Revision 2.14  2000/09/28  12:19:36  keisuke
00112  * Construct logn_auto_regu from logn_auto.
00113  * This procedure is needed for et_bin_upmetr.C.
00114  *
00115  * Revision 2.13  2000/05/25  13:48:12  eric
00116  * Ajout de l'argument thres_adapt: l'adaptation du mapping n'est
00117  * plus effectuee si dH/dr_eq passe sous un certain seuil.
00118  *
00119  * Revision 2.12  2000/05/25  12:58:31  eric
00120  * Modifs classe Param: les int et double sont desormais passes par leurs
00121  *  adresses.
00122  *
00123  * Revision 2.11  2000/03/29  11:57:38  eric
00124  * *** empty log message ***
00125  *
00126  * Revision 2.10  2000/03/29  11:53:41  eric
00127  * Modif affichage
00128  *
00129  * Revision 2.9  2000/03/22  16:37:29  eric
00130  * Calcul des erreurs dans la resolution des equations de Poisson
00131  * et sortie de ces erreurs dans le Tbl diff.
00132  *
00133  * Revision 2.8  2000/03/22  12:56:18  eric
00134  * Nouveau prototype d'Etoile_bin::equilibrium : diff_ent est remplace
00135  *   par le Tbl diff.
00136  *
00137  * Revision 2.7  2000/03/10  15:47:19  eric
00138  * On appel desormais poisson_vect avec dzpuis = 4.
00139  *
00140  * Revision 2.6  2000/03/07  16:52:15  eric
00141  * Modifs manipulations source pour le shift.
00142  *
00143  * Revision 2.5  2000/03/07  08:32:47  eric
00144  * Appel de Map_radial::reevaluate_sym (pour tenir compte de la symetrie
00145  *  / plan y=0).
00146  *
00147  * Revision 2.4  2000/02/17  19:56:57  eric
00148  * L'appel de Map_radial::reevaluate pour ent est fait sur nzet+1 zone
00149  * et non plus nzet.
00150  *
00151  * Revision 2.2  2000/02/16  17:12:03  eric
00152  * Premiere version avec les equations du champ gravitationnel.
00153  *
00154  * Revision 2.1  2000/02/15  15:59:52  eric
00155  * *** empty log message ***
00156  *
00157  * Revision 2.0  2000/02/15  15:40:42  eric
00158  * *** empty log message ***
00159  *
00160  *
00161  * $Header: /cvsroot/Lorene/C++/Source/Etoile/et_bin_equilibrium.C,v 1.12 2009/06/15 09:25:18 k_taniguchi Exp $
00162  *
00163  */
00164 
00165 // Headers C
00166 #include <math.h>
00167 
00168 // Headers Lorene
00169 #include "etoile.h"
00170 #include "param.h"
00171 #include "eos.h" 
00172 
00173 #include "graphique.h"
00174 #include "utilitaires.h"
00175 #include "unites.h"     
00176 
00177 void Etoile_bin::equilibrium(double ent_c, 
00178                              int mermax, int mermax_poisson, 
00179              double relax_poisson, int mermax_potvit, 
00180              double relax_potvit, double thres_adapt,
00181              const Tbl& fact_resize, Tbl& diff, const Tbl* pent_limit ) {
00182                  
00183 
00184     // Fundamental constants and units
00185     // -------------------------------
00186 
00187   using namespace Unites ;
00188     
00189     // Initializations
00190     // ---------------
00191     
00192     const Mg3d* mg = mp.get_mg() ; 
00193     int nz = mg->get_nzone() ;      // total number of domains
00194     
00195     // The following is required to initialize mp_prev as a Map_et:
00196     Map_et& mp_et = dynamic_cast<Map_et&>(mp) ; 
00197     
00198     // Domain and radial indices of points at the surface of the star:
00199     int l_b = nzet - 1 ; 
00200     int i_b = mg->get_nr(l_b) - 1 ; 
00201     int k_b ;
00202     int j_b ; 
00203     
00204     // Value of the enthalpy defining the surface of the star
00205     double ent_b = 0 ; 
00206     
00207     // Error indicators
00208     // ----------------
00209     
00210     double& diff_ent = diff.set(0) ; 
00211     double& diff_vel_pot = diff.set(1) ; 
00212     double& diff_logn = diff.set(2) ; 
00213     double& diff_beta = diff.set(3) ; 
00214     double& diff_shift_x = diff.set(4) ; 
00215     double& diff_shift_y = diff.set(5) ; 
00216     double& diff_shift_z = diff.set(6) ; 
00217 
00218     // Parameters for the function Map_et::adapt
00219     // -----------------------------------------
00220     
00221     Param par_adapt ; 
00222     int nitermax = 100 ;  
00223     int niter ; 
00224     int adapt_flag = 1 ;    //  1 = performs the full computation, 
00225                 //  0 = performs only the rescaling by 
00226                 //      the factor alpha_r
00227     //##    int nz_search = nzet + 1 ;  // Number of domains for searching the enthalpy
00228     int nz_search = nzet ;  // Number of domains for searching the enthalpy
00229                 //  isosurfaces
00230 
00231     double precis_secant = 1.e-14 ; 
00232     double alpha_r ; 
00233     double reg_map = 1. ; // 1 = regular mapping, 0 = contracting mapping
00234 
00235     par_adapt.add_int(nitermax, 0) ; // maximum number of iterations to 
00236                      // locate zeros by the secant method
00237     par_adapt.add_int(nzet, 1) ;    // number of domains where the adjustment 
00238                     // to the isosurfaces of ent is to be 
00239                     // performed
00240     par_adapt.add_int(nz_search, 2) ;   // number of domains to search for
00241                     // the enthalpy isosurface
00242     par_adapt.add_int(adapt_flag, 3) ; //  1 = performs the full computation, 
00243                        //  0 = performs only the rescaling by 
00244                        //      the factor alpha_r
00245     par_adapt.add_int(j_b, 4) ; //  theta index of the collocation point 
00246                     //  (theta_*, phi_*)
00247     par_adapt.add_int(k_b, 5) ; //  theta index of the collocation point 
00248                     //  (theta_*, phi_*)
00249 
00250     par_adapt.add_int_mod(niter, 0) ;  //  number of iterations actually used in 
00251                        //  the secant method
00252     
00253     par_adapt.add_double(precis_secant, 0) ; // required absolute precision in 
00254                          // the determination of zeros by 
00255                          // the secant method
00256     par_adapt.add_double(reg_map, 1)    ;  // 1. = regular mapping, 0 = contracting mapping
00257     
00258     par_adapt.add_double(alpha_r, 2) ;      // factor by which all the radial 
00259                         // distances will be multiplied 
00260 
00261     // Enthalpy values for the adaptation
00262     Tbl ent_limit(nzet) ; 
00263     if (pent_limit != 0x0) ent_limit = *pent_limit ; 
00264            
00265     par_adapt.add_tbl(ent_limit, 0) ;   // array of values of the field ent 
00266                         // to define the isosurfaces.              
00267  
00268     // Parameters for the function Map_et::poisson for logn_auto
00269     // ---------------------------------------------------------
00270 
00271     double precis_poisson = 1.e-16 ;     
00272 
00273     Param par_poisson1 ; 
00274 
00275     par_poisson1.add_int(mermax_poisson,  0) ;  // maximum number of iterations
00276     par_poisson1.add_double(relax_poisson,  0) ; // relaxation parameter
00277     par_poisson1.add_double(precis_poisson, 1) ; // required precision
00278     par_poisson1.add_int_mod(niter, 0) ;  //  number of iterations actually used 
00279     par_poisson1.add_cmp_mod( ssjm1_logn ) ; 
00280                        
00281     // Parameters for the function Map_et::poisson for beta_auto
00282     // ---------------------------------------------------------
00283 
00284     Param par_poisson2 ; 
00285 
00286     par_poisson2.add_int(mermax_poisson,  0) ;  // maximum number of iterations
00287     par_poisson2.add_double(relax_poisson,  0) ; // relaxation parameter
00288     par_poisson2.add_double(precis_poisson, 1) ; // required precision
00289     par_poisson2.add_int_mod(niter, 0) ;  //  number of iterations actually used 
00290     par_poisson2.add_cmp_mod( ssjm1_beta ) ; 
00291     
00292                        
00293     // Parameters for the function Tenseur::poisson_vect
00294     // -------------------------------------------------
00295 
00296     Param par_poisson_vect ; 
00297 
00298     par_poisson_vect.add_int(mermax_poisson,  0) ;  // maximum number of iterations
00299     par_poisson_vect.add_double(relax_poisson,  0) ; // relaxation parameter
00300     par_poisson_vect.add_double(precis_poisson, 1) ; // required precision
00301     par_poisson_vect.add_cmp_mod( ssjm1_khi ) ; 
00302     par_poisson_vect.add_tenseur_mod( ssjm1_wshift ) ; 
00303     par_poisson_vect.add_int_mod(niter, 0) ;   
00304 
00305                        
00306     // External potential
00307     // See Eq (99) from Gourgoulhon et al. (2001)
00308     // -----------------------------------------
00309     
00310     Tenseur pot_ext = logn_comp + pot_centri + loggam ;
00311 //##
00312 //  des_coupe_z(pot_ext(), 0., 1, "pot_ext", &(ent()) ) ; 
00313 //##
00314     
00315     Tenseur ent_jm1 = ent ; // Enthalpy at previous step
00316     
00317     Tenseur source(mp) ;    // source term in the equation for logn_auto
00318                 // and beta_auto
00319                 
00320     Tenseur source_shift(mp, 1, CON, ref_triad) ;  // source term in the equation 
00321                            //  for shift_auto
00322 
00323     //=========================================================================
00324     //          Start of iteration
00325     //=========================================================================
00326 
00327     for(int mer=0 ; mer<mermax ; mer++ ) {
00328 
00329     cout << "-----------------------------------------------" << endl ;
00330     cout << "step: " << mer << endl ;
00331     cout << "diff_ent = " << diff_ent << endl ;    
00332 
00333     //-----------------------------------------------------
00334     // Resolution of the elliptic equation for the velocity
00335     // scalar potential
00336     //-----------------------------------------------------
00337 
00338     if (irrotational) {
00339         diff_vel_pot = velocity_potential(mermax_potvit, 
00340                            precis_poisson, relax_potvit) ; 
00341 
00342     }
00343 
00344     //-----------------------------------------------------
00345     // Computation of the new radial scale
00346     //-----------------------------------------------------
00347 
00348     // alpha_r (r = alpha_r r') is determined so that the enthalpy
00349     // takes the requested value ent_b at the stellar surface
00350     
00351     // Values at the center of the star:
00352     double logn_auto_c  = logn_auto()(0, 0, 0, 0) ; 
00353     double pot_ext_c  = pot_ext()(0, 0, 0, 0) ; 
00354 
00355     // Search for the reference point (theta_*, phi_*) [notation of
00356     //  Bonazzola, Gourgoulhon & Marck PRD 58, 104020 (1998)]
00357     //  at the surface of the star
00358     // ------------------------------------------------------------
00359     double alpha_r2 = 0 ; 
00360     for (int k=0; k<mg->get_np(l_b); k++) {
00361         for (int j=0; j<mg->get_nt(l_b); j++) {
00362         
00363         double pot_ext_b  = pot_ext()(l_b, k, j, i_b) ; 
00364         double logn_auto_b  = logn_auto()(l_b, k, j, i_b) ; 
00365 
00366 
00367         // See Eq (100) from Gourgoulhon et al. (2001)
00368         double alpha_r2_jk = ( ent_c - ent_b + pot_ext_c - pot_ext_b) / 
00369                 ( logn_auto_b - logn_auto_c ) ;
00370         
00371 //      cout << "k, j, alpha_r2_jk : " << k << "  " << j << "  " 
00372 //           << alpha_r2_jk << endl ; 
00373           
00374         if (alpha_r2_jk > alpha_r2) {
00375             alpha_r2 = alpha_r2_jk ; 
00376             k_b = k ; 
00377             j_b = j ; 
00378         }
00379 
00380         }
00381     }
00382     
00383     alpha_r = sqrt(alpha_r2) ;
00384         
00385     cout << "k_b, j_b, alpha_r: " << k_b << "  " << j_b << "  " 
00386          <<  alpha_r << endl ;
00387 
00388     // New value of logn_auto 
00389     // ----------------------
00390     
00391     logn_auto = alpha_r2 * logn_auto ;
00392     logn_auto_regu = alpha_r2 * logn_auto_regu ;
00393     logn_auto_c  = logn_auto()(0, 0, 0, 0) ;
00394 
00395 
00396     //------------------------------------------------------------
00397     // Change the values of the inner points of the second domain
00398     // by those of the outer points of the first domain
00399     //------------------------------------------------------------
00400 
00401     (logn_auto().va).smooth(nzet, (logn_auto.set()).va) ;
00402 
00403 
00404     //------------------------------------------
00405     // First integral   --> enthalpy in all space
00406     // See Eq (98) from Gourgoulhon et al. (2001)
00407     //-------------------------------------------
00408 
00409     ent = (ent_c + logn_auto_c + pot_ext_c) - logn_auto - pot_ext ;
00410 
00411     (ent().va).smooth(nzet, (ent.set()).va) ;
00412 
00413     //----------------------------------------------------
00414     // Adaptation of the mapping to the new enthalpy field
00415     //----------------------------------------------------
00416     
00417     // Shall the adaptation be performed (cusp) ?
00418     // ------------------------------------------
00419     
00420     double dent_eq = ent().dsdr().val_point(ray_eq(),M_PI/2.,0.) ;
00421     double dent_pole = ent().dsdr().val_point(ray_pole(),0.,0.) ;
00422     double rap_dent = fabs( dent_eq / dent_pole ) ; 
00423     cout << "| dH/dr_eq / dH/dr_pole | = " << rap_dent << endl ; 
00424     
00425     if ( rap_dent < thres_adapt ) {
00426         adapt_flag = 0 ;    // No adaptation of the mapping 
00427         cout << "******* FROZEN MAPPING  *********" << endl ; 
00428     }
00429     else{
00430         adapt_flag = 1 ;    // The adaptation of the mapping is to be
00431                 //  performed
00432     }
00433 
00434 
00435     if (pent_limit == 0x0) {
00436       ent_limit.set_etat_qcq() ; 
00437       for (int l=0; l<nzet; l++) {  // loop on domains inside the star
00438         ent_limit.set(l) = ent()(l, k_b, j_b, i_b) ; 
00439       }
00440       ent_limit.set(nzet-1) = ent_b  ; 
00441     }
00442 
00443     Map_et mp_prev = mp_et ; 
00444 
00445 //##    cout  << "Enthalpy field at the outer boundary of domain 0 : " 
00446 //   << endl ; 
00447 //    for (int k=0; k<mg->get_np(0); k++) {
00448 //  cout << "k = " << k << " : " ; 
00449 //  for (int j=0; j<mg->get_nt(0); j++) {
00450 //      cout << "  " << ent()(0, k, j, mg->get_nr(0)-1) ;
00451 //  }
00452 //  cout << endl ; 
00453 //  }
00454 //    cout  << "Enthalpy field at the inner boundary of domain 1 : " 
00455 //   << endl ; 
00456 //    for (int k=0; k<mg->get_np(1); k++) {
00457 //  cout << "k = " << k << " : " ; 
00458 //  for (int j=0; j<mg->get_nt(1); j++) {
00459 //      cout << "  " << ent()(1, k, j, 0) ;
00460 //  }
00461 //  cout << endl ; 
00462 //    }
00463 //    cout  << "Difference enthalpy field boundary between domains 0 and 1: " 
00464 //   << endl ; 
00465 //    for (int k=0; k<mg->get_np(1); k++) {
00466 //  cout << "k = " << k << " : " ; 
00467 //  for (int j=0; j<mg->get_nt(1); j++) {
00468 //      cout << "  " << ent()(0, k, j, mg->get_nr(0)-1) -
00469 //              ent()(1, k, j, 0) ;
00470 //  }
00471 //  cout << endl ; 
00472 //    }
00473 
00474 
00475 //##
00476 //  des_coupe_z(gam_euler(), 0., 1, "gam_euler") ; 
00477 //  des_coupe_z(loggam(), 0., 1, "loggam") ; 
00478 //  des_coupe_y(loggam(), 0., 1, "loggam") ; 
00479 //  des_coupe_z(d_psi(0), 0., 1, "d_psi_0") ; 
00480 //  des_coupe_z(d_psi(1), 0., 1, "d_psi_1") ; 
00481 //  des_coupe_z(d_psi(2), 0., 1, "d_psi_2") ; 
00482 //  des_coupe_z(ent(), 0., 1, "ent before adapt", &(ent()) ) ; 
00483 //##
00484 
00485 
00486     mp.adapt(ent(), par_adapt) ;
00487 
00488     // Readjustment of the external boundary of domain l=nzet
00489     // to keep a fixed ratio with respect to star's surface
00490     
00491     double rr_in_1 = mp.val_r(nzet, -1., M_PI/2., 0.) ;
00492 
00493     // Resizes the outer boundary of the shell including the comp. NS
00494     double rr_out_nm2 = mp.val_r(nz-2, 1., M_PI/2., 0.) ;
00495 
00496     mp.resize(nz-2, rr_in_1/rr_out_nm2 * fact_resize(1)) ;
00497 
00498     // Resizes the inner boundary of the shell including the comp. NS
00499     double rr_out_nm3 = mp.val_r(nz-3, 1., M_PI/2., 0.) ;
00500 
00501     mp.resize(nz-3, rr_in_1/rr_out_nm3 * fact_resize(0)) ;
00502 
00503     if (nz > nzet+3) {
00504 
00505         // Resize of the domain from 1(nzet) to N-4
00506         double rr_out_nm3_new = mp.val_r(nz-3, 1., M_PI/2., 0.) ;
00507 
00508         for (int i=nzet-1; i<nz-4; i++) {
00509 
00510             double rr_out_i = mp.val_r(i, 1., M_PI/2., 0.) ;
00511 
00512         double rr_mid = rr_out_i
00513           + (rr_out_nm3_new - rr_out_i) / double(nz - 3 - i) ;
00514 
00515         double rr_2timesi = 2. * rr_out_i ;
00516 
00517         if (rr_2timesi < rr_mid) {
00518 
00519             double rr_out_ip1 = mp.val_r(i+1, 1., M_PI/2., 0.) ;
00520 
00521             mp.resize(i+1, rr_2timesi / rr_out_ip1) ;
00522 
00523         }
00524         else {
00525 
00526             double rr_out_ip1 = mp.val_r(i+1, 1., M_PI/2., 0.) ;
00527 
00528             mp.resize(i+1, rr_mid / rr_out_ip1) ;
00529 
00530         }  // End of else
00531 
00532         }  // End of i loop
00533 
00534     }  // End of (nz > nzet+3) loop
00535 
00536 
00537     //----------------------------------------------------
00538     // Computation of the enthalpy at the new grid points
00539     //----------------------------------------------------
00540 
00541     mp_prev.homothetie(alpha_r) ; 
00542     
00543     mp.reevaluate_symy(&mp_prev, nzet+1, ent.set()) ; 
00544 
00545 //  des_coupe_z(ent(), 0., 1, "ent after reevaluate", &(ent()) ) ; 
00546 
00547     double ent_s_max = -1 ; 
00548     int k_s_max = -1 ; 
00549     int j_s_max = -1 ; 
00550     for (int k=0; k<mg->get_np(l_b); k++) {
00551         for (int j=0; j<mg->get_nt(l_b); j++) {
00552         double xx = fabs( ent()(l_b, k, j, i_b) ) ;
00553         if (xx > ent_s_max) {
00554             ent_s_max = xx ; 
00555             k_s_max = k ; 
00556             j_s_max = j ; 
00557         }
00558         }
00559     }
00560     cout << "Max. abs(enthalpy) at the boundary between domains nzet-1"
00561          << " and nzet : " << endl ; 
00562     cout << "   " << ent_s_max << " reached for k = " << k_s_max <<
00563         " and j = " << j_s_max << endl ; 
00564 
00565     //----------------------------------------------------
00566     // Equation of state  
00567     //----------------------------------------------------
00568     
00569     equation_of_state() ;   // computes new values for nbar (n), ener (e) 
00570                 // and press (p) from the new ent (H)
00571     
00572     //---------------------------------------------------------
00573     // Matter source terms in the gravitational field equations 
00574     //---------------------------------------------------------
00575 
00576     hydro_euler() ;     // computes new values for ener_euler (E), 
00577                 // s_euler (S) and u_euler (U^i)
00578 
00579     //--------------------------------------------------------
00580     // Poisson equation for logn_auto (nu_auto)
00581     //--------------------------------------------------------
00582 
00583     // Source 
00584     // See Eq (50) from Gourgoulhon et al. (2001)
00585     // ------------------------------------------
00586     
00587     if (relativistic) {
00588         source = qpig * a_car % (ener_euler + s_euler)
00589             + akcar_auto + akcar_comp 
00590          - flat_scalar_prod_desal(d_logn_auto,
00591                  d_beta_auto + d_beta_comp) ;
00592      
00593     }
00594     else {
00595         source = qpig * nbar ; 
00596     }
00597     
00598     source.set_std_base() ;     
00599 
00600     // Resolution of the Poisson equation 
00601     // ----------------------------------
00602 
00603     source().poisson(par_poisson1, logn_auto.set()) ; 
00604 
00605     // Construct logn_auto_regu for et_bin_upmetr.C
00606     // --------------------------------------------
00607 
00608     logn_auto_regu = logn_auto ;
00609 
00610     // Check: has the Poisson equation been correctly solved ?
00611     // -----------------------------------------------------
00612     
00613     Tbl tdiff_logn = diffrel(logn_auto().laplacien(), source()) ;
00614     cout << 
00615     "Relative error in the resolution of the equation for logn_auto : "
00616     << endl ; 
00617     for (int l=0; l<nz; l++) {
00618         cout << tdiff_logn(l) << "  " ; 
00619     }
00620     cout << endl ;
00621     diff_logn = max(abs(tdiff_logn)) ; 
00622 
00623 
00624     if (relativistic) {
00625 
00626         //--------------------------------------------------------
00627         // Poisson equation for beta_auto 
00628         //--------------------------------------------------------
00629 
00630         // Source 
00631         // See Eq (51) from Gourgoulhon et al. (2001)
00632         // ------------------------------------------
00633     
00634         source = qpig * a_car % s_euler
00635             + .75 * ( akcar_auto + akcar_comp )
00636             - .5 * flat_scalar_prod_desal(d_logn_auto,  
00637                           d_logn_auto + d_logn_comp)
00638             - .5 * flat_scalar_prod_desal(d_beta_auto,  
00639                           d_beta_auto + d_beta_comp) ;
00640              
00641         source.set_std_base() ;     
00642 
00643         // Resolution of the Poisson equation 
00644         // ----------------------------------
00645 
00646         source().poisson(par_poisson2, beta_auto.set()) ; 
00647 
00648         // Check: has the Poisson equation been correctly solved ?
00649         // -----------------------------------------------------
00650     
00651         Tbl tdiff_beta = diffrel(beta_auto().laplacien(), source()) ;
00652         cout << 
00653         "Relative error in the resolution of the equation for beta_auto : "
00654         << endl ; 
00655         for (int l=0; l<nz; l++) {
00656         cout << tdiff_beta(l) << "  " ; 
00657         }
00658         cout << endl ;
00659         diff_beta = max(abs(tdiff_beta)) ; 
00660 
00661         //--------------------------------------------------------
00662         // Vector Poisson equation for shift_auto 
00663         //--------------------------------------------------------
00664 
00665         // Source
00666         // See Eq (52) from Gourgoulhon et al. (2001)
00667         // ------
00668         
00669         Tenseur vtmp =  6. * ( d_beta_auto + d_beta_comp )
00670                -8. * ( d_logn_auto + d_logn_comp ) ;
00671         
00672         source_shift = (-4.*qpig) * nnn % a_car % (ener_euler + press)
00673           % u_euler 
00674         + nnn % flat_scalar_prod_desal(tkij_auto, vtmp) ;
00675     
00676         source_shift.set_std_base() ;   
00677  
00678         // Resolution of the Poisson equation 
00679         // ----------------------------------
00680 
00681         // Filter for the source of shift vector
00682         
00683         for (int i=0; i<3; i++) {
00684 
00685           if (source_shift(i).get_etat() != ETATZERO)
00686             source_shift.set(i).filtre(4) ;
00687 
00688         }
00689         
00690         // For Tenseur::poisson_vect, the triad must be the mapping triad,
00691         // not the reference one:
00692         
00693         source_shift.change_triad( mp.get_bvect_cart() ) ; 
00694 
00695         for (int i=0; i<3; i++) {
00696         if(source_shift(i).dz_nonzero()) {
00697             assert( source_shift(i).get_dzpuis() == 4 ) ; 
00698         }
00699         else{
00700             (source_shift.set(i)).set_dzpuis(4) ; 
00701         }
00702         }
00703 
00704         //##
00705         // source_shift.dec2_dzpuis() ;    // dzpuis 4 -> 2
00706 
00707         double lambda_shift = double(1) / double(3) ; 
00708     
00709         source_shift.poisson_vect(lambda_shift, par_poisson_vect, 
00710                           shift_auto, w_shift, khi_shift) ;      
00711 
00712 
00713         // Check: has the equation for shift_auto been correctly solved ?
00714         // --------------------------------------------------------------
00715         
00716         // Divergence of shift_auto : 
00717         Tenseur divn = contract(shift_auto.gradient(), 0, 1) ; 
00718         divn.dec2_dzpuis() ;    // dzpuis 2 -> 0
00719         
00720         // Grad(div) : 
00721         Tenseur graddivn = divn.gradient() ; 
00722         graddivn.inc2_dzpuis() ;    // dzpuis 2 -> 4
00723         
00724         // Full operator : 
00725         Tenseur lap_shift(mp, 1, CON, mp.get_bvect_cart() ) ;  
00726         lap_shift.set_etat_qcq() ; 
00727         for (int i=0; i<3; i++) {
00728         lap_shift.set(i) = shift_auto(i).laplacien() 
00729                     + lambda_shift * graddivn(i) ;
00730         }
00731 
00732         Tbl tdiff_shift_x = diffrel(lap_shift(0), source_shift(0)) ; 
00733         Tbl tdiff_shift_y = diffrel(lap_shift(1), source_shift(1)) ; 
00734         Tbl tdiff_shift_z = diffrel(lap_shift(2), source_shift(2)) ; 
00735 
00736         cout << 
00737         "Relative error in the resolution of the equation for shift_auto : "
00738         << endl ; 
00739         cout << "x component : " ;
00740         for (int l=0; l<nz; l++) {
00741         cout << tdiff_shift_x(l) << "  " ; 
00742         }
00743         cout << endl ;
00744         cout << "y component : " ;
00745         for (int l=0; l<nz; l++) {
00746         cout << tdiff_shift_y(l) << "  " ; 
00747         }
00748         cout << endl ;
00749         cout << "z component : " ;
00750         for (int l=0; l<nz; l++) {
00751         cout << tdiff_shift_z(l) << "  " ; 
00752         }
00753         cout << endl ;
00754             
00755         diff_shift_x = max(abs(tdiff_shift_x)) ; 
00756         diff_shift_y = max(abs(tdiff_shift_y)) ; 
00757         diff_shift_z = max(abs(tdiff_shift_z)) ; 
00758 
00759         // Final result
00760         // ------------
00761         // The output of Tenseur::poisson_vect is on the mapping triad,
00762         // it should therefore be transformed to components on the
00763         // reference triad :
00764         
00765         shift_auto.change_triad( ref_triad ) ; 
00766 
00767 
00768     }   // End of relativistic equations    
00769     
00770 
00771     if (nzet > 1) {
00772       cout.precision(10) ;
00773 
00774       for (int ltrans = 0; ltrans < nzet-1; ltrans++) {
00775     cout << endl << "Values at boundary between domains no. " << ltrans << " and " <<   ltrans+1 << " for theta = pi/2 and phi = 0 :" << endl ;
00776 
00777     double rt1 = mp.val_r(ltrans, 1., M_PI/2, 0.) ; 
00778     double rt2 = mp.val_r(ltrans+1, -1., M_PI/2, 0.) ; 
00779     cout << "   Coord. r [km] (left, right, rel. diff) : " 
00780       << rt1 / km << "  " << rt2 / km << "  " << (rt2 - rt1)/rt1  << endl ; 
00781   
00782     int ntm1 = mg->get_nt(ltrans) - 1; 
00783     int nrm1 = mg->get_nr(ltrans) - 1 ; 
00784     double ent1 = ent()(ltrans, 0, ntm1, nrm1) ; 
00785     double ent2 = ent()(ltrans+1, 0, ntm1, 0) ; 
00786       cout << "   Enthalpy (left, right, rel. diff) : " 
00787         << ent1 << "  " << ent2 << "  " << (ent2-ent1)/ent1  << endl ; 
00788 
00789     double press1 = press()(ltrans, 0, ntm1, nrm1) ; 
00790     double press2 = press()(ltrans+1, 0, ntm1, 0) ; 
00791       cout << "   Pressure (left, right, rel. diff) : " 
00792       << press1 << "  " << press2 << "  " << (press2-press1)/press1 << endl ; 
00793 
00794     double nb1 = nbar()(ltrans, 0, ntm1, nrm1) ; 
00795     double nb2 = nbar()(ltrans+1, 0, ntm1, 0) ; 
00796       cout << "   Baryon density (left, right, rel. diff) : " 
00797       << nb1 << "  " << nb2 << "  " << (nb2-nb1)/nb1  << endl ; 
00798       }
00799     }
00800 /*    if (mer % 10 == 0) {
00801     cout << "mer = " << mer << endl ; 
00802     double r_max = 1.2 * ray_eq() ; 
00803     des_profile(nbar(), 0., r_max, M_PI/2, 0., "n", "Baryon density") ; 
00804     des_profile(ener(), 0., r_max, M_PI/2, 0., "e", "Energy density") ; 
00805     des_profile(press(), 0., r_max, M_PI/2, 0., "p", "Pressure") ; 
00806     des_profile(ent(), 0., r_max, M_PI/2, 0., "H", "Enthalpy") ;   
00807     }*/
00808 
00809     //-------------------------------------------------
00810     //  Relative change in enthalpy
00811     //-------------------------------------------------
00812 
00813     Tbl diff_ent_tbl = diffrel( ent(), ent_jm1() ) ; 
00814     diff_ent = diff_ent_tbl(0) ; 
00815     for (int l=1; l<nzet; l++) {
00816         diff_ent += diff_ent_tbl(l) ; 
00817     }
00818     diff_ent /= nzet ; 
00819     
00820     
00821     ent_jm1 = ent ; 
00822 
00823 
00824     } // End of main loop
00825     
00826     //=========================================================================
00827     //          End of iteration
00828     //=========================================================================
00829 
00830 
00831 }

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