<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated on Wed, 23 May 2012 11:20:06 -0700 -->
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/feed/" rel="self" type="application/rss+xml" />
    <title>Intel Software Network Comments Feed</title>
    <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>By jm77</title>
      <description><![CDATA[ Hi Michael, 

First thank you very much for your excellent series of articles that I have been following for quite some time. I've picked up a great deal from the simple language and diagrams. I had a question about the kernel you've chosen, in vontron.h, in the calculation of "distlaw".

You currently use 1.0f / (radius^2 * dist). My question is, why do you use this value instead of dist / r^4? From what I've read this would be a more linear choice, as when dist is very small the first option would still have some large velocities.

Thanks again for all your work, and hope you keep making these! ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68270</link>
      <pubDate>Sat, 17 Dec 2011 16:45:27 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68270</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ Hello jm77,

I just spent over an hour composing a detailed response to your excellent question, including detailed instructions for experiments to try.

I pressed "submit" and got an error message that the comment system was down, and lost all my text.

It's very late (early) here so I'm out of patience with ISN for the time being.  I'll try to work up the gumption to reiterate my reply soon.

Meanwhile, short answer is that what you propose could be made to work, and what is in the code is indeed inconsistent with what article 3 describes (which is 1/radius^3), and that all 3 of these options (your suggestion, what's in the code and what article 3 claim) are valid -- and the specific choice doesn't make a huge qualitative difference. ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68275</link>
      <pubDate>Sat, 17 Dec 2011 23:50:36 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68275</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ Oops, pressed "submit" too soon that time.

I also wanted to thank you for your excellent question and for the feedback on the articles.

Part of my answer included detailed instructions for how to use some "easter egg" features of the code that comes with article 11, plus a teaser for how all of this ties into the next article (12).

So, you posed a precient and inciteful question.

Thanks again!
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68276</link>
      <pubDate>Sat, 17 Dec 2011 23:53:19 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68276</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ Hi again jm77,

The short answer is that you did indeed find a difference between what article 3 describes and what the code implements.  So either the article text is wrong or the code is wrong.  Either way, I apologize for the mistake and thank you for pointing it out.

For the code to match the formula in article 3, it should look like this:

#define VORTON_ACCUMULATE_VELOCITY_private( vVelocity , vPosQuery , mPosition , mAngularVelocity , mSize)       
{                                                                                                               
    const Vec3          vNeighborToSelf     = vPosQuery - mPosition ;                                           
    const float         radius2             = mSize * mSize * 0.25f ;                                           
    const float         dist2               = vNeighborToSelf.Mag2() + sAvoidSingularity PLUS_MAGIC_BUFFER ;    
    /* If the reciprocal law is used everywhere then when 2 vortices get close, they tend to jettison. */       
    /* Mitigate this by using a linear law when 2 vortices get close to each other. */                          
    const float         distLaw             = ( dist2 < radius2 )                                               
                                                ?   /* Inside vortex core */                                    
                                                ( 1.0f / ( radius2 * mSize * 0.5f ) )                           
                                                :   /* Outside vortex core */                                   
                                                ( finvsqrtf( dist2 ) / dist2 ) ;                                
    /* The actual formula for velocity is                                                   */                  
    /*  OneOverFourPi * ( FourPiOver3 * radius^3 ) * vorticity ^ vNeighborToSelf * distLaw  */                  
    /* but the FourPi's cancel, vorticity=AngVel*2 and mSize==radius/2                      */                  
    vVelocity +=  OneThird * radius2 * mSize * mAngularVelocity ^ vNeighborToSelf * distLaw ;                   
}


Note that this does not match the formula you suggest.  I'll explain why in subsequent comment.
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68307</link>
      <pubDate>Sun, 18 Dec 2011 07:03:31 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68307</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ jm77,

As part 3 describes, the velocity-from-vorticity formula should be regularized to avoid the singularity that would otherwise exist at dist=radius.

The velocity-from-vorticity formula should have these features:

* It is not singular, that is, the dependency on "dist" should be non-negative. That includes the following possibilities:

** constant (which is what the code accompanying this article uses)
** linear (which is what article 3 describes)
** quadratic (which is what the formula you propose describes -- which I'll explain in a moment)

* The dimensional analysis (that is, units) should be correct.  Again, easy to construct especially given the next constraint:

* The integral over the cutoff must be identical to the integral over a singularity. That is, the total circulation must be the same, and the velocity outside the cutoff must be the same.  Both of those are easy to construct:
** The total circulation can be rescaled by changing the constant coefficient out front.
** The velocity outside the core is made the same by simply providing different the formulae inside and outside the core, which is what we've done.  But doing so introduces a discontinuity at some derivative. That least to the next constraint:

* The formula should be continuous in at least the function itself (if not also its derivatives with respect to distance).  Basically that means that at precisely dist==radius, the function should have the same value for the "inside" and "outside" parts. Which is, again, easy to construct.  (Note that the choice of formula I used has a discontinuity in the first derivative.)

It turns out that there are a lot of options that satisfy these properties, and if you took a survey of the literature, you'd find that the cutoff I chose for these articles is the simplest.  In contrast, Cottet & Koumoutsakos describe a more exotic cutoff that is continuous for every derivative.  That also unfortunately means their kernel does not have "compact support" meaning, integrating it requires performing an integral instead of a summation, which makes that cutoff useless for the treecode method.  It could be used with a spectral method though.

In summary, the world of cutoff functions is large and is an active topic of research in the scientific community.

In the next comment I'll explain why dist/r^4 turns out to be quadratic instead of linear.
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68308</link>
      <pubDate>Sun, 18 Dec 2011 07:22:53 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68308</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ jm77,

So, why do I claim that dist/r^4 yields a quadratic dependenct on dist, when clearly "dist/r^4" is linear in "dist"?

Because that gets multiplied by vNeighborToSelf whose magnitude is dist.  We could write vNeighborToSelf as "dist * vNeighborToSelfDir" where the "...Dir" form is the unit vector.

(And indeed, the code has a variable called vNeighborToSelfDir initialized to vNeighborToSelf * oneOverDist but was never used.  So your question prompted me to discover this unused variable and remove it.  Curious that the compiler didn't complain about it since I have warnings cranked up.)

Still, as I mentioned in the comments above, the formula in the code does not match what article 3 describes so no matter how you slice it, I published a mistake, and you pointed it out.

I have changed the code to match what article 3 describes.

I'll follow up with one more comment that explains what the impact of all this is.  Short version: not much, but it's fun and interesting to investigate. And that exercise also leads to an understanding of why this demo code looks so jerky.
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68309</link>
      <pubDate>Sun, 18 Dec 2011 07:27:53 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68309</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ jm77,

Here's an "easter egg":  The demo code that accompanies article 11 (this one) has a bunch of diagnostic features.  You can press various keys to cycle through or toggle different renderings:

* v - toggles vorton rendering.  Vortons are rendered as translucent disks with a sharp outline and a dot in the center, plus a faint square on the outer edge of the texture.  You can barely see them with all the tracers in place though, so you'll want to turn off tracers.
* t - cycles through different tracer rendering.  You can view fuel, flame, smoke, all or none.  To diagnose issues, "none" is the best because it lets you see other diagnistics.
* g - cycles through grid rendering.  One of the options is to render all grid cells.  But grid cells are also made more translucent and transparent, the farther away they are from the camera look-at point.  So if you move the camera, grid cells will appear and disappear.
* d - cycles through diagnostic text and line rendering.  One mode lets you see information about every grid cell and every vorton.  The amount of information is so huge that it's incomprehensible and illegible unless you zoom in very close.  Also, the text is (like the grid cells) transparent everywhere except near the camera look-at point.
* down-arrow - pauses time.
* right-arrow - when paused, advances time forward by one tick.
* up-arrow - resumes time.

If you enable vortons, grid cells and diagnostic text, and disable tracers, pause time and step through the simulation tick by tick, you can see vortons that occasionally pass over a grid point (the corner of a grid cell).  When this happens, the diagnostic text for a vorton turns red.

That happens somewhat rarely and briefly, which is why you have to single-step through the simulation to catch it.

If you pay very close attention, you'll find that whenever you see jerking, it corresponds with a vorton getting near a gridpoint.  This is the topic of the next article (12).

Meanwhile, I encourage you to try the different cutoff functions discussed here:
* The original that the demo code uses (constant)
* Linear (using code I provided in the comment above)
* Quadratic (using the formula you propose).

You'll find that the choice does not make a huge qualitative difference in the overall fluid behavior.  And that's a good thing because otherwise that would imply that an arbitrary numerical choice leads to significantly different simulated results -- which it should not.

Put another way, if the time step was very tiny and the computer had infinite precision, then the choice of cutoff should not matter (as long as it obeys the constraints I mentioned above).
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68315</link>
      <pubDate>Sun, 18 Dec 2011 07:41:31 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68315</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ jm77,

In case I didn't explain it elsewhere, you can move the camera:

* left-click-drag orbits the camera eye around the camera look-at point.
* middle-click-drag translates the camera eye and look-at points together.
* right-click-drag moves the camera eye toward or away from the look-at point.

Have fun! ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68316</link>
      <pubDate>Sun, 18 Dec 2011 07:46:20 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68316</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ jm77,

One final note: In the comments above I carelessly wrote "cutoff" instead of "kernel".  They're related to each other but not the same.  In your question you correctly used the term "kernel".

Too bad I can't edit comments :) ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68317</link>
      <pubDate>Sun, 18 Dec 2011 07:55:55 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68317</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ Wow, and I spelled "insightful" wrong.  Next time I'll resist the temptation to compose replies at 2am.  I seem to be a mistake generator. :)
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68334</link>
      <pubDate>Sun, 18 Dec 2011 09:04:38 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68334</guid>
    </item>
    <item>
      <title>By jm77</title>
      <description><![CDATA[ Hi Michael,

Wow, thanks for the detailed response. I see you are right, I had thought that vNeighborToSelf was normalized, hence the gap in my understanding. I've been doing quite a bit of reading on kernels, smoothing, cutoffs and all these terms. I actually like your formulation a lot, due it's computational and conceptual simplicity. The paper by Robert Speck on multipole methods is also very cool but seems very challenging.

Looking forward to the article on fixing the grid jerkiness. I did implement a version of the grid code, but I eventually switched to summation over a finite area. However as my understanding is the kernel in question does not (or maybe does?) have compact support, but extends out to infinity, I'm now searching for a way of convolving this kernel or modifying it in some way such that it reaches zero at a finite radius.

Also the debug visualizations are very helpful. :)

Thanks again for your time!
Jamie ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68338</link>
      <pubDate>Sun, 18 Dec 2011 14:48:08 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-68338</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ Note that the first section head should read "Combustion: Fuel + Oxygen + Heat --› Fire" with an arrow between Heat and Fire. ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-71230</link>
      <pubDate>Tue, 06 Mar 2012 22:06:20 -0800</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-71230</guid>
    </item>
    <item>
      <title>By Dr. Michael J. Gourlay</title>
      <description><![CDATA[ Jamie,

Article 12 is up: http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-12/

It explains and repairs jerkiness.
 ]]></description>
      <link>http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-71589</link>
      <pubDate>Thu, 15 Mar 2012 14:32:39 -0700</pubDate>
      <guid isPermaLink="true">http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-11/#comment-71589</guid>
    </item>
  </channel></rss>
