|
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 // 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: Alejandro Mota (amota@sandia.gov) 00038 // 00039 // ************************************************************************ 00040 // @HEADER 00041 00042 #if !defined(Intrepid_MiniTensor_Geometry_i_h) 00043 #define Intrepid_MiniTensor_Geometry_i_h 00044 00045 00046 namespace Intrepid { 00047 00048 // 00049 // Helper functions for determining the type of element 00050 // 00051 namespace { 00052 00053 inline 00054 ELEMENT::Type 00055 find_type_1D(Index const nodes) 00056 { 00057 switch (nodes) { 00058 case 2: return ELEMENT::SEGMENTAL; 00059 default: return ELEMENT::UNKNOWN; 00060 } 00061 } 00062 00063 inline 00064 ELEMENT::Type 00065 find_type_2D(Index const nodes) 00066 { 00067 switch (nodes) { 00068 case 3: return ELEMENT::TRIANGULAR; 00069 case 4: return ELEMENT::QUADRILATERAL; 00070 default: return ELEMENT::UNKNOWN; 00071 } 00072 } 00073 00074 inline 00075 ELEMENT::Type 00076 find_type_3D(Index const nodes) 00077 { 00078 switch (nodes) { 00079 case 4: return ELEMENT::TETRAHEDRAL; 00080 case 8: return ELEMENT::HEXAHEDRAL; 00081 default: return ELEMENT::UNKNOWN; 00082 } 00083 } 00084 00085 } // anonymous namespace 00086 00087 00088 // 00089 // 00090 // 00091 inline 00092 ELEMENT::Type 00093 find_type(Index const dimension, Index const number_nodes) 00094 { 00095 00096 ELEMENT::Type 00097 type = ELEMENT::UNKNOWN; 00098 00099 switch (dimension) { 00100 00101 case 1: 00102 type = find_type_1D(number_nodes); 00103 break; 00104 00105 case 2: 00106 type = find_type_2D(number_nodes); 00107 break; 00108 00109 case 3: 00110 type = find_type_3D(number_nodes); 00111 break; 00112 00113 default: 00114 break; 00115 00116 } 00117 00118 if (type == ELEMENT::UNKNOWN) { 00119 std::cerr << "ERROR: " << __PRETTY_FUNCTION__; 00120 std::cerr << std::endl; 00121 std::cerr << "Unknown element type." << std::endl; 00122 std::cerr << std::endl; 00123 std::cerr << "Spatial dimension: "; 00124 std::cerr << dimension << std::endl; 00125 std::cerr << "Vertices per element: "; 00126 std::cerr << number_nodes << std::endl; 00127 exit(1); 00128 } 00129 00130 return type; 00131 } 00132 00133 // 00134 // Constructor for SphericalParametrization 00135 // 00136 template<typename T, Index N> 00137 inline 00138 SphericalParametrization<T, N>::SphericalParametrization( 00139 Tensor4<T, N> const & A) : tangent_(A) 00140 { 00141 minimum_ = std::numeric_limits<T>::max(); 00142 maximum_ = std::numeric_limits<T>::min(); 00143 return; 00144 } 00145 00146 // 00147 // Evaluation for SphericalParemetrization 00148 // 00149 template<typename T, Index N> 00150 inline 00151 void 00152 SphericalParametrization<T, N>::operator()( 00153 Vector<T, dimension_const<N, 2>::value> const & parameters 00154 ) 00155 { 00156 T const & 00157 phi = parameters(0); 00158 00159 T const & 00160 theta = parameters(1); 00161 00162 Vector<T, N> const 00163 normal(sin(phi) * sin(theta), cos(phi), sin(phi) * cos(theta)); 00164 00165 // Localization tensor 00166 Tensor<T, N> const 00167 Q = dot(normal, dot(tangent_, normal)); 00168 00169 T const 00170 determinant = det(Q); 00171 00172 if (determinant < minimum_) { 00173 minimum_ = determinant; 00174 arg_minimum_ = parameters; 00175 } 00176 00177 if (determinant > maximum_) { 00178 maximum_ = determinant; 00179 arg_maximum_ = parameters; 00180 } 00181 00182 return; 00183 } 00184 00185 // 00186 // Constructor for StereographicParametrization 00187 // 00188 template<typename T, Index N> 00189 inline 00190 StereographicParametrization<T, N>::StereographicParametrization( 00191 Tensor4<T, N> const & A) : tangent_(A) 00192 { 00193 minimum_ = std::numeric_limits<T>::max(); 00194 maximum_ = std::numeric_limits<T>::min(); 00195 return; 00196 } 00197 00198 // 00199 // Evaluation for StereographicParemetrization 00200 // 00201 template<typename T, Index N> 00202 inline 00203 void 00204 StereographicParametrization<T, N>::operator()( 00205 Vector<T, dimension_const<N, 2>::value> const & parameters 00206 ) 00207 { 00208 T const & 00209 x = parameters(0); 00210 00211 T const & 00212 y = parameters(1); 00213 00214 T const 00215 r2 = x * x + y * y; 00216 00217 Vector<T, N> 00218 normal(2.0 * x, 2.0 * y, r2 - 1.0); 00219 00220 normal /= (r2 + 1.0); 00221 00222 // Localization tensor 00223 Tensor<T, N> const 00224 Q = dot(normal, dot(tangent_, normal)); 00225 00226 T const 00227 determinant = det(Q); 00228 00229 if (determinant < minimum_) { 00230 minimum_ = determinant; 00231 arg_minimum_ = parameters; 00232 } 00233 00234 if (determinant > maximum_) { 00235 maximum_ = determinant; 00236 arg_maximum_ = parameters; 00237 } 00238 00239 return; 00240 } 00241 00242 // 00243 // Constructor for ProjectiveParametrization 00244 // 00245 template<typename T, Index N> 00246 inline 00247 ProjectiveParametrization<T, N>::ProjectiveParametrization( 00248 Tensor4<T, N> const & A) : tangent_(A) 00249 { 00250 minimum_ = std::numeric_limits<T>::max(); 00251 maximum_ = std::numeric_limits<T>::min(); 00252 return; 00253 } 00254 00255 // 00256 // Evaluation for ProjectiveParemetrization 00257 // 00258 template<typename T, Index N> 00259 inline 00260 void 00261 ProjectiveParametrization<T, N>::operator()( 00262 Vector<T, dimension_const<N, 4>::value> const & parameters 00263 ) 00264 { 00265 T const & 00266 x = parameters(0); 00267 00268 T const & 00269 y = parameters(1); 00270 00271 T const & 00272 z = parameters(2); 00273 00274 T const & 00275 lambda = parameters(3); 00276 00277 const Vector<T, N> 00278 normal(x, y, z); 00279 00280 // Localization tensor 00281 Tensor<T, N> const 00282 Q = dot(normal, dot(tangent_, normal)); 00283 00284 T const 00285 determinant = det(Q); 00286 00287 T const 00288 function = determinant + lambda * (x * x + y * y + z * z - 1.0); 00289 00290 if (function < minimum_) { 00291 minimum_ = function; 00292 arg_minimum_ = parameters; 00293 } 00294 00295 if (function > maximum_) { 00296 maximum_ = function; 00297 arg_maximum_ = parameters; 00298 } 00299 00300 return; 00301 } 00302 00303 // 00304 // Constructor for TangentParametrization 00305 // 00306 template<typename T, Index N> 00307 inline 00308 TangentParametrization<T, N>::TangentParametrization( 00309 Tensor4<T, N> const & A) : tangent_(A) 00310 { 00311 minimum_ = std::numeric_limits<T>::max(); 00312 maximum_ = std::numeric_limits<T>::min(); 00313 return; 00314 } 00315 00316 // 00317 // Evaluation for TangentParemetrization 00318 // 00319 template<typename T, Index N> 00320 inline 00321 void 00322 TangentParametrization<T, N>::operator()( 00323 Vector<T, dimension_const<N, 2>::value> const & parameters 00324 ) 00325 { 00326 assert(parameters.get_dimension() == 2); 00327 00328 T const & 00329 x = parameters(0); 00330 00331 T const & 00332 y = parameters(1); 00333 00334 T const 00335 r = std::sqrt(x * x + y * y); 00336 00337 Vector<T, N> 00338 normal(3, ZEROS); 00339 00340 if (r > 0.0) { 00341 normal(0) = x * sin(r) / r; 00342 normal(1) = y * sin(r) / r; 00343 normal(2) = cos(r); 00344 } 00345 00346 // Localization tensor 00347 Tensor<T, N> const 00348 Q = dot(normal, dot(tangent_, normal)); 00349 00350 T const 00351 determinant = det(Q); 00352 00353 if (determinant < minimum_) { 00354 minimum_ = determinant; 00355 arg_minimum_ = parameters; 00356 } 00357 00358 if (determinant > maximum_) { 00359 maximum_ = determinant; 00360 arg_maximum_ = parameters; 00361 } 00362 00363 return; 00364 } 00365 00366 // 00367 // Constructor for CartesianParametrization 00368 // 00369 template<typename T, Index N> 00370 inline 00371 CartesianParametrization<T, N>::CartesianParametrization( 00372 Tensor4<T, N> const & A) : tangent_(A) 00373 { 00374 minimum_ = std::numeric_limits<T>::max(); 00375 maximum_ = std::numeric_limits<T>::min(); 00376 return; 00377 } 00378 00379 // 00380 // Evaluation for CartesianParemetrization 00381 // 00382 template<typename T, Index N> 00383 inline 00384 void 00385 CartesianParametrization<T, N>::operator()( 00386 Vector<T, dimension_const<N, 3>::value> const & parameters 00387 ) 00388 { 00389 T const & 00390 x = parameters(0); 00391 00392 T const & 00393 y = parameters(1); 00394 00395 T const 00396 z = parameters(2); 00397 00398 const Vector<T, N> 00399 normal(x, y, z); 00400 00401 // Localization tensor 00402 Tensor<T, N> const 00403 Q = dot(normal, dot(tangent_, normal)); 00404 00405 T const 00406 determinant = det(Q); 00407 00408 if (determinant < minimum_) { 00409 minimum_ = determinant; 00410 arg_minimum_ = parameters; 00411 } 00412 00413 if (determinant > maximum_) { 00414 maximum_ = determinant; 00415 arg_maximum_ = parameters; 00416 } 00417 00418 return; 00419 } 00420 00421 // 00422 // Constructor for ParametricGrid 00423 // 00424 template<typename T, Index N> 00425 inline 00426 ParametricGrid<T, N>::ParametricGrid( 00427 Vector<T, N> const & lower, 00428 Vector<T, N> const & upper, 00429 Vector<Index, N> const & points_per_dimension) 00430 { 00431 assert(lower.get_dimension() == upper.get_dimension()); 00432 assert(lower.get_dimension() == points_per_dimension.get_dimension()); 00433 00434 lower_ = lower; 00435 upper_ = upper; 00436 points_per_dimension_ = points_per_dimension; 00437 00438 return; 00439 } 00440 00441 // 00442 // Traverse the grid and apply the visitor to each point. 00443 // 00444 template<typename T, Index N> 00445 template<typename Visitor> 00446 inline 00447 void 00448 ParametricGrid<T, N>::traverse(Visitor & visitor) const 00449 { 00450 // Loop over the grid 00451 Index const 00452 number_parameters = lower_.get_dimension(); 00453 00454 LongCount 00455 total_number_points = 1; 00456 00457 for (Index dimension = 0; dimension < number_parameters; ++dimension) { 00458 total_number_points *= points_per_dimension_(dimension); 00459 } 00460 00461 Vector<LongCount, N> 00462 steps(number_parameters, ONES); 00463 00464 for (Index dimension = 1; dimension < number_parameters; ++dimension) { 00465 steps(dimension) = 00466 steps(dimension - 1) * points_per_dimension_(dimension - 1); 00467 } 00468 00469 Vector<Index, N> 00470 indices(number_parameters, ZEROS); 00471 00472 Vector<T, N> 00473 position_in_grid(number_parameters, ZEROS); 00474 00475 Vector<T, N> const 00476 span = upper_ - lower_; 00477 00478 for (LongCount point = 1; point <= total_number_points; ++point) { 00479 00480 //std::cout << "Indices : "; 00481 00482 for (Index dimension = 0; dimension < number_parameters; ++dimension) { 00483 00484 position_in_grid(dimension) = indices(dimension) * span(dimension) / 00485 (points_per_dimension_(dimension) - 1) + lower_(dimension); 00486 00487 visitor(position_in_grid); 00488 00489 //std::cout << indices(dimension) << " "; 00490 00491 // Check if index needs to be increased or rolled back 00492 if (point % steps(dimension) == 0) { 00493 ++indices(dimension); 00494 } 00495 if (indices(dimension) == points_per_dimension_(dimension)) { 00496 indices(dimension) = 0; 00497 } 00498 00499 } 00500 00501 //std::cout << std::endl; 00502 //std::cout << "Position : " << position_in_grid << std::endl; 00503 00504 } 00505 00506 return; 00507 } 00508 00509 } // namespace Intrepid 00510 00511 #endif // Intrepid_MiniTensor_Geometry_i_h 00512
1.7.6.1