diff --git a/python/py_dof_manager.cc b/python/py_dof_manager.cc
index 6af11fe89..1adddf59d 100644
--- a/python/py_dof_manager.cc
+++ b/python/py_dof_manager.cc
@@ -1,295 +1,296 @@
/*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*/
/* -------------------------------------------------------------------------- */
#include "py_dof_manager.hh"
#include "py_aka_array.hh"
#include "py_akantu_pybind11_compatibility.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#include
#include
/* -------------------------------------------------------------------------- */
#include
#include
#include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace {
class PySolverCallback : public SolverCallback {
public:
using SolverCallback::SolverCallback;
/// get the type of matrix needed
MatrixType getMatrixType(const ID & matrix_id) const override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE_PURE(MatrixType, SolverCallback, getMatrixType,
matrix_id);
}
/// callback to assemble a Matrix
void assembleMatrix(const ID & matrix_id) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE_PURE(void, SolverCallback, assembleMatrix, matrix_id);
}
/// callback to assemble a lumped Matrix
void assembleLumpedMatrix(const ID & matrix_id) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE_PURE(void, SolverCallback, assembleLumpedMatrix,
matrix_id);
}
/// callback to assemble the residual (rhs)
void assembleResidual() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE_PURE(void, SolverCallback, assembleResidual);
}
/// callback for the predictor (in case of dynamic simulation)
void predictor() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, SolverCallback, predictor);
}
/// callback for the corrector (in case of dynamic simulation)
void corrector() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, SolverCallback, corrector);
}
void beforeSolveStep() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, SolverCallback, beforeSolveStep);
}
void afterSolveStep(bool converged) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, SolverCallback, afterSolveStep, converged);
}
};
class PyInterceptSolverCallback : public InterceptSolverCallback {
public:
using InterceptSolverCallback::InterceptSolverCallback;
MatrixType getMatrixType(const ID & matrix_id) const override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(MatrixType, InterceptSolverCallback, getMatrixType,
matrix_id);
}
void assembleMatrix(const ID & matrix_id) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, assembleMatrix,
matrix_id);
}
/// callback to assemble a lumped Matrix
void assembleLumpedMatrix(const ID & matrix_id) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, assembleLumpedMatrix,
matrix_id);
}
void assembleResidual() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, assembleResidual);
}
void predictor() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, predictor);
}
void corrector() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, corrector);
}
void beforeSolveStep() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, beforeSolveStep);
}
void afterSolveStep(bool converged) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, InterceptSolverCallback, afterSolveStep,
converged);
}
};
} // namespace
/* -------------------------------------------------------------------------- */
void register_dof_manager(py::module & mod) {
py::class_>(mod, "DOFManager")
.def("getMatrix", &DOFManager::getMatrix,
py::return_value_policy::reference)
.def(
"getNewMatrix",
[](DOFManager & self, const std::string & name,
const std::string & matrix_to_copy_id) -> decltype(auto) {
return self.getNewMatrix(name, matrix_to_copy_id);
},
py::return_value_policy::reference)
.def(
"getResidual",
[](DOFManager & self) -> decltype(auto) {
return self.getResidual();
},
py::return_value_policy::reference)
.def(
"getSolution",
[](DOFManager & self) -> decltype(auto) {
return self.getSolution();
},
py::return_value_policy::reference)
.def("getArrayPerDOFs", &DOFManager::getArrayPerDOFs)
.def(
"hasMatrix",
[](DOFManager & self, const ID & name) -> bool {
return self.hasMatrix(name);
},
py::arg("name"))
.def("assembleToResidual", &DOFManager::assembleToResidual,
py::arg("dof_id"), py::arg("array_to_assemble"),
py::arg("scale_factor") = 1.)
.def("assembleMatMulVectToGlobalArray",
&DOFManager::assembleMatMulVectToGlobalArray, py::arg("dof_id"),
py::arg("A_id"), py::arg("x"), py::arg("array"),
py::arg("scale_factor") = 1.)
.def("assembleToLumpedMatrix", &DOFManager::assembleToLumpedMatrix,
py::arg("dof_id"), py::arg("array_to_assemble"),
py::arg("lumped_mtx"), py::arg("scale_factor") = 1.)
.def("assemblePreassembledMatrix",
&DOFManager::assemblePreassembledMatrix, py::arg("matrix_id"),
py::arg("terms"))
.def("zeroResidual", &DOFManager::zeroResidual)
.def("globalToLocalEquationNumber",
&DOFManager::globalToLocalEquationNumber)
.def("localToGlobalEquationNumber",
&DOFManager::localToGlobalEquationNumber)
.def("getLocalEquationsNumbers", &DOFManager::getLocalEquationsNumbers)
.def("getGlobalBlockedDOFs", &DOFManager::getGlobalBlockedDOFs)
.def("updateGlobalBlockedDofs", &DOFManager::updateGlobalBlockedDofs)
.def("getTimeStepSolver", &DOFManager::getTimeStepSolver,
py::return_value_policy::reference)
.def(
"assembleElementalArrayLocalArray",
[](DOFManager & self, const Array & elementary_vect,
Array & array_assembeled, ElementType type,
GhostType ghost_type, Real scale_factor) {
self.assembleElementalArrayLocalArray(elementary_vect,
array_assembeled, type,
ghost_type, scale_factor);
},
py::arg("elementary_vect"), py::arg("array_assembeled"),
py::arg("type"), py::arg("ghost_type") = _not_ghost,
py::arg("scale_factor") = 1.)
.def(
"assembleToGlobalArray",
[](DOFManager & self, const ID & dof_id,
const Array & array_to_assemble, SolverVector & global_array,
Real scale_factor) {
self.assembleToGlobalArray(dof_id, array_to_assemble, global_array,
scale_factor);
},
py::arg("dof_id"), py::arg("array_to_assemble"),
py::arg("global_array"), py::arg("scale_factor") = 1.)
.def("getNewGlobalVector", &DOFManager::getNewGlobalVector,
py::return_value_policy::reference);
py::class_(mod, "NonLinearSolver")
.def(
"set",
[](NonLinearSolver & self, const std::string & id, const Real & val) {
if (id == "max_iterations") {
self.set(id, int(val));
} else {
self.set(id, val);
}
})
.def("set",
[](NonLinearSolver & self, const std::string & id,
const SolveConvergenceCriteria & val) { self.set(id, val); })
.def("getNbIterations",
[](NonLinearSolver & self) -> Int {
return self.get("nb_iterations");
})
.def("getConvergenceStatus",
[](NonLinearSolver & self) -> bool { return self.get("converged"); })
.def("getError",
[](NonLinearSolver & self) -> Real { return self.get("error"); })
.def("getMaxIterations",
[](NonLinearSolver & self) -> Int {
return self.get("max_iterations");
})
.def("getThreshold", [](NonLinearSolver & self) -> Real {
- return self.get("threshold");
+ return self.get("threshold_normalized");
});
py::class_(mod, "TimeStepSolver")
.def(
"assembleResidual",
[](TimeStepSolver & self, const ID & residual_part) {
self.assembleResidual(residual_part);
},
py::arg("residual_part"))
.def("assembleResidual",
[](TimeStepSolver & self) { self.assembleResidual(); })
+ .def("assembleMatrix", &TimeStepSolver::assembleMatrix)
.def(
"assembleResidual",
[](TimeStepSolver & self, SolverCallback & solver_callback,
const ID & residual_part) {
self.assembleResidual(solver_callback, residual_part);
},
py::arg("solver_callback"), py::arg("residual_part"))
.def(
"assembleResidual",
[](TimeStepSolver & self, SolverCallback & solver_callback) {
self.assembleResidual(solver_callback);
},
py::arg("solver_callback"))
.def("getIntegrationScheme", &TimeStepSolver::getIntegrationScheme);
py::class_(mod, "SolverCallback")
.def(py::init_alias())
.def("getMatrixType", &SolverCallback::getMatrixType)
.def("assembleMatrix", &SolverCallback::assembleMatrix)
.def("assembleLumpedMatrix", &SolverCallback::assembleLumpedMatrix)
.def("assembleResidual",
[](SolverCallback & self) { self.assembleResidual(); })
.def("predictor", &SolverCallback::predictor)
.def("corrector", &SolverCallback::corrector)
.def("beforeSolveStep", &SolverCallback::beforeSolveStep)
.def("afterSolveStep", &SolverCallback::afterSolveStep)
.def_property_readonly("dof_manager", &SolverCallback::getSCDOFManager,
py::return_value_policy::reference);
py::class_(mod, "InterceptSolverCallback")
.def(py::init_alias());
}
} // namespace akantu
diff --git a/python/py_heat_transfer_interface_model.cc b/python/py_heat_transfer_interface_model.cc
index c97c07340..a96b0d94c 100644
--- a/python/py_heat_transfer_interface_model.cc
+++ b/python/py_heat_transfer_interface_model.cc
@@ -1,102 +1,104 @@
/**
* @file py_heat_transfer_interface_model.cc
*
* @author Emil Gallyamov
*
* @date creation: Tue May 16 2023
* @date last modification: Tue May 16 2023
*
* @brief pybind11 interface to HeatTransferInterfaceModel
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "py_aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
#include
/* -------------------------------------------------------------------------- */
// #include
#include
// #include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
#define def_deprecated(func_name, mesg) \
def(func_name, [](py::args, py::kwargs) { AKANTU_ERROR(mesg); })
#define def_function_nocopy(func_name) \
def( \
#func_name, \
[](HeatTransferInterfaceModel & self) -> decltype(auto) { \
return self.func_name(); \
}, \
py::return_value_policy::reference)
#define def_function(func_name) \
def(#func_name, [](HeatTransferInterfaceModel & self) -> decltype(auto) { \
return self.func_name(); \
})
/* -------------------------------------------------------------------------- */
void register_heat_transfer_interface_model(py::module & mod) {
py::class_(
mod, "HeatTransferInterfaceModel")
.def(py::init(), py::arg("mesh"),
py::arg("spatial_dimension") = _all_dimensions,
py::arg("id") = "heat_transfer_model")
.def(
"initFull",
[](HeatTransferInterfaceModel & self,
const HeatTransferModelOptions & options) {
self.initFull(options);
},
py::arg("_analysis_method") = HeatTransferModelOptions())
.def(
"initFull",
[](HeatTransferInterfaceModel & self,
const AnalysisMethod & _analysis_method) {
self.initFull(HeatTransferModelOptions(_analysis_method));
},
py::arg("_analysis_method"))
.def("setTimeStep", &HeatTransferInterfaceModel::setTimeStep,
py::arg("time_step"), py::arg("solver_id") = "")
- .def("getTransversalConductivityOnQpoints",
- &HeatTransferInterfaceModel::getTransversalConductivityOnQpoints,
- py::arg("el_type"), py::arg("ghost_type") = _not_ghost,
- py::return_value_policy::reference)
+ .def("computeTempOnQpoints",
+ &HeatTransferInterfaceModel::computeTempOnQpoints,
+ py::arg("ghost_type") = _not_ghost)
.def("getLongitudinalConductivityOnQpoints",
&HeatTransferInterfaceModel::getLongitudinalConductivityOnQpoints,
py::arg("el_type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"getOpening",
[](HeatTransferInterfaceModel & self, ElementType & el_type,
GhostType & ghost_type) { self.getOpening(el_type, ghost_type); },
py::arg("el_type"), py::arg("ghost_type") = _not_ghost,
- py::return_value_policy::reference);
+ py::return_value_policy::reference)
+ .def("updateNormalOpeningAtQuadraturePoints",
+ &HeatTransferInterfaceModel::updateNormalOpeningAtQuadraturePoints,
+ py::arg("positions"), py::arg("ghost_type") = _not_ghost);
}
} // namespace akantu
diff --git a/python/py_heat_transfer_model.cc b/python/py_heat_transfer_model.cc
index 568397bcb..00cd5c9c2 100644
--- a/python/py_heat_transfer_model.cc
+++ b/python/py_heat_transfer_model.cc
@@ -1,142 +1,143 @@
/**
* @file py_heat_transfer_model.cc
*
* @author Nicolas Richart
*
* @date creation: Sun Jun 16 2019
* @date last modification: Sun Jun 16 2019
*
* @brief pybind11 interface to HeatTransferModel
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "py_aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
#include
/* -------------------------------------------------------------------------- */
// #include
#include
// #include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
#define def_deprecated(func_name, mesg) \
def(func_name, [](py::args, py::kwargs) { AKANTU_ERROR(mesg); })
#define def_function_nocopy(func_name) \
def( \
#func_name, \
[](HeatTransferModel & self) -> decltype(auto) { \
return self.func_name(); \
}, \
py::return_value_policy::reference)
#define def_function(func_name) \
def(#func_name, [](HeatTransferModel & self) -> decltype(auto) { \
return self.func_name(); \
})
/* -------------------------------------------------------------------------- */
void register_heat_transfer_model(py::module & mod) {
py::class_(mod, "HeatTransferModelOptions")
.def(py::init(),
py::arg("analysis_method") = _explicit_lumped_mass);
py::class_(mod, "HeatTransferModel",
py::multiple_inheritance())
.def(py::init(), py::arg("mesh"),
py::arg("spatial_dimension") = _all_dimensions,
py::arg("id") = "heat_transfer_model")
.def(
"initFull",
[](HeatTransferModel & self,
const HeatTransferModelOptions & options) {
self.initFull(options);
},
py::arg("_analysis_method") = HeatTransferModelOptions())
.def(
"initFull",
[](HeatTransferModel & self,
const AnalysisMethod & _analysis_method) {
self.initFull(HeatTransferModelOptions(_analysis_method));
},
py::arg("_analysis_method"))
.def("setTimeStep", &HeatTransferModel::setTimeStep, py::arg("time_step"),
py::arg("solver_id") = "")
.def("getTimeStep", &HeatTransferModel::getTimeStep,
py::arg("solver_id") = "")
.def_function(getStableTimeStep)
.def_function(getCapacity)
.def_function(getDensity)
.def_function(assembleInternalHeatRate)
+ .def_function(assembleCapacity)
.def_function_nocopy(getTemperature)
.def_function_nocopy(getTemperatureRate)
.def_function_nocopy(getBlockedDOFs)
.def_function_nocopy(getExternalHeatRate)
.def_function_nocopy(getInternalHeatRate)
.def_function_nocopy(getMesh)
.def_function(needToReassembleCapacity)
.def_function(getConductivityMatrixRelease)
.def("getConductivityRelease", &HeatTransferModel::getConductivityRelease,
py::arg("ghost_type") = _not_ghost)
.def("getTemperatureGradient", &HeatTransferModel::getTemperatureGradient,
py::arg("el_type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def("getKgradT", &HeatTransferModel::getKgradT, py::arg("el_type"),
py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def("getTemperatureRateOnQpoints",
&HeatTransferModel::getTemperatureRateOnQpoints, py::arg("el_type"),
py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def("applyBC",
[](HeatTransferModel & self, BC::Dirichlet::DirichletFunctor & func,
const std::string & element_group) {
self.applyBC(func, element_group);
})
.def("synchronizeField", &HeatTransferModel::synchronizeField,
py::arg("synchronization_tag"))
.def(
"assignPropertyToPhysicalGroup",
[](HeatTransferModel & self, const std::string & property_name,
const std::string & group_name, Real value) {
self.assignPropertyToPhysicalGroup(property_name, group_name,
value);
},
py::arg("property_name"), py::arg("group_name"), py::arg("value"))
.def(
"assignPropertyToPhysicalGroup",
[](HeatTransferModel & self, const std::string & property_name,
const std::string & group_name, Matrix cond_matrix) {
self.assignPropertyToPhysicalGroup(property_name, group_name,
cond_matrix);
},
py::arg("property_name"), py::arg("group_name"),
py::arg("cond_matrix"));
}
} // namespace akantu
diff --git a/python/py_material.cc b/python/py_material.cc
index a496d2f8a..c220cbc3f 100644
--- a/python/py_material.cc
+++ b/python/py_material.cc
@@ -1,478 +1,521 @@
/**
* @file py_material.cc
*
* @author Guillaume Anciaux
* @author Mohit Pundir
* @author Nicolas Richart
*
* @date creation: Thu Jun 20 2019
* @date last modification: Fri Apr 09 2021
*
* @brief pybind11 interface to Material
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "py_aka_array.hh"
#include "py_akantu_pybind11_compatibility.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#if defined(AKANTU_COHESIVE_ELEMENT)
#include
#include
#include
#include
#include
#endif
#include
/* -------------------------------------------------------------------------- */
#include
#include
#include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace {
template class PyMaterial : public _Material {
public:
/* Inherit the constructors */
using _Material::_Material;
~PyMaterial() override = default;
void initMaterial() override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, _Material, initMaterial, );
};
void computeStress(ElementType el_type,
GhostType ghost_type = _not_ghost) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE_PURE(void, _Material, computeStress, el_type,
ghost_type);
}
void computeTangentModuli(ElementType el_type, Array & tangent_matrix,
GhostType ghost_type = _not_ghost) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, _Material, computeTangentModuli, el_type,
tangent_matrix, ghost_type);
}
-
void computePotentialEnergy(ElementType el_type) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, _Material, computePotentialEnergy, el_type);
}
Real getPushWaveSpeed(const Element & element) const override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(Real, _Material, getPushWaveSpeed, element);
}
Real getShearWaveSpeed(const Element & element) const override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(Real, _Material, getShearWaveSpeed, element);
}
template
void registerInternal(const std::string & name, UInt nb_component) {
auto && internal = std::make_shared>(name, *this);
AKANTU_DEBUG_INFO("alloc internal " << name << " "
<< &this->internals[name]);
internal->initialize(nb_component);
this->internals[name] = internal;
}
template
void setDefaultValueToInternal(const ID & int_id, const T value) {
auto & internal_field = this->template getInternal(int_id);
internal_field.setDefaultValue(value);
}
protected:
std::map> internals;
};
/* ------------------------------------------------------------------------ */
template
void register_material_classes(py::module & mod, const std::string & name) {
py::class_<_Material, Material, Parsable, PyMaterial<_Material>>(
mod, name.c_str(), py::multiple_inheritance())
.def(py::init())
.def("registerInternalReal",
[](Material & self, const std::string & name, Int nb_component) {
return dynamic_cast &>(self)
.template registerInternal(name, nb_component);
})
.def("registerInternalUInt",
[](Material & self, const std::string & name, Int nb_component) {
return dynamic_cast &>(self)
.template registerInternal(name, nb_component);
})
.def("setDefaultValueToInternalReal",
[](Material & self, const ID & int_id, const Real value) {
return dynamic_cast &>(self)
.template setDefaultValueToInternal(int_id, value);
})
.def("setDefaultValueToInternalUInt",
[](Material & self, const ID & int_id, const UInt value) {
return dynamic_cast &>(self)
.template setDefaultValueToInternal(int_id, value);
});
}
#if defined(AKANTU_COHESIVE_ELEMENT)
// trampoline for the cohesive materials
template
class PyMaterialCohesive : public PyMaterial<_Material> {
using Parent = PyMaterial<_Material>;
public:
using Parent::Parent;
void checkInsertion(bool check_only) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, _Material, checkInsertion, check_only);
}
void computeTraction(const Array & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE_PURE(void, _Material, computeTraction, normal, el_type,
ghost_type);
}
void computeTangentTraction(ElementType el_type,
Array & tangent_matrix,
const Array & normal,
GhostType ghost_type = _not_ghost) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, _Material, computeTangentTraction, el_type,
tangent_matrix, normal, ghost_type);
}
void computeStress(ElementType /*el_type*/,
GhostType /*ghost_type*/ = _not_ghost) final {}
void computeTangentModuli(ElementType /*el_type*/,
Array & /*tangent_matrix*/,
GhostType /*ghost_type*/ = _not_ghost) final {}
template
void registerInternal(const std::string & name, Int nb_component) {
auto && internal =
std::make_shared>(name, *this);
AKANTU_DEBUG_INFO("alloc internal " << name << " "
<< &this->internals[name]);
internal->initialize(nb_component);
this->internals[name] = internal;
}
};
// trampoline for the cohesive material inheritance where computeTraction is
// not pure virtual
template
class PyMaterialCohesiveDaughters : public PyMaterialCohesive<_Material> {
using Parent = PyMaterialCohesive<_Material>;
public:
using Parent::Parent;
void computeTraction(const Array & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) override {
// NOLINTNEXTLINE
PYBIND11_OVERRIDE(void, _Material, computeTraction, normal, el_type,
ghost_type);
}
+
+ void computeTangentTraction(ElementType el_type,
+ Array & tangent_matrix,
+ const Array & normal,
+ GhostType ghost_type = _not_ghost) override {
+ // NOLINTNEXTLINE
+ PYBIND11_OVERRIDE(void, _Material, computeTangentTraction, el_type,
+ tangent_matrix, normal, ghost_type);
+ }
};
template
void register_material_cohesive_classes(py::module & mod,
const std::string & name) {
py::class_<_Material, MaterialCohesive,
PyMaterialCohesiveDaughters<_Material>>(
mod, name.c_str(), py::multiple_inheritance())
.def(py::init())
.def("registerInternalReal",
[](_Material & self, const std::string & name, UInt nb_component) {
return dynamic_cast &>(self)
.template registerInternal(name, nb_component);
})
.def("registerInternalUInt",
[](_Material & self, const std::string & name, UInt nb_component) {
return dynamic_cast &>(self)
.template registerInternal(name, nb_component);
})
.def("setDefaultValueToInternalReal",
[](_Material & self, const ID & int_id, const Real value) {
return dynamic_cast &>(self)
.template setDefaultValueToInternal(int_id, value);
})
.def("setDefaultValueToInternalUInt",
[](_Material & self, const ID & int_id, const UInt value) {
return dynamic_cast &>(self)
.template setDefaultValueToInternal(int_id, value);
})
- .def("computeTraction", [](_Material & self, const Array & normal,
- ElementType el_type, GhostType ghost_type) {
+ .def("computeTraction",
+ [](_Material & self, const Array & normal,
+ ElementType el_type, GhostType ghost_type) {
+ return dynamic_cast &>(
+ self)
+ .computeTraction(normal, el_type, ghost_type);
+ })
+ .def("computeTangentTraction", [](_Material & self, ElementType el_type,
+ Array & tangent_matrix,
+ const Array & normal,
+ GhostType ghost_type) {
return dynamic_cast &>(self)
- .computeTraction(normal, el_type, ghost_type);
+ .computeTangentTraction(el_type, tangent_matrix, normal,
+ ghost_type);
});
;
}
#endif
/* ------------------------------------------------------------------------ */
template
void register_internal_field(py::module & mod, const std::string & name) {
py::class_, ElementTypeMapArray,
std::shared_ptr>>(
mod, ("InternalField" + name).c_str());
}
} // namespace
/* -------------------------------------------------------------------------- */
void register_material(py::module & mod) {
py::class_(mod, "MaterialFactory")
.def_static(
"getInstance",
[]() -> MaterialFactory & { return Material::getFactory(); },
py::return_value_policy::reference)
.def("registerAllocator",
[](MaterialFactory & self, const std::string id, py::function func) {
self.registerAllocator(
id,
[func, id](UInt dim, const ID & /*unused*/,
SolidMechanicsModel & model,
const ID & option) -> std::unique_ptr {
py::object obj = func(dim, id, model, option);
auto & ptr = py::cast(obj);
obj.release();
return std::unique_ptr(&ptr);
});
})
.def("getPossibleAllocators", &MaterialFactory::getPossibleAllocators);
register_internal_field(mod, "Real");
register_internal_field(mod, "UInt");
py::class_>(
mod, "Material", py::multiple_inheritance())
.def(py::init())
.def(
"getGradU",
[](Material & self, ElementType el_type,
GhostType ghost_type = _not_ghost) -> decltype(auto) {
return self.getGradU(el_type, ghost_type);
},
py::arg("el_type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"getStress",
[](Material & self, ElementType el_type,
GhostType ghost_type = _not_ghost) -> decltype(auto) {
return self.getStress(el_type, ghost_type);
},
py::arg("el_type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"getPotentialEnergy",
[](Material & self, ElementType el_type) -> decltype(auto) {
return self.getPotentialEnergy(el_type);
},
py::arg("el_type"), py::return_value_policy::reference)
.def(
"getPotentialEnergy",
[](Material & self, ElementType el_type, UInt index) -> Real {
return self.getPotentialEnergy(el_type, index);
},
py::arg("el_type"), py::arg("index"))
.def("getPotentialEnergy",
[](Material & self) -> Real { return self.getPotentialEnergy(); })
.def("initMaterial", &Material::initMaterial)
.def("getModel", &Material::getModel)
.def("registerInternalReal",
[](Material & self, const std::string & name, UInt nb_component) {
return dynamic_cast &>(self)
.registerInternal(name, nb_component);
})
.def("registerInternalUInt",
[](Material & self, const std::string & name, UInt nb_component) {
return dynamic_cast &>(self)
.registerInternal(name, nb_component);
})
.def("setDefaultValueToInternalReal",
[](Material & self, const ID & int_id, const Real value) {
return dynamic_cast &>(self)
.setDefaultValueToInternal(int_id, value);
})
.def("setDefaultValueToInternalUInt",
[](Material & self, const ID & int_id, const UInt value) {
return dynamic_cast &>(self)
.setDefaultValueToInternal(int_id, value);
})
.def(
"getInternalReal",
[](Material & self, const ID & id) -> decltype(auto) {
return self.getInternal(id);
},
py::arg("id"), py::return_value_policy::reference)
+ .def(
+ "getInternalRealPrevious",
+ [](Material & self, const ID & id) -> decltype(auto) {
+ return self.getInternal(id).previous();
+ },
+ py::arg("id"), py::return_value_policy::reference)
.def(
"getInternalUInt",
[](Material & self, const ID & id) -> decltype(auto) {
return self.getInternal(id);
},
py::arg("id"), py::return_value_policy::reference)
.def(
"getElementFilter",
[](Material & self) -> decltype(auto) {
return self.getElementFilter();
},
py::return_value_policy::reference)
/*
* These functions override the `Parsable` interface.
* This ensure that the `updateInternalParameters()` function is called.
*/
.def(
"setReal",
[](Material & self, const ID & name, const Real value) -> void {
self.setParam(name, value);
return;
},
py::arg("name"), py::arg("value"))
.def(
"setBool",
[](Material & self, const ID & name, const bool value) -> void {
self.setParam(name, value);
return;
},
py::arg("name"), py::arg("value"))
.def(
"setString",
[](Material & self, const ID & name,
const std::string & value) -> void {
self.setParam(name, value);
return;
},
py::arg("name"), py::arg("value"))
.def(
"setInt",
[](Material & self, const ID & name, const int value) -> void {
self.setParam(name, value);
return;
},
py::arg("name"), py::arg("value"))
.def("getPushWaveSpeed", &Material::getPushWaveSpeed)
.def("getShearWaveSpeed", &Material::getShearWaveSpeed)
.def("__repr__", [](Material & self) {
std::stringstream sstr;
sstr << self;
return sstr.str();
});
register_material_classes>(mod, "MaterialElastic2D");
register_material_classes>(mod, "MaterialElastic3D");
#if defined(AKANTU_COHESIVE_ELEMENT)
/* ------------------------------------------------------------------------ */
py::class_>(mod, "MaterialCohesive",
py::multiple_inheritance())
.def(py::init())
.def("registerInternalReal",
[](MaterialCohesive & self, const std::string & name,
UInt nb_component) {
return dynamic_cast &>(self)
.registerInternal(name, nb_component);
})
.def("registerInternalUInt",
[](MaterialCohesive & self, const std::string & name,
UInt nb_component) {
return dynamic_cast &>(self)
.registerInternal(name, nb_component);
})
.def(
"getFacetFilter",
[](MaterialCohesive & self) -> decltype(auto) {
return self.getFacetFilter();
},
py::return_value_policy::reference)
.def(
"getFacetFilter",
[](MaterialCohesive & self, ElementType type,
GhostType ghost_type) -> decltype(auto) {
return self.getFacetFilter(type, ghost_type);
},
py::arg("type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"getOpening",
[](MaterialCohesive & self, ElementType type, GhostType ghost_type)
-> decltype(auto) { return self.getOpening(type, ghost_type); },
py::arg("type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"getTraction",
[](MaterialCohesive & self, ElementType type, GhostType ghost_type)
-> decltype(auto) { return self.getTraction(type, ghost_type); },
py::arg("type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"computeTraction",
[](MaterialCohesive & self, GhostType ghost_type) {
return self.computeTraction(ghost_type);
},
py::arg("ghost_type") = _not_ghost)
.def(
"computeTraction",
[](MaterialCohesive & self, const Array & normal,
ElementType el_type, GhostType ghost_type) {
return dynamic_cast &>(self)
.computeTraction(normal, el_type, ghost_type);
},
py::arg("normal"), py::arg("el_type"),
py::arg("ghost_type") = _not_ghost)
+ .def(
+ "computeTangentTraction",
+ [](MaterialCohesive & self, ElementType el_type,
+ Array & tangent_matrix, const Array & normal,
+ GhostType ghost_type) {
+ return dynamic_cast &>(self)
+ .computeTangentTraction(el_type, tangent_matrix, normal,
+ ghost_type);
+ },
+ py::arg("el_type"), py::arg("tangent_matrix"), py::arg("normal"),
+ py::arg("ghost_type") = _not_ghost)
+ .def(
+ "computeNormal",
+ [](MaterialCohesive & self, const Array & position,
+ Array & normal, ElementType type, GhostType ghost_type) {
+ self.computeNormal(position, normal, type, ghost_type);
+ },
+ py::arg("position"), py::arg("normal"), py::arg("type"),
+ py::arg("ghost_type") = _not_ghost)
.def("getNormalsAtQuads", &MaterialCohesive::getNormalsAtQuads);
register_material_cohesive_classes>(
mod, "MaterialCohesiveLinear2D");
register_material_cohesive_classes>(
mod, "MaterialCohesiveLinear3D");
register_material_cohesive_classes>(
mod, "MaterialCohesiveBilinear2D");
register_material_cohesive_classes>(
mod, "MaterialCohesiveBilinear3D");
register_material_cohesive_classes>(
mod, "MaterialCohesiveLinearFriction2D");
register_material_cohesive_classes>(
mod, "MaterialCohesiveLinearFriction3D");
#endif
}
} // namespace akantu
diff --git a/python/py_mesh.cc b/python/py_mesh.cc
index e379a189c..140d86288 100644
--- a/python/py_mesh.cc
+++ b/python/py_mesh.cc
@@ -1,290 +1,292 @@
/**
* @file py_mesh.cc
*
* @author Guillaume Anciaux
* @author Philip Mueller
* @author Mohit Pundir
* @author Nicolas Richart
*
* @date creation: Sun Jun 16 2019
* @date last modification: Mon Mar 15 2021
*
* @brief pybind11 interface to Mesh
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_config.hh"
/* -------------------------------------------------------------------------- */
#include "py_aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#include
/* -------------------------------------------------------------------------- */
#include
#include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace {
/* ------------------------------------------------------------------------ */
template
decltype(auto) register_element_type_map_array(py::module & mod,
const std::string & name) {
return py::class_,
std::shared_ptr>>(
mod, ("ElementTypeMapArray" + name).c_str())
.def(py::init(),
py::arg("id") = "by_element_type_array",
py::arg("parent_id") = "no_parent")
.def(
"__call__",
[](ElementTypeMapArray & self, ElementType type,
GhostType ghost_type) -> decltype(auto) {
return self(type, ghost_type);
},
py::arg("type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference, py::keep_alive<0, 1>())
.def(
"elementTypes",
[](ElementTypeMapArray & self, UInt _dim, GhostType _ghost_type,
ElementKind _kind) -> std::vector {
auto types = self.elementTypes(_dim, _ghost_type, _kind);
std::vector _types;
for (auto && t : types) {
_types.push_back(t);
}
return _types;
},
py::arg("dim") = _all_dimensions,
py::arg("ghost_type") = _not_ghost, py::arg("kind") = _ek_regular)
.def(
"initialize",
[](ElementTypeMapArray & self, const Mesh & mesh,
GhostType ghost_type = _casper, UInt nb_component = 1,
UInt spatial_dimension = UInt(-2),
ElementKind element_kind = _ek_not_defined,
bool with_nb_element = false,
bool with_nb_nodes_per_element = false, T default_value = T(),
bool do_not_default = false) {
self.initialize(
mesh, _ghost_type = ghost_type, _nb_component = nb_component,
_spatial_dimension = (spatial_dimension == UInt(-2)
? mesh.getSpatialDimension()
: spatial_dimension),
_element_kind = element_kind,
_with_nb_element = with_nb_element,
_with_nb_nodes_per_element = with_nb_nodes_per_element,
_default_value = default_value,
_do_not_default = do_not_default);
},
py::arg("mesh"), py::arg("ghost_type") = _casper,
py::arg("nb_component") = 1,
py::arg("spatial_dimension") = UInt(-2),
py::arg("element_kind") = _ek_not_defined,
py::arg("with_nb_element") = false,
py::arg("with_nb_nodes_per_element") = false,
py::arg("default_value") = T(), py::arg("do_not_default") = false);
}
} // namespace
/* -------------------------------------------------------------------------- */
void register_mesh(py::module & mod) {
py::class_(mod, "PeriodicSlaves")
.def(
"__iter__",
[](Mesh::PeriodicSlaves & _this) {
py::make_iterator(_this.begin(), _this.end());
},
py::keep_alive<0, 1>());
py::class_(mod, "MeshData")
.def(
"getElementalDataUInt",
[](MeshData & _this, const ID & name) -> decltype(auto) {
return _this.getElementalData(name);
},
py::return_value_policy::reference)
.def(
"getElementalDataReal",
[](MeshData & _this, const ID & name) -> decltype(auto) {
return _this.getElementalData(name);
},
py::return_value_policy::reference);
py::class_(mod, "Mesh",
py::multiple_inheritance())
.def(py::init(), py::arg("spatial_dimension"),
py::arg("id") = "mesh")
.def("read", &Mesh::read, py::arg("filename"),
py::arg("mesh_io_type") = _miot_auto, "read the mesh from a file")
.def(
"getNodes",
[](Mesh & self) -> decltype(auto) { return self.getNodes(); },
py::return_value_policy::reference)
.def("getNbNodes", &Mesh::getNbNodes)
+ .def("getLowerBounds", &Mesh::getLowerBounds)
+ .def("getUpperBounds", &Mesh::getUpperBounds)
.def(
"getNodesFlags",
[](const Mesh & self) -> decltype(auto) {
return self.getNodesFlags();
},
py::return_value_policy::reference)
.def(
"getConnectivity",
[](Mesh & self, ElementType type) -> decltype(auto) {
return self.getConnectivity(type);
},
py::return_value_policy::reference)
.def(
"getConnectivity",
[](Mesh & self, ElementType type,
GhostType ghost_type) -> decltype(auto) {
return self.getConnectivity(type, ghost_type);
},
py::return_value_policy::reference)
.def(
"getConnectivities",
[](Mesh & self) -> decltype(auto) {
return self.getConnectivities();
},
py::return_value_policy::reference)
.def(
"addConnectivityType",
[](Mesh & self, ElementType type, GhostType ghost_type) -> void {
self.addConnectivityType(type, ghost_type);
},
py::arg("type"), py::arg("ghost_type") = _not_ghost)
.def("distribute", [](Mesh & self) { self.distribute(); })
.def("isDistributed",
[](const Mesh & self) { return self.isDistributed(); })
.def("fillNodesToElements", &Mesh::fillNodesToElements,
py::arg("dimension") = _all_dimensions)
.def("getAssociatedElements",
[](Mesh & self, const UInt & node, py::list list) {
Array elements;
self.getAssociatedElements(node, elements);
for (auto && element : elements) {
list.append(element);
}
})
.def("makePeriodic",
[](Mesh & self, const SpatialDirection & direction) {
self.makePeriodic(direction);
})
.def(
"getNbElement",
[](Mesh & self, const UInt spatial_dimension, GhostType ghost_type,
ElementKind kind) {
return self.getNbElement(spatial_dimension, ghost_type, kind);
},
py::arg("spatial_dimension") = _all_dimensions,
py::arg("ghost_type") = _not_ghost, py::arg("kind") = _ek_not_defined)
.def(
"getNbElement",
[](Mesh & self, ElementType type, GhostType ghost_type) {
return self.getNbElement(type, ghost_type);
},
py::arg("type"), py::arg("ghost_type") = _not_ghost)
.def_static(
"getSpatialDimension",
[](ElementType & type) { return Mesh::getSpatialDimension(type); })
.def_static("getNaturalSpaceDimension",
[](ElementType & type) {
return Mesh::getNaturalSpaceDimension(type);
})
.def_static("getKind",
[](ElementType & type) { return Mesh::getKind(type); })
.def_static(
"getNbNodesPerElement",
[](ElementType & type) { return Mesh::getNbNodesPerElement(type); })
.def(
"getDataReal",
[](Mesh & _this, const ID & name, ElementType type,
GhostType ghost_type) -> decltype(auto) {
return _this.getData(name, type, ghost_type);
},
py::arg("name"), py::arg("type"), py::arg("ghost_type") = _not_ghost,
py::return_value_policy::reference)
.def(
"hasDataReal",
[](Mesh & _this, const ID & name, ElementType type,
GhostType ghost_type) -> bool {
return _this.hasData(name, type, ghost_type);
},
py::arg("name"), py::arg("type"), py::arg("ghost_type") = _not_ghost)
.def("isPeriodic", [](const Mesh & _this) { return _this.isPeriodic(); })
.def("getPeriodicMaster", &Mesh::getPeriodicMaster)
.def("getPeriodicSlaves", &Mesh::getPeriodicSlaves)
.def("isPeriodicSlave", &Mesh::isPeriodicSlave)
.def("isPeriodicMaster", &Mesh::isPeriodicMaster)
.def(
"getMeshFacets",
[](const Mesh & self) -> const Mesh & {
return self.getMeshFacets();
},
py::return_value_policy::reference)
.def("initMeshFacets", &Mesh::initMeshFacets,
py::arg("id") = "mesh_facets", py::return_value_policy::reference)
.def(
"elementTypes",
[](Mesh & self, UInt spatial_dimension, GhostType ghost_type,
ElementKind kind) -> std::vector {
auto types = self.elementTypes(spatial_dimension, ghost_type, kind);
std::vector _types;
for (auto && t : types) {
_types.push_back(t);
}
return _types;
},
py::arg("spatial_dimension") = _all_dimensions,
py::arg("ghost_type") = _not_ghost, py::arg("kind") = _ek_regular);
/* ------------------------------------------------------------------------
*/
py::class_(mod, "MeshUtils")
.def_static("buildFacets", &MeshUtils::buildFacets);
py::class_(mod, "MeshAccessor")
.def(py::init(), py::arg("mesh"))
.def(
"resizeConnectivity",
[](MeshAccessor & self, UInt new_size, ElementType type, GhostType gt)
-> void { self.resizeConnectivity(new_size, type, gt); },
py::arg("new_size"), py::arg("type"),
py::arg("ghost_type") = _not_ghost)
.def(
"resizeNodes",
[](MeshAccessor & self, UInt new_size) -> void {
self.resizeNodes(new_size);
},
py::arg("new_size"))
.def("makeReady", &MeshAccessor::makeReady);
register_element_type_map_array(mod, "Real");
register_element_type_map_array(mod, "UInt");
register_element_type_map_array(mod, "bool");
// register_element_type_map_array(mod, "String");
}
} // namespace akantu
diff --git a/python/py_model.cc b/python/py_model.cc
index 96b091cb9..deaac9af1 100644
--- a/python/py_model.cc
+++ b/python/py_model.cc
@@ -1,150 +1,151 @@
/**
* @file py_model.cc
*
* @author Guillaume Anciaux
* @author Emil Gallyamov
* @author Philip Mueller
* @author Mohit Pundir
* @author Nicolas Richart
*
* @date creation: Sun Jun 16 2019
* @date last modification: Sat Mar 13 2021
*
* @brief pybind11 interface to Model and parent classes
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "py_aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#include
#include
#include
/* -------------------------------------------------------------------------- */
#include
#include
#include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
void register_model(py::module & mod) {
py::class_(mod, "ModelSolver",
py::multiple_inheritance())
.def(
"getNonLinearSolver",
[](ModelSolver & self, const ID & solver_id) -> NonLinearSolver & {
return self.getNonLinearSolver(solver_id);
},
py::arg("solver_id") = "", py::return_value_policy::reference)
.def(
"getTimeStepSolver",
[](ModelSolver & self, const ID & solver_id) -> TimeStepSolver & {
return self.getTimeStepSolver(solver_id);
},
py::arg("solver_id") = "", py::return_value_policy::reference)
.def(
"solveStep",
[](ModelSolver & self, const ID & solver_id) {
self.solveStep(solver_id);
},
py::arg("solver_id") = "")
.def(
"solveStep",
[](ModelSolver & self, SolverCallback & callback,
const ID & solver_id) { self.solveStep(callback, solver_id); },
py::arg("callback"), py::arg("solver_id") = "");
py::class_(mod, "Model", py::multiple_inheritance())
.def("getSpatialDimension", &Model::getSpatialDimension)
.def("setBaseName", &Model::setBaseName)
.def("setDirectory", &Model::setDirectory)
.def("getFEEngine", &Model::getFEEngine, py::arg("name") = "",
py::return_value_policy::reference)
.def("getFEEngineBoundary", &Model::getFEEngine, py::arg("name") = "",
py::return_value_policy::reference)
.def("addDumpFieldVector", &Model::addDumpFieldVector)
.def("addDumpField", &Model::addDumpField)
.def("setBaseNameToDumper", &Model::setBaseNameToDumper)
+ .def("setDirectoryToDumper", &Model::setDirectoryToDumper)
.def("addDumpFieldVectorToDumper", &Model::addDumpFieldVectorToDumper)
.def("addDumpFieldToDumper", &Model::addDumpFieldToDumper)
.def("dump", [](Model & self) { self.dump(); })
.def(
"dump", [](Model & self, UInt step) { self.dump(step); },
py::arg("step"))
.def(
"dump",
[](Model & self, Real time, UInt step) { self.dump(time, step); },
py::arg("time"), py::arg("step"))
.def(
"dump",
[](Model & self, const std::string & dumper) { self.dump(dumper); },
py::arg("dumper_name"))
.def(
"dump",
[](Model & self, const std::string & dumper, UInt step) {
self.dump(dumper, step);
},
py::arg("dumper_name"), py::arg("step"))
.def(
"dump",
[](Model & self, const std::string & dumper, Real time, UInt step) {
self.dump(dumper, time, step);
},
py::arg("dumper_name"), py::arg("time"), py::arg("step"))
.def("initNewSolver", &Model::initNewSolver)
.def(
"getNewSolver",
[](Model & self, const std::string id,
const TimeStepSolverType & time,
const NonLinearSolverType & type) {
self.getNewSolver(id, time, type);
},
py::return_value_policy::reference)
.def(
"setIntegrationScheme",
[](Model & self, const std::string id, const std::string primal,
const IntegrationSchemeType & scheme_type,
IntegrationScheme::SolutionType solution_type) {
self.setIntegrationScheme(id, primal, scheme_type, solution_type);
},
py::arg("id"), py::arg("primal"), py::arg("scheme_type"),
py::arg("solution_type") =
IntegrationScheme::SolutionType::_not_defined)
// .def("setIntegrationScheme",
// [](Model & self, const std::string id, const std::string primal,
// std::unique_ptr & scheme,
// IntegrationScheme::SolutionType solution_type) {
// self.setIntegrationScheme(id, primal, scheme, solution_type);
// })
.def("getDOFManager", &Model::getDOFManager,
py::return_value_policy::reference)
.def("assembleMatrix", &Model::assembleMatrix);
}
} // namespace akantu
diff --git a/python/py_solid_mechanics_model.cc b/python/py_solid_mechanics_model.cc
index 2446e2b86..899af20da 100644
--- a/python/py_solid_mechanics_model.cc
+++ b/python/py_solid_mechanics_model.cc
@@ -1,187 +1,199 @@
/**
* @file py_solid_mechanics_model.cc
*
* @author Guillaume Anciaux
* @author Mohit Pundir
* @author Nicolas Richart
*
* @date creation: Sun Jun 16 2019
* @date last modification: Sat Mar 13 2021
*
* @brief pybind11 interface to SolidMechanicsModel
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "py_aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
#include
/* -------------------------------------------------------------------------- */
#include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
#define def_deprecated(func_name, mesg) \
def(func_name, [](py::args, py::kwargs) { AKANTU_ERROR(mesg); })
#define def_function_nocopy(func_name) \
def( \
#func_name, \
[](SolidMechanicsModel & self) -> decltype(auto) { \
return self.func_name(); \
}, \
py::return_value_policy::reference)
#define def_function(func_name) \
def(#func_name, [](SolidMechanicsModel & self) -> decltype(auto) { \
return self.func_name(); \
})
/* -------------------------------------------------------------------------- */
void register_solid_mechanics_model(py::module & mod) {
py::class_(mod, "SolidMechanicsModelOptions")
.def(py::init(),
py::arg("_analysis_method") = _explicit_lumped_mass);
py::class_(mod, "SolidMechanicsModel",
py::multiple_inheritance())
.def(py::init,
const ModelType>(),
py::arg("mesh"), py::arg("spatial_dimension") = _all_dimensions,
py::arg("id") = "solid_mechanics_model",
py::arg("dof_manager") = nullptr,
py::arg("model_type") = ModelType::_solid_mechanics_model)
.def(
"initFull",
[](SolidMechanicsModel & self,
const SolidMechanicsModelOptions & options) {
self.initFull(options);
},
py::arg("option") = SolidMechanicsModelOptions())
.def(
"initFull",
[](SolidMechanicsModel & self,
const AnalysisMethod & analysis_method) {
self.initFull(_analysis_method = analysis_method);
},
py::arg("_analysis_method"))
.def_deprecated("applyDirichletBC", "Deprecated: use applyBC")
.def("applyBC",
[](SolidMechanicsModel & self,
BC::Dirichlet::DirichletFunctor & func,
const std::string & element_group) {
self.applyBC(func, element_group);
})
.def("applyBC",
[](SolidMechanicsModel & self, BC::Neumann::NeumannFunctor & func,
const std::string & element_group) {
self.applyBC(func, element_group);
})
.def("setTimeStep", &SolidMechanicsModel::setTimeStep,
py::arg("time_step"), py::arg("solver_id") = "")
.def(
"getEnergy",
[](SolidMechanicsModel & self, const std::string & energy_id) {
return self.getEnergy(energy_id);
},
py::arg("energy_id"))
.def(
"getEnergy",
[](SolidMechanicsModel & self, const std::string & energy_id,
const std::string & group_id) {
return self.getEnergy(energy_id, group_id);
},
py::arg("energy_id"), py::arg("group_id"))
-
+ .def("getDisplacementRelease",
+ [](SolidMechanicsModel & self) {
+ return self.getDisplacementRelease();
+ })
+ .def("setDisplacementRelease",
+ [](SolidMechanicsModel & self, UInt value) {
+ return self.setDisplacementRelease(value);
+ })
+ .def("increaseDisplacementRelease",
+ [](SolidMechanicsModel & self) {
+ UInt release = self.getDisplacementRelease();
+ return self.setDisplacementRelease(release + 1);
+ })
.def_function(assembleStiffnessMatrix)
.def_function(assembleInternalForces)
.def_function(assembleMass)
.def_function(assembleMassLumped)
.def_function(getStableTimeStep)
.def_function_nocopy(getExternalForce)
.def_function_nocopy(getDisplacement)
.def_function_nocopy(getPreviousDisplacement)
.def_function_nocopy(getCurrentPosition)
.def_function_nocopy(getIncrement)
.def_function_nocopy(getMass)
.def_function_nocopy(getVelocity)
.def_function_nocopy(getAcceleration)
.def_function_nocopy(getInternalForce)
.def_function_nocopy(getBlockedDOFs)
.def_function_nocopy(getMesh)
.def(
"getMaterial",
[](SolidMechanicsModel & self, UInt material_id) -> decltype(auto) {
return self.getMaterial(material_id);
},
py::arg("material_id"), py::return_value_policy::reference)
.def(
"getMaterial",
[](SolidMechanicsModel & self, const ID & material_name)
-> decltype(auto) { return self.getMaterial(material_name); },
py::arg("material_name"), py::return_value_policy::reference)
.def(
"getMaterial",
[](SolidMechanicsModel & self, const Element & element)
-> decltype(auto) { return self.getMaterial(element); },
py::arg("element"), py::return_value_policy::reference)
.def("getNbMaterials", &SolidMechanicsModel::getNbMaterials)
.def("getMaterialIndex", &SolidMechanicsModel::getMaterialIndex)
.def("setMaterialSelector",
[](SolidMechanicsModel & self,
std::shared_ptr material_selector) {
std::cout << (*material_selector)(ElementNull) << std::endl;
self.setMaterialSelector(material_selector);
})
.def("getMaterialSelector", &SolidMechanicsModel::getMaterialSelector)
.def(
"getMaterialByElement",
[](const SolidMechanicsModel & self) -> decltype(auto) {
return self.getMaterialByElement();
},
py::return_value_policy::reference, py::keep_alive<0, 1>())
.def("reassignMaterial", &SolidMechanicsModel::reassignMaterial)
.def(
"registerNewMaterial",
[](SolidMechanicsModel & self, const ID & mat_name,
const ID & mat_type, const ID & opt_param) -> decltype(auto) {
return self.registerNewMaterial(mat_name, mat_type, opt_param);
},
py::arg("material_name"), py::arg("material_type"),
py::arg("option") = "", py::return_value_policy::reference)
.def("initMaterials", &SolidMechanicsModel::initMaterials)
.def("flattenInternal", &SolidMechanicsModel::flattenInternal,
py::return_value_policy::reference)
.def("inflateInternal", &SolidMechanicsModel::inflateInternal,
py::return_value_policy::reference)
.def("synchronizeField", &SolidMechanicsModel::synchronizeField,
py::arg("synchronization_tag"));
}
} // namespace akantu
diff --git a/python/py_solver.cc b/python/py_solver.cc
index 505aaa49b..3a146ede8 100644
--- a/python/py_solver.cc
+++ b/python/py_solver.cc
@@ -1,144 +1,145 @@
/**
* @file py_solver.cc
*
* @author Nicolas Richart
*
* @date creation: Tue Sep 29 2020
* @date last modification: Sat Mar 06 2021
*
* @brief pybind11 interface to Solver and SparseMatrix
*
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "py_solver.hh"
#include "py_aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#include
#include
/* -------------------------------------------------------------------------- */
#include
#include
#include
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
void register_solvers(py::module & mod) {
py::class_(mod, "SparseMatrix")
.def("getMatrixType", &SparseMatrix::getMatrixType)
.def("size", &SparseMatrix::size)
.def("zero", &SparseMatrix::zero)
.def("mul", &SparseMatrix::mul)
.def("saveProfile", &SparseMatrix::saveProfile)
.def("saveMatrix", &SparseMatrix::saveMatrix)
.def(
"add", [](SparseMatrix & self, UInt i, UInt j) { self.add(i, j); },
"Add entry in the profile")
.def(
"add",
[](SparseMatrix & self, UInt i, UInt j, Real value) {
self.add(i, j, value);
},
"Add the value to the matrix")
.def(
"add",
[](SparseMatrix & self, SparseMatrix & A, Real alpha) {
self.add(A, alpha);
},
"Add a matrix to the matrix", py::arg("A"), py::arg("alpha") = 1.)
.def("isFinite", &SparseMatrix::isFinite)
.def("getRelease",
[](const SparseMatrix & self) -> UInt { return self.getRelease(); })
.def("__call__",
[](const SparseMatrix & self, UInt i, UInt j) { return self(i, j); })
.def("getRelease", &SparseMatrix::getRelease)
.def("applyBoundary", &SparseMatrix::applyBoundary,
py::arg("block_val") = 1.);
py::class_(mod, "SparseMatrixAIJ")
.def("getIRN", &SparseMatrixAIJ::getIRN)
.def("getJCN", &SparseMatrixAIJ::getJCN)
.def("getA", &SparseMatrixAIJ::getA)
.def("copyContent", &SparseMatrixAIJ::copyContent)
.def("copyProfile", &SparseMatrixAIJ::copyProfile)
.def(
"matVecMul",
[](const SparseMatrixAIJ & self, const Array & x,
Array & y, Real alpha,
Real beta) { self.matVecMul(x, y, alpha, beta); },
"Multiply a matrix by a normal vector", py::arg("x"), py::arg("y"),
py::arg("alpha") = 1., py::arg("beta") = 0.);
py::class_(mod, "SolverVector")
.def("zero", &SolverVector::zero)
.def(
"getValues",
[](SolverVector & self) -> decltype(auto) {
return static_cast &>(self);
},
py::return_value_policy::reference_internal,
"Transform this into a vector, Is not copied.")
.def("isDistributed",
[](const SolverVector & self) { return self.isDistributed(); })
// had to use DUNder methods, otherwise compilation fails
.def("__iadd__", &SolverVector::operator+=,
py::return_value_policy::reference)
.def("__isub__", &SolverVector::operator-=,
py::return_value_policy::reference)
.def("__imul__", &SolverVector::operator*=,
py::return_value_policy::reference)
.def("dot", &SolverVector::dot)
.def("set", &SolverVector::set)
.def("copy", &SolverVector::copy)
.def("add", &SolverVector::add)
- .def("norm", &SolverVector::norm);
+ .def("norm", &SolverVector::norm)
+ .def("normFreeDOFs", &SolverVector::normFreeDOFs);
py::class_(mod, "TermToAssemble")
.def(py::init())
.def(py::self += Real())
.def_property_readonly("i", &TermsToAssemble::TermToAssemble::i)
.def_property_readonly("j", &TermsToAssemble::TermToAssemble::j);
py::class_(mod, "TermsToAssemble")
.def(py::init())
.def("getDOFIdM", &TermsToAssemble::getDOFIdM)
.def("getDOFIdN", &TermsToAssemble::getDOFIdN)
.def(
"__call__",
[](TermsToAssemble & self, UInt i, UInt j, Real val) {
auto & term = self(i, j);
term = val;
return term;
},
py::arg("i"), py::arg("j"), py::arg("val") = 0.,
py::return_value_policy::reference);
}
} // namespace akantu
diff --git a/src/fe_engine/shape_cohesive_inline_impl.hh b/src/fe_engine/shape_cohesive_inline_impl.hh
index cf735c74b..3181cadd5 100644
--- a/src/fe_engine/shape_cohesive_inline_impl.hh
+++ b/src/fe_engine/shape_cohesive_inline_impl.hh
@@ -1,610 +1,610 @@
/**
* @file shape_cohesive_inline_impl.hh
*
* @author Nicolas Richart
* @author Marco Vocialta
*
* @date creation: Fri Feb 03 2012
* @date last modification: Tue Sep 29 2020
*
* @brief ShapeCohesive inline implementation
*
*
* @section LICENSE
*
* Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_iterators.hh"
#include "shape_cohesive.hh"
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_SHAPE_COHESIVE_INLINE_IMPL_HH_
#define AKANTU_SHAPE_COHESIVE_INLINE_IMPL_HH_
namespace akantu {
/* -------------------------------------------------------------------------- */
inline ShapeLagrange<_ek_cohesive>::ShapeLagrange(const Mesh & mesh,
UInt spatial_dimension,
const ID & id)
: ShapeLagrangeBase(mesh, spatial_dimension, _ek_cohesive, id) {}
#define INIT_SHAPE_FUNCTIONS(type) \
setIntegrationPointsByType(integration_points, ghost_type); \
precomputeShapesOnIntegrationPoints(nodes, ghost_type); \
precomputeShapeDerivativesOnIntegrationPoints(nodes, ghost_type);
/* -------------------------------------------------------------------------- */
inline void ShapeLagrange<_ek_cohesive>::initShapeFunctions(
const Array & nodes, const Matrix & integration_points,
ElementType type, GhostType ghost_type) {
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template
void ShapeLagrange<_ek_cohesive>::computeShapeDerivativesOnIntegrationPoints(
const Array & nodes, const Matrix & integration_points,
Array & shape_derivatives, GhostType ghost_type,
const Array & filter_elements) const {
AKANTU_DEBUG_IN();
this->computeShapeDerivativesOnIntegrationPointsLowerDimension(
nodes, integration_points, shape_derivatives, ghost_type,
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void
ShapeLagrange<_ek_cohesive>::computeShapeDerivativesOnIntegrationPoints(
const Array & nodes, const Matrix & integration_points,
Array & shape_derivatives, ElementType type, GhostType ghost_type,
const Array & filter_elements) const {
#define AKANTU_COMPUTE_SHAPES(type) \
computeShapeDerivativesOnIntegrationPoints( \
nodes, integration_points, shape_derivatives, ghost_type, \
filter_elements);
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES);
#undef AKANTU_COMPUTE_SHAPES
}
/* -------------------------------------------------------------------------- */
template
void ShapeLagrange<_ek_cohesive>::precomputeShapesOnIntegrationPoints(
const Array & nodes, GhostType ghost_type) {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty::interpolation_type;
Matrix & natural_coords = integration_points(type, ghost_type);
UInt size_of_shapes = ElementClass::getShapeSize();
Array & shapes_tmp =
shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
this->computeShapesOnIntegrationPoints(nodes, natural_coords,
shapes_tmp, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template
void ShapeLagrange<_ek_cohesive>::precomputeShapeDerivativesOnIntegrationPoints(
const Array & nodes, GhostType ghost_type) {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty::interpolation_type;
Matrix & natural_coords = integration_points(type, ghost_type);
UInt size_of_shapesd = ElementClass::getShapeDerivativesSize();
UInt spatial_dimension = mesh.getSpatialDimension();
Array & shapes_derivatives_tmp =
shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
this->computeShapeDerivativesOnIntegrationPointsLowerDimension(
nodes, natural_coords, shapes_derivatives_tmp, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template
void ShapeLagrange<_ek_cohesive>::
computeShapeDerivativesOnIntegrationPointsLowerDimension(
const Array & nodes, const Matrix & integration_points,
Array