ViennaLS
Loading...
Searching...
No Matches
lsEngquistOsher.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 EngquistOsher {
19 SmartPointer<viennals::Domain<T, D>> levelSet;
20 SmartPointer<viennals::VelocityField<T>> velocities;
21 viennahrle::SparseStarIterator<viennahrle::Domain<T, D>, order>
22 neighborIterator;
23 bool calculateNormalVectors = true;
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 EngquistOsher(SmartPointer<viennals::Domain<T, D>> passedlsDomain,
34 SmartPointer<viennals::VelocityField<T>> vel,
35 bool calcNormal = true)
36 : levelSet(passedlsDomain), velocities(vel),
37 neighborIterator(
38 viennahrle::SparseStarIterator<viennahrle::Domain<T, D>, order>(
39 levelSet->getDomain())),
40 calculateNormalVectors(calcNormal) {}
41
42 std::pair<T, T> operator()(const viennahrle::Index<D> &indices,
43 int material) {
44 auto &grid = levelSet->getGrid();
45 double gridDelta = grid.getGridDelta();
46
47 VectorType<T, 3> coordinate{0., 0., 0.};
48 for (unsigned i = 0; i < D; ++i) {
49 coordinate[i] = indices[i] * gridDelta;
50 }
51
52 // move neighborIterator to current position
53 neighborIterator.goToIndicesSequential(indices);
54
55 T gradPos[D];
56 T gradNeg[D];
57
58 T gradPosTotal = 0;
59 T gradNegTotal = 0;
60
61 for (int i = 0; i < D; i++) {
62 const T deltaPos = gridDelta;
63 const T deltaNeg = -gridDelta;
64
65 const T phi0 = neighborIterator.getCenter().getValue();
66 const T phiPos = neighborIterator.getNeighbor(i).getValue();
67 const T phiNeg = neighborIterator.getNeighbor(i + D).getValue();
68
69 T diffPos = (phiPos - phi0) / deltaPos;
70 T diffNeg = (phiNeg - phi0) / deltaNeg;
71
72 if (order == 2) { // if second order time integration scheme is used
73 const T deltaPosPos = 2 * gridDelta;
74 const T deltaNegNeg = -2 * gridDelta;
75
76 const T phiPosPos =
77 neighborIterator.getNeighbor((D * order) + i).getValue();
78 const T phiNegNeg =
79 neighborIterator.getNeighbor((D * order) + D + i).getValue();
80
81 const T diff00 =
82 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
83 phi0)) /
84 (deltaPos * deltaNeg);
85 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
86 (deltaNegNeg - deltaNeg) +
87 phi0)) /
88 (deltaNegNeg * deltaNeg);
89 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
90 (deltaPosPos - deltaPos) +
91 phi0)) /
92 (deltaPosPos * deltaPos);
93
94 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
95 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
96 diffPos -= deltaPos * diffPosPos;
97 } else {
98 diffPos += deltaNeg * diff00;
99 }
100 }
101
102 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
103 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
104 diffNeg -= deltaNeg * diffNegNeg;
105 } else {
106 diffNeg += deltaPos * diff00;
107 }
108 }
109 }
110
111 gradPos[i] = diffNeg;
112 gradNeg[i] = diffPos;
113
114 gradPosTotal +=
115 pow2(std::max(diffNeg, T(0))) + pow2(std::min(diffPos, T(0)));
116 gradNegTotal +=
117 pow2(std::min(diffNeg, T(0))) + pow2(std::max(diffPos, T(0)));
118 }
119
120 T vel_grad = 0.;
121
122 // Calculate normal vector for velocity calculation
123 // use std::array since it will be exposed to interface
124 Vec3D<T> normalVector = {};
125 if (calculateNormalVectors) {
126 T denominator = 0;
127 for (int i = 0; i < D; i++) {
128 T pos = neighborIterator.getNeighbor(i).getValue() -
129 neighborIterator.getCenter().getValue();
130 T neg = neighborIterator.getCenter().getValue() -
131 neighborIterator.getNeighbor(i + D).getValue();
132 normalVector[i] = (pos + neg) * 0.5; // = 0;
133 denominator += normalVector[i] * normalVector[i];
134 }
135 denominator = std::sqrt(denominator);
136 for (unsigned i = 0; i < D; ++i) {
137 normalVector[i] /= denominator;
138 }
139 }
140
141 double scalarVelocity = velocities->getScalarVelocity(
142 coordinate, material, normalVector,
143 neighborIterator.getCenter().getPointId());
144 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
145 coordinate, material, normalVector,
146 neighborIterator.getCenter().getPointId());
147
148 if (scalarVelocity > 0) {
149 vel_grad += std::sqrt(gradPosTotal) * scalarVelocity;
150 } else {
151 vel_grad += std::sqrt(gradNegTotal) * scalarVelocity;
152 }
153
154 for (int w = 0; w < D; w++) {
155 if (vectorVelocity[w] > 0.) {
156 vel_grad += vectorVelocity[w] * gradPos[w];
157 } else {
158 vel_grad += vectorVelocity[w] * gradNeg[w];
159 }
160 }
161
162 return {vel_grad, 0.};
163 }
164
165 void reduceTimeStepHamiltonJacobi(double &MaxTimeStep,
166 double gridDelta) const {}
167};
168
169} // namespace lsInternal
void reduceTimeStepHamiltonJacobi(double &MaxTimeStep, double gridDelta) const
Definition lsEngquistOsher.hpp:165
std::pair< T, T > operator()(const viennahrle::Index< D > &indices, int material)
Definition lsEngquistOsher.hpp:42
EngquistOsher(SmartPointer< viennals::Domain< T, D > > passedlsDomain, SmartPointer< viennals::VelocityField< T > > vel, bool calcNormal=true)
Definition lsEngquistOsher.hpp:33
static void prepareLS(SmartPointer< viennals::Domain< T, D > > passedlsDomain)
Definition lsEngquistOsher.hpp:28
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 lsCurvatureFormulas.hpp:9
constexpr int D
Definition pyWrap.cpp:70
double T
Definition pyWrap.cpp:68