yade-users team mailing list archive
-
yade-users team
-
Mailing list archive
-
Message #25066
[Question #695734]: no softening behavior of cpm in tension test
New question #695734 on Yade:
https://answers.launchpad.net/yade/+question/695734
hello everyone,
I am trying to calibrate the concrete by using cpm. But I find that no matter how I adjust the parameters (eg, epsCrackOnset, relductility), the uniaxial tension test in model always have a linear elastic state and then followed by a sharp drop in stress-strain diagram, the tangent of the stress decrease is almost 90 degree. But in experiment data, there should be a softening part after the peak stress. The model seems so too 'brittle'. Is it because of the interaction enlarge factor? I took 1.5 as recommended.
I try to reduce the factor to 1.1, 1.05,etc and the model start to have softening behavior but the elastic modulus has a huge decrease from 180 to 50 MPa. and I have to increase the young's to a very large value in order to match the elastic modulus, but then I found excessive long hardening curve before the peak, which should be there. Any advice or thoughts is welcomed! (the code attach below may take 2-3hr to finish at current strainrate). Thanks!!!
#########################code begin###########################
###############get dense pack of particles########################################
from yade import pack,plot
# The following 5 lines will be used later for batch execution
nRead=readParamsFromTable(
num_spheres=10000,# number of spheres
compFricDegree = 30, # contact friction during the confining phase
key='_triax_base_', # put you simulation's name here
unknownOk=True
)
from yade.params import table
num_spheres=table.num_spheres# number of spheres
key=table.key
targetPorosity = 0.55 #the porosity we want for the packing
compFricDegree = table.compFricDegree # initial contact friction during the confining phase (will be decreased during the REFD compaction process)
finalFricDegree = 30 # contact friction during the deviatoric loading
rate=-0.02 # loading rate (strain rate)
damp=0.2 # damping coefficient
stabilityThreshold=0.01 # we test unbalancedForce against this value in different loops (see below)
young=5e6 # contact stiffness
mn,mx=Vector3(0,-.0075,0),Vector3(0.7,.0075,.15) # corners of the initial packing (0,-.0075,0),(0.7,.0075,.15)
O.switchScene();O.resetThisScene()
## create materials for spheres and plates
O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=radians(compFricDegree),density=2600,label='spheres'))
O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls'))
## create walls around the packing
walls=aabbWalls([(0,-.1,0),(.05,.1,.3)],thickness=0,material='walls')
wallIds=O.bodies.append(walls)
## use a SpherePack object to generate a random loose particles packing
sp=pack.SpherePack()
sp.makeCloud((0,0,0),(.05,0,.3),-1,0.3,num_spheres,False, 0.95,seed=1) #"seed" make the "random" generation always the same
spp=O.bodies.append([sphere(center,rad,material='spheres') for center,rad in sp])
for s in spp:
O.bodies[s].state.blockDOFs='yXZ'
triax=TriaxialStressController(
## TriaxialStressController will be used to control stress and strain. It controls particles size and plates positions.
## this control of boundary conditions was used for instance in http://dx.doi.org/10.1016/j.ijengsci.2008.07.002
maxMultiplier=1.+2e4/young, # spheres growing factor (fast growth)
finalMaxMultiplier=1.+2e3/young, # spheres growing factor (slow growth)
thickness = 0,
## switch stress/strain control using a bitmask. What is a bitmask, huh?!
## Say x=1 if stess is controlled on x, else x=0. Same for for y and z, which are 1 or 0.
## Then an integer uniquely defining the combination of all these tests is: mask = x*1 + y*2 + z*4
## to put it differently, the mask is the integer whose binary representation is xyz, i.e.
## "100" (1) means "x", "110" (3) means "x and y", "111" (7) means "x and y and z", etc.
stressMask = 7,
internalCompaction=True, # If true the confining pressure is generated by growing particles
)
newton=NewtonIntegrator(damping=damp)
O.engines=[
ForceResetter(),
InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb()]),
InteractionLoop(
[Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
[Ip2_FrictMat_FrictMat_FrictPhys()],
[Law2_ScGeom_FrictPhys_CundallStrack()]
),
## We will use the global stiffness of each body to determine an optimal timestep (see https://yade-dem.org/w/images/1/1b/Chareyre&Villard2005_licensed.pdf)
GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.8),
triax,
TriaxialStateRecorder(iterPeriod=100,file='WallStresses'+table.key),
newton
]
#the value of (isotropic) confining stress defines the target stress to be applied in all three directions
triax.goal1=triax.goal3=-500
triax.goal2=0
while 1:
O.run(1000, True)
##the global unbalanced force on dynamic bodies, thus excluding boundaries, which are not at equilibrium
unb=unbalancedForce()
print ('unbalanced force:',unb,' mean stress: ',triax.meanStress)
if unb<stabilityThreshold and abs(-1000/3-triax.meanStress)/1000/3<0.001:
break
sp=SpherePack(); sp.fromSimulation()
print ("### Isotropic state saved ###")
O.switchScene()
##define parameters
readParamsFromTable(strainRateTension=.1,sphereRadius=.0005,young=1.5e9,sigmaT=4e6,frictionAngle=atan(0.6),relDuctility= 1.1,omegaThreshold=0.99,epsCrackOnset=.025,damping=.6,sampleNum=1,damLaw = 1,relFuzz=0,factor=1.5,strength_law=1,std=0.4,low=0.5,high=1.5)
from yade.params.table import *
import numpy as np
from yade import pack,plot
isoPrestress=0
poisson= 0.1
pred=pack.inAlignedBox((-1,-1,-1),(1,1,1))-pack.inAlignedBox((-.005,-.0075,-.075),(.005,.0075,-.033))
idConcrete=O.materials.append(CpmMat(young=young,poisson=poisson,frictionAngle=frictionAngle,density=3120,sigmaT=sigmaT,epsCrackOnset=epsCrackOnset,isoPrestress=isoPrestress,relDuctility = relDuctility,damLaw = damLaw))
cement=sp.toSimulation(material=idConcrete)
################################################################### start the simulation################################
###obtain the information of the model
volume = 0
NumOfParticle = 0
for i in cement:
volume += pi * (O.bodies[i].shape.radius) ** 2
NumOfParticle += 1
print(f'density = {volume/(.05*.3)}')
print(f'number of particle = {NumOfParticle}')
bb=uniaxialTestFeatures()
negIds,posIds,axis,crossSectionArea=bb['negIds'],bb['posIds'],bb['axis'],bb['area']
O.engines=[
ForceResetter(),
InsertionSortCollider([
Bo1_Sphere_Aabb(aabbEnlargeFactor=factor,label='bo1s'),],verletDist=.05*sphereRadius), ## expand the collision detection to creat initial interactions
##
InteractionLoop(
[Ig2_Sphere_Sphere_ScGeom(interactionDetectionFactor=factor,label='ig2ss'), ## create collision geometry
Ig2_Facet_Sphere_ScGeom()],
[Ip2_CpmMat_CpmMat_CpmPhys(cohesiveThresholdIter=1)], ## creat collision phys
[Law2_ScGeom_CpmPhys_Cpm(omegaThreshold=omegaThreshold)],
),
GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.3),
NewtonIntegrator(damping=damping,label='damper'),
CpmStateUpdater(realPeriod=.5), ## update CpmState of bodies based on interactions and can change the bodies's color depending on the damage
UniaxialStrainer(strainRate=strainRateTension,axis=axis,asymmetry=0,posIds=posIds,negIds=negIds,crossSectionArea=crossSectionArea,blockDisplacements=False,blockRotations=False,setSpeeds=True,label='strainer'),## apply strain on the both end of the body along the axis and the strain speed is set at the beginning directly
#PyRunner(iterPeriod=100,command='crackCount()'),
PyRunner(iterPeriod=100,command='addPlotData()'),
PyRunner(realPeriod=5,command='stopIfDamaged()',label='damageChecker'), ## set the stop criteria for the simulation
#qt.SnapshotEngine(fileBase='3d',iterPeriod=1000,label='snapshot'),
#PyRunner(command='finish()',iterPeriod=20000
]
#sigma=strainer.avgStress+isoPrestress
O.step() ## go one step to creat interactions
bo1s.aabbEnlargeFactor=1 ## reset the interaction radius
ig2ss.interactionDetectionFactor=1
### reinforcing the boundary
dim=utils.aabbExtrema()
if strainRateTension>0:
layerSize=1/6
height=dim[1][axis]-dim[0][axis]
for b in O.bodies:
if isinstance(b.shape,Sphere):
if (b.state.pos[axis]<(dim[0][axis]+layerSize*height)) or (b.state.pos[axis]> (dim[1][axis]-layerSize*height)):
b.shape.color=(1,1,1)
for i in O.interactions:
if isinstance(O.bodies[i.id1].shape,Sphere) and isinstance(O.bodies[i.id2].shape,Sphere):
if O.bodies[i.id1].shape.color==(1,1,1) or O.bodies[i.id2].shape.color==(1,1,1):
i.phys.neverDamage=True
def stopIfDamaged():
if O.iter<2 or 'sigma' not in plot.data : return
epsilon = plot.data['eps']
sigma=plot.data['sigma']
extremum=max(sigma)
##Gf calculator
global Gf
if abs(sigma[-1]/extremum)>0.2:
Gf += 0.5*(sigma[-1]+sigma[-2])*(epsilon[-1]-epsilon[-2])
##elastic modulus calculator
up=round(sigma.index(extremum)*0.5)
down=round(sigma.index(extremum)*0.125)
elasticModulus = (sigma[up]-sigma[down])/(epsilon[up]-epsilon[down])
if abs(sigma[-1]/extremum)<0.2: ## stop the test if the sigma is too small or strain is too large
O.pause()
def addPlotData():
plot.addData(i=O.iter,sigma=strainer.avgStress,eps=strainer.strain)
plot.plots={'eps':('sigma')}
plot.plot()
O.saveTmp()
O.run()
waitIfBatch()
--
You received this question notification because your team yade-users is
an answer contact for Yade.