Basis_HGRAD_QUAD_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_QUAD_Cn_FEM( const int order, const EPointType &pointType ): ptsx_( order+1 , 1 ) , ptsy_( order+1 , 1 ) { Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1); bases[0].resize(2); bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( order , pointType ) ); bases[0][1] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( order , pointType ) ); this->setBases( bases ); this->basisCardinality_ = (order+1)*(order+1); this->basisDegree_ = order; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; // fill up the pt arrays with calls to the lattice EPointType pt = (pointType==POINTTYPE_EQUISPACED)?pointType:POINTTYPE_WARPBLEND; PointTools::getLattice<Scalar,ArrayScalar >( ptsx_ , shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >()) , order , 0 , pt ); for (int i=0;i<order+1;i++) { ptsy_(i,0) = ptsx_(i,0); } initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HDIV_HEX_In_FEM<Scalar,ArrayScalar>::Basis_HDIV_HEX_In_FEM( int order , const ArrayScalar & ptsClosed , const ArrayScalar & ptsOpen): closedBasis_( order , ptsClosed ), openBasis_( order-1 , ptsOpen ), closedPts_( ptsClosed ), openPts_( ptsOpen ) { this -> basisDegree_ = order; this -> basisCardinality_ = 3 * closedBasis_.getCardinality() * openBasis_.getCardinality() * openBasis_.getCardinality(); this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; Array<Array<RCP<Basis<Scalar,ArrayScalar > > > > bases(3); bases[0].resize(3); bases[1].resize(3); bases[2].resize(3); bases[0][0] = rcp( &closedBasis_ , false ); bases[0][1] = rcp( &openBasis_ , false ); bases[0][2] = rcp( &openBasis_ , false ); bases[1][0] = rcp( &openBasis_ , false ); bases[1][1] = rcp( &closedBasis_ , false ); bases[1][2] = rcp( &openBasis_ , false ); bases[2][0] = rcp( &openBasis_ , false ); bases[2][1] = rcp( &openBasis_ , false ); bases[2][2] = rcp( &closedBasis_ , false ); this->setBases( bases ); initializeTags(); this->basisTagsAreSet_ = true; }
void TagExtractor::findStartEndPositions(const QString &tag) { initializeTags(tag); starts = findAll(startTag); ends = findAll(endTag); }
Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_LINE_Cn_FEM( const int n , const EPointType &pointType ): latticePts_( n+1 , 1 ), Phis_( n ), V_(n+1,n+1), Vinv_(n+1,n+1) { const int N = n+1; this -> basisCardinality_ = N; this -> basisDegree_ = n; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; switch(pointType) { case POINTTYPE_EQUISPACED: PointTools::getLattice<Scalar,ArrayScalar >( latticePts_ , this->basisCellTopology_ , n , 0 , POINTTYPE_EQUISPACED ); break; case POINTTYPE_SPECTRAL: case POINTTYPE_WARPBLEND: PointTools::getLattice<Scalar,ArrayScalar >( latticePts_ , this->basisCellTopology_ , n , 0 , POINTTYPE_WARPBLEND ); break; case POINTTYPE_SPECTRAL_OPEN: PointTools::getGaussPoints<Scalar,ArrayScalar >( latticePts_ , n ); break; default: TEUCHOS_TEST_FOR_EXCEPTION( true , std::invalid_argument , "Basis_HGRAD_LINE_Cn_FEM:: invalid point type" ); break; } // form Vandermonde matrix. Actually, this is the transpose of the VDM, // so we transpose on copy below. Phis_.getValues( V_ , latticePts_ , OPERATOR_VALUE ); // now I need to copy V into a Teuchos array to do the inversion Teuchos::SerialDenseMatrix<int,Scalar> Vsdm(N,N); for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { Vsdm(i,j) = V_(i,j); } } // invert the matrix Teuchos::SerialDenseSolver<int,Scalar> solver; solver.setMatrix( rcp( &Vsdm , false ) ); solver.invert( ); // now I need to copy the inverse into Vinv for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { Vinv_(i,j) = Vsdm(j,i); } } initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HGRAD_TRI_C1_FEM<Scalar,ArrayScalar>::Basis_HGRAD_TRI_C1_FEM() { this -> basisCardinality_ = 3; this -> basisDegree_ = 1; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() ); this -> basisType_ = BASIS_FEM_DEFAULT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HGRAD_QUAD_C2_FEM<Scalar, ArrayScalar>::Basis_HGRAD_QUAD_C2_FEM() { this -> basisCardinality_ = 9; this -> basisDegree_ = 2; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() ); this -> basisType_ = BASIS_FEM_DEFAULT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HCURL_HEX_I1_FEM<Scalar,ArrayScalar>::Basis_HCURL_HEX_I1_FEM() { this -> basisCardinality_ = 12; this -> basisDegree_ = 1; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() ); this -> basisType_ = BASIS_FEM_DEFAULT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HGRAD_TET_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_TET_Cn_FEM( const int n , const EPointType pointType ): Phis( n ), V((n+1)*(n+2)*(n+3)/6,(n+1)*(n+2)*(n+3)/6), Vinv((n+1)*(n+2)*(n+3)/6,(n+1)*(n+2)*(n+3)/6), latticePts( (n+1)*(n+2)*(n+3)/6 , 3 ) { const int N = (n+1)*(n+2)*(n+3)/6; this -> basisCardinality_ = N; this -> basisDegree_ = n; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Tetrahedron<4> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; // construct lattice PointTools::getLattice<Scalar,ArrayScalar >( latticePts , this->getBaseCellTopology() , n , 0 , pointType ); // form Vandermonde matrix. Actually, this is the transpose of the VDM, // so we transpose on copy below. Phis.getValues( V , latticePts , OPERATOR_VALUE ); // now I need to copy V into a Teuchos array to do the inversion Teuchos::SerialDenseMatrix<int,Scalar> Vsdm(N,N); for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { Vsdm(i,j) = V(i,j); } } // invert the matrix Teuchos::SerialDenseSolver<int,Scalar> solver; solver.setMatrix( rcp( &Vsdm , false ) ); solver.invert( ); // now I need to copy the inverse into Vinv for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { Vinv(i,j) = Vsdm(j,i); } } initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HGRAD_LINE_Cn_FEM_JACOBI<Scalar,ArrayScalar>::Basis_HGRAD_LINE_Cn_FEM_JACOBI(int order, Scalar alpha, Scalar beta) { this -> basisCardinality_ = order+1; this -> basisDegree_ = order; this -> jacobiAlpha_ = alpha; this -> jacobiBeta_ = beta; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<> >() ); this -> basisType_ = BASIS_FEM_HIERARCHICAL; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HDIV_HEX_In_FEM<Scalar,ArrayScalar>::Basis_HDIV_HEX_In_FEM( int order , const EPointType &pointType ): closedBasis_( order , pointType==POINTTYPE_SPECTRAL?POINTTYPE_SPECTRAL:POINTTYPE_EQUISPACED ), openBasis_( order-1 , pointType==POINTTYPE_SPECTRAL?POINTTYPE_SPECTRAL_OPEN:POINTTYPE_EQUISPACED ), closedPts_( order+1 , 1 ), openPts_( order , 1 ) { this -> basisDegree_ = order; this -> basisCardinality_ = 3 * closedBasis_.getCardinality() * openBasis_.getCardinality() * openBasis_.getCardinality(); this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; PointTools::getLattice<Scalar,ArrayScalar >( closedPts_ , shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >()) , order , 0 , pointType==POINTTYPE_SPECTRAL?POINTTYPE_WARPBLEND:POINTTYPE_EQUISPACED ); if (pointType == POINTTYPE_SPECTRAL) { PointTools::getGaussPoints<Scalar,ArrayScalar >( openPts_ , order - 1 ); } else { PointTools::getLattice<Scalar,ArrayScalar >( openPts_ , shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >()) , order - 1, 0 , POINTTYPE_EQUISPACED ); } Array<Array<RCP<Basis<Scalar,ArrayScalar > > > > bases(3); bases[0].resize(3); bases[1].resize(3); bases[2].resize(3); bases[0][0] = rcp( &closedBasis_ , false ); bases[0][1] = rcp( &openBasis_ , false ); bases[0][2] = rcp( &openBasis_ , false ); bases[1][0] = rcp( &openBasis_ , false ); bases[1][1] = rcp( &closedBasis_ , false ); bases[1][2] = rcp( &openBasis_ , false ); bases[2][0] = rcp( &openBasis_ , false ); bases[2][1] = rcp( &openBasis_ , false ); bases[2][2] = rcp( &closedBasis_ , false ); this->setBases( bases ); initializeTags(); this->basisTagsAreSet_ = true; }
QString TagExtractor::getFirstInTag(const QString &tag) { initializeTags(tag); int start = contents.indexOf(startTag, 0); int end = contents.indexOf(endTag, 0); QString contents; if(start != -1 && end != -1) contents = extract(start, end); return contents; }
Basis_HGRAD_HEX_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_HEX_Cn_FEM( const int orderx , const int ordery , const int orderz , const ArrayScalar &pts_x , const ArrayScalar &pts_y , const ArrayScalar &pts_z ): ptsx_( pts_x.dimension(0) , 1 ), ptsy_( pts_y.dimension(0) , 1 ), ptsz_( pts_z.dimension(0) , 1 ) { for (int i=0;i<pts_x.dimension(0);i++) { ptsx_(i,0) = pts_x(i,0); } for (int i=0;i<pts_y.dimension(0);i++) { ptsy_(i,0) = pts_y(i,0); } for (int i=0;i<pts_z.dimension(0);i++) { ptsz_(i,0) = pts_z(i,0); } Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1); bases[0].resize(3); bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( orderx , pts_x ) ); bases[0][1] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( ordery , pts_y ) ); bases[0][2] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( orderz , pts_z ) ); this->setBases( bases ); this->basisCardinality_ = (orderx+1)*(ordery+1)*(orderz+1); if (orderx >= ordery && orderx >= orderz ) { this->basisDegree_ = orderx; } else if (ordery >= orderx && ordery >= orderz) { this->basisDegree_ = ordery; } else { this->basisDegree_ = orderz; } this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HGRAD_HEX_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_HEX_Cn_FEM( const int order , const EPointType & pointType ): ptsx_( order+1 , 1 ), ptsy_( order+1 , 1 ), ptsz_( order+1 , 1 ) { Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1); bases[0].resize(3); bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( order , pointType ) ); // basis is same in each direction, so I only need to instantiate it once! bases[0][1] = bases[0][0]; bases[0][2] = bases[0][0]; this->setBases( bases ); this->basisCardinality_ = (order+1)*(order+1)*(order+1); this->basisDegree_ = order; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; // get points EPointType pt = (pointType==POINTTYPE_EQUISPACED)?pointType:POINTTYPE_WARPBLEND; PointTools::getLattice<Scalar,ArrayScalar >( ptsx_ , shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >()) , order , 0 , pt ); for (int i=0;i<order+1;i++) { ptsy_(i,0) = ptsx_(i,0); ptsz_(i,0) = ptsx_(i,0); } initializeTags(); this->basisTagsAreSet_ = true; }
void Basis_HGRAD_LINE_Hermite_FEM<Scalar,ArrayScalar>::setupVandermonde( bool factor ) { initializeTags(); int nBf = this->getCardinality(); int n = nBf/2; V_.shape(nBf,nBf); // Make containers to store the Legendre polynomials and their derivatives // at a given point ArrayScalar P ( nBf ); ArrayScalar Px( nBf ); // Loop over grid points for( int i=0; i<n; ++i ) { recurrence(P,Px,latticePts_(i,0)); // Loop over basis functions for(int j=0; j<nBf; ++j ) { V_(j, i ) = P (j); V_(j, i+n) = Px(j); } } solver_.setMatrix(Teuchos::rcpFromRef(V_)); if(factor) { solver_.factorWithEquilibration(true); solver_.factor(); isFactored_ = true; } else { isFactored_ = false; } }
Basis_HGRAD_QUAD_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_QUAD_Cn_FEM( const int orderx , const int ordery, const ArrayScalar &pts_x , const ArrayScalar &pts_y ): ptsx_( pts_x.dimension(0) , 1 ) , ptsy_( pts_y.dimension(0) , 1 ) { Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1); bases[0].resize(2); bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( orderx , pts_x ) ); bases[0][1] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( ordery , pts_y ) ); this->setBases( bases ); this->basisCardinality_ = (orderx+1)*(ordery+1); if (orderx > ordery) { this->basisDegree_ = orderx; } else { this->basisDegree_ = ordery; } this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; for (int i=0;i<pts_x.dimension(0);i++) { ptsx_(i,0) = pts_x(i,0); } for (int i=0;i<pts_y.dimension(0);i++) { ptsy_(i,0) = pts_y(i,0); } initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HDIV_TRI_In_FEM<Scalar,ArrayScalar>::Basis_HDIV_TRI_In_FEM( const ordinal_type n , const EPointType pointType ): Phis( n ), coeffs( (n+1)*(n+2) , n*(n+2) ) { const ordinal_type N = n*(n+2); this -> basisCardinality_ = N; this -> basisDegree_ = n; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; const ordinal_type littleN = n*(n+1); // dim of (P_{n-1})^2 -- smaller space const ordinal_type bigN = (n+1)*(n+2); // dim of (P_{n})^2 -- larger space const ordinal_type scalarSmallestN = (n-1)*n / 2; const ordinal_type scalarLittleN = littleN/2; const ordinal_type scalarBigN = bigN/2; // first, need to project the basis for RT space onto the // orthogonal basis of degree n // get coefficients of PkHx Teuchos::SerialDenseMatrix<ordinal_type,Scalar> V1(bigN, N); // basis for the space is // { (phi_i,0) }_{i=0}^{scalarLittleN-1} , // { (0,phi_i) }_{i=0}^{scalarLittleN-1} , // { (x,y) . phi_i}_{i=scalarLittleN}^{scalarBigN-1} // columns of V1 are expansion of this basis in terms of the basis // for P_{n}^2 // these two loops get the first two sets of basis functions for (ordinal_type i=0;i<scalarLittleN;i++) { V1(i,i) = 1.0; V1(scalarBigN+i,scalarLittleN+i) = 1.0; } // now I need to integrate { (x,y) phi } against the big basis // first, get a cubature rule. CubatureDirectTriDefault<Scalar,ArrayScalar > myCub( 2 * n ); ArrayScalar cubPoints( myCub.getNumPoints() , 2 ); ArrayScalar cubWeights( myCub.getNumPoints() ); myCub.getCubature( cubPoints , cubWeights ); // tabulate the scalar orthonormal basis at cubature points ArrayScalar phisAtCubPoints( scalarBigN , myCub.getNumPoints() ); Phis.getValues( phisAtCubPoints , cubPoints , OPERATOR_VALUE ); // now do the integration for (ordinal_type i=0;i<n;i++) { for (ordinal_type j=0;j<scalarBigN;j++) { // ordinal_type (x,y) phi_i \cdot (phi_j,0) V1(j,littleN+i) = 0.0; for (ordinal_type k=0;k<myCub.getNumPoints();k++) { V1(j,littleN+i) += cubWeights(k) * cubPoints(k,0) * phisAtCubPoints(scalarSmallestN+i,k) * phisAtCubPoints(j,k); } } for (ordinal_type j=0;j<scalarBigN;j++) { // ordinal_type (x,y) phi_i \cdot (0,phi_j) V1(j+scalarBigN,littleN+i) = 0.0; for (ordinal_type k=0;k<myCub.getNumPoints();k++) { V1(j+scalarBigN,littleN+i) += cubWeights(k) * cubPoints(k,1) * phisAtCubPoints(scalarSmallestN+i,k) * phisAtCubPoints(j,k); } } } //std::cout << V1 << "\n"; // next, apply the RT nodes (rows) to the basis for (P_n)^2 (columns) Teuchos::SerialDenseMatrix<ordinal_type,Scalar> V2(N , bigN); // first 3 * degree nodes are normals at each edge // get the points on the line ArrayScalar linePts( n , 1 ); if (pointType == POINTTYPE_WARPBLEND) { CubatureDirectLineGauss<Scalar> edgeRule( n ); ArrayScalar edgeCubWts( n ); edgeRule.getCubature( linePts , edgeCubWts ); } else if (pointType == POINTTYPE_EQUISPACED ) { shards::CellTopology linetop(shards::getCellTopologyData<shards::Line<2> >() ); PointTools::getLattice<Scalar,ArrayScalar >( linePts , linetop , n+1 , 1 , POINTTYPE_EQUISPACED ); } // holds the image of the line points ArrayScalar edgePts( n , 2 ); ArrayScalar phisAtEdgePoints( scalarBigN , n ); // these are scaled by the appropriate edge lengths. const Scalar nx[] = {0.0,1.0,-1.0}; const Scalar ny[] = {-1.0,1.0,0.0}; for (ordinal_type i=0;i<3;i++) { // loop over edges CellTools<Scalar>::mapToReferenceSubcell( edgePts , linePts , 1 , i , this->basisCellTopology_ ); Phis.getValues( phisAtEdgePoints , edgePts , OPERATOR_VALUE ); // loop over points (rows of V2) for (ordinal_type j=0;j<n;j++) { // loop over orthonormal basis functions (columns of V2) for (ordinal_type k=0;k<scalarBigN;k++) { V2(n*i+j,k) = nx[i] * phisAtEdgePoints(k,j); V2(n*i+j,k+scalarBigN) = ny[i] * phisAtEdgePoints(k,j); } } } // next map the points to each edge // remaining nodes are divided into two pieces: point value of x // components and point values of y components. These are // evaluated at the interior of a lattice of degree + 1, For then // the degree == 1 space corresponds classicaly to RT0 and so gets // no internal nodes, and degree == 2 corresponds to RT1 and needs // one internal node per vector component. const ordinal_type numInternalPoints = PointTools::getLatticeSize( this->getBaseCellTopology() , n + 1 , 1 ); if (numInternalPoints > 0) { ArrayScalar internalPoints( numInternalPoints , 2 ); PointTools::getLattice<Scalar,ArrayScalar >( internalPoints , this->getBaseCellTopology() , n + 1 , 1 , pointType ); ArrayScalar phisAtInternalPoints( scalarBigN , numInternalPoints ); Phis.getValues( phisAtInternalPoints , internalPoints , OPERATOR_VALUE ); // copy values into right positions of V2 for (ordinal_type i=0;i<numInternalPoints;i++) { for (ordinal_type j=0;j<scalarBigN;j++) { // x component V2(3*n+i,j) = phisAtInternalPoints(j,i); // y component V2(3*n+numInternalPoints+i,scalarBigN+j) = phisAtInternalPoints(j,i); } } } // std::cout << "Nodes on big basis\n"; // std::cout << V2 << "\n"; // std::cout << "End nodes\n"; Teuchos::SerialDenseMatrix<ordinal_type,Scalar> Vsdm( N , N ); // multiply V2 * V1 --> V Vsdm.multiply( Teuchos::NO_TRANS , Teuchos::NO_TRANS , 1.0 , V2 , V1 , 0.0 ); // std::cout << "Vandermonde:\n"; // std::cout << Vsdm << "\n"; // std::cout << "End Vandermonde\n"; Teuchos::SerialDenseSolver<ordinal_type,Scalar> solver; solver.setMatrix( rcp( &Vsdm , false ) ); solver.invert( ); Teuchos::SerialDenseMatrix<ordinal_type,Scalar> Csdm( bigN , N ); Csdm.multiply( Teuchos::NO_TRANS , Teuchos::NO_TRANS , 1.0 , V1 , Vsdm , 0.0 ); // std::cout << Csdm << "\n"; for (ordinal_type i=0;i<bigN;i++) { for (ordinal_type j=0;j<N;j++) { coeffs(i,j) = Csdm(i,j); } } initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HCURL_TRI_In_FEM<Scalar,ArrayScalar>::Basis_HCURL_TRI_In_FEM( const int n , const EPointType pointType ): Phis_( n ), coeffs_( (n+1)*(n+2) , n*(n+2) ) { const int N = n*(n+2); this -> basisCardinality_ = N; this -> basisDegree_ = n; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; const int littleN = n*(n+1); // dim of (P_{n-1})^2 -- smaller space const int bigN = (n+1)*(n+2); // dim of (P_{n})^2 -- larger space const int scalarSmallestN = (n-1)*n / 2; const int scalarLittleN = littleN/2; const int scalarBigN = bigN/2; // first, need to project the basis for Nedelec space onto the // orthogonal basis of degree n // get coefficients of PkHx Teuchos::SerialDenseMatrix<int,Scalar> V1(bigN, N); // basis for the space is // { (phi_i,0) }_{i=0}^{scalarLittleN-1} , // { (0,phi_i) }_{i=0}^{scalarLittleN-1} , // { (x,y) \times phi_i}_{i=scalarLittleN}^{scalarBigN-1} // { (x,y) \times phi = (y phi , -x \phi) // columns of V1 are expansion of this basis in terms of the basis // for P_{n}^2 // these two loops get the first two sets of basis functions for (int i=0;i<scalarLittleN;i++) { V1(i,i) = 1.0; V1(scalarBigN+i,scalarLittleN+i) = 1.0; } // now I need to integrate { (x,y) \times phi } against the big basis // first, get a cubature rule. CubatureDirectTriDefault<Scalar,ArrayScalar > myCub( 2 * n ); ArrayScalar cubPoints( myCub.getNumPoints() , 2 ); ArrayScalar cubWeights( myCub.getNumPoints() ); myCub.getCubature( cubPoints , cubWeights ); // tabulate the scalar orthonormal basis at cubature points ArrayScalar phisAtCubPoints( scalarBigN , myCub.getNumPoints() ); Phis_.getValues( phisAtCubPoints , cubPoints , OPERATOR_VALUE ); // now do the integration for (int i=0;i<n;i++) { for (int j=0;j<scalarBigN;j++) { // int (x,y) phi_i \cdot (phi_j,0) V1(j,littleN+i) = 0.0; for (int k=0;k<myCub.getNumPoints();k++) { V1(j,littleN+i) -= cubWeights(k) * cubPoints(k,1) * phisAtCubPoints(scalarSmallestN+i,k) * phisAtCubPoints(j,k); } } for (int j=0;j<scalarBigN;j++) { // int (x,y) phi_i \cdot (0,phi_j) V1(j+scalarBigN,littleN+i) = 0.0; for (int k=0;k<myCub.getNumPoints();k++) { V1(j+scalarBigN,littleN+i) += cubWeights(k) * cubPoints(k,0) * phisAtCubPoints(scalarSmallestN+i,k) * phisAtCubPoints(j,k); } } } //std::cout << V1 << "\n"; // next, apply the RT nodes (rows) to the basis for (P_n)^2 (columns) Teuchos::SerialDenseMatrix<int,Scalar> V2(N , bigN); // first 3 * degree nodes are normals at each edge // get the points on the line ArrayScalar linePts( n , 1 ); if (pointType == POINTTYPE_WARPBLEND) { CubatureDirectLineGauss<Scalar> edgeRule( 2*n - 1 ); ArrayScalar edgeCubWts( n ); edgeRule.getCubature( linePts , edgeCubWts ); } else if (pointType == POINTTYPE_EQUISPACED ) { shards::CellTopology linetop(shards::getCellTopologyData<shards::Line<2> >() ); PointTools::getLattice<Scalar,ArrayScalar >( linePts , linetop , n+1 , 1 , POINTTYPE_EQUISPACED ); } ArrayScalar edgePts( n , 2 ); ArrayScalar phisAtEdgePoints( scalarBigN , n ); ArrayScalar edgeTan(2); for (int i=0;i<3;i++) { // loop over edges CellTools<Scalar>::getReferenceEdgeTangent( edgeTan , i , this->basisCellTopology_ ); /* multiply by 2.0 to account for a Jacobian in Pavel's definition */ for (int j=0;j<2;j++) { edgeTan(j) *= 2.0; } CellTools<Scalar>::mapToReferenceSubcell( edgePts , linePts , 1 , i , this->basisCellTopology_ ); Phis_.getValues( phisAtEdgePoints , edgePts , OPERATOR_VALUE ); // loop over points (rows of V2) for (int j=0;j<n;j++) { // loop over orthonormal basis functions (columns of V2) for (int k=0;k<scalarBigN;k++) { V2(n*i+j,k) = edgeTan(0) * phisAtEdgePoints(k,j); V2(n*i+j,k+scalarBigN) = edgeTan(1) * phisAtEdgePoints(k,j); } } } // remaining nodes are x- and y- components at internal points, if n > 1 // this code is exactly the same as it is for HDIV const int numInternalPoints = PointTools::getLatticeSize( this->getBaseCellTopology() , n + 1 , 1 ); if (numInternalPoints > 0) { ArrayScalar internalPoints( numInternalPoints , 2 ); PointTools::getLattice<Scalar,ArrayScalar >( internalPoints , this->getBaseCellTopology() , n + 1 , 1 , pointType ); ArrayScalar phisAtInternalPoints( scalarBigN , numInternalPoints ); Phis_.getValues( phisAtInternalPoints , internalPoints , OPERATOR_VALUE ); // copy values into right positions of V2 for (int i=0;i<numInternalPoints;i++) { for (int j=0;j<scalarBigN;j++) { // x component V2(3*n+i,j) = phisAtInternalPoints(j,i); // y component V2(3*n+numInternalPoints+i,scalarBigN+j) = phisAtInternalPoints(j,i); } } } // std::cout << "Nodes on big basis\n"; // std::cout << V2 << "\n"; // std::cout << "End nodes\n"; Teuchos::SerialDenseMatrix<int,Scalar> Vsdm( N , N ); // multiply V2 * V1 --> V Vsdm.multiply( Teuchos::NO_TRANS , Teuchos::NO_TRANS , 1.0 , V2 , V1 , 0.0 ); // std::cout << "Vandermonde:\n"; // std::cout << Vsdm << "\n"; // std::cout << "End Vandermonde\n"; Teuchos::SerialDenseSolver<int,Scalar> solver; solver.setMatrix( rcp( &Vsdm , false ) ); solver.invert( ); Teuchos::SerialDenseMatrix<int,Scalar> Csdm( bigN , N ); Csdm.multiply( Teuchos::NO_TRANS , Teuchos::NO_TRANS , 1.0 , V1 , Vsdm , 0.0 ); // std::cout << Csdm << "\n"; for (int i=0;i<bigN;i++) { for (int j=0;j<N;j++) { coeffs_(i,j) = Csdm(i,j); } } initializeTags(); this->basisTagsAreSet_ = true; }
Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_LINE_Cn_FEM( const int n , const ArrayScalar &pts ): latticePts_( n+1 , 1 ), Phis_( n ), V_(n+1,n+1), Vinv_(n+1,n+1) { const int N = n+1; this -> basisCardinality_ = N; this -> basisDegree_ = n; this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() ); this -> basisType_ = BASIS_FEM_FIAT; this -> basisCoordinates_ = COORDINATES_CARTESIAN; this -> basisTagsAreSet_ = false; // check validity of points for (int i=0;i<n;i++) { TEUCHOS_TEST_FOR_EXCEPTION( pts(i,0) >= pts(i+1,0) , std::runtime_error , "Intrepid2::Basis_HGRAD_LINE_Cn_FEM Illegal points given to constructor" ); } // copy points int latticePts, correcting endpoints if needed if (std::abs(pts(0,0)+1.0) < INTREPID_TOL) { latticePts_(0,0) = -1.0; } else { latticePts_(0,0) = pts(0,0); } for (int i=1;i<n;i++) { latticePts_(i,0) = pts(i,0); } if (std::abs(pts(n,0)-1.0) < INTREPID_TOL) { latticePts_(n,0) = 1.0; } else { latticePts_(n,0) = pts(n,0); } // form Vandermonde matrix. Actually, this is the transpose of the VDM, // so we transpose on copy below. Phis_.getValues( V_ , latticePts_ , OPERATOR_VALUE ); // now I need to copy V into a Teuchos array to do the inversion Teuchos::SerialDenseMatrix<int,Scalar> Vsdm(N,N); for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { Vsdm(i,j) = V_(i,j); } } // invert the matrix Teuchos::SerialDenseSolver<int,Scalar> solver; solver.setMatrix( rcp( &Vsdm , false ) ); solver.invert( ); // now I need to copy the inverse into Vinv for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { Vinv_(i,j) = Vsdm(j,i); } } initializeTags(); this->basisTagsAreSet_ = true; }