Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/src/Discretization/Integration/Intrepid_CubatureGenSparseDef.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 
00036 namespace Intrepid {
00037 
00038 /**************************************************************************
00039 **  Function Definitions for Class CubatureGenSparse
00040 ***************************************************************************/
00041 
00042 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00043 CubatureGenSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::CubatureGenSparse(const int degree) :
00044     degree_(degree) {
00045 
00046   SGNodes<int, dimension_> list;
00047   SGNodes<int,dimension_> bigger_rules;
00048 
00049   bool continue_making_first_list = true;
00050   bool more_bigger_rules = true;
00051 
00052   int poly_exp[dimension_];
00053   int level[dimension_];
00054   int temp_big_rule[dimension_];
00055   
00056   for(int i = 0; i<dimension_; i++){
00057     poly_exp[i] = 0;
00058     temp_big_rule[i] = 0;
00059   }
00060 
00061   while(continue_making_first_list){
00062     for(int i = 0; i < dimension_; i++)
00063     {
00064       int max_exp = 0;
00065       if(i == 0)
00066         max_exp = std::max(degree_,1) - Sum(poly_exp,1,dimension_-1);
00067       else if(i == dimension_ -1)
00068         max_exp = std::max(degree_,1) - Sum(poly_exp,0,dimension_-2);
00069       else
00070         max_exp = std::max(degree_,1) - Sum(poly_exp,0,dimension_-1) + poly_exp[i];
00071 
00072       if(poly_exp[i] < max_exp)
00073       {
00074         poly_exp[i]++;
00075         break;
00076       }
00077       else
00078       {
00079         if(i == dimension_-1)
00080           continue_making_first_list = false;
00081         else
00082           poly_exp[i] = 0;
00083           
00084       }
00085     }
00086 
00087     if(continue_making_first_list)
00088     {
00089       for(int j = 0; j < dimension_;j++)
00090       {
00091         /*******************
00092         **  Slow-Gauss
00093         ********************/
00094         level[j] = (int)std::ceil((((Scalar)poly_exp[j])+3.0)/4.0);
00095         /*******************
00096         **  Fast-Gauss
00097         ********************/
00098         //level[j] = intstd::ceil(std::log(poly_exp[j]+3)/std::log(2) - 1);
00099       }
00100       list.addNode(level,1);
00101       
00102     }
00103   }
00104 
00105 
00106   while(more_bigger_rules)
00107   {
00108     bigger_rules.addNode(temp_big_rule,1);
00109 
00110     for(int i = 0; i < dimension_; i++)
00111     {
00112       if(temp_big_rule[i] == 0){
00113         temp_big_rule[i] = 1;
00114         break;
00115       }
00116       else{
00117         if(i == dimension_-1)
00118           more_bigger_rules = false;
00119         else
00120           temp_big_rule[i] = 0;
00121       }
00122     }
00123   } 
00124 
00125   for(int x = 0; x < list.size(); x++){
00126     for(int y = 0; y < bigger_rules.size(); y++)
00127     { 
00128       SGPoint<int, dimension_> next_rule;
00129       for(int t = 0; t < dimension_; t++)
00130         next_rule.coords[t] = list.nodes[x].coords[t] + bigger_rules.nodes[y].coords[t];
00131 
00132       bool is_in_set = false;
00133       for(int z = 0; z < list.size(); z++)
00134       {
00135         if(next_rule == list.nodes[z]){
00136           is_in_set = true;
00137           break;
00138         }
00139       }
00140 
00141       if(is_in_set)
00142       {
00143         int big_sum[dimension_];
00144         for(int i = 0; i < dimension_; i++)
00145           big_sum[i] = bigger_rules.nodes[y].coords[i];
00146         Scalar coeff = std::pow(-1.0, Sum(big_sum, 0, dimension_-1));
00147         
00148         Scalar point[dimension_];
00149         int point_record[dimension_];
00150 
00151         for(int j = 0; j<dimension_; j++)
00152           point_record[j] = 1;
00153 
00154         bool more_points = true;
00155 
00156         while(more_points)
00157         {
00158           Scalar weight = 1.0;
00159         
00160           for(int w = 0; w < dimension_; w++){
00161             /*******************
00162             **  Slow-Gauss
00163             ********************/
00164             int order1D = 2*list.nodes[x].coords[w]-1;
00165             /*******************
00166             **  Fast-Gauss
00167             ********************/
00168             //int order1D = (int)std::pow(2.0,next_rule.coords[w]) - 1;
00169 
00170             int cubDegree1D = 2*order1D - 1;
00171             CubatureDirectLineGauss<Scalar> Cub1D(cubDegree1D);
00172             FieldContainer<Scalar> cubPoints1D(order1D, 1);
00173             FieldContainer<Scalar> cubWeights1D(order1D);
00174 
00175             Cub1D.getCubature(cubPoints1D, cubWeights1D);
00176 
00177             point[w] =  cubPoints1D(point_record[w]-1, 0);
00178             weight = weight * cubWeights1D(point_record[w]-1);
00179           }     
00180           weight = weight*coeff;
00181           grid.addNode(point, weight);
00182 
00183           for(int v = 0; v < dimension_; v++)
00184           {
00185             if(point_record[v] < 2*list.nodes[x].coords[v]-1){
00186               (point_record[v])++;
00187               break;
00188             }
00189             else{
00190               if(v == dimension_-1)
00191                 more_points = false;
00192               else
00193                 point_record[v] = 1;
00194             }
00195           }
00196         }
00197       }
00198     }
00199   }
00200 
00201   numPoints_ = grid.size();
00202 }
00203 
00204 
00205 
00206 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00207 void CubatureGenSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getCubature(ArrayPoint  & cubPoints,
00208                                                                               ArrayWeight & cubWeights) const{
00209   grid.copyToArrays(cubPoints, cubWeights);
00210 } // end getCubature
00211 
00212 
00213 
00214 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00215 int CubatureGenSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getNumPoints() const {
00216   return numPoints_;
00217 } // end getNumPoints
00218 
00219 
00220 
00221 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00222 int CubatureGenSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getDimension() const {
00223   return dimension_;
00224 } // end dimension
00225 
00226 
00227 
00228 template <class Scalar, int dimension_, class ArrayPoint, class ArrayWeight>
00229 void CubatureGenSparse<Scalar,dimension_,ArrayPoint,ArrayWeight>::getAccuracy(std::vector<int> & accuracy) const {
00230   accuracy.assign(1, degree_);
00231 } //end getAccuracy
00232 
00233 
00234 } // end namespace Intrepid