13#ifndef CD_KMCSOLVERIMPLEM_H
14#define CD_KMCSOLVERIMPLEM_H
18#include <unordered_set>
27#include <CD_NamespaceHeader.H>
29template <
typename R,
typename State,
typename T>
32 CH_TIME(
"KMCSolver::KMCSolver");
34 this->setSolverParameters(0, 0, 100, std::numeric_limits<Real>::max(), 0.0, 1.E-6);
37template <
typename R,
typename State,
typename T>
40 CH_TIME(
"KMCSolver::KMCSolver");
45template <
typename R,
typename State,
typename T>
48 CH_TIME(
"KMCSolver::~KMCSolver");
51template <
typename R,
typename State,
typename T>
60 this->setSolverParameters(0, 0, 100, std::numeric_limits<Real>::max(), 0.0, 1.E-6);
63template <
typename R,
typename State,
typename T>
72 CH_TIME(
"KMCSolver::setSolverParameters");
82template <
typename R,
typename State,
typename T>
86 CH_TIME(
"KMCSolver::getNu(State)");
98 x =
static_cast<T>(0);
117template <
typename R,
typename State,
typename T>
121 CH_TIME(
"KMCSolver::propensities(State)");
123 return this->propensities(
a_state, m_reactions);
126template <
typename R,
typename State,
typename T>
130 CH_TIME(
"KMCSolver::propensities(State, ReactionList)");
143template <
typename R,
typename State,
typename T>
147 CH_TIME(
"KMCSolver::totalPropensity(State)");
149 return this->totalPropensity(
a_state, m_reactions);
152template <
typename R,
typename State,
typename T>
156 CH_TIME(
"KMCSolver::totalPropensity(State, ReactionList)");
169template <
typename R,
typename State,
typename T>
173 CH_TIME(
"KMCSolver::partitionReactions(State)");
175 return this->partitionReactions(
a_state, m_reactions);
178template <
typename R,
typename State,
typename T>
182 CH_TIME(
"KMCSolver::partitionReactions(State, ReactionList)");
208template <
typename R,
typename State,
typename T>
213 return this->getCriticalTimeStep(
a_state, m_reactions);
216template <
typename R,
typename State,
typename T>
221 CH_TIME(
"KMCSolver::getCriticalTimeStep");
225 Real dt = std::numeric_limits<Real>::max();
231 dt = this->getCriticalTimeStep(
A);
237template <
typename R,
typename State,
typename T>
241 CH_TIME(
"KineticMonteCarlo::getCriticalTimeStep(std::vector<Real>)");
244 Real A = std::numeric_limits<Real>::min();
250 return this->getCriticalTimeStep(
A);
253template <
typename R,
typename State,
typename T>
257 CH_TIME(
"KineticMonteCarlo::getCriticalTimeStep(Real)");
264template <
typename R,
typename State,
typename T>
268 CH_TIME(
"KMCSolver::getNonCriticalTimeStep(State");
275template <
typename R,
typename State,
typename T>
279 CH_TIME(
"KMCSolver::getNonCriticalTimeStep(State, ReactionList");
286template <
typename R,
typename State,
typename T>
292 CH_TIME(
"KMCSolver::getNonCriticalTimeStep(State, ReactionList, std::vector<Real>");
298 Real dt = std::numeric_limits<Real>::max();
344 Real dt1 = std::numeric_limits<Real>::max();
345 Real dt2 = std::numeric_limits<Real>::max();
352 if (
mu > std::numeric_limits<Real>::min()) {
355 if (
sigma2 > std::numeric_limits<Real>::min()) {
367template <
typename R,
typename State,
typename T>
374 CH_TIME(
"KMCSolver::computeDt(State, ReactionList, std::vector<Real>, Real");
380 Real dt = std::numeric_limits<Real>::max();
428 if (
mu > std::numeric_limits<Real>::min()) {
438template <
typename R,
typename State,
typename T>
442 CH_TIME(
"KMCSolver::stepSSA(State, Real)");
444 this->stepSSA(
a_state, m_reactions);
447template <
typename R,
typename State,
typename T>
451 CH_TIME(
"KMCSolver::stepSSA(State, ReactionList, Real)");
462template <
typename R,
typename State,
typename T>
468 CH_TIME(
"KMCSolver::stepSSA(State, ReactionList, std::vector<Real>)");
475 constexpr T one = (
T)1;
505template <
typename R,
typename State,
typename T>
509 CH_TIME(
"KMCSolver::advanceSSA(State, Real)");
514template <
typename R,
typename State,
typename T>
518 CH_TIME(
"KMCSolver::advanceSSA(State, ReactionList, Real)");
532 const Real nextDt = this->getCriticalTimeStep(propensities);
544template <
typename R,
typename State,
typename T>
548 CH_TIME(
"KMCSolver::stepExplicitEuler(State, Real)");
550 this->stepExplicitEuler(
a_state, m_reactions,
a_dt);
553template <
typename R,
typename State,
typename T>
559 CH_TIME(
"KMCSolver::stepExplicitEuler(State, ReactionList, std::vector<Real>, Real)");
577template <
typename R,
typename State,
typename T>
581 CH_TIME(
"KMCSolver::stepMidpoint(State&, const Real)");
586template <
typename R,
typename State,
typename T>
590 CH_TIMERS(
"KMCSolver::stepMidpoint(State&, const ReactionList&, const Real)");
591 CH_TIMER(
"KMCSolver::stepTauMidPoint::first_loop",
t1);
592 CH_TIMER(
"KMCSolver::stepTauMidPoint::second_loop",
t2);
622template <
typename R,
typename State,
typename T>
626 CH_TIME(
"KMCSolver::stepPRC(State&, const Real)");
631template <
typename R,
typename State,
typename T>
635 CH_TIMERS(
"KMCSolver::stepPRC(State&, const ReactionList&, const Real)");
636 CH_TIMER(
"KMCSolver::stepPRC::first_loop",
t1);
637 CH_TIMER(
"KMCSolver::stepPRC::second_loop",
t2);
663 const T nr = (
T)Random::getPoisson<long long>(
aj[
i] *
a_dt);
671template <
typename R,
typename State,
typename T>
675 CH_TIME(
"KMCSolver::stepImplicitEuler(State, a_dt)");
677 this->stepImplicitEuler(
a_state, m_reactions,
a_dt);
680template <
typename R,
typename State,
typename T>
686 CH_TIME(
"KMCSolver::stepImplicitEuler(State, ReactionList, a_dt)");
718 for (
int i = 0;
i <
N;
i++) {
724 for (
int j = 0;
j <
M;
j++) {
727 for (
int i = 0;
i <
N;
i++) {
734 auto computeF = [&](
double*
F,
const double*
Xit,
const double*
C) ->
void {
739 for (
int i = 0;
i <
N;
i++) {
748 for (
int i = 0;
i <
N;
i++) {
752 for (
int j = 0;
j <
M;
j++) {
755 for (
int i = 0;
i <
N;
i++) {
767 for (
int i = 0;
i <
N;
i++) {
794 for (
int i = 0;
i <
N;
i++) {
802 for (
int k = 0;
k < m_maxIter;
k++) {
811 for (
int j = 0;
j <
N;
j++) {
813 for (
int s = 0;
s <
N;
s++) {
817 X2[
j] += std::max(0.01 *
X[
j], 1.0);
821 for (
int i = 0;
i <
N;
i++) {
832 const std::string err =
"KMCSolver<R, State, T>::stepImplicitEuler -- could not solve A*x = b";
842 for (
int i = 0;
i <
N;
i++) {
859 for (
int i = 0;
i <
N;
i++) {
865 for (
int i = 0;
i <
N;
i++) {
873template <
typename R,
typename State,
typename T>
879 CH_TIME(
"KMCSolver::advanceTau(State, ReactionList, Real, KMCLeapPropagator)");
884template <
typename R,
typename State,
typename T>
891 CH_TIME(
"KMCSolver::advanceTau(State, ReactionList, Real, KMCLeapPropagator)");
952template <
typename R,
typename State,
typename T>
958 CH_TIME(
"KMCSolver::advanceHybrid(State, Real, KMCLeapPropagator)");
963template <
typename R,
typename State,
typename T>
970 CH_TIME(
"KMCSolver::advanceHybrid(State, ReactionList, Real, KMCLeapPropagator)");
975 this->stepExplicitEuler(
s,
r,
dt);
982 this->stepMidpoint(
s,
r,
dt);
989 this->stepPRC(
s,
r,
dt);
996 this->stepImplicitEuler(
s,
r,
dt);
1002 MayDay::Error(
"KMCSolver::advanceHybrid - unknown leap propagator requested");
1007template <
typename R,
typename State,
typename T>
1015 CH_TIME(
"KMCSolver::advanceHybrid(State, ReactionList, Real, std::function)");
1017 constexpr T one = (
T)1;
1077 for (
size_t i = 0;
i < propensities.size();
i++) {
1078 Asum += propensities[
i];
1144#include <CD_NamespaceFooter.H>
Class for running Kinetic Monte Carlo functionality.
KMCLeapPropagator
Supported propagators for hybrid tau leaping.
Definition CD_KMCSolver.H:35
@ ImplicitEuler
Implicit Euler tau leaping.
@ Midpoint
Gillespie's midpoint method.
@ ExplicitEuler
Regular tau leaping.
@ PRC
Hu and Li's Poisson random correction method.
Interface to some LaPack routines.
File containing some useful static methods related to random number generation.
std::vector< std::shared_ptr< const R > > ReactionList
Alias for the list of reactions.
Definition CD_KMCSolver.H:63
void setSolverParameters(T a_numCrit, T a_numSSA, T a_maxIter, Real a_eps, Real a_SSAlim, Real a_exitTol) noexcept
Set solver parameters.
Definition CD_KMCSolverImplem.H:65
Real computeDt(const State &a_state, const ReactionList &a_reactions, const std::vector< Real > &a_propensities, Real a_epsilon) const noexcept
Compute a time step using the leap condition on the mean value.
Definition CD_KMCSolverImplem.H:369
virtual ~KMCSolver() noexcept
Destructor.
Definition CD_KMCSolverImplem.H:46
void define(const ReactionList &a_reactions) noexcept
Define function. Sets the reactions.
Definition CD_KMCSolverImplem.H:53
KMCSolver() noexcept
Default constructor. Must subsequently call define.
Definition CD_KMCSolverImplem.H:30
std::vector< std::vector< T > > getNu(const State &a_state, const ReactionList &a_reactions) const noexcept
Compute the state vector changes for all reactions.
Definition CD_KMCSolverImplem.H:84
Real getCriticalTimeStep(const State &a_state) const noexcept
Get the time to the next critical reaction.
Definition CD_KMCSolverImplem.H:210
void advanceSSA(State &a_state, Real a_dt) const noexcept
Advance with the SSA over the input time. This can end up using substepping.
Definition CD_KMCSolverImplem.H:507
void stepImplicitEuler(State &a_state, Real a_dt) const noexcept
Perform one implicit Euler tau-leaping step using ALL reactions.
Definition CD_KMCSolverImplem.H:673
void advanceHybrid(State &a_state, Real a_dt, const KMCLeapPropagator &a_leapPropagator=KMCLeapPropagator::ExplicitEuler) const noexcept
Advance using Cao et. al. hybrid algorithm over the input time. This can end up using substepping.
Definition CD_KMCSolverImplem.H:954
void stepPRC(State &a_state, Real a_dt) const noexcept
Perform one leaping step using the PRC method for ALL reactions.
Definition CD_KMCSolverImplem.H:624
void stepMidpoint(State &a_state, Real a_dt) const noexcept
Perform one leaping step using the midpoint method for ALL reactions.
Definition CD_KMCSolverImplem.H:579
std::pair< ReactionList, ReactionList > partitionReactions(const State &a_state) const noexcept
Partition reactions into critical and non-critical reactions.
Definition CD_KMCSolverImplem.H:171
void stepSSA(State &a_state) const noexcept
Perform a single SSA step.
Definition CD_KMCSolverImplem.H:440
void advanceTau(State &a_state, const Real &a_dt, const KMCLeapPropagator &a_leapPropagator=KMCLeapPropagator::ExplicitEuler) const noexcept
Advance using a specified tau-leaping algorithm.
Definition CD_KMCSolverImplem.H:875
Real getNonCriticalTimeStep(const State &a_state) const noexcept
Get the non-critical time step.
Definition CD_KMCSolverImplem.H:266
Real totalPropensity(const State &a_state) const noexcept
Compute the total propensity for ALL reactions.
Definition CD_KMCSolverImplem.H:145
void stepExplicitEuler(State &a_state, Real a_dt) const noexcept
Perform one plain tau-leaping step using ALL reactions.
Definition CD_KMCSolverImplem.H:546
std::vector< Real > propensities(const State &a_state) const noexcept
Compute propensities for ALL reactions.
Definition CD_KMCSolverImplem.H:119
static Real getUniformReal01()
Get a uniform real number on the interval [0,1].
Definition CD_RandomImplem.H:156
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:38
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:26