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#------------------------------------------------------------------------------- 26# Library modules import 27#------------------------------------------------------------------------------- 28 29import string 30import unittest 31 32#------------------------------------------------------------------------------- 33# Application modules import 34#------------------------------------------------------------------------------- 35 36from code_saturne.model.XMLvariables import Model, Variables 37from code_saturne.model.XMLmodel import ModelTest 38from code_saturne.model.XMLengine import * 39from code_saturne.model.TurbulenceNeptuneModel import TurbulenceModelsDescription 40 41class NumericalParamEquatModel(Model): 42 43 """ 44 This class manages the turbulence objects in the XML file 45 """ 46 47 def __init__(self, case) : 48 """ 49 Constuctor. 50 """ 51 # 52 # XML file parameters 53 self.case = case 54 self.XMLThermo = self.case.xmlGetNode('thermophysical_models') 55 self.XMLNodeVariable = self.XMLThermo.xmlGetNode('variables') 56 self.XMLClosure = self.case.xmlGetNode('closure_modeling') 57 self.XMLTurbulence = self.XMLClosure.xmlInitNode('turbulence') 58 self.XMLTurbVariable = self.XMLTurbulence.xmlInitNode('variables') 59 self.XMLAddScalar = self.case.xmlInitNode('additional_scalars') 60 self.XMLScalar = self.XMLAddScalar.xmlInitNode('scalars') 61 self.XMLnonCond = self.XMLThermo.xmlInitNode('non_condensable_list') 62 63 self.imgra_model = ['iterative_handling', \ 64 'sweep_linear', \ 65 'sweep_linear_ext_neigh', \ 66 'least_square_linear', \ 67 'least_square_linear_ext_neigh', \ 68 'iterative_handling_weighted', \ 69 'least_square_linear_weighted', \ 70 'least_square_linear_ext_neigh_weighted'] 71 72 73 def defaultValues(self) : 74 default = {} 75 76 default['max_iter_number'] = 10000 77 default['solver_precision'] = 1e-5 78 default['solver_precision_alpha'] = 1e-8 79 default['solver_precision_enthal'] = 1e-7 80 default['slope_test'] = 'on' 81 default['flux_reconstruction'] = 'off' 82 default['order_scheme'] = 'solu' 83 default['order_scheme_pressure_turbulence'] = 'upwind' 84 default['solver'] = 'automatic' 85 default['gradient_reconstruction'] = 'sweep_linear_ext_neigh' 86 return default 87 88 89 def getVariableList(self) : 90 """ 91 return list of variables 92 """ 93 list = [] 94 from code_saturne.model.MainFieldsModel import MainFieldsModel 95 for node in self.XMLNodeVariable.xmlGetNodeList('variable') : 96 if self._isPressure(node) != 1 : 97 # control to add enthalpy only if solved!!! 98 if self._isEnthalpy(node) == 1 : 99 field = node['field_id'] 100 if MainFieldsModel(self.case).getEnergyResolution(field) == "on": 101 list.append(node['label']) 102 else: 103 list.append(node['label']) 104 105 if self.XMLTurbVariable != None: 106 for node in self.XMLTurbVariable.xmlGetNodeList('variable') : 107 list.append(node['label']) 108 109 for node in self.XMLScalar.xmlGetNodeList('variable') : 110 list.append(node['label']) 111 112 for node in self.XMLnonCond.xmlGetNodeList('variable') : 113 list.append(node['label']) 114 115 del MainFieldsModel 116 return list 117 118 119 def _isPressure(self, node) : 120 """ 121 Return : 1 if name of node is 'pressure', 0 if not 122 """ 123 if node and node['name'] == 'pressure': 124 return 1 125 else: 126 return 0 127 128 129 def _isTurbulenceVariable(self, node) : 130 """ 131 Return : 1 if name of node is a turbulence variable, 0 if not 132 """ 133 if node and node['name'] in TurbulenceModelsDescription.turbulenceVariables['all'] : 134 return 1 135 else: 136 return 0 137 138 139 def _isAlpha(self, node) : 140 """ 141 Return : 1 if name of node is 'alpha', 0 if not 142 """ 143 if node and node['name'] == 'volume_fraction': 144 return 1 145 else: 146 return 0 147 148 149 def _isEnthalpy(self, node): 150 """ 151 Return : 1 if name of node is 'enthalpy', 0 if not 152 """ 153 if node and node['name'] == 'enthalpy': 154 return 1 155 else: 156 return 0 157 158 159 def _getSchemeLabelNode(self, label): 160 """ Private method: return node called with label'label' for scheme nodes""" 161 for node in self.XMLNodeVariable.xmlGetNodeList('variable') : 162 if node['label'] == label: 163 if node['label'] == 'Pressure': 164 raise ValueError("This method does not run with pressure") 165 else: 166 return node 167 for node in self.XMLTurbVariable.xmlGetNodeList('variable') : 168 if node['label'] == label: 169 return node 170 171 for node in self.XMLScalar.xmlGetNodeList('variable') : 172 if node['label'] == label: 173 return node 174 175 for node in self.XMLnonCond.xmlGetNodeList('variable') : 176 if node['label'] == label: 177 return node 178 179 raise ValueError("This label does not exist: " + label) 180 181 182 @Variables.undoGlobal 183 def setSchemeModel(self, label, value) : 184 """ 185 Put value of order scheme for variable or scalar labelled label 186 only if it 's different of default value 187 """ 188 self.isInList(value, ('upwind', 'centered', 'solu')) 189 node = self._getSchemeLabelNode(label) 190 defval = self.defaultValues()['order_scheme'] 191 if (self._isTurbulenceVariable(node)) : 192 defval = self.defaultValues()['order_scheme_pressure_turbulence'] 193 194 if value == defval : 195 node.xmlRemoveChild('scheme') 196 else: 197 n = node.xmlInitNode('scheme') 198 n['choice'] = value 199 200 if value == "upwind": 201 self.setSlopeTestStatus(label, "off") 202 else: 203 self.setSlopeTestStatus(label, "on") 204 205 206 @Variables.noUndo 207 def getSchemeModel(self, label) : 208 """ 209 Return value of order scheme for variable labelled label 210 """ 211 node = self._getSchemeLabelNode(label) 212 value = self.defaultValues()['order_scheme'] 213 if (self._isTurbulenceVariable(node)) : 214 value = self.defaultValues()['order_scheme_pressure_turbulence'] 215 n = node.xmlGetNode('scheme') 216 if n: 217 value = n['choice'] 218 return value 219 220 221 @Variables.undoLocal 222 def setSlopeTestStatus(self, label, status) : 223 """ 224 Put status of slope test for variable labelled label 225 """ 226 self.isOnOff(status) 227 node = self._getSchemeLabelNode(label) 228 if status == self.defaultValues()['slope_test']: 229 node.xmlRemoveChild('slope_test') 230 else: 231 n = node.xmlInitNode('slope_test') 232 n['status'] = status 233 234 235 @Variables.noUndo 236 def getSlopeTestStatus(self, label) : 237 """ 238 Return value of slope test for variable labelled label 239 """ 240 node = self._getSchemeLabelNode(label) 241 value = self.defaultValues()['slope_test'] 242 n = node.xmlGetNode('slope_test') 243 if n: 244 value = n['status'] 245 return value 246 247 248 @Variables.undoLocal 249 def setSolverModel(self, label, value) : 250 """ 251 Put value of solver for variable or scalar labelled label 252 """ 253 self.isInList(value, ('automatic', 'jacobi', 'pcg', 'cgstab', 'jacobi_saturne', 'pcg_saturne', 'bicgstab_saturne', 'bicgstab2_saturne', 'gmres_saturne', 'gauss_seidel_saturne', 'sym_gauss_seidel_saturne', 'pcr3_saturne')) 254 node = self._getSchemeLabelNode(label) 255 default = self.defaultValues()['solver'] 256 if value == default: 257 node.xmlRemoveChild('solver') 258 else: 259 n = node.xmlInitNode('solver') 260 n['choice'] = value 261 262 263 @Variables.noUndo 264 def getSolverModel(self, label) : 265 """ 266 Return value of solver for variable labelled label 267 """ 268 node = self._getSchemeLabelNode(label) 269 value = self.defaultValues()['solver'] 270 n = node.xmlGetNode('solver') 271 if n: 272 value = n['choice'] 273 return value 274 275 276 @Variables.undoLocal 277 def setSolverPrecision(self, label, value) : 278 """ 279 Put value of solveur precision for variable labelled label 280 """ 281 self.isPositiveFloat(value) 282 node = self._getSchemeLabelNode(label) 283 default = self.defaultValues()['solver_precision'] 284 if self._isAlpha(node): 285 default = self.defaultValues()['solver_precision_alpha'] 286 elif self._isEnthalpy(node): 287 default = self.defaultValues()['solver_precision_enthal'] 288 289 if value != default: 290 node.xmlSetData('solver_precision', value) 291 else: 292 node.xmlRemoveChild('solver_precision') 293 294 295 @Variables.noUndo 296 def getSolverPrecision(self, label) : 297 """ 298 Return value of solveur precision for variable labelled label 299 """ 300 node = self._getSchemeLabelNode(label) 301 302 default = self.defaultValues()['solver_precision'] 303 if self._isAlpha(node): 304 default = self.defaultValues()['solver_precision_alpha'] 305 elif self._isEnthalpy(node): 306 default = self.defaultValues()['solver_precision_enthal'] 307 308 value = node.xmlGetDouble('solver_precision') 309 if value == None: 310 value = default 311 return value 312 313 314 @Variables.undoLocal 315 def setMaximumIteration(self, label, value) : 316 """ 317 Put number of maximum iterations for variable labelled label 318 """ 319 self.isInt(value) 320 node = self._getSchemeLabelNode(label) 321 default = self.defaultValues()['max_iter_number'] 322 if value != default : 323 node.xmlSetData('max_iter_number', value) 324 else: 325 node.xmlRemoveChild('max_iter_number') 326 327 328 @Variables.noUndo 329 def getMaximumIteration(self, label) : 330 """ 331 Return number of maximum iterations for variable labelled label 332 """ 333 node = self._getSchemeLabelNode(label) 334 value = node.xmlGetInt('max_iter_number') 335 if value == None: 336 value = self.defaultValues()['max_iter_number'] 337 return value 338 339 340 def getPressureNodefields(self): 341 for node in self.XMLNodeVariable.xmlGetNodeList('variable') : 342 if node['label'] == 'Pressure': 343 return node 344 345#------------------------------------------------------------------------------- 346# DefineUsersScalars test case 347#------------------------------------------------------------------------------- 348 349class NumericalParamEquatTestCase(ModelTest): 350 """ 351 """ 352 def checkNumericalParamEquatInstantiation(self): 353 """Check whether the NumericalParamEquationModel class could be instantiated""" 354 model = None 355 model = NumericalParamEquatModel(self.case) 356 assert model != None, 'Could not instantiate NumericalParamEquationModel' 357 358 359 def checkGetVariableList(self): 360 """Check whether the NumericalParamEquationModel class could get the VariableList""" 361 from code_saturne.model.MainFieldsModel import MainFieldsModel 362 MainFieldsModel(self.case).addField() 363 mdl = NumericalParamEquatModel(self.case) 364 assert mdl.getVariableList() == ['enthalpy1', 'alpha1', 'U1', 'V1', 'W1'],\ 365 'Could not get VariableList' 366 367 368 def checkGetandSetSchemeModel(self): 369 """Check whether the NumericalParamEquationModel class could be set and get SchemeModel""" 370 from code_saturne.model.MainFieldsModel import MainFieldsModel 371 MainFieldsModel(self.case).addField() 372 mdl = NumericalParamEquatModel(self.case) 373 mdl.setSchemeModel('pressure','solu') 374 doc = '''<variable field_id="none" label="Pressure" name="pressure"> 375 <listing_printing status="on"/> 376 <postprocessing_recording status="on"/> 377 <scheme choice="solu"/> 378 </variable>''' 379 assert mdl.getPressureNodefields() == self.xmlNodeFromString(doc),\ 380 'Could not set SchemeModel' 381 assert mdl.getSchemeModel('Pressure') == 'solu',\ 382 'Could not get SchemeModel' 383 384 385 def checkGetandSetSlopeTestStatus(self): 386 """Check whether the NumericalParamEquationModel class could be set and get SlopeTestStatus""" 387 from code_saturne.model.MainFieldsModel import MainFieldsModel 388 MainFieldsModel(self.case).addField() 389 mdl = NumericalParamEquatModel(self.case) 390 mdl.setSlopeTestStatus('Pressure','off') 391 doc = '''<variable field_id="none" label="Pressure" name="pressure"> 392 <listing_printing status="on"/> 393 <postprocessing_recording status="on"/> 394 <slope_test status="off"/> 395 </variable>''' 396 assert mdl.getPressureNodefields() == self.xmlNodeFromString(doc),\ 397 'Could not set SlopeTestStatus' 398 assert mdl.getSlopeTestStatus('Pressure') == 'off',\ 399 'Could not get SlopeTestStatus' 400 401 402 def checkGetandSetSolverModel(self): 403 """Check whether the NumericalParamEquationModel class could be set and get SolverModel""" 404 from code_saturne.model.MainFieldsModel import MainFieldsModel 405 MainFieldsModel(self.case).addField() 406 mdl = NumericalParamEquatModel(self.case) 407 mdl.setSolverModel('Pressure','jacobi') 408 doc = '''<variable field_id="none" label="Pressure" name="pressure"> 409 <listing_printing status="on"/> 410 <postprocessing_recording status="on"/> 411 <solver choice="jacobi"/> 412 </variable>''' 413 assert mdl.getPressureNodefields() == self.xmlNodeFromString(doc),\ 414 'Could not set SolverModel' 415 assert mdl.getSolverModel('Pressure') == 'jacobi',\ 416 'Could not get SolverModel' 417 418 419 def checkGetandSetSolverPrecision(self): 420 """Check whether the NumericalParamEquationModel class could be set and get SolverPrecision""" 421 from code_saturne.model.MainFieldsModel import MainFieldsModel 422 MainFieldsModel(self.case).addField() 423 mdl = NumericalParamEquatModel(self.case) 424 mdl.setSolverPrecision('Pressure',56.23) 425 doc = '''<variable field_id="none" label="Pressure" name="pressure"> 426 <listing_printing status="on"/> 427 <postprocessing_recording status="on"/> 428 <solver_precision> 429 56.23 430 </solver_precision> 431 </variable>''' 432 assert mdl.getPressureNodefields() == self.xmlNodeFromString(doc),\ 433 'Could not set SolverPrecision' 434 assert mdl.getSolverPrecision('Pressure') == 56.23,\ 435 'Could not get SolverPrecision' 436 437 438 def checkGetandSetMaximumIteration(self): 439 """Check whether the NumericalParamEquationModel class could be set and get MaximumIteration""" 440 from code_saturne.model.MainFieldsModel import MainFieldsModel 441 MainFieldsModel(self.case).addField() 442 mdl = NumericalParamEquatModel(self.case) 443 mdl.setMaximumIteration('Pressure',18) 444 doc = '''<variable field_id="none" label="Pressure" name="pressure"> 445 <listing_printing status="on"/> 446 <postprocessing_recording status="on"/> 447 <max_iter_number> 448 18 449 </max_iter_number> 450 </variable>''' 451 assert mdl.getPressureNodefields() == self.xmlNodeFromString(doc),\ 452 'Could not set MaximumIteration' 453 assert mdl.getMaximumIteration('Pressure') == 18,\ 454 'Could not get MaximumIteration' 455 456 457def suite(): 458 testSuite = unittest.makeSuite(NumericalParamEquatTestCase, "check") 459 return testSuite 460 461 462def runTest(): 463 print("NumericalParamEquatTestCase") 464 runner = unittest.TextTestRunner() 465 runner.run(suite()) 466