-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated butterfly libraries and a half-broken prototype
- Updated butterfly libraries. Added files for blockMehDict and BFSurface - Created a prototype for an interior case with the help of @TheodoreGalanos. 💯 OpenFOAM gives an error for face area which is probably because of the order of the points. Fortunately I have a working example that I can use to debug the code. Next steps is to add snappyHexMeshDict and then default system folder for boundary condition.
- Loading branch information
1 parent
a507c06
commit c5d2cb3
Showing
62 changed files
with
1,939,325 additions
and
386 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
__all__ = ["core", "fields", "foamfile", "solvers", "version", "stl"] | ||
__all__ = ["core", "fields", "foamfile", "solvers", "version", "gh"] | ||
|
||
import core, fields, foamfile, solvers, version, stl | ||
import core, fields, foamfile, solvers, version, gh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
"BlockMeshDict class." | ||
from foamfile import FoamFile | ||
import os | ||
|
||
class BlockMeshDict(FoamFile): | ||
|
||
def __init__(self, scale, BFSurfaces, blocks): | ||
FoamFile.__init__(self, name='blockMeshDict', cls='dictionary') | ||
self.scale = scale | ||
self.blocks = blocks | ||
# collect uniqe vertices from all BFSurfaces | ||
self.vertices = tuple(set(v for f in BFSurfaces for vgroup in f.borderVertices for v in vgroup)) | ||
self.BFSurfaces = BFSurfaces | ||
|
||
def toOpenFoam(self): | ||
_hea = self.header() | ||
_body = "\nconvertToMeters 1;\n" \ | ||
"\n" \ | ||
"vertices\n" \ | ||
"(\n%s\n);\n" \ | ||
"\n" \ | ||
"blocks\n" \ | ||
"(\n%s\n);\n" \ | ||
"\n" \ | ||
"edges\n" \ | ||
"(%s);\n" \ | ||
"\n" \ | ||
"boundary\n" \ | ||
"(%s);\n" \ | ||
"\n" \ | ||
"mergePatchPair\n" \ | ||
"(%s);\n" | ||
|
||
return _hea + \ | ||
_body % ( | ||
"\n".join(tuple(str(ver).replace(",", "") | ||
for ver in self.vertices)), | ||
"\n".join(block.blockMeshDict(self.vertices) | ||
for block in self.blocks), #blocks | ||
"\n", # edges | ||
"\n".join(srf.blockMeshDict(self.vertices) | ||
for srf in self.BFSurfaces), | ||
"\n" # merge patch pair | ||
) | ||
|
||
def save(self, folder): | ||
with open(os.path.join(folder, "blockMeshDict"), "wb") as outf: | ||
outf.write(self.toOpenFoam()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,92 @@ | ||
"""Butterfly core library.""" | ||
import os | ||
import solvers | ||
from fields import BoundaryField as bouf | ||
from blockMeshDict import BlockMeshDict | ||
|
||
class BFProject: | ||
|
||
def __init__(self, projectName): | ||
self.projectName = projectName | ||
class Case(object): | ||
"""Butterfly case.""" | ||
def __init__(self, BFSurfaces, blockMeshDict, snappyHexMesh=False): | ||
"""Init project.""" | ||
self.username = os.getenv("USERNAME") | ||
self.__solvers = [] | ||
|
||
def createProject(self): | ||
"""Create project folders and write input files | ||
self.BFSurfaces = BFSurfaces | ||
self.blockMeshDict = blockMeshDict | ||
self.snappyHexMesh = snappyHexMesh | ||
|
||
workingDir for Butterfly files will be under | ||
"users/username/butterfy/" | ||
@classmethod | ||
def fromBlocks(cls, BFSurfaces, blocks, scale): | ||
"""Create case from BFSurfaces and blocks. | ||
OpenFOAM for windows uses users/username folder to share data | ||
projectDir will be set to: | ||
"users/username/butterfy/projectName/" | ||
This case will only be meshed using blockMesh | ||
""" | ||
_blockMeshDict = BlockMeshDict(scale, BFSurfaces, blocks) | ||
return cls(BFSurfaces, _blockMeshDict, snappyHexMesh=False) | ||
|
||
def write(self, projectName, workingDir=None): | ||
"""Create project folders and write input files. | ||
Args: | ||
projectName: A valid name for project. Avoid whitespace and special | ||
charecters. | ||
workingDir: By default workingDir for Butterfly files will be under | ||
"users/<username>/butterfy/". Do not change the folder unless you | ||
need to save the files in a different folder. OpenFOAM for windows | ||
uses "users/<username>" folder to share data. | ||
""" | ||
self.projectName = projectName | ||
self.workingDir = "c:/users/%s/butterfly/" % self.username if not workingDir \ | ||
else workingDir | ||
self.projectDir = os.path.join(self.workingDir, self.projectName) | ||
|
||
# This method will be only useful on new systems | ||
self.__createWorkingDir() | ||
self.__createCaseFolder() | ||
# Create sub folders (0, constant, system) | ||
self.__createSubFolders() | ||
|
||
# Create porject folders (0, constant, system) | ||
self.__createProjectDir() | ||
print "Files are exported to:\n%s" % os.path.normpath(self.projectDir) | ||
|
||
def __createWorkingDir(self): | ||
baseDir = "c:/users/%s/butterfly/"%self.username | ||
self.workingDir = self.__createDir(baseDir) | ||
|
||
def __createProjectDir(self): | ||
projectDir = self.workingDir + self.projectName + "/" | ||
self.projectDir = self.__createDir(projectDir) | ||
self.__createSubFolders() | ||
def __createCaseFolder(self): | ||
self.__createDir(self.workingDir) | ||
|
||
def __createSubFolders(self): | ||
# create zero directory | ||
zeroDir = self.projectDir + "0/" | ||
self.zeroDir = self.__createDir(zeroDir) | ||
self.__writeFilesInZeroDir() | ||
|
||
# create constant directory | ||
constantDir = self.projectDir + "constant/" | ||
constantDir = os.path.join(self.projectDir, "constant") | ||
self.constantDir = self.__createDir(constantDir) | ||
# create polyMesh folder under contstant | ||
self.__createDir(os.path.join(self.constantDir, "polyMesh")) | ||
|
||
# create system directory | ||
systemDir = self.projectDir + "system/" | ||
self.systemDir = self.__createDir(systemDir) | ||
if self.snappyHexMesh: | ||
self.__createDir(os.path.join(self.constantDir, "triSurface")) | ||
|
||
def __writeFilesInZeroDir(self): | ||
for solver in self.__solvers: | ||
solver.writeToFile(self.zeroDir) | ||
self.__writeConstantFiles() | ||
|
||
# TODO: write files inside the folder | ||
def createConstantDir(self): | ||
pass | ||
# create system directory | ||
systemDir = os.path.join(self.projectDir, "system") | ||
self.systemDir = self.__createDir(systemDir) | ||
|
||
# TODO: write files inside the folder | ||
def createSystemDir(self): | ||
pass | ||
# create time directory | ||
timestepDir = os.path.join(self.projectDir, "0") | ||
self.timestepDir = self.__createDir(timestepDir) | ||
# TODO: write velocity and pressure boundary condition | ||
# self.__writeFilesInZeroDir() | ||
|
||
def __writeConstantFiles(self): | ||
"""write files in constant folder.""" | ||
# write blockMeshDict to polyMesh | ||
self.blockMeshDict.save(os.path.join(self.constantDir, "polyMesh")) | ||
# write stl files to triSurface | ||
# for surface in self | ||
if self.snappyHexMesh: | ||
for BFSurface in self.BFSurfaces: | ||
BFSurface.writeToStl(os.path.join(self.constantDir, "triSurface")) | ||
|
||
@staticmethod | ||
def __createDir(directory, overwrite = True): | ||
def __createDir(directory, overwrite=True): | ||
if not os.path.isdir(directory): | ||
try: | ||
os.mkdir(directory) | ||
except: | ||
raise Exception("Failed to create %s"%directory) | ||
else: | ||
# TODO add one more step to ask for user permission | ||
print "%s already existed! Files will be overwritten"%directory | ||
|
||
except Exception as e: | ||
raise ValueError("Failed to create %s:\n%s" % (directory, e)) | ||
# TODO add one more step to ask for user permission | ||
# print "%s already existed! Files will be overwritten." % directory | ||
return directory | ||
|
||
# TODO: Check the solver to be valid | ||
def add_solver(self, newSolver): | ||
"""Add solver to the list of solvers""" | ||
solverNames = [solver.FoamFile.object for solver in self.__solvers] | ||
|
||
if newSolver.FoamFile.object not in solverNames: | ||
self.__solvers.append(newSolver) | ||
else: | ||
raise ValueError("%s already exist in project."%newSolver.FoamFile.object + \ | ||
"\nUse Project.get_solverByName and update the solver") | ||
|
||
def get_solverByName(self, name): | ||
"""Return solver by name""" | ||
try: | ||
return [solver for solver in self.__solvers if solver.FoamFile.object == name][0] | ||
except: | ||
raise Exception("%s is not a solver in this project.\n"%name + \ | ||
"You can create additional solvers and add them to project using Project.addSolver") | ||
|
||
@property | ||
def solvers(self): | ||
names = [solver.FoamFile.object for solver in self.__solvers] | ||
return ", ".join(names) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,50 @@ | ||
#Foam File Class | ||
from version import Version | ||
from version import Version, Header | ||
|
||
class FoamFile: | ||
"""FoamFile setting | ||
class FoamFile(object): | ||
"""FoamFile base class. | ||
Read (http://cfd.direct/openfoam/user-guide/basic-file-format/) for | ||
more information about FoamFile | ||
Read (http://cfd.direct/openfoam/user-guide/basic-file-format/) for | ||
more information about FoamFile | ||
Attributes: | ||
name : Filename (e.g. controlDict) | ||
OFClass : OpenFOAM class constructed from the data file | ||
concerned. Typically dictionary or a field, e.g. volVectorField | ||
location : Path to the file (0, constant or system) | ||
fileFormat : File format (ascii / binary) (default: ascii) | ||
Attributes: | ||
name: Filename (e.g. controlDict) | ||
OFClass: OpenFOAM class constructed from the data file | ||
concerned. Typically dictionary or a field, e.g. volVectorField | ||
location: Folder name (0, constant or system) | ||
fileFormat: File format (ascii / binary) (default: ascii) | ||
Usage: | ||
ff = FoamFile("k", "volScalarField", "0") | ||
print ff.get_OFString() | ||
""" | ||
|
||
# TODO: Add set and get methods | ||
def __init__(self, name, OFClass, location = None, fileFormat = "ascii"): | ||
Usage: | ||
ff = FoamFile("k", "volScalarField", "0") | ||
print ff.header() | ||
""" | ||
def __init__(self, name, cls, location=None, fileFormat="ascii"): | ||
self.__version = str(Version.OFVer()) | ||
self.format = str(fileFormat) # ascii / binary | ||
self.OFClass = str(OFClass) #dictionary or field | ||
self.cls = str(cls) # dictionary or field | ||
self.object = str(name) | ||
self.location = str(location) #location is optional | ||
self.location = location #location is optional | ||
if self.location == "0": | ||
self.location = '"' + self.location + '"' | ||
|
||
def get_OFString(self): | ||
def header(self): | ||
"""Return open foam style string""" | ||
if self.location: | ||
return "FoamFile\n{\n" + \ | ||
"\tversion\t\t%s;\n"%self.__version + \ | ||
"\tformat\t\t%s;\n"%self.format + \ | ||
"\tclass\t\t%s;\n"%self.OFClass + \ | ||
"\tlocation\t%s;\n"%self.location + \ | ||
"\tobject\t\t%s;\n"%self.object + \ | ||
"}\n" | ||
return Header.header() + \ | ||
"FoamFile\n{\n" \ | ||
"\tversion\t\t%s;\n" \ | ||
"\tformat\t\t%s;\n" \ | ||
"\tclass\t\t%s;\n" \ | ||
"\tlocation\t%s;\n" \ | ||
"\tobject\t\t%s;\n" \ | ||
"}\n" % (self.__version, self.format, self.cls, self.location, | ||
self.object) | ||
|
||
else: | ||
return "FoamFile\n{\n" + \ | ||
"\tversion\t\t%s;\n"%self.__version + \ | ||
"\tformat\t\t%s;\n"%self.format + \ | ||
"\tclass\t\t%s;\n"%self.OFClass + \ | ||
"\tobject\t\t%s;\n"%self.object + \ | ||
"}\n" | ||
return Header.header() + \ | ||
"FoamFile\n{\n" \ | ||
"\tversion\t\t%s;\n" \ | ||
"\tformat\t\t%s;\n" \ | ||
"\tclass\t\t%s;\n" \ | ||
"\tobject\t\t%s;\n" \ | ||
"}\n" % (self.__version, self.format, self.cls, self.object) |
Oops, something went wrong.