Skip to content
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

Added 00_basic and 01_tips_n_tricks examples #95

Merged
merged 8 commits into from
Oct 12, 2023
5 changes: 0 additions & 5 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
PyMechanical Remote Sessions Examples
=====================================

These examples demonstrate the basic simulation capabilities of Ansys Mechanical using remote sessions.

.. === EXAMPLES Gallery ===

..
Expand Down
7 changes: 7 additions & 0 deletions examples/00_basic/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
===========================
Simple Mechanical workflows
===========================

This section demonstrates how you can use Mechanical capabilities from Python to perform
Mechanical simulations. This includes importing the geometry, meshing, setting up
and running the solver, and reviewing the results.
216 changes: 216 additions & 0 deletions examples/00_basic/example_01_simple_structural_solve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
""".. _ref_example_01_simple_structural_solve:

Static structural analysis
--------------------------

Using supplied files, this example shows how to insert a static structural
analysis into a new Mechanical session and execute a sequence of Python scripting
commands that define and solve the analysis. The example then shows how
to report deformation results.

"""

###############################################################################
# Download required files
# ~~~~~~~~~~~~~~~~~~~~~~~
# Download the required files. Print the file path for the geometry file.
import os

from ansys.mechanical.core import launch_mechanical
from ansys.mechanical.core.examples import download_file

geometry_path = download_file("example_01_geometry.agdb", "pymechanical", "00_basic")
print(f"Downloaded the geometry file to: {geometry_path}")

###############################################################################
# Launch Mechanical
# ~~~~~~~~~~~~~~~~~
# Launch a new Mechanical session in batch, setting the ``cleanup_on_exit``
# argument to ``False``. To close this Mechanical session when finished,
# this example must call the ``mechanical.exit()`` method.

mechanical = launch_mechanical(batch=True, cleanup_on_exit=False)
print(mechanical)

###############################################################################
# Initialize variable for workflow
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set the ``part_file_path`` variable on the server for later use.
# Make this variable compatible for Windows, Linux, and Docker containers.

project_directory = mechanical.project_directory
print(f"project directory = {project_directory}")

# Upload the file to the project directory.
mechanical.upload(file_name=geometry_path, file_location_destination=project_directory)

# Build the path relative to project directory.
base_name = os.path.basename(geometry_path)
combined_path = os.path.join(project_directory, base_name)
part_file_path = combined_path.replace("\\", "\\\\")
mechanical.run_python_script(f"part_file_path='{part_file_path}'")

# Verify the path.
result = mechanical.run_python_script("part_file_path")
print(f"part_file_path on server: {result}")

###################################################################################
# Run the script
# ~~~~~~~~~~~~~~
# Run the Mechanical script to attach the geometry and set up and solve the
# analysis.

output = mechanical.run_python_script(
"""
import json

# Section 1: Read geometry information
geometry_import_group_11 = Model.GeometryImportGroup
geometry_import_19 = geometry_import_group_11.AddGeometryImport()

geometry_import_19_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.\
Format.Automatic
geometry_import_19_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences()
geometry_import_19_preferences.ProcessNamedSelections = True
geometry_import_19_preferences.ProcessCoordinateSystems = True

geometry_import_19.Import(part_file_path, geometry_import_19_format, geometry_import_19_preferences)

Model.AddStaticStructuralAnalysis()
STAT_STRUC = Model.Analyses[0]
CS_GRP = Model.CoordinateSystems
ANALYSIS_SETTINGS = STAT_STRUC.Children[0]
SOLN= STAT_STRUC.Solution

# Section 2: Set up the unit system.

ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardMKS
ExtAPI.Application.ActiveAngleUnit = AngleUnitType.Radian

# Section 3: Define named selection and coordinate system.

NS1 = Model.NamedSelections.Children[0]
NS2 = Model.NamedSelections.Children[1]
NS3 = Model.NamedSelections.Children[2]
NS4 = Model.NamedSelections.Children[3]
GCS = CS_GRP.Children[0]
LCS1 = CS_GRP.Children[1]

# Section 4: Define remote point.

RMPT_GRP = Model.RemotePoints
RMPT_1 = RMPT_GRP.AddRemotePoint()
RMPT_1.Location = NS1
RMPT_1.XCoordinate=Quantity("7 [m]")
RMPT_1.YCoordinate=Quantity("0 [m]")
RMPT_1.ZCoordinate=Quantity("0 [m]")

# Section 5: Define mesh settings.

MSH = Model.Mesh
MSH.ElementSize =Quantity("0.5 [m]")
MSH.GenerateMesh()

# Section 6: Define boundary conditions.

# Insert fixed support.
FIX_SUP = STAT_STRUC.AddFixedSupport()
FIX_SUP.Location = NS2

# Insert frictionless support.
FRIC_SUP = STAT_STRUC.AddFrictionlessSupport()
FRIC_SUP.Location = NS3

# Section 7: Define remote force.

REM_FRC1 = STAT_STRUC.AddRemoteForce()
REM_FRC1.Location = RMPT_1
REM_FRC1.DefineBy =LoadDefineBy.Components
REM_FRC1.XComponent.Output.DiscreteValues = [Quantity("1e10 [N]")]

# Section 8: Define thermal condition.

THERM_COND = STAT_STRUC.AddThermalCondition()
THERM_COND.Location = NS4
THERM_COND.Magnitude.Output.DefinitionType=VariableDefinitionType.Formula
THERM_COND.Magnitude.Output.Formula="50*(20+z)"
THERM_COND.XYZFunctionCoordinateSystem=LCS1
THERM_COND.RangeMinimum=Quantity("-20 [m]")
THERM_COND.RangeMaximum=Quantity("1 [m]")

# Section 9: Insert directional deformation.

DIR_DEF = STAT_STRUC.Solution.AddDirectionalDeformation()
DIR_DEF.Location = NS1
DIR_DEF.NormalOrientation =NormalOrientationType.XAxis

# Section 10: Add total deformation and force reaction probe.

TOT_DEF = STAT_STRUC.Solution.AddTotalDeformation()

# Add force reaction.
FRC_REAC_PROBE = STAT_STRUC.Solution.AddForceReaction()
FRC_REAC_PROBE.BoundaryConditionSelection = FIX_SUP
FRC_REAC_PROBE.ResultSelection =ProbeDisplayFilter.XAxis

# Section 11: Solve and get the results.

# Solve static analysis.
STAT_STRUC.Solution.Solve(True)

dir_deformation_details = {
"Minimum": str(DIR_DEF.Minimum),
"Maximum": str(DIR_DEF.Maximum),
"Average": str(DIR_DEF.Average),
}

json.dumps(dir_deformation_details)
"""
)
print(output)


###############################################################################
# Download output file from solve and print contents
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Download the ``solve.out`` file from the server to the current working
# directory and print the contents. Remove the ``solve.out`` file.


def get_solve_out_path(mechanical):
solve_out_path = ""
for file_path in mechanical.list_files():
if file_path.find("solve.out") != -1:
solve_out_path = file_path
break

return solve_out_path


def write_file_contents_to_console(path):
with open(path, "rt") as file:
for line in file:
print(line, end="")


solve_out_path = get_solve_out_path(mechanical)

if solve_out_path != "":
current_working_directory = os.getcwd()

local_file_path_list = mechanical.download(
solve_out_path, target_dir=current_working_directory
)
solve_out_local_path = local_file_path_list[0]
print(f"Local solve.out path : {solve_out_local_path}")

write_file_contents_to_console(solve_out_local_path)

os.remove(solve_out_local_path)

###########################################################
# Close Mechanical
# ~~~~~~~~~~~~~~~~
# Close the Mechanical instance.

mechanical.exit()
143 changes: 143 additions & 0 deletions examples/00_basic/example_02_capture_images.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
""".. _ref_example_02_capture_images:

Capture images after a solve
----------------------------

Using supplied files, this example shows how to resume a MECHDAT file
and capture the images of all results in a folder on the disk.

"""

###############################################################################
# Download required files
# ~~~~~~~~~~~~~~~~~~~~~~~
# Download the required files. Print the file paths for the MECHDAT file and
# script files.

import os

from ansys.mechanical.core import launch_mechanical
from ansys.mechanical.core.examples import download_file
from matplotlib import image as mpimg
from matplotlib import pyplot as plt

mechdat_path = download_file(
"example_03_simple_bolt_new.mechdat", "pymechanical", "00_basic"
)
print(f"Downloaded the MECHDAT file to: {mechdat_path}")

script_file_path = download_file(
"example_02_capture_images_helper.py", "pymechanical", "00_basic"
)
print(f"Downloaded the script files to: {script_file_path}")

###############################################################################
# Launch Mechanical
# ~~~~~~~~~~~~~~~~~
# Launch a new Mechanical session in batch, setting the ``cleanup_on_exit``
# argument to ``False``. To close this Mechanical session when finished,
# this example must call the ``mechanical.exit()`` method.

mechanical = launch_mechanical(batch=True, cleanup_on_exit=False)
print(mechanical)

###############################################################################
# Initialize the variable needed for opening the MECHDAT file
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set the ``mechdat_path`` variable for later use.
# Make the variable compatible for Windows, Linux, and Docker containers.

project_directory = mechanical.project_directory
print(f"project directory = {project_directory}")

# Upload the file to the project directory.
mechanical.upload(file_name=mechdat_path, file_location_destination=project_directory)

# Build the path relative to the project directory.
base_name = os.path.basename(mechdat_path)
combined_path = os.path.join(project_directory, base_name)
mechdat_path_modified = combined_path.replace("\\", "\\\\")
mechanical.run_python_script(f"mechdat_path='{mechdat_path_modified}'")

# Verify the path for the MECHDAT file.
result = mechanical.run_python_script(f"mechdat_path")
print(f"MECHDATA file is stored on the server at: {result}")

###################################################################################
# Open the MECHDAT file
# ~~~~~~~~~~~~~~~~~~~~~
# Run the script to open the MECHDAT file.

mechanical.run_python_script("ExtAPI.DataModel.Project.Open(mechdat_path)")

###################################################################################
# Initialize the variable needed for the image directory
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set the ``image_dir`` variable for later use.
# Make the variable compatible for Windows, Linux, and Docker containers.

# Open the MECHDAT file to change the project directory.
project_directory = mechanical.project_directory
print(f"project directory = {project_directory}")

image_directory_modified = project_directory.replace("\\", "\\\\")
mechanical.run_python_script(f"image_dir='{image_directory_modified}'")

# Verify the path for image directory.
result_image_dir_server = mechanical.run_python_script(f"image_dir")
print(f"Images are stored on the server at: {result_image_dir_server}")

###################################################################################
# Run the Mechanical script
# ~~~~~~~~~~~~~~~~~~~~~~~~~
# Run the Mechanical script file for creating the images.

mechanical.run_python_script_from_file(script_file_path)

###############################################################################
# Download the image and plot
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Download one image file from the server to the current working directory and plot
# using matplotlib.


def get_image_path(image_name):
return result_image_dir_server + image_name


def display_image(path):
print(f"Printing {path} using matplotlib")
image1 = mpimg.imread(path)
plt.figure(figsize=(15, 15))
plt.axis("off")
plt.imshow(image1)
plt.show()


image_name = "Total Deformation @ 1 sec_Right.png"
image_path_server = get_image_path(image_name)

if image_path_server != "":
current_working_directory = os.getcwd()

local_file_path_list = mechanical.download(
image_path_server, target_dir=current_working_directory
)
image_local_path = local_file_path_list[0]
print(f"Local image path : {image_local_path}")

display_image(image_local_path)

###################################################################################
# Clear the data
# ~~~~~~~~~~~~~~
# Clear the data so it isn't saved to the project.

mechanical.clear()

###########################################################
# Close Mechanical
# ~~~~~~~~~~~~~~~~
# Close the Mechanical instance.

mechanical.exit()
Loading