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