I found Peridynamics to be unsuitable:
Checkout my implementation with PeriFlakes:
https://github.com/afqueiruga/PeriFlakes
The Jupyter notebook replicates the graphs in this presentation.
Today, I'm going to talk about the path I took to make those determinations, and discuss the stabilization around fracture tips.
Shale natural gas, Enhanced geothermal, Escape of gasses from nuclear waste, Bubbling of methane through oceanic sediments
It looks good, but not under actual scrutiny:
Queiruga, A. F. and G. J. Moridis, "Numerical experiments on the convergence properties of state-based peridynamic laws and influence functions in two-dimensional problems." Computer Methods in Applied Mechanics and Engineering 322 (2017): 97-122.
It is critical to verify and validate numerical methods on known solutions and expected discretization refinement behavior.
It is well known that bond-based does not work due to $\nu$ problem.
The are two classes of state-based models:
Our goal is to obtain a computer program that solves the problems we want accurately and efficiently.
In the Peridynamics scope, we have the following hyperparameters:
These are arbitrary. We need to determine which combinations are acceptable, and which of those are the best.
https://github.com/afqueiruga/PeriFlakes
Alejandro Francisco Queiruga. (2018). 2D Peridynamic Displacement Fields [Data set]. Zenodo. http://doi.org/10.5281/zenodo.1284634
(I'm still working; it'll be 100% done by WCCM)
The file peri_kernels_pop.py
contains object-oriented implementations like this:
class Oterkus(StateBased):
def m_expr(self):
return self.w0I * alpha_I * rxabs
def a_expr(self):
return self.w0I * alpha_I * rxabs**2
def b_expr(self):
return self.w0I * alpha_I * (xn[0] * xn[1] )**2 * rxabs**2
def theta_expr(self):
return 2/m[0] * self.w0I * alpha_I * (ryabs-rxabs) * (yn.T*xn)[0,0]
def force(self):
a = (c_K - 2*c_G*a_integ[0]/b_denom[0])/2
b = c_G /( 2* b_denom[0])
A = 2 * self.w0I* alpha_I * ( a*2/m[0]*(yn.T*xn)[0,0]*theta[0] + b*(ryabs-rxabs) )
return A * yn
We want to exhaustively search for methods:
formulations = {
'Silling' : StateBased,
'Oterkus2': Oterkus,
'Fbased':Fbased,
'Fstab_Littlewood':Fstab_Littlewood,
'Fstab_Silling':Fstab_Silling,
}
delta = i_delta[0]
weight_funcs = {
'const' : lambda r : Piecewise( (1.0 , Le(r,delta)), (0.0,True)),
'inv' : lambda r : Piecewise( (delta/r, Le(r,delta)), (0.0,True)),
'linear': lambda r : Piecewise( ((1.0-r / delta)**1.0, Le(r,delta)), (0.0,True)),
'quadr' : lambda r : Piecewise( ((1.0-r / delta)**2.0, Le(r,delta)), (0.0,True)),
'cubic' : lambda r : Piecewise( ((1.0-r / delta)**3.0, Le(r,delta)), (0.0,True)),
'quarticA':lambda r: Piecewise( (1.0 - 6.0*(r/delta)**2 + 8.0*(r/delta)**3 - 3.0*(r/delta)**4, Le(r,delta)), (0.0,True))
}
for methodname,c in formulations.iteritems():
for weightname,f in weight_funcs.iteritems():
c(methodname+"_"+weightname, f).kernel()
This generates 30 different methods with only 240 lines of code!
isotropic | shear | uniaxial | |
Fbased | 0.998518471486 | 0.88580762397 | 0.961508949756 |
Oterkus2 | -0.0934425713562 | 0.992619961121 | -0.133199906094 |
Silling | 0.940215702548 | -0.155718080685 | -0.120152361872 |
We need to check for convergence to analytical solutions.
\begin{equation}
\hat{Z}\left(z = x+iy\right)=P\left(\sqrt{z^{2}-L^{2}}-z\right)
\end{equation}
\begin{equation} u_{x} = \frac{1}{2G}\left(\frac{2-4\nu}{2}\mathrm{Re}\left[\hat{Z}\right]-y\mathrm{Im}\left[Z\right]\right) \end{equation} \begin{equation} u_{y} = \frac{1}{2G}\left(\frac{4-4\nu}{2}\mathrm{Im}\left[\hat{Z}\right]-y\mathrm{Re}\left[Z\right]\right) \end{equation}
Calculate an error to judge numerical solution $u^N$: \begin{equation} e = \frac{ \int \left|u^N-u^a \right|^2 \mathrm{d}x }{ \int \left|u^a \right|^2 \mathrm{d}x } \end{equation}
The F-based method's instability effects bond stretches, making the fracture branch and jump nonphysically.
My ad hoc approach was to post process the solution: \begin{equation} \mathbf{u}^s = \frac{\int_\mathcal{H} w^s \alpha \mathbf{u} \mathrm{d}x'}{\int_\mathcal{H} w^s \alpha \mathrm{d}x'} \end{equation}
The smoothing kernel $w^s$ doesn't have to be the same $w$.
This worked to stabilize the fracture path in my original hydraulic fracturing simulations, but the method never passed any other validations!
We can add a stabilizer to the force: \begin{equation} \mathbf{T}\left<\xi\right> = w\alpha \sigma \mathbf{K}^{-1} \mathbf{\xi} + \mathbf{T}^s \end{equation}
Silling's 2017 paper: \begin{equation} \mathbf{T}^s = w\alpha A \frac{18 K}{ w_0 \pi \delta^5} \left( \mathbf{Y} - \mathbf{F}\xi \right), \quad w_0 = \int_\mathcal{H} w\alpha \mathrm{d}x' \end{equation}
Littlewood's 2010 paper: \begin{equation} \mathbf{T}^s = w\alpha A \frac{18 K}{\pi \delta^4} \left( \frac{ \left|\mathbf{Y}\right| - \left|\mathbf{F}\xi\right| }{ \left|\xi\right| } \right) \frac{\mathbf{Y}}{\left|\mathbf{Y}\right|} \end{equation}
$A$ is a new penalty hyperparameter. It would be nice if it were insensitive to the grid size.
Smoothing with a cubic function.
All of the functions are about the same.
Set $A = 2.0$
Looks grid-size invariant, best around 1.
Set $A=10.0$
Needed to sweep higher.
We're searching for a numerical method that:
Compare to a discretely meshed fracture solved by FEM:
PeriFlakes/fem/fem_crack.py
Wall-clock time for matrix/vector assemble + solve.
FEM solves a smaller length scale faster!
We can churn out and test more Peridynamics models in PeriFlakes!
Email: afqueiruga@lbl.gov
Checkout my codes at
https://github.com/afqueiruga/PeriFlakes
and look at the Jupyter notebook and Zenodo database.
I have another upcoming talk at WCCM in July:
#2018172, Numerical Experiments on the Convergence Properties of State-based Peridynamic Laws and Influence Functions in Two-Dimensional Problems