Direction definition example#

This example shows how to define directions from lookup tables. They can be either reference directions for oriented selection sets or draping angles for modeling plies. The example only shows the PyACP part of the setup. For a complete composite analysis, see Basic PyACP workflow example.

Import modules#

Import the standard library and third-party dependencies.

import pathlib
import tempfile

import numpy as np

Import the PyACP dependencies.

from ansys.acp.core import (
    ACPWorkflow,
    DimensionType,
    DrapingType,
    LookUpTableColumnValueType,
    PlyType,
    RosetteSelectionMethod,
    get_directions_plotter,
    launch_acp,
)
from ansys.acp.core.example_helpers import ExampleKeys, get_example_file

Start ACP and load the model#

Get the example file from the server.

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

Launch the PyACP server and connect to it.

acp = launch_acp()

Define the input file and instantiate an ACPWorkflow instance. The ACPWorkflow class provides convenience methods that simplify the handling. It automatically creates a model based on the input file. This example’s input file contains a flat plate with a single ply.

workflow = ACPWorkflow.from_cdb_or_dat_file(
    acp=acp,
    cdb_or_dat_file_path=input_file,
    local_working_directory=WORKING_DIR,
)

model = workflow.model
print(workflow.working_directory.path)
print(model.unit_system)
/tmp/tmpb8u7tdmo
mks

Setup materials and oriented selection set#

#

Create a material and fabric.

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

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

Create a parallel rosette.

rosette = model.create_rosette()

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

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

Plot the orientation and reference direction of the OSS. The reference direction is defined by the rosette.

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

Define reference direction from lookup table#

Create a 3D lookup table to store the direction and angle corrections.

lookup_table = model.create_lookup_table_3d()

Create a grid of points on the plate where the lookup table values are stored.

Compute the directions tangential to circles around the point (0,0,0).

Create the lookup table and add the direction data.

lookup_table.columns["Location"].data = points
direction_column = lookup_table.create_column(
    data=directions,
    dimension_type=DimensionType.DIMENSIONLESS,
    value_type=LookUpTableColumnValueType.DIRECTION,
)

Assign the lookup table to the OSS.

oss.rosette_selection_method = RosetteSelectionMethod.DIRECTIONS_FROM_TABULAR_VALUES
oss.reference_direction_field = direction_column

Plot the orientation and the reference direction of the OSS.

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

Reset the OSS so that it may use the rosette again for the reference direction.

oss.rosette_selection_method = RosetteSelectionMethod.MINIMUM_ANGLE

Define draping angles from lookup table#

%% Compute a correction angle to define circular fiber paths.

correction_angle = np.arctan2(xx.ravel(), zz.ravel()) * 180 / np.pi
angle_column_1 = lookup_table.create_column(
    data=correction_angle,
    dimension_type=DimensionType.DIMENSIONLESS,
    value_type=LookUpTableColumnValueType.SCALAR,
)

Compute the transverse correction angle, assuming a constant shear angle of -30°.

shear_angle = -30
transverse_correction_angle = correction_angle + shear_angle
angle_column_2 = lookup_table.create_column(
    data=transverse_correction_angle,
    dimension_type=DimensionType.DIMENSIONLESS,
    value_type=LookUpTableColumnValueType.SCALAR,
)

Create a modeling ply with the angle corrections.

modeling_group = model.create_modeling_group(name="modeling_group")
modeling_ply = modeling_group.create_modeling_ply(
    name="ply",
    ply_angle=0,
    ply_material=fabric,
    oriented_selection_sets=[oss],
    draping=DrapingType.TABULAR_VALUES,
    draping_angle_1_field=angle_column_1,
    draping_angle_2_field=angle_column_2,
)

Plot the directions of the modeling ply. First, plot the directions without correction angles.

model.update()
plotter = get_directions_plotter(
    model=model,
    components=[
        modeling_ply.elemental_data.fiber_direction,
        modeling_ply.elemental_data.transverse_direction,
    ],
)
plotter.show()
007 direction definitions

Next, plot the draped directions, including the correction angles, from the lookup table.

plotter = get_directions_plotter(
    model=model,
    components=[
        modeling_ply.elemental_data.draped_fiber_direction,
        modeling_ply.elemental_data.draped_transverse_direction,
    ],
)
plotter.show()
007 direction definitions

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

Gallery generated by Sphinx-Gallery