Page MenuHomec4science

model.hh
No OneTemporary

File Metadata

Created
Thu, May 9, 16:40

model.hh

/**
* @file
* @section LICENSE
*
* Copyright (©) 2016-2020 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef MODEL_HH
#define MODEL_HH
/* -------------------------------------------------------------------------- */
#include "be_engine.hh"
#include "grid_base.hh"
#include "integral_operator.hh"
#include "model_dumper.hh"
#include "model_type.hh"
#include "tamaas.hh"
#include <algorithm>
#include <memory>
#include <unordered_map>
#include <vector>
/* -------------------------------------------------------------------------- */
namespace tamaas {
/* -------------------------------------------------------------------------- */
/**
* @brief Class for linear isotropic elasticity
*/
namespace influence {
template <UInt dim>
struct ElasticHelper {
ElasticHelper(Real mu, Real nu)
: mu(mu), nu(nu), lambda(2 * mu * nu / (1 - 2 * nu)) {}
template <typename DT, typename ST>
Matrix<std::remove_cv_t<DT>, dim, dim>
operator()(const StaticMatrix<DT, ST, dim, dim>& gradu) const {
auto trace = gradu.trace();
Matrix<std::remove_cv_t<DT>, dim, dim> sigma;
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
sigma(i, j) =
(i == j) * lambda * trace + mu * (gradu(i, j) + gradu(j, i));
return sigma;
}
template <typename DT, typename ST>
SymMatrix<std::remove_cv_t<DT>, dim>
operator()(const StaticSymMatrix<DT, ST, dim>& eps) const {
SymMatrix<std::remove_cv_t<DT>, dim> sigma;
auto trace = eps.trace();
for (UInt i = 0; i < dim; ++i)
sigma(i) = lambda * trace + 2 * mu * eps(i);
for (UInt i = dim; i < voigt_size<dim>::value; ++i)
sigma(i) = 2 * mu * eps(i);
return sigma;
}
template <typename DT, typename ST>
Matrix<std::remove_cv_t<DT>, dim, dim>
inverse(const StaticMatrix<DT, ST, dim, dim>& sigma) const {
Matrix<std::remove_cv_t<DT>, dim, dim> epsilon;
auto trace = sigma.trace();
auto c1 = 1. / (2 * mu);
auto c2 = -lambda / (3 * lambda + 2 * mu);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
epsilon(i, j) = c1 * (sigma(i, j) + c2 * trace * (i == j));
}
const Real mu, nu, lambda;
};
} // namespace influence
/* -------------------------------------------------------------------------- */
/**
* @brief Model containing pressure and displacement
* This class is a container for the model fields. It is supposed to be
* dimension agnostic, hence the GridBase members.
*/
class Model {
protected:
/// Constructor
Model(std::vector<Real> system_size, std::vector<UInt> discretization);
public:
/// Destructor
virtual ~Model();
public:
/// Set elasticity parameters
void setElasticity(Real E, Real nu);
/// Get Hertz contact modulus
Real getHertzModulus() const;
/// Get Young's modulus
Real getYoungModulus() const { return E; }
/// Get Poisson's ratio
Real getPoissonRatio() const { return nu; }
/// Get shear modulus
Real getShearModulus() const { return E / (2 * (1 + nu)); }
/// Set Young's modulus
void setYoungModulus(Real E_) {
if (E_ < 0)
TAMAAS_EXCEPTION("Elastic modulus should be positive");
this->E = E_;
updateOperators();
}
/// Set Poisson's ratio
void setPoissonRatio(Real nu_) {
if (nu_ > 0.5 or nu_ <= -1)
TAMAAS_EXCEPTION("Poisson ratio should be in ]-1, 0.5]");
this->nu = nu_;
updateOperators();
}
public:
virtual void applyElasticity(GridBase<Real>& stress,
const GridBase<Real>& strain) const = 0;
public:
/// Get pressure
GridBase<Real>& getTraction();
/// Get pressure
const GridBase<Real>& getTraction() const;
/// Get displacement
GridBase<Real>& getDisplacement();
/// Get displacement
const GridBase<Real>& getDisplacement() const;
/// Get model type
virtual model_type getType() const = 0;
/// Get system physical size
const std::vector<Real>& getSystemSize() const;
/// Get boundary system physical size
virtual std::vector<Real> getBoundarySystemSize() const = 0;
/// Get discretization
const std::vector<UInt>& getDiscretization() const;
/// Get boundary discretization
virtual std::vector<UInt> getBoundaryDiscretization() const = 0;
/// Get boundary element engine
BEEngine& getBEEngine() {
TAMAAS_ASSERT(engine, "BEEngine was not initialized");
return *engine;
}
/// Solve Neumann problem using default neumann operator
void solveNeumann();
/// Solve Dirichlet problem using default dirichlet operator
void solveDirichlet();
public:
/// Register a new integral operator
template <typename Operator>
IntegralOperator* registerIntegralOperator(const std::string& name) {
Logger().get(LogLevel::debug)
<< "[Model] registering operator " + name + '\n';
operators[name] = std::make_unique<Operator>(this);
return operators[name].get();
}
/// Get a registerd integral operator
IntegralOperator* getIntegralOperator(const std::string& name);
/// Tell operators to update their cache
void updateOperators();
public:
/// Register a field
void registerField(const std::string& name,
std::shared_ptr<GridBase<Real>> field);
/// Get a field
const GridBase<Real>& getField(const std::string& name) const;
/// Get a non-const field
GridBase<Real>& getField(const std::string& name);
/// Get fields
std::vector<std::string> getFields() const;
/// Get fields map
const auto& getFieldsMap() const { return fields; }
public:
/// Set the dumper object
void addDumper(std::shared_ptr<ModelDumper> dumper);
/// Dump the model
void dump() const;
protected:
Real E = 1, nu = 0;
std::vector<Real> system_size;
std::vector<UInt> discretization;
std::unique_ptr<BEEngine> engine = nullptr;
std::unordered_map<std::string, std::shared_ptr<IntegralOperator>> operators;
std::unordered_map<std::string, std::shared_ptr<GridBase<Real>>> fields;
std::vector<std::shared_ptr<ModelDumper>> dumpers;
};
/* -------------------------------------------------------------------------- */
/* Output model to stream */
/* -------------------------------------------------------------------------- */
std::ostream& operator<<(std::ostream& o, const Model& _this);
/* -------------------------------------------------------------------------- */
/* Simpler grid allocation */
/* -------------------------------------------------------------------------- */
template <bool boundary, typename T>
std::unique_ptr<GridBase<T>> allocateGrid(Model& model) {
return allocateGrid<boundary, T>(
model.getType(), (boundary) ? model.getBoundaryDiscretization()
: model.getDiscretization());
}
template <bool boundary, typename T>
std::unique_ptr<GridBase<T>> allocateGrid(Model& model, UInt nc) {
return allocateGrid<boundary, T>(model.getType(),
(boundary)
? model.getBoundaryDiscretization()
: model.getDiscretization(),
nc);
}
} // namespace tamaas
#endif // MODEL_HH

Event Timeline