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 Time averages page.
27
28This module defines the following classes:
29- TimeAveragesModel
30- TimeAveragesTestCase
31"""
32
33#-------------------------------------------------------------------------------
34# Library modules import
35#-------------------------------------------------------------------------------
36
37import os, sys, types, unittest
38
39#-------------------------------------------------------------------------------
40# Application modules import
41#-------------------------------------------------------------------------------
42
43from code_saturne.model.Common import *
44from code_saturne.model.XMLmodel import XMLmodel, ModelTest
45from code_saturne.model.XMLvariables import Model, Variables
46from code_saturne.model.OutputVolumicVariablesModel import OutputVolumicVariablesModel
47from code_saturne.model.StartRestartModel import StartRestartModel
48
49#-------------------------------------------------------------------------------
50# Model class
51#-------------------------------------------------------------------------------
52
53class TimeAveragesModel(Model):
54    """
55    Class to open TimeAverages Page.
56    """
57    def __init__(self, case):
58        """
59        Simple constructor.
60        """
61        self.case = case
62        self.node_anal     = self.case.xmlInitNode('analysis_control')
63        self.node_mean     = self.node_anal.xmlInitNode('time_averages')
64
65        self.__var_prop_list = self.__updateDicoLabel2Name()
66
67
68    def defaultValues(self):
69        """
70        Public method.
71        @return: dictionary with default values.
72        @rtype: C{Dict}
73        """
74        value = {}
75        value['start']     = 1
76        value['timestart'] = 0.
77        value['restart']   = -2
78        value['name']     = "TimeAverage"
79
80        return value
81
82
83    def __updateDicoLabel2Name(self):
84        """
85        Private method.
86        Gets a dictionnary to connect name and label from
87        variables and properties.
88        """
89        mdl = OutputVolumicVariablesModel(self.case)
90
91        # For time averages, we also consider field components
92        self.dicoLabel2Name = mdl.getVolumeFieldsLabel2Name(time_averages=False, get_components=True)
93
94        return self.dicoLabel2Name
95
96
97    @Variables.undoGlobal
98    def addTimeAverage(self):
99        """
100        Public method.
101        Add a new time average and return a default name
102        """
103        name = self.defaultValues()['name']
104        def_name = name + str(len(self.getTimeAverageNames()) + 1)
105
106        # define default name
107        if def_name in self.getTimeAverageNames():
108            i = 2
109            while def_name in self.getTimeAverageNames():
110                def_name = name + str(len(self.getTimeAverageNames()) + i)
111                i = i + 1
112
113        node = self.node_mean.xmlInitNode('time_average', name = def_name, label = def_name)
114        node['id'] = len(self.getTimeAverageNames())
115        ntdmom = self.defaultValues()['start']
116        ttdmom = -1.0
117        imoold = self.defaultValues()['restart']
118        self.setTimeStepStart(def_name, ntdmom)
119        self.setTimeStart(def_name, ttdmom)
120        self.setRestart(def_name, imoold)
121
122        return def_name, ntdmom, ttdmom, imoold
123
124
125    @Variables.undoGlobal
126    def deleteTimeAverage(self, name):
127        """
128        Public method.
129        @type name: C{String}
130        @param name: name of the time average to delete.
131        """
132        node = self.node_mean.xmlGetNode('time_average', name=name)
133        if node:
134            nb = node['id']
135            node.xmlRemoveNode()
136
137            # renumbering of all time averages
138            for p in range(int(nb)+1, self.getNumberOfTimeAverage()+2):
139                t = self.node_mean.xmlGetNode('time_average', id=p)
140                t['id'] = p - 1
141
142
143    @Variables.noUndo
144    def getTimeAverageData(self, imom):
145        """
146        Public method.
147        @return: data for time average number I{imom}.
148        @rtype: C{Tuple}
149        """
150        self.isInt(imom)
151        restart = self.defaultValues()['restart']
152        node = self.node_mean.xmlGetNode('time_average', id=imom)
153        start = node.xmlGetInt('time_step_start')
154        timestart = node.xmlGetDouble('time_start')
155        restart = node.xmlGetInt('restart_from_time_average')
156
157        lst = OutputVolumicVariablesModel(self.case).getVariablesAtNode(node, time_averages=False, get_components=True)
158        return node['name'], start, timestart, restart, lst
159
160
161    @Variables.undoLocal
162    def setName(self, old_name, name):
163        """
164        Public method.
165        """
166        self.isInList(old_name, self.getTimeAverageNames())
167        node = self.node_mean.xmlInitNode('time_average', name=old_name)
168        node['name'] = name
169        node['label'] = name
170
171
172    @Variables.undoLocal
173    def setTimeStart(self, name, start):
174        """
175        Public method.
176        """
177        self.isFloat(start)
178        self.isInList(name, self.getTimeAverageNames())
179        node = self.node_mean.xmlInitNode('time_average', name=name)
180        node.xmlSetData('time_start', start)
181
182
183    @Variables.noUndo
184    def getTimeStart(self, name):
185        """
186        Public method.
187        """
188        self.isInList(name, self.getTimeAverageNames())
189        node = self.node_mean.xmlInitNode('time_average', name=name)
190        return node.xmlGetDouble('time_start')
191
192
193    @Variables.undoLocal
194    def setTimeStepStart(self, name, start):
195        """
196        Public method.
197        """
198        self.isInt(start)
199        self.isInList(name, self.getTimeAverageNames())
200        node = self.node_mean.xmlInitNode('time_average', name=name)
201        node.xmlSetData('time_step_start', start)
202
203
204    @Variables.noUndo
205    def getTimeStepStart(self, name):
206        """
207        Public method.
208        """
209        self.isInList(name, self.getTimeAverageNames())
210        node = self.node_mean.xmlInitNode('time_average', name=name)
211        return node.xmlGetInt('time_step_start')
212
213
214    @Variables.undoLocal
215    def setRestart(self, name, restart):
216        """
217        Public method.
218        """
219        self.isInt(restart)
220        self.isInList(name, self.getTimeAverageNames())
221        node = self.node_mean.xmlInitNode('time_average', name=name)
222        if restart != -2:
223            node.xmlSetData('restart_from_time_average', restart)
224        else:
225            node.xmlRemoveChild('restart_from_time_average')
226
227
228    @Variables.noUndo
229    def getRestart(self, name):
230        """
231        Public method.
232        """
233        self.isInList(name, self.getTimeAverageNames())
234        node = self.node_mean.xmlInitNode('time_average', name=name)
235        return node.xmlGetInt('restart_from_time_average')
236
237
238    @Variables.undoLocal
239    def setVariable(self, name, lst):
240        """
241        Public method.
242        """
243        self.isInList(name, self.getTimeAverageNames())
244        node = self.node_mean.xmlInitNode('time_average', name=name)
245        OutputVolumicVariablesModel(self.case).setVariablesAtNode(node, lst, time_averages=False, get_components=True)
246
247    @Variables.noUndo
248    def getVariable(self, name):
249        """
250        Public method.
251        """
252        self.isInList(name, self.getTimeAverageNames())
253        node = self.node_mean.xmlInitNode('time_average', name=name)
254        return OutputVolumicVariablesModel(self.case).getVariablesAtNode(node, time_averages=False, get_components=True)
255
256
257    @Variables.noUndo
258    def getTimeAverageNames(self):
259        """
260        Public method.
261        @return: list of time averages names.
262        @rtype: C{List} of C{String}
263        """
264        lst = []
265        for node in self.node_mean.xmlGetNodeList('time_average'):
266            name = node['name']
267            lst.append(name)
268        return lst
269
270
271    @Variables.noUndo
272    def getNumberOfTimeAverage(self):
273        """
274        Public method.
275        @return: number of time averages already defined.
276        @rtype: C{Int}
277        """
278        return len(self.node_mean.xmlGetNodeList('time_average'))
279
280#-------------------------------------------------------------------------------
281# TimeAveragesModel test case
282#-------------------------------------------------------------------------------
283
284class TimeAveragesTestCase(ModelTest):
285    """
286    unittest
287    """
288    def checkTimeAveragesInstantiation(self):
289        """Check whether the TimeAveragesModel class could be instantiated"""
290        model = None
291        model = TimeAveragesModel(self.case)
292        assert model != None, 'Could not instantiate TimeAveragesModel'
293
294
295    def checksetTimeAverage(self):
296        """Check whether the TimeAveragesModel class could be set a average"""
297        mdl = TimeAveragesModel(self.case)
298        mdl.setTimeAverage(1, 'moyenne', 10, 1, ['VelocitU', 'VelocitV'])
299        mdl.setTimeAverage(2, 'deux', 20, 1, ['Pressure'])
300
301        doc = '''<time_averages>
302                    <time_average id="1" name="moyenne">
303                            <var_prop name="velocity" component="0"/>
304                            <var_prop name="velocity" component="1"/>
305                            <time_step_start>10</time_step_start>
306                    </time_average>
307                    <time_average id="2" name="deux">
308                            <var_prop name="pressure"/>
309                            <time_step_start>20</time_step_start>
310                    </time_average>
311                 </time_averages>'''
312
313        assert mdl.node_mean == self.xmlNodeFromString(doc),\
314            'Could not set some averages in TimeAveragesModel'
315
316
317    def checkreplaceTimeAverage(self):
318        """Check whether the TimeAveragesModel class could be replaced one average"""
319        mdl = TimeAveragesModel(self.case)
320        mdl.setTimeAverage(1, 'moyenne', 10, 1, ['VelocitU', 'VelocitV'])
321        mdl.setTimeAverage(2, 'deux', 20, 1, ['Pressure'])
322        mdl.setTimeAverage(3, 'trois', 33, 1, ['Pressure', 'VelocitU'])
323        mdl.replaceTimeAverage(2, 'SECOND', 12, 1, ['VelocitW', 'VelocitV'])
324        mdl.replaceTimeAverage(3, 'trois', 33, 1, ['Pressure', 'VelocitW'])
325        doc = '''<time_averages>
326                    <time_average id="1" name="moyenne">
327                            <var_prop name="velocity" component="0"/>
328                            <var_prop name="velocity" component="1"/>
329                            <time_step_start>10</time_step_start>
330                    </time_average>
331                    <time_average id="2" name="SECOND">
332                            <var_prop name="velocity" component="2"/>
333                            <var_prop name="velocity" component="1"/>
334                            <time_step_start>12</time_step_start>
335                    </time_average>
336                    <time_average id="3" name="trois">
337                            <var_prop name="pressure"/>
338                            <var_prop name="velocity" component="2"/>
339                            <time_step_start>33</time_step_start>
340                    </time_average>
341                 </time_averages>'''
342        assert mdl.node_mean == self.xmlNodeFromString(doc),\
343            'Could not replace one average in TimeAveragesModel'
344
345
346    def checkdeleteTimeAverage(self):
347        """Check whether the TimeAveragesModel class could be deleted one average"""
348        mdl = TimeAveragesModel(self.case)
349        mdl.setTimeAverage(1, 'moyenne', 10, 1, ['VelocitU', 'VelocitV'])
350        mdl.setTimeAverage(2, 'deux', 20, 1, ['VelocitU'])
351        mdl.setTimeAverage(3, 'trois', 33, 1, ['VelocitW', 'VelocitU'])
352        mdl.deleteTimeAverage(2)
353        doc = '''<time_averages>
354                    <time_average id="1" name="moyenne">
355                            <var_prop name="velocity" component="0"/>
356                            <var_prop name="velocity" component="1"/>
357                            <time_step_start>10</time_step_start>
358                    </time_average>
359                    <time_average id="2" name="trois">
360                            <var_prop name="velocity" component="2"/>
361                            <var_prop name="velocity" component="0"/>
362                            <time_step_start>33</time_step_start>
363                    </time_average>
364                 </time_averages>'''
365
366        assert mdl.node_mean == self.xmlNodeFromString(doc),\
367            'Could not delete one average in TimeAveragesModel'
368
369
370def suite():
371    testSuite = unittest.makeSuite(TimeAveragesTestCase, "check")
372    return testSuite
373
374
375def runTest():
376    print(__file__)
377    runner = unittest.TextTestRunner()
378    runner.run(suite())
379
380#-------------------------------------------------------------------------------
381# End
382#-------------------------------------------------------------------------------
383