Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/src/Shared/MiniTensor/Intrepid_MiniTensor_Geometry.i.h
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