42 std::pair<T, T>
operator()(
const viennahrle::Index<D> &indices,
45 Vec3D<T> coordinate{0., 0., 0.};
46 for (
unsigned i = 0; i <
D; ++i) {
47 coordinate[i] = indices[i] * gridDelta;
51 neighborIterator.goToIndicesSequential(indices);
59 Vec3D<T> normalVector;
62 for (
int i = 0; i <
D; i++) {
64 const T deltaPos = gridDelta;
65 const T deltaNeg = -gridDelta;
67 const T phi0 = neighborIterator.getCenter().getValue();
68 const T phiPos = neighborIterator.getNeighbor(i).getValue();
69 const T phiNeg = neighborIterator.getNeighbor(i +
D).getValue();
71 T diffPos = (phiPos - phi0) / deltaPos;
72 T diffNeg = (phiNeg - phi0) / deltaNeg;
74 if constexpr (order == 2) {
76 const T deltaPosPos = 2 * gridDelta;
77 const T deltaNegNeg = -2 * gridDelta;
80 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
82 (deltaPos * deltaNeg);
84 neighborIterator.getNeighbor((
D * order) + i).getValue();
86 neighborIterator.getNeighbor((
D * order) +
D + i).getValue();
88 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
89 (deltaNegNeg - deltaNeg) +
91 (deltaNegNeg * deltaNeg);
92 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
93 (deltaPosPos - deltaPos) +
95 (deltaPosPos * deltaPos);
97 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
98 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
99 diffPos -= deltaPos * diffPosPos;
101 diffPos += deltaNeg * diff00;
105 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
106 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
107 diffNeg -= deltaNeg * diffNegNeg;
109 diffNeg += deltaPos * diff00;
114 gradPos[i] = diffNeg;
115 gradNeg[i] = diffPos;
117 normalVector[i] = (diffNeg + diffPos) * 0.5;
118 normalModulus += normalVector[i] * normalVector[i];
120 grad += pow2((diffNeg + diffPos) * 0.5);
124 normalModulus = 1. / std::sqrt(normalModulus);
125 for (
unsigned i = 0; i <
D; ++i) {
126 normalVector[i] *= normalModulus;
130 T scalarVelocity = velocities->getScalarVelocity(
131 coordinate, material, normalVector,
132 neighborIterator.getCenter().getPointId());
133 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
134 coordinate, material, normalVector,
135 neighborIterator.getCenter().getPointId());
139 if (scalarVelocity != 0.) {
140 totalGrad = scalarVelocity * std::sqrt(grad);
143 for (
int w = 0; w <
D; w++) {
144 if (vectorVelocity[w] > 0.) {
145 totalGrad += vectorVelocity[w] * gradPos[w];
147 totalGrad += vectorVelocity[w] * gradNeg[w];
151 if (totalGrad ==
T(0)) {
157 for (
unsigned i = 0; i <
D; ++i) {
159 std::abs((scalarVelocity + vectorVelocity[i]) * normalVector[i]);
160 finalAlphas[i] = std::max(finalAlphas[i], alpha);
161 dissipation += alphaFactor * alpha * (gradNeg[i] - gradPos[i]) * 0.5;
164 return {totalGrad, dissipation};