matthuszagh/pyems

openems floating point errors for length=0 dimensions

matthuszagh opened this issue · 0 comments

The floating point used by openems can present problems when trying to line up mesh lines with primitives which are of exactly 0 length in at least 1 dimension. In these cases, floating point errors can accumulate and the mesh line will be placed a very small distance away from the primitive it should be coincident with.

Superficially, there seems be a good way of dealing with this. Specifically, keep all coordinates as full-precision floating point internally. Then, right before passing these coordinates to csxcad, round them to some limited precision (e.g. np.round(val, 10)). As long as the precision error is larger than the floating point rounding error by a sufficient margin, all values that should be the same will be the same. The exception where this approach fails is with transformations. Openems handles transformations internally within the C++ codebase and they do not affect GetBoundBox() and other similar coordinate-reporting functions for primitives.

Currently, my method for constructing primitives with transformations is to construct the primitive first at the origin then apply the transformation if there is one and finally translate the primitive (with a transformation) to the final position. This has the obvious downside that it leads to the issue stated above even when no transform has been requested. A better solution would be to only use this method when a transform has actually been requested. Otherwise, all transformations (including the translation) can be avoided and the primitive can be constructed directly at the final location. This gives me full control to round the values as I want.

It will still be permissible for a user to specify a transformation for these 0-length structures, since for instance, a 3D rotation to a planar structure can generate a result that has a nonzero length in every dimension. However, this leaves cases where the transformation will create issues. These transformations should never be needed since these structures can be created directly in the final transformed state. The correct solution, I believe, is to issue errors when such a case is detected. However, this is probably difficult and the temporary situation will be to allow the user to misuse the interface in this way.