Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "GeneralUserObject.h" 13 : #include "CrackFrontPointsProvider.h" 14 : #include "BoundaryRestrictable.h" 15 : #include <set> 16 : #include "ADRankTwoTensorForward.h" 17 : 18 : class AuxiliarySystem; 19 : 20 : // libMesh forward declarations 21 : namespace libMesh 22 : { 23 : class QBase; 24 : } 25 : 26 : // fixme lynn this needs to be removed from the globalname space in a seperate commit 27 : void addCrackFrontDefinitionParams(InputParameters & params); 28 : /** 29 : * Class used in fracture integrals to define geometric characteristics of the crack front 30 : */ 31 : class CrackFrontDefinition : public GeneralUserObject, public BoundaryRestrictable 32 : { 33 : public: 34 : static InputParameters validParams(); 35 : 36 : CrackFrontDefinition(const InputParameters & parameters); 37 : virtual ~CrackFrontDefinition(); 38 : 39 : virtual void initialSetup() override; 40 : virtual void initialize() override; 41 : virtual void finalize() override; 42 : virtual void execute() override; 43 : 44 : /** 45 : * Change the number of crack front nodes. As the crack grows, the number of crack fronts nodes 46 : * may keep increasing in many cases. 47 : */ 48 : void updateNumberOfCrackFrontPoints(const std::size_t num_points); 49 : 50 : /** 51 : * Get the node pointer for a specified node on the crack front 52 : * @param node_index Index of the node 53 : * @return Pointer to node 54 : */ 55 : const Node * getCrackFrontNodePtr(const std::size_t node_index) const; 56 : 57 : /** 58 : * Get a Point object for a specified point on the crack front 59 : * @param point_index Index of the point 60 : * @return Point object 61 : */ 62 : const Point * getCrackFrontPoint(const std::size_t point_index) const; 63 : 64 : /** 65 : * Get the vector tangent to the crack front at a specified position 66 : * @param point_index Index of the point 67 : * @return tangent vector 68 : */ 69 : const RealVectorValue & getCrackFrontTangent(const std::size_t point_index) const; 70 : 71 : /** 72 : * Get the length of the line segment on the crack front ahead of the specified position 73 : * @param point_index Index of the point 74 : * @return Line segment length 75 : */ 76 : Real getCrackFrontForwardSegmentLength(const std::size_t point_index) const; 77 : 78 : /** 79 : * Get the length of the line segment on the crack front behind the specified position 80 : * @param point_index Index of the point 81 : * @return Line segment length 82 : */ 83 : Real getCrackFrontBackwardSegmentLength(const std::size_t point_index) const; 84 : 85 : /** 86 : * Get the unit vector of the crack extension direction at the specified position 87 : * @param point_index Index of the point 88 : * @return Crack extension direction vector 89 : */ 90 : const RealVectorValue & getCrackDirection(const std::size_t point_index) const; 91 : 92 : /** 93 : * Get the distance along the crack front from the beginning of the crack to the 94 : * specified position 95 : * @param point_index Index of the point 96 : * @return Distance along crack 97 : */ 98 : Real getDistanceAlongFront(const std::size_t point_index) const; 99 : 100 : /** 101 : * Whether the distance along the crack front is available as an angle 102 : * @return true if it is available as an angle 103 : */ 104 : bool hasAngleAlongFront() const; 105 : 106 : /** 107 : * Get the angle along the crack front from the beginning of the crack to the 108 : * specified position 109 : * @param point_index Index of the point 110 : * @return Angle along crack 111 : */ 112 : Real getAngleAlongFront(const std::size_t point_index) const; 113 : 114 : /** 115 : * Get the number of points defining the crack front as a set of line segments 116 : * @return Number of points 117 : */ 118 : std::size_t getNumCrackFrontPoints() const; 119 : 120 : /** 121 : * Whether the fracture computations are treated as 2D for the model 122 : * @return true if treated as 2D 123 : */ 124 1223239 : bool treatAs2D() const { return _treat_as_2d; } 125 : 126 : /** 127 : * Is the crack defined by a mesh cutter object 128 : * @return true if using a mesh cutter 129 : */ 130 1047 : bool usingMeshCutter() const { return _use_mesh_cutter; } 131 : 132 : /** 133 : * Rotate a vector in the global coordinate coordinate system to the crack 134 : * front local coordinate system at a specified point on the crack. 135 : * @param vector Vector in global coordinates 136 : * @param point_index Index of the point 137 : * @return Vector in crack local coordinates 138 : */ 139 : RealVectorValue rotateToCrackFrontCoords(const RealVectorValue vector, 140 : const std::size_t point_index) const; 141 : /** 142 : * Rotate a RankTwoTensor in the global coordinate coordinate system to the crack 143 : * front local coordinate system at a specified point on the crack. 144 : * @param tensor Tensor in global coordinates 145 : * @param point_index Index of the point 146 : * @return Tensor in crack local coordinates 147 : */ 148 : RankTwoTensor rotateToCrackFrontCoords(const RankTwoTensor tensor, 149 : const std::size_t point_index) const; 150 : 151 : /** 152 : * Rotate a vector from crack front cartesian coordinate to global cartesian coordinate 153 : * @param vector Vector in crack local coordinates 154 : * @param point_index Index of the point 155 : * @return Vector in global coordinates 156 : */ 157 : RealVectorValue rotateFromCrackFrontCoordsToGlobal(const RealVectorValue vector, 158 : const std::size_t point_index) const; 159 : 160 : /** 161 : * Calculate r and theta of a point in the crack front polar coordinates for a given 162 : * crack point index. 163 : * @param qp The Point for which coordinates are evaluated 164 : * @param point_index the crack front point index 165 : * @param r Value of the radial coordinate computed in this function 166 : * @param theta Value of the theta coordinate computed in this function 167 : */ 168 : void calculateRThetaToCrackFront(const Point qp, 169 : const std::size_t point_index, 170 : Real & r, 171 : Real & theta) const; 172 : 173 : /** 174 : * Calculate r and theta of a point in the crack front polar coordinate relative to the 175 : * closest crack front point. This function loops over all crack front points 176 : * to find the one closest to the specified point 177 : * @param qp The Point for which coordinates are evaluated 178 : * @param r Value of the radial coordinate computed in this function 179 : * @param theta Value of the theta coordinate computed in this function 180 : * @return Index of the closest crack front point 181 : */ 182 : std::size_t calculateRThetaToCrackFront(const Point qp, Real & r, Real & theta) const; 183 : 184 : /** 185 : * Determine whether a given node is on one of the boundaries that intersects an end 186 : * of the crack front 187 : * @param node Pointer to node 188 : * @return true if the node is on an intersecting boundary 189 : */ 190 : bool isNodeOnIntersectingBoundary(const Node * const node) const; 191 : 192 : /** 193 : * Determine whether a given crack front point is on one of the boundaries that 194 : * intersects an end of the crack front 195 : * @param point_index the crack front point index 196 : * @return true if the point is on an intersecting boundary 197 : */ 198 : bool isPointWithIndexOnIntersectingBoundary(const std::size_t point_index) const; 199 : 200 : /** 201 : * Get the strain in the direction tangent to the crack front at a given point 202 : * @param node_index the crack front node index 203 : * @return Tangential strain 204 : */ 205 : Real getCrackFrontTangentialStrain(const std::size_t node_index) const; 206 : 207 : /** 208 : * Determine whether the crack front was defined using nodes 209 : * @return true if it was defined using nodes 210 : */ 211 : bool hasCrackFrontNodes() const 212 : { 213 72 : return _geom_definition_method == CRACK_GEOM_DEFINITION::CRACK_FRONT_NODES; 214 : } 215 : 216 : /** 217 : * Determine whether a node is contained within a specified volume integral element ring 218 : * for a given node on the crack front 219 : * @param ring_index Index of the ring 220 : * @param connected_node_id ID of the node 221 : * @param node_index Index of the crack front node 222 : * @return true if the node is in the ring 223 : */ 224 : bool isNodeInRing(const std::size_t ring_index, 225 : const dof_id_type connected_node_id, 226 : const std::size_t node_index) const; 227 : 228 : /** 229 : * Compute the q function for the case where it is defined geometrically 230 : * @param crack_front_point_index Index of the point on the crack front 231 : * @param ring_index Index of the volume integral ring 232 : * @param current_node Node at which q is evaluated 233 : * @return q 234 : */ 235 : Real DomainIntegralQFunction(std::size_t crack_front_point_index, 236 : std::size_t ring_index, 237 : const Node * const current_node) const; 238 : 239 : /** 240 : * Compute the q function for the case where it is defined through element connectivity 241 : * @param crack_front_point_index Index of the point on the crack front 242 : * @param ring_index Index of the volume integral ring 243 : * @param current_node Node at which q is evaluated 244 : * @return q 245 : */ 246 : Real DomainIntegralTopologicalQFunction(std::size_t crack_front_point_index, 247 : std::size_t ring_index, 248 : const Node * const current_node) const; 249 : 250 : /** 251 : Set the value of _is_cutter_modified 252 : */ 253 : void isCutterModified(const bool is_cutter_modified); 254 : 255 : protected: 256 : /// Enum used to define the method for computing the crack extension direction 257 : const enum class DIRECTION_METHOD { 258 : CRACK_DIRECTION_VECTOR, 259 : CRACK_MOUTH, 260 : CURVED_CRACK_FRONT 261 : } _direction_method; 262 : 263 : /// Enum used to define the method for computing the crack extension direction 264 : /// at the ends of the crack 265 : const enum class END_DIRECTION_METHOD { 266 : NO_SPECIAL_TREATMENT, 267 : END_CRACK_DIRECTION_VECTOR, 268 : END_CRACK_TANGENT_VECTOR 269 : } _end_direction_method; 270 : 271 : /// Enum used to define the type of the nodes on the crack front (end or middle) 272 : enum CRACK_NODE_TYPE 273 : { 274 : MIDDLE_NODE, 275 : END_1_NODE, 276 : END_2_NODE 277 : }; 278 : 279 : /// Enum used to define whether the crack front is defined using nodes or points 280 : enum class CRACK_GEOM_DEFINITION 281 : { 282 : CRACK_FRONT_NODES, 283 : CRACK_FRONT_POINTS 284 : } _geom_definition_method; 285 : 286 : /// Reference to the auxiliary system 287 : AuxiliarySystem & _aux; 288 : /// Reference to the mesh 289 : MooseMesh & _mesh; 290 : /// Tolerance used in geometric calculations 291 : static const Real _tol; 292 : 293 : /// Crack front nodes ordered from the start to end of the crack front 294 : std::vector<dof_id_type> _ordered_crack_front_nodes; 295 : /// Vector of points along the crack front 296 : std::vector<Point> _crack_front_points; 297 : /// Vector of tangent directions along the crack front 298 : std::vector<RealVectorValue> _tangent_directions; 299 : /// Vector of crack extension directions along the crack front 300 : std::vector<RealVectorValue> _crack_directions; 301 : /// Vector of segment lengths along the crack front 302 : std::vector<std::pair<Real, Real>> _segment_lengths; 303 : /// Vector of distances along the crack front 304 : std::vector<Real> _distances_along_front; 305 : /// Vector of angles along the crack front 306 : std::vector<Real> _angles_along_front; 307 : /// Vector of tangential strain along the crack front 308 : std::vector<Real> _strain_along_front; 309 : /// Vector of rotation matrices along the crack front 310 : std::vector<RankTwoTensor> _rot_matrix; 311 : /// Overall length of the crack 312 : Real _overall_length; 313 : /// Fixed vector optionally used to define crack extension direction 314 : RealVectorValue _crack_direction_vector; 315 : /// Fixed vector optionally used to define crack extension direction at end 1 of crack front 316 : RealVectorValue _crack_direction_vector_end_1; 317 : /// Fixed vector optionally used to define crack extension direction at end 2 of crack front 318 : RealVectorValue _crack_direction_vector_end_2; 319 : /// Fixed vector optionally used to define crack tangent direction at end 1 of crack front 320 : RealVectorValue _crack_tangent_vector_end_1; 321 : /// Fixed vector optionally used to define crack tangent direction at end 2 of crack front 322 : RealVectorValue _crack_tangent_vector_end_2; 323 : /// Names of boundaries used to define location of crack mouth 324 : std::vector<BoundaryName> _crack_mouth_boundary_names; 325 : /// IDs of boundaries used to define location of crack mouth 326 : std::vector<BoundaryID> _crack_mouth_boundary_ids; 327 : /// Names of boundaries that intersect crack at its ends 328 : std::vector<BoundaryName> _intersecting_boundary_names; 329 : /// IDs of boundaries that intersect crack at its ends 330 : std::vector<BoundaryID> _intersecting_boundary_ids; 331 : /// Coordinates of crack mouth 332 : RealVectorValue _crack_mouth_coordinates; 333 : /// Vector normal to the crack plane of a planar crack 334 : RealVectorValue _crack_plane_normal; 335 : /// Vector normals to a nonplanar crack described by the cutter mesh when _use_mesh_cutter = true 336 : std::vector<RealVectorValue> _crack_plane_normals; 337 : /// Whether to treat the model as 2D for computation of fracture integrals 338 : bool _treat_as_2d; 339 : /// Whether to describe the crack as a mesh cutter 340 : bool _use_mesh_cutter; 341 : /// Indicator that shows if the cutter mesh is modified or not in the calculation step 342 : bool _is_cutter_modified; 343 : /// Whether the crack forms a closed loop 344 : bool _closed_loop; 345 : /// Out of plane axis when crack is treated as 2D 346 : unsigned int _axis_2d; 347 : /// Whether the crack plane is also a symmetry plane in the model 348 : bool _has_symmetry_plane; 349 : /// Which plane is the symmetry plane 350 : unsigned int _symmetry_plane; 351 : /// Names of the x, y, and z displacement variables 352 : ///@{ 353 : std::string _disp_x_var_name; 354 : std::string _disp_y_var_name; 355 : std::string _disp_z_var_name; 356 : ///@} 357 : /// Whether the T-stress is being computed 358 : bool _t_stress; 359 : /// Whether topological rings are used to define the q functions 360 : bool _q_function_rings; 361 : /// Numer of elements from crack tip to last topological ring 362 : std::size_t _last_ring; 363 : /// Numer of elements from crack tip to first topological ring 364 : std::size_t _first_ring; 365 : /// Data structure used to store information about topological rings 366 : /// Key is a pair of the crack front node index and ring id 367 : /// Data is a set of the IDs of the nodes in the ring for that crack front node 368 : std::map<std::pair<dof_id_type, std::size_t>, std::set<dof_id_type>> 369 : _crack_front_node_to_node_map; 370 : /// Method used to define the q function 371 : MooseEnum _q_function_type; 372 : /// Vector of bools indicating whether individual crack front points are on 373 : /// an intersecting boundary 374 : std::vector<bool> _is_point_on_intersecting_boundary; 375 : /// Vector of inner radii of the rings used for geometric q functions 376 : std::vector<Real> _j_integral_radius_inner; 377 : /// Vector of outer radii of the rings used for geometric q functions 378 : std::vector<Real> _j_integral_radius_outer; 379 : /// Pointer to a CrackFrontPointsProvider object optionally used to define 380 : /// the crack front points 381 : const CrackFrontPointsProvider * _crack_front_points_provider; 382 : /// Number of points coming from the CrackFrontPointsProvider 383 : std::size_t _num_points_from_provider; 384 : 385 : /** 386 : * Get the set of all crack front nodes 387 : * @param nodes Set of nodes -- populated by this method 388 : */ 389 : void getCrackFrontNodes(std::set<dof_id_type> & nodes); 390 : 391 : /** 392 : * Arrange the crack front nodes by their position along the crack front, 393 : * and put them in the _ordered_crack_front_nodes member variable. 394 : * @param nodes Set of nodes to be ordered 395 : */ 396 : void orderCrackFrontNodes(std::set<dof_id_type> & nodes); 397 : 398 : /** 399 : * Determine which of the end nodes should be the starting point of the 400 : * crack front. 401 : * @param end_nodes Vector containing two end nodes. The order of this is 402 : * rearranged so that the first end node is the start of 403 : * the crack front, and the second is at the end. 404 : */ 405 : void orderEndNodes(std::vector<dof_id_type> & end_nodes); 406 : 407 : /** 408 : * For the case of a crack that is a complete loop, determine which of the 409 : * nodes should be the start and end nodes in a repeatable way. 410 : * @param end_nodes Vector containing two end nodes -- populated by this method 411 : * @param nodes Set of all nodes on the crack front 412 : * @param node_to_line_elem_map Map from crack front nodes to line elements on crack 413 : * front (see line_elems param) 414 : * @param line_elems Line elements on crack front defined as vectors of the 415 : * nodes on each end of the line elements. 416 : */ 417 : void 418 : pickLoopCrackEndNodes(std::vector<dof_id_type> & end_nodes, 419 : std::set<dof_id_type> & nodes, 420 : std::map<dof_id_type, std::vector<dof_id_type>> & node_to_line_elem_map, 421 : std::vector<std::vector<dof_id_type>> & line_elems); 422 : /** 423 : * Find the node with the maximum value of its coordinate. This is used to 424 : * deterministically find the first node on the crack front. First, the nodes 425 : * with the maximum coordinate in one direction are found, and then if there 426 : * are duplicates with that same coordinate, search through the other two 427 : * coordinates to find the node with the maximum coordinate in all 3 directions. 428 : * @param nodes Set of all nodes on the crack front 429 : * @param dir0 First coordinate direction in which to order the coordinates 430 : */ 431 : dof_id_type maxNodeCoor(std::vector<Node *> & nodes, unsigned int dir0 = 0); 432 : 433 : /** 434 : * Update the data structures defining the crack front geometry such as 435 : * the ordered crack front nodes/points and other auxiliary data. 436 : */ 437 : void updateCrackFrontGeometry(); 438 : 439 : /** 440 : * Update the data structures used to determine the crack front direction 441 : * vectors such as crack mouth coordinates. 442 : */ 443 : void updateDataForCrackDirection(); 444 : 445 : /** 446 : * Compute the direction of crack extension for a given point on the crack front. 447 : * @param crack_front_point Point on the crack front 448 : * @param tangent_direction Tangent direction vector for the crack front point 449 : * @param ntype Node type such as MIDDLE_NODE, END_1_NODE, END_2_NODE 450 : * @param crack_front_point_index Index of the point on the crack front 451 : */ 452 : RealVectorValue calculateCrackFrontDirection(const Point & crack_front_point, 453 : const RealVectorValue & tangent_direction, 454 : const CRACK_NODE_TYPE ntype, 455 : const std::size_t crack_front_point_index = 0) const; 456 : 457 : /** 458 : * Compute the strain in the direction tangent to the crack at all points on the 459 : * crack front. 460 : */ 461 : void calculateTangentialStrainAlongFront(); 462 : 463 : /** 464 : * Create the data defining the rings used to define the q function when the topological 465 : * option is used to define the q function. 466 : */ 467 : void createQFunctionRings(); 468 : 469 : /** 470 : * Find nodes that are connected through elements to the nodes in the previous 471 : * node ring. 472 : * @param nodes_new_ring Nodes in the new ring -- populated by this method 473 : * @param nodes_old_ring Nodes in the previous ring 474 : * @param nodes_all_rings Nodes in all other rings to be excluded from the new ring 475 : * @param nodes_neighbor1 Nodes in the neighboring ring to one side to be excluded from the new 476 : * ring 477 : * @param nodes_neighbor2 Nodes in the neighboring ring to the other side to be excluded from the 478 : * new ring 479 : * @param nodes_to_elem_map Map of nodes to connected elements 480 : */ 481 : void addNodesToQFunctionRing(std::set<dof_id_type> & nodes_new_ring, 482 : const std::set<dof_id_type> & nodes_old_ring, 483 : const std::set<dof_id_type> & nodes_all_rings, 484 : const std::set<dof_id_type> & nodes_neighbor1, 485 : const std::set<dof_id_type> & nodes_neighbor2, 486 : std::vector<std::vector<const Elem *>> & nodes_to_elem_map); 487 : 488 : /** 489 : * Project a point to a specified point along the crack front and compute the 490 : * projected normal and tangential distance to the front 491 : * @param dist_to_front Projected normal distance to the front -- computed by this method 492 : * @param dist_along_tangent Project tangent distance to the front -- computed by this method 493 : * @param crack_front_point_index Index of the point on the crack front 494 : * @param current_node Node to be projected to the front 495 : */ 496 : void projectToFrontAtPoint(Real & dist_to_front, 497 : Real & dist_along_tangent, 498 : std::size_t crack_front_point_index, 499 : const Node * const current_node) const; 500 : };