154 T operator()(
const hrleVectorType<hrleIndexType, D> &indices,
int material) {
155 auto &grid = levelSet->getGrid();
156 double gridDelta = grid.getGridDelta();
158 hrleVectorType<T, 3> coordinate(0., 0., 0.);
159 for (
unsigned i = 0; i <
D; ++i) {
160 coordinate[i] = indices[i] * gridDelta;
164 neighborIterator.goToIndicesSequential(indices);
167 std::array<T, 3> coordArray = {coordinate[0], coordinate[1], coordinate[2]};
172 std::array<T, 3> normalVector = {};
174 for (
unsigned i = 0; i <
D; i++) {
175 hrleVectorType<T, 3> neighborIndex(
T(0));
176 neighborIndex[i] = 1;
178 T pos = neighborIterator.getNeighbor(neighborIndex).getValue() -
179 neighborIterator.getCenter().getValue();
180 T neg = neighborIterator.getCenter().getValue() -
181 neighborIterator.getNeighbor(-neighborIndex).getValue();
182 normalVector[i] = (pos + neg) * 0.5;
184 denominator += normalVector[i] * normalVector[i];
186 denominator = std::sqrt(denominator);
188 for (
unsigned i = 0; i <
D; ++i) {
189 normalVector[i] /= denominator;
192 double scalarVelocity = velocities->getScalarVelocity(
193 coordArray, material, normalVector,
194 neighborIterator.getCenter().getPointId());
195 std::array<T, 3> vectorVelocity = velocities->getVectorVelocity(
196 coordArray, material, normalVector,
197 neighborIterator.getCenter().getPointId());
200 for (
unsigned i = 0; i <
D; ++i) {
201 scalarVelocity += vectorVelocity[i] * normalVector[i];
204 if (scalarVelocity ==
T(0)) {
209 NormL2(calculateGradient(hrleVectorType<hrleIndexType, D>(0))) *
216 std::vector<hrleVectorType<T, D>> alphas;
217 alphas.reserve(numStencilPoints);
219 hrleVectorType<hrleIndexType, D> currentIndex(-order);
220 for (
size_t i = 0; i < numStencilPoints; ++i) {
221 hrleVectorType<T, D> alpha;
222 hrleVectorType<T, 3> normal(calculateNormal(currentIndex));
227 if ((std::abs(normal[0]) < 1e-6) && (std::abs(normal[1]) < 1e-6) &&
228 (std::abs(normal[2]) < 1e-6)) {
229 alphas.push_back(hrleVectorType<T, D>(
T(0)));
233 std::array<T, 3> normal_p = {normal[0], normal[1], normal[2]};
234 std::array<T, 3> normal_n = {normal[0], normal[1], normal[2]};
236 hrleVectorType<T, D> velocityDelta(
T(0));
239 std::array<T, 3> localCoordArray = coordArray;
240 for (
unsigned dir = 0; dir <
D; ++dir)
241 localCoordArray[dir] += currentIndex[dir];
243 T localScalarVelocity = velocities->getScalarVelocity(
244 localCoordArray, material, normal_p,
245 neighborIterator.getCenter().getPointId());
246 std::array<T, 3> localVectorVelocity = velocities->getVectorVelocity(
247 localCoordArray, material, normal_p,
248 neighborIterator.getCenter().getPointId());
250 for (
unsigned i = 0; i <
D; ++i) {
251 localScalarVelocity += localVectorVelocity[i] * normal[i];
254 const T DN = std::abs(normalEpsilon * scalarVelocity);
256 for (
int k = 0; k <
D; ++k) {
261 T vp = velocities->getScalarVelocity(
262 localCoordArray, material, normal_p,
263 neighborIterator.getCenter().getPointId());
264 T vn = velocities->getScalarVelocity(
265 localCoordArray, material, normal_n,
266 neighborIterator.getCenter().getPointId());
268 velocityDelta[k] = (vn - vp) / (2.0 * DN);
275 for (
int k = 0; k <
D; ++k) {
282 hrleVectorType<T, D> gradient = calculateGradient(currentIndex);
284 for (
int j = 0; j <
D - 1; ++j) {
285 int idx = (k + 1 + j) %
D;
286 monti += gradient[idx] * gradient[idx];
287 toifl += gradient[idx] * velocityDelta[idx];
290 T denominator = Norm2(gradient);
291 monti *= velocityDelta[k] / denominator;
292 toifl *= -gradient[k] / denominator;
295 T osher = localScalarVelocity * normal[k];
297 alpha[k] = std::fabs(monti + toifl + osher);
300 alphas.push_back(alpha);
305 for (; dim <
D - 1; ++dim) {
306 if (currentIndex[dim] < order)
308 currentIndex[dim] = -order;
315 hrleVectorType<T, D> gradientDiff = calculateGradientDiff();
316 for (
int d = 0; d <
D; ++d) {
319 for (
size_t i = 0; i < numStencilPoints; ++i) {
320 maxAlpha = std::max(maxAlpha, alphas[i][d]);
323 finalAlphas[d] = maxAlpha;
324 dissipation += maxAlpha * gradientDiff[d];
327 return hamiltonian - dissipation;