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