1668 Block_number_to_dof_number_lookup.clear();
1670 Ndof_in_block.clear();
1674 Dof_number_to_block_number_lookup.resize(Internal_ndof_types);
1677 for (
unsigned i = 0;
i < Internal_ndof_types;
i++)
1689 if (Block_number_to_dof_number_lookup[
i].
size() == 0)
1691 std::ostringstream error_message;
1692 error_message <<
"block number " <<
i
1693 <<
" does not have any DOFs associated with it";
1705 bool distributed = this->master_distribution_pt()->distributed();
1708 Internal_block_distribution_pt.resize(Internal_nblock_types);
1709 for (
unsigned i = 0;
i < Internal_nblock_types;
i++)
1712 for (
unsigned j = 0;
j < Ndof_in_block[
i];
j++)
1715 internal_dof_block_dimension(Block_number_to_dof_number_lookup[
i][
j]);
1717 Internal_block_distribution_pt[
i] =
1718 new LinearAlgebraDistribution(comm_pt(),
block_dim, distributed);
1726 if (is_subsidiary_block_preconditioner())
1730 Dof_block_distribution_pt.size();
1733 delete Dof_block_distribution_pt[
dof_i];
1736 Dof_block_distribution_pt.resize(
ndofs, 0);
1745 Doftype_coarsen_map_coarse[
dof_i].size();
1752 master_block_preconditioner_pt()->dof_block_distribution_pt(
1753 Doftype_in_master_preconditioner_coarse
1757 Dof_block_distribution_pt[
dof_i] =
new LinearAlgebraDistribution;
1773 delete Block_distribution_pt[
dist_i];
1776 Block_distribution_pt.clear();
1794 Block_distribution_pt[
super_block_i] =
new LinearAlgebraDistribution;
1808 LinearAlgebraDistribution
dist;
1810 Internal_block_distribution_pt,
dist);
1813 if (is_subsidiary_block_preconditioner())
1815 this->build_distribution(
dist);
1819 Internal_preconditioner_matrix_distribution_pt =
1820 new LinearAlgebraDistribution(
dist);
1823 Preconditioner_matrix_distribution_pt =
new LinearAlgebraDistribution;
1825 Block_distribution_pt, *Preconditioner_matrix_distribution_pt);
1834 const unsigned nblocks = Block_distribution_pt.size();
1844 std::map<Vector<unsigned>, LinearAlgebraDistribution*>
::iterator iter =
1845 Auxiliary_block_distribution_pt.begin();
1846 while (
iter != Auxiliary_block_distribution_pt.end())
1850 delete iter->second;
1860 Auxiliary_block_distribution_pt.clear();
1863 insert_auxiliary_block_distribution(
1881 for (
unsigned p = 0;
p <
nproc;
p++)
1898 Global_index.resize(Internal_nblock_types);
1899 for (
unsigned b = 0; b < Internal_nblock_types; b++)
1901 Global_index[b].resize(Internal_block_distribution_pt[b]->nrow());
1905 unsigned nrow = this->master_nrow();
1906 for (
unsigned i = 0;
i < nrow;
i++)
1913 unsigned block_number = Dof_number_to_block_number_lookup[
dof_number];
1916 unsigned index_in_block = 0;
1918 while (
int(Block_number_to_dof_number_lookup[block_number][
ptr]) !=
1921 index_in_block += internal_dof_block_dimension(
1922 Block_number_to_dof_number_lookup[block_number][
ptr]);
1925 index_in_block += internal_index_in_dof(
i);
1926 Global_index[block_number][index_in_block] =
i;
1936 const LinearAlgebraDistribution* master_distribution_pt =
1937 this->master_distribution_pt();
1940 Nrows_to_send_for_get_block.resize(Internal_nblock_types,
nproc);
1941 Nrows_to_send_for_get_block.initialise(0);
1942 Nrows_to_send_for_get_ordered.resize(
nproc);
1943 Nrows_to_send_for_get_ordered.initialise(0);
1946 unsigned nrow_local = master_distribution_pt->nrow_local();
1947 unsigned first_row = master_distribution_pt->first_row();
1948 for (
unsigned i = 0;
i < nrow_local;
i++)
1951 int b = this->internal_block_number(first_row +
i);
1957 unsigned j = this->internal_index_in_block(first_row +
i);
1961 while (!(Internal_block_distribution_pt[b]->first_row(
block_p) <=
j &&
1962 (Internal_block_distribution_pt[b]->first_row(
block_p) +
1963 Internal_block_distribution_pt[b]->nrow_local(
block_p) >
1970 Nrows_to_send_for_get_block(b,
block_p)++;
1971 Nrows_to_send_for_get_ordered[
block_p]++;
1976 Nrows_to_recv_for_get_block.resize(Internal_nblock_types,
nproc);
1977 Nrows_to_recv_for_get_block.initialise(0);
1978 Nrows_to_recv_for_get_ordered.resize(
nproc);
1979 Nrows_to_recv_for_get_ordered.initialise(0);
1986 Vector<unsigned>
proc;
1987 for (
unsigned p = 0;
p <
nproc;
p++)
1994 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2000 Internal_nblock_types,
2012 Internal_nblock_types,
2023 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2025 Nrows_to_recv_for_get_block(b,
p) =
2026 Nrows_to_send_for_get_block(b,
p);
2028 Nrows_to_recv_for_get_ordered[
p] = Nrows_to_send_for_get_ordered[
p];
2038 Rows_to_send_for_get_block.resize(Internal_nblock_types,
nproc);
2039 Rows_to_send_for_get_block.initialise(0);
2040 Rows_to_send_for_get_ordered.resize(
nproc);
2041 Rows_to_send_for_get_ordered.initialise(0);
2042 Rows_to_recv_for_get_block.resize(Internal_nblock_types,
nproc);
2043 Rows_to_recv_for_get_block.initialise(0);
2046 for (
unsigned p = 0;
p <
nproc;
p++)
2048 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2050 Rows_to_send_for_get_block(b,
p) =
2051 new int[Nrows_to_send_for_get_block(b,
p)];
2055 new int[Nrows_to_send_for_get_block(b,
p)];
2059 Rows_to_recv_for_get_block(b,
p) =
2060 new int[Nrows_to_send_for_get_block(b,
p)];
2063 Rows_to_send_for_get_ordered[
p] =
2064 new int[Nrows_to_send_for_get_ordered[
p]];
2069 DenseMatrix<unsigned>
ptr_block(Internal_nblock_types,
nproc, 0);
2070 for (
unsigned i = 0;
i < nrow_local;
i++)
2073 int b = this->internal_block_number(first_row +
i);
2079 unsigned j = this->internal_index_in_block(first_row +
i);
2083 while (!(Internal_block_distribution_pt[b]->first_row(
block_p) <=
j &&
2084 (Internal_block_distribution_pt[b]->first_row(
block_p) +
2085 Internal_block_distribution_pt[b]->nrow_local(
block_p) >
2096 j - Internal_block_distribution_pt[b]->first_row(
block_p);
2101 j - Internal_block_distribution_pt[b]->first_row(
block_p);
2108 for (
unsigned p = 0;
p <
nproc; ++
p)
2111 for (
unsigned b = 0; b < Internal_nblock_types; ++b)
2113 for (
unsigned i = 0;
i < Nrows_to_send_for_get_block(b,
p); ++
i)
2115 Rows_to_send_for_get_ordered[
p][
pt] =
2116 Rows_to_send_for_get_block(b,
p)[
i];
2139 Nrows_to_recv_for_get_ordered[
p] = 0;
2140 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2151 Rows_to_recv_for_get_ordered.resize(
nproc, 0);
2152 for (
unsigned p = 0;
p <
nproc;
p++)
2156 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2158 Rows_to_recv_for_get_block(b,
p) =
2159 new int[Nrows_to_recv_for_get_block(b,
p)];
2168 for (
unsigned p = 0;
p <
nproc;
p++)
2172 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2174 if (Nrows_to_send_for_get_block(b,
p) > 0)
2178 if (Nrows_to_recv_for_get_block(b,
p) > 0)
2190 for (
unsigned p = 0;
p <
nproc;
p++)
2201 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2203 if (Nrows_to_send_for_get_block(b,
p) > 0)
2246 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2248 if (Nrows_to_recv_for_get_block(b,
p) > 0)
2298 Rows_to_recv_for_get_ordered.resize(
nproc);
2299 Rows_to_recv_for_get_ordered.initialise(0);
2302 Vector<int>
vec_offset(Internal_nblock_types, 0);
2303 for (
unsigned b = 1; b < Internal_nblock_types; ++b)
2306 Internal_block_distribution_pt[b - 1]->nrow_local();
2310 for (
unsigned p = 0;
p <
nproc;
p++)
2313 Rows_to_recv_for_get_ordered[
p] =
2314 new int[Nrows_to_recv_for_get_ordered[
p]];
2315 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2317 for (
unsigned i = 0;
i < Nrows_to_recv_for_get_block(b,
p);
i++)
2319 Rows_to_recv_for_get_ordered[
p][
pt] =
2327 for (
unsigned p = 0;
p <
nproc;
p++)
2331 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2335 if (Nrows_to_send_for_get_ordered[
p] > 0)
2348 for (
unsigned p = 0;
p <
nproc;
p++)
2356 if (block_output_on()) output_blocks_to_files(Output_base_filename);
2375 template<
typename MATRIX>
2385 for (
unsigned dof_i = 0;
2396 turn_into_subsidiary_block_preconditioner(
2454 template<
typename MATRIX>
2466 Doftype_in_master_preconditioner_coarse =
2482 template<
typename MATRIX>
2488 if (this->is_master_block_preconditioner())
2491 unsigned n = nmesh();
2494 err_msg <<
"No meshes have been set for this block preconditioner!\n"
2495 <<
"Set one with set_nmesh(...), set_mesh(...)" << std::endl;
2498 for (
unsigned m = 0;
m <
n;
m++)
2500 if (Mesh_pt[
m] == 0)
2502 err_msg <<
"The mesh pointer to mesh " <<
m <<
" is null!\n"
2503 <<
"Set a non-null one with set_mesh(...)" << std::endl;
2536 template<
typename MATRIX>
2549 std::ostringstream error_message;
2550 error_message <<
"The size of the matrix of bools required_blocks "
2551 <<
"(which indicates which blocks are required) is not the "
2552 <<
"right size, required_blocks is "
2554 <<
", whereas it should "
2564 std::ostringstream error_message;
2565 error_message <<
"The size of the block matrix pt is not the "
2566 <<
"right size, block_matrix_pt is "
2568 <<
", whereas it should "
2607 template<
typename MATRIX>
2619 err_msg <<
"The distribution of the global vector v must be setup.";
2628 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
2631 err_msg <<
"The distribution of the global vector v must match the "
2632 <<
" specified master_distribution_pt(). \n"
2633 <<
"i.e. Distribution_pt in the master preconditioner";
2646 <<
" number of blocks, (block_vec_number.size() is "
2649 <<
" nblock_types.\n"
2650 <<
"Please make sure that block_vec_number is correctly sized.\n";
2668 <<
" nblock_types.\n";
2678 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
2685 <<
" appears twice.\n";
2686 throw OomphLibError(
2703 for (
unsigned b = 0; b <
n_block; b++)
2707 Block_to_dof_map_fine[
mapped_b].begin(),
2708 Block_to_dof_map_fine[
mapped_b].end());
2730 if (
iter != Auxiliary_block_distribution_pt.end())
2741 for (
unsigned b = 0; b <
n_block; b++)
2748 LinearAlgebraDistribution*
tmp_dist_pt =
new LinearAlgebraDistribution;
2773 template<
typename MATRIX>
2785 err_msg <<
"The distribution of the global vector v must be setup.";
2794 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
2797 err_msg <<
"The distribution of the global vector v must match the "
2798 <<
" specified master_distribution_pt(). \n"
2799 <<
"i.e. Distribution_pt in the master preconditioner";
2812 <<
" block vectors.\n"
2813 <<
"But there are only " <<
para_n_block <<
" block types.\n";
2830 <<
"But there are only " <<
para_n_block <<
" block types.\n";
2840 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
2847 <<
" appears twice.\n";
2848 throw OomphLibError(
2857 err_msg <<
"The distribution of the block vector w must be setup.";
2858 throw OomphLibError(
2882 err_msg <<
"The distribution of the block vector w does not match \n"
2883 <<
"the concatenation of the block distributions defined in \n"
2884 <<
"block_vec_number.\n";
2885 throw OomphLibError(
2901 for (
unsigned b = 0; b <
n_block; b++)
2905 Block_to_dof_map_fine[
mapped_b].begin(),
2906 Block_to_dof_map_fine[
mapped_b].end());
2915 for (
unsigned d = 0; d <
ndof; d++)
2938 template<
typename MATRIX>
2950 err_msg <<
"The distribution of the global vector v must be setup.";
2959 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
2962 err_msg <<
"The distribution of the global vector v must match the "
2963 <<
" specified master_distribution_pt(). \n"
2964 <<
"i.e. Distribution_pt in the master preconditioner";
2977 <<
" number of blocks, (block_vec_number.size() is "
2980 <<
" nblock_types.\n"
2981 <<
"Please make sure that block_vec_number is correctly sized.\n";
2999 <<
" nblock_types.\n";
3008 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
3015 <<
" appears twice.\n";
3034 for (
unsigned b = 0; b <
n_block; b++)
3039 Block_to_dof_map_fine[
mapped_b].begin(),
3040 Block_to_dof_map_fine[
mapped_b].end());
3054 unsigned offset = 0;
3056 for (
unsigned b = 0; b <
n_block; b++)
3072 s[b].build(Block_distribution_pt[
mapped_b], 0);
3101 template<
typename MATRIX>
3106 const unsigned n_block = nblock_types();
3130 template<
typename MATRIX>
3139 std::ostringstream error_message;
3140 error_message <<
"The distribution of the global vector v must be setup.";
3144 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
3146 std::ostringstream error_message;
3147 error_message <<
"The distribution of the global vector v must match the "
3148 <<
" specified master_distribution_pt(). \n"
3149 <<
"i.e. Distribution_pt in the master preconditioner";
3162 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
3163 !this->distribution_pt()->distributed())
3169 const double*
v_pt =
v.values_pt();
3172 for (
unsigned b = 0; b <
nblock; b++)
3176 double*
s_pt =
s[b].values_pt();
3177 unsigned nrow =
s[b].nrow();
3178 for (
unsigned i = 0;
i < nrow;
i++)
3189 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
3192 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
3196 for (
unsigned b = 0; b <
nblock; b++)
3208 for (
unsigned p = 0;
p <
nproc;
p++)
3210 for (
unsigned b = 0; b <
nblock; b++)
3238 for (
unsigned p = 0;
p <
nproc;
p++)
3251 for (
unsigned b = 0; b <
nblock; b++)
3287 MPI_Isend(
const_cast<double*
>(
v.values_pt()),
3292 this->distribution_pt()->communicator_pt()->mpi_comm(),
3320 for (
unsigned b = 0; b <
nblock; b++)
3355 this->distribution_pt()->communicator_pt()->
mpi_comm(),
3370 for (
unsigned b = 0; b <
nblock; b++)
3375 for (
unsigned i = 0;
3397 std::ostringstream error_message;
3398 error_message <<
"The preconditioner is distributed and on more than one "
3399 <<
"processor. MPI is required.";
3419 template<
typename MATRIX>
3424 const unsigned nblock = this->internal_nblock_types();
3426 for (
unsigned b = 0; b <
nblock; b++)
3442 template<
typename MATRIX>
3454 err_msg <<
"The distribution of the global vector v must be setup.";
3463 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
3466 err_msg <<
"The distribution of the global vector v must match the "
3467 <<
" specified master_distribution_pt(). \n"
3468 <<
"i.e. Distribution_pt in the master preconditioner";
3483 <<
"But they must be the same size!\n";
3495 <<
" block vectors.\n"
3496 <<
"But there are only " <<
para_n_block <<
" block types.\n";
3513 <<
"But there are only " <<
para_n_block <<
" block types.\n";
3523 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
3530 <<
" appears twice.\n";
3543 err_msg <<
"The distribution of the block vector s[" << b
3544 <<
"] must be setup.\n";
3555 if (*(
s[b].distribution_pt()) !=
3558 std::ostringstream error_message;
3560 <<
"The distribution of the block vector " << b <<
" must match the"
3561 <<
" specified distribution at "
3563 <<
"The distribution of the Block_distribution_pt is determined by\n"
3564 <<
"the vector block_vec_number. Perhaps it is incorrect?\n";
3583 for (
unsigned b = 0; b <
n_block; b++)
3588 Block_to_dof_map_fine[
mapped_b].begin(),
3589 Block_to_dof_map_fine[
mapped_b].end());
3595 unsigned offset = 0;
3598 for (
unsigned b = 0; b <
n_block; b++)
3617 for (
unsigned d = 0; d <
ndof; d++)
3654 template<
typename MATRIX>
3659 const unsigned n_block = nblock_types();
3683 template<
typename MATRIX>
3695 std::ostringstream error_message;
3696 error_message <<
"The distribution of the global vector v must be setup.";
3700 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
3702 std::ostringstream error_message;
3703 error_message <<
"The distribution of the global vector v must match the "
3704 <<
" specified master_distribution_pt(). \n"
3705 <<
"i.e. Distribution_pt in the master preconditioner";
3709 for (
unsigned b = 0; b <
nblock; b++)
3713 std::ostringstream error_message;
3714 error_message <<
"The distribution of the block vector " << b
3715 <<
" must be setup.";
3721 if (*(
s[b].distribution_pt()) !=
3724 std::ostringstream error_message;
3726 <<
"The distribution of the block vector " << b <<
" must match the"
3727 <<
" specified distribution at Internal_block_distribution_pt[" << b
3739 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
3740 !this->distribution_pt()->distributed())
3742 double*
v_pt =
v.values_pt();
3743 for (
unsigned b = 0; b <
nblock; b++)
3747 const double*
s_pt =
s[b].values_pt();
3749 for (
unsigned i = 0;
i < nrow;
i++)
3761 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
3764 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
3772 for (
unsigned p = 0;
p <
nproc;
p++)
3774 for (
unsigned b = 0; b <
nblock; b++)
3803 for (
unsigned p = 0;
p <
nproc;
p++)
3816 for (
unsigned b = 0; b <
nblock; b++)
3857 this->distribution_pt()->communicator_pt()->mpi_comm(),
3886 for (
unsigned b = 0; b <
nblock; b++)
3917 MPI_Isend(
const_cast<double*
>(
s[0].values_pt()),
3922 this->distribution_pt()->communicator_pt()->
mpi_comm(),
3937 for (
unsigned b = 0; b <
nblock; b++)
3942 for (
unsigned i = 0;
3964 std::ostringstream error_message;
3965 error_message <<
"The preconditioner is distributed and on more than one "
3966 <<
"processor. MPI is required.";
3986 template<
typename MATRIX>
3991 const unsigned nblock = this->internal_nblock_types();
3993 for (
unsigned b = 0; b <
nblock; b++)
4008 template<
typename MATRIX>
4014 const unsigned n_blocks = this->internal_nblock_types();
4019 std::ostringstream error_message;
4021 <<
"Requested block vector " << b
4022 <<
", however this preconditioner has internal_nblock_types() "
4023 <<
"= " << internal_nblock_types() << std::endl;
4029 std::ostringstream error_message;
4030 error_message <<
"The distribution of the global vector v must be setup.";
4034 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
4036 std::ostringstream error_message;
4037 error_message <<
"The distribution of the global vector v must match the "
4038 <<
" specified master_distribution_pt(). \n"
4039 <<
"i.e. Distribution_pt in the master preconditioner";
4046 w.
build(Internal_block_distribution_pt[b], 0.0);
4051 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4052 !this->distribution_pt()->distributed())
4055 const double*
v_pt =
v.values_pt();
4057 for (
unsigned i = 0;
i <
n_row;
i++)
4068 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4071 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4075 for (
unsigned p = 0;
p <
nproc;
p++)
4093 for (
unsigned p = 0;
p <
nproc;
p++)
4098 if (Nrows_to_send_for_get_block(b,
p) > 0)
4104 Rows_to_send_for_get_block(b,
p),
4111 MPI_Isend(
const_cast<double*
>(
v.values_pt()),
4116 this->distribution_pt()->communicator_pt()->mpi_comm(),
4122 if (Nrows_to_recv_for_get_block(b,
p) > 0)
4128 Rows_to_recv_for_get_block(b,
p),
4140 this->distribution_pt()->communicator_pt()->mpi_comm(),
4152 for (
unsigned i = 0;
i < Nrows_to_send_for_get_block(b,
p);
i++)
4171 std::ostringstream error_message;
4172 error_message <<
"The preconditioner is distributed and on more than one "
4173 <<
"processor. MPI is required.";
4185 template<
typename MATRIX>
4198 err_msg <<
"Requested block vector " << b
4199 <<
", however this preconditioner has only " <<
para_n_blocks
4209 err_msg <<
"The distribution of the global vector v must be setup.";
4213 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
4216 err_msg <<
"The distribution of the global vector v must match the "
4217 <<
" specified master_distribution_pt(). \n"
4218 <<
"i.e. Distribution_pt in the master preconditioner";
4271 w.
build(Block_distribution_pt[b], 0);
4292 template<
typename MATRIX>
4298 const unsigned n_blocks = this->internal_nblock_types();
4303 std::ostringstream error_message;
4305 <<
"Requested block vector " << b
4306 <<
", however this preconditioner has internal_nblock_types() "
4307 <<
"= " << internal_nblock_types() << std::endl;
4313 std::ostringstream error_message;
4314 error_message <<
"The distribution of the global vector v must be setup.";
4318 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4320 std::ostringstream error_message;
4321 error_message <<
"The distribution of the global vector v must match the "
4322 <<
" specified master_distribution_pt(). \n"
4323 <<
"i.e. Distribution_pt in the master preconditioner";
4329 std::ostringstream error_message;
4330 error_message <<
"The distribution of the block vector w must be setup.";
4336 std::ostringstream error_message;
4338 <<
"The distribution of the block vector w must match the "
4339 <<
" specified distribution at Internal_block_distribution_pt[b]";
4348 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4349 !this->distribution_pt()->distributed())
4352 unsigned n_row = this->internal_block_dimension(b);
4355 double*
v_pt =
v.values_pt();
4357 for (
unsigned i = 0;
i <
n_row;
i++)
4368 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4371 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4375 for (
unsigned p = 0;
p <
nproc;
p++)
4393 for (
unsigned p = 0;
p <
nproc;
p++)
4398 if (Nrows_to_recv_for_get_block(b,
p) > 0)
4404 Rows_to_recv_for_get_block(b,
p),
4416 this->distribution_pt()->communicator_pt()->mpi_comm(),
4422 if (Nrows_to_send_for_get_block(b,
p) > 0)
4428 Rows_to_send_for_get_block(b,
p),
4440 this->distribution_pt()->communicator_pt()->mpi_comm(),
4452 for (
unsigned i = 0;
i < Nrows_to_send_for_get_block(b,
p);
i++)
4471 std::ostringstream error_message;
4472 error_message <<
"The preconditioner is distributed and on more than one "
4473 <<
"processor. MPI is required.";
4488 template<
typename MATRIX>
4501 err_msg <<
"Requested block vector " << b
4503 <<
" block types.\n";
4510 err_msg <<
"The distribution of the global vector v must be setup.";
4514 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4517 err_msg <<
"The distribution of the global vector v must match the "
4518 <<
" specified master_distribution_pt(). \n"
4519 <<
"i.e. Distribution_pt in the master preconditioner";
4526 err_msg <<
"The distribution of the block vector b must be setup.";
4548 for (
unsigned d = 0; d <
n_dof_vec; d++)
4597 template<
typename MATRIX>
4605 std::ostringstream error_message;
4606 error_message <<
"The distribution of the global vector v must be setup.";
4610 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4612 std::ostringstream error_message;
4613 error_message <<
"The distribution of the global vector v must match the "
4614 <<
" specified master_distribution_pt(). \n"
4615 <<
"i.e. Distribution_pt in the master preconditioner";
4622 w.
build(this->internal_preconditioner_matrix_distribution_pt(), 0.0);
4627 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4628 !this->distribution_pt()->distributed())
4631 unsigned nblock = this->Internal_nblock_types;
4636 const double*
v_pt =
v.values_pt();
4637 for (
unsigned b = 0; b <
nblock; b++)
4639 unsigned block_nrow = this->internal_block_dimension(b);
4653 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4656 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4660 for (
unsigned p = 0;
p <
nproc;
p++)
4678 for (
unsigned p = 0;
p <
nproc;
p++)
4683 if (Nrows_to_send_for_get_ordered[
p] > 0)
4689 Rows_to_send_for_get_ordered[
p],
4696 MPI_Isend(
const_cast<double*
>(
v.values_pt()),
4701 this->distribution_pt()->communicator_pt()->mpi_comm(),
4707 if (Nrows_to_recv_for_get_ordered[
p] > 0)
4713 Rows_to_recv_for_get_ordered[
p],
4725 this->distribution_pt()->communicator_pt()->mpi_comm(),
4737 for (
unsigned i = 0;
i < Nrows_to_send_for_get_ordered[
p];
i++)
4756 std::ostringstream error_message;
4757 error_message <<
"The preconditioner is distributed and on more than one "
4758 <<
"processor. MPI is required.";
4792 template<
typename MATRIX>
4799 std::ostringstream error_message;
4800 error_message <<
"The distribution of the global vector v must be setup.";
4804 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4806 std::ostringstream error_message;
4807 error_message <<
"The distribution of the global vector v must match the "
4808 <<
" specified master_distribution_pt(). \n"
4809 <<
"i.e. Distribution_pt in the master preconditioner";
4816 unsigned nblocks = this->nblock_types();
4820 for (
unsigned b = 0; b <
nblocks; b++)
4848 template<
typename MATRIX>
4856 std::ostringstream error_message;
4857 error_message <<
"The distribution of the global vector v must be setup.";
4861 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4863 std::ostringstream error_message;
4864 error_message <<
"The distribution of the global vector v must match the "
4865 <<
" specified master_distribution_pt(). \n"
4866 <<
"i.e. Distribution_pt in the master preconditioner";
4872 std::ostringstream error_message;
4873 error_message <<
"The distribution of the block vector w must be setup.";
4878 *
this->internal_preconditioner_matrix_distribution_pt())
4880 std::ostringstream error_message;
4881 error_message <<
"The distribution of the block vector w must match the "
4882 <<
" specified distribution at Distribution_pt[b]";
4892 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4893 !this->distribution_pt()->distributed())
4896 unsigned nblock = this->Internal_nblock_types;
4901 double*
v_pt =
v.values_pt();
4902 for (
unsigned b = 0; b <
nblock; b++)
4904 unsigned block_nrow = this->internal_block_dimension(b);
4918 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4921 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4925 for (
unsigned p = 0;
p <
nproc;
p++)
4943 for (
unsigned p = 0;
p <
nproc;
p++)
4948 if (Nrows_to_recv_for_get_ordered[
p] > 0)
4954 Rows_to_recv_for_get_ordered[
p],
4966 this->distribution_pt()->communicator_pt()->mpi_comm(),
4972 if (Nrows_to_send_for_get_ordered[
p] > 0)
4978 Rows_to_send_for_get_ordered[
p],
4990 this->distribution_pt()->communicator_pt()->mpi_comm(),
5002 for (
unsigned i = 0;
i < Nrows_to_send_for_get_ordered[
p];
i++)
5021 std::ostringstream error_message;
5022 error_message <<
"The preconditioner is distributed and on more than one "
5023 <<
"processor. MPI is required.";
5045 template<
typename MATRIX>
5052 std::ostringstream error_message;
5053 error_message <<
"The distribution of the global vector v must be setup.";
5057 if (*
v.distribution_pt() != *
this->master_distribution_pt())
5059 std::ostringstream error_message;
5060 error_message <<
"The distribution of the global vector v must match the "
5061 <<
" specified master_distribution_pt(). \n"
5062 <<
"i.e. Distribution_pt in the master preconditioner";
5068 std::ostringstream error_message;
5069 error_message <<
"The distribution of the block vector w must be setup.";
5075 std::ostringstream error_message;
5076 error_message <<
"The distribution of the block vector w must match the "
5077 <<
"concatenations of distributions in "
5078 <<
"Block_distribution_pt.\n";
5085 const unsigned nblocks = nblock_types();
5087 for (
unsigned b = 0; b <
nblocks; b++)
5108 const unsigned n_blocks = this->internal_nblock_types();
5113 std::ostringstream error_message;
5116 <<
"), however this preconditioner has internal_nblock_types() "
5117 <<
"= " << internal_nblock_types() << std::endl;
5123 if (is_subsidiary_block_preconditioner())
5125 if (master_block_preconditioner_pt()->matrix_pt() != matrix_pt())
5127 std::string
err =
"Master and subs should have same matrix.";
5140 if (
cr_matrix_pt->distribution_pt()->communicator_pt()->nproc() == 1 ||
5170 unsigned master_nrow = this->master_nrow();
5175 for (
unsigned k = 0;
k < master_nrow;
k++)
5177 if (internal_block_number(
k) ==
static_cast<int>(
block_i))
5185 temp_ptr[internal_index_in_block(
k) + 1]++;
5207 for (
unsigned k = 0;
k < master_nrow;
k++)
5209 if (internal_block_number(
k) ==
static_cast<int>(
block_i))
5237 if (Run_block_matrix_test)
5251 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
5254 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
5275 unsigned nrow_local =
5276 Internal_block_distribution_pt[
block_i]->nrow_local();
5282 for (
unsigned p = 0;
p <
nproc;
p++)
5300 unsigned row = Rows_to_send_for_get_block(
block_i,
p)[
i];
5331 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5345 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5354 for (
unsigned p = 0;
p <
nproc;
p++)
5370 unsigned row = Rows_to_send_for_get_block(
block_i,
p)[
i];
5417 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5436 for (
unsigned p = 0;
p <
nproc;
p++)
5439 for (
unsigned i = 0;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5451 for (
unsigned p = 0;
p <
nproc;
p++)
5453 if (Nrows_to_recv_for_get_block(
block_i,
p) > 0)
5457 for (
unsigned i = 1;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5459 if (Rows_to_recv_for_get_block(
block_i,
p)[
i] !=
5460 Rows_to_recv_for_get_block(
block_i,
p)[
i - 1] + 1)
5469 for (
unsigned i = 0;
i <= nrow_local;
i++)
5473 for (
unsigned p = 0;
p <
nproc;
p++)
5475 for (
unsigned i = 0;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5483 for (
unsigned i = 1;
i < nrow_local;
i++)
5494 for (
unsigned p = 0;
p <
nproc;
p++)
5496 if (Nrows_to_recv_for_get_block(
block_i,
p) > 0)
5509 for (
unsigned i = 1;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5511 if (Rows_to_recv_for_get_block(
block_i,
p)[
i] !=
5512 Rows_to_recv_for_get_block(
block_i,
p)[
i - 1] + 1)
5528 for (
unsigned p = 0;
p <
nproc;
p++)
5575 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5594 if (Rows_to_recv_for_get_block(
block_i,
p)[
i] !=
5595 Rows_to_recv_for_get_block(
block_i,
p)[
i - 1] + 1)
5641 for (
unsigned p = 0;
p <
nproc;
p++)
5651 std::ostringstream error_message;
5652 error_message <<
"The matrix is distributed and on more than one "
5653 <<
"processor. MPI is required.";
5686 <<
"), however this preconditioner has ndof_types() "
5709 if (is_master_block_preconditioner())
5718 master_block_preconditioner_pt()->get_dof_level_block(
5733 if (is_subsidiary_block_preconditioner())
5747 if (is_master_block_preconditioner())
5757 master_block_preconditioner_pt()->get_dof_level_block(
5774 if (is_master_block_preconditioner())
5785 master_block_preconditioner_pt()->dof_block_distribution_pt(
5798 if (is_master_block_preconditioner())
5808 master_block_preconditioner_pt()->dof_block_distribution_pt(
5838 template<
typename MATRIX>
5848 unsigned n_row = matrix_pt()->nrow();
5851 unsigned n_col = matrix_pt()->ncol();
5854 for (
unsigned i = 0;
i <
n_row;
i++)
5858 if (
static_cast<int>(
block_i) == this->internal_block_number(
i))
5861 for (
unsigned j = 0;
j <
n_col;
j++)
5865 if (
static_cast<int>(
block_j) == this->internal_block_number(
j))
5869 if (matrix_pt()->
operator()(
i,
j) !=
5871 internal_index_in_block(
j)))
5883 std::ostringstream error_message;
5884 error_message <<
"The require elements have not been successfully copied"
5885 <<
" from the original matrix to the block matrices";