Wokring Without Heunwith force and MBD
This commit is contained in:
parent
e63239ed47
commit
29779754e9
32
README.md
Normal file
32
README.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
Brownian Motion Integrator Implementation
|
||||||
|
===============
|
||||||
|
|
||||||
|
This is a sample Implementation for different BD Algorithm
|
||||||
|
|
||||||
|
1. Classic Euler algorithm
|
||||||
|
2. Heun algorithm
|
||||||
|
3. Exact solution
|
||||||
|
4. BDAS - RotationMatrix
|
||||||
|
5. MBD
|
||||||
|
|
||||||
|
The current implementation allows only the use for a 2D case
|
||||||
|
|
||||||
|
build
|
||||||
|
-----
|
||||||
|
|
||||||
|
To build this project you need to install
|
||||||
|
- conan ```pip3 install --user conan```
|
||||||
|
- CMake
|
||||||
|
|
||||||
|
To generate the build files
|
||||||
|
```shell
|
||||||
|
cmake -S . -B build
|
||||||
|
```
|
||||||
|
For build configuration use
|
||||||
|
```shell
|
||||||
|
ccmake build
|
||||||
|
```
|
||||||
|
and to build the program
|
||||||
|
```shell
|
||||||
|
cmake --build build
|
||||||
|
```
|
@ -4,8 +4,8 @@ find_package(Eigen3)
|
|||||||
|
|
||||||
# Generic test that uses conan libs
|
# Generic test that uses conan libs
|
||||||
add_library(integratoren SHARED LiveAgg.cpp Rod2d.cpp Simulation.cpp
|
add_library(integratoren SHARED LiveAgg.cpp Rod2d.cpp Simulation.cpp
|
||||||
Simulation.h Integratoren2d_forceless.cpp
|
Simulation.h Integratoren2d_forceless.cpp Integratoren2d_force.cpp
|
||||||
Calculation.cpp Calculation.h Compute.cpp Compute.h)
|
Calculation.cpp Compute.cpp)
|
||||||
target_include_directories(integratoren PUBLIC .)
|
target_include_directories(integratoren PUBLIC .)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
integratoren
|
integratoren
|
||||||
|
@ -24,7 +24,7 @@ Calculation::Calculation(std::function<void(Rod2d &, Simulation &)> t_integrator
|
|||||||
: sim(deltaT, seed), m_integrator(
|
: sim(deltaT, seed), m_integrator(
|
||||||
std::move(t_integrator)) {
|
std::move(t_integrator)) {
|
||||||
for (const auto &pair: t_computes) {
|
for (const auto &pair: t_computes) {
|
||||||
computes.emplace_back(rod, pair.first, pair.second);
|
computes.emplace_back(Compute(rod, pair.first, pair.second,sim));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Rod2d.hpp"
|
#include "Rod2d.hpp"
|
||||||
|
#include "Simulation.h"
|
||||||
|
|
||||||
void Compute::evalMSD(const Rod2d &rod2D) {
|
void Compute::evalMSD(const Rod2d &rod2D) {
|
||||||
const auto &new_pos = rod2D.getPos();
|
const auto &new_pos = rod2D.getPos();
|
||||||
@ -32,7 +33,7 @@ void Compute::eval_empYY(const Rod2d & /*rod2D*/) {
|
|||||||
|
|
||||||
void Compute::eval(const Rod2d &rod2D) {
|
void Compute::eval(const Rod2d &rod2D) {
|
||||||
time_step++;
|
time_step++;
|
||||||
if (time_step % every == 0){
|
if (time_step % every == 0) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::msd:
|
case Type::msd:
|
||||||
evalMSD(rod2D);
|
evalMSD(rod2D);
|
||||||
@ -52,8 +53,23 @@ void Compute::eval(const Rod2d &rod2D) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Compute::Compute(Rod2d rod, Type t_type, size_t t_every)
|
Compute::Compute(Rod2d rod, Type t_type, size_t t_every, Simulation &sim)
|
||||||
: start_rod(std::move(rod)), agg({}), every(t_every), time_step(0), type(t_type) {
|
: start_rod(std::move(rod)), every(t_every), time_step(0), type(t_type) {
|
||||||
|
auto time = sim.getMDeltaT() * static_cast<double>(every);
|
||||||
|
switch (type) {
|
||||||
|
case Type::msd:
|
||||||
|
target = 4.0 * 0.5 * (rod.getDiff().trace()) * time;
|
||||||
|
break;
|
||||||
|
case Type::oaf:
|
||||||
|
target = std::exp(-rod.getDRot() * time);
|
||||||
|
break;
|
||||||
|
case Type::empxx:
|
||||||
|
target = 0;
|
||||||
|
break;
|
||||||
|
case Type::empyy:
|
||||||
|
target = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const LiveAgg &Compute::getAgg() const {
|
const LiveAgg &Compute::getAgg() const {
|
||||||
@ -67,3 +83,11 @@ Compute::Type Compute::getType() const {
|
|||||||
double Compute::getTime() const {
|
double Compute::getTime() const {
|
||||||
return static_cast<double>(every);
|
return static_cast<double>(every);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Compute::getTarget() const {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Compute::getDifference() const {
|
||||||
|
return abs(agg.getMean() -target);
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "LiveAgg.hpp"
|
#include "LiveAgg.hpp"
|
||||||
#include "Rod2d.hpp"
|
#include "Rod2d.hpp"
|
||||||
|
#include "Simulation.h"
|
||||||
|
|
||||||
class Compute {
|
class Compute {
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ public:
|
|||||||
msd, oaf, empxx, empyy
|
msd, oaf, empxx, empyy
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Compute(Rod2d rod, Type t_type, size_t t_every);
|
explicit Compute(Rod2d rod, Type t_type, size_t t_every, Simulation &sim);
|
||||||
|
|
||||||
void eval(const Rod2d &rod2D);
|
void eval(const Rod2d &rod2D);
|
||||||
|
|
||||||
@ -26,6 +27,8 @@ public:
|
|||||||
|
|
||||||
void eval_empXX(const Rod2d &rod2D);
|
void eval_empXX(const Rod2d &rod2D);
|
||||||
|
|
||||||
|
double getTarget() const;
|
||||||
|
|
||||||
void eval_empYY(const Rod2d &rod2D);
|
void eval_empYY(const Rod2d &rod2D);
|
||||||
|
|
||||||
[[nodiscard]] const LiveAgg &getAgg() const;
|
[[nodiscard]] const LiveAgg &getAgg() const;
|
||||||
@ -34,12 +37,17 @@ public:
|
|||||||
|
|
||||||
double getTime() const;
|
double getTime() const;
|
||||||
|
|
||||||
|
double getDifference() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Rod2d start_rod;
|
Rod2d start_rod;
|
||||||
LiveAgg agg;
|
LiveAgg agg;
|
||||||
size_t every;
|
size_t every;
|
||||||
size_t time_step;
|
size_t time_step;
|
||||||
Type type;
|
Type type;
|
||||||
|
double target;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
171
src/Integratoren2d_force.cpp
Normal file
171
src/Integratoren2d_force.cpp
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
//
|
||||||
|
// Created by jholder on 21.10.21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Integratoren2d_force.h"
|
||||||
|
|
||||||
|
constexpr double kBT = 1.0;
|
||||||
|
using Vector = Eigen::Vector2d;
|
||||||
|
|
||||||
|
|
||||||
|
Vector Integratoren2d_force::ortho(Vector e) {
|
||||||
|
return Vector{-e[1], e[0]};
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Matrix2d Integratoren2d_force::MatTraf(Vector e) {
|
||||||
|
Eigen::Matrix2d mat;
|
||||||
|
mat << e[0], -e[1],
|
||||||
|
e[1], e[0];
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Integratoren2d_force::Set0_deterministic(Rod2d &rod2D, Simulation & /*sim*/) {
|
||||||
|
auto trans_lab = Vector({0, 0.01});
|
||||||
|
rod2D.setPos(rod2D.getPos() + trans_lab);
|
||||||
|
Eigen::Rotation2D<double> rot(0.1);
|
||||||
|
rod2D.setE(rot * rod2D.getE());
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector Integratoren2d_force::unitVec = {1, 0};
|
||||||
|
|
||||||
|
|
||||||
|
void Integratoren2d_force::Set5_MBD(Rod2d &/*rod2D*/, Simulation &/*sim*/) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Integratoren2d_force::Set1_Euler(Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<Vector(Vector, Vector)> &force,
|
||||||
|
const std::function<double(Vector, Vector)> &torque) {
|
||||||
|
auto std = sim.getSTD(); // sqrt(2*delta_T)
|
||||||
|
//translation
|
||||||
|
Vector rand = {sim.getNorm(std), sim.getNorm(std)}; //gaussian noise
|
||||||
|
Vector trans_part = rod2D.getDiff_Sqrt() * rand; //translation vector in Particle System
|
||||||
|
Vector trans_lab = rod2D.getE_Base_matrix() * trans_part;
|
||||||
|
|
||||||
|
//Force
|
||||||
|
Vector F_lab = force(rod2D.getPos(), rod2D.getE());
|
||||||
|
Vector F_part = rod2D.getE_Base_matrix().inverse() * F_lab;
|
||||||
|
Vector F_trans = rod2D.getDiff_Sqrt() * F_part;
|
||||||
|
F_trans *= sim.getMDeltaT() / kBT;
|
||||||
|
|
||||||
|
|
||||||
|
//rotation
|
||||||
|
double rot = sim.getNorm(std) * rod2D.getDRot_Sqrt();// rotationsmatrix verwenden.
|
||||||
|
Vector e = rod2D.getE();
|
||||||
|
double M_rot = torque(rod2D.getPos(), rod2D.getE()) * rod2D.getDRot() / kBT * sim.getMDeltaT();
|
||||||
|
Vector new_e = e + (rot + M_rot) * ortho(e);
|
||||||
|
new_e.normalize();
|
||||||
|
//apply
|
||||||
|
rod2D.setPos(rod2D.getPos() + trans_lab + F_trans);
|
||||||
|
rod2D.setE(new_e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector Integratoren2d_force::Heun_predictor_pos(const Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<Vector(Vector, Vector)> &force) {
|
||||||
|
auto standard_dev = sim.getSTD();
|
||||||
|
Vector rand_pred = {sim.getNorm(standard_dev), sim.getNorm(standard_dev)}; //gaussian noise
|
||||||
|
Vector trans_pred_part = rod2D.getDiff_Sqrt() * rand_pred; //translation vector in Particle System
|
||||||
|
Vector trans_pred_lab = rod2D.getE_Base_matrix() * trans_pred_part;
|
||||||
|
|
||||||
|
Vector F_pred_lab = force(rod2D.getPos(), rod2D.getE());
|
||||||
|
Vector F_pred_part = rod2D.getE_Base_matrix().inverse() * F_pred_lab;
|
||||||
|
Vector F_pred_trans = rod2D.getDiff_Sqrt() * F_pred_part;
|
||||||
|
F_pred_trans *= sim.getMDeltaT() / kBT;
|
||||||
|
|
||||||
|
return F_pred_trans + trans_pred_lab;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector Integratoren2d_force::Heun_predictor_rot(const Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<double(Vector, Vector)> &torque) {
|
||||||
|
auto std = sim.getSTD();
|
||||||
|
double rot_predict = sim.getNorm(std) * rod2D.getDRot_Sqrt();// rotationsmatrix verwenden.
|
||||||
|
Vector e = rod2D.getE();
|
||||||
|
double M_predict_rot = torque(rod2D.getPos(), rod2D.getE()) * rod2D.getDRot() / kBT * sim.getMDeltaT();
|
||||||
|
Vector e_change_predict = (rot_predict + M_predict_rot) * ortho(e);
|
||||||
|
|
||||||
|
return e_change_predict;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Integratoren2d_force::Set2_Heun(Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<Vector(Vector, Vector)> &force,
|
||||||
|
const std::function<double(Vector, Vector)> &torque) {
|
||||||
|
|
||||||
|
Vector delta_pos_predictor = Heun_predictor_pos(rod2D, sim, force);
|
||||||
|
Vector pos_predictor = rod2D.getPos() + delta_pos_predictor;
|
||||||
|
|
||||||
|
Vector delta_e_predictor = Heun_predictor_rot(rod2D, sim, torque);
|
||||||
|
Vector e_predict = rod2D.getE() + delta_e_predictor;
|
||||||
|
e_predict.normalize();
|
||||||
|
|
||||||
|
|
||||||
|
Rod2d pred_rod = rod2D;
|
||||||
|
pred_rod.setPos(pos_predictor);
|
||||||
|
pred_rod.setE(e_predict);
|
||||||
|
|
||||||
|
Vector delta_pos_future = Heun_predictor_pos(pred_rod, sim, force);
|
||||||
|
Vector delta_e_future = Heun_predictor_rot(pred_rod, sim, torque);
|
||||||
|
|
||||||
|
//integration
|
||||||
|
Vector pos_integrated = 0.5 * rod2D.getPos() + 0.5 * pos_predictor + 0.5 * delta_pos_future;
|
||||||
|
Vector e_integrated = rod2D.getE() + 0.5 * (delta_e_predictor + delta_e_future);
|
||||||
|
//apply
|
||||||
|
rod2D.setPos(pos_integrated);
|
||||||
|
rod2D.setE(e_integrated.normalized());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Integratoren2d_force::Set3_Exact(Rod2d &rod2D, Simulation &sim,
|
||||||
|
std::function<Eigen::Vector2d(Eigen::Vector2d, Eigen::Vector2d)> force,
|
||||||
|
std::function<double(Eigen::Vector2d, Eigen::Vector2d)> torque) {
|
||||||
|
auto std = sim.getSTD(); // sqrt(2*delta_T)
|
||||||
|
//translation
|
||||||
|
Vector rand = {sim.getNorm(std), sim.getNorm(std)}; //gaussian noise
|
||||||
|
Vector trans_part = rod2D.getDiff_Sqrt() * rand; //translation vector in Particle System
|
||||||
|
|
||||||
|
Vector F_lab = force(rod2D.getPos(), rod2D.getE());
|
||||||
|
Vector F_part = rod2D.getE_Base_matrix().inverse() * F_lab;
|
||||||
|
|
||||||
|
Vector F_trans = rod2D.getDiff_Sqrt() * F_part;
|
||||||
|
F_trans *= sim.getMDeltaT() / kBT;
|
||||||
|
Vector trans_lab = rod2D.getE_Base_matrix() * trans_part;
|
||||||
|
|
||||||
|
//rotation
|
||||||
|
double rot = sim.getNorm(std) * rod2D.getDRot_Sqrt();// rotationsmatrix verwenden.
|
||||||
|
Vector e = rod2D.getE();
|
||||||
|
double M_rot = torque(rod2D.getPos(), rod2D.getE()) * rod2D.getDRot() / kBT * sim.getMDeltaT();
|
||||||
|
auto correction = -0.5 * pow(rod2D.getDRot(), 2) / pow(kBT, 2) * sim.getMDeltaT();
|
||||||
|
Vector new_e = e + (rot + M_rot) * ortho(e) + correction * e;
|
||||||
|
new_e.normalize();
|
||||||
|
//apply
|
||||||
|
rod2D.setPos(rod2D.getPos() + trans_lab + F_trans);
|
||||||
|
rod2D.setE(new_e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Integratoren2d_force::Set4_BDAS(Rod2d &rod2D, Simulation &sim,
|
||||||
|
std::function<Eigen::Vector2d(Eigen::Vector2d, Eigen::Vector2d)> force,
|
||||||
|
std::function<double(Eigen::Vector2d, Eigen::Vector2d)> /*torque*/) {
|
||||||
|
auto std = sim.getSTD();
|
||||||
|
//translation
|
||||||
|
auto rand = Vector(sim.getNorm(std), sim.getNorm(std));
|
||||||
|
auto trans_part = rod2D.getDiff_Sqrt() * rand; //translation vector in Particle System
|
||||||
|
Eigen::Rotation2D rotMat(acos(unitVec.dot(rod2D.getE())));
|
||||||
|
auto trans_lab = rotMat * trans_part;
|
||||||
|
|
||||||
|
Vector F_lab = force(rod2D.getPos(), rod2D.getE());
|
||||||
|
Vector F_part = rotMat.inverse() * F_lab;
|
||||||
|
|
||||||
|
Vector F_trans = rod2D.getDiff_Sqrt() * F_part;
|
||||||
|
F_trans *= sim.getMDeltaT() / kBT;
|
||||||
|
|
||||||
|
|
||||||
|
auto rot = Eigen::Rotation2D<double>(sim.getNorm(std) * rod2D.getDRot_Sqrt());
|
||||||
|
Eigen::Rotation2Dd rotation(rot);
|
||||||
|
auto e_new = (rotation.toRotationMatrix() * rod2D.getE()).normalized();
|
||||||
|
|
||||||
|
// Normalisation should not be necessary if a proper angular representation is used.
|
||||||
|
// But with vector e it is done in case of numerical errors
|
||||||
|
|
||||||
|
rod2D.setPos(rod2D.getPos() + trans_lab);
|
||||||
|
rod2D.setE(e_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
48
src/Integratoren2d_force.h
Normal file
48
src/Integratoren2d_force.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// Created by jholder on 21.10.21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Rod2d.hpp"
|
||||||
|
#include "Simulation.h"
|
||||||
|
|
||||||
|
class Integratoren2d_force {
|
||||||
|
public:
|
||||||
|
static void Set1_Euler(Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<Eigen::Vector2d(Eigen::Vector2d, Eigen::Vector2d)> &force,
|
||||||
|
const std::function<double(Eigen::Vector2d, Eigen::Vector2d)> &torque);
|
||||||
|
|
||||||
|
|
||||||
|
static void Set2_Heun(Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<Eigen::Vector2d(Eigen::Vector2d, Eigen::Vector2d)> &force,
|
||||||
|
const std::function<double(Eigen::Vector2d, Eigen::Vector2d)> &torque);
|
||||||
|
|
||||||
|
static void Set3_Exact(Rod2d &rod2D, Simulation &sim,
|
||||||
|
std::function<Eigen::Vector2d(Eigen::Vector2d, Eigen::Vector2d)> force,
|
||||||
|
std::function<double(Eigen::Vector2d, Eigen::Vector2d)> torque);
|
||||||
|
|
||||||
|
static void Set4_BDAS(Rod2d &rod2D, Simulation &sim,
|
||||||
|
std::function<Eigen::Vector2d(Eigen::Vector2d, Eigen::Vector2d)> force,
|
||||||
|
std::function<double(Eigen::Vector2d, Eigen::Vector2d)> torque);
|
||||||
|
|
||||||
|
static const Eigen::Vector2d unitVec;
|
||||||
|
|
||||||
|
static void Set5_MBD(Rod2d &rod2D, Simulation &sim);
|
||||||
|
|
||||||
|
static void Set0_deterministic(Rod2d &rod2D, Simulation &sim);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Eigen::Vector2d ortho(Eigen::Vector2d e);
|
||||||
|
|
||||||
|
static Eigen::Matrix2d MatTraf(Eigen::Matrix<double, 2, 1> e);
|
||||||
|
|
||||||
|
static Eigen::Vector2d Heun_predictor_pos(const Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<Eigen::Vector2d(Eigen::Vector2d,
|
||||||
|
Eigen::Vector2d)> &force);
|
||||||
|
|
||||||
|
static Eigen::Vector2d
|
||||||
|
Heun_predictor_rot(const Rod2d &rod2D, Simulation &sim,
|
||||||
|
const std::function<double(Eigen::Vector2d, Eigen::Vector2d)> &torque);
|
||||||
|
};
|
||||||
|
|
@ -4,17 +4,10 @@
|
|||||||
|
|
||||||
#include "Integratoren2d_forceless.h"
|
#include "Integratoren2d_forceless.h"
|
||||||
|
|
||||||
Eigen::Vector2d ortho(Eigen::Vector2d e) {
|
Eigen::Vector2d Integratoren2d_forceless::ortho(Eigen::Vector2d e) {
|
||||||
return Eigen::Vector2d{-e[1], e[0]};
|
return Eigen::Vector2d{-e[1], e[0]};
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::Matrix2d mat(Eigen::Vector2d e) {
|
|
||||||
Eigen::Matrix2d matrix;
|
|
||||||
matrix << e, ortho(e);
|
|
||||||
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Integratoren2d_forceless::Set0_deterministic(Rod2d &rod2D, Simulation & /*sim*/) {
|
void Integratoren2d_forceless::Set0_deterministic(Rod2d &rod2D, Simulation & /*sim*/) {
|
||||||
auto trans_lab = Eigen::Vector2d({0, 0.01});
|
auto trans_lab = Eigen::Vector2d({0, 0.01});
|
||||||
rod2D.setPos(rod2D.getPos() + trans_lab);
|
rod2D.setPos(rod2D.getPos() + trans_lab);
|
||||||
@ -57,6 +50,9 @@ void Integratoren2d_forceless::Set2_Heun(Rod2d &rod2D, Simulation &sim) {
|
|||||||
|
|
||||||
double rot = sim.getNorm(std) * rod2D.getDRot_Sqrt();
|
double rot = sim.getNorm(std) * rod2D.getDRot_Sqrt();
|
||||||
Eigen::Vector2d e_integrated = e + 0.5 * (rot * ortho(e) + rot * ortho(e_predict));
|
Eigen::Vector2d e_integrated = e + 0.5 * (rot * ortho(e) + rot * ortho(e_predict));
|
||||||
|
//TODO pos integration with future system ???
|
||||||
|
// Eigen::Vector2d pos_integrated = rod2D.getPos() + 0.5 * (rot * ortho(e) + rot * ortho(e_predict));
|
||||||
|
|
||||||
//apply
|
//apply
|
||||||
rod2D.setPos(pos_predictor);
|
rod2D.setPos(pos_predictor);
|
||||||
rod2D.setE(e_integrated.normalized());
|
rod2D.setE(e_integrated.normalized());
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#ifndef MYPROJECT_INTEGRATOREN2D_FORCELESS_H
|
#ifndef MYPROJECT_INTEGRATOREN2D_FORCELESS_H
|
||||||
#define MYPROJECT_INTEGRATOREN2D_FORCELESS_H
|
#define MYPROJECT_INTEGRATOREN2D_FORCELESS_H
|
||||||
|
|
||||||
#include "Rod2d.hpp"
|
#include "Rod2d.hpp"
|
||||||
#include "Simulation.h"
|
#include "Simulation.h"
|
||||||
|
|
||||||
@ -19,11 +20,14 @@ public:
|
|||||||
|
|
||||||
static const Eigen::Vector2d unitVec;
|
static const Eigen::Vector2d unitVec;
|
||||||
|
|
||||||
static Eigen::Matrix2d e_2_matrix(Eigen::Vector2d m_e) ;
|
static Eigen::Matrix2d e_2_matrix(Eigen::Vector2d m_e);
|
||||||
|
|
||||||
static void Set5_MBD(Rod2d &rod2D, Simulation &sim);
|
static void Set5_MBD(Rod2d &rod2D, Simulation &sim);
|
||||||
|
|
||||||
static void Set0_deterministic(Rod2d &rod2D, Simulation &sim);
|
static void Set0_deterministic(Rod2d &rod2D, Simulation &sim);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Eigen::Vector2d ortho(Eigen::Vector2d e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
39
src/main.cpp
39
src/main.cpp
@ -5,10 +5,27 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Calculation.h"
|
#include "Calculation.h"
|
||||||
#include "Integratoren2d_forceless.h"
|
#include "Integratoren2d_forceless.h"
|
||||||
|
#include "Integratoren2d_force.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
constexpr int numStep = 1000000;
|
constexpr int numStep = 1000;
|
||||||
Calculation euler(Integratoren2d_forceless::Set4_BDAS, {{Compute::Type::msd, 1},
|
auto zero_Force = [](const Eigen::Vector2d & /*pos*/,
|
||||||
|
const Eigen::Vector2d & /*torque*/) -> Eigen::Vector2d { return {0.0, 0.0}; };
|
||||||
|
auto zero_Torque = [](const Eigen::Vector2d & /*pos*/,
|
||||||
|
const Eigen::Vector2d & /*torque*/) -> double { return 0.0; };
|
||||||
|
/* auto euler_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set1_Euler(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};*/
|
||||||
|
auto heun_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set2_Heun(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};
|
||||||
|
/*auto exact_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set3_Exact(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};*//*
|
||||||
|
auto bdas_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set4_BDAS(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};*/
|
||||||
|
Calculation euler(heun_Zero, {{Compute::Type::msd, 1},
|
||||||
{Compute::Type::msd, 2},
|
{Compute::Type::msd, 2},
|
||||||
{Compute::Type::msd, 4},
|
{Compute::Type::msd, 4},
|
||||||
{Compute::Type::msd, 8},
|
{Compute::Type::msd, 8},
|
||||||
@ -20,21 +37,15 @@ int main() {
|
|||||||
{Compute::Type::oaf, 16}}, 0.01, 12345);
|
{Compute::Type::oaf, 16}}, 0.01, 12345);
|
||||||
euler.run(numStep);
|
euler.run(numStep);
|
||||||
for (const auto &com: euler.getComputes()) {
|
for (const auto &com: euler.getComputes()) {
|
||||||
if(com.getType()!=Compute::Type::msd)
|
if (com.getType() != Compute::Type::msd)
|
||||||
continue;
|
continue;
|
||||||
auto time = euler.getSim().getMDeltaT() * com.getTime();
|
std::cout << "MSD: " << com.getDifference() << " " << com.getAgg().getMean()
|
||||||
auto targetMSD = 4.0 * 0.5 * (euler.getRod().getDiff().trace()) * time;
|
<< " <-> " << com.getTarget() << std::endl;
|
||||||
std::cout << "MSD: " << com.getAgg().getMean()
|
|
||||||
<< " +- "
|
|
||||||
<< com.getAgg().getSEM()
|
|
||||||
<< " " << targetMSD << std::endl;
|
|
||||||
}
|
}
|
||||||
for (const auto &com: euler.getComputes()) {
|
for (const auto &com: euler.getComputes()) {
|
||||||
if(com.getType()!=Compute::Type::oaf)
|
if (com.getType() != Compute::Type::oaf)
|
||||||
continue;
|
continue;
|
||||||
auto time = euler.getSim().getMDeltaT() * com.getTime();
|
std::cout << "OAF: " << com.getDifference() << " " << com.getAgg().getMean()
|
||||||
auto targetOAF = std::exp(-euler.getRod().getDRot() * time);
|
<< " <-> "<< com.getTarget() << std::endl;
|
||||||
std::cout <<"OAF: " << com.getAgg().getMean()
|
|
||||||
<< " +- " << com.getAgg().getSEM() << " " << targetOAF << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ target_link_libraries(catch_main PRIVATE project_options)
|
|||||||
set(TEST_FILES
|
set(TEST_FILES
|
||||||
test_LiveAgg.cpp
|
test_LiveAgg.cpp
|
||||||
test_Rod2d.cpp
|
test_Rod2d.cpp
|
||||||
test_Calculation.cpp test_Compute.cpp test_Simulation.cpp)
|
test_Calculation.cpp test_Compute.cpp test_Simulation.cpp test_Integratoren.cpp)
|
||||||
|
|
||||||
add_executable(tests ${TEST_FILES})
|
add_executable(tests ${TEST_FILES})
|
||||||
target_link_libraries(tests PRIVATE project_warnings project_options catch_main Eigen3::Eigen3 integratoren)
|
target_link_libraries(tests PRIVATE project_warnings project_options catch_main Eigen3::Eigen3 integratoren)
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
#include "Integratoren2d_forceless.h"
|
#include "Integratoren2d_forceless.h"
|
||||||
|
|
||||||
TEST_CASE("Compute") {
|
TEST_CASE("Compute") {
|
||||||
auto rod = Rod2d(1.0);
|
Rod2d rod(1.0);
|
||||||
auto com = Compute(rod, Compute::Type::msd, 10);
|
Simulation sim(0.1,1);
|
||||||
|
auto com = Compute(rod, Compute::Type::msd, 10, sim);
|
||||||
SECTION("Mean of same values") {
|
SECTION("Mean of same values") {
|
||||||
for (int i = 0; i < 100; ++i) {
|
for (int i = 0; i < 100; ++i) {
|
||||||
com.eval(rod);
|
com.eval(rod);
|
||||||
|
76
test/test_Integratoren.cpp
Normal file
76
test/test_Integratoren.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// Created by jholder on 24.10.21.
|
||||||
|
//
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <Integratoren2d_forceless.h>
|
||||||
|
#include <Calculation.h>
|
||||||
|
#include <Compute.h>
|
||||||
|
#include <Integratoren2d_force.h>
|
||||||
|
|
||||||
|
TEST_CASE("Integratoren") {
|
||||||
|
auto zero_Force = [](const Eigen::Vector2d & /*pos*/,
|
||||||
|
const Eigen::Vector2d & /*torque*/) -> Eigen::Vector2d { return {0.0, 0.0}; };
|
||||||
|
auto zero_Torque = [](const Eigen::Vector2d & /*pos*/,
|
||||||
|
const Eigen::Vector2d & /*torque*/) -> double { return 0.0; };
|
||||||
|
auto euler_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set1_Euler(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};
|
||||||
|
auto heun_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set2_Heun(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};
|
||||||
|
auto exact_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set3_Exact(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};
|
||||||
|
auto bdas_Zero = [&](Rod2d &rod, Simulation &sim) {
|
||||||
|
return Integratoren2d_force::Set4_BDAS(rod, sim, zero_Force, zero_Torque);
|
||||||
|
};
|
||||||
|
SECTION("Euler") {
|
||||||
|
Calculation euler(Integratoren2d_forceless::Set1_Euler, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
euler.run(10000);
|
||||||
|
for (auto &c: euler.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
Calculation euler_force(euler_Zero, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
euler_force.run(10000);
|
||||||
|
for (auto &c: euler_force.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}SECTION("Heun") {
|
||||||
|
{
|
||||||
|
Calculation heun(Integratoren2d_forceless::Set2_Heun, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
heun.run(10000);
|
||||||
|
for (auto &c: heun.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Calculation heun_force(heun_Zero, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
heun_force.run(10000);
|
||||||
|
for (auto &c: heun_force.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}
|
||||||
|
}SECTION("Exact") {
|
||||||
|
{
|
||||||
|
Calculation exact(Integratoren2d_forceless::Set3_Exact, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
exact.run(10000);
|
||||||
|
for (auto &c: exact.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Calculation exact_force(exact_Zero, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
exact_force.run(10000);
|
||||||
|
for (auto &c: exact_force.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}
|
||||||
|
}SECTION("BDAS") {
|
||||||
|
{
|
||||||
|
Calculation bdas(Integratoren2d_forceless::Set4_BDAS, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
bdas.run(10000);
|
||||||
|
for (auto &c: bdas.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Calculation bdas_zero(bdas_Zero, {{Compute::Type::msd, 1},
|
||||||
|
{Compute::Type::oaf, 1}}, 0.01, 12345);
|
||||||
|
bdas_zero.run(10000);
|
||||||
|
for (auto &c: bdas_zero.getComputes()) { CHECK(c.getDifference() <= 0.005); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user