Source code for opencmp.solvers.stationary

########################################################################################################################
# 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/>.                                                                                     #
########################################################################################################################

import ngsolve as ngs
from ngsolve import Parameter, Preconditioner
from typing import List, Optional
from .base_solver import Solver
from typing import Tuple

"""
Module for the stationary solver class.
"""


[docs]class StationarySolver(Solver): """ Stationary solver. """ def _apply_boundary_conditions(self) -> None: self.model.apply_dirichlet_bcs_to(self.gfu) def _assemble(self) -> None: for i in range(len(self.a)): self.a[i].Assemble() self.L[i].Assemble() self._update_preconditioners() def _create_linear_and_bilinear_forms(self) -> None: U, V = self.model.get_trial_and_test_functions() # Bilinear form self.a = [] a_coeff_terms = self.model.construct_bilinear_time_coefficient(U, V, Parameter(1.0), 0) a_ode_terms = self.model.construct_bilinear_time_ODE(U, V) for i in range(self.model.num_weak_forms): a = ngs.BilinearForm(self.model.fes) a += a_coeff_terms[i] a += a_ode_terms[i] self.a.append(a) # Linear form # NOTE: No IMEX terms since IMEX should only be used with transient solves. self.L = [] L_terms = self.model.construct_linear(V, None, Parameter(1.0), 0) for i in range(self.model.num_weak_forms): L = ngs.LinearForm(self.model.fes) L += L_terms[i] self.L.append(L) def _create_preconditioners(self) -> None: self.preconditioners = self.model.construct_preconditioners(self.a) def _update_preconditioners(self, precond_lst: List[Optional[Preconditioner]] = None) -> None: for preconditioner in self.preconditioners: if preconditioner is not None: preconditioner.Update() def _load_and_apply_initial_conditions(self) -> None: self.gfu_0_list: List[ngs.GridFunction] = [self.model.construct_gfu()] def _log_timestep(self, accepted: bool, error_abs: float, error_rel: float, component: str) -> None: # Print nothing since it's a single iteration pass def _re_assemble(self) -> None: self._assemble() def _single_solve(self) -> None: # performs a single linear solve in order to determine the current iterate value self.model.solve_single_step(self.a, self.L, self.preconditioners, self.gfu) def _startup(self) -> None: # Not applicable. pass def _update_time_step(self) -> Tuple[bool, float, float, str]: # Do nothing since it's a stationary solver return True, -1.0, -1.0, ''