You drop a porous zone — a radiator, a heat-exchanger core, a filter — into a domain, and the two ways you measure its pressure drop disagree wildly. ParaView shows a few kPa front-to-back; your surfaceFieldValue function objects report about 1 Pa. The reflex is to assume one of them is broken — but usually neither is. They are measuring different things, on different faces. This guide separates the two effects, shows why the function objects collapse to ~1 Pa, and gives the setup that makes both pictures agree.
There are two pressure signals around a porous block, and they are not the same number:
A point probe hovered "just in front" of the block reads the second one. The first one only shows up cleanly when the flow is actually forced through the zone. Sort out which you are after before trusting either tool.
This is the usual reason the function objects collapse to ~1 Pa. If radiatorInlet and radiatorOutlet came from a topoSet plane or box, they very likely captured faces out in the freestream on either side of the block, not just the radiator footprint. Average a face that is mostly freestream and you get near-atmospheric on both sides:
// run log — both sides read essentially atmospheric → Δp ≈ 1 Pa
areaAverage(radiatorInlet) of p = 101324.747254
areaAverage(radiatorOutlet) of p = 101323.533020
The test: write the faceZones out and look at them. They are almost certainly a full cross-section, not the porous frontal area:
foamToVTK -faceZones '(radiatorInlet radiatorOutlet)' -latestTime
The fix: define the measurement faces from the porous cellZone's own interface, not a plane that runs across the whole domain. The faces that bound the cellZone are exactly the radiator front and back; a plane cut is not.
A common follow-up guess is that the faceZone normals are flipped. For a scalar like p that does not matter: areaAverage weights the field by the face-area magnitude |Sf|, so the result is the same whichever way the normal points.
areaAverage(p) = Σ(p · |Sf|) / Σ|Sf| // uses magnitude → orientation-independent
Orientation only changes flux-type operations — areaIntegrate of phi, a signed flux sum, a mass-flow tally. So if your two faceZones report nearly equal pressures, chase their location and area (§2), not their normals.
With no ducting, the block behaves like any obstacle in crossflow. The point you hover in front sits in the local stagnation region, so it reads the dynamic head of the decelerating flow:
½ · ρ · U² ≈ 0.5 · 1.2 · 56.5² ≈ 1915 Pa
So "103000 in front, 100000 behind" — about 3 kPa — is dominated by that stagnation-plus-wake signature, not by the resistance the medium imposes on the through-flow. ParaView is not lying; it is just answering the bluff-body question, not the radiator-Δp question.
Here is the physical part the function objects may be reporting correctly. With nothing forcing the flow through it, most of the air goes around the porous block — the path of least resistance — and only a little goes through. Little through-flow means a genuinely small static pressure drop across the through-path. So a ~1 Pa Δp on properly placed faces can be the real answer for an unducted zone; it just isn't the radiator number you were after.
The test: measure the actual mass flow through each face. If almost nothing is passing through, bypass is confirmed:
radInletFlow
{
type surfaceFieldValue;
libs (fieldFunctionObjects);
regionType faceZone;
name radiatorInlet;
operation sum; // net flux through the face
fields (phi);
}
Put the four fixes together:
radInletPbar
{
type surfaceFieldValue;
libs (fieldFunctionObjects);
regionType faceZone;
name radiatorInlet;
operation weightedAverage; // mass/flux-weighted, not plain areaAverage
weightField phi;
fields (p);
}
Then sanity-check the resistance itself: confirm your DarcyForchheimer d and f coefficients actually give the Δp you expect at 56.5 m/s with a quick 1-D hand calculation. If the coefficients are an order out, no amount of post-processing will produce the right drop.
foamToVTK -faceZones — are they the porous footprint or a full cross-section?areaAverage is orientation-independent.sum of phi) — is the flow bypassing an unducted zone?½ρU² stagnation, not porous loss.p.They measure different things. The function objects area-average p over faceZones that — if cut from a topoSet plane — often include freestream, diluting the result to ~1 Pa. The ParaView point in front reads stagnation (½ρU²), not porous loss. Fix the faces to the cellZone interface and flux-average, and they agree.
No. A scalar areaAverage weights by |Sf|, so a flipped normal is irrelevant. Orientation only matters for flux operations (areaIntegrate of phi, signed sums).
Without ducting most of the air bypasses the block, so little flows through and the through-path Δp is genuinely small. Enclose the zone in ducting to force the flow through it.
Duct the zone, take the inlet/outlet faces from the porous cellZone interface, use operation weightedAverage with weightField phi (or compare total pressures), and confirm equal, non-trivial mass flow through both faces.
Mostly no — it is the dynamic head of the stagnating flow (½ρU² ≈ 1.9 kPa at 56.5 m/s). The resistance through the medium is separate and, unducted, much smaller.
CFDpilot is an AI agent for OpenFOAM — it reads your case from the terminal, checks where your faceZones actually sit, whether the flow is bypassing your porous zone, and whether your DarcyForchheimer coefficients give the Δp you intended.
See how CFDpilot works →