60 T operator()(
const hrleVectorType<hrleIndexType, D> &indices,
int material) {
62 auto &grid = levelSet->getGrid();
63 double gridDelta = grid.getGridDelta();
65 hrleVectorType<T, 3> coordinate(0., 0., 0.);
66 for (
unsigned i = 0; i <
D; ++i) {
67 coordinate[i] = indices[i] * gridDelta;
71 neighborIterator.goToIndicesSequential(indices);
74 Vec3D<T> coordArray = {coordinate[0], coordinate[1], coordinate[2]};
82 Vec3D<T> normalVector = {};
85 for (
int i = 0; i <
D; i++) {
86 hrleVectorType<hrleIndexType, D> posUnit(0);
87 hrleVectorType<hrleIndexType, 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;
105 const T deltaPosPos = 2 * gridDelta;
106 const T deltaNegNeg = -2 * gridDelta;
109 (((deltaNeg * phiPos - deltaPos * phiNeg) / (deltaPos - deltaNeg) +
111 (deltaPos * deltaNeg);
112 const T phiPosPos = neighborIterator.getNeighbor(posUnit).getValue();
113 const T phiNegNeg = neighborIterator.getNeighbor(negUnit).getValue();
115 const T diffNegNeg = (((deltaNeg * phiNegNeg - deltaNegNeg * phiNeg) /
116 (deltaNegNeg - deltaNeg) +
118 (deltaNegNeg * deltaNeg);
119 const T diffPosPos = (((deltaPos * phiPosPos - deltaPosPos * phiPos) /
120 (deltaPosPos - deltaPos) +
122 (deltaPosPos * deltaPos);
124 if (std::signbit(diff00) == std::signbit(diffPosPos)) {
125 if (std::abs(diffPosPos * deltaPos) < std::abs(diff00 * deltaNeg)) {
126 diffPos -= deltaPos * diffPosPos;
128 diffPos += deltaNeg * diff00;
132 if (std::signbit(diff00) == std::signbit(diffNegNeg)) {
133 if (std::abs(diffNegNeg * deltaNeg) < std::abs(diff00 * deltaPos)) {
134 diffNeg -= deltaNeg * diffNegNeg;
136 diffNeg += deltaPos * diff00;
141 gradPos[i] = diffNeg;
142 gradNeg[i] = diffPos;
144 normalVector[i] = (diffNeg + diffPos) * 0.5;
145 normalModulus += normalVector[i] * normalVector[i];
147 grad += pow2((diffNeg + diffPos) * 0.5);
151 normalModulus = std::sqrt(normalModulus);
152 for (
unsigned i = 0; i <
D; ++i) {
153 normalVector[i] /= normalModulus;
157 double scalarVelocity = velocities->getScalarVelocity(
158 coordArray, material, normalVector,
159 neighborIterator.getCenter().getPointId());
160 Vec3D<T> vectorVelocity = velocities->getVectorVelocity(
161 coordArray, material, normalVector,
162 neighborIterator.getCenter().getPointId());
166 if (scalarVelocity != 0.) {
167 totalGrad = scalarVelocity * std::sqrt(grad);
170 for (
int w = 0; w <
D; w++) {
171 if (vectorVelocity[w] > 0.) {
172 totalGrad += vectorVelocity[w] * gradPos[w];
174 totalGrad += vectorVelocity[w] * gradNeg[w];
182 const hrleIndexType minIndex = -1;
183 const hrleIndexType maxIndex = 1;
184 const unsigned numNeighbors = std::pow((maxIndex - minIndex),
D);
186 hrleVectorType<hrleIndexType, D> neighborIndex(minIndex);
187 for (
unsigned i = 0; i < numNeighbors; ++i) {
189 Vec3D<T> normal = {};
190 auto center = neighborIterator.getNeighbor(neighborIndex).getValue();
191 for (
unsigned dir = 0; dir <
D; ++dir) {
192 hrleVectorType<hrleIndexType, D> unity(0);
195 neighborIterator.getNeighbor(neighborIndex - unity).getValue();
197 neighborIterator.getNeighbor(neighborIndex + unity).getValue();
198 normal[dir] = calculateNormalComponent(neg, center, pos, gridDelta);
201 for (
unsigned dir = 0; dir <
D; ++dir) {
202 T tempAlpha = velocities->getDissipationAlpha(dir, material, normal);
203 alpha[dir] = std::max(alpha[dir], tempAlpha);
207 incrementIndices(neighborIndex, minIndex, maxIndex);
213 for (
unsigned i = 0; i <
D; ++i) {
214 dissipation += alpha[i] * (gradNeg[i] - gradPos[i]) * 0.5;
219 return totalGrad - ((totalGrad != 0.) ? dissipation : 0);