\( \usepackage{euler} % must be loaded before fontspec for the whole doc (below); this must be kept for pngmath, however \usepackage{hyperref} \usepackage{amsmath} \usepackage{amsbsy} %\usepackage{mathabx} \usepackage{underscore} \usepackage[all]{xy} % Metadata of the pdf output \hypersetup{pdftitle={Yade Documentation}} \hypersetup{pdfauthor={Smilauer, V., et al.}} \hypersetup{pdfkeywords={Discrete element method, granular materials, contact law, hydromechanical coupling}} % symbols \renewcommand{\mat}{\boldsymbol} \renewcommand{\vec}{\boldsymbol} \renewcommand{\tens}{\boldsymbol} %normalized and locfram here \def\normalized#1{\widehat{#1}} \def\locframe#1{\widetilde{#1}} % timestep \def\Dt{\Delta t} \def\Dtcr{\Dt_{\rm cr}} % algorithm complexity \def\bigO#1{{\mathcal{O}(#1)}} % variants for greek symbols \let\epsilon\varepsilon \let\theta\vartheta \let\phi\varphi % shorthands \let\sig\sigma \let\eps\epsilon % variables at different points of time \def\prev#1{#1^-} \def\pprev#1{#1^\ominus} \def\curr#1{#1^{\circ}} \def\nnext#1{#1^\oplus} \def\next#1{#1^+} % shorthands for geometry \def\currn{\curr{\vec{n}}} \def\currC{\curr{\vec{C}}} \def\uT{\vec{u}_T} \def\curruT{\curr{\vec{u}}_T} \def\prevuT{\prev{\vec{u}}_T} \def\currn{\curr{\vec{n}}} \def\prevn{\prev{\vec{n}}} % motion \def\pprevvel{\pprev{\dot{\vec{u}}}} \def\nnextvel{\nnext{\dot{\vec{u}}}} \def\curraccel{\curr{\ddot{\vec{u}}}} \def\prevpos{\prev{\vec{u}}} \def\currpos{\curr{\vec{u}}} \def\nextpos{\next{\vec{u}}} \def\curraaccel{\curr{\dot{\vec{\omega}}}} \def\pprevangvel{\pprev{\vec{\omega}}} \def\nnextangvel{\nnext{\vec{\omega}}} \def\loccurr#1{\curr{\locframe{#1}}} \def\numCPU{n_{\rm cpu}} \DeclareMathOperator{\Align}{Align} \DeclareMathOperator{\sign}{sgn} % sorting algorithms \def\isleq#1{\currelem{#1}\ar@/^/[ll]^{\leq}} \def\isnleq#1{\currelem{#1}\ar@/^/[ll]^{\not\leq}} \def\currelem#1{\fbox{$#1$}} \def\sortSep{||} \def\sortInv{\hbox{\phantom{||}}} \def\sortlines#1{\xymatrix@=3pt{#1}} \def\crossBound{||\mkern-18mu<} \)

# Day 1 - Yade Hands-on part 1

## Let’s create a bouncing sphere

First we need to define a material for our sphere:

    # Start by defining a material
    O.materials.append(FrictMat(young=1.0e9, poisson=0.2, density=2500, label='frictmat'))

`O` is our scene, it contains all the information that we need to run a DEM simulation. We can edit various components of the scene such as `materials` here. We use the python function `.append()` to add this material to the existing list of materials inside Python.

The `FrictMat` is a type of material available in Yade. Yade boasts a wide variety of materials such as `CohFrictMat`. These materials all have different constitutive laws associated with them. For now we stick with the simplest one, `FrictMat`.

Next, we need to create two spheres by appending two `bodies` to our scene, `O`:

    O.bodies.append(
        [
        # fixed: particle's position in space will not change (support)
        sphere(center=(0, 0, 0), radius=.5, fixed=True),
        # this particles is free, subject to dynamics
        sphere((0, 0, 2), .5)
        ]
    )

We see that we appended a `sphere` to the scene by designating its center and radius. Yade has a variety of shapes that can be appended as bodies such as `Facet`, `Box`, and others.

Now it is time to define how these spheres should move. The scene `O` has an “engines” list in `O.engines` which is a list of actions that are taken for each iteration in our simulation.

    O.engines = [
        ForceResetter(),
        InsertionSortCollider([Bo1_Sphere_Aabb()]),
        InteractionLoop(
                [Ig2_Sphere_Sphere_ScGeom()],  # collision geometry
                [Ip2_FrictMat_FrictMat_FrictPhys()],  # collision "physics"
                [Law2_ScGeom_FrictPhys_CundallStrack()]  # contact law -- apply forces
        ),
        # Apply gravity force to particles. damping: numerical dissipation of energy.
        NewtonIntegrator(gravity=(0, 0, -9.81), damping=0.1)
    ]

Some of this may look foreign to you, but there is a logic to it. The `ForceResetter()` resets all forces stored in the scene, `InsertionSortCollider` is simply creating a sorted list of possible body interactions. `InteractionLoop()` is where we assign the interaction geometry (`Ig2_Sphere_Sphere_ScGeom()`) which conveniently matches our appended body shape (`Sphere`), the collision physics `Ip2_FrictMat_FrictMat_FrictPhys()` conveniently matches our material assignment (`FrictMat`). Finally, the constitutive law is defined with `Law2_ScGeom_FrictPhys_CundallStrack()`, so we are using the classical CundallStrack contact law here. The timeintegration occurs in the last component `NewtonIntegrator` where we can add a gravitational force and damping.

Although we have already added our material, body, and engines to the scene, we should still take care to define the time step in `O.dt`:

    O.dt = .5 * PWaveTimeStep()

Where the `PWaveTimeStep()` automatically estimates the critical time step associated with the stiffness of the packing. We factor that down by 1/2 to be safe, since it is but an estimate.

## Starting the Script

Now that we have the full script written for our bouncing ball, it is time to start it by executing:

    yade bouncing_sphere.py

in our terminal.