226 std::pair<T, T>
operator()(
const viennahrle::Index<D> &indices,
228 auto &grid = levelSet->getGrid();
229 double gridDelta = grid.getGridDelta();
231 Vec3D<T> coordinate{};
232 for (
unsigned i = 0; i <
D; ++i) {
233 coordinate[i] = indices[i] * gridDelta;
237 neighborIterator.goToIndicesSequential(indices);
242 Vec3D<T> normalVector{};
244 for (
unsigned i = 0; i <
D; i++) {
245 viennahrle::Index<D> neighborIndex(0);
246 neighborIndex[i] = 1;
248 T pos = neighborIterator.getNeighbor(neighborIndex).getValue() -
249 neighborIterator.getCenter().getValue();
250 T neg = neighborIterator.getCenter().getValue() -
251 neighborIterator.getNeighbor(-neighborIndex).getValue();
252 normalVector[i] = (pos + neg) * 0.5;
254 denominator += normalVector[i] * normalVector[i];
256 denominator = 1 / std::sqrt(denominator);
257 for (
unsigned i = 0; i <
D; ++i) {
258 normalVector[i] *= denominator;
261 double scalarVelocity = velocities->getScalarVelocity(
262 coordinate, material, normalVector,
263 neighborIterator.getCenter().getPointId());
264 auto vectorVelocity = velocities->getVectorVelocity(
265 coordinate, material, normalVector,
266 neighborIterator.getCenter().getPointId());
269 for (
unsigned i = 0; i <
D; ++i) {
270 scalarVelocity += vectorVelocity[i] * normalVector[i];
273 if (scalarVelocity ==
T(0)) {
278 Norm(calculateGradient(viennahrle::Index<D>(0))) * scalarVelocity;
284 std::array<VectorType<T, D>, numStencilPoints> alphas{};
286 viennahrle::Index<D> currentIndex(-order);
287 for (
size_t i = 0; i < numStencilPoints; ++i) {
288 VectorType<T, D> alpha;
289 Vec3D<T> normal = calculateNormal(currentIndex);
292 if ((std::abs(normal[0]) < 1e-6) && (std::abs(normal[1]) < 1e-6) &&
293 (std::abs(normal[2]) < 1e-6)) {
298 Vec3D<T> normal_p{normal[0], normal[1], normal[2]};
299 Vec3D<T> normal_n{normal[0], normal[1], normal[2]};
301 VectorType<T, D> velocityDelta;
302 velocityDelta.fill(0.);
305 Vec3D<T> localCoordArray = coordinate;
306 for (
unsigned dir = 0; dir <
D; ++dir)
307 localCoordArray[dir] += currentIndex[dir];
309 T localScalarVelocity = velocities->getScalarVelocity(
310 localCoordArray, material, normal_p,
311 neighborIterator.getCenter().getPointId());
312 Vec3D<T> localVectorVelocity = velocities->getVectorVelocity(
313 localCoordArray, material, normal_p,
314 neighborIterator.getCenter().getPointId());
316 for (
unsigned dir = 0; dir <
D; ++dir) {
317 localScalarVelocity += localVectorVelocity[dir] * normal[dir];
322#if ADAPTIVE_EPSILON_STRATEGY == 0
324 DN = std::abs(baseNormalEpsilon * scalarVelocity);
325#elif ADAPTIVE_EPSILON_STRATEGY == 1
328 levelSet->getGrid().getGridDelta());
329#elif ADAPTIVE_EPSILON_STRATEGY == 2
331 DN = calculateAdaptiveEpsilon(localScalarVelocity,
332 levelSet->getGrid().getGridDelta(),
333 localCoordArray, material, normal);
336 DN = std::abs(baseNormalEpsilon * scalarVelocity);
339 for (
int k = 0; k <
D; ++k) {
344 T vp = velocities->getScalarVelocity(
345 localCoordArray, material, normal_p,
346 neighborIterator.getCenter().getPointId());
347 T vn = velocities->getScalarVelocity(
348 localCoordArray, material, normal_n,
349 neighborIterator.getCenter().getPointId());
351 velocityDelta[k] = (vn - vp) / (2.0 * DN);
358 for (
int k = 0; k <
D; ++k) {
365 VectorType<T, D> gradient = calculateGradient(currentIndex);
367 for (
int j = 0; j <
D - 1; ++j) {
368 int idx = (k + 1 + j) %
D;
369 monti += gradient[idx] * gradient[idx];
370 toifl += gradient[idx] * velocityDelta[idx];
373 T denom = DotProduct(gradient, gradient);
374 monti *= velocityDelta[k] / denom;
375 toifl *= -gradient[k] / denom;
378 T osher = localScalarVelocity * normal[k];
380 alpha[k] = std::fabs(monti + toifl + osher);
382 if (alpha[k] > maxDissipation) {
383 alpha[k] = maxDissipation;
392 for (; dim <
D - 1; ++dim) {
393 if (currentIndex[dim] < order)
395 currentIndex[dim] = -order;
402 VectorType<T, D> gradientDiff = calculateGradientDiff();
403 for (
int d = 0; d <
D; ++d) {
406 for (
size_t i = 0; i < numStencilPoints; ++i) {
407 maxAlpha = std::max(maxAlpha, alphas[i][d]);
410 finalAlphas[d] = maxAlpha;
411 dissipation += maxAlpha * gradientDiff[d];
414 return {hamiltonian, dissipation};