rl_Multilayer.cc

00001 // File:   rl_Multilayer.cc
00002 // Author: Terry Gaetz
00003 
00004 // --8<--8<--8<--8<--
00005 //
00006 // Copyright (C) 2006, 2007 Smithsonian Astrophysical Observatory
00007 //
00008 // This file is part of rl_raylib
00009 //
00010 // rl_raylib is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public License
00012 // as published by the Free Software Foundation; either version 2
00013 // of the License, or (at your option) any later version.
00014 //
00015 // rl_raylib 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 this program; if not, write to the 
00022 //       Free Software Foundation, Inc. 
00023 //       51 Franklin Street, Fifth Floor
00024 //       Boston, MA  02110-1301, USA
00025 //
00026 // -->8-->8-->8-->8--
00027 
00028 #include <rl_Multilayer.h>         // rl_Multilayer
00029 
00030 #include <cstdio>
00031 #include <cstddef>
00032 #include <cmath>
00033 #include <mathconst/mathconst.h>       // M_PI
00034 
00035 #include <rl_DielectricData.h>      // rl_DielectricData
00036 #include <rl_DielectricLayer.h>     // rl_DielectricLayer
00037 #include <rl_ReflectionCoefPOD.h>   // rl_ReflectionCoefPOD
00038 
00039 using namespace std;
00040 
00041 //=========================================================================
00042 // dtor, ctors
00043 
00044 //-------------------------------------------------------------------------
00045 rl_Multilayer::
00046 ~rl_Multilayer()
00047 {
00048   if ( own_data_ && layer_ ) { delete [] layer_; }
00049 }
00050 
00051 //-------------------------------------------------------------------------
00052 rl_Multilayer::
00053 rl_Multilayer( int                 num_layers,
00054                rl_DielectricLayer* layers,
00055                rl_Traits::Bool     adopt_data )
00056   : num_layers_(num_layers),
00057     vacuum_( "vacuum" ),
00058     layer_(layers),
00059     own_data_(adopt_data)
00060 {}
00061 
00062 //-------------------------------------------------------------------------
00063 void rl_Multilayer::
00064 init( int                 num_layers,
00065       rl_DielectricLayer* layers,
00066       rl_Traits::Bool     adopt_data )
00067 {
00068   if ( own_data_ && layer_ ) { delete [] layer_; }
00069   num_layers_ = num_layers;
00070   layer_      = layers;
00071   own_data_   = adopt_data;
00072 }
00073 
00074 //=========================================================================
00075 // mutators
00076 
00077 //-------------------------------------------------------------------------
00078 // C The thicknesses in Angstrom are in zcoat0.  The variable zcoat
00079 // C is 4*pi*zcoat0 / wavelength (in Angstrom).
00080 // c
00081 // C REFLECT computes reflectivities for polarizations perpendicular and
00082 // C parallel to the plane of incidence.  This version can handle 1200 layers.
00083 // [The C version has no such limit.  TJG]
00084 //
00085 //    subroutine reflect( nlayer, alpha, gamma, zcoat, sinphi, rcosphi,
00086 //   a                    fourpi, lambda, srough, rpara, rperp )
00087 
00088 int
00089 rl_Multilayer::
00090 multilayer_reflect_coef( rl_ReflectionCoefPOD& rfl,
00091                          double                energy,
00092                          double                sinphi )
00093 {
00094   vacuum_.setup_for( energy, sinphi );
00095 
00096   int rc = 0;
00097   int n;
00098   for ( n = 0 ; n < num_layers_ ; ++n )
00099   {
00100     rc = layer_[n].setup_for( energy, sinphi );
00101     if ( rc )
00102     {
00103       rc = n+1;
00104       break;
00105     }
00106   }
00107 
00108   if (! rc )
00109   {
00110     //----------------------------------
00111     // Calculate complex reflectance amplitudes
00112     // for first interface [between vacuum and material 1].
00113 
00114     layer_[0].reflect_amp( vacuum_, sinphi );
00115 
00116     for ( n = 1 ; n < num_layers_ ; ++n )
00117     {
00118       layer_[n].reflect_amp( layer_[n-1], sinphi );
00119     }
00120 
00121     //----------------------------------
00122     // Calculate reflectivity from n layers for polarizations
00123 
00124     layer_->reflect_nlayer( layer_, num_layers_ );
00125   }
00126   else
00127   {
00128     cerr << "Problem setting up layer " << (rc-1) << endl;
00129   }
00130   rfl = layer_[0].reflection_coef();
00131 
00132   return rc;
00133 }
00134 
00135 int rl_Multilayer::
00136 multilayer_reflectivity(
00137         double& rfl,                 // out: multilayer reflectivity
00138         double  energy,              // in:  energy of ray
00139         double  sg,                  // in:  sine graze angle
00140         double  polarization_factor  // in:  polarization_factor
00141 )
00142 { 
00143   rl_ReflectionCoefPOD rflcoef;
00144   rflcoef.init();
00145   int rc = multilayer_reflect_coef( rflcoef, energy, sg );
00146   rfl    = rflcoef.reflectivity( polarization_factor );
00147 
00148   return rc;
00149 }
00150 
00151 //=========================================================================
00152 // accessors 
00153 
00154 //-------------------------------------------------------------------------
00155 rl_DielectricLayer const& rl_Multilayer::
00156 layer( int layer_no ) const
00157 { return layer_[layer_no]; }
00158 
00159 //=========================================================================
00160 // i/o
00161 
00162 //-------------------------------------------------------------------------
00163 std::ostream& rl_Multilayer::
00164 dump_on( std::ostream& os, int layer_no,
00165                            char const pre[], 
00166                            char const pst[] ) const
00167 {
00168   if ( strlen(pre) )
00169   { os << pre; }
00170 
00171   layer_[layer_no].dump_on( os, pre, pst );
00172 
00173   if ( strlen(pst) )
00174   { os << pst; }
00175 
00176   return os;
00177 }
00178 
00179 //-------------------------------------------------------------------------
00180 void rl_Multilayer::
00181 cdump_on( std::FILE* of, int layer_no,
00182                          char const pre[], 
00183                          char const pst[] ) const
00184 {
00185   if ( strlen(pre) )
00186   { fprintf(of, "%s", pre); }
00187 
00188   layer_[layer_no].cdump_on( of, "", "" );
00189 
00190   if ( strlen(pst) )
00191   { fprintf(of, "%s", pst); }
00192 }

Generated on Mon Nov 3 18:15:05 2008 for rl_raylib by  doxygen 1.5.6