map_et_adapt.C

00001 /*
00002  *  Method of the class Map_et to compute the mapping parameters to let the
00003  *  domain boundaries coincide with isosurfaces of a given scalar field.
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_adapt_C[] = "$Header: /cvsroot/Lorene/C++/Source/Map/map_et_adapt.C,v 1.9 2010/01/31 16:58:39 e_gourgoulhon Exp $" ;
00031 
00032 /*
00033  * $Id: map_et_adapt.C,v 1.9 2010/01/31 16:58:39 e_gourgoulhon Exp $
00034  * $Log: map_et_adapt.C,v $
00035  * Revision 1.9  2010/01/31 16:58:39  e_gourgoulhon
00036  * Back to rev. 1.7 (1.8 has been committed by mistake).
00037  *
00038  * Revision 1.8  2010/01/31 16:51:47  e_gourgoulhon
00039  * File local_settings_linux is now called local_settings_linux_old (for
00040  * it is quite old and not compatible with the gcc 4.x series).
00041  *
00042  * Revision 1.7  2006/09/05 13:39:45  p_grandclement
00043  * update of the bin_ns_bh project
00044  *
00045  * Revision 1.6  2006/05/17 13:27:12  j_novak
00046  * Removed strange character on line 534.
00047  *
00048  * Revision 1.5  2006/05/03 11:15:25  p_grandclement
00049  * modif filtering
00050  *
00051  * Revision 1.4  2006/05/03 07:07:52  p_grandclement
00052  * Petite correction
00053  *
00054  * Revision 1.3  2006/04/25 07:21:59  p_grandclement
00055  * Various changes for the NS_BH project
00056  *
00057  * Revision 1.2  2003/10/03 15:58:48  j_novak
00058  * Cleaning of some headers
00059  *
00060  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00061  * LORENE
00062  *
00063  * Revision 2.6  2000/11/10  15:19:300  eric
00064  * Appel de Valeur::equipot_outward plutot que Valeur::equipot
00065  *   dans la determination des isopotentielles.
00066  *
00067  * Revision 2.5  2000/10/23  14:01:17  eric
00068  * Changement des arguments (en autre, ajout de nz_search, qui est
00069  * desormais a priori independant de nzadapt).
00070  *
00071  * Revision 2.4  2000/10/20  13:13:01  eric
00072  * nzet --> nzadapt.
00073  * nz_search = nzadapt --> nz_search = nzadapt + 1
00074  *
00075  * Revision 2.3  2000/02/17  19:00:53  eric
00076  * nz_search = nzet  et non plus  nz_search = nz-1.
00077  *
00078  * Revision 2.2  2000/02/15  15:09:12  eric
00079  * Changement du Param : fact_echelle est desormais passe en double_mod.
00080  *
00081  * Revision 2.1  2000/01/03  15:46:59  eric
00082  * *** empty log message ***
00083  *
00084  * Revision 2.0  2000/01/03  13:30:59  eric
00085  * *** empty log message ***
00086  *
00087  *
00088  * $Header: /cvsroot/Lorene/C++/Source/Map/map_et_adapt.C,v 1.9 2010/01/31 16:58:39 e_gourgoulhon Exp $
00089  *
00090  */
00091 
00092 // Headers C
00093 #include <assert.h>
00094 
00095 // Headers Lorene
00096 #include "cmp.h"
00097 #include "itbl.h"
00098 #include "param.h"
00099 #include "proto.h"
00100 
00101 void Map_et::adapt(const Cmp& ent, const Param& par, int nbr_filtre) {
00102     
00103     // Parameters of the computation
00104     // -----------------------------
00105     
00106     int nitermax = par.get_int(0) ;
00107     int& niter = par.get_int_mod(0) ; 
00108     int nzadapt = par.get_int(1) ;
00109     int nz_search = par.get_int(2)  ;
00110     int adapt_flag = par.get_int(3) ;
00111     int j_bord = par.get_int(4) ;   // index of theta_*
00112     int k_bord = par.get_int(5) ;   // index of phi_*
00113     double precis = par.get_double(0) ;
00114     double fact_lamu = par.get_double(1) ;
00115     double fact_echelle = par.get_double(2) ;
00116 
00117     const Tbl& ent_limit = par.get_tbl(0) ; 
00118     
00119     int nz = mg->get_nzone() ;  
00120     int nt = mg->get_nt(0) ; 
00121     int np = mg->get_np(0) ; 
00122     
00123     
00124     // Protections 
00125     // -----------
00126     assert(ent.get_mp() == this) ; 
00127     assert(nzadapt < nz) ;
00128     assert(nzadapt > 0) ;
00129     assert(nz_search >= nzadapt) ; 
00130     for (int l=1; l<nz; l++) {
00131     assert( mg->get_nt(l) == nt ) ; 
00132     assert( mg->get_np(l) == np ) ; 
00133     }
00134     assert(ent_limit.get_ndim() == 1) ; 
00135     assert(ent_limit.get_taille() >= nzadapt) ; 
00136     assert(ent_limit.get_etat() == ETATQCQ) ; 
00137 
00138     // Initializations 
00139     // ---------------
00140     
00141     niter = 0 ;
00142     const double xi_max = 1 ; 
00143     
00144     //=======================================================================
00145     //   Special case of a fixed mapping : only a rescaling is performed
00146     //=======================================================================
00147 
00148     if ( (adapt_flag == 0) || (nzadapt == 0) ) { 
00149 
00150     homothetie(fact_echelle) ; 
00151     
00152     return ; 
00153     }        
00154     
00155     //=======================================================================
00156     //   General case 
00157     //=======================================================================
00158     
00159     // New mapping parameters
00160     // ----------------------
00161     
00162     double* nalpha = new double[nz] ;
00163     double* nbeta = new double[nz] ;
00164 
00165     Itbl l_ext(np, nt) ;
00166     Tbl  x_ext(np, nt) ;
00167     
00168     Tbl xtgg(np, nt, 1) ;   // working array constructed from the isosurface
00169                 //  equation
00170     Tbl xtff(np, nt, 1) ;   // idem 
00171 
00172     //----------------------------------------------------------------
00173     //   Adaptation of the nucleus
00174     //----------------------------------------------------------------
00175     
00176     double ent0 = ent_limit(0) ; 
00177 
00178     // Search for the equipotential surface ent = ent0 
00179     //    --->  l = l_ext(theta, phi) 
00180     //      xi = x_ext(theta, phi)
00181     // -----------------------------------------------
00182 
00183     int niter0 ; 
00184     (ent.va).equipot_outward(ent0, nz_search, precis, nitermax, niter0, 
00185                  l_ext, x_ext) ; 
00186 
00187     niter = ( niter0 > niter ) ? niter0 : niter ;
00188 
00189     // The new mapping must be such that the found isosurface corresponds
00190     //  to xi = 1
00191     
00192     // Computation of r_ext(theta, phi) - r_eq ---> xtgg
00193     // -------------------------------------------------
00194     
00195     xtgg.set_etat_qcq() ; 
00196     assert(l_ext.get_etat() == ETATQCQ) ; 
00197 
00198     double r_eq = val_r_jk(0, xi_max, j_bord, k_bord) ;
00199 
00200     double* pxtgg = xtgg.t ; 
00201     int* pl_ext = l_ext.t ;
00202     double* px_ext = x_ext.t ;
00203     
00204     for (int k=0; k<np; k++) {
00205     for (int j=0; j<nt; j++) {
00206 
00207         *pxtgg = val_r_jk(*pl_ext, *px_ext, j, k) - r_eq  ;
00208                         
00209         // ... next one
00210         pl_ext++ ;
00211         px_ext++ ;
00212         pxtgg++ ;
00213     }      
00214     }   
00215 
00216     // Decomposition into even and odd harmonics in phi of xtgg = r_ext - r_eq :
00217     //      even phi harmonics --> xtgg
00218     //      odd  phi harmonics --> xtff
00219     // ------------------------------------------------------------------------
00220     
00221     int base_p = ( ((ent.va).base).b[0] ) & MSQ_P ;
00222 
00223     switch( base_p ) {
00224 
00225     case P_COSSIN_P : { // case of only even harmonics in phi
00226 
00227         xtff.set_etat_zero() ; 
00228         break ; 
00229     }
00230         
00231     case P_COSSIN : {   // general case: a Fourier transform must be
00232                 //  done
00233 
00234         xtff.set_etat_qcq() ; 
00235         double* pxtff = xtff.t ; 
00236         pxtgg = xtgg.t ; 
00237 
00238         assert(np>=4) ;
00239         int deg[3] ;
00240         int dimc[3] ;
00241         deg[0] = np ;
00242         deg[1] = nt ;
00243         deg[2] = 1; 
00244         dimc[0] = np + 2 ;
00245         dimc[1] = nt ;
00246         dimc[2] = 1 ; 
00247         double* cf = new double[(np+2)*nt] ; 
00248         double* cf0 = new double[(np+2)*nt] ; 
00249         double* ff0 = new double[np*nt] ; 
00250 
00251         for (int i=0; i < np*nt; i++) {
00252         cf[i] = *pxtgg ;
00253         pxtgg++ ;
00254         }
00255         
00256         cfpcossin(deg, dimc, cf) ;      // Fourier transform 
00257         
00258         // Even harmonics
00259         // --------------
00260         double* pcf0 = cf0 ; 
00261         double* pcf = cf ; 
00262         for (int k=0; k<np-1; k += 4) {
00263         for(int j=0; j<2*nt; j++) {
00264             *pcf0 = *pcf ; 
00265             pcf0++ ; 
00266             pcf++ ;
00267         }
00268         for(int j=0; j<2*nt; j++) {
00269             *pcf0 = 0 ; 
00270             pcf0++ ; 
00271             pcf++ ;
00272         }
00273         }   
00274         if (np%4 == 0) {        // particular case of np multiple of 4
00275         for(int j=0; j<2*nt; j++) {
00276             *pcf0 = *pcf ; 
00277             pcf0++ ; 
00278             pcf++ ;
00279         }       
00280         }
00281 
00282         cipcossin(deg, dimc, deg, cf0, ff0) ; // Inverse Fourier transform 
00283 
00284         pxtgg = xtgg.t ; 
00285         for (int i=0; i < np*nt; i++) {
00286         *pxtgg = ff0[i] ;
00287         pxtgg++ ;
00288         }
00289         
00290         // Odd harmonics
00291         // -------------
00292         pcf0 = cf0 ; 
00293         pcf = cf ; 
00294         for (int k=0; k<np-1; k += 4) {
00295         for(int j=0; j<2*nt; j++) {
00296             *pcf0 = 0 ; 
00297             pcf0++ ; 
00298             pcf++ ;
00299         }
00300         for(int j=0; j<2*nt; j++) {
00301             *pcf0 = *pcf ; 
00302             pcf0++ ; 
00303             pcf++ ;
00304         }
00305         }   
00306         if (np%4 == 0) {        // particular case of np multiple of 4
00307         for(int j=0; j<2*nt; j++) {
00308             *pcf0 = 0 ; 
00309             pcf0++ ; 
00310         }       
00311         }
00312 
00313         cipcossin(deg, dimc, deg, cf0, ff0) ; // TF inverse
00314 
00315         pxtff = xtff.t ; 
00316         for (int i=0; i < np*nt; i++) {
00317         *pxtff = ff0[i] ;
00318         pxtff++ ;
00319         }
00320         
00321         delete [] cf ; 
00322         delete [] cf0 ; 
00323         delete [] ff0 ; 
00324         break ;
00325     }
00326     
00327     default : { 
00328         cout << "Map_et::adapt: unknown phi basis !" << endl ; 
00329         cout << "  base_p = " << base_p << endl ; 
00330         abort() ; 
00331     }
00332     }
00333     
00334     // Computation of lambda and mu in the nucleus :
00335     // --------------------------------------------  
00336     
00337     double lambda = 0 ;     // lambda is set to zero because F(theta, phi)
00338                 // must not have constant terms in the nucleus
00339      
00340     double mu = - fact_lamu * min(xtgg) ; 
00341 
00342     // Computation of alpha and beta in the nucleus : 
00343     // --------------------------------------------  
00344 
00345     nalpha[0] = r_eq - lambda - mu ; 
00346     nbeta[0] = 0 ; 
00347     
00348     // Computation of F_0, G_0 and {\tilde F_1} :
00349     // ------------------------------------------
00350 
00351     Mtbl nff(ff.get_mg()) ; 
00352     Mtbl ngg(gg.get_mg()) ; 
00353     nff.set_etat_qcq() ; 
00354     ngg.set_etat_qcq() ; 
00355     
00356     *(nff.t[0]) = ( xtff + lambda ) / nalpha[0] ; 
00357     *(ngg.t[0]) = ( xtgg + mu     ) / nalpha[0] ; 
00358     xtff += xtgg ; 
00359     
00360     
00361     //----------------------------------------------------------------
00362     //   Adaptation of the shells
00363     //----------------------------------------------------------------
00364     
00365     double r_eqlm1 = r_eq ; 
00366 
00367 
00368     // Loop on the shells where the adaptation must be performed 
00369     
00370     for (int l=1; l<nzadapt; l++) {
00371     
00372     ent0 = ent_limit(l) ; 
00373 
00374     // Search for the equipotential surface ent = ent0 
00375     //    --->  l = l_ext(theta, phi) 
00376     //      xi = x_ext(theta, phi)
00377     // -----------------------------------------------
00378 
00379     (ent.va).equipot_outward(ent0, nz_search, precis, nitermax, niter0, 
00380                  l_ext, x_ext) ; 
00381              
00382     niter = ( niter0 > niter ) ? niter0 : niter ;
00383 
00384     // The new mapping must be such that the found isosurface corresponds
00385     //  to xi = 1
00386     
00387     // Computation of r_ext(theta, phi) - r_eq ---> xtgg
00388     // -------------------------------------------------
00389     
00390     xtgg.set_etat_qcq() ; 
00391     assert(l_ext.get_etat() == ETATQCQ) ; 
00392 
00393     r_eq = val_r_jk(l, xi_max, j_bord, k_bord) ;
00394 
00395     pxtgg = xtgg.t ; 
00396     pl_ext = l_ext.t ;
00397     px_ext = x_ext.t ;
00398     
00399     for (int k=0; k<np; k++) {
00400         for (int j=0; j<nt; j++) {
00401 
00402         *pxtgg = val_r_jk(*pl_ext, *px_ext, j, k) - r_eq  ;
00403                         
00404         // ... next one
00405         pl_ext++ ;
00406         px_ext++ ;
00407         pxtgg++ ;
00408         }      
00409     }   
00410 
00411     // Computation of lambda and mu in domain no. l :
00412     // --------------------------------------------  
00413     
00414     lambda = - fact_lamu * max(xtff) ; 
00415     mu = - fact_lamu * min(xtgg) ; 
00416 
00417     // Computation of alpha and beta in domain no. l : 
00418     // --------------------------------------------  
00419 
00420     nalpha[l] = .5 * ( r_eq - r_eqlm1 + lambda - mu ) ;
00421     nbeta[l] =  .5 * ( r_eq + r_eqlm1 - lambda - mu ) ; 
00422     
00423     // Computation of F_l, G_l and {\tilde F_(l+1)} :
00424     // ------------------------------------------
00425     
00426     *(nff.t[l]) = ( xtff + lambda ) / nalpha[l] ; 
00427     *(ngg.t[l]) = ( xtgg + mu     ) / nalpha[l] ; 
00428     xtff = xtgg ; 
00429     
00430     r_eqlm1 = r_eq ; 
00431     
00432     } // end of the loop on the shells where the adaptation must be performed
00433     
00434     //----------------------------------------------------------------
00435     //   Adaptation of the domain of index nzadapt
00436     //----------------------------------------------------------------
00437     
00438     if (mg->get_type_r(nzadapt) == UNSURR) {
00439     
00440     // Case of a compactified domain 
00441     // -----------------------------
00442     
00443     xtff = 1 / (xtff + r_eqlm1) - double(1) / r_eqlm1 ; 
00444     
00445     lambda = - fact_lamu * min(xtff) ;
00446     
00447     nalpha[nzadapt] = .5 * ( lambda - double(1) / r_eqlm1 ) ; 
00448     nbeta[nzadapt] = - nalpha[nzadapt] ;
00449     
00450     // Computation of F_nzadapt : 
00451     *(nff.t[nzadapt]) = ( xtff + lambda ) / nalpha[nzadapt] ; 
00452     
00453     }
00454     else {
00455     // Case of a non-compactified domain 
00456     // ----------------------------------
00457     
00458     r_eq = val_r_jk(nzadapt, xi_max, j_bord, k_bord) ;
00459     
00460     lambda = - fact_lamu * max(xtff) ;
00461 
00462     nalpha[nzadapt] = .5 * ( r_eq - r_eqlm1 + lambda ) ; 
00463     nbeta[nzadapt]  = .5 * ( r_eq + r_eqlm1 - lambda ) ; 
00464 
00465     // Computation of F_l : 
00466 
00467     *(nff.t[nzadapt]) = ( xtff + lambda ) / nalpha[nzadapt] ;   
00468 
00469     }
00470 
00471     // In all cases, G_nzadapt is set to zero : 
00472     ngg.t[nzadapt]->set_etat_zero() ; 
00473 
00474     //----------------------------------------------------------------
00475     //  Values of alpha, beta, F and G in the most external domains
00476     //   where the mapping is unchanged
00477     //----------------------------------------------------------------
00478 
00479     for (int l=nzadapt+1; l<nz; l++) {
00480 
00481     nalpha[l] = alpha[l] ; 
00482     nbeta[l]  = beta[l] ;
00483 
00484     }
00485 
00486     if (ff.get_etat() == ETATZERO) {
00487     for (int l=nzadapt+1; l<nz; l++) {
00488         nff.t[l]->set_etat_zero() ; 
00489     }   
00490     }
00491     else {
00492     assert(ff.get_etat() == ETATQCQ) ; 
00493     assert(ff.c != 0x0) ; 
00494     assert(ff.c->get_etat() == ETATQCQ) ; 
00495     for (int l=nzadapt+1; l<nz; l++) {
00496         *(nff.t[l]) = *(ff.c->t[l]) ; 
00497     }   
00498     }
00499     
00500     if (gg.get_etat() == ETATZERO) {
00501     for (int l=nzadapt+1; l<nz; l++) {
00502         ngg.t[l]->set_etat_zero() ; 
00503     }   
00504     }
00505     else {
00506     assert(gg.get_etat() == ETATQCQ) ; 
00507     assert(gg.c != 0x0) ; 
00508     assert(gg.c->get_etat() == ETATQCQ) ; 
00509     for (int l=nzadapt+1; l<nz; l++) {
00510         *(ngg.t[l]) = *(gg.c->t[l]) ; 
00511     }   
00512     }
00513     
00514 
00515     //=============================================================================
00516     //  Assignment of the mapping parameters alpha, beta, ff and gg to
00517     //   the newly computed values
00518     //=============================================================================
00519 
00520     for (int l=0; l<nz; l++) {
00521     
00522     if (mg->get_type_r(l) == UNSURR) {
00523         alpha[l] = nalpha[l] / fact_echelle ; 
00524         beta[l] = nbeta[l] / fact_echelle  ; 
00525     }
00526     else {
00527         alpha[l] = fact_echelle * nalpha[l] ; 
00528         beta[l] = fact_echelle * nbeta[l] ;         
00529     }
00530     
00531     }
00532 
00533     ff = nff ; 
00534     gg = ngg ; 
00535     
00536     ff.std_base_scal() ;    // Standard spectral bases for F 
00537     gg.std_base_scal() ;    // Standard spectral bases for G
00538         
00539 
00540     if (nbr_filtre !=0) {
00541       ff.coef() ;
00542       gg.coef() ;
00543       ff.set_etat_cf_qcq() ;
00544       gg.set_etat_cf_qcq() ;
00545       for (int l=0 ; l<nzadapt+1 ; l++)
00546     for (int k=np-nbr_filtre ; k<np ; k++) 
00547       for (int j=0 ; j<nt ; j++) {
00548         if (ff.c_cf->t[l]->get_etat() != ETATZERO)
00549           ff.c_cf->set(l, k,j,0) = 0 ;
00550       
00551         if  (gg.c_cf->t[l]->get_etat() != ETATZERO)
00552           gg.c_cf->set(l,k,j,0) = 0 ;
00553       }
00554     }
00555 
00556     // The derived quantities must be reset
00557     // ------------------------------------
00558     
00559     reset_coord() ; 
00560 
00561 
00562     // Clean exit
00563     // ----------
00564     
00565     delete [] nalpha ;   
00566     delete [] nbeta ;  
00567         
00568 }

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