Files @ d6faa5ffcedf
Branch filter:

Location: MD/arcos/src/reaction.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
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 reaction.c
 *  @brief Functions to handle the "reaction" part of
 *  convection-diffusion-reaction equation.
 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "cdr.h"
#include "grid.h"
#include "parameters.h"
#include "photo.h"
#include "proto.h"
#include "react_table.h"
#include "species.h"
#include "reaction.h"

static void fill_react_gaps ();

reaction_t *reactions_list = NULL;
extern double z_cutoff;
double species_written[20];

/** @brief Returns the position in the species-array of a given species.
 *
 * Returns -1 if not found. */
int
find_species_by_name(const char *spec_name)
{
  int res = -1;
  int cnt;

  for (cnt = 0; cnt < no_species; cnt++)
  {
    if (strcmp(spec_index[cnt]->name, spec_name) == 0) 
      res = cnt;
  }

  if (res == -1) {
      printf("Species-lookup-failure: %s!\n",spec_name);
      assert(1 == 0);
  }
  return res;
}

/** @brief Adds a given reaction to the reaction list */
void
react_add (reaction_t *react)
{
  react_table *rt;

  debug (3, "react_add (...)\n");

  printf("Adding reaction with table: %s\n",react->tablefile);

  rt = (react_table *) xmalloc (sizeof(react_table));

  if (react->tablefile != NULL) {
    react_table_read(react->tablefile, rt);
    react->rt = rt;
  }

  react->next = reactions_list;
  reactions_list = react;
}

/** @brief Applies a reaction to the given @a grid */
void 
react_apply (reaction_t *react, cdr_grid_t *grid, int overwrite)
{
  int i, ir, iz, itheta;
  rz_array_t *grid_in[REACTION_MAX_IN], *grid_out[REACTION_MAX_IN + REACTION_MAX_OUT],
    *grid_eabs;
  double *in = NULL, *out = NULL, eabs;
  double test;
  double rate;
  int pos;
  double e1, e2, val1, val2, log_e, res, r_mod;
  int cnt, curr_species;

  debug (3, "react_apply (..., " grid_printf_str ")\n",
         grid_printf_args (grid));

  grid_eabs = grid->dens[no_species];

  for (i = 0; i < react->nin; i++) {
    grid_in[i] = grid->dens[react->input[i]];
    grid_out[i] = grid->d_dens[react->input[i]];
  }

  for (i = react->nin; i < react->nin + react->nout; i++) {
    grid_out[i] = grid->d_dens[react->output[i - react->nin]];
  }

#pragma omp parallel private(ir, iz, i, in, out)
  {
    /* malloc(0) is legal, but I do not want to play with fire. */
    if (react->nin > 0) {
      in = (double *) xmalloc (sizeof(double) * react->nin);
    }

    /* Do not know what use nout == 0 may have, (perhaps some debugging?)
       but we leave it here as theoretically possible. */
    if (react->nout > 0) {
      out = (double *) xmalloc (sizeof(double) * (react->nout + react->nin));
    }


    #pragma omp for
    iter_grid_theta(grid, itheta) { //ITER3
      iter_grid_z(grid, iz) { //ITER2
        double back_dens;
        if (sprite_module) {
          back_dens = spr_density_at (z_at (iz, grid->level));
        } else {
          back_dens = 1.0;
        }


        iter_grid_r(grid, ir) { //ITER1
          if ( z_at (iz, grid->level) < z_cutoff ) { //IF1
            eabs = fabs (RZT(grid_eabs, ir, iz, itheta));
            for (i = 0; i < react->nin; i++) {
              in[i] = fabs (RZT(grid_in[i], ir, iz, itheta));
	    }

            log_e = log10(eabs);

            /* If the supplied fieldstrength falls outside the boundaries of the table,
              return predetermined under-/overflow values */
            if (log_e < react->rt->e_min) {
              rate = react->rt->underflow;
            } else if (log_e > react->rt->e_min + react->rt->e_step * react->rt->steps) {
              rate = react->rt->overflow;
            } else {
              pos = floor((log_e - react->rt->e_min) / react->rt->e_step);
              val1 = react->rt->values[pos];
              val2 = react->rt->values[pos+1];
              e1 = pow(10, react->rt->e_min + react->rt->e_step * (double) pos);
              e2 = e1 * pow(10, react->rt->e_step);

              rate = val1 + ((val2 - val1) / (e2 - e1)) * (eabs - e1);
            }

            for (i = 0; i < react->nin; i++){ rate *=  MYMAX(0, in[i]); }

            for (i = 0; i < react->nin + react->nout; i++) { //FOR1
              if (i < react->nin) {
                curr_species = react->input[i]; r_mod = -rate;
              } else { curr_species = react->output[i - react->nin]; r_mod = rate; }
    
              if (spec_index[curr_species]->charge != 0.0) {
                 RZT(grid_out[i], ir, iz, itheta) += r_mod;
              }
            } //FOR1
          } //IF1
        } //ITER1
      } //ITER2
    } //ITER3
    free (in);
    free (out);
  }
}

/** @brief Recursive version of @a react_apply  */
void
react_apply_r (reaction_t *react, cdr_grid_t *grid, int overwrite)
{
  cdr_grid_t *child;

  react_apply (react, grid, overwrite);

  iter_childs (grid, child) {
    react_apply_r (react, child, overwrite);
  }
}

/** @brief Sets the d_dens field of a grid to zero */
void 
zero_fill (cdr_grid_t* grid)
{
  int ir, iz, itheta, i;

  iter_grid_3d (grid, ir, iz, itheta)
  for (i = 0; i < no_species; i++) {
    RZT(grid->d_dens[i], ir, iz, itheta) = 0.0;
  }
}

/** @brief Applies all reactions to the given @a grid and his descendants */
void 
react_apply_all (cdr_grid_t *grid)
{
  reaction_t *react;
  int overwrite;
  int last = -1;
  int cnt;

  zero_fill(grid);

  overwrite = TRUE;

  for (react = reactions_list; react; react = react->next) {
    if (react->is_photo) {
      photo_calc (photo_terms, grid);
    } else {
      react_apply_r (react, grid, overwrite);
    }
    overwrite = FALSE;
  }
}

/** @brief Fill in the gaps that we left in the definitions */
static void
fill_react_gaps ()
{
}

/** @brief Initializes the list of reactions. */
void 
react_init ()
{
  /* Note that the reactions are applied in inverse order than listed here. */
  /* Rest of the kinetic model: */
  kinetic_init ();
 
}

/** Below this electric field, we do not waste time calculating anything.
   Besides, this avoid NaNs for eabs == 0. */
#define EPS_EABS 1e-6