1 #include <Epetra_RowMatrixTransposer.h>     3 #include <deal.II/base/conditional_ostream.h>     5 #include <deal.II/distributed/tria.h>     6 #include <deal.II/grid/grid_generator.h>     7 #include <deal.II/grid/grid_tools.h>     9 #include <deal.II/numerics/vector_tools.h>    11 #include "physics/physics_factory.h"    12 #include "parameters/all_parameters.h"    13 #include "dg/dg_factory.hpp"    14 #include "functional/functional.h"    17     using Triangulation = dealii::Triangulation<PHILIP_DIM>;
    19     using Triangulation = dealii::parallel::distributed::Triangulation<PHILIP_DIM>;
    22 const double STEPSIZE = 1e-7;
    23 const double TOLERANCE = 1e-6;
    26 template <
int dim, 
int nstate, 
typename real>
    29     using FadType = Sacado::Fad::DFad<double>; 
    42     template <
typename real2>
    45         const dealii::Point<dim,real2> &phys_coord,
    46         const std::array<real2,nstate> &soln_at_q,
    47         const std::array<dealii::Tensor<1,dim,real2>,nstate> &)
 const    51         for (
int istate=0; istate<nstate; ++istate) {
    53             l2error += std::pow(soln_at_q[istate] - uexact, 2);
    62     template<
typename real2>
    66         const dealii::Point<dim,real2> &phys_coord,
    67         const dealii::Tensor<1,dim,real2> &,
    68         const std::array<real2,nstate> &soln_at_q,
    69         const std::array<dealii::Tensor<1,dim,real2>,nstate> &)
 const    72         for (
int istate=0; istate<nstate; ++istate) {
    74             l1error += std::abs(soln_at_q[istate] - uexact);
    83         const unsigned int boundary_id,
    84         const dealii::Point<dim,real> &phys_coord,
    85         const dealii::Tensor<1,dim,real> &normal,
    86         const std::array<real,nstate> &soln_at_q,
    87         const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_at_q)
 const override    89         return evaluate_boundary_integrand<real>(
   101         const unsigned int boundary_id,
   102         const dealii::Point<dim,FadFadType> &phys_coord,
   103         const dealii::Tensor<1,dim,FadFadType> &normal,
   104         const std::array<FadFadType,nstate> &soln_at_q,
   105         const std::array<dealii::Tensor<1,dim,FadFadType>,nstate> &soln_grad_at_q)
 const override   107         return evaluate_boundary_integrand<FadFadType>(
   120         const dealii::Point<dim,real> &phys_coord,
   121         const std::array<real,nstate> &soln_at_q,
   122         const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_at_q)
 const override   124         return evaluate_volume_integrand<>(physics, phys_coord, soln_at_q, soln_grad_at_q);
   129         const dealii::Point<dim,FadFadType> &phys_coord,
   130         const std::array<FadFadType,nstate> &soln_at_q,
   131         const std::array<dealii::Tensor<1,dim,FadFadType>,nstate> &soln_grad_at_q)
 const override   133         return evaluate_volume_integrand<>(physics, phys_coord, soln_at_q, soln_grad_at_q);
   139 template <
int dim, 
int nstate>
   142     dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
   148 int main(
int argc, 
char *argv[])
   151     const int dim = PHILIP_DIM;
   152     const int nstate = 1;
   153     int fail_bool = 
false;
   156     dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
   157     const int this_mpi_process = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
   158     dealii::ConditionalOStream 
pcout(std::cout, this_mpi_process==0);
   161     dealii::ParameterHandler parameter_handler;
   167     const unsigned poly_degree = 1;
   170     std::shared_ptr<Triangulation> grid = std::make_shared<Triangulation>(
   174         typename dealii::Triangulation<dim>::MeshSmoothing(
   175             dealii::Triangulation<dim>::smoothing_on_refinement |
   176             dealii::Triangulation<dim>::smoothing_on_coarsening));
   178     const unsigned int n_refinements = 2;
   181     const bool colorize = 
true;
   183     dealii::GridGenerator::hyper_cube(*grid, left, right, colorize);
   184     grid->refine_global(n_refinements);
   185     const double random_factor = 0.2;
   186     const bool keep_boundary = 
false;
   187     if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary);
   189     pcout << 
"Grid generated and refined" << std::endl;
   193     pcout << 
"dg created" << std::endl;
   195     dg->allocate_system();
   196     pcout << 
"dg allocated" << std::endl;
   198     const int n_refine = 2;
   199     for (
int i=0; i<n_refine;i++) {
   200         dg->high_order_grid->prepare_for_coarsening_and_refinement();
   201         grid->prepare_coarsening_and_refinement();
   202         unsigned int icell = 0;
   203         for (
auto cell = grid->begin_active(); cell!=grid->end(); ++cell) {
   205             if (!cell->is_locally_owned()) 
continue;
   206             if (icell < grid->n_global_active_cells()/2) {
   207                 cell->set_refine_flag();
   210         grid->execute_coarsening_and_refinement();
   211         bool mesh_out = (i==n_refine-1);
   212         dg->high_order_grid->execute_coarsening_and_refinement(mesh_out);
   214     dg->allocate_system ();
   217     using FadType = Sacado::Fad::DFad<double>;
   219     pcout << 
"Physics created" << std::endl;
   222     initialize_perturbed_solution(*dg, *physics_double);
   223     pcout << 
"solution initialized" << std::endl;
   226     pcout << std::endl << 
"Starting Hessian AD... " << std::endl;
   228     const bool compute_dIdW = 
false, compute_dIdX = 
false, compute_d2I = 
true;
   229     double functional_value = functional.
evaluate_functional(compute_dIdW, compute_dIdX, compute_d2I);
   230     (void) functional_value;
   232     dealii::TrilinosWrappers::SparseMatrix d2IdWdW_transpose;
   234         Epetra_CrsMatrix *transpose_CrsMatrix;
   235         Epetra_RowMatrixTransposer epmt(const_cast<Epetra_CrsMatrix *>(&functional.
d2IdWdW->trilinos_matrix()));
   236         epmt.CreateTranspose(
false, transpose_CrsMatrix);
   237         d2IdWdW_transpose.reinit(*transpose_CrsMatrix);
   238         d2IdWdW_transpose.add(-1.0,*functional.
d2IdWdW);
   241     dealii::TrilinosWrappers::SparseMatrix d2IdXdX_transpose;
   243         Epetra_CrsMatrix *transpose_CrsMatrix;
   244         Epetra_RowMatrixTransposer epmt(const_cast<Epetra_CrsMatrix *>(&functional.
d2IdXdX->trilinos_matrix()));
   245         epmt.CreateTranspose(
false, transpose_CrsMatrix);
   246         d2IdXdX_transpose.reinit(*transpose_CrsMatrix);
   247         d2IdXdX_transpose.add(-1.0,*functional.
d2IdXdX);
   263     pcout << 
"functional.d2IdWdW.frobenius_norm()  " << functional.
d2IdWdW->frobenius_norm() << std::endl;
   264     pcout << 
"functional.d2IdXdX.frobenius_norm()  " << functional.
d2IdXdX->frobenius_norm() << std::endl;
   266     const double d2IdWdW_norm = functional.
d2IdWdW->frobenius_norm();
   267     const double d2IdWdW_abs_diff = d2IdWdW_transpose.frobenius_norm();
   268     const double d2IdWdW_rel_diff = d2IdWdW_abs_diff / d2IdWdW_norm;
   270     const double d2IdXdX_norm = functional.
d2IdXdX->frobenius_norm();
   271     const double d2IdXdX_abs_diff = d2IdXdX_transpose.frobenius_norm();
   272     const double d2IdXdX_rel_diff = d2IdXdX_abs_diff / d2IdXdX_norm;
   274     const double tol = 1e-11;
   276                     << 
" d2IdWdW_abs_diff: " << d2IdWdW_abs_diff
   277                     << 
" d2IdWdW_rel_diff: " << d2IdWdW_rel_diff
   279                     << 
" d2IdXdX_abs_diff: " << d2IdXdX_abs_diff
   280                     << 
" d2IdXdX_rel_diff: " << d2IdXdX_rel_diff
   282     if (d2IdWdW_abs_diff > tol && d2IdWdW_rel_diff > tol) fail_bool = 
true;
   283     if (d2IdXdX_abs_diff > tol && d2IdXdX_rel_diff > tol) fail_bool = 
true;
 std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > d2IdXdX
Sparse matrix for storing the functional partial second derivatives. 
const bool uses_solution_gradient
Will evaluate solution gradient at quadrature points. 
const bool uses_solution_values
Will evaluate solution values at quadrature points. 
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived. 
real2 evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, real2 > &physics, const dealii::Point< dim, real2 > &phys_coord, const std::array< real2, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &) const
Templated volume integrand. 
virtual FadFadType evaluate_boundary_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, FadFadType > &physics, const unsigned int boundary_id, const dealii::Point< dim, FadFadType > &phys_coord, const dealii::Tensor< 1, dim, FadFadType > &normal, const std::array< FadFadType, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, FadFadType >, nstate > &soln_grad_at_q) const override
Virtual function for Sacado computation of cell boundary functional term and derivatives. 
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > d2IdWdW
Sparse matrix for storing the functional partial second derivatives. 
FadFadType evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, FadFadType > &physics, const dealii::Point< dim, FadFadType > &phys_coord, const std::array< FadFadType, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, FadFadType >, nstate > &soln_grad_at_q) const override
Non-template functions to override the template classes. 
Files for the baseline physics. 
Main parameter class that contains the various other sub-parameter classes. 
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution. 
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom. 
L2_Norm_Functional(std::shared_ptr< PHiLiP::DGBase< dim, real >> dg_input, const bool uses_solution_values=true, const bool uses_solution_gradient=false)
Constructor. 
Sacado::Fad::DFad< real > FadType
Sacado AD type for first derivatives. 
static std::shared_ptr< DGBase< dim, real, MeshType > > create_discontinuous_galerkin(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Creates a derived object DG, but returns it as DGBase. 
real evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, real > &physics, const dealii::Point< dim, real > &phys_coord, const std::array< real, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_at_q) const override
Non-template functions to override the template classes. 
static std::shared_ptr< PhysicsBase< dim, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file. 
Functional(std::shared_ptr< PHiLiP::DGBase< dim, real, dealii::parallel::distributed::Triangulation< dim > >> _dg, const bool _uses_solution_values=true, const bool _uses_solution_gradient=true)
void parse_parameters(dealii::ParameterHandler &prm)
Retrieve parameters from dealii::ParameterHandler. 
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid. 
Sacado::Fad::DFad< FadType > FadFadType
Sacado AD type that allows 2nd derivatives. 
static void declare_parameters(dealii::ParameterHandler &prm)
Declare parameters that can be set as inputs and set up the default options. 
virtual real evaluate_boundary_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, real > &physics, const unsigned int boundary_id, const dealii::Point< dim, real > &phys_coord, const dealii::Tensor< 1, dim, real > &normal, const std::array< real, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_at_q) const override
Virtual function for computation of cell boundary functional term. 
std::shared_ptr< DGBase< dim, real, dealii::parallel::distributed::Triangulation< dim > > > dg
Smart pointer to DGBase. 
DGBase is independent of the number of state variables. 
std::shared_ptr< ManufacturedSolutionFunction< dim, real > > manufactured_solution_function
Manufactured solution function. 
virtual real evaluate_functional(const bool compute_dIdW=false, const bool compute_dIdX=false, const bool compute_d2I=false)
Evaluates the functional derivative with respect to the solution variable. 
real2 evaluate_boundary_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, real2 > &physics, const unsigned int, const dealii::Point< dim, real2 > &phys_coord, const dealii::Tensor< 1, dim, real2 > &, const std::array< real2, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &) const
Virtual function for computation of cell boundary functional term. 
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.