Skip to content

Commit 1f5e8dd

Browse files
committed
Merge branch 'main' into release/0.3
2 parents d3d18f3 + e6ebc18 commit 1f5e8dd

25 files changed

+325
-70
lines changed

.github/dependabot.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ updates:
44
directory: "/" # Location of package manifests
55
insecure-external-code-execution: allow
66
schedule:
7-
interval: "daily"
7+
interval: "weekly"
88

99
- package-ecosystem: "github-actions"
1010
directory: "/"
1111
schedule:
12-
interval: "daily"
12+
interval: "weekly"

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ Usage
7777
=====
7878
Here is a basic preprocessing example:
7979

80-
Get the input file from "pydyna\\src\\ansys\\dyna\\core\\pre\\examples\\explicit\\ball_plate\\ball_plate.k"
80+
Get the input file from (``<repository-root-folder>/src/ansys/dyna/core/pre/examples/explicit/ball_plate/ball_plate.k``)
8181

82-
The follow example can be obtained from "pydyna\\examples\\Explicit\\ball_plate.py"
82+
The follow example can be obtained from (``<repository-root-folder>/examples/Explicit/ball_plate.py``)
8383

8484
.. code:: python
8585
@@ -164,7 +164,7 @@ The follow example can be obtained from "pydyna\\examples\\Explicit\\ball_plate.
164164
165165
Here is a basic solving example:
166166

167-
The follow example can be obtained from "pydyna\\examples\\solver\\ball_plate_solver.py"
167+
The follow example can be obtained from (``<repository-root-folder>/examples/solver/ball_plate_solver.py``)
168168

169169
.. code:: python
170170

docker/pre/README.rst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,22 @@ Prerequisites
2020

2121
* Ensure that Docker is installed on your machine. If you do not have Docker installed,
2222
see the `Docker website <https://www.docker.com>`_ for more information.
23+
24+
* If you are building the image on Windows, ensure that the Windows Subsystem for Linux (WSL)
25+
is installed. For installation information, see Microsoft's
26+
`Install Linux on Windows with WSL <https://learn.microsoft.com/en-us/windows/wsl/install>`_.
2327

2428
* Download the latest Linux release artifacts for the Linux Docker container:
25-
`linux-binaries.zip <https://github.com/ansys/pydyna/releases/download/v0.3.1/linux-binaries.zip>`_.
29+
`linux-binaries.zip <https://github.com/ansys/pydyna/releases/download/v0.3.4/linux-binaries.zip>`_.
2630

27-
* Move these ZIP files to the current location (``<repository-root-folder>/docker``).
31+
* Move this ZIP file to the current location (``<repository-root-folder>/docker/pre``).
2832

2933
Starting the docker container
3034
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3135

3236
There are two ways to start docker container.
3337

34-
1.bulid image and run container
38+
1.build image and run container
3539

3640

3741
Build the Docker image
@@ -74,7 +78,11 @@ Perform these steps to run the image as a container:
7478
7579
docker run -d -p 50051:50051 ghcr.io/ansys/ls-pre
7680
77-
#. Check that the image is running successfully.
81+
#. Check that the image is running successfully by running this command.
82+
83+
.. code:: bash
84+
85+
docker ps
7886
7987
Your output should look similar to this:
8088

docker/solver/README.rst

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,22 @@ Prerequisites
2525
`Install Linux on Windows with WSL <https://learn.microsoft.com/en-us/windows/wsl/install>`_.
2626

2727
* Download the latest Linux release artifacts for the Linux Docker container:
28-
`mppdyna_docker_centos7.zip <https://github.com/ansys/pydyna/releases/tag/v0.3.1/mppdyna_docker_centos7.zip>`_.
28+
`mppdyna_docker_centos7.zip <https://github.com/ansys/pydyna/releases/download/v0.3.4/mppdyna_docker_centos7.zip>`_.
2929

30-
* Move these ZIP files to a a local directory ``local_image_build_dir``.
30+
* Move this ZIP file to the current location (``<repository-root-folder>/docker/solver``) and unzip the mppdyna_docker_centos7.zip file.
3131

32+
The files in this folder should look similar to this:
33+
34+
.. code:: bash
35+
36+
>>> Dockerfile README.rst do_build docker-compose.yml docker_dir mpi mppdyna_docker_centos7.zip
3237
3338
Build the Docker image
3439
----------------------
3540

3641
Once all prerequisites are met, perform these steps to build the Docker image:
3742

38-
#. In your terminal, go to the ``local_image_build_dir`` directory.
43+
#. In your terminal, go to the ``pydyna/docker/solver`` directory.
3944
#. Run this Docker command:
4045

4146
.. code:: bash
@@ -71,9 +76,15 @@ Perform these steps to run the image as a container:
7176

7277
.. code:: bash
7378
74-
docker compose up
79+
docker compose up -d
80+
81+
#. Check that the image is running successfully by running this command.
82+
83+
.. code:: bash
7584
76-
#. Check that the image is running successfully.
85+
docker ps
86+
87+
Your output should look similar to this:
7788

7889
.. code:: bash
7990

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ classifiers = [
2727

2828
dependencies = [
2929
"ansys-dpf-core>=0.7.2",
30-
"ansys-api-dyna==0.2.0",
30+
"ansys-api-dyna==0.3.1",
3131
]
3232

3333
[project.optional-dependencies]
3434
tests = [
35-
"pyvista==0.40.1",
35+
"pyvista==0.41.1",
3636
"matplotlib==3.7.2",
3737
"numpy==1.25.2",
3838
"pytest==7.4.0",
@@ -49,24 +49,24 @@ doc = [
4949
"matplotlib==3.7.2",
5050
"imageio==2.31.1",
5151
"imageio-ffmpeg==0.4.8",
52-
"pyvista==0.40.1",
52+
"pyvista==0.41.1",
5353
"numpydoc==1.5.0",
54-
"Sphinx==7.1.1",
54+
"Sphinx==7.1.2",
5555
"sphinx-autobuild==2021.3.14",
5656
"sphinxcontrib-websupport==1.2.4",
5757
"pytest-sphinx==0.5.0",
5858
"sphinx-notfound-page==0.8.3",
5959
"sphinx-copybutton==0.5.2",
6060
"sphinx-gallery==0.13.0",
6161
"sphinx-autodoc-typehints==1.24.0",
62-
"ansys-sphinx-theme==0.10.0",
62+
"ansys-sphinx-theme==0.10.2",
6363
"pypandoc==1.11",
6464
"nbsphinx==0.9.2",
6565
"ipywidgets==8.1.0",
6666
"joblib==1.3.1",
6767
"scikit-learn==1.3.0",
6868
"ipython==8.14.0",
69-
"jupyterlab==4.0.3",
69+
"jupyterlab==4.0.4",
7070
"sphinx-jinja==2.0.2",
7171
"sphinx-autoapi==2.1.1",
7272
]

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

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,21 +113,22 @@ class Curve:
113113
114114
"""
115115

116-
def __init__(self, sfo=1, x=[], y=[], func=None):
116+
def __init__(self, sfo=1, x=[], y=[], func=None, title=""):
117117
self.sfo = sfo
118118
self.abscissa = x
119119
self.ordinate = y
120120
self.func = func
121+
self.title = title
121122

122123
def create(self, stub=None):
123124
"""Create a curve."""
124125
if stub is None:
125126
stub = DynaBase.get_stub()
126127
if self.func != None:
127-
ret = stub.CreateDefineCurveFunction(DefineCurveFunctionRequest(function=self.func))
128+
ret = stub.CreateDefineCurveFunction(DefineCurveFunctionRequest(function=self.func, title=self.title))
128129
else:
129130
ret = stub.CreateDefineCurve(
130-
DefineCurveRequest(sfo=self.sfo, abscissa=self.abscissa, ordinate=self.ordinate)
131+
DefineCurveRequest(sfo=self.sfo, abscissa=self.abscissa, ordinate=self.ordinate, title=self.title)
131132
)
132133
self.id = ret.id
133134
logging.info(f"Curve {self.id} defined...")
@@ -148,6 +149,32 @@ def create(self, stub):
148149
return self.id
149150

150151

152+
class Table2D:
153+
"""Define a table,a curve ID is specified for each value defined in the table."""
154+
155+
def __init__(self, title=""):
156+
self.title = title
157+
self.valuecurvelist = []
158+
159+
def append(self, value=0, curve=None):
160+
self.valuecurvelist.append((value, curve))
161+
162+
def create(self, stub=None):
163+
"""Create Table2D."""
164+
if stub is None:
165+
stub = DynaBase.get_stub()
166+
vls = []
167+
cvs = []
168+
for obj in self.valuecurvelist:
169+
vls.append(obj[0])
170+
cid = obj[1].create(stub)
171+
cvs.append(cid)
172+
ret = stub.CreateDefineTable2D(DefineTable2DRequest(title=self.title, values=vls, cids=cvs))
173+
self.id = ret.id
174+
logging.info(f"Table2D {self.id} defined...")
175+
return self.id
176+
177+
151178
class Point:
152179
"""Defines a point."""
153180

@@ -885,6 +912,33 @@ def create(self, stub):
885912
return self.id
886913

887914

915+
class NodeSetBox(BaseSet):
916+
"""include the nodes inside boxes.
917+
918+
Parameters
919+
----------
920+
boxes : list
921+
A list of BOX.
922+
"""
923+
924+
def __init__(self, boxes=[]):
925+
self.boxes = boxes
926+
self.type = "NODESETBOX"
927+
928+
def create(self, stub):
929+
"""Create a node set."""
930+
if len(self.boxes) <= 0:
931+
return 0
932+
boxids = []
933+
for box in self.boxes:
934+
boxid = box.create(stub)
935+
boxids.append(boxid)
936+
ret = stub.CreateNodeSet(NodeSetRequest(option="GENERAL", sid=0, genoption="BOX", entities=boxids))
937+
self.id = ret.id
938+
self.type = "NODESETBOX"
939+
return self.id
940+
941+
888942
class PartSet(BaseSet):
889943
"""Defines a set of parts with optional attributes."""
890944

@@ -1529,6 +1583,7 @@ def __init__(self, analysis_type=AnalysisType.IMPLICIT, initial_timestep_size=0)
15291583
self.defined_dynamic = False
15301584
self.defined_eigenvalue = False
15311585
self.defined_solution = False
1586+
self.defined_mass_matrix = False
15321587
self.imflag = analysis_type.value
15331588
self.dt0 = initial_timestep_size
15341589
self.stub = DynaBase.get_stub()
@@ -1640,6 +1695,10 @@ def set_solution(
16401695
self.maxref = stiffness_reformation_limit
16411696
self.abstol = absolute_convergence_tolerance
16421697

1698+
def set_consistent_mass_matrix(self):
1699+
"""Use the consistent mass matrix in implicit dynamics and eigenvalue solutions."""
1700+
self.defined_mass_matrix = True
1701+
16431702
def create(self):
16441703
"""Create an implicit analysis."""
16451704
if self.defined == False:
@@ -1662,6 +1721,8 @@ def create(self):
16621721
nsolver=self.nsolver, ilimit=self.ilimit, maxref=self.maxref, abstol=self.abstol
16631722
)
16641723
)
1724+
if self.defined_mass_matrix:
1725+
self.stub.CreateControlImplicitConsistentMass(ControlImplicitConsistentMassRequest(iflag=1))
16651726

16661727

16671728
class ThermalAnalysisType(Enum):

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

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,15 @@ def create(self):
669669
logging.info("EM Contact Created...")
670670

671671

672+
class EMRandlesLayer(Enum):
673+
DEFAULT = 0
674+
CURRENT_COLLECTOR_POSITIVE = 1
675+
POSITIVE_ELECTRODE = 2
676+
SEPARATOR = 3
677+
NEGATIVE_ELECTRODE = 4
678+
CURRENT_COLLECTOR_NEGATIVE = 5
679+
680+
672681
class Isopotential:
673682
"""Defines an isopotential.
674683
@@ -682,25 +691,29 @@ class Isopotential:
682691

683692
isopotlist = []
684693

685-
def __init__(self, set=None):
694+
def __init__(self, set=None, layer=EMRandlesLayer.DEFAULT):
686695
self.stub = DynaBase.get_stub()
687696
self.set = set
688697
self.id = 0
698+
self.rdltype = layer.value
689699

690700
def create(self):
691701
"""Create an isopotential."""
692-
isoinfo = [self.set.type, self.set.nodes]
702+
if self.set.type == "NODESETBOX":
703+
isoinfo = [self.set.type, self.set.boxes]
704+
else:
705+
isoinfo = [self.set.type, self.set.nodes]
693706
if isoinfo in Isopotential.isopotlist:
694707
pass
695708
id, settype = 0, 1
696709
if self.set is not None:
697710
id = self.set.create(self.stub)
698711
type = self.set.type
699-
if type == "NODESET":
712+
if type == "NODESET" or type == "NODESETBOX":
700713
settype = 2
701714
elif type == "SEGMENTSET":
702715
settype = 1
703-
ret = self.stub.CreateEMIsopotential(EMIsopotentialRequest(settype=settype, setid=id))
716+
ret = self.stub.CreateEMIsopotential(EMIsopotentialRequest(settype=settype, setid=id, rdltype=self.rdltype))
704717
self.id = ret.id
705718
logging.info(f"EM Isopotential {self.id} Created...")
706719
return self.id
@@ -732,3 +745,68 @@ def create(self):
732745
self.id = ret.id
733746
logging.info(f"EM Isopotential Rogo {self.id} Created...")
734747
return self.id
748+
749+
750+
class RandlesCellType(Enum):
751+
USER_DEFINED_EQUIVALENT_CIRCUIT_MODEL = -1
752+
RANDLES_CELL_0_ORDER = 0
753+
RANDLES_CELL_1_ORDER = 1
754+
RANDLES_CELL_2_ORDER = 2
755+
RANDLES_CELL_3_ORDER = 3
756+
757+
758+
class RandlesCell:
759+
"""Define parameters for a Randles Cell."""
760+
761+
def __init__(self, set=None):
762+
self.stub = DynaBase.get_stub()
763+
self.define_batmac = False
764+
765+
def set_batmac_model(
766+
self,
767+
cell_type=RandlesCellType.RANDLES_CELL_1_ORDER,
768+
cell_parts=None,
769+
area=2,
770+
cell_capacity=0,
771+
soc_conversion_factor=0,
772+
charge_init_state=0,
773+
circuit_parameter=None,
774+
constant_temperature=0,
775+
temperature_from_thermal_solver=False,
776+
add_heating_to_thermal_solver=False,
777+
):
778+
"""define the distributed Randles circuit parameters for a Randles cell when using the batmac model."""
779+
self.define_batmac = True
780+
self.rdltype = cell_type.value
781+
self.rdlarea = area
782+
self.psid = cell_parts
783+
self.q = cell_capacity
784+
self.cq = soc_conversion_factor
785+
self.socinit = charge_init_state
786+
self.prm = circuit_parameter
787+
self.temp = constant_temperature
788+
self.frther = temperature_from_thermal_solver
789+
self.r0toth = add_heating_to_thermal_solver
790+
791+
def create(self):
792+
"""Set parameter for Randles Cell."""
793+
if self.define_batmac:
794+
sid = 0
795+
if self.psid is not None:
796+
sid = self.psid.create(self.stub)
797+
ret = self.stub.CreateEMRandlesBatmac(
798+
EMRandlesBatmacRequest(
799+
rdltype=self.rdltype,
800+
rdlarea=self.rdlarea,
801+
psid=sid,
802+
q=self.q,
803+
cq=self.cq,
804+
socinit=self.socinit,
805+
chargedirparam=self.prm,
806+
temp=self.temp,
807+
frther=self.frther,
808+
r0toth=self.r0toth,
809+
)
810+
)
811+
self.id = ret.rdlid
812+
logging.info(f"EM Randles Batmac {self.id} Created...")

0 commit comments

Comments
 (0)