Skip to content

Instantly share code, notes, and snippets.

@mr-glt
Created May 4, 2024 14:51
Show Gist options
  • Save mr-glt/b7c704b8193ecbe331fd7bf1d8313390 to your computer and use it in GitHub Desktop.
Save mr-glt/b7c704b8193ecbe331fd7bf1d8313390 to your computer and use it in GitHub Desktop.
point_map.h
#ifndef POINT_MAP_H
#define POINT_MAP_H
// Local
#include "libvcad/tree/leaf.h"
#include "libvcad/geometry/primitives.h"
#include "libvcad/geometry/tetrahedron.h"
#include "libvcad/utils/expression_evaluator.h"
// CGAL
typedef CGAL::AABB_tree<AABB_tetrahedron_traits> AABBTree;
//! \brief A leaf node that represents simulation results that are imported.
//! \details This class is used to import simulation results from external files and map a multi-material distribution them as a design
//! The simulation results must be stored in a tetrahedral mesh saved as a .inp file and a displacement field saved as a .csv file
//! This class assumes nodal displacements are stored in the displacement field file and that the indices of the nodes in the tetrahedral mesh
//! correspond to the indices of the nodes in the displacement field file.
//! The displacement field file must have the following format (where xyz is the coordinates of the node and uvw is the displacement vector):
//! x1, y1, z1, u1, v1, w1
//! x2, y2, z2, u2, v2, w2
//! ...
//! The tetrahedral mesh file must be an Abaqus .inp file using C3D4 elements.
//! The point map can be used to evaluate functions at any point in space by interpolating the simulation results. However, the material distribution
//! is only available within the tetrahedral mesh. Likewise, the signed distance returned by the evaluate() function is simple point membership.
//! Mapping functions are defined using the exprtk library and are similar to the f_grade() node. When sampling a point in space, the following variables
//! are available in math expressions:
//! - x, y, z: The coordinates of the point
//! - rho, phic, r: The cylindrical coordinates of the point
//! - theta, phis: The spherical coordinates of the point
//! - dx, dy, dz: The displacement vector at the point
//! - len: The length of the displacement vector
//! Similar to f_grade(), each function defined must also have a corresponding material id defined with it. When sampled using distribution() the
//! volume fractions/ probability density is returned as evaluated by the functions.
//! The point map can be used in probability mode where the material() function uses the material distribution as a probability masses and returns
//! a random material id based on the distribution. Threshold mode is also available where
//! the material() function returns the material id with the highest probability mass.
//! \note This class only supports tetrahedral meshes and displacement fields
//! \todo Add support for other types of fields
class PointMap : public Leaf
{
public:
//! \brief Constructor
//! \param tet_mesh_path Path to the tetrahedral mesh file
//! \param displacement_field_path Path to the displacement field file
//! \param functions List of functions to evaluate
//! \param materials List of materials
//! \param prob_mode Whether the point map is in probability mode
PointMap(const std::string& tet_mesh_path, const std::string& displacement_field_path,
std::vector<std::string> functions, std::vector<uint8_t> materials, bool prob_mode = true);
//! \brief Destructor
PointMap() = default;
//! \brief Loads the tetrahedral mesh and displacement field
void prepare() final;
//! \see Node::evaluate()
double evaluate(double x, double y, double z) final;
//! \see Node::material()
uint8_t material(double x, double y, double z) final;
//! \see Node::material_list()
std::vector<uint8_t> material_list() override;
//! \see Node::distribution()
std::unordered_map<uint8_t, float> distribution(double x, double y, double z) override;
//! \see Node::clone()
std::shared_ptr<Node> clone() override;
private:
//! \brief A struct to store a point with its displacement
struct ValuedPoint
{
glm::vec3 coords;
vec3 displacement;
};
//! \brief Loads the displacement field from a file into this object
//! \param inp_filename Path to the inp file
//! \param point_map_filename Path to the displacement field file
void LoadTetrahedronsFromFile(const std::string& inp_filename, const std::string& point_map_filename);
//! \brief Computes the displacement at a point in space. If the point is not on a node, the displacement is interpolated
//! \param x X coordinate of the point
//! \param y Y coordinate of the point
//! \param z Z coordinate of the point
//! \return The displacement at the point, interpolated if necessary
vec3 compute_displacement(double x, double y, double z);
void prepare_evaluators();
//! \brief Splits a string by a delimiter
//! \param s The string to split
//! \param delimiter The delimiter to split by
//! \return A vector of strings
static std::vector<std::string> Split(const std::string &s, char delimiter);
// Parameters
std::string m_tet_mesh_path;
std::string m_displacement_field_path;
std::vector<std::string> m_function_strings;
std::vector<uint8_t> m_materials;
bool m_prob_mode = true;
std::vector<std::shared_ptr<ExpressionEvaluator>> m_evaluators;
std::shared_ptr<AABBTree> m_aabb_tree;
double m_x, m_y, m_z;
double m_rho, m_phic;
double m_r, m_theta, m_phis;
double m_dx, m_dy, m_dz;
double m_len;
};
#endif // POINT_MAP_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment