66 std::pair<T, T>
operator()(
const viennahrle::Index<D> &indices,
69 auto &grid = levelSet->getGrid();
70 double gridDelta = grid.getGridDelta();
72 VectorType<T, 3> coordinate{0., 0., 0.};
73 for (
unsigned i = 0; i <
D; ++i) {
74 coordinate[i] = indices[i] * gridDelta;
78 neighborIterator.goToIndicesSequential(indices);
86 Vec3D<T> normalVector{};
89 for (
int i = 0; i <
D; i++) {
90 viennahrle::Index<D> posUnit(0);
91 viennahrle::Index<D> negUnit(0);
95 const T deltaPos = gridDelta;
96 const T deltaNeg = -gridDelta;
98 const T phi0 = neighborIterator.getCenter().getValue();
99 const T phiPos = neighborIterator.getNeighbor(posUnit).getValue();
100 const T phiNeg = neighborIterator.getNeighbor(negUnit).getValue();
102 T diffPos = (phiPos - phi0) / deltaPos;
103 T diffNeg = (phiNeg - phi0) / deltaNeg;
105 if constexpr (order == 2) {
110 const T deltaPosPos = 2 * gridDelta;
111 const T deltaNegNeg = -2 * gridDelta;
114 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
116 (deltaPos * deltaNeg);
117 const T phiPosPos = neighborIterator.getNeighbor(posUnit).getValue();
118 const T phiNegNeg = neighborIterator.getNeighbor(negUnit).getValue();
120 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
121 (deltaNegNeg - deltaNeg) +
123 (deltaNegNeg * deltaNeg);
124 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
125 (deltaPosPos - deltaPos) +
127 (deltaPosPos * deltaPos);
129 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
130 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
131 diffPos -= deltaPos * diffPosPos;
133 diffPos += deltaNeg * diff00;
137 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
138 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
139 diffNeg -= deltaNeg * diffNegNeg;
141 diffNeg += deltaPos * diff00;
146 gradPos[i] = diffNeg;
147 gradNeg[i] = diffPos;
149 normalVector[i] = (diffNeg + diffPos) * 0.5;
150 normalModulus += normalVector[i] * normalVector[i];
152 grad += pow2((diffNeg + diffPos) * 0.5);
156 normalModulus = 1. / std::sqrt(normalModulus);
157 for (
unsigned i = 0; i <
D; ++i) {
158 normalVector[i] *= normalModulus;
162 T scalarVelocity = velocities->getScalarVelocity(
163 coordinate, material, normalVector,
164 neighborIterator.getCenter().getPointId());
165 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
166 coordinate, material, normalVector,
167 neighborIterator.getCenter().getPointId());
171 if (scalarVelocity != 0.) {
172 totalGrad = scalarVelocity * std::sqrt(grad);
175 for (
int w = 0; w <
D; w++) {
176 if (vectorVelocity[w] > 0.) {
177 totalGrad += vectorVelocity[w] * gradPos[w];
179 totalGrad += vectorVelocity[w] * gradNeg[w];
183 if (totalGrad ==
T(0)) {
191 constexpr viennahrle::IndexType minIndex = -1;
192 constexpr viennahrle::IndexType maxIndex = 1;
193 constexpr int numNeighbors = hrleUtil::pow(maxIndex - minIndex + 1,
D);
195 viennahrle::Index<D> neighborIndex(minIndex);
196 for (
unsigned i = 0; i < numNeighbors; ++i) {
199 auto center = neighborIterator.getNeighbor(neighborIndex).getValue();
200 for (
unsigned dir = 0; dir <
D; ++dir) {
201 viennahrle::Index<D> unity(0);
204 neighborIterator.getNeighbor(neighborIndex - unity).getValue();
206 neighborIterator.getNeighbor(neighborIndex + unity).getValue();
207 normal[dir] = calculateNormalComponent(neg, center, pos, gridDelta);
210 for (
unsigned dir = 0; dir <
D; ++dir) {
211 T tempAlpha = velocities->getDissipationAlpha(dir, material, normal);
212 alpha[dir] = std::max(alpha[dir], tempAlpha);
213 finalAlphas[dir] = std::max(finalAlphas[dir], tempAlpha);
217 incrementIndices(neighborIndex, minIndex, maxIndex);
223 for (
unsigned i = 0; i <
D; ++i) {
224 dissipation += alpha[i] * (gradNeg[i] - gradPos[i]) * 0.5;
227 return {totalGrad, dissipation};