Page MenuHomec4science

model.hh
No OneTemporary

File Metadata

Created
Fri, May 3, 05:05

model.hh

/*
* SPDX-License-Indentifier: AGPL-3.0-or-later
*
* Copyright (©) 2016-2023 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
* Copyright (©) 2020-2023 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef MODEL_HH
#define MODEL_HH
/* -------------------------------------------------------------------------- */
#include "be_engine.hh"
#include "field_container.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 <vector>
/* -------------------------------------------------------------------------- */
namespace tamaas {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/// Forward declaration
enum class integration_method;
/**
* @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 : public FieldContainer {
protected:
/// Constructor
Model(std::vector<Real> system_size, std::vector<UInt> discretization)
: FieldContainer(), system_size(std::move(system_size)),
discretization(std::move(discretization)) {}
public:
/// Set elasticity parameters
void setElasticity(Real E, Real nu);
/// Get Hertz contact modulus
Real getHertzModulus() const { return E / (1 - nu * nu); }
/// 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)
throw std::range_error{TAMAAS_MSG("Elastic modulus should be positive")};
this->E = E_;
updateOperators();
}
/// Set Poisson's ratio
void setPoissonRatio(Real nu_) {
if (nu_ > 0.5 or nu_ <= -1)
throw std::range_error{
TAMAAS_MSG("Poisson ratio should be in ]-1, 0.5]")};
this->nu = nu_;
updateOperators();
}
// Model info accessors
public:
/// 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 discretization of global MPI system
virtual std::vector<UInt> getGlobalDiscretization() const = 0;
/// 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;
}
// Exposing some common operators
public:
/// Apply Hooke's law
void applyElasticity(GridBase<Real>& stress,
const GridBase<Real>& strain) const;
/// 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>
std::shared_ptr<IntegralOperator>
registerIntegralOperator(const std::string& name);
/// Register external operator
void registerIntegralOperator(const std::string& name,
std::shared_ptr<IntegralOperator> op);
/// Get a registerd integral operator
std::shared_ptr<IntegralOperator>
getIntegralOperator(const std::string& name) const;
/// Get list of integral operators
std::vector<std::string> getIntegralOperators() const;
/// Get operators mapcar
const auto& getIntegralOperatorsMap() const { return operators; }
/// Tell operators to update their cache
void updateOperators();
/// Set integration method for registered volume operators
virtual void setIntegrationMethod(integration_method method, Real cutoff) = 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;
/// Determine if a field is defined on boundary
template <class T>
bool isBoundaryField(const GridBase<T>& field) const {
return field.getDimension() == getBoundaryDiscretization().size();
}
/// Return list of fields defined on boundary
std::vector<std::string> getBoundaryFields() const;
public:
/// Set the dumper object
void addDumper(std::shared_ptr<ModelDumper> dumper);
/// Dump the model
void dump() const;
friend std::ostream& operator<<(std::ostream& o, const Model& _this);
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::vector<std::shared_ptr<ModelDumper>> dumpers;
};
/* -------------------------------------------------------------------------- */
/* Template functions */
/* -------------------------------------------------------------------------- */
template <typename Operator>
std::shared_ptr<IntegralOperator>
Model::registerIntegralOperator(const std::string& name) {
Logger().get(LogLevel::debug) << TAMAAS_MSG("registering operator ", name);
operators[name] = std::make_unique<Operator>(this);
return operators[name];
}
/* -------------------------------------------------------------------------- */
/* 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