PKR Core
Use Case 7 min read

Same fibers, same loading, and one direction reads exactly zero

One fiber recipe at 20 % loading, swept over how tightly the fibers align. Held within 30° of the z axis, twelve structures conducted along z at 3.8 to 14.6 W/mK. Across the fibers, all twelve returned 0. The loading never moved, so the gap is orientation and nothing else.

  • Build Structures
  • Analyze Properties
  • Explore Design Space
Three cross sections of the same fiber recipe at orientation spreads of 0, 30 and 90 degrees, going from near-vertical bars to tilted fibers to scattered blobs at identical volume fraction.

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.

Three cross sections through the same recipe at orientation spreads of 0, 30 and 90 degrees. At 0 degrees the fibers appear as near-vertical bars, at 30 degrees they are tilted and shorter in projection, and at 90 degrees they are scattered blobs with no common direction.
The same recipe at three spreads, sliced on a plane that cuts the fibers lengthwise. All three hold the same amount of fiber. Only the alignment differs.

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.

orientationSpreadDegSolidAlong z, four seeds (W/mK)Across x, four seeds (W/mK)
0°20.05 %3.82, 6.06, 7.09, 14.650, 0, 0, 0
15°20.07 %10.60, 11.89, 12.61, 12.700, 0, 0, 0
30°20.04 %5.29, 6.86, 8.43, 10.090, 0, 0, 0
45°20.05 %0, 4.61, 8.09, 8.850, 0, 0.04, 3.44
90°20.04 %0, 0.23, 3.60, 8.990, 5.17, 6.47, 7.16
Dot plot of effective conductivity against orientation spread. Along z the points scatter between roughly 4 and 15 W per metre kelvin at spreads of 0, 15 and 30 degrees. Across x every point sits on zero at those three spreads, after which both directions scatter between zero and about 7.
Each spread carries four seeds in each direction. The orange points below 45° are not small values plotted near the axis. They are exactly zero.

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.

Line chart of the half-decay length of S₂ against orientation spread. The along-z curve falls steeply from 11.65 to 1.58 micrometres. The across-x curve stays flat near 1.4. A dashed line showing the single correlation length in the response barely moves, from 2.9 to 2.1.
How far apart two fiber points can be and still be correlated, measured along each axis. The dashed line is the one scalar the same response summarises with.

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.

Try it in PKR Core.

Open PKR Core