map_af_poisson2d.C

00001 /*
00002  * Method of the class Map_af 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_af_poisson2d_C[] = "$Header: /cvsroot/Lorene/C++/Source/Map/map_af_poisson2d.C,v 1.3 2002/09/09 13:54:20 e_gourgoulhon Exp $" ;
00031 
00032 /*
00033  * $Id: map_af_poisson2d.C,v 1.3 2002/09/09 13:54:20 e_gourgoulhon Exp $
00034  * $Log: map_af_poisson2d.C,v $
00035  * Revision 1.3  2002/09/09 13:54:20  e_gourgoulhon
00036  *
00037  * Change of name of the Fortran subroutines
00038  *  poisson2d -> poiss2d
00039  *  poisson2di -> poiss2di
00040  * to avoid any clash with Map::poisson2d and Map::poisson2di
00041  *
00042  * Revision 1.2  2002/09/09 13:00:39  e_gourgoulhon
00043  * Modification of declaration of Fortran 77 prototypes for
00044  * a better portability (in particular on IBM AIX systems):
00045  * All Fortran subroutine names are now written F77_* and are
00046  * defined in the new file C++/Include/proto_f77.h.
00047  *
00048  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00049  * LORENE
00050  *
00051  * Revision 2.1  2000/10/11  15:15:26  eric
00052  * 1ere version operationnelle.
00053  *
00054  * Revision 2.0  2000/10/09  13:47:10  eric
00055  * *** empty log message ***
00056  *
00057  *
00058  * $Header: /cvsroot/Lorene/C++/Source/Map/map_af_poisson2d.C,v 1.3 2002/09/09 13:54:20 e_gourgoulhon Exp $
00059  *
00060  */
00061 
00062 // Header Lorene:
00063 #include "map.h"
00064 #include "cmp.h"
00065 #include "param.h"
00066 #include "proto_f77.h"
00067 
00068 //*****************************************************************************
00069 
00070 void Map_af::poisson2d(const Cmp& source_mat, const Cmp& source_quad, 
00071                Param& par, Cmp& uu) const {
00072     
00073     assert(source_mat.get_etat() != ETATNONDEF) ; 
00074     assert(source_quad.get_etat() != ETATNONDEF) ; 
00075     assert(source_mat.get_mp()->get_mg() == mg) ; 
00076     assert(source_quad.get_mp()->get_mg() == mg) ; 
00077     assert(uu.get_mp()->get_mg() == mg) ; 
00078 
00079     assert( source_quad.check_dzpuis(4) ) ; 
00080     
00081     double& lambda = par.get_double_mod(0) ; 
00082 
00083     // Special case of a vanishing source 
00084     // ----------------------------------
00085 
00086     if (    (source_mat.get_etat() == ETATZERO) 
00087      && (source_quad.get_etat() == ETATZERO) ) {
00088     
00089     uu = 0 ; 
00090     lambda = 1 ; 
00091     return ; 
00092     }
00093 
00094     // ---------------------------------------------------------------------
00095     // Preparation of the parameters for the Fortran subroutines F77_poisson2d
00096     //  and F77_poisson2di
00097     // ---------------------------------------------------------------------
00098     
00099     int nz = mg->get_nzone() ;
00100     int np1 = 1 ;       // Axisymmetry enforced
00101     int nt = mg->get_nt(0) ; 
00102     int nt2 = 2*nt - 1 ;    // Number of points for the theta sampling
00103                 //  in [0,Pi], instead of [0,Pi/2]
00104     
00105     // Array NDL
00106     // ---------
00107     int* ndl = new int[nz+4] ; 
00108     ndl[0] = nz ; 
00109     for (int l=0; l<nz; l++) {
00110     ndl[1+l] = mg->get_nr(l) ; 
00111     }
00112     ndl[1+nz] = nt2 ; 
00113     ndl[2+nz] = np1 ; 
00114     ndl[3+nz] = nz ; 
00115     
00116     // Array INDD
00117     // ----------
00118     int* indd = new int[nz] ; 
00119     for (int l=0; l<nz; l++) {
00120     switch ( mg->get_type_r(l) ) {
00121         case RARE : {
00122         indd[l] = 0 ; 
00123         break ; 
00124         }
00125         case FIN : {
00126         indd[l] = 1 ; 
00127         break ; 
00128         }
00129         case UNSURR : {
00130         indd[l] = 2 ; 
00131         break ; 
00132         }
00133         default : {
00134         cout << "Map_af::poisson2d: unknown type_r !" << endl ; 
00135         abort() ; 
00136         break ; 
00137         }
00138     }
00139     }
00140     
00141     // Parameters NDR, NDT, NDP and NDZ
00142     // --------------------------------
00143     int nrmax = 0 ;
00144     for (int l=0; l<nz ; l++) {
00145     nrmax = ( ndl[1+l] > nrmax ) ? ndl[1+l] : nrmax ; 
00146     }
00147     int ndr = nrmax + 5 ;   // Le +5 est impose par les routines de resolution
00148                 // de l'equation de Poisson du type gr2p3s_
00149     int ndt = nt2 + 2 ;
00150     int ndp = np1 + 2 ;
00151     int ndz = nz ; 
00152     
00153     // Array ERRE
00154     // ----------
00155     
00156     double* erre = new double [ndz*ndr] ; 
00157     
00158     for (int l=0; l<nz; l++) {
00159     for (int i=0; i<ndl[1+l]; i++) {
00160         double xr = mg->get_grille3d(l)->x[i] ;
00161         erre[ ndr*l + i ] = alpha[l] * xr + beta[l]  ;
00162     }
00163     }
00164 
00165     // Arrays containing the data
00166     // --------------------------
00167     
00168     int ndrt = ndr*ndt ; 
00169     int ndrtp = ndr*ndt*ndp ; 
00170     int taille = ndrtp*ndz ;
00171 
00172     double* tsou_m = new double[ taille ] ;    
00173     double* tsou_q = new double[ taille ] ;    
00174     double* tuu = new double[ taille ] ;    
00175     
00176     // Initialisation to zero :
00177     for (int i=0; i<taille; i++) {
00178     tsou_m[i] = 0 ; 
00179     tsou_q[i] = 0 ; 
00180     tuu[i] = 0 ; 
00181     }
00182     
00183     // Copy of source_mat into tsou_m
00184     // ------------------------------
00185     const Valeur& va_m = source_mat.va ; 
00186     assert(va_m.get_etat() == ETATQCQ) ; 
00187     va_m.coef_i() ; 
00188     const Mtbl* s_m = va_m.c ; 
00189     assert(s_m->get_etat() == ETATQCQ) ; 
00190     
00191     Base_val base_s = va_m.base ; 
00192 
00193     for (int l=0; l<nz; l++) {
00194     int nr = mg->get_nr(l) ; 
00195     int nrt = nr*nt ;  
00196     if (s_m->t[l]->get_etat() == ETATZERO) {
00197         for (int k=0; k<np1; k++) {
00198         for (int j=0; j<nt; j++) {
00199             for (int i=0; i<nr; i++) {
00200             tsou_m[ndrtp*l + ndrt*k + ndr*j + i] = 0 ;
00201             // point symetrique par rapport au plan theta = pi/2 :
00202             tsou_m[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = 0 ;          
00203             }
00204         }
00205         }
00206         
00207     }
00208     else {
00209         assert( s_m->t[l]->get_etat() == ETATQCQ ) ; 
00210         for (int k=0; k<np1; k++) {
00211         for (int j=0; j<nt; j++) {
00212             for (int i=0; i<nr; i++) {
00213             double xx = s_m->t[l]->t[nrt*k + nr*j + i] ;
00214             tsou_m[ndrtp*l + ndrt*k + ndr*j + i] = xx ;
00215             // point symetrique par rapport au plan theta = pi/2 :
00216             tsou_m[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = xx ;         
00217             }
00218         }
00219         }
00220     }  // End of case etat != ETATZERO
00221     }  
00222 
00223     // Copy of source_quad into tsou_q
00224     // -------------------------------
00225 
00226     if (source_quad.get_etat() != ETATZERO) {
00227 
00228     const Valeur& va_q = source_quad.va ; 
00229     assert(va_q.get_etat() == ETATQCQ) ; 
00230     va_q.coef_i() ; 
00231     const Mtbl* s_q = va_q.c ;  
00232 
00233     assert( va_q.base == base_s ) ; 
00234 
00235     assert(s_q->get_etat() == ETATQCQ) ; 
00236 
00237     for (int l=0; l<nz; l++) {
00238         int nr = mg->get_nr(l) ; 
00239         int nrt = nr*nt ;  
00240         if (s_q->t[l]->get_etat() == ETATZERO) {
00241         for (int k=0; k<np1; k++) {
00242             for (int j=0; j<nt; j++) {
00243             for (int i=0; i<nr; i++) {
00244             tsou_q[ndrtp*l + ndrt*k + ndr*j + i] = 0 ;
00245             // point symetrique par rapport au plan theta = pi/2 :
00246             tsou_q[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = 0 ;          
00247             }
00248             }
00249         }
00250         
00251         }
00252         else {
00253         assert( s_q->t[l]->get_etat() == ETATQCQ ) ; 
00254         for (int k=0; k<np1; k++) {
00255             for (int j=0; j<nt; j++) {
00256             for (int i=0; i<nr; i++) {
00257             double xx = s_q->t[l]->t[nrt*k + nr*j + i] ;
00258             tsou_q[ndrtp*l + ndrt*k + ndr*j + i] = xx ;
00259             // point symetrique par rapport au plan theta = pi/2 :
00260             tsou_q[ndrtp*l + ndrt*k + ndr*(nt2-1-j) + i] = xx ;         
00261             }
00262             }
00263         }
00264         }  // End of case s_q->t[l]->etat != ETATZERO
00265     }
00266     
00267     } // End of case source_quad.etat != ETATZERO  
00268 
00269     //-----------------------------------------------------------
00270     //  Call of the Fortran subroutine poisson2d_ or poisson2di_
00271     //-----------------------------------------------------------
00272 
00273     int base_t = (va_m.base).get_base_t(0) ; 
00274 
00275     Base_val base_uu(nz) ;  // Output spectral bases
00276 
00277     switch (base_t) {
00278 
00279     case T_COS_P : {
00280     
00281         double lambda0 ; 
00282         
00283         F77_poiss2d(ndl, &ndr, &ndt, &ndp, indd, erre, tsou_m, tsou_q, 
00284                &lambda0, tuu) ;
00285               
00286         base_uu = base_s ;      // output bases = input bases
00287                
00288         lambda = lambda0 ; 
00289         break ;         
00290     }
00291     
00292     case T_SIN_I : {
00293 
00294         double* tsou = new double[taille] ; 
00295         for (int i=0; i<taille; i++) {
00296         tsou[i] = tsou_m[i] + tsou_q[i] ; 
00297         }
00298 
00299         F77_poiss2di(ndl, &ndr, &ndt, &ndp, indd, erre, tsou, tuu) ;
00300         
00301         base_uu = base_s ;      // output bases = input bases
00302 
00303         lambda = double(1) ; 
00304         
00305         delete [] tsou ; 
00306         break ;         
00307     }
00308     
00309     default : {
00310         cout << "Map_af::poisson2d : unkown theta basis !" << endl ;
00311         cout << "  basis : " << hex << base_t << endl ; 
00312         abort() ; 
00313         break ; 
00314     }
00315     }
00316     
00317     //-------------------------------
00318     // Copy of tuu into uu
00319     //-------------------------------
00320 
00321     uu.allocate_all() ; 
00322     (uu.va).set_etat_c_qcq() ;  // To make sure that the coefficients are
00323                 //  deleted
00324     
00325     for (int l=0; l<nz; l++) {
00326     int nr = mg->get_nr(l) ; 
00327     for (int k=0; k<mg->get_np(l); k++) {
00328         for (int j=0; j<nt; j++) {
00329         for (int i=0; i<nr; i++) {
00330             uu.set(l, k, j, i) = tuu[ndrtp*l + ndr*j + i]  ;
00331         }
00332         }
00333     }
00334     }
00335 
00336     (uu.va).set_base( base_uu ) ;   // Bases for spectral expansions
00337     
00338     uu.set_dzpuis(0) ; 
00339    
00340     // Cleaning
00341     // --------
00342     
00343     delete [] ndl ; 
00344     delete [] indd ; 
00345     delete [] erre ; 
00346     delete [] tsou_m ; 
00347     delete [] tsou_q ; 
00348     delete [] tuu ; 
00349     
00350     
00351 }
00352 
00353 

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