Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/src/Discretization/Basis/Intrepid_HGRAD_LINE_Cn_FEM_JACOBIDef.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ************************************************************************
00003 //
00004 //                           Intrepid Package
00005 //                 Copyright (2007) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Pavel Bochev (pbboche@sandia.gov) or
00025 //                    Denis Ridzal (dridzal@sandia.gov).
00026 //
00027 // ************************************************************************
00028 // @HEADER
00029 
00035 namespace Intrepid {
00036 
00037 
00038 template<class Scalar, class ArrayScalar>
00039 Basis_HGRAD_LINE_Cn_FEM_JACOBI<Scalar,ArrayScalar>::Basis_HGRAD_LINE_Cn_FEM_JACOBI(int order, Scalar alpha, Scalar beta) {
00040     this -> basisCardinality_  = order+1;
00041     this -> basisDegree_       = order;    
00042     this -> jacobiAlpha_       = alpha;    
00043     this -> jacobiBeta_        = beta;    
00044     this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<> >() );
00045     this -> basisType_         = BASIS_FEM_HIERARCHICAL;
00046     this -> basisCoordinates_  = COORDINATES_CARTESIAN;
00047     this -> basisTagsAreSet_   = false;
00048 }
00049 
00050 
00051 
00052 template<class Scalar, class ArrayScalar> 
00053 void Basis_HGRAD_LINE_Cn_FEM_JACOBI<Scalar, ArrayScalar>::getValues(ArrayScalar &        outputValues,
00054                                                                     const ArrayScalar &  inputPoints,
00055                                                                     const EOperator      operatorType) const {
00056   
00057   // Verify arguments
00058 #ifdef HAVE_INTREPID_DEBUG
00059   Intrepid::getValues_HGRAD_Args<Scalar, ArrayScalar>(outputValues,
00060                                                       inputPoints,
00061                                                       operatorType,
00062                                                       this -> getBaseCellTopology(),
00063                                                       this -> getCardinality() );
00064 #endif
00065   
00066   // Number of evaluation points = dimension 0 of inputPoints
00067   int numPoints = inputPoints.dimension(0);  
00068   
00069   Teuchos::Array<Scalar> tmpPoints(numPoints);
00070   Teuchos::Array<Scalar> jacobiPolyAtPoints(numPoints);
00071 
00072   // Copy inputPoints into tmpPoints, to prepare for call to jacobfd
00073   for (int i=0; i<numPoints; i++) {
00074     tmpPoints[i] = inputPoints(i, 0);
00075   }
00076 
00077   try {
00078     switch (operatorType) {
00079     case OPERATOR_VALUE: {
00080       for (int ord = 0; ord < this -> basisCardinality_; ord++) {
00081         IntrepidPolylib::jacobfd(numPoints, &tmpPoints[0], &jacobiPolyAtPoints[0], (Scalar*)0, ord, jacobiAlpha_, jacobiBeta_);
00082         for (int pt = 0; pt < numPoints; pt++) {
00083           // outputValues is a rank-2 array with dimensions (basisCardinality_, numPoints)
00084           outputValues(ord, pt) = jacobiPolyAtPoints[pt];
00085         }
00086       }
00087     }
00088     break;
00089       
00090     case OPERATOR_GRAD:
00091     case OPERATOR_D1: {
00092       for (int ord = 0; ord < this -> basisCardinality_; ord++) {
00093         IntrepidPolylib::jacobd(numPoints, &tmpPoints[0], &jacobiPolyAtPoints[0], ord, jacobiAlpha_, jacobiBeta_);
00094         for (int pt = 0; pt < numPoints; pt++) {
00095           // outputValues is a rank-2 array with dimensions (basisCardinality_, numPoints)
00096           outputValues(ord, pt, 0) = jacobiPolyAtPoints[pt];
00097         }
00098       }
00099     }
00100     break;
00101 
00102     case OPERATOR_D2:
00103     case OPERATOR_D3:
00104     case OPERATOR_D4:
00105     case OPERATOR_D5:
00106     case OPERATOR_D6:
00107     case OPERATOR_D7:
00108     case OPERATOR_D8:
00109     case OPERATOR_D9:
00110     case OPERATOR_D10: {
00111       int d_order = getOperatorOrder( operatorType );
00112       // fill in derivatives of polynomials of degree 0 through d_order - 1  with 0
00113       // e.g. D2 annhialates linears.
00114       int stop_order;
00115       if (d_order > this->getDegree()) {
00116         stop_order = this->getDegree();
00117       }
00118       else {
00119         stop_order = d_order;
00120       }
00121       for (int p_order=0;p_order<stop_order;p_order++) {
00122         for (int pt=0;pt<numPoints;pt++) {
00123           outputValues(p_order,pt,0) = 0.0;
00124         }
00125       }
00126       // fill in rest of derivatives with the differentiation rule for Jacobi polynomials
00127       for (int p_order=d_order;p_order<=this->getDegree();p_order++) {
00128         // calculate the scaling factor with a little loop.
00129         Scalar scalefactor = 1.0;
00130         for (int d=1;d<=d_order;d++) {
00131           scalefactor *= 0.5 * ( p_order + jacobiAlpha_ + jacobiBeta_ + d );
00132         }
00133 
00134         // put in the right call to IntrepidPolyLib
00135         IntrepidPolylib::jacobfd(numPoints, &tmpPoints[0], 
00136                                  &jacobiPolyAtPoints[0], 
00137                                  (Scalar*)0, p_order-d_order, 
00138                                  jacobiAlpha_ + d_order, 
00139                                  jacobiBeta_ + d_order);
00140         for (int pt = 0; pt < numPoints; pt++) {
00141           // outputValues is a rank-3 array with dimensions (basisCardinality_, numPoints)
00142           outputValues(p_order, pt,0) = scalefactor *jacobiPolyAtPoints[pt];
00143         }
00144         
00145       }
00146       
00147     }
00148     break;
00149     case OPERATOR_DIV:
00150     case OPERATOR_CURL:
00151         TEST_FOR_EXCEPTION( !( Intrepid::isValidOperator(operatorType) ), std::invalid_argument,
00152                             ">>> ERROR (Basis_HGRAD_LINE_Cn_FEM_JACOBI): Invalid operator type.");
00153       break;
00154     default:
00155       TEST_FOR_EXCEPTION( !( Intrepid::isValidOperator(operatorType) ), std::invalid_argument,
00156                           ">>> ERROR (Basis_HGRAD_LINE_Cn_FEM_JACOBI): Invalid operator type.");
00157       break;
00158     }
00159   }
00160   catch (std::invalid_argument &exception){
00161     TEST_FOR_EXCEPTION( true , std::invalid_argument,
00162                         ">>> ERROR (Basis_HGRAD_LINE_Cn_FEM_JACOBI): Operator failed");    
00163   }
00164 }
00165 
00166 
00167 
00168 template<class Scalar, class ArrayScalar>
00169 void Basis_HGRAD_LINE_Cn_FEM_JACOBI<Scalar, ArrayScalar>::getValues(ArrayScalar&           outputValues,
00170                                                                     const ArrayScalar &    inputPoints,
00171                                                                     const ArrayScalar &    cellVertices,
00172                                                                     const EOperator        operatorType) const {
00173   TEST_FOR_EXCEPTION( (true), std::logic_error,
00174                       ">>> ERROR (Basis_HGRAD_LINE_Cn_FEM_JACOBI): FEM Basis calling an FVD member function");
00175 }
00176 
00177 
00178 
00179 template<class Scalar, class ArrayScalar>
00180 void Basis_HGRAD_LINE_Cn_FEM_JACOBI<Scalar, ArrayScalar>::setBasisParameters(int n, Scalar alpha, Scalar beta) {
00181   this -> basisCardinality_  = n+1;
00182   this -> basisDegree_       = n;
00183   this -> jacobiAlpha_       = alpha;
00184   this -> jacobiBeta_        = beta;
00185   this -> initializeTags();
00186 }
00187 
00188 
00189 
00190 template<class Scalar, class ArrayScalar>
00191 void Basis_HGRAD_LINE_Cn_FEM_JACOBI<Scalar, ArrayScalar>::initializeTags() {
00192 
00193   // Basis-dependent initializations
00194 
00195   int tagSize  = 4;        // size of DoF tag, i.e., number of fields in the tag
00196   int posScDim = 0;        // position in the tag, counting from 0, of the subcell dim
00197   int posScOrd = 1;        // position in the tag, counting from 0, of the subcell ordinal
00198   int posDfOrd = 2;        // position in the tag, counting from 0, of DoF ordinal relative to the subcell
00199 
00200   FieldContainer<int> tags(this->basisCardinality_, 4);
00201 
00202   for (int i=0; i < this->basisCardinality_; i++) {
00203     tags(i, 0) = 1;                        // these are all "internal" i.e. "volume" DoFs
00204     tags(i, 1) = 0;                        // there is only one line
00205     tags(i, 2) = i;                        // local DoF id 
00206     tags(i, 3) = this->basisCardinality_;  // total number of DoFs 
00207   }
00208 
00209   // Basis-independent function, sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays:
00210   Intrepid::setOrdinalTagData(this -> tagToOrdinal_,
00211                               this -> ordinalToTag_,
00212                               &tags[0],
00213                               this -> basisCardinality_,
00214                               tagSize,
00215                               posScDim,
00216                               posScOrd,
00217                               posDfOrd);
00218 }
00219 
00220 }// namespace Intrepid