How to erase GridConnection

Asked by Loic Dugelas

Hi,

I'm beginning with Yade and I've a problem using GridConnection : during the simulation I want to erase a GridConnection.

In a first try, I erase the interaction with O.interactions.erase(id1,id2), doing this, the interaction is erase but the Cylinder added with the GridConnection is still there. Then I tried to delete it by O.bodies.erase() but here I've got a Core Dumped error.

To give a global overview of my problem, I'm trying to add some tension in a cable made with Grid. I'm trying to do this following this steps:
- delete one interaction of the cable
- move the sphere connected to the deleted interaction (closer or farther from the initial position if I want to add or remove tension)
- create the interaction again
- move the sphere back to it initial position
In my mind, after that there is a new equilibrium state with more or less tension in the cable.

I also thought that this can be done without deleting interaction but by resetting the initial distance of the interaction to the one I want, but I don't know if it's possible and how to do this.

I hope I made myself clear,
Thanks,

Loïc

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Klaus Thoeni
Solved:
Last query:
Last reply:
Revision history for this message
Klaus Thoeni (klaus.thoeni) said :
#1

Hi,

I never tried to erase a GridConnection, so not sure what's going on here. Also, without seeing your script it is difficult to guess.

Anyway, wouldn't it be easier to make the initial rope shorter and then apply the pretension to get to a desired length by moving the last node?

HTH
Klaus

Revision history for this message
Loic Dugelas (ldugelas) said :
#2

Hi Klaus,

Thank you for your answer, I'll post a simplified script of my problem as soon as possible.

I made a script which apply tension by this way and it works well if the cable is linear. But in my case it is not and I can't (or don't find the way to) apply this method.

Anyway, the final goal of this model is to be able to modify the tension during the simulation to get the right equilibrium state.

Thank you,
Loïc

Revision history for this message
Loic Dugelas (ldugelas) said :
#3

Here you can find my script

#-*- coding: utf-8 -*-
from yade import qt, plot
from yade.gridpfacet import *
import gts, os, locale, sys
import numpy as np

################ Engine ############

O.engines=[
 ForceResetter(),
 InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_GridConnection_Aabb(),]),
 InteractionLoop(
  [Ig2_Sphere_Sphere_ScGeom(),Ig2_GridNode_GridNode_GridNodeGeom6D(),Ig2_Sphere_GridConnection_ScGridCoGeom(),Ig2_GridConnection_GridConnection_GridCoGridCoGeom(),],
  [Ip2_WireMat_WireMat_WirePhys(),Ip2_FrictMat_FrictMat_FrictPhys(),Ip2_CohFrictMat_CohFrictMat_CohFrictPhys(setCohesionNow=True,setCohesionOnNewContacts=False),],
  [ Law2_ScGeom_WirePhys_WirePM(),Law2_ScGeom6D_CohFrictPhys_CohesionMoment(),Law2_ScGridCoGeom_CohFrictPhys_CundallStrack(),Law2_GridCoGridCoGeom_FrictPhys_CundallStrack(),Law2_ScGridCoGeom_FrictPhys_CundallStrack(),Law2_ScGeom_FrictPhys_CundallStrack(),]
 ),
 NewtonIntegrator(gravity=(0,0,-9.81),damping=0.9,label='newton'),
 PyRunner(initRun=True,iterPeriod=200,command='Force()'),
 PyRunner(virtPeriod=0.05, virtLast = 3, command='MEP_Pret()'),
]

################## Material & geometry ##########
youngc = 60e9
strenruptc=1400e9
densityc=7850.
poissonc = 0.3
shearCohc = 1e100
Rc = 0.008
cablemat = O.materials.append(CohFrictMat(young=youngc,poisson=poissonc,density=densityc,frictionAngle=radians(10),normalCohesion=pi*strenruptc,isCohesive=True,shearCohesion=shearCohc,momentRotationLaw=False, alphaKr = 1.0))
cablecomat = O.materials.append(FrictMat(young=youngc,poisson=poissonc,density=densityc,frictionAngle=radians(10)))

####################### Adding cable ##############
def Cable_droit_spheres(start, end, lseg, mtxnode, rayon): #just the meshing function

 lenght = end-start
 vecunit = lenght/(abs(lenght))
 lfinal = abs(lenght)
 cable = []
 nbseg = int(lfinal/lseg)
 for i in range(nbseg+1):
  x = start[0] + (vecunit*lfinal)[0]*i/nbseg
  y = start[1] + (vecunit*lfinal)[1]*i/nbseg
  z = start[2] + (vecunit*lfinal)[2]*i/nbseg
  cable.append(O.bodies.append(gridNode([x,y,z],rayon,wire=False,fixed=False,material=mtxnode)))

 return [cable]

#mapping the spheres of the cable
[c2a_1] = Cable_droit_spheres(start = Vector3(-1,0,0) , end = Vector3(-0.25, 0, 0), lseg = 0.1, mtxnode = cablemat,rayon = Rc)
[c2a_2] = Cable_droit_spheres(start = Vector3(-.20,0,-0.1), end = Vector3(0.20,0,-0.1), lseg = 0.1,mtxnode = cablemat,rayon = Rc)
[c2a_3] = Cable_droit_spheres(start = Vector3(0.25,0,0), end = Vector3(1,0,0), lseg = 0.1,mtxnode = cablemat,rayon = Rc)

cable = c2a_1 + c2a_2 + c2a_3

#and the link
concable = []
for i,j in zip(cable[:-1],cable[1:]):
 concable.append(O.bodies.append(gridConnection(O.bodies[i].id,O.bodies[j].id,Rc,wire=False, material = cablecomat) ))

O.bodies[cable[0]].state.blockedDOFs='xyzXYZ'
O.bodies[cable[-1]].state.blockedDOFs='xyzXYZ'

plot.plots={'t':('Fcable'),}
plot.plot(noShow=False, subPlots=False)
O.dt = 1e-6
#O.run()
################### Functions ####################

def MEP_Pret():

 Lcable = 0
 for i in range(len(cable)-1):
  Lcable += np.linalg.norm(O.bodies[cable[i]].state.pos-O.bodies[cable[i+1]].state.pos)

 if O.time > 0.6 :
  O.pause()
  pos1 = O.bodies[cable[-1]].state.pos

  for i in O.bodies[cable[-1]].intrs(): #deleting interaction with the extremity of the cable
   O.interactions.erase(i.id1,i.id2)
  for i in O.bodies[concable[-1]].intrs():
   O.interactions.erase(i.id1,i.id2)

  O.bodies.erase(concable[-1]) #deleting the cylinder (the crash comes from here)

  O.bodies[cable[-1]].state.pos = Vector3(pos1[0]-0.10,pos1[1],pos1[2])
  concable.append(O.bodies.append( gridConnection(cable[-2],cable[-1], Rc,material = cablecomat) ))
  O.bodies[cable[-1]].state.pos = pos1
  O.run()

def Force():

 Fcable = np.linalg.norm(O.forces.f(cable[0]))
 t = O.time
 plot.addData(
 Fcable = Fcable/1000,
 t = O.time)
 if t> 3.0 :
  O.pause()

Revision history for this message
Klaus Thoeni (klaus.thoeni) said :
#4

Hi Loic,

I played a bit with it myself and the trick is to also delete the non real interaction. Also, I would first delete the body and then the interaction because in theory erasing the body should also erase the interaction. The latter is however not implemented yet but I will probably do it in the future. Anyway, here my MWE. You can delete the cylinder and create one as many times as you want. This works for me.

# encoding: utf-8
from yade.gridpfacet import *

#### Parameters ####
L=2. # minimum length
r=0.5 # radius of the cylinder element
phi=30. # friction angle
E=1e6 # Young's modulus

#### Engines ####
O.engines=[
 ForceResetter(),
 InsertionSortCollider([
  Bo1_GridConnection_Aabb(),
  Bo1_Sphere_Aabb(),
  Bo1_Wall_Aabb(),
 ]),
 InteractionLoop([
  Ig2_GridNode_GridNode_GridNodeGeom6D(),
  Ig2_GridConnection_GridConnection_GridCoGridCoGeom(),
  Ig2_Wall_Sphere_ScGeom(),
 ],
 [
  Ip2_CohFrictMat_CohFrictMat_CohFrictPhys(setCohesionNow=True,setCohesionOnNewContacts=False),
  Ip2_FrictMat_FrictMat_FrictPhys()
 ],
 [
  Law2_ScGeom6D_CohFrictPhys_CohesionMoment(), # contact law for "internal" cylider forces
  Law2_ScGridCoGeom_FrictPhys_CundallStrack(), # contact law for Cylinder-pFacet interaction
  Law2_GridCoGridCoGeom_FrictPhys_CundallStrack() # contact law for cylinder-cylinder interaction
 ]
 ),
 GlobalStiffnessTimeStepper(timestepSafetyCoefficient=0.1,label='ts'),
 NewtonIntegrator(gravity=(0.,0,-10),damping=0.5,label='newton'),
]

#### Creat materials ####
O.materials.append( CohFrictMat( young=E,poisson=0.3,density=1000,frictionAngle=radians(phi),normalCohesion=1e10,shearCohesion=1e10,momentRotationLaw=True,label='cMat' ) ) # material to create the gridConnections
O.materials.append( FrictMat( young=E,poisson=0.3,density=1000,frictionAngle=radians(phi),label='fMat' ) ) # material for general interactions

#### Create cylinders ####
nodesIds=[]
cylIds=[]
cylinder((0,0,2*r),(0,0,L+2*r),radius=r,nodesIds=nodesIds,cylIds=cylIds,fixed=False,intMaterial='cMat',extMaterial='fMat')

#### For viewing ####
from yade import qt
qt.View()
Gl1_Sphere.stripes=True

#### Delete and create cylinder/gridConnection ####
def delcylinder():
 O.bodies.erase(cylIds[0]) # first delete the cylinder
 O.interactions.erase(nodesIds[0],nodesIds[1]) # then delete the real interaction between the gridNodes
 O.interactions.eraseNonReal() # finally delete non real interactions

def createcylinder():
 O.bodies.append(gridConnection(nodesIds[0],nodesIds[1],r,wire=False, material = 'cMat') )

HTH
Klaus

Revision history for this message
Loic Dugelas (ldugelas) said :
#5

Hi Klaus,

Thank you for your help, this is working, I can now delete and replace the cylinder. But there is a new problem, the new cylinder is here but it seems that the new interaction is not activated. I modify a little your script to show this problem. I think this comes from the fact that the new interaction is not taken into account but I don't know how to deal with it. Any idea ?

In the script if you don't change the cylinder, the node1 is falling as expect but if you change the cylinder, the interaction don't hold it:

############

# encoding: utf-8
from yade.gridpfacet import *

#### Parameters ####
L=2. # minimum length
r=0.5 # radius of the cylinder element
phi=30. # friction angle
E=1e6 # Young's modulus

#### Engines ####
O.engines=[
 ForceResetter(),
 InsertionSortCollider([
  Bo1_GridConnection_Aabb(),
  Bo1_Sphere_Aabb(),
  Bo1_Wall_Aabb(),
 ]),
 InteractionLoop([
  Ig2_GridNode_GridNode_GridNodeGeom6D(),
  Ig2_GridConnection_GridConnection_GridCoGridCoGeom(),
  Ig2_Wall_Sphere_ScGeom(),
 ],
 [
  Ip2_CohFrictMat_CohFrictMat_CohFrictPhys(setCohesionNow=True,setCohesionOnNewContacts=False),
  Ip2_FrictMat_FrictMat_FrictPhys()
 ],
 [
  Law2_ScGeom6D_CohFrictPhys_CohesionMoment(), # contact law for "internal" cylider forces
  Law2_ScGridCoGeom_FrictPhys_CundallStrack(), # contact law for Cylinder-pFacet interaction
  Law2_GridCoGridCoGeom_FrictPhys_CundallStrack() # contact law for cylinder-cylinder interaction
 ]
 ),
 GlobalStiffnessTimeStepper(timestepSafetyCoefficient=0.1,label='ts'),
 NewtonIntegrator(gravity=(0.,-10,0),damping=0.5,label='newton'),
 PyRunner(initRun=True,iterPeriod=200,command='delcylinder()'),
 PyRunner(initRun=True,iterPeriod=200,command='createcylinder()')
]

#### Creat materials ####
O.materials.append( CohFrictMat( young=E,poisson=0.3,density=1000,frictionAngle=radians(phi),normalCohesion=1e10,shearCohesion=1e10,momentRotationLaw=True,label='cMat' ) ) # material to create the gridConnections
O.materials.append( FrictMat( young=E,poisson=0.3,density=1000,frictionAngle=radians(phi),label='fMat' ) ) # material for general interactions

#### Create cylinders ####
nodesIds=[]
cylIds=[]
cylinder((0,0,2*r),(0,0,L+2*r),radius=r,nodesIds=nodesIds,cylIds=cylIds,fixed=False,intMaterial='cMat',extMaterial='fMat')

O.bodies[nodesIds[0]].state.blockedDOFs='xyzXYZ' #fixe the sides
O.bodies[nodesIds[1]].state.blockedDOFs='xyzXYZ'

#### For viewing ####
from yade import qt
qt.View()
Gl1_Sphere.stripes=True

#### Delete and create cylinder/gridConnection ####
def delcylinder():
 O.bodies.erase(cylIds[0]) # first delete the cylinder
 O.interactions.erase(nodesIds[0],nodesIds[1]) # then delete the real interaction between the gridNodes
 O.interactions.eraseNonReal() # finally delete non real interactions

def createcylinder():
 O.bodies.append(gridConnection(nodesIds[0],nodesIds[1],r,wire=False, material = 'cMat') )
 O.bodies[nodesIds[1]].state.blockedDOFs='' #release one side after changing the cylinder

Revision history for this message
Best Klaus Thoeni (klaus.thoeni) said :
#6

Hi Loic,

I see the problem but I can't find a quick fix for it at the moment. So deleting and recreating GridConnections is not recommended at the current stage. Nevertheless, I came up with a much nicer and easier solution for your problem. Just modify your equilibrium distance unp in the interaction physics. Here my simplified script:

-----------------------------------------------
# encoding: utf-8
from yade.gridpfacet import *

#### Parameters ####
L=5. # minimum length
r=0.5 # radius of the cylinder element
phi=30. # friction angle
E=1e6 # Young's modulus

#### Engines ####
O.engines=[
 ForceResetter(),
 InsertionSortCollider([
  Bo1_GridConnection_Aabb(),
  Bo1_Sphere_Aabb(),
 ]),
 InteractionLoop([
  Ig2_GridNode_GridNode_GridNodeGeom6D(),
 ],
 [
  Ip2_CohFrictMat_CohFrictMat_CohFrictPhys(setCohesionNow=True,setCohesionOnNewContacts=False),
 ],
 [
  Law2_ScGeom6D_CohFrictPhys_CohesionMoment(), # contact law for "internal" cylider forces
 ]
 ),
 NewtonIntegrator(gravity=(0.,0.,0.),damping=0.5,label='newton'),
]

#### Creat materials ####
O.materials.append( CohFrictMat( young=E,poisson=0.3,density=1000,frictionAngle=radians(phi),normalCohesion=1e10,shearCohesion=1e10,momentRotationLaw=True,label='cMat' ) ) # material to create the gridConnections
O.materials.append( FrictMat( young=E,poisson=0.3,density=1000,frictionAngle=radians(phi),label='fMat' ) ) # material for general interactions

#### Create cylinder ####
nodesIds=[]
cylIds=[]
cylinder((0,0,2*r),(0,0,L+2*r),radius=r,nodesIds=nodesIds,cylIds=cylIds,fixed=False,intMaterial='cMat',extMaterial='fMat')
O.bodies[nodesIds[0]].state.blockedDOFs='xyzXYZ' # fix one node

#### Change unp to simulate pre-stressing ####
cinter=O.interactions[nodesIds[0],nodesIds[1]]
cinter.phys.unp = -3.

O.dt=1.e-6

#### For viewing ####
from yade import qt
qtc = qt.Controller()
qtv = qt.View()
qtr = qt.Renderer()
qtr.intrAllWire = True
qtr.wire = True
qtr.intrPhys = True
-----------------------------------------------

If needed, you could iteratively set your unp to achieve a specific pre-stressing condition. I hope this is solving your problem.

HTH
Klaus

Revision history for this message
Loic Dugelas (ldugelas) said :
#7

Hi Klaus,

This is working nicely and solving my problem,

Thank you for your time,

Loïc

Revision history for this message
Loic Dugelas (ldugelas) said :
#8

Thanks Klaus Thoeni, that solved my question.