125 !finite(angleDegrees) || angleDegrees < 0.0 || angleDegrees >= 89.9 ||
126 !finite(hbar) || hbar <= 0.0) {
136 const double theta = angleDegrees * kPi / 180.0;
137 const double px = p * std::cos(theta);
138 const double py = p * std::sin(theta);
139 if (!(px > 1.0e-10))
return out;
142 const double rest = c.
restMass * cc * cc;
147 const Vec2 incident = eigenSpinor(C(px, 0.0), py, e, cc, rest);
148 const Vec2 reflected = eigenSpinor(C(-px, 0.0), py, e, cc, rest);
149 const Vec2 barrierForward = eigenSpinor(qx, py, er, cc, rest);
150 const Vec2 barrierBackward = eigenSpinor(-qx, py, er, cc, rest);
151 const Vec2 transmitted = incident;
153 const C phaseBarrierForward = std::exp(C(0.0, 1.0) * qx * c.
barrierWidth / hbar);
154 const C phaseBarrierBackward = std::exp(C(0.0, -1.0) * qx * c.
barrierWidth / hbar);
155 const C phaseTransmitted = std::exp(C(0.0, px * c.
barrierWidth / hbar));
159 for (
int component = 0; component < 2; ++component) {
160 const std::size_t k =
static_cast<std::size_t
>(component);
161 a[k][0] = reflected[k];
162 a[k][1] = -barrierForward[k];
163 a[k][2] = -barrierBackward[k];
164 a[k][3] = C(0.0, 0.0);
167 a[k + 2u][0] = C(0.0, 0.0);
168 a[k + 2u][1] = barrierForward[k] * phaseBarrierForward;
169 a[k + 2u][2] = barrierBackward[k] * phaseBarrierBackward;
170 a[k + 2u][3] = -transmitted[k] * phaseTransmitted;
171 b[k + 2u] = C(0.0, 0.0);
175 if (!solve4x4(a, b, solution))
return out;
177 const double r = std::norm(solution[0]);
178 const double t = std::norm(solution[3]);
179 if (!finite(r) || !finite(t))
return out;
183 out.
reflection = std::max(0.0, std::min(1.0, r));
191 double minimumAngleDegrees,
double maximumAngleDegrees,
192 int samples,
double hbar)
noexcept
196 !finite(minimumAngleDegrees) || !finite(maximumAngleDegrees) ||
197 minimumAngleDegrees < 0.0 || maximumAngleDegrees <= minimumAngleDegrees ||
198 maximumAngleDegrees >= 89.9 || samples < 2 || samples > 721 ||
199 !finite(hbar) || hbar <= 0.0) {
210 out.
points.reserve(
static_cast<std::size_t
>(samples));
212 bool allValid =
true;
213 for (
int i = 0; i < samples; ++i) {
214 const double f =
static_cast<double>(i) /
static_cast<double>(samples - 1);
215 const double angle = minimumAngleDegrees + f * (maximumAngleDegrees - minimumAngleDegrees);
217 allValid = allValid && point.valid;
218 out.
points.push_back(point);
220 out.
valid = allValid && out.
points.size() ==
static_cast<std::size_t
>(samples);
static QuantumKleinAngleScan2DResult scan(const QuantumKleinTunneling2DConfig &baseConfig, double minimumAngleDegrees=0.0, double maximumAngleDegrees=70.0, int samples=71, double hbar=1.0) noexcept
Performs scan.