Skip to content

Commit

Permalink
Add advance_postprocessing_timestep declarations and implementations …
Browse files Browse the repository at this point in the history
…for 1st order fixed timestep solvers.
  • Loading branch information
vikramvgarg committed Apr 23, 2022
1 parent 112b78c commit b51d0c4
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/solvers/euler2_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class Euler2Solver : public FirstOrderUnsteadySolver
virtual void integrate_adjoint_refinement_error_estimate(AdjointRefinementEstimator & adjoint_refinement_error_estimator, ErrorVector & QoI_elementwise_error) override;
#endif // LIBMESH_ENABLE_AMR

virtual void advance_postprocessing_timestep(std::vector<std::function<void(Real, System &)>> integration_operations) override;

/**
* This method uses the DifferentiablePhysics'
* element_time_derivative() and element_constraint()
Expand Down
2 changes: 2 additions & 0 deletions include/solvers/euler_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class EulerSolver : public FirstOrderUnsteadySolver
virtual void integrate_adjoint_refinement_error_estimate(AdjointRefinementEstimator & adjoint_refinement_error_estimator, ErrorVector & QoI_elementwise_error) override;
#endif // LIBMESH_ENABLE_AMR

virtual void advance_postprocessing_timestep(std::vector<std::function<void(Real, System &)>> integration_operations) override;

/**
* The value for the theta method to employ: 1.0 corresponds
* to backwards Euler, 0.0 corresponds to forwards Euler,
Expand Down
2 changes: 2 additions & 0 deletions include/solvers/first_order_unsteady_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class FirstOrderUnsteadySolver : public UnsteadySolver
virtual void integrate_adjoint_refinement_error_estimate(AdjointRefinementEstimator & adjoint_refinement_error_estimator, ErrorVector & QoI_elementwise_error) override = 0;
#endif // LIBMESH_ENABLE_AMR

virtual void advance_postprocessing_timestep(std::vector<std::function<void(Real, System &)>> integration_operations) override = 0;

protected:

/**
Expand Down
27 changes: 27 additions & 0 deletions src/solvers/euler2_solver.C
Original file line number Diff line number Diff line change
Expand Up @@ -482,4 +482,31 @@ void Euler2Solver::integrate_adjoint_refinement_error_estimate(AdjointRefinement
}
#endif // LIBMESH_ENABLE_AMR

void Euler2Solver::advance_postprocessing_timestep(std::vector<std::function<void(Real, System &)>> integration_operations)
{
// Enables the user to evaluate (1 - theta)*f(u_i-1) + theta*f(u_i)

// For correctness and adjoint consistency reasons we currently only support Backward Euler
if(theta != 0)
libmesh_not_implemented();

// The mesh and solutions (primal, adjoint) are already read in.
// So we are ready to call the user's integration operations.
for (auto integration_operations_iterator:integration_operations)
integration_operations_iterator(1.0 - theta, dynamic_cast<System&>(_system));

// Advance to t_j+1
_system.time = _system.time + _system.deltat;

// Retrieve the state and adjoint vectors for the next time instant
retrieve_timestep();

// Mesh and solution read in. Ready to call the user's integration operations.
for (auto integration_operations_iterator:integration_operations)
integration_operations_iterator(theta, dynamic_cast<System&>(_system));

return;

}

} // namespace libMesh
39 changes: 39 additions & 0 deletions src/solvers/euler_solver.C
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,43 @@ void EulerSolver::integrate_adjoint_refinement_error_estimate(AdjointRefinementE
}
#endif // LIBMESH_ENABLE_AMR

void EulerSolver::advance_postprocessing_timestep(std::vector<std::function<void(Real, System &)>> integration_operations)
{
// // For EulerSolver: \int_{t_i}^{t_(i+1)} f(u(t)) dt \approx f(theta u_i + (1-theta)u_i+1) (t_i+1 - t_i)

// Currently, we only support this functionality when Backward-Euler time integration is used.
if (theta != 1.0)
libmesh_not_implemented();

// u_i will be provided by the old nonlinear solution after we advance to the next time instant.

// Advance to t_j+1
_system.time = _system.time + _system.deltat;

// Retrieve the state and adjoint vectors for the next time instant
retrieve_timestep();

// Create a new weighted solution vector (1 - theta)*u_i-1 + theta*u_i
std::unique_ptr<NumericVector<Number>> weighted_vector = NumericVector<Number>::build(_system.comm());
weighted_vector->init(_system.get_vector("_old_nonlinear_solution"));

weighted_vector->add(1.0 - theta, _system.get_vector("_old_nonlinear_solution"));

weighted_vector->add(theta, *(_system.solution));

_system.solution->swap(*weighted_vector);

// Mesh and solution read in. Ready to call the user's integration operations.
// Since we have already weighted the solution and old solution, we just pass 1.0
// as the time quadrature weight.
for (auto integration_operations_iterator:integration_operations)
integration_operations_iterator(1.0, dynamic_cast<System&>(_system));

// Swap back
_system.solution->swap(*weighted_vector);

return;
}


} // namespace libMesh

0 comments on commit b51d0c4

Please sign in to comment.