ViennaLS
Loading...
Searching...
No Matches
lsLocalLocalLaxFriedrichs.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <hrleSparseStarIterator.hpp>
4
5#include <lsDomain.hpp>
6#include <lsExpand.hpp>
7#include <lsVelocityField.hpp>
8
9#include <vcVectorType.hpp>
10
11namespace lsInternal {
12
13using namespace viennacore;
14
18template <class T, int D, int order> class LocalLocalLaxFriedrichs {
19 SmartPointer<viennals::Domain<T, D>> levelSet;
20 SmartPointer<viennals::VelocityField<T>> velocities;
21 viennahrle::ConstSparseStarIterator<viennahrle::Domain<T, D>, order>
22 neighborIterator;
23 const double alphaFactor;
24 const double gridDelta;
25 VectorType<T, D> finalAlphas{};
26
27 static T pow2(const T &value) { return value * value; }
28
29public:
30 static void prepareLS(SmartPointer<viennals::Domain<T, D>> passedlsDomain) {
31 assert(order == 1 || order == 2);
32 viennals::Expand<T, D>(passedlsDomain, 2 * order + 1).apply();
33 }
34
35 LocalLocalLaxFriedrichs(SmartPointer<viennals::Domain<T, D>> passedlsDomain,
36 SmartPointer<viennals::VelocityField<T>> vel,
37 double a = 1.0)
38 : levelSet(passedlsDomain), velocities(vel),
39 neighborIterator(levelSet->getDomain()), alphaFactor(a),
40 gridDelta(levelSet->getGrid().getGridDelta()) {}
41
42 std::pair<T, T> operator()(const viennahrle::Index<D> &indices,
43 int material) {
44
45 Vec3D<T> coordinate{0., 0., 0.};
46 for (unsigned i = 0; i < D; ++i) {
47 coordinate[i] = indices[i] * gridDelta;
48 }
49
50 // move neighborIterator to current position
51 neighborIterator.goToIndicesSequential(indices);
52
53 T gradPos[D];
54 T gradNeg[D];
55
56 T grad = 0.;
57 T dissipation = 0.;
58
59 Vec3D<T> normalVector;
60 T normalModulus = 0;
61
62 for (int i = 0; i < D; i++) { // iterate over dimensions
63
64 const T deltaPos = gridDelta;
65 const T deltaNeg = -gridDelta;
66
67 const T phi0 = neighborIterator.getCenter().getValue();
68 const T phiPos = neighborIterator.getNeighbor(i).getValue();
69 const T phiNeg = neighborIterator.getNeighbor(i + D).getValue();
70
71 T diffPos = (phiPos - phi0) / deltaPos;
72 T diffNeg = (phiNeg - phi0) / deltaNeg;
73
74 if constexpr (order == 2) { // if second order spatial discretization
75 // scheme is used
76 const T deltaPosPos = 2 * gridDelta;
77 const T deltaNegNeg = -2 * gridDelta;
78
79 const T diff00 =
80 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
81 phi0)) /
82 (deltaPos * deltaNeg);
83 const T phiPosPos =
84 neighborIterator.getNeighbor((D * order) + i).getValue();
85 const T phiNegNeg =
86 neighborIterator.getNeighbor((D * order) + D + i).getValue();
87
88 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
89 (deltaNegNeg - deltaNeg) +
90 phi0)) /
91 (deltaNegNeg * deltaNeg);
92 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
93 (deltaPosPos - deltaPos) +
94 phi0)) /
95 (deltaPosPos * deltaPos);
96
97 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
98 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
99 diffPos -= deltaPos * diffPosPos;
100 } else {
101 diffPos += deltaNeg * diff00;
102 }
103 }
104
105 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
106 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
107 diffNeg -= deltaNeg * diffNegNeg;
108 } else {
109 diffNeg += deltaPos * diff00;
110 }
111 }
112 }
113
114 gradPos[i] = diffNeg;
115 gradNeg[i] = diffPos;
116
117 normalVector[i] = (diffNeg + diffPos) * 0.5;
118 normalModulus += normalVector[i] * normalVector[i];
119
120 grad += pow2((diffNeg + diffPos) * 0.5);
121 }
122
123 // normalize normal vector
124 normalModulus = 1. / std::sqrt(normalModulus);
125 for (unsigned i = 0; i < D; ++i) {
126 normalVector[i] *= normalModulus;
127 }
128
129 // Get velocities
130 T scalarVelocity = velocities->getScalarVelocity(
131 coordinate, material, normalVector,
132 neighborIterator.getCenter().getPointId());
133 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
134 coordinate, material, normalVector,
135 neighborIterator.getCenter().getPointId());
136
137 // calculate hamiltonian
138 T totalGrad = 0.;
139 if (scalarVelocity != 0.) {
140 totalGrad = scalarVelocity * std::sqrt(grad);
141 }
142
143 for (int w = 0; w < D; w++) {
144 if (vectorVelocity[w] > 0.) {
145 totalGrad += vectorVelocity[w] * gradPos[w];
146 } else {
147 totalGrad += vectorVelocity[w] * gradNeg[w];
148 }
149 }
150
151 if (totalGrad == T(0)) {
152 return {0, 0};
153 }
154
155 // calculate local dissipation alphas for each direction
156 // and add to dissipation term
157 for (unsigned i = 0; i < D; ++i) {
158 T alpha =
159 std::abs((scalarVelocity + vectorVelocity[i]) * normalVector[i]);
160 finalAlphas[i] = std::max(finalAlphas[i], alpha);
161 dissipation += alphaFactor * alpha * (gradNeg[i] - gradPos[i]) * 0.5;
162 }
163
164 return {totalGrad, dissipation};
165 }
166
167 void reduceTimeStepHamiltonJacobi(double &MaxTimeStep, double gridDelta) {
168 constexpr double alpha_maxCFL = 1.0;
169 // second time step test, based on alphas
170
171 double timeStep = 0;
172 for (int i = 0; i < D; ++i) {
173 timeStep += finalAlphas[i] / gridDelta;
174 }
175
176 timeStep = alpha_maxCFL / timeStep;
177 MaxTimeStep = std::min(timeStep, MaxTimeStep);
178 }
179};
180} // namespace lsInternal
constexpr int D
Definition Epitaxy.cpp:12
double T
Definition Epitaxy.cpp:13
void reduceTimeStepHamiltonJacobi(double &MaxTimeStep, double gridDelta)
Definition lsLocalLocalLaxFriedrichs.hpp:167
std::pair< T, T > operator()(const viennahrle::Index< D > &indices, int material)
Definition lsLocalLocalLaxFriedrichs.hpp:42
static void prepareLS(SmartPointer< viennals::Domain< T, D > > passedlsDomain)
Definition lsLocalLocalLaxFriedrichs.hpp:30
LocalLocalLaxFriedrichs(SmartPointer< viennals::Domain< T, D > > passedlsDomain, SmartPointer< viennals::VelocityField< T > > vel, double a=1.0)
Definition lsLocalLocalLaxFriedrichs.hpp:35
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:27
Expands the levelSet to the specified number of layers. The largest value in the levelset is thus wid...
Definition lsExpand.hpp:17
void apply()
Apply the expansion to the specified width.
Definition lsExpand.hpp:44
Abstract class defining the interface for the velocity field used during advection using lsAdvect.
Definition lsVelocityField.hpp:11
Definition lsAdvectIntegrationSchemes.hpp:41