GeMA
The GeMA main application
Spatial index object methods

Spatial index objects are a Lua wrapper over a GeMA spatial index providing a set of methods for executing spatial queries. They can be obtained in the orchestration by calling modelData:spatialIndex(). Some process plugins (see MmProcess) can also be used to create a spatial index during the orchestration.

Example:

-- Get a reference to the spatial index named 'myIndex'
local sindex = modelData:spatialIndex('myIndex')

Index:

Metadata methods

sindex:id()
Description: Returns the spatial index name.
Parameters: None.
Returns: Returns a string with the spatial index name (the id attribute given during its model definition).

Example:

-- Print the spatial index name
print(sindex:id())


sindex:hasCapability(capName)
Description: Check spatial index capabilities. Capabilities are query functionalities that are optionally implemented by an index plugin. This function allows to check if the index implements or not each of the optional functionalities.
Parameters: capName - The capability name to be queried. Standard capability names are "nearestNode", "nearestGauss", and "containingCell". Other capabilities might be implemented by specific index plugins.
Returns: Returns true if the spatial index supports the requested functionality, false if not.

Example:

if not sindex:hasCapability('containingCell') then
error('Model requires a spatial index capable of querying the cell that contains a given coordinate')
end


Nearest nodes methods

The following set of methods can only be called if the spatial index object supports the nearestNode capability.

sindex:closestNode(pointCoord)
Description: Given a point in the mesh domain, find the closest node to that point.
Important: only works if the index supports the nearestNode capability.
Parameters: pointCoord - A lua table with the point coordinates.
Returns: The closest node global id (integer) and the squared distance between the point and the node (real number).


sindex:closestNodes(pointCoord, n)
Description: Given a point in the mesh domain, find the n closest nodes to that point.
Important: only works if the index supports the nearestNode capability.
Parameters: pointCoord A lua table with the point coordinates.
n The number of nodes to query.
Returns: Two equal-sized lua tables, the first with the global ids of the closest nodes (list of integers) and the second with the associated squared distances between the target point and the closest nodes (list of positive real numbers). The lists are ordered by ascending distance.


sindex:closestNodesInRadius(pointCoord, r)
Description: Given a point in the mesh domain, find all the nodes in the region that has the given coordinate as its center and the given radius.
Important: only works if the index supports the nearestNode capability.
Parameters: pointCoord A lua table with the point coordinates.
r The distance from the target point which delimits the closest nodes region.
Returns: Two equal-sized lua tables, the first with the global ids of the closest nodes (list of integers) and the second with the associated squared distances between the target point and the closest nodes (list of positive real numbers). The lists are ordered by ascending distance.

The following code fragment is a quick validation test that checks if the closest node of a given node is itself:

local sindex = modelData:spatialIndex('myIndex')
assert(sindex:hasCapability('nearestNode')
local mesh = modelData:mesh('meshId')
local coordAc = mesh:nodeCoordAccessor()
local coord = coordAc:value(1)
local nodeId, sqDist = sindex:closestNode(coord)
assert( nodeId == 1 and equal(sqDist, 0) )

Here it shows how to print the ids of the four closest nodes of a given node and its associated squared distances and how to get the same result using the radius criterion:

local sindex = modelData:spatialIndex('myIndex')
assert(sindex:hasCapability('nearestNode')
local mesh = modelData:mesh('meshId')
local coordAc = mesh:nodeCoordAccessor()
local coord = coordAc:value(1)
local n = 5
local nodeId, sqDist = sindex:closestNodes(coord, n)
assert( #nodeId == n )
assert( #sqDist == n )
assert( nodeId[1] == 1 and equal(sqDist[1], 0) )
print( nodeId[2]..' '..sqDist[2] )
print( nodeId[3]..' '..sqDist[3] )
print( nodeId[4]..' '..sqDist[4] )
print( nodeId[5]..' '..sqDist[5] )
local r = math.sqrt(sqDist[5])
nodeId, sqDist = sindex:closestNodesInRadius(coord, r)
assert(#nodeId >= n)
assert( nodeId[1] == 1 and equal(sqDist[1], 0) )
print( nodeId[2]..' '..sqDist[2] )
print( nodeId[3]..' '..sqDist[3] )
print( nodeId[4]..' '..sqDist[4] )
print( nodeId[5]..' '..sqDist[5] )


Containing cell methods

The following set of methods can only be called if the spatial index object supports the containingCell capability.

sindex:containingCell(pointCoord)
Description: Given a point in the mesh domain, find its containing cell.
Important: only works if the index supports the containingCell capability.
Parameters: pointCoord - A lua table with the point coordinates.
Returns: The containing cell object or nil if no cell was found.

One can also check if a cell contains its own centroid:

local sindex = modelData:spatialIndex('myIndex')
assert(sindex:hasCapability('containingCell')
local mesh = modelData:mesh('meshId')
local cell = mesh:cell(1)
local coordAc = mesh:nodeCoordAccessor()
local centroid = cell:centroidCartesian(coordAc)
local c = sindex:containingCell(centroid)
assert( c:id() == 1 )


Nearest Gauss points methods

The following set of methods can only be called if the spatial index object supports the nearestGauss capability.

sindex:closestGaussPoint(pointCoord)
Description: Given a point in the mesh domain, find the closest Gauss point to that point.
Important: only works if the index supports the nearestGauss capability.
Parameters: pointCoord - A lua table with the point coordinates.
Returns: The closest Gauss point, represented by the element global id (integer) and the local Gauss point index (integer), and the squared distance between the Gauss point and the node (real number).


sindex:closestGaussPoints(pointCoord, n)
Description: Given a point in the mesh domain, find the n closest Gauss points to that point.
Important: only works if the index supports the nearestGauss capability.
Parameters: pointCoord A lua table with the point coordinates.
n The number of Gauss points to query.
Returns: Three equal-sized lua tables, the first with the global element ids of the closest gauss points (list of integers), the second with the local Gauss ponit indices inside the corresponding element (list of integers) and the third with the associated squared distances between the target point and the closest gauss points (list of positive real numbers). The lists are ordered by ascending distance.


sindex:closestGaussPointsInRadius(pointCoord, r)
Description: Given a point in the mesh domain, find all the Gauss points in the region that has the given coordinate as its center and the given radius.
Important: only works if the index supports the nearestGauss capability.
Parameters: pointCoord A lua table with the point coordinates.
r The distance from the target point which delimits the closest Gauss points region.
Returns: Three equal-sized lua tables, the first with the global element ids of the closest gauss points (list of integers), the second with the local Gauss ponit indices inside the corresponding element (list of integers) and the third with the associated squared distances between the target point and the closest gauss points (list of positive real numbers). The lists are ordered by ascending distance.

In a similar way to get closest nodes, this next code fragment shows how it works to get the closest gauss points of a given node:

local sindex = modelData:spatialIndex('myIndex')
assert(sindex:hasCapability('nearestGauss')
local mesh = modelData:mesh('meshId')
local coordAc = mesh:nodeCoordAccessor()
local coord = coordAc:value(1)
local elemId, ip, sqDist = sindex:closestGaussPoint(coord)
print( elemId..' '..ip..' '..sqDist )
local n = 4
elemId, ip, sqDist = sindex:closestGaussPoints(coord, n)
assert( #elemId == n )
assert( #ip == n )
assert( #sqDist == n )
print( elemId[1]..' '..ip[1]..' '..sqDist[1] )
print( elemId[2]..' '..ip[2]..' '..sqDist[2] )
print( elemId[3]..' '..ip[3]..' '..sqDist[3] )
print( elemId[4]..' '..ip[4]..' '..sqDist[4] )
local r = math.sqrt(sqDist[4])
elemId, ip, sqDist = sindex:closestGaussPointsInRadius(coord, r)
assert(#elemId >= n)
print( elemId[1]..' '..ip[1]..' '..sqDist[1] )
print( elemId[2]..' '..ip[2]..' '..sqDist[2] )
print( elemId[3]..' '..ip[3]..' '..sqDist[3] )
print( elemId[4]..' '..ip[4]..' '..sqDist[4] )