Complete PDE Examples

Three complete, real-world examples demonstrating MathHook's PDE solving capabilities across heat, wave, and Laplace equations. Each example includes full problem setup, mathematical formulation, MathHook implementation, and physical interpretation.

📐

Mathematical Definition

Example 1: Heat Diffusion

ut=α2ux2\frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2}

Example 2: Wave Propagation

2ut2=c22ux2\frac{\partial^2 u}{\partial t^2} = c^2 \frac{\partial^2 u}{\partial x^2}

Example 3: Electrostatic Potential

2ux2+2uy2=0\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = 0

Code Examples

Heat Diffusion in Steel Rod - Complete Implementation

1-meter steel rod cooling from 100°C with ice water at ends. Full implementation with error handling.

use mathhook::prelude::*;

fn solve_cooling_rod() -> Result<(), Box<dyn std::error::Error>> {
    // Define Variables
    let u = symbol!(u);
    let x = symbol!(x);
    let t = symbol!(t);

    // Create PDE
    let equation = expr!(u);
    let pde = Pde::new(equation, u, vec![x.clone(), t.clone()]);

    // Material Properties
    let alpha = expr!(0.000013);  // Steel thermal diffusivity

    // Boundary Conditions
    let bc_left = BoundaryCondition::dirichlet(
        expr!(0),
        BoundaryLocation::Simple {
            variable: x.clone(),
            value: expr!(0),
        },
    );
    let bc_right = BoundaryCondition::dirichlet(
        expr!(0),
        BoundaryLocation::Simple {
            variable: x,
            value: expr!(1),
        },
    );

    // Initial Condition
    let ic = InitialCondition::value(expr!(100));

    // Solve
    let solver = HeatEquationSolver::new();
    let result = solver.solve_heat_equation_1d(
        &pde,
        &alpha,
        &[bc_left, bc_right],
        &ic,
    )?;

    // Examine Solution
    println!("Heat Equation Solution for Cooling Steel Rod");
    println!("Solution structure: {}", result.solution);
    println!("Eigenvalues: {:?}", result.eigenvalues.iter().take(5).collect::<Vec<_>>());
    println!("Fourier coefficients: {:?}", result.coefficients.iter().take(5).collect::<Vec<_>>());

    Ok(())
}

Vibrating Guitar String - Musical Analysis

E4 guitar string with musical frequency analysis and standing wave nodes.

use mathhook::prelude::*;

fn solve_vibrating_string() -> Result<(), Box<dyn std::error::Error>> {
    let u = symbol!(u);
    let x = symbol!(x);
    let t = symbol!(t);

    let equation = expr!(u);
    let pde = Pde::new(equation, u, vec![x.clone(), t.clone()]);

    let c = expr!(442);  // Wave speed

    let bc1 = BoundaryCondition::dirichlet(
        expr!(0),
        BoundaryLocation::Simple { variable: x.clone(), value: expr!(0) },
    );
    let bc2 = BoundaryCondition::dirichlet(
        expr!(0),
        BoundaryLocation::Simple { variable: x, value: expr!(0.65) },
    );

    let ic_position = InitialCondition::value(expr!(0.005));
    let ic_velocity = InitialCondition::derivative(expr!(0));

    let solver = WaveEquationSolver::new();
    let result = solver.solve_wave_equation_1d(
        &pde, &c, &[bc1, bc2], &ic_position, &ic_velocity
    )?;

    println!("Wave Equation Solution for Vibrating Guitar String");
    println!("Solution: {}", result.solution);

    // Compute musical frequencies
    let L = 0.65;
    let c_val = 442.0;
    for n in 1..=5 {
        let f_n = (n as f64) * c_val / (2.0 * L);
        println!("f_{} = {:.2} Hz (mode {})", n, f_n, n);
    }

    Ok(())
}

Electrostatic Potential in Rectangular Plate

10cm × 5cm plate with grounded sides and fixed potential top edge.

use mathhook::prelude::*;

fn solve_electrostatic_potential() -> Result<(), Box<dyn std::error::Error>> {
    let u = symbol!(u);
    let x = symbol!(x);
    let y = symbol!(y);

    let equation = expr!(u);
    let pde = Pde::new(equation, u, vec![x.clone(), y.clone()]);

    let bc_left = BoundaryCondition::dirichlet(expr!(0), BoundaryLocation::Simple { variable: x.clone(), value: expr!(0) });
    let bc_right = BoundaryCondition::dirichlet(expr!(0), BoundaryLocation::Simple { variable: x.clone(), value: expr!(0.1) });
    let bc_bottom = BoundaryCondition::dirichlet(expr!(0), BoundaryLocation::Simple { variable: y.clone(), value: expr!(0) });
    let bc_top = BoundaryCondition::dirichlet(expr!(100), BoundaryLocation::Simple { variable: y, value: expr!(0.05) });

    let solver = LaplaceEquationSolver::new();
    let result = solver.solve_laplace_equation_2d(&pde, &[bc_left, bc_right, bc_bottom, bc_top])?;

    println!("Laplace Equation Solution for Electrostatic Potential");
    println!("Solution: {}", result.solution);
    println!("X-eigenvalues: {:?}", result.x_eigenvalues.iter().take(5).collect::<Vec<_>>());

    Ok(())
}

🔗 Related Topics