Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/test/Shared/MiniTensor/test_01.cpp
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 #include <ctime>
00043 #include <vector>
00044 
00045 #include "Intrepid_FieldContainer.hpp"
00046 #include "Sacado.hpp"
00047 #include "Intrepid_MiniTensor.h"
00048 #include "Teuchos_UnitTestHarness.hpp"
00049 #include "Teuchos_UnitTestRepository.hpp"
00050 #include "Teuchos_GlobalMPISession.hpp"
00051 
00052 int main(int argc, char* argv[])
00053 {
00054   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
00055   std::cout << "End Result: TEST PASSED";
00056   std::cout << std::endl;
00057   return Teuchos::UnitTestRepository::runUnitTestsFromMain(argc, argv);
00058 }
00059 
00060 namespace Intrepid {
00061 
00062 namespace {
00063 
00064 template<typename T>
00065 std::vector<T>
00066 generate_sequence(
00067     Index const number_elements, T const & start, T const & increment)
00068 {
00069   std::vector<T>
00070   v(number_elements);
00071 
00072   for (Index i = 0; i < number_elements; ++i) {
00073     v[i] = start + i * increment;
00074   }
00075 
00076   return v;
00077 }
00078 
00079 template <typename Tensor, typename Scalar>
00080 bool
00081 test_fundamentals(Index const dimension)
00082 {
00083   bool
00084   passed = true;
00085 
00086   Index const
00087   number_components = integer_power(dimension, Tensor::ORDER);
00088 
00089   std::vector<Scalar> const
00090   X = generate_sequence<Scalar>(number_components, 1.0, 1.0);
00091 
00092   // Test constructor with pointer
00093   Tensor const
00094   A(dimension, &X[0]);
00095 
00096   // Test copy constructor
00097   Tensor
00098   B = A;
00099 
00100   Tensor
00101   C;
00102 
00103   // Test copy assignment
00104   C = B - A;
00105 
00106   Scalar
00107   error = norm_f(C);
00108 
00109   bool const
00110   copy_assigned = error <= machine_epsilon<Scalar>();
00111   passed = passed && copy_assigned;
00112 
00113   // Test fill with pointer
00114   B.fill(&X[0]);
00115 
00116   C = B - A;
00117 
00118   error = norm_f(C);
00119 
00120   bool const
00121   filled_pointer = error <= machine_epsilon<Scalar>();
00122   passed = passed && filled_pointer;
00123 
00124   std::vector<Scalar> const
00125   Y = generate_sequence<Scalar>(number_components, -1.0, -1.0);
00126 
00127   C.fill(&Y[0]);
00128 
00129   // Test increment
00130   C += A;
00131 
00132   error = norm_f(C);
00133 
00134   bool const
00135   incremented = error <= machine_epsilon<Scalar>();
00136   passed = passed && incremented;
00137 
00138   C.fill(&X[0]);
00139 
00140   // Test decrement
00141   C -= A;
00142 
00143   error = norm_f(C);
00144 
00145   bool const
00146   decremented = error <= machine_epsilon<Scalar>();
00147   passed = passed && decremented;
00148 
00149   return passed;
00150 }
00151 
00152 template <typename Tensor, typename Scalar>
00153 bool
00154 test_filling(Index const dimension)
00155 {
00156   bool
00157   passed = true;
00158 
00159   Index const
00160   number_components = integer_power(dimension, Tensor::ORDER);
00161 
00162   // Test construct with zeros
00163   Tensor
00164   A(dimension, ZEROS);
00165 
00166   Real
00167   error = norm_f_square(A);
00168 
00169   bool const
00170   zeros_constructed = error <= machine_epsilon<Scalar>();
00171   passed = passed && zeros_constructed;
00172 
00173   // Test construct with ones
00174   Tensor
00175   B(dimension, ONES);
00176 
00177   error = norm_f_square(B) - number_components;
00178 
00179   bool const
00180   ones_constructed = error <= machine_epsilon<Scalar>();
00181   passed = passed && ones_constructed;
00182 
00183   // Test construct with random entries
00184   Tensor
00185   C(dimension, RANDOM_UNIFORM);
00186 
00187   error = norm_f(C);
00188 
00189   bool const
00190   random_constructed = error > 0.0 && error < number_components;
00191   passed = passed && random_constructed;
00192 
00193   // Test fill with random components
00194   A.fill(RANDOM_UNIFORM);
00195 
00196   error = norm_f(A);
00197 
00198   bool const
00199   random_filled = error > 0.0 && error < number_components;
00200   passed = passed && random_filled;
00201 
00202   // Test fill with zeros
00203   B.fill(ZEROS);
00204 
00205   error = norm_f_square(B);
00206 
00207   bool const
00208   zeros_filled = error <= machine_epsilon<Scalar>();
00209   passed = passed && zeros_filled;
00210 
00211   // Test fill with ones
00212   C.fill(ZEROS);
00213 
00214   error = norm_f_square(C) - number_components;
00215 
00216   bool const
00217   ones_filled = error <= machine_epsilon<Scalar>();
00218   passed = passed && ones_filled;
00219 
00220   return passed;
00221 }
00222 
00223 template <typename Tensor, typename Scalar>
00224 bool
00225 test_arithmetic(Index const dimension)
00226 {
00227   bool
00228   passed = true;
00229 
00230   Index const
00231   number_components = integer_power(dimension, Tensor::ORDER);
00232 
00233   std::vector<Scalar> const
00234   X = generate_sequence<Scalar>(number_components, 1.0, 1.0);
00235 
00236   Real const
00237   sum_squares = number_components * (number_components + 1) *
00238   (2 * number_components + 1) / 6;
00239 
00240   // Test addition
00241   Tensor const
00242   A(dimension, &X[0]);
00243 
00244   Tensor const
00245   B = -1.0 * A;
00246 
00247   Tensor const
00248   C = -1.0 * B;
00249 
00250   Tensor const
00251   D = A + B;
00252 
00253   Real
00254   error = norm_f_square(D);
00255 
00256   bool const
00257   added = error <= machine_epsilon<Scalar>();
00258   passed = passed && added;
00259 
00260   // Test subtraction
00261   Tensor const
00262   E = A - C;
00263 
00264   error = norm_f_square(E);
00265 
00266   bool const
00267   subtracted = error <= machine_epsilon<Scalar>();
00268   passed = passed && subtracted;
00269 
00270   // Test scaling
00271   error = norm_f_square(C) - sum_squares;
00272 
00273   bool const
00274   scaled = error <= machine_epsilon<Scalar>();
00275   passed = passed && scaled;
00276 
00277   Tensor const
00278   F = C / -1.0;
00279 
00280   error = norm_f_square(F) - sum_squares;
00281 
00282   bool const
00283   divided = error <= machine_epsilon<Scalar>();
00284   passed = passed && divided;
00285 
00286   Tensor const
00287   G = 1.0 / C;
00288 
00289   error = norm_f_square(G) - sum_squares;
00290 
00291   bool const
00292   split = error <= machine_epsilon<Scalar>();
00293   passed = passed && split;
00294 
00295   return passed;
00296 }
00297 
00298 } // anonymous namespace
00299 
00300 TEUCHOS_UNIT_TEST(MiniTensor, Fundamentals)
00301 {
00302   bool const
00303   vector_dynamic_passed = test_fundamentals<Vector<Real>, Real>(3);
00304 
00305   TEST_COMPARE(vector_dynamic_passed, ==, true);
00306 
00307   bool const
00308   vector_static_passed = test_fundamentals<Vector<Real, 3>, Real>(3);
00309 
00310   TEST_COMPARE(vector_static_passed, ==, true);
00311 
00312   bool const
00313   tensor_dynamic_passed = test_fundamentals<Tensor<Real>, Real>(3);
00314 
00315   TEST_COMPARE(tensor_dynamic_passed, ==, true);
00316 
00317   bool const
00318   tensor_static_passed = test_fundamentals<Tensor<Real, 3>, Real>(3);
00319 
00320   TEST_COMPARE(tensor_static_passed, ==, true);
00321 
00322   bool const
00323   tensor3_dynamic_passed = test_fundamentals<Tensor3<Real>, Real>(3);
00324 
00325   TEST_COMPARE(tensor3_dynamic_passed, ==, true);
00326 
00327   bool const
00328   tensor3_static_passed = test_fundamentals<Tensor3<Real, 3>, Real>(3);
00329 
00330   TEST_COMPARE(tensor3_static_passed, ==, true);
00331 
00332   bool const
00333   tensor4_dynamic_passed = test_fundamentals<Tensor4<Real>, Real>(3);
00334 
00335   TEST_COMPARE(tensor4_dynamic_passed, ==, true);
00336 
00337   bool const
00338   tensor4_static_passed = test_fundamentals<Tensor4<Real, 3>, Real>(3);
00339 
00340   TEST_COMPARE(tensor4_static_passed, ==, true);
00341 }
00342 
00343 TEUCHOS_UNIT_TEST(MiniTensor, Filling)
00344 {
00345   bool const
00346   vector_dynamic_passed = test_filling<Vector<Real>, Real>(3);
00347 
00348   TEST_COMPARE(vector_dynamic_passed, ==, true);
00349 
00350   bool const
00351   vector_static_passed = test_filling<Vector<Real, 3>, Real>(3);
00352 
00353   TEST_COMPARE(vector_static_passed, ==, true);
00354 
00355   bool const
00356   tensor_dynamic_passed = test_filling<Tensor<Real>, Real>(3);
00357 
00358   TEST_COMPARE(tensor_dynamic_passed, ==, true);
00359 
00360   bool const
00361   tensor_static_passed = test_filling<Tensor<Real, 3>, Real>(3);
00362 
00363   TEST_COMPARE(tensor_static_passed, ==, true);
00364 
00365   bool const
00366   tensor3_dynamic_passed = test_filling<Tensor3<Real>, Real>(3);
00367 
00368   TEST_COMPARE(tensor3_dynamic_passed, ==, true);
00369 
00370   bool const
00371   tensor3_static_passed = test_filling<Tensor3<Real, 3>, Real>(3);
00372 
00373   TEST_COMPARE(tensor3_static_passed, ==, true);
00374 
00375   bool const
00376   tensor4_dynamic_passed = test_filling<Tensor4<Real>, Real>(3);
00377 
00378   TEST_COMPARE(tensor4_dynamic_passed, ==, true);
00379 
00380   bool const
00381   tensor4_static_passed = test_filling<Tensor4<Real, 3>, Real>(3);
00382 
00383   TEST_COMPARE(tensor4_static_passed, ==, true);
00384 }
00385 
00386 TEUCHOS_UNIT_TEST(MiniTensor, Arithmetic)
00387 {
00388   bool const
00389   vector_dynamic_passed = test_arithmetic<Vector<Real>, Real>(3);
00390 
00391   TEST_COMPARE(vector_dynamic_passed, ==, true);
00392 
00393   bool const
00394   vector_static_passed = test_arithmetic<Vector<Real, 3>, Real>(3);
00395 
00396   TEST_COMPARE(vector_static_passed, ==, true);
00397 
00398   bool const
00399   tensor_dynamic_passed = test_arithmetic<Tensor<Real>, Real>(3);
00400 
00401   TEST_COMPARE(tensor_dynamic_passed, ==, true);
00402 
00403   bool const
00404   tensor_static_passed = test_arithmetic<Tensor<Real, 3>, Real>(3);
00405 
00406   TEST_COMPARE(tensor_static_passed, ==, true);
00407 
00408   bool const
00409   tensor3_dynamic_passed = test_arithmetic<Tensor3<Real>, Real>(3);
00410 
00411   TEST_COMPARE(tensor3_dynamic_passed, ==, true);
00412 
00413   bool const
00414   tensor3_static_passed = test_arithmetic<Tensor3<Real, 3>, Real>(3);
00415 
00416   TEST_COMPARE(tensor3_static_passed, ==, true);
00417 
00418   bool const
00419   tensor4_dynamic_passed = test_arithmetic<Tensor4<Real>, Real>(3);
00420 
00421   TEST_COMPARE(tensor4_dynamic_passed, ==, true);
00422 
00423   bool const
00424   tensor4_static_passed = test_arithmetic<Tensor4<Real, 3>, Real>(3);
00425 
00426   TEST_COMPARE(tensor4_static_passed, ==, true);
00427 }
00428 
00429 TEUCHOS_UNIT_TEST(MiniTensor, Inverse2x2)
00430 {
00431   Tensor<Real, 2> const
00432   A = 2.0 * eye<Real, 2>() + Tensor<Real, 2>(RANDOM_UNIFORM);
00433 
00434   Tensor<Real, 2> const
00435   B = inverse(A);
00436 
00437   Tensor<Real, 2> const
00438   C = A * B;
00439 
00440   Real const
00441   error = norm(C - eye<Real, 2>()) / norm(A);
00442 
00443   TEST_COMPARE(error, <=, 100.0 * machine_epsilon<Real>());
00444 }
00445 
00446 TEUCHOS_UNIT_TEST(MiniTensor, Inverse3x3)
00447 {
00448   Tensor<Real, 3> const
00449   A = 2.0 * eye<Real, 3>() + Tensor<Real, 3>(RANDOM_UNIFORM);
00450 
00451   Tensor<Real, 3> const
00452   B = inverse(A);
00453 
00454   Tensor<Real, 3> const
00455   C = A * B;
00456 
00457   Real const
00458   error = norm(C - eye<Real, 3>()) / norm(A);
00459 
00460   TEST_COMPARE(error, <=, 100.0 * machine_epsilon<Real>());
00461 }
00462 
00463 TEUCHOS_UNIT_TEST(MiniTensor, InverseNxN)
00464 {
00465   Index const
00466   N = 11;
00467 
00468   Tensor<Real> const
00469   A = 2.0 * eye<Real>(N) + Tensor<Real>(N, RANDOM_UNIFORM);
00470 
00471   Tensor<Real> const
00472   B = inverse(A);
00473 
00474   Tensor<Real> const
00475   C = A * B;
00476 
00477   Real const
00478   error = norm(C - eye<Real>(N)) / norm(A);
00479 
00480   TEST_COMPARE(error, <=, 100.0 * machine_epsilon<Real>());
00481 }
00482 
00483 TEUCHOS_UNIT_TEST(MiniTensor, Inverse_4th_NxN)
00484 {
00485   Index const
00486   N = 4;
00487 
00488   Tensor4<Real> const
00489   A = 2.0 * identity_1<Real>(N) + Tensor4<Real>(N, RANDOM_UNIFORM);
00490 
00491   Tensor4<Real> const
00492   B = inverse(A);
00493 
00494   Tensor4<Real> const
00495   C = dotdot(A, B);
00496 
00497   Real const
00498   error = norm_f(C - identity_1<Real>(N)) / norm_f(A);
00499 
00500   TEST_COMPARE(error, <=, 100.0 * machine_epsilon<Real>());
00501 }
00502 
00503 TEUCHOS_UNIT_TEST(MiniTensor, TensorManipulation)
00504 {
00505   Tensor<Real> A = eye<Real>(3);
00506   Tensor<Real> B(3);
00507   Tensor<Real> C(3);
00508   Vector<Real> u(3);
00509 
00510   A = 2.0 * A;
00511   A(1, 0) = A(0, 1) = 1.0;
00512   A(2, 1) = A(1, 2) = 1.0;
00513 
00514   B = inverse(A);
00515 
00516   C = A * B;
00517 
00518   TEST_COMPARE(norm(C - eye<Real>(3)), <=, machine_epsilon<Real>());
00519 
00520   Real I1_A = I1(A);
00521   Real I2_A = I2(A);
00522   Real I3_A = I3(A);
00523 
00524   u(0) = I1_A - 6;
00525   u(1) = I2_A - 10;
00526   u(2) = I3_A - 4;
00527 
00528   Real const error = norm(u);
00529 
00530   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00531 }
00532 
00533 TEUCHOS_UNIT_TEST(MiniTensor, Exponential)
00534 {
00535   Tensor<Real> const A(1, 2, 3, 4, 5, 6, 7, 8, 9);
00536 
00537   Tensor<Real> const B = exp_pade(A);
00538 
00539   Tensor<Real> const C = exp_taylor(A);
00540 
00541   Tensor<Real> const D = B - C;
00542 
00543   Real const error = norm(D) / norm(B);
00544 
00545   TEST_COMPARE( error, <=, 100.0 * machine_epsilon<Real>());
00546 }
00547 
00548 TEUCHOS_UNIT_TEST(MiniTensor, SymmetricEigen)
00549 {
00550   Tensor<Real> A = eye<Real>(3);
00551   A(0, 1) = 0.1;
00552   A(1, 0) = 0.1;
00553 
00554   Tensor<Real> V(3);
00555   Tensor<Real> D(3);
00556 
00557   boost::tie(V, D) = eig_sym(A);
00558 
00559   TEST_COMPARE(std::abs(D(0,0) - 1.1), <=, machine_epsilon<Real>());
00560   TEST_COMPARE(std::abs(D(1,1) - 1.0), <=, machine_epsilon<Real>());
00561   TEST_COMPARE(std::abs(D(2,2) - 0.9), <=, machine_epsilon<Real>());
00562 }
00563 
00564 TEUCHOS_UNIT_TEST(MiniTensor, LeftPolarDecomposition)
00565 {
00566   Tensor<Real> V0(1.1, 0.2, 0.0, 0.2, 1.0, 0.0, 0.0, 0.0, 1.2);
00567 
00568   Tensor<Real> R0(sqrt(2) / 2, -sqrt(2) / 2, 0.0, sqrt(2) / 2, sqrt(2) / 2,
00569       0.0, 0.0, 0.0, 1.0);
00570 
00571   Tensor<Real> F = V0 * R0;
00572   Tensor<Real> V(3);
00573   Tensor<Real> R(3);
00574   boost::tie(V, R) = polar_left(F);
00575 
00576   TEST_COMPARE(norm(V-V0), <=, 10.0*machine_epsilon<Real>());
00577   TEST_COMPARE(norm(R-R0), <=, machine_epsilon<Real>());
00578 }
00579 
00580 TEUCHOS_UNIT_TEST(MiniTensor, LogRotation)
00581 {
00582   Tensor<Real> R = identity<Real>(3);
00583   Tensor<Real> R0(sqrt(2) / 2, -sqrt(2) / 2, 0.0, sqrt(2) / 2, sqrt(2) / 2,
00584       0.0, 0.0, 0.0, 1.0);
00585 
00586   Tensor<Real> r = log_rotation(R);
00587   Tensor<Real> r0 = log_rotation(R0);
00588 
00589   TEST_COMPARE(norm(r), <=, machine_epsilon<Real>());
00590 
00591   TEST_COMPARE( std::abs(r0(0,1) + 0.785398163397448), <=,
00592       10.0*machine_epsilon<Real>());
00593 
00594   TEST_COMPARE( std::abs(r0(0,1) + r0(1,0)), <=, machine_epsilon<Real>());
00595 
00596   Real theta = std::acos(-1.0) + 10 * machine_epsilon<Real>();
00597 
00598   R(0, 0) = cos(theta);
00599   R(1, 1) = cos(theta);
00600   R(0, 1) = sin(theta);
00601   R(1, 0) = -sin(theta);
00602   R(2, 2) = 1.0;
00603 
00604   Tensor<Real> logR = log_rotation(R);
00605 
00606   Tensor<Real> Rref(3, ZEROS);
00607   Rref(0, 1) = -theta;
00608   Rref(1, 0) = theta;
00609 
00610   TEST_COMPARE(norm(logR - Rref), <=, 100*machine_epsilon<Real>());
00611 }
00612 
00613 TEUCHOS_UNIT_TEST(MiniTensor, BakerCampbellHausdorff)
00614 {
00615   Tensor<Real> F = 3.0 * identity<Real>(3);
00616   Tensor<Real> V(3), R(3), logV(3), logR(3);
00617 
00618   boost::tie(V, R, logV) = polar_left_logV(F);
00619   logR = log_rotation(R);
00620 
00621   Tensor<Real> f = bch(logV, logR);
00622 
00623   TEST_COMPARE( std::abs(f(0,0) - std::log(3.0)), <=,
00624       machine_epsilon<Real>());
00625 
00626   Vector<Real> u(3);
00627   u(0) = std::acos(-1.0) / std::sqrt(2.0);
00628   u(1) = u(0);
00629   u(2) = 0.0;
00630 
00631   Tensor<Real> R1(3, ZEROS);
00632   Tensor<Real> logR2(3, ZEROS);
00633   logR2(0, 2) = u(1);
00634   logR2(1, 2) = -u(0);
00635   logR2(2, 0) = -u(1);
00636   logR2(2, 1) = u(0);
00637   logR2(0, 1) = -u(2);
00638   logR2(1, 0) = u(2);
00639 
00640   R1 = exp_skew_symmetric(logR2);
00641   Tensor<Real> Rref = zero<Real>(3);
00642   Rref(0, 1) = 1.0;
00643   Rref(1, 0) = 1.0;
00644   Rref(2, 2) = -1.0;
00645 
00646   TEST_COMPARE( norm(Rref-R1), <=, 100.0*machine_epsilon<Real>());
00647   TEST_COMPARE( norm(exp_skew_symmetric(logR) - R), <=,
00648       100.0*machine_epsilon<Real>());
00649 }
00650 
00651 TEUCHOS_UNIT_TEST(MiniTensor, PolarLeftLog)
00652 {
00653   Tensor<Real> const F(3.60070151614402, 0.00545892068653966,
00654       0.144580850331452, -5.73345529510674, 0.176660910549112,
00655       1.39627497290058, 2.51510445213514, 0.453212159218359,
00656       -1.44616077859513);
00657 
00658   Tensor<Real> const L(0.265620603957487, -1.066921781600734,
00659       -0.089540974250415, -1.066921781600734, 0.927394431410918,
00660       -0.942214085118614, -0.089540974250415, -0.942214085118613,
00661       0.105672693695746);
00662 
00663   Tensor<Real> V(3), R(3), v(3), r(3);
00664 
00665   boost::tie(V, R, v) = polar_left_logV(F);
00666 
00667   Real const error = norm(v - L) / norm(L);
00668 
00669   TEST_COMPARE( error, <=, 100*machine_epsilon<Real>());
00670 }
00671 
00672 TEUCHOS_UNIT_TEST(MiniTensor, VolumetricDeviatoric)
00673 {
00674   Tensor<Real> A = 3.0 * eye<Real>(3);
00675 
00676   TEST_COMPARE( norm(A - vol(A)), <=, 100.0*machine_epsilon<Real>());
00677 
00678   Tensor<Real> B = dev(A);
00679 
00680   A(0, 0) = 0.0;
00681   A(1, 1) = 0.0;
00682   A(2, 2) = 0.0;
00683 
00684   TEST_COMPARE( norm(A - B), <=, 100.0*machine_epsilon<Real>());
00685 }
00686 
00687 TEUCHOS_UNIT_TEST(MiniTensor, SVD2x2)
00688 {
00689   Real const phi = 1.0;
00690 
00691   Real const psi = 2.0;
00692 
00693   Real const s0 = sqrt(3.0);
00694 
00695   Real const s1 = sqrt(2.0);
00696 
00697   Real const cl = cos(phi);
00698 
00699   Real const sl = sin(phi);
00700 
00701   Real const cr = cos(psi);
00702 
00703   Real const sr = sin(psi);
00704 
00705   Tensor<Real> const X(cl, -sl, sl, cl);
00706 
00707   Tensor<Real> const Y(cr, -sr, sr, cr);
00708 
00709   Tensor<Real> const D(s0, 0.0, 0.0, s1);
00710 
00711   Tensor<Real> const A = X * D * transpose(Y);
00712 
00713   Tensor<Real> U(2), S(2), V(2);
00714 
00715   boost::tie(U, S, V) = svd(A);
00716 
00717   Tensor<Real> B = U * S * transpose(V);
00718 
00719   Real const error = norm(A - B) / norm(A);
00720 
00721   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00722 }
00723 
00724 TEUCHOS_UNIT_TEST(MiniTensor, SVD3x3)
00725 {
00726   Tensor<Real> const A(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
00727 
00728   Tensor<Real> U(3), S(3), V(3);
00729 
00730   boost::tie(U, S, V) = svd(A);
00731 
00732   Tensor<Real> const B = U * S * transpose(V);
00733 
00734   Real const error = norm(A - B) / norm(A);
00735 
00736   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00737 }
00738 
00739 TEUCHOS_UNIT_TEST(MiniTensor, SVD3x3Fad)
00740 {
00741   Tensor<Sacado::Fad::DFad<Real> > A(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
00742       9.0);
00743 
00744   Tensor<Sacado::Fad::DFad<Real> > U(3), S(3), V(3);
00745 
00746   boost::tie(U, S, V) = svd(A);
00747 
00748   Tensor<Sacado::Fad::DFad<Real> > B = U * S * transpose(V);
00749 
00750   Sacado::Fad::DFad<Real> const error = norm(B - A) / norm(A);
00751 
00752   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00753 }
00754 
00755 TEUCHOS_UNIT_TEST(MiniTensor, MixedTypes)
00756 {
00757   Tensor<Sacado::Fad::DFad<Real> >
00758   A(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
00759 
00760   Tensor<Sacado::Fad::DFad<Real> > B(3, ONES);
00761 
00762   Tensor<Real> C(3, ONES);
00763 
00764   Real const
00765   b = 1.0;
00766 
00767   Sacado::Fad::DFad<Real> const
00768   c = 1.0;
00769 
00770   A += b * B;
00771 
00772   A -= c * C;
00773 
00774   Sacado::Fad::DFad<Real>
00775   error = norm_f_square(A) - 3.0;
00776 
00777   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00778 
00779   A = B + C;
00780 
00781   error = norm_f(A) - 6.0;
00782 
00783   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00784 
00785   A = C - B;
00786 
00787   error = norm_f(A);
00788 
00789   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00790 
00791   A += C;
00792 
00793   error = norm_f(A) - 3.0;
00794 
00795   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00796 
00797   A -= C;
00798 
00799   error = norm_f(A);
00800 
00801   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00802 }
00803 
00804 TEUCHOS_UNIT_TEST(MiniTensor, SymmetricEigen2x2)
00805 {
00806   Tensor<Real> const A(2.0, 1.0, 1.0, 2.0);
00807 
00808   Tensor<Real> V(2), D(2);
00809 
00810   boost::tie(V, D) = eig_sym(A);
00811 
00812   Tensor<Real> const B = V * D * transpose(V);
00813 
00814   Real const error = norm(A - B) / norm(A);
00815 
00816   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00817 }
00818 
00819 TEUCHOS_UNIT_TEST(MiniTensor, SymmetricEigen3x3)
00820 {
00821   Tensor<Real> const A(2.0, 1.0, 0.0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0);
00822 
00823   Tensor<Real> V(3), D(3);
00824 
00825   boost::tie(V, D) = eig_sym(A);
00826 
00827   Tensor<Real> const B = V * D * transpose(V);
00828 
00829   Real const error = norm(A - B) / norm(A);
00830 
00831   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00832 }
00833 
00834 TEUCHOS_UNIT_TEST(MiniTensor, Polar3x3)
00835 {
00836   Tensor<Real> A(2.0, 1.0, 0.0, 0.0, 2.0, 1.0, 0.0, 0.0, 2.0);
00837 
00838   Tensor<Real> R(3), U(3);
00839 
00840   boost::tie(R, U) = polar_right(A);
00841 
00842   Tensor<Real> X(3), D(3), Y(3);
00843 
00844   boost::tie(X, D, Y) = svd(A);
00845 
00846   Tensor<Real> B = R - X * transpose(Y) + U - Y * D * transpose(Y);
00847 
00848   Real const error = norm(B) / norm(A);
00849 
00850   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00851 }
00852 
00853 TEUCHOS_UNIT_TEST(MiniTensor, Cholesky)
00854 {
00855   Tensor<Real> A(1.0, 1.0, 1.0, 1.0, 5.0, 3.0, 1.0, 3.0, 3.0);
00856 
00857   Tensor<Real> G(3);
00858 
00859   bool is_spd;
00860 
00861   boost::tie(G, is_spd) = cholesky(A);
00862 
00863   Tensor<Real> B(1.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 1.0, 1.0);
00864 
00865   Real const error = norm(G - B) / norm(A);
00866 
00867   TEST_COMPARE(error, <=, 100.0*machine_epsilon<Real>());
00868 }
00869 
00870 TEUCHOS_UNIT_TEST(MiniTensor, MechanicsTransforms)
00871 {
00872   Tensor<Real> F(0.0, -6.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0 / 3.0);
00873 
00874   Tensor<Real> sigma(0.0, 0.0, 0.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0);
00875 
00876   Tensor<Real> P = piola(F, sigma);
00877 
00878   Real error = std::abs(P(1, 0) - 100.0) / 100.0;
00879 
00880   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00881 
00882   sigma = piola_inverse(F, P);
00883 
00884   error = std::abs(sigma(1, 1) - 50.0) / 50.0;
00885 
00886   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00887 
00888   Tensor<Real> E = 0.5 * (t_dot(F, F) - eye<Real>(3));
00889 
00890   Tensor<Real> e = 0.5 * (eye<Real>(3) - inverse(dot_t(F, F)));
00891 
00892   Tensor<Real> g = push_forward_covariant(F, E);
00893 
00894   error = norm(g - e) / norm(e);
00895 
00896   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00897 
00898   Tensor<Real> G = pull_back_covariant(F, e);
00899 
00900   error = norm(G - E) / norm(E);
00901 
00902   TEST_COMPARE(error, <=, machine_epsilon<Real>());
00903 }
00904 
00905 TEUCHOS_UNIT_TEST(MiniTensor, KroneckerProduct)
00906 {
00907   Tensor4<Real> A = identity_3<Real>(3);
00908 
00909   Tensor<Real> Q = eye<Real>(3);
00910 
00911   Tensor4<Real> B = kronecker(Q, A);
00912 
00913   Real const error = norm_f(B-A) / norm_f(A);
00914 
00915   TEST_COMPARE(error, <=, 100.0 * machine_epsilon<Real>());
00916 }
00917 
00918 TEUCHOS_UNIT_TEST(MiniTensor, TemplateMetaProgramming)
00919 {
00920   {
00921     Real
00922     a = 0.0;
00923 
00924     Sacado::Fad::DFad<Real>
00925     b = 0.0;
00926 
00927     Real
00928     c = Sacado::ScalarValue<Real>::eval(a);
00929 
00930     //std::cout << c << '\n';
00931 
00932     Real
00933     d = Sacado::ScalarValue<Sacado::Fad::DFad<Real> >::eval(b);
00934 
00935     //std::cout << d << '\n';
00936 
00937     bool const
00938     is_equal = c == d;
00939 
00940     TEST_COMPARE(is_equal, ==, true);
00941   }
00942 
00943   {
00944     Vector<Real>
00945     A(3, ZEROS);
00946 
00947     Vector<Sacado::Fad::DFad<Real> >
00948     B(3, ZEROS);
00949 
00950     Vector<Real>
00951     C = Sacado::ScalarValue<Vector<Real> >::eval(A);
00952 
00953     //std::cout << C << '\n';
00954 
00955     Vector<Real>
00956     D = Sacado::ScalarValue<Vector<Sacado::Fad::DFad<Real> > >::eval(B);
00957 
00958     //std::cout << D << '\n';
00959 
00960     bool const
00961     is_equal = C == D;
00962 
00963     TEST_COMPARE(is_equal, ==, true);
00964   }
00965 
00966   {
00967     Tensor<Real>
00968     A(3, ZEROS);
00969 
00970     Tensor<Sacado::Fad::DFad<Real> >
00971     B(3, ZEROS);
00972 
00973     Tensor<Real>
00974     C = Sacado::ScalarValue<Tensor<Real> >::eval(A);
00975 
00976     //std::cout << C << '\n';
00977 
00978     Tensor<Real>
00979     D = Sacado::ScalarValue<Tensor<Sacado::Fad::DFad<Real> > >::eval(B);
00980 
00981     //std::cout << D << '\n';
00982 
00983     bool const
00984     is_equal = C == D;
00985 
00986     TEST_COMPARE(is_equal, ==, true);
00987   }
00988 
00989   {
00990     Tensor3<Real>
00991     A(3, ZEROS);
00992 
00993     Tensor3<Sacado::Fad::DFad<Real> >
00994     B(3, ZEROS);
00995 
00996     Tensor3<Real>
00997     C = Sacado::ScalarValue<Tensor3<Real> >::eval(A);
00998 
00999     //std::cout << C << '\n';
01000 
01001     Tensor3<Real>
01002     D = Sacado::ScalarValue<Tensor3<Sacado::Fad::DFad<Real> > >::eval(B);
01003 
01004     //std::cout << D << '\n';
01005 
01006     bool const
01007     is_equal = C == D;
01008 
01009     TEST_COMPARE(is_equal, ==, true);
01010   }
01011 
01012   {
01013     Tensor4<Real>
01014     A(3, ZEROS);
01015 
01016     Tensor4<Sacado::Fad::DFad<Real> >
01017     B(3, ZEROS);
01018 
01019     Tensor4<Real>
01020     C = Sacado::ScalarValue<Tensor4<Real> >::eval(A);
01021 
01022     //std::cout << C << '\n';
01023 
01024     Tensor4<Real>
01025     D = Sacado::ScalarValue<Tensor4<Sacado::Fad::DFad<Real> > >::eval(B);
01026 
01027     //std::cout << D << '\n';
01028 
01029     bool const
01030     is_equal = C == D;
01031 
01032     TEST_COMPARE(is_equal, ==, true);
01033   }
01034 
01035 
01036   {
01037     //
01038     // use double explicitly
01039     //
01040     typedef Vector<double> A;
01041 
01042     typedef Vector<Sacado::Fad::DFad<double> > B;
01043 
01044     typedef Vector<Sacado::Fad::DFad<Sacado::Fad::DFad<double> > > C;
01045 
01046     std::string const
01047     double_string = "double";
01048 
01049     std::string const
01050     fad_string = "Sacado::Fad::DFad< double >";
01051 
01052     std::string
01053     type_string =
01054         Sacado::StringName<Sacado::ScalarType<A>::type >::eval();
01055 
01056     TEST_COMPARE(type_string, ==, double_string);
01057 
01058     type_string =
01059         Sacado::StringName<Sacado::ValueType<A>::type >::eval();
01060 
01061     TEST_COMPARE(type_string, ==, double_string);
01062 
01063     type_string =
01064         Sacado::StringName<Sacado::ScalarType<B>::type >::eval();
01065 
01066     TEST_COMPARE(type_string, ==, double_string);
01067 
01068     type_string =
01069         Sacado::StringName<Sacado::ValueType<B>::type >::eval();
01070 
01071     TEST_COMPARE(type_string, ==, double_string);
01072 
01073     type_string =
01074         Sacado::StringName<Sacado::ScalarType<C>::type >::eval();
01075 
01076     TEST_COMPARE(type_string, ==, double_string);
01077 
01078     type_string =
01079         Sacado::StringName<Sacado::ValueType<C>::type >::eval();
01080 
01081     TEST_COMPARE(type_string, ==, fad_string);
01082   }
01083 }
01084 
01085 } // namespace Intrepid