467 *
const std::array<double, dim>
p_sphere =
470 *
constexpr const double alpha = 2. / 3.;
480 * <a name=
"Parameters"></a>
502 *
std::string type =
"cg_with_amg";
503 *
unsigned int maxiter = 10000;
506 *
unsigned int smoother_sweeps = 1;
507 *
unsigned int n_cycles = 1;
508 *
std::string smoother_type =
"ILU";
513 *
std::string type =
"chebyshev";
514 *
double smoothing_range = 20;
515 *
unsigned int degree = 5;
516 *
unsigned int eig_cg_n_iterations = 20;
523 *
PolynomialCoarseningSequenceType::decrease_by_one;
542 *
unsigned int n_cycles = 8;
567 * <a name=
"MatrixfreeLaplaceoperator"></a>
568 * <
h3>Matrix-
free Laplace
operator</
h3>
588 *
template <
int dim,
typename number>
596 *
LaplaceOperator() =
default;
612 *
number el(
unsigned int,
unsigned int)
const;
614 *
void initialize_dof_vector(VectorType &
vec)
const;
616 *
void vmult(VectorType &dst,
const VectorType &src)
const;
618 *
void Tvmult(VectorType &dst,
const VectorType &src)
const;
629 *
const VectorType &src)
const;
635 *
const VectorType & src,
636 *
const std::pair<unsigned int, unsigned int> &
range)
const;
663 * right-
hand-side vector.
666 *
template <
int dim,
typename number>
667 *
LaplaceOperator<dim, number>::LaplaceOperator(
679 *
template <
int dim,
typename number>
680 *
void LaplaceOperator<dim, number>::reinit(
692 *
this->system_matrix.clear();
700 *
this->constraints.copy_from(constraints);
712 *
matrix_free.
reinit(mapping, dof_handler, constraints, quad,
data);
742 *
matrix_free.initialize_dof_vector(b);
743 *
matrix_free.initialize_dof_vector(
x);
745 *
constraints.distribute(
x);
747 *
matrix_free.cell_loop(&LaplaceOperator::do_cell_integral_range,
752 *
constraints.set_zero(b);
771 *
template <
int dim,
typename number>
774 *
return matrix_free.get_dof_handler().n_dofs();
785 *
template <
int dim,
typename number>
786 *
number LaplaceOperator<dim, number>::el(
unsigned int,
unsigned int)
const
800 *
template <
int dim,
typename number>
802 *
LaplaceOperator<dim, number>::initialize_dof_vector(VectorType &
vec)
const
804 *
matrix_free.initialize_dof_vector(
vec);
817 *
void LaplaceOperator<dim, number>::vmult(VectorType & dst,
820 *
this->matrix_free.cell_loop(
832 *
template <
int dim,
typename number>
833 *
void LaplaceOperator<dim, number>::Tvmult(VectorType & dst,
834 *
const VectorType &src)
const
836 *
this->vmult(dst, src);
850 *
template <
int dim,
typename number>
851 *
void LaplaceOperator<dim, number>::compute_inverse_diagonal(
852 *
VectorType &diagonal)
const
854 *
this->matrix_free.initialize_dof_vector(diagonal);
857 *
&LaplaceOperator::do_cell_integral_local,
861 *
i = (
std::
abs(i) > 1.0e-10) ? (1.0 / i) : 1.0;
881 *
LaplaceOperator<dim, number>::get_system_matrix()
const
883 *
if (system_matrix.m() == 0 && system_matrix.n() == 0)
885 *
const auto &dof_handler = this->matrix_free.get_dof_handler();
888 *
dof_handler.locally_owned_dofs(),
889 *
dof_handler.get_triangulation().get_communicator());
900 *
&LaplaceOperator::do_cell_integral_local,
904 *
return this->system_matrix;
916 *
template <
int dim,
typename number>
917 *
void LaplaceOperator<dim, number>::do_cell_integral_local(
935 *
template <
int dim,
typename number>
936 *
void LaplaceOperator<dim, number>::do_cell_integral_global(
939 *
const VectorType &src)
const
957 *
template <
int dim,
typename number>
958 *
void LaplaceOperator<dim, number>::do_cell_integral_range(
961 *
const VectorType & src,
962 *
const std::pair<unsigned int, unsigned int> &
range)
const
966 *
for (
unsigned cell =
range.first; cell <
range.second; ++cell)
979 * <a name=
"Solverandpreconditioner"></a>
985 * <a name=
"Conjugategradientsolverwithmultigridpreconditioner"></a>
995 *
template <
typename VectorType,
1003 *
const VectorType & src,
1014 *
const unsigned int min_level =
mg_matrices.min_level();
1015 *
const unsigned int max_level =
mg_matrices.max_level();
1031 *
min_level, max_level);
1036 *
std::make_shared<SmootherPreconditionerType>();
1042 *
mg_data.smoother.eig_cg_n_iterations;
1056 *
mg_data.coarse_solver.abstol,
1057 *
mg_data.coarse_solver.reltol,
1062 *
std::unique_ptr<MGCoarseGridBase<VectorType>>
mg_coarse;
1068 *
amg_data.smoother_type =
mg_data.coarse_solver.smoother_type.c_str();
1101 * <a name=
"Hybridpolynomialgeometricglobalcoarseningmultigridpreconditioner"></a>
1112 *
template <
typename VectorType,
typename OperatorType,
int dim>
1116 *
const VectorType & src,
1142 *
std::vector<std::shared_ptr<const Triangulation<dim>>>
1144 *
if (
mg_data.transfer.perform_h_transfer)
1147 *
dof_handler.get_triangulation());
1150 *
&(dof_handler.get_triangulation()), [](
auto *) {});
1161 *
unsigned int max = 0;
1163 *
for (
auto &cell : dof_handler.active_cell_iterators())
1164 *
if (cell->is_locally_owned())
1166 *
std::
max(
max, dof_handler.get_fe(cell->active_fe_index()).degree);
1177 *
for (
unsigned int i = 0; i < dof_handler.get_fe_collection().
size(); ++i)
1179 *
const unsigned int degree = dof_handler.get_fe(i).degree;
1181 *
ExcMessage(
"FECollection does not contain unique degrees."));
1185 *
unsigned int minlevel = 0;
1188 *
dof_handlers.resize(minlevel, maxlevel);
1202 *
dof_handlers[
l].distribute_dofs(dof_handler.get_fe_collection());
1213 *
for (
unsigned int i = 0, l = maxlevel; i <
n_p_levels; ++i, --
l)
1215 *
dof_handlers[
l].
reinit(dof_handler.get_triangulation());
1217 *
if (l == maxlevel)
1221 *
auto cell_other = dof_handler.begin_active();
1224 *
if (cell->is_locally_owned())
1225 *
cell->set_active_fe_index(
cell_other->active_fe_index());
1237 *
if (cell->is_locally_owned())
1246 *
ExcMessage(
"Next polynomial degree in sequence "
1247 *
"does not exist in FECollection."));
1255 *
dof_handlers[
l].distribute_dofs(dof_handler.get_fe_collection());
1267 *
constraints(minlevel, maxlevel);
1271 *
const auto &dof_handler = dof_handlers[
level];
1288 *
operators[
level] = std::make_unique<OperatorType>(mapping_collection,
1303 *
dof_handlers[
level],
1304 *
constraints[
level + 1],
1305 *
constraints[
level]);
1332 * <a name=
"ThecodeLaplaceProblemcodeclasstemplate"></a>
1348 *
template <
int dim>
1386 *
std::unique_ptr<FESeries::Legendre<dim>>
legendre;
1387 *
std::unique_ptr<parallel::CellWeights<dim>>
cell_weights;
1401 * <a name=
"ThecodeLaplaceProblemcodeclassimplementation"></a>
1407 * <a name=
"Constructor"></a>
1418 *
template <
int dim>
1424 *
,
pcout(std::cout,
1431 *
Assert(prm.min_h_level <= prm.max_h_level,
1433 *
"Triangulation level limits have been incorrectly set up."));
1434 *
Assert(prm.min_p_degree <= prm.max_p_degree,
1435 *
ExcMessage(
"FECollection degrees have been incorrectly set up."));
1457 *
for (
unsigned int degree = 1; degree <= prm.max_p_degree; ++degree)
1459 *
fe_collection.push_back(
FE_Q<dim>(degree));
1477 *
const unsigned int min_fe_index = prm.min_p_degree - 1;
1478 *
fe_collection.set_hierarchy(
1481 *
const unsigned int fe_index) ->
unsigned int {
1482 *
return ((fe_index + 1) < fe_collection.
size()) ? fe_index + 1 :
1487 *
const unsigned int fe_index) ->
unsigned int {
1489 *
ExcMessage(
"Finite element is not part of hierarchy!"));
1499 *
legendre = std::make_unique<FESeries::Legendre<dim>>(
1533 *
cell_weights = std::make_unique<parallel::CellWeights<dim>>(
1536 *
{prm.weighting_factor, prm.weighting_exponent}));
1567 *
prm.max_p_level_difference,
1570 *
boost::signals2::at_front);
1578 * <a name=
"LaplaceProbleminitialize_grid"></a>
1590 * in
the positive z-direction.
1604 * remove one cell in
every cell
from the negative direction,
but remove one
1624 *
for (
unsigned int d = 0;
d < dim; ++
d)
1644 *
const unsigned int min_fe_index = prm.min_p_degree - 1;
1645 *
for (
const auto &cell : dof_handler.active_cell_iterators())
1646 *
if (cell->is_locally_owned())
1649 *
dof_handler.distribute_dofs(fe_collection);
1659 * <a name=
"LaplaceProblemsetup_system"></a>
1671 *
template <
int dim>
1676 *
dof_handler.distribute_dofs(fe_collection);
1678 *
locally_owned_dofs = dof_handler.locally_owned_dofs();
1684 *
mpi_communicator);
1687 *
constraints.clear();
1691 *
mapping_collection, dof_handler, 0,
Solution<dim>(), constraints);
1692 *
constraints.close();
1706 * <a name=
"LaplaceProblemprint_diagnostics"></a>
1727 *
template <
int dim>
1731 *
std::min<unsigned int>(8,
1737 *
pcout <<
" Number of active cells: "
1739 *
<<
" by partition: ";
1748 *
pcout << std::endl;
1752 *
pcout <<
" Number of degrees of freedom: " << dof_handler.n_dofs()
1754 *
<<
" by partition: ";
1758 *
dof_handler.n_locally_owned_dofs());
1763 *
pcout << std::endl;
1770 *
pcout <<
" Number of constraints: "
1775 *
<<
" by partition: ";
1780 *
pcout << std::endl;
1785 *
for (
const auto &cell : dof_handler.active_cell_iterators())
1786 *
if (cell->is_locally_owned())
1791 *
pcout <<
" Frequencies of poly. degrees:";
1792 *
for (
unsigned int i = 0; i < fe_collection.
size(); ++i)
1795 *
pcout << std::endl;
1804 * <a name=
"LaplaceProblemsolve_system"></a>
1815 *
template <
int dim>
1824 *
prm.tolerance_factor *
system_rhs.l2_norm());
1831 *
mapping_collection,
1835 *
pcout <<
" Solved in " << solver_control.last_step() <<
" iterations."
1850 * <a name=
"LaplaceProblemcompute_indicators"></a>
1880 *
template <
int dim>
1888 *
face_quadrature_collection,
1912 * <a name=
"LaplaceProblemadapt_resolution"></a>
1923 *
template <
int dim>
1944 *
prm.refine_fraction,
1945 *
prm.coarsen_fraction);
1952 * polynomial degree.
1972 *
prm.p_refine_fraction,
1973 *
prm.p_coarsen_fraction);
1997 *
for (
const auto &cell :
1999 *
cell->clear_refine_flag();
2001 *
for (
const auto &cell :
2003 *
cell->clear_coarsen_flag();
2021 *
hp::Refinement::choose_p_over_h(dof_handler);
2066 *
if (cell->is_locally_owned())
2067 *
fe_degrees(cell->active_cell_index()) = cell->get_fe().degree;
2074 *
data_out.attach_dof_handler(dof_handler);
2076 *
data_out.add_data_vector(
fe_degrees,
"fe_degree");
2077 *
data_out.add_data_vector(
subdomain,
"subdomain");
2080 *
data_out.build_patches(mapping_collection);
2082 *
data_out.write_vtu_with_pvtu_record(
2083 *
"./",
"solution", cycle, mpi_communicator, 2, 1);
2091 * <a name=
"LaplaceProblemrun"></a>
2092 * <
h4>LaplaceProblem::run</
h4>
2105 *
template <
int dim>
2108 *
pcout <<
"Running with Trilinos on "
2110 *
<<
" MPI rank(s)..." << std::endl;
2113 *
pcout <<
"Calculating transformation matrices..." << std::endl;
2115 *
legendre->precalculate_all_transformation_matrices();
2118 *
for (
unsigned int cycle = 0; cycle < prm.n_cycles; ++cycle)
2120 *
pcout <<
"Cycle " << cycle <<
':' << std::endl;
2141 *
pcout << std::endl;
2151 * <a name=
"main"></a>
2165 *
using namespace dealii;
2166 *
using namespace Step75;
2174 *
catch (std::exception &exc)
2176 *
std::cerr << std::endl
2178 *
<<
"----------------------------------------------------"
2180 *
std::cerr <<
"Exception on processing: " << std::endl
2181 *
<< exc.what() << std::endl
2182 *
<<
"Aborting!" << std::endl
2183 *
<<
"----------------------------------------------------"
2190 *
std::cerr << std::endl
2192 *
<<
"----------------------------------------------------"
2194 *
std::cerr <<
"Unknown exception!" << std::endl
2195 *
<<
"Aborting!" << std::endl
2196 *
<<
"----------------------------------------------------"
2217 Number
of constraints: 542
2223+---------------------------------------------+------------+------------+
2227+---------------------------------+-----------+------------+------------+
2230| initialize grid | 1 | 0.011s | 6.4% |
2231| output results | 1 | 0.0343s | 20% |
2232| setup
system | 1 | 0.00839s | 4.9% |
2233| solve
system | 1 | 0.0896s | 52% |
2234+---------------------------------+-----------+------------+------------+
2242 Number
of constraints: 1202
2248+---------------------------------------------+------------+------------+
2252+---------------------------------+-----------+------------+------------+
2255| output results | 1 | 0.0243s | 15% |
2256| setup
system | 1 | 0.00662s | 4% |
2257| solve
system | 1 | 0.121s | 74% |
2258+---------------------------------+-----------+------------+------------+
2269 Number
of constraints: 14357
2271 Frequencies of poly. degrees: 2:1126 3:1289 4:2725 5:465 6:5
2275+---------------------------------------------+------------+------------+
2279+---------------------------------+-----------+------------+------------+
2282| output results | 1 | 0.0434s | 2.4% |
2283| setup
system | 1 | 0.0165s | 0.9% |
2284| solve
system | 1 | 1.74s | 95% |
2285+---------------------------------+-----------+------------+------------+
2309<
div class=
"twocolumn" style=
"width: 80%; text-align: center;">
2311 <
img src=
"https://www.dealii.org/images/steps/developer/step-75.subdomains-07.svg"
2312 alt=
"Partitioning after seven refinements.">
2315 <
img src=
"https://www.dealii.org/images/steps/developer/step-75.fedegrees-07.svg"
2316 alt=
"Local approximation degrees after seven refinements.">
2322<a name=
"extensions"></a>
2323<a name=
"Possibilitiesforextensions"></a><
h3>Possibilities
for extensions</
h3>
2356hp::Refinement::limit_p_level_difference() function.
At this stage, all
value_type * data() const noexcept
void reinit(value_type *starting_element, const std::size_t n_elements)
static void estimate(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim - 1 > &quadrature, const std::map< types::boundary_id, const Function< spacedim, typename InputVector::value_type > * > &neumann_bc, const InputVector &solution, Vector< float > &error, const ComponentMask &component_mask=ComponentMask(), const Function< spacedim > *coefficients=nullptr, const unsigned int n_threads=numbers::invalid_unsigned_int, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id, const types::material_id material_id=numbers::invalid_material_id, const Strategy strategy=cell_diameter_over_24)
virtual types::subdomain_id locally_owned_subdomain() const
void coarsen_global(const unsigned int times=1)
virtual void execute_coarsening_and_refinement()
unsigned int size() const
static WeightingFunction ndofs_weighting(const std::pair< float, float > &coefficients)
IteratorRange< active_cell_iterator > active_cell_iterators() const
__global__ void set(Number *val, const Number s, const size_type N)
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
void loop(ITERATOR begin, std_cxx20::type_identity_t< ITERATOR > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ update_gradients
Shape function gradients.
std::array< double, dim > to_spherical(const Point< dim > &point)
void hyper_L(Triangulation< dim > &tria, const double left=-1., const double right=1., const bool colorize=false)
void subdivided_hyper_L(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &bottom_left, const Point< dim > &top_right, const std::vector< int > &n_cells_to_remove)
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
void coarsen(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold)
@ matrix
Contents is actually a matrix.
@ symmetric
Matrix is symmetric.
@ diagonal
Matrix is diagonal.
@ general
No special properties.
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
FESeries::Legendre< dim, spacedim > default_fe_series(const hp::FECollection< dim, spacedim > &fe_collection, const unsigned int component=numbers::invalid_unsigned_int)
void coefficient_decay(FESeries::Legendre< dim, spacedim > &fe_legendre, const DoFHandler< dim, spacedim > &dof_handler, const VectorType &solution, Vector< float > &smoothness_indicators, const VectorTools::NormType regression_strategy=VectorTools::Linfty_norm, const double smallest_abs_coefficient=1e-10, const bool only_flagged_cells=false)
void call(const std::function< RT()> &function, internal::return_value< RT > &ret_val)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
std::vector< T > gather(const MPI_Comm comm, const T &object_to_send, const unsigned int root_process=0)
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)
bool limit_p_level_difference(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int max_difference=1, const unsigned int contains_fe_index=0)
void predict_error(const DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &error_indicators, Vector< Number > &predicted_errors, const double gamma_p=std::sqrt(0.4), const double gamma_h=2., const double gamma_n=1.)
void p_adaptivity_fixed_number(const DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &criteria, const double p_refine_fraction=0.5, const double p_coarsen_fraction=0.5, const ComparisonFunction< std_cxx20::type_identity_t< Number > > &compare_refine=std::greater_equal< Number >(), const ComparisonFunction< std_cxx20::type_identity_t< Number > > &compare_coarsen=std::less_equal< Number >())
int(&) functions(const void *v1, const void *v2)
const types::material_id invalid_material_id
const types::subdomain_id invalid_subdomain_id
static const unsigned int invalid_unsigned_int
void refine_and_coarsen_fixed_number(::Triangulation< dim, spacedim > &tria, const ::Vector< Number > &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const types::global_cell_index max_n_cells=std::numeric_limits< types::global_cell_index >::max())
double legendre(unsigned int l, double x)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned short int fe_index
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
boost::signals2::signal< void()> post_p4est_refinement