three_d_mesh_dist.cc File Reference
#include "generic.h"
#include "poisson.h"
#include "meshes/simple_cubic_mesh.h"

Classes

class  ThreeDPoissonProblem< ELEMENT >
 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_exact_u (const Vector< double > &x, double &u)
 Exact solution as a scalar. 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 3D Poisson problem. More...
 

Function Documentation

◆ main()

int main ( int argc  ,
char **  argv 
)

Driver code for 3D Poisson problem.

771 {
772 #ifdef OOMPH_HAS_MPI
773  // Setup MPI helpers
774  MPI_Helpers::init(argc,argv);
775 #endif
776 
777  // Store command line arguments
778  CommandLineArgs::setup(argc,argv);
779 
780 
781  // Default min. number of refinements before we distribute
782  unsigned n_refine_first_min=1;
783 
784  // Default max. number of refinements before we distribute
785  unsigned n_refine_first_max=1;
786 
787  // Default min. number of uniform refinements after distribution
788  unsigned n_uniform_min=1;
789 
790  // Default max. number of uniform refinements after distribution
791  unsigned n_uniform_max=2;
792 
793  // Redistribute after uniform refinement?
794  bool redistribute=true;
795 
796 
797 
798  if (CommandLineArgs::Argc==1)
799  {
800  std::cout << "Using default settings for flags" << std::endl;
801  }
802  else if (CommandLineArgs::Argc==6)
803  {
804 
805  // Min. number of refinements before we distribute
806  n_refine_first_min=atoi(argv[1]);
807 
808  // Max. number of refinements before we distribute
809  n_refine_first_max=atoi(argv[2]);
810 
811  // Min. number of uniform refinements after distribution
812  n_uniform_min=atoi(argv[3]);
813 
814  // Max. number of uniform refinements after distribution
815  n_uniform_max=atoi(argv[4]);
816 
817  // Redistribute after uniform refinement?
818  redistribute=atoi(argv[5]);
819  }
820  else
821  {
822  oomph_info
823  << "Wrong number of input args. Specify none or five "
824  << "(n_refine_first_min/max, n_uniform_min/max, redistributon flag)"
825  << std::endl;
826  exit(1);
827  }
828 
829 
830 
831  // Tell us what we're going to do
832  oomph_info << "Run with n_refine_first_min/max, n_uniform_min/max, redistribute: "
833  << n_refine_first_min << " "
834  << n_refine_first_max << " "
835  << n_uniform_min << " "
836  << n_uniform_max << " "
837  << redistribute << " "
838  << std::endl;
839 
840 
841  // switch off output for all but one processor
842 // if (my_rank>0)
843 // {
844 // oomph_info.stream_pt() = &oomph_nullstream;
845 // }
846 
847 
848  // Solve and self test?
849  bool solve=true; // (andy) only testing mesh distribution here
850  bool doc=true;
851 
852  // Write headers for analysis
853  ofstream some_file;
854  some_file.open("RESLT/three_d_initial_refinement_header.dat");
855  some_file << "VARIABLES= \"n<SUB>refine first</SUB>\","
856  << "\"n<SUB>dof orig</SUB>\","
857  << "\"n<SUB>dof</SUB>\","
858  << "\"t<SUB>serial adapt</SUB>\""
859  << std::endl;
860  some_file.close();
861 
862 
863  some_file.open("RESLT/three_d_initial_distr_header.dat");
864  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
865  << "\"n<SUB>dof</SUB>\","
866  << "\"t<SUB>distr</SUB>\","
867  << "\"average n<SUB>halo nodes</SUB>\","
868  << "\"max. n<SUB>halo nodes</SUB>\","
869  << "\"min. n<SUB>halo nodes</SUB>\","
870  << "\"average efficiency\","
871  << "\"max. efficiency\","
872  << "\"min. efficiency\""
873  << std::endl;
874  some_file.close();
875 
876 
877  some_file.open("RESLT/three_d_distributed_refinement_header.dat");
878  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
879  << "\"n<SUB>dof orig</SUB>\","
880  << "\"n<SUB>dof</SUB>\","
881  << "\"t<SUB>distributed refinement</SUB>\","
882  << "\"average n<SUB>halo nodes</SUB>\","
883  << "\"max. n<SUB>halo nodes</SUB>\","
884  << "\"min. n<SUB>halo nodes</SUB>\","
885  << "\"average efficiency\","
886  << "\"max. efficiency\","
887  << "\"min. efficiency\""
888  << std::endl;
889  some_file.close();
890 
891 
892  some_file.open("RESLT/three_d_redistribution_header.dat");
893  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
894  << "\"n<SUB>dof</SUB>\","
895  << "\"t<SUB>redistribution</SUB>\","
896  << "\"average n<SUB>halo nodes</SUB>\","
897  << "\"max. n<SUB>halo nodes</SUB>\","
898  << "\"min. n<SUB>halo nodes</SUB>\","
899  << "\"average efficiency\","
900  << "\"max. efficiency\","
901  << "\"min. efficiency\""
902  << std::endl;
903  some_file.close();
904 
905 
906 
907  some_file.open("RESLT/three_d_distributed_unrefinement_header.dat");
908  some_file << "VARIABLES= \"n_<SUB>p</SUB>\","
909  << "\"n<SUB>dof orig</SUB>\","
910  << "\"n<SUB>dof</SUB>\","
911  << "\"t<SUB>distributed unrefinement</SUB>\","
912  << "\"average n<SUB>halo nodes</SUB>\","
913  << "\"max. n<SUB>halo nodes</SUB>\","
914  << "\"min. n<SUB>halo nodes</SUB>\","
915  << "\"average efficiency\","
916  << "\"max. efficiency\","
917  << "\"min. efficiency\""
918  << std::endl;
919  some_file.close();
920 
921 
922  // Test the procedures in parallel mode
923  for (unsigned i=n_refine_first_min;i<=n_refine_first_max;i++)
924 
925  {
926  for (unsigned j=n_uniform_min;j<=n_uniform_max;j++)
927  {
928  parallel_test(i,j,redistribute,solve,doc);
929  }
930  }
931 
932 #ifdef OOMPH_HAS_MPI
933  MPI_Helpers::finalize();
934 #endif
935 
936 }
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
void parallel_test(const unsigned &n_refine_first, const unsigned &n_refine_once_distributed, const bool &redistribute, const bool &solve, const bool &doc)
Definition: three_d_mesh_dist.cc:310
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

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.

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