.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/workflows/06-cdb-to-pymechanical-workflow.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_workflows_06-cdb-to-pymechanical-workflow.py: .. _cdb_to_pymechanical_example: CDB to PyMechanical shell workflow ================================== This example shows how to define a composite lay-up in PyACP based on a mesh from a CDB file, import the model into PyMechanical for defining the load and boundary conditions, and run a failure analysis with PyDPF Composites. .. warning:: The PyACP / PyMechanical integration is still experimental. Refer to the :ref:`limitations section ` for more information. .. GENERATED FROM PYTHON SOURCE LINES 44-46 Import modules and start the Ansys products ------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 49-50 Import the standard library and third-party dependencies. .. GENERATED FROM PYTHON SOURCE LINES 50-56 .. code-block:: Python from concurrent.futures import ThreadPoolExecutor import pathlib import tempfile import textwrap .. GENERATED FROM PYTHON SOURCE LINES 57-58 Import PyACP, PyMechanical, and PyDPF Composites. .. GENERATED FROM PYTHON SOURCE LINES 58-66 .. code-block:: Python # isort: off import ansys.acp.core as pyacp from ansys.acp.core.extras import example_helpers import ansys.dpf.composites as pydpf_composites import ansys.mechanical.core as pymechanical .. GENERATED FROM PYTHON SOURCE LINES 68-70 Start the ACP, Mechanical, and DPF servers. We use a ``ThreadPoolExecutor`` to start them in parallel. .. GENERATED FROM PYTHON SOURCE LINES 70-78 .. code-block:: Python with ThreadPoolExecutor() as executor: futures = [ executor.submit(pyacp.launch_acp), executor.submit(pymechanical.launch_mechanical, batch=True), executor.submit(pydpf_composites.server_helpers.connect_to_or_start_server), ] acp, mechanical, dpf = (fut.result() for fut in futures) .. GENERATED FROM PYTHON SOURCE LINES 79-84 Get example input files ----------------------- Create a temporary working directory, and download the example input files to this directory. .. GENERATED FROM PYTHON SOURCE LINES 84-91 .. code-block:: Python working_dir = tempfile.TemporaryDirectory() working_dir_path = pathlib.Path(working_dir.name) input_file = example_helpers.get_example_file( example_helpers.ExampleKeys.BASIC_FLAT_PLATE_DAT, working_dir_path ) .. GENERATED FROM PYTHON SOURCE LINES 92-96 Set up the ACP model -------------------- Setup basic ACP lay-up based on the CDB file. .. GENERATED FROM PYTHON SOURCE LINES 96-101 .. code-block:: Python model = acp.import_model(path=input_file, format="ansys:cdb") model.unit_system .. GENERATED FROM PYTHON SOURCE LINES 102-103 Visualize the loaded mesh. .. GENERATED FROM PYTHON SOURCE LINES 103-107 .. code-block:: Python mesh = model.mesh.to_pyvista() mesh.plot(show_edges=True) .. GENERATED FROM PYTHON SOURCE LINES 108-113 Define the composite lay-up --------------------------- Create an orthotropic material and fabric including strain limits, which are later used to postprocess the simulation. .. GENERATED FROM PYTHON SOURCE LINES 113-142 .. code-block:: Python engineering_constants = ( pyacp.material_property_sets.ConstantEngineeringConstants.from_orthotropic_constants( E1=5e10, E2=1e10, E3=1e10, nu12=0.28, nu13=0.28, nu23=0.3, G12=5e9, G23=4e9, G31=4e9 ) ) strain_limit = 0.01 strain_limits = pyacp.material_property_sets.ConstantStrainLimits.from_orthotropic_constants( eXc=-strain_limit, eYc=-strain_limit, eZc=-strain_limit, eXt=strain_limit, eYt=strain_limit, eZt=strain_limit, eSxy=strain_limit, eSyz=strain_limit, eSxz=strain_limit, ) ud_material = model.create_material( name="UD", ply_type=pyacp.PlyType.REGULAR, engineering_constants=engineering_constants, strain_limits=strain_limits, ) fabric = model.create_fabric(name="UD", material=ud_material, thickness=1e-4) .. GENERATED FROM PYTHON SOURCE LINES 143-144 Define a rosette and oriented selection set. Plot the orientation. .. GENERATED FROM PYTHON SOURCE LINES 144-160 .. code-block:: Python rosette = model.create_rosette(origin=(0.0, 0.0, 0.0), dir1=(1.0, 0.0, 0.0), dir2=(0.0, 0.0, 1.0)) 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=[rosette], ) model.update() plotter = pyacp.get_directions_plotter(model=model, components=[oss.elemental_data.orientation]) plotter.show() .. GENERATED FROM PYTHON SOURCE LINES 161-162 Create various plies with different angles and add them to a modeling group. .. GENERATED FROM PYTHON SOURCE LINES 162-175 .. code-block:: Python modeling_group = model.create_modeling_group(name="modeling_group") angles = [0, 45, -45, 45, -45, 0] for idx, angle in enumerate(angles): modeling_group.create_modeling_ply( name=f"ply_{idx}_{angle}_{fabric.name}", ply_angle=angle, ply_material=fabric, oriented_selection_sets=[oss], ) model.update() .. GENERATED FROM PYTHON SOURCE LINES 176-177 Show the fiber directions of a specific ply. .. GENERATED FROM PYTHON SOURCE LINES 177-190 .. code-block:: Python modeling_ply = model.modeling_groups["modeling_group"].modeling_plies["ply_4_-45_UD"] fiber_direction = modeling_ply.elemental_data.fiber_direction assert fiber_direction is not None plotter = pyacp.get_directions_plotter( model=model, components=[fiber_direction], ) plotter.show() .. GENERATED FROM PYTHON SOURCE LINES 191-194 For a quick overview, print the model tree. Note that the model can also be opened in the ACP GUI. For more information, see :ref:`view_the_model_in_the_acp_gui`. .. GENERATED FROM PYTHON SOURCE LINES 194-196 .. code-block:: Python pyacp.print_model(model) .. GENERATED FROM PYTHON SOURCE LINES 197-199 Save the ACP model ------------------ .. GENERATED FROM PYTHON SOURCE LINES 199-209 .. code-block:: Python cdb_filename = "model.cdb" composite_definitions_h5_filename = "ACPCompositeDefinitions.h5" matml_filename = "materials.xml" model.export_analysis_model(working_dir_path / cdb_filename) model.export_shell_composite_definitions(working_dir_path / composite_definitions_h5_filename) model.export_materials(working_dir_path / matml_filename) .. GENERATED FROM PYTHON SOURCE LINES 210-214 Import mesh, materials and plies into Mechanical ------------------------------------------------ Import geometry, mesh, and named selections into Mechanical .. GENERATED FROM PYTHON SOURCE LINES 214-221 .. code-block:: Python pyacp.mechanical_integration_helpers.import_acp_mesh_from_cdb( mechanical=mechanical, cdb_path=working_dir_path / cdb_filename ) .. GENERATED FROM PYTHON SOURCE LINES 222-223 Import materials into Mechanical .. GENERATED FROM PYTHON SOURCE LINES 223-226 .. code-block:: Python mechanical.run_python_script(f"Model.Materials.Import({str(working_dir_path / matml_filename)!r})") .. GENERATED FROM PYTHON SOURCE LINES 227-228 Import plies into Mechanical .. GENERATED FROM PYTHON SOURCE LINES 228-233 .. code-block:: Python pyacp.mechanical_integration_helpers.import_acp_composite_definitions( mechanical=mechanical, path=working_dir_path / composite_definitions_h5_filename ) .. GENERATED FROM PYTHON SOURCE LINES 234-237 Set boundary condition and solve --------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 237-280 .. code-block:: Python mechanical.run_python_script( textwrap.dedent( """\ front_edge = Model.AddNamedSelection() front_edge.Name = "Front Edge" front_edge.ScopingMethod = GeometryDefineByType.Worksheet front_edge.GenerationCriteria.Add(None) front_edge.GenerationCriteria[0].EntityType = SelectionType.GeoEdge front_edge.GenerationCriteria[0].Criterion = SelectionCriterionType.LocationX front_edge.GenerationCriteria[0].Operator = SelectionOperatorType.Largest front_edge.Generate() back_edge = Model.AddNamedSelection() back_edge.Name = "Back Edge" back_edge.ScopingMethod = GeometryDefineByType.Worksheet back_edge.GenerationCriteria.Add(None) back_edge.GenerationCriteria[0].EntityType = SelectionType.GeoEdge back_edge.GenerationCriteria[0].Criterion = SelectionCriterionType.LocationX back_edge.GenerationCriteria[0].Operator = SelectionOperatorType.Smallest back_edge.Generate() analysis = Model.AddStaticStructuralAnalysis() fixed_support = analysis.AddFixedSupport() fixed_support.Location = back_edge force = analysis.AddForce() force.DefineBy = LoadDefineBy.Components force.XComponent.Output.SetDiscreteValue(0, Quantity(100, "N")) force.Location = front_edge analysis.Solution.Solve(True) """ ) ) rst_file = [filename for filename in mechanical.list_files() if filename.endswith(".rst")][0] matml_out = [filename for filename in mechanical.list_files() if filename.endswith("MatML.xml")][0] .. GENERATED FROM PYTHON SOURCE LINES 281-285 Postprocess results ------------------- Evaluate the failure criteria using the PyDPF Composites. .. GENERATED FROM PYTHON SOURCE LINES 285-315 .. code-block:: Python max_strain = pydpf_composites.failure_criteria.MaxStrainCriterion() cfc = pydpf_composites.failure_criteria.CombinedFailureCriterion( name="Combined Failure Criterion", failure_criteria=[max_strain], ) composite_model = pydpf_composites.composite_model.CompositeModel( composite_files=pydpf_composites.data_sources.ContinuousFiberCompositesFiles( rst=rst_file, composite={ "shell": pydpf_composites.data_sources.CompositeDefinitionFiles( definition=working_dir_path / composite_definitions_h5_filename ), }, engineering_data=working_dir_path / matml_out, ), server=dpf, ) # Evaluate the failure criteria output_all_elements = composite_model.evaluate_failure_criteria(cfc) # Query and plot the results irf_field = output_all_elements.get_field( {"failure_label": pydpf_composites.constants.FailureOutput.FAILURE_VALUE} ) irf_field.plot() .. _sphx_glr_download_examples_workflows_06-cdb-to-pymechanical-workflow.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 06-cdb-to-pymechanical-workflow.ipynb <06-cdb-to-pymechanical-workflow.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 06-cdb-to-pymechanical-workflow.py <06-cdb-to-pymechanical-workflow.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 06-cdb-to-pymechanical-workflow.zip <06-cdb-to-pymechanical-workflow.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_