cmp_pde_frontiere.C

00001 /*
00002  *   Copyright (c) 2000-2001 Philippe Grandclement
00003  *
00004  *   This file is part of LORENE.
00005  *
00006  *   LORENE is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   LORENE is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with LORENE; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 char cmp_pde_frontiere_C[] = "$Header: /cvsroot/Lorene/C++/Source/Cmp/cmp_pde_frontiere.C,v 1.6 2005/02/18 13:14:08 j_novak Exp $" ;
00024 
00025 /*
00026  * $Id: cmp_pde_frontiere.C,v 1.6 2005/02/18 13:14:08 j_novak Exp $
00027  * $Log: cmp_pde_frontiere.C,v $
00028  * Revision 1.6  2005/02/18 13:14:08  j_novak
00029  * Changing of malloc/free to new/delete + suppression of some unused variables
00030  * (trying to avoid compilation warnings).
00031  *
00032  * Revision 1.5  2004/11/23 12:49:58  f_limousin
00033  * Intoduce function poisson_dir_neu(...) to solve a scalar poisson
00034  * equation with a mixed boundary condition (Dirichlet + Neumann).
00035  *
00036  * Revision 1.4  2004/05/20 07:04:02  k_taniguchi
00037  * Recovery of "->get_angu()" in the assertion of Map_af::poisson_frontiere
00038  * because "limite" is the boundary value.
00039  *
00040  * Revision 1.3  2004/03/31 11:18:42  f_limousin
00041  * Methods Map_et::poisson_interne, Map_af::poisson_interne and
00042  * Cmp::poisson_neumann_interne have been implemented to solve the
00043  * continuity equation for strange stars.
00044  *
00045  * Revision 1.2  2003/10/03 15:58:45  j_novak
00046  * Cleaning of some headers
00047  *
00048  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00049  * LORENE
00050  *
00051  * Revision 2.6  2000/05/22  16:07:03  phil
00052  * *** empty log message ***
00053  *
00054  * Revision 2.5  2000/05/22  16:03:48  phil
00055  * ajout du cas dzpuis = 3
00056  *
00057  * Revision 2.4  2000/04/27  15:18:27  phil
00058  * ajout des procedures relatives a la resolution dans une seule zone avec deux conditions limites.
00059  *
00060  * Revision 2.3  2000/03/31  15:59:54  phil
00061  * gestion des cas ou la source est nulle.
00062  *
00063  * Revision 2.2  2000/03/20  13:08:53  phil
00064  * *** empty log message ***
00065  *
00066  * Revision 2.1  2000/03/17  17:33:05  phil
00067  * *** empty log message ***
00068  *
00069  * Revision 2.0  2000/03/17  17:25:08  phil
00070  * *** empty log message ***
00071  *
00072  *
00073  * $Header: /cvsroot/Lorene/C++/Source/Cmp/cmp_pde_frontiere.C,v 1.6 2005/02/18 13:14:08 j_novak Exp $
00074  *
00075  */
00076 
00077 // Header Lorene:
00078 #include "scalar.h" 
00079 #include "param.h" 
00080 #include "cmp.h"
00081 
00082 Mtbl_cf sol_poisson_frontiere(const Map_af&, const Mtbl_cf&, const Mtbl_cf&,
00083                   int, int, int, double = 0.,
00084                   double = 0.) ;
00085 
00086 Mtbl_cf sol_poisson_frontiere_double (const Map_af&, const Mtbl_cf&, const Mtbl_cf&,
00087                     const Mtbl_cf&, int) ;
00088 
00089 Mtbl_cf sol_poisson_interne(const Map_af&, const Mtbl_cf&, const Mtbl_cf&) ;
00090 
00091 Cmp Cmp::poisson_dirichlet (const Valeur& limite, int num_front) const {
00092     
00093     Cmp resu(*mp) ;
00094     mp->poisson_frontiere (*this, limite, 1, num_front, resu) ; 
00095     return resu ;          
00096 }
00097 
00098 
00099 Cmp Cmp::poisson_neumann (const Valeur& limite, int num_front) const {
00100     
00101     Cmp resu(*mp) ;
00102     mp->poisson_frontiere (*this, limite, 2, num_front, resu) ; 
00103     return resu ;    
00104 }
00105 
00106 Cmp Cmp::poisson_neumann_interne (const Valeur& limite, 
00107                   Param& par, Cmp& resu) const {
00108     
00109     mp->poisson_interne (*this, limite, par, resu) ; 
00110     return resu ;    
00111 }
00112 
00113 Cmp Cmp::poisson_frontiere_double (const Valeur& lim_func, const Valeur& lim_der, 
00114                     int num_zone) const {
00115     Cmp resu(*mp) ;
00116     mp->poisson_frontiere_double (*this, lim_func, lim_der, num_zone, resu) ; 
00117     return resu ;    
00118 }       
00119 
00120 void Map_et::poisson_frontiere(const Cmp&, const Valeur&, int, int, Cmp&, double, double) const {
00121     cout << "Procedure non implantee ! " << endl ;
00122     abort() ;
00123 }
00124 
00125 void Map_et::poisson_frontiere_double (const Cmp&, const Valeur&, const Valeur&,
00126                 int, Cmp&) const {
00127     cout << "Procedure non implantee ! " << endl ;
00128     abort() ;
00129 }
00130 
00131 void Map_af::poisson_frontiere(const Cmp& source, const Valeur& limite, 
00132                    int type_raccord, int num_front, 
00133                    Cmp& pot, double fact_dir, double fact_neu) const {
00134     
00135     assert(source.get_etat() != ETATNONDEF) ; 
00136     assert(source.get_mp()->get_mg() == mg) ; 
00137     assert(pot.get_mp()->get_mg() == mg) ; 
00138     
00139     assert( source.check_dzpuis(2) || source.check_dzpuis(4) 
00140         || source.check_dzpuis(3)) ; 
00141     assert ((type_raccord == 1) || (type_raccord==2)|| (type_raccord==3)) ;
00142     int dzpuis ; 
00143     
00144     if (source.dz_nonzero()){
00145     dzpuis = source.get_dzpuis() ; 
00146     }
00147     else{
00148     dzpuis = 4 ; 
00149     }
00150 
00151     // Spherical harmonic expansion of the source
00152     // ------------------------------------------
00153     
00154     Valeur sourva = source.va ;
00155     sourva.coef() ;
00156     sourva.ylm() ;
00157     
00158     // Pour gerer le cas ou source est dans ETAT_ZERO...
00159     Mtbl_cf so_cf (sourva.get_mg(), sourva.base) ;
00160     if (sourva.get_etat() == ETATZERO) {
00161     so_cf.set_etat_zero() ;
00162     }
00163     else
00164     so_cf = *sourva.c_cf ;
00165     
00166     
00167     Valeur conditions (limite) ;
00168     conditions.coef() ;
00169     conditions.ylm() ; // spherical harmonic transforms 
00170     
00171     // Pour gerer le cas ou condition est dans ETAT_ZERO...
00172     Mtbl_cf auxiliaire (conditions.get_mg(), conditions.base) ;
00173     if (conditions.get_etat() == ETATZERO)
00174     auxiliaire.set_etat_zero() ;
00175     else
00176     auxiliaire = *conditions.c_cf ;
00177     
00178     Mtbl_cf resu (sourva.get_mg(), sourva.base) ;
00179 
00180     if (type_raccord == 3){
00181 
00182     // Call to the Mtbl_cf version
00183     // ---------------------------
00184     resu = sol_poisson_frontiere(*this, so_cf, auxiliaire, 
00185                     type_raccord, num_front, dzpuis,
00186                      fact_dir, fact_neu) ;
00187     }
00188     else{
00189     resu = sol_poisson_frontiere(*this, so_cf, auxiliaire, 
00190                          type_raccord, num_front, dzpuis) ;
00191     }
00192 
00193     // Final result returned as a Cmp
00194     // ------------------------------
00195     
00196     pot.set_etat_zero() ;  // to call Cmp::del_t().
00197     pot.set_etat_qcq() ;  
00198     pot.va = resu ;
00199     (pot.va).ylm_i() ; // On repasse en base standard.      
00200     pot.set_dzpuis(0) ; 
00201 }
00202 
00203 
00204 void Map_af::poisson_frontiere_double (const Cmp& source, const Valeur& lim_func, 
00205                 const Valeur& lim_der, int num_zone, Cmp& pot) const {
00206     
00207     assert(source.get_etat() != ETATNONDEF) ; 
00208     assert(source.get_mp()->get_mg() == mg) ; 
00209     assert(pot.get_mp()->get_mg() == mg) ; 
00210     assert (source.get_mp()->get_mg()->get_angu() == lim_func.get_mg()) ;
00211     assert (source.get_mp()->get_mg()->get_angu() == lim_der.get_mg()) ;
00212     
00213     // Spherical harmonic expansion of the source
00214     // ------------------------------------------
00215     
00216     Valeur sourva = source.va ;
00217     sourva.coef() ;
00218     sourva.ylm() ;
00219     
00220     // Pour gerer le cas ou source est dans ETAT_ZERO...
00221     Mtbl_cf so_cf (sourva.get_mg(), sourva.base) ;
00222     if (sourva.get_etat() == ETATZERO) {
00223     so_cf.set_etat_zero() ;
00224     }
00225     else
00226     so_cf = *sourva.c_cf ;
00227     
00228     
00229     Valeur cond_func (lim_func) ;
00230     cond_func.coef() ;
00231     cond_func.ylm() ; // spherical harmonic transforms 
00232     
00233     // Pour gerer le cas ou condition est dans ETAT_ZERO...
00234     Mtbl_cf auxi_func (cond_func.get_mg(), cond_func.base) ;
00235     if (cond_func.get_etat() == ETATZERO)
00236     auxi_func.set_etat_zero() ;
00237     else
00238     auxi_func = *cond_func.c_cf ;
00239     
00240     Valeur cond_der (lim_der) ;
00241     cond_der.coef() ;
00242     cond_der.ylm() ; // spherical harmonic transforms 
00243     
00244     // Pour gerer le cas ou condition est dans ETAT_ZERO...
00245     Mtbl_cf auxi_der (cond_der.get_mg(), cond_der.base) ;
00246     if (cond_der.get_etat() == ETATZERO)
00247     auxi_der.set_etat_zero() ;
00248     else
00249     auxi_der = *cond_der.c_cf ;
00250     
00251     
00252     
00253     // Call to the Mtbl_cf version
00254     // ---------------------------
00255     
00256     Mtbl_cf resu = sol_poisson_frontiere_double (*this, so_cf, auxi_func,
00257                     auxi_der, num_zone) ;
00258     
00259     // Final result returned as a Cmp
00260     // ------------------------------
00261     
00262     pot.set_etat_zero() ;  // to call Cmp::del_t().
00263     pot.set_etat_qcq() ;  
00264     pot.va = resu ;
00265     (pot.va).ylm_i() ; // On repasse en base standard.
00266 }
00267 
00268 
00269 
00270 void Map_et::poisson_interne(const Cmp& source, const Valeur& limite,
00271                  Param& par, Cmp& uu) const {
00272 
00273     assert(source.get_etat() != ETATNONDEF) ; 
00274     assert(source.get_mp() == this) ;
00275 
00276     assert(uu.get_mp() == this) ; 
00277 
00278     int nz = mg->get_nzone() ; 
00279      
00280     //-------------------------------
00281     // Computation of the prefactor a  ---> Cmp apre
00282     //-------------------------------
00283 
00284     Mtbl unjj = 1 + srdrdt*srdrdt + srstdrdp*srstdrdp ;
00285 
00286     Mtbl apre1(*mg) ; 
00287     apre1.set_etat_qcq() ; 
00288     for (int l=0; l<nz; l++) {
00289     *(apre1.t[l]) = alpha[l]*alpha[l] ; 
00290     }
00291 
00292     apre1 = apre1 * dxdr * dxdr * unjj ;
00293 
00294     Cmp apre(*this) ; 
00295     apre = apre1 ; 
00296     
00297     Tbl amax0 = max(apre1) ;    // maximum values in each domain
00298 
00299     // The maximum values of a in each domain are put in a Mtbl
00300     Mtbl amax1(*mg) ; 
00301     amax1.set_etat_qcq() ; 
00302     for (int l=0; l<nz; l++) {
00303     *(amax1.t[l]) = amax0(l) ; 
00304     }
00305     
00306     Cmp amax(*this) ; 
00307     amax = amax1 ; 
00308 
00309     
00310     //-------------------
00311     //  Initializations 
00312     //-------------------
00313     
00314     int nitermax = par.get_int() ; 
00315     int& niter = par.get_int_mod() ; 
00316     double lambda = par.get_double() ; 
00317     double unmlambda = 1. - lambda ; 
00318     double precis = par.get_double(1) ;     
00319     
00320     Cmp& ssj = par.get_cmp_mod() ; 
00321     
00322     Cmp ssjm1 = ssj ; 
00323     Cmp ssjm2 = ssjm1 ; 
00324 
00325     Valeur& vuu = uu.va ; 
00326 
00327     Valeur vuujm1(*mg) ;
00328     if (uu.get_etat() == ETATZERO) {
00329     vuujm1 = 1 ;    // to take relative differences
00330     vuujm1.set_base( vuu.base ) ; 
00331     }
00332     else{
00333     vuujm1 = vuu ; 
00334     }
00335     
00336     // Affine mapping for the Laplacian-tilde
00337 
00338     Map_af mpaff(*this) ; 
00339     Param par_nul ; 
00340 
00341     cout << "Map_et::poisson : relat. diff. u^J <-> u^{J-1} : " << endl ;
00342     
00343 //==========================================================================
00344 //==========================================================================
00345 //              Start of iteration 
00346 //==========================================================================
00347 //==========================================================================
00348 
00349     Tbl tdiff(nz) ; 
00350     niter = 0 ; 
00351     
00352     do {
00353 
00354     //====================================================================
00355     //      Computation of R(u)    (the result is put in uu)
00356     //====================================================================
00357 
00358 
00359     //-----------------------
00360     // First operations on uu
00361     //-----------------------
00362     
00363     Valeur duudx = (uu.va).dsdx() ;     // d/dx 
00364 
00365     const Valeur& d2uudtdx = duudx.dsdt() ;     // d^2/dxdtheta
00366 
00367     const Valeur& std2uudpdx = duudx.stdsdp() ;    // 1/sin(theta) d^2/dxdphi   
00368 
00369     //------------------
00370     // Angular Laplacian 
00371     //------------------
00372     
00373     Valeur sxlapang = uu.va ; 
00374 
00375     sxlapang.ylm() ; 
00376     
00377     sxlapang = sxlapang.lapang() ;    
00378     
00379     sxlapang = sxlapang.sx() ;    //  Lap_ang(uu) /x      in the nucleus
00380                     
00381     //---------------------------------------------------------------
00382     //  Computation of 
00383     // [ 2 /(dRdx) ( A - 1 ) duu/dx + 1/R (B - 1) Lap_ang(uu) ] / x
00384     //
00385     // with A = 1/(dRdx) R/(x+beta_l/alpha_l) unjj 
00386     //      B = [1/(dRdx) R/(x+beta_l/alpha_l)]^2 unjj 
00387     // 
00388     //  The result is put in uu (via vuu)
00389     //---------------------------------------------------------------
00390 
00391     Valeur varduudx = duudx ; 
00392 
00393     uu.set_etat_qcq() ; 
00394     
00395     Base_val sauve_base = varduudx.base ; 
00396     
00397     vuu = 2. * dxdr * ( rsxdxdr * unjj - 1.) * varduudx 
00398         + ( rsxdxdr*rsxdxdr * unjj - 1.) * xsr * sxlapang ; 
00399 
00400     vuu.set_base(sauve_base) ; 
00401 
00402     vuu = vuu.sx() ; 
00403 
00404     //---------------------------------------
00405     // Computation of  R(u)  
00406     //
00407     //  The result is put in uu (via vuu)
00408     //---------------------------------------
00409 
00410 
00411     sauve_base = vuu.base ; 
00412 
00413     vuu =  xsr * vuu 
00414         + 2. * dxdr * ( sr2drdt * d2uudtdx 
00415                   + sr2stdrdp * std2uudpdx ) ;
00416 
00417     vuu += dxdr * ( lapr_tp + dxdr * ( 
00418         dxdr* unjj * d2rdx2 
00419         - 2. * ( sr2drdt * d2rdtdx  + sr2stdrdp * sstd2rdpdx ) ) 
00420                  ) * duudx ;            
00421 
00422     vuu.set_base(sauve_base) ; 
00423 
00424     //====================================================================
00425     //   Computation of the effective source s^J of the ``affine''
00426     //     Poisson equation 
00427     //====================================================================
00428     
00429     ssj = lambda * ssjm1 + unmlambda * ssjm2 ; 
00430     
00431     ssj = ( source + uu + (amax - apre) * ssj ) / amax ; 
00432 
00433     (ssj.va).set_base((source.va).base) ; 
00434     
00435     //====================================================================
00436     //   Resolution of the ``affine'' Poisson equation 
00437     //====================================================================
00438     
00439     mpaff.poisson_interne(ssj, limite, par_nul, uu) ; 
00440 
00441     tdiff = diffrel(vuu, vuujm1) ; 
00442 
00443     cout << "  step " << niter << " :  " ; 
00444     cout << tdiff(0) << "  " ;  
00445  
00446     cout << endl ; 
00447 
00448     //=================================
00449     //  Updates for the next iteration
00450     //=================================
00451     
00452     ssjm2 = ssjm1 ; 
00453     ssjm1 = ssj ; 
00454     vuujm1 = vuu ; 
00455     
00456     niter++ ; 
00457     
00458     }   // End of iteration 
00459     while ( (tdiff(0) > precis) && (niter < nitermax) ) ;
00460     
00461 //==========================================================================
00462 //==========================================================================
00463 //              End of iteration 
00464 //==========================================================================
00465 //==========================================================================
00466 
00467 }
00468 
00469 
00470 void Map_af::poisson_interne(const Cmp& source, const Valeur& limite, 
00471                  Param& , Cmp& pot) const {
00472     
00473     assert(source.get_etat() != ETATNONDEF) ; 
00474     assert(source.get_mp()->get_mg() == mg) ; 
00475     assert(pot.get_mp()->get_mg() == mg) ; 
00476     assert (source.get_mp()->get_mg()->get_angu() == limite.get_mg()) ;
00477  
00478     // Spherical harmonic expansion of the source
00479     // ------------------------------------------
00480     
00481     Valeur sourva = source.va ;
00482     sourva.coef() ;
00483     sourva.ylm() ;
00484     
00485     // Pour gerer le cas ou source est dans ETAT_ZERO...
00486     Mtbl_cf so_cf (sourva.get_mg(), sourva.base) ;
00487     if (sourva.get_etat() == ETATZERO) {
00488     so_cf.set_etat_zero() ;
00489     }
00490     else
00491     so_cf = *sourva.c_cf ;
00492     
00493     Valeur conditions (limite) ;
00494     conditions.coef() ;
00495     conditions.ylm() ; // spherical harmonic transforms 
00496  
00497 
00498     // Pour gerer le cas ou condition est dans ETAT_ZERO...
00499     Mtbl_cf auxiliaire (conditions.get_mg(), conditions.base) ;
00500     if (conditions.get_etat() == ETATZERO)
00501     auxiliaire.set_etat_zero() ;
00502     else
00503     auxiliaire = *conditions.c_cf ;
00504 
00505     // Call to the Mtbl_cf version
00506     // ---------------------------
00507     
00508     Mtbl_cf resu = sol_poisson_interne(*this, so_cf, auxiliaire) ;
00509     
00510     // Final result returned as a Cmp
00511     // ------------------------------
00512     
00513     pot.set_etat_zero() ;  // to call Cmp::del_t().
00514     pot.set_etat_qcq() ;  
00515     pot.va = resu ;
00516     (pot.va).ylm_i() ; // On repasse en base standard.      
00517     pot.set_dzpuis(0) ; 
00518 }
00519 

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