#include "filaments.h" double test_vorticity_filament0(coord pcar, int n_seg, double a, double* t0, coord* c, coord* tvec, coord* nvec, coord* bvec, int period){ /* Compute the local coordinates required for the vorticity field. Each position P(x,y,z) is projected into the local Frenet-Serret frame to obtain a set of local coordinates, such that: i) (P - X . T = 0 ii) (P - X) . N = x_n ii) (P - X) . B = x_b This requires finding the value of X(t0) along each space curve that verifies i) through a minization process. Then, we use the local coordinates (x_n, x_b) to define a radial coordinate rho required to compute the vorticity of a Lamb-Oseen vortex as omega = Gamma/(pi a²) exp(-rho²/a²) . T where Gamma is the circulation and a the core size. */ /* First, we approximate the minimal distance between the point P and each segment of the curve. */ double dmin = 1e30, tmin=0; double rho_loc; for (int i = 0; i < n_seg; i++){ if (vecdist2(pcar, c[i]) < dmin){ dmin = vecdist2(pcar, c[i]); tmin = t0[i]; } } if (period != 0) tmin = fmod(tmin + period*2*pi, period*2*pi); // If P is close to the vortex, we refine the initial guess coord ploc, ccar, frenet[3]; double tq = frenet_projection_min(n_seg, a, t0, c, tvec, nvec, bvec, pcar, tmin); ccar = gsl_interp1d( n_seg, t0, c, tq); // Then, compute the local coordinates for the vortex frenet[0] = gsl_interp1d( n_seg, t0, tvec, tq); frenet[1] = gsl_interp1d( n_seg, t0, nvec, tq); frenet[2] = gsl_interp1d( n_seg, t0, bvec, tq); ploc.x = vecdot(vecdiff(pcar, ccar), frenet[0]); ploc.y = vecdot(vecdiff(pcar, ccar), frenet[1]); ploc.z = vecdot(vecdiff(pcar, ccar), frenet[2]); rho_loc = sqrt(vecdot(ploc, ploc)); return rho_loc; } coord test_vorticity_filament1(coord pcar, int n_seg, double a, double* t0, coord* c, coord* tvec, coord* nvec, coord* bvec, int period){ double dmin = 1e30, tmin=0; for (int i = 0; i < n_seg; i++){ if (vecdist2(pcar, c[i]) < dmin){ dmin = vecdist2(pcar, c[i]); tmin = t0[i]; } } if (period != 0) tmin = fmod(tmin + period*2*pi, period*2*pi); // If P is close to the vortex, we refine the initial guess coord ccar, frenet[1]; double tq = frenet_projection_min(n_seg, a, t0, c, tvec, nvec, bvec, pcar, tmin); ccar = gsl_interp1d( n_seg, t0, c, tq); // Then, compute the local coordinates for the vortex frenet[0] = gsl_interp1d( n_seg, t0, tvec, tq); return (coord) {frenet[0].x, frenet[0].y, frenet[0].z}; } coord get_vorticity_filament(coord pcar, int n_seg, double a, double* t0, coord* c, coord* tvec, coord* nvec, coord* bvec, int period){ /* Compute the local coordinates required for the vorticity field. Each position P(x,y,z) is projected into the local Frenet-Serret frame to obtain a set of local coordinates, such that: i) (P - X . T = 0 ii) (P - X) . N = x_n ii) (P - X) . B = x_b This requires finding the value of X(t0) along each space curve that verifies i) through a minization process. Then, we use the local coordinates (x_n, x_b) to define a radial coordinate rho required to compute the vorticity of a Lamb-Oseen vortex as omega = Gamma/(pi a²) exp(-rho²/a²) . T where Gamma is the circulation and a the core size. */ /* First, we approximate the minimal distance between the point P and each segment of the curve. */ coord omega; double dmin = 1e30, tmin=0; double rho_loc, omega_mag; for (int i = 0; i < n_seg; i++){ if (vecdist2(pcar, c[i]) < dmin){ dmin = vecdist2(pcar, c[i]); tmin = t0[i]; } } if (period != 0) tmin = fmod(tmin + period*2*pi, period*2*pi); if (dmin < L0){ // If P is close to the vortex, we refine the initial guess coord ploc, ccar, frenet[3]; double tq = frenet_projection_min(n_seg, a, t0, c, tvec, nvec, bvec, pcar, tmin); ccar = gsl_interp1d( n_seg, t0, c, tq); // Then, compute the local coordinates for the vortex frenet[0] = gsl_interp1d( n_seg, t0, tvec, tq); frenet[1] = gsl_interp1d( n_seg, t0, nvec, tq); frenet[2] = gsl_interp1d( n_seg, t0, bvec, tq); ploc.x = vecdot(vecdiff(pcar, ccar), frenet[0]); ploc.y = vecdot(vecdiff(pcar, ccar), frenet[1]); ploc.z = vecdot(vecdiff(pcar, ccar), frenet[2]); rho_loc = sqrt(vecdot(ploc, ploc)); // Last, we compute the vorticity for the vortex 1 omega_mag = exp(-sq(rho_loc)/sq(a))/(pi*sq(a)); omega = (coord) {omega_mag * frenet[0].x, omega_mag * frenet[0].y, omega_mag * frenet[0].z}; } else { // Otherwise, if the point is too far, we set the vorticity to zero. foreach_dimension() omega.x = 0; } return omega; } coord get_vorticity_filament2(double Gamma, double Uc, coord pcar, int n_seg, double a, double* t0, coord* c, coord* tvec, coord* nvec, coord* bvec, int period){ /* Compute the local coordinates required for the vorticity field. Each position P(x,y,z) is projected into the local Frenet-Serret frame to obtain a set of local coordinates, such that: i) (P - X . T = 0 ii) (P - X) . N = x_n ii) (P - X) . B = x_b This requires finding the value of X(t0) along each space curve that verifies i) through a minization process. Then, we use the local coordinates (x_n, x_b) to define a radial coordinate rho required to compute the vorticity of a Lamb-Oseen vortex as omega = Gamma/(pi a²) exp(-rho²/a²) . T + 2 Uc/a (rho/a) exp(-rho²/a²) where Gamma is the circulation and a the core size and Uc is the axial centerline velocity. */ /* First, we approximate the minimal distance between the point P and each segment of the curve. */ coord omega; double dmin = 1e30, tmin=0; double rho_loc, omega_mag; for (int i = 0; i < n_seg; i++){ if (vecdist2(pcar, c[i]) < dmin){ dmin = vecdist2(pcar, c[i]); tmin = t0[i]; } } if (period != 0) tmin = fmod(tmin + period*2*pi, period*2*pi); if (dmin < L0){ // If P is close to the vortex, we refine the initial guess coord ploc, ccar, frenet[3]; double tq = frenet_projection_min(n_seg, a, t0, c, tvec, nvec, bvec, pcar, tmin); ccar = gsl_interp1d( n_seg, t0, c, tq); // Then, compute the local coordinates for the vortex frenet[0] = gsl_interp1d( n_seg, t0, tvec, tq); frenet[1] = gsl_interp1d( n_seg, t0, nvec, tq); frenet[2] = gsl_interp1d( n_seg, t0, bvec, tq); ploc.x = vecdot(vecdiff(pcar, ccar), frenet[0]); ploc.y = vecdot(vecdiff(pcar, ccar), frenet[1]); ploc.z = vecdot(vecdiff(pcar, ccar), frenet[2]); rho_loc = sqrt(vecdot(ploc, ploc)); // Last, we compute the vorticity for the vortex 1 omega_mag = exp(-sq(rho_loc)/sq(a))/(sq(a)); omega.x = omega_mag * (Gamma/pi * frenet[0].x + (2.0 * Uc) * (-ploc.z * frenet[1].x + ploc.y * frenet[2].x)); omega.y = omega_mag * (Gamma/pi * frenet[0].y + (2.0 * Uc) * (-ploc.z * frenet[1].y + ploc.y * frenet[2].y)); omega.z = omega_mag * (Gamma/pi * frenet[0].z + (2.0 * Uc) * (-ploc.z * frenet[1].z + ploc.y * frenet[2].z)); } else { // Otherwise, if the point is too far, we set the vorticity to zero. foreach_dimension() omega.x = 0; } return omega; }