40#include <boost/algorithm/string.hpp>
42template <
int dim,
int spacedim>
57 spacedim>::construct_multigrid_hierarchy)
63template <
int dim,
int spacedim>
66 const std::string &ids_and_cad_file_names,
71 grid_in.
read(grid_file_name);
72#ifdef DEAL_II_WITH_OPENCASCADE
73 using map_type = std::map<types::manifold_id, std::string>;
75 for (
const auto &pair : Converter::to_value(ids_and_cad_file_names))
77 const auto &manifold_id = pair.first;
78 const auto &cad_file_name = pair.second;
79 const auto extension = boost::to_lower_copy(
80 cad_file_name.substr(cad_file_name.find_last_of(
'.') + 1));
82 if (extension ==
"iges" || extension ==
"igs")
84 else if (extension ==
"step" || extension ==
"stp")
88 ExcNotImplemented(
"We found an extension that we "
89 "do not recognize as a CAD file "
90 "extension. Bailing out."));
92 if ((std::get<0>(n_elements) == 0))
96 else if (spacedim == 3)
99 t->set_manifold(manifold_id,
106 TopoDS::Face(shape)));
109 (void)ids_and_cad_file_names;
110 AssertThrow(
false, ExcNotImplemented(
"Generation of the grid failed."));
116template <
int dim,
int spacedim>
124 par.arguments_for_grid);
128 pcout <<
"Generating from name and argument failed." << std::endl
129 <<
"Trying to read from file name." << std::endl;
132 tria.refine_global(
par.initial_refinement);
137template <
int dim,
int spacedim>
143 quadrature = std::make_unique<QGauss<spacedim>>(
par.fe_degree + 1);
147template <
int dim,
int spacedim>
152 dh.distribute_dofs(*
fe);
153#ifdef MATRIX_FREE_PATH
154 dh.distribute_mg_dofs();
164 for (
const auto id :
par.dirichlet_ids)
169#ifdef MATRIX_FREE_PATH
175 std::shared_ptr<MatrixFree<spacedim, double>> system_mf_storage(
177 system_mf_storage->reinit(
183 const unsigned int nlevels =
tria.n_global_levels();
184 mg_matrices.resize(0, nlevels - 1);
186 const std::set<types::boundary_id> dirichlet_boundary_ids = {0};
187 mg_constrained_dofs.initialize(
dh);
188 mg_constrained_dofs.make_zero_boundary_constraints(
189 dh, dirichlet_boundary_ids);
194 dh.locally_owned_mg_dofs(
level),
197 mg_constrained_dofs.get_boundary_indices(
level))
199 level_constraints.
close();
202 additional_data_level;
208 std::shared_ptr<MatrixFree<spacedim, float>> mg_mf_storage_level =
209 std::make_shared<MatrixFree<spacedim, float>>();
210 mg_mf_storage_level->reinit(
mapping,
214 additional_data_level);
216 mg_matrices[
level].initialize(mg_mf_storage_level,
242 auto inclusions_set =
246 owned_dofs[1] = inclusions_set.tensor_product(
281#ifdef MATRIX_FREE_PATH
289 pcout <<
" Number of degrees of freedom: " <<
owned_dofs[0].size() <<
" + "
291 <<
" (locally owned: " <<
owned_dofs[0].n_elements() <<
" + "
292 <<
owned_dofs[1].n_elements() <<
")" << std::endl;
296#ifndef MATRIX_FREE_PATH
297template <
int dim,
int spacedim>
308 const unsigned int dofs_per_cell =
fe->n_dofs_per_cell();
309 const unsigned int n_q_points =
quadrature->size();
312 std::vector<double> rhs_values(n_q_points);
313 std::vector<Tensor<1, spacedim>> grad_phi_u(dofs_per_cell);
314 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
316 for (
const auto &cell :
dh.active_cell_iterators())
317 if (cell->is_locally_owned())
323 for (
unsigned int q = 0; q < n_q_points; ++q)
325 for (
unsigned int k = 0; k < dofs_per_cell; ++k)
326 grad_phi_u[k] = fe_values[scalar].gradient(k, q);
327 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
329 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
332 grad_phi_u[i] * grad_phi_u[j] * fe_values.
JxW(q);
334 cell_rhs(i) += fe_values.
shape_value(i, q) * rhs_values[q] *
338 cell->get_dof_indices(local_dof_indices);
339 constraints.distribute_local_to_global(cell_matrix,
351template <
int dim,
int spacedim>
359 std::vector<types::global_dof_index> dof_indices(
fe->n_dofs_per_cell());
360 std::vector<types::global_dof_index> inclusion_dof_indices;
362 auto particle =
inclusions.inclusions_as_particles.begin();
363 while (particle !=
inclusions.inclusions_as_particles.end())
365 const auto &cell = particle->get_surrounding_cell();
368 dh_cell->get_dof_indices(dof_indices);
371 inclusions.inclusions_as_particles.particles_in_cell(cell);
372 Assert(pic.begin() == particle, ExcInternalError());
373 std::set<types::global_dof_index> inclusion_dof_indices_set;
374 for (
const auto &p : pic)
376 const auto ids =
inclusions.get_dof_indices(p.get_id());
377 inclusion_dof_indices_set.insert(ids.begin(), ids.end());
379 inclusion_dof_indices.resize(0);
380 inclusion_dof_indices.insert(inclusion_dof_indices.begin(),
381 inclusion_dof_indices_set.begin(),
382 inclusion_dof_indices_set.end());
384 constraints.add_entries_local_to_global(dof_indices,
386 inclusion_dof_indices,
389 relevant.
add_indices(inclusion_dof_indices.begin(),
390 inclusion_dof_indices.end());
391 particle = pic.end();
398template <
int dim,
int spacedim>
403 pcout <<
"Assemble coupling matrix. " << std::endl;
405 std::vector<types::global_dof_index> fe_dof_indices(
fe->n_dofs_per_cell());
406 std::vector<types::global_dof_index> inclusion_dof_indices(
413 fe->n_dofs_per_cell());
420 auto particle =
inclusions.inclusions_as_particles.begin();
421 while (particle !=
inclusions.inclusions_as_particles.end())
423 const auto &cell = particle->get_surrounding_cell();
426 dh_cell->get_dof_indices(fe_dof_indices);
428 inclusions.inclusions_as_particles.particles_in_cell(cell);
429 Assert(pic.begin() == particle, ExcInternalError());
431 auto p = pic.begin();
432 auto next_p = pic.begin();
433 while (p != pic.end())
435 const auto inclusion_id =
inclusions.get_inclusion_id(p->get_id());
436 inclusion_dof_indices =
inclusions.get_dof_indices(p->get_id());
437 local_coupling_matrix = 0;
438 local_inclusion_matrix = 0;
442 std::vector<Point<spacedim>> ref_q_points;
443 for (; next_p != pic.end() &&
444 inclusions.get_inclusion_id(next_p->get_id()) == inclusion_id;
446 ref_q_points.push_back(next_p->get_reference_location());
451 for (
unsigned int q = 0; q < ref_q_points.size(); ++q)
453 const auto id = p->get_id();
454 const auto &inclusion_fe_values =
inclusions.get_fe_values(
id);
455 const auto &real_q = p->get_location();
458 for (
unsigned int j = 0; j <
inclusions.get_n_coefficients(); ++j)
460 for (
unsigned int i = 0; i <
fe->n_dofs_per_cell(); ++i)
461 local_coupling_matrix(i, j) +=
464 inclusion_fe_values[j] *
465 inclusions.get_inclusion_data(inclusion_id,
id, real_q);
467 local_inclusion_matrix(j, j) +=
468 (inclusion_fe_values[j] * inclusion_fe_values[j] /
469 inclusion_fe_values[0]);
474 Assert(p == next_p, ExcInternalError());
477 constraints.distribute_local_to_global(local_coupling_matrix,
480 inclusion_dof_indices,
483 local_rhs, inclusion_dof_indices,
system_rhs.block(1));
488 particle = pic.end();
491#ifndef MATRIX_FREE_PATH
500#ifdef MATRIX_FREE_PATH
501template <
int dim,
int spacedim>
505 stiffness_matrix.get_matrix_free()->initialize_dof_vector(solution.block(0));
506 stiffness_matrix.get_matrix_free()->initialize_dof_vector(
507 system_rhs.block(0));
509 solution.block(0) = 0;
510 constraints.distribute(solution.block(0));
511 solution.block(0).update_ghost_values();
513 FEEvaluation<spacedim, -1> phi(*stiffness_matrix.get_matrix_free());
514 for (
unsigned int cell = 0;
515 cell < stiffness_matrix.get_matrix_free()->n_cell_batches();
519 phi.read_dof_values_plain(solution.block(0));
521 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
524 phi.quadrature_point(q);
527 for (
unsigned int v = 0; v < VectorizedArray<double>::size(); ++v)
530 for (
unsigned int d = 0;
d < spacedim; ++
d)
532 f_value[v] = par.rhs.value(p);
534 phi.submit_gradient(-phi.get_gradient(q), q);
535 phi.submit_value(f_value, q);
538 phi.distribute_local_to_global(system_rhs.block(0));
546template <
int dim,
int spacedim>
551 pcout <<
"Preparing solve." << std::endl;
553#ifdef MATRIX_FREE_PATH
555 using Payload = dealii::internal::LinearOperatorImplementation::EmptyPayload;
569 smoother_data.
resize(0,
tria.n_global_levels() - 1);
574 smoother_data[
level].smoothing_range = 15.;
575 smoother_data[
level].degree = 5;
576 smoother_data[
level].eig_cg_n_iterations = 10;
580 smoother_data[0].smoothing_range = 1
e-3;
582 smoother_data[0].eig_cg_n_iterations = mg_matrices[0].m();
584 mg_matrices[
level].compute_diagonal();
585 smoother_data[
level].preconditioner =
586 mg_matrices[
level].get_matrix_diagonal_inverse();
588 mg_smoother.initialize(mg_matrices, smoother_data);
597 mg_interface_matrices;
598 mg_interface_matrices.
resize(0,
tria.n_global_levels() - 1);
600 mg_interface_matrices[
level].initialize(mg_matrices[
level]);
602 mg_interface_matrices);
605 mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother);
606 mg.set_edge_matrices(mg_interface, mg_interface);
611 preconditioner(
dh,
mg, mg_transfer);
621 LA::MPI::PreconditionAMG prec_A;
623 LA::MPI::PreconditionAMG::AdditionalData
data;
625 data.symmetric_operator =
true;
627 pcout <<
"Initialize AMG...";
629 pcout <<
"done." << std::endl;
650#ifdef MATRIX_FREE_PATH
653 Bt.reinit_range_vector = [
this](
VectorType &vec,
const bool) {
656 Bt.reinit_domain_vector = [
this](
VectorType &vec,
const bool) {
670 pcout <<
" Prepare schur... ";
671 const auto S = B * invA * Bt;
672 pcout <<
"S was built." << std::endl;
679 pcout <<
" f norm: " << f.l2_norm() <<
", g norm: " << g.l2_norm()
683 lambda = invS * (B * invA * f - g);
684 pcout <<
" Solved for lambda in " <<
par.outer_control.last_step()
685 <<
" iterations." << std::endl;
688 u = invA * (f - Bt * lambda);
689 pcout <<
" u norm: " << u.l2_norm()
690 <<
", lambda norm: " << lambda.l2_norm() << std::endl;
693 pcout <<
" Solved for u in " <<
par.inner_control.last_step()
694 <<
" iterations." << std::endl;
703template <
int dim,
int spacedim>
715 if (
par.refinement_strategy ==
"fixed_fraction")
718 tria, error_per_cell,
par.refinement_fraction,
par.coarsening_fraction);
720 else if (
par.refinement_strategy ==
"fixed_number")
725 par.refinement_fraction,
726 par.coarsening_fraction,
729 else if (
par.refinement_strategy ==
"global")
730 for (
const auto &cell :
tria.active_cell_iterators())
731 cell->set_refine_flag();
734 tria.prepare_coarsening_and_refinement();
735 inclusions.inclusions_as_particles.prepare_for_coarsening_and_refinement();
738 tria.execute_coarsening_and_refinement();
739 inclusions.inclusions_as_particles.unpack_after_coarsening_and_refinement();
748template <
int dim,
int spacedim>
753 std::string solution_name =
"solution";
758 for (
unsigned int i = 0; i < subdomain.
size(); ++i)
759 subdomain(i) =
tria.locally_owned_subdomain();
762 const std::string filename =
763 par.output_name +
"_" + std::to_string(
cycle) +
".vtu";
786template <
int dim,
int spacedim>
790 static std::vector<std::pair<double, std::string>> cycles_and_solutions;
791 static std::vector<std::pair<double, std::string>> cycles_and_particles;
793 if (cycles_and_solutions.size() ==
cycle)
797 const std::string particles_filename =
798 par.output_name +
"_particles_" + std::to_string(
cycle) +
".vtu";
802 cycles_and_particles.push_back({(double)
cycle, particles_filename});
804 std::ofstream pvd_solutions(
par.output_directory +
"/" +
par.output_name +
806 std::ofstream pvd_particles(
par.output_directory +
"/" +
par.output_name +
813template <
int dim,
int spacedim>
819 <<
"> using PETSc." << std::endl;
822 <<
"> using Trilinos." << std::endl;
824 par.prm.print_parameters(
par.output_directory +
"/" +
"used_parameters_" +
825 std::to_string(dim) + std::to_string(spacedim) +
830template <
int dim,
int spacedim>
841 if (
par.output_results_before_solving)
843#ifdef MATRIX_FREE_PATH
849#ifdef MATRIX_FREE_PATH
851 coupling_operator = std::make_unique<CouplingOperator<spacedim, double>>(
857 par.convergence_table.error_from_exact(
dh,
860 if (
cycle !=
par.n_refinement_cycles - 1)
862 if (
pcout.is_active())
863 par.convergence_table.output_table(
pcout.get_stream());
void constrain_dof_to_zero(const size_type constrained_dof)
void write_vtu_in_parallel(const std::string &filename, const MPI_Comm comm) const
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
void add_data_vector(const VectorType &data, const std::vector< std::string > &names, const DataVectorType type=type_automatic, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretation={})
virtual void build_patches(const unsigned int n_subdivisions=0)
void add(const size_type i, const size_type j)
const std::vector< Point< spacedim > > & get_quadrature_points() const
double JxW(const unsigned int q_point) const
const double & shape_value(const unsigned int i, const unsigned int q_point) const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
void attach_triangulation(Triangulation< dim, spacedim > &tria)
void read(std::istream &in, Format format=Default)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
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)
void initialize(const MGSmootherBase< VectorType > &coarse_smooth)
void resize(const unsigned int new_minlevel, const unsigned int new_maxlevel, Args &&...args)
void build(const DoFHandler< dim > &dof_handler, const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > &external_partitioners=std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > >())
void prepare_for_coarsening_and_refinement(const std::vector< const VectorType * > &all_in)
void interpolate(std::vector< VectorType * > &all_out)
virtual size_type size() const override
DoFHandler< spacedim > dh
Inclusions< spacedim > inclusions
AffineConstraints< double > inclusion_constraints
LA::MPI::SparseMatrix inclusion_matrix
std::unique_ptr< FiniteElement< spacedim > > fe
LA::MPI::SparseMatrix coupling_matrix
PoissonProblem(const ProblemParameters< dim, spacedim > &par)
BlockVectorType system_rhs
const ProblemParameters< dim, spacedim > & par
void output_results() const
std::unique_ptr< Quadrature< spacedim > > quadrature
LA::MPI::SparseMatrix stiffness_matrix
void refine_and_transfer()
LA::MPI::Vector VectorType
parallel::distributed::Triangulation< spacedim > tria
BlockVectorType locally_relevant_solution
TimerOutput computing_timer
MPI_Comm mpi_communicator
std::string output_solution() const
AffineConstraints< double > constraints
MappingQ< spacedim > mapping
std::vector< IndexSet > owned_dofs
void print_parameters() const
void assemble_poisson_system()
std::vector< IndexSet > relevant_dofs
IndexSet assemble_coupling_sparsity(DynamicSparsityPattern &dsp) const
#define Assert(cond, exc)
#define AssertThrow(cond, exc)
LinearOperator< Range, Domain, Payload > linear_operator(const OperatorExemplar &, const Matrix &)
LinearOperator< Domain, Range, Payload > transpose_operator(const LinearOperator< Range, Domain, Payload > &op)
LinearOperator< Domain, Range, Payload > inverse_operator(const LinearOperator< Range, Domain, Payload > &op, Solver &solver, const Preconditioner &preconditioner)
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)
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
IndexSet complete_index_set(const IndexSet::size_type N)
void read_grid_and_cad_files(const std::string &grid_file_name, const std::string &ids_and_cad_file_names, Triangulation< dim, spacedim > &tria)
std::vector< index_type > data
void write_pvd_record(std::ostream &out, const std::vector< std::pair< double, std::string > > ×_and_names)
void generate_from_name_and_arguments(Triangulation< dim, spacedim > &tria, const std::string &grid_generator_function_name, const std::string &grid_generator_function_arguments)
std::tuple< unsigned int, unsigned int, unsigned int > count_elements(const TopoDS_Shape &shape)
TopoDS_Shape read_STEP(const std::string &filename, const double scale_factor=1e-3)
TopoDS_Shape read_IGES(const std::string &filename, const double scale_factor=1e-3)
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
IndexSet create_evenly_distributed_partitioning(const MPI_Comm comm, const types::global_dof_index total_size)
std::string dim_string(const int dim, const int spacedim)
constexpr unsigned int invalid_unsigned_int
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)
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())
::SolutionTransfer< dim, VectorType, spacedim > SolutionTransfer
unsigned int global_dof_index
TasksParallelScheme tasks_parallel_scheme
UpdateFlags mapping_update_flags