underworld.function module¶
The function module contains the Function class, and related classes.
Function objects are constructed in python, but evaluated in C for efficiency. They provide a high level interface for users to compose model behaviour (such as viscosity), as well as a natural interface by which discrete data (such as meshvariables) may be utilised.
Submodules¶
underworld.function.analytic |
This module provides a suite of models which satisfy the Stokes system of equations. |
underworld.function.branching |
The branching module provides functions which provide branching behaviour. |
underworld.function.exception |
This module provides functions which raise an exception when given conditions are encountered during function evaluations. |
underworld.function.math |
This module provides math functions. |
underworld.function.misc |
Miscellaneous functions. |
underworld.function.rheology |
This module contains functions relating to rheological operations. |
underworld.function.shape |
This module includes shape type functions. |
underworld.function.tensor |
This module provides functions relating to tensor operations. |
underworld.function.view |
This module includes functions which provide views into the results of function queries. |
Classes¶
underworld.function.Function |
Objects which inherit from this class provide user definable functions within Underworld. |
underworld.function.FunctionInput |
Objects that inherit from this class are able to act as inputs to function evaluation from python. |
underworld.function.coord |
alias of underworld.function._function.input |
underworld.function.input |
This class generates a function which simply passes through its input. |
-
class
underworld.function.
Function
(argument_fns, **kwargs)[source]¶ Bases:
underworld._stgermain.LeftOverParamsChecker
Objects which inherit from this class provide user definable functions within Underworld.
Functions aim to achieve a number of goals: * Provide a natural interface for mathematical behaviour description within python. * Provide a high level interface to Underworld discrete objects. * Allow discrete objects to be used in combination with continuous objects. * Handle the evaluation of discrete objects in the most efficient manner. * Perform all heavy calculations at the C-level for efficiency. * Provide an interface for users to evaluate functions directly within python, utilising numpy arrays for input/output.
-
__add__
(other)[source]¶ Operator overloading for ‘+’ operation:
Fn3 = Fn1 + Fn2
Creates a new function Fn3 which performs additions of Fn1 and Fn2.
Returns: fn.add Return type: Add function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> three = misc.constant(3.) >>> four = misc.constant(4.) >>> np.allclose( (three + four).evaluate(0.), [[ 7.]] ) # note we can evaluate anywhere because it's a constant True
-
__and__
(other)[source]¶ Operator overloading for ‘&’ operation:
Fn3 = Fn1 & Fn2
Creates a new function Fn3 which returns a bool result for the operation.
Returns: fn.logical_and Return type: AND function Examples
>>> import underworld.function.misc as misc >>> trueFn = misc.constant(True) >>> falseFn = misc.constant(False) >>> (trueFn & falseFn).evaluate() array([[False]], dtype=bool)
Notes
The ‘&’ operator in python is usually used for bitwise ‘and’ operations, with the ‘and’ operator used for boolean type operators. It is not possible to overload the ‘and’ operator in python, so instead the bitwise equivalent has been utilised.
-
__ge__
(other)[source]¶ Operator overloading for ‘>=’ operation:
Fn3 = Fn1 >= Fn2
Creates a new function Fn3 which returns a bool result for the relation.
Returns: fn.greater_equal Return type: Greater than or equal to function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> two = misc.constant(2.) >>> (two >= two).evaluate() array([[ True]], dtype=bool)
-
__getitem__
(index)[source]¶ Operator overloading for ‘[]’ operation:
FnComponent = Fn[0]
Creates a new function FnComponent which returns the required component of Fn.
Returns: fn.at Return type: component function Examples
>>> import underworld.function.misc as misc >>> fn = misc.constant((2.,3.,4.)) >>> np.allclose( fn[1].evaluate(0.), [[ 3.]] ) # note we can evaluate anywhere because it's a constant True
-
__gt__
(other)[source]¶ Operator overloading for ‘>’ operation:
Fn3 = Fn1 > Fn2
Creates a new function Fn3 which returns a bool result for the relation.
Returns: fn.greater Return type: Greater than function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> two = misc.constant(2.) >>> four = misc.constant(4.) >>> (two > four).evaluate() array([[False]], dtype=bool)
-
__le__
(other)[source]¶ Operator overloading for ‘<=’ operation:
Fn3 = Fn1 <= Fn2
Creates a new function Fn3 which returns a bool result for the relation.
Returns: fn.less_equal Return type: Less than or equal to function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> two = misc.constant(2.) >>> (two <= two).evaluate() array([[ True]], dtype=bool)
-
__lt__
(other)[source]¶ Operator overloading for ‘<’ operation:
Fn3 = Fn1 < Fn2
Creates a new function Fn3 which returns a bool result for the relation.
Returns: fn.less Return type: Less than function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> two = misc.constant(2.) >>> four = misc.constant(4.) >>> (two < four).evaluate() array([[ True]], dtype=bool)
-
__mul__
(other)[source]¶ Operator overloading for ‘*’ operation:
Fn3 = Fn1 * Fn2
Creates a new function Fn3 which returns the product of Fn1 and Fn2.
Returns: fn.multiply Return type: Multiply function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> three = misc.constant(3.) >>> four = misc.constant(4.) >>> np.allclose( (three*four).evaluate(0.), [[ 12.]] ) # note we can evaluate anywhere because it's a constant True
-
__neg__
()[source]¶ Operator overloading for unary ‘-‘.
FnNeg = -Fn
Creates a new function FnNeg which is the negative of Fn.
Returns: fn.multiply Return type: Negative function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> four = misc.constant(4.) >>> np.allclose( (-four).evaluate(0.), [[ -4.]] ) # note we can evaluate anywhere because it's a constant True
-
__or__
(other)[source]¶ Operator overloading for ‘|’ operation:
Fn3 = Fn1 | Fn2
Creates a new function Fn3 which returns a bool result for the operation.
Returns: fn.logical_or Return type: OR function Examples
>>> import underworld.function.misc as misc >>> trueFn = misc.constant(True) >>> falseFn = misc.constant(False) >>> (trueFn | falseFn).evaluate() array([[ True]], dtype=bool)
Notes
The ‘|’ operator in python is usually used for bitwise ‘or’ operations, with the ‘or’ operator used for boolean type operators. It is not possible to overload the ‘or’ operator in python, so instead the bitwise equivalent has been utilised.
-
__pow__
(other)[source]¶ Operator overloading for ‘**’ operation:
Fn3 = Fn1 ** Fn2
Creates a new function Fn3 which returns Fn1 to the power of Fn2.
Returns: fn.math.pow Return type: Power function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> two = misc.constant(2.) >>> four = misc.constant(4.) >>> np.allclose( (two**four).evaluate(0.), [[ 16.]] ) # note we can evaluate anywhere because it's a constant True
-
__radd__
(other)¶ Operator overloading for ‘+’ operation:
Fn3 = Fn1 + Fn2
Creates a new function Fn3 which performs additions of Fn1 and Fn2.
Returns: fn.add Return type: Add function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> three = misc.constant(3.) >>> four = misc.constant(4.) >>> np.allclose( (three + four).evaluate(0.), [[ 7.]] ) # note we can evaluate anywhere because it's a constant True
-
__rmul__
(other)¶ Operator overloading for ‘*’ operation:
Fn3 = Fn1 * Fn2
Creates a new function Fn3 which returns the product of Fn1 and Fn2.
Returns: fn.multiply Return type: Multiply function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> three = misc.constant(3.) >>> four = misc.constant(4.) >>> np.allclose( (three*four).evaluate(0.), [[ 12.]] ) # note we can evaluate anywhere because it's a constant True
-
__rsub__
(other)[source]¶ Operator overloading for ‘-’ operation. Right hand version.
Fn3 = Fn1 - Fn2
Creates a new function Fn3 which performs subtraction of Fn2 from Fn1.
Returns: fn.subtract Return type: RHS subtract function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> four = misc.constant(4.) >>> np.allclose( (5. - four).evaluate(0.), [[ 1.]] ) # note we can evaluate anywhere because it's a constant True
-
__sub__
(other)[source]¶ Operator overloading for ‘-’ operation:
Fn3 = Fn1 - Fn2
Creates a new function Fn3 which performs subtraction of Fn2 from Fn1.
Returns: fn.subtract Return type: Subtract function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> three = misc.constant(3.) >>> four = misc.constant(4.) >>> np.allclose( (three - four).evaluate(0.), [[ -1.]] ) # note we can evaluate anywhere because it's a constant True
-
__truediv__
(other)[source]¶ Operator overloading for ‘/’ operation:
Fn3 = Fn1 / Fn2
Creates a new function Fn3 which returns the quotient of Fn1 and Fn2.
Returns: fn.divide Return type: Divide function Examples
>>> import underworld.function.misc as misc >>> import numpy as np >>> two = misc.constant(2.) >>> four = misc.constant(4.) >>> np.allclose( (four/two).evaluate(0.), [[ 2.]] ) # note we can evaluate anywhere because it's a constant True
-
__xor__
(other)[source]¶ Operator overloading for ‘^’ operation:
Fn3 = Fn1 ^ Fn2
Creates a new function Fn3 which returns a bool result for the operation.
Returns: fn.logical_xor Return type: XOR function Examples
>>> import underworld.function.misc as misc >>> trueFn = misc.constant(True) >>> falseFn = misc.constant(False) >>> (trueFn ^ falseFn).evaluate() array([[ True]], dtype=bool) >>> (trueFn ^ trueFn).evaluate() array([[False]], dtype=bool) >>> (falseFn ^ falseFn).evaluate() array([[False]], dtype=bool)
Notes
The ‘^’ operator in python is usually used for bitwise ‘xor’ operations, however here we always use the logical version, with the operation inputs cast to their bool equivalents before the operation.
-
static
convert
(obj)[source]¶ This method will attempt to convert the provided input into an equivalent underworld function. If the provided input is already of Function type, it is immediately returned. Likewise, if the input is of None type, it is also returned.
Parameters: obj (fn_like) – The object to be converted. Note that if obj is of type None or Function, it is simply returned immediately. Where obj is of type int/float/double, a Constant type function is returned which evaluates to the provided object’s value. Where obj is of type list/tuple, a function will be returned which evaluates to a vector of the provided list/tuple’s values (where possible). Returns: Return type: Fn.Function or None. Examples
>>> import underworld as uw >>> import underworld.function as fn
>>> fn_const = fn.Function.convert( 3 ) >>> fn_const.evaluate(0.) # eval anywhere for constant array([[3]], dtype=int32)
>>> fn_const == fn.Function.convert( fn_const ) True
>>> fn.Function.convert( None )
>>> fn1 = fn.input() >>> fn2 = 10.*fn.input() >>> fn3 = 100.*fn.input() >>> vec = (fn1,fn2,fn3) >>> fn_vec = fn.Function.convert(vec) >>> fn_vec.evaluate([3.]) array([[ 3., 30., 300.]])
-
evaluate
(inputData=None, inputType=None)[source]¶ This method performs evaluate of a function at the given input(s).
It accepts floats, lists, tuples, numpy arrays, or any object which is of class FunctionInput. lists/tuples must contain floats only.
FunctionInput class objects are shortcuts to their underlying data, often with performance advantages, and sometimes they are the only valid input type (such as using Swarm objects as an inputs to SwarmVariable evaluation). Objects of class FeMesh, Swarm, FeMesh_IndexSet and VoronoiIntegrationSwarm are also of class FunctionInput. See the Function section of the user guide for more information.
Results are returned as numpy array.
Parameters: - inputData (float, list, tuple, ndarray, underworld.function.FunctionInput) – The input to the function. The form of this input must be appropriate for the function being evaluated, or an exception will be thrown. Note that if no input is provided, function will be evaluated at 0.
- inputType (str) – Specifies the type the provided data represents. Acceptable values are ‘scalar’, ‘vector’, ‘symmetrictensor’, ‘tensor’, ‘array’.
Returns: ndarray
Return type: array of results
Examples
>>> import math as sysmath >>> import underworld.function.math as fnmath >>> sinfn = fnmath.sin()
Single evaluation:
>>> np.allclose( sinfn.evaluate(sysmath.pi/4.), [[ 0.5*sysmath.sqrt(2.)]] ) True
Multiple evaluations
>>> input = (0.,sysmath.pi/4.,2.*sysmath.pi) >>> np.allclose( sinfn.evaluate(input), [[ 0., 0.5*sysmath.sqrt(2.), 0.]] ) True
Single MeshVariable evaluations
>>> mesh = uw.mesh.FeMesh_Cartesian() >>> var = uw.mesh.MeshVariable(mesh,1) >>> import numpy as np >>> var.data[:,0] = np.linspace(0,1,len(var.data)) >>> result = var.evaluate( (0.2,0.5 ) ) >>> np.allclose( result, np.array([[ 0.45]]) ) True
Numpy input MeshVariable evaluation
>>> # evaluate at a set of locations.. provide these as a numpy array. >>> count = 10 >>> # create an empty array >>> locations = np.zeros( (count,2)) >>> # specify evaluation coodinates >>> locations[:,0] = 0.5 >>> locations[:,1] = np.linspace(0.,1.,count) >>> # evaluate >>> result = var.evaluate(locations) >>> np.allclose( result, np.array([[ 0.08333333], [ 0.17592593], [ 0.26851852], [ 0.36111111], [ 0.4537037 ], [ 0.5462963 ], [ 0.63888889], [ 0.73148148], [ 0.82407407], [ 0.91666667]]) ) True
Using the mesh object as a FunctionInput
>>> np.allclose( var.evaluate(mesh), var.evaluate(mesh.data)) True
Also note that if evaluating across an empty input, an empty output is returned. Note that the shape and type of the output is always fixed and may differ from the shape/type returned for an actual (non-empty) evaluation. Usually this should not be an issue. >>> var.evaluate(np.zeros((0,2))) array([], shape=(0, 1), dtype=float64) >>> var.evaluate(mesh.specialSets[“Empty”]) array([], shape=(0, 1), dtype=float64)
-
evaluate_global
(inputData, inputType=None)[source]¶ This method attempts to evalute inputData across all processes, and then consolide the results on the root processor. This is most useful where you wish to evalute your functions using global coordinates which may span processes in a parallel simulation.
Note that this method does not currently support ‘FunctionInput’ class input data.
Due to the communications required for this method, a significant performance overhead may be encountered. The standard evaluate method should be used instead wherever possible.
Please see evaluate method for parameter details.
Notes
This method must be called collectively by all processes.
Returns: - Only the root process gets the final results array. All other processes
- are returned None.
-
integrate
(mesh)[source]¶ Perform an integral of this underworld function over the given mesh
Parameters: mesh (uw.mesh.FeMesh_Cartesian) – Domain to perform integral over. Examples
>>> mesh = uw.mesh.FeMesh_Cartesian(minCoord=(0.0,0.0), maxCoord=(1.0,2.0)) >>> fn_1 = uw.function.misc.constant(2.0) >>> np.allclose( fn_1.integrate( mesh )[0], 4 ) True
>>> fn_2 = uw.function.misc.constant(2.0) * (0.5, 1.0) >>> np.allclose( fn_2.integrate( mesh ), [2,4] ) True
-
-
class
underworld.function.
FunctionInput
(*args, **kwargs)[source]¶ Bases:
underworld._stgermain.LeftOverParamsChecker
Objects that inherit from this class are able to act as inputs to function evaluation from python.
-
underworld.function.
coord
¶ alias of
underworld.function._function.input
-
class
underworld.function.
input
(*args, **kwargs)[source]¶ Bases:
underworld.function._function.Function
This class generates a function which simply passes through its input. It is the identity function. It is often useful when construct functions where the input itself needs to be accessed, such as to extract a particular component.
For example, you may wish to use this function when you wish to extract a particular coordinate component for manipulation. For this reason, we also provide an alias to this class called ‘coord’.
Returns: fn.input Return type: the input function Examples
Here we see the input function simply passing through its input.
>>> infunc = input() >>> np.allclose( infunc.evaluate( (1.,2.,3.) ), [ 1., 2., 3.] ) True
Often this behaviour is useful when we want to construct a function which operates on only a particular coordinate, such as a depth dependent density. We may wish to extract the z coordinate (in 2d):
>>> zcoord = input()[1] >>> baseDensity = 1. >>> density = baseDensity - 0.01*zcoord >>> testCoord1 = (0.1,0.4) >>> testCoord2 = (0.9,0.4) >>> np.allclose( density.evaluate( testCoord1 ), density.evaluate( testCoord2 ) ) True