.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/Implicit/camry_rc.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_Implicit_camry_rc.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_Implicit_camry_rc.py:


Implicit model
==============
This example shows how to create and use an implicit dynamic roof crush model.

.. GENERATED FROM PYTHON SOURCE LINES 31-35

Perform required imports
~~~~~~~~~~~~~~~~~~~~~~~~
Perform the required imports.


.. GENERATED FROM PYTHON SOURCE LINES 35-84

.. code-block:: Python

    import os
    import sys

    from camry_rc_data import (
        beamparts,
        biw,
        cnrbs,
        partswithmat180,
        partswithmat250,
        partswithmat300,
        partswithmat360,
        partswithmat400,
        partswithmat450,
        partswithmat500,
        platen,
        shellparts,
        spc,
        spotweld,
        spotweldbeams,
        spotweldsurfaces,
        vehicle,
    )

    from ansys.dyna.core.pre import examples, launch_dynapre
    from ansys.dyna.core.pre.dynamaterial import (
        MatModifiedPiecewiseLinearPlasticity,
        MatNull,
        MatPiecewiseLinearPlasticity,
        MatRigid,
        MatSpotweld,
    )
    from ansys.dyna.core.pre.dynamech import (
        DOF,
        AnalysisType,
        BeamPart,
        Contact,
        ContactCategory,
        ContactSurface,
        ContactType,
        Curve,
        DynaMech,
        NodeSet,
        OffsetType,
        PartSet,
        ShellPart,
        TimestepCtrol,
    )
    from ansys.dyna.core.pre.misc import check_valid_ip








.. GENERATED FROM PYTHON SOURCE LINES 85-99

Start the ``pre`` service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before starting the ``pre`` service, you must ensure that the Docker container
for this service has been started. For more information, see "Start the Docker
container for the ``pre`` service" in https://dyna.docs.pyansys.com/version/stable/index.html.

The ``pre`` service can also be started locally, please download the latest version of
ansys-pydyna-pre-server.zip package from https://github.com/ansys/pydyna/releases and start it
referring to the README.rst file in this server package.

Once the ``pre`` service is running, you can connect a client to it using
the hostname and port. This example uses the default localhost and port
(``"localhost"`` and ``"50051"`` respectively).


.. GENERATED FROM PYTHON SOURCE LINES 99-104

.. code-block:: Python

    hostname = "localhost"
    if len(sys.argv) > 1 and check_valid_ip(sys.argv[1]):
        hostname = sys.argv[1]
    camry_solution = launch_dynapre(ip=hostname)








.. GENERATED FROM PYTHON SOURCE LINES 105-110

Import initial mesh data
~~~~~~~~~~~~~~~~~~~~~~~~
Import the initial mesh data (nodes and elements), which includes the
vehicle data, weld data, and platen data.


.. GENERATED FROM PYTHON SOURCE LINES 110-121

.. code-block:: Python

    fns = []
    path = examples.camry_rc + os.sep
    fns.append(path + "Camry_RC_main.k")
    fns.append(path + "501_RIG_BAR_roof_crush_platen5.key")
    fns.append(path + "Camry_V1_NoSusAndPowerTrain_impl7.k")
    fns.append(path + "Camry_V1_NoSusAndPowerTrain_impl7_nodes.k")
    fns.append(path + "roof_welds.k")
    fns.append(path + "weld7.k")
    fns.append(path + "xtra_sw.k")
    camry_solution.open_files(fns)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    ret: true




.. GENERATED FROM PYTHON SOURCE LINES 122-129

Define global control cards
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because roof crush is a quasi-static loading case, you must run this model
as an implicit dynamic solution. Define the global control cards. From
the ``dynasolution`` class, set the termination time and the frequency for
the database ASCII options.


.. GENERATED FROM PYTHON SOURCE LINES 129-131

.. code-block:: Python

    camry_solution.set_termination(10)








.. GENERATED FROM PYTHON SOURCE LINES 132-135

Use the implicit analysis methods in the ``dynamech`` class to define
the IMPLICIT control cards.


.. GENERATED FROM PYTHON SOURCE LINES 135-138

.. code-block:: Python

    camry = DynaMech(analysis=AnalysisType.EXPLICIT)
    camry_solution.add(camry)








.. GENERATED FROM PYTHON SOURCE LINES 139-142

Set the automatic timestep control flag
and the optimal equilibrium iteration count per timestep.


.. GENERATED FROM PYTHON SOURCE LINES 142-148

.. code-block:: Python

    camry.implicitanalysis.set_initial_timestep_size(0.1)
    camry.implicitanalysis.set_timestep(
        control_flag=TimestepCtrol.AUTOMATICALLY_ADJUST_TIMESTEP_SIZE,
        Optimum_equilibrium_iteration_count=511,
    )








.. GENERATED FROM PYTHON SOURCE LINES 149-152

Use the ``set_dynamic()`` method to set the IMASS value to 1 and assign the
gamma and beta values.


.. GENERATED FROM PYTHON SOURCE LINES 152-153

.. code-block:: Python

    camry.implicitanalysis.set_dynamic(gamma=0.6, beta=0.38)







.. GENERATED FROM PYTHON SOURCE LINES 154-157

If normal modes must be extracted, use the ``set_eigenvalue()`` method.
The ``set_solution()`` method defines NSOLVR as 12 (Nolinear with BFGS update).


.. GENERATED FROM PYTHON SOURCE LINES 157-162

.. code-block:: Python

    camry.implicitanalysis.set_eigenvalue()
    camry.implicitanalysis.set_solution(
        iteration_limit=1, stiffness_reformation_limit=50, absolute_convergence_tolerance=-100
    )








.. GENERATED FROM PYTHON SOURCE LINES 163-169

Define materials
~~~~~~~~~~~~~~~~
This model uses four classes of material: ``MAT_NULL``, ``MAT_RIGID,``
``MAT_SPOTWELD``, and ``MAT_PIECEWISE_LINEAR_PLASTICITY``. Use the ``dynamaterial``
class to define these materials.


.. GENERATED FROM PYTHON SOURCE LINES 169-247

.. code-block:: Python

    matnull = MatNull(mass_density=6e-11)
    matrigid = MatRigid(mass_density=7.890e-09, young_modulus=2.100e05, poisson_ratio=0.3)
    matplaten = MatRigid(
        mass_density=7.80e-09,
        young_modulus=2.00e05,
        poisson_ratio=0.3,
        center_of_mass_constraint=1,
        rotational_constraint=7,
    )
    spotweldharden2100 = MatSpotweld(
        mass_density=7.850e-09,
        young_modulus=2.100e05,
        poisson_ratio=0.3,
        yield_stress=510,
        plastic_hardening_modulus=2100,
    )
    spotweldharden2200 = MatSpotweld(
        mass_density=7.850e-09,
        young_modulus=2.100e05,
        poisson_ratio=0.3,
        yield_stress=510,
        plastic_hardening_modulus=2200,
    )
    windowshield = MatModifiedPiecewiseLinearPlasticity(
        mass_density=2.355e-09,
        young_modulus=7.000e04,
        poisson_ratio=0.22,
        yield_stress=30,
        tangent_modulus=1400,
        plastic_strain_to_failure=0.015,
        integration_points_number=1,
    )
    windowsrear = MatModifiedPiecewiseLinearPlasticity(
        mass_density=2.425e-09,
        young_modulus=7.000e04,
        poisson_ratio=0.22,
        yield_stress=30,
        tangent_modulus=1400,
        plastic_strain_to_failure=0.015,
        integration_points_number=1,
    )
    plastic300 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=300, tangent_modulus=5000
    )
    plastic250 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=250, tangent_modulus=5000
    )
    plastic360 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=360, tangent_modulus=5000
    )
    plastic180 = MatPiecewiseLinearPlasticity(
        mass_density=7.850e-09, young_modulus=210000, yield_stress=180, tangent_modulus=5000
    )
    plastic450 = MatPiecewiseLinearPlasticity(
        mass_density=7.850e-09, young_modulus=210000, yield_stress=450, tangent_modulus=5000
    )
    plastic1300 = MatPiecewiseLinearPlasticity(
        mass_density=7.850e-09, young_modulus=210000, yield_stress=1300, tangent_modulus=5000
    )
    plastic400 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=400, tangent_modulus=5000
    )
    plastic500 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=500, tangent_modulus=5000
    )
    plastic675 = MatPiecewiseLinearPlasticity(
        mass_density=7.850e-09, young_modulus=210000, yield_stress=675, tangent_modulus=5000
    )
    plastic310 = MatPiecewiseLinearPlasticity(
        mass_density=2.255e-09, young_modulus=70000, yield_stress=310, tangent_modulus=5000
    )
    plastic220 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=220, tangent_modulus=5000
    )
    plastic220_410 = MatPiecewiseLinearPlasticity(
        mass_density=7.890e-09, young_modulus=210000, yield_stress=220, tangent_modulus=410
    )








.. GENERATED FROM PYTHON SOURCE LINES 248-258

Assign section and material properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Once all materials are explicitly defined, these material IDs must be cross-referenced
in the *PART* card. You use the ``set_material()`` method for this. Because many parts
share common materials, the assignment happens within a loop. Within the loop, the
``set_element_formulation()`` method is called to assign the elform for the beam and
shell elements. Accordingly, either the beam diameter or the shell thickness is also
defined. To identify the part ID that has a particular material type, a predefined
list is made available in the ``camry_rc_data.py`` file, which this script reads.


.. GENERATED FROM PYTHON SOURCE LINES 258-310

.. code-block:: Python

    for bpart in beamparts:
        part = BeamPart(bpart[0])
        if part.id in [50000002]:
            part.set_material(spotweldharden2200)
        else:
            part.set_material(spotweldharden2100)
        part.set_element_formulation(bpart[1])
        part.set_diameter(bpart[2])
        camry.parts.add(part)

    for spart in shellparts:
        part = ShellPart(spart[0])
        if part.id in [1463, 1464]:
            part.set_material(matnull)
        elif part.id in [417, 419, 530, 532, 585, 586, 587, 588]:
            part.set_material(matrigid)
        elif part.id in [50000001]:
            part.set_material(matplaten)
        elif part.id in [290]:
            part.set_material(windowshield)
        elif part.id in [291]:
            part.set_material(windowsrear)
        elif part.id in partswithmat300:
            part.set_material(plastic300)
        elif part.id in partswithmat250:
            part.set_material(plastic250)
        elif part.id in partswithmat360:
            part.set_material(plastic360)
        elif part.id in partswithmat180:
            part.set_material(plastic180)
        elif part.id in partswithmat450:
            part.set_material(plastic450)
        elif part.id in partswithmat400:
            part.set_material(plastic400)
        elif part.id in partswithmat500:
            part.set_material(plastic500)
        elif part.id in [57]:
            part.set_material(plastic1300)
        elif part.id in [286]:
            part.set_material(plastic675)
        elif part.id in [5000000]:
            part.set_material(plastic310)
        elif part.id in [5000006]:
            part.set_material(plastic220)
        elif part.id in [5000007]:
            part.set_material(plastic220_410)
        else:
            pass
        part.set_element_formulation(spart[1])
        part.set_thickness(spart[2])
        camry.parts.add(part)








.. GENERATED FROM PYTHON SOURCE LINES 311-317

Generate keywords for spotwelds and nodal rigid bodies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``camry_rc_data.py`` file contains the predefined node pairs and node sets
required for the *CONSTRAINED_SPOTWELD* and *CONSTRAINED_NODAL_RIGID_BODY*
definitions. Loop through these lists to generate the appropriate keywords.


.. GENERATED FROM PYTHON SOURCE LINES 317-323

.. code-block:: Python

    for sw in spotweld:
        camry.constraints.create_spotweld(nodeid1=sw[0], nodeid2=sw[1])

    for cnrb in cnrbs:
        camry.constraints.create_cnrb(nodeset=NodeSet(cnrb))








.. GENERATED FROM PYTHON SOURCE LINES 324-337

Define contacts
~~~~~~~~~~~~~~~
There are three contacts defined in this model:

- Automatic single surface contact for the BIW self contact
- Surface-to-surface contact between the platen and the BIW self contact
- Tied contact for the spotweld beams

Use the ``ContactSurface()`` method to set the SSTYPE and MSTYPE.
The ``PartSet()`` method accepts the name of a list and converts it to
*PART_SET_LIST*. Notice how the contact type and category can be used
to create the three different type of contacts for this model.


.. GENERATED FROM PYTHON SOURCE LINES 337-366

.. code-block:: Python

    selfcontact = Contact(type=ContactType.AUTOMATIC)
    selfcontact.set_mortar()
    selfcontact.set_friction_coefficient(static=0.2)
    surf1 = ContactSurface(PartSet(vehicle))
    selfcontact.set_slave_surface(surf1)
    camry.contacts.add(selfcontact)

    platebiw = Contact(type=ContactType.AUTOMATIC, category=ContactCategory.SURFACE_TO_SURFACE_CONTACT)
    platebiw.set_mortar()
    platebiw.set_friction_coefficient(static=0.2, dynamic=0.2)
    surf1 = ContactSurface(PartSet(biw))
    surf2 = ContactSurface(PartSet(platen))
    platebiw.set_slave_surface(surf1)
    platebiw.set_master_surface(surf2)
    camry.contacts.add(platebiw)

    swcontact = Contact(
        type=ContactType.TIED,
        category=ContactCategory.SHELL_EDGE_TO_SURFACE_CONTACT,
        offset=OffsetType.CONSTRAINED_OFFSET,
    )
    spotweldbeam = ContactSurface(PartSet(spotweldbeams))
    spotweldbeam.set_contact_thickness(thickness=-0.9)
    spotweldsurface = ContactSurface(PartSet(spotweldsurfaces))
    spotweldsurface.set_contact_thickness(thickness=-0.9)
    swcontact.set_slave_surface(spotweldbeam)
    swcontact.set_master_surface(spotweldsurface)
    camry.contacts.add(swcontact)








.. GENERATED FROM PYTHON SOURCE LINES 367-372

Define SPCs
~~~~~~~~~~~
You can use the ``boundaryconditions`` class to define both SPCs and
prescribed motions. The bottom of the BIW is SPCed by selecting a few nodes.
The prescribed motion is then assigned to the platen.

.. GENERATED FROM PYTHON SOURCE LINES 372-383

.. code-block:: Python

    camry.boundaryconditions.create_spc(NodeSet(spc))

    crv = Curve(
        x=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9.77, 100],
        y=[0, 13, 26, 39, 52, 65, 78, 91, 104, 117, 127, 127],
    )
    platen = PartSet([50000001])
    camry.boundaryconditions.create_imposed_motion(platen, crv, dof=DOF.X_TRANSLATIONAL, scalefactor=-0.0802216)
    camry.boundaryconditions.create_imposed_motion(platen, crv, dof=DOF.Y_TRANSLATIONAL, scalefactor=-0.0802216)
    camry.boundaryconditions.create_imposed_motion(platen, crv, dof=DOF.Z_TRANSLATIONAL, scalefactor=-0.0802216)








.. GENERATED FROM PYTHON SOURCE LINES 384-389

Define database cards and save input file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Define the frequency of output for the binary and ASCII database outputs
and save the input file.


.. GENERATED FROM PYTHON SOURCE LINES 389-401

.. code-block:: Python

    camry_solution.create_database_binary(dt=0.001)
    camry_solution.set_output_database(
        elout=0.0001,
        glstat=0.0001,
        matsum=0.0001,
        nodout=0.0001,
        rbdout=0.0001,
        rcforc=0.0001,
        secforc=0.0001,
    )

    camry_solution.save_file()




.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    '/server/output'




.. rst-class:: sphx-glr-timing

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


.. _sphx_glr_download_examples_Implicit_camry_rc.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: camry_rc.ipynb <camry_rc.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: camry_rc.py <camry_rc.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: camry_rc.zip <camry_rc.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_