From 58058ccd6e4c1088a16b69f39219ae23a8439390 Mon Sep 17 00:00:00 2001 From: Martin Beaudoin Date: Thu, 4 Jul 2013 23:35:16 -0400 Subject: [PATCH] ThirdParty: new PyFoam scripts for mixingPlane and GGI interfaces --- .../LocalDev/Hydro-Quebec/PyFoam/AllMake | 12 + .../PyFoam/ChangeMixingPlaneBoundary.py | 36 ++- .../ConvertMixingPlaneBoundaryToNewSyntax.py | 200 ++++++++++++ .../Hydro-Quebec/PyFoam/InitGgiInterface.py | 296 ++++++++++++++++++ .../PyFoam/InitMixingPlaneInterface.py | 241 ++++++++++++++ ...amConvertMixingPlaneBoundaryToNewSyntax.py | 5 + .../PyFoam/pyFoamInitGgiInterface.py | 5 + .../PyFoam/pyFoamInitMixingPlaneInterface.py | 5 + 8 files changed, 785 insertions(+), 15 deletions(-) create mode 100644 ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ConvertMixingPlaneBoundaryToNewSyntax.py create mode 100644 ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitGgiInterface.py create mode 100644 ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitMixingPlaneInterface.py create mode 100755 ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamConvertMixingPlaneBoundaryToNewSyntax.py create mode 100755 ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitGgiInterface.py create mode 100755 ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitMixingPlaneInterface.py diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/AllMake b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/AllMake index 5fb320e41..7c9cd98d9 100755 --- a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/AllMake +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/AllMake @@ -62,6 +62,18 @@ cp ChangeMixingPlaneBoundary.py $PYFOAM_DIR/lib/python$pythonVersion/site-packag cp pyFoamChangeGGIBoundary.py $PYFOAM_DIR/bin cp ChangeGGIBoundary.py $PYFOAM_DIR/lib/python$pythonVersion/site-packages/PyFoam/Applications +# pyFoamInitializeMixingPlane.py +cp pyFoamInitMixingPlaneInterface.py $PYFOAM_DIR/bin +cp InitMixingPlaneInterface.py $PYFOAM_DIR/lib/python$pythonVersion/site-packages/PyFoam/Applications + +# pyFoamInitializeGGI.py +cp pyFoamInitGgiInterface.py $PYFOAM_DIR/bin +cp InitGgiInterface.py $PYFOAM_DIR/lib/python$pythonVersion/site-packages/PyFoam/Applications + +# pyFoamConvertMixingPlaneBoundaryToNewSyntax.py +cp pyFoamConvertMixingPlaneBoundaryToNewSyntax.py $PYFOAM_DIR/bin +cp ConvertMixingPlaneBoundaryToNewSyntax.py $PYFOAM_DIR/lib/python$pythonVersion/site-packages/PyFoam/Applications + set +x echo ======================================== echo Done diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ChangeMixingPlaneBoundary.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ChangeMixingPlaneBoundary.py index 5025920aa..4486fc5d4 100644 --- a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ChangeMixingPlaneBoundary.py +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ChangeMixingPlaneBoundary.py @@ -58,18 +58,21 @@ Change MixingPlane boundary condition parameters dest="coordinateSystemE3", default=None, help='axis E3 for coordinate system of mixingPlane') - self.parser.add_option("--assembly", + self.parser.add_option("--ribbonPatchSweepAxis", action="store", - dest="assembly", + dest="ribbonPatchSweepAxis", default=None, - help='Assembly (master|slave|both|userdefined') - self.parser.add_option("--orientation", + help='ribbonPatch sweepAxis (X|Y|Z|R|Theta') + self.parser.add_option("--ribbonPatchStackAxis", action="store", - dest="orientation", + dest="ribbonPatchStackAxis", default=None, - help='Orientation of profile (\ -dirX_spanY| \ -dirX_spanZ|dirY_spanX|dirY_spanZ|dirZ_spanX|dirZ_spanY|dirR_spanTheta|dirR_spanZ|dirTheta_spanZ|dirTheta_spanR|dirZ_spanTheta|dirZ_spanR|unknown)') + help='ribbonPatch stackAxis (X|Y|Z|R|Theta') + self.parser.add_option("--ribbonPatchDiscretization", + action="store", + dest="ribbonPatchDiscretization", + default=None, + help='ribbonPatch discretization (masterPatch|slavePatch|bothPatches|uniform|userDefined)') self.parser.add_option("--test", action="store_true", @@ -99,9 +102,6 @@ dirX_spanZ|dirY_spanX|dirY_spanZ|dirZ_spanX|dirZ_spanY|dirR_spanTheta|dirR_spanZ if self.parser.getOptions().shadowPatch!=None: val["shadowPatch"]=self.parser.getOptions().shadowPatch - if self.parser.getOptions().orientation!=None: - val["orientation"]=self.parser.getOptions().orientation - if val.has_key("coordinateSystem")==False: val["coordinateSystem"]={} @@ -120,11 +120,17 @@ dirX_spanZ|dirY_spanX|dirY_spanZ|dirZ_spanX|dirZ_spanY|dirR_spanTheta|dirR_spanZ if self.parser.getOptions().coordinateSystemE3!=None: val["coordinateSystem"]["e3"]=self.parser.getOptions().coordinateSystemE3 - if self.parser.getOptions().assembly!=None: - val["assembly"]=self.parser.getOptions().assembly + if val.has_key("ribbonPatch")==False: + val["ribbonPatch"]={} - if self.parser.getOptions().orientation!=None: - val["orientation"]=self.parser.getOptions().orientation + if self.parser.getOptions().ribbonPatchSweepAxis!=None: + val["ribbonPatch"]["sweepAxis"]=self.parser.getOptions().ribbonPatchSweepAxis + + if self.parser.getOptions().ribbonPatchStackAxis!=None: + val["ribbonPatch"]["stackAxis"]=self.parser.getOptions().ribbonPatchStackAxis + + if self.parser.getOptions().ribbonPatchDiscretization!=None: + val["ribbonPatch"]["discretization"]=self.parser.getOptions().ribbonPatchDiscretization break diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ConvertMixingPlaneBoundaryToNewSyntax.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ConvertMixingPlaneBoundaryToNewSyntax.py new file mode 100644 index 000000000..e69de7785 --- /dev/null +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/ConvertMixingPlaneBoundaryToNewSyntax.py @@ -0,0 +1,200 @@ +""" +Application-class that implements pyFoamConvertMixingPlaneToNewSyntax.py + +Adjust the mixingPlane interface definition in the boundary +file to the latest supported syntax. + +Author: + Martin Beaudoin, Hydro-Quebec, 2012. All rights reserved + +""" + +from PyFoamApplication import PyFoamApplication +from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile +from os import path +import sys + +# ------> Start of Python code snippet copied from an external source +# +# Author : Brian Beck +# http://code.activestate.com/recipes/410692-readable-switch-construction-without-lambdas-or-di/ +# +# License for this Python code snippet: +# +# This code that was deposited before July 15, 2008 on aspn.activestate.com. +# It is governed by the Python license (http://www.python.org/psf/license/) +# in accordance with the Python Cookbook agreement. +# +# Description: +# Python's lack of a 'switch' statement has garnered much discussion and even +# a PEP. The most popular substitute uses dictionaries to map cases to +# functions, which requires lots of defs or lambdas. While the approach shown +# here may be O(n) for cases, it aims to duplicate C's original 'switch' +# functionality and structure with reasonable accuracy. +# +# This class provides the functionality we want. You only need to look at +# this if you want to know how this works. It only needs to be defined +# once, no need to muck around with its internals. +# + +class switch(object): + def __init__(self, value): + self.value = value + self.fall = False + + def __iter__(self): + """Return the match method once, then stop""" + yield self.match + raise StopIteration + + def match(self, *args): + """Indicate whether or not to enter a case suite""" + if self.fall or not args: + return True + elif self.value in args: # changed for v1.5, see below + self.fall = True + return True + else: + return False + +# ------> End of Python code snippet copied from an external source + +#################################################################### +# +# The rest of this source code was written by me. +# Martin Beaudoin, June 2012 + +class ConvertMixingPlaneBoundaryToNewSyntax(PyFoamApplication): + def __init__(self,args=None): + description=""" +Change MixingPlane boundary condition parameters +""" + PyFoamApplication.__init__(self, + args=args, + description=description, + usage="%prog ", + interspersed=True, + changeVersion=False, + nr=1) + + def addOptions(self): + + self.parser.add_option("--test", + action="store_true", + default=False, + dest="test", + help="Only print the new boundary file") + + def run(self): + fName=self.parser.getArgs()[0] + + boundary=ParsedParameterFile(path.join(".",fName,"constant","polyMesh","boundary"),debug=False,boundaryDict=True) + + bnd=boundary.content + + if type(bnd)!=list: + print "Problem with boundary file (not a list)" + sys.exit(-1) + + found=False + + for index in range(0, len(bnd), 2): + + indexDefPatch=index+1 + + oldAssembly="" + oldOrientation="" + + if bnd[indexDefPatch]["type"]=="mixingPlane": + if bnd[indexDefPatch].has_key("assembly"): + print " Replacing the parameter 'assembly' for patch", bnd[index] + oldAssembly=bnd[indexDefPatch]["assembly"] + del bnd[indexDefPatch]["assembly"] + + if bnd[indexDefPatch].has_key("orientation"): + print " Replacing the parameter 'orientation' for patch", bnd[index] + oldOrientation=bnd[indexDefPatch]["orientation"] + del bnd[indexDefPatch]["orientation"] + + if bnd[indexDefPatch].has_key("ribbonPatch")==False: + bnd[indexDefPatch]["ribbonPatch"]={} + + if oldAssembly != "": + # Converting "assembly" to ribbonPatch/discretization + for case in switch(oldAssembly): + if case('master'): + bnd[indexDefPatch]["ribbonPatch"]["discretization"]="masterPatch" + break + if case('slave'): + bnd[indexDefPatch]["ribbonPatch"]["discretization"]="slavePatch" + break + if case('both'): + bnd[indexDefPatch]["ribbonPatch"]["discretization"]="bothPatches" + break + if case('userdefined'): + bnd[indexDefPatch]["ribbonPatch"]["discretization"]="userDefined" + break + if case(): # default + print "Unsupported assembly type: ", oldAssembly + + if oldOrientation != "": + # Converting "orientation" to ribbonPatch/ribbonPatchSweepAxis and + # ribbonPatch/ribbonPatchStackAxis + for case in switch(oldOrientation): + + if case('dirX_spanY'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="X" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Y" + break + if case('dirX_spanZ'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="X" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Z" + break + if case('dirY_spanX'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Y" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="X" + break + if case('dirY_spanZ'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Y" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Z" + break + if case('dirZ_spanX'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Z" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="X" + break + if case('dirZ_spanY'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Z" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Y" + break + if case('dirR_spanTheta'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="R" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Theta" + break + if case('dirR_spanZ'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="R" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Z" + break + if case('dirTheta_spanZ'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Theta" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Z" + break + if case('dirTheta_spanR'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Theta" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="R" + break + if case('dirZ_spanTheta'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Z" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="Theta" + break + if case('dirZ_spanR'): + bnd[indexDefPatch]["ribbonPatch"]["stackAxis"]="Z" + bnd[indexDefPatch]["ribbonPatch"]["sweepAxis"]="R" + break + if case(): # default + print "Unsupported orientation type: ", oldOrientation + + if self.parser.getOptions().test: + print boundary + else: + boundary.writeFile() + diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitGgiInterface.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitGgiInterface.py new file mode 100644 index 000000000..8120d9076 --- /dev/null +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitGgiInterface.py @@ -0,0 +1,296 @@ +""" +Application-class that implements pyFoamInitGgiInterface.py + +Inititialize various ggi interface attributes in the +constant/polymesh/boundary file, and in the time directories. + +Backups of the boundary file is created. + +Generate companion scripts for initializing the ggi zone faceSets. + +Modify the decomposeParDict file for the new ggi zones names. + +Author: + Martin Beaudoin, Hydro-Quebec, 2012. All rights reserved + +""" + +import sys, fnmatch, re +from os import path, listdir, chmod +from stat import * + +from PyFoamApplication import PyFoamApplication +from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile +from PyFoam.RunDictionary.TimeDirectory import TimeDirectory +from PyFoam.Basics.BasicFile import BasicFile + +class InitGgiInterface(PyFoamApplication): + def __init__(self,args=None): + description=""" +Init GGI boundary condition parameters in boundary file. +Init GGI boundary fields in time directories. +Generate faceSet scripts for ggi zones. +Modify GGI zones information in decomposeParDict file. +""" + PyFoamApplication.__init__(self, + args=args, + description=description, + usage="%prog ggi_MasterPatchName ggi_ShadowPatchName", + interspersed=True, + changeVersion=False, + nr=3) + + def addOptions(self): + self.parser.add_option("--type", + action="store", + dest="ggiType", + default='ggi', + help='ggi type: ggi | cyclicGgi | overlapGgi') + self.parser.add_option("--patchZoneName", + action="store", + dest="patchZoneName", + default=None, + help='Name of the zone for the GGI patch') + self.parser.add_option("--bridgeOverlapFlag", + action="store", + dest="bridgeOverlapFlag", + default=None, + help='bridgeOverlap flag (on/off)') + self.parser.add_option("--rotationAxis", + action="store", + dest="rotationAxis", + default=None, + help='rotation axis for cyclicGgi or overlapGgi') + self.parser.add_option("--rotationAngle", + action="store", + dest="rotationAngle", + default=None, + help='rotation axis angle for cyclicGgi. Accept Python math expressions like 360.0/17.0') + self.parser.add_option("--separationOffset", + action="store", + dest="separationOffset", + default=None, + help='separation offset for cyclicGgi') + self.parser.add_option("--nCopies", + action="store", + dest="nCopies", + default=None, + help='number of copies for overlapGgi') + self.parser.add_option("--timeDirs", + action="store", + dest="timeDirs", + default=None, + help='time directories for modifying the ggi boundaryfields. Accept expressions like "[0-9]*", "0", etc.') + + self.parser.add_option("--genFaceSetForGgiZonesScriptName", + action="store", + dest="genFaceSetForGgiZonesScriptName", + default="genFaceSetForGgiZones.setSet", + help='setSet batch file for generating faceSets for GGI zones. Default: genFaceSetForGgiZones.setSet') + + self.parser.add_option("--initGgiZonesScriptName", + action="store", + dest="initGgiZonesScriptName", + default="initGgiZones.sh", + help='script name for initializing the GGI zone faceSets. Default: initGgiZones.sh') + + self.parser.add_option("--test", + action="store_true", + default=False, + dest="test", + help="Only print the new boundary file") + + def createGGIPatch(self, patch, patchName, ggiType): + description="""\ +Create a default definition for a ggi patch, and replace +the current definition + """ + print "Replacing definition of patch: ", patchName, ":", patch + newPatch={ + 'type' : ggiType, + 'nFaces' : patch["nFaces"], + 'startFace' : patch["startFace"], + 'shadowPatch' : 'unknown', + 'zone' : patchName+'Zone', + 'bridgeOverlap' : 'true', + 'rotationAxis' : '(0 0 1)', + 'rotationAngle' : '0.0', + 'separationOffset' : '(0 0 0)' + } + return newPatch + + def modifyGGIPatchDefinition(self, patch, patchName, shadowName, ggiType, rotationAngle): + description="""\ +Modify the definition of a ggi patch + """ + print " Modifying ggi boundary definition in constant/polyMesh/boundary for patch", patchName + + patch["type"]=ggiType + + patch["shadowPatch"]=shadowName + + if self.parser.getOptions().patchZoneName!=None: + patch["zone"]=self.parser.getOptions().patchZoneName + else: + patch["zone"]=patchName+'Zone' + + if self.parser.getOptions().bridgeOverlapFlag!=None: + patch["bridgeOverlap"]=self.parser.getOptions().bridgeOverlapFlag + + if ggiType=="cyclicGgi": + if self.parser.getOptions().rotationAxis!=None: + patch["rotationAxis"]=self.parser.getOptions().rotationAxis + + # Use the rotationAngle value passed as a parameter. + # The calling function will change the sign for the slave ggi patch + if self.parser.getOptions().rotationAngle!=None: + patch["rotationAngle"]=rotationAngle + + if self.parser.getOptions().separationOffset!=None: + patch["separationOffset"]=self.parser.getOptions().separationOffset + + if ggiType=="overlapGgi": + if self.parser.getOptions().rotationAxis!=None: + patch["rotationAxis"]=self.parser.getOptions().rotationAxis + + if self.parser.getOptions().nCopies!=None: + patch["nCopies"]=self.parser.getOptions().nCopies + + + def modifyGGIPatchDefinitionInTimeDirs(self, caseDir, patchName, ggiType, timeDirs): + description="""\ +Modify the definition of a ggi patch in the time directories + """ + regex = fnmatch.translate(timeDirs) + + reobj = re.compile(regex) + + for timeDir in listdir(caseDir): + if reobj.match(timeDir): + print " Modifying ggi boundaryFields in timeDir", timeDir, "for patch", patchName + + td=TimeDirectory(caseDir, timeDir, yieldParsedFiles=True) + + for f in td: + print " Modifying field", f.name + f["boundaryField"][patchName]["type"]=ggiType + f.writeFile() + + + def generateCompanionFiles(self, caseDir, boundary): + description="""\ +Generate a setSet batch file based on the zone info specified in the ggi interfaces definition. +Generate a bash file for invoking setSet and setsToZones +Update GGI zone infoprmation in decomposeParDict + """ + # Default file: genFaceSetForGgiZones.setSet + bfGenFaceSets = BasicFile(path.join(caseDir, self.parser.getOptions().genFaceSetForGgiZonesScriptName)) + + print " Updating file ", bfGenFaceSets.name, " for generating GGI zones faceSet using the setSet command" + + bnd=boundary.content + + if type(bnd)!=list: + self.error("Problem with boundary file (not a list)") + + # Memorize list of GGI zones for later processing + listOfGgiZones = [] + + for index in range(0, len(bnd), 2): + patchName = bnd[index] + indexDefPatch=index+1 + if bnd[indexDefPatch]["type"]=='ggi' or bnd[indexDefPatch]["type"]=='cyclicGgi' or bnd[indexDefPatch]["type"]=='overlapGgi': + bfGenFaceSets.writeLine([ "faceSet " + bnd[indexDefPatch]["zone"] + " new patchToFace "+ patchName ]) + listOfGgiZones.append(bnd[indexDefPatch]["zone"]) + + bfGenFaceSets.writeLine([ "quit" ]) + bfGenFaceSets.close() + + # Default file: initGgiZones.sh + bfInitGgiZones = BasicFile(path.join(caseDir, self.parser.getOptions().initGgiZonesScriptName)) + + print " Updating file ", bfInitGgiZones.name, " for inititalizing GGI zones" + + bfInitGgiZones.writeLine([ "#!/bin/bash" ]) + bfInitGgiZones.writeLine([ "setSet -batch " + self.parser.getOptions().genFaceSetForGgiZonesScriptName ]) + bfInitGgiZones.writeLine([ "setsToZones -noFlipMap" ]) + bfInitGgiZones.close() + + # Set execution permissions for this script (755) + chmod(bfInitGgiZones.name, S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH|S_IROTH) + + # DecomposeParDict + decomposeParDictPath=path.join(caseDir,"system","decomposeParDict") + if path.exists(decomposeParDictPath): + print " Updating file ", decomposeParDictPath, " for GGI zones" + decomposeParDict=ParsedParameterFile(decomposeParDictPath,debug=False,backup=True) + dcp=decomposeParDict.content + dcp["globalFaceZones"]="(\n " + '\n '.join(list(listOfGgiZones)) + "\n)" + decomposeParDict.writeFile() + + def run(self): + caseDir=self.parser.getArgs()[0] + masterbName=self.parser.getArgs()[1] + shadowbName=self.parser.getArgs()[2] + + boundary=ParsedParameterFile(path.join(".",caseDir,"constant","polyMesh","boundary"),debug=False,boundaryDict=True,backup=True) + + bnd=boundary.content + + if type(bnd)!=list: + self.error("Problem with boundary file (not a list)") + + masterFound=False + shadowFound=False + updateTimeDirs=False + + timeDirs="0" + if self.parser.getOptions().timeDirs!=None: + timeDirs=self.parser.getOptions().timeDirs + updateTimeDirs=True + + ggiType=self.parser.getOptions().ggiType + + rotationAngle=0.0 + if self.parser.getOptions().rotationAngle!=None: + rotationAngle=float(eval(self.parser.getOptions().rotationAngle)) + + for index in range(len(bnd)): + indexDefPatch=index+1 + + if bnd[index]==masterbName: + masterFound=True + if bnd[indexDefPatch]["type"]!=ggiType: + bnd[indexDefPatch] = self.createGGIPatch(bnd[indexDefPatch], masterbName, ggiType) + + self.modifyGGIPatchDefinition(bnd[indexDefPatch], masterbName, shadowbName, ggiType, rotationAngle) + + if updateTimeDirs: + self.modifyGGIPatchDefinitionInTimeDirs(caseDir, masterbName, ggiType, timeDirs) + + elif bnd[index]==shadowbName: + shadowFound=True + if bnd[indexDefPatch]["type"]!=ggiType: + bnd[indexDefPatch] = self.createGGIPatch(bnd[indexDefPatch], shadowbName, ggiType) + self.modifyGGIPatchDefinition(bnd[indexDefPatch], shadowbName, masterbName, ggiType, -rotationAngle) + + if updateTimeDirs: + self.modifyGGIPatchDefinitionInTimeDirs(caseDir, shadowbName, ggiType, timeDirs) + + if masterFound and shadowFound: + break; + + if not masterFound: + self.error("Boundary patch",masterbName,"not found in",bnd[::2]) + + if not shadowFound: + self.error("Boundary patch",shadowbName,"not found in",bnd[::2]) + + if self.parser.getOptions().test: + print boundary + else: + boundary.writeFile() + + # Write companion files + self.generateCompanionFiles(caseDir, boundary) + diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitMixingPlaneInterface.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitMixingPlaneInterface.py new file mode 100644 index 000000000..b213dbbc1 --- /dev/null +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/InitMixingPlaneInterface.py @@ -0,0 +1,241 @@ +""" +Application-class that implements pyFoamInitMixingPlaneInterface.py + +Initialize various mixingPlane interface attributes in the +constant/polymesh/boundary file, and in the time directories. + +Backups of the modified files are created + +Author: + Martin Beaudoin, Hydro-Quebec, 2012. All rights reserved + +""" + +from PyFoamApplication import PyFoamApplication +from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile +from PyFoam.RunDictionary.TimeDirectory import TimeDirectory +from os import path, listdir +import sys, fnmatch, re + +class InitMixingPlaneInterface(PyFoamApplication): + def __init__(self,args=None): + description=""" +Init MixingPlane boundary condition parameters +""" + PyFoamApplication.__init__(self, + args=args, + description=description, + usage="%prog mixingPlane_MasterPatchName mixingPlane_ShadowPatchName", + interspersed=True, + changeVersion=False, + nr=3) + + def addOptions(self): + # No need for option --shadowPatch since the name of the shadowPatch is a mandatory parameter to the script + #self.parser.add_option("--shadowPatch", + # action="store", + # dest="shadowPatch", + # default=None, + # help='Name of the shadowPatch') + self.parser.add_option("--coordinateSystemName", + action="store", + dest="coordinateSystemName", + default="mixingCS", + help='coordinateSystemName (mixingCS)') + self.parser.add_option("--coordinateSystemType", + action="store", + dest="coordinateSystemType", + default=None, + help='coordinateSystemType (cyindrical/spherical)') + self.parser.add_option("--coordinateSystemOrigin", + action="store", + dest="coordinateSystemOrigin", + default=None, + help='origin for coordinate system of mixingPlane') + self.parser.add_option("--coordinateSystemE1", + action="store", + dest="coordinateSystemE1", + default=None, + help='axis E1 for coordinate system of mixingPlane') + self.parser.add_option("--coordinateSystemE3", + action="store", + dest="coordinateSystemE3", + default=None, + help='axis E3 for coordinate system of mixingPlane') + self.parser.add_option("--ribbonPatchSweepAxis", + action="store", + dest="ribbonPatchSweepAxis", + default=None, + help='ribbonPatch sweepAxis (X|Y|Z|R|Theta') + self.parser.add_option("--ribbonPatchStackAxis", + action="store", + dest="ribbonPatchStackAxis", + default=None, + help='ribbonPatch stackAxis (X|Y|Z|R|Theta') + self.parser.add_option("--ribbonPatchDiscretization", + action="store", + dest="ribbonPatchDiscretization", + default=None, + help='ribbonPatch discretization (masterPatch|slavePatch|bothPatches|uniform|userDefined)') + + self.parser.add_option("--timeDirs", + action="store", + dest="timeDirs", + default=None, + help='time directories for the mixingPlane boundaryfields. Accept expressions like "[0-9]*", "0", etc.') + + self.parser.add_option("--test", + action="store_true", + default=False, + dest="test", + help="Only print the new boundary file") + + def createMixingPlanePatch(self, patch, patchName): + description="""\ +Create a default definition for a mixingPlane patch, and replace +the current definition + """ + print "Replacing definition of patch: ", patchName, ":", patch + newPatch={ + 'type' : "mixingPlane", + 'nFaces' : patch["nFaces"], + 'startFace' : patch["startFace"], + 'shadowPatch' : 'unknown', + 'coordinateSystem' : { + 'name' : 'mixingCS', + 'type' : 'cylindrical', + 'origin' : '(0 0 0)', + 'e1' : '(1 0 0)', + 'e3' : '(0 0 1)' + }, + 'ribbonPatch' : { + 'sweepAxis' : 'Theta', + 'stackAxis' : 'Z', + 'discretization' : 'bothPatches', + } + } + return newPatch + + def modifyMixinPlanePatchDefinition(self, patch, patchName, shadowName): + description="""\ +Modify the definition of a mixingPlane patch + """ + print " Modifying mixingPlane boundary definition in constant/polyMesh/boundary for patch", patchName + + patch["shadowPatch"]=shadowName + + if patch.has_key("coordinateSystem")==False: + patch["coordinateSystem"]={} + + if self.parser.getOptions().coordinateSystemName!=None: + patch["coordinateSystem"]["name"]=self.parser.getOptions().coordinateSystemName + + if self.parser.getOptions().coordinateSystemType!=None: + patch["coordinateSystem"]["type"]=self.parser.getOptions().coordinateSystemType + + if self.parser.getOptions().coordinateSystemOrigin!=None: + patch["coordinateSystem"]["origin"]=self.parser.getOptions().coordinateSystemOrigin + + if self.parser.getOptions().coordinateSystemE1!=None: + patch["coordinateSystem"]["e1"]=self.parser.getOptions().coordinateSystemE1 + + if self.parser.getOptions().coordinateSystemE3!=None: + patch["coordinateSystem"]["e3"]=self.parser.getOptions().coordinateSystemE3 + + if patch.has_key("ribbonPatch")==False: + patch["ribbonPatch"]={} + + if self.parser.getOptions().ribbonPatchSweepAxis!=None: + patch["ribbonPatch"]["sweepAxis"]=self.parser.getOptions().ribbonPatchSweepAxis + + if self.parser.getOptions().ribbonPatchStackAxis!=None: + patch["ribbonPatch"]["stackAxis"]=self.parser.getOptions().ribbonPatchStackAxis + + if self.parser.getOptions().ribbonPatchDiscretization!=None: + patch["ribbonPatch"]["discretization"]=self.parser.getOptions().ribbonPatchDiscretization + + + + def modifyMixinPlanePatchDefinitionInTimeDirs(self, caseDir, patchName, timeDirs): + description="""\ +Modify the definition of a mixingPlane patch in the time directories + """ + regex = fnmatch.translate(timeDirs) + + reobj = re.compile(regex) + + for timeDir in listdir(caseDir): + if reobj.match(timeDir): + print " Modifying mixingPlane boundaryFields in timeDir", timeDir, "for patch", patchName + + td=TimeDirectory(caseDir, timeDir, yieldParsedFiles=True) + + for f in td: + print " Modifying field", f.name + f["boundaryField"][patchName]["type"]='mixingPlane' + f.writeFile() + + def run(self): + fName=self.parser.getArgs()[0] + masterbName=self.parser.getArgs()[1] + shadowbName=self.parser.getArgs()[2] + + boundary=ParsedParameterFile(path.join(".",fName,"constant","polyMesh","boundary"),debug=False,boundaryDict=True,backup=True) + + bnd=boundary.content + + if type(bnd)!=list: + print "Problem with boundary file (not a list)" + sys.exit(-1) + + masterFound=False + shadowFound=False + updateTimeDirs=False + + timeDirs="0" + if self.parser.getOptions().timeDirs!=None: + timeDirs=self.parser.getOptions().timeDirs + updateTimeDirs=True + + print "UpdateTimeDirs: ", updateTimeDirs + + for index in range(len(bnd)): + + indexDefPatch=index+1 + + if bnd[index]==masterbName: + masterFound=True + if bnd[indexDefPatch]["type"]!="mixingPlane": + bnd[indexDefPatch] = self.createMixingPlanePatch(bnd[indexDefPatch], masterbName) + + self.modifyMixinPlanePatchDefinition(bnd[indexDefPatch], masterbName, shadowbName) + + if updateTimeDirs: + self.modifyMixinPlanePatchDefinitionInTimeDirs(fName, masterbName, timeDirs) + + elif bnd[index]==shadowbName: + shadowFound=True + if bnd[indexDefPatch]["type"]!="mixingPlane": + bnd[indexDefPatch] = self.createMixingPlanePatch(bnd[indexDefPatch], shadowbName) + + self.modifyMixinPlanePatchDefinition(bnd[indexDefPatch], shadowbName, masterbName) + + if updateTimeDirs: + self.modifyMixinPlanePatchDefinitionInTimeDirs(fName, shadowbName, timeDirs) + + if masterFound and shadowFound: + break; + + if not masterFound: + self.error("Boundary patch",masterbName,"not found in",bnd[::2]) + + if not shadowFound: + self.error("Boundary patch",shadowbName,"not found in",bnd[::2]) + + if self.parser.getOptions().test: + print boundary + else: + boundary.writeFile() + + + diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamConvertMixingPlaneBoundaryToNewSyntax.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamConvertMixingPlaneBoundaryToNewSyntax.py new file mode 100755 index 000000000..bbad29034 --- /dev/null +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamConvertMixingPlaneBoundaryToNewSyntax.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from PyFoam.Applications.ConvertMixingPlaneBoundaryToNewSyntax import ConvertMixingPlaneBoundaryToNewSyntax + +ConvertMixingPlaneBoundaryToNewSyntax() diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitGgiInterface.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitGgiInterface.py new file mode 100755 index 000000000..29ebd2830 --- /dev/null +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitGgiInterface.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from PyFoam.Applications.InitGgiInterface import InitGgiInterface + +InitGgiInterface() diff --git a/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitMixingPlaneInterface.py b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitMixingPlaneInterface.py new file mode 100755 index 000000000..e822fe16e --- /dev/null +++ b/ThirdParty/LocalDev/Hydro-Quebec/PyFoam/pyFoamInitMixingPlaneInterface.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from PyFoam.Applications.InitMixingPlaneInterface import InitMixingPlaneInterface + +InitMixingPlaneInterface()