sym_tensor_trans_dirac_boundfree.C

00001 /*
00002  *  Methods to impose the Dirac gauge: divergence-free condition, with interior boundary conditions added
00003  *
00004  *    (see file sym_tensor.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2006, 2007  Jerome Novak,Nicolas Vasset
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License version 2
00015  *   as published by the Free Software Foundation.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 // char sym_tensor_trans_dirac_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/sym_tensor_trans_dirac_boundfree.C,v 1.1 2008/08/20 15:09:01 n_vasset Exp $" ;
00029 
00030 /*
00031  * $Id: sym_tensor_trans_dirac_boundfree.C,v 1.1 2008/08/20 15:09:01 n_vasset Exp $
00032  * $Log: sym_tensor_trans_dirac_boundfree.C,v $
00033  * Revision 1.1  2008/08/20 15:09:01  n_vasset
00034  * First version
00035  *
00036  * Revision 1.2  2006/10/24 13:03:19  j_novak
00037  * New methods for the solution of the tensor wave equation. Perhaps, first
00038  * operational version...
00039  *
00040  * Revision 1.1  2006/09/05 15:38:45  j_novak
00041  * The fuctions sol_Dirac... are in a separate file, with new parameters to
00042  * control the boundary conditions.
00043  *
00044  *
00045  * $Header: /cvsroot/Lorene/C++/Source/Tensor/sym_tensor_trans_dirac_boundfree.C,v 1.1 2008/08/20 15:09:01 n_vasset Exp $
00046  *
00047  */
00048 
00049 // C headers
00050 #include <assert.h>
00051 #include <math.h>
00052 
00053 // Lorene headers
00054 #include "nbr_spx.h"
00055 #include "utilitaires.h"
00056 #include "math.h"
00057 #include "param.h"
00058 #include "param_elliptic.h"
00059 #include "metric.h"
00060 #include "tensor.h"
00061 #include "sym_tensor.h"
00062 #include "diff.h"
00063 #include "proto.h"
00064 #include "param.h"
00065 
00066 
00067 //----------------------------------------------------------------------------------
00068 //
00069 //                               sol_Dirac_A
00070 //
00071 //----------------------------------------------------------------------------------
00072 
00073 void Sym_tensor_trans::sol_Dirac_A2(const Scalar& aaa, Scalar& tilde_mu, Scalar& x_new, Scalar bound_mu, const Param* par_bc) {
00074   
00075   const Map_af* mp_aff = dynamic_cast<const Map_af*>(mp) ;
00076   assert(mp_aff != 0x0) ; //Only affine mapping for the moment
00077   
00078   //  WARNING!
00079   // This will only work if we have at least 2 shells!
00080   
00081   
00082   const Mg3d& mgrid = *mp_aff->get_mg() ;
00083   assert(mgrid.get_type_r(0) == RARE)  ;
00084   if (aaa.get_etat() == ETATZERO) {
00085     tilde_mu = 0 ;
00086     x_new = 0 ;
00087     return ;
00088   }
00089   
00090   // On suppose que le sym_tensor_entré est bien transverse;  
00091   
00092   //  assert ( maxabs(contract((*this).derive_cov(mets), 1, 2)) < 0.00000000000001 ) ; 
00093   
00094 
00095   bound_mu.set_spectral_va().ylm();
00096  
00097  
00098   assert(aaa.get_etat() != ETATNONDEF) ;
00099   int nz = mgrid.get_nzone() ;
00100   int nzm1 = nz - 1 ;
00101   bool ced = (mgrid.get_type_r(nzm1) == UNSURR) ;
00102   int n_shell = ced ? nz-2 : nzm1 ;
00103   int nz_bc = nzm1 ;
00104   if (par_bc != 0x0)
00105     if (par_bc->get_n_int() > 0) nz_bc = par_bc->get_int() ;
00106   n_shell = (nz_bc < n_shell ? nz_bc : n_shell) ;
00107   bool cedbc = (ced && (nz_bc == nzm1)) ; 
00108 #ifndef NDEBUG
00109   if (!cedbc) {
00110     assert(par_bc != 0x0) ;
00111     assert(par_bc->get_n_tbl_mod() >= 3) ;
00112   }
00113 #endif
00114   int nt = mgrid.get_nt(0) ;
00115   int np = mgrid.get_np(0) ;
00116   
00117   Scalar source = aaa ;
00118   Scalar source_coq = aaa ;
00119   source_coq.annule_domain(0) ;
00120   if (ced) source_coq.annule_domain(nzm1) ;
00121   source_coq.mult_r() ;
00122   source.set_spectral_va().ylm() ;
00123   source_coq.set_spectral_va().ylm() ;
00124   Base_val base = source.get_spectral_base() ;
00125   base.mult_x() ;
00126   
00127   tilde_mu.annule_hard() ;
00128   tilde_mu.set_spectral_base(base) ;
00129   tilde_mu.set_spectral_va().set_etat_cf_qcq() ;
00130   tilde_mu.set_spectral_va().c_cf->annule_hard() ;   
00131   x_new.annule_hard() ;
00132   x_new.set_spectral_base(base) ;
00133   x_new.set_spectral_va().set_etat_cf_qcq() ;
00134   x_new.set_spectral_va().c_cf->annule_hard() ;   
00135   
00136   Mtbl_cf sol_part_mu(mgrid, base) ; sol_part_mu.annule_hard() ;
00137   Mtbl_cf sol_part_x(mgrid, base) ; sol_part_x.annule_hard() ;
00138   Mtbl_cf sol_hom1_mu(mgrid, base) ; sol_hom1_mu.annule_hard() ;
00139   Mtbl_cf sol_hom1_x(mgrid, base) ; sol_hom1_x.annule_hard() ;
00140   Mtbl_cf sol_hom2_mu(mgrid, base) ; sol_hom2_mu.annule_hard() ;
00141   Mtbl_cf sol_hom2_x(mgrid, base) ; sol_hom2_x.annule_hard() ;
00142   
00143   int l_q, m_q, base_r ;
00144   
00145   //---------------
00146   //--  NUCLEUS ---
00147   //---------------
00148 
00149   // On va annuler toutes les solutions dans le noyau
00150 
00151   { int lz = 0 ;  
00152   int nr = mgrid.get_nr(lz) ;
00153   //  double alpha = mp_aff->get_alpha()[lz] ;
00154   // Matrice ope(2*nr, 2*nr) ;
00155   //  ope.set_etat_qcq() ;
00156   
00157   for (int k=0 ; k<np+1 ; k++) {
00158     for (int j=0 ; j<nt ; j++) {
00159       // quantic numbers and spectral bases
00160       base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00161       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
00162     
00163     
00164     Tbl sol(2*nr) ;
00165     sol.set_etat_zero();                
00166     for (int i=0; i<nr; i++) {
00167       sol_part_mu.set(lz, k, j, i) = 0 ;
00168       sol_part_x.set(lz, k, j, i) = 0 ;
00169     }
00170     for (int i=0; i<nr; i++) {
00171       sol_hom2_mu.set(lz, k, j, i) = 0 ;
00172       sol_hom2_x.set(lz, k, j, i) = 0 ;
00173     }
00174       }
00175     }
00176   }
00177   }
00178   
00179   //-------------
00180   // -- Shells --
00181   //-------------
00182   for (int lz=1; lz <= n_shell; lz++) {
00183     int nr = mgrid.get_nr(lz) ;
00184     assert(mgrid.get_nt(lz) == nt) ;
00185     assert(mgrid.get_np(lz) == np) ;
00186     double alpha = mp_aff->get_alpha()[lz] ;
00187     double ech = mp_aff->get_beta()[lz] / alpha ;
00188     Matrice ope(2*nr, 2*nr) ;
00189     ope.set_etat_qcq() ;
00190     
00191     for (int k=0 ; k<np+1 ; k++) {
00192       for (int j=0 ; j<nt ; j++) {
00193     // quantic numbers and spectral bases
00194     base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00195     if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
00196       Diff_xdsdx oxd(base_r, nr) ; const Matrice& mxd = oxd.get_matrice() ;
00197       Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
00198       Diff_id oid(base_r, nr) ; const Matrice& mid = oid.get_matrice() ;
00199       
00200       for (int lin=0; lin<nr; lin++) 
00201         for (int col=0; col<nr; col++) 
00202           ope.set(lin,col) = mxd(lin,col) + ech*md(lin,col) 
00203         + 3*mid(lin,col) ;
00204       for (int lin=0; lin<nr; lin++) 
00205         for (int col=0; col<nr; col++) 
00206           ope.set(lin,col+nr) = (2-l_q*(l_q+1))*mid(lin,col) ;
00207       for (int lin=0; lin<nr; lin++) 
00208         for (int col=0; col<nr; col++) 
00209           ope.set(lin+nr,col) = -mid(lin,col) ;
00210       for (int lin=0; lin<nr; lin++) 
00211         for (int col=0; col<nr; col++) 
00212           ope.set(lin+nr,col+nr) = mxd(lin,col) + ech*md(lin,col) ;
00213       
00214       int ind0 = 0 ;
00215       int ind1 = nr ;
00216       for (int col=0; col<2*nr; col++) {
00217         ope.set(ind0+nr-1, col) = 0 ;
00218         ope.set(ind1+nr-1, col) = 0 ;
00219       }
00220       ope.set(ind0+nr-1, ind0) = 1 ;
00221       ope.set(ind1+nr-1, ind1) = 1 ;
00222       
00223       ope.set_lu() ;
00224       
00225       Tbl sec(2*nr) ;
00226       sec.set_etat_qcq() ;
00227       for (int lin=0; lin<nr; lin++)
00228         sec.set(lin) = 0 ;
00229       for (int lin=0; lin<nr; lin++)
00230         sec.set(nr+lin) = (*source_coq.get_spectral_va().c_cf)
00231           (lz, k, j, lin) ;
00232       sec.set(ind0+nr-1) = 0 ;
00233       sec.set(ind1+nr-1) = 0 ;
00234       Tbl sol = ope.inverse(sec) ;
00235       for (int i=0; i<nr; i++) {
00236         sol_part_mu.set(lz, k, j, i) = sol(i) ;
00237         sol_part_x.set(lz, k, j, i) = sol(i+nr) ;
00238       }
00239       sec.annule_hard() ;
00240       sec.set(ind0+nr-1) = 1 ;
00241       sol = ope.inverse(sec) ;
00242       for (int i=0; i<nr; i++) {
00243         sol_hom1_mu.set(lz, k, j, i) = sol(i) ;
00244         sol_hom1_x.set(lz, k, j, i) = sol(i+nr) ;
00245       }         
00246       sec.set(ind0+nr-1) = 0 ;
00247       sec.set(ind1+nr-1) = 1 ;
00248       sol = ope.inverse(sec) ;
00249       for (int i=0; i<nr; i++) {
00250         sol_hom2_mu.set(lz, k, j, i) = sol(i) ;
00251         sol_hom2_x.set(lz, k, j, i) = sol(i+nr) ;
00252       }         
00253     }
00254       }
00255     }
00256   }
00257   
00258   //------------------------------
00259   // Compactified external domain
00260   //------------------------------
00261   if (cedbc) {int lz = nzm1 ;  
00262   int nr = mgrid.get_nr(lz) ;
00263   assert(mgrid.get_nt(lz) == nt) ;
00264   assert(mgrid.get_np(lz) == np) ;
00265   double alpha = mp_aff->get_alpha()[lz] ;
00266   Matrice ope(2*nr, 2*nr) ;
00267   ope.set_etat_qcq() ;
00268   
00269   for (int k=0 ; k<np+1 ; k++) {
00270     for (int j=0 ; j<nt ; j++) {
00271       // quantic numbers and spectral bases
00272       base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00273       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
00274     Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
00275     Diff_sx os(base_r, nr) ; const Matrice& ms = os.get_matrice() ;
00276     
00277     for (int lin=0; lin<nr; lin++) 
00278       for (int col=0; col<nr; col++) 
00279         ope.set(lin,col) = - md(lin,col) + 3*ms(lin,col) ;
00280     for (int lin=0; lin<nr; lin++) 
00281       for (int col=0; col<nr; col++) 
00282         ope.set(lin,col+nr) = (2-l_q*(l_q+1))*ms(lin,col) ;
00283     for (int lin=0; lin<nr; lin++) 
00284       for (int col=0; col<nr; col++) 
00285         ope.set(lin+nr,col) = -ms(lin,col) ;
00286     for (int lin=0; lin<nr; lin++) 
00287       for (int col=0; col<nr; col++) 
00288         ope.set(lin+nr,col+nr) = -md(lin,col) ;
00289     
00290     ope *= 1./alpha ;
00291     int ind0 = 0 ;
00292     int ind1 = nr ;
00293     for (int col=0; col<2*nr; col++) {
00294       ope.set(ind0+nr-1, col) = 0 ;
00295       ope.set(ind1+nr-2, col) = 0 ;
00296       ope.set(ind1+nr-1, col) = 0 ;
00297     }
00298     for (int col=0; col<nr; col++) {
00299       ope.set(ind0+nr-1, col+ind0) = 1 ;
00300       ope.set(ind1+nr-1, col+ind1) = 1 ;
00301     }
00302     ope.set(ind1+nr-2, ind1+1) = 1 ;
00303     
00304     ope.set_lu() ;
00305     
00306     Tbl sec(2*nr) ;
00307     sec.set_etat_qcq() ;
00308     for (int lin=0; lin<nr; lin++)
00309       sec.set(lin) = 0 ;
00310     for (int lin=0; lin<nr; lin++)
00311       sec.set(nr+lin) = (*source.get_spectral_va().c_cf)
00312         (lz, k, j, lin) ;
00313     sec.set(ind0+nr-1) = 0 ;
00314     sec.set(ind1+nr-2) = 0 ;
00315     sec.set(ind1+nr-1) = 0 ;
00316     Tbl sol = ope.inverse(sec) ;
00317     for (int i=0; i<nr; i++) {
00318       sol_part_mu.set(lz, k, j, i) = sol(i) ;
00319       sol_part_x.set(lz, k, j, i) = sol(i+nr) ;
00320     }
00321     sec.annule_hard() ;
00322     sec.set(ind1+nr-2) = 1 ;
00323     sol = ope.inverse(sec) ;
00324     for (int i=0; i<nr; i++) {
00325       sol_hom1_mu.set(lz, k, j, i) = sol(i) ;
00326       sol_hom1_x.set(lz, k, j, i) = sol(i+nr) ;
00327     }           
00328       }
00329     }
00330   }
00331   }
00332   
00333   
00334   // On écrit maintenant le système de raccord
00335   
00336   int taille = 2*nz_bc ;
00337   if (cedbc) taille-- ;
00338   Mtbl_cf& mmu = *tilde_mu.set_spectral_va().c_cf ;
00339   Mtbl_cf& mw = *x_new.set_spectral_va().c_cf ;
00340   
00341   Tbl sec_membre(taille) ; 
00342   Matrice systeme(taille, taille) ; 
00343   int ligne ;  int colonne ;
00344   Tbl pipo(1) ;
00345   const Tbl& mub = (cedbc ? pipo : par_bc->get_tbl_mod(2) );
00346   double c_mu = (cedbc ? 0 : par_bc->get_tbl_mod(0)(0) ) ;
00347   double d_mu = (cedbc ? 0 : par_bc->get_tbl_mod(0)(1) ) ;
00348   double c_x = (cedbc ? 0 : par_bc->get_tbl_mod(0)(2) ) ;
00349   double d_x = (cedbc ? 0 : par_bc->get_tbl_mod(0)(3) ) ;
00350   Mtbl_cf dhom1_mu = sol_hom1_mu ; 
00351   Mtbl_cf dhom2_mu = sol_hom2_mu ; 
00352   Mtbl_cf dpart_mu = sol_part_mu ; 
00353   Mtbl_cf dhom1_x = sol_hom1_x ; 
00354   Mtbl_cf dhom2_x = sol_hom2_x ; 
00355   Mtbl_cf dpart_x = sol_part_x ; 
00356   
00357   
00358   dhom1_mu.dsdx() ;
00359   dhom2_mu.dsdx() ;
00360   dpart_mu.dsdx() ;
00361   dhom1_x.dsdx() ;
00362   dhom2_x.dsdx() ;
00363   dpart_x.dsdx() ;
00364   
00365   
00366   // Loop on l and m
00367   //----------------
00368   for (int k=0 ; k<np+1 ; k++)
00369     for (int j=0 ; j<nt ; j++) {
00370       base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;
00371       if ((nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
00372     ligne = 0 ;
00373     colonne = 0 ;
00374     systeme.annule_hard() ;
00375     sec_membre.annule_hard() ;
00376     
00377     //First shell 
00378     // Internal boundary condition
00379     int nr = mgrid.get_nr(1) ;
00380     double alpha2 = mp_aff->get_alpha()[1] ;    
00381 
00382 
00383     systeme.set(ligne, colonne) = 2.*dhom1_mu.val_in_bound_jk(1,j,k)/alpha2 + (2. -double(l_q*(l_q+1)))*sol_hom1_mu.val_in_bound_jk(1, j, k);
00384     systeme.set(ligne, colonne+1) =  2.*dhom2_mu.val_in_bound_jk(1,j,k)/alpha2+ (2.-double(l_q*(l_q+1)))*sol_hom2_mu.val_in_bound_jk(1, j, k);
00385 
00387 
00388     //    double blob =  (*(bound_hrr.get_spectral_va().c_cf)).val_in_bound_jk(1, j, k);    
00389     //    double blob2 =  (*(bound_eta.get_spectral_va().c_cf)).val_in_bound_jk(1, j, k);    
00390 
00391     //    systeme.set(ligne, colonne)= 2.*dhom1_eta.val_in_bound_jk(1,j,k) -double(l_q*(l_q+1.))*sol_hom1_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom1_hrr.val_in_bound_jk(1,j,k);
00392 
00393 
00394 
00395     //    systeme.set(ligne, colonne+1)=  2.*dhom2_eta.val_in_bound_jk(1,j,k) -double(l_q*(l_q+1.))*sol_hom2_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom2_hrr.val_in_bound_jk(1,j,k);  
00396   
00397     //    systeme.set(ligne, colonne+2)=  2.*dhom3_eta.val_in_bound_jk(1,j,k) -double(l_q*(l_q+1.))*sol_hom3_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom3_hrr.val_in_bound_jk(1,j,k);
00398   
00399     //    sec_membre.set(ligne)= -(2.*dpart_eta.val_in_bound_jk(1,j,k) -double(l_q*(l_q+1.))*sol_part_eta.val_in_bound_jk(1,j,k) + 2.*sol_part_hrr.val_in_bound_jk(1,j,k));
00400     //    // ICI probleme: je ne vois pas pourquoi les derivees ne doivent pas etre divisees par alpha2 (experimentalement, elles ne doivent pas l'etre...) idees: parce que la condition est en etatilde et pas eta, ce qui elimine le facteur alpha?
00401 
00402     //        sec_membre.set(ligne) += blob2;
00403 
00404     //   ligne++ ;
00405 
00407 
00408     
00409     Mtbl_cf *boundmu = bound_mu.get_spectral_va().c_cf;
00410         double blob = (*boundmu).val_in_bound_jk(1,j,k);
00411     sec_membre.set(ligne) =  -(2.*dpart_mu.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1)))*sol_part_mu.val_in_bound_jk(1, j, k))+ blob;
00412 
00413   
00414 
00415     ligne++; 
00416     // Condition at x=1
00417     systeme.set(ligne, colonne) = 
00418       sol_hom1_mu.val_out_bound_jk(1, j, k) ;
00419     systeme.set(ligne, colonne+1) = 
00420       sol_hom2_mu.val_out_bound_jk(1, j, k) ;
00421     
00422     sec_membre.set(ligne) -= sol_part_mu.val_out_bound_jk(1, j, k) ;
00423     ligne++ ;
00424     
00425     systeme.set(ligne, colonne) = 
00426       sol_hom1_x.val_out_bound_jk(1, j, k) ;
00427     systeme.set(ligne, colonne+1) = 
00428       sol_hom2_x.val_out_bound_jk(1, j, k) ;
00429     
00430     sec_membre.set(ligne) -= sol_part_x.val_out_bound_jk(1, j, k) ;
00431     
00432     colonne += 2 ;
00433 
00434     //shells with nz>2
00435     for (int zone=2 ; zone<nz_bc ; zone++) {
00436       nr = mgrid.get_nr(zone) ;
00437       ligne-- ;
00438       
00439       //Condition at x = -1
00440       systeme.set(ligne, colonne) = 
00441         - sol_hom1_mu.val_in_bound_jk(zone, j, k) ;
00442       systeme.set(ligne, colonne+1) = 
00443         - sol_hom2_mu.val_in_bound_jk(zone, j, k) ;
00444       
00445       sec_membre.set(ligne) += sol_part_mu.val_in_bound_jk(zone, j, k) ;
00446       ligne++ ;
00447       
00448       systeme.set(ligne, colonne) = 
00449         - sol_hom1_x.val_in_bound_jk(zone, j, k) ;
00450       systeme.set(ligne, colonne+1) = 
00451         - sol_hom2_x.val_in_bound_jk(zone, j, k) ;
00452       
00453       sec_membre.set(ligne) += sol_part_x.val_in_bound_jk(zone, j, k) ;
00454       ligne++ ;
00455       
00456       // Condition at x=1
00457       systeme.set(ligne, colonne) = 
00458         sol_hom1_mu.val_out_bound_jk(zone, j, k) ;
00459       systeme.set(ligne, colonne+1) = 
00460         sol_hom2_mu.val_out_bound_jk(zone, j, k) ;
00461       
00462       sec_membre.set(ligne) -= sol_part_mu.val_out_bound_jk(zone, j, k) ;
00463       ligne++ ;
00464       
00465       systeme.set(ligne, colonne) = 
00466         sol_hom1_x.val_out_bound_jk(zone, j, k) ;
00467       systeme.set(ligne, colonne+1) = 
00468         sol_hom2_x.val_out_bound_jk(zone, j, k) ;
00469       
00470       sec_membre.set(ligne) -= sol_part_x.val_out_bound_jk(zone, j, k) ;
00471       
00472       colonne += 2 ;
00473     }
00474     
00475     //Last  domain   
00476     nr = mgrid.get_nr(nz_bc) ;
00477     double alpha = mp_aff->get_alpha()[nz_bc] ;
00478     ligne-- ;
00479     
00480     //Condition at x = -1
00481     systeme.set(ligne, colonne) = 
00482       - sol_hom1_mu.val_in_bound_jk(nz_bc, j, k) ;
00483     if (!cedbc) systeme.set(ligne, colonne+1) = 
00484               - sol_hom2_mu.val_in_bound_jk(nz_bc, j, k) ;
00485     
00486     sec_membre.set(ligne) += sol_part_mu.val_in_bound_jk(nz_bc, j, k) ;
00487     ligne++ ;
00488     
00489     systeme.set(ligne, colonne) = 
00490       - sol_hom1_x.val_in_bound_jk(nz_bc, j, k) ;
00491     if (!cedbc) systeme.set(ligne, colonne+1) = 
00492               - sol_hom2_x.val_in_bound_jk(nz_bc, j, k) ;
00493     
00494     sec_membre.set(ligne) += sol_part_x.val_in_bound_jk(nz_bc, j, k) ;
00495     ligne++ ;
00496     
00497     if (!cedbc) {// Special condition at x=1
00498       
00499       systeme.set(ligne, colonne) = 
00500         c_mu*sol_hom1_mu.val_out_bound_jk(nz_bc, j, k) 
00501         + d_mu*dhom1_mu.val_out_bound_jk(nz_bc, j, k) / alpha 
00502         + c_x*sol_hom1_x.val_out_bound_jk(nz_bc, j, k) 
00503         + d_x*dhom1_x.val_out_bound_jk(nz_bc, j, k) / alpha ;
00504       systeme.set(ligne, colonne+1) = 
00505         c_mu*sol_hom2_mu.val_out_bound_jk(nz_bc, j, k) 
00506         + d_mu*dhom2_mu.val_out_bound_jk(nz_bc, j, k) / alpha
00507         + c_x*sol_hom2_x.val_out_bound_jk(nz_bc, j, k) 
00508         + d_x*dhom2_x.val_out_bound_jk(nz_bc, j, k) / alpha ;
00509       
00510       sec_membre.set(ligne) -= c_mu*sol_part_mu.val_out_bound_jk(nz_bc, j, k) 
00511         + d_mu*dpart_mu.val_out_bound_jk(nz_bc, j, k)/alpha
00512         + c_x*sol_part_mu.val_out_bound_jk(nz_bc, j, k) 
00513         + d_x*dpart_mu.val_out_bound_jk(nz_bc, j, k)/alpha
00514         - mub(k, j) ;
00515     }
00516     
00517     
00518     
00519     
00521     // System inversion: Solution of the system giving the coefficients for the homogeneous 
00522     // solutions
00523     //-------------------------------------------------------------------
00524     systeme.set_lu() ;
00525     Tbl facteur = systeme.inverse(sec_membre) ;
00526     
00527        
00528     int conte = 0 ;
00529     
00530     // everything in its right place...
00531     //----------------------------------------
00532     nr = mgrid.get_nr(0) ; //nucleus
00533     for (int i=0 ; i<nr ; i++) {
00534       mmu.set(0, k, j, i) = 0 ;
00535       mw.set(0, k, j, i) = 0 ;
00536     }
00537     nr = mgrid.get_nr(1) ; //first shell
00538     for (int i=0 ; i<nr ; i++) {
00539       mmu.set(1, k, j, i) = sol_part_mu(1, k, j, i)
00540         + facteur(conte)*sol_hom1_mu(1, k, j, i)
00541         + facteur(conte+1)*sol_hom2_mu(1, k, j, i);
00542       mw.set(1, k, j, i) = sol_part_x(1, k, j, i)
00543         + facteur(conte)*sol_hom1_x(1, k, j, i)
00544         + facteur(conte+1)*sol_hom2_x(1,k,j,i);
00545     }
00546     conte+=2 ;
00547     for (int zone=2 ; zone<=n_shell ; zone++) { //shells
00548       nr = mgrid.get_nr(zone) ;
00549       for (int i=0 ; i<nr ; i++) {
00550         mmu.set(zone, k, j, i) = sol_part_mu(zone, k, j, i)
00551           + facteur(conte)*sol_hom1_mu(zone, k, j, i) 
00552           + facteur(conte+1)*sol_hom2_mu(zone, k, j, i) ;
00553         
00554         mw.set(zone, k, j, i) = sol_part_x(zone, k, j, i)
00555           + facteur(conte)*sol_hom1_x(zone, k, j, i) 
00556           + facteur(conte+1)*sol_hom2_x(zone, k, j, i) ;
00557       }
00558       conte+=2 ;
00559     }
00560     if (cedbc) {
00561       nr = mgrid.get_nr(nzm1) ; //compactified external domain
00562       for (int i=0 ; i<nr ; i++) {
00563         mmu.set(nzm1, k, j, i) = sol_part_mu(nzm1, k, j, i)
00564           + facteur(conte)*sol_hom1_mu(nzm1, k, j, i) ;
00565         
00566         mw.set(nzm1, k, j, i) = sol_part_x(nzm1, k, j, i)
00567           + facteur(conte)*sol_hom1_x(nzm1, k, j, i) ;
00568       }
00569     }
00570       } // End of nullite_plm  
00571     } //End of loop on theta
00572   
00573   if (tilde_mu.set_spectral_va().c != 0x0) 
00574     delete tilde_mu.set_spectral_va().c ;
00575   tilde_mu.set_spectral_va().c = 0x0 ;
00576   tilde_mu.set_spectral_va().ylm_i() ;
00577   
00578   if (x_new.set_spectral_va().c != 0x0) 
00579     delete x_new.set_spectral_va().c ;
00580   x_new.set_spectral_va().c = 0x0 ;
00581   x_new.set_spectral_va().ylm_i();
00582   
00583 }
00584 
00585 
00586 
00587 //----------------------------------------------------------------------------------
00588 //
00589 //                               sol_Dirac_tilde_B
00590 //
00591 //----------------------------------------------------------------------------------
00592 
00593 void Sym_tensor_trans::sol_Dirac_BC3(const Scalar& bbt, const Scalar& hh, 
00594                      Scalar& hrr, Scalar& tilde_eta, Scalar& ww, Scalar bound_hrr, Scalar bound_eta, Param* par_bc, Param* par_mat) {
00595   
00596   const Map_af* mp_aff = dynamic_cast<const Map_af*>(mp) ;
00597   assert(mp_aff != 0x0) ; //Only affine mapping for the moment
00598   
00599   const Mg3d& mgrid = *mp_aff->get_mg() ;
00600   assert(mgrid.get_type_r(0) == RARE)  ;
00601 
00602   int nz = mgrid.get_nzone() ;
00603   int nzm1 = nz - 1 ;
00604   bool ced = (mgrid.get_type_r(nzm1) == UNSURR) ;
00605   int n_shell = ced ? nz-2 : nzm1 ;
00606   int nz_bc = nzm1 ;
00607   if (par_bc != 0x0)
00608     if (par_bc->get_n_int() > 0)
00609       nz_bc = par_bc->get_int() ;
00610   n_shell = (nz_bc < n_shell ? nz_bc : n_shell) ;
00611   bool cedbc = (ced && (nz_bc == nzm1)) ; 
00612 #ifndef NDEBUG
00613   if (!cedbc) {
00614     assert(par_bc != 0x0) ;
00615     assert(par_bc->get_n_tbl_mod() >= 2) ;
00616   }
00617 #endif
00618   int nt = mgrid.get_nt(0) ;
00619   int np = mgrid.get_np(0) ;
00620     
00621   int l_q, m_q, base_r;
00622 
00623   // ON passe en ylm les quantités B et C !!! CRUCIAL !!! 
00624  
00625   Scalar bbt2 = bbt; bbt2.set_spectral_va().ylm();
00626 
00627   Scalar hh2 = hh; hh2.set_spectral_va().ylm();
00628  
00629   Base_val base = hh2.get_spectral_base() ; 
00630   
00631   
00632   //   Scalar tilde_b(*mp_aff); tilde_b.annule_hard(); tilde_b.std_spectral_base();
00633   //   tilde_b.set_spectral_va().ylm();
00634 
00635   //   // Base_val base = hrr.get_spectral_base();
00636 
00637   //   //   int m_q, l_q, base_r ;
00638   //    for (int lz=0; lz<nz; lz++) {
00639   //     int nr = mgrid.get_nr(lz);
00640   //        for (int k=0; k<np+1; k++)
00641   //        for (int j=0; j<nt; j++) {
00642   //            base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00643   //            if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1))
00644   //            {
00645   //            for (int i=0; i<nr; i++) 
00646   //                tilde_b.set_spectral_va().c_cf->set(lz, k, j, i)
00647   //        +=  2*(*bb2.get_spectral_va().c_cf)(lz, k, j, i)
00648   //          +  (*cc2.get_spectral_va().c_cf)(lz, k, j, i)/ (2* double(l_q +1.));
00649   //            }
00650   //        }
00651   //    }
00652 
00653 
00654   //        if (tilde_b.set_spectral_va().c != 0x0) 
00655   //        delete tilde_b.set_spectral_va().c ;
00656   //            tilde_b.set_spectral_va().c = 0x0 ;
00657   //    tilde_b.set_spectral_va().coef_i();
00658     
00659 
00660   if ( (bbt.get_etat() == ETATZERO) && (hh.get_etat() == ETATZERO) ) {
00661     hrr = 0 ;
00662     tilde_eta = 0 ;
00663     ww = 0 ;
00664     return ;
00665   }
00666 
00667   bound_hrr.set_spectral_va().ylm();
00668   bound_eta.set_spectral_va().ylm();
00669  
00670  
00671   assert (bbt.get_etat() != ETATNONDEF) ;
00672   assert (hh.get_etat() != ETATNONDEF) ;
00673   
00674   Scalar source = bbt ;
00675   Scalar source_coq = bbt ;
00676   source_coq.annule_domain(0) ;
00677   source_coq.annule_domain(nzm1) ;
00678   source_coq.mult_r() ;
00679   source.set_spectral_va().ylm() ;
00680   source_coq.set_spectral_va().ylm() ;
00681   bool bnull = (bbt.get_etat() == ETATZERO) ;
00682   
00683   assert(hh.check_dzpuis(0)) ;
00684   Scalar hoverr = hh ;
00685   hoverr.div_r_dzpuis(2) ;
00686   hoverr.set_spectral_va().ylm() ;
00687   Scalar dhdr = hh.dsdr() ;
00688   dhdr.set_spectral_va().ylm() ;
00689   Scalar h_coq = hh ;
00690   h_coq.set_spectral_va().ylm() ;
00691   Scalar dh_coq = hh.dsdr() ;
00692   dh_coq.mult_r_dzpuis(0) ;
00693   dh_coq.set_spectral_va().ylm() ;    
00694   bool hnull = (hh.get_etat() == ETATZERO) ;
00695     
00696   int lmax = base.give_lmax(mgrid, 0) + 1;
00697     
00698 
00699   // Utilisation des params, facultative, permettant uniquement une optimisation....
00700     
00701   bool need_calculation = true ;
00702   if (par_mat != 0x0) {
00703     bool param_new = false ;
00704     if ((par_mat->get_n_int_mod() >= 4)
00705     &&(par_mat->get_n_tbl_mod()>=1)
00706     &&(par_mat->get_n_matrice_mod()>=1)
00707     &&(par_mat->get_n_itbl_mod()>=1)) {
00708       if (par_mat->get_int_mod(0) < nz_bc) param_new = true ;
00709       if (par_mat->get_int_mod(1) != lmax) param_new = true ;
00710       if (par_mat->get_int_mod(2) != mgrid.get_type_t() ) param_new = true ;
00711       if (par_mat->get_int_mod(3) != mgrid.get_type_p() ) param_new = true ;
00712       if (par_mat->get_itbl_mod(0)(0) != mgrid.get_nr(0)) param_new = true ;
00713       if (fabs(par_mat->get_tbl_mod(0)(0) - mp_aff->get_alpha()[0]) > 2.e-15)
00714     param_new = true ; 
00715       for (int l=1; l<= n_shell; l++) {
00716     if (par_mat->get_itbl_mod(0)(l) != mgrid.get_nr(l)) param_new = true ;
00717     if (fabs(par_mat->get_tbl_mod(0)(l) - mp_aff->get_beta()[l] / 
00718          mp_aff->get_alpha()[l]) > 2.e-15) param_new = true ;
00719       }
00720       if (ced) {
00721     if (par_mat->get_itbl_mod(0)(nzm1) != mgrid.get_nr(nzm1)) param_new = true ;
00722     if (fabs(par_mat->get_tbl_mod(0)(nzm1) - mp_aff->get_alpha()[nzm1]) > 2.e-15)
00723       param_new = true ; 
00724       }
00725     }
00726     else{
00727       param_new = true ;
00728     }
00729     if (param_new) {
00730       par_mat->clean_all() ;
00731       par_mat->add_int_mod(*(new int(nz_bc)), 0) ;
00732       par_mat->add_int_mod(*(new int(lmax)), 1) ;
00733       par_mat->add_int_mod(*(new int(mgrid.get_type_t())), 2) ;
00734       par_mat->add_int_mod(*(new int(mgrid.get_type_p())), 3) ;
00735       Itbl* pnr = new Itbl(nz) ;
00736       pnr->set_etat_qcq() ;
00737       par_mat->add_itbl_mod(*pnr) ;
00738       for (int l=0; l<nz; l++)
00739     pnr->set(l) = mgrid.get_nr(l) ;
00740       Tbl* palpha = new Tbl(nz) ;
00741       palpha->set_etat_qcq() ;
00742       par_mat->add_tbl_mod(*palpha) ;
00743       palpha->set(0) = mp_aff->get_alpha()[0] ;
00744       for (int l=1; l<nzm1; l++)
00745     palpha->set(l) = mp_aff->get_beta()[l] / mp_aff->get_alpha()[l] ;
00746       palpha->set(nzm1) = mp_aff->get_alpha()[nzm1] ;
00747     }
00748     else need_calculation = false ;
00749   }
00750 
00751   hrr.set_etat_qcq() ;
00752   hrr.set_spectral_base(base) ;
00753   hrr.set_spectral_va().set_etat_cf_qcq() ;
00754   hrr.set_spectral_va().c_cf->annule_hard() ;   
00755   tilde_eta.annule_hard() ;
00756   tilde_eta.set_spectral_base(base) ;
00757   tilde_eta.set_spectral_va().set_etat_cf_qcq() ;
00758   tilde_eta.set_spectral_va().c_cf->annule_hard() ;   
00759   ww.annule_hard() ;
00760   ww.set_spectral_base(base) ;
00761   ww.set_spectral_va().set_etat_cf_qcq() ;
00762   ww.set_spectral_va().c_cf->annule_hard() ;   
00763 
00764   sol_Dirac_l01_bound(hh2, hrr, tilde_eta, bound_hrr, bound_eta, par_mat) ;
00765   tilde_eta.annule_l(0,0, true) ;
00766     
00767   Mtbl_cf sol_part_hrr(mgrid, base) ; sol_part_hrr.annule_hard() ;
00768   Mtbl_cf sol_part_eta(mgrid, base) ; sol_part_eta.annule_hard() ;
00769   Mtbl_cf sol_part_w(mgrid, base) ; sol_part_w.annule_hard() ;
00770   Mtbl_cf sol_hom1_hrr(mgrid, base) ; sol_hom1_hrr.annule_hard() ;
00771   Mtbl_cf sol_hom1_eta(mgrid, base) ; sol_hom1_eta.annule_hard() ;
00772   Mtbl_cf sol_hom1_w(mgrid, base) ; sol_hom1_w.annule_hard() ;
00773   Mtbl_cf sol_hom2_hrr(mgrid, base) ; sol_hom2_hrr.annule_hard() ;
00774   Mtbl_cf sol_hom2_eta(mgrid, base) ; sol_hom2_eta.annule_hard() ;
00775   Mtbl_cf sol_hom2_w(mgrid, base) ; sol_hom2_w.annule_hard() ;
00776   Mtbl_cf sol_hom3_hrr(mgrid, base) ; sol_hom3_hrr.annule_hard() ;
00777   Mtbl_cf sol_hom3_eta(mgrid, base) ; sol_hom3_eta.annule_hard() ;
00778   Mtbl_cf sol_hom3_w(mgrid, base) ; sol_hom3_w.annule_hard() ;
00779     
00780   Itbl mat_done(lmax) ;
00781     
00782     
00783   //   Calcul des solutions homogenes et particulieres... 
00784     
00785     
00786   //---------------
00787   //--  NUCLEUS ---
00788   //---------------
00789   {int lz = 0 ;  
00790   int nr = mgrid.get_nr(lz) ;
00791   double alpha = mp_aff->get_alpha()[lz] ;
00792   Matrice ope(3*nr, 3*nr) ;
00793   int ind2 = 2*nr ;
00794   if (need_calculation && (par_mat != 0x0)) mat_done.annule_hard() ;
00795     
00796   for (int k=0 ; k<np+1 ; k++) {
00797     for (int j=0 ; j<nt ; j++) {
00798       // quantic numbers and spectral bases
00799       base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00800       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
00801     if (need_calculation) {
00802       ope.set_etat_qcq() ;
00803       Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
00804       Diff_sx os(base_r, nr) ; const Matrice& ms = os.get_matrice() ;
00805           
00806       for (int lin=0; lin<nr; lin++) 
00807         for (int col=0; col<nr; col++) 
00808           ope.set(lin,col) = md(lin,col) + 3*ms(lin,col) ;
00809       for (int lin=0; lin<nr; lin++) 
00810         for (int col=0; col<nr; col++) 
00811           ope.set(lin,col+nr) = -l_q*(l_q+1)*ms(lin,col) ;
00812       for (int lin=0; lin<nr; lin++) 
00813         for (int col=0; col<nr; col++) 
00814           ope.set(lin,col+2*nr) = 0 ;
00815       for (int lin=0; lin<nr; lin++) 
00816         for (int col=0; col<nr; col++) 
00817           ope.set(lin+nr,col) = -0.5*ms(lin,col) ;
00818       for (int lin=0; lin<nr; lin++) 
00819         for (int col=0; col<nr; col++) 
00820           ope.set(lin+nr,col+nr) = md(lin,col) + 3*ms(lin,col) ;
00821       for (int lin=0; lin<nr; lin++) 
00822         for (int col=0; col<nr; col++) 
00823           ope.set(lin+nr,col+2*nr) = (2. - l_q*(l_q+1))*ms(lin,col) ;
00824       for (int lin=0; lin<nr; lin++) 
00825         for (int col=0; col<nr; col++) 
00826           ope.set(lin+2*nr,col) = -0.5*md(lin,col)/double(l_q+1) 
00827         - 0.5*double(l_q+4)/double(l_q+1)*ms(lin,col) ;
00828       for (int lin=0; lin<nr; lin++) 
00829         for (int col=0; col<nr; col++) 
00830           ope.set(lin+2*nr,col+nr) = -2*ms(lin,col) ;
00831       for (int lin=0; lin<nr; lin++) 
00832         for (int col=0; col<nr; col++) 
00833           ope.set(lin+2*nr,col+2*nr) =  (l_q+2)*md(lin,col) 
00834         + l_q*(l_q+2)*ms(lin,col) ;
00835           
00836       ope *= 1./alpha ;
00837       for (int col=0; col<3*nr; col++) 
00838         if (l_q>2) ope.set(ind2+nr-2, col) = 0 ;
00839       for (int col=0; col<3*nr; col++) {
00840         ope.set(nr-1, col) = 0 ;
00841         ope.set(2*nr-1, col) = 0 ;
00842         ope.set(3*nr-1, col) = 0 ;
00843       }
00844       int pari = 1 ;
00845       if (base_r == R_CHEBP) {
00846         for (int col=0; col<nr; col++) {
00847           ope.set(nr-1, col) = pari ;
00848           ope.set(2*nr-1, col+nr) = pari ;
00849           ope.set(3*nr-1, col+2*nr) = pari ;
00850           pari = - pari ;
00851         }
00852       }
00853       else { //In the odd case, the last coefficient must be zero!
00854         ope.set(nr-1, nr-1) = 1 ;
00855         ope.set(2*nr-1, 2*nr-1) = 1 ;
00856         ope.set(3*nr-1, 3*nr-1) = 1 ;
00857       }         
00858       if (l_q>2) 
00859         ope.set(ind2+nr-2, ind2) = 1 ;
00860           
00861       ope.set_lu() ;
00862       if ((par_mat != 0x0) && (mat_done(l_q) == 0)) {
00863         Matrice* pope = new Matrice(ope) ;
00864         par_mat->add_matrice_mod(*pope, lz*lmax + l_q) ;
00865         mat_done.set(l_q) = 1 ;
00866       }
00867     } //End of case when a calculation is needed
00868         
00869     const Matrice& oper = (par_mat == 0x0 ? ope : 
00870                    par_mat->get_matrice_mod(lz*lmax + l_q) ) ;
00871     Tbl sec(3*nr) ;
00872     sec.set_etat_qcq() ;
00873     if (hnull) {
00874       for (int lin=0; lin<2*nr; lin++)
00875         sec.set(lin) = 0 ;
00876       for (int lin=0; lin<nr; lin++)
00877         sec.set(2*nr+lin) = (*source.get_spectral_va().c_cf)
00878           (lz, k, j, lin) ;
00879     }
00880     else {
00881       for (int lin=0; lin<nr; lin++)
00882         sec.set(lin) = (*hoverr.get_spectral_va().c_cf)(lz, k, j, lin) ;
00883       for (int lin=0; lin<nr; lin++)
00884         sec.set(lin+nr) = -0.5*(*hoverr.get_spectral_va().c_cf)
00885           (lz, k, j, lin) ;
00886       if (bnull) {
00887         for (int lin=0; lin<nr; lin++)
00888           sec.set(2*nr+lin)= -0.5/double(l_q+1)*(
00889                   (*dhdr.get_spectral_va().c_cf)(lz, k, j, lin)
00890                               + (l_q+2)*(*hoverr.get_spectral_va().c_cf)(lz, k, j, lin) ) ; //HERE
00891       }
00892       else {
00893         for (int lin=0; lin<nr; lin++)
00894           sec.set(2*nr+lin) =  -0.5/double(l_q+1)*(
00895             (*dhdr.get_spectral_va().c_cf)(lz, k, j, lin)
00896                               + (l_q+2)*(*hoverr.get_spectral_va().c_cf)(lz, k, j, lin) )
00897             + (*source.get_spectral_va().c_cf)(lz, k, j, lin) ; //HERE
00898       }         
00899     }
00900     if (l_q>2) sec.set(ind2+nr-2) = 0 ;
00901     sec.set(3*nr-1) = 0 ;
00902     Tbl sol = oper.inverse(sec) ;
00903     for (int i=0; i<nr; i++) {
00904       sol_part_hrr.set(lz, k, j, i) = sol(i) ;
00905       sol_part_eta.set(lz, k, j, i) = sol(i+nr) ;
00906       sol_part_w.set(lz, k, j, i) = sol(i+2*nr) ;
00907     }
00908     sec.annule_hard() ;
00909     if (l_q>2) {
00910       sec.set(ind2+nr-2) = 1 ;
00911       sol = oper.inverse(sec) ;
00912     }
00913     else { //Homogeneous solution put in by hand in the case l=2
00914       sol.annule_hard() ;
00915       sol.set(0) = 4 ;
00916       sol.set(nr) = 2 ;
00917       sol.set(2*nr) = 1 ;
00918     }
00919     for (int i=0; i<nr; i++) {
00920       sol_hom3_hrr.set(lz, k, j, i) = sol(i) ;
00921       sol_hom3_eta.set(lz, k, j, i) = sol(i+nr) ;
00922       sol_hom3_w.set(lz, k, j, i) = sol(i+2*nr) ;
00923     }
00924       }
00925     }
00926   }
00927   }
00928     
00929     
00930   //-------------
00931   // -- Shells --
00932   //-------------
00933     
00934   for (int lz=1; lz<= n_shell; lz++) {
00935     if (need_calculation && (par_mat != 0x0)) mat_done.annule_hard() ;
00936     int nr = mgrid.get_nr(lz) ;
00937     int ind0 = 0 ;
00938     int ind1 = nr ;
00939     int ind2 = 2*nr ;
00940     double alpha = mp_aff->get_alpha()[lz] ;
00941     double ech = mp_aff->get_beta()[lz] / alpha ;
00942     Matrice ope(3*nr, 3*nr) ;
00943       
00944     for (int k=0 ; k<np+1 ; k++) {
00945       for (int j=0 ; j<nt ; j++) {
00946     // quantic numbers and spectral bases
00947     base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00948     if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
00949       if (need_calculation) {
00950         ope.set_etat_qcq() ;
00951         Diff_xdsdx oxd(base_r, nr) ; const Matrice& mxd = oxd.get_matrice() ;
00952         Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
00953         Diff_id oid(base_r, nr) ; const Matrice& mid = oid.get_matrice() ;
00954               
00955         for (int lin=0; lin<nr; lin++) 
00956           for (int col=0; col<nr; col++) 
00957         ope.set(lin,col) = mxd(lin,col) + ech*md(lin,col) 
00958           + 3*mid(lin,col) ;
00959         for (int lin=0; lin<nr; lin++) 
00960           for (int col=0; col<nr; col++) 
00961         ope.set(lin,col+nr) = -l_q*(l_q+1)*mid(lin,col) ;
00962         for (int lin=0; lin<nr; lin++) 
00963           for (int col=0; col<nr; col++) 
00964         ope.set(lin,col+2*nr) = 0 ;
00965         for (int lin=0; lin<nr; lin++) 
00966           for (int col=0; col<nr; col++) 
00967         ope.set(lin+nr,col) = -0.5*mid(lin,col) ;
00968         for (int lin=0; lin<nr; lin++) 
00969           for (int col=0; col<nr; col++) 
00970         ope.set(lin+nr,col+nr) = mxd(lin,col) + ech*md(lin,col) 
00971           + 3*mid(lin,col) ;
00972         for (int lin=0; lin<nr; lin++) 
00973           for (int col=0; col<nr; col++) 
00974         ope.set(lin+nr,col+2*nr) = (2. - l_q*(l_q+1))*mid(lin,col) ;
00975         for (int lin=0; lin<nr; lin++) 
00976           for (int col=0; col<nr; col++) 
00977         ope.set(lin+2*nr,col) = 
00978           -0.5/double(l_q+1)*(mxd(lin,col) + ech*md(lin,col)
00979                       + double(l_q+4)*mid(lin,col)) ;
00980         for (int lin=0; lin<nr; lin++) 
00981           for (int col=0; col<nr; col++) 
00982         ope.set(lin+2*nr,col+nr) = -2*mid(lin,col) ;
00983         for (int lin=0; lin<nr; lin++) 
00984           for (int col=0; col<nr; col++) 
00985         ope.set(lin+2*nr,col+2*nr) =  
00986           double(l_q+2)*(mxd(lin,col) + ech*md(lin,col) 
00987                  + l_q*mid(lin,col)) ;
00988         for (int col=0; col<3*nr; col++) {
00989           ope.set(ind0+nr-1, col) = 0 ;
00990           ope.set(ind1+nr-1, col) = 0 ;
00991           ope.set(ind2+nr-1, col) = 0 ;
00992         }
00993         ope.set(ind0+nr-1, ind0) = 1 ;
00994         ope.set(ind1+nr-1, ind1) = 1 ;
00995         ope.set(ind2+nr-1, ind2) = 1 ;
00996               
00997         ope.set_lu() ;
00998         if ((par_mat != 0x0) && (mat_done(l_q) == 0)) {
00999           Matrice* pope = new Matrice(ope) ;
01000           par_mat->add_matrice_mod(*pope, lz*lmax + l_q) ;
01001           mat_done.set(l_q) = 1 ;
01002         }
01003       } //End of case when a calculation is needed
01004       const Matrice& oper = (par_mat == 0x0 ? ope : 
01005                  par_mat->get_matrice_mod(lz*lmax + l_q) ) ;
01006       Tbl sec(3*nr) ;
01007       sec.set_etat_qcq() ;
01008       if (hnull) {
01009         for (int lin=0; lin<2*nr; lin++)
01010           sec.set(lin) = 0 ;
01011         for (int lin=0; lin<nr; lin++)
01012           sec.set(2*nr+lin) = (*source_coq.get_spectral_va().c_cf)
01013         (lz, k, j, lin) ;
01014       }
01015       else {
01016         for (int lin=0; lin<nr; lin++)
01017           sec.set(lin) = (*h_coq.get_spectral_va().c_cf)(lz, k, j, lin) ;
01018         for (int lin=0; lin<nr; lin++)
01019           sec.set(lin+nr) = -0.5*(*h_coq.get_spectral_va().c_cf)
01020         (lz, k, j, lin) ;
01021         if (bnull) {
01022           for (int lin=0; lin<nr; lin++)
01023         sec.set(2*nr+lin) = -0.5/double(l_q+1)*(
01024                 (*dh_coq.get_spectral_va().c_cf)(lz, k, j, lin)
01025                             + (l_q+2)*(*h_coq.get_spectral_va().c_cf)(lz, k, j, lin) ) ; //HERE
01026         }
01027         else {
01028           for (int lin=0; lin<nr; lin++)
01029         sec.set(2*nr+lin) = -0.5/double(l_q+1)*(
01030             (*dh_coq.get_spectral_va().c_cf)(lz, k, j, lin)
01031                             + (l_q+2)*(*h_coq.get_spectral_va().c_cf)(lz, k, j, lin) )
01032               + (*source_coq.get_spectral_va().c_cf)(lz, k, j, lin) ; //HERE
01033         }
01034       }
01035       sec.set(ind0+nr-1) = 0 ;
01036       sec.set(ind1+nr-1) = 0 ;
01037       sec.set(ind2+nr-1) = 0 ;
01038       Tbl sol = oper.inverse(sec) ;
01039       for (int i=0; i<nr; i++) {
01040         sol_part_hrr.set(lz, k, j, i) = sol(i) ;
01041         sol_part_eta.set(lz, k, j, i) = sol(i+nr) ;
01042         sol_part_w.set(lz, k, j, i) = sol(i+2*nr) ;
01043       }
01044       sec.annule_hard() ;
01045       sec.set(ind0+nr-1) = 1 ;
01046       sol = oper.inverse(sec) ;
01047       for (int i=0; i<nr; i++) {
01048         sol_hom1_hrr.set(lz, k, j, i) = sol(i) ;
01049         sol_hom1_eta.set(lz, k, j, i) = sol(i+nr) ;
01050         sol_hom1_w.set(lz, k, j, i) = sol(i+2*nr) ;
01051       }         
01052       sec.set(ind0+nr-1) = 0 ;
01053       sec.set(ind1+nr-1) = 1 ;
01054       sol = oper.inverse(sec) ;
01055       for (int i=0; i<nr; i++) {
01056         sol_hom2_hrr.set(lz, k, j, i) = sol(i) ;
01057         sol_hom2_eta.set(lz, k, j, i) = sol(i+nr) ;
01058         sol_hom2_w.set(lz, k, j, i) = sol(i+2*nr) ;
01059       }         
01060       sec.set(ind1+nr-1) = 0 ;
01061       sec.set(ind2+nr-1) = 1 ;
01062       sol = oper.inverse(sec) ;
01063       for (int i=0; i<nr; i++) {
01064         sol_hom3_hrr.set(lz, k, j, i) = sol(i) ;
01065         sol_hom3_eta.set(lz, k, j, i) = sol(i+nr) ;
01066         sol_hom3_w.set(lz, k, j, i) = sol(i+2*nr) ;
01067       } 
01068     }
01069       }
01070     }
01071   }
01072     
01073   //------------------------------
01074   // Compactified external domain
01075   //------------------------------
01076   if (cedbc) {int lz = nzm1 ;  
01077   if (need_calculation && (par_mat != 0x0)) mat_done.annule_hard() ;
01078   int nr = mgrid.get_nr(lz) ;
01079   int ind0 = 0 ;
01080   int ind1 = nr ;
01081   int ind2 = 2*nr ;
01082   double alpha = mp_aff->get_alpha()[lz] ;
01083   Matrice ope(3*nr, 3*nr) ;
01084     
01085   for (int k=0 ; k<np+1 ; k++) {
01086     for (int j=0 ; j<nt ; j++) {
01087       // quantic numbers and spectral bases
01088       base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
01089       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
01090     if (need_calculation) {
01091       ope.set_etat_qcq() ;
01092       Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
01093       Diff_sx os(base_r, nr) ; const Matrice& ms = os.get_matrice() ;
01094         
01095       for (int lin=0; lin<nr; lin++) 
01096         for (int col=0; col<nr; col++) 
01097           ope.set(lin,col) = - md(lin,col) + 3*ms(lin,col) ;
01098       for (int lin=0; lin<nr; lin++) 
01099         for (int col=0; col<nr; col++) 
01100           ope.set(lin,col+nr) = -l_q*(l_q+1)*ms(lin,col) ;
01101       for (int lin=0; lin<nr; lin++) 
01102         for (int col=0; col<nr; col++) 
01103           ope.set(lin,col+2*nr) = 0 ;
01104       for (int lin=0; lin<nr; lin++) 
01105         for (int col=0; col<nr; col++) 
01106           ope.set(lin+nr,col) = -0.5*ms(lin,col) ;
01107       for (int lin=0; lin<nr; lin++) 
01108         for (int col=0; col<nr; col++) 
01109           ope.set(lin+nr,col+nr) = -md(lin,col) + 3*ms(lin,col) ;
01110       for (int lin=0; lin<nr; lin++) 
01111         for (int col=0; col<nr; col++) 
01112           ope.set(lin+nr,col+2*nr) = (2. - l_q*(l_q+1))*ms(lin,col) ;
01113       for (int lin=0; lin<nr; lin++) 
01114         for (int col=0; col<nr; col++) 
01115           ope.set(lin+2*nr,col) =  0.5*md(lin,col)/double(l_q+1) 
01116         - 0.5*double(l_q+4)/double(l_q+1)*ms(lin,col) ;
01117       for (int lin=0; lin<nr; lin++) 
01118         for (int col=0; col<nr; col++) 
01119           ope.set(lin+2*nr,col+nr) = -2*ms(lin,col) ;
01120       for (int lin=0; lin<nr; lin++) 
01121         for (int col=0; col<nr; col++) 
01122           ope.set(lin+2*nr,col+2*nr) =  -(l_q+2)*md(lin,col) 
01123         + l_q*(l_q+2)*ms(lin,col) ;
01124       ope *= 1./alpha ;
01125       for (int col=0; col<3*nr; col++) {
01126         ope.set(ind0+nr-2, col) = 0 ;
01127         ope.set(ind0+nr-1, col) = 0 ;
01128         ope.set(ind1+nr-2, col) = 0 ;
01129         ope.set(ind1+nr-1, col) = 0 ;
01130         ope.set(ind2+nr-1, col) = 0 ;
01131       }
01132       for (int col=0; col<nr; col++) {
01133         ope.set(ind0+nr-1, col+ind0) = 1 ;
01134         ope.set(ind1+nr-1, col+ind1) = 1 ;
01135         ope.set(ind2+nr-1, col+ind2) = 1 ;
01136       }
01137       ope.set(ind0+nr-2, ind0+1) = 1 ;
01138       ope.set(ind1+nr-2, ind1+2) = 1 ;
01139         
01140       ope.set_lu() ;
01141       if ((par_mat != 0x0) && (mat_done(l_q) == 0)) {
01142         Matrice* pope = new Matrice(ope) ;
01143         par_mat->add_matrice_mod(*pope, lz*lmax + l_q) ;
01144         mat_done.set(l_q) = 1 ;
01145       }
01146     } //End of case when a calculation is needed
01147     const Matrice& oper = (par_mat == 0x0 ? ope : 
01148                    par_mat->get_matrice_mod(lz*lmax + l_q) ) ;
01149       
01150     Tbl sec(3*nr) ;
01151     sec.set_etat_qcq() ;
01152     if (hnull) {
01153       for (int lin=0; lin<2*nr; lin++)
01154         sec.set(lin) = 0 ;
01155       for (int lin=0; lin<nr; lin++)
01156         sec.set(2*nr+lin) = (*source.get_spectral_va().c_cf)
01157           (lz, k, j, lin) ;
01158     }
01159     else {
01160       for (int lin=0; lin<nr; lin++)
01161         sec.set(lin) = (*hoverr.get_spectral_va().c_cf)(lz, k, j, lin) ;
01162       for (int lin=0; lin<nr; lin++)
01163         sec.set(lin+nr) = -0.5*(*hoverr.get_spectral_va().c_cf)
01164           (lz, k, j, lin) ;
01165       if (bnull) {
01166         for (int lin=0; lin<nr; lin++)
01167           sec.set(2*nr+lin) = -0.5/double(l_q+1)*(
01168                   (*dhdr.get_spectral_va().c_cf)(lz, k, j, lin)
01169                               + (l_q+2)*(*hoverr.get_spectral_va().c_cf)(lz, k, j, lin) ) ; //HERE
01170       }
01171       else {
01172         for (int lin=0; lin<nr; lin++)
01173           sec.set(2*nr+lin) = -0.5/double(l_q+1)*(
01174             (*dhdr.get_spectral_va().c_cf)(lz, k, j, lin)
01175                               + (l_q+2)*(*hoverr.get_spectral_va().c_cf)(lz, k, j, lin) )
01176             + (*source.get_spectral_va().c_cf)(lz, k, j, lin) ; //HERE
01177       }
01178     }
01179     sec.set(ind0+nr-2) = 0 ;
01180     sec.set(ind0+nr-1) = 0 ;
01181     sec.set(ind1+nr-1) = 0 ;
01182     sec.set(ind1+nr-2) = 0 ;
01183     sec.set(ind2+nr-1) = 0 ;
01184     Tbl sol = oper.inverse(sec) ;
01185     for (int i=0; i<nr; i++) {
01186       sol_part_hrr.set(lz, k, j, i) = sol(i) ;
01187       sol_part_eta.set(lz, k, j, i) = sol(i+nr) ;
01188       sol_part_w.set(lz, k, j, i) = sol(i+2*nr) ;
01189     }
01190     sec.annule_hard() ;
01191     sec.set(ind0+nr-2) = 1 ;
01192     sol = oper.inverse(sec) ;
01193     for (int i=0; i<nr; i++) {
01194       sol_hom1_hrr.set(lz, k, j, i) = sol(i) ;
01195       sol_hom1_eta.set(lz, k, j, i) = sol(i+nr) ;
01196       sol_hom1_w.set(lz, k, j, i) = sol(i+2*nr) ;
01197     }           
01198     sec.set(ind0+nr-2) = 0 ;
01199     sec.set(ind1+nr-2) = 1 ;
01200     sol = oper.inverse(sec) ;
01201     for (int i=0; i<nr; i++) {
01202       sol_hom2_hrr.set(lz, k, j, i) = sol(i) ;
01203       sol_hom2_eta.set(lz, k, j, i) = sol(i+nr) ;
01204       sol_hom2_w.set(lz, k, j, i) = sol(i+2*nr) ;
01205     }
01206       }
01207     }
01208   }
01209   }
01210     
01211   // Matching system...
01212     
01213     
01214     
01215   int taille = 3*nz_bc ; // Un de moins que dans la version complete R3
01216   if (cedbc) taille-- ;
01217   Mtbl_cf& mhrr = *hrr.set_spectral_va().c_cf ;
01218   Mtbl_cf& meta = *tilde_eta.set_spectral_va().c_cf ;
01219   Mtbl_cf& mw = *ww.set_spectral_va().c_cf ;
01220   Tbl sec_membre(taille) ; 
01221   Matrice systeme(taille, taille) ; 
01222   int ligne ;  int colonne ;
01223   Tbl pipo(1) ;
01224   const Tbl& hrrb = (cedbc ? pipo : par_bc->get_tbl_mod(1) );
01225   double chrr = (cedbc ? 0 : par_bc->get_tbl_mod()(4) ) ;
01226   double dhrr = (cedbc ? 0 : par_bc->get_tbl_mod()(5) ) ;
01227   double ceta = (cedbc ? 0 : par_bc->get_tbl_mod()(6) ) ;
01228   double deta = (cedbc ? 0 : par_bc->get_tbl_mod()(7) ) ;
01229   double cw = (cedbc ? 0 : par_bc->get_tbl_mod()(8) ) ;
01230   double dw = (cedbc ? 0 : par_bc->get_tbl_mod()(9) ) ;
01231   Mtbl_cf dhom1_hrr = sol_hom1_hrr ; 
01232   Mtbl_cf dhom2_hrr = sol_hom2_hrr ; 
01233   Mtbl_cf dhom3_hrr = sol_hom3_hrr ; 
01234   Mtbl_cf dpart_hrr = sol_part_hrr ; 
01235   Mtbl_cf dhom1_eta = sol_hom1_eta ; 
01236   Mtbl_cf dhom2_eta = sol_hom2_eta ; 
01237   Mtbl_cf dhom3_eta = sol_hom3_eta ; 
01238   Mtbl_cf dpart_eta = sol_part_eta ; 
01239   Mtbl_cf dhom1_w = sol_hom1_w ; 
01240   Mtbl_cf dhom2_w = sol_hom2_w ; 
01241   Mtbl_cf dhom3_w = sol_hom3_w ; 
01242   Mtbl_cf dpart_w = sol_part_w ; 
01243 
01244 
01245   dhom1_hrr.dsdx() ; dhom1_eta.dsdx() ; dhom1_w.dsdx() ;
01246   dhom2_hrr.dsdx() ; dhom2_eta.dsdx() ; dhom2_w.dsdx() ;
01247   dhom3_hrr.dsdx() ; dhom3_eta.dsdx() ; dhom3_w.dsdx() ;
01248   dpart_hrr.dsdx() ; dpart_eta.dsdx() ; dpart_w.dsdx() ;
01249     
01250   Mtbl_cf d2hom1_hrr = dhom1_hrr ; 
01251   Mtbl_cf d2hom2_hrr = dhom2_hrr ;
01252   Mtbl_cf d2hom3_hrr = dhom3_hrr; 
01253   Mtbl_cf d2part_hrr = dpart_hrr ; 
01254   d2hom1_hrr.dsdx(); d2hom2_hrr.dsdx(); d2hom3_hrr.dsdx(); d2part_hrr.dsdx();
01255  
01256 
01257 
01259   // Loop on l and m//
01261     
01262   for (int k=0 ; k<np+1 ; k++)
01263     for (int j=0 ; j<nt ; j++) {
01264       base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;
01265       if ((nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1)) {
01266     ligne = 0 ;
01267     colonne = 0 ;
01268     systeme.annule_hard() ;
01269     sec_membre.annule_hard() ;
01270       
01271     //First shell
01272     //Condition at x=-1;
01273     int nr = mgrid.get_nr(1);
01274     double alpha2 = mp_aff->get_alpha()[1] ; 
01275     // A robyn-type condition (dependent on spectral harmonic) is imposed on eta.
01276  
01277 
01278  
01279 
01280 
01281     double blob =  (*(bound_hrr.get_spectral_va().c_cf)).val_in_bound_jk(1, j, k);  
01282     double blob2 =  (*(bound_eta.get_spectral_va().c_cf)).val_in_bound_jk(1, j, k);    
01283 
01284     systeme.set(ligne, colonne)= 2.*dhom1_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1.)))*sol_hom1_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom1_hrr.val_in_bound_jk(1,j,k);
01285 
01286     systeme.set(ligne, colonne+1)=  2.*dhom2_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1.)))*sol_hom2_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom2_hrr.val_in_bound_jk(1,j,k);  
01287   
01288     systeme.set(ligne, colonne+2)=  2.*dhom3_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1.)))*sol_hom3_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom3_hrr.val_in_bound_jk(1,j,k);
01289   
01290     sec_membre.set(ligne)= -(2.*dpart_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.- double(l_q*(l_q+1.)))*sol_part_eta.val_in_bound_jk(1,j,k) + 2.*sol_part_hrr.val_in_bound_jk(1,j,k));
01291 
01292 
01293     sec_membre.set(ligne) += blob2;
01294 
01295     ligne++ ;
01296 
01297     // A Robyn-type boundary condition is imposed on hrr
01298 
01299     systeme.set(ligne, colonne) =  2.*dhom1_hrr.val_in_bound_jk(1,j,k)/alpha2 + (4. -double(l_q*(l_q+1.)))*sol_hom1_hrr.val_in_bound_jk(1,j,k);
01300 
01301     systeme.set(ligne, colonne+1) =   2.*dhom2_hrr.val_in_bound_jk(1,j,k)/alpha2 + (4. -double(l_q*(l_q+1.)))*sol_hom2_hrr.val_in_bound_jk(1,j,k);
01302 
01303     systeme.set(ligne, colonne+2) =   2.*dhom3_hrr.val_in_bound_jk(1,j,k)/alpha2 + (4. -double(l_q*(l_q+1.)))*sol_hom3_hrr.val_in_bound_jk(1,j,k);
01304 
01305   
01306     sec_membre.set(ligne)=   -(2.*dpart_hrr.val_in_bound_jk(1,j,k)/alpha2 + (4. -double(l_q*(l_q+1.)))*sol_part_hrr.val_in_bound_jk(1,j,k)) +blob;
01307   
01308   
01309     ligne++ ;
01310       
01311       
01312     //Conditions at x=1;  
01313 
01314     systeme.set(ligne, colonne) = 
01315       sol_hom1_hrr.val_out_bound_jk(1, j, k) ;
01316     systeme.set(ligne, colonne+1) = 
01317       sol_hom2_hrr.val_out_bound_jk(1, j, k) ;
01318     systeme.set(ligne, colonne+2) = 
01319       sol_hom3_hrr.val_out_bound_jk(1, j, k) ;
01320       
01321     sec_membre.set(ligne) -= sol_part_hrr.val_out_bound_jk(1, j, k) ;
01322     ligne++ ;
01323       
01324     systeme.set(ligne, colonne) = 
01325       sol_hom1_eta.val_out_bound_jk(1, j, k) ;
01326     systeme.set(ligne, colonne+1) = 
01327       sol_hom2_eta.val_out_bound_jk(1, j, k) ;
01328     systeme.set(ligne, colonne+2) = 
01329       sol_hom3_eta.val_out_bound_jk(1, j, k) ;
01330       
01331     sec_membre.set(ligne) -= sol_part_eta.val_out_bound_jk(1, j, k) ;
01332     ligne++ ;
01333       
01334     systeme.set(ligne, colonne) = 
01335       sol_hom1_w.val_out_bound_jk(1, j, k) ;
01336     systeme.set(ligne, colonne+1) = 
01337       sol_hom2_w.val_out_bound_jk(1, j, k) ;
01338     systeme.set(ligne, colonne+2) = 
01339       sol_hom3_w.val_out_bound_jk(1, j, k) ;
01340           
01341       
01342     sec_membre.set(ligne) -= sol_part_w.val_out_bound_jk(1, j, k) ;
01343       
01344     colonne += 3 ;
01345 
01346     //shells
01347     for (int zone=2 ; zone<nz_bc ; zone++) {
01348       nr = mgrid.get_nr(zone) ;
01349       ligne -= 2 ;
01350         
01351       //Condition at x = -1
01352       systeme.set(ligne, colonne) = 
01353         - sol_hom1_hrr.val_in_bound_jk(zone, j, k) ;
01354       systeme.set(ligne, colonne+1) = 
01355         - sol_hom2_hrr.val_in_bound_jk(zone, j, k) ;
01356       systeme.set(ligne, colonne+2) = 
01357         - sol_hom3_hrr.val_in_bound_jk(zone, j, k) ;
01358         
01359       sec_membre.set(ligne) += sol_part_hrr.val_in_bound_jk(zone, j, k) ;
01360       ligne++ ;
01361         
01362       systeme.set(ligne, colonne) = 
01363         - sol_hom1_eta.val_in_bound_jk(zone, j, k) ;
01364       systeme.set(ligne, colonne+1) = 
01365         - sol_hom2_eta.val_in_bound_jk(zone, j, k) ;
01366       systeme.set(ligne, colonne+2) = 
01367         - sol_hom3_eta.val_in_bound_jk(zone, j, k) ;
01368         
01369       sec_membre.set(ligne) += sol_part_eta.val_in_bound_jk(zone, j, k) ;
01370       ligne++ ;
01371         
01372       systeme.set(ligne, colonne) = 
01373         - sol_hom1_w.val_in_bound_jk(zone, j, k) ;
01374       systeme.set(ligne, colonne+1) = 
01375         - sol_hom2_w.val_in_bound_jk(zone, j, k) ;
01376       systeme.set(ligne, colonne+2) = 
01377         - sol_hom3_w.val_in_bound_jk(zone, j, k) ;
01378         
01379       sec_membre.set(ligne) += sol_part_w.val_in_bound_jk(zone, j, k) ;
01380       ligne++ ;
01381         
01382       // Condition at x=1
01383       systeme.set(ligne, colonne) = 
01384         sol_hom1_hrr.val_out_bound_jk(zone, j, k) ;
01385       systeme.set(ligne, colonne+1) = 
01386         sol_hom2_hrr.val_out_bound_jk(zone, j, k) ;
01387       systeme.set(ligne, colonne+2) = 
01388         sol_hom3_hrr.val_out_bound_jk(zone, j, k) ;
01389         
01390       sec_membre.set(ligne) -= sol_part_hrr.val_out_bound_jk(zone, j, k) ;
01391       ligne++ ;
01392         
01393       systeme.set(ligne, colonne) = 
01394         sol_hom1_eta.val_out_bound_jk(zone, j, k) ;
01395       systeme.set(ligne, colonne+1) = 
01396         sol_hom2_eta.val_out_bound_jk(zone, j, k) ;
01397       systeme.set(ligne, colonne+2) = 
01398         sol_hom3_eta.val_out_bound_jk(zone, j, k) ;
01399         
01400       sec_membre.set(ligne) -= sol_part_eta.val_out_bound_jk(zone, j, k) ;
01401       ligne++ ;
01402         
01403       systeme.set(ligne, colonne) = 
01404         sol_hom1_w.val_out_bound_jk(zone, j, k) ;
01405       systeme.set(ligne, colonne+1) = 
01406         sol_hom2_w.val_out_bound_jk(zone, j, k) ;
01407       systeme.set(ligne, colonne+2) = 
01408         sol_hom3_w.val_out_bound_jk(zone, j, k) ;
01409         
01410       sec_membre.set(ligne) -= sol_part_w.val_out_bound_jk(zone, j, k) ;
01411         
01412       colonne += 3 ;
01413     }
01414       
01415     //Last domain
01416     nr = mgrid.get_nr(nz_bc) ;
01417     double alpha = mp_aff->get_alpha()[nz_bc] ;
01418     ligne -= 2 ;
01419       
01420     //Condition at x = -1
01421     systeme.set(ligne, colonne) = 
01422       - sol_hom1_hrr.val_in_bound_jk(nz_bc, j, k) ;
01423     systeme.set(ligne, colonne+1) = 
01424       - sol_hom2_hrr.val_in_bound_jk(nz_bc, j, k) ;
01425     if (!cedbc) systeme.set(ligne, colonne+2) = 
01426               - sol_hom3_hrr.val_in_bound_jk(nz_bc, j, k) ;
01427       
01428     sec_membre.set(ligne) += sol_part_hrr.val_in_bound_jk(nz_bc, j, k) ;
01429     ligne++ ;
01430       
01431     systeme.set(ligne, colonne) = 
01432       - sol_hom1_eta.val_in_bound_jk(nz_bc, j, k) ;
01433     systeme.set(ligne, colonne+1) = 
01434       - sol_hom2_eta.val_in_bound_jk(nz_bc, j, k) ;
01435     if (!cedbc) systeme.set(ligne, colonne+2) = 
01436               - sol_hom3_eta.val_in_bound_jk(nz_bc, j, k) ;
01437       
01438     sec_membre.set(ligne) += sol_part_eta.val_in_bound_jk(nz_bc, j, k) ;
01439     ligne++ ;
01440       
01441     systeme.set(ligne, colonne) = 
01442       - sol_hom1_w.val_in_bound_jk(nz_bc, j, k) ;
01443     systeme.set(ligne, colonne+1) = 
01444       - sol_hom2_w.val_in_bound_jk(nz_bc, j, k) ;
01445     if (!cedbc) systeme.set(ligne, colonne+2) = 
01446               - sol_hom3_w.val_in_bound_jk(nz_bc, j, k) ;
01447       
01448     sec_membre.set(ligne) += sol_part_w.val_in_bound_jk(nz_bc, j, k) ;
01449     ligne++ ;
01450       
01451     if (!cedbc) {//Special condition at x=1
01452       systeme.set(ligne, colonne) = 
01453         chrr*sol_hom1_hrr.val_out_bound_jk(nz_bc, j, k) 
01454         + dhrr*dhom1_hrr.val_out_bound_jk(nz_bc, j, k) / alpha 
01455         + ceta*sol_hom1_eta.val_out_bound_jk(nz_bc, j, k) 
01456         + deta*dhom1_eta.val_out_bound_jk(nz_bc, j, k) / alpha 
01457         + cw*sol_hom1_w.val_out_bound_jk(nz_bc, j, k) 
01458         + dw*dhom1_w.val_out_bound_jk(nz_bc, j, k) / alpha ;
01459       systeme.set(ligne, colonne+1) = 
01460         chrr*sol_hom2_hrr.val_out_bound_jk(nz_bc, j, k) 
01461         + dhrr*dhom2_hrr.val_out_bound_jk(nz_bc, j, k) / alpha 
01462         + ceta*sol_hom2_eta.val_out_bound_jk(nz_bc, j, k) 
01463         + deta*dhom2_eta.val_out_bound_jk(nz_bc, j, k) / alpha 
01464         + cw*sol_hom2_w.val_out_bound_jk(nz_bc, j, k) 
01465         + dw*dhom2_w.val_out_bound_jk(nz_bc, j, k) / alpha ;
01466       systeme.set(ligne, colonne+2) = 
01467         chrr*sol_hom3_hrr.val_out_bound_jk(nz_bc, j, k) 
01468         + dhrr*dhom3_hrr.val_out_bound_jk(nz_bc, j, k) / alpha 
01469         + ceta*sol_hom3_eta.val_out_bound_jk(nz_bc, j, k) 
01470         + deta*dhom3_eta.val_out_bound_jk(nz_bc, j, k) / alpha 
01471         + cw*sol_hom3_w.val_out_bound_jk(nz_bc, j, k) 
01472         + dw*dhom3_w.val_out_bound_jk(nz_bc, j, k) / alpha ;
01473         
01474       sec_membre.set(ligne) -= chrr*sol_part_hrr.val_out_bound_jk(nz_bc, j, k) 
01475         + dhrr*dpart_hrr.val_out_bound_jk(nz_bc, j, k)/alpha 
01476         + ceta*sol_part_eta.val_out_bound_jk(nz_bc, j, k) 
01477         + deta*dpart_eta.val_out_bound_jk(nz_bc, j, k)/alpha 
01478         + cw*sol_part_w.val_out_bound_jk(nz_bc, j, k) 
01479         + dw*dpart_w.val_out_bound_jk(nz_bc, j, k)/alpha 
01480         - hrrb(k, j)  ;
01481     }
01482       
01483 
01485        
01486       
01487       
01488     //System inversion:  Solution of the system giving the coefficients for the homogeneous 
01489     // solutions
01490     //-------------------------------------------------------------------
01491 
01492     systeme.set_lu() ;
01493     Tbl facteur = systeme.inverse(sec_membre) ;
01494     int conte = 0 ;
01495            
01496        
01497     // everything is put to the right place, 
01498     //---------------------------------------
01499     nr = mgrid.get_nr(0) ; //nucleus
01500     for (int i=0 ; i<nr ; i++) {
01501       mhrr.set(0, k, j, i) = 0 ;
01502       meta.set(0, k, j, i) = 0 ;
01503       mw.set(0, k, j, i) = 0 ;
01504     }
01505     for (int zone=1 ; zone<=n_shell ; zone++) { //shells
01506       nr = mgrid.get_nr(zone) ;
01507       for (int i=0 ; i<nr ; i++) {
01508         mhrr.set(zone, k, j, i) = sol_part_hrr(zone, k, j, i)
01509           + facteur(conte)*sol_hom1_hrr(zone, k, j, i) 
01510           + facteur(conte+1)*sol_hom2_hrr(zone, k, j, i) 
01511           + facteur(conte+2)*sol_hom3_hrr(zone, k, j, i) ;
01512             
01513         meta.set(zone, k, j, i) = sol_part_eta(zone, k, j, i)
01514           + facteur(conte)*sol_hom1_eta(zone, k, j, i) 
01515           + facteur(conte+1)*sol_hom2_eta(zone, k, j, i) 
01516           + facteur(conte+2)*sol_hom3_eta(zone, k, j, i) ;
01517             
01518         mw.set(zone, k, j, i) = sol_part_w(zone, k, j, i)
01519           + facteur(conte)*sol_hom1_w(zone, k, j, i) 
01520           + facteur(conte+1)*sol_hom2_w(zone, k, j, i) 
01521           + facteur(conte+2)*sol_hom3_w(zone, k, j, i) ;            
01522       }
01523       conte+=3 ;
01524     }
01525     if (cedbc) {
01526       nr = mgrid.get_nr(nzm1) ; //compactified external domain
01527       for (int i=0 ; i<nr ; i++) {
01528         mhrr.set(nzm1, k, j, i) = sol_part_hrr(nzm1, k, j, i)
01529           + facteur(conte)*sol_hom1_hrr(nzm1, k, j, i) 
01530           + facteur(conte+1)*sol_hom2_hrr(nzm1, k, j, i) ;
01531             
01532         meta.set(nzm1, k, j, i) = sol_part_eta(nzm1, k, j, i)
01533           + facteur(conte)*sol_hom1_eta(nzm1, k, j, i) 
01534           + facteur(conte+1)*sol_hom2_eta(nzm1, k, j, i) ; 
01535             
01536         mw.set(nzm1, k, j, i) = sol_part_w(nzm1, k, j, i)
01537           + facteur(conte)*sol_hom1_w(nzm1, k, j, i) 
01538           + facteur(conte+1)*sol_hom2_w(nzm1, k, j, i) ;
01539       }
01540     }
01541       } // End of nullite_plm  
01542     } //End of loop on theta
01543     
01544      
01545   if (hrr.set_spectral_va().c != 0x0) 
01546     delete hrr.set_spectral_va().c;
01547   hrr.set_spectral_va().c = 0x0 ;
01548   hrr.set_spectral_va().ylm_i() ;
01549     
01550   if (tilde_eta.set_spectral_va().c != 0x0) 
01551     delete tilde_eta.set_spectral_va().c ;
01552   tilde_eta.set_spectral_va().c = 0x0 ;
01553   tilde_eta.set_spectral_va().ylm_i() ;
01554     
01555   if (ww.set_spectral_va().c != 0x0) 
01556     delete ww.set_spectral_va().c ;
01557   ww.set_spectral_va().c = 0x0 ;
01558   ww.set_spectral_va().ylm_i() ;
01559     
01560 }    
01561 
01562 // // On doit resoudre séparément les cas l=0 et l=1; notamment dansces cas le systeme electrique se resout a deux equations
01563 // // au lieu de 3.
01564 
01565     
01566 
01567 
01568 
01569 void Sym_tensor_trans::sol_Dirac_l01_bound(const Scalar& hh, Scalar& hrr, Scalar& tilde_eta, Scalar& bound_hrr, Scalar& bound_eta, Param* par_mat) {
01570   
01571   
01572   
01573   // void Sym_tensor_trans::sol_Dirac_tilde_B2(const Scalar& tilde_b, const Scalar& hh, 
01574   //                      Scalar& hrr, Scalar& tilde_eta, Scalar& ww, Scalar bound_eta,double dir, double neum, double rhor, Param* par_bc, Param* par_mat) {
01575   
01576   
01577   const Map_af* mp_aff = dynamic_cast<const Map_af*>(mp) ;
01578   assert(mp_aff != 0x0) ; //Only affine mapping for the moment
01579   
01580   const Mg3d& mgrid = *mp_aff->get_mg() ;
01581   int nz = mgrid.get_nzone() ;
01582   assert(mgrid.get_type_r(0) == RARE)  ;
01583   assert(mgrid.get_type_r(nz-1) == UNSURR) ;
01584   
01585   if (hh.get_etat() == ETATZERO) {
01586     hrr.annule_hard() ;
01587     tilde_eta.annule_hard() ;
01588     return ;
01589   }
01590   
01591   int nt = mgrid.get_nt(0) ;
01592   int np = mgrid.get_np(0) ;
01593   
01594   Scalar source = hh ;
01595   source.div_r_dzpuis(2) ;
01596   Scalar source_coq = hh ;
01597   source.set_spectral_va().ylm() ;
01598   source_coq.set_spectral_va().ylm() ;
01599   Base_val base = source.get_spectral_base() ;
01600   base.mult_x() ;
01601   int lmax = base.give_lmax(mgrid, 0) + 1;
01602   
01603   assert (hrr.get_spectral_base() == base) ;
01604   assert (tilde_eta.get_spectral_base() == base) ;
01605   assert (hrr.get_spectral_va().c_cf != 0x0) ;
01606   assert (tilde_eta.get_spectral_va().c_cf != 0x0) ;
01607   
01608   Mtbl_cf sol_part_hrr(mgrid, base) ; sol_part_hrr.annule_hard() ;
01609   Mtbl_cf sol_part_eta(mgrid, base) ; sol_part_eta.annule_hard() ;
01610   Mtbl_cf sol_hom1_hrr(mgrid, base) ; sol_hom1_hrr.annule_hard() ;
01611   Mtbl_cf sol_hom1_eta(mgrid, base) ; sol_hom1_eta.annule_hard() ;
01612   Mtbl_cf sol_hom2_hrr(mgrid, base) ; sol_hom2_hrr.annule_hard() ;
01613   Mtbl_cf sol_hom2_eta(mgrid, base) ; sol_hom2_eta.annule_hard() ;
01614   
01615   bool need_calculation = true ;
01616   if (par_mat != 0x0)
01617     if (par_mat->get_n_matrice_mod() > 0) 
01618       if (&par_mat->get_matrice_mod(0) != 0x0) need_calculation = false ;
01619   
01620   int l_q, m_q, base_r ;
01621   Itbl mat_done(lmax) ;
01622   
01623   //---------------
01624   //--  NUCLEUS ---
01625   //---------------
01626   {int lz = 0 ;  
01627   int nr = mgrid.get_nr(lz) ;
01628   double alpha = mp_aff->get_alpha()[lz] ;
01629   Matrice ope(2*nr, 2*nr) ;
01630   if (need_calculation && (par_mat != 0x0)) mat_done.annule_hard() ;
01631   
01632   for (int k=0 ; k<np+1 ; k++) {
01633     for (int j=0 ; j<nt ; j++) {
01634       // quantic numbers and spectral bases
01635       base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
01636       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q < 2)) {
01637     if (need_calculation) {
01638       ope.set_etat_qcq() ;
01639       Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
01640       Diff_sx os(base_r, nr) ; const Matrice& ms = os.get_matrice() ;
01641       
01642       for (int lin=0; lin<nr; lin++) 
01643         for (int col=0; col<nr; col++) 
01644           ope.set(lin,col) = md(lin,col) + 3*ms(lin,col) ;
01645       for (int lin=0; lin<nr; lin++) 
01646         for (int col=0; col<nr; col++) 
01647           ope.set(lin,col+nr) = -l_q*(l_q+1)*ms(lin,col) ;
01648       for (int lin=0; lin<nr; lin++) 
01649         for (int col=0; col<nr; col++) 
01650           ope.set(lin+nr,col) = -0.5*ms(lin,col) ;
01651       for (int lin=0; lin<nr; lin++) 
01652         for (int col=0; col<nr; col++) 
01653           ope.set(lin+nr,col+nr) = md(lin,col) + 3*ms(lin, col);
01654       
01655       ope *= 1./alpha ;
01656       for (int col=0; col<2*nr; col++) {
01657         ope.set(nr-1, col) = 0 ;
01658         ope.set(2*nr-1, col) = 0 ;
01659       }
01660       int pari = 1 ;
01661       if (base_r == R_CHEBP) {
01662         for (int col=0; col<nr; col++) {
01663           ope.set(nr-1, col) = pari ;
01664           ope.set(2*nr-1, col+nr) = pari ;
01665           pari = - pari ;
01666         }
01667       }
01668       else { //In the odd case, the last coefficient must be zero!
01669         ope.set(nr-1, nr-1) = 1 ;
01670         ope.set(2*nr-1, 2*nr-1) = 1 ;
01671       }
01672       
01673       ope.set_lu() ;
01674       if ((par_mat != 0x0) && (mat_done(l_q) == 0)) {
01675         Matrice* pope = new Matrice(ope) ;
01676         par_mat->add_matrice_mod(*pope, lz*lmax + l_q) ;
01677         mat_done.set(l_q) = 1 ;
01678       }
01679     } //End of case when a calculation is needed
01680     
01681     const Matrice& oper = (par_mat == 0x0 ? ope : 
01682                    par_mat->get_matrice_mod(lz*lmax + l_q) ) ;
01683     Tbl sec(2*nr) ;
01684     sec.set_etat_qcq() ;
01685     for (int lin=0; lin<nr; lin++)
01686       sec.set(lin) = (*source.get_spectral_va().c_cf)(lz, k, j, lin) ;
01687     for (int lin=0; lin<nr; lin++)
01688       sec.set(nr+lin) = -0.5*(*source.get_spectral_va().c_cf)
01689         (lz, k, j, lin) ;
01690     sec.set(nr-1) = 0 ;
01691     if (base_r == R_CHEBP) {
01692       double h0 = 0 ; //In the l=0 case:  3*hrr(r=0) = h(r=0) 
01693       int pari = 1 ;
01694       for (int col=0; col<nr; col++) {
01695         h0 += pari*
01696           (*source_coq.get_spectral_va().c_cf)(lz, k, j, col) ;
01697         pari = - pari ;
01698       }
01699       sec.set(nr-1) = h0 / 3. ;
01700     }
01701     sec.set(2*nr-1) = 0 ;
01702     Tbl sol = oper.inverse(sec) ;
01703     for (int i=0; i<nr; i++) {
01704       sol_part_hrr.set(lz, k, j, i) = sol(i) ;
01705       sol_part_eta.set(lz, k, j, i) = sol(i+nr) ;
01706     }
01707     sec.annule_hard() ;
01708       }
01709     }
01710   }
01711   }
01712   
01713   //-------------
01714   // -- Shells --
01715   //-------------
01716   
01717   for (int lz=1; lz<nz-1; lz++) {
01718     if (need_calculation && (par_mat != 0x0)) mat_done.annule_hard() ;
01719     int nr = mgrid.get_nr(lz) ;
01720     int ind0 = 0 ;
01721     int ind1 = nr ;
01722     assert(mgrid.get_nt(lz) == nt) ;
01723     assert(mgrid.get_np(lz) == np) ;
01724     double alpha = mp_aff->get_alpha()[lz] ;
01725     double ech = mp_aff->get_beta()[lz] / alpha ;
01726     Matrice ope(2*nr, 2*nr) ;
01727     
01728     for (int k=0 ; k<np+1 ; k++) {
01729       for (int j=0 ; j<nt ; j++) {
01730     // quantic numbers and spectral bases
01731     base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
01732     if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q < 2)) {
01733       if (need_calculation) {
01734         ope.set_etat_qcq() ;
01735         Diff_xdsdx oxd(base_r, nr) ; const Matrice& mxd = oxd.get_matrice() ;
01736         Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
01737         Diff_id oid(base_r, nr) ; const Matrice& mid = oid.get_matrice() ;
01738         
01739         for (int lin=0; lin<nr; lin++) 
01740           for (int col=0; col<nr; col++) 
01741         ope.set(lin,col) = mxd(lin,col) + ech*md(lin,col) 
01742           + 3*mid(lin,col) ;
01743         for (int lin=0; lin<nr; lin++) 
01744           for (int col=0; col<nr; col++) 
01745         ope.set(lin,col+nr) = -l_q*(l_q+1)*mid(lin,col) ;
01746         for (int lin=0; lin<nr; lin++) 
01747           for (int col=0; col<nr; col++) 
01748         ope.set(lin+nr,col) = -0.5*mid(lin,col) ;
01749         for (int lin=0; lin<nr; lin++) 
01750           for (int col=0; col<nr; col++) 
01751         ope.set(lin+nr,col+nr) = mxd(lin,col) + ech*md(lin,col) 
01752           + 3*mid(lin, col) ;
01753         
01754         for (int col=0; col<2*nr; col++) {
01755           ope.set(ind0+nr-1, col) = 0 ;
01756           ope.set(ind1+nr-1, col) = 0 ;
01757         }
01758         ope.set(ind0+nr-1, ind0) = 1 ;
01759         ope.set(ind1+nr-1, ind1) = 1 ;
01760         
01761         ope.set_lu() ;
01762         if ((par_mat != 0x0) && (mat_done(l_q) == 0)) {
01763           Matrice* pope = new Matrice(ope) ;
01764           par_mat->add_matrice_mod(*pope, lz*lmax + l_q) ;
01765           mat_done.set(l_q) = 1 ;
01766         }
01767       } //End of case when a calculation is needed
01768       const Matrice& oper = (par_mat == 0x0 ? ope : 
01769                  par_mat->get_matrice_mod(lz*lmax + l_q) ) ;
01770       Tbl sec(2*nr) ;
01771       sec.set_etat_qcq() ;
01772       for (int lin=0; lin<nr; lin++)
01773         sec.set(lin) = (*source_coq.get_spectral_va().c_cf)
01774           (lz, k, j, lin) ; 
01775       for (int lin=0; lin<nr; lin++)
01776         sec.set(nr+lin) = -0.5*(*source_coq.get_spectral_va().c_cf)
01777           (lz, k, j, lin) ;
01778       sec.set(ind0+nr-1) = 0 ;
01779       sec.set(ind1+nr-1) = 0 ;
01780       Tbl sol = oper.inverse(sec) ;
01781       
01782       for (int i=0; i<nr; i++) {
01783         sol_part_hrr.set(lz, k, j, i) = sol(i) ;
01784         sol_part_eta.set(lz, k, j, i) = sol(i+nr) ;
01785       }
01786       sec.annule_hard() ;
01787       sec.set(ind0+nr-1) = 1 ;
01788       sol = oper.inverse(sec) ;
01789       for (int i=0; i<nr; i++) {
01790         sol_hom1_hrr.set(lz, k, j, i) = sol(i) ;
01791         sol_hom1_eta.set(lz, k, j, i) = sol(i+nr) ;
01792       }         
01793       sec.set(ind0+nr-1) = 0 ;
01794       sec.set(ind1+nr-1) = 1 ;
01795       sol = oper.inverse(sec) ;
01796       for (int i=0; i<nr; i++) {
01797         sol_hom2_hrr.set(lz, k, j, i) = sol(i) ;
01798         sol_hom2_eta.set(lz, k, j, i) = sol(i+nr) ;
01799       }         
01800     }
01801       }
01802     }
01803   }
01804   
01805   //------------------------------
01806   // Compactified external domain
01807   //------------------------------
01808   {int lz = nz-1 ;  
01809   if (need_calculation && (par_mat != 0x0)) mat_done.annule_hard() ;
01810   int nr = mgrid.get_nr(lz) ;
01811   int ind0 = 0 ;
01812   int ind1 = nr ;
01813   assert(mgrid.get_nt(lz) == nt) ;
01814   assert(mgrid.get_np(lz) == np) ;
01815   double alpha = mp_aff->get_alpha()[lz] ;
01816   Matrice ope(2*nr, 2*nr) ;
01817   
01818   for (int k=0 ; k<np+1 ; k++) {
01819     for (int j=0 ; j<nt ; j++) {
01820       // quantic numbers and spectral bases
01821       base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
01822       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q < 2)) {
01823     if (need_calculation) {
01824       ope.set_etat_qcq() ;
01825       Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
01826       Diff_sx os(base_r, nr) ; const Matrice& ms = os.get_matrice() ;
01827       
01828       for (int lin=0; lin<nr; lin++) 
01829         for (int col=0; col<nr; col++) 
01830           ope.set(lin,col) = - md(lin,col) + 3*ms(lin,col) ;
01831       for (int lin=0; lin<nr; lin++) 
01832         for (int col=0; col<nr; col++) 
01833           ope.set(lin,col+nr) = -l_q*(l_q+1)*ms(lin,col) ;
01834       for (int lin=0; lin<nr; lin++) 
01835         for (int col=0; col<nr; col++) 
01836           ope.set(lin+nr,col) = -0.5*ms(lin,col) ;
01837       for (int lin=0; lin<nr; lin++) 
01838         for (int col=0; col<nr; col++) 
01839           ope.set(lin+nr,col+nr) = -md(lin,col) + 3*ms(lin, col) ;
01840       
01841       ope *= 1./alpha ;
01842       for (int col=0; col<2*nr; col++) {
01843         ope.set(ind0+nr-2, col) = 0 ;
01844         ope.set(ind0+nr-1, col) = 0 ;
01845         ope.set(ind1+nr-2, col) = 0 ;
01846         ope.set(ind1+nr-1, col) = 0 ;
01847       }
01848       for (int col=0; col<nr; col++) {
01849         ope.set(ind0+nr-1, col+ind0) = 1 ;
01850         ope.set(ind1+nr-1, col+ind1) = 1 ;
01851       }
01852       ope.set(ind0+nr-2, ind0+1) = 1 ;
01853       ope.set(ind1+nr-2, ind1+1) = 1 ;
01854       
01855       ope.set_lu() ;
01856       if ((par_mat != 0x0) && (mat_done(l_q) == 0)) {
01857         Matrice* pope = new Matrice(ope) ;
01858         par_mat->add_matrice_mod(*pope, lz*lmax + l_q) ;
01859         mat_done.set(l_q) = 1 ;
01860       }
01861     } //End of case when a calculation is needed
01862     const Matrice& oper = (par_mat == 0x0 ? ope : 
01863                    par_mat->get_matrice_mod(lz*lmax + l_q) ) ;
01864     Tbl sec(2*nr) ;
01865     sec.set_etat_qcq() ;
01866     for (int lin=0; lin<nr; lin++)
01867       sec.set(lin) = (*source.get_spectral_va().c_cf)
01868         (lz, k, j, lin) ;
01869     for (int lin=0; lin<nr; lin++)
01870       sec.set(nr+lin) = -0.5*(*source.get_spectral_va().c_cf)
01871         (lz, k, j, lin) ;
01872     sec.set(ind0+nr-2) = 0 ;
01873     sec.set(ind0+nr-1) = 0 ;
01874     sec.set(ind1+nr-2) = 0 ;
01875     sec.set(ind1+nr-1) = 0 ;
01876     Tbl sol = oper.inverse(sec) ;
01877     for (int i=0; i<nr; i++) {
01878       sol_part_hrr.set(lz, k, j, i) = sol(i) ;
01879       sol_part_eta.set(lz, k, j, i) = sol(i+nr) ;
01880     }
01881     sec.annule_hard() ;
01882     sec.set(ind0+nr-2) = 1 ;
01883     sol = oper.inverse(sec) ;
01884     for (int i=0; i<nr; i++) {
01885       sol_hom1_hrr.set(lz, k, j, i) = sol(i) ;
01886       sol_hom1_eta.set(lz, k, j, i) = sol(i+nr) ;
01887     }
01888     sec.set(ind0+nr-2) = 0 ;
01889     sec.set(ind1+nr-2) = 1 ;
01890     sol = oper.inverse(sec) ;
01891     for (int i=0; i<nr; i++) {
01892       sol_hom2_hrr.set(lz, k, j, i) = sol(i) ;
01893       sol_hom2_eta.set(lz, k, j, i) = sol(i+nr) ;
01894     }
01895       }
01896     }
01897   }
01898   }
01899 
01900   // Matching system
01901 
01902   Mtbl_cf dhom1_hrr = sol_hom1_hrr ; 
01903   Mtbl_cf dhom2_hrr = sol_hom2_hrr ; 
01904   Mtbl_cf dpart_hrr = sol_part_hrr ; 
01905   Mtbl_cf dhom1_eta = sol_hom1_eta ; 
01906   Mtbl_cf dhom2_eta = sol_hom2_eta ; 
01907   Mtbl_cf dpart_eta = sol_part_eta ; 
01908 
01909   dhom1_hrr.dsdx() ; dhom1_eta.dsdx() ;
01910   dhom2_hrr.dsdx() ; dhom2_eta.dsdx() ;
01911   dpart_hrr.dsdx() ; dpart_eta.dsdx() ;
01912 
01913 
01914   
01915   int taille = 2*(nz-1) ;
01916   Mtbl_cf& mhrr = *hrr.set_spectral_va().c_cf ;
01917   Mtbl_cf& meta = *tilde_eta.set_spectral_va().c_cf ;
01918   
01919   Tbl sec_membre(taille) ; 
01920   Matrice systeme(taille, taille) ; 
01921   int ligne ;  int colonne ;
01922   
01923   // Loop on l and m
01924   //----------------
01925   for (int k=0 ; k<np+1 ; k++)
01926     for (int j=0 ; j<nt ; j++) {
01927       base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;
01928       if ((nullite_plm(j, nt, k, np, base) == 1) && (l_q < 2)) {
01929     ligne = 0 ;
01930     colonne = 0 ;
01931     systeme.annule_hard() ;
01932     sec_membre.annule_hard() ;
01933 
01934     int nr;
01935 
01936     //Nucleus 
01937     //  int nr = mgrid.get_nr(0) ;
01938     
01939     sec_membre.set(ligne) = 0.;
01940     ligne++ ;
01941     
01942     sec_membre.set(ligne) = 0.;
01943     
01944     //shell 1
01945     ligne-- ;
01946 
01947     double alpha2 = mp_aff->get_alpha()[1] ;    
01948     double blob =  (*(bound_hrr.get_spectral_va().c_cf)).val_in_bound_jk(1, j, k);  
01949     double blob2 =  (*(bound_eta.get_spectral_va().c_cf)).val_in_bound_jk(1, j, k);    
01950 
01951     // Condition at x= -1
01952     // A robyn condition is imposed on hrr as mirror of what is imposed in tt resolution: "homogeneous" boundary condition 
01953     
01954     systeme.set(ligne, colonne) = - (4. - double(l_q*(l_q+1.)))*sol_hom1_hrr.val_in_bound_jk(1,j,k) - 2.*dhom1_hrr.val_in_bound_jk(1,j,k)/alpha2;
01955       
01956     systeme.set(ligne, colonne +1) =  - (4. - double(l_q*(l_q+1.)))*sol_hom2_hrr.val_in_bound_jk(1,j,k) - 2.*dhom2_hrr.val_in_bound_jk(1,j,k)/alpha2;
01957       
01958     sec_membre.set(ligne) = (4. - double(l_q*(l_q+1.)))*sol_part_hrr.val_in_bound_jk(1,j,k) + 2.*dpart_hrr.val_in_bound_jk(1,j,k)/alpha2 - blob;
01959     ligne++;
01960 
01961     // / A robyn condition is imposed on hrr as mirror of what is imposed in tt resolution: "homogeneous" boundary condition 
01962 
01963     
01964     systeme.set(ligne, colonne) = - ( 2.*dhom1_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1.)))*sol_hom1_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom1_hrr.val_in_bound_jk(1,j,k));
01965       
01966     systeme.set(ligne, colonne +1) =  - ( 2.*dhom2_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1.)))*sol_hom2_eta.val_in_bound_jk(1,j,k) + 2.*sol_hom2_hrr.val_in_bound_jk(1,j,k));
01967       
01968     sec_membre.set(ligne) =  2.*dpart_eta.val_in_bound_jk(1,j,k)/alpha2 + (2.-double(l_q*(l_q+1.)))*sol_part_eta.val_in_bound_jk(1,j,k) + 2.*sol_part_hrr.val_in_bound_jk(1,j,k) - blob2;
01969 
01970     ligne++;
01971   
01972     // Condition at x=1
01973     systeme.set(ligne, colonne) = 
01974       sol_hom1_hrr.val_out_bound_jk(1, j, k) ;
01975     systeme.set(ligne, colonne+1) = 
01976       sol_hom2_hrr.val_out_bound_jk(1, j, k) ;
01977       
01978     sec_membre.set(ligne) -= sol_part_hrr.val_out_bound_jk(1, j, k) ;
01979     ligne++ ;
01980       
01981     systeme.set(ligne, colonne) = 
01982       sol_hom1_eta.val_out_bound_jk(1, j, k) ;
01983     systeme.set(ligne, colonne+1) = 
01984       sol_hom2_eta.val_out_bound_jk(1, j, k) ;
01985       
01986     sec_membre.set(ligne) -= sol_part_eta.val_out_bound_jk(1, j, k) ;
01987       
01988     colonne += 2 ;
01989 
01990     //shells nz>2
01991 
01992     for (int zone=2 ; zone<nz-1 ; zone++) {
01993      nr = mgrid.get_nr(zone) ;
01994       ligne-- ;
01995       
01996       //Condition at x = -1
01997       systeme.set(ligne, colonne) = 
01998         - sol_hom1_hrr.val_in_bound_jk(zone, j, k) ;
01999       systeme.set(ligne, colonne+1) = 
02000         - sol_hom2_hrr.val_in_bound_jk(zone, j, k) ;
02001       
02002       sec_membre.set(ligne) += sol_part_hrr.val_in_bound_jk(zone, j, k) ;
02003       ligne++ ;
02004       
02005       systeme.set(ligne, colonne) = 
02006         - sol_hom1_eta.val_in_bound_jk(zone, j, k) ;
02007       systeme.set(ligne, colonne+1) = 
02008         - sol_hom2_eta.val_in_bound_jk(zone, j, k) ;
02009       
02010       sec_membre.set(ligne) += sol_part_eta.val_in_bound_jk(zone, j, k) ;
02011       ligne++ ;
02012       
02013       // Condition at x=1
02014       systeme.set(ligne, colonne) = 
02015         sol_hom1_hrr.val_out_bound_jk(zone, j, k) ;
02016       systeme.set(ligne, colonne+1) = 
02017         sol_hom2_hrr.val_out_bound_jk(zone, j, k) ;
02018       
02019       sec_membre.set(ligne) -= sol_part_hrr.val_out_bound_jk(zone, j, k) ;
02020       ligne++ ;
02021       
02022       systeme.set(ligne, colonne) = 
02023         sol_hom1_eta.val_out_bound_jk(zone, j, k) ;
02024       systeme.set(ligne, colonne+1) = 
02025         sol_hom2_eta.val_out_bound_jk(zone, j, k) ;
02026       
02027       sec_membre.set(ligne) -= sol_part_eta.val_out_bound_jk(zone, j, k) ;
02028       
02029       colonne += 2 ;
02030     }
02031     
02032     //Compactified external domain
02033     nr = mgrid.get_nr(nz-1) ;
02034     
02035     ligne-- ;
02036     
02037     systeme.set(ligne, colonne) = 
02038       - sol_hom1_hrr.val_in_bound_jk(nz-1, j, k) ;
02039     systeme.set(ligne, colonne+1) = 
02040       - sol_hom2_hrr.val_in_bound_jk(nz-1, j, k) ;
02041     
02042     sec_membre.set(ligne) += sol_part_hrr.val_in_bound_jk(nz-1, j, k) ;
02043     ligne++ ;
02044     
02045     systeme.set(ligne, colonne) = 
02046       - sol_hom1_eta.val_in_bound_jk(nz-1, j, k) ;
02047     systeme.set(ligne, colonne+1) = 
02048       - sol_hom2_eta.val_in_bound_jk(nz-1, j, k) ;
02049     
02050     sec_membre.set(ligne) += sol_part_eta.val_in_bound_jk(nz-1, j, k) ;
02051     
02052     // Solution of the system giving the coefficients for the homogeneous 
02053     // solutions
02054     //-------------------------------------------------------------------
02055     systeme.set_lu() ;
02056     Tbl facteur = systeme.inverse(sec_membre) ;
02057     int conte = 0 ;
02058     
02059     // everything is put to the right place...
02060     //----------------------------------------
02061     nr = mgrid.get_nr(0) ; //nucleus
02062     for (int i=0 ; i<nr ; i++) {
02063       mhrr.set(0, k, j, i) = sol_part_hrr(0, k, j, i) ;
02064       meta.set(0, k, j, i) = sol_part_eta(0, k, j, i) ;
02065     }
02066     for (int zone=1 ; zone<nz-1 ; zone++) { //shells
02067       nr = mgrid.get_nr(zone) ;
02068       for (int i=0 ; i<nr ; i++) {
02069         mhrr.set(zone, k, j, i) = sol_part_hrr(zone, k, j, i)
02070           + facteur(conte)*sol_hom1_hrr(zone, k, j, i) 
02071           + facteur(conte+1)*sol_hom2_hrr(zone, k, j, i) ;
02072         
02073         meta.set(zone, k, j, i) = sol_part_eta(zone, k, j, i)
02074           + facteur(conte)*sol_hom1_eta(zone, k, j, i) 
02075           + facteur(conte+1)*sol_hom2_eta(zone, k, j, i) ;
02076       }
02077       conte+=2 ;
02078     }
02079     nr = mgrid.get_nr(nz-1) ; //compactified external domain
02080     for (int i=0 ; i<nr ; i++) {
02081       mhrr.set(nz-1, k, j, i) = sol_part_hrr(nz-1, k, j, i)
02082         + facteur(conte)*sol_hom1_hrr(nz-1, k, j, i) 
02083         + facteur(conte+1)*sol_hom2_hrr(nz-1, k, j, i) ;
02084       
02085       meta.set(nz-1, k, j, i) = sol_part_eta(nz-1, k, j, i)
02086         + facteur(conte)*sol_hom1_eta(nz-1, k, j, i) 
02087         + facteur(conte+1)*sol_hom2_eta(nz-1, k, j, i) ;
02088     }
02089     
02090       } // End of nullite_plm  
02091     } //End of loop on theta
02092 }

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