What you can do
You can find out how much of your material's performance depends on direction before you make any of it. One field on a fiber recipe controls how tightly the fibers align. Sweep that field, measure the same property along two axes, and the anisotropy falls out of the comparison.
- orientationSpreadDeg sets how far each fiber may tilt off its nominal axis. 0° is perfectly aligned, 90° is free to point anywhere.
- POST /api/v1/conductivity takes a direction, so one stored structure answers for z and for x without being rebuilt.
- Volume fraction, fiber size and seed all stay where they are, so nothing else can explain a difference.
- POST /api/v1/two-point-correlation returns S₂ separately along x, y and z, which shows the geometry behind the numbers.
Why it matters
Alignment is increasingly how thermal performance gets bought, instead of more filler. Filler is expensive, and it makes a compound harder to process. Getting the same conduction out of oriented fibers is the better trade when it works.
The cost of that trade is that one measurement stops describing the material. A number quoted without a direction is only safe if the structure is isotropic, and an oriented one is not. What follows is a cheap way to find out which case you are in.
One field, five values
The starting point is the fiber-packing example from GET /api/v1/examples, raised to 20 % fibers on a 64³ grid at 1 µm per voxel. Fibers are 4 µm across and 28 µm long. The nominal orientation is z in every case, and only orientationSpreadDeg changes.

The generator hit its target every time. Averaged over four seeds at each spread, solid fraction came back between 20.04 % and 20.07 %. The packing really is holding the loading fixed while the orientation changes.
One direction conducts, the other returns nothing
Below 45° of spread, the transverse directions are not merely low. They are zero.
Conductivity was measured along z and across x by the graph-network method. The fiber phase carried the 30 W/mK alumina preset from GET /api/v1/materials.
| orientationSpreadDeg | Solid | Along z, four seeds (W/mK) | Across x, four seeds (W/mK) |
|---|---|---|---|
| 0° | 20.05 % | 3.82, 6.06, 7.09, 14.65 | 0, 0, 0, 0 |
| 15° | 20.07 % | 10.60, 11.89, 12.61, 12.70 | 0, 0, 0, 0 |
| 30° | 20.04 % | 5.29, 6.86, 8.43, 10.09 | 0, 0, 0, 0 |
| 45° | 20.05 % | 0, 4.61, 8.09, 8.85 | 0, 0, 0.04, 3.44 |
| 90° | 20.04 % | 0, 0.23, 3.60, 8.99 | 0, 5.17, 6.47, 7.16 |
A zero here means the solver found no connected fiber path spanning that axis. It is not a rounding artefact or a failed call. Every request returned 200, and the y direction returned zero in the same twelve cases that x did.
That is the practical warning. At this loading, a single-axis measurement does not overstate the transverse performance by some margin you could correct for. It reports a material that conducts when the real answer is a material that does not.
The geometry agrees, and one number hides it
The two-point correlation confirms that the structure is anisotropic, using no solver at all. S₂ measures how likely two points a given distance apart are both in the fiber phase. It comes back per axis, so the decay along z can be compared with the decay across x in a single response.
Aligned fibers stay correlated along z for 11.65 µm and across x for 1.42 µm. The transverse figure is set by the fiber diameter and it hardly moves as the spread opens up. By 90° the two axes agree at roughly 1.6 µm, which is what isotropic looks like.
The scalar in the same response would have told you almost nothing. correlationLengthVoxels went from 2.92 to 2.11 across the whole sweep, a change of about a quarter. The along-z figure it summarises fell by a factor of seven. The per-axis arrays are in the payload, so read those.
Trust the zero, not the magnitude
The conducting value is noisy and the zero is not. Look at the 0° row of the table: the four seeds are spread by a factor of 3.8 along z. Nothing separates them but where the packer happened to put the fibers.
Across x, the same four seeds gave zero every time, and so did the four seeds at 15° and the four at 30°. Whether a spanning path exists is a robust property of the orientation. How well it conducts, once it exists, is a property of the particular structure you generated.
Where alignment stops helping
Past 45° the z direction starts failing too. One seed at 45° returned zero along z while returning 3.44 W/mK across x. For that structure the conducting axis had swapped over.
At 90° one seed returned zero in all three directions. Spreading the fibers out does not reliably trade z performance for x performance, and it can lose both.
The reason is that 20 % fiber is close to the threshold where this network percolates at all. Alignment is what pushes it over that threshold, and it can only do so along one axis. Read the table as a statement about a marginal loading rather than about fibers in general.
Raising the loading to test that reading did not work here. At 35 % the generator refused the 30° case with 422 generation_target_unattainable, after placing 91,038 of 91,750 target voxels. The 45° and 90° cases timed out. Getting a finite ratio instead of a zero needs a higher overlapPercent or thinner fibers.
Running it on your own recipe
Three requests cover one point of the sweep. Generate once, then send the same structureId to the analysis with the direction changed.
POST /api/v1/generate -> structureId
{
"recipe": {
"generatorType": "fiberPacking",
"grid": { "nx": 64, "ny": 64, "nz": 64, "voxelSizeUm": 1 },
"fillerConfigs": [{
"type": "fiber", "radius": 2, "length": 28, "materialId": 1,
"volumeFraction": 20,
"orientation": "z",
"orientationSpreadDeg": 0
}],
"randomness": { "seed": 20260911 }
},
"storeStructure": true
}
POST /api/v1/conductivity -- once with "z", once with "x"
{
"structureId": "<id>",
"request": {
"version": "phase0.v1",
"analysisType": "effectiveConductivity",
"inputs": { "grid": { "nx": 64, "ny": 64, "nz": 64, "voxelSizeUm": 1 },
"materialProperties": { "1": 30 } },
"params": { "direction": "z", "method": "graph-network" },
"requestedOutputs": ["summary"]
}
}
Two details will save you time. orientationSpreadDeg only applies when orientation names an axis, so setting it alongside "random" does nothing. The field is also carried in several places in a full recipe, including geometryParams.fibers and distributionRules.fiberDistribution. A recipe taken from GET /api/v1/examples needs all of them updated together.
A stored structure is also not guaranteed to be visible to the request that follows it. Of 30 analysis calls in one batch here, 22 came back 404 structure_not_found on an id that had just been created successfully. Generation is deterministic given a seed, so the fix is to re-issue the generate and retry, which rebuilds the identical structure.
The sweep is cheap. Across the structures built for this sweep, a generate took between 131 and 369 ms. A conductivity call took between 306 and 784 ms, measured from outside. Five spreads in two directions is under a minute of wall clock.
What this does not settle
This is one generator, one grid size, one loading and four seeds. The zeros are clean here because the system sits near its percolation threshold. A well-filled compound would show a finite ratio rather than an infinite one. The direction of the effect should carry further than the numbers do.
The graph-network method is also a reduced model, not a full grid solve. It answers about the connectivity of the conducting phase, which is exactly the question here. It is not the same calculation as a direct solve on all 262,144 voxels. Only the fiber phase was given a conductivity in these requests.