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

feat: apdl submodule #3385

Open
wants to merge 37 commits into
base: feat/main_commands
Choose a base branch
from
Open

feat: apdl submodule #3385

wants to merge 37 commits into from

Conversation

clatapie
Copy link
Contributor

@clatapie clatapie commented Sep 5, 2024

This PR is the first one in order to automate the PyMAPDL _commands documentation.
The changes have been generated using pyconverter-xml2py.

This PR focus on the apdl submodule.

Pinging @ansys/pymapdl-developers for visibility. Feel free to provide any feedback on the way the docstrings and the source code generation are handled.

Note

This PR is meant to be merged within the feat/main_commands branch. The latter will gather all the submodule changes, one by one, prior to be merged to the main branch.

Checklist

@clatapie clatapie added documentation Documentation related (improving, adding, etc) enhancement Improve any current implemented feature labels Sep 5, 2024
@clatapie clatapie self-assigned this Sep 5, 2024
@clatapie clatapie requested a review from a team as a code owner September 5, 2024 16:03
@clatapie clatapie requested review from germa89 and pyansys-ci-bot and removed request for a team September 5, 2024 16:03
@ansys-reviewer-bot
Copy link
Contributor

Thanks for opening a Pull Request. If you want to perform a review write a comment saying:

@ansys-reviewer-bot review

@clatapie clatapie requested a review from RobPasMue September 5, 2024 16:04
@github-actions github-actions bot added new feature Request or proposal for a new feature and removed documentation Documentation related (improving, adding, etc) labels Sep 5, 2024
@germa89
Copy link
Collaborator

germa89 commented Sep 5, 2024

I am setting this PR as draft because I think it is still not ready until you fix the line length thing.

Ping us and switch this PR to non-draft when you feel it is ready for it.

@germa89 germa89 marked this pull request as draft September 5, 2024 16:06
@clatapie
Copy link
Contributor Author

clatapie commented Sep 5, 2024

I can rework on it if docstring length is a priority. I already fixed some issues related in ansys/pyconverter-xml2py#222 but not all of them as you can see.
Except from this issue, feel free to comment any other change you would like me to work on.

Also, I had to comment the codespell pre-commit hook because it was failing even when I was ignoring the dedicated directory ``./src/ansys/mapdl/core/_commands). The next commit will show it.

@github-actions github-actions bot added CI/CD Related with CICD, Github Actions, etc examples Publishing PyMAPDL examples documentation Documentation related (improving, adding, etc) dependencies maintenance General maintenance of the repo (libraries, cicd, etc) labels Oct 18, 2024
@wiz-inc-572fc38784
Copy link
Contributor

wiz-inc-572fc38784 bot commented Oct 18, 2024

Wiz Scan Summary

Scanner Findings
Vulnerability Finding Vulnerabilities
Data Finding Sensitive Data
Secret Finding Secrets
IaC Misconfiguration IaC Misconfigurations
Total

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension.

@clatapie clatapie force-pushed the feat/apdl_submodule branch from ac7b46a to 04dac45 Compare October 18, 2024 12:15
@github-actions github-actions bot removed CI/CD Related with CICD, Github Actions, etc examples Publishing PyMAPDL examples documentation Documentation related (improving, adding, etc) dependencies maintenance General maintenance of the repo (libraries, cicd, etc) labels Oct 18, 2024
@github-actions github-actions bot added the CI/CD Related with CICD, Github Actions, etc label Oct 18, 2024
@clatapie
Copy link
Contributor Author

Error with *TREAD.

Currently in PyMAPDL:

command = f"*TREAD,{par},{fname},{ext},,{nskip}"

With the auto-generated package:

command = f"*TREAD,{par},{fname},{ext},{nskip}"

Fixing this coma error might solve other failing tests as well.
This will be fixed in ansys/pyconverter-xml2py#356

@@ -33,7 +33,7 @@ env:
DPF_PORT: 21004
MAPDL_PACKAGE: ghcr.io/ansys/mapdl
ON_CI: True
PYTEST_ARGUMENTS: '-vvv -rxXsa --color=yes --durations=10 --random-order --random-order-bucket=class --maxfail=10 --reruns 3 --reruns-delay 4 --cov=ansys.mapdl.core --cov-report=html'
PYTEST_ARGUMENTS: '-vvv -rxXsa --color=yes --durations=10 --random-order --random-order-bucket=class --maxfail=100 --reruns 3 --reruns-delay 4 --cov=ansys.mapdl.core --cov-report=html'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be reverted once the tests will pass

@germa89
Copy link
Collaborator

germa89 commented Nov 28, 2024

@clatapie ... CICD is SUPER unstable right now since I merged #3268. I'm working on that.

I would probably revert that commit in the main_commands branch and see if the PR passes. To be safe, I would probably revert any other commit after since I'm working quite a lot on that at the moment.

@germa89
Copy link
Collaborator

germa89 commented Nov 28, 2024

Overall LGTM - couldn't really evaluate whether all the changes make sense or not but the logic seems properly done and the docstrings are really nicely formatted (for being autogenerated).

My concern is only about modules that have been renamed completely (take array_param to array_parameters. Maybe we should "keep" the old file, throw a warning saying that this module is deprecated, and import all the "new module" objects in this module (through a star import). But I'd only do this if users are frequently accessing the _commands subpackage directly... otherwise, let the Mapdl object handle it for them.

Users are not expected to access _commands by themselves, so any adjustment can be done in any of the Commands subclasses:

@clatapie
Copy link
Contributor Author

Thanks for your feedback @germa89.

The issue I found here is unrelated to the unit test stability. However, if after fixing it the error persists, I will remove the random argument.

You are right! Then, changes should already be in place as I manually modified src/ansys/mapdl/core/commands.py.

Copy link
Collaborator

@germa89 germa89 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good progress, this is looking great.

I would say there a few pain points we need to fix first before final merging.

  • Paragraphs in Notes are being merged into one.
  • Identations are wrong in some arguments (fname mainly)
  • we should decide what to do when the arguments descriptions are the same.
  • Many places have strange line lengths... like way too long... sometimes they have links.
  • the mkdir command is missing the argument
  • It seems bold format is not respected (it is always ignored)
  • *SET notes section is bad formatted, I think it is missing stuff.

Another things to consider:

  • For some reason the left side bar is not in alphabetical order:
image

(it did take a while this review... damn)

Comment on lines 59 to 64
# - repo: https://github.com/codespell-project/codespell
# rev: v2.3.0
# hooks:
# - id: codespell
# args: ["--toml", "pyproject.toml"]
# additional_dependencies: ["tomli"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this was deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I commented it as explained in #3385 (comment)
I have planned to rework on it. For the moment, I don't know why the repository can not be ignored.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok... interesting.... Keep it like that until merging.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: #3385 (comment)

Comment on lines +18 to +21
Abbreviations.ucmd
Abbreviations.abbres
Abbreviations.abbr
Abbreviations.abbsav
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are going to extend this commands on _MapdlCommandExtended class... shouldn't we use Mapdl or _MapdlCommandExtended instead of Abbreviations ??

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for all the rest.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok... So... if there are commands like input which is "extended" (we change the behaviour to adapt to the diferent interfaces, or to adapt to python), we should probably not point to the docstring in the original code.

For instance, if we change the command ABBRES to do something inside the function that might change the docstring, we should not point the documentation to Abbreviations.abbres rather _MapdlCommandExtended.abbres (assuming the new ABBRES is coded in the _MapdlCommandExtended class.

I think this is also related to: #3385 (comment)

But I think for the moment, we should not worry much, since most of the commands are not going to be expanded. Just a few, for instance input which changes because of the gRPC interface. In that case, we might have both:

  • the original MAPDL command in run_controls.py
  • the extended MAPDL command in mapdl_grpc.py, and this one will overwrite the docstring of the above.

What will happen when we search for input?... presumably two results will come up...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLDR: Dont bother at the moment. We will figure out this in the future.

.. _ref_apdl:

<!-- vale off -->
Apdl
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think APDL should be all capital.

doc/source/mapdl_commands/apdl/index.rst Show resolved Hide resolved
examples/00-mapdl-examples/transient_thermal.py Outdated Show resolved Hide resolved
Comment on lines +777 to +778
\*TAXIS,longtable(1,4,1,1),2,1.0,2.2,3.5,4.7,5.9
``nAxis`` 2 (column location), starting at location 4.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing tex and newline.

Suggested change
\*TAXIS,longtable(1,4,1,1),2,1.0,2.2,3.5,4.7,5.9
``nAxis`` 2 (column location), starting at location 4.
\*TAXIS,longtable(1,4,1,1),2,1.0,2.2,3.5,4.7,5.9
would fill index values 1.0, 2.2, 3.5, 4.7, and 5.9 in ``nAxis`` 2 (column location), starting at location 4.

Assigns values to user-named parameters that may be substituted later
in the run. The equivalent (and recommended) format is
Reads data from a file and fills in an array parameter vector or matrix. Data are read from a
formatted file or, if the menu is off ( :ref:`menu` ,OFF) and ``Fname`` is blank, from the next input lines. The format of the data to be read must be input immediately following the :ref:`vread` command. The format specifies the number of fields to be read per record, the field width, and the placement of the decimal point (if none specified in the value). The read operation follows the available FORTRAN FORMAT conventions of the system (see your system FORTRAN manual). Any standard FORTRAN `real` format (such as (4F6.0), (E10.3,2X,D8.2), etc.) or alphanumeric format (A) may be used. Alphanumeric
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm puzzled with the line lengths.. they are so random...

Comment on lines +1222 to +1226
to (blank). A defined parameter must be deleted ( :ref:`starset` ) before its dimensions can be changed. Scalar (single valued) parameters should not be dimensioned. :ref:`dim` ,A,,3 defines a vector array with elements A(1), A(2), and A(3). :ref:`dim` ,B,,2,3 defines a 2x3 array with elements B(1,1), B(2,1), B(1,2), B(2,2), B(1,3), and B(2,3). Use :ref:`starstatus`, ``Par`` to display elements of array ``Par`` . You can write formatted data files (tabular formatting) from data held in arrays through the :ref:`vwrite` command.

If you use table parameters to define boundary conditions, then ``Var1``, ``Var2``, and/or ``Var3`` can either specify a primary variable (listed in ) or can be an independent parameter. If specifying an independent parameter, then you must define an additional table for the independent parameter. The additional table must have the same name as the independent parameter and may be a function of one or more primary variables or another independent parameter. All independent parameters must relate to a primary variable.

Tabular load arrays can be defined in both global Cartesian (default), cylindrical, spherical, or
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looong...

Comment on lines +88 to +93
def endif(self, **kwargs):
r"""Ends an if-then-else.

Mechanical APDL Command: `\*ENDIF <https://ansyshelp.ansys.com/Views/Secured/corp/v232/en//ans_cmd/Hlp_C_ENDIF.html>`_

Notes
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future I would like to add bits here.. like how these commands are compared to the python ones.

-----
Optional intermediate block separator within an if-then-else construct. All seven characters of the
command name (\*ELSEIF) must be input. This command is similar to the :ref:`if` command except that
the ``Base`` field is not used. The :ref:`if`, :ref:`elseif`, :ref:`else`, and :ref:`endif`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:ref:else is also taken from the python guide...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might need to go for :ref:ansys.mapdl.core.mapdl.MapdlBase.if or similar...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(double check the above)

@germa89
Copy link
Collaborator

germa89 commented Nov 28, 2024

Error with *TREAD.

Currently in PyMAPDL:

command = f"*TREAD,{par},{fname},{ext},,{nskip}"

With the auto-generated package:

command = f"*TREAD,{par},{fname},{ext},{nskip}"

Fixing this coma error might solve other failing tests as well. This will be fixed in ansys/pyconverter-xml2py#356

Just double checking that the version with the empty argument is the correct one. :)

@RobPasMue
Copy link
Member

@germa89 - this PR should be "automated". I don't understand the reason to make local changes.

@clatapie
Copy link
Contributor Author

@germa89 's previous changes might be automatic since the branch is connected to feat/main_commands and not to the main one.

@github-actions github-actions bot removed the examples Publishing PyMAPDL examples label Dec 16, 2024
@germa89
Copy link
Collaborator

germa89 commented Dec 17, 2024

@clatapie ... CICD is SUPER unstable right now since I merged #3268. I'm working on that.

I would probably revert that commit in the main_commands branch and see if the PR passes. To be safe, I would probably revert any other commit after since I'm working quite a lot on that at the moment.

btw, this was fixed. CICD is "stable" again.

@germa89
Copy link
Collaborator

germa89 commented Dec 17, 2024

For the commands with non-pythonic MAPDL commands (i.e. SECMODIF) where the MAPDL command signature might change depending on the argument:

image

additional_arguments option

@clatapie suggested an extra string argument such as:

def secmodif(self, secid="", Keyword="", additional_arguments="", **kwargs):
    # implementation
    return self.run(f"SECMODIF,{secid}, {keyword},{additional_arguments}")

So you can do:

mapdl.secmodif(1, "NORM", "NX=2,NY=3, NZ=2, KCN=2")

This effectively injects all the additional arguments as an string.

Caveats

While this method might work, it delegates to the user all the responsability of building the command, and additionally it forces you to specify all the intermediate arguments (or commas). For instance if you only wants to use KCN, you will have to:

mapdl.secmodif(1, "NORM", ", , , KCN=2")

which looks rather weird.

The * method

I would propose to use * in the function signature after the argument keyword. This way, the user is forced to use key arguments to specify the values.

def secmodif(self, secid, Keyword, *, nx="", ny="", nz="", kcn="", name="", Option="", dispPnltVal="", RotPnltVal=""):
    # We will know which command option by internally switching like this:
    if Keyword  == "NORM" or nx or ny:
         cmd = "SECMODIF, NORM, {nx}, {ny}, {nz}"
    elif Keyword  == "NAME" or name:
         cmd = "SECMODIF, NAME, {name}"
    else:
        raise ValueError("We couldn't map the arguments given....")

Then we can quickly use this like:

mapdl.secmodif(1, nx=1) # implicitly using keyword=NORM
mapdl.secmodif(name='name')  # implicitly using keyword=NAME

And because of * in the signature, you will get an error if trying to use more args than allowed:

mapdl.secmodif(1, "NORM", 1, 2) # Raise an error

Caveats

The problem of this is that the API can be broken... because the above mapdl.secmodif(1, "NORM", 1, 2) is something that most of other commands do. Furthermore, this will need for the translator module to be adapted so it can predict the key arguments (or just bypass the conversion using mapdl.run).

The *args option

We will use the *args option, but the implementation is rather complicated:

def secmodif(self, secid, Keyword, *args, **kwargs):
    # We will know which command option by internally switching like this:
    # getting kword
    args_kw = {}
    # dict with arguments names and their position
    arg_names = {
    "nx": 0, "ny": 1, "nz": 2,  "kcn": 3, "name": 0, "Option": 0, "dispPnltVal": 1, "RotPnltVal": 2
    }
    for arg_name, arg_indx in arg_names.items():
        args_kw[arg_name] = kwargs.pop(arg_name, args[arg_indx] if len(args) >= arg_indx + 1 else "")

    args_kw["secid"] = secid

    if Keyword  == "NORM" or nx or ny:
        cmd = "SECMODIF, {secid}, NORM, {nx}, {ny}, {nz}, {kcn}".format(**args_kw)
    elif Keyword  == "NAME" or name:
        cmd = "SECMODIF, {secid}, NAME, {name}".format(**args_kw)
    else:
        raise ValueError("We couldn't map the arguments given....")
    
    print(cmd)

secmodif("self", 1, "NORM", nx=1)
secmodif("self", 1, "NORM", 1, kcn=2)

It does respect the compatibility of the current API, and we do not have to bother about the converter. The signature si very clean, but we depend on the docs for explaining all the arguments. Intellisense might not help much in this case (maybe we can do something with typing module).

Opinions

I personally like more the * option, it is more elegant, and cleaner. But it does break the compatibility with the current Python code.

What do you think @clatapie @RobPasMue @koubaa @mikerife @mcMunich @pmaroneh??

@germa89
Copy link
Collaborator

germa89 commented Dec 17, 2024

@germa89 - this PR should be "automated". I don't understand the reason to make local changes.

Very true... I do not expect @clatapie applies the changes rather she is aware of them, so she can fix the package accordingly.

@germa89
Copy link
Collaborator

germa89 commented Dec 17, 2024

With respect to the arguments that have the same exact description, I will refer to the current discussion #3385 (comment)

@clatapie
Copy link
Contributor Author

Answering @germa89's comment:

additional_arguments option

additional_arguments needs to be used as follow:

mapdl.secmodif(1, "NORM", "2,3,2,2")

Thus, NX, NY, NZ and KCN are not mentioned in the current implementation.

This is due to the Python source code as reminded by @germa89:

def secmodif(self, secid="", kywrd="", additional_arguments="", **kwargs):
    # implementation
    command = f"SECMODIF,{secid},{kywrd},{additional_arguments}"
    return self.run(command)

With previous example, command == SECMODIF,1,NORM,2,3,2,2

I agree the API is not ideal this way but it enables passing all the needed values.

*-method

The * method is interesting because it would avoid a lot of issues.
However, I would not make those changes at the pyconverter-xml2py level but I would modify the functions one by one and add them as custom_functions, at least for now.
IMO, parsing the initial file to obtain the proposed code might not be that easy. Especially, this format appears in only 4 methods in all the converted PyMAPDL commands.
We can open an issue to keep a track of this enhancement

Proposed solution

Overall, as mentioned in the second section, I would recommend customizing one by one the 4 relevant functions with the *-method proposed by @germa89.
In the future, if we discover the issue appears quite often, a modification could be implemented.

@RobPasMue
Copy link
Member

RobPasMue commented Dec 17, 2024

My 2 cents... the problem with the The * method and The *args option is that it is not easy to automate IMO. If you are willing to pay the price and have them as custom functions which you implement ad-hoc... then I would go with The * method. Option The *args option seems overly complicated assuming you are already doing a custom function.

@MaxJPRey
Copy link
Contributor

MaxJPRey commented Dec 24, 2024

I agree with your approach too @clatapie.

The ROI seems low for now regarding the automation. It could even be difficult to maintain at first.
We can always come back on it later if our strategy happens to not be sustainable. This could be done in futur versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/CD Related with CICD, Github Actions, etc dependencies documentation Documentation related (improving, adding, etc) enhancement Improve any current implemented feature maintenance General maintenance of the repo (libraries, cicd, etc) new feature Request or proposal for a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants