1# -*- coding: utf-8 -*- 2 3#------------------------------------------------------------------------------- 4 5# This file is part of Code_Saturne, a general-purpose CFD tool. 6# 7# Copyright (C) 1998-2021 EDF S.A. 8# 9# This program is free software; you can redistribute it and/or modify it under 10# the terms of the GNU General Public License as published by the Free Software 11# Foundation; either version 2 of the License, or (at your option) any later 12# version. 13# 14# This program is distributed in the hope that it will be useful, but WITHOUT 15# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17# details. 18# 19# You should have received a copy of the GNU General Public License along with 20# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin 21# Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 23#------------------------------------------------------------------------------- 24 25""" 26This module defines the 'Start/Restart' page. 27 28This module defines the following classes: 29- StartRestartModel 30- StartRestartTestCase 31""" 32 33#------------------------------------------------------------------------------- 34# Library modules import 35#------------------------------------------------------------------------------- 36 37import os, sys, types 38import unittest 39 40#------------------------------------------------------------------------------- 41# Application modules import 42#------------------------------------------------------------------------------- 43 44from code_saturne.model.Common import * 45from code_saturne.model.XMLvariables import Model, Variables 46from code_saturne.model.XMLmodel import ModelTest 47 48#------------------------------------------------------------------------------- 49# Get info on a given restart path 50#------------------------------------------------------------------------------- 51 52def getRestartInfo(package, results_dir=None, restart_path='*'): 53 """ 54 Return a tuple (path, number of time steps, time value) or None 55 describing the current restart selection. 56 """ 57 58 restart_input = None 59 60 from code_saturne.cs_exec_environment import get_command_output, assemble_args 61 62 nt_names = ('nbre_pas_de_temps', 'ntcabs') 63 t_names = ('instant_precedent', 'ttcabs') 64 65 results = [] 66 67 if results_dir and restart_path == '*': 68 results = os.listdir(results_dir) 69 results.sort(reverse=True) 70 elif restart_path: 71 results = [restart_path,] 72 73 io_dump = package.get_io_dump() 74 75 for r in results: 76 if restart_path == '*': 77 m = os.path.join(results_dir, r, 'checkpoint', 'main') 78 else: 79 m = os.path.join(r, 'main') 80 if not os.path.isfile(m): 81 m += '.csc' 82 if os.path.isfile(m): 83 if True: # try: 84 nt = -1 85 for name in nt_names: 86 cmd = [io_dump, '-e', '--section'] 87 cmd.append(name) 88 cmd.append(m) 89 cmd_str = assemble_args(cmd) 90 res = get_command_output(cmd_str) 91 if res: 92 nt = -1 93 try: 94 nt = int(res.strip()) 95 break 96 except Exception: 97 pass 98 t = -1 99 for name in t_names: 100 cmd = [io_dump, '-e', '--section'] 101 cmd.append(name) 102 cmd.append(m) 103 cmd_str = assemble_args(cmd) 104 res = get_command_output(cmd_str) 105 if res: 106 t = -1 107 try: 108 t = float(res.strip()) 109 break 110 except Exception: 111 pass 112 113 return (os.path.split(m)[0], nt, t) 114 115 elif False: # except Exception: 116 d = os.path.split(m)[0] 117 print('checkpoint: ' + d + ' does not seem usable') 118 continue 119 restart_input = os.path.join(results_dir, r, 'checkpoint') 120 break 121 122 return None 123 124 125#------------------------------------------------------------------------------- 126# Start-Restart model class 127#------------------------------------------------------------------------------- 128 129class StartRestartModel(Model): 130 """ 131 Manage the input/output markups in the xml doc about Start and Restart 132 """ 133 def __init__(self, case): 134 """ 135 Constuctor. 136 """ 137 self.case = case 138 node_magt = self.case.xmlInitNode('calculation_management') 139 self.node_start = node_magt.xmlInitNode('start_restart') 140 141 142 def _defaultStartRestartValues(self): 143 """ 144 Return in a dictionnary which contains default values 145 """ 146 default = {} 147 default['restart'] = "off" 148 default['frozen_field'] = "off" 149 default['restart_with_auxiliary'] = "on" 150 default['restart_rescue'] = 0 151 default['period_rescue'] = "4 output" 152 return default 153 154 155 @Variables.noUndo 156 def getRestartPath(self): 157 """ 158 Return restart path if applicable; use '*' for automatic mode. 159 """ 160 restart = None 161 node = self.node_start.xmlGetNode('restart', 'path') 162 if node: 163 restart = node['path'] 164 return restart 165 166 167 @Variables.undoLocal 168 def setRestartPath(self, v): 169 """ 170 Set restart path if applicable; use '*' for automatic mode. 171 """ 172 node = self.node_start.xmlGetNode('restart') 173 if v: 174 if not node: 175 node = self.node_start.xmlInitNode('restart', 'path') 176 node['path'] = v 177 elif node: 178 node.xmlRemoveNode() 179 for n in self.case.xmlGetNodeList('time_average'): 180 n.xmlRemoveChild('restart_from_time_average') 181 182 183 @Variables.noUndo 184 def getRestartMeshPath(self): 185 """ 186 Return restart mesh path if applicable 187 """ 188 restart_mesh = None 189 node = self.node_start.xmlGetNode('restart_mesh', 'path') 190 if node: 191 restart_mesh = node['path'] 192 return restart_mesh 193 194 195 @Variables.undoLocal 196 def setRestartMeshPath(self, v): 197 """ 198 Set restart mesh path if applicable 199 """ 200 node = self.node_start.xmlGetNode('restart_mesh') 201 if v: 202 if not node: 203 node = self.node_start.xmlInitNode('restart_mesh', 'path') 204 node['path'] = v 205 elif node: 206 node.xmlRemoveNode() 207 208 209 @Variables.noUndo 210 def getFrozenField(self): 211 """ 212 Return if the velocity and the pressure are solved 213 """ 214 node = self.node_start.xmlInitNode('frozen_field', 'status') 215 status = node['status'] 216 if not status: 217 v = self._defaultStartRestartValues()['frozen_field'] 218 self.setFrozenField(v) 219 return status 220 221 222 @Variables.undoLocal 223 def setFrozenField(self, v): 224 """ 225 """ 226 self.isOnOff(v) 227 node = self.node_start.xmlInitNode('frozen_field', 'status') 228 node['status'] = v 229 230 231 @Variables.noUndo 232 def getRestartWithAuxiliaryStatus(self): 233 """ 234 Return status of reading auxiliary restart file for advanced options. 235 """ 236 node = self.node_start.xmlInitNode('restart_with_auxiliary', 'status') 237 status = node['status'] 238 if not status: 239 status = self._defaultStartRestartValues()['restart_with_auxiliary'] 240 self.setRestartWithAuxiliaryStatus(status) 241 return status 242 243 244 @Variables.noUndo 245 def getRestartRescue(self): 246 """ 247 Return frequency for restart checkpoints from advanced options. 248 """ 249 val = self.node_start.xmlGetInt('restart_rescue') 250 if val == None or val == 0: 251 period = self._defaultStartRestartValues()['period_rescue'] 252 val = self._defaultStartRestartValues()['restart_rescue'] 253 self.setRestartRescue(val) 254 else: 255 if val == -2: 256 period = "Never" 257 elif val == -1: 258 period = "At the end" 259 else: 260 period = "Frequency" 261 return val, period 262 263 264 @Variables.undoLocal 265 def setRestartWithAuxiliaryStatus(self, status): 266 """ 267 Input status of reading auxiliary restart file for advanced options. 268 """ 269 self.isOnOff(status) 270 node = self.node_start.xmlInitNode('restart_with_auxiliary', 'status') 271 if status != self._defaultStartRestartValues()['restart_with_auxiliary']: 272 node['status'] = status 273 else: 274 node.xmlRemoveNode() 275 276 277 @Variables.undoLocal 278 def setRestartRescue(self, freq): 279 """ 280 Inputfrequency for restart checkpoints from advanced options. 281 """ 282 self.isInt(freq) 283 self.node_start.xmlSetData('restart_rescue', freq) 284 285 286#------------------------------------------------------------------------------- 287# StartRestartModel test case 288#------------------------------------------------------------------------------- 289 290 291class StartRestartTestCase(ModelTest): 292 """ 293 """ 294 def checkStartRestartInstantiation(self): 295 """ 296 Check whether the StartRestartModel class could be instantiated 297 """ 298 model = None 299 model = StartRestartModel(self.case) 300 assert model != None, 'Could not instantiate StartRestartModel' 301 302 def checkSetandGetRestart(self): 303 """ 304 Check whether the restart method could be set and get 305 """ 306 model = StartRestartModel(self.case) 307 model.setRestartPath("RESU/test/restart") 308 doc= '''<start_restart> 309 <restart path="RESU/test/restart"/> 310 </start_restart>''' 311 312 assert model.node_start == self.xmlNodeFromString(doc),\ 313 'Could not set restart in StartRestart model' 314 assert model.getRestartPath() == 'RESU/test/restart',\ 315 'Could not get restart in StartRestart model' 316 317 def checkSetandGetFrozenStatus(self): 318 """ 319 Check whether the Frozen status method could be set and get 320 """ 321 model = StartRestartModel(self.case) 322 model.setRestart("on") 323 model.setFrozenField('on') 324 doc = '''<start_restart> 325 <restart status="on"/> 326 <frozen_field status="on"/> 327 </start_restart>''' 328 assert model.node_start == self.xmlNodeFromString(doc),\ 329 'Could not set frozen status in StartRestart model' 330 assert model.getFrozenField() == "on",\ 331 'Could not get frozen status in StartRestart model' 332 333 def checkSetAuxiliaryRestartStatus(self): 334 """ 335 Check whether the Auxiliary Restart Status method 336 could be set and get 337 """ 338 model = StartRestartModel(self.case) 339 model.setRestart("on") 340 model.setRestartWithAuxiliaryStatus('on') 341 doc= '''<start_restart> 342 <restart status="on"/> 343 <restart_with_auxiliary status="on"/> 344 </start_restart>''' 345 assert model.node_start == self.xmlNodeFromString(doc),\ 346 'Could not set auxiliary restart status in StartRestart model' 347 assert model.getRestartWithAuxiliaryStatus() == "on",\ 348 'Could not get auxiliary restart status in StartRestart model' 349 350 def checkSetandGetRestartRescue(self): 351 """ 352 Check whether the Restart rescue could be set and get 353 """ 354 model = StartRestartModel(self.case) 355 model.setRestart("on") 356 model.setRestartRescue(15) 357 doc = '''<start_restart> 358 <restart status="on"/> 359 <restart_rescue>15</restart_rescue> 360 </start_restart>''' 361 assert model.node_start == self.xmlNodeFromString(doc),\ 362 'Could not set restart rescue value in StartRestart model' 363 freq, period = model.getRestartRescue() 364 assert freq == 15,\ 365 'Could not get restart rescue value in StartRestart model' 366 assert period == "Frequency",\ 367 'Could not get restart rescue period in StartRestart model' 368 369 model.setRestartRescue(-1) 370 freq, period = model.getRestartRescue() 371 assert freq == -1,\ 372 'Could not get restart rescue value in StartRestart model' 373 assert period == "At the end",\ 374 'Could not get restart rescue period in StartRestart model' 375 376 377def suite(): 378 testSuite = unittest.makeSuite(StartRestartTestCase, "check") 379 return testSuite 380 381 382def runTest(): 383 print("StartRestartTestCase") 384 runner = unittest.TextTestRunner() 385 runner.run(suite()) 386 387 388#------------------------------------------------------------------------------- 389# End 390#------------------------------------------------------------------------------- 391