Source code for libICEpost.src.base.Functions.functionsForOF

#####################################################################
#                                  DOC                              #
#####################################################################

"""
@author: F. Ramognino       <federico.ramognino@polimi.it>
Last update:        12/06/2023

Functions used to handle OpenFOAM files
"""

#####################################################################
#                               IMPORT                              #
#####################################################################

#Type checking
from libICEpost.src.base.Functions.typeChecking import checkType

import struct
import os
from typing import Iterable

# Import functions to read OF files:
try:
    from PyFoam.RunDictionary.ParsedParameterFile import ParsedFileHeader,ParsedParameterFile
    from PyFoam.Basics.DataStructures import BinaryList
except Exception as e:
    if not isinstance(e, ImportError):
        print("Error importing PyFoam. This might be an issue related to the PyFoam installation. Try performing the patching procedure running 'libICEpost-applyPatches' script.") 
    raise e
#############################################################################
#                               MAIN FUNCTIONS                              #
#############################################################################
#Read a OpenFOAM file with a scalar list:
[docs] def readOFscalarList(fileName:str) -> Iterable[float]: """ Reads an OpenFOAM file storing a scalarList. Automatically detects if the file is binary or not. Args: fileName (str): Name of the OpenFOAM file. Raises: IOError: If the file does not exist or if it does not store a scalarList Returns: Iterable[float]: The data stored in the file. """ #Argument checking: checkType(fileName, str, entryName="fileName") #Check path: import os if not(os.path.isfile(fileName)): raise IOError("File '{}' not found.".format(fileName)) #Check header: header = ParsedFileHeader(fileName).header if not(header["class"] == "scalarList"): raise IOError("File '{}' does not store a scalarList, instead '{}' was found.".format(fileName, header["class"])) binary = False if header["format"] == "binary": binary = True #Load table: File = ParsedParameterFile(fileName, listDictWithHeader=True, binaryMode=binary) tab = File.content #Load data: if isinstance(tab, BinaryList): numel = tab.length import struct with open(fileName, "rb") as f: while True: ch = f.read(1) if ch == b'(': break data = f.read(8*tab.length) return list(struct.unpack("d" * numel, data)) else: return tab
############################################################################# #Write OF file with scalar list
[docs] def writeOFscalarList(values:Iterable[float], path:str, *, overwrite:bool=False, binary:bool=False) -> None: """ Write an OpenFOAM file storing a scalarList. Args: values (Iterable[float]): The data to store. path (str): The location where to file the scalarList. overwrite (bool, optional): Overwrite if found? Defaults to False. binary (bool, optional): Write in binary? Defaults to False. Raises: IOError: If the file exists and overwrite is False. """ #Argument checking: checkType(values, Iterable, entryName="values") [checkType(val, float, entryName=f"values[{ii}]")for ii,val in enumerate(values)] checkType(overwrite, bool, entryName="overwrite") checkType(binary, bool, entryName="binary") checkType(path, str, entryName="path") #Check path: if os.path.isfile(path) and not overwrite: raise IOError("File '{}' exists. Run with overwrite=True.".format(path)) #Create the file object File = ParsedParameterFile(path, noBody=True, binaryMode=True, dontRead=True, createZipped=False) #Header path = os.path.abspath(path) root, file = os.path.split(path) File.header = \ { "class":"scalarList", "version":2.0, "object":file, "location":os.path.split(root)[1], "format": "binary" if binary else "ascii" } #Empty at first File.writeFile(content={}) #Data with open(path, "ba") as file: file.write(f"{len(values)}".encode()) file.write(f"\n(".encode()) from array import array if binary: with open(path, "a+b") as file: file.write(struct.pack('d' * len(values), *tuple([float(v) for v in values]))) else: with open(path, "a") as file: file.write(" ".join([str(v) for v in values])) with open(path, "ba") as file: file.write(f")\n\n".encode())