https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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{
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
83 if (MooseUtils::absoluteFuzzyEqual(p, p2n))
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}
registerMooseObject("PhaseFieldApp", DiscreteNucleationTimeStep)
const Real p
Real PostprocessorValue
This UserObject manages the insertion and expiration of nuclei in the simulation domain it manages a ...
Returns a user defined timestep limit for the simulation step right after the introduction of a new n...
const Real & _rate
total nucleation rate integrated over the entire domain
static InputParameters validParams()
const Real _dt_nucleation
User specified nucleation time step.
const DiscreteNucleationInserterBase::NucleusChanges & _changes_made
nucleus count changes performed by the inserter
DiscreteNucleationTimeStep(const InputParameters &parameters)
Real _max_lambda
Maximum total event expectation value that is low enough so that the probability for more than one * ...
virtual PostprocessorValue getValue() const override
static InputParameters validParams()
void addRequiredParam(const std::string &name, const std::string &doc_string)
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)