This is to explain that code.
The code has the limited goal of supporting ray tracing.
This requires the numerical support for an affine connection which is knowing the coordinate transformation across facets.
The Zone module
Routine Zone.newz is called once per zone, during morphogenesis.
Arguments to Zone.newz:
- ds2 is the (n+1) by (n+1) array of squared edge lengths for the zone.
- neigh is the mutable array of n+1 facet access values.
The mutable neigh has probably not acquired values upon entry to newz but morphogenesis is the convenient time to deliver access to the array.
Presumably the array will be completed before Zone.rayIn is called, and constant thereafter.
Zone.newz returns a routine, gb here, that can be called, once per facet during morphgenesis, for this information.
This might be more economical of storage.
gb takes a parameter the facet number as known by zone.
gb returns 1 or n basis vectors expressed in facet coordinates.
Only the opposite facet need return n vectors; for the other facets there is only one basis vector that is not shared between zone and facet.
When the opposite facet calls (opposite the origin), all the basis vectors must be returned expressed in that facet’s bcc.
I try here an alternative style of describing the semantics of gb.
When gb is called the arguments convey the following request to code in the Zone module.
Routine gb is delivered to a particular facet and thus when gb is invoked it is that facet speaking.
“Please return your ith basis vector expressed in in my coordinate system.”
Often the response will merely be “My basis vector i is your basis vector j.”.
Perhaps in all cases either i = j or i = j–1.
The morphogenesis code already knew this but it is now the facet code speaking.
There are clearly modularity issues involved here.
Zone logic clearly has the information to answer this question.
This is a possibly important optimization since the facet can put together the transformation between zone bcc and facet bcc for each of its two neighbors.
This saves much multiplication when tensors cross.
On the other hand for high dimensions these matrices may be sparse.
Alternatively Zone.newz would return gu an array of n+1 vectors, one per facet, which is the basis vector that is not included in that facet.
These vectors are each expressed in the coordinate system of the associated facet.
Messages between zone and facet adopt the zone’s numbering system for the zone does not have access the the global numbering plan.
The arguments to Zone.rayIn are:
- fn : int
- The number of the facet thru which the ray enters.
- lam : float
- The current value of λ, the geodesic parameter.
Perhaps the ray will stop when it reaches zero.
- wh : float array
- Where on the facet the ray enters. (n+1 components)
- vel : float array
- Velocity of ray. (n+1 components)
Zone.rayIn returns nothing of interest; getting there is all the fun!
- The contravariant tensor (?)
float array array
- A routine that returns the zone’s j’th basis vector expressed in facet k’s coordinates.
int -> int -> float array
(called during morphogenesis)
- a routine to be called upon entry of a ray into this zone.
int -> float -> float array -> float array
To follow the plan described here to express vectors in facet coordinates we must formalize that concept.
Discarded idea
The above is now written around the idea that during morphogenesis each facet would develop a linear transformation between the bcc of the two adjacent zones.
I think now this is a bad idea.
It is bad because such a transformation is the product of two transformations between zone and facet bccs and each of these are generally sparse.
It may be both conceptually simpler and faster to perform the two transformations within the respective zones.
The facets would be limited to flipping the sign of the normal and permuting the vertex numbers.
This may save time, space and hair.
The Facet module
When morphogenesis has found two neighboring zones it calls Facet.newf passing the respective contravariant metric tensors.
It also gets the facet vertex permutation between the zones.
newf’s current job is to compute the resultant transformation matrices between the respective bcc systems, in order to relay ray tracing calls.
It must also permute the facet coordinates of the ray’s position.