|
Intrepid
|
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
1.7.4