Skip to content

Commit 4a143d8

Browse files
cpethrickjbrillon
andauthored
Time Refinement Study using flow_solver (#138)
* First commit for creating a time refinement study based on the flow_solver framework [does not build] * Flow solver runs 1D advection for one time-step size * Time refinement implemented and working * Writing convergence summary at each refinement * Bug fixes - test now runs as before * Adding exact solution [has bugs] * Bug fixes from previous commit * Results replicate 1D_explicit_ode_solver * Reorganized files and removed 1D_explicit_ode_solver test by removing directory from CMakeLists.txt * clean files/comments/naming * Renamed calculate_L2_error_at_final_time() --> calculate_L2_error_at_final_time_wrt_function() in anticipation of comparing to a reference solution' * Moved grid generation into straight_periodic_cube.cppw * Minor changes (comments, naming, minor functional changes) according to PR comments * Changed tolerance to 1E-13 rather than 0.5 dt for exiting the while loop in run_test() * Periodic1DFlow class now derives from PeriodicCubeFlow. Removed periodic_1D_flow.<cpp/h>. * Update src/testing/time_refinement_study_advection.cpp Co-authored-by: Julien Brillon <43619715+jbrillon@users.noreply.github.com> * Renamed TimeRefinementStudyAdvection --> TimeRefinementStudy * Moved calculate_L2_error_at_final_time_wrt_function() into TimeRefinementStudy * Added error check that initial_time_step evenly divides final_time * Renaming files and small changes as per PR comments * Added time refinement study section to parameters; only passing FlowSolverParams in create_ExactSolutionFunction() * Fixed as per PR comments: createExactSolution now takes time argument; Periodic1DUnsteady renamed and moved into separate files; a few minor fixes * Bug fixes from merge * Update src/testing/time_refinement_study.cpp Co-authored-by: Julien Brillon <43619715+jbrillon@users.noreply.github.com> * Update src/mesh/grids/straight_periodic_cube.cpp Co-authored-by: Julien Brillon <43619715+jbrillon@users.noreply.github.com> * Changes as per PR comments: remove extra #include lines, initialize t in member initializer list, fix comments Co-authored-by: Julien Brillon <43619715+jbrillon@users.noreply.github.com>
1 parent b13f5ff commit 4a143d8

27 files changed

+648
-23
lines changed

src/mesh/grids/straight_periodic_cube.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,36 @@ void straight_periodic_cube(std::shared_ptr<TriangulationType> &grid,
2424

2525
// Definition for each type of grid
2626
std::string grid_type_string;
27-
if(dim==3) {
27+
const bool colorize = true;
28+
dealii::GridGenerator::hyper_cube(*grid, domain_left, domain_right, colorize);
29+
if constexpr(dim == 1){
30+
grid_type_string = "Periodic 1D domain.";
31+
std::vector<dealii::GridTools::PeriodicFacePair<typename TriangulationType::cell_iterator> > matched_pairs;
32+
dealii::GridTools::collect_periodic_faces(*grid,0,1,0,matched_pairs);
33+
grid->add_periodicity(matched_pairs);
34+
}else if constexpr(dim==2) {
35+
grid_type_string = "Doubly periodic square.";
36+
std::vector<dealii::GridTools::PeriodicFacePair<typename dealii::Triangulation<dim>::cell_iterator> > matched_pairs;
37+
dealii::GridTools::collect_periodic_faces(*grid,0,1,0,matched_pairs);
38+
dealii::GridTools::collect_periodic_faces(*grid,2,3,1,matched_pairs);
39+
grid->add_periodicity(matched_pairs);
40+
}else if constexpr(dim==3) {
2841
grid_type_string = "Triply periodic cube.";
29-
const bool colorize = true;
30-
dealii::GridGenerator::hyper_cube(*grid, domain_left, domain_right, colorize);
3142
std::vector<dealii::GridTools::PeriodicFacePair<typename dealii::Triangulation<dim>::cell_iterator> > matched_pairs;
3243
dealii::GridTools::collect_periodic_faces(*grid,0,1,0,matched_pairs);
3344
dealii::GridTools::collect_periodic_faces(*grid,2,3,1,matched_pairs);
3445
dealii::GridTools::collect_periodic_faces(*grid,4,5,2,matched_pairs);
3546
grid->add_periodicity(matched_pairs);
36-
grid->refine_global(number_of_refinements);
37-
}
38-
else {
39-
std::cout << " ERROR: straight_periodic_cube() cannot be called for dim!=3 " << std::endl;
40-
std::abort();
4147
}
48+
grid->refine_global(number_of_refinements);
4249
}
4350

44-
template void straight_periodic_cube<3, dealii::parallel::distributed::Triangulation<3>> (std::shared_ptr<dealii::parallel::distributed::Triangulation<3>> &grid, const double domain_left, const double domain_right, const int number_of_cells_per_direction);
51+
#if PHILIP_DIM==1
52+
template void straight_periodic_cube<PHILIP_DIM, dealii::Triangulation<PHILIP_DIM>> (std::shared_ptr<dealii::Triangulation<PHILIP_DIM>> &grid, const double domain_left, const double domain_right, const int number_of_cells_per_direction);
53+
#endif
54+
#if PHILIP_DIM!=1
55+
template void straight_periodic_cube<PHILIP_DIM, dealii::parallel::distributed::Triangulation<PHILIP_DIM>> (std::shared_ptr<dealii::parallel::distributed::Triangulation<PHILIP_DIM>> &grid, const double domain_left, const double domain_right, const int number_of_cells_per_direction);
56+
#endif
4557

4658
} // namespace Grids
47-
} // namespace PHiLiP
59+
} // namespace PHiLiP

src/parameters/all_parameters.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ void AllParameters::declare_parameters (dealii::ParameterHandler &prm)
116116
" flow_solver | "
117117
" dual_weighted_residual_mesh_adaptation | "
118118
" taylor_green_vortex_energy_check | "
119-
" taylor_green_vortex_restart_check"),
119+
" taylor_green_vortex_restart_check | "
120+
" time_refinement_study"),
120121
"The type of test we want to solve. "
121122
"Choices are (only run control has been coded up for now)"
122123
" <run_control | "
@@ -143,7 +144,8 @@ void AllParameters::declare_parameters (dealii::ParameterHandler &prm)
143144
" flow_solver | "
144145
" dual_weighted_residual_mesh_adaptation | "
145146
" taylor_green_vortex_energy_check | "
146-
" taylor_green_vortex_restart_check>.");
147+
" taylor_green_vortex_restart_check | "
148+
" time_refinement_study>.");
147149

148150
prm.declare_entry("pde_type", "advection",
149151
dealii::Patterns::Selection(
@@ -243,6 +245,7 @@ void AllParameters::parse_parameters (dealii::ParameterHandler &prm)
243245
else if (test_string == "dual_weighted_residual_mesh_adaptation") { test_type = dual_weighted_residual_mesh_adaptation; }
244246
else if (test_string == "taylor_green_vortex_energy_check") { test_type = taylor_green_vortex_energy_check; }
245247
else if (test_string == "taylor_green_vortex_restart_check") { test_type = taylor_green_vortex_restart_check; }
248+
else if (test_string == "time_refinement_study") { test_type = time_refinement_study; }
246249

247250
const std::string pde_string = prm.get("pde_type");
248251
if (pde_string == "advection") {

src/parameters/all_parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class AllParameters
131131
dual_weighted_residual_mesh_adaptation,
132132
taylor_green_vortex_energy_check,
133133
taylor_green_vortex_restart_check,
134+
time_refinement_study,
134135
};
135136
TestType test_type; ///< Selected TestType from the input file.
136137

src/parameters/parameters_flow_solver.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ void FlowSolverParam::declare_parameters(dealii::ParameterHandler &prm)
1818
" taylor_green_vortex | "
1919
" burgers_viscous_snapshot | "
2020
" naca0012 | "
21-
" burgers_rewienski_snapshot"),
21+
" burgers_rewienski_snapshot | "
22+
" advection_periodic"),
2223
"The type of flow we want to simulate. "
2324
"Choices are "
2425
" <taylor_green_vortex | "
2526
" burgers_viscous_snapshot | "
2627
" naca0012 | "
27-
" burgers_rewienski_snapshot>.");
28+
" burgers_rewienski_snapshot | "
29+
" advection_periodic>.");
2830

2931
prm.declare_entry("final_time", "1",
3032
dealii::Patterns::Double(0, dealii::Patterns::Double::max_double_value),
@@ -94,6 +96,17 @@ void FlowSolverParam::declare_parameters(dealii::ParameterHandler &prm)
9496
" isothermal>.");
9597
}
9698
prm.leave_subsection();
99+
100+
prm.enter_subsection("time_refinement_study");
101+
{
102+
prm.declare_entry("number_of_times_to_solve", "4",
103+
dealii::Patterns::Integer(1, dealii::Patterns::Integer::max_int_value),
104+
"Number of times to run the flow solver during a time refinement study.");
105+
prm.declare_entry("refinement_ratio", "0.5",
106+
dealii::Patterns::Double(0, 1.0),
107+
"Ratio between a timestep size and the next in a time refinement study, 0<r<1.");
108+
}
109+
prm.leave_subsection();
97110
}
98111
prm.leave_subsection();
99112
}
@@ -107,6 +120,7 @@ void FlowSolverParam::parse_parameters(dealii::ParameterHandler &prm)
107120
else if (flow_case_type_string == "burgers_viscous_snapshot") {flow_case_type = burgers_viscous_snapshot;}
108121
else if (flow_case_type_string == "burgers_rewienski_snapshot") {flow_case_type = burgers_rewienski_snapshot;}
109122
else if (flow_case_type_string == "naca0012") {flow_case_type = naca0012;}
123+
else if (flow_case_type_string == "advection_periodic") {flow_case_type = advection_periodic;}
110124

111125
final_time = prm.get_double("final_time");
112126
courant_friedrich_lewy_number = prm.get_double("courant_friedrich_lewy_number");
@@ -131,6 +145,12 @@ void FlowSolverParam::parse_parameters(dealii::ParameterHandler &prm)
131145
else if (density_initial_condition_type_string == "isothermal") {density_initial_condition_type = isothermal;}
132146
}
133147
prm.leave_subsection();
148+
prm.enter_subsection("time_refinement_study");
149+
{
150+
number_of_times_to_solve = prm.get_integer("number_of_times_to_solve");
151+
refinement_ratio = prm.get_double("refinement_ratio");
152+
}
153+
prm.leave_subsection();
134154
}
135155
prm.leave_subsection();
136156
}

src/parameters/parameters_flow_solver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class FlowSolverParam
2020
burgers_viscous_snapshot,
2121
naca0012,
2222
burgers_rewienski_snapshot,
23+
advection_periodic
2324
};
2425
FlowCaseType flow_case_type; ///< Selected FlowCaseType from the input file
2526

@@ -62,6 +63,9 @@ class FlowSolverParam
6263
};
6364
/// Selected DensityInitialConditionType from the input file
6465
DensityInitialConditionType density_initial_condition_type;
66+
67+
int number_of_times_to_solve; ///<For time refinement study, number of times to run the calculation
68+
double refinement_ratio; ///<For time refinement study, ratio of next timestep size to current one, 0<r<1
6569

6670
/// Declares the possible variables and sets the defaults.
6771
static void declare_parameters (dealii::ParameterHandler &prm);

src/physics/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_subdirectory(initial_conditions)
2+
add_subdirectory(exact_solutions)
23

34
SET(SOURCE
45
physics_factory.cpp
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
set(SOURCE
2+
exact_solution.cpp
3+
)
4+
5+
foreach(dim RANGE 1 3)
6+
# Output library
7+
string(CONCAT ExactSolutionsLib ExactSolutions_${dim}D)
8+
add_library(${ExactSolutionsLib} STATIC ${SOURCE})
9+
# Link with PhysicsLib
10+
string(CONCAT PhysicsLib Physics_${dim}D)
11+
target_link_libraries(${ExactSolutionsLib} ${PhysicsLib})
12+
13+
target_compile_definitions(${ExactSolutionsLib} PRIVATE PHILIP_DIM=${dim})
14+
unset(PhysicsLib)
15+
16+
# Setup target with deal.II
17+
if(NOT DOC_ONLY)
18+
DEAL_II_SETUP_TARGET(${ExactSolutionsLib})
19+
endif()
20+
21+
unset(ExactSolutionsLib)
22+
endforeach()
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include <deal.II/base/function.h>
2+
#include "exact_solution.h"
3+
4+
namespace PHiLiP {
5+
6+
// ========================================================
7+
// ZERO -- Returns zero everywhere; used a placeholder when no exact solution is defined.
8+
// ========================================================
9+
template <int dim, int nstate, typename real>
10+
ExactSolutionFunction_Zero<dim,nstate,real>
11+
::ExactSolutionFunction_Zero(double time_compare)
12+
: ExactSolutionFunction<dim,nstate,real>()
13+
, t(time_compare)
14+
{
15+
}
16+
17+
template <int dim, int nstate, typename real>
18+
inline real ExactSolutionFunction_Zero<dim,nstate,real>
19+
::value(const dealii::Point<dim,real> &/*point*/, const unsigned int /*istate*/) const
20+
{
21+
real value = 0;
22+
return value;
23+
}
24+
25+
// ========================================================
26+
// 1D SINE -- Exact solution for advection_explicit_time_study
27+
// ========================================================
28+
template <int dim, int nstate, typename real>
29+
ExactSolutionFunction_1DSine<dim,nstate,real>
30+
::ExactSolutionFunction_1DSine (double time_compare)
31+
: ExactSolutionFunction<dim,nstate,real>()
32+
, t(time_compare)
33+
{
34+
}
35+
36+
template <int dim, int nstate, typename real>
37+
inline real ExactSolutionFunction_1DSine<dim,nstate,real>
38+
::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
39+
{
40+
double x_adv_speed = 1.0;
41+
42+
real value = 0;
43+
real pi = dealii::numbers::PI;
44+
if(point[0] >= 0.0 && point[0] <= 2.0){
45+
value = sin(2*pi*(point[0] - x_adv_speed * t)/2.0);
46+
}
47+
return value;
48+
}
49+
50+
51+
//=========================================================
52+
// FLOW SOLVER -- Exact Solution Base Class + Factory
53+
//=========================================================
54+
template <int dim, int nstate, typename real>
55+
ExactSolutionFunction<dim,nstate,real>
56+
::ExactSolutionFunction ()
57+
: dealii::Function<dim,real>(nstate)
58+
{
59+
//do nothing
60+
}
61+
62+
template <int dim, int nstate, typename real>
63+
std::shared_ptr<ExactSolutionFunction<dim, nstate, real>>
64+
ExactSolutionFactory<dim,nstate, real>::create_ExactSolutionFunction(
65+
const Parameters::FlowSolverParam& flow_solver_parameters,
66+
const double time_compare)
67+
{
68+
// Get the flow case type
69+
const FlowCaseEnum flow_type = flow_solver_parameters.flow_case_type;
70+
if (flow_type == FlowCaseEnum::advection_periodic) {
71+
if constexpr (dim==1 && nstate==dim) return std::make_shared<ExactSolutionFunction_1DSine<dim,nstate,real> > (time_compare);
72+
} else {
73+
// Select zero function if there is no exact solution defined
74+
return std::make_shared<ExactSolutionFunction_Zero<dim,nstate,real>> (time_compare);
75+
}
76+
return nullptr;
77+
}
78+
79+
template class ExactSolutionFunction <PHILIP_DIM,PHILIP_DIM, double>;
80+
template class ExactSolutionFunction <PHILIP_DIM,PHILIP_DIM+2, double>;
81+
template class ExactSolutionFactory <PHILIP_DIM, PHILIP_DIM+2, double>;
82+
template class ExactSolutionFactory <PHILIP_DIM, PHILIP_DIM, double>;
83+
template class ExactSolutionFunction_Zero <PHILIP_DIM,1, double>;
84+
template class ExactSolutionFunction_Zero <PHILIP_DIM,2, double>;
85+
template class ExactSolutionFunction_Zero <PHILIP_DIM,3, double>;
86+
template class ExactSolutionFunction_Zero <PHILIP_DIM,4, double>;
87+
template class ExactSolutionFunction_Zero <PHILIP_DIM,5, double>;
88+
89+
} // PHiLiP namespace
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#ifndef __EXACT_SOLUTION_H__
2+
#define __EXACT_SOLUTION_H__
3+
4+
// for the exact_solution function
5+
#include <deal.II/lac/vector.h>
6+
#include <deal.II/base/function.h>
7+
#include "parameters/all_parameters.h"
8+
9+
namespace PHiLiP {
10+
11+
/// Initial condition function used to initialize a particular flow setup/case
12+
template <int dim, int nstate, typename real>
13+
class ExactSolutionFunction : public dealii::Function<dim,real>
14+
{
15+
protected:
16+
using dealii::Function<dim,real>::value; ///< dealii::Function we are templating on
17+
18+
public:
19+
/// Constructor
20+
ExactSolutionFunction();
21+
/// Destructor
22+
~ExactSolutionFunction() {};
23+
24+
/// Value of the initial condition
25+
virtual real value (const dealii::Point<dim,real> &point, const unsigned int istate = 0) const = 0;
26+
};
27+
28+
/// Initial Condition Function: Zero Function; used as a placeholder when there is no exact solution
29+
template <int dim, int nstate, typename real>
30+
class ExactSolutionFunction_Zero
31+
: public ExactSolutionFunction<dim,nstate,real>
32+
{
33+
protected:
34+
using dealii::Function<dim,real>::value; ///< dealii::Function we are templating on
35+
36+
public:
37+
/// Constructor for InitialConditionFunction_Zero
38+
ExactSolutionFunction_Zero (double time_compare);
39+
40+
/// Time at which to compute the exact solution
41+
double t;
42+
43+
/// Value of initial condition
44+
real value (const dealii::Point<dim,real> &point, const unsigned int istate = 0) const override;
45+
};
46+
47+
/// Initial Condition Function: 1D Sine Function; used for temporal convergence
48+
template <int dim, int nstate, typename real>
49+
class ExactSolutionFunction_1DSine
50+
: public ExactSolutionFunction<dim,nstate,real>
51+
{
52+
protected:
53+
using dealii::Function<dim,real>::value; ///< dealii::Function we are templating on
54+
55+
public:
56+
/// Constructor for InitialConditionFunction_1DSine
57+
/** Calls the Function(const unsigned int n_components) constructor in deal.II*/
58+
ExactSolutionFunction_1DSine (double time_compare);
59+
60+
/// Time at which to compute the exact solution
61+
double t;
62+
63+
/// Value of initial condition
64+
real value (const dealii::Point<dim,real> &point, const unsigned int istate = 0) const override;
65+
};
66+
67+
68+
/// Initial condition function factory
69+
template <int dim, int nstate, typename real>
70+
class ExactSolutionFactory
71+
{
72+
protected:
73+
/// Enumeration of all flow solver initial conditions types defined in the Parameters class
74+
using FlowCaseEnum = Parameters::FlowSolverParam::FlowCaseType;
75+
76+
public:
77+
/// Construct InitialConditionFunction object from global parameter file
78+
static std::shared_ptr<ExactSolutionFunction<dim,nstate,real>>
79+
create_ExactSolutionFunction(const Parameters::FlowSolverParam& flow_solver_parameters, const double time_compare);
80+
};
81+
82+
} // PHiLiP namespace
83+
#endif

0 commit comments

Comments
 (0)