LCOV - code coverage report
Current view: top level - src/auxkernels - DomainIntegralQFunction.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 58 61 95.1 %
Date: 2024-02-27 11:53:14 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          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             : #include "DomainIntegralQFunction.h"
      11             : 
      12             : registerMooseObject("TensorMechanicsApp", DomainIntegralQFunction);
      13             : 
      14             : InputParameters
      15         703 : DomainIntegralQFunction::validParams()
      16             : {
      17         703 :   InputParameters params = AuxKernel::validParams();
      18         703 :   params.addClassDescription("Computes the q-function for a segment along the crack front, used in "
      19             :                              "the calculation of the J-integral");
      20        1406 :   params.addRequiredParam<Real>("j_integral_radius_inner", "Radius for J-Integral calculation");
      21        1406 :   params.addRequiredParam<Real>("j_integral_radius_outer", "Radius for J-Integral calculation");
      22        1406 :   params.addRequiredParam<UserObjectName>("crack_front_definition",
      23             :                                           "The CrackFrontDefinition user object name");
      24        1406 :   params.addParam<unsigned int>(
      25             :       "crack_front_point_index",
      26             :       "The index of the point on the crack front corresponding to this q function");
      27         703 :   params.set<bool>("use_displaced_mesh") = false;
      28         703 :   return params;
      29           0 : }
      30             : 
      31         624 : DomainIntegralQFunction::DomainIntegralQFunction(const InputParameters & parameters)
      32             :   : AuxKernel(parameters),
      33         624 :     _j_integral_radius_inner(getParam<Real>("j_integral_radius_inner")),
      34        1248 :     _j_integral_radius_outer(getParam<Real>("j_integral_radius_outer")),
      35         624 :     _crack_front_definition(&getUserObject<CrackFrontDefinition>("crack_front_definition")),
      36        1248 :     _has_crack_front_point_index(isParamValid("crack_front_point_index")),
      37         624 :     _crack_front_point_index(
      38        1041 :         _has_crack_front_point_index ? getParam<unsigned int>("crack_front_point_index") : 0),
      39         624 :     _treat_as_2d(false),
      40         624 :     _is_point_on_intersecting_boundary(false)
      41             : {
      42         624 : }
      43             : 
      44             : void
      45         624 : DomainIntegralQFunction::initialSetup()
      46             : {
      47         624 :   _treat_as_2d = _crack_front_definition->treatAs2D();
      48             :   bool using_mesh_cutter = _crack_front_definition->usingMeshCutter();
      49         624 :   if (_treat_as_2d && using_mesh_cutter == false)
      50             :   {
      51         207 :     if (_has_crack_front_point_index)
      52             :     {
      53           0 :       mooseWarning(
      54             :           "crack_front_point_index ignored because CrackFrontDefinition is set to treat as 2D");
      55             :     }
      56             :   }
      57             :   else
      58             :   {
      59         417 :     if (!_has_crack_front_point_index)
      60             :     {
      61           0 :       mooseError("crack_front_point_index must be specified in DomainIntegralQFunction");
      62             :     }
      63             :   }
      64         624 :   _is_point_on_intersecting_boundary =
      65         624 :       _crack_front_definition->isPointWithIndexOnIntersectingBoundary(_crack_front_point_index);
      66         624 : }
      67             : 
      68             : Real
      69      426612 : DomainIntegralQFunction::computeValue()
      70             : {
      71             :   Real dist_to_crack_front;
      72             :   Real dist_along_tangent;
      73      426612 :   projectToFrontAtPoint(dist_to_crack_front, dist_along_tangent);
      74             : 
      75             :   Real q = 1.0;
      76      426612 :   if (dist_to_crack_front > _j_integral_radius_inner &&
      77      419284 :       dist_to_crack_front < _j_integral_radius_outer)
      78        2112 :     q = (_j_integral_radius_outer - dist_to_crack_front) /
      79        2112 :         (_j_integral_radius_outer - _j_integral_radius_inner);
      80      424500 :   else if (dist_to_crack_front >= _j_integral_radius_outer)
      81             :     q = 0.0;
      82             : 
      83      426612 :   if (q > 0.0)
      84             :   {
      85        9432 :     Real tangent_multiplier = 1.0;
      86        9432 :     if (!_treat_as_2d)
      87             :     {
      88             :       const Real forward_segment_length =
      89        5140 :           _crack_front_definition->getCrackFrontForwardSegmentLength(_crack_front_point_index);
      90             :       const Real backward_segment_length =
      91        5140 :           _crack_front_definition->getCrackFrontBackwardSegmentLength(_crack_front_point_index);
      92             : 
      93        5140 :       if (dist_along_tangent >= 0.0)
      94             :       {
      95        3328 :         if (forward_segment_length > 0.0)
      96        3112 :           tangent_multiplier = 1.0 - dist_along_tangent / forward_segment_length;
      97             :       }
      98             :       else
      99             :       {
     100        1812 :         if (backward_segment_length > 0.0)
     101        1784 :           tangent_multiplier = 1.0 + dist_along_tangent / backward_segment_length;
     102             :       }
     103             :     }
     104             : 
     105        9432 :     tangent_multiplier = std::max(tangent_multiplier, 0.0);
     106        9432 :     tangent_multiplier = std::min(tangent_multiplier, 1.0);
     107             : 
     108             :     // Set to zero if a node is on a designated free surface and its crack front node is not.
     109        9432 :     if (_crack_front_definition->isNodeOnIntersectingBoundary(_current_node) &&
     110         948 :         !_is_point_on_intersecting_boundary)
     111         708 :       tangent_multiplier = 0.0;
     112             : 
     113        9432 :     q *= tangent_multiplier;
     114             :   }
     115             : 
     116      426612 :   return q;
     117             : }
     118             : 
     119             : void
     120      426612 : DomainIntegralQFunction::projectToFrontAtPoint(Real & dist_to_front, Real & dist_along_tangent)
     121             : {
     122             :   const Point * crack_front_point =
     123      426612 :       _crack_front_definition->getCrackFrontPoint(_crack_front_point_index);
     124             : 
     125      426612 :   Point p = *_current_node;
     126             :   const RealVectorValue & crack_front_tangent =
     127      426612 :       _crack_front_definition->getCrackFrontTangent(_crack_front_point_index);
     128             : 
     129             :   RealVectorValue crack_node_to_current_node = p - *crack_front_point;
     130      426612 :   dist_along_tangent = crack_node_to_current_node * crack_front_tangent;
     131             :   RealVectorValue projection_point = *crack_front_point + dist_along_tangent * crack_front_tangent;
     132             :   RealVectorValue axis_to_current_node = p - projection_point;
     133      426612 :   dist_to_front = axis_to_current_node.norm();
     134      426612 : }

Generated by: LCOV version 1.14