7#include <unordered_map>
51template <
class T,
int D>
53 using IndexType = viennahrle::Index<D>;
54 using ConstSparseIterator =
55 viennahrle::ConstSparseIterator<typename Domain<T, D>::DomainType>;
57 std::unordered_map<std::size_t, Vec3D<T>> velocity_;
62 SmartPointer<OxidationDeformation<T, D>> oxideMechanics_ =
nullptr;
70 : oxideMechanics_(oxideMechanics) {
71 if (oxideMechanics ==
nullptr || maskInterface ==
nullptr)
73 gridDelta_ = maskInterface->getGrid().getGridDelta();
80 std::vector<IndexType> index;
81 std::vector<Vec3D<T>> value;
82 std::vector<uint8_t> known;
83 std::unordered_map<std::size_t, std::size_t> lookup;
84 const T eps = std::numeric_limits<T>::epsilon();
88 for (ConstSparseIterator it(body->getDomain()); !it.isFinished(); ++it) {
91 const auto idx = it.getStartIndices();
92 Vec3D<T> coordinate{};
93 for (
unsigned d = 0; d <
D; ++d)
94 coordinate[d] =
static_cast<T>(idx[d]) * gridDelta_;
95 auto sampled = oxideMechanics->getResolvedVectorVelocity(coordinate);
97 for (
unsigned d = 0; d <
D; ++d)
98 magnitude += sampled[d] * sampled[d];
99 const bool onOxide = magnitude > eps;
101 index.push_back(idx);
102 value.push_back(onOxide ? sampled : Vec3D<T>{
T(0),
T(0),
T(0)});
103 known.push_back(onOxide ? uint8_t(1) : uint8_t(0));
107 for (
bool changed =
true; changed;) {
109 auto nextValue = value;
110 auto nextKnown = known;
111 for (std::size_t i = 0; i < index.size(); ++i) {
114 Vec3D<T> sum{
T(0),
T(0),
T(0)};
116 for (
unsigned d = 0; d <
D; ++d) {
117 for (
int offset = -1; offset <= 1; offset += 2) {
118 auto neighbor = index[i];
119 neighbor[d] += offset;
121 if (found == lookup.end() || !known[found->second])
123 for (
unsigned k = 0; k <
D; ++k)
124 sum[k] += value[found->second][k];
130 for (
unsigned k = 0; k <
D; ++k)
131 nextValue[i][k] = sum[k] /
static_cast<T>(count);
135 value.swap(nextValue);
136 known.swap(nextKnown);
139 for (std::size_t i = 0; i < index.size(); ++i)
144 template <
class... Args>
static auto New(Args &&...args) {
145 return SmartPointer<OxidationMaskCarry>::New(std::forward<Args>(args)...);
149 const Vec3D<T> &normalVector,
150 unsigned long pointId)
final {
158 if (oxideMechanics_ !=
nullptr) {
160 oxideMechanics_->getResolvedVectorVelocity(coordinate);
162 for (
unsigned d = 0; d <
D; ++d)
163 magnitude += onOxide[d] * onOxide[d];
164 if (magnitude > std::numeric_limits<T>::epsilon())
170 for (
unsigned d = 0; d <
D; ++d)
171 index[d] = std::llround(coordinate[d] / gridDelta_);
173 if (found == velocity_.end())
175 return found->second;
179 unsigned long)
final {
constexpr int D
Definition Epitaxy.cpp:12
double T
Definition Epitaxy.cpp:13
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:27
static auto New(Args &&...args)
Definition lsDomain.hpp:111
T getScalarVelocity(const Vec3D< T > &, int, const Vec3D< T > &, unsigned long) final
Should return a scalar value for the velocity at coordinate for a point of material with the given no...
Definition lsOxidationMask.hpp:178
OxidationMaskCarry()=default
OxidationMaskCarry(SmartPointer< OxidationDeformation< T, D > > oxideMechanics, SmartPointer< Domain< T, D > > maskInterface)
Definition lsOxidationMask.hpp:68
static auto New(Args &&...args)
Definition lsOxidationMask.hpp:144
Vec3D< T > getVectorVelocity(const Vec3D< T > &coordinate, int material, const Vec3D< T > &normalVector, unsigned long pointId) final
Like getScalarVelocity, but returns a velocity value for each cartesian direction.
Definition lsOxidationMask.hpp:148
std::size_t gridIndexHash(const viennahrle::Index< D > &index)
Definition lsOxidationSolverBase.hpp:30
Definition lsAdvect.hpp:41
Nitride (Si₃N₄) mask of the LOCOS process. The grid points inside the mask join the oxide mechanics s...
Definition lsOxidationMask.hpp:18
double poissonRatio
Definition lsOxidationMask.hpp:22
double shearActivationVolume
Definition lsOxidationMask.hpp:27
double viscosity
Definition lsOxidationMask.hpp:26
double youngModulus
Definition lsOxidationMask.hpp:21