Geometry library
The loadable library is accessible from Python and Ruby. It provides access to geometry functions for the construction of paths and surfaces compatible with those available in the Eilmer flow solver.
This is the reference manual for the Python flavour of the library and,
because of the history of development, the library comes in the eilmer
package.
For example, to construct a simple linear path element
from within your Python script and then evaluate the midpoint on that line,
you might try the following:
from eilmer.geom.vector3 import Vector3 from eilmer.geom.path import * a = Vector3(0.0, 2.0) b = Vector3(2.0, 0.0) line_ab = Line(p0=a, p1=b) print("line_ab=", line_ab) c = line_ab(0.5)
If you have not yet read the Geometry Package User Guide, this is a good time to do so.
1. Installing the library
The geometry library for Python3 is part of a larger gasdynamics toolkit and general getting started notes can be found at https://gdtk.uqcloud.net/docs/gettingstarted/prerequisites . There, you will see how to get a copy of the source code, and a list of what other software you will need to build and install the tool kit, and a collection of environment variables that need to be set.
To install the library, move to the gas source directory and use the make
utility.
cd dgd/src/gas make install
Even though this part of the package is a pure Python library, the rest of the loadable library, including gas models, will be built and installed with this command. So that the Python interpreter can find the installed library, set your environment variables with something like:
export DGD=$HOME/dgdinst export PYTHONPATH=${PYTHONPATH}:${DGD}/lib
2. Geometric elements
These functions are the Python equivalent of the Lua functions found in the Geometry User Guide.
2.1. Vector3
This class defines geometric vector objects with three Cartesian components:
x
, y
and z
.
The constructor accepts values for these components in a number of ways.
from eilmer.geom.vector3 import Vector3 p0 = Vector3(x=1.0, y=2.0, z=3.0) # named arguments p1 = Vector3(1.0, 2.0, 3.0) # positional arguments x, y, z p2 = Vector3([1.0, 2.0, 3.0]) # list of numbers p3 = Vector3({'x':1.0, 'y':2.0, 'z':3.0}) # dictionary p4 = Vector3(p3) # another Vector3 object
You need to specify at least the x
component.
The y
and z
components will default to values of 0.0
.
2.1.1. Vector3 expressions
A number of methods have been defined so that you can write arithmetic expressions that involve Vector3 objects. To see the embedded doc strings, you can use the Python help function.
from eilmer.geom.vector3 import Vector3 help(Vector3)
Sample expressions include:
from eilmer.geom.vector3 import Vector3 p0 = Vector3(x=1.0, y=2.0, z=3.0) p1 = Vector3(1.0, 2.0, 3.0) p2 = +p0 # positive copy > Vector3(x=1.0, y=2.0, z=3.0) p2 = p0 # negative copy > Vector3(x=1.0, y=2.0, z=3.0) p2 = p0 + p1 # addition > Vector3(x=2.0, y=4.0, z=6.0) p2 = p0  p1 # subtraction > Vector3(x=0.0, y=0.0, z=0.0) p2 += p1 # augmented addition > Vector3(x=1.0, y=2.0, z=3.0) p2 = p1 # augmented subtraction > Vector3(x=0.0, y=0.0, z=0.0) p2 = Vector3(p0) p2 = p0 * 3.0 # scaling > Vector3(x=3.0, y=6.0, z=9.0) p2 = 3.0 * p0 # scaling > Vector3(x=3.0, y=6.0, z=9.0) p2 = p0 / 3.0 # scaling > Vector3(x=0.333333, y=0.666666, z=1.0) p2 *= 3.0 # scaling > Vector3(x=1.0, y=2.0, z=3.0) p2 /= 3.0 # scaling > Vector3(x=0.333333, y=0.666666, z=1.0) p2.normalize() # scales to unit magnitude > Vector3(x=0.267261, y=0.534522, z=0.801783) a = abs(p2) # magnitude > 1.0 b = p1.dot(p0) # dot product > 14.0 p2 = p0.unit() # new unit vector > Vector3(x=0.267261, y=0.534522, z=0.801783)
There are also a pair of transformations, so that you change change into and out of a local coordinate system.
from eilmer.geom.vector3 import Vector3 p0 = Vector3(x=1.0, y=2.0, z=3.0) c = Vector3(0.0, 1.0, 2.0) n = Vector3(1.0, 0.0, 0.0) t1 = Vector3(0.0, 1.0, 0.0) t2 = Vector3(0.0, 0.0, 1.0) p1 = p0.transform_to_local_frame(n, t1, t2, c) # > Vector3(x=1.0, y=1.0, z=1.0) p2 = p1.transform_to_global_frame(n, t1, t2, c) # > Vector3(x=1.0, y=2.0, z=3.0)
Remember that the Python assignment operator binds names to objects.
from eilmer.geom.vector3 import Vector3 p0 = Vector3(x=1.0, y=2.0, z=3.0) p1 = Vector3(1.0, 2.0, 3.0) p2 = p1 # assignment binds new name p2 to same object as p1 p2 # > Vector3(x=1.0, y=2.0, z=3.0) p1.normalize() # change object details p2 # > Vector3(x=0.267261, y=0.534522, z=0.801783) p1 = p0 # change binding for name p1 p1 # > Vector3(x=1.0, y=2.0, z=3.0) p2 # > Vector3(x=0.267261, y=0.534522, z=0.801783)
2.1.2. Other functions
The other functions in module eilmer.geom.vector3
include:
approxEqualVectors(a, b, rel_tol=0.01, abs_tol=1e05)

Returns
True
if all components if vectorsa
andb
are close. cross(a, b)

Returns the Vector3 cross product of vector
a
with vectorb
. dot(a, b)

Returns dot product of vector
a
with vectorb
. hexahedron_properties(p0, p1, p2, p3, p4, p5, p6, p7)

Returns centroid and volume for the hexahedron defined by the 8 vertices.
hexahedron_volume(p0, p1, p2, p3, p4, p5, p6, p7)

Returns volume for the hexahedron defined by the 8 vertices.
quad_area(p0, p1, p2, p3)

Returns area for quadrilateral defined by the 4 corner points.
quad_centroid(p0, p1, p2, p3)

Returns centroid of quadrilateral.
quad_normal(p0, p1, p2, p3)

Returns unit normal for quadrilateral.
quad_properties(p0, p1, p2, p3)

Returns centroid, quadrilateraldefining unit vectors, and area.
tetrahedron_properties(p0, p1, p2, p3)

Returns centroid and volume of tetrahedron defined by 4 points.
unit(a)

Returns a new unit vector.
wedge_properties(p0, p1, p2, p3, p4, p5)

Returns centroid and volume for wedge defined by 6 points.
2.2. Path elements
The module eilmer.geom.path
includes classes for making Path
objects.
A Path object may be called to evaluate a point on the path at parameter t
,
where the parametric range is 0.0
to 1.0
.
The constructors for Path objects include:
Line(p0, p1)

Defines a straight line from point
p0
(t=0
) to pointp1
(t=1
). Bezier(B)

Defines a Bezier curve from the sequence of points
B
. NURBS(P, w, U, p)

Defines a NURBS from control points
P
, weightsw
, knot vectorU
and degreep
. Arc(a, b, c)

Defines a circular arc from point
a
to pointb
about centrec
. ArcLengthParameterizedPath(underlying_path, n=1000)

Derives path from
underlying_path
that has a uniformlydistributed set of points with parametert
. Polyline(segments, closed=False, tolerance=1e10)

Builds a single path from a sequence of
Path
objects. Settingclosed=True
will connect the ends with a straightline segment if the original end points are further apart thantolerance
. Spline(points, closed=False, tolerance=1e10)

Builds a spline of Bezier segments through the sequence of points. Setting
closed=True
will connect the ends with an extra segment if the original end points are further apart thantolerance
.
2.3. ParametricSurface elements
The module eilmer.geom.surface
includes classes for making ParametricSurface
objects.
These objects may be called two parameters r
, and s
to evaluate a point on the surface.
Presently, only one class of ParametricSurface
is implemented in the Python module.
CoonsPatch(north=None, east=None, south=None, west=None, p00=None, p10=None, p11=None, p01=None)

Define a surface using the method of interpolation described in S.A. Coons "Surfaces for Computer Aided Design of Space Forms" MAC TR41 Contract No. AF33 (600042859) MIT June 1967. The surface may be defined either by 4
Path
objects as edges (namednorth
,east
,south
,west
) or by 4 corner points (namedp00
,p10
,p11
,p01
). If defined by corner points, straightline paths will be used for the 4 edges.
2.4. Cluster functions
The module eilmer.geom.cluster
includes classes for constructing various
ClusterFunction
objects.
These objects have a distribute_parameter_values(nv)
method that returns
a sequence of nv
values spread over the parameter range 0.0
to 1.0
, inclusive.
2.4.1. Linear
from eilmer.geom.cluster import * cf = LinearFunction() values = cf.distribute_parameter_values(11)
will result in values
being array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
.
2.4.2. Roberts
If you want to cluster values toward either (or both) ends of the range,
there is RobertsFunction(end0, end1, beta)
where:
end0

Set
True
to cluster values towardt=0
. end1

Set
True
to cluster values towardt=1
. beta

The clustering parameter is larger than 1.0, and clustering increases in strength as
beta
approaches1.0
.
3. Grid elements
3.1. StructuredGrid
The constructor for a structuredgrid object accepts all of its arguments via keywords. For example:
from eilmer.geom.vector3 import Vector3 from eilmer.geom.surface import CoonsPatch from eilmer.geom.sgrid import StructuredGrid from eilmer.geom.cluster import RobertsFunction my_patch = CoonsPatch(p01=Vector3(0.1, 0.9), p11=Vector3(1.0, 1.0), p00=Vector3(0.0, 0.0), p10=Vector3(0.9, 0.1)) cf_y = RobertsFunction(True, False, 1.1) g = StructuredGrid(psurf=my_patch, niv=11, njv=5, cf_list=[None, cf_y, None, cf_y]) g.write_to_vtk_file("my_grid.vtk")