Buckling of beer can example#

This example is inspired by the “Buckling of Beer Can” example on the LS-DYNA Examples site. It shows how to use DYNA-Lib to create a keyword file for LS-DYNA and then solve it within a Pythonic environment.

Perform required imports#

Import required packages, including those for the keywords, deck, and solver.

import os
import pathlib
import shutil

import numpy as np
import pandas as pd

from ansys.dyna.keywords import Deck
from ansys.dyna.keywords import keywords as kwd
from ansys.dyna.run import run_dyna

dynadir = "run"
dynafile = "beer_can.k"

Create a deck and keywords#

Create a deck, which is the container for all the keywords. Then, create and append individual keywords to the deck.

p = pathlib.Path(dynadir)
p.mkdir(parents=True, exist_ok=True)


def write_deck(filepath):
    deck = Deck()

    # Append control keywords
    deck.extend(
        [
            kwd.ContactAutomaticSingleSurfaceMortar(),
            kwd.ControlAccuracy(iacc=1),
            kwd.ControlImplicitAuto(iauto=1, dtmax=0.01),
            kwd.ControlImplicitDynamics(imass=1, gamma=0.6, beta=0.38),
            kwd.ControlImplicitGeneral(imflag=1, dt0=0.01),
            kwd.ControlImplicitSolution(nlprint=2),
            kwd.ControlShell(esort=2, theory=-16, intgrd=1, nfail4=1),
            kwd.ControlTermination(endtim=1.0),
        ]
    )

    # Append database keywords
    deck.extend(
        [
            kwd.DatabaseGlstat(dt=1.0e-4, binary=3),
            kwd.DatabaseSpcforc(dt=1e-4, binary=3),
            kwd.DatabaseBinaryD3Plot(dt=1.0e-4),
            kwd.DatabaseExtentBinary(maxint=-3),
        ]
    )

    # Append part keywords
    beercanPart = kwd.Part()
    beercanPart.parts = pd.DataFrame({"heading": ["Beer Can"], "pid": [1], "secid": [1], "mid": [1], "eosid": [0]})

    floorPart = kwd.Part()
    floorPart.parts = pd.DataFrame({"heading": ["Floor"], "pid": [2], "secid": [2], "mid": [1]})

    # Append material keywords
    deck.extend(
        [
            beercanPart,
            kwd.MatElastic(mid=1, ro=2.59e-4, e=1.0e7, pr=0.33),
            kwd.SectionShell(secid=1, elform=-16, shrf=0.8333, nip=3, t1=0.002),
            floorPart,
            kwd.SectionShell(secid=2, elform=-16, shrf=0.833, t1=0.01),
        ]
    )

    load_curve = kwd.DefineCurve(lcid=1, curves=pd.DataFrame({"a1": [0.00, 1.00], "o1": [0.0, 1.000]}))
    deck.append(load_curve)

    # Define boundary conditions
    load_nodes = [
        50,
        621,
        670,
        671,
        672,
        673,
        674,
        675,
        676,
        677,
        678,
        679,
        680,
        681,
        682,
        683,
        684,
        685,
        686,
        687,
        31,
        32,
        33,
        34,
        35,
        36,
        37,
        38,
        39,
        40,
        41,
        42,
        43,
        44,
        45,
        46,
        47,
        48,
        49,
        1229,
        1230,
        1231,
        1232,
        1233,
        1234,
        1235,
        1236,
        1237,
        1238,
        1239,
        1240,
        1241,
        1242,
        1243,
        1244,
        1245,
        1246,
        1247,
        1799,
        1800,
        1801,
        1802,
        1803,
        1804,
        1805,
        1806,
        1807,
        1808,
        1809,
        1810,
        1811,
        1812,
        1813,
        1814,
        1815,
        1816,
    ]

    count = len(load_nodes)
    zeros = np.zeros(count)

    load_node_point = kwd.LoadNodePoint(
        nodes=pd.DataFrame(
            {
                "nid": load_nodes,
                "dof": np.full((count), 3),
                "lcid": np.full((count), 1),
                "sf": np.full((count), -13.1579),
                "cid": zeros,
                "m1": zeros,
                "m2": zeros,
                "m3": zeros,
            }
        )
    )

    deck.append(load_node_point)

    nid = [
        1,
        31,
        32,
        33,
        34,
        35,
        36,
        37,
        38,
        39,
        40,
        41,
        42,
        43,
        44,
        45,
        46,
        47,
        48,
        49,
        50,
        80,
        81,
        82,
        83,
        84,
        85,
        86,
        87,
        88,
        89,
        90,
        91,
        92,
        93,
        94,
        95,
        96,
        97,
        98,
        621,
        651,
        652,
        653,
        654,
        655,
        656,
        657,
        658,
        659,
        660,
        661,
        662,
        663,
        664,
        665,
        666,
        667,
        668,
        669,
        670,
        671,
        672,
        673,
        674,
        675,
        676,
        677,
        678,
        679,
        680,
        681,
        682,
        683,
        684,
        685,
        686,
        687,
        1210,
        1211,
        1212,
        1213,
        1214,
        1215,
        1216,
        1217,
        1218,
        1219,
        1220,
        1221,
        1222,
        1223,
        1224,
        1225,
        1226,
        1227,
        1228,
        1229,
        1230,
        1231,
        1232,
        1233,
        1234,
        1235,
        1236,
        1237,
        1238,
        1239,
        1240,
        1241,
        1242,
        1243,
        1244,
        1245,
        1246,
        1247,
        1799,
        1800,
        1801,
        1802,
        1803,
        1804,
        1805,
        1806,
        1807,
        1808,
        1809,
        1810,
        1811,
        1812,
        1813,
        1814,
        1815,
        1816,
        1817,
        1818,
        1819,
        1820,
        1821,
        1822,
        1823,
        1824,
        1825,
        1826,
        1827,
        1828,
        1829,
        1830,
        1831,
        1832,
        1833,
        1834,
    ]

    count = len(nid)
    zeros = np.zeros(count)
    ones = np.full((count), 1)

    dofz = [
        1,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        0,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
    ]

    boundary_spc_node = kwd.BoundarySpcNode(
        nodes=pd.DataFrame(
            {
                "nid": nid,
                "cid": zeros,
                "dofx": ones,
                "dofy": ones,
                "dofz": dofz,
                "dofrx": ones,
                "dofry": ones,
                "dofrz": ones,
            }
        )
    )

    deck.append(boundary_spc_node)

    # Define nodes and elements
    deck.append(kwd.Include(filename="mesh.k"))

    deck.export_file(filepath)
    return deck


def run_post(filepath):
    pass


deck = write_deck(os.path.join(dynadir, dynafile))
shutil.copy("mesh.k", "run/mesh.k")

View the model#

You can use the PyVista plot method in the deck class to view the model.

out = deck.plot(cwd=dynadir)

Run the Dyna solver#

try:
    filepath = run_dyna(dynafile, working_directory=dynadir)
    print("completed")
    run_post(filepath)
    print("post_completed")
except Exception as e:
    print(e)

Total running time of the script: (0 minutes 0.000 seconds)

Gallery generated by Sphinx-Gallery