Skip to content

Commit adf7703

Browse files
authored
Merge pull request #3 from maxnezdyur/nonlocal_damage
Combine branches to have correct history
2 parents 043ffbd + aa81768 commit adf7703

File tree

16 files changed

+734
-47
lines changed

16 files changed

+734
-47
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# RadialAverage
2+
3+
!syntax description /UserObjects/RadialAverage
4+
5+
Given a material property and a radius for averaging. The RadialAverage object
6+
computes the spatial average value of the property over the radius.
7+
8+
## Applications
9+
This can be used for nonlocal damage models where the damage_index that is used
10+
for computing the damage stress is average over a certain radius. This can help
11+
alleviate mesh sensitivity in certain cases.
12+
13+
## Design
14+
15+
The RadialAverage user object is derived from `ElementUserObject` and
16+
works in two stages.
17+
18+
1. In the element loop (in the `execute()` method) a list of all quadrature
19+
points, their locations, indices, and selected variable value is compiled.
20+
21+
2. In the `finalize()` method
22+
23+
1. the list is communicated in parallel
24+
25+
2. a KD-tree is filled witha ll quadrature point entries (utilizing the
26+
[nanoflann](https://github.com/jlblancoc/nanoflann) library bundled with
27+
libMesh)
28+
29+
3. a loop over all QPs is performed and at each QP a $r_{cut}$ (`r_cut`)
30+
radius search in the KD-tree is performed
31+
32+
4. the results from the search are used to spatially averaged
33+
34+
35+
!syntax parameters /UserObjects/RadialAverage
36+
37+
!syntax inputs /UserObjects/RadialAverage
38+
39+
!syntax children /UserObjects/RadialAverage
40+
41+
!bibtex bibliography

framework/include/userobject/ThreadedRadialAverageLoop.h

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,6 @@
1313

1414
#include "libmesh/nanoflann.hpp"
1515

16-
using QPDataRange =
17-
StoredRange<std::vector<RadialAverage::QPData>::const_iterator, RadialAverage::QPData>;
18-
19-
/**
20-
* RadialAverage threaded loop
21-
*/
22-
class ThreadedRadialAverageLoop
23-
{
24-
public:
25-
ThreadedRadialAverageLoop(RadialAverage &);
26-
27-
/// Splitting constructor
28-
ThreadedRadialAverageLoop(const ThreadedRadialAverageLoop & x, Threads::split split);
29-
30-
/// dummy virtual destructor
31-
virtual ~ThreadedRadialAverageLoop() {}
32-
33-
/// parens operator with the code that is executed in threads
34-
void operator()(const QPDataRange & range);
35-
36-
/// thread join method
37-
virtual void join(const ThreadedRadialAverageLoop & /*x*/) {}
38-
39-
protected:
40-
/// rasterizer to manage the sample data
41-
RadialAverage & _radavg;
42-
43-
/// ID number of the current thread
44-
THREAD_ID _tid;
45-
46-
private:
47-
}; //* This file is part of the MOOSE framework
48-
//* https://www.mooseframework.org
49-
//*
50-
//* All rights reserved, see COPYRIGHT for full restrictions
51-
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
52-
//*
53-
//* Licensed under LGPL 2.1, please see LICENSE for details
54-
//* https://www.gnu.org/licenses/lgpl-2.1.html
55-
56-
#pragma once
57-
58-
#include "RadialAverage.h"
59-
60-
#include "libmesh/nanoflann.hpp"
61-
6216
using QPDataRange =
6317
StoredRange<std::vector<RadialAverage::QPData>::const_iterator, RadialAverage::QPData>;
6418

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Scalar Material Damage
2+
3+
!syntax description /Materials/ADNonLocalDamage
4+
5+
## Description
6+
7+
`ADNonLocalDamage` is a model to define the effect of damage on the stress and stiffness in a continuum damage mechanics setting. It does not directly compute the stress, but must be used in conjunction with [ComputeDamageStress](/ComputeDamageStress.md).
8+
9+
This model is a scalar damage model in which the stress $\boldsymbol{\sigma}$ is computed as a function of the damage $d$, the original stiffness of the material $\mathbb{C}$ and the elastic strain $\boldsymbol{\varepsilon}$:
10+
11+
\begin{equation}
12+
\boldsymbol{\sigma} = (1 - d)\ \mathbb{C} : \boldsymbol{\varepsilon}
13+
\end{equation}
14+
15+
The damage variable $d$ itself is computed as a nonlocal extension of an
16+
external scalar damage model defined by the `local_damage_model`
17+
and `average_UO` input parameters. Where `average_UO` is a RadialAverage user
18+
object that defines the nonlocal averaging properties. The damage value is
19+
delayed by a single `execte_on` (timestep or nonlinear).
20+
21+
22+
!syntax parameters /Materials/ADNonLocalDamage
23+
24+
!syntax inputs /Materials/ADNonLocalDamage
25+
26+
!syntax children /Materials/ADNonLocalDamage
27+
28+
!bibtex bibliography
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Scalar Material Damage
2+
3+
!syntax description /Materials/NonLocalDamage
4+
5+
## Description
6+
7+
`NonLocalDamage` is a model to define the effect of damage on the stress and stiffness in a continuum damage mechanics setting. It does not directly compute the stress, but must be used in conjunction with [ComputeDamageStress](/ComputeDamageStress.md).
8+
9+
This model is a scalar damage model in which the stress $\boldsymbol{\sigma}$ is computed as a function of the damage $d$, the original stiffness of the material $\mathbb{C}$ and the elastic strain $\boldsymbol{\varepsilon}$:
10+
11+
\begin{equation}
12+
\boldsymbol{\sigma} = (1 - d)\ \mathbb{C} : \boldsymbol{\varepsilon}
13+
\end{equation}
14+
15+
The damage variable $d$ itself is computed as a nonlocal extension of an
16+
external scalar damage model defined by the `local_damage_model`
17+
and `average_UO` input parameters. Where `average_UO` is a RadialAverage user
18+
object that defines the nonlocal averaging properties. The damage value is
19+
delayed by a single `execte_on` (timestep or nonlinear).
20+
21+
22+
!syntax parameters /Materials/NonLocalDamage
23+
24+
!syntax inputs /Materials/NonLocalDamage
25+
26+
!syntax children /Materials/NonLocalDamage
27+
28+
!bibtex bibliography
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
#pragma once
11+
12+
#include "MooseTypes.h"
13+
#include "ScalarDamageBase.h"
14+
#include "GuaranteeConsumer.h"
15+
#include "RadialAverage.h"
16+
17+
/**
18+
* Scalar damage model that defines the damage parameter using a material property
19+
*/
20+
template <bool is_ad>
21+
class NonLocalDamageTempl : public ScalarDamageBaseTempl<is_ad>, public GuaranteeConsumer
22+
{
23+
public:
24+
static InputParameters validParams();
25+
26+
NonLocalDamageTempl(const InputParameters & parameters);
27+
28+
virtual void initialSetup() override;
29+
30+
virtual void initQpStatefulProperties() override;
31+
32+
protected:
33+
virtual void updateQpDamageIndex() override;
34+
35+
// Averaged Material
36+
// std::string _avg_material_name;
37+
const RadialAverage::Result & _average;
38+
RadialAverage::Result::const_iterator _average_damage;
39+
40+
///{@ Local damage model needed for updating
41+
MaterialName _local_damage_model_name;
42+
ScalarDamageBaseTempl<is_ad> * _local_damage_model;
43+
///@}
44+
45+
// Pointer to last element for comparison for speed
46+
const Elem * _prev_elem;
47+
48+
///@{ Make hierarchy parameters available in this class
49+
using ScalarDamageBaseTempl<is_ad>::_damage_index;
50+
using ScalarDamageBaseTempl<is_ad>::_damage_index_name;
51+
using ScalarDamageBaseTempl<is_ad>::_damage_index_old;
52+
using ScalarDamageBaseTempl<is_ad>::_damage_index_older;
53+
using ScalarDamageBaseTempl<is_ad>::_qp;
54+
using ScalarDamageBaseTempl<is_ad>::_use_old_damage;
55+
using ScalarDamageBaseTempl<is_ad>::_dt;
56+
using ScalarDamageBaseTempl<is_ad>::_base_name;
57+
using ScalarDamageBaseTempl<is_ad>::_maximum_damage_increment;
58+
using ScalarDamageBaseTempl<is_ad>::_current_elem;
59+
using ScalarDamageBaseTempl<is_ad>::_JxW;
60+
using ScalarDamageBaseTempl<is_ad>::_coord;
61+
///@}
62+
};
63+
64+
typedef NonLocalDamageTempl<false> NonLocalDamage;
65+
typedef NonLocalDamageTempl<true> ADNonLocalDamage;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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 "NonLocalDamage.h"
11+
12+
registerMooseObject("MooseApp", NonLocalDamage);
13+
registerMooseObject("MooseApp", ADNonLocalDamage);
14+
15+
template <bool is_ad>
16+
InputParameters
17+
NonLocalDamageTempl<is_ad>::validParams()
18+
{
19+
InputParameters params = ScalarDamageBaseTempl<is_ad>::validParams();
20+
params.addClassDescription(
21+
"Nonlocal damage model. Given an RadialAverage UO this creates a new damage index that can "
22+
"be used as for ComputeDamageStress without havign to change existing local damage models.");
23+
params.addRequiredParam<UserObjectName>("average_UO", "Radial Average user object");
24+
params.addRequiredParam<MaterialName>("local_damage_model",
25+
"Name of the local damage model used to compute "
26+
"the nonlocal damage index");
27+
return params;
28+
}
29+
30+
template <bool is_ad>
31+
NonLocalDamageTempl<is_ad>::NonLocalDamageTempl(const InputParameters & parameters)
32+
: ScalarDamageBaseTempl<is_ad>(parameters),
33+
GuaranteeConsumer(this),
34+
_average(this->template getUserObject<RadialAverage>("average_UO").getAverage()),
35+
_local_damage_model_name(this->template getParam<MaterialName>("local_damage_model")),
36+
_prev_elem(nullptr)
37+
{
38+
}
39+
template <bool is_ad>
40+
void
41+
NonLocalDamageTempl<is_ad>::initialSetup()
42+
{
43+
_local_damage_model = dynamic_cast<ScalarDamageBaseTempl<is_ad> *>(
44+
&this->getMaterialByName(_local_damage_model_name));
45+
46+
if (!_local_damage_model)
47+
this->template paramError("damage_model",
48+
"Damage Model " + _local_damage_model_name +
49+
" is not compatible with NonLocalDamage model");
50+
}
51+
52+
template <bool is_ad>
53+
void
54+
NonLocalDamageTempl<is_ad>::initQpStatefulProperties()
55+
{
56+
ScalarDamageBaseTempl<is_ad>::initQpStatefulProperties();
57+
}
58+
59+
template <bool is_ad>
60+
void
61+
NonLocalDamageTempl<is_ad>::updateQpDamageIndex()
62+
{
63+
// First update underlying local damage model
64+
_local_damage_model->getQpDamageIndex(_qp);
65+
// Now update the nonlocal damage model
66+
// Only update iterator when we change to another element. This is for
67+
// computational costs related to map lookup.
68+
if (_prev_elem != _current_elem)
69+
{
70+
_average_damage = _average.find(_current_elem->id());
71+
_prev_elem = _current_elem;
72+
}
73+
// Make sure that we find the new element if not return 0
74+
if (_average_damage != _average.end())
75+
// return max of the old damage or new average damage
76+
_damage_index[_qp] = std::max(_average_damage->second[_qp], _damage_index_old[_qp]);
77+
else
78+
// during startup the map is not made yet or
79+
// if AMR is used then the new element will not be found but it should
80+
// already have an old nonlocal damage value that needs to perserved
81+
_damage_index[_qp] = std::max(0.0, _damage_index_old[_qp]);
82+
}
83+
84+
template class NonLocalDamageTempl<false>;
85+
template class NonLocalDamageTempl<true>;

0 commit comments

Comments
 (0)