# Restart a problem¶

This demo demonstrates the functionality of restarting a problem. This could be useful for example if one wants to run the simulation for longer than anticipated on initial solve, if one wants parts of the solution to have a different temporal resolution or if one wants to completely change the boundary conditions of the problem at a certain point.

It is based on the Beltrami problem, a 3D problem with a known analytical solution.

The source code for this demo can be found in `Restart.py`.

We start by importing the problem,

```
from os import path
import sys
# Add Beltrami problem as example problem
sys.path.insert(0, path.join(path.dirname(path.realpath(__file__)), '../../../demo/undocumented/Beltrami'))
from Beltrami import Beltrami
```

and cbcflow:

```
from cbcflow import *
```

## Play¶

We define the normal solve routine, by first initiating a problem and scheme:

```
def play():
problem = Beltrami(dict(dt=1e-2, T=1.0))
scheme = IPCS()
```

Note that we here use the `IPCS` scheme.

We then creates some fields to save for this solve:

```
fields = [
Velocity(dict(save=True, stride_timestep=5)),
Pressure(dict(save=True, stride_timestep=10)),
L2norm("Velocity", dict(save=True, stride_timestep=2))
]
```

Note that we *must* save velocity and pressure for restart to work.

We then add the fields to a `NSPostProcessor` instance,

```
postprocessor = NSPostProcessor(dict(casedir='results'))
postprocessor.add_fields(fields)
```

and solves the equation:

```
solver = NSSolver(problem, scheme, postprocessor)
solver.solve()
```

## Restart¶

When we restart the problem, we wish to reuse most of the parameters of the original
solve. These are save by the postprocessor to the case directory, and can be *unpickled*:

```
def restart():
# Load params, to reuse
import pickle
params = pickle.load(open('results/params.pickle', 'r'))
```

If we don’t change any of the parameters, we would basically be solving the exact same problem. Thus, we change the end time and time step of the problem:

```
problem = Beltrami(params.problem)
problem.params.T = 2.0
problem.params.dt = 5e-3
```

We are also free to change the scheme, so we change the scheme to `IPCS_Stable`:

```
scheme = IPCS_Stable(params.scheme)
```

On the restart, we also set up a different set of fields

```
# Set up postprocessor with new fields
fields = [
Velocity(dict(save=True)),
Pressure(dict(save=True)),
WSS(dict(save=True)),
]
```

and a new `NSPostProcessor` instance:

```
postprocessor = NSPostProcessor(dict(casedir='results'))
postprocessor.add_fields(fields)
```

We then need to define our new solver, and set some restart-specific parameters:

```
solver = NSSolver(problem, scheme, postprocessor)
solver.params["restart"] = True
solver.params["restart_time"] = 0.5
```

The solver will try to search for a solution in the postprocessors case directory at
time 0.5, and replace the the method `initial_conditions()` in the `NSProblem`
instance to reflect the solution at t=0.5.

Our call to solve will then restart this problem from the specified parameters, and solve the problem:

```
solver.solve()
```