# Seastead Parametric CAD Workflow Below is a complete, self-contained HTML document answering all your questions — the short version is: **yes, a single OpenSCAD ground truth is the right architecture**, with STL as your interchange format, **Capytaine (BEM) as your primary wave-response tool** (much cheaper than CFD at this stage), and **CalculiX or Code_Aster for FEA** via a gmsh mesh conversion step. The 1:50 plastic structural model question has a genuinely encouraging answer — the numbers happen to work out — with important caveats about FDM printing. ```html Seastead Parametric CAD Workflow — Open Source Toolchain

Parametric CAD Workflow for Seastead Design

One ground-truth model → printed scale models, wave simulations, FEA & CFD — all open source

Executive summary: Yes — a single OpenSCAD "ground truth" file set is not only reasonable, it's the standard best practice for this kind of multi-purpose parametric workflow. Keep all dimensions full-scale in meters in one parameters file, derive everything else from it, and export STL as your universal interchange format. Capytaine is the right primary tool for wave response (it wants exactly what OpenSCAD produces: a closed triangular mesh), FEA needs one extra conversion step (STL → gmsh → volume mesh → CalculiX), and full CFD should be saved for a few targeted confirmation runs. The 1:50 plastic structural model question has a surprisingly favorable answer — see §6.

1. Recommended Open-Source Software Stack

TaskPrimary ToolInput FormatNotes
Parametric ground truthOpenSCAD.scadKeep as-is. Your existing investment pays off.
Scale model printingPrusaSlicer or Cura.stlOpenSCAD CLI can batch-export scaled STLs.
Wave response (hydrodynamics)Capytaine (BEM, successor to Nemoh).stl (via meshio) or Nemoh .inpPython; gives RAOs, added mass, damping, wave loads vs. period. This should be your workhorse.
FEA (structure strength)CalculiX (with PrePoMax GUI) or Code_Aster (Salome-Meca), or Elmer.inp / .med (volume mesh)All accept Abaqus-style .inp from gmsh. CalculiX + PrePoMax has the gentlest learning curve.
CFD (waves, viscous effects)OpenFOAM + waves2Foam (or overWave / olaFlow).stl for snappyHexMeshUse sparingly — 100× the cost of BEM for this stage. Perfect STL consumption though.
Format conversion hubmeshio (Python) + MeshLabeverything → everythingSTL ↔ Nemoh, STL repair, decimation.
Mesh → volume mesh for FEAgmsh.stl → .inp/.medThe one unavoidable conversion step (see §5).
Version controlgit.scad + everythingEvery design variant is a commit; exports are regenerable artifacts.
Bridge / escape hatchFreeCAD (has an OpenSCAD workbench).scad → STEPWhen you eventually need STEP files for the naval architect or a machine shop.

2. Is a Single Ground Truth Reasonable? How to Structure It

Yes — this is exactly how professional engineering pipelines are built: a single parametric master model from which every derived artifact is generated. The rules that make it work:

2.1 One parameters file, full-scale units

OpenSCAD is unitless; software downstream isn't. The single most important convention: 1 OpenSCAD unit = 1 meter, full-scale. Capytaine, OpenFOAM, and FEA solvers all work in meters by default, so the ground truth needs no scaling for simulation. Only the 3D-printing exports get scaled (slicers assume 1 unit = 1 mm).

// ============ params.scad — THE single source of truth ============
// All lengths in meters, FULL SCALE. Nothing else in the project
// defines a dimension; every other file reads from here.

$fn = 64;              // global mesh resolution (tune per export)

// --- Hull / spar ---
spar_diameter     = 2.4;
spar_length       = 12.0;
ballast_draft     = 8.0;
hull_diameter     = 6.0;
hull_freeboard    = 3.0;

// --- Structure ---
plate_thickness   = 0.012;    // aluminum plate
bulkhead_spacing = 1.5;

// --- Joinery (printed model assembly) ---
pin_diameter      = 0.008;   // full-scale equiv. of registration pins
print_clearance   = 0.0002;  // slip-fit tolerance for printed parts

// --- Exports ---
print_scale       = 1/50;    // Froude model scale factor

2.2 File structure

seastead/
├── params.scad          # all constants — the only place numbers live
├── parts/
│   ├── spar.scad        # module spar() — geometry only, no dimensions
│   ├── hull.scad        # module hull()
│   ├── deck.scad
│   └── joinery.scad     # registration pins/holes for printed parts
├── assembly.scad        # the full seastead = the ground truth of "how it fits"
├── exports/
│   ├── export_print.scad    # scaled STLs for the printer
│   ├── export_sim.scad      # full-size closed STL for Capytaine/CFD
│   └── export_fea.scad      # exterior + internal bulkheads as surfaces
└── analysis/
    ├── capytaine/  (python scripts, results)
    ├── fea/        (gmsh .geo scripts, CalculiX runs)
    └── cfd/        (OpenFOAM cases)

2.3 How to specify how printed parts fit together

OpenSCAD has no assembly-constraint system like real CAD, but you can get 90% of the benefit with two conventions:

  1. Global coordinates in the assembly file. Each part module draws itself around its own origin; assembly.scad places parts with transforms computed only from params.scad. If two parts don't collide in assembly.scad, they fit at every scale.
  2. Parametric joinery. Put registration pins, keying tabs, and matching holes in joinery.scad, sized from pin_diameter and print_clearance. Every printable part automatically gets its pin holes cut and its pins added. Because both come from the same module, they mate at any scale.
// joinery.scad — every printed part calls these
module pin()   { cylinder(d = spar_diameter*0 + pin_diameter, h = pin_diameter*3); }
module pin_hole() { cylinder(d = pin_diameter + 2*print_clearance, h = pin_diameter*4); }

// export_print.scad — scale happens ONLY here
module export_spar_section_1() {
    scale(1000 * print_scale)   // meters → mm, scaled 1:50
        spar_section_1();
}
spar_section_1();  // selected via CLI -D part=...

2.4 Batch-regenerate everything with the CLI

Whenever you change a parameter, regenerate all artifacts. OpenSCAD's CLI makes this a script:

#!/bin/bash
# regenerate.sh — run after every design change
for p in spar_sec1 spar_sec2 hull deck flange; do
  openscad -o exports/STL/$p.stl -D "part=\"$p\"" exports/export_print.scad
done
openscad -o exports/STL/seastead_full.stl exports/export_sim.scad   # 1 unit = 1 m
openscad -o exports/STL/hull_surfaces.stl exports/export_fea.scad
# then: python analysis/capytaine/run_bem.py
#       gmsh analysis/fea/mesh.geo -3 -format inp
Why this works: because OpenSCAD's CSG-based output is usually manifold and watertight (unlike mesh-modeling tools), your STLs are directly usable by Capytaine, snappyHexMesh, and gmsh with minimal repair. That's a real, underrated advantage of OpenSCAD for exactly your use case.

2b. Froude-Scale Model Printing Notes

For tow-tank-style wave testing, remember the Froude scaling rules for interpreting your printed model (λ = 50):

QuantityModel / Full scale
Length1 / 50
Time, wave period1 / √50 ≈ 1 / 7.07
Velocity1 / √50
Frequency√50 ×
Force (hydrodynamic)1 / 50³ = 1 / 125,000
Mass (for ballast & CG match!)1 / 125,000 — you must add ballast to the printed model to match full-scale displacement, center of gravity, and (ideally) roll/pitch inertia. Printing alone will never get this right.

3. Pipeline to Capytaine — Your Primary Wave-Response Tool

At the design-screening stage you almost never need CFD. Capytaine is a boundary-element method (BEM) code: it computes, for each wave period and heading, the motions (RAOs — response amplitude operators), added mass, damping, and wave excitation forces. A run that would take OpenFOAM a day takes Capytaine seconds-to-minutes, so you can sweep dozens of design variants. It's the right tool for "how does it work in waves" at this stage.

It consumes exactly what you have: a closed triangular surface mesh, via meshio:

# pip install capytaine meshio matplotlib
import capytaine as cpt
from capytaine.io.meshio import load_from_meshio

# Full-scale closed hull (meters). Capytaine clips it at the waterline itself.
mesh = load_from_meshio("exports/STL/seastead_full.stl")
body = cpt.FloatingBody(mesh, name="seastead")
body.add_all_rigid_body_dofs()
body.center_of_mass = (0, 0, -1.5)      # from your params
body.inertia_matrix = ...               # scaled from your design

test_matrix = cpt.matrix_like(...)      # periods 2–20 s, headings
solver = cpt.BEMSolver()
rbs = solver.fill_dataset(test_matrix, body)

# Then plot RAOs: heave/pitch vs wave period, for each wave height,
# i.e. exactly "visualize different wave sizes and periods"
import matplotlib.pyplot as plt
rabs = rbs["RAO"]  # motion per wave amplitude

Mesh rules for BEM: panel size should be smaller than ~1/8 of the shortest wavelength you care about, and small enough to resolve hull curvature. Tune OpenSCAD's $fn up for the sim export (it's fine for the sim export to have 50k+ triangles; decimate in MeshLab only if runs get slow). Capytaine wants the wetted body — but since it can cut the mesh at the waterline itself, just export one closed solid of the whole exterior hull and set the draft via the body's position.

Bonus: the same Capytaine run gives you wave-pressure loads on the hull panels, which are exactly the boundary conditions you can later apply in FEA. That's a clean coupling between your hydro and structural pipelines — no extra software needed.

4. CFD (Optional, Targeted)

OpenFOAM + a wave-generation library (waves2Foam, olaFlow) is the open source standard, and its mesher snappyHexMesh consumes STL directly — again, zero format friction with OpenSCAD. But:

For most design screening, the Capytaine RAO plots — heave/pitch response vs. wave period, with wave height scaling linearly — are your "visualize different wave sizes and periods" answer.

5. Pipeline to FEA — The One Real Conversion Step

The honest catch: OpenSCAD gives you a surface mesh (STL); solid FEA needs a volume mesh. The open-source bridge is gmsh:

STL (watertight, from OpenSCAD)
  → MeshLab (optional: cleanup, decimate)
  → gmsh (.geo script: import surface, remesh, generate 3D tetrahedra)
  → export .inp (Abaqus format)
  → CalculiX (PrePoMax GUI) — apply aluminum, boundary conditions, wave loads
// analysis/fea/mesh.geo (gmsh)
Merge "hull_surfaces.stl";
Surface Loop 1 = Surface{:};
Volume(1) = {1};                       // creates solid from closed shell
Mesh.CharacteristicLengthMin = 0.05;   // meters — from params!
Mesh.CharacteristicLengthMax = 0.30;
Mesh.Algorithm3D = 1;
Mesh 3;
Save "hull_solid.inp";

Solver options, in order of friendliness:

ToolGUIWhy / why not
CalculiX + PrePoMaxPrePoMax (excellent, free, Windows/Linux)Abaqus-compatible .inp from gmsh loads directly. Best starting point. Open source (CalculiX) + free GUI.
Code_Aster (in Salome-Meca)Salome-MecaVery powerful, fully open source, French nuclear-grade. Steeper learning curve; documentation largely in French.
Elmer**ElmerGUIFully open source, general multiphysics, decent for linear statics.
Tip: for a thin-plated structure, consider exporting the shell surfaces (outer skin + bulkheads as thin extruded surfaces in OpenSCAD) and running shell elements — gmsh can mesh 2D surfaces directly into shell .inp files, skipping the volume-mesh step entirely. This often matches how a real aluminum hull is actually analyzed.

6. Scaled Structural Testing in Plastic: The 1:50 Question

This is the best question in your list, because the numbers actually work out surprisingly well — with caveats.

6.1 The physics: you can only satisfy one similitude at a time

Wave loading is gravity-driven, so hydrodynamics follow Froude scaling (time/velocity scale as √λ). Structural response follows Cauchy scaling: the ratio of inertial load to elastic stiffness must match, which requires:

Ca = ρ·v²/E  must be equal in model and prototype
→  E_model = E_aluminum / 50 × (ρ_model / ρ_aluminum)

With E_aluminum ≈ 69 GPa, ρ = 2700:
   E_model ≈ 69/50 × (1200/2700) ≈ 0.6 GPa
   (or ≈ 1.4 GPa if you ignore the density correction)
MaterialE (GPa)Verdict for 1:50 Cauchy model of aluminum
Target0.6 – 1.4
SLA resin (cured)1 – 3✅ Best match, and isotropic
PETG~2.0✅ Close
ABS~2.2✅ Close
PLA~3.5⚠️ ~2–5× too stiff (results conservative in deflection)

So yes — an ordinary plastic 1:50 model is in the right elastic ballpark for aluminum. That's a lucky coincidence worth exploiting. If similitude holds, then at corresponding points: strain is equal in model and prototype, deflection scales 1/λ, and if the model yields or cracks at load X, the full aluminum structure is in trouble at the Froude-scaled equivalent load.

6.2 The rules that make it actually useful

  1. Use SLA (resin) printing, not FDM, if possible. FDM parts are orthotropic — layer adhesion strength is often 50% of in-plane strength, and it varies with print orientation. That single fact destroys quantitative similitude. SLA resin is nearly isotropic. If you must use FDM: print solid (or 100% verified infill), orient all structural parts the same way relative to layers, and treat results as qualitative only.
  2. Scale the wave, not the load path. Run the structural model in the same wave tank conditions as the Froude model test — then the Froude/Cauchy combination above is automatically consistent. Don't apply artificial point loads "to make it break"; that breaks similitude.
  3. Calibrate against FEA first. Run your CalculiX model at model scale with plastic properties, predict where/when the model deforms or fails, then test the print. If FEA predicts the plastic model correctly, you've validated your FEA pipeline — and then you trust the FEA on the full-scale aluminum model. This cross-validation is the real payoff of the plastic structural model, more than the model's own numbers.
  4. Expect qualitative results. Absolute stresses are not transferable without the full Cauchy correction; failure modes, crack locations, buckling patterns, and "does the deck pant in waves" are.
  5. Watch for distortions: creep ( plastics creep at low stress; aluminum doesn't) and strain-rate sensitivity mean slow-loading tests can mislead. Wave-frequency cyclic loading is actually the favorable regime.
Bottom line on #4: a plastic 1:50 model can give useful qualitative and order-of-magnitude insight into aluminum behavior, especially as a validation tool for your FEA — but use SLA or carefully-printed FDM, run it under correctly Froude-scaled waves, and never trust it for absolute strength numbers. The printed model you'd build for hydrodynamic testing anyway can do double duty.

7. What the Whole Pipeline Looks Like

                    params.scad  (single source of truth, meters, full scale)
                          │
                 assembly.scad (fit/position ground truth)
                          │
        ┌─────────────┬────┴──────────┬────────────────┐
        ▼             ▼               ▼                ▼
  export_print    export_sim     export_fea        export_sim
  (1:50, mm)      (1:1, STL)     (shells/solid)    (1:1, STL)
        │             │               │                │
   PrusaSlicer    Capytaine      gmsh → .inp      OpenFOAM
   Froude model   (BEM: RAOs,    → CalculiX/      (targeted CFD:
   in waves        wave loads)    Code_Aster       slamming, viscous)
        │             │               │
        └────── physical test ─── validates ──┐
                                               ▼
                        FEA validated at model scale →
                        FEA trusted at full scale (aluminum)
                                               │
                                     naval architect hands off:
                                     params.scad + STEP (via FreeCAD)

8. Alternatives & Other Tools Worth Knowing

ToolRoleComment
FreeCAD (OpenSCAD workbench).scad → solid → STEPThe bridge when the naval architect or a fabricator asks for STEP. Conversion of complex CSG is imperfect; test early.
CadQuery / Build123D (Python)Alternative parametric coreExports true STEP/BREP solids, which feed FEA without the mesh conversion step. Consider migrating here if gmsh pain becomes excessive — but it means rebuilding your library. OpenSCAD is fine for now.
meshioFormat swiss-army knifeSTL ↔ Nemoh ↔ .inp ↔ .med etc. in one Python call.
MeshLabRepair, decimate, inspectDecimate high-$fn meshes for Capytaine speed.
Python + Jupyter + matplotlibResults analysisCapytaine results are xarray datasets — plot RAO families, compare variants, save every design iteration's curves.
ParaviewCFD/FEA results visualizationThe standard open-source post-processor.
git + GitHub/GitLabEverythingCommit .scad and analysis scripts; don't commit big result files. Every design variant is reproducible from history.

A note on honesty about the toolchain

The one structural weakness of a pure-OpenSCAD pipeline is that STL is a faceted approximation, and FEA of stress concentrations at faceted edges is meaningless at the local level. For screening-level global structure ("does the spar-to-hull joint have 3× margin against design wave loads?") it's fine. Fine detail (weld details, penetrations, ring stiffener sizing) is exactly what your naval architect will do in a real CAD/FEA package later — and this pipeline's job is to hand them a design where those details are worth refining.

9. Suggested Working Order

  1. Refactor existing .scad files into the params/parts/assembly structure above; commit to git.
  2. Get the Capytaine pipeline running on your current design — it's the highest information-per-hour tool you can add, and it's a weekend's work.
  3. Set up the printed Froude model export with parametric joinery; keep ballasting (mass, CG, inertia) as explicit parameters.
  4. Build the gmsh → CalculiX FEA pipeline on a simple test case (e.g., a plate + stiffener) before trying the whole hull.
  5. Only then: plastic structural model, run as FEA validation (§6).
  6. OpenFOAM: last, and only for 2–3 targeted questions on the best design.
``` --- **Key takeaways from the document:** 1. **Single ground truth: yes.** Structure it as `params.scad` (full-scale meters, the only place numbers live) + geometry modules + an assembly file that defines fit, with export "driver" files that apply scaling per consumer. Regenerate everything via OpenSCAD's CLI after each parameter change. 2. **Capytaine is your best wave tool** — it eats OpenSCAD's watertight STLs directly via meshio, runs in seconds, and gives RAOs vs. wave period/height (your "visualize different wave sizes" requirement). Save OpenFOAM CFD for a few targeted confirmation runs. 3. **FEA needs one conversion step** (STL → gmsh → CalculiX/Code_Aster), with shell elements on your plated structure as a shortcut that skips volume meshing entirely. 4. **The 1:50 plastic model is a pleasant surprise**: Cauchy scaling puts the ideal model modulus at 0.6–1.4 GPa, right in ordinary-plastic territory — so SLA-printed (isotropic) models under Froude-scaled waves give qualitatively meaningful aluminum insight, especially as a way to *validate your FEA at model scale* rather than trusting the plastic numbers directly.