27 #ifndef OOMPH_GEOMETRIC_MULTIGRID_HEADER
28 #define OOMPH_GEOMETRIC_MULTIGRID_HEADER
88 template<
unsigned DIM>
94 typedef Smoother* (*PreSmootherFactoryFctPt)();
98 typedef Smoother* (*PostSmootherFactoryFctPt)();
155 for (
unsigned i = 0;
i <
Nlevel - 1;
i++)
177 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
239 void plot(
const unsigned& hierarchy_level,
311 for (
unsigned i = 0;
i <
Nlevel - 1;
i++)
324 ->disable_doc_time();
414 ncol, nnz,
value, col_index, row_st);
438 "Setup of interpolation matrix distribution ";
439 warning_message +=
"has not been tested with MPI.";
453 dist_pt, ncol,
value, col_index, row_st);
467 for (
unsigned i = 0;
i <
Nlevel - 1;
i++)
517 if (0 == mg_problem_pt)
519 throw OomphLibError(
"Input problem must be of type MGProblem.",
531 std::ostringstream error_message_stream;
532 error_message_stream <<
"Cannot currently deal with more than 1 dof"
533 <<
" per node. This problem has " << n_value
534 <<
" dofs per node." << std::endl;
557 <<
"Multigrid Solve Complete"
558 <<
"=================\n"
575 oomph_info <<
"Total number of V-cycles required for solve: "
733 template<
unsigned DIM>
762 OomphLibWarning(
"Can't guarantee the MG solver will work in parallel!",
786 throw OomphLibError(
"Matrix and RHS vector sizes incompatible.",
803 <<
"\n==========Multigrid Preconditioner Solve Complete========="
825 template<
unsigned DIM>
829 double t_fs_start = 0.0;
832 if (!Suppress_all_output)
839 <<
"\n===============Starting Multigrid Full Setup=============="
843 oomph_info <<
"\nStarting the full setup of the multigrid solver."
850 if (
dynamic_cast<FiniteElement*
>(Mg_problem_pt->mesh_pt()->element_pt(0))
853 std::string err_strng =
"The dimension of the elements used in the mesh ";
854 err_strng +=
"does not match the dimension of the solver.";
861 if (Mg_problem_pt->mg_bulk_mesh_pt() != 0)
864 unsigned n_elements = Mg_problem_pt->mg_bulk_mesh_pt()->nelement();
868 for (
unsigned el_counter = 0; el_counter < n_elements; el_counter++)
872 Mg_problem_pt->mg_bulk_mesh_pt()->element_pt(el_counter));
879 "Element in global mesh could not be upcast to a refineable "
880 "element. We cannot deal with elements that are not refineable.",
889 "The provided bulk mesh pointer is set to be a null pointer. "
890 "The multigrid solver operates on the bulk mesh thus a pointer "
891 "to the correct mesh must be given.",
902 Mg_hierarchy.resize(1, 0);
905 Mg_hierarchy[0] = Mg_problem_pt;
908 setup_mg_hierarchy();
911 setup_transfer_matrices();
915 setup_mg_structures();
925 for (
unsigned i = 1;
i < Nlevel;
i++)
928 delete Mg_hierarchy[
i];
942 Has_been_setup =
true;
945 if (!Suppress_all_output)
949 double full_setup_time = t_fs_end - t_fs_start;
952 oomph_info <<
"\nCPU time for full setup [sec]: " << full_setup_time
957 <<
"\n===============Multigrid Full Setup Complete=============="
967 template<
unsigned DIM>
971 double t_m_start = 0.0;
974 if (!Suppress_all_output)
978 <<
"\n===============Creating Multigrid Hierarchy==============="
988 bool managed_to_create_unrefined_copy =
true;
996 while (managed_to_create_unrefined_copy)
1009 managed_to_create_unrefined_copy =
1012 Mg_hierarchy[level]->mg_bulk_mesh_pt());
1016 if (managed_to_create_unrefined_copy)
1023 if (!Suppress_all_output)
1026 oomph_info <<
"\nSuccess! Level " << level <<
" has been created."
1039 Mg_hierarchy.push_back(new_problem_pt);
1045 delete new_problem_pt;
1051 Nlevel = Mg_hierarchy.size();
1055 if (!Suppress_all_output)
1058 oomph_info <<
"\n Reached the coarsest level! "
1059 <<
"Number of levels: " << Nlevel << std::endl;
1067 Mg_matrices_storage_pt.resize(Nlevel, 0);
1070 X_mg_vectors_storage.resize(Nlevel);
1073 Rhs_mg_vectors_storage.resize(Nlevel);
1076 Residual_mg_vectors_storage.resize(Nlevel);
1080 Pre_smoothers_storage_pt.resize(Nlevel - 1, 0);
1084 Post_smoothers_storage_pt.resize(Nlevel - 1, 0);
1087 Interpolation_matrices_storage_pt.resize(Nlevel - 1, 0);
1090 Restriction_matrices_storage_pt.resize(Nlevel - 1, 0);
1092 if (!Suppress_all_output)
1096 double total_setup_time =
double(t_m_end - t_m_start);
1098 <<
"\nCPU time for creation of hierarchy of MG problems [sec]: "
1099 << total_setup_time << std::endl;
1103 <<
"\n===============Hierarchy Creation Complete================"
1116 template<
unsigned DIM>
1120 double t_r_start = 0.0;
1123 if (!Suppress_all_output)
1126 oomph_info <<
"Creating the transfer matrices ";
1133 if (!Suppress_all_output)
1136 oomph_info <<
"using full weighting (recommended).\n" << std::endl;
1143 Mg_problem_pt->mg_bulk_mesh_pt()))
1145 setup_interpolation_matrices();
1151 setup_interpolation_matrices_unstructured();
1155 set_restriction_matrices_as_interpolation_transposes();
1158 if (!Suppress_all_output)
1162 double total_G_setup_time =
double(t_r_end - t_r_start);
1163 oomph_info <<
"CPU time for transfer matrices setup [sec]: "
1164 << total_G_setup_time << std::endl;
1168 <<
"\n============Transfer Matrices Setup Complete=============="
1179 template<
unsigned DIM>
1183 double t_m_start = 0.0;
1186 if (!Suppress_all_output)
1193 for (
unsigned i = 0;
i < Nlevel;
i++)
1201 for (
unsigned i = 0;
i < Nlevel;
i++)
1204 if (!Suppress_all_output)
1207 oomph_info <<
"Setting up MG structures on level: " <<
i <<
"\n"
1212 unsigned n_dof = Mg_hierarchy[
i]->ndof();
1214 Mg_hierarchy[
i]->communicator_pt(), n_dof,
false);
1217 #ifdef OOMPH_HAS_MPI
1219 std::string warning_message =
"Setup of distribution has not been ";
1220 warning_message +=
"tested with MPI.";
1233 X_mg_vectors_storage[
i].clear();
1234 X_mg_vectors_storage[
i].build(dist_pt);
1237 Rhs_mg_vectors_storage[
i].clear();
1238 Rhs_mg_vectors_storage[
i].build(dist_pt);
1241 Residual_mg_vectors_storage[
i].clear();
1242 Residual_mg_vectors_storage[
i].build(dist_pt);
1251 Mg_matrices_storage_pt[
i]->
clear();
1252 Mg_matrices_storage_pt[
i]->distribution_pt()->build(
1253 Mg_hierarchy[
i]->communicator_pt(), n_dof,
false);
1265 double t_jac_start = 0.0;
1268 if (!Suppress_all_output)
1276 Mg_hierarchy[0]->get_jacobian(Rhs_mg_vectors_storage[0],
1277 *Mg_matrices_storage_pt[0]);
1279 if (!Suppress_all_output)
1283 double jacobian_setup_time = t_jac_end - t_jac_start;
1284 oomph_info <<
" - Time for setup of Jacobian [sec]: "
1285 << jacobian_setup_time <<
"\n"
1292 double t_gal_start = 0.0;
1295 if (!Suppress_all_output)
1309 Mg_matrices_storage_pt[
i - 1]->multiply(
1310 *Interpolation_matrices_storage_pt[
i - 1],
1311 *Mg_matrices_storage_pt[
i]);
1316 Restriction_matrices_storage_pt[
i - 1]->multiply(
1317 *Mg_matrices_storage_pt[
i], *Mg_matrices_storage_pt[
i]);
1320 if (!Suppress_all_output)
1326 double galerkin_matrix_calculation_time = t_gal_end - t_gal_start;
1330 <<
" - Time for system matrix formation using the Galerkin "
1331 <<
"approximation [sec]: " << galerkin_matrix_calculation_time
1339 if (!Suppress_all_output)
1343 double total_setup_time =
double(t_m_end - t_m_start);
1344 oomph_info <<
"Total CPU time for setup of MG structures [sec]: "
1345 << total_setup_time << std::endl;
1349 <<
"Multigrid Structures Setup Complete"
1359 template<
unsigned DIM>
1363 double t_m_start = 0.0;
1366 if (!Suppress_all_output)
1369 oomph_info <<
"Starting the setup of all smoothers.\n" << std::endl;
1376 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
1381 if (0 == Pre_smoother_factory_function_pt)
1390 Pre_smoothers_storage_pt[
i] = (*Pre_smoother_factory_function_pt)();
1396 if (0 == Post_smoother_factory_function_pt)
1405 Post_smoothers_storage_pt[
i] = (*Post_smoother_factory_function_pt)();
1414 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
1417 Pre_smoothers_storage_pt[
i]->
tolerance() = 1.0e-16;
1420 Post_smoothers_storage_pt[
i]->tolerance() = 1.0e-16;
1425 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
1428 Pre_smoothers_storage_pt[
i]->max_iter() = Npre_smooth;
1431 Post_smoothers_storage_pt[
i]->max_iter() = Npost_smooth;
1435 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
1439 Pre_smoothers_storage_pt[
i]->smoother_setup(Mg_matrices_storage_pt[
i]);
1443 Post_smoothers_storage_pt[
i]->smoother_setup(Mg_matrices_storage_pt[
i]);
1447 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
1452 unsigned n_dof = X_mg_vectors_storage[
i].nrow();
1457 Mg_hierarchy[
i]->communicator_pt(), n_dof,
false);
1460 #ifdef OOMPH_HAS_MPI
1463 "Setup of pre- and post-smoother distribution ";
1464 warning_message +=
"has not been tested with MPI.";
1477 Pre_smoothers_storage_pt[
i]->build_distribution(dist);
1480 Post_smoothers_storage_pt[
i]->build_distribution(dist);
1486 disable_smoother_and_superlu_doc_time();
1490 if (!Suppress_all_output)
1494 double total_setup_time =
double(t_m_end - t_m_start);
1495 oomph_info <<
"CPU time for setup of smoothers on all levels [sec]: "
1496 << total_setup_time << std::endl;
1500 <<
"\n==================Smoother Setup Complete================="
1509 template<
unsigned DIM>
1526 std::ostringstream error_message_stream;
1527 error_message_stream <<
"DIM should be 2 or 3 not " <<
DIM << std::endl;
1539 for (
unsigned level = 0; level < Nlevel - 1; level++)
1542 unsigned coarse_level = level + 1;
1543 unsigned fine_level = level;
1548 Mg_hierarchy[fine_level]->mg_bulk_mesh_pt());
1554 Mg_hierarchy[coarse_level]->mg_bulk_mesh_pt());
1559 unsigned fine_n_element = ref_fine_mesh_pt->
nelement();
1565 unsigned n_rows = Mg_hierarchy[fine_level]->ndof();
1566 unsigned n_cols = Mg_hierarchy[coarse_level]->ndof();
1576 coarse_mesh_reference_element_pt;
1580 unsigned e_coarse = 0;
1581 unsigned e_fine = 0;
1586 while (e_fine < fine_n_element)
1600 if (el_fine_pt->tree_pt()->level() != el_coarse_pt->tree_pt()->level())
1607 for (
unsigned i = 0;
i < n_sons;
i++)
1610 coarse_mesh_reference_element_pt
1625 coarse_mesh_reference_element_pt[el_fine_pt] = el_coarse_pt;
1635 std::vector<bool> contribution_made(n_rows,
false);
1656 for (
unsigned k = 0;
k < fine_n_element;
k++)
1666 coarse_mesh_reference_element_pt[el_fine_pt];
1674 if (el_fine_pt->tree_pt()->level() != el_coarse_pt->tree_pt()->level())
1677 son_type = el_fine_pt->tree_pt()->son_type();
1687 unsigned nnod_fine = el_fine_pt->nnode();
1690 for (
unsigned i = 0;
i < nnod_fine;
i++)
1694 int ii = el_fine_pt->node_pt(
i)->eqn_number(0);
1701 if (contribution_made[ii] ==
false)
1709 row_start[index] =
value.size();
1712 el_fine_pt->local_coordinate_of_node(
i,
s);
1717 level_up_local_coord_of_node(son_type,
s);
1720 Shape psi(el_coarse_pt->nnode());
1723 el_coarse_pt->shape(
s, psi);
1726 std::map<unsigned, double> contribution;
1730 unsigned nnod_coarse = el_coarse_pt->nnode();
1733 for (
unsigned j = 0;
j < nnod_coarse;
j++)
1738 int jj = el_coarse_pt->node_pt(
j)->eqn_number(0);
1745 if (el_coarse_pt->node_pt(
j)->is_hanging())
1750 el_coarse_pt->node_pt(
j)->hanging_pt();
1751 unsigned nmaster = hang_info_pt->
nmaster();
1754 for (
unsigned i_master = 0; i_master < nmaster; i_master++)
1757 Node* master_node_pt =
1763 int master_jj = master_node_pt->
eqn_number(0);
1772 contribution[master_jj] +=
1786 contribution[jj] += psi(
j);
1792 for (std::map<unsigned, double>::iterator it =
1793 contribution.begin();
1794 it != contribution.end();
1797 if (it->second != 0)
1799 column_index.push_back(it->first);
1800 value.push_back(it->second);
1811 contribution_made[ii] =
true;
1818 row_start[n_rows] =
value.size();
1823 interpolation_matrix_set(
1824 level,
value, column_index, row_start, n_cols, n_rows);
1831 template<
unsigned DIM>
1840 for (
unsigned level = 0; level < Nlevel - 1; level++)
1843 unsigned coarse_level = level + 1;
1844 unsigned fine_level = level;
1848 Mesh* ref_fine_mesh_pt = Mg_hierarchy[fine_level]->mg_bulk_mesh_pt();
1857 unsigned coarse_n_unknowns = Mg_hierarchy[coarse_level]->ndof();
1858 unsigned fine_n_unknowns = Mg_hierarchy[fine_level]->ndof();
1878 unsigned n_node_fine_mesh = ref_fine_mesh_pt->
nnode();
1881 for (
unsigned i_fine_node = 0; i_fine_node < n_node_fine_mesh;
1885 Node* fine_node_pt = ref_fine_mesh_pt->
node_pt(i_fine_node);
1895 row_start[i_fine] =
value.size();
1898 fine_node_pt->
position(fine_node_position);
1905 coarse_mesh_from_obj_pt->
locate_zeta(fine_node_position, el_pt,
s);
1911 unsigned n_node = el_coarse_pt->
nnode();
1917 el_coarse_pt->
shape(
s, psi);
1920 std::map<unsigned, double> contribution;
1925 for (
unsigned j_node = 0; j_node < n_node; j_node++)
1928 Node* coarse_node_pt = el_coarse_pt->
node_pt(j_node);
1932 int j_coarse = coarse_node_pt->
eqn_number(0);
1944 unsigned nmaster = hang_info_pt->
nmaster();
1947 for (
unsigned i_master = 0; i_master < nmaster; i_master++)
1955 int master_jj = master_node_pt->
eqn_number(0);
1964 contribution[master_jj] +=
1976 if (psi(j_node) != 0.0)
1978 contribution[j_coarse] += psi(j_node);
1985 for (std::map<unsigned, double>::iterator it = contribution.begin();
1986 it != contribution.end();
1989 if (it->second != 0)
1991 value.push_back(it->second);
1992 column_index.push_back(it->first);
1999 row_start[fine_n_unknowns] =
value.size();
2004 interpolation_matrix_set(level,
2019 template<
unsigned DIM>
2024 if (!(level < Nlevel - 1))
2026 throw OomphLibError(
"Input exceeds the possible parameter choice.",
2034 Restriction_matrices_storage_pt[level]->multiply(
2035 Residual_mg_vectors_storage[level], Rhs_mg_vectors_storage[level + 1]);
2042 template<
unsigned DIM>
2049 throw OomphLibError(
"Input level exceeds the possible parameter choice.",
2056 DoubleVector temp_soln(X_mg_vectors_storage[level - 1].distribution_pt());
2059 Interpolation_matrices_storage_pt[level - 1]->multiply(
2060 X_mg_vectors_storage[level], temp_soln);
2063 X_mg_vectors_storage[level - 1] += temp_soln;
2069 template<
unsigned DIM>
2076 for (
unsigned level = 0; level < Nlevel - 1; level++)
2079 restriction_matrix_pt = Restriction_matrices_storage_pt[level];
2082 const int* row_start_pt = restriction_matrix_pt->
row_start();
2085 double* value_pt = restriction_matrix_pt->
value();
2089 unsigned start_index = 0;
2093 unsigned end_index = 0;
2096 unsigned n_row = restriction_matrix_pt->
nrow();
2099 for (
unsigned i = 0;
i < n_row;
i++)
2102 start_index = row_start_pt[
i];
2105 end_index = row_start_pt[
i + 1];
2109 double row_sum = 0.0;
2112 for (
unsigned j = start_index;
j < end_index;
j++)
2115 row_sum += value_pt[
j];
2119 for (
unsigned j = start_index;
j < end_index;
j++)
2122 value_pt[
j] /= row_sum;
2134 template<
unsigned DIM>
2141 oomph_info <<
"\nStarting the multigrid solver self-test." << std::endl;
2144 Restriction_self_test_vectors_storage.resize(Nlevel);
2147 Interpolation_self_test_vectors_storage.resize(Nlevel);
2150 unsigned n_dof = X_mg_vectors_storage[0].nrow();
2154 Mg_problem_pt->communicator_pt(), n_dof,
false);
2157 #ifdef OOMPH_HAS_MPI
2159 std::string warning_message =
"Setup of distribution has not been ";
2160 warning_message +=
"tested with MPI.";
2173 Restriction_self_test_vectors_storage[0].build(dist_pt);
2183 set_self_test_vector();
2186 restriction_self_test();
2191 Interpolation_self_test_vectors_storage[Nlevel - 1] =
2192 Restriction_self_test_vectors_storage[Nlevel - 1];
2195 interpolation_self_test();
2198 Restriction_self_test_vectors_storage.resize(0);
2201 Interpolation_self_test_vectors_storage.resize(0);
2205 double total_st_time =
double(t_st_end - t_st_start);
2206 oomph_info <<
"\nCPU time for self-test [sec]: " << total_st_time
2210 oomph_info <<
"\n====================Self-Test Complete===================="
2218 template<
unsigned DIM>
2223 Mg_problem_pt->mg_bulk_mesh_pt();
2226 unsigned n_el = bulk_mesh_pt->
nelement();
2230 unsigned n_dim = bulk_mesh_pt->
node_pt(0)->
ndim();
2236 for (
unsigned e = 0;
e < n_el;
e++)
2242 for (
unsigned j = 0;
j < nnod;
j++)
2248 if (nod_pt->
nvalue() != 1)
2251 std::ostringstream error_stream;
2254 error_stream <<
"Sorry, not sure what to do here! I can't deal with "
2255 << nod_pt->
nvalue() <<
" values!" << std::endl;
2271 double coordinate_sum = 0.0;
2274 for (
unsigned i = 0;
i < n_dim;
i++)
2277 coordinate_sum += nod_pt->
x(
i);
2284 Restriction_self_test_vectors_storage[0][eqn_num] =
2306 template<
unsigned DIM>
2311 std::string outputfile =
"RESLT/restriction_self_test";
2314 for (
unsigned level = 0; level < Nlevel - 1; level++)
2317 Restriction_matrices_storage_pt[level]->multiply(
2318 Restriction_self_test_vectors_storage[level],
2319 Restriction_self_test_vectors_storage[level + 1]);
2323 for (
unsigned level = 0; level < Nlevel; level++)
2327 std::stringstream
string;
2333 plot(level, Restriction_self_test_vectors_storage[level],
filename);
2343 template<
unsigned DIM>
2348 std::string outputfile =
"RESLT/interpolation_self_test";
2351 for (
unsigned level = Nlevel - 1; level > 0; level--)
2354 Interpolation_matrices_storage_pt[level - 1]->multiply(
2355 Interpolation_self_test_vectors_storage[level],
2356 Interpolation_self_test_vectors_storage[level - 1]);
2359 for (
unsigned level = 0; level < Nlevel; level++)
2363 std::stringstream
string;
2369 plot(level, Interpolation_self_test_vectors_storage[level],
filename);
2378 template<
unsigned DIM>
2384 std::ofstream some_file;
2389 Mg_hierarchy[hierarchy_level]->mg_bulk_mesh_pt();
2392 unsigned n_el = bulk_mesh_pt->
nelement();
2396 unsigned n_dim = bulk_mesh_pt->
node_pt(0)->
ndim();
2405 for (
unsigned e = 0;
e < n_el;
e++)
2415 for (
unsigned j = 0;
j < nnod;
j++)
2421 if (nod_pt->
nvalue() != 1)
2423 std::ostringstream error_stream;
2425 error_stream <<
"Sorry, not sure what to do here!" << nod_pt->
nvalue()
2429 error_stream <<
"The dimension is: " << n_dim << std::endl;
2432 for (
unsigned i = 0;
i < n_dim;
i++)
2434 error_stream << nod_pt->
x(
i) <<
" ";
2438 error_stream << std::endl;
2448 for (
unsigned i = 0;
i < n_dim;
i++)
2450 some_file << nod_pt->
x(
i) <<
" ";
2458 some_file << input_vector[
e] << std::endl;
2466 if (hierarchy_level == 0)
2468 some_file << 0.0 << std::endl;
2474 some_file << input_vector[
e] << std::endl;
2482 double hang_sum = 0.0;
2487 unsigned nmaster = hang_info_pt->
nmaster();
2490 for (
unsigned i_master = 0; i_master < nmaster; i_master++)
2496 int master_jj = master_node_pt->
eqn_number(0);
2505 input_vector[master_jj];
2511 some_file << hang_sum << std::endl;
2524 template<
unsigned DIM>
2528 double t_mg_start = 0.0;
2529 if (!Suppress_v_cycle_output)
2536 unsigned finest_level = 0;
2539 V_cycle_counter = 0;
2542 double normalised_residual_norm = residual_norm(finest_level);
2543 if (!Suppress_v_cycle_output)
2545 oomph_info <<
"\nResidual on finest level for V-cycle: "
2546 << normalised_residual_norm << std::endl;
2553 while ((normalised_residual_norm > (this->Tolerance)) &&
2554 (V_cycle_counter != Nvcycle))
2556 if (!Suppress_v_cycle_output)
2559 oomph_info <<
"\nStarting V-cycle: " << V_cycle_counter << std::endl;
2564 for (
unsigned i = 0;
i < Nlevel - 1;
i++)
2572 X_mg_vectors_storage[
i].initialise(0.0);
2573 Residual_mg_vectors_storage[
i].initialise(0.0);
2582 restrict_residual(
i);
2593 for (
unsigned i = Nlevel - 1;
i > 0;
i--)
2597 interpolate_and_correct(
i);
2606 normalised_residual_norm = residual_norm(finest_level);
2610 if (Doc_convergence_history)
2612 if (!Output_file_stream.is_open())
2614 oomph_info << V_cycle_counter <<
" " << normalised_residual_norm
2619 Output_file_stream << V_cycle_counter <<
" "
2620 << normalised_residual_norm << std::endl;
2628 if (!Suppress_v_cycle_output)
2630 oomph_info <<
"Residual on finest level of V-cycle: "
2631 << normalised_residual_norm << std::endl;
2636 result = X_mg_vectors_storage[finest_level];
2639 if (!Suppress_v_cycle_output)
2645 if (!Suppress_all_output)
2648 if (normalised_residual_norm < (this->Tolerance))
2651 Has_been_solved =
true;
2656 if (!Suppress_v_cycle_output)
2660 double total_G_setup_time =
double(t_mg_end - t_mg_start);
2661 oomph_info <<
"CPU time for MG solver [sec]: " << total_G_setup_time
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Definition: matrices.h:888
int * row_start()
Access to C-style row_start array.
Definition: matrices.h:1060
double * value()
Access to C-style value array.
Definition: matrices.h:1084
unsigned long nrow() const
Return the number of rows of the matrix.
Definition: matrices.h:1002
Definition: iterative_linear_solver.h:1002
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
Definition: nodes.h:367
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
unsigned nrow() const
access function to the number of global rows.
Definition: linear_algebra_distribution.h:463
Definition: double_vector.h:58
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Definition: elements.h:3161
virtual void shape(const Vector< double > &s, Shape &psi) const =0
unsigned dim() const
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
virtual unsigned nnode_1d() const
Definition: elements.h:2218
Definition: geom_objects.h:101
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Definition: nodes.h:808
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
Definition: nodes.h:791
unsigned nmaster() const
Return the number of master nodes.
Definition: nodes.h:785
Definition: iterative_linear_solver.h:54
double Tolerance
Convergence tolerance.
Definition: iterative_linear_solver.h:239
double & tolerance()
Access to convergence tolerance.
Definition: iterative_linear_solver.h:107
Definition: linear_algebra_distribution.h:64
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
Definition: linear_algebra_distribution.h:335
void clear()
clears the distribution
Definition: linear_algebra_distribution.h:171
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77
An interface to allow scalar MG to be used as a Preconditioner.
Definition: geometric_multigrid.h:735
MGPreconditioner(const MGPreconditioner &)=delete
Broken copy constructor.
void setup()
Function to set up a preconditioner for the linear system.
Definition: geometric_multigrid.h:754
MGPreconditioner(MGProblem *mg_problem_pt)
Constructor.
Definition: geometric_multigrid.h:738
void operator=(const MGPreconditioner &)=delete
Broken assignment operator.
void clean_up_memory()
Clean up memory.
Definition: geometric_multigrid.h:818
~MGPreconditioner()
Destructor (empty)
Definition: geometric_multigrid.h:745
virtual void preconditioner_solve(const DoubleVector &rhs, DoubleVector &z)
Function applies MG to the vector r for a full solve.
Definition: geometric_multigrid.h:781
MGProblem class; subclass of Problem.
Definition: geometric_multigrid.h:57
virtual TreeBasedRefineableMeshBase * mg_bulk_mesh_pt()=0
MGProblem()
Constructor. Initialise pointers to coarser and finer levels.
Definition: geometric_multigrid.h:60
virtual MGProblem * make_new_problem()=0
virtual ~MGProblem()
Destructor (empty)
Definition: geometric_multigrid.h:63
Definition: geometric_multigrid.h:90
void set_self_test_vector()
Definition: geometric_multigrid.h:2219
void set_pre_smoother_factory_function(PreSmootherFactoryFctPt pre_smoother_fn)
Access function to set the pre-smoother creation function.
Definition: geometric_multigrid.h:101
bool Suppress_all_output
Definition: geometric_multigrid.h:642
void full_setup()
Runs a full setup of the MG solver.
Definition: geometric_multigrid.h:826
Vector< DoubleVector > Rhs_mg_vectors_storage
Definition: geometric_multigrid.h:631
void setup_mg_structures()
Set up the MG hierarchy structures.
Definition: geometric_multigrid.h:1180
void interpolation_self_test()
Definition: geometric_multigrid.h:2344
void level_up_local_coord_of_node(const int &son_type, Vector< double > &s)
unsigned V_cycle_counter
Pointer to counter for V-cycles.
Definition: geometric_multigrid.h:727
Vector< Smoother * > Post_smoothers_storage_pt
Vector to store the post-smoothers.
Definition: geometric_multigrid.h:704
PostSmootherFactoryFctPt Post_smoother_factory_function_pt
Function to create post-smoothers.
Definition: geometric_multigrid.h:655
Vector< DoubleVector > Residual_mg_vectors_storage
Vector to store the residual vectors.
Definition: geometric_multigrid.h:688
bool Doc_everything
Definition: geometric_multigrid.h:717
void setup_transfer_matrices()
Setup the transfer matrices on each level.
Definition: geometric_multigrid.h:1117
void enable_v_cycle_output()
Enable the output of the V-cycle timings and other output.
Definition: geometric_multigrid.h:276
void setup_interpolation_matrices()
Setup the interpolation matrix on each level.
Definition: geometric_multigrid.h:1510
Smoother *(* PreSmootherFactoryFctPt)()
Definition: geometric_multigrid.h:94
void post_smooth(const unsigned &level)
Definition: geometric_multigrid.h:366
void set_post_smoother_factory_function(PostSmootherFactoryFctPt post_smoother_fn)
Access function to set the post-smoother creation function.
Definition: geometric_multigrid.h:109
unsigned Nlevel
The number of levels in the multigrid heirachy.
Definition: geometric_multigrid.h:670
void plot(const unsigned &hierarchy_level, const DoubleVector &input_vector, const std::string &filename)
Definition: geometric_multigrid.h:2379
Vector< Smoother * > Pre_smoothers_storage_pt
Vector to store the pre-smoothers.
Definition: geometric_multigrid.h:701
std::ostream * Stream_pt
Definition: geometric_multigrid.h:648
void set_restriction_matrices_as_interpolation_transposes()
Definition: geometric_multigrid.h:465
MGSolver(MGProblem *mg_problem_pt)
Definition: geometric_multigrid.h:118
unsigned & max_iter()
Number of iterations.
Definition: geometric_multigrid.h:602
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: geometric_multigrid.h:509
void mg_solve(DoubleVector &result)
Linear solver.
Definition: geometric_multigrid.h:2525
void disable_output()
Definition: geometric_multigrid.h:256
Smoother *(* PostSmootherFactoryFctPt)()
Definition: geometric_multigrid.h:98
void restrict_residual(const unsigned &level)
Definition: geometric_multigrid.h:2020
Vector< DoubleVector > Restriction_self_test_vectors_storage
Definition: geometric_multigrid.h:698
unsigned & npost_smooth()
Return the number of post-smoothing iterations (lvalue)
Definition: geometric_multigrid.h:328
void interpolation_matrix_set(const unsigned &level, Vector< double > &value, Vector< int > &col_index, Vector< int > &row_st, unsigned &ncol, unsigned &nrow)
Definition: geometric_multigrid.h:420
void disable_smoother_and_superlu_doc_time()
Suppress the output of both smoothers and SuperLU.
Definition: geometric_multigrid.h:308
void clean_up_memory()
Clean up anything that needs to be cleaned up.
Definition: geometric_multigrid.h:148
void self_test()
Definition: geometric_multigrid.h:2135
Vector< CRDoubleMatrix * > Restriction_matrices_storage_pt
Vector to store the restriction matrices.
Definition: geometric_multigrid.h:682
void setup_mg_hierarchy()
Set up the MG hierarchy.
Definition: geometric_multigrid.h:968
Vector< CRDoubleMatrix * > Mg_matrices_storage_pt
Vector to store the system matrices.
Definition: geometric_multigrid.h:676
void setup_interpolation_matrices_unstructured()
Setup the interpolation matrices.
Definition: geometric_multigrid.h:1832
void direct_solve()
Call the direct solver (SuperLU) to solve the problem exactly.
Definition: geometric_multigrid.h:392
void setup_smoothers()
Set up the smoothers on all levels.
Definition: geometric_multigrid.h:1360
unsigned Npost_smooth
Number of post-smoothing steps.
Definition: geometric_multigrid.h:710
void disable_v_cycle_output()
Definition: geometric_multigrid.h:245
~MGSolver()
Delete any dynamically allocated data.
Definition: geometric_multigrid.h:141
unsigned Nvcycle
Definition: geometric_multigrid.h:622
Vector< MGProblem * > Mg_hierarchy
Vector containing pointers to problems in hierarchy.
Definition: geometric_multigrid.h:673
Vector< DoubleVector > Interpolation_self_test_vectors_storage
Definition: geometric_multigrid.h:693
Vector< CRDoubleMatrix * > Interpolation_matrices_storage_pt
Vector to store the interpolation matrices.
Definition: geometric_multigrid.h:679
void enable_output()
Enable the output from anything that could have been suppressed.
Definition: geometric_multigrid.h:295
void enable_doc_everything()
Enable the output from anything that could have been suppressed.
Definition: geometric_multigrid.h:286
void pre_smooth(const unsigned &level)
Definition: geometric_multigrid.h:348
bool Suppress_v_cycle_output
Definition: geometric_multigrid.h:637
unsigned Npre_smooth
Number of pre-smoothing steps.
Definition: geometric_multigrid.h:707
unsigned iterations() const
Number of iterations.
Definition: geometric_multigrid.h:595
void restriction_self_test()
Definition: geometric_multigrid.h:2307
unsigned & npre_smooth()
Return the number of pre-smoothing iterations (lvalue)
Definition: geometric_multigrid.h:336
Vector< DoubleVector > X_mg_vectors_storage
Vector to store the solution vectors (X_mg)
Definition: geometric_multigrid.h:685
void modify_restriction_matrices()
Modify the restriction matrices.
Definition: geometric_multigrid.h:2070
void interpolation_matrix_set(const unsigned &level, double *value, int *col_index, int *row_st, unsigned &ncol, unsigned &nnz)
Definition: geometric_multigrid.h:402
void interpolate_and_correct(const unsigned &level)
Definition: geometric_multigrid.h:2043
double residual_norm(const unsigned &level)
Definition: geometric_multigrid.h:375
bool Has_been_setup
Boolean variable to indicate whether or not the solver has been setup.
Definition: geometric_multigrid.h:720
MGProblem * Mg_problem_pt
Definition: geometric_multigrid.h:626
bool Has_been_solved
Definition: geometric_multigrid.h:724
PreSmootherFactoryFctPt Pre_smoother_factory_function_pt
Function to create pre-smoothers.
Definition: geometric_multigrid.h:652
static OomphCommunicator * communicator_pt()
access to the global oomph-lib communicator
Definition: oomph_utilities.cc:1046
Definition: mesh_as_geometric_object.h:93
void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
Definition: mesh_as_geometric_object.h:373
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
HangInfo *const & hanging_pt() const
Definition: nodes.h:1228
virtual bool is_on_boundary() const
Definition: nodes.h:1373
void position(Vector< double > &pos) const
Definition: nodes.cc:2499
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054
bool is_hanging() const
Test whether the node is geometrically hanging.
Definition: nodes.h:1285
int nproc() const
number of processors
Definition: communicator.h:157
std::ostream *& stream_pt()
Access function for the stream pointer.
Definition: oomph_definitions.h:464
Definition: oomph_definitions.h:222
Definition: oomph_definitions.h:267
Definition: preconditioner.h:54
Definition: problem.h:151
unsigned long ndof() const
Return the number of dofs.
Definition: problem.h:1674
virtual void actions_before_adapt()
Definition: problem.h:1022
Mesh *& mesh_pt()
Return a pointer to the global mesh.
Definition: problem.h:1280
unsigned long assign_eqn_numbers(const bool &assign_local_eqn_numbers=true)
Definition: problem.cc:1989
virtual void actions_after_adapt()
Actions that are to be performed after a mesh adaptation.
Definition: problem.h:1025
Definition: refineable_elements.h:97
Definition: refineable_mesh.h:48
Definition: Qelements.h:2259
Definition: iterative_linear_solver.h:550
Base class for tree-based refineable meshes.
Definition: refineable_mesh.h:376
virtual bool refine_base_mesh_as_in_reference_mesh_minus_one(TreeBasedRefineableMeshBase *const &ref_mesh_pt)
Definition: refineable_mesh.cc:1907
static const int OMEGA
Default value for an unassigned neighbour.
Definition: tree.h:262
RealScalar s
Definition: level1_cplx_impl.h:130
char char char int int * k
Definition: level2_impl.h:374
#define DIM
Definition: linearised_navier_stokes_elements.h:44
squared absolute value
Definition: GlobalFunctions.h:87
string filename
Definition: MergeRestartFiles.py:39
void plot()
Plot.
Definition: sphere_scattering.cc:180
const Mdouble pi
Definition: ExtendedMath.h:23
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
const double Pi
50 digits from maple
Definition: oomph_utilities.h:157
void clean_up_memory()
Definition: oomph_definitions.cc:86
double timer()
returns the time in seconds after some point in past
Definition: oomph_utilities.cc:1295
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
unsigned self_test()
Self-test: Return 0 for OK.
Nullstream oomph_nullstream
Single (global) instantiation of the Nullstream.
Definition: oomph_definitions.cc:313
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2