41 template<
typename MATRIX>
48 if (this->is_master_block_preconditioner())
51 if (this->gp_nmesh() == 0)
53 std::ostringstream err_msg;
54 err_msg <<
"There are no meshes set.\n"
55 <<
"Did you remember to call add_mesh(...)?";
57 err_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
62 this->gp_preconditioner_set_all_meshes();
66 Memory_usage_in_bytes = 0.0;
69 if (this->Silent_preconditioner_setup ==
true)
80 this->gp_preconditioner_block_setup();
83 unsigned n_block_types = this->nblock_types();
86 this->fill_in_subsidiary_preconditioners(n_block_types);
89 double t_subsidiary_setup_total = 0.0;
95 const bool want_block =
true;
98 for (
unsigned i = 0;
i < n_block_types;
i++)
101 for (
unsigned j = 0; j < n_block_types; j++)
104 required_blocks[
i][j].select_block(
i, j, want_block);
112 CRDoubleMatrix full_matrix = this->get_concatenated_block(required_blocks);
121 this->Subsidiary_preconditioner_pt[0]->setup(&full_matrix);
124 t_subsidiary_setup_total +=
128 Preconditioner_has_been_setup =
true;
131 if (this->Silent_preconditioner_setup ==
true)
141 oomph_info <<
"Total block extraction time [sec]: " << t_extraction_total
142 <<
"\nTotal subsidiary preconditioner setup time [sec]: "
143 << t_subsidiary_setup_total << std::endl;
150 if (Compute_memory_statistics)
153 unsigned n_row = this->matrix_pt()->nrow();
156 unsigned n_nnz = this->matrix_pt()->nnz();
159 double total_memory_usage_for_setup_phase =
161 this->Subsidiary_preconditioner_pt[0])
162 ->get_total_memory_needed_for_superlu();
165 total_memory_usage_for_setup_phase +=
166 ((2 * ((n_row + 1) *
sizeof(
int))) +
167 (n_nnz * (
sizeof(int) +
sizeof(
double))));
170 oomph_info <<
"\nTotal amount of memory being used after setup (MB): "
171 << total_memory_usage_for_setup_phase / 1.0e+06 <<
"\n"
180 template<
typename MATRIX>
188 this->get_block_vectors(r, block_r);
200 this->Subsidiary_preconditioner_pt[0]->preconditioner_solve(rhs_reordered,
211 this->return_block_vectors(block_z, z);
217 template<
typename MATRIX>
224 if (this->is_master_block_preconditioner())
227 if (this->gp_nmesh() == 0)
229 std::ostringstream err_msg;
230 err_msg <<
"There are no meshes set.\n"
231 <<
"Did you remember to call add_mesh(...)?";
233 err_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
238 this->gp_preconditioner_set_all_meshes();
242 Memory_usage_in_bytes = 0.0;
245 if (this->Silent_preconditioner_setup ==
true)
256 this->gp_preconditioner_block_setup();
259 unsigned n_block_types = this->nblock_types();
262 Off_diagonal_matrix_vector_products.resize(n_block_types, n_block_types, 0);
265 this->fill_in_subsidiary_preconditioners(n_block_types);
268 double t_extraction_total = 0.0;
271 double t_subsidiary_setup_total = 0.0;
274 double t_mvp_setup_total = 0.0;
277 for (
unsigned i = 0;
i < n_block_types;
i++)
281 this->Subsidiary_preconditioner_pt[
i]) != 0)
284 if (Compute_memory_statistics)
288 this->Subsidiary_preconditioner_pt[
i]))
293 this->Subsidiary_preconditioner_pt[
i])
294 ->enable_doc_memory_usage();
303 this->Subsidiary_preconditioner_pt[
i]->setup(this->matrix_pt());
309 t_subsidiary_setup_total +=
310 (t_subsidiary_setup_end - t_subsidiary_setup_start);
325 t_extraction_total += (t_extract_end - t_extract_start);
331 this->Subsidiary_preconditioner_pt[
i]->setup(&block_matrix);
337 t_subsidiary_setup_total +=
338 (t_subsidiary_setup_end - t_subsidiary_setup_start);
348 if (Upper_triangular)
354 if (Block_bandwidth >= 0)
357 u = std::min(n_block_types, l + Block_bandwidth);
373 if (Block_bandwidth >= 0)
378 l = std::max(0,
int(
int(u) - Block_bandwidth));
389 for (
unsigned j = l; j < u; j++)
398 if (Compute_memory_statistics)
401 unsigned n_row = block_matrix.
nrow();
404 unsigned n_nnz = block_matrix.
nnz();
408 Memory_usage_in_bytes += ((2 * ((n_row + 1) *
sizeof(
int))) +
409 (n_nnz * (
sizeof(int) +
sizeof(
double))));
416 t_extraction_total += (t_extract_end - t_extract_start);
426 this->setup_matrix_vector_product(
427 Off_diagonal_matrix_vector_products(
i, j), &block_matrix, j);
433 t_mvp_setup_total += (t_mvp_end - t_mvp_start);
438 Preconditioner_has_been_setup =
true;
441 if (this->Silent_preconditioner_setup ==
true)
451 oomph_info <<
"Total block extraction time [sec]: " << t_extraction_total
452 <<
"\nTotal subsidiary preconditioner setup time [sec]: "
453 << t_subsidiary_setup_total
454 <<
"\nTotal matrix-vector product setup time [sec]: "
455 << t_mvp_setup_total << std::endl;
462 if (Compute_memory_statistics)
465 double total_memory_usage_for_setup_phase = 0.0;
468 unsigned n_row = this->matrix_pt()->nrow();
471 unsigned n_nnz = this->matrix_pt()->nnz();
476 double memory_usage_for_storage_of_global_jacobian_in_bytes =
477 ((2 * ((n_row + 1) *
sizeof(
int))) +
478 (n_nnz * (
sizeof(int) +
sizeof(
double))));
481 double memory_usage_for_subsidiary_preconditioner_in_bytes = 0.0;
485 double memory_usage_for_nssbp_preconditioner_in_bytes = 0.0;
491 bool have_issued_warning_about_memory_calculations =
false;
494 for (
unsigned i = 0;
i < n_block_types;
i++)
499 this->Subsidiary_preconditioner_pt[
i]) != 0)
505 this->Subsidiary_preconditioner_pt[
i]);
508 memory_usage_for_subsidiary_preconditioner_in_bytes +=
512 memory_usage_for_nssbp_preconditioner_in_bytes +=
518 this->Subsidiary_preconditioner_pt[
i]) != 0)
521 memory_usage_for_subsidiary_preconditioner_in_bytes +=
523 this->Subsidiary_preconditioner_pt[
i])
524 ->get_total_memory_needed_for_superlu();
530 if (!have_issued_warning_about_memory_calculations)
533 have_issued_warning_about_memory_calculations =
true;
536 std::ostringstream warning_message_stream;
539 warning_message_stream
540 <<
"Can't compute the memory statistics for the " <<
i
541 <<
"-th diagonal block in the banded\nblock "
542 <<
"triangular preconditioner so I'm just going "
543 <<
"to skip it." << std::endl;
547 OOMPH_CURRENT_FUNCTION,
548 OOMPH_EXCEPTION_LOCATION);
557 if (memory_usage_for_nssbp_preconditioner_in_bytes > 0.0)
560 oomph_info <<
"Amount of memory used by Navier-Stokes subsidiary block "
561 <<
"preconditioner (MB): "
562 << memory_usage_for_nssbp_preconditioner_in_bytes / 1.0e+06
566 total_memory_usage_for_setup_phase +=
567 memory_usage_for_nssbp_preconditioner_in_bytes;
571 total_memory_usage_for_setup_phase +=
572 memory_usage_for_subsidiary_preconditioner_in_bytes;
578 total_memory_usage_for_setup_phase +=
579 memory_usage_for_storage_of_global_jacobian_in_bytes;
583 <<
"Amount of memory used by the subsidiary preconditioners "
585 << memory_usage_for_subsidiary_preconditioner_in_bytes / 1.0e+06
586 <<
"\nAmount of memory used by banded block triangular "
588 <<
"\nAmount of memory used to store (global) Jacobian (MB): "
589 << memory_usage_for_storage_of_global_jacobian_in_bytes / 1.0e+06
590 <<
"\nTotal amount of memory being used after setup (MB): "
591 << total_memory_usage_for_setup_phase / 1.0e+06 <<
"\n"
599 template<
typename MATRIX>
604 unsigned n_block = this->nblock_types();
620 if (Upper_triangular)
639 unsigned n_block_solved_with_gmres = 0;
645 this->get_block_vectors(r, block_r);
651 for (
int i =
start;
i != end;
i += step)
655 this->Subsidiary_preconditioner_pt[
i]) != 0)
665 this->return_block_vectors(block_r, r_updated);
668 this->Subsidiary_preconditioner_pt[
i]->preconditioner_solve(
669 r_updated, block_z_with_size_of_full_z);
673 this->get_block_vector(
i, block_z_with_size_of_full_z, block_z[
i]);
679 this->Subsidiary_preconditioner_pt[
i]->preconditioner_solve(block_r[
i],
686 this->Subsidiary_preconditioner_pt[
i]) != 0)
690 this->Subsidiary_preconditioner_pt[
i])
694 n_block_solved_with_gmres++;
698 if (Block_bandwidth >= 0)
701 if (Upper_triangular)
703 bandwidth_limit = std::max(end -
i, step + step * Block_bandwidth);
707 bandwidth_limit = std::min(end -
i, step + step * Block_bandwidth);
713 bandwidth_limit = end -
i;
717 for (
int j =
i + step; j !=
i + bandwidth_limit; j += step)
723 Off_diagonal_matrix_vector_products(j,
i)->multiply(block_z[
i], temp);
731 this->return_block_vectors(block_z, z);
734 if (n_block_solved_with_gmres > 0)
737 double n_iter_mean = 0.0;
740 double n_iter_var = 0.0;
743 for (
unsigned i = 0;
i < n_block;
i++)
747 this->Subsidiary_preconditioner_pt[
i]) != 0)
750 if (iteration_count[
i] < 0)
753 std::ostringstream error_message_stream;
757 <<
"Iteration count should be non-negative but "
758 <<
"you have an iteration\ncount of " << iteration_count[
i] <<
"!"
763 OOMPH_CURRENT_FUNCTION,
764 OOMPH_EXCEPTION_LOCATION);
770 for (
unsigned i = 0;
i < n_block;
i++)
774 this->Subsidiary_preconditioner_pt[
i]) != 0)
778 (double(iteration_count[
i]) / double(n_block_solved_with_gmres));
785 for (
unsigned i = 0;
i < n_block;
i++)
789 this->Subsidiary_preconditioner_pt[
i]) != 0)
793 (std::pow(
double(iteration_count[
i]) - n_iter_mean, 2.0) /
794 double(n_block_solved_with_gmres));
799 oomph_info <<
"\nNumber of subsidiary blocks solved with GMRES: "
800 << n_block_solved_with_gmres
801 <<
"\nAverage subsidiary preconditioner iteration count: "
803 <<
"\nStandard deviation of subsidiary preconditioner "
804 <<
"iteration count: " << std::sqrt(n_iter_var) << std::endl;
General purpose block triangular preconditioner. By default this operates as an upper triangular prec...
void setup()
Setup the preconditioner.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
A class for compressed row matrices. This is a distributable object.
unsigned long nnz() const
Return the number of nonzero entries (the local nnz)
unsigned long nrow() const
Return the number of rows of the matrix.
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
A vector in the mathematical sense, initially developed for linear algebra type applications....
General purpose block tridiagonal preconditioner. By default SuperLUPreconditioner (or SuperLUDistPre...
void setup()
Setup the preconditioner.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
The block preconditioner form of GMRES. This version extracts the blocks from the global systems and ...
SpaceTimeNavierStokesSubsidiaryPreconditioner * navier_stokes_subsidiary_preconditioner_pt() const
Handle to the Navier-Stokes subsidiary block preconditioner DRAIG: Make sure the desired const-ness i...
double get_memory_usage_in_bytes()
Get the memory statistics.
Matrix vector product helper class - primarily a wrapper to Trilinos's Epetra matrix vector product m...
std::ostream *& stream_pt()
Access function for the stream pointer.
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
double get_memory_usage_in_bytes()
Get the memory statistics.
An interface to allow SuperLU to be used as an (exact) Preconditioner.
VectorMatrix is a generalised, STL-map-based, matrix based on a Vector of Vectors.
A slight extension to the standard template vector class so that we can include "graceful" array rang...
void start(const unsigned &i)
(Re-)start i-th timer
void split(const DoubleVector &in_vector, Vector< DoubleVector * > &out_vector_pt)
Split a DoubleVector into the out DoubleVectors. Let vec_A be the in Vector, and let vec_B and vec_C ...
void concatenate(const Vector< DoubleVector * > &in_vector_pt, DoubleVector &out_vector)
Concatenate DoubleVectors. Takes a Vector of DoubleVectors. If the out vector is built,...
void clean_up_memory()
Clean up function that deletes anything dynamically allocated in this namespace.
double timer()
returns the time in seconds after some point in past
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Nullstream oomph_nullstream
///////////////////////////////////////////////////////////////////////// ///////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...
void get_memory_usage_in_bytes(double *lu_factor_memory, double *total_memory)