scalar_import_symy.C

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

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