Intrepid
http://trilinos.sandia.gov/packages/docs/r10.10/packages/intrepid/src/Discretization/Integration/Intrepid_CubatureSparseDef.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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Pavel Bochev  (pbboche@sandia.gov)
00038 //                    Denis Ridzal  (dridzal@sandia.gov), or
00039 //                    Kara Peterson (kjpeter@sandia.gov)
00040 //
00041 // ************************************************************************
00042 // @HEADER
00043 
00050 namespace Intrepid {
00051 
00052 /**************************************************************************
00053 **  Function Definitions for Class CubatureSparse
00054 ***************************************************************************/
00055 
00056 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00057 CubatureSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::CubatureSparse(const int degree) :
00058   degree_(degree) {
00059 
00060   if(dimension_ == 2)
00061   {
00062     if(degree == 1)
00063       level_ = 1;
00064     else if(degree <= 3)
00065       level_ = 2;
00066     else if(degree <= 7)
00067       level_ = 3;
00068     else if(degree <= 11)
00069       level_ = 4;
00070     else if(degree <= 15)
00071       level_ = 5;
00072     else if(degree <= 19)
00073       level_ = 6;
00074     else if(degree <= 23)
00075       level_ = 7;
00076     else if(degree <= 27)
00077       level_ = 8;
00078     else if(degree <= 31)
00079       level_ = 9;
00080     else if(degree <= 35)
00081       level_ = 10;
00082     else if(degree <= 39)
00083       level_ = 11;
00084     else if(degree <= 43)
00085       level_ = 12;
00086     else if(degree <= 47)
00087       level_ = 13;
00088     else if(degree <= 51)
00089       level_ = 14;
00090     else if(degree <= 55)
00091       level_ = 15;
00092     else if(degree <= 59)
00093       level_ = 16;
00094   }
00095   else if(dimension_ == 3)
00096   {
00097     if(degree == 1)
00098       level_ = 1;
00099     else if(degree <= 3)
00100       level_ = 2;
00101     else if(degree <= 5)
00102       level_ = 3;
00103     else if(degree <= 9)
00104       level_ = 4;
00105     else if(degree <= 13)
00106       level_ = 5;
00107     else if(degree <= 17)
00108       level_ = 6;
00109     else if(degree <= 21)
00110       level_ = 7;
00111     else if(degree <= 25)
00112       level_ = 8;
00113     else if(degree <= 29)
00114       level_ = 9;
00115     else if(degree <= 33)
00116       level_ = 10;
00117     else if(degree <= 37)
00118       level_ = 11;
00119     else if(degree <= 41)
00120       level_ = 12;
00121     else if(degree <= 45)
00122       level_ = 13;
00123     else if(degree <= 49)
00124       level_ = 14;
00125     else if(degree <= 53)
00126       level_ = 15;
00127     else if(degree <= 57)
00128       level_ = 16;
00129   }
00130 
00131   numPoints_ = calculateNumPoints(dimension_,level_);
00132 }
00133 
00134 
00135 
00136 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00137 void CubatureSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getCubature(ArrayPoint  & cubPoints,
00138                                                                            ArrayWeight & cubWeights) const{
00139   Teuchos::Array<Scalar> dummy_point(1);
00140   dummy_point[0] = 0.0;
00141   Scalar dummy_weight = 1.0;
00142   SGNodes<Scalar, dimension_> grid;
00143 
00144   iterateThroughDimensions(level_, dimension_, grid, dummy_point, dummy_weight);
00145   
00146   grid.copyToArrays(cubPoints, cubWeights);
00147 } // end getCubature
00148 
00149 
00150 
00151 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00152 int CubatureSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getNumPoints() const {
00153   return numPoints_;
00154 } // end getNumPoints
00155 
00156 
00157 
00158 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00159 int CubatureSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getDimension() const {
00160   return dimension_;
00161 } // end dimension
00162 
00163 
00164 
00165 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00166 void CubatureSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getAccuracy(std::vector<int> & accuracy) const {
00167   accuracy.assign(1, degree_);
00168 } //end getAccuracy
00169 
00170 
00171 
00172 /************************************************************************
00173 **     Function Definition for iterateThroughDimensions() 
00174 **                 and its helper functions
00175 *************************************************************************/
00176 
00177 template< class Scalar, int DIM>
00178 void iterateThroughDimensions(int level,
00179                               int dims_left,
00180                               SGNodes<Scalar,DIM> & cubPointsND,
00181                               Teuchos::Array<Scalar> & partial_node,
00182                               Scalar partial_weight)
00183 {
00184   int l = level;
00185   int d = DIM;
00186   int add_on = d - dims_left;
00187   int start = dims_left > 1 ? 1 : (int)std::max(1, l);
00188   int end = l + add_on;
00189 
00190   for(int k_i = start; k_i <= end; k_i++)
00191   {
00192     /*******************
00193     **  Slow-Gauss
00194     ********************/
00195     int order1D = 2*k_i-1;
00196 
00197     /*******************
00198     **  Fast-Gauss
00199     ********************/
00200     //int order1D = (int)pow(2,k_i) - 1;
00201 
00202     int cubDegree1D = 2*order1D - 1;
00203     CubatureDirectLineGauss<Scalar> Cub1D(cubDegree1D);
00204     FieldContainer<Scalar> cubPoints1D(order1D, 1);
00205     FieldContainer<Scalar> cubWeights1D(order1D);
00206 
00207     Cub1D.getCubature(cubPoints1D, cubWeights1D);
00208 
00209     for(int node1D = 0; node1D < order1D; node1D++)
00210     {
00211       Teuchos::Array<Scalar> node(d-dims_left+1);
00212       node[d-dims_left] = cubPoints1D(node1D,0);
00213       for(int m = 0; m < d-dims_left; m++)
00214         node[m] = partial_node[m];
00215 
00216       Scalar weight = cubWeights1D(node1D)*partial_weight;
00217 
00218       if(dims_left != 1)
00219       {
00220         iterateThroughDimensions(l - k_i, dims_left-1, cubPointsND, node, weight);
00221       }
00222       else
00223       {
00224         weight = pow(-1.0, end - k_i)*combination(d-1, k_i - l)*weight;
00225         cubPointsND.addNode(&node[0], weight);
00226       }
00227     }
00228   }
00229 }
00230 
00231 } // end namespace Intrepid