1 #include <deal.II/grid/grid_out.h> 2 #include <deal.II/grid/grid_in.h> 4 #include <deal.II/numerics/vector_tools.h> 6 #include "grid_refinement/gmsh_out.h" 7 #include "grid_refinement/msh_out.h" 8 #include "grid_refinement/size_field.h" 9 #include "grid_refinement/reconstruct_poly.h" 10 #include "grid_refinement/field.h" 12 #include "grid_refinement_continuous.h" 16 namespace GridRefinement {
19 template <
int dim,
int nstate>
25 double value(
const dealii::Point<dim> &,
const unsigned int )
const override 31 template <
int dim,
int nstate,
typename real,
typename MeshType>
39 adj_input->functional,
43 template <
int dim,
int nstate,
typename real,
typename MeshType>
56 template <
int dim,
int nstate,
typename real,
typename MeshType>
68 template <
int dim,
int nstate,
typename real,
typename MeshType>
80 template <
int dim,
int nstate,
typename real,
typename MeshType>
98 h_field = std::make_unique<FieldAnisotropic<dim,real>>();
100 h_field = std::make_unique<FieldIsotropic<dim,real>>();
113 + this->grid_refinement_param.complexity_add);
119 template <
int dim,
int nstate,
typename real,
typename MeshType>
131 if(refinement_type == RefinementTypeEnum::h){
133 }
else if(refinement_type == RefinementTypeEnum::p){
135 }
else if(refinement_type == RefinementTypeEnum::hp){
143 this->
dg->allocate_system();
146 std::shared_ptr<dealii::Function<dim>> initial_conditions =
147 std::make_shared<InitialConditions<dim,nstate>>();
149 dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
150 solution_no_ghost.reinit(this->
dg->locally_owned_dofs, MPI_COMM_WORLD);
151 const auto mapping = *(this->
dg->high_order_grid->mapping_fe_field);
152 dealii::VectorTools::interpolate(mapping, this->
dg->dof_handler, *initial_conditions, solution_no_ghost);
153 this->
dg->solution = solution_no_ghost;
159 template <
int dim,
int nstate,
typename real,
typename MeshType>
166 if(output_type == OutputType::gmsh_out){
168 }
else if(output_type == OutputType::msh_out){
174 template <
int dim,
int nstate,
typename real,
typename MeshType>
178 for(
auto cell = this->
dg->dof_handler.begin_active(); cell != this->
dg->dof_handler.end(); ++cell)
179 if(cell->is_locally_owned())
180 cell->set_future_fe_index(round(
p_field[cell->active_cell_index()]));
183 template <
int dim,
int nstate,
typename real,
typename MeshType>
193 template <
int dim,
int nstate,
typename real,
typename MeshType>
196 const int iproc = dealii::Utilities::MPI::this_mpi_process(this->
mpi_communicator);
199 std::string write_posname =
"grid-" +
200 dealii::Utilities::int_to_string(this->
iteration, 4) +
"." +
201 dealii::Utilities::int_to_string(iproc, 4) +
".pos";
202 std::ofstream outpos(write_posname);
207 const int poly_degree = this->
dg->get_max_fe_degree();
212 this->
h_field->get_inverse_quadratic_metric_vector(),
219 this->
h_field->get_scale_vector_dealii(),
224 std::string output_name =
"grid-" +
225 dealii::Utilities::int_to_string(this->
iteration, 4) +
".msh";
228 std::vector<std::string> posname_vec;
229 for(
unsigned int iproc = 0; iproc < dealii::Utilities::MPI::n_mpi_processes(this->
mpi_communicator); ++iproc)
230 posname_vec.push_back(
"grid-" +
231 dealii::Utilities::int_to_string(this->iteration, 4) +
"." +
232 dealii::Utilities::int_to_string(iproc, 4) +
".pos");
234 std::string write_geoname =
"grid-" +
235 dealii::Utilities::int_to_string(this->
iteration, 4) +
".geo";
236 std::ofstream outgeo(write_geoname);
261 dealii::GridIn<dim> gridin;
262 gridin.attach_triangulation(*(this->
tria));
263 std::ifstream f(output_name);
267 template <
int dim,
int nstate,
typename real,
typename MeshType>
275 using StorageType = PHiLiP::GridRefinement::StorageType;
276 StorageType storage_type = StorageType::element;
279 std::string write_msh_name =
"grid-a" +
280 dealii::Utilities::int_to_string(this->
iteration, 4) +
".msh";
282 std::ofstream out_msh(write_msh_name);
290 if(output_data_type == OutputDataType::size_field){
292 std::cout <<
"Writing the size_field to .msh file." << std::endl;
299 }
else if(output_data_type == OutputDataType::frame_field){
301 std::cout <<
"Writing the frame_field to .msh file." << std::endl;
304 for(
unsigned int j = 0; j < dim; ++j)
307 "frame_field_" + std::to_string(j));
310 }
else if(output_data_type == OutputDataType::metric_field){
312 std::cout <<
"Writing the metric_field to .msh file." << std::endl;
341 std::cout <<
".msh file written. (" <<
"/" << write_msh_name <<
")" << std::endl;
346 std::cout <<
"refine_grid_msh: read not supported, proceeding to results." << std::endl;
348 std::cout <<
"refine_grid_msh: read not supported, use option exit_after_refine to stop after .msh write." << std::endl;
353 template <
int dim,
int nstate,
typename real,
typename MeshType>
364 if(refinement_type == RefinementTypeEnum::h){
366 if(this->error_indicator_type == ErrorIndicatorEnum::error_based){
368 }
else if(this->error_indicator_type == ErrorIndicatorEnum::hessian_based){
370 }
else if(this->error_indicator_type == ErrorIndicatorEnum::residual_based){
372 }
else if(this->error_indicator_type == ErrorIndicatorEnum::adjoint_based){
375 }
else if(refinement_type == RefinementTypeEnum::p){
377 if(this->error_indicator_type == ErrorIndicatorEnum::error_based){
379 }
else if(this->error_indicator_type == ErrorIndicatorEnum::hessian_based){
381 }
else if(this->error_indicator_type == ErrorIndicatorEnum::residual_based){
383 }
else if(this->error_indicator_type == ErrorIndicatorEnum::adjoint_based){
386 }
else if(refinement_type == RefinementTypeEnum::hp){
388 if(this->error_indicator_type == ErrorIndicatorEnum::error_based){
390 }
else if(this->error_indicator_type == ErrorIndicatorEnum::hessian_based){
392 }
else if(this->error_indicator_type == ErrorIndicatorEnum::residual_based){
394 }
else if(this->error_indicator_type == ErrorIndicatorEnum::adjoint_based){
400 template <
int dim,
int nstate,
typename real,
typename MeshType>
416 template <
int dim,
int nstate,
typename real,
typename MeshType>
422 if(this->
dg->get_min_fe_degree() == this->
dg->get_max_fe_degree()){
424 unsigned int poly_degree = this->
dg->get_min_fe_degree();
425 return pow(poly_degree+1, dim) * this->
tria->n_global_active_cells();
428 for(
auto cell = this->
dg->dof_handler.begin_active(); cell != this->
dg->dof_handler.end(); ++cell)
429 if(cell->is_locally_owned())
430 complexity_sum += pow(cell->active_fe_index()+1, dim);
433 return dealii::Utilities::MPI::sum(complexity_sum, MPI_COMM_WORLD);
436 template <
int dim,
int nstate,
typename real,
typename MeshType>
441 this->
h_field->reinit(this->
tria->n_active_cells());
442 for(
auto cell = this->
dg->dof_handler.begin_active(); cell != this->
dg->dof_handler.end(); ++cell)
443 if(cell->is_locally_owned())
444 this->
h_field->set_scale(cell->active_cell_index(), pow(cell->measure(), 1.0/dim));
447 template <
int dim,
int nstate,
typename real,
typename MeshType>
452 for(
auto cell = this->
dg->dof_handler.begin_active(); cell != this->
dg->dof_handler.end(); ++cell)
453 if(cell->is_locally_owned())
454 this->
p_field[cell->active_cell_index()] = cell->active_fe_index();
457 template <
int dim,
int nstate,
typename real,
typename MeshType>
462 dealii::Vector<real> B(this->
tria->n_active_cells());
463 for(
auto cell = this->
dg->dof_handler.begin_active(); cell != this->
dg->dof_handler.end(); ++cell){
464 if(!cell->is_locally_owned())
continue;
467 dealii::Point<dim,real> center_point = cell->center();
470 dealii::SymmetricTensor<2,dim,real> hessian =
471 this->
physics->manufactured_solution_function->hessian(center_point);
476 B[cell->active_cell_index()] =
477 pow(abs(hessian[0][0]*hessian[1][1] - hessian[0][1]*hessian[1][0]), q/2);
481 if(this->
dg->get_min_fe_degree() == this->
dg->get_max_fe_degree()){
482 unsigned int poly_degree = this->
dg->get_min_fe_degree();
488 this->
dg->dof_handler,
497 const dealii::hp::MappingCollection<dim> mapping_collection(*(this->
dg->high_order_grid->mapping_fe_field));
502 this->
dg->dof_handler,
504 this->dg->fe_collection,
505 this->dg->volume_quadrature_collection,
506 this->volume_update_flags,
513 template <
int dim,
int nstate,
typename real,
typename MeshType>
519 template <
int dim,
int nstate,
typename real,
typename MeshType>
526 template <
int dim,
int nstate,
typename real,
typename MeshType>
530 std::cout <<
"Beggining field_h() computation" << std::endl;
533 const dealii::hp::MappingCollection<dim> mapping_collection(*(this->
dg->high_order_grid->mapping_fe_field));
536 const unsigned int rel_order = 1;
540 this->
dg->dof_handler,
542 this->dg->fe_collection,
543 this->dg->volume_quadrature_collection,
544 this->volume_update_flags);
556 std::cout <<
"Setting cell anisotropy" << std::endl;
560 this->
dg->dof_handler,
565 std::cout <<
"Applying anisotropy limits: \\rho = [" <<
569 this->
h_field->apply_anisotropic_limit(
571 this->grid_refinement_param.anisotropic_ratio_max);
576 dealii::Vector<real> B(this->
tria->n_active_cells());
579 for(
auto cell = this->
dg->dof_handler.begin_active(); cell < this->
dg->dof_handler.end(); ++cell)
580 if(cell->is_locally_owned()){
581 B[cell->active_cell_index()] = 1.0;
582 for(
unsigned int d = 0; d < dim; ++d)
583 B[cell->active_cell_index()] *= reconstruct_poly.
derivative_value[cell->active_cell_index()][d];
591 if(this->
dg->get_min_fe_degree() == this->
dg->get_max_fe_degree()){
592 unsigned int poly_degree = this->
dg->get_min_fe_degree();
597 this->
dg->dof_handler,
608 this->
dg->dof_handler,
610 this->dg->fe_collection,
611 this->dg->volume_quadrature_collection,
612 this->volume_update_flags,
619 template <
int dim,
int nstate,
typename real,
typename MeshType>
625 template <
int dim,
int nstate,
typename real,
typename MeshType>
632 template <
int dim,
int nstate,
typename real,
typename MeshType>
638 template <
int dim,
int nstate,
typename real,
typename MeshType>
644 template <
int dim,
int nstate,
typename real,
typename MeshType>
651 template <
int dim,
int nstate,
typename real,
typename MeshType>
655 std::cout <<
"Beggining anisotropic field_h() computation" << std::endl;
658 const dealii::hp::MappingCollection<dim> mapping_collection(*(this->
dg->high_order_grid->mapping_fe_field));
661 const unsigned int rel_order = 1;
665 this->
dg->dof_handler,
667 this->dg->fe_collection,
668 this->dg->volume_quadrature_collection,
669 this->volume_update_flags);
678 std::cout <<
"Setting cell anisotropy" << std::endl;
682 this->
dg->dof_handler,
687 std::cout <<
"Applying anisotropy limits: \\rho = [" <<
691 this->
h_field->apply_anisotropic_limit(
693 this->grid_refinement_param.anisotropic_ratio_max);
698 this->
adjoint->fine_grid_adjoint();
699 this->
adjoint->dual_weighted_residual();
700 dealii::Vector<real> dwr = this->
adjoint->dual_weighted_residual_fine;
706 if(this->
dg->get_min_fe_degree() == this->
dg->get_max_fe_degree()){
707 unsigned int poly_degree = this->
dg->get_min_fe_degree();
713 this->grid_refinement_param.c_max,
715 this->dg->dof_handler,
717 this->dg->fe_collection,
718 this->dg->volume_quadrature_collection,
719 this->volume_update_flags,
741 this->grid_refinement_param.c_max,
743 this->dg->dof_handler,
745 this->dg->fe_collection,
746 this->dg->volume_quadrature_collection,
747 this->volume_update_flags,
754 template <
int dim,
int nstate,
typename real,
typename MeshType>
760 template <
int dim,
int nstate,
typename real,
typename MeshType>
767 template <
int dim,
int nstate,
typename real,
typename MeshType>
770 std::vector< std::pair<dealii::Vector<real>, std::string> > data_out_vector;
774 data_out_vector.push_back(
776 this->
h_field->get_scale_vector_dealii(),
780 data_out_vector.push_back(
787 data_out_vector.push_back(
789 this->
h_field->get_scale_vector_dealii(),
792 data_out_vector.push_back(
800 data_out_vector.push_back(
802 this->
h_field->get_max_anisotropic_ratio_vector_dealii(),
803 "anisotropic_ratio_next"));
807 const dealii::hp::MappingCollection<dim> mapping_collection(*(this->
dg->high_order_grid->mapping_fe_field));
810 const unsigned int rel_order = 1;
814 this->
dg->dof_handler,
816 this->dg->fe_collection,
817 this->dg->volume_quadrature_collection,
818 this->volume_update_flags);
829 for(
unsigned int i = 0; i < dim; ++i)
830 data_out_vector.push_back(
833 "derivative_value_" + dealii::Utilities::int_to_string(i, 1)));
837 return data_out_vector;
Output class for GMSH .msh v4.1 file format.
void field_h_error()
Generate mesh distribution based on manufactured solution.
static void adjoint_uniform_balan(const real complexity, const real r_max, const real c_max, const dealii::Vector< real > &eta, const dealii::DoFHandler< dim > &dof_handler, const dealii::hp::MappingCollection< dim > &mapping_collection, const dealii::hp::FECollection< dim > &fe_collection, const dealii::hp::QCollection< dim > &quadrature_collection, const dealii::UpdateFlags &update_flags, std::unique_ptr< Field< dim, real >> &h_field, const real &poly_degree)
Performs adjoint based size field adaptation for uniform polynomial distribution based on the method ...
void target_complexity()
Updates the complexity target based on the current refinement iteration.
std::unique_ptr< Field< dim, real > > h_field
Continuous representation of the mesh size and anisotropy distribution.
std::vector< std::array< dealii::Tensor< 1, dim, real >, dim > > derivative_direction
Derivative directions.
RefinementType refinement_type
Selected type of refinement to be performed.
void add_data_vector(std::vector< T > data, StorageType storage_type)
Add data vector of specified storage type and values.
Polynomial Reconstruction Class.
ErrorIndicator
Types of error indicator to be used in the grid refinement.
static void isotropic_h(const real complexity, const dealii::Vector< real > &B, const dealii::DoFHandler< dim > &dof_handler, const dealii::hp::MappingCollection< dim > &mapping_collection, const dealii::hp::FECollection< dim > &fe_collection, const dealii::hp::QCollection< dim > &quadrature_collection, const dealii::UpdateFlags &update_flags, std::unique_ptr< Field< dim, real >> &h_field, const dealii::Vector< real > &p_field)
Computes the size field (element scale) for a potentially non-uniform - distribution.
double r_max
refinement factor for log DWR size field
PHiLiP::Parameters::GridRefinementParam grid_refinement_param
Grid refinement parameters.
OutputType
File type/interface to be used for access to external tools.
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.
void refine_grid_msh()
Generates an output .msh file with matrix information about the target frame field.
std::shared_ptr< MeshType > tria
Triangulation object of templated mesh type.
Files for the baseline physics.
void write_msh(std::ostream &out)
Output formatted .msh v4.1 file with mesh description and data field.
void refine_grid_p()
Updates the global polynomial distribution based on the target -field.
unsigned int iteration
Internal refinement steps iteration counter.
void reconstruct_directional_derivative(const dealii::LinearAlgebra::distributed::Vector< real > &solution, const unsigned int rel_order)
Construct the set of largest perpendicular directional derivatives.
GridRefinement_Continuous(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.
void field_hp_error()
(NOT IMPLEMENTED) Generate mesh and polynomial distribution based on manufactured solution ...
OutputDataType
Method of data storage in the output file for continuous methods.
std::vector< std::array< real, dim > > derivative_value
Derivative values.
void field_hp_residual()
(NOT IMPLEMENTED) Generate mesh and polynomial distribution based on fine-grid residual distribution ...
void field_hp_hessian()
(NOT IMPLEMENTED) Generate mesh and polynomial distribution based on directional derivatives ...
void field()
Updates the continuous mesh and polynomial distribution.
void get_current_field_p()
Evaluates the polynomial distribution for the current mesh.
real complexity_target
Current complexity target.
void refine_grid_gmsh()
Generates a new mesh based on GMSH using .pos and .geo files for i/o.
real current_complexity()
Evaluates the current complexity of the mesh.
bool anisotropic
Flag for performing anisotropic refinement.
void field_p_hessian()
(NOT IMPLEMENTED) Generate polynomial distribution based on directinal derivatives ...
Continuous Grid Refinement Class.
Base Grid Refinement Class.
static void write_geo(std::vector< std::string > &posFile_vec, std::ostream &out)
Writes the central .geo file for call to GMSH on main process with isotropic quad meshing...
std::shared_ptr< PHiLiP::DGBase< dim, real, MeshType > > dg
Discontinuous Galerkin object.
void field_hp_adjoint()
(NOT IMPLEMENTED) Generate mesh and polynomial distribution based on dual-weighted residual distribut...
void field_p_residual()
(NOT IMPLEMENTED) Generate polynomial distribution based on fine-grid residual distribution ...
void refine_grid() override
Perform call to the grid refinement object of choice.
void field_p_error()
(NOT IMPLEMENTED) Generate polynomial distribution based on manufactured solution ...
dealii::Vector< real > p_field
Continuous representation of the polynomial distribution.
dealii::Vector< real > get_derivative_value_vector_dealii(const unsigned int index)
Gets the i^th largest componet of the directional derivative vector as a dealii::Vector.
static void write_pos_anisotropic(const dealii::Triangulation< dim, dim > &tria, const std::vector< dealii::SymmetricTensor< 2, dim, real >> &data, std::ostream &out, const int p_scale=1)
Write anisotropic tensor .pos file for use with GMSH.
double complexity_add
additive constant to complexity between grid refinement iterations
static void write_geo_anisotropic(std::vector< std::string > &posFile_vec, std::ostream &out)
Writes the central .geo file for call to GMSH on main process with anisotropic quad meshing...
RefinementType
Controls the type of refinement to be performed.
bool exit_after_refine
Flag to exit after call to refinement.
OutputDataType output_data_type
Selected data storage type.
static void isotropic_uniform(const real &complexity, const dealii::Vector< real > &B, const dealii::DoFHandler< dim > &dof_handler, std::unique_ptr< Field< dim, real >> &h_field, const real &poly_degree)
Computes the size field (element scale) for a uniform - distribution.
static void write_pos(const dealii::Triangulation< dim, dim > &tria, dealii::Vector< real > data, std::ostream &out)
Write scalar .pos file for use with GMSH.
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)
real complexity_initial
Initial mesh complexity at construction.
void field_p_adjoint()
(NOT IMPLEMENTED) Generate polynomial distribution based on dual-weighted residual distribution ...
void field_h_adjoint()
Generate mesh distribution based on dual-weighted residual distribution.
std::vector< std::pair< dealii::Vector< real >, std::string > > output_results_vtk_method() override
Output refinement method dependent results.
double anisotropic_ratio_max
Maximum anisotropic ratio for continuous size field targets.
void refine_grid_h()
Performs call to global remeshing method.
void field_h_hessian()
Generate mesh distribution based on directional derivatives.
void refine_grid_hp()
(NOT IMPLEMENTED) Performs call to global remeshing method with updated polynomial distribution ...
static void adjoint_h_balan(const real complexity, const real r_max, const real c_max, const dealii::Vector< real > &eta, const dealii::DoFHandler< dim > &dof_handler, const dealii::hp::MappingCollection< dim > &mapping_collection, const dealii::hp::FECollection< dim > &fe_collection, const dealii::hp::QCollection< dim > &quadrature_collection, const dealii::UpdateFlags &update_flags, std::unique_ptr< Field< dim, real >> &h_field, const dealii::Vector< real > &p_field)
Performs adjoint based size field adaptation for non-uniform polynomial distribution based on the met...
double anisotropic_ratio_min
Minimum anisotropic ratio for continuous zie field targets.
DGBase is independent of the number of state variables.
std::vector< double > complexity_vector
Vector of complexities to be used for initial continuous grid refinement iterations.
double complexity_scale
multiplier to complexity between grid refinement iterations
void get_current_field_h()
Evaluates the mesh size and ansitropy description for the current mesh.
std::vector< real > complexity_vector
Vector of complexity target goals for each iteration.
void field_h_residual()
(NOT IMPLEMENTED) Generate mesh distribution based on fine-grid residual distribution ...
MPI_Comm mpi_communicator
MPI communicator.
OutputType output_type
Selected file output type.