Source code for opencmp.config_functions.reference_solutions

########################################################################################################################
# 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 .base_config_functions import ConfigFunctions
import ngsolve as ngs
from ngsolve import Mesh, Parameter, CoefficientFunction, GridFunction, FESpace
from typing import Dict, Union, List


[docs]class RefSolFunctions(ConfigFunctions): """ Class to hold the reference solutions. """ def __init__(self, config_rel_path: str, import_dir: str, mesh: Mesh, t_param: List[Parameter] = [Parameter(0.0)], new_variables: List[Dict[str, Union[float, CoefficientFunction, GridFunction]]] = [{}]) -> None: super().__init__(config_rel_path, import_dir, mesh, t_param) # Load the reference solution dict from the reference solution configfile. try: ref_sols, ref_sols_re_parse = self.config.get_one_level_dict('REFERENCE SOLUTIONS', self.import_dir, mesh, self.t_param, new_variables) except KeyError: # No options specified for L2_error. ref_sols = {} ref_sols_re_parse = {} try: # Note that all of the metrics are time-independent since they are just names of error metrics. metrics, metrics_re_parse = self.config.get_one_level_dict('METRICS', self.import_dir, mesh, new_variables=new_variables, all_str=True) except KeyError: # No options specified for other metrics. metrics = {} metrics_re_parse = {} self.ref_sol_dict = {'ref_sols': ref_sols, 'metrics': metrics} self.ref_sol_re_parse_dict = {'ref_sols': ref_sols_re_parse, 'metrics': metrics_re_parse}
[docs] def set_ref_solution(self, fes: FESpace, model_components: Dict[str, int]): """ Function to load the reference solutions from their configfile into a dictionary, including loading any saved gridfunctions. Args: fes: The finite element space of the model. model_components: Maps between variable names and their component in the finite element space. Returns: Dictionary of reference solutions. """ # Turn 'all' into a separate reference solution for each variable. Assuming that anytime 'all' is used the # reference solution is being loaded in from file since there is no way to parse closed form expressions for # multiple gridfunction components. if 'all' in self.ref_sol_dict['ref_sols'].keys(): val = self.ref_sol_dict['ref_sols'].pop('all') for var in model_components.keys(): self.ref_sol_dict['ref_sols'][var] = val for var, val_lst in self.ref_sol_dict['ref_sols'].items(): for i in range(len(val_lst)): val = val_lst[i] if isinstance(val, str): # Need to load a gridfunction from file. # Check that the file exists. val = self._find_rel_path_for_file(val) component = model_components[var] # Use a component of the finite element space. gfu_val = ngs.GridFunction(fes.components[component]) gfu_val.Load(val) # Replace the value in the ref_sol dictionary. self.ref_sol_dict['ref_sols'][var][i] = gfu_val else: # Already parsed pass return self.ref_sol_dict
[docs] def update_ref_solutions(self, t_param: List[Parameter], updated_variables: List[Dict[str, Union[float, CoefficientFunction, GridFunction]]], mesh: Mesh) \ -> None: """ Function to update the reference solutions with new values of the model_variables. Args: t_param: List of parameters representing the current time and previous time steps. updated_variables: List of dictionaries containing any new model variables and their values at each time step used in the time discretization scheme. mesh: Mesh used by the model """ for k1, v1 in self.ref_sol_re_parse_dict.items(): self.ref_sol_dict[k1] = self.re_parse(self.ref_sol_dict[k1], self.ref_sol_re_parse_dict[k1], t_param, updated_variables, mesh)