MRMD 0.4.0
Multi Resolution Molecular Dynamics
Loading...
Searching...
No Matches
LennardJones.hpp
Go to the documentation of this file.
1// Copyright 2024 Sebastian Eibl
2// Copyright 2026 Julian Friedrich Hille
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// https://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#pragma once
17
18#include "data/Atoms.hpp"
20#include "datatypes.hpp"
21
22namespace mrmd::action::impl
23{
25{
26public:
40
46
47private:
48 Kokkos::View<PrecomputedValues*> precomputedValues_;
49 bool isShifted_;
50
51public:
52 KOKKOS_INLINE_FUNCTION
53 ForceAndEnergy computeForceAndEnergy(const real_t& distSqr, const idx_t& typeIdx) const
54 {
56 if (distSqr >= precomputedValues_(typeIdx).cappingDistanceSqr)
57 {
58 // normal LJ calculation
59 auto frac2 = 1_r / distSqr;
60 auto frac6 = frac2 * frac2 * frac2;
61 ret.forceFactor =
62 frac6 *
63 (precomputedValues_(typeIdx).ff1 * frac6 - precomputedValues_(typeIdx).ff2) * frac2;
64 ret.energy = frac6 * (precomputedValues_(typeIdx).ef1 * frac6 -
65 precomputedValues_(typeIdx).ef2) -
66 precomputedValues_(typeIdx).shift;
67 return ret;
68 }
69
70 // force capping
71 auto dist = std::sqrt(distSqr);
72 ret.forceFactor = precomputedValues_(typeIdx).cappingCoeff / dist;
73 ret.energy = precomputedValues_(typeIdx).energyAtCappingPoint -
74 (dist - precomputedValues_(typeIdx).cappingDistance) *
75 precomputedValues_(typeIdx).cappingCoeff -
76 precomputedValues_(typeIdx).shift;
77 return ret;
78 }
79
84 KOKKOS_FUNCTION
85 void operator()(const idx_t& typeIdx) const;
86
87 CappedLennardJonesPotential(const std::vector<real_t>& cappingDistance,
88 const std::vector<real_t>& rc,
89 const std::vector<real_t>& sigma,
90 const std::vector<real_t>& epsilon,
91 const idx_t& numTypes,
92 const bool isShifted);
93};
94} // namespace mrmd::action::impl
95
96namespace mrmd::action
97{
99{
100private:
102 real_t rcSqr_;
104 data::Atoms::force_t::atomic_access_slice force_;
106
107 HalfVerletList verletList_;
108
109 const idx_t numTypes_;
110
111 data::EnergyAndVirialReducer energyAndVirial_;
112
113public:
114 real_t getEnergy() const;
115 real_t getVirial() const;
116
117 void apply(data::Atoms& atoms, HalfVerletList& verletList);
118
119 template <TwoPositionsPredicate Pred>
120 void apply_if(const data::Atoms& atoms, const HalfVerletList& verletList, const Pred& pred);
121
122 LennardJones(const real_t rc,
123 const real_t& sigma,
124 const real_t& epsilon,
125 const real_t& cappingDistance = 0_r);
126
127 LennardJones(const std::vector<real_t>& cappingDistance,
128 const std::vector<real_t>& rc,
129 const std::vector<real_t>& sigma,
130 const std::vector<real_t>& epsilon,
131 const idx_t& numTypes,
132 const bool isShifted);
133};
134
135template <TwoPositionsPredicate Pred>
137 const HalfVerletList& verletList,
138 const Pred& pred)
139{
140 energyAndVirial_ = data::EnergyAndVirialReducer();
141 pos_ = atoms.getPos();
142 force_ = atoms.getForce();
143 type_ = atoms.getType();
144 verletList_ = verletList;
145
146 auto policy = Kokkos::RangePolicy<>(0, atoms.numLocalAtoms);
147
148 // avoid capturing this pointer
149 auto pos = pos_;
150 auto force = force_;
151 auto type = type_;
152 auto verletListLocal = verletList_;
153 auto rcSqr = rcSqr_;
154 auto LJ = LJ_;
155 auto numTypes = numTypes_;
156 auto predLocal = pred;
157
158 auto kernel = KOKKOS_LAMBDA(const idx_t idx, data::EnergyAndVirialReducer& energyAndVirial)
159 {
160 real_t posTmp[3];
161 posTmp[0] = pos(idx, 0);
162 posTmp[1] = pos(idx, 1);
163 posTmp[2] = pos(idx, 2);
164
165 real_t forceTmp[3] = {0_r, 0_r, 0_r};
166
167 const auto numNeighbors = idx_c(HalfNeighborList::numNeighbor(verletListLocal, idx));
168 for (idx_t n = 0; n < numNeighbors; ++n)
169 {
170 idx_t jdx = idx_c(HalfNeighborList::getNeighbor(verletListLocal, idx, n));
171 assert(0 <= jdx);
172
173 if (!predLocal(posTmp[0], posTmp[1], posTmp[2], pos(jdx, 0), pos(jdx, 1), pos(jdx, 2)))
174 continue;
175
176 auto dx = posTmp[0] - pos(jdx, 0);
177 auto dy = posTmp[1] - pos(jdx, 1);
178 auto dz = posTmp[2] - pos(jdx, 2);
179
180 auto distSqr = dx * dx + dy * dy + dz * dz;
181
182 if (distSqr > rcSqr) continue;
183
184 auto typeIdx = type(idx) * numTypes + type(jdx);
185 auto forceAndEnergy = LJ.computeForceAndEnergy(distSqr, typeIdx);
186 assert(!std::isnan(forceAndEnergy.forceFactor));
187 energyAndVirial.energy += forceAndEnergy.energy;
188 energyAndVirial.virial -= 0.5_r * forceAndEnergy.forceFactor * distSqr;
189
190 forceTmp[0] += dx * forceAndEnergy.forceFactor;
191 forceTmp[1] += dy * forceAndEnergy.forceFactor;
192 forceTmp[2] += dz * forceAndEnergy.forceFactor;
193
194 force(jdx, 0) -= dx * forceAndEnergy.forceFactor;
195 force(jdx, 1) -= dy * forceAndEnergy.forceFactor;
196 force(jdx, 2) -= dz * forceAndEnergy.forceFactor;
197 }
198
199 force(idx, 0) += forceTmp[0];
200 force(idx, 1) += forceTmp[1];
201 force(idx, 2) += forceTmp[2];
202 };
203
204 Kokkos::parallel_reduce("LennardJones::apply_if", policy, kernel, energyAndVirial_);
205 Kokkos::fence();
206}
207
208} // namespace mrmd::action
Definition LennardJones.hpp:99
real_t getEnergy() const
Definition LennardJones.cpp:35
real_t getVirial() const
Definition LennardJones.cpp:36
void apply(data::Atoms &atoms, HalfVerletList &verletList)
Definition LennardJones.cpp:24
void apply_if(const data::Atoms &atoms, const HalfVerletList &verletList, const Pred &pred)
Definition LennardJones.hpp:136
KOKKOS_FUNCTION void operator()(const idx_t &typeIdx) const
Initialize shift and capping parameters.
Definition LennardJones.cpp:62
KOKKOS_INLINE_FUNCTION ForceAndEnergy computeForceAndEnergy(const real_t &distSqr, const idx_t &typeIdx) const
Definition LennardJones.hpp:53
Data structure for storing information about atoms on the host and the device.
Definition Atoms.hpp:35
idx_t numLocalAtoms
Definition Atoms.hpp:120
KOKKOS_FORCEINLINE_FUNCTION pos_t getPos() const
Definition Atoms.hpp:64
KOKKOS_FORCEINLINE_FUNCTION force_t getForce() const
Definition Atoms.hpp:66
typename AtomsT::template member_slice_type< TYPE > type_t
Definition Atoms.hpp:59
typename AtomsT::template member_slice_type< POS > pos_t
Definition Atoms.hpp:56
KOKKOS_FORCEINLINE_FUNCTION type_t getType() const
Definition Atoms.hpp:67
Definition Coulomb.hpp:26
Definition BerendsenBarostat.cpp:20
KOKKOS_INLINE_FUNCTION constexpr idx_t idx_c(const T &val)
Definition datatypes.hpp:93
Cabana::VerletList< Kokkos::DefaultExecutionSpace::memory_space, Cabana::HalfNeighborTag, Cabana::VerletLayout2D, Cabana::TeamOpTag > HalfVerletList
Definition datatypes.hpp:187
int64_t idx_t
Definition datatypes.hpp:91
double real_t
Definition datatypes.hpp:99
real_t ff2
force factor 2
Definition LennardJones.hpp:30
real_t ef2
energy factor 2
Definition LennardJones.hpp:32
real_t ff1
force factor 1
Definition LennardJones.hpp:29
real_t shift
shifting the potential at rc to zero
Definition LennardJones.hpp:37
real_t ef1
energy factor 1
Definition LennardJones.hpp:31
Definition EnergyAndVirialReducer.hpp:20
real_t virial
Definition EnergyAndVirialReducer.hpp:22
real_t energy
Definition EnergyAndVirialReducer.hpp:21