Files @ d6faa5ffcedf
Branch filter:

Location: MD/arcos/src/photo.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
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
d6faa5ffcedf
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 photo.c
 *  @brief Routines for the calculation of the photoionization source term.
 *
 * We use the Helmholtz approximation for the kernel in the photoionization
 * integral and we use the routines of the Poisson solver for the Helmholtz
 * equation (FISHPACK was modified to take a new inhomogeneous term into
 * account).
 */

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

#include "cdr.h"
#include "interpol2.h"
#include "mapper.h"
#include "parameters.h"
#include "photo.h"
#include "poisson.h"
#include "proto.h"
#include "rz_array.h"
#include "species.h"

void photo_copy (mapper_t *mapper, grid_t *source, grid_t *target, 
		 int ir, int iz, int itheta);
void photo_coarsen (mapper_t *mapper, grid_t *source, grid_t *target, 
		    int ir, int iz, int itheta);
int photo_interpol_set (mapper_t *mapper, grid_t *source, 
			 interpol_t *interpol,
			 int pr, int pz, int itheta);
void photo_interpol (mapper_t *mapper, grid_t *source, grid_t *target, 
		     interpol_t *interpol, 
		     int ir, int iz, int itheta);

photo_term_t *photo_terms = NULL;

mapper_t photo_mapper = {&interpol_bilin, photo_coarsen, photo_copy,
			 photo_interpol_set, photo_interpol};

mapper_t *photo_mappers[] = {&photo_mapper, NULL};

pois_problem_t *pois_photo_1;
pois_problem_t *pois_photo_2;
extern pois_problem_t *pois_electrostatic;

/** @brief Initializes photoionization QQQQ? */
void
photo_init ()
{
  /* Since it makes no sense, we use photo_extra_levels < 0 to say that
     the conditions for the photoionization are the same as for
     the electrostatic problem.  This is needed for backwards compatibility. */
  if (extra_photo_levels < 0) 
  {
    pois_photo_1 = pois_electrostatic;
    pois_photo_2 = pois_electrostatic;
    return;
  }

  /* Two different sets of refinement criteria for the two photoionization
     terms. If extra_photo_levels_2 < 0, then pois_photo_2 = pois_photo_1 */
  pois_photo_1 = xmalloc (sizeof (pois_problem_t));

  pois_photo_1->max_level = photo_max_level;
  pois_photo_1->extra_levels = extra_photo_levels;
  pois_photo_1->max_error = photo_max_error;

  pois_photo_1->bnd_right = photo_bnd_right;
  pois_photo_1->bnd_top = photo_bnd_top;
  pois_photo_1->bnd_bottom = photo_bnd_bottom;

  if (extra_photo_levels_2 < 0)
  {
     pois_photo_2 = pois_photo_1;
     return;
  }

  pois_photo_2 = xmalloc (sizeof (pois_problem_t));

  pois_photo_2->max_level = photo_max_level_2;
  pois_photo_2->extra_levels = extra_photo_levels_2;
  pois_photo_2->max_error = photo_max_error_2;

  pois_photo_2->bnd_right = photo_bnd_right_2;
  pois_photo_2->bnd_top = photo_bnd_top_2;
  pois_photo_2->bnd_bottom = photo_bnd_bottom_2;
}


/** @brief Copies the photoionization QQQQ? */
void
photo_copy (mapper_t *mapper, grid_t *source, grid_t *target, 
	    int ir, int iz, int itheta)
{
  cdr_grid_t *cdr;
  pois_grid_t *pois;

  cdr = (cdr_grid_t*) target;
  pois = (pois_grid_t*) source;

  RZT (cdr->photo, ir, iz, itheta) = RZ (pois->phi, ir, iz);
}

/** @brief Coarsens the photoionization QQQQ? */
void 
photo_coarsen (mapper_t *mapper, grid_t *source, grid_t *target, 
	       int ir, int iz, int itheta)
{
  cdr_grid_t *cdr;
  pois_grid_t *pois;
  int level_diff, z, r;

  cdr = (cdr_grid_t*) target;
  pois = (pois_grid_t*) source;

  level_diff = pois->level - cdr->level;

  z = (iz << level_diff) + (1 << (level_diff - 1));
  r = (ir << level_diff) + (1 << (level_diff - 1));

  if (grid_contains (source, r, z, GRID_INSIDE) && 
      grid_contains (source, r - 1, z, GRID_INSIDE) &&
      grid_contains (source, r, z - 1, GRID_INSIDE) &&
      grid_contains (source, r - 1, z - 1, GRID_INSIDE)) {
    
    RZT (cdr->photo, ir, iz, itheta)  = 0.25 *
      (RZ (pois->phi, r, z) 
       + RZ (pois->phi, r - 1, z) 
       + RZ (pois->phi, r, z - 1) 
       + RZ (pois->phi, r - 1, z - 1));
  }

}

/** @brief photo_interpol_set QQQQ? */
int 
photo_interpol_set (mapper_t *mapper, grid_t *source, interpol_t *interpol,
		      int pr, int pz, int itheta)
{
  pois_grid_t *pois;

  pois = (pois_grid_t*) source;

  interpol_set_stencil (interpol,
			r_at (pr, pois->level),
			z_at (pz, pois->level),
			RZ (pois->phi, pr, pz), 
			RZ (pois->phi, pr, pz + 1),
			RZ (pois->phi, pr + 1, pz), 
			RZ (pois->phi, pr + 1, pz + 1));

  return TRUE;
}

/** @brief photo_interpol QQQQ? */
void
photo_interpol (mapper_t *mapper, grid_t *source, grid_t *target, 
		interpol_t *interpol, int ir, int iz, int itheta)
{
  double r, z;
  cdr_grid_t *cdr;

  cdr = (cdr_grid_t *) target;

  r = r_at (ir, cdr->level);
  z = z_at (iz, cdr->level);

  RZT (cdr->photo, ir, iz, itheta) = interpol_apply (interpol, r, z);
}


/** @brief Registers a photoionization term with given @a A and @a lambda. */
void
photo_register (double A, double lambda)
{
  photo_term_t *t;

  t = (photo_term_t *) xmalloc (sizeof (photo_term_t));

  t->A = A;
  t->lambda = lambda;
  t->next = photo_terms;

  photo_terms = t;
}

/** @brief Copies a list of photo terms into @a *dest. */
void
photo_copy_list (photo_term_t *src, photo_term_t **dest)
{
  photo_term_t *ptr_term;
  photo_term_t *p = NULL, *p1;

  *dest = NULL;

  while (src) {
    p1 = (photo_term_t *) xmalloc (sizeof (photo_term_t));
    if (p) {
      p->next = p1;
    } else {
      *dest = p1;
    }

    p = p1;
    p->A = src->A;
    p->lambda = src->lambda;
    src = src->next;
  }

  if (p) p->next = NULL;
}


/** @brief Unregisters all the photoionization terms and
 *  frees the allocated space.
 */
void
photo_unregister_all (void)
{
  photo_term_t *t, *next;

  for (t = photo_terms; t; t = next) {
    next = t->next;
    free (t);
  }

  photo_terms = NULL;
}

/** @brief Transforms back the photoionization calculation into real space. */
void
photo_dft_r (cdr_grid_t *grid, int sign)
{
  cdr_grid_t *leaf;

  debug (3, "photo_dft_r(" grid_printf_str ", %d)\n", 
	 grid_printf_args(grid), sign);

  iter_childs (grid, leaf) {
    photo_dft_r (leaf, sign);
  }

  dft_transform (grid->photo, grid->photo, sign);
}

/** @brief Copies the derivative of the ion density into cdr->charge
 *
 * The ion density, which is supposed to be at this point, the impact
 * ionization) into cdr->charge, which will be used as the source for
 * the Poisson/Helmholtz solver. */
void
photo_copy_source (cdr_grid_t *grid)
{
  int ir, iz, itheta;

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

#pragma omp parallel
  {
#pragma omp for private (ir, iz)
    iter_grid_3d_n (grid, ir, iz, itheta, 2) {
      RZT (grid->charge, ir, iz, itheta) = 
	RZT (grid->d_dens[ions], ir, iz, itheta) / grid->ntheta;
    }
  }
}

/** @brief Recursive version of @a photo_copy_source. */
mk_recursive (photo_copy_source, cdr_grid_t)

/** @brief Once a photoionization term is computed, we add it to d_dens.
 *
 * Note that we already copied the contents of d_dens[ions] into
 * charge, so when we solve again the Helholtz equation, the source
 * is still the same.
 */
void
photo_add_term (photo_term_t *term, cdr_grid_t *cdr)
{
  int s, ir, iz, itheta;
  int updated[2] = {electrons, photo_ions};
  
  debug (3, "photo_add_term (" photo_printf_str ", " grid_printf_str ")\n",
	 photo_printf_args(term), grid_printf_args(cdr));
    
#pragma omp parallel
    {
#pragma omp for private (ir, iz, s)
      iter_grid_3d_n (cdr, ir, iz, itheta, 2) {
	for (s = 0; s < 2; s++) {
	  RZT (cdr->d_dens[updated[s]], ir, iz, itheta) += 
	    term->A * RZT (cdr->photo, ir, iz, itheta);
	}
      }
    }  
}

/** @brief ...and the recursive version of @a photo_add_term */
void
photo_add_term_r (photo_term_t *term, cdr_grid_t *cdr)
{
  cdr_grid_t *child;

  photo_add_term (term, cdr);

  iter_childs (cdr, child) {
    photo_add_term_r (term, child);
  }
}

/** @brief photo_calc_term QQQQ */
pois_grid_t **
photo_calc_term (photo_term_t *term, cdr_grid_t *cdr, int i)
{
  /* Call to the generic Poisson/Helmholtz solver */
  if (i == 1) {
	return pois_gen_solve_a (cdr, pois_photo_2, photo_mappers, term->lambda);
  } else {
	return pois_gen_solve_a (cdr, pois_photo_1, photo_mappers, term->lambda);
  }
}

/** @brief Calculates the photoionization and adds it to the derivatives
 *  of the species densities. */
void
photo_calc (photo_term_t *terms, cdr_grid_t *cdr)
{
  pois_grid_t **pois_modes;
  photo_term_t *term;
  // photo_term_t *ptr_term;

  photo_copy_source_r (cdr);
  
  if (cdr->ntheta != 1)
    cdr_dft_charge_r (cdr, 1);
  
  // for (ptr_term = terms; ptr_term != NULL; ptr_term = ptr_term->next) {
  //   printf("terms: A=%g lambda=%g ptr=%d\n", ptr_term->A, ptr_term->lambda, (int)ptr_term->next);
  // }

  int j = 0;
  for (term = terms; term; term = term->next ) {
    int i;
    pois_modes = photo_calc_term (term, cdr, j);
    j++;
    if (cdr->ntheta != 1)
      photo_dft_r (cdr, -1);

    photo_add_term_r (term, cdr);
    debug (3, "photo_calc (" photo_printf_str ", " grid_printf_str ")\n",
        	 photo_printf_args(term), grid_printf_args(cdr));

    /* Free the allocated memory. */
    for (i = 0; i < max_ntheta; i++) {      
      pois_free_r (pois_modes[i]);
    }
    free (pois_modes);
  }
}

/** @brief Loads a photoionization file, consisting in a series of rows with
   @a A and @a lambda. */
void
photo_load_file (char *fname)
{
  FILE *fp;
  double A, lambda;
  int c;
  int i;

  printf("\n");
  printf ("Loading photoionization data from `%s'...\n", fname);
  printf("\n");
  fp = fopen (fname, "r");

  if (NULL == fp) {
    warning ("Unable to open photoionization file `%s'\n", fname);
    exit (-1);
    return;
  }

  
  i=0;
  do {
    c = fscanf (fp, "%lf %lf", &A, &lambda);
    if (c != 2) {
      break;
    }

    printf ("Registring photoionization term A = %.5g, lambda = %.4g\n",
	    A, lambda);

    photo_register (A, lambda);
    i++;
  } while (TRUE);
  printf("\n");

  fclose (fp);
}