vector_poisson_boundary.C

00001 /*
00002  *  Method for vector Poisson equation inverting eqs. for V^r and eta as a block
00003  *  (with a boundary condition on the excised sphere).
00004  *
00005  *    (see file vector.h for documentation).
00006  *
00007  */
00008 
00009 /*
00010  *   Copyright (c) 2005  Jerome Novak
00011  *                       Francois Limousin
00012  *                       Jose Luis Jaramillo
00013  *
00014  *   This file is part of LORENE.
00015  *
00016  *   LORENE is free software; you can redistribute it and/or modify
00017  *   it under the terms of the GNU General Public License version 2
00018  *   as published by the Free Software Foundation.
00019  *
00020  *   LORENE is distributed in the hope that it will be useful,
00021  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *   GNU General Public License for more details.
00024  *
00025  *   You should have received a copy of the GNU General Public License
00026  *   along with LORENE; if not, write to the Free Software
00027  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  */
00030 
00031 char vector_poisson_boundary_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/vector_poisson_boundary.C,v 1.1 2005/06/09 08:00:09 f_limousin Exp $" ;
00032 
00033 /*
00034  * $Id: vector_poisson_boundary.C,v 1.1 2005/06/09 08:00:09 f_limousin Exp $
00035  * $Log: vector_poisson_boundary.C,v $
00036  * Revision 1.1  2005/06/09 08:00:09  f_limousin
00037  * Implement a new function sol_elliptic_boundary() and
00038  * Vector::poisson_boundary(...) which solve the vectorial poisson
00039  * equation (method 6) with an inner boundary condition.
00040  *
00041  *
00042  * $Header: /cvsroot/Lorene/C++/Source/Tensor/vector_poisson_boundary.C,v 1.1 2005/06/09 08:00:09 f_limousin Exp $
00043  *
00044  */
00045 
00046 // C headers
00047 #include <assert.h>
00048 #include <stdlib.h>
00049 #include <math.h>
00050 
00051 // Lorene headers
00052 #include "metric.h"
00053 #include "diff.h"
00054 #include "param_elliptic.h"
00055 #include "proto.h"
00056 #include "utilitaires.h"
00057 
00058 void Vector::poisson_boundary(double lam, const Mtbl_cf& bound_vr, 
00059                 const Mtbl_cf& bound_eta, const Mtbl_cf& bound_mu, 
00060                   int num_front, double fact_dir, double fact_neu, 
00061                   Vector& resu) const {
00062 
00063   const Map_af* mpaff = dynamic_cast<const Map_af*>(mp) ;
00064 #ifndef NDEBUG 
00065   for (int i=0; i<3; i++)
00066     assert(cmp[i]->check_dzpuis(4)) ;
00067   // All this has a meaning only for spherical components:
00068   const Base_vect_spher* bvs = dynamic_cast<const Base_vect_spher*>(triad) ;
00069   assert(bvs != 0x0) ; 
00070   //## ... and affine mapping, for the moment!
00071   assert( mpaff != 0x0) ;
00072 #endif
00073 
00074   if (fabs(lam + 1.) < 1.e-8) {
00075     cout << "Not implemented yet !!" << endl ;
00076     abort() ;
00077     /*
00078       const Metric_flat& mets = mp->flat_met_spher() ;
00079       Vector_divfree sou(*mp, *triad, mets) ;
00080       for (int i=1; i<=3; i++) sou.set(i) = *cmp[i-1] ;
00081       resu = sou.poisson() ;
00082       return ;
00083     */
00084   }
00085 
00086   // Some working objects
00087   //---------------------
00088   const Mg3d& mg = *mpaff->get_mg() ;
00089   int nz = mg.get_nzone() ; int nzm1 = nz - 1;
00090   assert(mg.get_type_r(nzm1) == UNSURR) ;
00091   Scalar S_r = *cmp[0] ;
00092   if (S_r.get_etat() == ETATZERO) S_r.annule_hard() ;
00093   Scalar S_eta = eta() ;
00094   if (S_eta.get_etat() == ETATZERO) S_eta.annule_hard() ;
00095   S_r.set_spectral_va().ylm() ;
00096   S_eta.set_spectral_va().ylm() ;
00097   const Base_val& base = S_eta.get_spectral_va().base ;
00098   Mtbl_cf sol_part_eta(mg, base) ; sol_part_eta.annule_hard() ;
00099   Mtbl_cf sol_part_vr(mg, base) ; sol_part_vr.annule_hard() ;
00100   Mtbl_cf solution_hom_un(mg, base) ; solution_hom_un.annule_hard() ;
00101   Mtbl_cf solution_hom_deux(mg, base) ; solution_hom_deux.annule_hard() ;
00102   Mtbl_cf solution_hom_trois(mg, base) ; solution_hom_trois.annule_hard() ;
00103   Mtbl_cf solution_hom_quatre(mg, base) ; solution_hom_quatre.annule_hard() ;
00104 
00105 
00106   // The l_0 component is solved independently   // Understand this step 
00107   //------------------------------------------
00108   Scalar sou_l0 = (*cmp[0]) / (1. + lam) ;
00109   Param_elliptic param_l0(sou_l0) ;
00110   for (int l=0; l<nz; l++)
00111     param_l0.set_poisson_vect_r(l, true) ;
00112  
00113   //  Scalar vrl0 = sou_l0.sol_elliptic(param_l0) ;
00114   Scalar vrl0 = sou_l0.sol_elliptic_boundary(param_l0, bound_vr, fact_dir, fact_neu) ;
00115 
00116   // Build-up & inversion of the system for (eta, V^r) in each domain
00117   //-----------------------------------------------------------------
00118 
00119   // Shells
00120   //-------
00121 
00122   int nr ;
00123   int nt = mg.get_nt(0) ;
00124   int np = mg.get_np(0) ;
00125   int l_q = 0 ; int m_q = 0; int base_r = 0 ;
00126   double alpha, beta, ech ;
00127 
00128   assert(num_front+1 < nzm1) ; // Minimum one shell
00129   for (int zone=num_front+1 ; zone<nzm1 ; zone++) {                 //begins the loop on zones
00130       nr = mg.get_nr(zone) ;
00131       alpha = mpaff->get_alpha()[zone] ;
00132       beta = mpaff->get_beta()[zone] ;
00133       ech = beta / alpha ;
00134       assert (nr > 5) ;
00135       assert(nt == mg.get_nt(zone)) ;
00136       assert(np == mg.get_np(zone)) ;
00137 
00138       // Loop on l and m
00139       //----------------
00140       for (int k=0 ; k<np+1 ; k++) {
00141     for (int j=0 ; j<nt ; j++) {
00142       base.give_quant_numbers(zone, k, j, m_q, l_q, base_r) ;
00143       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q != 0) ) {
00144         int dege1 = 2 ; //degeneracy of eq.1
00145         int dege2 = 2 ;  //degeneracy of eq.2
00146         int nr_eq1 = nr - dege1 ; //Eq.1 is for eta
00147         int nr_eq2 = nr - dege2 ; //Eq.2 is for V^r
00148         int nrtot = nr_eq1 + nr_eq2 ;
00149         Matrice oper(nrtot, nrtot) ; oper.set_etat_qcq() ;
00150         Tbl sec_membre(nrtot) ; sec_membre.set_etat_qcq() ;
00151         Diff_x2dsdx2 x2d2(base_r, nr); const Matrice& m2d2 = x2d2.get_matrice() ;
00152         Diff_xdsdx2 xd2(base_r, nr) ; const Matrice& mxd2 = xd2.get_matrice() ;
00153         Diff_dsdx2 d2(base_r, nr) ; const Matrice& md2 = d2.get_matrice() ;
00154         Diff_xdsdx xd(base_r, nr) ; const Matrice& mxd = xd.get_matrice() ;
00155         Diff_dsdx d1(base_r, nr) ; const Matrice& md = d1.get_matrice() ;
00156         Diff_id id(base_r, nr) ; const Matrice& mid = id.get_matrice() ;
00157 
00158         // Building the operator   // Which is the eq. from the notes that it is actually implemented?  
00159         //----------------------
00160         for (int lin=0; lin<nr_eq1; lin++) { 
00161           for (int col=dege1; col<nr; col++) 
00162         oper.set(lin,col-dege1) 
00163           = m2d2(lin,col) + 2*ech*mxd2(lin,col) + ech*ech*md2(lin,col) 
00164           + 2*(mxd(lin,col) + ech*md(lin,col)) 
00165           - (lam+1)*l_q*(l_q+1)*mid(lin,col) ;
00166           for (int col=dege2; col<nr; col++) 
00167         oper.set(lin,col-dege2+nr_eq1) 
00168           = lam*(mxd(lin,col) + ech*md(lin,col)) + 2*(1+lam)*mid(lin,col) ; 
00169         }
00170         for (int lin=0; lin<nr_eq2; lin++) {
00171           for (int col=dege1; col<nr; col++)
00172         oper.set(lin+nr_eq1,col-dege1) 
00173           = -l_q*(l_q+1)*(lam*(mxd(lin,col) + ech*md(lin,col))
00174                   - (lam+2)*mid(lin,col)) ;
00175           for (int col=dege2; col<nr; col++)
00176         oper.set(lin+nr_eq1, col-dege2+nr_eq1) 
00177           = (lam+1)*(m2d2(lin,col) + 2*ech*mxd2(lin,col) 
00178                  + ech*ech*md2(lin,col) 
00179                  + 2*(mxd(lin,col) + ech*md(lin,col)))
00180           -(2*(lam+1)+l_q*(l_q+1))*mid(lin,col) ;
00181         }
00182         oper.set_lu() ;
00183           
00184         // Filling the r.h.s
00185         //------------------
00186         Tbl sr(nr) ; sr.set_etat_qcq() ; 
00187         Tbl seta(nr) ; seta.set_etat_qcq() ;
00188         for (int i=0; i<nr; i++) {
00189           sr.set(i) = (*S_r.get_spectral_va().c_cf)(zone, k, j, i);
00190           seta.set(i) = (*S_eta.get_spectral_va().c_cf)(zone, k, j, i) ;
00191         }
00192         Tbl xsr= sr ;  Tbl x2sr= sr ;
00193         Tbl xseta= seta ; Tbl x2seta = seta ;
00194         multx2_1d(nr, &x2sr.t, base_r) ; multx_1d(nr, &xsr.t, base_r) ;
00195         multx2_1d(nr, &x2seta.t, base_r) ; multx_1d(nr, &xseta.t, base_r) ;
00196           
00197         for (int i=0; i<nr_eq1; i++) 
00198           sec_membre.set(i) = alpha*(alpha*x2seta(i) + 2*beta*xseta(i))
00199         + beta*beta*seta(i);
00200         for (int i=0; i<nr_eq2; i++)
00201           sec_membre.set(i+nr_eq1) = beta*beta*sr(i) 
00202         + alpha*(alpha*x2sr(i) + 2*beta*xsr(i)) ;
00203 
00204         // Inversion of the "big" operator
00205         //--------------------------------
00206         Tbl big_res = oper.inverse(sec_membre) ;
00207         Tbl res_eta(nr) ;    res_eta.set_etat_qcq() ;
00208         Tbl res_vr(nr) ;  res_vr.set_etat_qcq() ;
00209           
00210         // Putting coefficients of h and v to individual arrays
00211         //-----------------------------------------------------
00212         for (int i=0; i<dege1; i++)
00213           res_eta.set(i) = 0 ;
00214         for (int i=dege1; i<nr; i++)
00215           res_eta.set(i) = big_res(i-dege1) ;
00216         for (int i=0; i<dege2; i++)
00217           res_vr.set(i) = 0 ;
00218         for (int i=dege2; i<nr; i++)
00219           res_vr.set(i) = big_res(i-dege2+nr_eq1) ;
00220 
00221         //homogeneous solutions    //I do not understand!!! 
00222         Tbl sol_hom1 = solh(nr, l_q-1, ech, base_r) ;
00223         Tbl sol_hom2 = solh(nr, l_q+1, ech, base_r) ;
00224         for (int i=0 ; i<nr ; i++) {
00225           sol_part_eta.set(zone, k, j, i) = res_eta(i) ;
00226           sol_part_vr.set(zone, k, j, i) = res_vr(i) ;
00227           solution_hom_un.set(zone, k, j, i) = sol_hom1(0,i) ;
00228           solution_hom_deux.set(zone, k, j, i) = sol_hom2(1,i) ;
00229           solution_hom_trois.set(zone, k, j, i) = sol_hom2(0,i) ;
00230           solution_hom_quatre.set(zone, k, j, i) = sol_hom1(1,i) ;
00231         }
00232       } 
00233     }
00234       }
00235     }
00236 
00237   // Compactified external domain
00238   //-----------------------------
00239   nr = mg.get_nr(nzm1) ;
00240   assert(nt == mg.get_nt(nzm1)) ;
00241   assert(np == mg.get_np(nzm1)) ;
00242   alpha = mpaff->get_alpha()[nzm1] ;
00243   assert (nr > 4) ;
00244   int nr0 = nr - 2 ;  //two degrees of freedom less because of division by u^2
00245 
00246   // Loop on l and m
00247   //----------------
00248   for (int k=0 ; k<np+1 ; k++) {
00249     for (int j=0 ; j<nt ; j++) { 
00250       base.give_quant_numbers(nzm1, k, j, m_q, l_q, base_r) ;
00251       if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q != 0) ) {
00252     int dege1 = 1; //degeneracy of eq.1
00253     int dege2 = 0; //degeneracy of eq.2
00254     int nr_eq1 = nr0 - dege1 ; //Eq.1 is for eta
00255     int nr_eq2 = nr0 - dege2 ; //Eq.2 is the div-free condition
00256     int nrtot = nr_eq1 + nr_eq2 ;
00257     Matrice oper(nrtot, nrtot) ; oper.set_etat_qcq() ;
00258     Tbl sec_membre(nrtot) ; sec_membre.set_etat_qcq() ;
00259     Diff_x2dsdx2 x2d2(base_r, nr) ; const Matrice& m2d2 = x2d2.get_matrice() ;
00260     Diff_xdsdx xd(base_r, nr) ; const Matrice& mxd = xd.get_matrice() ;
00261     Diff_id id(base_r, nr) ; const Matrice& mid = id.get_matrice() ;
00262 
00263     // Building the operator
00264     //----------------------
00265     for (int lin=0; lin<nr_eq1; lin++) { 
00266       for (int col=dege1; col<nr0; col++) 
00267         oper.set(lin,col-dege1) 
00268           = m2d2(lin,col) + 4*mxd(lin,col) 
00269           + (2-(lam+1)*l_q*(l_q+1))*mid(lin,col) ;
00270       for (int col=dege2; col<nr0; col++) 
00271         oper.set(lin,col-dege2+nr_eq1) = 
00272           -lam*mxd(lin,col) + 2*mid(lin,col) ;
00273     }
00274     for (int lin=0; lin<nr_eq2; lin++) {
00275       for (int col=dege1; col<nr0; col++)
00276         oper.set(lin+nr_eq1,col-dege1) 
00277           = l_q*(l_q+1)*(lam*mxd(lin,col) + (3*lam+2)*mid(lin,col)) ;
00278       for (int col=dege2; col<nr0; col++)
00279         oper.set(lin+nr_eq1, col-dege2+nr_eq1) 
00280           = (lam+1)*(m2d2(lin,col) + 4*mxd(lin,col)) 
00281           - l_q*(l_q+1)*mid(lin,col) ;
00282     }
00283     oper.set_lu() ;
00284           
00285     // Filling the r.h.s
00286     //------------------
00287     for (int i=0; i<nr_eq1; i++) 
00288       sec_membre.set(i) = (*S_eta.get_spectral_va().c_cf)(nzm1, k, j, i) ;
00289     for (int i=0; i<nr_eq2; i++)
00290       sec_membre.set(i+nr_eq1) =(*S_r.get_spectral_va().c_cf)(nzm1, k, j, i);
00291     Tbl big_res = oper.inverse(sec_membre) ;
00292     Tbl res_eta(nr) ;    res_eta.set_etat_qcq() ;
00293     Tbl res_vr(nr) ;  res_vr.set_etat_qcq() ;
00294           
00295     // Putting coefficients of h and v to individual arrays
00296     //-----------------------------------------------------
00297     for (int i=0; i<dege1; i++)
00298       res_eta.set(i) = 0 ;
00299     for (int i=dege1; i<nr0; i++)
00300       res_eta.set(i) = big_res(i-dege1) ;
00301     res_eta.set(nr0) = 0 ;
00302     res_eta.set(nr0+1) = 0 ;
00303     for (int i=0; i<dege2; i++)
00304       res_vr.set(i) = 0 ;
00305     for (int i=dege2; i<nr0; i++)
00306       res_vr.set(i) = big_res(i-dege2+nr_eq1) ;
00307     res_vr.set(nr0) = 0 ;
00308     res_vr.set(nr0+1) = 0 ;
00309 
00310     // Multiplication by u^2 
00311     //-----------------------
00312     Tbl res_v2(nr) ;  res_v2.set_etat_qcq() ;
00313     Tbl res_e2(nr) ; res_e2.set_etat_qcq() ;
00314     mult2_xm1_1d_cheb(nr, res_eta.t, res_e2.t) ; 
00315     mult2_xm1_1d_cheb(nr, res_vr.t, res_v2.t) ; 
00316 
00317     // Homogeneous solution (only 1/r^(l+2) and 1/r^l in the CED)
00318     Tbl sol_hom1 = solh(nr, l_q-1, 0., base_r) ;
00319     Tbl sol_hom2 = solh(nr, l_q+1, 0., base_r) ;
00320     for (int i=0 ; i<nr ; i++) {
00321       sol_part_eta.set(nzm1, k, j, i) = alpha*alpha*res_e2(i) ;
00322       sol_part_vr.set(nzm1, k, j, i) = alpha*alpha*res_v2(i) ;
00323       solution_hom_un.set(nzm1, k, j, i) = 0. ;
00324       solution_hom_deux.set(nzm1, k, j, i) = sol_hom2(i) ;
00325       solution_hom_trois.set(nzm1, k, j, i) = 0. ;
00326       solution_hom_quatre.set(nzm1, k, j, i) = sol_hom1(i) ;
00327     }
00328       }     
00329     }
00330   }
00331 
00332   // Now let's match everything ...
00333   //-------------------------------
00334 
00335   // Resulting V^r & eta
00336   Scalar vr(*mpaff) ; vr.set_etat_qcq() ;
00337   vr.set_spectral_base(base) ;
00338   vr.set_spectral_va().set_etat_cf_qcq() ;
00339   Mtbl_cf& cf_vr = *vr.set_spectral_va().c_cf ;
00340   cf_vr.annule_hard() ;
00341   Scalar het(*mpaff) ; het.set_etat_qcq() ;
00342   het.set_spectral_base(base) ;
00343   het.set_spectral_va().set_etat_cf_qcq() ;
00344   Mtbl_cf& cf_eta = *het.set_spectral_va().c_cf ;
00345   cf_eta.annule_hard() ;
00346   int taille = 4*(nzm1-num_front)-2  ; //## a verifier
00347   Tbl sec_membre(taille) ; 
00348   Matrice systeme(taille, taille) ; 
00349   systeme.set_etat_qcq() ;
00350   int ligne ;  int colonne ;
00351   
00352   // Loop on l and m
00353   //----------------
00354   for (int k=0 ; k<np+1 ; k++)
00355     for (int j=0 ; j<nt ; j++) {
00356       base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;
00357       if ((nullite_plm(j, nt, k, np, base) == 1)&&(l_q != 0)) {
00358         
00359     double f3_eta = lam*l_q + 3*lam + 2 ;
00360     double f4_eta = 2 + 2*lam - lam*l_q ;
00361     double f3_vr = (l_q+1)*(lam*l_q - 2) ;
00362     double f4_vr = l_q*(lam*l_q + lam + 2) ;
00363     ligne = 0 ;
00364     colonne = 0 ;
00365     sec_membre.annule_hard() ;
00366     for (int l=0; l<taille; l++) 
00367       for (int c=0; c<taille; c++)
00368         systeme.set(l,c) = 0 ;
00369 
00370     // First shell
00371     nr = mg.get_nr(num_front+1) ;
00372     alpha = mpaff->get_alpha()[num_front+1] ;
00373     double echelle = mpaff->get_beta()[num_front+1]/alpha ;
00374     // Conditions on eta (configuration space)
00375     //value and derivative of (x+echelle)^(l-1) at -1 
00376     systeme.set(ligne, colonne) = pow(echelle-1., double(l_q-1)) ;
00377      
00378     // value and derivative of 1/(x+echelle) ^(l+2) at -1 
00379     systeme.set(ligne, colonne+1) = 1/pow(echelle-1., double(l_q+2)) ;
00380 
00381     //value and derivative of (x+echelle)^(l+1) at -1 
00382     systeme.set(ligne, colonne+2) = f3_eta*pow(echelle-1., double(l_q+1))  ;
00383     // value and derivative of 1/(x+echelle) ^l at -1 
00384     systeme.set(ligne, colonne+3) = f4_eta/pow(echelle-1., double(l_q))  ;
00385     for (int i=0 ; i<nr ; i++)
00386       if (i%2 == 0)
00387         sec_membre.set(ligne) -= sol_part_eta(num_front+1, k, j, i) ;
00388       else sec_membre.set(ligne) += sol_part_eta(num_front+1, k, j, i) ;
00389     sec_membre.set(ligne) += bound_eta(num_front+1, k, j, 0) ;
00390     ligne++ ;
00391 
00392     // ... and their couterparts for V^r
00393     systeme.set(ligne, colonne) = fact_dir*l_q*pow(echelle-1., double(l_q-1)) + fact_neu*l_q*(l_q-1)*pow(echelle-1., double(l_q-2))/alpha ;
00394     systeme.set(ligne, colonne+1) = -fact_dir*(l_q+1)/pow(echelle-1., double(l_q+2)) + fact_neu*(l_q+1)*(l_q+2)/pow(echelle-1., double(l_q+3))/alpha ;
00395     systeme.set(ligne, colonne+2) = fact_dir*f3_vr*pow(echelle-1., double(l_q+1)) + fact_neu*f3_vr*(l_q+1)*pow(echelle-1., double(l_q))/alpha ;
00396     systeme.set(ligne, colonne+3) = fact_dir*f4_vr/pow(echelle-1., double(l_q)) - fact_neu*(f4_vr*l_q/pow(echelle-1., double(l_q+1)))/alpha ;
00397     for (int i=0 ; i<nr ; i++)
00398       if (i%2 == 0)
00399         sec_membre.set(ligne) -= fact_dir*sol_part_vr(num_front+1, k, j, i) - fact_neu*i*i/alpha*sol_part_vr(num_front+1, k, j, i) ;
00400       else sec_membre.set(ligne) += fact_dir*sol_part_vr(num_front+1, k, j, i) - fact_neu*i*i/alpha*sol_part_vr(num_front+1, k, j, i)  ;
00401     sec_membre.set(ligne) += bound_vr(num_front+1, k, j, 0) ;
00402     
00403     ligne++ ;
00404     
00405 
00406     // Values at 1
00407     // eta
00408     //value of (x+echelle)^(l-1) at 1 
00409     systeme.set(ligne, colonne) = pow(echelle+1., double(l_q-1)) ;
00410     // value of 1/(x+echelle) ^(l+2) at 1 
00411     systeme.set(ligne, colonne+1) = 1./pow(echelle+1., double(l_q+2)) ;
00412     //value of (x+echelle)^(l+1) at 1 
00413     systeme.set(ligne, colonne+2) = f3_eta*pow(echelle+1., double(l_q+1));
00414     // value of 1/(x+echelle) ^l at 1 
00415     systeme.set(ligne, colonne+3) = f4_eta/pow(echelle+1., double(l_q)) ;
00416     for (int i=0 ; i<nr ; i++)
00417       sec_membre.set(ligne) -= sol_part_eta(num_front+1, k, j, i) ;
00418     ligne++ ;
00419     // ... and their couterparts for V^r
00420     systeme.set(ligne, colonne) = l_q*pow(echelle+1., double(l_q-1)) ;
00421     systeme.set(ligne, colonne+1) 
00422       = -double(l_q+1) / pow(echelle+1., double(l_q+2));
00423     systeme.set(ligne, colonne+2) = f3_vr*pow(echelle+1., double(l_q+1)) ;
00424     systeme.set(ligne, colonne+3) = f4_vr/pow(echelle+1., double(l_q));
00425     for (int i=0 ; i<nr ; i++)
00426       sec_membre.set(ligne) -= sol_part_vr(num_front+1, k, j, i) ;
00427     ligne++ ;
00428           
00429     //Derivatives at 1
00430     // eta
00431     //derivative of (x+echelle)^(l-1) at 1 
00432     systeme.set(ligne, colonne) 
00433       = (l_q-1) * pow(echelle+1., double(l_q-2))/alpha ;
00434     // derivative of 1/(x+echelle) ^(l+2) at 1 
00435     systeme.set(ligne, colonne+1) 
00436       = -(l_q+2) / pow(echelle+1., double(l_q+3))/alpha ;
00437     // derivative of (x+echelle)^(l+1) at 1 
00438     systeme.set(ligne, colonne+2) 
00439       = f3_eta*(l_q+1) * pow(echelle+1., double(l_q))/alpha;
00440     // derivative of 1/(x+echelle) ^l at 1 
00441     systeme.set(ligne, colonne+3) 
00442       = -f4_eta*l_q / pow(echelle+1., double(l_q+1))/alpha ;
00443     for (int i=0 ; i<nr ; i++)
00444       sec_membre.set(ligne) -= i*i/alpha*sol_part_eta(num_front+1, k, j, i) ;
00445     ligne++ ;
00446     // ... and their couterparts for V^r
00447     systeme.set(ligne, colonne) 
00448       = l_q*(l_q-1) * pow(echelle+1., double(l_q-2))/alpha ;
00449     systeme.set(ligne, colonne+1) 
00450       = (l_q+1)*(l_q+2) / pow(echelle+1., double(l_q+3))/alpha ;
00451     systeme.set(ligne, colonne+2) 
00452       = f3_vr*(l_q+1) * pow(echelle+1., double(l_q))/alpha ;
00453     systeme.set(ligne, colonne+3) 
00454       = -f4_vr*l_q / pow(echelle+1., double(l_q+1))/alpha ;
00455     for (int i=0 ; i<nr ; i++)
00456       sec_membre.set(ligne) -= i*i/alpha*sol_part_vr(num_front+1, k, j, i) ;
00457           
00458     colonne += 4 ; // We pass to the next domain
00459             
00460       
00461     // Next shells
00462     if (num_front+2<nzm1){
00463       for (int zone=num_front+2 ; zone<nzm1 ; zone++) {
00464         nr = mg.get_nr(zone) ;
00465         alpha = mpaff->get_alpha()[zone] ;
00466         echelle = mpaff->get_beta()[zone]/alpha ;
00467         ligne -= 3 ;
00468         //value of (x+echelle)^(l-1) at -1 
00469         systeme.set(ligne, colonne) = -pow(echelle-1., double(l_q-1)) ;  
00470         // value of 1/(x+echelle) ^(l+2) at -1 
00471         systeme.set(ligne, colonne+1) = -1/pow(echelle-1., double(l_q+2)) ;
00472         //value of (x+echelle)^(l+1) at -1 
00473         systeme.set(ligne, colonne+2) = -f3_eta*pow(echelle-1., double(l_q+1));
00474         // value of 1/(x+echelle) ^l at -1 
00475         systeme.set(ligne, colonne+3) = -f4_eta/pow(echelle-1., double(l_q)) ;
00476         for (int i=0 ; i<nr ; i++)
00477           if (i%2 == 0)
00478         sec_membre.set(ligne) += sol_part_eta(zone, k, j, i) ;
00479           else sec_membre.set(ligne) -= sol_part_eta(zone, k, j, i) ;
00480         ligne++ ;
00481         // ... and their couterparts for V^r
00482         systeme.set(ligne, colonne) = -l_q*pow(echelle-1., double(l_q-1)) ;
00483         systeme.set(ligne, colonne+1) = (l_q+1)/pow(echelle-1., double(l_q+2));
00484         systeme.set(ligne, colonne+2) = -f3_vr*pow(echelle-1., double(l_q+1)) ;
00485         systeme.set(ligne, colonne+3) = -f4_vr/pow(echelle-1., double(l_q));
00486         for (int i=0 ; i<nr ; i++)
00487           if (i%2 == 0)
00488         sec_membre.set(ligne) += sol_part_vr(zone, k, j, i) ;
00489           else sec_membre.set(ligne) -= sol_part_vr(zone, k, j, i) ;
00490         ligne++ ;
00491 
00492         //derivative of (x+echelle)^(l-1) at -1 
00493         systeme.set(ligne, colonne) 
00494           = -(l_q-1)*pow(echelle-1., double(l_q-2))/alpha ;
00495         // derivative of 1/(x+echelle) ^(l+2) at -1 
00496         systeme.set(ligne, colonne+1) 
00497           = (l_q+2)/pow(echelle-1., double(l_q+3))/alpha ;
00498         // derivative of (x+echelle)^(l+1) at -1 
00499         systeme.set(ligne, colonne+2) 
00500           = -f3_eta*(l_q+1)*pow(echelle-1., double(l_q))/alpha;
00501         // derivative of 1/(x+echelle) ^l at -1 
00502         systeme.set(ligne, colonne+3) 
00503           = (f4_eta*l_q/pow(echelle-1., double(l_q+1)))/alpha ;
00504         for (int i=0 ; i<nr ; i++)
00505           if (i%2 == 0) sec_membre.set(ligne) 
00506                   -= i*i/alpha*sol_part_eta(zone, k, j, i) ;    
00507           else sec_membre.set(ligne) +=
00508              i*i/alpha*sol_part_eta(zone, k, j, i) ;
00509         ligne++ ;
00510         // ... and their couterparts for V^r
00511         systeme.set(ligne, colonne) 
00512           = -l_q*(l_q-1)*pow(echelle-1., double(l_q-2))/alpha ;
00513         systeme.set(ligne, colonne+1) 
00514           = -(l_q+1)*(l_q+2)/pow(echelle-1., double(l_q+3))/alpha ;
00515         systeme.set(ligne, colonne+2) 
00516           = -f3_vr*(l_q+1)*pow(echelle-1., double(l_q))/alpha ;
00517         systeme.set(ligne, colonne+3) 
00518           = (f4_vr*l_q/pow(echelle-1., double(l_q+1)))/alpha ;
00519         for (int i=0 ; i<nr ; i++)
00520           if (i%2 == 0) sec_membre.set(ligne) 
00521                   -= i*i/alpha*sol_part_vr(zone, k, j, i) ;
00522           else sec_membre.set(ligne) +=
00523              i*i/alpha*sol_part_vr(zone, k, j, i) ;
00524         ligne++ ;
00525             
00526         //value of (x+echelle)^(l-1) at 1 
00527         systeme.set(ligne, colonne) = pow(echelle+1., double(l_q-1)) ;
00528         // value of 1/(x+echelle) ^(l+2) at 1 
00529         systeme.set(ligne, colonne+1) = 1./pow(echelle+1., double(l_q+2)) ;
00530         //value of (x+echelle)^(l+1) at 1 
00531         systeme.set(ligne, colonne+2) = f3_eta*pow(echelle+1., double(l_q+1));
00532         // value of 1/(x+echelle) ^l at 1 
00533         systeme.set(ligne, colonne+3) = f4_eta/pow(echelle+1., double(l_q)) ;
00534         for (int i=0 ; i<nr ; i++)
00535           sec_membre.set(ligne) -= sol_part_eta(zone, k, j, i) ;
00536         ligne++ ;
00537         // ... and their couterparts for V^r
00538         systeme.set(ligne, colonne) = l_q*pow(echelle+1., double(l_q-1)) ;
00539         systeme.set(ligne, colonne+1) 
00540           = -double(l_q+1) / pow(echelle+1., double(l_q+2));
00541         systeme.set(ligne, colonne+2) = f3_vr*pow(echelle+1., double(l_q+1)) ;
00542         systeme.set(ligne, colonne+3) = f4_vr/pow(echelle+1., double(l_q));
00543         for (int i=0 ; i<nr ; i++)
00544           sec_membre.set(ligne) -= sol_part_vr(zone, k, j, i) ;
00545         ligne++ ;
00546 
00547         //derivative of (x+echelle)^(l-1) at 1 
00548         systeme.set(ligne, colonne) 
00549           = (l_q-1) * pow(echelle+1., double(l_q-2))/alpha ;
00550         // derivative of 1/(x+echelle) ^(l+2) at 1 
00551         systeme.set(ligne, colonne+1) 
00552           = -(l_q+2) / pow(echelle+1., double(l_q+3))/alpha ;
00553         // derivative of (x+echelle)^(l+1) at 1 
00554         systeme.set(ligne, colonne+2) 
00555           = f3_eta*(l_q+1) * pow(echelle+1., double(l_q))/alpha;
00556         // derivative of 1/(x+echelle) ^l at 1 
00557         systeme.set(ligne, colonne+3) 
00558           = -f4_eta*l_q / pow(echelle+1., double(l_q+1))/alpha ;
00559         for (int i=0 ; i<nr ; i++)
00560           sec_membre.set(ligne) -= i*i/alpha*sol_part_eta(zone, k, j, i) ;
00561         ligne++ ;
00562         // ... and their couterparts for V^r
00563         systeme.set(ligne, colonne) 
00564           = l_q*(l_q-1) * pow(echelle+1., double(l_q-2))/alpha ;
00565         systeme.set(ligne, colonne+1) 
00566           = (l_q+1)*(l_q+2) / pow(echelle+1., double(l_q+3))/alpha ;
00567         systeme.set(ligne, colonne+2) 
00568           = f3_vr*(l_q+1) * pow(echelle+1., double(l_q))/alpha ;
00569         systeme.set(ligne, colonne+3) 
00570           = -f4_vr*l_q / pow(echelle+1., double(l_q+1))/alpha ;
00571         for (int i=0 ; i<nr ; i++)
00572           sec_membre.set(ligne) -= i*i/alpha*sol_part_vr(zone, k, j, i) ;
00573 
00574         colonne += 4 ;
00575       }         
00576     }
00577     //Compactified external domain
00578     nr = mg.get_nr(nzm1) ;
00579 
00580     alpha = mpaff->get_alpha()[nzm1] ;
00581     ligne -= 3 ;
00582     //value of (x-1)^(l+2) at -1 :
00583     systeme.set(ligne, colonne) = -pow(-2, double(l_q+2)) ;
00584     //value of (x-1)^l at -1 :
00585     systeme.set(ligne, colonne+1) = -f4_eta*pow(-2, double(l_q)) ;
00586     for (int i=0 ; i<nr ; i++)
00587       if (i%2 == 0) sec_membre.set(ligne) += sol_part_eta(nzm1, k, j, i) ;
00588       else sec_membre.set(ligne) -= sol_part_eta(nzm1, k, j, i) ;
00589     //... and of its couterpart for V^r
00590     systeme.set(ligne+1, colonne) = double(l_q+1)*pow(-2, double(l_q+2)) ;
00591     systeme.set(ligne+1, colonne+1) = -f4_vr*pow(-2, double(l_q)) ;
00592     for (int i=0 ; i<nr ; i++)
00593       if (i%2 == 0) sec_membre.set(ligne+1) += sol_part_vr(nzm1, k, j, i) ;
00594       else sec_membre.set(ligne+1) -= sol_part_vr(nzm1, k, j, i) ;
00595             
00596     ligne += 2 ;
00597     //derivative of (x-1)^(l+2) at -1 :
00598     systeme.set(ligne, colonne) = alpha*(l_q+2)*pow(-2, double(l_q+3)) ;
00599     //derivative of (x-1)^l at -1 :
00600     systeme.set(ligne, colonne+1) = alpha*l_q*f4_eta*pow(-2, double(l_q+1)) ;
00601     for (int i=0 ; i<nr ; i++)
00602       if (i%2 == 0) sec_membre.set(ligne) 
00603               -= -4*alpha*i*i*sol_part_eta(nzm1, k, j, i) ;
00604       else sec_membre.set(ligne) 
00605          += -4*alpha*i*i*sol_part_eta(nzm1, k, j, i) ;
00606     //... and of its couterpart for V^r
00607     systeme.set(ligne+1, colonne) 
00608       = -alpha*double((l_q+1)*(l_q+2))*pow(-2, double(l_q+3)) ;
00609     systeme.set(ligne+1, colonne+1) 
00610       = alpha*double(l_q)*f4_vr*pow(-2, double(l_q+1)) ;
00611     for (int i=0 ; i<nr ; i++)
00612       if (i%2 == 0) sec_membre.set(ligne+1) 
00613               -= -4*alpha*i*i*sol_part_vr(nzm1, k, j, i) ;
00614       else sec_membre.set(ligne+1) 
00615          += -4*alpha*i*i*sol_part_vr(nzm1, k, j, i) ;
00616             
00617     // Solution of the system giving the coefficients for the homogeneous 
00618     // solutions
00619     //-------------------------------------------------------------------
00620     if (taille > 2) systeme.set_band(5,5) ;
00621     else systeme.set_band(1,1) ;
00622     systeme.set_lu() ;
00623     Tbl facteurs(systeme.inverse(sec_membre)) ;
00624     int conte = 0 ;
00625 
00626     // everything is put to the right place, the same combination of hom.
00627     // solutions (with some l or -(l+1) factors) must be used for V^r
00628     //-------------------------------------------------------------------
00629 
00630     for (int zone=1 ; zone<nzm1 ; zone++) { //shells
00631       nr = mg.get_nr(zone) ;
00632       for (int i=0 ; i<nr ; i++) {
00633         cf_eta.set(zone, k, j, i) = 
00634           sol_part_eta(zone, k, j, i)
00635           +facteurs(conte)*solution_hom_un(zone, k, j, i) 
00636           +facteurs(conte+1)*solution_hom_deux(zone, k, j, i) 
00637           +facteurs(conte+2)*f3_eta*solution_hom_trois(zone, k, j, i) 
00638           +facteurs(conte+3)*f4_eta*solution_hom_quatre(zone, k, j, i) ;
00639         cf_vr.set(zone, k, j, i) = sol_part_vr(zone, k, j, i)
00640           +double(l_q)*facteurs(conte)*solution_hom_un(zone, k, j, i) 
00641           -double(l_q+1)*facteurs(conte+1)*solution_hom_deux(zone, k, j, i)    // What is the origin of these factors?!
00642           +f3_vr*facteurs(conte+2)*solution_hom_trois(zone, k, j, i) 
00643           +f4_vr*facteurs(conte+3)*solution_hom_quatre(zone, k, j, i) ;
00644       }
00645       conte+=4 ;
00646     }
00647     nr = mg.get_nr(nz-1) ; //compactified external domain
00648     for (int i=0 ; i<nr ; i++) {
00649       cf_eta.set(nzm1, k, j, i) = sol_part_eta(nzm1, k, j, i)
00650         +facteurs(conte)*solution_hom_deux(nzm1, k, j, i) 
00651         +f4_eta*facteurs(conte+1)*solution_hom_quatre(nzm1, k, j, i) ;
00652       cf_vr.set(nzm1, k, j, i) = sol_part_vr(nzm1, k, j, i)
00653         -double(l_q+1)*facteurs(conte)*solution_hom_deux(nzm1, k, j, i) 
00654         +f4_vr*facteurs(conte+1)*solution_hom_quatre(nzm1, k, j, i) ;
00655 
00656     }
00657       } // End of nullite_plm  
00658     } //End of loop on theta
00659   vr.set_spectral_va().ylm_i() ;
00660   vr += vrl0 ;
00661   het.set_spectral_va().ylm_i() ;
00662   
00663   Valeur temp_mu(mg.get_angu())  ;
00664   temp_mu = bound_mu ;
00665   const Valeur& limit_mu (temp_mu) ;
00666 
00667   resu.set_vr_eta_mu(vr, 0*het, mu().poisson_dirichlet(limit_mu, num_front)) ;
00668 
00669   return ; 
00670 }
00671 
00672 
00673 Vector Vector::poisson_dirichlet(double lam, const Valeur& bound_vr, 
00674                    const Valeur& bound_vt, const Valeur& bound_vp,
00675                    int num_front) const {
00676 
00677   Vector resu(*mp, CON, triad) ;
00678   resu = poisson_robin(lam, bound_vr, bound_vt, bound_vp, 1., 0., num_front) ;
00679 
00680   return resu ;
00681 
00682 }
00683 
00684 Vector Vector::poisson_neumann(double lam, const Valeur& bound_vr, 
00685                    const Valeur& bound_vt, const Valeur& bound_vp,
00686                    int num_front) const {
00687 
00688   Vector resu(*mp, CON, triad) ;
00689   resu = poisson_robin(lam, bound_vr, bound_vt, bound_vp, 0., 1., num_front) ;
00690 
00691   return resu ;
00692 
00693 }
00694 
00695 Vector Vector::poisson_robin(double lam, const Valeur& bound_vr, 
00696                  const Valeur& bound_vt, const Valeur& bound_vp,
00697                  double fact_dir, double fact_neu, 
00698                  int num_front) const {
00699  
00700  
00701   // Boundary condition for V^r    //Construction of a Mtbl_cf from Valeur with Ylm coefficients
00702   Valeur limit_vr (bound_vr) ; 
00703 
00704   limit_vr.coef() ;
00705   limit_vr.ylm() ; // Spherical harmonics transform.
00706   Mtbl_cf lim_vr (*(limit_vr.c_cf)) ;
00707 
00708   // bound_vt and bound_vp are only known at the boundary --> we fill 
00709   // all the zones extending the values at the boundary before calling to poisson_angu.
00710   Scalar temp_vt (*mp) ;
00711   Scalar temp_vp (*mp) ;
00712   temp_vt.annule_hard() ;
00713   temp_vp.annule_hard() ;
00714   int nz = mp->get_mg()->get_nzone() ;
00715   for (int l=0; l<nz; l++)
00716       for (int j=0; j<mp->get_mg()->get_nt(l); j++)
00717       for (int k=0; k<mp->get_mg()->get_np(l); k++) {
00718           temp_vt.set_grid_point(l, k, j, 0) = bound_vt(1, k, j, 0) ;
00719           temp_vp.set_grid_point(l, k, j, 0) = bound_vp(1, k, j, 0) ;
00720     }
00721   temp_vt.set_spectral_va().set_base(bound_vt.base) ;     // We set the basis
00722   temp_vp.set_spectral_va().set_base(bound_vp.base) ;
00723 
00724   cout << "temp_vp" << endl << norme(temp_vp) << endl ;
00725 
00726   //Source for eta
00727   Scalar source_eta(*mp) ;
00728   Scalar vtstant (temp_vt) ;
00729   vtstant.div_tant() ;
00730   source_eta = temp_vt.dsdt() + vtstant + temp_vp.stdsdp() ;
00731 
00732   //Source for mu
00733   Scalar source_mu(*mp) ;
00734   Scalar vpstant (temp_vp) ;
00735   vpstant.div_tant() ;
00736   source_mu = temp_vp.dsdt() + vpstant - temp_vt.stdsdp() ;    //There was a wrong sign here
00737 
00738   Scalar temp_mu (source_mu.poisson_angu()) ;
00739   Scalar temp_eta (source_eta.poisson_angu()) ;
00740 
00741   // Boundary condition for mu
00742   Valeur limit_mu ((*mp).get_mg()->get_angu() )  ;
00743   int nnp = (*mp).get_mg()->get_np(1) ;
00744   int nnt = (*mp).get_mg()->get_nt(1) ;
00745   limit_mu= 1 ;
00746   for (int k=0 ; k<nnp ; k++)
00747     for (int j=0 ; j<nnt ; j++)
00748       limit_mu.set(1, k, j, 0) = temp_mu.val_grid_point(1, k, j, 0) ;
00749   limit_mu.set_base(temp_mu.get_spectral_va().get_base()) ;
00750 
00751   limit_mu.coef() ;
00752   limit_mu.ylm() ; // Spherical harmonics transform.
00753   Mtbl_cf lim_mu (*(limit_mu.c_cf)) ;
00754 
00755   // Boundary condition for eta
00756   Valeur limit_eta ((*mp).get_mg()->get_angu() )  ;
00757   limit_eta = 1 ;
00758   for (int k=0 ; k<nnp ; k++)
00759     for (int j=0 ; j<nnt ; j++)
00760       limit_eta.set(1, k, j, 0) = temp_eta.val_grid_point(1, k, j, 0) ;
00761   limit_eta.set_base(temp_eta.get_spectral_va().get_base()) ;
00762 
00763   limit_eta.coef() ;
00764   limit_eta.ylm() ; // Spherical harmonics transform.
00765   Mtbl_cf lim_eta (*(limit_eta.c_cf)) ;
00766 
00767 
00768   // Call to poisson_boundary(...)
00769   bool nullite = true ;
00770   for (int i=0; i<3; i++) {
00771     assert(cmp[i]->check_dzpuis(4)) ;
00772     if (cmp[i]->get_etat() != ETATZERO || bound_vr.get_etat() != ETATZERO || 
00773     bound_vt.get_etat() != ETATZERO || bound_vp.get_etat() != ETATZERO) 
00774       nullite = false ;
00775   }
00776   
00777   Vector resu(*mp, CON, triad) ;
00778   if (nullite)
00779     resu.set_etat_zero() ;
00780   else 
00781     poisson_boundary(lam, lim_vr, lim_eta, lim_mu, num_front, fact_dir, 
00782              fact_neu, resu) ;
00783 
00784   return resu ;
00785 
00786 }

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