44 std::pair<T, T>
operator()(
const viennahrle::Index<D> &indices,
47 auto &grid = levelSet->getGrid();
48 double gridDelta = grid.getGridDelta();
50 VectorType<T, 3> coordinate{0., 0., 0.};
51 for (
unsigned i = 0; i <
D; ++i) {
52 coordinate[i] = indices[i] * gridDelta;
56 neighborIterator.goToIndicesSequential(indices);
59 Vec3D<T> coordArray{coordinate[0], coordinate[1], coordinate[2]};
67 Vec3D<T> normalVector = {};
70 for (
int i = 0; i <
D; i++) {
72 const T deltaPos = gridDelta;
73 const T deltaNeg = -gridDelta;
75 const T phi0 = neighborIterator.getCenter().getValue();
76 const T phiPos = neighborIterator.getNeighbor(i).getValue();
77 const T phiNeg = neighborIterator.getNeighbor(i +
D).getValue();
79 T diffPos = (phiPos - phi0) / deltaPos;
80 T diffNeg = (phiNeg - phi0) / deltaNeg;
83 const T deltaPosPos = 2 * gridDelta;
84 const T deltaNegNeg = -2 * gridDelta;
87 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
89 (deltaPos * deltaNeg);
91 neighborIterator.getNeighbor((
D * order) + i).getValue();
93 neighborIterator.getNeighbor((
D * order) +
D + i).getValue();
95 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
96 (deltaNegNeg - deltaNeg) +
98 (deltaNegNeg * deltaNeg);
99 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
100 (deltaPosPos - deltaPos) +
102 (deltaPosPos * deltaPos);
104 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
105 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
106 diffPos -= deltaPos * diffPosPos;
108 diffPos += deltaNeg * diff00;
112 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
113 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
114 diffNeg -= deltaNeg * diffNegNeg;
116 diffNeg += deltaPos * diff00;
121 gradPos[i] = diffNeg;
122 gradNeg[i] = diffPos;
124 normalVector[i] = (diffNeg + diffPos) * 0.5;
125 normalModulus += normalVector[i] * normalVector[i];
127 grad += pow2((diffNeg + diffPos) * 0.5);
131 normalModulus = std::sqrt(normalModulus);
132 for (
unsigned i = 0; i <
D; ++i) {
133 normalVector[i] /= normalModulus;
137 double scalarVelocity = velocities->getScalarVelocity(
138 coordArray, material, normalVector,
139 neighborIterator.getCenter().getPointId());
140 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
141 coordArray, material, normalVector,
142 neighborIterator.getCenter().getPointId());
146 if (scalarVelocity != 0.) {
147 totalGrad = scalarVelocity * std::sqrt(grad);
150 for (
int w = 0; w <
D; w++) {
151 if (vectorVelocity[w] > 0.) {
152 totalGrad += vectorVelocity[w] * gradPos[w];
154 totalGrad += vectorVelocity[w] * gradNeg[w];
160 for (
unsigned i = 0; i <
D; ++i) {
162 std::abs((scalarVelocity + vectorVelocity[i]) * normalVector[i]);
163 finalAlphas[i] = std::max(finalAlphas[i], alpha);
164 dissipation += alphaFactor * alpha * (gradNeg[i] - gradPos[i]) * 0.5;
167 return {totalGrad, ((totalGrad != 0.) ? dissipation : 0)};