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