65 std::pair<T, T>
operator()(
const viennahrle::Index<D> &indices,
68 Vec3D<T> coordinate{0., 0., 0.};
69 for (
unsigned i = 0; i <
D; ++i) {
70 coordinate[i] = indices[i] * gridDelta;
74 neighborIterator.goToIndicesSequential(indices);
82 Vec3D<T> normalVector;
85 for (
int i = 0; i <
D; i++) {
86 viennahrle::Index<D> posUnit(0);
87 viennahrle::Index<D> negUnit(0);
91 const T deltaPos = gridDelta;
92 const T deltaNeg = -gridDelta;
94 const T phi0 = neighborIterator.getCenter().getValue();
95 const T phiPos = neighborIterator.getNeighbor(posUnit).getValue();
96 const T phiNeg = neighborIterator.getNeighbor(negUnit).getValue();
98 T diffPos = (phiPos - phi0) / deltaPos;
99 T diffNeg = (phiNeg - phi0) / deltaNeg;
101 if constexpr (order == 2) {
106 const T deltaPosPos = 2 * gridDelta;
107 const T deltaNegNeg = -2 * gridDelta;
110 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
112 (deltaPos * deltaNeg);
113 const T phiPosPos = neighborIterator.getNeighbor(posUnit).getValue();
114 const T phiNegNeg = neighborIterator.getNeighbor(negUnit).getValue();
116 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
117 (deltaNegNeg - deltaNeg) +
119 (deltaNegNeg * deltaNeg);
120 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
121 (deltaPosPos - deltaPos) +
123 (deltaPosPos * deltaPos);
125 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
126 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
127 diffPos -= deltaPos * diffPosPos;
129 diffPos += deltaNeg * diff00;
133 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
134 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
135 diffNeg -= deltaNeg * diffNegNeg;
137 diffNeg += deltaPos * diff00;
142 gradPos[i] = diffNeg;
143 gradNeg[i] = diffPos;
145 normalVector[i] = (diffNeg + diffPos) * 0.5;
146 normalModulus += normalVector[i] * normalVector[i];
148 grad += pow2((diffNeg + diffPos) * 0.5);
152 normalModulus = 1. / std::sqrt(normalModulus);
153 for (
unsigned i = 0; i <
D; ++i) {
154 normalVector[i] *= normalModulus;
158 T scalarVelocity = velocities->getScalarVelocity(
159 coordinate, material, normalVector,
160 neighborIterator.getCenter().getPointId());
161 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
162 coordinate, material, normalVector,
163 neighborIterator.getCenter().getPointId());
167 if (scalarVelocity != 0.) {
168 totalGrad = scalarVelocity * std::sqrt(grad);
171 for (
int w = 0; w <
D; w++) {
172 if (vectorVelocity[w] > 0.) {
173 totalGrad += vectorVelocity[w] * gradPos[w];
175 totalGrad += vectorVelocity[w] * gradNeg[w];
179 if (totalGrad ==
T(0)) {
187 constexpr viennahrle::IndexType minIndex = -1;
188 constexpr viennahrle::IndexType maxIndex = 1;
189 constexpr unsigned numNeighbors =
190 static_cast<unsigned>(hrleUtil::pow((maxIndex - minIndex) + 1,
D));
192 viennahrle::Index<D> neighborIndex(minIndex);
193 for (
unsigned i = 0; i < numNeighbors; ++i) {
195 for (
unsigned dir = 0; dir <
D; ++dir) {
196 coords[dir] = coordinate[dir] + neighborIndex[dir] * gridDelta;
199 T normalModulus = 0.;
200 auto center = neighborIterator.getNeighbor(neighborIndex).getValue();
201 for (
unsigned dir = 0; dir <
D; ++dir) {
202 viennahrle::Index<D> unity(0);
205 neighborIterator.getNeighbor(neighborIndex - unity).getValue();
207 neighborIterator.getNeighbor(neighborIndex + unity).getValue();
208 normal[dir] = calculateNormalComponent(neg, center, pos, gridDelta);
209 normalModulus += normal[dir] * normal[dir];
212 normalModulus = 1. / std::sqrt(normalModulus);
213 for (
unsigned dir = 0; dir <
D; ++dir)
214 normal[dir] *= normalModulus;
216 T scaVel = velocities->getScalarVelocity(
217 coords, material, normal,
218 neighborIterator.getCenter().getPointId());
219 auto vecVel = velocities->getVectorVelocity(
220 coords, material, normal,
221 neighborIterator.getCenter().getPointId());
223 for (
unsigned dir = 0; dir <
D; ++dir) {
224 T tempAlpha = std::abs((scaVel + vecVel[dir]) * normal[dir]);
225 alpha[dir] = std::max(alpha[dir], tempAlpha);
226 finalAlphas[dir] = std::max(finalAlphas[dir], tempAlpha);
230 incrementIndices(neighborIndex, minIndex, maxIndex);
236 for (
unsigned i = 0; i <
D; ++i) {
237 dissipation += alphaFactor * alpha[i] * (gradNeg[i] - gradPos[i]) * 0.5;
240 return {totalGrad, dissipation};