3 #ifndef vtkDGOperationEvaluator_h
4 #define vtkDGOperationEvaluator_h
54 template <
typename InputIterator,
typename OutputIterator,
vtkDGSharingType DOFSharing,
71 op, connectivity, values, sideConn, offset, shapeGradient, shapeConnectivity, shapeValues)
75 throw std::logic_error(
"Must have non-null operator.");
77 if (Modifier !=
None && !shapeGradient)
79 throw std::logic_error(
"Must have non-null shape gradient operator.");
83 if (this->CellConnectivity)
85 ncc = this->CellConnectivity->GetNumberOfComponents();
86 this->ConnTuple.resize(ncc);
90 throw std::logic_error(
"DOF sharing requires a cell-connectivity array.");
92 int nvc = this->CellValues->GetNumberOfComponents();
95 this->NumberOfValuesPerFunction = nvc;
96 this->ValueTuple.resize(nvc * ncc);
100 this->NumberOfValuesPerFunction = nvc / this->OpEntry.NumberOfFunctions;
101 this->ValueTuple.resize(nvc);
106 if (Modifier !=
None)
108 this->Jacobian.resize(9);
109 this->ShapeBasisTuple.resize(shapeGradient.NumberOfFunctions * shapeGradient.OperatorSize);
111 if (this->ShapeConnectivity)
113 nsc = this->ShapeConnectivity->GetNumberOfComponents();
114 this->ShapeConnTuple.resize(nsc);
118 throw std::logic_error(
"Shape DOF-sharing requires a shape-connectivity array.");
120 int nvs = this->ShapeValues->GetNumberOfComponents();
123 this->NumberOfShapeValuesPerFunction = nvs;
124 this->ShapeValueTuple.resize(nvs * nsc);
128 this->NumberOfShapeValuesPerFunction = nvs / this->ShapeGradientEntry.NumberOfFunctions;
129 this->ShapeValueTuple.resize(nvs);
136 if (
auto* typedEntry =
140 ShapeSharing>::prepEntry(*typedEntry, this->OpEntry, this->CellConnectivity,
141 this->CellValues, this->SideConnectivity, this->Offset, this->ShapeGradientEntry,
142 this->ShapeConnectivity, this->ShapeValues);
151 auto xx(outIter[tt]);
152 int nc =
static_cast<int>(xx.size());
154 for (
int ii = 0; ii < nc; ++ii)
161 for (
int jj = 0; jj < this->OpEntry.OperatorSize; ++jj)
163 for (
int kk = 0; kk < this->OpEntry.NumberOfFunctions; ++kk)
165 xx[ii * this->OpEntry.OperatorSize + jj] +=
166 this->BasisTuple[kk * this->OpEntry.OperatorSize + jj] *
167 this->ValueTuple[kk * this->NumberOfValuesPerFunction + ii];
177 constexpr
int nc = 9;
178 assert(nc == this->ShapeGradientEntry.OperatorSize * this->NumberOfShapeValuesPerFunction);
180 for (
int ii = 0; ii < nc; ++ii)
182 this->Jacobian[ii] = 0.;
186 for (
int jj = 0; jj < this->ShapeGradientEntry.OperatorSize; ++jj)
188 for (
int kk = 0; kk < this->ShapeGradientEntry.NumberOfFunctions; ++kk)
190 this->Jacobian[jj + this->NumberOfShapeValuesPerFunction * ii] +=
191 this->ShapeBasisTuple[kk * this->ShapeGradientEntry.OperatorSize + jj] *
192 this->ShapeValueTuple[kk * this->NumberOfShapeValuesPerFunction + ii];
203 if (this->LastShapeCellId != this->LastCellId)
205 this->ShapeConnectivity->GetUnsignedTuple(this->LastCellId, this->ShapeConnTuple.data());
206 std::size_t nc = this->ShapeConnTuple.size();
207 int nv = this->ShapeValues->GetNumberOfComponents();
208 for (std::size_t jj = 0; jj < nc; ++jj)
210 this->ShapeValues->GetTuple(
211 this->ShapeConnTuple[jj], this->ShapeValueTuple.data() + nv * jj);
218 if (this->LastShapeCellId != this->LastCellId)
220 this->ShapeValues->GetTuple(this->LastCellId, this->ShapeValueTuple.data());
226 throw std::logic_error(
"Invalid shape DOF-sharing enumerant.");
228 this->ShapeGradientEntry.Op(this->RST, this->ShapeBasisTuple);
229 this->ShapeInnerProduct();
237 this->ComputeJacobian();
239 std::array<double, 9> inverseJacobian;
244 auto rr(outIter[ii]);
245 const int nc =
static_cast<int>(rr.size());
248 throw std::logic_error(
"Jacobian must apply to vector or matrix values.");
250 for (
int vv = 0; vv < nc / 3; ++vv)
252 vtkTypeUInt64 mm = 3 * vv;
253 double* vec = rr.data() + mm;
263 this->ComputeJacobian();
267 std::array<double, 3> vec;
268 auto rr(outIter[ii]);
269 const int nc =
static_cast<int>(rr.size());
272 throw std::logic_error(
"Jacobian must apply to vector or matrix values.");
274 for (
int vv = 0; vv < nc / 3; ++vv)
276 vtkTypeUInt64 mm = 3 * vv;
277 vec = { { rr[mm], rr[mm + 1], rr[mm + 2] } };
280 rr[mm ] = norm * (this->Jacobian[0] * vec[0] + this->Jacobian[1] * vec[1] + this->Jacobian[2] * vec[2]);
281 rr[mm + 1] = norm * (this->Jacobian[3] * vec[0] + this->Jacobian[4] * vec[1] + this->Jacobian[5] * vec[2]);
282 rr[mm + 2] = norm * (this->Jacobian[6] * vec[0] + this->Jacobian[7] * vec[1] + this->Jacobian[8] * vec[2]);
288 InputIterator& inIter, OutputIterator& outIter, vtkTypeUInt64 begin, vtkTypeUInt64 end)
const
290 vtkTypeUInt64 currId;
293 for (vtkTypeUInt64 ii = begin; ii != end; ++ii)
295 currId = inIter.GetCellId(ii);
296 this->SideConnectivity->GetUnsignedTuple(currId - this->Offset, this->SideTuple.data());
297 currId = this->SideTuple[0];
298 if (this->LastCellId != currId)
300 this->CellConnectivity->GetUnsignedTuple(currId, this->ConnTuple.data());
301 std::size_t nc = this->ConnTuple.size();
302 int nv = this->CellValues->GetNumberOfComponents();
303 for (std::size_t jj = 0; jj < nc; ++jj)
305 this->CellValues->GetTuple(this->ConnTuple[jj], this->ValueTuple.data() + nv * jj);
307 this->LastCellId = currId;
309 auto param = inIter.GetParameter(ii);
310 for (
int jj = 0; jj < 3; ++jj)
312 this->RST[jj] = param[jj];
314 this->OpEntry.Op(this->RST, this->BasisTuple);
315 this->InnerProduct(ii, outIter);
318 this->ApplyInverseJacobian(ii, outIter);
322 this->ApplyScaledJacobian(ii, outIter);
328 for (vtkTypeUInt64 ii = begin; ii != end; ++ii)
330 currId = inIter.GetCellId(ii);
331 if (this->LastCellId != currId)
335 this->CellConnectivity->GetUnsignedTuple(currId, this->ConnTuple.data());
336 std::size_t nc = this->ConnTuple.size();
337 int nv = this->CellValues->GetNumberOfComponents();
338 for (std::size_t jj = 0; jj < nc; ++jj)
340 this->CellValues->GetTuple(this->ConnTuple[jj], this->ValueTuple.data() + nv * jj);
342 this->LastCellId = currId;
344 auto param = inIter.GetParameter(ii);
345 for (
int jj = 0; jj < 3; ++jj)
347 this->RST[jj] = param[jj];
349 this->OpEntry.Op(this->RST, this->BasisTuple);
350 this->InnerProduct(ii, outIter);
353 this->ApplyInverseJacobian(ii, outIter);
357 this->ApplyScaledJacobian(ii, outIter);
363 for (vtkTypeUInt64 ii = begin; ii != end; ++ii)
365 currId = inIter.GetCellId(ii);
366 this->SideConnectivity->GetUnsignedTuple(currId - this->Offset, this->SideTuple.data());
367 currId = this->SideTuple[0];
368 if (this->LastCellId != currId)
370 this->CellValues->GetTuple(currId, this->ValueTuple.data());
371 this->LastCellId = currId;
373 auto param = inIter.GetParameter(ii);
374 for (
int jj = 0; jj < 3; ++jj)
376 this->RST[jj] = param[jj];
378 this->OpEntry.Op(this->RST, this->BasisTuple);
379 this->InnerProduct(ii, outIter);
382 this->ApplyInverseJacobian(ii, outIter);
386 this->ApplyScaledJacobian(ii, outIter);
392 for (vtkTypeUInt64 ii = begin; ii != end; ++ii)
394 currId = inIter.GetCellId(ii);
397 if (this->LastCellId != currId)
399 this->CellValues->GetTuple(currId, this->ValueTuple.data());
400 this->LastCellId = currId;
402 auto param = inIter.GetParameter(ii);
403 for (
int jj = 0; jj < 3; ++jj)
405 this->RST[jj] = param[jj];
407 this->OpEntry.Op(this->RST, this->BasisTuple);
408 this->InnerProduct(ii, outIter);
411 this->ApplyInverseJacobian(ii, outIter);
415 this->ApplyScaledJacobian(ii, outIter);
433 OutputIterator, DOFSharing, SourceType, Modifier, ShapeSharing>(
434 op, conn, values, sides,
offset, shapeGradient, shapeConnectivity, shapeValues));
435 entry.
Function = [&entry](InputIterator& inIter, OutputIterator& outIter, vtkTypeUInt64 begin,
439 DOFSharing, SourceType, Modifier, ShapeSharing
>*>(entry.
State.get());
440 return (*eval)(inIter, outIter, begin, end);
445 #endif // vtkDGOperationEvaluator_h
int NumberOfFunctions
The number of functions in the basis.
static void prepEntry(vtkDGOperationStateEntry< InputIterator, OutputIterator > &entry, vtkDGOperatorEntry op, vtkDataArray *conn, vtkDataArray *values, vtkDataArray *sides, vtkTypeUInt64 offset, vtkDGOperatorEntry shapeGradient=vtkDGOperatorEntry(), vtkDataArray *shapeConnectivity=nullptr, vtkDataArray *shapeValues=nullptr)
Prepare an entry for evaluating op with the given data arrays and class template parameters.
void operator()(InputIterator &inIter, OutputIterator &outIter, vtkTypeUInt64 begin, vtkTypeUInt64 end) const
vtkDGCellRangeEvaluator< InputIterator, OutputIterator > Function
InputIterator InputIteratorType
double Determinant()
Compute the determinant of the matrix and return it.
void ApplyScaledJacobian(vtkTypeUInt64 ii, OutputIterator &outIter) const
int OperatorSize
The number of coordinates each operator-function evaluates to.
Degrees of freedom are not shared.
This is a base class that exists so that vtkDGOperationState can provide a virtual CloneInto method t...
OutputIterator OutputIteratorType
int NumberOfValuesPerFunction
void ComputeJacobian() const
Compute the shape-attribute Jacobian matrix, storing it in this->Jacobian.
Degrees of freedom (DOF) are shared.
A side specified by a cell ID and an integer index into sides.
Encapsulate the state required to evaluate DG cell-attributes.
abstract superclass for arrays of numeric data
vtkDGSharingType
Whether degrees of freedom (DOF) are shared between cells.
void InnerProduct(vtkTypeUInt64 tt, OutputIterator &outIter) const
Compute the inner product of this->BasisTuple and this->ValueTuple, storing the result in the tt-th t...
Encapsulate the state required to evaluate DG cell-attributes.
A cell specified by degrees of freedom held in arrays.
Evaluate a vtkDGOperationEntry on a provided cell ID at provided parametric coordinates.
A record for a basis in a function space that is specific to one cell shape.
std::unique_ptr< vtkDGOperationState > State
void CloneInto(vtkDGOperationStateEntryBase &entry) const override
vtkDGOperationEvaluator(vtkDGOperatorEntry &op, vtkDataArray *connectivity, vtkDataArray *values, vtkDataArray *sideConn, vtkTypeUInt64 offset, vtkDGOperatorEntry shapeGradient=vtkDGOperatorEntry(), vtkDataArray *shapeConnectivity=nullptr, vtkDataArray *shapeValues=nullptr)
void MultiplyPoint(const float in[3], float out[3])
Multiply a homogeneous coordinate by this matrix, i.e.
void ShapeInnerProduct() const
Compute the inner product of this->ShapeBasisTuple and this->ShapeValueTuple, storing the result in t...
int NumberOfShapeValuesPerFunction
#define VTK_ALWAYS_EXPORT
vtkDGSideType
Whether cells are stand-alone or sides of other cells.
void ApplyInverseJacobian(vtkTypeUInt64 ii, OutputIterator &outIter) const
vtkDGShapeModifier
Which type of shape-function post-processing is required.