oomph::DenseLU Class Reference

#include <linear_solver.h>

+ Inheritance diagram for oomph::DenseLU:

Public Member Functions

 DenseLU ()
 Constructor, initialise storage. More...
 
 DenseLU (const DenseLU &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const DenseLU &)=delete
 Broken assignment operator. More...
 
 ~DenseLU ()
 Destructor, clean up the stored LU factors. More...
 
void solve (Problem *const &problem_pt, DoubleVector &result)
 
void solve (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
void solve (DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
 
double jacobian_setup_time () const
 
virtual double linear_solver_solution_time () const
 
- Public Member Functions inherited from oomph::LinearSolver
 LinearSolver ()
 Empty constructor, initialise the member data. More...
 
 LinearSolver (const LinearSolver &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const LinearSolver &)=delete
 Broken assignment operator. More...
 
virtual ~LinearSolver ()
 Empty virtual destructor. More...
 
void enable_doc_time ()
 Enable documentation of solve times. More...
 
void disable_doc_time ()
 Disable documentation of solve times. More...
 
bool is_doc_time_enabled () const
 Is documentation of solve times enabled? More...
 
bool is_resolve_enabled () const
 Boolean flag indicating if resolves are enabled. More...
 
virtual void enable_resolve ()
 
virtual void disable_resolve ()
 
virtual void solve_transpose (Problem *const &problem_pt, DoubleVector &result)
 
virtual void solve_transpose (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
virtual void solve_transpose (DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
 
virtual void resolve (const DoubleVector &rhs, DoubleVector &result)
 
virtual void resolve_transpose (const DoubleVector &rhs, DoubleVector &result)
 
virtual void enable_computation_of_gradient ()
 
void disable_computation_of_gradient ()
 
void reset_gradient ()
 
void get_gradient (DoubleVector &gradient)
 function to access the gradient, provided it has been computed More...
 
- Public Member Functions inherited from oomph::DistributableLinearAlgebraObject
 DistributableLinearAlgebraObject ()
 Default constructor - create a distribution. More...
 
 DistributableLinearAlgebraObject (const DistributableLinearAlgebraObject &matrix)=delete
 Broken copy constructor. More...
 
void operator= (const DistributableLinearAlgebraObject &)=delete
 Broken assignment operator. More...
 
virtual ~DistributableLinearAlgebraObject ()
 Destructor. More...
 
LinearAlgebraDistributiondistribution_pt () const
 access to the LinearAlgebraDistribution More...
 
unsigned nrow () const
 access function to the number of global rows. More...
 
unsigned nrow_local () const
 access function for the num of local rows on this processor. More...
 
unsigned nrow_local (const unsigned &p) const
 access function for the num of local rows on this processor. More...
 
unsigned first_row () const
 access function for the first row on this processor More...
 
unsigned first_row (const unsigned &p) const
 access function for the first row on this processor More...
 
bool distributed () const
 distribution is serial or distributed More...
 
bool distribution_built () const
 
void build_distribution (const LinearAlgebraDistribution *const dist_pt)
 
void build_distribution (const LinearAlgebraDistribution &dist)
 

Protected Member Functions

void factorise (DoubleMatrixBase *const &matrix_pt)
 Perform the LU decomposition of the matrix. More...
 
void backsub (const DoubleVector &rhs, DoubleVector &result)
 Do the backsubstitution step to solve the system LU result = rhs. More...
 
void backsub (const Vector< double > &rhs, Vector< double > &result)
 perform back substitution using Vector<double> More...
 
void clean_up_memory ()
 Clean up the stored LU factors. More...
 
- Protected Member Functions inherited from oomph::DistributableLinearAlgebraObject
void clear_distribution ()
 

Protected Attributes

double Jacobian_setup_time
 Jacobian setup time. More...
 
double Solution_time
 Solution time. More...
 
int Sign_of_determinant_of_matrix
 
- Protected Attributes inherited from oomph::LinearSolver
bool Enable_resolve
 
bool Doc_time
 Boolean flag that indicates whether the time taken. More...
 
bool Compute_gradient
 
bool Gradient_has_been_computed
 flag that indicates whether the gradient was computed or not More...
 
DoubleVector Gradient_for_glob_conv_newton_solve
 

Private Attributes

long * Index
 Pointer to storage for the index of permutations in the LU solve. More...
 
doubleLU_factors
 Pointer to storage for the LU decomposition. More...
 

Friends

class DenseDoubleMatrix
 The DenseDoubleMatrix class is a friend. More...
 

Detailed Description

Dense LU decomposition-based solve of full assembled linear system. VERY inefficient but useful to illustrate the principle. Only suitable for use with Serial matrices and vectors. This solver will only work with non-distributed matrices and vectors (note: DenseDoubleMatrix is not distributable)

Constructor & Destructor Documentation

◆ DenseLU() [1/2]

oomph::DenseLU::DenseLU ( )
inline

Constructor, initialise storage.

341  : Jacobian_setup_time(0.0),
342  Solution_time(0.0),
344  Index(0),
345  LU_factors(0)
346  {
347  // Shut up!
348  Doc_time = false;
349  }
double Jacobian_setup_time
Jacobian setup time.
Definition: linear_solver.h:408
long * Index
Pointer to storage for the index of permutations in the LU solve.
Definition: linear_solver.h:419
double * LU_factors
Pointer to storage for the LU decomposition.
Definition: linear_solver.h:422
double Solution_time
Solution time.
Definition: linear_solver.h:411
int Sign_of_determinant_of_matrix
Definition: linear_solver.h:415
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77

References oomph::LinearSolver::Doc_time.

◆ DenseLU() [2/2]

oomph::DenseLU::DenseLU ( const DenseLU dummy)
delete

Broken copy constructor.

◆ ~DenseLU()

oomph::DenseLU::~DenseLU ( )
inline

Destructor, clean up the stored LU factors.

359  {
360  clean_up_memory();
361  }
void clean_up_memory()
Clean up the stored LU factors.
Definition: linear_solver.cc:106

References clean_up_memory().

Member Function Documentation

◆ backsub() [1/2]

void oomph::DenseLU::backsub ( const DoubleVector rhs,
DoubleVector result 
)
protected

Do the backsubstitution step to solve the system LU result = rhs.

Do the backsubstitution for the DenseLU solver. WARNING: this class does not perform any PARANOID checks on the vectors - these are all performed in the solve(...) method.

321  {
322  // Get pointers to first entries
323  const double* rhs_pt = rhs.values_pt();
324  double* result_pt = result.values_pt();
325 
326  // Copy the rhs vector into the result vector
327  const unsigned long n = rhs.nrow();
328  for (unsigned long i = 0; i < n; ++i)
329  {
330  result_pt[i] = rhs_pt[i];
331  }
332 
333  // Loop over all rows for forward substition
334  unsigned long k = 0;
335  for (unsigned long i = 0; i < n; i++)
336  {
337  unsigned long ip = Index[i];
338  double sum = result_pt[ip];
339  result_pt[ip] = result_pt[i];
340  if (k != 0)
341  {
342  for (unsigned long j = k - 1; j < i; j++)
343  {
344  sum -= LU_factors[n * i + j] * result_pt[j];
345  }
346  }
347  else if (sum != 0.0)
348  {
349  k = i + 1;
350  }
351  result_pt[i] = sum;
352  }
353 
354  // Now do the back substitution
355  for (long i = long(n) - 1; i >= 0; i--)
356  {
357  double sum = result_pt[i];
358  for (long j = i + 1; j < long(n); j++)
359  {
360  sum -= LU_factors[n * i + j] * result_pt[j];
361  }
362  result_pt[i] = sum / LU_factors[n * i + i];
363  }
364  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
char char char int int * k
Definition: level2_impl.h:374
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References i, Index, j, k, LU_factors, n, oomph::DistributableLinearAlgebraObject::nrow(), and oomph::DoubleVector::values_pt().

Referenced by solve().

◆ backsub() [2/2]

void oomph::DenseLU::backsub ( const Vector< double > &  rhs,
Vector< double > &  result 
)
protected

perform back substitution using Vector<double>

Do the backsubstitution for the DenseLU solver. WARNING: this class does not perform any PARANOID checks on the vectors - these are all performed in the solve(...) method. So, if you call backsub directly, you have been warned...

373  {
374  // Copy the rhs vector into the result vector
375  const unsigned long n = rhs.size();
376  for (unsigned long i = 0; i < n; ++i)
377  {
378  result[i] = rhs[i];
379  }
380 
381  // Loop over all rows for forward substition
382  unsigned long k = 0;
383  for (unsigned long i = 0; i < n; i++)
384  {
385  unsigned long ip = Index[i];
386  double sum = result[ip];
387  result[ip] = result[i];
388  if (k != 0)
389  {
390  for (unsigned long j = k - 1; j < i; j++)
391  {
392  sum -= LU_factors[n * i + j] * result[j];
393  }
394  }
395  else if (sum != 0.0)
396  {
397  k = i + 1;
398  }
399  result[i] = sum;
400  }
401 
402  // Now do the back substitution
403  for (long i = long(n) - 1; i >= 0; i--)
404  {
405  double sum = result[i];
406  for (long j = i + 1; j < long(n); j++)
407  {
408  sum -= LU_factors[n * i + j] * result[j];
409  }
410  result[i] = sum / LU_factors[n * i + i];
411  }
412  }

References i, Index, j, k, LU_factors, and n.

◆ clean_up_memory()

void oomph::DenseLU::clean_up_memory ( )
protectedvirtual

Clean up the stored LU factors.

Delete the storage that has been allocated for the LU factors, if the matrix data is not itself being overwritten.

Reimplemented from oomph::LinearSolver.

107  {
108  // delete the Distribution_pt
109  this->clear_distribution();
110 
111  // Clean up the LU factor storage, if it has been allocated
112  // N.B. we don't need to check the index storage as well.
113  if (LU_factors != 0)
114  {
115  // Delete the pointer to the LU factors
116  delete[] LU_factors;
117  // Null out the vector
118  LU_factors = 0;
119  // Delete the pointer to the Index
120  delete[] Index;
121  // Null out
122  Index = 0;
123  }
124  }
void clear_distribution()
Definition: linear_algebra_distribution.h:522

References oomph::DistributableLinearAlgebraObject::clear_distribution(), Index, and LU_factors.

Referenced by factorise(), solve(), and ~DenseLU().

◆ factorise()

void oomph::DenseLU::factorise ( DoubleMatrixBase *const &  matrix_pt)
protected

Perform the LU decomposition of the matrix.

LU decompose the matrix. WARNING: this class does not perform any PARANOID checks on the vectors - these are all performed in the solve(...) method.

132  {
133  // Set the number of unknowns
134  const unsigned long n = matrix_pt->nrow();
135 
136  // Small constant
137  const double small_number = 1.0e-20;
138 
139  // Vector scaling stores the implicit scaling of each row
140  Vector<double> scaling(n);
141 
142  // Integer to store the sign that must multiply the determinant as
143  // a consequence of the row/column interchanges
144  int signature = 1;
145 
146  // Loop over rows to get implicit scaling information
147  for (unsigned long i = 0; i < n; i++)
148  {
149  double largest_entry = 0.0;
150  for (unsigned long j = 0; j < n; j++)
151  {
152  double tmp = std::fabs((*matrix_pt)(i, j));
153  if (tmp > largest_entry) largest_entry = tmp;
154  }
155  if (largest_entry == 0.0)
156  {
157  throw OomphLibError(
159  }
160  // Save the scaling
161  scaling[i] = 1.0 / largest_entry;
162  }
163 
164  // Firsly, we shall delete any previous LU storage.
165  // If the user calls this function twice without changing the matrix
166  // then it is their own inefficiency, not ours (this time).
167  clean_up_memory();
168 
169  // Allocate storage for the LU factors, the index and store
170  // the number of unknowns
171  LU_factors = new double[n * n];
172  Index = new long[n];
173 
174  // Now we know that memory has been allocated, copy over
175  // the matrix values
176  unsigned count = 0;
177  for (unsigned long i = 0; i < n; i++)
178  {
179  for (unsigned long j = 0; j < n; j++)
180  {
181  LU_factors[count] = (*matrix_pt)(i, j);
182  ++count;
183  }
184  }
185 
186  // Loop over columns
187  for (unsigned long j = 0; j < n; j++)
188  {
189  // Initialise imax
190  unsigned long imax = 0;
191 
192  for (unsigned long i = 0; i < j; i++)
193  {
194  double sum = LU_factors[n * i + j];
195  for (unsigned long k = 0; k < i; k++)
196  {
197  sum -= LU_factors[n * i + k] * LU_factors[n * k + j];
198  }
199  LU_factors[n * i + j] = sum;
200  }
201 
202  // Initialise search for largest pivot element
203  double largest_entry = 0.0;
204  for (unsigned long i = j; i < n; i++)
205  {
206  double sum = LU_factors[n * i + j];
207  for (unsigned long k = 0; k < j; k++)
208  {
209  sum -= LU_factors[n * i + k] * LU_factors[n * k + j];
210  }
211  LU_factors[n * i + j] = sum;
212  // Set temporary
213  double tmp = scaling[i] * std::fabs(sum);
214  if (tmp >= largest_entry)
215  {
216  largest_entry = tmp;
217  imax = i;
218  }
219  }
220 
221  // Test to see if we need to interchange rows
222  if (j != imax)
223  {
224  for (unsigned long k = 0; k < n; k++)
225  {
226  double tmp = LU_factors[n * imax + k];
227  LU_factors[n * imax + k] = LU_factors[n * j + k];
228  LU_factors[n * j + k] = tmp;
229  }
230  // Change the parity of signature
231  signature = -signature;
232 
233  // Interchange scale factor
234  scaling[imax] = scaling[j];
235  }
236 
237  // Set the index
238  Index[j] = imax;
239  if (LU_factors[n * j + j] == 0.0)
240  {
241  LU_factors[n * j + j] = small_number;
242  }
243  // Divide by pivot element
244  if (j != n - 1)
245  {
246  double tmp = 1.0 / LU_factors[n * j + j];
247  for (unsigned long i = j + 1; i < n; i++)
248  {
249  LU_factors[n * i + j] *= tmp;
250  }
251  }
252 
253  } // End of loop over columns
254 
255 
256  // Now multiply all the diagonal terms together to get the determinant
257  // Note that we need to use the mantissa, exponent formulation to
258  // avoid underflow errors
259  double determinant_mantissa = 1.0;
260  int determinant_exponent = 0, iexp;
261  for (unsigned i = 0; i < n; i++)
262  {
263  // Multiply by the next diagonal entry's mantissa
264  // and return the exponent
265  determinant_mantissa *= frexp(LU_factors[n * i + i], &iexp);
266 
267  // Add the new exponent to the current exponent
268  determinant_exponent += iexp;
269 
270  // normalise
271  determinant_mantissa = frexp(determinant_mantissa, &iexp);
272  determinant_exponent += iexp;
273  }
274 
275  // If paranoid issue a warning that the matrix is near singular
276  // #ifdef PARANOID
277  // int tiny_exponent = -60;
278  // if(determinant_exponent < tiny_exponent)
279  // {
280  // std::ostringstream warning_stream;
281  // warning_stream << "The determinant of the matrix is very close to
282  // zero.\n"
283  // << "It is " << determinant_mantissa << " x 2^"
284  // << determinant_exponent << "\n";
285  // warning_stream << "The results will depend on the exact details of
286  // the\n"
287  // << "floating point implementation ... just to let you
288  // know\n";
289  // OomphLibWarning(warning_stream.str(),
290  // "DenseLU::factorise()",
291  // OOMPH_EXCEPTION_LOCATION);
292  // }
293  // #endif
294 
295  // Integer to store the sign of the determinant
296  int sign = 0;
297 
298  // Find the sign of the determinant
299  if (determinant_mantissa > 0.0)
300  {
301  sign = 1;
302  }
303  if (determinant_mantissa < 0.0)
304  {
305  sign = -1;
306  }
307 
308  // Multiply the sign by the signature
309  sign *= signature;
310 
311  // Return the sign of the determinant
313  }
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
T sign(T x)
Definition: cxx11_tensor_builtins_sycl.cpp:172
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References clean_up_memory(), boost::multiprecision::fabs(), i, Index, j, k, LU_factors, n, oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, SYCL::sign(), Sign_of_determinant_of_matrix, and tmp.

Referenced by solve().

◆ jacobian_setup_time()

double oomph::DenseLU::jacobian_setup_time ( ) const
inlinevirtual

returns the time taken to assemble the jacobian matrix and residual vector

Reimplemented from oomph::LinearSolver.

383  {
384  return Jacobian_setup_time;
385  }

References Jacobian_setup_time.

◆ linear_solver_solution_time()

virtual double oomph::DenseLU::linear_solver_solution_time ( ) const
inlinevirtual

return the time taken to solve the linear system (needs to be overloaded for each linear solver)

Reimplemented from oomph::LinearSolver.

390  {
391  return Solution_time;
392  }

References Solution_time.

◆ operator=()

void oomph::DenseLU::operator= ( const DenseLU )
delete

Broken assignment operator.

◆ solve() [1/3]

void oomph::DenseLU::solve ( DoubleMatrixBase *const &  matrix_pt,
const DoubleVector rhs,
DoubleVector result 
)
virtual

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system.

Reimplemented from oomph::LinearSolver.

Reimplemented in oomph::FD_LU.

422  {
423 #ifdef PARANOID
424  // check that the rhs vector is not distributed
425  if (rhs.distribution_pt()->distributed())
426  {
427  std::ostringstream error_message_stream;
428  error_message_stream
429  << "The vectors rhs and result must not be distributed";
430  throw OomphLibError(error_message_stream.str(),
433  }
434 
435  // check that the matrix is square
436  if (matrix_pt->nrow() != matrix_pt->ncol())
437  {
438  std::ostringstream error_message_stream;
439  error_message_stream << "The matrix at matrix_pt must be square.";
440  throw OomphLibError(error_message_stream.str(),
443  }
444  // check that the matrix and the rhs vector have the same nrow()
445  if (matrix_pt->nrow() != rhs.nrow())
446  {
447  std::ostringstream error_message_stream;
448  error_message_stream
449  << "The matrix and the rhs vector must have the same number of rows.";
450  throw OomphLibError(error_message_stream.str(),
453  }
454 
455  // if the matrix is distributable then it too should have the same
456  // communicator as the rhs vector and should not be distributed
457  DistributableLinearAlgebraObject* dist_matrix_pt =
458  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
459  if (dist_matrix_pt != 0)
460  {
461  if (dist_matrix_pt->distribution_pt()->communicator_pt()->nproc() > 1 &&
462  dist_matrix_pt->distribution_pt()->distributed() == true)
463  {
464  throw OomphLibError(
465  "Matrix must not be distributed or only one processor",
468  }
469  OomphCommunicator temp_comm(*rhs.distribution_pt()->communicator_pt());
470  if (!(temp_comm == *dist_matrix_pt->distribution_pt()->communicator_pt()))
471  {
472  std::ostringstream error_message_stream;
473  error_message_stream
474  << "The matrix matrix_pt must have the same communicator as the "
475  "vectors"
476  << " rhs and result must have the same communicator";
477  throw OomphLibError(error_message_stream.str(),
480  }
481  }
482  // if the result vector is setup then check it is not distributed and has
483  // the same communicator as the rhs vector
484  if (result.distribution_built())
485  {
486  if (!(*result.distribution_pt() == *rhs.distribution_pt()))
487  {
488  std::ostringstream error_message_stream;
489  error_message_stream
490  << "The result vector distribution has been setup; it must have the "
491  << "same distribution as the rhs vector.";
492  throw OomphLibError(error_message_stream.str(),
495  }
496  }
497 #endif
498 
499  if (!result.distribution_built())
500  {
501  result.build(rhs.distribution_pt(), 0.0);
502  }
503 
504  // set the distribution
505  this->build_distribution(rhs.distribution_pt());
506 
507  // Time the solver
508  double t_start = TimingHelpers::timer();
509 
510  // factorise
511  factorise(matrix_pt);
512 
513  // backsubstitute
514  backsub(rhs, result);
515 
516  // Doc time for solver
517  double t_end = TimingHelpers::timer();
518 
519  Solution_time = t_end - t_start;
520  if (Doc_time)
521  {
522  oomph_info << std::endl
523  << "CPU for solve with DenseLU : "
526  << std::endl
527  << std::endl;
528  }
529 
530  // If we are not resolving then delete storage
531  if (!Enable_resolve)
532  {
533  clean_up_memory();
534  }
535  }
void backsub(const DoubleVector &rhs, DoubleVector &result)
Do the backsubstitution step to solve the system LU result = rhs.
Definition: linear_solver.cc:320
void factorise(DoubleMatrixBase *const &matrix_pt)
Perform the LU decomposition of the matrix.
Definition: linear_solver.cc:131
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
Definition: linear_algebra_distribution.h:507
DistributableLinearAlgebraObject()
Default constructor - create a distribution.
Definition: linear_algebra_distribution.h:438
bool Enable_resolve
Definition: linear_solver.h:73
double timer()
returns the time in seconds after some point in past
Definition: oomph_utilities.cc:1295
std::string convert_secs_to_formatted_string(const double &time_in_sec)
Definition: oomph_utilities.cc:1316
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References backsub(), oomph::DoubleVector::build(), oomph::DistributableLinearAlgebraObject::build_distribution(), clean_up_memory(), oomph::LinearAlgebraDistribution::communicator_pt(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distribution_built(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Doc_time, oomph::LinearSolver::Enable_resolve, factorise(), oomph::DoubleMatrixBase::ncol(), oomph::OomphCommunicator::nproc(), oomph::DistributableLinearAlgebraObject::nrow(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, Solution_time, and oomph::TimingHelpers::timer().

◆ solve() [2/3]

void oomph::DenseLU::solve ( DoubleMatrixBase *const &  matrix_pt,
const Vector< double > &  rhs,
Vector< double > &  result 
)
virtual

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system.

Reimplemented from oomph::LinearSolver.

Reimplemented in oomph::FD_LU.

544  {
545  // Time the solver
546  clock_t t_start = clock();
547 
548  factorise(matrix_pt);
549  backsub(rhs, result);
550 
551  // Doc time for solver
552  clock_t t_end = clock();
553 
554  Solution_time = double(t_end - t_start) / CLOCKS_PER_SEC;
555  if (Doc_time)
556  {
557  oomph_info << "CPU for solve with DenseLU : "
560  << std::endl;
561  }
562 
563  // If we are not resolving then delete storage
564  if (!Enable_resolve)
565  {
566  clean_up_memory();
567  }
568  }

References backsub(), clean_up_memory(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearSolver::Doc_time, oomph::LinearSolver::Enable_resolve, factorise(), oomph::oomph_info, and Solution_time.

◆ solve() [3/3]

void oomph::DenseLU::solve ( Problem *const &  problem_pt,
DoubleVector result 
)
virtual

Solver: Takes pointer to problem and returns the results Vector which contains the solution of the linear system defined by the problem's fully assembled Jacobian and residual Vector.

Implements oomph::LinearSolver.

Reimplemented in oomph::FD_LU.

52  {
53  // Initialise timer
54  double t_start = TimingHelpers::timer();
55 
56  // Find # of degrees of freedom (variables)
57  const unsigned n_dof = problem_pt->ndof();
58 
59  // Allocate storage for the residuals vector and the jacobian matrix
60  DoubleVector residuals;
61  DenseDoubleMatrix jacobian(n_dof);
62 
63  // initialise timer
64  double t_start_jacobian = TimingHelpers::timer();
65 
66  // Get the full jacobian and residuals of the problem
67  problem_pt->get_jacobian(residuals, jacobian);
68 
69  // compute jacobian setup time
70  double t_end_jacobian = TimingHelpers::timer();
71  Jacobian_setup_time = t_end_jacobian - t_start_jacobian;
72 
73  // Report the time
74  if (Doc_time)
75  {
76  oomph_info << std::endl
77  << "CPU for setup of Dense Jacobian: "
80  << std::endl;
81  }
82 
83  // Solve by dense LU decomposition VERY INEFFICIENT!
84  solve(&jacobian, residuals, result);
85 
86  // Set the sign of the determinant of the jacobian
87  problem_pt->sign_of_jacobian() = Sign_of_determinant_of_matrix;
88 
89  // Finalise/doc timings
90  double t_end = TimingHelpers::timer();
91  double total_time = t_end - t_start;
92  if (Doc_time)
93  {
94  oomph_info << "CPU for DenseLU LinearSolver: "
96  << std::endl
97  << std::endl;
98  }
99  }
std::vector< double > DoubleVector
loads clump configuration
Definition: ClumpInput.h:26
friend class DenseDoubleMatrix
The DenseDoubleMatrix class is a friend.
Definition: linear_solver.h:336
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:51

References oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearSolver::Doc_time, oomph::Problem::get_jacobian(), Jacobian_setup_time, oomph::Problem::ndof(), oomph::oomph_info, Sign_of_determinant_of_matrix, oomph::Problem::sign_of_jacobian(), and oomph::TimingHelpers::timer().

Referenced by oomph::FD_LU::solve().

Friends And Related Function Documentation

◆ DenseDoubleMatrix

friend class DenseDoubleMatrix
friend

The DenseDoubleMatrix class is a friend.

Member Data Documentation

◆ Index

long* oomph::DenseLU::Index
private

Pointer to storage for the index of permutations in the LU solve.

Referenced by backsub(), clean_up_memory(), and factorise().

◆ Jacobian_setup_time

double oomph::DenseLU::Jacobian_setup_time
protected

Jacobian setup time.

Referenced by jacobian_setup_time(), solve(), and oomph::FD_LU::solve().

◆ LU_factors

double* oomph::DenseLU::LU_factors
private

Pointer to storage for the LU decomposition.

Referenced by backsub(), clean_up_memory(), and factorise().

◆ Sign_of_determinant_of_matrix

int oomph::DenseLU::Sign_of_determinant_of_matrix
protected

Sign of the determinant of the matrix (obtained during the LU decomposition)

Referenced by factorise(), solve(), and oomph::FD_LU::solve().

◆ Solution_time

double oomph::DenseLU::Solution_time
protected

Solution time.

Referenced by linear_solver_solution_time(), and solve().


The documentation for this class was generated from the following files: