# -*- coding: utf-8 -*-

#-------------------------------------------------------------------------------

# This file is part of Code_Saturne, a general-purpose CFD tool.
#
# Copyright (C) 1998-2013 EDF S.A.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
# Street, Fifth Floor, Boston, MA 02110-1301, USA.

#-------------------------------------------------------------------------------

"""
This module defines the differents possible outputs : listings, for ensights
chronologic and historic files .... captors .... used variables ...

This module defines the following classes:
- NumericalParamEquatModel
- NumericalParamEquatModelTestCase
"""

#-------------------------------------------------------------------------------
# Library modules import
#-------------------------------------------------------------------------------

import string
import unittest

#-------------------------------------------------------------------------------
# Application modules import
#-------------------------------------------------------------------------------

from Base.Common import *
import Base.Toolbox as Tool
from Base.XMLvariables import Variables, Model
from Base.XMLmodel import XMLmodel, ModelTest
from Pages.DefineUserScalarsModel import DefineUserScalarsModel
from Pages.NumericalParamGlobalModel import NumericalParamGlobalModel
from Pages.TurbulenceModel import TurbulenceModel

#-------------------------------------------------------------------------------
# NumericalParamEquat model class
#-------------------------------------------------------------------------------

class NumericalParamEquatModel(Model):
    """
    """
    def __init__(self, case):
        """
        initialization of nodes lists
        """
        self.case = case
        self.node_models  = self.case.xmlGetNode('thermophysical_models')
        self.node_vitpre  = self.node_models.xmlGetNode('velocity_pressure')
        self.node_varVP   = self.node_vitpre.xmlGetNodeList('variable')
        self.node_np      = self.case.xmlInitNode('numerical_parameters')
        self.node_anal      = self.case.xmlGetNode('analysis_control')
        self.model = XMLmodel(self.case)

       #variables list
        self.var = []
        for node in self.node_varVP:
            self.var.append(node['label'])
        for node in self._getThermalScalarNode():
            self.var.append(node['label'])
        for node in self._getAdditionalScalarNodes():
            self.var.append(node['label'])

        self.thermo = []
        for node in self._getThermalScalarNode():
            self.thermo.append(node['label'])

        self.UVW = []
        for node in self.node_varVP:
            if node['name'] in ('velocity_U', 'velocity_V', 'velocity_W'):
                self.UVW.append(node['label'])


    def _defaultValues(self, label=""):
        """ Private method: return default values """
        self.default = {}
        self.default['time_step_factor'] = 1.0
        self.default['max_iter_number'] = 10000
        self.default['solver_precision'] = 1e-8
        self.default['solver_precision_pressure'] = 1e-8
        if NumericalParamGlobalModel(self.case).getTimeSchemeOrder() == 2:
            self.default['solver_precision'] = 1e-5
            self.default['solver_precision_pressure'] = 1e-5
        self.default['slope_test'] = 'on'
        self.default['flux_reconstruction'] = 'on'

        self.default['solver_choice_pressure'] = 'multigrid'
        self.default['solver_choice'] = 'automatic'

        if label not in self.var:
            self.default['order_scheme'] = 'upwind'
            self.default['blending_factor'] = 0.
        else:
            self.default['order_scheme'] = 'centered'
            self.default['blending_factor'] = 1.
        from Pages.CompressibleModel import CompressibleModel
        if CompressibleModel(self.case).getCompressibleModel() != 'off':
            self.default['order_scheme'] = 'upwind'
            self.default['blending_factor'] = 0.
        del CompressibleModel

        if TurbulenceModel(self.case).getTurbulenceModel() in \
            ('LES_Smagorinsky', 'LES_dynamique', 'LES_WALE'):
            if label in self.UVW:
                self.default['slope_test'] = 'off'
            if label == 'Pressure':
                self.default['rhs_reconstruction'] = 5
            else:
                self.default['rhs_reconstruction'] = 10
        else:
            if label == 'Pressure':
                self.default['rhs_reconstruction'] = 2
            else:
                self.default['rhs_reconstruction'] = 1

        if label in self.thermo:
            for node in self._getThermalScalarNode():
                if node['label'] == label:
                    if node['name'] == 'temperature_celsius':
                        self.default['min_value'] = -273.15
                        self.default['max_value'] = 1e+12
                    elif node['name'] =='temperature_kelvin':
                        self.default['min_value'] = 0
                        self.default['max_value'] = 1e+12
                    elif node['name'] =='enthalpy':
                        self.default['min_value'] = 0
                        self.default['max_value'] = 1e+12
                    elif node['name'] =='potential_temperature':
                        self.default['min_value'] = 0
                        self.default['max_value'] = 1e+12
                    elif node['name'] =='liquid_potential_temperature':
                        self.default['min_value'] = 0
                        self.default['max_value'] = 1e+12
        else:
            self.default['min_value'] = -1e+12
            self.default['max_value'] = 1e+12

        return self.default


    def _getThermalScalarNode(self):
        """ Private method: return node of thermal scalar """
        node_models = self.case.xmlGetNode('thermophysical_models')
        node_scalar = node_models.xmlGetNode('thermal_scalar')
        thermal_scalar_list = node_scalar.xmlGetNodeList('scalar', type='thermal')
        return thermal_scalar_list


    def _getPuCoalScalarsNodes(self):
        """ Private method: return list of pulverized coal scalar's nodes """
        nodList = []
        node = self.node_models.xmlGetNode('solid_fuels', 'model')
        model = node['model']
        if model != 'off':
            nodList = node.xmlGetNodeList('scalar')
        return nodList


    def _getGasScalarsNodes(self):
        """ Private method: return list of gas combustion scalar's nodes """
        nodList = []
        node = self.node_models.xmlGetNode('gas_combustion', 'model')
        model = node['model']
        if model != 'off':
            nodList = node.xmlGetNodeList('scalar')
        return nodList


    def _getMeteoScalarsNodes(self):
        """ Private method: return list of meteo scalar's nodes """
        nodList = []
        node = self.node_models.xmlGetNode('atmospheric_flows', 'model')
        if not node: return []
        model = node['model']
        if model != 'off':
            nodList = node.xmlGetNodeList('scalar')
        return nodList


    def _getElectricalScalarsNodes(self):
        """ Private method: return list of electric scalar's nodes """
        nodList = []
        node = self.node_models.xmlGetNode('joule_effect', 'model')
        if not node: return []
        model = node['model']
        if model != 'off':
            nodList = node.xmlGetNodeList('scalar')
        return nodList


    def _getCompressibleScalarsNodes(self):
        """ Private method: return list of compressible scalar's nodes """
        nodList = []
        node = self.node_models.xmlGetNode('compressible_model', 'model')
        if not node: return []
        model = node['model']
        if model != 'off':
            nodList = node.xmlGetNodeList('scalar')
        return nodList


    def _getAdditionalScalarNodes(self):
        """ Private method: return list of additional scalar's nodes """
        n = self.case.xmlGetNode('additional_scalars')
        return n.xmlGetNodeList('scalar', type='user')


    def _getAleVariablesNodes(self):
        """ Private method: return list of nodes for ALE"""
        nodList = []
        n = self.node_models.xmlGetNode('ale_method')
        if n['status'] == 'on':
            nodList =  n.xmlGetNodeList('variable')
        return nodList


    def _getClippingNodesList(self):
        """ Return list of nodes for class view Scheme"""
        self.var_clip = []

        for part in (self._getThermalScalarNode(),
                     self._getPuCoalScalarsNodes(),
                     self._getGasScalarsNodes(),
                     self._getMeteoScalarsNodes(),
                     self._getElectricalScalarsNodes(),
                     self._getCompressibleScalarsNodes(),
                     self._getAdditionalScalarNodes()):
            self.var_clip.append(part)
        return self.var_clip


    def _getSchemeNodesList(self):
        """ Return list of nodes for class view Scheme"""
        self.var_shem = []

        for part in (self.node_varVP,
                     self.model.getTurbVariable(),
                     self._getThermalScalarNode(),
                     self._getPuCoalScalarsNodes(),
                     self._getGasScalarsNodes(),
                     self._getMeteoScalarsNodes(),
                     self._getElectricalScalarsNodes(),
                     self._getCompressibleScalarsNodes(),
                     self._getAdditionalScalarNodes()):
            self.var_shem.append(part)
        return self.var_shem


    def _getSolverNodesList(self):
        """ Return list of nodes for class view Solver"""
        self.var_solv = []
        for part in (self.node_varVP,
                     self.model.getTurbVariable(),
                     self._getThermalScalarNode(),
                     self._getPuCoalScalarsNodes(),
                     self._getGasScalarsNodes(),
                     self._getMeteoScalarsNodes(),
                     self._getElectricalScalarsNodes(),
                     self._getAdditionalScalarNodes(),
                     self._getCompressibleScalarsNodes(),
                     self._getAleVariablesNodes()):
            self.var_solv.append(part)
        return self.var_solv


    def _getClippingLabelNode(self, label):
        """ Private method: return node called with label'label' for solver scheme"""
        for node in self._getClippingNodesList():
            for n in node:
                if n['label'] == label:
                    return n
        raise ValueError("This label does not exist: " + label)


    def _getSchemeLabelNode(self, label):
        """ Private method: return node called with label'label' for scheme nodes"""
        for node in self._getSchemeNodesList():
            for n in node:
                if n['label'] == label:
                    return n
        raise ValueError("This label does not exist: " + label)


    def _getSolverLabelNode(self, label):
        """ Private method: return node called with label'label' for solver scheme"""
        for node in self._getSolverNodesList():
            for n in node:
                if n['label'] == label:
                    return n
        raise ValueError("This label does not exist: " + label)


    def _isPressure(self, node):
        """ Return : 1 if name of node is 'pressure', 0 if not """
        if node and node['name'] == 'pressure':
            return 1
        else:
            return 0

    @Variables.undoGlobal
    def setSchemeDefaultValues(self):
        """Usefull for TurbulenceModel in case of LES"""
        for label in self.var:
            try:
                self.setBlendingFactor(label, self._defaultValues(label)['blending_factor'])
                self.setScheme(label, self._defaultValues(label)['order_scheme'])
                self.setSlopeTest(label, self._defaultValues(label)['slope_test'])
                self.setFluxReconstruction(label, self._defaultValues(label)['flux_reconstruction'])
                self.setRhsReconstruction(label, self._defaultValues(label)['rhs_reconstruction'])
            except:
                pass


    @Variables.noUndo
    def getClippingList(self):
        """ Return the variables label list for clipping parameters """
        list = []
        for node in self._getClippingNodesList():
            for n in node:
                if n['type'] != 'model':
                    list.append(n['label'])
        return list


    @Variables.noUndo
    def getSchemeList(self):
        """ Return the variables label list for scheme parameters """
        list = []
        for node in self._getSchemeNodesList():
            for n in node:
                list.append(n['label'])
        return list


    @Variables.noUndo
    def getSolverList(self):
        """ Return the variables label list for solver parameters """
        list = []
        from Pages.CompressibleModel import CompressibleModel
        comp_model = CompressibleModel(self.case).getCompressibleModel()
        del CompressibleModel

        for node in self._getSolverNodesList():
            for n in node:
                if self._isPressure(n):
                    if comp_model == 'off':
                        list.append(n['label'])
                else:
                    list.append(n['label'])

        return list


    def isScalar(self, label):
        """
        Return : 1 if type of node is 'user' or 'thermal' or 'model',
                 0 if not.  Only used by the view by solver class
        """
        node = self._getSolverLabelNode(label)
        if node:
            if node['type'] in ['user', 'thermal', 'model']:
                return 1
            else:
                return 0


# Following methods for dependances of scheme:

    @Variables.noUndo
    def getScheme(self, label):
        """ Return value of order scheme for variable labelled label """
        node = self._getSchemeLabelNode(label)
        if self._isPressure(node):
            return None
        value = self._defaultValues(label)['order_scheme']
        n = node.xmlGetNode('order_scheme')
        if n:
            value = n['choice']
        return value


    @Variables.noUndo
    def getBlendingFactor(self, label):
        """ Return value of blending factor for variable labelled label """
        node = self._getSchemeLabelNode(label)
        if self._isPressure(node):
            return None
        value = node.xmlGetDouble('blending_factor')
        if value == None:
            value = self._defaultValues(label)['blending_factor']
        return value


    @Variables.noUndo
    def getSlopeTest(self, label):
        """ Return value of slope test for variable labelled label """
        node = self._getSchemeLabelNode(label)
        if self._isPressure(node):
            return None
        value = self._defaultValues(label)['slope_test']
        n = node.xmlGetNode('slope_test')
        if n:
            value = n['status']
        return value


    @Variables.noUndo
    def getFluxReconstruction(self, label):
        """ Return value of flux reconstruction for variable labelled label """
        node = self._getSchemeLabelNode(label)
        if self._isPressure(node):
            return None
        value = self._defaultValues()['flux_reconstruction']
        if node.xmlGetNode('flux_reconstruction'):
            value = node.xmlGetNode('flux_reconstruction')['status']
        return value


    @Variables.noUndo
    def getRhsReconstruction(self, label):
        """ Return value of blending factor for variable labelled label """
        node = self._getSchemeLabelNode(label)
        value = node.xmlGetDouble('rhs_reconstruction')
        if value == None:
            if self._isPressure(node): # temporary fix for probable mix between label and name
                value = self._defaultValues('Pressure')['rhs_reconstruction']
            else:
                value = self._defaultValues(label)['rhs_reconstruction']
        return value


    @Variables.undoGlobal
    def setBlendingFactor(self, label, value):
        """
        Put value of blending factor for variable labelled label
        only if it 's different of default value
        """
        node = self._getSchemeLabelNode(label)
        if self._isPressure(node):
            return
        self.isGreaterOrEqual(value, 0.)
        self.isLowerOrEqual(value, 1.)
        scheme = self.getScheme(label)
        if scheme == self._defaultValues(label)['order_scheme']:
            if scheme == 'upwind':
                node.xmlRemoveChild('blending_factor')
            else:
                node.xmlSetData('blending_factor', value)
        else:
            node.xmlSetData('blending_factor', value)
#            if value != self._defaultValues(label)['blending_factor']:
#                node.xmlSetData('blending_factor', value)
#            else:
#                node.xmlRemoveChild('blending_factor')


    @Variables.undoGlobal
    def setScheme(self, label, value):
        """
        Put value of order scheme for variable or scalar labelled label
        only if it 's different of default value
        """
        self.isInList(value, ('upwind', 'centered', 'solu'))
        node = self._getSchemeLabelNode(label)
        if value == self._defaultValues(label)['order_scheme']:
            node.xmlRemoveChild('order_scheme')
            if self.getBlendingFactor(label) == self._defaultValues(label)['blending_factor']\
                or value == 'centered' and self.getBlendingFactor(label) == 0. \
                or value == 'upwind' and self.getBlendingFactor(label) != 0.:
                    node.xmlRemoveChild('blending_factor')
        else:
            n = node.xmlInitNode('order_scheme')
            n['choice'] = value


    @Variables.undoLocal
    def setSlopeTest(self, label, status):
        """ Put status of slope test for variable labelled label """
        self.isOnOff(status)
        node = self._getSchemeLabelNode(label)
        if status == self._defaultValues(label)['slope_test']:
            node.xmlRemoveChild('slope_test')
        else:
            n = node.xmlInitNode('slope_test')
            n['status'] = status


    @Variables.undoLocal
    def setFluxReconstruction(self, label, value):
        """ Put status of flux reconstruction for variable labelled label """
        self.isOnOff(value)
        node = self._getSchemeLabelNode(label)
        if value == self._defaultValues()['flux_reconstruction']:
            node.xmlRemoveChild('flux_reconstruction')
        else:
            n = node.xmlInitNode('flux_reconstruction')
            n['status']=value


    @Variables.undoLocal
    def setRhsReconstruction(self, label, value):
        """
        Put value of blending factor for variable labelled label
        only if it 's different of default value
        """
        self.isInt(value)
        node = self._getSchemeLabelNode(label)
        node.xmlSetData('rhs_reconstruction', value)


# Following methods for dependances of solver:

    @Variables.undoLocal
    def setMaxIterNumber(self, label, value):
        """ Put number of maximum iterations for variable labelled label """
        self.isInt(value)
        node = self._getSolverLabelNode(label)
        if value != self._defaultValues()['max_iter_number']:
            node.xmlSetData('max_iter_number', value)
        else:
            node.xmlRemoveChild('max_iter_number')


    @Variables.undoLocal
    def setSolverPrecision(self, label, value):
        """ Put value of solver precision for variable labelled label """
        # for pressure default value always equal to 1e-8
        self.isPositiveFloat(value)
        node = self._getSolverLabelNode(label)
        if self._isPressure(node):
            default = self._defaultValues()['solver_precision_pressure']
        else:
            default = self._defaultValues()['solver_precision']

        if value != default:
            node.xmlSetData('solver_precision', value)
        else:
            node.xmlRemoveChild('solver_precision')


    @Variables.undoLocal
    def setSolverChoice(self, label, value):
        """ Put choice of solver for variable labelled label """
        self.isInList(value, ('multigrid', 'conjugate_gradient', 'jacobi', 'bi_cgstab', 'gmres', 'automatic'))
        node = self._getSolverLabelNode(label)
        if self._isPressure(node):
            default = self._defaultValues()['solver_choice_pressure']
        else:
            default = self._defaultValues()['solver_choice']

        if value != default:
            n = node.xmlInitNode('solver_choice')
            n['choice'] = value
        else:
            node.xmlRemoveChild('solver_choice')


    @Variables.noUndo
    def getMaxIterNumber(self, label):
        """ Return number of maximum iterations for variable labelled label """
        node = self._getSolverLabelNode(label)
        value = node.xmlGetInt('max_iter_number')
        if value == None:
            value = self._defaultValues()['max_iter_number']
        return value


    @Variables.noUndo
    def getSolverPrecision(self, label):
        """ Return value of solver precision for variable labelled label """
        node = self._getSolverLabelNode(label)

        if self._isPressure(node):
            default = self._defaultValues()['solver_precision_pressure']
        else:
            default = self._defaultValues()['solver_precision']

        value = node.xmlGetDouble('solver_precision')
        if value == None:
            value = default
        return value


    @Variables.noUndo
    def getSolverChoice(self, label):
        """ Return choice of solver for variable labelled label """
        node = self._getSolverLabelNode(label)
        n = node.xmlGetNode('solver_choice')

        if n:
            value = n['choice']
        else:
            if self._isPressure(node):
                default = self._defaultValues()['solver_choice_pressure']
            else:
                default = self._defaultValues()['solver_choice']
            value = default
        return value


    @Variables.noUndo
    def getScalarTimeStepFactor(self, label):
        """ Return value of time_step_factor for variable labelled label """
        if self.isScalar(label):
            node = self._getSolverLabelNode(label)
            value = node.xmlGetDouble('time_step_factor')
            if value == None:
                value = self._defaultValues()['time_step_factor']
            return value
        else:
            raise ValueError("This method runs only with scalar label")


    @Variables.undoLocal
    def setScalarTimeStepFactor(self, label, value):
        """ Put value of time_step_factor for variable labelled label """
        self.isStrictPositiveFloat(value)
        if self.isScalar(label):
            node = self._getSolverLabelNode(label)
            if value != self._defaultValues()['time_step_factor']:
                node.xmlSetData('time_step_factor', value)
            else:
                node.xmlRemoveChild('time_step_factor')
        else:
            raise ValueError("This method runs only with scalar label")


    @Variables.noUndo
    def getMinValue(self, label):
        """Get minimal value from an additional_scalar with label scalar_label"""
        self.isInList(label, self.getClippingList())
        node = self._getClippingLabelNode(label)
        min_val = node.xmlGetChildDouble('min_value')
        if min_val == None:
            min_val = self._defaultValues(label)['min_value']
            self.setMinValue(label, min_val)

        return min_val


    @Variables.undoLocal
    def setMinValue(self, label, min_value):
        """
        Put minimal value for an additional_scalar with label scalar_label.
        Method also used by ThermalScalarModel
        """
        self.isFloat(min_value)
        self.isInList(label, self.getClippingList())
        node = self._getClippingLabelNode(label)
        node.xmlSetData('min_value', min_value)


    @Variables.noUndo
    def getMaxValue(self, label):
        """Get maximal value from an additional_scalar with label scalar_label"""
        self.isInList(label, self.getClippingList())
        node = self._getClippingLabelNode(label)
        max_val = node.xmlGetDouble('max_value')
        if max_val == None:
            max_val = self._defaultValues(label)['max_value']
            self.setMaxValue(label, max_val)
        return max_val


    @Variables.undoLocal
    def setMaxValue(self, label, max_value):
        """
        Put maximal value for an additional_scalar with label scalar_label.
        Method also used by ThermalScalarModel
        """
        self.isFloat(max_value)
        self.isInList(label, self.getClippingList())
        node = self._getClippingLabelNode(label)
        node.xmlSetData('max_value', max_value)


#-------------------------------------------------------------------------------
# NumericalParamEquat test case
#-------------------------------------------------------------------------------


class NumericalParamEquatTestCase(ModelTest):
    """
    """
    def checkNumericalParamEquatInstantiation(self):
        """
        Check whether the NumericalParamEquatModel class could be instantiated
        """
        model = None
        model = NumericalParamEquatModel(self.case)
        assert model != None, 'Could not instantiate NumericalParamEquatModel'

    def checkSetAndGetScheme(self):
        """
        Check whether the NumericalParamEquatModel class could set and get scheme
        """
        model = NumericalParamEquatModel(self.case)
        model.setScheme('VelocitW', 'upwind')
        doc = """<velocity_pressure>
                        <variable label="Pressure" name="pressure"/>
                        <variable label="VelocitU" name="velocity_U"/>
                        <variable label="VelocitV" name="velocity_V"/>
                        <variable label="VelocitW" name="velocity_W">
                                <order_scheme choice="upwind"/>
                        </variable>
                        <property label="total_pressure" name="total_pressure"/>
                        <property label="Yplus" name="yplus" support="boundary"/>
                        <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc),\
                'Could not set scheme in NumericalParamEquationModel'
        assert model.getScheme('VelocitW') == 'upwind',\
                'Could not get scheme in NumericalParamEquationModel'

    def checkSetAndGetBlendingFactor(self):
        """
        Check whether the NumericalParamEquatModel class could set and get blending factor
        """
        model = NumericalParamEquatModel(self.case)
        model.setScheme('VelocitW', 'centered')
        model.setBlendingFactor('VelocitW', 0.5)
        doc = """<velocity_pressure>
                    <variable label="Pressure" name="pressure"/>
                    <variable label="VelocitU" name="velocity_U"/>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W">
                            <blending_factor>0.5</blending_factor>
                    </variable>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc),\
                'Could not set blending factor in NumericalParamEquationModel'
        assert model.getBlendingFactor('VelocitW') == 0.5,\
                'Could not get blending factor in NumericalParamEquationModel'

    def checkSetAndGetSlopeTest(self):
        """
        Check whether the NumericalParamEquatModel class could set and get slope test
        """
        model = NumericalParamEquatModel(self.case)
        model.setSlopeTest('VelocitW', 'off')
        doc = """<velocity_pressure>
                    <variable label="Pressure" name="pressure"/>
                    <variable label="VelocitU" name="velocity_U"/>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W">
                            <slope_test status="off"/>
                    </variable>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc),\
                'Could not set status of slope test in NumericalParamEquationModel'
        assert model.getSlopeTest('VelocitW') == 'off',\
                'Could not get status of slope test in NumericalParamEquationModel'


    def checkSetAndGetFluxReconstruction(self):
        """
        Check whether the NumericalParamEquatModel class could set and get flux reconstruction
        """
        model = NumericalParamEquatModel(self.case)
        model.setFluxReconstruction('VelocitW', 'on')
        doc = """<velocity_pressure>
                    <variable label="Pressure" name="pressure"/>
                    <variable label="VelocitU" name="velocity_U"/>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W">
                    </variable>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc),\
                'Could not set status of flux reconstruction in NumericalParamEquationModel'
        assert model.getFluxReconstruction('VelocitW') == 'on',\
                'Could not get status of flux reconstruction in NumericalParamEquationModel'

        model.setFluxReconstruction('VelocitW', 'off')
        doc2 = """<velocity_pressure>
                    <variable label="Pressure" name="pressure"/>
                    <variable label="VelocitU" name="velocity_U"/>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W">
                        <flux_reconstruction status="off"/>
                    </variable>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                  </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc2),\
                'Could not set status of flux reconstruction in NumericalParamEquationModel'
        assert model.getFluxReconstruction('VelocitW') == 'off',\
                'Could not get status of flux reconstruction in NumericalParamEquationModel'

    def checkSetAndGetMaxIterNumber(self):
        """
        Check whether the NumericalParamEquatModel class could set and get max of number of iterations
        """
        model = NumericalParamEquatModel(self.case)
        model.setMaxIterNumber('Pressure', 22222)
        doc = """<velocity_pressure>
                    <variable label="Pressure" name="pressure">
                            <max_iter_number>22222</max_iter_number>
                    </variable>
                    <variable label="VelocitU" name="velocity_U"/>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W"/>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc),\
                'Could not set max of number of iterations in NumericalParamEquationModel'
        assert model.getMaxIterNumber('Pressure') == 22222,\
                'Could not get max of number of iterations in NumericalParamEquationModel'

    def checkSetAndGetSolverPrecision(self):
        """
        Check whether the NumericalParamEquatModel class could set and get solver precision
        """
        model = NumericalParamEquatModel(self.case)

        assert model.getSolverPrecision('Pressure') == 1e-8,\
                'Could not get solver precision for pressure in NumericalParamEquationModel'
        from Pages.NumericalParamGlobalModel import NumericalParamGlobalModel
        NumericalParamGlobalModel(self.case).setTimeSchemeOrder(2)
        del NumericalParamGlobalModel
        assert model.getSolverPrecision('VelocitU') == 1e-5

        model.setSolverPrecision('VelocitU', 2e-6)
        doc = """<velocity_pressure>
                    <variable label="Pressure" name="pressure"/>
                    <variable label="VelocitU" name="velocity_U">
                            <solver_precision>2e-06</solver_precision>
                    </variable>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W"/>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        assert model.node_vitpre == self.xmlNodeFromString(doc),\
                'Could not set solver precision in NumericalParamEquationModel'
        assert model.getSolverPrecision('VelocitU') == 2e-6,\
                'Could not get solver precision in NumericalParamEquationModel'

    def checkSetAndGetScalarTimeStepFactor(self):
        """
        Check whether the NumericalParamEquatModel class could set and get time step factor
        """
        model = NumericalParamEquatModel(self.case)
        from Pages.ThermalScalarModel import ThermalScalarModel
        ThermalScalarModel(self.case).setThermalModel('temperature_celsius')
        del ThermalScalarModel

##        self.failUnlessRaises(ValueError, model.setScalarTimeStepFactor('VelocitU', 25.), \
##           'Could not set time step factor in NumericalParamEquationModel')

        model.setScalarTimeStepFactor('TempC', 52.)
        node_sca = self.case.xmlGetNode('additional_scalars')
        vit = """<velocity_pressure>
                    <variable label="Pressure" name="pressure"/>
                    <variable label="VelocitU" name="velocity_U"/>
                    <variable label="VelocitV" name="velocity_V"/>
                    <variable label="VelocitW" name="velocity_W"/>
                    <property label="total_pressure" name="total_pressure"/>
                    <property label="Yplus" name="yplus" support="boundary"/>
                    <property label="Efforts" name="effort" support="boundary"/>
                 </velocity_pressure>"""
        sca = """<additional_scalars>
                    <scalar label="TempC" name="temperature_celsius" type="thermal">
                            <initial_value zone_id="1">20.0</initial_value>
                            <min_value>-1e+12 </min_value>
                            <max_value>1e+12</max_value>
                            <time_step_factor>52</time_step_factor>
                    </scalar>
                 </additional_scalars>"""
        assert model.node_vitpre == self.xmlNodeFromString(vit),\
                'Could not set time step factor in NumericalParamEquationModel'

        assert node_sca == self.xmlNodeFromString(sca),\
                'Could not set time step factor for scalar in NumericalParamEquationModel'

##        self.failUnlessRaises(ValueError, model.getScalarTimeStepFactor('VelocitV'), \
##           'Could not get time step factor in NumericalParamEquationModel')

        assert model.getScalarTimeStepFactor('TempC') == 52.,\
                'Could not get time step factor for scalar in NumericalParamEquationModel'

def suite():
    testSuite = unittest.makeSuite(NumericalParamEquatTestCase, "check")
    return testSuite

def runTest():
    print("NumericalParamEquatTestCase")
    runner = unittest.TextTestRunner()
    runner.run(suite())


#-------------------------------------------------------------------------------
# End
#-------------------------------------------------------------------------------
