Skip to content

Latest commit

 

History

History
373 lines (304 loc) · 15.4 KB

File metadata and controls

373 lines (304 loc) · 15.4 KB

VOLCO FEA Module - LLM Reference Document

This document provides a comprehensive overview of the Finite Element Analysis (FEA) module structure and functionality within the VOLCO repository. It serves as a reference for large language models to understand the FEA module without requiring all files to be uploaded as context.

1. Module Overview

The FEA module extends VOLCO's capabilities by providing structural analysis functionality for voxel models generated by VOLCO simulations. It enables users to:

  • Convert voxel matrices to finite element meshes
  • Apply boundary conditions to the mesh
  • Solve linear static structural problems
  • Visualize results including displacements and stresses using Plotly
  • Save and load analysis results in various formats

The module is designed to work seamlessly with VOLCO's voxel-based output, allowing for direct structural analysis of 3D printed parts simulated by VOLCO.

2. Module Structure

app/postprocessing/fea/
├── __init__.py       # Module entry point
├── core.py           # Main analysis functionality
├── mesh.py           # Mesh generation from voxel matrices
├── boundary.py       # Boundary condition application
├── solver.py         # Linear static FEA solver
├── viz.py            # Visualization of results
└── io.py             # Input/output functionality for saving/loading results

3. Core Components

Main Entry Point (app/postprocessing/fea/init.py)

  • Exposes the main functions: analyze_voxel_matrix and load_fea_results
  • Provides a clean interface for users to access the module's functionality

Core Analysis (app/postprocessing/fea/core.py)

  • analyze_voxel_matrix(): Main entry point for FEA analysis
  • load_fea_results(): Function to load previously saved results
  • Orchestrates the entire analysis process from mesh generation to results visualization

Mesh Generation (app/postprocessing/fea/mesh.py)

  • generate_mesh(): Converts voxel matrix to hexahedral elements
  • check_continuity(): Ensures the voxel model represents a single continuous body
  • extract_surface_elements(): Identifies elements on the model surface
  • get_top_surface_nodes(), get_bottom_surface_nodes(): Helper functions for boundary condition application

Boundary Conditions (app/postprocessing/fea/boundary.py)

  • Surface: Enumeration for standard surface identifiers (PLUS_X, MINUS_X, PLUS_Y, MINUS_Y, PLUS_Z, MINUS_Z)
  • apply_boundary_conditions(): Applies boundary conditions using the enhanced system
  • identify_surface_nodes(): Identifies nodes on a specified surface
  • select_nodes_by_predicate(), select_nodes_in_box(), select_nodes_on_plane(): Functional utilities for expert users

Solver (app/postprocessing/fea/solver.py)

  • solve_static_problem(): Main solver function for linear static analysis
  • assemble_system(): Assembles global stiffness matrix and force vector
  • calculate_element_stiffness(): Computes element stiffness matrices
  • shape_functions(): Calculates shape functions for hexahedral elements
  • apply_boundary_conditions(): Modifies system equations to account for boundary conditions
  • solve_system(): Solves the system of equations
  • calculate_stresses_and_strains(): Post-processes results to obtain stresses and strains

Visualization (app/postprocessing/fea/viz.py)

  • visualize_fea(): Unified visualization function using Plotly with optimized mesh rendering
  • export_visualization(): Saves visualizations to HTML files
  • visualize_voxel_matrix(): Visualizes the original voxel matrix

Input/Output (app/postprocessing/fea/io.py)

  • save_results(): Saves analysis results to file in various formats
  • load_results(): Loads analysis results from file
  • Support for multiple file formats: pickle, JSON, and HDF5 (if available)

4. Key Data Flows

Voxel Matrix to FE Mesh

  1. analyze_voxel_matrix() → Entry point for analysis
  2. check_continuity() → Ensures model is a single body
  3. generate_mesh() → Converts voxels to hexahedral elements
    • Creates nodes at voxel corners
    • Defines element connectivity
    • Maps physical coordinates based on voxel size

Boundary Condition Application

  1. apply_boundary_conditions() → Applies boundary conditions using the enhanced system
    • Simple Mode: Uses Surface enumerations (PLUS_X, MINUS_X, etc.) with "fix" keyword or vector constraints
    • Expert Mode: Uses custom functions for advanced boundary conditions
  2. identify_surface_nodes() → Identifies nodes on specified surfaces
  3. Creates dictionary mapping node indices to prescribed displacements

Solving the FE Problem

  1. solve_static_problem() → Main solver function
  2. assemble_system() → Creates global stiffness matrix and force vector
  3. apply_boundary_conditions() → Modifies system for boundary conditions
  4. solve_system() → Solves the linear system of equations
  5. calculate_stresses_and_strains() → Post-processes results

Results Visualization

  1. visualize_fea() → Creates Plotly visualization with optimized mesh rendering
    • Uses the "volco mesh visualization method" that only renders visible faces
    • Supports showing both original and deformed meshes simultaneously
    • Deforms mesh based on calculated displacements
    • Colors elements based on stress or displacement values
    • Creates interactive 3D visualization with colorbar

Results Storage and Retrieval

  1. save_results() → Saves results to file
    • Supports pickle, JSON, and HDF5 formats
    • Includes metadata about the analysis
  2. load_results() → Loads results from file
    • Automatically detects file format
    • Reconstructs numpy arrays from serialized data

5. Configuration Options

Material Properties

  • young_modulus: Young's modulus in MPa (default: 2000.0 for typical PLA)
  • poisson_ratio: Poisson's ratio (default: 0.3 for typical PLA)

Boundary Conditions

  • constraints: Dictionary mapping surface identifiers or custom functions to constraints
    • Simple Mode: {Surface.MINUS_Z: "fix", Surface.PLUS_Z: [None, None, -0.1, None, None, None]}
    • Expert Mode: {"custom": custom_function}

Visualization Options

  • visualization: Whether to generate visualization (default: True)
  • result_type: Type of result to visualize ('displacement', 'von_mises')
  • scale_factor: Factor to scale displacements for visualization (default: 1.0)
  • show_undeformed: Whether to show the original undeformed mesh (default: False)
  • original_opacity: Opacity of the original mesh when shown (default: 0.3)

Results Storage Options

  • save_results: Whether to save results to a file (default: False)
  • save_path: Path to save results (default: 'Results_volco/fea/results')
  • save_format: Format to save results ('pickle', 'json', or 'hdf5') (default: 'pickle')
  • include_visualization: Whether to include visualization in saved file (default: False)

6. Usage Patterns

Simplified Import

from volco import run_simulation
from volco_fea import analyze_voxel_matrix, Surface, visualize_fea, export_visualization

This simplified import pattern allows users to import all FEA functionality from a single location, making the code cleaner and more intuitive.

Basic Usage

from volco import run_simulation
from volco_fea import analyze_voxel_matrix, Surface

# Run VOLCO simulation
output = run_simulation(
    gcode_path='examples/gcode_example.gcode',
    printer_config_path='examples/printer_settings.json',
    sim_config_path='examples/simulation_settings.json'
)

# Get cropped voxel matrix and voxel size
voxel_matrix = output.cropped_voxel_space
voxel_size = output._simulation.voxel_size

# Define boundary conditions using Simple Mode
from app.postprocessing.fea.boundary import Surface

# Calculate displacement as 1% of model height
model_height = voxel_matrix.shape[2] * voxel_size
displacement_magnitude = model_height * 0.01

boundary_conditions = {
    'constraints': {
        Surface.MINUS_Z: "fix",  # Fix bottom surface
        Surface.PLUS_Z: [None, None, -displacement_magnitude, None, None, None]  # Apply compression on top
    }
}

# Run FEA analysis
results = analyze_voxel_matrix(
    voxel_matrix=voxel_matrix,
    voxel_size=voxel_size,
    boundary_conditions=boundary_conditions,
    visualization=True,
    result_type='von_mises',
    scale_factor=10.0  # Exaggerate deformation for visualization
)

# Access results
print(f"Maximum displacement: {results['max_displacement']} mm")
print(f"Maximum von Mises stress: {results['max_von_mises']} MPa")

# Save visualization
export_visualization(results['visualization'], "Results_volco/fea/von_mises.html")

Saving and Loading Results

# Save results
# Define boundary conditions
boundary_conditions = {
    'constraints': {
        Surface.MINUS_Z: "fix",  # Fix bottom surface
        Surface.PLUS_Z: [None, None, -displacement_magnitude, None, None, None]  # Apply compression on top
    }
}

results = analyze_voxel_matrix(
    voxel_matrix=voxel_matrix,
    voxel_size=voxel_size,
    boundary_conditions=boundary_conditions,
    save_results=True,
    save_path='Results_volco/fea/my_analysis',
    save_format='pickle'
)

# Load results
from volco_fea import load_fea_results, visualize_fea, export_visualization
loaded_results = load_fea_results('Results_volco/fea/my_analysis.pkl')

# Create visualization from loaded results
viz = visualize_fea(
    nodes=loaded_results['nodes'],
    elements=loaded_results['elements'],
    displacements=loaded_results['displacements'],
    von_mises=loaded_results['von_mises'],
    result_type='von_mises',
    scale_factor=1.0,
    show_undeformed=True  # Show both original and deformed meshes
)

# Export the visualization to an HTML file
export_visualization(viz, "Results_volco/fea/loaded_von_mises_with_undeformed.html")

Custom Material Properties

# Define custom material properties for ABS
material_properties = {
    'young_modulus': 2300.0,  # MPa (typical for ABS)
    'poisson_ratio': 0.35     # Typical for ABS
}

# Define boundary conditions
boundary_conditions = {
    'constraints': {
        Surface.MINUS_Z: "fix",  # Fix bottom surface
        Surface.PLUS_Z: [None, None, -displacement_magnitude, None, None, None]  # Apply compression on top
    }
}

results = analyze_voxel_matrix(
    voxel_matrix=voxel_matrix,
    voxel_size=voxel_size,
    material_properties=material_properties,
    boundary_conditions=boundary_conditions
)

Custom Boundary Conditions

Simple Mode

from volco_fea import Surface

# Define boundary conditions using Simple Mode
boundary_conditions = {
    'constraints': {
        Surface.MINUS_Z: "fix",  # Fix bottom surface
        Surface.PLUS_Z: [None, None, -0.1, None, None, None]  # Apply 0.1mm compression on top
    }
}

results = analyze_voxel_matrix(
    voxel_matrix=voxel_matrix,
    voxel_size=voxel_size,
    boundary_conditions=boundary_conditions
)

Expert Mode

# Define custom boundary conditions using expert mode
def custom_constraint_function(nodes, elements):
    # Get model dimensions directly
    z_coords = nodes[:, 2]
    min_z = np.min(z_coords)
    max_z = np.max(z_coords)
    
    # Calculate model height
    model_height = max_z - min_z
    
    # Calculate displacement as 1% of model height
    displacement_magnitude = model_height * 0.01
    
    return {
        # Fix nodes on the bottom surface
        i: [0, 0, 0, 0, 0, 0] for i in range(len(nodes))
        if abs(nodes[i, 2] - min_z) < 1e-6
    } | {
        # Apply displacement to nodes on the top surface
        i: [None, None, -displacement_magnitude, None, None, None] for i in range(len(nodes))
        if abs(nodes[i, 2] - max_z) < 1e-6
    }

boundary_conditions = {
    'constraints': {
        "custom": custom_constraint_function
    }
}

results = analyze_voxel_matrix(
    voxel_matrix=voxel_matrix,
    voxel_size=voxel_size,
    boundary_conditions=boundary_conditions
)

7. Key Algorithms

Mesh Generation

  • Voxel to Hexahedral Conversion: Each material voxel is converted to a hexahedral element with 8 nodes
  • Node Sharing: Nodes are shared between adjacent elements to ensure mesh continuity
  • Continuity Checking: Connected component labeling is used to ensure the model is a single continuous body

Linear Static FEA

  • Direct Stiffness Method: Assembly of element stiffness matrices into global stiffness matrix
  • Gaussian Quadrature: Numerical integration for element stiffness calculation
  • Shape Functions: Trilinear shape functions for hexahedral elements
  • Sparse Matrix Solver: Efficient solution of large sparse linear systems

Stress and Strain Calculation

  • Strain-Displacement Relation: B-matrix maps nodal displacements to strains
  • Stress-Strain Relation: D-matrix (material matrix) maps strains to stresses
  • von Mises Stress: Calculation of equivalent stress for failure prediction

8. Module Dependencies

  • volco_fea.pyapp/postprocessing/fea/core.py, app/postprocessing/fea/viz.py, app/postprocessing/fea/boundary.py, app/postprocessing/fea/io.py (simplified import interface)
  • app/postprocessing/fea/__init__.pyapp/postprocessing/fea/core.py
  • app/postprocessing/fea/core.pyapp/postprocessing/fea/mesh.py, app/postprocessing/fea/solver.py, app/postprocessing/fea/boundary.py, app/postprocessing/fea/viz.py, app/postprocessing/fea/io.py
  • app/postprocessing/fea/mesh.pyscipy.ndimage (for connected component labeling)
  • app/postprocessing/fea/solver.pyscipy.sparse, scipy.sparse.linalg (for sparse matrix operations)
  • app/postprocessing/fea/viz.pyplotly
  • app/postprocessing/fea/io.pypickle, json, h5py (optional)

9. Common Modification Patterns

Adding New Material Models

  1. Modify solver.py to include new material behavior
  2. Update the material matrix calculation in calculate_element_stiffness()
  3. Add new material parameters to the material_properties dictionary

Supporting Additional Boundary Conditions

  1. Add new surface identifiers to the Surface enumeration in boundary.py
  2. Extend the apply_boundary_conditions() function to handle new constraint types
  3. Add new functional utilities for expert users

Adding New Result Types

  1. Update calculate_stresses_and_strains() in solver.py to compute additional results
  2. Modify the results dictionary in analyze_voxel_matrix() to include the new results
  3. Update visualization functions to support the new result type

Extending Visualization Capabilities

  1. Add new visualization features to the unified visualize_fea() function in viz.py
  2. Add any necessary parameters to the visualization methods

10. Performance Considerations

  • Mesh Size: The number of elements grows cubically with model resolution, affecting memory usage and computation time
  • Sparse Matrix Operations: Efficient sparse matrix storage and solvers are used to handle large models
  • Visualization Memory Usage: Rendering large models can be memory-intensive, especially with Plotly
  • Optimized Mesh Rendering: The "volco mesh visualization method" significantly improves performance by only rendering visible faces
  • File Format Selection: HDF5 is more efficient for large datasets compared to pickle or JSON
  • Continuity Checking: Connected component labeling can be memory-intensive for large voxel matrices
  • Parallelization: The current implementation is single-threaded; parallelization could improve performance for large models