feat(mapper): finished porting over mapper

This commit is contained in:
2026-09-23 09:29:05 -04:00
parent 9e0e1f5c18
commit 52c42ec7cd
21 changed files with 1414 additions and 30 deletions

View File

@@ -0,0 +1,112 @@
#include "serif/mapping/volume_cache.hpp"
#include "serif/utils/error/errors.hpp"
#include "mfem/linalg/densemat.hpp"
#include "mfem/linalg/vector.hpp"
namespace serif::mapping {
using namespace utils::errors;
namespace {
// Replace all of these with a fast serialization class at some point. Probably in something like a serif/serialize module
void pack_vector(double*& destination, const mfem::Vector& vector) {
const int dim = vector.Size();
std::copy_n(vector.HostRead(), dim, destination);
destination += dim;
}
void pack_matrix(double*& destination, const mfem::DenseMatrix& matrix) {
serif_assert<SERiFErrorCode::MATRIX_SHAPE_ERROR>(matrix.Height() == matrix.Width(), "Matrix must be square to pack");
const int dim = matrix.Height();
std::copy_n(matrix.HostRead(), dim * dim, destination);
destination += dim * dim;
}
void unpack_vector(const double*& source, mfem::Vector& vector, const int dim) {
vector.SetSize(dim);
std::copy_n(source, dim, vector.HostWrite());
source += dim;
}
void unpack_matrix(const double*& source, mfem::DenseMatrix& matrix, const int dim) {
matrix.SetSize(dim, dim);
std::copy_n(source, dim * dim, matrix.HostWrite());
source += dim * dim;
}
}
void VolumeMappingCache::set_size(int point_count, int dimension) {
serif_assert<SERiFErrorCode::INVALID_DIMENSION>(point_count < 0 || dimension < 1 || dimension > 3, "Invalid point count or dimension for volume mapping cache. Point count: {}, dimension: {}", point_count, dimension);
const int stride = 3 * dimension + 4 * dimension * dimension + 4;
m_data.resize(static_cast<std::size_t>(point_count) * stride);
m_point_count = point_count;
m_dimension = dimension;
m_point_stride = stride;
}
void VolumeMappingCache::validate_point(const int point) const {
serif_assert<SERiFErrorCode::OUT_OF_RANGE_ERROR>(point < 0 || point >= m_point_count, "Point index {} is out of range for volume mapping cache with {} points", point, m_point_count);
}
const double *VolumeMappingCache::get_point_data(const int point) const {
validate_point(point);
return m_data.data() + static_cast<std::size_t>(point) * m_point_stride;
}
void VolumeMappingCache::store(int point, VolumeMappingContext &context) {
validate_point(point);
double *data = m_data.data() + static_cast<std::size_t>(point) * m_point_stride;
// What we build here is a FIFO data structure. we pack
// all the raw data from the mapping context into a single contiguous array of doubles.
// This allows us to avoid repeated allocations as the vector will grow to some appropriate size and then stay roughly there.
pack_vector(data, context.mapping.reference_position);
pack_vector(data, context.mapping.displaced_position);
pack_vector(data, context.mapping.physical_position);
pack_matrix(data, context.mapping.displacement_jacobian);
pack_matrix(data, context.mapping.mapping_jacobian);
pack_matrix(data, context.mapping.inverse_mapping_jacobian);
pack_matrix(data, context.quadrature.J_element_to_physical_inverse);
*data++ = context.mapping.mapping_determinate;
*data++ = context.mapping.compactified ? 1.0 : 0.0; // its possible this could cause issues, have not run into but when unpacked I worry that exact equality to some double value could be a problem. If there are wierd issues this may be a place to look,
*data++ = context.quadrature.mapping_determinate;
*data = context.quadrature.physical_integration_weight;
}
void VolumeMappingCache::load(int point, VolumeMappingContext &context) const {
const double *data = get_point_data(point);
// FIFO data structure so need to unpack in the same order as we packed.
// TODO: Redo this with some sort of fast serialization class so we do not need to worry about ordering
unpack_vector(data, context.mapping.reference_position, m_dimension);
unpack_vector(data, context.mapping.displaced_position, m_dimension);
unpack_vector(data, context.mapping.physical_position, m_dimension);
unpack_matrix(data, context.mapping.displacement_jacobian, m_dimension);
unpack_matrix(data, context.mapping.mapping_jacobian, m_dimension);
unpack_matrix(data, context.mapping.inverse_mapping_jacobian, m_dimension);
unpack_matrix(data, context.quadrature.J_element_to_physical_inverse, m_dimension);
context.mapping.mapping_determinate = *data++;
context.mapping.compactified = *data++ != 0.0; // See comment in store()
context.quadrature.mapping_determinate = *data++;
context.quadrature.physical_integration_weight = *data;
}
void VolumeMappingCache::load_inverse_jacobian(int point, mfem::DenseMatrix &inverse) const {
// Again this is unsafe, and really should be replaced. This was a quick cache scheme that solved the direct issue I had; however, it should be replaced
// with something that has at least a modicum of safety built in (we are pretty good about this in other parts of SERiF but its about 8pm and
// Im quite tired....
const double *data = get_point_data(point) + 3 * m_dimension + 3 * m_dimension * m_dimension; // skip to the inverse jacobian, this is just pointer math...Think back to CS-101. Do that have that in the future, are we still learning about memory like this is a PDP-11?
unpack_matrix(data, inverse, m_dimension);
}
int VolumeMappingCache::get_point_count() const noexcept {
return m_point_count;
}
int VolumeMappingCache::get_dimension() const noexcept {
return m_dimension;
}
}