rl_raylib  1.1.10
rl_Multilayer.cc
1 // File: rl_Multilayer.cc
2 // Author: Terry Gaetz
3 
4 // --8<--8<--8<--8<--
5 //
6 // Copyright (C) 2006, 2007 Smithsonian Astrophysical Observatory
7 //
8 // This file is part of rl_raylib
9 //
10 // rl_raylib is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
14 //
15 // rl_raylib is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the
22 // Free Software Foundation, Inc.
23 // 51 Franklin Street, Fifth Floor
24 // Boston, MA 02110-1301, USA
25 //
26 // -->8-->8-->8-->8--
27 
28 #include <rl_Multilayer.h> // rl_Multilayer
29 
30 #include <cstdio>
31 #include <cstddef>
32 #include <cmath>
33 #include <mathconst/mathconst.h> // M_PI
34 
35 #include <rl_DielectricData.h> // rl_DielectricData
36 #include <rl_DielectricLayer.h> // rl_DielectricLayer
37 #include <rl_ReflectionCoefPOD.h> // rl_ReflectionCoefPOD
38 
39 using namespace std;
40 
41 //=========================================================================
42 // dtor, ctors
43 
44 //-------------------------------------------------------------------------
47 {
48  if ( own_data_ && layer_ ) { delete [] layer_; }
49 }
50 
51 //-------------------------------------------------------------------------
52 rl_Multilayer::
53 rl_Multilayer( int num_layers,
54  rl_DielectricLayer* layers,
55  rl_Traits::Bool adopt_data )
56  : num_layers_(num_layers),
57  vacuum_( "vacuum" ),
58  layer_(layers),
59  own_data_(adopt_data)
60 {}
61 
62 //-------------------------------------------------------------------------
63 void rl_Multilayer::
64 init( int num_layers,
65  rl_DielectricLayer* layers,
66  rl_Traits::Bool adopt_data )
67 {
68  if ( own_data_ && layer_ ) { delete [] layer_; }
70  layer_ = layers;
71  own_data_ = adopt_data;
72 }
73 
74 //=========================================================================
75 // mutators
76 
77 //-------------------------------------------------------------------------
78 // C The thicknesses in Angstrom are in zcoat0. The variable zcoat
79 // C is 4*pi*zcoat0 / wavelength (in Angstrom).
80 // c
81 // C REFLECT computes reflectivities for polarizations perpendicular and
82 // C parallel to the plane of incidence. This version can handle 1200 layers.
83 // [The C version has no such limit. TJG]
84 //
85 // subroutine reflect( nlayer, alpha, gamma, zcoat, sinphi, rcosphi,
86 // a fourpi, lambda, srough, rpara, rperp )
87 
88 int
91  double energy,
92  double sinphi )
93 {
94  vacuum_.setup_for( energy, sinphi );
95 
96  int rc = 0;
97  int n;
98  for ( n = 0 ; n < num_layers_ ; ++n )
99  {
100  rc = layer_[n].setup_for( energy, sinphi );
101  if ( rc )
102  {
103  rc = n+1;
104  break;
105  }
106  }
107 
108  if (! rc )
109  {
110  //----------------------------------
111  // Calculate complex reflectance amplitudes
112  // for first interface [between vacuum and material 1].
113 
114  layer_[0].reflect_amp( vacuum_, sinphi );
115 
116  for ( n = 1 ; n < num_layers_ ; ++n )
117  {
118  layer_[n].reflect_amp( layer_[n-1], sinphi );
119  }
120 
121  //----------------------------------
122  // Calculate reflectivity from n layers for polarizations
123 
125  }
126  else
127  {
128  cerr << "Problem setting up layer " << (rc-1) << endl;
129  }
130  rfl = layer_[0].reflection_coef();
131 
132  return rc;
133 }
134 
135 int rl_Multilayer::
137  double& rfl, // out: multilayer reflectivity
138  double energy, // in: energy of ray
139  double sg, // in: sine graze angle
140  double polarization_factor // in: polarization_factor
141 )
142 {
143  rl_ReflectionCoefPOD rflcoef;
144  rflcoef.init();
145  int rc = multilayer_reflect_coef( rflcoef, energy, sg );
146  rfl = rflcoef.reflectivity( polarization_factor );
147 
148  return rc;
149 }
150 
151 //=========================================================================
152 // accessors
153 
154 //-------------------------------------------------------------------------
156 layer( int layer_no ) const
157 { return layer_[layer_no]; }
158 
159 //=========================================================================
160 // i/o
161 
162 //-------------------------------------------------------------------------
163 std::ostream& rl_Multilayer::
164 dump_on( std::ostream& os, int layer_no,
165  char const pre[],
166  char const pst[] ) const
167 {
168  if ( strlen(pre) )
169  { os << pre; }
170 
171  layer_[layer_no].dump_on( os, pre, pst );
172 
173  if ( strlen(pst) )
174  { os << pst; }
175 
176  return os;
177 }
178 
179 //-------------------------------------------------------------------------
180 void rl_Multilayer::
181 cdump_on( std::FILE* of, int layer_no,
182  char const pre[],
183  char const pst[] ) const
184 {
185  if ( strlen(pre) )
186  { fprintf(of, "%s", pre); }
187 
188  layer_[layer_no].cdump_on( of, "", "" );
189 
190  if ( strlen(pst) )
191  { fprintf(of, "%s", pst); }
192 }
int num_layers_
number of multilayers
Definition: rl_Multilayer.h:74
int setup_for(double energy, double sinphi)
Set up layer state for given energy and graze angle.
std::ostream & dump_on(std::ostream &os, int layer_no, char const pre[]="", char const pst[]="") const
Dump information about layer layer_no to stream os.
void cdump_on(std::FILE *of, int layer_no, char const pre[]="", char const pst[]="") const
Dump information about layer layer_no to output FILE*.
rl_Traits::Bool own_data_
do we own the rl_DielectricLayer array?
Definition: rl_Multilayer.h:80
void init(int num_layers, rl_DielectricLayer *layers, rl_Traits::Bool adopt_data=rl_Traits::True)
Initialize multilayer from num_layers individual layers.
void init()
initialize perpendicular (s) and parallel (p) reflection coefficients to zero.
void reflect_nlayer(rl_DielectricLayer layer[], int num)
Compute reflectivity for a stack of num layers.
A Plain Ol' Data class representing complex reflection coefficients.
void cdump_on(std::FILE *of, char const pre[]="", char const pst[]="") const
Dumps layer information to a C-style FILE* stream.
double reflectivity(double polarization_factor=0.0) const
evaluate the reflectivity.
rl_ReflectionCoefPOD const & reflection_coef() const
Returns this layer's complex reflection coefficient.
rl_DielectricLayer vacuum_
the top (vacuum) layer
Definition: rl_Multilayer.h:76
std::ostream & dump_on(std::ostream &os, char const pre[]="", char const pst[]="") const
Dumps layer information to a stream.
int multilayer_reflect_coef(rl_ReflectionCoefPOD &rfl, double energy, double sg)
Evaluate the multilayer reflection coefficients.
int num_layers() const
rl_DielectricLayer * layer_
array of dielectric layers
Definition: rl_Multilayer.h:78
int multilayer_reflectivity(double &rfl, double energy, double sg, double polarization_factor=0.0)
Evaluate the multilayer reflectivity (assuming unpolarized rays)
rl_DielectricLayer const & layer(int layer_no) const
void reflect_amp(rl_DielectricLayer const &layer, double sinphi)
Compute reflection amplitude for the interface between this layer and the layer immediately above it.
virtual ~rl_Multilayer()
Destructor.
A class encapsulating the multilayer reflection of a ray.
Bool
Typedef for the Boolean type.
Definition: rl_Traits.h:64