Gas Advect

Gas Advect

Gas Advect CL

Gas Advect Field

Advection Method

Advection Type(Velocity goes (-1,-0.5)cell to sample midd point of one upper low)

BFECC calculate error by (original*3-past)/2 at subtract_error_term. custom is modified to be (original-past)

Post-Multi can be 1/(ch("dstpremul")-1)

Dest Pre-Mult will be between 3 to 2(2 is too much, 3 is same as default. 2.5 may be the better results)

Advection method from "advect.h"

// Single Euler step.

void stepEuler(vector pos; float dt; vector vel)

{

pos += dt * vel;

}

// Single step of Midpoint. This midpoint formula matches the GasAdvect DOP.

void stepMidpoint(vector pos; const string input; const string vname; const float dt; const vector vel)

{

vector midpos = pos + dt * vel;

// Take another step of the same time value.

vector V1 = volumesamplev(input, vname, midpos);

vector endpos = midpos + dt * V1;

// Average the last pos with end pos to get the midpoint

// answer for a single step.

pos += endpos;

pos *= 0.5;

}

// Single step of RK3. This RK3 formula matches vdb::tools::VelocityIntegrator

// and the VDB Advect Points SOP as of VDB 3.0.

void stepRK3(vector pos; const string input; const string vname; const float dt; const vector V0)

{

vector V1 = volumesamplev(input, vname, pos + (0.5 * dt) * V0);

vector V2 = volumesamplev(input, vname, pos + dt * (2 * V1 - V0));

pos += (dt / 6) * (V0 + 4 * V1 + V2);

}

// Single step of RK4. This RK4 formula matches vdb::tools::VelocityIntegrator

// and the VDB Advect Points SOP as of VDB 3.0.

void stepRK4(vector pos; const string input; const string vname; const float dt; const vector V0)

{

vector V1 = volumesamplev(input, vname, pos + (0.5 * dt) * V0);

vector V2 = volumesamplev(input, vname, pos + (0.5 * dt) * V1);

vector V3 = volumesamplev(input, vname, pos + dt * V2);

pos += (dt / 6) * (V0 + 2 * (V1 + V2) + V3);

}

// Advect the position in the specified volume according to the supplied

// cfl condition using the specified integration method.

void advectTrace(vector pos; const int method; const string input; const string vname; const float totaltime; const float cfl)

{

vector vel, invcfl;

float dt, timestep, multiplier, ratio, time = totaltime;

int iter = 0;

// Look up volume prim for voxel size calc.

int prim = findattribval(input, "primitive", "name", sprintf("%s.x", vname));

if (prim < 0)

prim = findattribval(input, "primitive", "name", vname);

// No integration functions will work if we can't find any volumes.

if (prim < 0)

return;

// Approximate voxel size.

vector voxsize = volumeindextopos(input, prim, 1) - volumeindextopos(input, prim, 0);

multiplier = (time < 0) ? -1 : 1;

time *= multiplier;

invcfl = 1.0F / (voxsize * cfl);

while (time > 0 && iter < MAX_TRACE)

{

// Assume the full timestep to start.

timestep = time;

// Get velocity at current position.

vel = volumesamplev(input, vname, pos);

// Determine our timestep to obey CFL.

ratio = max(abs(timestep * vel * invcfl));

if (ratio > 1.0)

timestep /= ratio;

// Integrate.

dt = timestep * multiplier;

if (method == 1)

stepEuler(pos, dt, vel);

else if (method == 2)

stepMidpoint(pos, input, vname, dt, vel);

else if (method == 3)

stepRK3(pos, input, vname, dt, vel);

else if (method == 4)

stepRK4(pos, input, vname, dt, vel);

time -= timestep;

iter++;

}

}