cmp_import_asymy.C

00001 /*
00002  * Member function of the Cmp class for initiating a Cmp from a Cmp defined
00003  *  on another mapping.
00004  * Case where both Cmp's are antisymmetric with respect to their y=0 plane.
00005  */
00006 
00007 /*
00008  *   Copyright (c) 1999-2001 Eric Gourgoulhon
00009  *
00010  *   This file is part of LORENE.
00011  *
00012  *   LORENE is free software; you can redistribute it and/or modify
00013  *   it under the terms of the GNU General Public License as published by
00014  *   the Free Software Foundation; either version 2 of the License, or
00015  *   (at your option) any later version.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 
00029 char cmp_import_asymy_C[] = "$Header: /cvsroot/Lorene/C++/Source/Cmp/cmp_import_asymy.C,v 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon Exp $" ;
00030 
00031 
00032 /*
00033  * $Id: cmp_import_asymy.C,v 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon Exp $
00034  * $Log: cmp_import_asymy.C,v $
00035  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00036  * LORENE
00037  *
00038  * Revision 2.0  2000/03/06  10:56:07  eric
00039  * *** empty log message ***
00040  *
00041  *
00042  * $Header: /cvsroot/Lorene/C++/Source/Cmp/cmp_import_asymy.C,v 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon Exp $
00043  *
00044  */
00045 
00046 
00047 
00048 // Headers C
00049 #include <math.h>
00050 
00051 // Headers Lorene
00052 #include "cmp.h"
00053 #include "param.h"
00054 #include "nbr_spx.h"
00055 
00056             //-------------------------------//
00057             //  Importation in all domains   //
00058             //-------------------------------//
00059 
00060 void Cmp::import_asymy(const Cmp& ci) {
00061     
00062     int nz = mp->get_mg()->get_nzone() ; 
00063     
00064     import_asymy(nz, ci) ; 
00065         
00066 }
00067 
00068             //--------------------------------------//
00069             //  Importation in inner domains only   //
00070             //--------------------------------------//
00071 
00072 void Cmp::import_asymy(int nzet, const Cmp& cm_d) {
00073     
00074     const Map* mp_d = cm_d.mp ; // Departure mapping
00075 
00076     // Trivial case : mappings identical !
00077     // -----------------------------------
00078     
00079     if (mp_d == mp) {
00080     *this = cm_d ; 
00081     return ; 
00082     }
00083     
00084     // Relative orientation of the two mappings
00085     // ----------------------------------------
00086  
00087     int align_rel = (mp->get_bvect_cart()).get_align()  
00088             * (mp_d->get_bvect_cart()).get_align() ;
00089             
00090     switch (align_rel) {
00091 
00092     case 1 : {  // the two mappings have aligned Cartesian axis
00093         import_align_asymy(nzet, cm_d) ; 
00094         break ; 
00095     }
00096 
00097     case -1 : {  // the two mappings have anti-aligned Cartesian axis
00098         import_anti_asymy(nzet, cm_d) ; 
00099         break ; 
00100     }
00101 
00102     default : {  
00103         cout << "Cmp::import_asymy : unexpected value of align_rel : " 
00104          << align_rel << endl ; 
00105         abort() ; 
00106         break ; 
00107     }
00108 
00109     }
00110     
00111 }    
00112 
00113 
00114         //-----------------------------------------//
00115         //   Case of Cartesian axis anti-aligned   //
00116         //-----------------------------------------//
00117 
00118 
00119 void Cmp::import_anti_asymy(int nzet, const Cmp& cm_d) {
00120     
00121     // Trivial case : null Cmp
00122     // ------------------------
00123     
00124     if (cm_d.etat == ETATZERO) {
00125     set_etat_zero() ; 
00126     return ; 
00127     }
00128 
00129     const Map* mp_d = cm_d.mp ; // Departure mapping
00130 
00131     // Protections
00132     // -----------
00133     int align = (mp->get_bvect_cart()).get_align() ;
00134 
00135     assert( align  * (mp_d->get_bvect_cart()).get_align() == -1 ) ; 
00136     
00137     assert(cm_d.etat == ETATQCQ) ;
00138 
00139     if (cm_d.dzpuis != 0) {
00140     cout << 
00141     "Cmp::import_anti_asymy : the dzpuis of the Cmp to be imported"
00142       << " must be zero !" << endl ; 
00143     abort() ; 
00144     }
00145 
00146 
00147     const Mg3d* mg_a = mp->get_mg() ; 
00148     assert(mg_a->get_type_p() == NONSYM) ; 
00149     
00150     
00151     int nz_a = mg_a->get_nzone() ; 
00152     assert(nzet <= nz_a) ;     
00153 
00154     const Valeur& va_d = cm_d.va ; 
00155     va_d.coef() ;       // The coefficients are required
00156     
00157 
00158     // Preparations for storing the result in *this 
00159     // --------------------------------------------
00160     del_t() ;   // delete all previously computed derived quantities
00161     
00162     set_etat_qcq() ;        // Set the state to ETATQCQ
00163     
00164     va.set_etat_c_qcq() ;   // Allocates the memory for the Mtbl va.c
00165                 //  if it does not exist already
00166     va.c->set_etat_qcq() ;  // Allocates the memory for the Tbl's in each
00167                 //  domain if they do not exist already
00168 
00169 
00170     // Departure (x,y,z) coordinates of the origin of the Arrival mapping :
00171 
00172     double xx_a, yy_a, zz_a ; 
00173     if (align == 1) {
00174     xx_a = mp_d->get_ori_x() - mp->get_ori_x() ; 
00175     yy_a = mp_d->get_ori_y() - mp->get_ori_y() ; 
00176     }
00177     else {
00178     xx_a = mp->get_ori_x() - mp_d->get_ori_x() ; 
00179     yy_a = mp->get_ori_y() - mp_d->get_ori_y() ; 
00180     }
00181     zz_a = mp->get_ori_z() - mp_d->get_ori_z() ; 
00182 
00183     
00184     // r, theta, phi, x, y and z on the Arrival mapping 
00185     //  update of the corresponding Coord's if necessary
00186     
00187     if ( (mp->r).c == 0x0 ) (mp->r).fait() ; 
00188     if ( (mp->tet).c == 0x0 ) (mp->tet).fait() ; 
00189     if ( (mp->phi).c == 0x0 ) (mp->phi).fait() ; 
00190     if ( (mp->x).c == 0x0 ) (mp->x).fait() ; 
00191     if ( (mp->y).c == 0x0 ) (mp->y).fait() ; 
00192     if ( (mp->z).c == 0x0 ) (mp->z).fait() ; 
00193 
00194     const Mtbl* mr_a = (mp->r).c ; 
00195     const Mtbl* mtet_a = (mp->tet).c ; 
00196     const Mtbl* mphi_a = (mp->phi).c ; 
00197     const Mtbl* mx_a = (mp->x).c ;
00198     const Mtbl* my_a = (mp->y).c ;
00199     const Mtbl* mz_a = (mp->z).c ;
00200 
00201     Param par_precis ;      // Required precision in the method Map::val_lx
00202     int nitermax = 100 ;    // Maximum number of iteration in the secant method
00203     int niter ; 
00204     double precis = 1e-15 ; // Absolute precision in the secant method
00205     par_precis.add_int(nitermax) ;  
00206     par_precis.add_int_mod(niter) ; 
00207     par_precis.add_double(precis) ; 
00208 
00209 
00210     // Loop of the Arrival domains where the computation is to be performed
00211     // --------------------------------------------------------------------
00212     
00213     for (int l=0; l < nzet; l++) {
00214     
00215     int nr = mg_a->get_nr(l) ;
00216     int nt = mg_a->get_nt(l) ;
00217     int np = mg_a->get_np(l) ;
00218     int ntnr = nt*nr ;  
00219     
00220     const double* pr_a = mr_a->t[l]->t ;      // Pointer on the values of r
00221     const double* ptet_a = mtet_a->t[l]->t ;  // Pointer on the values of theta
00222     const double* pphi_a = mphi_a->t[l]->t ;  // Pointer on the values of phi
00223     const double* px_a = mx_a->t[l]->t ;      // Pointer on the values of X
00224     const double* py_a = my_a->t[l]->t ;      // Pointer on the values of Y
00225     const double* pz_a = mz_a->t[l]->t ;      // Pointer on the values of Z
00226     
00227     (va.c->t[l])->set_etat_qcq() ;       // Allocates the array of double to
00228                          //  store the result 
00229     double* ptx = (va.c->t[l])->t ;      // Pointer on the allocated array
00230     
00231     
00232     // Loop on half the grid points in the considered arrival domain
00233     // (the other half will be obtained by antisymmetry with respect to
00234     //  the y=0 plane). 
00235         
00236     // Case k=0 (phi=0) : the function is zero (by antisymmetry)
00237     for (int i=0; i<ntnr; i++) {
00238         *ptx = 0 ;   
00239         ptx++ ;   // next point
00240     }
00241     
00242     // Go to k=1 :
00243     pr_a += ntnr ;  
00244     ptet_a += ntnr ;  
00245     pphi_a += ntnr ; 
00246     px_a += ntnr ;  
00247     py_a += ntnr ;  
00248     pz_a += ntnr ;  
00249 
00250     for (int k=1 ; k<np/2 ; k++) {    // np/2 : ~ half the grid
00251         for (int j=0 ; j<nt ; j++) {
00252         for (int i=0 ; i<nr ; i++) {
00253 
00254             double r = *pr_a ; 
00255             double rd, tetd, phid ;
00256             if (r == __infinity) {
00257             rd = r ;
00258             tetd = *ptet_a ;
00259             phid = *pphi_a + M_PI ;
00260             if (phid < 0) phid += 2*M_PI ;
00261             }
00262             else {
00263 
00264             // Cartesian coordinates on the Departure mapping
00265             double xd = - *px_a + xx_a ; 
00266             double yd = - *py_a + yy_a ; 
00267             double zd = *pz_a + zz_a ; 
00268 
00269             // Spherical coordinates on the Departure mapping
00270             double rhod2 = xd*xd + yd*yd ; 
00271             double rhod = sqrt( rhod2 ) ;
00272             rd = sqrt(rhod2 + zd*zd) ;
00273             tetd = atan2(rhod, zd) ;
00274             phid = atan2(yd, xd) ; 
00275             if (phid < 0) phid += 2*M_PI ;
00276             }           
00277 
00278 
00279             // NB: to increase the efficiency, the method Cmp::val_point
00280             //  is not invoked; the method Mtbl_cf::val_point is 
00281             //  called directly instead. 
00282 
00283             // Value of the grid coordinates (l,xi) corresponding to
00284             //  (rd,tetd,phid) :
00285             
00286             int ld ;        // domain index
00287             double xxd ;    // radial coordinate xi in [0,1] or [-1,1]
00288             mp_d->val_lx(rd, tetd, phid, par_precis, ld, xxd) ;
00289 
00290             // Value of the Departure Cmp at the obtained point:
00291             *ptx = va_d.c_cf->val_point_asymy(ld, xxd, tetd, phid) ;
00292 
00293             // Next point : 
00294             ptx++ ;   
00295             pr_a++ ;  
00296             ptet_a++ ;  
00297             pphi_a++ ; 
00298             px_a++ ;  
00299             py_a++ ;  
00300             pz_a++ ;  
00301 
00302         }
00303         }
00304     }
00305     
00306     // Case k=np/2 (phi=pi) : the function is zero (by antisymmetry)
00307     for (int i=0; i<ntnr; i++) {
00308         *ptx = 0 ;   
00309         ptx++ ;   // next point
00310     }
00311     
00312     // Go to k=np/2+1 :
00313     pr_a += ntnr ;  
00314     ptet_a += ntnr ;  
00315     pphi_a += ntnr ; 
00316     px_a += ntnr ;  
00317     py_a += ntnr ;  
00318     pz_a += ntnr ;  
00319 
00320     // The remaining points are obtained by antisymmetry with rspect to the
00321     //  y=0 plane
00322         
00323     for (int k=np/2+1 ; k<np ; k++) {
00324 
00325         // pointer on the value (already computed) at the point symmetric 
00326         // with respect to the plane y=0
00327         double* ptx_symy = (va.c->t[l])->t + (np-k)*nt*nr ;  
00328 
00329         // copy : 
00330         for (int j=0 ; j<nt ; j++) {
00331         for (int i=0 ; i<nr ; i++) {
00332             *ptx = - (*ptx_symy) ; 
00333             ptx++ ;
00334             ptx_symy++ ; 
00335         }
00336         }
00337     } 
00338     
00339         
00340     }   // End of the loop on the Arrival domains
00341     
00342     // In the remaining domains, *this is set to zero:
00343     // ----------------------------------------------
00344     
00345     if (nzet < nz_a) {
00346     annule(nzet, nz_a - 1) ; 
00347     }
00348     
00349     // Treatment of dzpuis
00350     // -------------------
00351     
00352     set_dzpuis(0) ; 
00353 
00354 }
00355 
00356 
00357         //-------------------------------------//
00358         //   Case of aligned Cartesian axis    //
00359         //-------------------------------------//
00360 
00361 
00362 void Cmp::import_align_asymy(int nzet, const Cmp& cm_d) {
00363     
00364     // Trivial case : null Cmp
00365     // ------------------------
00366     
00367     if (cm_d.etat == ETATZERO) {
00368     set_etat_zero() ; 
00369     return ; 
00370     }
00371 
00372     const Map* mp_d = cm_d.mp ; // Departure mapping
00373 
00374     // Protections
00375     // -----------
00376     int align = (mp->get_bvect_cart()).get_align() ;
00377 
00378     assert( align  * (mp_d->get_bvect_cart()).get_align() == 1 ) ; 
00379     
00380     assert(cm_d.etat == ETATQCQ) ;
00381 
00382     if (cm_d.dzpuis != 0) {
00383     cout << 
00384     "Cmp::import_align_asymy : the dzpuis of the Cmp to be imported"
00385     << " must be zero !" << endl ; 
00386     abort() ; 
00387     }
00388 
00389 
00390     const Mg3d* mg_a = mp->get_mg() ; 
00391     assert(mg_a->get_type_p() == NONSYM) ; 
00392 
00393     int nz_a = mg_a->get_nzone() ; 
00394     assert(nzet <= nz_a) ;     
00395 
00396     const Valeur& va_d = cm_d.va ; 
00397     va_d.coef() ;       // The coefficients are required
00398     
00399 
00400     // Preparations for storing the result in *this 
00401     // --------------------------------------------
00402     del_t() ;   // delete all previously computed derived quantities
00403     
00404     set_etat_qcq() ;        // Set the state to ETATQCQ
00405     
00406     va.set_etat_c_qcq() ;   // Allocates the memory for the Mtbl va.c
00407                 //  if it does not exist already
00408     va.c->set_etat_qcq() ;  // Allocates the memory for the Tbl's in each
00409                 //  domain if they do not exist already
00410 
00411 
00412     // Departure (x,y,z) coordinates of the origin of the Arrival mapping :
00413 
00414     double xx_a, yy_a, zz_a ; 
00415     if (align == 1) {
00416     xx_a = mp->get_ori_x() - mp_d->get_ori_x() ; 
00417     yy_a = mp->get_ori_y() - mp_d->get_ori_y() ; 
00418     }
00419     else {
00420     xx_a = mp_d->get_ori_x() - mp->get_ori_x() ; 
00421     yy_a = mp_d->get_ori_y() - mp->get_ori_y() ; 
00422     }
00423     zz_a = mp->get_ori_z() - mp_d->get_ori_z() ; 
00424 
00425     
00426     // r, theta, phi, x, y and z on the Arrival mapping 
00427     //  update of the corresponding Coord's if necessary
00428     
00429     if ( (mp->r).c == 0x0 ) (mp->r).fait() ; 
00430     if ( (mp->tet).c == 0x0 ) (mp->tet).fait() ; 
00431     if ( (mp->phi).c == 0x0 ) (mp->phi).fait() ; 
00432     if ( (mp->x).c == 0x0 ) (mp->x).fait() ; 
00433     if ( (mp->y).c == 0x0 ) (mp->y).fait() ; 
00434     if ( (mp->z).c == 0x0 ) (mp->z).fait() ; 
00435 
00436     const Mtbl* mr_a = (mp->r).c ; 
00437     const Mtbl* mtet_a = (mp->tet).c ; 
00438     const Mtbl* mphi_a = (mp->phi).c ; 
00439     const Mtbl* mx_a = (mp->x).c ;
00440     const Mtbl* my_a = (mp->y).c ;
00441     const Mtbl* mz_a = (mp->z).c ;
00442 
00443     Param par_precis ;      // Required precision in the method Map::val_lx
00444     int nitermax = 100 ;    // Maximum number of iteration in the secant method
00445     int niter ; 
00446     double precis = 1e-15 ; // Absolute precision in the secant method
00447     par_precis.add_int(nitermax) ;  
00448     par_precis.add_int_mod(niter) ; 
00449     par_precis.add_double(precis) ; 
00450 
00451 
00452     // Loop of the Arrival domains where the computation is to be performed
00453     // --------------------------------------------------------------------
00454     
00455     for (int l=0; l < nzet; l++) {
00456     
00457     int nr = mg_a->get_nr(l) ;
00458     int nt = mg_a->get_nt(l) ;
00459     int np = mg_a->get_np(l) ;
00460     int ntnr = nt*nr ;      
00461     
00462     const double* pr_a = mr_a->t[l]->t ;      // Pointer on the values of r
00463     const double* ptet_a = mtet_a->t[l]->t ;  // Pointer on the values of theta
00464     const double* pphi_a = mphi_a->t[l]->t ;  // Pointer on the values of phi
00465     const double* px_a = mx_a->t[l]->t ;      // Pointer on the values of X
00466     const double* py_a = my_a->t[l]->t ;      // Pointer on the values of Y
00467     const double* pz_a = mz_a->t[l]->t ;      // Pointer on the values of Z
00468     
00469     (va.c->t[l])->set_etat_qcq() ;       // Allocates the array of double to
00470                          //  store the result 
00471     double* ptx = (va.c->t[l])->t ;      // Pointer on the allocated array
00472     
00473     
00474     
00475     // Loop on half the grid points in the considered arrival domain
00476     // (the other half will be obtained by antisymmetry with respect to
00477     //  the y=0 plane). 
00478         
00479     // Case k=0 (phi=0) : the function is zero (by antisymmetry)
00480     for (int i=0; i<ntnr; i++) {
00481         *ptx = 0 ;   
00482         ptx++ ;   // next point
00483     }
00484     
00485     // Go to k=1 :
00486     pr_a += ntnr ;  
00487     ptet_a += ntnr ;  
00488     pphi_a += ntnr ; 
00489     px_a += ntnr ;  
00490     py_a += ntnr ;  
00491     pz_a += ntnr ;  
00492 
00493     for (int k=1 ; k<np/2 ; k++) {    // np/2 : ~ half the grid
00494         for (int j=0 ; j<nt ; j++) {
00495         for (int i=0 ; i<nr ; i++) {
00496 
00497             double r = *pr_a ; 
00498             double rd, tetd, phid ;
00499             if (r == __infinity) {
00500             rd = r ;
00501             tetd = *ptet_a ;
00502             phid = *pphi_a ;
00503             }
00504             else {
00505 
00506             // Cartesian coordinates on the Departure mapping
00507             double xd = *px_a + xx_a ; 
00508             double yd = *py_a + yy_a ; 
00509             double zd = *pz_a + zz_a ; 
00510 
00511             // Spherical coordinates on the Departure mapping
00512             double rhod2 = xd*xd + yd*yd ; 
00513             double rhod = sqrt( rhod2 ) ;
00514             rd = sqrt(rhod2 + zd*zd) ;
00515             tetd = atan2(rhod, zd) ;
00516             phid = atan2(yd, xd) ; 
00517             if (phid < 0) phid += 2*M_PI ;
00518             }           
00519 
00520 
00521             // NB: to increase the efficiency, the method Cmp::val_point
00522             //  is not invoked; the method Mtbl_cf::val_point is 
00523             //  called directly instead. 
00524 
00525             // Value of the grid coordinates (l,xi) corresponding to
00526             //  (rd,tetd,phid) :
00527             
00528             int ld ;        // domain index
00529             double xxd ;    // radial coordinate xi in [0,1] or [-1,1]
00530             mp_d->val_lx(rd, tetd, phid, par_precis, ld, xxd) ;
00531 
00532             // Value of the Departure Cmp at the obtained point:
00533             *ptx = va_d.c_cf->val_point_asymy(ld, xxd, tetd, phid) ;
00534 
00535             // Next point : 
00536             ptx++ ;   
00537             pr_a++ ;  
00538             ptet_a++ ;  
00539             pphi_a++ ; 
00540             px_a++ ;  
00541             py_a++ ;  
00542             pz_a++ ;  
00543 
00544         }
00545         }
00546     }   
00547     
00548         
00549     // Case k=np/2 (phi=pi) : the function is zero (by antisymmetry)
00550     for (int i=0; i<ntnr; i++) {
00551         *ptx = 0 ;   
00552         ptx++ ;   // next point
00553     }
00554     
00555     // Go to k=np/2+1 :
00556     pr_a += ntnr ;  
00557     ptet_a += ntnr ;  
00558     pphi_a += ntnr ; 
00559     px_a += ntnr ;  
00560     py_a += ntnr ;  
00561     pz_a += ntnr ;  
00562 
00563     // The remaining points are obtained by antisymmetry with respect to the
00564     //  y=0 plane
00565         
00566     for (int k=np/2+1 ; k<np ; k++) {
00567 
00568         // pointer on the value (already computed) at the point symmetric 
00569         // with respect to the plane y=0
00570         double* ptx_symy = (va.c->t[l])->t + (np-k)*nt*nr ;  
00571 
00572         // copy : 
00573         for (int j=0 ; j<nt ; j++) {
00574         for (int i=0 ; i<nr ; i++) {
00575             *ptx = - (*ptx_symy) ; 
00576             ptx++ ;
00577             ptx_symy++ ; 
00578         }
00579         }
00580     } 
00581 
00582     }   // End of the loop on the Arrival domains
00583     
00584     // In the remaining domains, *this is set to zero:
00585     // ----------------------------------------------
00586     
00587     if (nzet < nz_a) {
00588     annule(nzet, nz_a - 1) ; 
00589     }
00590     
00591     // Treatment of dzpuis
00592     // -------------------
00593     
00594     set_dzpuis(0) ; 
00595 
00596 }

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