33 #ifndef OOMPH_SHAPE_HEADER 34 #define OOMPH_SHAPE_HEADER 39 #include <oomph-lib-config.h> 105 if((i >= Index1) || (j >= Index2))
107 std::ostringstream error_stream;
108 error_stream <<
"Range Error: ";
111 error_stream << i <<
" is not in the range (0," << Index1-1 <<
")" 116 error_stream << j <<
" is not in the range (0," << Index2-1 <<
")" 120 OOMPH_CURRENT_FUNCTION,
121 OOMPH_EXCEPTION_LOCATION);
128 Shape(
const unsigned &
N) : Index1(N), Index2(1)
132 Shape(
const unsigned &
N,
const unsigned &M) : Index1(N), Index2(M)
140 Shape() : Psi(0), Allocated_storage(0), Index1(0), Index2(0) {}
148 if((shape.
Index1 != Index1) ||
151 std::ostringstream error_stream;
152 error_stream <<
"Cannot assign Shape object:" << std::endl
153 <<
"Indices do not match " 154 <<
"LHS: " << Index1 <<
" " << Index2
158 OOMPH_CURRENT_FUNCTION,
159 OOMPH_EXCEPTION_LOCATION);
171 if((shape_pt->
Index1 != Index1) ||
172 (shape_pt->
Index2 != Index2))
174 std::ostringstream error_stream;
175 error_stream <<
"Cannot assign Shape object:" << std::endl
176 <<
"Indices do not match " 177 <<
"LHS: " << Index1 <<
" " << Index2
178 <<
", RHS: " << shape_pt->
Index1 <<
" " 182 OOMPH_CURRENT_FUNCTION,
183 OOMPH_EXCEPTION_LOCATION);
193 void resize(
const unsigned&
N,
const unsigned& M=1)
202 Allocated_storage =
new double[N*M];
209 #ifdef RANGE_CHECKING 218 #ifdef RANGE_CHECKING 227 #ifdef RANGE_CHECKING 236 #ifdef RANGE_CHECKING 245 #ifdef RANGE_CHECKING 248 return Psi[i*Index2 + j];
253 inline const double &
operator()(
const unsigned &
i,
const unsigned &j)
255 #ifdef RANGE_CHECKING 258 return Psi[i*Index2 + j];
300 const unsigned &k)
const 303 if((i >= Index1) || (j >= Index2) || (k >= Index3))
305 std::ostringstream error_stream;
306 error_stream <<
"Range Error: ";
310 <<
" is not in the range (0," << Index1-1 <<
")" 316 <<
" is not in the range (0," << Index2-1 <<
")" 322 <<
" is not in the range (0," << Index3-1 <<
")" 326 OOMPH_CURRENT_FUNCTION,
327 OOMPH_EXCEPTION_LOCATION);
335 DShape(
const unsigned &
N,
const unsigned &P) : Index1(N), Index2(1),
340 DShape(
const unsigned &
N,
const unsigned &M,
const unsigned &P) :
341 Index1(N), Index2(M), Index3(P)
346 DShape() : DPsi(0), Allocated_storage(0), Index1(0), Index2(0), Index3(0) {}
357 if((dshape.
Index1 != Index1) ||
358 (dshape.
Index2 != Index2) ||
359 (dshape.
Index3 != Index3))
361 std::ostringstream error_stream;
362 error_stream <<
"Cannot assign DShape object:" << std::endl
363 <<
"Indices do not match " 364 <<
"LHS: " << Index1 <<
" " << Index2 <<
" " 366 <<
", RHS: " << dshape.
Index1 <<
" " 370 OOMPH_CURRENT_FUNCTION,
371 OOMPH_EXCEPTION_LOCATION);
383 if((dshape_pt->
Index1 != Index1) ||
384 (dshape_pt->
Index2 != Index2) ||
385 (dshape_pt->
Index3 != Index3))
387 std::ostringstream error_stream;
388 error_stream <<
"Cannot assign Shape object:" << std::endl
389 <<
"Indices do not match " 390 <<
"LHS: " << Index1 <<
" " << Index2
392 <<
", RHS: " << dshape_pt->
Index1 <<
" " 393 << dshape_pt->
Index2 <<
" " 397 OOMPH_CURRENT_FUNCTION,
398 OOMPH_EXCEPTION_LOCATION);
401 DPsi = dshape_pt->
DPsi;
412 void resize(
const unsigned&
N,
const unsigned& P,
const unsigned& M=1)
422 Allocated_storage =
new double[N*M*P];
429 #ifdef RANGE_CHECKING 432 return DPsi[i*Index2*Index3 + k];
436 inline const double &
operator()(
const unsigned &
i,
const unsigned &k)
const 438 #ifdef RANGE_CHECKING 441 return DPsi[i*Index2*Index3 + k];
448 #ifdef RANGE_CHECKING 451 return DPsi[(i*Index2 + j)*Index3 + k];
455 inline const double &
operator()(
const unsigned &
i,
const unsigned &j,
456 const unsigned &k)
const 458 #ifdef RANGE_CHECKING 461 return DPsi[(i*Index2 + j)*Index3 + k];
483 const unsigned long &j)
const 484 {
return (i*Index2 + j)*Index3 + 0;}
495 inline unsigned long nindex3()
const {
return Index3;}
543 namespace OneDimLagrange
548 template<
unsigned NNODE_1D>
551 std::ostringstream error_stream;
552 error_stream <<
"One dimensional Lagrange shape functions " 553 <<
"have not been defined " 554 <<
"for " << NNODE_1D <<
" nodes." << std::endl;
556 OOMPH_CURRENT_FUNCTION,
557 OOMPH_EXCEPTION_LOCATION);
563 template<
unsigned NNODE_1D>
566 std::ostringstream error_stream;
567 error_stream <<
"One dimensional Lagrange shape function derivatives " 568 <<
"have not been defined " 569 <<
"for " << NNODE_1D <<
" nodes." << std::endl;
571 OOMPH_CURRENT_FUNCTION,
572 OOMPH_EXCEPTION_LOCATION);
579 template<
unsigned NNODE_1D>
582 std::ostringstream error_stream;
583 error_stream <<
"One dimensional Lagrange shape function " 584 <<
"second derivatives " 585 <<
"have not been defined " 586 <<
"for " << NNODE_1D <<
" nodes." << std::endl;
588 OOMPH_CURRENT_FUNCTION,
589 OOMPH_EXCEPTION_LOCATION);
598 Psi[0] = 0.5*(1.0-
s);
599 Psi[1] = 0.5*(1.0+
s);
625 Psi[0] = 0.5*s*(s-1.0);
627 Psi[2] = 0.5*s*(s+1.0);
657 double t3 = 0.5625*t2;
658 double t4 = 0.5625*t1;
659 double t5 = 0.625E-1*
s;
660 double t7 = 0.16875E1*t2;
661 double t8 = 0.16875E1*
s;
662 Psi[0] = -t3+t4+t5-0.625E-1;
663 Psi[1] = t7-t4-t8+0.5625;
664 Psi[2] = -t7-t4+t8+0.5625;
665 Psi[3] = t3+t4-t5-0.625E-1;
675 double t2 = 0.16875E1*t1;
676 double t3 = 0.1125E1*
s;
677 double t5 = 0.50625E1*t1;
678 DPsi[0] = -t2+t3+0.625E-1;
679 DPsi[1] = t5-t3-0.16875E1;
680 DPsi[2] = -t5-t3+0.16875E1;
681 DPsi[3] = t2+t3-0.625E-1;
691 double t2 = 0.16875E1*t1;
692 double t5 = 0.50625E1*t1;
693 DPsi[0] = -t2+0.1125E1;
694 DPsi[1] = t5-0.1125E1;
695 DPsi[2] = -t5-0.1125E1;
696 DPsi[3] = t2+0.1125E1;
704 namespace OneDimHermite
714 Psi[0][0] = 0.25*(s*s*s - 3.0*s + 2.0);
715 Psi[0][1] = 0.25*(s*s*s - s*s - s + 1.0);
717 Psi[1][0] = 0.25*(2.0 + 3.0*s - s*s*
s);
718 Psi[1][1] = 0.25*(s*s*s + s*s - s - 1.0);
723 inline void dshape(
const double &
s,
double DPsi[2][2])
726 DPsi[0][0] = 0.75*(s*s - 1.0);
727 DPsi[0][1] = 0.25*(3.0*s*s - 2.0*s - 1.0);
729 DPsi[1][0] = 0.75*(1.0 - s*
s);
730 DPsi[1][1] = 0.25*(3.0*s*s + 2.0*s - 1.0);
734 inline void d2shape(
const double &
s,
double DPsi[2][2])
738 DPsi[0][1] = 0.5*(3.0*s - 1.0);
741 DPsi[1][1] = 0.5*(3.0*s + 1.0);
750 template<
unsigned NNODE_1D>
761 if(!Nodes_calculated)
764 Nodes_calculated=
true;
774 using namespace Orthpoly;
776 unsigned p = NNODE_1D-1;
778 for(
unsigned i=0;
i<NNODE_1D;
i++)
792 template<
unsigned NNODE_1D>
795 template<
unsigned NNODE_1D>
799 template <
unsigned NNODE_1D>
806 unsigned p = NNODE_1D - 1;
812 for(
unsigned i=0;
i<NNODE_1D;
i++)
815 for(
unsigned j=0;j<NNODE_1D;j++)
825 if(
i==rootnum &&
i==0)
827 (*this)[
i]=-(1.0+p)*p/4.0;
829 else if(
i==rootnum &&
i==p)
831 (*this)[
i]=(1.0+p)*p/4.0;
871 (*this)[0] = 0.5*(1.0 -
s);
872 (*this)[1] = 0.5*(1.0 +
s);
873 for(
unsigned i=2;
i<p_order;
i++)
875 (*this)[
i] = (0.5*(1.0 -
s))*(0.5*(1.0 +
s))
891 for(
unsigned i=2;
i<p_order;
i++)
893 (*this)[
i] = (0.5*(1.0 -
s))*(0.5*(1.0 +
s))
unsigned Index2
Size of the second index of the shape function.
double & operator()(const unsigned &i, const unsigned &k)
Overload the round bracket operator for access to the data.
void shape(const double &s, double Psi[2][2])
Constructor sets the values of the shape functions at the position s.
unsigned nindex2() const
Return the range of index 2 of the shape function object.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
unsigned long nindex3() const
Return the range of index 3 of the derivatives of the shape functions.
void d2shape< 4 >(const double &s, double *DPsi)
double dlegendre(const unsigned &p, const double &x)
Calculates first derivative of Legendre polynomial of degree p at x using three term recursive formul...
OneDimensionalModalDShape(const unsigned p_order, const double &s)
void dshape< 2 >(const double &s, double *DPsi)
Derivatives of 1D shape functions specialised to linear order (2 Nodes)
DShape(const unsigned &N, const unsigned &M, const unsigned &P)
Constructor with three paramters: a two-index shape function.
Shape(const Shape &shape)
Broken copy constructor.
double & raw_direct_access(const unsigned long &i)
Direct access to internal storage of data in flat-packed C-style column-major format. WARNING: Only for experienced users. Only use this if raw speed is of the essence, as in the solid mechanics problems.
double * Allocated_storage
Pointer that addresses the storage allocated by the object on construction. This will be the same as ...
void operator=(const ShapeWithDeepCopy &old_shape)
Broken assignment operator.
void operator=(const DShape &dshape)
void shape< 3 >(const double &s, double *Psi)
1D shape functions specialised to quadratic order (3 Nodes)
double & operator[](const unsigned &i)
Overload the bracket operator to provide access to values.
const double & operator[](const unsigned &i) const
Overload the bracket operator (const version)
void d2shape(const double &s, double DPsi[2][2])
Second derivatives of the Hermite shape functions.
void d2shape< 2 >(const double &s, double *DPsi)
Second Derivatives of 1D shape functions, specialised to linear order (2 Nodes)
const double & operator()(const unsigned &i, const unsigned &k) const
Overload the round bracket operator (const version)
static Vector< double > z
const double & operator()(const unsigned &i) const
Overload the round bracket operator (const version)
ShapeWithDeepCopy()
Default constructor.
double legendre(const unsigned &p, const double &x)
Calculates Legendre polynomial of degree p at x using the three term recurrence relation ...
static double nodal_position(const unsigned &n)
void shape< 4 >(const double &s, double *Psi)
1D shape functions specialised to cubic order (4 Nodes)
void operator=(Shape *const &shape_pt)
unsigned long nindex2() const
Return the range of index 2 of the derivatives of the shape functions.
double * Allocated_storage
Pointer that addresses the storage allocated by the object on construction. This will be the same as ...
ShapeWithDeepCopy(const ShapeWithDeepCopy &old_shape)
Deep copy constructor.
~ShapeWithDeepCopy()
Destructor, clear up the memory allocated by the object.
double * Psi
Pointer that addresses the storage that will be used to read and set the shape functions. The shape functions are packed into a flat array of doubles.
void gll_nodes(const unsigned &Nnode, Vector< double > &x)
Calculates the Gauss Lobatto Legendre abscissas for degree p = NNode-1.
double ddlegendre(const unsigned &p, const double &x)
Calculates second derivative of Legendre polynomial of degree p at x using three term recursive formu...
OneDimensionalModalShape(const unsigned p_order, const double &s)
Constructor.
ShapeWithDeepCopy(const unsigned &N, const unsigned &M)
Constructor for a two-index set of shape functions.
DShape(const DShape &dshape)
Broken copy constructor.
void resize(const unsigned &N, const unsigned &M=1)
Change the size of the storage.
const double & raw_direct_access(const unsigned long &i) const
Direct access to internal storage of data in flat-packed C-style column-major format. WARNING: Only for experienced users. Only use this if raw speed is of the essence, as in the solid mechanics problems.
void dshape< 3 >(const double &s, double *DPsi)
Derivatives of 1D shape functions specialised to quadratic order (3 Nodes)
void range_check(const unsigned &i, const unsigned &j) const
Private function that checks whether the index is in range.
void d2shape< 3 >(const double &s, double *DPsi)
Shape(const unsigned &N)
Constructor for a single-index set of shape functions.
DShape(const unsigned &N, const unsigned &P)
Constructor with two parameters: a single-index shape function.
OneDimensionalLegendreDShape(const double &s)
unsigned Index2
Size of the second index of the shape function.
void range_check(const unsigned &i, const unsigned &j, const unsigned &k) const
Private function that checks whether the indices are in range.
Shape(const unsigned &N, const unsigned &M)
Constructor for a two-index set of shape functions.
ShapeWithDeepCopy(const unsigned &N)
Constructor for a single-index set of shape functions.
void dshape(const double &s, double DPsi[2][2])
Derivatives of 1D Hermite shape functions.
unsigned Index3
Size of the third index of the shape function.
unsigned long nindex1() const
Return the range of index 1 of the derivatives of the shape functions.
unsigned offset(const unsigned long &i, const unsigned long &j) const
Caculate the offset in flat-packed C-style, column-major format, required for a given i...
double * DPsi
Pointer that addresses the storage that will be used to read and set the shape-function derivatives...
~Shape()
Destructor, clear up the memory allocated by the object.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
OneDimensionalLegendreShape(const double &s)
Constructor.
void dshape< 4 >(const double &s, double *DPsi)
Derivatives of 1D shape functions specialised to cubic order (4 Nodes)
static void calculate_nodal_positions()
Static function used to populate the stored positions.
double & operator()(const unsigned &i, const unsigned &j)
Overload the round bracket operator, allowing for two indices.
const double & operator()(const unsigned &i, const unsigned &j) const
Overload the round bracket operator, allowing for two indices (const version)
unsigned nindex1() const
Return the range of index 1 of the shape function object.
~DShape()
Destructor, clean up the memory allocated by this object.
void resize(const unsigned &N, const unsigned &P, const unsigned &M=1)
const double & operator()(const unsigned &i, const unsigned &j, const unsigned &k) const
Overload the round bracket operator (const version)
double & operator()(const unsigned &i)
Overload the round bracket operator to provide access to values.
void operator=(DShape *const &dshape_pt)
unsigned Index1
Size of the first index of the shape function.
unsigned Index1
Size of the first index of the shape function.
double & operator()(const unsigned &i, const unsigned &j, const unsigned &k)
Overload the round bracket operator, with 3 indices.
void operator=(const Shape &shape)
Class that returns the shape functions associated with legendre.
static bool Nodes_calculated
void shape< 2 >(const double &s, double *Psi)
1D shape functions specialised to linear order (2 Nodes)