1667 Block_number_to_dof_number_lookup.clear();
1669 Ndof_in_block.clear();
1673 Dof_number_to_block_number_lookup.resize(Internal_ndof_types);
1676 for (
unsigned i = 0;
i < Internal_ndof_types;
i++)
1688 if (Block_number_to_dof_number_lookup[
i].
size() == 0)
1690 std::ostringstream error_message;
1691 error_message <<
"block number " <<
i
1692 <<
" does not have any DOFs associated with it";
1704 bool distributed = this->master_distribution_pt()->distributed();
1707 Internal_block_distribution_pt.resize(Internal_nblock_types);
1708 for (
unsigned i = 0;
i < Internal_nblock_types;
i++)
1711 for (
unsigned j = 0;
j < Ndof_in_block[
i];
j++)
1714 internal_dof_block_dimension(Block_number_to_dof_number_lookup[
i][
j]);
1716 Internal_block_distribution_pt[
i] =
1717 new LinearAlgebraDistribution(comm_pt(),
block_dim, distributed);
1725 if (is_subsidiary_block_preconditioner())
1729 Dof_block_distribution_pt.size();
1732 delete Dof_block_distribution_pt[
dof_i];
1735 Dof_block_distribution_pt.resize(
ndofs, 0);
1744 Doftype_coarsen_map_coarse[
dof_i].size();
1751 master_block_preconditioner_pt()->dof_block_distribution_pt(
1752 Doftype_in_master_preconditioner_coarse
1756 Dof_block_distribution_pt[
dof_i] =
new LinearAlgebraDistribution;
1772 delete Block_distribution_pt[
dist_i];
1775 Block_distribution_pt.clear();
1793 Block_distribution_pt[
super_block_i] =
new LinearAlgebraDistribution;
1807 LinearAlgebraDistribution
dist;
1809 Internal_block_distribution_pt,
dist);
1812 if (is_subsidiary_block_preconditioner())
1814 this->build_distribution(
dist);
1818 Internal_preconditioner_matrix_distribution_pt =
1819 new LinearAlgebraDistribution(
dist);
1822 Preconditioner_matrix_distribution_pt =
new LinearAlgebraDistribution;
1824 Block_distribution_pt, *Preconditioner_matrix_distribution_pt);
1833 const unsigned nblocks = Block_distribution_pt.size();
1843 std::map<Vector<unsigned>, LinearAlgebraDistribution*>
::iterator iter =
1844 Auxiliary_block_distribution_pt.begin();
1845 while (
iter != Auxiliary_block_distribution_pt.end())
1849 delete iter->second;
1859 Auxiliary_block_distribution_pt.clear();
1862 insert_auxiliary_block_distribution(
1880 for (
unsigned p = 0;
p <
nproc;
p++)
1897 Global_index.resize(Internal_nblock_types);
1898 for (
unsigned b = 0; b < Internal_nblock_types; b++)
1900 Global_index[b].resize(Internal_block_distribution_pt[b]->nrow());
1904 unsigned nrow = this->master_nrow();
1905 for (
unsigned i = 0;
i < nrow;
i++)
1912 unsigned block_number = Dof_number_to_block_number_lookup[
dof_number];
1915 unsigned index_in_block = 0;
1917 while (
int(Block_number_to_dof_number_lookup[block_number][
ptr]) !=
1920 index_in_block += internal_dof_block_dimension(
1921 Block_number_to_dof_number_lookup[block_number][
ptr]);
1924 index_in_block += internal_index_in_dof(
i);
1925 Global_index[block_number][index_in_block] =
i;
1935 const LinearAlgebraDistribution* master_distribution_pt =
1936 this->master_distribution_pt();
1939 Nrows_to_send_for_get_block.resize(Internal_nblock_types,
nproc);
1940 Nrows_to_send_for_get_block.initialise(0);
1941 Nrows_to_send_for_get_ordered.resize(
nproc);
1942 Nrows_to_send_for_get_ordered.initialise(0);
1945 unsigned nrow_local = master_distribution_pt->nrow_local();
1946 unsigned first_row = master_distribution_pt->first_row();
1947 for (
unsigned i = 0;
i < nrow_local;
i++)
1950 int b = this->internal_block_number(first_row +
i);
1956 unsigned j = this->internal_index_in_block(first_row +
i);
1960 while (!(Internal_block_distribution_pt[b]->first_row(
block_p) <=
j &&
1961 (Internal_block_distribution_pt[b]->first_row(
block_p) +
1962 Internal_block_distribution_pt[b]->nrow_local(
block_p) >
1969 Nrows_to_send_for_get_block(b,
block_p)++;
1970 Nrows_to_send_for_get_ordered[
block_p]++;
1975 Nrows_to_recv_for_get_block.resize(Internal_nblock_types,
nproc);
1976 Nrows_to_recv_for_get_block.initialise(0);
1977 Nrows_to_recv_for_get_ordered.resize(
nproc);
1978 Nrows_to_recv_for_get_ordered.initialise(0);
1985 Vector<unsigned>
proc;
1986 for (
unsigned p = 0;
p <
nproc;
p++)
1993 for (
unsigned b = 0; b < Internal_nblock_types; b++)
1999 Internal_nblock_types,
2011 Internal_nblock_types,
2022 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2024 Nrows_to_recv_for_get_block(b,
p) =
2025 Nrows_to_send_for_get_block(b,
p);
2027 Nrows_to_recv_for_get_ordered[
p] = Nrows_to_send_for_get_ordered[
p];
2037 Rows_to_send_for_get_block.resize(Internal_nblock_types,
nproc);
2038 Rows_to_send_for_get_block.initialise(0);
2039 Rows_to_send_for_get_ordered.resize(
nproc);
2040 Rows_to_send_for_get_ordered.initialise(0);
2041 Rows_to_recv_for_get_block.resize(Internal_nblock_types,
nproc);
2042 Rows_to_recv_for_get_block.initialise(0);
2045 for (
unsigned p = 0;
p <
nproc;
p++)
2047 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2049 Rows_to_send_for_get_block(b,
p) =
2050 new int[Nrows_to_send_for_get_block(b,
p)];
2054 new int[Nrows_to_send_for_get_block(b,
p)];
2058 Rows_to_recv_for_get_block(b,
p) =
2059 new int[Nrows_to_send_for_get_block(b,
p)];
2062 Rows_to_send_for_get_ordered[
p] =
2063 new int[Nrows_to_send_for_get_ordered[
p]];
2068 DenseMatrix<unsigned>
ptr_block(Internal_nblock_types,
nproc, 0);
2069 for (
unsigned i = 0;
i < nrow_local;
i++)
2072 int b = this->internal_block_number(first_row +
i);
2078 unsigned j = this->internal_index_in_block(first_row +
i);
2082 while (!(Internal_block_distribution_pt[b]->first_row(
block_p) <=
j &&
2083 (Internal_block_distribution_pt[b]->first_row(
block_p) +
2084 Internal_block_distribution_pt[b]->nrow_local(
block_p) >
2095 j - Internal_block_distribution_pt[b]->first_row(
block_p);
2100 j - Internal_block_distribution_pt[b]->first_row(
block_p);
2107 for (
unsigned p = 0;
p <
nproc; ++
p)
2110 for (
unsigned b = 0; b < Internal_nblock_types; ++b)
2112 for (
unsigned i = 0;
i < Nrows_to_send_for_get_block(b,
p); ++
i)
2114 Rows_to_send_for_get_ordered[
p][
pt] =
2115 Rows_to_send_for_get_block(b,
p)[
i];
2138 Nrows_to_recv_for_get_ordered[
p] = 0;
2139 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2150 Rows_to_recv_for_get_ordered.resize(
nproc, 0);
2151 for (
unsigned p = 0;
p <
nproc;
p++)
2155 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2157 Rows_to_recv_for_get_block(b,
p) =
2158 new int[Nrows_to_recv_for_get_block(b,
p)];
2167 for (
unsigned p = 0;
p <
nproc;
p++)
2171 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2173 if (Nrows_to_send_for_get_block(b,
p) > 0)
2177 if (Nrows_to_recv_for_get_block(b,
p) > 0)
2189 for (
unsigned p = 0;
p <
nproc;
p++)
2200 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2202 if (Nrows_to_send_for_get_block(b,
p) > 0)
2245 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2247 if (Nrows_to_recv_for_get_block(b,
p) > 0)
2297 Rows_to_recv_for_get_ordered.resize(
nproc);
2298 Rows_to_recv_for_get_ordered.initialise(0);
2301 Vector<int>
vec_offset(Internal_nblock_types, 0);
2302 for (
unsigned b = 1; b < Internal_nblock_types; ++b)
2305 Internal_block_distribution_pt[b - 1]->nrow_local();
2309 for (
unsigned p = 0;
p <
nproc;
p++)
2312 Rows_to_recv_for_get_ordered[
p] =
2313 new int[Nrows_to_recv_for_get_ordered[
p]];
2314 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2316 for (
unsigned i = 0;
i < Nrows_to_recv_for_get_block(b,
p);
i++)
2318 Rows_to_recv_for_get_ordered[
p][
pt] =
2326 for (
unsigned p = 0;
p <
nproc;
p++)
2330 for (
unsigned b = 0; b < Internal_nblock_types; b++)
2334 if (Nrows_to_send_for_get_ordered[
p] > 0)
2347 for (
unsigned p = 0;
p <
nproc;
p++)
2355 if (block_output_on()) output_blocks_to_files(Output_base_filename);
2374 template<
typename MATRIX>
2384 for (
unsigned dof_i = 0;
2395 turn_into_subsidiary_block_preconditioner(
2453 template<
typename MATRIX>
2465 Doftype_in_master_preconditioner_coarse =
2481 template<
typename MATRIX>
2487 if (this->is_master_block_preconditioner())
2490 unsigned n = nmesh();
2493 err_msg <<
"No meshes have been set for this block preconditioner!\n"
2494 <<
"Set one with set_nmesh(...), set_mesh(...)" << std::endl;
2497 for (
unsigned m = 0;
m <
n;
m++)
2499 if (Mesh_pt[
m] == 0)
2501 err_msg <<
"The mesh pointer to mesh " <<
m <<
" is null!\n"
2502 <<
"Set a non-null one with set_mesh(...)" << std::endl;
2535 template<
typename MATRIX>
2548 std::ostringstream error_message;
2549 error_message <<
"The size of the matrix of bools required_blocks "
2550 <<
"(which indicates which blocks are required) is not the "
2551 <<
"right size, required_blocks is "
2553 <<
", whereas it should "
2563 std::ostringstream error_message;
2564 error_message <<
"The size of the block matrix pt is not the "
2565 <<
"right size, block_matrix_pt is "
2567 <<
", whereas it should "
2606 template<
typename MATRIX>
2618 err_msg <<
"The distribution of the global vector v must be setup.";
2627 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
2630 err_msg <<
"The distribution of the global vector v must match the "
2631 <<
" specified master_distribution_pt(). \n"
2632 <<
"i.e. Distribution_pt in the master preconditioner";
2645 <<
" number of blocks, (block_vec_number.size() is "
2648 <<
" nblock_types.\n"
2649 <<
"Please make sure that block_vec_number is correctly sized.\n";
2667 <<
" nblock_types.\n";
2677 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
2684 <<
" appears twice.\n";
2702 for (
unsigned b = 0; b <
n_block; b++)
2706 Block_to_dof_map_fine[
mapped_b].begin(),
2707 Block_to_dof_map_fine[
mapped_b].end());
2729 if (
iter != Auxiliary_block_distribution_pt.end())
2740 for (
unsigned b = 0; b <
n_block; b++)
2747 LinearAlgebraDistribution*
tmp_dist_pt =
new LinearAlgebraDistribution;
2772 template<
typename MATRIX>
2784 err_msg <<
"The distribution of the global vector v must be setup.";
2793 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
2796 err_msg <<
"The distribution of the global vector v must match the "
2797 <<
" specified master_distribution_pt(). \n"
2798 <<
"i.e. Distribution_pt in the master preconditioner";
2811 <<
" block vectors.\n"
2812 <<
"But there are only " <<
para_n_block <<
" block types.\n";
2829 <<
"But there are only " <<
para_n_block <<
" block types.\n";
2839 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
2846 <<
" appears twice.\n";
2847 throw OomphLibError(
2856 err_msg <<
"The distribution of the block vector w must be setup.";
2857 throw OomphLibError(
2881 err_msg <<
"The distribution of the block vector w does not match \n"
2882 <<
"the concatenation of the block distributions defined in \n"
2883 <<
"block_vec_number.\n";
2884 throw OomphLibError(
2900 for (
unsigned b = 0; b <
n_block; b++)
2904 Block_to_dof_map_fine[
mapped_b].begin(),
2905 Block_to_dof_map_fine[
mapped_b].end());
2914 for (
unsigned d = 0; d <
ndof; d++)
2937 template<
typename MATRIX>
2949 err_msg <<
"The distribution of the global vector v must be setup.";
2958 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
2961 err_msg <<
"The distribution of the global vector v must match the "
2962 <<
" specified master_distribution_pt(). \n"
2963 <<
"i.e. Distribution_pt in the master preconditioner";
2976 <<
" number of blocks, (block_vec_number.size() is "
2979 <<
" nblock_types.\n"
2980 <<
"Please make sure that block_vec_number is correctly sized.\n";
2998 <<
" nblock_types.\n";
3007 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
3014 <<
" appears twice.\n";
3033 for (
unsigned b = 0; b <
n_block; b++)
3038 Block_to_dof_map_fine[
mapped_b].begin(),
3039 Block_to_dof_map_fine[
mapped_b].end());
3053 unsigned offset = 0;
3055 for (
unsigned b = 0; b <
n_block; b++)
3071 s[b].build(Block_distribution_pt[
mapped_b], 0);
3100 template<
typename MATRIX>
3105 const unsigned n_block = nblock_types();
3129 template<
typename MATRIX>
3138 std::ostringstream error_message;
3139 error_message <<
"The distribution of the global vector v must be setup.";
3143 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
3145 std::ostringstream error_message;
3146 error_message <<
"The distribution of the global vector v must match the "
3147 <<
" specified master_distribution_pt(). \n"
3148 <<
"i.e. Distribution_pt in the master preconditioner";
3161 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
3162 !this->distribution_pt()->distributed())
3168 const double*
v_pt =
v.values_pt();
3171 for (
unsigned b = 0; b <
nblock; b++)
3175 double*
s_pt =
s[b].values_pt();
3176 unsigned nrow =
s[b].nrow();
3177 for (
unsigned i = 0;
i < nrow;
i++)
3188 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
3191 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
3195 for (
unsigned b = 0; b <
nblock; b++)
3207 for (
unsigned p = 0;
p <
nproc;
p++)
3209 for (
unsigned b = 0; b <
nblock; b++)
3237 for (
unsigned p = 0;
p <
nproc;
p++)
3250 for (
unsigned b = 0; b <
nblock; b++)
3286 MPI_Isend(
const_cast<double*
>(
v.values_pt()),
3291 this->distribution_pt()->communicator_pt()->mpi_comm(),
3319 for (
unsigned b = 0; b <
nblock; b++)
3354 this->distribution_pt()->communicator_pt()->
mpi_comm(),
3369 for (
unsigned b = 0; b <
nblock; b++)
3374 for (
unsigned i = 0;
3396 std::ostringstream error_message;
3397 error_message <<
"The preconditioner is distributed and on more than one "
3398 <<
"processor. MPI is required.";
3418 template<
typename MATRIX>
3423 const unsigned nblock = this->internal_nblock_types();
3425 for (
unsigned b = 0; b <
nblock; b++)
3441 template<
typename MATRIX>
3453 err_msg <<
"The distribution of the global vector v must be setup.";
3462 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
3465 err_msg <<
"The distribution of the global vector v must match the "
3466 <<
" specified master_distribution_pt(). \n"
3467 <<
"i.e. Distribution_pt in the master preconditioner";
3482 <<
"But they must be the same size!\n";
3494 <<
" block vectors.\n"
3495 <<
"But there are only " <<
para_n_block <<
" block types.\n";
3512 <<
"But there are only " <<
para_n_block <<
" block types.\n";
3522 std::pair<std::set<unsigned>::iterator,
bool>
para_set_ret;
3529 <<
" appears twice.\n";
3542 err_msg <<
"The distribution of the block vector s[" << b
3543 <<
"] must be setup.\n";
3554 if (*(
s[b].distribution_pt()) !=
3557 std::ostringstream error_message;
3559 <<
"The distribution of the block vector " << b <<
" must match the"
3560 <<
" specified distribution at "
3562 <<
"The distribution of the Block_distribution_pt is determined by\n"
3563 <<
"the vector block_vec_number. Perhaps it is incorrect?\n";
3582 for (
unsigned b = 0; b <
n_block; b++)
3587 Block_to_dof_map_fine[
mapped_b].begin(),
3588 Block_to_dof_map_fine[
mapped_b].end());
3594 unsigned offset = 0;
3597 for (
unsigned b = 0; b <
n_block; b++)
3616 for (
unsigned d = 0; d <
ndof; d++)
3653 template<
typename MATRIX>
3658 const unsigned n_block = nblock_types();
3682 template<
typename MATRIX>
3694 std::ostringstream error_message;
3695 error_message <<
"The distribution of the global vector v must be setup.";
3699 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
3701 std::ostringstream error_message;
3702 error_message <<
"The distribution of the global vector v must match the "
3703 <<
" specified master_distribution_pt(). \n"
3704 <<
"i.e. Distribution_pt in the master preconditioner";
3708 for (
unsigned b = 0; b <
nblock; b++)
3712 std::ostringstream error_message;
3713 error_message <<
"The distribution of the block vector " << b
3714 <<
" must be setup.";
3720 if (*(
s[b].distribution_pt()) !=
3723 std::ostringstream error_message;
3725 <<
"The distribution of the block vector " << b <<
" must match the"
3726 <<
" specified distribution at Internal_block_distribution_pt[" << b
3738 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
3739 !this->distribution_pt()->distributed())
3741 double*
v_pt =
v.values_pt();
3742 for (
unsigned b = 0; b <
nblock; b++)
3746 const double*
s_pt =
s[b].values_pt();
3748 for (
unsigned i = 0;
i < nrow;
i++)
3760 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
3763 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
3771 for (
unsigned p = 0;
p <
nproc;
p++)
3773 for (
unsigned b = 0; b <
nblock; b++)
3802 for (
unsigned p = 0;
p <
nproc;
p++)
3815 for (
unsigned b = 0; b <
nblock; b++)
3856 this->distribution_pt()->communicator_pt()->mpi_comm(),
3885 for (
unsigned b = 0; b <
nblock; b++)
3916 MPI_Isend(
const_cast<double*
>(
s[0].values_pt()),
3921 this->distribution_pt()->communicator_pt()->
mpi_comm(),
3936 for (
unsigned b = 0; b <
nblock; b++)
3941 for (
unsigned i = 0;
3963 std::ostringstream error_message;
3964 error_message <<
"The preconditioner is distributed and on more than one "
3965 <<
"processor. MPI is required.";
3985 template<
typename MATRIX>
3990 const unsigned nblock = this->internal_nblock_types();
3992 for (
unsigned b = 0; b <
nblock; b++)
4007 template<
typename MATRIX>
4013 const unsigned n_blocks = this->internal_nblock_types();
4018 std::ostringstream error_message;
4020 <<
"Requested block vector " << b
4021 <<
", however this preconditioner has internal_nblock_types() "
4022 <<
"= " << internal_nblock_types() << std::endl;
4028 std::ostringstream error_message;
4029 error_message <<
"The distribution of the global vector v must be setup.";
4033 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
4035 std::ostringstream error_message;
4036 error_message <<
"The distribution of the global vector v must match the "
4037 <<
" specified master_distribution_pt(). \n"
4038 <<
"i.e. Distribution_pt in the master preconditioner";
4045 w.
build(Internal_block_distribution_pt[b], 0.0);
4050 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4051 !this->distribution_pt()->distributed())
4054 const double*
v_pt =
v.values_pt();
4056 for (
unsigned i = 0;
i <
n_row;
i++)
4067 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4070 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4074 for (
unsigned p = 0;
p <
nproc;
p++)
4092 for (
unsigned p = 0;
p <
nproc;
p++)
4097 if (Nrows_to_send_for_get_block(b,
p) > 0)
4103 Rows_to_send_for_get_block(b,
p),
4110 MPI_Isend(
const_cast<double*
>(
v.values_pt()),
4115 this->distribution_pt()->communicator_pt()->mpi_comm(),
4121 if (Nrows_to_recv_for_get_block(b,
p) > 0)
4127 Rows_to_recv_for_get_block(b,
p),
4139 this->distribution_pt()->communicator_pt()->mpi_comm(),
4151 for (
unsigned i = 0;
i < Nrows_to_send_for_get_block(b,
p);
i++)
4170 std::ostringstream error_message;
4171 error_message <<
"The preconditioner is distributed and on more than one "
4172 <<
"processor. MPI is required.";
4184 template<
typename MATRIX>
4197 err_msg <<
"Requested block vector " << b
4198 <<
", however this preconditioner has only " <<
para_n_blocks
4208 err_msg <<
"The distribution of the global vector v must be setup.";
4212 if (*(
v.distribution_pt()) != *(
this->master_distribution_pt()))
4215 err_msg <<
"The distribution of the global vector v must match the "
4216 <<
" specified master_distribution_pt(). \n"
4217 <<
"i.e. Distribution_pt in the master preconditioner";
4270 w.
build(Block_distribution_pt[b], 0);
4291 template<
typename MATRIX>
4297 const unsigned n_blocks = this->internal_nblock_types();
4302 std::ostringstream error_message;
4304 <<
"Requested block vector " << b
4305 <<
", however this preconditioner has internal_nblock_types() "
4306 <<
"= " << internal_nblock_types() << std::endl;
4312 std::ostringstream error_message;
4313 error_message <<
"The distribution of the global vector v must be setup.";
4317 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4319 std::ostringstream error_message;
4320 error_message <<
"The distribution of the global vector v must match the "
4321 <<
" specified master_distribution_pt(). \n"
4322 <<
"i.e. Distribution_pt in the master preconditioner";
4328 std::ostringstream error_message;
4329 error_message <<
"The distribution of the block vector w must be setup.";
4335 std::ostringstream error_message;
4337 <<
"The distribution of the block vector w must match the "
4338 <<
" specified distribution at Internal_block_distribution_pt[b]";
4347 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4348 !this->distribution_pt()->distributed())
4351 unsigned n_row = this->internal_block_dimension(b);
4354 double*
v_pt =
v.values_pt();
4356 for (
unsigned i = 0;
i <
n_row;
i++)
4367 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4370 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4374 for (
unsigned p = 0;
p <
nproc;
p++)
4392 for (
unsigned p = 0;
p <
nproc;
p++)
4397 if (Nrows_to_recv_for_get_block(b,
p) > 0)
4403 Rows_to_recv_for_get_block(b,
p),
4415 this->distribution_pt()->communicator_pt()->mpi_comm(),
4421 if (Nrows_to_send_for_get_block(b,
p) > 0)
4427 Rows_to_send_for_get_block(b,
p),
4439 this->distribution_pt()->communicator_pt()->mpi_comm(),
4451 for (
unsigned i = 0;
i < Nrows_to_send_for_get_block(b,
p);
i++)
4470 std::ostringstream error_message;
4471 error_message <<
"The preconditioner is distributed and on more than one "
4472 <<
"processor. MPI is required.";
4487 template<
typename MATRIX>
4500 err_msg <<
"Requested block vector " << b
4502 <<
" block types.\n";
4509 err_msg <<
"The distribution of the global vector v must be setup.";
4513 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4516 err_msg <<
"The distribution of the global vector v must match the "
4517 <<
" specified master_distribution_pt(). \n"
4518 <<
"i.e. Distribution_pt in the master preconditioner";
4525 err_msg <<
"The distribution of the block vector b must be setup.";
4547 for (
unsigned d = 0; d <
n_dof_vec; d++)
4596 template<
typename MATRIX>
4604 std::ostringstream error_message;
4605 error_message <<
"The distribution of the global vector v must be setup.";
4609 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4611 std::ostringstream error_message;
4612 error_message <<
"The distribution of the global vector v must match the "
4613 <<
" specified master_distribution_pt(). \n"
4614 <<
"i.e. Distribution_pt in the master preconditioner";
4621 w.
build(this->internal_preconditioner_matrix_distribution_pt(), 0.0);
4626 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4627 !this->distribution_pt()->distributed())
4630 unsigned nblock = this->Internal_nblock_types;
4635 const double*
v_pt =
v.values_pt();
4636 for (
unsigned b = 0; b <
nblock; b++)
4638 unsigned block_nrow = this->internal_block_dimension(b);
4652 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4655 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4659 for (
unsigned p = 0;
p <
nproc;
p++)
4677 for (
unsigned p = 0;
p <
nproc;
p++)
4682 if (Nrows_to_send_for_get_ordered[
p] > 0)
4688 Rows_to_send_for_get_ordered[
p],
4695 MPI_Isend(
const_cast<double*
>(
v.values_pt()),
4700 this->distribution_pt()->communicator_pt()->mpi_comm(),
4706 if (Nrows_to_recv_for_get_ordered[
p] > 0)
4712 Rows_to_recv_for_get_ordered[
p],
4724 this->distribution_pt()->communicator_pt()->mpi_comm(),
4736 for (
unsigned i = 0;
i < Nrows_to_send_for_get_ordered[
p];
i++)
4755 std::ostringstream error_message;
4756 error_message <<
"The preconditioner is distributed and on more than one "
4757 <<
"processor. MPI is required.";
4791 template<
typename MATRIX>
4798 std::ostringstream error_message;
4799 error_message <<
"The distribution of the global vector v must be setup.";
4803 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4805 std::ostringstream error_message;
4806 error_message <<
"The distribution of the global vector v must match the "
4807 <<
" specified master_distribution_pt(). \n"
4808 <<
"i.e. Distribution_pt in the master preconditioner";
4815 unsigned nblocks = this->nblock_types();
4819 for (
unsigned b = 0; b <
nblocks; b++)
4847 template<
typename MATRIX>
4855 std::ostringstream error_message;
4856 error_message <<
"The distribution of the global vector v must be setup.";
4860 if (*
v.distribution_pt() != *
this->master_distribution_pt())
4862 std::ostringstream error_message;
4863 error_message <<
"The distribution of the global vector v must match the "
4864 <<
" specified master_distribution_pt(). \n"
4865 <<
"i.e. Distribution_pt in the master preconditioner";
4871 std::ostringstream error_message;
4872 error_message <<
"The distribution of the block vector w must be setup.";
4877 *
this->internal_preconditioner_matrix_distribution_pt())
4879 std::ostringstream error_message;
4880 error_message <<
"The distribution of the block vector w must match the "
4881 <<
" specified distribution at Distribution_pt[b]";
4891 if (this->distribution_pt()->communicator_pt()->
nproc() == 1 ||
4892 !this->distribution_pt()->distributed())
4895 unsigned nblock = this->Internal_nblock_types;
4900 double*
v_pt =
v.values_pt();
4901 for (
unsigned b = 0; b <
nblock; b++)
4903 unsigned block_nrow = this->internal_block_dimension(b);
4917 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
4920 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
4924 for (
unsigned p = 0;
p <
nproc;
p++)
4942 for (
unsigned p = 0;
p <
nproc;
p++)
4947 if (Nrows_to_recv_for_get_ordered[
p] > 0)
4953 Rows_to_recv_for_get_ordered[
p],
4965 this->distribution_pt()->communicator_pt()->mpi_comm(),
4971 if (Nrows_to_send_for_get_ordered[
p] > 0)
4977 Rows_to_send_for_get_ordered[
p],
4989 this->distribution_pt()->communicator_pt()->mpi_comm(),
5001 for (
unsigned i = 0;
i < Nrows_to_send_for_get_ordered[
p];
i++)
5020 std::ostringstream error_message;
5021 error_message <<
"The preconditioner is distributed and on more than one "
5022 <<
"processor. MPI is required.";
5044 template<
typename MATRIX>
5051 std::ostringstream error_message;
5052 error_message <<
"The distribution of the global vector v must be setup.";
5056 if (*
v.distribution_pt() != *
this->master_distribution_pt())
5058 std::ostringstream error_message;
5059 error_message <<
"The distribution of the global vector v must match the "
5060 <<
" specified master_distribution_pt(). \n"
5061 <<
"i.e. Distribution_pt in the master preconditioner";
5067 std::ostringstream error_message;
5068 error_message <<
"The distribution of the block vector w must be setup.";
5074 std::ostringstream error_message;
5075 error_message <<
"The distribution of the block vector w must match the "
5076 <<
"concatenations of distributions in "
5077 <<
"Block_distribution_pt.\n";
5084 const unsigned nblocks = nblock_types();
5086 for (
unsigned b = 0; b <
nblocks; b++)
5107 const unsigned n_blocks = this->internal_nblock_types();
5112 std::ostringstream error_message;
5115 <<
"), however this preconditioner has internal_nblock_types() "
5116 <<
"= " << internal_nblock_types() << std::endl;
5122 if (is_subsidiary_block_preconditioner())
5124 if (master_block_preconditioner_pt()->matrix_pt() != matrix_pt())
5126 std::string
err =
"Master and subs should have same matrix.";
5139 if (
cr_matrix_pt->distribution_pt()->communicator_pt()->nproc() == 1 ||
5169 unsigned master_nrow = this->master_nrow();
5174 for (
unsigned k = 0;
k < master_nrow;
k++)
5176 if (internal_block_number(
k) ==
static_cast<int>(
block_i))
5184 temp_ptr[internal_index_in_block(
k) + 1]++;
5206 for (
unsigned k = 0;
k < master_nrow;
k++)
5208 if (internal_block_number(
k) ==
static_cast<int>(
block_i))
5236 if (Run_block_matrix_test)
5250 unsigned nproc = this->distribution_pt()->communicator_pt()->nproc();
5253 unsigned my_rank = this->distribution_pt()->communicator_pt()->my_rank();
5274 unsigned nrow_local =
5275 Internal_block_distribution_pt[
block_i]->nrow_local();
5281 for (
unsigned p = 0;
p <
nproc;
p++)
5299 unsigned row = Rows_to_send_for_get_block(
block_i,
p)[
i];
5330 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5344 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5353 for (
unsigned p = 0;
p <
nproc;
p++)
5369 unsigned row = Rows_to_send_for_get_block(
block_i,
p)[
i];
5416 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5435 for (
unsigned p = 0;
p <
nproc;
p++)
5438 for (
unsigned i = 0;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5450 for (
unsigned p = 0;
p <
nproc;
p++)
5452 if (Nrows_to_recv_for_get_block(
block_i,
p) > 0)
5456 for (
unsigned i = 1;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5458 if (Rows_to_recv_for_get_block(
block_i,
p)[
i] !=
5459 Rows_to_recv_for_get_block(
block_i,
p)[
i - 1] + 1)
5468 for (
unsigned i = 0;
i <= nrow_local;
i++)
5472 for (
unsigned p = 0;
p <
nproc;
p++)
5474 for (
unsigned i = 0;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5482 for (
unsigned i = 1;
i < nrow_local;
i++)
5493 for (
unsigned p = 0;
p <
nproc;
p++)
5495 if (Nrows_to_recv_for_get_block(
block_i,
p) > 0)
5508 for (
unsigned i = 1;
i < Nrows_to_recv_for_get_block(
block_i,
p);
i++)
5510 if (Rows_to_recv_for_get_block(
block_i,
p)[
i] !=
5511 Rows_to_recv_for_get_block(
block_i,
p)[
i - 1] + 1)
5527 for (
unsigned p = 0;
p <
nproc;
p++)
5574 this->distribution_pt()->communicator_pt()->
mpi_comm(),
5593 if (Rows_to_recv_for_get_block(
block_i,
p)[
i] !=
5594 Rows_to_recv_for_get_block(
block_i,
p)[
i - 1] + 1)
5640 for (
unsigned p = 0;
p <
nproc;
p++)
5650 std::ostringstream error_message;
5651 error_message <<
"The matrix is distributed and on more than one "
5652 <<
"processor. MPI is required.";
5685 <<
"), however this preconditioner has ndof_types() "
5708 if (is_master_block_preconditioner())
5717 master_block_preconditioner_pt()->get_dof_level_block(
5732 if (is_subsidiary_block_preconditioner())
5746 if (is_master_block_preconditioner())
5756 master_block_preconditioner_pt()->get_dof_level_block(
5773 if (is_master_block_preconditioner())
5784 master_block_preconditioner_pt()->dof_block_distribution_pt(
5797 if (is_master_block_preconditioner())
5807 master_block_preconditioner_pt()->dof_block_distribution_pt(
5837 template<
typename MATRIX>
5847 unsigned n_row = matrix_pt()->nrow();
5850 unsigned n_col = matrix_pt()->ncol();
5853 for (
unsigned i = 0;
i <
n_row;
i++)
5857 if (
static_cast<int>(
block_i) == this->internal_block_number(
i))
5860 for (
unsigned j = 0;
j <
n_col;
j++)
5864 if (
static_cast<int>(
block_j) == this->internal_block_number(
j))
5868 if (matrix_pt()->
operator()(
i,
j) !=
5870 internal_index_in_block(
j)))
5882 std::ostringstream error_message;
5883 error_message <<
"The require elements have not been successfully copied"
5884 <<
" from the original matrix to the block matrices";