Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/src/Discretization/Integration/Intrepid_CubatureTensorDef.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 template <class Scalar, class ArrayPoint, class ArrayWeight>
00038 CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::CubatureTensor(std::vector< Teuchos::RCP<Cubature<Scalar,ArrayPoint,ArrayWeight> > > cubatures) {
00039   unsigned numCubs = cubatures.size();
00040   TEST_FOR_EXCEPTION( (numCubs < 1),
00041                       std::out_of_range,
00042                       ">>> ERROR (CubatureTensor): Input cubature array must be of size 1 or larger.");
00043 
00044   cubatures_ = cubatures;
00045 
00046   std::vector<int> tmp;
00047   unsigned numDegrees = 0;
00048   for (unsigned i=0; i<numCubs; i++) {
00049     cubatures[i]->getAccuracy(tmp);
00050     numDegrees += tmp.size();
00051   }
00052 
00053   degree_.assign(numDegrees, 0);
00054   int count  = 0;
00055   dimension_ = 0;
00056   for (unsigned i=0; i<numCubs; i++) {
00057     cubatures[i]->getAccuracy(tmp);
00058     for (unsigned j=0; j<tmp.size(); j++) {
00059       degree_[count] = tmp[j];
00060       count++;
00061     }
00062     dimension_ += cubatures[i]->getDimension();
00063   }
00064 }
00065 
00066 
00067 
00068 template <class Scalar, class ArrayPoint, class ArrayWeight>
00069 CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::CubatureTensor(Teuchos::RCP<CubatureDirect<Scalar,ArrayPoint,ArrayWeight> > cubature1,
00070                                                               Teuchos::RCP<CubatureDirect<Scalar,ArrayPoint,ArrayWeight> > cubature2) {
00071   cubatures_.resize(2);
00072   cubatures_[0] = cubature1;
00073   cubatures_[1] = cubature2;
00074 
00075   degree_.assign(2, 0);
00076   std::vector<int> d(1);
00077   cubatures_[0]->getAccuracy(d); degree_[0] = d[0];
00078   cubatures_[1]->getAccuracy(d); degree_[1] = d[0];
00079 
00080   dimension_ = cubatures_[0]->getDimension() + cubatures_[1]->getDimension();
00081 }
00082 
00083 
00084 
00085 template <class Scalar, class ArrayPoint, class ArrayWeight>
00086 CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::CubatureTensor(Teuchos::RCP<CubatureDirect<Scalar,ArrayPoint,ArrayWeight> > cubature1,
00087                                                               Teuchos::RCP<CubatureDirect<Scalar,ArrayPoint,ArrayWeight> > cubature2,
00088                                                               Teuchos::RCP<CubatureDirect<Scalar,ArrayPoint,ArrayWeight> > cubature3) {
00089   cubatures_.resize(3);
00090   cubatures_[0] = cubature1;
00091   cubatures_[1] = cubature2;
00092   cubatures_[2] = cubature3;
00093 
00094   degree_.assign(3, 0);
00095   std::vector<int> d(1);
00096   cubatures_[0]->getAccuracy(d); degree_[0] = d[0];
00097   cubatures_[1]->getAccuracy(d); degree_[1] = d[0];
00098   cubatures_[2]->getAccuracy(d); degree_[2] = d[0];
00099 
00100   dimension_ = cubatures_[0]->getDimension() + cubatures_[1]->getDimension() + cubatures_[2]->getDimension();
00101 }
00102 
00103 
00104 
00105 template <class Scalar, class ArrayPoint, class ArrayWeight>
00106 CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::CubatureTensor(Teuchos::RCP<CubatureDirect<Scalar,ArrayPoint,ArrayWeight> > cubature, int n) {
00107   cubatures_.resize(n);
00108   for (int i=0; i<n; i++) {
00109     cubatures_[i] = cubature;
00110   }
00111 
00112   std::vector<int> d(1);
00113   cubatures_[0]->getAccuracy(d);
00114   degree_.assign(n,d[0]);
00115 
00116   dimension_ = cubatures_[0]->getDimension()*n;
00117 }
00118 
00119 
00120 
00121 template <class Scalar, class ArrayPoint, class ArrayWeight>
00122 void CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::getCubature(ArrayPoint  & cubPoints,
00123                                                                 ArrayWeight & cubWeights) const {
00124   int numCubPoints = getNumPoints();
00125   int cubDim       = getDimension();
00126   // check size of cubPoints and cubWeights
00127   TEST_FOR_EXCEPTION( ( ( (int)cubPoints.size() < numCubPoints*cubDim ) || ( (int)cubWeights.size() < numCubPoints ) ),
00128                       std::out_of_range,
00129                       ">>> ERROR (CubatureTensor): Insufficient space allocated for cubature points or weights.");
00130 
00131   unsigned numCubs   = cubatures_.size();
00132   std::vector<unsigned> numLocPoints(numCubs);
00133   std::vector<unsigned> locDim(numCubs);
00134   std::vector< FieldContainer<Scalar> > points(numCubs);
00135   std::vector< FieldContainer<Scalar> > weights(numCubs);
00136 
00137   // extract required points and weights
00138   for (unsigned i=0; i<numCubs; i++) {
00139 
00140     numLocPoints[i] = cubatures_[i]->getNumPoints();
00141     locDim[i]       = cubatures_[i]->getDimension();
00142     points[i].resize(numLocPoints[i], locDim[i]);
00143     weights[i].resize(numLocPoints[i]);
00144 
00145     // cubPoints and cubWeights are used here only for temporary data retrieval
00146     cubatures_[i]->getCubature(cubPoints, cubWeights);
00147     for (unsigned pt=0; pt<numLocPoints[i]; pt++) {
00148       for (unsigned d=0; d<locDim[i]; d++) {
00149         points[i](pt,d) = cubPoints(pt,d);
00150         weights[i](pt)  = cubWeights(pt);
00151       }
00152     }
00153 
00154   }
00155 
00156   // reset all weights to 1.0
00157   for (int i=0; i<numCubPoints; i++) {
00158       cubWeights(i) = (Scalar)1.0;
00159   }
00160 
00161   // fill tensor-product cubature
00162   int globDimCounter = 0;
00163   int shift          = 1;
00164   for (unsigned i=0; i<numCubs; i++) {
00165 
00166     for (int j=0; j<numCubPoints; j++) {
00167       /* int itmp = ((j*shift) % numCubPoints) + (j / (numCubPoints/shift)); // equivalent, but numerically unstable */
00168       int itmp = (j % (numCubPoints/shift))*shift + (j / (numCubPoints/shift));
00169       for (unsigned k=0; k<locDim[i]; k++) {
00170         cubPoints(itmp , globDimCounter+k) = points[i](j % numLocPoints[i], k);
00171       }
00172       cubWeights( itmp ) *= weights[i](j % numLocPoints[i]);
00173     }
00174     
00175     shift *= numLocPoints[i];
00176     globDimCounter += locDim[i];
00177   }
00178 
00179 } // end getCubature
00180 
00181 
00182 
00183 template <class Scalar, class ArrayPoint, class ArrayWeight>
00184 int CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::getNumPoints() const {
00185   unsigned numCubs = cubatures_.size();
00186   int numCubPoints = 1;
00187   for (unsigned i=0; i<numCubs; i++) {
00188     numCubPoints *= cubatures_[i]->getNumPoints();
00189   }
00190   return numCubPoints;
00191 } // end getNumPoints
00192 
00193 
00194 template <class Scalar, class ArrayPoint, class ArrayWeight>
00195 int CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::getDimension() const {
00196   return dimension_;
00197 } // end dimension
00198 
00199 
00200 
00201 template <class Scalar, class ArrayPoint, class ArrayWeight>
00202 void CubatureTensor<Scalar,ArrayPoint,ArrayWeight>::getAccuracy(std::vector<int> & degree) const {
00203   degree = degree_;
00204 } // end getAccuracy
00205 
00206 } // end namespace Intrepid