map_et_poisson_regu.C

00001 /*
00002  * Method of the class Map_et for the (iterative) resolution of the scalar
00003  *  Poisson equation by using regularized source.
00004  *
00005  * (see file map.h for the documentation).
00006  *
00007  */
00008 
00009 /*
00010  *   Copyright (c) 2000-2001 Keisuke Taniguchi
00011  *
00012  *   This file is part of LORENE.
00013  *
00014  *   LORENE is free software; you can redistribute it and/or modify
00015  *   it under the terms of the GNU General Public License as published by
00016  *   the Free Software Foundation; either version 2 of the License, or
00017  *   (at your option) any later version.
00018  *
00019  *   LORENE is distributed in the hope that it will be useful,
00020  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *   GNU General Public License for more details.
00023  *
00024  *   You should have received a copy of the GNU General Public License
00025  *   along with LORENE; if not, write to the Free Software
00026  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  *
00028  */
00029 
00030 
00031 char map_et_poisson_regu_C[] = "$Header: /cvsroot/Lorene/C++/Source/Map/map_et_poisson_regu.C,v 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon Exp $" ;
00032 
00033 /*
00034  * $Id: map_et_poisson_regu.C,v 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon Exp $
00035  * $Log: map_et_poisson_regu.C,v $
00036  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00037  * LORENE
00038  *
00039  * Revision 2.8  2000/09/27  14:07:14  keisuke
00040  * Traitement des bases spectrales de d_logn_auto_div.
00041  *
00042  * Revision 2.7  2000/09/26  15:41:20  keisuke
00043  * Correction erreur: la triade de duu_div doit etre celle de *this et
00044  *  non celle de l'objet temporaire mpaff.
00045  *
00046  * Revision 2.6  2000/09/25  15:03:34  keisuke
00047  * Correct the derivative duu_div.
00048  *
00049  * Revision 2.5  2000/09/11  14:00:20  keisuke
00050  * Suppress "uu = uu_regu + uu_div" because of double setting (in poisson_regular).
00051  *
00052  * Revision 2.4  2000/09/07  15:51:29  keisuke
00053  * Minor change.
00054  *
00055  * Revision 2.3  2000/09/07  15:30:07  keisuke
00056  * Add a new argument Cmp& uu.
00057  *
00058  * Revision 2.2  2000/09/04  15:56:15  keisuke
00059  * Change the argumant Cmp& duu_div_r into Tenseur& duu_div.
00060  *
00061  * Revision 2.1  2000/09/04  14:52:17  keisuke
00062  * Change the scheme of code into that of map_et_poisson.C.
00063  *
00064  * Revision 2.0  2000/09/01  09:55:33  keisuke
00065  * *** empty log message ***
00066  *
00067  *
00068  * $Header: /cvsroot/Lorene/C++/Source/Map/map_et_poisson_regu.C,v 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon Exp $
00069  *
00070  */
00071 
00072 // Header Lorene:
00073 #include "map.h"
00074 #include "cmp.h"
00075 #include "tenseur.h"
00076 #include "param.h"
00077 
00078 //*****************************************************************************
00079 
00080 void Map_et::poisson_regular(const Cmp& source, int k_div, int nzet,
00081                  double unsgam1, Param& par, Cmp& uu,
00082                  Cmp& uu_regu, Cmp& uu_div, Tenseur& duu_div,
00083                  Cmp& source_regu, Cmp& source_div) const {
00084 
00085 
00086     assert(source.get_etat() != ETATNONDEF) ; 
00087     assert(source.get_mp() == this) ;
00088 
00089     assert( source.check_dzpuis(2) || source.check_dzpuis(4)
00090         || source.check_dzpuis(3)) ;
00091 
00092     assert(uu.get_mp() == this) ; 
00093     assert(uu.check_dzpuis(0)) ; 
00094 
00095     int nz = mg->get_nzone() ;
00096     int nzm1 = nz - 1 ;
00097 
00098     // Indicator of existence of a compactified external domain
00099     bool zec = false ;
00100     if (mg->get_type_r(nzm1) == UNSURR) {
00101     zec = true ;
00102     }
00103 
00104     //-------------------------------
00105     // Computation of the prefactor a  ---> Cmp apre
00106     //-------------------------------
00107 
00108     Mtbl unjj = 1 + srdrdt*srdrdt + srstdrdp*srstdrdp ;
00109 
00110     Mtbl apre1(*mg) ;
00111     apre1.set_etat_qcq() ;
00112     for (int l=0; l<nz; l++) {
00113       *(apre1.t[l]) = alpha[l]*alpha[l] ;
00114     }
00115 
00116     apre1 = apre1 * dxdr * dxdr * unjj ;
00117 
00118     Cmp apre(*this) ;
00119     apre = apre1 ;
00120     
00121     Tbl amax0 = max(apre1) ;    // maximum values in each domain
00122 
00123     // The maximum values of a in each domain are put in a Mtbl
00124     Mtbl amax1(*mg) ;
00125     amax1.set_etat_qcq() ;
00126     for (int l=0; l<nz; l++) {
00127       *(amax1.t[l]) = amax0(l) ;
00128     }
00129 
00130     Cmp amax(*this) ;
00131     amax = amax1 ;
00132 
00133     //-------------------
00134     //  Initializations
00135     //-------------------
00136 
00137     int nitermax = par.get_int() ;
00138     int& niter = par.get_int_mod() ;
00139     double lambda = par.get_double() ;
00140     double unmlambda = 1. - lambda ;
00141     double precis = par.get_double(1) ;
00142 
00143     Cmp& ssj = par.get_cmp_mod() ;
00144 
00145     Cmp ssjm1 = ssj ;
00146     Cmp ssjm2 = ssjm1 ;
00147 
00148     Valeur& vuu = uu.va ;
00149 
00150     Valeur vuujm1(*mg) ;
00151     if (uu.get_etat() == ETATZERO) {
00152     vuujm1 = 1 ;    // to take relative differences
00153     vuujm1.set_base( vuu.base ) ;
00154     }
00155     else{
00156     vuujm1 = vuu ;
00157     }
00158 
00159     // Affine mapping for the Laplacian-tilde
00160 
00161     Map_af mpaff(*this) ;
00162     Param par_nul ;
00163 
00164     cout << "Map_et::poisson_regular : relat. diff. u^J <-> u^{J-1} : "
00165      << endl ;
00166 
00167 //==========================================================================
00168 //==========================================================================
00169 //              Start of iteration
00170 //==========================================================================
00171 //==========================================================================
00172 
00173     Tbl tdiff(nz) ;
00174     double diff ;
00175     niter = 0 ;
00176 
00177     do {
00178 
00179     //====================================================================
00180     //      Computation of R(u)    (the result is put in uu)
00181     //====================================================================
00182 
00183 
00184     //------------------------
00185     // First operations on uu
00186     //------------------------
00187 
00188     Valeur duudx = (uu.va).dsdx() ;     // d/dx
00189 
00190     const Valeur& d2uudtdx = duudx.dsdt() ;     // d^2/dxdtheta
00191 
00192     const Valeur& std2uudpdx = duudx.stdsdp() ;    // 1/sin(theta) d^2/dxdphi
00193 
00194 
00195     //------------------
00196     // Angular Laplacian
00197     //------------------
00198 
00199     Valeur sxlapang = uu.va ;
00200 
00201     sxlapang.ylm() ;
00202 
00203     sxlapang = sxlapang.lapang() ;
00204 
00205     sxlapang = sxlapang.sx() ;    //  Lap_ang(uu) /x      in the nucleus
00206                   //  Lap_ang(uu)         in the shells
00207                   //  Lap_ang(uu) /(x-1)  in the ZEC
00208 
00209     //------------------------------------------------------------------
00210     //  Computation of
00211     // [ 2 /(dRdx) ( A - 1 ) duu/dx + 1/R (B - 1) Lap_ang(uu) ] / x
00212     //
00213     // with A = 1/(dRdx) R/(x+beta_l/alpha_l) unjj
00214     //      B = [1/(dRdx) R/(x+beta_l/alpha_l)]^2 unjj
00215     //
00216     //  The result is put in uu (via vuu)
00217     //------------------------------------------------------------------
00218 
00219     Valeur varduudx = duudx ;
00220 
00221     if (zec) {
00222     varduudx.annule(nzm1) ;     // term in d/dx set to zero in the ZEC
00223     }
00224 
00225     uu.set_etat_qcq() ;
00226 
00227     Base_val sauve_base = varduudx.base ;
00228 
00229     vuu = 2. * dxdr * ( rsxdxdr * unjj - 1.) * varduudx
00230         + ( rsxdxdr*rsxdxdr * unjj - 1.) * xsr * sxlapang ;
00231 
00232     vuu.set_base(sauve_base) ;
00233 
00234     vuu = vuu.sx() ;
00235 
00236     //----------------------------------------
00237     // Computation of R(u)
00238     //
00239     //  The result is put in uu (via vuu)
00240     //----------------------------------------
00241 
00242     sauve_base = vuu.base ;
00243 
00244     vuu =  xsr * vuu
00245         + 2. * dxdr * ( sr2drdt * d2uudtdx
00246                   + sr2stdrdp * std2uudpdx ) ;
00247 
00248     vuu += dxdr * ( lapr_tp + dxdr * (
00249         dxdr* unjj * d2rdx2
00250         - 2. * ( sr2drdt * d2rdtdx  + sr2stdrdp * sstd2rdpdx ) )
00251                  ) * duudx ;    
00252 
00253     vuu.set_base(sauve_base) ;
00254 
00255     // Since the assignment is performed on vuu (uu.va), the treatment
00256     //  of uu.dzpuis must be performed by hand:
00257 
00258     uu.set_dzpuis(4) ;
00259 
00260     if (source.get_dzpuis() == 2) {
00261     uu.dec2_dzpuis() ;          // uu.dzpuis: 4 -> 2
00262     }
00263 
00264     if (source.get_dzpuis() == 3) {
00265     uu.dec_dzpuis() ;       //uu.dzpuis 4 -> 3
00266     }
00267 
00268     //====================================================================
00269     //   Computation of the effective source s^J of the ``affine''
00270     //     Poisson equation
00271     //====================================================================
00272 
00273     ssj = lambda * ssjm1 + unmlambda * ssjm2 ;
00274 
00275     ssj = ( source + uu + (amax - apre) * ssj ) / amax ;
00276 
00277     (ssj.va).set_base((source.va).base) ;
00278 
00279     //====================================================================
00280     //   Resolution of the ``affine'' Poisson equation
00281     //====================================================================
00282 
00283     if ( source.get_dzpuis() == 0 ){
00284     ssj.set_dzpuis( 4 ) ;
00285     }
00286     else {
00287     ssj.set_dzpuis( source.get_dzpuis() ) ;
00288                                            // Choice of the resolution
00289                            //  dzpuis = 2, 3 or 4
00290     }
00291 
00292     assert( uu.check_dzpuis( ssj.get_dzpuis() ) ) ;
00293 
00294     mpaff.poisson_regular(ssj, k_div, nzet, unsgam1, par_nul, uu,
00295                           uu_regu, uu_div, duu_div,
00296                           source_regu, source_div) ;
00297               
00298     //======================================
00299     //  Gradient of the diverging part (from that computed on the Map_af)
00300     //======================================
00301 
00302     Valeur& dr_uu_div = duu_div.set(0).va ; 
00303     Valeur& dt_uu_div = duu_div.set(1).va ; 
00304     Valeur& dp_uu_div = duu_div.set(2).va ; 
00305 
00306     Base_val bv = dr_uu_div.base ; 
00307     dr_uu_div = alpha[0] * dr_uu_div * dxdr ;    
00308     dr_uu_div.set_base( bv ) ; 
00309     
00310     bv = dt_uu_div.base ; 
00311     dt_uu_div = alpha[0] * dt_uu_div * xsr - srdrdt * dr_uu_div ;
00312     dt_uu_div.set_base( bv ) ; 
00313 
00314     bv = dp_uu_div.base ; 
00315     dp_uu_div = alpha[0] * dp_uu_div * xsr - srstdrdp * dr_uu_div ;
00316     dp_uu_div.set_base( bv ) ; 
00317     
00318     duu_div.set_triad( this->get_bvect_spher() ) ;
00319     
00320     
00321     //========================================
00322     // Relative difference with previous step
00323     //========================================
00324 
00325     tdiff = diffrel(vuu, vuujm1) ;
00326 
00327     diff = max(tdiff) ;
00328 
00329     cout << "  step " << niter << " :  " ;
00330     for (int l=0; l<nz; l++) {
00331     cout << tdiff(l) << "  " ;
00332     }
00333     cout << endl ;
00334 
00335     //=================================
00336     //  Updates for the next iteration
00337     //=================================
00338 
00339     ssjm2 = ssjm1 ;
00340     ssjm1 = ssj ;
00341     vuujm1 = vuu ;
00342 
00343     niter++ ;
00344 
00345     }   // End of iteration
00346     while ( (diff > precis) && (niter < nitermax) ) ;
00347 
00348 //==========================================================================
00349 //==========================================================================
00350 //              End of iteration
00351 //==========================================================================
00352 //==========================================================================
00353 
00354 
00355 }

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