00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <assert.h>
00047 #include <math.h>
00048
00049
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) ;
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. ;
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 }
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 }
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) ;
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 }
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 }
00385 }
00386 }
00387