|
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 #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
1.7.6.1