A qualitative pressure-rake post-processing tool
No, I don't actually refer to this project by that name, and definitely not by the acronym that took too long to come up with...
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 such that it 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 that I had already spent time to go through and categorise into three colours (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 2023 FSAE car:
The first vertical image set shows the initial results after the verification stage, in which every part of the setup (mesh, geometry complexity, surface finishes, turbulence models and parameters) is either an educated guess, or using settings that worked well for others. The coloured dots show the rake data from track testing categorised into freestream, intermediate, or low total pressure values. The second image set the same results after various changes to the CFD setup to improve correlation. These results look fine but 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.
Generate a radial gradient
Applies local "perturbations" in random places by superimposing a localised radial gradient with a 1.1 or 0.9 multiplier
Save, sample (I used 100x100), and export this as the "original CFD data"
Remove the perturbations
Rotate and vertically stretch the pressure field
Apply new perturbations
Sample using a 5x5 grid, and export this as the "rake data"
We now have an endless supply of CFD results, "real" pressure fields, and rake data to build the framework of the algorithm around
Clearly I forgot to re-title the figures after I switched from a 4x4 grid to 5x5.
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 the total cost is a combination of pressure difference and distance from the rake point (see first image below).
For the rake point with the most distant lowest-cost-point, "morph" that point to coincide with the rake point location. A region around the point is also morphed with decaying strength as radius increases (see second image below).
Reset and repeat steps 1 and 2 for all remaining rake points until each has applied a morph exactly once.
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 closer-still.
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 all the way to the rake point as required. This is a result of 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 original CFD field
Generated "real" field with rake samples
Morphed CFD 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.
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 OpenFOAM 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.
The output of the screenshot analyser is re-plotted to make sure it worked. Apart from the slightly different colourmap, the results show no differences to the original screenshots (see the first figure on this page)
Tuning the algorithm primarily involved playing with various values for these parameters, for which I hope the code comments explain them well enough (at least after reading the rest of this section):
Unsurprisingly, these more complex pressure fields 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 re-ordering steps and introducing multiple morph passes - see image 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.
After a quick test using the simpler procedurally generated pressure data to make sure the tuning hadn't been biased by these two real rake tests, 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.
Both outputs are based on the morph vector field, which is interpolated back to a higher resolution to smooth the data.
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. The qualifying regions are then plotted in order of strongest to weakest, with a minimum spacing between rotation centres.
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 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. Also important to note for the trustworthiness of the output is that, considering these two pressure fields are sampling the same wake just 45 cm apart, the location, magnitude, and direction of the rotational and linear shift markings look plausibly similar between the two outputs.
The full vector field and coarse contours may be useful to give an approximate idea of shape change, but these final rotational + linear shift diagram is what I consider the primary output.
With this success, I once again went back to the randomly generated pressure field tool for further verification that the final diagram remains accurate, and show appropriate strengths, radii, and total number of rotational and linear shift regions.
Original CFD and rake data (generated)
Morph vectors
Simplified output
From observing all the outputs, the linear shift arrows should be interpreted differently depending on their location. Those outside of rotational regions are a purely linear shift, while those that fall inside a rotational region indicate an asymmetric rotation strength. As such, it's important to remember when analysing rotational regions that their strength is not necessarily equal around their circumference, and more broadly that rotational and linear results should not be considered independently where overlap occurs.