Skip to content

Commit 2974e52

Browse files
germa89akaszynski
andauthored
Fix/filename and paths in cdread (#631)
* Added missing extension argument in fname. Added a check to make sure the fname is the complete file path. * Added test * Now pyansys will look for both possible options. (python and mapdl execution folders) * small things. * Adding the possibility of using fname + extension in cdread. * Added skipif for the test which requires to create a folder. * Format fixing. * Format fixing. * Format fixing. * Apply suggestions from code review Co-authored-by: Alex Kaszynski <[email protected]> * Fixing test in CICD. * Format fixing. * Added more test to increase test coverage. * Fixing default extension issue and adding more test cases. * Fixng style. * Update test_mapdl.py Grammar fixing. * Update test_mapdl.py Fixing whitespacing. * changed parameter testing name. * Simplified input file name checks. * fixing database extension convention. * Fixing parsav on local. * Fxing database file extension. * Fixing linux path issue. * Fixing style. * Fixing cdb extensions. * Trying to fix linux path issue. * address remote edge-case * simply assume that file must be remote * provide full path Co-authored-by: Alex Kaszynski <[email protected]>
1 parent 3f0970c commit 2974e52

File tree

4 files changed

+220
-14
lines changed

4 files changed

+220
-14
lines changed

ansys/mapdl/core/_commands/apdl/parameter_definition.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,19 @@ def parres(self, lab="", fname="", ext="", **kwargs):
377377

378378
if "Grpc" in self.__class__.__name__: # grpc mode
379379
if self._local:
380-
if not os.path.isfile(fname):
381-
raise FileNotFoundError('Unable to locate filename "%s"' % fname)
382-
383-
if not os.path.dirname(fname):
380+
# It must be a file!
381+
if os.path.isfile(fname):
382+
# And it exist!
384383
filename = os.path.join(os.getcwd(), fname)
384+
elif fname in self.list_files(): #
385+
# It exists in the Mapdl working directory
386+
filename = os.path.join(self.directory, fname)
387+
elif os.path.dirname(fname):
388+
raise ValueError(f"'{fname}' appears to be an incomplete directory path rather than a filename.")
385389
else:
386-
filename = fname
390+
# Finally
391+
raise FileNotFoundError(f"Unable to locate filename '{fname}'")
392+
387393
else:
388394
if not os.path.dirname(fname):
389395
# might be trying to run a local file. Check if the

ansys/mapdl/core/mapdl_grpc.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -989,8 +989,19 @@ def cdread(self, *args, **kwargs):
989989
"Input the geometry and mesh files separately "
990990
r'with "\INPUT" or ``mapdl.input``'
991991
)
992-
992+
# the old behaviour is to supplied the name and the extension separatelly.
993+
# to make it easier let's going to allow names with extensions
993994
fname = kwargs.get("fname", args[1])
995+
basename = os.path.basename(fname)
996+
if len(basename.split('.')) == 1:
997+
# there is no extension in the main name.
998+
if len(args) > 2:
999+
# if extension is an input as an option (old APDL style)
1000+
fname = kwargs.get("fname", args[1]) + '.' + kwargs.get("ext", args[2])
1001+
else:
1002+
# Using default .db
1003+
fname = kwargs.get("fname", args[1]) + '.' + 'cdb'
1004+
9941005
kwargs.setdefault("verbose", False)
9951006
kwargs.setdefault("progress_bar", False)
9961007
self.input(fname, **kwargs)
@@ -1049,22 +1060,37 @@ def input(
10491060
# always check if file is present as the grpc and MAPDL errors
10501061
# are unclear
10511062
if self._local:
1052-
if not os.path.isfile(fname):
1053-
raise FileNotFoundError('Unable to locate filename "%s"' % fname)
1054-
1055-
if not os.path.dirname(fname):
1056-
filename = os.path.join(os.getcwd(), fname)
1063+
if os.path.isdir(fname):
1064+
raise ValueError(f"`fname` should be a full file path or name, not the directory '{fname}'.")
10571065
else:
1058-
filename = fname
1066+
# It must be a file!
1067+
if os.path.isfile(fname):
1068+
# And it exist!
1069+
filename = os.path.join(os.getcwd(), fname)
1070+
elif fname in self.list_files(): #
1071+
# It exists in the Mapdl working directory
1072+
filename = os.path.join(self.directory, fname)
1073+
elif os.path.dirname(fname):
1074+
raise ValueError(f"'{fname}' appears to be an incomplete directory path rather than a filename.")
1075+
else:
1076+
# Finally
1077+
raise FileNotFoundError(f"Unable to locate filename '{fname}'")
1078+
10591079
else:
10601080
if not os.path.dirname(fname):
10611081
# might be trying to run a local file. Check if the
10621082
# file exists remotely.
10631083
if fname not in self.list_files():
10641084
self.upload(fname, progress_bar=progress_bar)
1085+
filename = fname
10651086
else:
1066-
self.upload(fname, progress_bar=progress_bar)
1067-
filename = os.path.basename(fname)
1087+
# upload the file if it exists locally
1088+
if os.path.isfile(fname):
1089+
self.upload(fname, progress_bar=progress_bar)
1090+
filename = os.path.basename(fname)
1091+
else:
1092+
# Otherwise, it must be remote. Use full path.
1093+
filename = fname
10681094

10691095
if time_step_stream is not None:
10701096
if time_step_stream <= 0:

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939

4040
# determine if we can launch an instance of MAPDL locally
41+
# start with ``False`` and always assume the remote case
4142
local = [False]
4243

4344
# check if the user wants to permit pytest to start MAPDL

tests/test_mapdl.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,17 @@
1212
from pyvista.plotting import system_supports_plotting
1313
from pyvista.plotting.renderer import CameraPosition
1414

15+
from ansys.mapdl.core.launcher import get_start_instance
16+
1517
skip_no_xserver = pytest.mark.skipif(
1618
not system_supports_plotting(), reason="Requires active X Server"
1719
)
1820

21+
skip_in_cloud = pytest.mark.skipif(
22+
not get_start_instance(),
23+
reason="Must be able to launch MAPDL locally. Cloud does not allow create folders."
24+
)
25+
1926

2027
CMD_BLOCK = """/prep7
2128
! Mat
@@ -32,6 +39,65 @@
3239
vmesh,all
3340
"""
3441

42+
## Testing CDREAD and CDWRITE
43+
# DB file generated locally with ANSYS.
44+
# Many of the commands could be deleted, but for the sake of good
45+
# testing we are going to leave them.
46+
47+
CDB_FILE = """/COM,ANSYS RELEASE 2021 R2 BUILD 21.2
48+
/PREP7
49+
/NOPR
50+
/TITLE,'CDREAD and CDWRITE tests
51+
*IF,_CDRDOFF,EQ,1,THEN !if solid model was read in
52+
_CDRDOFF= !reset flag, numoffs already performed
53+
*ELSE !offset database for the following FE model
54+
*ENDIF
55+
*SET,T_PAR,'asdf1234'
56+
*SET,_RETURN , 0.000000000000
57+
*SET,_STATUS , 0.000000000000
58+
*SET,_UIQR , 1.000000000000
59+
DOF,DELETE
60+
EXTOPT,ATTR, 0, 0, 0
61+
EXTOPT,ESIZE, 0, 0.0000
62+
EXTOPT,ACLEAR, 0
63+
TREF, 0.00000000
64+
IRLF, 0
65+
BFUNIF,TEMP,_TINY
66+
ACEL, 0.00000000 , 0.00000000 , 0.00000000
67+
OMEGA, 0.00000000 , 0.00000000 , 0.00000000
68+
DOMEGA, 0.00000000 , 0.00000000 , 0.00000000
69+
CGLOC, 0.00000000 , 0.00000000 , 0.00000000
70+
CGOMEGA, 0.00000000 , 0.00000000 , 0.00000000
71+
DCGOMG, 0.00000000 , 0.00000000 , 0.00000000
72+
73+
KUSE, 0
74+
TIME, 0.00000000
75+
ALPHAD, 0.00000000
76+
BETAD, 0.00000000
77+
DMPRAT, 0.00000000
78+
DMPSTR, 0.00000000
79+
CRPLIM, 0.100000000 , 0
80+
CRPLIM, 0.00000000 , 1
81+
NCNV, 1, 0.00000000 , 0, 0.00000000 , 0.00000000
82+
NEQIT, 0
83+
84+
ERESX,DEFA
85+
/GO
86+
FINISH
87+
"""
88+
89+
90+
def clearing_cdread_cdwrite_tests(mapdl):
91+
mapdl.finish(mute=True)
92+
# *MUST* be NOSTART. With START fails after 20 calls...
93+
# this has been fixed in later pymapdl and MAPDL releases
94+
mapdl.clear("NOSTART", mute=True)
95+
mapdl.prep7(mute=True)
96+
97+
98+
def asserting_cdread_cdwrite_tests(mapdl):
99+
return 'asdf1234' in mapdl.parameters['T_PAR'] # Using in because of the padding APDL does on strings.
100+
35101

36102
@pytest.fixture(scope="function")
37103
def make_block(mapdl, cleared):
@@ -612,6 +678,113 @@ def test_coriolis(mapdl, cleared):
612678
assert "PRINT ROTOR MASS SUMMARY ACTIVATED" in resp
613679

614680

681+
def test_title(mapdl, cleared):
682+
title = 'title1' # the title cannot be longer than 7 chars. Check *get,parm,active,0,title for more info.
683+
mapdl.title(title)
684+
assert title == mapdl.get('par', 'active', '0', 'title')
685+
686+
687+
def test_cdread(mapdl, cleared):
688+
random_letters = mapdl.directory.split('/')[0][-3:0]
689+
690+
mapdl.run(f"parmtest='{random_letters}'")
691+
mapdl.cdwrite('all', 'model2', 'cdb')
692+
693+
mapdl.clear()
694+
mapdl.cdread("db", 'model2', 'cdb')
695+
696+
assert random_letters == mapdl.parameters['parmtest']
697+
698+
699+
# CDREAD tests are actually a good way to test 'input' command.
700+
@skip_in_cloud
701+
def test_cdread_different_location(mapdl, cleared, tmpdir):
702+
random_letters = mapdl.directory.split('/')[0][-3:0]
703+
dirname = 'tt' + random_letters
704+
705+
curdir = mapdl.directory
706+
subdir = tmpdir.mkdir(dirname)
707+
708+
mapdl.run(f"parmtest='{random_letters}'")
709+
mapdl.cdwrite('all', subdir.join('model2'), 'cdb')
710+
711+
mapdl.clear()
712+
mapdl.cwd(subdir)
713+
mapdl.cdread("db", 'model2', "cdb")
714+
mapdl.cwd(curdir) #Going back
715+
716+
assert random_letters == mapdl.parameters['parmtest']
717+
718+
719+
def test_cdread_in_python_directory(mapdl, cleared):
720+
# Writing db file in python directory.
721+
# Pyansys should upload it when it detects it is not in the APDL directory.
722+
with open('model.cdb', 'w') as file:
723+
file.write(CDB_FILE)
724+
725+
mapdl.cdread('cdb', 'model', 'cdb')
726+
assert asserting_cdread_cdwrite_tests(mapdl)
727+
728+
clearing_cdread_cdwrite_tests(mapdl)
729+
mapdl.cdread('cdb', 'model.cdb')
730+
assert asserting_cdread_cdwrite_tests(mapdl)
731+
732+
clearing_cdread_cdwrite_tests(mapdl)
733+
mapdl.cdread('cdb', 'model')
734+
assert asserting_cdread_cdwrite_tests(mapdl)
735+
736+
clearing_cdread_cdwrite_tests(mapdl)
737+
fullpath = os.path.join(os.getcwd(), 'model.cdb')
738+
mapdl.cdread('cdb', fullpath)
739+
assert asserting_cdread_cdwrite_tests(mapdl)
740+
741+
clearing_cdread_cdwrite_tests(mapdl)
742+
fullpath = os.path.join(os.getcwd(), 'model')
743+
mapdl.cdread('cdb', fullpath, 'cdb')
744+
assert asserting_cdread_cdwrite_tests(mapdl)
745+
746+
clearing_cdread_cdwrite_tests(mapdl)
747+
fullpath = os.path.join(os.getcwd(), 'model')
748+
mapdl.cdread('cdb', fullpath)
749+
assert asserting_cdread_cdwrite_tests(mapdl)
750+
751+
752+
def test_cdread_in_apdl_directory(mapdl, cleared):
753+
# Writing a db file in apdl directory, using APDL.
754+
# Using APDL to write the archive as there are be cases where the
755+
# python code cannot reach the APDL execution directory because it
756+
# is remote.
757+
mapdl.run("*SET,T_PAR,'asdf1234'")
758+
mapdl.run("CDWRITE,'DB','model','cdb'")
759+
760+
clearing_cdread_cdwrite_tests(mapdl)
761+
mapdl.cdread('db', 'model', 'cdb')
762+
assert asserting_cdread_cdwrite_tests(mapdl)
763+
764+
clearing_cdread_cdwrite_tests(mapdl)
765+
mapdl.cdread('db', 'model.cdb')
766+
assert asserting_cdread_cdwrite_tests(mapdl)
767+
768+
clearing_cdread_cdwrite_tests(mapdl)
769+
mapdl.cdread('db', 'model')
770+
assert asserting_cdread_cdwrite_tests(mapdl)
771+
772+
clearing_cdread_cdwrite_tests(mapdl)
773+
fullpath = os.path.join(mapdl.directory, 'model.cdb')
774+
mapdl.cdread('db', fullpath)
775+
assert asserting_cdread_cdwrite_tests(mapdl)
776+
777+
clearing_cdread_cdwrite_tests(mapdl)
778+
fullpath = os.path.join(mapdl.directory, 'model')
779+
mapdl.cdread('db', fullpath, 'cdb')
780+
assert asserting_cdread_cdwrite_tests(mapdl)
781+
782+
clearing_cdread_cdwrite_tests(mapdl)
783+
fullpath = os.path.join(mapdl.directory, 'model')
784+
mapdl.cdread('db', fullpath)
785+
assert asserting_cdread_cdwrite_tests(mapdl)
786+
787+
615788
def test_inval_commands(mapdl, cleared):
616789
"""Test the output of invalid commands"""
617790
cmds = ["*END", "*vwrite", "/eof", "cmatrix"]

0 commit comments

Comments
 (0)