31#include <oomph-lib-config.h>
62 template<
typename MATRIX>
71 throw OomphLibError(
"No matrix was stored -- cannot re-solve",
89 template<
typename MATRIX>
113 Matrix_can_be_deleted =
true;
126 oomph_info <<
"Time for setup of Jacobian [sec]: " << Jacobian_setup_time
134 this->build_distribution(
136 ->distribution_pt());
146 (!(*
result.distribution_pt() == *
this->distribution_pt())))
149 result.build(this->distribution_pt(), 0.0);
150 this->solve_helper(Matrix_pt, f,
result);
155 this->solve_helper(Matrix_pt, f,
result);
159 if (!Enable_resolve) clean_up_memory();
170 template<
typename MATRIX>
187 if (matrix_pt->
nrow() != matrix_pt->
ncol())
197 if (matrix_pt->
nrow() !=
rhs.nrow())
201 <<
"The matrix and the rhs vector must have the same number of rows.";
217 <<
"The matrix matrix_pt must have the same communicator as the "
219 <<
" rhs and result must have the same communicator";
229 if (
rhs.distribution_pt()->distributed())
233 <<
"The matrix (matrix_pt) is not distributable and therefore the rhs"
234 <<
" vector must not be distributed";
244 if (!(*
solution.distribution_pt() == *
rhs.distribution_pt()))
248 "setup; it must have the "
249 <<
"same distribution as the rhs vector.";
258 if (!
solution.distribution_pt()->built())
260 solution.build(this->distribution_pt(), 0.0);
270 unsigned nrow_local = this->nrow_local();
282 double residual_norm = residual.
norm();
295 if (Doc_convergence_history)
297 if (!Output_file_stream.is_open())
312 oomph_info <<
"BiCGStab converged immediately" << std::endl;
322 oomph_info <<
"Time for solve with BiCGStab [sec]: " << Solution_time
332 if (Setup_preconditioner_before_solve)
337 preconditioner_pt()->setup(matrix_pt);
345 oomph_info <<
"Time for setup of preconditioner [sec]: "
346 << Preconditioner_setup_time << std::endl;
354 oomph_info <<
"Setup of preconditioner is bypassed in resolve mode"
368 p_hat(this->distribution_pt(), 0.0),
v(this->distribution_pt(), 0.0),
369 z(this->distribution_pt(), 0.0),
t(this->distribution_pt(), 0.0),
370 s(this->distribution_pt(), 0.0);
381 oomph_info <<
"BiCGStab has broken down after " <<
iter <<
" iterations"
383 oomph_info <<
"Returning with current normalised residual of "
395 for (
unsigned i = 0;
i < nrow_local;
i++)
397 p[
i] = residual[
i] + beta * (
p[
i] - omega *
v[
i]);
402 preconditioner_pt()->preconditioner_solve(
p,
p_hat);
408 for (
unsigned i = 0;
i < nrow_local;
i++)
410 s[
i] = residual[
i] - alpha *
v[
i];
419 if (Doc_convergence_history)
421 if (!Output_file_stream.is_open())
428 Output_file_stream <<
double(
iter - 0.5) <<
" "
436 for (
unsigned i = 0;
i < nrow_local;
i++)
444 oomph_info <<
"BiCGStab converged. Normalised residual norm: "
460 oomph_info <<
"Time for solve with BiCGStab [sec]: " << Solution_time
468 preconditioner_pt()->preconditioner_solve(
s, z);
475 for (
unsigned i = 0;
i < nrow_local;
i++)
477 x[
i] += alpha *
p_hat[
i] + omega * z[
i];
478 residual[
i] =
s[
i] - omega *
t[
i];
488 if (Doc_convergence_history)
490 if (!Output_file_stream.is_open())
507 oomph_info <<
"BiCGStab converged. Normalised residual norm: "
524 oomph_info <<
"Time for solve with BiCGStab [sec]: " << Solution_time
535 oomph_info <<
"BiCGStab breakdown with omega=0.0. "
538 oomph_info <<
"Number of iterations so far: " <<
iter << std::endl;
551 oomph_info <<
"Time for solve with BiCGStab [sec]: " << Solution_time
563 oomph_info <<
"BiCGStab did not converge to required tolerance! "
565 oomph_info <<
"Returning with normalised residual norm: "
567 oomph_info <<
"after " << Max_iter <<
" iterations." << std::endl;
578 oomph_info <<
"Time for solve with BiCGStab [sec]: " << Solution_time
582 if (Throw_error_after_max_iter)
584 std::string
err =
"Solver failed to converge and you requested an error";
585 err +=
" on convergence failures.";
604 template<
typename MATRIX>
621 if (matrix_pt->
nrow() != matrix_pt->
ncol())
631 if (matrix_pt->
nrow() !=
rhs.nrow())
635 <<
"The matrix and the rhs vector must have the same number of rows.";
651 <<
"The matrix matrix_pt must have the same communicator as the "
653 <<
" rhs and result must have the same communicator";
663 if (
rhs.distribution_pt()->distributed())
667 <<
"The matrix (matrix_pt) is not distributable and therefore the rhs"
668 <<
" vector must not be distributed";
678 if (!(*
solution.distribution_pt() == *
rhs.distribution_pt()))
682 "setup; it must have the "
683 <<
"same distribution as the rhs vector.";
692 if (!
solution.distribution_pt()->built())
694 solution.build(this->distribution_pt(), 0.0);
704 unsigned nrow_local = this->nrow_local();
716 double residual_norm = residual.
norm();
725 if (Doc_convergence_history)
727 if (!Output_file_stream.is_open())
742 oomph_info <<
"CG converged immediately" << std::endl;
752 oomph_info <<
"Time for solve with CG [sec]: " << Solution_time
763 if (Setup_preconditioner_before_solve)
768 preconditioner_pt()->setup(matrix_pt);
776 oomph_info <<
"Time for setup of preconditioner [sec]: "
777 << Preconditioner_setup_time << std::endl;
785 oomph_info <<
"Setup of preconditioner is bypassed in resolve mode"
794 p(this->distribution_pt(), 0.0),
798 double alpha, beta,
rz;
805 preconditioner_pt()->preconditioner_solve(residual, z);
811 rz = residual.
dot(z);
816 rz = residual.
dot(z);
818 for (
unsigned i = 0;
i < nrow_local;
i++)
820 p[
i] = z[
i] + beta *
p[
i];
832 for (
unsigned i = 0;
i < nrow_local;
i++)
834 x[
i] += alpha *
p[
i];
840 residual_norm = residual.
norm();
848 if (Doc_convergence_history)
850 if (!Output_file_stream.is_open())
869 oomph_info <<
"CG did not converge to required tolerance! " << std::endl;
870 oomph_info <<
"Returning with normalised residual norm: "
880 oomph_info <<
"CG converged. Normalised residual norm: "
901 oomph_info <<
"Time for solve with CG [sec]: " << Solution_time
905 if ((
counter >= Max_iter) && (Throw_error_after_max_iter))
907 std::string
err =
"Solver failed to converge and you requested an error";
908 err +=
" on convergence failures.";
921 template<
typename MATRIX>
930 throw OomphLibError(
"No matrix was stored -- cannot re-solve",
949 template<
typename MATRIX>
968 Matrix_can_be_deleted =
true;
976 oomph_info <<
"Time for setup of Jacobian [sec]: " << Jacobian_setup_time
984 this->build_distribution(
986 ->distribution_pt());
995 if (!
result.distribution_pt()->built())
997 result.build(this->distribution_pt(), 0.0);
1001 if (!(*
result.distribution_pt() == *
this->distribution_pt()))
1004 result.build(this->distribution_pt(), 0.0);
1005 this->solve_helper(Matrix_pt, f,
result);
1010 this->solve_helper(Matrix_pt, f,
result);
1014 if (!Enable_resolve) clean_up_memory();
1028 template<
typename MATRIX>
1032 const double&
n_dof)
1062 <<
"the linear system";
1068 if (
rhs.distribution_pt()->distributed())
1080 if (!(*
rhs.distribution_pt() == *
solution.distribution_pt()))
1084 <<
"must be the same as the rhs distribution";
1103 template<
typename MATRIX>
1108 Use_as_smoother =
false;
1126 this->build_distribution(
dist);
1139 Matrix_can_be_deleted =
true;
1148 oomph_info <<
"Time for setup of Jacobian [sec]: " << Jacobian_setup_time
1153 this->solve_helper(Matrix_pt, f,
result);
1156 if (!Enable_resolve) clean_up_memory();
1163 template<
typename MATRIX>
1185 if (!
solution.distribution_pt()->built())
1188 solution.build(this->distribution_pt(), 0.0);
1197 if (!Use_as_smoother)
1226 if (!Use_as_smoother)
1242 if (Doc_convergence_history)
1245 if (!Output_file_stream.is_open())
1254 Output_file_stream << Iterations <<
" " <<
norm_res << std::endl;
1263 for (
unsigned i = 0;
i <
n_dof;
i++)
1266 for (
unsigned j = 0;
j <
i;
j++)
1268 dummy -= (*(matrix_pt))(
i,
j) * x[
j];
1270 for (
unsigned j = (
i + 1);
j <
n_dof;
j++)
1272 dummy -= (*(matrix_pt))(
i,
j) * x[
j];
1274 x[
i] =
dummy / (*(matrix_pt))(
i,
i);
1281 if (!Use_as_smoother)
1292 if (Doc_convergence_history)
1294 if (!Output_file_stream.is_open())
1300 Output_file_stream << Iterations <<
" " <<
norm_res << std::endl;
1314 if (!Use_as_smoother)
1320 <<
"\nNumber of iterations to convergence: " << Iterations
1334 oomph_info <<
"Time for solve with GS [sec]: " << Solution_time
1340 if ((Iterations > Max_iter - 1) && (Throw_error_after_max_iter))
1342 std::string error_message =
1343 "Solver failed to converge and you requested ";
1344 error_message +=
"an error on convergence failures.";
1367 Use_as_smoother =
false;
1385 this->build_distribution(
dist);
1391 Matrix_pt->
build(this->distribution_pt());
1397 f.
build(this->distribution_pt(), 0.0);
1407 setup_helper(Matrix_pt);
1410 Matrix_can_be_deleted =
true;
1416 oomph_info <<
"Time for setup of Jacobian [sec]: " << Jacobian_setup_time
1421 solve_helper(Matrix_pt, f,
result);
1424 if (!Enable_resolve) clean_up_memory();
1442 Matrix_can_be_deleted =
false;
1453 Index_of_diagonal_entries = Matrix_pt->get_index_of_diagonal_entries();
1501 if (!
solution.distribution_pt()->built())
1503 solution.build(this->distribution_pt(), 0.0);
1512 if (!Use_as_smoother)
1541 if (!Use_as_smoother)
1557 if (Doc_convergence_history)
1559 if (!Output_file_stream.is_open())
1565 Output_file_stream << Iterations <<
" " <<
norm_res << std::endl;
1594 for (
unsigned i = 0;
i <
n_dof;
i++)
1597 unsigned diag_index = Index_of_diagonal_entries[
i];
1601 std::string
err_strng =
"Gauss-Seidel cannot operate on a matrix with ";
1618 for (
unsigned i = 0;
i <
n_dof;
i++)
1621 unsigned diag_index = Index_of_diagonal_entries[
i];
1634 unsigned column_index = 0;
1684 for (
unsigned i = 0;
i <
n_dof - 1;
i++)
1695 unsigned column_index = 0;
1704 temp_vec[
i] += (*(value_pt +
j)) * x[column_index];
1724 for (
unsigned i = 0;
i <
n_dof;
i++)
1727 unsigned diag_index = Index_of_diagonal_entries[
i];
1738 unsigned column_index = 0;
1775 if (!Use_as_smoother)
1786 if (Doc_convergence_history)
1788 if (!Output_file_stream.is_open())
1808 if (!Use_as_smoother)
1814 <<
"\nNumber of iterations to convergence: " << Iterations
1830 oomph_info <<
"Time for solve with Gauss-Seidel [sec]: " << Solution_time
1836 if ((Iterations > Max_iter - 1) && (Throw_error_after_max_iter))
1838 std::string error_message =
1839 "Solver failed to converge and you requested ";
1840 error_message +=
"an error on convergence failures.";
1857 template<
typename MATRIX>
1863 Use_as_smoother =
false;
1881 this->build_distribution(
dist);
1894 extract_diagonal_entries(Matrix_pt);
1897 Matrix_can_be_deleted =
true;
1906 oomph_info <<
"Time for setup of Jacobian [sec]: " << Jacobian_setup_time
1911 solve_helper(Matrix_pt, f,
result);
1914 if (!Enable_resolve) clean_up_memory();
1921 template<
typename MATRIX>
1943 if (!
solution.distribution_pt()->built())
1947 solution.build(this->distribution_pt(), 0.0);
1956 if (!Use_as_smoother)
1974 for (
unsigned i = 0;
i <
n_dof;
i++)
1996 if (!Use_as_smoother)
2012 if (Doc_convergence_history)
2014 if (!Output_file_stream.is_open())
2020 Output_file_stream << Iterations <<
" " <<
norm_res << std::endl;
2053 if (!Use_as_smoother)
2063 if (Doc_convergence_history)
2065 if (!Output_file_stream.is_open())
2071 Output_file_stream << Iterations <<
" " <<
norm_res << std::endl;
2085 if (!Use_as_smoother)
2091 <<
"\nNumber of iterations to convergence: " << Iterations
2105 oomph_info <<
"Time for solve with damped Jacobi [sec]: " << Solution_time
2111 if ((Iterations > Max_iter - 1) && (Throw_error_after_max_iter))
2113 std::string error_message =
2114 "Solver failed to converge and you requested ";
2115 error_message +=
"an error on convergence failures.";
2132 template<
typename MATRIX>
2141 throw OomphLibError(
"No matrix was stored -- cannot re-solve",
2160 template<
typename MATRIX>
2177 this->build_distribution(
dist);
2188 this->distribution_pt());
2189 f.
build(this->distribution_pt(), 0.0);
2195 Matrix_can_be_deleted =
true;
2203 oomph_info <<
"Time for setup of Jacobian [sec]: " << Jacobian_setup_time
2209 if (Compute_gradient)
2212 Matrix_pt->multiply_transpose(f, Gradient_for_glob_conv_newton_solve);
2214 Gradient_has_been_computed =
true;
2222 (!(*
result.distribution_pt() == *
this->distribution_pt())))
2225 result.build(this->distribution_pt(), 0.0);
2226 this->solve_helper(Matrix_pt, f,
result);
2232 this->solve_helper(Matrix_pt, f,
result);
2236 if (!Enable_resolve) clean_up_memory();
2249 template<
typename MATRIX>
2285 "RHS does not have the same dimension as the linear system",
2290 if (
rhs.distribution_pt()->distributed())
2302 if (!(*
rhs.distribution_pt() == *
solution.distribution_pt()))
2306 "must be the same as the "
2307 <<
"rhs distribution";
2316 Preconditioner_application_time = 0.0;
2321 solution.build(this->distribution_pt(), 0.0);
2339 if (!Iteration_restart)
2354 if (Setup_preconditioner_before_solve)
2360 preconditioner_pt()->setup(matrix_pt);
2368 oomph_info <<
"Time for setup of preconditioner [sec]: "
2369 << Preconditioner_setup_time << std::endl;
2377 oomph_info <<
"Setup of preconditioner is bypassed in resolve mode"
2384 if (Preconditioner_LHS)
2390 preconditioner_pt()->preconditioner_solve(
rhs,
r);
2393 Preconditioner_application_time +=
2403 double*
r_pt =
r.values_pt();
2404 for (
unsigned i = 0;
i <
n_dof;
i++)
2411 double beta =
normb;
2419 if (Doc_convergence_history)
2421 if (!Output_file_stream.is_open())
2427 Output_file_stream << 0 <<
" " <<
resid << std::endl;
2432 if (
resid <= Tolerance)
2436 oomph_info <<
"GMRES converged immediately. Normalised residual norm: "
2437 <<
resid << std::endl;
2446 oomph_info <<
"Time for all preconditioner applications [sec]: "
2447 << Preconditioner_application_time
2448 <<
"\n\nTime for solve with GMRES [sec]: " << Solution_time
2460 v.resize(Restart + 1);
2464 while (
iter <= Max_iter)
2467 v[0].build(this->distribution_pt(), 0.0);
2468 double*
v0_pt =
v[0].values_pt();
2469 for (
unsigned i = 0;
i <
n_dof;
i++)
2490 if (Preconditioner_LHS)
2499 preconditioner_pt()->preconditioner_solve(
temp, w);
2502 Preconditioner_application_time +=
2514 Preconditioner_application_time +=
2528 double*
vk_pt =
v[
k].values_pt();
2529 for (
unsigned i = 0;
i <
n_dof;
i++)
2535 for (
unsigned i = 0;
i <
n_dof;
i++)
2544 for (
unsigned i = 0;
i <
n_dof;
i++)
2555 for (
unsigned i = 0;
i <
n_dof;
i++)
2563 apply_plane_rotation(
2587 if (Doc_convergence_history)
2589 if (!Output_file_stream.is_open())
2595 Output_file_stream <<
iter <<
" " <<
resid << std::endl;
2600 if (
resid < Tolerance)
2609 oomph_info <<
"GMRES converged (1). Normalised residual norm: "
2610 <<
resid << std::endl;
2625 oomph_info <<
"Time for all preconditioner applications [sec]: "
2626 << Preconditioner_application_time
2627 <<
"\n\nTime for solve with GMRES [sec]: "
2628 << Solution_time << std::endl;
2643 for (
unsigned i = 0;
i <
n_dof;
i++)
2648 if (Preconditioner_LHS)
2653 preconditioner_pt()->preconditioner_solve(
temp,
r);
2656 Preconditioner_application_time +=
2663 r_pt =
r.values_pt();
2664 for (
unsigned i = 0;
i <
n_dof;
i++)
2672 if (
resid < Tolerance)
2677 oomph_info <<
"GMRES converged (2). Normalised residual norm: "
2678 <<
resid << std::endl;
2693 oomph_info <<
"Time for all preconditioner applications [sec]: "
2694 << Preconditioner_application_time
2695 <<
"\n\nTime for solve with GMRES [sec]: "
2696 << Solution_time << std::endl;
2716 oomph_info <<
"GMRES did not converge to required tolerance! " << std::endl;
2719 oomph_info <<
"after " << Max_iter <<
" iterations." << std::endl;
2723 if (Throw_error_after_max_iter)
2725 std::string
err =
"Solver failed to converge and you requested an error";
2726 err +=
" on convergence failures.";
2800 if ((!(*
result.distribution_pt() == *
this->distribution_pt())) &&
2840 throw OomphLibError(
"No matrix was stored -- cannot re-solve",
2891 <<
"LHS vector has " <<
rhs.nrow()
2892 <<
" rows but\nthey "
2893 <<
"should both have " <<
n_dof <<
" rows!"
2927 if (
rhs.distribution_pt()->distributed())
2939 if (!(*
rhs.distribution_pt() == *
lhs.distribution_pt()))
2943 "must be the same as the "
2944 <<
"rhs distribution";
2962 lhs.initialise(0.0);
3008 oomph_info <<
"Time for setup of preconditioner [sec]: "
3018 oomph_info <<
"Setup of preconditioner is bypassed in resolve mode"
3044 throw OomphLibError(
"Bordering vectors have not been created!",
3052 throw OomphLibError(
"Bordering vectors do not have the right size!",
3082 for (
unsigned i = 0;
i <
n_dof;
i++)
3121 double beta =
normb;
3152 oomph_info <<
"AugmentedProblemGMRES converged immediately. Normalised "
3153 <<
"residual norm: " <<
resid << std::endl;
3163 <<
"Time for all preconditioner applications [sec]: "
3165 <<
"\nTotal time for solve with AugmentedProblemGMRES [sec]: "
3259 double*
vk_pt =
v[
k].values_pt();
3330 for (
unsigned i = 0;
i <
n_dof;
i++)
3343 oomph_info <<
"\nAugmentedProblemGMRES converged (1). Normalised "
3344 <<
"residual norm: " <<
resid
3345 <<
"\nNumber of iterations "
3346 <<
"to convergence: " <<
iter <<
"\n"
3360 <<
"Time for all preconditioner applications [sec]: "
3362 <<
"\nTotal time for solve with AugmentedProblemGMRES [sec]: "
3383 <<
") almost zero at iteration "
3385 <<
"is only " <<
resid <<
" which does "
3386 <<
"not meet the tolerance (" <<
Tolerance
3387 <<
")!" << std::endl;
3411 for (
unsigned i = 0;
i <
n_dof;
i++)
3446 oomph_info <<
"\nAugmentedProblemGMRES converged (2). Normalised "
3447 <<
"residual norm: " <<
resid <<
"\nNumber of iterations "
3448 <<
"to convergence: " <<
iter <<
"\n"
3453 for (
unsigned i = 0;
i <
n_dof;
i++)
3472 <<
"Time for all preconditioner applications [sec]: "
3474 <<
"\nTotal time for solve with AugmentedProblemGMRES [sec]: "
3492 for (
unsigned i = 0;
i <
n_dof;
i++)
3502 oomph_info <<
"\nAugmentedProblemGMRES did not converge to required "
3503 <<
"tolerance!\nReturning with normalised residual norm: "
void apply_plane_rotation(double &dx, double &dy, double &cs, double &sn)
Helper function: Apply plane rotation. This is done using the update:
bool Resolving
Boolean flag to indicate if the solve is done in re-solve mode, bypassing setup of matrix and precond...
DoubleVector * C_pt
Pointer to the row vector in the bordered system.
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
General interface to solve function.
void resolve(const DoubleVector &rhs, DoubleVector &result)
Re-solve the system defined by the last assembled Jacobian and the rhs vector specified here....
CRDoubleMatrix * Matrix_pt
Pointer to matrix.
bool Iteration_restart
boolean indicating if iteration restarting is used
unsigned Restart
The number of iterations before the iteration proceedure is restarted if iteration restart is used.
void apply_schur_complement_preconditioner(const DoubleVector &rhs, DoubleVector &soln)
Apply the block-diagonal Schur complement preconditioner to compute the LHS which has size N+1 (the a...
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
void generate_plane_rotation(double &dx, double &dy, double &cs, double &sn)
Helper function: Generate a plane rotation. This is done by finding the values of (i....
double Schur_complement_scalar
The scalar component of the Schur complement preconditioner.
void augmented_matrix_multiply(CRDoubleMatrix *matrix_pt, const DoubleVector &x, DoubleVector &soln)
Multiply the vector x by the augmented system matrix.
unsigned Iterations
Number of iterations taken.
bool Matrix_can_be_deleted
Boolean flag to indicate if the matrix pointed to be Matrix_pt can be deleted.
void clean_up_memory()
Cleanup data that's stored for resolve (if any has been stored)
DoubleVector * B_pt
Pointer to the column vector in the bordered system.
bool Preconditioner_LHS
boolean indicating use of left hand preconditioning (if true) or right hand preconditioning (if false...
void update(const unsigned &k, const Vector< Vector< double > > &H, const Vector< double > &s, const Vector< DoubleVector > &v, DoubleVector &x)
Helper function to update the result vector using the result, x=x_0+V_m*y.
void resolve(const DoubleVector &rhs, DoubleVector &result)
Re-solve the system defined by the last assembled Jacobian and the rhs vector specified here....
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
General interface to solve function.
void resolve(const DoubleVector &rhs, DoubleVector &result)
Re-solve the system defined by the last assembled Jacobian and the rhs vector specified here....
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
General interface to solve function.
A class for compressed row matrices. This is a distributable object.
void sort_entries()
Sorts the entries associated with each row of the matrix in the column index vector and the value vec...
void build(const LinearAlgebraDistribution *distribution_pt, const unsigned &ncol, const Vector< double > &value, const Vector< int > &column_index, const Vector< int > &row_start)
build method: vector of values, vector of column indices, vector of row starts and number of rows and...
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
This is where the actual work is done – different implementations for different matrix types.
void solve(Problem *const &problem_pt, DoubleVector &result)
Use damped Jacobi iteration as an IterativeLinearSolver: This obtains the Jacobian matrix J and the r...
Base class for any linear algebra object that is distributable. Just contains storage for the LinearA...
bool distributed() const
distribution is serial or distributed
unsigned nrow() const
access function to the number of global rows.
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
setup the distribution of this distributable linear algebra object
Abstract base class for matrices of doubles – adds abstract interfaces for solving,...
virtual unsigned long ncol() const =0
Return the number of columns of the matrix.
virtual void multiply(const DoubleVector &x, DoubleVector &soln) const =0
Multiply the matrix by the vector x: soln=Ax.
virtual void residual(const DoubleVector &x, const DoubleVector &b, DoubleVector &residual_)
Find the residual, i.e. r=b-Ax the residual.
virtual unsigned long nrow() const =0
Return the number of rows of the matrix.
A vector in the mathematical sense, initially developed for linear algebra type applications....
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
double norm() const
compute the 2 norm of this vector
double dot(const DoubleVector &vec) const
compute the dot product of this vector with the vector vec.
double * values_pt()
access function to the underlying values
void resolve(const DoubleVector &rhs, DoubleVector &result)
Re-solve the system defined by the last assembled Jacobian and the rhs vector specified here....
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
General interface to solve function.
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
General interface to solve function.
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
double Tolerance
Convergence tolerance.
bool Throw_error_after_max_iter
Should we throw an error instead of just returning when we hit the max iterations?
double Preconditioner_setup_time
Preconditioner setup time.
double Jacobian_setup_time
Jacobian setup time.
static IdentityPreconditioner Default_preconditioner
Default preconditioner: The base class for preconditioners is a fully functional (if trivial!...
unsigned Max_iter
Maximum number of iterations.
double Solution_time
linear solver solution time
Preconditioner *& preconditioner_pt()
Access function to preconditioner.
std::ofstream Output_file_stream
Output file stream for convergence history.
bool Doc_convergence_history
Flag indicating if the convergence history is to be documented.
bool Setup_preconditioner_before_solve
indicates whether the preconditioner should be setup before solve. Default = true;
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
bool Doc_time
Boolean flag that indicates whether the time taken.
bool Enable_resolve
Boolean that indicates whether the matrix (or its factors, in the case of direct solver) should be st...
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
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....
virtual void setup(DoubleMatrixBase *matrix_pt)
Setup the preconditioner: store the matrix pointer and the communicator pointer then call preconditio...
virtual void preconditioner_solve(const DoubleVector &r, DoubleVector &z)=0
Apply the preconditioner. Pure virtual generic interface function. This method should apply the preco...
////////////////////////////////////////////////////////////////// //////////////////////////////////...
unsigned long ndof() const
Return the number of dofs.
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
virtual void get_jacobian(DoubleVector &residuals, DenseDoubleMatrix &jacobian)
Return the fully-assembled Jacobian and residuals for the problem Interface for the case when the Jac...
void check_validity_of_solve_helper_inputs(MATRIX *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution, const double &n_dof)
Self-test to check that all the dimensions of the inputs to solve helper are consistent and everythin...
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
TAdvectionDiffusionReactionElement()
Constructor: Call constructors for TElement and AdvectionDiffusionReaction equations.
double timer()
returns the time in seconds after some point in past
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...