two_d_mesh_dist.cc File Reference
#include "mpi.h"
#include "generic.h"
#include "poisson.h"
#include "meshes/rectangular_quadmesh.h"

Classes

class  MyRefineableRectangularQuadMesh< ELEMENT >
 Upgraded mesh. More...
 
class  RefineablePoissonProblem< ELEMENT >
 

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 parallel_test (const unsigned &n_refine_first, const unsigned &n_refine_once_distributed, const bool &redistribute, const bool &solve, const bool &doc)
 
int main (int argc, char **argv)
 Driver code for 2D Poisson problem. More...
 

Function Documentation

◆ main()

int main ( int argc  ,
char **  argv 
)

Driver code for 2D Poisson problem.

745 {
746 
747 #ifdef OOMPH_HAS_MPI
748  // Setup MPI helpers
749  MPI_Helpers::init(argc,argv);
750 #endif
751 
752  // Store command line arguments
753  CommandLineArgs::setup(argc,argv);
754 
755 
756  // Default min. number of refinements before we distribute
757  unsigned n_refine_first_min=2;
758 
759  // Default max. number of refinements before we distribute
760  unsigned n_refine_first_max=2;
761 
762  // Default min. number of uniform refinements after distribution
763  unsigned n_uniform_min=3;
764 
765  // Default max. number of uniform refinements after distribution
766  unsigned n_uniform_max=3;
767 
768  // Redistribute after uniform refinement?
769  bool redistribute=true;
770 
771 
772 
773  if (CommandLineArgs::Argc==1)
774  {
775  std::cout << "Using default settings for flags" << std::endl;
776  }
777  else if (CommandLineArgs::Argc==6)
778  {
779 
780  // Min. number of refinements before we distribute
781  n_refine_first_min=atoi(argv[1]);
782 
783  // Max. number of refinements before we distribute
784  n_refine_first_max=atoi(argv[2]);
785 
786  // Min. number of uniform refinements after distribution
787  n_uniform_min=atoi(argv[3]);
788 
789  // Max. number of uniform refinements after distribution
790  n_uniform_max=atoi(argv[4]);
791 
792  // Redistribute after uniform refinement?
793  redistribute=atoi(argv[5]);
794  }
795  else
796  {
797  oomph_info
798  << "Wrong number of input args. Specify none or five "
799  << "(n_refine_first_min/max, n_uniform_min/max, redistributon flag)"
800  << std::endl;
801  exit(1);
802  }
803 
804 
805 
806  // Tell us what we're going to do
807  oomph_info << "Run with n_refine_first_min/max, n_uniform_min/max, redistribute: "
808  << n_refine_first_min << " "
809  << n_refine_first_max << " "
810  << n_uniform_min << " "
811  << n_uniform_max << " "
812  << redistribute << " "
813  << std::endl;
814 
815 
816  // Solve and self test?
817  bool solve=true;
818  bool doc=true;
819 
820  // Write headers for analysis
821  ofstream some_file;
822  some_file.open("RESLT/two_d_initial_refinement_header.dat");
823  some_file << "VARIABLES= \"n<SUB>refine first</SUB>\","
824  << "\"n<SUB>dof orig</SUB>\","
825  << "\"n<SUB>dof</SUB>\","
826  << "\"t<SUB>serial adapt</SUB>\""
827  << std::endl;
828  some_file.close();
829 
830 
831  some_file.open("RESLT/two_d_initial_distr_header.dat");
832  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
833  << "\"n<SUB>dof</SUB>\","
834  << "\"t<SUB>distr</SUB>\","
835  << "\"average n<SUB>halo nodes</SUB>\","
836  << "\"max. n<SUB>halo nodes</SUB>\","
837  << "\"min. n<SUB>halo nodes</SUB>\","
838  << "\"average efficiency\","
839  << "\"max. efficiency\","
840  << "\"min. efficiency\""
841  << std::endl;
842  some_file.close();
843 
844 
845  some_file.open("RESLT/two_d_distributed_refinement_header.dat");
846  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
847  << "\"n<SUB>dof orig</SUB>\","
848  << "\"n<SUB>dof</SUB>\","
849  << "\"t<SUB>distributed refinement</SUB>\","
850  << "\"average n<SUB>halo nodes</SUB>\","
851  << "\"max. n<SUB>halo nodes</SUB>\","
852  << "\"min. n<SUB>halo nodes</SUB>\","
853  << "\"average efficiency\","
854  << "\"max. efficiency\","
855  << "\"min. efficiency\""
856  << std::endl;
857  some_file.close();
858 
859 
860  some_file.open("RESLT/two_d_redistribution_header.dat");
861  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
862  << "\"n<SUB>dof</SUB>\","
863  << "\"t<SUB>redistribution</SUB>\","
864  << "\"average n<SUB>halo nodes</SUB>\","
865  << "\"max. n<SUB>halo nodes</SUB>\","
866  << "\"min. n<SUB>halo nodes</SUB>\","
867  << "\"average efficiency\","
868  << "\"max. efficiency\","
869  << "\"min. efficiency\""
870  << std::endl;
871  some_file.close();
872 
873 
874 
875  some_file.open("RESLT/two_d_distributed_unrefinement_header.dat");
876  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
877  << "\"n<SUB>dof orig</SUB>\","
878  << "\"n<SUB>dof</SUB>\","
879  << "\"t<SUB>distributed unrefinement</SUB>\","
880  << "\"average n<SUB>halo nodes</SUB>\","
881  << "\"max. n<SUB>halo nodes</SUB>\","
882  << "\"min. n<SUB>halo nodes</SUB>\","
883  << "\"average efficiency\","
884  << "\"max. efficiency\","
885  << "\"min. efficiency\""
886  << std::endl;
887  some_file.close();
888 
889 
890  // Test the procedures in parallel mode
891  for (unsigned i=n_refine_first_min;i<=n_refine_first_max;i++)
892 
893  {
894  for (unsigned j=n_uniform_min;j<=n_uniform_max;j++)
895  {
896  parallel_test(i,j,redistribute,solve,doc);
897  }
898  }
899 
900 #ifdef OOMPH_HAS_MPI
901  MPI_Helpers::finalize();
902 #endif
903 
904 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
void setup(Time *time_pt)
Create all GeomObjects needed to define the cylinder and the flag.
Definition: turek_flag_non_fsi.cc:277
int Argc
Number of arguments + 1.
Definition: oomph_utilities.cc:407
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
Update the problem specs before solve
Definition: steady_axisym_advection_diffusion.cc:353
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
void parallel_test(const unsigned &n_refine_first, const unsigned &n_refine_once_distributed, const bool &redistribute, const bool &solve, const bool &doc)
Definition: two_d_mesh_dist.cc:290

References oomph::CommandLineArgs::Argc, i, j, oomph::oomph_info, parallel_test(), Flag_definition::setup(), and solve.

◆ parallel_test()

void parallel_test ( const unsigned n_refine_first,
const unsigned n_refine_once_distributed,
const bool redistribute,
const bool solve,
const bool doc 
)

Test mesh distribution in parallel, starting with n_uniform_first uniform refinments before starting the distribution. Then refine and unrefine uniformly as specified. Re-distribute after every uniform refinement if requested by the boolean flag.

295 {
296 
297  oomph_info
298  << std::endl << std::endl
299  << "Running with " << n_refine_first << " initial serial refinements and \n"
300  << "with " << n_refine_once_distributed
301  << " subsequent distributed refinements"
302  << std::endl << std::endl;
303 
304  double av_efficiency;
305  double max_efficiency;
306  double min_efficiency;
307  double av_number_halo_nodes;
308  unsigned max_number_halo_nodes;
309  unsigned min_number_halo_nodes;
310 
311  char filename[200];
312  std::ofstream some_file;
313 
314  DocInfo doc_info;
315  doc_info.set_directory("RESLT");
316 
317  DocInfo quiet_doc_info;
318  quiet_doc_info.set_directory("RESLT");
319 
320 
321  // Create the problem
322  //-------------------
326 
327  // Storage for number of processors and current rank
328  unsigned n_proc=problem_pt->communicator_pt()->nproc();
329  unsigned my_rank=problem_pt->communicator_pt()->my_rank();
330 
331  // Initial number of dofs in base mesh
332  unsigned n_dof_orig=problem_pt->ndof();
333  unsigned n_dof=problem_pt->ndof();
334 
335 
336  // Start with a few rounds of uniform refinement
337  //----------------------------------------------
338  clock_t t_start = clock();
339  for (unsigned i=0;i<n_refine_first;i++)
340  {
341  // Refine uniformly
342  problem_pt->refine_uniformly();
343  }
344  clock_t t_end = clock();
345 
346 
347  // Doc stats
348  if (my_rank==0)
349  {
350  double t_tot=double(t_end-t_start)/CLOCKS_PER_SEC;
351  oomph_info << "Time for initial adaptation [ndof=" << problem_pt->ndof()
352  << "]: " << t_tot << std::endl;
353 
354  n_dof=problem_pt->ndof();
355  sprintf(
356  filename,
357  "%s/two_d_initial_refinement_nrefinement_%i_ndofbefore_%i_ndofafter_%i.dat",
358  doc_info.directory().c_str(),
359  n_refine_first,
360  n_dof_orig,
361  n_dof);
362  some_file.open(filename);
363  some_file << n_refine_first << " "
364  << n_dof_orig << " "
365  << n_dof << " "
366  << t_tot << " "
367  << std::endl;
368  some_file.close();
369  }
370 
371 
372 
373  // Now distribute the problem
374  //---------------------------
375  t_start = clock();
376  if (doc)
377  {
378  std::ifstream input_file;
379  std::ofstream output_file;
380 
381  // Get the partition to be used from file
382  unsigned n_partition=problem_pt->mesh_pt()->nelement();
383  Vector<unsigned> element_partition(n_partition);
384  sprintf(filename,"two_d_mesh_dist_partition.dat");
385  input_file.open(filename);
386  std::string input_string;
387  for (unsigned e=0;e<n_partition;e++)
388  {
389  getline(input_file,input_string,'\n');
390  element_partition[e]=atoi(input_string.c_str());
391  }
392 
393  Vector<unsigned> out_element_partition;
394  bool report_stats=false;
395  out_element_partition=problem_pt->distribute(element_partition,
396  doc_info,report_stats);
397 
398  sprintf(filename,"out_two_d_mesh_dist_partition.dat");
399  output_file.open(filename);
400  for (unsigned e=0;e<n_partition;e++)
401  {
402  output_file << out_element_partition[e] << std::endl;
403  }
404  }
405  else
406  {
407  problem_pt->distribute();
408  }
409  t_end = clock();
410 
411 
412  // Assess the quality of the distribution
413  //---------------------------------------
414  problem_pt->mesh_pt()->get_halo_node_stats(av_number_halo_nodes,
415  max_number_halo_nodes,
416  min_number_halo_nodes);
417  problem_pt->mesh_pt()->get_efficiency_of_mesh_distribution
418  (av_efficiency,max_efficiency,min_efficiency);
419 
420 
421  // Doc stats
422  if (my_rank==0)
423  {
424  double t_tot=double(t_end-t_start)/CLOCKS_PER_SEC;
425  oomph_info << "Time for problem distribution [ndof=" << problem_pt->ndof()
426  << "]: " << t_tot << std::endl;
427 
428  sprintf(
429  filename,
430  "%s/two_d_initial_distr_np_%i_nrefinement_%i_ndof_%i.dat",
431  doc_info.directory().c_str(),
432  n_proc,
433  n_refine_first,
434  n_dof);
435  some_file.open(filename);
436  some_file << n_proc << " "
437  << n_dof << " "
438  << t_tot << " "
439  << av_number_halo_nodes << " "
440  << max_number_halo_nodes << " "
441  << min_number_halo_nodes << " "
442  << av_efficiency << " "
443  << max_efficiency << " "
444  << min_efficiency << " "
445  << std::endl;
446  some_file.close();
447  }
448 
449 
450  // Check things
451  //-------------
452  problem_pt->check_halo_schemes(quiet_doc_info);
453 
454 
455  // Solve?
456  //-------
457  if (solve)
458  {
459 
460 #ifdef OOMPH_HAS_TRILINOS
461 
462  // Notify...
463  oomph_info << "Using the TRILINOS solver" << std::endl;
464 
465  // Create a Trilinos solver
466  TrilinosAztecOOSolver* linear_solver_pt = new TrilinosAztecOOSolver;
467 
468  // Create the ML preconditioner
469  TrilinosMLPreconditioner* preconditioner_pt = new TrilinosMLPreconditioner;
470 
471  // Set preconditioner pointer
472  linear_solver_pt->preconditioner_pt() = preconditioner_pt;
473 
474  // Choose solver type (GMRES)
475  linear_solver_pt->solver_type()=TrilinosAztecOOSolver::GMRES;
476 
477  // Set linear solver
478  problem_pt->linear_solver_pt() = linear_solver_pt;
479  linear_solver_pt->disable_doc_time();
480 
481 #endif
482 
483  // Solve
484  problem_pt->newton_solve();
485 
486  if (doc)
487  {
488  // Doc the solution
489  problem_pt->doc_solution(doc_info);
490  }
491  }
492 
493 
494 
495 
496  // Now refine the distributed problem uniformly
497  //---------------------------------------------
498  for (unsigned i=0;i<n_refine_once_distributed;i++)
499  {
500  // Number of dofs before uniform refinement
501  n_dof_orig=problem_pt->ndof();
502 
503  // Refine uniformly
504  //-----------------
505  t_start = clock();
506  problem_pt->refine_uniformly();
507  t_end = clock();
508 
509 
510  // Assess efficiency
511  //------------------
512  problem_pt->mesh_pt()->get_halo_node_stats(av_number_halo_nodes,
513  max_number_halo_nodes,
514  min_number_halo_nodes);
515  problem_pt->mesh_pt()->get_efficiency_of_mesh_distribution
516  (av_efficiency,max_efficiency,min_efficiency);
517 
518 
519  if (my_rank==0)
520  {
521  double t_tot=double(t_end-t_start)/CLOCKS_PER_SEC;
522  oomph_info << "Time for distributed adaptation [ndof="
523  << problem_pt->ndof()
524  << "]: " << t_tot << std::endl;
525 
526  // Number of dofs achieved after uniform refinement
527  n_dof=problem_pt->ndof();
528 
529  // Snippet indicating if redistribution of haloes is used or not
530  string snippet="";
531  if (!redistribute) snippet="out";
532 
533  sprintf(
534  filename,
535  "%s/two_d_distributed_refinement_np_%i_ninitialrefinement_%i_ntotalrefinement_%i_ndof_%i_with%sredistribution.dat",
536  doc_info.directory().c_str(),
537  n_proc,
538  n_refine_first,
539  n_refine_first+i+1,
540  n_dof,
541  snippet.c_str());
542  some_file.open(filename);
543  some_file << n_proc << " "
544  << n_dof_orig << " "
545  << n_dof << " "
546  << t_tot << " "
547  << av_number_halo_nodes << " "
548  << max_number_halo_nodes << " "
549  << min_number_halo_nodes << " "
550  << av_efficiency << " "
551  << max_efficiency << " "
552  << min_efficiency << " "
553  << std::endl;
554  some_file.close();
555 
556  }
557 
558 
559 
560  // Redistribute (if required)
561  //---------------------------
562  if (redistribute)
563  {
564 
565  t_start = clock();
566  bool report_stats=false;
567  doc_info.disable_doc();
568  problem_pt->prune_halo_elements_and_nodes(doc_info,
569  report_stats);
570  t_end = clock();
571  double t_tot=double(t_end-t_start)/CLOCKS_PER_SEC;
572 
573 
574  if (my_rank==0)
575  {
576 
577  oomph_info << "Av., min. max. efficiency before redistribution "
578  << av_efficiency << " "
579  << min_efficiency << " "
580  << max_efficiency << " "
581  << std::endl;
582  sprintf(
583  filename,
584  "%s/two_d_redistribution_np_%i_ninitialrefinement_%i_ntotalrefinement_%i_ndof_%i.dat",
585  doc_info.directory().c_str(),
586  n_proc,
587  n_refine_first,
588  n_refine_first+i+1,
589  n_dof);
590  some_file.open(filename);
591  some_file << n_proc << " "
592  << n_dof << " "
593  << t_tot << " "
594  << av_number_halo_nodes << " "
595  << max_number_halo_nodes << " "
596  << min_number_halo_nodes << " "
597  << av_efficiency << " "
598  << max_efficiency << " "
599  << min_efficiency << " "
600  << std::endl;
601  }
602 
603 
604  // Re-assess efficiency
605  //----------------------
606  problem_pt->mesh_pt()->get_halo_node_stats(av_number_halo_nodes,
607  max_number_halo_nodes,
608  min_number_halo_nodes);
609  problem_pt->mesh_pt()->
610  get_efficiency_of_mesh_distribution(av_efficiency,
611  max_efficiency,
612  min_efficiency);
613 
614 
615  if (my_rank==0)
616  {
617  oomph_info << "Time for redistribution [ndof="
618  << problem_pt->ndof()
619  << "]: " << t_tot << std::endl;
620 
621 
622  some_file << n_proc << " "
623  << n_dof << " "
624  << t_tot << " "
625  << av_number_halo_nodes << " "
626  << max_number_halo_nodes << " "
627  << min_number_halo_nodes << " "
628  << av_efficiency << " "
629  << max_efficiency << " "
630  << min_efficiency << " "
631  << std::endl;
632  some_file.close();
633  }
634 
635  problem_pt->mesh_pt()->
636  get_efficiency_of_mesh_distribution(av_efficiency,
637  max_efficiency,
638  min_efficiency);
639  oomph_info << "Av., min., max. efficiency after redistribution "
640  << av_efficiency << " "
641  << min_efficiency << " "
642  << max_efficiency << " "
643  << std::endl;
644  }
645 
646 
647  // Check things
648  //-------------
649  problem_pt->check_halo_schemes(quiet_doc_info);
650 
651 
652  // Solve again
653  //------------
654  if (solve)
655  {
656  // Solve again
657  problem_pt->newton_solve();
658 
659  if (doc)
660  {
661  // Doc the solution
662  problem_pt->doc_solution(doc_info);
663  }
664  }
665 
666  }
667 
668 
669  // Unrefine the distributed problem uniformly (only if not redistributed)
670  //-----------------------------------------------------------------------
671  if (!redistribute)
672  {
673  // Number of dofs before unrefinement
674  n_dof_orig=problem_pt->ndof();
675 
676 
677  t_start = clock();
678  problem_pt->unrefine_uniformly();
679  t_end = clock();
680 
681  if (my_rank==0)
682  {
683  double t_tot=double(t_end-t_start)/CLOCKS_PER_SEC;
684  oomph_info << "Time for distributed unrefinement [ndof="
685  << problem_pt->ndof()
686  << "]: " << t_tot << std::endl;
687 
688  // Number of dofs after unrefinement
689  n_dof=problem_pt->ndof();
690 
691  sprintf(
692  filename,
693  "%s/two_d_distributed_unrefinement_np_%i_ninitialrefinement_%i_ntotalrefinement_%i_ndof_%i.dat",
694  doc_info.directory().c_str(),
695  n_proc,
696  n_refine_first,
697  n_refine_first+n_refine_once_distributed,
698  n_dof);
699  some_file.open(filename);
700  some_file << n_proc << " "
701  << n_dof_orig << " "
702  << n_dof << " "
703  << t_tot << " "
704  << av_number_halo_nodes << " "
705  << max_number_halo_nodes << " "
706  << min_number_halo_nodes << " "
707  << av_efficiency << " "
708  << max_efficiency << " "
709  << min_efficiency << " "
710  << std::endl;
711  some_file.close();
712 
713  }
714 
715 
716  // Check things
717  problem_pt->check_halo_schemes(quiet_doc_info);
718 
719  // Solve again
720  if (solve)
721  {
722  // Solve again
723  problem_pt->newton_solve();
724 
725 
726  if (doc)
727  {
728  // Doc the solution
729  problem_pt->doc_solution(doc_info);
730  }
731  }
732  }
733 
734 }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Definition: optimisation/use_coarse_base_meshes/two_d_poisson_adapt.cc:149
void doc_solution(DocInfo &doc_info)
Doc the solution: doc_info contains labels/output directory etc.
Definition: optimisation/use_coarse_base_meshes/two_d_poisson_adapt.cc:354
SimpleRefineableRectangularQuadMesh< ELEMENT > * mesh_pt()
Definition: optimisation/use_coarse_base_meshes/two_d_poisson_adapt.cc:188
Definition: oomph_utilities.h:499
void disable_doc()
Disable documentation.
Definition: oomph_utilities.h:542
std::string directory() const
Output directory.
Definition: oomph_utilities.h:524
void set_directory(const std::string &directory)
Definition: oomph_utilities.cc:298
Preconditioner *& preconditioner_pt()
Access function to preconditioner.
Definition: iterative_linear_solver.h:95
void disable_doc_time()
Disable documentation of solve times.
Definition: linear_solver.h:116
int my_rank() const
my rank
Definition: communicator.h:176
int nproc() const
number of processors
Definition: communicator.h:157
void refine_uniformly(const Vector< unsigned > &nrefine_for_mesh)
Definition: problem.h:2575
unsigned long ndof() const
Return the number of dofs.
Definition: problem.h:1674
unsigned unrefine_uniformly()
Definition: problem.cc:15831
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
Definition: problem.h:1246
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
Definition: problem.h:1466
void newton_solve()
Use Newton method to solve the problem.
Definition: problem.cc:8783
Definition: trilinos_solver.h:267
unsigned & solver_type()
Access function to Solver_type.
Definition: trilinos_solver.h:442
Definition: trilinos_preconditioners.h:152
string filename
Definition: MergeRestartFiles.py:39
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
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286

References oomph::Problem::communicator_pt(), oomph::DocInfo::directory(), oomph::DocInfo::disable_doc(), oomph::LinearSolver::disable_doc_time(), RefineablePoissonProblem< ELEMENT >::doc_solution(), e(), MergeRestartFiles::filename, TanhSolnForPoisson::get_source(), i, oomph::Problem::linear_solver_pt(), RefineablePoissonProblem< ELEMENT >::mesh_pt(), oomph::OomphCommunicator::my_rank(), oomph::Problem::ndof(), oomph::Problem::newton_solve(), oomph::OomphCommunicator::nproc(), oomph::oomph_info, oomph::IterativeLinearSolver::preconditioner_pt(), oomph::Problem::refine_uniformly(), oomph::DocInfo::set_directory(), solve, oomph::TrilinosAztecOOSolver::solver_type(), oomph::Global_string_for_annotation::string(), and oomph::Problem::unrefine_uniformly().

Referenced by main().