1 #ifndef INTREPID_HGRAD_LINE_HERMITE_FEMDEF_HPP
2 #define INTREPID_HGRAD_LINE_HERMITE_FEMDEF_HPP
59 template<
class Scalar,
class ArrayScalar>
64 this->
basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() );
79 template<
class Scalar,
class ArrayScalar>
81 latticePts_( pts.dimension(0), 1 ) {
83 int n = pts.dimension(0);
87 this->
basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() );
92 for(
int i=0; i<n-1; ++i ) {
93 TEUCHOS_TEST_FOR_EXCEPTION( pts(i,0) >= pts(i+1,0), std::runtime_error ,
94 "Intrepid::Basis_HGRAD_LINE_Hermite_FEM Illegal points given to constructor" );
98 if (std::abs(pts(0,0)+1.0) < INTREPID_TOL) {
104 for (
int i=1;i<n-1;i++) {
107 if (std::abs(pts(n-1,0)-1.0) < INTREPID_TOL) {
120 template<
class Scalar,
class ArrayScalar>
122 const EPointType &pointType ) :
125 TEUCHOS_TEST_FOR_EXCEPTION(n<2,std::invalid_argument,
"Intrepid::Basis_HGRAD_LINE_Hermite_FEM requires the "
126 "number of interpolation points to be at least 2");
130 this->
basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() );
136 case POINTTYPE_EQUISPACED:
137 PointTools::getLattice<Scalar,FieldContainer<Scalar> >(
latticePts_ ,
140 case POINTTYPE_SPECTRAL:
141 PointTools::getLattice<Scalar,FieldContainer<Scalar> >(
latticePts_ ,
144 case POINTTYPE_SPECTRAL_OPEN:
145 PointTools::getGaussPoints<Scalar,FieldContainer<Scalar> >(
latticePts_ , n-1 );
148 TEUCHOS_TEST_FOR_EXCEPTION(
true , std::invalid_argument ,
149 "Basis_HGRAD_LINE_Hermite_FEM:: invalid point type" );
159 template<
class Scalar,
class ArrayScalar>
164 int nBf = this->getCardinality();
171 ArrayScalar P ( nBf );
172 ArrayScalar Px( nBf );
175 for(
int i=0; i<n; ++i ) {
177 recurrence(P,Px,latticePts_(i,0));
180 for(
int j=0; j<nBf; ++j ) {
186 solver_.setMatrix(Teuchos::rcpFromRef(V_));
189 solver_.factorWithEquilibration(
true);
200 template<
class Scalar,
class ArrayScalar>
203 const Scalar x )
const {
205 int n = P.dimension(0);
212 for(
int j=0; j<n-1; ++j ) {
213 P (j+1) = x*P(j) + q*Px(j)/(j+1);
214 Px(j+1) = (j+1)*P(j) + x*Px(j);
221 template<
class Scalar,
class ArrayScalar>
225 const Scalar x )
const {
229 int C = this->getCardinality();
232 for(
int k=1;k<m;++k) {
236 for(
int j=0; j<C; ++j ) {
243 Px(j) = (j+k)*P(j-1) + x*Px(j-1);
251 template<
class Scalar,
class ArrayScalar>
253 const ArrayScalar & inputPoints,
254 const EOperator operatorType)
const {
257 #ifdef HAVE_INTREPID_DEBUG
258 Intrepid::getValues_HGRAD_Args<Scalar, ArrayScalar>(outputValues,
261 this -> getBaseCellTopology(),
262 this -> getCardinality() );
265 int nPts = inputPoints.dimension(0);
266 int nBf = this->getCardinality();
271 SerialDenseMatrix legendre(nBf,nPts);
274 SerialDenseMatrix hermite(nBf,nPts);
279 int derivative_order;
280 int derivative_case =
static_cast<int>(operatorType);
282 if( derivative_case == 0 ) {
283 derivative_order = 0;
285 else if( derivative_case > 0 && derivative_case < 5 ) {
286 derivative_order = 1;
289 derivative_order = derivative_case - 3;
294 switch (operatorType) {
297 for(
int i=0; i<nPts; ++i ) {
298 recurrence( P, Px, inputPoints(i,0) );
299 for(
int j=0; j<nBf; ++j ) {
300 legendre(j,i) = P(j);
310 for(
int i=0; i<nPts; ++i ) {
311 recurrence( P, Px, inputPoints(i,0) );
312 for(
int j=0; j<nBf; ++j ) {
313 legendre(j,i) = Px(j);
328 for(
int i=0; i<nPts; ++i ) {
329 legendre_d( P, Px, derivative_order, inputPoints(i,0));
330 for(
int j=0; j<nBf; ++j ) {
331 legendre(j,i) = Px(j);
337 TEUCHOS_TEST_FOR_EXCEPTION( !( Intrepid::isValidOperator(operatorType) ), std::invalid_argument,
338 ">>> ERROR (Basis_HGRAD_LINE_Hermite_FEM): Invalid operator type");
342 catch (std::invalid_argument &exception){
343 TEUCHOS_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
344 ">>> ERROR (Basis_HGRAD_LINE_Hermite_FEM): Operator failed");
348 solver_.factorWithEquilibration(
true);
352 solver_.setVectors(Teuchos::rcpFromRef(hermite),Teuchos::rcpFromRef(legendre));
355 if(derivative_order > 0)
357 for(
int i=0; i<n; ++i ) {
358 for(
int j=0; j<nPts; ++j ) {
359 outputValues(2*i, j,0) = hermite(i, j);
360 outputValues(2*i+1,j,0) = hermite(i+n,j);
365 for(
int i=0; i<n; ++i ) {
366 for(
int j=0; j<nPts; ++j ) {
367 outputValues(2*i ,j) = hermite(i, j);
368 outputValues(2*i+1,j) = hermite(i+n,j);
376 template<
class Scalar,
class ArrayScalar>
387 int C = this->getCardinality();
388 tags_.reserve( tagSize * C );
392 int hasLeftVertex =
static_cast<int>( latticePts_(0 , 0) == -1.0 );
393 int hasRightVertex =
static_cast<int>( latticePts_(n-1, 0) == 1.0 );
395 int internal_dof = C - 2*(hasLeftVertex+hasRightVertex);
397 if( hasLeftVertex ) {
418 tags_[3] = C-2*hasRightVertex;
424 tags_[7] = C-2*hasRightVertex;
427 if( hasRightVertex ) {
433 tags_[4*i0+1] = hasLeftVertex;
439 tags_[4*i1+1] = hasLeftVertex;
450 tags_[4*i0+2] = internal_dof-2;
451 tags_[4*i0+3] = internal_dof;
456 tags_[4*i1+2] = internal_dof-1;
457 tags_[4*i1+3] = internal_dof;
460 for(
int i=1; i<n-1; ++i ) {
461 int i0 = 2*i;
int i1 = 2*i+1;
466 tags_[4*i0+2] = i0 - 2*hasLeftVertex;
467 tags_[4*i0+3] = internal_dof;
472 tags_[4*i1+2] = i1 - 2*hasLeftVertex;
473 tags_[4*i1+3] = internal_dof;
477 Intrepid::setOrdinalTagData(
this -> tagToOrdinal_,
478 this -> ordinalToTag_,
480 this -> basisCardinality_,
489 template<
class Scalar,
class ArrayScalar>
492 int nBf = this->getCardinality();
494 os <<
"Tags:" << std::endl;
495 os <<
"-----" << std::endl;
499 for(
int i=0; i<nBf; ++i ) {
500 os << std::setw(4) << i;
505 os <<
"Subcell dim: ";
506 for(
int i=0; i<nBf; ++i ) {
507 os << std::setw(4) << tags_[4*i];
512 os <<
"Subcell ord: ";
513 for(
int i=0; i<nBf; ++i ) {
514 os << std::setw(4) << tags_[4*i+1];
519 os <<
"Subcell DoF: ";
520 for(
int i=0; i<nBf; ++i ) {
521 os << std::setw(4) << tags_[4*i+2];
526 os <<
"Total Sc DoF: ";
527 for(
int i=0; i<nBf; ++i ) {
528 os << std::setw(4) << tags_[4*i+3];
538 template<
class Scalar,
class ArrayScalar>
540 const ArrayScalar & inputPoints,
541 const ArrayScalar & cellVertices,
542 const EOperator operatorType)
const {
543 TEUCHOS_TEST_FOR_EXCEPTION( (
true), std::logic_error,
544 ">>> ERROR (Basis_HGRAD_LINE_Hermite_FEM): FEM Basis calling an FVD member function");
548 template<
class Scalar,
class ArrayScalar>
551 for (
int i=0;i<latticePts_.dimension(0);i++)
553 for (
int j=0;j<latticePts_.dimension(1);j++)
555 dofCoords(i,j) = latticePts_(i,j);
virtual void getDofCoords(ArrayScalar &DofCoords) const
implements the dofcoords interface
Implements Hermite interpolant basis of degree n on the reference Line cell. The basis has cardinalit...
FieldContainer< Scalar > latticePts_
Holds the points defining the Hermite basis.
EBasis basisType_
Type of the basis.
void legendre_d(ArrayScalar &Pm, ArrayScalar &Pm1, const int m, const Scalar pt) const
Evaluates and at a particular point .
void recurrence(ArrayScalar &P, ArrayScalar &Px, const Scalar x) const
Evaluates and at a particular point .
bool basisTagsAreSet_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
void getValues(ArrayScalar &outputValues, const ArrayScalar &inputPoints, const EOperator operatorType) const
Evaluation of a FEM basis on a reference Line cell.
void initializeTags()
Initializes tagToOrdinal_ and ordinalToTag_ lookup arrays.
shards::CellTopology basisCellTopology_
Base topology of the cells for which the basis is defined. See the Shards package http://trilinos...
void setupVandermonde(bool factor=true)
Form the Legendre/Derivative Vandermonde matrix at the given lattice points and have the linear solve...
int basisDegree_
Degree of the largest complete polynomial space that can be represented by the basis.
int basisCardinality_
Cardinality of the basis, i.e., the number of basis functions/degrees-of-freedom. ...
Basis_HGRAD_LINE_Hermite_FEM()
Default Constructor assumes the two interpolation points are the cell vertices. Cubic Hermite Interpo...