Source code for opencmp.config_functions.load_config

########################################################################################################################
# Copyright 2021 the authors (see AUTHORS file for full list).                                                         #
#                                                                                                                      #
# This file is part of OpenCMP.                                                                                        #
#                                                                                                                      #
# OpenCMP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public  #
# License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any     #
# later version.                                                                                                       #
#                                                                                                                      #
# OpenCMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied        #
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more  #
# details.                                                                                                             #
#                                                                                                                      #
# You should have received a copy of the GNU Lesser General Public License along with OpenCMP. If not, see             #
# <https://www.gnu.org/licenses/>.                                                                                     #
########################################################################################################################

from ngsolve import Mesh, Parameter, CoefficientFunction, GridFunction
from typing import List, Optional, Dict, Tuple, Union, Any, Callable
from . import parse_arithmetic


[docs]def parse_str(string: str, import_dir: str, t_param: Optional[List[Parameter]], new_variables: List[Dict[str, Union[int, str, float, CoefficientFunction, GridFunction]]] = [{}], filetypes: List[str] = ['.vol', '.sol', '.vtk'], mesh: Optional[Mesh] = None) \ -> Tuple[Union[str, float, CoefficientFunction, list], Union[str, bool, Callable]]: """ Checks if a string appears to be a path to a file and if not parses the string into Python code. Args: string: The string. import_dir: The path to the main run directory containing the file from which to import any Python functions. t_param: List of parameters representing the current time and previous time steps. If None, the parsed values have no possible time dependence and one single value is returned instead of a list of values corresponding to the parsed value at each time step. new_variables: List of dictionaries containing any new model variables and their values at each time step used in the time discretization scheme. filetypes: List of possible filetypes to consider. mesh: Mesh used by the model. Returns: Tuple[List[Union[str, float, CoefficientFunction]], Union[str, bool]]: - parsed_str: List containing the value of the parsed string at every time, or just the single value of the parsed string if it has no possible time dependence. - variable_eval: Whether or not the expression contains any of the new model variables (would need to be re-parsed if their values change). """ if not isinstance(string, str): # Likely got a default value from config_defaults. if t_param is None: return string, False else: return [string] * len(t_param), False for item in filetypes: if string.endswith(item): # Filename, don't try to parse. if t_param is None: return string, False else: return [string] * len(t_param), False # Otherwise parse into Python code. # This needs to be done separately for each time step so the value of the parsed string includes the correct time at # each time step. However, variable_eval will remain the same for each time step since it has nothing to do with the # time value. if t_param is None: parsed_str, variable_eval = parse_arithmetic.eval_python(string, import_dir, mesh, new_variables, t_param, None) else: parsed_str = [] for i in range(len(t_param)): tmp_parsed_str, variable_eval = parse_arithmetic.eval_python(string, import_dir, mesh, new_variables, t_param, i) parsed_str.append(tmp_parsed_str) return parsed_str, variable_eval
[docs]def convert_str_to_dict(string: str, import_dir: str, t_param: Optional[List[Parameter]], mesh: Mesh, new_variables: List[Dict[str, Union[int, str, float, CoefficientFunction, GridFunction]]] = [{}], filetypes: List[str] = ['.vol', '.sol', '.vtk'], all_str: bool = False) -> Tuple[Dict, Dict]: """ Function to convert a string into a dict. The values of the dict may be parsed into Python code or left as strings. Args: string: The string. import_dir: The path to the main run directory containing the file from which to import any Python functions. t_param: List of parameters representing the current time and previous time steps. If None, the parsed values have no possible time dependence and one single value is returned instead of a list of values corresponding to the parsed value at each time step. mesh: Mesh used for the model new_variables: List of dictionaries containing any new model variables and their values at each time step used in the time discretization scheme. filetypes: List of possible filetypes to consider. all_str: If True, don't bother parsing any values, just load them as strings. Returns: Tuple[Dict, Dict]: - param_dict: Dictionary of the parameters from the string. - re_parse_dict: Dictionary containing only parameter values that may need to be re-parsed in the future. """ # Replace extraneous whitespace characters. param_tmp = string.replace('\t', '') param_tmp = param_tmp.replace(' ', '') # If param_tmp contains multiple values, split them out into a list if '\n' in param_tmp: param_tmp_lst = param_tmp.split('\n') # Remove any empty strings resulting from extraneous newlines. param_tmp_lst = [item for item in param_tmp_lst if item != ''] else: param_tmp_lst = [param_tmp] # Split by the delimiting character and stick the results in a dictionary. param_dict = {} re_parse_dict = {} val: Union[List[Any], Any] # Just for type-hinting. variable_eval: Union[str, bool, Callable] # Just for type-hinting. for item in param_tmp_lst: key, val_tmp = item.split('->') if all_str: # Don't bother parsing if the values should all be kept as strings. if t_param is None: val = val_tmp else: val = [val_tmp] * len(t_param) variable_eval = False else: val, variable_eval = parse_str(val_tmp, import_dir, t_param, new_variables, filetypes, mesh) param_dict[key] = val # If variable_eval is a string expression or imported Python function add it to re_parse_dict in case the # expression needs to be re-parsed with new variable values in the future. if isinstance(variable_eval, str) or callable(variable_eval): re_parse_dict[key] = variable_eval return param_dict, re_parse_dict
[docs]def load_coefficientfunction_into_gridfunction(gfu: GridFunction, coef_dict: Dict[Optional[int], CoefficientFunction]) \ -> None: """ Function to load a coefficientfunction(s) into a gridfunction. The coefficientfunction(s) may have a different dimension than the gridfunction and need to be loaded into a specific component of it. Args: coef_dict: Dictionary containing the coefficientfunction(s) and which component they belong to (keys). gfu: The gridfunction to load the values into. """ for key, val in coef_dict.items(): if key is None: # Confirm that coef_dict only has one value, otherwise the gfu values will be overwritten multiple times assert len(coef_dict) == 1 gfu.Set(val) else: gfu.components[key].Set(val)