sandbox/acastillo/filaments/old_but_interesting/filaments.c

    #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;
    }