Skip to content

Commit c62895a

Browse files
committed
prepare advance electric field according to path length
not actually advance, to ensure tests run at this point
1 parent be2efd1 commit c62895a

File tree

11 files changed

+88
-27
lines changed

11 files changed

+88
-27
lines changed

Intern/rayx-core/src/Element/Behaviour.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ Behaviour makeRZPBehaviour(const DesignElement& dele) {
128128

129129
// designEnergy = designEnergy; // if Auto == true, take energy of Source
130130
// (param sourceEnergy), else designEnergy = designEnergy
131-
auto designWavelength = designEnergy == 0 ? 0 : hvlam(designEnergy);
131+
auto designWavelength = designEnergy == 0 ? 0 : energyToWaveLength(designEnergy);
132132
auto additionalOrder = double(dele.getAdditionalOrder());
133133

134134
auto imageType = dele.getImageType();
@@ -160,4 +160,4 @@ Behaviour makeFoil(const DesignElement& dele) {
160160
});
161161
}
162162

163-
} // namespace RAYX
163+
} // namespace RAYX

Intern/rayx-core/src/Shader/Behave.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Ray behaveCrystal(Ray r, const Behaviour behaviour, [[maybe_unused]] Collision c
2828
double polFactorS = 1.0;
2929
double polFactorP = std::fabs(cos(2 * bragg));
3030

31-
double wavelength = inm2eV / r.m_energy;
31+
double wavelength = energyToWaveLength(r.m_energy);
3232
double gamma = getDiffractionPrefactor(wavelength, b.m_unitCellVolume);
3333

3434
std::complex<double> F0(b.m_structureFactorReF0, b.m_structureFactorImF0);
@@ -80,7 +80,7 @@ Ray behaveSlit(Ray r, const Behaviour behaviour, Rand& __restrict rand) {
8080

8181
double dPhi = 0;
8282
double dPsi = 0;
83-
double wavelength = hvlam(r.m_energy);
83+
double wavelength = energyToWaveLength(r.m_energy);
8484

8585
// this was previously called "diffraction"
8686
if (wavelength > 0) {
@@ -109,7 +109,7 @@ RAYX_FN_ACC
109109
Ray behaveRZP(Ray r, const Behaviour behaviour, const Collision col, Rand& __restrict rand) {
110110
RZPBehaviour b = deserializeRZP(behaviour);
111111

112-
double WL = hvlam(r.m_energy);
112+
double WL = energyToWaveLength(r.m_energy);
113113
double Ord = b.m_orderOfDiffraction;
114114
int additional_order = int(b.m_additionalOrder);
115115

@@ -137,7 +137,7 @@ Ray behaveGrating(Ray r, const Behaviour behaviour, const Collision col) {
137137
GratingBehaviour b = deserializeGrating(behaviour);
138138

139139
// vls parameters passed in q.elementParams
140-
double WL = hvlam(r.m_energy);
140+
double WL = energyToWaveLength(r.m_energy);
141141
double lineDensity = b.m_lineDensity;
142142
double orderOfDiffraction = b.m_orderOfDiffraction;
143143

@@ -177,7 +177,7 @@ RAYX_FN_ACC
177177
Ray behaveFoil(Ray r, const Behaviour behaviour, const Collision col, const int material, const int* __restrict materialIndices,
178178
const double* __restrict materialTable) {
179179
FoilBehaviour f = deserializeFoil(behaviour);
180-
const double wavelength = hvlam(r.m_energy);
180+
const double wavelength = energyToWaveLength(r.m_energy);
181181

182182
const auto indexVacuum = complex::Complex(1., 0.);
183183
const auto indexMaterial = getRefractiveIndex(r.m_energy, material, materialIndices, materialTable);

Intern/rayx-core/src/Shader/Constants.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,9 @@
88

99
namespace RAYX {
1010

11-
// inverse nanometer-electron volt relationship / reziprocal factor
11+
/// inverse nanometer-electron volt relationship / reziprocal factor
1212
constexpr double INV_NM_TO_EVOLT = 1239.841984332002622;
1313

14-
// inverse nanometer-electron volt relationship / reziprocal factor
15-
constexpr double inm2eV = 1.239852e3; // TODO: Check, find better name maybe
16-
1714
constexpr double PI = 3.14159265358979323846264338327950;
1815
// 141592653589793238462643383279502884197169399
1916

@@ -39,7 +36,6 @@ constexpr double ELECTRON_MASS = 9.1093837015e-31; // Checked 2019-7-25, PB, NI
3936
/// RAY-UI shortcut for getFactorElectronEnergy
4037
constexpr double FACTOR_ELECTRON_ENERGY_SC = 1957;
4138

42-
//
4339
constexpr double FINE_STRUCTURE_CONSTANT = 7.2973525693e-3; // Checked 2020-2-18, PB, NIST: fine-structure constant, no units
4440

4541
/// \f$\epsilon_0\f$ [As/Vm]. vacuum electric permittivity.
@@ -53,6 +49,6 @@ constexpr double FACTOR_SCHWINGER_RAY = 1.2556937e15;
5349
constexpr double ELECTRIC_PERMITIVITY_MULTIPLIES_SPEED_OF_LIGHT = 2.6544187279929558624e-3;
5450

5551
constexpr double ELECTRON_RADIUS = 2.8179403205e-6; // Classical electron radius (nm)
56-
5752
// constexpr double ELECTRON_RADIUS = (ELEMENTARY_CHARGE / (SPEED_OF_LIGHT * SPEED_OF_LIGHT)) * 1.e9; // Classical electron radius in nm
53+
5854
} // namespace RAYX

Intern/rayx-core/src/Shader/Crystal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ inline double getTheta(Ray r, glm::dvec3 normal, double offsetAngle) {
5959
RAYX_FN_ACC
6060
inline double getBraggAngle(double energy, double dSpacing2) {
6161
int order = 1;
62-
double wavelength = hvlam(energy);
62+
double wavelength = energyToWaveLength(energy);
6363
double theta_factor = (order * wavelength) / dSpacing2;
6464

6565
// Check for physical validity

Intern/rayx-core/src/Shader/DynamicElements.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "Behave.h"
44
#include "Collision.h"
5+
#include "RecordEvent.h"
56
#include "Utils.h"
67

78
namespace RAYX {
@@ -64,7 +65,7 @@ void dynamicElements(const int gid, const InvState& inv, OutputEvents& outputEve
6465

6566
// write ray in local element coordinates to global memory
6667
if (numRecorded < inv.maxEvents && (!inv.recordMask || inv.recordMask[col.elementIndex])) {
67-
outputEvents.events[gid * inv.maxEvents + numRecorded] = ray;
68+
recordEvent(outputEvents.events, ray, getRecordIndex(gid, numRecorded, inv.maxEvents));
6869
++numRecorded;
6970
}
7071

@@ -75,9 +76,9 @@ void dynamicElements(const int gid, const InvState& inv, OutputEvents& outputEve
7576
// check if the number of events exceeds capacity
7677
if (!colNotFound && inv.sequential == Sequential::No && isRayActive(ray.m_eventType)) {
7778
Collision col = findCollisionNonSequential(ray.m_position, ray.m_direction, inv.elements, inv.numElements, rand);
78-
if (col.found) {
79+
if (col.found && (!inv.recordMask || inv.recordMask[col.elementIndex])) {
7980
ray = terminateRay(ray, EventType::TooManyEvents);
80-
outputEvents.events[gid * inv.maxEvents + inv.maxEvents - 1] = ray;
81+
recordEvent(outputEvents.events, ray, getRecordIndex(gid, inv.maxEvents, inv.maxEvents - 1));
8182
}
8283
}
8384

Intern/rayx-core/src/Shader/ElectricField.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@ inline double intensity(const Stokes stokes) { return stokes.x; }
2727
RAYX_FN_ACC
2828
inline double degreeOfPolarization(const Stokes stokes) { return glm::length(glm::vec3(stokes.y, stokes.z, stokes.w)) / stokes.x; }
2929

30+
/**
31+
* Advances an electric field propagating in a certain media by a certain distance
32+
* @param field electric field of incident photon
33+
* @param waveLength wavelength of incident photon
34+
* @param distance distance traveled in media
35+
* @param ior_real real component of complex index of refraction of media
36+
* @return advanced electric field
37+
* @TODO: check if waveLength and distance use the same
38+
*/
39+
RAYX_FN_ACC
40+
inline ElectricField advanceElectricField(const ElectricField field, double waveLength, const double distance, const float ior_real) {
41+
// bring wavelength from nanometers into millimeters
42+
waveLength /= 1e6;
43+
44+
// compute wave number (2π * n / λ)
45+
const double waveNumber = 2.0 * PI * ior_real / waveLength;
46+
47+
// reduce the distance modulo wavelength to avoid large angle errors
48+
const double reducedDistance = std::fmod(distance, waveLength);
49+
50+
// compute the phase shift using the reduced distance
51+
const double deltaPhi = waveNumber * reducedDistance;
52+
53+
// apply the complex exponential of the phase shift
54+
const auto phaseShift = complex::exp(complex::Complex(0.0, deltaPhi));
55+
56+
return field * phaseShift;
57+
}
58+
3059
/*
3160
* rotation of electric field
3261
*/

Intern/rayx-core/src/Shader/Ray.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct RAYX_API Ray {
4040
/// The complex electric field
4141
ElectricField m_field;
4242

43+
// TODO: until we support transmission in media with refractive index != 1.0, path length equivalent to optical path length. in future, we should
44+
// consider renaming this attribute to optical path length
4345
/// The distance that this ray has already traveled (in mm).
4446
double m_pathLength;
4547

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "Ray.h"
4+
#include "Utils.h"
5+
6+
namespace RAYX {
7+
8+
RAYX_FN_ACC
9+
inline int getRecordIndex(const int pathId, const int bounceId, const int maxEvents) { return pathId * maxEvents + bounceId; }
10+
11+
RAYX_FN_ACC
12+
inline void recordEvent(Ray* __restrict output, Ray& __restrict ray, const int recordIndex) {
13+
// TODO: this code is currently disabled to ensure all tests run with the changes that were made. in the next commit this code will be enabled and
14+
// seeded will be override, due to changes in the electric field of written rays
15+
16+
// we use a temporary here, to avoid copying the whole ray when writing the ray with the correct field value
17+
// const auto tmpField = ray.m_field;
18+
// ray.m_field = advanceElectricField(ray.m_field, energyToWaveLength(ray.m_energy), ray.m_pathLength, 1.0);
19+
output[recordIndex] = ray;
20+
// ray.m_field = tmpField;
21+
}
22+
23+
} // namespace RAYX

Intern/rayx-core/src/Shader/Utils.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44

55
namespace RAYX {
66

7-
// converts energy in eV to wavelength in nm
87
RAYX_FN_ACC
9-
double RAYX_API hvlam(double x) {
10-
if (x == 0) {
11-
return 0.0;
12-
}
8+
double RAYX_API energyToWaveLength(double x) {
139
return INV_NM_TO_EVOLT / x;
1410
}
1511

12+
RAYX_FN_ACC
13+
double waveLengthToEnergy(const double waveLength) { return INV_NM_TO_EVOLT / waveLength; }
14+
1615
// originally we calculcated 1/0, which might be UB (https://stackoverflow.com/questions/5802351/what-happens-when-you-divide-by-0-in-a-shader).
1716
// `return 1e+308 * 2.0;` correctly returns positive infinity on my machine (Rudi), but we have no guarantee that it always does.
1817
// So instead we return a sufficiently large number to be used like positive infinity.

Intern/rayx-core/src/Shader/Utils.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,19 @@
55

66
namespace RAYX {
77

8-
// converts energy in eV to wavelength in nm
9-
RAYX_FN_ACC double RAYX_API hvlam(double x);
8+
/**
9+
* converts energy (eV) to wavelength (nm)
10+
* @param energy energy of a photon in eV. must not be 0
11+
* @return wavelength of photon in nm
12+
*/
13+
RAYX_FN_ACC double RAYX_API energyToWaveLength(double energy);
14+
15+
/**
16+
* Convert photon wavelength (nm) to energy (eV)
17+
* @param wavelength of photon in nm. must not be 0
18+
* @return energy energy of a photon in eV
19+
*/
20+
RAYX_FN_ACC double RAYX_API waveLengthToEnergy(const double waveLength);
1021

1122
RAYX_FN_ACC double infinity();
1223

0 commit comments

Comments
 (0)