def run(self, state, **kwargs): """Implicit Euler step method. .. math:: u_{m+1}^{k+1} - \\Delta_\\tau F(t_{m+1}, u_{m+1}^{k+1}) = u_m^{k+1} + \\Delta_\\tau F(t_{m+1}, u_{m+1}^k) + \\Delta_t I_m^{m+1} \\left( F(\\vec{u}^k) \\right) Parameters ---------- solver_state : :py:class:`.SdcSolverState` """ super(ImplicitSdcCore, self).run(state, **kwargs) assert_is_instance(state, SdcSolverState, descriptor="State", checking_obj=self) assert_named_argument('problem', kwargs, types=IProblem, descriptor="Problem", checking_obj=self) _problem = kwargs['problem'] _previous_iteration_current_step = self._previous_iteration_current_step(state) if problem_has_direct_implicit(_problem, self): _previous_iteration_previous_step = self._previous_iteration_previous_step(state) _sol = _problem.direct_implicit(phis_of_time=[_previous_iteration_previous_step.value, _previous_iteration_current_step.value, state.current_time_step.previous_step.value], delta_node=state.current_step.delta_tau, integral=state.current_step.integral, core=self) else: # using step-wise formula # u_{m+1}^{k+1} - \Delta_\tau F(u_{m+1}^{k+1}) # = u_m^{k+1} - \Delta_\tau F(u_m^k) + \Delta_t I_m^{m+1}(F(u^k)) # Note: \Delta_t is always 1.0 as it's part of the integral _expl_term = \ (state.current_time_step.previous_step.value - state.current_step.delta_tau * _problem.evaluate_wrt_time(state.current_step.time_point, _previous_iteration_current_step.value) + state.current_step.integral).reshape(-1) _func = lambda x_next: \ _expl_term \ + state.current_step.delta_tau \ * _problem.evaluate_wrt_time(state.current_step.time_point, x_next.reshape(_problem.dim_for_time_solver)).reshape(-1) \ - x_next _sol = _problem.implicit_solve(state.current_step.value.reshape(-1), _func) if type(state.current_step.value) == type(_sol): state.current_step.value = _sol else: state.current_step.value = _sol[0]
def test_problem_has_direct_implicit_introspection(self): self.assertTrue(problem_has_direct_implicit(self._default)) self.assertFalse(problem_has_direct_implicit(IProblem()))
def run(self, state, **kwargs): """Implicit Euler step method. .. math:: u_{m+1}^{k+1} - \\Delta_\\tau F(t_{m+1}, u_{m+1}^{k+1}) = u_m^{k+1} + \\Delta_\\tau F(t_{m+1}, u_{m+1}^k) + \\Delta_t I_m^{m+1} \\left( F(\\vec{u}^k) \\right) Parameters ---------- solver_state : :py:class:`.MlSdcSolverState` """ super(ImplicitMlSdcCore, self).run(state, **kwargs) assert_is_instance(state, MlSdcSolverState, descriptor="State", checking_obj=self) assert_named_argument('problem', kwargs, types=IProblem, descriptor="Problem", checking_obj=self) _problem = kwargs['problem'] use_intermediate = kwargs['use_intermediate'] if 'use_intermediate' in kwargs else False if use_intermediate: # LOG.debug("using intermediate") _previous_iteration_current_step = state.current_iteration.current_level.current_step.intermediate elif not state.current_iteration.on_finest_level: _previous_iteration_current_step = state.current_iteration.current_level.current_step else: _previous_iteration_current_step = self._previous_iteration_current_step(state) if not _previous_iteration_current_step.rhs_evaluated: _previous_iteration_current_step.rhs = \ _problem.evaluate_wrt_time(_previous_iteration_current_step.time_point, _previous_iteration_current_step.value) if not state.current_iteration.on_finest_level: _previous_iteration_previous_step = state.current_iteration.current_level.previous_step else: _previous_iteration_previous_step = self._previous_iteration_previous_step(state) if not _previous_iteration_previous_step.rhs_evaluated: _previous_iteration_previous_step.rhs = \ _problem.evaluate_wrt_time(_previous_iteration_previous_step.time_point, _previous_iteration_previous_step.value) _fas = np.zeros(_previous_iteration_current_step.rhs.shape, dtype=_previous_iteration_current_step.rhs.dtype) if not use_intermediate and _previous_iteration_current_step.has_fas_correction(): # LOG.debug(" previous iteration current step has FAS: %s" # % _previous_iteration_current_step.fas_correction) _fas = _previous_iteration_current_step.fas_correction if problem_has_direct_implicit(_problem, self): if not state.current_iteration.on_finest_level: _previous_iteration_previous_step = state.current_iteration.current_level.previous_step else: _previous_iteration_previous_step = self._previous_iteration_previous_step(state) _sol = _problem.direct_implicit(phis_of_time=[_previous_iteration_previous_step.value, _previous_iteration_current_step.value, state.previous_step.value], delta_node=state.current_step.delta_tau, integral=state.current_step.integral, fas=_fas, core=self) else: # using step-wise formula # u_{m+1}^{k+1} - \Delta_\tau F(u_{m+1}^{k+1}) # = u_m^{k+1} - \Delta_\tau F(u_m^k) + \Delta_t I_m^{m+1}(F(u^k)) # Note: \Delta_t is always 1.0 as it's part of the integral _expl_term = \ state.current_time_step.previous_step.value \ - state.current_step.delta_tau * _previous_iteration_current_step.rhs \ + state.current_step.integral + _fas _func = lambda x_next: \ _expl_term \ + state.current_step.delta_tau * _problem.evaluate_wrt_time(state.current_step.time_point, x_next) \ - x_next _sol = _problem.implicit_solve(state.current_step.value, _func) if type(state.current_step.value) == type(_sol): state.current_step.value = _sol else: state.current_step.value = _sol[0]
def run(self, state, **kwargs): """Semi-Implicit Euler step method. .. math:: u_{m+1}^{k+1} - \\Delta_\\tau F_I(t_{m+1}, u_{m+1}^{k+1}) = u_m^{k+1} &+ \\Delta_\\tau \\left( F_I(t_{m+1}, u_{m+1}^k) - F_E(t_m, u_m^{k+1}) + F_E(t_m, u_m^k) \\right) \\\\ &+ \\Delta_t I_m^{m+1} \\left( F(\\vec{u}^k) \\right) Parameters ---------- state : :py:class:`.MlSdcSolverState` Notes ----- This step method requires the given problem to provide partial evaluation of the right-hand side. """ super(SemiImplicitMlSdcCore, self).run(state, **kwargs) assert_is_instance(state, MlSdcSolverState, descriptor="State", checking_obj=self) assert_named_argument('problem', kwargs, types=IProblem, descriptor="Problem", checking_obj=self) _problem = kwargs['problem'] use_intermediate = kwargs['use_intermediate'] if 'use_intermediate' in kwargs else False if use_intermediate: # LOG.debug("using intermediate") _previous_iteration_current_step = state.current_iteration.current_level.current_step.intermediate elif not state.current_iteration.on_finest_level: _previous_iteration_current_step = state.current_iteration.current_level.current_step else: _previous_iteration_current_step = self._previous_iteration_current_step(state) if not _previous_iteration_current_step.rhs_evaluated: _previous_iteration_current_step.rhs = \ _problem.evaluate_wrt_time(_previous_iteration_current_step.time_point, _previous_iteration_current_step.value) if not state.current_iteration.on_finest_level: _previous_iteration_previous_step = state.current_iteration.current_level.previous_step else: _previous_iteration_previous_step = self._previous_iteration_previous_step(state) if not _previous_iteration_previous_step.rhs_evaluated: _previous_iteration_previous_step.rhs = \ _problem.evaluate_wrt_time(_previous_iteration_previous_step.time_point, _previous_iteration_previous_step.value) _fas = np.zeros(_previous_iteration_current_step.rhs.shape, dtype=_previous_iteration_current_step.rhs.dtype) if not use_intermediate and _previous_iteration_current_step.has_fas_correction(): # LOG.debug(" previous iteration current step has FAS: %s" # % _previous_iteration_current_step.fas_correction) _fas = _previous_iteration_current_step.fas_correction if problem_has_direct_implicit(_problem, self): _sol = _problem.direct_implicit(phis_of_time=[_previous_iteration_previous_step.value, _previous_iteration_current_step.value, state.previous_step.value], delta_node=state.current_step.delta_tau, delta_step=state.delta_interval, integral=state.current_step.integral, fas=_fas, core=self) else: # Note: \Delta_t is always 1.0 as it's part of the integral _Fe_u_cp = _problem.evaluate_wrt_time(state.previous_step.time_point, state.previous_step.value, partial="expl") _Fe_u_pp = _problem.evaluate_wrt_time(_previous_iteration_previous_step.time_point, _previous_iteration_previous_step.value, partial="expl") _Fe_u_pc = _problem.evaluate_wrt_time(state.current_step.time_point, _previous_iteration_current_step.value, partial="impl") _expl_term = \ (state.previous_step.value + state.current_step.delta_tau * (_Fe_u_cp - _Fe_u_pp - _Fe_u_pc) + state.current_step.integral + _fas).reshape(-1) # LOG.debug("EXPL TERM: %s = %s + %f * (%s - %s - %s) + %s + %s" # % (_expl_term, state.previous_step.value, state.current_step.delta_tau, _Fe_u_cp, _Fe_u_pp, # _Fe_u_pc, state.current_step.integral, _fas)) _func = lambda x_next: \ _expl_term \ + state.current_step.delta_tau * _problem.evaluate_wrt_time(state.current_step.time_point, x_next.reshape(_problem.dim_for_time_solver), partial="impl").reshape(-1) \ - x_next # LOG.debug("shape of value: %s" % (state.current_step.value.shape,)) # LOG.debug("shape expl term: %s" % (_expl_term.shape,)) # LOG.debug("shape impl func: %s" % (_func(state.current_step.value.reshape(-1)).shape,)) _sol = \ _problem.implicit_solve( state.current_step.value.reshape(-1), _func, expl_term=_expl_term, time_level=state.current_iteration.current_level_index, delta_time=state.current_iteration.current_level.current_step.delta_tau ).reshape(state.current_step.value.shape) if type(state.current_step.value) == type(_sol): state.current_step.value = _sol else: LOG.debug("Solution Type %s but expected %s" % (type(_sol), type(state.current_step.value))) state.current_step.value = _sol[0]
def run(self, state, **kwargs): """Semi-Implicit Euler step method. .. math:: u_{m+1}^{k+1} - \\Delta_\\tau F_I(t_{m+1}, u_{m+1}^{k+1}) = u_m^{k+1} &+ \\Delta_\\tau \\left( F_I(t_{m+1}, u_{m+1}^k) - F_E(t_m, u_m^{k+1}) + F_E(t_m, u_m^k) \\right) \\\\ &+ \\Delta_t I_m^{m+1} \\left( F(\\vec{u}^k) \\right) Parameters ---------- state : :py:class:`.SdcSolverState` Notes ----- This step method requires the given problem to provide partial evaluation of the right-hand side. """ super(SemiImplicitSdcCore, self).run(state, **kwargs) assert_is_instance(state, SdcSolverState, descriptor="State", checking_obj=self) assert_named_argument('problem', kwargs, types=IProblem, descriptor="Problem", checking_obj=self) _problem = kwargs['problem'] _previous_iteration_current_step = self._previous_iteration_current_step(state) _previous_iteration_previous_step = self._previous_iteration_previous_step(state) if problem_has_direct_implicit(_problem, self): _sol = _problem.direct_implicit(phis_of_time=[_previous_iteration_previous_step.value, _previous_iteration_current_step.value, state.previous_step.value], delta_node=state.current_step.delta_tau, delta_step=state.current_time_step.delta_time_step, integral=state.current_step.integral) else: # Note: \Delta_t is always 1.0 as it's part of the integral _expl_term = \ (state.previous_step.value + state.current_step.delta_tau * (_problem.evaluate_wrt_time(state.current_step.time_point, state.previous_step.value, partial="expl") - _problem.evaluate_wrt_time(state.previous_step.time_point, _previous_iteration_previous_step.value, partial="expl") - _problem.evaluate_wrt_time(state.current_step.time_point, _previous_iteration_current_step.value, partial="impl")) + state.current_step.integral).reshape(-1) _func = lambda x_next: \ _expl_term \ + state.current_step.delta_tau \ * _problem.evaluate_wrt_time(state.current_step.time_point, x_next.reshape(_problem.dim_for_time_solver), partial="impl").reshape(-1) \ - x_next _sol = _problem.implicit_solve(state.current_step.value.reshape(-1), _func, expl_term=_expl_term, time_level=0, delta_time=state.current_step.delta_tau).reshape(state.current_step.value.shape) if type(state.current_step.value) == type(_sol): state.current_step.value = _sol else: state.current_step.value = _sol[0]