HGridOptimiser Class Reference

#include <HGridOptimiser.h>

Public Member Functions

void initialise (const MercuryBase &problem, unsigned int numberOfCells, int verbosity)
 
void initialisePolyFunc (double omega, std::vector< double > &coeff, unsigned int numberOfCells, int verbosity)
 
unsigned int radius2Cell (double r)
 Assigns a BaseParticle of given radius to a certain cell. More...
 
unsigned int radius2IntCell (double r)
 
double intCell2Min (unsigned int i)
 
double intCell2Max (unsigned int i)
 
double cell2Min (unsigned int i)
 Computes the left bound of the cell with given ordinal number. More...
 
double cell2Max (unsigned int i)
 Computes the right bound of the cell with given ordinal number. More...
 
double pdfIntCell (double start, double end, unsigned int i, int p)
 
double pdfInt (double start, double end, int power)
 
double diffPdfInt (double x, int power)
 diff(int(f(r)*r^power*dr,r=s..e)/int(f(r)*dr,r=0..omega),e)=f(e)*e^power/int(f(r)*dr,r=0..omega) More...
 
double expectedCellsIntegralCellNumerator (double start, double end, unsigned int i, int p, double h)
 
double diffHExpectedCellsIntegralCellNumerator (double start, double end, unsigned int i, int p, double h)
 
double expectedCellsIntegralCellDenominator (double start, double end, unsigned int i)
 
double expectedCellsIntegral (double start, double end, int p, double h)
 
double diffStartExpectedCellsIntegral (double start, double end, int p, double h)
 
double diffEndExpectedCellsIntegral (double start, double end, int p, double h)
 
double diffHExpectedCellsIntegral (double start, double end, int p, double h)
 
double calculateWork (std::vector< double > &hGridCellSizes, HGridMethod method, int verbosity)
 The amount of work that has to be done to run a simulation using the HGrid, in steps. More...
 
void calculateDiffWork (std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, HGridMethod method, int verbosity)
 
void calcDfDx (std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, HGridMethod method, int verbosity)
 
double checkLimit (std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, int verbosity)
 
void applyStep (std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, double stepsize, int verbosity)
 
double goldenSectionSearch (std::vector< double > &startHGridCellSizes, std::vector< double > &searchDirection, double min, double cur, double max, HGridMethod method, int verbosity)
 
void getOptimalDistribution (std::vector< double > &hGridCellSizes, unsigned int numberOfLevels, HGridMethod method, int verbosity)
 
void histNumberParticlesPerCell (std::vector< double > &hGridCellSizes)
 

Private Attributes

unsigned int numCells_
 Number of cells, usually called levels in the HGrid. More...
 
double rMin_
 Radius of the smallest particle, "rounded" to the largest double that is smaller than the radius of each particle. More...
 
double rMax_
 Radius of the largest particle, "rounded" to the smallest double that is larger than the radius of each particle. More...
 
double length_
 The weighted length of the domain. More...
 
double cellCheckOverContactCheckRatio_
 The ratio of the time required for a single geometric contact detection over the time required to retrieve information from a cell. This seems to be only used for checking the effort required by the HGrid, not to compute the cell sizes. More...
 
unsigned int dimension_
 The dimension of the system, usually 3, sometimes 2 or 1. More...
 
std::vector< doublecellN_
 
std::vector< doubleintCellN
 

Detailed Description

Todo:
Find out what this class does and document it.

Member Function Documentation

◆ applyStep()

void HGridOptimiser::applyStep ( std::vector< double > &  hGridCellSizes,
std::vector< double > &  dfdx,
double  stepsize,
int  verbosity 
)
947 {
948  if (verbosity > 0)
949  {
950  logger(VERBOSE, "Apply step:\n", Flusher::NO_FLUSH);
951  }
952  for (unsigned int i = 0; i < hGridCellSizes.size() - 1; i++)
953  {
954  hGridCellSizes[i] += stepsize * dfdx[i];
955  if (verbosity > 0)
956  {
957  logger(INFO, "hGridCellSizes[i]+%*%=%", stepsize, dfdx[i], hGridCellSizes[i]);
958  }
959  }
960 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ INFO
@ VERBOSE

References i, INFO, logger, NO_FLUSH, and VERBOSE.

Referenced by getOptimalDistribution(), and goldenSectionSearch().

◆ calcDfDx()

void HGridOptimiser::calcDfDx ( std::vector< double > &  hGridCellSizes,
std::vector< double > &  dfdx,
HGridMethod  method,
int  verbosity 
)
859 {
860  if (verbosity > 0)
861  {
862  logger(VERBOSE, "calcDfDx\n", Flusher::NO_FLUSH);
863  }
864  double W = calculateWork(hGridCellSizes, method, verbosity - 1);
865  double dx = 1e-7;
866  double nW;
867  dfdx.clear();
868  for (unsigned int i = 0; i < hGridCellSizes.size(); i++)
869  {
870  hGridCellSizes[i] += dx;
871  nW = calculateWork(hGridCellSizes, method, verbosity - 1);
872  dfdx.push_back((nW - W) / dx);
873  hGridCellSizes[i] -= dx;
874  if (verbosity > 0)
875  {
876  logger(INFO, "i= Value=% Change=% dfdx=%", i, hGridCellSizes[i], nW - W, dfdx.back());
877  }
878  }
879 }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
double calculateWork(std::vector< double > &hGridCellSizes, HGridMethod method, int verbosity)
The amount of work that has to be done to run a simulation using the HGrid, in steps.
Definition: HGridOptimiser.cc:707
@ W
Definition: quadtree.h:63

References calculateWork(), e(), i, INFO, logger, NO_FLUSH, VERBOSE, and oomph::QuadTreeNames::W.

◆ calculateDiffWork()

void HGridOptimiser::calculateDiffWork ( std::vector< double > &  hGridCellSizes,
std::vector< double > &  dfdx,
HGridMethod  method,
int  verbosity 
)
444 {
445  unsigned int NLevels = hGridCellSizes.size() - 1;
446  unsigned int NParams = hGridCellSizes.size();
447 
448  if (verbosity > 0)
449  {
450  logger(INFO, "Length scale=%\n", Flusher::NO_FLUSH, length_);
451  logger(INFO, "Level sizes:", Flusher::NO_FLUSH);
452  for (unsigned int i = 0; i < NParams; i++)
453  {
454  logger(INFO, " %", hGridCellSizes[i], Flusher::NO_FLUSH);
455  }
456  logger(INFO, "");
457  }
458 
459  std::vector<double> particlesPerLevel;
460  for (unsigned int i = 0; i < NLevels; i++)
461  {
462  particlesPerLevel.push_back(pdfInt(0.5 * hGridCellSizes[i], 0.5 * hGridCellSizes[i + 1], 0));
463  if (particlesPerLevel.back() < 0)
464  {
465  particlesPerLevel.back() = 0;
466  }
467  }
468  if (verbosity > 0)
469  {
470  logger(INFO, "Particles per level:\n", Flusher::NO_FLUSH);
471  for (unsigned int i = 0; i < NLevels; i++)
472  {
473  logger(INFO, " %", particlesPerLevel[i], Flusher::NO_FLUSH);
474  }
475  logger(INFO, "");
476  }
477 
478  //How changes particlesPerLeve[i] when hGridCellSize[j] is changed
479  std::vector<std::vector<double> > diffParticlesPerLevel;
480  diffParticlesPerLevel.resize(NLevels);
481  for (unsigned int i = 0; i < NLevels; i++)
482  {
483  for (unsigned int j = 0; j < NParams; j++)
484  {
485  diffParticlesPerLevel[i].push_back(0.0);
486  if (j == i)
487  {
488  diffParticlesPerLevel[i][j] += -0.5 * diffPdfInt(0.5 * hGridCellSizes[i], 0);
489  }
490  if (j == i + 1)
491  {
492  diffParticlesPerLevel[i][j] += 0.5 * diffPdfInt(0.5 * hGridCellSizes[i + 1], 0);
493  }
494  }
495  }
496  if (verbosity > 0)
497  {
498  logger(INFO, "Diff Particles per level: \n", Flusher::NO_FLUSH);
499  for (unsigned int i = 0; i < NLevels; i++)
500  {
501  for (unsigned int j = 0; j < NParams; j++)
502  {
503  logger(INFO, " %.12", diffParticlesPerLevel[i][j], Flusher::NO_FLUSH);
504  }
505  logger(INFO, "");
506  }
507  }
508 
509  std::vector<double> cellsPerLevel;
510  for (unsigned int i = 0; i < NLevels; i++)
511  {
512  cellsPerLevel.push_back(pow(length_ / hGridCellSizes[i + 1], dimension_));
513  }
514  if (verbosity > 0)
515  {
516  logger(INFO, "Cells per level:", Flusher::NO_FLUSH);
517  for (unsigned int i = 0; i < NLevels; i++)
518  {
519  logger(INFO, " %", cellsPerLevel[i], Flusher::NO_FLUSH);
520  }
521  logger(INFO, "");
522  }
523 
524  //How changes cellsPerLevel[i] when hGridCellSize[j] is changed
525  std::vector<std::vector<double> > diffCellsPerLevel;
526  diffCellsPerLevel.resize(hGridCellSizes.size());
527  for (unsigned int i = 0; i < NLevels; i++)
528  {
529  for (unsigned int j = 0; j < NParams; j++)
530  {
531  if (j == i + 1)
532  {
533  diffCellsPerLevel[i].push_back(
534  -pow(length_ / hGridCellSizes[i + 1], dimension_) * dimension_ / hGridCellSizes[i + 1]);
535  }
536  else
537  {
538  diffCellsPerLevel[i].push_back(0.0);
539  }
540  }
541  }
542  if (verbosity > 0)
543  {
544  logger(INFO, "Diff Cells per level: \n", Flusher::NO_FLUSH);
545  for (unsigned int i = 0; i < NLevels; i++)
546  {
547  for (unsigned int j = 0; j < NParams; j++)
548  {
549  logger(INFO, " %.12", diffCellsPerLevel[i][j], Flusher::NO_FLUSH);
550  }
551  logger(INFO, "");
552  }
553  }
554 
555  std::vector<double> particlesPerCell;
556  for (unsigned int i = 0; i < NLevels; i++)
557  {
558  particlesPerCell.push_back(particlesPerLevel[i] / cellsPerLevel[i]);
559  }
560  if (verbosity > 0)
561  {
562  logger(INFO, "Particles per cell:", Flusher::NO_FLUSH);
563  for (double i : particlesPerCell)
564  {
565  logger(INFO, " %", i, Flusher::NO_FLUSH);
566  }
567  logger(INFO, "");
568  }
569 
570  //How changes particlesPerCell[i] when hGridCellSize[j] is changed
571  std::vector<std::vector<double> > diffParticlesPerCell;
572  diffParticlesPerCell.resize(NLevels);
573  for (unsigned int i = 0; i < NLevels; i++)
574  {
575  for (unsigned int j = 0; j < NParams; j++)
576  {
577  diffParticlesPerCell[i].push_back(
578  (diffParticlesPerLevel[i][j] * cellsPerLevel[i] - particlesPerLevel[i] * diffCellsPerLevel[i][j]) /
579  (cellsPerLevel[i] * cellsPerLevel[i]));
580  }
581  }
582  if (verbosity > 0)
583  {
584  logger(INFO, "Diff Particles per Cell: \n", Flusher::NO_FLUSH);
585  for (unsigned int i = 0; i < NLevels; i++)
586  {
587  for (unsigned int j = 0; j < NParams; j++)
588  {
589  logger(INFO, " %.12", diffParticlesPerCell[i][j], Flusher::NO_FLUSH);
590  }
591  logger(INFO, "");
592  }
593  }
594 
595  double contactWork = 0, overheadWork = 0;
596  std::vector<double> diffContactWork;
597  std::vector<double> diffOverheadWork;
598  diffContactWork.resize(NParams);
599  diffOverheadWork.resize(NParams);
600  for (unsigned int j = 0; j < NParams; j++)
601  {
602  diffContactWork[j] = 0;
603  diffOverheadWork[j] = 0;
604  }
605 
606  for (unsigned int i = 0; i < NLevels; i++)
607  {
608  contactWork += 0.5 * pow(3, dimension_) * particlesPerCell[i] * particlesPerLevel[i];
609  overheadWork += 0.5 * (pow(3, dimension_) + 1) * particlesPerLevel[i];
610  for (unsigned int j = 0; j < NParams; j++)
611  {
612  diffContactWork[j] += 0.5 * pow(3, dimension_) * (diffParticlesPerCell[i][j] * particlesPerLevel[i] +
613  particlesPerCell[i] * diffParticlesPerLevel[i][j]);
614  diffOverheadWork[j] += 0.5 * (pow(3, dimension_) + 1) * diffParticlesPerLevel[i][j];
615  }
616 
617  unsigned int startJ, endJ;
618  switch (method)
619  {
620  case BOTTOMUP:
621  {
622  startJ = i + 1;
623  endJ = NLevels;
624  break;
625  }
626  case TOPDOWN:
627  {
628  startJ = 0;
629  endJ = i;
630  break;
631  }
632  }
633  for (unsigned int j = startJ; j < endJ; j++)
634  {
635  double numberOfCellToCheck;
636  numberOfCellToCheck = expectedCellsIntegral(0.5 * hGridCellSizes[i], 0.5 * hGridCellSizes[i + 1],
637  dimension_, hGridCellSizes[j + 1]);
638 
639  std::vector<double> diffNumberOfCellToCheck;
640  for (unsigned int k = 0; k < NParams; k++)
641  {
642  diffNumberOfCellToCheck.push_back(0.0);
643  if (k == i)
644  {
645  diffNumberOfCellToCheck[k] += 0.5 * diffStartExpectedCellsIntegral(0.5 * hGridCellSizes[i],
646  0.5 * hGridCellSizes[i + 1],
647  dimension_,
648  hGridCellSizes[j + 1]);
649  }
650  if (k == i + 1)
651  {
652  diffNumberOfCellToCheck[k] += 0.5 * diffEndExpectedCellsIntegral(0.5 * hGridCellSizes[i],
653  0.5 * hGridCellSizes[i + 1],
654  dimension_, hGridCellSizes[j + 1]);
655  }
656  if (k == j + 1)
657  {
658  diffNumberOfCellToCheck[k] += diffHExpectedCellsIntegral(0.5 * hGridCellSizes[i],
659  0.5 * hGridCellSizes[i + 1], dimension_,
660  hGridCellSizes[j + 1]);
661  }
662  }
663  contactWork += particlesPerLevel[i] * numberOfCellToCheck * particlesPerCell[j];
664  overheadWork += particlesPerLevel[i] * numberOfCellToCheck;
665  //std::cout<<"i= "<<i<<" j= "<<j<<" NumberOfCellToCheck= "<<numberOfCellToCheck<<" diffNumberOfCellToCheck[2]= "<<diffNumberOfCellToCheck[2]<<std::endl;
666  for (unsigned int k = 0; k < NParams; k++)
667  {
668  diffContactWork[k] += (diffParticlesPerLevel[i][k] * numberOfCellToCheck * particlesPerCell[j] +
669  particlesPerLevel[i] * diffNumberOfCellToCheck[k] * particlesPerCell[j] +
670  particlesPerLevel[i] * numberOfCellToCheck * diffParticlesPerCell[j][k]);
671  diffOverheadWork[k] += (diffParticlesPerLevel[i][k] * numberOfCellToCheck +
672  particlesPerLevel[i] * diffNumberOfCellToCheck[k]);
673  }
674  }
675  }
676  if (verbosity > 0)
677  {
678  logger(INFO, "Contact work: %\n"
679  "Overhead work: %\n"
680  "Sum work: %\n",
681  contactWork, cellCheckOverContactCheckRatio_ * overheadWork,
682  contactWork + cellCheckOverContactCheckRatio_ * overheadWork, Flusher::NO_FLUSH);
683  for (unsigned int j = 0; j < NParams; j++)
684  {
685  logger(INFO, "diff Contactwork: %", diffContactWork[j], Flusher::NO_FLUSH);
686  }
687  logger(INFO, "\ndiff Overheadwork: ", Flusher::NO_FLUSH);
688  for (unsigned int j = 0; j < NParams; j++)
689  {
690  logger(INFO, " %", cellCheckOverContactCheckRatio_ * diffOverheadWork[j], Flusher::NO_FLUSH);
691  }
692  logger(INFO, "\ndiff sum: ", Flusher::NO_FLUSH);
693  for (unsigned int j = 0; j < NParams; j++)
694  {
695  logger(INFO, " %", diffContactWork[j] + cellCheckOverContactCheckRatio_ * diffOverheadWork[j],
697  }
698  logger(INFO, "");
699  }
700  dfdx.clear();
701  for (unsigned int j = 0; j < NParams; j++)
702  {
703  dfdx.push_back(diffContactWork[j] + cellCheckOverContactCheckRatio_ * diffOverheadWork[j]);
704  }
705 }
@ BOTTOMUP
Definition: MercuryBase.h:24
@ TOPDOWN
Definition: MercuryBase.h:24
double pdfInt(double start, double end, int power)
Definition: HGridOptimiser.cc:203
double diffStartExpectedCellsIntegral(double start, double end, int p, double h)
Definition: HGridOptimiser.cc:332
unsigned int dimension_
The dimension of the system, usually 3, sometimes 2 or 1.
Definition: HGridOptimiser.h:185
double diffPdfInt(double x, int power)
diff(int(f(r)*r^power*dr,r=s..e)/int(f(r)*dr,r=0..omega),e)=f(e)*e^power/int(f(r)*dr,...
Definition: HGridOptimiser.cc:240
double expectedCellsIntegral(double start, double end, int p, double h)
Definition: HGridOptimiser.cc:302
double diffEndExpectedCellsIntegral(double start, double end, int p, double h)
Definition: HGridOptimiser.cc:373
double diffHExpectedCellsIntegral(double start, double end, int p, double h)
Definition: HGridOptimiser.cc:413
double cellCheckOverContactCheckRatio_
The ratio of the time required for a single geometric contact detection over the time required to ret...
Definition: HGridOptimiser.h:181
double length_
The weighted length of the domain.
Definition: HGridOptimiser.h:174
char char char int int * k
Definition: level2_impl.h:374
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References BOTTOMUP, cellCheckOverContactCheckRatio_, diffEndExpectedCellsIntegral(), diffHExpectedCellsIntegral(), diffPdfInt(), diffStartExpectedCellsIntegral(), dimension_, expectedCellsIntegral(), i, INFO, j, k, length_, logger, NO_FLUSH, pdfInt(), Eigen::bfloat16_impl::pow(), and TOPDOWN.

Referenced by getOptimalDistribution().

◆ calculateWork()

double HGridOptimiser::calculateWork ( std::vector< double > &  hGridCellSizes,
HGridMethod  method,
int  verbosity 
)

The amount of work that has to be done to run a simulation using the HGrid, in steps.

708 {
709  unsigned int NLevels = hGridCellSizes.size() - 1;
710  unsigned int NParams = hGridCellSizes.size();
711 
712  if (verbosity > 1)
713  {
714  logger(INFO, "Length scale=%", length_);
715  }
716  if (verbosity > 0)
717  {
718  logger(INFO, "Level sizes:\n", Flusher::NO_FLUSH);
719  for (unsigned int i = 0; i < NParams; i++)
720  {
721  logger(INFO, "%.10 ", hGridCellSizes[i], Flusher::NO_FLUSH);
722  }
723  logger(INFO, "");
724  }
725 
726  std::vector<double> particlesPerLevel;
727  for (unsigned int i = 0; i < NLevels; i++)
728  {
729  particlesPerLevel.push_back(pdfInt(0.5 * hGridCellSizes[i], 0.5 * hGridCellSizes[i + 1], 0));
730  if (particlesPerLevel.back() < 0)
731  {
732  particlesPerLevel.back() = 0;
733  }
734  }
735  if (verbosity > 0)
736  {
737  logger(INFO, "Particles per level:\n", Flusher::NO_FLUSH);
738  for (unsigned int i = 0; i < NLevels; i++)
739  {
740  logger(INFO, "%.10 ", particlesPerLevel[i], Flusher::NO_FLUSH);
741  }
742  logger(INFO, "");
743  }
744 
745  std::vector<double> cellsPerLevel;
746  for (unsigned int i = 0; i < NLevels; i++)
747  {
748  cellsPerLevel.push_back(pow(length_ / hGridCellSizes[i + 1], dimension_));
749  }
750  if (verbosity > 1)
751  {
752  logger(INFO, "Cells per level:\n", Flusher::NO_FLUSH);
753  for (unsigned int i = 0; i < NLevels; i++)
754  {
755  logger(INFO, "%.10 ", cellsPerLevel[i], Flusher::NO_FLUSH);
756  }
757  logger(INFO, "");
758  }
759 
760  std::vector<double> particlesPerCell;
761  for (unsigned int i = 0; i < NLevels; i++)
762  {
763  particlesPerCell.push_back(particlesPerLevel[i] / cellsPerLevel[i]);
764  }
765  if (verbosity > 1)
766  {
767  logger(INFO, "Particles per cell:\n", Flusher::NO_FLUSH);
768  for (double i : particlesPerCell)
769  {
770  logger(INFO, "%.10 ", i, Flusher::NO_FLUSH);
771  }
772  logger(INFO, "");
773  }
774 
775  std::vector<std::vector<double> > contactWork;
776  std::vector<std::vector<double> > overheadWork;
777  contactWork.resize(NLevels);
778  overheadWork.resize(NLevels);
779  for (unsigned int i = 0; i < NLevels; i++)
780  {
781  contactWork[i].resize(NLevels);
782  overheadWork[i].resize(NLevels);
783  for (unsigned int j = 0; j < NLevels; j++)
784  {
785  contactWork[i][j] = 0;
786  overheadWork[i][j] = 0;
787  }
788  }
789 
790  for (unsigned int i = 0; i < NLevels; i++)
791  {
792  contactWork[i][i] += 0.5 * pow(3, dimension_) * particlesPerCell[i] * particlesPerLevel[i];
793  overheadWork[i][i] += 0.5 * (pow(3, dimension_) + 1) * particlesPerLevel[i];
794 
795  unsigned int startJ, endJ;
796  switch (method)
797  {
798  case BOTTOMUP:
799  {
800  startJ = i + 1;
801  endJ = NLevels;
802  break;
803  }
804  case TOPDOWN:
805  {
806  startJ = 0;
807  endJ = i;
808  break;
809  }
810  }
811  for (unsigned int j = startJ; j < endJ; j++)
812  {
813  double numberOfCellToCheck;
814  numberOfCellToCheck = expectedCellsIntegral(0.5 * hGridCellSizes[i], 0.5 * hGridCellSizes[i + 1],
815  dimension_, hGridCellSizes[j + 1]);
816  contactWork[i][j] += particlesPerLevel[i] * numberOfCellToCheck * particlesPerCell[j];
817  overheadWork[i][j] += particlesPerLevel[i] * numberOfCellToCheck;
818 
819  }
820  }
821 
822  double totalContactWork = 0, totalOverheadWork = 0;
823  for (unsigned int i = 0; i < NLevels; i++)
824  {
825  for (unsigned int j = 0; j < NLevels; j++)
826  {
827  totalContactWork += contactWork[i][j];
828  totalOverheadWork += overheadWork[i][j];
829  }
830  }
831 
832  if (verbosity > 0)
833  {
834  logger(INFO, "Contact work: %\n", Flusher::NO_FLUSH, totalContactWork);
835  for (unsigned int i = 0; i < NLevels; i++)
836  {
837  for (unsigned int j = 0; j < NLevels; j++)
838  {
839  logger(INFO, "%.10 ", contactWork[i][j], Flusher::NO_FLUSH);
840  }
841  logger(INFO, "");
842  }
843  logger(INFO, "Overhead work: %\n", Flusher::NO_FLUSH, totalOverheadWork);
844  for (unsigned int i = 0; i < NLevels; i++)
845  {
846  for (unsigned int j = 0; j < NLevels; j++)
847  {
848  logger(INFO, "%.10 ", overheadWork[i][j], Flusher::NO_FLUSH);
849  }
850  logger(INFO, "");
851  }
852  logger(INFO, "Total work: %", totalContactWork + totalOverheadWork);
853  }
854  return totalContactWork + cellCheckOverContactCheckRatio_ * totalOverheadWork;
855 }

References BOTTOMUP, cellCheckOverContactCheckRatio_, dimension_, expectedCellsIntegral(), i, INFO, j, length_, logger, NO_FLUSH, pdfInt(), Eigen::bfloat16_impl::pow(), and TOPDOWN.

Referenced by calcDfDx(), getOptimalDistribution(), and goldenSectionSearch().

◆ cell2Max()

double HGridOptimiser::cell2Max ( unsigned int  i)

Computes the right bound of the cell with given ordinal number.

Computes the right bound of the cell with given ordinal number.

188 {
189  return rMin_ + (rMax_ - rMin_) * (i + 1) / numCells_;
190 }
unsigned int numCells_
Number of cells, usually called levels in the HGrid.
Definition: HGridOptimiser.h:156
double rMax_
Radius of the largest particle, "rounded" to the smallest double that is larger than the radius of ea...
Definition: HGridOptimiser.h:166
double rMin_
Radius of the smallest particle, "rounded" to the largest double that is smaller than the radius of e...
Definition: HGridOptimiser.h:161

References i, numCells_, rMax_, and rMin_.

Referenced by initialise(), and initialisePolyFunc().

◆ cell2Min()

double HGridOptimiser::cell2Min ( unsigned int  i)

Computes the left bound of the cell with given ordinal number.

Computes the left bound of the cell with given ordinal number.

180 {
181  return rMin_ + (rMax_ - rMin_) * i / numCells_;
182 }

References i, numCells_, rMax_, and rMin_.

Referenced by initialise(), and initialisePolyFunc().

◆ checkLimit()

double HGridOptimiser::checkLimit ( std::vector< double > &  hGridCellSizes,
std::vector< double > &  dfdx,
int  verbosity 
)
882 {
883  if (verbosity > 0)
884  {
885  logger(VERBOSE, "checkLimits part 1 remove levels");
886  }
887 
888  dfdx[0] = 0;
889  dfdx.back() = 0;
890  for (unsigned int i = 1; i < hGridCellSizes.size(); i++)
891  {
892  if (std::abs(hGridCellSizes[i - 1] - hGridCellSizes[i]) < 1e-6)
893  {
894  if (dfdx[i - 1] < dfdx[i])
895  {
896  if (verbosity > 0)
897  {
898  logger(INFO, "Remove level %", Flusher::NO_FLUSH, i);
899  }
900  if (i > 0.5 * hGridCellSizes.size())
901  {
902  hGridCellSizes.erase(hGridCellSizes.begin() + i - 1);
903  dfdx.erase(dfdx.begin() + i - 1);
904  }
905  else
906  {
907  hGridCellSizes.erase(hGridCellSizes.begin() + i);
908  dfdx.erase(dfdx.begin() + i);
909  }
910  i--;
911  }
912  }
913  }
914 
915  if (verbosity > 0)
916  {
917  logger(VERBOSE, "checkLimits part 2 calculate limit\n", Flusher::NO_FLUSH);
918  for (unsigned int i = 0; i < hGridCellSizes.size(); i++)
919  {
920  logger(INFO, "i=% Value=% dfdx=%\n", Flusher::NO_FLUSH, i, hGridCellSizes[i], dfdx[i]);
921  }
922  }
923  double maxStepSize = -std::numeric_limits<double>::max();
924  double nmax;
925  for (unsigned int i = 1; i < hGridCellSizes.size(); i++)
926  {
927  nmax = (hGridCellSizes[i - 1] - hGridCellSizes[i]) / (dfdx[i] - dfdx[i - 1]);
928  if (verbosity > 0)
929  {
930  logger(INFO, "Max f=% because otherwise %+x*% > %+x*%\n", Flusher::NO_FLUSH,
931  nmax, hGridCellSizes[i - 1], dfdx[i - 1], hGridCellSizes[i], dfdx[i]);
932  }
933  if (nmax < 0)
934  {
935  maxStepSize = std::max(nmax, maxStepSize);
936  }
937  }
938  if (verbosity > 0)
939  {
940  logger(INFO, "maxStepSize=%", maxStepSize);
941  }
942  return maxStepSize;
943 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
#define max(a, b)
Definition: datatypes.h:23

References abs(), e(), i, INFO, logger, max, NO_FLUSH, and VERBOSE.

Referenced by getOptimalDistribution().

◆ diffEndExpectedCellsIntegral()

double HGridOptimiser::diffEndExpectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)
374 {
375  unsigned int startCell = radius2IntCell(start);
376  unsigned int endCell = radius2IntCell(end);
377 
378  double numerator = 0;
379  double denominator = 0;
380 
381  double a = (intCellN[endCell + 1] - intCellN[endCell]) / (intCell2Max(endCell) - intCell2Min(endCell));
382  double b = (intCellN[endCell] * intCell2Max(endCell) - intCellN[endCell + 1] * intCell2Min(endCell)) /
383  (intCell2Max(endCell) - intCell2Min(endCell));
384 
385  double diffTeller = (
386  2.0 / h * p * std::pow(2.0 * (end + h) / h, p - 1) * (a * p * end - a * h + a * end + b * p + 2 * b) *
387  (end + h) / ((p + 1) * (p + 2)) +
388  std::pow(2.0 * (end + h) / h, p) * (a * p + a) * (end + h) / ((p + 1) * (p + 2)) +
389  std::pow(2.0 * (end + h) / h, p) * (a * p * end - a * h + a * end + b * p + 2 * b) / ((p + 1) * (p + 2)));
390  double diffNoemer = (a * end + b);
391  if (startCell == endCell)
392  {
393  numerator = expectedCellsIntegralCellNumerator(start, end, startCell, p, h);
394  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
395  }
396  else
397  {
398  numerator = expectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
399  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
400  for (unsigned int i = startCell + 1; i < endCell; i++)
401  {
404  }
405  numerator += expectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
406  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
407 
408  }
409  //std::cout<<"new: numerator="<<numerator<<" denominator="<<denominator<<" diffTeller="<<diffTeller<<" diffNoemer="<<diffNoemer<<std::endl;
410  return (diffTeller * denominator - numerator * diffNoemer) / (denominator * denominator);
411 }
float * p
Definition: Tutorial_Map_using.cpp:9
Scalar * b
Definition: benchVecAdd.cpp:17
double expectedCellsIntegralCellNumerator(double start, double end, unsigned int i, int p, double h)
Definition: HGridOptimiser.cc:254
std::vector< double > intCellN
Definition: HGridOptimiser.h:191
double expectedCellsIntegralCellDenominator(double start, double end, unsigned int i)
Definition: HGridOptimiser.cc:291
unsigned int radius2IntCell(double r)
Definition: HGridOptimiser.cc:152
double intCell2Min(unsigned int i)
Definition: HGridOptimiser.cc:160
double intCell2Max(unsigned int i)
Definition: HGridOptimiser.cc:168
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
const Scalar * a
Definition: level2_cplx_impl.h:32
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243

References a, b, Eigen::placeholders::end, expectedCellsIntegralCellDenominator(), expectedCellsIntegralCellNumerator(), i, intCell2Max(), intCell2Min(), intCellN, p, Eigen::bfloat16_impl::pow(), radius2IntCell(), and oomph::CumulativeTimings::start().

Referenced by calculateDiffWork().

◆ diffHExpectedCellsIntegral()

double HGridOptimiser::diffHExpectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)
414 {
415  unsigned int startCell = radius2IntCell(start);
416  unsigned int endCell = radius2IntCell(end);
417 
418  double denominator = 0;
419  double diffTeller = 0;
420 
421  if (startCell == endCell)
422  {
423  diffTeller = diffHExpectedCellsIntegralCellNumerator(start, end, startCell, p, h);
424  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
425  }
426  else
427  {
428  diffTeller = diffHExpectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
429  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
430  for (unsigned int i = startCell + 1; i < endCell; i++)
431  {
434  }
435  diffTeller += diffHExpectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
436  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
437  }
438  return diffTeller / denominator;
439 }
double diffHExpectedCellsIntegralCellNumerator(double start, double end, unsigned int i, int p, double h)
Definition: HGridOptimiser.cc:269

References diffHExpectedCellsIntegralCellNumerator(), Eigen::placeholders::end, expectedCellsIntegralCellDenominator(), i, intCell2Max(), intCell2Min(), p, radius2IntCell(), and oomph::CumulativeTimings::start().

Referenced by calculateDiffWork().

◆ diffHExpectedCellsIntegralCellNumerator()

double HGridOptimiser::diffHExpectedCellsIntegralCellNumerator ( double  start,
double  end,
unsigned int  i,
int  p,
double  h 
)
270 {
271  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
272  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
273  double r;
274  r = start;
275  //double min =std::pow(2.0*r/h+2.0,p)*(a*p*r-a*h+a*r+b*p+2*b)*(r+h)/((p+1)*(p+2));
276  double min =
277  (-2.0 * r / h / h * p * std::pow(2.0 * r / h + 2.0, p - 1) * (a * p * r - a * h + a * r + b * p + 2 * b) *
278  (r + h) +
279  -std::pow(2.0 * r / h + 2.0, p) * a * (r + h) +
280  std::pow(2.0 * r / h + 2.0, p) * (a * p * r - a * h + a * r + b * p + 2 * b)) / ((p + 1) * (p + 2));
281  r = end;
282  //double plus=std::pow(2.0*r/h+2.0,p)*(a*p*r-a*h+a*r+b*p+2*b)*(r+h)/((p+1)*(p+2));
283  double plus =
284  (-2.0 * r / h / h * p * std::pow(2.0 * r / h + 2.0, p - 1) * (a * p * r - a * h + a * r + b * p + 2 * b) *
285  (r + h) +
286  -std::pow(2.0 * r / h + 2.0, p) * a * (r + h) +
287  std::pow(2.0 * r / h + 2.0, p) * (a * p * r - a * h + a * r + b * p + 2 * b)) / ((p + 1) * (p + 2));
288  return plus - min;
289 }
#define min(a, b)
Definition: datatypes.h:22
r
Definition: UniformPSDSelfTest.py:20

References a, b, Eigen::placeholders::end, i, intCell2Max(), intCell2Min(), intCellN, min, p, Eigen::bfloat16_impl::pow(), UniformPSDSelfTest::r, and oomph::CumulativeTimings::start().

Referenced by diffHExpectedCellsIntegral().

◆ diffPdfInt()

double HGridOptimiser::diffPdfInt ( double  x,
int  power 
)

diff(int(f(r)*r^power*dr,r=s..e)/int(f(r)*dr,r=0..omega),e)=f(e)*e^power/int(f(r)*dr,r=0..omega)

241 {
242  unsigned int xCell = radius2IntCell(x);
243  double denominator = 0;
244  for (unsigned int i = 0; i <= numCells_; i++)
245  {
246  denominator += pdfIntCell(intCell2Min(i), intCell2Max(i), i, 0);
247  }
248  double a = (intCellN[xCell + 1] - intCellN[xCell]) / (intCell2Max(xCell) - intCell2Min(xCell));
249  double b = (intCellN[xCell] * intCell2Max(xCell) - intCellN[xCell + 1] * intCell2Min(xCell)) /
250  (intCell2Max(xCell) - intCell2Min(xCell));
251  return (a * std::pow(x, p + 1) + b * std::pow(x, p)) / denominator;
252 }
double pdfIntCell(double start, double end, unsigned int i, int p)
Definition: HGridOptimiser.cc:192
list x
Definition: plotDoE.py:28

References a, b, i, intCell2Max(), intCell2Min(), intCellN, numCells_, p, pdfIntCell(), Eigen::bfloat16_impl::pow(), radius2IntCell(), and plotDoE::x.

Referenced by calculateDiffWork().

◆ diffStartExpectedCellsIntegral()

double HGridOptimiser::diffStartExpectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)
333 {
334  unsigned int startCell = radius2IntCell(start);
335  unsigned int endCell = radius2IntCell(end);
336 
337  double numerator = 0;
338  double denominator = 0;
339 
340  double a = (intCellN[startCell + 1] - intCellN[startCell]) / (intCell2Max(startCell) - intCell2Min(startCell));
341  double b = (intCellN[startCell] * intCell2Max(startCell) - intCellN[startCell + 1] * intCell2Min(startCell)) /
342  (intCell2Max(startCell) - intCell2Min(startCell));
343 
344  double diffTeller = -(
345  2.0 / h * p * std::pow(2.0 * (start + h) / h, p - 1) * (a * p * start - a * h + a * start + b * p + 2 * b) *
346  (start + h) / ((p + 1) * (p + 2)) +
347  std::pow(2.0 * (start + h) / h, p) * (a * p + a) * (start + h) / ((p + 1) * (p + 2)) +
348  std::pow(2.0 * (start + h) / h, p) * (a * p * start - a * h + a * start + b * p + 2 * b) /
349  ((p + 1) * (p + 2)));
350  double diffNoemer = -(a * start + b);
351  if (startCell == endCell)
352  {
353  numerator = expectedCellsIntegralCellNumerator(start, end, startCell, p, h);
354  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
355  }
356  else
357  {
358  numerator = expectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
359  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
360  for (unsigned int i = startCell + 1; i < endCell; i++)
361  {
364  }
365  numerator += expectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
366  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
367 
368  }
369  //std::cout<<"new: numerator="<<numerator<<" denominator="<<denominator<<" diffTeller="<<diffTeller<<" diffNoemer="<<diffNoemer<<std::endl;
370  return (diffTeller * denominator - numerator * diffNoemer) / (denominator * denominator);
371 }

References a, b, Eigen::placeholders::end, expectedCellsIntegralCellDenominator(), expectedCellsIntegralCellNumerator(), i, intCell2Max(), intCell2Min(), intCellN, p, Eigen::bfloat16_impl::pow(), radius2IntCell(), and oomph::CumulativeTimings::start().

Referenced by calculateDiffWork().

◆ expectedCellsIntegral()

double HGridOptimiser::expectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)

This function calculates: int((2*r/h+2)^d f(r) dr,r=s..e)/int(f(r) dr,r=s..e)+ Used to calculated the expected number of cells to check at the level with maximum size h for particle radius between start and end

303 {
304  unsigned int startCell = radius2IntCell(start);
305  unsigned int endCell = radius2IntCell(end);
306 
307  double numerator = 0;
308  double denominator = 0;
309  if (startCell == endCell)
310  {
311  numerator = expectedCellsIntegralCellNumerator(start, end, startCell, p, h);
312  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
313  }
314  else
315  {
316  numerator = expectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
317  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
318  for (unsigned int i = startCell + 1; i < endCell; i++)
319  {
322  }
323  numerator += expectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
324  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
325 
326  }
327  // std::cout<<"New: numerator="<<numerator<<" denominator="<<denominator<<std::endl;
328  return numerator / denominator;
329 }

References Eigen::placeholders::end, expectedCellsIntegralCellDenominator(), expectedCellsIntegralCellNumerator(), i, intCell2Max(), intCell2Min(), p, radius2IntCell(), and oomph::CumulativeTimings::start().

Referenced by calculateDiffWork(), and calculateWork().

◆ expectedCellsIntegralCellDenominator()

double HGridOptimiser::expectedCellsIntegralCellDenominator ( double  start,
double  end,
unsigned int  i 
)

◆ expectedCellsIntegralCellNumerator()

double HGridOptimiser::expectedCellsIntegralCellNumerator ( double  start,
double  end,
unsigned int  i,
int  p,
double  h 
)
255 {
256  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
257  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
258  double r;
259  r = start;
260  double min = std::pow(2.0 * (r + h) / h, p) * (a * p * r - a * h + a * r + b * p + 2 * b) * (r + h) /
261  ((p + 1) * (p + 2));
262  r = end;
263  double plus = std::pow(2.0 * (r + h) / h, p) * (a * p * r - a * h + a * r + b * p + 2 * b) * (r + h) /
264  ((p + 1) * (p + 2));
265  return plus - min;
266 }

References a, b, Eigen::placeholders::end, i, intCell2Max(), intCell2Min(), intCellN, min, p, Eigen::bfloat16_impl::pow(), UniformPSDSelfTest::r, and oomph::CumulativeTimings::start().

Referenced by diffEndExpectedCellsIntegral(), diffStartExpectedCellsIntegral(), and expectedCellsIntegral().

◆ getOptimalDistribution()

void HGridOptimiser::getOptimalDistribution ( std::vector< double > &  hGridCellSizes,
unsigned int  numberOfLevels,
HGridMethod  method,
int  verbosity 
)
1024 {
1025  hGridCellSizes.clear();
1026  for (unsigned int i = 0; i <= numberOfLevels; i++)
1027  {
1028  hGridCellSizes.push_back(2.0 * (rMin_ + (rMax_ - rMin_) * i / numberOfLevels));
1029  }
1030 
1031  std::vector<double> dfdx;
1032  double step, max, W, oW;
1033  W = calculateWork(hGridCellSizes, method, verbosity - 3);
1034  int stepNumber = 0;
1035  do
1036  {
1037  oW = W;
1038  calculateDiffWork(hGridCellSizes, dfdx, method, verbosity - 3);
1039  max = checkLimit(hGridCellSizes, dfdx, verbosity - 3);
1040  step = goldenSectionSearch(hGridCellSizes, dfdx, max, 0.5 * max, 0, method, verbosity - 2);
1041  applyStep(hGridCellSizes, dfdx, step, verbosity - 3);
1042  W = calculateWork(hGridCellSizes, method, verbosity - 3);
1043  while (W > oW)
1044  {
1045  if (verbosity > 1)
1046  {
1047  logger(INFO, "% Bad step, trying closer search range\n", Flusher::NO_FLUSH, stepNumber);
1048  }
1049  applyStep(hGridCellSizes, dfdx, -step, verbosity - 3);
1050  max /= 2;
1051  step = goldenSectionSearch(hGridCellSizes, dfdx, max, 0.5 * max, 0, method, verbosity - 2);
1052  applyStep(hGridCellSizes, dfdx, step, verbosity - 3);
1053  W = calculateWork(hGridCellSizes, method, verbosity - 3);
1054  }
1055  ++stepNumber;
1056  if (verbosity > 1)
1057  {
1058  logger(INFO, "% Correct step: old work=% new work=% difference=& step=%\n", Flusher::NO_FLUSH,
1059  stepNumber, oW, W, oW - W, step / max);
1060  }
1061  } while (oW - W > 1e-13 && stepNumber);
1062  calculateDiffWork(hGridCellSizes, dfdx, method, verbosity - 2);
1063  if (verbosity > 0)
1064  {
1065  logger(INFO, "Work=%\nOptimal cell sizes:", W, Flusher::NO_FLUSH);
1066  for (double hGridCellSize : hGridCellSizes)
1067  {
1068  logger(INFO, " %", hGridCellSize, Flusher::NO_FLUSH);
1069  }
1070  logger(INFO, "");
1071  }
1072 }
double goldenSectionSearch(std::vector< double > &startHGridCellSizes, std::vector< double > &searchDirection, double min, double cur, double max, HGridMethod method, int verbosity)
Definition: HGridOptimiser.cc:963
double checkLimit(std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, int verbosity)
Definition: HGridOptimiser.cc:881
void calculateDiffWork(std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, HGridMethod method, int verbosity)
Definition: HGridOptimiser.cc:442
void applyStep(std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, double stepsize, int verbosity)
Definition: HGridOptimiser.cc:945

References applyStep(), calculateDiffWork(), calculateWork(), checkLimit(), e(), goldenSectionSearch(), i, INFO, logger, max, NO_FLUSH, rMax_, rMin_, and oomph::QuadTreeNames::W.

◆ goldenSectionSearch()

double HGridOptimiser::goldenSectionSearch ( std::vector< double > &  startHGridCellSizes,
std::vector< double > &  searchDirection,
double  min,
double  cur,
double  max,
HGridMethod  method,
int  verbosity 
)
965 {
966  std::vector<double> curHGridCellSizes = startHGridCellSizes;
967  std::vector<double> xHGridCellSizes = startHGridCellSizes;
968 
969  applyStep(curHGridCellSizes, searchDirection, cur, verbosity - 1);
970  double curWork = calculateWork(curHGridCellSizes, method, verbosity - 1);
971 
972  double x;
973  double resphi = 2.0 - 0.5 * (1 + std::sqrt(5));
974 
975  //Determine new probing point
976  if (max - cur > cur - min)
977  {
978  //x between cur and max
979  x = cur + resphi * (max - cur);
980  }
981  else
982  {
983  //x between min and cur
984  x = cur - resphi * (cur - min);
985  }
986 
987  if (std::abs(max - min) < 1e-7 * (std::abs(cur) + std::abs(x)))
988  {
989  return 0.5 * (min + max);
990  }
991 
992  applyStep(xHGridCellSizes, searchDirection, x, 0);
993  double xWork = calculateWork(xHGridCellSizes, method, 0);
994  if (verbosity > 0)
995  {
996  logger(INFO, "min=% max=% cur=% curWork=% x=% xWork=%", min, max, cur, curWork, x, xWork);
997  }
998  if (xWork < curWork) //x is better
999  {
1000  if (max - cur > cur - min)
1001  {
1002  return goldenSectionSearch(startHGridCellSizes, searchDirection, cur, x, max, method, verbosity);
1003  }
1004  else
1005  {
1006  return goldenSectionSearch(startHGridCellSizes, searchDirection, min, x, cur, method, verbosity);
1007  }
1008  }
1009  else //cur is better
1010  {
1011  if (max - cur > cur - min)
1012  {
1013  return goldenSectionSearch(startHGridCellSizes, searchDirection, min, cur, x, method, verbosity);
1014  }
1015  else
1016  {
1017  return goldenSectionSearch(startHGridCellSizes, searchDirection, x, cur, max, method, verbosity);
1018  }
1019  }
1020 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134

References abs(), applyStep(), calculateWork(), e(), INFO, logger, max, min, sqrt(), and plotDoE::x.

Referenced by getOptimalDistribution().

◆ histNumberParticlesPerCell()

void HGridOptimiser::histNumberParticlesPerCell ( std::vector< double > &  hGridCellSizes)
1075 {
1076  unsigned int NLevels = hGridCellSizes.size() - 1;
1077 
1078  std::vector<double> particlesPerLevel;
1079  for (unsigned int i = 0; i < NLevels; i++)
1080  {
1081  particlesPerLevel.push_back(pdfInt(0.5 * hGridCellSizes[i], 0.5 * hGridCellSizes[i + 1], 0));
1082  if (particlesPerLevel.back() < 0)
1083  {
1084  particlesPerLevel.back() = 0;
1085  }
1086  }
1087 
1088  std::vector<double> cellsPerLevel;
1089  for (unsigned int i = 0; i < NLevels; i++)
1090  {
1091  cellsPerLevel.push_back(pow(length_ / hGridCellSizes[i + 1], dimension_));
1092  }
1093 
1094  for (unsigned int i = 0; i < NLevels; i++)
1095  {
1096  double l = particlesPerLevel[i] / cellsPerLevel[i];
1097  logger(INFO, "Histogram for level %:", i, Flusher::NO_FLUSH);
1098  for (unsigned int k = 0; k <= 10; k++)
1099  {
1100  logger(INFO, " %.8",
1101  std::floor(std::pow(l, k) * std::exp(-l) / mathsFunc::factorial(k) * 1e4 * cellsPerLevel[i]),
1103  }
1104  logger(INFO, "");
1105  }
1106 }
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 floor(const bfloat16 &a)
Definition: BFloat16.h:643
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp(const bfloat16 &a)
Definition: BFloat16.h:615
constexpr T factorial(const T t)
factorial function
Definition: ExtendedMath.h:135

References dimension_, Eigen::bfloat16_impl::exp(), mathsFunc::factorial(), Eigen::bfloat16_impl::floor(), i, INFO, k, length_, logger, NO_FLUSH, pdfInt(), and Eigen::bfloat16_impl::pow().

◆ initialise()

void HGridOptimiser::initialise ( const MercuryBase problem,
unsigned int  numberOfCells,
int  verbosity 
)
13 {
14  //assign the number of cells
15  numCells_ = numberOfCells;
17 
18  cellN_.resize(numCells_);
19  for (double& it : cellN_)
20  {
21  it = 0.0;
22  }
23 
24  //Set the minimum and maximum radius of the particles.
25  rMin_ = nextafter(problem.particleHandler.getSmallestParticle()->getMaxInteractionRadius(), 0.0);
26  rMax_ = nextafter(nextafter(problem.particleHandler.getLargestParticle()->getMaxInteractionRadius(),
28 
29  //for all particles, add one to the cell in cellN_ which has is associated with
30  //the radius of that particle.
31  for (std::vector<BaseParticle*>::const_iterator it = problem.particleHandler.begin();
32  it != problem.particleHandler.end(); ++it)
33  {
34  cellN_[radius2Cell((*it)->getMaxInteractionRadius())]++;
35  }
36 
37  //assign what the number of particles is.
38  unsigned int numParticles = problem.particleHandler.getSize();
39 
40  intCellN.push_back(1.5 * cellN_[0] - 0.5 * cellN_[1]);
41  for (double& it : cellN_)
42  {
43  intCellN.push_back(it);
44  }
45  intCellN.push_back(1.5 * cellN_[numCells_ - 1] - 0.5 * cellN_[numCells_ - 2]);
46 
47  if (verbosity > 0)
48  {
49  logger(INFO, "rMin=% rMax=% NParticles=%\n", Flusher::NO_FLUSH, rMin_, rMax_, numParticles);
50  for (unsigned int i = 0; i < cellN_.size(); i++)
51  {
52  logger(INFO, "From %.8 to %.8 number=%.5\n", Flusher::NO_FLUSH, cell2Min(i), cell2Max(i), cellN_[i]);
53  }
54  logger(INFO, "Domain size [%,%]x[%,%]x[%,%]\n",
55  Flusher::NO_FLUSH, problem.getXMin(), problem.getXMax(), problem.getYMin(), problem.getYMax(), problem
56  .getZMin(), problem.getZMax());
57  for (unsigned int i = 0; i < intCellN.size() - 1; i++)
58  {
59  logger(INFO, "From %.8 to %.8 linear from %.8 to %.8",
61  }
62  /*std::cout<<"["<<cellN_[0];
63  for (unsigned int i=1;i<cellN_.size();i++)
64  {
65  std::cout<<","<<cellN_[i];
66  }
67  std::cout<<"]"<<std::endl;*/
68  }
69 
70  dimension_ = problem.getSystemDimensions();
71  switch (dimension_)
72  {
73  case 1:
74  length_ = pow((problem.getXMax() - problem.getXMin()) / numParticles, 1);
75  break;
76  case 2:
77  length_ = pow(
78  (problem.getXMax() - problem.getXMin()) * (problem.getYMax() - problem.getYMin()) / numParticles,
79  1.0 / 2.0);
80  break;
81  case 3:
82  length_ = pow((problem.getXMax() - problem.getXMin()) * (problem.getYMax() - problem.getYMin()) *
83  (problem.getZMax() - problem.getZMin()) / numParticles, 1.0 / 3.0);
84  break;
85  }
86 }
std::vector< double > cellN_
Definition: HGridOptimiser.h:190
double cell2Min(unsigned int i)
Computes the left bound of the cell with given ordinal number.
Definition: HGridOptimiser.cc:179
double cell2Max(unsigned int i)
Computes the right bound of the cell with given ordinal number.
Definition: HGridOptimiser.cc:187
unsigned int radius2Cell(double r)
Assigns a BaseParticle of given radius to a certain cell.
Definition: HGridOptimiser.cc:144
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 nextafter(const bfloat16 &from, const bfloat16 &to)
Definition: BFloat16.h:766
Constructor for SteadyAxisymAdvectionDiffusion problem
Definition: steady_axisym_advection_diffusion.cc:213

References cell2Max(), cell2Min(), cellCheckOverContactCheckRatio_, cellN_, dimension_, i, INFO, intCell2Max(), intCell2Min(), intCellN, length_, logger, max, Eigen::numext::nextafter(), NO_FLUSH, numCells_, Eigen::bfloat16_impl::pow(), problem, radius2Cell(), rMax_, and rMin_.

◆ initialisePolyFunc()

void HGridOptimiser::initialisePolyFunc ( double  omega,
std::vector< double > &  coeff,
unsigned int  numberOfCells,
int  verbosity 
)
90 {
91  numCells_ = numberOfCells;
93  cellN_.resize(numCells_);
94  for (double& it : cellN_)
95  {
96  it = 0;
97  }
98 
99  rMin_ = nextafter(1, 0.0);
101  for (unsigned int i = 0; i < cellN_.size(); i++)
102  {
103  double start = cell2Min(i);
104  double end = cell2Max(i);
105  for (unsigned int j = 0; j < coeff.size(); j++)
106  {
107  cellN_[i] += coeff[j] / (1.0 + j) * (std::pow(end, j + 1) - std::pow(start, j + 1));
108  }
109  }
110 
111  intCellN.push_back(1.5 * cellN_[0] - 0.5 * cellN_[1]);
112  for (double& it : cellN_)
113  {
114  intCellN.push_back(it);
115  }
116  intCellN.push_back(1.5 * cellN_[numCells_ - 1] - 0.5 * cellN_[numCells_ - 2]);
117 
118  dimension_ = 1;
119  length_ = 1.0;
120 
121  if (verbosity > 0)
122  {
123  logger(INFO, "rMin=% rMax=%\n", Flusher::NO_FLUSH, rMin_, rMax_);
124  for (unsigned int i = 0; i < cellN_.size(); i++)
125  {
126  logger(INFO, "From %.8 to %.8 number=%.5\n", Flusher::NO_FLUSH, cell2Min(i), cell2Max(i), cellN_[i]);
127  }
128 
129  for (unsigned int i = 0; i < intCellN.size() - 1; i++)
130  {
131  logger(INFO, "From %.8 to %.8 linear from %.8 to %.8",
133  }
134  }
135 }
Vector::Scalar omega(const Vector &t, const Vector &s, RealScalar angle)
Definition: IDRS.h:36

References cell2Max(), cell2Min(), cellCheckOverContactCheckRatio_, cellN_, dimension_, Eigen::placeholders::end, i, INFO, intCell2Max(), intCell2Min(), intCellN, j, length_, logger, max, Eigen::numext::nextafter(), NO_FLUSH, numCells_, Eigen::internal::omega(), Eigen::bfloat16_impl::pow(), rMax_, rMin_, and oomph::CumulativeTimings::start().

◆ intCell2Max()

◆ intCell2Min()

◆ pdfInt()

double HGridOptimiser::pdfInt ( double  start,
double  end,
int  p 
)

This function calculates: int(f(r)*r^power*dr,r=start..end)/int(f(r)*dr,r=0..omega) with r=a*r+b

204 {
205  //std::cout<<"pdfInit("<<start<<","<<end<<","<<p<<");"<<std::endl;
206  unsigned int startCell = radius2IntCell(start);
207  unsigned int endCell = radius2IntCell(end);
208 
209  double numerator = 0;
210  if (startCell == endCell)
211  {
212  numerator = pdfIntCell(start, end, startCell, p);
213  }
214  else if (endCell < startCell)
215  {
216  numerator = 0;
217  }
218  else
219  {
220  numerator = pdfIntCell(start, intCell2Max(startCell), startCell, p);
221  //std::cout<<"Teller+="<<pdfIntCell(start,intCell2Max(startCell),startCell,p)<<std::endl;
222  for (unsigned int i = startCell + 1; i < endCell; i++)
223  {
224  numerator += pdfIntCell(intCell2Min(i), intCell2Max(i), i, p);
225  //std::cout<<"Teller+="<<pdfIntCell(intCell2Min(i),intCell2Max(i),i,p)<<std::endl;
226  }
227  numerator += pdfIntCell(intCell2Min(endCell), end, endCell, p);
228  //std::cout<<"Teller+="<<pdfIntCell(intCell2Min(endCell),end,endCell,p)<<std::endl;
229  }
230  double denominator = 0;
231  for (unsigned int i = 0; i <= numCells_; i++)
232  {
233  denominator += pdfIntCell(intCell2Min(i), intCell2Max(i), i, 0);
234  //std::cout<<"Noemer+="<<pdfIntCell(intCell2Min(i),intCell2Max(i),i,0)<<std::endl;
235  }
236  return numerator / denominator;
237 }

References Eigen::placeholders::end, i, intCell2Max(), intCell2Min(), numCells_, p, pdfIntCell(), radius2IntCell(), and oomph::CumulativeTimings::start().

Referenced by calculateDiffWork(), calculateWork(), and histNumberParticlesPerCell().

◆ pdfIntCell()

double HGridOptimiser::pdfIntCell ( double  start,
double  end,
unsigned int  i,
int  p 
)
193 {
194  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
195  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
196  return (a / (p + 2) * (std::pow(end, p + 2) - std::pow(start, p + 2)) +
197  b / (p + 1) * (std::pow(end, p + 1) - std::pow(start, p + 1)));
198 }

References a, b, Eigen::placeholders::end, i, intCell2Max(), intCell2Min(), intCellN, p, Eigen::bfloat16_impl::pow(), and oomph::CumulativeTimings::start().

Referenced by diffPdfInt(), and pdfInt().

◆ radius2Cell()

unsigned int HGridOptimiser::radius2Cell ( double  r)

Assigns a BaseParticle of given radius to a certain cell.

Assigns a cell to a BaseParticle with the given radius. Note that the index of the cells are linear in the radius of a particle. For example, if numCells_ = 10 and we are looking in the radius range [0,10], than the cell number of the particle with radius r is the number r rounded down to an integer.

145 {
146  if (r < rMin_ || r >= rMax_)
147  logger(ERROR, "The radius % is not in the range [%,%]", r, rMin_, rMax_);
148  unsigned int y = static_cast<unsigned int> (floor(numCells_ * (r - rMin_) / (rMax_ - rMin_)));
149  return y;
150 }
@ ERROR
Scalar * y
Definition: level1_cplx_impl.h:128

References ERROR, Eigen::bfloat16_impl::floor(), logger, numCells_, UniformPSDSelfTest::r, rMax_, rMin_, and y.

Referenced by initialise().

◆ radius2IntCell()

unsigned int HGridOptimiser::radius2IntCell ( double  r)
153 {
154  if (r < rMin_ || r >= rMax_)
155  throw;
156  unsigned int y = static_cast<unsigned int> (floor(numCells_ * (r - rMin_) / (rMax_ - rMin_) + 0.5));
157  return y;
158 }

References Eigen::bfloat16_impl::floor(), numCells_, UniformPSDSelfTest::r, rMax_, rMin_, and y.

Referenced by diffEndExpectedCellsIntegral(), diffHExpectedCellsIntegral(), diffPdfInt(), diffStartExpectedCellsIntegral(), expectedCellsIntegral(), and pdfInt().

Member Data Documentation

◆ cellCheckOverContactCheckRatio_

double HGridOptimiser::cellCheckOverContactCheckRatio_
private

The ratio of the time required for a single geometric contact detection over the time required to retrieve information from a cell. This seems to be only used for checking the effort required by the HGrid, not to compute the cell sizes.

Referenced by calculateDiffWork(), calculateWork(), initialise(), and initialisePolyFunc().

◆ cellN_

std::vector<double> HGridOptimiser::cellN_
private

Referenced by initialise(), and initialisePolyFunc().

◆ dimension_

unsigned int HGridOptimiser::dimension_
private

The dimension of the system, usually 3, sometimes 2 or 1.

Referenced by calculateDiffWork(), calculateWork(), histNumberParticlesPerCell(), initialise(), and initialisePolyFunc().

◆ intCellN

◆ length_

double HGridOptimiser::length_
private

The weighted length of the domain.

The weighted length is computed by multiplying the lengths of all directions with each other, and then taking the appropriate type of root so that the unit is the same as that of a length (square root for 2D, cube root for 3D).

Referenced by calculateDiffWork(), calculateWork(), histNumberParticlesPerCell(), initialise(), and initialisePolyFunc().

◆ numCells_

unsigned int HGridOptimiser::numCells_
private

Number of cells, usually called levels in the HGrid.

Referenced by cell2Max(), cell2Min(), diffPdfInt(), initialise(), initialisePolyFunc(), intCell2Max(), intCell2Min(), pdfInt(), radius2Cell(), and radius2IntCell().

◆ rMax_

double HGridOptimiser::rMax_
private

Radius of the largest particle, "rounded" to the smallest double that is larger than the radius of each particle.

Referenced by cell2Max(), cell2Min(), getOptimalDistribution(), initialise(), initialisePolyFunc(), intCell2Max(), intCell2Min(), radius2Cell(), and radius2IntCell().

◆ rMin_

double HGridOptimiser::rMin_
private

Radius of the smallest particle, "rounded" to the largest double that is smaller than the radius of each particle.

Referenced by cell2Max(), cell2Min(), getOptimalDistribution(), initialise(), initialisePolyFunc(), intCell2Max(), intCell2Min(), radius2Cell(), and radius2IntCell().


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