PeriDyno 1.0.0
Loading...
Searching...
No Matches
FractureModule.cu
Go to the documentation of this file.
1#include "FractureModule.h"
2
3#include "ParticleSystem/Module/SummationDensity.h"
4#include "ParticleSystem/Module/Kernel.h"
5
6namespace dyno
7{
8 IMPLEMENT_TCLASS(FractureModule, TDataType)
9
10 template<typename TDataType>
11 FractureModule<TDataType>::FractureModule()
12 : ElastoplasticityModule<TDataType>()
13 {
14 }
15
16 template <typename Real, typename Coord, typename Bond>
17 __global__ void PM_ComputeInvariants(
18 DArray<Real> bulk_stiffiness,
19 DArray<Coord> X,
20 DArray<Coord> Y,
21 DArrayList<Bond> bonds,
22 Real horizon,
23 Real A,
24 Real B,
25 Real mu,
26 Real lambda)
27 {
28 int i = threadIdx.x + (blockIdx.x * blockDim.x);
29 if (i >= Y.size()) return;
30
31 CorrectedKernel<Real> kernSmooth;
32
33 Real s_A = A;
34
35 List<Bond>& bonds_i = bonds[i];
36 Coord x_i = X[i];
37 Coord y_i = Y[i];
38
39 Real I1_i = 0.0f;
40 Real J2_i = 0.0f;
41
42 //compute the first and second invariants of the deformation state, i.e., I1 and J2
43 int size_i = bonds_i.size();
44 Real total_weight = Real(0);
45 for (int ne = 1; ne < size_i; ne++)
46 {
47 Bond bond_ij = bonds_i[ne];
48 int j = bond_ij.idx;
49 Coord x_j = X[j];
50
51 Real r = (x_i - x_j).norm();
52
53 if (r > 0.01*horizon)
54 {
55 Real weight = kernSmooth.Weight(r, horizon);
56 Coord p = (Y[j] - y_i);
57 Real ratio_ij = p.norm() / r;
58
59 I1_i += weight*ratio_ij;
60
61 total_weight += weight;
62 }
63 }
64
65 if (total_weight > EPSILON)
66 {
67 I1_i /= total_weight;
68 }
69 else
70 {
71 I1_i = 1.0f;
72 }
73
74 for (int ne = 0; ne < size_i; ne++)
75 {
76 Bond bond_ij = bonds_i[ne];
77 int j = bond_ij.idx;
78 Coord x_j = X[j];
79 Real r = (x_i - x_j).norm();
80
81 if (r > 0.01*horizon)
82 {
83 Real weight = kernSmooth.Weight(r, horizon);
84 Vec3f p = (Y[j] - y_i);
85 Real ratio_ij = p.norm() / r;
86 J2_i = (ratio_ij - I1_i)*(ratio_ij - I1_i)*weight;
87 }
88 }
89 if (total_weight > EPSILON)
90 {
91 J2_i /= total_weight;
92 J2_i = sqrt(J2_i);
93 }
94 else
95 {
96 J2_i = 0.0f;
97 }
98
99 Real D1 = 1 - I1_i; //positive for compression and negative for stretching
100
101 Real s_J2 = J2_i*mu*bulk_stiffiness[i];
102 Real s_D1 = D1*lambda*bulk_stiffiness[i];
103
104 //Drucker-Prager yield criterion
105 if (s_J2 > s_A + B*s_D1)
106 {
107 bulk_stiffiness[i] = 0.0f;
108 }
109 }
110
111 template<typename TDataType>
112 void FractureModule<TDataType>::applyPlasticity()
113 {
114 int num = this->inY()->size();
115 uint pDims = cudaGridSize(num, BLOCK_SIZE);
116
117 Real A = this->computeA();
118 Real B = this->computeB();
119
120 PM_ComputeInvariants<< <pDims, BLOCK_SIZE >> > (
121 this->mBulkStiffness,
122 this->inX()->getData(),
123 this->inY()->getData(),
124 this->inBonds()->getData(),
125 this->inHorizon()->getData(),
126 A,
127 B,
128 this->varMu()->getData(),
129 this->varLambda()->getData());
130 cuSynchronize();
131 }
132
133 DEFINE_CLASS(FractureModule);
134}