Skip to content

Commit

Permalink
Add find value by bisection (idaholab#6389)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen committed May 4, 2016
1 parent 447c02f commit b7f11ff
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 0 deletions.
64 changes: 64 additions & 0 deletions modules/phase_field/include/postprocessors/FindValueOnLine.h
@@ -0,0 +1,64 @@
/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment */
/* */
/* All contents are licensed under LGPL V2.1 */
/* See LICENSE for full restrictions */
/****************************************************************/

#ifndef FINDVALUEONLINE_H
#define FINDVALUEONLINE_H

#include "GeneralPostprocessor.h"
#include "Coupleable.h"

class FindValueOnLine;

template<>
InputParameters validParams<FindValueOnLine>();

/**
* Finds a secific value along a line through a bisection search/
*/
class FindValueOnLine : public GeneralPostprocessor, public Coupleable
{
public:
FindValueOnLine(const InputParameters & parameters);

virtual void initialize();
virtual void execute();
virtual void finalize() {}

virtual PostprocessorValue getValue();

protected:
Real getValueAtPoint(const Point & p);

///@{ line to sample along
const Point _start_point;
const Point _end_point;
const Real _length;
///@}

/// value to find along the line
const Real _target;

/// search depth
const unsigned int _depth;

/// coupled variable
MooseVariable * _coupled_var;

/// detected interface location
Real _position;

/// The Mesh we're using
MooseMesh & _mesh;

/// So we don't have to create and destroy teh dummy vector
std::vector<Point> _point_vec;

/// helper object to locate elements containing points
UniquePtr<PointLocatorBase> _pl;
};

#endif // FINDVALUEONLINE_H
2 changes: 2 additions & 0 deletions modules/phase_field/src/base/PhaseFieldApp.C
Expand Up @@ -136,6 +136,7 @@
* Postprocessors
*/
#include "FeatureFloodCount.h"
#include "FindValueOnLine.h"
#include "GrainTracker.h"
#include "FauxGrainTracker.h"
#include "NodalVolumeFraction.h"
Expand Down Expand Up @@ -361,6 +362,7 @@ PhaseFieldApp::registerObjects(Factory & factory)
registerMaterial(ThirdPhaseSuppressionMaterial);

registerPostprocessor(FeatureFloodCount);
registerPostprocessor(FindValueOnLine);
registerPostprocessor(GrainTracker);
registerPostprocessor(FauxGrainTracker);
registerPostprocessor(NodalVolumeFraction);
Expand Down
114 changes: 114 additions & 0 deletions modules/phase_field/src/postprocessors/FindValueOnLine.C
@@ -0,0 +1,114 @@
/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment */
/* */
/* All contents are licensed under LGPL V2.1 */
/* See LICENSE for full restrictions */
/****************************************************************/

#include "FindValueOnLine.h"
#include "MooseMesh.h"

template<>
InputParameters validParams<FindValueOnLine>()
{
InputParameters params = validParams<GeneralPostprocessor>();
params.addParam<Point>("start_point", "Start point of the sample line.");
params.addParam<Point>("end_point", "End point of the sample line.");
params.addParam<Real>("target", "Target value to locate.");
params.addParam<unsigned int>("depth", "Number of bisections to perform.");
params.addCoupledVar("v", "Variable to inspect");
return params;
}

FindValueOnLine::FindValueOnLine(const InputParameters & parameters) :
GeneralPostprocessor(parameters),
Coupleable(this, false),
_start_point(getParam<Point>("start_point")),
_end_point(getParam<Point>("end_point")),
_length((_end_point - _start_point).norm()),
_target(getParam<Real>("target")),
_depth(getParam<unsigned int>("depth")),
_coupled_var(getVar("v", 0)),
_position(0.0),
_mesh(_subproblem.mesh()),
_point_vec(1)
{
}

void
FindValueOnLine::initialize()
{
// We do this here just in case it's been destroyed and recreated becaue of mesh adaptivity.
_pl = _mesh.getMesh().sub_point_locator();
}

void
FindValueOnLine::execute()
{
Real s;
Real s_left = 0.0;
Real left = getValueAtPoint(_start_point);
Real s_right = 1.0;
Real right = getValueAtPoint(_end_point);

for (unsigned i = 0; i < _depth; ++i)
{
// find midpoint
s = (s_left + s_right) / 2.0;
Point p = s * (_end_point - _start_point) + _start_point;

// sample value
Real value = getValueAtPoint(p);

// bisect
if ( (left >= _target && _target >= value)
|| (left <= _target && _target <= value))
{
// to the left
s_right = s;
right = value;
}
else
{
// to the right
s_left = s;
left = value;
}
}

_position = s * _length;
}

Real
FindValueOnLine::getValueAtPoint(const Point & p)
{
const Elem * elem = (*_pl)(p);

if (elem)
{
Real value;

if (elem->processor_id() == processor_id())
{
// element is local
_point_vec[0] = p;
_subproblem.reinitElemPhys(elem, _point_vec, 0);
value = _coupled_var->sln()[0];
}

// broadcast value
_communicator.broadcast(value, elem->processor_id());
return value;
}
else
{
// there is no element
mooseError("No element found.");
}
}

PostprocessorValue
FindValueOnLine::getValue()
{
return _position;
}
73 changes: 73 additions & 0 deletions modules/phase_field/tests/postprocessors/findvalueonline.i
@@ -0,0 +1,73 @@
[Mesh]
type = GeneratedMesh
dim = 2
nx = 20
ny = 20
xmin = 0
xmax = 10
ymin = 0
ymax = 10
[]

[Variables]
[./phi]
[./InitialCondition]
type = SmoothCircleIC
x1 = 0
y1 = 0
radius = 3
invalue = 1
outvalue = 0
int_width = 2
[../]
[../]
[]

[Kernels]
[./ac]
type = AllenCahn
variable = phi
f_name = F
mob_name = 1
[../]
[./aci]
type = ACInterface
kappa_name = 0.2
variable = phi
mob_name = 1
[../]
[./dt]
type = TimeDerivative
variable = phi
[../]
[]

[Materials]
[./F]
type = DerivativeParsedMaterial
args = phi
function = phi^2*(1-phi)^2-0.1*phi
[../]
[]

[Postprocessors]
[./pos]
type = FindValueOnLine
target = 0.5
depth = 20
v = phi
start_point = '0 0 0'
end_point = '10 10 0'
execute_on = 'initial timestep_end'
[../]
[]

[Executioner]
type = Transient
num_steps = 5
dt = 1
[]

[Outputs]
csv = true
[]
@@ -0,0 +1,8 @@
time,pos
0,2.9963644457983
1,3.0919602417168
2,3.2098365476321
3,3.3441130352399
4,3.4933870574218
5,3.6556625394324

8 changes: 8 additions & 0 deletions modules/phase_field/tests/postprocessors/tests
@@ -0,0 +1,8 @@
[Tests]
[./findvalueonline]
type = 'CSVDiff'
input = 'findvalueonline.i'
csvdiff = 'findvalueonline_out.csv'
rel_err = 1.0E-5
[../]
[]

0 comments on commit b7f11ff

Please sign in to comment.