Update#
import numpy as np
def nodal_total_force(mesh): “”” Compute total force as sum of internal, external and damping force.
Arguments:
mesh: mesh
a mesh object
"""
for node in mesh.nodes:
# Total force
node.f_total = node.f_int + node.f_ext + node.f_damp
def nodal_acceleration_velocity(mesh, dt):
“””
Compute nodal acceleration as :math:a = f / m
and v += a * dt
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for node in mesh.nodes:
# Total force
f_total = node.f_int + node.f_ext + node.f_damp
# Accleration
node.acc = f_total / node.mass if node.mass > 0 else 0.
# Velocity
node.velocity += node.acc * dt
def nodal_velocity(mesh):
“””Compute nodal velocity as :math:v = mv / m
.
Arguments:
mesh: mesh
a mesh object
"""
for node in mesh.nodes:
if(node.mass > 0.):
node.velocity = node.momentum / node.mass
def fix_nodal_bc_momentum(mesh): “””Set momentum and velocity to zero on specific boundary nodes.
Arguments:
mesh: mesh
a mesh object
"""
for nid in mesh.boundary_nodes:
mesh.nodes[nid].momentum = 0
mesh.nodes[nid].velocity = 0
def fix_nodal_bc_force(mesh): “””Set nodal force to zero on specific boundary nodes.
Arguments:
mesh: mesh
a mesh object
"""
for nid in mesh.boundary_nodes:
mesh.nodes[nid].f_total = 0
def momentum_in_nodes(mesh, dt):
“””Compute momentum in nodes. :math:mv += force * dt
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for node in mesh.nodes:
node.momentum += node.f_total * dt
def nodal_momentum(mesh):
“””
Update nodal momentum :math:(mv)_i = \sum_p N_i(x_p) * m_p * v_p
.
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for node in mesh.nodes:
node.momentum = 0
for el in mesh.elements:
for prtcl in el.particles:
for i in range(el.nnodes):
el.nodes[i].momentum += prtcl.mass * prtcl.velocity * prtcl.shapefn[i]
def reset_nodal_values(mesh): “””Reset nodal values at the end of the iteration. Reset mesh. “”” for node in mesh.nodes: node.reset_values()
def particle_strain_increment(mesh,dt): “”” Particle strain increment. Compute strain based on nodal velocity.
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for particle in mesh.particles:
particle.compute_strain(dt)
def particle_velocity(mesh, dt):
“””
Compute particle velocity transfer nodal velocity to particle. :math:v_p += \sum_i N_i(x_p) * {f_{total}}_i/m_i * dt
.
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for el in mesh.elements:
for prtcl in el.particles:
for i in range(el.nnodes):
prtcl.velocity += el.nodes[i].f_total/el.nodes[i].mass * prtcl.shapefn[i] * dt
def particle_position(mesh, dt):
“””
Compute particle position based on nodal momentum to particle. :math:x_p += \sum_i N_i(x_p) * {mv}_i/m_i * dt
.
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for el in mesh.elements:
for prtcl in el.particles:
for i in range(el.nnodes):
prtcl.x += el.nodes[i].momentum/el.nodes[i].mass * prtcl.shapefn[i] * dt
def particle_position_velocity(mesh, dt):
“””
Compute particle position and velocity based on nodal velocity. :math:x_p += \sum_i N_i(x_p) * v_i
and particle position :math:x_p += v_p * dt
.
Arguments:
mesh: mesh
a mesh object
dt: float
time step
"""
for el in mesh.elements:
for prtcl in el.particles:
prtcl.velocity = 0
for i in range(len(el.nodes)):
prtcl.velocity += prtcl.shapefn[i] * el.nodes[i].velocity
prtcl.x += prtcl.velocity * dt
def particle_volume_density(mesh):
“””
Compute particle volume from :math:V_p *= (1 + d\epsilon)
and :math:density = density / (1 + \epsilon)
Arguments:
mesh: mesh
a mesh object
"""
for prtcl in mesh.particles:
prtcl.volume *= (1 + prtcl.dstrain)
prtcl.density = prtcl.density / (1 + prtcl.dstrain)
def particle_stress(mesh): “””Update particle stress based on dstrain.
Arguments:
mesh: mesh
a mesh object
"""
for particle in mesh.particles:
particle.material.update_stress(particle)
def locate_particles(mesh): “””Locate particle in the mesh and compute xi (natural coordinates) of the material points.
Arguments:
mesh: mesh
a mesh object
"""
# clear particle list in elements
for element in mesh.elements:
element.particles = []
for prtcl in mesh.particles:
# get particle position
xp = prtcl.x
# for each element in mesh
for el in mesh.elements:
# verify the particle is inside the element
prcl_in_cell, xi = el.compute_xi(xp)
ncoords = np.array([node.x for node in el.nodes])
if (prcl_in_cell):
# update particle xi
prtcl.xi = xi
# update element in particle
prtcl.element = el
# update particle shapefns and grads
prtcl.shapefn = el.shapefn.sf(xi)
prtcl.dn_dx = el.shapefn.dn_dx(xi, ncoords)
# add the particle to the element list
el.particles.append(prtcl)
# break element loop for testing other particle
break