User:Colin Douglas Howell/YASim Surface objects

From FlightGear wiki
Jump to navigation Jump to search

YASim Surface objects

Surface objects provide the aerodynamics of most YASim objects that interact with the air, including wings, hstabs, vstabs, mstabs, fuselages, landing gear, and external weights. They describe both objects that produce lift, like Wing objects, and objects which mainly generate drag, like Fuselage objects.

Objects such as wings or fuselages are generally broken into segments, depending on the object's proportions. Each of these segments will get its own Surface to handle the aerodynamics of that particular region.

Surface objects are defined in the files Surface.hpp and Surface.cpp. The heart of the Surface object is the Surface::calcForce() method in Surface.cpp. Surface::calcForce(), given an airstream velocity vector v (in m/s) and an air density value rho (in kg/m3), returns a force vector out (in N) and a torque vector torque (in N·m). The force is simply the net aerodynamic force on the Surface, while the torque is a "self-torque", generated within the Surface itself by the airflow forces. To get the total aerodynamic torque exerted by the Surface on the aircraft as a whole, this self-torque must be combined with the dot-product of the Surface's force vector and its displacement vector from the aircraft's center of mass.

The details of a Surface's behavior are determined by the parameters which define it. These are described below.

Orientation

A Surface has its own internal coordinate system used when calculating forces; the orientation of this system's coordinate axes must be set when the Surface is created. This orientation is given as a 3-by-3 matrix which represents the rotation transformation needed to transform vectors from the aircraft's local coordinates to the Surface's internal coordinates. The transpose of this matrix (which is also its inverse) transforms vectors back from the Surface's coordinates to the aircraft's coordinates. The rows of the matrix are the unit vectors of the Surface's coordinate axes as expressed in aircraft coordinates; the columns are the unit vectors of the aircraft's coordinate axes as expressed in Surface coordinates.

A Surface's orientation matrix is in the 9-element array _orient[], stored in row-major order. By default, this matrix is set to the identity matrix. It is set with the Surface::setOrientation() method, which takes a single pointer to an array with the new matrix values, stored in the same format.

For a Surface representing an airfoil (a segment of a wing or wing-like object), the Surface coordinate system is arranged as follows. (Assume for now that the wing has zero incidence.) The X axis points "forward", towards the airfoil's leading edge and perpendicular to its midchord line. The Y axis points "left", towards the airfoil's left end, parallel to its midchord line, and perpendicular to X. The Z axis points "upward", toward the airfoil's upper surface and perpendicular to both X and Y. These three axes form a right-handed coordinate system. If the airfoil is moving directly forward along its X axis, then drag will be along the X axis in the negative-X direction, while lift will be along the Z axis in the positive-Z direction. If the airfoil is moving in some other direction, drag and lift, according to their usual definitions, will not coincide with the Surface axes. The Surface's self-torque will always be about the Y axis.

For a Surface representing a fuselage segment, the Surface coordinate system is simpler. Again, the X axis points forward, which this time is parallel with the fuselage toward its front end. The Y axis will point toward the fuselage's left side, and the Z axis will point toward the fuselage's top side. Both the Y and Z axes are perpendicular to their respective sides.

Incidence and twist

A Surface which represents an airfoil may have incidence and twist angles, the sum of which gives a net incidence angle. In this case, the airfoil's true orientation is not the same as that in the Surface's orientation matrix. Instead, the airfoil plane will be the orientation matrix's XY plane rotated about the Y axis by the net incidence angle. The XY plane defined by the matrix is thus the plane for an airfoil with zero net incidence.

Because of how the geometry works, a Surface's incidence and twist angles increase in the opposite direction from the usual usage in aviation. Positive incidence moves the airfoil's leading edge downward, since this corresponds to positive rotation angles around the Surface's Y axis. By contrast, the specification for "incidence" and "twist" in the XML file use the standard aviation convention, with positive values moving the leading edge upward. Airfoils which have positive "incidence" in the XML file will have Surfaces with negative incidence.

A Surface's _incidence and _twist properties give the incidence and twist angles, in radians. Both are zero by default; they are set by the methods Surface::setIncidence() and Surface::setTwist().

When Surface::calcForce() determines the force and self-torque on a Surface, it first normalizes the airstream velocity vector to get a direction vector, and then it transforms this vector with the Surface's orientation matrix. It then further rotates the transformed vector around the Surface's Y axis by the net incidence angle. After this rotation, the Surface's X and Y axes will both lie within the airfoil plane, and the Z axis will be perpendicular to this plane. Using these axes, calcForce() takes the transformed and rotated airstream direction vector and computes the force and self-torque vectors. Afterward, calcForce() reverses the incidence rotation for the force vector, rotating it around the Y axis by the negative of the net incidence angle. (The self-torque vector lies along the Y axis and thus does not need to be rotated.) Finally, calcForce() transforms both the rotated force vector and the self-torque vector with the transpose of the orientation matrix, converting both vectors to the aircraft's local coordinate system.

When calcForce() performs the incidence angle rotations, it uses an approximation which assumes that both the incidence angle and the angle of attack are small. The input airstream direction vector is assumed to be close to the XY plane, so this approximation only changes its Z component. For the force vector, what happens depends on the version of YASim. The original YASim version again changes the vector's Z component, but doing so is not correct for the force vector (Issue 1423). The force vector is close to the Z axis, not the XY plane. Therefore in the current YASim version, the rotation approximation changes the force vector's X component.

_c0: "total drag"

The force and self-torque vectors generated by calcForce() initially have magnitudes determined only by the airflow direction and the Surface's configuration. These vectors are then both scaled by a factor of ½⋅rhovel2_c0 in order to produce physical force and torque vectors with units of N and N·m. Here rho is the air density in kg/m3 and vel is the airstream velocity in m/s. The scaling constant _c0 is a Surface property which some parts of the code call "total drag". (This name shouldn't be taken too literally; it simply distinguishes the overall scaling constant _c0 from the directional scaling constants _cx, _cy, and _cz, discussed later. A more accurate name might be "overall drag factor".)

In order for the Surface's force and self-torque to have the proper dimensions and units, _c0 must have the dimensions of an area in m2. Thus, the _c0 of a Surface can be loosely thought of as its "drag area": its drag or lift coefficient multiplied by its reference area. However, this is only a rough interpretation, because the code for Surfaces doesn't distinguish between aerodynamic force coefficients and their reference areas and doesn't keep track of them independently.

_c0 is set by the method Surface::setTotalDrag() and can be retrieved by the method Surface::getTotalDrag(). The default value is 1, but in practice Surfaces never use this. Instead a Surface's _c0 is initially set based on the object's area. Later it is rescaled by the YASim solver using a common "drag factor", so that the aircraft's total drag satisfies the cruise and approach constraints.

For the Surface of a wing segment (including other wing-like objects), _c0 is initially set to the segment's area, the product of the segment's length in meters and its chord in meters.

For the Surface of a fuselage segment, _c0 is initially set to the segment's lateral cross-sectional area, the product of the segment's length in meters and the fuselage's height in meters at that point.

(In YASim's original version, the _c0 of a fuselage segment's Surface is initially set to the product of this area and the fuselage's XML attribute "cx", if that has been specified. Thus "cx" becomes an overall drag factor for the fuselage, regardless of direction. This is inconsistent with other YASim objects and contradicts YASim's documentation, which says that a fuselage's "cx" is a drag factor for its X axis only (Issue 1427). This bug is fixed in the current YASim version, for which "cx" only modifies X axis drag.)

It may seem odd that the drag for a fuselage segment would be proportional to its lateral cross-sectional area and that all the segments of a non-tapered fuselage would contribute equally to its drag along its long axis, but this is actually fairly reasonable. Although you might think that a fuselage's drag along its long axis should be proportional to its frontal cross-sectional area, this turns out to be false. For real fuselages, most of the drag in flight comes from viscous skin friction, and thus it is roughly proportional to the total surface area, which in turn is proportional to the lateral cross-sectional area. This is true even for relatively short, wide fuselages.

Landing gear and external weights also have Surfaces to represent their drag. For a Surface of a landing gear, its _c0 is initially set to the square of the gear's "length", which is assumed to be three times its compression distance.

(This isn't a good way to estimate the gear's aerodynamic size (Issue 1428). Real landing gear drag is roughly proportional to the size of the gear's wheels, but YASim doesn't take this into account at all. If a YASim aircraft has "stiff" landing gear with strong springs and short compression, its length will be short, so it will seem aerodynamically clean. On the other hand, the YASim Boeing 777 has main landing gear with unusually long compression, representing the vertical pivoting of the six-axle trucks. This long compression gives the gear an enormous aerodynamic size.)

An external weight which represents a droppable store has an XML attribute "size" in meters. Such a weight has a Surface whose _c0 is initially set to the square of this size. Weights with no "size" specified are assumed to be internal; while they too have Surfaces created for them, these Surfaces have a _c0 of zero and thus generate no force. For a streamlined external weight, it would probably be appropriate to set the "size" XML attribute equal to the square root of the object's side-on projected area in m2.

Once all the Surfaces of an aircraft have been created and their _c0 values have been initialized, the YASim solver will adjust the aircraft's overall drag to satisfy the cruise and approach constraints. It does this by multiplying the _c0 values for all Surfaces by a single common factor. This factor is generally much smaller than 1; its value, multiplied by 1000, is reported by the YASim command-line solver as the "Drag Coefficient". However, this factor actually affects lift as well as drag. For this reason, the YASim solver does not adjust lift independently, but rather determines the ratio of lift to drag, which it reports as the "Lift Ratio".

(The current YASim version no longer scales the _c0 of fuselage Surfaces by this drag factor; it instead scales the fuselage Surfaces' _cx. This is done to adjust fuselage longitudinal drag only while avoiding inappropriately reduction of the fuselage's transverse drag.)

YASim's reported "Drag Coefficient" should not be confused with the drag coefficient specified for real aircraft. Apart from differing by a factor of 1000, the two values are defined with different reference areas. By convention, a real aircraft's drag coefficient is defined relative to the "planform area" of its wing. YASim's "Drag Coefficient" is defined relative to the sum of the initial _c0 values of its Surfaces. Because of how these are set, the effective reference area is approximately the sum of the areas of all flight surfaces plus the sideways projected area of the fuselage.

Because the YASim solver scales the _c0 values of all Surfaces, each Surface's _c0 becomes a combination of the Surface's reference area and the drag coefficient estimated by the YASim solver. Hence _c0 is in effect a "drag area". This interpretation is most reasonable for the Surfaces of fuselages and other non-airfoil objects and for the X and Y force components of airfoils. For the Z force component of an airfoil, it makes more sense to treat the product _c0⋅_cz as a "lift area".

_cx, _cy, _cz: "XDrag", "YDrag", "ZDrag"

In addition to _c0, a Surface also has three directional coefficients for aerodynamic force: _cx, _cy, and _cz, which independently scale the forces on the Surface's X, Y, and Z axes, respectively. In some parts of the code, these are called "XDrag", "YDrag", and "ZDrag".

To understand these coefficients, think of the Surface not as a simple flat plane, but as a 3-dimensional shape. _cx, _cy, and _cz might represent the shape's relative cross-sectional areas across the respective axes. For example, a sphere would have _cx, _cy, and _cz all equal, as would a cube with its faces perpendicular to the X, Y, and Z axes, while a thin circular disk perpendicular to the Z axis would have _cx and _cy equal and _cz much larger.

By default, a Surface's _cx, _cy, and _cz are all 1. A Surface sets these coefficients using the Surface::setXDrag(), Surface::setYDrag(), and Surface::setZDrag() methods, respectively. (Originally YASim had no methods to retrieve the coefficient values, since it never needed to do so, but recently a Surface::getXDrag() method has been added to YASim to get the value of _cx.)

For airfoil-type Surfaces, the _cx, _cy, and _cz coefficients always refer to the axes defined relative to the airfoil plane, rather than those of the Surface's orientation matrix. This only makes a difference if the Surface's net incidence is nonzero; if so, _cx and _cz apply to the X and Z axes after they have been rotated about the Y axis by the net incidence angle.

All of an aircraft's airfoil-type Surfaces, including those for the horizontal and vertical stabilizers, have _cx and _cy kept at 1 and _cz set to a single common value much larger than 1. This is consistent with the way each of these Surfaces is constructed, as a wing segment with roughly equal span and chord which is thin along the X and Y axes and flattened along the Z axis. The common _cz value is calculated by the YASim solver to satisfy the aircraft's cruise and approach constraints and then applied to all airfoil surfaces. It is reported by the YASim command-line solver as the "Lift Ratio".

Fuselage Surfaces are more complicated. A fuselage can have "cx", "cy", and "cz" XML attributes defined for it; they default to 1 if unspecified. These attributes allow the fuselage's directional drag to be scaled to reflect its relative cross-sectional areas. As an example, consider an untapered fuselage. (Tapering makes no difference in how this works, but omitting it simplifies the explanation.) If this fuselage has a "width" XML attribute equal to its actual width, but the fuselage is twice as tall as it is wide, it should have a "cz" of 1 and "cy" of 2, because its top-view projected area would match a circular cylinder of the given width, but the side-view projected area would be twice as large. It should also have a "cx" of 2, because we'd expect it to have about twice as much drag as a circular cylinder of that width. This is partly because of the greater frontal area, but mostly because the overall surface area is about twice that of a circular cylinder.

The way _cx, _cy, and _cz are handled for fuselage Surfaces depends on the YASim version; it was changed from the original version to the current (3.2 and later) version in order to fix errors in how fuselage drag is calculated.

In the current YASim version, _cx is the fuselage's "cx" XML attribute multiplied by the solver's drag factor (the command-line solver's reported "Drag Coefficient" divided by 1000). (Other types of YASim Surfaces incorporate the solver's drag factor into _c0 rather than _cx.) _cy and _cz, on the other hand, are the "cy" and "cz" XML attributes multiplied by a fixed value of 0.5; the solver's drag factor is not involved. The reason for this difference between _cx and the other two directional coefficients is that the solver's drag factor effectively represents the aircraft's streamlining for normal flight, and this streamlining for fuselages is in only one direction. Along the other two axes, a fuselage is not streamlined at all; instead it acts as a "bluff body" which generates large amounts of drag.

The factor of 0.5 in _cy and _cz represents the approximate drag coefficient of a side-on circular cylinder at Reynolds numbers appropriate for an object the size of an aircraft fuselage moving at typical flight speeds. If the fuselage is flat-sided rather than a circular cylinder, its transverse drag coefficient will be bigger, and this effect can be achieved by increasing the value of "cy" and "cz". For a fuselage with a square cross-section, "cy" and "cz" should be set to 4, giving a drag coefficient along these axes of 2, which is approximately correct for a side-on square-section prism.

The original YASim version handled fuselage Surfaces differently, giving somewhat incorrect results. The solver's drag factor was incorporated into _c0 rather than _cx, just like other YASim Surfaces, so this factor affected drag on all fuselage axes. _cx was left at 1 and the "cx" XML attribute also became a factor of _c0, so it too affected all fuselage axes (Issue 1427). _cy and _cz were set to the "cy" and "cz" XML attributes multiplied by the fuselage's length-to-width ratio. Multiplying by this ratio increased fuselage transverse drag by that factor, but for many aircraft this wasn't big enough to counter the streamlining effect of the solver drag factor (Issue 1463). Thus the fuselage transverse drag was still quite low, and aircraft fuselages produced only mild side forces.

Surfaces for landing gear and external weights are different from all other Surfaces. They have their _cx, _cy, and _cz coefficients kept equal, and these coefficients are used in flight to adjust overall drag by resetting all three in sync. When landing gear are extended and retracted, the three coefficients are scaled by the amount of gear extension. External weights are "dropped" by setting all three coefficients to zero. (This would probably be better handled with an extra drag scaling factor that would leave the directional drag coefficients available for their usual purpose.)

Surface stall parameters

Stall behavior for Surfaces is calculated by Surface::stallFunc(), an internal function used by Surface:calcForce().

A Surface's stall behavior is determined by three property arrays, _stalls[], _widths[], and _peaks[]. These are arrays because there are four different cases to consider. The case for normal flight is the "forward positive" case, with the Surface moving forward at positive angle of attack, and is handled by _stalls[0], _widths[0], and _peaks[0]. For a Surface of a Wing object, it is these parameters which are set by the Wing's "stall" entry in the XML file. Another case is the "forward negative" case, with the Surface moving forward at negative angle of attack. This is the usual case for inverted flight, but it can also happen during normal flight for some aircraft with highly cambered wings which need a slight negative angle of attack to fly level at high speeds. The final cases are the "backward positive" and "backward negative" cases, with the Surface moving backward at positive or negative angle of attack. These are not possible in normal flight; they would only happen in unusual situations, such as if the airplane had stalled and was falling backward or if it was sitting on the ground in a tailwind. The forward negative case is covered by _stalls[1], _widths[1], and _peaks[0], the backward positive by _stalls[2], _widths[2], and _peaks[1], and the backward negative by _stalls[3], _widths[3], and _peaks[1].

In explaining how this works, it is important first to note that YASim Surfaces do not actually calculate "lift" according to the standard definition, as a force perpendicular to the airstream velocity vector. Instead, a Surface calculates that component of the force which is aligned with its own Z axis. The code often calls this "lift", but to avoid ambiguity, I will call it "Z-force".

For each of the stall cases, the _stalls[i] property is the angle of attack (in radians) where the Surface starts to approach the stall. Up to this angle the Z-force increases linearly with the angle (possibly with an offset at zero determined by _cz0, discussed later). Once the angle exceeds the _stalls[i] angle, the Surface enters the "stalling zone", whose width in radians is given by _widths[i]. Here, as angle of attack continues to increase, the rate of increase of the Z-force slows down, Z-force finally reaches a peak, and then it drops again, before eventually bottoming out and resuming its rise. Beyond the stalling zone the Z-force again increases with angle of attack, but more slowly, similar to an inclined flat plate. In most situations an airfoil Surface will never get far into this "post-stall zone".

This behavior is modeled after that of real airfoils. However, the lift curves of real airfoils plot true lift, the force perpendicular to the airflow velocity. This also varies linearly with angle of attack up to near the stall angle, where it peaks. For Surfaces, it is the Z-force, along the Surface's Z axis and perpendicular to the airfoil plane, which increases linearly with angle of attack. The distinction between an airfoil Surface's Z-force and a real airfoil's lift must be noted when comparing the results of Surface stall parameters to real airfoil lift curves.

How the Surface stall parameters work numerically and how they determine the Surface's lift curve is tricky, partly because of the above distinction, partly for other reasons, including differences between the parameters' internal values and those given in the XML file's "stall" entry. Unfortunately, the documentation of these parameters is vague and misleading in some ways. If you want a good match between a Surface's lift curve and that of a real airfoil, you can't rely on the documentation's claimed interpretation of the parameters; you have to look at the math and figure out what values will make the curve fit.

_widths[i] is probably the simplest parameter. It is simply the width of the interpolation zone between pre-stall and post-stall. Both of these regions scale the Surface's Z-force linearly with the Z component of the airflow direction. The interpolation zone does a cubic interpolation between these two linear curves, thus rounding out the peak and post-stall valley. For a Wing's Surfaces, _widths[0] is set with the "width" parameter of the Wing's "stall" entry; if left unspecified, it is set to 2 degrees. The greater the value, the wider and more rounded both the peak and the valley will be. (Greater values will also create a larger discrepancy between the _stalls[0] value and the true peak in Z-force; see below.) Judging what value to use might be a little tricky. One could simply try to reproduce the width of the peak-valley region between pre-stall lift and post-stall lift, but the post-stall lift curve for real airfoils is usually not available, and even if it were, it would likely be different from the cubic interpolation, so matching the zone width would probably generate a poor match for the shape of the lift peak, which is more important to flight performance than that of the post-stall valley. Accurately reproducing the peak shape is the best approach for setting "width".

_stalls[i] represents the stall angle, the angle of attack at which the Z-force curve peaks. It is actually the angle at which the curve switches from linear to the cubic interpolation. Because of this interpolation, it won't be the true peak angle except for the unrealistic case of _widths[i] = 0, a perfectly sharp stall. For small values of _widths[i] (less than around 4 degrees), _stalls[i] is still very close to the Z-force peak. As _widths[i] increases further, the peak shifts away from _stalls[i]: for _widths[i] = 7-8 degrees, the peak is around 1 degree past _stalls[i]; for _widths[i] = 10-11 degrees, the peak is around 2 degrees past _stalls[i]; and for _widths[i] = 15-16 degrees, the peak is around 4 degrees past _stalls[i]. The relationship isn't linear; it looks roughly quadratic for _widths[i] up to around 10 degrees, where it becomes less than quadratic.

For a Wing's Surfaces, _stalls[0] is based on the Wing's "aoa" and "width" parameters in its "stalls" entry. The Surfaces set _stalls[0] to "aoa" - "width"/4. This is a very crude correction for the shift of the Z-force peak with increasing stall width. It's too large for lower widths, and for very low widths no correction would be better.

_peaks[i] is the most obscure parameter, but it still matters, despite the fact that the documentation calls it "deep voodoo". According to the documentation, it represents the ratio between the height of the stall lift peak (actually the Z-force peak) and the post-stall secondary lift peak at an angle of attack of 45 degrees. Unlike the stall Z-force peak, this post-stall secondary peak only occurs on the true lift curve, not on the Z-force curve; it results from how the rising post-stall Z-force is partitioned between lift and drag.

It turns out the documentation is simplifying matters somewhat. _peaks[i] is actually the ratio between the peak of the Z-force curve's pre-stall linear portion and the post-stall secondary lift peak. The cubic interpolation will cause the actual Z-force peak to be higher than the linear portion's peak, much higher if _widths[i] is large. On the other hand, the difference in direction between Z-force and true lift will make the lift peak slightly shorter than the Z-force peak, more so for larger values of _stalls[i]. Thus _peaks[i] only approximates the true ratio of the pre-stall and post-stall lift curve peaks.

More importantly, the documentation of _peaks[] neglects a very important matter which this parameter affects. Remember that the pre-stall portion of an airfoil's lift curve is practically linear with angle of attack. Thin airfoil theory predicts that the slope of this portion should be exactly 2π per radian, or about 0.11 per degree, and for the lift curves of most 2-D airfoil sections, the slope is quite close to this value. Finite-span airfoils have somewhat lesser slopes, depending on the airfoil's aspect ratio. With YASim Surfaces, the slope of the pre-stall portion of the Z-force curve is automatically fixed by the ratio of _peaks[i] to _stalls[i]. Therefore the best way to set _peaks[i] is to recognize that once _stalls[i] has been determined from the airfoil's lift curve, we just need to set _peaks[i] to get the proper curve slope.

For a Wing's Surfaces, _peaks[0] is set to the "peaks" parameter of the Wing's "stall" entry; if left unspecified, it is set to 1.5. This value would give the proper lift curve slope for a 2-D thin airfoil section if _stalls[0] = 14 degrees.

The XML file only allows directly setting a Wing's parameters for the forward positive stall (the normal stall): _stalls[0], _widths[0], and _peaks[0]. The parameters for the forward negative stall (the inverted-flight stall), _stalls[1], _widths[1], and _peaks[0], are based on those for the forward positive stall. For symmetric airfoils (those with zero camber) and for negatively cambered airfoils (unusual, but plausible for some stabilizers), they are exactly the same as those for the normal stall. For positively cambered airfoils the stall parameters are somewhat worse: _stalls[1] is 0.8 * _stalls[0], and _widths[1] is 1/2 of _widths[0]. (Of course, the same _peaks[0] is used. The change in _stalls[1] for positively cambered airfoils doesn't affect the lift curve slope, because the forward-positive stall angle, _stalls[0], is used to determine the slope for both forward-stall cases.) The parameters for the backward positive and negative stalls, _stalls[2..3], _widths[2..3], and _peaks[1], are described in the code as "unmeasurable junk", and are set to a very sharp stall (width of 0.01 radians, or around half a degree) at an angle of attack of 13 degrees with a _peaks[1] value of 1.

For non-Wing Surfaces, the stall parameters are set to effectively disable airfoil-type pre-stall lift: _stalls[i] is set to zero, _widths[i] is set to 0.01 radians (around half a degree, very sharp), and _peaks[i] is set to 1. _stalls[i] being zero automatically short-circuits stallFunc(), causing it to treat all lift as post-stall "flat-plate" lift.

The three Surface parameters _stalls[i], _widths[i], and _peaks[i] are set by methods Surface::setStall(), Surface::setStallWidth(), and Surface::setStallPeak(), respectively. All three methods take the index i as the first argument and the parameter value as the second argument.

Though YASim models the lift curve effectively for stalls, it doesn't seem to do as good a job with the drag curve, at least with the induced drag parameter set to zero. Basic drag is just simple flat-plate drag throughout, but there's an extra contribution in the pre-stall and stall regions from the Z-force as it tilts backward with greater angle of attack . Once the stall is reached, this contribution drops off like the stall lift curve does, since it comes from the same Z-force interpolation. Thus there a dip in the drag curve with similar sharpness to that in the stall's lift curve. But for real airfoils, there is no dip in drag in the stall region, but rather a steep rise, because in that region the airfoil transitions from a streamlined body to a bluff body. Ideally, YASim's drag profile would mimic this somehow, but that would obviously require some study and a careful rework of the stall handling.