MRMD 0.4.0
Multi Resolution Molecular Dynamics
Loading...
Searching...
No Matches
Slab.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 "assert/assert.hpp"
19#include "constants.hpp"
20#include "datatypes.hpp"
21#include "util/math.hpp"
22
23namespace mrmd
24{
25namespace weighting_function
26{
27class Slab
28{
29public:
30 enum class InterfaceType
31 {
32 SMOOTH,
33 ABRUPT
34 };
35
36private:
37 const Point3D center_;
38 const real_t atomisticRegionHalfDiameter_;
39 const real_t hybridRegionDiameter_;
40 const idx_t exponent_;
41 const InterfaceType interfaceType_;
42
43public:
44 KOKKOS_INLINE_FUNCTION
45 bool isInATRegion(const real_t& x, const real_t& /*y*/, const real_t& /*z*/) const
46 {
47 auto dx = x - center_[0];
48 auto absDx = std::abs(dx);
49
50 return (absDx < atomisticRegionHalfDiameter_);
51 }
52 KOKKOS_INLINE_FUNCTION
53 bool isInHYRegion(const real_t& x, const real_t& /*y*/, const real_t& /*z*/) const
54 {
55 auto dx = x - center_[0];
56 auto absDx = std::abs(dx);
57
58 if (absDx < atomisticRegionHalfDiameter_)
59 {
60 return false;
61 }
62 return (absDx < atomisticRegionHalfDiameter_ + hybridRegionDiameter_);
63 }
64 KOKKOS_INLINE_FUNCTION
65 bool isInCGRegion(const real_t& x, const real_t& /*y*/, const real_t& /*z*/) const
66 {
67 auto dx = x - center_[0];
68 auto absDx = std::abs(dx);
69
70 return !(absDx < atomisticRegionHalfDiameter_ + hybridRegionDiameter_);
71 }
72
73 KOKKOS_INLINE_FUNCTION
75 real_t& absDx,
76 real_t& lambda,
77 real_t& modulatedLambda,
78 real_t& gradLambdaX,
79 real_t& gradLambdaY,
80 real_t& gradLambdaZ) const
81 {
82 switch (interfaceType_)
83 {
85 // smooth interface
87 dx, absDx, lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
88 break;
90 // abrupt interface
91 setAbruptWeightInHY(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
92 break;
93 }
94 }
95
96 KOKKOS_INLINE_FUNCTION
98 real_t& absDx,
99 real_t& lambda,
100 real_t& modulatedLambda,
101 real_t& gradLambdaX,
102 real_t& gradLambdaY,
103 real_t& gradLambdaZ) const
104 {
105 const real_t arg =
106 pi / (2_r * hybridRegionDiameter_) * (absDx - atomisticRegionHalfDiameter_);
107 auto base = std::cos(arg);
108 lambda = base * base;
109 MRMD_DEVICE_ASSERT(!std::isnan(lambda), "absDx: " << absDx);
110 modulatedLambda = util::powInt(base, exponent_);
111
112 auto factor = -pi / (2_r * hybridRegionDiameter_) * real_c(exponent_) * std::sin(arg) *
113 util::powInt(base, exponent_ - 1) / absDx;
114 MRMD_DEVICE_ASSERT(!std::isnan(factor));
115 MRMD_DEVICE_ASSERT(!std::isnan(dx));
116
117 gradLambdaX = factor * dx;
118 gradLambdaY = 0_r;
119 gradLambdaZ = 0_r;
120 }
121
122 KOKKOS_INLINE_FUNCTION
124 real_t& modulatedLambda,
125 real_t& gradLambdaX,
126 real_t& gradLambdaY,
127 real_t& gradLambdaZ) const
128 {
129 // abrupt interface sets weight to the same value as in AT region
130 setWeightInAT(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
131 }
132
133 KOKKOS_INLINE_FUNCTION
134 void setWeightInAT(real_t& lambda,
135 real_t& modulatedLambda,
136 real_t& gradLambdaX,
137 real_t& gradLambdaY,
138 real_t& gradLambdaZ) const
139 {
140 lambda = 1_r;
141 modulatedLambda = 1_r;
142 gradLambdaX = 0_r;
143 gradLambdaY = 0_r;
144 gradLambdaZ = 0_r;
145 }
146
147 KOKKOS_INLINE_FUNCTION
148 void setWeightInCG(real_t& lambda,
149 real_t& modulatedLambda,
150 real_t& gradLambdaX,
151 real_t& gradLambdaY,
152 real_t& gradLambdaZ) const
153 {
154 lambda = 0_r;
155 modulatedLambda = 0_r;
156 gradLambdaX = 0_r;
157 gradLambdaY = 0_r;
158 gradLambdaZ = 0_r;
159 }
160
161 KOKKOS_INLINE_FUNCTION
162 void operator()(const real_t x,
163 const real_t /*y*/,
164 const real_t /*z*/,
165 real_t& lambda,
166 real_t& modulatedLambda,
167 real_t& gradLambdaX,
168 real_t& gradLambdaY,
169 real_t& gradLambdaZ) const
170 {
171 real_t dx = x - center_[0];
172 real_t absDx = std::abs(dx);
173
174 if (absDx < atomisticRegionHalfDiameter_)
175 {
176 setWeightInAT(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
177 }
178 else if (absDx > atomisticRegionHalfDiameter_ + hybridRegionDiameter_)
179 {
180 setWeightInCG(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
181 }
182 else
183 {
185 dx, absDx, lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
186 }
187 }
188
189 Slab(const Point3D& center,
190 const real_t atomisticRegionDiameter,
191 const real_t hybridRegionDiameter,
192 const idx_t nu,
193 const InterfaceType interfaceType = InterfaceType::SMOOTH)
194 : center_(center),
195 atomisticRegionHalfDiameter_(0.5_r * atomisticRegionDiameter),
196 hybridRegionDiameter_(hybridRegionDiameter),
197 exponent_(2 * nu),
198 interfaceType_(interfaceType)
199 {
200 }
201};
202} // namespace weighting_function
203} // namespace mrmd
Definition Slab.hpp:28
KOKKOS_INLINE_FUNCTION void setWeightInHY(real_t &dx, real_t &absDx, real_t &lambda, real_t &modulatedLambda, real_t &gradLambdaX, real_t &gradLambdaY, real_t &gradLambdaZ) const
Definition Slab.hpp:74
KOKKOS_INLINE_FUNCTION void setSmoothWeightInHY(real_t &dx, real_t &absDx, real_t &lambda, real_t &modulatedLambda, real_t &gradLambdaX, real_t &gradLambdaY, real_t &gradLambdaZ) const
Definition Slab.hpp:97
KOKKOS_INLINE_FUNCTION void setAbruptWeightInHY(real_t &lambda, real_t &modulatedLambda, real_t &gradLambdaX, real_t &gradLambdaY, real_t &gradLambdaZ) const
Definition Slab.hpp:123
KOKKOS_INLINE_FUNCTION void operator()(const real_t x, const real_t, const real_t, real_t &lambda, real_t &modulatedLambda, real_t &gradLambdaX, real_t &gradLambdaY, real_t &gradLambdaZ) const
Definition Slab.hpp:162
KOKKOS_INLINE_FUNCTION bool isInATRegion(const real_t &x, const real_t &, const real_t &) const
Definition Slab.hpp:45
InterfaceType
Definition Slab.hpp:31
KOKKOS_INLINE_FUNCTION bool isInCGRegion(const real_t &x, const real_t &, const real_t &) const
Definition Slab.hpp:65
Slab(const Point3D &center, const real_t atomisticRegionDiameter, const real_t hybridRegionDiameter, const idx_t nu, const InterfaceType interfaceType=InterfaceType::SMOOTH)
Definition Slab.hpp:189
KOKKOS_INLINE_FUNCTION bool isInHYRegion(const real_t &x, const real_t &, const real_t &) const
Definition Slab.hpp:53
KOKKOS_INLINE_FUNCTION void setWeightInAT(real_t &lambda, real_t &modulatedLambda, real_t &gradLambdaX, real_t &gradLambdaY, real_t &gradLambdaZ) const
Definition Slab.hpp:134
KOKKOS_INLINE_FUNCTION void setWeightInCG(real_t &lambda, real_t &modulatedLambda, real_t &gradLambdaX, real_t &gradLambdaY, real_t &gradLambdaZ) const
Definition Slab.hpp:148
#define MRMD_DEVICE_ASSERT(...)
Definition device.hpp:465
KOKKOS_INLINE_FUNCTION real_t powInt(const real_t &x, const idx_t n)
Definition math.hpp:31
Definition BerendsenBarostat.cpp:18
Kokkos::Array< real_t, 3 > Point3D
Definition datatypes.hpp:100
constexpr auto pi
Definition constants.hpp:26
int64_t idx_t
Definition datatypes.hpp:91
double real_t
Definition datatypes.hpp:99
KOKKOS_INLINE_FUNCTION constexpr real_t real_c(T t)
Definition datatypes.hpp:114