14#include <range/v3/range/conversion.hpp>
15#include <range/v3/view/transform.hpp>
27namespace SmallDeformation
29template <
typename ShapeFunction,
int DisplacementDim>
33 std::size_t
const n_variables,
35 std::vector<unsigned>
const& dofIndex_to_localIndex,
37 bool const is_axially_symmetric,
40 n_variables * ShapeFunction::NPOINTS * DisplacementDim,
41 dofIndex_to_localIndex),
42 _process_data(process_data),
43 _integration_method(integration_method),
46 DisplacementDim>(e, is_axially_symmetric,
47 _integration_method)),
52 unsigned const n_integration_points =
55 _ip_data.reserve(n_integration_points);
59 auto frac_id =
_process_data._map_materialID_to_fractureID[mat_id];
68 ranges::views::transform(
71 ranges::to<std::vector>;
75 for (
unsigned ip = 0; ip < n_integration_points; ip++)
77 x_position.setIntegrationPoint(ip);
82 ip_data.integration_weight =
84 sm.integralMeasure * sm.detJ;
85 ip_data.h_matrices.setZero(DisplacementDim,
86 ShapeFunction::NPOINTS * DisplacementDim);
93 ip_data.w.setZero(DisplacementDim);
94 ip_data.sigma.setZero(DisplacementDim);
97 ip_data.sigma_prev.resize(DisplacementDim);
98 ip_data.w_prev.resize(DisplacementDim);
100 ip_data.C.resize(DisplacementDim, DisplacementDim);
103 ip_data.aperture_prev = ip_data.aperture0;
109template <
typename ShapeFunction,
int DisplacementDim>
112 Eigen::VectorXd
const& local_u,
113 Eigen::VectorXd& local_b, Eigen::MatrixXd& local_J)
115 auto const N_DOF_PER_VAR = ShapeFunction::NPOINTS * DisplacementDim;
116 auto const n_fractures = _fracture_props.size();
117 auto const n_junctions = _junction_props.size();
118 auto const n_enrich_var = n_fractures + n_junctions;
132 using BlockVectorType =
133 typename Eigen::VectorXd::FixedSegmentReturnType<N_DOF_PER_VAR>::Type;
134 using BlockMatrixType =
135 Eigen::Block<Eigen::MatrixXd, N_DOF_PER_VAR, N_DOF_PER_VAR>;
137 std::vector<BlockVectorType> vec_local_b_g;
138 for (
unsigned i = 0; i < n_enrich_var; i++)
140 vec_local_b_g.push_back(
141 local_b.segment<N_DOF_PER_VAR>(N_DOF_PER_VAR * i));
143 std::vector<std::vector<BlockMatrixType>> vec_local_J_gg(n_enrich_var);
144 for (
unsigned i = 0; i < n_enrich_var; i++)
146 for (
unsigned j = 0; j < n_enrich_var; j++)
148 auto sub_gg = local_J.block<N_DOF_PER_VAR, N_DOF_PER_VAR>(
149 N_DOF_PER_VAR * i, N_DOF_PER_VAR * j);
150 vec_local_J_gg[i].push_back(sub_gg);
154 std::vector<Eigen::VectorXd> vec_nodal_g;
155 for (
unsigned i = 0; i < n_enrich_var; i++)
157 auto sub =
const_cast<Eigen::VectorXd&
>(local_u).segment<N_DOF_PER_VAR>(
159 vec_nodal_g.push_back(sub);
167 int const index_normal = DisplacementDim - 1;
168 auto const& R = _fracture_property->R;
170 unsigned const n_integration_points =
171 _integration_method.getNumberOfPoints();
176 for (
unsigned ip = 0; ip < n_integration_points; ip++)
180 auto& ip_data = _ip_data[ip];
181 auto const& integration_weight = ip_data.integration_weight;
182 auto const& H = ip_data.h_matrices;
183 auto& mat = ip_data.fracture_material;
184 auto& sigma = ip_data.sigma;
185 auto const& sigma_prev = ip_data.sigma_prev;
187 auto const& w_prev = ip_data.w_prev;
189 auto& state = *ip_data.material_state_variables;
190 auto const& N = _secondary_data.N[ip];
194 _fracture_property->fracture_id, _fracture_props, _junction_props,
195 _fracID_to_local, ip_physical_coords));
199 Eigen::VectorXd nodal_gap(N_DOF_PER_VAR);
201 for (
unsigned i = 0; i < n_enrich_var; i++)
203 nodal_gap += levelsets[i] * vec_nodal_g[i];
207 w.noalias() = R * H * nodal_gap;
210 ip_data.aperture = ip_data.aperture0 + w[index_normal];
213 mat.computeConstitutiveRelation(
214 t, x_position, ip_data.aperture0,
215 Eigen::Matrix<double, DisplacementDim, 1>::Zero(),
219 w_prev, w, sigma_prev, sigma, C, state);
222 for (
unsigned i = 0; i < n_enrich_var; i++)
224 vec_local_b_g[i].noalias() -= levelsets[i] * H.transpose() *
225 R.transpose() * sigma *
230 for (
unsigned i = 0; i < n_enrich_var; i++)
232 for (
unsigned j = 0; j < n_enrich_var; j++)
235 vec_local_J_gg[i][j].noalias() +=
236 (levelsets[i] * H.transpose() * R.transpose()) * C *
237 (levelsets[j] * R * H) * integration_weight;
243template <
typename ShapeFunction,
int DisplacementDim>
246 Eigen::VectorXd
const& local_u)
248 auto const N_DOF_PER_VAR = ShapeFunction::NPOINTS * DisplacementDim;
249 auto const n_fractures = _fracture_props.size();
250 auto const n_junctions = _junction_props.size();
251 auto const n_enrich_var = n_fractures + n_junctions;
253 auto const& R = _fracture_property->R;
257 int const index_normal = DisplacementDim - 1;
259 unsigned const n_integration_points =
260 _integration_method.getNumberOfPoints();
265 std::vector<Eigen::VectorXd> vec_nodal_g;
266 for (
unsigned i = 0; i < n_enrich_var; i++)
268 auto sub =
const_cast<Eigen::VectorXd&
>(local_u).segment<N_DOF_PER_VAR>(
270 vec_nodal_g.push_back(sub);
273 for (
unsigned ip = 0; ip < n_integration_points; ip++)
277 auto& ip_data = _ip_data[ip];
278 auto const& H = ip_data.h_matrices;
279 auto& mat = ip_data.fracture_material;
280 auto& sigma = ip_data.sigma;
281 auto const& sigma_prev = ip_data.sigma_prev;
283 auto const& w_prev = ip_data.w_prev;
285 auto& state = *ip_data.material_state_variables;
286 auto& b_m = ip_data.aperture;
287 auto const& N = _secondary_data.N[ip];
291 _fracture_property->fracture_id, _fracture_props, _junction_props,
292 _fracID_to_local, ip_physical_coords));
296 Eigen::VectorXd nodal_gap(N_DOF_PER_VAR);
298 for (
unsigned i = 0; i < n_enrich_var; i++)
300 nodal_gap += levelsets[i] * vec_nodal_g[i];
304 w.noalias() = R * H * nodal_gap;
307 b_m = ip_data.aperture0 + w[index_normal];
311 "Element {:d}, gp {:d}: Fracture aperture is {:g}, but it must "
313 _element.getID(), ip, b_m);
317 mat.computeConstitutiveRelation(
318 t, x_position, ip_data.aperture0,
319 Eigen::Matrix<double, DisplacementDim, 1>::Zero(),
323 w_prev, w, sigma_prev, sigma, C, state);
328 HMatricesType::ForceVectorType::Zero(DisplacementDim);
330 HMatricesType::ForceVectorType::Zero(DisplacementDim);
332 for (
unsigned ip = 0; ip < n_integration_points; ip++)
334 auto const& ip_data = _ip_data[ip];
335 ele_b += ip_data.aperture;
337 ele_sigma += ip_data.sigma;
339 ele_b /= n_integration_points;
340 ele_w /= n_integration_points;
341 ele_sigma /= n_integration_points;
342 (*_process_data._mesh_prop_b)[_element.getID()] = ele_b;
343 (*_process_data._mesh_prop_w_n)[_element.getID()] = ele_w[index_normal];
344 (*_process_data._mesh_prop_w_s)[_element.getID()] = ele_w[0];
345 (*_process_data._mesh_prop_fracture_stress_normal)[_element.getID()] =
346 ele_sigma[index_normal];
347 (*_process_data._mesh_prop_fracture_stress_shear)[_element.getID()] =
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
virtual std::size_t getID() const final
Returns the ID of the element.
MathLib::WeightedPoint const & getWeightedPoint(unsigned const igp) const
unsigned getNumberOfPoints() const
void setElementID(std::size_t element_id)
void setIntegrationPoint(unsigned integration_point)
VectorType< DisplacementDim > ForceVectorType
std::vector< double > duGlobalEnrichments(std::size_t this_frac_id, 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)
Eigen::Vector3d computePhysicalCoordinates(MeshLib::Element const &e, Eigen::MatrixBase< Derived > const &shape)
void computeHMatrix(N_Type const &N, HMatrixType &H)
Fills a H-matrix based on given shape function.
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N
ParameterLib::Parameter< double > const & aperture0
Initial aperture.