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
00027
00028
00029 #define DIEL_GAMMA_NEGATIVE 1
00030
00031 #include <rl_DielectricLayer.h>
00032
00033 #include <cstring>
00034 #include <cstdio>
00035
00036 #include <mathconst/mathconst.h>
00037
00038 #include <iomanip>
00039
00040 using namespace std;
00041
00042
00043
00044
00045
00046 rl_DielectricLayer::
00047 ~rl_DielectricLayer()
00048 {
00049 if ( name_ ) { delete [] name_; }
00050 }
00051
00052
00053
00054
00055 rl_DielectricLayer::
00056 rl_DielectricLayer( char const layer_name[] )
00057 throw ( rl_Exception )
00058 : diel_info_()
00059 , thickness_(-1.0)
00060 , zcoat_(-1.0)
00061 , alpha_(0.0)
00062 , gamma_(0.0)
00063 , rtype_(rl_Traits::ERoughNone)
00064 , srough_(0.0)
00065 , lambda_(826.5)
00066 , prop_( complex(1.0,0.0) )
00067 , kt_perp_( complex(0.0,0.0) )
00068 , phase_factor_(0.0)
00069 , rflcoef_()
00070 , t_ij_()
00071 , t_ji_()
00072 , is_substrate_(rl_Traits::False)
00073 {
00074 try {
00075
00076 if ( layer_name )
00077 {
00078 name_ = new char[strlen(layer_name)+1];
00079 }
00080 else
00081 {
00082 name_ = new char[1];
00083 *name_ = '\0';
00084 }
00085
00086 } catch ( std::exception& bad_alloc ) {
00087
00088 char msg[] = "rl_DielectricLayer(layername): "
00089 "unable to allocate space for the layer name";
00090
00091 throw rl_Exception( msg );
00092 }
00093 }
00094
00095
00096
00097
00098 rl_DielectricLayer::
00099 rl_DielectricLayer( rl_DielectricLayer const& other )
00100 throw ( rl_Exception )
00101 : diel_info_()
00102 , thickness_(-1.0)
00103 , zcoat_(-1.0)
00104 , alpha_(0.0)
00105 , gamma_(0.0)
00106 , rtype_(rl_Traits::ERoughNone)
00107 , srough_(0.0)
00108 , lambda_(826.5)
00109 , prop_( complex(1.0,0.0) )
00110 , kt_perp_( complex(0.0,0.0) )
00111 , phase_factor_(0.0)
00112 , rflcoef_()
00113 , t_ij_()
00114 , t_ji_()
00115 , is_substrate_(rl_Traits::False)
00116 {
00117 try {
00118
00119 if ( other.name_ )
00120 {
00121 name_ = new char[strlen(other.name_)+1];
00122 strcpy( name_, other.name_ );
00123 }
00124 else
00125 {
00126 name_ = new char[1];
00127 *name_ = '\0';
00128 }
00129
00130 } catch ( std::exception& bad_alloc ) {
00131
00132 char msg[] = "rl_DielectricLayer copy constructor: "
00133 "unable to allocate space for the layer name";
00134
00135 throw rl_Exception( msg );
00136 }
00137 }
00138
00139
00140
00141 rl_DielectricLayer::
00142 rl_DielectricLayer( rl_Traits::rl_DielectricPOD const* diel,
00143 std::size_t ndielpts,
00144 double layer_thickness,
00145 double roughness,
00146 rl_Traits::ERoughType roughness_type,
00147 rl_Traits::EInterpMode interp_mode,
00148 double bulkdensity,
00149 char const* layer_name,
00150 rl_Traits::Bool is_substrate )
00151 throw ( rl_Exception )
00152 {
00153 init( diel, ndielpts, layer_thickness, roughness, roughness_type,
00154 interp_mode, bulkdensity, layer_name, is_substrate );
00155 }
00156
00157
00158
00159 void rl_DielectricLayer::
00160 init( rl_Traits::rl_DielectricPOD const* diel,
00161 std::size_t ndielpts,
00162 double layer_thickness,
00163 double roughness,
00164 rl_Traits::ERoughType roughness_type,
00165 rl_Traits::EInterpMode interp_mode,
00166 double bulkdensity,
00167 char const* layer_name,
00168 rl_Traits::Bool is_substrate )
00169 throw ( rl_Exception )
00170 {
00171 diel_info_.init( diel, ndielpts, interp_mode, bulkdensity );
00172
00173 try {
00174
00175 if ( layer_name )
00176 {
00177 name_ = new char[strlen(layer_name)+1];
00178 strcpy( name_, layer_name );
00179 }
00180 else
00181 {
00182 name_ = new char[1];
00183 *name_ = '\0';
00184 }
00185
00186 } catch ( std::exception& bad_alloc ) {
00187
00188 char msg[256] = "rl_DielectricLayer::init(...): "
00189 "unable to allocate space for layer name";
00190
00191 throw rl_Exception( msg );
00192 }
00193
00194 thickness_ = layer_thickness;
00195 rtype_ = roughness_type;
00196 srough_ = roughness;
00197 is_substrate_ = is_substrate;
00198
00199 switch ( rtype_ )
00200 {
00201 case rl_Traits::ERoughDebyeWaller_RSAO :
00202 case rl_Traits::ERoughDebyeWaller_CSAO :
00203 case rl_Traits::ERoughDebyeWaller_Spiller :
00204 case rl_Traits::ERoughNevotCroce :
00205 case rl_Traits::ERoughModifiedDebyeWaller :
00206 case rl_Traits::ERoughNone : break;
00207
00208 default :
00209 { char msg[256];
00210 char const format[] = "rl_DielectricPODArray::init(...): "
00211 "Invalid roughness type was %d\n";
00212 sprintf( msg, format, rtype_ );
00213 throw rl_Exception( msg );
00214 }
00215 }
00216
00217 }
00218
00219
00220
00221
00222
00223 int rl_DielectricLayer::
00224 setup_for( double energy, double sinphi )
00225 {
00226 lambda_ = 12.39854 / energy;
00227
00228 if ( rtype_ != rl_Traits::ERoughNone )
00229 {
00230 phase_factor_ = 2.0 * M_PI * srough_ / lambda_;
00231 }
00232 else
00233 {
00234 phase_factor_ = 0.0;
00235 }
00236
00237 int rc = diel_info_.alpha_gamma( energy, alpha_, gamma_ );
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 double const difab = sinphi * sinphi - alpha_;
00258 double const sumab = sqrt( difab * difab + gamma_ * gamma_ );
00259
00260
00261
00262
00263
00264 double const a = sqrt( (sumab + difab) / 2.0 );
00265 double const tmp = (sumab - difab) / 2.0;
00266 double const b = (tmp >= 0.0) ? sqrt( tmp ) : sqrt( -tmp );
00267
00268
00269 #ifdef DIEL_GAMMA_GENERAL
00270 kt_perp_ = complex( a, ((gamma_ > 0.0) ? 1.0 : -1.0) * b );
00271 #else
00272 #ifdef DIEL_GAMMA_NEGATIVE
00273 kt_perp_ = complex( a, -b );
00274 #endif
00275 #ifdef DIEL_GAMMA_POSITIVE
00276 kt_perp_ = complex( a, b );
00277 #endif
00278 #endif
00279
00280 #if defined(DEBUG_DIELECTRICLAYER)
00281 fprintf(stdout, "\nDEBUG: ___SETUP_FOR___ %s ---------------------\n",
00282 name_ );
00283 fprintf(stdout, "kt_perp_ (%.15e %.15e)\n",
00284 kt_perp_.real(),
00285 kt_perp_.imag() );
00286 fprintf(stdout, "alpha_ gamma_ (%.15e %.15e)\n",
00287 alpha_, gamma_ );
00288 fprintf(stdout, "energy, sinphi (%.15e %.15e)\n",
00289 energy, sinphi );
00290 fprintf(stdout, "difab sumab tmp (%.15e %.15e %.15e)\n",
00291 difab, sumab, tmp );
00292 fprintf(stdout, "a, b (%.15e %.15e)\n",
00293 a, b );
00294 #endif
00295
00296
00297
00298
00299
00300 if (! rc )
00301 {
00302 if (! is_vacuum() && ! is_substrate() )
00303 {
00304 zcoat_ = 4.0 * M_PI * thickness_ / lambda_;
00305
00306
00307 prop_ = exp( complex( -b * zcoat_, -a * zcoat_ ) );
00308 #if defined(DEBUG_DIELECTRICLAYER)
00309 fprintf(stdout, "zcoat_ %.15e\n",
00310 zcoat_ );
00311 fprintf(stdout, "prop_ (r,i) (%.15e %.15e)\n",
00312 prop_.real(), prop_.imag() );
00313 #endif
00314 }
00315 }
00316 return rc;
00317 }
00318
00319
00320
00321
00322
00323 void rl_DielectricLayer::
00324 reflect_amp( rl_DielectricLayer const& upper, double sinphi )
00325 {
00326 double alpha_jm1 = upper.alpha_;
00327 double gamma_jm1 = upper.gamma_;
00328 double alpha_j = alpha_;
00329 double gamma_j = gamma_;
00330
00331 complex upper_delta_eps( -alpha_jm1, -gamma_jm1 );
00332 complex delta_eps( -alpha_j, -gamma_j );
00333
00334 complex eps_upper( upper_delta_eps + 1.0 );
00335 complex eps( delta_eps + 1.0 );
00336
00337 complex num_perp = upper.kt_perp_ - kt_perp_;
00338 complex denom_perp = upper.kt_perp_ + kt_perp_;
00339
00340 rflcoef_.perp() = num_perp / denom_perp;
00341
00342 #if defined(DEBUG_DIELECTRICLAYER)
00343 fprintf(stdout, "\nDEBUG: ___REFLECT_AMP___ ___AAA0___ --------\n");
00344 fprintf(stdout, "upper, this layer (%s %s)\n",
00345 upper.name_, name_);
00346 fprintf(stdout, "alpha, gamma (j-1): (%.15e, %.15e)\n",
00347 alpha_jm1, gamma_jm1);
00348 fprintf(stdout, "alpha, gamma (j): (%.15e, %.15e)\n",
00349 alpha_j, gamma_j);
00350 fprintf(stdout, "rflcoef (perp) (%.15e %.15e)\n",
00351 rflcoef_.perp().real(),
00352 rflcoef_.perp().imag() );
00353 fprintf(stdout, "num_perp (%.15e %.15e)\n",
00354 num_perp.real(),
00355 num_perp.imag() );
00356 fprintf(stdout, "denom_perp (%.15e %.15e)\n",
00357 denom_perp.real(),
00358 denom_perp.imag() );
00359 fprintf(stdout, "upper.kt_perp_ (%.15e %.15e)\n",
00360 upper.kt_perp_.real(),
00361 upper.kt_perp_.imag() );
00362 fprintf(stdout, "kt_perp_ %.15e %.15e)\n",
00363 kt_perp_.real(),
00364 kt_perp_.imag() );
00365 #endif
00366
00367 complex num_para = delta_eps * upper.kt_perp_;
00368 num_para -= upper_delta_eps * kt_perp_;
00369 num_para += num_perp;
00370
00371 complex denom_para = delta_eps * upper.kt_perp_;
00372 denom_para += upper_delta_eps * kt_perp_;
00373 denom_para += denom_perp;
00374
00375 rflcoef_.para() = num_para / denom_para;
00376
00377 double eps_epsupper_r = alpha_jm1 * alpha_j - gamma_jm1 * gamma_j;
00378 eps_epsupper_r -= alpha_jm1 + alpha_j;
00379 eps_epsupper_r += 1.0;
00380
00381 double eps_epsupper_i = alpha_jm1 * gamma_j + gamma_jm1 * alpha_j;
00382 eps_epsupper_i -= gamma_jm1 + gamma_j;
00383
00384 eps_epsupper_ = complex( eps_epsupper_r, eps_epsupper_i );
00385
00386 #if defined(DEBUG_DIELECTRICLAYER)
00387 fprintf(stdout, "eps_epsupper (r,i): (%.15e, %.15e)\n",
00388 eps_epsupper_r, eps_epsupper_i);
00389 fprintf(stdout, "num_para (%.15e %.15e)\n",
00390 num_para.real(),
00391 num_para.imag() );
00392 fprintf(stdout, "denom_perp (%.15e %.15e)\n",
00393 denom_para.real(),
00394 denom_para.imag() );
00395 fprintf(stdout, "rflcoef (para) (%.15e %.15e)\n",
00396 rflcoef_.para().real(),
00397 rflcoef_.para().imag() );
00398 #endif
00399
00400 if (! is_substrate() )
00401 {
00402 t_ij_.perp() = 2.0 * upper.kt_perp_ / denom_perp;
00403 t_ji_.perp() = 2.0 * kt_perp_ / denom_perp;
00404
00405 t_ij_.para() = 2.0 * ( eps * upper.kt_perp_ ) / denom_para;
00406 t_ji_.para() = 2.0 * ( eps_upper * kt_perp_ ) / denom_para;
00407
00408 tij_tji_perp_ = t_ij_.perp() * t_ji_.perp();
00409 tij_tji_para_ = t_ij_.para() * t_ji_.para();
00410
00411 r_perp_ = rflcoef_.perp();
00412 r_para_ = rflcoef_.para();
00413 r2_perp_ = rflcoef_.perp() * rflcoef_.perp();
00414 r2_para_ = rflcoef_.para() * rflcoef_.para();
00415 r2_tij_tji_perp_ = r2_perp_ + tij_tji_perp_;
00416 r2_tij_tji_para_ = r2_para_ + tij_tji_para_;
00417
00418 #if defined(DEBUG_DIELECTRICLAYER)
00419 fprintf(stdout, "t_ij_ (para) (%.15e %.15e)\n",
00420 t_ij_.para().real(),
00421 t_ij_.para().imag() );
00422 fprintf(stdout, "t_ji_ (para) (%.15e %.15e)\n",
00423 t_ji_.para().real(),
00424 t_ji_.para().imag() );
00425 fprintf(stdout, "t_ij_ (perp) (%.15e %.15e)\n",
00426 t_ij_.perp().real(),
00427 t_ij_.perp().imag() );
00428 fprintf(stdout, "t_ji_ (perp) (%.15e %.15e)\n",
00429 t_ji_.perp().real(),
00430 t_ji_.perp().imag() );
00431 fprintf(stdout, "tij_tji_perp_ (%.15e %.15e)\n",
00432 tij_tji_perp_.real(),
00433 tij_tji_perp_.imag() );
00434 fprintf(stdout, "tij_tji_para_ (%.15e %.15e)\n",
00435 tij_tji_para_.real(),
00436 tij_tji_para_.imag() );
00437 fprintf(stdout, "r_perp_ (%.15e %.15e)\n",
00438 r_perp_.real(),
00439 r_perp_.imag() );
00440 fprintf(stdout, "r_para_ (%.15e %.15e)\n",
00441 r_para_.real(),
00442 r_para_.imag() );
00443 fprintf(stdout, "r2_perp_ (%.15e %.15e)\n",
00444 r2_perp_.real(),
00445 r2_perp_.imag() );
00446 fprintf(stdout, "r2_para_ (%.15e %.15e)\n",
00447 r2_para_.real(),
00448 r2_para_.imag() );
00449 fprintf(stdout, "r2_tij_tji_perp_ (%.15e %.15e)\n",
00450 r2_tij_tji_perp_.real(),
00451 r2_tij_tji_perp_.imag() );
00452 fprintf(stdout, "r2_tij_tji_para_ (%.15e %.15e)\n",
00453 r2_tij_tji_para_.real(),
00454 r2_tij_tji_para_.imag() );
00455 #endif
00456
00457 }
00458
00459 switch ( rtype_ )
00460 {
00461 case rl_Traits::ERoughDebyeWaller_RSAO :
00462
00463 apply_DebyeWaller_RSAO_factor( upper, sinphi );
00464 break;
00465
00466 case rl_Traits::ERoughDebyeWaller_CSAO :
00467
00468 apply_DebyeWaller_CSAO_factor( upper, sinphi );
00469 break;
00470
00471 case rl_Traits::ERoughDebyeWaller_Spiller :
00472
00473 apply_DebyeWaller_Spiller_factor( sinphi );
00474 break;
00475
00476 case rl_Traits::ERoughNevotCroce :
00477
00478 apply_NevotCroce_factor( upper, sinphi );
00479 break;
00480
00481 case rl_Traits::ERoughModifiedDebyeWaller :
00482
00483 apply_ModifiedDW_factor( upper, sinphi );
00484 break;
00485
00486 case rl_Traits::ERoughNone :
00487
00488
00489 break;
00490
00491 default :
00492
00493 cerr << "Invalid roughness type in rl_DielectricLayer::reflect_amp"
00494 << endl;
00495 cerr << "Roughness type was " << rtype_ << endl;
00496 exit(1);
00497
00498 }
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 void rl_DielectricLayer::
00520 reflect_nlayer( rl_DielectricLayer layer[],
00521 int num )
00522 {
00523 complex eps_para( layer[num-1].rflcoef_.para() );
00524 complex eps_perp( layer[num-1].rflcoef_.perp() );
00525 const complex one( 1.0 );
00526 #if defined(DEBUG_DIELECTRICLAYER)
00527 fprintf(stdout, "\nDEBUG: ___REFLECT_NLAYER___ ___AAA0___ -----\n");
00528 fprintf(stdout, "\n==> layer %5d -- ", num-1);
00529 fprintf(stdout, "layer[n-1] (%5d %.s)\n",
00530 num-1, layer[num-1].name_);
00531 fprintf(stdout, "rl_DielectricLayer::reflect_nlayer ");
00532 fprintf(stdout, "======================\n");
00533 fprintf(stdout, "eps (para) %5d (%.15e %.15e)\n",
00534 num-1, eps_para.real(), eps_para.imag());
00535 fprintf(stdout, "eps (perp) %5d (%.15e %.15e)\n",
00536 num-1, eps_perp.real(), eps_perp.imag());
00537 #endif
00538
00539 for ( int n = num-2; n >= 0; --n )
00540 {
00541 rl_Traits::complex prop_eps_para( layer[n].propagator() * eps_para );
00542 eps_para = (layer[n].rflcoef_.para()
00543 + layer[n].r2_tij_tji_para_ * prop_eps_para)
00544 / (one + layer[n].rflcoef_.para() * prop_eps_para);
00545
00546 rl_Traits::complex prop_eps_perp( layer[n].propagator() * eps_perp );
00547 eps_perp = (layer[n].rflcoef_.perp()
00548 + layer[n].r2_tij_tji_perp_ * prop_eps_perp)
00549 / (one + layer[n].rflcoef_.perp() * prop_eps_perp);
00550
00551 #if defined(DEBUG_DIELECTRICLAYER)
00552 fprintf(stdout, "\nDEBUG: ___REFLECT_NLAYER___ ___AAA1___ -----\n");
00553 fprintf(stdout, "\n==> layer %5d -- ", n);
00554 fprintf(stdout, "rl_DielectricLayer::reflect_nlayer ");
00555 fprintf(stdout, "======================\n");
00556 cprint_constraints_on( stdout );
00557 fprintf(stdout, "rflcoef (para) %5d, (%.15e %.15e)\n",
00558 n, layer[n].rflcoef_.para().real(),
00559 layer[n].rflcoef_.para().imag() );
00560
00561 fprintf(stdout, "rflcoef (perp) %5d, (%.15e %.15e)\n",
00562 n, layer[n].rflcoef_.perp().real(),
00563 layer[n].rflcoef_.perp().imag() );
00564
00565 fprintf(stdout, "r2_tt (para) %5d, (%.15e %.15e)\n",
00566 n, layer[n].r2_tij_tji_para_.real(),
00567 layer[n].r2_tij_tji_para_.imag() );
00568
00569 fprintf(stdout, "r2_tt (perp) %5d, (%.15e %.15e)\n",
00570 n, layer[n].r2_tij_tji_perp_.real(),
00571 layer[n].r2_tij_tji_perp_.imag() );
00572
00573 fprintf(stdout, "eps (para) %5d, (%.15e %.15e)\n",
00574 n, eps_para.real(), eps_para.imag());
00575 fprintf(stdout, "eps (perp) %5d, (%.15e %.15e)\n",
00576 n, eps_perp.real(), eps_perp.imag());
00577 #endif
00578 }
00579 layer[0].rflcoef_.para() = eps_para;
00580 layer[0].rflcoef_.perp() = eps_perp;
00581
00582 #if defined(DEBUG_DIELECTRICLAYER)
00583 fprintf(stdout, "\n");
00584 #endif
00585
00586 #if 0
00587 refl = abs( eps );
00588 refl *= refl;
00589 #endif
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 void rl_DielectricLayer::
00603 apply_DebyeWaller_CSAO_factor( rl_DielectricLayer const& upper,
00604 double sinphi
00605 )
00606 {
00607 double phase_factor = -2 * phase_factor_ * phase_factor_;
00608 double sinphi_sq = sinphi * sinphi;
00609
00610 complex sinterm_0( sinphi_sq - upper.alpha_, -upper.gamma_ );
00611 sinterm_0 /= complex( 1.0 - upper.alpha_, -upper.gamma_ );
00612
00613 complex ckphase( sinterm_0 );
00614 ckphase *= phase_factor;
00615 ckphase = exp(ckphase);
00616
00617 rflcoef_.para() *= ckphase;
00618 rflcoef_.perp() *= ckphase;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 void rl_DielectricLayer::
00630 apply_DebyeWaller_RSAO_factor( rl_DielectricLayer const& upper,
00631 double sinphi
00632 )
00633 {
00634 double phase_factor = -2.0 * phase_factor_ * phase_factor_;
00635 double sinphi_sq = sinphi * sinphi;
00636
00637 complex sinterm_0( sinphi_sq - upper.alpha_, -upper.gamma_ );
00638 sinterm_0 /= complex( 1.0 - upper.alpha_, -upper.gamma_ );
00639
00640 complex ckphase( sinterm_0 );
00641 ckphase *= phase_factor;
00642 double real_phase_factor = ckphase.real();
00643 real_phase_factor = exp( real_phase_factor );
00644
00645 rflcoef_.para() *= real_phase_factor;
00646 rflcoef_.perp() *= real_phase_factor;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 void rl_DielectricLayer::
00659 apply_DebyeWaller_Spiller_factor( double sinphi
00660 )
00661 {
00662 double phase_factor = phase_factor_;
00663
00664 phase_factor *= sinphi;
00665 phase_factor *= phase_factor;
00666 phase_factor *= 2.0;
00667
00668 complex ckphase( phase_factor * (alpha_ - 1.0),
00669 phase_factor * gamma_ );
00670
00671 complex cexp_factor = exp(ckphase);
00672
00673 rflcoef_.para() *= cexp_factor;
00674 rflcoef_.perp() *= cexp_factor;
00675 }
00676
00677
00678
00679
00680
00681 void rl_DielectricLayer::
00682 apply_ModifiedDW_factor( rl_DielectricLayer const& upper,
00683 double sinphi
00684 )
00685 {
00686 double phase_factor = phase_factor_;
00687 double sinphi_sq = sinphi * sinphi;
00688
00689 #if defined(DEBUG_DIELECTRICLAYER)
00690 fprintf(stdout, "\nDEBUG: ___MDW___ ---------------------------\n");
00691 cerr << "==================================================================="
00692 << endl;
00693 cerr << "Layer j-1:" << endl;
00694 upper.cdump_on( stdout );
00695 cerr << "-------------------------------------------------------------------"
00696 << endl;
00697 cerr << "Layer j:" << endl;
00698 cdump_on( stdout );
00699 cerr << "-------------------------------------------------------------------"
00700 << endl;
00701 #endif
00702
00703 phase_factor *= -2.0 * phase_factor;
00704
00705 #if defined(DEBUG_DIELECTRICLAYER)
00706 cerr << "sinphi: " << sinphi << endl;
00707 cerr << "phi: " << 60.0 * asin(sinphi) / M_DEG2RAD << endl;
00708 cerr << "-2 (2pi sigma/lambda)^2: " << phase_factor << endl;
00709 #endif
00710
00711 complex sinterm_0( sinphi_sq - upper.alpha_, -upper.gamma_ );
00712 complex nopt0 = sqrt( complex( 1.0 - upper.alpha_, -upper.gamma_ ));
00713 complex cos2_0 = sqrt( sinterm_0 ) / nopt0;
00714
00715 #if defined(DEBUG_DIELECTRICLAYER)
00716 cerr << "cos_{j-1}: " << cos2_0 << endl;
00717 #endif
00718
00719 complex sinterm_1( sinphi_sq - alpha_, -gamma_ );
00720 complex nopt1 = sqrt( complex( 1.0 - alpha_, -gamma_ ) );
00721 complex cos2_1 = sqrt( sinterm_1 ) / nopt1;
00722
00723 #if defined(DEBUG_DIELECTRICLAYER)
00724 complex cosij = cos2_0 * cos2_1;
00725 complex cosj = cos2_0 * nopt0 / nopt1;
00726 complex sin2_0 = sqrt( complex(1.0) - cos2_0 * cos2_0 );
00727 complex sin2_1 = sqrt( complex(1.0) - cos2_1 * cos2_1 );
00728 cerr << "cos_{j}: " << cos2_1 << endl;
00729 cerr << "cos_{j-1} n_{j-1} / n_{j} " << cos2_0 * nopt0 / nopt1 << endl;
00730 cerr << "n_{j-1} sin_{j-1} " << sin2_0 * nopt0 << endl;
00731 cerr << "n_{j} sin_{j} " << sin2_1 * nopt1 << endl;
00732 cerr << "cos_{j} cos_{j-1} " << cosij << endl;
00733 #endif
00734
00735 complex cexp_factor( cos2_0 );
00736 cexp_factor *= cos2_1;
00737 cexp_factor *= phase_factor;
00738 cexp_factor = exp( cexp_factor );
00739
00740 rflcoef_.para() *= cexp_factor;
00741 rflcoef_.perp() *= cexp_factor;
00742
00743 #if defined(DEBUG_DIELECTRICLAYER)
00744 cerr << "==================================================================="
00745 << endl;
00746 #endif
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 void rl_DielectricLayer::
00763 apply_NevotCroce_factor( rl_DielectricLayer const& upper,
00764 double sinphi
00765 )
00766 {
00767 double phase_factor = phase_factor_;
00768 double sinphi_sq = sinphi * sinphi;
00769
00770 phase_factor *= phase_factor;
00771 phase_factor *= -2.0;
00772
00773 complex sinterm_0( sinphi_sq - upper.alpha_, -upper.gamma_ );
00774 complex sinterm_1( sinphi_sq - alpha_, -gamma_ );
00775 complex ckphase( sinterm_0 );
00776
00777 ckphase *= sinterm_1;
00778 ckphase = sqrt( ckphase );
00779 ckphase *= phase_factor;
00780 ckphase = exp(ckphase);
00781
00782 rflcoef_.para() *= ckphase;
00783 rflcoef_.perp() *= ckphase;
00784 }
00785
00786
00787
00788
00789
00790 std::ostream& rl_DielectricLayer::
00791 dump_on( std::ostream& os, char const pre[], char const pst[] ) const
00792 {
00793 if ( strlen(pre) )
00794 { os << pre; }
00795
00796 os << "Layer: " << name_ << endl;
00797 os.setf( ios::scientific, ios::floatfield );
00798 os.precision(12);
00799
00800 os << "minimum energy (keV): " << diel_info_.energy_min() << endl;
00801 os << "maximum energy (keV): " << diel_info_.energy_max() << endl;
00802 os << "bulk density scale: " << diel_info_.bulk_density_factor() << endl;
00803
00804 os << "thickness (Angstrom): " << thickness_ << endl;
00805 if (! is_vacuum() )
00806 {
00807 os << "reflection coefficient: " << rflcoef_ << endl;
00808 }
00809 os << "alpha: " << alpha_ << endl;
00810 os << "gamma: " << gamma_ << endl;
00811 os << "refractive index: "
00812 << sqrt( complex( 1.0 - alpha_, -gamma_ )) << endl;
00813 if (! is_vacuum() )
00814 {
00815 os << "roughness type: " << rtype_ << endl;
00816 os << "sigma_rough: " << srough_ << endl;
00817 os << "wavelength: " << lambda_ << endl;
00818 os << "zcoat: " << zcoat_ << endl;
00819 os << "propagator: " << prop_ << endl;
00820 os << "kt_perp_: " << kt_perp_ << endl;
00821 }
00822 os << "is_vacuum: " << is_vacuum() << endl;
00823 os << "is_substrate: " << is_substrate_ << endl;
00824
00825 if ( strlen(pst) )
00826 { os << pst; }
00827
00828 return os;
00829 }
00830
00831
00832
00833
00834
00835 void rl_DielectricLayer::
00836 cdump_on( std::FILE* of, char const pre[], char const pst[] ) const
00837 {
00838 if ( strlen(pre) )
00839 { fprintf(of, "%s", pre); }
00840
00841 fprintf(of, "Layer: %s\n", name_);
00842
00843 fprintf(of, "minimum energy (keV): %.15e\n", diel_info_.energy_min());
00844 fprintf(of, "maximum energy (keV): %.15e\n", diel_info_.energy_max());
00845 fprintf(of, "bulk density scale: %.15e\n",
00846 diel_info_.bulk_density_factor());
00847
00848 fprintf(of, "thickness (Angstrom): %.15e\n", thickness_);
00849 if (! is_vacuum() )
00850 {
00851 rflcoef_.cprint_on(of);
00852 }
00853 fprintf( of, "alpha: %.15e\n", alpha_);
00854 fprintf( of, "gamma: %.15e\n", gamma_);
00855
00856 complex srt = sqrt( complex( 1.0 - alpha_, -gamma_ ) );
00857 fprintf(of, "refractive index: (%.15e, %.15e)\n",
00858 srt.real(), srt.imag());
00859
00860 if (! is_vacuum() )
00861 {
00862 fprintf(of, "roughness type: %d\n", rtype_);
00863 fprintf(of, "sigma_rough: %.15e\n", srough_);
00864 fprintf(of, "wavelength: %.15e\n", lambda_);
00865 fprintf(of, "zcoat: %.15e\n", zcoat_);
00866 fprintf(of, "propagator: (%.15e, %.15e)\n",
00867 prop_.real(), prop_.imag());
00868 fprintf(of, "kt_perp_: (%.15e, %.15e)\n",
00869 kt_perp_.real(), kt_perp_.imag());
00870 }
00871 fprintf(of, "is_vacuum: %d\n", is_vacuum());
00872 fprintf(of, "is_substrate: %d\n", is_substrate_);
00873
00874 if ( strlen(pst) )
00875 { fprintf(of, "%s", pst); }
00876 }
00877
00878
00879 void rl_DielectricLayer::
00880 cprint_constraints_on( std::FILE* of,
00881 char const pre[], char const pst[] ) const
00882 {
00883 if ( strlen(pre) )
00884 { fprintf(of, "%s", pre); }
00885
00886 fprintf(of, "Layer: %s\n", name_);
00887
00888 complex identperp = t_ij_.perp() - rflcoef_.perp();
00889 complex identpara = t_ij_.para() - rflcoef_.para();
00890
00891 fprintf(of, "minimum energy (keV): %.14e\n", diel_info_.energy_min());
00892 fprintf(of, "maximum energy (keV): %.14e\n", diel_info_.energy_max());
00893 fprintf(of, "bulk density scale: %.14e\n",
00894 diel_info_.bulk_density_factor());
00895
00896 fprintf(of, "thickness (Angstrom): %.14e\n", thickness_);
00897 fprintf( of, "alpha: %.14e\n", alpha_);
00898 fprintf( of, "gamma: %.14e\n", gamma_);
00899
00900 complex srt = sqrt( complex( 1.0 - alpha_, -gamma_ ) );
00901 fprintf(of, "refractive index: (%.14e, %.14e)\n",
00902 srt.real(), srt.imag());
00903
00904 if (! is_vacuum() )
00905 {
00906 fprintf(of, "roughness type: %d\n", rtype_);
00907 fprintf(of, "sigma_rough: %.14e\n", srough_);
00908 fprintf(of, "wavelength: %.14e\n", lambda_);
00909 fprintf(of, "zcoat: %.14e\n", zcoat_);
00910 fprintf(of, "propagator: (%.14e, %.14e)\n",
00911 prop_.real(), prop_.imag());
00912 fprintf(of, "kt_perp_: (%.14e, %.14e)\n",
00913 kt_perp_.real(), kt_perp_.imag());
00914 fprintf(of, "\n");
00915
00916 fprintf(of, "Tji_perp: (%.14e, %.14e)\n",
00917 t_ji_.perp().real(), t_ji_.perp().imag());
00918 fprintf(of, "Tij_perp: (%.14e, %.14e)\n",
00919 t_ij_.perp().real(), t_ij_.perp().imag());
00920 fprintf(of, "Rij_perp: (%.14e, %.14e)\n",
00921 rflcoef_.perp().real(), rflcoef_.perp().imag());
00922 fprintf(of, "Rij^2 (perp): (%.14e, %.14e)\n",
00923 r2_perp_.real(), r2_perp_.imag());
00924 fprintf(of, "Tij Tji (perp): (%.14e, %.14e)\n",
00925 tij_tji_perp_.real(), tij_tji_perp_.imag());
00926 double tprpi = (fabs(identperp.imag()) >= 1e-15)
00927 ? identperp.imag() : 0.0;
00928 fprintf(of, "Tij_perp-Rij_perp: (%.14e, %.14e)\n",
00929 identperp.real(), tprpi);
00930 fprintf(of, "Rij^2+Tij Tji (perp): (%.14e, %.14e)\n",
00931 r2_tij_tji_perp_.real(), r2_tij_tji_perp_.imag());
00932 fprintf(of, "\n");
00933
00934 fprintf(of, "Tji_para: (%.14e, %.14e)\n",
00935 t_ji_.para().real(), t_ji_.para().imag());
00936 fprintf(of, "Tij_para: (%.14e, %.14e)\n",
00937 t_ij_.para().real(), t_ij_.para().imag());
00938 fprintf(of, "Rij_para: (%.14e, %.14e)\n",
00939 rflcoef_.para().real(), rflcoef_.para().imag());
00940 fprintf(of, "Rij^2 (para): (%.14e, %.14e)\n",
00941 r2_para_.real(), r2_para_.imag());
00942 fprintf(of, "Tij Tji (para): (%.14e, %.14e)\n",
00943 tij_tji_para_.real(), tij_tji_para_.imag());
00944 fprintf(of, "Tij_para-Rij_para: (%.14e, %.14e)\n",
00945 identpara.real(), identpara.imag());
00946 fprintf(of, "Rij^2+Tij Tji (para): (%.14e, %.14e)\n",
00947 r2_tij_tji_para_.real(), r2_tij_tji_para_.imag());
00948 fprintf(of, "\n");
00949 }
00950 fprintf(of, "is_vacuum: %d\n", is_vacuum());
00951 fprintf(of, "is_substrate: %d\n", is_substrate_);
00952
00953 if ( strlen(pst) )
00954 { fprintf(of, "%s", pst); }
00955 }