create Motion classes on runtime instead of compile

This commit is contained in:
Dominik Demuth 2024-11-09 17:59:37 +01:00
parent 29be30c040
commit 3730413f6c
12 changed files with 106 additions and 24800 deletions

14
io.cpp
View File

@ -25,22 +25,28 @@ Arguments parse_args(const int argc, char **argv) {
for (int i=1; i<argc; i++) {
if (std::string arg = argv[i]; arg[0] == '-') {
if (arg == "-ste") {
if (arg == "--ste") {
args.ste = true;
} else if (arg == "-spectrum") {
} else if (arg == "--spectrum") {
args.spectrum = true;
} else {
throw std::runtime_error("Unrecognized option: " + arg);
}
} else if (args.parameter_file.empty()) {
args.parameter_file = arg;
} else if (args.motion_type.empty()) {
args.motion_type = arg;
} else {
throw std::runtime_error("Too many options for parameter file");
throw std::invalid_argument("Too many options for parameter file");
}
}
if (args.parameter_file.empty()) {
throw std::runtime_error("Missing parameter file");
throw std::invalid_argument("Missing parameter file");
}
if (args.motion_type.empty()) {
throw std::invalid_argument("Missing motion model");
}
return args;

1
io.h
View File

@ -12,6 +12,7 @@ struct Arguments {
std::string parameter_file{};
bool ste = false;
bool spectrum = false;
std::string motion_type{};
};
Arguments parse_args(int argc, char **argv);

24766
json.hpp

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
#include "io.h"
#include "sims.h"
#include "motions/base.h"
#include "motions/bimodalangle.h"
#include "motions/isosmallangle.h"
#include "motions/random.h"
@ -12,6 +13,7 @@
#include "times/lognormal.h"
int main (const int argc, char *argv[]) {
Arguments args;
try {
@ -26,18 +28,15 @@ int main (const int argc, char *argv[]) {
std::random_device rd;
std::mt19937_64 rng(rd());
// auto motion = BimodalAngle(1, 1, 2, 30, 0.98, rng); // arguments: delta, eta, angle1, angle2, probability of angle1
auto motion = TetrahedralJump(rng);
// auto motion = RandomJump(rng);
// auto motion = SmallAngle(1, 1, 4, rng); // arguments: delta, eta, angle
Motion *motion = Motion::createFromInput(args.motion_type, rng);
auto dist = DeltaDistribution(rng);
// auto dist = LogNormalDistribution(1, 2, rng); // arguments: tau_max, sigma
if (args.spectrum) {
run_spectrum(parameter, motion, dist);
run_spectrum(parameter, *motion, dist);
}
if (args.ste) {
run_ste(parameter, motion, dist);
run_ste(parameter, *motion, dist);
}
}

View File

@ -2,20 +2,25 @@
// Created by dominik on 8/12/24.
//
// #include <cmath>
#include <random>
#include <cmath>
#include "base.h"
#include <stdexcept>
#include <utility>
#include "coordinates.h"
#include "bimodalangle.h"
#include "isosmallangle.h"
#include "random.h"
#include "tetrahedral.h"
#include <unordered_map>
Motion::Motion(const double delta, const double eta, std::mt19937_64& rng) : m_delta(delta), m_eta(eta), m_rng(rng) {
Motion::Motion(std::string name, const double delta, const double eta, std::mt19937_64& rng) : m_name(std::move(name)), m_delta(delta), m_eta(eta), m_rng(rng) {
m_uni_dist = std::uniform_real_distribution(0., 1.);
}
Motion::Motion(std::mt19937_64& rng) : m_rng(rng) {
Motion::Motion(std::string name, std::mt19937_64& rng) : m_name(std::move(name)), m_rng(rng) {
m_uni_dist = std::uniform_real_distribution(0., 1.);
}
@ -27,7 +32,6 @@ double Motion::omega_q(const double cos_theta, const double phi) const {
}
double Motion::omega_q(const SphericalPos& pos) const {
// std::cout << pos.cos_theta << " " << pos.phi << std::endl;
auto [cos_theta, phi] = pos;
return omega_q(cos_theta, phi);
@ -39,3 +43,24 @@ SphericalPos Motion::draw_position() {
return {cos_theta, phi};
}
Motion* Motion::createFromInput(const std::string& input, std::mt19937_64& rng) {
if (input == "TetrahedralJump")
return new TetrahedralJump(rng);
if (input == "IsotropicAngle")
return new SmallAngle(rng);
if (input == "RandomJump")
return new RandomJump(rng);
if (input == "BimodalAngle")
return new BimodalAngle(rng);
throw std::invalid_argument("Invalid input " + input);
}
std::ostream& operator<<(std::ostream& os, const Motion& m) {
os << m.getName();
return os;
}

View File

@ -7,15 +7,13 @@
#include "coordinates.h"
#include <random>
#include <unordered_map>
class Motion {
public:
virtual ~Motion() = default;
Motion(double, double, std::mt19937_64&);
explicit Motion(std::mt19937_64&);
Motion(std::string, double, double, std::mt19937_64&);
explicit Motion(std::string, std::mt19937_64&);
SphericalPos draw_position();
[[nodiscard]] double omega_q(double, double) const;
@ -28,13 +26,18 @@ public:
void setDelta(const double delta) { m_delta = delta; }
[[nodiscard]] double getEta() const { return m_eta; }
void setEta(const double eta) { m_eta = eta; }
[[nodiscard]] std::string getName() const { return m_name; }
static Motion* createFromInput(const std::string& input, std::mt19937_64& rng);
protected:
std::string m_name{"Base motion"};
double m_delta{1.};
double m_eta{0.};
std::mt19937_64& m_rng;
std::uniform_real_distribution<> m_uni_dist;
};
std::ostream& operator<<(std::ostream& os, const Motion& m);
#endif //RWSIM_MOTIONBASE_H

View File

@ -6,11 +6,11 @@
#include "base.h"
BimodalAngle::BimodalAngle(const double delta, const double eta, const double angle1, const double angle2, const double prob, std::mt19937_64 &rng) :
Motion(delta, eta, rng),
Motion(std::string("Bimodal Angle Jump"), delta, eta, rng),
m_angle1(angle1 * M_PI / 180.0),
m_angle2(angle2 * M_PI / 180.0),
m_prob(prob) {};
BimodalAngle::BimodalAngle(std::mt19937_64 &rng) : Motion(rng) {}
BimodalAngle::BimodalAngle(std::mt19937_64 &rng) : Motion(std::string("Bimodal Angle Jump"), rng) {}
void BimodalAngle::initialize() {
m_prev_pos = draw_position();

View File

@ -6,8 +6,9 @@
#include "coordinates.h"
SmallAngle::SmallAngle(const double delta, const double eta, const double chi, std::mt19937_64 &rng) : Motion(delta, eta, rng), m_chi(chi * M_PI / 180.0) {};
SmallAngle::SmallAngle(std::mt19937_64 &rng) : Motion(rng) {}
SmallAngle::SmallAngle(const double delta, const double eta, const double chi, std::mt19937_64 &rng) :
Motion(std::string("Isotropic Angle Jump"), delta, eta, rng), m_chi(chi * M_PI / 180.0) {};
SmallAngle::SmallAngle(std::mt19937_64 &rng) : Motion(std::string("Isotropic Angle Jump"), rng) {}
void SmallAngle::initialize() {
m_prev_pos = draw_position();

View File

@ -5,9 +5,9 @@
#include "random.h"
RandomJump::RandomJump(const double delta, const double eta, std::mt19937_64 &rng) : Motion(delta, eta, rng) {}
RandomJump::RandomJump(const double delta, const double eta, std::mt19937_64 &rng) : Motion(std::string("Random Jump"), delta, eta, rng) {}
RandomJump::RandomJump(std::mt19937_64 &rng) : Motion(rng) {}
RandomJump::RandomJump(std::mt19937_64 &rng) : Motion(std::string("Random Jump"), rng) {}
void RandomJump::initialize() {}

View File

@ -2,11 +2,13 @@
// Created by dominik on 8/16/24.
//
#include <random>
#include "tetrahedral.h"
TetrahedralJump::TetrahedralJump(const double delta, const double eta, std::mt19937_64& rng) : Motion(delta, eta, rng) {}
TetrahedralJump::TetrahedralJump(const double delta, const double eta, std::mt19937_64& rng) :
Motion(std::string{"TetrahedralJump"}, delta, eta, rng) {}
TetrahedralJump::TetrahedralJump(std::mt19937_64& rng) : Motion(rng) {}
TetrahedralJump::TetrahedralJump(std::mt19937_64& rng) : Motion(std::string{"TetrahedralJump"}, rng) {}
void TetrahedralJump::initialize() {
const auto pos = draw_position();

27
sims.h
View File

@ -11,8 +11,33 @@
#include "motions/base.h"
#include "times/base.h"
/**
* @brief Run simulation for spectra
*
* @param parameter Dictionary of parameter for simulation
* @param motion Motion model
* @param dist Distribution of correlation times
*/
void run_spectrum(std::unordered_map<std::string, double>& parameter, Motion& motion, Distribution& dist);
/**
* @brief Run simulation for stimulated echoes
*
* @param parameter Dictionary of parameter for simulation
* @param motion Motion model
* @param dist Distribution of correlation times
*/
void run_ste(std::unordered_map<std::string, double>& parameter, Motion& motion, Distribution& dist);
void make_trajectory(Motion&, Distribution&, double, std::vector<double>&, std::vector<double>&);
/**
* @brief Create trajectory of a single walker
*
* @param motion Motion model
* @param dist Distribution of correlation times
* @param t_max Double that defines maximum time of trajectory
* @param out_time Vector of waiting times
* @param out_phase Vector of phase between waiting times
*/
void make_trajectory(Motion& motion, Distribution& dist, double t_max, std::vector<double>& out_time, std::vector<double>& out_phase);
#endif //RWSIM_SIMS_H

20
test.py
View File

@ -7,11 +7,21 @@ import matplotlib.pyplot as plt
def run_sims(taus):
def run_sims(taus, ste: bool = True, spectrum: bool = False, exec_file: str = './build/rwsim', config_file: str = './config.txt'):
for tau in taus:
with pathlib.Path('./config.txt').open('a') as f:
arguments = [exec_file, config_file]
if ste:
arguments += ['--ste']
if spectrum:
arguments += ['--spectrum']
arguments += ['IsotropicAngle']
with pathlib.Path(config_file).open('a') as f:
f.write(f'tau={tau}\n')
subprocess.run(['./build/rwsim', '-ste', './config.txt'])
subprocess.run(arguments)
def dampening(x: np.ndarray, apod: float) -> np.ndarray:
@ -101,7 +111,7 @@ def post_process_ste(taus):
res = curve_fit(ste, t_mix, raw_data_cc[:, j+1], p0, bounds=[(0, 0, 0, 0), (np.inf, np.inf, 1, 1)])
m0, tauc, beta, finfty = res[0]
print(f'Cos-Cos-Fit for {tevo[j]}: tau_c = {tauc:.6e}, beta={beta:.4e}, amplitude = {m0: .4e}, f_infty={finfty:.4e}')
# print(f'Cos-Cos-Fit for {tevo[j]}: tau_c = {tauc:.6e}, beta={beta:.4e}, amplitude = {m0: .4e}, f_infty={finfty:.4e}')
tau_cc_fit.append(res[0][1])
beta_cc_fit.append(res[0][2])
@ -116,7 +126,7 @@ def post_process_ste(taus):
res = curve_fit(ste, t_mix, raw_data_ss[:, j+1], p0, bounds=[(0, 0, 0, 0), (np.inf, np.inf, 1, 1)])
m0, tauc, beta, finfty = res[0]
print(f'Sin-Sin-Fit for {tevo[j]}: tau_c = {tauc:.6e}, beta={beta:.4e}, amplitude = {m0: .4e}, f_infty={finfty:.4e}')
# print(f'Sin-Sin-Fit for {tevo[j]}: tau_c = {tauc:.6e}, beta={beta:.4e}, amplitude = {m0: .4e}, f_infty={finfty:.4e}')
tau_ss_fit.append(res[0][1])
beta_ss_fit.append(res[0][2])