Together with stevengj/meep#634 and stevengj/mpb#83, fixes stevengj/meep#608.
The traditional libctl paradigm for handling geometric objects poses some difficulties for incorporating prisms, which are more complicated than the existing primitives like block and cylinder. In particular, the design of the geometric_object structure assumes that the center of an object is independent of the various shape-specific data fields that live in the subclass_data. This is is not true for prisms, for which the center is fixed by the vertices, axis, and height. (Actually, for right-angle prisms the axis is not independent either; see below.)
In principle, the prism implementation could be shoehorned into the existing paradigm by e.g. eliminating height as an independent parameter, in which case center would reemerge as an independent quantity as for the other types of geometric objects. This would at least allow prisms to be implemented without requiring any modifications to the handling of geometric objects. However, it would be unwieldy and inconvenient for users.
The more natural approach, already implemented in the python and C++ interfaces, is to have users specify the vertices and height, then compute the center as a derived quantity. However, libctl in its current form doesn't allow this, for a couple of reasons:
center is a mandatory input parameter when instantiating a geometric object of any type, including prisms. There is no existing framework for instantiating objects in which center is derived from other user-specified quantities.
The calling convention for geom_fix_object routine accepts as input a geometric_object o, passed by reference (i.e. not a pointer to geometric_object). This allows geom_fix_object to modify the contents of o.subclass_data, but noto.center.
I have addressed these issues as follows.
1A. For scheme instantiation of prisms in which center is to be treated as a derived quantity, I have added a new scheme keyword auto-center as the value to specify for the mandatory center field. This is a specially-coded value signifying to libctl that center is to be overwritten as a derived parameter based on the caller's vertices, height, and axis.
1B. On the other hand, in some cases one might want to subject a prism to a rigid translation upon instantiating it---for example, perhaps you want to define two identical prisms separated in space by a displacement vector Delta. In this case, instead of auto_center simply set center equal to the desired final center of your prism, and the prism defined by vertices, height, axis will be rigidly translated in space to be centered at that point.
I have changed the prototype for geom_fix_object so that it now accepts a pointer to geometric_object, allowing the center field to be updated. Of course this revision breaks existing code, but the updates required in the meep and mpb code bases turn out to be minor, because the only cases in which geom_fix_object needs to be called explicitly from those codes seem to be cases in which we need to update an entire list of objects, and for that purpose the existing routine geom_fix_objects0 suffices with no change in calling convention needed.
Note: I find the name of this routine confusing, and suggest that geom_fix_objects0 be renamed geom_fix_object_list.
In conjunction with accommodating prism instantiation in scheme, I have updated the prism data structure to store more information than it did previously---for example, the vertex coordinates in both the ordinary and prism coordinate systems are stored. This simplifies some handling in geom.py and elsewhere.
Together with stevengj/meep#634 and stevengj/mpb#83, fixes stevengj/meep#608.
The traditional
libctl
paradigm for handling geometric objects poses some difficulties for incorporating prisms, which are more complicated than the existing primitives likeblock
andcylinder.
In particular, the design of thegeometric_object
structure assumes that thecenter
of an object is independent of the various shape-specific data fields that live in thesubclass_data.
This is is not true for prisms, for which thecenter
is fixed by thevertices
,axis
, andheight
. (Actually, for right-angle prisms theaxis
is not independent either; see below.)In principle, the prism implementation could be shoehorned into the existing paradigm by e.g. eliminating
height
as an independent parameter, in which casecenter
would reemerge as an independent quantity as for the other types of geometric objects. This would at least allow prisms to be implemented without requiring any modifications to the handling of geometric objects. However, it would be unwieldy and inconvenient for users.The more natural approach, already implemented in the python and C++ interfaces, is to have users specify the
vertices
andheight,
then compute thecenter
as a derived quantity. However,libctl
in its current form doesn't allow this, for a couple of reasons:center
is a mandatory input parameter when instantiating a geometric object of any type, including prisms. There is no existing framework for instantiating objects in whichcenter
is derived from other user-specified quantities.The calling convention for
geom_fix_object
routine accepts as input ageometric_object o,
passed by reference (i.e. not a pointer togeometric_object
). This allowsgeom_fix_object
to modify the contents ofo.subclass_data
, but noto.center
.I have addressed these issues as follows.
1A. For scheme instantiation of prisms in which
center
is to be treated as a derived quantity, I have added a new scheme keywordauto-center
as the value to specify for the mandatorycenter
field. This is a specially-coded value signifying tolibctl
thatcenter
is to be overwritten as a derived parameter based on the caller'svertices
,height
, andaxis.
1B. On the other hand, in some cases one might want to subject a prism to a rigid translation upon instantiating it---for example, perhaps you want to define two identical prisms separated in space by a displacement vector
Delta.
In this case, instead ofauto_center
simply setcenter
equal to the desired final center of your prism, and the prism defined byvertices, height, axis
will be rigidly translated in space to be centered at that point.geom_fix_object
so that it now accepts a pointer togeometric_object
, allowing thecenter
field to be updated. Of course this revision breaks existing code, but the updates required in themeep
andmpb
code bases turn out to be minor, because the only cases in whichgeom_fix_object
needs to be called explicitly from those codes seem to be cases in which we need to update an entire list of objects, and for that purpose the existing routinegeom_fix_objects0
suffices with no change in calling convention needed.Note: I find the name of this routine confusing, and suggest that
geom_fix_objects0
be renamedgeom_fix_object_list
.In conjunction with accommodating prism instantiation in scheme, I have updated the prism data structure to store more information than it did previously---for example, the vertex coordinates in both the ordinary and prism coordinate systems are stored. This simplifies some handling in
geom.py
and elsewhere.