22
22
23
23
"""Windows implementation of LS-DYNA runner."""
24
24
25
+ import logging
25
26
import os
26
27
from pathlib import Path
27
28
import subprocess
29
+ import time
28
30
29
31
from ansys .tools .path import get_latest_ansys_installation
30
32
from ansys .tools .path .path import _get_unified_install_base_for_version
31
33
32
34
from ansys .dyna .core .run .base_runner import BaseRunner
33
35
from ansys .dyna .core .run .options import MpiOption , Precision
34
36
37
+ log = logging .getLogger (__name__ )
38
+
35
39
36
40
class WindowsRunner (BaseRunner ):
37
41
"""Windows implementation to Run LS-DYNA.
@@ -80,6 +84,7 @@ def _get_env_script(self) -> str:
80
84
script_name = "lsdynamsvar.bat"
81
85
lsprepost = [p for p in os .listdir (self .solver_location ) if "lsprepost" in p ][0 ]
82
86
env_script_path = os .path .join (self .solver_location , lsprepost , "LS-Run" , script_name )
87
+
83
88
return env_script_path
84
89
85
90
def _get_exe_name (self ) -> str :
@@ -106,15 +111,52 @@ def _scriptname(self) -> str:
106
111
def run (self ) -> None :
107
112
"""Run LS-DYNA."""
108
113
self ._write_runscript ()
109
- subprocess .check_call (
110
- f"cmd /c { self ._scriptname } " ,
111
- shell = False ,
112
- universal_newlines = True ,
113
- cwd = self .working_directory ,
114
- stdin = subprocess .PIPE ,
115
- stdout = subprocess .PIPE ,
116
- stderr = subprocess .PIPE ,
117
- )
114
+ script_path = Path (self .working_directory ) / self ._scriptname
115
+ log_file = Path (self .working_directory ) / "lsrun.out.txt"
116
+
117
+ try :
118
+ process = subprocess .Popen (
119
+ ["cmd" , "/c" , str (script_path )],
120
+ cwd = self .working_directory ,
121
+ stdin = subprocess .DEVNULL ,
122
+ stdout = subprocess .DEVNULL ,
123
+ stderr = subprocess .DEVNULL ,
124
+ universal_newlines = True ,
125
+ bufsize = 1 ,
126
+ )
127
+ log .info ("LS-DYNA execution started." )
128
+
129
+ warning_detected = False
130
+
131
+ while process .poll () is None :
132
+ if log_file .exists ():
133
+ with log_file .open ("r" , encoding = "utf-8" , errors = "ignore" ) as f :
134
+ content = f .readlines ()
135
+ for line in content :
136
+ if "warning" in line .lower () or "error" in line .lower ():
137
+ warning_detected = True
138
+ time .sleep (2 )
139
+
140
+ process .wait ()
141
+ if warning_detected :
142
+ log .warning ("LS-DYNA completed with warnings or errors in the log." )
143
+ log .warning (f"Check the log file for details: { log_file } " )
144
+
145
+ if process .returncode != 0 :
146
+ log .error (f"LS-DYNA run failed with exit code { process .returncode } ." )
147
+ if log_file .exists ():
148
+ log .error (f"See log file for details: { log_file } " )
149
+ raise RuntimeError (f"LS-DYNA failed with exit code { process .returncode } " )
150
+
151
+ log .info ("LS-DYNA run completed successfully." )
152
+
153
+ except subprocess .SubprocessError as e :
154
+ msg = f"Subprocess execution failed: { e } "
155
+ msg += f"to run LS-DYNA in { self .working_directory } with command: { self ._get_command_line ()} "
156
+ if log_file .exists ():
157
+ msg += f"\n See log file at: { log_file } "
158
+ log .error (msg )
159
+ raise RuntimeError (msg ) from e
118
160
119
161
def _get_command_line (self ) -> str :
120
162
"""Get the command line to run LS-DYNA."""
@@ -132,5 +174,4 @@ def _get_command_line(self) -> str:
132
174
command = (
133
175
f'mpiexec -wdir "{ self .working_directory } " -c { ncpu } -aa { self .solver } i={ input_file } memory={ mem } '
134
176
)
135
-
136
177
return f"{ script } && { command } > lsrun.out.txt 2>&1"
0 commit comments