Concepts#

System#

namespace pressio{ namespace ode{

template <class T>
concept OdeSystem =
  requires(){ typename T::independent_variable_type; }
  && std::copy_constructible<typename T::state_type>
  && std::copy_constructible<typename T::rhs_type>
  && requires(const T & A,
	      const typename T::state_type & state,
	      const typename T::independent_variable_type & evalValue,
	      typename T::rhs_type & f)
  {
    { A.createState() } -> std::same_as<typename T::state_type>;
    { A.createRhs()   } -> std::same_as<typename T::rhs_type>;
    { A.rhs(state, evalValue, f) } -> std::same_as<void>;
  };

template <class T>
concept OdeSystemFusingRhsAndJacobian =
  requires(){ typename T::independent_variable_type; }
  && std::copy_constructible<typename T::state_type>
  && std::copy_constructible<typename T::rhs_type>
  && std::copy_constructible<typename T::jacobian_type>
  && requires(const T & A,
	      const typename T::state_type & state,
	      const typename T::independent_variable_type & evalValue,
	      typename T::rhs_type & f,
	      std::optional<typename T::jacobian_type*> J)
  {
    { A.createState()    } -> std::same_as<typename T::state_type>;
    { A.createRhs()      } -> std::same_as<typename T::rhs_type>;
    { A.createJacobian() } -> std::same_as<typename T::jacobian_type>;
    { A.rhsAndJacobian(state, evalValue, f, J) } -> std::same_as<void>;
  };

template <class T>
concept OdeSystemFusingMassMatrixAndRhs =
  requires(){ typename T::independent_variable_type; }
  && std::copy_constructible<typename T::state_type>
  && std::copy_constructible<typename T::rhs_type>
  && std::copy_constructible<typename T::mass_matrix_type>
  && requires(const T & A,
	      const typename T::state_type & state,
	      const typename T::independent_variable_type & evalValue,
	      typename T::mass_matrix_type & M,
	      typename T::rhs_type & f)
  {
    { A.createState()      } -> std::same_as<typename T::state_type>;
    { A.createRhs()        } -> std::same_as<typename T::rhs_type>;
    { A.createMassMatrix() } -> std::same_as<typename T::mass_matrix_type>;
    { A.massMatrixAndRhs(state, evalValue, M, f) } -> std::same_as<void>;
  };

template <class T>
concept CompleteOdeSystem =
  requires(){ typename T::independent_variable_type; }
  && std::copy_constructible<typename T::state_type>
  && std::copy_constructible<typename T::rhs_type>
  && std::copy_constructible<typename T::mass_matrix_type>
  && std::copy_constructible<typename T::jacobian_type>
  && requires(const T & A,
	      const typename T::state_type & state,
	      const typename T::independent_variable_type & evalValue,
	      typename T::mass_matrix_type & M,
	      typename T::rhs_type & f,
	      std::optional<typename T::jacobian_type*> J)
  {
    { A.createState()      } -> std::same_as<typename T::state_type>;
    { A.createRhs()        } -> std::same_as<typename T::rhs_type>;
    { A.createMassMatrix() } -> std::same_as<typename T::mass_matrix_type>;
    { A.massMatrixAndRhsAndJacobian(state, evalValue, M, f, J) } -> std::same_as<void>;
  };

template <class T, int NumStates>
concept FullyDiscreteSystemWithJacobian =
  requires(){ typename T::independent_variable_type; }
  && std::copy_constructible<typename T::state_type>
  && std::copy_constructible<typename T::discrete_residual_type>
  && std::copy_constructible<typename T::discrete_jacobian_type>
  && requires(const T & A)
  {
    { A.createState()            } -> std::same_as<typename T::state_type>;
    { A.createDiscreteResidual() } -> std::same_as<typename T::discrete_residual_type>;
    { A.createDiscreteJacobian() } -> std::same_as<typename T::discrete_jacobian_type>;
  }
  /*todo: fix syntax */
  && ::pressio::ode::has_const_discrete_residual_jacobian_method<
    T, NumStates,
    typename ::pressio::ode::StepCount::value_type,
    typename T::independent_variable_type,
    typename T::state_type,
    typename T::discrete_residual_type,
    typename T::discrete_jacobian_type>::value;

}}

Real-valued system refinement#

namespace pressio{ namespace ode{

template <class T>
concept RealValuedOdeSystem =
     OdeSystem<T>
  && std::floating_point< scalar_trait_t<typename T::state_type> >
  && std::floating_point< scalar_trait_t<typename T::rhs_type> >
  && std::convertible_to<
      typename T::independent_variable_type,
      scalar_trait_t<typename T::state_type> >;

template <class T>
concept RealValuedOdeSystemFusingMassMatrixAndRhs =
  OdeSystemFusingMassMatrixAndRhs<T>
  && std::floating_point< scalar_trait_t<typename T::state_type> >
  && std::floating_point< scalar_trait_t<typename T::rhs_type> >
  && std::floating_point< scalar_trait_t<typename T::mass_matrix_type> >
  && std::convertible_to<
      typename T::independent_variable_type,
      scalar_trait_t<typename T::state_type> >;

template <class T>
concept RealValuedOdeSystemFusingRhsAndJacobian =
     OdeSystemFusingRhsAndJacobian<T>
  && std::floating_point< scalar_trait_t<typename T::state_type> >
  && std::floating_point< scalar_trait_t<typename T::rhs_type> >
  && std::floating_point< scalar_trait_t<typename T::jacobian_type> >
  && std::convertible_to<
      typename T::independent_variable_type,
      scalar_trait_t<typename T::state_type> >;

template <class T>
concept RealValuedCompleteOdeSystem =
     CompleteOdeSystem<T>
  && std::floating_point< scalar_trait_t<typename T::state_type> >
  && std::floating_point< scalar_trait_t<typename T::rhs_type> >
  && std::floating_point< scalar_trait_t<typename T::mass_matrix_type> >
  && std::floating_point< scalar_trait_t<typename T::jacobian_type> >
  && std::convertible_to<
      typename T::independent_variable_type,
      scalar_trait_t<typename T::state_type> >;

template <class T, int NumStates>
concept RealValuedFullyDiscreteSystemWithJacobian =
     FullyDiscreteSystemWithJacobian<T, NumStates>
  && std::floating_point< scalar_trait_t<typename T::state_type> >
  && std::floating_point< scalar_trait_t<typename T::discrete_residual_type> >
  && std::floating_point< scalar_trait_t<typename T::discrete_jacobian_type> >
  && std::convertible_to<
      typename T::independent_variable_type,
      scalar_trait_t<typename T::state_type> >;

}}

Others#

namespace pressio{ namespace ode{

template <class T>
concept Steppable =
  requires(){
    typename T::independent_variable_type;
    typename T::state_type;
  }
  && requires(T & A,
	      typename T::state_type & state,
	      const ::pressio::ode::StepStartAt<typename T::independent_variable_type> & startAt,
	      const ::pressio::ode::StepCount & stepNumber,
	      const ::pressio::ode::StepSize<typename T::independent_variable_type> & dt)
  {
    A(state, startAt, stepNumber, dt);
  };

template <class T, class AuxT, class ...Args>
concept SteppableWithAuxiliaryArgs =
  requires(){
    typename T::independent_variable_type;
    typename T::state_type;
  }
  && requires(T & A,
	      typename T::state_type & state,
	      const ::pressio::ode::StepStartAt<typename T::independent_variable_type> & startAt,
	      const ::pressio::ode::StepCount & stepNumber,
	      const ::pressio::ode::StepSize<typename T::independent_variable_type> & dt,
	      AuxT && aux,
	      Args && ... args)
  {
    A(state, startAt, stepNumber, dt,
      std::forward<AuxT>(aux), std::forward<Args>(args)...);
  };

template <class T>
concept StronglySteppable = Steppable<T>;

template <class T, class AuxT, class ...Args>
concept StronglySteppableWithAuxiliaryArgs = SteppableWithAuxiliaryArgs<T, AuxT, Args...>;

template <class T, class IndVarType, class StateType>
concept StateObserver =
  requires(T && A,
	   const ::pressio::ode::StepCount & stepNumber,
	   const IndVarType & indVal,
	   const StateType & state)
  {
    A(stepNumber, indVal, state);
  };

template <class T, class IndVarType, class StateType>
concept StateGuesser =
  requires(T && A,
	   const ::pressio::ode::StepCount & stepNumber,
	   const ::pressio::ode::StepStartAt<IndVarType> & startAt,
	   StateType & state)
  {
    A(stepNumber, startAt, state);
  };

template <class T, class IndVarType>
concept StepSizePolicy =
  requires(T && A,
	   const ::pressio::ode::StepCount & stepNumber,
	   const ::pressio::ode::StepStartAt<IndVarType> & startAt,
	   ::pressio::ode::StepSize<IndVarType> & dt)
  {
    A(stepNumber, startAt, dt);
  };

template <class T, class IndVarType>
concept StepSizePolicyWithReductionScheme =
  requires(T && A,
	   const ::pressio::ode::StepCount & stepNumber,
	   const ::pressio::ode::StepStartAt<IndVarType> & startAt,
	   ::pressio::ode::StepSize<IndVarType> & dt,
	   ::pressio::ode::StepSizeMinAllowedValue<IndVarType> & minDt,
	   ::pressio::ode::StepSizeScalingFactor<IndVarType> & scalingFactor)
  {
    A(stepNumber, startAt, dt, minDt, scalingFactor);
  };

}}// end namespace pressio::ode