SpECTRE
v2024.12.16
|
Map from a square or cube to a wedge. More...
#include <Wedge.hpp>
Public Types | |
enum class | WedgeHalves { Both , UpperOnly , LowerOnly } |
Public Member Functions | |
Wedge (double radius_inner, double radius_outer, double sphericity_inner, double sphericity_outer, OrientationMap< Dim > orientation_of_wedge, bool with_equiangular_map, WedgeHalves halves_to_use=WedgeHalves::Both, Distribution radial_distribution=Distribution::Linear, const std::array< double, Dim - 1 > &opening_angles=make_array< Dim - 1 >(M_PI_2), bool with_adapted_equiangular_map=true) | |
Constructs a centered wedge (one with no focal offset) More... | |
Wedge (double radius_inner, std::optional< double > radius_outer, double cube_half_length, std::array< double, Dim > focal_offset, OrientationMap< Dim > orientation_of_wedge, bool with_equiangular_map, WedgeHalves halves_to_use=WedgeHalves::Both, Distribution radial_distribution=Distribution::Linear) | |
Constructs a wedge with a focal offset. More... | |
Wedge (Wedge &&)=default | |
Wedge (const Wedge &)=default | |
Wedge & | operator= (const Wedge &)=default |
Wedge & | operator= (Wedge &&)=default |
template<typename T > | |
std::array< tt::remove_cvref_wrap_t< T >, Dim > | operator() (const std::array< T, Dim > &source_coords) const |
std::optional< std::array< double, Dim > > | inverse (const std::array< double, Dim > &target_coords) const |
For a Wedge , returns invalid if | |
template<typename T > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, Dim, Frame::NoFrame > | jacobian (const std::array< T, Dim > &source_coords) const |
template<typename T > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, Dim, Frame::NoFrame > | inv_jacobian (const std::array< T, Dim > &source_coords) const |
void | pup (PUP::er &p) |
Static Public Member Functions | |
static constexpr bool | is_identity () |
Static Public Attributes | |
static constexpr size_t | dim = Dim |
Friends | |
template<size_t LocalDim> | |
bool | operator== (const Wedge< LocalDim > &lhs, const Wedge< LocalDim > &rhs) |
Map from a square or cube to a wedge.
The mapping that goes from a reference cube (in 3D) or square (in 2D) to a wedge centered on a coordinate axis covering a volume between an inner surface and outer surface. Each surface can be given a curvature between flat (a sphericity of 0) or spherical (a sphericity of 1).
In 2D, the first logical coordinate corresponds to the radial coordinate, and the second logical coordinate corresponds to the angular coordinate. In 3D, the first two logical coordinates correspond to the two angular coordinates, and the third to the radial coordinate. This difference originates from separate implementations for the 2D and 3D map that were merged. The 3D implementation can be changed to use the first logical coordinate as the radial direction, but this requires propagating the change through the rest of the domain code (see issue https://github.com/sxs-collaboration/spectre/issues/2988).
The following documentation is for the centered 3D map, as we will defer the dicussion of Wedge
s with a focal_offset_
to a later section. The 2D map is obtained by setting either of the two angular coordinates to zero (and using
The Wedge map is constructed by linearly interpolating between a bulged face of radius radius_inner_
to a bulged face of radius radius_outer_
, where the radius of each bulged face is defined to be the radius of the sphere circumscribing the bulge.
We make a choice here as to whether we wish to use the logical coordinates parameterizing these surface as they are, in which case we have the equidistant choice of coordinates, or whether to apply a tangent map to them which leads us to the equiangular choice of coordinates. Wedge
s have variable opening_angles_
which, for centered Wedge
s, are the angular sizes of the wedge in the Wedge
s have opening angles of
For a Wedge with
With derivatives:
The equidistant coordinates are:
with derivatives:
We also define the variable
The surface map for the spherical face of radius
Where
The bulged surface is itself constructed by linearly interpolating between a cubical face and a spherical face. The surface map for the cubical face of side length
Where
To construct the bulged map we interpolate between this cubical face map and a spherical face map of radius
We constrain
The final map for the wedge which lies along the radial_distribution_
is domain::CoordinateMaps::Distribution::Linear), this interpolation results in the following map:
We will define the variables
Where
The map can then be rewritten as:
The inverse map is given by:
We provide some common derivatives:
The Jacobian then is:
A common factor that shows up in the inverse Jacobian is:
The inverse Jacobian then is:
By default, Wedge linearly distributes its gridpoints in the radial direction. An exponential distribution of gridpoints can be obtained by linearly interpolating in the logarithm of the radius in order to obtain a relatively higher resolution at smaller radii. Since this is a radial rescaling of Wedge, this option is only supported for fully spherical wedges with sphericity_inner_
= sphericity_outer_
= 1.
The linear interpolation done for a logarithmic radial distribution (radial_distribution_
is domain::CoordinateMaps::Distribution::Logarithmic) is:
The map then is:
We can rewrite this map to take on the same form as the map for the linear radial distribution, where we set
Which gives us
The Jacobian then is still Eq. (
Alternatively, an inverse radial distribution (radial_distribution_
is domain::CoordinateMaps::Distribution::Inverse) can be chosen where the linear interpolation is:
Which can be rewritten as:
The map likewise takes the form:
Where
Again, the Jacobian is still Eq. (
Consider the following map on
It is convenient to compute the polar coordinate
The opening angle of the map is defined to be:
We can see that with
On the other hand, the following map has an opening angle of
Let us also consider the generalized map
where
For the map
In other words, this parameterization has the property that the logical coordinate
As for the map
this choice of with_adapted_equiangular_map
controls whether to set true
case) or to set false
case). When working with a 3D Wedge, the opening angles for the Wedge can be separately controlled for both the with_adapted_equiangular_map
will apply to both directions. Additionally in the 3D case, it is not possible to set with_equiangular_map_
to true
for all of the six wedges of a sphere unless every opening angle is Wedge
s are allowed to have a user-specified opening angle in the Wedge
s in the Wedge
s, as the six Wedge
s must conforming have gridpoint distributions at the
In the case of the rectangular BinaryCompactObject domain, it becomes desirable to offset the center of the spherical excision surface relative to the center of the cubical surface surrounding it. To enable the offsetting of the central excision, the Wedge map must be generalized according to the focal lifting method, which we will now discuss.
We consider the problem of creating parameterized volumes from parameterized surfaces. Consider a parameterized surface
which makes apparent how the mapped point
The above map can be thought of as constructing a wedge from a biunit cube centered at the origin. Points on the parent surface are scaled by a factor of focal_offset_
to be non-zero), we scale the original parent surface
where we are now defining
This map is often written as:
where
The map can be inverted by first solving for
In other words, when
Moving all the known quantities in Eq. (
Note that
The quantity
With
which gives
To compute the Jacobian, it is useful to first note that
and that we can express the target coordinates in Eq. (
Some common terms used in the Jacobian are the derivatives of
The Jacobian then is:
A common factor that shows up in this inverse Jacobian is:
And the inverse Jacobian is then:
The default Wedge map is oriented in the orientation_of_wedge
. When offsetting a rotated Wedge, the coordinates passed as parameters to focal_offset
are in the coordinate frame in which the Wedge is rotated (the target frame). However, the focal lifting procedure (shown in Eq. (
When a Wedge is created with a non-zero focal offset, the resulting shape can take on a variety of possible angular sizes, depending on where the focus is placed relative to the default centered location. The reader might note that the angular size of a Wedge can also be controlled by passing an argument to the opening_angles
parameter in the Wedge constructor. While both of these methods allow the angular size of a Wedge to be changed, the user is prevented from employing both of them at the same time. In particular, when the the offset is set to some non-zero value, the opening_angles_
member variable is set to opening_angles_
member being set to
Because opening_angles_
is set to with_equiangular_map_
is true
, opening_angles_
of
|
strong |
domain::CoordinateMaps::Wedge< Dim >::Wedge | ( | double | radius_inner, |
double | radius_outer, | ||
double | sphericity_inner, | ||
double | sphericity_outer, | ||
OrientationMap< Dim > | orientation_of_wedge, | ||
bool | with_equiangular_map, | ||
WedgeHalves | halves_to_use = WedgeHalves::Both , |
||
Distribution | radial_distribution = Distribution::Linear , |
||
const std::array< double, Dim - 1 > & | opening_angles = make_array< Dim - 1 >(M_PI_2) , |
||
bool | with_adapted_equiangular_map = true |
||
) |
Constructs a centered wedge (one with no focal offset)
radius_inner | Distance from the origin to one of the corners which lie on the inner surface. |
radius_outer | Distance from the origin to one of the corners which lie on the outer surface. |
orientation_of_wedge | The orientation of the desired wedge relative to the orientation of the default wedge which is a wedge that has its curved surfaces pierced by the upper-z axis. The logical |
sphericity_inner | Value between 0 and 1 which determines whether the inner surface is flat (value of 0), spherical (value of 1) or somewhere in between. |
sphericity_outer | Value between 0 and 1 which determines whether the outer surface is flat (value of 0), spherical (value of 1) or somewhere in between. |
with_equiangular_map | Determines whether to apply a tangent function mapping to the logical coordinates (for true ) or not (for false ). |
halves_to_use | Determines whether to construct a full wedge or only half a wedge. If constructing only half a wedge, the resulting shape has a face normal to the x direction (assuming default OrientationMap). If constructing half a wedge, an intermediate affine map is applied to the logical xi coordinate such that the interval [-1,1] is mapped to the corresponding logical half of the wedge. For example, if UpperOnly is specified, [-1,1] is mapped to [0,1], and if LowerOnly is specified, [-1,1] is mapped to [-1,0]. The case of Both means a full wedge, with no intermediate map applied. In all cases, the logical points returned by the inverse map will lie in the range [-1,1] in each dimension. Half wedges are currently only useful in constructing domains for binary systems. |
radial_distribution | Determines how to distribute gridpoints along the radial direction. For wedges that are not exactly spherical, only Distribution::Linear is currently supported. |
opening_angles | Determines the angular size of the wedge. The default value is |
with_adapted_equiangular_map | Determines whether to adapt the point distribution in the wedge to match its physical angular size. When true , angular distances are proportional to logical distances. Note that it is not possible to use adapted maps in every Wedge of a Sphere unless each Wedge has the same size along both angular directions. |
domain::CoordinateMaps::Wedge< Dim >::Wedge | ( | double | radius_inner, |
std::optional< double > | radius_outer, | ||
double | cube_half_length, | ||
std::array< double, Dim > | focal_offset, | ||
OrientationMap< Dim > | orientation_of_wedge, | ||
bool | with_equiangular_map, | ||
WedgeHalves | halves_to_use = WedgeHalves::Both , |
||
Distribution | radial_distribution = Distribution::Linear |
||
) |
Constructs a wedge with a focal offset.
Can construct an offset Wedge with a spherical inner surface and either a spherical or a flat outer surface. If radius_outer
has a value, a spherical Wedge will be constructed, and if not, a flat one will be constructed.
Note that because the focal offset is what determines the angular size of the Wedge, opening angles cannot be used with offset Wedges.
In the event that focal_offset
happens to be zero, the Wedge's member variables and behavior will be set up to be equivalent to that of a centered Wedge:
cube_half_length
will be ignoredradius_outer
is std::nullopt
, the outer radius of the Wedge will be set to cube_half_length
radius_inner | Distance from the origin to one of the corners which lie on the inner surface. |
radius_outer | If this has a value, it creates a spherical Wedge (inner and outer sphericity are 1) where this is the distance from the origin to one of the corners that lie on the inner surface. If this is std::nullopt , it creates a Wedge with a flat outer surface (inner sphericity is 1 and outer sphericity is 0). In the event that radius_outer == std::nullopt and focal_offset is zero, the outer radius will instead be set to cube_half_length . The outer radius is given a value in this circumstance so that it can be handled as a centered Wedge (one with no offset). |
orientation_of_wedge | The orientation of the desired wedge relative to the orientation of the default wedge which is a wedge that has its curved surfaces pierced by the upper-z axis. The logical |
cube_half_length | Half the length of the parent surface (see Wedge documentation for more details). If focal_offset is zero, this parameter has no effect and is ignored so that the Wedge can be handled as a centered Wedge (one with no offset). |
focal_offset | The target frame coordinates of the focus from which the Wedge is focally lifted. |
with_equiangular_map | Determines whether to apply a tangent function mapping to the logical coordinates (for true ) or not (for false ). |
halves_to_use | Determines whether to construct a full wedge or only half a wedge. If constructing only half a wedge, the resulting shape has a face normal to the x direction (assuming default OrientationMap). If constructing half a wedge, an intermediate affine map is applied to the logical xi coordinate such that the interval [-1,1] is mapped to the corresponding logical half of the wedge. For example, if UpperOnly is specified, [-1,1] is mapped to [0,1], and if LowerOnly is specified, [-1,1] is mapped to [-1,0]. The case of Both means a full wedge, with no intermediate map applied. In all cases, the logical points returned by the inverse map will lie in the range [-1,1] in each dimension. Half wedges are currently only useful in constructing domains for binary systems. |
radial_distribution | Determines how to distribute gridpoints along the radial direction. For wedges that are not exactly spherical, only Distribution::Linear is currently supported. |