2323"""Windows implementation of LS-DYNA runner."""
2424
2525import os
26+ from pathlib import Path
2627import subprocess
2728
2829from ansys .tools .path import get_latest_ansys_installation
@@ -43,20 +44,33 @@ def __init__(self, **kwargs):
4344 """Initialize WindowsRunner."""
4445 super ().__init__ (** kwargs )
4546 version = kwargs .get ("version" , None )
46- self ._find_solver (version )
47+ executable = kwargs .get ("executable" , None )
48+ self ._find_solver (version , executable )
4749
4850 def set_input (self , input_file : str , working_directory : str ) -> None :
4951 """Set input file and working directory."""
5052 self .input_file = input_file
5153 self .working_directory = working_directory
5254
53- def _find_solver (self , version : int ) -> None :
55+ def _find_solver (self , version : int , executable : str = None ) -> None :
5456 """Find LS-DYNA solver location."""
55- if version is not None :
56- install_loc , _ = _get_unified_install_base_for_version (version )
57+ if executable :
58+ exe_path = Path (executable )
59+ if exe_path .is_file ():
60+ self .solver_location = str (exe_path .parent )
61+ self .solver = f'"{ str (exe_path )} "'
62+ return
63+ raise FileNotFoundError (f"Specified executable not found: { executable } " )
64+ if version :
65+ install_base , _ = _get_unified_install_base_for_version (version )
5766 else :
58- _ , install_loc = get_latest_ansys_installation ()
59- self .solver_location = os .path .join (install_loc , "ansys" , "bin" , "winx64" )
67+ _ , install_base = get_latest_ansys_installation ()
68+ solver_dir = Path (install_base ) / "ansys" / "bin" / "winx64"
69+ solver_exe = solver_dir / self ._get_exe_name ()
70+ if not solver_exe .is_file ():
71+ raise FileNotFoundError (f"LS-DYNA executable not found: { solver_exe } " )
72+ self .solver_location = str (solver_dir )
73+ self .solver = f'"{ str (solver_exe )} "'
6074
6175 def _get_env_script (self ) -> str :
6276 """Get env script when running using lsrun from workbench."""
@@ -80,9 +94,6 @@ def _get_exe_name(self) -> str:
8094 }[(self .mpi_option , self .precision )]
8195 return exe_name
8296
83- def _get_executable (self ) -> str :
84- return os .path .join (self .solver_location , self ._get_exe_name ())
85-
8697 def _write_runscript (self ) -> None :
8798 with open (os .path .join (self .working_directory , self ._scriptname ), "w" ) as f :
8899 f .write (self ._get_command_line ())
@@ -108,19 +119,18 @@ def run(self) -> None:
108119 def _get_command_line (self ) -> str :
109120 """Get the command line to run LS-DYNA."""
110121 script = f'call "{ self ._get_env_script ()} "'
111- solver = f'"{ self ._get_executable ()} "'
112122 ncpu = self .ncpu
113123 mem = self .get_memory_string ()
114124 input_file = self .input_file
115125 if self .mpi_option == MpiOption .SMP :
116- command = f"{ solver } i={ input_file } ncpu={ ncpu } memory={ mem } "
126+ command = f"{ self . solver } i={ input_file } ncpu={ ncpu } memory={ mem } "
117127 elif self .mpi_option == MpiOption .MPP_INTEL_MPI :
118128 # -wdir is used here because sometimes mpiexec does not pass its working directory
119129 # to dyna on windows when run from python subprocess
130+ command = f'mpiexec -wdir "{ self .working_directory } " -localonly -np { ncpu } { self .solver } i={ input_file } memory={ mem } ' # noqa:E501
131+ elif self .mpi_option == MpiOption .MPP_MS_MPI :
120132 command = (
121- f'mpiexec -wdir "{ self .working_directory } " -localonly -np { ncpu } { solver } i={ input_file } memory={ mem } '
133+ f'mpiexec -wdir "{ self .working_directory } " -c { ncpu } -aa { self . solver } i={ input_file } memory={ mem } '
122134 )
123- elif self .mpi_option == MpiOption .MPP_MS_MPI :
124- command = f'mpiexec -wdir "{ self .working_directory } " -c { ncpu } -aa { solver } i={ input_file } memory={ mem } '
125135
126136 return f"{ script } && { command } > lsrun.out.txt 2>&1"
0 commit comments