<commit_before>use super::read_mesh::{parse_mesh, read_mesh};
use super::{At, Geo};
use crate::shapes::{kind_from_ndim_npoint, new_shape, Kind, Shape};
use crate::util::GridSearch;
use crate::StrError;
use russell_lab::{sort2, sort3};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;

/// Aliases usize as the group of Point, Edge, Face, or Cell
pub type Group = usize;

/// Aliases usize as the index (==id) of Point and Cell
pub type Index = usize;

/// Aliases (usize,usize) as the key of Edge
pub type EdgeKey = (usize, usize);

/// Aliases (usize,usize,usize) as the key of Face
pub type FaceKey = (usize, usize, usize);

/// Holds point data
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Point {
    /// Identification number which equals the index of the point in the mesh
    ///
    /// **raw data**
    pub id: Index,

    /// Group in which this point belongs to
    ///
    /// # Note
    ///
    /// A good strategy is to leave all point groups set to zero and then mark some
    /// points with a non-zero group to indicate that a selection has been made.
    ///
    /// **raw data**
    pub group: Group,

    /// Point coordinates (2D or 3D)
    ///
    /// **raw data**
    pub coords: Vec<f64>,

    /// Set of boundary edges sharing this point
    ///
    /// (derived property)
    pub shared_by_boundary_edges: HashSet<EdgeKey>,

    /// Set of boundary faces sharing this point
    ///
    /// (derived property)
    pub shared_by_boundary_faces: HashSet<FaceKey>,
}

/// Holds cell (aka geometric shape, polygon, polyhedra) data
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Cell {
    /// Identification number which equals the index of the cell in the mesh
    ///
    /// **raw data**
    pub id: Index,

    /// Group in which this face belongs to
    ///
    /// **raw data**
    pub group: Group,

    /// Space dimension of this cell
    ///
    /// # Note
    ///
    /// The cell's ndim may be different than the space dimension of the mesh.
    /// For example, a 1D line in the 2D or 3D space or a 2D triangle in the 3D space.
    ///
    /// **raw data**
    pub ndim: usize,

    /// List of points defining this cell; in the right order (unsorted)
    ///
    /// **raw data**
    pub points: Vec<Index>,
}

/// Holds edge data (derived data structure)
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Edge {
    /// Group in which this edge belongs to
    ///
    /// # Note
    ///
    /// A good strategy is to leave all edge groups set to zero and then mark some
    /// edge with a non-zero group to indicate that a selection has been made.
    pub group: Group,

    /// List of points defining this edge; in the right order (unsorted)
    pub points: Vec<Index>,

    /// Set of 2D cells sharing this edge (to find the boundary)
    ///
    /// **2D mesh only**
    pub shared_by_2d_cells: HashSet<Index>,

    /// Set of boundary faces sharing this edge
    pub shared_by_boundary_faces: HashSet<FaceKey>,
}

/// Holds face data (derived data structure)
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Face {
    /// Group in which this face belongs to
    ///
    /// # Note
    ///
    /// A good strategy is to leave all face groups set to zero and then mark some
    /// face with a non-zero group to indicate that a selection has been made.
    pub group: Group,

    /// List of points defining this face; in the right order (unsorted)
    pub points: Vec<Index>,

    /// Set of cells sharing this face
    pub shared_by_cells: HashSet<Index>,
}

/// Holds mesh data
#[derive(Deserialize, Serialize)]
pub struct Mesh {
    /// Space dimension of the mesh
    ///
    /// # Note
    ///
    /// The mesh's ndim may be different that an cell's ndim.
    /// For example, a 3D mesh may contain 1D lines or 2D triangles.
    ///
    /// **raw data**
    pub ndim: usize,

    /// All points in the mesh
    ///
    /// **raw data**
    pub points: Vec<Point>,

    /// All cells (aka geometric shape, polygon, polyhedra) in the mesh
    ///
    /// **raw data**
    pub cells: Vec<Cell>,

    /// Set of points on the boundaries
    ///
    /// # Definition
    ///
    /// * A boundary point belongs to a boundary edge or a boundary face
    ///
    /// (derived property)
    pub boundary_points: HashSet<Index>,

    /// Set of edges on the boundaries
    ///
    /// # Definition
    ///
    /// * In 2D: a boundary edge is such that it's shared by one 2D cell only (ignore 1D cells)
    /// * In 3D: a boundary edge belongs to a boundary face
    ///
    /// (derived property)
    pub boundary_edges: HashMap<EdgeKey, Edge>,

    /// Set of faces on the boundaries
    ///
    /// # Definition
    ///
    /// * A boundary face is such that it's shared by one 3D cell only
    ///<commit_msg>Improve doc<commit_after>use super::read_mesh::{parse_mesh, read_mesh};
use super::{At, Geo};
use crate::shapes::{kind_from_ndim_npoint, new_shape, Kind, Shape};
use crate::util::GridSearch;
use crate::StrError;
use russell_lab::{sort2, sort3};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;

/// Aliases usize as the group of Point, Edge, Face, or Cell
pub type Group = usize;

/// Aliases usize as the index (==id) of Point and Cell
pub type Index = usize;

/// Aliases (usize,usize) as the key of Edge
pub type EdgeKey = (usize, usize);

/// Aliases (usize,usize,usize) as the key of Face
pub type FaceKey = (usize, usize, usize);

/// Holds point data
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Point {
    /// Identification number which equals the index of the point in the mesh
    ///
    /// **raw data**
    pub id: Index,

    /// Group in which this point belongs to
    ///
    /// A good strategy is to leave all point groups set to zero and then mark some
    /// points with a non-zero group to indicate that a selection has been made.
    ///
    /// **raw data**
    pub group: Group,

    /// Point coordinates (2D or 3D)
    ///
    /// **raw data**
    pub coords: Vec<f64>,

    /// Set of boundary edges sharing this point
    ///
    /// (derived property)
    pub shared_by_boundary_edges: HashSet<EdgeKey>,

    /// Set of boundary faces sharing this point
    ///
    /// (derived property)
    pub shared_by_boundary_faces: HashSet<FaceKey>,
}

/// Holds cell (aka geometric shape, polygon, polyhedra) data
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Cell {
    /// Identification number which equals the index of the cell in the mesh
    ///
    /// **raw data**
    pub id: Index,

    /// Group in which this face belongs to
    ///
    /// **raw data**
    pub group: Group,

    /// Space dimension of this cell
    ///
    /// The cell's ndim may be different than the space dimension of the mesh.
    /// For example, a 1D line in the 2D or 3D space or a 2D triangle in the 3D space.
    ///
    /// **raw data**
    pub ndim: usize,

    /// List of points defining this cell; in the right order (unsorted)
    ///
    /// **raw data**
    pub points: Vec<Index>,
}

/// Holds edge data (derived data structure)
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Edge {
    /// Group in which this edge belongs to
    ///
    /// A good strategy is to leave all edge groups set to zero and then mark some
    /// edge with a non-zero group to indicate that a selection has been made.
    pub group: Group,

    /// List of points defining this edge; in the right order (unsorted)
    pub points: Vec<Index>,

    /// Set of 2D cells sharing this edge (to find the boundary)
    ///
    /// **2D mesh only**
    pub shared_by_2d_cells: HashSet<Index>,

    /// Set of boundary faces sharing this edge
    pub shared_by_boundary_faces: HashSet<FaceKey>,
}

/// Holds face data (derived data structure)
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Face {
    /// Group in which this face belongs to
    ///
    /// A good strategy is to leave all face groups set to zero and then mark some
    /// face with a non-zero group to indicate that a selection has been made.
    pub group: Group,

    /// List of points defining this face; in the right order (unsorted)
    pub points: Vec<Index>,

    /// Set of cells sharing this face
    pub shared_by_cells: HashSet<Index>,
}

/// Holds mesh data
#[derive(Deserialize, Serialize)]
pub struct Mesh {
    /// Space dimension of the mesh
    ///
    /// The mesh's ndim may be different that an cell's ndim.
    /// For example, a 3D mesh may contain 1D lines or 2D triangles.
    ///
    /// **raw data**
    pub ndim: usize,

    /// All points in the mesh
    ///
    /// **raw data**
    pub points: Vec<Point>,

    /// All cells (aka geometric shape, polygon, polyhedra) in the mesh
    ///
    /// **raw data**
    pub cells: Vec<Cell>,

    /// Set of points on the boundaries
    ///
    /// Note: a boundary point belongs to a boundary edge or a boundary face
    ///
    /// (derived property)
    pub boundary_points: HashSet<Index>,

    /// Set of edges on the boundaries
    ///
    /// Note: In 2D, a boundary edge is such that it's shared by one 2D cell only (ignore 1D cells)
    ///
    /// Note: In 3D, a boundary edge belongs to a boundary face
    ///
    /// (derived property)
    pub boundary_edges: HashMap<EdgeKey, Edge>,

    /// Set of faces on the boundaries
    ///
    /// Note: A boundary face is such that it's shared by one 3D cell only
    ///
{'fraction_non_alphanumeric': 0.12628865979381443, 'fraction_numerical': 0.004536082474226804, 'mean_word_length': 2.3245373543522962, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '573258', 'n_tokens_mistral': 2927, 'n_tokens_neox': 2871, 'n_words': 1233}