43 #define OPTIMIZED_VERSION_A4dot4 49 for (
int j = 0; j <
nsd; j++ ) {
69 int *indexKnotVec, indexKnotVal;
78 for (
int i = 0; i <
nsd; i++ ) {
79 if (
degree [ i ] > max_deg ) {
91 for (
int n = 0; n <
nsd; n++ ) {
92 localIndexKnotVector_tmp.
clear();
93 IR_GIVE_FIELD(ir, localIndexKnotVector_tmp, IFT_localIndexKnotVector [ n ]);
94 if ( localIndexKnotVector_tmp.
giveSize() != totalNumberOfControlPoints * (
degree [ n ] + 2 ) ) {
95 OOFEM_WARNING(
"invalid size of knot vector %s", IFT_localIndexKnotVector [ n ]);
104 for (
int j = 0; j < degree [ n ] + 2; j++ ) {
105 indexKnotVec [ p++ ] = localIndexKnotVector_tmp(pos++);
109 indexKnotVal = indexKnotVec [ 0 ];
110 for (
int j = 1; j < degree [ n ] + 2; j++ ) {
111 if ( indexKnotVal > indexKnotVec [ j ] ) {
112 OOFEM_WARNING(
"local index knot vector %s of control point %d is not monotonic",
113 IFT_localIndexKnotVector [ n ], i + 1);
122 indexKnotVal = indexKnotVec [ j ];
126 if ( indexKnotVal == indexKnotVec [ 0 ] ) {
127 OOFEM_WARNING(
"local index knot vector %s of control point %d is degenerated",
128 IFT_localIndexKnotVector [ n ], i + 1);
133 if ( indexKnotVec [ 0 ] <= 0 || indexKnotVal >
knotValues [ n ].giveSize() ) {
134 OOFEM_WARNING(
"local index knot vector %s of control point %d out of range",
135 IFT_localIndexKnotVector [ n ], i + 1);
151 double sum = 0.0, val;
161 for (
int i = 0; i <
nsd; i++ ) {
172 for (
int k = 0; k < count; k++ ) {
173 for (
int i = 0; i <
nsd; i++ ) {
183 answer.
at(count--) /= sum;
196 double Jacob = 0., product, w, xw, yw, weight;
198 std :: vector< FloatArray > tmp_ders(
nsd);
199 std :: vector< FloatMatrix > ders(
nsd);
214 for (
int i = 0; i <
nsd; i++ ) {
224 for (
int i = 0; i <
nsd; i++ ) {
225 ders [ i ].resize(2, count);
235 for (
int i = 0; i <
nsd; i++ ) {
244 for (
int k = 0; k < count; k++ ) {
245 for (
int i = 0; i <
nsd; i++ ) {
248 ders [ i ](0, k) = tmp_ders [ i ](0);
249 ders [ i ](1, k) = tmp_ders [ i ](1);
255 w = vertexCoordsPtr->
at(3);
256 xw = vertexCoordsPtr->
at(1) * w;
257 yw = vertexCoordsPtr->
at(2) * w;
259 product = tmp_ders [ 0 ](0) * tmp_ders [ 1 ](0);
260 Aders [ 0 ](0, 0) += product * xw;
261 Aders [ 1 ](0, 0) += product * yw;
262 wders(0, 0) += product * w;
264 product = tmp_ders [ 0 ](1) * tmp_ders [ 1 ](0);
265 Aders [ 0 ](1, 0) += product * xw;
266 Aders [ 1 ](1, 0) += product * yw;
267 wders(1, 0) += product * w;
269 product = tmp_ders [ 0 ](0) * tmp_ders [ 1 ](1);
270 Aders [ 0 ](0, 1) += product * xw;
271 Aders [ 1 ](0, 1) += product * yw;
272 wders(0, 1) += product * w;
275 weight = wders(0, 0);
292 temp(0) = Aders [ 0 ](0, 0) / weight;
293 temp(1) = Aders [ 1 ](0, 0) / weight;
294 jacobian(1, 0) = ( Aders [ 0 ](0, 1) - wders(0, 1) * temp(0) ) / weight;
295 jacobian(1, 1) = ( Aders [ 1 ](0, 1) - wders(0, 1) * temp(1) ) / weight;
296 jacobian(0, 0) = ( Aders [ 0 ](1, 0) - wders(1, 0) * temp(0) ) / weight;
297 jacobian(0, 1) = ( Aders [ 1 ](1, 0) - wders(1, 0) * temp(1) ) / weight;
302 product = Jacob * weight * weight;
304 for (
int k = 0; k < count; k++ ) {
307 temp(0) = ders [ 0 ](1, k) * ders [ 1 ](0, k) * w * weight - ders [ 0 ](0, k) * ders [ 1 ](0, k) * w * wders(1, 0);
309 temp(1) = ders [ 0 ](0, k) * ders [ 1 ](1, k) * w * weight - ders [ 0 ](0, k) * ders [ 1 ](0, k) * w * wders(0, 1);
311 answer(k, 0) = ( jacobian(1, 1) * temp(0) - jacobian(0, 1) * temp(1) ) / product;
312 answer(k, 1) = ( -jacobian(1, 0) * temp(0) + jacobian(0, 0) * temp(1) ) / product;
328 double w, xw, yw, product, weight = 0.0;
338 for (
int i = 0; i <
nsd; i++ ) {
351 for (
int k = 0; k < count; k++ ) {
352 for (
int i = 0; i <
nsd; i++ ) {
357 w = vertexCoordsPtr->
at(3);
358 xw = vertexCoordsPtr->
at(1) * w;
359 yw = vertexCoordsPtr->
at(2) * w;
361 product =
N(0) *
N(1);
362 answer(0) += product * xw;
363 answer(1) += product * yw;
364 weight += product * w;
368 answer.
times(1.0 / weight);
382 double w, xw, yw, product, weight;
384 std :: vector< FloatArray > ders(
nsd);
400 for (
int i = 0; i <
nsd; i++ ) {
416 for (
int i = 0; i <
nsd; i++ ) {
425 for (
int k = 0; k < count; k++ ) {
426 for (
int i = 0; i <
nsd; i++ ) {
433 w = vertexCoordsPtr->
at(3);
434 xw = vertexCoordsPtr->
at(1) * w;
435 yw = vertexCoordsPtr->
at(2) * w;
437 product = ders [ 0 ](0) * ders [ 1 ](0);
438 Aders [ 0 ](0, 0) += product * xw;
439 Aders [ 1 ](0, 0) += product * yw;
440 wders(0, 0) += product * w;
442 product = ders [ 0 ](1) * ders [ 1 ](0);
443 Aders [ 0 ](1, 0) += product * xw;
444 Aders [ 1 ](1, 0) += product * yw;
445 wders(1, 0) += product * w;
447 product = ders [ 0 ](0) * ders [ 1 ](1);
448 Aders [ 0 ](0, 1) += product * xw;
449 Aders [ 1 ](0, 1) += product * yw;
450 wders(0, 1) += product * w;
453 weight = wders(0, 0);
457 Sders[0](0,0) = Aders[0](0,0) / weight;
458 Sders[1](0,0) = Aders[1](0,0) / weight;
459 Sders[0](0,1) = (Aders[0](0,1)-wders(0,1)*Sders[0](0,0)) / weight;
460 Sders[1](0,1) = (Aders[1](0,1)-wders(0,1)*Sders[1](0,0)) / weight;
461 Sders[0](1,0) = (Aders[0](1,0)-wders(1,0)*Sders[0](0,0)) / weight;
462 Sders[1](1,0) = (Aders[1](1,0)-wders(1,0)*Sders[1](0,0)) / weight;
464 jacobian(0,0) = Sders[0](1,0);
465 jacobian(0,1) = Sders[1](1,0);
466 jacobian(1,0) = Sders[0](0,1);
467 jacobian(1,1) = Sders[1](0,1);
470 temp(0) = Aders [ 0 ](0, 0) / weight;
471 temp(1) = Aders [ 1 ](0, 0) / weight;
472 jacobian(1, 0) = ( Aders [ 0 ](0, 1) - wders(0, 1) * temp(0) ) / weight;
473 jacobian(1, 1) = ( Aders [ 1 ](0, 1) - wders(0, 1) * temp(1) ) / weight;
474 jacobian(0, 0) = ( Aders [ 0 ](1, 0) - wders(1, 0) * temp(0) ) / weight;
475 jacobian(0, 1) = ( Aders [ 1 ](1, 0) - wders(1, 0) * temp(1) ) / weight;
498 for (
int j = 0; j <
nsd; j++ ) {
499 knotStart(j) =
knotVector [ j ] [ knotSpan(j) ];
500 knotEnd(j) =
knotVector [ j ] [ knotSpan(j) + 1 ];
507 for (
int j = 0; j <
nsd; j++ ) {
536 for (
int j = 0; j <
nsd; j++ ) {
537 knotStart(j) =
knotVector [ j ] [ knotSpan(j) ];
538 knotEnd(j) =
knotVector [ j ] [ knotSpan(j) + 1 ];
545 for (
int j = 0; j <
nsd; j++ ) {
578 for (
int j = 0; j <
nsd; j++ ) {
579 knotStart(j) =
knotVector [ j ] [ startKnotSpan(j) ];
580 knotEnd(j) =
knotVector [ j ] [ endKnotSpan(j) + 1 ];
587 for (
int j = 0; j <
nsd; j++ ) {
615 for (
int j = 0; j <
nsd; j++ ) {
616 knotStart(j) =
knotVector [ j ] [ startKnotSpan(j) ];
617 knotEnd(j) =
knotVector [ j ] [ endKnotSpan(j) + 1 ];
624 for (
int j = 0; j <
nsd; j++ ) {
642 int span, prepend, append;
651 return N(p - span + prepend);
659 int span, prepend, append;
669 for (
int i = 0; i <= n; i++ ) {
670 ders(i) = Ders(i, p - span + prepend);
677 int j = 0, index_first = I [ 0 ], index_last = I [ p + 1 ], mult_first = 1, mult_last = 1;
678 double first = U.
at(index_first), last = U.
at(index_last);
680 for (
int i = 1; i < p + 1; i++ ) {
681 if ( I [ i ] != index_first ) {
688 for (
int i = p; i > 0; i-- ) {
689 if ( I [ i ] != index_last ) {
696 * prepend = p + 1 - mult_first;
697 * append = p + 1 - mult_last;
700 for (
int i = 0; i <= * prepend; i++ ) {
705 for (
int i = 1; i <= p; i++ ) {
710 for (
int i = 0; i <= * append; i++ ) {
double giveDeterminant() const
Returns the trace (sum of diagonal components) of the receiver.
const IntArray * knotSpan
#define _IFT_TSplineInterpolation_localIndexKnotVectorV
void createLocalKnotVector(int p, const FloatArray &U, const int *I, int *prepend, int *append)
Creates local open knot vector.
virtual const FloatArray * giveKnotValues(int dim)
Returns the knot values of the receiver.
void dersBasisFunction(int n, double u, int p, const FloatArray &U, const int *I, FloatArray &ders)
Computes the middle basis function and it derivatives on local knot vector at u.
double & at(int i)
Coefficient access function.
virtual const FloatArray * giveVertexCoordinates(int i) const =0
int findSpan(int n, int p, double u, const double *U) const
Determines the knot span index (Algorithm A2.1 from the NURBS book)
int * degree
Degree in each direction.
Class representing a general abstraction for cell geometry.
virtual ~TSplineInterpolation()
virtual int giveNumberOfKnotSpanBasisFunctions(const IntArray &knotSpan)
Returns the number of nonzero basis functions at individual knot span,.
virtual void local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates global coordinates from given local ones.
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
const char * InputFieldType
Identifier of fields in input records.
double * openLocalKnotVector
Temporary open local knot vector to enable use of BSpline algorithms (common for all directions) [3*m...
Class implementing an array of integers.
#define _IFT_TSplineInterpolation_localIndexKnotVectorW
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
int totalNumberOfControlPoints
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
void clear()
Clears the array (zero size).
double ** knotVector
Knot vectors [nsd][knot_vector_size].
FloatArray * knotValues
Knot values [nsd].
virtual void giveJacobianMatrixAt(FloatMatrix &jacobianMatrix, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Gives the jacobian matrix at the local coordinates.
Class representing vector of real numbers.
IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
double basisFunction(double u, int p, const FloatArray &U, const int *I)
Evaluates the middle basis function on local knot vector at u.
Implementation of matrix containing floating point numbers.
IRResultType
Type defining the return values of InputRecord reading operations.
int *** localIndexKnotVector
Local index knot vector of the dimensions [totalNumberOfControlPoints][nsd][degree+2].
void dersBasisFuns(int n, double u, int span, int p, double *const U, FloatMatrix &ders)
Computes nonzero basis functions and their derivatives at u.
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
void zero()
Zeroes all coefficients of receiver.
void times(double s)
Multiplies receiver with scalar.
void zero()
Zeroes all coefficient of receiver.
Geometry wrapper for IGA elements.
int * numberOfControlPoints
numberOfControlPoints[nsd]
void preallocate(int futureSize)
Preallocates receiver to given futureSize if larger then allocatedSize.
the oofem namespace is to define a context or scope in which all oofem names are defined.
#define _IFT_TSplineInterpolation_localIndexKnotVectorU
void basisFuns(FloatArray &N, int span, double u, int p, const double *U)
Evaluates the nonvanishing basis functions of 1d BSpline (algorithm A2.2 from NURBS book) ...
int nsd
Number of spatial directions.
virtual int giveKnotSpanBasisFuncMask(const IntArray &knotSpan, IntArray &mask)
Returns indices (zero based) of nonzero basis functions for given knot span.
#define OOFEM_WARNING(...)
void resize(int s)
Resizes receiver towards requested size.