two_d_poisson_compare_solvers.cc File Reference
#include "generic.h"
#include "poisson.h"
#include "meshes/simple_rectangular_quadmesh.h"

Classes

class  PoissonProblem< ELEMENT >
 Micky mouse Poisson problem. More...
 

Namespaces

 TanhSolnForPoisson
 Namespace for exact solution for Poisson equation with "sharp step".
 

Functions

void TanhSolnForPoisson::get_exact_u (const Vector< double > &x, Vector< double > &u)
 Exact solution as a Vector. More...
 
void TanhSolnForPoisson::get_source (const Vector< double > &x, double &source)
 Source function to make it an exact solution. More...
 
void run (const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
 
int main ()
 Driver code for 2D Poisson problem – compare different solvers. More...
 

Function Documentation

◆ main()

int main ( )

Driver code for 2D Poisson problem – compare different solvers.

Use SuperLU with compressed row storage

Use compressed row storage

Switch on full doc

Use SuperLU with compressed column storage

Use compressed row storage

Switch on full doc

Use dense matrix LU decomposition

Use dense matrix LU decomposition

386 {
387 
388  // Pointer to linear solver
389  LinearSolver* linear_solver_pt;
390 
391  // Result directory
392  string dir_name;
393 
394  // Cpu start/end times
395  clock_t cpu_start,cpu_end;
396 
397  // Storage for cpu times with and without messed up order
398  Vector<double> superlu_cr_cpu(2);
399  Vector<double> superlu_cc_cpu(2);
400  Vector<double> hsl_ma42_cpu(2);
401  Vector<double> hsl_ma42_reordered_cpu(2);
402  Vector<double> dense_lu_cpu(2);
403  Vector<double> fd_lu_cpu(2);
404 
405  // Flag to indicate if order should be messed up:
406  bool mess_up_order;
407 
408  // Number of elements along 1D edge of mesh; total number of elements
409  // is nel_1d x nel_1d
410  unsigned nel_1d;
411 
412  // Do run with and without messed up elements
413  for (unsigned mess=0;mess<2;mess++)
414  {
415 
416  // Mess up order?
417  if (mess==0)
418  {
419  mess_up_order=true;
420  }
421  else
422  {
423  mess_up_order=false;
424  }
425 
427  //-----------------------------------------
428 
429  cout << std::endl;
430  cout << " Use SuperLU with compressed row storage: " << std::endl;
431  cout << "========================================= " << std::endl;
432  cout << std::endl;
433 
434  // Start cpu clock
435  cpu_start=clock();
436 
437  // Build linear solver
438  linear_solver_pt = new SuperLUSolver;
439 
441  static_cast<SuperLUSolver*>(linear_solver_pt)
442  ->use_compressed_row_for_superlu_serial();
443 
445  static_cast<SuperLUSolver*>(linear_solver_pt)->enable_doc_stats();
446 
447  // Choose result directory
448  dir_name="RESLT_cr";
449 
450  // Number of elements along 1D edge of mesh; total number of elements
451  // is nel_1d x nel_1d
452  nel_1d=20;
453 
454  // Run it
455  run(dir_name,linear_solver_pt,nel_1d,mess_up_order);
456 
457  // Note: solver does not have to be deleted -- it's killed automatically
458  // in the problem destructor.
459 
460  // End cpu clock
461  cpu_end=clock();
462 
463  // Timing
464  superlu_cr_cpu[mess]=double(cpu_end-cpu_start)/CLOCKS_PER_SEC;
465 
466 
467 
468 
470  //--------------------------------------------
471 
472 
473  cout << std::endl;
474  cout << " Use SuperLU with compressed column storage: " << std::endl;
475  cout << "============================================ " << std::endl;
476  cout << std::endl;
477 
478 
479  // Start cpu clock
480  cpu_start=clock();
481 
482  // Build linear solver
483  linear_solver_pt = new SuperLUSolver;
484 
486  static_cast<SuperLUSolver*>(linear_solver_pt)
487  ->use_compressed_column_for_superlu_serial();
488 
490  static_cast<SuperLUSolver*>(linear_solver_pt)->enable_doc_stats();
491 
492  // Choose result directory
493  dir_name="RESLT_cc";
494 
495  // Number of elements along 1D edge of mesh; total number of elements
496  // is nel_1d x nel_1d
497  nel_1d=20;
498 
499  // Run it
500  run(dir_name,linear_solver_pt,nel_1d,mess_up_order);
501 
502  // Note: solver does not have to be deleted -- it's killed automatically
503  // in the problem destructor.
504 
505  // End cpu clock
506  cpu_end=clock();
507 
508  // Timing
509  superlu_cc_cpu[mess]=double(cpu_end-cpu_start)/CLOCKS_PER_SEC;
510 
511 
512 #ifdef HAVE_HSL_SOURCES
513 
515  //---------------------------------------------------------
516 
517  cout << std::endl;
518  cout << " Use HSL frontal solver MA42 without element re-ordering: " << std::endl;
519  cout << "========================================================= " << std::endl;
520  cout << std::endl;
521 
522  // Start cpu clock
523  cpu_start=clock();
524 
525  // Build linear solver
526  linear_solver_pt = new HSL_MA42;
527 
529  static_cast<HSL_MA42*>(linear_solver_pt)->enable_doc_stats();
530 
531  // Choose result directory
532  dir_name="RESLT_frontal";
533 
534 
535  // Number of elements along 1D edge of mesh; total number of elements
536  // is nel_1d x nel_1d
537  nel_1d=20;
538 
539  // Run it
540  run(dir_name,linear_solver_pt,nel_1d,mess_up_order);
541 
542  // Note: solver does not have to be deleted -- it's killed automatically
543  // in the problem destructor.
544 
545 
546  // End cpu clock
547  cpu_end=clock();
548 
549  // Timing
550  hsl_ma42_cpu[mess]=double(cpu_end-cpu_start)/CLOCKS_PER_SEC;
551 
552 
553 
555  //--------------------------------------------------------------------------
556 
557  cout << std::endl;
558  cout << " Use HSL frontal solver MA42 with element re-ordering: " << std::endl;
559  cout << "====================================================== " << std::endl;
560  cout << std::endl;
561 
562  // Start cpu clock
563  cpu_start=clock();
564 
565  // Build linear solver
566  linear_solver_pt = new HSL_MA42;
567 
569  static_cast<HSL_MA42*>(linear_solver_pt)->enable_doc_stats();
570 
571 
573  static_cast<HSL_MA42*>(linear_solver_pt)->enable_reordering();
574 
575  // Choose result directory
576  dir_name="RESLT_frontal_reordered";
577 
578 
579  // Number of elements along 1D edge of mesh; total number of elements
580  // is nel_1d x nel_1d
581  nel_1d=20;
582 
583  // Run it
584  run(dir_name,linear_solver_pt,nel_1d,mess_up_order);
585 
586  // Note: solver does not have to be deleted -- it's killed automatically
587  // in the problem destructor.
588 
589 
590  // End cpu clock
591  cpu_end=clock();
592 
593  // Timing
594  hsl_ma42_reordered_cpu[mess]=double(cpu_end-cpu_start)/CLOCKS_PER_SEC;
595 
596 
597 #endif
598 
600  //-----------------------------------
601 
602  cout << std::endl;
603  cout << " Use dense matrix LU decomposition: " << std::endl;
604  cout << "=================================== " << std::endl;
605  cout << std::endl;
606 
607  // Start cpu clock
608  cpu_start=clock();
609 
610  // Build linear solver
611  linear_solver_pt = new DenseLU;
612 
613  // Choose result directory
614  dir_name="RESLT_dense_LU";
615 
616  // Number of elements along 1D edge of mesh; total number of elements
617  // is nel_1d x nel_1d
618  nel_1d=4;
619 
620  // Run it
621  run(dir_name,linear_solver_pt,nel_1d,mess_up_order);
622 
623  // Note: solver does not have to be deleted -- it's killed automatically
624  // in the problem destructor.
625 
626 
627  // End cpu clock
628  cpu_end=clock();
629 
630  // Timing
631  dense_lu_cpu[mess]=double(cpu_end-cpu_start)/CLOCKS_PER_SEC;
632 
633 
634 
635 
637  //-----------------------------------
638 
639  cout << std::endl;
640  cout << " Use dense FD-ed matrix LU decomposition: " << std::endl;
641  cout << "========================================= " << std::endl;
642  cout << std::endl;
643 
644  // Start cpu clock
645  cpu_start=clock();
646 
647  // Build linear solver
648  linear_solver_pt = new FD_LU;
649 
650  // Choose result directory
651  dir_name="RESLT_FD_LU";
652 
653  // Number of elements along 1D edge of mesh; total number of elements
654  // is nel_1d x nel_1d
655  nel_1d=4;
656 
657  // Run it
658  run(dir_name,linear_solver_pt,nel_1d,mess_up_order);
659 
660  // Note: solver does not have to be deleted -- it's killed automatically
661  // in the problem destructor.
662 
663  // End cpu clock
664  cpu_end=clock();
665 
666  // Timing
667  fd_lu_cpu[mess]=double(cpu_end-cpu_start)/CLOCKS_PER_SEC;
668 
669  }
670 
671 
672  // Doc timings with and without messed up elements
673  for (unsigned mess=0;mess<2;mess++)
674  {
675  cout << std::endl << std::endl << std::endl ;
676  if (mess==0)
677  {
678  cout << "TIMINGS WITH MESSED UP ORDERING OF ELEMENTS: " << std::endl;
679  cout << "============================================ " << std::endl;
680 
681  }
682  else
683  {
684  cout << "TIMINGS WITHOUT MESSED UP ORDERING OF ELEMENTS: " << std::endl;
685  cout << "=============================================== " << std::endl;
686  }
687 
688  cout << "CPU time with SuperLU compressed row : "
689  << superlu_cr_cpu[mess] << std::endl;
690  cout << "CPU time with SuperLU compressed col : "
691  << superlu_cc_cpu[mess] << std::endl;
692 #ifdef HAVE_HSL_SOURCES
693  cout << "CPU time with MA42 frontal solver : "
694  << hsl_ma42_cpu[mess] << std::endl;
695  cout << "CPU time with MA42 frontal solver (incl. reordering) : "
696  << hsl_ma42_reordered_cpu[mess] << std::endl;
697 #endif
698  cout << "CPU time with dense LU solver (fewer elements!) : "
699  << dense_lu_cpu[mess] << std::endl;
700  cout << "CPU time with dense LU solver & FD (fewer elements!) : "
701  << fd_lu_cpu[mess] << std::endl;
702  cout << std::endl << std::endl << std::endl ;
703  }
704 
705 
706 
707 
708 } //end of main
Definition: linear_solver.h:334
Definition: linear_solver.h:432
Definition: frontal_solver.h:56
Definition: linear_solver.h:68
Definition: linear_solver.h:486
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317

References run().

◆ run()

void run ( const string &  dir_name,
LinearSolver linear_solver_pt,
const unsigned  nel_1d,
bool  mess_up_order 
)

Build and run problem with specified linear solver. Also pass flag to specify if order of elements should be messed up. nel_1d is the number of elements along the 1D mesh edge. Total number of elements is nel_1d x nel_1d.

Set linear solver:

321 {
322 
323  //Set up the problem
324  //------------------
325 
326  // Create the problem with 2D nine-node elements from the
327  // QPoissonElement family. Pass pointer to source function
328  // and flag to specify if order of elements should be messed up.
330  problem(&TanhSolnForPoisson::get_source,nel_1d,mess_up_order);
331 
332 
334  //--------------------
335  problem.linear_solver_pt() = linear_solver_pt;
336 
337 
338  // Create label for output
339  //------------------------
340  DocInfo doc_info;
341 
342  // Set output directory
343  doc_info.set_directory(dir_name);
344 
345  // Step number
346  doc_info.number()=0;
347 
348  // Check if we're ready to go:
349  //----------------------------
350  cout << "\n\n\nProblem self-test:";
351  if (problem.self_test()==0)
352  {
353  cout << "passed: Problem can be solved." << std::endl;
354  }
355  else
356  {
357  throw OomphLibError("Self test failed",
360  }
361 
362 
363  // Set the orientation of the "step" to 45 degrees
365 
366  // Initial value for the steepness of the "step"
368 
369  // Solve the problem
370  problem.newton_solve();
371 
372  //Output the solution
373  problem.doc_solution(doc_info);
374 
375 
376 } //end of run
Micky mouse Poisson problem.
Definition: HypreSolver_test.cc:81
Definition: oomph_utilities.h:499
void set_directory(const std::string &directory)
Definition: oomph_utilities.cc:298
unsigned & number()
Number used (e.g.) for labeling output files.
Definition: oomph_utilities.h:554
Definition: oomph_definitions.h:222
double TanPhi
Parameter for angle Phi of "step".
Definition: HypreSolver_test.cc:51
void get_source(const Vector< double > &x, double &source)
Source function to make it an exact solution.
Definition: extrude_with_macro_element_representation.cc:224
double Alpha
Parameter for steepness of step.
Definition: extrude_with_macro_element_representation.cc:185
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
Constructor for SteadyAxisymAdvectionDiffusion problem
Definition: steady_axisym_advection_diffusion.cc:213

References TanhSolnForPoisson::Alpha, TanhSolnForPoisson::get_source(), oomph::DocInfo::number(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, problem, oomph::DocInfo::set_directory(), and TanhSolnForPoisson::TanPhi.

Referenced by Eigen::internal::generic_product_impl< Lhs, Rhs, DenseShape, DenseShape, InnerProduct >::addTo(), adjoint(), Eigen::DenseBase< Derived >::all(), Eigen::SimplicialCholeskyBase< Derived >::analyzePattern_preordered(), Eigen::DenseBase< Derived >::any(), Eigen::DynamicSGroup::apply(), Eigen::internal::call_assignment_no_alias(), Eigen::internal::call_assignment_no_alias_no_transpose(), Eigen::internal::call_dense_assignment_loop(), Eigen::internal::call_restricted_packet_assignment_no_alias(), cast_test(), casting_all(), Eigen::MatrixBase< Derived >::computeInverseAndDetWithCheck(), Eigen::DenseBase< Derived >::count(), DefaultAssign(), DeviceAssign(), EIGEN_DECLARE_TEST(), Eigen::numext::equal_strict(), Eigen::TensorReductionEvaluatorBase< const TensorReductionOp< Op, Dims, ArgType, MakePointer_ >, Device >::evalSubExprsIfNeededCommon(), Eigen::internal::generic_product_impl< Inverse< Lhs >, Rhs, PermutationShape, MatrixShape, ProductTag >::evalTo(), Eigen::internal::generic_product_impl< Lhs, Inverse< Rhs >, MatrixShape, PermutationShape, ProductTag >::evalTo(), Eigen::internal::generic_product_impl< Lhs, Rhs, PermutationShape, MatrixShape, ProductTag >::evalTo(), Eigen::internal::generic_product_impl< Lhs, Rhs, MatrixShape, PermutationShape, ProductTag >::evalTo(), Eigen::internal::generic_product_impl< Lhs, Rhs, DenseShape, DenseShape, InnerProduct >::evalTo(), Eigen::internal::h_array_apply(), Eigen::internal::h_array_apply_and_reduce(), Eigen::internal::h_array_zip(), Eigen::internal::h_array_zip_and_reduce(), Eigen::internal::instantiate_by_c_array(), main(), mapstaticmethods(), Eigen::numext::not_equal_strict(), Eigen::internal::scalar_unary_pow_op< Scalar, ExponentScalar, BaseIsInteger, true, false, false >::operator()(), Eigen::internal::gemm_functor< Scalar, Index, Gemm, Lhs, Rhs, Dest, BlockingType >::operator()(), Eigen::RotationBase< Derived, Dim_ >::operator*(), Eigen::Transform< Scalar_, Dim_, Mode_, Options_ >::operator*(), Eigen::Transform< Scalar_, Dim_, Mode_, Options_ >::operator=(), Eigen::EulerAngles< Scalar_, _System >::operator=(), Eigen::QuaternionBase< Derived >::operator=(), Eigen::TensorAsyncDevice< ExpressionType, DeviceType, DoneCallback >::operator=(), Eigen::SparseVector< Scalar_, Options_, StorageIndex_ >::operator=(), Eigen::internal::unary_evaluator< Reverse< ArgType, Direction > >::packet(), Eigen::internal::product_evaluator< Product< Lhs, Rhs, LazyProduct >, ProductTag, DenseShape, DenseShape >::packet(), Eigen::internal::scalar_unary_pow_op< Scalar, ExponentScalar, false, false, false, false >::packetOp(), Eigen::internal::scalar_unary_pow_op< Scalar, ExponentScalar, BaseIsInteger, true, false, false >::packetOp(), Eigen::internal::pcast(), Eigen::internal::preinterpret(), Eigen::internal::psignbit(), Eigen::SelfAdjointView< MatrixType_, UpLo >::rankUpdate(), Eigen::internal::lapacke_helpers::lapacke_llt< Scalar, Mode >::rankUpdate(), Eigen::DenseBase< Derived >::redux(), Eigen::Tensor< Scalar_, NumIndices_, Options_, IndexType_ >::resize(), Eigen::PlainObjectBase< Derived >::resize(), Eigen::PlainObjectBase< Derived >::resizeLike(), Eigen::VectorwiseOp< ExpressionType, Direction >::reverseInPlace(), test_transform< func, arg1, arg2 >::run(), cast_test_impl< SrcType, DstType, RowsAtCompileTime, ColsAtCompileTime >::run(), test_cast< SrcPacket, TgtPacket >::run(), Eigen::internal::reduce< Reducer, A, Ts... >::run(), Eigen::internal::h_array_reduce< Reducer, T, N, n >::run(), Eigen::internal::h_instantiate_by_c_array< InstType, ArrType, N, false, Ps... >::run(), Eigen::internal::h_instantiate_by_c_array< InstType, ArrType, N, true, Ps... >::run(), Eigen::internal::random_impl< bfloat16 >::run(), Eigen::internal::visit_impl< Derived, Visitor, ShortCircuitEvaulation >::run(), Eigen::internal::visitor_impl< Visitor, Derived, Dynamic, false, false, ShortCircuitEvaluation >::run(), Eigen::internal::visitor_impl< Visitor, Derived, Dynamic, true, false, ShortCircuitEvaluation >::run(), Eigen::internal::visitor_impl< Visitor, Derived, Dynamic, false, true, ShortCircuitEvaluation >::run(), Eigen::internal::visitor_impl< Visitor, Derived, Dynamic, true, true, ShortCircuitEvaluation >::run(), Eigen::internal::inner_product_impl< Evaluator, true >::run(), Eigen::internal::redux_impl< Func, Evaluator, DefaultTraversal, CompleteUnrolling >::run(), Eigen::internal::redux_impl< Func, Evaluator, LinearTraversal, CompleteUnrolling >::run(), Eigen::internal::redux_impl< Func, Evaluator, SliceVectorizedTraversal, Unrolling >::run(), Eigen::internal::random_impl< half >::run(), Eigen::internal::gemv_dense_selector< OnTheLeft, StorageOrder, BlasCompatible >::run(), Eigen::internal::triangular_solver_unroller< Lhs, Rhs, Mode, LoopIndex, Size, false >::run(), Eigen::internal::triangular_solver_selector< Lhs, Rhs, OnTheLeft, Mode, CompleteUnrolling, 1 >::run(), Eigen::internal::default_inner_product_impl< Lhs, Rhs, Conj >::run(), mapstaticmethods_impl< PlainObjectType, false, IsVector >::run(), Eigen::internal::random_int_impl< Scalar, true, true >::run(), Eigen::internal::random_default_impl< Scalar, true, false >::run(), Eigen::internal::tensor_static_symgroup_do_apply< internal::type_list< first, next... > >::run(), Eigen::numext::equal_strict_impl< X, Y, true, true, true, false >::run(), Eigen::internal::conservative_resize_like_impl< Derived, OtherDerived, true >::run(), Eigen::internal::sparse_vector_assign_selector< Dest, Src, SVA_RuntimeSwitch >::run(), Eigen::internal::Assignment< DstXprType, CwiseNullaryOp< scalar_constant_op< typename DstXprType::Scalar >, SrcPlainObject >, assign_op< typename DstXprType::Scalar, typename DstXprType::Scalar >, Dense2Dense, Weak >::run(), Eigen::internal::Assignment< DstXprType, CwiseNullaryOp< scalar_zero_op< typename DstXprType::Scalar >, SrcPlainObject >, assign_op< typename DstXprType::Scalar, typename DstXprType::Scalar >, Dense2Dense, Weak >::run(), Eigen::internal::AssignmentWithDevice< DstXprType, Product< Lhs, Rhs, Options >, Functor, Device, Dense2Dense, Weak >::run(), Eigen::internal::triangular_matrix_vector_product< Index, Mode, LhsScalar, ConjLhs, RhsScalar, ConjRhs, RowMajor, Version >::run(), Eigen::internal::triangular_matrix_vector_product< Index, Mode, LhsScalar, ConjLhs, RhsScalar, ConjRhs, ColMajor, Version >::run(), Eigen::internal::etor_product_packet_impl< RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode >::run(), Eigen::internal::etor_product_packet_impl< ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode >::run(), Eigen::internal::general_rank1_update< Scalar, Index, RowMajor, ConjLhs, ConjRhs >::run(), Eigen::internal::selfadjoint_packed_rank1_update< Scalar, Index, RowMajor, UpLo, ConjLhs, ConjRhs >::run(), Eigen::selfadjoint_rank1_update< Scalar, Index, RowMajor, UpLo, ConjLhs, ConjRhs >::run(), Eigen::internal::random_default_impl< Scalar, false, false >::run(), Eigen::internal::dense_assignment_loop< Kernel, SliceVectorizedTraversal, NoUnrolling >::run(), Eigen::internal::dense_assignment_loop_with_device< Kernel, Device, Traversal, Unrolling >::run(), Eigen::internal::tuple_impl::tuple_cat_impl< NTuples, TupleImpl< N1, Args1... >, TupleImpl< N2, Args2... >, Tuples... >::run(), Eigen::internal::generic_product_impl< Lhs, Rhs, TriangularShape, DenseShape, ProductTag >::scaleAndAddTo(), Eigen::internal::generic_product_impl< Lhs, Rhs, DenseShape, TriangularShape, ProductTag >::scaleAndAddTo(), Eigen::internal::generic_product_impl< Lhs, Rhs, SelfAdjointShape, DenseShape, ProductTag >::scaleAndAddTo(), Eigen::internal::generic_product_impl< Lhs, Rhs, DenseShape, SelfAdjointShape, ProductTag >::scaleAndAddTo(), Eigen::DenseBase< Derived >::setConstant(), Eigen::DenseBase< Derived >::setZero(), Eigen::numext::signbit(), Eigen::internal::sparse_time_dense_product(), Eigen::internal::generic_product_impl< Lhs, Rhs, DenseShape, DenseShape, InnerProduct >::subTo(), test_execute_binary_expr(), test_execute_broadcasting(), test_execute_broadcasting_of_forced_eval(), test_execute_chipping_lvalue(), test_execute_chipping_rvalue(), test_execute_generator_op(), test_execute_reshape(), test_execute_reverse_rvalue(), test_execute_slice_lvalue(), test_execute_slice_rvalue(), test_execute_unary_expr(), test_tensor_ostream(), testGeneral(), testLogThenExp(), testMatrixSqrt(), tpmv(), tpsv(), Eigen::Transform< Scalar_, Dim_, Mode_, Options_ >::Transform(), Eigen::DenseBase< Derived >::transposeInPlace(), VerifyBlockAssignment(), VerifyBlockEvaluator(), Eigen::viewAsCholmod(), Eigen::DenseBase< Derived >::visit(), and Eigen::internal::unary_evaluator< Reverse< ArgType, Direction > >::writePacket().