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 page is devoted to the time step management.
27
28This module contains the following classes and function:
29- TimeStepModel
30- TimeStepModelTestCase
31"""
32
33#-------------------------------------------------------------------------------
34# Library modules import
35#-------------------------------------------------------------------------------
36
37import unittest
38
39#-------------------------------------------------------------------------------
40# Application modules import
41#-------------------------------------------------------------------------------
42
43from code_saturne.model.Common import *
44from code_saturne.model.XMLvariables import Variables, Model
45from code_saturne.model.XMLmodel import ModelTest
46from code_saturne.model.OutputVolumicVariablesModel import OutputVolumicVariablesModel
47
48#-------------------------------------------------------------------------------
49# Time Step Model class
50#-------------------------------------------------------------------------------
51
52class TimeStepModel(Model):
53    """
54    Class to open the Time Step Page.
55    """
56    def __init__(self, case):
57        """
58        Constructor.
59        """
60        self.case =case
61
62        self.node_models       = self.case.xmlGetNode('thermophysical_models')
63        self.node_turb         = self.node_models.xmlGetNode('turbulence')
64        self.node_control      = self.case.xmlGetNode('analysis_control')
65        self.node_np           = self.case.xmlGetNode('numerical_parameters')
66        self.node_time         = self.node_control.xmlInitNode('time_parameters')
67
68
69    def defaultValues(self):
70        """
71        Return in a dictionnary which contains default values
72        """
73        default = {}
74
75        default['iterations']             = 10
76        default['time_passing']           = 0
77        default['velocity_pressure_algo'] ='simplec'
78        default['time_step_ref']          = 0.1
79        default['max_courant_num']        = 1.0
80        default['max_fourier_num']        = 10.0
81        default['relaxation_coefficient'] = 0.7
82        default['time_step_min_factor']   = 0.1
83        default['time_step_max_factor']   = 1000.0
84        default['time_step_var']          = 0.1
85        default['thermal_time_step']      = 'off'
86        from code_saturne.model.CompressibleModel import CompressibleModel
87        if CompressibleModel(self.case).getCompressibleModel() != 'off':
88            default['piso_sweep_number'] = 1
89        else:
90            default['piso_sweep_number'] = 2
91        del CompressibleModel
92
93        return default
94
95
96    def thermalCase(self):
97        """
98        Is the current case adapted for IPTLRO ?
99        """
100        thermal_case = 0
101        from code_saturne.model.FluidCharacteristicsModel import FluidCharacteristicsModel
102        n_atmo, n_joul, n_thermo, n_gas, n_coal, n_comp, n_hgn = \
103            FluidCharacteristicsModel(self.case).getThermoPhysicalModel()
104
105        if n_atmo != 'off' or n_joul != 'off' or  n_thermo != 'off' or  n_gas != 'off' or  n_coal != 'off':
106           thermal_case = 1
107
108        # gravity
109        from code_saturne.model.BodyForcesModel import BodyForcesModel
110        mdl = BodyForcesModel(self.case)
111        gx = mdl.getGravity('gravity_x')
112        gy = mdl.getGravity('gravity_y')
113        gz = mdl.getGravity('gravity_z')
114        if gx == 0.0 and gy  == 0.0 and gz == 0.0:
115            thermal_case = 0
116
117        # variable rho
118        if FluidCharacteristicsModel(self.case).getPropertyMode('density') == 'constant':
119            thermal_case = 0
120
121        del FluidCharacteristicsModel
122        del BodyForcesModel
123        return thermal_case
124
125
126    @Variables.noUndo
127    def getTimePassing(self):
128        """
129        Get value of time_passing (IDTVAR) for node "time_parameters"
130        """
131        tag = 'time_passing'
132        v = self.node_time.xmlGetInt(tag)
133        if v == None:
134            v = self.defaultValues()[tag]
135            self.setTimePassing(v)
136
137        from code_saturne.model.TurbulenceModel import TurbulenceModel
138        model = TurbulenceModel(self.case).getTurbulenceModel()
139        del TurbulenceModel
140        if model in ('LES_Smagorinsky', 'LES_dynamique', 'LES_WALE'):
141            v = 0
142            self.setTimePassing(v)
143
144        return v
145
146
147    @Variables.undoGlobal
148    def setTimePassing(self, val):
149        """
150        Get value of time_passing (IDTVAR) for node "time_parameters"
151        Used also by TurbulenceModel
152        """
153        self.isIntInList(val, [0, 1, 2, -1])
154        self.node_time.xmlSetData('time_passing', val)
155
156        if val == -1:
157            algo = "simple"
158        else:
159            algo = self.getVelocityPressureAlgorithm()
160            if algo == "simple":
161                algo = "simplec"
162        self.setVelocityPressureAlgorithm(algo)
163
164        from code_saturne.model.GroundwaterModel import GroundwaterModel
165        if GroundwaterModel(self.case).getGroundwaterModel() == 'off':
166            Variables(self.case).setNewProperty(self.node_time, 'courant_number')
167            Variables(self.case).setNewProperty(self.node_time, 'fourier_number')
168        else:
169            nn = self.node_time.xmlGetNode('property', name='courant_number')
170            if nn:
171                nn.xmlRemoveNode()
172            nn = self.node_time.xmlGetNode('property', name='fourier_number')
173            if nn:
174                nn.xmlRemoveNode()
175        del GroundwaterModel
176
177        if val in (1, 2):
178            Variables(self.case).setNewProperty(self.node_time, 'local_time_step')
179            n = self.node_time.xmlInitNode('property', name='local_time_step')
180            if val == 1:
181                n.xmlInitNode('postprocessing_recording')['status']= "off"
182                n.xmlInitNode('probes')['choice']= "0"
183            else:
184                n.xmlRemoveChild('postprocessing_recording')
185                n.xmlRemoveChild('probes')
186        else:
187            self.node_time.xmlRemoveChild('property', name='local_time_step')
188            for tag in ('max_courant_num',
189                        'max_fourier_num',
190                        'time_step_min_factor',
191                        'time_step_max_factor',
192                        'time_step_var'):
193                self.node_time.xmlRemoveChild(tag)
194
195
196    @Variables.noUndo
197    def getVelocityPressureAlgorithm(self):
198        """
199        Return velocity pressure algoritm value
200        """
201        node = self.node_np.xmlInitNode('velocity_pressure_algo','choice')
202        value = node['choice']
203        if not value:
204            value = self.defaultValues()['velocity_pressure_algo']
205            self.setVelocityPressureAlgorithm(value)
206        return value
207
208
209    @Variables.undoGlobal
210    def setVelocityPressureAlgorithm(self, value):
211        """
212        Put value of velocity pressure algorithm
213        """
214        self.isInList(value, ('simple', 'simplec', 'piso'))
215        node = self.node_np.xmlInitNode('velocity_pressure_algo', 'choice')
216        node['choice'] = value
217        if value == 'simple' or value =='simplec':
218            self.setVelocityPressureParamSweepNumber(1)
219        else:
220            default = self.defaultValues()['piso_sweep_number']
221            if self.getVelocityPressureParamSweepNumber() < default:
222                value = default
223                self.setVelocityPressureParamSweepNumber(value)
224
225
226    @Variables.noUndo
227    def getVelocityPressureParamSweepNumber(self):
228        """
229        Return piso_sweep_number value
230        """
231        self.node_algo = self.node_np.xmlGetNode('velocity_pressure_algo')
232        value = self.node_algo.xmlGetInt('piso_sweep_number')
233        if value == None:
234            value = self.defaultValues()['piso_sweep_number']
235        return value
236
237
238    @Variables.undoLocal
239    def setVelocityPressureParamSweepNumber(self, value):
240        """
241        Put value of NTRUP
242        """
243        self.isInt(value)
244        self.node_algo = self.node_np.xmlGetNode('velocity_pressure_algo')
245        self.node_algo.xmlSetData('piso_sweep_number', value, default=1)
246
247
248    @Variables.noUndo
249    def getRelaxCoefficient(self):
250        """
251        Get value of coefficient of relaxation from xml file.
252        """
253        tag = 'relaxation_coefficient'
254        v = self.node_time.xmlGetDouble(tag)
255        if v == None:
256            v = self.defaultValues()[tag]
257            self.setRelaxCoefficient(v)
258
259        return v
260
261
262    @Variables.undoLocal
263    def setRelaxCoefficient(self, value):
264        """
265        Set value of coefficient of relaxation into xml file.
266        """
267        self.isGreater(value, 0.)
268        self.isLowerOrEqual(value, 1.)
269        self.node_time.xmlSetData('relaxation_coefficient', value)
270
271
272    @Variables.noUndo
273    def getTimeStep(self):
274        """
275        Get value of time_step_reference for node "time_parameters"
276        """
277        tag = 'time_step_ref'
278        v = self.node_time.xmlGetDouble(tag)
279        if v == None:
280            v = self.defaultValues()[tag]
281            self.setTimeStep(v)
282
283        return v
284
285
286    @Variables.undoLocal
287    def setTimeStep(self, val):
288        """
289        Get value of time_step_reference for node "time_parameters"
290        """
291        self.isPositiveFloat(val)
292        self.node_time.xmlSetData('time_step_ref', val)
293
294
295    @Variables.noUndo
296    def getStopCriterion(self):
297        """
298        Get stop criterion type and value for node "time_parameters"
299        """
300        crit_type = None
301        value = None
302
303        for tag in ('iterations', 'iterations_add'):
304            v = self.node_time.xmlGetInt(tag)
305            if v != None:
306                crit_type = tag
307                value = v
308
309        if not crit_type:
310            for tag in ('maximum_time', 'maximum_time_add'):
311                v = self.node_time.xmlGetDouble(tag)
312                if v != None:
313                    crit_type = tag
314                    value = v
315
316        if not crit_type:
317            crit_type = 'iterations'
318            value = self.defaultValues()[crit_type]
319
320        return crit_type, value
321
322
323    @Variables.undoLocal
324    def setStopCriterion(self, type, val):
325        """
326        Put number of iterations for node "time_parameters"
327        """
328
329        for tag in ('iterations', 'iterations_add',
330                    'maximum_time', 'maximum_time_add'):
331            if tag == type:
332                self.node_time.xmlSetData(tag, val)
333            else:
334                n = self.node_time.xmlGetNode(tag)
335                if n:
336                    n.xmlRemoveNode()
337
338
339    @Variables.noUndo
340    def getMaxCourant(self):
341        """
342        Return the max courant number allowed
343        """
344        tag = 'max_courant_num'
345        return self.getOptions(tag)
346
347
348    @Variables.undoGlobal
349    def setMaxCourant(self, val):
350        """
351        Input the max courant number allowed
352        """
353        self.isStrictPositiveFloat(val)
354        self.setOptions('max_courant_num', val)
355
356
357    @Variables.noUndo
358    def getMaxFourier(self):
359        """
360        Return the max fourier number allowed
361        """
362        tag = 'max_fourier_num'
363        return self.getOptions(tag)
364
365
366    @Variables.undoGlobal
367    def setMaxFourier(self, val):
368        """
369        Input the max fourier number allowed
370        """
371        self.isStrictPositiveFloat(val)
372        self.setOptions('max_fourier_num', val)
373
374
375    @Variables.noUndo
376    def getTimeStepMinFactor(self):
377        """
378        Return the minimal time step factor
379        """
380        tag = 'time_step_min_factor'
381        return self.getOptions(tag)
382
383
384    @Variables.undoGlobal
385    def setTimeStepMinFactor(self, val):
386        """
387        Input the minimal time step factor
388        """
389        self.isPositiveFloat(val)
390        self.setOptions('time_step_min_factor', val)
391
392
393    @Variables.noUndo
394    def getTimeStepMaxFactor(self):
395        """
396        Return the maximal time step factor
397        """
398        tag = 'time_step_max_factor'
399        return self.getOptions(tag)
400
401
402    @Variables.undoGlobal
403    def setTimeStepMaxFactor(self, val):
404        """
405        Input the maximal time step factor
406        """
407        self.isStrictPositiveFloat(val)
408        self.setOptions('time_step_max_factor', val)
409
410
411    @Variables.noUndo
412    def getTimeStepVariation(self):
413        """
414        Return the maximal variation of time step between two iteration
415        """
416        tag = 'time_step_var'
417        return self.getOptions(tag)
418
419
420    @Variables.undoGlobal
421    def setTimeStepVariation(self, val):
422        """
423        Input the maximal variation of time step between two iteration
424        """
425        self.isStrictPositiveFloat(val)
426        self.setOptions('time_step_var', val)
427
428
429    @Variables.noUndo
430    def getOptions(self, tag):
431        """
432        Get options for node "time_parameters"
433        """
434        if self.getTimePassing() == 0:
435            msg = "No option : " + tag + " in this case"
436            raise ValueError(msg)
437
438        v = self.node_time.xmlGetChildDouble(tag)
439        if v == None:
440            v = self.defaultValues()[tag]
441            self.setOptions(tag, v)
442        return v
443
444
445    @Variables.undoLocal
446    def setOptions(self, tag, val):
447        """
448        Put options for node "time_parameters"
449        """
450        if self.getTimePassing() == 0:
451            msg = "No option : " + tag + " in this case"
452            raise ValueError(msg)
453
454        if tag == 'time_step_min_factor':
455            self.isPositiveFloat(val)
456        else:
457            self.isStrictPositiveFloat(val)
458        self.node_time.xmlSetData(tag, val)
459
460
461    @Variables.noUndo
462    def getThermalTimeStep(self):
463        """
464        Get status of thermal_time_step for node "time_parameters"
465        """
466        if not self.thermalCase():
467            raise ValueError("TimeStepModel: no thermal model in this case")
468
469        node = self.node_time.xmlInitChildNode('thermal_time_step', 'status')
470        s = node['status']
471        if not s:
472            s = self.defaultValues()['thermal_time_step']
473            self.setThermalTimeStep(s)
474        return s
475
476
477    @Variables.undoLocal
478    def setThermalTimeStep(self, status):
479        """
480        Put status of thermal_time_step for node "time_parameters"
481        """
482
483        if not self.thermalCase():
484            raise ValueError("TimeStepModel: no thermal model in this case")
485
486        self.isOnOff(status)
487        node = self.node_time.xmlInitChildNode('thermal_time_step', 'status')
488        node['status'] = status
489
490
491    def RemoveThermalTimeStepNode(self):
492        """
493        Remove Thermal time step node for node "time_parameters"
494        Also called by ThermalScalarModel
495        """
496        node = self.node_time.xmlGetNode('thermal_time_step')
497        if node:
498            self.node_time.xmlRemoveChild('thermal_time_step')
499
500#-------------------------------------------------------------------------------
501# TimeStepModel Test Class
502#-------------------------------------------------------------------------------
503
504class TimeStepModelTestCase(ModelTest):
505    """
506    """
507    def checkTimeStepModelInstantiation(self):
508        """Check whether the TimeStepModel class could be instantiated"""
509        mdl = None
510        mdl = TimeStepModel(self.case)
511        assert mdl != None, 'Could not instantiate TimeStepModel'
512
513    def checkSetandGetTimePassing(self):
514        """Check whether the TimeStepModel class could be set and get time passing"""
515        mdl = TimeStepModel(self.case)
516        mdl.setTimePassing(1)
517        doc = '''<time_parameters>
518                    <property label="Courant nb" name="courant_number"/>
519                    <property label="Fourier nb" name="fourier_number"/>
520                    <time_step_ref>0.1</time_step_ref>
521                    <iterations>10</iterations>
522                    <time_passing>1</time_passing>
523                    <property label="loc.time" name="local_time_step"/>
524                 </time_parameters>'''
525        assert mdl.node_time == self.xmlNodeFromString(doc),\
526            'Could not set time passing in TimeStepModel'
527        assert mdl.getTimePassing() == 1,\
528            'Could not get time passing in TimeStepModel'
529
530        mdl.setTimePassing(0)
531        doc = '''<time_parameters>
532                    <property label="Courant nb" name="courant_number"/>
533                    <property label="Fourier nb" name="fourier_number"/>
534                    <time_step_ref>0.1</time_step_ref>
535                    <iterations>10</iterations>
536                    <time_passing>0</time_passing>
537                 </time_parameters>'''
538        assert mdl.node_time == self.xmlNodeFromString(doc),\
539            'Could not remove local time step node in TimeStepModel'
540
541        mdl.setTimePassing(2)
542        mdl.setTimeStepMin(0.05)
543        mdl.setTimeStepMax(500)
544        mdl.setTimeStepVariation(0.25)
545        mdl.setTimePassing(0)
546        doc = '''<time_parameters>
547                    <property label="Courant nb" name="courant_number"/>
548                    <property label="Fourier nb" name="fourier_number"/>
549                    <time_step_ref>0.1</time_step_ref>
550                    <iterations>10</iterations>
551                    <time_passing>0</time_passing>
552                 </time_parameters>'''
553        assert mdl.node_time == self.xmlNodeFromString(doc),\
554            'Could not remove tagged time node in TimeStepModel'
555
556    def checkGetandSetVelocityPressureAlgorithm(self):
557        """
558        Check whether velocity pressure algorithm could be set and get
559        """
560        model = NumericalParamGlobalModel(self.case)
561        model.setVelocityPressureAlgorithm('piso')
562        doc = '''<numerical_parameters>
563                         <velocity_pressure_algo choice="piso"/>
564                 </numerical_parameters>'''
565        assert model.node_np== self.xmlNodeFromString(doc), \
566                    'Could not set velocity pressure algorithm'
567        assert model.getVelocityPressureAlgorithm() == 'piso',\
568                    'Could not get velocity pressure algorithm'
569
570    def checkGetandSetNterup(self):
571        """
572        Check whether velocity pressure algorithm could be set and get
573        """
574        model = NumericalParamGlobalModel(self.case)
575        model.setVelocityPressureAlgorithm('piso')
576        model.setNterup(3)
577        doc = '''<numerical_parameters>
578                         <velocity_pressure_algo choice="piso">
579                                 <piso_sweep_number>
580                                         3
581                                 </piso_sweep_number>
582                         </velocity_pressure_algo>
583                 </numerical_parameters>'''
584        assert model.node_np == self.xmlNodeFromString(doc), \
585                    'Could not set nterup'
586        assert model.getNterup() == 3,\
587                    'Could not get nterup'
588
589    def checkSetandGetIterationsNumber(self):
590        """Check whether the TimeStepModel class could be set and get number of iterations"""
591        mdl = TimeStepModel(self.case)
592        mdl.setStopCriterion('iterations', 50)
593        doc = '''<time_parameters>
594                    <property label="Courant nb" name="courant_number"/>
595                    <property label="Fourier nb" name="fourier_number"/>
596                    <time_step_ref>0.1</time_step_ref>
597                    <iterations>50</iterations>
598                    <time_passing>0</time_passing>
599                 </time_parameters>'''
600        assert mdl.node_time == self.xmlNodeFromString(doc),\
601            'Could not set number of iterations in TimeStepModel'
602        assert mdl.getStopCriterion()[1] == 50,\
603            'Could not get number of iterations in TimeStepModel'
604
605    def checkSetandGetMaxCourant(self):
606        """Check whether the TimeStepModel class could be
607        set and get max courant number : option(s) only for idtvar = 1 or 2"""
608        mdl = TimeStepModel(self.case)
609        mdl.setTimePassing(1)
610        mdl.setMaxCourant(10)
611        doc = '''<time_parameters>
612                    <property label="Courant nb" name="courant_number"/>
613                    <property label="Fourier nb" name="fourier_number"/>
614                    <time_step_ref>0.1</time_step_ref>
615                    <iterations>10</iterations>
616                    <time_passing>1</time_passing>
617                    <property label="loc.time" name="local_time_step"/>
618                    <max_courant_num>10</max_courant_num>
619                 </time_parameters>'''
620        assert mdl.node_time == self.xmlNodeFromString(doc),\
621            'Could not set max courant number in TimeStepModel'
622        assert mdl.getMaxCourant() == 10,\
623            'Could not get max courant number in TimeStepModel'
624
625    def checkSetandGetMaxFourier(self):
626        """Check whether the TimeStepModel class could be set and get
627         max fourier number (if idtvar = 0 : no options max fourier)"""
628        mdl = TimeStepModel(self.case)
629        mdl.setTimePassing(1)
630        mdl.setMaxFourier(100.)
631        doc = '''<time_parameters>
632                    <property label="Courant nb" name="courant_number"/>
633                    <property label="Fourier nb" name="fourier_number"/>
634                    <time_step_ref>0.1</time_step_ref>
635                    <iterations>10</iterations>
636                    <time_passing>1</time_passing>
637                    <property label="loc.time" name="local_time_step"/>
638                    <max_fourier_num>100.</max_fourier_num>
639                 </time_parameters>'''
640        assert mdl.node_time == self.xmlNodeFromString(doc),\
641            'Could not set max fourier number in TimeStepModel'
642        assert mdl.getMaxFourier() == 100.,\
643            'Could not get max fourier number in TimeStepModel'
644
645    def checkSetandGetTimeStepMinMaxandVariation(self):
646        """Check whether the TimeStepModel class could be set and get
647         options :min max and variation for time step"""
648        mdl = TimeStepModel(self.case)
649        mdl.setTimePassing(2)
650        mdl.setTimeStepMin(0.05)
651        mdl.setTimeStepMax(500)
652        mdl.setTimeStepVariation(0.25)
653        doc = '''<time_parameters>
654                    <property label="Courant nb" name="courant_number"/>
655                    <property label="Fourier nb" name="fourier_number"/>
656                    <time_step_ref>0.1</time_step_ref>
657                    <iterations>10</iterations>
658                    <time_passing>2</time_passing>
659                    <property label="loc.time" name="local_time_step"/>
660                    <time_step_min_factor>0.05</time_step_min_factor>
661                    <time_step_max_factor>500</time_step_max_factor>
662                    <time_step_var>0.25</time_step_var>
663                 </time_parameters>'''
664        assert mdl.node_time == self.xmlNodeFromString(doc),\
665            'Could not set min max and variation of time step in TimeStepModel'
666        assert mdl.getTimeStepMin() == 0.05,\
667            'Could not get min of time step in TimeStepModel'
668        assert mdl.getTimeStepMax() == 500,\
669            'Could not get max of time step in TimeStepModel'
670        assert mdl.getTimeStepVariation() == 0.25,\
671            'Could not get variation of time step in TimeStepModel'
672
673    def checkSetandGetThermalTimeStep(self):
674        """Check whether the TimeStepModel class could be set and get thermal time step"""
675        mdl = TimeStepModel(self.case)
676        from code_saturne.model.ThermalScalarModel import ThermalScalarModel
677        ThermalScalarModel(self.case).setThermalModel('temperature_celsius')
678        del ThermalScalarModel
679        from code_saturne.model.FluidCharacteristicsModel import FluidCharacteristicsModel
680        FluidCharacteristicsModel(self.case).setPropertyMode('density','variable')
681        del FluidCharacteristicsModel
682        from code_saturne.model.BodyForcesModel import BodyForcesModel
683        BodyForcesModel(self.case).setGravity('gravity_x', 9.81)
684        del BodyForcesModel
685        mdl.setThermalTimeStep('on')
686        doc = '''<time_parameters>
687                    <property label="Courant nb" name="courant_number"/>
688                    <property label="Fourier nb" name="fourier_number"/>
689                    <time_step_ref>0.1</time_step_ref>
690                    <iterations>10</iterations>
691                    <time_passing>0</time_passing>
692                    <thermal_time_step status="on"/>
693                 </time_parameters>'''
694        assert mdl.node_time == self.xmlNodeFromString(doc),\
695            'Could not set thermal time step in TimeStepModel'
696        assert mdl.getThermalTimeStep() == 'on',\
697            'Could not get thermal time step in TimeStepModel'
698
699    def checkRemoveThermalTimeStepNode(self):
700        """Check whether the TimeStepModel class could be removed thermal time step node"""
701        mdl = TimeStepModel(self.case)
702        from code_saturne.model.ThermalScalarModel import ThermalScalarModel
703        ThermalScalarModel(self.case).setThermalModel('temperature_celsius')
704        del ThermalScalarModel
705        from code_saturne.model.FluidCharacteristicsModel import FluidCharacteristicsModel
706        FluidCharacteristicsModel(self.case).setPropertyMode('density','variable')
707        del FluidCharacteristicsModel
708        from code_saturne.model.BodyForcesModel import BodyForcesModel
709        BodyForcesModel(self.case).setGravity('gravity_x', 9.81)
710        del BodyForcesModel
711        mdl.setThermalTimeStep('on')
712        mdl.RemoveThermalTimeStepNode()
713        doc = '''<time_parameters>
714                    <property label="Courant nb" name="courant_number"/>
715                    <property label="Fourier nb" name="fourier_number"/>
716                    <time_step_ref>0.1</time_step_ref>
717                    <iterations>10</iterations>
718                    <time_passing>0</time_passing>
719                 </time_parameters>'''
720        assert mdl.node_time == self.xmlNodeFromString(doc),\
721            'Could not remove thermal time step node in TimeStepModel'
722
723def suite():
724    testSuite = unittest.makeSuite(TimeStepModelTestCase, "check")
725    return testSuite
726
727def runTest():
728    print("TimeStepModelTestCase")
729    runner = unittest.TextTestRunner()
730    runner.run(suite())
731
732#-------------------------------------------------------------------------------
733# End
734#-------------------------------------------------------------------------------
735