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

.. only:: html

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

        :ref:`Go to the end <sphx_glr_download_examples_modeling_features_002-rosettes-ply-directions.py>`
        to download the full example code.

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

.. _sphx_glr_examples_modeling_features_002-rosettes-ply-directions.py:


.. _rosette_example:

Rosette
=======

This example illustrates how you can use rosettes to define the reference directions of a ply.
It only shows the PyACP part of the setup. For a complete composite analysis,
see :ref:`pymapdl_workflow_example`.

.. GENERATED FROM PYTHON SOURCE LINES 35-39

Import modules
--------------

Import the standard library and third-party dependencies.

.. GENERATED FROM PYTHON SOURCE LINES 39-44

.. code-block:: Python

    import pathlib
    import tempfile

    import numpy as np








.. GENERATED FROM PYTHON SOURCE LINES 45-46

Import the PyACP dependencies.

.. GENERATED FROM PYTHON SOURCE LINES 46-57

.. code-block:: Python

    from ansys.acp.core import (
        EdgeSetType,
        PlyType,
        RosetteSelectionMethod,
        RosetteType,
        get_directions_plotter,
        launch_acp,
    )
    from ansys.acp.core.extras import ExampleKeys, get_example_file









.. GENERATED FROM PYTHON SOURCE LINES 59-61

Start ACP and load the model
----------------------------

.. GENERATED FROM PYTHON SOURCE LINES 63-64

Get the example file from the server.

.. GENERATED FROM PYTHON SOURCE LINES 64-68

.. code-block:: Python

    tempdir = tempfile.TemporaryDirectory()
    WORKING_DIR = pathlib.Path(tempdir.name)
    input_file = get_example_file(ExampleKeys.BASIC_FLAT_PLATE_DAT, WORKING_DIR)








.. GENERATED FROM PYTHON SOURCE LINES 69-70

Launch the PyACP server and connect to it.

.. GENERATED FROM PYTHON SOURCE LINES 70-72

.. code-block:: Python

    acp = launch_acp()








.. GENERATED FROM PYTHON SOURCE LINES 73-75

Import the model from the input file.
This example's input file contains a flat plate.

.. GENERATED FROM PYTHON SOURCE LINES 75-78

.. code-block:: Python

    model = acp.import_model(input_file, format="ansys:dat")
    print(model.unit_system)





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

 .. code-block:: none

    mks




.. GENERATED FROM PYTHON SOURCE LINES 79-81

Define directions with a parallel rosette
-----------------------------------------

.. GENERATED FROM PYTHON SOURCE LINES 83-84

Create a material and fabric.

.. GENERATED FROM PYTHON SOURCE LINES 84-91

.. code-block:: Python

    ud_material = model.create_material(
        name="UD",
        ply_type=PlyType.REGULAR,
    )

    fabric = model.create_fabric(name="UD", material=ud_material, thickness=0.1)








.. GENERATED FROM PYTHON SOURCE LINES 92-93

Create a parallel rosette where the first direction is rotated by 45 degrees around the y axis.

.. GENERATED FROM PYTHON SOURCE LINES 93-101

.. code-block:: Python

    parallel_rosette_45_deg = model.create_rosette(
        name="ParallelRosette",
        rosette_type=RosetteType.PARALLEL,
        origin=(0, 0, 0),
        dir1=(np.sqrt(2) / 2, 0, np.sqrt(2) / 2),
        dir2=(-np.sqrt(2) / 2, 0, np.sqrt(2) / 2),
    )








.. GENERATED FROM PYTHON SOURCE LINES 102-103

Create an oriented selection set (OSS) and assign the rosette.

.. GENERATED FROM PYTHON SOURCE LINES 103-113

.. code-block:: Python

    oss = model.create_oriented_selection_set(
        name="oss",
        orientation_point=(0.0, 0.0, 0.0),
        orientation_direction=(0.0, 1.0, 0),
        element_sets=[model.element_sets["All_Elements"]],
        rosettes=[parallel_rosette_45_deg],
    )

    model.update()








.. GENERATED FROM PYTHON SOURCE LINES 114-115

Plot the orientation and reference directions of the OSS.

.. GENERATED FROM PYTHON SOURCE LINES 115-120

.. code-block:: Python

    plotter = get_directions_plotter(
        model=model, components=[oss.elemental_data.orientation, oss.elemental_data.reference_direction]
    )
    plotter.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_001.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_001.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_001.vtksz



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

 .. code-block:: none

    /home/runner/.cache/pypoetry/virtualenvs/ansys-acp-core-O77fA6pn-py3.12/lib/python3.12/site-packages/trame_vuetify/widgets/vuetify.py:495: SyntaxWarning: invalid escape sequence '\|'
      """




.. GENERATED FROM PYTHON SOURCE LINES 121-124

Create a ply that uses the reference directions defined by the rosette.
The ply angle is set to 20 degrees, which means that the fiber direction is rotated by 20 degrees
from the reference direction.

.. GENERATED FROM PYTHON SOURCE LINES 124-132

.. code-block:: Python

    modeling_group = model.create_modeling_group(name="modeling_group")
    modeling_ply = modeling_group.create_modeling_ply(
        name="ply",
        ply_angle=20,
        ply_material=fabric,
        oriented_selection_sets=[oss],
    )








.. GENERATED FROM PYTHON SOURCE LINES 133-134

Plot the reference directions, fiber directions, and transverse directions of the ply.

.. GENERATED FROM PYTHON SOURCE LINES 134-144

.. code-block:: Python

    plotter = get_directions_plotter(
        model=model,
        components=[
            modeling_ply.elemental_data.reference_direction,
            modeling_ply.elemental_data.fiber_direction,
            modeling_ply.elemental_data.transverse_direction,
        ],
    )
    plotter.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_002.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_002.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_002.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 145-153

Define directions with a radial rosette
---------------------------------------

Create a radial rosette and plot the resulting reference directions.
For a radial rosette, a line is constructed that goes through the origin. Its
direction vector is normal to a plane spanned by ``dir1`` and ``dir2``.
Therefore, the reference directions are parallel to the shortest connection from the line to
each point for which it is computed.

.. GENERATED FROM PYTHON SOURCE LINES 153-167

.. code-block:: Python

    radial_rosette = model.create_rosette(
        name="RadialRosette",
        rosette_type=RosetteType.RADIAL,
        origin=(0.005, 0, 0.005),
        dir1=(1, 0, 0),
        dir2=(0, 0, 1),
    )

    oss.rosettes = [radial_rosette]
    model.update()

    plotter = get_directions_plotter(model=model, components=[oss.elemental_data.reference_direction])
    plotter.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_003.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_003.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_003.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 168-174

Define directions with a cylindrical rosette
--------------------------------------------

Create a cylindrical rosette and plot the resulting reference directions.
For a cylindrical rosette, the reference directions are tangential to the circles around the origin
that lie in a plane spanned by ``dir1`` and ``dir2``.

.. GENERATED FROM PYTHON SOURCE LINES 174-188

.. code-block:: Python

    cylindrical_rosette = model.create_rosette(
        name="CylindricalRosette",
        rosette_type=RosetteType.CYLINDRICAL,
        origin=(0.005, 0, 0.005),
        dir1=(1, 0, 0),
        dir2=(0, 0, 1),
    )

    oss.rosettes = [cylindrical_rosette]
    model.update()

    plotter = get_directions_plotter(model=model, components=[oss.elemental_data.reference_direction])
    plotter.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_004.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_004.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_004.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 189-196

Define directions with a spherical rosette
------------------------------------------

Create a spherical rosette and plot the resulting reference directions.
For a spherical rosette, the reference directions are tangential to a sphere around the origin.
Note that for this example, the reference directions of the spherical rosette are the same as
those of the cylindrical rosette.

.. GENERATED FROM PYTHON SOURCE LINES 196-210

.. code-block:: Python

    spherical_rosette = model.create_rosette(
        name="SphericalRosette",
        rosette_type=RosetteType.SPHERICAL,
        origin=(0.005, 0, 0.005),
        dir1=(1, 0, 0),
        dir2=(0, 0, 1),
    )

    oss.rosettes = [spherical_rosette]
    model.update()

    plotter = get_directions_plotter(model=model, components=[oss.elemental_data.reference_direction])
    plotter.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_005.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_005.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_005.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 211-222

Define directions with an edge-wise rosette
-------------------------------------------

Create an edge-wise rosette and plot the resulting reference directions.
The reference directions are given by a projection of ``dir1``
and the path of the edge set. ``dir1`` of the rosette is projected onto the point
on the edge that is closest to the rosette's origin. This determines the reference directions
along the edge set.
You can reverse the reference directions by inverting ``dir1``.
An element within an OSS gets its reference directions from the direction
of the point on the edge that is closest to the element centroid.

.. GENERATED FROM PYTHON SOURCE LINES 224-226

Create the edge set from the "All_Elements" element set. Because you assigned
120 degrees to the limit angle, all the edges are selected.

.. GENERATED FROM PYTHON SOURCE LINES 226-250

.. code-block:: Python

    edge_set = model.create_edge_set(
        name="edge_set",
        edge_set_type=EdgeSetType.BY_REFERENCE,
        limit_angle=120,
        element_set=model.element_sets["All_Elements"],
        origin=(0, 0, 0),
    )

    edge_wise_rosette = model.create_rosette(
        name="EdgeWiseRosette",
        rosette_type=RosetteType.EDGE_WISE,
        edge_set=edge_set,
        origin=(0.005, 0, 0.005),
        dir1=(1, 0, 0),
        dir2=(0, 0, 1),
    )

    oss.rosettes = [edge_wise_rosette]
    model.update()

    plotter = get_directions_plotter(model=model, components=[oss.elemental_data.reference_direction])
    plotter.show()









.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_006.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_006.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_006.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 251-253

Combine rosettes
----------------

.. GENERATED FROM PYTHON SOURCE LINES 255-257

Create an additional parallel rosette that points along the x direction and has its origin
at ``(0.01, 0, 0.01)``.

.. GENERATED FROM PYTHON SOURCE LINES 257-265

.. code-block:: Python

    parallel_rosette_0_deg = model.create_rosette(
        name="ParallelRosette",
        rosette_type=RosetteType.PARALLEL,
        origin=(0.01, 0, 0.01),
        dir1=(1, 0, 0),
        dir2=(0, 0, 1),
    )








.. GENERATED FROM PYTHON SOURCE LINES 266-270

Assign both rosettes to the OSS and set the rosette selection method to
``RosetteSelectionMethod.MINIMUM_DISTANCE_SUPERPOSED``. This implies that the reference directions
are weighted by the inverse distance to each rosette. Note that the origin of
the rotated rosette is at ``(0,0,0)``.

.. GENERATED FROM PYTHON SOURCE LINES 270-273

.. code-block:: Python

    oss.rosettes = [parallel_rosette_45_deg, parallel_rosette_0_deg]
    oss.rosette_selection_method = RosetteSelectionMethod.MINIMUM_DISTANCE_SUPERPOSED








.. GENERATED FROM PYTHON SOURCE LINES 274-275

Plot the resulting reference directions.

.. GENERATED FROM PYTHON SOURCE LINES 275-278

.. code-block:: Python

    model.update()
    plotter = get_directions_plotter(model=model, components=[oss.elemental_data.reference_direction])
    plotter.show()







.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_007.png
        :alt: 002 rosettes ply directions
        :srcset: /examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_007.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyacp/pyacp/doc/source/examples/modeling_features/images/sphx_glr_002-rosettes-ply-directions_007.vtksz







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

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


.. _sphx_glr_download_examples_modeling_features_002-rosettes-ply-directions.py:

.. only:: html

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

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

      :download:`Download Jupyter notebook: 002-rosettes-ply-directions.ipynb <002-rosettes-ply-directions.ipynb>`

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

      :download:`Download Python source code: 002-rosettes-ply-directions.py <002-rosettes-ply-directions.py>`

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

      :download:`Download zipped: 002-rosettes-ply-directions.zip <002-rosettes-ply-directions.zip>`


.. only:: html

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

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