3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BSPLINEBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BSPLINEBASIS_HH
16#include <dune/localfunctions/common/localbasis.hh>
18#include <dune/localfunctions/common/localkey.hh>
19#include <dune/localfunctions/common/localfiniteelementtraits.hh>
21#include <dune/functions/functionspacebases/nodes.hh>
22#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
23#include <dune/functions/functionspacebases/flatmultiindex.hh>
30template<
typename GV,
typename R,
typename MI>
31class BSplineLocalFiniteElement;
33template<
typename GV,
class MI>
45template<
class GV,
class R,
class MI>
50 typedef typename GV::ctype D;
51 enum {dim = GV::dimension};
64 : preBasis_(preBasis),
75 scaling_.
umv(in,globalIn);
77 preBasis_.evaluateFunction(globalIn, out, lFE_.currentKnotSpan_);
87 scaling_.
umv(in,globalIn);
89 preBasis_.evaluateJacobian(globalIn, out, lFE_.currentKnotSpan_);
91 for (
size_t i=0; i<out.size(); i++)
92 for (
int j=0; j<dim; j++)
93 out[i][0][j] *= scaling_[j][j];
98 inline void evaluate (
const typename std::array<int,k>& directions,
100 std::vector<typename Traits::RangeType>& out)
const
110 scaling_.
umv(in,globalIn);
112 preBasis_.evaluate(directions, globalIn, out, lFE_.currentKnotSpan_);
114 for (
size_t i=0; i<out.size(); i++)
115 out[i][0] *= scaling_[directions[0]][directions[0]];
121 scaling_.
umv(in,globalIn);
123 preBasis_.evaluate(directions, globalIn, out, lFE_.currentKnotSpan_);
125 for (
size_t i=0; i<out.size(); i++)
126 out[i][0] *= scaling_[directions[0]][directions[0]]*scaling_[directions[1]][directions[1]];
143 return *std::max_element(preBasis_.order_.begin(), preBasis_.order_.end());
181 std::array<unsigned int,dim> multiindex (
unsigned int i)
const
183 std::array<unsigned int,dim> alpha;
184 for (
int j=0; j<dim; j++)
186 alpha[j] = i % sizes_[j];
193 void setup1d(std::vector<unsigned int>& subEntity)
204 unsigned lastIndex=0;
205 subEntity[lastIndex++] = 0;
206 for (
unsigned i = 0; i < sizes_[0] - 2; ++i)
207 subEntity[lastIndex++] = 0;
209 subEntity[lastIndex++] = 1;
211 assert(
size()==lastIndex);
214 void setup2d(std::vector<unsigned int>& subEntity)
216 unsigned lastIndex=0;
230 subEntity[lastIndex++] = 0;
231 for (
unsigned i = 0; i < sizes_[0]-2; ++i)
232 subEntity[lastIndex++] = 2;
234 subEntity[lastIndex++] = 1;
237 for (
unsigned e = 0; e < sizes_[1]-2; ++e)
239 subEntity[lastIndex++] = 0;
240 for (
unsigned i = 0; i < sizes_[0]-2; ++i)
241 subEntity[lastIndex++] = 0;
242 subEntity[lastIndex++] = 1;
246 subEntity[lastIndex++] = 2;
247 for (
unsigned i = 0; i < sizes_[0]-2; ++i)
248 subEntity[lastIndex++] = 3;
250 subEntity[lastIndex++] = 3;
252 assert(
size()==lastIndex);
257 void init(
const std::array<unsigned,dim>& sizes)
264 std::vector<unsigned int> codim(li_.size());
266 for (std::size_t i=0; i<codim.size(); i++)
271 std::array<unsigned int,dim> mIdx = multiindex(i);
272 for (
int j=0; j<dim; j++)
273 if (mIdx[j]==0 or mIdx[j]==sizes[j]-1)
282 std::vector<unsigned int> index(
size());
284 for (std::size_t i=0; i<index.size(); i++)
288 std::array<unsigned int,dim> mIdx = multiindex(i);
290 for (
int j=dim-1; j>=0; j--)
291 if (mIdx[j]>0 and mIdx[j]<sizes[j]-1)
292 index[i] = (sizes[j]-1)*index[i] + (mIdx[j]-1);
296 std::vector<unsigned int> subEntity(li_.size());
298 if (subEntity.size() > 0)
304 }
else if (dim==2 and sizes_[0]>1 and sizes_[1]>1) {
311 for (
size_t i=0; i<li_.size(); i++)
312 li_[i] =
LocalKey(subEntity[i], codim[i], index[i]);
318 return std::accumulate(sizes_.begin(), sizes_.end(), 1, std::multiplies<unsigned int>());
330 std::array<unsigned, dim> sizes_;
332 std::vector<LocalKey> li_;
339template<
int dim,
class LB>
344 template<
typename F,
typename C>
362template<
class GV,
class R,
class MI>
365 typedef typename GV::ctype D;
366 enum {dim = GV::dimension};
379 : preBasis_(preBasis),
380 localBasis_(preBasis,*this)
386 : preBasis_(other.preBasis_),
387 localBasis_(preBasis_,*this)
396 void bind(
const std::array<unsigned,dim>& elementIdx)
399 for (
size_t i=0; i<elementIdx.size(); i++)
401 currentKnotSpan_[i] = 0;
404 while (preBasis_.knotVectors_[i][currentKnotSpan_[i]+1] < preBasis_.knotVectors_[i][currentKnotSpan_[i]]+1e-8)
405 currentKnotSpan_[i]++;
407 for (
size_t j=0; j<elementIdx[i]; j++)
409 currentKnotSpan_[i]++;
412 while (preBasis_.knotVectors_[i][currentKnotSpan_[i]+1] < preBasis_.knotVectors_[i][currentKnotSpan_[i]]+1e-8)
413 currentKnotSpan_[i]++;
417 localBasis_.offset_[i] = preBasis_.knotVectors_[i][currentKnotSpan_[i]];
418 localBasis_.scaling_[i][i] = preBasis_.knotVectors_[i][currentKnotSpan_[i]+1] - preBasis_.knotVectors_[i][currentKnotSpan_[i]];
422 std::array<unsigned int, dim> sizes;
423 for (
size_t i=0; i<dim; i++)
425 localCoefficients_.init(sizes);
437 return localCoefficients_;
443 return localInterpolation_;
450 for (
int i=0; i<dim; i++)
467 const auto& order = preBasis_.order_;
468 unsigned int r = order[i]+1;
469 if (currentKnotSpan_[i]<order[i])
470 r -= (order[i] - currentKnotSpan_[i]);
471 if ( order[i] > (preBasis_.knotVectors_[i].size() - currentKnotSpan_[i] - 2) )
472 r -= order[i] - (preBasis_.knotVectors_[i].size() - currentKnotSpan_[i] - 2);
483 std::array<unsigned,dim> currentKnotSpan_;
487template<
typename GV,
typename MI>
500template<
typename GV,
class MI>
503 static const int dim = GV::dimension;
506 class MultiDigitCounter
513 MultiDigitCounter(
const std::array<unsigned int,dim>& limits)
516 std::fill(counter_.begin(), counter_.end(), 0);
520 MultiDigitCounter& operator++()
522 for (
int i=0; i<dim; i++)
527 if (counter_[i] < limits_[i])
536 const unsigned int& operator[](
int i)
const
542 unsigned int cycle()
const
545 for (
int i=0; i<dim; i++)
553 const std::array<unsigned int,dim> limits_;
556 std::array<unsigned int,dim> counter_;
564 using size_type = std::size_t;
566 using Node = BSplineNode<GV, MI>;
569 using IndexSet = Impl::DefaultNodeIndexSet<BSplinePreBasis>;
598 const std::vector<double>& knotVector,
600 bool makeOpen =
true)
610 for (
int i=0; i<dim; i++)
615 for (
unsigned int j=0; j<order; j++)
621 for (
unsigned int j=0; j<order; j++)
652 const std::array<unsigned int,dim>& elements,
654 bool makeOpen =
true)
662 for (
int i=0; i<dim; i++)
667 for (
unsigned int j=0; j<order; j++)
671 for (
size_t j=0; j<elements[i]+1; j++)
675 for (
unsigned int j=0; j<order; j++)
713 [[deprecated(
"Warning: The IndexSet typedef and the makeIndexSet method are deprecated. "\
714 "As a replacement use the indices() method of the PreBasis directly.")]]
723 assert(prefix.
size() == 0 || prefix.
size() == 1);
724 return (prefix.
size() == 0) ?
size() : 0;
736 size_type result = 1;
737 for (
int i=0; i<dim; i++)
743 template<
typename It>
748 std::array<unsigned int, dim> localSizes;
749 for (
int i=0; i<dim; i++)
750 localSizes[i] = node.finiteElement().size(i);
751 for (size_type i = 0, end = node.size() ; i < end ; ++i, ++it)
753 std::array<unsigned int,dim> localIJK =
getIJK(i, localSizes);
755 const auto currentKnotSpan = node.finiteElement().currentKnotSpan_;
756 const auto order =
order_;
758 std::array<unsigned int,dim> globalIJK;
759 for (
int i=0; i<dim; i++)
760 globalIJK[i] =
std::max((
int)currentKnotSpan[i] - (
int)order[i], 0) + localIJK[i];
763 size_type globalIdx = globalIJK[dim-1];
765 for (
int i=dim-2; i>=0; i--)
766 globalIdx = globalIdx *
size(i) + globalIJK[i];
776 unsigned int result = 1;
777 for (
size_t i=0; i<dim; i++)
783 unsigned int size (
size_t d)
const
792 const std::array<unsigned,dim>& currentKnotSpan)
const
795 std::array<std::vector<R>, dim> oneDValues;
797 for (
size_t i=0; i<dim; i++)
800 std::array<unsigned int, dim> limits;
801 for (
int i=0; i<dim; i++)
802 limits[i] = oneDValues[i].
size();
804 MultiDigitCounter ijkCounter(limits);
806 out.resize(ijkCounter.cycle());
808 for (
size_t i=0; i<out.size(); i++, ++ijkCounter)
811 for (
size_t j=0; j<dim; j++)
812 out[i] *= oneDValues[j][ijkCounter[j]];
823 const std::array<unsigned,dim>& currentKnotSpan)
const
826 std::array<unsigned int, dim> limits;
827 for (
int i=0; i<dim; i++)
830 if (currentKnotSpan[i]<
order_[i])
831 limits[i] -= (
order_[i] - currentKnotSpan[i]);
837 std::array<unsigned int, dim> offset;
838 for (
int i=0; i<dim; i++)
842 std::array<std::vector<R>, dim> oneDValues;
845 std::array<std::vector<R>, dim> lowOrderOneDValues;
847 std::array<DynamicMatrix<R>, dim> values;
849 for (
size_t i=0; i<dim; i++)
853 for (
size_t j=0; j<oneDValues[i].size(); j++)
854 oneDValues[i][j] = values[i][
order_[i]][j];
859 for (
size_t j=0; j<lowOrderOneDValues[i].size(); j++)
860 lowOrderOneDValues[i][j] = values[i][
order_[i]-1][j];
866 std::array<std::vector<R>, dim> oneDDerivatives;
867 for (
size_t i=0; i<dim; i++)
869 oneDDerivatives[i].resize(limits[i]);
872 std::fill(oneDDerivatives[i].begin(), oneDDerivatives[i].end(), R(0.0));
875 for (
size_t j=offset[i]; j<offset[i]+limits[i]; j++)
880 if (std::isnan(derivativeAddend1))
881 derivativeAddend1 = 0;
882 if (std::isnan(derivativeAddend2))
883 derivativeAddend2 = 0;
884 oneDDerivatives[i][j-offset[i]] =
order_[i] * ( derivativeAddend1 - derivativeAddend2 );
891 std::array<std::vector<R>, dim> oneDValuesShort;
893 for (
int i=0; i<dim; i++)
895 oneDValuesShort[i].resize(limits[i]);
897 for (
size_t j=0; j<limits[i]; j++)
898 oneDValuesShort[i][j] = oneDValues[i][offset[i] + j];
904 MultiDigitCounter ijkCounter(limits);
906 out.resize(ijkCounter.cycle());
909 for (
size_t i=0; i<out.size(); i++, ++ijkCounter)
910 for (
int j=0; j<dim; j++)
913 for (
int k=0; k<dim; k++)
914 out[i][0][j] *= (j==k) ? oneDDerivatives[k][ijkCounter[k]]
915 : oneDValuesShort[k][ijkCounter[k]];
921 template <
size_type k>
922 void evaluate(
const typename std::array<int,k>& directions,
925 const std::array<unsigned,dim>& currentKnotSpan)
const
927 if (k != 1 && k != 2)
931 std::array<std::vector<R>, dim> oneDValues;
932 std::array<std::vector<R>, dim> oneDDerivatives;
933 std::array<std::vector<R>, dim> oneDSecondDerivatives;
937 for (
size_t i=0; i<dim; i++)
938 evaluateAll(in[i], oneDValues[i],
true, oneDDerivatives[i],
false, oneDSecondDerivatives[i],
knotVectors_[i],
order_[i], currentKnotSpan[i]);
940 for (
size_t i=0; i<dim; i++)
944 std::array<unsigned int, dim> offset;
945 for (
int i=0; i<dim; i++)
949 std::array<unsigned int, dim> limits;
950 for (
int i=0; i<dim; i++)
955 if (currentKnotSpan[i]<
order_[i])
956 limits[i] -= (
order_[i] - currentKnotSpan[i]);
963 std::array<std::vector<R>, dim> oneDValuesShort;
965 for (
int i=0; i<dim; i++)
967 oneDValuesShort[i].resize(limits[i]);
969 for (
size_t j=0; j<limits[i]; j++)
970 oneDValuesShort[i][j] = oneDValues[i][offset[i] + j];
974 MultiDigitCounter ijkCounter(limits);
976 out.resize(ijkCounter.cycle());
981 for (
size_t i=0; i<out.size(); i++, ++ijkCounter)
984 for (
int l=0; l<dim; l++)
985 out[i][0] *= (directions[0]==l) ? oneDDerivatives[l][ijkCounter[l]]
986 : oneDValuesShort[l][ijkCounter[l]];
993 for (
size_t i=0; i<out.size(); i++, ++ijkCounter)
996 for (
int j=0; j<dim; j++)
998 if (directions[0] != directions[1])
999 if (directions[0] == j || directions[1] == j)
1000 out[i][0] *= oneDDerivatives[j][ijkCounter[j]];
1002 out[i][0] *= oneDValuesShort[j][ijkCounter[j]];
1004 if (directions[0] == j)
1005 out[i][0] *= oneDSecondDerivatives[j][ijkCounter[j]];
1007 out[i][0] *= oneDValuesShort[j][ijkCounter[j]];
1018 static std::array<unsigned int,dim>
getIJK(
typename GridView::IndexSet::IndexType idx, std::array<unsigned int,dim> elements)
1020 std::array<unsigned,dim> result;
1021 for (
int i=0; i<dim; i++)
1023 result[i] = idx%elements[i];
1038 const std::vector<R>& knotVector,
1040 unsigned int currentKnotSpan)
1042 std::size_t outSize = order+1;
1043 if (currentKnotSpan<order)
1044 outSize -= (order - currentKnotSpan);
1045 if ( order > (knotVector.size() - currentKnotSpan - 2) )
1046 outSize -= order - (knotVector.size() - currentKnotSpan - 2);
1047 out.resize(outSize);
1058 for (
size_t i=0; i<knotVector.size()-1; i++)
1059 N[0][i] = (i == currentKnotSpan);
1061 for (
size_t r=1; r<=order; r++)
1062 for (
size_t i=0; i<knotVector.size()-r-1; i++)
1064 R factor1 = ((knotVector[i+r] - knotVector[i]) > 1e-10)
1065 ? (in - knotVector[i]) / (knotVector[i+r] - knotVector[i])
1067 R factor2 = ((knotVector[i+r+1] - knotVector[i+1]) > 1e-10)
1068 ? (knotVector[i+r+1] - in) / (knotVector[i+r+1] - knotVector[i+1])
1070 N[r][i] = factor1 * N[r-1][i] + factor2 * N[r-1][i+1];
1077 for (
size_t i=0; i<out.size(); i++) {
1078 out[i] = N[order][
std::max((
int)(currentKnotSpan - order),0) + i];
1096 const std::vector<R>& knotVector,
1098 unsigned int currentKnotSpan)
1103 N.
resize(order+1, knotVector.size()-1);
1111 for (
size_t i=0; i<knotVector.size()-1; i++)
1112 N[0][i] = (i == currentKnotSpan);
1114 for (
size_t r=1; r<=order; r++)
1115 for (
size_t i=0; i<knotVector.size()-r-1; i++)
1117 R factor1 = ((knotVector[i+r] - knotVector[i]) > 1e-10)
1118 ? (in - knotVector[i]) / (knotVector[i+r] - knotVector[i])
1120 R factor2 = ((knotVector[i+r+1] - knotVector[i+1]) > 1e-10)
1121 ? (knotVector[i+r+1] - in) / (knotVector[i+r+1] - knotVector[i+1])
1123 N[r][i] = factor1 * N[r-1][i] + factor2 * N[r-1][i+1];
1138 std::vector<R>& out,
1140 bool evaluateHessian, std::vector<R>& outHess,
1141 const std::vector<R>& knotVector,
1143 unsigned int currentKnotSpan)
1148 if (currentKnotSpan<order)
1149 limit -= (order - currentKnotSpan);
1150 if ( order > (knotVector.size() - currentKnotSpan - 2) )
1151 limit -= order - (knotVector.size() - currentKnotSpan - 2);
1154 unsigned int offset;
1155 offset =
std::max((
int)(currentKnotSpan - order),0);
1162 out.resize(knotVector.size()-order-1);
1163 for (
size_t j=0; j<out.size(); j++)
1164 out[j] = values[order][j];
1167 std::vector<R> lowOrderOneDValues;
1171 lowOrderOneDValues.
resize(knotVector.size()-(order-1)-1);
1172 for (
size_t j=0; j<lowOrderOneDValues.size(); j++)
1173 lowOrderOneDValues[j] = values[order-1][j];
1177 std::vector<R> lowOrderTwoDValues;
1179 if (order>1 && evaluateHessian)
1181 lowOrderTwoDValues.
resize(knotVector.size()-(order-2)-1);
1182 for (
size_t j=0; j<lowOrderTwoDValues.size(); j++)
1183 lowOrderTwoDValues[j] = values[order-2][j];
1192 std::fill(outJac.begin(), outJac.end(), R(0.0));
1195 for (
size_t j=offset; j<offset+limit; j++)
1197 R derivativeAddend1 = lowOrderOneDValues[j] / (knotVector[j+order]-knotVector[j]);
1198 R derivativeAddend2 = lowOrderOneDValues[j+1] / (knotVector[j+order+1]-knotVector[j+1]);
1200 if (std::isnan(derivativeAddend1))
1201 derivativeAddend1 = 0;
1202 if (std::isnan(derivativeAddend2))
1203 derivativeAddend2 = 0;
1204 outJac[j-offset] = order * ( derivativeAddend1 - derivativeAddend2 );
1210 if (evaluateHessian)
1212 outHess.resize(limit);
1215 std::fill(outHess.begin(), outHess.end(), R(0.0));
1218 for (
size_t j=offset; j<offset+limit; j++)
1220 assert(j+2 < lowOrderTwoDValues.size());
1221 R derivativeAddend1 = lowOrderTwoDValues[j] / (knotVector[j+order]-knotVector[j]) / (knotVector[j+order-1]-knotVector[j]);
1222 R derivativeAddend2 = lowOrderTwoDValues[j+1] / (knotVector[j+order]-knotVector[j]) / (knotVector[j+order]-knotVector[j+1]);
1223 R derivativeAddend3 = lowOrderTwoDValues[j+1] / (knotVector[j+order+1]-knotVector[j+1]) / (knotVector[j+order]-knotVector[j+1]);
1224 R derivativeAddend4 = lowOrderTwoDValues[j+2] / (knotVector[j+order+1]-knotVector[j+1]) / (knotVector[j+1+order]-knotVector[j+2]);
1227 if (std::isnan(derivativeAddend1))
1228 derivativeAddend1 = 0;
1229 if (std::isnan(derivativeAddend2))
1230 derivativeAddend2 = 0;
1231 if (std::isnan(derivativeAddend3))
1232 derivativeAddend3 = 0;
1233 if (std::isnan(derivativeAddend4))
1234 derivativeAddend4 = 0;
1235 outHess[j-offset] = order * (order-1) * ( derivativeAddend1 - derivativeAddend2 -derivativeAddend3 + derivativeAddend4 );
1256template<
typename GV,
typename MI>
1258 public LeafBasisNode
1260 static const int dim = GV::dimension;
1264 using size_type = std::size_t;
1269 preBasis_(preBasis),
1270 finiteElement_(*preBasis)
1274 const Element& element()
const
1283 const FiniteElement& finiteElement()
const
1285 return finiteElement_;
1289 void bind(
const Element& e)
1292 auto elementIndex = preBasis_->gridView().indexSet().index(e);
1293 finiteElement_.bind(preBasis_->getIJK(elementIndex,preBasis_->elements_));
1294 this->setSize(finiteElement_.size());
1299 const BSplinePreBasis<GV,MI>* preBasis_;
1301 FiniteElement finiteElement_;
1307namespace BasisFactory {
1311class BSplinePreBasisFactory
1314 static const std::size_t requiredMultiIndexSize=1;
1316 BSplinePreBasisFactory(
const std::vector<double>& knotVector,
1318 bool makeOpen =
true)
1319 : knotVector_(knotVector),
1324 template<
class MultiIndex,
class Gr
idView>
1325 auto makePreBasis(
const GridView& gridView)
const
1327 return BSplinePreBasis<GridView, MultiIndex>(gridView, knotVector_, order_, makeOpen_);
1331 const std::vector<double>& knotVector_;
1332 unsigned int order_;
1344auto bSpline(
const std::vector<double>& knotVector,
1346 bool makeOpen =
true)
1348 return Imp::BSplinePreBasisFactory(knotVector, order, makeOpen);
1363template<
typename GV>
Construct a matrix with a dynamic size.
Definition: dynmatrix.hh:59
void resize(size_type r, size_type c, value_type v=value_type())
resize matrix to r × c
Definition: dynmatrix.hh:104
A dense n x m matrix.
Definition: fmatrix.hh:69
vector space out of a tensor product of fields.
Definition: fvector.hh:95
LocalBasis class in the sense of dune-localfunctions, presenting the restriction of a B-spline patch ...
Definition: bsplinebasis.hh:47
LocalBasisTraits< D, dim, FieldVector< D, dim >, R, 1, FieldVector< R, 1 >, FieldMatrix< R, 1, dim > > Traits
export type traits for function signature
Definition: bsplinebasis.hh:56
BSplineLocalBasis(const BSplinePreBasis< GV, MI > &preBasis, const BSplineLocalFiniteElement< GV, R, MI > &lFE)
Constructor with a given B-spline patch.
Definition: bsplinebasis.hh:62
void evaluateFunction(const FieldVector< D, dim > &in, std::vector< FieldVector< R, 1 > > &out) const
Evaluate all shape functions.
Definition: bsplinebasis.hh:71
void evaluate(const typename std::array< int, k > &directions, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions and derivatives of any order.
Definition: bsplinebasis.hh:98
unsigned int order() const
Polynomial order of the shape functions.
Definition: bsplinebasis.hh:141
void evaluateJacobian(const FieldVector< D, dim > &in, std::vector< FieldMatrix< D, 1, dim > > &out) const
Evaluate Jacobian of all shape functions.
Definition: bsplinebasis.hh:83
std::size_t size() const
Return the number of basis functions on the current knot span.
Definition: bsplinebasis.hh:148
Attaches a shape function to an entity.
Definition: bsplinebasis.hh:179
const LocalKey & localKey(std::size_t i) const
get i'th index
Definition: bsplinebasis.hh:322
std::size_t size() const
number of coefficients
Definition: bsplinebasis.hh:316
LocalFiniteElement in the sense of dune-localfunctions, for the B-spline basis on tensor-product grid...
Definition: bsplinebasis.hh:364
const BSplineLocalBasis< GV, R, MI > & localBasis() const
Hand out a LocalBasis object.
Definition: bsplinebasis.hh:429
unsigned size() const
Number of shape functions in this finite element.
Definition: bsplinebasis.hh:447
GeometryType type() const
Return the reference element that the local finite element is defined on (here, a hypercube)
Definition: bsplinebasis.hh:457
void bind(const std::array< unsigned, dim > &elementIdx)
Bind LocalFiniteElement to a specific knot span of the spline patch.
Definition: bsplinebasis.hh:396
LocalFiniteElementTraits< BSplineLocalBasis< GV, R, MI >, BSplineLocalCoefficients< dim >, BSplineLocalInterpolation< dim, BSplineLocalBasis< GV, R, MI > > > Traits
Export various types related to this LocalFiniteElement.
Definition: bsplinebasis.hh:374
const BSplineLocalCoefficients< dim > & localCoefficients() const
Hand out a LocalCoefficients object.
Definition: bsplinebasis.hh:435
const BSplineLocalInterpolation< dim, BSplineLocalBasis< GV, R, MI > > & localInterpolation() const
Hand out a LocalInterpolation object.
Definition: bsplinebasis.hh:441
BSplineLocalFiniteElement(const BSplineLocalFiniteElement &other)
Copy constructor.
Definition: bsplinebasis.hh:385
BSplineLocalFiniteElement(const BSplinePreBasis< GV, MI > &preBasis)
Constructor with a given B-spline basis.
Definition: bsplinebasis.hh:378
unsigned int size(int i) const
Number of degrees of freedom for one coordinate direction.
Definition: bsplinebasis.hh:465
Local interpolation in the sense of dune-localfunctions, for the B-spline basis on tensor-product gri...
Definition: bsplinebasis.hh:341
void interpolate(const F &f, std::vector< C > &out) const
Local interpolation of a function.
Definition: bsplinebasis.hh:345
Pre-basis for B-spline basis.
Definition: bsplinebasis.hh:502
GV GridView
The grid view that the FE space is defined on.
Definition: bsplinebasis.hh:563
unsigned int size(size_t d) const
Number of shape functions in one direction.
Definition: bsplinebasis.hh:783
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: bsplinebasis.hh:728
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: bsplinebasis.hh:693
void evaluateJacobian(const FieldVector< typename GV::ctype, dim > &in, std::vector< FieldMatrix< R, 1, dim > > &out, const std::array< unsigned, dim > ¤tKnotSpan) const
Evaluate Jacobian of all B-spline basis functions.
Definition: bsplinebasis.hh:821
static void evaluateFunction(const typename GV::ctype &in, std::vector< R > &out, const std::vector< R > &knotVector, unsigned int order, unsigned int currentKnotSpan)
Evaluate all one-dimensional B-spline functions for a given coordinate direction.
Definition: bsplinebasis.hh:1037
BSplinePreBasis(const GridView &gridView, const std::vector< double > &knotVector, unsigned int order, bool makeOpen=true)
Construct a B-spline basis for a given grid view and set of knot vectors.
Definition: bsplinebasis.hh:597
unsigned int size() const
Total number of B-spline basis functions.
Definition: bsplinebasis.hh:774
size_type size(const SizePrefix prefix) const
Return number of possible values for next position in multi index.
Definition: bsplinebasis.hh:721
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: bsplinebasis.hh:572
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: bsplinebasis.hh:734
void initializeIndices()
Initialize the global indices.
Definition: bsplinebasis.hh:683
std::array< unsigned, dim > elements_
Number of grid elements in the different coordinate directions.
Definition: bsplinebasis.hh:1249
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: bsplinebasis.hh:687
It indices(const Node &node, It it) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis.
Definition: bsplinebasis.hh:744
static void evaluateAll(const typename GV::ctype &in, std::vector< R > &out, bool evaluateJacobian, std::vector< R > &outJac, bool evaluateHessian, std::vector< R > &outHess, const std::vector< R > &knotVector, unsigned int order, unsigned int currentKnotSpan)
Evaluate the second derivatives of all one-dimensional B-spline functions for a given coordinate dire...
Definition: bsplinebasis.hh:1137
void evaluateFunction(const FieldVector< typename GV::ctype, dim > &in, std::vector< FieldVector< R, 1 > > &out, const std::array< unsigned, dim > ¤tKnotSpan) const
Evaluate all B-spline basis functions at a given point.
Definition: bsplinebasis.hh:790
BSplinePreBasis(const GridView &gridView, const FieldVector< double, dim > &lowerLeft, const FieldVector< double, dim > &upperRight, const std::array< unsigned int, dim > &elements, unsigned int order, bool makeOpen=true)
Construct a B-spline basis for a given grid view with uniform knot vectors.
Definition: bsplinebasis.hh:649
Impl::DefaultNodeIndexSet< BSplinePreBasis > IndexSet
Type of created tree node index set.
Definition: bsplinebasis.hh:569
static void evaluateFunctionFull(const typename GV::ctype &in, DynamicMatrix< R > &out, const std::vector< R > &knotVector, unsigned int order, unsigned int currentKnotSpan)
Evaluate all one-dimensional B-spline functions for a given coordinate direction.
Definition: bsplinebasis.hh:1094
static std::array< unsigned int, dim > getIJK(typename GridView::IndexSet::IndexType idx, std::array< unsigned int, dim > elements)
Compute integer element coordinates from the element index.
Definition: bsplinebasis.hh:1018
IndexSet makeIndexSet() const
Create tree node index set.
Definition: bsplinebasis.hh:715
void evaluate(const typename std::array< int, k > &directions, const FieldVector< typename GV::ctype, dim > &in, std::vector< FieldVector< R, 1 > > &out, const std::array< unsigned, dim > ¤tKnotSpan) const
Evaluate Derivatives of all B-spline basis functions.
Definition: bsplinebasis.hh:922
Node makeNode() const
Create tree node.
Definition: bsplinebasis.hh:701
std::array< std::vector< double >, dim > knotVectors_
The knot vectors, one for each space dimension.
Definition: bsplinebasis.hh:1246
std::array< unsigned int, dim > order_
Order of the B-spline for each space dimension.
Definition: bsplinebasis.hh:1243
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:47
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:123
Describe position of one degree of freedom.
Definition: localkey.hh:21
Default exception for dummy implementations.
Definition: exceptions.hh:261
Default exception class for range errors.
Definition: exceptions.hh:252
A Vector class with statically reserved memory.
Definition: reservedvector.hh:43
size_type size() const
Returns number of elements in the vector.
Definition: reservedvector.hh:184
This file implements a quadratic diagonal matrix of fixed size.
This file implements a dense matrix with dynamic numbers of rows and columns.
void umv(const X &x, Y &y) const
y += A x
Definition: diagonalmatrix.hh:295
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
auto bSpline(const std::vector< double > &knotVector, unsigned int order, bool makeOpen=true)
Create a pre-basis factory that can create a B-spline pre-basis.
Definition: bsplinebasis.hh:1344
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:470
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:289
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:79
constexpr HybridTreePath< T..., std::size_t > push_back(const HybridTreePath< T... > &tp, std::size_t i)
Appends a run time index to a HybridTreePath.
Definition: treepath.hh:278
Dune namespace.
Definition: alignedallocator.hh:11
Static tag representing a codimension.
Definition: dimension.hh:22
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:32
D DomainType
domain type
Definition: localbasis.hh:43
traits helper struct
Definition: localfiniteelementtraits.hh:11
A unique label for each type of element that can occur in a grid.