@@ -17,9 +17,11 @@ consistent (correspondence) formulation of non-ordinary state-based peridynamics
1717 - [`NeoHooke`](@ref)
1818 - [`MooneyRivlin`](@ref)
1919 - [`SaintVenantKirchhoff`](@ref)
20- - `zem::AbstractZEMStabilization`: Zero-energy mode stabilization. The
21- stabilization algorithm of Silling (2017) is used as default. \\
22- (default: [`ZEMSilling`](@ref))
20+ - `zem::AbstractZEMStabilization`: Algorithm of zero-energy mode stabilization. \\
21+ (default: [`ZEMSilling`](@ref)) \\
22+ The following algorithms can be used:
23+ - [`ZEMSilling`](@ref)
24+ - [`ZEMWan`](@ref)
2325- `dmgmodel::AbstractDamageModel`: Damage model defining the damage behavior. \\
2426 (default: [`CriticalStretch`](@ref))
2527- `maxdmg::Float64`: Maximum value of damage a point is allowed to obtain. If this value is
@@ -106,7 +108,7 @@ When specifying the `fields` keyword of [`Job`](@ref) for a [`Body`](@ref) with
106108struct CMaterial{CM,ZEM,K,DM} <: AbstractCorrespondenceMaterial{CM,ZEM}
107109 kernel:: K
108110 constitutive_model:: CM
109- zem_stabilization :: ZEM
111+ zem :: ZEM
110112 dmgmodel:: DM
111113 maxdmg:: Float64
112114 function CMaterial (kernel:: K , cm:: CM , zem:: ZEM , dmgmodel:: DM ,
@@ -132,15 +134,38 @@ function log_material_property(::Val{:constitutive_model}, mat; indentation)
132134 return msg_qty (" constitutive model" , mat. constitutive_model; indentation)
133135end
134136
135- function log_material_property (:: Val{:zem_stabilization } , mat; indentation)
136- return msg_qty (" zero-energy mode stabilization" , mat. zem_stabilization ; indentation)
137+ function log_material_property (:: Val{:zem } , mat; indentation)
138+ return msg_qty (" zero-energy mode stabilization" , mat. zem ; indentation)
137139end
138140
139141function log_material_property (:: Val{:maxdmg} , mat; indentation)
140142 return msg_qty (" maximum damage" , mat. maxdmg; indentation)
141143end
142144
143- @params CMaterial StandardPointParameters
145+ struct CPointParameters <: AbstractPointParameters
146+ δ:: Float64
147+ rho:: Float64
148+ E:: Float64
149+ nu:: Float64
150+ G:: Float64
151+ K:: Float64
152+ λ:: Float64
153+ μ:: Float64
154+ Gc:: Float64
155+ εc:: Float64
156+ bc:: Float64
157+ C:: MArray{NTuple{4,3},Float64,4,81}
158+ end
159+
160+ function CPointParameters (mat:: AbstractMaterial , p:: Dict{Symbol,Any} )
161+ (; δ, rho, E, nu, G, K, λ, μ) = get_required_point_parameters (mat, p)
162+ (; Gc, εc) = get_frac_params (mat. dmgmodel, p, δ, K)
163+ bc = 18 * K / (π * δ^ 4 ) # bond constant
164+ C = get_hooke_matrix (nu, λ, μ)
165+ return CPointParameters (δ, rho, E, nu, G, K, λ, μ, Gc, εc, bc, C)
166+ end
167+
168+ @params CMaterial CPointParameters
144169
145170@storage CMaterial struct CStorage
146171 @lthfield position:: Matrix{Float64}
@@ -187,13 +212,12 @@ function force_density_point!(storage::AbstractStorage, system::AbstractSystem,
187212 defgrad_res = calc_deformation_gradient (storage, system, mat, params, i)
188213 too_much_damage! (storage, system, mat, defgrad_res, i) && return nothing
189214 PKinv = calc_first_piola_kirchhoff! (storage, mat, params, defgrad_res, Δt, i)
190- zem = mat. zem_stabilization
191- c_force_density! (storage, system, mat, params, zem, PKinv, defgrad_res, i)
215+ c_force_density! (storage, system, mat, params, mat. zem, PKinv, defgrad_res, i)
192216 return nothing
193217end
194218
195219function calc_deformation_gradient (storage:: CStorage , system:: BondSystem , :: CMaterial ,
196- :: StandardPointParameters , i)
220+ :: CPointParameters , i)
197221 (; bonds, volume) = system
198222 (; bond_active) = storage
199223 K = zero (SMatrix{3 ,3 ,Float64,9 })
@@ -217,7 +241,7 @@ function calc_deformation_gradient(storage::CStorage, system::BondSystem, ::CMat
217241end
218242
219243function calc_first_piola_kirchhoff! (storage:: CStorage , mat:: CMaterial ,
220- params:: StandardPointParameters , defgrad_res, Δt, i)
244+ params:: CPointParameters , defgrad_res, Δt, i)
221245 (; F, Kinv) = defgrad_res
222246 P = first_piola_kirchhoff (mat. constitutive_model, storage, params, F)
223247 PKinv = P * Kinv
@@ -252,6 +276,40 @@ function c_force_density!(storage::AbstractStorage, system::AbstractSystem,
252276 return nothing
253277end
254278
279+ function c_force_density! (storage:: AbstractStorage , system:: AbstractSystem ,
280+ mat:: AbstractCorrespondenceMaterial ,
281+ params:: AbstractPointParameters , zem:: ZEMWan , PKinv, defgrad_res,
282+ i)
283+ (; bonds, volume) = system
284+ (; bond_active) = storage
285+ (; F) = defgrad_res
286+ C_1 = calc_zem_stiffness_tensor! (storage, system, mat, params, zem, defgrad_res, i)
287+ for bond_id in each_bond_idx (system, i)
288+ bond = bonds[bond_id]
289+ j = bond. neighbor
290+ ΔXij = get_vector_diff (system. position, i, j)
291+ Δxij = get_vector_diff (storage. position, i, j)
292+
293+ # improved stabilization from this article:
294+ # https://doi.org/10.1007/s10409-019-00873-y
295+ ωij = kernel (system, bond_id) * bond_active[bond_id]
296+ tzem = ωij * C_1 * (Δxij .- F * ΔXij)
297+
298+ # update of force density
299+ tij = ωij * PKinv * ΔXij + tzem
300+ update_add_vector! (storage. b_int, i, tij .* volume[j])
301+ update_add_vector! (storage. b_int, j, - tij .* volume[i])
302+ end
303+ return nothing
304+ end
305+
306+ function calc_zem_stiffness_tensor! (storage:: CStorage , system:: BondSystem , mat:: CMaterial ,
307+ params:: CPointParameters , zem:: ZEMWan , defgrad_res, i)
308+ (; Kinv) = defgrad_res
309+ C_1 = calc_zem_stiffness_tensor (params. C, Kinv)
310+ return C_1
311+ end
312+
255313function too_much_damage! (storage:: AbstractStorage , system:: AbstractSystem ,
256314 mat:: AbstractCorrespondenceMaterial , defgrad_res, i)
257315 (; F) = defgrad_res
0 commit comments