79 *
#include <deal.II/base/function.h>
80 *
#include <deal.II/base/quadrature_lib.h>
81 *
#include <deal.II/base/timer.h>
82 *
#include <deal.II/lac/generic_linear_algebra.h>
83 *
#define FORCE_USE_OF_TRILINOS
85 *
#
if defined(DEAL_II_WITH_PETSC) && !defined(DEAL_II_PETSC_WITH_COMPLEX) && \
86 *
!(defined(DEAL_II_WITH_TRILINOS) && defined(FORCE_USE_OF_TRILINOS))
87 *
using namespace dealii::LinearAlgebraPETSc;
88 *
#define USE_PETSC_LA
89 *
#elif defined(DEAL_II_WITH_TRILINOS)
90 *
using namespace dealii::LinearAlgebraTrilinos;
92 *
#error DEAL_II_WITH_PETSC or DEAL_II_WITH_TRILINOS required
96 *
#include <deal.II/base/conditional_ostream.h>
97 *
#include <deal.II/base/index_set.h>
98 *
#include <deal.II/base/utilities.h>
99 *
#include <deal.II/distributed/grid_refinement.h>
100 *
#include <deal.II/distributed/tria.h>
101 *
#include <deal.II/dofs/dof_handler.h>
102 *
#include <deal.II/dofs/dof_tools.h>
103 *
#include <deal.II/fe/fe_q.h>
104 *
#include <deal.II/fe/fe_values.h>
105 *
#include <deal.II/grid/grid_generator.h>
106 *
#include <deal.II/lac/affine_constraints.h>
107 *
#include <deal.II/lac/dynamic_sparsity_pattern.h>
108 *
#include <deal.II/lac/full_matrix.h>
109 *
#include <deal.II/lac/solver_cg.h>
110 *
#include <deal.II/lac/sparsity_tools.h>
111 *
#include <deal.II/lac/vector.h>
112 *
#include <deal.II/numerics/data_out.h>
113 *
#include <deal.II/numerics/error_estimator.h>
114 *
#include <deal.II/numerics/matrix_creator.h>
115 *
#include <deal.II/numerics/matrix_tools.h>
116 *
#include <deal.II/numerics/solution_transfer.h>
117 *
#include <deal.II/numerics/vector_tools.h>
120 *
#include <iostream>
122 *
namespace MPIHeatEquation {
125 *
template <
int dim>
class HeatEquation {
131 *
void setup_system();
132 *
void assemble_system(
const double &time);
133 *
void solve_time_step();
134 *
void output_results()
const;
135 *
void refine_mesh(
const unsigned int min_grid_level,
136 *
const unsigned int max_grid_level);
151 *
LA::MPI::SparseMatrix system_matrix;
153 *
LA::MPI::Vector locally_relevant_solution;
154 *
LA::MPI::Vector old_locally_relevant_solution;
155 *
LA::MPI::Vector system_rhs;
159 *
unsigned int timestep_number;
160 *
const double theta;
163 *
template <
int dim>
class RightHandSide :
public Function<dim> {
165 *
RightHandSide() :
Function<dim>(), period(0.2) {}
168 *
const unsigned int component = 0)
const override;
171 *
const double period;
175 *
double RightHandSide<dim>::value(
const Point<dim> &p,
176 *
const unsigned int component)
const {
179 *
Assert(dim == 2, ExcNotImplemented());
181 *
const double time = this->
get_time();
182 *
const double point_within_period =
183 *
(time / period - std::floor(time / period));
185 *
if ((point_within_period >= 0.0) && (point_within_period <= 0.2)) {
186 *
if ((p[0] > 0.5) && (p[1] > -0.5))
190 *
}
else if ((point_within_period >= 0.5) && (point_within_period <= 0.7)) {
191 *
if ((p[0] > -0.5) && (p[1] > 0.5))
199 *
template <
int dim>
class BoundaryValues :
public Function<dim> {
202 *
const unsigned int component = 0)
const override;
206 *
double BoundaryValues<dim>::value(
const Point<dim> & ,
207 *
const unsigned int component)
const {
209 *
Assert(component == 0, ExcIndexRange(component, 0, 1));
215 *
HeatEquation<dim>::HeatEquation()
217 *
: mpi_communicator(MPI_COMM_WORLD),
222 *
triangulation(mpi_communicator), fe(1), dof_handler(triangulation),
223 *
time_step(1. / 500),
theta(0.5) {}
225 *
template <
int dim>
void HeatEquation<dim>::setup_system() {
228 *
dof_handler.distribute_dofs(fe);
231 *
<<
"===========================================" << std::endl
232 *
<<
" Number of active cells: "
233 *
<< triangulation.n_global_active_cells() << std::endl
234 *
<<
" Number of degrees of freedom: " << dof_handler.n_dofs()
237 *
locally_owned_dofs = dof_handler.locally_owned_dofs();
239 *
locally_relevant_solution.reinit(locally_owned_dofs, locally_relevant_dofs,
241 *
old_locally_relevant_solution.reinit(locally_owned_dofs,
242 *
locally_relevant_dofs, mpi_communicator);
243 *
system_rhs.reinit(locally_owned_dofs, mpi_communicator);
245 *
constraints.clear();
246 *
constraints.reinit(locally_owned_dofs, locally_relevant_dofs);
250 *
constraints.close();
255 *
dsp,locally_owned_dofs, mpi_communicator,
256 *
locally_relevant_dofs);
258 *
system_matrix.reinit(locally_owned_dofs, locally_owned_dofs, dsp,
262 *
template <
int dim>
void HeatEquation<dim>::assemble_system(
const double &time) {
265 *
const QGauss<dim> quadrature_formula(fe.degree + 1);
270 *
const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
271 *
const unsigned int n_q_points = quadrature_formula.size();
280 *
std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
281 *
std::vector<double> rhs_values(n_q_points);
282 *
std::vector<double> rhs_values_old(n_q_points);
283 *
for (
const auto &cell : dof_handler.active_cell_iterators())
284 *
if (cell->is_locally_owned())
288 *
cell_mass_matrix = 0;
289 *
cell_laplace_matrix = 0;
291 *
cell_forcing_terms = 0;
294 *
fe_values.reinit(cell);
296 *
for (
const unsigned int q_point : fe_values.quadrature_point_indices()) {
297 *
for (
const unsigned int i : fe_values.dof_indices()) {
299 *
for (
const unsigned int j : fe_values.dof_indices()) {
301 *
cell_mass_matrix(i, j) += fe_values.shape_value(i, q_point) *
302 *
fe_values.shape_value(j, q_point) *
303 *
fe_values.JxW(q_point);
304 *
cell_laplace_matrix(i, j) += fe_values.shape_grad(i, q_point) *
305 *
fe_values.shape_grad(j, q_point) *
306 *
fe_values.JxW(q_point);
309 *
((fe_values.shape_value(i, q_point) *
310 *
fe_values.shape_value(j, q_point)) +
311 *
(theta * time_step * fe_values.shape_grad(i, q_point) *
312 *
fe_values.shape_grad(j, q_point))) *
313 *
fe_values.JxW(q_point);
320 * First compute M*U_old -(1-
theta)*k*A*U_old
323 *
cell->get_dof_indices(local_dof_indices);
325 *
cell->get_dof_values(old_locally_relevant_solution, old_cell_solution);
326 *
cell_mass_matrix.vmult(cell_rhs, old_cell_solution);
327 *
cell_laplace_matrix.vmult(cell_tmp, old_cell_solution);
328 *
cell_rhs.add(-(1 - theta) * time_step, cell_tmp);
335 *
RightHandSide<dim> rhs_function;
341 *
rhs_function.set_time(time);
342 *
rhs_function.value_list(fe_values.get_quadrature_points(), rhs_values);
343 *
for (
const unsigned int q_point : fe_values.quadrature_point_indices())
344 *
for (
const unsigned
int i : fe_values.dof_indices())
345 *
cell_rhs(i) += time_step *
theta *
346 *
(fe_values.shape_value(i, q_point) *
347 *
rhs_values[q_point] * fe_values.JxW(q_point));
351 * Adding:k*(1-
theta)*F^{n-1}
354 *
rhs_function.set_time(time - time_step);
355 *
rhs_function.value_list(fe_values.get_quadrature_points(),
357 *
for (
const unsigned int q_point : fe_values.quadrature_point_indices())
358 *
for (
const unsigned
int i : fe_values.dof_indices())
359 *
cell_rhs(i) += time_step * (1 -
theta) *
360 *
(fe_values.shape_value(i, q_point) *
361 *
rhs_values_old[q_point] * fe_values.JxW(q_point));
363 *
constraints.distribute_local_to_global(
364 *
cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs);
371 *
template <
int dim>
void HeatEquation<dim>::solve_time_step() {
374 *
LA::MPI::Vector completely_distributed_solution(locally_owned_dofs,
377 *
SolverControl solver_control(1000, 1e-8 * system_rhs.l2_norm());
381 *
LA::MPI::PreconditionAMG::AdditionalData
data;
382 *
#ifdef USE_PETSC_LA
383 *
data.symmetric_operator =
true;
387 *
LA::MPI::PreconditionAMG preconditioner;
388 *
preconditioner.initialize(system_matrix,
data);
390 *
solver.solve(system_matrix, completely_distributed_solution, system_rhs,
393 *
pcout <<
" Solved in " << solver_control.last_step() <<
" iterations."
396 *
constraints.distribute(completely_distributed_solution);
398 *
locally_relevant_solution = completely_distributed_solution;
401 *
template <
int dim>
void HeatEquation<dim>::output_results()
const {
404 *
data_out.add_data_vector(locally_relevant_solution,
"T");
407 *
for (
unsigned int i = 0; i < subdomain.size(); ++i)
408 *
subdomain(i) = triangulation.locally_owned_subdomain();
409 *
data_out.add_data_vector(subdomain,
"subdomain");
411 *
data_out.build_patches();
414 *
data_out.write_vtu_with_pvtu_record(
"./",
"solution", timestep_number,
415 *
mpi_communicator, 2, 8);
419 *
void HeatEquation<dim>::refine_mesh(
const unsigned int min_grid_level,
420 *
const unsigned int max_grid_level)
425 *
triangulation.n_locally_owned_active_cells());
430 *
locally_relevant_solution, estimated_error_per_cell);
433 *
triangulation, estimated_error_per_cell, 0.6, 0.4);
435 *
if (triangulation.n_levels() > max_grid_level) {
436 *
for (
const auto &cell :
437 *
triangulation.active_cell_iterators_on_level(max_grid_level))
438 *
if (cell->is_locally_owned())
439 *
cell->clear_refine_flag();
441 *
for (
const auto &cell :
442 *
triangulation.active_cell_iterators_on_level(min_grid_level)) {
443 *
if (cell->is_locally_owned())
444 *
cell->clear_coarsen_flag();
449 *
LA::MPI::Vector previous_locally_relevant_solution(
450 *
locally_owned_dofs, locally_relevant_dofs, mpi_communicator);
451 *
previous_locally_relevant_solution = locally_relevant_solution;
452 *
triangulation.prepare_coarsening_and_refinement();
453 *
solution_trans.prepare_for_coarsening_and_refinement(
454 *
previous_locally_relevant_solution);
455 *
triangulation.execute_coarsening_and_refinement();
457 *
LA::MPI::Vector completely_distributed_solution(locally_owned_dofs,
460 *
solution_trans.interpolate(completely_distributed_solution);
461 *
constraints.distribute(completely_distributed_solution);
462 *
locally_relevant_solution = completely_distributed_solution;
465 *
template <
int dim>
void HeatEquation<dim>::run() {
466 *
pcout <<
"Running with "
467 *
#ifdef USE_PETSC_LA
473 *
<<
" MPI rank(s)..." << std::endl;
475 *
const unsigned int initial_global_refinement = 2;
476 *
const unsigned int n_adaptive_pre_refinement_steps = 4;
478 *
triangulation.refine_global(initial_global_refinement);
482 *
unsigned int pre_refinement_step = 0;
484 *
start_time_iteration:
487 *
timestep_number = 0;
489 *
LA::MPI::Vector completely_distributed_solution(locally_owned_dofs,
492 *
completely_distributed_solution);
493 *
old_locally_relevant_solution = completely_distributed_solution;
495 *
locally_relevant_solution = completely_distributed_solution;
502 *
const double end_time = 0.5;
503 *
while (time < end_time) {
506 *
while (time <= end_time) {
512 *
pcout <<
"Time step " << timestep_number <<
" at t=" << time << std::endl;
514 *
system_rhs.reinit(locally_owned_dofs, mpi_communicator);
518 *
dsp, dof_handler.locally_owned_dofs(), mpi_communicator,
519 *
locally_relevant_dofs);
520 *
system_matrix.reinit(locally_owned_dofs, locally_owned_dofs, dsp,
523 *
assemble_system(time);
530 *
computing_timer.print_summary();
531 *
computing_timer.reset();
532 *
pcout << std::endl;
534 *
if ((timestep_number == 1) &&
535 *
(pre_refinement_step < n_adaptive_pre_refinement_steps)) {
536 *
refine_mesh(initial_global_refinement,
537 *
initial_global_refinement + n_adaptive_pre_refinement_steps);
538 *
++pre_refinement_step;
540 *
pcout << std::endl;
542 *
goto start_time_iteration;
543 *
}
else if ((timestep_number > 0) && (timestep_number % 5 == 0)) {
544 *
refine_mesh(initial_global_refinement,
545 *
initial_global_refinement + n_adaptive_pre_refinement_steps);
548 *
old_locally_relevant_solution = locally_relevant_solution;
553 *
int main(
int argc,
char *argv[]) {
562 *
using namespace MPIHeatEquation;
571 *
HeatEquation<2> heat_equation_solver;
572 *
heat_equation_solver.run();
573 *
}
catch (std::exception &exc) {
574 *
std::cerr << std::endl
576 *
<<
"----------------------------------------------------"
578 *
std::cerr <<
"Exception on processing: " << std::endl
579 *
<< exc.what() << std::endl
580 *
<<
"Aborting!" << std::endl
581 *
<<
"----------------------------------------------------"
586 *
std::cerr << std::endl
588 *
<<
"----------------------------------------------------"
590 *
std::cerr <<
"Unknown exception!" << std::endl
591 *
<<
"Aborting!" << std::endl
592 *
<<
"----------------------------------------------------"
* * for(const auto &cell :triangulation.active_cell_iterators())
* * int main(int argc, char **argv)
* * * struct InterferenceTaperTransform *
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
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, Number > * > &neumann_bc, const ReadVector< Number > &solution, Vector< float > &error, const ComponentMask &component_mask={}, 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)
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
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={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ 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 hyper_L(Triangulation< dim > &tria, const double left=-1., const double right=1., const bool colorize=false)
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.)
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
* * * ScaleZFunction< dim, Number, components >::ScaleZFunction * component(component)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
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)
void refine_and_coarsen_fixed_fraction(::Triangulation< dim, spacedim > &tria, const ::Vector< Number > &criteria, const double top_fraction_of_error, const double bottom_fraction_of_error, const VectorTools::NormType norm_type=VectorTools::L1_norm)