52 template<
class Scalar,
class ArrayScalar>
54 const EPointType pointType ):
56 coeffs_( (n+1)*(n+2)*(n+3)/2 , n*(n+2)*(n+3)/2 )
58 const int N = n*(n+2)*(n+3)/2;
61 this ->
basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Tetrahedron<4> >() );
66 const int littleN = n*(n+1)*(n+2)/2;
67 const int bigN = (n+1)*(n+2)*(n+3)/2;
68 const int start_PkH = (n-1)*n*(n+1)/6;
69 const int dim_PkH = n*(n+1)*(n+2)/6 - start_PkH;
70 const int scalarLittleN = littleN/3;
71 const int scalarBigN = bigN/3;
77 Teuchos::SerialDenseMatrix<int,Scalar> V1(bigN, littleN + 3 * dim_PkH);
80 for (
int i=0;i<scalarLittleN;i++) {
81 for (
int k=0;k<3;k++) {
82 V1(i+k*scalarBigN,i+k*scalarLittleN) = 1.0;
98 Phis_.getValues( phisAtCubPoints , cubPoints , OPERATOR_VALUE );
104 for (
int j=0;j<dim_PkH;j++) {
107 for (
int i=0;i<scalarBigN;i++) {
108 V1(scalarBigN+i,littleN+j) = 0.0;
110 V1(scalarBigN+i,littleN+j) -= cubWeights(k) * cubPoints(k,2)
111 * phisAtCubPoints(start_PkH+j,k)
112 * phisAtCubPoints(i,k);
116 for (
int i=0;i<scalarBigN;i++) {
117 V1(2*scalarBigN+i,littleN+j) = 0.0;
119 V1(2*scalarBigN+i,littleN+j) += cubWeights(k) * cubPoints(k,1)
120 * phisAtCubPoints(start_PkH+j,k)
121 * phisAtCubPoints(i,k);
127 for (
int j=0;j<dim_PkH;j++) {
130 for (
int i=0;i<scalarBigN;i++) {
131 V1(i,littleN+dim_PkH+j) = 0.0;
133 V1(i,littleN+dim_PkH+j) += cubWeights(k) * cubPoints(k,2)
134 * phisAtCubPoints(start_PkH+j,k)
135 * phisAtCubPoints(i,k);
140 for (
int i=0;i<scalarBigN;i++) {
141 V1(2*scalarBigN+i,littleN+dim_PkH+j) = 0.0;
143 V1(2*scalarBigN+i,littleN+dim_PkH+j) -= cubWeights(k) * cubPoints(k,0)
144 * phisAtCubPoints(start_PkH+j,k)
145 * phisAtCubPoints(i,k);
151 for (
int j=0;j<dim_PkH;j++) {
154 for (
int i=0;i<scalarBigN;i++) {
155 V1(i,littleN+2*dim_PkH+j) = 0.0;
157 V1(i,littleN+2*dim_PkH+j) -= cubWeights(k) * cubPoints(k,1)
158 * phisAtCubPoints(start_PkH+j,k)
159 * phisAtCubPoints(i,k);
163 for (
int i=0;i<scalarBigN;i++) {
164 V1(scalarBigN+i,littleN+2*dim_PkH+j) = 0.0;
166 V1(scalarBigN+i,littleN+2*dim_PkH+j) += cubWeights(k) * cubPoints(k,0)
167 * phisAtCubPoints(start_PkH+j,k)
168 * phisAtCubPoints(i,k);
174 Teuchos::SerialDenseMatrix<int,Scalar> S(bigN,1);
175 Teuchos::SerialDenseMatrix<int,Scalar> U(bigN, bigN);
176 Teuchos::SerialDenseMatrix<int,Scalar> Vt(bigN,bigN);
177 Teuchos::SerialDenseMatrix<int,Scalar> work(5*bigN,1);
178 Teuchos::SerialDenseMatrix<int,Scalar> rWork(1,1);
181 Teuchos::LAPACK<int,Scalar> lala;
199 int num_nonzero_sv = 0;
200 for (
int i=0;i<bigN;i++) {
201 if (S(i,0) > INTREPID_TOL) {
206 Teuchos::SerialDenseMatrix<int,Scalar> Uslender(bigN, num_nonzero_sv);
207 for (
int j=0;j<num_nonzero_sv;j++) {
208 for (
int i=0;i<bigN;i++) {
209 Uslender(i,j) = U(i,j);
214 Teuchos::SerialDenseMatrix<int,Scalar> V2(N, bigN);
216 shards::CellTopology edgeTop(shards::getCellTopologyData<shards::Line<2> >() );
217 shards::CellTopology faceTop(shards::getCellTopologyData<shards::Triangle<3> >() );
236 if (pointType == POINTTYPE_WARPBLEND) {
241 else if (pointType == POINTTYPE_EQUISPACED ) {
242 PointTools::getLattice<Scalar,FieldContainer<Scalar> >( oneDPts ,
249 PointTools::getLattice<Scalar,FieldContainer<Scalar> >( twoDPts ,
265 for (
int edge=0;edge<6;edge++) {
270 for (
int j=0;j<3;j++) {
280 Phis_.getValues( phisAtEdgePoints , edgePts , OPERATOR_VALUE );
283 for (
int j=0;j<numPtsPerEdge;j++) {
285 for (
int k=0;k<scalarBigN;k++) {
286 for (
int d=0;d<3;d++) {
287 V2(edge*numPtsPerEdge+j,k+scalarBigN*d) = edgeTan(d) * phisAtEdgePoints(k,j);
297 for (
int face=0;face<4;face++) {
307 Phis_.getValues( phisAtFacePoints , facePts , OPERATOR_VALUE );
308 for (
int j=0;j<numPtsPerFace;j++) {
309 for (
int k=0;k<scalarBigN;k++) {
310 for (
int d=0;d<3;d++) {
311 V2(6*numPtsPerEdge+2*face*numPtsPerFace+2*j,k+scalarBigN*d) =
312 refFaceTanU(d) * phisAtFacePoints(k,j);
313 V2(6*numPtsPerEdge+2*face*numPtsPerFace+2*j+1,k+scalarBigN*d) =
314 refFaceTanV(d) * phisAtFacePoints(k,j);
324 PointTools::getLattice<Scalar,FieldContainer<Scalar> >( cellPoints ,
330 Phis_.getValues( phisAtCellPoints , cellPoints , OPERATOR_VALUE );
331 for (
int i=0;i<numPtsPerCell;i++) {
332 for (
int j=0;j<scalarBigN;j++) {
333 for (
int k=0;k<3;k++) {
334 V2(6*numPtsPerEdge+8*numPtsPerFace+k*numPtsPerCell+i,k*scalarBigN+j) = phisAtCellPoints(j,i);
340 Teuchos::SerialDenseMatrix<int,Scalar> Vsdm( N , N );
343 Vsdm.multiply( Teuchos::NO_TRANS , Teuchos::NO_TRANS , 1.0 , V2 , Uslender , 0.0 );
345 Teuchos::SerialDenseSolver<int,Scalar> solver;
346 solver.setMatrix( rcp( &Vsdm ,
false ) );
351 Teuchos::SerialDenseMatrix<int,Scalar> Csdm( bigN , N );
352 Csdm.multiply( Teuchos::NO_TRANS , Teuchos::NO_TRANS , 1.0 , Uslender , Vsdm , 0.0 );
356 for (
int i=0;i<bigN;i++) {
357 for (
int j=0;j<N;j++) {
366 template<
class Scalar,
class ArrayScalar>
376 int *tags =
new int[ tagSize * this->getCardinality() ];
378 const int deg = this->getDegree();
380 shards::CellTopology edgeTop(shards::getCellTopologyData<shards::Line<2> >() );
381 shards::CellTopology faceTop(shards::getCellTopologyData<shards::Triangle<3> >() );
397 for (
int e=0;e<6;e++) {
398 for (
int i=0;i<numPtsPerEdge;i++) {
399 tag_cur[0] = 1; tag_cur[1] = e; tag_cur[2] = i; tag_cur[3] = numPtsPerEdge;
405 for (
int f=0;f<4;f++) {
406 for (
int i=0;i<2*numPtsPerFace;i++) {
407 tag_cur[0] = 2; tag_cur[1] = f; tag_cur[2] = i; tag_cur[3] = 2*numPtsPerFace;
413 for (
int i=0;i<3*numPtsPerCell;i++) {
414 tag_cur[0] = 3; tag_cur[1] = 0; tag_cur[2] = i; tag_cur[3] = 3*numPtsPerCell;
417 Intrepid::setOrdinalTagData(
this -> tagToOrdinal_,
418 this -> ordinalToTag_,
420 this -> basisCardinality_,
432 template<
class Scalar,
class ArrayScalar>
434 const ArrayScalar & inputPoints,
435 const EOperator operatorType)
const {
438 #ifdef HAVE_INTREPID_DEBUG
439 Intrepid::getValues_HCURL_Args<Scalar, ArrayScalar>(outputValues,
442 this -> getBaseCellTopology(),
443 this -> getCardinality() );
445 const int numPts = inputPoints.dimension(0);
446 const int deg =
this -> getDegree();
447 const int scalarBigN = (deg+1)*(deg+2)*(deg+3)/6;
450 switch (operatorType) {
454 Phis_.getValues( phisCur , inputPoints , OPERATOR_VALUE );
456 for (
int i=0;i<outputValues.dimension(0);i++) {
457 for (
int j=0;j<outputValues.dimension(1);j++) {
458 for (
int d=0;d<3;d++) {
459 outputValues(i,j,d) = 0.0;
461 for (
int k=0;k<scalarBigN;k++) {
462 for (
int d=0;d<3;d++) {
463 outputValues(i,j,d) += coeffs_(k+d*scalarBigN,i) * phisCur(k,j);
473 Phis_.getValues( phisCur , inputPoints , OPERATOR_GRAD );
474 for (
int i=0;i<outputValues.dimension(0);i++) {
475 for (
int j=0;j<outputValues.dimension(1);j++) {
476 outputValues(i,j,0) = 0.0;
477 for (
int k=0;k<scalarBigN;k++) {
478 outputValues(i,j,0) += coeffs_(k+2*scalarBigN,i) * phisCur(k,j,1);
479 outputValues(i,j,0) -= coeffs_(k+scalarBigN,i) * phisCur(k,j,2);
482 outputValues(i,j,1) = 0.0;
483 for (
int k=0;k<scalarBigN;k++) {
484 outputValues(i,j,1) += coeffs_(k,i) * phisCur(k,j,2);
485 outputValues(i,j,1) -= coeffs_(k+2*scalarBigN,i) * phisCur(k,j,0);
488 outputValues(i,j,2) = 0.0;
489 for (
int k=0;k<scalarBigN;k++) {
490 outputValues(i,j,2) += coeffs_(k+scalarBigN,i) * phisCur(k,j,0);
491 outputValues(i,j,2) -= coeffs_(k,i) * phisCur(k,j,1);
498 TEUCHOS_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
499 ">>> ERROR (Basis_HCURL_TET_In_FEM): Operator type not implemented");
503 catch (std::invalid_argument &exception){
504 TEUCHOS_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
505 ">>> ERROR (Basis_HCURL_TET_In_FEM): Operator type not implemented");
512 template<
class Scalar,
class ArrayScalar>
514 const ArrayScalar & inputPoints,
515 const ArrayScalar & cellVertices,
516 const EOperator operatorType)
const {
517 TEUCHOS_TEST_FOR_EXCEPTION( (
true), std::logic_error,
518 ">>> ERROR (Basis_HCURL_TET_In_FEM): FEM Basis calling an FVD member function");
Basis_HCURL_TET_In_FEM(const int n, const EPointType pointType)
Constructor.
virtual void initializeTags()
Initializes tagToOrdinal_ and ordinalToTag_ lookup arrays.
virtual void getCubature(ArrayPoint &cubPoints, ArrayWeight &cubWeights) const
Returns cubature points and weights (return arrays must be pre-sized/pre-allocated).
Defines Gauss integration rules on a line.
EBasis basisType_
Type of the basis.
Defines direct integration rules on a tetrahedron.
bool basisTagsAreSet_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
virtual int getNumPoints() const
Returns the number of cubature points.
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
shards::CellTopology basisCellTopology_
Base topology of the cells for which the basis is defined. See the Shards package http://trilinos...
virtual const shards::CellTopology getBaseCellTopology() const
Returns the base cell topology for which the basis is defined. See Shards documentation http://trilin...
FieldContainer< Scalar > coeffs_
Array holding the expansion coefficients of the nodal basis in terms of Phis_.
void getValues(ArrayScalar &outputValues, const ArrayScalar &inputPoints, const EOperator operatorType) const
Evaluation of a FEM basis on a reference Tetrahedron cell.
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_TET_Cn_FEM_ORTH< Scalar, FieldContainer< Scalar > > Phis_
Orthogonal basis of ofder n, in terms of which the H(curl) basis functions are expressed.