25 public Vec3 m_delta; // cell dimensions
27 private Vec3 m_externalAcceleration;
28 public Vec3 m_domainMin;
29 public Vec3 m_domainMax;
33 public float m_densityCoeff;
34 public float m_pressureCoeff;
35 public float m_viscosityCoeff;
40 public int m_frameNum;
42 public Cell[][][] m_cells;
43 public Cell[][][] m_cells2;
44 public HashMap m_neighCells; // neighbour cells
48 public Grid(int _id, int _sx, int _sy, int _sz, int _ex, int _ey, int _ez,
49 float _h, float _hSq, Vec3 _delta,
50 float _densityCoeff, float _pressureCoeff, float _viscosityCoeff,
51 int _nx, int _ny, int _nz, int _frameNum) {
59 this.m_delta = _delta;
60 this.m_externalAcceleration = new Vec3(0.f, -9.8f, 0.f);
61 this.m_domainMin = new Vec3(-0.065f, -0.08f, -0.065f);
62 this.m_domainMax = new Vec3(0.065f, 0.1f, 0.065f);
65 this.m_densityCoeff = _densityCoeff;
66 this.m_pressureCoeff = _pressureCoeff;
67 this.m_viscosityCoeff = _viscosityCoeff;
71 this.m_frameNum = _frameNum;
72 this.m_cells = new Cell[_ex-_sx][_ey-_sy][_ez-_sz];
73 this.m_cells2 = new Cell[_ex-_sx][_ey-_sy][_ez-_sz];
74 this.m_neighCells = new HashMap();
77 public void initCells(Cell[][][] _cells) {
78 for(int ix = 0; ix < this.m_ex - this.m_sx; ix++) {
79 for(int iy = 0; iy < this.m_ey - this.m_sy; iy++) {
80 for(int iz = 0; iz < this.m_ez - this.m_sz; iz++) {
81 this.m_cells2[ix][iy][iz] =
82 _cells[ix+this.m_sx][iy+this.m_sy][iz+this.m_sz];
83 this.m_cells[ix][iy][iz] =
84 new Cell(this.m_cells2[ix][iy][iz].m_id);
90 public void initNeighCells(Cell[][][] _cells, PSFADemo _psfaDemo) {
91 for(int iz = 0; iz < this.m_ez; iz = this.m_ez - 1) {
92 for(int iy = 0; iy < this.m_ey; iy++) {
93 for(int ix = 0; ix < this.m_ex; ix++) {
94 for(int dk = -1; dk <= 1; ++dk) {
95 for(int dj = -1; dj <= 1; ++dj) {
96 for(int di = -1; di <= 1; ++di) {
97 int ci = ix + this.m_sx + di;
98 int cj = iy + this.m_sy + dj;
99 int ck = iz + this.m_sz + dk;
103 } else if(ci > (this.m_nx-1)) {
108 } else if(cj > (this.m_ny-1)) {
113 } else if(ck > (this.m_nz-1)) {
117 if( ci < this.m_sx || ci >= this.m_ex ||
118 cj < this.m_sy || cj >= this.m_ey ||
119 ck < this.m_sz || ck >= this.m_ez ) {
120 Integer index = new Integer((ck*this.m_ny
121 + cj)*this.m_nx + ci);
122 if(!this.m_neighCells.containsKey(index)) {
123 this.m_neighCells.put(index,
124 new Cell(index.intValue()));
126 _psfaDemo.addBorderCells(index.intValue());
135 for(int iy = 0; iy < this.m_ey; iy = this.m_ey - 1) {
136 for(int iz = 0; iz < this.m_ez; iz++) {
137 for(int ix = 0; ix < this.m_ex; ix++) {
138 for(int dk = -1; dk <= 1; ++dk) {
139 for(int dj = -1; dj <= 1; ++dj) {
140 for(int di = -1; di <= 1; ++di) {
141 int ci = ix + this.m_sx + di;
142 int cj = iy + this.m_sy + dj;
143 int ck = iz + this.m_sz + dk;
147 } else if(ci > (this.m_nx-1)) {
152 } else if(cj > (this.m_ny-1)) {
157 } else if(ck > (this.m_nz-1)) {
161 if( ci < this.m_sx || ci >= this.m_ex ||
162 cj < this.m_sy || cj >= this.m_ey ||
163 ck < this.m_sz || ck >= this.m_ez ) {
164 Integer index = new Integer((ck*this.m_ny
165 + cj)*this.m_nx + ci);
166 if(!this.m_neighCells.containsKey(index)) {
167 this.m_neighCells.put(index,
168 new Cell(index.intValue()));
170 _psfaDemo.addBorderCells(index.intValue());
179 for(int ix = 0; ix < this.m_ex; ix = this.m_ex - 1) {
180 for(int iy = 0; iy < this.m_ey; iy++) {
181 for(int iz = 0; iz < this.m_ez; iz++) {
182 for(int dk = -1; dk <= 1; ++dk) {
183 for(int dj = -1; dj <= 1; ++dj) {
184 for(int di = -1; di <= 1; ++di) {
185 int ci = ix + this.m_sx + di;
186 int cj = iy + this.m_sy + dj;
187 int ck = iz + this.m_sz + dk;
191 } else if(ci > (this.m_nx-1)) {
196 } else if(cj > (this.m_ny-1)) {
201 } else if(ck > (this.m_nz-1)) {
205 if( ci < this.m_sx || ci >= this.m_ex ||
206 cj < this.m_sy || cj >= this.m_ey ||
207 ck < this.m_sz || ck >= this.m_ez ) {
208 Integer index = new Integer((ck*this.m_ny
209 + cj)*this.m_nx + ci);
210 if(!this.m_neighCells.containsKey(index)) {
211 this.m_neighCells.put(index,
212 new Cell(index.intValue()));
214 _psfaDemo.addBorderCells(index.intValue());
224 public void ClearParticlesMT() {
225 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
226 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
227 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
228 this.m_cells[ix][iy][iz].m_numPars = 0;
233 HashMapIterator it_values = this.m_neighCells.iterator(1);
234 while(it_values.hasNext()) {
235 Cell value = (Cell)it_values.next();
240 public void RebuildGridMT() {
241 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
242 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
243 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
244 Cell cell2 = this.m_cells2[ix][iy][iz];
245 int np2 = cell2.m_numPars;
246 for(int j = 0; j < np2; ++j) {
247 int ci = (int)((cell2.m_p[j].m_x - this.m_domainMin.m_x)
249 int cj = (int)((cell2.m_p[j].m_y - this.m_domainMin.m_y)
251 int ck = (int)((cell2.m_p[j].m_z - this.m_domainMin.m_z)
256 } else if(ci > (this.m_nx-1)) {
261 } else if(cj > (this.m_ny-1)) {
266 } else if(ck > (this.m_nz-1)) {
272 if( ci < this.m_sx || ci >= this.m_ex ||
273 cj < this.m_sy || cj >= this.m_ey ||
274 ck < this.m_sz || ck >= this.m_ez ) {
275 // move to a neighbour cell
276 int index = (ck*this.m_ny + cj)*this.m_nx + ci;
277 // this assumes that particles cannot travel more than
278 // one grid cell per time step
279 cell = (Cell)this.m_neighCells.get(
282 // move to a inside cell
283 cell = this.m_cells[ix][iy][iz];
286 cell.m_p[np].m_x = cell2.m_p[j].m_x;
287 cell.m_p[np].m_y = cell2.m_p[j].m_y;
288 cell.m_p[np].m_z = cell2.m_p[j].m_z;
289 cell.m_hv[np].m_x = cell2.m_hv[j].m_x;
290 cell.m_hv[np].m_y = cell2.m_hv[j].m_y;
291 cell.m_hv[np].m_z = cell2.m_hv[j].m_z;
292 cell.m_v[np].m_x = cell2.m_v[j].m_x;
293 cell.m_v[np].m_y = cell2.m_v[j].m_y;
294 cell.m_v[np].m_z = cell2.m_v[j].m_z;
302 private int InitNeighCellList(int ci, int cj, int ck, Vec3[] neighCells) {
303 int numNeighCells = 0;
305 for(int di = -1; di <= 1; ++di) {
306 for(int dj = -1; dj <= 1; ++dj) {
307 for(int dk = -1; dk <= 1; ++dk) {
311 if(ii >= 0 && ii < this.m_nx && jj >= 0 && jj < this.m_ny
312 && kk >= 0 && kk < this.m_nz) {
313 if( ii < this.m_sx || ii >= this.m_ex ||
314 jj < this.m_sy || jj >= this.m_ey ||
315 kk < this.m_sz || kk >= this.m_ez ) {
316 Integer index = new Integer((kk*this.m_ny + jj)
318 if(((Cell)(this.m_neighCells.get(index))).m_numPars
320 neighCells[numNeighCells] = new Vec3(ii,jj,kk);
324 if(this.m_cells[ii - this.m_sx]
326 [kk - this.m_sz].m_numPars != 0) {
327 neighCells[numNeighCells] = new Vec3(ii,jj,kk);
336 return numNeighCells;
339 public void InitDensitiesAndForcesMT() {
340 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
341 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
342 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
343 Cell cell = this.m_cells[ix][iy][iz];
344 int np = cell.m_numPars;
345 for(int j = 0; j < np; ++j) {
346 cell.m_density[j] = 0.f;
347 cell.m_a[j].m_x = this.m_externalAcceleration.m_x;
348 cell.m_a[j].m_y = this.m_externalAcceleration.m_y;
349 cell.m_a[j].m_z = this.m_externalAcceleration.m_z;
355 HashMapIterator it_values = this.m_neighCells.iterator(1);
356 while(it_values.hasNext()) {
357 Cell value = (Cell)it_values.next();
358 int np = value.m_numPars;
359 for(int j = 0; j < np; ++j) {
360 value.m_density[j] = 0.f;
361 value.m_a[j].m_x = this.m_externalAcceleration.m_x;
362 value.m_a[j].m_y = this.m_externalAcceleration.m_y;
363 value.m_a[j].m_z = this.m_externalAcceleration.m_z;
368 public void ComputeDensitiesMT() {
369 Vec3[] neighCells = new Vec3[27];
371 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
372 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
373 for(int ix = 0; ix < this.m_ex- this.m_sx; ++ix) {
374 Cell cell = this.m_cells[ix][iy][iz];
375 int np = cell.m_numPars;
377 int numNeighCells = InitNeighCellList(ix + this.m_sx,
382 for(int j = 0; j < np; ++j) {
383 for(int inc = 0; inc < numNeighCells; ++inc) {
384 Vec3 indexNeigh = neighCells[inc];
386 if( indexNeigh.m_x < this.m_sx ||
387 indexNeigh.m_x >= this.m_ex ||
388 indexNeigh.m_y < this.m_sy ||
389 indexNeigh.m_y >= this.m_ey ||
390 indexNeigh.m_z < this.m_sz ||
391 indexNeigh.m_z >= this.m_ez ) {
392 int index = (int)((indexNeigh.m_z*this.m_ny
393 + indexNeigh.m_y)*this.m_nx
395 neigh = (Cell)(this.m_neighCells.get(
396 new Integer(index)));
398 neigh = this.m_cells[(int)indexNeigh.m_x-this.m_sx]
399 [(int)indexNeigh.m_y-this.m_sy]
400 [(int)indexNeigh.m_z-this.m_sz];
402 int numNeighPars = neigh.m_numPars;
403 for(int iparNeigh = 0; iparNeigh < numNeighPars;
405 if(neigh.m_p[iparNeigh].isLess(cell.m_p[j])) {
406 float distSq = (cell.m_p[j].sub1
407 (neigh.m_p[iparNeigh])).
409 if(distSq < this.m_hSq) {
410 float t = this.m_hSq - distSq;
412 cell.m_density[j] += tc;
413 neigh.m_density[iparNeigh] += tc;
425 public void ComputeDensities2MT() {
426 float tc = this.m_hSq*this.m_hSq*this.m_hSq;
427 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
428 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
429 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
430 Cell cell = this.m_cells[ix][iy][iz];
431 int np = cell.m_numPars;
432 for(int j = 0; j < np; ++j) {
433 cell.m_density[j] += tc;
434 cell.m_density[j] *= this.m_densityCoeff;
441 public void ComputeForcesMT() {
442 float doubleRestDensity = 2000.f;
444 Vec3[] neighCells = new Vec3[27];
446 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
447 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
448 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
449 Cell cell = this.m_cells[ix][iy][iz];
450 int np = cell.m_numPars;
452 int numNeighCells = InitNeighCellList(ix + this.m_sx,
457 for(int j = 0; j < np; ++j) {
458 for(int inc = 0; inc < numNeighCells; ++inc) {
459 Vec3 indexNeigh = neighCells[inc];
461 if( indexNeigh.m_x < this.m_sx ||
462 indexNeigh.m_x >= this.m_ex ||
463 indexNeigh.m_y < this.m_sy ||
464 indexNeigh.m_y >= this.m_ey ||
465 indexNeigh.m_z < this.m_sz ||
466 indexNeigh.m_z >= this.m_ez ) {
467 int index = (int)((indexNeigh.m_z*this.m_ny
468 + indexNeigh.m_y)*this.m_nx
470 neigh = (Cell)(this.m_neighCells.get(
471 new Integer(index)));
473 neigh = this.m_cells[(int)indexNeigh.m_x-this.m_sx]
474 [(int)indexNeigh.m_y-this.m_sy]
475 [(int)indexNeigh.m_z-this.m_sz];
477 int numNeighPars = neigh.m_numPars;
478 for(int iparNeigh = 0; iparNeigh < numNeighPars;
480 if(neigh.m_p[iparNeigh].isLess(cell.m_p[j])) {
481 Vec3 disp = cell.m_p[j].sub1
482 (neigh.m_p[iparNeigh]);
483 float distSq = disp.GetLengthSq();
484 if(distSq < this.m_hSq) {
486 if(distSq > 1e-12f) {
489 float dist = Math.sqrtf(max);
490 float hmr = this.m_h - dist;
492 Vec3 acc = disp.mul1(
493 this.m_pressureCoeff).mul1(
496 neigh.m_density[iparNeigh] -
498 acc.add0(neigh.m_v[iparNeigh].sub1(
500 this.m_viscosityCoeff *
502 acc.div0(cell.m_density[j] *
503 neigh.m_density[iparNeigh]);
504 cell.m_a[j].add0(acc);
505 neigh.m_a[iparNeigh].sub0(acc);
517 public void ProcessCollisionsMT() {
518 float timeStep = 0.005f;
519 float parSize = 0.0002f;
520 float epsilon = 1e-10f;
521 float stiffness = 30000.f;
522 float damping = 128.f;
524 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
525 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
526 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
527 Cell cell = this.m_cells[ix][iy][iz];
528 int np = cell.m_numPars;
529 for(int j = 0; j < np; ++j) {
530 Vec3 pos = cell.m_p[j].add1(
531 cell.m_hv[j].mul1(timeStep));
533 float diff = parSize - (pos.m_x - this.m_domainMin.m_x);
535 cell.m_a[j].m_x += stiffness*diff
536 - damping*cell.m_v[j].m_x;
539 diff = parSize - (this.m_domainMax.m_x - pos.m_x);
541 cell.m_a[j].m_x -= stiffness*diff
542 + damping*cell.m_v[j].m_x;
545 diff = parSize - (pos.m_y - this.m_domainMin.m_y);
547 cell.m_a[j].m_y += stiffness*diff
548 - damping*cell.m_v[j].m_y;
551 diff = parSize - (this.m_domainMax.m_y - pos.m_y);
553 cell.m_a[j].m_y -= stiffness*diff
554 + damping*cell.m_v[j].m_y;
557 diff = parSize - (pos.m_z - this.m_domainMin.m_z);
559 cell.m_a[j].m_z += stiffness*diff
560 - damping*cell.m_v[j].m_z;
563 diff = parSize - (this.m_domainMax.m_z - pos.m_z);
565 cell.m_a[j].m_z -= stiffness*diff
566 + damping*cell.m_v[j].m_z;
574 public void AdvanceParticlesMT() {
575 float timeStep = 0.005f;
577 for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
578 for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
579 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
580 Cell cell = this.m_cells[ix][iy][iz];
581 int np = cell.m_numPars;
582 for(int j = 0; j < np; ++j) {
583 Vec3 v_half = cell.m_hv[j].add1(cell.m_a[j].mul1(
585 cell.m_p[j].add0(v_half.mul1(timeStep));
586 cell.m_v[j] = cell.m_hv[j].add1(v_half);
587 cell.m_v[j].mul0(0.5f);
588 cell.m_hv[j] = v_half;
595 public boolean isFinish() {
597 return (this.m_frameNum == 0);