VTK  9.3.20240916
vtkDGInvokeOperator.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3#ifndef vtkDGInvokeOperator_h
4#define vtkDGInvokeOperator_h
5
6#include "vtkCellAttribute.h" // For CellTypeInfo.
7#include "vtkDGOperatorEntry.h" // For ivars.
8#include "vtkDataArray.h" // For implementation.
9#include "vtkFiltersCellGridModule.h" // For export macro.
10
11#include <array>
12#include <cstring> // For std::memset.
13#include <vector>
14
15VTK_ABI_NAMESPACE_BEGIN
16
52class VTKFILTERSCELLGRID_EXPORT vtkDGInvokeOperator
53{
54public:
57
59 {
60 vtkDataArray* Coefficients{ nullptr };
61
63 FetchUnsharedCellDOF(vtkDataArray* vals, vtkDataArray* conn) { this->Initialize(vals, conn); }
64
65 void Initialize(vtkDataArray* vals, vtkDataArray* conn = nullptr)
66 {
67 (void)conn;
68 this->Coefficients = vals;
69 }
70
71 void operator()(vtkIdType ii, std::vector<double>& tuple)
72 {
73 // tuple.resize(this->Coefficients->GetNumberOfComponents());
74 this->Coefficients->GetTuple(ii, tuple.data());
75 }
76 };
77
79 {
80 vtkDataArray* Coefficients{ nullptr };
81 vtkDataArray* Connectivity{ nullptr };
82 vtkIdType Stride{ 0 };
83 std::vector<vtkTypeInt64> ConnTuple;
84
85 FetchSharedCellDOF() = default;
86 FetchSharedCellDOF(vtkDataArray* vals, vtkDataArray* conn) { this->Initialize(vals, conn); }
87
89 {
90 this->Coefficients = vals;
91 this->Connectivity = conn;
92 this->Stride = vals->GetNumberOfComponents();
93 this->ConnTuple.resize(conn->GetNumberOfComponents());
94 }
95
96 void operator()(vtkIdType ii, std::vector<double>& tuple)
97 {
98 this->Connectivity->GetIntegerTuple(ii, this->ConnTuple.data());
99 auto valIt = tuple.begin();
100 for (const auto& valId : this->ConnTuple)
101 {
102 this->Coefficients->GetTuple(valId, &(*valIt));
103 valIt += this->Stride;
104 }
105 }
106 };
107
115 template <typename InputIterator, typename OutputIterator>
116 bool InvokeOp(const vtkDGOperatorEntry& op, const vtkCellAttribute::CellTypeInfo& info,
117 InputIterator begin, InputIterator end, OutputIterator out);
118
122
123 template <typename InputIterator, typename OutputIterator>
124 bool InvokeSharedDOF(const vtkDGOperatorEntry& op, const vtkCellAttribute::CellTypeInfo& info,
125 InputIterator begin, InputIterator end, OutputIterator out);
126 template <typename InputIterator, typename OutputIterator>
127 bool InvokeUnsharedDOF(const vtkDGOperatorEntry& op, const vtkCellAttribute::CellTypeInfo& info,
128 InputIterator begin, InputIterator end, OutputIterator out);
129
137 template <typename OutputIterator>
138 void InnerProduct(int coefficientsPerDOF, int stride, const vtkDGOperatorEntry& op,
139 const std::array<double, 3>& rst, OutputIterator& out);
141
149 std::size_t num, const vtkIdType* cellIds, const double* rst, double* result);
150
152 std::vector<double> CoeffTuple;
153
155 std::vector<double> OperatorTuple;
156
159
162};
163
164template <typename InputIterator, typename OutputIterator>
166 const vtkCellAttribute::CellTypeInfo& info, InputIterator begin, InputIterator end,
167 OutputIterator out)
168{
169 if (info.DOFSharing.IsValid())
170 {
171 return this->InvokeSharedDOF(op, info, begin, end, out);
172 }
173 else
174 {
175 return this->InvokeUnsharedDOF(op, info, begin, end, out);
176 }
177}
178
179template <typename InputIterator, typename OutputIterator>
181 const vtkCellAttribute::CellTypeInfo& info, InputIterator begin, InputIterator end,
182 OutputIterator out)
183{
184 using namespace vtk::literals;
185
186 if (!op)
187 {
188 return false;
189 }
190 auto valsit = info.ArraysByRole.find("values"_token);
191 if (valsit == info.ArraysByRole.end() || !valsit->second)
192 {
193 return false;
194 }
195 auto connit = info.ArraysByRole.find("connectivity"_token);
196 if (connit == info.ArraysByRole.end() || !connit->second)
197 {
198 return false;
199 }
201 vtkDataArray::SafeDownCast(valsit->second), vtkDataArray::SafeDownCast(connit->second));
202 int coefficientsPerDOF = valsit->second->GetNumberOfComponents();
203 this->CoeffTuple.resize(connit->second->GetNumberOfComponents() * coefficientsPerDOF);
204 this->OperatorTuple.resize(op.OperatorSize * op.NumberOfFunctions);
205 // There must be exactly one connectivity entry per operator function.
206 if (connit->second->GetNumberOfComponents() != op.NumberOfFunctions)
207 {
208 return false;
209 }
210 int stride = op.OperatorSize * coefficientsPerDOF;
211 vtkIdType lastCellId = -1; // Start with an invalid cell ID.
212 for (auto initer = begin; initer != end; ++initer)
213 {
214 if (lastCellId != initer.GetCellId())
215 {
216 lastCellId = initer.GetCellId();
217 this->SharedFetcher(lastCellId, this->CoeffTuple);
218 }
219 this->InnerProduct(coefficientsPerDOF, stride, op, initer.GetParameter(), out);
220 }
221 return true;
222}
223
224template <typename InputIterator, typename OutputIterator>
226 const vtkCellAttribute::CellTypeInfo& info, InputIterator begin, InputIterator end,
227 OutputIterator out)
228{
229 using namespace vtk::literals;
230
231 if (!op)
232 {
233 return false;
234 }
235 auto valsit = info.ArraysByRole.find("values"_token);
236 if (valsit == info.ArraysByRole.end() || !valsit->second)
237 {
238 return false;
239 }
240 this->DiscontinuousFetcher.Initialize(vtkDataArray::SafeDownCast(valsit->second));
241 int totalCoefficients = valsit->second->GetNumberOfComponents();
244 if (totalCoefficients % op.NumberOfFunctions != 0)
245 {
246 return false;
247 }
248 int coefficientsPerDOF = totalCoefficients / op.NumberOfFunctions;
249 this->CoeffTuple.resize(totalCoefficients);
250 this->OperatorTuple.resize(op.OperatorSize * op.NumberOfFunctions);
251 int stride = op.OperatorSize * coefficientsPerDOF;
252 vtkIdType lastCellId = -1; // Start with an invalid cell ID.
253 for (auto initer = begin; initer != end; ++initer)
254 {
255 if (lastCellId != initer.GetCellId())
256 {
257 lastCellId = initer.GetCellId();
258 this->DiscontinuousFetcher(lastCellId, this->CoeffTuple);
259 }
260 this->InnerProduct(coefficientsPerDOF, stride, op, initer.GetParameter(), out);
261 }
262 return true;
263}
264
265template <typename OutputIterator>
266void vtkDGInvokeOperator::InnerProduct(int coefficientsPerDOF, int stride,
267 const vtkDGOperatorEntry& op, const std::array<double, 3>& rst, OutputIterator& out)
268{
269 // Compute the values for \a op at \a rst.
270 op.Op(rst, this->OperatorTuple);
271 // Zero the output for this input cell-id+(r,s,t)-tuple.
272 std::memset(&(out[0]), 0, sizeof(double) * stride);
273 // Now sum the "inner product" of the coeffient tuple and operator tuple into the output.
274 for (int ii = 0; ii < coefficientsPerDOF; ++ii)
275 {
276 for (int jj = 0; jj < op.NumberOfFunctions; ++jj)
277 {
278 for (int kk = 0; kk < op.OperatorSize; ++kk)
279 {
280 out[ii * op.OperatorSize + kk] += this->CoeffTuple[jj * coefficientsPerDOF + ii] *
281 this->OperatorTuple[jj * op.OperatorSize + kk];
282 }
283 }
284 }
285 out += stride;
286}
287
288VTK_ABI_NAMESPACE_END
289#endif // vtkDGInvokeOperator_h
RealT rst
Definition TetF2Basis.h:17
int GetNumberOfComponents() const
Set/Get the dimension (n) of the components.
Invoke a DG-cell operator, weighting basis functions by coefficients.
std::vector< double > CoeffTuple
Hold the function coefficients for a single cell.
std::vector< double > OperatorTuple
Hold the function values for a single (r,s,t) evaluation.
bool InvokeSharedDOF(const vtkDGOperatorEntry &op, const vtkCellAttribute::CellTypeInfo &info, InputIterator begin, InputIterator end, OutputIterator out)
Hold the function coefficients for a single cell.
void InnerProduct(int coefficientsPerDOF, int stride, const vtkDGOperatorEntry &op, const std::array< double, 3 > &rst, OutputIterator &out)
Invoke the operator op once on rst and compute the inner product.
bool InvokeOp(const vtkDGOperatorEntry &op, const vtkCellAttribute::CellTypeInfo &info, InputIterator begin, InputIterator end, OutputIterator out)
Given input cells and parametric coordinates to iterate, evaluate the operator and store the results ...
bool InvokeUnsharedDOF(const vtkDGOperatorEntry &op, const vtkCellAttribute::CellTypeInfo &info, InputIterator begin, InputIterator end, OutputIterator out)
bool Invoke(const vtkDGOperatorEntry &op, const vtkCellAttribute::CellTypeInfo &info, std::size_t num, const vtkIdType *cellIds, const double *rst, double *result)
This is a convenience method that makes invoking the operator from python (as well as C++) simpler.
FetchUnsharedCellDOF DiscontinuousFetcher
Fetch values into CoeffTuple when DOF are not shared.
vtkDGInvokeOperator(const vtkDGInvokeOperator &)=default
FetchSharedCellDOF SharedFetcher
Fetch values into CoeffTuple when DOF are shared among cells by connectivity.
vtkDGInvokeOperator()=default
A record for a basis in a function space that is specific to one cell shape.
int OperatorSize
The number of coordinates each operator-function evaluates to.
OperatorFunction Op
A function you may call to evaluate the operator.
int NumberOfFunctions
The number of functions in the basis.
abstract superclass for arrays of numeric data
void operator()(vtkIdType ii, std::vector< double > &tuple)
FetchSharedCellDOF(vtkDataArray *vals, vtkDataArray *conn)
void Initialize(vtkDataArray *vals, vtkDataArray *conn)
FetchUnsharedCellDOF(vtkDataArray *vals, vtkDataArray *conn)
void Initialize(vtkDataArray *vals, vtkDataArray *conn=nullptr)
void operator()(vtkIdType ii, std::vector< double > &tuple)
int vtkIdType
Definition vtkType.h:315