.. _sect-jint:

************
*J*-Integral
************

Sierra/SM provides a capability to compute the :math:`J`-integral via a domain integral. 

.. admonition:: Known Issue
   :class: admonition warning

   Currently, the :math:`J`-Integral evaluation capability is based on assumptions of elastostatics and a stationary crack, and is only implemented for 8-noded hexahedral elements with a single integration point.

:math:`J` is analogous to :math:`G` from linear elastic fracture mechanics (:math:`-\delta \pi / \delta a`) and is the driving force on the crack tip of length :math:`a` [:footcite:`eshelby1951`, :footcite:`rice1968`]. Crack propagation occurs when :math:`J(a) \ge R(a)`, where :math:`R(a)` is the material resistance. For constant :math:`R`, the resistance is often termed :math:`J_{c}`. In the reference configuration, the vector form of the :math:`J`-integral in finite deformation [:footcite:`maugin1993`] is

.. math::
   :label: eqn:jint:surface1

   \mathbf{J}=\int_{\Gamma_{0}}{\boldsymbol{\Sigma}\mathbf{N}\,\text{d}A}

where :math:`\boldsymbol{\Sigma} = W\mathbf{I} - \mathbf{F}^{T}\mathbf{P}` is called the Eshelby energy-momentum tensor [:footcite:`eshelby1970`]. :math:`W` is the stored energy density in the reference configuration and :math:`\mathbf{F}` and :math:`\mathbf{P}` are the deformation gradient and first Piola-Kirchhoff stress,  respectively. Rice [:footcite:`rice1968`] realized that because :math:`\boldsymbol{\Sigma}` is divergence-free in the absence of body forces, one can examine :math:`\mathbf{J}` in the direction of the defect :math:`\mathbf{L}` (unit vector) and  obtain a path-independent integral for traction-free crack faces. :math:`J` can be written as

.. math::
   :label: eqn:jint:surface2

   J=\int_{\Gamma_{0}}{\mathbf{L} \cdot \boldsymbol{\Sigma}\mathbf{N}\,\text{d}A}
   
and interpreted as a path-independent driving force in the direction of the defect. We note that one  can also express :math:`\boldsymbol{\Sigma}` in terms of :math:`\bar{\boldsymbol{\Sigma}}`, where :math:`\bar{\boldsymbol{\Sigma}} = W\mathbf{I} -  \mathbf{H}^{T}\mathbf{P}` and :math:`\mathbf{H} = \text{Grad}\,\mathbf{u}`. Although :math:`\boldsymbol{\Sigma}` is symmetric  and :math:`\bar{\boldsymbol{\Sigma}}` is not symmetric, they are equivalent when integrated over the body (:math:`\text{Div}\mathbf{P}=\mathbf{0}`). Differences in the energy-momentum tensor stem from the  functional dependence of the stored energy function :math:`W`. :math:`\boldsymbol{\Sigma}` and :math:`\bar{\boldsymbol{\Sigma}}` derive from :math:`W(\mathbf{F})` and :math:`W(\mathbf{H})`, respectively. When integrated, both collapse to the familiar 2-D relation for infinitesimal deformations.

.. math::
   :label: eqn:jint:surface3

   J=\int_{\Gamma}{\mathbf{e}_{1} \cdot \boldsymbol{\Sigma}\mathbf{n}\,\text{d}s} = \int_{\Gamma}{(Wn_1-u_{i,1}\sigma_{ij}n_j)\text{d}s}
 
Technique for Computing *J*
===========================

.. \label{eqn:jint:surfint}
.. J=\int_{\Gamma}{(Wn_1-u_{i,1}\sigma_{ij}n_j)\,\text{d}s}

.. \label{eqn-jint-volint}
.. J=\int_{\Omega}{(u_{i,1}\sigma_{ij}n_j-W\delta_{ij})\frac{{\partial}q_1}{{\partial}x_j}\,\text{d}V}

:math:`J` is often expressed as a line (2D) or surface (3D) integral on a ring surrounding the crack tip. Defining a smooth ring over which to compute this surface integral and performing projections of the required field values onto that ring presents many difficulties in the context of a finite element code.

To compute the :math:`J`-integral in a finite element code, it is more convenient to perform a volume integral over a domain surrounding the crack tip. We can then leverage the information at integration points rather than rely on less accurate projections. To do this, we follow the method described in [:footcite:`liShih`]. We replace :math:`\mathbf{L}` with a smooth function :math:`\mathbf{q}`. On the  inner contour of the domain :math:`\Gamma_{0}`, :math:`\mathbf{q} = \mathbf{L}`. On the outer contour of    the domain :math:`C_{0}`, :math:`\mathbf{q} = \mathbf{0}`. Because the outer normal of the domain :math:`\mathbf{M}` is equal and  opposite of the normal :math:`\mathbf{N}` on :math:`\Gamma_{0}`, there is a change of sign. For traction-free surfaces, we can apply the divergence theorem, enforce :math:`\text{Div}\bar{\boldsymbol{\Sigma}}=\mathbf{0}`,  and find that the energy per unit length :math:`\bar{J}` is

.. math::
   :label: eqn-jint-volint

   \bar{J}=-\int_{\Omega_{0}}(\bar{\boldsymbol{\Sigma}}:\text{Grad}\,\mathbf{q})\text{d}V.

We can also introduce a correction if we seek to consider cases in which the crack faces, :math:`A_{0}^{+} + A_{0}^{-}`, or "caps", :math:`S_{0}^{+} + S_{0}^{-}`, of the domain are not traction free. For example, both cases would be satisfied for a thumbnail crack in a pressure vessel. The correction

.. math::
   :label: eqn-jint-volint_correction
  
   \bar{J}=-\int_{\Omega_{0}}(\bar{\boldsymbol{\Sigma}}:\text{Grad}\,\mathbf{q})\text{d}V- \int_{S_{0}^{+} + S_{0}^{-} + A_{0}^{+} + A_{0}^{-}}{\mathbf{q} \cdot \mathbf{H}^{T}\mathbf{T}\,\text{d}A}.

effectively removes the contribution of the applied tractions and ensures that the integral remains path independent. We note that the correction is integrated in the reference configuration with referential traction :math:`\mathbf{T}`. When pressure is applied to :math:`S_{0}^{+}`, :math:`S_{0}^{-}`, :math:`A_{0}^{+}`, or :math:`A_{0}^{-}`, Sierra employs :eq:`eqn-jint-volint_correction`.

We note that all the field quantities are given via simulation and we choose to define :math:`\mathbf{q}` on the nodes of the domain :math:`\mathbf{q}^{I}`. We then employ the standard finite element shape functions to calculate the gradient. We can specify the crack direction :math:`\mathbf{L}` or assume that the crack will propagate in the direction normalto the crack front :math:`-\mathbf{M}`. For a "straight" crack front, :math:`\mathbf{L} = -\mathbf{M}`. If :math:`\mathbf{S}` is tangent to the crack front and :math:`\mathbf{T}` is normal to the lower crack surface, :math:`\mathbf{S} \times \mathbf{M} = \mathbf{T}`. We note that for non-planar, curving cracks, :math:`\mathbf{M}`, :math:`\mathbf{S}`, and :math:`\mathbf{T}` are functions of the arc length :math:`S`. For ease, we employ the notation :math:`\mathbf{N}` rather than :math:`-\mathbf{M}`. For a crack front :math:`S_{0}`, we can define the average driving force :math:`J_{avg}` as

.. math::
   :label: eqn:jint:javg

   {J_{avg}}=\frac{\bar{J}}{\int_{S_{0}}\mathbf{L} \cdot \mathbf{N}\,\text{d}S}.

While the average driving force is useful for interpreting experimental findings and obtaining a  macroscopic representation of the driving force, we also seek to examine the local driving force :math:`J(S)`. Using the finite element interpolation functions to discretize :math:`\mathbf{L}` through the smooth function :math:`\mathbf{q}`,  we find :math:`\mathbf{q} = \lambda^{I}\mathbf{q}^{I}`. For a specific node :math:`K`, we can define :math:`|\mathbf{q}^{K}| = 1` and :math:`\mathbf{q}^{I} = \mathbf{0}` for all other :math:`I \ne K` on :math:`S_{0}`. Note that we still need to specify the function :math:`\mathbf{q}` in the  :math:`\mathbf{S}-\mathbf{T}` plane from the inner contour :math:`\Gamma_{0}` to the outer contour :math:`C_{0}`. The resulting  expression for the approximate, point-wise driving force at node :math:`K` on the crack front is

.. math::
   :label: eqn:jint:jpointwise

   J^{K}=\frac{\bar{J}}{\int_{S_{0}} \lambda^{K}\mathbf{q}^{K} \cdot \mathbf{N}\,\text{d}S}.

Again, we note that if the direction of propagation :math:`\mathbf{L}` is taken in the direction of the normal :math:`\mathbf{N}`, the  denominator is :math:`\int_{S_{0}} \lambda^{K}\text{d}S`. More information regarding the point-wise approximation of  :math:`J^{K}` can be found in [:footcite:`shih`, :footcite:`HKS`].

Additional information on the J Integral capability can be found in [:footcite:`ohashi`].

Input Commands
==============

Output quantities related to :math:`J`-integrals may be computed during the analysis by including one or more ``J INTEGRAL`` command blocks in the ``REGION`` scope. This block can contain the following commands:

.. code-block:: sierrainput

   BEGIN J INTEGRAL <jint_name>
     #
     # Definition of integration domain
     BLOCK = <string list>blockNames
     REMOVE BLOCK = <string list>removeBlocks
     ELEMENT = <int_list>elemNumbers
     ASSEMBLY = <string list>assemblyNames
     INCLUDE ALL BLOCKS
     #
     # integral parameter specification commands
     CRACK PLANE SIDE SET = <string list>side_sets
     CRACK TIP NODE SET = <string list>node_sets
     USE SURFACE FOR EDGE DIRECTION = OFF|ON(ON)
     CRACK DIRECTION = <real>dir_x 
                       <real>dir_y 
                       <real>dir_z
     INTEGRATION RADIUS = <real>int_radius
     NUMBER OF DOMAINS = <integer>num_domains
     FUNCTION = 
        PLATEAU|PLATEAU_RAMP|LINEAR(PLATEAU) 
     SYMMETRY = OFF|ON(OFF)
     DEBUG OUTPUT = OFF|ON(OFF) WITH 
       <integer>num_nodes NODES ON THE CRACK FRONT
     #
     # time period selection commands
     ACTIVE PERIODS = <string list>period_names
     INACTIVE PERIODS = <string list>period_names
   END J INTEGRAL <jint_name>

The :math:`J`-integral is performed over a domain defined by a set of elements using the standard element assignment commands. See :numref:`conditions-general-entity` for details.

A set of parameters must be provided to define the crack geometry  used in the calculation of the :math:`J`-integral. The :math:`J`-integral command block uses a sideset on one surface of the crack plane behind the crack tip and a nodeset containing the nodes on the crack tip. Both the ``CRACK PLANE SIDE SET`` and ``CRACK TIP NODE SET`` commands are required. These commands specify the names of the sideset behind the crack tip and the nodeset on the crack tip, respectively. Assemblies may contain blocks, or assemblies of these.

By default, the direction of crack propagation is computed from the geometry of the crack plane and tip, as provided in the crack plane sideset and crack tip nodeset (:math:`\mathbf{L}=\mathbf{N}`). At locations where the crack intersects a surface, the computed :math:`\mathbf{N}` is commonly less accurate. At these locations, the ``USE SURFACE FOR EDGE DIRECTION = ON`` command will attempt to improve :math:`\mathbf{N}` by projecting it onto the intersected surface. The default is ``ON``, and ``USE SURFACE FOR EDGE DIRECTION = OFF`` should only be set if the crack tip is known to intersect the surface at a sharp angle. Alternatively, the ``CRACK DIRECTION`` command can be used to override the  computed direction of crack propagation (:math:`\mathbf{L}`). This command takes three  real numbers that define the three components of the crack direction vector in  the global XYZ coordinate system.

To fully define the domains used for the domain integrals, the radius of the domains and the number of domains must also be specified. A series of disc-shaped integration domains are formed with varying radii going out from the crack tip. The ``INTEGRATION RADIUS`` command specifies the radius of the outermost domain. The number of integration domains is specified using the ``NUMBER OF DOMAINS`` command. The radii of the domains increase linearly going from the innermost to the outermost domain. The domains will only include elements included in the overall integration domain defined by the ``BLOCK`` command and other related commands.

The weight function :math:`\mathbf{q}` used to calculate the :math:`J`-integral is specified by use of the ``FUNCTION`` command line. The ``LINEAR`` function sets the weight function to 1.0 on the crack front :math:`\Gamma_{0}` and 0.0 at the edge of the domain :math:`C_{0}`, ``int_radius`` away from the crack tip. The ``PLATEAU`` function, which is the default behavior, sets all values of the weight function to 1.0 that lie within the domain of integration and all values outside of the domain are set to 0.0. This allows for integration over a single ring of elements at the edge of the domain. The third option for the ``FUNCTION`` command is ``PLATEAU_RAMP``, which for a single domain will take on the same values as the ``LINEAR`` function. However, when there are multiple domains over the radius ``int_radius``, the :math:`n^{th}` domain will have weight function values of 1.0 over the inner :math:`n-1` domains and will vary from 1.0 to 0.0 over the outer :math:`n^{th}` ring of the domain. These functions can be seen graphically in :numref:`fig-jint-domains`.

.. _fig-jint-domains:

.. figure:: ../../_static/figures/fig_jintDomains.png
   :align: center
   :scale: 20 %

   Example weight functions for a :math:`J`-integral integration domain. Weight functions shown for domain 5.

We note that in employing both the ``PLATEAU`` and the ``PLATEAU_RAMP`` functions, one is effectively taking a line integral at finite radius (albeit different radii). In contrast, the ``LINEAR`` option  can be viewed as taking the :math:`lim \; \Gamma_{0} \rightarrow 0^{+}`. If the model is a half symmetry model with the symmetry plane on the plane of the crack, the optional ``SYMMETRY`` command can be used to include the symmetry conditions in the formation of the integration domains and in the evaluation of the integral. The default behavior is for symmetry to not be used.

The user may optionally specify the time periods during which the :math:`J`-integral is computed. The ``ACTIVE PERIODS`` and ``INACTIVE PERIODS`` command lines are used for this purpose. See the :numref:`commands-functionality` for more information about these command lines.

.. _sect-jint-region:

*J*-Integral Region
===================

Optionally, a ``J_INTEGRAL REGION`` can be used for computation and output of :math:`J`-integral quantities. This particular region must be part of an input deck with multiple regions: an ``ADAGIO REGION`` and the ``J_INTEGRAL REGION``. The input deck structure is as follows.

.. code-block:: sierrainput

   BEGIN ADAGIO REGION <string>adagio_region_name
     USE FINITE ELEMENT MODEL <string>full_model_name
     # adagio commands for boundary value problem
     ...
   END [ADAGIO REGION <string>adagio_region_name]
   
   BEGIN J_INTEGRAL REGION <string>jintegral_region_name
     USE FINITE ELEMENT MODEL <string>refined_crack_model_name
     # one or more J-integral command blocks
     # output of J-integral fields
   END [J_INTEGRAL REGION <string>jintegral_region_name]

The ``J_INTEGRAL REGION`` is essentially a post-processing region specifically designed for the :math:`J`-integral capability. The usage of a separate region with the ``USE FINITE ELEMENT MODEL`` command line allows for a separate mesh to be used for the computation of the :math:`J`-integral. This facilitates the ability to use a well-structured, highly refined hexahedral mesh of the crack for robust :math:`J`-integral computations, while using a generally unstructured, less refined mesh with any three-dimensional solid element (\textit{e.g.}, tetrahedra) for modeling the crack in the full model being analyzed. At every results output step in the ``J_INTEGRAL REGION``, Sierra/SM performs an :math:`L_2`-projection transfer (see :numref:`transfers-inter`) from the ``ADAGION REGION``. This transfer includes all fields needed by the :math:`J`-integral, and it is immediately followed by computation and output of the requested :math:`J`-integral quantities. The transfer is fully automated and cannot be re-defined or modified in the input deck commands for the ``J_INTEGRAL REGION``.

The only additional command block available in the ``J_INTEGRAL REGION`` is the pressure boundary condition (see :numref:`conditions-force-pressure`). This boundary condition is available only for the purpose of allowing the :math:`J`-integral algorithm to apply the appropriate pressure corrections. These pressure boundary conditions should identically match equivalent pressure boundary conditions applied in the ``ADAGIO REGION``; the pressure magnitudes and surfaces receiving the pressure loads should be consistent between the two regions.

Output
======

Many variables are generated for output when the computation of the :math:`J`-integral is requested. The average value of :math:`J` for each integration domain is available as a global variable, as described in Table :numref:`output-tab-jint_globvars`. The point-wise value of :math:`J` at nodes along the crack for each integration domain is available as a nodal variable, as shown in Table :numref:`output-tab-jint_nodevars`. An element variable to illustrate the integration domains is also available, as listed in Table :numref:`output-tab-jint_elemvars`.

The ``DEBUG OUTPUT`` command is useful to generate output data for debugging the :math:`J`-integral. If the ``DEBUG OUTPUT = ON|OFF(OFF) WITH <integer>num_nodes NODES ON THE CRACK FRONT`` line command is set to ``ON``, the weight functions, :math:`q`, will be output for each node-based :math:`J` value that is calculated. The user must specify ``num_nodes``, which represents the number of nodes along the crack front. An internal check is performed during problem initialization that will verify that the number of nodes specified by the user on the command line matches the number of nodes associated with the crack front. 

.. warning::

   Using the ``DEBUG OUTPUT`` command line can potentially result in an extremely large output file because every node in the integration domain will now compute and store :math:`(NumNodeOnCrackFront + 1)*NumDomains` weight function vectors. This can also potentially exhaust the available memory on the machine.

Required Discretization
=======================

In order to enable the correct construction of the test function :math:`\mathbf{q}^{I}`, the hexahedral mesh should be orthogonal to the crack front. An orthogonal mesh will ensure that the elements are not skewed along the crack front. Because these elements will experience large deformation during crack-tip blunting, well-formed elements increase the accuracy of the solution. We note that this capability is not specific to crack front nodes. Any ellipsoidal surface with a constant bias will generate skewed elements.

In addition, an orthogonal mesh will ensure that the location of a point-wise surface integral will be a closest point projection from the crack-tip node. Consequently, any surface integral via a domain integral at a node along the crack front will be most accurate if the specified radius is a minimum. In addition to increasing the accuracy of point-wise evaluations of the :math:`J`-integral, an orthogonal mesh will also ease the search algorithm for point-wise evaluations. The search is performed along the normal to the crack front. If the mesh is aligned with the normal, the specification of :math:`\mathbf{q}` is straightforward. Misalignment can result in a "checker boarding" of the integration domains which presents the possibility that :math:`\mathbf{q}^{I}` will always be one and the :math:`J`-integral will be zero. Future work may generalize the calculation of :math:`J^{K}`, but we are currently limited to hexahedra. Given these requirements, we collaborated with the Cubit team to add the capability to generate meshes orthogonal to a surface. The Cubit team implemented the command

.. code-block:: sh

   adjust boundary surface AA snap_to_normal curve A
 
which enables the generated elements on surface ``AA`` to be "snapped" normal to the curve ``A``. For example, one may choose to sweep adjacent squares along the crack front curve ``A``. For crack plane surfaces ``AA`` and ``AB`` joined by the crack front curve ``A``, one would issue the following commands in Cubit

.. code-block:: sh

   surface AA AB scheme map
   mesh surface AA
   node in curve A position fixed
   adjust boundary surface AA snap_to_normal curve A
   mesh surface AB
   node in curve A position fixed
   adjust boundary surface AB snap_to_normal curve A 
             fixed curve A
 
to obtain an orthogonal mesh. The next step is to sweep that mesh "up" and "down" from the crack surface. To ensure that Cubit employs a "simple" sweep so that the search is consistent through the direction of the sweep, we use

.. code-block:: sh

   volume ABC  scheme sweep source surface AA target 
         surface AC 
   propagate_bias autosmooth_target off sweep_smooth 
         linear 
   sweep_transform translate

for volume ``ABC``. Because proper mesh construction ensures accuracy and smoothness in :math:`J^{K}`, we encourage analysts to use the ``snap_to_normal`` and ``autosmooth_target off`` options.

Results and History Output
==========================

This section lists output variables for :math:`J`-Integral.

- Table :numref:`output-tab-jint_globvars`  Global Variables for :math:`J`-Integral 
- Table :numref:`output-tab-jint_nodevars`  Nodal Variables for :math:`J`-Integral 
- Table :numref:`output-tab-jint_elemvars`  Element Variables for :math:`J`-Integral

.. _output-tab-jint_globvars:

.. csv-table:: Global Variables for :math:`J`-Integral
   :align: center
   :delim: &
   :header: Variable Name, Type, Comments
   :widths: 30 15 55

   ``j_average_<jint_name>``& ``Real[]`` & Average value of the :math:`J`-integral over the crack. Array sized to number of integration domains and numbered from inner to outer domain. ``<jint_name>`` is the name of the ``J INTEGRAL`` block.

.. _output-tab-jint_nodevars:

.. csv-table:: Nodal Variables for :math:`J`-Integral
   :align: center
   :delim: &
   :header: Variable Name, Type, Comments
   :widths: 30 15 55

   ``j_<jint_name>``& ``Real[]`` & Point-wise value of :math:`J`-integral along crack. Array sized to number of integration domains and numbered from inner to outer domain. ``<jint_name>`` is the name of the ``J INTEGRAL`` block.

.. _output-tab-jint_elemvars:

.. csv-table:: Element Variables for :math:`J`-Integral
   :align: center
   :delim: &
   :header: Variable Name, Type, Comments
   :widths: 40 15 45

   ``j_integration_domains_<jint_name>``& ``Integer[]`` & Flag indicating elements in integration domains. Set to 1 if in domain, 0 otherwise. Array sized to number of domains and numbered from inner to outer domain. ``<jint_name>`` is the name of the ``J INTEGRAL`` block.

.. raw::
  html

  <hr>

.. footbibliography::
