vector_divfree_A_1z.C

00001 /*
00002  *  Methods to impose the Dirac gauge: divergence-free condition.
00003  *
00004  *    (see file sym_tensor.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2006  Jerome Novak
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 version 2
00015  *   as published by the Free Software Foundation.
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 char sol_Dirac_A_1z_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/vector_divfree_A_1z.C,v 1.2 2009/10/23 13:18:46 j_novak Exp $" ;
00029 
00030 /*
00031  * $Id: vector_divfree_A_1z.C,v 1.2 2009/10/23 13:18:46 j_novak Exp $
00032  * $Log: vector_divfree_A_1z.C,v $
00033  * Revision 1.2  2009/10/23 13:18:46  j_novak
00034  * Minor modifications
00035  *
00036  * Revision 1.1  2008/08/27 09:01:27  jl_cornou
00037  * Methods for solving Dirac systems for divergence free vectors
00038  *
00039  *
00040  * $Header: /cvsroot/Lorene/C++/Source/Tensor/vector_divfree_A_1z.C,v 1.2 2009/10/23 13:18:46 j_novak Exp $
00041  *
00042  */
00043 
00044 
00045 // C headers
00046 #include <stdlib.h>
00047 #include <assert.h>
00048 #include <math.h>
00049 
00050 // Lorene headers
00051 #include "metric.h"
00052 #include "diff.h"
00053 #include "proto.h"
00054 #include "param.h"
00055 
00056 //----------------------------------------------------------------------------------
00057 //
00058 //                               sol_Dirac_A
00059 //              1 seule zone !
00060 //----------------------------------------------------------------------------------
00061 
00062 void Vector_divfree::sol_Dirac_A_1z(const Scalar& aaa, Scalar& tilde_vr, Scalar& tilde_eta,
00063                    const Param* par_bc) const {
00064 
00065     const Map_af* mp_aff = dynamic_cast<const Map_af*>(mp) ;
00066     assert(mp_aff != 0x0) ; //Only affine mapping for the moment
00067 
00068     const Mg3d& mgrid = *mp_aff->get_mg() ;
00069     assert(mgrid.get_type_r(0) == RARE)  ;
00070     if (aaa.get_etat() == ETATZERO) {
00071     tilde_vr = 0 ;
00072     tilde_eta = 0 ;
00073     return ;
00074     }
00075     assert(aaa.get_etat() != ETATNONDEF) ;
00076     int nz = mgrid.get_nzone() ;
00077     int nzm1 = nz - 1 ;
00078     bool ced = (mgrid.get_type_r(nzm1) == UNSURR) ;
00079     int n_shell = ced ? nz-2 : nzm1 ;
00080     int nz_bc = nzm1 ;
00081     if (par_bc != 0x0)
00082     if (par_bc->get_n_int() > 0) nz_bc = par_bc->get_int() ;
00083     n_shell = (nz_bc < n_shell ? nz_bc : n_shell) ;
00084 //#ifndef NDEBUG
00085 //    if (!cedbc) {
00086 //  assert(par_bc != 0x0) ;
00087 //  assert(par_bc->get_n_tbl_mod() >= 3) ;
00088 //    }
00089 //#endif
00090     int nt = mgrid.get_nt(0) ;
00091     int np = mgrid.get_np(0) ;
00092 
00093     Scalar source = aaa ;
00094     Scalar source_coq = aaa ;
00095     source_coq.annule_domain(0) ;
00096     if (ced) source_coq.annule_domain(nzm1) ;
00097     source_coq.mult_r() ;
00098     source.set_spectral_va().ylm() ;
00099     source_coq.set_spectral_va().ylm() ;
00100     Base_val base = source.get_spectral_base() ;
00101     base.mult_x() ;
00102 
00103     tilde_vr.annule_hard() ;
00104     tilde_vr.set_spectral_base(base) ;
00105     tilde_vr.set_spectral_va().set_etat_cf_qcq() ;
00106     tilde_vr.set_spectral_va().c_cf->annule_hard() ;   
00107     tilde_eta.annule_hard() ;
00108     tilde_eta.set_spectral_base(base) ;
00109     tilde_eta.set_spectral_va().set_etat_cf_qcq() ;
00110     tilde_eta.set_spectral_va().c_cf->annule_hard() ;   
00111  
00112     Mtbl_cf sol_vr(mgrid, base) ; sol_vr.annule_hard() ;
00113     Mtbl_cf sol_eta(mgrid, base) ; sol_eta.annule_hard() ;
00114     
00115     int l_q, m_q, base_r ;
00116 
00117     //---------------
00118     //--  NUCLEUS ---
00119     //---------------
00120     {int lz = 0 ;  
00121     int nr = mgrid.get_nr(lz) ;
00122     double alpha = mp_aff->get_alpha()[lz] ;
00123     Matrice ope(2*nr, 2*nr) ;
00124     ope.set_etat_qcq() ;
00125     
00126     for (int k=0 ; k<np+1 ; k++) {
00127     for (int j=0 ; j<nt ; j++) {
00128         // quantic numbers and spectral bases
00129         base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00130         if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 0)) {
00131         Diff_dsdx od(base_r, nr) ; const Matrice& md = od.get_matrice() ;
00132         Diff_sx os(base_r, nr) ; const Matrice& ms = os.get_matrice() ;
00133 
00134         for (int lin=0; lin<nr; lin++) 
00135             for (int col=0; col<nr; col++) 
00136             ope.set(lin,col) = md(lin,col) + 2*ms(lin,col) ;
00137         for (int lin=0; lin<nr; lin++) 
00138             for (int col=0; col<nr; col++) 
00139             ope.set(lin,col+nr) = -l_q*(l_q+1)*ms(lin,col) ;
00140         for (int lin=0; lin<nr; lin++) 
00141             for (int col=0; col<nr; col++) 
00142             ope.set(lin+nr,col) = -ms(lin,col) ;
00143         for (int lin=0; lin<nr; lin++) 
00144             for (int col=0; col<nr; col++) 
00145             ope.set(lin+nr,col+nr) = md(lin,col) + ms(lin,col) ;
00146 
00147         ope *= 1./alpha ;
00148         int ind1 = nr ;
00149         
00150         if (l_q==1) {
00151         ind1 += 1 ;
00152         int pari = 1 ;
00153         for (int col=0 ; col<nr; col++) {
00154         ope.set(nr-1,col) = pari ;
00155         ope.set(nr-1,col+nr) = -pari ;
00156         pari = - pari ;
00157         }
00158         for (int col=0 ; col<nr ; col++) {
00159         ope.set(2*nr-1,col+nr)=1 ;
00160             }
00161         }
00162         
00163         else{
00164         for (int col=0; col<2*nr; col++) {
00165             ope.set(ind1+nr-2, col) = 0 ;
00166         }
00167         for (int col=nr; col<2*nr; col++) 
00168             ope.set(ind1+nr-2, col) = 1 ;
00169         for (int col=0; col<2*nr; col++) {
00170             ope.set(nr-1, col) = 0 ;
00171             ope.set(2*nr-1, col) = 0 ;
00172         }
00173         int pari = 1 ;
00174         if (base_r == R_CHEBP) {
00175             for (int col=0; col<nr; col++) {
00176             ope.set(nr-1, col) = pari ;
00177             ope.set(2*nr-1, col+nr) = pari ;
00178             pari = - pari ;
00179             }
00180         }
00181         else { //In the odd case, the last coefficient must be zero!
00182             ope.set(nr-1, nr-1) = 1 ;
00183             ope.set(2*nr-1, 2*nr-1) = 1 ;
00184         }
00185                 
00186         }
00187 
00188         ope.set_lu() ;
00189         
00190         Tbl sec(2*nr) ;
00191         sec.set_etat_qcq() ;
00192         for (int lin=0; lin<nr; lin++)
00193             sec.set(lin) = 0 ;
00194         for (int lin=0; lin<nr; lin++) 
00195             sec.set(nr+lin) = (*source.get_spectral_va().c_cf)
00196             (lz, k, j, lin) ;
00197         sec.set(2*nr-1) = 0 ;
00198 
00199         
00200 
00201 /*      // BC is here
00202         if ((l_q==2)&&(k==3))  {
00203         sec.set(ind1+nr-2) = -5./2. ; }
00204         else { sec.set(ind1+nr-2) = 0 ; }*/
00205 
00206 
00207  
00208         Tbl sol = ope.inverse(sec) ;
00209                 
00210         for (int i=0; i<nr; i++) {
00211             sol_vr.set(lz, k, j, i) = sol(i) ;
00212             sol_eta.set(lz, k, j, i) = sol(i+nr) ;
00213         }
00214         if ((l_q==2)&&(k==3))  {
00215         cout << " ========================== " << endl ;
00216         cout << " Operateur                  " << endl ;
00217         cout << " ========================== " << endl ;
00218         cout << ope << endl ;
00219         cout << " ========================== " << endl ;
00220         cout << " Second membre              " << endl ;
00221         cout << " ========================== " << endl ;
00222         cout << sec << endl ;
00223         cout << " ========================== " << endl ;
00224         cout << " Solution                   " << endl ;
00225         cout << " ========================== " << endl ;
00226         cout << sol << endl ;
00227 
00228         }
00229         }
00230     }
00231     }
00232   }
00233   
00234     Mtbl_cf& mvr = *tilde_vr.set_spectral_va().c_cf ;
00235     Mtbl_cf& meta = *tilde_eta.set_spectral_va().c_cf ;
00236     
00237     Mtbl_cf d_vr = sol_vr ; 
00238     Mtbl_cf d_eta = sol_eta ; 
00239     
00240     
00241     // Loop on l and m
00242     //----------------
00243     for (int k=0 ; k<np+1 ; k++)
00244     for (int j=0 ; j<nt ; j++) {
00245         base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;
00246         if ((nullite_plm(j, nt, k, np, base) == 1) && (l_q > 0)) {
00247         // everything is put to the right place...
00248         //----------------------------------------
00249         int nr = mgrid.get_nr(0) ; //nucleus
00250         for (int i=0 ; i<nr ; i++) {
00251             mvr.set(0, k, j, i) = sol_vr(0, k, j, i) ;
00252             meta.set(0, k, j, i) = sol_eta(0, k, j, i) ;
00253         }
00254         } // End of nullite_plm  
00255     } //End of loop on theta
00256     
00257         
00258     if (tilde_vr.set_spectral_va().c != 0x0) 
00259     delete tilde_vr.set_spectral_va().c ;
00260     tilde_vr.set_spectral_va().c = 0x0 ;
00261     tilde_vr.set_spectral_va().ylm_i() ;
00262 
00263     if (tilde_eta.set_spectral_va().c != 0x0) 
00264     delete tilde_eta.set_spectral_va().c ;
00265     tilde_eta.set_spectral_va().c = 0x0 ;
00266     tilde_eta.set_spectral_va().ylm_i() ;
00267 
00268 } 

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