Page MenuHomec4science

model_factory.cpp
No OneTemporary

File Metadata

Created
Wed, Jun 19, 05:51

model_factory.cpp

/*
* SPDX-License-Indentifier: AGPL-3.0-or-later
*
* Copyright (©) 2016-2022 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
* Copyright (©) 2020-2022 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 "model_factory.hh"
#include "model_template.hh"
#include <functional>
/* -------------------------------------------------------------------------- */
namespace tamaas {
template <typename Abstract, template <model_type> class Concrete,
class... Args>
decltype(auto) createFromModelType(model_type type, Args&&... args) {
using namespace std::placeholders;
return model_type_dispatch(
std::bind(
[](auto&& _, Args&&... args) -> std::unique_ptr<Abstract> {
constexpr auto type = std::decay_t<decltype(_)>::value;
return std::make_unique<Concrete<type>>(
std::forward<Args>(args)...);
},
_1, std::forward<Args>(args)...),
type);
}
std::unique_ptr<Model>
ModelFactory::createModel(model_type type, const std::vector<Real>& system_size,
const std::vector<UInt>& discretization) {
return createFromModelType<Model, ModelTemplate>(type, system_size,
discretization);
}
std::unique_ptr<Model> ModelFactory::createModel(const Model& model) {
auto copy = createModel(model.getType(), model.getSystemSize(),
model.getDiscretization());
copy->setElasticity(model.getYoungModulus(), model.getPoissonRatio());
// Register and copy all fields
for (auto&& k : model.getFields()) {
auto&& f = model[k];
dimension_dispatch(
[&copy, &f, &k](auto&& _) {
constexpr UInt dim = std::decay_t<decltype(_)>::value;
const auto* ptr = dynamic_cast<const Grid<Real, dim>*>(&f);
if (ptr != nullptr) {
auto new_f = std::make_shared<Grid<Real, dim>>(
ptr->sizes(), ptr->getNbComponents());
*new_f = *ptr;
copy->registerField(k, std::move(new_f));
}
},
f.getDimension());
}
// TODO: Registrer and copy integral operators
return copy;
}
std::unique_ptr<Residual>
ModelFactory::createResidual(Model* model, Real sigma_y, Real hardening) {
if (model->getType() != model_type::volume_2d)
TAMAAS_EXCEPTION("Cannot instanciate model: " << model);
return std::make_unique<ResidualTemplate<model_type::volume_2d>>(
model, sigma_y, hardening);
}
void ModelFactory::registerVolumeOperators(Model& m) {
if (m.getType() != model_type::volume_2d)
TAMAAS_EXCEPTION("Registering volume operators not supported on "
<< m.getType());
constexpr auto type = model_type::volume_2d;
m.registerIntegralOperator<Mindlin<type, 2>>("mindlin_gradient");
m.registerIntegralOperator<Boussinesq<type, 1>>("boussinesq_gradient");
m.registerIntegralOperator<Mindlin<type, 1>>("mindlin");
m.registerIntegralOperator<Boussinesq<type, 0>>("boussinesq");
}
void ModelFactory::setIntegrationMethod(IntegralOperator& op,
integration_method method,
Real cutoff) {
#define CAST(derivative) \
do { \
auto* casted = \
dynamic_cast<Kelvin<model_type::volume_2d, derivative>*>(&op); \
if (casted != nullptr) { \
casted->setIntegrationMethod(method, cutoff); \
return; \
} \
} while (0)
CAST(0);
CAST(1);
CAST(2);
}
} // namespace tamaas

Event Timeline