KIDS  ver-0.0.1
KIDS : Kernel Integrated Dynamics Simulator
Loading...
Searching...
No Matches
Kernel_Thermostat.h
Go to the documentation of this file.
1#ifndef Thermostat_H
2#define Thermostat_H
3#include <map>
4
5#include "kids/Kernel.h"
6
7#endif // Thermostat_H
8
10const int ndofs_sy = 7;
11const kids_real wgt_sy[ndofs_sy] = {0.784513610477560f, 0.235573213359357f, -1.17767998417887f, 1.3151863206839063f,
12 -1.17767998417887f, 0.235573213359357f, 0.784513610477560f};
13namespace thermo_policy {
15const std::map<std::string, _enum> _dict = {{"#none", None}, {"#lang", Langevin}, {"#and", Andersen}, {"#nhc", NHC}};
16}; // namespace thermo_policy
17
18class Kernel_Update_T final : public Kernel {
19 public:
20 Kernel_Update_T(double scale) : Kernel(), scale{scale} {};
21
22 virtual const std::string getName();
23
24 virtual int getType() const;
25
26 private:
28
29 int ndofs;
30
31 double scale;
32 double dt;
33 double beta;
34 double gammal;
35 double randu;
36
37 double *p, *m;
38 double *c1, *c2p;
39 double *nhc_x, *nhc_p, *nhc_G, *nhc_Q;
40
41 virtual void setInputParam_impl(std::shared_ptr<Param>& PM) {
42 ndofs = PM->get_int("N", LOC());
43 dt = PM->get_double("dt", LOC());
44 gammal = PM->get_double("gammal", LOC(), 0.1);
45 dt *= scale;
46
47 thermo_option.flag = PM->get_string("thermo_flag", LOC(), "#lang");
49
50 // read temperature
51 double temp = PM->get_double("temp", LOC(), phys::temperature_d, 1.0f);
52 beta = 1.0f / (phys::au::k * temp); // never ignore k_Boltzman
53
54 nthstp = PM->get_int("nthstp", LOC(), 0);
55 nchain = PM->get_int("nchain", LOC(), 1);
56 nrespa = PM->get_int("nrespa", LOC(), 10);
57 }
58
59 virtual void setInputDataSet_impl(std::shared_ptr<DataSet>& DS) {
60 m = DS->def_real("integrator.m", ndofs);
61 p = DS->def_real("integrator.p", ndofs);
62
63
64 // if Langevin dynamics, set optimal c1 & c2p
65 c1 = DS->def_real("integrator.param.c1", ndofs);
66 c2p = DS->def_real("integrator.param.c2p", ndofs);
67 for (int i = 0; i < ndofs; ++i) {
68 c1[i] = exp(-gammal * dt);
69 c2p[i] = sqrt(1.0 - c1[i] * c1[i]);
70 }
71
72 // for NHC
73 if (thermo_option.type == thermo_policy::NHC) { // allow you to re-allocate it
74 nhc_x = DS->def_real("integrator.nhc.x", nchain * ndofs);
75 nhc_p = DS->def_real("integrator.nhc.p", nchain * ndofs);
76 nhc_G = DS->def_real("integrator.nhc.G", nchain * ndofs);
77 nhc_Q = DS->def_real("integrator.nhc.Q", nchain);
78
79 // optimal gammal = 20*dt
80 for (int i = 0; i < nchain; ++i) nhc_Q[i] = gammal * gammal / beta;
81 nhc_Q[0] *= ndofs;
82 }
83 }
84
85 virtual Status& executeKernel_impl(Status& stat) {
86 switch (thermo_option.type) {
88 for (int i = 0; i < ndofs; ++i) {
89 Kernel_Random::rand_gaussian(&randu);
90 p[i] = c1[i] * p[i] + c2p[i] * sqrt(m[i] / beta) * randu;
91 }
92 break;
94 for (int i = 0; i < ndofs; ++i) {
95 Kernel_Random::rand_uniform(&randu);
96 if (randu < 1 - c1[i]) {
97 Kernel_Random::rand_gaussian(&randu);
98 p[i] = sqrt(m[i] / beta) * randu;
99 }
100 }
101 break;
102 case thermo_policy::NHC: {
103 num_real smalldt = dt / nrespa;
104 num_real hsmalldt = 0.5f * smalldt;
105 num_real qsmalldt = 0.25f * smalldt;
106 num_real Te = 1.0f / (phys::au::k * beta);
107 num_real* rx = nhc_r + start; // thermostat with (start, start + N) DOFs
108 num_real* px = nhc_p + start; // thermostat with (start, start + N) DOFs
109 for (int i = 0, ix = 0; i < N; ++i, rx += nchain, px += nchain) {
110 // sweep nchain
111 for (int k = 0; k < nrespa; ++k) {
112 for (int s = 0; s < size_sy; ++s) {
113 // update nhc_p from nchain tail to head
114 if (nchain > 1)
115 px[nchain - 1] +=
116 (px[nchain - 2] * px[nchain - 2] / nhc_Q[nchain - 2] - Te) * wgt_sy[s] * hsmalldt;
117 for (int h = nchain - 2; h > 0; --h) {
118 px[h] *= exp(-px[h + 1] / nhc_Q[h + 1] * wgt_sy[s] * qsmalldt);
119 px[h] += (px[h - 1] * px[h - 1] / nhc_Q[h - 1] - Te) * wgt_sy[s] * hsmalldt;
120 px[h] *= exp(-px[h + 1] / nhc_Q[h + 1] * wgt_sy[s] * qsmalldt);
121 }
122 if (nchain > 1) px[0] -= px[1] / nhc_Q[1] * wgt_sy[s] * qsmalldt;
123 px[0] += (np[i] * np[i] / nm[i] - Te) * wgt_sy[s] * hsmalldt;
124 if (nchain > 1) px[0] -= px[1] / nhc_Q[1] * wgt_sy[s] * qsmalldt;
125
126 // update nhc_x and np
127 for (int h = 0; h < nchain; ++h) rx[h] += px[h] / nhc_Q[h] * wgt_sy[s] * smalldt;
128 np[i] *= exp(-px[0] / nhc_Q[0] * wgt_sy[s] * smalldt);
129
130 // update nhc_p from head to tail
131 if (nchain > 1) px[0] -= px[1] / nhc_Q[1] * wgt_sy[s] * qsmalldt;
132 px[0] += (np[i] * np[i] / nm[i] - Te) * wgt_sy[s] * hsmalldt;
133 if (nchain > 1) px[0] -= px[1] / nhc_Q[1] * wgt_sy[s] * qsmalldt;
134 for (int h = 1; h < nchain - 1; ++h) {
135 px[h] *= exp(-px[h + 1] / nhc_Q[h + 1] * wgt_sy[s] * qsmalldt);
136 px[h] += (px[h - 1] * px[h - 1] / nhc_Q[h - 1] - Te) * wgt_sy[s] * hsmalldt;
137 px[h] *= exp(-px[h + 1] / nhc_Q[h + 1] * wgt_sy[s] * qsmalldt);
138 }
139 if (nchain > 1)
140 px[nchain - 1] +=
141 (px[nchain - 2] * px[nchain - 2] / nhc_Q[nchain - 2] - Te) * wgt_sy[s] * hsmalldt;
142 }
143 }
144 }
145 break;
146 }
148 default:
149 break;
150 }
151 return 0;
152 }
153};
this file provide Kernel class
const kids_real wgt_sy[ndofs_sy]
const int ndofs_sy
Suzuki-Yoshida decomposition framework.
double * c2p
auxiliary
virtual int getType() const
virtual void setInputParam_impl(std::shared_ptr< Param > &PM)
Kernel_Update_T(double scale)
virtual void setInputDataSet_impl(std::shared_ptr< DataSet > &DS)
virtual Status & executeKernel_impl(Status &stat)
double * nhc_Q
auxiliary
double * m
saved in "integrator"
virtual const std::string getName()
#define LOC()
show the location information for debug
Definition fmt.h:49
constexpr dimension7 temperature_d
Definition phys.h:195
const std::map< std::string, _enum > _dict