Files @ d6faa5ffcedf
Branch filter:

Location: MD/arcos/src/sprites.c - annotation

Margreet Nool
install arcos
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
/** @file sprites.c
 *  @brief Routines for the "sprites module."
 *
 * The idea here is to cope with strongly varying densities along
 * the streamer propagation.
 *
 * For photoionization we use a "local maximum approximation", i.e. the
 * quenching and absorption lengths for all the volume are taken as those
 * corresponding to the streamer head.
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include "cdr.h"
#include "parameters.h"
#include "photo.h"
#include "proto.h"
#include "rz_array.h"
#include "species.h"

static int var_max_axis (cdr_grid_t *grid, rz_array_t *var, int sign);

double spr_nu_a, spr_nu_d, spr_nu_rt;
photo_term_t *spr_photo_terms;
extern photo_term_t *photo_terms;

/** @brief The density at a given height, assuming dens = 1.0 at height = 0.0.
 *
 * We are assuming an exponential profile here but in principle any other
 * profile would also do.
 */
double
spr_density_at (double altitude)
{
  return exp (-altitude / dens_decay_len);
}


/** @brief Initialize the sprite module.
 *
 * We have to remember the values of the global variables that we will adapt
 * to altitude.
 */
void
spr_init ()
{
  /* We make the Courant numbers depend on the altitude: this is because
     when we apply the Courant-Levy criterium we assume v = -E, which is not
     true if the mobility now is != 1.0 */
  spr_nu_a = nu_a;
  spr_nu_d = nu_d;
  spr_nu_rt = nu_rt;

  photo_copy_list (photo_terms, &spr_photo_terms);
}

/** @brief Hook to update the variables that depend on the head altitude.
 *
 * Has to be called AFTER the charge is calculated.
 */
void
spr_hook (cdr_grid_t *grid)
{
  double altitude;
  
  altitude = spr_head_altitude (grid, sprite_sign);

  spr_update (altitude);
}

/** @brief Updates the magnitudes that we are tracking according to a
 * given altitude. 
 */
void
spr_update (double altitude)
{
  double back_dens = spr_density_at (altitude);
  photo_term_t *p0, *p;

  nu_a = spr_nu_a;
  nu_d = spr_nu_d * back_dens;
  nu_rt = spr_nu_rt;

  for (p0 = spr_photo_terms, p = photo_terms; p0; p0 = p0->next, p = p->next) {
    p->lambda = p0->lambda * back_dens * back_dens;
    p->A = p0->A * (sprite_dens_0 + sprite_dens_q) 
      / (back_dens + sprite_dens_q);
  }
  
}

/** @brief Finds the position of the streamer head by locating the maximum
 * (or -maximum) of the charge along the streamer axis.
 *
 * @a sign has to be +1 for positive streamers and -1 for negative streamers.
 */
double
spr_head_altitude (cdr_grid_t *grid, int sign)
{
  int ih;
  ih = var_max_axis (grid, grid->charge, sign);
  if (0 == ih) ih = var_max_axis (grid, grid->dens[electrons], 1);
  return z_at (ih, grid->level);
}

/** @brief var_max_axis QQQQ */
static int
var_max_axis (cdr_grid_t *grid, rz_array_t *var, int sign)
{
  int iz, iz_max = 0;
  double var_max = 0.0;

  iter_grid_z (grid, iz) {
    if (sign * RZT (var, 0, iz, 0) > var_max) {
      iz_max = iz;
      var_max = RZT (var, 0, iz, 0);
    }
  }
  
  return iz_max;
}