6#include <range/v3/view/join.hpp>
32template <
int DisplacementDim>
36 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
37 std::vector<std::unique_ptr<ParameterLib::ParameterBase>>
const& parameters,
38 unsigned const integration_order,
39 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>&&
43 bool const use_monolithic_scheme)
44 :
Process(std::move(
name), mesh, std::move(jacobian_assembler), parameters,
45 integration_order, std::move(process_variables),
46 std::move(secondary_variables), use_monolithic_scheme),
53 "The numericial Jacobian assembler is not supported for the "
54 "LIE HydroMechanics process.");
57 INFO(
"[LIE/HM] looking for fracture elements in the given mesh");
58 std::vector<std::pair<std::size_t, std::vector<int>>>
59 vec_branch_nodeID_matIDs;
60 std::vector<std::pair<std::size_t, std::vector<int>>>
61 vec_junction_nodeID_matIDs;
66 vec_junction_nodeID_matIDs);
72 "The number of the given fracture properties ({:d}) are not "
73 "consistent with the number of fracture groups in a mesh ({:d}).",
81 _process_data.map_materialID_to_fractureID.resize(*max_frac_mat_id + 1);
95 _process_data.vec_ele_connected_fractureIDs[e->getID()].push_back(
101 for (
auto& fracture_prop :
_process_data.fracture_properties)
111 for (
auto const& [vec_branch_nodeID, matID] : vec_branch_nodeID_matIDs)
113 auto const master_matId = matID[0];
114 auto const slave_matId = matID[1];
123 *mesh.
getNode(vec_branch_nodeID), master_frac, slave_frac));
126 *mesh.
getNode(vec_branch_nodeID), master_frac, slave_frac));
130 transform(cbegin(vec_junction_nodeID_matIDs),
131 cend(vec_junction_nodeID_matIDs),
133 [&](
auto& vec_junction_nodeID_matID)
136 _mesh.getNode(vec_junction_nodeID_matID.first));
139 for (std::size_t i = 0; i < vec_junction_nodeID_matIDs.size(); i++)
141 auto const& material_ids = vec_junction_nodeID_matIDs[i].second;
142 assert(material_ids.size() == 2);
143 std::array<int, 2> fracture_ids{
144 {
_process_data.map_materialID_to_fractureID[material_ids[0]],
145 _process_data.map_materialID_to_fractureID[material_ids[1]]}};
148 i, *mesh.
getNode(vec_junction_nodeID_matIDs[i].first),
155 for (
unsigned i = 0; i < vec_junction_nodeID_matIDs.size(); i++)
157 auto node = mesh.
getNode(vec_junction_nodeID_matIDs[i].first);
161 _process_data.vec_ele_connected_junctionIDs[id].push_back(i);
167 vec_junction_nodeID_matIDs.size());
168 for (
unsigned i = 0; i < vec_junction_nodeID_matIDs.size(); i++)
170 auto node = mesh.
getNode(vec_junction_nodeID_matIDs[i].first);
188 std::make_unique<MeshLib::ElementStatus>(&mesh);
197 "Could not get minimum/maximum ranges values for the "
198 "MaterialIDs property in the mesh '{:s}'.",
202 std::vector<int> vec_p_inactive_matIDs;
203 for (
int matID = range->first; matID <= range->second; matID++)
209 vec_p_inactive_matIDs.push_back(matID);
213 std::make_unique<MeshLib::ElementStatus>(&mesh,
214 vec_p_inactive_matIDs);
216 const int monolithic_process_id = 0;
226template <
int DisplacementDim>
234 std::make_unique<MeshLib::MeshSubset>(
_mesh,
_mesh.getNodes());
242 std::make_unique<MeshLib::MeshSubset>(
_mesh,
_mesh.getNodes());
247 std::make_unique<MeshLib::MeshSubset const>(
256 std::vector<MeshLib::MeshSubset> all_mesh_subsets;
258 std::generate_n(std::back_inserter(all_mesh_subsets), DisplacementDim,
262 std::generate_n(std::back_inserter(all_mesh_subsets),
264 [&]() {
return *ms; });
266 std::generate_n(std::back_inserter(all_mesh_subsets),
272 std::vector<int> vec_n_components;
273 vec_n_components.push_back(1);
274 vec_n_components.insert(
275 vec_n_components.end(),
280 ranges::views::join |
281 ranges::to<std::vector>();
282 std::vector<std::vector<MeshLib::Element*>
const*> vec_var_elements;
285 vec_var_elements.push_back(&
_mesh.getElements());
291 vec_var_elements.push_back(&all_fracture_matrix_elements);
303 INFO(
"[LIE/HM] creating a DoF table");
305 std::make_unique<NumLib::LocalToGlobalIndexMap>(
306 std::move(all_mesh_subsets),
314template <
int DisplacementDim>
318 Eigen::Vector3d
const pt(getCenterOfGravity(e).asEigenVector3d());
319 std::vector<FractureProperty*> e_fracture_props;
320 std::unordered_map<int, int> e_fracID_to_local;
324 e_fracture_props.push_back(&
_process_data.fracture_properties[fid]);
325 e_fracID_to_local.insert({fid, tmpi++});
327 std::vector<JunctionProperty*> e_junction_props;
328 std::unordered_map<int, int> e_juncID_to_local;
332 e_junction_props.push_back(&
_process_data.junction_properties[fid]);
333 e_juncID_to_local.insert({fid, tmpi++});
336 e_fracture_props, e_junction_props, e_fracID_to_local, pt));
338 auto update_levelset_property = [&](
unsigned const i,
int const id,
339 unsigned const levelset_idx_offset,
340 unsigned const name_offset)
344 "levelset" + std::to_string(
id + 1 + name_offset),
347 (*levelset_property)[e.
getID()] = levelsets[i + levelset_idx_offset];
350 for (
unsigned i = 0; i < e_fracture_props.size(); i++)
352 update_levelset_property(i, e_fracture_props[i]->fracture_id, 0, 0);
354 for (
unsigned i = 0; i < e_junction_props.size(); i++)
356 update_levelset_property(i, e_junction_props[i]->junction_id,
357 e_fracture_props.size(),
362template <
int DisplacementDim>
366 unsigned const integration_order)
369 INFO(
"[LIE/HM] creating local assemblers");
378 auto add_secondary_variable = [&](std::string
const&
name,
379 int const num_components,
380 auto get_ip_values_function)
386 std::move(get_ip_values_function)));
389 add_secondary_variable(
"sigma",
391 DisplacementDim>::RowsAtCompileTime,
394 add_secondary_variable(
"epsilon",
396 DisplacementDim>::RowsAtCompileTime,
399 add_secondary_variable(
"velocity", DisplacementDim,
402 add_secondary_variable(
"fracture_velocity", DisplacementDim,
405 add_secondary_variable(
"fracture_stress", DisplacementDim,
408 add_secondary_variable(
"fracture_aperture", 1,
411 add_secondary_variable(
412 "fracture_permeability", 1,
419 DisplacementDim>::RowsAtCompileTime);
427 if (e->getDimension() < DisplacementDim)
455 auto const& mesh_prop_matid = *
_process_data.mesh_prop_materialIDs;
456 for (
auto const& fracture_prop :
_process_data.fracture_properties)
460 if (e->getDimension() == DisplacementDim)
464 if (mesh_prop_matid[e->getID()] != fracture_prop.mat_id)
470 (*mesh_prop_b)[e->getID()] =
471 fracture_prop.aperture0
472 .getNodalValuesOnElement(*e, 0)
478 const_cast<MeshLib::Mesh&
>(mesh),
"fracture_permeability_avg",
483 auto mesh_prop_fracture_shear_failure =
489 mesh_prop_fracture_shear_failure;
520template <
int DisplacementDim>
522 std::vector<GlobalVector*>
const& x,
523 std::vector<GlobalVector*>
const& x_prev,
const double t,
double const dt,
524 int const process_id)
528 DBUG(
"PostTimestep HydroMechanicsProcess.");
533 x_prev, t, dt, process_id);
536 DBUG(
"Compute the secondary variables for HydroMechanicsProcess.");
544 int g_variable_id = 0;
546 const int monolithic_process_id = 0;
550 { return pv.getName() ==
"displacement_jump1"; });
554 "Didn't find expected 'displacement_jump1' process variable.");
556 g_variable_id =
static_cast<int>(std::distance(pvs.begin(), it));
561 const int monolithic_process_id = 0;
567 for (
int component_id = 0; component_id < num_comp; ++component_id)
569 auto const& mesh_subset =
570 dof_table.getMeshSubset(g_variable_id, component_id);
574 auto const global_index =
575 dof_table.getGlobalIndex(l, g_variable_id, component_id);
576 auto const node_id = l.item_id;
577 mesh_prop_g[node_id * num_comp + component_id] =
578 (*x[process_id])[global_index];
583template <
int DisplacementDim>
589template <
int DisplacementDim>
591 const double t,
double const dt, std::vector<GlobalVector*>
const& x,
592 std::vector<GlobalVector*>
const& x_prev,
int const process_id,
595 DBUG(
"Assemble HydroMechanicsProcess.");
597 std::vector<NumLib::LocalToGlobalIndexMap const*> dof_table = {
602 dof_table, t, dt, x, x_prev, process_id, &M, &K, &b);
605template <
int DisplacementDim>
608 const double t,
double const dt, std::vector<GlobalVector*>
const& x,
609 std::vector<GlobalVector*>
const& x_prev,
int const process_id,
612 DBUG(
"AssembleWithJacobian HydroMechanicsProcess.");
615 std::vector<NumLib::LocalToGlobalIndexMap const*> dof_table = {
620 process_id, &b, &Jac);
622 auto copyRhs = [&](
int const variable_id,
auto& output_vector)
624 transformVariableFromGlobalVector(b, variable_id,
626 output_vector, std::negate<double>());
633template <
int DisplacementDim>
635 std::vector<GlobalVector*>
const& x,
double const t,
double const dt,
636 int const process_id)
638 DBUG(
"PreTimestep HydroMechanicsProcess.");
MathLib::EigenMatrix GlobalMatrix
MathLib::EigenVector GlobalVector
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
std::size_t getID() const
Returns the ID of the element.
bool isAxiallySymmetric() const
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
const Node * getNode(std::size_t idx) const
Get the node with the given index.
Properties & getProperties()
const std::string getName() const
Get name of the mesh.
std::size_t getNumberOfNodes() const
Get the number of nodes.
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
std::size_t getNumberOfElements() const
Get the number of elements.
PropertyVector< T > const * getPropertyVector(std::string_view name) const
virtual std::vector< double > const & getIntPtFracturePermeability(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
virtual std::vector< double > const & getIntPtDarcyVelocity(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
virtual std::vector< double > const & getIntPtFractureAperture(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
virtual std::vector< double > const & getIntPtFractureStress(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
virtual std::vector< double > const & getIntPtEpsilon(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
virtual std::vector< double > const & getIntPtFractureVelocity(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
virtual std::vector< double > const & getIntPtSigma(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const =0
HydroMechanicsProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const ¶meters, unsigned const integration_order, std::vector< std::vector< std::reference_wrapper< ProcessVariable > > > &&process_variables, HydroMechanicsProcessData< DisplacementDim > &&process_data, SecondaryVariableCollection &&secondary_variables, bool const use_monolithic_scheme)
void postTimestepConcreteProcess(std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, double const t, double const dt, int const process_id) override
void initializeConcreteProcess(NumLib::LocalToGlobalIndexMap const &dof_table, MeshLib::Mesh const &mesh, unsigned const integration_order) override
Process specific initialization called by initialize().
std::vector< std::unique_ptr< MeshLib::MeshSubset const > > _mesh_subset_fracture_nodes
std::vector< std::vector< MeshLib::Node * > > _vec_fracture_nodes
std::vector< MeshLib::Element * > _vec_matrix_elements
std::vector< int > _vec_fracture_mat_IDs
std::vector< std::vector< MeshLib::Element * > > _vec_junction_fracture_matrix_elements
void preTimestepConcreteProcess(std::vector< GlobalVector * > const &x, double const t, double const dt, int const process_id) override
std::unique_ptr< MeshLib::MeshSubset const > _mesh_subset_matrix_nodes
std::vector< MeshLib::Node * > _vec_junction_nodes
void assembleConcreteProcess(const double t, double const dt, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id, GlobalMatrix &M, GlobalMatrix &K, GlobalVector &b) override
void constructDofTable() override
std::unique_ptr< MeshLib::MeshSubset const > _mesh_subset_junction_nodes
void updateElementLevelSets(MeshLib::Element const &e, MeshLib::Mesh &mesh)
std::unique_ptr< MeshLib::MeshSubset const > _mesh_subset_nodes_p
std::vector< std::vector< MeshLib::Element * > > _vec_fracture_elements
HydroMechanicsProcessData< DisplacementDim > _process_data
std::vector< MeshLib::Node * > _mesh_nodes_p
void assembleWithJacobianConcreteProcess(const double t, double const dt, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id, GlobalVector &b, GlobalMatrix &Jac) override
bool isLinear() const override
std::vector< std::unique_ptr< LocalAssemblerInterface > > _local_assemblers
std::vector< std::vector< MeshLib::Element * > > _vec_fracture_matrix_elements
virtual void postTimestep(std::size_t const mesh_item_id, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, double const t, double const dt, int const process_id)
virtual void preTimestep(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table, GlobalVector const &x, double const t, double const delta_t)
ParameterLib::Parameter< double > const & getInitialCondition() const
std::string const & getName() const
int getNumberOfGlobalComponents() const
Returns the number of components of the process variable.
std::vector< NumLib::LocalToGlobalIndexMap const * > getDOFTables(int const number_of_processes) const
Process(std::string name_, MeshLib::Mesh &mesh, std::unique_ptr< AbstractJacobianAssembler > &&jacobian_assembler, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const ¶meters, unsigned const integration_order, std::vector< std::vector< std::reference_wrapper< ProcessVariable > > > &&process_variables, SecondaryVariableCollection &&secondary_variables, const bool use_monolithic_scheme=true)
std::unique_ptr< MeshLib::MeshSubset const > _mesh_subset_all_nodes
std::vector< std::size_t > const & getActiveElementIDs() const
virtual NumLib::LocalToGlobalIndexMap const & getDOFTable(const int) const
SecondaryVariableCollection _secondary_variables
VectorMatrixAssembler _global_assembler
std::unique_ptr< NumLib::LocalToGlobalIndexMap > _local_to_global_index_map
std::unique_ptr< ProcessLib::AbstractJacobianAssembler > _jacobian_assembler
std::vector< std::vector< std::reference_wrapper< ProcessVariable > > > const & getProcessVariables() const
NumLib::Extrapolator & getExtrapolator() const
Handles configuration of several secondary variables from the project file.
void assemble(std::size_t const mesh_item_id, LocalAssemblerInterface &local_assembler, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, double const t, double const dt, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id, GlobalMatrix *M, GlobalMatrix *K, GlobalVector *b)
void assembleWithJacobian(std::size_t const mesh_item_id, LocalAssemblerInterface &local_assembler, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, const double t, double const dt, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id, GlobalVector *b, GlobalMatrix *Jac)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
void setLocalAccessibleVector(PETScVector const &x)
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
auto meshLocations(Mesh const &mesh, MeshItemType const item_type)
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)
std::vector< Node * > getBaseNodes(std::vector< Element * > const &elements)
@ BY_COMPONENT
Ordering data by component type.
void createLocalAssemblers(std::vector< MeshLib::Element * > const &mesh_elements, NumLib::LocalToGlobalIndexMap const &dof_table, std::vector< std::unique_ptr< LocalAssemblerInterface > > &local_assemblers, NumLib::IntegrationOrder const integration_order, ExtraCtorArgs &&... extra_ctor_args)
void setFractureProperty(int const dim, MeshLib::Element const &e, FractureProperty &frac_prop)
void getFractureMatrixDataInMesh(MeshLib::Mesh const &mesh, std::vector< MeshLib::Element * > &vec_matrix_elements, std::vector< int > &vec_fracture_mat_IDs, std::vector< std::vector< MeshLib::Element * > > &vec_fracture_elements, std::vector< std::vector< MeshLib::Element * > > &vec_fracture_matrix_elements, std::vector< std::vector< MeshLib::Node * > > &vec_fracture_nodes, std::vector< std::pair< std::size_t, std::vector< int > > > &vec_branch_nodeID_matIDs, std::vector< std::pair< std::size_t, std::vector< int > > > &vec_junction_nodeID_matIDs)
std::vector< double > uGlobalEnrichments(std::vector< FractureProperty * > const &frac_props, std::vector< JunctionProperty * > const &junction_props, std::unordered_map< int, int > const &fracID_to_local, Eigen::Vector3d const &x)
BranchProperty createBranchProperty(MeshLib::Node const &branchNode, FractureProperty const &master_frac, FractureProperty const &slave_frac)
SecondaryVariableFunctions makeExtrapolator(const unsigned num_components, NumLib::Extrapolator &extrapolator, LocalAssemblerCollection const &local_assemblers, typename NumLib::ExtrapolatableLocalAssemblerCollection< LocalAssemblerCollection >::IntegrationPointValuesMethod integration_point_values_method)
static void executeSelectedMemberOnDereferenced(Method method, Container const &container, std::vector< std::size_t > const &active_container_ids, Args &&... args)
static void executeSelectedMemberDereferenced(Object &object, Method method, Container const &container, std::vector< std::size_t > const &active_container_ids, Args &&... args)
static void executeMemberDereferenced(Object &object, Method method, Container const &container, Args &&... args)