PKR Core
Use Case 8 min read

Five plain-English specs, and what the structures actually measured

Five plain-English material specs went into PKR Core's parameter assist. The parameters that came back were built into structures and measured, all in the same session. Every one returned a valid recipe in under half a second. Not one of them matched the numbers in the sentence, and three of the five produced the identical box.

  • Build Structures
  • Analyze Properties
  • Automate Workflows
Two cross sections of the same recipe asked for 40 % loading: sparse on the left where the loading stayed on the top-level field, and four times as full on the right where it was written onto the filler entry.

What you can do

You can find out what a described structure is really made of before you rely on it. Describing a material in a sentence is quick. Checking that the sentence survived the trip into parameters used to need a separate tool.

  • POST /api/v1/ai/parameter-assist turns a sentence into a full parameter set.
  • The response carries paramReasons, which names every field it set from your words. Anything missing from that list is a default.
  • POST /api/v1/generate builds the parameters into a structure and stores it.
  • POST /api/v1/metrics reads the solid fraction, porosity and surface area back off that structure.
  • POST /api/v1/chord-length measures the solid along x, y and z, which is how you check a shape or an alignment.

Three requests take you from a sentence to a measured number. The assist answered in 186 to 397 ms across the five specs, and building each 64³ box took 304 to 638 ms.

Why it matters

Writing a spec in words and getting candidate parameters back is a route a lot of tools now offer. What is usually left to the user is the other half: deciding whether the parameters actually meet the spec.

That check is only cheap if building and measuring live next to the parameters. Here they do. The run below is what happens when you close that loop instead of trusting the first answer.

Five sentences, five structures

Each sentence was sent on its own, with no prior parameters and no conversation history. These are the exact strings.

  • Spheres about 4 µm across, packed to 40 % solid, in a 64 µm cube.
  • A fiber network at 15 % loading, fiber radius 2 µm, mostly aligned along z.
  • An open foam with about 70 % porosity at 5 µm per voxel.
  • Electrode-like: 35 % active particles with a one-voxel binder shell.
  • A bimodal packing: half the solid in 5 µm spheres, half in 2 µm.

All five returned 200 and a complete parameter set. All five built without error. Nothing in the responses or the status codes suggested a problem.

The generator choice was right every time. Spheres and the electrode and the bimodal packing became particlePacking, the fiber network became fiberPacking, and the foam became foamLike.

Almost nothing else was taken from the sentences. The paramReasons field listed a single entry for four of the five specs, and that entry was the generator type. The fiber spec was the only one with two, because it also picked up the radius.

What was asked for, and what was there

Every spec lost at least one of its numbers. The table puts the sentence, the parameters and the measurement side by side.

Asked forCame backMeasured on the built structure
40 % solid, spheres 4 µm across, 64 µm boxloading 10 %, sphere radius 4 µm, 64³ at 1 µm per voxel10.1 % solid, mean component diameter 7.0 µm, 64 µm box
15 % loading, fiber radius 2 µm, mostly aligned along zloading 10 %, fiber radius 2 µm, orientation random10.0 % solid, solid chords 3.80 / 3.70 / 3.74 µm along x / y / z
70 % porosity, 5 µm per voxeltarget solid fraction 10 %, 1 µm per voxel78.1 % porosity, 1 µm per voxel
35 % active particles, one-voxel binder shellloading 10 %, binder fraction 0 %10.1 % solid, one material in the box and no binder
half the solid in 5 µm spheres, half in 2 µmone sphere entry at radius 4 µm10.1 % solid, a single particle size

Two numbers landed by accident rather than by parsing. The 64 µm box in the first spec is what 64³ voxels at the default 1 µm happens to give. The 4 µm radius is the default, and the sentence asked for 4 µm across, which is half that.

Three of the five specs produced the same structure. Spheres, electrode and bimodal all came back at 26,423 solid voxels, 113 connected components and the same specific surface area. Three different materials, described three different ways, and one box.

The errors field does not point at the gap

Three of the five responses carried an errors entry, and none of them named the field that went missing. They named a word lifted out of the sentence.

  • The sphere spec reported packed: Parameter "packed" is unsupported or cannot be edited.
  • The electrode spec reported the same thing for like.
  • The bimodal spec reported it for A bimodal packing.

The loading was the thing that went missing in all three, and the errors field never mentioned it. So read paramReasons instead. It is a positive list of what was set, and comparing it against the numbers in your sentence takes one glance.

The reply field is a prose summary in Japanese, written for the app's chat panel. It quotes the current grid, loading and seed, so it does carry the answer. The machine-readable version is params and paramReasons.

Naming the fields moves most of them

The assist reads a fixed vocabulary, so restating the same specs in that vocabulary works. The sphere spec rewritten as particle packing, volume fraction 40, radius 2, overlap 15, 64x64x64 came back with seven fields set instead of one.

Two of the five specs still could not be expressed. Both failures are worth knowing before you plan around this endpoint.

  • Fiber orientation is not editable here. Sending orientation = z returns Parameter "orientation" is unsupported or cannot be edited.
  • A second filler size needs the whole fillerConfigs array as JSON, and the parser stops the value at the first comma. The array comes back as a JSON parse error.
  • Binder did land once it was named: binder volume fraction 8, binder shell thickness: 1 produced a box with two materials in it.

The loading is written in two places, and only one of them is packed

Asking for volume fraction 40 is not enough, and the measurement is what shows it. The parameters came back with a top-level volumeFraction of 40 and a filler entry still at 10. The structure built from them measured 10.0 % solid.

The generator packs to the loading on the filler entry. Copy 40 onto that entry and the same recipe measures 40.0 % solid, which is 0.002 percentage points off the target.

Two z cross sections side by side, each 64 by 64 voxels with blue solid on a green background. The left panel is sparse, with scattered small clusters. The right panel is roughly four times as full, with solid covering much of the frame.
The same recipe, the same seed, and the same requested 40 % loading. On the left the loading was left where the assist put it. On the right it was also written onto the filler entry.

Nothing in the response flags this. Both recipes validate, both generate, and the only difference visible to the caller is the number that comes back from metrics.

The foam generator behaves differently again. Its target solid fraction is not a value you can read back: 10 % measured 21.9 % solid and 30 % measured 48.3 %. For foam, treat the target as a dial and the measurement as the answer.

Checking a word, not a number

"Mostly aligned along z" never reached the structure, and the chord lengths say so. The solid measured 3.80, 3.70 and 3.74 µm along x, y and z. Those are the same number three times.

A measurement that finds nothing only means something if it can find the thing at all. So the same recipe was built again with the fibers actually pointed along z.

Two z cross sections side by side, each 64 by 64 voxels. The left panel shows elongated blue streaks lying at many angles. The right panel shows small compact blue blobs, which are fibers cut end-on.
Same fiber recipe at 15 % loading, cut across z. Random orientation on the left, fibers pointed along z on the right, where they appear as end-on circles.

The aligned build measured 3.16, 3.25 and 30.63 µm along x, y and z. The z chord is more than nine times the cross-fiber ones, so the measurement detects alignment easily when it is there.

That makes the flat result on the first build a real answer rather than a null one. The word was dropped, and a single request found out.

The same sentence answers the same way twice

All five sentences were sent a second time and came back byte for byte identical, including paramReasons and the errors entries. This is a parser, not a sampler.

That matters for how much checking you have to do. A check you run once stays valid for that sentence. Rewording is what changes the answer, not rerunning.

Running the check yourself

Three calls, and the third one is the one that settles it. Ask for the structure to be stored so the measurement can refer to it by id.

POST /api/v1/ai/parameter-assist
{ "message": "A fiber network at 15 % loading, fiber radius 2 µm, mostly aligned along z." }

-> params          the full parameter set, defaults included
-> paramReasons    only the fields your sentence set

POST /api/v1/generate
{ "recipe": <recipe built from params>, "storeStructure": true }

-> structureId

POST /api/v1/metrics
{ "structureId": "structure-..." }

-> structureSummary.statistics.occupancyRatio
-> metrics.porosity
-> metrics.surfaceStats.specificSurfaceArea

Two habits make this quick. Read paramReasons first, because it costs nothing and catches the words that were never heard. Then measure, because that is the only thing that catches a number written into a field nobody packs.

Directional properties need the third call. Use chord-length when you want to know whether a shape or an alignment made it into the voxels.

What this does not settle

This is one session, five sentences and one phrasing of each. A different wording reaches different fields, and the second round of specs proves it. Read the table as five worked examples, not as a measurement of how good the parsing is.

The specs were also written the way a person writes, not the way the field list reads. That is the point of the exercise, but it sets the difficulty. Sentences built from the parameter names land far more of their numbers.

Mean chord length is a coarse alignment test. It separated random from fully aligned fibers by a factor of nine here. A partial alignment, or a spread of a few tens of degrees, would need a finer descriptor.

Try it in PKR Core.

Open PKR Core