caexfer 0.2.0

Transfer finite-element meshes, voxel occupancy, and results across CAE formats
Documentation
use std::path::PathBuf;

use crate::core::{Dataset, VoxelGrid};

use super::Format;

/// Where an omission or assumption enters a conversion.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Stage {
    /// Information not represented when reading the source.
    Source,

    /// Information not representable by the destination.
    Destination,

    /// A value or frame assumed by the projection.
    Assumption,
}

impl Stage {
    /// Stable lowercase name for machine-readable reports.
    #[must_use]
    pub fn name(self) -> &'static str {
        match self {
            Self::Source => "source",
            Self::Destination => "destination",
            Self::Assumption => "assumption",
        }
    }
}

/// A caller decision that supplies or accepts a value absent from the source.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AssumptionKind {
    /// Treat a companion mesh and Nastran result as using the basic frame.
    BasicFrame,

    /// Fill absent rotational displacement components with numeric zero.
    ZeroRotations,

    /// Treat a synthetic all-zero displacement table as intended output.
    SyntheticZero,
}

/// One piece of information omitted or explicitly assumed.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Omission {
    /// Origin of the omission or assumption.
    pub stage: Stage,

    /// Specific caller assumption, when this notice supplies missing data.
    pub assumption: Option<AssumptionKind>,

    /// Human-readable detail; wording is not a stable API.
    pub detail: String,
}

impl Omission {
    /// Retain the origin of one omission for machine-readable reports.
    pub(super) fn new(stage: Stage, detail: impl Into<String>) -> Self {
        Self {
            stage,
            assumption: None,
            detail: detail.into(),
        }
    }

    /// Record one specifically identified projection assumption.
    pub fn assumed(kind: AssumptionKind, detail: impl Into<String>) -> Self {
        Self {
            stage: Stage::Assumption,
            assumption: Some(kind),
            detail: detail.into(),
        }
    }
}

/// Supported source data and its read-side omissions or assumptions.
/// The `dataset` is a projection; `omissions` explains what was not carried
/// or verified from the source format. Retain the original file when those
/// details matter.
#[derive(Debug, Clone, PartialEq)]
pub struct ReadResult {
    /// Detected or explicitly selected source format.
    pub format: Format,

    /// Projected mesh and fields.
    pub dataset: Dataset,

    /// Exact grid geometry when the source is VTI or VOX.
    pub voxel_grid: Option<VoxelGrid>,

    /// Source information omitted or assumed in the projected dataset.
    pub omissions: Vec<Omission>,

    /// True when source point IDs were assigned because the file did not carry them.
    /// Such a mesh cannot verify Nastran result node identity.
    pub generated_point_ids: bool,
}

/// Counts and omissions for one conversion.
/// `fields` counts fields before destination filtering, while `omissions`
/// records source losses, destination losses, and explicit assumptions.
/// The default is an empty report with zero counts.
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ConversionReport {
    /// Number of source mesh points.
    pub points: usize,

    /// Number of source mesh cells.
    pub cells: usize,

    /// Number of source numeric fields before destination filtering.
    pub fields: usize,

    /// Destination grid dimensions and occupied cell count for VTI/VOX output.
    pub voxel_grid: Option<([usize; 3], usize)>,

    /// Source and destination omissions, including explicit assumptions.
    pub omissions: Vec<Omission>,

    /// Separate receipt when an OP2 companion mesh is written.
    pub mesh_output: Option<CompanionReport>,
}

/// Receipt for a separately written OP2 companion mesh.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CompanionReport {
    /// Installed companion path.
    pub path: PathBuf,
    /// Companion mesh format.
    pub format: Format,
    /// Source and destination omissions for the companion.
    pub omissions: Vec<Omission>,
}