Reduced Lagrange Multipliers
 
Loading...
Searching...
No Matches
laplacian.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2024 by Luca Heltai
4//
5// This file is part of the reduced_lagrange_multipliers application, based on
6// the deal.II library.
7//
8// The reduced_lagrange_multipliers application is free software; you can use
9// it, redistribute it, and/or modify it under the terms of the Apache-2.0
10// License WITH LLVM-exception as published by the Free Software Foundation;
11// either version 3.0 of the License, or (at your option) any later version. The
12// full text of the license can be found in the file LICENSE.md at the top level
13// of the reduced_lagrange_multipliers distribution.
14//
15// ---------------------------------------------------------------------
16
17/* ---------------------------------------------------------------------
18 *
19 * Copyright (C) 2000 - 2020 by the deal.II authors
20 *
21 * This file is part of the deal.II library.
22 *
23 * The deal.II library is free software; you can use it, redistribute
24 * it, and/or modify it under the terms of the GNU Lesser General
25 * Public License as published by the Free Software Foundation; either
26 * version 2.1 of the License, or (at your option) any later version.
27 * The full text of the license can be found in the file LICENSE.md at
28 * the top level directory of deal.II.
29 *
30 * ---------------------------------------------------------------------
31 *
32 * Author: Wolfgang Bangerth, University of Heidelberg, 2000
33 * Modified by: Luca Heltai, 2020
34 */
35
36
37
38#include "laplacian.h"
39
40#include <boost/algorithm/string.hpp>
41
42template <int dim, int spacedim>
45 : par(par)
46 , mpi_communicator(MPI_COMM_WORLD)
47 , pcout(std::cout, (Utilities::MPI::this_mpi_process(mpi_communicator) == 0))
49 pcout,
50 TimerOutput::summary,
51 TimerOutput::wall_times)
53 typename Triangulation<spacedim>::MeshSmoothing(
54 Triangulation<spacedim>::smoothing_on_refinement |
55 Triangulation<spacedim>::smoothing_on_coarsening),
56 parallel::distributed::Triangulation<
57 spacedim>::construct_multigrid_hierarchy)
58 , dh(tria)
59 , mapping(1)
60{}
61
62
63template <int dim, int spacedim>
64void
65read_grid_and_cad_files(const std::string &grid_file_name,
66 const std::string &ids_and_cad_file_names,
68{
70 grid_in.attach_triangulation(tria);
71 grid_in.read(grid_file_name);
72#ifdef DEAL_II_WITH_OPENCASCADE
73 using map_type = std::map<types::manifold_id, std::string>;
74 using Converter = Patterns::Tools::Convert<map_type>;
75 for (const auto &pair : Converter::to_value(ids_and_cad_file_names))
76 {
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));
81 TopoDS_Shape shape;
82 if (extension == "iges" || extension == "igs")
83 shape = OpenCASCADE::read_IGES(cad_file_name);
84 else if (extension == "step" || extension == "stp")
85 shape = OpenCASCADE::read_STEP(cad_file_name);
86 else
87 AssertThrow(false,
88 ExcNotImplemented("We found an extension that we "
89 "do not recognize as a CAD file "
90 "extension. Bailing out."));
91 const auto n_elements = OpenCASCADE::count_elements(shape);
92 if ((std::get<0>(n_elements) == 0))
93 tria.set_manifold(
94 manifold_id,
96 else if (spacedim == 3)
97 {
98 const auto t = reinterpret_cast<Triangulation<dim, 3> *>(&tria);
99 t->set_manifold(manifold_id,
101 shape));
102 }
103 else
104 tria.set_manifold(manifold_id,
106 TopoDS::Face(shape)));
107 }
108#else
109 (void)ids_and_cad_file_names;
110 AssertThrow(false, ExcNotImplemented("Generation of the grid failed."));
111#endif
112}
113
114
115
116template <int dim, int spacedim>
117void
119{
120 try
121 {
123 par.name_of_grid,
124 par.arguments_for_grid);
125 }
126 catch (...)
127 {
128 pcout << "Generating from name and argument failed." << std::endl
129 << "Trying to read from file name." << std::endl;
130 read_grid_and_cad_files(par.name_of_grid, par.arguments_for_grid, tria);
131 }
132 tria.refine_global(par.initial_refinement);
133}
134
135
136
137template <int dim, int spacedim>
138void
140{
141 TimerOutput::Scope t(computing_timer, "Initial setup");
142 fe = std::make_unique<FESystem<spacedim>>(FE_Q<spacedim>(par.fe_degree), 1);
143 quadrature = std::make_unique<QGauss<spacedim>>(par.fe_degree + 1);
144}
145
146
147template <int dim, int spacedim>
148void
150{
151 TimerOutput::Scope t(computing_timer, "Setup dofs");
152 dh.distribute_dofs(*fe);
153#ifdef MATRIX_FREE_PATH
154 dh.distribute_mg_dofs();
155#endif
156
157 owned_dofs.resize(2);
158 owned_dofs[0] = dh.locally_owned_dofs();
159 relevant_dofs.resize(2);
161 {
162 constraints.reinit(owned_dofs[0], relevant_dofs[0]);
164 for (const auto id : par.dirichlet_ids)
166 constraints.close();
167 }
168 {
169#ifdef MATRIX_FREE_PATH
170 typename MatrixFree<spacedim, double>::AdditionalData additional_data;
171 additional_data.tasks_parallel_scheme =
173 additional_data.mapping_update_flags =
175 std::shared_ptr<MatrixFree<spacedim, double>> system_mf_storage(
177 system_mf_storage->reinit(
178 mapping, dh, constraints, QGauss<1>(fe->degree + 1), additional_data);
179 stiffness_matrix.initialize(system_mf_storage);
180
181 // Perform setup for matrix-free multigrid
182 {
183 const unsigned int nlevels = tria.n_global_levels();
184 mg_matrices.resize(0, nlevels - 1);
185
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);
190
191 for (unsigned int level = 0; level < nlevels; ++level)
192 {
193 AffineConstraints<double> level_constraints(
194 dh.locally_owned_mg_dofs(level),
196 for (const types::global_dof_index dof_index :
197 mg_constrained_dofs.get_boundary_indices(level))
198 level_constraints.constrain_dof_to_zero(dof_index);
199 level_constraints.close();
200
202 additional_data_level;
203 additional_data_level.tasks_parallel_scheme =
205 additional_data_level.mapping_update_flags =
207 additional_data_level.mg_level = 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,
211 dh,
212 level_constraints,
213 QGauss<1>(fe->degree + 1),
214 additional_data_level);
215
216 mg_matrices[level].initialize(mg_mf_storage_level,
217 mg_constrained_dofs,
218 level);
219 }
220 }
221
222
223#else
224 stiffness_matrix.clear();
228 owned_dofs[0],
230 relevant_dofs[0]);
232 owned_dofs[0],
233 dsp,
235
236#endif
237 }
238 inclusion_constraints.close();
239
240 if (inclusions.n_dofs() > 0)
241 {
242 auto inclusions_set =
244 mpi_communicator, inclusions.n_inclusions());
245
246 owned_dofs[1] = inclusions_set.tensor_product(
247 complete_index_set(inclusions.get_n_coefficients()));
248
249 coupling_matrix.clear();
250 DynamicSparsityPattern dsp(dh.n_dofs(),
251 inclusions.n_dofs(),
252 relevant_dofs[0]);
253
256 owned_dofs[0],
258 relevant_dofs[0]);
259 coupling_matrix.reinit(owned_dofs[0],
260 owned_dofs[1],
261 dsp,
263
265 inclusions.n_dofs(),
266 relevant_dofs[1]);
267 for (const auto i : relevant_dofs[1])
268 idsp.add(i, i);
270 owned_dofs[1],
272 relevant_dofs[1]);
274 owned_dofs[1],
275 idsp,
277 }
278
280
281#ifdef MATRIX_FREE_PATH
284#else
287#endif
288
289 pcout << " Number of degrees of freedom: " << owned_dofs[0].size() << " + "
290 << owned_dofs[1].size()
291 << " (locally owned: " << owned_dofs[0].n_elements() << " + "
292 << owned_dofs[1].n_elements() << ")" << std::endl;
293}
294
295
296#ifndef MATRIX_FREE_PATH
297template <int dim, int spacedim>
298void
300{
302 coupling_matrix = 0;
303 system_rhs = 0;
304 FEValues<spacedim> fe_values(*fe,
305 *quadrature,
308 const unsigned int dofs_per_cell = fe->n_dofs_per_cell();
309 const unsigned int n_q_points = quadrature->size();
310 FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
311 Vector<double> cell_rhs(dofs_per_cell);
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);
315 const FEValuesExtractors::Scalar scalar(0);
316 for (const auto &cell : dh.active_cell_iterators())
317 if (cell->is_locally_owned())
318 {
319 cell_matrix = 0;
320 cell_rhs = 0;
321 fe_values.reinit(cell);
322 par.rhs.value_list(fe_values.get_quadrature_points(), rhs_values);
323 for (unsigned int q = 0; q < n_q_points; ++q)
324 {
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)
328 {
329 for (unsigned int j = 0; j < dofs_per_cell; ++j)
330 {
331 cell_matrix(i, j) +=
332 grad_phi_u[i] * grad_phi_u[j] * fe_values.JxW(q);
333 }
334 cell_rhs(i) += fe_values.shape_value(i, q) * rhs_values[q] *
335 fe_values.JxW(q);
336 }
337 }
338 cell->get_dof_indices(local_dof_indices);
339 constraints.distribute_local_to_global(cell_matrix,
340 cell_rhs,
341 local_dof_indices,
343 system_rhs.block(0));
344 }
347}
348#endif
349
350
351template <int dim, int spacedim>
354 DynamicSparsityPattern &dsp) const
355{
356 TimerOutput::Scope t(computing_timer, "Assemble Coupling sparsity");
357 IndexSet relevant(inclusions.n_dofs());
358
359 std::vector<types::global_dof_index> dof_indices(fe->n_dofs_per_cell());
360 std::vector<types::global_dof_index> inclusion_dof_indices;
361
362 auto particle = inclusions.inclusions_as_particles.begin();
363 while (particle != inclusions.inclusions_as_particles.end())
364 {
365 const auto &cell = particle->get_surrounding_cell();
366 const auto dh_cell =
367 typename DoFHandler<spacedim>::cell_iterator(*cell, &dh);
368 dh_cell->get_dof_indices(dof_indices);
369
370 const auto pic =
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)
375 {
376 const auto ids = inclusions.get_dof_indices(p.get_id());
377 inclusion_dof_indices_set.insert(ids.begin(), ids.end());
378 }
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());
383
384 constraints.add_entries_local_to_global(dof_indices,
386 inclusion_dof_indices,
387 dsp);
388
389 relevant.add_indices(inclusion_dof_indices.begin(),
390 inclusion_dof_indices.end());
391 particle = pic.end();
392 }
393 return relevant;
394}
395
396
397
398template <int dim, int spacedim>
399void
401{
402 TimerOutput::Scope t(computing_timer, "Assemble Coupling matrix");
403 pcout << "Assemble coupling matrix. " << std::endl;
404
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(
407 inclusions.get_n_coefficients());
408
409 FullMatrix<double> local_coupling_matrix(fe->n_dofs_per_cell(),
410 inclusions.get_n_coefficients());
411
412 [[maybe_unused]] FullMatrix<double> local_bulk_matrix(fe->n_dofs_per_cell(),
413 fe->n_dofs_per_cell());
414
415 FullMatrix<double> local_inclusion_matrix(inclusions.get_n_coefficients(),
416 inclusions.get_n_coefficients());
417
418 Vector<double> local_rhs(inclusions.get_n_coefficients());
419
420 auto particle = inclusions.inclusions_as_particles.begin();
421 while (particle != inclusions.inclusions_as_particles.end())
422 {
423 const auto &cell = particle->get_surrounding_cell();
424 const auto dh_cell =
425 typename DoFHandler<spacedim>::cell_iterator(*cell, &dh);
426 dh_cell->get_dof_indices(fe_dof_indices);
427 const auto pic =
428 inclusions.inclusions_as_particles.particles_in_cell(cell);
429 Assert(pic.begin() == particle, ExcInternalError());
430
431 auto p = pic.begin();
432 auto next_p = pic.begin();
433 while (p != pic.end())
434 {
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;
439 local_rhs = 0;
440
441 // Extract all points that refer to the same inclusion
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;
445 ++next_p)
446 ref_q_points.push_back(next_p->get_reference_location());
448 ref_q_points,
450 fev.reinit(dh_cell);
451 for (unsigned int q = 0; q < ref_q_points.size(); ++q)
452 {
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();
456
457 // Coupling and inclusions matrix
458 for (unsigned int j = 0; j < inclusions.get_n_coefficients(); ++j)
459 {
460 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
461 local_coupling_matrix(i, j) +=
462 (fev.shape_value(i, q)) * inclusion_fe_values[j];
463 local_rhs(j) +=
464 inclusion_fe_values[j] *
465 inclusions.get_inclusion_data(inclusion_id, id, real_q);
466
467 local_inclusion_matrix(j, j) +=
468 (inclusion_fe_values[j] * inclusion_fe_values[j] /
469 inclusion_fe_values[0]);
470 }
471 ++p;
472 }
473 // I expect p and next_p to be the same now.
474 Assert(p == next_p, ExcInternalError());
475
476 // Add local matrices to global ones
477 constraints.distribute_local_to_global(local_coupling_matrix,
478 fe_dof_indices,
480 inclusion_dof_indices,
482 inclusion_constraints.distribute_local_to_global(
483 local_rhs, inclusion_dof_indices, system_rhs.block(1));
484
485 inclusion_constraints.distribute_local_to_global(
486 local_inclusion_matrix, inclusion_dof_indices, inclusion_matrix);
487 }
488 particle = pic.end();
489 }
491#ifndef MATRIX_FREE_PATH
493#endif
496 pcout << "System rhs: " << system_rhs.l2_norm() << std::endl;
497}
498
499
500#ifdef MATRIX_FREE_PATH
501template <int dim, int spacedim>
502void
504{
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));
508 system_rhs = 0;
509 solution.block(0) = 0;
510 constraints.distribute(solution.block(0));
511 solution.block(0).update_ghost_values();
512
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();
516 ++cell)
517 {
518 phi.reinit(cell);
519 phi.read_dof_values_plain(solution.block(0));
520 phi.evaluate(EvaluationFlags::gradients);
521 for (unsigned int q = 0; q < phi.n_q_points; ++q)
522 {
524 phi.quadrature_point(q);
525
526 VectorizedArray<double> f_value = 0.0;
527 for (unsigned int v = 0; v < VectorizedArray<double>::size(); ++v)
528 {
530 for (unsigned int d = 0; d < spacedim; ++d)
531 p[d] = p_vect[d][v];
532 f_value[v] = par.rhs.value(p);
533 }
534 phi.submit_gradient(-phi.get_gradient(q), q);
535 phi.submit_value(f_value, q);
536 }
538 phi.distribute_local_to_global(system_rhs.block(0));
539 }
540
541 system_rhs.compress(VectorOperation::add);
542}
543#endif
544
545
546template <int dim, int spacedim>
547void
549{
551 pcout << "Preparing solve." << std::endl;
552 SolverCG<VectorType> cg_stiffness(par.inner_control);
553#ifdef MATRIX_FREE_PATH
554
555 using Payload = dealii::internal::LinearOperatorImplementation::EmptyPayload;
558
559 MGTransferMatrixFree<spacedim, float> mg_transfer(mg_constrained_dofs);
560 mg_transfer.build(dh);
561
562 using SmootherType =
563 PreconditionChebyshev<LevelMatrixType,
565 mg::SmootherRelaxation<SmootherType,
567 mg_smoother;
569 smoother_data.resize(0, tria.n_global_levels() - 1);
570 for (unsigned int level = 0; level < tria.n_global_levels(); ++level)
571 {
572 if (level > 0)
573 {
574 smoother_data[level].smoothing_range = 15.;
575 smoother_data[level].degree = 5;
576 smoother_data[level].eig_cg_n_iterations = 10;
577 }
578 else
579 {
580 smoother_data[0].smoothing_range = 1e-3;
581 smoother_data[0].degree = numbers::invalid_unsigned_int;
582 smoother_data[0].eig_cg_n_iterations = mg_matrices[0].m();
583 }
584 mg_matrices[level].compute_diagonal();
585 smoother_data[level].preconditioner =
586 mg_matrices[level].get_matrix_diagonal_inverse();
587 }
588 mg_smoother.initialize(mg_matrices, smoother_data);
589
591 mg_coarse;
592 mg_coarse.initialize(mg_smoother);
593
595
597 mg_interface_matrices;
598 mg_interface_matrices.resize(0, tria.n_global_levels() - 1);
599 for (unsigned int level = 0; level < tria.n_global_levels(); ++level)
600 mg_interface_matrices[level].initialize(mg_matrices[level]);
602 mg_interface_matrices);
603
605 mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother);
606 mg.set_edge_matrices(mg_interface, mg_interface);
607
608 PreconditionMG<spacedim,
611 preconditioner(dh, mg, mg_transfer);
612
613 auto invA = A;
614 invA = inverse_operator(A, cg_stiffness, preconditioner);
615#else
616 using Payload =
620
621 LA::MPI::PreconditionAMG prec_A;
622 {
623 LA::MPI::PreconditionAMG::AdditionalData data;
624# ifdef USE_PETSC_LA
625 data.symmetric_operator = true;
626# endif
627 pcout << "Initialize AMG...";
628 prec_A.initialize(stiffness_matrix, data);
629 pcout << "done." << std::endl;
630 }
631 const auto amgA = linear_operator<VectorType, VectorType, Payload>(A, prec_A);
632 auto invA = A;
633 invA = inverse_operator(A, cg_stiffness, amgA);
634#endif
635
636
637 // Some aliases
638 auto &u = solution.block(0);
639 auto &lambda = solution.block(1);
640
641 const auto &f = system_rhs.block(0);
642 const auto &g = system_rhs.block(1);
643
644 if (inclusions.n_dofs() == 0)
645 {
646 u = invA * f;
647 }
648 else
649 {
650#ifdef MATRIX_FREE_PATH
651 auto Bt =
653 Bt.reinit_range_vector = [this](VectorType &vec, const bool) {
654 vec.reinit(owned_dofs[0], relevant_dofs[0], mpi_communicator);
655 };
656 Bt.reinit_domain_vector = [this](VectorType &vec, const bool) {
657 vec.reinit(owned_dofs[1], relevant_dofs[1], mpi_communicator);
658 };
659
661#else
662 const auto Bt =
665#endif
666 const auto C =
668
669 // Schur complement
670 pcout << " Prepare schur... ";
671 const auto S = B * invA * Bt;
672 pcout << "S was built." << std::endl;
673
674 // Schur complement preconditioner
675 auto invS = S;
676 SolverCG<VectorType> cg_schur(par.outer_control);
678
679 pcout << " f norm: " << f.l2_norm() << ", g norm: " << g.l2_norm()
680 << std::endl;
681
682 // Compute Lambda first
683 lambda = invS * (B * invA * f - g);
684 pcout << " Solved for lambda in " << par.outer_control.last_step()
685 << " iterations." << std::endl;
686
687 // Then compute u
688 u = invA * (f - Bt * lambda);
689 pcout << " u norm: " << u.l2_norm()
690 << ", lambda norm: " << lambda.l2_norm() << std::endl;
691 }
692
693 pcout << " Solved for u in " << par.inner_control.last_step()
694 << " iterations." << std::endl;
695 constraints.distribute(u);
696 inclusion_constraints.distribute(lambda);
697 solution.update_ghost_values();
699}
700
701
702
703template <int dim, int spacedim>
704void
706{
708 Vector<float> error_per_cell(tria.n_active_cells());
710 QGauss<spacedim - 1>(par.fe_degree +
711 1),
712 {},
714 error_per_cell);
715 if (par.refinement_strategy == "fixed_fraction")
716 {
718 tria, error_per_cell, par.refinement_fraction, par.coarsening_fraction);
719 }
720 else if (par.refinement_strategy == "fixed_number")
721 {
723 tria,
724 error_per_cell,
725 par.refinement_fraction,
726 par.coarsening_fraction,
727 par.max_cells);
728 }
729 else if (par.refinement_strategy == "global")
730 for (const auto &cell : tria.active_cell_iterators())
731 cell->set_refine_flag();
732
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();
740 setup_dofs();
741 transfer.interpolate(solution.block(0));
742 constraints.distribute(solution.block(0));
743 locally_relevant_solution.block(0) = solution.block(0);
744}
745
746
747
748template <int dim, int spacedim>
749std::string
751{
752 TimerOutput::Scope t(computing_timer, "Output results");
753 std::string solution_name = "solution";
754 DataOut<spacedim> data_out;
755 data_out.attach_dof_handler(dh);
756 data_out.add_data_vector(locally_relevant_solution.block(0), solution_name);
757 Vector<float> subdomain(tria.n_active_cells());
758 for (unsigned int i = 0; i < subdomain.size(); ++i)
759 subdomain(i) = tria.locally_owned_subdomain();
760 data_out.add_data_vector(subdomain, "subdomain");
761 data_out.build_patches();
762 const std::string filename =
763 par.output_name + "_" + std::to_string(cycle) + ".vtu";
764 data_out.write_vtu_in_parallel(par.output_directory + "/" + filename,
766 return filename;
767}
768
769
770
771// template <int dim, int spacedim>
772// std::string
773// PoissonProblem<dim, spacedim>::output_particles() const
774// {
775// Particles::DataOut<spacedim> particles_out;
776// particles_out.build_patches(inclusions.inclusions_as_particles);
777// const std::string filename =
778// par.output_name + "_particles_" + std::to_string(cycle) + ".vtu";
779// particles_out.write_vtu_in_parallel(par.output_directory + "/" +
780// filename,
781// mpi_communicator);
782// return filename;
783// }
784
785
786template <int dim, int spacedim>
787void
789{
790 static std::vector<std::pair<double, std::string>> cycles_and_solutions;
791 static std::vector<std::pair<double, std::string>> cycles_and_particles;
792
793 if (cycles_and_solutions.size() == cycle)
794 {
795 cycles_and_solutions.push_back({(double)cycle, output_solution()});
796
797 const std::string particles_filename =
798 par.output_name + "_particles_" + std::to_string(cycle) + ".vtu";
799 inclusions.output_particles(par.output_directory + "/" +
800 particles_filename);
801
802 cycles_and_particles.push_back({(double)cycle, particles_filename});
803
804 std::ofstream pvd_solutions(par.output_directory + "/" + par.output_name +
805 ".pvd");
806 std::ofstream pvd_particles(par.output_directory + "/" + par.output_name +
807 "_particles.pvd");
808 DataOutBase::write_pvd_record(pvd_solutions, cycles_and_solutions);
809 DataOutBase::write_pvd_record(pvd_particles, cycles_and_particles);
810 }
811}
812
813template <int dim, int spacedim>
814void
816{
817#ifdef USE_PETSC_LA
818 pcout << "Running PoissonProblem<" << Utilities::dim_string(dim, spacedim)
819 << "> using PETSc." << std::endl;
820#else
821 pcout << "Running PoissonProblem<" << Utilities::dim_string(dim, spacedim)
822 << "> using Trilinos." << std::endl;
823#endif
824 par.prm.print_parameters(par.output_directory + "/" + "used_parameters_" +
825 std::to_string(dim) + std::to_string(spacedim) +
826 ".prm",
828}
829
830template <int dim, int spacedim>
831void
833{
835 make_grid();
836 setup_fe();
837 for (cycle = 0; cycle < par.n_refinement_cycles; ++cycle)
838 {
839 inclusions.setup_inclusions_particles(tria);
840 setup_dofs();
841 if (par.output_results_before_solving)
843#ifdef MATRIX_FREE_PATH
844 assemble_rhs();
845#else
847#endif
849#ifdef MATRIX_FREE_PATH
851 coupling_operator = std::make_unique<CouplingOperator<spacedim, double>>(
853#endif
854 // return;
855 solve();
857 par.convergence_table.error_from_exact(dh,
859 par.bc);
860 if (cycle != par.n_refinement_cycles - 1)
862 if (pcout.is_active())
863 par.convergence_table.output_table(pcout.get_stream());
864 }
865}
866
867
868// Template instantiations
869template class PoissonProblem<2>;
870template class PoissonProblem<2, 3>;
871template class PoissonProblem<3>;
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
Definition laplacian.h:245
Inclusions< spacedim > inclusions
Definition laplacian.h:242
AffineConstraints< double > inclusion_constraints
Definition laplacian.h:250
LA::MPI::SparseMatrix inclusion_matrix
Definition laplacian.h:253
std::unique_ptr< FiniteElement< spacedim > > fe
Definition laplacian.h:241
LA::MPI::SparseMatrix coupling_matrix
Definition laplacian.h:252
PoissonProblem(const ProblemParameters< dim, spacedim > &par)
Definition laplacian.cc:43
BlockVectorType system_rhs
Definition laplacian.h:276
const ProblemParameters< dim, spacedim > & par
Definition laplacian.h:236
void output_results() const
Definition laplacian.cc:788
std::unique_ptr< Quadrature< spacedim > > quadrature
Definition laplacian.h:243
LA::MPI::SparseMatrix stiffness_matrix
Definition laplacian.h:269
void assemble_coupling()
Definition laplacian.cc:400
void refine_and_transfer()
Definition laplacian.cc:705
LA::MPI::Vector VectorType
Definition laplacian.h:270
unsigned int cycle
Definition laplacian.h:278
BlockVectorType solution
Definition laplacian.h:274
parallel::distributed::Triangulation< spacedim > tria
Definition laplacian.h:240
BlockVectorType locally_relevant_solution
Definition laplacian.h:275
TimerOutput computing_timer
Definition laplacian.h:239
ConditionalOStream pcout
Definition laplacian.h:238
MPI_Comm mpi_communicator
Definition laplacian.h:237
std::string output_solution() const
Definition laplacian.cc:750
void setup_dofs()
Definition laplacian.cc:149
AffineConstraints< double > constraints
Definition laplacian.h:249
MappingQ< spacedim > mapping
Definition laplacian.h:254
std::vector< IndexSet > owned_dofs
Definition laplacian.h:246
void print_parameters() const
Definition laplacian.cc:815
void assemble_poisson_system()
Definition laplacian.cc:299
std::vector< IndexSet > relevant_dofs
Definition laplacian.h:247
IndexSet assemble_coupling_sparsity(DynamicSparsityPattern &dsp) const
Definition laplacian.cc:353
unsigned int level
#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)
update_values
update_JxW_values
update_gradients
update_quadrature_points
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)
Definition laplacian.cc:65
std::vector< index_type > data
void write_pvd_record(std::ostream &out, const std::vector< std::pair< double, std::string > > &times_and_names)
IndexSet extract_locally_relevant_dofs(const DoFHandler< dim, spacedim > &dof_handler)
IndexSet extract_locally_relevant_level_dofs(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
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)
void distribute_sparsity_pattern(DynamicSparsityPattern &dsp, const IndexSet &locally_owned_rows, const MPI_Comm mpi_comm, const IndexSet &locally_relevant_rows)
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)
void interpolate_boundary_values(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const std::map< types::boundary_id, const Function< spacedim, number > * > &function_map, std::map< types::global_dof_index, number > &boundary_values, const ComponentMask &component_mask={})
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