import itasca as it
it.command("python-reset-state false")
from itasca import ballarray as ba
from itasca import ball as balls
from itasca import contact as contacts
import numpy as np
it.command("""
model new
model large-strain on
model domain extent -1 1 -1 1 -1 1
contact cmat default model linearpbond property pb_ten 12.0e6 pb_coh 10.0e6 pb_fa 20.0 fric 0.5 ...
method deformability emod 8.5e9 kratio 2.5 ...
method pb_deformability emod 8.5e9 kratio 2.5 ...
proximity 4e-4
""")
box_len = 38.1e-3
data = np.loadtxt("balls.txt",delimiter=",")
for datum in data:
r, p, fix = datum[0],datum[1:4], datum[4]
b = balls.create(r, p)
if fix == 1.0:
if b.pos_z() > 0.0:
b.set_extra(1, 1)
else:
b.set_extra(1, 2)
else:
b.set_extra(1,0)
it.command("""
ball attribute density 2000.0 damp 0.6
model clean
contact method bond gap 4e-4
contact property lin_mode 1
contact cmat default proximity 0.0
model clean all
""")
print ("This model has {} contacts".format(it.contact.count()))
for name, value in it.contact.find(it.BallBallContact, 1).props().items():
print ("{:15}: {}".format(name, value))
vel = 1e-2
top_count = 0
bottom_count = 0
for b in balls.list():
if b.extra(1) == 1:
b.set_vel_z(-vel)
b.set_fix(3, True)
top_count += 1
elif b.extra(1) == 2:
b.set_vel_z(0)
b.set_fix(3,True)
bottom_count += 1
print ("{} top boundary particles and {} bottom boundary particles".format(top_count, bottom_count))
top_mask = np.array([b.extra(1) == 1 for b in balls.list()])
bottom_mask = np.array([b.extra(1) == 2 for b in balls.list()])
boundary_mask = np.logical_or(top_mask, bottom_mask)
top_mask = np.array([b.extra(1) == 1 for b in balls.list()])
bottom_mask = np.array([b.extra(1) == 2 for b in balls.list()])
boundary_mask = np.logical_or(top_mask, bottom_mask)
r"""Create some (empty) lists to store the time and unbalanced forces
during the UCS test. """
strain = []
stress = []
top_mask = np.array([b.extra(1) == 1 for b in balls.list()])
bottom_mask = np.array([b.extra(1) == 2 for b in balls.list()])
boundary_mask = np.logical_or(top_mask, bottom_mask)
r"""Create some (empty) lists to store the time and unbalanced forces
during the UCS test. """
strain = []
stress = []
r"""We use the matplotlib.pylab module to create a plot of the stress versus strain response of the model
during the UCS test. """
import matplotlib.pylab as plt
area = box_len**2
plt.plot(strain, stress)
plt.title("Stress vs Strain")
plt.xlabel("Strain [%]")
plt.ylabel("Stress [MPa]")
plt.grid(True)
plt.draw()
def store_force(*args):
"""This function is called during |pfc| cycling to record the stress
strain curve.
"""
if it.cycle() % 100: return
strain.append(vel*it.mech_age()*100.0/box_len)
stress.append(abs(ba.force_unbal()[boundary_mask][:,2]).sum()/2.0/area/1e6)
plt.gca().clear()
plt.xlabel("Strain [%]")
plt.ylabel("Stress [MPa]")
plt.grid(True)
plt.plot(strain, stress)
plt.draw()
it.set_callback("store_force", 43.0)
it.command("model cycle 40000")
speak = np.amax(stress)
ipeak = np.argmax(stress)
epeak = strain[ipeak]/100.0
i50 = int(0.5*ipeak)
s50 = stress[i50]*1e6
e50 = strain[i50]/100.0
emod50 = s50 / e50 / 1e9
txtE = r'$E_{{50}}={:.1f} GPa$'.format(emod50)
txtS = r'$UCS = {:.1f} MPa$'.format(speak)
plt.text(0.25*100*e50,0.5*speak, txtE,fontsize=12)
plt.text(0.75*100*epeak,1.01*speak, txtS,fontsize=12)
plt.draw()
plt.savefig('p3d-test-ucs.png')
plt.close('all')