scalar_match_tau.C

00001 /*
00002  * Function to perform a matching across domains + imposition of boundary conditions
00003  * at the outer domain and regularity condition at the center.
00004  */
00005 
00006 /*
00007  *   Copyright (c) 2008  Jerome Novak
00008  *
00009  *   This file is part of LORENE.
00010  *
00011  *   LORENE is free software; you can redistribute it and/or modify
00012  *   it under the terms of the GNU General Public License version 2
00013  *   as published by the Free Software Foundation.
00014  *
00015  *   LORENE is distributed in the hope that it will be useful,
00016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *   GNU General Public License for more details.
00019  *
00020  *   You should have received a copy of the GNU General Public License
00021  *   along with LORENE; if not, write to the Free Software
00022  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 char scalar_match_tau_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_match_tau.C,v 1.3 2012/02/06 12:59:07 j_novak Exp $" ;
00027 
00028 /*
00029  * $Id: scalar_match_tau.C,v 1.3 2012/02/06 12:59:07 j_novak Exp $
00030  * $Log: scalar_match_tau.C,v $
00031  * Revision 1.3  2012/02/06 12:59:07  j_novak
00032  * Correction of some errors.
00033  *
00034  * Revision 1.2  2008/08/20 13:23:43  j_novak
00035  * The shift in quantum number l (e.g. for \tilde{B}) is now taken into account.
00036  *
00037  * Revision 1.1  2008/05/24 15:05:22  j_novak
00038  * New method Scalar::match_tau to match the output of an explicit time-marching scheme with the tau method.
00039  *
00040  *
00041  * $Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_match_tau.C,v 1.3 2012/02/06 12:59:07 j_novak Exp $
00042  *
00043  */
00044 
00045 // C headers
00046 #include <assert.h>
00047 #include <math.h>
00048 
00049 // Lorene headers
00050 #include "tensor.h"
00051 #include "matrice.h"
00052 #include "proto.h"
00053 #include "param.h"
00054 
00055 void Scalar::match_tau(Param& par_bc, Param* par_mat) {
00056 
00057     const Map_af* mp_aff = dynamic_cast<const Map_af*>(mp) ;
00058     assert(mp_aff != 0x0) ; //Only affine mapping for the moment
00059 
00060     const Mg3d& mgrid = *mp_aff->get_mg() ;
00061     assert(mgrid.get_type_r(0) == RARE)  ;
00062     assert (par_bc.get_n_tbl_mod() > 0) ;
00063     Tbl mu = par_bc.get_tbl_mod(0) ;
00064     if (etat == ETATZERO) {
00065     if (mu.get_etat() == ETATZERO) 
00066         return ;
00067     else
00068         annule_hard() ;
00069     }
00070 
00071     int nz = mgrid.get_nzone() ;
00072     int nzm1 = nz - 1 ;
00073     bool ced = (mgrid.get_type_r(nzm1) == UNSURR) ;
00074     assert(par_bc.get_n_int() >= 2);
00075     int domain_bc = par_bc.get_int(0) ;
00076     bool bc_ced = ((ced) && (domain_bc == nzm1)) ;
00077 
00078     int n_conditions = par_bc.get_int(1) ;
00079     assert ((n_conditions==1)||(n_conditions==2)) ;
00080     bool derivative = (n_conditions == 2) ;
00081     int dl = 0 ; int l_min = 0 ;
00082     if (par_bc.get_n_int() > 2) {
00083     assert(par_bc.get_n_int() == 4) ;
00084     dl = par_bc.get_int(2) ;
00085     l_min = par_bc.get_int(3) ;
00086     }
00087     int nt = mgrid.get_nt(0) ;
00088     int np = mgrid.get_np(0) ;
00089     assert (par_bc.get_n_double_mod() == 2) ;
00090     double c_val = par_bc.get_double_mod(0) ;
00091     double c_der = par_bc.get_double_mod(1) ;
00092     if (bc_ced) {
00093     c_val = 1 ;
00094     c_der = 0 ;
00095     mu.annule_hard() ;
00096     }
00097     if (mu.get_etat() == ETATZERO)
00098     mu.annule_hard() ;
00099     int system01_size = 1 ;
00100     int system_size = 2 ;
00101     for (int lz=1; lz<=domain_bc; lz++) {
00102         system01_size += n_conditions ;
00103         system_size += n_conditions ;
00104     }
00105     assert (etat != ETATNONDEF) ;
00106 
00107     bool need_matrices = true ;
00108     if (par_mat != 0x0)
00109     if (par_mat->get_n_matrice_mod() == 4) 
00110         need_matrices = false ;
00111     
00112     Matrice system_l0(system01_size, system01_size) ;
00113     Matrice system_l1(system01_size, system01_size) ;
00114     Matrice system_even(system_size, system_size) ;
00115     Matrice system_odd(system_size, system_size) ;    
00116     
00117     if (need_matrices) {
00118     system_l0.annule_hard() ;
00119     system_l1.annule_hard() ;
00120     system_even.annule_hard() ;
00121     system_odd.annule_hard() ;
00122     int index = 0 ; int index01 = 0 ;
00123     int nr = mgrid.get_nr(0) ;
00124     double alpha = mp_aff->get_alpha()[0] ; 
00125     system_even.set(index, index) = 1. ;
00126     system_even.set(index, index + 1) = -1. ; //C_{N-1} - C_N = \sum (-1)^i C_i
00127     system_odd.set(index, index) = -(2.*nr - 5.)/alpha ; 
00128     system_odd.set(index, index+1) = (2.*nr - 3.)/alpha ;
00129     index++ ;
00130     if (domain_bc == 0) {
00131         system_l0.set(index01, index01) = c_val + c_der*4.*(nr-1)*(nr-1)/alpha ;
00132         system_l1.set(index01, index01) = c_val + c_der*(2*nr-3)*(2*nr-3)/alpha ;
00133         index01++ ;
00134         system_even.set(index, index-1) = c_val + c_der*4.*(nr-2)*(nr-2)/alpha ;
00135         system_even.set(index, index) = c_val + c_der*4.*(nr-1)*(nr-1)/alpha ;
00136         system_odd.set(index, index-1) = c_val + c_der*(2*nr-5)*(2*nr-5)/alpha ;
00137         system_odd.set(index, index) = c_val + c_der*(2*nr-3)*(2*nr-3)/alpha ;
00138         index++ ;
00139     }
00140     else {
00141         system_l0.set(index01, index01) = 1. ;
00142         system_l1.set(index01, index01) = 1. ;
00143         system_even.set(index, index-1) = 1. ;
00144         system_even.set(index, index) = 1. ;
00145         system_odd.set(index, index-1) = 1. ;
00146         system_odd.set(index, index) = 1. ;
00147         if (derivative) {
00148         system_l0.set(index01+1, index01) = 4*(nr-1)*(nr-1)/alpha ;
00149         system_l1.set(index01+1, index01) = (2*nr-3)*(2*nr-3)/alpha ;
00150         system_even.set(index+1, index-1) = 4*(nr-2)*(nr-2)/alpha ;
00151         system_even.set(index+1, index) = 4*(nr-1)*(nr-1)/alpha ;
00152         system_odd.set(index+1, index-1) = (2*nr-5)*(2*nr-5)/alpha ;
00153         system_odd.set(index+1, index) = (2*nr-3)*(2*nr-3)/alpha ;
00154         }
00155     }
00156     for (int lz=1; lz<=domain_bc; lz++) {
00157         nr = mgrid.get_nr(lz) ;
00158         alpha = mp_aff->get_alpha()[lz] ;
00159         if ((lz == domain_bc)&&(bc_ced))
00160         alpha = -0.25/alpha ;
00161         system_l0.set(index01, index01+1) = 1. ;
00162         system_l0.set(index01, index01+2) = -1. ;
00163         system_l1.set(index01, index01+1) = 1. ;
00164         system_l1.set(index01, index01+2) = -1. ;
00165         index01++ ;
00166         system_even.set(index, index+1) = 1. ;
00167         system_even.set(index, index+2) = -1. ;
00168         system_odd.set(index, index+1) = 1. ;
00169         system_odd.set(index, index+2) = -1. ;
00170         index++ ;
00171         if (derivative) {
00172         system_l0.set(index01, index01) = -(nr-2)*(nr-2)/alpha ;
00173         system_l0.set(index01, index01+1) = (nr-1)*(nr-1)/alpha ;
00174         system_l1.set(index01, index01) = -(nr-2)*(nr-2)/alpha ;
00175         system_l1.set(index01, index01+1) = (nr-1)*(nr-1)/alpha ;
00176         index01++ ;
00177         system_even.set(index, index) = -(nr-2)*(nr-2)/alpha ;
00178         system_even.set(index, index+1) = (nr-1)*(nr-1)/alpha ;
00179         system_odd.set(index, index) = -(nr-2)*(nr-2)/alpha ;
00180         system_odd.set(index, index+1) = (nr-1)*(nr-1)/alpha ;
00181         index++ ;
00182         }
00183     
00184         if (lz == domain_bc) {
00185         system_l0.set(index01, index01-1) = c_val + c_der*(nr-2)*(nr-2)/alpha ;
00186         system_l0.set(index01, index01) = c_val + c_der*(nr-1)*(nr-1)/alpha ;
00187         system_l1.set(index01, index01-1) = c_val + c_der*(nr-2)*(nr-2)/alpha ;
00188         system_l1.set(index01, index01) = c_val + c_der*(nr-1)*(nr-1)/alpha ;
00189         index01++ ; 
00190         system_even.set(index, index-1) = c_val + c_der*(nr-2)*(nr-2)/alpha ;
00191         system_even.set(index, index) = c_val + c_der*(nr-1)*(nr-1)/alpha ;
00192         system_odd.set(index, index-1) = c_val + c_der*(nr-2)*(nr-2)/alpha ;
00193         system_odd.set(index, index) = c_val + c_der*(nr-1)*(nr-1)/alpha ;
00194         index++ ;
00195         }
00196         else {
00197         system_l0.set(index01, index01-1) = 1. ;
00198         system_l0.set(index01, index01) = 1. ;
00199         system_l1.set(index01, index01-1) = 1. ;
00200         system_l1.set(index01, index01) = 1. ;
00201         system_even.set(index, index-1) = 1. ;
00202         system_even.set(index, index) = 1. ;
00203         system_odd.set(index, index-1) = 1. ;
00204         system_odd.set(index, index) = 1. ;
00205         if (derivative) {
00206             system_l0.set(index01+1, index01-1) = (nr-2)*(nr-2)/alpha ;
00207             system_l0.set(index01+1, index01) = (nr-1)*(nr-1)/alpha ;
00208             system_l1.set(index01+1, index01-1) = (nr-2)*(nr-2)/alpha ;
00209             system_l1.set(index01+1, index01) = (nr-1)*(nr-1)/alpha ;
00210             system_even.set(index+1, index-1) = (nr-2)*(nr-2)/alpha ;
00211             system_even.set(index+1, index) = (nr-1)*(nr-1)/alpha ;
00212             system_odd.set(index+1, index-1) = (nr-2)*(nr-2)/alpha ;
00213             system_odd.set(index+1, index) = (nr-1)*(nr-1)/alpha ;
00214         }       
00215         }
00216     } // End of loop on lz
00217 
00218     assert(index01 == system01_size) ;
00219     assert(index == system_size) ;
00220     system_l0.set_lu() ;
00221     system_l1.set_lu() ;
00222     system_even.set_lu() ;
00223     system_odd.set_lu() ;
00224     if (par_mat != 0x0) {
00225         Matrice* pmat0 = new Matrice(system_l0) ;
00226         Matrice* pmat1 = new Matrice(system_l1) ;
00227         Matrice* pmat2 = new Matrice(system_even) ;
00228         Matrice* pmat3 = new Matrice(system_odd) ;
00229         par_mat->add_matrice_mod(*pmat0, 0) ;
00230         par_mat->add_matrice_mod(*pmat1, 1) ;
00231         par_mat->add_matrice_mod(*pmat2, 2) ;
00232         par_mat->add_matrice_mod(*pmat3, 3) ;
00233     }
00234     }// End of if (need_matrices) ...
00235 
00236     const Matrice& sys_l0 = (need_matrices ? system_l0 : par_mat->get_matrice_mod(0) ) ;
00237     const Matrice& sys_l1 = (need_matrices ? system_l1 : par_mat->get_matrice_mod(1) ) ;
00238     const Matrice& sys_even = (need_matrices ? system_even : 
00239                    par_mat->get_matrice_mod(2) ) ;
00240     const Matrice& sys_odd = (need_matrices ? system_odd : 
00241                   par_mat->get_matrice_mod(3) ) ;
00242 
00243     va.coef() ;
00244     va.ylm() ;
00245     const Base_val& base = get_spectral_base() ;
00246     Mtbl_cf& coef = *va.c_cf ;
00247     if (va.c != 0x0) {
00248     delete va.c ;
00249     va.c = 0x0 ;
00250     }
00251     int m_q, l_q, base_r ;
00252     for (int k=0; k<np+2; k++) {
00253     for (int j=0; j<nt; j++) {
00254         base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;//#0 here as domain index
00255         if ((nullite_plm(j, nt, k, np, base) == 1)&&(l_q >= l_min)) {
00256         l_q += dl ;
00257         int sys_size = (l_q < 2 ? system01_size : system_size) ;
00258         int nl = (l_q < 2 ? 1 : 2) ;
00259         Tbl rhs(sys_size) ; rhs.annule_hard() ;
00260         int index = 0 ;
00261         int pari = 1 ;
00262         double alpha = mp_aff->get_alpha()[0] ;
00263         int nr = mgrid.get_nr(0) ;
00264         if (l_q>=2) {
00265             if (base_r == R_CHEBP) {
00266             double val_c = 0.; pari = 1 ;
00267             for (int i=0; i<nr-nl; i++) {
00268                 val_c += pari*coef(0, k, j, i) ;
00269                 pari = -pari ;
00270             }
00271             rhs.set(index) = val_c ;
00272             }
00273             else {
00274             assert( base_r == R_CHEBI) ;
00275             double der_c = 0.; pari = 1 ;
00276             for (int i=0; i<nr-nl-1; i++) {
00277                 der_c += pari*(2*i+1)*coef(0, k, j, i) ;
00278                 pari = -pari ;
00279             }
00280             rhs.set(index) = der_c / alpha ;
00281             }
00282             index++ ;
00283         }
00284         double val_b = 0. ;
00285         double der_b =0. ;
00286         if (base_r == R_CHEBP) {
00287             for (int i=0; i<nr-nl; i++) {
00288             val_b += coef(0, k, j, i) ;
00289             der_b += 4*i*i*coef(0, k, j, i) ;
00290             }
00291         }
00292         else {
00293             assert(base_r == R_CHEBI) ;
00294             for (int i=0; i<nr-nl-1; i++) {
00295             val_b += coef(0, k, j, i) ;
00296             der_b += (2*i+1)*(2*i+1)*coef(0, k, j, i) ;         
00297             }
00298         }
00299         if (domain_bc==0) {
00300             rhs.set(index) = mu(k,j) - c_val*val_b - c_der*der_b/alpha ;
00301             index++ ;
00302         }
00303         else {
00304             rhs.set(index) = -val_b ;
00305             if (derivative) 
00306             rhs.set(index+1) = -der_b/alpha ;
00307         }
00308         for (int lz=1; lz<=domain_bc; lz++) {
00309             alpha = mp_aff->get_alpha()[lz] ;
00310             if ((lz == domain_bc)&&(bc_ced))
00311             alpha = -0.25/alpha ;
00312             nr = mgrid.get_nr(lz) ;
00313             int nr_lim = nr - n_conditions ;
00314             val_b = 0 ; pari = 1 ;
00315             for (int i=0; i<nr_lim; i++) { 
00316             val_b += pari*coef(lz, k, j, i) ;
00317             pari = -pari ;
00318             }
00319             rhs.set(index) += val_b ;
00320             index++ ;
00321             if (derivative) {
00322             der_b = 0 ; pari = -1 ;
00323             for (int i=0; i<nr_lim; i++) {
00324                 der_b += pari*i*i*coef(lz, k, j, i) ;
00325                 pari = -pari ;
00326             }
00327             rhs.set(index) += der_b/alpha ;
00328             index++ ;
00329             }
00330             val_b = 0 ;
00331             for (int i=0; i<nr_lim; i++)
00332             val_b += coef(lz, k, j, i) ;
00333             der_b = 0 ;
00334             for (int i=0; i<nr_lim; i++) {
00335             der_b += i*i*coef(lz, k, j, i) ;
00336             }
00337             if (domain_bc==lz) {
00338             rhs.set(index) = mu(k,j) - c_val*val_b - c_der*der_b/alpha ;
00339             index++ ;
00340             }
00341             else {
00342             rhs.set(index) = -val_b ;
00343             if (derivative) rhs.set(index+1) = -der_b / alpha ;
00344             }
00345         }
00346         Tbl solut(sys_size);
00347         assert(l_q>=0) ;
00348         switch (l_q) {
00349             case 0 :
00350             solut = sys_l0.inverse(rhs) ;
00351             break ;
00352             case 1: 
00353             solut = sys_l1.inverse(rhs) ;
00354             break ;
00355             default:
00356             solut = (l_q%2 == 0 ? sys_even.inverse(rhs) : 
00357                  sys_odd.inverse(rhs)) ; 
00358         }
00359         index = 0 ;
00360         int dec = (base_r == R_CHEBP ? 0 : 1) ;
00361         nr = mgrid.get_nr(0) ;
00362         if (l_q>=2) {
00363             coef.set(0, k, j, nr-2-dec) = solut(index) ;
00364             index++ ;
00365         }
00366         coef.set(0, k, j, nr-1-dec) = solut(index) ;
00367         index++ ;
00368         if (base_r == R_CHEBI)
00369             coef.set(0, k, j, nr-1) = 0 ;
00370         for (int lz=1; lz<=domain_bc; lz++) {
00371           nr = mgrid.get_nr(lz) ;
00372           for (nl=1; nl<=n_conditions; nl++) {
00373             int ii = n_conditions - nl + 1 ;
00374             coef.set(lz, k, j, nr-ii) = solut(index) ;
00375             index++ ;
00376           }
00377         }
00378         } //End of nullite_plm
00379         else {
00380         for (int lz=0; lz<=domain_bc; lz++) 
00381             for (int i=0; i<mgrid.get_nr(lz); i++) 
00382             coef.set(lz, k, j, i) = 0 ;
00383         }
00384     } //End of loop on j
00385     } //End of loop on k
00386 }
00387 

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