Reference documentation for deal.II version GIT 6da2e5d553 2022-07-01 18:55:02+00:00
Algorithms::ThetaTimestepping< VectorType > Class Template Reference

#include <deal.II/algorithms/theta_timestepping.h>

Inheritance diagram for Algorithms::ThetaTimestepping< VectorType >:
[legend]

## Public Member Functions

ThetaTimestepping (OperatorBase &op_explicit, OperatorBase &op_implicit)

virtual void operator() (AnyData &out, const AnyData &in) override

virtual void notify (const Event &) override

void set_output (OutputOperator< VectorType > &output)

void parse_parameters (ParameterHandler &param)

double current_time () const

double theta () const

double theta (double new_theta)

const TimestepDataexplicit_data () const

const TimestepDataimplicit_data () const

TimestepControltimestep_control ()

void clear_events ()

## Static Public Member Functions

static void declare_parameters (ParameterHandler &param)

## Private Attributes

TimestepControl control

double vtheta

TimestepData d_explicit

TimestepData d_implicit

SmartPointer< OperatorBase, ThetaTimestepping< VectorType > > op_explicit

SmartPointer< OperatorBase, ThetaTimestepping< VectorType > > op_implicit

SmartPointer< OutputOperator< VectorType >, ThetaTimestepping< VectorType > > output

## Subscriptor functionality

Classes derived from Subscriptor provide a facility to subscribe to this object. This is mostly used by the SmartPointer class.

std::atomic< unsigned int > counter

std::map< std::string, unsigned int > counter_map

std::vector< std::atomic< bool > * > validity_pointers

const std::type_info * object_info

void subscribe (std::atomic< bool > *const validity, const std::string &identifier="") const

void unsubscribe (std::atomic< bool > *const validity, const std::string &identifier="") const

unsigned int n_subscriptions () const

template<typename StreamType >
void list_subscribers (StreamType &stream) const

void list_subscribers () const

template<class Archive >
void serialize (Archive &ar, const unsigned int version)

static ::ExceptionBaseExcInUse (int arg1, std::string arg2, std::string arg3)

static ::ExceptionBaseExcNoSubscriber (std::string arg1, std::string arg2)

using map_value_type = decltype(counter_map)::value_type

using map_iterator = decltype(counter_map)::iterator

static std::mutex mutex

void check_no_subscribers () const noexcept

## Detailed Description

### template<typename VectorType> class Algorithms::ThetaTimestepping< VectorType >

Application class performing the theta timestepping scheme.

The theta scheme is an abstraction of implicit and explicit Euler schemes, the Crank-Nicholson scheme and linear combinations of those. The choice of the actual scheme is controlled by the parameter theta as follows.

• theta=0: explicit Euler scheme
• theta=1: implicit Euler scheme
• theta=½: Crank-Nicholson scheme

For fixed theta, the Crank-Nicholson scheme is the only second order scheme. Nevertheless, further stability may be achieved by choosing theta larger than ½, thereby introducing a first order error term. In order to avoid a loss of convergence order, the adaptive theta scheme can be used, where theta=½+c dt.

Assume that we want to solve the equation u' + F(u) = 0 with a step size k. A step of the theta scheme can be written as

$M u_{n+1} + \theta k F(u_{n+1}) = M u_n - (1-\theta)k F(u_n).$

Here, M is the mass matrix. We see, that the right hand side amounts to an explicit Euler step with modified step size in weak form (up to inversion of M). The left hand side corresponds to an implicit Euler step with modified step size (right hand side given). Thus, the implementation of the theta scheme will use two Operator objects, one for the explicit, one for the implicit part. Each of these will use its own TimestepData to account for the modified step sizes (and different times if the problem is not autonomous). Note that once the explicit part has been computed, the left hand side actually constitutes a linear or nonlinear system which has to be solved.

### Usage AnyData

ThetaTimestepping uses AnyData for communicating vectors and time step information. With outer or inner Operator objects. It does not use itself the input vectors provided, but forwards them to the explicit and implicit operators.

#### Vector data

The explicit Operator op_explicit receives in its input in first place the vector "Previous iterate", which is the solution value after the previous timestep. It is followed by all vectors provided to ThetaTimestepping::operator() as input argument. op_explicit is supposed to write its result into the first position of its output argument, labeled "Result".

The implicit Operator op_implicit receives the result of op_explicit in its first input vector labeled "Previous time". It is followed by all vectors provided to ThetaTimestepping::operator() as input argument. The output of op_implicit is directly written into the output argument given to ThetaTimestepping.

#### Scalar data

Since the introduction of AnyData, ThetaTimestepping is able to communicate the current time step information through AnyData as well. Therefore, the AnyData objects handed as input to op_explicit and op_implicit contain two entries of type const double* named "Time" and "Timestep". Note that "Time" refers to the time at the beginning of the current step for op_explicit and at the end for op_implicit, respectively.

### Usage of ThetaTimestepping

The use ThetaTimestepping is more complicated than for instance Newton, since the inner operators will usually need to access the TimeStepData. Thus, we have a circular dependency of information, and we include the following example for its use.

First, we define the two operators used by ThetaTimestepping and call them Implicit and Explicit. They both share the public interface of Operator, and additionally provide storage for the matrices to be used and a pointer to TimestepData. Note that we do not use a SmartPointer here, since the TimestepData will be destroyed before the operator.

class Explicit : public OperatorBase
{
public:
Explicit(const FullMatrix<double> &matrix);
void operator()(AnyData &out, const AnyData &in);
private:
};
class Implicit : public OperatorBase
{
public:
Implicit(const FullMatrix<double> &matrix);
void operator()(AnyData &out, const AnyData &in);
private:
};
virtual void operator()(AnyData &out, const AnyData &in) override
@ matrix
Contents is actually a matrix.

These operators will be implemented after the main program. But let us look first at how they get used. First, let us define a matrix to be used for our system and also an OutputOperator in order to write the data of each timestep to a file.

int main()
{
matrix(0, 0) = 0.;
matrix(1, 1) = 0.;
matrix(0, 1) = 3.14;
matrix(1, 0) = -3.14;
OutputOperator<Vector<double>> out;
out.initialize_stream(std::cout);

Now we create objects for the implicit and explicit parts of the steps as well as the ThetaTimestepping itself. We initialize the timestepping with the output operator in order to be able to see the output in every step.

Explicit op_explicit(matrix);
Implicit op_implicit(matrix);
ThetaTimestepping<Vector<double>> solver(op_explicit, op_implicit);
solver.set_output(out);
SmartPointer< OperatorBase, ThetaTimestepping< VectorType > > op_implicit
SmartPointer< OperatorBase, ThetaTimestepping< VectorType > > op_explicit

The next step is providing the vectors to be used. value is filled with the initial value and is also the vector where the solution at each timestep will be. Because the interface of Operator has to be able to handle several vectors, we need to store it in an AnyData object. Since our problem has no additional parameters, the input AnyData object remains empty.

value(0) = 1.;
AnyData indata;
AnyData outdata;
void add(type entry, const std::string &name)
Definition: any_data.h:432

Finally, we are ready to tell the solver, that we are starting at the initial timestep and run it.

solver.notify(Events::initial);
solver(outdata, indata);
}
const Event initial
Definition: event.cc:65

Besides the main function, we need to define the members functions of the implicit and explicit operators. First the constructor, which simply copies the system matrix into the member pointer for later use.

Explicit::Explicit(const FullMatrix<double> &M)
: matrix(&M)
{
m.reinit(M.m(), M.n());
}
size_type n() const
size_type m() const

Now we need to study the application of the implicit and explicit operator. We assume that the pointer matrix points to the matrix created in the main program (the constructor did this for us). Here, we first get the time step size from the AnyData object that was provided as input. Then, if we are in the first step or if the timestep has changed, we fill the local matrix $$m$$, such that with the given matrix $$M$$, it becomes

$m = I - \Delta t M.$

After we have worked off the notifications, we clear them, such that the matrix is only generated when necessary.

void Explicit::operator()(AnyData &out, const AnyData &in)
{
{
m.equ(-timestep, *matrix);
for (unsigned int i = 0; i < m.m(); ++i)
m(i, i) += 1.;
}
bool test(const Event &event) const
Definition: event.h:186
void clear()
Definition: event.cc:50
const type * read_ptr(const std::string &name) const
Dedicated read only access by name for pointer data.
Definition: any_data.h:385
const Event new_timestep_size
Definition: event.cc:69

Now we multiply the input vector with the new matrix and store on output.

m.vmult(*out.entry<Vector<double> *>(0),
}
type entry(const std::string &name)
Definition: any_data.h:351

The code for the implicit operator is almost the same, except that we change the sign in front of the timestep and use the inverse of the matrix.

Implicit::Implicit(const FullMatrix<double> &M)
: matrix(&M)
{
m.reinit(M.m(), M.n());
}
void Implicit::operator()(AnyData &out, const AnyData &in)
{
{
m.equ(timestep, *matrix);
for (unsigned int i = 0; i < m.m(); ++i)
m(i, i) += 1.;
m.gauss_jordan();
}
m.vmult(*out.entry<Vector<double> *>(0),
}

Definition at line 287 of file theta_timestepping.h.

## ◆ ThetaTimestepping()

template<typename VectorType >
 Algorithms::ThetaTimestepping< VectorType >::ThetaTimestepping ( OperatorBase & op_explicit, OperatorBase & op_implicit )

Constructor, receiving the two operators stored in op_explicit and op_implicit. For their meaning, see the description of those variables.

## ◆ operator()()

template<typename VectorType >
 virtual void Algorithms::ThetaTimestepping< VectorType >::operator() ( AnyData & out, const AnyData & in )
overridevirtual

The timestepping scheme.

Parameters
 in is ignored by ThetaTimestepping, but is merged into the AnyData objects used as input for the operators op_explicit and op_implicit. out in its first argument must contain a pointer to a VectorType instance, which contains the initial value when the operator is called. It contains the final value when the operator returns.

Implements Algorithms::OperatorBase.

## ◆ notify()

template<typename VectorType >
 virtual void Algorithms::ThetaTimestepping< VectorType >::notify ( const Event & )
overridevirtual

Register an event triggered by an outer iteration.

Reimplemented from Algorithms::OperatorBase.

## ◆ set_output()

template<typename VectorType >
 void Algorithms::ThetaTimestepping< VectorType >::set_output ( OutputOperator< VectorType > & output )
inline

Define an operator which will output the result in each step. Note that no output will be generated without this.

Definition at line 463 of file theta_timestepping.h.

## ◆ declare_parameters()

template<typename VectorType >
 static void Algorithms::ThetaTimestepping< VectorType >::declare_parameters ( ParameterHandler & param )
static

Declare parameters in a parameter handler.

## ◆ parse_parameters()

template<typename VectorType >
 void Algorithms::ThetaTimestepping< VectorType >::parse_parameters ( ParameterHandler & param )

Read the parameters in the ParameterHandler.

## ◆ current_time()

template<typename VectorType >
 double Algorithms::ThetaTimestepping< VectorType >::current_time
inline

The current time in the timestepping scheme.

Definition at line 489 of file theta_timestepping.h.

## ◆ theta() [1/2]

template<typename VectorType >
 double Algorithms::ThetaTimestepping< VectorType >::theta
inline

The weight between implicit and explicit part.

Definition at line 471 of file theta_timestepping.h.

## ◆ theta() [2/2]

template<typename VectorType >
 double Algorithms::ThetaTimestepping< VectorType >::theta ( double new_theta )
inline

Set a new weight and return the old

Definition at line 479 of file theta_timestepping.h.

## ◆ explicit_data()

template<typename VectorType >
 const TimestepData & Algorithms::ThetaTimestepping< VectorType >::explicit_data
inline

The data handed to the op_explicit time stepping operator.

The time in here is the time at the beginning of the current step, the time step is (1-theta) times the actual time step.

Definition at line 440 of file theta_timestepping.h.

## ◆ implicit_data()

template<typename VectorType >
 const TimestepData & Algorithms::ThetaTimestepping< VectorType >::implicit_data
inline

The data handed to the op_implicit time stepping operator.

The time in here is the time at the beginning of the current step, the time step is theta times the actual time step.

Definition at line 448 of file theta_timestepping.h.

## ◆ timestep_control()

template<typename VectorType >
 TimestepControl & Algorithms::ThetaTimestepping< VectorType >::timestep_control
inline

Definition at line 456 of file theta_timestepping.h.

## ◆ clear_events()

 void Algorithms::OperatorBase::clear_events ( )
inherited

Definition at line 49 of file operator.cc.

## ◆ control

template<typename VectorType >
 TimestepControl Algorithms::ThetaTimestepping< VectorType >::control
private

The object controlling the time step size and computing the new time in each step.

Definition at line 383 of file theta_timestepping.h.

## ◆ vtheta

template<typename VectorType >
 double Algorithms::ThetaTimestepping< VectorType >::vtheta
private

The control parameter theta in the range [0,1]. It defaults to 0.5.

Definition at line 389 of file theta_timestepping.h.

template<typename VectorType >
private

Use adaptive theta if true. Not yet implemented.

Definition at line 393 of file theta_timestepping.h.

## ◆ d_explicit

template<typename VectorType >
 TimestepData Algorithms::ThetaTimestepping< VectorType >::d_explicit
private

The data for the explicit part of the scheme.

Definition at line 398 of file theta_timestepping.h.

## ◆ d_implicit

template<typename VectorType >
 TimestepData Algorithms::ThetaTimestepping< VectorType >::d_implicit
private

The data for the implicit part of the scheme.

Definition at line 403 of file theta_timestepping.h.

## ◆ op_explicit

template<typename VectorType >
 SmartPointer > Algorithms::ThetaTimestepping< VectorType >::op_explicit
private

The operator computing the explicit part of the scheme. This will receive in its input data the value at the current time with name "Current time solution". It should obtain the current time and time step size from explicit_data().

Its return value is $$Mu+cF(u)$$, where $$u$$ is the current state vector, $$M$$ the mass matrix, $$F$$ the operator in space and $$c$$ is the adjusted time step size $$(1-\theta) \Delta t$$.

Definition at line 416 of file theta_timestepping.h.

## ◆ op_implicit

template<typename VectorType >
 SmartPointer > Algorithms::ThetaTimestepping< VectorType >::op_implicit
private

The operator solving the implicit part of the scheme. It will receive in its input data the vector "Previous time". Information on the timestep should be obtained from implicit_data().

Its return value is the solution u of Mu-cF(u)=f, where f is the dual space vector found in the "Previous time" entry of the input data, M the mass matrix, F the operator in space and c is the adjusted time step size $$\theta \Delta t$$

Definition at line 428 of file theta_timestepping.h.

## ◆ output

template<typename VectorType >
 SmartPointer, ThetaTimestepping > Algorithms::ThetaTimestepping< VectorType >::output
private

The operator writing the output in each time step

Definition at line 434 of file theta_timestepping.h.