Extending the Library
This page shows how to create a custom micromechanical model in Python and C++.
Note
In C++, make sure to add the following include directories of the micromechanical library and the Eigen library to the include directories of your compiler:
Define the micromechanical model
To create a custom micromechanical model, first create a class that inherits from the MicromechanicalBase class or one of its subclasses. Check ChangHicherAbstractModel for an example of the Chang-Hicher model. The following code only shows the class inheritance:
from micromechanical.python.micromechanical.core.average import LoveWeberAveraging, BestFitAveraging
from micromechanical.python.micromechanical.core.localize import KinematicHypothesisLocalization, StaticHypothesisLocalization
from micromechanical.python.micromechanical.core.mixedload import MixedLoadControl
class ChangHicherAbstractModel(
MixedLoadControl,
LoveWeberAveraging,
BestFitAveraging,
StaticHypothesisLocalization,
KinematicHypothesisLocalization,
):
...
#include <micromechanical/core/average.hpp>
#include <micromechanical/core/localize.hpp>
#include <micromechanical/core/mixedload.hpp>
using namespace micromechanical::core;
template <typename T = double>
struct ChangHicher : public MixedLoadControl<T>,
public LoveWeberAveraging<T>,
public BestFitAveraging<T>,
public StaticHypothesisLocalization<T>,
public KinematicHypothesisLocalization<T> {};
Define the contact law
After that, define the contact law for the micromechanical model. To do so, create a class that inherits from the NonlinearElasticContactLaw class to define a nonlinear elastic contact law, or ElastoplasticContactLaw class to define an elastoplastic contact law. For example, the following code defines an elastic contact law:
import numpy as np
from micromechanical.python.micromechanical.contacts.register import contact_registry
from micromechanical.python.micromechanical.core.contactlaw import NonlinearElasticContactLaw
from micromechanical.python.micromechanical.core.stiffness import ConstantStiffness
from micromechanical.python.micromechanical.core.statevariable import StateVariable
from micromechanical.numba import numba
from micromechanical.registry import register
@register("Elastic", saveto=contact_registry)
@numba.experimental.jitclass
class ElasticContactLaw(NonlinearElasticContactLaw, ConstantStiffness):
def stiffness(self, idx: int, ddisp: np.ndarray, sv: StateVariable) -> np.ndarray:
return sv.elasticStiffnessMatrix()
#include <micromechanical/core/contactlaw.hpp>
#include <micromechanical/core/stiffness.hpp>
#include <micromechanical/core/statevariable.hpp>
using namespace micromechanical::core;
template <typename T = double>
class ElasticContactLaw : public NonlinearElasticContactLaw<T>, public ConstantStiffness<T> {
Eigen::Matrix<T, 3, 3> stiffness(int idx, const Eigen::Matrix<T, 3, 1>& ddisp,
StateVariable<T>& sv) const override {
return sv.elasticStiffnessMatrix();
}
}
Link the contact law to the micromechanical model
Then, define the contact law for the micromechanical model. To do so, create a class that inherits from the class you defined above. Then, register the class with register decorator. For example, the following code defines the Chang-Hicher model with an elastic contact law:
from micromechanical.python.micromechanical.changhicher import ChangHicherAbstractModel
from micromechanical.python.micromechanical.contacts.elastic import ElasticContactLaw
from micromechanical.python.micromechanical.registry import micromechanical_registry
from micromechanical.numba import numba
from micromechanical.registry import register
@register("ChangHicher-Elastic", saveto=micromechanical_registry)
@numba.experimental.jitclass
class ChangHicherElasticModel(ChangHicherAbstractModel):
"""Chang-Hicher model with the elastic contact law."""
contact: ElasticContactLaw
def createContactLaw(self, props: dict[str, float] = None):
return ElasticContactLaw(props)
Note
In C++ backend, you don't have to create a new class to link the contact law to the micromechanical model. You can simply pass a pointer to the contact law to the constructor of the micromechanical model. For example:
Instantiate the micromechanical model
After registering the class, you can now pass the instance of the class or the custom model name to the Model class to create a micromechanical model instance.
Or pass an instance of the class you defined above to the Model class.