379 * #include <deal.II/base/utilities.h>
380 * #include <deal.II/base/quadrature_lib.h>
381 * #include <deal.II/base/function.h>
382 * #include <deal.II/base/logstream.h>
383 * #include <deal.II/lac/vector.h>
384 * #include <deal.II/lac/full_matrix.h>
385 * #include <deal.II/lac/dynamic_sparsity_pattern.h>
386 * #include <deal.II/lac/sparse_matrix.h>
387 * #include <deal.II/lac/solver_cg.h>
388 * #include <deal.II/lac/precondition.h>
389 * #include <deal.II/lac/affine_constraints.h>
390 * #include <deal.II/grid/tria.h>
391 * #include <deal.II/grid/grid_generator.h>
392 * #include <deal.II/grid/grid_refinement.h>
393 * #include <deal.II/grid/grid_out.h>
394 * #include <deal.II/dofs/dof_handler.h>
395 * #include <deal.II/dofs/dof_tools.h>
396 * #include <deal.II/fe/fe_q.h>
397 * #include <deal.II/fe/fe_system.h>
398 * #include <deal.II/fe/fe_values.h>
399 * #include <deal.II/numerics/data_out.h>
400 * #include <deal.II/numerics/vector_tools.h>
401 * #include <deal.II/numerics/error_estimator.h>
402 * #include <deal.II/numerics/solution_transfer.h>
403 * #include <deal.II/numerics/matrix_tools.h>
404 * #include <deal.II/lac/sparse_direct.h>
405 * #include <deal.II/base/timer.h>
407 * #include <deal.II/grid/manifold_lib.h>
408 * #include <deal.II/grid/grid_tools.h>
410 * #include <
boost/math/special_functions/ellint_1.hpp>
413 * #include <iostream>
416 *
namespace SwiftHohenbergSolver
427 *
enum MeshType {HYPERCUBE, CYLINDER, SPHERE, TORUS, SINUSOID};
436 *
enum InitialConditionType {HOTSPOT, PSUEDORANDOM, RANDOM};
448 *
template<
int spacedim>
453 * Currently
this only works
for a 3-dimensional embedding space
454 * because we are explicitly referencing the x, y, and z coordinates
457 *
Assert(spacedim == 3, ExcNotImplemented());
461 * Returns a
point where the x-coordinate is unchanged but the y and z coordinates are adjusted
462 * by a
cos wave of period 20, amplitude .5, and vertical
shift 1
479 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
485 * / @brief Default constructor, initializes all variables and objects with
default values
500 * SHEquation(
const unsigned int degree
501 * ,
double time_step_denominator
502 * ,
unsigned int ref_num
503 * ,
double r_constant = 0.5
504 * ,
double g1_constant = 0.5
505 * , std::string output_file_name =
"solution-"
506 * ,
double end_time = 0.5);
510 *
void setup_system();
511 *
void solve_time_step();
512 *
void output_results()
const;
521 *
void make_cylinder();
524 * / @brief Uses the same process as creating a
cylinder, but then also warps the boundary of the
cylinder by the function (1 + 0.5*
cos(pi*x/10))
527 *
void make_sinusoid();
530 * / @brief Generates a spherical mesh of radius 6*pi
using GridGenerator and refines it refinement_number times.
533 *
void make_sphere();
536 * / @brief Generates a
torus mesh with inner radius 4 and outer radius 9
using GridGenerator and refines it refinement_number times.
542 * / @brief Generates a hypercube mesh with sidelenth 12*pi
using GridGenerator and refines it refinement_number times.
545 *
void make_hypercube();
550 * / @brief The degree of finite element to be used,
default 1
553 *
const unsigned int degree;
557 * / @brief Object holding the mesh
567 * / @brief Object which understands which finite elements are at each node
574 * / @brief Describes the sparsity of the system
matrix, allows
for more efficient storage
581 * / @brief Object holding the system
matrix, stored as a sparse
matrix
592 * / @brief Stores the solution from the previous timestep. Used to compute non-linear terms
603 * / @brief Stores the current time, in the units of the problem
609 * / @brief The amount time is increased each iteration/ the denominator of the discretized time derivative
615 * / @brief Counts the number of iterations that have elapsed
618 *
unsigned int timestep_number;
621 * / @brief Used to compute the time_step: time_step = 1/timestep_denominator
624 *
unsigned int timestep_denominator;
627 * / @brief Determines how much to globally
refine each mesh
630 *
unsigned int refinement_number;
634 * / @brief Coefficient of the linear term in the SH equation. This is often taken to be
constant and g_1 allowed to vary
640 * / @brief Coefficient of the quadratic term in the SH equation. Determines whether hexagonal lattices can form
646 * / @brief A control parameter
for the cubic term. Can be useful
for testing, in
this code we let k=1 in all cases
653 * / @brief Name used to create output file. Should not include extension
656 *
const std::string output_file_name;
660 * / @brief Determines when the solver terminates, endtime of ~100 are useful to see equilibrium results
663 *
const double end_time;
672 *
template <
int spacedim>
673 *
class BoundaryValues :
public Function<spacedim>
681 *
const unsigned int component = 0)
const override;
693 *
template <
int spacedim>
695 *
const unsigned int component)
const
716 *
template<
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
717 *
class InitialCondition :
public Function<spacedim>
722 * / @brief The
value of the parameter r, used to determine a bound
for the magnitude of the
initial conditions
728 * / @brief A center
point, used to determine the location of the hot spot
for the HotSpot
initial condition
734 * / @brief Radius of the hot spot
740 * / @brief Stores the randomly generated coefficients
for planar sine waves along the x-axis, used
for psuedorandom
initial conditions
743 *
double x_sin_coefficients[10];
746 * / @brief Stores the randomly generated coefficients
for planar sine waves along the y-axis, used
for psuedorandom
initial conditions
749 *
double y_sin_coefficients[10];
760 *
for(
int i = 0; i < 10; ++i){
771 * InitialCondition(
const double r,
772 *
const double radius)
777 *
for(
int i = 0; i < 10; ++i){
812 *
double InitialCondition<2, HYPERCUBE, HOTSPOT>::value(
814 *
const unsigned int component)
const
816 *
if(component == 0){
817 *
if(p.square() <= radius){
835 *
double InitialCondition<3, CYLINDER, HOTSPOT>::value(
837 *
const unsigned int component)
const
839 *
if(component == 0){
841 *
const Point<3> compare(p - center);
842 *
if(compare.square() <= radius){
860 *
double InitialCondition<3, SPHERE, HOTSPOT>::value(
862 *
const unsigned int component)
const
864 *
if(component == 0){
865 *
const Point<3> center(18.41988074, 0, 0);
866 *
const Point<3> compare(p - center);
867 *
if(compare.square() <= radius){
885 *
double InitialCondition<3, TORUS, HOTSPOT>::value(
887 *
const unsigned int component)
const
889 *
if(component == 0){
891 *
const Point<3> compare(p - center);
892 *
if(compare.square() <= radius){
910 *
double InitialCondition<3, SINUSOID, HOTSPOT>::value(
912 *
const unsigned int component)
const
914 *
if(component == 0){
916 *
const Point<3> compare(p - center);
917 *
if(compare.square() <= radius){
935 *
double InitialCondition<2, HYPERCUBE, PSUEDORANDOM>::value(
937 *
const unsigned int component)
const
939 *
if(component == 0){
942 *
for(
int i=0; i < 10; ++i){
943 * x_val += x_sin_coefficients[i]*
std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
944 * y_val += y_sin_coefficients[i]*
std::sin(2*3.141592653*p(1)/((i+1)*1.178097245));
947 *
return x_val*y_val;
960 *
double InitialCondition<3, CYLINDER, PSUEDORANDOM>::value(
962 *
const unsigned int component)
const
964 *
if(component == 0){
967 *
double width = ((std::atan2(p(1),p(2)) - 3.1415926)/3.1415926)*18.84955592;
968 *
for(
int i=0; i < 10; ++i){
969 * x_val += x_sin_coefficients[i]*
std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
970 * w_val += y_sin_coefficients[i]*
std::sin(2*3.141592653*width/((i+1)*1.178097245));
973 *
return x_val*w_val;
986 *
double InitialCondition<3, SPHERE, PSUEDORANDOM>::value(
988 *
const unsigned int component)
const
990 *
if(component == 0){
993 *
for(
int i=0; i < 10; ++i){
994 * x_val += x_sin_coefficients[i]*
std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
995 * y_val += y_sin_coefficients[i]*
std::sin(2*3.141592653*p(1)/((i+1)*1.178097245));
998 *
return x_val*y_val;
1011 *
double InitialCondition<3, TORUS, PSUEDORANDOM>::value(
1013 *
const unsigned int component)
const
1015 *
if(component == 0){
1018 *
for(
int i=0; i < 10; ++i){
1019 * x_val += x_sin_coefficients[i]*
std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
1020 * z_val += y_sin_coefficients[i]*
std::sin(2*3.141592653*p(2)/((i+1)*1.178097245));
1023 *
return x_val*z_val;
1036 *
double InitialCondition<3, SINUSOID, PSUEDORANDOM>::value(
1038 *
const unsigned int component)
const
1040 *
if(component == 0){
1043 *
double width = ((std::atan2(p(1),p(2)) - 3.1415926)/3.1415926)*18.84955592;
1044 *
for(
int i=0; i < 10; ++i){
1045 * x_val += x_sin_coefficients[i]*
std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
1046 * w_val += y_sin_coefficients[i]*
std::sin(2*3.141592653*width/((i+1)*1.178097245));
1049 *
return x_val*w_val;
1062 *
double InitialCondition<2, HYPERCUBE, RANDOM>::value(
1064 *
const unsigned int component)
const
1066 *
if(component == 0){
1080 *
double InitialCondition<3, CYLINDER, RANDOM>::value(
1082 *
const unsigned int component)
const
1084 *
if(component == 0){
1098 *
double InitialCondition<3, SPHERE, RANDOM>::value(
1100 *
const unsigned int component)
const
1102 *
if(component == 0){
1116 *
double InitialCondition<3, TORUS, RANDOM>::value(
1118 *
const unsigned int component)
const
1120 *
if(component == 0){
1134 *
double InitialCondition<3, SINUSOID, RANDOM>::value(
1136 *
const unsigned int component)
const
1138 *
if(component == 0){
1146 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1147 * SHEquation<dim, spacedim, MESH, ICTYPE>::SHEquation()
1151 * , time_step(1. / 1500)
1152 * , timestep_denominator(1500)
1153 * , refinement_number(4)
1157 * , output_file_name(
"solution-")
1161 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1162 * SHEquation<dim, spacedim, MESH, ICTYPE>::SHEquation(
const unsigned int degree,
1163 *
double time_step_denominator,
1164 *
unsigned int ref_num,
1165 *
double r_constant,
1166 *
double g1_constant,
1167 * std::string output_file_name,
1172 * , time_step(1. / time_step_denominator)
1173 * , timestep_denominator(time_step_denominator)
1174 * , refinement_number(ref_num)
1178 * , output_file_name(output_file_name)
1179 * , end_time(end_time)
1189 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1190 *
void SHEquation<dim, spacedim, MESH, ICTYPE>::setup_system()
1192 * dof_handler.distribute_dofs(fe);
1196 * Counts the DoF
's for outputting to consolse
1199 * const std::vector<types::global_dof_index> dofs_per_component =
1200 * DoFTools::count_dofs_per_fe_component(dof_handler);
1201 * const unsigned int n_u = dofs_per_component[0],
1202 * n_v = dofs_per_component[1];
1204 * std::cout << "Number of active cells: " << triangulation.n_active_cells()
1206 * << "Total number of cells: " << triangulation.n_cells()
1208 * << "Number of degrees of freedom: " << dof_handler.n_dofs()
1209 * << " (" << n_u << '+
' << n_v << ')
' << std::endl;
1211 * DynamicSparsityPattern dsp(dof_handler.n_dofs());
1213 * DoFTools::make_sparsity_pattern(dof_handler,
1215 * sparsity_pattern.copy_from(dsp);
1217 * system_matrix.reinit(sparsity_pattern);
1219 * solution.reinit(dof_handler.n_dofs());
1220 * old_solution.reinit(dof_handler.n_dofs());
1221 * system_rhs.reinit(dof_handler.n_dofs());
1225 * /** @brief Uses a direct solver to invert the system matrix, then multiplies the RHS vector by the inverted matrix to get the solution.
1226 * * Also includes a timer feature, which is currently commented out, but can be helpful to compute how long a run will take
1227 * * @tparam dim The dimension of the manifold
1228 * * @tparam spacedim The dimension of the ambient space
1229 * * @tparam MESH The type of mesh being used, doesn't change how
this function works
1230 * * @tparam ICTYPE The type of initial condition used, doesn
't change how this function works
1232 * template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1233 * void SHEquation<dim, spacedim, MESH, ICTYPE>::solve_time_step()
1237 * std::cout << "Solving linear system" << std::endl;
1244 * SparseDirectUMFPACK direct_solver;
1246 * direct_solver.initialize(system_matrix);
1248 * direct_solver.vmult(solution, system_rhs);
1253 * std::cout << "done (" << timer.cpu_time() << " s)" << std::endl;
1260 * /** @brief Converts the solution vector into a .vtu file and labels the outputs as u and v
1261 * * @tparam dim The dimension of the manifold
1262 * * @tparam spacedim The dimension of the ambient space
1263 * * @tparam MESH The type of mesh being used, doesn't change how
this function works
1264 * * @tparam ICTYPE The type of initial condition used, doesn
't change how this function works
1266 * template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1267 * void SHEquation<dim, spacedim, MESH, ICTYPE>::output_results() const
1269 * std::vector<std::string> solution_names(1, "u");
1270 * solution_names.emplace_back("v");
1271 * std::vector<DataComponentInterpretation::DataComponentInterpretation>
1273 * DataComponentInterpretation::component_is_scalar);
1274 * interpretation.push_back(DataComponentInterpretation::component_is_scalar);
1276 * DataOut<dim, spacedim> data_out;
1277 * data_out.add_data_vector(dof_handler,
1280 * interpretation /*,
1281 * DataOut<dim, spacedim>::type_dof_data*/);
1283 * data_out.build_patches(degree + 1);
1287 * Takes the output_file_name string and appends timestep_number with up to three leading 0's
1290 *
const std::string filename =
1293 * std::ofstream output(filename);
1294 * data_out.write_vtu(output);
1299 * Below are all the different
template cases
for the make_grid() function
1303 *
void SHEquation<2, 2, HYPERCUBE, HOTSPOT>::make_grid()
1309 *
void SHEquation<2, 3, CYLINDER, HOTSPOT>::make_grid()
1315 *
void SHEquation<2, 3, SPHERE, HOTSPOT>::make_grid()
1321 *
void SHEquation<2, 3, TORUS, HOTSPOT>::make_grid()
1327 *
void SHEquation<2, 3, SINUSOID, HOTSPOT>::make_grid()
1333 *
void SHEquation<2, 2, HYPERCUBE, PSUEDORANDOM>::make_grid()
1339 *
void SHEquation<2, 3, CYLINDER, PSUEDORANDOM>::make_grid()
1345 *
void SHEquation<2, 3, SPHERE, PSUEDORANDOM>::make_grid()
1351 *
void SHEquation<2, 3, TORUS, PSUEDORANDOM>::make_grid()
1357 *
void SHEquation<2, 3, SINUSOID, PSUEDORANDOM>::make_grid()
1363 *
void SHEquation<2, 2, HYPERCUBE, RANDOM>::make_grid()
1369 *
void SHEquation<2, 3, CYLINDER, RANDOM>::make_grid()
1375 *
void SHEquation<2, 3, SPHERE, RANDOM>::make_grid()
1381 *
void SHEquation<2, 3, TORUS, RANDOM>::make_grid()
1387 *
void SHEquation<2, 3, SINUSOID, RANDOM>::make_grid()
1400 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1401 *
void SHEquation<dim, spacedim, MESH, ICTYPE>::run()
1409 * Counts total time elapsed
1415 * Counts number of iterations
1418 * timestep_number = 0;
1422 * Sets the
random seed so runs are repeatable, remove
for varying
random initial conditions
1427 * InitialCondition<spacedim, MESH, ICTYPE> initial_conditions(r, 0.5);
1431 * Applies the
initial conditions to the old_solution
1435 * initial_conditions,
1437 * solution = old_solution;
1448 * Sets up the quadrature formula and
FEValues object
1451 *
const QGauss<dim> quadrature_formula(degree + 2);
1457 *
const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
1464 * The vector which stores the global indices that each local
index connects to
1467 * std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1471 * Extracts the finite elements associated to u and v
1479 * Loops over the cells to create the system
matrix. We
do this only once because the timestep is
constant
1482 *
for(
const auto &cell : dof_handler.active_cell_iterators()){
1486 * fe_values.reinit(cell);
1488 * cell->get_dof_indices(local_dof_indices);
1490 *
for(
const unsigned int q_index : fe_values.quadrature_point_indices()){
1492 *
for(
const unsigned int i : fe_values.dof_indices()){
1495 * These are the ith finite elements associated to u and v
1498 *
const double phi_i_u = fe_values[u].value(i, q_index);
1500 *
const double phi_i_v = fe_values[v].value(i, q_index);
1503 *
for(
const unsigned int j : fe_values.dof_indices())
1507 * These are the jth finite elements associated to u and v
1510 * const double phi_j_u = fe_values[u].
value(j, q_index);
1512 *
const double phi_j_v = fe_values[v].value(j, q_index);
1517 * This formula comes from expanding the PDE system
1520 *
cell_matrix(i, j) += (phi_i_u*phi_j_u - time_step*r*phi_i_u*phi_j_u
1521 * + time_step*phi_i_u*phi_j_v - time_step*grad_phi_i_u*grad_phi_j_v
1522 * + phi_i_v*phi_j_u - grad_phi_i_v*grad_phi_j_u
1523 * - phi_i_v*phi_j_v)*fe_values.JxW(q_index);
1530 * Loops over the dof indices to fill the entries of the system_matrix with the local
data
1533 *
for(
unsigned int i : fe_values.dof_indices()){
1534 *
for(
unsigned int j : fe_values.dof_indices()){
1535 * system_matrix.add(local_dof_indices[i],
1536 * local_dof_indices[j],
1544 * Loops over time, incrementing by timestep, to create the RHS, solve the linear system, then output the result
1547 *
while (time <= end_time)
1551 * Increments time and timestep_number
1554 * time += time_step;
1555 * ++timestep_number;
1559 * Outputs to console the number of iterations and current time. Currently outputs once every
"second"
1562 *
if(timestep_number%timestep_denominator == 0){
1563 * std::cout <<
"Time step " << timestep_number <<
" at t=" << time
1569 * Resets the system_rhs vector. THIS IS VERY IMPORTANT TO ENSURE THE SYSTEM IS SOLVED CORRECTLY AT EACH TIMESTEP
1576 * Loops over cells, then quadrature points, then dof indices to construct the RHS
1579 *
for(
const auto &cell : dof_handler.active_cell_iterators()){
1582 * Resets the cell_rhs. THIS IS ALSO VERY IMPORTANT TO ENSURE THE SYSTEM IS SOLVED CORRECTLY
1589 * Resets the
FEValues object to only the current cell
1592 * fe_values.
reinit(cell);
1594 * cell->get_dof_indices(local_dof_indices);
1598 * Loop over the quadrature points
1601 *
for(
const unsigned int q_index : fe_values.quadrature_point_indices()){
1604 * Stores the
value of the previous solution at the quadrature
point
1611 * Loops over the dof indices to get the
value of Un1
1614 *
for(
const unsigned int i : fe_values.dof_indices()){
1615 * Un1 += old_solution(local_dof_indices[i])*fe_values[u].value(i, q_index);
1620 * Loops over the dof indices,
using Un1 to construct the RHS
for the current timestep. Un1 is used to account
for the nonlinear terms in the SH equation
1623 *
for(
const unsigned int i : fe_values.dof_indices()){
1624 * cell_rhs(i) += (Un1 + time_step*g1*
std::pow(Un1, 2) - time_step*k*
std::pow(Un1, 3))
1625 * *fe_values[u].
value(i, q_index)*fe_values.JxW(q_index);
1631 * Loops over the dof indices to store the local
data in the global RHS vector
1634 *
for(
unsigned int i : fe_values.dof_indices()){
1635 * system_rhs(local_dof_indices[i]) += cell_rhs(i);
1642 * This is where Dirichlet conditions are applied, or Neumann conditions
if the code is commented out
1661 * solve_time_step();
1665 * Outputs the solution at regular intervals, currently once every
"second" The SH equation evolves slowly in time, so
this saves disk space
1668 *
if(timestep_number%timestep_denominator == 0){
1672 * old_solution = solution;
1676 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1677 *
void SHEquation<dim, spacedim, MESH, ICTYPE>::make_cylinder()
1689 * Extracts the boundary mesh with ID 0, which happens to be the tube part of the
cylinder
1696 * The manifold information is lost upon boundary extraction. This sets the mesh boundary type to be a
cylinder again
1706 *
template <
int dim,
int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1707 *
void SHEquation<dim, spacedim, MESH, ICTYPE>::make_sinusoid()
1711 * Same process as above
1727 * We warp the mesh after refinement to avoid a jagged mesh. We can
't tell the code that the boundary should be a perfect sine wave, so we only warp after the
1728 * mesh is fine enough to resolve this
1731 * GridTools::transform(transform_function<spacedim>, triangulation);
1734 * template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1735 * void SHEquation<dim, spacedim, MESH, ICTYPE>::make_sphere()
1737 * GridGenerator::hyper_sphere(triangulation, Point<3>(0, 0, 0), 18.41988074);
1738 * triangulation.refine_global(refinement_number);
1741 * template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1742 * void SHEquation<dim, spacedim, MESH, ICTYPE>::make_torus()
1744 * GridGenerator::torus(triangulation, 9., 4.);
1745 * triangulation.refine_global(refinement_number);
1747 * template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1748 * void SHEquation<dim, spacedim, MESH, ICTYPE>::make_hypercube()
1750 * GridGenerator::hyper_cube(triangulation, -18.84955592, 18.84955592);
1751 * triangulation.refine_global(refinement_number);
1753 * } // namespace SwiftHohenbergSolver
1759 * using namespace SwiftHohenbergSolver;
1763 * An array of mesh types. We iterate over this to allow for longer runs without having to stop the code
1766 * MeshType mesh_types[5] = {HYPERCUBE, CYLINDER, SPHERE, TORUS, SINUSOID};
1769 * An array of initial condition types. We iterate this as well, for the same reason
1772 * InitialConditionType ic_types[3] = {HOTSPOT, PSUEDORANDOM, RANDOM};
1776 * Controls how long the code runs
1779 * const double end_time = 100.;
1783 * The number of times we refine the hypercube mesh
1786 * const unsigned int ref_num = 6;
1790 * The timestep will be 1/timestep_denominator
1793 * const unsigned int timestep_denominator = 25;
1797 * Loops over mesh types, then initial condition types, then loops over values of g_1
1800 * for(const auto MESH : mesh_types){
1801 * for(const auto ICTYPE: ic_types){
1802 * for(int i = 0; i < 8; ++i){
1805 * The value of g_1 passed to the solver object
1808 * const double g_constant = 0.2*i;
1812 * Used to distinguish the start of each run
1815 * std::cout<< std::endl << std::endl;
1820 * Switch statement that determines what template parameters are used by the solver object. Template parameters must be known at compile time, so we cannot
1821 * pass this as a variable unfortunately. In each case, we create a filename string (named appropriately for the particular case), output to the console what
1822 * we are running, create the solver object, and call run(). Note that for the cylinder, sphere, and sinusoid we decrease the refinement number by 1. This keeps
1823 * the number of dofs used in these cases comparable to the number of dofs on the 2D hypercube (otherwise the number of dofs is much larger). For the torus, we
1824 * decrease the refinement number by 2.
1833 * std::string filename = "HYPERCUBE-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1834 * std::cout << "Running: " << filename << std::endl << std::endl;
1836 * SHEquation<2, 2, HYPERCUBE, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1837 * ref_num, 0.3, g_constant,
1838 * filename, end_time);
1839 * heat_equation_solver.run();
1843 * case PSUEDORANDOM:
1845 * std::string filename = "HYPERCUBE-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1846 * std::cout << "Running: " << filename << std::endl << std::endl;
1848 * SHEquation<2, 2, HYPERCUBE, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1849 * ref_num, 0.3, g_constant,
1850 * filename, end_time);
1851 * heat_equation_solver.run();
1857 * std::string filename = "HYPERCUBE-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1858 * std::cout << "Running: " << filename << std::endl << std::endl;
1860 * SHEquation<2, 2, HYPERCUBE, RANDOM> heat_equation_solver(1, timestep_denominator,
1861 * ref_num, 0.3, g_constant,
1862 * filename, end_time);
1863 * heat_equation_solver.run();
1872 * std::string filename = "CYLINDER-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1873 * std::cout << "Running: " << filename << std::endl << std::endl;
1875 * SHEquation<2, 3, CYLINDER, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1876 * ref_num-1, 0.3, g_constant,
1877 * filename, end_time);
1878 * heat_equation_solver.run();
1882 * case PSUEDORANDOM:
1884 * std::string filename = "CYLINDER-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1885 * std::cout << "Running: " << filename << std::endl << std::endl;
1887 * SHEquation<2, 3, CYLINDER, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1888 * ref_num-1, 0.3, g_constant,
1889 * filename, end_time);
1890 * heat_equation_solver.run();
1896 * std::string filename = "CYLINDER-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1897 * std::cout << "Running: " << filename << std::endl << std::endl;
1899 * SHEquation<2, 3, CYLINDER, RANDOM> heat_equation_solver(1, timestep_denominator,
1900 * ref_num-1, 0.3, g_constant,
1901 * filename, end_time);
1902 * heat_equation_solver.run();
1911 * std::string filename = "SPHERE-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1912 * std::cout << "Running: " << filename << std::endl << std::endl;
1914 * SHEquation<2, 3, SPHERE, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1915 * ref_num-1, 0.3, g_constant,
1916 * filename, end_time);
1917 * heat_equation_solver.run();
1921 * case PSUEDORANDOM:
1923 * std::string filename = "SPHERE-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1924 * std::cout << "Running: " << filename << std::endl << std::endl;
1926 * SHEquation<2, 3, SPHERE, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1927 * ref_num-1, 0.3, g_constant,
1928 * filename, end_time);
1929 * heat_equation_solver.run();
1935 * std::string filename = "SPHERE-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1936 * std::cout << "Running: " << filename << std::endl << std::endl;
1938 * SHEquation<2, 3, SPHERE, RANDOM> heat_equation_solver(1, timestep_denominator,
1939 * ref_num-1, 0.3, g_constant,
1940 * filename, end_time);
1941 * heat_equation_solver.run();
1950 * std::string filename = "TORUS-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1951 * std::cout << "Running: " << filename << std::endl << std::endl;
1953 * SHEquation<2, 3, TORUS, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1954 * ref_num-2, 0.3, g_constant,
1955 * filename, end_time);
1956 * heat_equation_solver.run();
1960 * case PSUEDORANDOM:
1962 * std::string filename = "TORUS-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1963 * std::cout << "Running: " << filename << std::endl << std::endl;
1965 * SHEquation<2, 3, TORUS, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1966 * ref_num-2, 0.3, g_constant,
1967 * filename, end_time);
1968 * heat_equation_solver.run();
1974 * std::string filename = "TORUS-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1975 * std::cout << "Running: " << filename << std::endl << std::endl;
1977 * SHEquation<2, 3, TORUS, RANDOM> heat_equation_solver(1, timestep_denominator,
1978 * ref_num-2, 0.3, g_constant,
1979 * filename, end_time);
1980 * heat_equation_solver.run();
1989 * std::string filename = "SINUSOID-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1990 * std::cout << "Running: " << filename << std::endl << std::endl;
1992 * SHEquation<2, 3, SINUSOID, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1993 * ref_num-1, 0.3, g_constant,
1994 * filename, end_time);
1995 * heat_equation_solver.run();
1999 * case PSUEDORANDOM:
2001 * std::string filename = "SINUSOID-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
2002 * std::cout << "Running: " << filename << std::endl << std::endl;
2004 * SHEquation<2, 3, SINUSOID, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
2005 * ref_num-1, 0.3, g_constant,
2006 * filename, end_time);
2007 * heat_equation_solver.run();
2013 * std::string filename = "SINUSOID-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
2014 * std::cout << "Running: " << filename << std::endl << std::endl;
2016 * SHEquation<2, 3, SINUSOID, RANDOM> heat_equation_solver(1, timestep_denominator,
2017 * ref_num-1, 0.3, g_constant,
2018 * filename, end_time);
2019 * heat_equation_solver.run();
2028 * catch (std::exception &exc)
2030 * std::cout << "An error occurred" << std::endl;
2031 * std::cerr << std::endl
2033 * << "----------------------------------------------------"
2035 * std::cerr << "Exception on processing: " << std::endl
2036 * << exc.what() << std::endl
2037 * << "Aborting!" << std::endl
2038 * << "----------------------------------------------------"
2045 * std::cout << "Error occurred, made it past first catch" << std::endl;
2046 * std::cerr << std::endl
2048 * << "----------------------------------------------------"
2050 * std::cerr << "Unknown exception!" << std::endl
2051 * << "Aborting!" << std::endl
2052 * << "----------------------------------------------------"
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
std::vector< index_type > data
void random(DoFHandler< dim, spacedim > &dof_handler)
void cylinder(Triangulation< dim > &tria, const double radius=1., const double half_length=1.)
return_type extract_boundary_mesh(const MeshType< dim, spacedim > &volume_mesh, MeshType< dim - 1, spacedim > &surface_mesh, const std::set< types::boundary_id > &boundary_ids=std::set< types::boundary_id >())
void torus(Triangulation< dim, spacedim > &tria, const double centerline_radius, const double inner_radius, const unsigned int n_cells_toroidal=6, const double phi=2.0 *numbers::PI)
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
@ matrix
Contents is actually a matrix.
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation