How we set up a detailed CFD base model to ensure its adaptability and applicability as a vital tool in years to come
Here I cover the process of getting our existing CAD model of last year's car into a new CFD environment. Why last year's car? We need to be able to validate our simulation setup before we can trust it enough to pour in hours of design work on something new, and since the 2024 car doesn't exist yet in reality, this is our only option.
The first step was to simplify the car. For some parts this process is obvious; you aren't going to be needing the pedal box or the accumulator mounting bolts in an aerodynamic simulation. All these "internal" parts can simply be removed, and any mostly-enclosed hollow areas can be filled in. For other parts, the decision to include them (or how much to simplify them) is less obvious. Items like the wishbones, wishbone clevises, headrest, rear axle, parts housed inside the wheel structure, and even small gaps in the bodywork can be expected to affect airflow, but the question is by how much? I decided to include them all with minor simplifications to start with, as they could easily be removed from the model later if found superfluous. At the end of the simplification process, this is what I was working with as a first test model:
Simplified CAD model of EV23 for CFD use with an initial guess of ideal geometric complexity
The driver model proportions and arm positions were measured from our tallest driver sitting in the car.
An important factor in deciding how much effort should be put into maximising CFD accuracy is that our team does not have access to a full-scale wind tunnel (or even a suitable model-scale tunnel) anywhere in Tasmania. This limits us in design complexity as it is difficult to validate small/complex flow structures during on-track testing. Our best option is to make the most out of what we can achieve using CFD, and simply refrain from relying too heavily on complex flow features and/or surface design for performance.
The first case I set up was a straight-airflow scenario at ride-height at 18 ms-1 (65 kph). This is a good compromise between driving fast enough to provide sufficient forces (once aerodynamic components are on the car) to allow accurate measurements, while remaining slow enough to get a decent number of data points to average per run down the main straight at track. he domain for the straight and braking cases is a simple rectangular prism. Dimensions were estimated erring on the larger side until domain size independence could be assessed later. Both cases utilised a half-car model.
For the cornering cases, the full car was positioned in a cylindrical domain centred at the middle of the effective corner, considering typical vehicle slip angle predicted by our suspension/tyre simulation code (we don't yet have an IMU or yaw probe, so have no real-world slip data to go off). Suspension positions and steering angle for each case were also taken from simulation, but these had been validated against data from several track days with the EV23 car. Toe and camber used our usual autocross setup.
Next I had to make sure the wheels could spin properly. This is easy for tangential motion such as the tyre, but for parts with any normal motion component (e.g. the wheel centre and its "spokes"), it's a little more involved. For a steady-state simulation, these parts need surrounding with a separate fluid region with its own moving reference frame (MRF). The exact angular position of the "spokes" in the model would theoretically effect the result given the MRF creates only instantaneous relative motion, but we just had to assume it didn't matter.
As a retrospective note, these MRF's were later removed, keeping the same wheel centre geometry but with only tangential motion. This greatly reduced manual setup time (when suspension positions were changed), improved simulation stability, and gave nearly a 10% faster solve time. This resulted in <1.5% changes to downforce and drag estimates.
Front left wheel region encompassing all parts with a normal motion component, and assigned to a local moving reference frame (MRF)
For the cornering cases, the domain itself needed its own MRF, which was set up exactly the same way as the wheels. For both half-car and full-car cases, the walls and roof were all set to symmetry planes, which in combination with having the walls sufficiently far drom the vehicle, gave a far-field/freestream boundary approximation.
Non-zero roughness was applied to the tyres (tread and sidewall independently) and the ground. Like many other inputs so far, these values were a guess and mostly just a placeholder until we get validation data.
Mesh sizes were selected for all the surfaces based on a combination of research on similar applications, and a bit of intuition. These ranged from 2.5 mm for complex curvature and proximity refinements, to 5mm for wheel internals, chassis tubes, tyres, wishbones, etc, to 10 mm for bodywork, all the way up to 320 mm near the boundaries. Additional finer mesh sizes down to ~0.15 mm were then used at the tyre contact patches which had a 1 mm intersection with the ground and a 1 mm tall "plinth" around the perimeter to remove the sharp contact angle for cleaner meshing (the CFD tyre models were completey changed later on - see Squishy tyres). Finally, the ground, which was otherwise set to 160mm surface sizing, was set to 5mm surface sizing in a small region directly surrounding the vehicle.
Additional refinement volumes were added where complex off-body flow (wake) was expected. These included a 20 mm sizing behind the front and rear wheels, 40 mm sizing directly in front of the car, and 40 mm sizing extending from the car rearwards to the domain outlet (both occupying an area a little larger than the cross section of the car). Several volumes with gradually coarsening mesh were placed around tyre plinths to smoothly meet the surrounding mesh size, more gradually than the default growth rate. At this point, the half-car model had about 7 million cells. This is low for a full-detail vehicle simulation, but I have no wake refinements (yet) other than a very crude and coarse rectangular volume behind each wheel.
All surfaces are using a wall-modelled approach based on some quick research suggesting that this is perfectly sufficient for for vehicle bodywork and anywhere with low pressure gradients; with no aero-specific surfaces, this applies to the whole car.
Physics settings were generally based on default values for the k-omega SST turbulence model, with a few adjustments based on some quick research and reading of the manual:
a1 parameter was increased from the default value of 0.31 to 1.0, in-line with a recommendation by CD-Adapco engineers for similar applications.
CT (realisability coefficient) was increased from the default value of 0.6 to 1.2, in-line with a recommendation by Siemens and Evans et al. (2016) for steady-state vehicle aerodynamics simulation.
Both values (and other potential physics/turbulence model changes) are subject to future validation studies, particularly since a low Reynolds number FSAE car does not represent a typical industry vehicle aerodynamics scenario.
The final part of the setup involved creating functions for automated mesh refinement (AMR). The complexity of airflow around a vehicle (particularly with open wheels) means using simple volumetric refinements for all mesh sizing is inefficient. Some research suggested we should be looking to refine cells with high vorticity and velocity gradient.
Vorticity was defined by the Lambda-2 criterion being less than 0, with a wall distance weighting to avoid picking up too many cells where vorticity was dominated by shear rather than defined stream-wise rotational structures. This acted down to 5mm. For all the AMR criteria, it was again a case of estimating an initial threshold which was later adjusted based on convergence of results monitors as part of verification testing.
Velocity gradient was used to minimise uncertainty and artificial drifting or weakening of the borders of wake areas, and had three levels of refinement from 80mm down to 20mm.
As another note from the future, verification tests led to additionally refining areas of low total pressure and high turbulent kinetic energy (both set to 10mm), to decrease apparent mesh sensitivities of blown-up, weak, or poorly formed vortices from the suspension clevises and cockpit opening, and reducing premature wake turbulence dissipation. An additional buffer of 5 cells surrounding the refinement volumes were also refined. Some of these refinement functions required a little more math and a few extra "if" statements for the cornering cases, as the velocity relative to the car differs depending on the local radius within the domain.
Isosurface showing cells flagged for refinement by the turbulent kinetic energy AMR criteria for a half-car simulation. The main purpose of this refinement was to reduce turbulent dissipation, reducing premature blending/softening of wake feature perimeters and weak vortices with freestream flow that became apparent with larger mesh sizes.
Initial simulations were mainly used for debugging purposes, guiding small mesh adjustments to eliminate instabilities, and tuning y+ values. AMR update intervals were also adjusted and set to trigger when the current solution is approaching convergence. 3 update intervals were used. After 3 updates, the final mesh count for a half-car case was around 14M, and 27M for a full car. I'd expect aerodynamic surfaces and the associated increase in flow complexity to add an additional 20% or so to each of these. Convergence was based on monitors for lift coefficient, drag coefficient, aero balance, and two total pressure probes being steady within 3 decimal places. This typically took around 800 iterations, with an additional 200 iterations run to allow the monitors to be averaged. With 72 CPU cores, this only takes 1.5 hours for a full-detail half car case, and 3 hours for a cornering case. We have up to 128 cores available but there are diminishing returns over 72 cores for our mesh count, and other research students also require use of the machine.
One of the most important checks in this period was making sure the y+ value fell within an acceptable range on all important surfaces. The easiest way to monitor this is through weighting local cell y+ values with the surface friction coefficient. In regions where there is no flow attachment or where velocity is low (and thus surface friction is also low), y+ can be sacrificed with negligible effect on the result. Surface area is also a good weighting factor. I set up a series of histogram plots to show y+ weighted by the product of friction coefficient and surface area for the critical surfaces: bodywork/aero, tyres, and ground. The plot below shows the results after some tweaking. Some cells unavoidably remain between 5 and 30, but their weighting is small. Very high values (200+) were also avoided where possible.
Weighted y+ distributions for bodywork and tyres (top), and the ground (bottom)
To help locate areas with problematic y+, a scene was created to show the local value with categorical levels. An example of this is shown below. The only area that stands out as potentially problematic in this example is the orange (high y+) area on the sidewall of the front tyre, however tests with a locally thinner first layer height showed negligible difference in local skin friction or the sidewall flow separation and wake behaviour/shape. The large areas of red on the ground are acceptable given the low wall shear, reflected in the above plot.
Surface y+ values shown with categorical colour assignments: blue: y+ <5, red: 5< y+ <30, green: 30< y+ <300, orange: 300< y+
Another scene was created to check R+ (dimensionless roughness) values, and in particular the ratio of R+ to y+. Having R+ > y+ is theoretically acceptable when using the k-omega turbulence model, which does not enforce maximum roughness like k-epsilon does, however it still seems like good practise to identify and minimise such occurences as much as possible.
The last thing I'll mention is that we found some issues with the AMR process where after refinement, the flow "solution" seemed to be having a hard time adapting to and converging on the new finer cells, with monitors and residuals floating around aimlessly for a while after each AMR update. One solution was to just wait out the convergence, but this was occasionally taking upwards of 1500 iterations. Given the issue seemed to be related to how the solution was moving through the domain, adjustments to the CFL number seemed like a logical place to look. For the half-car case, it was naturally peaking at around 150-175, and for the full-car cornering cases at 200-300. We set a maximum limit of 150 and this sped up convergence (down to the 800 iterations mentioned earlier) while having negligible effect on the final solution. Individual iterations took slightly longer but overall solve time was reduced by around 25%, and decreased sensitivity of the results was noted.
I won't go into detail on convergence/verification studies on this page (here's a link to a post from the future instead), but the following parameters were all investigated using the metrics of lift coefficient, drag coefficient, aero balance, lift/drag ratio, and total pressure probes:
Domain width (or outer and inner radii for cornering cases)
Domain fore length
Domain aft length
Domain height
Base mesh size (from which refinements are scaled as a percentage)
Wheel contact patch refinement volume size
AMR threshold values
Exclusionor simplification of various geometry details from the simulation
I'll cover post-processing visualisations and utilising CFD results in future posts.