12 #ifndef Versor_vsr_field_h
13 #define Versor_vsr_field_h
15 #include "vsr_cubicLattice.h"
16 #include "util/vsr_math.h"
17 #include "gfx/gfx_patch.h"
22 for (int i = 0; i < this->mNum; ++i) {
27 for (int i = 0; i < this->mWidth; ++i){\
28 for (int j = 0; j < this->mHeight; ++j){\
29 for (int k = 0; k < this->mDepth; ++k){\
30 int tidx = this->idx(i,j,k);
35 for (int i = 0; i < x.w(); ++i){\
36 for (int j = 0; j < x.h(); ++j){\
37 for (int k = 0; k < x.d(); ++k){\
38 int tidx = idx(i,j,k);
41 for (int i = 0; i < this->mWidth; ++i){\
42 double u = 1.0 * i/this->mWidth;\
43 for (int j = 0; j < this->mHeight; ++j){\
44 double v = 1.0 * j/this->mHeight;\
45 for (int k = 0; k < this->mDepth; ++k){\
46 double w = 1.0 * k/this->mDepth; \
47 int tidx = this->idx(i,j,k);
51 for (int i = 1; i < this->mWidth-1; ++i){ \
52 for (int j = 1; j < this->mHeight-1; ++j){ \
53 for (int k = 1; k < this->mDepth-1; ++k){ \
56 for (int i = 1; i < x.w()-1; ++i){ \
57 for (int j = 1; j < x.h()-1; ++j){ \
58 for (int k = 1; k < x.d()-1; ++k){ \
73 using GridType =
typename T::space::point;
80 T * dataPtr()
const {
return mData; }
81 void dataPtr( T* d ) { mData = d; }
84 void zero() { ITER mData[tidx] = T(0); ITEND }
86 Field(
int w=1,
int h=1,
int d=1,
double spacingX = 1.0,
double spacingY = 1.0,
double spacingZ = 1.0) :
87 CubicLattice<GridType>(w,h,d,spacingX,spacingY,spacingZ), mData( NULL )
94 Field& resize(
int w,
int h,
int d,
double spacingX = 1.0,
double spacingY = 1.0,
double spacingZ=1.0){
96 CubicLattice<GridType>::resize(w,h,d,spacingX,spacingY,spacingZ);
109 if (mData)
delete[] mData;
114 if (mData)
delete[] mData;
115 mData =
new T[this->mNum];
123 T&
at(
int w = 0,
int h = 0,
int d = 0) {
return mData[ this->
idx(w, h, d) ]; }
125 T
at(
int w = 0,
int h = 0,
int d = 0)
const {
return mData[ this->
idx(w, h, d) ]; }
130 mData[ tidx ] = this->mPoint[tidx].template copy<T>();
138 void reset() { init(); }
155 T euler2d(
const V& v){
156 V t = this->range2D(v);
157 return surf(t[0], t[1]);
162 T euler3d(
const V& v)
const{
164 return vol(t[0], t[1], t[2]);
169 T
surf(VSR_PRECISION u, VSR_PRECISION v){
177 return Interp::surface<T> (a,b,c,d, p.rw, p.rh);
180 T vol(VSR_PRECISION u, VSR_PRECISION v, VSR_PRECISION w)
const {
183 T a = mData[ p.a ]; T b = mData[ p.b ]; T c = mData[ p.c ]; T d = mData[ p.d ];
184 T e = mData[ p.e ]; T f = mData[ p.f ]; T g = mData[ p.g ]; T h = mData[ p.h ];
185 return Interp::volume<T> (a,b,c,d,e,f,g,h, p.rw, p.rh, p.rd );
189 T vol(
const A& a){
return vol(a[0],a[1],a[2]); }
193 vector<V> contour(
const V& v,
int num,
double force){
196 for (
int i = 0; i < num; ++i){
198 tv += euler3d(tv) * force;
215 for (
int i = 1; i < 7; ++i){
216 if (this->nbr(idx)[i] != -1 ) tdx += mData[ this->nbr(idx)[i] ];
221 T diffNbrs (
int idx)
const {
223 tdx += mData[ this->nbr(idx).xr ] - mData [ this->nbr(idx).xl ];
224 tdx += mData[ this->nbr(idx).yt ] - mData [ this->nbr(idx).yb ];
225 tdx += mData[ this->nbr(idx).zb ] - mData [ this->nbr(idx).zf ];
230 T diffXNbrs (
int ix)
const{
231 return mData[ this->nbr(ix).xr ] - mData [ this->nbr(ix).xl ];;
234 T diffYNbrs (
int ix)
const{
235 return mData[ this->nbr(ix).yt ] - mData [ this-> nbr(ix).yb ];
238 T diffZNbrs (
int ix)
const{
239 return mData[ this->nbr(ix).zb ] - mData [ this->nbr(ix).zf ];
242 T dx(
int ix)
const{
return diffXNbrs(ix); }
243 T dy(
int ix)
const{
return diffYNbrs(ix); }
244 T dz(
int ix)
const{
return diffZNbrs(ix); }
262 double tensNbrs (
int idx)
const {
264 tdx += mData[ this->nbr(idx).xr ][0] - mData [ this->nbr(idx).xl ][0];
265 tdx += mData[ this->nbr(idx).yt ][1] - mData [ this->nbr(idx).yb ][1];
266 tdx += mData[ this->nbr(idx).zb ][2] - mData [ this->nbr(idx).zf ][2];
271 double tensNbrsWt(
int idx)
const {
272 double tdx;
double ww = 1.0 / this->w();
double wh = 1.0/this->h();
double wd = 1.0/this->d();
273 tdx += ( mData[ this->nbr(idx).xr ][0] - mData [ this->nbr(idx).xl ][0] ) * ww;
274 tdx += ( mData[ this->nbr(idx).yt ][1] - mData [ this->nbr(idx).yb ][1] ) * wh;
275 tdx += ( mData[ this->nbr(idx).zb ][2] - mData [ this->nbr(idx).zf ][2] ) * wd;
281 double tensNbrsRwt(
int idx)
const {
283 tdx += ( mData[ this->nbr(idx).xr ][0] - mData [ this->nbr(idx).xl ][0] ) * this-> w();
284 tdx += ( mData[ this->nbr(idx).yt ][1] - mData [ this->nbr(idx).yb ][1] ) * this-> h();
285 tdx += ( mData[ this->nbr(idx).zb ][2] - mData [ this->nbr(idx).zf ][2] ) * this-> d();
293 for (
int m = 0; m < it; ++m){
295 int ix = this->
idx(i,j,k);
297 mData[ix] = (prev[ix] +
td ) / 6.0;
300 boundaryConditions(0);
305 void diffuse(
const Field& prev,
double diffRate,
bool bounded,
bool ref){
309 double rate = diffRate * .001 * this->mNum;
313 for (
int k = 0; k < it; ++k){
315 for (
int i = 0; i < this->num(); ++i){
322 mData[i] = ( prev[i] +
td ) / (1 + 6*rate);
329 for (
int n = 0; n < it; ++n){
332 int tdx = this->
idx(i,j,k);
337 mData[tdx] = ( prev[tdx] +
td ) / (1 + 6*rate);
340 boundaryConditions(ref);
352 int tidx = this->
idx(i,j,k);
353 auto p = this->mPoint[ tidx ] + f.euler3d( this->mPoint[tidx] ) * -dt0;
354 mData[tidx] = prev.euler3d( p );
357 boundaryConditions(ref);
367 int ix = this->
idx(i,j,k);
368 mData[ix] = f.tensNbrsWt(ix) * ( -.5 );
370 boundaryConditions(0);
375 Field& swap( Field& f ){
376 T * tmp = dataPtr(); dataPtr( f.dataPtr() ); f.dataPtr( tmp );
382 Field& operator * ( N val ) { ITN mData[i] *= val; END
return *
this; }
390 void boundaryConditions(
bool ref){
392 for (
int i = 0; i < this->mFace.size(); ++i){
393 int ix = this->mFace[i];
395 n = this->mNbr[ ix ];
401 if (type & LEFT) mData[ix] += ref ? -mData[n.xr] : mData[n.xr];
402 if (type & RIGHT) mData[ix] += ref ? -mData[n.xl] : mData[n.xl];
403 if (type & TOP) mData[ix] += ref ? -mData[n.yb] : mData[n.yb];
404 if (type & BOTTOM) mData[ix] += ref ? -mData[n.yt] : mData[n.yt];
405 if (type & BACK) mData[ix] += ref ? -mData[n.zf] : mData[n.zf];
406 if (type & FRONT) mData[ix] += ref ? -mData[n.zb] : mData[n.zb];
408 mData[ix] /= Math::bitcount(type);
void gsSolver(const Field &prev)
Guass Siedel Relaxation Solver Using a Previous Field State.
Definition: vsr_field.h:290
VPatch vidx(double u, double v, double w) const
Volume Index at u,v,w [0-1].
Definition: vsr_cubicLattice.h:412
void diffuse(const Field &prev, double diffRate, bool bounded, bool ref)
Backwards Diffusion Using a Previous Field State.
Definition: vsr_field.h:305
T & operator[](int i)
Set Data by Index.
Definition: vsr_field.h:119
Volume Patch Info Container for Euler integration of a 3d Field.
Definition: vsr_patch.h:54
A Basic 3D Field (slowly porting this over from the now defunct vsr_lattice class) Use to Evaluate Ne...
Definition: vsr_field.h:67
double td() const
Total Depth.
Definition: vsr_cubicLattice.h:144
Info Container for Euler integration of a 2d Field.
Definition: vsr_patch.h:44
T & at(int w=0, int h=0, int d=0)
Set Data by Coordinate.
Definition: vsr_field.h:123
void alloc()
Allocate Memory.
Definition: vsr_field.h:113
void advect(const Field &prev, const Field< B > &f, double dt, bool ref)
Backwards Advection Using a Previous Field State prev and Based on a Velocity Frame f...
Definition: vsr_field.h:348
T at(int w=0, int h=0, int d=0) const
Get Data by Coordinate.
Definition: vsr_field.h:125
Discretized Volume Indexing (Isometric Cubic Lattice w/o data)
Definition: vsr_cubicLattice.h:61
int idx(int i, int j, int k=0) const
Get Index In Array.
Definition: vsr_cubicLattice.h:113
T & dataAt(const B &p)
Random Vector in Field.
Definition: vsr_field.h:148
the versor library namespace
Definition: vsr_algebra.h:29
Patch surfIdx(double u, double v)
Indicex of surface at u, v [0, 1].
Definition: vsr_cubicLattice.h:389
Vxl vxlAt(const V &tv) const
Voxel of Vector v.
Definition: vsr_cubicLattice.h:219
T sumNbrs(int idx) const
Get QUADRIC Interpolated Data at eval u,v [0-1].
Definition: vsr_field.h:213
void zero()
Zero Out All Data.
Definition: vsr_field.h:84
T surf(VSR_PRECISION u, VSR_PRECISION v)
Get BILINEAR Interpolated Data at eval u,v [0-1.0].
Definition: vsr_field.h:169