Commit 0ef519a4a62c88829271fa984c25fd465b707890
1 parent
7c246292
optimized material class, still have to add KK
Showing
5 changed files
with
199 additions
and
584 deletions
Show diff stats
math/complex.h
... | ... | @@ -294,6 +294,19 @@ struct complex |
294 | 294 | return false; |
295 | 295 | } |
296 | 296 | |
297 | + CUDA_CALLABLE bool operator<(complex<T> rhs){ | |
298 | + return abs() < rhs.abs(); | |
299 | + } | |
300 | + CUDA_CALLABLE bool operator<=(complex<T> rhs){ | |
301 | + return abs() <= rhs.abs(); | |
302 | + } | |
303 | + CUDA_CALLABLE bool operator>(complex<T> rhs){ | |
304 | + return abs() > rhs.abs(); | |
305 | + } | |
306 | + CUDA_CALLABLE bool operator >=(complex<T> rhs){ | |
307 | + return abs() >= rhs.abs(); | |
308 | + } | |
309 | + | |
297 | 310 | //CASTING operators |
298 | 311 | template < typename otherT > |
299 | 312 | operator complex<otherT>() |
... | ... | @@ -469,6 +482,20 @@ std::ostream& operator<<(std::ostream& os, rts::complex<A> x) |
469 | 482 | return os; |
470 | 483 | } |
471 | 484 | |
485 | +template<class A> | |
486 | +std::istream& operator>>(std::istream& is, rts::complex<A>& x) | |
487 | +{ | |
488 | + A r, i; | |
489 | + r = i = 0; //initialize the real and imaginary parts to zero | |
490 | + is>>r; //parse | |
491 | + is>>i; | |
492 | + | |
493 | + x.real(r); //assign the parsed values to x | |
494 | + x.imag(i); | |
495 | + | |
496 | + return is; //return the stream | |
497 | +} | |
498 | + | |
472 | 499 | //#if __GNUC__ > 3 && __GNUC_MINOR__ > 7 |
473 | 500 | //template<class T> using rtsComplex = rts::complex<T>; |
474 | 501 | //#endif | ... | ... |
math/function.h
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 | #define RTS_FUNCTION_H |
3 | 3 | |
4 | 4 | #include <string> |
5 | +#include <cmath> | |
5 | 6 | |
6 | 7 | namespace rts{ |
7 | 8 | |
... | ... | @@ -9,8 +10,12 @@ namespace rts{ |
9 | 10 | template <class Tx, class Ty> |
10 | 11 | class function |
11 | 12 | { |
13 | +protected: | |
14 | + | |
12 | 15 | std::vector<Tx> X; |
13 | 16 | std::vector<Ty> Y; |
17 | + Ty range[2]; | |
18 | + Ty bounding[2]; | |
14 | 19 | |
15 | 20 | //comparison function for searching lambda |
16 | 21 | static bool findCeiling(Tx ax, Tx bx){ |
... | ... | @@ -21,11 +26,6 @@ class function |
21 | 26 | void process_string(std::string s){ |
22 | 27 | std::stringstream ss(s); |
23 | 28 | |
24 | - //std::string test; | |
25 | - //std::getline(ss, test); | |
26 | - //std::cout<<test; | |
27 | - //exit(1); | |
28 | - | |
29 | 29 | Tx x; |
30 | 30 | Ty y; |
31 | 31 | std::string line; |
... | ... | @@ -40,21 +40,36 @@ class function |
40 | 40 | lstream>>x; //read the x value |
41 | 41 | lstream>>y; //read the y value |
42 | 42 | |
43 | - //std::cout<<x<<", "<<y<<std::endl; | |
44 | - | |
45 | 43 | if(ss.eof()) break; |
46 | 44 | insert(x, y); //insert the read value into the function |
47 | - | |
48 | 45 | } |
49 | 46 | } |
50 | 47 | |
48 | + void update_range(Ty y){ | |
49 | + //if the function is empty, just set the range to the given value | |
50 | + if(X.size() == 0){ | |
51 | + range[0] = range[1] = y; | |
52 | + } | |
53 | + | |
54 | + //otherwise compare the values and set them appropriately | |
55 | + if(y < range[0]) range[0] = y; | |
56 | + if(y > range[1]) range[1] = y; | |
57 | + } | |
58 | + | |
51 | 59 | |
52 | 60 | public: |
61 | + function(){ | |
62 | + range[0] = range[1] = NAN; | |
63 | + bounding[0] = bounding[1] = 0; | |
64 | + } | |
53 | 65 | |
54 | 66 | //linear interpolation |
55 | 67 | Ty linear(Tx x) const |
56 | 68 | { |
57 | - if(X.size() == 0) return (Ty)0; //return zero if the function is empty | |
69 | + if(X.size() == 0) return bounding[0]; //return zero if the function is empty | |
70 | + //return bounding values if x is outside the sample domain | |
71 | + if(x < X[0]) return bounding[0]; | |
72 | + if(x > X.back()) return bounding[1]; | |
58 | 73 | |
59 | 74 | unsigned int N = X.size(); //number of sample points |
60 | 75 | |
... | ... | @@ -92,6 +107,8 @@ public: |
92 | 107 | { |
93 | 108 | unsigned int N = X.size(); //number of sample points |
94 | 109 | |
110 | + update_range(y); //update the range of the function | |
111 | + | |
95 | 112 | if(N == 0 || X[N-1] < x){ |
96 | 113 | X.push_back(x); |
97 | 114 | Y.push_back(y); |
... | ... | @@ -172,14 +189,30 @@ public: |
172 | 189 | } |
173 | 190 | |
174 | 191 | |
175 | - | |
192 | + //output a string description of the function (used for console output and debugging) | |
176 | 193 | std::string str(){ |
177 | - stringstream ss; | |
194 | + unsigned int N = X.size(); | |
195 | + | |
196 | + std::stringstream ss; | |
197 | + ss<<"# of samples: "<<N<<std::endl; | |
198 | + | |
199 | + if(N == 0) return ss.str(); | |
200 | + | |
201 | + ss<<"domain: ["<<X[0]<<", "<<X[X.size()-1]<<"]"<<std::endl; | |
202 | + ss<<"range: ["<<range[0]<<", "<<range[1]<<"]"<<std::endl; | |
203 | + | |
204 | + | |
205 | + return ss.str(); | |
206 | + | |
207 | + } | |
208 | + std::string str_vals(){ | |
209 | + std::stringstream ss; | |
178 | 210 | |
179 | 211 | unsigned int N = X.size(); //number of sample points |
180 | 212 | //output each function value |
181 | 213 | for(unsigned int i = 0; i<N; i++){ |
182 | - ss<<X[i]<<", "<<Y[i]<<std::endl; | |
214 | + if(i != 0) ss<<std::endl; | |
215 | + ss<<X[i]<<", "<<Y[i]; | |
183 | 216 | } |
184 | 217 | |
185 | 218 | return ss.str(); | ... | ... |
optics/material.h
1 | -#ifndef MATERIALSTRUCT_H | |
2 | -#define MATERIALSTRUCT_H | |
1 | +#ifndef RTS_MATERIAL_H | |
2 | +#define RTS_MATERIAL_H | |
3 | 3 | |
4 | 4 | #include <vector> |
5 | 5 | #include <ostream> |
... | ... | @@ -9,596 +9,145 @@ |
9 | 9 | #include <algorithm> |
10 | 10 | #include <sstream> |
11 | 11 | #include "rts/math/complex.h" |
12 | +#include "rts/math/constants.h" | |
12 | 13 | #include "rts/math/function.h" |
13 | 14 | |
14 | -#define PI 3.14159f | |
15 | - | |
16 | 15 | namespace rts{ |
17 | 16 | |
18 | - enum field_type {field_microns, field_wavenumber, field_n, field_k, field_A, field_ignore}; | |
19 | - | |
20 | - //conversion functions | |
21 | - | |
22 | - //convert wavenumber to lambda | |
23 | - template <class T> | |
24 | - static T _wn(T inverse_cm) | |
25 | - { | |
26 | - return (T)10000.0/inverse_cm; | |
27 | - } | |
17 | +//Material class - default representation for the material property is the refractive index (RI) | |
18 | +template<typename T> | |
19 | +class material : public function< T, complex<T> >{ | |
28 | 20 | |
29 | - template <class T> | |
30 | - static T _2wn(T lambda) | |
31 | - { | |
32 | - return (T)10000.0/lambda; | |
33 | - } | |
21 | +public: | |
22 | + enum wave_property{microns, inverse_cm}; | |
23 | + enum material_property{ri, absorbance}; | |
34 | 24 | |
35 | - //convert absorbance to k | |
36 | - template <class T> | |
37 | - static T _A(T absorbance, T lambda) | |
38 | - { | |
39 | - return (absorbance * lambda) / (4 * PI); | |
40 | - } | |
41 | - template <class T> | |
42 | - static T _2A(T k, T lambda) | |
43 | - { | |
44 | - return (4 * PI * k)/lambda; | |
45 | - } | |
25 | +private: | |
46 | 26 | |
47 | - //define the dispersion as a single wavelength/refractive index pair | |
48 | - template <class T> | |
49 | - struct refIndex | |
50 | - { | |
51 | - //wavelength (in microns) | |
52 | - T lambda; | |
53 | - complex<T> n; | |
54 | - }; | |
55 | - | |
56 | - template <class T> | |
57 | - struct entryType | |
58 | - { | |
59 | - //list of value types per entry | |
60 | - std::vector<field_type> valueList; | |
61 | - | |
62 | - entryType(std::string format) | |
63 | - { | |
64 | - //location of the end of a parameter | |
65 | - size_t e; | |
66 | - | |
67 | - //string storing a token | |
68 | - std::string token; | |
69 | - | |
70 | - do | |
71 | - { | |
72 | - //find the end of the first parameter | |
73 | - e = format.find_first_of(','); | |
74 | - | |
75 | - //get the substring up to the comma | |
76 | - token = format.substr(0, e); | |
77 | - | |
78 | - //turn the token into a val_type | |
79 | - if(token == "microns") | |
80 | - valueList.push_back(field_microns); | |
81 | - else if(token == "wavenumber") | |
82 | - valueList.push_back(field_wavenumber); | |
83 | - else if(token == "n") | |
84 | - valueList.push_back(field_n); | |
85 | - else if(token == "k") | |
86 | - valueList.push_back(field_k); | |
87 | - else if(token == "A") | |
88 | - valueList.push_back(field_A); | |
89 | - else | |
90 | - valueList.push_back(field_ignore); | |
91 | - | |
92 | - //remove the first token from the format string | |
93 | - format = format.substr(e+1, format.length()-1); | |
94 | - }while(e != std::string::npos); | |
95 | - | |
96 | - | |
97 | - | |
98 | - } | |
99 | - | |
100 | - void addValue(field_type value) | |
101 | - { | |
102 | - valueList.push_back(value); | |
103 | - } | |
104 | - | |
105 | - refIndex<T> inputEntry(std::string line, T scaleA = 1.0) | |
106 | - { | |
107 | - T val; | |
108 | - std::stringstream ss(line); | |
109 | - | |
110 | - //create a new refractive index | |
111 | - refIndex<T> newRI; | |
112 | - | |
113 | - | |
114 | - //read the entry from an input string | |
115 | - for(unsigned int i=0; i<valueList.size(); i++) | |
116 | - { | |
117 | - | |
118 | - | |
119 | - while(ss.peek() < '0' || ss.peek() > '9') | |
120 | - { | |
121 | - //cout<<"bad char"<<endl; | |
122 | - ss.ignore(); | |
123 | - } | |
124 | - | |
125 | - //retrieve the value | |
126 | - ss>>val; | |
127 | - //cout<<val<<endl; | |
128 | - | |
129 | - //store the value in the appropriate location | |
130 | - switch(valueList[i]) | |
131 | - { | |
132 | - case field_microns: | |
133 | - newRI.lambda = val; | |
134 | - break; | |
135 | - case field_wavenumber: | |
136 | - newRI.lambda = _wn(val); | |
137 | - break; | |
138 | - case field_n: | |
139 | - newRI.n.real(val); | |
140 | - break; | |
141 | - case field_k: | |
142 | - newRI.n.imag(val); | |
143 | - break; | |
144 | - case field_A: | |
145 | - newRI.n.imag(_A(val * scaleA, newRI.lambda)); | |
146 | - break; | |
147 | - default: | |
148 | - break; | |
149 | - } | |
150 | - } | |
151 | - | |
152 | - //return the refractive index associated with the entry | |
153 | - return newRI; | |
154 | - | |
155 | - } | |
156 | - | |
157 | - std::string outputEntry(refIndex<T> material) | |
158 | - { | |
159 | - //std::string result; | |
160 | - std::stringstream ss; | |
161 | - | |
162 | - //for each field in the entry | |
163 | - for(int i=0; i<valueList.size(); i++) | |
164 | - { | |
165 | - if(i > 0) | |
166 | - ss<<"\t"; | |
167 | - //store the value in the appropriate location | |
168 | - switch(valueList[i]) | |
169 | - { | |
170 | - case field_microns: | |
171 | - ss<<material.lambda; | |
172 | - break; | |
173 | - case field_wavenumber: | |
174 | - ss<<_2wn(material.lambda); | |
175 | - break; | |
176 | - case field_n: | |
177 | - ss<<material.n.real(); | |
178 | - break; | |
179 | - case field_k: | |
180 | - ss<<material.n.imag(); | |
181 | - break; | |
182 | - case field_A: | |
183 | - ss<<_2A(material.n.imag(), material.lambda); | |
184 | - break; | |
185 | - } | |
27 | + using function< T, complex<T> >::X; | |
28 | + using function< T, complex<T> >::Y; | |
29 | + using function< T, complex<T> >::insert; | |
30 | + using function< T, complex<T> >::bounding; | |
186 | 31 | |
187 | - } | |
188 | - return ss.str(); | |
189 | - } | |
32 | + std::string name; //name for the material (defaults to file name) | |
190 | 33 | |
34 | + void process_header(std::string str, wave_property& wp, material_property& mp){ | |
191 | 35 | |
192 | - }; | |
193 | - | |
194 | - | |
195 | - //a material is a list of refractive index values | |
196 | - template <class T> | |
197 | - class material | |
198 | - { | |
199 | - std::string name; | |
200 | - //dispersion (refractive index as a function of wavelength) | |
201 | - //std::vector< refIndex<T> > dispersion; | |
202 | - function< T, complex<T> > dispersion; | |
203 | - | |
204 | - //average refractive index (approximately 1.4) | |
205 | - T n0; | |
206 | - | |
207 | - /*void add(refIndex<T> ri) | |
208 | - { | |
209 | - //refIndex<T> converted = convert(ri, measurement); | |
210 | - dispersion.push_back(ri); | |
211 | - }*/ | |
212 | - | |
213 | - //comparison function for sorting | |
214 | - static bool compare(refIndex<T> a, refIndex<T> b) | |
215 | - { | |
216 | - return (a.lambda < b.lambda); | |
217 | - } | |
218 | - | |
219 | - //comparison function for searching lambda | |
220 | - /*static bool findCeiling(refIndex<T> a, refIndex<T> b) | |
221 | - { | |
222 | - return (a.lambda > b.lambda); | |
223 | - }*/ | |
224 | - | |
225 | - public: | |
226 | - void add(T lambda, complex<T> n) | |
227 | - { | |
228 | - dispersion.insert(lambda, n); | |
229 | - } | |
230 | - | |
231 | - std::string getName() | |
232 | - { | |
233 | - return name; | |
234 | - } | |
235 | - void setName(std::string n) | |
236 | - { | |
237 | - name = n; | |
238 | - } | |
239 | - T getN0() | |
240 | - { | |
241 | - return n0; | |
242 | - } | |
243 | - void setN0(T n) | |
244 | - { | |
245 | - n0 = n; | |
246 | - } | |
36 | + std::stringstream ss(str); //create a stream from the data string | |
37 | + std::string line; | |
38 | + std::getline(ss, line); //get the first line as a string | |
39 | + while(line[0] == '#'){ //continue looping while the line is a comment | |
247 | 40 | |
248 | - void setM(function< T, complex<T> > m) | |
249 | - { | |
250 | - dispersion = m; | |
251 | - } | |
252 | - unsigned int nSamples() | |
253 | - { | |
254 | - return dispersion.size(); | |
255 | - } | |
256 | - material<T> computeN(T _n0, unsigned int n_samples = 0, T pf = 2) | |
257 | - { | |
258 | - /* This function computes the real part of the refractive index | |
259 | - from the imaginary part. The Hilbert transform is required. I | |
260 | - use an FFT in order to simplify this, so either the FFTW or CUFFT | |
261 | - packages are required. CUFFT is used if this file is passed through | |
262 | - a CUDA compiler. Otherwise, FFTW is used if available. | |
263 | - */ | |
264 | - | |
265 | - n0 = _n0; | |
266 | - | |
267 | - int N; | |
268 | - if(n_samples) | |
269 | - N = n_samples; | |
270 | - else | |
271 | - N = dispersion.size(); | |
272 | - | |
273 | - | |
274 | -#ifdef FFTW_AVAILABLE | |
275 | - //allocate memory for the FFT | |
276 | - complex<T>* Chi2 = (complex<T>*)fftw_malloc(sizeof(complex<T>) * N * pf); | |
277 | - complex<T>* Chi2FFT = (complex<T>*)fftw_malloc(sizeof(complex<T>) * N * pf); | |
278 | - complex<T>* Chi1 = (complex<T>*)fftw_malloc(sizeof(complex<T>) * N * pf); | |
279 | - | |
280 | - //create an FFT plan for the forward and inverse transforms | |
281 | - fftw_plan planForward, planInverse; | |
282 | - planForward = fftw_plan_dft_1d(N*pf, (fftw_complex*)Chi2, (fftw_complex*)Chi2FFT, FFTW_FORWARD, FFTW_ESTIMATE); | |
283 | - planInverse = fftw_plan_dft_1d(N*pf, (fftw_complex*)Chi2FFT, (fftw_complex*)Chi1, FFTW_BACKWARD, FFTW_ESTIMATE); | |
284 | - | |
285 | - float k, alpha; | |
286 | - T chi_temp; | |
287 | - | |
288 | - //the spectrum will be re-sampled in uniform values of wavenumber | |
289 | - T nuMin = _2wn(dispersion.back().lambda); | |
290 | - T nuMax = _2wn(dispersion.front().lambda); | |
291 | - T dnu = (nuMax - nuMin)/(N-1); | |
292 | - T lambda, tlambda; | |
293 | - for(int i=0; i<N; i++) | |
294 | - { | |
295 | - //go from back-to-front (wavenumber is the inverse of wavelength) | |
296 | - lambda = _wn(nuMax - i * dnu); | |
297 | - | |
298 | - //compute the frequency | |
299 | - k = 2 * PI / (lambda); | |
300 | - | |
301 | - //get the absorbance | |
302 | - alpha = getN(lambda).imag() * (2 * k); | |
303 | - | |
304 | - //compute chi2 | |
305 | - Chi2[i] = -alpha * (n0 / k); | |
306 | - } | |
41 | + std::stringstream lstream(line); //create a stream from the line | |
42 | + lstream.ignore(); //ignore the first character ('#') | |
307 | 43 | |
308 | - //use linear interpolation between the start and end points to pad the spectrum | |
309 | - //complex<T> nMin = dispersion.back(); | |
310 | - //complex<T> nMax = dispersion.front(); | |
311 | - T a; | |
312 | - for(int i=N; i<N*pf; i++) | |
313 | - { | |
314 | - //a = (T)(i-N)/(T)(N*pf - N); | |
315 | - //Chi2[i] = a * Chi2[0] + ((T)1 - a) * Chi2[N-1]; | |
44 | + std::string prop; //get the property name | |
45 | + lstream>>prop; | |
316 | 46 | |
317 | - Chi2[i] = 0.0;//Chi2[N-1]; | |
47 | + if(prop == "X"){ | |
48 | + std::string wp_name; | |
49 | + lstream>>wp_name; | |
50 | + if(wp_name == "microns") wp = microns; | |
51 | + else if(wp_name == "inverse_cm") wp = inverse_cm; | |
318 | 52 | } |
319 | - | |
320 | - //perform the FFT | |
321 | - fftw_execute(planForward); | |
322 | - | |
323 | - //perform the Hilbert transform in the Fourier domain | |
324 | - complex<T> j(0, 1); | |
325 | - for(int i=0; i<N*pf; i++) | |
326 | - { | |
327 | - //if w = 0, set the DC component to zero | |
328 | - if(i == 0) | |
329 | - Chi2FFT[i] *= (T)0.0; | |
330 | - //if w <0, multiply by i | |
331 | - else if(i < N*pf/2.0) | |
332 | - Chi2FFT[i] *= j; | |
333 | - //if i > N/2, multiply by -i | |
334 | - else | |
335 | - Chi2FFT[i] *= -j; | |
53 | + else if(prop == "Y"){ | |
54 | + std::string mp_name; | |
55 | + lstream>>mp_name; | |
56 | + if(mp_name == "ri") mp = ri; | |
57 | + else if(mp_name == "absorbance") mp = absorbance; | |
336 | 58 | } |
337 | 59 | |
338 | - //execute the inverse Fourier transform (completing the Hilbert transform) | |
339 | - fftw_execute(planInverse); | |
340 | - | |
341 | - //divide the Chi1 values by N | |
342 | - for(int i=0; i<N*pf; i++) | |
343 | - Chi1[i] /= (T)(N*pf); | |
344 | - | |
345 | - //create a new material | |
346 | - material<T> newM; | |
347 | - newM.dispersion.clear(); | |
348 | - refIndex<T> ri; | |
349 | - for(int i=0; i<N; i++) | |
350 | - { | |
351 | - ri.lambda = _wn(nuMax - i * dnu); | |
352 | - ri.n.real(Chi1[i].real() / (2 * n0) + n0); | |
353 | - ri.n.imag(getN(ri.lambda).imag()); | |
354 | - | |
355 | - newM.dispersion.push_back(ri); | |
356 | - } | |
357 | - | |
358 | - | |
359 | - //dispersion[i].n.real(Chi1[i].real() / (2 * n0) + n0); | |
360 | - | |
361 | - | |
362 | - /*//output the Absorbance value | |
363 | - ofstream outOrig("origN.txt"); | |
364 | - for(int i=0; i<N; i++) | |
365 | - outOrig<<dispersion[i].lambda<<" "<<dispersion[i].n.real()<<endl; | |
366 | - | |
367 | - //output the Chi2 value | |
368 | - ofstream outChi2("chi2.txt"); | |
369 | - for(int i=0; i<N; i++) | |
370 | - outChi2<<dispersion[i].lambda<<" "<<Chi2[i].real()<<endl; | |
371 | - | |
372 | - //output the Fourier transform | |
373 | - ofstream outFFT("chi2_FFT.txt"); | |
374 | - for(int i=0; i<N; i++) | |
375 | - { | |
376 | - float mag = std::sqrt( std::pow(Chi2FFT[i].real(), 2.0) + std::pow(Chi2FFT[i].imag(), 2.0)); | |
377 | - outFFT<<dispersion[i].lambda<<" "<<mag<<endl; | |
378 | - } | |
60 | + std::getline(ss, line); //get the next line | |
61 | + } | |
379 | 62 | |
380 | - //output the computed Chi1 value | |
381 | - ofstream outChi1("chi1.txt"); | |
382 | - for(int i=0; i<N; i++) | |
383 | - { | |
384 | - outChi1<<dispersion[i].lambda<<" "<<Chi1[i].real()<<" "<<Chi1[i].imag()<<endl; | |
385 | - } | |
63 | + function< T, rts::complex<T> >::process_string(str); | |
64 | + } | |
386 | 65 | |
387 | - ofstream outN("n.txt"); | |
388 | - for(int i=0; i<N; i++) | |
389 | - outN<<dispersion[i].lambda<<" "<<Chi1[i].real() / (2 * n0) + n0<<endl;*/ | |
66 | + void from_inverse_cm(){ | |
67 | + //convert inverse centimeters to wavelength (in microns) | |
68 | + for(unsigned int i=0; i<X.size(); i++) | |
69 | + X[i] = 10000 / X[i]; | |
390 | 70 | |
71 | + //reverse the function array | |
72 | + std::reverse(X.begin(), X.end()); | |
73 | + std::reverse(Y.begin(), Y.end()); | |
391 | 74 | |
392 | - //de-allocate memory | |
393 | - fftw_destroy_plan(planForward); | |
394 | - fftw_destroy_plan(planInverse); | |
395 | - fftw_free(Chi2); | |
396 | - fftw_free(Chi2FFT); | |
397 | - fftw_free(Chi1); | |
75 | + } | |
398 | 76 | |
399 | - return newM; | |
400 | -#else | |
401 | - std::cout<<"MATERIAL Error: Must have FFTW in order to compute Kramers-Kronig."<<std::endl; | |
402 | - return material<T>(); | |
403 | -#endif | |
404 | - } | |
77 | + void init(){ | |
78 | + bounding[0] = bounding[1] = rts::complex<T>(1, 0); | |
79 | + } | |
405 | 80 | |
406 | - material(T lambda = 1, T n = 1, T k = 0) | |
407 | - { | |
408 | - dispersion.insert(lambda, complex<T>(n, k)); | |
409 | - /*//create a default refractive index | |
410 | - refIndex<T> def; | |
411 | - def.lambda = lambda; | |
412 | - def.n.real(n); | |
413 | - def.n.imag(k); | |
414 | - add(def); | |
415 | - */ | |
416 | - //set n0 | |
417 | - n0 = 0; | |
418 | - } | |
419 | - | |
420 | - material(std::string filename, std::string format = "", T scaleA = 1.0) | |
421 | - { | |
422 | - fromFile(filename, format); | |
423 | - n0 = 0; | |
424 | - } | |
425 | - | |
426 | - void fromFile(std::string filename, std::string format = "", T scaleA = 1.0) | |
427 | - { | |
428 | - name = filename; | |
429 | - //clear any previous values | |
430 | - dispersion = rts::function< T, complex<T> >(); | |
431 | - | |
432 | - //load the file into a string | |
433 | - std::ifstream ifs(filename.c_str()); | |
434 | - | |
435 | - std::string line; | |
436 | - | |
437 | - if(!ifs.is_open()) | |
438 | - { | |
439 | - std::cout<<"Material Error -- file not found: "<<filename<<std::endl; | |
440 | - exit(1); | |
441 | - } | |
442 | - | |
443 | - //process the file as a string | |
444 | - std::string instr((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); | |
445 | - fromStr(instr, format, scaleA); | |
446 | - } | |
447 | - | |
448 | - void fromStr(std::string str, std::string format = "", T scaleA = 1.0) | |
449 | - { | |
450 | - //create a string stream to process the input data | |
451 | - std::stringstream ss(str); | |
452 | - | |
453 | - //this string will be read line-by-line (where each line is an entry) | |
454 | - std::string line; | |
455 | - | |
456 | - //if the format is not provided, see if it is in the file, otherwise use a default | |
457 | - if(format == "") | |
458 | - { | |
459 | - //set a default format of "lambda,n,k" | |
460 | - format = "microns,n,k"; | |
461 | - | |
462 | - //see if the first line is a comment | |
463 | - char c = ss.peek(); | |
464 | - if(c == '#') | |
465 | - { | |
466 | - //get the first line | |
467 | - getline(ss, line); | |
468 | - //look for a bracket, denoting the start of a format string | |
469 | - int istart = line.find('['); | |
470 | - if(istart != std::string::npos) | |
471 | - { | |
472 | - //look for a bracket terminating the format string | |
473 | - int iend = line.find(']'); | |
474 | - if(iend != std::string::npos) | |
475 | - { | |
476 | - //read the string between the brackets | |
477 | - format = line.substr(istart+1, iend - istart - 1); | |
478 | - } | |
479 | - } | |
480 | - } | |
481 | - | |
482 | - } | |
483 | - | |
484 | - entryType<T> entry(format); | |
485 | - | |
486 | - //std::cout<<"Loading material with format: "<<format<<std::endl; | |
487 | - | |
488 | - while(!ss.eof()) | |
489 | - { | |
490 | - //read a line from the string | |
491 | - getline(ss, line); | |
492 | - | |
493 | - //if the line is not a comment, process it | |
494 | - if(line[0] != '#') | |
495 | - { | |
496 | - //load the entry and add it to the dispersion list | |
497 | - add(entry.inputEntry(line, scaleA).lambda, entry.inputEntry(line, scaleA).n); | |
498 | - } | |
499 | - //generally have to peek to trigger the eof flag | |
500 | - ss.peek(); | |
501 | - } | |
502 | - | |
503 | - //sort the vector by lambda | |
504 | - //sort(dispersion.begin(), dispersion.end(), &material<T>::compare); | |
505 | - } | |
506 | - | |
507 | - //convert the material to a string | |
508 | - std::string toStr(std::string format = "microns,n,k", bool reverse_order = false) | |
509 | - { | |
510 | - std::stringstream ss; | |
511 | - entryType<T> entry(format); | |
512 | - | |
513 | - if(reverse_order) | |
514 | - { | |
515 | - for(int l=dispersion.size() - 1; l>=0; l--) | |
516 | - { | |
517 | - if(l < dispersion.size() - 1) ss<<std::endl; | |
518 | - ss<<entry.outputEntry(dispersion[l]); | |
519 | - } | |
520 | 81 | |
521 | - } | |
522 | - else | |
523 | - { | |
524 | - for(unsigned int l=0; l<dispersion.size(); l++) | |
525 | - { | |
526 | - if(l > 0) ss<<std::endl; | |
527 | - ss<<entry.outputEntry(dispersion[l]); | |
528 | - } | |
529 | - } | |
530 | - | |
531 | - return ss.str(); | |
532 | - } | |
533 | - | |
534 | - void save(std::string filename, std::string format = "microns,n,k", bool reverse_order = false) | |
535 | - { | |
536 | - std::ofstream outfile(filename.c_str()); | |
537 | - outfile<<"#material file saved as [" + format + "]"<<std::endl; | |
538 | - outfile<<toStr(format, reverse_order)<<std::endl; | |
539 | - | |
540 | - } | |
541 | - | |
542 | - //convert between wavelength and wavenumber | |
543 | - /*void nu2lambda(T s = (T)1) | |
544 | - { | |
545 | - for(int i=0; i<dispersion.size(); i++) | |
546 | - dispersion[i].lambda = s/dispersion[i].lambda; | |
547 | - } | |
548 | - | |
549 | - void lambda2nu(T s = (T)1) | |
550 | - { | |
551 | - for(int i=0; i<dispersion.size(); i++) | |
552 | - dispersion[i].lambda = s/dispersion[i].lambda; | |
553 | - }*/ | |
554 | - | |
555 | - | |
556 | - refIndex<T>& operator[](unsigned int i) | |
557 | - { | |
558 | - return dispersion[i]; | |
82 | +public: | |
559 | 83 | |
560 | - } | |
84 | + material(std::string filename, wave_property wp, material_property mp){ | |
85 | + name = filename; | |
86 | + load(filename, wp, mp); | |
87 | + } | |
561 | 88 | |
562 | - complex<T> getN(T l) | |
563 | - { | |
564 | - //return complex<T>(1.0, 0.0); | |
565 | - complex<T> ri = dispersion.linear(l) + n0; | |
566 | - return ri; | |
567 | - } | |
89 | + material(std::string filename){ | |
90 | + name = filename; | |
91 | + load(filename); | |
92 | + } | |
568 | 93 | |
569 | - function<T, complex<T> > getF() | |
570 | - { | |
571 | - return dispersion + complex<T>(n0, 0.0); | |
572 | - } | |
94 | + material(){ | |
95 | + init(); | |
96 | + } | |
573 | 97 | |
574 | - //returns the scattering efficiency at wavelength l | |
575 | - complex<T> eta(T l) | |
576 | - { | |
577 | - //get the refractive index | |
578 | - complex<T> ri = getN(l); | |
98 | + complex<T> getN(T lambda){ | |
99 | + return function< T, complex<T> >::linear(lambda); | |
100 | + } | |
579 | 101 | |
580 | - //convert the refractive index to scattering efficiency | |
581 | - return ri*ri - 1.0; | |
102 | + void load(std::string filename, wave_property wp, material_property mp){ | |
582 | 103 | |
583 | - } | |
584 | - //interpolate the given lambda value and return the index of refraction | |
585 | - complex<T> operator()(T l) | |
586 | - { | |
587 | - return getN(l); | |
588 | - } | |
104 | + //load the file as a function | |
105 | + function< T, complex<T> >::load(filename); | |
106 | + } | |
589 | 107 | |
108 | + void load(std::string filename){ | |
109 | + | |
110 | + wave_property wp = inverse_cm; | |
111 | + material_property mp = ri; | |
112 | + //turn the file into a string | |
113 | + std::ifstream t(filename.c_str()); //open the file as a stream | |
114 | + | |
115 | + if(!t){ | |
116 | + std::cout<<"ERROR: Couldn't open the material file '"<<filename<<"'"<<std::endl; | |
117 | + exit(1); | |
118 | + } | |
119 | + std::string str((std::istreambuf_iterator<char>(t)), | |
120 | + std::istreambuf_iterator<char>()); | |
121 | + | |
122 | + //process the header information | |
123 | + process_header(str, wp, mp); | |
124 | + | |
125 | + //convert units | |
126 | + if(wp == inverse_cm) | |
127 | + from_inverse_cm(); | |
128 | + //set the bounding values | |
129 | + bounding[0] = Y[0]; | |
130 | + bounding[1] = Y.back(); | |
131 | + } | |
132 | + std::string str(){ | |
133 | + std::stringstream ss; | |
134 | + ss<<name<<std::endl; | |
135 | + ss<<function< T, complex<T> >::str(); | |
136 | + return ss.str(); | |
137 | + } | |
138 | + std::string get_name(){ | |
139 | + return name; | |
140 | + } | |
590 | 141 | |
591 | - }; | |
592 | -} //end namespace rts | |
142 | + void set_name(std::string str){ | |
143 | + name = str; | |
144 | + } | |
593 | 145 | |
594 | -template <typename T> | |
595 | -std::ostream& operator<<(std::ostream& os, rts::material<T> m) | |
596 | -{ | |
597 | - os<<m.toStr(); | |
146 | +}; | |
598 | 147 | |
599 | - return os; | |
600 | 148 | } |
601 | 149 | |
602 | 150 | |
603 | 151 | |
152 | + | |
604 | 153 | #endif | ... | ... |
optics/mirst-1d.cuh
1 | 1 | #include "../optics/material.h" |
2 | 2 | #include "../math/complexfield.cuh" |
3 | +#include "../math/constants.h" | |
3 | 4 | |
4 | 5 | #include "cufft.h" |
5 | 6 | |
... | ... | @@ -51,7 +52,7 @@ __global__ void gpu_mirst1d_layer_fft(complex<T>* dest, complex<T>* ri, |
51 | 52 | |
52 | 53 | //T l = w * ri[inu].real(); |
53 | 54 | //complex<T> e(0.0, -2 * PI * fz * (zf[inu] + zR/2 - l/2.0)); |
54 | - complex<T> e(0, -2 * PI * fz * (zf[inu] + opl/2)); | |
55 | + complex<T> e(0, -2 * rtsPI * fz * (zf[inu] + opl/2)); | |
55 | 56 | |
56 | 57 | complex<T> eta = ri[inu] * ri[inu] - 1; |
57 | 58 | |
... | ... | @@ -59,7 +60,7 @@ __global__ void gpu_mirst1d_layer_fft(complex<T>* dest, complex<T>* ri, |
59 | 60 | if(ifz == 0) |
60 | 61 | dest[i] += opl * exp(e) * eta * src[inu]; |
61 | 62 | else |
62 | - dest[i] += opl * exp(e) * eta * src[inu] * sin(PI * fz * opl) / (PI * fz * opl); | |
63 | + dest[i] += opl * exp(e) * eta * src[inu] * sin(rtsPI * fz * opl) / (rtsPI * fz * opl); | |
63 | 64 | } |
64 | 65 | |
65 | 66 | template<typename T> |
... | ... | @@ -139,7 +140,7 @@ __global__ void gpu_mirst1d_apply_filter(complex<T>* sampleFFT, T* lambda, |
139 | 140 | //compute the final filter |
140 | 141 | T mirst = 0; |
141 | 142 | if(fz != 0) |
142 | - mirst = 2 * PI * r * s * Q * (1/fz); | |
143 | + mirst = 2 * rtsPI * r * s * Q * (1/fz); | |
143 | 144 | |
144 | 145 | sampleFFT[i] *= mirst; |
145 | 146 | |
... | ... | @@ -246,7 +247,7 @@ private: |
246 | 247 | //store the refractive index and source profile in a CPU array |
247 | 248 | for(int inu=0; inu<S; inu++){ |
248 | 249 | //save the refractive index to the GPU |
249 | - ri = matlist[n].getN(lambdas[inu]); | |
250 | + ri = matlist[n].getN(lambdas[inu]); | |
250 | 251 | HANDLE_ERROR(cudaMemcpy( gpuRi + inu, &ri, sizeof(complex<T>), cudaMemcpyHostToDevice )); |
251 | 252 | |
252 | 253 | //save the source profile to the GPU |
... | ... | @@ -320,6 +321,7 @@ public: |
320 | 321 | pad = padding; |
321 | 322 | NA[0] = 0; |
322 | 323 | NA[1] = 0.8; |
324 | + S = 0; | |
323 | 325 | } |
324 | 326 | |
325 | 327 | //add a layer, thickness = microns |
... | ... | @@ -397,16 +399,17 @@ public: |
397 | 399 | std::string str(){ |
398 | 400 | |
399 | 401 | stringstream ss; |
400 | - | |
402 | + ss<<"1D MIRST Simulation========================="<<std::endl; | |
401 | 403 | ss<<"z-axis resolution: "<<Z<<std::endl; |
404 | + ss<<"simulation domain: ["<<lambdas[0]<<", "<<lambdas.back()<<"]"<<std::endl; | |
402 | 405 | ss<<"number of wavelengths: "<<lambdas.size()<<std::endl; |
403 | 406 | ss<<"padding: "<<pad<<std::endl; |
404 | 407 | ss<<"sample thickness: "<<thickness()<<" um"<<std::endl; |
405 | 408 | ss<<"dz: "<<dz()<<" um"<<std::endl; |
406 | 409 | ss<<std::endl; |
407 | - ss<<"layers: "<<layers.size()<<" -----------------"<<std::endl; | |
410 | + ss<<layers.size()<<" layers-------------"<<std::endl; | |
408 | 411 | for(unsigned int l=0; l<layers.size(); l++) |
409 | - ss<<"layer "<<l<<": "<<layers[l]<<" um"<<" ("<<matlist[l].getName()<<")"<<std::endl; | |
412 | + ss<<"layer "<<l<<": "<<layers[l]<<" um"<<"---------"<<std::endl<<matlist[l].str()<<std::endl; | |
410 | 413 | |
411 | 414 | return ss.str(); |
412 | 415 | |
... | ... | @@ -417,4 +420,4 @@ public: |
417 | 420 | |
418 | 421 | }; |
419 | 422 | |
420 | -} | |
421 | 423 | \ No newline at end of file |
424 | +} | ... | ... |
ui/arguments.h
... | ... | @@ -196,15 +196,15 @@ namespace rts{ |
196 | 196 | if(d == 0) |
197 | 197 | ss<<desc[0]; |
198 | 198 | else |
199 | - ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<desc[d]; | |
199 | + ss<<std::endl<<std::setfill(' ')<<std::setw(width)<<" "<<desc[d]; | |
200 | 200 | |
201 | 201 | } |
202 | 202 | |
203 | 203 | //output the range in the right column |
204 | 204 | if(range != "" && ansi) |
205 | - ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<" "<<std::string("setw(width)<<" "<<" "<<std::string("\033[1;36m") + range + "\033[0m";33[1;36m") + range + "setw(width)<<" "<<" "<<std::string("\033[1;36m") + range + "\033[0m";33[0m"; | |
205 | + ss<<std::endl<<std::setfill(' ')<<std::setw(width)<<" "<<" "<<std::string("setw(width)<<" "<<" "<<std::string("\033[1;36m") + range + "\033[0m";33[1;36m") + range + "setw(width)<<" "<<" "<<std::string("\033[1;36m") + range + "\033[0m";33[0m"; | |
206 | 206 | else if(range != "") |
207 | - ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<" "<<range; | |
207 | + ss<<std::endl<<std::setfill(' ')<<std::setw(width)<<" "<<" "<<range; | |
208 | 208 | |
209 | 209 | return ss.str(); |
210 | 210 | } |
... | ... | @@ -253,7 +253,10 @@ namespace rts{ |
253 | 253 | |
254 | 254 | public: |
255 | 255 | |
256 | - arglist(){ col_width = 0; } | |
256 | + arglist(){ | |
257 | + col_width = 0; | |
258 | + ansi = true; | |
259 | + } | |
257 | 260 | |
258 | 261 | void set_ansi(bool b) |
259 | 262 | { |
... | ... | @@ -295,9 +298,9 @@ namespace rts{ |
295 | 298 | if(si != -1 && a == sections[si].index) |
296 | 299 | { |
297 | 300 | if(ansi) |
298 | - ss<<std::endl<<std::left<<setfill('=')<<setw(col_width)<<std::string("setw(col_width)<<std::string("\033[1;31m") + sections[si].name<<"\033[0m"<<std::endl;33[1;31m") + sections[si].name<<"setw(col_width)<<std::string("\033[1;31m") + sections[si].name<<"\033[0m"<<std::endl;33[0m"<<std::endl; | |
301 | + ss<<std::endl<<std::left<<std::setfill('=')<<std::setw(col_width)<<std::string("setw(col_width)<<std::string("\033[1;31m") + sections[si].name<<"\033[0m"<<std::endl;33[1;31m") + sections[si].name<<"setw(col_width)<<std::string("\033[1;31m") + sections[si].name<<"\033[0m"<<std::endl;33[0m"<<std::endl; | |
299 | 302 | else |
300 | - ss<<std::endl<<std::left<<setfill('=')<<setw(col_width)<<sections[si].name<<std::endl; | |
303 | + ss<<std::endl<<std::left<<std::setfill('=')<<std::setw(col_width)<<sections[si].name<<std::endl; | |
301 | 304 | si++; |
302 | 305 | if(si == sections.size()) si = -1; |
303 | 306 | } |
... | ... | @@ -326,7 +329,7 @@ namespace rts{ |
326 | 329 | { |
327 | 330 | args[i].set(_value); |
328 | 331 | //adjust the column width if necessary |
329 | - col_width = max(col_width, args[i].col_width()); | |
332 | + col_width = std::max(col_width, args[i].col_width()); | |
330 | 333 | } |
331 | 334 | else |
332 | 335 | std::cout<<"ERROR - Argument not recognized: "<<_name<<std::endl; | ... | ... |