NanoComp / libctl

Guile-based library implementing flexible control files for scientific simulations
GNU General Public License v2.0
18 stars 23 forks source link

Refactor prisms for scheme #35

Closed HomerReid closed 5 years ago

HomerReid commented 5 years ago

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:

  1. 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.

  2. 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 not o.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.

  1. 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.