151 std::pair<T, T>
operator()(
const hrleVectorType<hrleIndexType, D> &indices,
153 auto &grid = levelSet->getGrid();
154 double gridDelta = grid.getGridDelta();
156 hrleVectorType<T, 3> coordinate(0., 0., 0.);
157 for (
unsigned i = 0; i <
D; ++i) {
158 coordinate[i] = indices[i] * gridDelta;
162 neighborIterator.goToIndicesSequential(indices);
165 std::array<T, 3> coordArray = {coordinate[0], coordinate[1], coordinate[2]};
170 std::array<T, 3> normalVector = {};
172 for (
unsigned i = 0; i <
D; i++) {
173 hrleVectorType<T, 3> neighborIndex(
T(0));
174 neighborIndex[i] = 1;
176 T pos = neighborIterator.getNeighbor(neighborIndex).getValue() -
177 neighborIterator.getCenter().getValue();
178 T neg = neighborIterator.getCenter().getValue() -
179 neighborIterator.getNeighbor(-neighborIndex).getValue();
180 normalVector[i] = (pos + neg) * 0.5;
182 denominator += normalVector[i] * normalVector[i];
184 denominator = std::sqrt(denominator);
186 for (
unsigned i = 0; i <
D; ++i) {
187 normalVector[i] /= denominator;
190 double scalarVelocity = velocities->getScalarVelocity(
191 coordArray, material, normalVector,
192 neighborIterator.getCenter().getPointId());
193 std::array<T, 3> vectorVelocity = velocities->getVectorVelocity(
194 coordArray, material, normalVector,
195 neighborIterator.getCenter().getPointId());
198 for (
unsigned i = 0; i <
D; ++i) {
199 scalarVelocity += vectorVelocity[i] * normalVector[i];
202 if (scalarVelocity ==
T(0)) {
207 NormL2(calculateGradient(hrleVectorType<hrleIndexType, D>(0))) *
214 std::vector<hrleVectorType<T, D>> alphas;
215 alphas.reserve(numStencilPoints);
217 hrleVectorType<hrleIndexType, D> currentIndex(-order);
218 for (
size_t i = 0; i < numStencilPoints; ++i) {
219 hrleVectorType<T, D> alpha;
220 hrleVectorType<T, 3> normal(calculateNormal(currentIndex));
225 if ((std::abs(normal[0]) < 1e-6) && (std::abs(normal[1]) < 1e-6) &&
226 (std::abs(normal[2]) < 1e-6)) {
227 alphas.push_back(hrleVectorType<T, D>(
T(0)));
231 std::array<T, 3> normal_p = {normal[0], normal[1], normal[2]};
232 std::array<T, 3> normal_n = {normal[0], normal[1], normal[2]};
234 hrleVectorType<T, D> velocityDelta(
T(0));
237 std::array<T, 3> localCoordArray = coordArray;
238 for (
unsigned dir = 0; dir <
D; ++dir)
239 localCoordArray[dir] += currentIndex[dir];
241 T localScalarVelocity = velocities->getScalarVelocity(
242 localCoordArray, material, normal_p,
243 neighborIterator.getCenter().getPointId());
244 std::array<T, 3> localVectorVelocity = velocities->getVectorVelocity(
245 localCoordArray, material, normal_p,
246 neighborIterator.getCenter().getPointId());
248 for (
unsigned i = 0; i <
D; ++i) {
249 localScalarVelocity += localVectorVelocity[i] * normal[i];
252 const T DN = std::abs(normalEpsilon * scalarVelocity);
254 for (
int k = 0; k <
D; ++k) {
259 T vp = velocities->getScalarVelocity(
260 localCoordArray, material, normal_p,
261 neighborIterator.getCenter().getPointId());
262 T vn = velocities->getScalarVelocity(
263 localCoordArray, material, normal_n,
264 neighborIterator.getCenter().getPointId());
266 velocityDelta[k] = (vn - vp) / (2.0 * DN);
273 for (
int k = 0; k <
D; ++k) {
280 hrleVectorType<T, D> gradient = calculateGradient(currentIndex);
282 for (
int j = 0; j <
D - 1; ++j) {
283 int idx = (k + 1 + j) %
D;
284 monti += gradient[idx] * gradient[idx];
285 toifl += gradient[idx] * velocityDelta[idx];
288 T denominator = Norm2(gradient);
289 monti *= velocityDelta[k] / denominator;
290 toifl *= -gradient[k] / denominator;
293 T osher = localScalarVelocity * normal[k];
295 alpha[k] = std::fabs(monti + toifl + osher);
298 alphas.push_back(alpha);
303 for (; dim <
D - 1; ++dim) {
304 if (currentIndex[dim] < order)
306 currentIndex[dim] = -order;
313 hrleVectorType<T, D> gradientDiff = calculateGradientDiff();
314 for (
int d = 0; d <
D; ++d) {
317 for (
size_t i = 0; i < numStencilPoints; ++i) {
318 maxAlpha = std::max(maxAlpha, alphas[i][d]);
321 finalAlphas[d] = maxAlpha;
322 dissipation += maxAlpha * gradientDiff[d];
325 return {hamiltonian, dissipation};