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 
)
968 {
969  if (verbosity > 0)
970  {
971  logger(VERBOSE, "Apply step:\n", Flusher::NO_FLUSH);
972  }
973  for (unsigned int i = 0; i < hGridCellSizes.size() - 1; i++)
974  {
975  hGridCellSizes[i] += stepsize * dfdx[i];
976  if (verbosity > 0)
977  {
978  logger(INFO, "hGridCellSizes[i]+%*%=%", stepsize, dfdx[i], hGridCellSizes[i]);
979  }
980  }
981 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ INFO
@ VERBOSE
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References constants::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 
)
880 {
881  if (verbosity > 0)
882  {
883  logger(VERBOSE, "calcDfDx\n", Flusher::NO_FLUSH);
884  }
885  double W = calculateWork(hGridCellSizes, method, verbosity - 1);
886  double dx = 1e-7;
887  double nW;
888  dfdx.clear();
889  for (unsigned int i = 0; i < hGridCellSizes.size(); i++)
890  {
891  hGridCellSizes[i] += dx;
892  nW = calculateWork(hGridCellSizes, method, verbosity - 1);
893  dfdx.push_back((nW - W) / dx);
894  hGridCellSizes[i] -= dx;
895  if (verbosity > 0)
896  {
897  logger(INFO, "i= Value=% Change=% dfdx=%", i, hGridCellSizes[i], nW - W, dfdx.back());
898  }
899  }
900 }
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:728

References calculateWork(), constants::i, INFO, logger, NO_FLUSH, and VERBOSE.

◆ calculateDiffWork()

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

References BOTTOMUP, cellCheckOverContactCheckRatio_, diffEndExpectedCellsIntegral(), diffHExpectedCellsIntegral(), diffPdfInt(), diffStartExpectedCellsIntegral(), dimension_, expectedCellsIntegral(), constants::i, INFO, length_, logger, NO_FLUSH, pdfInt(), 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.

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

References BOTTOMUP, cellCheckOverContactCheckRatio_, dimension_, expectedCellsIntegral(), constants::i, INFO, length_, logger, NO_FLUSH, pdfInt(), 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.

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

References constants::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.

201 {
202  return rMin_ + (rMax_ - rMin_) * i / numCells_;
203 }

References constants::i, numCells_, rMax_, and rMin_.

Referenced by initialise(), and initialisePolyFunc().

◆ checkLimit()

double HGridOptimiser::checkLimit ( std::vector< double > &  hGridCellSizes,
std::vector< double > &  dfdx,
int  verbosity 
)
903 {
904  if (verbosity > 0)
905  {
906  logger(VERBOSE, "checkLimits part 1 remove levels");
907  }
908 
909  dfdx[0] = 0;
910  dfdx.back() = 0;
911  for (unsigned int i = 1; i < hGridCellSizes.size(); i++)
912  {
913  if (std::abs(hGridCellSizes[i - 1] - hGridCellSizes[i]) < 1e-6)
914  {
915  if (dfdx[i - 1] < dfdx[i])
916  {
917  if (verbosity > 0)
918  {
919  logger(INFO, "Remove level %", Flusher::NO_FLUSH, i);
920  }
921  if (i > 0.5 * hGridCellSizes.size())
922  {
923  hGridCellSizes.erase(hGridCellSizes.begin() + i - 1);
924  dfdx.erase(dfdx.begin() + i - 1);
925  }
926  else
927  {
928  hGridCellSizes.erase(hGridCellSizes.begin() + i);
929  dfdx.erase(dfdx.begin() + i);
930  }
931  i--;
932  }
933  }
934  }
935 
936  if (verbosity > 0)
937  {
938  logger(VERBOSE, "checkLimits part 2 calculate limit\n", Flusher::NO_FLUSH);
939  for (unsigned int i = 0; i < hGridCellSizes.size(); i++)
940  {
941  logger(INFO, "i=% Value=% dfdx=%\n", Flusher::NO_FLUSH, i, hGridCellSizes[i], dfdx[i]);
942  }
943  }
944  double maxStepSize = -std::numeric_limits<double>::max();
945  double nmax;
946  for (unsigned int i = 1; i < hGridCellSizes.size(); i++)
947  {
948  nmax = (hGridCellSizes[i - 1] - hGridCellSizes[i]) / (dfdx[i] - dfdx[i - 1]);
949  if (verbosity > 0)
950  {
951  logger(INFO, "Max f=% because otherwise %+x*% > %+x*%\n", Flusher::NO_FLUSH,
952  nmax, hGridCellSizes[i - 1], dfdx[i - 1], hGridCellSizes[i], dfdx[i]);
953  }
954  if (nmax < 0)
955  {
956  maxStepSize = std::max(nmax, maxStepSize);
957  }
958  }
959  if (verbosity > 0)
960  {
961  logger(INFO, "maxStepSize=%", maxStepSize);
962  }
963  return maxStepSize;
964 }

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

Referenced by getOptimalDistribution().

◆ diffEndExpectedCellsIntegral()

double HGridOptimiser::diffEndExpectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)
395 {
396  unsigned int startCell = radius2IntCell(start);
397  unsigned int endCell = radius2IntCell(end);
398 
399  double numerator = 0;
400  double denominator = 0;
401 
402  double a = (intCellN[endCell + 1] - intCellN[endCell]) / (intCell2Max(endCell) - intCell2Min(endCell));
403  double b = (intCellN[endCell] * intCell2Max(endCell) - intCellN[endCell + 1] * intCell2Min(endCell)) /
404  (intCell2Max(endCell) - intCell2Min(endCell));
405 
406  double diffTeller = (
407  2.0 / h * p * std::pow(2.0 * (end + h) / h, p - 1) * (a * p * end - a * h + a * end + b * p + 2 * b) *
408  (end + h) / ((p + 1) * (p + 2)) +
409  std::pow(2.0 * (end + h) / h, p) * (a * p + a) * (end + h) / ((p + 1) * (p + 2)) +
410  std::pow(2.0 * (end + h) / h, p) * (a * p * end - a * h + a * end + b * p + 2 * b) / ((p + 1) * (p + 2)));
411  double diffNoemer = (a * end + b);
412  if (startCell == endCell)
413  {
414  numerator = expectedCellsIntegralCellNumerator(start, end, startCell, p, h);
415  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
416  }
417  else
418  {
419  numerator = expectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
420  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
421  for (unsigned int i = startCell + 1; i < endCell; i++)
422  {
425  }
426  numerator += expectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
427  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
428 
429  }
430  //std::cout<<"new: numerator="<<numerator<<" denominator="<<denominator<<" diffTeller="<<diffTeller<<" diffNoemer="<<diffNoemer<<std::endl;
431  return (diffTeller * denominator - numerator * diffNoemer) / (denominator * denominator);
432 }
double expectedCellsIntegralCellNumerator(double start, double end, unsigned int i, int p, double h)
Definition: HGridOptimiser.cc:275
std::vector< double > intCellN
Definition: HGridOptimiser.h:212
double expectedCellsIntegralCellDenominator(double start, double end, unsigned int i)
Definition: HGridOptimiser.cc:312
unsigned int radius2IntCell(double r)
Definition: HGridOptimiser.cc:173
double intCell2Min(unsigned int i)
Definition: HGridOptimiser.cc:181
double intCell2Max(unsigned int i)
Definition: HGridOptimiser.cc:189

References expectedCellsIntegralCellDenominator(), expectedCellsIntegralCellNumerator(), constants::i, intCell2Max(), intCell2Min(), intCellN, and radius2IntCell().

Referenced by calculateDiffWork().

◆ diffHExpectedCellsIntegral()

double HGridOptimiser::diffHExpectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)
435 {
436  unsigned int startCell = radius2IntCell(start);
437  unsigned int endCell = radius2IntCell(end);
438 
439  double denominator = 0;
440  double diffTeller = 0;
441 
442  if (startCell == endCell)
443  {
444  diffTeller = diffHExpectedCellsIntegralCellNumerator(start, end, startCell, p, h);
445  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
446  }
447  else
448  {
449  diffTeller = diffHExpectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
450  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
451  for (unsigned int i = startCell + 1; i < endCell; i++)
452  {
455  }
456  diffTeller += diffHExpectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
457  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
458  }
459  return diffTeller / denominator;
460 }
double diffHExpectedCellsIntegralCellNumerator(double start, double end, unsigned int i, int p, double h)
Definition: HGridOptimiser.cc:290

References diffHExpectedCellsIntegralCellNumerator(), expectedCellsIntegralCellDenominator(), constants::i, intCell2Max(), intCell2Min(), and radius2IntCell().

Referenced by calculateDiffWork().

◆ diffHExpectedCellsIntegralCellNumerator()

double HGridOptimiser::diffHExpectedCellsIntegralCellNumerator ( double  start,
double  end,
unsigned int  i,
int  p,
double  h 
)
291 {
292  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
293  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
294  double r;
295  r = start;
296  //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));
297  double min =
298  (-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) *
299  (r + h) +
300  -std::pow(2.0 * r / h + 2.0, p) * a * (r + h) +
301  std::pow(2.0 * r / h + 2.0, p) * (a * p * r - a * h + a * r + b * p + 2 * b)) / ((p + 1) * (p + 2));
302  r = end;
303  //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));
304  double plus =
305  (-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) *
306  (r + h) +
307  -std::pow(2.0 * r / h + 2.0, p) * a * (r + h) +
308  std::pow(2.0 * r / h + 2.0, p) * (a * p * r - a * h + a * r + b * p + 2 * b)) / ((p + 1) * (p + 2));
309  return plus - min;
310 }

References constants::i, intCell2Max(), intCell2Min(), and intCellN.

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)

262 {
263  unsigned int xCell = radius2IntCell(x);
264  double denominator = 0;
265  for (unsigned int i = 0; i <= numCells_; i++)
266  {
267  denominator += pdfIntCell(intCell2Min(i), intCell2Max(i), i, 0);
268  }
269  double a = (intCellN[xCell + 1] - intCellN[xCell]) / (intCell2Max(xCell) - intCell2Min(xCell));
270  double b = (intCellN[xCell] * intCell2Max(xCell) - intCellN[xCell + 1] * intCell2Min(xCell)) /
271  (intCell2Max(xCell) - intCell2Min(xCell));
272  return (a * std::pow(x, p + 1) + b * std::pow(x, p)) / denominator;
273 }
double pdfIntCell(double start, double end, unsigned int i, int p)
Definition: HGridOptimiser.cc:213

References constants::i, intCell2Max(), intCell2Min(), intCellN, numCells_, pdfIntCell(), and radius2IntCell().

Referenced by calculateDiffWork().

◆ diffStartExpectedCellsIntegral()

double HGridOptimiser::diffStartExpectedCellsIntegral ( double  start,
double  end,
int  p,
double  h 
)
354 {
355  unsigned int startCell = radius2IntCell(start);
356  unsigned int endCell = radius2IntCell(end);
357 
358  double numerator = 0;
359  double denominator = 0;
360 
361  double a = (intCellN[startCell + 1] - intCellN[startCell]) / (intCell2Max(startCell) - intCell2Min(startCell));
362  double b = (intCellN[startCell] * intCell2Max(startCell) - intCellN[startCell + 1] * intCell2Min(startCell)) /
363  (intCell2Max(startCell) - intCell2Min(startCell));
364 
365  double diffTeller = -(
366  2.0 / h * p * std::pow(2.0 * (start + h) / h, p - 1) * (a * p * start - a * h + a * start + b * p + 2 * b) *
367  (start + h) / ((p + 1) * (p + 2)) +
368  std::pow(2.0 * (start + h) / h, p) * (a * p + a) * (start + h) / ((p + 1) * (p + 2)) +
369  std::pow(2.0 * (start + h) / h, p) * (a * p * start - a * h + a * start + b * p + 2 * b) /
370  ((p + 1) * (p + 2)));
371  double diffNoemer = -(a * start + b);
372  if (startCell == endCell)
373  {
374  numerator = expectedCellsIntegralCellNumerator(start, end, startCell, p, h);
375  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
376  }
377  else
378  {
379  numerator = expectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
380  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
381  for (unsigned int i = startCell + 1; i < endCell; i++)
382  {
385  }
386  numerator += expectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
387  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
388 
389  }
390  //std::cout<<"new: numerator="<<numerator<<" denominator="<<denominator<<" diffTeller="<<diffTeller<<" diffNoemer="<<diffNoemer<<std::endl;
391  return (diffTeller * denominator - numerator * diffNoemer) / (denominator * denominator);
392 }

References expectedCellsIntegralCellDenominator(), expectedCellsIntegralCellNumerator(), constants::i, intCell2Max(), intCell2Min(), intCellN, and radius2IntCell().

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

324 {
325  unsigned int startCell = radius2IntCell(start);
326  unsigned int endCell = radius2IntCell(end);
327 
328  double numerator = 0;
329  double denominator = 0;
330  if (startCell == endCell)
331  {
332  numerator = expectedCellsIntegralCellNumerator(start, end, startCell, p, h);
333  denominator = expectedCellsIntegralCellDenominator(start, end, startCell);
334  }
335  else
336  {
337  numerator = expectedCellsIntegralCellNumerator(start, intCell2Max(startCell), startCell, p, h);
338  denominator = expectedCellsIntegralCellDenominator(start, intCell2Max(startCell), startCell);
339  for (unsigned int i = startCell + 1; i < endCell; i++)
340  {
343  }
344  numerator += expectedCellsIntegralCellNumerator(intCell2Min(endCell), end, endCell, p, h);
345  denominator += expectedCellsIntegralCellDenominator(intCell2Min(endCell), end, endCell);
346 
347  }
348  // std::cout<<"New: numerator="<<numerator<<" denominator="<<denominator<<std::endl;
349  return numerator / denominator;
350 }

References expectedCellsIntegralCellDenominator(), expectedCellsIntegralCellNumerator(), constants::i, intCell2Max(), intCell2Min(), and radius2IntCell().

Referenced by calculateDiffWork(), and calculateWork().

◆ expectedCellsIntegralCellDenominator()

double HGridOptimiser::expectedCellsIntegralCellDenominator ( double  start,
double  end,
unsigned int  i 
)
313 {
314  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
315  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
316  return (a / 2.0 * (pow(end, 2) - pow(start, 2)) + b * (pow(end, 1) - pow(start, 1)));
317 }

References constants::i, intCell2Max(), intCell2Min(), and intCellN.

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

◆ expectedCellsIntegralCellNumerator()

double HGridOptimiser::expectedCellsIntegralCellNumerator ( double  start,
double  end,
unsigned int  i,
int  p,
double  h 
)
276 {
277  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
278  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
279  double r;
280  r = start;
281  double min = std::pow(2.0 * (r + h) / h, p) * (a * p * r - a * h + a * r + b * p + 2 * b) * (r + h) /
282  ((p + 1) * (p + 2));
283  r = end;
284  double plus = std::pow(2.0 * (r + h) / h, p) * (a * p * r - a * h + a * r + b * p + 2 * b) * (r + h) /
285  ((p + 1) * (p + 2));
286  return plus - min;
287 }

References constants::i, intCell2Max(), intCell2Min(), and intCellN.

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

◆ getOptimalDistribution()

void HGridOptimiser::getOptimalDistribution ( std::vector< double > &  hGridCellSizes,
unsigned int  numberOfLevels,
HGridMethod  method,
int  verbosity 
)
1045 {
1046  hGridCellSizes.clear();
1047  for (unsigned int i = 0; i <= numberOfLevels; i++)
1048  {
1049  hGridCellSizes.push_back(2.0 * (rMin_ + (rMax_ - rMin_) * i / numberOfLevels));
1050  }
1051 
1052  std::vector<double> dfdx;
1053  double step, max, W, oW;
1054  W = calculateWork(hGridCellSizes, method, verbosity - 3);
1055  int stepNumber = 0;
1056  do
1057  {
1058  oW = W;
1059  calculateDiffWork(hGridCellSizes, dfdx, method, verbosity - 3);
1060  max = checkLimit(hGridCellSizes, dfdx, verbosity - 3);
1061  step = goldenSectionSearch(hGridCellSizes, dfdx, max, 0.5 * max, 0, method, verbosity - 2);
1062  applyStep(hGridCellSizes, dfdx, step, verbosity - 3);
1063  W = calculateWork(hGridCellSizes, method, verbosity - 3);
1064  while (W > oW)
1065  {
1066  if (verbosity > 1)
1067  {
1068  logger(INFO, "% Bad step, trying closer search range\n", Flusher::NO_FLUSH, stepNumber);
1069  }
1070  applyStep(hGridCellSizes, dfdx, -step, verbosity - 3);
1071  max /= 2;
1072  step = goldenSectionSearch(hGridCellSizes, dfdx, max, 0.5 * max, 0, method, verbosity - 2);
1073  applyStep(hGridCellSizes, dfdx, step, verbosity - 3);
1074  W = calculateWork(hGridCellSizes, method, verbosity - 3);
1075  }
1076  ++stepNumber;
1077  if (verbosity > 1)
1078  {
1079  logger(INFO, "% Correct step: old work=% new work=% difference=& step=%\n", Flusher::NO_FLUSH,
1080  stepNumber, oW, W, oW - W, step / max);
1081  }
1082  } while (oW - W > 1e-13 && stepNumber);
1083  calculateDiffWork(hGridCellSizes, dfdx, method, verbosity - 2);
1084  if (verbosity > 0)
1085  {
1086  logger(INFO, "Work=%\nOptimal cell sizes:", W, Flusher::NO_FLUSH);
1087  for (double hGridCellSize : hGridCellSizes)
1088  {
1089  logger(INFO, " %", hGridCellSize, Flusher::NO_FLUSH);
1090  }
1091  logger(INFO, "");
1092  }
1093 }
double goldenSectionSearch(std::vector< double > &startHGridCellSizes, std::vector< double > &searchDirection, double min, double cur, double max, HGridMethod method, int verbosity)
Definition: HGridOptimiser.cc:984
double checkLimit(std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, int verbosity)
Definition: HGridOptimiser.cc:902
void calculateDiffWork(std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, HGridMethod method, int verbosity)
Definition: HGridOptimiser.cc:463
void applyStep(std::vector< double > &hGridCellSizes, std::vector< double > &dfdx, double stepsize, int verbosity)
Definition: HGridOptimiser.cc:966

References applyStep(), calculateDiffWork(), calculateWork(), checkLimit(), goldenSectionSearch(), constants::i, INFO, logger, NO_FLUSH, rMax_, and rMin_.

◆ goldenSectionSearch()

double HGridOptimiser::goldenSectionSearch ( std::vector< double > &  startHGridCellSizes,
std::vector< double > &  searchDirection,
double  min,
double  cur,
double  max,
HGridMethod  method,
int  verbosity 
)
986 {
987  std::vector<double> curHGridCellSizes = startHGridCellSizes;
988  std::vector<double> xHGridCellSizes = startHGridCellSizes;
989 
990  applyStep(curHGridCellSizes, searchDirection, cur, verbosity - 1);
991  double curWork = calculateWork(curHGridCellSizes, method, verbosity - 1);
992 
993  double x;
994  double resphi = 2.0 - 0.5 * (1 + std::sqrt(5));
995 
996  //Determine new probing point
997  if (max - cur > cur - min)
998  {
999  //x between cur and max
1000  x = cur + resphi * (max - cur);
1001  }
1002  else
1003  {
1004  //x between min and cur
1005  x = cur - resphi * (cur - min);
1006  }
1007 
1008  if (std::abs(max - min) < 1e-7 * (std::abs(cur) + std::abs(x)))
1009  {
1010  return 0.5 * (min + max);
1011  }
1012 
1013  applyStep(xHGridCellSizes, searchDirection, x, 0);
1014  double xWork = calculateWork(xHGridCellSizes, method, 0);
1015  if (verbosity > 0)
1016  {
1017  logger(INFO, "min=% max=% cur=% curWork=% x=% xWork=%", min, max, cur, curWork, x, xWork);
1018  }
1019  if (xWork < curWork) //x is better
1020  {
1021  if (max - cur > cur - min)
1022  {
1023  return goldenSectionSearch(startHGridCellSizes, searchDirection, cur, x, max, method, verbosity);
1024  }
1025  else
1026  {
1027  return goldenSectionSearch(startHGridCellSizes, searchDirection, min, x, cur, method, verbosity);
1028  }
1029  }
1030  else //cur is better
1031  {
1032  if (max - cur > cur - min)
1033  {
1034  return goldenSectionSearch(startHGridCellSizes, searchDirection, min, cur, x, method, verbosity);
1035  }
1036  else
1037  {
1038  return goldenSectionSearch(startHGridCellSizes, searchDirection, x, cur, max, method, verbosity);
1039  }
1040  }
1041 }

References applyStep(), calculateWork(), INFO, and logger.

Referenced by getOptimalDistribution().

◆ histNumberParticlesPerCell()

void HGridOptimiser::histNumberParticlesPerCell ( std::vector< double > &  hGridCellSizes)
1096 {
1097  unsigned int NLevels = hGridCellSizes.size() - 1;
1098 
1099  std::vector<double> particlesPerLevel;
1100  for (unsigned int i = 0; i < NLevels; i++)
1101  {
1102  particlesPerLevel.push_back(pdfInt(0.5 * hGridCellSizes[i], 0.5 * hGridCellSizes[i + 1], 0));
1103  if (particlesPerLevel.back() < 0)
1104  {
1105  particlesPerLevel.back() = 0;
1106  }
1107  }
1108 
1109  std::vector<double> cellsPerLevel;
1110  for (unsigned int i = 0; i < NLevels; i++)
1111  {
1112  cellsPerLevel.push_back(pow(length_ / hGridCellSizes[i + 1], dimension_));
1113  }
1114 
1115  for (unsigned int i = 0; i < NLevels; i++)
1116  {
1117  double l = particlesPerLevel[i] / cellsPerLevel[i];
1118  logger(INFO, "Histogram for level %:", i, Flusher::NO_FLUSH);
1119  for (unsigned int k = 0; k <= 10; k++)
1120  {
1121  logger(INFO, " %.8",
1122  std::floor(std::pow(l, k) * std::exp(-l) / mathsFunc::factorial(k) * 1e4 * cellsPerLevel[i]),
1124  }
1125  logger(INFO, "");
1126  }
1127 }
Mdouble exp(Mdouble Exponent)
Definition: ExtendedMath.cc:84
constexpr T factorial(const T t)
factorial function
Definition: ExtendedMath.h:155

References dimension_, mathsFunc::exp(), mathsFunc::factorial(), constants::i, INFO, length_, logger, NO_FLUSH, and pdfInt().

◆ initialise()

void HGridOptimiser::initialise ( const MercuryBase problem,
unsigned int  numberOfCells,
int  verbosity 
)
34 {
35  //assign the number of cells
36  numCells_ = numberOfCells;
38 
39  cellN_.resize(numCells_);
40  for (double& it : cellN_)
41  {
42  it = 0.0;
43  }
44 
45  //Set the minimum and maximum radius of the particles.
47  rMax_ = nextafter(nextafter(problem.particleHandler.getLargestParticle()->getMaxInteractionRadius(),
48  std::numeric_limits<double>::max()), std::numeric_limits<double>::max());
49 
50  //for all particles, add one to the cell in cellN_ which has is associated with
51  //the radius of that particle.
52  for (std::vector<BaseParticle*>::const_iterator it = problem.particleHandler.begin();
53  it != problem.particleHandler.end(); ++it)
54  {
55  cellN_[radius2Cell((*it)->getMaxInteractionRadius())]++;
56  }
57 
58  //assign what the number of particles is.
59  unsigned int numParticles = problem.particleHandler.getSize();
60 
61  intCellN.push_back(1.5 * cellN_[0] - 0.5 * cellN_[1]);
62  for (double& it : cellN_)
63  {
64  intCellN.push_back(it);
65  }
66  intCellN.push_back(1.5 * cellN_[numCells_ - 1] - 0.5 * cellN_[numCells_ - 2]);
67 
68  if (verbosity > 0)
69  {
70  logger(INFO, "rMin=% rMax=% NParticles=%\n", Flusher::NO_FLUSH, rMin_, rMax_, numParticles);
71  for (unsigned int i = 0; i < cellN_.size(); i++)
72  {
73  logger(INFO, "From %.8 to %.8 number=%.5\n", Flusher::NO_FLUSH, cell2Min(i), cell2Max(i), cellN_[i]);
74  }
75  logger(INFO, "Domain size [%,%]x[%,%]x[%,%]\n",
76  Flusher::NO_FLUSH, problem.getXMin(), problem.getXMax(), problem.getYMin(), problem.getYMax(), problem
77  .getZMin(), problem.getZMax());
78  for (unsigned int i = 0; i < intCellN.size() - 1; i++)
79  {
80  logger(INFO, "From %.8 to %.8 linear from %.8 to %.8",
82  }
83  /*std::cout<<"["<<cellN_[0];
84  for (unsigned int i=1;i<cellN_.size();i++)
85  {
86  std::cout<<","<<cellN_[i];
87  }
88  std::cout<<"]"<<std::endl;*/
89  }
90 
91  dimension_ = problem.getSystemDimensions();
92  switch (dimension_)
93  {
94  case 1:
95  length_ = pow((problem.getXMax() - problem.getXMin()) / numParticles, 1);
96  break;
97  case 2:
98  length_ = pow(
99  (problem.getXMax() - problem.getXMin()) * (problem.getYMax() - problem.getYMin()) / numParticles,
100  1.0 / 2.0);
101  break;
102  case 3:
103  length_ = pow((problem.getXMax() - problem.getXMin()) * (problem.getYMax() - problem.getYMin()) *
104  (problem.getZMax() - problem.getZMin()) / numParticles, 1.0 / 3.0);
105  break;
106  }
107 }
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:690
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:704
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655
Mdouble getMaxInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e....
Definition: BaseParticle.h:362
Mdouble getXMin() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMin() returns XMin.
Definition: DPMBase.h:619
Mdouble getXMax() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMax() returns XMax.
Definition: DPMBase.h:626
Mdouble getYMin() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMin() returns YMin.
Definition: DPMBase.h:632
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1437
Mdouble getYMax() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMax() returns XMax.
Definition: DPMBase.h:638
unsigned int getSystemDimensions() const
Returns the system dimensionality.
Definition: DPMBase.cc:1430
Mdouble getZMax() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMax() returns ZMax.
Definition: DPMBase.h:650
Mdouble getZMin() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMin() returns ZMin.
Definition: DPMBase.h:644
std::vector< double > cellN_
Definition: HGridOptimiser.h:211
double cell2Min(unsigned int i)
Computes the left bound of the cell with given ordinal number.
Definition: HGridOptimiser.cc:200
double cell2Max(unsigned int i)
Computes the right bound of the cell with given ordinal number.
Definition: HGridOptimiser.cc:208
unsigned int radius2Cell(double r)
Assigns a BaseParticle of given radius to a certain cell.
Definition: HGridOptimiser.cc:165
BaseParticle * getLargestParticle() const
Returns the pointer of the largest particle in the particle handler. When mercury is running in paral...
Definition: ParticleHandler.cc:534
BaseParticle * getSmallestParticle() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the loc...
Definition: ParticleHandler.cc:511

References BaseHandler< T >::begin(), cell2Max(), cell2Min(), cellCheckOverContactCheckRatio_, cellN_, dimension_, BaseHandler< T >::end(), ParticleHandler::getLargestParticle(), BaseParticle::getMaxInteractionRadius(), BaseHandler< T >::getSize(), ParticleHandler::getSmallestParticle(), DPMBase::getSystemDimensions(), DPMBase::getXMax(), DPMBase::getXMin(), DPMBase::getYMax(), DPMBase::getYMin(), DPMBase::getZMax(), DPMBase::getZMin(), constants::i, INFO, intCell2Max(), intCell2Min(), intCellN, length_, logger, NO_FLUSH, numCells_, DPMBase::particleHandler, radius2Cell(), rMax_, and rMin_.

◆ initialisePolyFunc()

void HGridOptimiser::initialisePolyFunc ( double  omega,
std::vector< double > &  coeff,
unsigned int  numberOfCells,
int  verbosity 
)
111 {
112  numCells_ = numberOfCells;
114  cellN_.resize(numCells_);
115  for (double& it : cellN_)
116  {
117  it = 0;
118  }
119 
120  rMin_ = nextafter(1, 0.0);
121  rMax_ = nextafter(omega, std::numeric_limits<double>::max());
122  for (unsigned int i = 0; i < cellN_.size(); i++)
123  {
124  double start = cell2Min(i);
125  double end = cell2Max(i);
126  for (unsigned int j = 0; j < coeff.size(); j++)
127  {
128  cellN_[i] += coeff[j] / (1.0 + j) * (std::pow(end, j + 1) - std::pow(start, j + 1));
129  }
130  }
131 
132  intCellN.push_back(1.5 * cellN_[0] - 0.5 * cellN_[1]);
133  for (double& it : cellN_)
134  {
135  intCellN.push_back(it);
136  }
137  intCellN.push_back(1.5 * cellN_[numCells_ - 1] - 0.5 * cellN_[numCells_ - 2]);
138 
139  dimension_ = 1;
140  length_ = 1.0;
141 
142  if (verbosity > 0)
143  {
144  logger(INFO, "rMin=% rMax=%\n", Flusher::NO_FLUSH, rMin_, rMax_);
145  for (unsigned int i = 0; i < cellN_.size(); i++)
146  {
147  logger(INFO, "From %.8 to %.8 number=%.5\n", Flusher::NO_FLUSH, cell2Min(i), cell2Max(i), cellN_[i]);
148  }
149 
150  for (unsigned int i = 0; i < intCellN.size() - 1; i++)
151  {
152  logger(INFO, "From %.8 to %.8 linear from %.8 to %.8",
154  }
155  }
156 }

References cell2Max(), cell2Min(), cellCheckOverContactCheckRatio_, cellN_, dimension_, constants::i, INFO, intCell2Max(), intCell2Min(), intCellN, length_, logger, NO_FLUSH, numCells_, rMax_, and rMin_.

◆ 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

225 {
226  //std::cout<<"pdfInit("<<start<<","<<end<<","<<p<<");"<<std::endl;
227  unsigned int startCell = radius2IntCell(start);
228  unsigned int endCell = radius2IntCell(end);
229 
230  double numerator = 0;
231  if (startCell == endCell)
232  {
233  numerator = pdfIntCell(start, end, startCell, p);
234  }
235  else if (endCell < startCell)
236  {
237  numerator = 0;
238  }
239  else
240  {
241  numerator = pdfIntCell(start, intCell2Max(startCell), startCell, p);
242  //std::cout<<"Teller+="<<pdfIntCell(start,intCell2Max(startCell),startCell,p)<<std::endl;
243  for (unsigned int i = startCell + 1; i < endCell; i++)
244  {
245  numerator += pdfIntCell(intCell2Min(i), intCell2Max(i), i, p);
246  //std::cout<<"Teller+="<<pdfIntCell(intCell2Min(i),intCell2Max(i),i,p)<<std::endl;
247  }
248  numerator += pdfIntCell(intCell2Min(endCell), end, endCell, p);
249  //std::cout<<"Teller+="<<pdfIntCell(intCell2Min(endCell),end,endCell,p)<<std::endl;
250  }
251  double denominator = 0;
252  for (unsigned int i = 0; i <= numCells_; i++)
253  {
254  denominator += pdfIntCell(intCell2Min(i), intCell2Max(i), i, 0);
255  //std::cout<<"Noemer+="<<pdfIntCell(intCell2Min(i),intCell2Max(i),i,0)<<std::endl;
256  }
257  return numerator / denominator;
258 }

References constants::i, intCell2Max(), intCell2Min(), numCells_, pdfIntCell(), and radius2IntCell().

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

◆ pdfIntCell()

double HGridOptimiser::pdfIntCell ( double  start,
double  end,
unsigned int  i,
int  p 
)
214 {
215  double a = (intCellN[i + 1] - intCellN[i]) / (intCell2Max(i) - intCell2Min(i));
216  double b = (intCellN[i] * intCell2Max(i) - intCellN[i + 1] * intCell2Min(i)) / (intCell2Max(i) - intCell2Min(i));
217  return (a / (p + 2) * (std::pow(end, p + 2) - std::pow(start, p + 2)) +
218  b / (p + 1) * (std::pow(end, p + 1) - std::pow(start, p + 1)));
219 }

References constants::i, intCell2Max(), intCell2Min(), and intCellN.

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.

166 {
167  if (r < rMin_ || r >= rMax_)
168  logger(ERROR, "The radius % is not in the range [%,%]", r, rMin_, rMax_);
169  unsigned int y = static_cast<unsigned int> (floor(numCells_ * (r - rMin_) / (rMax_ - rMin_)));
170  return y;
171 }
@ ERROR

References ERROR, logger, numCells_, rMax_, and rMin_.

Referenced by initialise().

◆ radius2IntCell()

unsigned int HGridOptimiser::radius2IntCell ( double  r)
174 {
175  if (r < rMin_ || r >= rMax_)
176  throw;
177  unsigned int y = static_cast<unsigned int> (floor(numCells_ * (r - rMin_) / (rMax_ - rMin_) + 0.5));
178  return y;
179 }

References numCells_, rMax_, and rMin_.

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: