Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap CMATRIX for gRPC #584

Merged
merged 12 commits into from
Sep 10, 2021
4 changes: 2 additions & 2 deletions .ci/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ jobs:
strategy:
matrix:
MAPDL2021R1:
MAPDL.VERSION: 'v21.1.0'
MAPDL.VERSION: 'v21.1.1'
MAPDL2021R2:
MAPDL.VERSION: 'v21.2.0'
MAPDL.VERSION: 'v21.2.1'
steps:
- task: UsePythonVersion@0
inputs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:

env:
DISPLAY: ':99.0'
MAPDL_IMAGE: 'docker.pkg.github.com/pyansys/pymapdl/mapdl:v21.2.0'
MAPDL_IMAGE: 'docker.pkg.github.com/pyansys/pymapdl/mapdl:v21.2.1'
PYMAPDL_PORT: 32771 # default won't work on azure
PYMAPDL_START_INSTANCE: FALSE
PYANSYS_OFF_SCREEN: True
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly-doc-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:

env:
DISPLAY: ':99.0'
MAPDL_IMAGE: 'docker.pkg.github.com/pyansys/pymapdl/mapdl:v21.2.0'
MAPDL_IMAGE: 'docker.pkg.github.com/pyansys/pymapdl/mapdl:v21.2.1'
PYMAPDL_PORT: 32771 # default won't work on azure
PYMAPDL_START_INSTANCE: FALSE
PYANSYS_OFF_SCREEN: True
Expand Down
2 changes: 1 addition & 1 deletion ansys/mapdl/core/_commands/solution/analysis_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ def cmatrix(self, symfac="", condname="", numcond="", grndkey="",

This command does not support multiframe restarts.
"""
command = f"CMATRIX,{symfac},{condname},{numcond},{grndkey},{capname}"
command = f"CMATRIX,{symfac},'{condname}',{numcond},{grndkey},'{capname}'"
return self.run(command, **kwargs)

def cmsopt(self, cmsmeth="", nmode="", freqb="", freqe="", fbddef="",
Expand Down
3 changes: 2 additions & 1 deletion ansys/mapdl/core/mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
'*END': 'Create a function within python or run as non_interactive',
'/EOF': 'Unsupported command. Use ``exit`` to stop the server.',
'*ASK': 'Unsupported command. Use python ``input`` instead.',
'*IF': 'Use a python ``if`` or run as non_interactive'}
'*IF': 'Use a python ``if`` or run as non_interactive',
'CMATRIX': 'Use as non_interactive'}

PLOT_COMMANDS = ['NPLO', 'EPLO', 'KPLO', 'LPLO', 'APLO', 'VPLO', 'PLNS', 'PLES']
MAX_COMMAND_LENGTH = 600 # actual is 640, but seems to fail above 620
Expand Down
16 changes: 16 additions & 0 deletions ansys/mapdl/core/mapdl_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1627,3 +1627,19 @@ def igesin(self, fname="", ext="", **kwargs):
out = super().igesin(basename, **kwargs)

return out

@wraps(_MapdlCore.cmatrix)
def cmatrix(self, symfac="", condname="", numcond="", grndkey="",
capname="", **kwargs):
"""Run CMATRIX in non-interactive mode and return the response from file. """

# The CMATRIX command needs to run in non-interactive mode
if not self._store_commands:
with self.non_interactive:
super().cmatrix(symfac, condname, numcond, grndkey, capname, **kwargs)
self._response = self._download_as_raw('cmatrix.out').decode()
return self._response

# otherwise, simply run cmatrix as we're already in
# non-interactive and there's no output to return
super().cmatrix(symfac, condname, numcond, grndkey, capname, **kwargs)
6 changes: 6 additions & 0 deletions doc/source/user_guide/mapdl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -733,12 +733,18 @@ supported.
* ``*REPEAT``
* ``*RETURN``
* ``*VWRITE``
* ``CMATRIX``

Note, many of these commands do not make sense in a Python context.
For example the ``*ASK`` can be replaced with a Python ``input``,
``*IF`` with a Python ``if`` statement, and instead of ``*CREATE`` and
``*USE`` can simply call another Python function or module.

The command ``CMATRIX`` does not kill the server, however when it is
run on interactive mode does not make any effect. This command needs to
be run in non_interactive mode (:attr:`Mapdl.non_interactive
<ansys.mapdl.core.Mapdl.non_interactive>`).


GUI Commands
~~~~~~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion docker/mapdl/IMAGE_NAME
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
VERSION=v21.2.0
VERSION=v21.2.1
REPO=docker.pkg.github.com/pyansys/pymapdl
IMAGE=$REPO/mapdl:$VERSION
21 changes: 13 additions & 8 deletions docker/mapdl/reduce_mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
import numpy as np

ver = '212'
source_directory = f'/mnt/old/usr/ansys_inc/v{ver}/' # mounted with strictatime

# source_directory = f'/mnt/old/usr/ansys_inc/v{ver}/' # mounted with strictatime
source_directory = f'/mnt/thumb/ansys_inc/v{ver}/' # mounted with strictatime

def convert_size(size_bytes):
if size_bytes == 0:
Expand All @@ -46,11 +46,14 @@ def convert_size(size_bytes):
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])

# time.time() # manually run
cutoff = 1622174341.787562

# update this...
cutoff = 0 # <from time.time()>


# next, run mapdl and pymapdl unit testing in both DPM and SMP modes


total_size = 0
times = []
recent_files = []
Expand All @@ -77,8 +80,8 @@ def convert_size(size_bytes):
print(recent_files[i][0])
# print('%40s %s' % (recent_files[i][1], time.ctime(accesstime)))
dest = recent_files[i][0].replace(f'/v{ver}/', f'/v{ver}_docker/')
os.makedirs(os.path.dirname(dest), exist_ok=True)
shutil.copy(recent_files[i][0], dest)
# os.makedirs(os.path.dirname(dest), exist_ok=True)
# shutil.copy(recent_files[i][0], dest)


# these may not be captured if not using a newer xeon cpu
Expand All @@ -87,10 +90,12 @@ def convert_size(size_bytes):
f'/usr/ansys_inc/v{ver}/tp/IntelMKL/2020.0.166/linx64/lib/intel64/libmkl_def.so',
]

# TODO: Move over all MAC files in /usr/ansys_inc/<ver>/ansys/apdl/* as well

for filename in extra_files:
dest = filename.replace(f'/v{ver}/', f'/v{ver}_docker/')
os.makedirs(os.path.dirname(dest), exist_ok=True)
shutil.copy(filename, dest)
# os.makedirs(os.path.dirname(dest), exist_ok=True)
# shutil.copy(filename, dest)

print(np.sum(times > cutoff), 'out of', len(times))
print(convert_size(total_size))
Empty file added tests/test_commands.py
Empty file.
63 changes: 63 additions & 0 deletions tests/test_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,51 @@
pytestmark = pytest.mark.skip_grpc


@pytest.fixture(scope='function')
def setup_for_cmatrix(mapdl, cleared):
mapdl.prep7()
mapdl.title("Capacitance of two long cylinders above a ground plane")
mapdl.run("a=100") # Cylinder inside radius (μm)
mapdl.run("d=400") # Outer radius of air region
mapdl.run("ro=800") # Outer radius of infinite elements
mapdl.et(1, 121) # 8-node 2-D electrostatic element
mapdl.et(2, 110, 1, 1) # 8-node 2-D Infinite element
mapdl.emunit("epzro", 8.854e-6) # Set free-space permittivity for μMKSV units
mapdl.mp("perx", 1, 1)
mapdl.cyl4("d/2", "d/2", "a", 0) # Create mode in first quadrant
mapdl.cyl4(0, 0, "ro", 0, "", 90)
mapdl.cyl4(0, 0, "2*ro", 0, "", 90)
mapdl.aovlap("all")
mapdl.numcmp("area")
mapdl.run("smrtsiz,4")
mapdl.mshape(1) # Mesh air region
mapdl.amesh(3)
mapdl.lsel("s", "loc", "x", "1.5*ro")
mapdl.lsel("a", "loc", "y", "1.5*ro")
mapdl.lesize("all", "", "", 1)
mapdl.type(2)
mapdl.mshape(0)
mapdl.mshkey(1)
mapdl.amesh(2) # Mesh infinite region
mapdl.run("arsymm,x,all") # Reflect model about y axis
mapdl.nummrg("node")
mapdl.nummrg("kpoi")
mapdl.csys(1)
mapdl.nsel("s", "loc", "x", "2*ro")
mapdl.sf("all", 'inf') # Set infinite flag in Infinite elements
mapdl.local(11, 1, "d/2", "d/2")
mapdl.nsel("s", "loc", "x", "a")
mapdl.cm("cond1", "node") # Assign node component to 1st conductor
mapdl.local(12, 1, "-d/2", "d/2")
mapdl.nsel("s", "loc", "x", "a")
mapdl.cm("cond2", "node") # Assign node component to 2nd conductor
mapdl.csys(0)
mapdl.nsel("s", "loc", "y", 0)
mapdl.cm("cond3", "node") # Assign node component to ground conductor
mapdl.allsel("all")
mapdl.finish()
mapdl.run("/solu")

def test_clear_nostart(mapdl):
resp = mapdl._send_command('FINISH')
resp = mapdl._send_command('/CLEAR, NOSTART')
Expand Down Expand Up @@ -93,6 +138,24 @@ def test_download_missing_file(mapdl, tmpdir):
mapdl.download('__notafile__', target)


def test_cmatrix(mapdl, setup_for_cmatrix):
cap_name = 'aaaaa'
output = mapdl.cmatrix(1, 'cond', 3, 0, cap_name)
assert 'Capacitance matricies are stored in file' in output
assert cap_name in output

# also test if it works while we're already in non-interactive:
# no asserts needed here since we're not concerned about the last response
cap_name = 'bbbbb'
with mapdl.non_interactive:
mapdl.cmatrix(1, 'cond', 3, 0, cap_name)

# we have to manually get the response here. This is ok because
# user is not expected to do this.
output = mapdl._download_as_raw('cmatrix.out').decode()
assert 'Capacitance matricies are stored in file' in output
assert cap_name in output

# these tests take some time to run, and we might consider moving
# these to a functional testing module/directory outside of the tests
# directory.
Expand Down
1 change: 0 additions & 1 deletion tests/test_mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,6 @@ def test_load_table(mapdl):
assert np.allclose(mapdl.parameters['my_conv'], my_conv[:, -1])


@pytest.mark.xfail(ON_CI, reason="Bug in docker 2021R1 release candidate image")
@pytest.mark.skip_grpc
def test_lssolve(mapdl, cleared):
mapdl.mute = True
Expand Down