Mod: improved file and case usage

Mod: openfoam submodule documentation
This commit is contained in:
L-Nafaryus 2022-01-29 16:44:46 +05:00
parent 33ff54bd3b
commit 12ee8ab0b0
No known key found for this signature in database
GPG Key ID: C76D8DCD2727DBB7
4 changed files with 135 additions and 52 deletions

View File

@ -1,49 +1,85 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os, shutil from __future__ import annotations
import os
import shutil
import re import re
from copy import deepcopy import pathlib
from . import FoamFile from . import FoamFile
class FoamCase(object): class FoamCase(object):
def __init__(self, foamfiles: list = None, path: str = None): def __init__(self, files: FoamFile | list[FoamFile] = None, path: str = None):
self.path = path or os.path.abspath("") self.path = path
self._files = []
if foamfiles: if files is not None:
self.extend(foamfiles) self.add(files)
def __enter__(self): def __repr__(self) -> str:
self.__curpath = os.path.abspath("") content = [ file.object for file in self._files ]
os.chdir(self.path)
return
def __exit__(self, exc_type, exc_val, exc_tb): return "<FoamCase: {}>".format(", ".join(content) or None)
os.chdir(self.__curpath)
self.__curpath = None
def append(self, ff: FoamFile): def add(self, files: FoamFile | list[FoamFile]):
if FoamFile in ff.__class__.mro(): if type(files) is not list:
setattr(self, ff.header["object"], deepcopy(ff)) assert type(files) is FoamFile, "passed object is not a FoamFile"
else: files = [ files ]
raise Exception("Trying to put not a FoamFile to FoamCase.")
def extend(self, foamfiles: list): for file in files:
for ff in foamfiles: assert type(file) is FoamFile, "passed object is not a FoamFile"
self.append(ff) assert file.object is not None, "FoamFile object attribute is None"
def write(self): for n, _file in enumerate(self._files):
for value in self.__dict__.values(): if _file.object == file.object:
if FoamFile in value.__class__.mro(): self._files.pop(n)
value.write(self.path) self._files.append(file)
def read(self): return self
for value in self.__dict__.values():
if FoamFile in value.__class__.mro(): self._files.append(file)
value.read()
return self
def __add__(self, files: FoamFile | list[FoamFile]):
return self.add(files)
def write(self, path: str = None):
path = pathlib.Path(path or self.path or "")
for file in self._files:
path /= (
file.location + "/" + file.object
if file.location else file.object
)
file.write(path.resolve())
def read(self, path: str = None):
path = pathlib.Path(path or self.path or "")
for file in self._files:
path /= (
file.location + "/" + file.object
if file.location else file.object
)
file.read(path.resolve())
def remove(self, path: str = None):
path = pathlib.Path(path or self.path or "")
for file in self._files:
path /= (
file.location + "/" + file.object
if file.location else file.object
)
file.remove(path.resolve())
def clean(self, included: list = ["0", "constant", "system"]): def clean(self, included: list = ["0", "constant", "system"]):
regxs = [ regxs = [
@ -72,5 +108,3 @@ class FoamCase(object):
if os.path.isfile(file): if os.path.isfile(file):
os.remove(file) os.remove(file)

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from typing import List from . import FoamRunner
from .runner import FoamRunner
### ###
# meshConversion # meshConversion
@ -186,6 +186,7 @@ def simpleFoam(parallel: bool = False, run: bool = True, **kwargs) -> FoamRunner
return runner return runner
### ###
# postProcessing # postProcessing
## ##

View File

@ -8,15 +8,18 @@ from . import conversion
class FoamFile(object): class FoamFile(object):
def __init__( def __init__(
self, self,
filename: str = None,
_version: float = 2.0, _version: float = 2.0,
_format: str = "ascii", _format: str = "ascii",
_class: str = "dictionary", _class: str = "dictionary",
_object: str = None, _object: str = None,
_location: str = None, _location: str = None
filename: str = None
): ):
"""A FoamFile object. """A FoamFile object.
:param filename:
Can be used as shortcut to set _location and _object,
_location and _object parameters will be ignored.
:param _version: :param _version:
Version of the file format, current is 2.0. Version of the file format, current is 2.0.
:param _format: :param _format:
@ -29,9 +32,6 @@ class FoamFile(object):
:param _location: :param _location:
Path to the parent directory of the file according Path to the parent directory of the file according
to the case root. to the case root.
:param filename:
Can be used as shortcut to set _location and _object,
_location and _object parameters will be ignored.
""" """
if filename: if filename:
@ -50,6 +50,26 @@ class FoamFile(object):
if _location: if _location:
self.header["location"] = f'"{ _location }"' self.header["location"] = f'"{ _location }"'
@property
def version(self) -> str:
return self.header.get("version")
@property
def format(self) -> str:
return self.header.get("format")
@property
def class_(self) -> str:
return self.header.get("class")
@property
def object(self) -> str:
return self.header.get("object")
@property
def location(self) -> str:
return self.header.get("location")
def __getitem__(self, key): def __getitem__(self, key):
return self.content[key] return self.content[key]
@ -72,16 +92,27 @@ class FoamFile(object):
def __repr__(self) -> str: def __repr__(self) -> str:
return "<FoamFile: {}>".format(self.header["object"] or None) return "<FoamFile: {}>".format(self.header["object"] or None)
def __add__(self, file):
from . import FoamCase
assert type(file) is FoamFile
return FoamCase([ self, file ])
def read(self, filename: str = None): def read(self, filename: str = None):
"""Read a FoamFile. """Read a FoamFile.
:param filename: :param filename:
Path to the file. If None, use location from header with Path to the file. If None, use location and object from header with
current working directory. the current working directory.
:return: :return:
Self. Self.
""" """
path = pathlib.Path(filename or self.header["location"]).resolve() filename = (
filename or self.location + "/" + self.object
if self.location else self.object
)
path = pathlib.Path(filename).resolve()
header, content = conversion.read_foamfile(path) header, content = conversion.read_foamfile(path)
self.header = header self.header = header
@ -97,8 +128,28 @@ class FoamFile(object):
"""Write a FoamFile to the file. """Write a FoamFile to the file.
:param filename: :param filename:
Path to the file. If None, use location from header with Path to the file. If None, use location and object from header with
current working directory.. the current working directory.
""" """
filename = pathlib.Path(filename or self.header["location"]).resolve() filename = (
conversion.write_foamfile(self.header, self.content, filename) filename or self.location + "/" + self.object
if self.location else self.object
)
path = pathlib.Path(filename).resolve()
conversion.write_foamfile(self.header, self.content, path)
def remove(self, filename: str = None):
"""Remove a FoamFile.
:param filename:
Path to the file. If None, use location and object from header with
the current working directory.
"""
filename = (
filename or self.location + "/" + self.object
if self.location else self.object
)
path = pathlib.Path(filename).resolve()
if path.exists():
pathlib.os.remove(filename)

View File

@ -2,14 +2,13 @@
import os import os
import subprocess import subprocess
import sys
from typing import List
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class FoamRunner(object): class FoamRunner(object):
def __init__(self, command: str, args: List[str] = None, mpi: bool = False, cwd: str = None, logpath: str = None, exit: bool = False): def __init__(self, command: str, args: list[str] = None, mpi: bool = False, cwd: str = None, logpath: str = None, exit: bool = False):
self.command = command self.command = command
self.args = args self.args = args
self.mpi = mpi self.mpi = mpi
@ -20,7 +19,7 @@ class FoamRunner(object):
self.error = "" self.error = ""
self.returncode = 0 self.returncode = 0
def fullcommand(self) -> List[str]: def fullcommand(self) -> list[str]:
command = [] command = []
if self.mpi: if self.mpi:
@ -49,8 +48,6 @@ class FoamRunner(object):
if self.logpath: if self.logpath:
with proc, open(self.logpath, "w") as io: with proc, open(self.logpath, "w") as io:
while True: while True:
output = proc.stdout.read(1) output = proc.stdout.read(1)
if output == "" and proc.poll() is not None: if output == "" and proc.poll() is not None: