diff --git a/functions.cpp b/functions.cpp index a0d3cca..13c5fed 100644 --- a/functions.cpp +++ b/functions.cpp @@ -15,6 +15,9 @@ int nearest_index(const std::vector &x_ref, const double x, int start=0) } double lerp(const std::vector& x_ref, const std::vector& y_ref, const double x, const int i) { + /* + * Linear interpolation between two + */ const double x_left = x_ref[i]; const double y_left = y_ref[i]; const double x_right = x_ref[i+1]; @@ -26,6 +29,9 @@ double lerp(const std::vector& x_ref, const std::vector& y_ref, } std::chrono::time_point printSteps( + /* + * Prints roughly every 10 seconds how many runs were done and gives a time estimation + */ const std::chrono::time_point last_print_out, const std::chrono::time_point start, const int total, @@ -37,15 +43,11 @@ std::chrono::time_point printSteps( return last_print_out; } - std::chrono::duration duration = now - start; + const std::chrono::duration duration = now - start; const auto passed = duration.count(); std::cout << steps << " of " << total << " steps: " << passed << "s passed; ~" << passed * static_cast(total-steps) / static_cast(steps) << "s remaining\n"; return now; - // time_t end_time = std::chrono::system_clock::to_time_t(end); - // std::cout << "End tau = " << tau_i << "s : " << ctime(&end_time); - // std::cout << "Duration: " << duration.count() << "s\n" << std::endl; - } \ No newline at end of file diff --git a/io.cpp b/io.cpp index 859a5f7..1dcb038 100644 --- a/io.cpp +++ b/io.cpp @@ -12,9 +12,15 @@ #include #include #include +#include -std::unordered_map parse_arguments(const char *infile) { +std::unordered_map parse_arguments(const std::filesystem::path& infile) { + if (!std::filesystem::exists(infile)) { + std::cerr << "File " << infile << " does not exist" << std::endl; + exit(1); + } + std::ifstream instream(infile); std::unordered_map parameter; @@ -25,8 +31,6 @@ std::unordered_map parse_arguments(const char *infile) { std::string value; size_t delim_pos; - // TODO this needs a check for file existence - while (std::getline(instream, line)) { line.erase(std::remove(line.begin(), line.end(), ' '), line.end()); delim_pos = line.find('='); diff --git a/io.h b/io.h index 9837d04..ec4f620 100644 --- a/io.h +++ b/io.h @@ -5,9 +5,10 @@ #include #include #include +#include #include -std::unordered_map parse_arguments(const char *); +std::unordered_map parse_arguments(const std::filesystem::path&); void fid_write_out(const std::string&, const std::vector&, const std::vector&, double, double); void fid_write_out(const std::string&, const std::vector&, const std::map>&, double tau); diff --git a/main.cpp b/main.cpp index d73cfcf..98a94e5 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -7,8 +8,15 @@ #include "times/delta.h" -int main () { - std::unordered_map parameter { parse_arguments("config.txt") }; +int main (int argc, char *argv[]) { + + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " PARAMETER_FILE" << std::endl; + return 1; + } + std::cout << argv[0] << std::endl; + + std::unordered_map parameter { parse_arguments(argv[1]) }; std::random_device rd; std::mt19937_64 rng(rd()); diff --git a/motions/base.cpp b/motions/base.cpp index f05d017..457cc24 100644 --- a/motions/base.cpp +++ b/motions/base.cpp @@ -2,11 +2,14 @@ // Created by dominik on 8/12/24. // -#include +// #include #include +#include +#include #include "base.h" + Motion::Motion(const double delta, const double eta, std::mt19937_64& rng) : m_delta(delta), m_eta(eta), m_rng(rng) { m_uni_dist = std::uniform_real_distribution(0., 1.); } @@ -19,13 +22,13 @@ double Motion::omega_q(const double cos_theta, const double phi) const { const double cos_theta_square = cos_theta * cos_theta; const double sin_theta_square = 1. - cos_theta_square; - return M_PI * m_delta * (3 * cos_theta_square - 1 - m_eta * sin_theta_square * cos(2.*phi)); + return M_PI * m_delta * (3 * cos_theta_square - 1 - m_eta * sin_theta_square * std::cos(2.*phi)); } -double Motion::draw_position() { +std::pair Motion::draw_position() { const double cos_theta = 1 - 2 * m_uni_dist(m_rng); const double phi = 2.0 * M_PI * m_uni_dist(m_rng); - return omega_q(cos_theta, phi); + return std::make_pair(cos_theta, phi); } diff --git a/motions/base.h b/motions/base.h index 06442e4..6cceb51 100644 --- a/motions/base.h +++ b/motions/base.h @@ -7,6 +7,7 @@ #include +#include class Motion { public: @@ -15,9 +16,10 @@ public: Motion(double, double, std::mt19937_64&); explicit Motion(std::mt19937_64&); - double draw_position(); + std::pair draw_position(); [[nodiscard]] double omega_q(double, double) const; + virtual void initialize() = 0; virtual double jump() = 0; [[nodiscard]] double getDelta() const { return m_delta; } @@ -25,11 +27,11 @@ public: [[nodiscard]] double getEta() const { return m_eta; } void setEta(const double eta) { m_eta = eta; } -private: +protected: double m_delta{1.}; double m_eta{0.}; std::mt19937_64& m_rng; - std::uniform_real_distribution m_uni_dist; + std::uniform_real_distribution<> m_uni_dist; }; #endif //RWSIM_MOTIONBASE_H diff --git a/motions/random.cpp b/motions/random.cpp index d6bc9f1..fe68628 100644 --- a/motions/random.cpp +++ b/motions/random.cpp @@ -9,6 +9,9 @@ RandomJump::RandomJump(const double delta, const double eta, std::mt19937_64 &rn RandomJump::RandomJump(std::mt19937_64 &rng) : Motion(rng) {} +void RandomJump::initialize() {} + double RandomJump::jump() { - return draw_position(); + const auto [cos_theta, phi] = draw_position(); + return omega_q(cos_theta, phi); } diff --git a/motions/random.h b/motions/random.h index 0645583..ed4f9e2 100644 --- a/motions/random.h +++ b/motions/random.h @@ -13,6 +13,7 @@ public: RandomJump(double, double, std::mt19937_64&); explicit RandomJump(std::mt19937_64&); + void initialize() override; double jump() override; }; diff --git a/motions/tetrahedral.cpp b/motions/tetrahedral.cpp index e5991b3..c9eb2ee 100644 --- a/motions/tetrahedral.cpp +++ b/motions/tetrahedral.cpp @@ -9,6 +9,46 @@ TetrahedralJump::TetrahedralJump(const double delta, const double eta, std::mt19 TetrahedralJump::TetrahedralJump(std::mt19937_64& rng) : Motion(rng) {} -double TetrahedralJump::jump() { - return draw_position(); +void TetrahedralJump::initialize() { + // const auto [cos_theta, phi] = draw_position(); + // + // m_corners[0] = omega_q(cos_theta, phi); + // + // const double alpha = 2. * M_PI * m_uni_dist(m_rng); + // std::cout << alpha << std::endl; + + // v1[0] = sin(phi0)*sin(teta0); + // v2[0] = cos(phi0)*sin(teta0); + // v3[0] = cos(teta0); + // + // abs = v1[0]*v1[0]+v2[0]*v2[0]+v3[0]*v3[0]; // Normalization + // v1[0] = v1[0]/abs; + // v2[0] = v2[0]/abs; + // v3[0] = v3[0]/abs; + // + // /*Calculating the components of the other orientationts. Compare Master Thesis M. Sattig,corrected Version (Share/Abschlussarbeiten)*/ + // norm = sqrt(1 - v3[0]*v3[0])+1E-12; + // normI = 1.0/(norm); + // + // cosgama = cos(delta0); + // singama = sin(delta0); + // v1[1] = v1[0]*cosBETA + sinBETA*normI*(-v1[0]*v3[0]*singama - v2[0]*cosgama); + // v2[1] = v2[0]*cosBETA + sinBETA*normI*(-v2[0]*v3[0]*singama + v1[0]*cosgama); + // v3[1] = v3[0]*cosBETA + sinBETA*norm*singama; + // + // cosgama = cos(gama + delta0); + // singama = sin(gama + delta0); + // v1[2] = v1[0]*cosBETA + sinBETA*normI*(-v1[0]*v3[0]*singama - v2[0]*cosgama); + // v2[2] = v2[0]*cosBETA + sinBETA*normI*(-v2[0]*v3[0]*singama + v1[0]*cosgama); + // v3[2] = v3[0]*cosBETA + sinBETA*norm*singama; + // + // cosgama = cos(2.0*gama + delta0); + // singama = sin(2.0*gama + delta0); + // v1[3] = v1[0]*cosBETA + sinBETA*normI*(-v1[0]*v3[0]*singama - v2[0]*cosgama); + // v2[3] = v2[0]*cosBETA + sinBETA*normI*(-v2[0]*v3[0]*singama + v1[0]*cosgama); + // v3[3] = v3[0]*cosBETA + sinBETA*norm*singama; +} + +double TetrahedralJump::jump() { + return 0.; } diff --git a/motions/tetrahedral.h b/motions/tetrahedral.h index 04315ab..78cba62 100644 --- a/motions/tetrahedral.h +++ b/motions/tetrahedral.h @@ -7,13 +7,20 @@ #include "base.h" #include +#include +#include class TetrahedralJump final : public Motion { public: TetrahedralJump(double, double, std::mt19937_64&); explicit TetrahedralJump(std::mt19937_64&); + void initialize() override; double jump() override; + +private: + const double m_beta{std::acos(-1/3.)}; + std::array m_corners{}; }; diff --git a/ranges.cpp b/ranges.cpp index 0fdff2e..d10faac 100644 --- a/ranges.cpp +++ b/ranges.cpp @@ -49,8 +49,8 @@ std::vector logspace(const double start, const double stop, const int st return range; } - const double logstart = log10(start); - const double logstop = log10(stop); + const double logstart = std::log10(start); + const double logstop = std::log10(stop); const double stepsize = (logstop-logstart) / (steps-1); for (int i=0; i& parameter, Motion& mo current_pos = nearest_index(traj_time, real_time, current_pos); const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos); - fid_j[acq_idx] += cos(phase_acq - 2 * phase_tevo) / num_walker; + fid_j[acq_idx] += std::cos(phase_acq - 2 * phase_tevo) / num_walker; } last_print_out = printSteps(last_print_out, start, num_walker, mol_i); } @@ -95,7 +95,8 @@ void run_ste(std::unordered_map& parameter, Motion& motion, const int num_acq = static_cast(parameter[std::string("num_acq")]); const int num_walker = static_cast(parameter[std::string("num_walker")]); - const std::vector correlation_times = logspace(parameter["tau_start"], parameter["tau_stop"], static_cast(parameter["tau_steps"])); + const double tau = parameter["tau"]; + dist.setTau(tau); motion.setDelta(parameter["delta"]); motion.setEta(parameter["eta"]); @@ -103,7 +104,6 @@ void run_ste(std::unordered_map& parameter, Motion& motion, const std::vector evolution_times = linspace(parameter["tevo_start"], parameter["tevo_stop"], static_cast(parameter["tevo_steps"])); const std::vector mixing_times = linspace(parameter["tevo_start"], parameter["tevo_stop"], static_cast(parameter["tevo_steps"])); - std::map> fid_dict; for (auto t_evo_i: evolution_times) { fid_dict[t_evo_i] = std::vector(num_acq); @@ -111,54 +111,50 @@ void run_ste(std::unordered_map& parameter, Motion& motion, } // each trajectory must have a duration of at least tmax - const double tmax = *std::max_element(evolution_times.begin(), evolution_times.end()) * 2 + *std::max_element(mixing_times.begin(), mixing_times.end()); - for (const auto tau_i: correlation_times) { - auto start = std::chrono::system_clock::now(); - time_t start_time = std::chrono::system_clock::to_time_t(start); - std::cout << "Start tau = " << tau_i << "s : " << ctime(&start_time); + const auto start = std::chrono::system_clock::now(); + const time_t start_time = std::chrono::system_clock::to_time_t(start); + std::cout << "Start tau = " << tau << "s : " << ctime(&start_time); - dist.setTau(tau_i); + for (auto& [_, fid_j]: fid_dict) { + std::fill(fid_j.begin(), fid_j.end(), 0.); + } - for (auto& [_, fid_j]: fid_dict) { - std::fill(fid_j.begin(), fid_j.end(), 0.); - } + // reset array for each correlation time + for (int mol_i = 0; mol_i < num_walker; mol_i++){ + std::vector traj_time{}; + std::vector traj_phase{}; - // reset array for each correlation time - for (int mol_i = 0; mol_i < num_walker; mol_i++){ - std::vector traj_time{}; - std::vector traj_phase{}; + make_trajectory(motion, dist, tmax, traj_time, traj_phase); - make_trajectory(motion, dist, tmax, traj_time, traj_phase); + for (auto& [t_evo_j, fid_j] : fid_dict) { + int current_pos = nearest_index(traj_time, t_evo_j, 0); + const double phase_tevo = lerp(traj_time, traj_phase, t_evo_j, current_pos); - for (auto& [t_evo_j, fid_j] : fid_dict) { - int current_pos = nearest_index(traj_time, t_evo_j, 0); - const double phase_tevo = lerp(traj_time, traj_phase, t_evo_j, current_pos); + // time axis by echo delay to get time in trajectory - // time axis by echo delay to get time in trajectory + for (int acq_idx = 0; acq_idx < num_acq; acq_idx++) { + const double real_time = mixing_times[acq_idx] + t_evo_j; - for (int acq_idx = 0; acq_idx < num_acq; acq_idx++) { - const double real_time = mixing_times[acq_idx] + t_evo_j; + current_pos = nearest_index(traj_time, real_time, current_pos); + const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos); - current_pos = nearest_index(traj_time, real_time, current_pos); - const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos); - - fid_j[acq_idx] += cos(phase_acq - 2 * phase_tevo); - } + fid_j[acq_idx] += cos(phase_acq - 2 * phase_tevo); } } - - // write fid to files - fid_write_out("ste", mixing_times, fid_dict, tau_i); - - auto end = std::chrono::system_clock::now(); - - std::chrono::duration duration = end - start; - time_t end_time = std::chrono::system_clock::to_time_t(end); - std::cout << "End tau = " << tau_i << "s : " << ctime(&end_time); - std::cout << "Duration: " << duration.count() << "s\n" << std::endl; } + + // write fid to files + fid_write_out("ste", mixing_times, fid_dict, tau); + + const auto end = std::chrono::system_clock::now(); + + const std::chrono::duration duration = end - start; + const time_t end_time = std::chrono::system_clock::to_time_t(end); + std::cout << "End tau = " << tau << "s : " << ctime(&end_time); + std::cout << "Duration: " << duration.count() << "s\n" << std::endl; + } @@ -167,6 +163,8 @@ void make_trajectory(Motion& motion, const Distribution& dist, const double t_ma double t_passed = 0; double phase = 0; + motion.initialize(); + out_time.emplace_back(t_passed); out_phase.emplace_back(0); @@ -176,8 +174,6 @@ void make_trajectory(Motion& motion, const Distribution& dist, const double t_ma phase += motion.jump() * t; -// phase += jump(delta, eta, rng) * t; - out_time.emplace_back(t_passed); out_phase.emplace_back(phase); }