KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
nurbs_volume_shape_functions.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Manuel Messmer
11 //
12 
13 #if !defined(KRATOS_NURBS_VOLUME_SHAPE_FUNCTIONS_H_INCLUDED )
14 #define KRATOS_NURBS_VOLUME_SHAPE_FUNCTIONS_H_INCLUDED
15 
16 // Project includes
19 #include "input_output/logger.h"
20 
21 namespace Kratos
22 {
25 
32 {
33 public:
36 
37  typedef std::size_t IndexType;
38  typedef std::size_t SizeType;
39 
43 
46  {
47  };
48 
49  // Constructor using the degree u, degree v, degree w and the order of shape functions.
50  // This is required to make an optimized memory management.
56  {
58  }
59 
63 
73  {
74  IndexType number_of_shape_function_rows = 0.0;
75  for( IndexType i = 0; i < DerivativeOrder + 1; ++i){
76  number_of_shape_function_rows += (1 + i) * (2 + i) / 2;
77  }
78 
79  return number_of_shape_function_rows;
80  }
92  const SizeType DerivativeOrderU,
93  const SizeType DerivativeOrderV,
94  const SizeType DerivativeOrderW)
95  {
96  // This seraializes the pascals pyramid.
97  const SizeType current_level = DerivativeOrderU + DerivativeOrderV + DerivativeOrderW;
98 
99  SizeType first_index_of_current_level = 0;
100  if( current_level > 0){
101  first_index_of_current_level = NumberOfShapeFunctionRows(current_level - 1);
102  const SizeType offset = current_level - DerivativeOrderU;
103  SizeType index_in_current_level = 0;
104  for( IndexType i = 0; i < offset; ++i){
105  index_in_current_level += i + 1;
106  }
107  index_in_current_level += DerivativeOrderW;
108 
109  return first_index_of_current_level + index_in_current_level;
110  }
111  else {
112  return 0;
113  }
114  }
115 
119 
120  double operator()(
121  const IndexType ControlPointIndex,
122  const IndexType DerivativeRow) const
123  {
124  return ShapeFunctionValue(ControlPointIndex, DerivativeRow);
125  }
126 
127  double operator()(
128  const IndexType ControlPointIndexU,
129  const IndexType ControlPointIndexV,
130  const IndexType ControlPointIndexW,
131  const IndexType DerivativeRow) const
132  {
133  return ShapeFunctionValue(ControlPointIndexU, ControlPointIndexV, ControlPointIndexW, DerivativeRow);
134  }
135 
139 
148  {
149  const SizeType number_of_shape_function_rows = this->NumberOfShapeFunctionRows(DerivativeOrder);
150  const SizeType number_of_nonzero_control_points = (PolynomialDegreeU + 1) * (PolynomialDegreeV + 1) * (PolynomialDegreeW + 1);
151 
155  mShapeFunctionValues.resize(number_of_nonzero_control_points * number_of_shape_function_rows);
156  // mWeightedSums.resize(number_of_shape_function_rows);
157 
158  mDerivativeOrder = DerivativeOrder;
159  }
160 
162  {
163  return mShapeFunctionsU.PolynomialDegree();
164  }
165 
167  {
168  return mShapeFunctionsV.PolynomialDegree();
169  }
170 
172  {
173  return mShapeFunctionsW.PolynomialDegree();
174  }
175 
177  {
178  return mDerivativeOrder;
179  }
180 
182  {
184  }
185 
187  {
188  return mShapeFunctionsU.NumberOfNonzeroControlPoints();
189  }
190 
192  {
193  return mShapeFunctionsV.NumberOfNonzeroControlPoints();
194  }
195 
197  {
198  return mShapeFunctionsW.NumberOfNonzeroControlPoints();
199  }
200 
202  {
204  }
205 
210  std::vector<array_1d<int, 3>> NonzeroControlPointIndices() const
211  {
212  std::vector<array_1d<int, 3>> indices(NumberOfNonzeroControlPoints());
213 
214  for (IndexType i = 0; i < NumberOfNonzeroControlPointsU(); ++i) {
215  for (IndexType j = 0; j < NumberOfNonzeroControlPointsV(); ++j) {
216  for (IndexType k = 0; k < NumberOfNonzeroControlPointsW(); ++k) {
219 
223 
224  indices[poleIndex][0] = poleU;
225  indices[poleIndex][1] = poleV;
226  indices[poleIndex][2] = poleW;
227  }
228  }
229  }
230  return indices;
231  }
232 
240  std::vector<int> ControlPointIndices(
241  SizeType NumberOfControlPointsU, SizeType NumberOfControlPointsV, SizeType NumberOfControlPointsW) const
242  {
243  std::vector<int> indices(NumberOfNonzeroControlPoints());
244 
245  for (IndexType i = 0; i < NumberOfNonzeroControlPointsU(); ++i) {
246  for (IndexType j = 0; j < NumberOfNonzeroControlPointsV(); ++j) {
247  for(IndexType k = 0; k < NumberOfNonzeroControlPointsW(); ++k) {
250 
251  IndexType cp_index_u = GetFirstNonzeroControlPointU() + i;
252  IndexType cp_index_v = GetFirstNonzeroControlPointV() + j;
253  IndexType cp_index_w = GetFirstNonzeroControlPointW() + k;
254 
256  NumberOfControlPointsU, NumberOfControlPointsV, NumberOfControlPointsW, cp_index_u, cp_index_v, cp_index_w);
257  }
258  }
259  }
260 
261  return indices;
262  }
263 
268  const IndexType ControlPointIndexU,
269  const IndexType ControlPointIndexV,
270  const IndexType ControlPointIndexW,
271  const SizeType DerivativeRow) const
272  {
273  const IndexType index = this->GetIndex(
274  ControlPointIndexU,
275  ControlPointIndexV,
276  ControlPointIndexW,
277  DerivativeRow);
278 
279  KRATOS_DEBUG_ERROR_IF(index >= mShapeFunctionValues.size()) << "Index exceeds size of shape function values. Index: "
280  << index << ", mShapeFunctionValues.size(): " << mShapeFunctionValues.size()
281  << ", ControlPointIndexU: " << ControlPointIndexU << ", ControlPointIndexV: " << ControlPointIndexV
282  << ", ControlPointIndexW: " << ControlPointIndexW << ", DerivativeRow: " << DerivativeRow << std::endl;
283 
284  return mShapeFunctionValues[index];
285  }
286 
291  const IndexType ControlPointIndex,
292  const SizeType DerivativeOrder) const
293  {
296  DerivativeOrder, ControlPointIndex);
297 
298  KRATOS_DEBUG_ERROR_IF(index >= mShapeFunctionValues.size()) << "Index exceeds size of shape function values. Index: "
299  << index << ", mShapeFunctionValues.size(): " << mShapeFunctionValues.size()
300  << ", ControlPointIndex: " << ControlPointIndex << ", DerivativeOrder: " << DerivativeOrder << std::endl;
301 
302  return mShapeFunctionValues[index];
303  }
304 
306  {
307  return mFirstNonzeroControlPointU;
308  }
309 
311  {
313  }
314 
316  {
317  return mFirstNonzeroControlPointV;
318  }
319 
321  {
323  }
324 
326  {
327  return mFirstNonzeroControlPointW;
328  }
329 
331  {
333  }
334 
339  const Vector& rKnotsU,
340  const Vector& rKnotsV,
341  const Vector& rKnotsW,
342  const int SpanU,
343  const int SpanV,
344  const int SpanW,
345  const double ParameterU,
346  const double ParameterV,
347  const double ParameterW)
348  {
349  mShapeFunctionValues = ZeroVector(mShapeFunctionValues.size());
350 
351  mFirstNonzeroControlPointU = SpanU - PolynomialDegreeU() + 1;
352  mFirstNonzeroControlPointV = SpanV - PolynomialDegreeV() + 1;
353  mFirstNonzeroControlPointW = SpanW - PolynomialDegreeW() + 1;
354 
355  // Compute 1D shape functions
356  mShapeFunctionsU.ComputeBSplineShapeFunctionValuesAtSpan(rKnotsU, SpanU, ParameterU);
357  mShapeFunctionsV.ComputeBSplineShapeFunctionValuesAtSpan(rKnotsV, SpanV, ParameterV);
358  mShapeFunctionsW.ComputeBSplineShapeFunctionValuesAtSpan(rKnotsW, SpanW, ParameterW);
359  // Compute 3D shape functions
360  for( IndexType currrent_order = 0; currrent_order <= DerivativeOrder(); ++currrent_order){
361  for (int OrderU = currrent_order; OrderU >= 0; OrderU = OrderU - 1) {
362  const IndexType difference = currrent_order - OrderU;
363  for (IndexType OrderW = 0; OrderW <= difference; ++OrderW) {
364  const IndexType OrderV = difference - OrderW;
365  for (IndexType a = 0; a < NumberOfNonzeroControlPointsU(); ++a) {
366  for (IndexType b = 0; b < NumberOfNonzeroControlPointsV(); ++b) {
367  for (IndexType c = 0; c < NumberOfNonzeroControlPointsW(); ++c) {
368  const IndexType index = IndexOfShapeFunctionRow(OrderU, OrderV, OrderW);
369  ShapeFunctionValue(a, b, c, index) = mShapeFunctionsU(a, OrderU) * mShapeFunctionsV(b, OrderV) * mShapeFunctionsW(c, OrderW);
370  }
371  }
372  }
373  }
374  }
375  }
376  }
377 
384  const Vector& rKnotsU,
385  const Vector& rKnotsV,
386  const Vector& rKnotsW,
387  const double ParameterU,
388  const double ParameterV,
389  const double ParameterW)
390  {
391  const IndexType SpanU = NurbsUtilities::GetLowerSpan(PolynomialDegreeU(), rKnotsU, ParameterU);
392  const IndexType SpanV = NurbsUtilities::GetLowerSpan(PolynomialDegreeV(), rKnotsV, ParameterV);
393  const IndexType SpanW = NurbsUtilities::GetLowerSpan(PolynomialDegreeW(), rKnotsW, ParameterW);
394 
396  rKnotsU,
397  rKnotsV,
398  rKnotsW,
399  SpanU,
400  SpanV,
401  SpanW,
402  ParameterU,
403  ParameterV,
404  ParameterW);
405  }
406 
408  const Vector& rKnotsU,
409  const Vector& rKnotsV,
410  const Vector& rKnotsW,
411  const IndexType SpanU,
412  const IndexType SpanV,
413  const IndexType SpanW,
414  const Vector& Weights,
415  const double ParameterU,
416  const double ParameterV,
417  const double ParameterW)
418  {
419  // Check input
420  KRATOS_WARNING("NURBSVolumeShapeFunctions: ComputeNurbsShapeFunctionValuesAtSpan")
421  << "The NURBS weights are not yet imlemented. "
422  << "Therefore the 'ComputeBSplineShapeFunctionValuesAtSpan' is invoked." << std::endl;
423 
424  // Compute B-Spline shape functions
426  rKnotsU, rKnotsV, rKnotsW, SpanU, SpanV, SpanW, ParameterU, ParameterV, ParameterW);
427  }
428 
430  const Vector& rKnotsU,
431  const Vector& rKnotsV,
432  const Vector& rKnotsW,
433  const Vector& Weights,
434  const double ParameterU,
435  const double ParameterV,
436  const double ParameterW)
437  {
438  const IndexType SpanU = NurbsUtilities::GetLowerSpan(PolynomialDegreeU(), rKnotsU, ParameterU);
439  const IndexType SpanV = NurbsUtilities::GetLowerSpan(PolynomialDegreeV(), rKnotsV, ParameterV);
440  const IndexType SpanW = NurbsUtilities::GetLowerSpan(PolynomialDegreeW(), rKnotsW, ParameterW);
441 
443  rKnotsU, rKnotsV, rKnotsW, SpanU, SpanV, SpanW, Weights, ParameterU, ParameterV, ParameterW);
444  }
446 private:
449 
450  // Attention: Weight ar not yet implemented.
451  // double& GetWeightedSum(const IndexType Index)
452  // {
453  // return mWeightedSums[Index];
454  // }
455 
456  // double& GetWeightedSum(const SizeType DerivativeOrderU, const SizeType DerivativeOrderV, const SizeType DerivativeOrderW)
457  // {
458  // const int index = IndexOfShapeFunctionRow(DerivativeOrderU, DerivativeOrderV, DerivativeOrderW);
459 
460  // return GetWeightedSum(index);
461  // }
462 
463  inline int GetControlPointIndex(
464  const SizeType NumberOfKnotsU,
465  const SizeType NumberOfKnotsV,
466  const SizeType NumberOfKnotsW,
467  const IndexType ControlPointIndexU,
468  const IndexType ControlPointIndexV,
469  const IndexType ControlPointIndexW)
470  const
471  {
476  ControlPointIndexU, ControlPointIndexV, ControlPointIndexW);
477  }
478 
479  inline int GetNonzeroControlPointIndex(
480  const IndexType ControlPointIndexU,
481  const IndexType ControlPointIndexV,
482  const IndexType ControlPointIndexW)
483  const
484  {
487  ControlPointIndexU, ControlPointIndexV, ControlPointIndexW);
488  }
489 
490  inline int GetIndex(
491  const IndexType ControlPointIndexU,
492  const IndexType ControlPointIndexV,
493  const IndexType ControlPointIndexW,
494  const SizeType DerivativeRow)
495  const
496  {
497  const IndexType control_point_index = GetNonzeroControlPointIndex(
498  ControlPointIndexU, ControlPointIndexV, ControlPointIndexW);
499 
502  DerivativeRow, control_point_index);
503 
504  return index;
505  }
506 
507  double& ShapeFunctionValue(
508  const IndexType ControlPointIndex,
509  const IndexType DerivativeRow)
510  {
513  DerivativeRow, ControlPointIndex);
514 
515  return mShapeFunctionValues[index];
516  }
517 
518  double& ShapeFunctionValue(
519  const IndexType ControlPointIndexU,
520  const IndexType ControlPointIndexV,
521  const IndexType ControlPointIndexW,
522  const SizeType DerivativeRow)
523  {
524  const IndexType index = this->GetIndex(ControlPointIndexU, ControlPointIndexV, ControlPointIndexW, DerivativeRow);
525 
526  return mShapeFunctionValues[index];
527  }
528 
532 
533  int mDerivativeOrder;
534  NurbsCurveShapeFunction mShapeFunctionsU;
535  NurbsCurveShapeFunction mShapeFunctionsV;
536  NurbsCurveShapeFunction mShapeFunctionsW;
537  Vector mShapeFunctionValues;
538  IndexType mFirstNonzeroControlPointU;
539  IndexType mFirstNonzeroControlPointV;
540  IndexType mFirstNonzeroControlPointW;
542  }; // class NurbsVolumeShapeFunction
543 
544 } // namespace Kratos
545 
546 #endif // KRATOS_NURBS_VOLUME_SHAPE_FUNCTIONS_H_INCLUDED defined
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
void ResizeDataContainers(const SizeType PolynomialDegree, const SizeType DerivativeOrder)
Definition: nurbs_curve_shape_functions.h:79
void ComputeBSplineShapeFunctionValuesAtSpan(const Vector &rKnots, const IndexType Span, const double ParameterT)
Definition: nurbs_curve_shape_functions.h:188
SizeType NumberOfNonzeroControlPoints() const
Definition: nurbs_curve_shape_functions.h:108
SizeType PolynomialDegree() const
Definition: nurbs_curve_shape_functions.h:98
Definition: nurbs_volume_shape_functions.h:32
SizeType PolynomialDegreeU() const
Definition: nurbs_volume_shape_functions.h:161
double ShapeFunctionValue(const IndexType ControlPointIndex, const SizeType DerivativeOrder) const
Get shape function value for given CP-index and derivative row.
Definition: nurbs_volume_shape_functions.h:290
IndexType GetLastNonzeroControlPointW() const
Definition: nurbs_volume_shape_functions.h:330
NurbsVolumeShapeFunction()
Default constructor.
Definition: nurbs_volume_shape_functions.h:45
void ComputeNurbsShapeFunctionValuesAtSpan(const Vector &rKnotsU, const Vector &rKnotsV, const Vector &rKnotsW, const IndexType SpanU, const IndexType SpanV, const IndexType SpanW, const Vector &Weights, const double ParameterU, const double ParameterV, const double ParameterW)
Definition: nurbs_volume_shape_functions.h:407
static IndexType IndexOfShapeFunctionRow(const SizeType DerivativeOrderU, const SizeType DerivativeOrderV, const SizeType DerivativeOrderW)
Returns the index of the shape function row for the given derivative indices.
Definition: nurbs_volume_shape_functions.h:91
double operator()(const IndexType ControlPointIndexU, const IndexType ControlPointIndexV, const IndexType ControlPointIndexW, const IndexType DerivativeRow) const
Definition: nurbs_volume_shape_functions.h:127
void ComputeBSplineShapeFunctionValues(const Vector &rKnotsU, const Vector &rKnotsV, const Vector &rKnotsW, const double ParameterU, const double ParameterV, const double ParameterW)
Computes the shape function values at the given parameter.
Definition: nurbs_volume_shape_functions.h:383
IndexType GetFirstNonzeroControlPointU() const
Definition: nurbs_volume_shape_functions.h:305
std::size_t SizeType
Definition: nurbs_volume_shape_functions.h:38
IndexType GetFirstNonzeroControlPointW() const
Definition: nurbs_volume_shape_functions.h:325
IndexType GetLastNonzeroControlPointV() const
Definition: nurbs_volume_shape_functions.h:320
SizeType NumberOfShapeFunctionRows() const
Definition: nurbs_volume_shape_functions.h:181
SizeType PolynomialDegreeW() const
Definition: nurbs_volume_shape_functions.h:171
SizeType DerivativeOrder() const
Definition: nurbs_volume_shape_functions.h:176
std::vector< array_1d< int, 3 > > NonzeroControlPointIndices() const
Computes indices of the nonzero control points.
Definition: nurbs_volume_shape_functions.h:210
SizeType NumberOfNonzeroControlPointsU() const
Definition: nurbs_volume_shape_functions.h:186
void ComputeNurbsShapeFunctionValues(const Vector &rKnotsU, const Vector &rKnotsV, const Vector &rKnotsW, const Vector &Weights, const double ParameterU, const double ParameterV, const double ParameterW)
Definition: nurbs_volume_shape_functions.h:429
std::size_t IndexType
Definition: nurbs_volume_shape_functions.h:37
void ResizeDataContainers(const SizeType PolynomialDegreeU, const SizeType PolynomialDegreeV, const SizeType PolynomialDegreeW, const SizeType DerivativeOrder)
Prepares the required shape function data containers.
Definition: nurbs_volume_shape_functions.h:143
void ComputeBSplineShapeFunctionValuesAtSpan(const Vector &rKnotsU, const Vector &rKnotsV, const Vector &rKnotsW, const int SpanU, const int SpanV, const int SpanW, const double ParameterU, const double ParameterV, const double ParameterW)
Computes the shape function values at the given parameter and span.
Definition: nurbs_volume_shape_functions.h:338
std::vector< int > ControlPointIndices(SizeType NumberOfControlPointsU, SizeType NumberOfControlPointsV, SizeType NumberOfControlPointsW) const
Definition: nurbs_volume_shape_functions.h:240
double operator()(const IndexType ControlPointIndex, const IndexType DerivativeRow) const
Definition: nurbs_volume_shape_functions.h:120
NurbsVolumeShapeFunction(const SizeType PolynomialDegreeU, const SizeType PolynomialDegreeV, const SizeType PolynomialDegreeW, const SizeType DerivativeOrder)
Definition: nurbs_volume_shape_functions.h:51
SizeType NumberOfNonzeroControlPointsV() const
Definition: nurbs_volume_shape_functions.h:191
static SizeType NumberOfShapeFunctionRows(const SizeType DerivativeOrder)
Returns the number of shape function rows for a given order.
Definition: nurbs_volume_shape_functions.h:72
double ShapeFunctionValue(const IndexType ControlPointIndexU, const IndexType ControlPointIndexV, const IndexType ControlPointIndexW, const SizeType DerivativeRow) const
Get shape function value for given CP-indices and derivative row.
Definition: nurbs_volume_shape_functions.h:267
SizeType NumberOfNonzeroControlPoints() const
Definition: nurbs_volume_shape_functions.h:201
SizeType PolynomialDegreeV() const
Definition: nurbs_volume_shape_functions.h:166
IndexType GetFirstNonzeroControlPointV() const
Definition: nurbs_volume_shape_functions.h:315
IndexType GetLastNonzeroControlPointU() const
Definition: nurbs_volume_shape_functions.h:310
SizeType NumberOfNonzeroControlPointsW() const
Definition: nurbs_volume_shape_functions.h:196
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_DEBUG_ERROR_IF(conditional)
Definition: exception.h:171
#define KRATOS_WARNING(label)
Definition: logger.h:265
IndexType GetLowerSpan(const SizeType PolynomialDegree, const Vector &rKnots, const double ParameterT)
Definition: nurbs_utilities.h:64
SizeType GetNumberOfControlPoints(const SizeType PolynomialDegree, const SizeType NumberOfKnots)
Definition: nurbs_utilities.h:99
static constexpr IndexType GetVectorIndexFromMatrixIndices(const SizeType NumberPerRow, const SizeType NumberPerColumn, const IndexType RowIndex, const IndexType ColumnIndex) noexcept
Definition: nurbs_utilities.h:133
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17