-
Notifications
You must be signed in to change notification settings - Fork 25
Add a Mode-Superposition Transient Analysis example #1256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
0bff018
a6b5126
1e0d38c
8c48cac
c61d7cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
""" | ||
.. _ref_msup_transient: | ||
|
||
Mode superposition transient analysis | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This example shows how to postprocess a mode superposition transient result | ||
and visualize the outputs. It also shows how to select modes for the modal expansion. | ||
|
||
""" | ||
# Import the necessary modules | ||
from ansys.dpf import core as dpf | ||
from ansys.dpf.core import examples | ||
|
||
############################################################################### | ||
# Download the mode superposition transient result example. This example is | ||
# not included in DPF-Core by default to speed up the installation. | ||
# Downloading this example should take only a few seconds. | ||
# | ||
# Next, create the model and display the state of the result. This mode superposition transient | ||
# result file contains several individual results, each at a different timestamp, automatically | ||
# expanded on all available modes. | ||
|
||
# msup_transient_files = examples.find_msup_transient() | ||
msup_transient_files = { | ||
"rst": r"D:\ANSYSDev\Sandbox\UnitTestDataFiles\expansion\msup\Transient\plate1\file.rst", | ||
"rdsp": r"D:\ANSYSDev\Sandbox\UnitTestDataFiles\expansion\msup\Transient\plate1\file.rdsp", | ||
"mode": r"D:\ANSYSDev\Sandbox\UnitTestDataFiles\expansion\msup\Transient\plate1\modal\file.mode", | ||
"modal_rst": r"D:\ANSYSDev\Sandbox\UnitTestDataFiles\expansion\msup\Transient\plate1\modal\file.rst", | ||
} | ||
# print(msup_transient_files) | ||
|
||
############################################################################### | ||
# Modal superposition on all modes available | ||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
# Create a datasource with upstream modal information | ||
data_sources = dpf.DataSources(msup_transient_files["rdsp"]) | ||
|
||
up_stream_data_sources = dpf.DataSources(msup_transient_files["mode"]) | ||
up_stream_data_sources.add_file_path(msup_transient_files["modal_rst"]) | ||
data_sources.add_upstream(up_stream_data_sources) | ||
|
||
# Load into a model | ||
model = dpf.Model(data_sources) | ||
print(model) | ||
|
||
############################################################################### | ||
# Get the expanded displacement fields for each time-step | ||
disp = model.results.displacement.on_all_time_freqs.eval() | ||
print(disp) | ||
|
||
############################################################################### | ||
# Animate the result | ||
disp.animate(scale_factor=5.0) | ||
|
||
############################################################################### | ||
# Get the expanded displacement fields on selected time-steps: | ||
disp = model.results.displacement.on_time_scoping([1, 2, 3]).eval() | ||
print(disp) | ||
|
||
############################################################################### | ||
# Get the expanded displacement fields on part of the mesh, for selected time-steps: | ||
# TODO: NOT WORKING | ||
# partial_scoping = dpf.mesh_scoping_factory.nodal_scoping( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is not working? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cbellot000 when running this commented part I get:
I think the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. who looks bad, did you create a bug in TFS to track it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not yet, I'll do it right now |
||
# model.metadata.meshed_region.nodes.scoping.ids[:200] | ||
# ) | ||
# disp = model.results.displacement.on_time_scoping( | ||
# [1, 2, 3] | ||
# ).on_mesh_scoping( | ||
# partial_scoping | ||
# ).eval() | ||
# print(disp) | ||
|
||
############################################################################### | ||
# Modal superposition on selected modes | ||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
# To select a subset of modes for expansion, you cannot use the source operators directly. | ||
# Below is a workflow to extract results while specifying modes for expansion: | ||
|
||
# First build a data source for the modal response factors | ||
transient_response_ds = dpf.DataSources(result_path=msup_transient_files["rdsp"]) | ||
|
||
# Define the time-steps of interest | ||
time_scoping = dpf.time_freq_scoping_factory.scoping_by_sets(list(range(1, 22))) | ||
|
||
# Extract the result of interest | ||
displacement_fc = dpf.operators.result.displacement( | ||
data_sources=transient_response_ds, # Input here the modal response data source | ||
time_scoping=time_scoping, # Input here the time-steps of interest | ||
mesh_scoping=None # Specify here the region of interest | ||
).eval() | ||
|
||
# The FieldsContainer contains one field per time-step, with data for each mode (entity) | ||
print(displacement_fc) | ||
|
||
############################################################################### | ||
# Now scope the FieldsContainer to the modes of interest | ||
mode_scoping = dpf.Scoping(ids=list(range(1, 3))) # Modes of interest | ||
displacement_fc = dpf.operators.scoping.rescope_fc( | ||
fields_container=displacement_fc, | ||
mesh_scoping=mode_scoping, # Input here the modes of interest | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you input this to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rafacanton no, interestingly enough, this displacement_fc contains fields located at
While trying out different combinations, I realized that this is really not straightforward with the API currently in place. For example, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conclusion: this example is useful to showcase how to do this, but really we lack helpers regarding mode manipulation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's a bit confusing, I think it's worth adding a comment to explain |
||
).eval() | ||
|
||
# The FieldsContainer contains one field per time-step, with data for each selected mode (entity) | ||
print(displacement_fc) | ||
|
||
############################################################################### | ||
# Get the modal basis of interest, with mode selection | ||
modal_basis_ds = dpf.DataSources(result_path=msup_transient_files["mode"]) | ||
modal_basis_ds.add_file_path(msup_transient_files["modal_rst"]) # Associate mesh data to the mode shapes | ||
modal_basis_fc = dpf.operators.result.modal_basis( | ||
data_sources=modal_basis_ds, | ||
time_scoping=mode_scoping, # Input here the modes of interest | ||
mesh_scoping=None, # Specify here the region of interest | ||
).eval() | ||
|
||
# The modal basis FieldsContainer contains one field per mode shape | ||
print(modal_basis_fc) | ||
|
||
############################################################################### | ||
# Plot each mode shape | ||
for n, modal_basis_f in enumerate(modal_basis_fc): | ||
modal_basis_f.plot(deform_by=modal_basis_f, text=f"mode shape {n+1}") | ||
|
||
############################################################################### | ||
# Apply modal superposition | ||
modal_superposition_fc = dpf.operators.math.modal_superposition( | ||
modal_basis=modal_basis_fc, # FieldsContainer obtained via the modal_basis operator | ||
solution_in_modal_space=displacement_fc, # FieldsContainer obtained via the result operator | ||
time_scoping=time_scoping, # Specify here the time-steps of interest | ||
mesh_scoping=None, # Specify here the region of interest | ||
).eval() | ||
|
||
# We obtain the displacement fields at each time-step, with modal superposition | ||
print(modal_superposition_fc) | ||
|
||
############################################################################### | ||
# Animate the result | ||
modal_superposition_fc.animate(scale_factor=5.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it meant to be hardcoded path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, that is until a find a nicer example file to add to our example repo