Page MenuHomec4science

hooke.cpp
No OneTemporary

File Metadata

Created
Wed, May 8, 04:26

hooke.cpp

/*
* SPDX-License-Indentifier: AGPL-3.0-or-later
*
* Copyright (©) 2016-2024 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
* Copyright (©) 2020-2024 Lucas Frérot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "hooke.hh"
#include "influence.hh"
#include "loop.hh"
#include "model.hh"
#include "static_types.hh"
#include <boost/preprocessor/seq.hpp>
/* -------------------------------------------------------------------------- */
namespace tamaas {
template <model_type type>
void Hooke<type>::apply(GridBase<Real>& strain, GridBase<Real>& stress) const {
constexpr auto dim = model_type_traits<type>::dimension;
const influence::ElasticHelper<dim> elasticity(
this->model->getShearModulus(), this->model->getPoissonRatio());
// Checking incompressibility
if (elasticity.nu == 0.5)
throw std::range_error{TAMAAS_MSG("Incompressibility error, nu = 0.5")};
// Checking number of components
if (strain.getNbComponents() == dim * dim) {
Loop::loop(
[elasticity] CUDA_LAMBDA(MatrixProxy<Real, dim, dim> sigma,
MatrixProxy<const Real, dim, dim> epsilon) {
sigma = elasticity(epsilon);
},
range<MatrixProxy<Real, dim, dim>>(stress),
range<MatrixProxy<const Real, dim, dim>>(strain));
}
// in case we have voigt notation
else if (strain.getNbComponents() == voigt_size<dim>::value) {
Loop::loop(
[elasticity] CUDA_LAMBDA(SymMatrixProxy<Real, dim> sigma,
SymMatrixProxy<const Real, dim> epsilon) {
sigma = elasticity(epsilon);
},
range<SymMatrixProxy<Real, dim>>(stress),
range<SymMatrixProxy<const Real, dim>>(strain));
}
else
throw std::invalid_argument{TAMAAS_MSG("Strain components (",
strain.getNbComponents(),
") do not match model type ", type)};
}
/* -------------------------------------------------------------------------- */
template <model_type type>
std::pair<UInt, UInt> Hooke<type>::matvecShape() const {
auto shape = this->model->getDiscretization();
auto N =
std::accumulate(shape.begin(), shape.end(), 6, std::multiplies<UInt>());
return std::make_pair(N, N);
}
template <model_type type>
GridBase<Real> Hooke<type>::matvec(GridBase<Real>& X) const {
constexpr auto dim = model_type_traits<type>::dimension;
X.setNbComponents(voigt_size<dim>::value);
GridBase<Real> x(X.getGlobalNbPoints(), X.getNbComponents());
apply(X, x);
return x;
}
/* -------------------------------------------------------------------------- */
template <model_type type>
HookeField<type>::HookeField(Model* model) : Hooke<type>(model) {
this->template request<false, Real>("mu", model->getType(),
model->getDiscretization(), 1);
this->template request<false, Real>("nu", model->getType(),
model->getDiscretization(), 1);
this->template field<Real>("mu") = model->getShearModulus();
this->template field<Real>("nu") = model->getPoissonRatio();
}
template <UInt dim>
struct HookeFieldHelper {
void operator()(MatrixProxy<Real, dim, dim> sigma,
MatrixProxy<const Real, dim, dim> epsilon, const Real& mu,
const Real& nu) {
elasticity.mu = mu;
elasticity.nu = nu;
sigma = elasticity(epsilon);
}
influence::ElasticHelper<dim> elasticity{0, 0};
};
template <UInt dim>
struct SymHookeFieldHelper {
void operator()(SymMatrixProxy<Real, dim> sigma,
SymMatrixProxy<const Real, dim> epsilon, const Real& mu,
const Real& nu) {
elasticity.mu = mu;
elasticity.nu = nu;
sigma = elasticity(epsilon);
}
influence::ElasticHelper<dim> elasticity{0, 0};
};
template <model_type type>
void HookeField<type>::apply(GridBase<Real>& strain,
GridBase<Real>& stress) const {
constexpr auto dim = model_type_traits<type>::dimension;
// Checking incompressibility
auto incompressible =
Loop::reduce<operation::plus>([](Real nu) -> UInt { return nu >= 0.5; },
this->template field<Real>("nu"));
if (incompressible > 0)
throw std::range_error{
TAMAAS_MSG("Incompressibility error, nu = 0.5 somewhere")};
std::vector<influence::ElasticHelper<dim>> hookes;
const auto& mu = this->template field<Real>("mu");
const auto& nu = this->template field<Real>("nu");
hookes.reserve(mu.getNbPoints());
std::transform(mu.begin(), mu.end(), nu.begin(), std::back_inserter(hookes),
[](const Real& mu, const Real& nu) {
return influence::ElasticHelper<dim>{mu, nu};
});
// Checking number of components
if (strain.getNbComponents() == dim * dim) {
Loop::loop(
[](MatrixProxy<Real, dim, dim> stress,
MatrixProxy<const Real, dim, dim> strain,
const influence::ElasticHelper<dim>& elasticity) {
stress = elasticity(strain);
},
range<MatrixProxy<Real, dim, dim>>(stress),
range<MatrixProxy<const Real, dim, dim>>(strain), hookes);
}
// in case we have voigt notation
else if (strain.getNbComponents() == voigt_size<dim>::value) {
Loop::loop(
[](SymMatrixProxy<Real, dim> stress,
SymMatrixProxy<const Real, dim> strain,
const influence::ElasticHelper<dim>& elasticity) {
stress = elasticity(strain);
},
range<SymMatrixProxy<Real, dim>>(stress),
range<SymMatrixProxy<const Real, dim>>(strain), hookes);
}
else
throw std::invalid_argument{TAMAAS_MSG("Strain components (",
strain.getNbComponents(),
") do not match model type ", type)};
}
/* -------------------------------------------------------------------------- */
#define INSTANTIATE_HOOKE(r, _, type) \
template class Hooke<type>; \
template class HookeField<type>;
BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_HOOKE, ~, TAMAAS_MODEL_TYPES);
#undef INSTANTIATE_HOOKE
} // namespace tamaas

Event Timeline