map_et_poisson2d.C

00001 /*
00002  * Method of the class Map_et for the resolution of the 2-D Poisson
00003  *  equation.
00004  *
00005  * (see file map.h for documentation).
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2000-2001 Eric Gourgoulhon
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 as published by
00015  *   the Free Software Foundation; either version 2 of the License, or
00016  *   (at your option) any later version.
00017  *
00018  *   LORENE is distributed in the hope that it will be useful,
00019  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  *   GNU General Public License for more details.
00022  *
00023  *   You should have received a copy of the GNU General Public License
00024  *   along with LORENE; if not, write to the Free Software
00025  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  */
00028 
00029 
00030 char map_et_poisson2d_C[] = "$Header: /cvsroot/Lorene/C++/Source/Map/map_et_poisson2d.C,v 1.2 2002/02/07 14:55:58 e_gourgoulhon Exp $" ;
00031 
00032 /*
00033  * $Id: map_et_poisson2d.C,v 1.2 2002/02/07 14:55:58 e_gourgoulhon Exp $
00034  * $Log: map_et_poisson2d.C,v $
00035  * Revision 1.2  2002/02/07 14:55:58  e_gourgoulhon
00036  * Corrected a bug when the source is known only in the coefficient
00037  * space.
00038  *
00039  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00040  * LORENE
00041  *
00042  * Revision 2.4  2000/11/07  14:21:03  eric
00043  * Correction d'une erreur dans le cas T_SIN_I (calcul de R(u)).
00044  *
00045  * Revision 2.3  2000/10/26  15:58:00  eric
00046  * Correction cas T_COS_P : l'import de saff_q se fait par copie du Tbl.
00047  *
00048  * Revision 2.2  2000/10/12  15:37:43  eric
00049  * Traitement des bases spectrales dans le cas T_COS_P.
00050  *
00051  * Revision 2.1  2000/10/11  15:15:43  eric
00052  * 1ere version operationnelle.
00053  *
00054  * Revision 2.0  2000/10/09  13:47:17  eric
00055  * *** empty log message ***
00056  *
00057  *
00058  * $Header: /cvsroot/Lorene/C++/Source/Map/map_et_poisson2d.C,v 1.2 2002/02/07 14:55:58 e_gourgoulhon Exp $
00059  *
00060  */
00061 
00062 // Headers C
00063 #include <math.h>
00064 
00065 // Headers Lorene:
00066 #include "map.h"
00067 #include "cmp.h"
00068 #include "param.h"
00069 
00070 //*****************************************************************************
00071 
00072 void Map_et::poisson2d(const Cmp& source_mat, const Cmp& source_quad, 
00073                Param& par, Cmp& uu) const {
00074     
00075     assert(source_mat.get_etat() != ETATNONDEF) ; 
00076     assert(source_quad.get_etat() != ETATNONDEF) ; 
00077     assert(source_mat.get_mp()->get_mg() == mg) ; 
00078     assert(source_quad.get_mp()->get_mg() == mg) ; 
00079     assert(uu.get_mp()->get_mg() == mg) ; 
00080 
00081     assert( source_quad.check_dzpuis(4) ) ; 
00082     
00083     double& lambda = par.get_double_mod(0) ; 
00084     int nz = mg->get_nzone() ; 
00085     int nzm1 = nz-1 ; 
00086 
00087     // Special case of a vanishing source 
00088     // ----------------------------------
00089 
00090     if (    (source_mat.get_etat() == ETATZERO) 
00091      && (source_quad.get_etat() == ETATZERO) ) {
00092     
00093     uu = 0 ; 
00094     lambda = 1 ; 
00095     return ; 
00096     }
00097 
00098     int base_t = ((source_mat.va).base).get_base_t(0) ; 
00099 
00100     switch (base_t) {
00101     
00102     //==================================================================
00103     //      case T_COS_P
00104     //==================================================================
00105 
00106     case T_COS_P : {
00107 
00108     // Construction of a Map_af which coincides with *this on the equator
00109     // ------------------------------------------------------------------
00110     
00111     double theta0 = M_PI / 2 ;      // Equator
00112     double phi0 = 0 ; 
00113 
00114     Map_af mpaff(*this) ; 
00115 
00116     for (int l=0 ; l<nz ; l++) {
00117     double rmax = val_r(l, double(1), theta0, phi0) ;
00118     switch ( mg->get_type_r(l) ) {
00119         case RARE:  {
00120         double rmin = val_r(l, double(0), theta0, phi0) ;
00121         mpaff.set_alpha(rmax - rmin, l) ;
00122         mpaff.set_beta(rmin, l) ;
00123         break ; 
00124         }
00125         
00126         case FIN:   {
00127         double rmin = val_r(l, double(-1), theta0, phi0) ;
00128         mpaff.set_alpha( double(.5) * (rmax - rmin), l ) ;
00129         mpaff.set_beta( double(.5) * (rmax + rmin), l) ;
00130         break ;
00131         }
00132         
00133         case UNSURR: {
00134         double rmin = val_r(l, double(-1), theta0, phi0) ;
00135         double umax = double(1) / rmin ;
00136         double umin = double(1) / rmax ;
00137         mpaff.set_alpha( double(.5) * (umin - umax),  l) ; 
00138         mpaff.set_beta( double(.5) * (umin + umax), l) ; 
00139         break ;
00140         }
00141         
00142         default: {
00143         cout << "Map_et::poisson2d: unknown type_r ! " << endl ;
00144         abort () ;
00145         break ;
00146         }
00147         
00148     }
00149     }
00150 
00151     // Importation of source_mat and source_quad of the affine mapping
00152     // ---------------------------------------------------------------
00153     Cmp saff_m(mpaff) ; 
00154     saff_m.import( nzm1, source_mat ) ; 
00155     (saff_m.va).set_base( (source_mat.va).base ) ; 
00156     
00157     Cmp saff_q(mpaff) ; 
00158     
00159     // In order to use Cmp::import with dzpuis != 0 :
00160     Cmp set_q = source_quad ; 
00161     set_q.set_dzpuis(0) ;   // dzpuis artificially set to 0
00162 
00163     saff_q.import( nzm1, set_q ) ; 
00164     (saff_q.va).set_base( (set_q.va).base ) ; 
00165 
00166     // Copy in the external domain :
00167     if ( (set_q.va).get_etat() == ETATQCQ) {
00168         (set_q.va).coef_i() ; // the values in configuration space are required
00169         assert(   (set_q.va).c->get_etat() == ETATQCQ ) ;
00170         assert(  (saff_q.va).c->get_etat() == ETATQCQ ) ;
00171     *( (saff_q.va).c->t[nzm1] ) = *( (set_q.va).c->t[nzm1] ) ;
00172     }
00173 
00174     // the true dzpuis is restored : 
00175     saff_q.set_dzpuis( source_quad.get_dzpuis() ) ; 
00176 
00177     // Resolution of the 2-D Poisson equation on the spherical domains
00178     // ---------------------------------------------------------------
00179     
00180     Cmp uaff(mpaff) ; 
00181     
00182     mpaff.poisson2d(saff_m, saff_q, par, uaff) ;
00183     
00184     // Importation of the solution on the Map_et mapping *this
00185     // -------------------------------------------------------
00186     
00187     uu.import(uaff) ; 
00188     
00189     uu.va.set_base( uaff.va.base ) ;    // same spectral bases 
00190     
00191     break ;
00192     }
00193     
00194     //==================================================================
00195     //      case T_SIN_I
00196     //==================================================================
00197 
00198     case T_SIN_I : {
00199          
00200     //-------------------------------
00201     // Computation of the prefactor a  ---> Cmp apre
00202     //-------------------------------
00203 
00204     Mtbl unjj = 1 + srdrdt*srdrdt  ;
00205 
00206     Mtbl apre1(*mg) ; 
00207     apre1.set_etat_qcq() ; 
00208     for (int l=0; l<nz; l++) {
00209     *(apre1.t[l]) = alpha[l]*alpha[l] ; 
00210     }
00211 
00212     apre1 = apre1 * dxdr * dxdr * unjj ;
00213 
00214     Cmp apre(*this) ; 
00215     apre = apre1 ; 
00216     
00217     Tbl amax0 = max(apre1) ;    // maximum values in each domain
00218 
00219     // The maximum values of a in each domain are put in a Mtbl
00220     Mtbl amax1(*mg) ; 
00221     amax1.set_etat_qcq() ; 
00222     for (int l=0; l<nz; l++) {
00223     *(amax1.t[l]) = amax0(l) ; 
00224     }
00225 
00226     Cmp amax(*this) ; 
00227     amax = amax1 ; 
00228 
00229     
00230     //-------------------
00231     //  Initializations 
00232     //-------------------
00233     
00234     int nitermax = par.get_int() ; 
00235     int& niter = par.get_int_mod() ; 
00236     double lambda_relax = par.get_double() ; 
00237     double unmlambda_relax = 1. - lambda_relax ; 
00238     double precis = par.get_double(1) ;     
00239     
00240     Cmp& ssj = par.get_cmp_mod() ; 
00241     
00242     Cmp ssjm1 = ssj ; 
00243     Cmp ssjm2 = ssjm1 ; 
00244 
00245     Cmp ssj_q(*this) ;
00246     ssj_q = 0 ;  
00247     
00248     Valeur& vuu = uu.va ; 
00249 
00250     Valeur vuujm1(*mg) ;
00251     if (uu.get_etat() == ETATZERO) {
00252     vuujm1 = 1 ;    // to take relative differences
00253     vuujm1.set_base( vuu.base ) ; 
00254     }
00255     else{
00256     vuujm1 = vuu ; 
00257     }
00258     
00259     // Affine mapping for the Laplacian-tilde
00260 
00261     Map_af mpaff(*this) ; 
00262 
00263     cout << "Map_et::poisson2d : relat. diff. u^J <-> u^{J-1} : " << endl ;
00264     
00265 //==========================================================================
00266 //==========================================================================
00267 //              Start of iteration 
00268 //==========================================================================
00269 //==========================================================================
00270 
00271     Tbl tdiff(nz) ; 
00272     double diff ; 
00273     niter = 0 ; 
00274     
00275     do {
00276 
00277     //====================================================================
00278     //      Computation of R(u)    (the result is put in uu)
00279     //====================================================================
00280 
00281 
00282     //-----------------------
00283     // First operations on uu
00284     //-----------------------
00285     
00286     Valeur duudx = (uu.va).dsdx() ;     // d/dx 
00287 
00288     const Valeur& d2uudtdx = duudx.dsdt() ;     // d^2/dxdtheta
00289 
00290     //-------------------
00291     // 1/x d^2uu/dtheta^2
00292     //-------------------
00293     
00294     Valeur sxlapang = uu.va ; 
00295 
00296     sxlapang = sxlapang.d2sdt2() ;    
00297     
00298     sxlapang = sxlapang.sx() ;    //  d^2(uu)/dth^2 /x      in the nucleus
00299                   //  d^2(uu)/dth^2         in the shells
00300                   //  d^2(uu)/dth^2 /(x-1)  in the ZEC
00301     
00302     //---------------------------------------------------------------
00303     //  Computation of 
00304     // [ (dR/dx)^{-1} ( A - 1 ) duu/dx + 1/R (B - 1) d^2uu/dth^2 ] / x
00305     //
00306     // with A = 1/(dRdx) R/(x+beta_l/alpha_l) unjj 
00307     //      B = [1/(dRdx) R/(x+beta_l/alpha_l)]^2 unjj 
00308     // 
00309     //  The result is put in uu (via vuu)
00310     //---------------------------------------------------------------
00311 
00312     // Intermediate quantity jac which value is
00313     //     (dR/dx)^{-1}   in the nucleus and the shells
00314     //     +(dU/dx)^{-1}  in the ZEC
00315 
00316     Mtbl jac = dxdr ; 
00317     if (mg->get_type_r(nzm1) == UNSURR) {
00318     jac.annule(nzm1, nzm1) ; 
00319     Mtbl jac_ext = dxdr ; 
00320     jac_ext.annule(0, nzm1-1) ;
00321     jac_ext = - jac_ext ; 
00322     jac = jac + jac_ext ; 
00323     }
00324 
00325     uu.set_etat_qcq() ; 
00326     
00327     Base_val sauve_base = duudx.base ; 
00328     
00329     vuu = jac * ( rsxdxdr * unjj - 1.) * duudx 
00330         + ( rsxdxdr*rsxdxdr * unjj - 1.) * xsr * sxlapang ; 
00331 
00332     vuu.set_base(sauve_base) ; 
00333 
00334     vuu = vuu.sx() ; 
00335 
00336     //---------------------------------------
00337     // Computation of  R(u)  
00338     //
00339     //  The result is put in uu (via vuu)
00340     //---------------------------------------
00341 
00342 
00343     sauve_base = vuu.base ; 
00344 
00345     vuu =  xsr * vuu 
00346         + 2. * dxdr * sr2drdt * d2uudtdx  ;
00347 
00348     vuu += dxdr * ( sr2d2rdt2 + dxdr * ( 
00349         dxdr* unjj * d2rdx2 
00350         - 2. * sr2drdt * d2rdtdx  ) 
00351                  ) * duudx ;            
00352 
00353     vuu.set_base(sauve_base) ; 
00354 
00355     // Since the assignment is performed on vuu (uu.va), the treatment
00356     //  of uu.dzpuis must be performed by hand:
00357     
00358     uu.set_dzpuis(4) ; 
00359 
00360     //====================================================================
00361     //   Computation of the effective source s^J of the ``affine''
00362     //     Poisson equation 
00363     //====================================================================
00364     
00365     ssj = lambda_relax * ssjm1 + unmlambda_relax * ssjm2 ; 
00366     
00367     ssj = ( source_mat + source_quad + uu + (amax - apre) * ssj ) / amax ; 
00368 
00369     (ssj.va).set_base((source_mat.va).base) ; 
00370     
00371     //====================================================================
00372     //   Resolution of the ``affine'' Poisson equation 
00373     //====================================================================
00374     
00375     assert( uu.check_dzpuis( ssj.get_dzpuis() ) ) ; 
00376                                        
00377     mpaff.poisson2d(ssj, ssj_q, par, uu) ; 
00378 
00379     tdiff = diffrel(vuu, vuujm1) ; 
00380 
00381     diff = max(tdiff) ;
00382     
00383 
00384     cout << "  step " << niter << " :  " ; 
00385     for (int l=0; l<nz; l++) {
00386     cout << tdiff(l) << "  " ;  
00387     }
00388     cout << endl ; 
00389 
00390     //=================================
00391     //  Updates for the next iteration
00392     //=================================
00393     
00394     ssjm2 = ssjm1 ; 
00395     ssjm1 = ssj ; 
00396     vuujm1 = vuu ; 
00397     
00398     niter++ ; 
00399     
00400     }   // End of iteration 
00401     while ( (diff > precis) && (niter < nitermax) ) ;
00402     
00403 //==========================================================================
00404 //==========================================================================
00405 //              End of iteration 
00406 //==========================================================================
00407 //==========================================================================
00408     
00409 
00410     break ; 
00411     }
00412     
00413     default : {
00414         cout << "Map_et::poisson2d : unkown theta basis !" << endl ; 
00415         cout << "  basis : " << hex << base_t << endl ; 
00416         abort() ; 
00417         break ; 
00418     }
00419     }   // End of switch on base_t
00420 }
00421 
00422 

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