# -*- coding: iso-8859-1 -*-
#
#-------------------------------------------------------------------------------
#                    Code_Saturne version 1.3
#                    ------------------------
#
#
#     This file is part of the Code_Saturne User Interface, element of the
#     Code_Saturne CFD tool.
#
#     Copyright (C) 1998-2007 EDF S.A., France
#
#     contact: saturne-support@edf.fr
#
#     The Code_Saturne User Interface 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.
#
#     The Code_Saturne User Interface 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 the Code_Saturne Kernel; if not, write to the
#     Free Software Foundation, Inc.,
#     51 Franklin St, Fifth Floor,
#     Boston, MA  02110-1301  USA
#
#-------------------------------------------------------------------------------


"""
This module defines the turbulence model data management.

This module contains the following classes and function:
- TurbulenceModel
- AdvancedOptionsDialog
- TurbulenceView
- PageText
- TurbulenceTestCase
"""


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


import Tix
from Tkconstants import *
import sys, unittest


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


from Base.Common import *
import Base.Toolbox as Tool
import Base.Dialog as Dialog
import Base.TkPage as TkPage
from Base.XMLvariables import Variables


#-------------------------------------------------------------------------------
# Turbulence model class
#-------------------------------------------------------------------------------


class TurbulenceModel(Variables):
    """
    Manage the input/output markups in the xml doc about Turbulence
    """
    def __init__(self, case):
        """
        Constructor.
        """
        self.case = case

        self.node_models = self.case.xmlGetNode('thermophysical_models')
        self.node_lagr   = self.case.xmlGetNode('lagrangian')
        self.node_coal   = self.node_models.xmlGetChildNode('pulverized_coal', 'model')
        self.node_joule  = self.node_models.xmlGetChildNode('joule_effect',    'model')
        self.node_gas    = self.node_models.xmlGetChildNode('gas_combustion',  'model')
        self.node_turb   = self.node_models.xmlInitChildNode('turbulence', 'model')
        self.node_bc     = self.case.xmlGetNode('boundary_conditions')

        self.turbModel = ('off',
                          'mixing_length',
                          'k-epsilon',
                          'k-epsilon-PL',
                          'Rij-epsilon',
                          'Rij-SSG',
                          'v2f-phi',
                          'k-omega-SST',
                          'LES_Smagorinsky',
                          'LES_dynamique')


    def defaultTurbulenceValues(self):
        """
        Return in a dictionnary which contains default values
        """
        default = {}
        default['turbulence_model'] = "k-epsilon"
        default['length_scale']     = 1.0
        default['scale_model']      = 1
        default['gravity_terms']    = "on"

        return default


    def turbulenceModelsList(self):
        """
        Create a tuple with the turbulence models allowed by the analysis
        features (multi-phases model, and reactive flow models).
        """
        turbList = self.turbModel

        if self.node_lagr and self.node_lagr['model'] != 'off':
            turbList = ('off', 'k-epsilon', 'k-epsilon-PL', 
                        'Rij-epsilon', 'Rij-SSG', 'v2f-phi', 'k-omega-SST')

        for node in (self.node_gas, self.node_coal, self.node_joule):
            if node and node['model'] != 'off':
                turbList = ('k-epsilon', 'k-epsilon-PL', 
                            'Rij-epsilon', 'Rij-SSG', 'v2f-phi', 'k-omega-SST')

        return turbList


    def getAllTurbulenceModel(self):
        """
        Return all defined turbulence models in a tuple
        """
        return self.turbModel


    def setTurbulenceModel(self, model_turb):
        """
        Input ITURB
        """
        if model_turb not in self.turbulenceModelsList():
#TODO MSG
            sys.exit(1)

        if model_turb == 'mixing_length':
            self.setNewProperty(self.node_turb, 'turb_viscosity')

        elif model_turb in ('k-epsilon', 'k-epsilon-PL'):
            for value in ('turb_k', 'turb_eps'):
                self.setNewVariable(self.node_turb, value)            
            self.setNewProperty(self.node_turb, 'turb_viscosity')
            self.setBoundaryTurbulence()

        elif model_turb in ('Rij-epsilon', 'Rij-SSG'):
            for value in ('component_R11', 'component_R22', 'component_R33',
                          'component_R12', 'component_R13', 'component_R23',
                          'turb_eps'):
                self.setNewVariable(self.node_turb, value)            
            self.setNewProperty(self.node_turb, 'turb_viscosity')
            self.setBoundaryTurbulence()

        elif model_turb in ('LES_Smagorinsky', 'LES_dynamique'):
            self.setNewProperty(self.node_turb, 'smagorinsky_constant')
            from TimeStep import TimeStepModel
            TimeStepModel(self.case).setTimePassing(0)
            del TimeStepModel

        elif model_turb == 'v2f-phi':
            for value in ('turb_k', 'turb_eps', 'turb_phi', 'turb_fb'):
                self.setNewVariable(self.node_turb, value)            
            self.setNewProperty(self.node_turb, 'turb_viscosity')
            self.setBoundaryTurbulence()

        elif model_turb == 'k-omega-SST':
            for value in ('turb_k', 'turb_omega'):
                self.setNewVariable(self.node_turb, value)            
            self.setNewProperty(self.node_turb, 'turb_viscosity')
            self.setBoundaryTurbulence()

        else:
            model_turb = 'off'

        self.node_turb['model'] = model_turb



    def setBoundaryTurbulence(self):
        """
        Put boundaries conditions if it's necessary
        """
        from DefineBoundaryRegions import DefBCModel
        for nodbc in self.node_bc.xmlGetChildNodeList('inlet'):
            DefBCModel(self.case).initCondTurbulence(nodbc, '0.0')
        del DefBCModel


    def getTurbulenceVariable(self):
        """
        """
        model = self.getTurbulenceModel()
        nodeList = []

        if model in ('k-epsilon', 'k-epsilon-PL'):
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_k'))
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_eps'))

        elif model in ('Rij-epsilon', 'Rij-SSG'):
            for var in ('component_R11', 'component_R22', 'component_R33',
                        'component_R12', 'component_R13', 'component_R23',
                        'turb_eps'):
                nodeList.append(nodeTurb.xmlGetNode('variable', name=var))

        elif model in ('v2f-phi'):
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_k'))
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_eps'))
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_phi'))
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_fb'))

        elif model in ('k-omega-SST'):
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_k'))
            nodeList.append(nodeTurb.xmlGetNode('variable', name='turb_omega'))

        return nodeList



    def getTurbulenceModel(self):
        """
        Return the current turbulence model.
        """ 
        model = self.node_turb['model']
        if model not in self.turbulenceModelsList():
            model = self.defaultTurbulenceValues()['turbulence_model']
            self.setTurbulenceModel(model)
        return model


    def setLengthScale(self, l_scale):
        """
        Input XLOMLG.
        """
        if self.getTurbulenceModel() == 'mixing_length':
            self.node_turb.xmlSetData('mixing_length_scale', l_scale)


    def getLengthScale(self):
        """
        Return XLOMLG.
        """
        l_scale = self.node_turb.xmlGetDouble('mixing_length_scale')
        if not l_scale:
            l_scale = self.defaultTurbulenceValues()['length_scale']
            self.setLengthScale(l_scale)
        return l_scale


#FIXME : to modify for a scriptable application
    def getAdvancedOptions(self):
        """
        Ask one popup for advanced specifications.
        """
        node_gravity = self.node_turb.xmlInitNodeList('gravity_terms', 'status')[0]

        default = {}

        default['model']     = self.getTurbulenceModel()
        default['scale_mod'] = self.node_turb.xmlGetInt('scale_model')
        default['gravity']   = node_gravity['status']

        if default['scale_mod'] != 0 and default['scale_mod'] != 1 and default['scale_mod'] != 2:
            default['scale_mod'] = self.defaultTurbulenceValues()['scale_model']
        if not default['gravity']:
            default['gravity'] = self.defaultTurbulenceValues()['gravity_terms']
        return default
#FIXME : to modify for a scriptable application


#FIXME : to modify for a scriptable application
    def setAdvancedOptions(self, select):
        """
        Ask one popup for advanced specifications
        """
        node_gravity = self.node_turb.xmlGetNodeList('gravity_terms', 'status')[0]

        self.node_turb.xmlSetData('scale_model', select['scale_mod'])
        node_gravity['status'] = select['gravity']
#FIXME : to modify for a scriptable application
        

    def getTurbulenceVariable(self):
        """
        Return the turbulence <variable> markup list.
        """
        model = self.getTurbulenceModel()
        nodeList = []

        if model in ('k-epsilon','k-epsilon-PL'):
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_k')[0])
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_eps')[0])
        elif model in ('Rij-epsilon', 'Rij-SSG'):
            for var in ('component_R11', 'component_R22', 'component_R33',
                        'component_R12', 'component_R13', 'component_R23'):
                nodeList.append(self.node_turb.xmlGetNodeList('variable', name=var)[0])
        elif model == 'v2f-phi':
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_k')[0])
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_eps')[0])
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_phi')[0])
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_fb')[0])
        elif model == 'k-omega-SST':
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_k')[0])
            nodeList.append(self.node_turb.xmlGetNodeList('variable', name='turb_omega')[0])
        return nodeList


    def getTurbulenceProperty(self):
        """
        Return the turbulence <property> markup list.
        """
        model = self.getTurbulenceModel()
        nodeList = []

        if model in ('mixing_length', 'k-epsilon', 'k-epsilon-PL', 
                     'Rij-epsilon', 'Rij-SSG', 'v2f-phi', 'k-omega-SST'):
            nodeList.append(self.node_turb.xmlGetNodeList('property', name='turb_viscosity')[0])
        elif model in ('LES_Smagorinsky', 'LES_dynamique'):
            nodeList.append(self.node_turb.xmlGetNodeList('property', name='smagorinsky_constant')[0])
        return nodeList


    def getTurbulenceNodeList(self):
        """
        Return all nodes about turbulence modelling.
        """
        nodeList = []
        for node in self.getTurbulenceVariable(): nodeList.append(node)
        for node in self.getTurbulenceProperty(): nodeList.append(node)
        return nodeList


#-------------------------------------------------------------------------------
# Popup window
#-------------------------------------------------------------------------------



class AdvancedOptionsDialog(Dialog.Dialog):
    """
    """
    def getGravityTerms(self, event=None):
        """
        Input IGRAKE/IGRARI.
        """
        return self.gravity_terms.get()


    def getScales(self, event=None):
        """
        Input IDEUCH.
        """
        return self.scales.get()


    def body(self,master):
        """
        Creation of popup window's widgets
        """
        t = PageText()

        self.gravity_terms = Tix.StringVar()
        self.scales = Tix.StringVar()

        self.result = self.default
        self.gravity_terms.set(self.result['gravity'])
        self.scales.set(self.result['scale_mod'])
        model = self.result['model']

        # IGRAKE/IGRARI
        #
        w = Tix.Frame(master, relief=FLAT)
        w.pack(side=TOP, fill=X, padx=10, pady=10)

        l2 = Tix.Label(w, text=t.GRAVITY_TERMS1)
        self.balloon.bind_widget(l2, statusmsg=t.MSG_GRAVITY,
                                 balloonmsg=t.KEYWORD+"IGRAKE / IGRARI")

        c2 = Tix.Checkbutton(w,
                             onvalue='on', offvalue='off',
                             variable=self.gravity_terms,
                             command=self.getGravityTerms)
        self.balloon.bind_widget(c2, statusmsg=t.MSG_GRAVITY,
                                 balloonmsg=t.KEYWORD+"IGRAKE / IGRARI")

        # Wall function type
        #
        l3 = Tix.Label(w, text=t.SCALES)
        self.balloon.bind_widget(l3, balloonmsg=t.KEYWORD+"IDEUCH")

        c3 = Tix.OptionMenu(w, options='menubutton.width 15')
        c3.menubutton.config(bd=2, relief=RAISED)
        self.balloon.bind_widget(c3, balloonmsg=t.KEYWORD+"IDEUCH")

        c3.add_command('0', label=t.SCALE1)
        c3.add_command('1', label=t.SCALES2)
        c3.add_command('2', label=t.INVAR)
        c3.config(variable=self.scales, command=self.getScales)

        l2.grid(row=1, column=0, padx=5, pady=10, sticky=W)
        c2.grid(row=1, column=1, padx=15)
        l3.grid(row=0, column=0, padx=5, pady=10, sticky=W)
        c3.grid(row=0, column=1, padx=15)

        if model == 'k-epsilon': l2.config(text=t.GRAVITY_TERMS1)
        elif model == 'Rij-epsilon': l2.config(text=t.GRAVITY_TERMS2)


    def apply(self):
        """
        What to do when user clicks on 'OK'.
        """
        self.result['scale_mod'] = self.getScales()
        self.result['gravity'] = self.getGravityTerms()


#-------------------------------------------------------------------------------
# Main view class
#-------------------------------------------------------------------------------


class TurbulenceView(TkPage.Page):
    """
    Class to open Turbulence Page.
    """
    def _dependsPages(self, name):
        """
        Construction of the list of dependencies Pages.
        """
        self.case[name]['depends'] = ['models/initia',
                                      'bounda/thermo']


    def _tkControlVariables(self):
        """
        Tkinter variables declaration.
        """
        self.turb_model = Tix.StringVar()
        self.scales = Tix.StringVar()
        self.gravity_terms = Tix.StringVar()
        self.l_scale = Tix.DoubleVar()


    def _pageControl(self):
        """
        Instantiate the turbulence modelling class.
        """
        self.model = TurbulenceModel(self.case)


    def getLengthScale(self, event=None):
        """
        Input XLOMLG.
        """
        self.stbar.busy()

        if self.check2.isSPositive(self.e1, self.l_scale):
            self.model.setLengthScale(self.l_scale.get())
        self.stbar.idle()


    def getTurbulenceModel(self, event=None):
        """
        Input ITURB.
        """
        self.stbar.busy()

        model = self.turb_model.get()
        self.model.setTurbulenceModel(model)

        self.s.pack_forget()
        self.w2.pack_forget()
        self.w3.pack_forget()

        if model == 'mixing_length':
            self.s.pack(side=TOP, fill=X)
            self.w2.pack(side=TOP, fill=X, padx=10)
            self.model.getLengthScale()
        elif model not in ('off', 'LES_Smagorinsky', 'LES_dynamique'):
            self.s.pack(side=TOP, fill=X)
            self.w3.pack(side=TOP, fill=X, padx=10)
  
        if model in ('LES_Smagorinsky', 'LES_dynamique'):
            t = PageText()
            Dialog.ShowInfo(self.master,
                            title=t.TURBULENCE_TITLE,
                            text=t.MSG_LES)
        self.stbar.idle()

 
    def getAdvancedOptions(self, event=None):
        """
        Ask one popup for advanced specifications
        """
        self.stbar.busy()
        t = PageText()

        default = self.model.getAdvancedOptions()
        if default['model'] in ('k-epsilon','k-epsilon-PL'):windowTitle = t.POPUP_KEPS
        if default['model'] in ('Rij-epsilon', 'Rij-SSG'): windowTitle = t.POPUP_RIJ
        if default['model'] == 'k-omega-SST': windowTitle = t.POPUP_KOMEGA
        if default['model'] == 'v2f-phi': windowTitle = t.POPUP_V2F

        dialog = AdvancedOptionsDialog(self.master,
                                       title=windowTitle,
                                       stbar=self.stbar,
                                       default=default)
        self.model.setAdvancedOptions(dialog.result)

        self.stbar.idle()


    def _createWidgets(self):
        """
        Create the Page layout.
        """
        t = PageText()

        lf1 = Tix.LabelFrame(self.myPage, bd=2,
                             label=t.TURBULENCE_TITLE, relief=FLAT)
        lf1.label.config(font=fT)
        lf1.pack(side=TOP, fill=X, padx=10, pady=10)

        w1 = Tix.Frame(lf1.frame, relief=FLAT)
        w1.pack(side=TOP, fill=X)

        # Select the turbulence model
        #
        self.b1 = Tix.OptionMenu(w1, options='menubutton.width 45')
        self.b1.menubutton.config(bd=2, relief=RAISED)
        self.balloon.bind_widget(self.b1, statusmsg=t.MSG_ITURB,
                                 balloonmsg=t.KEYWORD+"ITURB")

        self.b1.grid(row=0, column=0, padx=10, pady=20)

        self.b1.add_command('off',              label=t.LAMINAR)
        self.b1.add_separator('')
        self.b1.add_command('mixing_length',    label=t.MIXING)
        self.b1.add_command('k-epsilon',        label=t.KEPS)
        self.b1.add_command('k-epsilon-PL',     label=t.KEPSPL)
        self.b1.add_command('Rij-epsilon',      label=t.RIJEPS)
        self.b1.add_command('Rij-SSG',		label=t.RIJSSG)
        self.b1.add_command('v2f-phi',		label=t.V2F)
        self.b1.add_command('k-omega-SST',      label=t.KOSST)
        self.b1.add_command('LES_Smagorinsky',  label=t.LES1)
        self.b1.add_command('LES_dynamique',    label=t.LES2)
        self.b1.config(variable=self.turb_model,
                       command=self.getTurbulenceModel)

        # Separator
        #
        self.s = Tix.Frame(lf1.frame, height=2, bd=2, relief=SUNKEN)
        self.s.pack(side=TOP, fill=X)

        # Length scale for the mixing length turbulence model
        #
        self.w2 = Tix.Frame(lf1.frame, relief=FLAT)
        self.w2.pack(side=TOP, fill=X)

        l1 = Tix.Label(self.w2, text=t.LENGTH_SCALE)
        l1.grid(row=0, column=0, padx=20, pady=30)
        self.balloon.bind_widget(l1, balloonmsg=t.KEYWORD+"XLOMLG",
                                 statusmsg=t.MSG_LENGTH_SCALE)

        self.e1 = Tix.Entry(self.w2, bd=2, width=10, textvariable=self.l_scale)
        self.balloon.bind_widget(self.e1, balloonmsg=t.KEYWORD+"XLOMLG",
                                 statusmsg=t.MSG_LENGTH_SCALE)
        self.e1.grid(row=0, column=1, padx=15, pady=10, sticky=E)
        self.e1.event_add("<<Event>>", "<Return>", "<Leave>", "<FocusOut>")
        self.e1.bind ("<<Event>>", self.getLengthScale)

        # Advanced options
        #
        self.w3 = Tix.Frame(lf1.frame, relief=FLAT)
        self.w3.pack(side=TOP, fill=X)

        Tix.Label(self.w3, text=t.ADVANCED, relief=FLAT).grid(row=0, 
                     column=0, padx=20,pady=30)
        self.imsop = Tix.PhotoImage(file=PIC_PATH+'graduate.gif')
        self.buw1 = Tix.Button(self.w3, image=self.imsop,
                               command=self.getAdvancedOptions)
        self.buw1.grid(row=0, column=1)


    def _initializeWidgets(self):
        """
        Extract resquested informations from XML document.
        This informations are used to initialize the widgets.
        For this page default values of all widgets are necessary
        included in the XML file.
        """
        # Update the turbulence models list with the analysis features
        #
        for turb in self.model.turbModel:
            if turb not in self.model.turbulenceModelsList():
                self.b1.disable(turb)

        # Select the turbulence model
        model = self.model.getTurbulenceModel()
        self.b1.config(value=model)

        # Length scale
        self.l_scale.set(self.model.getLengthScale())


#-------------------------------------------------------------------------------
# Text and messages for this page
#-------------------------------------------------------------------------------


class PageText:
    """
    Storage of all texts and messages for this page.
    """
    def __init__(self):
        
        # 1) Texts
        #
        if Tool.GuiParam.lang == 'fr':
            self.ADVANCED         = "Options avancées"
            self.GRAVITY_TERMS1   = "Termes de gravité dans les équations de k-epsilon"
            self.GRAVITY_TERMS2   = "Termes de gravité dans les équations de Rij-epsilon"
            self.LENGTH_SCALE     = "Longueur de mélange"
            self.KEYWORD          = "Mot clé Code_Saturne : "
            self.LAMINAR          = "Pas de modèle (i.e. écoulement laminaire)"
            self.KEPS             = "k-epsilon"
            self.KEPSPL           = "k-epsilon Production Linéaire"
            self.RIJEPS           = "Rij-epsilon LRR"
            self.RIJSSG           = "Rij-epsilon SSG"
            self.V2F              = "v2f-phi"
            self.KOSST            = "k-omega SST"
            self.LES1             = "LES (Smagorinsky)"
            self.LES2             = "LES (modèle dynamique classique)"
            self.MIXING           = "Longueur de mélange (à valider)"
            self.ON               = "oui"
            self.OFF              = "non"
            self.SCALE1           = "modèle à 1 échelle"
            self.SCALES2          = "modèle à 2 échelles"
            self.INVAR            = "loi invariante"
            self.POPUP_KEPS       = "Options pour le modèle k-epsilon"
            self.POPUP_RIJ        = "Options pour le modèle Rij-epsilon"
            self.POPUP_KOMEGA     = "Options pour le modèle k-omega_SST"
            self.POPUP_V2F        = "Options pour le modèle v2f-phi"
            self.SCALES           = "Type de loi de paroi"
            self.TURBULENCE_TITLE = "Modèle de turbulence"
        else:
            self.ADVANCED         = "Advanced options"
            self.GRAVITY_TERMS1   = "Gravity terms in the k-epsilon equations"
            self.GRAVITY_TERMS2   = "Gravity terms in the Rij-epsilon equations"
            self.LENGTH_SCALE     = "Length scale"
            self.KEYWORD          = "Code_Saturne key word: "
            self.LAMINAR          = "No model (i.e. laminar flow)"
            self.KEPS             = "k-epsilon"
            self.KEPSPL           = "k-epsilon Linear Production"
            self.RIJEPS           = "Rij-epsilon LLR"
            self.RIJSSG           = "Rij-epsilon SSG"
            self.V2F              = "v2f-phi"
            self.KOSST            = "k-omega SST"
            self.LES1             = "LES (Smagorinsky)"
            self.LES2             = "LES (classical dynamic model)"
            self.MIXING           = "Mixing length (to validate)"
#            self.ON               = "on"
#            self.OFF              = "off"
            self.SCALE1           = "One scale model"
            self.SCALES2          = "Two scales model"
            self.INVAR            = "Invariant law"
            self.POPUP_KEPS       = "Options for k-epsilon model"
            self.POPUP_RIJ        = "Options for Rij-epsilon model"
            self.POPUP_KOMEGA     = "Options for k-omega_SST model"
            self.POPUP_V2F        = "Options for v2f-phi model"
            self.SCALES           = "Wall function type"
            self.TURBULENCE_TITLE = "Turbulence model"

        # 2) Messages
        #
        if Tool.GuiParam.lang == 'fr':
            self.MSG_GRAVITY      = "Utile si la gravité est non nulle."
            self.MSG_ITURB        = "Pour le modèle 'longueur de mélange' contacter "\
                                    "l'équipe de développement."
            self.MSG_LENGTH_SCALE = "L'echelle de longueur est un réel > 0."
            self.MSG_LES          = "Consultez les informations dans le "\
                                    "sous-programme utilisateur : 'ussmag'"
        else:
            self.MSG_GRAVITY      = "Usefull if gravity is not set to zero."
            self.MSG_ITURB        = "For mixing length contact the "\
                                    "development team."
            self.MSG_LENGTH_SCALE = "The mixing length is a > 0 real."
            self.MSG_LES          = "Please report to the informations "\
                                    "contain in the user subroutine: 'ussmag'"


#-------------------------------------------------------------------------------
# TurbulenceModel test case
#-------------------------------------------------------------------------------


class TurbulenceTestCase(unittest.TestCase):
    """
    """
    def setUp(self):
        """This method is executed before all "check" methods."""
        from Base.XMLengine import Case, XMLDocument
        from Base.XMLinitialize import XMLinit
        Tool.GuiParam.lang = 'en'
        self.case = Case(None)
        XMLinit(self.case)
        self.doc = XMLDocument()

    def tearDown(self):
        """This method is executed after all "check" methods."""
        del self.case
        del self.doc

    def xmlNodeFromString(self, string):
        """Private method to return a xml node from string"""
        return self.doc.parseString(string).root()

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

    def checkTurbulenceModelsList(self):
        """Check whether the TurbulenceModelList could be get"""
        mdl = TurbulenceModel(self.case)
        from Lagrangian import LagrangianModel
        LagrangianModel(self.case).setLagrangianModel('one_way')
        del LagrangianModel

        ff = ('off','k-epsilon','k-epsilon-PL','Rij-epsilon',
              'Rij-SSG','v2f-phi','k-omega-SST')
        assert mdl.turbulenceModelsList() == ff, \
               'Could not return Lagrangian turbulence models'

        mdl.node_gas['model'] = 'on'
        ff = ('k-epsilon','k-epsilon-PL','Rij-epsilon',
                'Rij-SSG','v2f-phi','k-omega-SST')
        assert mdl.turbulenceModelsList() == ff, \
            'Could not return combustion turbulence models'

    def checkSetMixingLength(self):
        """Check whether the mixing length turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.setTurbulenceModel('mixing_length')
        truc = mdl.node_turb
        doc = '<turbulence model="mixing_length">'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1</reference_velocity>'\
                '</initialization>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
            'Could not set the mixing length turbulence model'

    def checkSetkepsilon(self):
        """Check whether the k-epsilon turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('k-epsilon')
        truc = mdl.node_turb
        doc = '<turbulence model="k-epsilon">'\
                '<variable label="TurbEner" name="turb_k"/>'\
                '<variable label="Dissip" name="turb_eps"/>'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1</reference_velocity>'\
                '</initialization>'\
               '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
            'Could not set the k-epsilon turbulence model'

    def checkSetkepsilonPL(self):
        """Check whether the k-epsilon turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('k-epsilon-PL')
        truc = mdl.node_turb
        doc = '<turbulence model="k-epsilon-PL">'\
                '<variable label="TurbEner" name="turb_k"/>'\
                '<variable label="Dissip" name="turb_eps"/>'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1</reference_velocity>'\
                '</initialization>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
            'Could not set the linear production k-epsilon turbulence model'

    def checkSetRijepsilon(self):
        """Check whether the Rij-epsilon turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.setTurbulenceModel('Rij-epsilon')
        truc = mdl.node_turb
        doc = '<turbulence model="Rij-epsilon">'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<variable label="R11" name="component_R11"/>'\
                '<variable label="R22" name="component_R22"/>'\
                '<variable label="R33" name="component_R33"/>'\
                '<variable label="R12" name="component_R12"/>'\
                '<variable label="R13" name="component_R13"/>'\
                '<variable label="R23" name="component_R23"/>'\
                '<variable label="Dissip" name="turb_eps"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1</reference_velocity>'\
                '</initialization>'\
            '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
            'Could not set the Rij-epsilon turbulence model'

    def checkSetRijepsilonSSG(self):
        """Check whether the Rij-epsilon SSG turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.setTurbulenceModel('Rij-SSG')
        truc = mdl.node_turb
        doc = '<turbulence model="Rij-SSG">'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1</reference_velocity>'\
                '</initialization>'\
                '<variable label="R11" name="component_R11"/>'\
                '<variable label="R22" name="component_R22"/>'\
                '<variable label="R33" name="component_R33"/>'\
                '<variable label="R12" name="component_R12"/>'\
                '<variable label="R13" name="component_R13"/>'\
                '<variable label="R23" name="component_R23"/>'\
                '<variable label="Dissip" name="turb_eps"/>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
           'Could not set the Rij-epsilon SSG turbulence model'

    def checkSetLESSmagorinsky(self):
        """Check whether the classical LES turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.node_turb.xmlRemoveChild('property')
        mdl.node_turb.xmlRemoveChild('initialization')
        mdl.setTurbulenceModel('LES_Smagorinsky')
        truc = mdl.node_turb
        doc = '<turbulence model="LES_Smagorinsky">'\
                '<property label="Csdyn2" name="smagorinsky_constant"/>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
             'Could not set the LES turbulence model'

    def checkSetLESdynamique(self):
        """Check whether the dynamique LES turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.node_turb.xmlRemoveChild('property')
        mdl.node_turb.xmlRemoveChild('initialization')
        mdl.setTurbulenceModel('LES_dynamique')
        truc = mdl.node_turb
        doc = '<turbulence model="LES_dynamique">'\
                '<property label="Csdyn2" name="smagorinsky_constant"/>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
           'Could not set the dynamique LES turbulence model'

    def checkSetV2F(self):
        """Check whether the v2f phi turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('v2f-phi')
        truc = mdl.node_turb
        doc = '<turbulence model="v2f-phi">'\
                '<variable label="TurbEner" name="turb_k"/>'\
                '<variable label="Dissip" name="turb_eps"/>'\
                '<variable label="phi" name="turb_phi"/>'\
                '<variable label="fb" name="turb_fb"/>'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1.0</reference_velocity>'\
                '</initialization>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
           'Could not set the v2f phi turbulence model'

    def checkkOmegaSST(self):
        """Check whether the k-Omega SST turbulence model could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('k-omega-SST')
        doc = '<turbulence model="k-omega-SST">'\
                '<variable label="TurbEner" name="turb_k"/>'\
                '<variable label="Dissip" name="turb_eps"/>'\
                '<property label="turb. vi" name="turb_viscosity"/>'\
                '<variable label="omega" name="turb_omega"/>'\
                '<initialization choice="reference_velocity">'\
                  '<reference_velocity>1.0</reference_velocity>'\
                '</initialization>'\
            '</turbulence>'
        assert mdl.node_turb == self.xmlNodeFromString(doc),\
           'Could not set the k_Omega SST turbulence model'

    def checkGetTurbulenceModel(self):
        """Check whether the turbulence model could be get"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('Rij-epsilon')
        assert mdl.getTurbulenceModel() == 'Rij-epsilon', \
            'Could not get the turbulence model'

    def checkGetLengthScale(self):
        """Check whether the mixing length scale could be get"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('mixing_length')
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.node_turb.xmlRemoveChild('property')
        mdl.node_turb.xmlRemoveChild('initialization')
        assert mdl.getLengthScale() == mdl.defaultTurbulenceValues()['length_scale'],\
            'Could not get the default mixing length scale'

    def checkSetLengthScale(self):
        """Check whether the mixing length scale could be set"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('mixing_length')
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.node_turb.xmlRemoveChild('property')
        mdl.node_turb.xmlRemoveChild('initialization')
        mdl.setLengthScale(123.0)
        truc = mdl.node_turb
        doc = '<turbulence model="mixing_length">'\
                '<mixing_length_scale>123</mixing_length_scale>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
           'Could not set the mixing length scale'

    def checkGetAdvancedOptions(self):
        """Check whether the advanced options could be get"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('k-epsilon')
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.node_turb.xmlRemoveChild('property')
        mdl.node_turb.xmlRemoveChild('initialization')
        d = mdl.getAdvancedOptions()
        dd = mdl.defaultTurbulenceValues()
        assert d['scale_mod'] == dd['scale_model'],\
            'Could not get the default two scales model'
        assert d['gravity'] == dd['gravity_terms'],\
            'Could not get the default gravity terms'

    def checkSetAdvancedOptions(self):
        """Check whether the advanced options could be get"""
        mdl = TurbulenceModel(self.case)
        mdl.setTurbulenceModel('k-epsilon')
        mdl.node_turb.xmlRemoveChild('variable')
        mdl.node_turb.xmlRemoveChild('property')
        mdl.node_turb.xmlRemoveChild('initialization')
        d = mdl.getAdvancedOptions()
        d['gravity'] = "off"
        d['scale_mod'] = 1
        mdl.setAdvancedOptions(d)
        truc = mdl.node_turb
        doc = '<turbulence model="k-epsilon">'\
                  '<gravity_terms status="off"/>'\
                  '<scale_model>1</scale_model>'\
              '</turbulence>'
        assert truc == self.xmlNodeFromString(doc),\
           'Could not get the advanced options'

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

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

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


syntax highlighted by Code2HTML, v. 0.9.1