Postprocess a harmonic analysis#

This example shows how to evaluate failure criteria for a harmonic simulation. It shows how to create a phase sweep to compute the maximum IRF in the frequency-phase space and shows how to identify the critical failure mode and the critical layer.

Note

When using a Workbench project, use the composite_files_from_workbench_harmonic_analysis() method to obtain the input files.

Set up analysis#

Setting up the analysis consists of loading the required modules, connecting to the DPF server, and retrieving the example files.

Load Ansys libraries and matplotlib

import ansys.dpf.core as dpf
import matplotlib.pyplot as plt

from ansys.dpf.composites.composite_model import CompositeModel
from ansys.dpf.composites.constants import FAILURE_LABEL, FailureOutput
from ansys.dpf.composites.example_helper import get_continuous_fiber_example_files
from ansys.dpf.composites.failure_criteria import (
    CombinedFailureCriterion,
    FailureModeEnum,
    MaxStressCriterion,
    TsaiWuCriterion,
)
from ansys.dpf.composites.layup_info.material_operators import get_material_operators
from ansys.dpf.composites.server_helpers import connect_to_or_start_server
from ansys.dpf.composites.unit_system import get_unit_system

Start a DPF server and copy the example files into the current working directory.

server = connect_to_or_start_server()
composite_files_on_server = get_continuous_fiber_example_files(server, "harmonic")

Create a composite model

composite_model = CompositeModel(composite_files_on_server, server)

Define a failure criterion

combined_fc = CombinedFailureCriterion(
    name="My Failure Criteria",
    failure_criteria=[
        MaxStressCriterion(),
        TsaiWuCriterion(),
    ],
)

Obtain stresses and strains and compute max IRF over all phases and frequencies#

Get complex stresses and strains at all frequencies

stress_operator = composite_model.core_model.results.stress.on_all_time_freqs()
stress_operator.inputs.bool_rotate_to_global(False)

strain_operator = composite_model.core_model.results.elastic_strain.on_all_time_freqs()
strain_operator.inputs.bool_rotate_to_global(False)

Get operators that provide material data

material_operators = get_material_operators(
    composite_model.data_sources.rst,
    composite_model.data_sources.engineering_data,
    get_unit_system(composite_model.data_sources.rst),
)

Define the frequency sweep. This is relatively coarse so the example does not take too much time.

Initialize result containers. We create a result container for the failure value, the failure mode and the layer index in which the failure occurs.

Loop over all the phases and evaluate the failure criterion. The result is added to the field containers declared in the previous cell. In the end each container contains a field for each combination of frequency and phase

for phase in sweep_phases:
    # Stress & strains at sweeping phase
    stress_at_phase = dpf.operators.math.sweeping_phase_fc(
        fields_container=stress_operator, angle=float(phase), unit_name="deg", abs_value=False
    )

    strain_at_phase = dpf.operators.math.sweeping_phase_fc(
        fields_container=strain_operator, angle=float(phase), unit_name="deg", abs_value=False
    )

    failure_evaluator = dpf.Operator("composite::multiple_failure_criteria_operator")
    failure_evaluator.inputs.configuration(combined_fc.to_json())
    failure_evaluator.inputs.materials_container(material_operators.material_provider)
    failure_evaluator.inputs.stresses_container(stress_at_phase)
    failure_evaluator.inputs.strains_container(strain_at_phase)
    failure_evaluator.inputs.mesh(composite_model.get_mesh())

    # Note: the min/max layer indices are 1-based starting with
    # Workbench 2024 R1 (DPF server 7.1)
    minmax_per_element = dpf.Operator("composite::minmax_per_element_operator")
    minmax_per_element.inputs.fields_container(failure_evaluator)
    minmax_per_element.inputs.mesh(composite_model.get_mesh())
    minmax_per_element.inputs.material_support(
        material_operators.material_support_provider.outputs.abstract_field_support
    )

    max_for_all_frequencies_at_phase = minmax_per_element.outputs.field_max()

    for frequency_id in max_for_all_frequencies_at_phase.get_time_scoping().ids:
        output_label = {FREQ_LABEL: frequency_id, PHASE_LABEL: phase}
        all_phases_and_freqs_failure_value_fc.add_field(
            output_label,
            max_for_all_frequencies_at_phase.get_field(
                {FAILURE_LABEL: FailureOutput.FAILURE_VALUE.value, FREQ_LABEL: frequency_id}
            ),
        )
        all_phases_and_freqs_critical_layer_fc.add_field(
            output_label,
            max_for_all_frequencies_at_phase.get_field(
                {FAILURE_LABEL: FailureOutput.MAX_LAYER_INDEX.value, FREQ_LABEL: frequency_id}
            ),
        )

        all_phases_and_freqs_failure_mode_fc.add_field(
            output_label,
            max_for_all_frequencies_at_phase.get_field(
                {FAILURE_LABEL: FailureOutput.FAILURE_MODE.value, FREQ_LABEL: frequency_id}
            ),
        )

Compute maximum over all the phases and frequencies for each element and plot the resulting IRF values

010 harmonic example

Detailed analysis of the critical element#

Identify the element with the maximum IRF

The element with highest IRF is 3.

Scope container with all frequencies and phases to critical element so we can plot the critical IRF over all the frequencies

Compute the maximum IRF over all the phases for each frequency and plot the result for the critical element. Note: this can be different from maximum overall IRF at each frequency, because we look only at the element that has the highest IRF overall.

010 harmonic example
[<matplotlib.lines.Line2D object at 0x7f73ec6c0550>]

Compute the critical phase

The phase with the highest IRF is -120°.

Compute critical layer and critical failure mode.

The critical ply is P1L1__ModelingPly.3.
The maximum IRF is 0.17852210868866686.
The critical failure mode is s1c.

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

Gallery generated by Sphinx-Gallery