Back to all questions

How do I define constraints for my material optimization?

Material Domains
constraints
validation
feasibility

Constraints ensure that the optimizer only proposes physically valid and feasible compositions. MatCraft supports several constraint types.

Sum Constraints

The most common constraint in materials science — component fractions must sum to a fixed value:

yaml
constraints:
  - type: sum_equals
    components: [nickel, manganese, cobalt]
    value: 1.0
    tolerance: 0.001  # Allow 0.1% deviation

  - type: sum_lte
    components: [filler_a, filler_b, filler_c]
    value: 0.4
    description: "Total filler loading must not exceed 40%"

Ratio Constraints

Specify that the ratio between two parameters must fall within a range:

yaml
constraints:
  - type: ratio_between
    numerator: nickel
    denominator: cobalt
    bounds: [2.0, 10.0]
    description: "Ni:Co ratio must be between 2:1 and 10:1"

Inequality Constraints

General linear or nonlinear inequality constraints:

yaml
constraints:
  - type: custom
    expression: "temperature * pressure <= 50000"
    description: "Equipment safety limit"

  - type: custom
    expression: "polymer_concentration >= 2 * additive_concentration"
    description: "Polymer must be at least 2x the additive"

Categorical Constraints

Conditional constraints that depend on categorical parameter values:

yaml
constraints:
  - type: conditional
    condition: "solvent == 'DMSO'"
    constraint:
      type: custom
      expression: "temperature <= 189"
      description: "DMSO boiling point limit"

How Constraints Are Enforced

MatCraft enforces constraints at two levels:

1. Repair Operator (During Optimization)

When CMA-ES generates a candidate that violates a constraint, a repair operator projects it back to the feasible region:

  • Sum constraints: Components are rescaled proportionally to satisfy the sum.
  • Bound constraints: Values are clamped to bounds.
  • Custom constraints: Candidates are rejected and resampled.

2. Validation (During Data Import)

When importing experimental data, constraint violations are reported as warnings but data is not rejected. Real measurements may legitimately deviate from target constraints due to experimental error.

Common Patterns

Composition Simplex

For materials where all components must sum to exactly 1.0:

yaml
constraints:
  - type: sum_equals
    components: [comp_a, comp_b, comp_c, comp_d]
    value: 1.0

MatCraft uses a simplex projection to handle this efficiently — internally reducing the dimensionality by one.

Nested Constraints

yaml
constraints:
  - type: sum_equals
    components: [ni, mn, co]
    value: 1.0
  - type: custom
    expression: "ni >= 0.33"
    description: "Minimum Ni content for high-energy cathode"
  - type: custom
    expression: "co <= 0.2"
    description: "Cap cobalt for cost reduction"

Debugging Constraints

Use the CLI to check if your constraint set is feasible:

bash
materia config check-constraints my_material.yaml --samples 10000

This generates 10,000 random compositions and reports what fraction satisfy all constraints. If the feasible fraction is below 1%, your constraints may be too tight.

Related Questions