00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035 namespace Intrepid {
00036
00037 template <class Scalar, class ArrayType>
00038 CubatureTensor<Scalar,ArrayType>::CubatureTensor(std::vector< Teuchos::RCP<Cubature<Scalar,ArrayType> > > 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 ArrayType>
00069 CubatureTensor<Scalar,ArrayType>::CubatureTensor(Teuchos::RCP<CubatureDirect<Scalar,ArrayType> > cubature1,
00070 Teuchos::RCP<CubatureDirect<Scalar,ArrayType> > 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 ArrayType>
00086 CubatureTensor<Scalar,ArrayType>::CubatureTensor(Teuchos::RCP<CubatureDirect<Scalar,ArrayType> > cubature1,
00087 Teuchos::RCP<CubatureDirect<Scalar,ArrayType> > cubature2,
00088 Teuchos::RCP<CubatureDirect<Scalar,ArrayType> > 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 ArrayType>
00106 CubatureTensor<Scalar,ArrayType>::CubatureTensor(Teuchos::RCP<CubatureDirect<Scalar,ArrayType> > 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 ArrayType>
00122 void CubatureTensor<Scalar,ArrayType>::getCubature(ArrayType & cubPoints,
00123 ArrayType & cubWeights) const {
00124 int numCubPoints = getNumPoints();
00125 int cubDim = getDimension();
00126
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
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
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
00157 for (int i=0; i<numCubPoints; i++) {
00158 cubWeights(i) = (Scalar)1.0;
00159 }
00160
00161
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
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 }
00180
00181
00182
00183 template <class Scalar, class ArrayType>
00184 int CubatureTensor<Scalar,ArrayType>::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 }
00192
00193
00194 template <class Scalar, class ArrayType>
00195 int CubatureTensor<Scalar,ArrayType>::getDimension() const {
00196 return dimension_;
00197 }
00198
00199
00200
00201 template <class Scalar, class ArrayType>
00202 void CubatureTensor<Scalar,ArrayType>::getAccuracy(std::vector<int> & degree) const {
00203 degree = degree_;
00204 }
00205
00206 }