1 #include "grid_refinement.h"     3 #include <deal.II/base/quadrature_lib.h>     4 #include <deal.II/distributed/grid_refinement.h>     5 #include <deal.II/distributed/shared_tria.h>     6 #include <deal.II/distributed/tria.h>     7 #include <deal.II/dofs/dof_tools.h>     8 #include <deal.II/fe/fe_values.h>     9 #include <deal.II/grid/grid_in.h>    10 #include <deal.II/grid/grid_out.h>    11 #include <deal.II/grid/grid_refinement.h>    12 #include <deal.II/grid/tria.h>    13 #include <deal.II/numerics/data_out.h>    17 #include "dg/dg_base.hpp"    18 #include "functional/adjoint.h"    19 #include "functional/functional.h"    20 #include "grid_refinement/field.h"    21 #include "grid_refinement/gmsh_out.h"    22 #include "grid_refinement/grid_refinement_continuous.h"    23 #include "grid_refinement/grid_refinement_fixed_fraction.h"    24 #include "grid_refinement/grid_refinement_uniform.h"    25 #include "grid_refinement/msh_out.h"    26 #include "grid_refinement/reconstruct_poly.h"    27 #include "grid_refinement/size_field.h"    28 #include "mesh/high_order_grid.h"    29 #include "parameters/all_parameters.h"    30 #include "parameters/parameters_grid_refinement.h"    31 #include "physics/physics.h"    32 #include "post_processor/physics_post_processor.h"    36 namespace GridRefinement {
    39 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
    43     dealii::DataOut<dim, dealii::DoFHandler<dim>> data_out;
    44     data_out.attach_dof_handler(dg->dof_handler);
    47     std::shared_ptr< dealii::DataPostprocessor<dim> > post_processor;
    48     dealii::Vector<float>                             subdomain;
    49     std::vector<unsigned int>                         active_fe_indices;
    50     dealii::Vector<double>                            cell_poly_degree;
    51     std::vector<std::string>                          residual_names;
    53         output_results_vtk_dg(data_out, post_processor, subdomain, active_fe_indices, cell_poly_degree, residual_names);
    58         output_results_vtk_functional(data_out);
    62         output_results_vtk_physics(data_out);
    75     dealii::Vector<real> l2_error_vec;
    76     if(physics && physics->manufactured_solution_function)
    77         output_results_vtk_error(data_out, l2_error_vec);
    81     std::vector< std::pair<dealii::Vector<real>, std::string> > data_out_vector = output_results_vtk_method();
    84     for(
unsigned int index = 0; index < data_out_vector.size(); index++){
    85         data_out.add_data_vector(
    86             data_out_vector[index].first,
    87             data_out_vector[index].second,
    88             dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
    92     const int iproc = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
    95     data_out.build_patches();
   107     std::string filename = 
"gridRefinement-"   109                          + dealii::Utilities::int_to_string(iref, 4) + 
"."   110                          + dealii::Utilities::int_to_string(iteration, 4) + 
"."   111                          + dealii::Utilities::int_to_string(iproc, 4) + 
".vtu";
   112     std::ofstream output(filename);
   113     data_out.write_vtu(output);
   117         std::vector<std::string> filenames;
   118         for(
unsigned int iproc = 0; iproc < dealii::Utilities::MPI::n_mpi_processes(mpi_communicator); ++iproc){
   119             std::string fn = 
"gridRefinement-"   121                              + dealii::Utilities::int_to_string(iref, 4) + 
"."   122                              + dealii::Utilities::int_to_string(iteration, 4) + 
"."   123                              + dealii::Utilities::int_to_string(iproc, 4) + 
".vtu";
   124             filenames.push_back(fn);
   127         std::string master_filename = 
"gridRefinement-"   129                                       + dealii::Utilities::int_to_string(iref, 4) + 
"."   130                                       + dealii::Utilities::int_to_string(iteration, 4) + 
".pvtu";
   131         std::ofstream master_output(master_filename);
   132         data_out.write_pvtu_record(master_output, filenames);
   137 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   139     dealii::DataOut<dim, dealii::DoFHandler<dim>> &    data_out,
   140     std::shared_ptr< dealii::DataPostprocessor<dim> > &post_processor,
   141     dealii::Vector<float> &                            subdomain,
   142     std::vector<unsigned int> &                        active_fe_indices,
   143     dealii::Vector<double> &                           cell_poly_degree,
   144     std::vector<std::string> &                         residual_names)
   146     post_processor = std::make_shared< PHiLiP::Postprocess::PhysicsPostprocessor<dim,nstate> >(dg->all_parameters);
   147     data_out.add_data_vector(dg->solution, *post_processor);
   149     subdomain.reinit(dg->triangulation->n_active_cells());
   150     for (
unsigned int i = 0; i < subdomain.size(); ++i) {
   151         subdomain(i) = dg->triangulation->locally_owned_subdomain();
   153     data_out.add_data_vector(subdomain, 
"subdomain", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
   156     dg->dof_handler.get_active_fe_indices(active_fe_indices);
   157     dealii::Vector<double> active_fe_indices_dealiivector(active_fe_indices.begin(), active_fe_indices.end());
   158     cell_poly_degree = active_fe_indices_dealiivector;
   160     data_out.add_data_vector(cell_poly_degree, 
"PolynomialDegree", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
   162     for(
int s=0;s<nstate;++s) {
   163         std::string varname = 
"residual" + dealii::Utilities::int_to_string(s,1);
   164         residual_names.push_back(varname);
   167     data_out.add_data_vector(dg->right_hand_side, residual_names, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
   170 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   172     dealii::DataOut<dim, dealii::DoFHandler<dim>> &data_out)
   178 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   180     dealii::DataOut<dim, dealii::DoFHandler<dim>> &data_out)
   186 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   188     dealii::DataOut<dim, dealii::DoFHandler<dim>> &data_out,
   189     std::vector<std::string> &                     dIdw_names_coarse,
   190     std::vector<std::string> &                     adjoint_names_coarse,
   191     std::vector<std::string> &                     dIdw_names_fine,
   192     std::vector<std::string> &                     adjoint_names_fine)
   196     adjoint->coarse_grid_adjoint();
   198     for(
int s=0;s<nstate;++s) {
   199         std::string varname = 
"dIdw" + dealii::Utilities::int_to_string(s,1) + 
"_coarse";
   200         dIdw_names_coarse.push_back(varname);
   202     data_out.add_data_vector(adjoint->dIdw_coarse, dIdw_names_coarse, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
   204     for(
int s=0;s<nstate;++s) {
   205         std::string varname = 
"psi" + dealii::Utilities::int_to_string(s,1) + 
"_coarse";
   206         adjoint_names_coarse.push_back(varname);
   208     data_out.add_data_vector(adjoint->adjoint_coarse, adjoint_names_coarse, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
   211     adjoint->fine_grid_adjoint();
   212     adjoint->dual_weighted_residual();
   214     for(
int s=0;s<nstate;++s) {
   215         std::string varname = 
"dIdw" + dealii::Utilities::int_to_string(s,1) + 
"_fine";
   216         dIdw_names_fine.push_back(varname);
   220     for(
int s=0;s<nstate;++s) {
   221         std::string varname = 
"psi" + dealii::Utilities::int_to_string(s,1) + 
"_fine";
   222         adjoint_names_fine.push_back(varname);
   226     data_out.add_data_vector(adjoint->dual_weighted_residual_fine, 
"DWR", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
   232 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   234     dealii::DataOut<dim, dealii::DoFHandler<dim>> &data_out,
   235     dealii::Vector<real> &                             l2_error_vec)
   237     int overintegrate = 10;
   238     int poly_degree = dg->get_max_fe_degree();
   239     dealii::QGauss<dim> quad_extra(dg->max_degree+overintegrate);
   240     dealii::FEValues<dim,dim> fe_values_extra(*(dg->high_order_grid->mapping_fe_field), dg->fe_collection[poly_degree], quad_extra, 
   241         dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
   242     const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
   243     std::array<real,nstate> soln_at_q;
   244     std::vector<dealii::types::global_dof_index> dofs_indices (fe_values_extra.dofs_per_cell);
   247     l2_error_vec.reinit(tria->n_active_cells());
   248     for(
auto cell = dg->dof_handler.begin_active(); cell < dg->dof_handler.end(); ++cell){
   249         if(!cell->is_locally_owned()) 
continue;
   251         fe_values_extra.reinit(cell);
   252         cell->get_dof_indices(dofs_indices);
   254         real cell_l2_error   = 0.0;
   256         for(
unsigned int iquad = 0; iquad < n_quad_pts; ++iquad){
   257             std::fill(soln_at_q.begin(), soln_at_q.end(), 0);
   258             for(
unsigned int idof = 0; idof < fe_values_extra.dofs_per_cell; ++idof){
   259                 const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
   260                 soln_at_q[istate] += dg->solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
   263             const dealii::Point<dim> qpoint = (fe_values_extra.quadrature_point(iquad));
   265             for(
unsigned int istate = 0; istate < nstate; ++istate){
   266                 const double uexact = physics->manufactured_solution_function->value(qpoint, istate);
   267                 cell_l2_error += pow(soln_at_q[istate] - uexact, 2) * fe_values_extra.JxW(iquad);
   271         l2_error_vec[cell->active_cell_index()] += cell_l2_error;
   274     data_out.add_data_vector(l2_error_vec, 
"l2_error", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
   278 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   286             adj_input->functional, 
   290 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   303 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   315 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   327 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   335         error_indicator_type(gr_param_input.error_indicator),
   340         tria(dg_input->triangulation),
   349 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   350 std::shared_ptr< GridRefinementBase<dim,nstate,real,MeshType> > 
   363     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   364        error_indicator   == ErrorIndicatorEnum::adjoint_based){
   365         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   366     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   367              error_indicator   == ErrorIndicatorEnum::adjoint_based){
   368         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   372     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   373        error_indicator   == ErrorIndicatorEnum::hessian_based){
   374         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   375     }
else if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   376              error_indicator   == ErrorIndicatorEnum::error_based){
   377         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   378     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   379              error_indicator   == ErrorIndicatorEnum::hessian_based){
   380         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   381     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   382              error_indicator   == ErrorIndicatorEnum::error_based){
   383         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   387     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   388        error_indicator   == ErrorIndicatorEnum::residual_based){
   389         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   390     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   391              error_indicator   == ErrorIndicatorEnum::residual_based){
   392         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   393     }
else if(refinement_method == RefinementMethodEnum::uniform){
   394         return std::make_shared< GridRefinement_Uniform<dim,nstate,real,MeshType> >(gr_param, adj, 
physics);
   397     return create_GridRefinement(gr_param, adj->dg, 
physics, adj->functional);
   401 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   402 std::shared_ptr< GridRefinementBase<dim,nstate,real,MeshType> > 
   416     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   417        error_indicator   == ErrorIndicatorEnum::hessian_based){
   418         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   419     }
else if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   420              error_indicator   == ErrorIndicatorEnum::error_based){
   421         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   422     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   423              error_indicator   == ErrorIndicatorEnum::hessian_based){
   424         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   425     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   426              error_indicator   == ErrorIndicatorEnum::error_based){
   427         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   431     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   432        error_indicator   == ErrorIndicatorEnum::residual_based){
   433         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   434     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   435              error_indicator   == ErrorIndicatorEnum::residual_based){
   436         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   437     }
else if(refinement_method == RefinementMethodEnum::uniform){
   438         return std::make_shared< GridRefinement_Uniform<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics, 
functional);
   441     return create_GridRefinement(gr_param, 
dg, 
physics);
   445 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   446 std::shared_ptr< GridRefinementBase<dim,nstate,real,MeshType> > 
   459     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   460        error_indicator   == ErrorIndicatorEnum::hessian_based){
   461         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   462     }
else if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   463              error_indicator   == ErrorIndicatorEnum::error_based){
   464         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   465     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   466              error_indicator   == ErrorIndicatorEnum::hessian_based){
   467         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   468     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   469              error_indicator   == ErrorIndicatorEnum::error_based){
   470         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   474     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   475        error_indicator   == ErrorIndicatorEnum::residual_based){
   476         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   477     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   478              error_indicator   == ErrorIndicatorEnum::residual_based){
   479         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   480     }
else if(refinement_method == RefinementMethodEnum::uniform){
   481         return std::make_shared< GridRefinement_Uniform<dim,nstate,real,MeshType> >(gr_param, 
dg, 
physics);
   484     return create_GridRefinement(gr_param, 
dg);
   488 template <
int dim, 
int nstate, 
typename real, 
typename MeshType>
   489 std::shared_ptr< GridRefinementBase<dim,nstate,real,MeshType> > 
   500     if(refinement_method == RefinementMethodEnum::fixed_fraction &&
   501        error_indicator   == ErrorIndicatorEnum::residual_based){
   502         return std::make_shared< GridRefinement_FixedFraction<dim,nstate,real,MeshType> >(gr_param, 
dg);
   503     }
else if(refinement_method == RefinementMethodEnum::continuous &&
   504              error_indicator   == ErrorIndicatorEnum::residual_based){
   505         return std::make_shared< GridRefinement_Continuous<dim,nstate,real,MeshType> >(gr_param, 
dg);
   506     }
else if(refinement_method == RefinementMethodEnum::uniform){
   507         return std::make_shared< GridRefinement_Uniform<dim,nstate,real,MeshType> >(gr_param, 
dg);
   510     std::cout << 
"Invalid GridRefinement." << std::endl;
 ErrorIndicator
Types of error indicator to be used in the grid refinement. 
PHiLiP::Parameters::GridRefinementParam grid_refinement_param
Grid refinement parameters. 
std::shared_ptr< PHiLiP::Adjoint< dim, nstate, real, MeshType > > adjoint
Adjoint object (if provided to factory) 
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived. 
std::shared_ptr< MeshType > tria
Triangulation object of templated mesh type. 
void output_results_vtk_physics(dealii::DataOut< dim, dealii::DoFHandler< dim >> &data_out)
Output refinement results related to the problem physics. 
Files for the baseline physics. 
void output_results_vtk_adjoint(dealii::DataOut< dim, dealii::DoFHandler< dim >> &data_out, std::vector< std::string > &dIdw_names_coarse, std::vector< std::string > &adjoint_names_coarse, std::vector< std::string > &dIdw_names_fine, std::vector< std::string > &adjoint_names_fine)
Output refinement results related to the adjoint object. 
unsigned int iteration
Internal refinement steps iteration counter. 
RefinementMethod
Controls the underlying method of refinement. 
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0. 
ErrorIndicator error_indicator
Selected error indicator type. 
std::shared_ptr< PHiLiP::Functional< dim, nstate, real, MeshType > > functional
Functional object (if provided to factory, directly or indirectly) 
void output_results_vtk_error(dealii::DataOut< dim, dealii::DoFHandler< dim >> &data_out, dealii::Vector< real > &l2_error_vec)
Output refinement results related to the solution error. 
RefinementMethod refinement_method
Selected method of refinement. 
Base Grid Refinement Class. 
std::shared_ptr< PHiLiP::DGBase< dim, real, MeshType > > dg
Discontinuous Galerkin object. 
void output_results_vtk(const unsigned int iref)
Write information about the grid refinement step to a .vtk file. 
void output_results_vtk_functional(dealii::DataOut< dim, dealii::DoFHandler< dim >> &data_out)
Output refinement results related to the functional object. 
Parameters related to individual grid refinement run. 
std::shared_ptr< PHiLiP::Physics::PhysicsBase< dim, nstate, real > > physics
Problem physics (if provided to factory, directly or indirectly) 
static std::shared_ptr< GridRefinementBase< dim, nstate, real, MeshType > > create_GridRefinement(PHiLiP::Parameters::GridRefinementParam gr_param, std::shared_ptr< PHiLiP::Adjoint< dim, nstate, real, MeshType > > adj, std::shared_ptr< PHiLiP::Physics::PhysicsBase< dim, nstate, real > > physics_input)
Construct grid refinement class based on adjoint and physics. 
GridRefinementBase(PHiLiP::Parameters::GridRefinementParam gr_param_input, std::shared_ptr< PHiLiP::Adjoint< dim, nstate, real, MeshType > > adj_input, std::shared_ptr< PHiLiP::Physics::PhysicsBase< dim, nstate, real > > physics_input)
Constructor. Stores the adjoint object, physics and parameters. 
Grid Refinement Class Factory. 
DGBase is independent of the number of state variables. 
void output_results_vtk_dg(dealii::DataOut< dim, dealii::DoFHandler< dim >> &data_out, std::shared_ptr< dealii::DataPostprocessor< dim > > &post_processor, dealii::Vector< float > &subdomain, std::vector< unsigned int > &active_fe_indices, dealii::Vector< double > &cell_poly_degree, std::vector< std::string > &residual_names)
Output refinement results related to the DG object. 
MPI_Comm mpi_communicator
MPI communicator.