https://mooseframework.inl.gov
DiscreteNucleationTimeStep.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
12 #include "MooseUtils.h"
13 
15 
18 {
20  params.addClassDescription(
21  "Return a time step limit for nucleation event to be used by IterationAdaptiveDT");
22  params.addRequiredParam<Real>("dt_max",
23  "Time step to cut back to at the start of a nucleation event");
24  params.addRangeCheckedParam<Real>(
25  "p2nucleus",
26  0.01,
27  "p2nucleus > 0 & p2nucleus < 1",
28  "Maximum probability for more than one nucleus to appear during a time "
29  "step. This will limit the time step based on the total nucleation rate for "
30  "the domain to make sure the probability for two or more nuclei to appear "
31  "is always below the chosen number.");
32  params.addRequiredParam<UserObjectName>("inserter", "DiscreteNucleationInserter user object");
33  return params;
34 }
35 
37  : GeneralPostprocessor(parameters),
38  _inserter(getUserObject<DiscreteNucleationInserterBase>("inserter")),
39  _dt_nucleation(getParam<Real>("dt_max")),
40  _changes_made(_inserter.getInsertionsAndDeletions()),
41  _rate(_inserter.getRate())
42 {
43  //
44  // We do a bisection search because math is hard
45  // (i.e. probability function is not analytically invertible)
46  //
47 
48  // this is the target value
49  const Real p2n = getParam<Real>("p2nucleus");
50 
51  // initial guess
52  _max_lambda = 0.1;
53  Real upper_bound = _max_lambda;
54  Real lower_bound = 0.0;
55 
56  // At this point we do not know a proper upper bound for a search interval
57  // so we grow our initial guess until we find it (we only allow for a finite
58  // number of iterations)
59  for (unsigned int i = 0; i < 100; ++i)
60  {
61  const Real p_upper = 1.0 - (1.0 + upper_bound) * std::exp(-upper_bound);
62 
63  // we have found a lambda value that results in a p > p2n, this is the upper end of the interval
64  if (p_upper > p2n)
65  break;
66 
67  // upper_bound is actually below our target lambda, set it as the new lower
68  // bound and double the upper_bound value
69  lower_bound = upper_bound;
70  upper_bound *= 2.0;
71  }
72 
73  // now that we have an upper and a lower interval bounds we can do a proper bisection
74  for (unsigned int i = 0; i < 100; ++i)
75  {
76  // pick the middle of the current interval
77  _max_lambda = (upper_bound - lower_bound) / 2.0 + lower_bound;
78 
79  // calculate new probability for 2 or more nuclei to appear
80  const Real p = 1.0 - (1.0 + _max_lambda) * std::exp(-_max_lambda);
81 
82  // quit if we zeroed in on the target
84  break;
85 
86  // otherwise adjust interval bounds
87  else if (p > p2n)
88  upper_bound = _max_lambda;
89  else
90  lower_bound = _max_lambda;
91  }
92 }
93 
96 {
97  // check if a nucleus insertion has occurred...
98  if (_changes_made.first > 0)
99  // and cut back time step for nucleus formation
100  return _dt_nucleation;
101 
102  // otherwise check the total nucleation rate in the domain...
103  if (_rate == 0.0)
104  // ...and return no limit on the time step if the rate is zero...
105  return std::numeric_limits<Real>::max();
106  else
107  // ...or return the maximum time step that satisfies the bound on the 2+ nuclei probability
108  return _max_lambda / _rate;
109 }
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Real _max_lambda
Maximum total event expectation value that is low enough so that the probability for more than one * ...
static InputParameters validParams()
Returns a user defined timestep limit for the simulation step right after the introduction of a new n...
const Real _dt_nucleation
User specified nucleation time step.
void addRequiredParam(const std::string &name, const std::string &doc_string)
const DiscreteNucleationInserterBase::NucleusChanges & _changes_made
nucleus count changes performed by the inserter
static InputParameters validParams()
This UserObject manages the insertion and expiration of nuclei in the simulation domain it manages a ...
Real PostprocessorValue
DiscreteNucleationTimeStep(const InputParameters &parameters)
const Real & _rate
total nucleation rate integrated over the entire domain
registerMooseObject("PhaseFieldApp", DiscreteNucleationTimeStep)
virtual PostprocessorValue getValue() const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)