-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29576 from lynnmunday/nonlocal_cracktip_matl
Nonlocal cracktip material
- Loading branch information
Showing
35 changed files
with
582 additions
and
283 deletions.
There are no files selected for viewing
19 changes: 19 additions & 0 deletions
19
...ics/doc/content/source/vectorpostprocessors/CrackFrontNonlocalScalarMaterial.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# CrackFrontNonlocalScalarMaterial | ||
|
||
!syntax description /VectorPostprocessors/CrackFrontNonlocalScalarMaterial | ||
|
||
## Description | ||
|
||
This object computes the average of a scalar material property in the region of the crack front points defined by [CrackFrontDefinition.md]. The main use case for this `VectorPostprocessor` is to compute an average fracture toughness or $K_c$ at the crack front for use with the `MeshCut2DFractureUserObject` to grow cracks. This allows for spatially varying $K_c$ values defined by a `Material`. | ||
|
||
`CrackFrontNonlocalScalarMaterial` computes an average of the material property over a box-shaped domain at each crack tip point that is centered on the crack tip and extends [!param](/VectorPostprocessors/CrackFrontNonlocalScalarMaterial/box_length) in front of the crack tip. The [!param](/VectorPostprocessors/CrackFrontNonlocalScalarMaterial/box_height) is the dimension normal to the crack face, and [!param](/VectorPostprocessors/CrackFrontNonlocalScalarMaterial/box_width) is the dimension tangential to the crack face. [!param](/VectorPostprocessors/CrackFrontNonlocalScalarMaterial/box_width) is not used in 2D problems. | ||
|
||
In the following input file example, the mesh consists of a 3D plate with a hole in the middle. The CrackFrontDefinition defines crack points around the center line of the hole, `boundary=1001`. This `CrackFrontNonlocalScalarMaterial` averages a material property named `scalar_kcrit` over each 3D box at each crack front point. | ||
|
||
!listing crack_front_nonlocal_materials.i block=UserObjects VectorPostprocessors/CrackFrontNonlocalKcrit | ||
|
||
!syntax parameters /VectorPostprocessors/CrackFrontNonlocalScalarMaterial | ||
|
||
!syntax inputs /VectorPostprocessors/CrackFrontNonlocalScalarMaterial | ||
|
||
!syntax children /VectorPostprocessors/CrackFrontNonlocalScalarMaterial |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
modules/solid_mechanics/include/vectorpostprocessors/CrackFrontNonlocalMaterialBase.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#pragma once | ||
|
||
#include "ElementVectorPostprocessor.h" | ||
|
||
// Forward Declarations | ||
class CrackFrontDefinition; | ||
|
||
/** | ||
* Computes the average material property in regions near points provided by the | ||
* crack_front_definition vectorpostprocessor. | ||
*/ | ||
class CrackFrontNonlocalMaterialBase : public ElementVectorPostprocessor | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
|
||
CrackFrontNonlocalMaterialBase(const InputParameters & parameters, | ||
const std::string & property_name); | ||
|
||
virtual void initialSetup() override; | ||
virtual void initialize() override; | ||
virtual void execute() override; | ||
virtual void finalize() override; | ||
virtual void threadJoin(const UserObject & y) override; | ||
|
||
protected: | ||
/// Material property name from derived class | ||
const std::string _property_name; | ||
/** dimensions of the box in front of the crack tip that the stress is averaged over | ||
* The box is centered in front of the crack tip | ||
* _box_length distance box extends in front of the crack tip | ||
* _box_width is tangent to the crack tip, centered on the crack point | ||
* _box_height is normal to the crack tip, centered on the crack point | ||
*/ | ||
///@{ | ||
Real _box_length; | ||
Real _box_width; | ||
Real _box_height; | ||
///@} | ||
|
||
/// used to transform local coordinates to crack front coordinates | ||
const CrackFrontDefinition * _crack_front_definition; | ||
|
||
/// Base name of the material system | ||
const std::string _base_name; | ||
|
||
// volume being integrated over for each crack front | ||
std::vector<Real> _volume; | ||
|
||
/// Vectors computed by this VectorPostprocessor: | ||
/// x,y,z coordinates, and position of nodes along crack front, and crack tip average scalar stress | ||
///@{ | ||
VectorPostprocessorValue & _x; | ||
VectorPostprocessorValue & _y; | ||
VectorPostprocessorValue & _z; | ||
VectorPostprocessorValue & _position; | ||
VectorPostprocessorValue & _avg_crack_tip_scalar; | ||
///@} | ||
|
||
/** | ||
* Determine whether a point is located within a specified crack front oriented box | ||
* @param crack_front_point_index Index of the point on the crack front that the box is based on | ||
* @param qp_coord Point object to determine whether it is inside the box | ||
* @return 1 if point is within the box, 0 otherwise | ||
*/ | ||
Real BoxWeightingFunction(std::size_t crack_front_point_index, const Point & qp_coord) const; | ||
/** | ||
* Determine whether a point is located within a specified crack front oriented box | ||
* @param qp quardature point to get material properties at | ||
* @param crack_face_normal normal direction to crack face | ||
* @return Value of material property at this qp and direction | ||
*/ | ||
virtual Real getQPCrackFrontScalar(const unsigned int qp, | ||
const Point crack_face_normal) const = 0; | ||
}; |
31 changes: 31 additions & 0 deletions
31
modules/solid_mechanics/include/vectorpostprocessors/CrackFrontNonlocalScalarMaterial.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#pragma once | ||
|
||
#include "CrackFrontNonlocalMaterialBase.h" | ||
|
||
/** | ||
* Computes the average material at points provided by the crack_front_definition | ||
* vectorpostprocessor. | ||
*/ | ||
class CrackFrontNonlocalScalarMaterial : public CrackFrontNonlocalMaterialBase | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
|
||
CrackFrontNonlocalScalarMaterial(const InputParameters & parameters); | ||
|
||
protected: | ||
/// Property that is averaged over the crack front points | ||
const MaterialProperty<Real> & _scalar; | ||
|
||
Real getQPCrackFrontScalar(const unsigned int qp, | ||
const Point /*crack_face_normal*/) const override; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
modules/solid_mechanics/src/vectorpostprocessors/CrackFrontNonlocalMaterialBase.C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#include "CrackFrontNonlocalMaterialBase.h" | ||
#include "CrackFrontDefinition.h" | ||
|
||
InputParameters | ||
CrackFrontNonlocalMaterialBase::validParams() | ||
{ | ||
InputParameters params = ElementVectorPostprocessor::validParams(); | ||
params.addRequiredParam<UserObjectName>("crack_front_definition", | ||
"The CrackFrontDefinition user object name"); | ||
params.addRequiredParam<Real>( | ||
"box_length", "Dimension of property-averaging box in direction of crack extension."); | ||
params.addRequiredParam<Real>( | ||
"box_height", "Dimension of property-averaging box in direction normal to crack."); | ||
params.addParam<Real>("box_width", 1.0, "Distance tangent to front of crack front."); | ||
params.addParam<std::string>("base_name", | ||
"Optional parameter that allows the user to define " | ||
"multiple mechanics material systems on the same " | ||
"block, i.e. for multiple phases"); | ||
params.set<bool>("use_displaced_mesh") = false; | ||
params.set<ExecFlagEnum>("execute_on") = {EXEC_TIMESTEP_BEGIN}; | ||
params.addClassDescription("Computes the average material property at a crack front."); | ||
return params; | ||
} | ||
|
||
CrackFrontNonlocalMaterialBase::CrackFrontNonlocalMaterialBase(const InputParameters & parameters, | ||
const std::string & property_name) | ||
: ElementVectorPostprocessor(parameters), | ||
_property_name(property_name), | ||
_box_length(getParam<Real>("box_length")), | ||
_box_width(getParam<Real>("box_width")), | ||
_box_height(getParam<Real>("box_height")), | ||
_base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""), | ||
_x(declareVector("x")), | ||
_y(declareVector("y")), | ||
_z(declareVector("z")), | ||
_position(declareVector("id")), | ||
// get the property name instead of materialname | ||
_avg_crack_tip_scalar(declareVector("crack_tip_" + _base_name + _property_name)) | ||
{ | ||
if (_mesh.dimension() == 3 && !isParamSetByUser("box_width")) | ||
paramError("box_width", "Must define box_width in 3D problems."); | ||
// add user object dependencies by name (the UOs do not need to exist yet for this) | ||
_depend_uo.insert(getParam<UserObjectName>("crack_front_definition")); | ||
} | ||
|
||
void | ||
CrackFrontNonlocalMaterialBase::initialSetup() | ||
{ | ||
const auto uo_name = getParam<UserObjectName>("crack_front_definition"); | ||
_crack_front_definition = | ||
&(getUserObjectByName<CrackFrontDefinition>(uo_name, /*is_dependency = */ false)); | ||
} | ||
|
||
void | ||
CrackFrontNonlocalMaterialBase::initialize() | ||
{ | ||
std::size_t num_pts = _crack_front_definition->getNumCrackFrontPoints(); | ||
|
||
_volume.assign(num_pts, 0.0); | ||
_x.assign(num_pts, 0.0); | ||
_y.assign(num_pts, 0.0); | ||
_z.assign(num_pts, 0.0); | ||
_position.assign(num_pts, 0.0); | ||
_avg_crack_tip_scalar.assign(num_pts, 0.0); | ||
} | ||
|
||
void | ||
CrackFrontNonlocalMaterialBase::execute() | ||
{ | ||
// icfp crack front point index | ||
for (const auto icfp : index_range(_avg_crack_tip_scalar)) | ||
{ | ||
Point crack_front_normal = _crack_front_definition->getCrackFrontNormal(icfp); | ||
for (unsigned int qp = 0; qp < _qrule->n_points(); qp++) | ||
{ | ||
Real q = BoxWeightingFunction(icfp, _q_point[qp]); | ||
if (q == 0) | ||
continue; | ||
|
||
Real scalar = getQPCrackFrontScalar(qp, crack_front_normal); | ||
_avg_crack_tip_scalar[icfp] += _JxW[qp] * _coord[qp] * scalar * q; | ||
_volume[icfp] += _JxW[qp] * _coord[qp] * q; | ||
} | ||
} | ||
} | ||
|
||
void | ||
CrackFrontNonlocalMaterialBase::finalize() | ||
{ | ||
gatherSum(_avg_crack_tip_scalar); | ||
gatherSum(_volume); | ||
for (const auto icfp : index_range(_avg_crack_tip_scalar)) | ||
{ | ||
if (_volume[icfp] != 0) | ||
_avg_crack_tip_scalar[icfp] = _avg_crack_tip_scalar[icfp] / _volume[icfp]; | ||
else | ||
_avg_crack_tip_scalar[icfp] = 0; | ||
|
||
const auto cfp = _crack_front_definition->getCrackFrontPoint(icfp); | ||
_x[icfp] = (*cfp)(0); | ||
_y[icfp] = (*cfp)(1); | ||
_z[icfp] = (*cfp)(2); | ||
_position[icfp] = _crack_front_definition->getDistanceAlongFront(icfp); | ||
} | ||
} | ||
|
||
void | ||
CrackFrontNonlocalMaterialBase::threadJoin(const UserObject & y) | ||
{ | ||
const auto & uo = static_cast<const CrackFrontNonlocalMaterialBase &>(y); | ||
for (const auto i : index_range(_avg_crack_tip_scalar)) | ||
{ | ||
_volume[i] += uo._volume[i]; | ||
_avg_crack_tip_scalar[i] += uo._avg_crack_tip_scalar[i]; | ||
} | ||
} | ||
|
||
Real | ||
CrackFrontNonlocalMaterialBase::BoxWeightingFunction(std::size_t crack_front_point_index, | ||
const Point & qp_coord) const | ||
{ | ||
const Point * cf_pt = _crack_front_definition->getCrackFrontPoint(crack_front_point_index); | ||
RealVectorValue crack_node_to_current_node = qp_coord - *cf_pt; | ||
|
||
// crackfront coordinates are: | ||
// crack_node_to_current_node_rot[0]= crack direction | ||
// crack_node_to_current_node_rot[1]= normal to crack face | ||
// crack_node_to_current_node_rot[2]= tangent to crack face along crack front (not used in 2D) | ||
RealVectorValue crack_node_to_current_node_rot = | ||
_crack_front_definition->rotateToCrackFrontCoords(crack_node_to_current_node, | ||
crack_front_point_index); | ||
if ((crack_node_to_current_node_rot(0) > 0) && | ||
(crack_node_to_current_node_rot(0) <= _box_length) && | ||
(std::abs(crack_node_to_current_node_rot(1)) <= _box_height / 2) && | ||
(std::abs(crack_node_to_current_node_rot(2)) <= _box_width / 2)) | ||
return 1.0; | ||
|
||
return 0.0; | ||
} |
Oops, something went wrong.