SpECTRE  v2024.12.16
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
domain::CoordinateMaps::TimeDependent::SphericalCompression< InteriorMap > Class Template Reference

Time-dependent compression of a finite 3D spherical volume. More...

#include <SphericalCompression.hpp>

Public Member Functions

 SphericalCompression (std::string function_of_time_name, double min_radius, double max_radius, const std::array< double, 3 > &center)
 
template<typename T >
std::array< tt::remove_cvref_wrap_t< T >, 3 > operator() (const std::array< T, 3 > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
std::optional< std::array< double, 3 > > inverse (const std::array< double, 3 > &target_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 The inverse function is only callable with doubles because the inverse might fail if called for a point out of range, and it is unclear what should happen if the inverse were to succeed for some points in a DataVector but fail for other points.
 
template<typename T >
std::array< tt::remove_cvref_wrap_t< T >, 3 > frame_velocity (const std::array< T, 3 > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
template<typename T >
tnsr::Ij< tt::remove_cvref_wrap_t< T >, 3, Frame::NoFramejacobian (const std::array< T, 3 > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
template<typename T >
tnsr::Ij< tt::remove_cvref_wrap_t< T >, 3, Frame::NoFrameinv_jacobian (const std::array< T, 3 > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
void pup (PUP::er &p)
 
const std::unordered_set< std::string > & function_of_time_names () const
 

Static Public Member Functions

static bool is_identity ()
 

Static Public Attributes

static constexpr size_t dim = 3
 

Friends

bool operator== (const SphericalCompression &lhs, const SphericalCompression &rhs)
 

Detailed Description

template<bool InteriorMap>
class domain::CoordinateMaps::TimeDependent::SphericalCompression< InteriorMap >

Time-dependent compression of a finite 3D spherical volume.

Details

Let ξi be the unmapped coordinates, and let ρ be the Euclidean radius corresponding to these coordinates with respect to some center Ci. The transformation implemented by this map is equivalent to the following transformation: at each point, the mapped coordinates are the same as the unmapped coordinates, except in a spherical region ρρmax, where instead coordinates are mapped using a compression that is spherically symmetric about the center Ci. The amount of compression decreases linearly from a maximum at ρ=ρmin to zero at ρ=ρmax. A scalar domain::FunctionsOfTime::FunctionOfTime λ00(t) controls the amount of compression.

The mapped coordinates are a continuous function of the unmapped coordinates, but the Jacobians are not continuous at ρmin and ρmax. Therefore, ρmin and ρmax should both be surfaces corresponding to block boundaries. Therefore, this class implements the transformation described above as follows: the if the template parameter InteriorMap is true, the map is the one appropriate for ρ<ρmin, while if InteriorMap is false, the map is the one appropriate for ρminρρmax. To use this map, add it to the blocks where the transformation is not the identity, using the appropriate template parameter, depending on which region the block is in.

Note
This map performs a only a spherical compression. A generalization of this map that changes the region's shape as well as its size, by including more terms than the spherically symmetric term included here, can be found in the domain::CoordinateMaps::TimeDependent::Shape map.
The quantity stored in the FunctionOfTime is really the spherical-harmonic coefficient λ00(t). This is different from the Shape map, which stores ylm::Spherepack coefficients alm(t) and blm(t) instead of λlm(t). See domain::CoordinateMaps::TimeDependent::Shape for more details.

Mapped coordinates

The mapped coordinates xi are related to the unmapped coordinates ξi as follows:

(1)xi={ξiλ00(t)4πρiρmin,ρ<ρmin,ξiλ00(t)4πρmax/ρ1ρmaxρminρi,ρminρρmax,ξi,ρmax<ρ,

where ρi=ξiCi is the Euclidean radial position vector in the unmapped coordinates with respect to the center Ci, ρ=δkl(ξkCl)(ξlCl) is the Euclidean magnitude of ρi, and ρj=δijρi.

Frame velocity

The frame velocity vidxi/dt is then

(2)vi={λ00(t)4πρiρmin,ρ<ρmin,λ00(t)4πρmax/ρ1ρmaxρminρi,ρminρρmax,0,ρmax<ρ,

where λ00(t)dλ00/dt.

Jacobian

Differentiating the equations for xi gives the Jacobian xi/ξj. Using the result

(3)ρiξj=ξj(ξiCi)=ξiξj=δji

and taking the derivatives yields

(4)xiξj={δji(1λ00(t)4π1ρmin),ρ<ρmin,δji(1λ00(t)4πρmax/ρ1ρmaxρmin)ρiλ00(t)4πξj(ρmax/ρ1ρmaxρmin),ρminρ<ρmax,δji,ρmax<ρ.

Inserting

(5)ξj(ρmax/ρ1ρmaxρmin)=ρmaxρmaxρminξj(1ρ)=ρmaxρmaxρmin1ρ2ρξj

and

(6)ρξj=ρjρ.

into the Jacobian yields

(7)xiξj={δji(1λ00(t)4π1ρmin),ρ<ρmin,δji(1λ00(t)4πρmax/ρ1ρmaxρmin)+ρiρjλ00(t)4πρmaxρmaxρmin1ρ3,ρminρ<ρmax,δji,ρmax<ρ.

Inverse Jacobian

This map finds the inverse Jacobian by first finding the Jacobian and then numerically inverting it.

Inverse map

For λ00(t) that satisfy

(8)ρminρmax<λ00(t)/4π<ρmin,

the map will be invertible and nonsingular. For simplicity, here we enforce this condition, even though perhaps the map might be generalized to handle cases that are still invertible but violate this condition. This avoids the need to specially handle the cases λ00(t)/4π=ρminρmax and λ00(t)/4π=ρmin, both of which yield a singular map, and it also avoids cases where the map behaves in undesirable ways (such as a larger λ00(t) leading to an expansion and a coordinate inversion instead of a compression).

After requiring the above inequality to be satisfied, however, the inverse mapping can be derived as follows. Let rixiCi. In terms of ri, the map is

(9)ri={ρi(1λ00(t)4π1ρmin),ρ<ρmin,ρi(1λ00(t)4πρmax/ρ1ρmaxρmin),ρminρρmax,ρi,ρmax<ρ.

Taking the Euclidean magnitude of both sides and simplifying yields

(10)rρ={1λ00(t)4π1ρmin,ρ<ρmin,1λ00(t)4πρmax/ρ1ρmaxρmin,ρminρρmax,1,ρmax<ρ,

which implies

(11)ri=ρirρρi=riρr.

Inserting ρmin or ρmax then gives the corresponding bounds in the mapped coordinates:

(12)rmin=ρminλ00(t)4π,(13)rmax=ρmax.

In the regime ρminρ<ρmax, rearranging yields a linear relationship between ρ and r, which can then be solved for ρ(r):

(14)r=ρλ00(t)4πρmaxρρmaxρmin(15)r=ρ(1+λ00(t)4π1ρmaxρmin)λ00(t)4πρmaxρmaxρmin.

Solving this linear equation for ρ yields

(16)ρ=(r+λ00(t)4πρmaxρmaxρmin)(1+λ00(t)4π1ρmaxρmin)1.

Inserting the expressions for ρ into the equation

(17)ρi=riρr

then gives

(18)ρi={ri(1λ00(t)4π1ρmin)1,r<ρminλ00(t)4π,ri(1+1rλ00(t)4πρmaxρmaxρmin)(1+λ00(t)4π1ρmaxρmin)1,ρminλ00(t)4πrρmax,ri,ρmax<r.

Finally, inserting ρi=ξiCi yields the inverse map:

(19)ξi={ri(1λ00(t)4π1ρmin)1+Ci,r<ρminλ00(t)4π,ri(1+1rλ00(t)4πρmaxρmaxρmin)(1+λ00(t)4π1ρmaxρmin)1+Ci,ρminλ00(t)4πrρmax,ri+Ci=xi,ρmax<r.


The documentation for this class was generated from the following file: