perf(allocations): reduced overall allocations by 95%, increaseed jacobian applicatin by 2x
This commit uses global pre allocated work space to dramatically reduce memory usage and allocation time
This commit is contained in:
@@ -54,6 +54,7 @@ namespace mean_field::mapping::compactification {
|
||||
if (!std::isfinite(compactification_coordinate))
|
||||
return MappingStatus::non_finite_input;
|
||||
|
||||
// How close we will allow the code to get to compactified infinity
|
||||
const double tolerance = m_options.coordinate_tolerance;
|
||||
|
||||
if (compactification_coordinate < -tolerance || compactification_coordinate > 1.0 + tolerance) {
|
||||
@@ -68,13 +69,21 @@ namespace mean_field::mapping::compactification {
|
||||
return MappingStatus::at_compactified_infinity;
|
||||
}
|
||||
|
||||
// Here we need to do some transformations from the options defined on the mesh to useful computational coordinates
|
||||
// r_inf_ref is the computational / reference radius of the infinity surface (the edge of the entire domain) and r_star_ref is the radius of the spherical
|
||||
// stellar model inscribed within. Therefore radial extent is the computational radial distance between the stellar surface and the infinity surface.
|
||||
// Note that this is separate from the parameterize compactification coordinate.
|
||||
const double radial_extent = m_options.r_inf_ref - m_options.r_star_ref;
|
||||
|
||||
// This places us at the correct spot in computational space given the current compactification coordinate. Say you have compactification = 0.5,
|
||||
// an r_star_ref of 2 and a radial extent of 3, this this will place you at 2 + 0.5 * 3 = 3.5 in computational space, which is half way between the stellar surface and the infinity surface.
|
||||
const double computational_radius = m_options.r_star_ref + coordinate * radial_extent;
|
||||
|
||||
if (!std::isfinite(computational_radius) || computational_radius <= 0.0) {
|
||||
return MappingStatus::invalid_reference_radius;
|
||||
}
|
||||
|
||||
// Invert the exterior coordinate so it runs from 0 at the star to 1 at compactified infinity
|
||||
const double one_minus_coordinate = 1.0 - coordinate;
|
||||
const double denominator = computational_radius * one_minus_coordinate;
|
||||
|
||||
@@ -82,6 +91,11 @@ namespace mean_field::mapping::compactification {
|
||||
return MappingStatus::non_finite_result;
|
||||
}
|
||||
|
||||
// The scale here is the factor which stretches the finite computational domain into the infinite physical domain. Properties we need this to have
|
||||
// include that it should go to 1 at the stellar surface and go to infinity at the compactified infinity.
|
||||
// Mathematically this is scale = |r|/|x| where r is the physical radius and x is the computational radius.
|
||||
// Put another way, scale is the ratio of the target physical radius for the current compactification coordinate
|
||||
// to the current mesh radius.
|
||||
const double scale = m_options.r_star_ref / denominator;
|
||||
const double scale_derivative = scale * (1.0 / one_minus_coordinate - radial_extent / computational_radius);
|
||||
|
||||
@@ -119,6 +133,8 @@ namespace mean_field::mapping::compactification {
|
||||
}
|
||||
|
||||
RadialFactors factors;
|
||||
|
||||
// The key radial factors we use are the scale (which stretches the finite computational domain into the infinite physical domain) and the scale derivative (which is used to compute the mapping jacobian).
|
||||
const MappingStatus factor_status = ComputeRadialFactors(input.compactification_coordinate, factors);
|
||||
if (factor_status != MappingStatus::valid)
|
||||
return factor_status;
|
||||
@@ -127,12 +143,21 @@ namespace mean_field::mapping::compactification {
|
||||
result.mapping_jacobian.SetSize(dimension, dimension);
|
||||
|
||||
for (int i = 0; i < dimension; ++i) {
|
||||
// Note how the physical position is just the product of the displaced position and the scale factor.
|
||||
result.physical_position(i) = factors.scale * input.displaced_position(i);
|
||||
|
||||
// The mapping jacobian comes from trivial application of the product rule
|
||||
// recall: r_i = scale * x_i where r is the physical position and x is the displaced position.
|
||||
// then we can differentiate wrt. X_j holding nothing fixed. Note the capital X here, this is the mesh coordinate not the displaced position.
|
||||
// Lets call this jacobian F
|
||||
// F = \frac{\partial r_i}{\partial X_{j}}
|
||||
// F then tells us how the physical position changes as we move along mesh coordinates
|
||||
// Lets then apply this to the function we have for the kelvin compactification
|
||||
// F = scale * \frac{\partial x_i}{\partial X_j} + x_i * \frac{\partial scale}{\partial X_j}
|
||||
// Below you can see the displacement jacobian (\frac{\partial x_i}{\partial X_j}) and the scale derivative (\frac{\partial scale}{\partial X_j}) being applied to compute the mapping jacobian.
|
||||
for (int j = 0; j < dimension; ++j) {
|
||||
const double scale_gradient = factors.scale_derivative * input.compactification_coordinate_gradient(j);
|
||||
result.mapping_jacobian(i, j) =
|
||||
factors.scale * input.displacement_jacobian(i, j) + input.displaced_position(i) * scale_gradient;
|
||||
result.mapping_jacobian(i, j) = factors.scale * input.displacement_jacobian(i, j) + input.displaced_position(i) * scale_gradient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user