Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add beam eigenemittances to reduced diagnostics. #702

Merged
merged 54 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
3000016
Add eigenemittance calculation.
cemitch99 Sep 13, 2024
9584c62
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 13, 2024
176405a
Update CovarianceMatrixMath.H
cemitch99 Sep 13, 2024
b51293b
Update EmittanceInvariants.cpp
cemitch99 Sep 13, 2024
6b1e911
Update EmittanceInvariants.H
cemitch99 Sep 13, 2024
4b3fdd1
Update EmittanceInvariants.cpp
cemitch99 Sep 13, 2024
62a11c5
Treat special case of vanishing discriminant in Cardano's formula.
cemitch99 Sep 13, 2024
55ec468
Test from ReducedDiagnostics; update ej ordering.
cemitch99 Sep 13, 2024
ecde532
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 13, 2024
8f22292
Add diagnostic output.
cemitch99 Sep 13, 2024
2297ae5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 13, 2024
db26dde
Comment print statements used for debugging.
cemitch99 Sep 13, 2024
d4f0a14
Update ReducedBeamCharacteristics.cpp
cemitch99 Sep 13, 2024
939909d
Add benchmark example.
cemitch99 Sep 14, 2024
beccb40
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 14, 2024
d12e44c
Add documentation.
cemitch99 Sep 14, 2024
b3fe78a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 14, 2024
7bd8c5a
Update CMakeLists.txt
cemitch99 Sep 14, 2024
8d001eb
Update CMakeLists.txt
cemitch99 Sep 14, 2024
27e9882
Normalize momenta by mc (dynamical units) for eigenemittances.
cemitch99 Sep 14, 2024
f33bd59
Add alternative routine for cubic roots.
cemitch99 Sep 16, 2024
f22eaae
Update EmittanceInvariants.cpp
cemitch99 Sep 16, 2024
e4a9421
Update CovarianceMatrixMath.H
cemitch99 Sep 16, 2024
1a62b70
Temporarily comment pytest test_transformation.
cemitch99 Sep 16, 2024
8fdee82
Update test_transformation.py
cemitch99 Sep 16, 2024
9070654
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 16, 2024
8cfafc6
Delete commented debugging print statements.
cemitch99 Sep 16, 2024
ea114ff
Update EmittanceInvariants.H
cemitch99 Sep 16, 2024
101803c
Update EmittanceInvariants.cpp
cemitch99 Sep 16, 2024
2ee73f4
Apply suggestions from code review
cemitch99 Sep 19, 2024
96818f2
Update src/particles/diagnostics/EmittanceInvariants.cpp
cemitch99 Sep 19, 2024
e6bd898
Update EmittanceInvariants.cpp
cemitch99 Sep 19, 2024
06b63c2
Add emittance_1,2,3 print.
cemitch99 Sep 24, 2024
0e8ecf1
Finalize print of emittance_1,2,3.
cemitch99 Sep 24, 2024
71bb155
Add ParmParse for optional calculation.
cemitch99 Sep 24, 2024
49d5677
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 24, 2024
3684108
Update test_transformation.py
cemitch99 Sep 24, 2024
c883ee8
Apply suggestions from code review
cemitch99 Sep 25, 2024
0172e10
Update EmittanceInvariants.cpp
cemitch99 Sep 25, 2024
587a095
Update CovarianceMatrixMath.H
cemitch99 Sep 26, 2024
851b46a
Update src/particles/diagnostics/CovarianceMatrixMath.H
cemitch99 Sep 26, 2024
45f21b9
Update CovarianceMatrixMath.H
cemitch99 Sep 26, 2024
59f5b4d
Update CovarianceMatrixMath.H
cemitch99 Sep 26, 2024
53024fa
Use amrex:: math for complex functions.
cemitch99 Sep 26, 2024
534e40f
Avoid copying matrices
ax3l Oct 2, 2024
ed52ed7
Formatting: Whitespaces
ax3l Oct 2, 2024
b922bb4
More general odd-ness test
ax3l Oct 2, 2024
41bee2b
Add conditional emittance output columns.
cemitch99 Oct 5, 2024
e27c30e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2024
4f2d689
Add documentation for user-facing input control.
cemitch99 Oct 5, 2024
d8128ac
Update dataanalysis documentation of eigenemittances.
cemitch99 Oct 5, 2024
4b8f7b3
Update CovarianceMatrixMath.H
cemitch99 Oct 8, 2024
6d61630
Apply suggestions from code review
cemitch99 Oct 8, 2024
345f5b1
Update tests/python/test_transformation.py
ax3l Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/particles/diagnostics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ target_sources(lib
PRIVATE
ReducedBeamCharacteristics.cpp
DiagnosticOutput.cpp
EmittanceInvariants.cpp
)
137 changes: 137 additions & 0 deletions src/particles/diagnostics/CovarianceMatrixMath.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/* Copyright 2022-2023 The Regents of the University of California, through Lawrence
* Berkeley National Laboratory (subject to receipt of any required
* approvals from the U.S. Dept. of Energy). All rights reserved.
*
* This file is part of ImpactX.
*
* Authors: Chad Mitchell, Axel Huebl
* License: BSD-3-Clause-LBNL
*/
#ifndef COVARIANCE_MATRIX_MATH_H
#define COVARIANCE_MATRIX_MATH_H

#include <ablastr/constant.H>
#include <AMReX_Array.H>
#include <AMReX_REAL.H>
#include <tuple>

namespace impactx::diagnostics
{

/** Function to return the roots of a cubic polynomial ax^3 + bx^2 + cx + d.
* The trigonometric form of Cardano's formula is used.
* This implementation expects three real roots, which is verified
* by checking the sign of the discriminant.
*
* @param[in] a coefficient of cubic term
* @param[in] b coefficient of quadratic term
* @param[in] c coefficient of linear term
* @param[in] d coefficient of constant term
* @returns tuple of three real roots
*/
std::tuple<
amrex::ParticleReal,
amrex::ParticleReal,
amrex::ParticleReal>
ax3l marked this conversation as resolved.
Show resolved Hide resolved
CubicRoots (
amrex::ParticleReal a,
amrex::ParticleReal b,
amrex::ParticleReal c,
amrex::ParticleReal d
)
{
using namespace amrex::literals;
using ablastr::constant::math::pi;

std::tuple <amrex::ParticleReal,amrex::ParticleReal,amrex::ParticleReal> roots;
ax3l marked this conversation as resolved.
Show resolved Hide resolved
amrex::ParticleReal x1 = 0.0_prt;
amrex::ParticleReal x2 = 0.0_prt;
amrex::ParticleReal x3 = 0.0_prt;

amrex::ParticleReal Q = (3.0_prt*a*c - pow(b,2))/(9.0_prt * pow(a,2));
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved
amrex::ParticleReal R = (9.0_prt*a*b*c - 27_prt*pow(a,2)*d - 2.0_prt*pow(b,3))/(54.0_prt*pow(a,3));
amrex::ParticleReal discriminant = pow(Q,3) + pow(R,2);

// Discriminant should be < 0. Otherwise, keep theta at default and throw an error.
amrex::ParticleReal tol = 1.0e-12; //allow for roundoff error
if(discriminant > tol){
ax3l marked this conversation as resolved.
Show resolved Hide resolved

std::cout << "Polynomial in CubicRoots has one or more complex roots." << "\n";
ax3l marked this conversation as resolved.
Show resolved Hide resolved

} else if (Q == 0.0_prt){ // Special case of a triple root
ax3l marked this conversation as resolved.
Show resolved Hide resolved

x1 = - b/(3.0_prt*a);
x2 = - b/(3.0_prt*a);
x3 = - b/(3.0_prt*a);

} else {

//Three real roots in trigonometric form.
amrex::ParticleReal theta = acos(R/sqrt(-pow(Q,3)));
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved
x1 = 2.0_prt*sqrt(-Q)*cos(theta/3.0_prt) - b/(3.0_prt*a);
x2 = 2.0_prt*sqrt(-Q)*cos(theta/3.0_prt + 2.0_prt*pi/3.0_prt) - b/(3.0_prt*a);
x3 = 2.0_prt*sqrt(-Q)*cos(theta/3.0_prt + 4.0_prt*pi/3.0_prt) - b/(3.0_prt*a);

}

//std::cout << "Discriminant, Q, R " << discriminant << " " << Q << " " << R << "\n";
//std::cout << "Return x1, x2, x3 " << x1 << " " << x2 << " " << x3 << "\n";
Fixed Show fixed Hide fixed
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved

ax3l marked this conversation as resolved.
Show resolved Hide resolved
roots = std::make_tuple(x1,x2,x3);
return roots;
}


/** Function to take the trace of a square 6x6 matrix.
*
* @param[in] A a square matrix
* @returns the trace of A
*/
amrex::ParticleReal
TraceMat (
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> A
ax3l marked this conversation as resolved.
Show resolved Hide resolved
)
{
int const dim = 6;
amrex::ParticleReal trA = 0.0;

for (int i = 1; i < dim+1; i++) {
trA += A(i,i);
}
return trA;
}


/** Function to multiply two square matrices of dimension 6.
*
* @param[in] A a square matrix
* @param[in] B square matrix
* @returns the matrix C = AB
*/
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6>
MultiplyMat (
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> A,
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> B
ax3l marked this conversation as resolved.
Show resolved Hide resolved
)
{
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> C;
int const dim = 6;

for (int i = 1; i < dim+1; i++) {
for (int j = 1; j < dim+1; j++) {
C(i,j) = 0;

for (int k = 1; k < dim+1; k++) {
C(i,j) += A(i,k) * B(k,j);
}

}

}
return C;
}


} // namespace impactx::diagnostics

#endif // COVARIANCE_MATRIX_MATH_H
61 changes: 61 additions & 0 deletions src/particles/diagnostics/EmittanceInvariants.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* Copyright 2022-2023 The Regents of the University of California, through Lawrence
* Berkeley National Laboratory (subject to receipt of any required
* approvals from the U.S. Dept. of Energy). All rights reserved.
*
* This file is part of ImpactX.
*
* Authors: Marco Garten, Chad Mitchell, Axel Huebl
* License: BSD-3-Clause-LBNL
*/
#ifndef IMPACTX_EMITTANCE_INVARIANTS
#define IMPACTX_EMITTANCE_INVARIANTS

#include "particles/ImpactXParticleContainer.H"

#include <AMReX_REAL.H>

#include <string>
#include <unordered_map>
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved


namespace impactx::diagnostics
{

/** Returns the three independent kinetic invariants
* denoted I2, I4, and I6 as constructed from the 6x6
* beam covariance matrix. These three quantities are invariant
* under any linear symplectic transport map, and are used in the
* calculation of the three eigenemittances.
*
* @param[in] Sigma symmetric 6x6 covariance matrix
* @returns tuple containing invariants I2, I4, and I6
*/
std::tuple<
amrex::ParticleReal,
amrex::ParticleReal,
amrex::ParticleReal>
ax3l marked this conversation as resolved.
Show resolved Hide resolved
KineticInvariants (
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> Sigma
ax3l marked this conversation as resolved.
Show resolved Hide resolved
);

/** Returns the three eigenemittances
* denoted e1, e2, and e3 as constructed from the 6x6
* beam covariance matrix. These three quantities are invariant
* under any linear symplectic transport map, and reduce to
* the projected normalized rms emittances in the limit of
* uncoupled transport.
*
* @param[in] Sigma symmetric 6x6 covariance matrix
* @returns tuple containing eigenemittances e1, e2, and e3
*/
std::tuple<
amrex::ParticleReal,
amrex::ParticleReal,
amrex::ParticleReal>
Eigenemittances (
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> Sigma
ax3l marked this conversation as resolved.
Show resolved Hide resolved
);

} // namespace impactx::diagnostics

#endif // IMPACTX_EMITTANCE_INVARIANTS
138 changes: 138 additions & 0 deletions src/particles/diagnostics/EmittanceInvariants.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/* Copyright 2022-2023 The Regents of the University of California, through Lawrence
* Berkeley National Laboratory (subject to receipt of any required
* approvals from the U.S. Dept. of Energy). All rights reserved.
*
* This file is part of ImpactX.
*
* Authors: Chad Mitchell, Axel Huebl
* License: BSD-3-Clause-LBNL
*/
#include "CovarianceMatrixMath.H"

#include <stdexcept>
#include <AMReX_Extension.H>
#include <AMReX_REAL.H>
#include <AMReX_GpuComplex.H>
#include <cmath>
#include <vector>
#include <tuple>
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved


namespace impactx::diagnostics
{

/** This function returns the three independent kinetic invariants
* denoted I2, I4, and I6 as constructed from the 6x6
* beam covariance matrix. These three quantities are invariant
* under any linear symplectic transport map, and are used in the
* calculation of the three eigenemittances.
*
* input - Sigma symmetric 6x6 covariance matrix
* returns - tuple containing invarants I2, I4, and I6
*/
std::tuple<
amrex::ParticleReal,
amrex::ParticleReal,
amrex::ParticleReal>
ax3l marked this conversation as resolved.
Show resolved Hide resolved
KineticInvariants (
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> Sigma
ax3l marked this conversation as resolved.
Show resolved Hide resolved
)
{
using namespace amrex::literals;

std::tuple <amrex::ParticleReal,amrex::ParticleReal,amrex::ParticleReal> invariants;
amrex::ParticleReal I2 = 0.0_prt;
amrex::ParticleReal I4 = 0.0_prt;
amrex::ParticleReal I6 = 0.0_prt;

// Intermediate matrices used for storage.
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> S1;
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> S2;
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> S4;
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> S6;

// Construct the matrix S1 = Sigma*J. This is a
// permutation of the columns of Sigma with
// a change of sign.
for (int i = 1; i < 7; i++) {
for (int j = 1; j < 7; j++) {
if (j % 2) {
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved
S1(i,j) = -Sigma(i,j+1); // if j is odd
}
else {
S1(i,j) = +Sigma(i,j-1); // if j is even
}
}
}

// Carry out necessary matrix multiplications (3 are needed).
S2 = impactx::diagnostics::MultiplyMat(S1,S1);
S4 = impactx::diagnostics::MultiplyMat(S2,S2);
S6 = impactx::diagnostics::MultiplyMat(S2,S4);

// Define the three kinematic invariants (should be nonnegative).
I2 = -impactx::diagnostics::TraceMat(S2)/2.0_prt;
I4 = +impactx::diagnostics::TraceMat(S4)/2.0_prt;
I6 = -impactx::diagnostics::TraceMat(S6)/2.0_prt;

//std::cout << "Return I2, I4, I6 " << I2 << " " << I4 << " " << I6 << "\n";
Fixed Show fixed Hide fixed
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved

invariants = std::make_tuple(I2,I4,I6);
return invariants;
}


/** This function returns the three eigenemittances
* denoted e1, e2, and e3 as constructed from the 6x6
* beam covariance matrix. These three quantities are invariant
* under any linear symplectic transport map, and reduce to
* the projected normalized rms emittances in the limit of
* uncoupled transport.
*
* input - Sigma symmetric 6x6 covariance matrix
* returns - tuple containing eigenemittances e1, e2, and e3
*/
std::tuple<
amrex::ParticleReal,
amrex::ParticleReal,
amrex::ParticleReal>
Eigenemittances (
amrex::Array2D<amrex::ParticleReal, 1, 6, 1, 6> Sigma
Fixed Show fixed Hide fixed
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved Hide resolved
)
{
using namespace amrex::literals;
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved

std::tuple <amrex::ParticleReal,amrex::ParticleReal,amrex::ParticleReal> invariants;
std::tuple <amrex::ParticleReal,amrex::ParticleReal,amrex::ParticleReal> roots;
std::tuple <amrex::ParticleReal,amrex::ParticleReal,amrex::ParticleReal> emittances;
ax3l marked this conversation as resolved.
Show resolved Hide resolved

// Get the invariants I2, I4, and I6 from the covariance matrix.
invariants = KineticInvariants(Sigma);
amrex::ParticleReal I2 = std::get<0>(invariants);
amrex::ParticleReal I4 = std::get<1>(invariants);
amrex::ParticleReal I6 = std::get<2>(invariants);

// Construct the coefficients of the cubic polynomial
amrex::ParticleReal a = 1.0_prt;
amrex::ParticleReal b = -I2;
amrex::ParticleReal c = (pow(I2,2)-I4)/2.0_prt;
amrex::ParticleReal d = -pow(I2,3)/6.0_prt + I2*I4/2.0_prt - I6/3.0_prt;

// Return the cubic coefficients
//std::cout << "Return a,b,c,d " << a << " " << b << " " << c << " " << d << "\n";

// Solve for the roots to obtain the eigenemittances.
roots = CubicRoots(a,b,c,d);
amrex::ParticleReal e1 = sqrt(std::get<1>(roots));
amrex::ParticleReal e2 = sqrt(std::get<2>(roots));
amrex::ParticleReal e3 = sqrt(std::get<0>(roots));
cemitch99 marked this conversation as resolved.
Show resolved Hide resolved

// Caution: The order of e1,e2,e3 should be consistent with the
// order ex,ey,et in the limit of uncoupled transport. The
// ordering remains to be carefully checked (TODO).
emittances = std::make_tuple(e1,e2,e3);
return emittances;
}


} // namespace impactx::diagnostics
Loading
Loading