From 244c1ddaa812eb082d5c29e41fde124ea7e79d44 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Thu, 31 Aug 2023 18:00:38 -0400 Subject: [PATCH 01/21] Edits made on 8/31/23 --- README.rst | 36 +- doc/source/getting_started/index.rst | 213 ++++---- src/ansys/additive/additive.py | 108 ++-- src/ansys/additive/download.py | 11 +- src/ansys/additive/examples/__init__.py | 2 +- src/ansys/additive/examples/downloads.py | 50 +- src/ansys/additive/geometry_file.py | 10 +- src/ansys/additive/machine.py | 66 +-- src/ansys/additive/material.py | 150 +++--- src/ansys/additive/material_tuning.py | 49 +- src/ansys/additive/microstructure.py | 94 ++-- .../additive/parametric_study/constants.py | 22 +- .../display/ave_grain_size_plot.py | 6 +- .../display/porosity_contour_plot.py | 6 +- .../parametric_study/display/show_table.py | 10 +- .../display/single_bead_eval_plot.py | 10 +- .../parametric_study/parametric_runner.py | 22 +- .../parametric_study/parametric_study.py | 488 ++++++++++-------- .../parametric_study/parametric_utils.py | 15 +- 19 files changed, 738 insertions(+), 630 deletions(-) diff --git a/README.rst b/README.rst index edf3391f0..c07e957d7 100644 --- a/README.rst +++ b/README.rst @@ -37,18 +37,18 @@ PyAdditive :alt: Black -A Python client library for the Ansys Additive service. +PyAdditive is a Python client library for the Ansys Additive service. Installation ============ -PyAdditive can be installed using ``pip``. Until PyAdditive is made public, -a private PyPI repository must be used. See `Getting Started`_ for more information. +You can use `pip `_ to install PyAdditive. Until PyAdditive +is made public, you must use a private PyPI repository. For more information, see `Getting Started`_. .. code:: bash pip install ansys-additive --index-url=https://${PYANSYS_PYPI_PRIVATE_PAT}@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/ -To install the latest development version, use the following commands. +To install the latest development version, use these commands: .. code:: bash @@ -56,9 +56,11 @@ To install the latest development version, use the following commands. cd pyadditive pip install -e . -Basic Usage +Basic usage =========== +This code shows how to import PyAdditive and use some basic capabilities: + .. code:: python import ansys.additive as pyadditive @@ -74,15 +76,25 @@ Basic Usage summary = additive.simulate(input) -For more detailed usage information, see the `Examples`_ in the `PyAdditive Documentation`_. +For more detailed usage information, see `Examples`_ in the `PyAdditive Documentation`_. + +Documentation and issues +======================== +Documentation for the latest stable release of PyMechanical is hosted at `PyAdditive documentation`_. + +In the upper right corner of the documentation's title bar, there is an option for switching from +viewing the documentation for the latest stable release to viewing the documentation for the +development version or previously released versions. -Documentation -============= +On the `PyAdditive Issues `_ page, +you can create issues to report bugs and request new features. On the `PyAdditive Discussions +`_ page or the `Discussions `_ +page on the Ansys Developer portal, you can post questions, share ideas, and get community feedback. + +To reach the project support team, email `pyansys.core@ansys.com `_. -Refer to the `PyAdditive Documentation`_ for more information. .. LINKS AND REFERENCES .. _Getting Started: https://additive.docs.pyansys.com/version/stable/getting_started/index.html -.. _Examples: https://additive.docs.pyansys.com/version/stable/examples/index.html -.. _PyAdditive Documentation: https://additive.docs.pyansys.com/version/stable/index.html - +.. _Examples: https://additive.docs.pyansys.com/version/dev/examples/gallery_examples/index.html +.. _PyAdditive documentation: https://additive.docs.pyansys.com/version/stable/index.html diff --git a/doc/source/getting_started/index.rst b/doc/source/getting_started/index.rst index 0084753e2..c6e253dac 100644 --- a/doc/source/getting_started/index.rst +++ b/doc/source/getting_started/index.rst @@ -11,59 +11,67 @@ PyAdditive is a Python client library for the Ansys Additive service. .. note:: PyAdditive has not been made public and is currently hosted in a private - PyPI repository. The PyAnsys team can provide you a read-only token to be - assigned to an environment variable called ``PYANSYS_PYPI_PRIVATE_PAT``. + PyPI repository. The PyAnsys team can provide you a read-only token to + assign to an environment variable named ``PYANSYS_PYPI_PRIVATE_PAT``. To request a token, email `pyansys.support@ansys.com `_. - Additionally, the additive service docker image is stored under the private + Additionally, the Docker image for the Additive service is stored under the private PyAnsys organization packages on GitHub. If you want to run the image yourself, - you'll need to have a GitHub account with - `two factor authentication `_ - and request to be added to the PyAnsys organization by contacting - `pyansys.support@ansys.com `_. - You also need to create a - `personal access token `_ - with ``read:packages`` scope and `authorize it for single sign on - `_. + you must have a GitHub account with two-factor authentication. For more + information, see `Configuring two-factor authentication + `_ + in the GitHub documentation. You must also contact + `pyansys.support@ansys.com `_ + to request that you be added to the PyAnsys organization. + Lastly, you must create a personal access token with ``read:packages`` scope and + authorize it for single sign on. For more information, see these topics in the + GitHub documentation: + + - `Managing your personal access tokens `_ + - `Authorizing a personal access token for use with SAML single sign-on `_. Ansys Lab usage =============== -The easiest way to use PyAdditive is within a jupyter notebook in the `Ansys Lab +The easiest way to use PyAdditive is within a Jupyter notebook in the `Ansys Lab `_ cloud environment. -Once logged in to Ansys Lab, create a new jupyter notebook and connect to the additive service using: +Once you sign in to Ansys Lab, create a Jupyter notebook and connect to the Additive +service with this code: .. code:: pycon >>> import ansys.additive as pyadditive >>> additive = pyadditive.Additive() -Example notebooks can found in the `Examples `_ -section of the `PyAdditive documentation `_. +Example notebooks are available in `Examples `_. Standalone usage ================ -To use PyAdditive in a standalone mode, first start the service locally. If you have docker installed and have -`authenticated to ghcr.io -`_, -you can start the additive service locally using ``docker`` with: +To use PyAdditive in standalone mode, first start the Additive service locally. If you have +Docker installed, you must be authenticated to ghcr.io. For more information, see +`Working with the Container registry `_ +in the GitHub documentation. .. warning:: - In order to authenticate to ghcr.io, you need to have your GitHub user - account added to the PyAnsys organization. See preceding note. + To authenticate to ghcr.io, you must have your GitHub user + account added to the PyAnsys organization as indicated in + the preceding note. + + +Start the Additive service locally with this Docker command: .. code:: bash docker run --rm --name additive -p 50052:50052 ghcr.io/pyansys/pyadditive:latest -Next, connect to the service with: +Next, connect to the Additive service with this code: .. code:: pycon @@ -76,75 +84,88 @@ Installation Package dependencies -------------------- -PyAdditive is supported on Python versions >= 3.8. Previous versions of Python are -no longer supported as outlined `here `_. -PyAdditive dependencies are automatically checked when packages are installed. -The following projects are required dependencies for PyAdditive: +PyAdditive is supported on Python version 3.8 and later. Previous versions of Python are +no longer supported as outlined in this `Moving to require Python 3 `_ +statement. + +PyAdditive dependencies are automatically checked when packages are installed. These projects +are required dependencies for PyAdditive: -* `ansys-api-additive` - The gRPC code generated from Protobuf files. -* `pandoc `_ - pandoc is used for documentation generation -* `NumPy `_ - NumPy arrays provide a core foundation for data array access for PyAdditive. -* `PyVista `_ - PyVista is used for result visualization interactive 3D plotting. +* `ansys-api-additive `_: Python package containing the auto-generated + gRPC Python interface files for the Additive service +* `pandoc `_: Universal document converter for documentation generation +* `NumPy `_: Fundamental package for scientific computing with Python, providing + data array access for PyAdditive +* `PyVista `_: 3D visualization library for interactive 3D plotting of + PyAdditive results. .. - * `Pint `_ - Pint is used for the measurement units. + * `Pint `_: Python package to define, operate, and manipulate physical quantities, + including conversions from and to different measurement units. -How to install --------------- +Install the package +------------------- -There are three modes of installation: user, developer, and offline. +PyAdditive has three installation modes: user, developer, and offline. -For users -^^^^^^^^^ +Install in user mode +^^^^^^^^^^^^^^^^^^^^ -On Windows systems, install `Python `_, if it is not -already installed. -In order to install PyAdditive, make sure you have the latest version of `pip `_, then run: +On a Windows system, install `Python `_ if it is not already installed. + +Before installing PyAdditive in user mode, run this command to make sure that you have the latest version +of `pip `_: .. code:: bash python -m pip install -U pip -Then, you can simply execute: +Then, run this command to install PyAdditive: .. code:: bash python -m pip install ansys-additive -.. warning:: +.. caution:: Until PyAdditive is made public, you must provide the index - URL to the private PyPI repository when performing a ``pip install``. + URL to the private PyPI repository when performing a ``pip`` install: * Index URL: ``https://pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/`` + If access to this package registry is needed, email `pyansys.core@ansys.com `_ + to request access. The PyAnsys team can provide you a read-only token to be inserted in ``${PRIVATE_PYPI_ACCESS_TOKEN}``. + + Once you have the token run the installation command for your OS: + .. code:: bash - # On linux + # On Linux pip install ansys-additive --index-url=https://${PYANSYS_PYPI_PRIVATE_PAT}@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/ # On Windows pip install ansys-additive --index-url=https://%PYANSYS_PYPI_PRIVATE_PAT%@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/ - See preceding note for how to get the access token to use for ``PYANSYS_PYPI_PRIVATE_PAT``. - -For developers -^^^^^^^^^^^^^^ +Install in developer mode +^^^^^^^^^^^^^^^^^^^^^^^^^ Installing PyAdditive in developer mode allows you to modify the source code and enhance it. -Before contributing to the project, please refer to the `Contributing `_ topic -in the *PyAnsys Developer's Guide*, then, follow these steps: +.. note:: + Before contributing to PyAdditive, see the `Contributing `_ topic +in the *PyAnsys Developer's Guide*. You should be thoroughly familiar with this guide. -#. Clone this repository: +To install PyAdditive in developer mode, perform these steps: + +#. Clone the repository and access the directory where it has been cloned: .. code:: bash git clone https://github.com/ansys-internal/pyadditive cd pyadditive -#. Create a new Python environment and activate it: +#. Create a clean Python virtual environment and activate it: .. code:: bash @@ -160,13 +181,16 @@ in the *PyAnsys Developer's Guide*, then, follow these steps: # Activate it in Windows Powershell .venv\Scripts\Activate.ps1 + If you require additional information on virtual environments, see `Creation of virtual environments + `_ in the Python documentation. + #. Install the required build system tools: .. code:: bash python -m pip install -U pip tox -#. Verify your development installation by running: +#. Verify your development installation: .. code:: bash @@ -174,8 +198,8 @@ in the *PyAnsys Developer's Guide*, then, follow these steps: .. warning:: - ``PYANSYS_PYPI_PRIVATE_PAT`` must be defined for ``tox`` to run to completion. - See preceding note for more information. + The ``PYANSYS_PYPI_PRIVATE_PAT`` environment variable must be defined + for ``tox`` to run to completion. For more information, see the preceding note. #. Optionally, install the project in editable mode: @@ -183,68 +207,72 @@ in the *PyAnsys Developer's Guide*, then, follow these steps: python -m pip install -e . -#. When finished, you can exit the virtual environment by running: +#. When finished, you can exit the virtual environment: .. code:: bash deactivate -Offline mode installation -^^^^^^^^^^^^^^^^^^^^^^^^^ +Install in offline mode +^^^^^^^^^^^^^^^^^^^^^^^ If you lack an internet connection on your installation machine (or you do not have access to the -private Ansys PyPI packages repository), the recommended way of installing PyAdditive is downloading the wheelhouse -archive from the `Releases Page `_ for your +private Ansys PyPI packages repository), you should install PyAdditive by downloading the wheelhouse +archive from the `Releases `_ page for your corresponding machine architecture. Each wheelhouse archive contains all the Python wheels necessary to install PyAdditive from scratch on Windows, -Linux, and MacOS from Python 3.8 to 3.11. You can install this on an isolated system with a fresh Python -installation or on a virtual environment. +Linux, and MacOS from Python 3.8 to 3.11. You can unzip and install the wheelhouse archive on an isolated +system with a fresh Python installation or in a virtual environment. -For example, on Linux with Python 3.8, unzip the wheelhouse archive and install it with the following: +For example, on Linux with Python 3.8, unzip and install the wheelhouse archive with these commands: .. code:: bash unzip ansys-additive-v0.1.dev0-wheelhouse-Linux-3.8.zip wheelhouse pip install ansys-additive -f wheelhouse --no-index --upgrade --ignore-installed -If you're on Windows with Python 3.9, unzip to a wheelhouse directory and install using the preceding command. +If you're on Windows with Python 3.9, unzip the wheelhouse archive to a wheelhouse directory and +then install using the preceding command. + +Consider using a virtual environment for the installation. -Consider installing using a `virtual environment `_. Testing ======= -This project takes advantage of `tox`_. This tool allows to automate common -development tasks (similar to Makefile) but it is oriented towards Python +This project takes advantage of `tox`_. This tool automates common +development tasks (similar to Makefile), but it is oriented towards Python development. -Using tox ---------- +Using ``tox`` +------------- -As Makefile has rules, `tox`_ has environments. In fact, the tool creates its -own virtual environment so anything being tested is isolated from the project in -order to guarantee project's integrity. The following environments commands are provided: +While Makefile has rules, `tox`_ has environments. In fact, ``tox`` creates its +own virtual environment so that anything being tested is isolated from the project to +guarantee the project's integrity. + +The following commands are provided: .. vale off -- **tox -e style**: will check for coding style quality. -- **tox -e py**: runs unit tests. -- **tox -e py-coverage**: runs unit tests and generates code coverage reports. -- **tox -e doc**: builds and checks the documentation. +- **tox -e style**: Checks for coding style quality. +- **tox -e py**: Checks for and runs unit tests. +- **tox -e py-coverage**: Checks for and runs unit tests, generating code coverage reports. +- **tox -e doc**: Checks for building the documentation successfully. .. vale on Raw testing ----------- -If required, you can always call the style commands (`black`_, `isort`_, -`flake8`_, or other) or unit testing ones (`pytest`_) from the command line. However, +If required, from the command line, you can call style commands like `black`_, `isort`_, +and `flake8`_ and call unit testing commands like `pytest`_. However, this does not guarantee that your project is being tested in an isolated -environment, which is the reason why tools like `tox`_ exist. +environment, which is the reason why tools like ``tox`` exist. -To run the unit tests without using tox, first install ``pytest-cov`` and the -project in editable mode. +To run unit tests without using ``tox``, first install the ``pytest-cov`` package in +editable mode: .. code:: bash @@ -252,7 +280,7 @@ project in editable mode. python -m pip install -e . -Then use the following command within the root folder of the project. +Then, run this command from the root folder of the project: .. code:: bash @@ -261,15 +289,16 @@ Then use the following command within the root folder of the project. System testing on localhost --------------------------- -Install `docker-compose `_, if necessary. -Start the server using the following command from the root folder of the project. +Install the `docker-compose `_ package, if necessary. +Start the server by running this command from the root folder of the project: .. code:: bash docker compose up -Open a jupyter notebook in VS Code and execute it or start jupyter lab using the following -commands. +Open a Jupyter notebook in Visual Studio Code and execute it. + +Or, use these commands to start `JupyterLab `_: .. code:: bash @@ -284,15 +313,15 @@ commands. jupyter lab -Open jupyter lab in your browser using ``http://localhost:8888/lab``. Note the port number may -be different but it will be listed in the ``jupyter lab`` start up messages. Example -notebooks can be found in the ``examples`` folder of this repository. +The URL for opening JupyterLab in your browser is ``http://localhost:8888/lab``. Note that the port number may +be different, but the port number that you should use is listed in the JupyterLab startup messages. You can find +example Jupyter notebooks in the ``examples`` folder of the PyAdditive repository. -A note on pre-commit -==================== +pre-commit +========== The style checks take advantage of `pre-commit`_. Developers are not forced but -encouraged to install this tool via: +encouraged to install this tool by running this command: .. code:: bash @@ -309,7 +338,7 @@ For building documentation, you can run the usual rules provided in the make -C doc/ html && your_browser_name doc/html/index.html -However, the recommended way of checking documentation integrity is using: +However, the recommended way of checking documentation integrity is to use ``tox``: .. code:: bash diff --git a/src/ansys/additive/additive.py b/src/ansys/additive/additive.py index 1bb89eb04..435893f6f 100644 --- a/src/ansys/additive/additive.py +++ b/src/ansys/additive/additive.py @@ -1,6 +1,5 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. -"""This module contains the Additive class which interacts with the Additive -service.""" +"""Provides for interacting with the Additive service.""" import concurrent.futures from datetime import datetime import hashlib @@ -39,10 +38,9 @@ class Additive: - """Client interface to Additive service. + """Provides the client interface to the Additive service. - The method :meth:`simulate` is - used to execute simulations. + The :meth:`simulate` method is used to execute simulations. """ def __init__( @@ -54,7 +52,7 @@ def __init__( log_file: typing.Optional[str] = "", channel: typing.Optional[grpc.Channel] = None, ) -> None: # PEP 484 - """Initialize connection to the server.""" + """Initialize a connection to the server.""" if channel is not None and (ip is not None or port is not None): raise ValueError("If 'channel' is specified, neither 'port' nor 'ip' can be specified.") @@ -80,7 +78,7 @@ def __init__( print("user data path: " + self._user_data_path) def __del__(self): - """Destructor, used to clean up service connection.""" + """Destructor for cleaning up the service connection.""" if hasattr(self, "_server_instance") and self._server_instance: self._server_instance.delete() if hasattr(self, "_server_process") and self._server_process: @@ -111,31 +109,30 @@ def _create_channel( ): """Create an insecure gRPC channel. - A channel connection will be established using one of the following methods. + A channel connection is established using one of the following methods. The methods are listed in order of precedence. - 1. Using the user provided ip and port values, if any - 2. Using PyPim if the client is running in a PyPim enabled environment - such as Ansys Lab - 3. Using an ip and port definition string defined by the - ANSYS_ADDITIVE_ADDRESS environment variable - 4. Using a default ip and port, `localhost:50052` + + #. Use the user-provided IP address and port values, if any. + #. Use PyPIM if the client is running in a PyPIM-enabled environment + such as Ansys Lab. + #. Use an IP address and port definition string defined by the + ``ANSYS_ADDITIVE_ADDRESS`` environment variable. + #. Use the default IP address and port, ``localhost:50052``. Parameters ---------- - - ip: str - Internet protocol address of remote server host in IPv4 dotted-quad string format. - - port: int - Port number on server to connect to. - - product_version: str - Additive server product version. Only applies in PyPim environments. + ip: str, None + IP address of the remote server host in IPv4 dotted-quad string format. + port: int, None + Port number on the server to connect to. + product_version: str, None + Product version of the Additive server. This parameter is only applicable + in PyPIM environments. Returns ------- channel: grpc.Channel - Insecure grpc channel. + Insecure gRPC channel. """ if port: misc.check_valid_port(port) @@ -165,16 +162,22 @@ def _create_channel( return self.__open_insecure_channel(f"{LOCALHOST}:{port}") def __open_insecure_channel(self, target: str) -> grpc.Channel: - """Open an insecure grpc channel to a given target.""" + """Open an insecure gRPC channel to a given target. + + Parameters + ---------- + target : str + Target for the insecure gRPC channel. + """ return grpc.insecure_channel( target, options=[("grpc.max_receive_message_length", MAX_MESSAGE_LENGTH)] ) @property def _channel_str(self): - """Return the target string. + """Target string. - Generally of the form of "ip:port", like "127.0.0.1:50052". + The form is generally ``"ip:port"``. For example, ``"127.0.0.1:50052"``. """ if self._channel is not None: return self._channel._channel.target().decode() @@ -202,18 +205,17 @@ def simulate(self, inputs, nproc: typing.Optional[int] = None): inputs: :class:`SingleBeadInput`, :class:`PorosityInput`, :class:`MicrostructureInput`, :class:`ThermalHistoryInput` or a list of these input types - Parameters to use for simulation(s). + Parameters to use for simulations. - nproc: int + nproc: int, None Number of processors to use for simulation. This corresponds - to the maximum number of licenses that will be checked out - at a time. If not specified, the value of ``npoc`` provided - in the Additive service constructor will be used. - + to the maximum number of licenses to check out at one time. + If no value is specified, the value of the ``npoc`` parameter + provided in the Additive service constructor is used. Returns ------- - A :class:`SingleBeadSummary`, :class:`PorositySummary`, + :class:`SingleBeadSummary`, :class:`PorositySummary`, :class:`MicrostructureSummary`, :class:`ThermalHistorySummary`, :class:`SimulationError`, or, if a list of inputs was provided, a list of these types. @@ -253,12 +255,12 @@ def _simulate(self, input, show_progress: bool = False): input: SingleBeadInput, PorosityInput, MicrostructureInput, ThermalHistoryInput Parameters to use for simulation. - show_progress: bool - If ``True``, send progress updates to user interface. + show_progress: bool, False + Whether to send progress updates to the user interface. Returns ------- - One of the follow summary objects. + One of the follow summary objects: :class:`SingleBeadSummary`, :class:`PorositySummary`, :class:`MicrostructureSummary`, :class:`ThermalHistorySummary`, :class:`SimulationError` @@ -295,7 +297,7 @@ def _simulate(self, input, show_progress: bool = False): return SimulationError(input, str(e)) def get_materials_list(self) -> list[str]: - """Retrieve a list of material names used in additive simulations. + """Get a list of material names used in additive simulations. Returns ------- @@ -305,7 +307,7 @@ def get_materials_list(self) -> list[str]: return self._materials_stub.GetMaterialsList(Empty()) def get_material(self, name: str) -> AdditiveMaterial: - """Return a specified material for use in an additive simulation. + """Get a material for use in an additive simulation. Parameters ---------- @@ -326,22 +328,26 @@ def get_material(self, name: str) -> AdditiveMaterial: def load_material( parameters_file: str, thermal_lookup_file: str, characteristic_width_lookup_file: str ) -> AdditiveMaterial: - """Load a user provided material definition. + """Load a user-provided material definition. Parameters ---------- - parameters_file: str - Name of `json file containing material parameters + Name of the JSON file containing material parameters. For more information, see + `Create Material Parameters File (.json) `_ - + in the *Additiivate Manufacturing Beta Features* documentation. thermal_lookup_file: str - Name of `CSV file containing a lookup table for thermal dependent properties + Name of the CSV file containing the lookup table for thermal dependent properties. + For more information, see `Create Material Lookup File (.csv) `_ - + in the *Additiivate Manufacturing Beta Features* documentation. characteristic_width_lookup_file: str - Name of `CSV file containing a lookup table for characteristic melt pool width + Name of the CSV file containing the lookup table for characteristic melt pool width. For + more information, see + `Find Characteristic Width Values and Generate Characteristic Width File (.csv) `_ + in the *Additiivate Manufacturing Beta Features* documentation. """ material = AdditiveMaterial() material._load_parameters(parameters_file) @@ -356,13 +362,11 @@ def tune_material( Parameters ---------- - input: MaterialTuningInput Input parameters for material tuning. Returns ------- - MaterialTuningSummary Summary of material tuning. """ @@ -373,7 +377,7 @@ def tune_material( if os.path.exists(out_dir): raise Exception( - f"Directory {out_dir} already exists. Please delete or choose a different output directory." + f"Directory {out_dir} already exists. Delete or choose a different output directory." ) request = input._to_request() @@ -422,19 +426,15 @@ def _simulate_thermal_history( Parameters ---------- - input: ThermalHistoryInput Simulation input parameters. - out_dir: str Folder path for output files. - logger: ProgressLogger Log message handler. Returns ------- - :class:`ThermalHistorySummary` """ if input.geometry == None or input.geometry.path == "": @@ -478,5 +478,5 @@ def _validate_inputs(self, inputs): if input.id == "": input.id = misc.short_uuid() if input.id in ids: - raise ValueError(f'Duplicate simulation id "{input.id}" in input list') + raise ValueError(f'Duplicate simulation ID "{input.id}" in input list') ids.append(input.id) diff --git a/src/ansys/additive/download.py b/src/ansys/additive/download.py index a30dff400..927fd8d6b 100644 --- a/src/ansys/additive/download.py +++ b/src/ansys/additive/download.py @@ -15,19 +15,16 @@ def download_file( local_folder: str, logger: ProgressLogger = None, ): - """Download a file from the server to the local host. + """Download a file from the server to the localhost. Parameters ---------- - remote_file_name: str - Path to file on the server - + Path to file on the server. local_folder: str - Folder on local host to write file to - + Folder on yjr localhost to write yjr file to. logger: ProgressLogger - Log message handler + Log message handler. """ if not os.path.isdir(local_folder): diff --git a/src/ansys/additive/examples/__init__.py b/src/ansys/additive/examples/__init__.py index e77e4cc6a..b63b1f169 100644 --- a/src/ansys/additive/examples/__init__.py +++ b/src/ansys/additive/examples/__init__.py @@ -1,5 +1,5 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. -"""Utilities for use with PyAdditive examples.""" +"""Provides utilities for use with PyAdditive examples.""" from ansys.additive.examples.downloads import ( decompress, diff --git a/src/ansys/additive/examples/downloads.py b/src/ansys/additive/examples/downloads.py index 868fd0c5b..7bd9e91b7 100644 --- a/src/ansys/additive/examples/downloads.py +++ b/src/ansys/additive/examples/downloads.py @@ -1,5 +1,6 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. -"""Functions to download sample datasets from the pyansys data repository.""" +"""Provides functions for downloading sample datasets from the PyAdditive +repository.""" from http.client import HTTPMessage import os import shutil @@ -29,8 +30,21 @@ def delete_downloads(): def decompress(filename, subdir=None) -> str: - """Decompress a zip file into the examples directory and return the - path.""" + """Decompress a ZIP file to the ``examples`` directory. + + Parameters + ---------- + filename : str + Name of the file. + subdir : str, None + Name of the subdirectory where the file resides. The + default is ``None``. + + Returns + ------- + str + Path to the decompressed ZIP file. + """ outdir = EXAMPLES_PATH zip_ref = zipfile.ZipFile(filename, "r") if subdir: @@ -48,13 +62,19 @@ def _get_file_url(filename, directory=None): def _retrieve_file(url, filename) -> tuple[str, HTTPMessage]: - """Retrieve an example data file either from local storage or from the - given url. + """Retrieve an example data file from either a URL or local storage. + + Parameters + ---------- + url : str + URL for the example data file. + filename : str + Name for the example data file. Returns ------- - str: local file path - HttpMessage: http status message if any + str: Local file path + HttpMessage: HTTP status message if any """ # First check if file has already been downloaded local_path = os.path.join(EXAMPLES_PATH, os.path.basename(filename)) @@ -76,7 +96,7 @@ def _download_file(filename, directory=None) -> tuple[str, HTTPMessage]: def download_10mm_cube(): - """Download an STL file describing a 10 millimeter cube.""" + """Download an STL file describing a 10-millimeter cube.""" return _download_file("10mm_cube.stl", PARTS_FOLDER)[0] @@ -86,7 +106,7 @@ def download_small_wedge_slm_build_file(): class MaterialTuningExampleInputFiles: - """Class to hold the example inputs for the material tuning process.""" + """Holds the example inputs for the material tuning process.""" def __init__( self, @@ -95,7 +115,7 @@ def __init__( thermal_properties_lookup_file: str, characteristic_width_lookup_file: str, ): - """Initialize the MaterialTuningInputs class. + """Initialize the ``MaterialTuningInputs`` class. Parameters ---------- @@ -155,7 +175,7 @@ def download_material_tuning_input() -> MaterialTuningExampleInputFiles: class CustomMaterialExampleFiles: - """Class to hold the files associated with a custom material definition.""" + """Holds the files associated with a custom material definition.""" def __init__( self, @@ -163,7 +183,7 @@ def __init__( thermal_properties_lookup_file: str, characteristic_width_lookup_file: str, ): - """Initialize the CustomMaterialExampleFiles class. + """Initialize the ``CustomMaterialExampleFiles`` class. Parameters ---------- @@ -180,17 +200,17 @@ def __init__( @property def material_parameters_file(self): - """Material parameters file path.""" + """Path to the material parameters file.""" return self._material_parameters_file @property def thermal_properties_lookup_file(self): - """Thermal properties lookup file path.""" + """Path to the thermal properties lookup file.""" return self._thermal_properties_lookup_file @property def characteristic_width_lookup_file(self): - """Characteristic width lookup file path.""" + """Path to the characteristic width lookup file.""" return self._characteristic_width_lookup_file diff --git a/src/ansys/additive/geometry_file.py b/src/ansys/additive/geometry_file.py index 5ad6f0b99..ae36a2807 100644 --- a/src/ansys/additive/geometry_file.py +++ b/src/ansys/additive/geometry_file.py @@ -17,7 +17,7 @@ class MachineType(IntEnum): class BuildFile: - """Build file description.""" + """Provides the build file description.""" def __init__(self, type: MachineType, path: str): if not isinstance(type, MachineType): @@ -58,8 +58,8 @@ def type(self, value: MachineType): @property def path(self) -> str: - """Path of zip archive containing build instruction file, geometry stl - file and optional support stl files.""" + """Path of the ZIP file containing the build instruction file, geometry + STL file, and optional support STL files.""" return self._path @path.setter @@ -73,7 +73,7 @@ def path(self, value: str): class StlFile: - """Container for stl file definition.""" + """Container for the STL file definition.""" def __init__(self, path: str): if not exists(path): @@ -96,7 +96,7 @@ def __eq__(self, other: object) -> bool: @property def path(self) -> str: - """Path of stl file.""" + """Path of the STL file.""" return self._path @path.setter diff --git a/src/ansys/additive/machine.py b/src/ansys/additive/machine.py index dc540336f..b9d1971ae 100644 --- a/src/ansys/additive/machine.py +++ b/src/ansys/additive/machine.py @@ -7,6 +7,8 @@ class MachineConstants: + """Provides constants for additive manufacturing machine settings.""" + #: Default laser power in Watts. DEFAULT_LASER_POWER = 195 MIN_LASER_POWER = 50 @@ -46,11 +48,12 @@ class MachineConstants: class AdditiveMachine: - """Additive manufacturing machine settings used during simulation. + """Provides the additive manufacturing machine settings used during + simulations. - Units are SI (m, kg, s, K) unless otherwise noted. Exceptions include - angles, which are in degrees, and ``heater_temperature``, which is in - degrees Celsius. + Units are SI (m, kg, s, or K) unless otherwise noted. Exceptions + include angles, which are in degrees, and the heater temperature, + which is in degrees Celsius. """ def __init__( @@ -118,7 +121,7 @@ def laser_power(self, value: float): @property def scan_speed(self) -> float: - """Laser scanning speed in (m/s). + """Laser scanning speed (m/s). Valid values are from 0.35 to 2.5 m/s. """ @@ -133,7 +136,7 @@ def scan_speed(self, value: float): @property def heater_temperature(self) -> float: - """Temperature of machine build chamber heater (°C). + """Temperature (°C) of the machine build chamber heater. Valid values are from 20 to 500 °C. """ @@ -151,8 +154,8 @@ def heater_temperature(self, value: float): @property def layer_thickness(self) -> float: - """The thickness of the powder layer deposited with each pass of the - recoater blade (m). + """Thickness (m) of the powder layer deposited with each pass of the + recoater blade. Valid values are from 1e-5 to 1e-4 m (10 to 100 µm). """ @@ -170,12 +173,13 @@ def layer_thickness(self, value: float): @property def beam_diameter(self) -> float: - """The width of the laser on the powder or substrate surface defined - using the D4σ beam diameter definition (m). + """Width (m) of the laser on the powder or substrate surface defined + using the D4σ beam diameter definition. + + Usually this value is provided by the machine manufacturer. It + is sometimes called the laser spot diameter. - Usually this value is provided by the machine manufacturer. - Sometimes called laser spot diameter. Valid values are from 2e-5 - to 1.4e-4 m (20 and 140 µm). + Valid values are from 2e-5 to 1.4e-4 m (20 and 140 µm). """ return self._beam_diameter @@ -191,11 +195,13 @@ def beam_diameter(self, value: float): @property def starting_layer_angle(self) -> float: - """The angle at which the first layer will be scanned (°). + """Angle (°) to scan the first layer at. + + The angle is measured counterclockwise from the X axis, such + that a value of 90° results in scan lines parallel to the Y + axis. - It is measured counter clockwise from the X axis, such that a - value of 90° results in scan lines parallel to the Y axis. Valid - values are from 0 to 180°. + Valid values are from 0 to 180°. """ return self._starting_layer_angle @@ -211,8 +217,7 @@ def starting_layer_angle(self, value: float): @property def layer_rotation_angle(self) -> float: - """The angle, in degrees, at which scan vector orientation changes from - layer to layer (°). + """Angle (°) to change the scan vector orientation from layer to layer. Valid values are from 0 to 180°. """ @@ -230,13 +235,14 @@ def layer_rotation_angle(self, value: float): @property def hatch_spacing(self) -> float: - """The distance between adjacent scan vectors, or hatches when - rastering back and forth with the laser (m). + """Distance (m) between adjacent scan vectors, or hatches, when + rastering back and forth with the laser. Hatch spacing should allow for a slight overlap of scan vector tracks such that some of the material re-melts to ensure full - coverage of solid material. Valid values are from 6e-5 to 2e-4 m - (0.06 and 0.2 mm). + coverage of solid material. + + Valid values are from 6e-5 to 2e-4 m (0.06 and 0.2 mm). """ return self._hatch_spacing @@ -252,10 +258,10 @@ def hatch_spacing(self, value: float): @property def slicing_stripe_width(self) -> float: - """The width of a stripe (m). + """Width (m) of a stripe, which is a section of scan lines within a + layer. - A stripe is a section of scan lines within a layer. Valid values - must be between 0.001 and 0.1 m (1 and 100 mm). + Valid values are from 0.001 to 0.1 m (1 and 100 mm). """ return self._slicing_stripe_width @@ -271,8 +277,8 @@ def slicing_stripe_width(self, value: float): @staticmethod def _from_machine_message(msg: MachineMessage): - """Create an ``AdditiveMachine`` from a machine message received from - the Additive service.""" + """Create an additive machine from a machine message received from the + Additive service.""" if isinstance(msg, MachineMessage): return AdditiveMachine( laser_power=msg.laser_power, @@ -289,8 +295,8 @@ def _from_machine_message(msg: MachineMessage): raise ValueError("Invalid message type passed to _from_machine_message()") def _to_machine_message(self) -> MachineMessage: - """Create a machine message from this ``AdditiveMachine`` to send to - the Additive service.""" + """Create a machine message from the additive machine to send to the + Additive service.""" return MachineMessage( laser_power=self.laser_power, scan_speed=self.scan_speed, diff --git a/src/ansys/additive/material.py b/src/ansys/additive/material.py index fb06e9f66..172e0960e 100644 --- a/src/ansys/additive/material.py +++ b/src/ansys/additive/material.py @@ -14,20 +14,20 @@ class CharacteristicWidthDataPoint: - """Container for a characteristic width data point. + """Provides the container for a characteristic width data point. Additive material definitions include a file containing a - characteristic width lookup table which allows a given laser speed - and power to be correlated to a characteristic melt pool width. This + characteristic width lookup table, allowing a given laser speed and + power to be correlated to a characteristic melt pool width. This class represents a single row in the lookup table. - Units are SI (m, kg, s, K) unless otherwise noted. + Units are SI (m, kg, s, and K) unless otherwise noted. """ def __init__( self, *, laser_power: float = 0, scan_speed: float = 0, characteristic_width: float = 0 ): - """Create a ``CharacteristicWidthDataPoint``.""" + """Create a characteristic width data point.""" self._laser_power = laser_power self._scan_speed = scan_speed self._characteristic_width = characteristic_width @@ -85,8 +85,8 @@ def scan_speed(self, value: float): @staticmethod def _from_characteristic_width_data_point_message(msg: CharacteristicWidthDataPointMessage): - """Create a ``CharacteristicWidthDataPoint`` from a characteristic data - point message received from Additive service.""" + """Create a characteristic width data point`` from a characteristic + data point message received from the Additive service.""" if not isinstance(msg, CharacteristicWidthDataPointMessage): raise ValueError( "Invalid message object passed to from_characteristic_width_data_point_message()" @@ -100,7 +100,7 @@ def _to_characteristic_width_data_point_message( self, ) -> CharacteristicWidthDataPointMessage: """Create a characteristic width data point message from this - ``CharacteristicWidthDataPoint`` to send to the Additive service.""" + characteristic width data point to send to the Additive service.""" msg = CharacteristicWidthDataPointMessage() for p in self.__dict__: setattr(msg, p.replace("_", "", 1), getattr(self, p)) @@ -108,14 +108,14 @@ def _to_characteristic_width_data_point_message( class ThermalPropertiesDataPoint: - """Container for a temperature dependent properties. + """Provides the container for temperature-dependent properties. Additive material definitions include a file containing a lookup - table which describes the material's thermal properties at different + table describing the material's thermal properties at different temperatures. This class represents a single row in the lookup table. - Units are SI (m, kg, s, K) unless otherwise noted. + Units are SI (m, kg, s, and K) unless otherwise noted. """ def __init__( @@ -129,7 +129,7 @@ def __init__( thermal_conductivity: float = 0, thermal_conductivity_ratio: float = 0, ): - """Create a ``ThermalPropertiesDataPoint``.""" + """Create a thermal properties data point.""" self._density = density self._density_ratio = density_ratio self._specific_heat = specific_heat @@ -171,7 +171,7 @@ def density_ratio(self) -> float: @density_ratio.setter def density_ratio(self, value: float): - """Set density_ratio value.""" + """Set density ratio value.""" if value < 0: raise ValueError("Density ratio must not be negative.") self._density_ratio = value @@ -230,8 +230,8 @@ def thermal_conductivity_ratio(self, value: float): @staticmethod def _from_thermal_properties_data_point_message(msg: ThermalPropertiesDataPointMessage): - """Create a ``ThermalPropertiesDataPoint`` from a thermal - characteristic data point message received from the Additive service. + """Create a thermal properties data point from a thermal characteristic + data point message received from the Additive service. :meta private: """ @@ -247,8 +247,8 @@ def _from_thermal_properties_data_point_message(msg: ThermalPropertiesDataPointM def _to_thermal_properties_data_point_message( self, ) -> ThermalPropertiesDataPointMessage: - """Create a thermal characteristic data point message from this - ``ThermalPropertiesDataPoint`` object to send to the Additive service. + """Create a thermal characteristic data point message from this thermal + properties data point to send to the Additive service. :meta private: """ @@ -259,8 +259,8 @@ def _to_thermal_properties_data_point_message( class AdditiveMaterial: - """Container for material properties used during additive manufacturing - simulation.""" + """Provides the container for material properties used during additive + manufacturing simulation.""" def __init__( self, @@ -301,7 +301,7 @@ def __init__( characteristic_width_data: list[CharacteristicWidthDataPoint] = None, thermal_properties_data: list[ThermalPropertiesDataPoint] = None, ): - """Create an ``AdditiveMaterial``.""" + """Create an additive material.""" self._absorptivity_maximum = absorptivity_maximum self._absorptivity_minimum = absorptivity_minimum self._absorptivity_powder_coefficient_a = absorptivity_powder_coefficient_a @@ -375,7 +375,7 @@ def absorptivity_maximum(self) -> float: @absorptivity_maximum.setter def absorptivity_maximum(self, value: float): - """Set absorptivity_maximum.""" + """Set absorptivity maximum.""" self._absorptivity_maximum = value @property @@ -385,7 +385,7 @@ def absorptivity_minimum(self) -> float: @absorptivity_minimum.setter def absorptivity_minimum(self, value: float): - """Set absorptivity_minimum.""" + """Set absorptivity minimum.""" self._absorptivity_minimum = value @property @@ -395,7 +395,7 @@ def absorptivity_powder_coefficient_a(self) -> float: @absorptivity_powder_coefficient_a.setter def absorptivity_powder_coefficient_a(self, value: float): - """Set absorptivity_powder_coefficient_a.""" + """Set absorptivity powder coefficient a.""" self._absorptivity_powder_coefficient_a = value @property @@ -405,7 +405,7 @@ def absorptivity_powder_coefficient_b(self) -> float: @absorptivity_powder_coefficient_b.setter def absorptivity_powder_coefficient_b(self, value: float): - """Set absorptivity_powder_coefficient_b.""" + """Set absorptivity powder coefficient b.""" self._absorptivity_powder_coefficient_b = value @property @@ -415,7 +415,7 @@ def absorptivity_solid_coefficient_a(self) -> float: @absorptivity_solid_coefficient_a.setter def absorptivity_solid_coefficient_a(self, value: float): - """Set absorptivity_solid_coefficient_a.""" + """Set absorptivity solid coefficient a.""" self._absorptivity_solid_coefficient_a = value @property @@ -425,7 +425,7 @@ def absorptivity_solid_coefficient_b(self) -> float: @absorptivity_solid_coefficient_b.setter def absorptivity_solid_coefficient_b(self, value: float): - """Set absorptivity_solid_coefficient_b.""" + """Set absorptivity solid coefficient b.""" self._absorptivity_solid_coefficient_b = value @property @@ -436,7 +436,7 @@ def anisotropic_strain_coefficient_parallel(self) -> float: @anisotropic_strain_coefficient_parallel.setter def anisotropic_strain_coefficient_parallel(self, value: float): - """Set anisotropic_strain_coefficient_parallel.""" + """Set anisotropic strain coefficient parallel.""" self._anisotropic_strain_coefficient_parallel = value @property @@ -448,7 +448,7 @@ def anisotropic_strain_coefficient_perpendicular(self) -> float: @anisotropic_strain_coefficient_perpendicular.setter def anisotropic_strain_coefficient_perpendicular(self, value: float): - """Set anisotropic_strain_coefficient_perpendicular.""" + """Set anisotropic strain coefficient perpendicular.""" self._anisotropic_strain_coefficient_perpendicular = value @property @@ -458,7 +458,7 @@ def anisotropic_strain_coefficient_z(self) -> float: @anisotropic_strain_coefficient_z.setter def anisotropic_strain_coefficient_z(self, value: float): - """Set anisotropic_strain_coefficient_z.""" + """Set anisotropic strain coefficient z.""" self._anisotropic_strain_coefficient_z = value @property @@ -468,30 +468,30 @@ def elastic_modulus(self) -> float: @elastic_modulus.setter def elastic_modulus(self, value: float): - """Set elastic_modulus.""" + """Set elastic modulus.""" self._elastic_modulus = value @property def hardening_factor(self) -> float: """Factor relating the elastic modulus to the tangent modulus for plasticity simulations (tangent modulus = elastic modulus * hardening - factor ).""" + factor).""" return self._hardening_factor @hardening_factor.setter def hardening_factor(self, value: float): - """Set hardening_factor.""" + """Set hardening factor.""" self._hardening_factor = value @property def liquidus_temperature(self) -> float: - """Minimum temperature at which the material is completely liquid - (K).""" + """Minimum temperature (K) at which the material is completely + liquid.""" return self._liquidus_temperature @liquidus_temperature.setter def liquidus_temperature(self, value: float): - """Set liquidus_temperature.""" + """Set liquidus temperature.""" self._liquidus_temperature = value @property @@ -501,12 +501,12 @@ def material_yield_strength(self) -> float: @material_yield_strength.setter def material_yield_strength(self, value: float): - """Set material_yield_strength.""" + """Set material yield strength.""" self._material_yield_strength = value @property def name(self) -> str: - """Name of material.""" + """Name of the material.""" return self._name @name.setter @@ -522,18 +522,18 @@ def nucleation_constant_bulk(self) -> float: @nucleation_constant_bulk.setter def nucleation_constant_bulk(self, value: float): - """Set nucleation_constant_bulk.""" + """Set nucleation constant bulk.""" self._nucleation_constant_bulk = value @property def nucleation_constant_interface(self) -> float: - """Controls the heterogeneous nucleation rate (on existing solid - interfaces) during solidification (1/m/K^2).""" + """Heterogeneous nucleation rate (on existing solid interfaces) during + solidification (1/m/K^2).""" return self._nucleation_constant_interface @nucleation_constant_interface.setter def nucleation_constant_interface(self, value: float): - """Set nucleation_constant_interface.""" + """Set nucleation constant interface.""" self._nucleation_constant_interface = value @property @@ -543,7 +543,7 @@ def penetration_depth_maximum(self) -> float: @penetration_depth_maximum.setter def penetration_depth_maximum(self, value: float): - """Set penetration_depth_maximum.""" + """Set penetration depth maximum.""" self._penetration_depth_maximum = value @property @@ -553,7 +553,7 @@ def penetration_depth_minimum(self) -> float: @penetration_depth_minimum.setter def penetration_depth_minimum(self, value: float): - """Set penetration_depth_minimum.""" + """Set penetration depth minimum.""" self._penetration_depth_minimum = value @property @@ -563,7 +563,7 @@ def penetration_depth_powder_coefficient_a(self) -> float: @penetration_depth_powder_coefficient_a.setter def penetration_depth_powder_coefficient_a(self, value: float): - """Set penetration_depth_powder_coefficient_a.""" + """Set penetration depth powder coefficient a.""" self._penetration_depth_powder_coefficient_a = value @property @@ -573,7 +573,7 @@ def penetration_depth_powder_coefficient_b(self) -> float: @penetration_depth_powder_coefficient_b.setter def penetration_depth_powder_coefficient_b(self, value: float): - """Set penetration_depth_powder_coefficient_b.""" + """Set penetration depth powder coefficient b.""" self._penetration_depth_powder_coefficient_b = value @property @@ -583,7 +583,7 @@ def penetration_depth_solid_coefficient_a(self) -> float: @penetration_depth_solid_coefficient_a.setter def penetration_depth_solid_coefficient_a(self, value: float): - """Set penetration_depth_solid_coefficient_a.""" + """Set penetration depth solid coefficient a.""" self._penetration_depth_solid_coefficient_a = value @property @@ -593,7 +593,7 @@ def penetration_depth_solid_coefficient_b(self) -> float: @penetration_depth_solid_coefficient_b.setter def penetration_depth_solid_coefficient_b(self, value: float): - """Set penetration_depth_solid_coefficient_b.""" + """Set penetration_depth solid coefficient b.""" self._penetration_depth_solid_coefficient_b = value @property @@ -603,7 +603,7 @@ def poisson_ratio(self) -> float: @poisson_ratio.setter def poisson_ratio(self, value: float): - """Set poisson_ratio.""" + """Set Poisson ratio.""" self._poisson_ratio = value @property @@ -613,7 +613,7 @@ def powder_packing_density(self) -> float: @powder_packing_density.setter def powder_packing_density(self, value: float): - """Set powder_packing_density.""" + """Set powder packing density.""" self._powder_packing_density = value @property @@ -624,7 +624,7 @@ def purging_gas_convection_coefficient(self) -> float: @purging_gas_convection_coefficient.setter def purging_gas_convection_coefficient(self, value: float): - """Set purging_gas_convection_coefficient.""" + """Set purging gas convection coefficient.""" self._purging_gas_convection_coefficient = value @property @@ -634,7 +634,7 @@ def solid_density_at_room_temperature(self) -> float: @solid_density_at_room_temperature.setter def solid_density_at_room_temperature(self, value: float): - """Set solid_density_at_room_temperature.""" + """Set solid density at room temperature.""" self._solid_density_at_room_temperature = value @property @@ -645,7 +645,7 @@ def solid_specific_heat_at_room_temperature(self) -> float: @solid_specific_heat_at_room_temperature.setter def solid_specific_heat_at_room_temperature(self, value: float): - """Set solid_specific_heat_at_room_temperature.""" + """Set solid specific heat at room temperature.""" self._solid_specific_heat_at_room_temperature = value @property @@ -656,18 +656,18 @@ def solid_thermal_conductivity_at_room_temperature(self) -> float: @solid_thermal_conductivity_at_room_temperature.setter def solid_thermal_conductivity_at_room_temperature(self, value: float): - """Set solid_thermal_conductivity_at_room_temperature.""" + """Set solid thermal conductivity at_room temperature.""" self._solid_thermal_conductivity_at_room_temperature = value @property def solidus_temperature(self) -> float: - """Maximum temperature at which the material is completely solid - (K).""" + """Maximum temperature (K) at which the material is completely + solid.""" return self._solidus_temperature @solidus_temperature.setter def solidus_temperature(self, value: float): - """Set solidus_temperature.""" + """Set solidus temperature.""" self._solidus_temperature = value @property @@ -677,18 +677,18 @@ def strain_scaling_factor(self) -> float: @strain_scaling_factor.setter def strain_scaling_factor(self, value: float): - """Set strain_scaling_factor.""" + """Set strain scaling factor.""" self._strain_scaling_factor = value @property def support_yield_strength_ratio(self) -> float: - """Factor to reduce the yield strength and elastic modulus of support - material.""" + """Factor to reduce the yield strength and elastic modulus of the + support material.""" return self._support_yield_strength_ratio @support_yield_strength_ratio.setter def support_yield_strength_ratio(self, value: float): - """Set support_yield_strength_ratio.""" + """Set support yield strength ratio.""" self._support_yield_strength_ratio = value @property @@ -698,28 +698,28 @@ def thermal_expansion_coefficient(self) -> float: @thermal_expansion_coefficient.setter def thermal_expansion_coefficient(self, value: float): - """Set thermal_expansion_coefficient.""" + """Set thermal expansion coefficient.""" self._thermal_expansion_coefficient = value @property def vaporization_temperature(self) -> float: - """Temperature at which material has completely changed from liquid to - vapor (K).""" + """Temperature (K) at which the material has completely changed from + liquid to vapor.""" return self._vaporization_temperature @vaporization_temperature.setter def vaporization_temperature(self, value: float): - """Set vaporization_temperature (K).""" + """Set vaporization temperature (K).""" self._vaporization_temperature = value @property def characteristic_width_data(self) -> list[CharacteristicWidthDataPoint]: - """List of :class:`CharacteristicWidthDataPoint`.""" + """List of the :class:`CharacteristicWidthDataPoint` class.""" return self._characteristic_width_data @characteristic_width_data.setter def characteristic_width_data(self, value: list[CharacteristicWidthDataPoint]): - """Set characteristic_width_data.""" + """Set characteristic width data.""" if not isinstance(value, collections.abc.Sequence): raise TypeError( "Invalid object type, {}, passed to characteristic_width_data()".format(type(value)) @@ -728,12 +728,12 @@ def characteristic_width_data(self, value: list[CharacteristicWidthDataPoint]): @property def thermal_properties_data(self) -> list[ThermalPropertiesDataPoint]: - """List of :class:`ThermalPropertiesDataPoint`.""" + """List of the :class:`ThermalPropertiesDataPoint` class.""" return self._thermal_properties_data @thermal_properties_data.setter def thermal_properties_data(self, value: list[ThermalPropertiesDataPoint]): - """Set thermal_properties_data.""" + """Set thermal properties data.""" if not isinstance(value, collections.abc.Sequence): raise TypeError( "Invalid object type, {}, passed to thermal_properties_data()".format(type(value)) @@ -742,8 +742,8 @@ def thermal_properties_data(self, value: list[ThermalPropertiesDataPoint]): @staticmethod def _from_material_message(msg: MaterialMessage): - """Create an ``AdditiveMaterial`` object from a material message - received from the Additive service.""" + """Create an additive mMaterial from a material message received from + the Additive service.""" if not isinstance(msg, MaterialMessage): raise ValueError("Invalid message object passed to from_material_message()") material = AdditiveMaterial() @@ -761,8 +761,8 @@ def _from_material_message(msg: MaterialMessage): return material def _to_material_message(self) -> MaterialMessage: - """Create a material message from this ``AdditiveMaterial`` to send to - the Additive service.""" + """Create a material message from the additive material to send to the + Additive service.""" msg = MaterialMessage() for p in self.__dict__: if p != "_characteristic_width_data" and p != "_thermal_properties_data": @@ -776,7 +776,7 @@ def _to_material_message(self) -> MaterialMessage: return msg def _load_parameters(self, parameters_file: str): - """Load material parameters from a json file.""" + """Load material parameters from a JSON file.""" with open(parameters_file, "r") as f: data = json.load(f) self.name = data["name"] @@ -790,7 +790,7 @@ def _load_parameters(self, parameters_file: str): setattr(self, name, parameters[p]) def _load_thermal_properties(self, thermal_lookup_file: str): - """Load thermal properties from a csv file.""" + """Load thermal properties from a CSV file.""" with open(thermal_lookup_file, "r") as f: reader = csv.reader(f) self.thermal_properties_data.clear() @@ -809,7 +809,7 @@ def _load_thermal_properties(self, thermal_lookup_file: str): ) def _load_characteristic_width(self, cw_lookup_file: str): - """Load characteristic width values from a csv file.""" + """Load characteristic width values from a CSV file.""" with open(cw_lookup_file, "r") as f: reader = csv.reader(f) self.characteristic_width_data.clear() diff --git a/src/ansys/additive/material_tuning.py b/src/ansys/additive/material_tuning.py index 02bf8911f..f060998be 100644 --- a/src/ansys/additive/material_tuning.py +++ b/src/ansys/additive/material_tuning.py @@ -11,18 +11,18 @@ class MaterialTuningInput: - """Input parameters for tuning a custom material. + """Provides input parameters for tuning a custom material. Parameters ---------- id: string - User provided identifier for this simulation. + User-provided ID for this simulation. machine: AdditiveMachine - Machine related parameters. + Machine-related parameters. material: AdditiveMaterial Material used during simulation. bead_length: float - Length of bead to simulate (m). + Length (m) of bead to simulate. """ def __init__( @@ -42,29 +42,28 @@ def __init__( Parameters ---------- id: str - Identifier for this set of tuning simulations. + ID for this set of tuning simulations. experiment_data_file: str - Name of CSV file containing experimental results data. + Name of the CSV file containing the experimental results data. material_parameters_file: str - Name of JSON file containing material parameters. + Name of the JSON file containing the material parameters. thermal_properties_lookup_file: str - Name of CSV file containing a lookup table for thermal dependent properties. - characteristic_width_lookup_file: str - Optional: Name of CSV file containing a lookup table for the characteristic melt pool - width at a given temperature. If not provided, the characteristic width will be - calculated and ``base_plate_temperature`` must be provided. - Default is None. - allowable_error: float + Name of the CSV file containing a lookup table for thermal-dependent properties. + characteristic_width_lookup_file: str, None + Name of the CSV file containing a lookup table for the characteristic melt pool + width at a given temperature. The default is ``None``, in which case the characteristic + width is calculated. However, a value must be provided for the ``base_plate_temperature`` + parameter. + allowable_error: float, 0.05 Maximum allowable error between experimental and simulated results. - Default is 0.05 (5%). - max_iterations: int + The default is ``0.05``, which is 5 percent. + max_iterations: int, 15 Maximum number of iterations to perform when trying to match simulation results to an experiment if the allowable error is not met. - Default is 15. - base_plate_temperature: float - Temperature of the base plate in Kelvin. This is only required if - ``characteristic_width_lookup_file`` is ``None``. It is ignored otherwise. - Default is 353.15 K (80 C). + base_plate_temperature: float, 353.15 + Temperature of the base plate in Kelvin. This is only required if the + value for the ``characteristic_width_lookup_file`` parameter is ``None``. + This value is ignored otherwise. The default is ``353.15`` K, which is 80 C. """ if not os.path.isfile(experiment_data_file): @@ -120,7 +119,7 @@ def __eq__(self, other: object) -> bool: class MaterialTuningSummary: - """Summary of a material tuning simulations.""" + """Provides a summary of material tuning simulations.""" def __init__(self, input: MaterialTuningInput, msg: MaterialTuningResultMessage, out_dir: str): """Initialize a ``MaterialTuningSummary`` object.""" @@ -159,17 +158,17 @@ def input(self) -> MaterialTuningInput: @property def optimized_parameters_file(self) -> str: - """Path to optimization parameters file.""" + """Path to the optimization parameters file.""" return self._optimized_parameters_file @property def characteristic_width_file(self) -> str: - """Path to characteristic width file or ``None``.""" + """Path to the characteristic width file or ``None``.""" return self._characteristic_width_file @property def log_file(self) -> str: - """Path to tuning log file or ``None``.""" + """Path to the tuning log file or ``None``.""" return self._log_file def __repr__(self): diff --git a/src/ansys/additive/microstructure.py b/src/ansys/additive/microstructure.py index 426657027..96829aed8 100644 --- a/src/ansys/additive/microstructure.py +++ b/src/ansys/additive/microstructure.py @@ -16,9 +16,9 @@ class MicrostructureInput: - """Input parameters for microstructure simulation. + """Provides input parameters for microstructure simulation. - Units are SI (m, kg, s, K) unless otherwise noted. + Units are SI (m, kg, s, and K) unless otherwise noted. """ #: Default minimum x, y, z, position coordinate (m). @@ -163,7 +163,7 @@ def __validate_size(size_value, sensor_value, cushion, name): @property def id(self) -> str: - """User provided identifier for this simulation.""" + """User-provided ID for this simulation.""" return self._id @id.setter @@ -172,7 +172,7 @@ def id(self, value: str): @property def machine(self): - """Machine related parameters.""" + """Machine-related parameters.""" return self._machine @machine.setter @@ -190,7 +190,7 @@ def material(self, value): @property def sample_min_x(self) -> float: - """Minimum x coordinate of the geometry sample (m).""" + """Minimum x coordinate (m) of the geometry sample.""" return self._sample_min_x @sample_min_x.setter @@ -202,7 +202,7 @@ def sample_min_x(self, value: float): @property def sample_min_y(self) -> float: - """Minimum y coordinate of the geometry sample (m).""" + """Minimum y coordinate (m) of the geometry sample.""" return self._sample_min_y @sample_min_y.setter @@ -214,7 +214,7 @@ def sample_min_y(self, value: float): @property def sample_min_z(self) -> float: - """Minimum z coordinate of the geometry sample (m).""" + """Minimum z coordinate (m) of the geometry sample.""" return self._sample_min_z @sample_min_z.setter @@ -228,7 +228,7 @@ def sample_min_z(self, value: float): def sample_size_x(self) -> float: """Size of the geometry sample in the x direction (m). - Valid values are 0.001 to 0.01. + Valid values are from 0.001 to 0.01. """ return self._sample_size_x @@ -246,7 +246,7 @@ def sample_size_x(self, value: float): def sample_size_y(self) -> float: """Size of the geometry sample in the y direction (m). - Valid values are 0.001 to 0.01. + Valid values are from 0.001 to 0.01. """ return self._sample_size_y @@ -264,7 +264,7 @@ def sample_size_y(self, value: float): def sample_size_z(self) -> float: """Size of the geometry sample in the z direction (m). - Valid values are 0.001 to 0.01. + Valid values are from 0.001 to 0.01. """ return self._sample_size_z @@ -282,7 +282,7 @@ def sample_size_z(self, value: float): def sensor_dimension(self) -> float: """Dimension of the sensor (m). - Valid values are 0.0001 to 0.001. + Valid values are from 0.0001 to 0.001. """ return self._sensor_dimension @@ -317,8 +317,9 @@ def sensor_dimension(self, value: float): @property def use_provided_thermal_parameters(self) -> bool: - """If ``True``, indicates that cooling_rate, thermal_gradient, - melt_pool_depth and melt_pool_width have been provided by the user.""" + """Check to see if the ``cooling_rate``, ``thermal_gradient``, + ``melt_pool_depth``, and ``melt_pool_width`` parameters have been + provided by the user.""" return self._use_provided_thermal_parameters @use_provided_thermal_parameters.setter @@ -329,7 +330,7 @@ def use_provided_thermal_parameters(self, value: bool): def cooling_rate(self) -> float: """Material cooling rate (K/s). - Valid values are 1e5 to 1e7. + Valid values are from 1e5 to 1e7. """ return self._cooling_rate @@ -344,7 +345,7 @@ def cooling_rate(self, value: float): def thermal_gradient(self) -> float: """Material thermal gradient (K/m). - Valid values are 1e5 to 1e8. + Valid values are from 1e5 to 1e8. """ return self._thermal_gradient @@ -359,10 +360,12 @@ def thermal_gradient(self, value: float): def melt_pool_width(self) -> float: """Melt pool width (m). - This is the width of the melt pool measured at the top of the powder layer - which corresponds to the ``WIDTH``value in - :class:`MeltPoolColumnNames `. - Valid values are 7.5e-5 to 8e-4. + This is the width of the melt pool measured at the top of the powder layer, + which corresponds to the ``WIDTH`` value in + :class:`MeltPoolColumnNames ` + class. + + Valid values are from 7.5e-5 to 8e-4. """ return self._melt_pool_width @@ -377,10 +380,12 @@ def melt_pool_width(self, value: float): def melt_pool_depth(self) -> float: """Melt pool depth (m). - This is the depth of the melt pool as measured from the top of the powder layer - which corresponds to the ``DEPTH``value in - :class:`MeltPoolColumnNames `. - Valid values are 1.5e-5 to 8e-4. + This is the depth of the melt pool as measured from the top of the powder layer, + which corresponds to the ``DEPTH``value in the + :class:`MeltPoolColumnNames ` + class. + + Valid values are from 1.5e-5 to 8e-4. """ return self._melt_pool_depth @@ -395,7 +400,7 @@ def melt_pool_depth(self, value: float): def random_seed(self) -> int: """Random seed for the simulation. - Valid values are 1 to 4294967295. + Valid values are from 1 to 4294967295. """ return self._random_seed @@ -428,7 +433,7 @@ def _to_simulation_request(self) -> SimulationRequest: class CircleEquivalenceColumnNames: - """Column names for the circle equivalence data frame.""" + """Provides column names for the circle equivalence data frame.""" #: Grain number GRAIN_NUMBER = "grain_number" @@ -441,10 +446,11 @@ class CircleEquivalenceColumnNames: class MicrostructureSummary: - """Summary of a microstructure simulation. + """Provides the summary of a microstructure simulation. - Units are typically SI (m, kg, s, K), however, some of the values - listed below do not use SI units. See descriptions for details. + Units are typically SI (m, kg, s, and K). However, some of the + following values do not use SI units. For more information, see the + descriptions. """ def __init__( @@ -491,61 +497,67 @@ def __init__( @property def input(self): - """Simulation input, see :class:`MicrostructureInput`.""" + """Simulation input. + + For more information, see the :class:`MicrostructureInput` class. + """ return self._input @property def xy_vtk(self) -> str: - """Path to VTK file containing 2-D grain structure data in XY plane.""" + """Path to the VTK file containing the 2-D grain structure data in the + XY plane.""" return self._xy_vtk @property def xz_vtk(self) -> str: - """Path to VTK file containing 2-D grain structure data in XZ plane.""" + """Path to the VTK file containing the 2-D grain structure data in the + XZ plane.""" return self._xz_vtk @property def yz_vtk(self) -> str: - """Path to VTK file containing 2-D grain structure data in YZ plane.""" + """Path to the VTK file containing the 2-D grain structure data in the + YZ plane.""" return self._yz_vtk @property def xy_circle_equivalence(self) -> pd.DataFrame: - """Circle equivalence data for XY plane. + """Circle equivalence data for the XY plane. - See :class:`CircleEquivalenceColumnNames` for data frame column names. + For data frame column names, see the :class:`CircleEquivalenceColumnNames` class. """ return self._xy_circle_equivalence @property def xz_circle_equivalence(self) -> pd.DataFrame: - """Circle equivalence data for XZ plane. + """Circle equivalence data forthe XZ plane. - See :class:`CircleEquivalenceColumnNames` for data frame column names. + For data frame column names, see the :class:`CircleEquivalenceColumnNames` class. """ return self._xz_circle_equivalence @property def yz_circle_equivalence(self) -> pd.DataFrame: - """Circle equivalence data for YZ plane. + """Circle equivalence data for the YZ plane. - See :class:`CircleEquivalenceColumnNames` for data frame column names. + For data frame column names, see the :class:`CircleEquivalenceColumnNames` class. """ return self._yz_circle_equivalence @property def xy_average_grain_size(self) -> float: - """Average grain size (µm) for XY plane.""" + """Average grain size (µm) for the XY plane.""" return self._xy_average_grain_size @property def xz_average_grain_size(self) -> float: - """Average grain size (µm) for XZ plane.""" + """Average grain size (µm) for the XZ plane.""" return self._xz_average_grain_size @property def yz_average_grain_size(self) -> float: - """Average grain size (µm) for YZ plane.""" + """Average grain size (µm) for the YZ plane.""" return self._yz_average_grain_size @staticmethod diff --git a/src/ansys/additive/parametric_study/constants.py b/src/ansys/additive/parametric_study/constants.py index 8e6142539..7f30a476c 100644 --- a/src/ansys/additive/parametric_study/constants.py +++ b/src/ansys/additive/parametric_study/constants.py @@ -1,26 +1,26 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. class ColumnNames: - """Column names for the parametric study data frame. + """Provides column names for the parametric study data frame. Values are stored internally as a :class:`Pandas DataFrame - `. The column names are defined here. + `. Column name definitions follow. """ #: Name of the parametric summary project. PROJECT = "Project" - #: Iteration number, useful for tracking the sequence of simulation groups. + #: Iteration number, which is useful for tracking the sequence of simulation groups. ITERATION = "Iteration" #: Priority value used to determine execution order. PRIORITY = "Priority" - #: Type of simulation, e.g. single bead, porosity, microstructure. + #: Type of simulation. For example, single bead, porosity, or microstructure. TYPE = "Type" #: Identifier for the simulation. #: NOTE: A unique ID for each permutation is enforced by the parametric study. ID = "ID" - #: Status of the simulation, e.g. pending, success, failure. + #: Status of the simulation. For example, pending, success, or failure. STATUS = "Status" #: Name of material used during simulation. - #: See :class:`AdditiveMaterial ` for more information. + #: For more information, see :class:`AdditiveMaterial `. MATERIAL = "Material" #: Heater temperature (°C). HEATER_TEMPERATURE = "Heater Temp (°C)" @@ -83,15 +83,15 @@ class ColumnNames: MICRO_SIZE_Z = "Micro Size Z (m)" #: Sensor dimension used in microstructure simulations (m). MICRO_SENSOR_DIM = "Micro Sensor Dim (m)" - #: User provided cooling rate used in microstructure simulations (°K/s). + #: User-provided cooling rate used in microstructure simulations (°K/s). COOLING_RATE = "Cooling Rate (°K/s)" - #: User provided thermal gradient used in microstructure simulations (°K/m). + #: User-provided thermal gradient used in microstructure simulations (°K/m). THERMAL_GRADIENT = "Thermal Gradient (°K/m)" - #: User provided melt pool width used in microstructure simulation (m). + #: User-provided melt pool width used in microstructure simulation (m). MICRO_MELT_POOL_WIDTH = "Micro Melt Pool Width (m)" - #: User provided melt pool depth used in microstructure simulation (m). + #: User-provided melt pool depth used in microstructure simulation (m). MICRO_MELT_POOL_DEPTH = "Micro Melt Pool Depth (m)" - #: User provided random seed used in microstructure simulation. + #: User-provided random seed used in microstructure simulation. RANDOM_SEED = "Random Seed" #: Average microstructure grain size in the XY plane (µm). XY_AVERAGE_GRAIN_SIZE = "XY Average Grain Size (µm)" diff --git a/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py b/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py index f2453fe6c..286d09764 100644 --- a/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py +++ b/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py @@ -16,17 +16,17 @@ def ave_grain_size_plot(ps: ParametricStudy): - """Provides a contour plot of build rate and relative density. + """Generates a contour plot of build rate and relative density. Parameters ---------- ps : :class:`ParametricStudy ` - Parametric study to be plotted. + Parametric study to plot. Returns ------- :class: `panel.Row ` - A ``Panel Row`` object containing the plot and controls. + Panel row containing the plot and controls. """ df = __data_frame(ps) ( diff --git a/src/ansys/additive/parametric_study/display/porosity_contour_plot.py b/src/ansys/additive/parametric_study/display/porosity_contour_plot.py index b54ebbae9..93c9e5f50 100644 --- a/src/ansys/additive/parametric_study/display/porosity_contour_plot.py +++ b/src/ansys/additive/parametric_study/display/porosity_contour_plot.py @@ -15,17 +15,17 @@ def porosity_contour_plot(ps: ParametricStudy): - """Provides a contour plot of build rate and relative density. + """Generates a contour plot of build rate and relative density. Parameters ---------- ps : :class:`ParametricStudy ` - Parametric study to be plotted. + Parametric study to plot. Returns ------- :class: `panel.Row ` - A ``Panel Row`` object containing the plot and controls. + Panel row containing the plot and controls. """ df = __data_frame(ps) ( diff --git a/src/ansys/additive/parametric_study/display/show_table.py b/src/ansys/additive/parametric_study/display/show_table.py index 878e1f2f1..c588515c5 100644 --- a/src/ansys/additive/parametric_study/display/show_table.py +++ b/src/ansys/additive/parametric_study/display/show_table.py @@ -17,19 +17,19 @@ def show_table(ps: ParametricStudy, page_size: int = 10): - """Provides an interactive display of the parametric study table. + """Generate an interactive display of the parametric study table. Parameters ---------- ps : :class:`ParametricStudy ` - Parametric study to be displayed. - page_size : int, optional - Number of rows to display per page. The default is 10. + Parametric study to display. + page_size : int, 10 + Number of rows to display per page. Returns ------- :class:`panel.Column ` - A ``Panel Column`` object containing the table and controls. + Panel column containing the table and controls. """ global _df, _ps, _iter_select, _pri_select diff --git a/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py b/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py index 6a2efbae0..ba51bd80d 100644 --- a/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py +++ b/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py @@ -20,18 +20,18 @@ def single_bead_eval_plot(ps: ParametricStudy): - """Provides a contour plot of single bead results useful for determining - desirable melt pool statistics. + """Generate a contour plot of single bead results to determine desirable + melt pool statistics. Parameters ---------- ps : :class:`ParametricStudy ` - Parametric study to be plotted. + Parametric study to plot. Returns ------- :class: `panel.Row ` - A Panel Row object containing the plot and controls. + Panel row containing the plot and controls. """ df = __data_frame(ps) ( @@ -204,7 +204,7 @@ def __update_plot( def __contour_data( df: pd.DataFrame, ht: float, lt: float, bd: float, poi: str, range: Tuple[float, float] ) -> Tuple[list, list, list, list]: - """Returns lists of scan speed, laser power, and parameter of interest + """Get lists of scan speed, laser power, and parameter of interest values.""" idx = df[ diff --git a/src/ansys/additive/parametric_study/parametric_runner.py b/src/ansys/additive/parametric_study/parametric_runner.py index 428271335..39c4e9fae 100644 --- a/src/ansys/additive/parametric_study/parametric_runner.py +++ b/src/ansys/additive/parametric_study/parametric_runner.py @@ -33,23 +33,25 @@ def simulate( ``SimulationStatus.PENDING`` in the ``ColumnNames.STATUS`` column. Execution order is determined by the values in the ``ColumnNames.PRIORITY`` column. - Lower values are interpreted as having higher priority and will be run first. + Lower values are interpreted as having higher priority and are run first. Parameters ---------- df : pd.DataFrame - The parametric study data frame. - additive: Additive - The :class:`Additive ` service to use for running simulations. - type : Optional[List[SimulationType]], optional - The type of simulations to run, ``None`` indicates all types. - priority : Optional[int] - The priority of simulations to run, ``None`` indicates all priorities. + Parametric study data frame. + additive: :class:`Additive ` + Additive service to use for running simulations. + type : list, None + List of the simulation types to run. The default is ``None``, in which case all + simulation types are run. + priority : int, None + Priority of simulations to run. The default is ``None``, in which case + all priorities are run. Returns ------- List[Union[MicrostructureSummary, PorositySummary, SingleBeadSummary]] - A list of simulation summaries. + List of simulation summaries. """ if type is None: type = [ @@ -68,7 +70,7 @@ def simulate( view = view.sort_values(by=ColumnNames.PRIORITY, ascending=True) inputs = [] - # NOTICE: We use iterrows() instead of itertuples() here in order to + # NOTICE: We use iterrows() instead of itertuples() here to # access values by column name for _, row in view.iterrows(): try: diff --git a/src/ansys/additive/parametric_study/parametric_study.py b/src/ansys/additive/parametric_study/parametric_study.py index b328c6ddb..7eaaea253 100644 --- a/src/ansys/additive/parametric_study/parametric_study.py +++ b/src/ansys/additive/parametric_study/parametric_study.py @@ -32,7 +32,7 @@ class ParametricStudy: - """Data storage and utility methods for a parametric study.""" + """Provides data storage and utility methods for a parametric study.""" def __init__(self, project_name: str): pn.extension() @@ -51,11 +51,12 @@ def __eq__(self, other): ) def data_frame(self) -> pd.DataFrame: - """Return a copy of the internal parametric study :class:`DataFrame - `. + """Return a copy of the internal data frame for the parametric study. - See :class:`ColumnNames` for the column names used in the returned ``DataFrame``. - .. note:: Updating the returned ``DataFrame`` will not update the internal ``DataFrame``. + For the column names used in the returned data frame, see the `:class:`ColumnNames` class. + + .. note:: + Updating the returned data frame does not update the internal data frame. """ return self._data_frame.copy() @@ -71,26 +72,28 @@ def run_simulations( ``SimulationStatus.PENDING`` in the ``ColumnNames.STATUS`` column. Execution order is determined by the values in the ``ColumnNames.PRIORITY`` column. Lower values are interpreted as having - higher priority and will be run first. + higher priority and are run first. Parameters ---------- - additive: Additive - The :class:`Additive ` service to use for running simulations. - type : Optional[List[SimulationType]], optional - The type of simulations to run, ``None`` indicates all types. - priority : Optional[int] - The priority of simulations to run, ``None`` indicates all priorities. + additive: :class:`Additive ` + Additive service to use for running simulations. + type : list[SimulationType], None + Type of simulations to run. The default is ``None``, in which case + all simulation types are run. + priority : int, None + Priority of simulations to run. The default is ``None``, in which + case all priorities are run. """ # TODO: Add support for running multiple simulations in parallel # once issue https://github.com/ansys-internal/pyadditive/issues/9 # is resolved - # workers : int, optional - # The number of workers to use for multiprocessing. Each worker - # will need to be able to check out an Additive license. - # threads : int, optional - # The number of threads to use for each worker. Each thread will - # check out an HPC license. + # workers : int, 1 + # Number of workers to use for multiprocessing. Each worker + # must be able to check out an Additive license. + # threads : int, 4 + # Number of threads to use for each worker. Each thread must + # be able to check out an HPC license. summaries = ParametricRunner.simulate( self.data_frame(), additive, @@ -107,7 +110,7 @@ def save(self, filename): Parameters ---------- filename : str - Name of file to save the parametric study to. + Name of the file to save the parametric study to. """ with open(filename, "wb") as f: dill.dump(self, f) @@ -124,7 +127,7 @@ def load(filename): Returns ------- ParametricStudy - The loaded parametric study. + Loaded parametric study. """ with open(filename, "rb") as f: return dill.load(f) @@ -137,8 +140,8 @@ def add_summaries( """Add summaries of previously executed simulations to the parametric study. - This function adds new simulations to the parametric study. To update existing - simulations, use :meth:`update`. + This method adds new simulations to the parametric study. To update existing + simulations, use the :meth:`update` method. Parameters ---------- @@ -281,15 +284,15 @@ def _common_param_to_dict( Parameters ---------- summary : Union[SingleBeadSummary, PorositySummary, MicrostructureSummary] - The summary to convert. + Summary of common simulation parameters to convert. - iteration : int, optional - The iteration number for this simulation. + iteration : int, DEFAULT_ITERATION + Iteration number for this simulation. Returns ------- Dict[str, Any] - The dictionary of common parameters. + Dictionary of common simulation parameters. """ return { ColumnNames.PROJECT: self._project_name, @@ -327,39 +330,43 @@ def generate_single_bead_permutations( Parameters ---------- material_name : str - The material name. - laser_powers : List[float] + Material name. + laser_powers : list[float] Laser powers (W) to use for single bead simulations. - scan_speeds : List[float] + scan_speeds : list[float] Scan speeds (m/s) to use for single bead simulations. - bead_length : float, optional - The length of the bead (m). - layer_thicknesses : Optional[List[float]] + bead_length : float, DEFAULT_BEAD_LENGTH + Length of the bead (m). + layer_thicknesses : list[float], None Layer thicknesses (m) to use for single bead simulations. - If None, ``MachineConstants.DEFAULT_LAYER_THICKNESS`` is used. - See :class:`MachineConstants `. - heater_temperatures : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_LAYER_THICKNESS`` + is used. For more information, see the + :class:`MachineConstants ` + class. + heater_temperatures : List[float], None Heater temperatures (C) to use for single bead simulations. - If None, ``MachineConstants.DEFAULT_HEATER_TEMP`` is used. - See :class:`MachineConstants `. - beam_diameters : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_HEATER_TEMP`` + is used. For more information, see the + :class:`MachineConstants ` + class. + beam_diameters : List[float], None Beam diameters (m) to use for single bead simulations. - If None, ``MachineConstants.DEFAULT_BEAM_DIAMETER`` is used. - See :class:`MachineConstants `. - min_area_energy_density : Optional[float] - The minimum area energy density (J/m^2) to use for single bead simulations. - Parameter combinations with an area energy density below this value will - not be included. - Area energy density is defined as laser power / (layer thickness * scan speed). - max_area_energy_density : Optional[float] - The maximum area energy density (J/m^2) to use for single bead simulations. - Parameter combinations with an area energy density above this value will - not be included. - Area energy density is defined as laser power / (layer thickness * scan speed). - iteration : int, optional - The iteration number for this set of simulations. - priority : int, optional - The priority for this set of simulations. + The default is ``None``, in which case``MachineConstants.DEFAULT_BEAM_DIAMETER`` + is used. For more information, see the + :class:`MachineConstants ` + class. + min_area_energy_density : float, None + Minimum area energy density (J/m^2) to use for single bead simulations. + Parameter combinations with an area energy density below this value are + not included. Area energy density is defined as laser power / (layer thickness * scan speed). + max_area_energy_density : float, None + Maximum area energy density (J/m^2) to use for single bead simulations. + Parameter combinations with an area energy density above this value are + not included. Area energy density is defined as laser power / (layer thickness * scan speed). + iteration : int, DEFAULT_ITERATION + Iteration number for this set of simulations. + priority : int, DEFAULT_PRIORITY + Priority for this set of simulations. """ lt = ( layer_thicknesses @@ -458,73 +465,79 @@ def generate_porosity_permutations( Parameters ---------- material_name : str - The material name. - laser_powers : List[float] + Material name. + laser_powers : list[float] Laser powers (W) to use for porosity simulations. - scan_speeds : List[float] + scan_speeds : list[float] Scan speeds (m/s) to use for porosity simulations. - size_x : float, optional - The size (m) of the porosity sample in the x direction. + size_x : float, DEFAULT_SAMPLE_SIZE + Size (m) of the porosity sample in the x direction. Valid values are between 0.001 and 0.01. - size_y : float, optional - The size (m) of the porosity sample in the y direction. + size_y : float, DEFAULT_SAMPLE_SIZE + Size (m) of the porosity sample in the y direction. Valid values are between 0.001 and 0.01. - size_z : float, optional - The size (m) of the porosity sample in the z direction. + size_z : float, DEFAULT_SAMPLE_SIZE + Size (m) of the porosity sample in the z direction. Valid values are between 0.001 and 0.01. - layer_thicknesses : Optional[List[float]] + layer_thicknesses : list[float], None Layer thicknesses (m) to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_LAYER_THICKNESS`` is used. - See :class:`MachineConstants `. - heater_temperatures : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_LAYER_THICKNESS`` + is used. For more information, see the + :class:`MachineConstants ` + class. + heater_temperatures : list[float], None Heater temperatures (C) to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_HEATER_TEMP`` is used. - See :class:`MachineConstants `. - beam_diameters : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_HEATER_TEMP`` + is used. For more information, see the + :class:`MachineConstants ` + class. + beam_diameters : list[float], None Beam diameters (m) to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_BEAM_DIAMETER`` is used. - See :class:`MachineConstants `. - start_angles : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_BEAM_DIAMETER`` + is used. For more information, see the + :class:`MachineConstants ` + class. + start_angles : list[float], None Scan angles (deg) for the first layer to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_STARTING_LAYER_ANGLE`` is used. - See :class:`MachineConstants `. - rotation_angles : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_STARTING_LAYER_ANGLE`` + is used. For more information, see the + :class:`MachineConstants ` class. + rotation_angles : list[float], None Angles (deg) by which the scan direction is rotated with each layer - to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_LAYER_ROTATION_ANGLE`` is used. - See :class:`MachineConstants `. - hatch_spacings : Optional[List[float]] - Hatch spacings (m) to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_HATCH_SPACING`` is used. - See :class:`MachineConstants `. - stripe_widths : Optional[List[float]] - Stripe widths (m) to use for porosity simulations. - If None, ``MachineConstants.DEFAULT_SLICING_STRIPE_WIDTH`` is used. - See :class:`MachineConstants `. - min_energy_density : Optional[float] - The minimum energy density (J/m^3) to use for porosity simulations. - Parameter combinations with an area energy density below this value will - not be included. - Area energy density is defined as laser power / (layer thickness * scan speed * hatch spacing). - max_energy_density : Optional[float] - The maximum energy density (J/m^3) to use for porosity simulations. - Parameter combinations with an area energy density above this value will - not be included. - Energy density is defined as laser power / (layer thickness * scan speed * hatch spacing). - min_build_rate : Optional[float] - The minimum build rate (m^3/s) to use for porosity simulations. - Parameter combinations with a build rate below this value will - not be included. - Build rate is defined as layer thickness * scan speed * hatch spacing. - max_build_rate : Optional[float] - The maximum build rate (m^3/s) to use for porosity simulations. - Parameter combinations with a build rate above this value will - not be included. - Build rate is defined as layer thickness * scan speed * hatch spacing. - iteration : int, optional - The iteration number for this set of simulations. - priority : int, optional - The priority for this set of simulations. + to use for porosity simulations. The default is ``None``, in which + case ``MachineConstants.DEFAULT_LAYER_ROTATION_ANGLE`` is used. For more + information, see the :class:`MachineConstants ` + class. + hatch_spacings : list[float], None + Hatch spacings (m) to use for porosity simulations. The default is ``None``, + in which case ``MachineConstants.DEFAULT_HATCH_SPACING`` is used. For more + information, see the :class:`MachineConstants ` + class. + stripe_widths : list[float], None + Stripe widths (m) to use for porosity simulations. The default is ``None``, in + which case ``MachineConstants.DEFAULT_SLICING_STRIPE_WIDTH`` is used. For more + information, see the :class:`MachineConstants ` + class. + min_energy_density : float, None + Minimum energy density (J/m^3) to use for porosity simulations. Parameter combinations + with an area energy density below this value are not included. Area energy density is + defined as laser power / (layer thickness * scan speed * hatch spacing). + max_energy_density : float, None + Maximum energy density (J/m^3) to use for porosity simulations. Parameter combinations + with an area energy density above this value are not included. Energy density is defined + as laser power / (layer thickness * scan speed * hatch spacing). + min_build_rate : float, None + Minimum build rate (m^3/s) to use for porosity simulations. Parameter combinations + with a build rate below this value are not included. Build rate is defined as + layer thickness * scan speed * hatch spacing. + max_build_rate : float, None + Maximum build rate (m^3/s) to use for porosity simulations. Parameter combinations + with a build rate above this value are not included. Build rate is defined as + layer thickness * scan speed * hatch spacing. + iteration : int, DEFAULT_ITERATION + Iteration number for this set of simulations. + priority : int, DEFAULT_PRIORITY + Priority for this set of simulations. """ lt = ( layer_thicknesses @@ -672,113 +685,130 @@ def generate_microstructure_permutations( Parameters ---------- material_name : str - The material name. - laser_powers : List[float] + Material name. + laser_powers : list[float] Laser powers (W) to use for microstructure simulations. - scan_speeds : List[float] + scan_speeds : list[float] Scan speeds (m/s) to use for microstructure simulations. - min_x : float, optional - The minimum x coordinate (m) of the microstructure sample. - min_y : float, optional - The minimum y coordinate (m) of the microstructure sample. - min_z : float, optional - The minimum z coordinate (m) of the microstructure sample. - size_x : float, optional - The size (m) of the microstructure sample in the x direction. + min_x : float, DEFAULT_POSITION_COORDINATE + Minimum x coordinate (m) of the microstructure sample. + min_y : float, DEFAULT_POSITION_COORDINATE + Minimum y coordinate (m) of the microstructure sample. + min_z : float, DEFAULT_POSITION_COORDINATE + Minimum z coordinate (m) of the microstructure sample. + size_x : float, DEFAULT_SAMPLE_SIZE + Size (m) of the microstructure sample in the x direction. Valid values are between 0.001 and 0.01. - size_y : float, optional - The size (m) of the microstructure sample in the y direction. + size_y : float, DEFAULT_SAMPLE_SIZE + Size (m) of the microstructure sample in the y direction. Valid values are between 0.001 and 0.01. - size_z : float, optional - The size (m) of the microstructure sample in the z direction. + size_z : float, DEFAULT_SAMPLE_SIZE + Size (m) of the microstructure sample in the z direction. Valid values are between 0.001 and 0.01. - sensor_dimension : float, optional - The sensor dimension (m) to use for microstructure simulations. - Valid values are between 0.0001 and 0.001. - ``size_x`` and ``size_y`` must be greater than ``sensor_dimension`` by 0.0005. - ``size_z`` must be greater than ``sensor_dimension`` by 0.001. - layer_thicknesses : Optional[List[float]] + sensor_dimension : float, DEFAULT_SENSOR_DIMENSION + Sensor dimension (m) to use for microstructure simulations. + Valid values are between 0.0001 and 0.001. The values for the + ``size_x`` and ``size_y`` parameters must be greater than the + ``sensor_dimension`` parameter by 0.0005. The value for the + ``size_z`` parameter must be greater than ``sensor_dimension`` + parameter by 0.001. + layer_thicknesses : list[float], None Layer thicknesses (m) to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_LAYER_THICKNESS`` is used. - See :class:`MachineConstants `. - heater_temperatures : Optional[List[float]] + The default is ``None``, in which case + ``MachineConstants.DEFAULT_LAYER_THICKNESS`` is used. + For more information, see the + :class:`MachineConstants ` + class. + heater_temperatures : list[float], None Heater temperatures (C) to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_HEATER_TEMP`` is used. - See :class:`MachineConstants `. - beam_diameters : Optional[List[float]] - Beam diameters (m) to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_BEAM_DIAMETER`` is used. - See :class:`MachineConstants `. - start_angles : Optional[List[float]] + The default is ``None``, in which case + ``MachineConstants.DEFAULT_HEATER_TEMP`` is used. + For more information, see the + :class:`MachineConstants ` class. + beam_diameters : list[float], None + Beam diameters (m) to use for microstructure simulations. The default is + ``None``, in which case ``MachineConstants.DEFAULT_BEAM_DIAMETER`` is used. + For more information, see the + :class:`MachineConstants ` class. + start_angles : list[float], None Scan angles (deg) for the first layer to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_STARTING_LAYER_ANGLE`` is used. - See :class:`MachineConstants `. - rotation_angles : Optional[List[float]] + The default is ``None``, in which case ``MachineConstants.DEFAULT_STARTING_LAYER_ANGLE`` + is used. For more information, see the + :class:`MachineConstants ` class. + rotation_angles : List[float], None Angles (deg) by which the scan direction is rotated with each layer - to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_LAYER_ROTATION_ANGLE`` is used. - See :class:`MachineConstants `. - hatch_spacings : Optional[List[float]] - Hatch spacings (m) to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_HATCH_SPACING`` is used. - See :class:`MachineConstants `. - stripe_widths : Optional[List[float]] - Stripe widths (m) to use for microstructure simulations. - If None, ``MachineConstants.DEFAULT_SLICING_STRIPE_WIDTH`` is used. - See :class:`MachineConstants `. - min_energy_density : Optional[float] - The minimum energy density (J/m^3) to use for microstructure simulations. - Parameter combinations with an area energy density below this value will - not be included. - Area energy density is defined as laser power / (layer thickness * scan speed * hatch spacing). - max_energy_density : Optional[float] - The maximum energy density (J/m^3) to use for microstructure simulations. - Parameter combinations with an area energy density above this value will - not be included. - Energy density is defined as laser power / (layer thickness * scan speed * hatch spacing). - min_build_rate : Optional[float] - The minimum build rate (m^3/s) to use for microstructure simulations. - Parameter combinations with a build rate below this value will - not be included. - Build rate is defined as layer thickness * scan speed * hatch spacing. - max_build_rate : Optional[float] - The maximum build rate (m^3/s) to use for microstructure simulations. - Parameter combinations with a build rate above this value will - not be included. - Build rate is defined as layer thickness * scan speed * hatch spacing. - cooling_rate : Optional[float] - The cooling rate (K/s) to use for microstructure simulations. - If None, and ``thermal_gradient``, ``melt_pool_width``, and ``melt_pool_depth`` - are None, it will be calculated. If None and any of the other three parameters - are not None, it will be set to ``MicrostructureInput.DEFAULT_COOLING_RATE``. - See :class:`MicrostructureInput `. - thermal_gradient : Optional[float] - The thermal gradient (K/m) to use for microstructure simulations. - If None, and ``cooling_rate``, ``melt_pool_width``, and ``melt_pool_depth`` - are None, it will be calculated. If None and any of the other three parameters - are not None, it will be set to ``MicrostructureInput.DEFAULT_THERMAL_GRADIENT``. - See :class:`MicrostructureInput `. - melt_pool_width : Optional[float] - The melt pool width (m) to use for microstructure simulations. - If None, and ``cooling_rate``, ``thermal_gradient``, and ``melt_pool_depth`` - are None, it will be calculated. If None and any of the other three parameters - are not None, it will be set to ``MicrostructureInput.DEFAULT_MELT_POOL_WIDTH``. - See :class:`MicrostructureInput `. - melt_pool_depth : Optional[float] - The melt pool depth (m) to use for microstructure simulations. - If None, and ``cooling_rate``, ``thermal_gradient``, and ``melt_pool_width`` - are None, it will be calculated. If None and any of the other three parameters - are not None, it will be set to ``MicrostructureInput.DEFAULT_MELT_POOL_DEPTH``. - See :class:`MicrostructureInput `. - random_seed : Optional[int] - The random seed to use for microstructure simulations. If None, - an automatically generated random seed will be used. - Valid values are between 1 and 2^31 - 1. - iteration : int, optional - The iteration number for this set of simulations. - - priority : int, optional - The priority for this set of simulations. + to use for microstructure simulations. The default is ``None``, in + which case ``MachineConstants.DEFAULT_LAYER_ROTATION_ANGLE`` is used. + For more information, see the + :class:`MachineConstants ` class. + hatch_spacings : list[float], None + Hatch spacings (m) to use for microstructure simulations. The default is + ``None``, in which case ``MachineConstants.DEFAULT_HATCH_SPACING`` is used. + For more information, see the + :class:`MachineConstants ` class. + stripe_widths : list[float], None + Stripe widths (m) to use for microstructure simulations. The default is + ``None``, in which case``MachineConstants.DEFAULT_SLICING_STRIPE_WIDTH`` is used. + For more information, see the :class:`MachineConstants ` + class. + min_energy_density : float, None + Minimum energy density (J/m^3) to use for microstructure simulations. Parameter combinations + with an area energy density below this value are not included. Area energy density is defined as + laser power / (layer thickness * scan speed * hatch spacing). + max_energy_density : float + Xaximum energy density (J/m^3) to use for microstructure simulations. Parameter combinations + with an area energy density above this value are not included. Energy density is defined as + laser power / (layer thickness * scan speed * hatch spacing). + min_build_rate : float, None + Minimum build rate (m^3/s) to use for microstructure simulations. Parameter combinations + with a build rate below this value are not included. Build rate is defined as + layer thickness * scan speed * hatch spacing. + max_build_rate : float, None + Maximum build rate (m^3/s) to use for microstructure simulations. Parameter combinations + with a build rate above this value are not included. Build rate is defined as + layer thickness * scan speed * hatch spacing. + cooling_rate : float, None + Cooling rate (K/s) to use for microstructure simulations. The default is ``None``, + in which case if the values are also ``None`` for the ``thermal_gradient``, + ``melt_pool_width``, and ``melt_pool_depth`` parameters, the cooling rate is + calculated. If the value for the ``cooling_rate`` parameter is ``None`` and any of + the other three parameters have a value other than ``None``, the cooling rate is set + to ``MicrostructureInput.DEFAULT_COOLING_RATE``. For more information, see the + :class:`MicrostructureInput ` class. + thermal_gradient : float, None + Thermal gradient (K/m) to use for microstructure simulations. The default is + ``None``, in which case if the values are also ``None`` for the ``cooling_rate``, + ``melt_pool_width``, and ``melt_pool_depth`` parameters, the thermal gradient is + calculated. If the value for the ``thermal_gradient`` parameter is ``None`` and any + of the other three parameters have a value other than ``None``, the thermal gradient + is set to ``MicrostructureInput.DEFAULT_THERMAL_GRADIENT``. For more information, + see the :class:`MicrostructureInput ` + class. + melt_pool_width : float, None + Melt pool width (m) to use for microstructure simulations. The default is + ``None``, in which case if the values are also ``None`` for the ``cooling_rate``, + ``thermal_gradient``, and ``melt_pool_depth`` parameters, the melt pool width + is calculated. If the value for the ``melt_pool_width`` parameter is ``None`` and + any of the other three parameters have a value other than ``None``, the melt pool + width is set to ``MicrostructureInput.DEFAULT_MELT_POOL_WIDTH``. For more information, + see the :class:`MicrostructureInput ` class. + melt_pool_depth : float, None + Melt pool depth (m) to use for microstructure simulations. The default is + ``None``, in which case if the values are also ``None`` for the ``cooling_rate``, + ``thermal_gradient``, and ``melt_pool_width`` parameters, melt pool depth is + calculated. If the value for the ``melt_pool_depth`` parameter is ``None`` and any + of the other three parameters have value other than ``None``, the melt pool depth + is set to ``MicrostructureInput.DEFAULT_MELT_POOL_DEPTH``. For more information, + see the :class:`MicrostructureInput ` + class. + random_seed : int, None + Random seed to use for microstructure simulations. The default is ``None``, + in which case a random seed is automatically generated. Valid values are between + 1 and 2^31 - 1. + iteration : int, optiDEFAULT_ITERATION + Iteration number for this set of simulations. + priority : int, DEFAULT_PRIORITY + Priority for this set of simulations. """ lt = ( layer_thicknesses @@ -948,12 +978,12 @@ def update( """Update the results of simulations in the parametric study. This method updates values for existing simulations in the parametric study. To add - completed simulations, use :meth:`add_summaries` instead. + completed simulations, use the :meth:`add_summaries` method instead. Parameters ---------- - summaries : List[Union[SingleBeadSummary, PorositySummary, MicrostructureSummary, SimulationError]] - The list of simulation summaries to use for updating the parametric study. + summaries : list[Union[SingleBeadSummary, PorositySummary, MicrostructureSummary, SimulationError]] + List of simulation summaries to use for updating the parametric study. """ for summary in summaries: if isinstance(summary, SingleBeadSummary): @@ -1040,14 +1070,14 @@ def add_inputs( Parameters ---------- - inputs : List[Union[SingleBeadInput, PorosityInput, MicrostructureInput]] - The list of simulation inputs to add to the parametric study. + inputs : list[Union[SingleBeadInput, PorosityInput, MicrostructureInput]] + List of simulation inputs to add to the parametric study. - iteration : int - The iteration number for the simulation inputs. + iteration : int, DEFAULT_ITERATION + Iteration number for the simulation inputs. - priority : int - The priority for the simulations. + priority : int, DEFAULT_PRIORITY + Priority for the simulations. """ for input in inputs: dict = {} @@ -1105,7 +1135,7 @@ def remove(self, ids: Union[str, List[str]]): Parameters ---------- ids : Union[str, List[str]] - Single or list of the ID field values for the rows to remove. + One or more ID field values for the rows to remove. """ if isinstance(ids, str): ids = [ids] @@ -1118,10 +1148,10 @@ def set_status(self, ids: Union[str, List[str]], status: SimulationStatus): Parameters ---------- index : Union[int, List[int]] - The ID or list of IDs of the simulations to update. + One or more IDs of the simulations to update. status : SimulationStatus - The status to use for the simulations. + Status for the simulations. """ if isinstance(ids, str): ids = [ids] @@ -1134,10 +1164,10 @@ def set_priority(self, ids: Union[str, List[str]], priority: int): Parameters ---------- index : Union[int, List[int]] - The ID or list of IDs of the simulations to update. + One or more IDs of the simulations to update. priority : int - The priority to use for the simulations. + Priority for the simulations. """ if isinstance(ids, str): ids = [ids] @@ -1150,10 +1180,10 @@ def set_iteration(self, ids: Union[str, List[str]], iteration: int): Parameters ---------- index : Union[int, List[int]] - The ID or list of IDs of the simulations to update. + One or more IDs of the simulations to update. iteration : int - The iteration to use for the simulations. + Iteration for the simulations. """ if isinstance(ids, str): ids = [ids] @@ -1166,15 +1196,15 @@ def _create_unique_id(self, prefix: Optional[str] = None, id: Optional[str] = No Parameters ---------- prefix : str - The prefix to use for the ID. + Prefix for the ID. id: str - The ID to use if it is unique. ``id`` will be used as a prefix if - it is not unique. + ID to use if it is unique. ``id`` is used as the prefix if + the ID is not unique. Returns ------- str - A unique ID. If ``id`` is unique, it will be returned. Otherwise, + Unique ID. If ``id`` is unique, it is returned. Otherwise, """ if id is not None and not self._data_frame[ColumnNames.ID].str.match(f"{id}").any(): diff --git a/src/ansys/additive/parametric_study/parametric_utils.py b/src/ansys/additive/parametric_study/parametric_utils.py index 484cfa4a6..8a155f2bd 100644 --- a/src/ansys/additive/parametric_study/parametric_utils.py +++ b/src/ansys/additive/parametric_study/parametric_utils.py @@ -17,14 +17,14 @@ def build_rate( Laser scan speed. layer_thickness : float Powder deposit layer thickness. - hatch_spacing : float, optional + hatch_spacing : float, None Distance between hatch scan lines. Returns ------- float - The volumetric build rate if hatch spacing is provided, - otherwise an area build rate. If input units are m/s, m, m, + Volumetric build rate is returned if hatch spacing is provided. + Otherwise, an area build rate is returned. If input units are m/s, m, or m, the output units are m^3/s or m^2/s. """ if hatch_spacing is None: @@ -41,7 +41,8 @@ def energy_density( """Calculate the energy density. This is an approximate value useful for comparison. The returned value is simply - the laser power divided by the build rate. See :meth:`build_rate`. + the laser power divided by the build rate. For more information, see the :meth:`build_rate` + method. Parameters ---------- @@ -51,14 +52,14 @@ def energy_density( Laser scan speed. layer_thickness : float Powder deposit layer thickness. - hatch_spacing : float, optional + hatch_spacing : float, None Distance between hatch scan lines. Returns ------- float - The volumetric energy density if hatch spacing is provided, - otherwise an area energy density. If input units are W, m/s, m, m, + Volumetric energy density is returned i hatch spacing is provided. + Otherwise an area energy density is returned. If input units are W, m/s, m, or m, the output units are J/m^3 or J/m^2. """ br = build_rate(scan_speed, layer_thickness, hatch_spacing) From 3aa130d1b8ba5ab5bfc552c52284dab140360ac4 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Fri, 1 Sep 2023 14:12:06 -0400 Subject: [PATCH 02/21] Edits to PyAdditive files --- examples/00_additive_single_bead.py | 67 +++++++++++++----------- examples/01_additive_porosity.py | 46 ++++++++++------- examples/02_additive_microstructure.py | 68 +++++++++++++----------- examples/03_additive_thermal_history.py | 69 +++++++++++++++---------- src/ansys/additive/material.py | 4 +- src/ansys/additive/microstructure.py | 6 +-- src/ansys/additive/porosity.py | 42 ++++++++------- src/ansys/additive/progress_logger.py | 2 + src/ansys/additive/server_utils.py | 9 ++-- src/ansys/additive/simulation.py | 6 +-- src/ansys/additive/single_bead.py | 46 ++++++++++------- src/ansys/additive/thermal_history.py | 39 ++++++++------ 12 files changed, 233 insertions(+), 171 deletions(-) diff --git a/examples/00_additive_single_bead.py b/examples/00_additive_single_bead.py index 5aedf8562..eeccba64f 100644 --- a/examples/00_additive_single_bead.py +++ b/examples/00_additive_single_bead.py @@ -1,16 +1,19 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Single Bead Analysis +Single bead analysis ==================== -This tutorial shows how you can use PyAdditive to determine -meltpool characteristics for given material and machine +This example shows how you can use PyAdditive to determine +melt pool characteristics for a given material and machine parameter combinations. Units are SI (m, kg, s, K) unless otherwise noted. - -First, connect to the Additive service. """ +############################################################################### +# Perform required imports and connect +# ----------------------------------- +# Perform the required imports and connect to the Additive service. + import matplotlib.pyplot as plt import ansys.additive as pyadditive @@ -19,23 +22,24 @@ additive = pyadditive.Additive() ############################################################################### -# Select Material +# Select material # --------------- -# The next step is a to choose a material. A list of available materials can -# be obtained using the +# Select a material. You can use the # :meth:`get_materials_list() ` -# command. +# method to obtain a list of available materials. print(additive.get_materials_list()) ############################################################################### -# Obtain the parameters for a single material by passing one of the names -# from the materials list to -# :meth:`get_material() `. +# You can obtain the parameters for a single material by passing a name +# from the materials list to the +# :meth:`get_material() ` +# method. + material = additive.get_material("17-4PH") ############################################################################### -# Set Machine Parameters +# Specify machine parameters # ---------------------- # Specify machine parameters by first creating an # :class:`AdditiveMachine ` object @@ -49,12 +53,15 @@ ############################################################################### # Set laser power and scan speed +# ------------------------------ +# Set the laser power and scan speed. + machine.scan_speed = 1 # m/s machine.laser_power = 300 # W ############################################################################### -# Specify Single Bead Simulation Inputs -# ------------------------------------- +# Specify inputs for single bead simulation +# ----------------------------------------- # Create a :class:`SingleBeadInput ` # object containing the desired simulation parameters. @@ -63,24 +70,23 @@ ) ############################################################################### -# Run Simulation +# Run simulation # -------------- # Use the :meth:`simulate() ` # method of the ``additive`` object to run the simulation. The returned object is a # :class:`SingleBeadSummary ` -# containing the input and a +# class containing the input and a # :class:`MeltPool ` object. summary = additive.simulate(input) ############################################################################### -# Plot Melt Pool Statistics +# Plot melt pool statistics # ------------------------- -# A :class:`Pandas DataFrame ` containing the melt pool -# statistics can be obtained using the -# :meth:`data_frame() ` property -# of the ``melt_pool`` attribute of the ``summary`` object. The -# :meth:`plot() ` method can be used to plot the melt +# Obtain a :class:`Pandas DataFrame ` containing the melt pool +# statistics by using the :meth:`data_frame() ` +# property of the ``melt_pool`` attribute of the ``summary`` object. Use the +# :meth:`plot() ` method to plot the melt # pool dimensions as a function of bead length. df = summary.melt_pool.data_frame().multiply(1e6) # convert from meters to microns @@ -102,19 +108,20 @@ ############################################################################### -# List Melt Pool Statistics +# List melt pool statistics # ------------------------- -# A table of the melt pool statistics can be shown by simply -# typing the name of the data frame object and pressing enter. -# Here we show only the first few rows using ``head()`` for brevity. -# NOTE: If running this example as a python script, no output will be shown. +# You can show a table of the melt pool statistics by typing the name of the +# data frame object and pressing enter. For brevity, the following code +# uses ``head()`` so that only the first few rows are shown. df.head() +# .. note:: +# If running this example as a Python script, no output is shown. ############################################################################### -# Save Melt Pool Statistics +# Save melt pool statistics # ------------------------- -# The melt pool statistics can be saved to a CSV file using the +# Save the melt pool statistics to a CSV file using the # :meth:`to_csv() ` method. df.to_csv("melt_pool.csv") diff --git a/examples/01_additive_porosity.py b/examples/01_additive_porosity.py index 63fc72ca6..bd0601be1 100644 --- a/examples/01_additive_porosity.py +++ b/examples/01_additive_porosity.py @@ -1,42 +1,47 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Porosity Analysis +Porosity analysis ================= -This tutorial shows how you can use PyAdditive to determine -porosity for given material and machine parameter combinations. +This example shows how you can use PyAdditive to determine +porosity for a given material and machine parameter combinations. Units are SI (m, kg, s, K) unless otherwise noted. - -First, connect to the Additive service. """ +############################################################################### +# Perform required import and connect +# ----------------------------------- +# Perform the required import and connect to the Additive service. + import ansys.additive as pyadditive additive = pyadditive.Additive() ############################################################################### -# Select Material +# Select material # --------------- -# The next step is a to choose a material. A list of available materials can -# be obtained using the +# Select a material. You can use the # :meth:`get_materials_list() ` -# command. +# method to obtain a list of available materials. print(additive.get_materials_list()) ############################################################################### -# Obtain the parameters for a single material by passing one of the names -# from the materials list to -# :meth:`get_material() `. +# You can obtain the parameters for a single material by passing a name +# from the materials list to the +# :meth:`get_material() ` +# method. + material = additive.get_material("316L") ############################################################################### -# Set Machine Parameters +# Specify machine parameters # ---------------------- # Specify machine parameters by first creating an # :class:`AdditiveMachine ` object -# then assigning the desired values. All values are in SI units (m, kg, s, K) -# unless otherwise noted. +# and then assigning the desired values. All values are in SI units +# (m, kg, s, K) unless otherwise noted. + machine = pyadditive.AdditiveMachine() # Show available parameters @@ -44,12 +49,15 @@ ############################################################################### # Set laser power and scan speed +# ------------------------------ +# Set the laser power and scan speed. + machine.scan_speed = 1.2 # m/s machine.laser_power = 250 # W ############################################################################### -# Specify Porosity Simulation Inputs -# ---------------------------------- +# Specify inputs for porosity simulation +# -------------------------------------- # Create a :class:`PorosityInput ` object # containing the desired simulation parameters. @@ -63,7 +71,7 @@ ) ############################################################################### -# Run Simulation +# Run simulation # -------------- # Use the :meth:`simulate() ` method # on the ``additive`` object to run the simulation. The returned object is a @@ -73,7 +81,7 @@ summary = additive.simulate(input) ############################################################################### -# Print Results +# Print results # ------------- print(f"For {summary.input.material.name} with \n", summary.input.machine) diff --git a/examples/02_additive_microstructure.py b/examples/02_additive_microstructure.py index 758b32216..16d741dc6 100644 --- a/examples/02_additive_microstructure.py +++ b/examples/02_additive_microstructure.py @@ -1,41 +1,45 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Microstructure Analysis +Microstructure analysis ####################### -This tutorial shows how you can use PyAdditive to determine +This example shows how you can use PyAdditive to determine the microstructure for a sample coupon with given material and machine parameters. Units are SI (m, kg, s, K) unless otherwise noted. - -First, connect to the Additive service. """ +############################################################################### +# Perform required import and connect +# ----------------------------------- +# Perform the required import and connect to the Additive service. + import ansys.additive as pyadditive additive = pyadditive.Additive() ############################################################################### -# Select Material +# Select material # --------------- -# The next step is a to choose a material. A list of available materials can -# be obtained using the +# Select a material. You can use the # :meth:`get_materials_list() ` -# command. +# method to obtain a list of available materials. print(additive.get_materials_list()) ############################################################################### -# Obtain the parameters for a single material by passing one of the names -# from the materials list to -# :meth:`get_material() `. +# You can obtain the parameters for a single material by passing a name +# from the materials list to the +# :meth:`get_material() ` +# method. + material = additive.get_material("17-4PH") ############################################################################### -# Set Machine Parameters -# ---------------------- +# Specify machine parameters +# -------------------------- # Specify machine parameters by first creating an ``AdditiveMachine`` object -# then assigning the desired values. All values are in SI units (m, kg, s, K) +# and then assigning the desired values. All values are in SI units (m, kg, s, K) # unless otherwise noted. machine = pyadditive.AdditiveMachine() @@ -45,19 +49,22 @@ ############################################################################### # Set laser power and scan speed +# ------------------------------ +# Set the laser power and scan speed. + machine.scan_speed = 1 # m/s machine.laser_power = 500 # W ############################################################################### -# Specify Microstructure Simulation Inputs -# ---------------------------------------- -# Microstructure simulation inputs can either include thermal parameters or not. +# Specify inputs for microstructure simulation +# --------------------------------------------- +# Microstructure simulation inputs can include thermal parameters. # Thermal parameters consist of ``cooling_rate``, ``thermal_gradient``, -# ``melt_pool_width`` and ``melt_pool_depth``. If thermal parameters are not -# specified, the thermal solver will be used to obtain the parameters prior +# ``melt_pool_width``, and ``melt_pool_depth``. If thermal parameters are not +# specified, the thermal solver is used to obtain the parameters prior # to running the microstructure solver. -# Specifying microstructure inputs with thermal parameters +# Specify microstructure inputs with thermal parameters input_with_thermal = pyadditive.MicrostructureInput( machine=machine, material=material, @@ -73,7 +80,7 @@ melt_pool_depth=1.1e-4, # meters (110 microns) ) -# Specifying microstructure inputs without thermal parameters +# Specify microstructure inputs without thermal parameters input_without_thermal = pyadditive.MicrostructureInput( machine=machine, material=material, @@ -86,20 +93,19 @@ ) ############################################################################### -# Run Simulation +# Run simulation # -------------- # Use the ``simulate`` method of the ``additive`` object to run the simulation. - summary = additive.simulate(input_with_thermal) ############################################################################### -# Plot Results +# Plot results # ------------ # The microstructure simulation results include three VTK files, one for each -# of the XY, XZ and YZ planes. Each of the files contains data sets for grain -# orientation, boundaries and number. In addition, the results include grain -# statistics. See :class:`MicrostructureSummary`. +# of the XY, XZ, and YZ planes. Each file contains data sets for grain +# orientation, boundaries, and number. In addition, the results include grain +# statistics. For more information, see the :class:`MicrostructureSummary` class. from matplotlib import colors from matplotlib.colors import LinearSegmentedColormap as colorMap @@ -111,8 +117,10 @@ from ansys.additive import CircleEquivalenceColumnNames ############################################################################### -# Plot Grain 2D Visualizations +# Plot grain 2D visualizations # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# Plot the planar data, read VTK data in data set objects, and create a color +# map to use with the boundary map. # Function to plot the planar data @@ -148,7 +156,7 @@ def plot_microstructure( xz = pv.read(summary.xz_vtk) yz = pv.read(summary.yz_vtk) -# Create colormap to use with boundary plot +# Create a color map to use with the boundary plot white_black_cmap = colorMap.from_list("whiteblack", ["white", "black"]) plot_microstructure(xy, xz, yz, "GrainBoundaries", white_black_cmap).show(title="Grain Boundaries") @@ -158,6 +166,8 @@ def plot_microstructure( ############################################################################### # Plot Grain Statistics # ^^^^^^^^^^^^^^^^^^^^^ +# Add grain statistic plots to a figure, create a figure for grain statistics, +# and then plot the figure. # Function to simplify plotting grain statistics diff --git a/examples/03_additive_thermal_history.py b/examples/03_additive_thermal_history.py index 38d206b05..1cf9eaf65 100644 --- a/examples/03_additive_thermal_history.py +++ b/examples/03_additive_thermal_history.py @@ -1,63 +1,73 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Thermal History Analysis +Thermal history analysis ======================== -This tutorial shows how you can use PyAdditive to determine +This example shows how you can use PyAdditive to determine thermal history during a build using a simulated coaxial average sensor. Units are SI (m, kg, s, K) unless otherwise noted. - -First, connect to the Additive service. """ +############################################################################### +# Perform required import and connect +# ----------------------------------- +# Perform the required import and connect to the Additive service. + import ansys.additive as pyadditive additive = pyadditive.Additive() ############################################################################### -# Model Selection -# --------------- -# The next step is a to specify a geometry model. Currently, PyAdditive supports -# two types of geometry specifications, STL files and build files. A build file -# in this context is a zip archive containing an STL file describing the -# geometry, a machine instruction file and zero or more STL files describing -# support structures. For details of the build file see . +# Select model +# ------------ +# Select the geometry model. Currently, PyAdditive supports +# two types of geometry specifications, STL files and build files. In +# this context, a build file is a ZIP archive that contains an STL file describing the +# geometry, a machine instruction file, and zero or more STL files describing +# support structures. For more information on build files, see . # -# Example build and STL files can be downloaded by importing the examples -# module as shown below. +# You can download example build and STL files by importing the ``examples`` +# module. import ansys.additive.examples as examples -# Creating an ``StlFile`` object -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create ``StlFile`` object +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create an ``StlFile`` object. stl_name = examples.download_10mm_cube() stl_file = pyadditive.StlFile(stl_name) -# Creating a ``BuildFile`` object -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create ``BuildFile`` object +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a ``BuildFile`` object. build_file_name = examples.download_small_wedge_slm_build_file() build_file = pyadditive.BuildFile(pyadditive.MachineType.SLM, build_file_name) ############################################################################### -# Select Material +# Select material # --------------- -# The next step is a to choose a material. A list of available materials can -# be obtained using the ``get_materials_list`` command. +# Select a material. You can use the +# :meth:`get_materials_list() ` +# method to obtain a list of available materials. print(additive.get_materials_list()) ############################################################################### -# Obtain the parameters for a single material using one of the names from the list. +# You can obtain the parameters for a single material by passing a name +# from the materials list to the +# :meth:`get_material() ` +# method. + material = additive.get_material("17-4PH") ############################################################################### -# Set Machine Parameters +# Specify machine parameters # ---------------------- # Specify machine parameters by first creating an ``AdditiveMachine`` object -# then assigning the desired values. All values are in SI units (m, kg, s, K) +# and then assigning the desired values. All values are in SI units (m, kg, s, K) # unless otherwise noted. machine = pyadditive.AdditiveMachine() @@ -67,12 +77,15 @@ ############################################################################### # Set laser power and scan speed +# ------------------------------ +# Set the laser power and scan speed. + machine.scan_speed = 1 # m/s machine.laser_power = 500 # W ############################################################################### -# Specify Thermal History Simulation Inputs -# ----------------------------------------- +# Specify inputs for thermal history simulation +# --------------------------------------------- # Create a ``ThermalHistoryInput`` object containing the desired simulation # parameters. The ``ThermalHistoryInput`` object contains ``CoaxialAverageSensorInputs``. # ``CoaxialAverageSensorInputs`` consist of a sensor radius and one or more ``Range`` @@ -93,16 +106,16 @@ ) ############################################################################### -# Run Simulation +# Run simulation # -------------- # Use the ``simulate`` method of the ``additive`` object to run the simulation. summary = additive.simulate(input) ############################################################################### -# Plot Thermal History +# Plot thermal history # -------------------- -# You can plot the thermal history using pyvista as shown below. +# Plot the thermal history using PyVista. import glob import os diff --git a/src/ansys/additive/material.py b/src/ansys/additive/material.py index 172e0960e..43ce75860 100644 --- a/src/ansys/additive/material.py +++ b/src/ansys/additive/material.py @@ -21,7 +21,7 @@ class CharacteristicWidthDataPoint: power to be correlated to a characteristic melt pool width. This class represents a single row in the lookup table. - Units are SI (m, kg, s, and K) unless otherwise noted. + Units are SI (m, kg, s, K) unless otherwise noted. """ def __init__( @@ -115,7 +115,7 @@ class ThermalPropertiesDataPoint: temperatures. This class represents a single row in the lookup table. - Units are SI (m, kg, s, and K) unless otherwise noted. + Units are SI (m, kg, s, K) unless otherwise noted. """ def __init__( diff --git a/src/ansys/additive/microstructure.py b/src/ansys/additive/microstructure.py index 96829aed8..627527371 100644 --- a/src/ansys/additive/microstructure.py +++ b/src/ansys/additive/microstructure.py @@ -18,7 +18,7 @@ class MicrostructureInput: """Provides input parameters for microstructure simulation. - Units are SI (m, kg, s, and K) unless otherwise noted. + Units are SI (m, kg, s, K) unless otherwise noted. """ #: Default minimum x, y, z, position coordinate (m). @@ -448,8 +448,8 @@ class CircleEquivalenceColumnNames: class MicrostructureSummary: """Provides the summary of a microstructure simulation. - Units are typically SI (m, kg, s, and K). However, some of the - following values do not use SI units. For more information, see the + Units are typically SI (m, kg, s, K). However, some of the following + values do not use SI units. For more information, see the descriptions. """ diff --git a/src/ansys/additive/porosity.py b/src/ansys/additive/porosity.py index 343ee6ea6..f5064706c 100644 --- a/src/ansys/additive/porosity.py +++ b/src/ansys/additive/porosity.py @@ -8,22 +8,25 @@ class PorosityInput: - """Input parameters for porosity simulation. + """Provides input parameters for porosity simulation. Parameters ---------- id: string - User provided identifier for this simulation. - size_x: float - Size of simulated sample in x dimension (m), valid values: 0.001 to 0.01. - size_y: float - Size of simulated sample in y dimension (m), valid values: 0.001 to 0.01. - size_z: float - Size of simulated sample in z dimension (m), valid values: 0.001 to 0.01. + User-provided ID for the simulation. + size_x: float, DEFAULT_SAMPLE_SIZE + Size of the simulated sample in the x dimension (m). Valid values are from + 0.001 to 0.01. + size_y: float, DEFAULT_SAMPLE_SIZE + Size of the simulated sample in the y dimension (m). Valid values from 0.001 + to 0.01. + size_z: float, DEFAULT_SAMPLE_SIZE + Size of the simulated sample in the z dimension (m). Valid values are from + 0.001 to 0.01. machine: AdditiveMachine - Machine related parameters. + Machine-related parameters. material: AdditiveMaterial - Material used during simulation. + Material used during the simulation. """ #: Default sample size (m) in each dimension. @@ -75,7 +78,7 @@ def __validate_range(self, value, min, max, name): @property def id(self): - """User provided identifier for this simulation.""" + """User-provided ID for the simulation.""" return self._id @id.setter @@ -84,7 +87,7 @@ def id(self, value): @property def machine(self): - """Machine related parameters.""" + """Machine-related parameters.""" return self._machine @machine.setter @@ -93,7 +96,7 @@ def machine(self, value): @property def material(self): - """Material used during simulation.""" + """Material used during the simulation.""" return self._material @material.setter @@ -102,7 +105,7 @@ def material(self, value): @property def size_x(self): - """Size of simulated sample in x dimension (m). + """Size (m) of the simulated sample in the x dimension. Valid values are from 1e-3 to 1e-2 m (1 to 10 mm). """ @@ -115,7 +118,7 @@ def size_x(self, value): @property def size_y(self): - """Size of simulated sample in y dimension (m). + """Size (m) of the simulated sample in the y dimension. Valid values are from 1e-3 to 1e-2 m (1 to 10 mm). """ @@ -128,7 +131,7 @@ def size_y(self, value): @property def size_z(self): - """Size of simulated sample in z dimension (m). + """Size (m) of the simulated sample in the z dimension. Valid values are from 1e-3 to 1e-2 m (1 to 10 mm). """ @@ -152,7 +155,7 @@ def _to_simulation_request(self) -> SimulationRequest: class PorositySummary: - """Summary of a porosity simulation. + """Provides a summary of a porosity simulation. Units are SI unless otherwise noted. """ @@ -171,7 +174,10 @@ def __init__( @property def input(self) -> PorosityInput: - """Simulation input, see :class:`PorosityInput`.""" + """Simulation input. + + For more information, see the :class:`PorosityInput` class. + """ return self._input @property diff --git a/src/ansys/additive/progress_logger.py b/src/ansys/additive/progress_logger.py index 215ff7ec9..641b79d71 100644 --- a/src/ansys/additive/progress_logger.py +++ b/src/ansys/additive/progress_logger.py @@ -7,6 +7,8 @@ class ProgressLogger: + """Provides for progress logging.""" + def __init__(self, name: str = None) -> None: self._log = logging.getLogger(name) self._last_percent_complete = 0 diff --git a/src/ansys/additive/server_utils.py b/src/ansys/additive/server_utils.py index 3b08b1c0e..94c23bf70 100644 --- a/src/ansys/additive/server_utils.py +++ b/src/ansys/additive/server_utils.py @@ -17,13 +17,13 @@ def launch_server(port: int, cwd: str = USER_DATA_PATH) -> subprocess.Popen: ---------- port: int Port number to use for gRPC connections. - cwd: str + cwd: str, USER_DATA_PATH Current working directory to use for the server process. Returns ------- process: subprocess.Popen - Server process. To stop the server, call ``kill()`` on the returned object. + Server process. To stop the server, call the ``kill()`` function on the returned object. """ ver = DEFAULT_ANSYS_VERSION server_exe = "" @@ -77,7 +77,10 @@ def find_open_port() -> int: Returns ------- port: int - Open port number. *Note:* this port may be taken by the time you try to use it. + Open port number. + + .. note:: + This port may be taken by the time you try to use it. """ import socket diff --git a/src/ansys/additive/simulation.py b/src/ansys/additive/simulation.py index bc47ffe06..52605e18c 100644 --- a/src/ansys/additive/simulation.py +++ b/src/ansys/additive/simulation.py @@ -8,7 +8,7 @@ class SimulationType: - """Simulation types.""" + """Provides simulation types.""" #: Single bead simulation. SINGLE_BEAD = "SingleBead" @@ -32,7 +32,7 @@ class SimulationStatus: class SimulationError: - """Container for simulation errors.""" + """Provides simulation errors.""" def __init__( self, @@ -51,5 +51,5 @@ def input( @property def message(self) -> str: - """Simulation error message.""" + """Provides simulation error message.""" return self._message diff --git a/src/ansys/additive/single_bead.py b/src/ansys/additive/single_bead.py index 5fd67133a..d7d1564e8 100644 --- a/src/ansys/additive/single_bead.py +++ b/src/ansys/additive/single_bead.py @@ -9,7 +9,7 @@ class SingleBeadInput: - """Input parameters for single bead simulation.""" + """Provides input parameters for single bead simulation.""" #: Default bead length (m). DEFAULT_BEAD_LENGTH = 3e-3 @@ -53,7 +53,7 @@ def __validate_range(self, value, min, max, name): @property def id(self): - """User provided identifier for this simulation.""" + """User-provided ID for the simulation.""" return self._id @id.setter @@ -62,7 +62,7 @@ def id(self, value): @property def machine(self): - """Machine related parameters.""" + """Machine-related parameters.""" return self._machine @machine.setter @@ -80,7 +80,7 @@ def material(self, value): @property def bead_length(self): - """Length of bead to simulate (m). + """Length (m) of bead to simulate. Valid values are from 1e-3 to 1e-2 m (1 to 10 mm). """ @@ -102,7 +102,7 @@ def _to_simulation_request(self) -> SimulationRequest: class MeltPoolColumnNames: - """Column names for melt pool data frame.""" + """Provides column names for the melt pool data frame.""" #: Width of melt pool (m). WIDTH = "width" @@ -117,7 +117,8 @@ class MeltPoolColumnNames: class MeltPool: - """Container for the melt pool evolution during a single bead simulation. + """Provides the container for the melt pool evolution during a single bead + simulation. Units are SI unless otherwise noted. """ @@ -142,24 +143,23 @@ def __init__(self, msg: MeltPoolMessage): self._df.index.name = "bead_length" def data_frame(self) -> DataFrame: - """Return :class:`Pandas DataFrame ` containing melt - pool data. + """Get the data frame containing the melt pool data. Values are in meters. Indices: - - bead_length: Length of bead at each time step. + - ``bead_length``: Length of the bead at each time step. Columns: - - ``MeltPoolColumnNames.LENGTH``: length of melt pool at each time step. - - ``MeltPoolColumnNames.WIDTH``: width of melt pool at each time step. - - ``MeltPoolColumnNames.DEPTH``: depth of melt pool at each time step. - - ``MeltPoolColumnNames.REFERENCE_WIDTH``: reference width of melt pool at each time step. - Reference width is the melt pool width at the bottom of the powder layer, - or, the width at the top of the substrate. - - ``MeltPoolColumnNames.REFERENCE_DEPTH``: reference depth of melt pool at each time step. + - ``MeltPoolColumnNames.LENGTH``: Length of the melt pool at each time step. + - ``MeltPoolColumnNames.WIDTH``: Width of the melt pool at each time step. + - ``MeltPoolColumnNames.DEPTH``: Depth of the melt pool at each time step. + - ``MeltPoolColumnNames.REFERENCE_WIDTH``: Reference width of the melt pool at each time step. + Reference width is the melt pool width at the bottom of the powder layer + or the width at the top of the substrate. + - ``MeltPoolColumnNames.REFERENCE_DEPTH``: Reference depth of the melt pool at each time step. Reference depth is the depth of the entire melt pool minus the powder - layer thickness, or, the depth of penetration into the substrate. + layer thickness or the depth of penetration into the substrate. """ return self._df.copy() @@ -175,7 +175,7 @@ def __repr__(self): class SingleBeadSummary: - """Summary of a single bead simulation.""" + """Provides a summary of a single bead simulation.""" def __init__( self, @@ -191,12 +191,18 @@ def __init__( @property def input(self) -> SingleBeadInput: - """Simulation input, see :class:`SingleBeadInput`.""" + """Simulation input. + + For more information, see the :class:`SingleBeadInput` class. + """ return self._input @property def melt_pool(self) -> MeltPool: - """Resulting melt pool, see :class:`MeltPool`.""" + """Resulting melt pool. + + For more information, see the :class:`MeltPool` class. + """ return self._melt_pool def __repr__(self): diff --git a/src/ansys/additive/thermal_history.py b/src/ansys/additive/thermal_history.py index 2ebcef475..b31b279be 100644 --- a/src/ansys/additive/thermal_history.py +++ b/src/ansys/additive/thermal_history.py @@ -54,14 +54,14 @@ def _to_range_message(self) -> RangeMessage: class CoaxialAverageSensorInputs: - """Coaxial average sensor descriptions. - - radius: float (meters) - Radius for circular field of view of sensor. Validated values - are 5e-5 to 1.5e-2 (0.05 - 15 mm). - z_heights: Range[] (meters) - Array of ranges along the z axis of the geometry. The simulated sensor will - follow the scan path for each deposit layer within each range. + """Provides descriptions for coaxial average sensors. + + radius: float + Radius in meters for the circular field of the view of sensor. Valid values + are from 5e-5 to 1.5e-2 m (0.05 - 15 mm). + z_heights: Range[] + Array of ranges in meters along the z axis of the geometry. The simulated + sensor follows the scan path for each deposit layer within each range. """ def __init__(self, **kwargs): @@ -99,17 +99,17 @@ def _to_coaxial_average_sensor_inputs_message(self) -> CoaxialAverageSensorInput class ThermalHistoryInput: - """Input parameters for microstructure simulation. + """Provides input parameters for microstructure simulation. id: string - Simulation identifier. + Simulation ID. machine: AdditiveMachine - Machine related parameters. + Machine-related parameters. material: AdditiveMaterial Material used during simulation. geometry: StlFile or BuildFile - Geometry to use in simulation. - coax_ave_sensor_inputs: CoaxialAverageSensorInputs + Geometry to use in the simulation. + coax_ave_sensor_inputs: :class:`CoaxialAverageSensorInputs` Coaxial average sensor definition. """ @@ -147,7 +147,11 @@ def __eq__(self, other: object) -> bool: @property def geometry(self): - """Part geometry, either :class:`StlFile` or :class:`BuildFile`.""" + """Part geometry. + + For more information, see the :class:`StlFile` + class or the :class:`BuildFile` class. + """ return self._geometry @geometry.setter @@ -194,10 +198,13 @@ def __init__(self, input: ThermalHistoryInput, coax_ave_output_folder: str): @property def input(self): - """Simulation input, :class:`ThermalHistoryInput`.""" + """Simulation input. + + For more information, see the :class:`ThermalHistoryInput` class. + """ return self._input @property def coax_ave_output_folder(self): - """Path to folder containing coaxial average sensor results.""" + """Path to the folder containing the coaxial average sensor results.""" return self._coax_ave_output_folder From f2188b35af2c4f0955e40331c4014c2b07ac5811 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Fri, 1 Sep 2023 14:12:21 -0400 Subject: [PATCH 03/21] Edits to PyAdditive files --- examples/04_additive_doe.py | 42 +++++---- examples/05_advanced_optimization_workflow.py | 93 ++++++++++--------- .../06_advanced_custom_material_tuning.py | 47 ++++++---- examples/07_using_a_custom_material.py | 40 +++++--- src/ansys/additive/additive.py | 6 +- 5 files changed, 127 insertions(+), 101 deletions(-) diff --git a/examples/04_additive_doe.py b/examples/04_additive_doe.py index 5d4a2df80..1b14533c5 100644 --- a/examples/04_additive_doe.py +++ b/examples/04_additive_doe.py @@ -1,16 +1,19 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Design Of Experiments +Design of experiments ===================== -This tutorial shows how you can use PyAdditive to run a design of experiments (DOE). -For this DOE we will vary laser power and scan speed over multiple single bead -simulations and plot the results. +This example shows how you can use PyAdditive to run a design of experiments (DOE). +For this DOE, laser power and scan speed are varied over multiple single bead +simulations and results are plotted. Units are SI (m, kg, s, K) unless otherwise noted. - -First, connect to the Additive service. """ +############################################################################### +# Perform required import and connect +# ----------------------------------- +# Perform the required import and connect to the Additive service. + # from matplotlib.colors import LinearSegmentedColormap as colorMap # import matplotlib.pyplot as plt # import numpy as np @@ -20,9 +23,9 @@ # additive = pyadditive.Additive() ############################################################################### -# Specify Parameters -# --------------------------------- -# Here we create a list of ``SingleBeadInput`` objects with various laser power +# Specify parameters +# ------------------- +# Create a list of ``SingleBeadInput`` objects with various laser power # and scan speed combinations. # bead_length = 0.001 @@ -47,16 +50,17 @@ # ) # ############################################################################### -# # Run Simulations -# # --------------- -# # The ``simulate`` method returns a list of summaries. In this case they are of -# # type :class:`SingleBeadSummary`. +# Run simulation +# -------------- +# Use the ``simulate`` method of the ``additive`` object to run the simulation. +# The list of summaries returned here are of the :class:`SingleBeadSummary` type. # summaries = additive.simulate(inputs) ############################################################################### -# Plot Individual Meltpool Statistics -# ----------------------------------- +# Plot melt pool statistics +# ------------------------- +# Plot the indidivual melt pool statistics. # import plotly.graph_objects as go # summaries.sort(key=lambda s: (s.input.machine.laser_power, s.input.machine.scan_speed)) @@ -128,10 +132,10 @@ # ############################################################################### -# # Plot Meltpool Average Depth Over Width Verses Laser Power And Scan Speed -# # ------------------------------------------------------------------------ -# # Here we create a "watermelon" plot to visualize the optimal laser power -# # and scan speed combinations. +# Plot melt pool average depth over width verses laser power and scan speed +# ------------------------------------------------------------------------- +# Create a "watermelon" plot to visualize the optimal laser power +# and scan speed combinations. # # Gather plot values # powers = [] diff --git a/examples/05_advanced_optimization_workflow.py b/examples/05_advanced_optimization_workflow.py index 8759ca984..c4aad7bde 100644 --- a/examples/05_advanced_optimization_workflow.py +++ b/examples/05_advanced_optimization_workflow.py @@ -1,15 +1,19 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Optimization Workflow Analysis +Optimization workflow analysis ============================== -This tutorial shows how you can use PyAdditive to perform machine +This example shows how you can use PyAdditive to perform machine parameter optimization. Units are SI (m, kg, s, K) unless otherwise noted. - -First, connect to the Additive service. """ + +############################################################################### +# Perform required imports and connect +# ----------------------------------- +# Perform the required imports and connect to the Additive service. + # from matplotlib import colors # from matplotlib.colors import LinearSegmentedColormap as colorMap # import matplotlib.pyplot as plt @@ -22,10 +26,10 @@ # additive = pyadditive.Additive() # ############################################################################### -# # Perform A Single Bead Evaluation -# # --------------------------------- -# # Here we simulate multiple single beads using various laser power -# # and scan speed combinations. +# Perform a single bead evaluation +# -------------------------------- +# Simulate multiple single beads using various laser power +# and scan speed combinations. # # Select a material to use for the evaluation # material = additive.get_material("17-4PH") @@ -38,7 +42,7 @@ # bead_length = 0.001 # # Create a list of machines, one per power and scan speed combination. -# # We use a comprehension to create the list. +# # A comprehension is used here to create the list. # machines = [ # pyadditive.AdditiveMachine(laser_power=p, scan_speed=s) # for p in initial_powers @@ -57,17 +61,18 @@ # ############################################################################### -# # Run The Simulations -# # ^^^^^^^^^^^^^^^^^^^ -# # The ``simulate`` method returns a list of summaries. In this case they are of -# # type :class:`SingleBeadSummary`. +# Run simulation +# -------------- +# # Use the ``simulate`` method of the ``additive`` object to run the simulation. +# The list of summaries returned here are of the :class:`SingleBeadSummary` type. # sb_summaries = additive.simulate(inputs) ############################################################################### -# Plot Individual Meltpool Statistics -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# Plot melt pool statistics +# ------------------------- +# Plot the indidivual melt pool statistics. # sb_summaries.sort(key=lambda s: (s.input.machine.laser_power, s.input.machine.scan_speed)) # nrows = len(initial_powers) @@ -95,12 +100,13 @@ # axs[r][c].set_title(title) # ############################################################################### -# # Plot Meltpool Average Depth Over Width Verses Laser Power And Scan Speed -# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -# # Here we create a "watermelon" plot to visualize the desired range for laser -# # power and scan speed. The criteria used is the melt pool average depth over -# # width. The acceptable range is defined by ``dwMin`` and ``dwMax`` below. The -# # combinations that fall in this range will be used in the porosity evaluation. +# Plot melt pool average depth over width verses laser power and scan speed +# ------------------------------------------------------------------------- +# Create a "watermelon" plot to visualize the desired range for laser +# power and scan speed. The criteria used is the melt pool average depth over +# width. The acceptable range is defined by ``dwMin`` and ``dwMax`` in the +# following code. The combinations that fall in this range are used in the +# porosity evaluation. # # Gather plot values # powers = [] @@ -146,15 +152,15 @@ # ax.set_ylabel(f"Laser Power (W)") # ############################################################################### -# # Perform A Porosity Evaluation -# # ----------------------------- -# # Here we filter the results from the single bead simulations and combine them -# # with various hatch spacing values to run porosity simulations. The filter -# # criteria used is a range of average meltpool depth over width values. This range -# # is defined by ``dwMin`` and ``dwMax`` above. - -# # Determine laser power and scan speed combinations of interest -# # We narrow the range from what was used earlier only to reduce simulation time +# Perform a porosity evaluation +# ----------------------------- +# Filter the results from the single bead simulations and combine them +# with various hatch spacing values to run porosity simulations. The filter +# criteria used is a range of average melt pool depth over width values. This range +# is defined by ``dwMin`` and ``dwMax`` in the preceding code. + +# # Determine laser power and scan speed combinations of interest. +# # Narrow the range from what was used earlier only to reduce simulation time # dwMin = 0.45 # dwMax = 0.55 # ps_of_interest = [] @@ -172,7 +178,7 @@ # for h in hatch_spacings # ] -# # Create a list of PorosityInputs, one per machine +# # Create a list of porosity inputs, one per machine # inputs = [] # for count, machine in enumerate(machines): # inputs.append( @@ -185,16 +191,15 @@ # size_z=0.001, # ) # ) - # # Run the simulations # porosity_summaries = additive.simulate(inputs) # ############################################################################### -# # Perform A Microstructure Evaluation -# # ----------------------------------- -# # Here we filter the results of the porosity simulations based upon the solid -# # ratio value. For results above this value we run microstructure simulations -# # to determine if the resulting build has the desired grain properties. +# Perform a microstructure evaluation +# ----------------------------------- +# Filter the results of the porosity simulations based upon the solid +# ratio value. For results above this value, run microstructure simulations +# to determine if the resulting build has the desired grain properties. # # Specify the minimum acceptable solid ratio # min_solid_ratio = 0.99 @@ -228,10 +233,10 @@ # micro_summaries = additive.simulate(inputs) # ############################################################################### -# # Plot Grain 2D Visualtions -# # ^^^^^^^^^^^^^^^^^^^^^^^^^ -# # For the plots that follow, we use only the first microstructure summary. -# # Plotting the remaining summaries is similar. +# Plot grain 2D visualtions +# ^^^^^^^^^^^^^^^^^^^^^^^^^ +# The following code uses only the first microstructure summary for plots. +# Plotting the remaining summaries is similar. # # Function to plot the planar data # def plot_microstructure( @@ -269,7 +274,7 @@ # xz = pv.read(summary.xz_vtk) # yz = pv.read(summary.yz_vtk) -# # Create colormap to use with boundary plot +# # Create color map to use with boundary plot # white_black_cmap = colorMap.from_list("whiteblack", ["white", "black"]) # plot_microstructure(xy, xz, yz, "GrainBoundaries", white_black_cmap).show(title="Grain Boundaries") @@ -277,8 +282,8 @@ # plot_microstructure(xy, xz, yz, "GrainNumber", None).show(title="Grain Number") # ############################################################################### -# # Plot Grain Statistics -# # ^^^^^^^^^^^^^^^^^^^^^ +# Plot grain statistics +# ^^^^^^^^^^^^^^^^^^^^^ # # Function to simplify plotting grain statistics # def add_grain_statistics_to_figure( diff --git a/examples/06_advanced_custom_material_tuning.py b/examples/06_advanced_custom_material_tuning.py index fa018fe91..a90ed3b0d 100644 --- a/examples/06_advanced_custom_material_tuning.py +++ b/examples/06_advanced_custom_material_tuning.py @@ -1,43 +1,50 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Custom Material Tuning +Custom material tuning ====================== -This tutorial shows how you can tune a custom material for use with PyAdditive. -Background information and file formats can be found in `the Additive documentation -`_. -To prevent wasted time, the steps described in the Additive documentation should be -reviewed carefully before executing the tuning process below. +This example shows how you can tune a custom material for use with PyAdditive. +For background information and file formats, see +`Material Tuning Tool (Beta) to Create User Defined Materials +`_ +in the *Additive Manufacturing Beta Features* documentation. +To prevent wasted time, before executing this example, carefully review +the steps described in this PyAdditive documentation. Units are SI (m, kg, s, K) unless otherwise noted. - """ +############################################################################### +# Perform required import and connect +# ----------------------------------- +# Perform the required import and connect to the Additive service. + import ansys.additive as pyadditive additive = pyadditive.Additive() ############################################################################### -# Specify the Tuning Inputs -# ------------------------- +# Specify tuning inputs +# --------------------- # The ``MaterialTuningInput`` object contains the paths to the files needed to # tune a material. The ``experiment_data_file`` is a CSV file containing the # results of single bead experiments. The ``material_parameters_file`` is a JSON # file containing the material parameters. The ``thermal_properties_lookup_file`` -# is a CSV file containing the temperature dependent properties of the material. +# is a CSV file containing the temperature-dependent properties of the material. # The ``characteristic_width_lookup_file`` is an optional CSV file containing # the melt pool characteristic width at various laser powers and scan speeds. -# If the characteristic width lookup file is not specified, it will be generated +# If the characteristic width lookup file is not specified, it is generated # during the tuning process. # -# Example input files can be downloaded as shown below. +# Download example input files. import ansys.additive.examples as examples input_files = examples.download_material_tuning_input() -# Below we include the characteristic width lookup file in order to reduce +# This code includes the characteristic width lookup file to reduce # processing time. If a characteristic width lookup file is not available, # the field can be omitted when creating the ``MaterialTuningInput`` object. + input = pyadditive.MaterialTuningInput( id="custom-material-tuning", experiment_data_file=input_files.experiment_data_file, @@ -50,18 +57,18 @@ ) ############################################################################### -# Perform the Material Tuning -# --------------------------- -# Material tuning is performed using the ``tune_material`` method. +# Perform material tuning +# ------------------------ +# Use the ``tune_material`` method to perform material tuning. summary = additive.tune_material(input) ############################################################################### -# Review the Results -# ------------------ +# Review results +# -------------- # The ``MaterialTuningSummary`` object contains the results of the material # tuning process. These results are used in follow-on steps to calculate the -# material parameters needed by PyAdditive. See the Additive documentation -# referred to above for details. +# material parameters needed by PyAdditive. For more information, see the +# Additive documentation referred to earlier. print(summary) diff --git a/examples/07_using_a_custom_material.py b/examples/07_using_a_custom_material.py index 0db8b5f25..05b88277b 100644 --- a/examples/07_using_a_custom_material.py +++ b/examples/07_using_a_custom_material.py @@ -1,43 +1,53 @@ # (c) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. """ -Using A Custom Material +Using a custom material ======================= -This tutorial shows how you can use a custom material in PyAdditive simulations. -Background information and file formats can be found in `the Additive documentation -`_. +This example shows how you can use a custom material in PyAdditive simulations. +For background information and file formats, see +`Material Tuning Tool (Beta) to Create User Defined Materials +`_ +in the *Additive Manufacturing Beta Features* documentation. +To prevent wasted time, before executing this example, carefully review +the steps described in this PyAdditive documentation. Units are SI (m, kg, s, K) unless otherwise noted. - """ +############################################################################### +# Perform required import and connect +# ----------------------------------- +# Perform the required import and connect to the Additive service. + import ansys.additive as pyadditive additive = pyadditive.Additive() ############################################################################### -# Example Custom Material -# ----------------------- -# Here we download an example custom material. Typically a user would have the -# files defining their custom material stored locally. +# Download custom material +# ------------------------ +# Download an example of a custom material. Typically, you would have the +# files defining your custom material stored locally. + import ansys.additive.examples as examples material_files = examples.download_custom_material() ############################################################################### -# Load the Custom Material Files -# ------------------------------ -# The ``load_material`` method on the ``additive`` object loads the files defining a custom material. +# Load custom material files +# -------------------------- +# Use the ``load_material`` method on the ``additive`` object to load the files +# defining a custom material. + custom_material = additive.load_material( parameters_file=material_files.material_parameters_file, thermal_lookup_file=material_files.thermal_properties_lookup_file, characteristic_width_lookup_file=material_files.characteristic_width_lookup_file, ) - ############################################################################### -# Use the Custom Material in a Simulation +# Use the custom material in a simulation # --------------------------------------- -# Once the custom material has been loaded, it can be assigned to a simulation input +# Once the custom material has been loaded, you can assign it to a simulation input # object. input = pyadditive.SingleBeadInput( diff --git a/src/ansys/additive/additive.py b/src/ansys/additive/additive.py index 435893f6f..90475c1ed 100644 --- a/src/ansys/additive/additive.py +++ b/src/ansys/additive/additive.py @@ -335,18 +335,18 @@ def load_material( parameters_file: str Name of the JSON file containing material parameters. For more information, see `Create Material Parameters File (.json) - `_ + `_ in the *Additiivate Manufacturing Beta Features* documentation. thermal_lookup_file: str Name of the CSV file containing the lookup table for thermal dependent properties. For more information, see `Create Material Lookup File (.csv) - `_ + `_ in the *Additiivate Manufacturing Beta Features* documentation. characteristic_width_lookup_file: str Name of the CSV file containing the lookup table for characteristic melt pool width. For more information, see `Find Characteristic Width Values and Generate Characteristic Width File (.csv) - `_ + `_ in the *Additiivate Manufacturing Beta Features* documentation. """ material = AdditiveMaterial() From 8869997c4ffc79f1391baf6f2c1a3978bda2c759 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Fri, 1 Sep 2023 14:25:08 -0400 Subject: [PATCH 04/21] Minor edit --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index c07e957d7..d33e4356c 100644 --- a/README.rst +++ b/README.rst @@ -48,7 +48,7 @@ is made public, you must use a private PyPI repository. For more information, se pip install ansys-additive --index-url=https://${PYANSYS_PYPI_PRIVATE_PAT}@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/ -To install the latest development version, use these commands: +To install the latest development version, run these commands: .. code:: bash @@ -76,7 +76,7 @@ This code shows how to import PyAdditive and use some basic capabilities: summary = additive.simulate(input) -For more detailed usage information, see `Examples`_ in the `PyAdditive Documentation`_. +For comprehensive usage information, see `Examples`_ in the `PyAdditive Documentation`_. Documentation and issues ======================== From dd9a9624d97d33f397fc2ae202f5d68214cfee4c Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Fri, 1 Sep 2023 14:46:52 -0400 Subject: [PATCH 05/21] Fix the ONE error message string that I did edit. --- tests/test_additive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_additive.py b/tests/test_additive.py index 8d65fb548..4b0249cda 100644 --- a/tests/test_additive.py +++ b/tests/test_additive.py @@ -174,7 +174,7 @@ def test_simulate_list_of_inputs_with_duplicate_ids_raises_exception(): ] # act, assert - with pytest.raises(ValueError, match='Duplicate simulation id "id" in input list'): + with pytest.raises(ValueError, match='Duplicate simulation ID "id" in input list'): additive.simulate(inputs) From dba2c0320b34fe1845230605d81619e62b306a27 Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 12:49:39 -0600 Subject: [PATCH 06/21] Fix heading underlines --- examples/00_additive_single_bead.py | 2 +- examples/01_additive_porosity.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/00_additive_single_bead.py b/examples/00_additive_single_bead.py index eeccba64f..cb5cd193a 100644 --- a/examples/00_additive_single_bead.py +++ b/examples/00_additive_single_bead.py @@ -40,7 +40,7 @@ ############################################################################### # Specify machine parameters -# ---------------------- +# -------------------------- # Specify machine parameters by first creating an # :class:`AdditiveMachine ` object # then assigning the desired values. All values are in SI units (m, kg, s, K) diff --git a/examples/01_additive_porosity.py b/examples/01_additive_porosity.py index bd0601be1..f3325e45f 100644 --- a/examples/01_additive_porosity.py +++ b/examples/01_additive_porosity.py @@ -36,7 +36,7 @@ ############################################################################### # Specify machine parameters -# ---------------------- +# -------------------------- # Specify machine parameters by first creating an # :class:`AdditiveMachine ` object # and then assigning the desired values. All values are in SI units From a068a34672194decc6a62d18bd0143c573ae2fcd Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 13:28:42 -0600 Subject: [PATCH 07/21] Update vale vocabulary --- doc/styles/Vocab/ANSYS/accept.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/styles/Vocab/ANSYS/accept.txt b/doc/styles/Vocab/ANSYS/accept.txt index 4936a6c13..8c1f0adb0 100644 --- a/doc/styles/Vocab/ANSYS/accept.txt +++ b/doc/styles/Vocab/ANSYS/accept.txt @@ -20,4 +20,6 @@ Makefile isort pandoc Ansys Lab -subpackages \ No newline at end of file +subpackages +single sign-on +sign-on \ No newline at end of file From 45e87934b5f82991dab1a0aabae5576d615a5e3a Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 13:50:24 -0600 Subject: [PATCH 08/21] Fix typo --- src/ansys/additive/additive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/additive/additive.py b/src/ansys/additive/additive.py index 90475c1ed..300629bb2 100644 --- a/src/ansys/additive/additive.py +++ b/src/ansys/additive/additive.py @@ -210,7 +210,7 @@ def simulate(self, inputs, nproc: typing.Optional[int] = None): nproc: int, None Number of processors to use for simulation. This corresponds to the maximum number of licenses to check out at one time. - If no value is specified, the value of the ``npoc`` parameter + If no value is specified, the value of the ``nproc`` parameter provided in the Additive service constructor is used. Returns From c52782b98f41958f360dbffd875636e6b0d2092c Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 13:54:55 -0600 Subject: [PATCH 09/21] Fix typo --- src/ansys/additive/download.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/additive/download.py b/src/ansys/additive/download.py index 927fd8d6b..e6908098f 100644 --- a/src/ansys/additive/download.py +++ b/src/ansys/additive/download.py @@ -22,7 +22,7 @@ def download_file( remote_file_name: str Path to file on the server. local_folder: str - Folder on yjr localhost to write yjr file to. + Folder on your localhost to write your file to. logger: ProgressLogger Log message handler. """ From 006707c6dde503cff67e675368075df54aef062f Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 14:07:41 -0600 Subject: [PATCH 10/21] Fix parameter explanation --- src/ansys/additive/examples/downloads.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ansys/additive/examples/downloads.py b/src/ansys/additive/examples/downloads.py index 7bd9e91b7..0977b3c63 100644 --- a/src/ansys/additive/examples/downloads.py +++ b/src/ansys/additive/examples/downloads.py @@ -37,13 +37,13 @@ def decompress(filename, subdir=None) -> str: filename : str Name of the file. subdir : str, None - Name of the subdirectory where the file resides. The - default is ``None``. + Name of the subdirectory of the ``examples`` directory + to extract the ZIP file contents to. The default is ``None``. Returns ------- str - Path to the decompressed ZIP file. + Path to the decompressed contents of the ZIP file. """ outdir = EXAMPLES_PATH zip_ref = zipfile.ZipFile(filename, "r") @@ -73,8 +73,8 @@ def _retrieve_file(url, filename) -> tuple[str, HTTPMessage]: Returns ------- - str: Local file path - HttpMessage: HTTP status message if any + str: Local path file was downloaded to. + HttpMessage: HTTP status message, if any. """ # First check if file has already been downloaded local_path = os.path.join(EXAMPLES_PATH, os.path.basename(filename)) From 92b38ca6eaa72c1c16a6585ea50527e7b354c9a1 Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 14:17:34 -0600 Subject: [PATCH 11/21] Fix doc comments and typo --- src/ansys/additive/material.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/additive/material.py b/src/ansys/additive/material.py index 43ce75860..09da3ef18 100644 --- a/src/ansys/additive/material.py +++ b/src/ansys/additive/material.py @@ -714,7 +714,7 @@ def vaporization_temperature(self, value: float): @property def characteristic_width_data(self) -> list[CharacteristicWidthDataPoint]: - """List of the :class:`CharacteristicWidthDataPoint` class.""" + """List of characteristic width data points.""" return self._characteristic_width_data @characteristic_width_data.setter @@ -728,7 +728,7 @@ def characteristic_width_data(self, value: list[CharacteristicWidthDataPoint]): @property def thermal_properties_data(self) -> list[ThermalPropertiesDataPoint]: - """List of the :class:`ThermalPropertiesDataPoint` class.""" + """List of thermal properties data points.""" return self._thermal_properties_data @thermal_properties_data.setter @@ -742,7 +742,7 @@ def thermal_properties_data(self, value: list[ThermalPropertiesDataPoint]): @staticmethod def _from_material_message(msg: MaterialMessage): - """Create an additive mMaterial from a material message received from + """Create an additive material from a material message received from the Additive service.""" if not isinstance(msg, MaterialMessage): raise ValueError("Invalid message object passed to from_material_message()") From 45040593c8685ca78f6b2c5f49ae08c567d91f2a Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 14:31:28 -0600 Subject: [PATCH 12/21] Fix typo --- src/ansys/additive/microstructure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/additive/microstructure.py b/src/ansys/additive/microstructure.py index 627527371..4a53d15e6 100644 --- a/src/ansys/additive/microstructure.py +++ b/src/ansys/additive/microstructure.py @@ -531,7 +531,7 @@ def xy_circle_equivalence(self) -> pd.DataFrame: @property def xz_circle_equivalence(self) -> pd.DataFrame: - """Circle equivalence data forthe XZ plane. + """Circle equivalence data for the XZ plane. For data frame column names, see the :class:`CircleEquivalenceColumnNames` class. """ From 9a68023103289f1969e138b3ec3d619aece86ccf Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 14:33:34 -0600 Subject: [PATCH 13/21] Fix typo --- src/ansys/additive/microstructure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/additive/microstructure.py b/src/ansys/additive/microstructure.py index 4a53d15e6..ce2558547 100644 --- a/src/ansys/additive/microstructure.py +++ b/src/ansys/additive/microstructure.py @@ -531,7 +531,7 @@ def xy_circle_equivalence(self) -> pd.DataFrame: @property def xz_circle_equivalence(self) -> pd.DataFrame: - """Circle equivalence data for the XZ plane. + """Circle equivalence data for the XZ plane. For data frame column names, see the :class:`CircleEquivalenceColumnNames` class. """ From 0daf90c8edf523e77690dad8061e0c3ce24ff2fd Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 14:45:26 -0600 Subject: [PATCH 14/21] Fix doc string and return type --- .../parametric_study/display/single_bead_eval_plot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py b/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py index ba51bd80d..6a80ac0ab 100644 --- a/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py +++ b/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py @@ -20,8 +20,8 @@ def single_bead_eval_plot(ps: ParametricStudy): - """Generate a contour plot of single bead results to determine desirable - melt pool statistics. + """Generate a contour plot of single bead results to determine parametric + regions with desirable melt pool statistics. Parameters ---------- @@ -203,7 +203,7 @@ def __update_plot( def __contour_data( df: pd.DataFrame, ht: float, lt: float, bd: float, poi: str, range: Tuple[float, float] -) -> Tuple[list, list, list, list]: +) -> Tuple[list, list, list]: """Get lists of scan speed, laser power, and parameter of interest values.""" From 5812b8aa0a4cb39927801895cdd19c2f40555015 Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 14:59:00 -0600 Subject: [PATCH 15/21] Fix typo and truncated doc string --- src/ansys/additive/parametric_study/parametric_study.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansys/additive/parametric_study/parametric_study.py b/src/ansys/additive/parametric_study/parametric_study.py index 7eaaea253..133fc44bb 100644 --- a/src/ansys/additive/parametric_study/parametric_study.py +++ b/src/ansys/additive/parametric_study/parametric_study.py @@ -805,7 +805,7 @@ def generate_microstructure_permutations( Random seed to use for microstructure simulations. The default is ``None``, in which case a random seed is automatically generated. Valid values are between 1 and 2^31 - 1. - iteration : int, optiDEFAULT_ITERATION + iteration : int, DEFAULT_ITERATION Iteration number for this set of simulations. priority : int, DEFAULT_PRIORITY Priority for this set of simulations. @@ -1205,6 +1205,7 @@ def _create_unique_id(self, prefix: Optional[str] = None, id: Optional[str] = No ------- str Unique ID. If ``id`` is unique, it is returned. Otherwise, + it is used as a prefix for a unique ID. """ if id is not None and not self._data_frame[ColumnNames.ID].str.match(f"{id}").any(): From ffeb6f27242d0578e0d33ab7b4343060d9915d38 Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 15:03:59 -0600 Subject: [PATCH 16/21] Fix doc string --- src/ansys/additive/parametric_study/parametric_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/additive/parametric_study/parametric_utils.py b/src/ansys/additive/parametric_study/parametric_utils.py index 8a155f2bd..a665cecaf 100644 --- a/src/ansys/additive/parametric_study/parametric_utils.py +++ b/src/ansys/additive/parametric_study/parametric_utils.py @@ -24,7 +24,7 @@ def build_rate( ------- float Volumetric build rate is returned if hatch spacing is provided. - Otherwise, an area build rate is returned. If input units are m/s, m, or m, + Otherwise, an area build rate is returned. If input units are m/s and m, the output units are m^3/s or m^2/s. """ if hatch_spacing is None: From c3e609389d706e1461eb5d7ef72548e543c8382c Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 15:08:05 -0600 Subject: [PATCH 17/21] Fix wording of doc string --- src/ansys/additive/server_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/additive/server_utils.py b/src/ansys/additive/server_utils.py index 94c23bf70..68cb16bed 100644 --- a/src/ansys/additive/server_utils.py +++ b/src/ansys/additive/server_utils.py @@ -23,7 +23,7 @@ def launch_server(port: int, cwd: str = USER_DATA_PATH) -> subprocess.Popen: Returns ------- process: subprocess.Popen - Server process. To stop the server, call the ``kill()`` function on the returned object. + Server process. To stop the server, call the ``kill()`` method on the returned object. """ ver = DEFAULT_ANSYS_VERSION server_exe = "" From 4460d4ffcb7fb1bf0df07950937ffc550749607d Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 15:24:32 -0600 Subject: [PATCH 18/21] Reword doc strings --- src/ansys/additive/single_bead.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ansys/additive/single_bead.py b/src/ansys/additive/single_bead.py index d7d1564e8..db5e189bd 100644 --- a/src/ansys/additive/single_bead.py +++ b/src/ansys/additive/single_bead.py @@ -117,8 +117,8 @@ class MeltPoolColumnNames: class MeltPool: - """Provides the container for the melt pool evolution during a single bead - simulation. + """Contains the melt pool size dimensions for each time step during a + single bead simulation. Units are SI unless otherwise noted. """ @@ -151,13 +151,13 @@ def data_frame(self) -> DataFrame: - ``bead_length``: Length of the bead at each time step. Columns: - - ``MeltPoolColumnNames.LENGTH``: Length of the melt pool at each time step. - - ``MeltPoolColumnNames.WIDTH``: Width of the melt pool at each time step. - - ``MeltPoolColumnNames.DEPTH``: Depth of the melt pool at each time step. - - ``MeltPoolColumnNames.REFERENCE_WIDTH``: Reference width of the melt pool at each time step. + - ``MeltPoolColumnNames.LENGTH``: Length of the melt pool. + - ``MeltPoolColumnNames.WIDTH``: Width of the melt pool. + - ``MeltPoolColumnNames.DEPTH``: Depth of the melt pool. + - ``MeltPoolColumnNames.REFERENCE_WIDTH``: Reference width of the melt pool. Reference width is the melt pool width at the bottom of the powder layer or the width at the top of the substrate. - - ``MeltPoolColumnNames.REFERENCE_DEPTH``: Reference depth of the melt pool at each time step. + - ``MeltPoolColumnNames.REFERENCE_DEPTH``: Reference depth of the melt pool. Reference depth is the depth of the entire melt pool minus the powder layer thickness or the depth of penetration into the substrate. """ From 4e43560941367e25dec15488c75693c552fe239d Mon Sep 17 00:00:00 2001 From: Peter Krull - ANSYS Date: Fri, 1 Sep 2023 15:33:07 -0600 Subject: [PATCH 19/21] Update src/ansys/additive/microstructure.py Reword doc string --- src/ansys/additive/microstructure.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ansys/additive/microstructure.py b/src/ansys/additive/microstructure.py index ce2558547..ba32652d8 100644 --- a/src/ansys/additive/microstructure.py +++ b/src/ansys/additive/microstructure.py @@ -317,9 +317,10 @@ def sensor_dimension(self, value: float): @property def use_provided_thermal_parameters(self) -> bool: - """Check to see if the ``cooling_rate``, ``thermal_gradient``, + """Flag indicating if the ``cooling_rate``, ``thermal_gradient``, ``melt_pool_depth``, and ``melt_pool_width`` parameters have been - provided by the user.""" + provided by the user. If the value is ``False``, these values + will be calculated. Default is ``False``.""" return self._use_provided_thermal_parameters @use_provided_thermal_parameters.setter From c156d83e58a24e2deef9a24d887e9d2897717719 Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 15:42:00 -0600 Subject: [PATCH 20/21] Fix doc strings --- .../additive/parametric_study/display/ave_grain_size_plot.py | 2 +- .../parametric_study/display/porosity_contour_plot.py | 2 +- src/ansys/additive/parametric_study/display/show_table.py | 4 ++-- .../parametric_study/display/single_bead_eval_plot.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py b/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py index 286d09764..88bfb6165 100644 --- a/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py +++ b/src/ansys/additive/parametric_study/display/ave_grain_size_plot.py @@ -26,7 +26,7 @@ def ave_grain_size_plot(ps: ParametricStudy): Returns ------- :class: `panel.Row ` - Panel row containing the plot and controls. + Iteractive plot. """ df = __data_frame(ps) ( diff --git a/src/ansys/additive/parametric_study/display/porosity_contour_plot.py b/src/ansys/additive/parametric_study/display/porosity_contour_plot.py index 93c9e5f50..c83c744ad 100644 --- a/src/ansys/additive/parametric_study/display/porosity_contour_plot.py +++ b/src/ansys/additive/parametric_study/display/porosity_contour_plot.py @@ -25,7 +25,7 @@ def porosity_contour_plot(ps: ParametricStudy): Returns ------- :class: `panel.Row ` - Panel row containing the plot and controls. + Interactive plot. """ df = __data_frame(ps) ( diff --git a/src/ansys/additive/parametric_study/display/show_table.py b/src/ansys/additive/parametric_study/display/show_table.py index c588515c5..003c3accb 100644 --- a/src/ansys/additive/parametric_study/display/show_table.py +++ b/src/ansys/additive/parametric_study/display/show_table.py @@ -24,12 +24,12 @@ def show_table(ps: ParametricStudy, page_size: int = 10): ps : :class:`ParametricStudy ` Parametric study to display. page_size : int, 10 - Number of rows to display per page. + Number of table rows to display per page. Returns ------- :class:`panel.Column ` - Panel column containing the table and controls. + Interactive table. """ global _df, _ps, _iter_select, _pri_select diff --git a/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py b/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py index 6a80ac0ab..02f0c228a 100644 --- a/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py +++ b/src/ansys/additive/parametric_study/display/single_bead_eval_plot.py @@ -31,7 +31,7 @@ def single_bead_eval_plot(ps: ParametricStudy): Returns ------- :class: `panel.Row ` - Panel row containing the plot and controls. + Interactive plot. """ df = __data_frame(ps) ( From 8a3d5da92b1d517aa34d6a286e00ce4b44baeeb9 Mon Sep 17 00:00:00 2001 From: Peter Krull Date: Fri, 1 Sep 2023 16:47:54 -0600 Subject: [PATCH 21/21] Fix pre-commit check --- src/ansys/additive/microstructure.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ansys/additive/microstructure.py b/src/ansys/additive/microstructure.py index ba32652d8..e0efd65e2 100644 --- a/src/ansys/additive/microstructure.py +++ b/src/ansys/additive/microstructure.py @@ -319,8 +319,11 @@ def sensor_dimension(self, value: float): def use_provided_thermal_parameters(self) -> bool: """Flag indicating if the ``cooling_rate``, ``thermal_gradient``, ``melt_pool_depth``, and ``melt_pool_width`` parameters have been - provided by the user. If the value is ``False``, these values - will be calculated. Default is ``False``.""" + provided by the user. + + If the value is ``False``, these values + will be calculated. Default is ``False``. + """ return self._use_provided_thermal_parameters @use_provided_thermal_parameters.setter