Skip to content
Permalink
Browse files

Merge pull request #13183 from joshuahansel/boundary-flux-postprocessor

Added post-processor for querying BoundaryFlux objects
  • Loading branch information...
moosebuild committed Apr 5, 2019
2 parents 3c232a4 + de26f11 commit ecd319840ce389c6110e58c938ea21ea604c31a8
@@ -0,0 +1,16 @@
!syntax description /Postprocessors/BoundaryFluxPostprocessor

This post-processor is used to query flux vectors that are computed via
objects derived from `BoundaryFluxBase`. It computes the side integral of the
specified entry of the flux at a specified boundary.

This post-processor is useful for conservation tests because the inflow and
outflow fluxes for a domain can be integrated. Note that in this case, one still
needs to integrate the post-processor over time; this is done with the
[TotalVariableValue](/TotalVariableValue.md) post-processor.

!syntax parameters /Postprocessors/BoundaryFluxPostprocessor

!syntax inputs /Postprocessors/BoundaryFluxPostprocessor

!syntax children /Postprocessors/BoundaryFluxPostprocessor
@@ -0,0 +1,48 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifndef BOUNDARYFLUXPOSTPROCESSOR_H
#define BOUNDARYFLUXPOSTPROCESSOR_H

#include "SideIntegralPostprocessor.h"

class BoundaryFluxPostprocessor;
class BoundaryFluxBase;

template <>
InputParameters validParams<BoundaryFluxPostprocessor>();

/**
* Computes the side integral of a flux entry from a BoundaryFluxBase user object
*/
class BoundaryFluxPostprocessor : public SideIntegralPostprocessor
{
public:
BoundaryFluxPostprocessor(const InputParameters & parameters);

virtual Real computeQpIntegral() override;

protected:
/// Boundary flux user object
const BoundaryFluxBase & _boundary_flux_uo;

/// Index within flux vector to query
const unsigned int & _flux_index;

/// Did the user request to override the boundary normal?
const bool _provided_normal;

/// Number of components in the solution vector used to compute the flux
const unsigned int _n_components;

/// Variables to pass to boundary flux user object, in the correct order
std::vector<const VariableValue *> _U;
};

#endif /* BOUNDARYFLUXPOSTPROCESSOR_H */
@@ -0,0 +1,56 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "BoundaryFluxPostprocessor.h"
#include "BoundaryFluxBase.h"

registerMooseObject("RdgApp", BoundaryFluxPostprocessor);

template <>
InputParameters
validParams<BoundaryFluxPostprocessor>()
{
InputParameters params = validParams<SideIntegralPostprocessor>();

params.addRequiredParam<UserObjectName>("boundary_flux_uo", "Boundary flux user object name");
params.addRequiredParam<unsigned int>("flux_index", "Index within flux vector to query");
params.addParam<Point>("normal", "Normal vector for boundary (if requesting override)");
params.addRequiredCoupledVar(
"variables", "Variables to pass to boundary flux user object, in the correct order");

params.addClassDescription(
"Computes the side integral of a flux entry from a BoundaryFluxBase user object");

return params;
}

BoundaryFluxPostprocessor::BoundaryFluxPostprocessor(const InputParameters & parameters)
: SideIntegralPostprocessor(parameters),

_boundary_flux_uo(getUserObject<BoundaryFluxBase>("boundary_flux_uo")),
_flux_index(getParam<unsigned int>("flux_index")),
_provided_normal(isParamValid("normal")),
_n_components(coupledComponents("variables"))
{
for (unsigned int i = 0; i < _n_components; i++)
_U.push_back(&coupledValue("variables", i));
}

Real
BoundaryFluxPostprocessor::computeQpIntegral()
{
std::vector<Real> U(_n_components);
for (unsigned int i = 0; i < _n_components; i++)
U[i] = (*_U[i])[_qp];

const Point & normal = _provided_normal ? getParam<Point>("normal") : _normals[_qp];

const auto & flux = _boundary_flux_uo.getFlux(_current_side, _current_elem->id(), U, normal);
return flux[_flux_index];
}
@@ -0,0 +1,41 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifndef TESTBOUNDARYFLUX_H
#define TESTBOUNDARYFLUX_H

#include "BoundaryFluxBase.h"

class TestBoundaryFlux;

template <>
InputParameters validParams<TestBoundaryFlux>();

/**
* Boundary flux used for testing
*/
class TestBoundaryFlux : public BoundaryFluxBase
{
public:
TestBoundaryFlux(const InputParameters & parameters);

virtual void calcFlux(unsigned int iside,
dof_id_type ielem,
const std::vector<Real> & uvec1,
const RealVectorValue & dwave,
std::vector<Real> & flux) const override;

virtual void calcJacobian(unsigned int iside,
dof_id_type ielem,
const std::vector<Real> & uvec1,
const RealVectorValue & dwave,
DenseMatrix<Real> & jac1) const override;
};

#endif
@@ -0,0 +1,54 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "TestBoundaryFlux.h"

registerMooseObject("RdgTestApp", TestBoundaryFlux);

template <>
InputParameters
validParams<TestBoundaryFlux>()
{
InputParameters params = validParams<BoundaryFluxBase>();
params.addClassDescription("Boundary flux used for testing");
return params;
}

TestBoundaryFlux::TestBoundaryFlux(const InputParameters & parameters)
: BoundaryFluxBase(parameters)
{
}

void
TestBoundaryFlux::calcFlux(unsigned int /*iside*/,
dof_id_type /*ielem*/,
const std::vector<Real> & solution,
const RealVectorValue & normal,
std::vector<Real> & flux) const
{
mooseAssert(solution.size() == 3, "Solution vector must have exactly 3 entries.");

const Real & A = solution[0];
const Real & B = solution[1];
const Real & C = solution[2];

flux.resize(2);
flux[0] = (A - B) * C * normal(0);
flux[1] = A * B * normal(0);
}

void
TestBoundaryFlux::calcJacobian(unsigned int /*iside*/,
dof_id_type /*ielem*/,
const std::vector<Real> & /*uvec*/,
const RealVectorValue & /*dwave*/,
DenseMatrix<Real> & /*jac1*/) const
{
mooseError("Not implemented.");
}
@@ -0,0 +1,149 @@
# This input file is used to test BoundaryFluxPostprocessor, which queries
# fluxes computed using user objects derived from BoundaryFluxBase. The boundary
# flux used in this test is TestBoundaryFlux, which expects a solution vector
# of size 3 (call this U = {A, B, C}) and computes a flux of size 2 with the
# following entries:
#
# flux[0] = (A - B) * C * nx
# flux[1] = A * B * nx
#
# where the normal vector used is {nx, ny, nz}.

A = 1
B = 2
C = 3

# Multiple cases are computed in this test. Each corresponds to a different PP object:
# * flux0_boundary0: boundary 0, flux entry 0, default normal ({-1, 0, 0})
# * flux0_boundary1: boundary 1, flux entry 0, default normal ({1, 0, 0})
# * flux0_provided: boundary 0, flux entry 0, user-provided normal ({2, 0, 0})
# * flux1_boundary0: boundary 0, flux entry 1, default normal ({-1, 0, 0})

nx_boundary0 = -1
nx_boundary1 = 1
nx_provided = 2

flux0_boundary0 = ${fparse (A - B) * C * nx_boundary0}
flux0_boundary1 = ${fparse (A - B) * C * nx_boundary1}
flux0_provided = ${fparse (A - B) * C * nx_provided}
flux1_boundary0 = ${fparse A * B * nx_boundary0}

[GlobalParams]
order = CONSTANT
family = MONOMIAL
execute_on = 'initial timestep_end'
variables = 'A B C'
[]

[Postprocessors]
[./flux0_boundary0]
type = BoundaryFluxPostprocessor
boundary_flux_uo = boundary_flux_flux0_boundary0
boundary = 0
flux_index = 0
[../]
[./flux0_boundary1]
type = BoundaryFluxPostprocessor
boundary_flux_uo = boundary_flux_flux0_boundary1
boundary = 1
flux_index = 0
[../]
[./flux0_provided]
type = BoundaryFluxPostprocessor
boundary_flux_uo = boundary_flux_flux0_provided
boundary = 0
flux_index = 0
normal = '${nx_provided} 0 0'
[../]
[./flux1_boundary0]
type = BoundaryFluxPostprocessor
boundary_flux_uo = boundary_flux_flux1_boundary0
boundary = 0
flux_index = 1
[../]

[./flux0_boundary0_err]
type = RelativeDifferencePostprocessor
value1 = flux0_boundary0
value2 = ${flux0_boundary0}
[../]
[./flux0_boundary1_err]
type = RelativeDifferencePostprocessor
value1 = flux0_boundary1
value2 = ${flux0_boundary1}
[../]
[./flux0_provided_err]
type = RelativeDifferencePostprocessor
value1 = flux0_provided
value2 = ${flux0_provided}
[../]
[./flux1_boundary0_err]
type = RelativeDifferencePostprocessor
value1 = flux1_boundary0
value2 = ${flux1_boundary0}
[../]
[]

[UserObjects]
[./boundary_flux_flux0_boundary0]
type = TestBoundaryFlux
[../]
[./boundary_flux_flux0_boundary1]
type = TestBoundaryFlux
[../]
[./boundary_flux_flux0_provided]
type = TestBoundaryFlux
[../]
[./boundary_flux_flux1_boundary0]
type = TestBoundaryFlux
[../]
[]

[Variables]
[./A]
[../]
[./B]
[../]
[./C]
[../]
[]

[ICs]
[./A_ic]
type = ConstantIC
variable = A
value = ${A}
[../]
[./B_ic]
type = ConstantIC
variable = B
value = ${B}
[../]
[./C_ic]
type = ConstantIC
variable = C
value = ${C}
[../]
[]

[Mesh]
type = GeneratedMesh
dim = 1
[]

[Problem]
kernel_coverage_check = false
solve = false
[]

[Executioner]
type = Transient
scheme = implicit-euler
dt = 1
num_steps = 1
[]

[Outputs]
csv = true
show = 'flux0_boundary0_err flux0_boundary1_err flux0_provided_err flux1_boundary0_err'
[]
@@ -0,0 +1,3 @@
time,flux0_boundary0_err,flux0_boundary1_err,flux0_provided_err,flux1_boundary0_err
0,0,0,0,0
1,0,0,0,0
@@ -0,0 +1,16 @@
[Tests]
[./test]
type = 'CSVDiff'
input = 'boundary_flux_postprocessor.i'
csvdiff = 'boundary_flux_postprocessor_out.csv'
rel_err = 0
abs_zero = 1e-15

allow_test_objects = true
threading = '!pthreads'

requirement = "BoundaryFluxPostprocessor shall output correct boundary flux values."
issues = '#13178'
design = '/BoundaryFluxPostprocessor.md'
[../]
[]

0 comments on commit ecd3198

Please sign in to comment.
You can’t perform that action at this time.