Ejemplo n.º 1
0
def check_mode(mode, version):
    """Check if the MAPDL server mode matches the allowable version

    If ``None``, the newest mode will be selected.

    Returns a value from ``ALLOWABLE_MODES``.
    """
    if isinstance(mode, str):
        mode = mode.lower()
        if mode == 'grpc':
            if version < 211:
                if version < 202 and os.name == 'nt':
                    raise VersionError(
                        'gRPC mode requires MAPDL 2020R2 or newer '
                        'on Windows.')
                elif os.name == 'posix':
                    raise VersionError(
                        'gRPC mode requires MAPDL 2021R1 or newer.')
        elif mode == 'corba':
            if version < 170:
                raise VersionError(
                    'CORBA AAS mode requires MAPDL v17.0 or newer.')
            if version >= 211:
                raise VersionError(
                    'Console mode not supported for 2021R1 or newer.  '
                    'Use the default "grpc" mode.')
        elif mode == 'console':
            if os.name == 'nt':
                raise ValueError('Console mode requires Linux')
            if version >= 211:
                raise VersionError(
                    'Console mode not supported for 2021R1 or newer.  '
                    'Use the default "grpc" mode.')
        else:
            raise ValueError(
                f'Invalid MAPDL server mode "{mode}".\n\n'
                f'Use one of the following modes:\n{ALLOWABLE_MODES}')

    else:  # auto-select based on best version
        if version >= 211:
            mode = 'grpc'
        elif version == 202 and os.name == 'nt':
            # Windows supports it as of 2020R2
            mode = 'grpc'
        elif version >= 170:
            mode = 'corba'
        else:
            if os.name == 'nt':
                raise VersionError('Running MAPDL as a service requires '
                                   'v17.0 or greater on Windows.')
            mode = 'console'

    if version < 130:
        warnings.warn('MAPDL as a service has not been tested on MAPDL < v13')

    return mode
Ejemplo n.º 2
0
def check_mode(mode, version):
    """Check if the MAPDL server mode matches the allowable version

    If ``None``, the newest mode will be selected.

    Returns a value from ``ALLOWABLE_MODES``.
    """
    if isinstance(mode, str):
        mode = mode.lower()
        if mode == "grpc":
            if version < 211:
                if version < 202 and os.name == "nt":
                    raise VersionError(
                        "gRPC mode requires MAPDL 2020R2 or newer "
                        "on Windows.")
                elif os.name == "posix":
                    raise VersionError(
                        "gRPC mode requires MAPDL 2021R1 or newer.")
        elif mode == "corba":
            if version < 170:
                raise VersionError(
                    "CORBA AAS mode requires MAPDL v17.0 or newer.")
            if version >= 211:
                raise VersionError(
                    "Console mode not supported for 2021R1 or newer.  "
                    'Use the default "grpc" mode.')
        elif mode == "console":
            if os.name == "nt":
                raise ValueError("Console mode requires Linux")
            if version >= 211:
                raise VersionError(
                    "Console mode not supported for 2021R1 or newer.  "
                    'Use the default "grpc" mode.')
        else:
            raise ValueError(
                f'Invalid MAPDL server mode "{mode}".\n\n'
                f"Use one of the following modes:\n{ALLOWABLE_MODES}")

    else:  # auto-select based on best version
        if version >= 211:
            mode = "grpc"
        elif version == 202 and os.name == "nt":
            # Windows supports it as of 2020R2
            mode = "grpc"
        elif version >= 170:
            mode = "corba"
        else:
            if os.name == "nt":
                raise VersionError("Running MAPDL as a service requires "
                                   "v17.0 or greater on Windows.")
            mode = "console"

    if version < 130:
        warnings.warn("MAPDL as a service has not been tested on MAPDL < v13")

    return mode
Ejemplo n.º 3
0
    def __init__(
        self,
        n_instances,
        wait=True,
        run_location=None,
        port=MAPDL_DEFAULT_PORT,
        progress_bar=True,
        restart_failed=True,
        remove_temp_files=True,
        **kwargs,
    ):
        """Initialize several instances of mapdl"""
        self._instances = []
        self._root_dir = run_location
        kwargs["remove_temp_files"] = remove_temp_files
        kwargs["mode"] = "grpc"
        self._spawn_kwargs = kwargs

        # verify that mapdl is 2021R1 or newer
        if "exec_file" in kwargs:
            exec_file = kwargs["exec_file"]
        else:  # get default executable
            exec_file = get_ansys_path()
            if exec_file is None:
                raise FileNotFoundError(
                    "Invalid exec_file path or cannot load cached "
                    "ansys path.  Enter one manually using "
                    "exec_file=<path to executable>")

        if _version_from_path(exec_file) < 211:
            raise VersionError(
                "LocalMapdlPool requires MAPDL 2021R1 or later.")

        # grab available ports
        ports = available_ports(n_instances, port)

        if self._root_dir is not None:
            if not os.path.isdir(self._root_dir):
                os.makedirs(self._root_dir)

        self._instances = []
        self._active = True  # used by pool monitor

        n_instances = int(n_instances)
        if n_instances < 2:
            raise ValueError(
                "Must request at least 2 instances to create a pool.")

        pbar = None
        if wait and progress_bar:
            pbar = tqdm(total=n_instances, desc="Creating Pool")

        # initialize a list of dummy instances
        self._instances = [None for _ in range(n_instances)]

        # threaded spawn
        threads = [
            self._spawn_mapdl(i, ports[i], pbar, name=f'Instance {i}')
            for i in range(n_instances)
        ]
        if wait:
            [thread.join() for thread in threads]

            # check if all clients connected have connected
            if len(self) != n_instances:
                n_connected = len(self)
                warnings.warn(
                    f"Only %d clients connected out of %d requested" %
                    (n_connected, n_instances))
            if pbar is not None:
                pbar.close()

        # monitor pool if requested
        if restart_failed:
            self._pool_monitor_thread = self._monitor_pool(
                name='Monitoring_Thread')

        self._verify_unique_ports()
Ejemplo n.º 4
0
def launch_grpc(exec_file='', jobname='file', nproc=2, ram=None,
                run_location=None, port=MAPDL_DEFAULT_PORT,
                additional_switches='', custom_bin=None,
                override=True, timeout=20, verbose=False) -> int:
    """Start MAPDL locally in gRPC mode.

    Parameters
    ----------
    exec_file : str, optional
        The location of the MAPDL executable.  Will use the cached
        location when left at the default ``None``.

    jobname : str, optional
        MAPDL jobname.  Defaults to ``'file'``.

    nproc : int, optional
        Number of processors.  Defaults to 2.

    ram : float, optional
        Fixed amount of memory to request for MAPDL.  If ``None``,
        then MAPDL will use as much as available on the host machine.

    run_location : str, optional
        MAPDL working directory.  Defaults to a temporary working
        directory.

    port : int
        Port to launch MAPDL gRPC on.  Final port will be the first
        port available after (or including) this port.

    additional_switches : str, optional
        Additional switches for MAPDL, for example aa_r, and academic
        research license, would be added with:

        - ``additional_switches="-aa_r"``

        Avoid adding switches like -i -o or -b as these are already
        included to start up the MAPDL server.  See the notes
        section for additional details.

    custom_bin : str, optional
        Path to the MAPDL custom executable.

    override : bool, optional
        Attempts to delete the lock file at the run_location.
        Useful when a prior MAPDL session has exited prematurely and
        the lock file has not been deleted.

    verbose : bool, optional
        Print all output when launching and running MAPDL.  Not
        recommended unless debugging the MAPDL start.  Default
        ``False``.

    Returns
    -------
    port : int
        Returns the port number that the gRPC instance started on.

    Examples
    --------
    Launch MAPDL using the default configuration.

    >>> from ansys.mapdl import launch_mapdl
    >>> mapdl = launch_mapdl()

    Run MAPDL with shared memory parallel and specify the location of
    the ansys binary.

    >>> exec_file = 'C:/Program Files/ANSYS Inc/v202/ansys/bin/win64/ANSYS202.exe'
    >>> mapdl = launch_mapdl(exec_file, additional_switches='-smp')

    Notes
    -----
    These are the MAPDL switch options as of 2020R2 applicable for
    running MAPDL as a service via gRPC.  Excluded switches such as
    ``"-j"`` either not applicable or are set via keyword arguments.

    -acc <device> : Enables the use of GPU hardware.  See GPU
     Accelerator Capability in the Parallel Processing Guide for more
     information.

    -amfg : Enables the additive manufacturing capability.  Requires
     an additive manufacturing license. For general information about
     this feature, see AM Process Simulation in ANSYS Workbench.

    -ansexe <executable> :  Activates a custom mechanical APDL executable.
     In the ANSYS Workbench environment, activates a custom
     Mechanical APDL executable.

    -custom <executable> : Calls a custom Mechanical APDL executable
     See Running Your Custom Executable in the Programmer's Reference
     for more information.

    -db value : Initial memory allocation
     Defines the portion of workspace (memory) to be used as the
     initial allocation for the database. The default is 1024
     MB. Specify a negative number to force a fixed size throughout
     the run; useful on small memory systems.

    -dis : Enables Distributed ANSYS
     See the Parallel Processing Guide for more information.

    -dvt : Enables ANSYS DesignXplorer advanced task (add-on).
     Requires DesignXplorer.

    -l <language> : Specifies a language file to use other than English
     This option is valid only if you have a translated message file
     in an appropriately named subdirectory in
     ``/ansys_inc/v201/ansys/docu`` or
     ``Program Files\\ANSYS\\Inc\\V201\\ANSYS\\docu``

    -m <workspace> : Specifies the total size of the workspace
     Workspace (memory) in megabytes used for the initial
     allocation. If you omit the ``-m`` option, the default is 2 GB
     (2048 MB). Specify a negative number to force a fixed size
     throughout the run.

    -machines <IP> : Specifies the distributed machines
     Machines on which to run a Distributed ANSYS analysis. See
     Starting Distributed ANSYS in the Parallel Processing Guide for
     more information.

    -mpi <value> : Specifies the type of MPI to use.
     See the Parallel Processing Guide for more information.

    -mpifile <appfile> : Specifies an existing MPI file
     Specifies an existing MPI file (appfile) to be used in a
     Distributed ANSYS run. See Using MPI Files in the Parallel
     Processing Guide for more information.

    -na <value>: Specifies the number of GPU accelerator devices
     Number of GPU devices per machine or compute node when running
     with the GPU accelerator feature. See GPU Accelerator Capability
     in the Parallel Processing Guide for more information.

    -name <value> : Defines Mechanical APDL parameters
     Set mechanical APDL parameters at program start-up. The parameter
     name must be at least two characters long. For details about
     parameters, see the ANSYS Parametric Design Language Guide.

    -p <productname> : ANSYS session product
     Defines the ANSYS session product that will run during the
     session. For more detailed information about the ``-p`` option,
     see Selecting an ANSYS Product via the Command Line.

    -ppf <license feature name> : HPC license
     Specifies which HPC license to use during a parallel processing
     run. See HPC Licensing in the Parallel Processing Guide for more
     information.

    -smp : Enables shared-memory parallelism.
     See the Parallel Processing Guide for more information.
    """
    # disable all MAPDL pop-up errors:
    os.environ['ANS_CMD_NODIAG'] = 'TRUE'

    # use temporary directory if run_location is unspecified
    if run_location is None:
        run_location = create_temp_dir()
    elif not os.path.isdir(run_location):
        os.mkdir(run_location)

    if not os.access(run_location, os.W_OK):
        raise IOError('Unable to write to ``run_location`` "%s"' % run_location)

    # verify version
    if _version_from_path(exec_file) < 202:
        raise VersionError('The MAPDL gRPC interface requires MAPDL 20.2 or later')

    # verify lock file does not exist
    check_lock_file(run_location, jobname, override)

    # get the next available port
    if port is None:
        if not pymapdl._LOCAL_PORTS:
            port = MAPDL_DEFAULT_PORT
        else:
            port = max(pymapdl._LOCAL_PORTS) + 1

    while port_in_use(port) or port in pymapdl._LOCAL_PORTS:
        port += 1
    pymapdl._LOCAL_PORTS.append(port)

    cpu_sw = '-np %d' % nproc
    if ram:
        ram_sw = '-m %d' % int(1024*ram)
    else:
        ram_sw = ''

    job_sw = '-j %s' % jobname
    port_sw = '-port %d' % port
    grpc_sw = '-grpc'

    # remove any temporary error files at the run location.  This is
    # important because we need to know if MAPDL is already running
    # here and because we're looking for any temporary files that are
    # created to tell when the process has started
    for filename in os.listdir(run_location):
        if ".err" == filename[-4:] and jobname in filename:
            try:
                os.remove(filename)
            except:
                raise IOError('Unable to remove {filename}.  There might be '
                              'an instance of MAPDL running at this location')

    # Windows will spawn a new window, only linux will let you use pexpect...
    if os.name == 'nt':

        # track PIDs since MAPDL isn't directly launched within the shell
        tmp_inp = '.__tmp__.inp'
        with open(os.path.join(run_location, tmp_inp), 'w') as f:
            f.write('FINISH\r\n')

        # must start in batch mode on windows to hide APDL window
        command = ['"%s"' % exec_file, job_sw, cpu_sw, ram_sw, '-b',
                   '-i', tmp_inp, '-o', '.__tmp__.out',
                   additional_switches, port_sw, grpc_sw]
        command = ' '.join(command)

    else:  # linux
        command_parm = []
        command_parm.extend(['"%s"' % exec_file, job_sw, cpu_sw,
                            ram_sw, additional_switches, port_sw,
                            grpc_sw])
        command = ' '.join(command_parm)

    if verbose:
        print(f'Running {command}')
        subprocess.Popen(command,
                         shell=os.name != 'nt',
                         cwd=run_location)
    else:
        subprocess.Popen(command,
                         shell=os.name != 'nt',
                         cwd=run_location,
                         stdin=subprocess.DEVNULL,
                         stdout=subprocess.DEVNULL,
                         stderr=subprocess.DEVNULL)


    # watch for the creation of temporary files at the run_directory.
    # This lets us know that the MAPDL process has at least started
    sleep_time = 0.1
    for _ in range(int(timeout/sleep_time)):
        # check if any error files have been created.  This is
        # more reliable than using the lock file

        files = os.listdir(run_location)
        has_ans = any([filename for filename in files if ".err" in filename])
        if has_ans:
            break
        time.sleep(sleep_time)

    return port, run_location