A qualitative pressure-rake post-processing tool
This project involved creating an algorithm to post-process total pressure data from rakes during track or tunnel testing. The goal was to produce something qualitative that was not necessarily a perfect or numerically accurate recreation, but rather an easily interpretable set of suggestions to bridge the gap between obtaining the raw data and jumping into CFD to try and improve correlation.
From my limited rake testing experience, I found I could piece together the changes that need to be made in CFD by looking through and analysing a small section of rake data at a time, but it was hard to think holistically or in a cause-effect way without some trial and error, especially when all I had where some coloured dots (see Making simulations better for more detail). It would be nice if all these middle steps could be done for me...
Before I start anything, here are the original CFD results from the start of 2024 on the EV2023 FSAE car:
The first vertical image set shows the initial results of the first CFD setup, and the second image set the same results after various changes to the CFD setup to improve correlation. The coloured dots show the experimental rake data categorised into freestream (black), intermediate (red), or low (blue) total pressure values. I was happy with the final results but they took a while to reach. I'll be using this data later to test and tune the processing tool.
The first step was to make a tool that produces simple pressure fields with slight differences to help me tune the algorithm.
Generate a radial gradient
Apply local "perturbations" in random places with a 1.1 or 0.9 multiplier and small radius
Sample the result with a 100x100 grid, and export this as a mock CFD result (I'll refer to this as "original CFD data")
Remove the perturbations
Rotate and vertically stretch the pressure field
Apply new perturbations, with the result being the "real" pressure field
Sample the "real" pressure field using a 5x5 grid, and export this as mock experimental results ("rake data")
Simply, the task of the algorithm is to take the CFD data and adjust it until it locally matches the rake data. Hopefully, it should then closely resemble the "real" pressure field.
This is the core of the algorithm and involves shifting parts of the original CFD pressure field until the rake and CFD values match at the rake probe locations.
For each rake point, search the CFD field within a defined radius to find the point with the lowest "cost", where cost is a combination of pressure difference and distance from the rake point (see first image below).
Starting with the rake point with the farthest lowest-cost-point, "morph" that point to coincide with the rake point location. A region around the point is also morphed with decaying radial strength (see second image below).
Reset and repeat steps 1 and 2 for all remaining rake points until a morph has occurred for each point.
By including a distance component, the results become less sensitive to pressure magnitude differences between CFD and test data, and the final result is kept more coherent to the original structure. The graphic below illustrates how the distance cost weighting allows nearby points to be preferred if the accuracy loss is minor. The Gaussian shape as well as the direct ratio of distance vs accuracy contribution to total "cost" were both tuned during testing. The choice of a Gaussian curve means that if an exact match is already nearby, it is more likely to be preferred even if a near-match exists even closer.
An example of the execution of a morph and the effect on the surrounding region is shown below:
You'll notice that this morph wasn't sufficiently strong enough to pull the high-total-pressure flow (dark red) all the way to the rake point as required. This is due to an adjustment made during fine tuning that I'll discuss later.
Once a region had been morphed, "damping" was applied to it, meaning any subsequent morphs had reduced influence on these already-shifted areas. The strength of the damping was applied proportionally to the distance of the morph vectors, i.e. strongest damping at the centre. The introduction of damping avoided highly distorted results, and scenarios where a latter morph would undo the effects of an earlier one.
Below are some of the first results before any fine-tuning. The "morph vectors" are created by subdividing the field into cells, then calculating the average magnitude and direction for that cell. One vector is then plotted for each cell.
Generated mock CFD field
Generated mock "real" field with rake samples
Morphed field
Morph vector field
For an initial test, the results were promising. The morphed CFD result looks significantly more like the "real" result than the original CFD field, and the morph vectors indicate that this was achieved in an efficient and physically plausible way. This was a very simple test though, so the next step was to run it again on some real and more complex pressure fields. There's obviously a limit to how this algorithm can be applied, and it relies on the original CFD field at least partially resembling the real field, but I think this is a reasonable assumption for a well set-up CFD simulation.
At this point, I'd lost access to most of our CFD files from 2024 after the university pulled the software license from us with no warning. The current aero team is working on transferring everything to an ANSYS environment, but for me it means I didn't have any raw pressure data that I could extract. The solution was to create a script that can read a screenshot and convert it to data by comparing colour values to their colour bar. This ended up working so well that it's probably the better option for importing CFD data now as it saves having to set up a sampling grid in CFD and export the sampled data. It also guarantees a sufficiently high resolution.
Tuning the algorithm primarily involved playing with various values for the parameters in the image below, for which I hope the code comments explain them well enough (at least after reading the rest of this section):
Unsurprisingly, the more complex pressure fields from the real car were much more sensitive to small changes in these values compared to the procedurally generated fields. The goal then was to tune the algorithm itself (such as introducing multiple morph passes, discussed below) and find a combination of input parameters such that the results satisfied three criteria:
The final result showed good agreement between the rake pressure values data and the morphed CFD pressure values
The morphed CFD pressure field was largely free of artefacts or otherwise seemingly unrealistic shapes and morph directions
Any further small changes to the input parameters produced only small changes to the results
The main change was the introduction of multiple passes. The first pass is gentler, while subsequent passes are broader and more aggressive, working to nudge any remaining discrepancies over what should then be a shorter required distance.
First Pass
Morph radius is automatically set as the distance from the current rake point to its nearest neighbour. This ensures the majority of the field is covered, but greatly limits distortion that arises from similar areas being morphed multiple times.
Morph regions are only shifted half their required distance. This gives nearby rake points a chance to re-calculate their lowest-cost point while the field hasn't yet changed too much, again avoiding potential distortion.
Subsequent Passes
Morph radius is constant to avoid over-fitting the CFD field to the rake points
Only rake points with more than a 7.5% error to the morphed CFD field have morphs calculated and applied, to avoid distortion and over-fitting
Distance weighting is slightly reduced to allow more flexibility, since the previous pass/es should have moved appropriate pressures closer anyway
Some example results from during the tuning process:
Higher weighting for nearby points
More readily accepts distant points
Balanced distance weighting, multiple passes
None of these results look particularly like the final "validated" CFD results shown back at the start of this page. This is because of inadequate rake data points around the outboard side, particularly the lower region, as well as the fact that it's relying purely on the original CFD data for shape detail. For this reason, the above images are not the primary output of the algorithm. If anything they were more for debugging during the tuning phase. Generally I tried to avoid deliberately recreating the validated CFD output to reduce bias and overfitting.
What I consider a more useful output is the total morphed vector field, which for clarity is plotted on top of a very coarse contour map of the morphed pressure field shape.
This is where the sensitivity to small input changes really shows itself, which became much less of an issue after introducing the gentle first pass.
The final algorithm was then applied to the second lot of rake data:
It's important to remember that the details of the final morphed shape are not critical and are likely to be quite inaccurate to, and what matters instead is the relative difference between the initial and final shapes.
The last step was to make an instructional diagram that's simple enough to be immediately interpretable. I wanted to consolidate the vector field into regions of rotation and regions of bulk linear/parallel displacement. This would advise the user of where vorticity need to be introduced, increased, or decreased, and which areas need a significant linear shift.
Rotational region identification
For each grid point on the interpolated vector field, a small search radius is imposed, and the cross product of all vectors within the radius is summed to give a moment about the point of interest. The search radius is expanded until the quotient of total moment and search area stops increasing. This determines a representative size of the net rotational region around each point. To qualify for plotting, at least 75% of the vectors in the search radius must contribute to the same moment direction; this avoids detecting regions of linear shear as rotational. Finally, the qualifying regions are compared to a threshold value based on the longest vector in the field, and those that exceed the threshold are plotted.
Linear region identification
Generally follows the same process as rotational regions, except the expanding search area is now a fixed-size line (30% of the overall field size) normal to each vector. Dot product is used instead of cross product, and qualification relies on the average magnitude within the proposed search line being at least some percentage (currently 70%) of the highest magnitude vector in the whole field.
Original CFD
Algorithm output
Updated CFD
Ignoring the outboard (RHS) lower wake region (and thus the existence/strength of the two large CCW regions in the first algorithm output) which suffered from a lack of rake points, the alterations shown by the algorithm otherwise appear to effectively describe the "improved" CFD results in both cases.
This suggests that if I'd had access to the algorithm output and followed its instructions when I was working on the correlation of these pressure fields last year, then I would have likely ended up with a very similar result, only much faster as I would have had a holistic view of the problem rather than thinking about individual points.
With this success, I once again went back to the randomly generated pressure field tool for further verification that the final diagram remains accurate/appropriate, which it did.
Mock CFD and rake data
Morph vectors
Simplified output