diff options
author | Sebastián Barschkis <sebbas@sebbas.org> | 2019-12-16 17:51:02 +0300 |
---|---|---|
committer | Sebastián Barschkis <sebbas@sebbas.org> | 2019-12-16 18:37:57 +0300 |
commit | 7bd3d2be080720a5b40b6898e6588e937497201f (patch) | |
tree | 087b9996b14a9e5aa1c5ddadeab2aec8f566056b /intern/smoke | |
parent | d27ccf990c2b957a10f4676e3153f907829a4b22 (diff) |
Mantaflow [Part 5]: Update other /intern packages
Cycles needs some smaller updates so that the up-res smoke wavelet noise and the liquid mesh speed vector export work correctly.
Reviewed By: mont29
Maniphest Tasks: T59995
Differential Revision: https://developer.blender.org/D3854
Diffstat (limited to 'intern/smoke')
50 files changed, 0 insertions, 15946 deletions
diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt deleted file mode 100644 index 5c8e495fa93..00000000000 --- a/intern/smoke/CMakeLists.txt +++ /dev/null @@ -1,99 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# ***** END GPL LICENSE BLOCK ***** - -set(INC - intern - ../memutil -) - -set(INC_SYS - ${BULLET_INCLUDE_DIRS} - ${PNG_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} -) - -set(SRC - intern/EIGENVALUE_HELPER.cpp - intern/FLUID_3D.cpp - intern/FLUID_3D_SOLVERS.cpp - intern/FLUID_3D_STATIC.cpp - intern/LU_HELPER.cpp - intern/SPHERE.cpp - intern/WTURBULENCE.cpp - intern/smoke_API.cpp - - extern/smoke_API.h - intern/EIGENVALUE_HELPER.h - intern/FFT_NOISE.h - intern/FLUID_3D.h - intern/IMAGE.h - intern/INTERPOLATE.h - intern/LU_HELPER.h - intern/MERSENNETWISTER.h - intern/OBSTACLE.h - intern/SPHERE.h - intern/VEC3.h - intern/WAVELET_NOISE.h - intern/WTURBULENCE.h - intern/tnt/jama_eig.h - intern/tnt/jama_lu.h - intern/tnt/tnt.h - intern/tnt/tnt_array1d.h - intern/tnt/tnt_array1d_utils.h - intern/tnt/tnt_array2d.h - intern/tnt/tnt_array2d_utils.h - intern/tnt/tnt_array3d.h - intern/tnt/tnt_array3d_utils.h - intern/tnt/tnt_cmat.h - intern/tnt/tnt_fortran_array1d.h - intern/tnt/tnt_fortran_array1d_utils.h - intern/tnt/tnt_fortran_array2d.h - intern/tnt/tnt_fortran_array2d_utils.h - intern/tnt/tnt_fortran_array3d.h - intern/tnt/tnt_fortran_array3d_utils.h - intern/tnt/tnt_i_refvec.h - intern/tnt/tnt_math_utils.h - intern/tnt/tnt_sparse_matrix_csr.h - intern/tnt/tnt_stopwatch.h - intern/tnt/tnt_subscript.h - intern/tnt/tnt_vec.h - intern/tnt/tnt_version.h -) - -set(LIB -) - -# quiet -Wundef -add_definitions(-DDDF_DEBUG=0) - -if(WITH_OPENMP) - add_definitions(-DPARALLEL=1) -else() - add_definitions(-DPARALLEL=0) -endif() - -if(WITH_FFTW3) - add_definitions(-DWITH_FFTW3) - list(APPEND INC_SYS - ${FFTW3_INCLUDE_DIRS} - ) -endif() - -blender_add_lib(bf_intern_smoke "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h deleted file mode 100644 index 169f679526c..00000000000 --- a/intern/smoke/extern/smoke_API.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 by Daniel Genrich - * All rights reserved. - */ - -/** \file - * \ingroup smoke - */ - - -#ifndef SMOKE_API_H_ -#define SMOKE_API_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct FLUID_3D; - -// low res -struct FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors); -void smoke_free(struct FLUID_3D *fluid); - -void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, - float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp); -void smoke_step(struct FLUID_3D *fluid, float gravity[3], float dtSubdiv); - -float *smoke_get_density(struct FLUID_3D *fluid); -float *smoke_get_flame(struct FLUID_3D *fluid); -float *smoke_get_fuel(struct FLUID_3D *fluid); -float *smoke_get_react(struct FLUID_3D *fluid); -float *smoke_get_color_r(struct FLUID_3D *fluid); -float *smoke_get_color_g(struct FLUID_3D *fluid); -float *smoke_get_color_b(struct FLUID_3D *fluid); -void smoke_get_rgba(struct FLUID_3D *fluid, float *data, int sequential); -void smoke_get_rgba_from_density(struct FLUID_3D *fluid, float color[3], float *data, int sequential); -float *smoke_get_heat(struct FLUID_3D *fluid); -float *smoke_get_velocity_x(struct FLUID_3D *fluid); -float *smoke_get_velocity_y(struct FLUID_3D *fluid); -float *smoke_get_velocity_z(struct FLUID_3D *fluid); - -/* Moving obstacle velocity provided by blender */ -void smoke_get_ob_velocity(struct FLUID_3D *fluid, float **x, float **y, float **z); - -float *smoke_get_force_x(struct FLUID_3D *fluid); -float *smoke_get_force_y(struct FLUID_3D *fluid); -float *smoke_get_force_z(struct FLUID_3D *fluid); - -unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid); - -size_t smoke_get_index(int x, int max_x, int y, int max_y, int z); -size_t smoke_get_index2d(int x, int max_x, int y); - -void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log); - -// wavelet turbulence functions -struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, const char *noisefile_path, int use_fire, int use_colors); -void smoke_turbulence_free(struct WTURBULENCE *wt); -void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid); - -float *smoke_turbulence_get_density(struct WTURBULENCE *wt); -float *smoke_turbulence_get_color_r(struct WTURBULENCE *wt); -float *smoke_turbulence_get_color_g(struct WTURBULENCE *wt); -float *smoke_turbulence_get_color_b(struct WTURBULENCE *wt); -void smoke_turbulence_get_rgba(struct WTURBULENCE *wt, float *data, int sequential); -void smoke_turbulence_get_rgba_from_density(struct WTURBULENCE *wt, float color[3], float *data, int sequential); -float *smoke_turbulence_get_flame(struct WTURBULENCE *wt); -float *smoke_turbulence_get_fuel(struct WTURBULENCE *wt); -float *smoke_turbulence_get_react(struct WTURBULENCE *wt); -void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res); -int smoke_turbulence_get_cells(struct WTURBULENCE *wt); -void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type, const char *noisefile_path); -void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength); -void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log); - -/* export */ -void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, float **heatold, - float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles); -void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, - float **r, float **g, float **b, float **tcu, float **tcv, float **tcw); - -/* data fields */ -int smoke_has_heat(struct FLUID_3D *fluid); -int smoke_has_fuel(struct FLUID_3D *fluid); -int smoke_has_colors(struct FLUID_3D *fluid); -int smoke_turbulence_has_fuel(struct WTURBULENCE *wt); -int smoke_turbulence_has_colors(struct WTURBULENCE *wt); - -void smoke_ensure_heat(struct FLUID_3D *fluid); -void smoke_ensure_fire(struct FLUID_3D *fluid, struct WTURBULENCE *wt); -void smoke_ensure_colors(struct FLUID_3D *fluid, struct WTURBULENCE *wt, float init_r, float init_g, float init_b); - -#ifdef __cplusplus -} -#endif - -#endif /* SMOKE_API_H_ */ diff --git a/intern/smoke/intern/EIGENVALUE_HELPER.cpp b/intern/smoke/intern/EIGENVALUE_HELPER.cpp deleted file mode 100644 index fbfd6d3bd22..00000000000 --- a/intern/smoke/intern/EIGENVALUE_HELPER.cpp +++ /dev/null @@ -1,888 +0,0 @@ -/** \file - * \ingroup smoke - */ - -#include "EIGENVALUE_HELPER.h" - - -void Eigentred2(sEigenvalue& eval) { - - // This is derived from the Algol procedures tred2 by - // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for - // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - - int n=eval.n; - - for (int j = 0; j < n; j++) { - eval.d[j] = eval.V[n-1][j]; - } - - // Householder reduction to tridiagonal form. - - for (int i = n-1; i > 0; i--) { - - // Scale to avoid under/overflow. - - float scale = 0.0; - float h = 0.0; - for (int k = 0; k < i; k++) { - scale = scale + fabs(eval.d[k]); - } - if (scale == 0.0f) { - eval.e[i] = eval.d[i-1]; - for (int j = 0; j < i; j++) { - eval.d[j] = eval.V[i-1][j]; - eval.V[i][j] = 0.0; - eval.V[j][i] = 0.0; - } - } else { - - // Generate Householder vector. - - for (int k = 0; k < i; k++) { - eval.d[k] /= scale; - h += eval.d[k] * eval.d[k]; - } - float f = eval.d[i-1]; - float g = sqrt(h); - if (f > 0) { - g = -g; - } - eval.e[i] = scale * g; - h = h - f * g; - eval.d[i-1] = f - g; - for (int j = 0; j < i; j++) { - eval.e[j] = 0.0; - } - - // Apply similarity transformation to remaining columns. - - for (int j = 0; j < i; j++) { - f = eval.d[j]; - eval.V[j][i] = f; - g = eval.e[j] + eval.V[j][j] * f; - for (int k = j+1; k <= i-1; k++) { - g += eval.V[k][j] * eval.d[k]; - eval.e[k] += eval.V[k][j] * f; - } - eval.e[j] = g; - } - f = 0.0; - for (int j = 0; j < i; j++) { - eval.e[j] /= h; - f += eval.e[j] * eval.d[j]; - } - float hh = f / (h + h); - for (int j = 0; j < i; j++) { - eval.e[j] -= hh * eval.d[j]; - } - for (int j = 0; j < i; j++) { - f = eval.d[j]; - g = eval.e[j]; - for (int k = j; k <= i-1; k++) { - eval.V[k][j] -= (f * eval.e[k] + g * eval.d[k]); - } - eval.d[j] = eval.V[i-1][j]; - eval.V[i][j] = 0.0; - } - } - eval.d[i] = h; - } - - // Accumulate transformations. - - for (int i = 0; i < n-1; i++) { - eval.V[n-1][i] = eval.V[i][i]; - eval.V[i][i] = 1.0; - float h = eval.d[i+1]; - if (h != 0.0f) { - for (int k = 0; k <= i; k++) { - eval.d[k] = eval.V[k][i+1] / h; - } - for (int j = 0; j <= i; j++) { - float g = 0.0; - for (int k = 0; k <= i; k++) { - g += eval.V[k][i+1] * eval.V[k][j]; - } - for (int k = 0; k <= i; k++) { - eval.V[k][j] -= g * eval.d[k]; - } - } - } - for (int k = 0; k <= i; k++) { - eval.V[k][i+1] = 0.0; - } - } - for (int j = 0; j < n; j++) { - eval.d[j] = eval.V[n-1][j]; - eval.V[n-1][j] = 0.0; - } - eval.V[n-1][n-1] = 1.0; - eval.e[0] = 0.0; -} - -void Eigencdiv(sEigenvalue& eval, float xr, float xi, float yr, float yi) { - float r,d; - if (fabs(yr) > fabs(yi)) { - r = yi/yr; - d = yr + r*yi; - eval.cdivr = (xr + r*xi)/d; - eval.cdivi = (xi - r*xr)/d; - } else { - r = yr/yi; - d = yi + r*yr; - eval.cdivr = (r*xr + xi)/d; - eval.cdivi = (r*xi - xr)/d; - } - } - -void Eigentql2 (sEigenvalue& eval) { - - // This is derived from the Algol procedures tql2, by - // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for - // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - - int n=eval.n; - - for (int i = 1; i < n; i++) { - eval.e[i-1] = eval.e[i]; - } - eval.e[n-1] = 0.0; - - float f = 0.0; - float tst1 = 0.0; - float eps = pow(2.0,-52.0); - for (int l = 0; l < n; l++) { - - // Find small subdiagonal element - - tst1 = max(tst1,fabs(eval.d[l]) + fabs(eval.e[l])); - int m = l; - - // Original while-loop from Java code - while (m < n) { - if (fabs(eval.e[m]) <= eps*tst1) { - break; - } - m++; - } - - - // If m == l, d[l] is an eigenvalue, - // otherwise, iterate. - - if (m > l) { - int iter = 0; - do { - iter = iter + 1; // (Could check iteration count here.) - - // Compute implicit shift - - float g = eval.d[l]; - float p = (eval.d[l+1] - g) / (2.0f * eval.e[l]); - float r = hypot(p,1.0); - if (p < 0) { - r = -r; - } - eval.d[l] = eval.e[l] / (p + r); - eval.d[l+1] = eval.e[l] * (p + r); - float dl1 = eval.d[l+1]; - float h = g - eval.d[l]; - for (int i = l+2; i < n; i++) { - eval.d[i] -= h; - } - f = f + h; - - // Implicit QL transformation. - - p = eval.d[m]; - float c = 1.0; - float c2 = c; - float c3 = c; - float el1 = eval.e[l+1]; - float s = 0.0; - float s2 = 0.0; - for (int i = m-1; i >= l; i--) { - c3 = c2; - c2 = c; - s2 = s; - g = c * eval.e[i]; - h = c * p; - r = hypot(p,eval.e[i]); - eval.e[i+1] = s * r; - s = eval.e[i] / r; - c = p / r; - p = c * eval.d[i] - s * g; - eval.d[i+1] = h + s * (c * g + s * eval.d[i]); - - // Accumulate transformation. - - for (int k = 0; k < n; k++) { - h = eval.V[k][i+1]; - eval.V[k][i+1] = s * eval.V[k][i] + c * h; - eval.V[k][i] = c * eval.V[k][i] - s * h; - } - } - p = -s * s2 * c3 * el1 * eval.e[l] / dl1; - eval.e[l] = s * p; - eval.d[l] = c * p; - - // Check for convergence. - - } while (fabs(eval.e[l]) > eps*tst1); - } - eval.d[l] = eval.d[l] + f; - eval.e[l] = 0.0; - } - - // Sort eigenvalues and corresponding vectors. - - for (int i = 0; i < n-1; i++) { - int k = i; - float p = eval.d[i]; - for (int j = i+1; j < n; j++) { - if (eval.d[j] < p) { - k = j; - p = eval.d[j]; - } - } - if (k != i) { - eval.d[k] = eval.d[i]; - eval.d[i] = p; - for (int j = 0; j < n; j++) { - p = eval.V[j][i]; - eval.V[j][i] = eval.V[j][k]; - eval.V[j][k] = p; - } - } - } -} - -void Eigenorthes (sEigenvalue& eval) { - - // This is derived from the Algol procedures orthes and ortran, - // by Martin and Wilkinson, Handbook for Auto. Comp., - // Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutines in EISPACK. - - int n=eval.n; - - int low = 0; - int high = n-1; - - for (int m = low+1; m <= high-1; m++) { - - // Scale column. - - float scale = 0.0; - for (int i = m; i <= high; i++) { - scale = scale + fabs(eval.H[i][m-1]); - } - if (scale != 0.0f) { - - // Compute Householder transformation. - - float h = 0.0; - for (int i = high; i >= m; i--) { - eval.ort[i] = eval.H[i][m-1]/scale; - h += eval.ort[i] * eval.ort[i]; - } - float g = sqrt(h); - if (eval.ort[m] > 0) { - g = -g; - } - h = h - eval.ort[m] * g; - eval.ort[m] = eval.ort[m] - g; - - // Apply Householder similarity transformation - // H = (I-u*u'/h)*H*(I-u*u')/h) - - for (int j = m; j < n; j++) { - float f = 0.0; - for (int i = high; i >= m; i--) { - f += eval.ort[i]*eval.H[i][j]; - } - f = f/h; - for (int i = m; i <= high; i++) { - eval.H[i][j] -= f*eval.ort[i]; - } - } - - for (int i = 0; i <= high; i++) { - float f = 0.0; - for (int j = high; j >= m; j--) { - f += eval.ort[j]*eval.H[i][j]; - } - f = f/h; - for (int j = m; j <= high; j++) { - eval.H[i][j] -= f*eval.ort[j]; - } - } - eval.ort[m] = scale*eval.ort[m]; - eval.H[m][m-1] = scale*g; - } - } - - // Accumulate transformations (Algol's ortran). - - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - eval.V[i][j] = (i == j ? 1.0 : 0.0); - } - } - - for (int m = high-1; m >= low+1; m--) { - if (eval.H[m][m-1] != 0.0f) { - for (int i = m+1; i <= high; i++) { - eval.ort[i] = eval.H[i][m-1]; - } - for (int j = m; j <= high; j++) { - float g = 0.0; - for (int i = m; i <= high; i++) { - g += eval.ort[i] * eval.V[i][j]; - } - // Double division avoids possible underflow - g = (g / eval.ort[m]) / eval.H[m][m-1]; - for (int i = m; i <= high; i++) { - eval.V[i][j] += g * eval.ort[i]; - } - } - } - } - } - -void Eigenhqr2 (sEigenvalue& eval) { - - // This is derived from the Algol procedure hqr2, - // by Martin and Wilkinson, Handbook for Auto. Comp., - // Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - - // Initialize - - int nn = eval.n; - int n = nn-1; - int low = 0; - int high = nn-1; - float eps = pow(2.0,-52.0); - float exshift = 0.0; - float p=0,q=0,r=0,s=0,z=0,t,w,x,y; - - // Store roots isolated by balanc and compute matrix norm - - float norm = 0.0; - for (int i = 0; i < nn; i++) { - if ((i < low) || (i > high)) { - eval.d[i] = eval.H[i][i]; - eval.e[i] = 0.0; - } - for (int j = max(i-1,0); j < nn; j++) { - norm = norm + fabs(eval.H[i][j]); - } - } - - // Outer loop over eigenvalue index - - int iter = 0; - int totIter = 0; - while (n >= low) { - - // NT limit no. of iterations - totIter++; - if(totIter>100) { - //if(totIter>15) std::cout<<"!!!!iter ABORT !!!!!!! "<<totIter<<"\n"; - // NT hack/fix, return large eigenvalues - for (int i = 0; i < nn; i++) { - eval.d[i] = 10000.; - eval.e[i] = 10000.; - } - return; - } - - // Look for single small sub-diagonal element - - int l = n; - while (l > low) { - s = fabs(eval.H[l-1][l-1]) + fabs(eval.H[l][l]); - if (s == 0.0f) { - s = norm; - } - if (fabs(eval.H[l][l-1]) < eps * s) { - break; - } - l--; - } - - // Check for convergence - // One root found - - if (l == n) { - eval.H[n][n] = eval.H[n][n] + exshift; - eval.d[n] = eval.H[n][n]; - eval.e[n] = 0.0; - n--; - iter = 0; - - // Two roots found - - } else if (l == n-1) { - w = eval.H[n][n-1] * eval.H[n-1][n]; - p = (eval.H[n-1][n-1] - eval.H[n][n]) / 2.0f; - q = p * p + w; - z = sqrt(fabs(q)); - eval.H[n][n] = eval.H[n][n] + exshift; - eval.H[n-1][n-1] = eval.H[n-1][n-1] + exshift; - x = eval.H[n][n]; - - // float pair - - if (q >= 0) { - if (p >= 0) { - z = p + z; - } else { - z = p - z; - } - eval.d[n-1] = x + z; - eval.d[n] = eval.d[n-1]; - if (z != 0.0f) { - eval.d[n] = x - w / z; - } - eval.e[n-1] = 0.0; - eval.e[n] = 0.0; - x = eval.H[n][n-1]; - s = fabs(x) + fabs(z); - p = x / s; - q = z / s; - r = sqrt(p * p+q * q); - p = p / r; - q = q / r; - - // Row modification - - for (int j = n-1; j < nn; j++) { - z = eval.H[n-1][j]; - eval.H[n-1][j] = q * z + p * eval.H[n][j]; - eval.H[n][j] = q * eval.H[n][j] - p * z; - } - - // Column modification - - for (int i = 0; i <= n; i++) { - z = eval.H[i][n-1]; - eval.H[i][n-1] = q * z + p * eval.H[i][n]; - eval.H[i][n] = q * eval.H[i][n] - p * z; - } - - // Accumulate transformations - - for (int i = low; i <= high; i++) { - z = eval.V[i][n-1]; - eval.V[i][n-1] = q * z + p * eval.V[i][n]; - eval.V[i][n] = q * eval.V[i][n] - p * z; - } - - // Complex pair - - } else { - eval.d[n-1] = x + p; - eval.d[n] = x + p; - eval.e[n-1] = z; - eval.e[n] = -z; - } - n = n - 2; - iter = 0; - - // No convergence yet - - } else { - - // Form shift - - x = eval.H[n][n]; - y = 0.0; - w = 0.0; - if (l < n) { - y = eval.H[n-1][n-1]; - w = eval.H[n][n-1] * eval.H[n-1][n]; - } - - // Wilkinson's original ad hoc shift - - if (iter == 10) { - exshift += x; - for (int i = low; i <= n; i++) { - eval.H[i][i] -= x; - } - s = fabs(eval.H[n][n-1]) + fabs(eval.H[n-1][n-2]); - x = y = 0.75f * s; - w = -0.4375f * s * s; - } - - // MATLAB's new ad hoc shift - - if (iter == 30) { - s = (y - x) / 2.0f; - s = s * s + w; - if (s > 0) { - s = sqrt(s); - if (y < x) { - s = -s; - } - s = x - w / ((y - x) / 2.0f + s); - for (int i = low; i <= n; i++) { - eval.H[i][i] -= s; - } - exshift += s; - x = y = w = 0.964; - } - } - - iter = iter + 1; // (Could check iteration count here.) - - // Look for two consecutive small sub-diagonal elements - - int m = n-2; - while (m >= l) { - z = eval.H[m][m]; - r = x - z; - s = y - z; - p = (r * s - w) / eval.H[m+1][m] + eval.H[m][m+1]; - q = eval.H[m+1][m+1] - z - r - s; - r = eval.H[m+2][m+1]; - s = fabs(p) + fabs(q) + fabs(r); - p = p / s; - q = q / s; - r = r / s; - if (m == l) { - break; - } - if (fabs(eval.H[m][m-1]) * (fabs(q) + fabs(r)) < - eps * (fabs(p) * (fabs(eval.H[m-1][m-1]) + fabs(z) + - fabs(eval.H[m+1][m+1])))) { - break; - } - m--; - } - - for (int i = m+2; i <= n; i++) { - eval.H[i][i-2] = 0.0; - if (i > m+2) { - eval.H[i][i-3] = 0.0; - } - } - - // Double QR step involving rows l:n and columns m:n - - for (int k = m; k <= n-1; k++) { - int notlast = (k != n-1); - if (k != m) { - p = eval.H[k][k-1]; - q = eval.H[k+1][k-1]; - r = (notlast ? eval.H[k+2][k-1] : 0.0f); - x = fabs(p) + fabs(q) + fabs(r); - if (x != 0.0f) { - p = p / x; - q = q / x; - r = r / x; - } - } - if (x == 0.0f) { - break; - } - s = sqrt(p * p + q * q + r * r); - if (p < 0) { - s = -s; - } - if (s != 0) { - if (k != m) { - eval.H[k][k-1] = -s * x; - } else if (l != m) { - eval.H[k][k-1] = -eval.H[k][k-1]; - } - p = p + s; - x = p / s; - y = q / s; - z = r / s; - q = q / p; - r = r / p; - - // Row modification - - for (int j = k; j < nn; j++) { - p = eval.H[k][j] + q * eval.H[k+1][j]; - if (notlast) { - p = p + r * eval.H[k+2][j]; - eval.H[k+2][j] = eval.H[k+2][j] - p * z; - } - eval.H[k][j] = eval.H[k][j] - p * x; - eval.H[k+1][j] = eval.H[k+1][j] - p * y; - } - - // Column modification - - for (int i = 0; i <= min(n,k+3); i++) { - p = x * eval.H[i][k] + y * eval.H[i][k+1]; - if (notlast) { - p = p + z * eval.H[i][k+2]; - eval.H[i][k+2] = eval.H[i][k+2] - p * r; - } - eval.H[i][k] = eval.H[i][k] - p; - eval.H[i][k+1] = eval.H[i][k+1] - p * q; - } - - // Accumulate transformations - - for (int i = low; i <= high; i++) { - p = x * eval.V[i][k] + y * eval.V[i][k+1]; - if (notlast) { - p = p + z * eval.V[i][k+2]; - eval.V[i][k+2] = eval.V[i][k+2] - p * r; - } - eval.V[i][k] = eval.V[i][k] - p; - eval.V[i][k+1] = eval.V[i][k+1] - p * q; - } - } // (s != 0) - } // k loop - } // check convergence - } // while (n >= low) - //if(totIter>15) std::cout<<"!!!!iter "<<totIter<<"\n"; - - // Backsubstitute to find vectors of upper triangular form - - if (norm == 0.0f) { - return; - } - - for (n = nn-1; n >= 0; n--) { - p = eval.d[n]; - q = eval.e[n]; - - // float vector - - if (q == 0) { - int l = n; - eval.H[n][n] = 1.0; - for (int i = n-1; i >= 0; i--) { - w = eval.H[i][i] - p; - r = 0.0; - for (int j = l; j <= n; j++) { - r = r + eval.H[i][j] * eval.H[j][n]; - } - if (eval.e[i] < 0.0f) { - z = w; - s = r; - } else { - l = i; - if (eval.e[i] == 0.0f) { - if (w != 0.0f) { - eval.H[i][n] = -r / w; - } else { - eval.H[i][n] = -r / (eps * norm); - } - - // Solve real equations - - } else { - x = eval.H[i][i+1]; - y = eval.H[i+1][i]; - q = (eval.d[i] - p) * (eval.d[i] - p) + eval.e[i] * eval.e[i]; - t = (x * s - z * r) / q; - eval.H[i][n] = t; - if (fabs(x) > fabs(z)) { - eval.H[i+1][n] = (-r - w * t) / x; - } else { - eval.H[i+1][n] = (-s - y * t) / z; - } - } - - // Overflow control - - t = fabs(eval.H[i][n]); - if ((eps * t) * t > 1) { - for (int j = i; j <= n; j++) { - eval.H[j][n] = eval.H[j][n] / t; - } - } - } - } - - // Complex vector - - } else if (q < 0) { - int l = n-1; - - // Last vector component imaginary so matrix is triangular - - if (fabs(eval.H[n][n-1]) > fabs(eval.H[n-1][n])) { - eval.H[n-1][n-1] = q / eval.H[n][n-1]; - eval.H[n-1][n] = -(eval.H[n][n] - p) / eval.H[n][n-1]; - } else { - Eigencdiv(eval, 0.0,-eval.H[n-1][n],eval.H[n-1][n-1]-p,q); - eval.H[n-1][n-1] = eval.cdivr; - eval.H[n-1][n] = eval.cdivi; - } - eval.H[n][n-1] = 0.0; - eval.H[n][n] = 1.0; - for (int i = n-2; i >= 0; i--) { - float ra,sa,vr,vi; - ra = 0.0; - sa = 0.0; - for (int j = l; j <= n; j++) { - ra = ra + eval.H[i][j] * eval.H[j][n-1]; - sa = sa + eval.H[i][j] * eval.H[j][n]; - } - w = eval.H[i][i] - p; - - if (eval.e[i] < 0.0f) { - z = w; - r = ra; - s = sa; - } else { - l = i; - if (eval.e[i] == 0) { - Eigencdiv(eval,-ra,-sa,w,q); - eval.H[i][n-1] = eval.cdivr; - eval.H[i][n] = eval.cdivi; - } else { - - // Solve complex equations - - x = eval.H[i][i+1]; - y = eval.H[i+1][i]; - vr = (eval.d[i] - p) * (eval.d[i] - p) + eval.e[i] * eval.e[i] - q * q; - vi = (eval.d[i] - p) * 2.0f * q; - if ((vr == 0.0f) && (vi == 0.0f)) { - vr = eps * norm * (fabs(w) + fabs(q) + - fabs(x) + fabs(y) + fabs(z)); - } - Eigencdiv(eval, x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi); - eval.H[i][n-1] = eval.cdivr; - eval.H[i][n] = eval.cdivi; - if (fabs(x) > (fabs(z) + fabs(q))) { - eval.H[i+1][n-1] = (-ra - w * eval.H[i][n-1] + q * eval.H[i][n]) / x; - eval.H[i+1][n] = (-sa - w * eval.H[i][n] - q * eval.H[i][n-1]) / x; - } else { - Eigencdiv(eval, -r-y*eval.H[i][n-1],-s-y*eval.H[i][n],z,q); - eval.H[i+1][n-1] = eval.cdivr; - eval.H[i+1][n] = eval.cdivi; - } - } - - // Overflow control - - t = max(fabs(eval.H[i][n-1]),fabs(eval.H[i][n])); - if ((eps * t) * t > 1) { - for (int j = i; j <= n; j++) { - eval.H[j][n-1] = eval.H[j][n-1] / t; - eval.H[j][n] = eval.H[j][n] / t; - } - } - } - } - } - } - - // Vectors of isolated roots - - for (int i = 0; i < nn; i++) { - if (i < low || i > high) { - for (int j = i; j < nn; j++) { - eval.V[i][j] = eval.H[i][j]; - } - } - } - - // Back transformation to get eigenvectors of original matrix - - for (int j = nn-1; j >= low; j--) { - for (int i = low; i <= high; i++) { - z = 0.0; - for (int k = low; k <= min(j,high); k++) { - z = z + eval.V[i][k] * eval.H[k][j]; - } - eval.V[i][j] = z; - } - } -} - - - -int computeEigenvalues3x3( - float dout[3], - float a[3][3]) -{ - /*TNT::Array2D<float> A = TNT::Array2D<float>(3,3, &a[0][0]); - TNT::Array1D<float> eig = TNT::Array1D<float>(3); - TNT::Array1D<float> eigImag = TNT::Array1D<float>(3); - JAMA::Eigenvalue<float> jeig = JAMA::Eigenvalue<float>(A);*/ - - sEigenvalue jeig; - - // Compute the values - { - jeig.n = 3; - int n=3; - //V = Array2D<float>(n,n); - //d = Array1D<float>(n); - //e = Array1D<float>(n); - for (int y=0; y<3; y++) - { - jeig.d[y]=0.0f; - jeig.e[y]=0.0f; - for (int t=0; t<3; t++) jeig.V[y][t]=0.0f; - } - - jeig.issymmetric = 1; - for (int j = 0; (j < 3) && jeig.issymmetric; j++) { - for (int i = 0; (i < 3) && jeig.issymmetric; i++) { - jeig.issymmetric = (a[i][j] == a[j][i]); - } - } - - if (jeig.issymmetric) { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - jeig.V[i][j] = a[i][j]; - } - } - - // Tridiagonalize. - Eigentred2(jeig); - - // Diagonalize. - Eigentql2(jeig); - - } else { - //H = TNT::Array2D<float>(n,n); - for (int y=0; y<3; y++) - { - jeig.ort[y]=0.0f; - for (int t=0; t<3; t++) jeig.H[y][t]=0.0f; - } - //ort = TNT::Array1D<float>(n); - - for (int j = 0; j < n; j++) { - for (int i = 0; i < n; i++) { - jeig.H[i][j] = a[i][j]; - } - } - - // Reduce to Hessenberg form. - Eigenorthes(jeig); - - // Reduce Hessenberg to real Schur form. - Eigenhqr2(jeig); - } - } - - //jeig.getfloatEigenvalues(eig); - - // complex ones - //jeig.getImagEigenvalues(eigImag); - dout[0] = sqrt(jeig.d[0]*jeig.d[0] + jeig.e[0]*jeig.e[0]); - dout[1] = sqrt(jeig.d[1]*jeig.d[1] + jeig.e[1]*jeig.e[1]); - dout[2] = sqrt(jeig.d[2]*jeig.d[2] + jeig.e[2]*jeig.e[2]); - return 0; -} diff --git a/intern/smoke/intern/EIGENVALUE_HELPER.h b/intern/smoke/intern/EIGENVALUE_HELPER.h deleted file mode 100644 index ef204b442d9..00000000000 --- a/intern/smoke/intern/EIGENVALUE_HELPER.h +++ /dev/null @@ -1,77 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -////////////////////////////////////////////////////////////////////// -// Modified to not require TNT matrix library anymore. It was very slow -// when being run in parallel. Required TNT JAMA::Eigenvalue libraries were -// converted into independent functions. -// - MiikaH -// -////////////////////////////////////////////////////////////////////// -// Helper function, compute eigenvalues of 3x3 matrix -////////////////////////////////////////////////////////////////////// - -#ifndef EIGENVAL_HELPER_H -#define EIGENVAL_HELPER_H - -//#include "tnt/jama_eig.h" - -#include <algorithm> -#include <cmath> - -using namespace std; - -////////////////////////////////////////////////////////////////////// -// eigenvalues of 3x3 non-symmetric matrix -////////////////////////////////////////////////////////////////////// - - -struct sEigenvalue -{ - int n; - int issymmetric; - float d[3]; /* real part */ - float e[3]; /* img part */ - float V[3][3]; /* Eigenvectors */ - - float H[3][3]; - - - float ort[3]; - - float cdivr; - float cdivi; -}; - -void Eigentred2(sEigenvalue& eval); - -void Eigencdiv(sEigenvalue& eval, float xr, float xi, float yr, float yi); - -void Eigentql2 (sEigenvalue& eval); - -void Eigenorthes (sEigenvalue& eval); - -void Eigenhqr2 (sEigenvalue& eval); - -int computeEigenvalues3x3(float dout[3], float a[3][3]); - - -#endif diff --git a/intern/smoke/intern/FFT_NOISE.h b/intern/smoke/intern/FFT_NOISE.h deleted file mode 100644 index d44cbabd64e..00000000000 --- a/intern/smoke/intern/FFT_NOISE.h +++ /dev/null @@ -1,183 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -///////////////////////////////////////////////////////////////////////// -// - -#ifndef FFT_NOISE_H_ -#define FFT_NOISE_H_ - -#ifdef WITH_FFTW3 -#include <iostream> -#include <fftw3.h> -#include <MERSENNETWISTER.h> - -#include "WAVELET_NOISE.h" - -#ifndef M_PI -#define M_PI 3.14159265 -#endif - -///////////////////////////////////////////////////////////////////////// -// shift spectrum to the format that FFTW expects -///////////////////////////////////////////////////////////////////////// -static void shift3D(float*& field, int xRes, int yRes, int zRes) -{ - int xHalf = xRes / 2; - int yHalf = yRes / 2; - int zHalf = zRes / 2; - // int slabSize = xRes * yRes; - for (int z = 0; z < zHalf; z++) - for (int y = 0; y < yHalf; y++) - for (int x = 0; x < xHalf; x++) - { - int index = x + y * xRes + z * xRes * yRes; - float temp; - int xSwap = xHalf; - int ySwap = yHalf * xRes; - int zSwap = zHalf * xRes * yRes; - - // [0,0,0] to [1,1,1] - temp = field[index]; - field[index] = field[index + xSwap + ySwap + zSwap]; - field[index + xSwap + ySwap + zSwap] = temp; - - // [1,0,0] to [0,1,1] - temp = field[index + xSwap]; - field[index + xSwap] = field[index + ySwap + zSwap]; - field[index + ySwap + zSwap] = temp; - - // [0,1,0] to [1,0,1] - temp = field[index + ySwap]; - field[index + ySwap] = field[index + xSwap + zSwap]; - field[index + xSwap + zSwap] = temp; - - // [0,0,1] to [1,1,0] - temp = field[index + zSwap]; - field[index + zSwap] = field[index + xSwap + ySwap]; - field[index + xSwap + ySwap] = temp; - } -} - -static void generatTile_FFT(float* const noiseTileData, std::string filename) -{ - if (loadTile(noiseTileData, filename)) return; - - int res = NOISE_TILE_SIZE; - int xRes = res; - int yRes = res; - int zRes = res; - int totalCells = xRes * yRes * zRes; - - // create and shift the filter - float* filter = new float[totalCells]; - for (int z = 0; z < zRes; z++) - for (int y = 0; y < yRes; y++) - for (int x = 0; x < xRes; x++) - { - int index = x + y * xRes + z * xRes * yRes; - float diff[] = {(float)abs(x - xRes / 2), - (float)abs(y - yRes / 2), - (float)abs(z - zRes / 2)}; - float radius = sqrtf(diff[0] * diff[0] + - diff[1] * diff[1] + - diff[2] * diff[2]) / (xRes / 2); - radius *= M_PI; - float H = cos((M_PI / 2.0f) * log(4.0f * radius / M_PI) / log(2.0f)); - H = H * H; - float filtered = H; - - // clamp everything outside the wanted band - if (radius >= M_PI / 2.0f) - filtered = 0.0f; - - // make sure to capture all low frequencies - if (radius <= M_PI / 4.0f) - filtered = 1.0f; - - filter[index] = filtered; - } - shift3D(filter, xRes, yRes, zRes); - - // create the noise - float* noise = new float[totalCells]; - int index = 0; - MTRand twister; - for (int z = 0; z < zRes; z++) - for (int y = 0; y < yRes; y++) - for (int x = 0; x < xRes; x++, index++) - noise[index] = twister.randNorm(); - - // create padded field - fftw_complex* forward = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * totalCells); - - // init padded field - index = 0; - for (int z = 0; z < zRes; z++) - for (int y = 0; y < yRes; y++) - for (int x = 0; x < xRes; x++, index++) - { - forward[index][0] = noise[index]; - forward[index][1] = 0.0f; - } - - // forward FFT - fftw_complex* backward = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * totalCells); - fftw_plan forwardPlan = fftw_plan_dft_3d(xRes, yRes, zRes, forward, backward, FFTW_FORWARD, FFTW_ESTIMATE); - fftw_execute(forwardPlan); - fftw_destroy_plan(forwardPlan); - - // apply filter - index = 0; - for (int z = 0; z < zRes; z++) - for (int y = 0; y < yRes; y++) - for (int x = 0; x < xRes; x++, index++) - { - backward[index][0] *= filter[index]; - backward[index][1] *= filter[index]; - } - - // backward FFT - fftw_plan backwardPlan = fftw_plan_dft_3d(xRes, yRes, zRes, backward, forward, FFTW_BACKWARD, FFTW_ESTIMATE); - fftw_execute(backwardPlan); - fftw_destroy_plan(backwardPlan); - - // subtract out the low frequency components - index = 0; - for (int z = 0; z < zRes; z++) - for (int y = 0; y < yRes; y++) - for (int x = 0; x < xRes; x++, index++) - noise[index] -= forward[index][0] / totalCells; - - // fill noiseTileData - memcpy(noiseTileData, noise, sizeof(float) * totalCells); - // save out the noise tile - saveTile(noise, filename); - - fftw_free(forward); - fftw_free(backward); - delete[] filter; - delete[] noise; -} - -#endif - -#endif /* FFT_NOISE_H_ */ diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp deleted file mode 100644 index e76abea35d8..00000000000 --- a/intern/smoke/intern/FLUID_3D.cpp +++ /dev/null @@ -1,1792 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// FLUID_3D.cpp: implementation of the FLUID_3D class. -// -////////////////////////////////////////////////////////////////////// -// Heavy parallel optimization done. Many of the old functions now -// take begin and end parameters and process only specified part of the data. -// Some functions were divided into multiple ones. -// - MiikaH -////////////////////////////////////////////////////////////////////// - -#include "FLUID_3D.h" -#include "IMAGE.h" -#include <INTERPOLATE.h> -#include "SPHERE.h" -#include <zlib.h> - -#include "float.h" - -#if PARALLEL==1 -#include <omp.h> -#endif // PARALLEL - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -FLUID_3D::FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors) : - _xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f) -{ - // set simulation consts - _dt = dtdef; // just in case. set in step from a RNA factor - - _iterations = 100; - _tempAmb = 0; - _heatDiffusion = 1e-3; - _totalTime = 0.0f; - _totalSteps = 0; - _res = Vec3Int(_xRes,_yRes,_zRes); - _maxRes = MAX3(_xRes, _yRes, _zRes); - - // initialize wavelet turbulence - /* - if(amplify) - _wTurbulence = new WTURBULENCE(_res[0],_res[1],_res[2], amplify, noisetype); - else - _wTurbulence = NULL; - */ - - // scale the constants according to the refinement of the grid - if (!dx) - _dx = 1.0f / (float)_maxRes; - else - _dx = dx; - _constantScaling = 64.0f / _maxRes; - _constantScaling = (_constantScaling < 1.0f) ? 1.0f : _constantScaling; - _vorticityEps = 2.0f / _constantScaling; // Just in case set a default value - - // allocate arrays - _totalCells = _xRes * _yRes * _zRes; - _slabSize = _xRes * _yRes; - _xVelocity = new float[_totalCells]; - _yVelocity = new float[_totalCells]; - _zVelocity = new float[_totalCells]; - _xVelocityOb = new float[_totalCells]; - _yVelocityOb = new float[_totalCells]; - _zVelocityOb = new float[_totalCells]; - _xVelocityOld = new float[_totalCells]; - _yVelocityOld = new float[_totalCells]; - _zVelocityOld = new float[_totalCells]; - _xForce = new float[_totalCells]; - _yForce = new float[_totalCells]; - _zForce = new float[_totalCells]; - _density = new float[_totalCells]; - _densityOld = new float[_totalCells]; - _obstacles = new unsigned char[_totalCells]; // set 0 at end of step - - // For threaded version: - _xVelocityTemp = new float[_totalCells]; - _yVelocityTemp = new float[_totalCells]; - _zVelocityTemp = new float[_totalCells]; - _densityTemp = new float[_totalCells]; - - // DG TODO: check if alloc went fine - - for (int x = 0; x < _totalCells; x++) - { - _density[x] = 0.0f; - _densityOld[x] = 0.0f; - _xVelocity[x] = 0.0f; - _yVelocity[x] = 0.0f; - _zVelocity[x] = 0.0f; - _xVelocityOb[x] = 0.0f; - _yVelocityOb[x] = 0.0f; - _zVelocityOb[x] = 0.0f; - _xVelocityOld[x] = 0.0f; - _yVelocityOld[x] = 0.0f; - _zVelocityOld[x] = 0.0f; - _xForce[x] = 0.0f; - _yForce[x] = 0.0f; - _zForce[x] = 0.0f; - _obstacles[x] = false; - } - - /* heat */ - _heat = _heatOld = _heatTemp = NULL; - if (init_heat) { - initHeat(); - } - // Fire simulation - _flame = _fuel = _fuelTemp = _fuelOld = NULL; - _react = _reactTemp = _reactOld = NULL; - if (init_fire) { - initFire(); - } - // Smoke color - _color_r = _color_rOld = _color_rTemp = NULL; - _color_g = _color_gOld = _color_gTemp = NULL; - _color_b = _color_bOld = _color_bTemp = NULL; - if (init_colors) { - initColors(0.0f, 0.0f, 0.0f); - } - - // boundary conditions of the fluid domain - // set default values -> vertically non-colliding - _domainBcFront = true; - _domainBcTop = false; - _domainBcLeft = true; - _domainBcBack = _domainBcFront; - _domainBcBottom = _domainBcTop; - _domainBcRight = _domainBcLeft; - - _colloPrev = 1; // default value -} - -void FLUID_3D::initHeat() -{ - if (!_heat) { - _heat = new float[_totalCells]; - _heatOld = new float[_totalCells]; - _heatTemp = new float[_totalCells]; - - for (int x = 0; x < _totalCells; x++) - { - _heat[x] = 0.0f; - _heatOld[x] = 0.0f; - } - } -} - -void FLUID_3D::initFire() -{ - if (!_flame) { - _flame = new float[_totalCells]; - _fuel = new float[_totalCells]; - _fuelTemp = new float[_totalCells]; - _fuelOld = new float[_totalCells]; - _react = new float[_totalCells]; - _reactTemp = new float[_totalCells]; - _reactOld = new float[_totalCells]; - - for (int x = 0; x < _totalCells; x++) - { - _flame[x] = 0.0f; - _fuel[x] = 0.0f; - _fuelTemp[x] = 0.0f; - _fuelOld[x] = 0.0f; - _react[x] = 0.0f; - _reactTemp[x] = 0.0f; - _reactOld[x] = 0.0f; - } - } -} - -void FLUID_3D::initColors(float init_r, float init_g, float init_b) -{ - if (!_color_r) { - _color_r = new float[_totalCells]; - _color_rOld = new float[_totalCells]; - _color_rTemp = new float[_totalCells]; - _color_g = new float[_totalCells]; - _color_gOld = new float[_totalCells]; - _color_gTemp = new float[_totalCells]; - _color_b = new float[_totalCells]; - _color_bOld = new float[_totalCells]; - _color_bTemp = new float[_totalCells]; - - for (int x = 0; x < _totalCells; x++) - { - _color_r[x] = _density[x] * init_r; - _color_rOld[x] = 0.0f; - _color_g[x] = _density[x] * init_g; - _color_gOld[x] = 0.0f; - _color_b[x] = _density[x] * init_b; - _color_bOld[x] = 0.0f; - } - } -} - -void FLUID_3D::setBorderObstacles() -{ - - // set side obstacles - unsigned int index; - for (int y = 0; y < _yRes; y++) - for (int x = 0; x < _xRes; x++) - { - // bottom slab - index = x + y * _xRes; - if(_domainBcBottom) _obstacles[index] = 1; - - // top slab - index += _totalCells - _slabSize; - if(_domainBcTop) _obstacles[index] = 1; - } - - for (int z = 0; z < _zRes; z++) - for (int x = 0; x < _xRes; x++) - { - // front slab - index = x + z * _slabSize; - if(_domainBcFront) _obstacles[index] = 1; - - // back slab - index += _slabSize - _xRes; - if(_domainBcBack) _obstacles[index] = 1; - } - - for (int z = 0; z < _zRes; z++) - for (int y = 0; y < _yRes; y++) - { - // left slab - index = y * _xRes + z * _slabSize; - if(_domainBcLeft) _obstacles[index] = 1; - - // right slab - index += _xRes - 1; - if(_domainBcRight) _obstacles[index] = 1; - } -} - -FLUID_3D::~FLUID_3D() -{ - if (_xVelocity) delete[] _xVelocity; - if (_yVelocity) delete[] _yVelocity; - if (_zVelocity) delete[] _zVelocity; - if (_xVelocityOb) delete[] _xVelocityOb; - if (_yVelocityOb) delete[] _yVelocityOb; - if (_zVelocityOb) delete[] _zVelocityOb; - if (_xVelocityOld) delete[] _xVelocityOld; - if (_yVelocityOld) delete[] _yVelocityOld; - if (_zVelocityOld) delete[] _zVelocityOld; - if (_xForce) delete[] _xForce; - if (_yForce) delete[] _yForce; - if (_zForce) delete[] _zForce; - if (_density) delete[] _density; - if (_densityOld) delete[] _densityOld; - if (_heat) delete[] _heat; - if (_heatOld) delete[] _heatOld; - if (_obstacles) delete[] _obstacles; - - if (_xVelocityTemp) delete[] _xVelocityTemp; - if (_yVelocityTemp) delete[] _yVelocityTemp; - if (_zVelocityTemp) delete[] _zVelocityTemp; - if (_densityTemp) delete[] _densityTemp; - if (_heatTemp) delete[] _heatTemp; - - if (_flame) delete[] _flame; - if (_fuel) delete[] _fuel; - if (_fuelTemp) delete[] _fuelTemp; - if (_fuelOld) delete[] _fuelOld; - if (_react) delete[] _react; - if (_reactTemp) delete[] _reactTemp; - if (_reactOld) delete[] _reactOld; - - if (_color_r) delete[] _color_r; - if (_color_rOld) delete[] _color_rOld; - if (_color_rTemp) delete[] _color_rTemp; - if (_color_g) delete[] _color_g; - if (_color_gOld) delete[] _color_gOld; - if (_color_gTemp) delete[] _color_gTemp; - if (_color_b) delete[] _color_b; - if (_color_bOld) delete[] _color_bOld; - if (_color_bTemp) delete[] _color_bTemp; - - // printf("deleted fluid\n"); -} - -// init direct access functions from blender -void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision, float *burning_rate, - float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp) -{ - _alpha = alpha; - _beta = beta; - _dtFactor = dt_factor; - _vorticityRNA = vorticity; - _borderColli = borderCollision; - _burning_rate = burning_rate; - _flame_smoke = flame_smoke; - _flame_smoke_color = flame_smoke_color; - _flame_vorticity = flame_vorticity; - _ignition_temp = flame_ignition_temp; - _max_temp = flame_max_temp; -} - -////////////////////////////////////////////////////////////////////// -// step simulation once -////////////////////////////////////////////////////////////////////// -void FLUID_3D::step(float dt, float gravity[3]) -{ -#if 0 - // If border rules have been changed - if (_colloPrev != *_borderColli) { - printf("Border collisions changed\n"); - - // DG TODO: Need to check that no animated obstacle flags are overwritten - setBorderCollisions(); - } -#endif - - // DG: TODO for the moment redo border for every timestep since it's been deleted every time by moving obstacles - setBorderCollisions(); - - - // set delta time by dt_factor - _dt = (*_dtFactor) * dt; - // set vorticity from RNA value - _vorticityEps = (*_vorticityRNA)/_constantScaling; - -#if PARALLEL==1 - int threadval = 1; - threadval = omp_get_max_threads(); - - int stepParts = 1; - float partSize = _zRes; - - stepParts = threadval*2; // Dividing parallelized sections into numOfThreads * 2 sections - partSize = (float)_zRes/stepParts; // Size of one part; - - if (partSize < 4) {stepParts = threadval; // If the slice gets too low (might actually slow things down, change it to larger - partSize = (float)_zRes/stepParts;} - if (partSize < 4) {stepParts = (int)(ceil((float)_zRes/4.0f)); // If it's still too low (only possible on future systems with +24 cores), change it to 4 - partSize = (float)_zRes/stepParts;} -#else - int zBegin=0; - int zEnd=_zRes; -#endif - - wipeBoundariesSL(0, _zRes); - -#if PARALLEL==1 - #pragma omp parallel - { - #pragma omp for schedule(static,1) - for (int i=0; i<stepParts; i++) - { - int zBegin = (int)((float)i*partSize + 0.5f); - int zEnd = (int)((float)(i+1)*partSize + 0.5f); -#endif - - addVorticity(zBegin, zEnd); - addBuoyancy(_heat, _density, gravity, zBegin, zEnd); - addForce(zBegin, zEnd); - -#if PARALLEL==1 - } // end of parallel - #pragma omp barrier - - #pragma omp single - { -#endif - /* - * addForce() changed Temp values to preserve thread safety - * (previous functions in per thread loop still needed - * original velocity data) - * - * So swap temp values to velocity - */ - SWAP_POINTERS(_xVelocity, _xVelocityTemp); - SWAP_POINTERS(_yVelocity, _yVelocityTemp); - SWAP_POINTERS(_zVelocity, _zVelocityTemp); -#if PARALLEL==1 - } // end of single - - #pragma omp barrier - - #pragma omp for - for (int i=0; i<2; i++) - { - if (i==0) - { -#endif - project(); -#if PARALLEL==1 - } - else if (i==1) - { -#endif - if (_heat) { - diffuseHeat(); - } -#if PARALLEL==1 - } - } - - #pragma omp barrier - - #pragma omp single - { -#endif - /* - * For thread safety use "Old" to read - * "current" values but still allow changing values. - */ - SWAP_POINTERS(_xVelocity, _xVelocityOld); - SWAP_POINTERS(_yVelocity, _yVelocityOld); - SWAP_POINTERS(_zVelocity, _zVelocityOld); - SWAP_POINTERS(_density, _densityOld); - SWAP_POINTERS(_heat, _heatOld); - - SWAP_POINTERS(_fuel, _fuelOld); - SWAP_POINTERS(_react, _reactOld); - - SWAP_POINTERS(_color_r, _color_rOld); - SWAP_POINTERS(_color_g, _color_gOld); - SWAP_POINTERS(_color_b, _color_bOld); - - advectMacCormackBegin(0, _zRes); - -#if PARALLEL==1 - } // end of single - - #pragma omp barrier - - - #pragma omp for schedule(static,1) - for (int i=0; i<stepParts; i++) - { - - int zBegin = (int)((float)i*partSize + 0.5f); - int zEnd = (int)((float)(i+1)*partSize + 0.5f); -#endif - - advectMacCormackEnd1(zBegin, zEnd); - -#if PARALLEL==1 - } // end of parallel - - #pragma omp barrier - - #pragma omp for schedule(static,1) - for (int i=0; i<stepParts; i++) - { - - int zBegin = (int)((float)i*partSize + 0.5f); - int zEnd = (int)((float)(i+1)*partSize + 0.5f); -#endif - - advectMacCormackEnd2(zBegin, zEnd); - - artificialDampingSL(zBegin, zEnd); - - // Using forces as temp arrays - -#if PARALLEL==1 - } - } - - - - for (int i=1; i<stepParts; i++) - { - int zPos=(int)((float)i*partSize + 0.5f); - - artificialDampingExactSL(zPos); - - } -#endif - - /* - * swap final velocity back to Velocity array - * from temp xForce storage - */ - SWAP_POINTERS(_xVelocity, _xForce); - SWAP_POINTERS(_yVelocity, _yForce); - SWAP_POINTERS(_zVelocity, _zForce); - - _totalTime += _dt; - _totalSteps++; - - for (int i = 0; i < _totalCells; i++) - { - _xForce[i] = _yForce[i] = _zForce[i] = 0.0f; - } - -} - - -// Set border collision model from RNA setting - -void FLUID_3D::setBorderCollisions() { - - - _colloPrev = *_borderColli; // saving the current value - - // boundary conditions of the fluid domain - if (_colloPrev == 0) - { - // No collisions - _domainBcFront = false; - _domainBcTop = false; - _domainBcLeft = false; - } - else if (_colloPrev == 2) - { - // Collide with all sides - _domainBcFront = true; - _domainBcTop = true; - _domainBcLeft = true; - } - else - { - // Default values: Collide with "walls", but not top and bottom - _domainBcFront = true; - _domainBcTop = false; - _domainBcLeft = true; - } - - _domainBcBack = _domainBcFront; - _domainBcBottom = _domainBcTop; - _domainBcRight = _domainBcLeft; - - - - // set side obstacles - setBorderObstacles(); -} - -////////////////////////////////////////////////////////////////////// -// helper function to dampen co-located grid artifacts of given arrays in intervals -// (only needed for velocity, strength (w) depends on testcase... -////////////////////////////////////////////////////////////////////// - - -void FLUID_3D::artificialDampingSL(int zBegin, int zEnd) { - const float w = 0.9; - - memmove(_xForce+(_slabSize*zBegin), _xVelocityTemp+(_slabSize*zBegin), sizeof(float)*_slabSize*(zEnd-zBegin)); - memmove(_yForce+(_slabSize*zBegin), _yVelocityTemp+(_slabSize*zBegin), sizeof(float)*_slabSize*(zEnd-zBegin)); - memmove(_zForce+(_slabSize*zBegin), _zVelocityTemp+(_slabSize*zBegin), sizeof(float)*_slabSize*(zEnd-zBegin)); - - - if(_totalSteps % 4 == 1) { - for (int z = zBegin+1; z < zEnd-1; z++) - for (int y = 1; y < _res[1]-1; y++) - for (int x = 1+(y+z)%2; x < _res[0]-1; x+=2) { - const int index = x + y*_res[0] + z * _slabSize; - _xForce[index] = (1-w)*_xVelocityTemp[index] + 1.0f/6.0f * w*( - _xVelocityTemp[index+1] + _xVelocityTemp[index-1] + - _xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] + - _xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] ); - - _yForce[index] = (1-w)*_yVelocityTemp[index] + 1.0f/6.0f * w*( - _yVelocityTemp[index+1] + _yVelocityTemp[index-1] + - _yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] + - _yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] ); - - _zForce[index] = (1-w)*_zVelocityTemp[index] + 1.0f/6.0f * w*( - _zVelocityTemp[index+1] + _zVelocityTemp[index-1] + - _zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] + - _zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] ); - } - } - - if(_totalSteps % 4 == 3) { - for (int z = zBegin+1; z < zEnd-1; z++) - for (int y = 1; y < _res[1]-1; y++) - for (int x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) { - const int index = x + y*_res[0] + z * _slabSize; - _xForce[index] = (1-w)*_xVelocityTemp[index] + 1.0f/6.0f * w*( - _xVelocityTemp[index+1] + _xVelocityTemp[index-1] + - _xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] + - _xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] ); - - _yForce[index] = (1-w)*_yVelocityTemp[index] + 1.0f/6.0f * w*( - _yVelocityTemp[index+1] + _yVelocityTemp[index-1] + - _yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] + - _yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] ); - - _zForce[index] = (1-w)*_zVelocityTemp[index] + 1.0f/6.0f * w*( - _zVelocityTemp[index+1] + _zVelocityTemp[index-1] + - _zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] + - _zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] ); - } - - } -} - - - -void FLUID_3D::artificialDampingExactSL(int pos) { - const float w = 0.9; - int index, x,y,z; - - - size_t posslab; - - for (z=pos-1; z<=pos; z++) - { - posslab=z * _slabSize; - - if(_totalSteps % 4 == 1) { - for (y = 1; y < _res[1]-1; y++) - for (x = 1+(y+z)%2; x < _res[0]-1; x+=2) { - index = x + y*_res[0] + posslab; - /* - * Uses xForce as temporary storage to allow other threads to read - * old values from xVelocityTemp - */ - _xForce[index] = (1-w)*_xVelocityTemp[index] + 1.0f/6.0f * w*( - _xVelocityTemp[index+1] + _xVelocityTemp[index-1] + - _xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] + - _xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] ); - - _yForce[index] = (1-w)*_yVelocityTemp[index] + 1.0f/6.0f * w*( - _yVelocityTemp[index+1] + _yVelocityTemp[index-1] + - _yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] + - _yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] ); - - _zForce[index] = (1-w)*_zVelocityTemp[index] + 1.0f/6.0f * w*( - _zVelocityTemp[index+1] + _zVelocityTemp[index-1] + - _zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] + - _zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] ); - - } - } - - if(_totalSteps % 4 == 3) { - for (y = 1; y < _res[1]-1; y++) - for (x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) { - index = x + y*_res[0] + posslab; - - /* - * Uses xForce as temporary storage to allow other threads to read - * old values from xVelocityTemp - */ - _xForce[index] = (1-w)*_xVelocityTemp[index] + 1.0f/6.0f * w*( - _xVelocityTemp[index+1] + _xVelocityTemp[index-1] + - _xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] + - _xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] ); - - _yForce[index] = (1-w)*_yVelocityTemp[index] + 1.0f/6.0f * w*( - _yVelocityTemp[index+1] + _yVelocityTemp[index-1] + - _yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] + - _yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] ); - - _zForce[index] = (1-w)*_zVelocityTemp[index] + 1.0f/6.0f * w*( - _zVelocityTemp[index+1] + _zVelocityTemp[index-1] + - _zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] + - _zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] ); - - } - - } - } -} - -////////////////////////////////////////////////////////////////////// -// copy out the boundary in all directions -////////////////////////////////////////////////////////////////////// -void FLUID_3D::copyBorderAll(float* field, int zBegin, int zEnd) -{ - int index, x, y, z; - int zSize = zEnd-zBegin; - int _blockTotalCells=_slabSize * zSize; - - if (zBegin==0) - for (int y = 0; y < _yRes; y++) - for (int x = 0; x < _xRes; x++) - { - // front slab - index = x + y * _xRes; - field[index] = field[index + _slabSize]; - } - - if (zEnd==_zRes) - for (y = 0; y < _yRes; y++) - for (x = 0; x < _xRes; x++) - { - - // back slab - index = x + y * _xRes + _blockTotalCells - _slabSize; - field[index] = field[index - _slabSize]; - } - - for (z = 0; z < zSize; z++) - for (x = 0; x < _xRes; x++) - { - // bottom slab - index = x + z * _slabSize; - field[index] = field[index + _xRes]; - - // top slab - index += _slabSize - _xRes; - field[index] = field[index - _xRes]; - } - - for (z = 0; z < zSize; z++) - for (y = 0; y < _yRes; y++) - { - // left slab - index = y * _xRes + z * _slabSize; - field[index] = field[index + 1]; - - // right slab - index += _xRes - 1; - field[index] = field[index - 1]; - } -} - -////////////////////////////////////////////////////////////////////// -// wipe boundaries of velocity and density -////////////////////////////////////////////////////////////////////// -void FLUID_3D::wipeBoundaries(int zBegin, int zEnd) -{ - setZeroBorder(_xVelocity, _res, zBegin, zEnd); - setZeroBorder(_yVelocity, _res, zBegin, zEnd); - setZeroBorder(_zVelocity, _res, zBegin, zEnd); - setZeroBorder(_density, _res, zBegin, zEnd); - if (_fuel) { - setZeroBorder(_fuel, _res, zBegin, zEnd); - setZeroBorder(_react, _res, zBegin, zEnd); - } - if (_color_r) { - setZeroBorder(_color_r, _res, zBegin, zEnd); - setZeroBorder(_color_g, _res, zBegin, zEnd); - setZeroBorder(_color_b, _res, zBegin, zEnd); - } -} - -void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) -{ - - ///////////////////////////////////// - // setZeroBorder to all: - ///////////////////////////////////// - - ///////////////////////////////////// - // setZeroX - ///////////////////////////////////// - - const int slabSize = _xRes * _yRes; - int index, x,y,z; - - for (z = zBegin; z < zEnd; z++) - for (y = 0; y < _yRes; y++) - { - // left slab - index = y * _xRes + z * slabSize; - _xVelocity[index] = 0.0f; - _yVelocity[index] = 0.0f; - _zVelocity[index] = 0.0f; - _density[index] = 0.0f; - if (_fuel) { - _fuel[index] = 0.0f; - _react[index] = 0.0f; - } - if (_color_r) { - _color_r[index] = 0.0f; - _color_g[index] = 0.0f; - _color_b[index] = 0.0f; - } - - // right slab - index += _xRes - 1; - _xVelocity[index] = 0.0f; - _yVelocity[index] = 0.0f; - _zVelocity[index] = 0.0f; - _density[index] = 0.0f; - if (_fuel) { - _fuel[index] = 0.0f; - _react[index] = 0.0f; - } - if (_color_r) { - _color_r[index] = 0.0f; - _color_g[index] = 0.0f; - _color_b[index] = 0.0f; - } - } - - ///////////////////////////////////// - // setZeroY - ///////////////////////////////////// - - for (z = zBegin; z < zEnd; z++) - for (x = 0; x < _xRes; x++) - { - // bottom slab - index = x + z * slabSize; - _xVelocity[index] = 0.0f; - _yVelocity[index] = 0.0f; - _zVelocity[index] = 0.0f; - _density[index] = 0.0f; - if (_fuel) { - _fuel[index] = 0.0f; - _react[index] = 0.0f; - } - if (_color_r) { - _color_r[index] = 0.0f; - _color_g[index] = 0.0f; - _color_b[index] = 0.0f; - } - - // top slab - index += slabSize - _xRes; - _xVelocity[index] = 0.0f; - _yVelocity[index] = 0.0f; - _zVelocity[index] = 0.0f; - _density[index] = 0.0f; - if (_fuel) { - _fuel[index] = 0.0f; - _react[index] = 0.0f; - } - if (_color_r) { - _color_r[index] = 0.0f; - _color_g[index] = 0.0f; - _color_b[index] = 0.0f; - } - - } - - ///////////////////////////////////// - // setZeroZ - ///////////////////////////////////// - - - const int totalCells = _xRes * _yRes * _zRes; - - index = 0; - if (zBegin == 0) - for (y = 0; y < _yRes; y++) - for (x = 0; x < _xRes; x++, index++) - { - // front slab - _xVelocity[index] = 0.0f; - _yVelocity[index] = 0.0f; - _zVelocity[index] = 0.0f; - _density[index] = 0.0f; - if (_fuel) { - _fuel[index] = 0.0f; - _react[index] = 0.0f; - } - if (_color_r) { - _color_r[index] = 0.0f; - _color_g[index] = 0.0f; - _color_b[index] = 0.0f; - } - } - - if (zEnd == _zRes) - { - index=0; - int index_top=0; - const int cellsslab = totalCells - slabSize; - - for (y = 0; y < _yRes; y++) - for (x = 0; x < _xRes; x++, index++) - { - - // back slab - index_top = index + cellsslab; - _xVelocity[index_top] = 0.0f; - _yVelocity[index_top] = 0.0f; - _zVelocity[index_top] = 0.0f; - _density[index_top] = 0.0f; - if (_fuel) { - _fuel[index_top] = 0.0f; - _react[index_top] = 0.0f; - } - if (_color_r) { - _color_r[index_top] = 0.0f; - _color_g[index_top] = 0.0f; - _color_b[index_top] = 0.0f; - } - } - } - -} -////////////////////////////////////////////////////////////////////// -// add forces to velocity field -////////////////////////////////////////////////////////////////////// -void FLUID_3D::addForce(int zBegin, int zEnd) -{ - int begin=zBegin * _slabSize; - int end=begin + (zEnd - zBegin) * _slabSize; - - for (int i = begin; i < end; i++) - { - _xVelocityTemp[i] = _xVelocity[i] + _dt * _xForce[i]; - _yVelocityTemp[i] = _yVelocity[i] + _dt * _yForce[i]; - _zVelocityTemp[i] = _zVelocity[i] + _dt * _zForce[i]; - } -} -////////////////////////////////////////////////////////////////////// -// project into divergence free field -////////////////////////////////////////////////////////////////////// -void FLUID_3D::project() -{ - int x, y, z; - size_t index; - - float *_pressure = new float[_totalCells]; - float *_divergence = new float[_totalCells]; - - memset(_pressure, 0, sizeof(float)*_totalCells); - memset(_divergence, 0, sizeof(float)*_totalCells); - - // set velocity and pressure inside of obstacles to zero - setObstacleBoundaries(_pressure, 0, _zRes); - - // copy out the boundaries - if(!_domainBcLeft) setNeumannX(_xVelocity, _res, 0, _zRes); - else setZeroX(_xVelocity, _res, 0, _zRes); - - if(!_domainBcFront) setNeumannY(_yVelocity, _res, 0, _zRes); - else setZeroY(_yVelocity, _res, 0, _zRes); - - if(!_domainBcTop) setNeumannZ(_zVelocity, _res, 0, _zRes); - else setZeroZ(_zVelocity, _res, 0, _zRes); - - // calculate divergence - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - - if(_obstacles[index]) - { - _divergence[index] = 0.0f; - continue; - } - - - float xright = _xVelocity[index + 1]; - float xleft = _xVelocity[index - 1]; - float yup = _yVelocity[index + _xRes]; - float ydown = _yVelocity[index - _xRes]; - float ztop = _zVelocity[index + _slabSize]; - float zbottom = _zVelocity[index - _slabSize]; - - if(_obstacles[index+1]) xright = - _xVelocity[index]; // DG: += - if(_obstacles[index-1]) xleft = - _xVelocity[index]; - if(_obstacles[index+_xRes]) yup = - _yVelocity[index]; - if(_obstacles[index-_xRes]) ydown = - _yVelocity[index]; - if(_obstacles[index+_slabSize]) ztop = - _zVelocity[index]; - if(_obstacles[index-_slabSize]) zbottom = - _zVelocity[index]; - - if(_obstacles[index+1] & 8) xright += _xVelocityOb[index + 1]; - if(_obstacles[index-1] & 8) xleft += _xVelocityOb[index - 1]; - if(_obstacles[index+_xRes] & 8) yup += _yVelocityOb[index + _xRes]; - if(_obstacles[index-_xRes] & 8) ydown += _yVelocityOb[index - _xRes]; - if(_obstacles[index+_slabSize] & 8) ztop += _zVelocityOb[index + _slabSize]; - if(_obstacles[index-_slabSize] & 8) zbottom += _zVelocityOb[index - _slabSize]; - - _divergence[index] = -_dx * 0.5f * ( - xright - xleft + - yup - ydown + - ztop - zbottom ); - - // Pressure is zero anyway since now a local array is used - _pressure[index] = 0.0f; - } - - copyBorderAll(_pressure, 0, _zRes); - - // fix fluid compression caused in isolated components by obstacle movement - fixObstacleCompression(_divergence); - - // solve Poisson equation - solvePressurePre(_pressure, _divergence, _obstacles); - - setObstaclePressure(_pressure, 0, _zRes); - - // project out solution - // New idea for code from NVIDIA graphic gems 3 - DG - float invDx = 1.0f / _dx; - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - float vMask[3] = {1.0f, 1.0f, 1.0f}, vObst[3] = {0, 0, 0}; - // float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f; // UNUSED - - float pC = _pressure[index]; // center - float pR = _pressure[index + 1]; // right - float pL = _pressure[index - 1]; // left - float pU = _pressure[index + _xRes]; // Up - float pD = _pressure[index - _xRes]; // Down - float pT = _pressure[index + _slabSize]; // top - float pB = _pressure[index - _slabSize]; // bottom - - if(!_obstacles[index]) - { - // DG TODO: What if obstacle is left + right and one of them is moving? - if(_obstacles[index+1]) { pR = pC; vObst[0] = _xVelocityOb[index + 1]; vMask[0] = 0; } - if(_obstacles[index-1]) { pL = pC; vObst[0] = _xVelocityOb[index - 1]; vMask[0] = 0; } - if(_obstacles[index+_xRes]) { pU = pC; vObst[1] = _yVelocityOb[index + _xRes]; vMask[1] = 0; } - if(_obstacles[index-_xRes]) { pD = pC; vObst[1] = _yVelocityOb[index - _xRes]; vMask[1] = 0; } - if(_obstacles[index+_slabSize]) { pT = pC; vObst[2] = _zVelocityOb[index + _slabSize]; vMask[2] = 0; } - if(_obstacles[index-_slabSize]) { pB = pC; vObst[2] = _zVelocityOb[index - _slabSize]; vMask[2] = 0; } - - _xVelocity[index] -= 0.5f * (pR - pL) * invDx; - _yVelocity[index] -= 0.5f * (pU - pD) * invDx; - _zVelocity[index] -= 0.5f * (pT - pB) * invDx; - - _xVelocity[index] = (vMask[0] * _xVelocity[index]) + vObst[0]; - _yVelocity[index] = (vMask[1] * _yVelocity[index]) + vObst[1]; - _zVelocity[index] = (vMask[2] * _zVelocity[index]) + vObst[2]; - } - else - { - _xVelocity[index] = _xVelocityOb[index]; - _yVelocity[index] = _yVelocityOb[index]; - _zVelocity[index] = _zVelocityOb[index]; - } - } - - // DG: was enabled in original code but now we do this later - // setObstacleVelocity(0, _zRes); - - if (_pressure) delete[] _pressure; - if (_divergence) delete[] _divergence; -} - -////////////////////////////////////////////////////////////////////// -// calculate the obstacle velocity at boundary -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setObstacleVelocity(int zBegin, int zEnd) -{ - - // completely TODO <-- who wrote this and what is here TODO? DG - - const size_t index_ = _slabSize + _xRes + 1; - - //int vIndex=_slabSize + _xRes + 1; - - int bb=0; - int bt=0; - - if (zBegin == 0) {bb = 1;} - if (zEnd == _zRes) {bt = 1;} - - // tag remaining obstacle blocks - for (int z = zBegin + bb; z < zEnd - bt; z++) - { - size_t index = index_ +(z-1)*_slabSize; - - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - if (!_obstacles[index]) - { - // if(_obstacles[index+1]) xright = - _xVelocityOb[index]; - if((_obstacles[index - 1] & 8) && abs(_xVelocityOb[index - 1]) > FLT_EPSILON ) - { - // printf("velocity x!\n"); - _xVelocity[index] = _xVelocityOb[index - 1]; - _xVelocity[index - 1] = _xVelocityOb[index - 1]; - } - // if(_obstacles[index+_xRes]) yup = - _yVelocityOb[index]; - if((_obstacles[index - _xRes] & 8) && abs(_yVelocityOb[index - _xRes]) > FLT_EPSILON) - { - // printf("velocity y!\n"); - _yVelocity[index] = _yVelocityOb[index - _xRes]; - _yVelocity[index - _xRes] = _yVelocityOb[index - _xRes]; - } - // if(_obstacles[index+_slabSize]) ztop = - _zVelocityOb[index]; - if((_obstacles[index - _slabSize] & 8) && abs(_zVelocityOb[index - _slabSize]) > FLT_EPSILON) - { - // printf("velocity z!\n"); - _zVelocity[index] = _zVelocityOb[index - _slabSize]; - _zVelocity[index - _slabSize] = _zVelocityOb[index - _slabSize]; - } - } - else - { - _density[index] = 0; - } - //vIndex++; - } // x loop - //vIndex += 2; - } // y loop - //vIndex += 2 * _xRes; - } // z loop -} - -////////////////////////////////////////////////////////////////////// -// diffuse heat -////////////////////////////////////////////////////////////////////// -void FLUID_3D::diffuseHeat() -{ - SWAP_POINTERS(_heat, _heatOld); - - copyBorderAll(_heatOld, 0, _zRes); - solveHeat(_heat, _heatOld, _obstacles); - - // zero out inside obstacles - for (int x = 0; x < _totalCells; x++) - if (_obstacles[x]) - _heat[x] = 0.0f; -} - -////////////////////////////////////////////////////////////////////// -// stamp an obstacle in the _obstacles field -////////////////////////////////////////////////////////////////////// -void FLUID_3D::addObstacle(OBSTACLE* obstacle) -{ - int index = 0; - for (int z = 0; z < _zRes; z++) - for (int y = 0; y < _yRes; y++) - for (int x = 0; x < _xRes; x++, index++) - if (obstacle->inside(x * _dx, y * _dx, z * _dx)) { - _obstacles[index] = true; - } -} - -////////////////////////////////////////////////////////////////////// -// calculate the obstacle directional types -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setObstaclePressure(float *_pressure, int zBegin, int zEnd) -{ - - // completely TODO <-- who wrote this and what is here TODO? DG - - const size_t index_ = _slabSize + _xRes + 1; - - //int vIndex=_slabSize + _xRes + 1; - - int bb=0; - int bt=0; - - if (zBegin == 0) {bb = 1;} - if (zEnd == _zRes) {bt = 1;} - - // tag remaining obstacle blocks - for (int z = zBegin + bb; z < zEnd - bt; z++) - { - size_t index = index_ +(z-1)*_slabSize; - - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - // could do cascade of ifs, but they are a pain - if (_obstacles[index] /* && !(_obstacles[index] & 8) DG TODO TEST THIS CONDITION */) - { - const int top = _obstacles[index + _slabSize]; - const int bottom= _obstacles[index - _slabSize]; - const int up = _obstacles[index + _xRes]; - const int down = _obstacles[index - _xRes]; - const int left = _obstacles[index - 1]; - const int right = _obstacles[index + 1]; - - // unused - // const bool fullz = (top && bottom); - // const bool fully = (up && down); - //const bool fullx = (left && right); - - /* - _xVelocity[index] = - _yVelocity[index] = - _zVelocity[index] = 0.0f; - */ - _pressure[index] = 0.0f; - - // average pressure neighbors - float pcnt = 0.; - if (left && !right) { - _pressure[index] += _pressure[index + 1]; - pcnt += 1.0f; - } - if (!left && right) { - _pressure[index] += _pressure[index - 1]; - pcnt += 1.0f; - } - if (up && !down) { - _pressure[index] += _pressure[index - _xRes]; - pcnt += 1.0f; - } - if (!up && down) { - _pressure[index] += _pressure[index + _xRes]; - pcnt += 1.0f; - } - if (top && !bottom) { - _pressure[index] += _pressure[index - _slabSize]; - pcnt += 1.0f; - } - if (!top && bottom) { - _pressure[index] += _pressure[index + _slabSize]; - pcnt += 1.0f; - } - - if(pcnt > 0.000001f) - _pressure[index] /= pcnt; - - // TODO? set correct velocity bc's - // velocities are only set to zero right now - // this means it's not a full no-slip boundary condition - // but a "half-slip" - still looks ok right now - } - //vIndex++; - } // x loop - //vIndex += 2; - } // y loop - //vIndex += 2 * _xRes; - } // z loop -} - -void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd) -{ - // cull degenerate obstacles , move to addObstacle? - - // r = b - Ax - const size_t index_ = _slabSize + _xRes + 1; - - int bb=0; - int bt=0; - - if (zBegin == 0) {bb = 1;} - if (zEnd == _zRes) {bt = 1;} - - for (int z = zBegin + bb; z < zEnd - bt; z++) - { - size_t index = index_ +(z-1)*_slabSize; - - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - if (_obstacles[index] != EMPTY) - { - const int top = _obstacles[index + _slabSize]; - const int bottom= _obstacles[index - _slabSize]; - const int up = _obstacles[index + _xRes]; - const int down = _obstacles[index - _xRes]; - const int left = _obstacles[index - 1]; - const int right = _obstacles[index + 1]; - - int counter = 0; - if (up) counter++; - if (down) counter++; - if (left) counter++; - if (right) counter++; - if (top) counter++; - if (bottom) counter++; - - if (counter < 3) - _obstacles[index] = EMPTY; - } - if (_obstacles[index]) - { - _xVelocity[index] = - _yVelocity[index] = - _zVelocity[index] = 0.0f; - _pressure[index] = 0.0f; - } - //vIndex++; - } // x-loop - //vIndex += 2; - } // y-loop - //vIndex += 2* _xRes; - } // z-loop -} - -void FLUID_3D::floodFillComponent(int *buffer, size_t *queue, size_t limit, size_t pos, int from, int to) -{ - /* Flood 'from' cells with 'to' in the grid. Rely on (from != 0 && from != to && edges == 0) to stop. */ - int offsets[] = { -1, +1, -_xRes, +_xRes, -_slabSize, +_slabSize }; - size_t qend = 0; - - buffer[pos] = to; - queue[qend++] = pos; - - for (size_t qidx = 0; qidx < qend; qidx++) - { - pos = queue[qidx]; - - for (int i = 0; i < 6; i++) - { - size_t next = pos + offsets[i]; - - if (next < limit && buffer[next] == from) - { - buffer[next] = to; - queue[qend++] = next; - } - } - } -} - -void FLUID_3D::mergeComponents(int *buffer, size_t *queue, size_t cur, size_t other) -{ - /* Replace higher value with lower. */ - if (buffer[other] < buffer[cur]) - { - floodFillComponent(buffer, queue, cur, cur, buffer[cur], buffer[other]); - } - else if (buffer[cur] < buffer[other]) - { - floodFillComponent(buffer, queue, cur, other, buffer[other], buffer[cur]); - } -} - -void FLUID_3D::fixObstacleCompression(float *divergence) -{ - int x, y, z; - size_t index; - - /* Find compartments completely separated by obstacles. - * Edge of the domain is automatically component 0. */ - int *component = new int[_totalCells]; - size_t *queue = new size_t[_totalCells]; - - memset(component, 0, sizeof(int) * _totalCells); - - int next_id = 1; - - for (z = 1, index = _slabSize + _xRes + 1; z < _zRes - 1; z++, index += 2 * _xRes) - { - for (y = 1; y < _yRes - 1; y++, index += 2) - { - for (x = 1; x < _xRes - 1; x++, index++) - { - if(!_obstacles[index]) - { - /* Check for connection to the domain edge at iteration end. */ - if ((x == _xRes-2 && !_obstacles[index + 1]) || - (y == _yRes-2 && !_obstacles[index + _xRes]) || - (z == _zRes-2 && !_obstacles[index + _slabSize])) - { - component[index] = 0; - } - else { - component[index] = next_id; - } - - if (!_obstacles[index - 1]) - mergeComponents(component, queue, index, index - 1); - if (!_obstacles[index - _xRes]) - mergeComponents(component, queue, index, index - _xRes); - if (!_obstacles[index - _slabSize]) - mergeComponents(component, queue, index, index - _slabSize); - - if (component[index] == next_id) - next_id++; - } - } - } - } - - delete[] queue; - - /* Compute average divergence within each component. */ - float *total_divergence = new float[next_id]; - int *component_size = new int[next_id]; - - memset(total_divergence, 0, sizeof(float) * next_id); - memset(component_size, 0, sizeof(int) * next_id); - - for (z = 1, index = _slabSize + _xRes + 1; z < _zRes - 1; z++, index += 2 * _xRes) - { - for (y = 1; y < _yRes - 1; y++, index += 2) - { - for (x = 1; x < _xRes - 1; x++, index++) - { - if(!_obstacles[index]) - { - int ci = component[index]; - - component_size[ci]++; - total_divergence[ci] += divergence[index]; - } - } - } - } - - /* Adjust divergence to make the average zero in each component except the edge. */ - total_divergence[0] = 0.0f; - - for (z = 1, index = _slabSize + _xRes + 1; z < _zRes - 1; z++, index += 2 * _xRes) - { - for (y = 1; y < _yRes - 1; y++, index += 2) - { - for (x = 1; x < _xRes - 1; x++, index++) - { - if(!_obstacles[index]) - { - int ci = component[index]; - - divergence[index] -= total_divergence[ci] / component_size[ci]; - } - } - } - } - - delete[] component; - delete[] component_size; - delete[] total_divergence; -} - -////////////////////////////////////////////////////////////////////// -// add buoyancy forces -////////////////////////////////////////////////////////////////////// -void FLUID_3D::addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd) -{ - int index = zBegin*_slabSize; - - for (int z = zBegin; z < zEnd; z++) - for (int y = 0; y < _yRes; y++) - for (int x = 0; x < _xRes; x++, index++) - { - float buoyancy = *_alpha * density[index] + (*_beta * (((heat) ? heat[index] : 0.0f) - _tempAmb)); - _xForce[index] -= gravity[0] * buoyancy; - _yForce[index] -= gravity[1] * buoyancy; - _zForce[index] -= gravity[2] * buoyancy; - } -} - - -////////////////////////////////////////////////////////////////////// -// add vorticity to the force field -////////////////////////////////////////////////////////////////////// -#define VORT_VEL(i, j) \ - ((_obstacles[obpos[(i)]] & 8) ? ((abs(objvelocity[(j)][obpos[(i)]]) > FLT_EPSILON) ? objvelocity[(j)][obpos[(i)]] : velocity[(j)][index]) : velocity[(j)][obpos[(i)]]) - -void FLUID_3D::addVorticity(int zBegin, int zEnd) -{ - // set flame vorticity from RNA value - float flame_vorticity = (*_flame_vorticity)/_constantScaling; - //int x,y,z,index; - if(_vorticityEps+flame_vorticity<=0.0f) return; - - int _blockSize=zEnd-zBegin; - int _blockTotalCells = _slabSize * (_blockSize+2); - - float *_xVorticity, *_yVorticity, *_zVorticity, *_vorticity; - - int bb=0; - int bt=0; - int bb1=-1; - int bt1=-1; - - if (zBegin == 0) {bb1 = 1; bb = 1; _blockTotalCells-=_blockSize;} - if (zEnd == _zRes) {bt1 = 1;bt = 1; _blockTotalCells-=_blockSize;} - - _xVorticity = new float[_blockTotalCells]; - _yVorticity = new float[_blockTotalCells]; - _zVorticity = new float[_blockTotalCells]; - _vorticity = new float[_blockTotalCells]; - - memset(_xVorticity, 0, sizeof(float)*_blockTotalCells); - memset(_yVorticity, 0, sizeof(float)*_blockTotalCells); - memset(_zVorticity, 0, sizeof(float)*_blockTotalCells); - memset(_vorticity, 0, sizeof(float)*_blockTotalCells); - - //const size_t indexsetupV=_slabSize; - const size_t index_ = _slabSize + _xRes + 1; - - // calculate vorticity - float gridSize = 0.5f / _dx; - //index = _slabSize + _xRes + 1; - - float *velocity[3]; - float *objvelocity[3]; - - velocity[0] = _xVelocity; - velocity[1] = _yVelocity; - velocity[2] = _zVelocity; - - objvelocity[0] = _xVelocityOb; - objvelocity[1] = _yVelocityOb; - objvelocity[2] = _zVelocityOb; - - size_t vIndex=_xRes + 1; - for (int z = zBegin + bb1; z < (zEnd - bt1); z++) - { - size_t index = index_ +(z-1)*_slabSize; - vIndex = index-(zBegin-1+bb)*_slabSize; - - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - if (!_obstacles[index]) - { - int obpos[6]; - - obpos[0] = (_obstacles[index + _xRes] == 1) ? index : index + _xRes; // up - obpos[1] = (_obstacles[index - _xRes] == 1) ? index : index - _xRes; // down - float dy = (obpos[0] == index || obpos[1] == index) ? 1.0f / _dx : gridSize; - - obpos[2] = (_obstacles[index + _slabSize] == 1) ? index : index + _slabSize; // out - obpos[3] = (_obstacles[index - _slabSize] == 1) ? index : index - _slabSize; // in - float dz = (obpos[2] == index || obpos[3] == index) ? 1.0f / _dx : gridSize; - - obpos[4] = (_obstacles[index + 1] == 1) ? index : index + 1; // right - obpos[5] = (_obstacles[index - 1] == 1) ? index : index - 1; // left - float dx = (obpos[4] == index || obpos[5] == index) ? 1.0f / _dx : gridSize; - - float xV[2], yV[2], zV[2]; - - zV[1] = VORT_VEL(0, 2); - zV[0] = VORT_VEL(1, 2); - yV[1] = VORT_VEL(2, 1); - yV[0] = VORT_VEL(3, 1); - _xVorticity[vIndex] = (zV[1] - zV[0]) * dy + (-yV[1] + yV[0]) * dz; - - xV[1] = VORT_VEL(2, 0); - xV[0] = VORT_VEL(3, 0); - zV[1] = VORT_VEL(4, 2); - zV[0] = VORT_VEL(5, 2); - _yVorticity[vIndex] = (xV[1] - xV[0]) * dz + (-zV[1] + zV[0]) * dx; - - yV[1] = VORT_VEL(4, 1); - yV[0] = VORT_VEL(5, 1); - xV[1] = VORT_VEL(0, 0); - xV[0] = VORT_VEL(1, 0); - _zVorticity[vIndex] = (yV[1] - yV[0]) * dx + (-xV[1] + xV[0])* dy; - - _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] + - _yVorticity[vIndex] * _yVorticity[vIndex] + - _zVorticity[vIndex] * _zVorticity[vIndex]); - - } - vIndex++; - } - vIndex+=2; - } - //vIndex+=2*_xRes; - } - - // calculate normalized vorticity vectors - float eps = _vorticityEps; - - //index = _slabSize + _xRes + 1; - vIndex=_slabSize + _xRes + 1; - - for (int z = zBegin + bb; z < (zEnd - bt); z++) - { - size_t index = index_ +(z-1)*_slabSize; - vIndex = index-(zBegin-1+bb)*_slabSize; - - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - // - - if (!_obstacles[index]) - { - float N[3]; - - int up = (_obstacles[index + _xRes] == 1) ? vIndex : vIndex + _xRes; - int down = (_obstacles[index - _xRes] == 1) ? vIndex : vIndex - _xRes; - float dy = (up == vIndex || down == vIndex) ? 1.0f / _dx : gridSize; - - int out = (_obstacles[index + _slabSize] == 1) ? vIndex : vIndex + _slabSize; - int in = (_obstacles[index - _slabSize] == 1) ? vIndex : vIndex - _slabSize; - float dz = (out == vIndex || in == vIndex) ? 1.0f / _dx : gridSize; - - int right = (_obstacles[index + 1] == 1) ? vIndex : vIndex + 1; - int left = (_obstacles[index - 1] == 1) ? vIndex : vIndex - 1; - float dx = (right == vIndex || left == vIndex) ? 1.0f / _dx : gridSize; - - N[0] = (_vorticity[right] - _vorticity[left]) * dx; - N[1] = (_vorticity[up] - _vorticity[down]) * dy; - N[2] = (_vorticity[out] - _vorticity[in]) * dz; - - float magnitude = sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); - if (magnitude > FLT_EPSILON) - { - float flame_vort = (_fuel) ? _fuel[index]*flame_vorticity : 0.0f; - magnitude = 1.0f / magnitude; - N[0] *= magnitude; - N[1] *= magnitude; - N[2] *= magnitude; - - _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * (eps + flame_vort); - _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * (eps + flame_vort); - _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * (eps + flame_vort); - } - } // if - vIndex++; - } // x loop - vIndex+=2; - } // y loop - //vIndex+=2*_xRes; - } // z loop - - if (_xVorticity) delete[] _xVorticity; - if (_yVorticity) delete[] _yVorticity; - if (_zVorticity) delete[] _zVorticity; - if (_vorticity) delete[] _vorticity; -} - - -void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd) -{ - Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - - setZeroX(_xVelocityOld, res, zBegin, zEnd); - setZeroY(_yVelocityOld, res, zBegin, zEnd); - setZeroZ(_zVelocityOld, res, zBegin, zEnd); -} - -////////////////////////////////////////////////////////////////////// -// Advect using the MacCormack method from the Selle paper -////////////////////////////////////////////////////////////////////// -void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd) -{ - Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - - const float dt0 = _dt / _dx; - - int begin=zBegin * _slabSize; - int end=begin + (zEnd - zBegin) * _slabSize; - for (int x = begin; x < end; x++) - _xForce[x] = 0.0; - - // advectFieldMacCormack1(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res) - - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _densityTemp, res, zBegin, zEnd); - if (_heat) { - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd); - } - if (_fuel) { - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuelTemp, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _reactTemp, res, zBegin, zEnd); - } - if (_color_r) { - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_rTemp, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_gTemp, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_bTemp, res, zBegin, zEnd); - } - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, res, zBegin, zEnd); - - // Have to wait untill all the threads are done -> so continuing in step 3 -} - -////////////////////////////////////////////////////////////////////// -// Advect using the MacCormack method from the Selle paper -////////////////////////////////////////////////////////////////////// -void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) -{ - const float dt0 = _dt / _dx; - Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - - // use force array as temp array - float* t1 = _xForce; - - // advectFieldMacCormack2(dt, xVelocity, yVelocity, zVelocity, oldField, newField, tempfield, temp, res, obstacles) - - /* finish advection */ - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, _densityTemp, t1, res, _obstacles, zBegin, zEnd); - if (_heat) { - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd); - } - if (_fuel) { - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuel, _fuelTemp, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _react, _reactTemp, t1, res, _obstacles, zBegin, zEnd); - } - if (_color_r) { - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_r, _color_rTemp, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_g, _color_gTemp, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_b, _color_bTemp, t1, res, _obstacles, zBegin, zEnd); - } - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocityTemp, _xVelocity, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd); - - /* set boundary conditions for velocity */ - if(!_domainBcLeft) copyBorderX(_xVelocityTemp, res, zBegin, zEnd); - else setZeroX(_xVelocityTemp, res, zBegin, zEnd); - - if(!_domainBcFront) copyBorderY(_yVelocityTemp, res, zBegin, zEnd); - else setZeroY(_yVelocityTemp, res, zBegin, zEnd); - - if(!_domainBcTop) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd); - else setZeroZ(_zVelocityTemp, res, zBegin, zEnd); - - /* clear data boundaries */ - setZeroBorder(_density, res, zBegin, zEnd); - if (_fuel) { - setZeroBorder(_fuel, res, zBegin, zEnd); - setZeroBorder(_react, res, zBegin, zEnd); - } - if (_color_r) { - setZeroBorder(_color_r, res, zBegin, zEnd); - setZeroBorder(_color_g, res, zBegin, zEnd); - setZeroBorder(_color_b, res, zBegin, zEnd); - } -} - - -void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *heat, - float *r, float *g, float *b, int total_cells, float dt) -{ - float burning_rate = *_burning_rate; - float flame_smoke = *_flame_smoke; - float ignition_point = *_ignition_temp; - float temp_max = *_max_temp; - - for (int index = 0; index < total_cells; index++) - { - float orig_fuel = fuel[index]; - float orig_smoke = smoke[index]; - float smoke_emit = 0.0f; - float flame = 0.0f; - - /* process fuel */ - fuel[index] -= burning_rate * dt; - if (fuel[index] < 0.0f) fuel[index] = 0.0f; - /* process reaction coordinate */ - if (orig_fuel > FLT_EPSILON) { - react[index] *= fuel[index]/orig_fuel; - flame = pow(react[index], 0.5f); - } - else { - react[index] = 0.0f; - } - - /* emit smoke based on fuel burn rate and "flame_smoke" factor */ - smoke_emit = (orig_fuel < 1.0f) ? (1.0f - orig_fuel)*0.5f : 0.0f; - smoke_emit = (smoke_emit + 0.5f) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke; - smoke[index] += smoke_emit; - CLAMP(smoke[index], 0.0f, 1.0f); - - /* set fluid temperature from the flame temperature profile */ - if (heat && flame) - heat[index] = (1.0f - flame)*ignition_point + flame*temp_max; - - /* mix new color */ - if (r && smoke_emit > FLT_EPSILON) { - float smoke_factor = smoke[index]/(orig_smoke+smoke_emit); - r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor; - g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor; - b[index] = (b[index] + _flame_smoke_color[2] * smoke_emit) * smoke_factor; - } - } -} - -void FLUID_3D::updateFlame(float *react, float *flame, int total_cells) -{ - for (int index = 0; index < total_cells; index++) - { - /* model flame temperature curve from the reaction coordinate (fuel) - * TODO: Would probably be best to get rid of whole "flame" data field. - * Currently it's just sqrt mirror of reaction coordinate, and therefore - * basically just waste of memory and disk space... - */ - if (react[index]>0.0f) { - /* do a smooth falloff for rest of the values */ - flame[index] = pow(react[index], 0.5f); - } - else - flame[index] = 0.0f; - } -} diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h deleted file mode 100644 index 097451836f2..00000000000 --- a/intern/smoke/intern/FLUID_3D.h +++ /dev/null @@ -1,269 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// FLUID_3D.h: interface for the FLUID_3D class. -// -////////////////////////////////////////////////////////////////////// -// Heavy parallel optimization done. Many of the old functions now -// take begin and end parameters and process only specified part of the data. -// Some functions were divided into multiple ones. -// - MiikaH -////////////////////////////////////////////////////////////////////// - -#ifndef FLUID_3D_H -#define FLUID_3D_H - -#include <cstdlib> -#include <cmath> -#include <cstring> -#include <iostream> -#include "OBSTACLE.h" -// #include "WTURBULENCE.h" -#include "VEC3.h" - -using namespace std; -using namespace BasicVector; -struct WTURBULENCE; - -struct FLUID_3D -{ - public: - FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors); - FLUID_3D() {}; - virtual ~FLUID_3D(); - - void initHeat(); - void initFire(); - void initColors(float init_r, float init_g, float init_b); - - void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, - float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *ignition_temp, float *max_temp); - - // create & allocate vector noise advection - void initVectorNoise(int amplify); - - void addSmokeColumn(); - static void addSmokeTestCase(float* field, Vec3Int res); - - void step(float dt, float gravity[3]); - void addObstacle(OBSTACLE* obstacle); - - const float* xVelocity() { return _xVelocity; }; - const float* yVelocity() { return _yVelocity; }; - const float* zVelocity() { return _zVelocity; }; - - int xRes() const { return _xRes; }; - int yRes() const { return _yRes; }; - int zRes() const { return _zRes; }; - - public: - // dimensions - int _xRes, _yRes, _zRes, _maxRes; - Vec3Int _res; - size_t _totalCells; - int _slabSize; - float _dx; - float _p0[3]; - float _p1[3]; - float _totalTime; - int _totalSteps; - int _totalImgDumps; - int _totalVelDumps; - - void artificialDampingSL(int zBegin, int zEnd); - void artificialDampingExactSL(int pos); - - void setBorderObstacles(); - - // fields - float* _density; - float* _densityOld; - float* _heat; - float* _heatOld; - float* _xVelocity; - float* _yVelocity; - float* _zVelocity; - float* _xVelocityOb; - float* _yVelocityOb; - float* _zVelocityOb; - float* _xVelocityOld; - float* _yVelocityOld; - float* _zVelocityOld; - float* _xForce; - float* _yForce; - float* _zForce; - unsigned char* _obstacles; /* only used (useful) for static obstacles like domain boundaries */ - unsigned char* _obstaclesAnim; - - // Required for proper threading: - float* _xVelocityTemp; - float* _yVelocityTemp; - float* _zVelocityTemp; - float* _heatTemp; - float* _densityTemp; - - // fire simulation - float *_flame; - float *_fuel; - float *_fuelTemp; - float *_fuelOld; - float *_react; - float *_reactTemp; - float *_reactOld; - - // smoke color - float *_color_r; - float *_color_rOld; - float *_color_rTemp; - float *_color_g; - float *_color_gOld; - float *_color_gTemp; - float *_color_b; - float *_color_bOld; - float *_color_bTemp; - - - // CG fields - int _iterations; - - // simulation constants - float _dt; - float *_dtFactor; - float _vorticityEps; - float _heatDiffusion; - float *_vorticityRNA; // RNA-pointer. - float *_alpha; // for the buoyancy density term <-- as pointer to get blender RNA in here - float *_beta; // was _buoyancy <-- as pointer to get blender RNA in here - float _tempAmb; /* ambient temperature */ - float _constantScaling; - - bool _domainBcFront; // z - bool _domainBcTop; // y - bool _domainBcLeft; // x - bool _domainBcBack; // DOMAIN_BC_FRONT - bool _domainBcBottom; // DOMAIN_BC_TOP - bool _domainBcRight; // DOMAIN_BC_LEFT - int *_borderColli; // border collision rules <-- as pointer to get blender RNA in here - int _colloPrev; // To track whether value has been changed (to not - // have to recalibrate borders if nothing has changed - void setBorderCollisions(); - - void setObstacleVelocity(int zBegin, int zEnd); - - // WTURBULENCE object, if active - // WTURBULENCE* _wTurbulence; - - // boundary setting functions - void copyBorderAll(float* field, int zBegin, int zEnd); - - // timestepping functions - void wipeBoundaries(int zBegin, int zEnd); - void wipeBoundariesSL(int zBegin, int zEnd); - void addForce(int zBegin, int zEnd); - void addVorticity(int zBegin, int zEnd); - void addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd); - - // solver stuff - void project(); - void diffuseHeat(); - void diffuseColor(); - void solvePressure(float* field, float* b, unsigned char* skip); - void solvePressurePre(float* field, float* b, unsigned char* skip); - void solveHeat(float* field, float* b, unsigned char* skip); - void solveDiffusion(float* field, float* b, float* factor); - - - // handle obstacle boundaries - void setObstacleBoundaries(float *_pressure, int zBegin, int zEnd); - void setObstaclePressure(float *_pressure, int zBegin, int zEnd); - - void fixObstacleCompression(float *divergence); - - public: - // advection, accessed e.g. by WTURBULENCE class - //void advectMacCormack(); - void advectMacCormackBegin(int zBegin, int zEnd); - void advectMacCormackEnd1(int zBegin, int zEnd); - void advectMacCormackEnd2(int zBegin, int zEnd); - - void floodFillComponent(int *components, size_t *queue, size_t limit, size_t start, int from, int to); - void mergeComponents(int *components, size_t *queue, size_t cur, size_t other); - - /* burning */ - float *_burning_rate; // RNA pointer - float *_flame_smoke; // RNA pointer - float *_flame_smoke_color; // RNA pointer - float *_flame_vorticity; // RNA pointer - float *_ignition_temp; // RNA pointer - float *_max_temp; // RNA pointer - void processBurn(float *fuel, float *smoke, float *react, float *heat, - float *r, float *g, float *b, int total_cells, float dt); - void updateFlame(float *react, float *flame, int total_cells); - - // boundary setting functions - static void copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd); - static void copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd); - static void copyBorderZ(float* field, Vec3Int res, int zBegin, int zEnd); - static void setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd); - static void setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd); - static void setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd); - static void setZeroX(float* field, Vec3Int res, int zBegin, int zEnd); - static void setZeroY(float* field, Vec3Int res, int zBegin, int zEnd); - static void setZeroZ(float* field, Vec3Int res, int zBegin, int zEnd); - static void setZeroBorder(float* field, Vec3Int res, int zBegin, int zEnd) { - setZeroX(field, res, zBegin, zEnd); - setZeroY(field, res, zBegin, zEnd); - setZeroZ(field, res, zBegin, zEnd); - }; - - - - // static advection functions, also used by WTURBULENCE - static void advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd); - static void advectFieldMacCormack1(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* tempResult, Vec3Int res, int zBegin, int zEnd); - static void advectFieldMacCormack2(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, float* tempResult, float* temp1,Vec3Int res, const unsigned char* obstacles, int zBegin, int zEnd); - - - // temp ones for testing - /*static void advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles);*/ - /*static void advectFieldSemiLagrange2(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res);*/ - - // maccormack helper functions - static void clampExtrema(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd); - static void clampOutsideRays(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection, int zBegin, int zEnd); - - - - // output helper functions - // static void writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.); - // static void writeImageSliceYZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.); - // static void writeImageSliceXZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.); - // static void writeProjectedIntern(const float *field, Vec3Int res, int dir1, int dir2, string prefix, int picCnt, float scale=1.); -}; - -#endif diff --git a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp deleted file mode 100644 index b05c45e1a02..00000000000 --- a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// FLUID_3D.cpp: implementation of the FLUID_3D class. -// -////////////////////////////////////////////////////////////////////// -// Both solvers optimized by merging loops and precalculating -// stuff used in iteration loop. -// - MiikaH -////////////////////////////////////////////////////////////////////// - -#include "FLUID_3D.h" -#include <cstring> -#define SOLVER_ACCURACY 1e-06 - -////////////////////////////////////////////////////////////////////// -// solve the heat equation with CG -////////////////////////////////////////////////////////////////////// -void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip) -{ - int x, y, z; - const int twoxr = 2 * _xRes; - size_t index; - const float heatConst = _dt * _heatDiffusion / (_dx * _dx); - float *_q, *_residual, *_direction, *_Acenter; - - // i = 0 - int i = 0; - - _residual = new float[_totalCells]; // set 0 - _direction = new float[_totalCells]; // set 0 - _q = new float[_totalCells]; // set 0 - _Acenter = new float[_totalCells]; // set 0 - - memset(_residual, 0, sizeof(float)*_totalCells); - memset(_q, 0, sizeof(float)*_totalCells); - memset(_direction, 0, sizeof(float)*_totalCells); - memset(_Acenter, 0, sizeof(float)*_totalCells); - - float deltaNew = 0.0f; - - // r = b - Ax - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += twoxr) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - // if the cell is a variable - _Acenter[index] = 1.0f; - if (!skip[index]) - { - // set the matrix to the Poisson stencil in order - if (!skip[index + 1]) _Acenter[index] += heatConst; - if (!skip[index - 1]) _Acenter[index] += heatConst; - if (!skip[index + _xRes]) _Acenter[index] += heatConst; - if (!skip[index - _xRes]) _Acenter[index] += heatConst; - if (!skip[index + _slabSize]) _Acenter[index] += heatConst; - if (!skip[index - _slabSize]) _Acenter[index] += heatConst; - - _residual[index] = b[index] - (_Acenter[index] * field[index] + - field[index - 1] * (skip[index - 1] ? 0.0f : -heatConst) + - field[index + 1] * (skip[index + 1] ? 0.0f : -heatConst) + - field[index - _xRes] * (skip[index - _xRes] ? 0.0f : -heatConst) + - field[index + _xRes] * (skip[index + _xRes] ? 0.0f : -heatConst) + - field[index - _slabSize] * (skip[index - _slabSize] ? 0.0f : -heatConst) + - field[index + _slabSize] * (skip[index + _slabSize] ? 0.0f : -heatConst)); - } - else - { - _residual[index] = 0.0f; - } - - _direction[index] = _residual[index]; - deltaNew += _residual[index] * _residual[index]; - } - - - // While deltaNew > (eps^2) * delta0 - const float eps = SOLVER_ACCURACY; - float maxR = 2.0f * eps; - while ((i < _iterations) && (maxR > eps)) - { - // q = Ad - float alpha = 0.0f; - - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += twoxr) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - // if the cell is a variable - if (!skip[index]) - { - - _q[index] = (_Acenter[index] * _direction[index] + - _direction[index - 1] * (skip[index - 1] ? 0.0f : -heatConst) + - _direction[index + 1] * (skip[index + 1] ? 0.0f : -heatConst) + - _direction[index - _xRes] * (skip[index - _xRes] ? 0.0f : -heatConst) + - _direction[index + _xRes] * (skip[index + _xRes] ? 0.0f : -heatConst) + - _direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0f : -heatConst) + - _direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0f : -heatConst)); - } - else - { - _q[index] = 0.0f; - } - alpha += _direction[index] * _q[index]; - } - - if (fabs(alpha) > 0.0f) - alpha = deltaNew / alpha; - - float deltaOld = deltaNew; - deltaNew = 0.0f; - - maxR = 0.0f; - - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += twoxr) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - field[index] += alpha * _direction[index]; - - _residual[index] -= alpha * _q[index]; - maxR = (_residual[index] > maxR) ? _residual[index] : maxR; - - deltaNew += _residual[index] * _residual[index]; - } - - float beta = deltaNew / deltaOld; - - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += twoxr) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - _direction[index] = _residual[index] + beta * _direction[index]; - - - i++; - } - // cout << i << " iterations converged to " << maxR << endl; - - if (_residual) delete[] _residual; - if (_direction) delete[] _direction; - if (_q) delete[] _q; - if (_Acenter) delete[] _Acenter; -} - -void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip) -{ - int x, y, z; - size_t index; - float *_q, *_Precond, *_h, *_residual, *_direction; - - // i = 0 - int i = 0; - - _residual = new float[_totalCells]; // set 0 - _direction = new float[_totalCells]; // set 0 - _q = new float[_totalCells]; // set 0 - _h = new float[_totalCells]; // set 0 - _Precond = new float[_totalCells]; // set 0 - - memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes); - memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes); - memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes); - memset(_h, 0, sizeof(float)*_xRes*_yRes*_zRes); - memset(_Precond, 0, sizeof(float)*_xRes*_yRes*_zRes); - - float deltaNew = 0.0f; - - // r = b - Ax - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - // if the cell is a variable - float Acenter = 0.0f; - if (!skip[index]) - { - // set the matrix to the Poisson stencil in order - if (!skip[index + 1]) Acenter += 1.0f; - if (!skip[index - 1]) Acenter += 1.0f; - if (!skip[index + _xRes]) Acenter += 1.0f; - if (!skip[index - _xRes]) Acenter += 1.0f; - if (!skip[index + _slabSize]) Acenter += 1.0f; - if (!skip[index - _slabSize]) Acenter += 1.0f; - - _residual[index] = b[index] - (Acenter * field[index] + - field[index - 1] * (skip[index - 1] ? 0.0f : -1.0f) + - field[index + 1] * (skip[index + 1] ? 0.0f : -1.0f) + - field[index - _xRes] * (skip[index - _xRes] ? 0.0f : -1.0f)+ - field[index + _xRes] * (skip[index + _xRes] ? 0.0f : -1.0f)+ - field[index - _slabSize] * (skip[index - _slabSize] ? 0.0f : -1.0f)+ - field[index + _slabSize] * (skip[index + _slabSize] ? 0.0f : -1.0f) ); - } - else - { - _residual[index] = 0.0f; - } - - // P^-1 - if(Acenter < 1.0f) - _Precond[index] = 0.0; - else - _Precond[index] = 1.0f / Acenter; - - // p = P^-1 * r - _direction[index] = _residual[index] * _Precond[index]; - - deltaNew += _residual[index] * _direction[index]; - } - - - // While deltaNew > (eps^2) * delta0 - const float eps = SOLVER_ACCURACY; - //while ((i < _iterations) && (deltaNew > eps*delta0)) - float maxR = 2.0f * eps; - // while (i < _iterations) - while ((i < _iterations) && (maxR > 0.001f * eps)) - { - - float alpha = 0.0f; - - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - // if the cell is a variable - float Acenter = 0.0f; - if (!skip[index]) - { - // set the matrix to the Poisson stencil in order - if (!skip[index + 1]) Acenter += 1.0f; - if (!skip[index - 1]) Acenter += 1.0f; - if (!skip[index + _xRes]) Acenter += 1.0f; - if (!skip[index - _xRes]) Acenter += 1.0f; - if (!skip[index + _slabSize]) Acenter += 1.0f; - if (!skip[index - _slabSize]) Acenter += 1.0f; - - _q[index] = Acenter * _direction[index] + - _direction[index - 1] * (skip[index - 1] ? 0.0f : -1.0f) + - _direction[index + 1] * (skip[index + 1] ? 0.0f : -1.0f) + - _direction[index - _xRes] * (skip[index - _xRes] ? 0.0f : -1.0f) + - _direction[index + _xRes] * (skip[index + _xRes] ? 0.0f : -1.0f)+ - _direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0f : -1.0f) + - _direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0f : -1.0f); - } - else - { - _q[index] = 0.0f; - } - - alpha += _direction[index] * _q[index]; - } - - - if (fabs(alpha) > 0.0f) - alpha = deltaNew / alpha; - - float deltaOld = deltaNew; - deltaNew = 0.0f; - - maxR = 0.0; - - float tmp; - - // x = x + alpha * d - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - { - field[index] += alpha * _direction[index]; - - _residual[index] -= alpha * _q[index]; - - _h[index] = _Precond[index] * _residual[index]; - - tmp = _residual[index] * _h[index]; - deltaNew += tmp; - maxR = (tmp > maxR) ? tmp : maxR; - - } - - - // beta = deltaNew / deltaOld - float beta = deltaNew / deltaOld; - - // d = h + beta * d - index = _slabSize + _xRes + 1; - for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) - for (y = 1; y < _yRes - 1; y++, index += 2) - for (x = 1; x < _xRes - 1; x++, index++) - _direction[index] = _h[index] + beta * _direction[index]; - - // i = i + 1 - i++; - } - // cout << i << " iterations converged to " << sqrt(maxR) << endl; - - if (_h) delete[] _h; - if (_Precond) delete[] _Precond; - if (_residual) delete[] _residual; - if (_direction) delete[] _direction; - if (_q) delete[] _q; -} diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp deleted file mode 100644 index 60c13ae9e60..00000000000 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ /dev/null @@ -1,646 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// FLUID_3D.cpp: implementation of the static functions of the FLUID_3D class. -// -////////////////////////////////////////////////////////////////////// -// Heavy parallel optimization done. Many of the old functions now -// take begin and end parameters and process only specified part of the data. -// Some functions were divided into multiple ones. -// - MiikaH -////////////////////////////////////////////////////////////////////// - -#include <zlib.h> -#include "FLUID_3D.h" -#include "IMAGE.h" -#include "WTURBULENCE.h" -#include "INTERPOLATE.h" - -////////////////////////////////////////////////////////////////////// -// add a test cube of density to the center -////////////////////////////////////////////////////////////////////// -/* -void FLUID_3D::addSmokeColumn() { - addSmokeTestCase(_density, _res, 1.0); - // addSmokeTestCase(_zVelocity, _res, 1.0); - addSmokeTestCase(_heat, _res, 1.0); - if (_wTurbulence) { - addSmokeTestCase(_wTurbulence->getDensityBig(), _wTurbulence->getResBig(), 1.0); - } -} -*/ - -////////////////////////////////////////////////////////////////////// -// generic static version, so that it can be applied to the -// WTURBULENCE grid as well -////////////////////////////////////////////////////////////////////// - -void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res) -{ - const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res); - float dx = 1.0f / (float)maxRes; - - float xTotal = dx * res[0]; - float yTotal = dx * res[1]; - - float heighMin = 0.05; - float heighMax = 0.10; - - for (int y = 0; y < res[2]; y++) - for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++) - for (int x = 0; x < res[0]; x++) { - float xLength = x * dx - xTotal * 0.4f; - float yLength = y * dx - yTotal * 0.5f; - float radius = sqrtf(xLength * xLength + yLength * yLength); - - if (radius < 0.075f * xTotal) { - int index = x + y * res[0] + z * slabSize; - field[index] = 1.0f; - } - } -} - - -////////////////////////////////////////////////////////////////////// -// set x direction to Neumann boundary conditions -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - int index; - for (int z = zBegin; z < zEnd; z++) - for (int y = 0; y < res[1]; y++) - { - // left slab - index = y * res[0] + z * slabSize; - field[index] = field[index + 2]; - - // right slab - index = y * res[0] + z * slabSize + res[0] - 1; - field[index] = field[index - 2]; - } - } - -////////////////////////////////////////////////////////////////////// -// set y direction to Neumann boundary conditions -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - int index; - for (int z = zBegin; z < zEnd; z++) - for (int x = 0; x < res[0]; x++) - { - // front slab - index = x + z * slabSize; - field[index] = field[index + 2 * res[0]]; - - // back slab - index = x + z * slabSize + slabSize - res[0]; - field[index] = field[index - 2 * res[0]]; - } -} - -////////////////////////////////////////////////////////////////////// -// set z direction to Neumann boundary conditions -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - const int totalCells = res[0] * res[1] * res[2]; - const int cellsslab = totalCells - slabSize; - int index; - - if (zBegin == 0) { - for (int y = 0; y < res[1]; y++) - for (int x = 0; x < res[0]; x++) - { - // front slab - index = x + y * res[0]; - field[index] = field[index + 2 * slabSize]; - } - } - - if (zEnd == res[2]) { - for (int y = 0; y < res[1]; y++) - for (int x = 0; x < res[0]; x++) - { - // back slab - index = x + y * res[0] + cellsslab; - field[index] = field[index - 2 * slabSize]; - } - } - -} - -////////////////////////////////////////////////////////////////////// -// set x direction to zero -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setZeroX(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - int index; - for (int z = zBegin; z < zEnd; z++) - for (int y = 0; y < res[1]; y++) - { - // left slab - index = y * res[0] + z * slabSize; - field[index] = 0.0f; - - // right slab - index += res[0] - 1; - field[index] = 0.0f; - } -} - -////////////////////////////////////////////////////////////////////// -// set y direction to zero -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setZeroY(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - int index; - for (int z = zBegin; z < zEnd; z++) - for (int x = 0; x < res[0]; x++) - { - // bottom slab - index = x + z * slabSize; - field[index] = 0.0f; - - // top slab - index += slabSize - res[0]; - field[index] = 0.0f; - } -} - -////////////////////////////////////////////////////////////////////// -// set z direction to zero -////////////////////////////////////////////////////////////////////// -void FLUID_3D::setZeroZ(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - const int totalCells = res[0] * res[1] * res[2]; - - int index = 0; - if (zBegin == 0) - { - for (int y = 0; y < res[1]; y++) - for (int x = 0; x < res[0]; x++, index++) - { - // front slab - field[index] = 0.0f; - } - } - - if (zEnd == res[2]) - { - index=0; - int indexx=0; - const int cellsslab = totalCells - slabSize; - - for (int y = 0; y < res[1]; y++) - for (int x = 0; x < res[0]; x++, index++) - { - - // back slab - indexx = index + cellsslab; - field[indexx] = 0.0f; - } - } - } -////////////////////////////////////////////////////////////////////// -// copy grid boundary -////////////////////////////////////////////////////////////////////// -void FLUID_3D::copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - int index; - for (int z = zBegin; z < zEnd; z++) - for (int y = 0; y < res[1]; y++) - { - // left slab - index = y * res[0] + z * slabSize; - field[index] = field[index + 1]; - - // right slab - index += res[0] - 1; - field[index] = field[index - 1]; - } -} -void FLUID_3D::copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - //const int totalCells = res[0] * res[1] * res[2]; - int index; - for (int z = zBegin; z < zEnd; z++) - for (int x = 0; x < res[0]; x++) - { - // bottom slab - index = x + z * slabSize; - field[index] = field[index + res[0]]; - // top slab - index += slabSize - res[0]; - field[index] = field[index - res[0]]; - } -} -void FLUID_3D::copyBorderZ(float* field, Vec3Int res, int zBegin, int zEnd) -{ - const int slabSize = res[0] * res[1]; - const int totalCells = res[0] * res[1] * res[2]; - int index=0; - - if (zBegin == 0) - { - for (int y = 0; y < res[1]; y++) - for (int x = 0; x < res[0]; x++, index++) - { - field[index] = field[index + slabSize]; - } - } - - if (zEnd == res[2]) - { - - index=0; - int indexx=0; - const int cellsslab = totalCells - slabSize; - - for (int y = 0; y < res[1]; y++) - for (int x = 0; x < res[0]; x++, index++) - { - // back slab - indexx = index + cellsslab; - field[indexx] = field[indexx - slabSize]; - } - } -} - -///////////////////////////////////////////////////////////////////// -// advect field with the semi lagrangian method -////////////////////////////////////////////////////////////////////// -void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd) -{ - const int xres = res[0]; - const int yres = res[1]; - const int zres = res[2]; - const int slabSize = res[0] * res[1]; - - - for (int z = zBegin; z < zEnd; z++) - for (int y = 0; y < yres; y++) - for (int x = 0; x < xres; x++) - { - const int index = x + y * xres + z * xres*yres; - - // backtrace - float xTrace = x - dt * velx[index]; - float yTrace = y - dt * vely[index]; - float zTrace = z - dt * velz[index]; - - // clamp backtrace to grid boundaries - if (xTrace < 0.5f) xTrace = 0.5f; - if (xTrace > xres - 1.5f) xTrace = xres - 1.5f; - if (yTrace < 0.5f) yTrace = 0.5f; - if (yTrace > yres - 1.5f) yTrace = yres - 1.5f; - if (zTrace < 0.5f) zTrace = 0.5f; - if (zTrace > zres - 1.5f) zTrace = zres - 1.5f; - - // locate neighbors to interpolate - const int x0 = (int)xTrace; - const int x1 = x0 + 1; - const int y0 = (int)yTrace; - const int y1 = y0 + 1; - const int z0 = (int)zTrace; - const int z1 = z0 + 1; - - // get interpolation weights - const float s1 = xTrace - x0; - const float s0 = 1.0f - s1; - const float t1 = yTrace - y0; - const float t0 = 1.0f - t1; - const float u1 = zTrace - z0; - const float u0 = 1.0f - u1; - - const int i000 = x0 + y0 * xres + z0 * slabSize; - const int i010 = x0 + y1 * xres + z0 * slabSize; - const int i100 = x1 + y0 * xres + z0 * slabSize; - const int i110 = x1 + y1 * xres + z0 * slabSize; - const int i001 = x0 + y0 * xres + z1 * slabSize; - const int i011 = x0 + y1 * xres + z1 * slabSize; - const int i101 = x1 + y0 * xres + z1 * slabSize; - const int i111 = x1 + y1 * xres + z1 * slabSize; - - // interpolate - // (indices could be computed once) - newField[index] = u0 * (s0 * (t0 * oldField[i000] + - t1 * oldField[i010]) + - s1 * (t0 * oldField[i100] + - t1 * oldField[i110])) + - u1 * (s0 * (t0 * oldField[i001] + - t1 * oldField[i011]) + - s1 * (t0 * oldField[i101] + - t1 * oldField[i111])); - } -} - - -///////////////////////////////////////////////////////////////////// -// advect field with the maccormack method -// -// comments are the pseudocode from selle's paper -////////////////////////////////////////////////////////////////////// -void FLUID_3D::advectFieldMacCormack1(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* tempResult, Vec3Int res, int zBegin, int zEnd) -{ - /*const int sx= res[0]; - const int sy= res[1]; - const int sz= res[2]; - - for (int x = 0; x < sx * sy * sz; x++) - phiHatN[x] = phiHatN1[x] = oldField[x];*/ // not needed as all the values are written first - - float*& phiN = oldField; - float*& phiN1 = tempResult; - - - - // phiHatN1 = A(phiN) - advectFieldSemiLagrange( dt, xVelocity, yVelocity, zVelocity, phiN, phiN1, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole) -} - - - -void FLUID_3D::advectFieldMacCormack2(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, float* tempResult, float* temp1, Vec3Int res, const unsigned char* obstacles, int zBegin, int zEnd) -{ - float* phiHatN = tempResult; - float* t1 = temp1; - const int sx= res[0]; - const int sy= res[1]; - - float*& phiN = oldField; - float*& phiN1 = newField; - - - - // phiHatN = A^R(phiHatN1) - advectFieldSemiLagrange( -1.0f*dt, xVelocity, yVelocity, zVelocity, phiHatN, t1, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole) - - // phiN1 = phiHatN1 + (phiN - phiHatN) / 2 - const int border = 0; - for (int z = zBegin+border; z < zEnd-border; z++) - for (int y = border; y < sy-border; y++) - for (int x = border; x < sx-border; x++) { - int index = x + y * sx + z * sx*sy; - phiN1[index] = phiHatN[index] + (phiN[index] - t1[index]) * 0.50f; - //phiN1[index] = phiHatN1[index]; // debug, correction off - } - copyBorderX(phiN1, res, zBegin, zEnd); - copyBorderY(phiN1, res, zBegin, zEnd); - copyBorderZ(phiN1, res, zBegin, zEnd); - - // clamp any newly created extrema - clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole) - - // if the error estimate was bad, revert to first order - clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN, zBegin, zEnd); // phiHatN is only used at cells within thread range, so its ok - -} - - -////////////////////////////////////////////////////////////////////// -// Clamp the extrema generated by the BFECC error correction -////////////////////////////////////////////////////////////////////// -void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd) -{ - const int xres= res[0]; - const int yres= res[1]; - const int zres= res[2]; - const int slabSize = res[0] * res[1]; - - int bb=0; - int bt=0; - - if (zBegin == 0) {bb = 1;} - if (zEnd == res[2]) {bt = 1;} - - - for (int z = zBegin+bb; z < zEnd-bt; z++) - for (int y = 1; y < yres-1; y++) - for (int x = 1; x < xres-1; x++) - { - const int index = x + y * xres+ z * xres*yres; - // backtrace - float xTrace = x - dt * velx[index]; - float yTrace = y - dt * vely[index]; - float zTrace = z - dt * velz[index]; - - // clamp backtrace to grid boundaries - if (xTrace < 0.5f) xTrace = 0.5f; - if (xTrace > xres - 1.5f) xTrace = xres - 1.5f; - if (yTrace < 0.5f) yTrace = 0.5f; - if (yTrace > yres - 1.5f) yTrace = yres - 1.5f; - if (zTrace < 0.5f) zTrace = 0.5f; - if (zTrace > zres - 1.5f) zTrace = zres - 1.5f; - - // locate neighbors to interpolate - const int x0 = (int)xTrace; - const int x1 = x0 + 1; - const int y0 = (int)yTrace; - const int y1 = y0 + 1; - const int z0 = (int)zTrace; - const int z1 = z0 + 1; - - const int i000 = x0 + y0 * xres + z0 * slabSize; - const int i010 = x0 + y1 * xres + z0 * slabSize; - const int i100 = x1 + y0 * xres + z0 * slabSize; - const int i110 = x1 + y1 * xres + z0 * slabSize; - const int i001 = x0 + y0 * xres + z1 * slabSize; - const int i011 = x0 + y1 * xres + z1 * slabSize; - const int i101 = x1 + y0 * xres + z1 * slabSize; - const int i111 = x1 + y1 * xres + z1 * slabSize; - - float minField = oldField[i000]; - float maxField = oldField[i000]; - - minField = (oldField[i010] < minField) ? oldField[i010] : minField; - maxField = (oldField[i010] > maxField) ? oldField[i010] : maxField; - - minField = (oldField[i100] < minField) ? oldField[i100] : minField; - maxField = (oldField[i100] > maxField) ? oldField[i100] : maxField; - - minField = (oldField[i110] < minField) ? oldField[i110] : minField; - maxField = (oldField[i110] > maxField) ? oldField[i110] : maxField; - - minField = (oldField[i001] < minField) ? oldField[i001] : minField; - maxField = (oldField[i001] > maxField) ? oldField[i001] : maxField; - - minField = (oldField[i011] < minField) ? oldField[i011] : minField; - maxField = (oldField[i011] > maxField) ? oldField[i011] : maxField; - - minField = (oldField[i101] < minField) ? oldField[i101] : minField; - maxField = (oldField[i101] > maxField) ? oldField[i101] : maxField; - - minField = (oldField[i111] < minField) ? oldField[i111] : minField; - maxField = (oldField[i111] > maxField) ? oldField[i111] : maxField; - - newField[index] = (newField[index] > maxField) ? maxField : newField[index]; - newField[index] = (newField[index] < minField) ? minField : newField[index]; - } -} - -////////////////////////////////////////////////////////////////////// -// Reverts any backtraces that go into boundaries back to first -// order -- in this case the error correction term was totally -// incorrect -////////////////////////////////////////////////////////////////////// -void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection, int zBegin, int zEnd) -{ - const int sx= res[0]; - const int sy= res[1]; - const int sz= res[2]; - const int slabSize = res[0] * res[1]; - - int bb=0; - int bt=0; - - if (zBegin == 0) {bb = 1;} - if (zEnd == res[2]) {bt = 1;} - - for (int z = zBegin+bb; z < zEnd-bt; z++) - for (int y = 1; y < sy-1; y++) - for (int x = 1; x < sx-1; x++) - { - const int index = x + y * sx+ z * slabSize; - // backtrace - float xBackward = x + dt * velx[index]; - float yBackward = y + dt * vely[index]; - float zBackward = z + dt * velz[index]; - float xTrace = x - dt * velx[index]; - float yTrace = y - dt * vely[index]; - float zTrace = z - dt * velz[index]; - - // see if it goes outside the boundaries - bool hasObstacle = - (zTrace < 1.0f) || (zTrace > sz - 2.0f) || - (yTrace < 1.0f) || (yTrace > sy - 2.0f) || - (xTrace < 1.0f) || (xTrace > sx - 2.0f) || - (zBackward < 1.0f) || (zBackward > sz - 2.0f) || - (yBackward < 1.0f) || (yBackward > sy - 2.0f) || - (xBackward < 1.0f) || (xBackward > sx - 2.0f); - // reuse old advection instead of doing another one... - if(hasObstacle) { newField[index] = oldAdvection[index]; continue; } - - // clamp to prevent an out of bounds access when looking into - // the _obstacles array - zTrace = (zTrace < 0.5f) ? 0.5f : zTrace; - zTrace = (zTrace > sz - 1.5f) ? sz - 1.5f : zTrace; - yTrace = (yTrace < 0.5f) ? 0.5f : yTrace; - yTrace = (yTrace > sy - 1.5f) ? sy - 1.5f : yTrace; - xTrace = (xTrace < 0.5f) ? 0.5f : xTrace; - xTrace = (xTrace > sx - 1.5f) ? sx - 1.5f : xTrace; - - // locate neighbors to interpolate, - // do backward first since we will use the forward indices if a - // reversion is actually necessary - zBackward = (zBackward < 0.5f) ? 0.5f : zBackward; - zBackward = (zBackward > sz - 1.5f) ? sz - 1.5f : zBackward; - yBackward = (yBackward < 0.5f) ? 0.5f : yBackward; - yBackward = (yBackward > sy - 1.5f) ? sy - 1.5f : yBackward; - xBackward = (xBackward < 0.5f) ? 0.5f : xBackward; - xBackward = (xBackward > sx - 1.5f) ? sx - 1.5f : xBackward; - - int x0 = (int)xBackward; - int x1 = x0 + 1; - int y0 = (int)yBackward; - int y1 = y0 + 1; - int z0 = (int)zBackward; - int z1 = z0 + 1; - if(obstacles && !hasObstacle) { - hasObstacle = hasObstacle || - obstacles[x0 + y0 * sx + z0*slabSize] || - obstacles[x0 + y1 * sx + z0*slabSize] || - obstacles[x1 + y0 * sx + z0*slabSize] || - obstacles[x1 + y1 * sx + z0*slabSize] || - obstacles[x0 + y0 * sx + z1*slabSize] || - obstacles[x0 + y1 * sx + z1*slabSize] || - obstacles[x1 + y0 * sx + z1*slabSize] || - obstacles[x1 + y1 * sx + z1*slabSize] ; - } - // reuse old advection instead of doing another one... - if(hasObstacle) { newField[index] = oldAdvection[index]; continue; } - - x0 = (int)xTrace; - x1 = x0 + 1; - y0 = (int)yTrace; - y1 = y0 + 1; - z0 = (int)zTrace; - z1 = z0 + 1; - if(obstacles && !hasObstacle) { - hasObstacle = hasObstacle || - obstacles[x0 + y0 * sx + z0*slabSize] || - obstacles[x0 + y1 * sx + z0*slabSize] || - obstacles[x1 + y0 * sx + z0*slabSize] || - obstacles[x1 + y1 * sx + z0*slabSize] || - obstacles[x0 + y0 * sx + z1*slabSize] || - obstacles[x0 + y1 * sx + z1*slabSize] || - obstacles[x1 + y0 * sx + z1*slabSize] || - obstacles[x1 + y1 * sx + z1*slabSize] ; - } // obstacle array - // reuse old advection instead of doing another one... - if(hasObstacle) { newField[index] = oldAdvection[index]; continue; } - - // see if either the forward or backward ray went into - // a boundary - if (hasObstacle) { - // get interpolation weights - float s1 = xTrace - x0; - float s0 = 1.0f - s1; - float t1 = yTrace - y0; - float t0 = 1.0f - t1; - float u1 = zTrace - z0; - float u0 = 1.0f - u1; - - const int i000 = x0 + y0 * sx + z0 * slabSize; - const int i010 = x0 + y1 * sx + z0 * slabSize; - const int i100 = x1 + y0 * sx + z0 * slabSize; - const int i110 = x1 + y1 * sx + z0 * slabSize; - const int i001 = x0 + y0 * sx + z1 * slabSize; - const int i011 = x0 + y1 * sx + z1 * slabSize; - const int i101 = x1 + y0 * sx + z1 * slabSize; - const int i111 = x1 + y1 * sx + z1 * slabSize; - - // interpolate, (indices could be computed once) - newField[index] = u0 * (s0 * ( - t0 * oldField[i000] + - t1 * oldField[i010]) + - s1 * (t0 * oldField[i100] + - t1 * oldField[i110])) + - u1 * (s0 * (t0 * oldField[i001] + - t1 * oldField[i011]) + - s1 * (t0 * oldField[i101] + - t1 * oldField[i111])); - } - } // xyz -} diff --git a/intern/smoke/intern/IMAGE.h b/intern/smoke/intern/IMAGE.h deleted file mode 100644 index 4680e4eace2..00000000000 --- a/intern/smoke/intern/IMAGE.h +++ /dev/null @@ -1,289 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -////////////////////////////////////////////////////////////////////// -// -#ifndef IMAGE_H -#define IMAGE_H - -#include <stdlib.h> -#include <string> -#include <fstream> -#include <sstream> -#include <zlib.h> - -////////////////////////////////////////////////////////////////////// -// NT helper functions -////////////////////////////////////////////////////////////////////// -template < class T > inline T ABS( T a ) { - return (0 < a) ? a : -a ; -} - -template < class T > inline void SWAP_POINTERS( T &a, T &b ) { - T temp = a; - a = b; - b = temp; -} - -template < class T > inline void CLAMP( T &a, T b=0., T c=1.) { - if(a<b) { a=b; return; } - if(a>c) { a=c; return; } -} - -template < class T > inline T MIN( const T& a, const T& b) { - return (a < b) ? a : b; -} - -template < class T > inline T MAX( const T& a, const T& b) { - return (a > b) ? a : b; -} - -template < class T > inline T MAX3( const T& a, const T& b, const T& c) { - T max = (a > b) ? a : b; - max = (max > c) ? max : c; - return max; -} - -template < class T > inline float MAX3V( const T& vec) { - float max = (vec[0] > vec[1]) ? vec[0] : vec[1]; - max = (max > vec[2]) ? max : vec[2]; - return max; -} - -template < class T > inline float MIN3V( const T& vec) { - float min = (vec[0] < vec[1]) ? vec[0] : vec[1]; - min = (min < vec[2]) ? min : vec[2]; - return min; -} - -////////////////////////////////////////////////////////////////////// -// PNG, POV-Ray, and PBRT output functions -////////////////////////////////////////////////////////////////////// -#ifndef NOPNG -#ifdef WIN32 -#include "png.h" -#else -#include <png.h> -#endif -#endif // NOPNG - -/* - NOTE when someone decided to uncomment the following code, please remember to put it between #ifndef NOPNG #endif -*/ -namespace IMAGE { - /* - static int writePng(const char *fileName, unsigned char **rowsp, int w, int h) - { - // defaults - const int colortype = PNG_COLOR_TYPE_RGBA; - const int bitdepth = 8; - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - png_bytep *rows = rowsp; - - FILE *fp = NULL; - std::string doing = "open for writing"; - if (!(fp = fopen(fileName, "wb"))) goto fail; - - if(!png_ptr) { - doing = "create png write struct"; - if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail; - } - if(!info_ptr) { - doing = "create png info struct"; - if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail; - } - - if (setjmp(png_jmpbuf(png_ptr))) goto fail; - doing = "init IO"; - png_init_io(png_ptr, fp); - doing = "write header"; - png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - doing = "write info"; - png_write_info(png_ptr, info_ptr); - doing = "write image"; - png_write_image(png_ptr, rows); - doing = "write end"; - png_write_end(png_ptr, NULL); - doing = "write destroy structs"; - png_destroy_write_struct(&png_ptr, &info_ptr); - - fclose( fp ); - return 0; - - fail: - std::cerr << "writePng: could not "<<doing<<" !\n"; - if(fp) fclose( fp ); - if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); - return -1; - } - */ - - ///////////////////////////////////////////////////////////////////////////////// - // write a numbered PNG file out, padded with zeros up to three zeros - ///////////////////////////////////////////////////////////////////////////////// - /* - static void dumpNumberedPNG(int counter, std::string prefix, float* field, int xRes, int yRes) - { - char buffer[256]; - sprintf(buffer,"%04i", counter); - std::string number = std::string(buffer); - - unsigned char pngbuf[xRes*yRes*4]; - unsigned char *rows[yRes]; - float *pfield = field; - for (int j=0; j<yRes; j++) { - for (int i=0; i<xRes; i++) { - float val = *pfield; - if(val>1.) val=1.; - if(val<0.) val=0.; - pngbuf[(j*xRes+i)*4+0] = (unsigned char)(val*255.); - pngbuf[(j*xRes+i)*4+1] = (unsigned char)(val*255.); - pngbuf[(j*xRes+i)*4+2] = (unsigned char)(val*255.); - pfield++; - pngbuf[(j*xRes+i)*4+3] = 255; - } - rows[j] = &pngbuf[(yRes-j-1)*xRes*4]; - } - std::string filenamePNG = prefix + number + std::string(".png"); - writePng(filenamePNG.c_str(), rows, xRes, yRes, false); - printf("Writing %s\n", filenamePNG.c_str()); - - } -*/ - ///////////////////////////////////////////////////////////////////////////////// - // export pbrt volumegrid geometry object - ///////////////////////////////////////////////////////////////////////////////// - /* - static void dumpPBRT(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes) - { - char buffer[256]; - sprintf(buffer,"%04i", counter); - std::string number = std::string(buffer); - - std::string filenamePbrt = prefix + number + std::string(".pbrt.gz"); - printf("Writing PBRT %s\n", filenamePbrt.c_str()); - - float *field = new float[xRes*yRes*zRes]; - // normalize values - float maxDensVal = ABS(fieldOrg[0]); - float targetNorm = 0.5; - for (int i = 0; i < xRes * yRes * zRes; i++) { - if(ABS(fieldOrg[i])>maxDensVal) maxDensVal = ABS(fieldOrg[i]); - field[i] = 0.; - } - if(maxDensVal>0.) { - for (int i = 0; i < xRes * yRes * zRes; i++) { - field[i] = ABS(fieldOrg[i]) / maxDensVal * targetNorm; - } - } - - std::fstream fout; - fout.open(filenamePbrt.c_str(), std::ios::out); - - int maxRes = (xRes > yRes) ? xRes : yRes; - maxRes = (maxRes > zRes) ? maxRes : zRes; - - const float xSize = 1.0 / (float)maxRes * (float)xRes; - const float ySize = 1.0 / (float)maxRes * (float)yRes; - const float zSize = 1.0 / (float)maxRes * (float)zRes; - - gzFile file; - file = gzopen(filenamePbrt.c_str(), "wb1"); - if (file == NULL) { - std::cerr << " Couldn't write file " << filenamePbrt << "!!!" << std::endl; - return; - } - - // dimensions - gzprintf(file, "Volume \"volumegrid\" \n"); - gzprintf(file, " \"integer nx\" %i\n", xRes); - gzprintf(file, " \"integer ny\" %i\n", yRes); - gzprintf(file, " \"integer nz\" %i\n", zRes); - gzprintf(file, " \"point p0\" [ 0.0 0.0 0.0 ] \"point p1\" [%f %f %f ] \n", xSize, ySize, zSize); - gzprintf(file, " \"float density\" [ \n"); - for (int i = 0; i < xRes * yRes * zRes; i++) - gzprintf(file, "%f ", field[i]); - gzprintf(file, "] \n \n"); - - gzclose(file); - delete[] field; - } - */ - - ///////////////////////////////////////////////////////////////////////////////// - // 3D df3 export - ///////////////////////////////////////////////////////////////////////////////// -/* - static void dumpDF3(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes) - { - char buffer[256]; - - // do deferred copying to final directory, better for network directories - sprintf(buffer,"%04i", counter); - std::string number = std::string(buffer); - std::string filenameDf3 = prefix + number + std::string(".df3.gz"); - printf("Writing DF3 %s\n", filenameDf3.c_str()); - - gzFile file; - file = gzopen(filenameDf3.c_str(), "wb1"); - if (file == NULL) { - std::cerr << " Couldn't write file " << filenameDf3 << "!!!" << std::endl; - return; - } - - // dimensions - const int byteSize = 2; - const unsigned short int onx=xRes,ony=yRes,onz=zRes; - unsigned short int nx,ny,nz; - nx = onx >> 8; - ny = ony >> 8; - nz = onz >> 8; - nx += (onx << 8); - ny += (ony << 8); - nz += (onz << 8); - gzwrite(file, (void*)&nx, sizeof(short)); - gzwrite(file, (void*)&ny, sizeof(short)); - gzwrite(file, (void*)&nz, sizeof(short)); - const int nitems = onx*ony*onz; - const float mul = (float)( (1<<(8*byteSize))-1); - - unsigned short int *buf = new unsigned short int[nitems]; - for (int k = 0; k < onz; k++) - for (int j = 0; j < ony; j++) - for (int i = 0; i < onx; i++) { - float val = fieldOrg[k*(onx*ony)+j*onx+i] ; - CLAMP(val); - buf[k*(onx*ony)+j*onx+i] = (short int)(val*mul); - } - gzwrite(file, (void*)buf, sizeof(unsigned short int)* nitems); - - gzclose(file); - delete[] buf; - } - */ - -}; - - -#endif - diff --git a/intern/smoke/intern/INTERPOLATE.h b/intern/smoke/intern/INTERPOLATE.h deleted file mode 100644 index e9821e4f93e..00000000000 --- a/intern/smoke/intern/INTERPOLATE.h +++ /dev/null @@ -1,230 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -////////////////////////////////////////////////////////////////////// -#ifndef INTERPOLATE_H -#define INTERPOLATE_H - -#include <iostream> -#include <VEC3.h> - -namespace INTERPOLATE { - -////////////////////////////////////////////////////////////////////// -// linear interpolators -////////////////////////////////////////////////////////////////////// -static inline float lerp(float t, float a, float b) { - return ( a + t * (b - a) ); -} - -static inline float lerp(float* field, float x, float y, int res) { - // clamp backtrace to grid boundaries - if (x < 0.5f) x = 0.5f; - if (x > res - 1.5f) x = res - 1.5f; - if (y < 0.5f) y = 0.5f; - if (y > res - 1.5f) y = res - 1.5f; - - const int x0 = (int)x; - const int y0 = (int)y; - x -= x0; - y -= y0; - float d00, d10, d01, d11; - - // lerp the velocities - d00 = field[x0 + y0 * res]; - d10 = field[(x0 + 1) + y0 * res]; - d01 = field[x0 + (y0 + 1) * res]; - d11 = field[(x0 + 1) + (y0 + 1) * res]; - return lerp(y, lerp(x, d00, d10), - lerp(x, d01, d11)); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// 3d linear interpolation -////////////////////////////////////////////////////////////////////////////////////////// -static inline float lerp3d(float* field, float x, float y, float z, int xres, int yres, int zres) { - // clamp pos to grid boundaries - if (x < 0.5f) x = 0.5f; - if (x > xres - 1.5f) x = xres - 1.5f; - if (y < 0.5f) y = 0.5f; - if (y > yres - 1.5f) y = yres - 1.5f; - if (z < 0.5f) z = 0.5f; - if (z > zres - 1.5f) z = zres - 1.5f; - - // locate neighbors to interpolate - const int x0 = (int)x; - const int x1 = x0 + 1; - const int y0 = (int)y; - const int y1 = y0 + 1; - const int z0 = (int)z; - const int z1 = z0 + 1; - - // get interpolation weights - const float s1 = x - (float)x0; - const float s0 = 1.0f - s1; - const float t1 = y - (float)y0; - const float t0 = 1.0f - t1; - const float u1 = z - (float)z0; - const float u0 = 1.0f - u1; - - const int slabSize = xres*yres; - const int i000 = x0 + y0 * xres + z0 * slabSize; - const int i010 = x0 + y1 * xres + z0 * slabSize; - const int i100 = x1 + y0 * xres + z0 * slabSize; - const int i110 = x1 + y1 * xres + z0 * slabSize; - const int i001 = x0 + y0 * xres + z1 * slabSize; - const int i011 = x0 + y1 * xres + z1 * slabSize; - const int i101 = x1 + y0 * xres + z1 * slabSize; - const int i111 = x1 + y1 * xres + z1 * slabSize; - - // interpolate (indices could be computed once) - return ( u0 * (s0 * (t0 * field[i000] + - t1 * field[i010]) + - s1 * (t0 * field[i100] + - t1 * field[i110])) + - u1 * (s0 * (t0 * field[i001] + - t1 * field[i011]) + - s1 * (t0 * field[i101] + - t1 * field[i111])) ); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// convert field entries of type T to floats, then interpolate -////////////////////////////////////////////////////////////////////////////////////////// -template <class T> -static inline float lerp3dToFloat(T* field1, - float x, float y, float z, int xres, int yres, int zres) { - // clamp pos to grid boundaries - if (x < 0.5f) x = 0.5f; - if (x > xres - 1.5f) x = xres - 1.5f; - if (y < 0.5f) y = 0.5f; - if (y > yres - 1.5f) y = yres - 1.5f; - if (z < 0.5f) z = 0.5f; - if (z > zres - 1.5f) z = zres - 1.5f; - - // locate neighbors to interpolate - const int x0 = (int)x; - const int x1 = x0 + 1; - const int y0 = (int)y; - const int y1 = y0 + 1; - const int z0 = (int)z; - const int z1 = z0 + 1; - - // get interpolation weights - const float s1 = x - (float)x0; - const float s0 = 1.0f - s1; - const float t1 = y - (float)y0; - const float t0 = 1.0f - t1; - const float u1 = z - (float)z0; - const float u0 = 1.0f - u1; - - const int slabSize = xres*yres; - const int i000 = x0 + y0 * xres + z0 * slabSize; - const int i010 = x0 + y1 * xres + z0 * slabSize; - const int i100 = x1 + y0 * xres + z0 * slabSize; - const int i110 = x1 + y1 * xres + z0 * slabSize; - const int i001 = x0 + y0 * xres + z1 * slabSize; - const int i011 = x0 + y1 * xres + z1 * slabSize; - const int i101 = x1 + y0 * xres + z1 * slabSize; - const int i111 = x1 + y1 * xres + z1 * slabSize; - - // interpolate (indices could be computed once) - return (float)( - ( u0 * (s0 * (t0 * (float)field1[i000] + - t1 * (float)field1[i010]) + - s1 * (t0 * (float)field1[i100] + - t1 * (float)field1[i110])) + - u1 * (s0 * (t0 * (float)field1[i001] + - t1 * (float)field1[i011]) + - s1 * (t0 * (float)field1[i101] + - t1 * (float)field1[i111])) ) ); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// interpolate a vector from 3 fields -////////////////////////////////////////////////////////////////////////////////////////// -static inline Vec3 lerp3dVec(float* field1, float* field2, float* field3, - float x, float y, float z, int xres, int yres, int zres) { - // clamp pos to grid boundaries - if (x < 0.5f) x = 0.5f; - if (x > xres - 1.5f) x = xres - 1.5f; - if (y < 0.5f) y = 0.5f; - if (y > yres - 1.5f) y = yres - 1.5f; - if (z < 0.5f) z = 0.5f; - if (z > zres - 1.5f) z = zres - 1.5f; - - // locate neighbors to interpolate - const int x0 = (int)x; - const int x1 = x0 + 1; - const int y0 = (int)y; - const int y1 = y0 + 1; - const int z0 = (int)z; - const int z1 = z0 + 1; - - // get interpolation weights - const float s1 = x - (float)x0; - const float s0 = 1.0f - s1; - const float t1 = y - (float)y0; - const float t0 = 1.0f - t1; - const float u1 = z - (float)z0; - const float u0 = 1.0f - u1; - - const int slabSize = xres*yres; - const int i000 = x0 + y0 * xres + z0 * slabSize; - const int i010 = x0 + y1 * xres + z0 * slabSize; - const int i100 = x1 + y0 * xres + z0 * slabSize; - const int i110 = x1 + y1 * xres + z0 * slabSize; - const int i001 = x0 + y0 * xres + z1 * slabSize; - const int i011 = x0 + y1 * xres + z1 * slabSize; - const int i101 = x1 + y0 * xres + z1 * slabSize; - const int i111 = x1 + y1 * xres + z1 * slabSize; - - // interpolate (indices could be computed once) - return Vec3( - ( u0 * (s0 * (t0 * field1[i000] + - t1 * field1[i010]) + - s1 * (t0 * field1[i100] + - t1 * field1[i110])) + - u1 * (s0 * (t0 * field1[i001] + - t1 * field1[i011]) + - s1 * (t0 * field1[i101] + - t1 * field1[i111])) ) , - ( u0 * (s0 * (t0 * field2[i000] + - t1 * field2[i010]) + - s1 * (t0 * field2[i100] + - t1 * field2[i110])) + - u1 * (s0 * (t0 * field2[i001] + - t1 * field2[i011]) + - s1 * (t0 * field2[i101] + - t1 * field2[i111])) ) , - ( u0 * (s0 * (t0 * field3[i000] + - t1 * field3[i010]) + - s1 * (t0 * field3[i100] + - t1 * field3[i110])) + - u1 * (s0 * (t0 * field3[i001] + - t1 * field3[i011]) + - s1 * (t0 * field3[i101] + - t1 * field3[i111])) ) - ); -} - -}; -#endif diff --git a/intern/smoke/intern/LICENSE.txt b/intern/smoke/intern/LICENSE.txt deleted file mode 100644 index 94a9ed024d3..00000000000 --- a/intern/smoke/intern/LICENSE.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/intern/smoke/intern/LU_HELPER.cpp b/intern/smoke/intern/LU_HELPER.cpp deleted file mode 100644 index 0a4260c2e64..00000000000 --- a/intern/smoke/intern/LU_HELPER.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/** \file - * \ingroup smoke - */ - -#include "LU_HELPER.h" - -int isNonsingular (sLU LU_) { - for (int j = 0; j < 3; j++) { - if (LU_.values[j][j] == 0) - return 0; - } - return 1; -} - -sLU computeLU( float a[3][3]) -{ - sLU result; - int m=3; - int n=3; - - //float LU_[3][3]; - for (int i = 0; i < m; i++) { - result.piv[i] = i; - for (int j = 0; j < n; j++) result.values[i][j]=a[i][j]; - } - - result.pivsign = 1; - //Real *LUrowi = 0;; - //Array1D<Real> LUcolj(m); - //float *LUrowi = 0; - float LUcolj[3]; - - // Outer loop. - - for (int j = 0; j < n; j++) { - - // Make a copy of the j-th column to localize references. - - for (int i = 0; i < m; i++) { - LUcolj[i] = result.values[i][j]; - } - - // Apply previous transformations. - - for (int i = 0; i < m; i++) { - //float LUrowi[3]; - //LUrowi = result.values[i]; - - // Most of the time is spent in the following dot product. - - int kmax = min(i,j); - double s = 0.0; - for (int k = 0; k < kmax; k++) { - s += (double)(result.values[i][k]*LUcolj[k]); - } - - result.values[i][j] = LUcolj[i] -= (float)s; - } - - // Find pivot and exchange if necessary. - - int p = j; - for (int i = j+1; i < m; i++) { - if (abs(LUcolj[i]) > abs(LUcolj[p])) { - p = i; - } - } - if (p != j) { - int k=0; - for (k = 0; k < n; k++) { - double t = result.values[p][k]; - result.values[p][k] = result.values[j][k]; - result.values[j][k] = t; - } - k = result.piv[p]; - result.piv[p] = result.piv[j]; - result.piv[j] = k; - result.pivsign = -result.pivsign; - } - - // Compute multipliers. - - if ((j < m) && (result.values[j][j] != 0.0f)) { - for (int i = j+1; i < m; i++) { - result.values[i][j] /= result.values[j][j]; - } - } - } - - return result; -} - -void solveLU3x3(sLU& A, float x[3], float b[3]) -{ - //TNT::Array1D<float> jamaB = TNT::Array1D<float>(3, &b[0]); - //TNT::Array1D<float> jamaX = A.solve(jamaB); - - - // Solve A, B - - { - if (!isNonsingular(A)) { - x[0]=0.0f; - x[1]=0.0f; - x[2]=0.0f; - return; - } - - - //Array1D<Real> Ax = permute_copy(b, piv); - float Ax[3]; - - // permute copy: b , A.piv - { - for (int i = 0; i < 3; i++) - Ax[i] = b[A.piv[i]]; - } - - // Solve L*Y = B(piv) - for (int k = 0; k < 3; k++) { - for (int i = k+1; i < 3; i++) { - Ax[i] -= Ax[k]*A.values[i][k]; - } - } - - // Solve U*X = Y; - for (int k = 2; k >= 0; k--) { - Ax[k] /= A.values[k][k]; - for (int i = 0; i < k; i++) - Ax[i] -= Ax[k]*A.values[i][k]; - } - - - x[0] = Ax[0]; - x[1] = Ax[1]; - x[2] = Ax[2]; - return; - } -} diff --git a/intern/smoke/intern/LU_HELPER.h b/intern/smoke/intern/LU_HELPER.h deleted file mode 100644 index 3cc8e9e3ced..00000000000 --- a/intern/smoke/intern/LU_HELPER.h +++ /dev/null @@ -1,54 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -////////////////////////////////////////////////////////////////////// -// Modified to not require TNT matrix library anymore. It was very slow -// when being run in parallel. Required TNT JAMA:LU libraries were -// converted into independent functions. -// - MiikaH -////////////////////////////////////////////////////////////////////// - -#ifndef LU_HELPER_H -#define LU_HELPER_H - -#include <cmath> -#include <algorithm> - -using namespace std; - -////////////////////////////////////////////////////////////////////// -// Helper function, compute eigenvalues of 3x3 matrix -////////////////////////////////////////////////////////////////////// - -struct sLU -{ - float values[3][3]; - int pivsign; - int piv[3]; -}; - - -int isNonsingular (sLU LU_); -sLU computeLU( float a[3][3]); -void solveLU3x3(sLU& A, float x[3], float b[3]); - - -#endif diff --git a/intern/smoke/intern/MERSENNETWISTER.h b/intern/smoke/intern/MERSENNETWISTER.h deleted file mode 100644 index b142ca4072b..00000000000 --- a/intern/smoke/intern/MERSENNETWISTER.h +++ /dev/null @@ -1,432 +0,0 @@ -/** \file - * \ingroup smoke - */ -// MersenneTwister.h -// Mersenne Twister random number generator -- a C++ class MTRand -// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com - -// The Mersenne Twister is an algorithm for generating random numbers. It -// was designed with consideration of the flaws in various other generators. -// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, -// are far greater. The generator is also fast; it avoids multiplication and -// division, and it benefits from caches and pipelines. For more information -// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html - -// Reference -// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally -// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on -// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. - -// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, -// Copyright (C) 2000 - 2003, Richard J. Wagner -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The names of its contributors may not be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The original code included the following notice: -// -// When you use this, send an email to: matumoto@math.keio.ac.jp -// with an appropriate reference to your work. -// -// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu -// when you write. - -#ifndef MERSENNETWISTER_H -#define MERSENNETWISTER_H - -// Not thread safe (unless auto-initialization is avoided and each thread has -// its own MTRand object) - -#include <iostream> -#include <limits.h> -#include <stdio.h> -#include <time.h> -#include <math.h> - -class MTRand { -// Data -public: - typedef unsigned long uint32; // unsigned integer type, at least 32 bits - - enum { N = 624 }; // length of state vector - enum { SAVE = N + 1 }; // length of array for save() - -protected: - enum { M = 397 }; // period parameter - - uint32 state[N]; // internal state - uint32 *pNext; // next value to get from state - int left; // number of values left before reload needed - - -//Methods -public: - MTRand( const uint32& oneSeed ); // initialize with a simple uint32 - MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array - MTRand(); // auto-initialize with /dev/urandom or time() and clock() - - // Do NOT use for CRYPTOGRAPHY without securely hashing several returned - // values together, otherwise the generator state can be learned after - // reading 624 consecutive values. - - // Access to 32-bit random numbers - double rand(); // real number in [0,1] - double rand( const double& n ); // real number in [0,n] - double randExc(); // real number in [0,1) - double randExc( const double& n ); // real number in [0,n) - double randDblExc(); // real number in (0,1) - double randDblExc( const double& n ); // real number in (0,n) - uint32 randInt(); // integer in [0,2^32-1] - uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32 - double operator()() { return rand(); } // same as rand() - - // Access to 53-bit random numbers (capacity of IEEE double precision) - double rand53(); // real number in [0,1) - - // Access to nonuniform random number distributions - double randNorm( const double& mean = 0.0, const double& variance = 1.0 ); - - // Re-seeding functions with same behavior as initializers - void seed( const uint32 oneSeed ); - void seed( uint32 *const bigSeed, const uint32 seedLength = N ); - void seed(); - - // Saving and loading generator state - void save( uint32* saveArray ) const; // to array of size SAVE - void load( uint32 *const loadArray ); // from such array - friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); - friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); - -protected: - void initialize( const uint32 oneSeed ); - void reload(); - uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } - uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } - uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } - uint32 mixBits( const uint32& u, const uint32& v ) const - { return hiBit(u) | loBits(v); } - uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const - { return m ^ (mixBits(s0,s1)>>1) ^ ((~loBit(s1) + 1) & 0x9908b0dfUL); } - static uint32 hash( time_t t, clock_t c ); -}; - - -inline MTRand::MTRand( const uint32& oneSeed ) - { seed(oneSeed); } - -inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) - { seed(bigSeed,seedLength); } - -inline MTRand::MTRand() - { seed(); } - -inline double MTRand::rand() - { return double(randInt()) * (1.0/4294967295.0); } - -inline double MTRand::rand( const double& n ) - { return rand() * n; } - -inline double MTRand::randExc() - { return double(randInt()) * (1.0/4294967296.0); } - -inline double MTRand::randExc( const double& n ) - { return randExc() * n; } - -inline double MTRand::randDblExc() - { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } - -inline double MTRand::randDblExc( const double& n ) - { return randDblExc() * n; } - -inline double MTRand::rand53() -{ - uint32 a = randInt() >> 5, b = randInt() >> 6; - return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada -} - -inline double MTRand::randNorm( const double& mean, const double& variance ) -{ - // Return a real number from a normal (Gaussian) distribution with given - // mean and variance by Box-Muller method - double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; - double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); - return mean + r * cos(phi); -} - -inline MTRand::uint32 MTRand::randInt() -{ - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - - if( left == 0 ) reload(); - --left; - - uint32 s1; - s1 = *pNext++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680UL; - s1 ^= (s1 << 15) & 0xefc60000UL; - return ( s1 ^ (s1 >> 18) ); -} - -inline MTRand::uint32 MTRand::randInt( const uint32& n ) -{ - // Find which bits are used in n - // Optimized by Magnus Jonsson (magnus@smartelectronix.com) - uint32 used = n; - used |= used >> 1; - used |= used >> 2; - used |= used >> 4; - used |= used >> 8; - used |= used >> 16; - - // Draw numbers until one is found in [0,n] - uint32 i; - do - i = randInt() & used; // toss unused bits to shorten search - while( i > n ); - return i; -} - - -inline void MTRand::seed( const uint32 oneSeed ) -{ - // Seed the generator with a simple uint32 - initialize(oneSeed); - reload(); -} - - -inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) -{ - // Seed the generator with an array of uint32's - // There are 2^19937-1 possible initial states. This function allows - // all of those to be accessed by providing at least 19937 bits (with a - // default seed length of N = 624 uint32's). Any bits above the lower 32 - // in each element are discarded. - // Just call seed() if you want to get array from /dev/urandom - initialize(19650218UL); - int i = 1; - uint32 j = 0; - int k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); - for( ; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); - state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; - state[i] &= 0xffffffffUL; - ++i; ++j; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - if( j >= seedLength ) j = 0; - } - for( k = N - 1; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); - state[i] -= i; - state[i] &= 0xffffffffUL; - ++i; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - } - state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array - reload(); -} - - -inline void MTRand::seed() -{ - // seed deterministically to produce reproducible runs - seed(123456); - - /* - // Seed the generator with an array from /dev/urandom if available - // Otherwise use a hash of time() and clock() values - - // First try getting an array from /dev/urandom - FILE* urandom = fopen( "/dev/urandom", "rb" ); - if( urandom ) - { - uint32 bigSeed[N]; - uint32 *s = bigSeed; - int i = N; - bool success = true; - while( success && i-- ) - success = fread( s++, sizeof(uint32), 1, urandom ); - fclose(urandom); - if( success ) { seed( bigSeed, N ); return; } - } - - // Was not successful, so use time() and clock() instead - seed( hash( time(NULL), clock() ) ); - */ -} - - -inline void MTRand::initialize( const uint32 seed ) -{ - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - uint32 *s = state; - uint32 *r = state; - int i = 1; - *s++ = seed & 0xffffffffUL; - for( ; i < N; ++i ) - { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; - } -} - - -inline void MTRand::reload() -{ - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - uint32 *p = state; - int i; - for( i = N - M; i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for( i = M; --i; ++p ) - *p = twist( p[M-N], p[0], p[1] ); - *p = twist( p[M-N], p[0], state[0] ); - - left = N, pNext = state; -} - - -inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) -{ - // Get a uint32 from t and c - // Better than uint32(x) in case x is floating point in [0,1] - // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) - - static uint32 differ = 0; // guarantee time-based seeds will change - - uint32 h1 = 0; - unsigned char *p = (unsigned char *) &t; - for( size_t i = 0; i < sizeof(t); ++i ) - { - h1 *= UCHAR_MAX + 2U; - h1 += p[i]; - } - uint32 h2 = 0; - p = (unsigned char *) &c; - for( size_t j = 0; j < sizeof(c); ++j ) - { - h2 *= UCHAR_MAX + 2U; - h2 += p[j]; - } - return ( h1 + differ++ ) ^ h2; -} - - -inline void MTRand::save( uint32* saveArray ) const -{ - uint32 *sa = saveArray; - const uint32 *s = state; - int i = N; - for( ; i--; *sa++ = *s++ ) {} - *sa = left; -} - - -inline void MTRand::load( uint32 *const loadArray ) -{ - uint32 *s = state; - uint32 *la = loadArray; - int i = N; - for( ; i--; *s++ = *la++ ) {} - left = *la; - pNext = &state[N-left]; -} - - -inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) -{ - const MTRand::uint32 *s = mtrand.state; - int i = mtrand.N; - for( ; i--; os << *s++ << "\t" ) {} - return os << mtrand.left; -} - - -inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) -{ - MTRand::uint32 *s = mtrand.state; - int i = mtrand.N; - for( ; i--; is >> *s++ ) {} - is >> mtrand.left; - mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; - return is; -} - -#endif // MERSENNETWISTER_H - -// Change log: -// -// v0.1 - First release on 15 May 2000 -// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// - Translated from C to C++ -// - Made completely ANSI compliant -// - Designed convenient interface for initialization, seeding, and -// obtaining numbers in default or user-defined ranges -// - Added automatic seeding from /dev/urandom or time() and clock() -// - Provided functions for saving and loading generator state -// -// v0.2 - Fixed bug which reloaded generator one step too late -// -// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew -// -// v0.4 - Removed trailing newline in saved generator format to be consistent -// with output format of built-in types -// -// v0.5 - Improved portability by replacing static const int's with enum's and -// clarifying return values in seed(); suggested by Eric Heimburg -// - Removed MAXINT constant; use 0xffffffffUL instead -// -// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits -// - Changed integer [0,n] generator to give better uniformity -// -// v0.7 - Fixed operator precedence ambiguity in reload() -// - Added access for real numbers in (0,1) and (0,n) -// -// v0.8 - Included time.h header to properly support time_t and clock_t -// -// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto -// - Allowed for seeding with arrays of any length -// - Added access for real numbers in [0,1) with 53-bit resolution -// - Added access for real numbers from normal (Gaussian) distributions -// - Increased overall speed by optimizing twist() -// - Doubled speed of integer [0,n] generation -// - Fixed out-of-range number generation on 64-bit machines -// - Improved portability by substituting literal constants for long enum's -// - Changed license from GNU LGPL to BSD - diff --git a/intern/smoke/intern/Makefile.FFT b/intern/smoke/intern/Makefile.FFT deleted file mode 100644 index 7e9d089cec2..00000000000 --- a/intern/smoke/intern/Makefile.FFT +++ /dev/null @@ -1,22 +0,0 @@ -# common stuff -LDFLAGS_COMMON = -lfftw3 #-lglut -lglu32 -lopengl32 -lz -lpng -CFLAGS_COMMON = -c -Wall -I./ #-I/cygdrive/c/lib/glvu/include -D_WIN32 - -CC = g++ -CFLAGS = ${CFLAGS_COMMON} -O3 -Wno-unused -LDFLAGS = ${LDFLAGS_COMMON} -EXECUTABLE = noiseFFT - -SOURCES = noiseFFT.cpp -OBJECTS = $(SOURCES:.cpp=.o) - -all: $(SOURCES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - -.cpp.o: - $(CC) $(CFLAGS) $< -o $@ - -clean: - rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE) diff --git a/intern/smoke/intern/Makefile.cygwin b/intern/smoke/intern/Makefile.cygwin deleted file mode 100644 index 2a747219554..00000000000 --- a/intern/smoke/intern/Makefile.cygwin +++ /dev/null @@ -1,23 +0,0 @@ -CC = g++ -LDFLAGS = -lz -lpng -CFLAGS = -O3 -Wno-unused -c -Wall -I./ -D_WIN32 -EXECUTABLE = FLUID_3D - -SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp -OBJECTS = $(SOURCES:.cpp=.o) - -all: $(SOURCES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - -.cpp.o: - $(CC) $(CFLAGS) $< -o $@ - -SPHERE.o: SPHERE.h -FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp -FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp -main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp - -clean: - rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE) diff --git a/intern/smoke/intern/Makefile.linux b/intern/smoke/intern/Makefile.linux deleted file mode 100644 index 5fbb6e6c3e3..00000000000 --- a/intern/smoke/intern/Makefile.linux +++ /dev/null @@ -1,23 +0,0 @@ -CC = g++ -LDFLAGS = -lz -lpng -fopenmp -lgomp -CFLAGS = -c -Wall -I./ -fopenmp -DPARALLEL=1 -O3 -Wno-unused -EXECUTABLE = FLUID_3D - -SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp -OBJECTS = $(SOURCES:.cpp=.o) - -all: $(SOURCES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - -.cpp.o: - $(CC) $(CFLAGS) $< -o $@ - -SPHERE.o: SPHERE.h -FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp -FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp -main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp - -clean: - rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE) diff --git a/intern/smoke/intern/Makefile.mac b/intern/smoke/intern/Makefile.mac deleted file mode 100644 index d0b7bd38c85..00000000000 --- a/intern/smoke/intern/Makefile.mac +++ /dev/null @@ -1,35 +0,0 @@ -CC = g++ - -# uncomment the other two OPENMP_... lines, if your gcc supports OpenMP -#OPENMP_FLAGS = -fopenmp -DPARALLEL=1 -I/opt/gcc-4.3/usr/local/include -#OPENMPLD_FLAGS = -fopenmp -lgomp -I/opt/gcc-4.3/usr/local/lib -OPENMP_FLAGS = -OPENMPLD_FLAGS = - -# assumes MacPorts libpng installation -PNG_INCLUDE = -I/opt/local/include -PNG_LIBS = -I/opt/local/lib - -LDFLAGS = $(PNG_LIBS)-lz -lpng $(OPENMPLD_FLAGS) -CFLAGS = -c -Wall -I./ $(PNG_INCLUDE) $(OPENMP_FLAGS) -O3 -Wno-unused -EXECUTABLE = FLUID_3D - -SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp -OBJECTS = $(SOURCES:.cpp=.o) - -all: $(SOURCES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - -.cpp.o: - $(CC) $(CFLAGS) $< -o $@ - -SPHERE.o: SPHERE.h -FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp -FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp -main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp - -clean: - rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE) - diff --git a/intern/smoke/intern/OBSTACLE.h b/intern/smoke/intern/OBSTACLE.h deleted file mode 100644 index a23b484e7c1..00000000000 --- a/intern/smoke/intern/OBSTACLE.h +++ /dev/null @@ -1,46 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// OBSTACLE.h: interface for the OBSTACLE class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef OBSTACLE_H -#define OBSTACLE_H - -enum OBSTACLE_FLAGS { - EMPTY = 0, - /* 1 is used to flag an object cell */ - MARCHED = 2, - RETIRED = 4, - ANIMATED = 8, -}; - -class OBSTACLE -{ -public: - OBSTACLE() {}; - virtual ~OBSTACLE() {}; - - virtual bool inside(float x, float y, float z) = 0; -}; - -#endif diff --git a/intern/smoke/intern/SPHERE.cpp b/intern/smoke/intern/SPHERE.cpp deleted file mode 100644 index 914ed5666c3..00000000000 --- a/intern/smoke/intern/SPHERE.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// SPHERE.cpp: implementation of the SPHERE class. -// -////////////////////////////////////////////////////////////////////// - -#include "SPHERE.h" - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -SPHERE::SPHERE(float x, float y, float z, float radius) : - _radius(radius) -{ - _center[0] = x; - _center[1] = y; - _center[2] = z; -} - -SPHERE::~SPHERE() -{ - -} - -bool SPHERE::inside(float x, float y, float z) -{ - float translate[] = {x - _center[0], y - _center[1], z - _center[2]}; - float magnitude = translate[0] * translate[0] + - translate[1] * translate[1] + - translate[2] * translate[2]; - - return (magnitude < _radius * _radius) ? true : false; -} diff --git a/intern/smoke/intern/SPHERE.h b/intern/smoke/intern/SPHERE.h deleted file mode 100644 index 6fdc93a5ee9..00000000000 --- a/intern/smoke/intern/SPHERE.h +++ /dev/null @@ -1,44 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// SPHERE.h: interface for the SPHERE class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef SPHERE_H -#define SPHERE_H - -#include "OBSTACLE.h" - -class SPHERE : public OBSTACLE -{ -public: - SPHERE(float x, float y, float z, float radius); - virtual ~SPHERE(); - - bool inside(float x, float y, float z); - -private: - float _center[3]; - float _radius; -}; - -#endif diff --git a/intern/smoke/intern/VEC3.h b/intern/smoke/intern/VEC3.h deleted file mode 100644 index 3672da74196..00000000000 --- a/intern/smoke/intern/VEC3.h +++ /dev/null @@ -1,991 +0,0 @@ -/** \file - * \ingroup smoke - */ -/****************************************************************************** - * Copyright 2007 Nils Thuerey - * Basic vector class - *****************************************************************************/ -#ifndef BASICVECTOR_H -#define BASICVECTOR_H - -#include <math.h> -#include <stdlib.h> -#include <stdio.h> -#include <iostream> -#include <sstream> - -// use which fp-precision? 1=float, 2=double -#ifndef FLOATINGPOINT_PRECISION -#if DDF_DEBUG==1 -#define FLOATINGPOINT_PRECISION 2 -#else // DDF_DEBUG==1 -#define FLOATINGPOINT_PRECISION 1 -#endif // DDF_DEBUG==1 -#endif - -// VECTOR_EPSILON is the minimal vector length -// In order to be able to discriminate floating point values near zero, and -// to be sure not to fail a comparison because of roundoff errors, use this -// value as a threshold. - -#if FLOATINGPOINT_PRECISION==1 -typedef float Real; -#define FP_REAL_MAX __FLT_MAX__ -#define VECTOR_EPSILON (1e-5f) -#else -typedef double Real; -#define FP_REAL_MAX __DBL_MAX__ -#define VECTOR_EPSILON (1e-10) -#endif - - -// hardcoded limits for now... -// for e.g. MSVC compiler... -// some of these defines can be needed -// for linux systems as well (e.g. FLT_MAX) -#ifndef __FLT_MAX__ -# ifdef FLT_MAX // try to use it instead -# define __FLT_MAX__ FLT_MAX -# else // FLT_MAX -# define __FLT_MAX__ 3.402823466e+38f -# endif // FLT_MAX -#endif // __FLT_MAX__ -#ifndef __DBL_MAX__ -# ifdef DBL_MAX // try to use it instead -# define __DBL_MAX__ DBL_MAX -# else // DBL_MAX -# define __DBL_MAX__ 1.7976931348623158e+308 -# endif // DBL_MAX -#endif // __DBL_MAX__ - -#ifndef FLT_MAX -#define FLT_MAX __FLT_MAX__ -#endif - -#ifndef DBL_MAX -#define DBL_MAX __DBL_MAX__ -#endif - -#ifndef M_PI -# define M_PI 3.1415926536 -# define M_E 2.7182818284 -#endif - - - -namespace BasicVector { - - -// basic inlined vector class -template<class Scalar> -class Vector3Dim -{ -public: - // Constructor - inline Vector3Dim(); - // Copy-Constructor - inline Vector3Dim(const Vector3Dim<Scalar> &v ); - inline Vector3Dim(const float *); - inline Vector3Dim(const double *); - // construct a vector from one Scalar - inline Vector3Dim(Scalar); - // construct a vector from three Scalars - inline Vector3Dim(Scalar, Scalar, Scalar); - - // get address of array for OpenGL - Scalar *getAddress() { return value; } - - // Assignment operator - inline const Vector3Dim<Scalar>& operator= (const Vector3Dim<Scalar>& v); - // Assignment operator - inline const Vector3Dim<Scalar>& operator= (Scalar s); - // Assign and add operator - inline const Vector3Dim<Scalar>& operator+= (const Vector3Dim<Scalar>& v); - // Assign and add operator - inline const Vector3Dim<Scalar>& operator+= (Scalar s); - // Assign and sub operator - inline const Vector3Dim<Scalar>& operator-= (const Vector3Dim<Scalar>& v); - // Assign and sub operator - inline const Vector3Dim<Scalar>& operator-= (Scalar s); - // Assign and mult operator - inline const Vector3Dim<Scalar>& operator*= (const Vector3Dim<Scalar>& v); - // Assign and mult operator - inline const Vector3Dim<Scalar>& operator*= (Scalar s); - // Assign and div operator - inline const Vector3Dim<Scalar>& operator/= (const Vector3Dim<Scalar>& v); - // Assign and div operator - inline const Vector3Dim<Scalar>& operator/= (Scalar s); - - - // unary operator - inline Vector3Dim<Scalar> operator- () const; - - // binary operator add - inline Vector3Dim<Scalar> operator+ (const Vector3Dim<Scalar>&) const; - // binary operator add - inline Vector3Dim<Scalar> operator+ (Scalar) const; - // binary operator sub - inline Vector3Dim<Scalar> operator- (const Vector3Dim<Scalar>&) const; - // binary operator sub - inline Vector3Dim<Scalar> operator- (Scalar) const; - // binary operator mult - inline Vector3Dim<Scalar> operator* (const Vector3Dim<Scalar>&) const; - // binary operator mult - inline Vector3Dim<Scalar> operator* (Scalar) const; - // binary operator div - inline Vector3Dim<Scalar> operator/ (const Vector3Dim<Scalar>&) const; - // binary operator div - inline Vector3Dim<Scalar> operator/ (Scalar) const; - - // Projection normal to a vector - inline Vector3Dim<Scalar> getOrthogonalntlVector3Dim() const; - // Project into a plane - inline const Vector3Dim<Scalar>& projectNormalTo(const Vector3Dim<Scalar> &v); - - // minimize - inline const Vector3Dim<Scalar> &minimize(const Vector3Dim<Scalar> &); - // maximize - inline const Vector3Dim<Scalar> &maximize(const Vector3Dim<Scalar> &); - - // access operator - inline Scalar& operator[](unsigned int i); - // access operator - inline const Scalar& operator[](unsigned int i) const; - - //! actual values - union { - struct { - Scalar value[3]; - }; - struct { - Scalar x; - Scalar y; - Scalar z; - }; - struct { - Scalar X; - Scalar Y; - Scalar Z; - }; - }; -protected: - -}; - - - - - -//------------------------------------------------------------------------------ -// VECTOR inline FUNCTIONS -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Constructor. - */ -template<class Scalar> -inline Vector3Dim<Scalar>::Vector3Dim( void ) -{ - value[0] = value[1] = value[2] = 0; -} - - - -/************************************************************************* - Copy-Constructor. - */ -template<class Scalar> -inline Vector3Dim<Scalar>::Vector3Dim( const Vector3Dim<Scalar> &v ) -{ - value[0] = v.value[0]; - value[1] = v.value[1]; - value[2] = v.value[2]; -} -template<class Scalar> -inline Vector3Dim<Scalar>::Vector3Dim( const float *fvalue) -{ - value[0] = (Scalar)fvalue[0]; - value[1] = (Scalar)fvalue[1]; - value[2] = (Scalar)fvalue[2]; -} -template<class Scalar> -inline Vector3Dim<Scalar>::Vector3Dim( const double *fvalue) -{ - value[0] = (Scalar)fvalue[0]; - value[1] = (Scalar)fvalue[1]; - value[2] = (Scalar)fvalue[2]; -} - - - -/************************************************************************* - Constructor for a vector from a single Scalar. All components of - the vector get the same value. - \param s The value to set - \return The new vector - */ -template<class Scalar> -inline Vector3Dim<Scalar>::Vector3Dim(Scalar s ) -{ - value[0]= s; - value[1]= s; - value[2]= s; -} - - -/************************************************************************* - Constructor for a vector from three Scalars. - \param s1 The value for the first vector component - \param s2 The value for the second vector component - \param s3 The value for the third vector component - \return The new vector - */ -template<class Scalar> -inline Vector3Dim<Scalar>::Vector3Dim(Scalar s1, Scalar s2, Scalar s3) -{ - value[0]= s1; - value[1]= s2; - value[2]= s3; -} - - - -/************************************************************************* - Copy a Vector3Dim componentwise. - \param v vector with values to be copied - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator=( const Vector3Dim<Scalar> &v ) -{ - value[0] = v.value[0]; - value[1] = v.value[1]; - value[2] = v.value[2]; - return *this; -} - - -/************************************************************************* - Copy a Scalar to each component. - \param s The value to copy - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator=(Scalar s) -{ - value[0] = s; - value[1] = s; - value[2] = s; - return *this; -} - - -/************************************************************************* - Add another Vector3Dim componentwise. - \param v vector with values to be added - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator+=( const Vector3Dim<Scalar> &v ) -{ - value[0] += v.value[0]; - value[1] += v.value[1]; - value[2] += v.value[2]; - return *this; -} - - -/************************************************************************* - Add a Scalar value to each component. - \param s Value to add - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator+=(Scalar s) -{ - value[0] += s; - value[1] += s; - value[2] += s; - return *this; -} - - -/************************************************************************* - Subtract another vector componentwise. - \param v vector of values to subtract - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator-=( const Vector3Dim<Scalar> &v ) -{ - value[0] -= v.value[0]; - value[1] -= v.value[1]; - value[2] -= v.value[2]; - return *this; -} - - -/************************************************************************* - Subtract a Scalar value from each component. - \param s Value to subtract - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator-=(Scalar s) -{ - value[0]-= s; - value[1]-= s; - value[2]-= s; - return *this; -} - - -/************************************************************************* - Multiply with another vector componentwise. - \param v vector of values to multiply with - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator*=( const Vector3Dim<Scalar> &v ) -{ - value[0] *= v.value[0]; - value[1] *= v.value[1]; - value[2] *= v.value[2]; - return *this; -} - - -/************************************************************************* - Multiply each component with a Scalar value. - \param s Value to multiply with - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator*=(Scalar s) -{ - value[0] *= s; - value[1] *= s; - value[2] *= s; - return *this; -} - - -/************************************************************************* - Divide by another Vector3Dim componentwise. - \param v vector of values to divide by - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator/=( const Vector3Dim<Scalar> &v ) -{ - value[0] /= v.value[0]; - value[1] /= v.value[1]; - value[2] /= v.value[2]; - return *this; -} - - -/************************************************************************* - Divide each component by a Scalar value. - \param s Value to divide by - \return Reference to self - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::operator/=(Scalar s) -{ - value[0] /= s; - value[1] /= s; - value[2] /= s; - return *this; -} - - -//------------------------------------------------------------------------------ -// unary operators -//------------------------------------------------------------------------------ - - -/************************************************************************* - Build componentwise the negative this vector. - \return The new (negative) vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator-() const -{ - return Vector3Dim<Scalar>(-value[0], -value[1], -value[2]); -} - - - -//------------------------------------------------------------------------------ -// binary operators -//------------------------------------------------------------------------------ - - -/************************************************************************* - Build a vector with another vector added componentwise. - \param v The second vector to add - \return The sum vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator+( const Vector3Dim<Scalar> &v ) const -{ - return Vector3Dim<Scalar>(value[0]+v.value[0], - value[1]+v.value[1], - value[2]+v.value[2]); -} - - -/************************************************************************* - Build a vector with a Scalar value added to each component. - \param s The Scalar value to add - \return The sum vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator+(Scalar s) const -{ - return Vector3Dim<Scalar>(value[0]+s, - value[1]+s, - value[2]+s); -} - - -/************************************************************************* - Build a vector with another vector subtracted componentwise. - \param v The second vector to subtract - \return The difference vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator-( const Vector3Dim<Scalar> &v ) const -{ - return Vector3Dim<Scalar>(value[0]-v.value[0], - value[1]-v.value[1], - value[2]-v.value[2]); -} - - -/************************************************************************* - Build a vector with a Scalar value subtracted componentwise. - \param s The Scalar value to subtract - \return The difference vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator-(Scalar s ) const -{ - return Vector3Dim<Scalar>(value[0]-s, - value[1]-s, - value[2]-s); -} - - - -/************************************************************************* - Build a vector with another vector multiplied by componentwise. - \param v The second vector to muliply with - \return The product vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator*( const Vector3Dim<Scalar>& v) const -{ - return Vector3Dim<Scalar>(value[0]*v.value[0], - value[1]*v.value[1], - value[2]*v.value[2]); -} - - -/************************************************************************* - Build a Vector3Dim with a Scalar value multiplied to each component. - \param s The Scalar value to multiply with - \return The product vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator*(Scalar s) const -{ - return Vector3Dim<Scalar>(value[0]*s, value[1]*s, value[2]*s); -} - - -/************************************************************************* - Build a vector divided componentwise by another vector. - \param v The second vector to divide by - \return The ratio vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator/(const Vector3Dim<Scalar>& v) const -{ - return Vector3Dim<Scalar>(value[0]/v.value[0], - value[1]/v.value[1], - value[2]/v.value[2]); -} - - - -/************************************************************************* - Build a vector divided componentwise by a Scalar value. - \param s The Scalar value to divide by - \return The ratio vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> -Vector3Dim<Scalar>::operator/(Scalar s) const -{ - return Vector3Dim<Scalar>(value[0]/s, - value[1]/s, - value[2]/s); -} - - - - - -/************************************************************************* - Get a particular component of the vector. - \param i Number of Scalar to get - \return Reference to the component - */ -template<class Scalar> -inline Scalar& -Vector3Dim<Scalar>::operator[]( unsigned int i ) -{ - return value[i]; -} - - -/************************************************************************* - Get a particular component of a constant vector. - \param i Number of Scalar to get - \return Reference to the component - */ -template<class Scalar> -inline const Scalar& -Vector3Dim<Scalar>::operator[]( unsigned int i ) const -{ - return value[i]; -} - - - -//------------------------------------------------------------------------------ -// BLITZ compatibility functions -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Compute the scalar product with another vector. - \param v The second vector to work with - \return The value of the scalar product - */ -template<class Scalar> -inline Scalar dot(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v ) -{ - //return t.value[0]*v.value[0] + t.value[1]*v.value[1] + t.value[2]*v.value[2]; - return ((t[0]*v[0]) + (t[1]*v[1]) + (t[2]*v[2])); -} - - -/************************************************************************* - Calculate the cross product of this and another vector - */ -template<class Scalar> -inline Vector3Dim<Scalar> cross(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v) -{ - Vector3Dim<Scalar> cp( - ((t[1]*v[2]) - (t[2]*v[1])), - ((t[2]*v[0]) - (t[0]*v[2])), - ((t[0]*v[1]) - (t[1]*v[0])) ); - return cp; -} - - - - -/************************************************************************* - Compute a vector that is orthonormal to self. Nothing else can be assumed - for the direction of the new vector. - \return The orthonormal vector - */ -template<class Scalar> -Vector3Dim<Scalar> -Vector3Dim<Scalar>::getOrthogonalntlVector3Dim() const -{ - // Determine the component with max. absolute value - int max= (fabs(value[0]) > fabs(value[1])) ? 0 : 1; - max= (fabs(value[max]) > fabs(value[2])) ? max : 2; - - /************************************************************************* - Choose another axis than the one with max. component and project - orthogonal to self - */ - Vector3Dim<Scalar> vec(0.0); - vec[(max+1)%3]= 1; - vec.normalize(); - vec.projectNormalTo(this->getNormalized()); - return vec; -} - - -/************************************************************************* - Projects the vector into a plane normal to the given vector, which must - have unit length. Self is modified. - \param v The plane normal - \return The projected vector - */ -template<class Scalar> -inline const Vector3Dim<Scalar>& -Vector3Dim<Scalar>::projectNormalTo(const Vector3Dim<Scalar> &v) -{ - Scalar sprod = dot(*this,v); - value[0]= value[0] - v.value[0] * sprod; - value[1]= value[1] - v.value[1] * sprod; - value[2]= value[2] - v.value[2] * sprod; - return *this; -} - - - -//------------------------------------------------------------------------------ -// Other helper functions -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Minimize the vector, i.e. set each entry of the vector to the minimum - of both values. - \param pnt The second vector to compare with - \return Reference to the modified self - */ -template<class Scalar> -inline const Vector3Dim<Scalar> & -Vector3Dim<Scalar>::minimize(const Vector3Dim<Scalar> &pnt) -{ - for (unsigned int i = 0; i < 3; i++) - value[i] = MIN(value[i],pnt[i]); - return *this; -} - - - -/************************************************************************* - Maximize the vector, i.e. set each entry of the vector to the maximum - of both values. - \param pnt The second vector to compare with - \return Reference to the modified self - */ -template<class Scalar> -inline const Vector3Dim<Scalar> & -Vector3Dim<Scalar>::maximize(const Vector3Dim<Scalar> &pnt) -{ - for (unsigned int i = 0; i < 3; i++) - value[i] = MAX(value[i],pnt[i]); - return *this; -} - - - - - - -/************************************************************************/ -// HELPER FUNCTIONS, independent of implementation -/************************************************************************/ - -#define VECTOR_TYPE Vector3Dim<Scalar> - - -/************************************************************************* - Compute the length (norm) of the vector. - \return The value of the norm - */ -template<class Scalar> -inline Scalar norm( const VECTOR_TYPE &v) -{ - Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - return (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) ? 1. : sqrt(l); -} - -// for e.g. min max operator -inline Real normHelper(const Vector3Dim<Real> &v) { - return norm(v); -} -inline Real normHelper(const Real &v) { - return (0.0f < v) ? v : -v ; -} -inline Real normHelper(const int &v) { - return (0 < v) ? (Real)(v) : (Real)(-v) ; -} - - -/************************************************************************* - Same as getNorm but doesnt sqrt - */ -template<class Scalar> -inline Scalar normNoSqrt( const VECTOR_TYPE &v) -{ - return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -} - - -/************************************************************************* - Compute a normalized vector based on this vector. - \return The new normalized vector - */ -template<class Scalar> -inline VECTOR_TYPE getNormalized( const VECTOR_TYPE &v) -{ - Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) - return v; /* normalized "enough"... */ - else if (l > VECTOR_EPSILON*VECTOR_EPSILON) - { - Scalar fac = 1./sqrt(l); - return VECTOR_TYPE(v[0]*fac, v[1]*fac, v[2]*fac); - } - else - return VECTOR_TYPE((Scalar)0); -} - - -/************************************************************************* - Compute the norm of the vector and normalize it. - \return The value of the norm - */ -template<class Scalar> -inline Scalar normalize( VECTOR_TYPE &v) -{ - Scalar norm; - Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) { - norm = 1.; - } else if (l > VECTOR_EPSILON*VECTOR_EPSILON) { - norm = sqrt(l); - Scalar fac = 1./norm; - v[0] *= fac; - v[1] *= fac; - v[2] *= fac; - } else { - v[0]= v[1]= v[2]= 0; - norm = 0.; - } - return (Scalar)norm; -} - - -/************************************************************************* - Compute a vector, that is self (as an incoming - vector) reflected at a surface with a distinct normal vector. Note - that the normal is reversed, if the scalar product with it is positive. - \param n The surface normal - \return The new reflected vector - */ -template<class Scalar> -inline VECTOR_TYPE reflectVector(const VECTOR_TYPE &t, const VECTOR_TYPE &n) -{ - VECTOR_TYPE nn= (dot(t, n) > 0.0) ? (n*-1.0) : n; - return ( t - nn * (2.0 * dot(nn, t)) ); -} - - - -/************************************************************************* - * My own refraction calculation - * Taken from Glassner's book, section 5.2 (Heckberts method) - */ -template<class Scalar> -inline VECTOR_TYPE refractVector(const VECTOR_TYPE &t, const VECTOR_TYPE &normal, Scalar nt, Scalar nair, int &refRefl) -{ - Scalar eta = nair / nt; - Scalar n = -dot(t, normal); - Scalar tt = 1.0 + eta*eta* (n*n-1.0); - if(tt<0.0) { - // we have total reflection! - refRefl = 1; - } else { - // normal reflection - tt = eta*n - sqrt(tt); - return( t*eta + normal*tt ); - } - return t; -} - - -/************************************************************************* - Test two ntlVector3Dims for equality based on the equality of their - values within a small threshold. - \param c The second vector to compare - \return TRUE if both are equal - \sa getEpsilon() - */ -template<class Scalar> -inline bool equal(const VECTOR_TYPE &v, const VECTOR_TYPE &c) -{ - return (ABS(v[0]-c[0]) + - ABS(v[1]-c[1]) + - ABS(v[2]-c[2]) < VECTOR_EPSILON); -} - - -/************************************************************************* - * Assume this vector is an RGB color, and convert it to HSV - */ -template<class Scalar> -inline void rgbToHsv( VECTOR_TYPE &V ) -{ - Scalar h=0,s=0,v=0; - Scalar maxrgb, minrgb, delta; - // convert to hsv... - maxrgb = V[0]; - int maxindex = 1; - if(V[2] > maxrgb){ maxrgb = V[2]; maxindex = 2; } - if(V[1] > maxrgb){ maxrgb = V[1]; maxindex = 3; } - minrgb = V[0]; - if(V[2] < minrgb) minrgb = V[2]; - if(V[1] < minrgb) minrgb = V[1]; - - v = maxrgb; - delta = maxrgb-minrgb; - - if(maxrgb > 0) s = delta/maxrgb; - else s = 0; - - h = 0; - if(s > 0) { - if(maxindex == 1) { - h = ((V[1]-V[2])/delta) + 0.0; } - if(maxindex == 2) { - h = ((V[2]-V[0])/delta) + 2.0; } - if(maxindex == 3) { - h = ((V[0]-V[1])/delta) + 4.0; } - h *= 60.0; - if(h < 0.0) h += 360.0; - } - - V[0] = h; - V[1] = s; - V[2] = v; -} - -/************************************************************************* - * Assume this vector is HSV and convert to RGB - */ -template<class Scalar> -inline void hsvToRgb( VECTOR_TYPE &V ) -{ - Scalar h = V[0], s = V[1], v = V[2]; - Scalar r=0,g=0,b=0; - Scalar p,q,t, fracth; - int floorh; - // ...and back to rgb - if(s == 0) { - r = g = b = v; } - else { - h /= 60.0; - floorh = (int)h; - fracth = h - floorh; - p = v * (1.0 - s); - q = v * (1.0 - (s * fracth)); - t = v * (1.0 - (s * (1.0 - fracth))); - switch (floorh) { - case 0: r = v; g = t; b = p; break; - case 1: r = q; g = v; b = p; break; - case 2: r = p; g = v; b = t; break; - case 3: r = p; g = q; b = v; break; - case 4: r = t; g = p; b = v; break; - case 5: r = v; g = p; b = q; break; - } - } - - V[0] = r; - V[1] = g; - V[2] = b; -} - -//------------------------------------------------------------------------------ -// STREAM FUNCTIONS -//------------------------------------------------------------------------------ - - - -//! global string for formatting vector output in utilities.cpp -//extern const char *globVecFormatStr; -#if 0 -static const char *globVecFormatStr = "[%6.4f,%6.4f,%6.4f]"; -#endif - -/************************************************************************* - Outputs the object in human readable form using the format - [x,y,z] - */ -template<class Scalar> -std::ostream& -operator<<( std::ostream& os, const BasicVector::Vector3Dim<Scalar>& i ) -{ -#if 0 - char buf[256]; -# if _WIN32 - sprintf(buf,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]); -# else - snprintf(buf,256,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]); -# endif - os << std::string(buf); -#else - (void)i; /* Ignored. */ -#endif - return os; -} - - -/************************************************************************* - Reads the contents of the object from a stream using the same format - as the output operator. - */ -template<class Scalar> -std::istream& -operator>>( std::istream& is, BasicVector::Vector3Dim<Scalar>& i ) -{ - char c; - char dummy[3]; - is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c; - return is; -} - - -/**************************************************************************/ -// typedefs! -/**************************************************************************/ - -/* get minimal vector length value that can be discriminated. */ -inline Real getVecEpsilon() { return (Real)VECTOR_EPSILON; } - -// a 3D integer vector -typedef Vector3Dim<int> Vec3Int; - -// a 3D vector -typedef Vector3Dim<Real> Vec3; - - -}; // namespace - - -#endif /* BASICVECTOR_H */ diff --git a/intern/smoke/intern/WAVELET_NOISE.h b/intern/smoke/intern/WAVELET_NOISE.h deleted file mode 100644 index 13ffe1e9697..00000000000 --- a/intern/smoke/intern/WAVELET_NOISE.h +++ /dev/null @@ -1,519 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -////////////////////////////////////////////////////////////////////////////////////////// -// Wavelet noise functions -// -// This code is based on the C code provided in the appendices of: -// -// @article{1073264, -// author = {Robert L. Cook and Tony DeRose}, -// title = {Wavelet noise}, -// journal = {ACM Trans. Graph.}, -// volume = {24}, -// number = {3}, -// year = {2005}, -// issn = {0730-0301}, -// pages = {803--811}, -// doi = {http://doi.acm.org/10.1145/1073204.1073264}, -// publisher = {ACM}, -// address = {New York, NY, USA}, -// } -// -////////////////////////////////////////////////////////////////////////////////////////// - -#ifndef WAVELET_NOISE_H -#define WAVELET_NOISE_H - -#include <MERSENNETWISTER.h> - -#include <string.h> - -#ifdef WIN32 -#include <float.h> -#define isnan _isnan -#endif - -// Tile file header, update revision upon any change done to the noise generator -static const char tilefile_headerstring[] = "Noise Tile File rev. "; -static const char tilefile_revision[] = "001"; - -#define NOISE_TILE_SIZE 128 -static const int noiseTileSize = NOISE_TILE_SIZE; - -// warning - noiseTileSize has to be 128^3! -#define modFast128(x) ((x) & 127) -#define modFast64(x) ((x) & 63) -#define DOWNCOEFFS 0.000334f,-0.001528f, 0.000410f, 0.003545f,-0.000938f,-0.008233f, 0.002172f, 0.019120f, \ - -0.005040f,-0.044412f, 0.011655f, 0.103311f,-0.025936f,-0.243780f, 0.033979f, 0.655340f, \ - 0.655340f, 0.033979f,-0.243780f,-0.025936f, 0.103311f, 0.011655f,-0.044412f,-0.005040f, \ - 0.019120f, 0.002172f,-0.008233f,-0.000938f, 0.003546f, 0.000410f,-0.001528f, 0.000334f - -////////////////////////////////////////////////////////////////////////////////////////// -// Wavelet downsampling -- periodic boundary conditions -////////////////////////////////////////////////////////////////////////////////////////// -static void downsampleX(float *from, float *to, int n){ - // if these values are not local incorrect results are generated - float downCoeffs[32] = { DOWNCOEFFS }; - const float *a = &downCoeffs[16]; - for (int i = 0; i < n / 2; i++) { - to[i] = 0; - for (int k = 2 * i - 16; k < 2 * i + 16; k++) - to[i] += a[k - 2 * i] * from[modFast128(k)]; - } -} -static void downsampleY(float *from, float *to, int n){ - // if these values are not local incorrect results are generated - float downCoeffs[32] = { DOWNCOEFFS }; - const float *a = &downCoeffs[16]; - for (int i = 0; i < n / 2; i++) { - to[i * n] = 0; - for (int k = 2 * i - 16; k < 2 * i + 16; k++) - to[i * n] += a[k - 2 * i] * from[modFast128(k) * n]; - } -} -static void downsampleZ(float *from, float *to, int n){ - // if these values are not local incorrect results are generated - float downCoeffs[32] = { DOWNCOEFFS }; - const float *a = &downCoeffs[16]; - for (int i = 0; i < n / 2; i++) { - to[i * n * n] = 0; - for (int k = 2 * i - 16; k < 2 * i + 16; k++) - to[i * n * n] += a[k - 2 * i] * from[modFast128(k) * n * n]; - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Wavelet downsampling -- Neumann boundary conditions -////////////////////////////////////////////////////////////////////////////////////////// -static void downsampleNeumann(const float *from, float *to, int n, int stride) -{ - // if these values are not local incorrect results are generated - float downCoeffs[32] = { DOWNCOEFFS }; - const float *const aCoCenter= &downCoeffs[16]; - for (int i = 0; i <= n / 2; i++) { - to[i * stride] = 0; - for (int k = 2 * i - 16; k < 2 * i + 16; k++) { - // handle boundary - float fromval; - if (k < 0) { - fromval = from[0]; - } else if(k > n - 1) { - fromval = from[(n - 1) * stride]; - } else { - fromval = from[k * stride]; - } - to[i * stride] += aCoCenter[k - 2 * i] * fromval; - } - } -} -static void downsampleXNeumann(float* to, const float* from, int sx,int sy, int sz) { - for (int iy = 0; iy < sy; iy++) - for (int iz = 0; iz < sz; iz++) { - const int i = iy * sx + iz*sx*sy; - downsampleNeumann(&from[i], &to[i], sx, 1); - } -} -static void downsampleYNeumann(float* to, const float* from, int sx,int sy, int sz) { - for (int ix = 0; ix < sx; ix++) - for (int iz = 0; iz < sz; iz++) { - const int i = ix + iz*sx*sy; - downsampleNeumann(&from[i], &to[i], sy, sx); - } -} -static void downsampleZNeumann(float* to, const float* from, int sx,int sy, int sz) { - for (int ix = 0; ix < sx; ix++) - for (int iy = 0; iy < sy; iy++) { - const int i = ix + iy*sx; - downsampleNeumann(&from[i], &to[i], sz, sx*sy); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Wavelet upsampling - periodic boundary conditions -////////////////////////////////////////////////////////////////////////////////////////// -static float _upCoeffs[4] = {0.25f, 0.75f, 0.75f, 0.25f}; -static void upsampleX(float *from, float *to, int n) { - const float *p = &_upCoeffs[2]; - - for (int i = 0; i < n; i++) { - to[i] = 0; - for (int k = i / 2; k <= i / 2 + 1; k++) - to[i] += p[i - 2 * k] * from[modFast64(k)]; - } -} -static void upsampleY(float *from, float *to, int n) { - const float *p = &_upCoeffs[2]; - - for (int i = 0; i < n; i++) { - to[i * n] = 0; - for (int k = i / 2; k <= i / 2 + 1; k++) - to[i * n] += p[i - 2 * k] * from[modFast64(k) * n]; - } -} -static void upsampleZ(float *from, float *to, int n) { - const float *p = &_upCoeffs[2]; - - for (int i = 0; i < n; i++) { - to[i * n * n] = 0; - for (int k = i / 2; k <= i / 2 + 1; k++) - to[i * n * n] += p[i - 2 * k] * from[modFast64(k) * n * n]; - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Wavelet upsampling - Neumann boundary conditions -////////////////////////////////////////////////////////////////////////////////////////// -static void upsampleNeumann(const float *from, float *to, int n, int stride) { - static const float *const pCoCenter = &_upCoeffs[2]; - for (int i = 0; i < n; i++) { - to[i * stride] = 0; - for (int k = i / 2; k <= i / 2 + 1; k++) { - float fromval; - if(k>n/2) { - fromval = from[(n/2) * stride]; - } else { - fromval = from[k * stride]; - } - to[i * stride] += pCoCenter[i - 2 * k] * fromval; - } - } -} -static void upsampleXNeumann(float* to, const float* from, int sx, int sy, int sz) { - for (int iy = 0; iy < sy; iy++) - for (int iz = 0; iz < sz; iz++) { - const int i = iy * sx + iz*sx*sy; - upsampleNeumann(&from[i], &to[i], sx, 1); - } -} -static void upsampleYNeumann(float* to, const float* from, int sx, int sy, int sz) { - for (int ix = 0; ix < sx; ix++) - for (int iz = 0; iz < sz; iz++) { - const int i = ix + iz*sx*sy; - upsampleNeumann(&from[i], &to[i], sy, sx); - } -} -static void upsampleZNeumann(float* to, const float* from, int sx, int sy, int sz) { - for (int ix = 0; ix < sx; ix++) - for (int iy = 0; iy < sy; iy++) { - const int i = ix + iy*sx; - upsampleNeumann(&from[i], &to[i], sz, sx*sy); - } -} - - -////////////////////////////////////////////////////////////////////////////////////////// -// load in an existing noise tile -////////////////////////////////////////////////////////////////////////////////////////// -static bool loadTile(float* const noiseTileData, std::string filename) -{ - FILE* file; - char headerbuffer[64]; - size_t headerlen; - size_t bread; - int endiantest = 1; - char endianness; - - file = fopen(filename.c_str(), "rb"); - - if (file == NULL) { - printf("loadTile: No noise tile '%s' found.\n", filename.c_str()); - return false; - } - - //Check header - headerlen = strlen(tilefile_headerstring) + strlen(tilefile_revision) + 2; - bread = fread((void*)headerbuffer, 1, headerlen, file); - if (*((unsigned char*)&endiantest) == 1) - endianness = 'L'; - else - endianness = 'B'; - if ((bread != headerlen) - || (strncmp(headerbuffer, tilefile_headerstring, strlen(tilefile_headerstring))) - || (strncmp(headerbuffer+ strlen(tilefile_headerstring), tilefile_revision, strlen(tilefile_revision))) - || (headerbuffer[headerlen-2] != endianness) - || (headerbuffer[headerlen-1] != (char)((char)sizeof(long)+'0'))) - { - printf("loadTile : Noise tile '%s' was generated on an incompatible platform.\n",filename.c_str()); - fclose(file); - return false; - } - - // dimensions - size_t gridSize = noiseTileSize * noiseTileSize * noiseTileSize; - - // noiseTileData memory is managed by caller - bread = fread((void*)noiseTileData, sizeof(float), gridSize, file); - fclose(file); - printf("Noise tile file '%s' loaded.\n", filename.c_str()); - - if (bread != gridSize) { - printf("loadTile: Noise tile '%s' is wrong size %d.\n", filename.c_str(), (int)bread); - return false; - } - - // check for invalid nan tile data that could be generated. bug is now - // fixed, but invalid files may still hang around - if (isnan(noiseTileData[0])) { - printf("loadTile: Noise tile '%s' contains nan values.\n", filename.c_str()); - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// write out an existing noise tile -////////////////////////////////////////////////////////////////////////////////////////// -static void saveTile(float* const noiseTileData, std::string filename) -{ - FILE* file; - file = fopen(filename.c_str(), "wb"); - int endiantest=1; - char longsize; - - if (file == NULL) { - printf("saveTile: Noise tile '%s' could not be saved.\n", filename.c_str()); - return; - } - - //Write file header - fwrite(tilefile_headerstring, strlen(tilefile_headerstring), 1, file); - fwrite(tilefile_revision, strlen(tilefile_revision), 1, file); - //Endianness - if (*((unsigned char*)&endiantest) == 1) - fwrite("L", 1, 1, file); //Little endian - else - fwrite("B",1,1,file); //Big endian - //32/64bit - longsize = (char)sizeof(long)+'0'; - fwrite(&longsize, 1, 1, file); - - - fwrite((void*)noiseTileData, sizeof(float), noiseTileSize * noiseTileSize * noiseTileSize, file); - fclose(file); - - printf("saveTile: Noise tile file '%s' saved.\n", filename.c_str()); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// create a new noise tile if necessary -////////////////////////////////////////////////////////////////////////////////////////// -static void generateTile_WAVELET(float* const noiseTileData, std::string filename) { - // if a tile already exists, just use that - if (loadTile(noiseTileData, filename)) return; - - const int n = noiseTileSize; - const int n3 = n*n*n; - std::cout <<"Generating new 3d noise tile size="<<n<<"^3 \n"; - MTRand twister; - - float *temp13 = new float[n3]; - float *temp23 = new float[n3]; - float *noise3 = new float[n3]; - - // initialize - for (int i = 0; i < n3; i++) { - temp13[i] = temp23[i] = noise3[i] = 0.; - } - - // Step 1. Fill the tile with random numbers in the range -1 to 1. - for (int i = 0; i < n3; i++) - noise3[i] = twister.randNorm(); - - // Steps 2 and 3. Downsample and upsample the tile - for (int iy = 0; iy < n; iy++) - for (int iz = 0; iz < n; iz++) { - const int i = iy * n + iz*n*n; - downsampleX(&noise3[i], &temp13[i], n); - upsampleX (&temp13[i], &temp23[i], n); - } - for (int ix = 0; ix < n; ix++) - for (int iz = 0; iz < n; iz++) { - const int i = ix + iz*n*n; - downsampleY(&temp23[i], &temp13[i], n); - upsampleY (&temp13[i], &temp23[i], n); - } - for (int ix = 0; ix < n; ix++) - for (int iy = 0; iy < n; iy++) { - const int i = ix + iy*n; - downsampleZ(&temp23[i], &temp13[i], n); - upsampleZ (&temp13[i], &temp23[i], n); - } - - // Step 4. Subtract out the coarse-scale contribution - for (int i = 0; i < n3; i++) - noise3[i] -= temp23[i]; - - // Avoid even/odd variance difference by adding odd-offset version of noise to itself. - int offset = n / 2; - if (offset % 2 == 0) offset++; - - int icnt=0; - for (int ix = 0; ix < n; ix++) - for (int iy = 0; iy < n; iy++) - for (int iz = 0; iz < n; iz++) { - temp13[icnt] = noise3[modFast128(ix+offset) + modFast128(iy+offset)*n + modFast128(iz+offset)*n*n]; - icnt++; - } - - for (int i = 0; i < n3; i++) - noise3[i] += temp13[i]; - - for (int i = 0; i < n3; i++) - noiseTileData[i] = noise3[i]; - - saveTile(noise3, filename); - delete[] temp13; - delete[] temp23; - delete[] noise3; - std::cout <<"Generating new 3d noise done\n"; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// x derivative of noise -////////////////////////////////////////////////////////////////////////////////////////// -static inline float WNoiseDx(Vec3 p, float* data) { - int c[3], mid[3], n = noiseTileSize; - float w[3][3], t, result = 0; - - mid[0] = (int)ceil(p[0] - 0.5f); - t = mid[0] - (p[0] - 0.5f); - w[0][0] = -t; - w[0][2] = (1.f - t); - w[0][1] = 2.0f * t - 1.0f; - - mid[1] = (int)ceil(p[1] - 0.5f); - t = mid[1] - (p[1] - 0.5f); - w[1][0] = t * t / 2; - w[1][2] = (1 - t) * (1 - t) / 2; - w[1][1] = 1 - w[1][0] - w[1][2]; - - mid[2] = (int)ceil(p[2] - 0.5f); - t = mid[2] - (p[2] - 0.5f); - w[2][0] = t * t / 2; - w[2][2] = (1 - t) * (1 - t)/2; - w[2][1] = 1 - w[2][0] - w[2][2]; - - // to optimize, explicitly unroll this loop - for (int z = -1; z <=1; z++) - for (int y = -1; y <=1; y++) - for (int x = -1; x <=1; x++) - { - float weight = 1.0f; - c[0] = modFast128(mid[0] + x); - weight *= w[0][x+1]; - c[1] = modFast128(mid[1] + y); - weight *= w[1][y+1]; - c[2] = modFast128(mid[2] + z); - weight *= w[2][z+1]; - result += weight * data[c[2]*n*n+c[1]*n+c[0]]; - } - return result; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// y derivative of noise -////////////////////////////////////////////////////////////////////////////////////////// -static inline float WNoiseDy(Vec3 p, float* data) { - int c[3], mid[3], n=noiseTileSize; - float w[3][3], t, result =0; - - mid[0] = (int)ceil(p[0] - 0.5f); - t = mid[0]-(p[0] - 0.5f); - w[0][0] = t * t / 2; - w[0][2] = (1 - t) * (1 - t) / 2; - w[0][1] = 1 - w[0][0] - w[0][2]; - - mid[1] = (int)ceil(p[1] - 0.5f); - t = mid[1]-(p[1] - 0.5f); - w[1][0] = -t; - w[1][2] = (1.f - t); - w[1][1] = 2.0f * t - 1.0f; - - mid[2] = (int)ceil(p[2] - 0.5f); - t = mid[2] - (p[2] - 0.5f); - w[2][0] = t * t / 2; - w[2][2] = (1 - t) * (1 - t)/2; - w[2][1] = 1 - w[2][0] - w[2][2]; - - // to optimize, explicitly unroll this loop - for (int z = -1; z <=1; z++) - for (int y = -1; y <=1; y++) - for (int x = -1; x <=1; x++) - { - float weight = 1.0f; - c[0] = modFast128(mid[0] + x); - weight *= w[0][x+1]; - c[1] = modFast128(mid[1] + y); - weight *= w[1][y+1]; - c[2] = modFast128(mid[2] + z); - weight *= w[2][z+1]; - result += weight * data[c[2]*n*n+c[1]*n+c[0]]; - } - - return result; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// z derivative of noise -////////////////////////////////////////////////////////////////////////////////////////// -static inline float WNoiseDz(Vec3 p, float* data) { - int c[3], mid[3], n=noiseTileSize; - float w[3][3], t, result =0; - - mid[0] = (int)ceil(p[0] - 0.5f); - t = mid[0]-(p[0] - 0.5f); - w[0][0] = t * t / 2; - w[0][2] = (1 - t) * (1 - t) / 2; - w[0][1] = 1 - w[0][0] - w[0][2]; - - mid[1] = (int)ceil(p[1] - 0.5f); - t = mid[1]-(p[1] - 0.5f); - w[1][0] = t * t / 2; - w[1][2] = (1 - t) * (1 - t) / 2; - w[1][1] = 1 - w[1][0] - w[1][2]; - - mid[2] = (int)ceil(p[2] - 0.5f); - t = mid[2] - (p[2] - 0.5f); - w[2][0] = -t; - w[2][2] = (1.f - t); - w[2][1] = 2.0f * t - 1.0f; - - // to optimize, explicitly unroll this loop - for (int z = -1; z <=1; z++) - for (int y = -1; y <=1; y++) - for (int x = -1; x <=1; x++) - { - float weight = 1.0f; - c[0] = modFast128(mid[0] + x); - weight *= w[0][x+1]; - c[1] = modFast128(mid[1] + y); - weight *= w[1][y+1]; - c[2] = modFast128(mid[2] + z); - weight *= w[2][z+1]; - result += weight * data[c[2]*n*n+c[1]*n+c[0]]; - } - return result; -} - -#endif - diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp deleted file mode 100644 index 0703412d013..00000000000 --- a/intern/smoke/intern/WTURBULENCE.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// WTURBULENCE handling -/////////////////////////////////////////////////////////////////////////////////// -// Parallelized turbulence even further. TNT matrix library functions -// rewritten to improve performance. -// - MiikaH -////////////////////////////////////////////////////////////////////// - -#include "WTURBULENCE.h" -#include "INTERPOLATE.h" -#include "IMAGE.h" -#include <MERSENNETWISTER.h> -#include "WAVELET_NOISE.h" -#include "FFT_NOISE.h" -#include "EIGENVALUE_HELPER.h" -#include "LU_HELPER.h" -#include "SPHERE.h" -#include <zlib.h> -#include <math.h> - -// needed to access static advection functions -#include "FLUID_3D.h" - -#if PARALLEL==1 -#include <omp.h> -#endif // PARALLEL - -// 2^ {-5/6} -static const float persistence = 0.56123f; - -////////////////////////////////////////////////////////////////////// -// constructor -////////////////////////////////////////////////////////////////////// -WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, const char *noisefile_path, int init_fire, int init_colors) -{ - // if noise magnitude is below this threshold, its contribution - // is negilgible, so stop evaluating new octaves - _cullingThreshold = 1e-3; - - // factor by which to increase the simulation resolution - _amplify = amplify; - - // manually adjust the overall amount of turbulence - // DG - RNA-fied _strength = 2.; - - // add the corresponding octaves of noise - _octaves = (int)(log((float)_amplify) / log(2.0f) + 0.5f); // XXX DEBUG/ TODO: int casting correct? - dg - - // noise resolution - _xResBig = _amplify * xResSm; - _yResBig = _amplify * yResSm; - _zResBig = _amplify * zResSm; - _resBig = Vec3Int(_xResBig, _yResBig, _zResBig); - _invResBig = Vec3(1.0f/(float)_resBig[0], 1.0f/(float)_resBig[1], 1.0f/(float)_resBig[2]); - _slabSizeBig = _xResBig*_yResBig; - _totalCellsBig = _slabSizeBig * _zResBig; - - // original / small resolution - _xResSm = xResSm; - _yResSm = yResSm; - _zResSm = zResSm; - _resSm = Vec3Int(xResSm, yResSm, zResSm); - _invResSm = Vec3(1.0f/(float)_resSm[0], 1.0f/(float)_resSm[1], 1.0f/(float)_resSm[2] ); - _slabSizeSm = _xResSm*_yResSm; - _totalCellsSm = _slabSizeSm * _zResSm; - - // allocate high resolution density field - _totalStepsBig = 0; - _densityBig = new float[_totalCellsBig]; - _densityBigOld = new float[_totalCellsBig]; - - for(int i = 0; i < _totalCellsBig; i++) { - _densityBig[i] = - _densityBigOld[i] = 0.; - } - - /* fire */ - _flameBig = _fuelBig = _fuelBigOld = NULL; - _reactBig = _reactBigOld = NULL; - if (init_fire) { - initFire(); - } - /* colors */ - _color_rBig = _color_rBigOld = NULL; - _color_gBig = _color_gBigOld = NULL; - _color_bBig = _color_bBigOld = NULL; - if (init_colors) { - initColors(0.0f, 0.0f, 0.0f); - } - - // allocate & init texture coordinates - _tcU = new float[_totalCellsSm]; - _tcV = new float[_totalCellsSm]; - _tcW = new float[_totalCellsSm]; - _tcTemp = new float[_totalCellsSm]; - - // map all - const float dx = 1.0f/(float)(_resSm[0]); - const float dy = 1.0f/(float)(_resSm[1]); - const float dz = 1.0f/(float)(_resSm[2]); - int index = 0; - for (int z = 0; z < _zResSm; z++) - for (int y = 0; y < _yResSm; y++) - for (int x = 0; x < _xResSm; x++, index++) - { - _tcU[index] = x*dx; - _tcV[index] = y*dy; - _tcW[index] = z*dz; - _tcTemp[index] = 0.; - } - - // noise tiles - _noiseTile = new float[noiseTileSize * noiseTileSize * noiseTileSize]; - setNoise(noisetype, noisefile_path); -} - -void WTURBULENCE::initFire() -{ - if (!_fuelBig) { - _flameBig = new float[_totalCellsBig]; - _fuelBig = new float[_totalCellsBig]; - _fuelBigOld = new float[_totalCellsBig]; - _reactBig = new float[_totalCellsBig]; - _reactBigOld = new float[_totalCellsBig]; - - for(int i = 0; i < _totalCellsBig; i++) { - _flameBig[i] = - _fuelBig[i] = - _fuelBigOld[i] = 0.; - _reactBig[i] = - _reactBigOld[i] = 0.; - } - } -} - -void WTURBULENCE::initColors(float init_r, float init_g, float init_b) -{ - if (!_color_rBig) { - _color_rBig = new float[_totalCellsBig]; - _color_rBigOld = new float[_totalCellsBig]; - _color_gBig = new float[_totalCellsBig]; - _color_gBigOld = new float[_totalCellsBig]; - _color_bBig = new float[_totalCellsBig]; - _color_bBigOld = new float[_totalCellsBig]; - - for(int i = 0; i < _totalCellsBig; i++) { - _color_rBig[i] = _densityBig[i] * init_r; - _color_rBigOld[i] = 0.0f; - _color_gBig[i] = _densityBig[i] * init_g; - _color_gBigOld[i] = 0.0f; - _color_bBig[i] = _densityBig[i] * init_b; - _color_bBigOld[i] = 0.0f; - } - } -} - -////////////////////////////////////////////////////////////////////// -// destructor -////////////////////////////////////////////////////////////////////// -WTURBULENCE::~WTURBULENCE() { - delete[] _densityBig; - delete[] _densityBigOld; - if (_flameBig) delete[] _flameBig; - if (_fuelBig) delete[] _fuelBig; - if (_fuelBigOld) delete[] _fuelBigOld; - if (_reactBig) delete[] _reactBig; - if (_reactBigOld) delete[] _reactBigOld; - - if (_color_rBig) delete[] _color_rBig; - if (_color_rBigOld) delete[] _color_rBigOld; - if (_color_gBig) delete[] _color_gBig; - if (_color_gBigOld) delete[] _color_gBigOld; - if (_color_bBig) delete[] _color_bBig; - if (_color_bBigOld) delete[] _color_bBigOld; - - delete[] _tcU; - delete[] _tcV; - delete[] _tcW; - delete[] _tcTemp; - - delete[] _noiseTile; -} - -////////////////////////////////////////////////////////////////////// -// Change noise type -// -// type (1<<0) = wavelet / 2 -// type (1<<1) = FFT / 4 -// type (1<<2) = curl / 8 -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::setNoise(int type, const char *noisefile_path) -{ - if(type == (1<<1)) // FFT - { -#ifdef WITH_FFTW3 - // needs fft - std::string noiseTileFilename = std::string(noisefile_path) + std::string("noise.fft"); - generatTile_FFT(_noiseTile, noiseTileFilename); - return; -#else - fprintf(stderr, "FFTW not enabled, falling back to wavelet noise.\n"); -#endif - } -#if 0 - if(type == (1<<2)) // curl - { - // TODO: not supported yet - return; - } -#endif - - std::string noiseTileFilename = std::string(noisefile_path) + std::string("noise.wavelets"); - generateTile_WAVELET(_noiseTile, noiseTileFilename); -} - -// init direct access functions from blender -void WTURBULENCE::initBlenderRNA(float *strength) -{ - _strength = strength; -} - -////////////////////////////////////////////////////////////////////// -// Get the smallest valid x derivative -// -// Takes the one-sided finite difference in both directions and -// selects the smaller of the two -////////////////////////////////////////////////////////////////////// -static float minDx(int x, int y, int z, float* input, const Vec3Int& res) -{ - const int index = x + y * res[0] + z * res[0] * res[1]; - const int maxx = res[0]-2; - - // get grid values - float center = input[index]; - float left = (x <= 1) ? FLT_MAX : input[index - 1]; - float right = (x >= maxx) ? FLT_MAX : input[index + 1]; - - const float dx = res[0]; - - // get all the derivative estimates - float dLeft = (x <= 1) ? FLT_MAX : (center - left) * dx; - float dRight = (x >= maxx) ? FLT_MAX : (right - center) * dx; - float dCenter = (x <= 1 || x >= maxx) ? FLT_MAX : (right - left) * dx * 0.5f; - - // if it's on a boundary, only one estimate is valid - if (x <= 1) return dRight; - if (x >= maxx) return dLeft; - - // if it's not on a boundary, get the smallest one - float finalD; - finalD = (fabs(dCenter) < fabs(dRight)) ? dCenter : dRight; - finalD = (fabs(finalD) < fabs(dLeft)) ? finalD : dLeft; - - return finalD; -} - -////////////////////////////////////////////////////////////////////// -// get the smallest valid y derivative -// -// Takes the one-sided finite difference in both directions and -// selects the smaller of the two -////////////////////////////////////////////////////////////////////// -static float minDy(int x, int y, int z, float* input, const Vec3Int& res) -{ - const int index = x + y * res[0] + z * res[0] * res[1]; - const int maxy = res[1]-2; - - // get grid values - float center = input[index]; - float down = (y <= 1) ? FLT_MAX : input[index - res[0]]; - float up = (y >= maxy) ? FLT_MAX : input[index + res[0]]; - - const float dx = res[1]; // only for square domains - - // get all the derivative estimates - float dDown = (y <= 1) ? FLT_MAX : (center - down) * dx; - float dUp = (y >= maxy) ? FLT_MAX : (up - center) * dx; - float dCenter = (y <= 1 || y >= maxy) ? FLT_MAX : (up - down) * dx * 0.5f; - - // if it's on a boundary, only one estimate is valid - if (y <= 1) return dUp; - if (y >= maxy) return dDown; - - // if it's not on a boundary, get the smallest one - float finalD = (fabs(dCenter) < fabs(dUp)) ? dCenter : dUp; - finalD = (fabs(finalD) < fabs(dDown)) ? finalD : dDown; - - return finalD; -} - -////////////////////////////////////////////////////////////////////// -// get the smallest valid z derivative -// -// Takes the one-sided finite difference in both directions and -// selects the smaller of the two -////////////////////////////////////////////////////////////////////// -static float minDz(int x, int y, int z, float* input, const Vec3Int& res) -{ - const int slab = res[0]*res[1]; - const int index = x + y * res[0] + z * slab; - const int maxz = res[2]-2; - - // get grid values - float center = input[index]; - float front = (z <= 1) ? FLT_MAX : input[index - slab]; - float back = (z >= maxz) ? FLT_MAX : input[index + slab]; - - const float dx = res[2]; // only for square domains - - // get all the derivative estimates - float dfront = (z <= 1) ? FLT_MAX : (center - front) * dx; - float dback = (z >= maxz) ? FLT_MAX : (back - center) * dx; - float dCenter = (z <= 1 || z >= maxz) ? FLT_MAX : (back - front) * dx * 0.5f; - - // if it's on a boundary, only one estimate is valid - if (z <= 1) return dback; - if (z >= maxz) return dfront; - - // if it's not on a boundary, get the smallest one - float finalD = (fabs(dCenter) < fabs(dback)) ? dCenter : dback; - finalD = (fabs(finalD) < fabs(dfront)) ? finalD : dfront; - - return finalD; -} - -////////////////////////////////////////////////////////////////////// -// handle texture coordinates (advection, reset, eigenvalues), -// Beware -- uses big density maccormack as temporary arrays -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2) { - - // advection - SWAP_POINTERS(_tcTemp, _tcU); - FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel, - _tcTemp, tempBig1, _resSm, 0 , _resSm[2]); - FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel, - _tcTemp, _tcU, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]); - - SWAP_POINTERS(_tcTemp, _tcV); - FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel, - _tcTemp, tempBig1, _resSm, 0 , _resSm[2]); - FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel, - _tcTemp, _tcV, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]); - - SWAP_POINTERS(_tcTemp, _tcW); - FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]); - FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel, - _tcTemp, tempBig1, _resSm, 0 , _resSm[2]); - FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel, - _tcTemp, _tcW, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]); -} - -////////////////////////////////////////////////////////////////////// -// Compute the eigenvalues of the advected texture -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::computeEigenvalues(float *_eigMin, float *_eigMax) { - // stats - float maxeig = -1.; - float mineig = 10.; - - // texture coordinate eigenvalues - for (int z = 1; z < _zResSm-1; z++) { - for (int y = 1; y < _yResSm-1; y++) - for (int x = 1; x < _xResSm-1; x++) - { - const int index = x+ y *_resSm[0] + z*_slabSizeSm; - - // compute jacobian - float jacobian[3][3] = { - { minDx(x, y, z, _tcU, _resSm), minDx(x, y, z, _tcV, _resSm), minDx(x, y, z, _tcW, _resSm) } , - { minDy(x, y, z, _tcU, _resSm), minDy(x, y, z, _tcV, _resSm), minDy(x, y, z, _tcW, _resSm) } , - { minDz(x, y, z, _tcU, _resSm), minDz(x, y, z, _tcV, _resSm), minDz(x, y, z, _tcW, _resSm) } - }; - - // ONLY compute the eigenvalues after checking that the matrix - // is nonsingular - sLU LU = computeLU(jacobian); - - if (isNonsingular(LU)) - { - // get the analytic eigenvalues, quite slow right now... - Vec3 eigenvalues = Vec3(1.); - computeEigenvalues3x3( &eigenvalues[0], jacobian); - _eigMax[index] = MAX3V(eigenvalues); - _eigMin[index] = MIN3V(eigenvalues); - maxeig = MAX(_eigMax[index],maxeig); - mineig = MIN(_eigMin[index],mineig); - } - else - { - _eigMax[index] = 10.0f; - _eigMin[index] = 0.1; - } - } - } -} - -////////////////////////////////////////////////////////////////////// -// advect & reset texture coordinates based on eigenvalues -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::resetTextureCoordinates(float *_eigMin, float *_eigMax) -{ - // allowed deformation of the textures - const float limit = 2.f; - const float limitInv = 1.0f/limit; - - // standard reset - int resets = 0; - const float dx = 1.0f/(float)(_resSm[0]); - const float dy = 1.0f/(float)(_resSm[1]); - const float dz = 1.0f/(float)(_resSm[2]); - - for (int z = 1; z < _zResSm-1; z++) - for (int y = 1; y < _yResSm-1; y++) - for (int x = 1; x < _xResSm-1; x++) - { - const int index = x+ y *_resSm[0] + z*_slabSizeSm; - if (_eigMax[index] > limit || _eigMin[index] < limitInv) - { - _tcU[index] = (float)x * dx; - _tcV[index] = (float)y * dy; - _tcW[index] = (float)z * dz; - resets++; - } - } -} - -////////////////////////////////////////////////////////////////////// -// Compute the highest frequency component of the wavelet -// decomposition -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::decomposeEnergy(float *_energy, float *_highFreqEnergy) -{ - // do the decomposition -- the goal here is to have - // the energy with the high frequency component stomped out - // stored in _tcTemp when it is done. _highFreqEnergy is only used - // as an additional temp array - - // downsample input - downsampleXNeumann(_highFreqEnergy, _energy, _xResSm, _yResSm, _zResSm); - downsampleYNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm); - downsampleZNeumann(_highFreqEnergy, _tcTemp, _xResSm, _yResSm, _zResSm); - - // upsample input - upsampleZNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm); - upsampleYNeumann(_highFreqEnergy, _tcTemp, _xResSm, _yResSm, _zResSm); - upsampleXNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm); - - // subtract the down and upsampled field from the original field -- - // what should be left over is solely the high frequency component - int index = 0; - for (int z = 0; z < _zResSm; z++) - for (int y = 0; y < _yResSm; y++) { - for (int x = 0; x < _xResSm; x++, index++) { - // brute force reset of boundaries - if(z >= _zResSm - 1 || x >= _xResSm - 1 || y >= _yResSm - 1 || z <= 0 || y <= 0 || x <= 0) - _highFreqEnergy[index] = 0.; - else - _highFreqEnergy[index] = _energy[index] - _tcTemp[index]; - } - } -} - -////////////////////////////////////////////////////////////////////// -// compute velocity from energies and march into obstacles -// for wavelet decomposition -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::computeEnergy(float *_energy, float* xvel, float* yvel, float* zvel, unsigned char *origObstacles) -{ - unsigned char *obstacles = new unsigned char[_totalCellsSm]; - memcpy(obstacles, origObstacles, sizeof(unsigned char) * _totalCellsSm); - - // compute everywhere - for (int x = 0; x < _totalCellsSm; x++) - _energy[x] = 0.5f * (xvel[x] * xvel[x] + yvel[x] * yvel[x] + zvel[x] * zvel[x]); - - FLUID_3D::copyBorderX(_energy, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderY(_energy, _resSm, 0 , _resSm[2]); - FLUID_3D::copyBorderZ(_energy, _resSm, 0 , _resSm[2]); - - // pseudo-march the values into the obstacles - // the wavelet upsampler only uses a 3x3 support neighborhood, so - // propagating the values in by 4 should be sufficient - int index; - - // iterate - for (int iter = 0; iter < 4; iter++) - { - index = _slabSizeSm + _xResSm + 1; - for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm) - for (int y = 1; y < _yResSm - 1; y++, index += 2) - for (int x = 1; x < _xResSm - 1; x++, index++) - if (obstacles[index] && obstacles[index] != RETIRED) - { - float sum = 0.0f; - int valid = 0; - - if (!obstacles[index + 1] || obstacles[index + 1] == RETIRED) - { - sum += _energy[index + 1]; - valid++; - } - if (!obstacles[index - 1] || obstacles[index - 1] == RETIRED) - { - sum += _energy[index - 1]; - valid++; - } - if (!obstacles[index + _xResSm] || obstacles[index + _xResSm] == RETIRED) - { - sum += _energy[index + _xResSm]; - valid++; - } - if (!obstacles[index - _xResSm] || obstacles[index - _xResSm] == RETIRED) - { - sum += _energy[index - _xResSm]; - valid++; - } - if (!obstacles[index + _slabSizeSm] || obstacles[index + _slabSizeSm] == RETIRED) - { - sum += _energy[index + _slabSizeSm]; - valid++; - } - if (!obstacles[index - _slabSizeSm] || obstacles[index - _slabSizeSm] == RETIRED) - { - sum += _energy[index - _slabSizeSm]; - valid++; - } - if (valid > 0) - { - _energy[index] = sum / (float)valid; - obstacles[index] = MARCHED; - } - } - index = _slabSizeSm + _xResSm + 1; - for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm) - for (int y = 1; y < _yResSm - 1; y++, index += 2) - for (int x = 1; x < _xResSm - 1; x++, index++) - if (obstacles[index] == MARCHED) - obstacles[index] = RETIRED; - } - index = _slabSizeSm + _xResSm + 1; - for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm) - for (int y = 1; y < _yResSm - 1; y++, index += 2) - for (int x = 1; x < _xResSm - 1; x++, index++) - if (obstacles[index]) - obstacles[index] = 1; // DG TODO ? animated obstacle flag? - - delete [] obstacles; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Evaluate derivatives -////////////////////////////////////////////////////////////////////////////////////////// -Vec3 WTURBULENCE::WVelocity(Vec3 orgPos) -{ - // arbitrarily offset evaluation points - const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2.0,0,0); - const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2.0,0); - const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2.0); - - const float f1y = WNoiseDy(p1, _noiseTile); - const float f1z = WNoiseDz(p1, _noiseTile); - - const float f2x = WNoiseDx(p2, _noiseTile); - const float f2z = WNoiseDz(p2, _noiseTile); - - const float f3x = WNoiseDx(p3, _noiseTile); - const float f3y = WNoiseDy(p3, _noiseTile); - - Vec3 ret = Vec3( - f3y - f2z, - f1z - f3x, - f2x - f1y ); - return ret; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Evaluate derivatives with Jacobian -////////////////////////////////////////////////////////////////////////////////////////// -Vec3 WTURBULENCE::WVelocityWithJacobian(const Vec3& orgPos, float* xUnwarped, float* yUnwarped, float* zUnwarped) -{ - // arbitrarily offset evaluation points - const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2.0,0,0); - const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2.0,0); - const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2.0); - - Vec3 final; - final[0] = WNoiseDx(p1, _noiseTile); - final[1] = WNoiseDy(p1, _noiseTile); - final[2] = WNoiseDz(p1, _noiseTile); - // UNUSED const float f1x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2]; - const float f1y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2]; - const float f1z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2]; - - final[0] = WNoiseDx(p2, _noiseTile); - final[1] = WNoiseDy(p2, _noiseTile); - final[2] = WNoiseDz(p2, _noiseTile); - const float f2x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2]; - // UNUSED const float f2y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2]; - const float f2z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2]; - - final[0] = WNoiseDx(p3, _noiseTile); - final[1] = WNoiseDy(p3, _noiseTile); - final[2] = WNoiseDz(p3, _noiseTile); - const float f3x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2]; - const float f3y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2]; - // UNUSED const float f3z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2]; - - Vec3 ret = Vec3( - f3y - f2z, - f1z - f3x, - f2x - f1y ); - return ret; -} - - -////////////////////////////////////////////////////////////////////// -// perform an actual noise advection step -////////////////////////////////////////////////////////////////////// -/*void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles) -{ - // enlarge timestep to match grid - const float dt = dtOrg * _amplify; - const float invAmp = 1.0f / _amplify; - float *tempBig1 = new float[_totalCellsBig]; - float *tempBig2 = new float[_totalCellsBig]; - float *bigUx = new float[_totalCellsBig]; - float *bigUy = new float[_totalCellsBig]; - float *bigUz = new float[_totalCellsBig]; - float *_energy = new float[_totalCellsSm]; - float *highFreqEnergy = new float[_totalCellsSm]; - float *eigMin = new float[_totalCellsSm]; - float *eigMax = new float[_totalCellsSm]; - - memset(tempBig1, 0, sizeof(float)*_totalCellsBig); - memset(tempBig2, 0, sizeof(float)*_totalCellsBig); - memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm); - memset(eigMin, 0, sizeof(float)*_totalCellsSm); - memset(eigMax, 0, sizeof(float)*_totalCellsSm); - - // prepare textures - advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2); - - // compute eigenvalues of the texture coordinates - computeEigenvalues(eigMin, eigMax); - - // do wavelet decomposition of energy - computeEnergy(_energy, xvel, yvel, zvel, obstacles); - decomposeEnergy(_energy, highFreqEnergy); - - // zero out coefficients inside of the obstacle - for (int x = 0; x < _totalCellsSm; x++) - if (obstacles[x]) _energy[x] = 0.f; - - float maxVelocity = 0.; - for (int z = 1; z < _zResBig - 1; z++) - for (int y = 1; y < _yResBig - 1; y++) - for (int x = 1; x < _xResBig - 1; x++) - { - // get unit position for both fine and coarse grid - const Vec3 pos = Vec3(x,y,z); - const Vec3 posSm = pos * invAmp; - - // get grid index for both fine and coarse grid - const int index = x + y *_xResBig + z *_slabSizeBig; - const int indexSmall = (int)posSm[0] + (int)posSm[1] * _xResSm + (int)posSm[2] * _slabSizeSm; - - // get a linearly interpolated velocity and texcoords - // from the coarse grid - Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel, - posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); - Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW, - posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); - - // multiply the texture coordinate by _resSm so that turbulence - // synthesis begins at the first octave that the coarse grid - // cannot capture - Vec3 texCoord = Vec3(uvw[0] * _resSm[0], - uvw[1] * _resSm[1], - uvw[2] * _resSm[2]); - - // retrieve wavelet energy at highest frequency - float energy = INTERPOLATE::lerp3d( - highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm); - - // base amplitude for octave 0 - float coefficient = sqrtf(2.0f * fabs(energy)); - const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence; - - // add noise to velocity, but only if the turbulence is - // sufficiently undeformed, and the energy is large enough - // to make a difference - const bool addNoise = eigMax[indexSmall] < 2. && - eigMin[indexSmall] > 0.5; - if (addNoise && amplitude > _cullingThreshold) { - // base amplitude for octave 0 - float amplitudeScaled = amplitude; - - for (int octave = 0; octave < _octaves; octave++) - { - // multiply the vector noise times the maximum allowed - // noise amplitude at this octave, and add it to the total - vel += WVelocity(texCoord) * amplitudeScaled; - - // scale coefficient for next octave - amplitudeScaled *= persistence; - texCoord *= 2.0f; - } - } - - // Store velocity + turbulence in big grid for maccormack step - // - // If you wanted to save memory, you would instead perform a - // semi-Lagrangian backtrace for the current grid cell here. Then - // you could just throw the velocity away. - bigUx[index] = vel[0]; - bigUy[index] = vel[1]; - bigUz[index] = vel[2]; - - // compute the velocity magnitude for substepping later - const float velMag = bigUx[index] * bigUx[index] + - bigUy[index] * bigUy[index] + - bigUz[index] * bigUz[index]; - if (velMag > maxVelocity) maxVelocity = velMag; - - // zero out velocity inside obstacles - float obsCheck = INTERPOLATE::lerp3dToFloat( - obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm); - if (obsCheck > 0.95) - bigUx[index] = bigUy[index] = bigUz[index] = 0.; - } - - // prepare density for an advection - SWAP_POINTERS(_densityBig, _densityBigOld); - - // based on the maximum velocity present, see if we need to substep, - // but cap the maximum number of substeps to 5 - const int maxSubSteps = 5; - maxVelocity = sqrt(maxVelocity) * dt; - int totalSubsteps = (int)(maxVelocity / (float)maxSubSteps); - totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps; - totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; - const float dtSubdiv = dt / (float)totalSubsteps; - - // set boundaries of big velocity grid - FLUID_3D::setZeroX(bigUx, _resBig, 0, _resBig[2]); - FLUID_3D::setZeroY(bigUy, _resBig, 0, _resBig[2]); - FLUID_3D::setZeroZ(bigUz, _resBig, 0, _resBig[2]); - - // do the MacCormack advection, with substepping if necessary - for(int substep = 0; substep < totalSubsteps; substep++) - { - FLUID_3D::advectFieldMacCormack(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL); - - if (substep < totalSubsteps - 1) - SWAP_POINTERS(_densityBig, _densityBigOld); - } // substep - - // wipe the density borders - FLUID_3D::setZeroBorder(_densityBig, _resBig, 0, _resBig[2]); - - // reset texture coordinates now in preparation for next timestep - // Shouldn't do this before generating the noise because then the - // eigenvalues stored do not reflect the underlying texture coordinates - resetTextureCoordinates(eigMin, eigMax); - - delete[] tempBig1; - delete[] tempBig2; - delete[] bigUx; - delete[] bigUy; - delete[] bigUz; - delete[] _energy; - delete[] highFreqEnergy; - - delete[] eigMin; - delete[] eigMax; - - - _totalStepsBig++; -}*/ - -//struct - -////////////////////////////////////////////////////////////////////// -// perform the full turbulence algorithm, including OpenMP -// if available -////////////////////////////////////////////////////////////////////// -void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles) -{ - // enlarge timestep to match grid - const float dt = dtOrg * _amplify; - const float invAmp = 1.0f / _amplify; - float *tempFuelBig = NULL, *tempReactBig = NULL; - float *tempColor_rBig = NULL, *tempColor_gBig = NULL, *tempColor_bBig = NULL; - float *tempDensityBig = (float *)calloc(_totalCellsBig, sizeof(float)); - float *tempBig = (float *)calloc(_totalCellsBig, sizeof(float)); - float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float)); - float *bigUy = (float *)calloc(_totalCellsBig, sizeof(float)); - float *bigUz = (float *)calloc(_totalCellsBig, sizeof(float)); - float *_energy = (float *)calloc(_totalCellsSm, sizeof(float)); - float *highFreqEnergy = (float *)calloc(_totalCellsSm, sizeof(float)); - float *eigMin = (float *)calloc(_totalCellsSm, sizeof(float)); - float *eigMax = (float *)calloc(_totalCellsSm, sizeof(float)); - - if (_fuelBig) { - tempFuelBig = (float *)calloc(_totalCellsBig, sizeof(float)); - tempReactBig = (float *)calloc(_totalCellsBig, sizeof(float)); - } - if (_color_rBig) { - tempColor_rBig = (float *)calloc(_totalCellsBig, sizeof(float)); - tempColor_gBig = (float *)calloc(_totalCellsBig, sizeof(float)); - tempColor_bBig = (float *)calloc(_totalCellsBig, sizeof(float)); - } - - memset(_tcTemp, 0, sizeof(float)*_totalCellsSm); - - - // prepare textures - advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempDensityBig, tempBig); - - // do wavelet decomposition of energy - computeEnergy(_energy, xvel, yvel, zvel, obstacles); - - for (int x = 0; x < _totalCellsSm; x++) - if (obstacles[x]) _energy[x] = 0.f; - - decomposeEnergy(_energy, highFreqEnergy); - - // zero out coefficients inside of the obstacle - for (int x = 0; x < _totalCellsSm; x++) - if (obstacles[x]) highFreqEnergy[x] = 0.f; - - Vec3Int ressm(_xResSm, _yResSm, _zResSm); - FLUID_3D::setNeumannX(highFreqEnergy, ressm, 0 , ressm[2]); - FLUID_3D::setNeumannY(highFreqEnergy, ressm, 0 , ressm[2]); - FLUID_3D::setNeumannZ(highFreqEnergy, ressm, 0 , ressm[2]); - - - int threadval = 1; -#if PARALLEL==1 - threadval = omp_get_max_threads(); -#endif - - - // parallel region setup - // Uses omp_get_max_trheads to get number of required cells. - float* maxVelMagThreads = new float[threadval]; - - for (int i=0; i<threadval; i++) maxVelMagThreads[i] = -1.0f; - -#if PARALLEL==1 - -#pragma omp parallel -#endif - { float maxVelMag1 = 0.; -#if PARALLEL==1 - const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */ -#endif - - // vector noise main loop -#if PARALLEL==1 -#pragma omp for schedule(static,1) -#endif - for (int zSmall = 0; zSmall < _zResSm; zSmall++) - { - for (int ySmall = 0; ySmall < _yResSm; ySmall++) - for (int xSmall = 0; xSmall < _xResSm; xSmall++) - { - const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm; - - // compute jacobian - float jacobian[3][3] = { - { minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } , - { minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } , - { minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) } - }; - - // get LU factorization of texture jacobian and apply - // it to unit vectors - sLU LU = computeLU(jacobian); - float xUnwarped[3], yUnwarped[3], zUnwarped[3]; - float xWarped[3], yWarped[3], zWarped[3]; - bool nonSingular = isNonsingular(LU); - - xUnwarped[0] = 1.0f; xUnwarped[1] = 0.0f; xUnwarped[2] = 0.0f; - yUnwarped[0] = 0.0f; yUnwarped[1] = 1.0f; yUnwarped[2] = 0.0f; - zUnwarped[0] = 0.0f; zUnwarped[1] = 0.0f; zUnwarped[2] = 1.0f; - - xWarped[0] = 1.0f; xWarped[1] = 0.0f; xWarped[2] = 0.0f; - yWarped[0] = 0.0f; yWarped[1] = 1.0f; yWarped[2] = 0.0f; - zWarped[0] = 0.0f; zWarped[1] = 0.0f; zWarped[2] = 1.0f; - -#if 0 - // UNUSED - float eigMax = 10.0f; - float eigMin = 0.1f; -#endif - if (nonSingular) - { - solveLU3x3(LU, xUnwarped, xWarped); - solveLU3x3(LU, yUnwarped, yWarped); - solveLU3x3(LU, zUnwarped, zWarped); - - // compute the eigenvalues while we have the Jacobian available - Vec3 eigenvalues = Vec3(1.); - computeEigenvalues3x3( &eigenvalues[0], jacobian); - eigMax[indexSmall] = MAX3V(eigenvalues); - eigMin[indexSmall] = MIN3V(eigenvalues); - } - - // make sure to skip one on the beginning and end - int xStart = (xSmall == 0) ? 1 : 0; - int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify; - int yStart = (ySmall == 0) ? 1 : 0; - int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify; - int zStart = (zSmall == 0) ? 1 : 0; - int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify; - - for (int zBig = zStart; zBig < zEnd; zBig++) - for (int yBig = yStart; yBig < yEnd; yBig++) - for (int xBig = xStart; xBig < xEnd; xBig++) - { - const int x = xSmall * _amplify + xBig; - const int y = ySmall * _amplify + yBig; - const int z = zSmall * _amplify + zBig; - - // get unit position for both fine and coarse grid - const Vec3 pos = Vec3(x,y,z); - const Vec3 posSm = pos * invAmp; - - // get grid index for both fine and coarse grid - const int index = x + y *_xResBig + z *_slabSizeBig; - - // get a linearly interpolated velocity and texcoords - // from the coarse grid - Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel, - posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); - Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW, - posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); - - // multiply the texture coordinate by _resSm so that turbulence - // synthesis begins at the first octave that the coarse grid - // cannot capture - Vec3 texCoord = Vec3(uvw[0] * _resSm[0], - uvw[1] * _resSm[1], - uvw[2] * _resSm[2]); - - // retrieve wavelet energy at highest frequency - float energy = INTERPOLATE::lerp3d( - highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm); - - // base amplitude for octave 0 - float coefficient = sqrtf(2.0f * fabs(energy)); - const float amplitude = *_strength * fabs(0.5f * coefficient) * persistence; - - // add noise to velocity, but only if the turbulence is - // sufficiently undeformed, and the energy is large enough - // to make a difference - const bool addNoise = eigMax[indexSmall] < 2.0f && - eigMin[indexSmall] > 0.5f; - if (addNoise && amplitude > _cullingThreshold) { - // base amplitude for octave 0 - float amplitudeScaled = amplitude; - - for (int octave = 0; octave < _octaves; octave++) - { - // multiply the vector noise times the maximum allowed - // noise amplitude at this octave, and add it to the total - vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled; - - // scale coefficient for next octave - amplitudeScaled *= persistence; - texCoord *= 2.0f; - } - } - - // Store velocity + turbulence in big grid for maccormack step - // - // If you wanted to save memory, you would instead perform a - // semi-Lagrangian backtrace for the current grid cell here. Then - // you could just throw the velocity away. - bigUx[index] = vel[0]; - bigUy[index] = vel[1]; - bigUz[index] = vel[2]; - - // compute the velocity magnitude for substepping later - const float velMag = bigUx[index] * bigUx[index] + - bigUy[index] * bigUy[index] + - bigUz[index] * bigUz[index]; - if (velMag > maxVelMag1) maxVelMag1 = velMag; - - // zero out velocity inside obstacles - float obsCheck = INTERPOLATE::lerp3dToFloat( - obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm); - if (obsCheck > 0.95f) - bigUx[index] = bigUy[index] = bigUz[index] = 0.; - } // xyz*/ - -#if PARALLEL==1 - maxVelMagThreads[id] = maxVelMag1; -#else - maxVelMagThreads[0] = maxVelMag1; -#endif - } - } - } // omp - - // compute maximum over threads - float maxVelMag = maxVelMagThreads[0]; -#if PARALLEL==1 - for (int i = 1; i < threadval; i++) - if (maxVelMag < maxVelMagThreads[i]) - maxVelMag = maxVelMagThreads[i]; -#endif - delete [] maxVelMagThreads; - - - // prepare density for an advection - SWAP_POINTERS(_densityBig, _densityBigOld); - SWAP_POINTERS(_fuelBig, _fuelBigOld); - SWAP_POINTERS(_reactBig, _reactBigOld); - SWAP_POINTERS(_color_rBig, _color_rBigOld); - SWAP_POINTERS(_color_gBig, _color_gBigOld); - SWAP_POINTERS(_color_bBig, _color_bBigOld); - - // based on the maximum velocity present, see if we need to substep, - // but cap the maximum number of substeps to 5 - const int maxSubSteps = 25; - const int maxVel = 5; - maxVelMag = sqrt(maxVelMag) * dt; - int totalSubsteps = (int)(maxVelMag / (float)maxVel); - totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps; - // printf("totalSubsteps: %d\n", totalSubsteps); - totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; - const float dtSubdiv = dt / (float)totalSubsteps; - - // set boundaries of big velocity grid - FLUID_3D::setZeroX(bigUx, _resBig, 0 , _resBig[2]); - FLUID_3D::setZeroY(bigUy, _resBig, 0 , _resBig[2]); - FLUID_3D::setZeroZ(bigUz, _resBig, 0 , _resBig[2]); - -#if PARALLEL==1 - int stepParts = threadval*2; // Dividing parallelized sections into numOfThreads * 2 sections - float partSize = (float)_zResBig/stepParts; // Size of one part; - - if (partSize < 4) {stepParts = threadval; // If the slice gets too low (might actually slow things down, change it to larger - partSize = (float)_zResBig/stepParts;} - if (partSize < 4) {stepParts = (int)(ceil((float)_zResBig/4.0f)); // If it's still too low (only possible on future systems with +24 cores), change it to 4 - partSize = (float)_zResBig/stepParts;} -#else - int zBegin=0; - int zEnd=_resBig[2]; -#endif - - // do the MacCormack advection, with substepping if necessary - for(int substep = 0; substep < totalSubsteps; substep++) - { - -#if PARALLEL==1 - #pragma omp parallel - { - - #pragma omp for schedule(static,1) - for (int i=0; i<stepParts; i++) - { - int zBegin = (int)((float)i*partSize + 0.5f); - int zEnd = (int)((float)(i+1)*partSize + 0.5f); -#endif - FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, tempDensityBig, _resBig, zBegin, zEnd); - if (_fuelBig) { - FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _fuelBigOld, tempFuelBig, _resBig, zBegin, zEnd); - FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _reactBigOld, tempReactBig, _resBig, zBegin, zEnd); - } - if (_color_rBig) { - FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _color_rBigOld, tempColor_rBig, _resBig, zBegin, zEnd); - FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _color_gBigOld, tempColor_gBig, _resBig, zBegin, zEnd); - FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _color_bBigOld, tempColor_bBig, _resBig, zBegin, zEnd); - } -#if PARALLEL==1 - } - - #pragma omp barrier - - #pragma omp for schedule(static,1) - for (int i=0; i<stepParts; i++) - { - int zBegin = (int)((float)i*partSize + 0.5f); - int zEnd = (int)((float)(i+1)*partSize + 0.5f); -#endif - FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, _densityBig, tempDensityBig, tempBig, _resBig, NULL, zBegin, zEnd); - if (_fuelBig) { - FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _fuelBigOld, _fuelBig, tempFuelBig, tempBig, _resBig, NULL, zBegin, zEnd); - FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _reactBigOld, _reactBig, tempReactBig, tempBig, _resBig, NULL, zBegin, zEnd); - } - if (_color_rBig) { - FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _color_rBigOld, _color_rBig, tempColor_rBig, tempBig, _resBig, NULL, zBegin, zEnd); - FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _color_gBigOld, _color_gBig, tempColor_gBig, tempBig, _resBig, NULL, zBegin, zEnd); - FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _color_bBigOld, _color_bBig, tempColor_bBig, tempBig, _resBig, NULL, zBegin, zEnd); - } -#if PARALLEL==1 - } - } -#endif - - if (substep < totalSubsteps - 1) { - SWAP_POINTERS(_densityBig, _densityBigOld); - SWAP_POINTERS(_fuelBig, _fuelBigOld); - SWAP_POINTERS(_reactBig, _reactBigOld); - SWAP_POINTERS(_color_rBig, _color_rBigOld); - SWAP_POINTERS(_color_gBig, _color_gBigOld); - SWAP_POINTERS(_color_bBig, _color_bBigOld); - } - } // substep - - free(tempDensityBig); - if (tempFuelBig) free(tempFuelBig); - if (tempReactBig) free(tempReactBig); - if (tempColor_rBig) free(tempColor_rBig); - if (tempColor_gBig) free(tempColor_gBig); - if (tempColor_bBig) free(tempColor_bBig); - free(tempBig); - free(bigUx); - free(bigUy); - free(bigUz); - free(_energy); - free(highFreqEnergy); - - // wipe the density borders - FLUID_3D::setZeroBorder(_densityBig, _resBig, 0 , _resBig[2]); - if (_fuelBig) { - FLUID_3D::setZeroBorder(_fuelBig, _resBig, 0 , _resBig[2]); - FLUID_3D::setZeroBorder(_reactBig, _resBig, 0 , _resBig[2]); - } - if (_color_rBig) { - FLUID_3D::setZeroBorder(_color_rBig, _resBig, 0 , _resBig[2]); - FLUID_3D::setZeroBorder(_color_gBig, _resBig, 0 , _resBig[2]); - FLUID_3D::setZeroBorder(_color_bBig, _resBig, 0 , _resBig[2]); - } - - // reset texture coordinates now in preparation for next timestep - // Shouldn't do this before generating the noise because then the - // eigenvalues stored do not reflect the underlying texture coordinates - resetTextureCoordinates(eigMin, eigMax); - - free(eigMin); - free(eigMax); - - // output files - // string prefix = string("./amplified.preview/density_bigxy_"); - // FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f); - //string df3prefix = string("./df3/density_big_"); - //IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); - // string pbrtPrefix = string("./pbrt/density_big_"); - // IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); - - _totalStepsBig++; -} diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h deleted file mode 100644 index 7ad04cfd36e..00000000000 --- a/intern/smoke/intern/WTURBULENCE.h +++ /dev/null @@ -1,150 +0,0 @@ -/** \file - * \ingroup smoke - */ -////////////////////////////////////////////////////////////////////// -// This file is part of Wavelet Turbulence. -// -// Wavelet Turbulence is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Wavelet Turbulence is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. -// -// Copyright 2008 Theodore Kim and Nils Thuerey -// -// WTURBULENCE handling -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef WTURBULENCE_H -#define WTURBULENCE_H - -#include "VEC3.h" -using namespace BasicVector; -class SIMPLE_PARSER; - -/////////////////////////////////////////////////////////////////////////////// -/// Main WTURBULENCE class, stores large density array etc. -/////////////////////////////////////////////////////////////////////////////// -struct WTURBULENCE -{ - public: - // both config files can be NULL, altCfg might override values from noiseCfg - WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, const char *noisefile_path, int init_fire, int init_colors); - - /// destructor - virtual ~WTURBULENCE(); - - void initFire(); - void initColors(float init_r, float init_g, float init_b); - - void setNoise(int type, const char *noisefile_path); - void initBlenderRNA(float *strength); - - // step more readable version -- no rotation correction - void stepTurbulenceReadable(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles); - - // step more complete version -- include rotation correction - // and use OpenMP if available - void stepTurbulenceFull(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles); - - // texcoord functions - void advectTextureCoordinates(float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2); - void resetTextureCoordinates(float *_eigMin, float *_eigMax); - - void computeEnergy(float *energy, float* xvel, float* yvel, float* zvel, unsigned char *obstacles); - - // evaluate wavelet noise function - Vec3 WVelocity(Vec3 p); - Vec3 WVelocityWithJacobian(const Vec3& p, float* xUnwarped, float* yUnwarped, float* zUnwarped); - - // access functions - inline float* getDensityBig() { return _densityBig; } - inline float* getFlameBig() { return _flameBig; } - inline float* getFuelBig() { return _fuelBig; } - inline float* getArrayTcU() { return _tcU; } - inline float* getArrayTcV() { return _tcV; } - inline float* getArrayTcW() { return _tcW; } - - inline Vec3Int getResSm() { return _resSm; } // small resolution - inline Vec3Int getResBig() { return _resBig; } - inline int getOctaves() { return _octaves; } - - // is accessed on through rna gui - float *_strength; - - // protected: - // enlargement factor from original velocity field / simulation - // _Big = _amplify * _Sm - int _amplify; - int _octaves; - - // noise settings - float _cullingThreshold; - // float _noiseStrength; - // float _noiseSizeScale; - // bool _uvwAdvection; - // bool _uvwReset; - // float _noiseTimeanimSpeed; - // int _dumpInterval; - // nt _noiseControlType; - // debug, scale density for projections output images - // float _outputScale; - - // noise resolution - int _xResBig; - int _yResBig; - int _zResBig; - Vec3Int _resBig; - Vec3 _invResBig; - int _totalCellsBig; - int _slabSizeBig; - // original / small resolution - int _xResSm; - int _yResSm; - int _zResSm; - Vec3Int _resSm; - Vec3 _invResSm; - int _totalCellsSm; - int _slabSizeSm; - - float* _densityBig; - float* _densityBigOld; - float* _flameBig; - float* _fuelBig; - float* _fuelBigOld; - float* _reactBig; - float* _reactBigOld; - - float* _color_rBig; - float* _color_rBigOld; - float* _color_gBig; - float* _color_gBigOld; - float* _color_bBig; - float* _color_bBigOld; - - // texture coordinates for noise - float* _tcU; - float* _tcV; - float* _tcW; - float* _tcTemp; - - // noise data - float* _noiseTile; - //float* _noiseTileExt; - - // step counter - int _totalStepsBig; - - void computeEigenvalues(float *_eigMin, float *_eigMax); - void decomposeEnergy(float *energy, float *_highFreqEnergy); -}; - -#endif // WTURBULENCE_H - diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp deleted file mode 100644 index a02fa3bd684..00000000000 --- a/intern/smoke/intern/smoke_API.cpp +++ /dev/null @@ -1,495 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 by Daniel Genrich - * All rights reserved. - */ - -/** \file - * \ingroup smoke - */ - -#include "FLUID_3D.h" -#include "WTURBULENCE.h" - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#include "../extern/smoke_API.h" /* to ensure valid prototypes */ - -extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors) -{ - FLUID_3D *fluid = new FLUID_3D(res, dx, dtdef, use_heat, use_fire, use_colors); - return fluid; -} - -extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, const char *noisefile_path, int use_fire, int use_colors) -{ - if (amplify) - return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, noisefile_path, use_fire, use_colors); - else - return NULL; -} - -extern "C" void smoke_free(FLUID_3D *fluid) -{ - delete fluid; - fluid = NULL; -} - -extern "C" void smoke_turbulence_free(WTURBULENCE *wt) -{ - delete wt; - wt = NULL; -} - -extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */) -{ - return x + y * max_x + z * max_x*max_y; -} - -extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */) -{ - return x + y * max_x; -} - -extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv) -{ - if (fluid->_fuel) { - fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_heat, - fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv); - } - fluid->step(dtSubdiv, gravity); - - if (fluid->_fuel) { - fluid->updateFlame(fluid->_react, fluid->_flame, fluid->_totalCells); - } -} - -extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid) -{ - if (wt->_fuelBig) { - fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, 0, - wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt); - } - wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); - - if (wt->_fuelBig) { - fluid->updateFlame(wt->_reactBig, wt->_flameBig, wt->_totalCellsBig); - } -} - -extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, - float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp) -{ - fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli, burning_rate, flame_smoke, flame_smoke_color, flame_vorticity, flame_ignition_temp, flame_max_temp); -} - -extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) -{ - wt->initBlenderRNA(strength); -} - -static void data_dissolve(float *density, float *heat, float *r, float *g, float *b, int total_cells, int speed, int log) -{ - if (log) { - /* max density/speed = dydx */ - float fac = 1.0f - (1.0f / (float)speed); - - for(size_t i = 0; i < total_cells; i++) - { - /* density */ - density[i] *= fac; - - /* heat */ - if (heat) { - heat[i] *= fac; - } - - /* color */ - if (r) { - r[i] *= fac; - g[i] *= fac; - b[i] *= fac; - } - } - } - else // linear falloff - { - /* max density/speed = dydx */ - float dydx = 1.0f / (float)speed; - - for(size_t i = 0; i < total_cells; i++) - { - float d = density[i]; - /* density */ - density[i] -= dydx; - if (density[i] < 0.0f) - density[i] = 0.0f; - - /* heat */ - if (heat) { - if (abs(heat[i]) < dydx) heat[i] = 0.0f; - else if (heat[i] > 0.0f) heat[i] -= dydx; - else if (heat[i] < 0.0f) heat[i] += dydx; - } - - /* color */ - if (r && d) { - r[i] *= (density[i]/d); - g[i] *= (density[i]/d); - b[i] *= (density[i]/d); - } - - } - } -} - -extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) -{ - data_dissolve(fluid->_density, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, speed, log); -} - -extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) -{ - data_dissolve(wt->_densityBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, speed, log); -} - -extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, - float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles) -{ - *dens = fluid->_density; - if(fuel) - *fuel = fluid->_fuel; - if(react) - *react = fluid->_react; - if(flame) - *flame = fluid->_flame; - if(heat) - *heat = fluid->_heat; - if(heatold) - *heatold = fluid->_heatOld; - *vx = fluid->_xVelocity; - *vy = fluid->_yVelocity; - *vz = fluid->_zVelocity; - if(r) - *r = fluid->_color_r; - if(g) - *g = fluid->_color_g; - if(b) - *b = fluid->_color_b; - *obstacles = fluid->_obstacles; - *dt = fluid->_dt; - *dx = fluid->_dx; -} - -extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, - float **r, float **g, float **b , float **tcu, float **tcv, float **tcw) -{ - if (!wt) - return; - - *dens = wt->_densityBig; - if(fuel) - *fuel = wt->_fuelBig; - if(react) - *react = wt->_reactBig; - if(flame) - *flame = wt->_flameBig; - if(r) - *r = wt->_color_rBig; - if(g) - *g = wt->_color_gBig; - if(b) - *b = wt->_color_bBig; - *tcu = wt->_tcU; - *tcv = wt->_tcV; - *tcw = wt->_tcW; -} - -extern "C" float *smoke_get_density(FLUID_3D *fluid) -{ - return fluid->_density; -} - -extern "C" float *smoke_get_fuel(FLUID_3D *fluid) -{ - return fluid->_fuel; -} - -extern "C" float *smoke_get_react(FLUID_3D *fluid) -{ - return fluid->_react; -} - -extern "C" float *smoke_get_heat(FLUID_3D *fluid) -{ - return fluid->_heat; -} - -extern "C" float *smoke_get_velocity_x(FLUID_3D *fluid) -{ - return fluid->_xVelocity; -} - -extern "C" float *smoke_get_velocity_y(FLUID_3D *fluid) -{ - return fluid->_yVelocity; -} - -extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid) -{ - return fluid->_zVelocity; -} - -extern "C" float *smoke_get_force_x(FLUID_3D *fluid) -{ - return fluid->_xForce; -} - -extern "C" float *smoke_get_force_y(FLUID_3D *fluid) -{ - return fluid->_yForce; -} - -extern "C" float *smoke_get_force_z(FLUID_3D *fluid) -{ - return fluid->_zForce; -} - -extern "C" float *smoke_get_flame(FLUID_3D *fluid) -{ - return fluid->_flame; -} - -extern "C" float *smoke_get_color_r(FLUID_3D *fluid) -{ - return fluid->_color_r; -} - -extern "C" float *smoke_get_color_g(FLUID_3D *fluid) -{ - return fluid->_color_g; -} - -extern "C" float *smoke_get_color_b(FLUID_3D *fluid) -{ - return fluid->_color_b; -} - -static void get_rgba(float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential) -{ - int i; - int m = 4, i_g = 1, i_b = 2, i_a = 3; - /* sequential data */ - if (sequential) { - m = 1; - i_g *= total_cells; - i_b *= total_cells; - i_a *= total_cells; - } - - for (i=0; i<total_cells; i++) { - float alpha = a[i]; - if (alpha) { - data[i*m ] = r[i]; - data[i*m+i_g] = g[i]; - data[i*m+i_b] = b[i]; - } - else { - data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f; - } - data[i*m+i_a] = alpha; - } -} - -extern "C" void smoke_get_rgba(FLUID_3D *fluid, float *data, int sequential) -{ - get_rgba(fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_density, fluid->_totalCells, data, sequential); -} - -extern "C" void smoke_turbulence_get_rgba(WTURBULENCE *wt, float *data, int sequential) -{ - get_rgba(wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_densityBig, wt->_totalCellsBig, data, sequential); -} - -/* get a single color premultiplied voxel grid */ -static void get_rgba_from_density(float color[3], float *a, int total_cells, float *data, int sequential) -{ - int i; - int m = 4, i_g = 1, i_b = 2, i_a = 3; - /* sequential data */ - if (sequential) { - m = 1; - i_g *= total_cells; - i_b *= total_cells; - i_a *= total_cells; - } - - for (i=0; i<total_cells; i++) { - float alpha = a[i]; - if (alpha) { - data[i*m ] = color[0] * alpha; - data[i*m+i_g] = color[1] * alpha; - data[i*m+i_b] = color[2] * alpha; - } - else { - data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f; - } - data[i*m+i_a] = alpha; - } -} - -extern "C" void smoke_get_rgba_from_density(FLUID_3D *fluid, float color[3], float *data, int sequential) -{ - get_rgba_from_density(color, fluid->_density, fluid->_totalCells, data, sequential); -} - -extern "C" void smoke_turbulence_get_rgba_from_density(WTURBULENCE *wt, float color[3], float *data, int sequential) -{ - get_rgba_from_density(color, wt->_densityBig, wt->_totalCellsBig, data, sequential); -} - -extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt) -{ - return wt ? wt->getDensityBig() : NULL; -} - -extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt) -{ - return wt ? wt->getFuelBig() : NULL; -} - -extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt) -{ - return wt ? wt->_reactBig : NULL; -} - -extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt) -{ - return wt ? wt->_color_rBig : NULL; -} - -extern "C" float *smoke_turbulence_get_color_g(WTURBULENCE *wt) -{ - return wt ? wt->_color_gBig : NULL; -} - -extern "C" float *smoke_turbulence_get_color_b(WTURBULENCE *wt) -{ - return wt ? wt->_color_bBig : NULL; -} - -extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt) -{ - return wt ? wt->getFlameBig() : NULL; -} - -extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) -{ - if (wt) { - Vec3Int r = wt->getResBig(); - res[0] = r[0]; - res[1] = r[1]; - res[2] = r[2]; - } -} - -extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt) -{ - if (wt) { - Vec3Int r = wt->getResBig(); - return r[0] * r[1] * r[2]; - } - return 0; -} - -extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid) -{ - return fluid->_obstacles; -} - -extern "C" void smoke_get_ob_velocity(FLUID_3D *fluid, float **x, float **y, float **z) -{ - *x = fluid->_xVelocityOb; - *y = fluid->_yVelocityOb; - *z = fluid->_zVelocityOb; -} - -#if 0 -extern "C" unsigned char *smoke_get_obstacle_anim(FLUID_3D *fluid) -{ - return fluid->_obstaclesAnim; -} -#endif - -extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type, const char *noisefile_path) -{ - wt->setNoise(type, noisefile_path); -} - -extern "C" int smoke_has_heat(FLUID_3D *fluid) -{ - return (fluid->_heat) ? 1 : 0; -} - -extern "C" int smoke_has_fuel(FLUID_3D *fluid) -{ - return (fluid->_fuel) ? 1 : 0; -} - -extern "C" int smoke_has_colors(FLUID_3D *fluid) -{ - return (fluid->_color_r && fluid->_color_g && fluid->_color_b) ? 1 : 0; -} - -extern "C" int smoke_turbulence_has_fuel(WTURBULENCE *wt) -{ - return (wt->_fuelBig) ? 1 : 0; -} - -extern "C" int smoke_turbulence_has_colors(WTURBULENCE *wt) -{ - return (wt->_color_rBig && wt->_color_gBig && wt->_color_bBig) ? 1 : 0; -} - -/* additional field initialization */ -extern "C" void smoke_ensure_heat(FLUID_3D *fluid) -{ - if (fluid) { - fluid->initHeat(); - } -} - -extern "C" void smoke_ensure_fire(FLUID_3D *fluid, WTURBULENCE *wt) -{ - if (fluid) { - fluid->initFire(); - } - if (wt) { - wt->initFire(); - } -} - -extern "C" void smoke_ensure_colors(FLUID_3D *fluid, WTURBULENCE *wt, float init_r, float init_g, float init_b) -{ - if (fluid) { - fluid->initColors(init_r, init_g, init_b); - } - if (wt) { - wt->initColors(init_r, init_g, init_b); - } -} diff --git a/intern/smoke/intern/tnt/jama_eig.h b/intern/smoke/intern/tnt/jama_eig.h deleted file mode 100644 index 8b1ac999798..00000000000 --- a/intern/smoke/intern/tnt/jama_eig.h +++ /dev/null @@ -1,1053 +0,0 @@ -/** \file - * \ingroup smoke - */ -#ifndef JAMA_EIG_H -#define JAMA_EIG_H - - -#include "tnt_array1d.h" -#include "tnt_array2d.h" -#include "tnt_math_utils.h" - -#include <algorithm> -// for min(), max() below - -#include <cmath> -// for fabs() below - -using namespace TNT; -using namespace std; - -// NT debugging -//static int gEigenDebug=0; -//if(gEigenDebug) std::cerr<<"n="<<n<<" m="<<m<<" l="<<l<<"\n"; -// m has to be smaller l! in line 262 -// gcc can get confused with abs calls, replaced by fabs - -namespace JAMA -{ - -/** - - Computes eigenvalues and eigenvectors of a real (non-complex) - matrix. -<P> - If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is - diagonal and the eigenvector matrix V is orthogonal. That is, - the diagonal values of D are the eigenvalues, and - V*V' = I, where I is the identity matrix. The columns of V - represent the eigenvectors in the sense that A*V = V*D. - -<P> - If A is not symmetric, then the eigenvalue matrix D is block diagonal - with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, - a + i*b, in 2-by-2 blocks, [a, b; -b, a]. That is, if the complex - eigenvalues look like -<pre> - - u + iv . . . . . - . u - iv . . . . - . . a + ib . . . - . . . a - ib . . - . . . . x . - . . . . . y -</pre> - then D looks like -<pre> - - u v . . . . - -v u . . . . - . . a b . . - . . -b a . . - . . . . x . - . . . . . y -</pre> - This keeps V a real matrix in both symmetric and non-symmetric - cases, and A*V = V*D. - - - - <p> - The matrix V may be badly - conditioned, or even singular, so the validity of the equation - A = V*D*inverse(V) depends upon the condition number of V. - - <p> - (Adapted from JAMA, a Java Matrix Library, developed by jointly - by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama). -**/ - -template <class Real> -class Eigenvalue -{ - - - /** Row and column dimension (square matrix). */ - int n; - - int issymmetric; /* boolean*/ - - /** Arrays for internal storage of eigenvalues. */ - - TNT::Array1D<Real> d; /* real part */ - TNT::Array1D<Real> e; /* img part */ - - /** Array for internal storage of eigenvectors. */ - TNT::Array2D<Real> V; - - /** Array for internal storage of nonsymmetric Hessenberg form. - @serial internal storage of nonsymmetric Hessenberg form. - */ - TNT::Array2D<Real> H; - - - /** Working storage for nonsymmetric algorithm. - @serial working storage for nonsymmetric algorithm. - */ - TNT::Array1D<Real> ort; - - - // Symmetric Householder reduction to tridiagonal form. - - void tred2() { - - // This is derived from the Algol procedures tred2 by - // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for - // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - - for (int j = 0; j < n; j++) { - d[j] = V[n-1][j]; - } - - // Householder reduction to tridiagonal form. - - for (int i = n-1; i > 0; i--) { - - // Scale to avoid under/overflow. - - Real scale = 0.0; - Real h = 0.0; - for (int k = 0; k < i; k++) { - scale = scale + fabs(d[k]); - } - if (scale == 0.0) { - e[i] = d[i-1]; - for (int j = 0; j < i; j++) { - d[j] = V[i-1][j]; - V[i][j] = 0.0; - V[j][i] = 0.0; - } - } else { - - // Generate Householder vector. - - for (int k = 0; k < i; k++) { - d[k] /= scale; - h += d[k] * d[k]; - } - Real f = d[i-1]; - Real g = sqrt(h); - if (f > 0) { - g = -g; - } - e[i] = scale * g; - h = h - f * g; - d[i-1] = f - g; - for (int j = 0; j < i; j++) { - e[j] = 0.0; - } - - // Apply similarity transformation to remaining columns. - - for (int j = 0; j < i; j++) { - f = d[j]; - V[j][i] = f; - g = e[j] + V[j][j] * f; - for (int k = j+1; k <= i-1; k++) { - g += V[k][j] * d[k]; - e[k] += V[k][j] * f; - } - e[j] = g; - } - f = 0.0; - for (int j = 0; j < i; j++) { - e[j] /= h; - f += e[j] * d[j]; - } - Real hh = f / (h + h); - for (int j = 0; j < i; j++) { - e[j] -= hh * d[j]; - } - for (int j = 0; j < i; j++) { - f = d[j]; - g = e[j]; - for (int k = j; k <= i-1; k++) { - V[k][j] -= (f * e[k] + g * d[k]); - } - d[j] = V[i-1][j]; - V[i][j] = 0.0; - } - } - d[i] = h; - } - - // Accumulate transformations. - - for (int i = 0; i < n-1; i++) { - V[n-1][i] = V[i][i]; - V[i][i] = 1.0; - Real h = d[i+1]; - if (h != 0.0) { - for (int k = 0; k <= i; k++) { - d[k] = V[k][i+1] / h; - } - for (int j = 0; j <= i; j++) { - Real g = 0.0; - for (int k = 0; k <= i; k++) { - g += V[k][i+1] * V[k][j]; - } - for (int k = 0; k <= i; k++) { - V[k][j] -= g * d[k]; - } - } - } - for (int k = 0; k <= i; k++) { - V[k][i+1] = 0.0; - } - } - for (int j = 0; j < n; j++) { - d[j] = V[n-1][j]; - V[n-1][j] = 0.0; - } - V[n-1][n-1] = 1.0; - e[0] = 0.0; - } - - // Symmetric tridiagonal QL algorithm. - - void tql2 () { - - // This is derived from the Algol procedures tql2, by - // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for - // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - - for (int i = 1; i < n; i++) { - e[i-1] = e[i]; - } - e[n-1] = 0.0; - - Real f = 0.0; - Real tst1 = 0.0; - Real eps = pow(2.0,-52.0); - for (int l = 0; l < n; l++) { - - // Find small subdiagonal element - - tst1 = max(tst1,fabs(d[l]) + fabs(e[l])); - int m = l; - - // Original while-loop from Java code - while (m < n) { - if (fabs(e[m]) <= eps*tst1) { - break; - } - m++; - } - - - // If m == l, d[l] is an eigenvalue, - // otherwise, iterate. - - if (m > l) { - int iter = 0; - do { - iter = iter + 1; // (Could check iteration count here.) - - // Compute implicit shift - - Real g = d[l]; - Real p = (d[l+1] - g) / (2.0 * e[l]); - Real r = hypot(p,1.0); - if (p < 0) { - r = -r; - } - d[l] = e[l] / (p + r); - d[l+1] = e[l] * (p + r); - Real dl1 = d[l+1]; - Real h = g - d[l]; - for (int i = l+2; i < n; i++) { - d[i] -= h; - } - f = f + h; - - // Implicit QL transformation. - - p = d[m]; - Real c = 1.0; - Real c2 = c; - Real c3 = c; - Real el1 = e[l+1]; - Real s = 0.0; - Real s2 = 0.0; - for (int i = m-1; i >= l; i--) { - c3 = c2; - c2 = c; - s2 = s; - g = c * e[i]; - h = c * p; - r = hypot(p,e[i]); - e[i+1] = s * r; - s = e[i] / r; - c = p / r; - p = c * d[i] - s * g; - d[i+1] = h + s * (c * g + s * d[i]); - - // Accumulate transformation. - - for (int k = 0; k < n; k++) { - h = V[k][i+1]; - V[k][i+1] = s * V[k][i] + c * h; - V[k][i] = c * V[k][i] - s * h; - } - } - p = -s * s2 * c3 * el1 * e[l] / dl1; - e[l] = s * p; - d[l] = c * p; - - // Check for convergence. - - } while (fabs(e[l]) > eps*tst1); - } - d[l] = d[l] + f; - e[l] = 0.0; - } - - // Sort eigenvalues and corresponding vectors. - - for (int i = 0; i < n-1; i++) { - int k = i; - Real p = d[i]; - for (int j = i+1; j < n; j++) { - if (d[j] < p) { - k = j; - p = d[j]; - } - } - if (k != i) { - d[k] = d[i]; - d[i] = p; - for (int j = 0; j < n; j++) { - p = V[j][i]; - V[j][i] = V[j][k]; - V[j][k] = p; - } - } - } - } - - // Nonsymmetric reduction to Hessenberg form. - - void orthes () { - - // This is derived from the Algol procedures orthes and ortran, - // by Martin and Wilkinson, Handbook for Auto. Comp., - // Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutines in EISPACK. - - int low = 0; - int high = n-1; - - for (int m = low+1; m <= high-1; m++) { - - // Scale column. - - Real scale = 0.0; - for (int i = m; i <= high; i++) { - scale = scale + fabs(H[i][m-1]); - } - if (scale != 0.0) { - - // Compute Householder transformation. - - Real h = 0.0; - for (int i = high; i >= m; i--) { - ort[i] = H[i][m-1]/scale; - h += ort[i] * ort[i]; - } - Real g = sqrt(h); - if (ort[m] > 0) { - g = -g; - } - h = h - ort[m] * g; - ort[m] = ort[m] - g; - - // Apply Householder similarity transformation - // H = (I-u*u'/h)*H*(I-u*u')/h) - - for (int j = m; j < n; j++) { - Real f = 0.0; - for (int i = high; i >= m; i--) { - f += ort[i]*H[i][j]; - } - f = f/h; - for (int i = m; i <= high; i++) { - H[i][j] -= f*ort[i]; - } - } - - for (int i = 0; i <= high; i++) { - Real f = 0.0; - for (int j = high; j >= m; j--) { - f += ort[j]*H[i][j]; - } - f = f/h; - for (int j = m; j <= high; j++) { - H[i][j] -= f*ort[j]; - } - } - ort[m] = scale*ort[m]; - H[m][m-1] = scale*g; - } - } - - // Accumulate transformations (Algol's ortran). - - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - V[i][j] = (i == j ? 1.0 : 0.0); - } - } - - for (int m = high-1; m >= low+1; m--) { - if (H[m][m-1] != 0.0) { - for (int i = m+1; i <= high; i++) { - ort[i] = H[i][m-1]; - } - for (int j = m; j <= high; j++) { - Real g = 0.0; - for (int i = m; i <= high; i++) { - g += ort[i] * V[i][j]; - } - // Double division avoids possible underflow - g = (g / ort[m]) / H[m][m-1]; - for (int i = m; i <= high; i++) { - V[i][j] += g * ort[i]; - } - } - } - } - } - - - // Complex scalar division. - - Real cdivr, cdivi; - void cdiv(Real xr, Real xi, Real yr, Real yi) { - Real r,d; - if (fabs(yr) > fabs(yi)) { - r = yi/yr; - d = yr + r*yi; - cdivr = (xr + r*xi)/d; - cdivi = (xi - r*xr)/d; - } else { - r = yr/yi; - d = yi + r*yr; - cdivr = (r*xr + xi)/d; - cdivi = (r*xi - xr)/d; - } - } - - - // Nonsymmetric reduction from Hessenberg to real Schur form. - - void hqr2 () { - - // This is derived from the Algol procedure hqr2, - // by Martin and Wilkinson, Handbook for Auto. Comp., - // Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - - // Initialize - - int nn = this->n; - int n = nn-1; - int low = 0; - int high = nn-1; - Real eps = pow(2.0,-52.0); - Real exshift = 0.0; - Real p=0,q=0,r=0,s=0,z=0,t,w,x,y; - - // Store roots isolated by balanc and compute matrix norm - - Real norm = 0.0; - for (int i = 0; i < nn; i++) { - if ((i < low) || (i > high)) { - d[i] = H[i][i]; - e[i] = 0.0; - } - for (int j = max(i-1,0); j < nn; j++) { - norm = norm + fabs(H[i][j]); - } - } - - // Outer loop over eigenvalue index - - int iter = 0; - int totIter = 0; - while (n >= low) { - - // NT limit no. of iterations - totIter++; - if(totIter>100) { - //if(totIter>15) std::cout<<"!!!!iter ABORT !!!!!!! "<<totIter<<"\n"; - // NT hack/fix, return large eigenvalues - for (int i = 0; i < nn; i++) { - d[i] = 10000.; - e[i] = 10000.; - } - return; - } - - // Look for single small sub-diagonal element - - int l = n; - while (l > low) { - s = fabs(H[l-1][l-1]) + fabs(H[l][l]); - if (s == 0.0) { - s = norm; - } - if (fabs(H[l][l-1]) < eps * s) { - break; - } - l--; - } - - // Check for convergence - // One root found - - if (l == n) { - H[n][n] = H[n][n] + exshift; - d[n] = H[n][n]; - e[n] = 0.0; - n--; - iter = 0; - - // Two roots found - - } else if (l == n-1) { - w = H[n][n-1] * H[n-1][n]; - p = (H[n-1][n-1] - H[n][n]) / 2.0; - q = p * p + w; - z = sqrt(fabs(q)); - H[n][n] = H[n][n] + exshift; - H[n-1][n-1] = H[n-1][n-1] + exshift; - x = H[n][n]; - - // Real pair - - if (q >= 0) { - if (p >= 0) { - z = p + z; - } else { - z = p - z; - } - d[n-1] = x + z; - d[n] = d[n-1]; - if (z != 0.0) { - d[n] = x - w / z; - } - e[n-1] = 0.0; - e[n] = 0.0; - x = H[n][n-1]; - s = fabs(x) + fabs(z); - p = x / s; - q = z / s; - r = sqrt(p * p+q * q); - p = p / r; - q = q / r; - - // Row modification - - for (int j = n-1; j < nn; j++) { - z = H[n-1][j]; - H[n-1][j] = q * z + p * H[n][j]; - H[n][j] = q * H[n][j] - p * z; - } - - // Column modification - - for (int i = 0; i <= n; i++) { - z = H[i][n-1]; - H[i][n-1] = q * z + p * H[i][n]; - H[i][n] = q * H[i][n] - p * z; - } - - // Accumulate transformations - - for (int i = low; i <= high; i++) { - z = V[i][n-1]; - V[i][n-1] = q * z + p * V[i][n]; - V[i][n] = q * V[i][n] - p * z; - } - - // Complex pair - - } else { - d[n-1] = x + p; - d[n] = x + p; - e[n-1] = z; - e[n] = -z; - } - n = n - 2; - iter = 0; - - // No convergence yet - - } else { - - // Form shift - - x = H[n][n]; - y = 0.0; - w = 0.0; - if (l < n) { - y = H[n-1][n-1]; - w = H[n][n-1] * H[n-1][n]; - } - - // Wilkinson's original ad hoc shift - - if (iter == 10) { - exshift += x; - for (int i = low; i <= n; i++) { - H[i][i] -= x; - } - s = fabs(H[n][n-1]) + fabs(H[n-1][n-2]); - x = y = 0.75 * s; - w = -0.4375 * s * s; - } - - // MATLAB's new ad hoc shift - - if (iter == 30) { - s = (y - x) / 2.0; - s = s * s + w; - if (s > 0) { - s = sqrt(s); - if (y < x) { - s = -s; - } - s = x - w / ((y - x) / 2.0 + s); - for (int i = low; i <= n; i++) { - H[i][i] -= s; - } - exshift += s; - x = y = w = 0.964; - } - } - - iter = iter + 1; // (Could check iteration count here.) - - // Look for two consecutive small sub-diagonal elements - - int m = n-2; - while (m >= l) { - z = H[m][m]; - r = x - z; - s = y - z; - p = (r * s - w) / H[m+1][m] + H[m][m+1]; - q = H[m+1][m+1] - z - r - s; - r = H[m+2][m+1]; - s = fabs(p) + fabs(q) + fabs(r); - p = p / s; - q = q / s; - r = r / s; - if (m == l) { - break; - } - if (fabs(H[m][m-1]) * (fabs(q) + fabs(r)) < - eps * (fabs(p) * (fabs(H[m-1][m-1]) + fabs(z) + - fabs(H[m+1][m+1])))) { - break; - } - m--; - } - - for (int i = m+2; i <= n; i++) { - H[i][i-2] = 0.0; - if (i > m+2) { - H[i][i-3] = 0.0; - } - } - - // Double QR step involving rows l:n and columns m:n - - for (int k = m; k <= n-1; k++) { - int notlast = (k != n-1); - if (k != m) { - p = H[k][k-1]; - q = H[k+1][k-1]; - r = (notlast ? H[k+2][k-1] : 0.0); - x = fabs(p) + fabs(q) + fabs(r); - if (x != 0.0) { - p = p / x; - q = q / x; - r = r / x; - } - } - if (x == 0.0) { - break; - } - s = sqrt(p * p + q * q + r * r); - if (p < 0) { - s = -s; - } - if (s != 0) { - if (k != m) { - H[k][k-1] = -s * x; - } else if (l != m) { - H[k][k-1] = -H[k][k-1]; - } - p = p + s; - x = p / s; - y = q / s; - z = r / s; - q = q / p; - r = r / p; - - // Row modification - - for (int j = k; j < nn; j++) { - p = H[k][j] + q * H[k+1][j]; - if (notlast) { - p = p + r * H[k+2][j]; - H[k+2][j] = H[k+2][j] - p * z; - } - H[k][j] = H[k][j] - p * x; - H[k+1][j] = H[k+1][j] - p * y; - } - - // Column modification - - for (int i = 0; i <= min(n,k+3); i++) { - p = x * H[i][k] + y * H[i][k+1]; - if (notlast) { - p = p + z * H[i][k+2]; - H[i][k+2] = H[i][k+2] - p * r; - } - H[i][k] = H[i][k] - p; - H[i][k+1] = H[i][k+1] - p * q; - } - - // Accumulate transformations - - for (int i = low; i <= high; i++) { - p = x * V[i][k] + y * V[i][k+1]; - if (notlast) { - p = p + z * V[i][k+2]; - V[i][k+2] = V[i][k+2] - p * r; - } - V[i][k] = V[i][k] - p; - V[i][k+1] = V[i][k+1] - p * q; - } - } // (s != 0) - } // k loop - } // check convergence - } // while (n >= low) - //if(totIter>15) std::cout<<"!!!!iter "<<totIter<<"\n"; - - // Backsubstitute to find vectors of upper triangular form - - if (norm == 0.0) { - return; - } - - for (n = nn-1; n >= 0; n--) { - p = d[n]; - q = e[n]; - - // Real vector - - if (q == 0) { - int l = n; - H[n][n] = 1.0; - for (int i = n-1; i >= 0; i--) { - w = H[i][i] - p; - r = 0.0; - for (int j = l; j <= n; j++) { - r = r + H[i][j] * H[j][n]; - } - if (e[i] < 0.0) { - z = w; - s = r; - } else { - l = i; - if (e[i] == 0.0) { - if (w != 0.0) { - H[i][n] = -r / w; - } else { - H[i][n] = -r / (eps * norm); - } - - // Solve real equations - - } else { - x = H[i][i+1]; - y = H[i+1][i]; - q = (d[i] - p) * (d[i] - p) + e[i] * e[i]; - t = (x * s - z * r) / q; - H[i][n] = t; - if (fabs(x) > fabs(z)) { - H[i+1][n] = (-r - w * t) / x; - } else { - H[i+1][n] = (-s - y * t) / z; - } - } - - // Overflow control - - t = fabs(H[i][n]); - if ((eps * t) * t > 1) { - for (int j = i; j <= n; j++) { - H[j][n] = H[j][n] / t; - } - } - } - } - - // Complex vector - - } else if (q < 0) { - int l = n-1; - - // Last vector component imaginary so matrix is triangular - - if (fabs(H[n][n-1]) > fabs(H[n-1][n])) { - H[n-1][n-1] = q / H[n][n-1]; - H[n-1][n] = -(H[n][n] - p) / H[n][n-1]; - } else { - cdiv(0.0,-H[n-1][n],H[n-1][n-1]-p,q); - H[n-1][n-1] = cdivr; - H[n-1][n] = cdivi; - } - H[n][n-1] = 0.0; - H[n][n] = 1.0; - for (int i = n-2; i >= 0; i--) { - Real ra,sa,vr,vi; - ra = 0.0; - sa = 0.0; - for (int j = l; j <= n; j++) { - ra = ra + H[i][j] * H[j][n-1]; - sa = sa + H[i][j] * H[j][n]; - } - w = H[i][i] - p; - - if (e[i] < 0.0) { - z = w; - r = ra; - s = sa; - } else { - l = i; - if (e[i] == 0) { - cdiv(-ra,-sa,w,q); - H[i][n-1] = cdivr; - H[i][n] = cdivi; - } else { - - // Solve complex equations - - x = H[i][i+1]; - y = H[i+1][i]; - vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q; - vi = (d[i] - p) * 2.0 * q; - if ((vr == 0.0) && (vi == 0.0)) { - vr = eps * norm * (fabs(w) + fabs(q) + - fabs(x) + fabs(y) + fabs(z)); - } - cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi); - H[i][n-1] = cdivr; - H[i][n] = cdivi; - if (fabs(x) > (fabs(z) + fabs(q))) { - H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x; - H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x; - } else { - cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q); - H[i+1][n-1] = cdivr; - H[i+1][n] = cdivi; - } - } - - // Overflow control - - t = max(fabs(H[i][n-1]),fabs(H[i][n])); - if ((eps * t) * t > 1) { - for (int j = i; j <= n; j++) { - H[j][n-1] = H[j][n-1] / t; - H[j][n] = H[j][n] / t; - } - } - } - } - } - } - - // Vectors of isolated roots - - for (int i = 0; i < nn; i++) { - if (i < low || i > high) { - for (int j = i; j < nn; j++) { - V[i][j] = H[i][j]; - } - } - } - - // Back transformation to get eigenvectors of original matrix - - for (int j = nn-1; j >= low; j--) { - for (int i = low; i <= high; i++) { - z = 0.0; - for (int k = low; k <= min(j,high); k++) { - z = z + V[i][k] * H[k][j]; - } - V[i][j] = z; - } - } - } - -public: - - - /** Check for symmetry, then construct the eigenvalue decomposition - @param A Square real (non-complex) matrix - */ - - Eigenvalue(const TNT::Array2D<Real> &A) { - n = A.dim2(); - V = Array2D<Real>(n,n); - d = Array1D<Real>(n); - e = Array1D<Real>(n); - - issymmetric = 1; - for (int j = 0; (j < n) && issymmetric; j++) { - for (int i = 0; (i < n) && issymmetric; i++) { - issymmetric = (A[i][j] == A[j][i]); - } - } - - if (issymmetric) { - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - V[i][j] = A[i][j]; - } - } - - // Tridiagonalize. - tred2(); - - // Diagonalize. - tql2(); - - } else { - H = TNT::Array2D<Real>(n,n); - ort = TNT::Array1D<Real>(n); - - for (int j = 0; j < n; j++) { - for (int i = 0; i < n; i++) { - H[i][j] = A[i][j]; - } - } - - // Reduce to Hessenberg form. - orthes(); - - // Reduce Hessenberg to real Schur form. - hqr2(); - } - } - - - /** Return the eigenvector matrix - @return V - */ - - void getV (TNT::Array2D<Real> &V_) { - V_ = V; - return; - } - - /** Return the real parts of the eigenvalues - @return real(diag(D)) - */ - - void getRealEigenvalues (TNT::Array1D<Real> &d_) { - d_ = d; - return ; - } - - /** Return the imaginary parts of the eigenvalues - in parameter e_. - - @pararm e_: new matrix with imaginary parts of the eigenvalues. - */ - void getImagEigenvalues (TNT::Array1D<Real> &e_) { - e_ = e; - return; - } - - -/** - Computes the block diagonal eigenvalue matrix. - If the original matrix A is not symmetric, then the eigenvalue - matrix D is block diagonal with the real eigenvalues in 1-by-1 - blocks and any complex eigenvalues, - a + i*b, in 2-by-2 blocks, [a, b; -b, a]. That is, if the complex - eigenvalues look like -<pre> - - u + iv . . . . . - . u - iv . . . . - . . a + ib . . . - . . . a - ib . . - . . . . x . - . . . . . y -</pre> - then D looks like -<pre> - - u v . . . . - -v u . . . . - . . a b . . - . . -b a . . - . . . . x . - . . . . . y -</pre> - This keeps V a real matrix in both symmetric and non-symmetric - cases, and A*V = V*D. - - @param D: upon return, the matrix is filled with the block diagonal - eigenvalue matrix. - -*/ - void getD (TNT::Array2D<Real> &D) { - D = Array2D<Real>(n,n); - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - D[i][j] = 0.0; - } - D[i][i] = d[i]; - if (e[i] > 0) { - D[i][i+1] = e[i]; - } else if (e[i] < 0) { - D[i][i-1] = e[i]; - } - } - } -}; - -} //namespace JAMA - - -#endif -// JAMA_EIG_H diff --git a/intern/smoke/intern/tnt/jama_lu.h b/intern/smoke/intern/tnt/jama_lu.h deleted file mode 100644 index 7855c060eca..00000000000 --- a/intern/smoke/intern/tnt/jama_lu.h +++ /dev/null @@ -1,322 +0,0 @@ -/** \file - * \ingroup smoke - */ -#ifndef JAMA_LU_H -#define JAMA_LU_H - -#include "tnt.h" -#include <algorithm> -//for min(), max() below - -using namespace TNT; -using namespace std; - -namespace JAMA -{ - - /** LU Decomposition. - <P> - For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n - unit lower triangular matrix L, an n-by-n upper triangular matrix U, - and a permutation vector piv of length m so that A(piv,:) = L*U. - If m < n, then L is m-by-m and U is m-by-n. - <P> - The LU decompostion with pivoting always exists, even if the matrix is - singular, so the constructor will never fail. The primary use of the - LU decomposition is in the solution of square systems of simultaneous - linear equations. This will fail if isNonsingular() returns false. - */ -template <class Real> -class LU -{ - - - - /* Array for internal storage of decomposition. */ - Array2D<Real> LU_; - int m, n, pivsign; - Array1D<int> piv; - - - Array2D<Real> permute_copy(const Array2D<Real> &A, - const Array1D<int> &piv, int j0, int j1) - { - int piv_length = piv.dim(); - - Array2D<Real> X(piv_length, j1-j0+1); - - - for (int i = 0; i < piv_length; i++) - for (int j = j0; j <= j1; j++) - X[i][j-j0] = A[piv[i]][j]; - - return X; - } - - Array1D<Real> permute_copy(const Array1D<Real> &A, - const Array1D<int> &piv) - { - int piv_length = piv.dim(); - if (piv_length != A.dim()) - return Array1D<Real>(); - - Array1D<Real> x(piv_length); - - - for (int i = 0; i < piv_length; i++) - x[i] = A[piv[i]]; - - return x; - } - - - public : - - /** LU Decomposition - @param A Rectangular matrix - @return LU Decomposition object to access L, U and piv. - */ - - LU (const Array2D<Real> &A) : LU_(A.copy()), m(A.dim1()), n(A.dim2()), - piv(A.dim1()) - - { - - // Use a "left-looking", dot-product, Crout/Doolittle algorithm. - - - for (int i = 0; i < m; i++) { - piv[i] = i; - } - pivsign = 1; - Real *LUrowi = 0;; - Array1D<Real> LUcolj(m); - - // Outer loop. - - for (int j = 0; j < n; j++) { - - // Make a copy of the j-th column to localize references. - - for (int i = 0; i < m; i++) { - LUcolj[i] = LU_[i][j]; - } - - // Apply previous transformations. - - for (int i = 0; i < m; i++) { - LUrowi = LU_[i]; - - // Most of the time is spent in the following dot product. - - int kmax = min(i,j); - double s = 0.0; - for (int k = 0; k < kmax; k++) { - s += LUrowi[k]*LUcolj[k]; - } - - LUrowi[j] = LUcolj[i] -= s; - } - - // Find pivot and exchange if necessary. - - int p = j; - for (int i = j+1; i < m; i++) { - if (abs(LUcolj[i]) > abs(LUcolj[p])) { - p = i; - } - } - if (p != j) { - int k=0; - for (k = 0; k < n; k++) { - double t = LU_[p][k]; - LU_[p][k] = LU_[j][k]; - LU_[j][k] = t; - } - k = piv[p]; - piv[p] = piv[j]; - piv[j] = k; - pivsign = -pivsign; - } - - // Compute multipliers. - - if ((j < m) && (LU_[j][j] != 0.0)) { - for (int i = j+1; i < m; i++) { - LU_[i][j] /= LU_[j][j]; - } - } - } - } - - - /** Is the matrix nonsingular? - @return 1 (true) if upper triangular factor U (and hence A) - is nonsingular, 0 otherwise. - */ - - int isNonsingular () { - for (int j = 0; j < n; j++) { - if (LU_[j][j] == 0) - return 0; - } - return 1; - } - - /** Return lower triangular factor - @return L - */ - - Array2D<Real> getL () { - Array2D<Real> L_(m,n); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (i > j) { - L_[i][j] = LU_[i][j]; - } else if (i == j) { - L_[i][j] = 1.0; - } else { - L_[i][j] = 0.0; - } - } - } - return L_; - } - - /** Return upper triangular factor - @return U portion of LU factorization. - */ - - Array2D<Real> getU () { - Array2D<Real> U_(n,n); - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (i <= j) { - U_[i][j] = LU_[i][j]; - } else { - U_[i][j] = 0.0; - } - } - } - return U_; - } - - /** Return pivot permutation vector - @return piv - */ - - Array1D<int> getPivot () { - return piv; - } - - - /** Compute determinant using LU factors. - @return determinant of A, or 0 if A is not square. - */ - - Real det () { - if (m != n) { - return Real(0); - } - Real d = Real(pivsign); - for (int j = 0; j < n; j++) { - d *= LU_[j][j]; - } - return d; - } - - /** Solve A*X = B - @param B A Matrix with as many rows as A and any number of columns. - @return X so that L*U*X = B(piv,:), if B is nonconformant, returns - 0x0 (null) array. - */ - - Array2D<Real> solve (const Array2D<Real> &B) - { - - /* Dimensions: A is mxn, X is nxk, B is mxk */ - - if (B.dim1() != m) { - return Array2D<Real>(0,0); - } - if (!isNonsingular()) { - return Array2D<Real>(0,0); - } - - // Copy right hand side with pivoting - int nx = B.dim2(); - - - Array2D<Real> X = permute_copy(B, piv, 0, nx-1); - - // Solve L*Y = B(piv,:) - for (int k = 0; k < n; k++) { - for (int i = k+1; i < n; i++) { - for (int j = 0; j < nx; j++) { - X[i][j] -= X[k][j]*LU_[i][k]; - } - } - } - // Solve U*X = Y; - for (int k = n-1; k >= 0; k--) { - for (int j = 0; j < nx; j++) { - X[k][j] /= LU_[k][k]; - } - for (int i = 0; i < k; i++) { - for (int j = 0; j < nx; j++) { - X[i][j] -= X[k][j]*LU_[i][k]; - } - } - } - return X; - } - - - /** Solve A*x = b, where x and b are vectors of length equal - to the number of rows in A. - - @param b a vector (Array1D> of length equal to the first dimension - of A. - @return x a vector (Array1D> so that L*U*x = b(piv), if B is nonconformant, - returns 0x0 (null) array. - */ - - Array1D<Real> solve (const Array1D<Real> &b) - { - - /* Dimensions: A is mxn, X is nxk, B is mxk */ - - if (b.dim1() != m) { - return Array1D<Real>(); - } - if (!isNonsingular()) { - return Array1D<Real>(); - } - - - Array1D<Real> x = permute_copy(b, piv); - - // Solve L*Y = B(piv) - for (int k = 0; k < n; k++) { - for (int i = k+1; i < n; i++) { - x[i] -= x[k]*LU_[i][k]; - } - } - - // Solve U*X = Y; - for (int k = n-1; k >= 0; k--) { - x[k] /= LU_[k][k]; - for (int i = 0; i < k; i++) - x[i] -= x[k]*LU_[i][k]; - } - - - return x; - } - -}; /* class LU */ - -} /* namespace JAMA */ - -#endif -/* JAMA_LU_H */ diff --git a/intern/smoke/intern/tnt/tnt.h b/intern/smoke/intern/tnt/tnt.h deleted file mode 100644 index ef9de784bb3..00000000000 --- a/intern/smoke/intern/tnt/tnt.h +++ /dev/null @@ -1,67 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT): Linear Algebra Module -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -#ifndef TNT_H -#define TNT_H - - - -//--------------------------------------------------------------------- -// Define this macro if you want TNT to track some of the out-of-bounds -// indexing. This can encur a small run-time overhead, but is recommended -// while developing code. It can be turned off for production runs. -// -// #define TNT_BOUNDS_CHECK -//--------------------------------------------------------------------- -// - -//#define TNT_BOUNDS_CHECK - - - -#include "tnt_version.h" -#include "tnt_math_utils.h" -#include "tnt_array1d.h" -#include "tnt_array2d.h" -#include "tnt_array3d.h" -#include "tnt_array1d_utils.h" -#include "tnt_array2d_utils.h" -#include "tnt_array3d_utils.h" - -#include "tnt_fortran_array1d.h" -#include "tnt_fortran_array2d.h" -#include "tnt_fortran_array3d.h" -#include "tnt_fortran_array1d_utils.h" -#include "tnt_fortran_array2d_utils.h" -#include "tnt_fortran_array3d_utils.h" - -#include "tnt_sparse_matrix_csr.h" - -#include "tnt_stopwatch.h" -#include "tnt_subscript.h" -#include "tnt_vec.h" -#include "tnt_cmat.h" - - -#endif -// TNT_H diff --git a/intern/smoke/intern/tnt/tnt_array1d.h b/intern/smoke/intern/tnt/tnt_array1d.h deleted file mode 100644 index 999cbd08d24..00000000000 --- a/intern/smoke/intern/tnt/tnt_array1d.h +++ /dev/null @@ -1,281 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_ARRAY1D_H -#define TNT_ARRAY1D_H - -//#include <cstdlib> -#include <iostream> - -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif - - -#include "tnt_i_refvec.h" - -namespace TNT -{ - -template <class T> -class Array1D -{ - - private: - - /* ... */ - i_refvec<T> v_; - int n_; - T* data_; /* this normally points to v_.begin(), but - * could also point to a portion (subvector) - * of v_. - */ - - void copy_(T* p, const T* q, int len) const; - void set_(T* begin, T* end, const T& val); - - - public: - - typedef T value_type; - - - Array1D(); - explicit Array1D(int n); - Array1D(int n, const T &a); - Array1D(int n, T *a); - inline Array1D(const Array1D &A); - inline operator T*(); - inline operator const T*(); - inline Array1D & operator=(const T &a); - inline Array1D & operator=(const Array1D &A); - inline Array1D & ref(const Array1D &A); - Array1D copy() const; - Array1D & inject(const Array1D & A); - inline T& operator[](int i); - inline const T& operator[](int i) const; - inline int dim1() const; - inline int dim() const; - ~Array1D(); - - - /* ... extended interface ... */ - - inline int ref_count() const; - inline Array1D<T> subarray(int i0, int i1); - -}; - - - - -template <class T> -Array1D<T>::Array1D() : v_(), n_(0), data_(0) {} - -template <class T> -Array1D<T>::Array1D(const Array1D<T> &A) : v_(A.v_), n_(A.n_), - data_(A.data_) -{ -#ifdef TNT_DEBUG - std::cout << "Created Array1D(const Array1D<T> &A) \n"; -#endif - -} - - -template <class T> -Array1D<T>::Array1D(int n) : v_(n), n_(n), data_(v_.begin()) -{ -#ifdef TNT_DEBUG - std::cout << "Created Array1D(int n) \n"; -#endif -} - -template <class T> -Array1D<T>::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin()) -{ -#ifdef TNT_DEBUG - std::cout << "Created Array1D(int n, const T& val) \n"; -#endif - set_(data_, data_+ n, val); - -} - -template <class T> -Array1D<T>::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin()) -{ -#ifdef TNT_DEBUG - std::cout << "Created Array1D(int n, T* a) \n"; -#endif -} - -template <class T> -inline Array1D<T>::operator T*() -{ - return &(v_[0]); -} - - -template <class T> -inline Array1D<T>::operator const T*() -{ - return &(v_[0]); -} - - - -template <class T> -inline T& Array1D<T>::operator[](int i) -{ -#ifdef TNT_BOUNDS_CHECK - assert(i>= 0); - assert(i < n_); -#endif - return data_[i]; -} - -template <class T> -inline const T& Array1D<T>::operator[](int i) const -{ -#ifdef TNT_BOUNDS_CHECK - assert(i>= 0); - assert(i < n_); -#endif - return data_[i]; -} - - - - -template <class T> -Array1D<T> & Array1D<T>::operator=(const T &a) -{ - set_(data_, data_+n_, a); - return *this; -} - -template <class T> -Array1D<T> Array1D<T>::copy() const -{ - Array1D A( n_); - copy_(A.data_, data_, n_); - - return A; -} - - -template <class T> -Array1D<T> & Array1D<T>::inject(const Array1D &A) -{ - if (A.n_ == n_) - copy_(data_, A.data_, n_); - - return *this; -} - - - - - -template <class T> -Array1D<T> & Array1D<T>::ref(const Array1D<T> &A) -{ - if (this != &A) - { - v_ = A.v_; /* operator= handles the reference counting. */ - n_ = A.n_; - data_ = A.data_; - - } - return *this; -} - -template <class T> -Array1D<T> & Array1D<T>::operator=(const Array1D<T> &A) -{ - return ref(A); -} - -template <class T> -inline int Array1D<T>::dim1() const { return n_; } - -template <class T> -inline int Array1D<T>::dim() const { return n_; } - -template <class T> -Array1D<T>::~Array1D() {} - - -/* ............................ exented interface ......................*/ - -template <class T> -inline int Array1D<T>::ref_count() const -{ - return v_.ref_count(); -} - -template <class T> -inline Array1D<T> Array1D<T>::subarray(int i0, int i1) -{ - if ((i0 > 0) && (i1 < n_) || (i0 <= i1)) - { - Array1D<T> X(*this); /* create a new instance of this array. */ - X.n_ = i1-i0+1; - X.data_ += i0; - - return X; - } - else - { - return Array1D<T>(); - } -} - - -/* private internal functions */ - - -template <class T> -void Array1D<T>::set_(T* begin, T* end, const T& a) -{ - for (T* p=begin; p<end; p++) - *p = a; - -} - -template <class T> -void Array1D<T>::copy_(T* p, const T* q, int len) const -{ - T *end = p + len; - while (p<end ) - *p++ = *q++; - -} - - -} /* namespace TNT */ - -#endif -/* TNT_ARRAY1D_H */ - diff --git a/intern/smoke/intern/tnt/tnt_array1d_utils.h b/intern/smoke/intern/tnt/tnt_array1d_utils.h deleted file mode 100644 index 4ff0c803325..00000000000 --- a/intern/smoke/intern/tnt/tnt_array1d_utils.h +++ /dev/null @@ -1,233 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - -#ifndef TNT_ARRAY1D_UTILS_H -#define TNT_ARRAY1D_UTILS_H - -#include <cstdlib> -#include <cassert> - -namespace TNT -{ - - -template <class T> -std::ostream& operator<<(std::ostream &s, const Array1D<T> &A) -{ - int N=A.dim1(); - -#ifdef TNT_DEBUG - s << "addr: " << (void *) &A[0] << "\n"; -#endif - s << N << "\n"; - for (int j=0; j<N; j++) - { - s << A[j] << "\n"; - } - s << "\n"; - - return s; -} - -template <class T> -std::istream& operator>>(std::istream &s, Array1D<T> &A) -{ - int N; - s >> N; - - Array1D<T> B(N); - for (int i=0; i<N; i++) - s >> B[i]; - A = B; - return s; -} - - - -template <class T> -Array1D<T> operator+(const Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Array1D<T>(); - - else - { - Array1D<T> C(n); - - for (int i=0; i<n; i++) - { - C[i] = A[i] + B[i]; - } - return C; - } -} - - - -template <class T> -Array1D<T> operator-(const Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Array1D<T>(); - - else - { - Array1D<T> C(n); - - for (int i=0; i<n; i++) - { - C[i] = A[i] - B[i]; - } - return C; - } -} - - -template <class T> -Array1D<T> operator*(const Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Array1D<T>(); - - else - { - Array1D<T> C(n); - - for (int i=0; i<n; i++) - { - C[i] = A[i] * B[i]; - } - return C; - } -} - - -template <class T> -Array1D<T> operator/(const Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Array1D<T>(); - - else - { - Array1D<T> C(n); - - for (int i=0; i<n; i++) - { - C[i] = A[i] / B[i]; - } - return C; - } -} - - - - - - - - - -template <class T> -Array1D<T>& operator+=(Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=0; i<n; i++) - { - A[i] += B[i]; - } - } - return A; -} - - - - -template <class T> -Array1D<T>& operator-=(Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=0; i<n; i++) - { - A[i] -= B[i]; - } - } - return A; -} - - - -template <class T> -Array1D<T>& operator*=(Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=0; i<n; i++) - { - A[i] *= B[i]; - } - } - return A; -} - - - - -template <class T> -Array1D<T>& operator/=(Array1D<T> &A, const Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=0; i<n; i++) - { - A[i] /= B[i]; - } - } - return A; -} - - - - - - -} // namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_array2d.h b/intern/smoke/intern/tnt/tnt_array2d.h deleted file mode 100644 index e96beab9367..00000000000 --- a/intern/smoke/intern/tnt/tnt_array2d.h +++ /dev/null @@ -1,318 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_ARRAY2D_H -#define TNT_ARRAY2D_H - -#include <cstdlib> -#include <iostream> -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif - -#include "tnt_array1d.h" - -namespace TNT -{ - -template <class T> -class Array2D -{ - - - private: - - - - Array1D<T> data_; - Array1D<T*> v_; - int m_; - int n_; - - public: - - typedef T value_type; - Array2D(); - Array2D(int m, int n); - Array2D(int m, int n, T *a); - Array2D(int m, int n, const T &a); - inline Array2D(const Array2D &A); - inline operator T**(); - inline operator const T**(); - inline Array2D & operator=(const T &a); - inline Array2D & operator=(const Array2D &A); - inline Array2D & ref(const Array2D &A); - Array2D copy() const; - Array2D & inject(const Array2D & A); - inline T* operator[](int i); - inline const T* operator[](int i) const; - inline int dim1() const; - inline int dim2() const; - ~Array2D(); - - /* extended interface (not part of the standard) */ - - - inline int ref_count(); - inline int ref_count_data(); - inline int ref_count_dim1(); - Array2D subarray(int i0, int i1, int j0, int j1); - -}; - - -template <class T> -Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {} - -template <class T> -Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_), - m_(A.m_), n_(A.n_) {} - - - - -template <class T> -Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n) -{ - if (m>0 && n>0) - { - T* p = &(data_[0]); - for (int i=0; i<m; i++) - { - v_[i] = p; - p += n; - } - } -} - - - -template <class T> -Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m), - m_(m), n_(n) -{ - if (m>0 && n>0) - { - data_ = val; - T* p = &(data_[0]); - for (int i=0; i<m; i++) - { - v_[i] = p; - p += n; - } - } -} - -template <class T> -Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n) -{ - if (m>0 && n>0) - { - T* p = &(data_[0]); - - for (int i=0; i<m; i++) - { - v_[i] = p; - p += n; - } - } -} - - -template <class T> -inline T* Array2D<T>::operator[](int i) -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 0); - assert(i < m_); -#endif - -return v_[i]; - -} - - -template <class T> -inline const T* Array2D<T>::operator[](int i) const -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 0); - assert(i < m_); -#endif - -return v_[i]; - -} - -template <class T> -Array2D<T> & Array2D<T>::operator=(const T &a) -{ - /* non-optimzied, but will work with subarrays in future verions */ - - for (int i=0; i<m_; i++) - for (int j=0; j<n_; j++) - v_[i][j] = a; - return *this; -} - - - - -template <class T> -Array2D<T> Array2D<T>::copy() const -{ - Array2D A(m_, n_); - - for (int i=0; i<m_; i++) - for (int j=0; j<n_; j++) - A[i][j] = v_[i][j]; - - - return A; -} - - -template <class T> -Array2D<T> & Array2D<T>::inject(const Array2D &A) -{ - if (A.m_ == m_ && A.n_ == n_) - { - for (int i=0; i<m_; i++) - for (int j=0; j<n_; j++) - v_[i][j] = A[i][j]; - } - return *this; -} - - - - -template <class T> -Array2D<T> & Array2D<T>::ref(const Array2D<T> &A) -{ - if (this != &A) - { - v_ = A.v_; - data_ = A.data_; - m_ = A.m_; - n_ = A.n_; - - } - return *this; -} - - - -template <class T> -Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A) -{ - return ref(A); -} - -template <class T> -inline int Array2D<T>::dim1() const { return m_; } - -template <class T> -inline int Array2D<T>::dim2() const { return n_; } - - -template <class T> -Array2D<T>::~Array2D() {} - - - - -template <class T> -inline Array2D<T>::operator T**() -{ - return &(v_[0]); -} -template <class T> -inline Array2D<T>::operator const T**() -{ - return &(v_[0]); -} - -/* ............... extended interface ............... */ -/** - Create a new view to a subarray defined by the boundaries - [i0][i0] and [i1][j1]. The size of the subarray is - (i1-i0) by (j1-j0). If either of these lengths are zero - or negative, the subarray view is null. - -*/ -template <class T> -Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1) -{ - Array2D<T> A; - int m = i1-i0+1; - int n = j1-j0+1; - - /* if either length is zero or negative, this is an invalide - subarray. return a null view. - */ - if (m<1 || n<1) - return A; - - A.data_ = data_; - A.m_ = m; - A.n_ = n; - A.v_ = Array1D<T*>(m); - T* p = &(data_[0]) + i0 * n_ + j0; - for (int i=0; i<m; i++) - { - A.v_[i] = p + i*n_; - - } - return A; -} - -template <class T> -inline int Array2D<T>::ref_count() -{ - return ref_count_data(); -} - - - -template <class T> -inline int Array2D<T>::ref_count_data() -{ - return data_.ref_count(); -} - -template <class T> -inline int Array2D<T>::ref_count_dim1() -{ - return v_.ref_count(); -} - - - - -} /* namespace TNT */ - -#endif -/* TNT_ARRAY2D_H */ - diff --git a/intern/smoke/intern/tnt/tnt_array2d_utils.h b/intern/smoke/intern/tnt/tnt_array2d_utils.h deleted file mode 100644 index 63f98073506..00000000000 --- a/intern/smoke/intern/tnt/tnt_array2d_utils.h +++ /dev/null @@ -1,290 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -#ifndef TNT_ARRAY2D_UTILS_H -#define TNT_ARRAY2D_UTILS_H - -#include <cstdlib> -#include <cassert> - -namespace TNT -{ - - -template <class T> -std::ostream& operator<<(std::ostream &s, const Array2D<T> &A) -{ - int M=A.dim1(); - int N=A.dim2(); - - s << M << " " << N << "\n"; - - for (int i=0; i<M; i++) - { - for (int j=0; j<N; j++) - { - s << A[i][j] << " "; - } - s << "\n"; - } - - - return s; -} - -template <class T> -std::istream& operator>>(std::istream &s, Array2D<T> &A) -{ - - int M, N; - - s >> M >> N; - - Array2D<T> B(M,N); - - for (int i=0; i<M; i++) - for (int j=0; j<N; j++) - { - s >> B[i][j]; - } - - A = B; - return s; -} - - -template <class T> -Array2D<T> operator+(const Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Array2D<T>(); - - else - { - Array2D<T> C(m,n); - - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - C[i][j] = A[i][j] + B[i][j]; - } - return C; - } -} - -template <class T> -Array2D<T> operator-(const Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Array2D<T>(); - - else - { - Array2D<T> C(m,n); - - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - C[i][j] = A[i][j] - B[i][j]; - } - return C; - } -} - - -template <class T> -Array2D<T> operator*(const Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Array2D<T>(); - - else - { - Array2D<T> C(m,n); - - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - C[i][j] = A[i][j] * B[i][j]; - } - return C; - } -} - - - - -template <class T> -Array2D<T> operator/(const Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Array2D<T>(); - - else - { - Array2D<T> C(m,n); - - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - C[i][j] = A[i][j] / B[i][j]; - } - return C; - } -} - - - - - -template <class T> -Array2D<T>& operator+=(Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - A[i][j] += B[i][j]; - } - } - return A; -} - - - -template <class T> -Array2D<T>& operator-=(Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - A[i][j] -= B[i][j]; - } - } - return A; -} - - - -template <class T> -Array2D<T>& operator*=(Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - A[i][j] *= B[i][j]; - } - } - return A; -} - - - - - -template <class T> -Array2D<T>& operator/=(Array2D<T> &A, const Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=0; i<m; i++) - { - for (int j=0; j<n; j++) - A[i][j] /= B[i][j]; - } - } - return A; -} - -/** - Matrix Multiply: compute C = A*B, where C[i][j] - is the dot-product of row i of A and column j of B. - - - @param A an (m x n) array - @param B an (n x k) array - @return the (m x k) array A*B, or a null array (0x0) - if the matrices are non-conformant (i.e. the number - of columns of A are different than the number of rows of B.) - - -*/ -template <class T> -Array2D<T> matmult(const Array2D<T> &A, const Array2D<T> &B) -{ - if (A.dim2() != B.dim1()) - return Array2D<T>(); - - int M = A.dim1(); - int N = A.dim2(); - int K = B.dim2(); - - Array2D<T> C(M,K); - - for (int i=0; i<M; i++) - for (int j=0; j<K; j++) - { - T sum = 0; - - for (int k=0; k<N; k++) - sum += A[i][k] * B [k][j]; - - C[i][j] = sum; - } - - return C; - -} - -} // namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_array3d.h b/intern/smoke/intern/tnt/tnt_array3d.h deleted file mode 100644 index e62358ea614..00000000000 --- a/intern/smoke/intern/tnt/tnt_array3d.h +++ /dev/null @@ -1,299 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_ARRAY3D_H -#define TNT_ARRAY3D_H - -#include <cstdlib> -#include <iostream> -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif - -#include "tnt_array1d.h" -#include "tnt_array2d.h" - -namespace TNT -{ - -template <class T> -class Array3D -{ - - - private: - Array1D<T> data_; - Array2D<T*> v_; - int m_; - int n_; - int g_; - - - public: - - typedef T value_type; - - Array3D(); - Array3D(int m, int n, int g); - Array3D(int m, int n, int g, T val); - Array3D(int m, int n, int g, T *a); - - inline operator T***(); - inline operator const T***(); - inline Array3D(const Array3D &A); - inline Array3D & operator=(const T &a); - inline Array3D & operator=(const Array3D &A); - inline Array3D & ref(const Array3D &A); - Array3D copy() const; - Array3D & inject(const Array3D & A); - - inline T** operator[](int i); - inline const T* const * operator[](int i) const; - inline int dim1() const; - inline int dim2() const; - inline int dim3() const; - ~Array3D(); - - /* extended interface */ - - inline int ref_count(){ return data_.ref_count(); } - Array3D subarray(int i0, int i1, int j0, int j1, - int k0, int k1); -}; - -template <class T> -Array3D<T>::Array3D() : data_(), v_(), m_(0), n_(0) {} - -template <class T> -Array3D<T>::Array3D(const Array3D<T> &A) : data_(A.data_), - v_(A.v_), m_(A.m_), n_(A.n_), g_(A.g_) -{ -} - - - -template <class T> -Array3D<T>::Array3D(int m, int n, int g) : data_(m*n*g), v_(m,n), - m_(m), n_(n), g_(g) -{ - - if (m>0 && n>0 && g>0) - { - T* p = & (data_[0]); - int ng = n_*g_; - - for (int i=0; i<m_; i++) - { - T* ping = p+ i*ng; - for (int j=0; j<n; j++) - v_[i][j] = ping + j*g_; - } - } -} - - - -template <class T> -Array3D<T>::Array3D(int m, int n, int g, T val) : data_(m*n*g, val), - v_(m,n), m_(m), n_(n), g_(g) -{ - if (m>0 && n>0 && g>0) - { - - T* p = & (data_[0]); - int ng = n_*g_; - - for (int i=0; i<m_; i++) - { - T* ping = p+ i*ng; - for (int j=0; j<n; j++) - v_[i][j] = ping + j*g_; - } - } -} - - - -template <class T> -Array3D<T>::Array3D(int m, int n, int g, T* a) : - data_(m*n*g, a), v_(m,n), m_(m), n_(n), g_(g) -{ - - if (m>0 && n>0 && g>0) - { - T* p = & (data_[0]); - int ng = n_*g_; - - for (int i=0; i<m_; i++) - { - T* ping = p+ i*ng; - for (int j=0; j<n; j++) - v_[i][j] = ping + j*g_; - } - } -} - - - -template <class T> -inline T** Array3D<T>::operator[](int i) -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 0); - assert(i < m_); -#endif - -return v_[i]; - -} - -template <class T> -inline const T* const * Array3D<T>::operator[](int i) const -{ return v_[i]; } - -template <class T> -Array3D<T> & Array3D<T>::operator=(const T &a) -{ - for (int i=0; i<m_; i++) - for (int j=0; j<n_; j++) - for (int k=0; k<g_; k++) - v_[i][j][k] = a; - - return *this; -} - -template <class T> -Array3D<T> Array3D<T>::copy() const -{ - Array3D A(m_, n_, g_); - for (int i=0; i<m_; i++) - for (int j=0; j<n_; j++) - for (int k=0; k<g_; k++) - A.v_[i][j][k] = v_[i][j][k]; - - return A; -} - - -template <class T> -Array3D<T> & Array3D<T>::inject(const Array3D &A) -{ - if (A.m_ == m_ && A.n_ == n_ && A.g_ == g_) - - for (int i=0; i<m_; i++) - for (int j=0; j<n_; j++) - for (int k=0; k<g_; k++) - v_[i][j][k] = A.v_[i][j][k]; - - return *this; -} - - - -template <class T> -Array3D<T> & Array3D<T>::ref(const Array3D<T> &A) -{ - if (this != &A) - { - m_ = A.m_; - n_ = A.n_; - g_ = A.g_; - v_ = A.v_; - data_ = A.data_; - } - return *this; -} - -template <class T> -Array3D<T> & Array3D<T>::operator=(const Array3D<T> &A) -{ - return ref(A); -} - - -template <class T> -inline int Array3D<T>::dim1() const { return m_; } - -template <class T> -inline int Array3D<T>::dim2() const { return n_; } - -template <class T> -inline int Array3D<T>::dim3() const { return g_; } - - - -template <class T> -Array3D<T>::~Array3D() {} - -template <class T> -inline Array3D<T>::operator T***() -{ - return v_; -} - - -template <class T> -inline Array3D<T>::operator const T***() -{ - return v_; -} - -/* extended interface */ -template <class T> -Array3D<T> Array3D<T>::subarray(int i0, int i1, int j0, - int j1, int k0, int k1) -{ - - /* check that ranges are valid. */ - if (!( 0 <= i0 && i0 <= i1 && i1 < m_ && - 0 <= j0 && j0 <= j1 && j1 < n_ && - 0 <= k0 && k0 <= k1 && k1 < g_)) - return Array3D<T>(); /* null array */ - - - Array3D<T> A; - A.data_ = data_; - A.m_ = i1-i0+1; - A.n_ = j1-j0+1; - A.g_ = k1-k0+1; - A.v_ = Array2D<T*>(A.m_,A.n_); - T* p = &(data_[0]) + i0*n_*g_ + j0*g_ + k0; - - for (int i=0; i<A.m_; i++) - { - T* ping = p + i*n_*g_; - for (int j=0; j<A.n_; j++) - A.v_[i][j] = ping + j*g_ ; - } - - return A; -} - - - -} /* namespace TNT */ - -#endif -/* TNT_ARRAY3D_H */ - diff --git a/intern/smoke/intern/tnt/tnt_array3d_utils.h b/intern/smoke/intern/tnt/tnt_array3d_utils.h deleted file mode 100644 index cbc02365f9a..00000000000 --- a/intern/smoke/intern/tnt/tnt_array3d_utils.h +++ /dev/null @@ -1,239 +0,0 @@ -/** \file - * \ingroup smoke - */ - - -#ifndef TNT_ARRAY3D_UTILS_H -#define TNT_ARRAY3D_UTILS_H - -#include <cstdlib> -#include <cassert> - -namespace TNT -{ - - -template <class T> -std::ostream& operator<<(std::ostream &s, const Array3D<T> &A) -{ - int M=A.dim1(); - int N=A.dim2(); - int K=A.dim3(); - - s << M << " " << N << " " << K << "\n"; - - for (int i=0; i<M; i++) - { - for (int j=0; j<N; j++) - { - for (int k=0; k<K; k++) - s << A[i][j][k] << " "; - s << "\n"; - } - s << "\n"; - } - - - return s; -} - -template <class T> -std::istream& operator>>(std::istream &s, Array3D<T> &A) -{ - - int M, N, K; - - s >> M >> N >> K; - - Array3D<T> B(M,N,K); - - for (int i=0; i<M; i++) - for (int j=0; j<N; j++) - for (int k=0; k<K; k++) - s >> B[i][j][k]; - - A = B; - return s; -} - - - -template <class T> -Array3D<T> operator+(const Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Array3D<T>(); - - else - { - Array3D<T> C(m,n,p); - - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - C[i][j][k] = A[i][j][k] + B[i][j][k]; - - return C; - } -} - - -template <class T> -Array3D<T> operator-(const Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Array3D<T>(); - - else - { - Array3D<T> C(m,n,p); - - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - C[i][j][k] = A[i][j][k] - B[i][j][k]; - - return C; - } -} - - - - -template <class T> -Array3D<T> operator*(const Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Array3D<T>(); - - else - { - Array3D<T> C(m,n,p); - - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - C[i][j][k] = A[i][j][k] * B[i][j][k]; - - return C; - } -} - - -template <class T> -Array3D<T> operator/(const Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Array3D<T>(); - - else - { - Array3D<T> C(m,n,p); - - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - C[i][j][k] = A[i][j][k] / B[i][j][k]; - - return C; - } -} - - - -template <class T> -Array3D<T>& operator+=(Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - A[i][j][k] += B[i][j][k]; - } - - return A; -} - -template <class T> -Array3D<T>& operator-=(Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - A[i][j][k] -= B[i][j][k]; - } - - return A; -} - -template <class T> -Array3D<T>& operator*=(Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - A[i][j][k] *= B[i][j][k]; - } - - return A; -} - - -template <class T> -Array3D<T>& operator/=(Array3D<T> &A, const Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=0; i<m; i++) - for (int j=0; j<n; j++) - for (int k=0; k<p; k++) - A[i][j][k] /= B[i][j][k]; - } - - return A; -} - - - - - -} // namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_cmat.h b/intern/smoke/intern/tnt/tnt_cmat.h deleted file mode 100644 index 34d5412a9b8..00000000000 --- a/intern/smoke/intern/tnt/tnt_cmat.h +++ /dev/null @@ -1,583 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -// C compatible matrix: row-oriented, 0-based [i][j] and 1-based (i,j) indexing -// - -#ifndef TNT_CMAT_H -#define TNT_CMAT_H - -#include "tnt_subscript.h" -#include "tnt_vec.h" -#include <cstdlib> -#include <cassert> -#include <iostream> -#include <sstream> - -namespace TNT -{ - - -template <class T> -class Matrix -{ - - - public: - - typedef Subscript size_type; - typedef T value_type; - typedef T element_type; - typedef T* pointer; - typedef T* iterator; - typedef T& reference; - typedef const T* const_iterator; - typedef const T& const_reference; - - Subscript lbound() const { return 1;} - - protected: - Subscript m_; - Subscript n_; - Subscript mn_; // total size - T* v_; - T** row_; - T* vm1_ ; // these point to the same data, but are 1-based - T** rowm1_; - - // internal helper function to create the array - // of row pointers - - void initialize(Subscript M, Subscript N) - { - mn_ = M*N; - m_ = M; - n_ = N; - - v_ = new T[mn_]; - row_ = new T*[M]; - rowm1_ = new T*[M]; - - assert(v_ != NULL); - assert(row_ != NULL); - assert(rowm1_ != NULL); - - T* p = v_; - vm1_ = v_ - 1; - for (Subscript i=0; i<M; i++) - { - row_[i] = p; - rowm1_[i] = p-1; - p += N ; - - } - - rowm1_ -- ; // compensate for 1-based offset - } - - void copy(const T* v) - { - Subscript N = m_ * n_; - Subscript i; - -#ifdef TNT_UNROLL_LOOPS - Subscript Nmod4 = N & 3; - Subscript N4 = N - Nmod4; - - for (i=0; i<N4; i+=4) - { - v_[i] = v[i]; - v_[i+1] = v[i+1]; - v_[i+2] = v[i+2]; - v_[i+3] = v[i+3]; - } - - for (i=N4; i< N; i++) - v_[i] = v[i]; -#else - - for (i=0; i< N; i++) - v_[i] = v[i]; -#endif - } - - void set(const T& val) - { - Subscript N = m_ * n_; - Subscript i; - -#ifdef TNT_UNROLL_LOOPS - Subscript Nmod4 = N & 3; - Subscript N4 = N - Nmod4; - - for (i=0; i<N4; i+=4) - { - v_[i] = val; - v_[i+1] = val; - v_[i+2] = val; - v_[i+3] = val; - } - - for (i=N4; i< N; i++) - v_[i] = val; -#else - - for (i=0; i< N; i++) - v_[i] = val; - -#endif - } - - - - void destroy() - { - /* do nothing, if no memory has been previously allocated */ - if (v_ == NULL) return ; - - /* if we are here, then matrix was previously allocated */ - if (v_ != NULL) delete [] (v_); - if (row_ != NULL) delete [] (row_); - - /* return rowm1_ back to original value */ - rowm1_ ++; - if (rowm1_ != NULL ) delete [] (rowm1_); - } - - - public: - - operator T**(){ return row_; } - operator T**() const { return row_; } - - - Subscript size() const { return mn_; } - - // constructors - - Matrix() : m_(0), n_(0), mn_(0), v_(0), row_(0), vm1_(0), rowm1_(0) {}; - - Matrix(const Matrix<T> &A) - { - initialize(A.m_, A.n_); - copy(A.v_); - } - - Matrix(Subscript M, Subscript N, const T& value = T()) - { - initialize(M,N); - set(value); - } - - Matrix(Subscript M, Subscript N, const T* v) - { - initialize(M,N); - copy(v); - } - - Matrix(Subscript M, Subscript N, const char *s) - { - initialize(M,N); - //std::istrstream ins(s); - std::istringstream ins(s); - - Subscript i, j; - - for (i=0; i<M; i++) - for (j=0; j<N; j++) - ins >> row_[i][j]; - } - - // destructor - // - ~Matrix() - { - destroy(); - } - - - // reallocating - // - Matrix<T>& newsize(Subscript M, Subscript N) - { - if (num_rows() == M && num_cols() == N) - return *this; - - destroy(); - initialize(M,N); - - return *this; - } - - - - - // assignments - // - Matrix<T>& operator=(const Matrix<T> &A) - { - if (v_ == A.v_) - return *this; - - if (m_ == A.m_ && n_ == A.n_) // no need to re-alloc - copy(A.v_); - - else - { - destroy(); - initialize(A.m_, A.n_); - copy(A.v_); - } - - return *this; - } - - Matrix<T>& operator=(const T& scalar) - { - set(scalar); - return *this; - } - - - Subscript dim(Subscript d) const - { -#ifdef TNT_BOUNDS_CHECK - assert( d >= 1); - assert( d <= 2); -#endif - return (d==1) ? m_ : ((d==2) ? n_ : 0); - } - - Subscript num_rows() const { return m_; } - Subscript num_cols() const { return n_; } - - - - - inline T* operator[](Subscript i) - { -#ifdef TNT_BOUNDS_CHECK - assert(0<=i); - assert(i < m_) ; -#endif - return row_[i]; - } - - inline const T* operator[](Subscript i) const - { -#ifdef TNT_BOUNDS_CHECK - assert(0<=i); - assert(i < m_) ; -#endif - return row_[i]; - } - - inline reference operator()(Subscript i) - { -#ifdef TNT_BOUNDS_CHECK - assert(1<=i); - assert(i <= mn_) ; -#endif - return vm1_[i]; - } - - inline const_reference operator()(Subscript i) const - { -#ifdef TNT_BOUNDS_CHECK - assert(1<=i); - assert(i <= mn_) ; -#endif - return vm1_[i]; - } - - - - inline reference operator()(Subscript i, Subscript j) - { -#ifdef TNT_BOUNDS_CHECK - assert(1<=i); - assert(i <= m_) ; - assert(1<=j); - assert(j <= n_); -#endif - return rowm1_[i][j]; - } - - - - inline const_reference operator() (Subscript i, Subscript j) const - { -#ifdef TNT_BOUNDS_CHECK - assert(1<=i); - assert(i <= m_) ; - assert(1<=j); - assert(j <= n_); -#endif - return rowm1_[i][j]; - } - - - - -}; - - -/* *************************** I/O ********************************/ - -template <class T> -std::ostream& operator<<(std::ostream &s, const Matrix<T> &A) -{ - Subscript M=A.num_rows(); - Subscript N=A.num_cols(); - - s << M << " " << N << "\n"; - - for (Subscript i=0; i<M; i++) - { - for (Subscript j=0; j<N; j++) - { - s << A[i][j] << " "; - } - s << "\n"; - } - - - return s; -} - -template <class T> -std::istream& operator>>(std::istream &s, Matrix<T> &A) -{ - - Subscript M, N; - - s >> M >> N; - - if ( !(M == A.num_rows() && N == A.num_cols() )) - { - A.newsize(M,N); - } - - - for (Subscript i=0; i<M; i++) - for (Subscript j=0; j<N; j++) - { - s >> A[i][j]; - } - - - return s; -} - -// *******************[ basic matrix algorithms ]*************************** - - -template <class T> -Matrix<T> operator+(const Matrix<T> &A, - const Matrix<T> &B) -{ - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - - assert(M==B.num_rows()); - assert(N==B.num_cols()); - - Matrix<T> tmp(M,N); - Subscript i,j; - - for (i=0; i<M; i++) - for (j=0; j<N; j++) - tmp[i][j] = A[i][j] + B[i][j]; - - return tmp; -} - -template <class T> -Matrix<T> operator-(const Matrix<T> &A, - const Matrix<T> &B) -{ - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - - assert(M==B.num_rows()); - assert(N==B.num_cols()); - - Matrix<T> tmp(M,N); - Subscript i,j; - - for (i=0; i<M; i++) - for (j=0; j<N; j++) - tmp[i][j] = A[i][j] - B[i][j]; - - return tmp; -} - -template <class T> -Matrix<T> mult_element(const Matrix<T> &A, - const Matrix<T> &B) -{ - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - - assert(M==B.num_rows()); - assert(N==B.num_cols()); - - Matrix<T> tmp(M,N); - Subscript i,j; - - for (i=0; i<M; i++) - for (j=0; j<N; j++) - tmp[i][j] = A[i][j] * B[i][j]; - - return tmp; -} - - -template <class T> -Matrix<T> transpose(const Matrix<T> &A) -{ - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - - Matrix<T> S(N,M); - Subscript i, j; - - for (i=0; i<M; i++) - for (j=0; j<N; j++) - S[j][i] = A[i][j]; - - return S; -} - - - -template <class T> -inline Matrix<T> matmult(const Matrix<T> &A, - const Matrix<T> &B) -{ - -#ifdef TNT_BOUNDS_CHECK - assert(A.num_cols() == B.num_rows()); -#endif - - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - Subscript K = B.num_cols(); - - Matrix<T> tmp(M,K); - T sum; - - for (Subscript i=0; i<M; i++) - for (Subscript k=0; k<K; k++) - { - sum = 0; - for (Subscript j=0; j<N; j++) - sum = sum + A[i][j] * B[j][k]; - - tmp[i][k] = sum; - } - - return tmp; -} - -template <class T> -inline Matrix<T> operator*(const Matrix<T> &A, - const Matrix<T> &B) -{ - return matmult(A,B); -} - -template <class T> -inline int matmult(Matrix<T>& C, const Matrix<T> &A, - const Matrix<T> &B) -{ - - assert(A.num_cols() == B.num_rows()); - - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - Subscript K = B.num_cols(); - - C.newsize(M,K); - - T sum; - - const T* row_i; - const T* col_k; - - for (Subscript i=0; i<M; i++) - for (Subscript k=0; k<K; k++) - { - row_i = &(A[i][0]); - col_k = &(B[0][k]); - sum = 0; - for (Subscript j=0; j<N; j++) - { - sum += *row_i * *col_k; - row_i++; - col_k += K; - } - C[i][k] = sum; - } - - return 0; -} - - -template <class T> -Vector<T> matmult(const Matrix<T> &A, const Vector<T> &x) -{ - -#ifdef TNT_BOUNDS_CHECK - assert(A.num_cols() == x.dim()); -#endif - - Subscript M = A.num_rows(); - Subscript N = A.num_cols(); - - Vector<T> tmp(M); - T sum; - - for (Subscript i=0; i<M; i++) - { - sum = 0; - const T* rowi = A[i]; - for (Subscript j=0; j<N; j++) - sum = sum + rowi[j] * x[j]; - - tmp[i] = sum; - } - - return tmp; -} - -template <class T> -inline Vector<T> operator*(const Matrix<T> &A, const Vector<T> &x) -{ - return matmult(A,x); -} - -} // namespace TNT - -#endif -// CMAT_H diff --git a/intern/smoke/intern/tnt/tnt_fortran_array1d.h b/intern/smoke/intern/tnt/tnt_fortran_array1d.h deleted file mode 100644 index 45a764cf3e0..00000000000 --- a/intern/smoke/intern/tnt/tnt_fortran_array1d.h +++ /dev/null @@ -1,270 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_FORTRAN_ARRAY1D_H -#define TNT_FORTRAN_ARRAY1D_H - -#include <cstdlib> -#include <iostream> - -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif - - -#include "tnt_i_refvec.h" - -namespace TNT -{ - -template <class T> -class Fortran_Array1D -{ - - private: - - i_refvec<T> v_; - int n_; - T* data_; /* this normally points to v_.begin(), but - * could also point to a portion (subvector) - * of v_. - */ - - void initialize_(int n); - void copy_(T* p, const T* q, int len) const; - void set_(T* begin, T* end, const T& val); - - - public: - - typedef T value_type; - - - Fortran_Array1D(); - explicit Fortran_Array1D(int n); - Fortran_Array1D(int n, const T &a); - Fortran_Array1D(int n, T *a); - inline Fortran_Array1D(const Fortran_Array1D &A); - inline Fortran_Array1D & operator=(const T &a); - inline Fortran_Array1D & operator=(const Fortran_Array1D &A); - inline Fortran_Array1D & ref(const Fortran_Array1D &A); - Fortran_Array1D copy() const; - Fortran_Array1D & inject(const Fortran_Array1D & A); - inline T& operator()(int i); - inline const T& operator()(int i) const; - inline int dim1() const; - inline int dim() const; - ~Fortran_Array1D(); - - - /* ... extended interface ... */ - - inline int ref_count() const; - inline Fortran_Array1D<T> subarray(int i0, int i1); - -}; - - - - -template <class T> -Fortran_Array1D<T>::Fortran_Array1D() : v_(), n_(0), data_(0) {} - -template <class T> -Fortran_Array1D<T>::Fortran_Array1D(const Fortran_Array1D<T> &A) : v_(A.v_), n_(A.n_), - data_(A.data_) -{ -#ifdef TNT_DEBUG - std::cout << "Created Fortran_Array1D(const Fortran_Array1D<T> &A) \n"; -#endif - -} - - -template <class T> -Fortran_Array1D<T>::Fortran_Array1D(int n) : v_(n), n_(n), data_(v_.begin()) -{ -#ifdef TNT_DEBUG - std::cout << "Created Fortran_Array1D(int n) \n"; -#endif -} - -template <class T> -Fortran_Array1D<T>::Fortran_Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin()) -{ -#ifdef TNT_DEBUG - std::cout << "Created Fortran_Array1D(int n, const T& val) \n"; -#endif - set_(data_, data_+ n, val); - -} - -template <class T> -Fortran_Array1D<T>::Fortran_Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin()) -{ -#ifdef TNT_DEBUG - std::cout << "Created Fortran_Array1D(int n, T* a) \n"; -#endif -} - -template <class T> -inline T& Fortran_Array1D<T>::operator()(int i) -{ -#ifdef TNT_BOUNDS_CHECK - assert(i>= 1); - assert(i <= n_); -#endif - return data_[i-1]; -} - -template <class T> -inline const T& Fortran_Array1D<T>::operator()(int i) const -{ -#ifdef TNT_BOUNDS_CHECK - assert(i>= 1); - assert(i <= n_); -#endif - return data_[i-1]; -} - - - - -template <class T> -Fortran_Array1D<T> & Fortran_Array1D<T>::operator=(const T &a) -{ - set_(data_, data_+n_, a); - return *this; -} - -template <class T> -Fortran_Array1D<T> Fortran_Array1D<T>::copy() const -{ - Fortran_Array1D A( n_); - copy_(A.data_, data_, n_); - - return A; -} - - -template <class T> -Fortran_Array1D<T> & Fortran_Array1D<T>::inject(const Fortran_Array1D &A) -{ - if (A.n_ == n_) - copy_(data_, A.data_, n_); - - return *this; -} - - - - - -template <class T> -Fortran_Array1D<T> & Fortran_Array1D<T>::ref(const Fortran_Array1D<T> &A) -{ - if (this != &A) - { - v_ = A.v_; /* operator= handles the reference counting. */ - n_ = A.n_; - data_ = A.data_; - - } - return *this; -} - -template <class T> -Fortran_Array1D<T> & Fortran_Array1D<T>::operator=(const Fortran_Array1D<T> &A) -{ - return ref(A); -} - -template <class T> -inline int Fortran_Array1D<T>::dim1() const { return n_; } - -template <class T> -inline int Fortran_Array1D<T>::dim() const { return n_; } - -template <class T> -Fortran_Array1D<T>::~Fortran_Array1D() {} - - -/* ............................ exented interface ......................*/ - -template <class T> -inline int Fortran_Array1D<T>::ref_count() const -{ - return v_.ref_count(); -} - -template <class T> -inline Fortran_Array1D<T> Fortran_Array1D<T>::subarray(int i0, int i1) -{ -#ifdef TNT_DEBUG - std::cout << "entered subarray. \n"; -#endif - if ((i0 > 0) && (i1 < n_) || (i0 <= i1)) - { - Fortran_Array1D<T> X(*this); /* create a new instance of this array. */ - X.n_ = i1-i0+1; - X.data_ += i0; - - return X; - } - else - { -#ifdef TNT_DEBUG - std::cout << "subarray: null return.\n"; -#endif - return Fortran_Array1D<T>(); - } -} - - -/* private internal functions */ - - -template <class T> -void Fortran_Array1D<T>::set_(T* begin, T* end, const T& a) -{ - for (T* p=begin; p<end; p++) - *p = a; - -} - -template <class T> -void Fortran_Array1D<T>::copy_(T* p, const T* q, int len) const -{ - T *end = p + len; - while (p<end ) - *p++ = *q++; - -} - - -} /* namespace TNT */ - -#endif -/* TNT_FORTRAN_ARRAY1D_H */ - diff --git a/intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h b/intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h deleted file mode 100644 index f06b33f1910..00000000000 --- a/intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h +++ /dev/null @@ -1,245 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - -#ifndef TNT_FORTRAN_ARRAY1D_UTILS_H -#define TNT_FORTRAN_ARRAY1D_UTILS_H - -#include <iostream> - -namespace TNT -{ - - -/** - Write an array to a character outstream. Output format is one that can - be read back in via the in-stream operator: one integer - denoting the array dimension (n), followed by n elements, - one per line. - -*/ -template <class T> -std::ostream& operator<<(std::ostream &s, const Fortran_Array1D<T> &A) -{ - int N=A.dim1(); - - s << N << "\n"; - for (int j=1; j<=N; j++) - { - s << A(j) << "\n"; - } - s << "\n"; - - return s; -} - -/** - Read an array from a character stream. Input format - is one integer, denoting the dimension (n), followed - by n whitespace-separated elments. Newlines are ignored - - <p> - Note: the array being read into references new memory - storage. If the intent is to fill an existing conformant - array, use <code> cin >> B; A.inject(B) ); </code> - instead or read the elements in one-a-time by hand. - - @param s the charater to read from (typically <code>std::in</code>) - @param A the array to read into. -*/ -template <class T> -std::istream& operator>>(std::istream &s, Fortran_Array1D<T> &A) -{ - int N; - s >> N; - - Fortran_Array1D<T> B(N); - for (int i=1; i<=N; i++) - s >> B(i); - A = B; - return s; -} - - -template <class T> -Fortran_Array1D<T> operator+(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Fortran_Array1D<T>(); - - else - { - Fortran_Array1D<T> C(n); - - for (int i=1; i<=n; i++) - { - C(i) = A(i) + B(i); - } - return C; - } -} - - - -template <class T> -Fortran_Array1D<T> operator-(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Fortran_Array1D<T>(); - - else - { - Fortran_Array1D<T> C(n); - - for (int i=1; i<=n; i++) - { - C(i) = A(i) - B(i); - } - return C; - } -} - - -template <class T> -Fortran_Array1D<T> operator*(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Fortran_Array1D<T>(); - - else - { - Fortran_Array1D<T> C(n); - - for (int i=1; i<=n; i++) - { - C(i) = A(i) * B(i); - } - return C; - } -} - - -template <class T> -Fortran_Array1D<T> operator/(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() != n ) - return Fortran_Array1D<T>(); - - else - { - Fortran_Array1D<T> C(n); - - for (int i=1; i<=n; i++) - { - C(i) = A(i) / B(i); - } - return C; - } -} - - - - - - - - - -template <class T> -Fortran_Array1D<T>& operator+=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=1; i<=n; i++) - { - A(i) += B(i); - } - } - return A; -} - - - - -template <class T> -Fortran_Array1D<T>& operator-=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=1; i<=n; i++) - { - A(i) -= B(i); - } - } - return A; -} - - - -template <class T> -Fortran_Array1D<T>& operator*=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=1; i<=n; i++) - { - A(i) *= B(i); - } - } - return A; -} - - - - -template <class T> -Fortran_Array1D<T>& operator/=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B) -{ - int n = A.dim1(); - - if (B.dim1() == n) - { - for (int i=1; i<=n; i++) - { - A(i) /= B(i); - } - } - return A; -} - - -} // namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_fortran_array2d.h b/intern/smoke/intern/tnt/tnt_fortran_array2d.h deleted file mode 100644 index 7f14d5436e9..00000000000 --- a/intern/smoke/intern/tnt/tnt_fortran_array2d.h +++ /dev/null @@ -1,228 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT): Two-dimensional Fortran numerical array -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_FORTRAN_ARRAY2D_H -#define TNT_FORTRAN_ARRAY2D_H - -#include <cstdlib> -#include <iostream> - -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif - -#include "tnt_i_refvec.h" - -namespace TNT -{ - -template <class T> -class Fortran_Array2D -{ - - - private: - i_refvec<T> v_; - int m_; - int n_; - T* data_; - - - void initialize_(int n); - void copy_(T* p, const T* q, int len); - void set_(T* begin, T* end, const T& val); - - public: - - typedef T value_type; - - Fortran_Array2D(); - Fortran_Array2D(int m, int n); - Fortran_Array2D(int m, int n, T *a); - Fortran_Array2D(int m, int n, const T &a); - inline Fortran_Array2D(const Fortran_Array2D &A); - inline Fortran_Array2D & operator=(const T &a); - inline Fortran_Array2D & operator=(const Fortran_Array2D &A); - inline Fortran_Array2D & ref(const Fortran_Array2D &A); - Fortran_Array2D copy() const; - Fortran_Array2D & inject(const Fortran_Array2D & A); - inline T& operator()(int i, int j); - inline const T& operator()(int i, int j) const ; - inline int dim1() const; - inline int dim2() const; - ~Fortran_Array2D(); - - /* extended interface */ - - inline int ref_count() const; - -}; - -template <class T> -Fortran_Array2D<T>::Fortran_Array2D() : v_(), m_(0), n_(0), data_(0) {} - - -template <class T> -Fortran_Array2D<T>::Fortran_Array2D(const Fortran_Array2D<T> &A) : v_(A.v_), - m_(A.m_), n_(A.n_), data_(A.data_) {} - - - -template <class T> -Fortran_Array2D<T>::Fortran_Array2D(int m, int n) : v_(m*n), m_(m), n_(n), - data_(v_.begin()) {} - -template <class T> -Fortran_Array2D<T>::Fortran_Array2D(int m, int n, const T &val) : - v_(m*n), m_(m), n_(n), data_(v_.begin()) -{ - set_(data_, data_+m*n, val); -} - - -template <class T> -Fortran_Array2D<T>::Fortran_Array2D(int m, int n, T *a) : v_(a), - m_(m), n_(n), data_(v_.begin()) {} - - - - -template <class T> -inline T& Fortran_Array2D<T>::operator()(int i, int j) -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 1); - assert(i <= m_); - assert(j >= 1); - assert(j <= n_); -#endif - - return v_[ (j-1)*m_ + (i-1) ]; - -} - -template <class T> -inline const T& Fortran_Array2D<T>::operator()(int i, int j) const -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 1); - assert(i <= m_); - assert(j >= 1); - assert(j <= n_); -#endif - - return v_[ (j-1)*m_ + (i-1) ]; - -} - - -template <class T> -Fortran_Array2D<T> & Fortran_Array2D<T>::operator=(const T &a) -{ - set_(data_, data_+m_*n_, a); - return *this; -} - -template <class T> -Fortran_Array2D<T> Fortran_Array2D<T>::copy() const -{ - - Fortran_Array2D B(m_,n_); - - B.inject(*this); - return B; -} - - -template <class T> -Fortran_Array2D<T> & Fortran_Array2D<T>::inject(const Fortran_Array2D &A) -{ - if (m_ == A.m_ && n_ == A.n_) - copy_(data_, A.data_, m_*n_); - - return *this; -} - - - -template <class T> -Fortran_Array2D<T> & Fortran_Array2D<T>::ref(const Fortran_Array2D<T> &A) -{ - if (this != &A) - { - v_ = A.v_; - m_ = A.m_; - n_ = A.n_; - data_ = A.data_; - } - return *this; -} - -template <class T> -Fortran_Array2D<T> & Fortran_Array2D<T>::operator=(const Fortran_Array2D<T> &A) -{ - return ref(A); -} - -template <class T> -inline int Fortran_Array2D<T>::dim1() const { return m_; } - -template <class T> -inline int Fortran_Array2D<T>::dim2() const { return n_; } - - -template <class T> -Fortran_Array2D<T>::~Fortran_Array2D() -{ -} - -template <class T> -inline int Fortran_Array2D<T>::ref_count() const { return v_.ref_count(); } - - - - -template <class T> -void Fortran_Array2D<T>::set_(T* begin, T* end, const T& a) -{ - for (T* p=begin; p<end; p++) - *p = a; - -} - -template <class T> -void Fortran_Array2D<T>::copy_(T* p, const T* q, int len) -{ - T *end = p + len; - while (p<end ) - *p++ = *q++; - -} - - -} /* namespace TNT */ - -#endif -/* TNT_FORTRAN_ARRAY2D_H */ - diff --git a/intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h b/intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h deleted file mode 100644 index 078d34c087e..00000000000 --- a/intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h +++ /dev/null @@ -1,239 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -#ifndef TNT_FORTRAN_ARRAY2D_UTILS_H -#define TNT_FORTRAN_ARRAY2D_UTILS_H - -#include <iostream> - -namespace TNT -{ - - -template <class T> -std::ostream& operator<<(std::ostream &s, const Fortran_Array2D<T> &A) -{ - int M=A.dim1(); - int N=A.dim2(); - - s << M << " " << N << "\n"; - - for (int i=1; i<=M; i++) - { - for (int j=1; j<=N; j++) - { - s << A(i,j) << " "; - } - s << "\n"; - } - - - return s; -} - -template <class T> -std::istream& operator>>(std::istream &s, Fortran_Array2D<T> &A) -{ - - int M, N; - - s >> M >> N; - - Fortran_Array2D<T> B(M,N); - - for (int i=1; i<=M; i++) - for (int j=1; j<=N; j++) - { - s >> B(i,j); - } - - A = B; - return s; -} - - - - -template <class T> -Fortran_Array2D<T> operator+(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Fortran_Array2D<T>(); - - else - { - Fortran_Array2D<T> C(m,n); - - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - C(i,j) = A(i,j) + B(i,j); - } - return C; - } -} - -template <class T> -Fortran_Array2D<T> operator-(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Fortran_Array2D<T>(); - - else - { - Fortran_Array2D<T> C(m,n); - - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - C(i,j) = A(i,j) - B(i,j); - } - return C; - } -} - - -template <class T> -Fortran_Array2D<T> operator*(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Fortran_Array2D<T>(); - - else - { - Fortran_Array2D<T> C(m,n); - - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - C(i,j) = A(i,j) * B(i,j); - } - return C; - } -} - - -template <class T> -Fortran_Array2D<T> operator/(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() != m || B.dim2() != n ) - return Fortran_Array2D<T>(); - - else - { - Fortran_Array2D<T> C(m,n); - - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - C(i,j) = A(i,j) / B(i,j); - } - return C; - } -} - - - -template <class T> -Fortran_Array2D<T>& operator+=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - A(i,j) += B(i,j); - } - } - return A; -} - -template <class T> -Fortran_Array2D<T>& operator-=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - A(i,j) -= B(i,j); - } - } - return A; -} - -template <class T> -Fortran_Array2D<T>& operator*=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - A(i,j) *= B(i,j); - } - } - return A; -} - -template <class T> -Fortran_Array2D<T>& operator/=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - - if (B.dim1() == m || B.dim2() == n ) - { - for (int i=1; i<=m; i++) - { - for (int j=1; j<=n; j++) - A(i,j) /= B(i,j); - } - } - return A; -} - -} // namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_fortran_array3d.h b/intern/smoke/intern/tnt/tnt_fortran_array3d.h deleted file mode 100644 index ee3de255a15..00000000000 --- a/intern/smoke/intern/tnt/tnt_fortran_array3d.h +++ /dev/null @@ -1,226 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT): Three-dimensional Fortran numerical array -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_FORTRAN_ARRAY3D_H -#define TNT_FORTRAN_ARRAY3D_H - -#include <cstdlib> -#include <iostream> -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif -#include "tnt_i_refvec.h" - -namespace TNT -{ - -template <class T> -class Fortran_Array3D -{ - - - private: - - - i_refvec<T> v_; - int m_; - int n_; - int k_; - T* data_; - - public: - - typedef T value_type; - - Fortran_Array3D(); - Fortran_Array3D(int m, int n, int k); - Fortran_Array3D(int m, int n, int k, T *a); - Fortran_Array3D(int m, int n, int k, const T &a); - inline Fortran_Array3D(const Fortran_Array3D &A); - inline Fortran_Array3D & operator=(const T &a); - inline Fortran_Array3D & operator=(const Fortran_Array3D &A); - inline Fortran_Array3D & ref(const Fortran_Array3D &A); - Fortran_Array3D copy() const; - Fortran_Array3D & inject(const Fortran_Array3D & A); - inline T& operator()(int i, int j, int k); - inline const T& operator()(int i, int j, int k) const ; - inline int dim1() const; - inline int dim2() const; - inline int dim3() const; - inline int ref_count() const; - ~Fortran_Array3D(); - - -}; - -template <class T> -Fortran_Array3D<T>::Fortran_Array3D() : v_(), m_(0), n_(0), k_(0), data_(0) {} - - -template <class T> -Fortran_Array3D<T>::Fortran_Array3D(const Fortran_Array3D<T> &A) : - v_(A.v_), m_(A.m_), n_(A.n_), k_(A.k_), data_(A.data_) {} - - - -template <class T> -Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k) : - v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) {} - - - -template <class T> -Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k, const T &val) : - v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) -{ - for (T* p = data_; p < data_ + m*n*k; p++) - *p = val; -} - -template <class T> -Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k, T *a) : - v_(a), m_(m), n_(n), k_(k), data_(v_.begin()) {} - - - - -template <class T> -inline T& Fortran_Array3D<T>::operator()(int i, int j, int k) -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 1); - assert(i <= m_); - assert(j >= 1); - assert(j <= n_); - assert(k >= 1); - assert(k <= k_); -#endif - - return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1]; - -} - -template <class T> -inline const T& Fortran_Array3D<T>::operator()(int i, int j, int k) const -{ -#ifdef TNT_BOUNDS_CHECK - assert(i >= 1); - assert(i <= m_); - assert(j >= 1); - assert(j <= n_); - assert(k >= 1); - assert(k <= k_); -#endif - - return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1]; -} - - -template <class T> -Fortran_Array3D<T> & Fortran_Array3D<T>::operator=(const T &a) -{ - - T *end = data_ + m_*n_*k_; - - for (T *p=data_; p != end; *p++ = a); - - return *this; -} - -template <class T> -Fortran_Array3D<T> Fortran_Array3D<T>::copy() const -{ - - Fortran_Array3D B(m_, n_, k_); - B.inject(*this); - return B; - -} - - -template <class T> -Fortran_Array3D<T> & Fortran_Array3D<T>::inject(const Fortran_Array3D &A) -{ - - if (m_ == A.m_ && n_ == A.n_ && k_ == A.k_) - { - T *p = data_; - T *end = data_ + m_*n_*k_; - const T* q = A.data_; - for (; p < end; *p++ = *q++); - } - return *this; -} - - - - -template <class T> -Fortran_Array3D<T> & Fortran_Array3D<T>::ref(const Fortran_Array3D<T> &A) -{ - - if (this != &A) - { - v_ = A.v_; - m_ = A.m_; - n_ = A.n_; - k_ = A.k_; - data_ = A.data_; - } - return *this; -} - -template <class T> -Fortran_Array3D<T> & Fortran_Array3D<T>::operator=(const Fortran_Array3D<T> &A) -{ - return ref(A); -} - -template <class T> -inline int Fortran_Array3D<T>::dim1() const { return m_; } - -template <class T> -inline int Fortran_Array3D<T>::dim2() const { return n_; } - -template <class T> -inline int Fortran_Array3D<T>::dim3() const { return k_; } - - -template <class T> -inline int Fortran_Array3D<T>::ref_count() const -{ - return v_.ref_count(); -} - -template <class T> -Fortran_Array3D<T>::~Fortran_Array3D() -{ -} - - -} /* namespace TNT */ - -#endif -/* TNT_FORTRAN_ARRAY3D_H */ - diff --git a/intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h b/intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h deleted file mode 100644 index d337932380b..00000000000 --- a/intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h +++ /dev/null @@ -1,252 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -#ifndef TNT_FORTRAN_ARRAY3D_UTILS_H -#define TNT_FORTRAN_ARRAY3D_UTILS_H - -#include <cstdlib> -#include <cassert> - -namespace TNT -{ - - -template <class T> -std::ostream& operator<<(std::ostream &s, const Fortran_Array3D<T> &A) -{ - int M=A.dim1(); - int N=A.dim2(); - int K=A.dim3(); - - s << M << " " << N << " " << K << "\n"; - - for (int i=1; i<=M; i++) - { - for (int j=1; j<=N; j++) - { - for (int k=1; k<=K; k++) - s << A(i,j,k) << " "; - s << "\n"; - } - s << "\n"; - } - - - return s; -} - -template <class T> -std::istream& operator>>(std::istream &s, Fortran_Array3D<T> &A) -{ - - int M, N, K; - - s >> M >> N >> K; - - Fortran_Array3D<T> B(M,N,K); - - for (int i=1; i<=M; i++) - for (int j=1; j<=N; j++) - for (int k=1; k<=K; k++) - s >> B(i,j,k); - - A = B; - return s; -} - - -template <class T> -Fortran_Array3D<T> operator+(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Fortran_Array3D<T>(); - - else - { - Fortran_Array3D<T> C(m,n,p); - - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - C(i,j,k) = A(i,j,k)+ B(i,j,k); - - return C; - } -} - - -template <class T> -Fortran_Array3D<T> operator-(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Fortran_Array3D<T>(); - - else - { - Fortran_Array3D<T> C(m,n,p); - - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - C(i,j,k) = A(i,j,k)- B(i,j,k); - - return C; - } -} - - -template <class T> -Fortran_Array3D<T> operator*(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Fortran_Array3D<T>(); - - else - { - Fortran_Array3D<T> C(m,n,p); - - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - C(i,j,k) = A(i,j,k)* B(i,j,k); - - return C; - } -} - - -template <class T> -Fortran_Array3D<T> operator/(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) - return Fortran_Array3D<T>(); - - else - { - Fortran_Array3D<T> C(m,n,p); - - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - C(i,j,k) = A(i,j,k)/ B(i,j,k); - - return C; - } -} - - -template <class T> -Fortran_Array3D<T>& operator+=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - A(i,j,k) += B(i,j,k); - } - - return A; -} - - -template <class T> -Fortran_Array3D<T>& operator-=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - A(i,j,k) -= B(i,j,k); - } - - return A; -} - - -template <class T> -Fortran_Array3D<T>& operator*=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - A(i,j,k) *= B(i,j,k); - } - - return A; -} - - -template <class T> -Fortran_Array3D<T>& operator/=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B) -{ - int m = A.dim1(); - int n = A.dim2(); - int p = A.dim3(); - - if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) - { - for (int i=1; i<=m; i++) - for (int j=1; j<=n; j++) - for (int k=1; k<=p; k++) - A(i,j,k) /= B(i,j,k); - } - - return A; -} - - -} // namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_i_refvec.h b/intern/smoke/intern/tnt/tnt_i_refvec.h deleted file mode 100644 index eaf8a4d0e68..00000000000 --- a/intern/smoke/intern/tnt/tnt_i_refvec.h +++ /dev/null @@ -1,246 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_I_REFVEC_H -#define TNT_I_REFVEC_H - -#include <cstdlib> -#include <iostream> - -#ifdef TNT_BOUNDS_CHECK -#include <assert.h> -#endif - -#ifndef NULL -#define NULL 0 -#endif - -namespace TNT -{ -/* - Internal representation of ref-counted array. The TNT - arrays all use this building block. - - <p> - If an array block is created by TNT, then every time - an assignment is made, the left-hand-side reference - is decreased by one, and the right-hand-side refernce - count is increased by one. If the array block was - external to TNT, the refernce count is a NULL pointer - regardless of how many references are made, since the - memory is not freed by TNT. - - - -*/ -template <class T> -class i_refvec -{ - - - private: - T* data_; - int *ref_count_; - - - public: - - i_refvec(); - explicit i_refvec(int n); - inline i_refvec(T* data); - inline i_refvec(const i_refvec &v); - inline T* begin(); - inline const T* begin() const; - inline T& operator[](int i); - inline const T& operator[](int i) const; - inline i_refvec<T> & operator=(const i_refvec<T> &V); - void copy_(T* p, const T* q, const T* e); - void set_(T* p, const T* b, const T* e); - inline int ref_count() const; - inline int is_null() const; - inline void destroy(); - ~i_refvec(); - -}; - -template <class T> -void i_refvec<T>::copy_(T* p, const T* q, const T* e) -{ - for (T* t=p; q<e; t++, q++) - *t= *q; -} - -template <class T> -i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {} - -/** - In case n is 0 or negative, it does NOT call new. -*/ -template <class T> -i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL) -{ - if (n >= 1) - { -#ifdef TNT_DEBUG - std::cout << "new data storage.\n"; -#endif - data_ = new T[n]; - ref_count_ = new int; - *ref_count_ = 1; - } -} - -template <class T> -inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_), - ref_count_(V.ref_count_) -{ - if (V.ref_count_ != NULL) - (*(V.ref_count_))++; -} - - -template <class T> -i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {} - -template <class T> -inline T* i_refvec<T>::begin() -{ - return data_; -} - -template <class T> -inline const T& i_refvec<T>::operator[](int i) const -{ - return data_[i]; -} - -template <class T> -inline T& i_refvec<T>::operator[](int i) -{ - return data_[i]; -} - - -template <class T> -inline const T* i_refvec<T>::begin() const -{ - return data_; -} - - - -template <class T> -i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V) -{ - if (this == &V) - return *this; - - - if (ref_count_ != NULL) - { - (*ref_count_) --; - if ((*ref_count_) == 0) - destroy(); - } - - data_ = V.data_; - ref_count_ = V.ref_count_; - - if (V.ref_count_ != NULL) - (*(V.ref_count_))++; - - return *this; -} - -template <class T> -void i_refvec<T>::destroy() -{ - if (ref_count_ != NULL) - { -#ifdef TNT_DEBUG - std::cout << "destorying data... \n"; -#endif - delete ref_count_; - -#ifdef TNT_DEBUG - std::cout << "deleted ref_count_ ...\n"; -#endif - if (data_ != NULL) - delete []data_; -#ifdef TNT_DEBUG - std::cout << "deleted data_[] ...\n"; -#endif - data_ = NULL; - } -} - -/* -* return 1 is vector is empty, 0 otherwise -* -* if is_null() is false and ref_count() is 0, then -* -*/ -template<class T> -int i_refvec<T>::is_null() const -{ - return (data_ == NULL ? 1 : 0); -} - -/* -* returns -1 if data is external, -* returns 0 if a is NULL array, -* otherwise returns the positive number of vectors sharing -* this data space. -*/ -template <class T> -int i_refvec<T>::ref_count() const -{ - if (data_ == NULL) - return 0; - else - return (ref_count_ != NULL ? *ref_count_ : -1) ; -} - -template <class T> -i_refvec<T>::~i_refvec() -{ - if (ref_count_ != NULL) - { - (*ref_count_)--; - - if (*ref_count_ == 0) - destroy(); - } -} - - -} /* namespace TNT */ - - - - - -#endif -/* TNT_I_REFVEC_H */ - diff --git a/intern/smoke/intern/tnt/tnt_math_utils.h b/intern/smoke/intern/tnt/tnt_math_utils.h deleted file mode 100644 index ed4a3b7f78f..00000000000 --- a/intern/smoke/intern/tnt/tnt_math_utils.h +++ /dev/null @@ -1,35 +0,0 @@ -/** \file - * \ingroup smoke - */ -#ifndef MATH_UTILS_H -#define MATH_UTILS_H - -/* needed for fabs, sqrt() below */ -#include <cmath> - -namespace TNT -{ -/** - @returns hypotenuse of real (non-complex) scalars a and b by - avoiding underflow/overflow - using (a * sqrt( 1 + (b/a) * (b/a))), rather than - sqrt(a*a + b*b). -*/ -template <class Real> -Real hypot(const Real &a, const Real &b) -{ - - if (a== 0) - return fabs(b); - else - { - Real c = b/a; - return fabs(a) * sqrt(1 + c*c); - } -} -} /* TNT namespace */ - - - -#endif -/* MATH_UTILS_H */ diff --git a/intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h b/intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h deleted file mode 100644 index 61d52542641..00000000000 --- a/intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h +++ /dev/null @@ -1,106 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -#ifndef TNT_SPARSE_MATRIX_CSR_H -#define TNT_SPARSE_MATRIX_CSR_H - -#include "tnt_array1d.h" - -namespace TNT -{ - - -/** - Read-only view of a sparse matrix in compressed-row storage - format. Neither array elements (nonzeros) nor sparsity - structure can be modified. If modifications are required, - create a new view. - - <p> - Index values begin at 0. - - <p> - <b>Storage requirements:</b> An (m x n) matrix with - nz nonzeros requires no more than ((T+I)*nz + M*I) - bytes, where T is the size of data elements and - I is the size of integers. - - -*/ -template <class T> -class Sparse_Matrix_CompRow { - -private: - Array1D<T> val_; // data values (nz_ elements) - Array1D<int> rowptr_; // row_ptr (dim_[0]+1 elements) - Array1D<int> colind_; // col_ind (nz_ elements) - - int dim1_; // number of rows - int dim2_; // number of cols - -public: - - Sparse_Matrix_CompRow(const Sparse_Matrix_CompRow &S); - Sparse_Matrix_CompRow(int M, int N, int nz, const T *val, - const int *r, const int *c); - - - - inline const T& val(int i) const { return val_[i]; } - inline const int& row_ptr(int i) const { return rowptr_[i]; } - inline const int& col_ind(int i) const { return colind_[i];} - - inline int dim1() const {return dim1_;} - inline int dim2() const {return dim2_;} - int NumNonzeros() const {return val_.dim1();} - - - Sparse_Matrix_CompRow& operator=( - const Sparse_Matrix_CompRow &R); - - - -}; - -/** - Construct a read-only view of existing sparse matrix in - compressed-row storage format. - - @param M the number of rows of sparse matrix - @param N the number of columns of sparse matrix - @param nz the number of nonzeros - @param val a contiguous list of nonzero values - @param r row-pointers: r[i] denotes the begining position of row i - (i.e. the ith row begins at val[row[i]]). - @param c column-indices: c[i] denotes the column location of val[i] -*/ -template <class T> -Sparse_Matrix_CompRow<T>::Sparse_Matrix_CompRow(int M, int N, int nz, - const T *val, const int *r, const int *c) : val_(nz,val), - rowptr_(M, r), colind_(nz, c), dim1_(M), dim2_(N) {} - - -} -// namespace TNT - -#endif diff --git a/intern/smoke/intern/tnt/tnt_stopwatch.h b/intern/smoke/intern/tnt/tnt_stopwatch.h deleted file mode 100644 index a4eb09acbc4..00000000000 --- a/intern/smoke/intern/tnt/tnt_stopwatch.h +++ /dev/null @@ -1,98 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef STOPWATCH_H -#define STOPWATCH_H - -// for clock() and CLOCKS_PER_SEC -#include <time.h> - - -namespace TNT -{ - -inline static double seconds(void) -{ - const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; - return ( (double) clock() ) * secs_per_tick; -} - -class Stopwatch { - private: - int running_; - double start_time_; - double total_; - - public: - inline Stopwatch(); - inline void start(); - inline double stop(); - inline double read(); - inline void resume(); - inline int running(); -}; - -inline Stopwatch::Stopwatch() : running_(0), start_time_(0.0), total_(0.0) {} - -void Stopwatch::start() -{ - running_ = 1; - total_ = 0.0; - start_time_ = seconds(); -} - -double Stopwatch::stop() -{ - if (running_) - { - total_ += (seconds() - start_time_); - running_ = 0; - } - return total_; -} - -inline void Stopwatch::resume() -{ - if (!running_) - { - start_time_ = seconds(); - running_ = 1; - } -} - - -inline double Stopwatch::read() -{ - if (running_) - { - stop(); - resume(); - } - return total_; -} - - -} /* TNT namespace */ -#endif - - - diff --git a/intern/smoke/intern/tnt/tnt_subscript.h b/intern/smoke/intern/tnt/tnt_subscript.h deleted file mode 100644 index 00cc0220bd1..00000000000 --- a/intern/smoke/intern/tnt/tnt_subscript.h +++ /dev/null @@ -1,57 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - -#ifndef TNT_SUBSCRPT_H -#define TNT_SUBSCRPT_H - - -//--------------------------------------------------------------------- -// This definition describes the default TNT data type used for -// indexing into TNT matrices and vectors. The data type should -// be wide enough to index into large arrays. It defaults to an -// "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE, -// e.g. -// -// c++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ... -// -//--------------------------------------------------------------------- -// - -#ifndef TNT_SUBSCRIPT_TYPE -#define TNT_SUBSCRIPT_TYPE int -#endif - -namespace TNT -{ - typedef TNT_SUBSCRIPT_TYPE Subscript; -} /* namespace TNT */ - - -// () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the -// first elements. This offset is left as a macro for future -// purposes, but should not be changed in the current release. -// -// -#define TNT_BASE_OFFSET (1) - -#endif diff --git a/intern/smoke/intern/tnt/tnt_vec.h b/intern/smoke/intern/tnt/tnt_vec.h deleted file mode 100644 index 77458c6b8c1..00000000000 --- a/intern/smoke/intern/tnt/tnt_vec.h +++ /dev/null @@ -1,407 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - - - -#ifndef TNT_VEC_H -#define TNT_VEC_H - -#include "tnt_subscript.h" -#include <cstdlib> -#include <cassert> -#include <iostream> -#include <sstream> - -namespace TNT -{ - -/** - <b>[Deprecatred]</b> Value-based vector class from pre-1.0 - TNT version. Kept here for backward compatiblity, but should - use the newer TNT::Array1D classes instead. - -*/ - -template <class T> -class Vector -{ - - - public: - - typedef Subscript size_type; - typedef T value_type; - typedef T element_type; - typedef T* pointer; - typedef T* iterator; - typedef T& reference; - typedef const T* const_iterator; - typedef const T& const_reference; - - Subscript lbound() const { return 1;} - - protected: - T* v_; - T* vm1_; // pointer adjustment for optimzied 1-offset indexing - Subscript n_; - - // internal helper function to create the array - // of row pointers - - void initialize(Subscript N) - { - // adjust pointers so that they are 1-offset: - // v_[] is the internal contiguous array, it is still 0-offset - // - assert(v_ == NULL); - v_ = new T[N]; - assert(v_ != NULL); - vm1_ = v_-1; - n_ = N; - } - - void copy(const T* v) - { - Subscript N = n_; - Subscript i; - -#ifdef TNT_UNROLL_LOOPS - Subscript Nmod4 = N & 3; - Subscript N4 = N - Nmod4; - - for (i=0; i<N4; i+=4) - { - v_[i] = v[i]; - v_[i+1] = v[i+1]; - v_[i+2] = v[i+2]; - v_[i+3] = v[i+3]; - } - - for (i=N4; i< N; i++) - v_[i] = v[i]; -#else - - for (i=0; i< N; i++) - v_[i] = v[i]; -#endif - } - - void set(const T& val) - { - Subscript N = n_; - Subscript i; - -#ifdef TNT_UNROLL_LOOPS - Subscript Nmod4 = N & 3; - Subscript N4 = N - Nmod4; - - for (i=0; i<N4; i+=4) - { - v_[i] = val; - v_[i+1] = val; - v_[i+2] = val; - v_[i+3] = val; - } - - for (i=N4; i< N; i++) - v_[i] = val; -#else - - for (i=0; i< N; i++) - v_[i] = val; - -#endif - } - - - - void destroy() - { - /* do nothing, if no memory has been previously allocated */ - if (v_ == NULL) return ; - - /* if we are here, then matrix was previously allocated */ - delete [] (v_); - - v_ = NULL; - vm1_ = NULL; - } - - - public: - - // access - - iterator begin() { return v_;} - iterator end() { return v_ + n_; } - iterator begin() const { return v_;} - iterator end() const { return v_ + n_; } - - // destructor - - ~Vector() - { - destroy(); - } - - // constructors - - Vector() : v_(0), vm1_(0), n_(0) {}; - - Vector(const Vector<T> &A) : v_(0), vm1_(0), n_(0) - { - initialize(A.n_); - copy(A.v_); - } - - Vector(Subscript N, const T& value = T()) : v_(0), vm1_(0), n_(0) - { - initialize(N); - set(value); - } - - Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0) - { - initialize(N); - copy(v); - } - - Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0) - { - initialize(N); - std::istringstream ins(s); - - Subscript i; - - for (i=0; i<N; i++) - ins >> v_[i]; - } - - - // methods - // - Vector<T>& newsize(Subscript N) - { - if (n_ == N) return *this; - - destroy(); - initialize(N); - - return *this; - } - - - // assignments - // - Vector<T>& operator=(const Vector<T> &A) - { - if (v_ == A.v_) - return *this; - - if (n_ == A.n_) // no need to re-alloc - copy(A.v_); - - else - { - destroy(); - initialize(A.n_); - copy(A.v_); - } - - return *this; - } - - Vector<T>& operator=(const T& scalar) - { - set(scalar); - return *this; - } - - inline Subscript dim() const - { - return n_; - } - - inline Subscript size() const - { - return n_; - } - - - inline reference operator()(Subscript i) - { -#ifdef TNT_BOUNDS_CHECK - assert(1<=i); - assert(i <= n_) ; -#endif - return vm1_[i]; - } - - inline const_reference operator() (Subscript i) const - { -#ifdef TNT_BOUNDS_CHECK - assert(1<=i); - assert(i <= n_) ; -#endif - return vm1_[i]; - } - - inline reference operator[](Subscript i) - { -#ifdef TNT_BOUNDS_CHECK - assert(0<=i); - assert(i < n_) ; -#endif - return v_[i]; - } - - inline const_reference operator[](Subscript i) const - { -#ifdef TNT_BOUNDS_CHECK - assert(0<=i); - - - - - - - assert(i < n_) ; -#endif - return v_[i]; - } - - - -}; - - -/* *************************** I/O ********************************/ - -template <class T> -std::ostream& operator<<(std::ostream &s, const Vector<T> &A) -{ - Subscript N=A.dim(); - - s << N << "\n"; - - for (Subscript i=0; i<N; i++) - s << A[i] << " " << "\n"; - s << "\n"; - - return s; -} - -template <class T> -std::istream & operator>>(std::istream &s, Vector<T> &A) -{ - - Subscript N; - - s >> N; - - if ( !(N == A.size() )) - { - A.newsize(N); - } - - - for (Subscript i=0; i<N; i++) - s >> A[i]; - - - return s; -} - -// *******************[ basic matrix algorithms ]*************************** - - -template <class T> -Vector<T> operator+(const Vector<T> &A, - const Vector<T> &B) -{ - Subscript N = A.dim(); - - assert(N==B.dim()); - - Vector<T> tmp(N); - Subscript i; - - for (i=0; i<N; i++) - tmp[i] = A[i] + B[i]; - - return tmp; -} - -template <class T> -Vector<T> operator-(const Vector<T> &A, - const Vector<T> &B) -{ - Subscript N = A.dim(); - - assert(N==B.dim()); - - Vector<T> tmp(N); - Subscript i; - - for (i=0; i<N; i++) - tmp[i] = A[i] - B[i]; - - return tmp; -} - -template <class T> -Vector<T> operator*(const Vector<T> &A, - const Vector<T> &B) -{ - Subscript N = A.dim(); - - assert(N==B.dim()); - - Vector<T> tmp(N); - Subscript i; - - for (i=0; i<N; i++) - tmp[i] = A[i] * B[i]; - - return tmp; -} - - -template <class T> -T dot_prod(const Vector<T> &A, const Vector<T> &B) -{ - Subscript N = A.dim(); - assert(N == B.dim()); - - Subscript i; - T sum = 0; - - for (i=0; i<N; i++) - sum += A[i] * B[i]; - - return sum; -} - -} /* namespace TNT */ - -#endif -// TNT_VEC_H diff --git a/intern/smoke/intern/tnt/tnt_version.h b/intern/smoke/intern/tnt/tnt_version.h deleted file mode 100644 index d770efb15c7..00000000000 --- a/intern/smoke/intern/tnt/tnt_version.h +++ /dev/null @@ -1,42 +0,0 @@ -/** \file - * \ingroup smoke - */ -/* -* -* Template Numerical Toolkit (TNT) -* -* Mathematical and Computational Sciences Division -* National Institute of Technology, -* Gaithersburg, MD USA -* -* -* This software was developed at the National Institute of Standards and -* Technology (NIST) by employees of the Federal Government in the course -* of their official duties. Pursuant to title 17 Section 105 of the -* United States Code, this software is not subject to copyright protection -* and is in the public domain. NIST assumes no responsibility whatsoever for -* its use by other parties, and makes no guarantees, expressed or implied, -* about its quality, reliability, or any other characteristic. -* -*/ - -#ifndef TNT_VERSION_H -#define TNT_VERSION_H - - -//--------------------------------------------------------------------- -// current version -//--------------------------------------------------------------------- - - -#define TNT_MAJOR_VERSION '1' -#define TNT_MINOR_VERSION '2' -#define TNT_SUBMINOR_VERSION '6' -#define TNT_VERSION_STRING "1.2.6" - - - - - -#endif -// TNT_VERSION_H |