Skip to content

Commit

Permalink
add the sodium iodide research scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
tjira committed Nov 11, 2024
1 parent 9bf420c commit 5ea8878
Show file tree
Hide file tree
Showing 14 changed files with 482 additions and 171 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,3 @@ tex/

# nested folders
/docs/python/

# exceptions
!/education/python/**
201 changes: 136 additions & 65 deletions docs/pages/codesolutions.md

Large diffs are not rendered by default.

219 changes: 142 additions & 77 deletions education/python/resmet.py

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion include/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct Input {
} data_export;
int iterations, imaginary, real;
double time_step;
std::unordered_map<std::string, double> constants;
std::vector<std::vector<std::string>> potential;
} quantum_dynamics;
struct ClassicalDynamics {
Expand Down Expand Up @@ -73,7 +74,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::HartreeFock::CoupledCluster, excitatio
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::HartreeFock::MollerPlesset, order);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::HartreeFock, diis_size, max_iter, threshold, configuration_interaction, coupled_cluster, moller_plesset, generalized, gradient);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::QuantumDynamics::DataExport, diabatic_wavefunction, adiabatic_wavefunction, diabatic_density, adiabatic_density, diabatic_population, adiabatic_population, diabatic_potential, adiabatic_potential, total_energy, position, momentum, acf, potential_energy, kinetic_energy);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::QuantumDynamics, potential, imaginary, real, iterations, time_step, data_export);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::QuantumDynamics, potential, constants, imaginary, real, iterations, time_step, data_export);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::ClassicalDynamics::DataExport, total_energy, position, momentum, diabatic_population, adiabatic_population, total_energy_mean, position_mean, momentum_mean, potential_energy, potential_energy_mean, kinetic_energy, kinetic_energy_mean, hopping_geometry, hopping_time);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::ClassicalDynamics::InitialConditions, positions, momenta, diabatic_state, adiabatic_state, mass, position_distribution, momentum_distribution);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Input::ClassicalDynamics::SurfaceHopping, kappa, type, quantum_step_factor);
Expand Down
2 changes: 1 addition & 1 deletion research/fssh_vs_lzsh/fssh_vs_lzsh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ for MODEL in ${MODELS[@]}; do
jq '.classical_dynamics |= . + {"surface_hopping" : {"type" : "landau-zener" }}' "lzsh_${MODEL,,}_P=${MOMENTUM}.json" > temp.json && mv temp.json "lzsh_${MODEL,,}_P=${MOMENTUM}.json"

# run the dynamics and delete the inputs
$ACORN -i "exact_${MODEL,,}_P=${MOMENTUM}.json" "fssh_${MODEL,,}_P=${MOMENTUM}.json" "kfssh_${MODEL,,}_P=${MOMENTUM}.json" "lzsh_${MODEL,,}_P=${MOMENTUM}.json" -n $CORES && rm *.json
$ACORN -n $CORES run "exact_${MODEL,,}_P=${MOMENTUM}.json" "fssh_${MODEL,,}_P=${MOMENTUM}.json" "kfssh_${MODEL,,}_P=${MOMENTUM}.json" "lzsh_${MODEL,,}_P=${MOMENTUM}.json" && rm *.json

# get the populations at the last time step
POP_EXACT=$(tail -n 1 POPULATION-ADIABATIC_EXACT-REAL_1.mat | awk -v i=$IS '{print $(i+1)}');
Expand Down
33 changes: 33 additions & 0 deletions research/sodium_iodide/fssh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"wavefunction" : {
"guess" : ["0", "0", "exp(-(x-4.96678210296807)^2)", "0"],
"dimension" : 1,
"grid_limits" : [3, 30],
"grid_points" : 4096,
"mass" : 35480.251398,
"momentum" : [50]
},
"classical_dynamics" : {
"potential" : [
["((A2+(B2/(x*au2a))^8)*exp(-(x*au2a)/rho)-e2/(x*au2a)-e2*(lp+lm)/2/(x*au2a)^4-C2/(x*au2a)^6-2*e2*lm*lp/(x*au2a)^7+de)/au2ev", "A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev"],
["A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev", "A1*exp(-beta1*((x*au2a)-R0))/au2ev" ]
],
"constants" : {
"A2" : 2760, "B2" : 2.398, "C2" : 11.3, "rho" : 0.3489, "e2" : 14.3996, "lp" : 0.408, "lm" : 6.431,
"A1" : 0.813, "beta1" : 4.08, "A12" : 0.055, "beta12" : 0.6931, "R0" : 2.67, "Rx" : 6.93, "de" : 2.075,

"au2ev" : 27.21138602, "au2a" : 0.529177
},
"surface_hopping" : {
"type" : "fewest-switches"
},
"adiabatic" : true,
"iterations" : 9000,
"time_step" : 1,
"trajectories" : 1000,
"log_interval_step" : 500,
"data_export" : {
"diabatic_population" : true, "adiabatic_population" : true
}
}
}
36 changes: 36 additions & 0 deletions research/sodium_iodide/kfssh-check.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"classical_dynamics" : {
"initial_conditions" : {
"positions" : [
[4.966781744519960462]
],
"momenta" : [
[-7.511477096479932669]
],
"adiabatic_state" : 2,
"mass" : 35480.251398
},
"potential" : [
["((A2+(B2/(x*au2a))^8)*exp(-(x*au2a)/rho)-e2/(x*au2a)-e2*(lp+lm)/2/(x*au2a)^4-C2/(x*au2a)^6-2*e2*lm*lp/(x*au2a)^7+de)/au2ev", "A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev"],
["A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev", "A1*exp(-beta1*((x*au2a)-R0))/au2ev" ]
],
"constants" : {
"A2" : 2760, "B2" : 2.398, "C2" : 11.3, "rho" : 0.3489, "e2" : 14.3996, "lp" : 0.408, "lm" : 6.431,
"A1" : 0.813, "beta1" : 4.08, "A12" : 0.055, "beta12" : 0.6931, "R0" : 2.67, "Rx" : 6.93, "de" : 2.075,

"au2ev" : 27.21138602, "au2a" : 0.529177
},
"surface_hopping" : {
"type" : "fewest-switches",
"kappa" : true
},
"adiabatic" : true,
"iterations" : 9000,
"time_step" : 1,
"trajectories" : 1,
"log_interval_step" : 1,
"data_export" : {
"diabatic_population" : true, "adiabatic_population" : true
}
}
}
34 changes: 34 additions & 0 deletions research/sodium_iodide/kfssh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"wavefunction" : {
"guess" : ["0", "0", "exp(-(x-4.96678210296807)^2)", "0"],
"dimension" : 1,
"grid_limits" : [3, 30],
"grid_points" : 4096,
"mass" : 35480.251398,
"momentum" : [50]
},
"classical_dynamics" : {
"potential" : [
["((A2+(B2/(x*au2a))^8)*exp(-(x*au2a)/rho)-e2/(x*au2a)-e2*(lp+lm)/2/(x*au2a)^4-C2/(x*au2a)^6-2*e2*lm*lp/(x*au2a)^7+de)/au2ev", "A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev"],
["A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev", "A1*exp(-beta1*((x*au2a)-R0))/au2ev" ]
],
"constants" : {
"A2" : 2760, "B2" : 2.398, "C2" : 11.3, "rho" : 0.3489, "e2" : 14.3996, "lp" : 0.408, "lm" : 6.431,
"A1" : 0.813, "beta1" : 4.08, "A12" : 0.055, "beta12" : 0.6931, "R0" : 2.67, "Rx" : 6.93, "de" : 2.075,

"au2ev" : 27.21138602, "au2a" : 0.529177
},
"surface_hopping" : {
"type" : "fewest-switches",
"kappa" : true
},
"adiabatic" : true,
"iterations" : 9000,
"time_step" : 1,
"trajectories" : 1000,
"log_interval_step" : 500,
"data_export" : {
"diabatic_population" : true, "adiabatic_population" : true
}
}
}
33 changes: 33 additions & 0 deletions research/sodium_iodide/lzsh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"wavefunction" : {
"guess" : ["0", "0", "exp(-(x-4.96678210296807)^2)", "0"],
"dimension" : 1,
"grid_limits" : [3, 30],
"grid_points" : 4096,
"mass" : 35480.251398,
"momentum" : [50]
},
"classical_dynamics" : {
"potential" : [
["((A2+(B2/(x*au2a))^8)*exp(-(x*au2a)/rho)-e2/(x*au2a)-e2*(lp+lm)/2/(x*au2a)^4-C2/(x*au2a)^6-2*e2*lm*lp/(x*au2a)^7+de)/au2ev", "A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev"],
["A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev", "A1*exp(-beta1*((x*au2a)-R0))/au2ev" ]
],
"constants" : {
"A2" : 2760, "B2" : 2.398, "C2" : 11.3, "rho" : 0.3489, "e2" : 14.3996, "lp" : 0.408, "lm" : 6.431,
"A1" : 0.813, "beta1" : 4.08, "A12" : 0.055, "beta12" : 0.6931, "R0" : 2.67, "Rx" : 6.93, "de" : 2.075,

"au2ev" : 27.21138602, "au2a" : 0.529177
},
"surface_hopping" : {
"type" : "landau-zener"
},
"adiabatic" : true,
"iterations" : 9000,
"time_step" : 1,
"trajectories" : 1000,
"log_interval_step" : 500,
"data_export" : {
"diabatic_population" : true, "adiabatic_population" : true
}
}
}
29 changes: 29 additions & 0 deletions research/sodium_iodide/qd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"wavefunction" : {
"guess" : ["0", "0", "exp(-(x-4.96678210296807)^2)", "0"],
"dimension" : 1,
"grid_limits" : [3, 30],
"grid_points" : 4096,
"mass" : 35480.251398,
"momentum" : [50]
},
"quantum_dynamics" : {
"potential" : [
["((A2+(B2/(x*au2a))^8)*exp(-(x*au2a)/rho)-e2/(x*au2a)-e2*(lp+lm)/2/(x*au2a)^4-C2/(x*au2a)^6-2*e2*lm*lp/(x*au2a)^7+de)/au2ev", "A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev"],
["A12*exp(-beta12*((x*au2a)-Rx)^2)/au2ev", "A1*exp(-beta1*((x*au2a)-R0))/au2ev" ]
],
"constants" : {
"A2" : 2760, "B2" : 2.398, "C2" : 11.3, "rho" : 0.3489, "e2" : 14.3996, "lp" : 0.408, "lm" : 6.431,
"A1" : 0.813, "beta1" : 4.08, "A12" : 0.055, "beta12" : 0.6931, "R0" : 2.67, "Rx" : 6.93, "de" : 2.075,

"au2ev" : 27.21138602, "au2a" : 0.529177
},
"real" : 1,
"iterations" : 9000,
"time_step" : 1,
"data_export" : {
"diabatic_population" : true, "adiabatic_population" : true,
"diabatic_potential" : true, "adiabatic_potential" : true
}
}
}
3 changes: 1 addition & 2 deletions script/general/docstopdf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,7 @@ water/RHF/STO-3G/-74.965901192180
numbers=none,
frame=single,
showstringspaces=false,
captionpos=b,
tabsize=2
captionpos=b
}
\lstset{style=code}
Expand Down
54 changes: 33 additions & 21 deletions src/classicaldynamics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,27 +269,39 @@ void ClassicalDynamics::run(const Input::Wavefunction& initial_diabatic_wavefunc
}

std::tuple<Eigen::MatrixXd, Eigen::MatrixXd, Eigen::MatrixXd> ClassicalDynamics::sample_initial_conditions(const Input::ClassicalDynamics::InitialConditions& ic, const Eigen::VectorXd& initial_position, const Eigen::VectorXd& initial_momentum, std::mt19937& mt, double mass) const {
// define the vector of distributions
std::vector<std::normal_distribution<double>> position_dist(!ic.position_distribution.empty() ? ic.position_distribution.size() : initial_position.size());
std::vector<std::normal_distribution<double>> momentum_dist(!ic.momentum_distribution.empty() ? ic.momentum_distribution.size() : initial_momentum.size());

// fill the distributions for the initial wavefuction
for (size_t i = 0; i < position_dist.size() && ic.position_distribution.empty(); i++) position_dist.at(i) = std::normal_distribution<double>(initial_position(i), 0.5);
for (size_t i = 0; i < momentum_dist.size() && ic.momentum_distribution.empty(); i++) momentum_dist.at(i) = std::normal_distribution<double>(initial_momentum(i), 1.0);

// fill the distributions for the initial conditions
for (size_t i = 0; i < position_dist.size() && !ic.position_distribution.empty(); i++) position_dist.at(i) = std::normal_distribution<double>(ic.position_distribution.at(i).at(0), ic.position_distribution.at(i).at(1));
for (size_t i = 0; i < momentum_dist.size() && !ic.momentum_distribution.empty(); i++) momentum_dist.at(i) = std::normal_distribution<double>(ic.momentum_distribution.at(i).at(0), ic.momentum_distribution.at(i).at(1));

// define the initial conditions
Eigen::MatrixXd position(input.iterations + 1, position_dist.size()), velocity(input.iterations + 1, momentum_dist.size()), acceleration(input.iterations + 1, momentum_dist.size());

// fill the initial conditions for position and momentum
for (size_t i = 0; i < position_dist.size(); i++) position(0, i) = position_dist.at(i)(mt);
for (size_t i = 0; i < momentum_dist.size(); i++) velocity(0, i) = momentum_dist.at(i)(mt);

// fill the acceleration and divide the momentum by the mass
acceleration.row(0).fill(0); velocity.row(0) /= mass;
// define the output matrices
Eigen::MatrixXd position, velocity, acceleration;

// if the sampling is needed
if (initial_position.size() > 0 || !ic.position_distribution.empty()) {

// define the vector of distributions
std::vector<std::normal_distribution<double>> position_dist(!ic.position_distribution.empty() ? ic.position_distribution.size() : initial_position.size());
std::vector<std::normal_distribution<double>> momentum_dist(!ic.momentum_distribution.empty() ? ic.momentum_distribution.size() : initial_momentum.size());

// fill the distributions for the initial wavefuction
for (size_t i = 0; i < position_dist.size() && ic.position_distribution.empty(); i++) position_dist.at(i) = std::normal_distribution<double>(initial_position(i), 0.5);
for (size_t i = 0; i < momentum_dist.size() && ic.momentum_distribution.empty(); i++) momentum_dist.at(i) = std::normal_distribution<double>(initial_momentum(i), 1.0);

// fill the distributions for the initial conditions
for (size_t i = 0; i < position_dist.size() && !ic.position_distribution.empty(); i++) position_dist.at(i) = std::normal_distribution<double>(ic.position_distribution.at(i).at(0), ic.position_distribution.at(i).at(1));
for (size_t i = 0; i < momentum_dist.size() && !ic.momentum_distribution.empty(); i++) momentum_dist.at(i) = std::normal_distribution<double>(ic.momentum_distribution.at(i).at(0), ic.momentum_distribution.at(i).at(1));

// define the initial conditions
position.resize(input.iterations + 1, position_dist.size()), velocity.resize(input.iterations + 1, momentum_dist.size()), acceleration.resize(input.iterations + 1, momentum_dist.size());

// set all to zero
position.setZero(), velocity.setZero(), acceleration.setZero();

// fill the initial conditions for position and momentum
for (size_t i = 0; i < position_dist.size(); i++) position(0, i) = position_dist.at(i)(mt);
for (size_t i = 0; i < momentum_dist.size(); i++) velocity(0, i) = momentum_dist.at(i)(mt);

// momentum to velocity
velocity.row(0) /= mass;

// if the sampling is not nesessary and explicit initial conditions are provided, set the correct shape of the matrices
} else position = Eigen::MatrixXd::Zero(input.iterations + 1, ic.positions.at(0).size()), velocity = position, acceleration = position;

// return the initial conditions
return {position, velocity, acceleration};
Expand Down
1 change: 1 addition & 0 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ nlohmann::json default_input = R"(
},
"quantum_dynamics" : {
"potential" : [["0.5*x^2"]],
"constants" : {},
"imaginary" : 0,
"real" : 0,
"iterations" : 1000,
Expand Down
2 changes: 1 addition & 1 deletion src/quantumdynamics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Eigen::MatrixXd QuantumDynamics::get_diabatic_potential(const Eigen::MatrixXd& g

// fill the diabatic potential
for (size_t i = 0; i < input.potential.size(); i++) for (size_t j = 0; j < input.potential.size(); j++) {
diabatic_potential.col(i * input.potential.size() + j) = Expression(input.potential.at(i).at(j), variables).evaluate(grid);
diabatic_potential.col(i * input.potential.size() + j) = Expression(input.potential.at(i).at(j), variables, input.constants).evaluate(grid);
}

// return the diabatic potential
Expand Down

0 comments on commit 5ea8878

Please sign in to comment.