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

Allow arrays/tables as arguments #3332

Open
germa89 opened this issue Aug 6, 2024 · 2 comments
Open

Allow arrays/tables as arguments #3332

germa89 opened this issue Aug 6, 2024 · 2 comments
Labels
future To work on it in the future, since it can be delayed

Comments

@germa89
Copy link
Collaborator

germa89 commented Aug 6, 2024

Writing something somewhere I had an idea.

I thought we could replicate the MAPDL behaviour accepting arrays as arguments.

For examples, the command D can accept tables for the argument values:

D,Node,TEMP,%tabname%

I think we could wrap every APDL command with something like:

    def _allow_array_tables_on_args(self):
        def _upload_arg_as_array(arg):
            # to be defined
            # we might need to sanitize the name of the new array from the variable
            # name.
            return arg_name # Array name in MAPDL database

        def _upload_arg_as_table(arg):
            # to be defined
            # we might need to sanitize the name of the new array from the variable
            # name.
            return arg_name # table name in MAPDL database

        def _process_arg(arg):
            if isinstance(each_arg, np.array):
                arg =_upload_arg_as_array(arg)
            
            elif isinstance(each_arg, pd.DataFrame):
                arg = _upload_arg_as_table(arg)
            
            return arg


        def wrap_bc_listing_function(func):
            @wraps(func)
            def inner_wrapper(*args, **kwargs):
                
                args_ = []
                for each_arg in args:
                    arg = _process_arg(each_arg)
                    args_.append(arg)
                
                kwargs_ = {}
                for each_key, each_value in kwargs:
                    arg = _process_arg(each_value)
                    args_.append(arg)

                return func(*args_, **kwargs)
            return inner_wrapper

        for name in dir(self):
            if name[0:4].upper() in CMD_LISTING and name in dir(
                Commands
            ):  # avoid matching Mapdl properties which starts with same letters as MAPDL commands.
                func = self.__getattribute__(name)
                setattr(self, name, wrap_listing_function(func))

I think it could be useful because then you can do something like:

mytable = pd.Dataframe(index=[1,2,3], data = [[35],[36],[37]])
# apply temperatures 35,36 and 37 to nodes 1,2 and 3 respectively
mapdl.d("all",TEMP, mytable)

Pinging @mikerife, @mcMunich @koubaa and @pmaroneh for feedback. This an idea, I cannot work on it yet, but I'm happy to heard about this.

References:

  • Example for implementation:
    def _wrap_listing_functions(self):
    # Wrapping LISTING FUNCTIONS.
    def wrap_listing_function(func):
    # Injecting doc string modification
    if hasattr(func, "__func__"):
    func.__func__.__doc__ = inject_docs(func.__func__.__doc__)
    else: # pragma: no cover
    func.__doc__ = inject_docs(func.__doc__)
    @wraps(func)
    def inner_wrapper(*args, **kwargs):
    return CommandListingOutput(func(*args, **kwargs))
    return inner_wrapper
    def wrap_bc_listing_function(func):
    # Injecting doc string modification
    if hasattr(func, "__func__"):
    func.__func__.__doc__ = inject_docs(func.__func__.__doc__)
    else: # pragma: no cover
    func.__doc__ = inject_docs(func.__doc__)
    @wraps(func)
    def inner_wrapper(*args, **kwargs):
    return BoundaryConditionsListingOutput(func(*args, **kwargs))
    return inner_wrapper
    for name in dir(self):
    if name[0:4].upper() in CMD_LISTING and name in dir(
    Commands
    ): # avoid matching Mapdl properties which starts with same letters as MAPDL commands.
    func = self.__getattribute__(name)
    setattr(self, name, wrap_listing_function(func))
    if name[0:4].upper() in CMD_BC_LISTING and name in dir(Commands):
    func = self.__getattribute__(name)
    setattr(self, name, wrap_bc_listing_function(func))
@germa89 germa89 added the future To work on it in the future, since it can be delayed label Aug 6, 2024
@germa89
Copy link
Collaborator Author

germa89 commented Aug 6, 2024

Corollary

Same approach could be done for components. If a list/array is used as an argument, create the component with the parameter name and use it. When using an object defined in the same line, for instance:

mapdl.d([1,2,3], Temp, mytable)

we can create a temporary component and use it.

It might be not super obvious to the user though that the component/array/table is being created on the background.

@pmaroneh
Copy link
Contributor

That is a great suggestion. Being able to use lists and/or pandas dataframes to define tabular load value would be so much easier than having to create MAPDL tables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
future To work on it in the future, since it can be delayed
Projects
None yet
Development

No branches or pull requests

2 participants