@@ -154,28 +154,28 @@ def __init__(self, material_properties):
154154 ---------
155155 material_properties: dict
156156 Dictionary with material properties. For Bingham
157- material, 'density','youngs_modulus','poisson_ratio','tau0','mu'
158- and 'critical_shear_rate' are required keys.
159-
160- ndim: int
161- Dimension of the problem supports 1D and 2D
157+ material, 'density','youngs_modulus','poisson_ratio','tau0','mu',
158+ 'ndim and 'critical_shear_rate' are required keys.
159+
160+ Methods
161+ -------
162+ initialise_state_variables
163+ Initialises the state variables for the Bingham material
164+ compute_stress
165+ computes the stress for the Bingham material particles
166+
162167 """
163168 self .validate_props (material_properties )
164169 self .ndim = material_properties ["ndim" ]
165- density = material_properties ["density" ]
166170 youngs_modulus = material_properties ["youngs_modulus" ]
167171 poisson_ratio = material_properties ["poisson_ratio" ]
168- tau0 = material_properties ["tau0" ]
169- mu_ = material_properties ["mu" ]
170- critical_shear_rate = material_properties ["critical_shear_rate" ]
172+ self .state_variables = ["pressure" ]
171173 # Calculate the bulk modulus
172174 bulk_modulus = youngs_modulus / (3.0 * (1.0 - 2.0 * poisson_ratio ))
173175 compressibility_multiplier_ = 1.0
174176 # Special Material Properties
175- if "incompressible" in material_properties :
176- incompressible = material_properties ["incompressible" ]
177- if incompressible :
178- compressibility_multiplier_ = 0.0
177+ if material_properties .get ("incompressible" , False ):
178+ compressibility_multiplier_ = 0.0
179179 self .properties = {
180180 ** material_properties ,
181181 "bulk_modulus" : bulk_modulus ,
@@ -191,16 +191,30 @@ def initialise_state_variables(particles):
191191 state_vars ["pressure" ] = jnp .zeros ((particles .loc .shape [0 ]))
192192 return state_vars
193193
194- # State Variables
195- def state_variables ():
196- return ["pressure" ]
197-
198194 # Compute the pressure
199- def thermodynamic_pressure (self , volumetric_strain ):
195+ def __thermodynamic_pressure (self , volumetric_strain ):
200196 return - self .properties ["bulk_modulus" ] * volumetric_strain
201197
202198 # Compute the stress
203- def compute_stress (self , dstrain , particles , state_vars ):
199+ def compute_stress (self , dstrain , particles , state_vars :dict ):
200+ """
201+ Computes the stress for the Bingham material
202+
203+ Arguments
204+ ---------
205+ dstrain: array_like
206+ The strain rate tensor for the particles
207+ particles: diffmpm.particles.Particles
208+ state_vars: dict {str: jnp.ndarray}
209+ dictionary containig the string as the name of the
210+ property and the jnp.ndarray shape (nparticles, 1) as the
211+ values of the property at each particle.
212+
213+ Returns
214+ -------
215+ updated_stress: jnp.ndarray
216+ The updated stress for the particles expected shape (nparticles, 6,1)
217+ """
204218 shear_rate_threshold = 1e-15
205219 # dirac delta in Voigt notation
206220 dirac_delta = jnp .array ([0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ]).reshape ((6 , 1 ))
@@ -218,7 +232,7 @@ def compute_stress(self, dstrain, particles, state_vars):
218232 )
219233
220234 @jit
221- def compute_stress_per_particle (
235+ def __compute_stress_per_particle (
222236 particle_strain_rate ,
223237 self ,
224238 state_vars_pressure ,
@@ -228,21 +242,20 @@ def compute_stress_per_particle(
228242 strain_r = particle_strain_rate
229243 # Convert strain rate to rate of deformation tensor
230244 strain_r = strain_r .at [- 3 :].multiply (0.5 )
231- """
232- Rate of shear = sqrt(2 * D_ij * D_ij)
233- Since D (D_ij) is in Voigt notation (D_i), and the definition above is in
234- matrix, the last 3 components have to be doubled D_ij * D_ij = D_0^2 +
235- D_1^2 + D_2^2 + 2*D_3^2 + 2*D_4^2 + 2*D_5^2 Yielding is defined: rate of
236- shear > critical_shear_rate_^2 Checking yielding from strain rate vs
237- critical yielding shear rate
238- """
245+
246+ # Rate of shear = sqrt(2 * Strain_r_ij * Strain_r_ij)
247+ # Strain_r is in Voigt notation so the above formula reduces in the voigt notation to
248+ # sqrt(Strain_r_0^2 + Strain_r_1^2 + Strain_r_2^2 + 2*Strain_r_3^2
249+ # + 2*Strain_r_4^2 + 2*Strain_r_5^2)
250+ # When shear rate> critical_shear_rate^2 then the material is yielding
251+
239252 shear_rate = jnp .sqrt (
240253 2.0 * (strain_r .T @ (strain_r ) + strain_r [- 3 :].T @ strain_r [- 3 :])
241254 )
242- """
243- Apparent_viscosity maps shear rate to shear stress
244- Check if shear rate is 0
245- """
255+
256+ # Apparent_viscosity maps shear rate to shear stress
257+ # Check if shear rate is 0
258+
246259 apparent_viscosity_true = 2.0 * (
247260 (self .properties ["tau0" ] / shear_rate [0 , 0 ]) + self .properties ["mu" ]
248261 )
@@ -251,17 +264,15 @@ def compute_stress_per_particle(
251264 * self .properties ["critical_shear_rate" ]
252265 )
253266 apparent_viscosity = lax .select (condition , apparent_viscosity_true , 0.0 )
254- """
255- Compute shear change to volumetric
256- tau deviatoric part of cauchy stress tensor
257- """
267+
268+ # Compute volumetric tau
269+
258270 tau = apparent_viscosity * strain_r
259- """
260- von Mises criterion
261- trace of second invariant J2 of deviatoric stress in matrix form
262- Since tau is in Voigt notation, only the first three numbers matter
263- yield condition trace of the invariant > tau0^2
264- """
271+ # von Mises criterion
272+ # yield condition trace of the invariant > tau0^2
273+ # and trace can be found using the first 3 numbers of tau
274+ # as tau is in voigt notation
275+
265276 trace_invariant = 0.5 * jnp .dot (tau [:3 , 0 ], tau [:3 , 0 ])
266277 tau = lax .cond (
267278 trace_invariant < (self .properties ["tau0" ] * self .properties ["tau0" ]),
@@ -272,23 +283,26 @@ def compute_stress_per_particle(
272283 # update pressure
273284 state_vars_pressure += self .properties [
274285 "compressibility_multiplier"
275- ] * self .thermodynamic_pressure (dvolumetric_strain_per_particle )
276- """
277- Update volumetric and deviatoric stress
278- thermodynamic pressure is from material point
279- stress = -thermodynamic_pressure I + tau, where I is identity matrix or
280- direc_delta in Voigt notation
281- """
286+ ] * self .__thermodynamic_pressure (dvolumetric_strain_per_particle )
287+
288+ # Update volumetric and deviatoric stress
289+ # thermodynamic pressure is from material point
290+ # stress = -thermodynamic_pressure I + tau, where I is identity matrix or
291+ # direc_delta in Voigt notation
292+
282293 updated_stress_per_particle = (
283294 - (state_vars_pressure )
284295 * dirac_delta
285296 * self .properties ["compressibility_multiplier" ]
286297 + tau
287298 )
288299 return updated_stress_per_particle , state_vars_pressure
289-
300+
301+ # using vmap to vectorise the function compute stress per particle
302+ # for all the particles using the first dimension of the strain rate
303+ # and the dvolumetric_strain and state_vars pressure
290304 updated_stress , state_vars ["pressure" ] = vmap (
291- compute_stress_per_particle , in_axes = (0 , None , 0 , 0 , None )
305+ __compute_stress_per_particle , in_axes = (0 , None , 0 , 0 , None )
292306 )(
293307 particles .strain_rate ,
294308 self ,
0 commit comments