abaqus-topology-optimization

Complete workflow for topology optimization using Tosca. Use to minimize weight while maintaining stiffness. Requires full Abaqus license (not Learning Edition).

SKILL.md

GitHub

Abaqus Topology Optimization Workflow

Two workflow paths for topology optimization:

  1. CAE API path — Use TopologyTask, DesignResponse, ObjectiveFunction, and OptimizationProcess entirely within Abaqus CAE. Works for Abaqus built-in optimization.
  2. Tosca CLI hybrid path — CAE API builds the FE model, then Tosca CLI runs the optimization via a hand-written .par file. Required when using Tosca-specific features.

When to Use This Skill

Triggers: topology optimization, minimize weight, lightweight design, organic structure, generative design, where to remove material, material efficiency, design for additive, stress-constrained optimization

USE for: Minimize weight subject to stress constraint, maximize stiffness at target volume fraction, generate organic load-carrying structures

Do NOT use for: Shape optimization (surface only) -> /abaqus-shape-optimization, Learning Edition users -> Tosca requires full license

CAE API Path (Abaqus Built-In Optimization)

The CAE optimization API works correctly when used with the right tuple format:

# TopologyTask defines design space
model.TopologyTask(name='Task', region=model.rootAssembly.sets['DesignSpace'])

# DesignResponse — 4 members: name, region, type, stepName
model.optimizationTasks['Task'].DesignResponse(
    name='DR_Volume', region=MODEL, response=VOLUME)
model.optimizationTasks['Task'].DesignResponse(
    name='DR_StrainEnergy', region=MODEL, response=STRAIN_ENERGY)

# ObjectiveFunction — objectives is a tuple of 4-tuples:
#   (suppress, designResponse, weight, referenceValue)
model.optimizationTasks['Task'].ObjectiveFunction(
    name='ObjFunc',
    objectives=((OFF, 'DR_StrainEnergy', 1.0, 0.0),))  # 4-tuple!

# OptimizationProcess
mdb.OptimizationProcess(name='OptProcess', model='Model-1',
                         task='Task', prototypeJob='Job-1')
mdb.optimizationProcesses['OptProcess'].submit()

CRITICAL PITFALL: The objectives parameter must use 4-tuples (suppress, designResponse, weight, referenceValue). Passing a 5-tuple (e.g., with a trailing empty string) corrupts internal C++ state and causes segfaults or KeyErrors.

Note: The CAE API generates .par files for Abaqus's own optimization system, not for standalone Tosca. For Tosca CLI usage, .par files must be hand-written (see Tosca CLI path below).

Tosca CLI Hybrid Path

For Tosca-specific features or when running Tosca standalone, use the hybrid pipeline (proven in experiments 7-10): CAE builds the model, writeInput() or noPartsInputFile=ON generates a flat .inp, a hand-written .par defines the optimization, and tosca optimize runs it.

Important: License Required

Topology optimization requires a full Abaqus license with Tosca module. NOT available in Learning Edition.

Prerequisites

  1. Working static analysis model (geometry, material, mesh, BCs, loads)
  2. Design space defined with frozen regions partitioned via datum planes
  3. Clear objective (min volume with stress constraint, or min compliance with volume constraint)
  4. Known load cases and boundary conditions
  5. Element type selection: C3D10 for stress-constrained, C3D8R for compliance

Workflow Paths Overview

Path A: CAE API (Abaqus built-in optimization)

CAE API (noGUI)
----------------
1. Build FE model
2. TopologyTask + DesignResponse + ObjectiveFunction (4-tuple!)
3. OptimizationProcess.submit()
4. Post-process ODB

Path B: Tosca CLI Hybrid Pipeline

CAE API (noGUI)          .inp generation                Tosca CLI
----------------         ----------------------         ---------
1. Build FE model   -->  3. noPartsInputFile=ON    --> 5. tosca optimize
2. writeInput()          4. Generate .par file      --> 6. Post-process

Note: Path B previously required manual .inp flattening (removing *Part/*Instance/*Assembly wrappers). This is no longer necessary — set noPartsInputFile=ON before writeInput() and Abaqus produces a flat .inp directly. Alternatively, Tosca auto-flattens hierarchical .inp during its data check (but group names get prefixed with <assembly>_<instance>_).

Workflow Steps

Phase 1: Build FE Model in CAE (Steps 1-5 of script)

  1. Geometry -- Create design space envelope
  2. Pin holes -- Cut holes for load application points
  3. Partition frozen regions -- Use DatumPlaneByPrincipalPlane to split cells at boundaries between frozen blocks and design space. This creates separate cells that can be assigned to element sets.
  4. Create part-level sets -- FrozenUpper, FrozenLowerLeft, etc. using getByBoundingBox() on the partitioned cells. Sets MUST be on the part (not instance) when using dependent=ON.
  5. Material + Section -- Elastic properties AND density (required for volume response)
  6. Mesh -- TET/FREE with appropriate element type:
    • C3D10 (quadratic tet) for stress-constrained optimization -- avoids shear locking
    • C3D8R (hex) for compliance optimization -- faster, no stress accuracy needed
    • Mesh size 2-5mm typical. Filter radius = 2-3x mesh size.
  7. Assembly + Step -- dependent=ON instance, StaticStep, field outputs including ENER
  8. RP coupling for pin loads -- Reference points coupled to cylindrical hole surfaces via KINEMATIC coupling, loads/BCs applied to RPs
  9. Generate flat .inp -- Set noPartsInputFile=ON then call writeInput()

Phase 2: Generate Flat .inp for Tosca

Tosca requires a flat .inp without *Part/*Instance/*Assembly hierarchy. The simplest approach:

mdb.models['Model-1'].setValues(noPartsInputFile=ON)
mdb.jobs[job_name].writeInput()

This produces a flat .inp directly — no manual flattening needed.

Note on group names: When Tosca auto-flattens a hierarchical .inp, set names get prefixed with <assembly>_<instance>_ (e.g., ASSEMBLY_PART-1_FrozenUpper). Using noPartsInputFile=ON avoids this prefix issue.

Legacy approach (manual flattening): If noPartsInputFile=ON is not available, the .inp can be flattened manually by removing wrapper keywords, stripping instance= qualifiers, and renumbering assembly-level RP nodes. See references/common-patterns.md for the legacy flattening code.

Phase 3: Generate .par File

The .par file defines the Tosca optimization in its native format:

  • FEM_INPUT -- points to the flattened .inp
  • DV_TOPO -- design variables on ALL_ELEMENTS
  • GROUP_DEF + DVCON_TOPO -- frozen region groups with CHECK_TYPE = FROZEN
  • DRESP -- design responses (VOLUME, STRAIN_ENERGY, SIG_SENS_MISES)
  • OBJ_FUNC -- objective (MIN volume or MIN strain energy)
  • CONSTRAINT -- constraint (stress <= limit or volume <= fraction)
  • OPTIMIZE -- ties DV, objective, constraints, strategy together
  • OPT_PARAM -- filter radius
  • STOP -- max iterations
  • SMOOTH -- STL export at iso-surface threshold

See references/common-patterns.md for complete .par templates.

Phase 4: Run Tosca CLI

tosca optimize -j job_name -p file.par -s abaqus -scpus 4

Or via subprocess from within the CAE script (see exp10_optimize.py).

Phase 5: Post-Process

  • Tosca creates job_name/ directory with per-cycle results
  • SAVE.inp/<cycle>/ contains the last-cycle .inp with tosca_distribution.inp (per-element densities)
  • Run abaqus job=Optimized input=<last_cycle>.inp to generate ODB for stress visualization
  • STL exported automatically if SMOOTH block is in .par

Key Decisions

Goal Objective Constraint Element
Stiffest at weight Min compliance (STRAIN_ENERGY) Volume <= X% (REL) C3D8R
Lightest under stress Min VOLUME Stress <= Y MPa (ABS) C3D10
Avoid resonance Max frequency Volume <= X% C3D10

Volume Fraction (for compliance optimization)

Fraction Use Case
20-30% Aggressive (aerospace)
30-40% Balanced (general)
40-50% Conservative (safety-critical)

Filter Radius

Multiplier Effect
2x mesh size Minimum (some checkerboard risk)
3x mesh size Recommended default
4-5x mesh size Thicker members, smoother topology

What to Ask User

Critical:

  • Design space: "What is the bounding volume where material can exist?"
  • Frozen regions: "Which areas must remain solid? (BC/load attachment)"
  • Objective: "Minimize weight (stress-constrained) or maximize stiffness (volume-constrained)?"
  • Loads and BCs: "What loads and supports act on the structure?"

With Defaults:

  • Stress limit: Material yield / safety factor (if stress-constrained)
  • Volume fraction: 30% (if compliance optimization)
  • Mesh size: 3mm (adjust for geometry scale)
  • Filter radius: 3x mesh size
  • Max iterations: 20-50 (more for stress-constrained)
  • Element type: C3D10 for stress, C3D8R for compliance

Validation

Stage Check
Base model writeInput() succeeds, .inp file has correct sets
Flat .inp noPartsInputFile=ON produces flat .inp without *Part/*Instance/*Assembly wrappers
.par file FEM_INPUT.FILE points to flat .inp, frozen groups reference correct set names
Tosca run Exit code 0, iterations decreasing objective
Final design Load path intact, no floating regions, STL exported

Troubleshooting

See references/troubleshooting.md for detailed solutions. Key issues:

Issue Solution
CAE API segfault Check ObjectiveFunction tuple format — must be 4-tuple, not 5-tuple
Tosca "cannot read .inp" Use noPartsInputFile=ON before writeInput() for flat .inp
RP node collision Renumber assembly RP nodes by adding max_mesh_node_id offset
Stress singularity at pins Use RP coupling (distributes load), exclude loaded nodes from stress constraint
Checkerboard pattern Increase filter radius to 3-5x mesh size
C3D4 shear locking Use C3D10 (quadratic tet) for stress accuracy

Code Patterns

For API syntax and code examples, see:

  • references/common-patterns.md -- Real working code from experiments 7-10
  • references/workflow-checklist.md -- Step-by-step checklist
  • references/troubleshooting.md -- Known issues and solutions

Related Skills

  • /abaqus-optimization -- Base optimization concepts (objective, constraint, design response)
  • /abaqus-static-analysis -- Required before optimization
  • /abaqus-geometry -- Design space creation and partitioning
  • /abaqus-mesh -- Element type selection and mesh quality
  • /abaqus-export -- Export optimized geometry