How to extract result fields from LS-DYNA using PyDPF-Core

Member Posts: 24
10 Comments Name Dropper
**

I would like to extract Principal stresses, von Mises stress and directional displacements fields from LS-DYNA using PyDPF-Core. Below is my implementation, but currently, I can only plot one displacement field, and it’s unclear which type of displacement it represents. Additionally, when trying to extract von Mises stress, I encounter an “AttributeError: ‘CommonResults’ object has no attribute ‘von_mises_stress’.”

path0 = r'C:\my_path'
path = os.path.join(path0, "d3plot")
act_units = os.path.join(path0, "file.actunits")

ds = dpf.DataSources()
ds.set_result_file_path(path, "d3plot")
ds.add_file_path(act_units , "actunits")

model = dpf.Model(ds)
print(model)

cpos_list = ['xy' ,'xz', 'yz', 'yx', 'zx', 'zy', 'iso']

cpos = cpos_list[0]

cpos =[(1, 1, 50),
(10, 10, 0),
(0, 1, 0)

N = model.results.stress(time_scoping=[12]).eval()
u = model.results.displacement(time_scoping=[12]).eval()
eqv_stress = model.results.von_mises_stress(time_scoping=[12]).eval()

fields_d_= u[0]
pl = DpfPlotter(notebook=False, off_screen=True)

Add the field to the plotter

pl.add_field(fields_d_, model.metadata.meshed_region,how_edges=True, opacity=0.8,
show_max=True,show_min=True,label_text_size=10)
output_image_path_d = os.path.join(os.getcwd(), 'Visualizations/disp.png')
pl.show_figure(cpos=cpos, screenshot=output_image_path_d,auto_close=False)

Welcome!

It looks like you're new here. Sign in or register to get started.
«1

Answers

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @hbolandi said:
    @Ayush Kumar, I would like to extract Principal stresses, von Mises stress and directional displacements fields from LS-DYNA using PyDPF-Core. Below is my implementation, but currently, I can only plot one displacement field, and it’s unclear which type of displacement it represents. Additionally, when trying to extract von Mises stress, I encounter an “AttributeError: ‘CommonResults’ object has no attribute ‘von_mises_stress’.”

    path0 = r'C:\my_path'
    path = os.path.join(path0, "d3plot")
    act_units = os.path.join(path0, "file.actunits")

    ds = dpf.DataSources()
    ds.set_result_file_path(path, "d3plot")
    ds.add_file_path(act_units , "actunits")

    model = dpf.Model(ds)
    print(model)

    cpos_list = ['xy' ,'xz', 'yz', 'yx', 'zx', 'zy', 'iso']
    cpos =[(1, 1, 50),
    (10, 10, 0),
    (0, 1, 0)

    N = model.results.stress(time_scoping=[12]).eval()
    u = model.results.displacement(time_scoping=[12]).eval()
    eqv_stress = model.results.von_mises_stress(time_scoping=[12]).eval()

    fields_d_= u[0]
    pl = DpfPlotter(notebook=False, off_screen=True)

    pl.add_field(fields_d_, model.metadata.meshed_region,how_edges=True, opacity=0.8,
    show_max=True,show_min=True,label_text_size=10)
    output_image_path_d = os.path.join(os.getcwd(), 'Visualizations/disp.png')
    pl.show_figure(cpos=cpos, screenshot=output_image_path_d,auto_close=False)

  • Member, Moderator, Employee Posts: 312
    50 Answers 100 Comments Second Anniversary 25 Likes
    ✭✭✭✭

    Not sure about all the questions.

    But if yo do print(model)

    Then we can see what results are included:

    e.g.,

    1. - velocity: Nodal Velocity
    2. - acceleration: Nodal Acceleration
    3. - stress: Elemental Stress
    4. - stress_von_mises: Elemental Stress Von Mises
    5. - plastic_strain_eqv: Elemental Plastic Strain Eqv
    6. - total_strain: Elemental Total Strain

    So as shown above the VM stress is say model.results.stress_von_mises and not von_mises_stress.

    Hope some of this helps

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    Thanks @Erik Kostson for the solution.
    @hbolandi you tagged the wrong Ayush :smile:

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Erik Kostson thanks for your response! The model displayed below. It might be due to the PyDPF-Core version, but for me, it's showing as von_mises_stress. Any thoughts?"

    Available results:
    - global_kinetic_energy: Unknown Global Kinetic Energy
    - global_internal_energy: Unknown Global Internal Energy
    - global_total_energy: Unknown Global Total Energy
    - global_velocity: Unknown Global Velocity
    - node_initial_coordinates: Unknown Node Initial Coordinates
    - node_coordinates: Unknown Node Coordinates
    - node_velocity: Nodal Node Velocity
    - node_acceleration: Nodal Node Acceleration
    - stress: Elemental Stress
    - von_mises_stress: Elemental Von Mises Stress
    - effective_plastic_strain: Elemental Effective Plastic Strain
    - displacement: Nodal Displacement

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar Sorry for the wrong tag. Do you have any thoughts on how to extract principal stresses and directional displacements from LS-DYNA using PyDPF-Core?

  • Member, Moderator, Employee Posts: 312
    50 Answers 100 Comments Second Anniversary 25 Likes
    ✭✭✭✭
    edited September 2024

    Hi
    For principal stresses not sure (perhaps we need to calculate from stress tensor).

    For directional displacement say z-dir., see below

    Hope it helps (not sure if you can plot these :))

    1. displacements = model.results.displacement(time_scoping=[22])
    2.  
    3. fields = displacements.outputs.fields_container()
    4.  
    5. arvm=fields[0].data
    6.  
    7. print(arvm[0][2]) # for z for x - arvm[0][0], etc.
  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi as @Erik Kostson points out, for principal stress you need to calculate it from the stress tensor. Pass the tensor as the input to the following operator to get principal stresses:

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi for displacements you can use component selector on the displacement vector, refer to operator help.

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Erik Kostson fields = displacements.outputs.fields_container() raised the following error:

    AttributeError: 'FieldsContainer' object has no attribute 'outputs'

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar thanks for your response! I tried using stress_fields = stress.outputs.fields_container() to calculate the stress container, but I encountered the same error as with the displacement field: AttributeError: 'FieldsContainer' object has no attribute 'outputs'.

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi looking at your code above, the following are already field containers, you can pass those directly to the code snapshots in my above posts.

    1. N = model.results.stress(time_scoping=[12]).eval()
    2. u = model.results.displacement(time_scoping=[12]).eval()
    3. eqv_stress = model.results.von_mises_stress(time_scoping=[12]).eval()
  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar thanks for your response! I tried to plot the first principal stress filed using the code below, but encountered this error: "AttributeError: 'Output' object has no attribute 'name' " which is originated from pl.add_field

    N = model.results.stress(time_scoping=[12]).eval()
    op = dpf.operators.invariant.principal_invariants_fc()
    op.inputs.fields_container.connect(N)
    my_fields_eig_1 = op.outputs.fields_eig_1
    my_fields_eig_2 = op.outputs.fields_eig_2
    my_fields_eig_3 = op.outputs.fields_eig_3

    pl = DpfPlotter(notebook=False, off_screen=True)

    pl.add_field(my_fields_eig_1, model.metadata.meshed_region,how_edges=True, opacity=0.8,
    show_max=True,show_min=True,label_text_size=10)
    output_image_path_d = os.path.join(os.getcwd(), 'Visualizations/S1.png')
    pl.show_figure(cpos=cpos, screenshot=output_image_path_d,auto_close=False)

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi parenthesis are missing:

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar Nice catch!

    After adding the parentheses, I attempted to plot the stress fields as described in my earlier post. However, I encountered the following error:

    1. server_meet_version_and_raise
    2. raise dpf_errors.DpfVersionNotSupported(required_version, msg=msg)
    3. DpfVersionNotSupported: called from name

    I checked my dpf.core version, and it is the latest one (0.13.0). Any thoughts on this?

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi check your server version with the following command and check for compatibility with ansys.dpf.core version.

    https://dpf.docs.pyansys.com/version/stable/getting_started/compatibility.html

    dpf.SERVER.info

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar I am using ANSYS 2022R2. According to the requirements from the link you provided, I should have DPF server version 4 and DPF core version 0.10.0 or later, which I already have. That being said the server and dpf versions should be compatible.

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi 22R2 was way too old for DPF to work with LS-Dyna results. I would suggest using 24R2 in case you have 24R2 installed. Below are the commands to connect to a 24R2 server. Another option is installing a standalone DPF Server. Link below.

    1. from ansys.dpf import core as dpf
    2. server = dpf.start_local_server(ansys_path=r"C:\Program Files\ANSYS Inc\v242")

    https://dpf.docs.pyansys.com/version/stable/getting_started/dpf_server.html

  • Member Posts: 20
    10 Comments First Anniversary 5 Likes First Answer
    **

    @hbolandi, if you prefer to use some lightweight solution there is standalone DPF

    https://dpf.docs.pyansys.com/version/stable/getting_started/dpf_server.html#install-dpf-server

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar I Installed ANSYS 2024R2 and checked its compatibility with ansys.dpf.core version. This is my code:

    ``` path0 = r’C:\Users\my_path’

    path = os.path.join(path0, "d3plot")

    act_units = os.path.join(path0, "file.actunits")

    ds = dpf.DataSources()
    ds.set_result_file_path(path, "d3plot")
    ds.add_file_path(act_units , "actunits")

    model = dpf.Model(ds)

    cpos_list = ['xy' ,'xz', 'yz', 'yx', 'zx', 'zy', 'iso']
    cpos =[(1, 1, 50),
    (10, 10, 0),
    (0, 1, 0) ]

    N = model.results.stress(time_scoping=[12]).eval()
    op = dpf.operators.invariant.principal_invariants_fc()
    op.inputs.fields_container.connect(N)
    my_fields_eig_1 = op.outputs.fields_eig_1()
    my_fields_eig_2 = op.outputs.fields_eig_2()
    my_fields_eig_3 = op.outputs.fields_eig_3()
    print(my_fields_eig_1)

    pl = DpfPlotter(notebook=False, off_screen=True)

    pl.add_field(my_fields_eig_1[0], model.metadata.meshed_region,how_edges=True, opacity=0.8, show_max=True,show_min=True,label_text_size=10) ```

    It raised error below:

    IndexError: boolean index did not match indexed array along dimension 0; dimension is 2151 but corresponding boolean dimension is 717

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭
    edited September 2024

    @hbolandi there is known bug where the LS-Dyna stress results are reported like shell layers results even for solid elements, this bug has been fixed and the bugfix should be available in the next release. For now, you can use a workaround, where you pass all your stress results through the change_shell_layer operator, so it can strip down all the inconsistency in results. The following should work:

    1. layer = dpf.operators.utility.change_shell_layers(fields_container=my_fields_eig_1, e_shell_layer=0, mesh=model.metadata.meshed_region)
    2. layer_fc = layer.outputs.fields_container_as_fields_container.get_data()
    3.  
    4. pl.add_field(layer_fc[0], model.metadata.meshed_region)
    5.  
  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar Thanks for your solution! it worked both for principal stress and displacement components. could you also guide me know how to extract von Mises stress filed.

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi please refer to DPF operators help document. You can search for keywords to get the right operator.
    https://dpf.docs.pyansys.com/version/stable/operator_reference_load.html

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar Thanks for your response! Based on the link you provided I implemented the code below.

    path0 = r'C:\Users\my_path
    path = os.path.join(path0, "d3plot")
    act_units = os.path.join(path0, "file.actunits")

    ds = dpf.DataSources()
    ds.set_result_file_path(path, "d3plot")
    ds.add_file_path(act_units , "actunits")

    model = dpf.Model(ds)

    cpos_list = ['xy' ,'xz', 'yz', 'yx', 'zx', 'zy', 'iso']
    cpos =[(1, 1, 50), # Camera position (X, Y, Z)
    (10, 10, 0), # Target point (X, Y, Z)
    (0, 1, 0) ]#

    op = dpf.operators.result.stress_eqv_as_mechanical() # operator instantiation
    op.inputs.time_scoping.connect([12])# optional
    op.inputs.data_sources.connect(ds)
    fields_container_eqv = op.outputs.fields_container()
    meshes_container = op.outputs.meshes_container()

    layer_eqv = dpf.operators.utility.change_shell_layers(fields_container=fields_container_eqv, e_shell_layer=0, mesh=model.metadata.meshed_region)
    layer_fc_eqv = layer_eqv.outputs.fields_container_as_fields_container.get_data()

    pl = DpfPlotter(notebook=False, off_screen=True)

    pl.add_field(layer_fc_eqv[0], model.metadata.meshed_region,how_edges=True, opacity=0.8,
    show_max=True,show_min=True,label_text_size=10)

    image_path_d = os.path.join(os.getcwd(), 'Visualizations/von_Mises.png')
    pl.show_figure(cpos=cpos, screenshot=output_image_path_d,auto_close=False)

    But it through the following error:

    DPFServerException: stress_eqv_as_mechanical:431<-error code 4:DPF error - runtime error: dpf core function call; remove_unnecessary_label:461<-logic::if:475<-Rescope_fc:460<-logic::if:474<-merge::weighted_fields_container_label:459<-eqv_fc:458<-logic::if:473<-elemental_nodal_To_nodal_fc:457<-S:455<-averaging from Elemental to ElementalNodal is not implemented

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi sorry, I just realized the previous operator is meant for APDL results for LS-Dyna you can use the following:

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar Thanks for your response! If I want to take the maximum stress over time should I implement a loop to iterate over all time steps to take the max or is there a simpler way?

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi, use the operator min_max_by_time(), there are various min / max operators in DPF, search for min_max in the operator help. Looping over will cost time and you lose the benefit of using DPF.

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar thanks for your help. Below is a snippet of my implementation using the min-max operator. However, it returns NaN for the stress values in the von Mises stress field. Any comments?

    op1 = dpf.operators.result.stress_von_mises()

    op1.inputs.data_sources.connect(ds)

    fields_container_eqv = op1.outputs.fields_container()

    op = dpf.operators.min_max.min_max_by_time() # operator instantiation
    op.inputs.fields_container.connect(fields_container_eqv)
    my_min = op.outputs.min()
    my_max = op.outputs.max()

    layer_eqv = dpf.operators.utility.change_shell_layers(fields_container=my_max, e_shell_layer=0, mesh=model.metadata.meshed_region)
    layer_fc_eqv = layer_eqv.outputs.fields_container_as_fields_container.get_data()

    pl = DpfPlotter(notebook=False, off_screen=True)

    pl.add_field(layer_fc_eqv[0], model.metadata.meshed_region,how_edges=True, opacity=0.8,
    show_max=True,show_min=True,label_text_size=10)

    output_image_path = os.path.join(os.getcwd(), 'Visualizations/von_Mises_max.png')
    pl.show_figure(cpos=cpos, screenshot=output_image_path,auto_close=False)

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi if you are doing a min_max, you don't need to pass the fields container through the layer operator, you can skip that part.

  • Member Posts: 24
    10 Comments Name Dropper
    **

    @Ayush Kumar I directly passed my_max into the plot operator and still have the same issue. Here is how I did it:

    pl = DpfPlotter(notebook=False, off_screen=True)

    pl.add_field(my_max[0], model.metadata.meshed_region,how_edges=True, opacity=0.8,
    show_max=True,show_min=True,label_text_size=10)

    output_image_path = os.path.join(os.getcwd(), 'Visualizations/von_Mises_max.png')
    pl.show_figure(cpos=cpos, screenshot=output_image_path,auto_close=False)

  • Member, Moderator, Employee Posts: 479
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    @hbolandi then you need to debug each line and see where the data disappears. Print the field in my_max to check if there is sensible data in there, if yes, go a level up and see the field for stress.

Welcome!

It looks like you're new here. Sign in or register to get started.