Files
@ 215974bd7440
Branch filter:
Location: MD/arcos/src/sprites.c
215974bd7440
2.9 KiB
text/x-csrc
Edited file README via RhodeCode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | /** @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;
}
|