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