← Back to team overview

yade-users team mailing list archive

[Question #698825]: Yade-batch is being indeterministic

 

New question #698825 on Yade:
https://answers.launchpad.net/yade/+question/698825

Hello,

I am simulating the interaction between a brush (modelled using gridConnections) and a rotating box (pfacet clump). I noticed some inconsistencies in the batch simulations and I tried a batch simulation in which the only parameter that was changed was the ID. The outputs of each simulation in the batch were different. From what I understand according to [1], there YADE will be indeterministic when it a single simulation is run in parallel multiple times. However, I understood that YADE-batch has each simulation running using one thread/code by default. So why are all the results different? Please find my code below. Please note I am using the json module in python to write and read the data. You may have to install it using pip install json

Kind regards,
Rohit K. John

[1] https://yade-dem.org/doc/formulation.html#result-indeterminism

# -------------------------------------------------------------------------------------------------------------------------------------------- parameters.table
ID 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

# -------------------------------------------------------------------------------------------------------------------------------------------- cube_LP.gts
14 36 24 GtsSurface GtsFace GtsEdge GtsVertex
0.03 0.03 0.03
0.03 0.03 -0.03
0.03 -0.03 0.03
0.03 -0.03 -0.03
-0.03 0.03 0.03
-0.03 0.03 -0.03
-0.03 -0.03 0.03
-0.03 -0.03 -0.03
0.03 0.0 0.0
0.0 0.03 0.0
-0.03 0.0 0.0
0.0 0.0 0.03
0.0 -0.03 0.0
0.0 0.0 -0.03
6 8
2 6
1 2
8 7
3 4
5 6
3 7
1 3
8 4
7 5
5 1
4 2
9 3
2 9
4 9
1 9
10 1
6 10
5 10
2 10
11 5
8 11
7 11
6 11
12 3
5 12
7 12
1 12
13 7
4 13
8 13
3 13
14 4
6 14
8 14
2 14
7 25 27 
7 29 32 
10 21 23 
12 33 36 
8 13 16 
11 17 19 
12 14 15 
5 15 13 
3 16 14 
2 18 20 
6 19 18 
3 20 17 
1 22 24 
4 23 22 
6 24 21 
11 26 28 
10 27 26 
8 28 25 
9 30 31 
4 31 29 
5 32 30 
1 34 35 
9 35 33 
2 36 34 
# --------------------------------------------------------------------------------------------------------------------------------------------python script

from yade.gridpfacet import *
from yade import plot
import sys
import json
from json import JSONEncoder

sys.path.append(".")
# ---------------------------------------------------------------------------------------------- input parameter
simulation_mode = "batch"

if simulation_mode == 'single':
    ID = 14
    # randomness = 0e-7

elif simulation_mode == 'batch':
    readParamsFromTable(
        ID = 14,
        # randomness = 0e-7
        )
    from yade.params.table import *

# ---------------------------------------------------------------------------------------------- input parameter
# ----------------------------------------------------- target
target_young    = 3.2e6
target_density  = 1250
target_poisson  = 0.48
target_friction = radians(44)

p_radius    = 1e-3

# ---------------------------------------------------------------------------------------------------------------------------- Materials
target_int_mat = 'pfacet_int_mat'
target_ext_mat = 'pfacet_ext_mat'

O.materials.append(
    FrictMat(
        young   = target_young,
        poisson = target_poisson,
        density = target_density,
        label   = target_ext_mat,
        frictionAngle = target_friction,
    )
)

O.materials.append(
    CohFrictMat(
        young   = target_young,
        poisson = target_poisson,
        density = target_density,
        label   = target_int_mat,

        frictionAngle     = target_friction,
        normalCohesion    = 3e100,
        shearCohesion     = 3e100,
        momentRotationLaw = True,
    )
)
# ---------------------------------------------------------------------------------------------------------------------------- Engines
O.engines = [
                ForceResetter(),

                InsertionSortCollider([
                    Bo1_GridConnection_Aabb(),
                    Bo1_PFacet_Aabb(),
                    Bo1_Sphere_Aabb(),
                ]),

                InteractionLoop(
                    [
                        Ig2_PFacet_PFacet_ScGeom(),
                        Ig2_GridConnection_GridConnection_GridCoGridCoGeom(),
                        Ig2_GridNode_GridNode_GridNodeGeom6D(),
                        Ig2_GridConnection_PFacet_ScGeom(),
                        Ig2_Sphere_PFacet_ScGridCoGeom(),
                    ],
                    [
                        Ip2_FrictMat_FrictMat_FrictPhys(),
                        Ip2_CohFrictMat_CohFrictMat_CohFrictPhys(
                            setCohesionNow = True, 
                            setCohesionOnNewContacts = False
                            ),
                    ],
                    [
                        Law2_GridCoGridCoGeom_FrictPhys_CundallStrack(),
                        Law2_ScGeom_FrictPhys_CundallStrack(),
                        Law2_ScGridCoGeom_FrictPhys_CundallStrack(),
                        Law2_ScGeom6D_CohFrictPhys_CohesionMoment(),
                    ],
                )
            ] 
# ---------------------------------------------------------------------------------------------------------------------------- objects 
# ---------------------------------------------------------------------- target
target_pos         = [0.0, 0.0, 70e-3]
(
pnode,
pcyl,
pfacet 
) = gtsPFacet(
    'cube_LP.gts',
    radius = p_radius,
    shift  = target_pos,
    scale  = 1,
    wire   = False,
    fixed  = False,
    color  = [0.1,0.5,0.1],
    materialNodes = 'pfacet_int_mat',
    material      = 'pfacet_ext_mat',
)


target_ids  = pnode + pcyl + pfacet
for i in pcyl:
    O.bodies[i].state.mass = 1e-13 # or else the mass of the gridConnections will be added to clump

target_clump_ID = O.bodies.clump(target_ids)
O.bodies[target_clump_ID].state.blockedDOFs = "xyzYZ"

ang_vel = 50
O.bodies[target_clump_ID].state.angVel = [ang_vel, 0.0, 0.0]

# ---------------------------------------------------------------------- brush
n_rows = 5
n_cols = 11
n_segs = 11
dx     =  2.4375e-3
dz     =  2.4375e-3
bristle_tip_pos_y  =  35.55e-3
bristle_tip_pos_z  =  63.5e-3
brislte_len        = 35e-3
dy                 = brislte_len / (n_segs - 1)
bristle_radius     = 1e-3 

nodeIds=[]
connectionIds=[]
for row_i in range(n_rows):
    for col_i in range(n_cols):
        brislte_seg_ids = []
        for seg_i in range(n_segs):            
            pos = Vector3([
                col_i * dx,
                seg_i * dy + bristle_tip_pos_y,
                row_i * dz + bristle_tip_pos_z,
            ])
            brislte_seg_ids.append( 
                O.bodies.append( 
                    gridNode(pos,
                    bristle_radius,
                    wire=False,
                    fixed=False,
                    material='pfacet_int_mat',
                    ) ) )
        
        nodeIds = nodeIds + brislte_seg_ids         
        O.bodies[nodeIds[-1]].state.blockedDOFs = "xyzXYZ"

        for idx in range(len(brislte_seg_ids[1:])):
            connectionIds.append(
                O.bodies.append( 
                    gridConnection(
                        brislte_seg_ids[idx], brislte_seg_ids[idx + 1],
                        bristle_radius,
                        material='pfacet_ext_mat'
                        ) ) )



# ----------------------------------------------------------------------------------------------- Additional engines
O.engines += [
    NewtonIntegrator(gravity = [0,0,0], damping = 0),
    PyRunner(command = 'graph()',   iterPeriod = 1000),
    PyRunner(command = 'stopper()', iterPeriod = 200000)
]

# ---------------------------------------------------------------------- plotting
plot.plots = {'t':('wx')}

def graph():     
    w = O.bodies[target_clump_ID].state.angVel
    plot.addData(
        t  = O.time, 
        wx    = w[0]
    )

plot.plot()


# ---------------------------------------------------------------------- VectorEncoder
class VectorEncoder(JSONEncoder):
    """
    This is used to serialise the Vector3 class so that json.dump can write this class
    """
    def default(self, o):
        return list(o)

def stopper():
    result_dict               = {}
    result_dict['data']       = plot.data
    result_dict["ID"]         = ID
    
    file_json = 'Sim_result_ID_' + str(ID) + '.json'
    with open(file_json, 'w') as f:
        json.dump(result_dict, f, indent=4, cls=VectorEncoder)

    O.pause()
# ----------------------------------------------------------------------------------------------- Sim controller 
O.dt = 1e-6
if simulation_mode == 'batch':
    O.run()
    waitIfBatch()

else:
    O.saveTmp()

-- 
You received this question notification because your team yade-users is
an answer contact for Yade.