ViennaLS
Loading...
Searching...
No Matches
lsLocalLocalLaxFriedrichs.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <hrleSparseStarIterator.hpp>
4#include <hrleVectorType.hpp>
5
6#include <lsDomain.hpp>
7#include <lsExpand.hpp>
8#include <lsVelocityField.hpp>
9
10#include <vcVectorUtil.hpp>
11
12namespace lsInternal {
13
14using namespace viennacore;
15
19template <class T, int D, int order> class LocalLocalLaxFriedrichs {
20 SmartPointer<viennals::Domain<T, D>> levelSet;
21 SmartPointer<viennals::VelocityField<T>> velocities;
22 hrleSparseStarIterator<hrleDomain<T, D>, order> neighborIterator;
23 const double alphaFactor;
24
25 static T pow2(const T &value) { return value * value; }
26
27public:
28 static void prepareLS(SmartPointer<viennals::Domain<T, D>> passedlsDomain) {
29 assert(order == 1 || order == 2);
30 viennals::Expand<T, D>(passedlsDomain, 2 * order + 1).apply();
31 }
32
33 LocalLocalLaxFriedrichs(SmartPointer<viennals::Domain<T, D>> passedlsDomain,
34 SmartPointer<viennals::VelocityField<T>> vel,
35 double a = 1.0)
36 : levelSet(passedlsDomain), velocities(vel),
37 neighborIterator(hrleSparseStarIterator<hrleDomain<T, D>, order>(
38 levelSet->getDomain())),
39 alphaFactor(a) {}
40
41 T operator()(const hrleVectorType<hrleIndexType, D> &indices, int material) {
42
43 auto &grid = levelSet->getGrid();
44 double gridDelta = grid.getGridDelta();
45
46 hrleVectorType<T, 3> coordinate(0., 0., 0.);
47 for (unsigned i = 0; i < D; ++i) {
48 coordinate[i] = indices[i] * gridDelta;
49 }
50
51 // move neighborIterator to current position
52 neighborIterator.goToIndicesSequential(indices);
53
54 // convert coordinate to std array for interface
55 Vec3D<T> coordArray = {coordinate[0], coordinate[1], coordinate[2]};
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 (order == 2) { // if second order time integration scheme is used
79 const T deltaPosPos = 2 * gridDelta;
80 const T deltaNegNeg = -2 * gridDelta;
81
82 const T diff00 =
83 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
84 phi0)) /
85 (deltaPos * deltaNeg);
86 const T phiPosPos =
87 neighborIterator.getNeighbor((D * order) + i).getValue();
88 const T phiNegNeg =
89 neighborIterator.getNeighbor((D * order) + D + i).getValue();
90
91 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
92 (deltaNegNeg - deltaNeg) +
93 phi0)) /
94 (deltaNegNeg * deltaNeg);
95 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
96 (deltaPosPos - deltaPos) +
97 phi0)) /
98 (deltaPosPos * deltaPos);
99
100 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
101 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
102 diffPos -= deltaPos * diffPosPos;
103 } else {
104 diffPos += deltaNeg * diff00;
105 }
106 }
107
108 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
109 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
110 diffNeg -= deltaNeg * diffNegNeg;
111 } else {
112 diffNeg += deltaPos * diff00;
113 }
114 }
115 }
116
117 gradPos[i] = diffNeg;
118 gradNeg[i] = diffPos;
119
120 normalVector[i] = (diffNeg + diffPos) * 0.5;
121 normalModulus += normalVector[i] * normalVector[i];
122
123 grad += pow2((diffNeg + diffPos) * 0.5);
124 }
125
126 // normalise normal vector
127 normalModulus = std::sqrt(normalModulus);
128 for (unsigned i = 0; i < D; ++i) {
129 normalVector[i] /= normalModulus;
130 }
131
132 // Get velocities
133 double scalarVelocity = velocities->getScalarVelocity(
134 coordArray, material, normalVector,
135 neighborIterator.getCenter().getPointId());
136 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
137 coordArray, material, normalVector,
138 neighborIterator.getCenter().getPointId());
139
140 // calculate hamiltonian
141 T totalGrad = 0.;
142 if (scalarVelocity != 0.) {
143 totalGrad = scalarVelocity * std::sqrt(grad);
144 }
145
146 for (int w = 0; w < D; w++) {
147 if (vectorVelocity[w] > 0.) {
148 totalGrad += vectorVelocity[w] * gradPos[w];
149 } else {
150 totalGrad += vectorVelocity[w] * gradNeg[w];
151 }
152 }
153
154 // calculate local dissipation alphas for each direction
155 // and add to dissipation term
156 for (unsigned i = 0; i < D; ++i) {
157 T alpha =
158 std::abs((scalarVelocity + vectorVelocity[i]) * normalVector[i]);
159 dissipation += alphaFactor * alpha * (gradNeg[i] - gradPos[i]) * 0.5;
160 }
161
162 return totalGrad - ((totalGrad != 0.) ? dissipation : 0);
163 }
164};
165} // namespace lsInternal
Lax Friedrichs integration scheme, which considers only the current point for alpha calculation....
Definition lsLocalLocalLaxFriedrichs.hpp:19
T operator()(const hrleVectorType< hrleIndexType, D > &indices, int material)
Definition lsLocalLocalLaxFriedrichs.hpp:41
static void prepareLS(SmartPointer< viennals::Domain< T, D > > passedlsDomain)
Definition lsLocalLocalLaxFriedrichs.hpp:28
LocalLocalLaxFriedrichs(SmartPointer< viennals::Domain< T, D > > passedlsDomain, SmartPointer< viennals::VelocityField< T > > vel, double a=1.0)
Definition lsLocalLocalLaxFriedrichs.hpp:33
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
Expands the leveleSet to the specified number of layers. The largest value in the levelset is thus wi...
Definition lsExpand.hpp:16
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:13
Definition lsAdvect.hpp:37
constexpr int D
Definition pyWrap.cpp:65
double T
Definition pyWrap.cpp:63