66 std::pair<T, T>
operator()(
const hrleVectorType<hrleIndexType, D> &indices,
69 auto &grid = levelSet->getGrid();
70 double gridDelta = grid.getGridDelta();
72 hrleVectorType<T, 3> coordinate(0., 0., 0.);
73 for (
unsigned i = 0; i <
D; ++i) {
74 coordinate[i] = indices[i] * gridDelta;
78 neighborIterator.goToIndicesSequential(indices);
81 Vec3D<T> coordArray = {coordinate[0], coordinate[1], coordinate[2]};
89 Vec3D<T> normalVector = {};
92 for (
int i = 0; i <
D; i++) {
93 hrleVectorType<hrleIndexType, D> posUnit(0);
94 hrleVectorType<hrleIndexType, D> negUnit(0);
98 const T deltaPos = gridDelta;
99 const T deltaNeg = -gridDelta;
101 const T phi0 = neighborIterator.getCenter().getValue();
102 const T phiPos = neighborIterator.getNeighbor(posUnit).getValue();
103 const T phiNeg = neighborIterator.getNeighbor(negUnit).getValue();
105 T diffPos = (phiPos - phi0) / deltaPos;
106 T diffNeg = (phiNeg - phi0) / deltaNeg;
112 const T deltaPosPos = 2 * gridDelta;
113 const T deltaNegNeg = -2 * gridDelta;
116 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
118 (deltaPos * deltaNeg);
119 const T phiPosPos = neighborIterator.getNeighbor(posUnit).getValue();
120 const T phiNegNeg = neighborIterator.getNeighbor(negUnit).getValue();
122 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
123 (deltaNegNeg - deltaNeg) +
125 (deltaNegNeg * deltaNeg);
126 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
127 (deltaPosPos - deltaPos) +
129 (deltaPosPos * deltaPos);
131 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
132 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
133 diffPos -= deltaPos * diffPosPos;
135 diffPos += deltaNeg * diff00;
139 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
140 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
141 diffNeg -= deltaNeg * diffNegNeg;
143 diffNeg += deltaPos * diff00;
148 gradPos[i] = diffNeg;
149 gradNeg[i] = diffPos;
151 normalVector[i] = (diffNeg + diffPos) * 0.5;
152 normalModulus += normalVector[i] * normalVector[i];
154 grad += pow2((diffNeg + diffPos) * 0.5);
158 normalModulus = std::sqrt(normalModulus);
159 for (
unsigned i = 0; i <
D; ++i) {
160 normalVector[i] /= normalModulus;
164 double scalarVelocity = velocities->getScalarVelocity(
165 coordArray, material, normalVector,
166 neighborIterator.getCenter().getPointId());
167 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
168 coordArray, material, normalVector,
169 neighborIterator.getCenter().getPointId());
173 if (scalarVelocity != 0.) {
174 totalGrad = scalarVelocity * std::sqrt(grad);
177 for (
int w = 0; w <
D; w++) {
178 if (vectorVelocity[w] > 0.) {
179 totalGrad += vectorVelocity[w] * gradPos[w];
181 totalGrad += vectorVelocity[w] * gradNeg[w];
189 const hrleIndexType minIndex = -1;
190 const hrleIndexType maxIndex = 1;
191 const unsigned numNeighbors = std::pow((maxIndex - minIndex) + 1,
D);
193 hrleVectorType<hrleIndexType, D> neighborIndex(minIndex);
194 for (
unsigned i = 0; i < numNeighbors; ++i) {
196 for (
unsigned dir = 0; dir <
D; ++dir) {
197 coords[dir] = coordinate[dir] + neighborIndex[dir] * gridDelta;
199 Vec3D<T> normal = {};
200 double normalModulus = 0.;
201 auto center = neighborIterator.getNeighbor(neighborIndex).getValue();
202 for (
unsigned dir = 0; dir <
D; ++dir) {
203 hrleVectorType<hrleIndexType, D> unity(0);
206 neighborIterator.getNeighbor(neighborIndex - unity).getValue();
208 neighborIterator.getNeighbor(neighborIndex + unity).getValue();
209 normal[dir] = calculateNormalComponent(neg, center, pos, gridDelta);
210 normalModulus += normal[dir] * normal[dir];
212 normalModulus = 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) {
225 T tempAlpha = std::abs((scaVel + vecVel[dir]) * normal[dir]);
226 alpha[dir] = std::max(alpha[dir], tempAlpha);
227 finalAlphas[dir] = std::max(finalAlphas[dir], tempAlpha);
231 incrementIndices(neighborIndex, minIndex, maxIndex);
237 for (
unsigned i = 0; i <
D; ++i) {
238 dissipation += alphaFactor * alpha[i] * (gradNeg[i] - gradPos[i]) * 0.5;
241 return {totalGrad, ((totalGrad != 0.) ? dissipation : 0)};