From bbc93d4d3f7b07f92b53d732c62c08511daf3efd Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 17:59:31 +0530 Subject: [PATCH 01/13] removed post directory from core --- src/ansys/dyna/core/post/README.md | 1 - src/ansys/dyna/core/post/__init__.py | 0 2 files changed, 1 deletion(-) delete mode 100644 src/ansys/dyna/core/post/README.md delete mode 100644 src/ansys/dyna/core/post/__init__.py diff --git a/src/ansys/dyna/core/post/README.md b/src/ansys/dyna/core/post/README.md deleted file mode 100644 index 963a0a4b50..0000000000 --- a/src/ansys/dyna/core/post/README.md +++ /dev/null @@ -1 +0,0 @@ -This is where pydyna postprocessing module will live \ No newline at end of file diff --git a/src/ansys/dyna/core/post/__init__.py b/src/ansys/dyna/core/post/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 From 2127ad9764ae670f997ebb3267bd1806abc5ce84 Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 18:00:17 +0530 Subject: [PATCH 02/13] removed docker filed from the top directory since they are moved to pre or solver --- docker/Dockerfile | 21 ------------ docker/README.rst | 70 --------------------------------------- docker/docker-compose.yml | 22 ------------ 3 files changed, 113 deletions(-) delete mode 100644 docker/Dockerfile delete mode 100644 docker/README.rst delete mode 100644 docker/docker-compose.yml diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 799b847445..0000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# Pydyna-pre service Linux-based Dockerfile - -FROM python:3.8-slim-buster - -# Define the working directory -WORKDIR /server - -# Install unzip -RUN apt-get update && apt-get install -y unzip - -# Add the binary files from the latest release -COPY linux-binaries.zip . -RUN unzip -qu linux-binaries.zip && rm linux-binaries.zip - -RUN pip3 install grpcio grpcio-tools protobuf - -RUN python -m grpc_tools.protoc --python_out=./linux-binaries --grpc_python_out=./linux-binaries -I./linux-binaries ./linux-binaries/kwprocess.proto - -EXPOSE 50051 - -CMD ["python3", "./linux-binaries/kwserver.py"] diff --git a/docker/README.rst b/docker/README.rst deleted file mode 100644 index 6363a54d56..0000000000 --- a/docker/README.rst +++ /dev/null @@ -1,70 +0,0 @@ -Create your own pydyna-pre service docker container -=================================================== - -The pydyna-pre service Docker containers can be easily built by following -these steps. - -Inside this folder, the instructions (i.e. ``Dockerfile.*`` files) for -building the pydyna-pre service Docker containers are made available. - -* ``Dockerfile``: this file builds the Linux-based Docker image. - -Prerequisites -^^^^^^^^^^^^^ - -* Ensure that ``docker`` is installed in your machine. - If you do not have ``docker`` available, please refer to the - `official Docker site `_. - -* Download the latest release artifacts for the Linux - Docker container. You can do this as follows: - - * Latest Linux artifacts: `linux-binaries.zip `_ - -* Move these ``.zip`` files to the current location (i.e. ``/docker``). - -Building the Docker images -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In order to build your images, follow the next instructions: - -* Locate yourself at ``/docker`` in your terminal. -* Run the following Docker command: - - .. code:: bash - - docker build -t ghcr.io/ansys/ls-pre: -f . - - Bear in mind that you will need to substitute the following entries in the previous command: - - * ````: this will be ``Dockerfile`` - * ````: this will be ``latest`` - -* Check that the image has been created successfully. You should see an output similar - to this one when running the following command: - - .. code:: bash - - docker images - - >>> REPOSITORY TAG IMAGE ID CREATED SIZE - >>> ghcr.io/ansys/ls-pre *******-latest ............ X seconds ago 188MB - >>> ...... ...... ............ .............. ...... - -Run the image as a container -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Run the following Docker command: - - .. code:: bash - - docker run -d -p 50051:50051 ghcr.io/ansys/ls-pre . - -* Check that the image has been created successfully. - - -.. code:: bash - - - >>> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - >>> c77ffd67f9fa ghcr.io/ansys/ls-pre "python3 ./linux-bin…" 7 seconds ago Up 7 seconds 0.0.0.0:50051->50051/tcp, :::50051->50051/tcp hardcore_margulis \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index d65afde474..0000000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: "3.8" -services: - dyna: - image: ghcr.io/ansys/dynasolver:0.3 - networks: - - dyna_internal - deploy: - replicas: 1 - volumes: - - /rundir - cap_add: - - SYS_PTRACE - ports: - - target: 5000 - published: 5000 - mode: ingress - user: mpirun - entrypoint: ["/ansys_inc/server.py","dyna"] - environment: - - LSTC_LICENSE_SERVER=lvrpanda.ansys.com -networks: - dyna_internal: From d58f37ce1aeae3f5cf52b67b359fb265b1f96443 Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 18:02:23 +0530 Subject: [PATCH 03/13] included docker doc in index.rst --- doc/source/index.rst | 3 +- docker/pre/Dockerfile | 21 +++++++++++++ docker/pre/README.rst | 70 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 docker/pre/Dockerfile create mode 100644 docker/pre/README.rst diff --git a/doc/source/index.rst b/doc/source/index.rst index bca21ad579..4f2c29bb0b 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -2,7 +2,8 @@ PyDyna documentation |version| =============================== .. include:: ../../README.rst - +.. include:: ../../docker/pre/README.rst +.. include:: ../../docker/solver/README.rst .. jinja:: main_toctree diff --git a/docker/pre/Dockerfile b/docker/pre/Dockerfile new file mode 100644 index 0000000000..799b847445 --- /dev/null +++ b/docker/pre/Dockerfile @@ -0,0 +1,21 @@ +# Pydyna-pre service Linux-based Dockerfile + +FROM python:3.8-slim-buster + +# Define the working directory +WORKDIR /server + +# Install unzip +RUN apt-get update && apt-get install -y unzip + +# Add the binary files from the latest release +COPY linux-binaries.zip . +RUN unzip -qu linux-binaries.zip && rm linux-binaries.zip + +RUN pip3 install grpcio grpcio-tools protobuf + +RUN python -m grpc_tools.protoc --python_out=./linux-binaries --grpc_python_out=./linux-binaries -I./linux-binaries ./linux-binaries/kwprocess.proto + +EXPOSE 50051 + +CMD ["python3", "./linux-binaries/kwserver.py"] diff --git a/docker/pre/README.rst b/docker/pre/README.rst new file mode 100644 index 0000000000..6363a54d56 --- /dev/null +++ b/docker/pre/README.rst @@ -0,0 +1,70 @@ +Create your own pydyna-pre service docker container +=================================================== + +The pydyna-pre service Docker containers can be easily built by following +these steps. + +Inside this folder, the instructions (i.e. ``Dockerfile.*`` files) for +building the pydyna-pre service Docker containers are made available. + +* ``Dockerfile``: this file builds the Linux-based Docker image. + +Prerequisites +^^^^^^^^^^^^^ + +* Ensure that ``docker`` is installed in your machine. + If you do not have ``docker`` available, please refer to the + `official Docker site `_. + +* Download the latest release artifacts for the Linux + Docker container. You can do this as follows: + + * Latest Linux artifacts: `linux-binaries.zip `_ + +* Move these ``.zip`` files to the current location (i.e. ``/docker``). + +Building the Docker images +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In order to build your images, follow the next instructions: + +* Locate yourself at ``/docker`` in your terminal. +* Run the following Docker command: + + .. code:: bash + + docker build -t ghcr.io/ansys/ls-pre: -f . + + Bear in mind that you will need to substitute the following entries in the previous command: + + * ````: this will be ``Dockerfile`` + * ````: this will be ``latest`` + +* Check that the image has been created successfully. You should see an output similar + to this one when running the following command: + + .. code:: bash + + docker images + + >>> REPOSITORY TAG IMAGE ID CREATED SIZE + >>> ghcr.io/ansys/ls-pre *******-latest ............ X seconds ago 188MB + >>> ...... ...... ............ .............. ...... + +Run the image as a container +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Run the following Docker command: + + .. code:: bash + + docker run -d -p 50051:50051 ghcr.io/ansys/ls-pre . + +* Check that the image has been created successfully. + + +.. code:: bash + + + >>> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + >>> c77ffd67f9fa ghcr.io/ansys/ls-pre "python3 ./linux-bin…" 7 seconds ago Up 7 seconds 0.0.0.0:50051->50051/tcp, :::50051->50051/tcp hardcore_margulis \ No newline at end of file From 8fe42d76fc7e071f9f507475ffebc0e0409e4ee3 Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 18:03:04 +0530 Subject: [PATCH 04/13] docker file and build script added to solver --- docker/solver/Dockerfile | 87 ++++++++++++++++++++++++++++++++ docker/solver/README.rst | 67 ++++++++++++++++++++++++ docker/solver/do_build | 13 +++++ docker/solver/docker-compose.yml | 20 ++++++++ 4 files changed, 187 insertions(+) create mode 100644 docker/solver/Dockerfile create mode 100644 docker/solver/README.rst create mode 100644 docker/solver/do_build create mode 100644 docker/solver/docker-compose.yml diff --git a/docker/solver/Dockerfile b/docker/solver/Dockerfile new file mode 100644 index 0000000000..7b43ed5193 --- /dev/null +++ b/docker/solver/Dockerfile @@ -0,0 +1,87 @@ +FROM centos:7 +# +# The order of the lines in here should be (as much as possible) in +# an order that will create the same series of intermediate images +# no mater what version of dyna we are using. This will speed up +# experiments when creating containers over and over. Ordering the +# commands this way makes the Dockerfile a bit more confusing, because +# for example we make all the directories up top, but don't put things +# in them until further down. And some environment variables are near +# the top, but others near the bottom + +LABEL "com.ansys.description"="Ansys MPPDYNA with gRPC server" + +# install some missing stuff we want/need + +RUN yum -y install openssh-clients openssh-server bind-utils sudo python3 +RUN python3 -m pip install --upgrade pip +RUN python3 -m pip install grpcio +RUN python3 -m pip install grpcio-tools +# +ENV USER mpirun +ENV HOME /home/mpirun +ENV LD_LIBRARY_PATH /ansys_inc/lib +ENV LSTC_LICENSE network +ENV LSTC_LICENSE_SERVER license +ENV SSHDIR ${HOME}/.ssh/ + + +RUN groupadd ${USER} +RUN useradd -g ${USER} -d ${HOME} ${USER} && \ + echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers +# +RUN mkdir -p /ansys_inc/lib +RUN mkdir -p /rundir +RUN mkdir /var/run/sshd +RUN mkdir -p ${SSHDIR} +RUN chown -R ${USER}:${USER} /rundir +RUN chmod -R 755 /rundir +WORKDIR /rundir + +# set up the runtime environment variables for +# dyna + +RUN echo "export LD_LIBRARY_PATH=/ansys_inc/lib:/opt/openmpi/lib" > ${HOME}/.bashrc +# Adding these causes problems because they can't be overridden +# via the "environment" attribute in a docker-compose file. +# The ENV commands above come through as defaults, but can be +# overridden (to use the ANSYS license, or a different license server) +# +# RUN echo "export LSTC_LICENSE=network" >> ${HOME}/.bashrc +# RUN echo "export LSTC_LICENSE_SERVER=license" >> ${HOME}/.bashrc +# +# Get ssh properly set up +# +RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config +# SSH login fix. Otherwise user is kicked off after login +RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd +# +EXPOSE 22 +CMD ["/usr/sbin/sshd", "-D"] +# +# Everything above here should not depend on the version of DYNA or the MPI we are using +# and so should behave nicely as regards the Docker image cache. Below here not so much +# +ENV PATH /opt/openmpi/bin:${PATH} +RUN echo "export PATH=/opt/openmpi/bin:\${PATH}" >> ${HOME}/.bashrc + +ADD ssh/config ${SSHDIR}/config +ADD ssh/id_rsa ${SSHDIR}/id_rsa +ADD ssh/id_rsa.pub ${SSHDIR}/id_rsa.pub +ADD ssh/id_rsa.pub ${SSHDIR}/authorized_keys +RUN ssh-keygen -A + +RUN chmod -R 600 ${SSHDIR}* && \ + chown -R ${USER}:${USER} ${SSHDIR} + +RUN chown -R ${USER}:${USER} ${HOME} + +# Copy the openmpi libraries + +RUN mkdir -p /opt +COPY mpi /opt/openmpi + +# The executable will go in /ansys_inc, and the +# ifort runtime libraries in /ansys_inc/lib + +COPY docker_dir /ansys_inc diff --git a/docker/solver/README.rst b/docker/solver/README.rst new file mode 100644 index 0000000000..0b0720b342 --- /dev/null +++ b/docker/solver/README.rst @@ -0,0 +1,67 @@ +Create your own pydyna-solver service docker container +=================================================== + +The pydyna-solver service Docker containers can be easily built by following +these steps. + +* ``docker/solver/Dockerfile``: this file builds the Linux-based Docker image. + +Prerequisites +^^^^^^^^^^^^^ + +* Ensure that ``docker`` is installed in your machine. + If you do not have ``docker`` available, please refer to the + `official Docker site `_. + +* If you are building the image on Windows, you will need to have + Windows Subsystem for Linux (WSL) installed. The instructions for that can be found `here ` + +* Download the latest release artifacts for the Linux + Docker container. You can do this as follows: + + * Latest Linux artifacts: `mppdyna_docker_centos7.zip `_ + +* Move these ``.zip`` files to a local directory ``local_image_build_dir``. + +Building the Docker images +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In order to build your images, follow the next instructions: + +* cd to ``local_image_build_dir``. +* Run the following Docker command: + + .. code:: bash + + ./do_build + +* Check that the image has been created successfully. You should see an output similar + to this one when running the following command: + + .. code:: bash + + docker images + + >>> REPOSITORY TAG IMAGE ID CREATED SIZE + >>> dyna_solver_v04 latest defbadbeee8e 16 minutes ago 730MB + >>> ...... ...... ............ .............. ...... + +Run the image as a container +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Edit the docker-compose.yml file and replace ```` with the correct license server hosting the DYNA license. + If you are using Ansy Flexlm license + +* Run the following Docker command: + + .. code:: bash + + docker-compose up + +* Check that the image has been created successfully. + + +.. code:: bash + + >>> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + >>> be84c95db31d dyna_solver_v04 "/ansys_inc/server.p…" 18 minutes ago Up 8 seconds 22/tcp, 0.0.0.0:5000->5000/tcp mppdyna_docker_centos7_dyna_1 diff --git a/docker/solver/do_build b/docker/solver/do_build new file mode 100644 index 0000000000..99df1bdb95 --- /dev/null +++ b/docker/solver/do_build @@ -0,0 +1,13 @@ +#!/bin/sh +# +# Do some basic ssh setup +# +rm -rf ssh +mkdir ssh +ssh-keygen -q -b 2048 -f ssh/id_rsa -N "" +echo "Host *" > ssh/config +echo " StrictHostKeyChecking no" >> ssh/config +# +# Build container +# +docker build -t dyna_solver_v04 . diff --git a/docker/solver/docker-compose.yml b/docker/solver/docker-compose.yml new file mode 100644 index 0000000000..0eef2a2fac --- /dev/null +++ b/docker/solver/docker-compose.yml @@ -0,0 +1,20 @@ +version: "3.3" +services: + dyna: + image: dyna_solver_v04 + networks: + - dyna_internal + volumes: + - /rundir + cap_add: + - SYS_PTRACE + ports: + - target: 5000 + published: 5000 + mode: ingress + user: mpirun + environment: + - LSTC_LICENSE_SERVER= + entrypoint: ["/ansys_inc/server.py","dyna"] +networks: + dyna_internal: \ No newline at end of file From 4d3c2808d5e258f47f6b640017c47f731f310568 Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 20:57:03 +0530 Subject: [PATCH 05/13] updated getting started to reflect the public release instructions --- doc/source/getting-started/index.rst | 73 +++++++++++++++++----------- doc/source/index.rst | 3 +- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/doc/source/getting-started/index.rst b/doc/source/getting-started/index.rst index edec344234..25262906ab 100644 --- a/doc/source/getting-started/index.rst +++ b/doc/source/getting-started/index.rst @@ -1,50 +1,65 @@ Getting started =============== +************ Installation -~~~~~~~~~~~~ +************ -This package is not yet available on the public PyPI, but you can still install -it using ``pip`` from the private PyPI repository. +Python Module +~~~~~~~~~~~~~ -The following on Windows: +The ``ansys.dyna.core`` package currently supports Python 3.8 through +Python 3.10 on Windows, Mac OS, and Linux. -.. code:: +Install the latest release from +`PyPi `_ with: - set PYANSYS_PYPI_PRIVATE_PAT= - set INDEX_URL=https://%PYANSYS_PYPI_PRIVATE_PAT%@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/ - python -m pip install ansys-dyna-core --index-url %INDEX_URL% +.. code:: console -And if you are running Linux: + pip install ansys-dyna-core -.. code:: +Alternatively, install the latest from +`PyDYNA GitHub `_ via: - PYANSYS_PYPI_PRIVATE_PAT= - export INDEX_URL='https://$PYANSYS_PYPI_PRIVATE_PAT@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple/' - python -m pip install ansys-dyna-core --index-url $INDEX_URL +.. code:: console + + pip install git+https://github.com/pyansys/pydyna.git + -Email your friendly PyAnsys team member for the ``PYANSYS_PYPI_PRIVATE_PAT`` -at `pyansys.core@ansys.com `_ or send a message via Teams. +For a local *development* version, install with: -**Installing from git** +.. code:: console -If you have ``git`` installed and want the bleeding edge version: + git clone https://github.com/pyansys/pydyna.git + cd pydyna + pip install -e . -.. code:: +This allows you to install the ``ansys-dyna-core`` module +and modify it locally and have the changes reflected in your setup +after restarting the Python kernel. - pip install -U git+https://github.com/pyansys/pyDyna@main +Offline installation +~~~~~~~~~~~~~~~~~~~~ +If you lack an internet connection on your install machine, the recommended way +of installing PyDYNA is downloading the wheelhouse archive from the +`Releases Page `_ for your corresponding +machine architecture. -You need to be logged into GitHub locally and be a member of the `PyAnsys Organization `_. +Each wheelhouse archive contains all the Python wheels necessary to install +PyDYNA from scratch on Windows and Linux for Python 3.8 through 3.11. You can install +this on an isolated system with a fresh Python or on a virtual environment. -Alternatively, if you need to modify the repository locally (or want to -do local development), you can clone it and install it in "development" mode with: +For example, on Linux with Python 3.8, unzip it and install it with the following: -.. code:: +.. code:: console - git clone https://github.com/pyansys/pyDyna - cd pyDyna - pip install -e . + unzip ansys-dyna-core-v0.3.1-wheelhouse-ubuntu-latest-3.8.zip wheelhouse + pip install ansys-dyna-core -f wheelhouse --no-index --upgrade --ignore-installed + +If you're on Windows with Python 3.8, unzip to a ``wheelhouse`` directory and +install using the preceding command. + +Consider installing using a `virtual environment `_. -Note the ``-e`` flag, which denotes that you are in development mode. -You can make changes in the local ``pyDyna`` and have them reflected -in your local install of PyDyna. +.. include:: ../../../docker/pre/README.rst +.. include:: ../../../docker/solver/README.rst \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst index 4f2c29bb0b..bca21ad579 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -2,8 +2,7 @@ PyDyna documentation |version| =============================== .. include:: ../../README.rst -.. include:: ../../docker/pre/README.rst -.. include:: ../../docker/solver/README.rst + .. jinja:: main_toctree From 38e5291aceaac21ae48d7d44c855a35deaa89aaa Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 21:01:39 +0530 Subject: [PATCH 06/13] uncommented dpf related lines from docs --- examples/EM/railgun/em_post.py | 83 ++++++++++++++++++++++++++ examples/EM/railgun/em_railgun.py | 97 +++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 examples/EM/railgun/em_post.py create mode 100644 examples/EM/railgun/em_railgun.py diff --git a/examples/EM/railgun/em_post.py b/examples/EM/railgun/em_post.py new file mode 100644 index 0000000000..e6b2442044 --- /dev/null +++ b/examples/EM/railgun/em_post.py @@ -0,0 +1,83 @@ +""" +.. _ref_em_railgun_post: +EM multi physics post processing example +---------------------------------------- + +This example show how to animate the d3plot and display the electric field in the railgun. + +""" +from ansys.dpf import core as dpf +from ansys.dpf.core import examples + +############################################################################### +# Connect to DPF +# ~~~~~~~~~~~~~~ +dpf.connect_to_server() + +############################################################################### +# Load the model +# ~~~~~~~~~~~~~~ +# Load the model and print the contents of the model. Since this is a multiphysics problem +# the default results returned is the structural results. +# +ds = dpf.DataSources() +ds.set_result_file_path(r'D:\PYDYNA_BETA_V.0.1\example-data\pydyna\EM\d3plot', 'd3plot') +model=dpf.Model(ds) +print(model) + +############################################################################### +# Get MS mesh +# ~~~~~~~~~~~ +# We now define an operator to extract the mesh from the EM solver. +# "lsdyna::ms::meshs_provider" is the operator we can connect to get the mesh. +# Since the meshes container contains the mesh for all time states, we need to scope it to the +# desired timestate. +# +meshOP = dpf.Operator("lsdyna::ms::meshes_provider") +meshOP.inputs.data_sources.connect(ds) +timeScoping = dpf.Scoping() +timeScoping.ids = list(range(1, 21)) +meshOP.inputs.time_scoping.connect(timeScoping) +meshes = meshOP.outputs.meshes() +mesh = meshes.get_mesh({'time':1}) + +############################################################################### +# MS Result Info +# ~~~~~~~~~~~~~~ +# "result_info_provider" lets us list all the variables available in the container. +# +resultInfoOp = dpf.Operator("lsdyna::ms::result_info_provider") +resultInfoOp.inputs.data_sources(ds) +result_info = resultInfoOp.outputs.result_info() +print(result_info) + +############################################################################### +# Get Field Variable from the available results +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# The actual field variable of interest is extracted from the "lsdyna::ms::results" operator. +# The fileds extracted from this operator is first associated with a mesh. The variable of interest is +# the electric field in this case. This can be retrieved from specifying the right Domain ID and the Variable ID +# In this case Domain=0 and Variable=1014 represents the electric field as seen from the output above. +# electric_fielddomain_id__0__variable_id__1014: Elemental Electric Field(domain Id: 0, Variable Id: 1014) +# +ms_op = dpf.Operator("lsdyna::ms::results") +ms_op.inputs.data_sources(ds) +ms_op.inputs.time_scoping([44]) +fields = ms_op.outputs.results() +for f in fields: + f.meshed_region=mesh +field0 = fields.get_field({"domain_id":0, "variable_id":1014}) +print(field0) + +############################################################################### +# Plot the Electric Field +# ~~~~~~~~~~~~~~~~~~~~~~~ +# Now that we have the field of interest, we can plot it at any given state. In order to display the mesh at that +# state, we need to extract the displacement and deform the field by the displacement field which is shown below. +# +disp = model.results.displacement(time_scoping=[44]).eval() +c_pos = [(346.9131285482345, 313.2551112639297, 39.299903249251045), + (101.24994659423828, 0.0, 0.0), + (-0.09694442015878338, -0.04868966261897064, 0.9940981320544406)] +field0.plot(deform_by=disp[0],show_edges=False,cpos=c_pos) + diff --git a/examples/EM/railgun/em_railgun.py b/examples/EM/railgun/em_railgun.py new file mode 100644 index 0000000000..980f16fc55 --- /dev/null +++ b/examples/EM/railgun/em_railgun.py @@ -0,0 +1,97 @@ +""" +Railgun example +=============== + +This example demonstrates how to create an EM Railgun input deck. \n +LS-DYNA version : ls-dyna_smp_d_R13.0_365-gf8a97bda2a_winx64_ifort190.exe +""" + +import os +import sys + +from ansys.dyna.core.pre.dynasolution import DynaSolution +from ansys.dyna.core.pre.dynaem import ( + DynaEM, + Circuit, + CircuitType, + SegmentSet, + NodeSet, + Curve, + SolidPart, + SolidFormulation, + EMContact, + BEMSOLVER, + FEMSOLVER, +) +from ansys.dyna.core.pre.dynamaterial import MatElastic, MatRigid, EMMATTYPE +from em_railgun_data import * +from ansys.dyna.core.pre import examples +# sphinx_gallery_thumbnail_path = '_static/pre/em/railgun.png' + +hostname = "localhost" +if len(sys.argv) > 1: + hostname = sys.argv[1] + +solution = DynaSolution(hostname) +fns = [] +path = examples.em_railgun + os.sep +fns.append(path + "em_railgun.k") +solution.open_files(fns) +solution.set_termination(termination_time=3e-4) +solution.create_database_binary(dt=5e-6) + +railgun = DynaEM() +solution.add(railgun) + +railgun.analysis.set_timestep(timestep=5e-6) +railgun.analysis.set_solver_bem(solver=BEMSOLVER.PCG) +railgun.analysis.set_solver_fem(solver=FEMSOLVER.DIRECT_SOLVER, relative_tol=1e-3) + +circuit = Circuit( + circuit_type=CircuitType.IMPOSED_CURRENT_VS_TIME, + loadcurve=Curve(x=[0, 8e-5, 2e-4, 4e-4, 6e-4, 1e-3], y=[0, 350, 450, 310, 230, 125], sfo=2e6), +) +circuit.set_current( + current=SegmentSet(cur), current_inlet=SegmentSet(inlet), current_outlet=SegmentSet(outlet) +) +railgun.add(circuit) + +matelastic = MatElastic(mass_density=2.64e-3, young_modulus=9.7e10, poisson_ratio=0.31) +matelastic.set_electromagnetic_property(material_type=EMMATTYPE.CONDUCTOR, initial_conductivity=25) +matrigid = MatRigid( + mass_density=2.64e-3, + young_modulus=9.7e10, + poisson_ratio=0.31, + center_of_mass_constraint=1, + translational_constraint=7, + rotational_constraint=7, +) +matrigid.set_electromagnetic_property(material_type=EMMATTYPE.CONDUCTOR, initial_conductivity=25) + +coil = SolidPart(1) +coil.set_material(matelastic) +coil.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT) +railgun.parts.add(coil) + +workpiece1 = SolidPart(2) +workpiece1.set_material(matrigid) +workpiece1.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT) +railgun.parts.add(workpiece1) + +workpiece2 = SolidPart(3) +workpiece2.set_material(matrigid) +workpiece2.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT) +railgun.parts.add(workpiece2) + +railgun.boundaryconditions.create_spc(NodeSet(spc1), tx=False, ty=False, rz=False, death=0) +railgun.boundaryconditions.create_spc(NodeSet(spc2), tx=False, ty=False, rz=False, death=0) + +contact = EMContact() +railgun.contacts.add(contact) + +railgun.set_rogowsky_coil_to_output_current(SegmentSet(cur)) +railgun.create_em_database_globalenergy(outlv=1) + +railgun.create_em_output(mats=2, matf=2, sols=2, solf=2) + +solution.save_file() From 4adb24bf017fb140e3430189da5b3b1c5ef75bd6 Mon Sep 17 00:00:00 2001 From: kanthadya Date: Fri, 30 Jun 2023 21:03:48 +0530 Subject: [PATCH 07/13] uncommented dpf related lines from docs --- docker/pre/README.rst | 14 +++-- docker/solver/README.rst | 4 +- examples/Airbag/airbag_post.py | 40 +++++++------- examples/EM/em_post.py | 83 ----------------------------- examples/EM/em_railgun.py | 97 ---------------------------------- 5 files changed, 31 insertions(+), 207 deletions(-) delete mode 100644 examples/EM/em_post.py delete mode 100644 examples/EM/em_railgun.py diff --git a/docker/pre/README.rst b/docker/pre/README.rst index 6363a54d56..e2f1b76171 100644 --- a/docker/pre/README.rst +++ b/docker/pre/README.rst @@ -1,13 +1,17 @@ -Create your own pydyna-pre service docker container -=================================================== +Build pydyna-pre service docker container +========================================= The pydyna-pre service Docker containers can be easily built by following these steps. -Inside this folder, the instructions (i.e. ``Dockerfile.*`` files) for -building the pydyna-pre service Docker containers are made available. +To build the docker image you will need to clone pydyna repo locally: -* ``Dockerfile``: this file builds the Linux-based Docker image. +.. code:: console + + git clone https://github.com/pyansys/pydyna.git + cd pydyna + +* ``docker/pre/Dockerfile``: this file builds the Linux-based Docker image. Prerequisites ^^^^^^^^^^^^^ diff --git a/docker/solver/README.rst b/docker/solver/README.rst index 0b0720b342..9a44a1d0b3 100644 --- a/docker/solver/README.rst +++ b/docker/solver/README.rst @@ -1,5 +1,5 @@ -Create your own pydyna-solver service docker container -=================================================== +Build pydyna-solver service docker container +============================================ The pydyna-solver service Docker containers can be easily built by following these steps. diff --git a/examples/Airbag/airbag_post.py b/examples/Airbag/airbag_post.py index 9fa403cfad..c2a3ee29e7 100644 --- a/examples/Airbag/airbag_post.py +++ b/examples/Airbag/airbag_post.py @@ -6,12 +6,12 @@ This example show how to animate the d3plot and display the stress on the airbag. """ -# from ansys.dpf import core as dpf -# from ansys.dpf.core import examples +from ansys.dpf import core as dpf +from ansys.dpf.core import examples ############################################################################### # Connect to DPF # ~~~~~~~~~~~~~~ -# dpf.connect_to_server() +dpf.connect_to_server() ############################################################################### # Load the model @@ -19,39 +19,39 @@ # Load the model and print the contents of the model. All parts in the model are shell parts. # Model info lists the result components as well as the number of states available in the d3plot # -# ds = dpf.DataSources() -# ds.set_result_file_path(r'D:\PYDYNA_BETA_V.0.1\example-data\pydyna\Airbag\d3plot', 'd3plot') -# model = dpf.Model(ds) -# print(model) +ds = dpf.DataSources() +ds.set_result_file_path(r'D:\PYDYNA_BETA_V.0.1\example-data\pydyna\Airbag\d3plot', 'd3plot') +model = dpf.Model(ds) +print(model) ############################################################################### # Let's extract the stress on all the parts. The stress field container is scoped to all time frequencies # so as to be able to animate the change in stress on the airbag fabric. # -# stress = model.results.stress.on_all_time_freqs() -# stress.inputs.data_sources(ds) -# stress.inputs.requested_location.connect("Nodal") -# fieldsStr = stress.outputs.fields_container() +stress = model.results.stress.on_all_time_freqs() +stress.inputs.data_sources(ds) +stress.inputs.requested_location.connect("Nodal") +fieldsStr = stress.outputs.fields_container() ############################################################################### # Since the shell stress is reported at three through thickness points as default # in the d3plot file, the next few lines depicts how the stress # can be extracted on the mid integration point. # -# shell_layer_extract = dpf.operators.utility.change_shell_layers() -# shell_layer_extract.inputs.fields_container.connect(fieldsStr) -# shell_layer_extract.inputs.e_shell_layer.connect(dpf.common.shell_layers.mid.value) -# fields_top = shell_layer_extract.outputs.fields_container_as_fields_container() +shell_layer_extract = dpf.operators.utility.change_shell_layers() +shell_layer_extract.inputs.fields_container.connect(fieldsStr) +shell_layer_extract.inputs.e_shell_layer.connect(dpf.common.shell_layers.mid.value) +fields_top = shell_layer_extract.outputs.fields_container_as_fields_container() ############################################################################### # Plot the deformed state at 9ms # -# N = fields_top[19] -# D = model.results.displacement(time_scoping=[19]).eval() -# N.plot(deform_by=D[0],show_edges=False) +N = fields_top[19] +D = model.results.displacement(time_scoping=[19]).eval() +N.plot(deform_by=D[0],show_edges=False) ############################################################################### # Finally display the stress field and set the mesh to deform by the displacement of the nodes. # -# disp = model.results.displacement.on_all_time_freqs.eval() -# fields_top.animate(deform_by=disp,show_edges=False) \ No newline at end of file +disp = model.results.displacement.on_all_time_freqs.eval() +fields_top.animate(deform_by=disp,show_edges=False) \ No newline at end of file diff --git a/examples/EM/em_post.py b/examples/EM/em_post.py deleted file mode 100644 index 42c6823a93..0000000000 --- a/examples/EM/em_post.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -.. _ref_em_railgun_post: -EM multi physics post processing example ----------------------------------------- - -This example show how to animate the d3plot and display the electric field in the railgun. - -""" -# from ansys.dpf import core as dpf -# from ansys.dpf.core import examples - -############################################################################### -# Connect to DPF -# ~~~~~~~~~~~~~~ -# dpf.connect_to_server() - -############################################################################### -# Load the model -# ~~~~~~~~~~~~~~ -# Load the model and print the contents of the model. Since this is a multiphysics problem -# the default results returned is the structural results. -# -# ds = dpf.DataSources() -# ds.set_result_file_path(r'D:\PYDYNA_BETA_V.0.1\example-data\pydyna\EM\d3plot', 'd3plot') -# model=dpf.Model(ds) -# print(model) - -############################################################################### -# Get MS mesh -# ~~~~~~~~~~~ -# We now define an operator to extract the mesh from the EM solver. -# "lsdyna::ms::meshs_provider" is the operator we can connect to get the mesh. -# Since the meshes container contains the mesh for all time states, we need to scope it to the -# desired timestate. -# -# meshOP = dpf.Operator("lsdyna::ms::meshes_provider") -# meshOP.inputs.data_sources.connect(ds) -# timeScoping = dpf.Scoping() -# timeScoping.ids = list(range(1, 21)) -# meshOP.inputs.time_scoping.connect(timeScoping) -# meshes = meshOP.outputs.meshes() -# mesh = meshes.get_mesh({'time':1}) - -############################################################################### -# MS Result Info -# ~~~~~~~~~~~~~~ -# "result_info_provider" lets us list all the variables available in the container. -# -# resultInfoOp = dpf.Operator("lsdyna::ms::result_info_provider") -# resultInfoOp.inputs.data_sources(ds) -# result_info = resultInfoOp.outputs.result_info() -# print(result_info) - -############################################################################### -# Get Field Variable from the available results -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# The actual field variable of interest is extracted from the "lsdyna::ms::results" operator. -# The fileds extracted from this operator is first associated with a mesh. The variable of interest is -# the electric field in this case. This can be retrieved from specifying the right Domain ID and the Variable ID -# In this case Domain=0 and Variable=1014 represents the electric field as seen from the output above. -# electric_fielddomain_id__0__variable_id__1014: Elemental Electric Field(domain Id: 0, Variable Id: 1014) -# -# ms_op = dpf.Operator("lsdyna::ms::results") -# ms_op.inputs.data_sources(ds) -# ms_op.inputs.time_scoping([44]) -# fields = ms_op.outputs.results() -# for f in fields: -# f.meshed_region=mesh -# field0 = fields.get_field({"domain_id":0, "variable_id":1014}) -# print(field0) - -############################################################################### -# Plot the Electric Field -# ~~~~~~~~~~~~~~~~~~~~~~~ -# Now that we have the field of interest, we can plot it at any given state. In order to display the mesh at that -# state, we need to extract the displacement and deform the field by the displacement field which is shown below. -# -# disp = model.results.displacement(time_scoping=[44]).eval() -# c_pos = [(346.9131285482345, 313.2551112639297, 39.299903249251045), -# (101.24994659423828, 0.0, 0.0), -# (-0.09694442015878338, -0.04868966261897064, 0.9940981320544406)] -# field0.plot(deform_by=disp[0],show_edges=False,cpos=c_pos) - diff --git a/examples/EM/em_railgun.py b/examples/EM/em_railgun.py deleted file mode 100644 index 980f16fc55..0000000000 --- a/examples/EM/em_railgun.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -Railgun example -=============== - -This example demonstrates how to create an EM Railgun input deck. \n -LS-DYNA version : ls-dyna_smp_d_R13.0_365-gf8a97bda2a_winx64_ifort190.exe -""" - -import os -import sys - -from ansys.dyna.core.pre.dynasolution import DynaSolution -from ansys.dyna.core.pre.dynaem import ( - DynaEM, - Circuit, - CircuitType, - SegmentSet, - NodeSet, - Curve, - SolidPart, - SolidFormulation, - EMContact, - BEMSOLVER, - FEMSOLVER, -) -from ansys.dyna.core.pre.dynamaterial import MatElastic, MatRigid, EMMATTYPE -from em_railgun_data import * -from ansys.dyna.core.pre import examples -# sphinx_gallery_thumbnail_path = '_static/pre/em/railgun.png' - -hostname = "localhost" -if len(sys.argv) > 1: - hostname = sys.argv[1] - -solution = DynaSolution(hostname) -fns = [] -path = examples.em_railgun + os.sep -fns.append(path + "em_railgun.k") -solution.open_files(fns) -solution.set_termination(termination_time=3e-4) -solution.create_database_binary(dt=5e-6) - -railgun = DynaEM() -solution.add(railgun) - -railgun.analysis.set_timestep(timestep=5e-6) -railgun.analysis.set_solver_bem(solver=BEMSOLVER.PCG) -railgun.analysis.set_solver_fem(solver=FEMSOLVER.DIRECT_SOLVER, relative_tol=1e-3) - -circuit = Circuit( - circuit_type=CircuitType.IMPOSED_CURRENT_VS_TIME, - loadcurve=Curve(x=[0, 8e-5, 2e-4, 4e-4, 6e-4, 1e-3], y=[0, 350, 450, 310, 230, 125], sfo=2e6), -) -circuit.set_current( - current=SegmentSet(cur), current_inlet=SegmentSet(inlet), current_outlet=SegmentSet(outlet) -) -railgun.add(circuit) - -matelastic = MatElastic(mass_density=2.64e-3, young_modulus=9.7e10, poisson_ratio=0.31) -matelastic.set_electromagnetic_property(material_type=EMMATTYPE.CONDUCTOR, initial_conductivity=25) -matrigid = MatRigid( - mass_density=2.64e-3, - young_modulus=9.7e10, - poisson_ratio=0.31, - center_of_mass_constraint=1, - translational_constraint=7, - rotational_constraint=7, -) -matrigid.set_electromagnetic_property(material_type=EMMATTYPE.CONDUCTOR, initial_conductivity=25) - -coil = SolidPart(1) -coil.set_material(matelastic) -coil.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT) -railgun.parts.add(coil) - -workpiece1 = SolidPart(2) -workpiece1.set_material(matrigid) -workpiece1.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT) -railgun.parts.add(workpiece1) - -workpiece2 = SolidPart(3) -workpiece2.set_material(matrigid) -workpiece2.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT) -railgun.parts.add(workpiece2) - -railgun.boundaryconditions.create_spc(NodeSet(spc1), tx=False, ty=False, rz=False, death=0) -railgun.boundaryconditions.create_spc(NodeSet(spc2), tx=False, ty=False, rz=False, death=0) - -contact = EMContact() -railgun.contacts.add(contact) - -railgun.set_rogowsky_coil_to_output_current(SegmentSet(cur)) -railgun.create_em_database_globalenergy(outlv=1) - -railgun.create_em_output(mats=2, matf=2, sols=2, solf=2) - -solution.save_file() From c80619197b7d20bd9cff9a5a58ffa78063cf7c87 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Mon, 3 Jul 2023 16:00:27 +0200 Subject: [PATCH 08/13] docs: solving vale issues --- doc/source/getting-started/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/source/getting-started/index.rst b/doc/source/getting-started/index.rst index 25262906ab..af00be885a 100644 --- a/doc/source/getting-started/index.rst +++ b/doc/source/getting-started/index.rst @@ -5,7 +5,7 @@ Getting started Installation ************ -Python Module +Python module ~~~~~~~~~~~~~ The ``ansys.dyna.core`` package currently supports Python 3.8 through @@ -19,7 +19,7 @@ Install the latest release from pip install ansys-dyna-core Alternatively, install the latest from -`PyDYNA GitHub `_ via: +`PyDyna GitHub `_ via: .. code:: console @@ -41,12 +41,12 @@ after restarting the Python kernel. Offline installation ~~~~~~~~~~~~~~~~~~~~ If you lack an internet connection on your install machine, the recommended way -of installing PyDYNA is downloading the wheelhouse archive from the +of installing PyDyna is downloading the wheelhouse archive from the `Releases Page `_ for your corresponding machine architecture. Each wheelhouse archive contains all the Python wheels necessary to install -PyDYNA from scratch on Windows and Linux for Python 3.8 through 3.11. You can install +PyDyna from scratch on Windows and Linux for Python 3.8 through 3.11. You can install this on an isolated system with a fresh Python or on a virtual environment. For example, on Linux with Python 3.8, unzip it and install it with the following: @@ -62,4 +62,4 @@ install using the preceding command. Consider installing using a `virtual environment `_. .. include:: ../../../docker/pre/README.rst -.. include:: ../../../docker/solver/README.rst \ No newline at end of file +.. include:: ../../../docker/solver/README.rst From 76da9965b6ba569a2a00569a77b7f9f9c13f7e2c Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 4 Jul 2023 09:20:40 +0200 Subject: [PATCH 09/13] docs: ignore autoapi folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b6429eebcb..a3bd2f86c1 100644 --- a/.gitignore +++ b/.gitignore @@ -164,3 +164,4 @@ cython_debug/ # Ignore rendered examples doc/source/examples/ doc/source/API/_autosummary/ +doc/source/autoapi \ No newline at end of file From 54c1b670bc8a57212bf35243600334845bd795ac Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 4 Jul 2023 09:20:55 +0200 Subject: [PATCH 10/13] docs: allow no-docstring objects --- doc/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 25c2ff31c9..d32f0de814 100755 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -50,7 +50,7 @@ # general "GL06", # Found unknown section "GL07", # Sections are in the wrong order. - "GL08", # The object does not have a docstring + # "GL08", # The object does not have a docstring "GL09", # Deprecation warning should precede extended summary "GL10", # reST directives {directives} must be followed by two colons # Summary From a053911eb87a68734f49085485cd33624dbbf5ef Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 4 Jul 2023 10:45:33 +0200 Subject: [PATCH 11/13] docs: improvements --- doc/source/conf.py | 2 +- doc/source/getting-started/index.rst | 6 ++++++ doc/source/user-guide/index.rst | 9 --------- docker/pre/README.rst | 2 +- docker/solver/README.rst | 2 +- examples/Airbag/airbag_deploy.py | 15 +++++++-------- examples/Airbag/airbag_post.py | 1 - examples/Explicit/belted_dummy.py | 3 +-- examples/Implicit/camry_rc.py | 13 +++++++------ examples/NVH/frf_plate_damping.py | 5 ++--- examples/Thermal/thermal_stress.py | 3 +-- src/ansys/dyna/core/pre/launcher.py | 24 ++++++++++++++++-------- 12 files changed, 43 insertions(+), 42 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index d32f0de814..264acad35a 100755 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -33,7 +33,7 @@ # Intersphinx mapping intersphinx_mapping = { - "python": ("https://docs.python.org/dev", None), + "python": ("https://docs.python.org/3", None), "numpy": ("https://numpy.org/devdocs", None), "matplotlib": ("https://matplotlib.org/stable", None), "imageio": ("https://imageio.readthedocs.io/en/stable", None), diff --git a/doc/source/getting-started/index.rst b/doc/source/getting-started/index.rst index af00be885a..57ac5d6438 100644 --- a/doc/source/getting-started/index.rst +++ b/doc/source/getting-started/index.rst @@ -63,3 +63,9 @@ Consider installing using a `virtual environment `_. .. include:: ../../../docker/pre/README.rst .. include:: ../../../docker/solver/README.rst + +.. LINKS +.. _pydyna_pypi: https://pypi.org/projects/ansys-dyna-core/ +.. _pydyna_releases: https://github.com/ansys/pydyna/releases +.. _pydyna_issues: https://github.com/ansys/pydyna/issues +.. _using_venv: https://docs.python.org/3/library/venv.html \ No newline at end of file diff --git a/doc/source/user-guide/index.rst b/doc/source/user-guide/index.rst index eccbf28f7d..0ad53c787d 100644 --- a/doc/source/user-guide/index.rst +++ b/doc/source/user-guide/index.rst @@ -26,12 +26,3 @@ leaving a Python environment. Visit the `DPF-Post Documentation `_ for a detailed description of the package - -.. toctree:: - :hidden: - - pydyna_pre - pydyna_solver - pydyna_post - - diff --git a/docker/pre/README.rst b/docker/pre/README.rst index e2f1b76171..eeeccf4e14 100644 --- a/docker/pre/README.rst +++ b/docker/pre/README.rst @@ -1,5 +1,5 @@ Build pydyna-pre service docker container -========================================= +::::::::::::::::::::::::::::::::::::::::: The pydyna-pre service Docker containers can be easily built by following these steps. diff --git a/docker/solver/README.rst b/docker/solver/README.rst index 9a44a1d0b3..b29bcd6f34 100644 --- a/docker/solver/README.rst +++ b/docker/solver/README.rst @@ -1,5 +1,5 @@ Build pydyna-solver service docker container -============================================ +:::::::::::::::::::::::::::::::::::::::::::: The pydyna-solver service Docker containers can be easily built by following these steps. diff --git a/examples/Airbag/airbag_deploy.py b/examples/Airbag/airbag_deploy.py index 85249d01da..f06f4fe5d1 100644 --- a/examples/Airbag/airbag_deploy.py +++ b/examples/Airbag/airbag_deploy.py @@ -1,5 +1,4 @@ """ -.. _ref_airbag_deploy: Airbag deploy example --------------------- @@ -65,7 +64,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Dynasolution class is like a workflow orchestrator. # It inherits methods from other classes and helps create a complete workflow. -# "set_termination" method here is used to set the termination time to 0.03 in *CONTROL_TERMINATION. +# "set_termination" method here is used to set the termination time to 0.03 in *CONTROL_TERMINATION*. # DynaMech class automatically generates the common control cards used in # explicit problems. CONTROL_ACCURACY, CONTACT, BULK VISCOCITY, CONTACT # are all automatically generated @@ -75,8 +74,8 @@ airbag_solution.add(airbagdeploy) ############################################################################### -# Define *AIRBAG_SIMPLE_AIRBAG_MODEL -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define *AIRBAG_SIMPLE_AIRBAG_MODEL* +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # DynaMech class has Airbag function that can be used to create this keyword. # LSDYNA has many different AIRBAG models. Only SIMPLE_AIRBAG_MODEL is supported # by pydyna at this moment. Please contact us if there is an urgent need for other @@ -95,16 +94,16 @@ airbagdeploy.add(airbag) ############################################################################### -# Define *RIGIDWALL_PLANAR -# ~~~~~~~~~~~~~~~~~~~~~~~~ +# Define *RIGIDWALL_PLANAR* +# ~~~~~~~~~~~~~~~~~~~~~~~~~ # Infinite planar rigidwall is generated by defining the coordinates of the heat vector # and the tail vector of the plane. rigidwall = RigidwallPlanar(Point(0, 0, 0), Point(0, 1, 0), coulomb_friction_coefficient=0.5) airbagdeploy.add(rigidwall) ############################################################################### -# Define *CONTACT_NODES_TO_SURFACE -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define *CONTACT_NODES_TO_SURFACE* +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # A contact NODES_TO_SURFACE is defined here by passing a master set and a slave part set. contact = Contact(category=ContactCategory.NODES_TO_SURFACE) diff --git a/examples/Airbag/airbag_post.py b/examples/Airbag/airbag_post.py index c2a3ee29e7..bad62ba22a 100644 --- a/examples/Airbag/airbag_post.py +++ b/examples/Airbag/airbag_post.py @@ -1,5 +1,4 @@ """ -.. _ref_airbag_deploy_post: Airbag deploy post processing example ------------------------------------- diff --git a/examples/Explicit/belted_dummy.py b/examples/Explicit/belted_dummy.py index 01b9385099..936f859b72 100644 --- a/examples/Explicit/belted_dummy.py +++ b/examples/Explicit/belted_dummy.py @@ -1,5 +1,4 @@ """ -.. _ref_belted_dummy: Belted dummy example ==================== @@ -61,7 +60,7 @@ # Start the Solution workflow # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # NODES and ELEMENTS are read in from the "belted_dummy.k" file. This file also has the -# *PART defined in it but the section and material fields are empty to begin with +# *PART* defined in it but the section and material fields are empty to begin with fns = [] path = examples.belted_dummy + os.sep diff --git a/examples/Implicit/camry_rc.py b/examples/Implicit/camry_rc.py index 8619798df1..aee61ddd83 100644 --- a/examples/Implicit/camry_rc.py +++ b/examples/Implicit/camry_rc.py @@ -1,5 +1,4 @@ """ -.. _ref_implicit: Implicit Example ===================== @@ -189,10 +188,10 @@ ) ############################################################################### -# Assining Section and Material Properties -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Assigning Section and Material Properties +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Once all the materials are explicitly defined, these material IDs needs to be cross-referenced -# in the *PART card. set_material() method is used for this. Since many parts share common materials +# in the *PART* card. set_material() method is used for this. Since many parts share common materials # the assignment happens within a loop. While within the loop, set_element_formulation() method # is called to assign the elform for the beam and the shell elements. Accordingly either the beam # diameter or the shell thickness is also defined. To identify the part ID that has a particular material type @@ -253,7 +252,7 @@ # Spotwelds and Nodal Rigid Bodies # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Again, camry_rc_data.py contains the predefined node pairs and node sets required for -# *CONSTRAINED_SPOTWELD and *CONSTRAINED_NODAL_RIGID_BODY definitions. We are looping through +# *CONSTRAINED_SPOTWELD* and *CONSTRAINED_NODAL_RIGID_BODY* definitions. We are looping through # these lists to generate the appropriate keywords. for sw in spotweld: camry.constraints.create_spotweld(nodeid1=sw[0], nodeid2=sw[1]) @@ -265,11 +264,13 @@ # Define Contacts # ~~~~~~~~~~~~~~~ # There are three Contacts defined in this model. +# # 1. Automatic Single surface contact for the BIW self contact # 2. Surface to Surface Contact between the platen and the BIW # 3. Tied contact for the Spotweld beams +# # The ContactSurface() method here sets the SSTYPE and MSTYPE. -# PartSet() method accepts the name of a list and converts it to *PART_SET_LIST. +# PartSet() method accepts the name of a list and converts it to *PART_SET_LIST*. # Notice how the contact type and category can be used to create the three # different type of contacts for this model. selfcontact = Contact(type=ContactType.AUTOMATIC) diff --git a/examples/NVH/frf_plate_damping.py b/examples/NVH/frf_plate_damping.py index 4063a024cc..c335336575 100644 --- a/examples/NVH/frf_plate_damping.py +++ b/examples/NVH/frf_plate_damping.py @@ -1,5 +1,4 @@ """ -.. _ref_frf: FRF for a rectangular plate =========================== @@ -44,7 +43,7 @@ ############################################################################### # Import the initial mesh data(nodes and elements) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Mesh data is imported which includes the *NODE, *ELEMENT_ and *PART cards predefined +# Mesh data is imported which includes the *NODE*, *ELEMENT_* and *PART* cards predefined fns = [] path = examples.nvh_frf_plate_damping + os.sep fns.append(path + "frf_plate_damping.k") @@ -69,7 +68,7 @@ ############################################################################### # Frequency Domain Cards # ~~~~~~~~~~~~~~~~~~~~~~ -# *FREQUENCY_DOMAIN_FRF is used to compute the frequency response function due to nodal excitations. +# *FREQUENCY_DOMAIN_FRF* is used to compute the frequency response function due to nodal excitations. # In this case a base velocity is define as an input at node 131. The base acceleration response is measured at # nodes 131 and 651. The max natural frequency employed in FRF is limited to 2000Hz. fd = FrequencyDomain() diff --git a/examples/Thermal/thermal_stress.py b/examples/Thermal/thermal_stress.py index ae3e6b81d6..f8a9e60f55 100644 --- a/examples/Thermal/thermal_stress.py +++ b/examples/Thermal/thermal_stress.py @@ -1,5 +1,4 @@ """ -.. _ref_thermal_stress: Thermal stress example ====================== @@ -43,7 +42,7 @@ # Start the Solution workflow # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # NODES and ELEMENTS are read in from the "thermal_stress.k" file. This file also has the -# *PART defined in it but the section and material fields are empty to begin with +# *PART* defined in it but the section and material fields are empty to begin with fns = [] path = examples.thermal_stress + os.sep fns.append(path + "thermal_stress.k") diff --git a/src/ansys/dyna/core/pre/launcher.py b/src/ansys/dyna/core/pre/launcher.py index fdb14d8474..cf6f1f881a 100644 --- a/src/ansys/dyna/core/pre/launcher.py +++ b/src/ansys/dyna/core/pre/launcher.py @@ -21,12 +21,17 @@ def check_ports(port_range, ip="localhost"): def port_in_use(port, host=LOCALHOST): - """Returns True when a port is in use at the given host. - Must actually "bind" the address. Just checking if we can create + """ + Returns ``True`` when a port is in use at the given host. + + Notes + ----- + Must actually "bind" the address. Just checking if we can create a socket is insufficient as it's possible to run into permission errors like: - - An attempt was made to access a socket in a way forbidden by its - access permissions. + + "An attempt was made to access a socket in a way forbidden by its + access permissions." """ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: try: @@ -37,18 +42,19 @@ def port_in_use(port, host=LOCALHOST): def launch_grpc(port=DYNAPRE_DEFAULT_PORT, ip=LOCALHOST, server_path=None) -> tuple: # pragma: no cover - """Start kwserver locally in gRPC mode. + """ + Start kwserver locally in gRPC mode. + Parameters ---------- port : int - Port to launch PyDyna gRPC on. Final port will be the first + Port to launch PyDyna gRPC on. Final port will be the first port available after (or including) this port. Returns ------- int Returns the port number that the gRPC instance started on. - """ LOG.debug("Starting 'launch_kwserver'.") @@ -86,7 +92,9 @@ def launch_dynapre( port=50051, ip="localhost", ): - """Start kwserver locally. + """ + Start kwserver locally. + Parameters ---------- port : int From ea340ef8fd8f15584a368c2d3e8143a9598e50ac Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 4 Jul 2023 10:50:53 +0200 Subject: [PATCH 12/13] fix: style issues --- doc/source/getting-started/index.rst | 2 +- src/ansys/dyna/core/pre/launcher.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/getting-started/index.rst b/doc/source/getting-started/index.rst index 57ac5d6438..250be096ef 100644 --- a/doc/source/getting-started/index.rst +++ b/doc/source/getting-started/index.rst @@ -12,7 +12,7 @@ The ``ansys.dyna.core`` package currently supports Python 3.8 through Python 3.10 on Windows, Mac OS, and Linux. Install the latest release from -`PyPi `_ with: +`PyPI `_ with: .. code:: console diff --git a/src/ansys/dyna/core/pre/launcher.py b/src/ansys/dyna/core/pre/launcher.py index cf6f1f881a..bfd2e1c210 100644 --- a/src/ansys/dyna/core/pre/launcher.py +++ b/src/ansys/dyna/core/pre/launcher.py @@ -44,7 +44,7 @@ def port_in_use(port, host=LOCALHOST): def launch_grpc(port=DYNAPRE_DEFAULT_PORT, ip=LOCALHOST, server_path=None) -> tuple: # pragma: no cover """ Start kwserver locally in gRPC mode. - + Parameters ---------- port : int From 2500a06d5db0264573e60d9515b036190c31e91c Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 4 Jul 2023 10:53:50 +0200 Subject: [PATCH 13/13] docs: comment post example --- examples/Airbag/airbag_post.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/Airbag/airbag_post.py b/examples/Airbag/airbag_post.py index bad62ba22a..875771256e 100644 --- a/examples/Airbag/airbag_post.py +++ b/examples/Airbag/airbag_post.py @@ -18,39 +18,39 @@ # Load the model and print the contents of the model. All parts in the model are shell parts. # Model info lists the result components as well as the number of states available in the d3plot # -ds = dpf.DataSources() +""" ds = dpf.DataSources() ds.set_result_file_path(r'D:\PYDYNA_BETA_V.0.1\example-data\pydyna\Airbag\d3plot', 'd3plot') model = dpf.Model(ds) -print(model) +print(model) """ ############################################################################### # Let's extract the stress on all the parts. The stress field container is scoped to all time frequencies # so as to be able to animate the change in stress on the airbag fabric. # -stress = model.results.stress.on_all_time_freqs() +""" stress = model.results.stress.on_all_time_freqs() stress.inputs.data_sources(ds) stress.inputs.requested_location.connect("Nodal") -fieldsStr = stress.outputs.fields_container() +fieldsStr = stress.outputs.fields_container()""" ############################################################################### # Since the shell stress is reported at three through thickness points as default # in the d3plot file, the next few lines depicts how the stress # can be extracted on the mid integration point. # -shell_layer_extract = dpf.operators.utility.change_shell_layers() +""" shell_layer_extract = dpf.operators.utility.change_shell_layers() shell_layer_extract.inputs.fields_container.connect(fieldsStr) shell_layer_extract.inputs.e_shell_layer.connect(dpf.common.shell_layers.mid.value) -fields_top = shell_layer_extract.outputs.fields_container_as_fields_container() +fields_top = shell_layer_extract.outputs.fields_container_as_fields_container() """ ############################################################################### # Plot the deformed state at 9ms # -N = fields_top[19] +""" N = fields_top[19] D = model.results.displacement(time_scoping=[19]).eval() -N.plot(deform_by=D[0],show_edges=False) +N.plot(deform_by=D[0],show_edges=False) """ ############################################################################### # Finally display the stress field and set the mesh to deform by the displacement of the nodes. # -disp = model.results.displacement.on_all_time_freqs.eval() -fields_top.animate(deform_by=disp,show_edges=False) \ No newline at end of file +""" disp = model.results.displacement.on_all_time_freqs.eval() +fields_top.animate(deform_by=disp,show_edges=False) """ \ No newline at end of file