Skip to content

Commit

Permalink
Merge pull request #31 from J-Hizzle/implement-abrupt-hy-cg-interface
Browse files Browse the repository at this point in the history
Implement abrupt hy cg interface
  • Loading branch information
XzzX authored Jan 31, 2025
2 parents 8e72655 + 029ae48 commit d14f428
Showing 1 changed file with 107 additions and 29 deletions.
136 changes: 107 additions & 29 deletions mrmd/weighting_function/Slab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,19 @@ namespace weighting_function
{
class Slab
{
public:
enum class InterfaceType
{
SMOOTH,
ABRUPT
};

private:
const Point3D center_;
const real_t atomisticRegionHalfDiameter_;
const real_t hybridRegionDiameter_;
const idx_t exponent_;
const InterfaceType interfaceType_;

public:
KOKKOS_INLINE_FUNCTION
Expand Down Expand Up @@ -62,37 +70,37 @@ class Slab
}

KOKKOS_INLINE_FUNCTION
void operator()(const real_t x,
const real_t /*y*/,
const real_t /*z*/,
real_t& lambda,
real_t& modulatedLambda,
real_t& gradLambdaX,
real_t& gradLambdaY,
real_t& gradLambdaZ) const
void setWeightInHY(real_t& dx,
real_t& absDx,
real_t& lambda,
real_t& modulatedLambda,
real_t& gradLambdaX,
real_t& gradLambdaY,
real_t& gradLambdaZ) const
{
auto dx = x - center_[0];
auto absDx = std::abs(dx);

if (absDx < atomisticRegionHalfDiameter_)
switch (interfaceType_)
{
lambda = 1_r;
modulatedLambda = 1_r;
gradLambdaX = 0_r;
gradLambdaY = 0_r;
gradLambdaZ = 0_r;
return;
}
if (absDx > atomisticRegionHalfDiameter_ + hybridRegionDiameter_)
{
lambda = 0_r;
modulatedLambda = 0_r;
gradLambdaX = 0_r;
gradLambdaY = 0_r;
gradLambdaZ = 0_r;
return;
case InterfaceType::SMOOTH:
// smooth interface
setSmoothWeightInHY(
dx, absDx, lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
break;
case InterfaceType::ABRUPT:
// abrupt interface
setAbruptWeightInHY(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
break;
}
}

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
{
const real_t arg =
pi / (2_r * hybridRegionDiameter_) * (absDx - atomisticRegionHalfDiameter_);
auto base = std::cos(arg);
Expand All @@ -104,19 +112,89 @@ class Slab
util::powInt(base, exponent_ - 1) / absDx;
MRMD_DEVICE_ASSERT(!std::isnan(factor));
MRMD_DEVICE_ASSERT(!std::isnan(dx));

gradLambdaX = factor * dx;
gradLambdaY = 0_r;
gradLambdaZ = 0_r;
}

KOKKOS_INLINE_FUNCTION
void setAbruptWeightInHY(real_t& lambda,
real_t& modulatedLambda,
real_t& gradLambdaX,
real_t& gradLambdaY,
real_t& gradLambdaZ) const
{
// abrupt interface sets weight to the same value as in AT region
setWeightInAT(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
}

KOKKOS_INLINE_FUNCTION
void setWeightInAT(real_t& lambda,
real_t& modulatedLambda,
real_t& gradLambdaX,
real_t& gradLambdaY,
real_t& gradLambdaZ) const
{
lambda = 1_r;
modulatedLambda = 1_r;
gradLambdaX = 0_r;
gradLambdaY = 0_r;
gradLambdaZ = 0_r;
}

KOKKOS_INLINE_FUNCTION
void setWeightInCG(real_t& lambda,
real_t& modulatedLambda,
real_t& gradLambdaX,
real_t& gradLambdaY,
real_t& gradLambdaZ) const
{
lambda = 0_r;
modulatedLambda = 0_r;
gradLambdaX = 0_r;
gradLambdaY = 0_r;
gradLambdaZ = 0_r;
}

KOKKOS_INLINE_FUNCTION
void operator()(const real_t x,
const real_t /*y*/,
const real_t /*z*/,
real_t& lambda,
real_t& modulatedLambda,
real_t& gradLambdaX,
real_t& gradLambdaY,
real_t& gradLambdaZ) const
{
real_t dx = x - center_[0];
real_t absDx = std::abs(dx);

if (absDx < atomisticRegionHalfDiameter_)
{
setWeightInAT(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
}
else if (absDx > atomisticRegionHalfDiameter_ + hybridRegionDiameter_)
{
setWeightInCG(lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
}
else
{
setWeightInHY(
dx, absDx, lambda, modulatedLambda, gradLambdaX, gradLambdaY, gradLambdaZ);
}
}

Slab(const Point3D& center,
const real_t atomisticRegionDiameter,
const real_t hybridRegionDiameter,
const idx_t nu)
const idx_t nu,
const InterfaceType interfaceType = InterfaceType::SMOOTH)
: center_(center),
atomisticRegionHalfDiameter_(0.5_r * atomisticRegionDiameter),
hybridRegionDiameter_(hybridRegionDiameter),
exponent_(2 * nu)
exponent_(2 * nu),
interfaceType_(interfaceType)
{
}
};
Expand Down

0 comments on commit d14f428

Please sign in to comment.