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