Skip to content

Commit c65f3b1

Browse files
feat: run against Docker container (#184)
* feat: run against Docker container * try to fix testing problem * fix testing problem * try to fix downloading problem * update readme.rst files * update README..rst * update README.rst * Apply suggestions from code review * Apply suggestions from code review --------- Co-authored-by: Zhanqun Zhang <[email protected]> Co-authored-by: zhangzhanqun <[email protected]>
1 parent 57c4fc6 commit c65f3b1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+904
-763
lines changed

.github/workflows/ci_cd.yml

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,8 @@ jobs:
134134

135135
tests:
136136
name: Testing
137-
runs-on: ${{ matrix.os }}
137+
runs-on: ubuntu-latest
138138
needs: [smoke-tests]
139-
strategy:
140-
fail-fast: false
141-
matrix:
142-
os: [windows-latest, ubuntu-latest]
143-
144139
steps:
145140
- name: Checkout repository
146141
uses: actions/checkout@v3
@@ -152,35 +147,39 @@ jobs:
152147
cache: 'pip'
153148
cache-dependency-path: 'pyproject.toml'
154149

150+
- name: Login to GitHub Container Registry
151+
uses: docker/login-action@v2
152+
with:
153+
registry: ghcr.io
154+
username: ${{ github.actor }}
155+
password: ${{ secrets.GITHUB_TOKEN }}
156+
157+
- name: LS-DYNA Keyword server activation
158+
run: |
159+
docker pull ghcr.io/ansys/ls-pre:latest
160+
docker run -d --name kw_server -p 50051:50051 ghcr.io/ansys/ls-pre:latest && echo "Keyword server active on port 50051."
161+
155162
- name: Install ansys-dyna-core (with test requirements)
156163
run: |
157164
pip install -e .[tests]
158165
159-
- name: Run tests (Windows)
160-
if: runner.os == 'Windows'
166+
- name: Run tests
161167
run: |
162-
Start-Job -ScriptBlock {cd ${{ github.workspace }}\src\ansys\dyna\core\pre\Server\;python kwserver.py >> server_output.txt}
163-
Start-Sleep -Seconds 10
164168
pytest
165169
166-
- name: Run tests (Linux)
167-
if: runner.os == 'Linux'
170+
- name: Extract the server logs
171+
if: always()
168172
run: |
169-
cd src/ansys/dyna/core/pre/Server
170-
python kwserver.py > server_output.txt &
171-
sleep 10
172-
cd -
173-
pytest
173+
docker logs kw_server > server_output.txt
174174
175175
- name: Upload the server logs
176176
if: always()
177177
uses: actions/upload-artifact@v3
178178
with:
179-
name: server-logs-${{ runner.os }}
180-
path: src/ansys/dyna/core/pre/Server/server_output.txt
179+
name: server_output.txt
180+
path: server_output.txt
181181

182182
- name: Upload coverage results
183-
if: runner.os == 'Linux'
184183
uses: actions/upload-artifact@v3
185184
with:
186185
name: coverage-html

README.rst

Lines changed: 105 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ build up ansys-dyna input deck, submit to solver and finally post processing the
77

88
Project Overview
99
----------------
10-
There are 3 related packages here, pre and solver are all under the ansys/dyna/ directory,
10+
There are 3 related packages here, pre and solver are all under the ansys/pydyna/ directory,
1111
while pyDPF is used for post-processing.
1212

1313
pre contains highly abstracted APIs for setting up a LS-DYNA input deck, so far,
@@ -35,8 +35,33 @@ leaving a Python environment.
3535
Visit the `DPF-Post Documentation <https://postdocs.pyansys.com>`_ for a
3636
detailed description of the package.
3737

38-
Installation
39-
------------
38+
Install PyDyna-Pre Docker
39+
-------------------------
40+
41+
Launching the PyDyna-Pre service locally, the only requirement is that:
42+
43+
* Docker is installed on your machine.
44+
45+
.. caution::
46+
47+
The PyDyna-Pre service is currently available only as a Linux Docker image.
48+
make sure that your Docker engine is configured to run Linux Docker images.
49+
50+
Please refer to ``docker/README.rst`` to install PyDyna-Pre service docker container
51+
52+
Install PyDyna-Solver Docker
53+
----------------------------
54+
55+
Once pydyna is installed, the docker-compose.yml file to build and launch the dyna solver docker can be located
56+
under ``docker``. The yml file can be copied locally. To run the docker the following command can be used
57+
58+
.. code:: bash
59+
60+
docker-compose up
61+
62+
63+
Install the package
64+
-------------------
4065

4166
PyDyna has three installation modes: user, developer, and offline.
4267

@@ -98,31 +123,21 @@ archive from the `Releases Page <https://github.com/pyansys/pydyna/releases>`_ f
98123
corresponding machine architecture.
99124

100125
Each wheelhouse archive contains all the Python wheels necessary to install PyDyna from scratch on Windows
101-
and Linux, from Python 3.7 to 3.10. You can install this on an isolated system with a fresh Python
126+
and Linux, from Python 3.6,3.8 and 3.9. You can install this on an isolated system with a fresh Python
102127
installation or on a virtual environment.
103128

104-
For example, on Linux with Python 3.7, unzip the wheelhouse archive and install it with:
129+
For example, on Linux with Python 3.8, unzip the wheelhouse archive and install it with:
105130

106131
.. code:: bash
107132
108-
unzip ansys-dyna-core-v0.3.dev0-wheelhouse-Linux-3.7.zip wheelhouse
133+
unzip ansys-dyna-core-v0.3.dev0-wheelhouse-Linux-3.8.zip wheelhouse
109134
pip install ansys-dyna-core -f wheelhouse --no-index --upgrade --ignore-installed
110135
111136
If you are on Windows with Python 3.9, unzip the corresponding wheelhouse to a wheelhouse directory
112137
and install using the preceding command.
113138

114139
Consider installing using a `virtual environment <https://docs.python.org/3/library/venv.html>`_.
115140

116-
Install Solver Docker
117-
^^^^^^^^^^^^^^^^^^^^^
118-
119-
Once pydyna is installed, the docker-compose.yml file to build and launch the dyna solver docker can be located
120-
under /src/ansys/dyna/core/solver/. The yml file can be copied locally. To run the docker the following command can be used
121-
122-
.. code:: bash
123-
124-
docker-compose up
125-
126141
Documentation
127142
-------------
128143
For comprehesive information on PyDyna, see the latest release
@@ -138,28 +153,80 @@ Here is a basic pre-processing example:
138153

139154
.. code:: python
140155
141-
from ansys.dyna.core.pre.dynasolution import *
142-
from ansys.dyna.core.pre.dynaiga import *
143-
from ansys.dyna.core.pre.dynamaterial import *
144-
hostname = "localhost"
145-
iga_solution = DynaSolution(hostname)
146-
fns = []
147-
path = os.getcwd() + os.sep + "input" + os.sep + "iga_sample" + os.sep
148-
fns.append(path + "maino.k")
149-
fns.append(path + "rkrwelds.key")
150-
fns.append(path + "27parts.key")
151-
iga_solution.open_files(fns)
152-
iga_solution.set_termination(20)
153-
iga_solution.create_database_binary(dt=0.1)
154-
iga = DynaIGA()
155-
iga_solution.add(iga)
156-
iga.set_timestep(timestep_size_for_mass_scaled=-0.0004)
157-
...
158-
selfcontact = Contact(type=ContactType.AUTOMATIC)
159-
selfcontact.set_friction_coefficient(static=0.2)
160-
surf1=ContactSurface(PartSet(igaparts))
161-
selfcontact.set_slave_surface(surf1)
162-
iga_solution.save_file()
156+
import os
157+
import sys
158+
from ansys.dyna.core.pre.dynasolution import DynaSolution
159+
from ansys.dyna.core.pre.dynaicfd import (
160+
DynaICFD,
161+
ICFDAnalysis,
162+
MatICFD,
163+
ICFDPart,
164+
ICFDDOF,
165+
Curve,
166+
ICFDVolumePart,
167+
MeshedVolume,
168+
)
169+
from ansys.dyna.core.pre import examples
170+
# sphinx_gallery_thumbnail_path = '_static/pre/icfd/cylinderflow.png'
171+
172+
hostname = "localhost"
173+
if len(sys.argv) > 1:
174+
hostname = sys.argv[1]
175+
176+
icfd_solution = DynaSolution(hostname)
177+
# Import the initial mesh data(nodes and elements)
178+
fns = []
179+
path = examples.cylinder_flow + os.sep
180+
fns.append(path + "cylinder_flow.k")
181+
icfd_solution.open_files(fns)
182+
# Set total time of simulation
183+
icfd_solution.set_termination(termination_time=100)
184+
185+
icfd = DynaICFD()
186+
icfd_solution.add(icfd)
187+
188+
icfdanalysis = ICFDAnalysis()
189+
icfdanalysis.set_timestep()
190+
icfd.add(icfdanalysis)
191+
192+
# define model
193+
mat = MatICFD(flow_density=1.0, dynamic_viscosity=0.005)
194+
195+
part_inflow = ICFDPart(1)
196+
part_inflow.set_material(mat)
197+
part_inflow.set_prescribed_velocity(dof=ICFDDOF.X, motion=Curve(x=[0, 10000], y=[1, 1]))
198+
part_inflow.set_prescribed_velocity(dof=ICFDDOF.Y, motion=Curve(x=[0, 10000], y=[0, 0]))
199+
icfd.parts.add(part_inflow)
200+
201+
part_outflow = ICFDPart(2)
202+
part_outflow.set_material(mat)
203+
part_outflow.set_prescribed_pressure(pressure=Curve(x=[0, 10000], y=[0, 0]))
204+
icfd.parts.add(part_outflow)
205+
206+
part_symmetric = ICFDPart(3)
207+
part_symmetric.set_material(mat)
208+
part_symmetric.set_free_slip()
209+
icfd.parts.add(part_symmetric)
210+
211+
part_wall = ICFDPart(4)
212+
part_wall.set_material(mat)
213+
part_wall.set_non_slip()
214+
part_wall.compute_drag_force()
215+
part_wall.set_boundary_layer(number=3)
216+
icfd.parts.add(part_wall)
217+
218+
partvol = ICFDVolumePart(surfaces=[1, 2, 3, 4])
219+
partvol.set_material(mat)
220+
icfd.parts.add(partvol)
221+
# define the volume space that will be meshed,The boundaries
222+
# of the volume are the surfaces "spids"
223+
meshvol = MeshedVolume(surfaces=[1, 2, 3, 4])
224+
icfd.add(meshvol)
225+
226+
icfd_solution.create_database_binary(dt=1)
227+
icfd_solution.save_file()
228+
229+
For more examples, visit https://dyna.docs.pyansys.com/version/stable/examples/index.html
163230

164231
Here is a basic solving example:
165232

docker/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ RUN pip3 install grpcio grpcio-tools protobuf
1616

1717
RUN python -m grpc_tools.protoc --python_out=./linux-binaries --grpc_python_out=./linux-binaries -I./linux-binaries ./linux-binaries/kwprocess.proto
1818

19+
EXPOSE 50051
20+
1921
CMD ["python3", "./linux-binaries/kwserver.py"]

docker/README.rst

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Create your own pydyna-pre service docker container
2-
=================================================
2+
===================================================
33

44
The pydyna-pre service Docker containers can be easily built by following
55
these steps.
@@ -19,7 +19,7 @@ Prerequisites
1919
* Download the latest release artifacts for the Linux
2020
Docker container. You can do this as follows:
2121

22-
* Latest Linux artifacts: `linux-binaries.zip <https://github.com/ansys/pydyna/releases/latest/download/linux-binaries.zip>`_
22+
* Latest Linux artifacts: `linux-binaries.zip <https://github.com/ansys/pydyna/releases/download/v0.2.1/linux-binaries.zip>`_
2323

2424
* Move these ``.zip`` files to the current location (i.e. ``<repository-root-folder>/docker``).
2525

@@ -33,7 +33,12 @@ In order to build your images, follow the next instructions:
3333

3434
.. code:: bash
3535
36-
docker build -t ls-pre .
36+
docker build -t ghcr.io/ansys/ls-pre:<DOCKER_IMAGE_TAG> -f <DOCKERFILE_NAME> .
37+
38+
Bear in mind that you will need to substitute the following entries in the previous command:
39+
40+
* ``<DOCKERFILE_NAME>``: this will be ``Dockerfile``
41+
* ``<DOCKER_IMAGE_TAG>``: this will be ``latest``
3742

3843
* Check that the image has been created successfully. You should see an output similar
3944
to this one when running the following command:
@@ -43,5 +48,23 @@ In order to build your images, follow the next instructions:
4348
docker images
4449
4550
>>> REPOSITORY TAG IMAGE ID CREATED SIZE
46-
>>> ls-pre *******-latest ............ X seconds ago 187MB
51+
>>> ghcr.io/ansys/ls-pre *******-latest ............ X seconds ago 188MB
4752
>>> ...... ...... ............ .............. ......
53+
54+
Run the image as a container
55+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56+
57+
* Run the following Docker command:
58+
59+
.. code:: bash
60+
61+
docker run -d -p 50051:50051 ghcr.io/ansys/ls-pre .
62+
63+
* Check that the image has been created successfully.
64+
65+
66+
.. code:: bash
67+
68+
69+
>>> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
70+
>>> 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

docker/docker-compose.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
version: "3.8"
2+
services:
3+
dyna:
4+
image: ghcr.io/pyansys/dynasolver:0.3
5+
networks:
6+
- dyna_internal
7+
deploy:
8+
replicas: 1
9+
volumes:
10+
- /rundir
11+
cap_add:
12+
- SYS_PTRACE
13+
ports:
14+
- target: 5000
15+
published: 5000
16+
mode: ingress
17+
user: mpirun
18+
entrypoint: ["/ansys_inc/server.py","dyna"]
19+
environment:
20+
- LSTC_LICENSE_SERVER=lvrpanda.ansys.com
21+
networks:
22+
dyna_internal:

src/ansys/dyna/core/pre/Server/kwprocess.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,7 @@ message SaveFileRequest {
11801180

11811181
message SaveFileReply {
11821182
int64 length = 1;
1183+
string outpath = 2;
11831184
}
11841185

11851186
message LoadFileRequest {

src/ansys/dyna/core/pre/Server/kwprocess_pb2.py

Lines changed: 280 additions & 280 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ansys/dyna/core/pre/Server/kwserver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def SaveFile(self, request, context):
104104
self.kwdproc.write(subsystems)
105105
self.fns.clear()
106106
print("Saved Successfully!")
107-
return kwprocess_pb2.SaveFileReply(length=1)
107+
return kwprocess_pb2.SaveFileReply(length=1,outpath=fn)
108108

109109
def CreateTimestep(self, request, context):
110110
tssfac = request.tssfac

src/ansys/dyna/core/pre/dynasolution.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ def upload(self, stub_, filename):
107107
chunks_generator = self.get_file_chunks(filename)
108108
response = stub_.Upload(chunks_generator)
109109

110-
def download(self, stub_, remote_name, local_name):
110+
def download(self, remote_name, local_name):
111111
"""Download files from server."""
112-
response = stub_.Download(DownloadRequest(url=remote_name))
112+
response = self.stub.Download(DownloadRequest(url=remote_name))
113113
with open(local_name, "wb") as f:
114114
for chunk in response:
115115
f.write(chunk.buffer)
@@ -294,4 +294,4 @@ def save_file(self):
294294
ret = self.stub.SaveFile(SaveFileRequest(name=self.mainname))
295295
msg = self.mainname + " is outputed..."
296296
logging.info(msg)
297-
return ret
297+
return ret.outpath

src/ansys/dyna/core/pre/kwprocess_pb2.py

Lines changed: 280 additions & 280 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)