Create a solver builder class which makes the linear solver, the state, the jacobian information, etc. so that either backward euler or rosenbrock can be created
[x] #514
[x] #538
[x] #529
[x] #539
Acceptance criteria
The builder wrapper should be only called once during a simulation.
We add a new builder for the Rosenbrock solver and a test for it (does not break the existing tests).
We add a new builder for the Backward Euler solver and a test for it (does not break the existing tests).
We update the existing Rosenbrock tests with the new solver builder and fix the broken tests.
Ideas
In the test driver, we can generate a Rosenbrock solver like:
auto rosenbrock_solver = Solver::Create()
.SetSystem(chemical_system)
.SetReactions(reactions)
.SetNumberOfGridCells(19)
.Rosenbrock<MatrixPolicy, SparseMatrixPolicy>(RosenbrockSolverParameters::ThreeStageRosenbrockParameters());
and a backward Euler solver like:
auto backward_euler_solver = Solver::Create()
.SetSystem(chemical_system)
.SetReactions(reactions)
.SetNumberOfGridCells(19)
.BackwardEuler(BackwardEulerParameters::CamChemParameters());
and a CUDA rosenbrock solver like:
auto cuda_solver = Solver::Create()
.SetSystem(chemical_system)
.SetReactions(reactions)
.SetNumberOfGridCells(19)
.Rosenbrock<CudaDenseMatrixPolicy, CudaSparseMatrixPolicy>(RosenbrockSolverParameters::ThreeStageRosenbrockParameter());
then we can generate a state variable for different solvers like:
auto rosenbrock_state = rosenbrock_solver.GetState();
auto backward_euler_state = backward_euler_solver.GetState();
auto cuda_state = cuda_solver.GetState();
then we can initialize the conditions like:
rosenbrock_state.conditions_[0].temperature_ = 287.45; // K
rosenbrock_state.conditions_[0].pressure_ = 101319.9; // Pa
rosenbrock_state.SetConcentration(foo, 20.0); // mol m-3
backward_euler_state.conditions_[0].temperature_ = 287.45; // K
backward_euler_state.conditions_[0].pressure_ = 101319.9; // Pa
backward_euler_state.SetConcentration(foo, 20.0); // mol m-3
cuda_state.conditions_[0].temperature_ = 287.45; // K
cuda_state.conditions_[0].pressure_ = 101319.9; // Pa
cuda_state.SetConcentration(foo, 20.0); // mol m-3
then we can establish a time loop for the cuda solver:
cuda_state.PrintHeader();
for (int i = 0; i < 10; ++i)
{
cuda_state.CalculateRateConstants(); // calculate rate constants on the host
cuda_state.SyncToDevice(); // copy the updated rate constants to the device
auto result = cuda_solver.Solve(500.0, cuda_state); // solve on the device
cuda_state.variables_ = result.result_; // device to device copy with overloaded operator=
cuda_state.SyncToHost();
cuda_state.PrintState(i * 500);
}
Create a solver builder class which makes the linear solver, the state, the jacobian information, etc. so that either backward euler or rosenbrock can be created
Acceptance criteria
Ideas
and a backward Euler solver like:
and a CUDA rosenbrock solver like:
then we can initialize the conditions like: