Page MenuHomec4science

test_linear_material_composite.cc
No OneTemporary

File Metadata

Created
Fri, Nov 15, 23:00

test_linear_material_composite.cc

/**
* file test_linear_material_composite.cc
*
* @author Till Junge <till.junge@epfl.ch>
*
* @date 17 Aug 2017
*
* @brief Check the linear material law using layered composites
*
* @section LICENCE
*
* Copyright (C) 2017 Till Junge
*
* µSpectre is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3, or (at
* your option) any later version.
*
* µSpectre is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Emacs; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <boost/test/unit_test.hpp>
#include "system/system_base.cc"
#include "tests.hh"
#include "materials/material_linear_elastic.hh"
#include "materials/material_hyper_elastic.hh"
#include "system/fftw_engine_r2c.hh"
#include <array>
#include <iostream>
#include <random>
#include <memory>
namespace muSpectre {
BOOST_AUTO_TEST_SUITE(Linear_System_Test)
const Dim_t dim{3};
const Dim_t nb_pix{3};
const Real len{1.};
struct linear_sys_fixture: public SystemBase<dim, dim> {
linear_sys_fixture()
:SystemBase<dim, dim>(std_size, std_nb_pix){}
const static std::array<Real, dim> std_size;
const static Ccoord_t<dim> std_nb_pix;
const static Dim_t dim_s, dim_m;
};
const std::array<Real, dim> linear_sys_fixture::std_size = {len, len, len};
const Ccoord_t<dim> linear_sys_fixture::std_nb_pix = {nb_pix, nb_pix, nb_pix};
const Dim_t linear_sys_fixture::dim_s = dim;
const Dim_t linear_sys_fixture::dim_m = dim;
/* ---------------------------------------------------------------------- */
BOOST_FIXTURE_TEST_CASE(Constructor_test, linear_sys_fixture) {
}
class RandRange {
public:
RandRange(): rd(), gen(rd()) {}
Real randval(Real&& lower, Real&& upper) {
auto distro = std::uniform_real_distribution<Real>(lower, upper);
return distro(this->gen);
}
private:
std::random_device rd;
std::default_random_engine gen;
};
/* ---------------------------------------------------------------------- */
BOOST_FIXTURE_TEST_CASE(Stretch_z_dir_test, linear_sys_fixture) {
RandRange rng;
// set up material parameters
// suffix 1 or 2 refer to the materials of the block
auto nu1 = .3;//rng.randval(.2, .4); // Poisson ratio
auto nu2 = .35;
auto E1 = 12.;//rng.randval(2., 20); // Young's modulus
auto first_lame = [](const auto & E, const auto & nu) {return E*nu/((1+nu) * (1-2*nu));};
auto second_lame = [](const auto & E, const auto & nu) {return E/(2*(1+nu));};
auto lambda1{first_lame(E1, nu1)}; // First Lamé parameter
auto mu1{second_lame(E1, nu1)}; // Second Lamé parameter
auto E2{10*E1};
auto lambda2{first_lame(E2, nu2)};
auto mu2{second_lame(E2, nu2)};
// compute predicted stretches
auto stretch = .25;//{rng.randval(.05, .5)}; // overall stretch of system
auto expected_s2{stretch*3/((lambda2 + 2*mu2)/(lambda1 + 2*mu1) + 2)};
auto expected_s1{expected_s2*(lambda2 + 2*mu2)/(lambda1 + 2*mu1)};
// set up system
// size parameters
const Dim_t res{3};
const Real size = 2.;//{rng.randval(1.2, 100.)};
const Dim_t dim{3};
const std::array<Real, dim> sizes{size, size, size};
const std::array<Dim_t, dim> nb_pixels{res, res, res};
// build components
using Sys_t = SystemBase<dim, dim>;
Sys_t system(sizes, nb_pixels);
auto fft_eng = std::make_shared<FFTW_EngineR2C<dim, dim>>
(nb_pixels, FFT_PlanFlags::estimate);
using Mat_t = MaterialLinearElastic<dim, dim>;
//using Mat_t = MaterialHyperElastic<dim, dim>;
auto mat1{std::make_shared<Mat_t>("material 1", E1, nu1)};
auto mat2{std::make_shared<Mat_t>("material 2", E2, nu2)};
system.set_fft_engine(fft_eng);
system.add_material(mat1);
system.add_material(mat2);
Real newton_tol{1e-8};
Real cg_tol{1e-7};
Dim_t maxiter{100};
for (const auto && pixel: system) {
if (pixel[2] == 0) {
mat1->add_pixel(pixel);
} else {
mat2->add_pixel(pixel);
}
}
using grad_t = Sys_t::T2;
grad_t DeltaF;
DeltaF.setZero();
DeltaF(2, 2) = stretch;
auto verbose{true};
system.solve(DeltaF, newton_tol, cg_tol, maxiter, verbose);
std::cout << "Mean overall stretch in zz direction: " << stretch << std::endl;
auto&& solution = system.get_grad();
auto&& stress = system.get_stress();
for (Dim_t i = 0; i < solution.dimension(2); i++) {
std::cout << i << ": F = " << std::endl << solution.chip(i, 2) << std::endl << "σ:" << std::endl << stress.chip(i, 2) << std::endl;;
}
std::cout << "Expected s1 = " << expected_s1 << ", expected s2 = " << expected_s2 << std::endl;
for (const auto & idx: system) {
std::cout << idx << std::endl;
}
}
/* ---------------------------------------------------------------------- */
BOOST_AUTO_TEST_SUITE_END();
} // muSpectre

Event Timeline