Support for unit safe types [part 2]
Description
I want to make the grid interface compatible with unit safe types (see part 1: #79 (closed)). Here I discuss about the dimensionless unit types on the interface.
Local coordinates
Currently, the types for local and global coordinates in the geometry are given by a FieldVector
of ctype
:
//! type of local coordinates
typedef FieldVector<ctype, mydim> LocalCoordinate;
//! type of the global coordinates
typedef FieldVector<ctype, cdim> GlobalCoordinate;
Now, on discussions about unit safe grids we agreed that the units of the coordinate type (ctype
) only affects the global coordinates while local coordinates should be dimensionless. This simplifies a lot since nothing in dune-grometry
needs to be unit safe. However, the aliases in the interface do not allow for a mismatch between a coordinate type and a dimensionless unit on local and global coordinates (as seen above). This also affects the ADL to get reference elements on grid geometries. The current implementation relies on the ctype
as well:
template< int mydim, int cdim, class GridImp, template< int, int, class > class GeometryImp, typename Impl>
auto referenceElement(const Geometry<mydim,cdim,GridImp,GeometryImp>& geo, const Impl&)
-> decltype(referenceElement<typename GridImp::ctype,mydim>(geo.type()))
{
using Geo = Geometry<mydim,cdim,GridImp,GeometryImp>;
return referenceElement<typename Geo::ctype,Geo::mydimension>(geo.type());
}
Clearly, if we want unit safe types, we need some notion of dimensionless type. Below I present some possible alternatives:
decltype
local coordinate
Option 1: Use the same approach as for volume, that is, decltype()
the type out of the implementation.
typedef decltype(std::declval<Implementation>().local(std::declval<Implementation>().center())) LocalCoordinate;
I don't particularly like this syntax, but at least is consistent with Volume
.
Option 2: Typedef from implementation
Extract type from implementation. This would be the cleanest solution, but again, we would face backwards compatibility issues on implementations that forgot to have the alias.
typedef typename Implementation::LocalCoordinate LocalCoordinate;
Option 3: Deduce dimensionless unit
Since we are talking about dimensionless units, the unit safe type system would always provide a dimensionless units when division to the same units are applied.
typedef decltype(ctype{}/ctype{}) DimensionlessCoordinate; // TODO: choose a better name
typedef FieldVector< DimensionlessCoordinate, cdim > LocalCoordinate;
Naturally, this is backwards compatible with normal types like double
or float
.