Source code for casefoam.loadData

import os
import pandas as pd


[docs]def getCases(solutionDir, caseStructure, baseCase, postDir='postProcessing'): """Get cases. Get cases out of the ``caseStructure`` that contain a solution directory. Parameters ---------- solutionDir : str Solution directory in the OpenFOAM case ``postProcessing`` directory. caseStructure : list List of parent, child and grandchild names. baseCase : str Root directory of all cases. Returns ------- cases : list List with relative path to all cases containg a ``surfaces`` directory. caseCombs : list A list with all case combinations as tuples. """ if(caseStructure is None): return [os.path.join(baseCase, postDir, solutionDir)], [(baseCase,)] multiIndex = pd.MultiIndex.from_product(caseStructure) allCaseCombs = multiIndex.values cases = list() caseCombs = list() try: for caseComb in allCaseCombs: _len = len(caseComb) _path = baseCase for i in range(_len): _path = os.path.join(_path, caseComb[i]) _path = os.path.join(_path, postDir, solutionDir) if os.path.isdir(_path): cases.append(_path) caseCombs.append(caseComb) except AttributeError: # handle caseStructures with only one level for caseComb in allCaseCombs: _path = os.path.join(baseCase, caseComb, postDir, solutionDir) if os.path.isdir(_path): cases.append(_path) caseCombs.append((caseComb,)) # write as tuple return cases.copy(), caseCombs.copy()
def __get_timeSeries(solutionFile, columnNames=None): """Load timeSeries data. Load a timeSeries Parameters ---------- solutionFile : str Path to the solution file. columnNames : list, optional List of forces. Returns ------- pandas.DataFrame If a list of columnNames is given, the output will have the ``columnNames`` as columns. If no columnNames are given the columns will be ``[1, 2, ..., n]``. """ _outputDf = pd.read_csv(solutionFile, comment='#', sep='[() \t]+', engine='python', header=None) # drop last column as it terminates with if(pd.isnull(_outputDf.iloc[0, -1])): _outputDf.drop(_outputDf.columns[[-1, ]], axis=1, inplace=True) _outputDf.set_index(0, inplace=True) if(columnNames is not None): _outputDf.columns = columnNames return _outputDf def __get_posField(solutionFile): """Load pos data. Load a posSeries Parameters ---------- solutionFile : str Path to the solution file Returns ------- pandas.DataFrame """ try: suffix = os.path.splitext(solutionFile)[1] if suffix in ('.xy', '.raw'): return pd.read_csv(solutionFile, comment='#', delim_whitespace=True, header=None) elif suffix == '.csv': return pd.read_csv(solutionFile) else: raise Exception( 'File Format : ', suffix, ' is not supported only xy ', 'raw csv. Please change the setFormat or', 'surfaceFormat in the ``controlDict`` to ``csv`` or ``raw``' ) except FileNotFoundError: return None
[docs]def time_series(solutionDir, file, caseStructure=None, baseCase='.', columnNames=None): """Load timeSeries(e.g probes, forces etc) Loads a timeseries of a given case and save them into one pandas.DataFrame. multiple cases can be combined with the caseStructure argument Parameters ---------- solutionDir : str Solution directory in the OpenFOAM case ``postProcessing`` directory. file : str File name of the solution file. caseStructure : list, optional List of parent, child and grandchild names:: [[parent1, parent2], [child1, child2, child3], [grandchild1, grandchild2]] baseCase : str, optional Root directory of all cases. columnNames : list, optional List of columnNames. Returns ------- outputDf : pandas.DataFrame pandas.DataFrame with solutions for all times. """ outputDf = pd.DataFrame() cases, caseCombs = getCases(solutionDir, caseStructure, baseCase) for i, caseComb in enumerate(caseCombs): currentSolutionFile = os.path.join(cases[i], file) if os.path.exists(currentSolutionFile): try: currentDataFrame = __get_timeSeries(currentSolutionFile, columnNames) except pd.errors.EmptyDataError: print('Note: {} was empty. Skipping.'.format(currentSolutionFile)) continue counter = 0 for variables in caseComb: currentDataFrame['var_' + str(counter)] = variables counter += 1 currentDataFrame.index.name = 't' outputDf = outputDf.append(currentDataFrame) del currentDataFrame return outputDf
[docs]def positional_field(solutionDir, file, time, caseStructure=None, baseCase='.'): """Load positionalField(surfaces and sets). Loads a positionalField of a given case and save them into one pandas.DataFrame. multiple cases can be combined with the caseStructure argument Parameters ---------- solutionDir : str Solution directory in the OpenFOAM case ``postProcessing`` directory. file : str File name of the solution file. time : float Point of time at which to load the field. caseStructure : list, optional List of parent, child and grandchild names:: [[parent1, parent2], [child1, child2, child3], [grandchild1, grandchild2]] baseCase : str, optional Root directory of all cases. Returns ------- outputDf : pandas.DataFrame pandas.DataFrame with solutions for all times. """ outputDf = pd.DataFrame() cases, caseCombs = getCases(solutionDir, caseStructure, baseCase) for i, caseComb in enumerate(caseCombs): currentSolutionFile = os.path.join(cases[i], str(time), file) if os.path.exists(currentSolutionFile): try: currentDataFrame = __get_posField(currentSolutionFile) except pd.errors.EmptyDataError: print('Note: {} was empty. Skipping.'.format(currentSolutionFile)) continue counter = 0 for variables in caseComb: currentDataFrame['var_' + str(counter)] = variables counter += 1 outputDf = outputDf.append(currentDataFrame) del currentDataFrame return outputDf
[docs]def posField_to_timeSeries(solutionDir, file, postFunction, caseStructure=None, baseCase='.', **kwargs): """Converts multiple posionalFields to timeSeries with a function Load all postional Fields of a given case, manipulate the data for each time step and save the manipulated results into one pandas.DataFrame for all times. Parameters ---------- solutionDir : str Solution directory in the OpenFOAM case ``postProcessing`` directory. file : str File name of the solution file. postFunction : function User function to manipulate the solution data ``['x', 'y', 'z', 'values', ...]``. The function must return output DataFrame should has and has to have the parameters ``(caseComb, time, currentDataFrame)`` caseStructure : list, optional List of parent, child and grandchild names:: [[parent1, parent2], [child1, child2, child3], [grandchild1, grandchild2]] baseCase : str, optional Root directory of all cases. **kwargs Keyword arguments if needed by ``postFunction``. Returns ------- outputDf : pandas.DataFrame pandas.DataFrame with solutions for all times. Examples -------- Define a user ``postFunction``. >>> def userFunction(caseComb, time, currentDataFrame): t = time minimum = currentDataFrame.iloc[:, 1].min() mean = currentDataFrame.iloc[:, 1].mean() maximum = currentDataFrame.iloc[:, 1].max() df = pd.DataFrame(np.array([time, minimum, mean, maximum], ndmin=2), columns=['time', 'min', 'mean', 'max']) df = df.set_index('time') return df """ outputDf = pd.DataFrame() cases, caseCombs = getCases(solutionDir, caseStructure, baseCase) for i, caseComb in enumerate(caseCombs): times = os.listdir(cases[i]) for time in times: currentSolutionFile = os.path.join(cases[i], time, file) try: surfaceDataFrame = __get_posField(currentSolutionFile) except pd.errors.EmptyDataError: print('Note: {} was empty. Skipping.'.format(currentSolutionFile)) continue funcDataFrame = postFunction( caseComb, float(time), surfaceDataFrame, **kwargs) counter = 0 for variables in caseComb: funcDataFrame['var_' + str(counter)] = variables counter += 1 outputDf = outputDf.append(funcDataFrame) del surfaceDataFrame return outputDf