-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCoupledWaveStructure.h
More file actions
139 lines (126 loc) · 5.45 KB
/
CoupledWaveStructure.h
File metadata and controls
139 lines (126 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#pragma once
#include "tira/optics/planewave.h"
#include <vector>
#include <fstream>
/// Coupled Wave structure file format
// [64-bit unsigned int] precision (number of bytes, 4 = float, 8 - double)
// [64-bit unsigned int] number of incident plane waves
// FOR EACH INCIDENT PLANE WAVE
// [N-bit float] E0.x (real)
// [N-bit float] E0.x (imaginary)
// [N-bit float] E0.y (real)
// [N-bit float] E0.y (imaginary)
// [N-bit float] k.x (real)
// [N-bit float] k.x (imaginary)
// [N-bit float] k.y (real)
// [N-bit float] k.y (imaginary)
// [N-bit float] k.z (real)
// [N-bit float] k.z (imaginary)
// FOR EACH LAYER
// [N-bit float] z coordinate
// [64-bit unsigned int] number of reflected plane waves
// FOR EACH REFLECTED PLANE WAVE
// [N-bit float] E0.x (real)
// [N-bit float] E0.x (imaginary)
// [N-bit float] E0.y (real)
// [N-bit float] E0.y (imaginary)
// [N-bit float] k.x (real)
// [N-bit float] k.x (imaginary)
// [N-bit float] k.y (real)
// [N-bit float] k.y (imaginary)
// [N-bit float] k.z (real)
// [N-bit float] k.z (imaginary)
// [64-bit unsigned int] number of transmitted plane waves
// FOR EACH TRANSMITTED PLANE WAVE
// [N-bit float] E0.x (real)
// [N-bit float] E0.x (imaginary)
// [N-bit float] E0.y (real)
// [N-bit float] E0.y (imaginary)
// [N-bit float] k.x (real)
// [N-bit float] k.x (imaginary)
// [N-bit float] k.y (real)
// [N-bit float] k.y (imaginary)
// [N-bit float] k.z (real)
// [N-bit float] k.z (imaginary)
template <typename T>
struct HomogeneousLayer {
T z; // z coordinate of the layer
std::vector < tira::planewave<T> > Pr; // plane waves reflected off of the boundary (along -z)
std::vector < tira::planewave<T> > Pt; // plane wave transmitted through the boundary (along z)
};
template <typename T>
class CoupledWaveStructure {
public:
std::vector< tira::planewave<T> > Pi; // incoming plane waves
std::vector< HomogeneousLayer<T> > Layers; // homogeneous sample layers and their respective plane waves
void save(std::string filename) {
std::ofstream file(filename, std::ios::out | std::ios::binary);
size_t sizeof_T = sizeof(T);
file.write((char*)&sizeof_T, sizeof(size_t)); // output the precision (float = 4, double = 8)
size_t sizeof_Pi = Pi.size();
file.write((char*)&sizeof_Pi, sizeof(size_t)); // output the number of incident plane waves
for (size_t iPi = 0; iPi < Pi.size(); iPi++) {
file.write((char*)&Pi[iPi], sizeof(tira::planewave<T>));
}
size_t sizeof_Layers = Layers.size();
size_t sizeof_Pr, sizeof_Pt; // Pr/Pt has a dim of M. While the inside field has a dim of M*2M
file.write((char*)&sizeof_Layers, sizeof(size_t)); // output the number of homogeneous layers
for (size_t iLayers = 0; iLayers < sizeof_Layers; iLayers++) {
file.write((char*)&Layers[iLayers].z, sizeof(T)); // output the layer position
sizeof_Pr = Layers[iLayers].Pr.size();
file.write((char*)&sizeof_Pr, sizeof(size_t)); // output the number of reflected plane waves
for (size_t iPr = 0; iPr < Layers[iLayers].Pr.size(); iPr++) {
file.write((char*)&Layers[iLayers].Pr[iPr], sizeof(tira::planewave<T>));
}
sizeof_Pt = Layers[iLayers].Pt.size();
file.write((char*)&sizeof_Pt, sizeof(size_t)); // output the number of transmitted plane waves
for (size_t iPt = 0; iPt < Layers[iLayers].Pt.size(); iPt++) {
file.write((char*)&Layers[iLayers].Pt[iPt], sizeof(tira::planewave<T>));
}
}
file.close();
}
bool load(std::string filename) {
std::ifstream file(filename, std::ios::in | std::ios::binary);
if (!file) return false;
size_t sizeof_T;
file.read((char*)&sizeof_T, sizeof(size_t)); // read the precision (float = 4, double = 8)
size_t sizeof_Pi;
file.read((char*)&sizeof_Pi, sizeof(size_t)); // read the number of incident plane waves
Pi.resize(sizeof_Pi); // allocate space for the incident plane waves
for (size_t iPi = 0; iPi < Pi.size(); iPi++) {
file.read((char*)&Pi[iPi], sizeof(tira::planewave<T>));
}
size_t sizeof_Layers;
size_t sizeof_Pr, sizeof_Pt;
file.read((char*)&sizeof_Layers, sizeof(size_t)); // read the number of homogeneous layers
Layers.resize(sizeof_Layers); // allocate space for the layer structures
for (size_t iLayers = 0; iLayers < sizeof_Layers; iLayers++) {
file.read((char*)&Layers[iLayers].z, sizeof(T)); // read the layer position
file.read((char*)&sizeof_Pr, sizeof(size_t)); // read the number of reflected plane waves
Layers[iLayers].Pr.resize(sizeof_Pr); // allocate space for the reflected waves
for (size_t iPr = 0; iPr < Layers[iLayers].Pr.size(); iPr++) {
file.read((char*)&Layers[iLayers].Pr[iPr], sizeof(tira::planewave<T>));
}
file.read((char*)&sizeof_Pt, sizeof(size_t)); // read the number of transmitted plane waves
Layers[iLayers].Pt.resize(sizeof_Pt); // allocate space for the transmitted plane waves
for (size_t iPt = 0; iPt < Layers[iLayers].Pt.size(); iPt++) {
file.read((char*)&Layers[iLayers].Pt[iPt], sizeof(tira::planewave<T>));
}
}
file.close();
return true;
}
/// <summary>
/// Get the plane index from the given z coordinate
/// </summary>
/// <param name="z">spatial z coordinate to be tested</param>
/// <returns>Returns an index to the next plane along the positive z axis </returns>
size_t getPlaneIndex(T z) {
for (size_t l = 0; l < Layers.size(); l++) {
if (z >= Layers[l].z)
return l + 1;
}
return 0;
}
};