Progress on bringing the DomainMapper over
This commit is contained in:
153
src/lib/serif/mapping/data.cpp
Normal file
153
src/lib/serif/mapping/data.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "mfem/linalg/vector.hpp"
|
||||
#include "mfem/fem/fe/fe_base.hpp"
|
||||
#include "mfem/fem/fespace.hpp"
|
||||
|
||||
#include "serif/mapping/data.hpp"
|
||||
|
||||
#include "serif/utils/error/errors.hpp"
|
||||
|
||||
namespace serif::mapping {
|
||||
using namespace serif::utils::errors;
|
||||
using mfem::Ordering;
|
||||
|
||||
ElementDisplacementData::ElementDisplacementData(
|
||||
const mfem::FiniteElement& element,
|
||||
mfem::Vector& displacement_dofs,
|
||||
const Ordering::Type ordering
|
||||
) : m_element(&element), m_dimension(0), m_ordering(ordering) {
|
||||
const int dof_count = element.GetDof();
|
||||
|
||||
if (dof_count <= 0) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_DOF_COUNT>("ElementDisplacementData: Displacement elements must have at least one degree of freedom. Got an element with {} dofs", dof_count);
|
||||
}
|
||||
if (displacement_dofs.Size() <= 0 || displacement_dofs.Size() % dof_count != 0) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_DOF_COUNT>("ElementDisplacementData: The displacement vector size ({}) must be a positive multiple of the element degree of freedom count ({}).", displacement_dofs.Size(), dof_count);
|
||||
}
|
||||
|
||||
m_dimension = displacement_dofs.Size() / dof_count;
|
||||
m_dof_matrix.SetSize(dof_count, m_dimension);
|
||||
|
||||
switch (ordering) {
|
||||
case Ordering::byNODES: {
|
||||
for (int componentID = 0; componentID < m_dimension; ++componentID) {
|
||||
for (int dofID = 0; dofID < dof_count; ++dofID) {
|
||||
m_dof_matrix(dofID, componentID) = displacement_dofs(dofID + componentID * dof_count);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Ordering::byVDIM: {
|
||||
for (int dofID = 0; dofID < dof_count; ++dofID) {
|
||||
for (int componentID = 0; componentID < m_dimension; ++componentID) {
|
||||
m_dof_matrix(dofID, componentID) = displacement_dofs(componentID + dofID * m_dimension);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_DOF_ORDERING>("Unsupported ordering");
|
||||
}
|
||||
}
|
||||
|
||||
const mfem::FiniteElement& ElementDisplacementData::get_element() const noexcept {
|
||||
return *m_element;
|
||||
}
|
||||
|
||||
const mfem::DenseMatrix& ElementDisplacementData::get_dof_matrix() const noexcept {
|
||||
return m_dof_matrix;
|
||||
}
|
||||
|
||||
int ElementDisplacementData::get_dimension() const noexcept {
|
||||
return m_dimension;
|
||||
}
|
||||
|
||||
int ElementDisplacementData::get_dof_count() const noexcept {
|
||||
return m_element->GetDof();
|
||||
}
|
||||
|
||||
Ordering::Type ElementDisplacementData::get_ordering() const noexcept {
|
||||
return m_ordering;
|
||||
}
|
||||
|
||||
ElementDisplacementData element_displacement_data_from_element_vdofs(const mfem::FiniteElement& element, mfem::Vector& displacement_dofs) {
|
||||
return ElementDisplacementData(element, displacement_dofs, Ordering::byNODES);
|
||||
}
|
||||
|
||||
ElementCompactificationData::ElementCompactificationData(
|
||||
const mfem::FiniteElement& element,
|
||||
const mfem::Vector& dofs
|
||||
) : m_element(&element), m_dofs(dofs) {
|
||||
if (element.GetRangeType() != mfem::FiniteElement::SCALAR) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_COMPACTIFICATION_RANK>("Compactification coordinate requires a scalar finite element.");
|
||||
}
|
||||
|
||||
if (element.GetMapType() != mfem::FiniteElement::VALUE) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_COMPACTIFICATION_TYPE>("Compactification coordinate requires a value-mapped scalar finite element");
|
||||
}
|
||||
|
||||
if (element.GetDerivType() != mfem::FiniteElement::GRAD) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_COMPACTIFICATION_DERIVATIVE_VALUE>("Compactification coordinate finite element must provide a gradient");
|
||||
}
|
||||
|
||||
if (element.GetDof() <= 0) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_DOF_COUNT>("Compactification coordinatge finite element must have a positive non-zero number of degrees of freedom. Recived {}", element.GetDof());
|
||||
}
|
||||
|
||||
if (dofs.Size() != element.GetDof()) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_DOF_COUNT>("Compactification coordinate degree of freedom count ({}) does not match its finite element dof count ({})", dofs.Size(), element.GetDof());
|
||||
}
|
||||
}
|
||||
|
||||
const mfem::FiniteElement& ElementCompactificationData::get_element() const noexcept {
|
||||
return *m_element;
|
||||
}
|
||||
|
||||
const mfem::Vector& ElementCompactificationData::get_dofs() const noexcept {
|
||||
return m_dofs;
|
||||
}
|
||||
|
||||
int ElementCompactificationData::get_dof_count() const noexcept {
|
||||
return m_dofs.Size();
|
||||
}
|
||||
|
||||
DMWorkspace::DMWorkspace(const int dimension) {
|
||||
set_dimension(dimension);
|
||||
}
|
||||
|
||||
void DMWorkspace::set_dimension(const int dimension) {
|
||||
if (dimension <= 0) {
|
||||
serif_error<std::invalid_argument, SERiFErrorCode::INVALID_DIMENSION>("Domain mapping workspace dimension must be positive and finite. Received {}", dimension);
|
||||
}
|
||||
|
||||
m_dimension = dimension;
|
||||
|
||||
m_field_value.SetSize(dimension);
|
||||
m_field_jacobian.SetSize(dimension, dimension);
|
||||
m_reference_field_jacobian.SetSize(dimension, dimension);
|
||||
|
||||
m_compactification_point.compactification_coordinate = 0.0;
|
||||
m_compactification_point.coordinate_gradient.SetSize(dimension);
|
||||
|
||||
m_reference_normal.SetSize(dimension);
|
||||
m_mapped_normal.SetSize(dimension);
|
||||
m_full_element_jacobian.SetSize(dimension, dimension);
|
||||
|
||||
m_vector_temp.SetSize(dimension);
|
||||
m_matrix_temp_1.SetSize(dimension, dimension);
|
||||
m_matrix_temp_2.SetSize(dimension, dimension);
|
||||
|
||||
m_exterior_result.physical_position.SetSize(dimension);
|
||||
m_exterior_result.mapping_jacobian.SetSize(dimension, dimension);
|
||||
|
||||
m_exterior_variation.physical_position_variation.SetSize(dimension);
|
||||
m_exterior_variation.mapping_jacobian_variation.SetSize(dimension, dimension);
|
||||
}
|
||||
|
||||
int DMWorkspace::get_dimension() const noexcept {
|
||||
return m_dimension;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user