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 contains the following classes and function:
27- TimeStepView
28"""
29
30#-------------------------------------------------------------------------------
31# Library modules import
32#-------------------------------------------------------------------------------
33
34import logging
35
36#-------------------------------------------------------------------------------
37# Third-party modules
38#-------------------------------------------------------------------------------
39
40from code_saturne.Base.QtCore    import *
41from code_saturne.Base.QtGui     import *
42from code_saturne.Base.QtWidgets import *
43
44#-------------------------------------------------------------------------------
45# Application modules import
46#-------------------------------------------------------------------------------
47
48from code_saturne.model.Common import GuiParam
49from code_saturne.Base.QtPage import ComboModel, IntValidator, DoubleValidator, from_qvariant
50from code_saturne.Pages.TimeStepForm import Ui_TimeStepForm
51from code_saturne.model.TimeStepModel import TimeStepModel
52
53#-------------------------------------------------------------------------------
54# log config
55#-------------------------------------------------------------------------------
56
57logging.basicConfig()
58log = logging.getLogger("TimeStepView")
59log.setLevel(GuiParam.DEBUG)
60
61#-------------------------------------------------------------------------------
62# Main class
63#-------------------------------------------------------------------------------
64
65class TimeStepView(QWidget, Ui_TimeStepForm):
66    """
67    """
68    def __init__(self, parent, case, tree):
69        """
70        Constructor
71        """
72        QWidget.__init__(self, parent)
73
74        Ui_TimeStepForm.__init__(self)
75        self.setupUi(self)
76
77        self.case = case
78        self.case.undoStopGlobal()
79        self.mdl = TimeStepModel(self.case)
80        self.browser = tree
81
82        # Check if xml contains deprecated steady algorithme
83        has_deprecated_steady = False
84        if str(self.mdl.getTimePassing()) == '-1':
85            has_deprecated_steady = True
86
87       # Combo model
88        if has_deprecated_steady:
89            self.modelTimeOptions = ComboModel(self.comboBoxOptions,4,1)
90        else:
91            self.modelTimeOptions = ComboModel(self.comboBoxOptions,3,1)
92        self.modelTimeOptions.addItem(self.tr("Constant"), '0')
93        self.modelTimeOptions.addItem(self.tr("Time varying (adaptive)"), '1')
94        self.modelTimeOptions.addItem(self.tr("Steady (local time step)"), '2')
95        if has_deprecated_steady:
96            self.modelTimeOptions.addItem(self.tr("Deprecated: steady (constant relaxation coefficient)"), '-1')
97
98        self.modelNTERUP = ComboModel(self.comboBoxNTERUP,3,1)
99        self.modelNTERUP.addItem(self.tr("SIMPLE"), 'simple')
100        self.modelNTERUP.addItem(self.tr("SIMPLEC"), 'simplec')
101        self.modelNTERUP.addItem(self.tr("Inner iterations"), 'piso')
102        self.comboBoxNTERUP.setSizeAdjustPolicy(QComboBox.AdjustToContents)
103
104        self.modelTimeStop = ComboModel(self.comboBoxStopCrit, 2, 1)
105        self.modelTimeStop.addItem(self.tr("Number of time steps"), "iterations")
106        self.modelTimeStop.addItem(self.tr("Physical time (s)"), "maximum_time")
107        self.modelTimeStop.addItem(self.tr("Additional time steps"), "iterations_add")
108        self.modelTimeStop.addItem(self.tr("Additional physical time (s)"), "maximum_time_add")
109
110        # Connections
111        self.comboBoxOptions.activated[str].connect(self.slotTimePassing)
112        self.lineEditDTREF.textChanged[str].connect(self.slotTimeStep)
113        self.lineEditRELXST.textChanged[str].connect(self.slotRelaxCoef)
114        self.lineEditCOUMAX.textChanged[str].connect(self.slotTimeOptionCOUMAX)
115        self.lineEditFOUMAX.textChanged[str].connect(self.slotTimeOptionFOUMAX)
116        self.lineEditCDTMIN.textChanged[str].connect(self.slotTimeOptionCDTMIN)
117        self.lineEditCDTMAX.textChanged[str].connect(self.slotTimeOptionCDTMAX)
118        self.lineEditVARRDT.textChanged[str].connect(self.slotTimeOptionVARRDT)
119        self.checkBoxIPTLRO.clicked.connect(self.slotThermalTimeStep)
120        self.comboBoxNTERUP.activated[str].connect(self.slotNTERUP)
121        self.spinBoxNTERUP.valueChanged[int].connect(self.slotNTERUP2)
122        self.comboBoxStopCrit.activated[str].connect(self.slotStopCritModel)
123        self.lineEditStop.textChanged[str].connect(self.slotStopCritValue)
124
125        # Validators
126
127        validatorDTREF = DoubleValidator(self.lineEditDTREF, min=0.0)
128        validatorDTREF.setExclusiveMin(True)
129        validatorRELXST = DoubleValidator(self.lineEditRELXST, min=0.0, max=1.0)
130        validatorRELXST.setExclusiveMin(True)
131        validatorCOUMAX = DoubleValidator(self.lineEditCOUMAX, min=0.0)
132        validatorCOUMAX.setExclusiveMin(True)
133        validatorFOUMAX = DoubleValidator(self.lineEditFOUMAX, min=0.0)
134        validatorFOUMAX.setExclusiveMin(True)
135        validatorCDTMIN = DoubleValidator(self.lineEditCDTMIN, min=0.0, max=1.0)
136        validatorCDTMIN.setExclusiveMin(True)
137        validatorCDTMAX = DoubleValidator(self.lineEditCDTMAX, min=1.0)
138        validatorVARRDT = DoubleValidator(self.lineEditVARRDT, min=0.0)
139        validatorVARRDT.setExclusiveMin(True)
140
141        self.lineEditDTREF.setValidator(validatorDTREF)
142        self.lineEditRELXST.setValidator(validatorRELXST)
143        self.lineEditCOUMAX.setValidator(validatorCOUMAX)
144        self.lineEditFOUMAX.setValidator(validatorFOUMAX)
145        self.lineEditCDTMIN.setValidator(validatorCDTMIN)
146        self.lineEditCDTMAX.setValidator(validatorCDTMAX)
147        self.lineEditVARRDT.setValidator(validatorVARRDT)
148
149        self.validatorNTABS = IntValidator(self.lineEditStop, min=0)
150        self.validatorTABS = DoubleValidator(self.lineEditStop, min=0.0)
151
152        # Initialization
153
154        idtvar = self.mdl.getTimePassing()
155        idtvar_p = idtvar
156
157        # Constraints on time step from Turbulence model
158
159        from code_saturne.model.TurbulenceModel import TurbulenceModel
160        model = TurbulenceModel(self.case).getTurbulenceModel()
161        del TurbulenceModel
162
163        if model in ('LES_Smagorinsky', 'LES_dynamique', 'LES_WALE'):
164            idtvar = 0
165
166            # Deactivate all modes except constant time step
167            for itm in self.modelTimeOptions.getItems():
168                if str(itm) != "0":
169                    self.modelTimeOptions.disableItem(str_model=itm)
170
171        # Constraints on time step from Lagrangian model
172
173        from code_saturne.model.LagrangianModel import LagrangianModel
174        model = LagrangianModel(self.case).getLagrangianModel()
175        if model in ['one_way', 'two_way']:
176            if idtvar not in [0, 1]:
177                idtvar = 0
178
179            # Deactivate certain modes
180            for itm in self.modelTimeOptions.getItems():
181                if str(itm) == "2":
182                    self.modelTimeOptions.disableItem(str_model=itm)
183                elif str(itm) == "1" and model == 'two_way':
184                    self.modelTimeOptions.disableItem(str_model=itm)
185
186        # Constraints on time step from compressible model
187
188        from code_saturne.model.CompressibleModel import CompressibleModel
189        model = CompressibleModel(self.case).getCompressibleModel()
190        if model != 'off':
191            if idtvar not in [0, 1]:
192                idtvar = 0
193
194            # Deactivate steady time step
195            # Using list to allow additions in the future
196            for itm in self.modelTimeOptions.getItems():
197                if str(itm) in ["2"]:
198                    self.modelTimeOptions.disableItem(str_model=itm)
199
200            self.labelNTERUP.setText("Velocity-Pressure algorithm\nsub-iterations on Navier-Stokes")
201            self.comboBoxNTERUP.hide()
202            self.spinBoxNTERUP.show()
203
204        # Constraints on time step from groundwater model
205
206        from code_saturne.model.GroundwaterModel import GroundwaterModel
207        model = GroundwaterModel(self.case).getGroundwaterModel()
208        if model != 'off':
209            if idtvar not in [0, 1]:
210                idtvar = 0
211
212            # Deactivate all modes except constant time step
213            for itm in self.modelTimeOptions.getItems():
214                if str(itm) != "0":
215                    self.modelTimeOptions.disableItem(str_model=itm)
216
217        # Change time step option if required by model constraints
218
219        if idtvar_p != idtvar:
220            self.mdl.setTimePassing(idtvar)
221
222        if self.mdl.thermalCase():
223            if self.mdl.getThermalTimeStep() == 'on':
224                self.checkBoxIPTLRO.setChecked(True)
225            else:
226                self.checkBoxIPTLRO.setChecked(False)
227        else:
228            self.labelIPTLRO.hide()
229            self.checkBoxIPTLRO.hide()
230            self.mdl.RemoveThermalTimeStepNode()
231
232        self.__setTimePassingDisplay(idtvar)
233        self.__setStopCritDisplay()
234
235        self.case.undoStartGlobal()
236
237
238    def __setTimePassingDisplay(self, idtvar):
239        """
240        Choices based on IDTVAR.
241        """
242
243        self.modelTimeOptions.setItem(str_model=str(idtvar))
244
245        if idtvar in (-1, 2):
246            if idtvar == -1:
247                self.modelNTERUP.enableItem(str_model = 'simple')
248                self.modelNTERUP.disableItem(str_model = 'simplec')
249            elif idtvar == 2:
250                self.modelNTERUP.disableItem(str_model = 'simple')
251                self.modelNTERUP.enableItem(str_model = 'simplec')
252            self.modelNTERUP.disableItem(str_model = 'piso')
253
254            m_prev, c_prev = self.mdl.getStopCriterion()
255            for m in ('maximum_time', 'maximum_time_add'):
256                if m_prev == m:
257                    dtref = self.mdl.getTimeStep()
258                    value = int(float(c_prev) / float(dtref))
259                    model = 'iterations'
260                    if m[-4:] == '_add':
261                        model += '_add'
262                    self.mdl.setStopCriterion(model, value)
263                    self.__setStopCritDisplay()
264
265                self.modelTimeStop.disableItem(str_model=m)
266
267        else:
268            self.modelNTERUP.disableItem(str_model = 'simple')
269            self.modelNTERUP.enableItem(str_model = 'simplec')
270            self.modelNTERUP.enableItem(str_model = 'piso')
271
272            self.modelTimeStop.enableItem(str_model='maximum_time')
273            self.modelTimeStop.enableItem(str_model='maximum_time_add')
274
275        algo = self.mdl.getVelocityPressureAlgorithm()
276        self.modelNTERUP.setItem(str_model=algo)
277        if algo == 'piso':
278            self.spinBoxNTERUP.show()
279        else:
280            self.spinBoxNTERUP.hide()
281
282        value = self.mdl.getVelocityPressureParamSweepNumber()
283        self.spinBoxNTERUP.setValue(value)
284
285        if idtvar == -1:
286            self.labelRELXST.show()
287            self.lineEditRELXST.show()
288            self.labelDTREF.hide()
289            self.labelDTREFunit.hide()
290            self.lineEditDTREF.hide()
291            relax_coef = self.mdl.getRelaxCoefficient()
292            self.lineEditRELXST.setText(str(relax_coef))
293
294        else:
295            self.labelRELXST.hide()
296            self.lineEditRELXST.hide()
297            self.labelDTREF.show()
298            self.labelDTREFunit.show()
299            self.lineEditDTREF.show()
300            dtref = self.mdl.getTimeStep()
301            self.lineEditDTREF.setText(str(dtref))
302
303        if idtvar in (1, 2):
304            courant_max   = self.mdl.getOptions('max_courant_num')
305            fourier_max   = self.mdl.getOptions('max_fourier_num')
306            time_step_min_factor = self.mdl.getOptions('time_step_min_factor')
307            time_step_max_factor = self.mdl.getOptions('time_step_max_factor')
308            time_step_var = self.mdl.getOptions('time_step_var')
309
310            self.lineEditCOUMAX.setText(str(courant_max))
311            self.lineEditFOUMAX.setText(str(fourier_max))
312            self.lineEditCDTMIN.setText(str(time_step_min_factor))
313            self.lineEditCDTMAX.setText(str(time_step_max_factor))
314            self.lineEditVARRDT.setText(str(time_step_var))
315
316            self.labelCOUMAX.show()
317            self.lineEditCOUMAX.show()
318            self.labelFOUMAX.show()
319            self.lineEditFOUMAX.show()
320            self.labelCDTMIN.show()
321            self.lineEditCDTMIN.show()
322            self.labelCDTMAX.show()
323            self.lineEditCDTMAX.show()
324            self.labelVARRDT.show()
325            self.lineEditVARRDT.show()
326
327        else:
328            self.labelCOUMAX.hide()
329            self.lineEditCOUMAX.hide()
330            self.labelFOUMAX.hide()
331            self.lineEditFOUMAX.hide()
332            self.labelCDTMIN.hide()
333            self.lineEditCDTMIN.hide()
334            self.labelCDTMAX.hide()
335            self.lineEditCDTMAX.hide()
336            self.labelVARRDT.hide()
337            self.lineEditVARRDT.hide()
338
339
340    def __setStopCritDisplay(self):
341        """
342        Stop criterion option
343        """
344
345        model, value = self.mdl.getStopCriterion()
346
347        if model in ("iterations", "iterations_add"):
348            self.lineEditStop.setValidator(self.validatorNTABS)
349        elif model in ("maximum_time", "maximum_time_add"):
350            self.lineEditStop.setValidator(self.validatorTABS)
351
352        self.modelTimeStop.setItem(str_model=str(model))
353        self.lineEditStop.setText(str(value))
354
355
356    @pyqtSlot(str)
357    def slotTimePassing(self, text):
358        """
359        Input IDTVAR.
360        """
361        idtvar = int(self.modelTimeOptions.dicoV2M[str(text)])
362
363        self.mdl.setTimePassing(idtvar)
364
365        self.__setTimePassingDisplay(idtvar)
366
367
368    @pyqtSlot(str)
369    def slotStopCritModel(self, text):
370        """
371        Select stop criterion model
372        """
373        m_prev, c_prev = self.mdl.getStopCriterion()
374        model = self.modelTimeStop.dicoV2M[str(text)]
375
376        value = c_prev
377        if m_prev in ("iterations", "iterations_add"):
378            if model in ("maximum_time", "maximum_time_add"):
379                dtref = self.mdl.getTimeStep()
380                value = float(c_prev) * float(dtref)
381        elif m_prev in ("maximum_time", "maximum_time_add"):
382            if model in ("iterations", "iterations_add"):
383                dtref = self.mdl.getTimeStep()
384                value = int(float(c_prev) / float(dtref))
385
386        self.mdl.setStopCriterion(model, value)
387
388        self.__setStopCritDisplay()
389
390
391    @pyqtSlot(str)
392    def slotStopCritValue(self, text):
393        """
394        Input stop criterion
395        """
396        if self.lineEditStop.validator().state == QValidator.Acceptable:
397
398            model, c_prev = self.mdl.getStopCriterion()
399
400            value = c_prev
401            if model in ("iterations", "iterations_add"):
402                value = from_qvariant(text, int)
403                self.mdl.setStopCriterion(model, value)
404            elif model in ("maximum_time", "maximum_time_add"):
405                value = from_qvariant(text, float)
406                self.mdl.setStopCriterion(model, value)
407
408
409    @pyqtSlot(str)
410    def slotTimeStep(self, text):
411        """
412        Input DTREF.
413        """
414        if self.lineEditDTREF.validator().state == QValidator.Acceptable:
415            time_step = from_qvariant(text, float)
416            self.mdl.setTimeStep(time_step)
417
418
419    @pyqtSlot(str)
420    def slotNTERUP(self,text):
421        """
422        Set value for parameterNTERUP
423        """
424        NTERUP = self.modelNTERUP.dicoV2M[str(text)]
425        self.mdl.setVelocityPressureAlgorithm(NTERUP)
426        if NTERUP == 'piso':
427            self.spinBoxNTERUP.show()
428            value = self.mdl.getVelocityPressureParamSweepNumber()
429            self.spinBoxNTERUP.setValue(value)
430        else:
431            self.spinBoxNTERUP.hide()
432        self.browser.configureTree(self.case)
433        log.debug("slotNTERUP-> %s" % NTERUP)
434
435
436    @pyqtSlot(int)
437    def slotNTERUP2(self, var):
438        """
439        Set value for velocity-pressure parameter sweep number
440        """
441        self.mdl.setVelocityPressureParamSweepNumber(var)
442        log.debug("slotNTERUP2-> %s" % var)
443
444
445    @pyqtSlot(str)
446    def slotRelaxCoef(self, text):
447        """
448        Input relaxation coefficient.
449        """
450        if self. lineEditRELXST.validator().state == QValidator.Acceptable:
451            relax_coef = from_qvariant(text, float)
452            self.mdl.setRelaxCoefficient(relax_coef)
453
454
455    @pyqtSlot(str)
456    def slotTimeOptionCOUMAX(self, text):
457        """
458        Input COUMAX.
459        """
460        if self.lineEditCOUMAX.validator().state == QValidator.Acceptable:
461            courant_max = from_qvariant(text, float)
462            self.mdl.setOptions('max_courant_num', courant_max)
463
464
465    @pyqtSlot(str)
466    def slotTimeOptionFOUMAX(self, text):
467        """
468        Input FOUMAX.
469        """
470        if self.lineEditFOUMAX.validator().state == QValidator.Acceptable:
471            fourier_max = from_qvariant(text, float)
472            self.mdl.setOptions('max_fourier_num', fourier_max)
473
474
475    @pyqtSlot(str)
476    def slotTimeOptionCDTMIN(self, text):
477        """
478        Input CDTMIN.
479        """
480        if self.lineEditCDTMIN.validator().state == QValidator.Acceptable:
481            time_step_min_factor = from_qvariant(text, float)
482            self.mdl.setOptions('time_step_min_factor', time_step_min_factor)
483
484
485    @pyqtSlot(str)
486    def slotTimeOptionCDTMAX(self, text):
487        """
488        Input CDTMAX.
489        """
490        if self.lineEditCDTMAX.validator().state == QValidator.Acceptable:
491            time_step_max_factor = from_qvariant(text, float)
492            self.mdl.setOptions('time_step_max_factor', time_step_max_factor)
493
494
495    @pyqtSlot(str)
496    def slotTimeOptionVARRDT(self, text):
497        """
498        Input VARRDT.
499        """
500        if self.lineEditVARRDT.validator().state == QValidator.Acceptable:
501            time_step_var = from_qvariant(text, float)
502            self.mdl.setOptions('time_step_var', time_step_var)
503
504
505    @pyqtSlot()
506    def slotThermalTimeStep(self):
507        """
508        Input IPTLRO.
509        """
510        if self.checkBoxIPTLRO.isChecked():
511            self.mdl.setThermalTimeStep("on")
512        else:
513            self.mdl.setThermalTimeStep("off")
514
515
516#-------------------------------------------------------------------------------
517# Testing part
518#-------------------------------------------------------------------------------
519
520if __name__ == "__main__":
521    pass
522
523#-------------------------------------------------------------------------------
524# End
525#-------------------------------------------------------------------------------
526