excision_surf.C

00001 /*
00002  *  Definition of methods for the class Excision_surf and its subclass App_hor
00003  *
00004  */
00006 //                               LOCAL VERSION
00007 //  Several additional functions that may be temporary (on the testing pad...)
00009 
00010 /*
00011  *   Copyright (c) 2008  Jose-Luis Jaramillo & Jerome Novak & Nicolas Vasset
00012  *
00013  *   This file is part of LORENE.
00014  *
00015  *   LORENE is free software; you can redistribute it and/or modify
00016  *   it under the terms of the GNU General Public License version 
00017  *   as published by the Free Software Foundation.
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 char excision_surf_C[] = "$Header: /cvsroot/Lorene/C++/Source/App_hor/excision_surf.C,v 1.4 2010/01/29 15:11:57 n_vasset Exp $" ;
00031 
00032 /*
00033  * $Header: /cvsroot/Lorene/C++/Source/App_hor/excision_surf.C,v 1.4 2010/01/29 15:11:57 n_vasset Exp $
00034  *
00035  */
00036 
00037 // C headers
00038 #include <math.h>
00039 
00040 // Lorene headers
00041 #include "metric.h"
00042 #include "spheroid.h"
00043 #include "utilitaires.h"
00044 #include "param.h"
00045 #include "itbl.h"
00046 #include "map.h"
00047 #include <assert.h>
00048 #include "nbr_spx.h"
00049 #include "math.h"
00050 #include "param_elliptic.h"
00051 #include "tensor.h"
00052 #include "sym_tensor.h"
00053 #include "diff.h"
00054 #include "proto.h"
00055 #include "param.h" 
00056 #include "excision_surf.h"
00057 
00058 //---------------//
00059 //  Constructors //
00060 //--------------// 
00061  
00062 
00063 Excision_surf::Excision_surf(const Scalar& h_in, const Metric& gij, const Sym_tensor& Kij2, const Scalar& ppsi, const Scalar& nn, const Vector& beta, double timestep, int int_nos = 1):
00064   sph(h_in, gij, Kij2),
00065   conf_fact(ppsi),
00066   lapse(nn),
00067   shift(beta),
00068   gamij (gij),
00069   Kij(Kij2),
00070   delta_t(timestep),
00071   no_of_steps(int_nos),
00072   expa(sph.theta_plus()),
00073   dt_expa(sph.theta_plus())
00074 
00075 {
00076   
00077   dt_expa.set_etat_zero();
00078  
00079  set_der_0x0() ;
00080 
00081 }
00082 
00083 
00084 
00085 
00086 
00087 //Copy constructor//
00088 
00089 Excision_surf::Excision_surf (const Excision_surf &exc_in) :sph(exc_in.sph),
00090                                 conf_fact(exc_in.conf_fact),
00091                                 lapse(exc_in.lapse),                                        
00092                                 shift(exc_in.shift),
00093                                 gamij (exc_in.gamij),
00094                                 Kij (exc_in.Kij),
00095                                 delta_t(exc_in.delta_t),
00096                                 no_of_steps(exc_in.no_of_steps),
00097                                 expa(exc_in.expa),
00098                                 dt_expa(exc_in.dt_expa)
00099 
00100 {
00101   set_der_0x0() ; 
00102   
00103 }
00104 
00105 
00106 
00107 
00108 // Assignment to another Excision_surf
00109 void Excision_surf::operator=(const Excision_surf& surf_in)
00110 {
00111 
00112   sph = surf_in.sph ;
00113   conf_fact = surf_in.conf_fact ;
00114   lapse = surf_in.lapse ;
00115   shift = surf_in.shift ;
00116   gamij  = surf_in.gamij ;
00117   Kij = surf_in.Kij ;
00118   delta_t = surf_in.delta_t ;
00119   no_of_steps = surf_in.no_of_steps ;
00120   expa = surf_in.expa;
00121   dt_expa = surf_in.dt_expa;
00122   del_deriv() ;  // Deletes all derived quantities
00123 
00124 }
00125 
00126 //------------//
00127 //Destructor //
00128 //-----------//
00129 
00130 Excision_surf::~Excision_surf()
00131 {
00132   del_deriv() ;
00133 }
00134 
00135 // -----------------//
00136 // Memory management//
00137 //------------------//
00138 void Excision_surf::del_deriv() const {
00139   if (p_get_BC_conf_fact_1 != 0x0) delete p_get_BC_conf_fact_1 ;
00140   if (p_get_BC_lapse_1 != 0x0) delete p_get_BC_lapse_1 ;
00141   if (p_get_BC_shift_1 != 0x0) delete p_get_BC_shift_1 ;
00142   if (p_get_BC_Npsi_1 != 0x0) delete p_get_BC_Npsi_1 ;
00143   if (p_get_BC_conf_fact_2 != 0x0) delete p_get_BC_conf_fact_2 ;
00144   if (p_get_BC_conf_fact_3 != 0x0) delete p_get_BC_conf_fact_3 ;
00145   if (p_get_BC_conf_fact_4 != 0x0) delete p_get_BC_conf_fact_4 ;
00146   if (p_get_BC_lapse_2 != 0x0) delete p_get_BC_lapse_2 ;
00147   if (p_get_BC_lapse_3 != 0x0) delete p_get_BC_lapse_3 ;
00148   if (p_get_BC_lapse_4 != 0x0) delete p_get_BC_lapse_4 ;
00149   if (p_derive_t_expa != 0x0) delete p_derive_t_expa ;
00150   if (p_get_BC_shift_2 != 0x0) delete p_get_BC_shift_2 ;
00151   if (p_get_BC_shift_3 != 0x0) delete p_get_BC_shift_3 ;
00152   if (p_get_BC_shift_4 != 0x0) delete p_get_BC_shift_4 ;
00153   if (p_get_BC_Npsi_2 != 0x0) delete p_get_BC_Npsi_2 ;
00154   if (p_get_BC_Npsi_3 != 0x0) delete p_get_BC_Npsi_3 ;
00155   if (p_get_BC_Npsi_4 != 0x0) delete p_get_BC_Npsi_4 ;
00156   if (p_get_BC_Npsi_5 != 0x0) delete p_get_BC_Npsi_5 ;
00157   set_der_0x0() ;
00158 }
00159 
00160 void Excision_surf::set_der_0x0() const {
00161   p_get_BC_conf_fact_1 = 0x0 ;
00162   p_get_BC_lapse_1 = 0x0 ;
00163   p_get_BC_shift_1 = 0x0 ;
00164   p_get_BC_Npsi_1 = 0x0 ;
00165   p_get_BC_conf_fact_2 = 0x0 ;
00166   p_get_BC_conf_fact_3 = 0x0 ;
00167   p_get_BC_conf_fact_4 = 0x0 ;
00168   p_get_BC_lapse_2 = 0x0 ;
00169   p_get_BC_lapse_3 = 0x0 ;
00170   p_get_BC_lapse_4 = 0x0 ;
00171   p_derive_t_expa = 0x0 ;
00172   p_get_BC_shift_2 = 0x0 ;
00173   p_get_BC_shift_3 = 0x0 ;
00174   p_get_BC_shift_4 = 0x0 ;
00175   p_get_BC_Npsi_2 = 0x0 ;
00176   p_get_BC_Npsi_3 = 0x0 ;
00177   p_get_BC_Npsi_4 = 0x0 ;
00178   p_get_BC_Npsi_5 = 0x0 ;
00179 
00180 } 
00181 
00182 
00183 
00184                 //--------------//
00185                 //    Outputs   //
00186                 //--------------//
00187 
00188 
00189 
00190 // Provides the three parameters to use for hyperbolic evolution of the expansion,
00191 // Using expansion and its time derivative on initial data.
00192 // WARNING: to be called once and for all on initial data. Re-calling it does not make sense.
00193 
00194 void Excision_surf::get_evol_params_from_ID(double alpha, double beta, double gamma, Scalar& Ee, Vector& Jj, Sym_tensor& Ss){
00195   cout << "===========================================================================================" << endl;
00196   cout << "Starting the routine that computes parameters for the hyperbolic evolution of the expansion" << endl;
00197   cout << "Those parameters should be set once and for all: do not call that routine twice" <<endl;
00198   cout << "===========================================================================================" << endl;
00199 
00200   Scalar expa_0= sph.theta_plus();
00201   expa_0.set_spectral_va().ylm();
00202 
00203   set_expa() = expa_0;
00204 
00205   if ((max(expa_0))(0)<=1.e-5)
00206     
00207     {  
00208       cout << "=============================================================================" << endl;
00209       cout << " WARNING: Routine failure..." << endl;
00210       cout << "the horizon expansion is already pretty close to zero..."<<  endl;
00211        cout << "We advise to switch from hyperbolic evolution to parabolic evolution" << endl;
00212        cout << "This routine will not do anything relevant on parameters alpha, beta, gamma" << endl;
00213      cout << "=============================================================================" << endl;
00214      double is_expansion_adapted = 1.;
00215      assert (is_expansion_adapted ==2.);
00216       
00217     return;
00218     }
00219   else{
00220 
00221   Scalar fbN = derive_t_expa(Ee, Jj, Ss);       // Basic "right" time derivative of the expansion from ID
00222   set_dt_expa()=fbN;  
00223 
00224   Scalar tf_zero = 2.*fbN/expa_0; tf_zero.std_spectral_base(); 
00225   tf_zero.set_spectral_va().ylm(); // Relevant quantity for parameter characterization (see notes).
00226   
00227   Mtbl_cf* tfz = tf_zero.set_spectral_va().c_cf;// Mtbl_cf storing the spectral coefficients of tf_zero.
00228   
00229   // Choice for \beta (see notes for all choices)
00230   beta = 2.*(*tfz).val_in_bound_jk(0,0,0);
00231 
00232   cout << "beta:   " << beta << endl;
00233   
00234   // Choice for \gamma
00235   gamma = -beta*beta* (1./8.); // Any choice between zero and -beta*beta*(1./4.) is acceptable.
00236 
00237     cout << "gamma:    " << gamma << endl; 
00238     
00239   // Choice for \alpha, with an additional assertion.
00240     alpha = 0.;
00241     double alpha_aux=0;  
00242   double nb_l = (*tfz).set(0).get_dim(1);
00243     double nb_m = (*tfz).set(0).get_dim(2);
00244       
00245     cout << "nb_l:   " << nb_l << endl;
00246     cout << "nb_m:   " << nb_m << endl;
00247       
00248     if (nb_m==1){
00249     alpha =  2.*fabs(beta - (*tfz).val_in_bound_jk(0,1,0));
00250     }
00251     else{
00252      for (int ii=0; ii <nb_m; ii++){
00253      alpha_aux = 2.*fabs(beta - (*tfz).val_in_bound_jk(0,1,ii));
00254      if (alpha_aux >=alpha){
00255        alpha = alpha_aux;
00256        }
00257     }
00258     }
00259     cout << "alpha:   " << alpha << endl;
00260     // Test for higher harmonics, supposedly of lower amplitude, but... 
00261     for (int ii=2; ii <nb_l; ii++)
00262       for (int jj=0; jj <nb_m; jj++){
00263     alpha_aux =  2.*(beta - (*tfz).val_in_bound_jk(0,ii,jj))/(double(ii*(ii+1)));
00264        if (alpha_aux >= alpha){
00265          cout << "higher Ylm harmonics are predominant in the expansion variation on the horizon!" << endl;
00266          cout << "changing the values of the parameters accordingly..." << endl;
00267          alpha = alpha_aux;}
00268       }
00269 
00270   return;                                                                         
00271 }
00272 }
00273 
00274 //---------//
00275 //Accessors//
00276 //---------//
00277 
00278 // Source for the Neumann BC on the conformal factor, with arbitrary expansion
00279 const Scalar& Excision_surf::get_BC_conf_fact_1(bool isMOTS) const{
00280  
00281  
00282  if (p_get_BC_conf_fact_1 == 0x0){
00283 
00284     //Initialization of expa in the trivial case
00285     Scalar exppa(sph.theta_plus().get_mp());
00286     if ( isMOTS == true)
00287       {
00288     exppa.set_etat_zero();
00289     
00290       } 
00291     else {
00292       assert (expa.get_spectral_va().get_etat() !=0);
00293     exppa = expa;
00294    
00295  
00296 //  expa.spectral_display();
00297 //  int tgh; cin >> tgh;
00298     }
00299 
00300    // 3d interpolation for expa
00301      Scalar expa_3 (lapse.get_mp()); 
00302  
00303   expa_3.allocate_all();
00304   expa_3.std_spectral_base();
00305 
00306   int nz = (*lapse.get_mp().get_mg()).get_nzone();
00307   int nr = (*lapse.get_mp().get_mg()).get_nr(1);
00308   int nt = (*lapse.get_mp().get_mg()).get_nt(1);
00309   int np = (*lapse.get_mp().get_mg()).get_np(1);
00310 
00311 
00312   for (int f= 0; f<nz; f++)
00313     for (int k=0; k<np; k++)
00314       for (int j=0; j<nt; j++) {
00315     for (int l=0; l<nr; l++) {
00316 
00317       expa_3.set_grid_point(f,k,j,l) = exppa.val_grid_point(0,k,j,0);
00318     
00319     }
00320       }
00321 
00322   if (nz >2){
00323   
00324      expa_3.annule_domain(0);
00325     expa_3.annule_domain(nz - 1);
00326   }
00327   expa_3.std_spectral_base();
00328   expa_3.set_spectral_va().ylm();
00329  // End Mapping interpolation
00330 
00331 
00332     Sym_tensor gamconfcov = gamij.cov()/pow(conf_fact, 4); 
00333     gamconfcov.std_spectral_base();
00334     Metric gamconf(gamconfcov);
00335     Vector tilde_s = gamconf.radial_vect();
00336     Scalar bound_psi =   -((1./conf_fact)*contract((contract(Kij,1,tilde_s,0)),0, tilde_s,0));    
00337     bound_psi.annule_domain(nz-1);
00338     bound_psi += -conf_fact*tilde_s.divergence(gamconf);
00339     bound_psi.annule_domain(nz-1);
00340     bound_psi += (conf_fact*conf_fact*conf_fact)*Kij.trace(gamij);
00341     bound_psi = 0.25*bound_psi;
00342     bound_psi.annule_domain(nz-1);
00343     bound_psi = (bound_psi -contract(conf_fact.derive_cov(gamconf),0,tilde_s,0)) + conf_fact.dsdr();
00344     Scalar bound_psi2 = expa_3*((conf_fact*conf_fact*conf_fact))/4.;
00345     // Remark: the used expansion term is actually \frac{\theta^{+}}{N}, as it is not normalized by the lapse in the Spheroid class.
00346     bound_psi2.annule_domain(nz -1);
00347     bound_psi = bound_psi + bound_psi2;
00348     bound_psi.std_spectral_base();
00349     bound_psi.set_spectral_va().ylm();    
00350 
00351   p_get_BC_conf_fact_1 = new Scalar(bound_psi);
00352 
00353   
00354 }
00355   return *p_get_BC_conf_fact_1 ;
00356 
00357 }
00358 
00359 
00360 
00361 
00362 // Source for the Dirichlet BC on the conformal factor, based on a parabolic driver
00363 const Scalar& Excision_surf::get_BC_conf_fact_2(double c_psi_lap, double c_psi_fin, Scalar& expa_fin) const{
00364   if (p_get_BC_conf_fact_2 == 0x0){
00365 
00366     // Definition of ff
00367     // ================
00368 
00369     // Start Mapping interpolation
00370     Scalar thetaplus = sph.theta_plus();
00371       Scalar theta_plus3 (lapse.get_mp()); 
00372  
00373   theta_plus3.allocate_all();
00374   theta_plus3.std_spectral_base();
00375 
00376       Scalar expa_fin3 (lapse.get_mp()); 
00377  
00378   expa_fin3.allocate_all();
00379   expa_fin3.std_spectral_base();
00380 
00381   int nz = (*lapse.get_mp().get_mg()).get_nzone();
00382   int nr = (*lapse.get_mp().get_mg()).get_nr(1);
00383   int nt = (*lapse.get_mp().get_mg()).get_nt(1);
00384   int np = (*lapse.get_mp().get_mg()).get_np(1);
00385 
00386 
00387   for (int f= 0; f<nz; f++)
00388     for (int k=0; k<np; k++)
00389       for (int j=0; j<nt; j++) {
00390     for (int l=0; l<nr; l++) {
00391         
00392       theta_plus3.set_grid_point(f,k,j,l) = thetaplus.val_grid_point(0,k,j,0);
00393       expa_fin3.set_grid_point(f,k,j,l) = expa_fin.val_grid_point(0,k,j,0);
00394     
00395     }
00396       }
00397   if (nz >2){
00398      theta_plus3.annule_domain(0);
00399     theta_plus3.annule_domain(nz - 1);
00400      expa_fin3.annule_domain(0);
00401     expa_fin3.annule_domain(nz - 1);
00402   }
00403     // End Mapping interpolation
00404   
00405 
00406   Scalar ff = lapse*(c_psi_lap*theta_plus3.lapang() + c_psi_fin*(theta_plus3 - expa_fin3));
00407   ff.std_spectral_base();
00408 
00409   // Definition of k_1
00410   Scalar k_1 =delta_t*ff;
00411    
00412   // Intermediate value of the expansion, for Runge-Kutta 2nd order scheme
00413   Scalar psi_int = conf_fact + k_1; psi_int.std_spectral_base();
00414   Sym_tensor gamconfcov = gamij.cov()/pow(psi_int, 4); // think about the consistency of redifining the conformal metric
00415                                                        // since in this manner the unimodular conditions is lost
00416   gamconfcov.std_spectral_base();
00417   Metric gamconf(gamconfcov);
00418   Vector tilde_s = gamconf.radial_vect();
00419   Scalar theta_int =   ((1./psi_int)*contract((contract(Kij,1,tilde_s,0)),0, tilde_s,0));    
00420   theta_int += psi_int*tilde_s.divergence(gamconf);
00421   theta_int += 4.*contract(psi_int.derive_cov(gamconf),0,tilde_s,0);
00422   theta_int = theta_int/pow(psi_int,3);
00423   theta_int += -Kij.trace(gamij);
00424   theta_int.std_spectral_base();
00425  
00426   // Recalculation of ff with intermediate values. 
00427   Scalar ff_int =  lapse*(c_psi_lap*theta_int.lapang() + c_psi_fin*(theta_int - expa_fin3));
00428  
00429   // Definition of k_2
00430   Scalar k_2 = delta_t*ff_int; 
00431   k_2.std_spectral_base();
00432  
00433   // Result of RK2 evolution
00434   if (nz >2){
00435     k_2.annule_domain(nz-1);}
00436   Scalar bound_psi = conf_fact + k_2;
00437   bound_psi.std_spectral_base();
00438   bound_psi.set_spectral_va().ylm();
00439   
00440   // Assignment of output
00441   p_get_BC_conf_fact_2 = new Scalar(bound_psi);
00442 
00443 }
00444   return *p_get_BC_conf_fact_2 ;
00445 }
00446 
00447 
00448 
00449 
00450 // Source for the Neumann BC on the conformal factor, based on a parabolic driver for the expansion
00451 const Scalar& Excision_surf::get_BC_conf_fact_3(double c_theta_lap, double c_theta_fin, Scalar& expa_fin) const{
00452   if (p_get_BC_conf_fact_3 == 0x0){
00453 
00454     // Definition of ff
00455     // ================
00456 
00457     // Start Mapping interpolation
00458     Scalar thetaplus = sph.theta_plus();
00459       Scalar theta_plus3 (lapse.get_mp()); 
00460  
00461   theta_plus3.allocate_all();
00462   theta_plus3.std_spectral_base();
00463 
00464       Scalar expa_fin3 (lapse.get_mp()); 
00465  
00466   expa_fin3.allocate_all();
00467   expa_fin3.std_spectral_base();
00468 
00469   int nz = (*lapse.get_mp().get_mg()).get_nzone();
00470   int nr = (*lapse.get_mp().get_mg()).get_nr(1);
00471   int nt = (*lapse.get_mp().get_mg()).get_nt(1);
00472   int np = (*lapse.get_mp().get_mg()).get_np(1);
00473 
00474 
00475   for (int f= 0; f<nz; f++)
00476     for (int k=0; k<np; k++)
00477       for (int j=0; j<nt; j++) {
00478     for (int l=0; l<nr; l++) {
00479         
00480       theta_plus3.set_grid_point(f,k,j,l) = thetaplus.val_grid_point(0,k,j,0);
00481       expa_fin3.set_grid_point(f,k,j,l) = expa_fin.val_grid_point(0,k,j,0);
00482     
00483     }
00484       }
00485   if (nz >2){
00486      theta_plus3.annule_domain(0);
00487     theta_plus3.annule_domain(nz - 1);
00488      expa_fin3.annule_domain(0);
00489     expa_fin3.annule_domain(nz - 1);
00490   }
00491 
00492     // End Mapping interpolation
00493 //   cout << "convergence?" << endl;
00494 //   cout << expa_fin3.val_grid_point(1,0,0,0) << endl;
00495 //   cout << theta_plus3.val_grid_point(1,0,0,0) << endl;
00496   
00497 
00498   Scalar ff = lapse*(c_theta_lap*theta_plus3.lapang() + c_theta_fin*(theta_plus3 - expa_fin3));
00499   ff.std_spectral_base();
00500 
00501   // Definition of k_1
00502   Scalar k_1 =delta_t*ff;
00503    
00504   // Intermediate value of the expansion, for Runge-Kutta 2nd order scheme
00505   Scalar theta_int = theta_plus3 + k_1; theta_int.std_spectral_base();
00506 
00507   // Recalculation of ff with intermediate values. 
00508   Scalar ff_int =  lapse*(c_theta_lap*theta_int.lapang() + c_theta_fin*(theta_int - expa_fin3));
00509  
00510   // Definition of k_2
00511   Scalar k_2 = delta_t*ff_int; 
00512   k_2.std_spectral_base();
00513  
00514   // Result of RK2 evolution
00515   Scalar bound_theta = theta_plus3 + k_2;
00516   bound_theta.std_spectral_base();
00517   
00518   // Calculation of Neumann BC for Psi
00519   Scalar bound_psi = get_BC_conf_fact_1(true) + bound_theta*pow(conf_fact,3)/4.;
00520   bound_psi.std_spectral_base();
00521   bound_psi.set_spectral_va().ylm();
00522 
00523   // Assignment of output
00524   p_get_BC_conf_fact_3 = new Scalar(bound_psi);
00525 
00526 }
00527   return *p_get_BC_conf_fact_3 ;
00528 }
00529 
00530 // Source for the Dirchlet BC on the conformal factor, based on the consistency condition derived from the trace
00531 // of the kinematical relation
00532 const Scalar& Excision_surf::get_BC_conf_fact_4() const{
00533   if (p_get_BC_conf_fact_4 == 0x0){
00534 
00535     // Definition of ff
00536     // ================
00537     const Metric_flat& flat = lapse.get_mp().flat_met_spher() ; 
00538     
00539  int nz = (*lapse.get_mp().get_mg()).get_nzone();
00540     Scalar ff = contract(shift, 0, conf_fact.derive_cov(flat), 0) 
00541       + 1./6. * (conf_fact * (shift.divergence(flat) - lapse*Kij.trace(gamij))) ; // Add he N K term
00542     // Divergence with respect to the conformal metric coincides with divergence withh respect to the
00543     // flat metric (from the unimodular condition on the conformal metric)
00544     // In this way, we do not need to recalculate a conformal metric in the intermediate RK step that would violated
00545     // the unimodular condition
00546 
00547     ff.std_spectral_base() ;
00548 
00549     // Definition of k_1
00550     Scalar k_1 =delta_t*ff;
00551     k_1.annule_domain(nz-1);
00552 
00553     
00554     // Intermediate value of the expansion, for Runge-Kutta 2nd order scheme
00555     Scalar psi_int = conf_fact + k_1; psi_int.std_spectral_base();
00556     psi_int.annule_domain(nz-1);
00557 
00558     // Recalculation of ff with intermediate values. 
00559     Scalar ff_int =  contract(shift, 0, psi_int.derive_cov(flat), 0) 
00560                     + 1./6. * psi_int * (shift.divergence(flat) -  lapse*Kij.trace(gamij)) ;  // Add he N K term
00561 
00562  
00563     // Definition of k_2
00564     Scalar k_2 = delta_t*ff_int; 
00565     
00566     //  k_2 = k_2*1000; //TO REMOVE
00567 
00568     k_2.std_spectral_base();
00569 
00570     k_2.annule_domain(nz-1);
00571     // Result of RK2 evolution
00572     Scalar bound_psi = conf_fact + k_2;
00573 
00574 
00575     bound_psi.std_spectral_base();
00576     bound_psi.set_spectral_va().ylm();
00577 
00578     // Assignment of output
00579     p_get_BC_conf_fact_4 = new Scalar(bound_psi);
00580 
00581 }
00582   return *p_get_BC_conf_fact_4 ;
00583 }
00584 
00585 
00586 
00587 
00588 // Source for the Dirichlet BC on the lapse
00589 const Scalar& Excision_surf::get_BC_lapse_1(double value) const{
00590   if (p_get_BC_lapse_1 == 0x0){
00591 
00592     Scalar bound_lapse(lapse.get_mp()); 
00593     bound_lapse = value; bound_lapse.std_spectral_base();
00594     bound_lapse.set_spectral_va().ylm();
00595     p_get_BC_lapse_1 = new Scalar(bound_lapse); 
00596     
00597 }
00598   return *p_get_BC_lapse_1 ;
00599 }
00600 
00601 // Source for Dirichlet BC on the lapse, based on a parabolic driver
00602 const Scalar& Excision_surf::get_BC_lapse_2(double lapse_fin, double c_lapse_lap, double c_lapse_fin) const{
00603   if (p_get_BC_lapse_2 == 0x0){
00604 
00605   
00606   
00607     Scalar ff = lapse*(c_lapse_lap*lapse.lapang() + c_lapse_fin*lapse);
00608   ff.std_spectral_base();
00609   ff = ff -lapse*c_lapse_fin*lapse_fin;
00610   ff.std_spectral_base();
00611 
00612 
00613   // Definition of k_1
00614   Scalar k_1 =delta_t*ff;
00615    
00616   // Intermediate value of lapse, for Runge-Kutta 2nd order scheme
00617   Scalar lapse_int = lapse + k_1; lapse_int.std_spectral_base();
00618 
00619   // Recalculation of ff with intermediate values. 
00620   Scalar ff_int =  lapse*(c_lapse_lap*lapse_int.lapang() + c_lapse_fin*lapse_int);
00621   ff_int.std_spectral_base();
00622   ff_int = ff_int -lapse*c_lapse_fin*lapse_fin;
00623   ff_int.std_spectral_base();
00624   
00625  
00626   // Definition of k_2
00627   Scalar k_2 = delta_t*ff_int; 
00628   k_2.std_spectral_base();
00629  
00630   // Result of RK2 evolution
00631   Scalar bound_lapse = lapse + k_2;
00632   bound_lapse.std_spectral_base();
00633   bound_lapse.set_spectral_va().ylm();
00634 
00635   
00636         p_get_BC_lapse_2 = new Scalar(bound_lapse); 
00637     
00638 }
00639   return *p_get_BC_lapse_2 ;
00640 }
00641 
00642 
00643 
00644 
00645 // Source for Dirichlet BC on the lapse, based on einstein equations!! dttheta is 2d scalar, and matter quantities are 3d.
00646 const Scalar& Excision_surf::get_BC_lapse_3(Scalar& dttheta, Scalar& Ee, Vector& Jj, Sym_tensor& Sij, bool sph_sym) const{
00647   if (p_get_BC_lapse_3 == 0x0){
00648   int nz2 = (*lapse.get_mp().get_mg()).get_nzone();
00649     // Radial vector for the full 3-metric.
00650      Vector sss = gamij.radial_vect();
00651      Vector sss_down = sss.up_down(gamij);
00652      Scalar bb = contract (shift,0, sss_down,0); 
00653 
00654      Scalar bound_N3(lapse.get_mp()); bound_N3.allocate_all(); bound_N3.std_spectral_base();// Result to be stored there.
00655     
00656     Scalar Kappa  = bb*contract(contract(Kij,0,sss,0),0,sss,0) - contract(sss,0, lapse.derive_cov(gamij),0);
00657     Scalar Matter = 8.*M_PI*(bb*Ee);
00658     Matter.annule_domain(nz2-1);
00659     Matter += - 8.*M_PI*(bb + lapse)*contract(Jj,0,sss_down,0);
00660     Matter.annule_domain(nz2-1);
00661     Matter +=  8.*M_PI*lapse*contract(contract(Sij,0,sss_down,0),0,sss_down,0);
00662   
00663   
00664   // 2d interpolation of the Kappa constant and the matter terms.
00665   
00666   Scalar Kappa2 = sph.get_ricci();
00667   Kappa2.annule_hard();
00668   Scalar bb2 = Kappa2;
00669   Scalar Matter2 = Kappa2;
00670   Scalar nn2 = Kappa2;
00671 
00672   const Metric_flat& flat2 = Kappa2.get_mp().flat_met_spher();
00673 
00674   int nt = (*Kappa2.get_mp().get_mg()).get_nt(0);
00675   int np = (*Kappa2.get_mp().get_mg()).get_np(0);
00676     for (int k=0; k<np; k++)
00677       for (int j=0; j<nt; j++) {
00678       Kappa2.set_grid_point(0,k,j,0) = Kappa.val_grid_point(1,k,j,0);
00679       bb2.set_grid_point(0,k,j,0) = bb.val_grid_point(1,k,j,0);
00680       Matter2.set_grid_point(0,k,j,0) = Matter.val_grid_point(1,k,j,0);
00681       nn2.set_grid_point(0,k,j,0) = lapse.val_grid_point(1,k,j,0);
00682       }
00683       
00684     Kappa2.std_spectral_base();
00685     bb2.std_spectral_base();
00686     Matter2.std_spectral_base();
00687 
00688     Scalar Tplus = sph.theta_plus();
00689     Scalar Tminus = sph.theta_minus();
00690     Scalar Ricci = sph.get_ricci();
00691     Vector Ll = sph.get_ll();
00692     Sym_tensor Shear = sph.shear();
00693     Metric qab = sph.get_qab();
00694 
00695     Scalar source = 2.*contract(Ll.up_down(qab),0,sph.derive_cov2d(bb2),0) + bb2*(contract(sph.derive_cov2d(Ll.up_down(qab)),0,1)+ contract(Ll,0,Ll.up_down(qab),0)- 0.5*(Ricci + Tplus*Tminus) + 0.25*Tplus*Tplus + 0.5*contract(Shear.up_down(qab),0,1,Shear,0,1)) + Matter2 + Tplus*Kappa2 + dttheta;
00696  
00697     Scalar lapb = contract(sph.derive_cov2d(sph.derive_cov2d(bb2)).up(0,qab),0,1);
00698     
00699     source = source + lapb;
00700 
00701   
00702     Scalar source_add =  2.*contract(Ll.up_down(qab),0,sph.derive_cov2d(nn2),0); 
00703 
00704     source = source - source_add; 
00705     
00706     Scalar sqrt_q_h2 = sph.sqrt_q() * sph.get_hsurf() * sph.get_hsurf() ;
00707     Tensor Delta2 = sph.delta();
00708     Sym_tensor qab_con = sph.get_qab().con() / (sph.get_hsurf() * sph.get_hsurf()) ;
00709   qab_con.set(1,1) = 1. ;
00710   qab_con.set(1,2) = 0. ;
00711   qab_con.set(1,3) = 0. ;
00712   qab_con.std_spectral_base() ;
00713 
00714   Sym_tensor hab =(qab_con*sqrt_q_h2 - flat2.con()) / (sph.get_hsurf()*sph.get_hsurf()) ;
00715   hab.set(1,1) = 1. ;
00716   hab.set(1,2) = 0. ;
00717   hab.set(1,3) = 0. ;
00718   hab.std_spectral_base() ;
00719 
00720   Vector dN = sph.derive_cov2dflat(nn2);
00721   Tensor ddN = sph.derive_cov2dflat(dN);
00722 
00723   Scalar lap_rem = contract(qab_con, 0,1, contract(Delta2,0,dN,0),0,1)*sqrt_q_h2 - sph.get_hsurf()*sph.get_hsurf()*contract(hab,0,1,ddN,0,1);// What remains of the laplacian
00724 
00725   source = sqrt_q_h2*source + lap_rem;
00726 
00727   Scalar bound_N=nn2;
00728 
00729     if (sph_sym == true){
00730       Scalar lapang_s_par = (contract(sph.derive_cov2d(Ll.up_down(qab)),0,1)+ contract(Ll,0,Ll.up_down(qab),0)- 0.5*(Ricci + Tplus*Tminus) - 0.25*Tplus*Tplus - 0.5*contract(Shear.up_down(qab),0,1,Shear,0,1))*sqrt_q_h2;
00731       double lapang_par = lapang_s_par.val_grid_point(0,0,0,0);
00732      
00733       bound_N = source.poisson_angu(lapang_par);
00734       bound_N.set_spectral_va().coef_i();
00735       bound_N.set_spectral_va().ylm();
00736     }
00737 
00738     else{
00739       cout << "non_spherical case has not been treated yet!" << endl;}
00740 
00741     // Interpolation to get a 3d value (as poisson solvers take this for boundary...)
00742   
00743   
00744  
00745 
00746   int nr2 = (*lapse.get_mp().get_mg()).get_nr(1);
00747   int nt2 = (*lapse.get_mp().get_mg()).get_nt(1);
00748   int np2 = (*lapse.get_mp().get_mg()).get_np(1);
00749 
00750 
00751   for (int f= 0; f<nz2; f++)
00752     for (int k=0; k<np2; k++)
00753       for (int j=0; j<nt2; j++) {
00754     for (int l=0; l<nr2; l++) {
00755         
00756       bound_N3.set_grid_point(f,k,j,l) = bound_N.val_grid_point(0,k,j,0);
00757 
00758     
00759     }
00760       }
00761   if (nz2 >2){
00762     bound_N3.annule_domain(nz2 - 1);
00763 
00764   }
00765     
00766   bound_N3.std_spectral_base();
00767   bound_N3.set_spectral_va().ylm();
00768 
00769   // End interpolation
00770 
00771     p_get_BC_lapse_3 = new Scalar(bound_N3); 
00772     
00773   }
00774   return *p_get_BC_lapse_3 ;
00775 }
00776 
00777 
00778 
00779 
00780 
00781 // Used to retrieve d (theta)/dt over only initial data. Probably obsolete in a practical use on CoCoNuT. Uses the same formalism as get_BC_lapse_3().
00782 const Scalar& Excision_surf::derive_t_expa( Scalar& Ee, Vector& Jj, Sym_tensor& Sij)const{
00783 if (p_derive_t_expa == 0x0){
00784 
00785   int nz2 = (*lapse.get_mp().get_mg()).get_nzone();
00786     // Radial vector for the full 3-metric.
00787      Vector sss = gamij.radial_vect();
00788      Vector sss_down = sss.up_down(gamij);
00789      Scalar bb = contract (shift,0, sss_down,0); 
00790     
00791     Scalar Kappa  = bb*contract(contract(Kij,0,sss,0),0,sss,0) - contract(sss,0, lapse.derive_cov(gamij),0);
00792     Scalar Matter = 8.*M_PI*(bb*Ee);
00793     Matter.annule_domain(nz2-1);
00794     Matter += - 8.*M_PI*(bb + lapse)*contract(Jj,0,sss_down,0);
00795     Matter.annule_domain(nz2-1);
00796     Matter +=  8.*M_PI*lapse*contract(contract(Sij,0,sss_down,0),0,sss_down,0);
00797   
00798   
00799   // 2d interpolation of the Kappa constant and the matter terms.
00800   
00801   Scalar Kappa2 = sph.get_ricci();
00802   Kappa2.annule_hard();
00803   Scalar bb2 = Kappa2;
00804   Scalar Matter2 = Kappa2;
00805   Scalar nn2 = Kappa2;
00806 
00807   int nt = (*Kappa2.get_mp().get_mg()).get_nt(0);
00808   int np = (*Kappa2.get_mp().get_mg()).get_np(0);
00809     for (int k=0; k<np; k++)
00810       for (int j=0; j<nt; j++) {
00811       Kappa2.set_grid_point(0,k,j,0) = Kappa.val_grid_point(1,k,j,0);
00812       bb2.set_grid_point(0,k,j,0) = bb.val_grid_point(1,k,j,0);
00813       Matter2.set_grid_point(0,k,j,0) = Matter.val_grid_point(1,k,j,0);
00814       nn2.set_grid_point(0,k,j,0) = lapse.val_grid_point(1,k,j,0);
00815       }
00816       
00817     Kappa2.std_spectral_base();
00818     bb2.std_spectral_base();
00819     Matter2.std_spectral_base();
00820 
00821     Scalar Tplus = sph.theta_plus();
00822     Scalar Tminus = sph.theta_minus();
00823     Scalar Ricci2 = sph.get_ricci();
00824     Vector Ll = sph.get_ll();
00825     Sym_tensor Shear = sph.shear();
00826     Metric qab = sph.get_qab();
00827 
00828     Scalar source = 2.*contract(Ll.up_down(qab),0,sph.derive_cov2d(nn2 -bb2),0) + (nn2- bb2)*(contract(sph.derive_cov2d(Ll.up_down(qab)),0,1)+ contract(Ll,0,Ll.up_down(qab),0)- 0.5*(Ricci2 + Tplus*Tminus)) -(bb2 +nn2)*(0.25*Tplus*Tplus + 0.5*contract(Shear.up_down(qab),0,1,Shear,0,1)) - Matter2 - Tplus*Kappa2 ;
00829  
00830     Scalar lapNmb = contract(sph.derive_cov2d(sph.derive_cov2d(nn2-bb2)).up(0,qab),0,1);
00831     
00832     source = source + lapNmb;
00833     source.set_spectral_va().ylm();
00834 
00835     Scalar difftheta = source*delta_t;
00836     cout << "mean difference between old and new expansion" << endl;
00837     cout << difftheta.val_grid_point(0,0,0,0) << endl;
00838 
00839  
00840   p_derive_t_expa = new Scalar (source);
00841  }
00842 
00843  return *p_derive_t_expa ;
00844 }
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 // Source for the Dirichlet BC on the shift
00854 const Vector& Excision_surf::get_BC_shift_1(double Omega) const{
00855   if (p_get_BC_shift_1 == 0x0){
00856     
00857     // Radial vector for the full 3-metric.
00858     Vector sss = gamij.radial_vect();
00859     
00860     // Boundary value for the radial part of the shift
00861     Scalar bound = lapse ;
00862     //   bound = bound + 0.05; // REMOVE real quick
00863 
00864     // Tangent part of the shift
00865     // (For now, only axisymmetric configurations are envisaged)
00866     
00867     Vector V_par = shift;
00868     Scalar V_phi = lapse; V_phi.annule_hard(); V_phi = 1.; // Rotation parameter for spacetime
00869     V_phi.std_spectral_base() ; V_phi.mult_rsint();
00870     V_par.set(1).annule_hard();
00871     V_par.set(2).annule_hard();
00872     V_par.set(3) = V_phi;
00873     
00874     V_par = V_par*Omega;
00875     
00876     
00877     // Construction of the total shift boundary condition
00878     Vector bound_shift = bound*sss + V_par;
00879     bound_shift.std_spectral_base(); // Boundary is fixed by value of 3 components of a vector (rather than value of potentials) 
00880     p_get_BC_shift_1 = new Vector(bound_shift);
00881   }
00882   return *p_get_BC_shift_1 ;
00883 }
00884 
00885 
00886 // Source for the Dirichlet BC on the shift, based on a Parabolic driver
00887 const Vector& Excision_surf::get_BC_shift_2(double c_bb_lap, double c_bb_fin, double c_V_lap, double epsilon) const{
00888   if (p_get_BC_shift_2 == 0x0){
00889 
00890     // Radial vector for the full 3-metric.
00891      Vector sss = gamij.radial_vect();
00892      Vector sss_down = sss.up_down(gamij);
00893      
00894 //     // Boundary value for the radial part of the shift: parabolic driver for (b-N)
00895      //  Scalar bound = lapse ; 
00896      Scalar bb = contract (shift,0, sss_down,0); 
00897    
00898   Scalar b_min_N = bb - lapse;
00899   Scalar ff = lapse*(c_bb_lap*b_min_N.lapang() + c_bb_fin*b_min_N);
00900  
00901   ff.std_spectral_base();
00902  
00903 
00904   // Definition of k_1
00905   Scalar k_1 =delta_t*ff;
00906    
00907   // Intermediate value of b-N, for Runge-Kutta 2nd order scheme
00908   Scalar b_min_N_int = b_min_N + k_1; b_min_N_int.std_spectral_base();
00909 
00910   // Recalculation of ff with intermediate values. 
00911   Scalar ff_int =  lapse*(c_bb_lap*b_min_N_int.lapang() + c_bb_fin*b_min_N_int);
00912 
00913   // Definition of k_2
00914   Scalar k_2 = delta_t*ff_int; 
00915   k_2.std_spectral_base();
00916  
00917   // Result of RK2 evolution
00918   Scalar bound_b_min_N =  b_min_N + k_2;
00919   bound_b_min_N.std_spectral_base();
00920   bound_b_min_N.set_spectral_va().ylm();
00921 
00922   Scalar bb2 = bound_b_min_N + lapse; // Look out for additional term for time variation of lapse and sss
00923   
00924 
00925   // Tangent part of the shift, with parabolic driver
00926   
00927   
00928   Vector V_par = shift - bb*sss;
00929   Sym_tensor q_upup = gamij.con() - sss*sss;
00930   Sym_tensor q_downdown = gamij.cov() - sss_down*sss_down;
00931  Tensor q_updown = q_upup.down(1, gamij); 
00932 
00933  
00934 
00935  
00936 
00937   // Calculation of the conformal 2d laplacian of V
00938  Tensor d_V = contract(q_updown, 1, contract(q_updown,0 , V_par.derive_cov(gamij),1 ),1);
00939  Tensor d_V_con = contract(d_V,1,q_upup,1);
00940   Tensor dd_V = d_V_con.derive_cov(gamij);
00941   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
00942   dd_V = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V, 2), 2), 2);
00943   Tensor dd_Vdown = contract (dd_V,1,q_downdown,1);
00944   Vector Ricci1 = contract(dd_Vdown,0,1) - contract(dd_Vdown,0,2);    
00945   Vector Ricci2 = contract (q_upup,1,Ricci1,0);
00946   Vector lap_V = contract(dd_V, 1,2);
00947 
00948 
00949 
00950 //   Tensor dd_V = V_par.derive_con(gamij);
00951 //   dd_V = contract(q_updown, 1, contract(q_updown,1 ,dd_V, 0), 1);
00952 //   Vector lap_V = contract(q_updown, 1, contract(dd_V.derive_cov(gamij),1,2), 0);
00953 
00954 
00955   
00956   // 3d interpolation of the Ricci scalar on the surface.
00957   
00958   Scalar ricci2 = sph.get_ricci();
00959   
00960      // Start Mapping interpolation
00961  
00962       Scalar ricci3 (lapse.get_mp()); 
00963  
00964   ricci3.allocate_all();
00965   ricci3.std_spectral_base();
00966 
00967   int nz = (*lapse.get_mp().get_mg()).get_nzone();
00968   int nr = (*lapse.get_mp().get_mg()).get_nr(1);
00969   int nt = (*lapse.get_mp().get_mg()).get_nt(1);
00970   int np = (*lapse.get_mp().get_mg()).get_np(1);
00971 
00972 
00973   for (int f= 0; f<nz; f++)
00974     for (int k=0; k<np; k++)
00975       for (int j=0; j<nt; j++) {
00976     for (int l=0; l<nr; l++) {
00977         
00978       ricci3.set_grid_point(f,k,j,l) = ricci2.val_grid_point(0,k,j,0);
00979 
00980     
00981     }
00982       }
00983   if (nz >2){
00984     //     ricci3.annule_domain(0);
00985     ricci3.annule_domain(nz - 1);
00986 
00987   }
00988     // End Mapping interpolation
00989   
00990     // Construction of the Ricci COV tensor on the sphere
00991  
00992   Sym_tensor ricci_t = gamij.cov() - sss_down*sss_down;
00993   ricci_t = 0.5*ricci3*ricci_t;
00994   ricci_t.std_spectral_base();
00995  
00996   Tensor ricci_t_updown = contract(q_upup,0, ricci_t,0); 
00997   
00998   // Calculation of ff 
00999 
01000   // Vector ffV = c_V_lap*lapse*(lap_V + contract(ricci_t_updown,1, V_par,0));
01001    Vector ffV = c_V_lap*lapse*(lap_V + Ricci2);
01002 
01003   ffV.annule_domain(nz-1);
01004 
01005 
01006 //   cout << "verification of vanishing shear" << endl;
01007 //   cout << "points on the surface" << endl;
01008   
01009 //   Tbl val_ffV(3, nt, np);
01010 //   val_ffV.set_etat_qcq();
01011 //   for(int mm=0; mm <np; mm++)
01012 //     for (int pp=0; pp<nt; pp++){
01013 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01014 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01015 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01016 //     }
01017 
01018 //   //  cout << val_ffV<< endl;
01019 //   cout << max(val_ffV) << endl;
01020 //   val_ffV.set_etat_nondef();
01021  
01022  
01023 
01024    ffV = ffV + epsilon*lapse*contract(V_par,0,V_par.derive_cov(gamij),1); // Add of dragging term for time transport.
01025   ffV.annule_domain(nz-1);
01026 
01027   ffV.std_spectral_base();
01028 
01029 //   cout << "verification of vanishing shear with dragging" << endl;
01030 //  cout << "points on the surface" << endl;
01031 //   val_ffV.set_etat_qcq();
01032 //   for(int mm=0; mm <np; mm++)
01033 //     for (int pp=0; pp<nt; pp++){
01034 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01035 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01036 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01037 //     }
01038 
01039 //   //  cout << val_ffV<< endl;
01040 //   cout << max(val_ffV) << endl;
01041 //   val_ffV.set_etat_nondef();
01042  
01043  
01044 
01045 
01046   // Definition of k_1
01047   Vector k_1V =delta_t*ffV;
01048    
01049   // Intermediate value of Npsi, for Runge-Kutta 2nd order scheme
01050   if (nz >2){
01051     k_1V.annule_domain(nz-1);
01052   }                             // Patch to avoid dzpuis problems if existent.
01053   Vector V_par_int = V_par + k_1V;// V_par_int.std_spectral_base();
01054 
01055   // Calculation of the conformal 2d laplacian of V
01056  Tensor d_V_int = contract(q_updown, 1, contract(q_updown,0 , V_par_int.derive_cov(gamij),1 ),1);
01057  Tensor d_V_con_int = contract(d_V_int,1,q_upup,1);
01058   Tensor dd_V_int = d_V_con_int.derive_cov(gamij);
01059   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01060   dd_V_int = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V_int, 2), 2), 2);
01061   Tensor dd_Vdown_int = contract (dd_V_int,1,q_downdown,1);
01062   Vector Ricci1_int = contract(dd_Vdown_int,0,1) - contract(dd_Vdown_int,0,2);    
01063   Vector Ricci2_int = contract (q_upup,1,Ricci1_int,0);
01064   Vector lap_V_int = contract(dd_V_int, 1,2);
01065 
01066 
01067   // Recalculation of ff with intermediate values.
01068 //   Tensor dd_V_int = V_par_int.derive_con(gamij).derive_cov(gamij);
01069 //   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01070 //   dd_V_int = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V_int, 2), 2), 2);
01071 //   Vector lap_V_int = contract(dd_V_int, 1,2);
01072  
01073   Vector ffV_int =  c_V_lap*lapse*(lap_V_int + contract(ricci_t_updown,1, V_par_int,0));
01074   ffV_int.annule_domain(nz-1);
01075    ffV_int = ffV_int + epsilon*lapse*contract(V_par_int,0,V_par_int.derive_cov(gamij),1); // Add of dragging term for time transport.
01076 
01077    //  ffV_int = -ffV_int; // Only a test..
01078 
01079 
01080   ffV_int.annule_domain(nz-1);
01081  
01082 
01083 //   cout << "verification of vanishing shear for intermediate RK value" << endl;
01084 //   cout << "points on the surface" << endl;
01085 
01086 
01087 //   val_ffV.set_etat_qcq();
01088 //   for(int mm=0; mm <np; mm++)
01089 //     for (int pp=0; pp<nt; pp++){
01090 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01091 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01092 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01093 //     }
01094 
01095 //   //  cout << val_ffV<< endl;
01096 //   cout << max(val_ffV) << endl;
01097 //   val_ffV.set_etat_nondef();
01098 
01099 
01100 
01101   // Definition of k_2
01102   Vector k_2V = delta_t*ffV_int; 
01103   //  k_2.std_spectral_base();
01104  
01105   // Result of RK2 evolution
01106   if (nz >2){
01107     k_2V.annule_domain(nz-1);
01108   }
01109   Vector bound_V = V_par + k_2V;
01110   //  bound_V.std_spectral_base();
01111 
01112        // Construction of the total shift boundary condition
01113        Vector bound_shift = bb2*sss + bound_V;
01114        bound_shift.std_spectral_base();
01115        p_get_BC_shift_2 = new Vector(bound_shift);
01116 }
01117   return *p_get_BC_shift_2 ;
01118 }
01119 
01120 
01121 
01122 
01123 
01124 // Source for the Dirichlet BC on the shift, based on kinematical relation for the radial part, and a parabolic evolution for the tangent part.
01125 // It takes as a fixed argument the time derivative of the psi factor, that can be deduced from the function.get_BC_conf_fact_4(). 
01126 const Vector& Excision_surf::get_BC_shift_3(Scalar& dtpsi, double c_V_lap, double epsilon) const{
01127   if (p_get_BC_shift_3 == 0x0){
01128 
01129     // Radial vector for the full 3-metric.
01130      Vector sss = gamij.radial_vect();
01131      Vector sss_down = sss.up_down(gamij);
01132      
01133     const Metric_flat& flat = lapse.get_mp().flat_met_spher() ; 
01134     
01135  int nz = (*lapse.get_mp().get_mg()).get_nzone();
01136 
01137 //     // Boundary value for the radial part of the shift: parabolic driver for (b-N)
01138      //  Scalar bound = lapse ; 
01139      Scalar bb = contract (shift,0, sss_down,0); 
01140 
01141      Scalar pure_source = contract(sss,0,bb.derive_cov(flat),0)*conf_fact*1./6.;
01142      pure_source.annule_domain(nz-1); // CAREFUL
01143      pure_source = dtpsi - pure_source;
01144      pure_source.annule_domain(nz-1);
01145      
01146      Scalar factor = conf_fact*sss.divergence(flat)*1./6.;
01147      factor.annule_domain(nz-1);
01148      factor = factor + contract (sss, 0, conf_fact.derive_cov(flat),0);
01149     
01150      Scalar source = pure_source/factor;
01151      
01152 
01153 
01154      Scalar bb2 = source; // Look out for additional term for time variation of lapse and sss
01155   
01156 
01157   // Tangent part of the shift, with parabolic driver
01158   
01159   
01160   Vector V_par = shift - bb*sss;
01161   Sym_tensor q_upup = gamij.con() - sss*sss;
01162   Sym_tensor q_downdown = gamij.cov() - sss_down*sss_down;
01163  Tensor q_updown = q_upup.down(1, gamij); 
01164 
01165  
01166   // Calculation of the conformal 2d laplacian of V
01167  Tensor d_V = contract(q_updown, 1, contract(q_updown,0 , V_par.derive_cov(gamij),1 ),1);
01168  Tensor d_V_con = contract(d_V,1,q_upup,1);
01169   Tensor dd_V = d_V_con.derive_cov(gamij);
01170   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01171   dd_V = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V, 2), 2), 2);
01172   Tensor dd_Vdown = contract (dd_V,1,q_downdown,1);
01173   Vector Ricci1 = contract(dd_Vdown,0,1) - contract(dd_Vdown,0,2);    
01174   Vector Ricci2 = contract (q_upup,1,Ricci1,0);
01175   Vector lap_V = contract(dd_V, 1,2);
01176 
01177 
01178 
01179 //   Tensor dd_V = V_par.derive_con(gamij);
01180 //   dd_V = contract(q_updown, 1, contract(q_updown,1 ,dd_V, 0), 1);
01181 //   Vector lap_V = contract(q_updown, 1, contract(dd_V.derive_cov(gamij),1,2), 0);
01182 
01183 
01184   
01185   // 3d interpolation of the Ricci scalar on the surface.
01186   
01187   Scalar ricci2 = sph.get_ricci();
01188   
01189      // Start Mapping interpolation
01190  
01191       Scalar ricci3 (lapse.get_mp()); 
01192  
01193   ricci3.allocate_all();
01194   ricci3.std_spectral_base();
01195 
01196 
01197   int nr = (*lapse.get_mp().get_mg()).get_nr(1);
01198   int nt = (*lapse.get_mp().get_mg()).get_nt(1);
01199   int np = (*lapse.get_mp().get_mg()).get_np(1);
01200 
01201 
01202   for (int f= 0; f<nz; f++)
01203     for (int k=0; k<np; k++)
01204       for (int j=0; j<nt; j++) {
01205     for (int l=0; l<nr; l++) {
01206         
01207       ricci3.set_grid_point(f,k,j,l) = ricci2.val_grid_point(0,k,j,0);
01208 
01209     
01210     }
01211       }
01212   if (nz >2){
01213     //     ricci3.annule_domain(0);
01214     ricci3.annule_domain(nz - 1);
01215 
01216   }
01217     // End Mapping interpolation
01218   
01219     // Construction of the Ricci COV tensor on the sphere
01220  
01221   Sym_tensor ricci_t = gamij.cov() - sss_down*sss_down;
01222   ricci_t = 0.5*ricci3*ricci_t;
01223   ricci_t.std_spectral_base();
01224  
01225   Tensor ricci_t_updown = contract(q_upup,0, ricci_t,0); 
01226   
01227   // Calculation of ff 
01228 
01229   // Vector ffV = c_V_lap*lapse*(lap_V + contract(ricci_t_updown,1, V_par,0));
01230    Vector ffV = c_V_lap*lapse*(lap_V + Ricci2);
01231 
01232   ffV.annule_domain(nz-1);
01233 
01234 
01235 //   cout << "verification of vanishing shear" << endl;
01236 //   cout << "points on the surface" << endl;
01237   
01238 //   Tbl val_ffV(3, nt, np);
01239 //   val_ffV.set_etat_qcq();
01240 //   for(int mm=0; mm <np; mm++)
01241 //     for (int pp=0; pp<nt; pp++){
01242 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01243 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01244 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01245 //     }
01246 
01247 //   //  cout << val_ffV<< endl;
01248 //   cout << max(val_ffV) << endl;
01249 //   val_ffV.set_etat_nondef();
01250  
01251  
01252 
01253    ffV = ffV + epsilon*lapse*contract(V_par,0,V_par.derive_cov(gamij),1); // Add of dragging term for time transport.
01254   ffV.annule_domain(nz-1);
01255 
01256   ffV.std_spectral_base();
01257 
01258 //   cout << "verification of vanishing shear with dragging" << endl;
01259 //  cout << "points on the surface" << endl;
01260 //   val_ffV.set_etat_qcq();
01261 //   for(int mm=0; mm <np; mm++)
01262 //     for (int pp=0; pp<nt; pp++){
01263 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01264 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01265 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01266 //     }
01267 
01268 //   //  cout << val_ffV<< endl;
01269 //   cout << max(val_ffV) << endl;
01270 //   val_ffV.set_etat_nondef();
01271  
01272  
01273 
01274 
01275   // Definition of k_1
01276   Vector k_1V =delta_t*ffV;
01277    
01278   // Intermediate value of Npsi, for Runge-Kutta 2nd order scheme
01279   if (nz >2){
01280     k_1V.annule_domain(nz-1);
01281   }                             // Patch to avoid dzpuis problems if existent.
01282   Vector V_par_int = V_par + k_1V;// V_par_int.std_spectral_base();
01283 
01284   // Calculation of the conformal 2d laplacian of V
01285  Tensor d_V_int = contract(q_updown, 1, contract(q_updown,0 , V_par_int.derive_cov(gamij),1 ),1);
01286  Tensor d_V_con_int = contract(d_V_int,1,q_upup,1);
01287   Tensor dd_V_int = d_V_con_int.derive_cov(gamij);
01288   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01289   dd_V_int = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V_int, 2), 2), 2);
01290   Tensor dd_Vdown_int = contract (dd_V_int,1,q_downdown,1);
01291   Vector Ricci1_int = contract(dd_Vdown_int,0,1) - contract(dd_Vdown_int,0,2);    
01292   Vector Ricci2_int = contract (q_upup,1,Ricci1_int,0);
01293   Vector lap_V_int = contract(dd_V_int, 1,2);
01294 
01295 
01296   // Recalculation of ff with intermediate values.
01297 //   Tensor dd_V_int = V_par_int.derive_con(gamij).derive_cov(gamij);
01298 //   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01299 //   dd_V_int = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V_int, 2), 2), 2);
01300 //   Vector lap_V_int = contract(dd_V_int, 1,2);
01301  
01302   Vector ffV_int =  c_V_lap*lapse*(lap_V_int + contract(ricci_t_updown,1, V_par_int,0));
01303   ffV_int.annule_domain(nz-1);
01304    ffV_int = ffV_int + epsilon*lapse*contract(V_par_int,0,V_par_int.derive_cov(gamij),1); // Add of dragging term for time transport.
01305 
01306    //  ffV_int = -ffV_int; // Only a test..
01307 
01308 
01309   ffV_int.annule_domain(nz-1);
01310  
01311 
01312 //   cout << "verification of vanishing shear for intermediate RK value" << endl;
01313 //   cout << "points on the surface" << endl;
01314 
01315 
01316 //   val_ffV.set_etat_qcq();
01317 //   for(int mm=0; mm <np; mm++)
01318 //     for (int pp=0; pp<nt; pp++){
01319 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01320 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01321 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01322 //     }
01323 
01324 //   //  cout << val_ffV<< endl;
01325 //   cout << max(val_ffV) << endl;
01326 //   val_ffV.set_etat_nondef();
01327 
01328 
01329 
01330   // Definition of k_2
01331   Vector k_2V = delta_t*ffV_int; 
01332   //  k_2.std_spectral_base();
01333  
01334   // Result of RK2 evolution
01335   if (nz >2){
01336     k_2V.annule_domain(nz-1);
01337   }
01338   Vector bound_V = V_par + k_2V;
01339   //  bound_V.std_spectral_base();
01340 
01341        // Construction of the total shift boundary condition
01342        Vector bound_shift = bb2*sss + bound_V;
01343        bound_shift.std_spectral_base();
01344        p_get_BC_shift_3 = new Vector(bound_shift);
01345 }
01346   return *p_get_BC_shift_3 ;
01347 }
01348 
01349 
01350 
01351 
01352 
01353 
01354 
01355 
01356 
01357 
01358 // Source for the Dirichlet BC on the shift, based on projection of Einstein Equations for the radial part, and a parabolic evolution for the tangent part.
01359 // It takes as fixed arguments the time derivative of the expansion, the matter terms and a boolean specifying whether or not we are in spherical symmetry.. 
01360 const Vector& Excision_surf::get_BC_shift_4(Scalar& dttheta, Scalar& Ee, Vector& Jj, Sym_tensor& Sij, double c_V_lap, double epsilon, bool sph_sym) const{
01361   if (p_get_BC_shift_4 == 0x0){
01362 
01363     // Radial vector for the full 3-metric.
01364      Vector sss = gamij.radial_vect();
01365      Vector sss_down = sss.up_down(gamij);
01366          
01367      int nz = (*lapse.get_mp().get_mg()).get_nzone();
01368 
01369 //     // Boundary value for the radial part of the shift: parabolic driver for (b-N)
01370      //  Scalar bound = lapse ; 
01371      Scalar bb = contract (shift,0, sss_down,0); 
01372 
01373 
01374 
01375      Scalar bound_b3(lapse.get_mp()); bound_b3.allocate_all(); bound_b3.set_spectral_base(bb.get_spectral_base());// Result to be stored there.
01376     
01377     Scalar Kappa  = bb*contract(contract(Kij,0,sss,0),0,sss,0) - contract(sss,0, lapse.derive_cov(gamij),0);
01378     Scalar Matter = 8.*M_PI*(bb*Ee);
01379     Matter.annule_domain(nz-1);
01380     Matter += - 8.*M_PI*(bb + lapse)*contract(Jj,0,sss_down,0);
01381     Matter.annule_domain(nz-1);
01382     Matter +=  8.*M_PI*lapse*contract(contract(Sij,0,sss_down,0),0,sss_down,0);
01383   
01384   
01385   // 2d interpolation of the Kappa constant and the matter terms.
01386   
01387   Scalar Kappa2 = sph.get_ricci();
01388   Kappa2.annule_hard();
01389   Scalar bb2 = Kappa2;
01390   Scalar Matter2 = Kappa2;
01391   Scalar nn2 = Kappa2;
01392 
01393   const Metric_flat& flat2 = Kappa2.get_mp().flat_met_spher();
01394 
01395   int nt = (*Kappa2.get_mp().get_mg()).get_nt(0);
01396   int np = (*Kappa2.get_mp().get_mg()).get_np(0);
01397     for (int k=0; k<np; k++)
01398       for (int j=0; j<nt; j++) {
01399       Kappa2.set_grid_point(0,k,j,0) = Kappa.val_grid_point(1,k,j,0);
01400       bb2.set_grid_point(0,k,j,0) = bb.val_grid_point(1,k,j,0);
01401       Matter2.set_grid_point(0,k,j,0) = Matter.val_grid_point(1,k,j,0);
01402       nn2.set_grid_point(0,k,j,0) = lapse.val_grid_point(1,k,j,0);
01403       }
01404       
01405     Kappa2.std_spectral_base();
01406     bb2.std_spectral_base();
01407     Matter2.std_spectral_base();
01408     nn2.std_spectral_base();
01409 
01410 
01411     Scalar Tplus = sph.theta_plus();
01412     Scalar Tminus = sph.theta_minus();
01413     Scalar Ricci = sph.get_ricci();
01414     Vector Ll = sph.get_ll();
01415     Sym_tensor Shear = sph.shear();
01416     Metric qab = sph.get_qab();
01417 
01418     Scalar source = 2.*contract(Ll.up_down(qab),0,sph.derive_cov2d(nn2),0) + nn2*(contract(sph.derive_cov2d(Ll.up_down(qab)),0,1)+ contract(Ll,0,Ll.up_down(qab),0)- 0.5*(Ricci + Tplus*Tminus) - 0.25*Tplus*Tplus - 0.5*contract(Shear.up_down(qab),0,1,Shear,0,1)) - Matter2 - Tplus*Kappa2 - dttheta;
01419  
01420     Scalar lapN = contract(sph.derive_cov2d(sph.derive_cov2d(nn2)).up(0,qab),0,1);
01421     
01422     source = source + lapN;
01423 
01424   
01425     Scalar source_add =  2.*contract(Ll.up_down(qab),0,sph.derive_cov2d(bb2),0); 
01426 
01427     source = source - source_add; 
01428     
01429     Scalar sqrt_q_h2 = sph.sqrt_q() * sph.get_hsurf() * sph.get_hsurf() ;
01430     Tensor Delta2 = sph.delta();
01431     Sym_tensor qab_con = sph.get_qab().con() / (sph.get_hsurf() * sph.get_hsurf()) ;
01432   qab_con.set(1,1) = 1. ;
01433   qab_con.set(1,2) = 0. ;
01434   qab_con.set(1,3) = 0. ;
01435   qab_con.std_spectral_base() ;
01436 
01437   Sym_tensor hab =(qab_con*sqrt_q_h2 - flat2.con()) / (sph.get_hsurf()*sph.get_hsurf()) ;
01438   hab.set(1,1) = 1. ;
01439   hab.set(1,2) = 0. ;
01440   hab.set(1,3) = 0. ;
01441   hab.std_spectral_base() ;
01442 
01443   Vector db = sph.derive_cov2dflat(bb2);
01444   Tensor ddb = sph.derive_cov2dflat(db);
01445 
01446   Scalar lap_rem = contract(qab_con, 0,1, contract(Delta2,0,db,0),0,1)*sqrt_q_h2 - sph.get_hsurf()*sph.get_hsurf()*contract(hab,0,1,ddb,0,1);// What remains of the laplacian
01447 
01448   source = sqrt_q_h2*source + lap_rem;
01449 
01450   Scalar bound_b=bb2;
01451       Scalar lapang_s_par = (contract(sph.derive_cov2d(Ll.up_down(qab)),0,1)+ contract(Ll,0,Ll.up_down(qab),0)- 0.5*(Ricci + Tplus*Tminus) + 0.25*Tplus*Tplus + 0.5*contract(Shear.up_down(qab),0,1,Shear,0,1))*sqrt_q_h2;
01452       double lapang_par = lapang_s_par.val_grid_point(0,0,0,0);
01453 
01454     if (sph_sym == true){
01455       bound_b = source/lapang_par;
01456       bound_b.set_spectral_va().coef_i();
01457       bound_b.set_spectral_va().ylm();
01458     }
01459 
01460     else{
01461       cout << "non spherical case has not been treated yet!" << endl;  
01462     }
01463 
01464     // Interpolation to get a 3d value (as poisson solvers take this for boundary...)
01465   
01466   
01467  
01468 
01469   int nr2 = (*lapse.get_mp().get_mg()).get_nr(1);
01470   int nt2 = (*lapse.get_mp().get_mg()).get_nt(1);
01471   int np2 = (*lapse.get_mp().get_mg()).get_np(1);
01472 
01473 
01474   for (int f= 0; f<nz; f++)
01475     for (int k=0; k<np2; k++)
01476       for (int j=0; j<nt2; j++) {
01477     for (int l=0; l<nr2; l++) {
01478         
01479       bound_b3.set_grid_point(f,k,j,l) = bound_b.val_grid_point(0,k,j,0);
01480 
01481     
01482     }
01483       }
01484   if (nz >2){
01485     bound_b3.annule_domain(nz - 1);
01486 
01487   }
01488     
01489   bound_b3.std_spectral_base();
01490   bound_b3.set_spectral_va().ylm();
01491 
01492 
01493 
01494 
01495      Scalar bbb2 = bound_b3; // Look out for additional term for time variation of lapse and sss
01496   
01497 
01498   // Tangent part of the shift, with parabolic driver
01499   
01500   
01501   Vector V_par = shift - bb*sss;
01502   Sym_tensor q_upup = gamij.con() - sss*sss;
01503   Sym_tensor q_downdown = gamij.cov() - sss_down*sss_down;
01504  Tensor q_updown = q_upup.down(1, gamij); 
01505 
01506  
01507   // Calculation of the conformal 2d laplacian of V
01508  Tensor d_V = contract(q_updown, 1, contract(q_updown,0 , V_par.derive_cov(gamij),1 ),1);
01509  Tensor d_V_con = contract(d_V,1,q_upup,1);
01510   Tensor dd_V = d_V_con.derive_cov(gamij);
01511   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01512   dd_V = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V, 2), 2), 2);
01513   Tensor dd_Vdown = contract (dd_V,1,q_downdown,1);
01514   Vector Ricci1 = contract(dd_Vdown,0,1) - contract(dd_Vdown,0,2);    
01515   Vector Ricci2 = contract (q_upup,1,Ricci1,0);
01516   Vector lap_V = contract(dd_V, 1,2);
01517 
01518 
01519 
01520 //   Tensor dd_V = V_par.derive_con(gamij);
01521 //   dd_V = contract(q_updown, 1, contract(q_updown,1 ,dd_V, 0), 1);
01522 //   Vector lap_V = contract(q_updown, 1, contract(dd_V.derive_cov(gamij),1,2), 0);
01523 
01524 
01525   
01526   // 3d interpolation of the Ricci scalar on the surface.
01527   
01528   Scalar ricci2 = sph.get_ricci();
01529   
01530      // Start Mapping interpolation
01531  
01532       Scalar ricci3 (lapse.get_mp()); 
01533  
01534   ricci3.allocate_all();
01535   ricci3.std_spectral_base();
01536 
01537   for (int f= 0; f<nz; f++)
01538     for (int k=0; k<np2; k++)
01539       for (int j=0; j<nt2; j++) {
01540     for (int l=0; l<nr2; l++) {
01541         
01542       ricci3.set_grid_point(f,k,j,l) = ricci2.val_grid_point(0,k,j,0);
01543 
01544     
01545     }
01546       }
01547   if (nz >2){
01548     //     ricci3.annule_domain(0);
01549     ricci3.annule_domain(nz - 1);
01550 
01551   }
01552     // End Mapping interpolation
01553   
01554     // Construction of the Ricci COV tensor on the sphere
01555  
01556   Sym_tensor ricci_t = gamij.cov() - sss_down*sss_down;
01557   ricci_t = 0.5*ricci3*ricci_t;
01558   ricci_t.std_spectral_base();
01559  
01560   Tensor ricci_t_updown = contract(q_upup,0, ricci_t,0); 
01561   
01562   // Calculation of ff 
01563 
01564   // Vector ffV = c_V_lap*lapse*(lap_V + contract(ricci_t_updown,1, V_par,0));
01565    Vector ffV = c_V_lap*lapse*(lap_V + Ricci2);
01566 
01567   ffV.annule_domain(nz-1);
01568 
01569 
01570 //   cout << "verification of vanishing shear" << endl;
01571 //   cout << "points on the surface" << endl;
01572   
01573 //   Tbl val_ffV(3, nt, np);
01574 //   val_ffV.set_etat_qcq();
01575 //   for(int mm=0; mm <np; mm++)
01576 //     for (int pp=0; pp<nt; pp++){
01577 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01578 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01579 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01580 //     }
01581 
01582 //   //  cout << val_ffV<< endl;
01583 //   cout << max(val_ffV) << endl;
01584 //   val_ffV.set_etat_nondef();
01585  
01586  
01587 
01588    ffV = ffV + epsilon*lapse*contract(V_par,0,V_par.derive_cov(gamij),1); // Add of dragging term for time transport.
01589   ffV.annule_domain(nz-1);
01590 
01591   ffV.std_spectral_base();
01592 
01593 //   cout << "verification of vanishing shear with dragging" << endl;
01594 //  cout << "points on the surface" << endl;
01595 //   val_ffV.set_etat_qcq();
01596 //   for(int mm=0; mm <np; mm++)
01597 //     for (int pp=0; pp<nt; pp++){
01598 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01599 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01600 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01601 //     }
01602 
01603 //   //  cout << val_ffV<< endl;
01604 //   cout << max(val_ffV) << endl;
01605 //   val_ffV.set_etat_nondef();
01606  
01607  
01608 
01609 
01610   // Definition of k_1
01611   Vector k_1V =delta_t*ffV;
01612    
01613   // Intermediate value of Npsi, for Runge-Kutta 2nd order scheme
01614   if (nz >2){
01615     k_1V.annule_domain(nz-1);
01616   }                             // Patch to avoid dzpuis problems if existent.
01617   Vector V_par_int = V_par + k_1V;// V_par_int.std_spectral_base();
01618 
01619   // Calculation of the conformal 2d laplacian of V
01620  Tensor d_V_int = contract(q_updown, 1, contract(q_updown,0 , V_par_int.derive_cov(gamij),1 ),1);
01621  Tensor d_V_con_int = contract(d_V_int,1,q_upup,1);
01622   Tensor dd_V_int = d_V_con_int.derive_cov(gamij);
01623   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01624   dd_V_int = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V_int, 2), 2), 2);
01625   Tensor dd_Vdown_int = contract (dd_V_int,1,q_downdown,1);
01626   Vector Ricci1_int = contract(dd_Vdown_int,0,1) - contract(dd_Vdown_int,0,2);    
01627   Vector Ricci2_int = contract (q_upup,1,Ricci1_int,0);
01628   Vector lap_V_int = contract(dd_V_int, 1,2);
01629 
01630 
01631   // Recalculation of ff with intermediate values.
01632 //   Tensor dd_V_int = V_par_int.derive_con(gamij).derive_cov(gamij);
01633 //   // Vector lap_V = contract(dd_V.derive_cov(gamij),1,2);
01634 //   dd_V_int = contract(q_updown, 1, contract(q_updown,1 ,contract(q_updown,0,dd_V_int, 2), 2), 2);
01635 //   Vector lap_V_int = contract(dd_V_int, 1,2);
01636  
01637   Vector ffV_int =  c_V_lap*lapse*(lap_V_int + contract(ricci_t_updown,1, V_par_int,0));
01638   ffV_int.annule_domain(nz-1);
01639    ffV_int = ffV_int + epsilon*lapse*contract(V_par_int,0,V_par_int.derive_cov(gamij),1); // Add of dragging term for time transport.
01640 
01641    //  ffV_int = -ffV_int; // Only a test..
01642 
01643 
01644   ffV_int.annule_domain(nz-1);
01645  
01646 
01647 //   cout << "verification of vanishing shear for intermediate RK value" << endl;
01648 //   cout << "points on the surface" << endl;
01649 
01650 
01651 //   val_ffV.set_etat_qcq();
01652 //   for(int mm=0; mm <np; mm++)
01653 //     for (int pp=0; pp<nt; pp++){
01654 //       val_ffV.set(0,pp,mm) = ffV(1).val_grid_point(1,mm,pp,0);
01655 //       val_ffV.set(1,pp,mm) = ffV(2).val_grid_point(1,mm,pp,0);
01656 //       val_ffV.set(2,pp,mm) = ffV(3).val_grid_point(1,mm,pp,0);
01657 //     }
01658 
01659 //   //  cout << val_ffV<< endl;
01660 //   cout << max(val_ffV) << endl;
01661 //   val_ffV.set_etat_nondef();
01662 
01663 
01664 
01665   // Definition of k_2
01666   Vector k_2V = delta_t*ffV_int; 
01667   //  k_2.std_spectral_base();
01668  
01669   // Result of RK2 evolution
01670   if (nz >2){
01671     k_2V.annule_domain(nz-1);
01672   }
01673   Vector bound_V = V_par + k_2V;
01674   //  bound_V.std_spectral_base();
01675 
01676        // Construction of the total shift boundary condition
01677        Vector bound_shift = bbb2*sss + bound_V;
01678        bound_shift.std_spectral_base();
01679        p_get_BC_shift_4 = new Vector(bound_shift);
01680 }
01681   return *p_get_BC_shift_4 ;
01682 }
01683 
01684 
01685 
01686 
01687 
01688 
01689 
01690 
01691 
01692 
01693 
01694 
01695 
01696 
01697 
01698 
01699 
01700 
01701 
01702 
01703 // Source for the Dirichlet BC on (N*Psi1)
01704 const Scalar& Excision_surf::get_BC_Npsi_1(double value) const{
01705   if (p_get_BC_Npsi_1 == 0x0){
01706 
01707     Scalar bound_Npsi = value*conf_fact;
01708     bound_Npsi.set_spectral_va().ylm();
01709     p_get_BC_Npsi_1 = new Scalar(bound_Npsi);
01710     
01711 }
01712   return *p_get_BC_Npsi_1 ;
01713 }
01714 
01715 // Source for the Dirichlet BC on (N*Psi1), based on a parabolic driver.
01716 const Scalar& Excision_surf::get_BC_Npsi_2(double npsi_fin, double c_npsi_lap, double c_npsi_fin) const{
01717   if (p_get_BC_Npsi_2 == 0x0){
01718 
01719 
01720     Scalar npsi = lapse*conf_fact; npsi.std_spectral_base();
01721     Scalar ff = lapse*(c_npsi_lap*npsi.lapang() + c_npsi_fin*npsi);
01722   ff.std_spectral_base();
01723   ff = ff -lapse*c_npsi_fin*npsi_fin;
01724   ff.std_spectral_base();
01725 
01726 
01727   // Definition of k_1
01728   Scalar k_1 =delta_t*ff;
01729    
01730   // Intermediate value of Npsi, for Runge-Kutta 2nd order scheme
01731   Scalar npsi_int = npsi + k_1; npsi_int.std_spectral_base();
01732 
01733   // Recalculation of ff with intermediate values. 
01734   Scalar ff_int =  lapse*(c_npsi_lap*npsi_int.lapang() + c_npsi_fin*(npsi_int - npsi_fin));
01735  
01736   // Definition of k_2
01737   Scalar k_2 = delta_t*ff_int; 
01738   k_2.std_spectral_base();
01739  
01740   // Result of RK2 evolution
01741   Scalar bound_npsi = npsi + k_2;
01742   bound_npsi.std_spectral_base();
01743   bound_npsi.set_spectral_va().ylm();
01744 
01745 
01746 
01747 //     Scalar bound_Npsi = value*conf_fact;
01748 //     bound_Npsi.set_spectral_va().ylm();
01749      p_get_BC_Npsi_2 = new Scalar(bound_npsi);
01750     
01751 }
01752   return *p_get_BC_Npsi_2 ;
01753 }
01754 
01755 // Source for the Dirichlet BC on (N*Psi1), with a Kerr_Schild-like form for the lapse.
01756 const Scalar& Excision_surf::get_BC_Npsi_3(double n_0, double beta) const{
01757   if (p_get_BC_Npsi_3 == 0x0){
01758 
01759 
01760     const Coord& ct = lapse.get_mp().cost;
01761     Scalar boundN(lapse.get_mp()); boundN = sqrt(n_0 + beta*ct*ct); // Kerr_Schild form for the lapse.
01762     boundN.std_spectral_base();
01763     Scalar bound_npsi = boundN*conf_fact;
01764     bound_npsi.set_spectral_va().ylm();
01765 
01766 //     Scalar npsi = lapse*conf_fact; npsi.std_spectral_base();
01767 //   Scalar ff = lapse*(c_npsi_lap*npsi.lapang() + c_npsi_fin*npsi);
01768 //   ff.std_spectral_base();
01769 //   ff += -lapse*c_npsi_fin*npsi_fin;
01770 //   ff.std_spectral_base();
01771 
01772 
01773 //   // Definition of k_1
01774 //   Scalar k_1 =delta_t*ff;
01775    
01776 //   // Intermediate value of Npsi, for Runge-Kutta 2nd order scheme
01777 //   Scalar npsi_int = npsi + k_1; npsi_int.std_spectral_base();
01778 
01779 //   // Recalculation of ff with intermediate values. 
01780 //   Scalar ff_int =  lapse*(c_npsi_lap*npsi_int.lapang() + c_npsi_fin*(npsi_int - npsi_fin));
01781  
01782 //   // Definition of k_2
01783 //   Scalar k_2 = delta_t*ff_int; 
01784 //   k_2.std_spectral_base();
01785  
01786 //   // Result of RK2 evolution
01787 //   Scalar bound_npsi = npsi + k_2;
01788 //   bound_npsi.std_spectral_base();
01789 //   bound_npsi.set_spectral_va().ylm();
01790 
01791 
01792 
01793 //     Scalar bound_Npsi = value*conf_fact;
01794 //     bound_Npsi.set_spectral_va().ylm();
01795      p_get_BC_Npsi_3 = new Scalar(bound_npsi);
01796     
01797 }
01798   return *p_get_BC_Npsi_3 ;
01799 }
01800 
01801 
01802 // Source for a Dirichlet BC on (N*Psi1), fixing the surface gravity as a constant in space and time.
01803 const Scalar& Excision_surf::get_BC_Npsi_4(double Kappa) const{
01804   if (p_get_BC_Npsi_4 == 0x0){
01805 
01806 
01807     const Vector s_i = gamij.radial_vect();
01808     Scalar bound_npsi = contract(s_i,0, lapse.derive_cov(gamij),0); bound_npsi.set_dzpuis(0);
01809     bound_npsi = bound_npsi - Kappa;
01810     bound_npsi.std_spectral_base();
01811     bound_npsi = bound_npsi*(conf_fact/contract(contract(Kij,0,s_i,0),0,s_i,0));
01812     bound_npsi.set_dzpuis(0); bound_npsi.std_spectral_base();
01813     bound_npsi.set_spectral_va().ylm();
01814 
01815      p_get_BC_Npsi_4 = new Scalar(bound_npsi);
01816     
01817 }
01818   return *p_get_BC_Npsi_4 ;
01819 }
01820 
01821 
01822 
01823 // Source for a Neumann BC on (N*Psi1), fixing the surface gravity as a constant in space and time. // Check redundancy with the previous one.
01824 const Scalar& Excision_surf::get_BC_Npsi_5(double Kappa) const{
01825   if (p_get_BC_Npsi_5 == 0x0){
01826 
01827 
01828     const Vector s_i = gamij.radial_vect();
01829   int nz = (*lapse.get_mp().get_mg()).get_nzone();
01830     Scalar bound_npsi = lapse*contract(s_i,0, conf_fact.derive_cov(gamij),0); bound_npsi.annule_domain(nz -1);
01831     Scalar bound_npsi2 = pow(conf_fact,3)*lapse*contract(contract(Kij,0,s_i,0),0,s_i,0);
01832     bound_npsi2.annule_domain(nz-1);
01833     bound_npsi += bound_npsi2;
01834     bound_npsi = bound_npsi + pow(conf_fact,3)*(Kappa); bound_npsi.annule_domain(nz -1);
01835     bound_npsi = bound_npsi -(conf_fact*conf_fact*contract(s_i,0, (conf_fact*lapse).derive_cov(gamij),0) - (conf_fact*lapse).dsdr());
01836     //    bound_npsi = bound_npsi*(conf_fact/contract(contract(Kij,0,s_i,0),0,s_i,0));
01837     bound_npsi.annule_domain(nz-1); bound_npsi.std_spectral_base();
01838     bound_npsi.set_spectral_va().ylm();
01839 
01840      p_get_BC_Npsi_5 = new Scalar(bound_npsi);
01841     
01842 }
01843   return *p_get_BC_Npsi_5 ;
01844 }
01845 
01846 
01847 
01848 
01849 
01850  void Excision_surf::sauve(FILE* ) const {
01851 
01852    cout << "c'est pas fait!" << endl ;
01853    return ; 
01854 
01855  }

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