k-dot-p 0.1

oneoff_optimize_1d.c++ File Reference

#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <glib.h>
#include <gio/gio.h>
#include <gsl/gsl_errno.h>
#include <libmodelxx/matdb.h++>
#include <libmodelxx/matdb-dotcode.h++>
#include <libmodelxx/continuous_structure.h++>
#include <libmodelxx/generic_structure.h++>
#include <libmodelxx/cartesian_grid.h++>
#include <libkdotp/hamiltonians.h++>
#include <libmodelxx/grid.h++>
#include <libmodelxx/material.h++>
#include <libmodelxx/utilities.h++>
#include <libmetacalc/calculation_self_consistent_potential.h++>
#include <libkdotp/wavefunction_cartesian_effective_mass.h++>
#include <libpostproccalx/alpha_calc.h>
#include <libmodelxx/function_specification.h++>
#include <libmetacalc/digital_alloy_optimizer_1d.h++>
#include <libmetacalc/continuous_alloy_optimizer_1d.h++>
#include "oneoff_optimize_1d_argprocess.h++"
Include dependency graph for oneoff_optimize_1d.c++:

Go to the source code of this file.

Classes

struct  set_point_callback_privdat

Typedefs

typedef
kdotp::libmodelxx::grid::cartesian_grid
< kdotp::libmodelxx::structure::material *, 1, 1 > 
matgrid
typedef
kdotp::libmodelxx::grid::cartesian_grid
< double, 1, 1 > 
potgrid

Functions

static void free_value (void *value, void *pridat)
static void delete_double (void *value, void *pridat)
void set_point_callback (unsigned X, const material *mat, void *privdat)
double alpha_efield_change_calculation_callback (void *privdat, unsigned assignment, long unsigned iteration)
double calculate_alpha_for_structure (void *privdat, unsigned assignment, long unsigned iteration)
void write_raw_bands_file (GFile *file, struct generic_structure *genstruct)
void yyparse ()
int yylex ()
static void gsl_error_handler (const char *reason, const char *file, int line, int gsl_errno)
int main (int argc, char **argv)

Variables

int yydebug
struct continuous_structurethe_structure
GInputStream * instream

Typedef Documentation

Definition at line 79 of file oneoff_optimize_1d.c++.


Function Documentation

double alpha_efield_change_calculation_callback ( void *  privdat,
unsigned  assignment,
long unsigned  iteration 
)

Definition at line 382 of file oneoff_optimize_1d.c++.

References set_point_callback_privdat::alpha_by_iteration_file, set_point_callback_privdat::alpha_by_iteration_gos, set_point_callback_privdat::alpha_efield, set_point_callback_privdat::alpha_efield_0field, set_point_callback_privdat::alpha_iface, set_point_callback_privdat::alpha_iface_0field, set_point_callback_privdat::alpha_method2, set_point_callback_privdat::alpha_method2_0field, set_point_callback_privdat::base_job_directory, calculate_alpha_for_structure(), kdp::constants::e, kdotp::libmodelxx::structure::generic_structure::g, kdotp::libmodelxx::structure::generic_structure_free_potential(), set_point_callback_privdat::genstruct, and kdotp::libmodelxx::structure::generic_structure::potential_grid.

Referenced by main().

                                                                                                             {
  struct set_point_callback_privdat* spcp = (struct set_point_callback_privdat*)privdat;
  /*We set the job directory to "with_field/" and "without_field/" for each respective run
    Additionally, we save off the alpha values that are being overwritten.
    Technically, Ep should change (it's an average), but not a lot.
   */
  GFile* original_base_job_dir = spcp->base_job_directory;

  GError* e = NULL;
  void* original_applied_potential = spcp->genstruct->potential_grid;
  if(e != NULL) {
    fprintf(stderr, "ERROR making 0-potential grid: %s\n", e->message);
    g_error_free(e);
    exit(64);
  }
  spcp->genstruct->potential_grid = set_up_grid<double>(spcp->genstruct->g, 0, &e);
  spcp->base_job_directory = g_file_get_child(original_base_job_dir, "without_field");
  calculate_alpha_for_structure(privdat, assignment, iteration);

  generic_structure_free_potential(spcp->genstruct);
  spcp->genstruct->potential_grid = original_applied_potential;
  spcp->alpha_iface_0field = spcp->alpha_iface;
  spcp->alpha_efield_0field = spcp->alpha_efield;
  spcp->alpha_method2_0field = spcp->alpha_method2;
  g_object_unref(spcp->base_job_directory);
  spcp->base_job_directory = g_file_get_child(original_base_job_dir, "with_field");
  calculate_alpha_for_structure(privdat, assignment, iteration);

  g_object_unref(spcp->base_job_directory);
  spcp->base_job_directory = original_base_job_dir;
  /*Now write out the values we got*/
  GString* gs = g_string_new("");
  g_string_append_printf(gs, "%lu\t%g\t%g\t%g", iteration, spcp->alpha_iface + spcp->alpha_efield, spcp->alpha_iface, spcp->alpha_efield);
  g_string_append_printf(gs, "%g\t%g\t%g", spcp->alpha_iface_0field + spcp->alpha_efield_0field, spcp->alpha_iface_0field, spcp->alpha_efield_0field);
  g_string_append_printf(gs, "%g\t%g\t%g", (spcp->alpha_iface - spcp->alpha_iface_0field) + (spcp->alpha_efield - spcp->alpha_efield_0field), spcp->alpha_iface - spcp->alpha_iface_0field, spcp->alpha_efield - spcp->alpha_efield_0field);
  gsize wlen;
  GError *gerr = NULL;
  if(!g_output_stream_write_all(spcp->alpha_by_iteration_gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
    fprintf(stderr, "ERROR writing to alpha_by_iteration file (%s): %s\n", g_file_get_uri(spcp->alpha_by_iteration_file), gerr->message);
    exit(32);
  }
  /*Stopping memory leaks*/
  g_string_free(gs, TRUE);
  /*And return the *difference**/
  return (spcp->alpha_iface - spcp->alpha_iface_0field) + (spcp->alpha_efield - spcp->alpha_efield_0field);
}

Here is the call graph for this function:

Here is the caller graph for this function:

double calculate_alpha_for_structure ( void *  privdat,
unsigned  assignment,
long unsigned  iteration 
)

Bands: 0->CB, 1->HH, 2->SO

Note:
that the bandedge of the HH/LH band includes the potential (previous loop)

Definition at line 429 of file oneoff_optimize_1d.c++.

References set_point_callback_privdat::alpha_by_iteration_file, set_point_callback_privdat::alpha_by_iteration_gos, set_point_callback_privdat::alpha_efield, set_point_callback_privdat::alpha_iface, set_point_callback_privdat::alpha_method2, set_point_callback_privdat::base_job_directory, delete_double(), set_point_callback_privdat::do_nofield_comparison, kdp::constants::e, kdotp::libkdotp::hamiltonian::EC, set_point_callback_privdat::Ep, kdotp::libkdotp::hamiltonian::EPSILON, set_point_callback_privdat::genstruct, kdotp::libkdotp::wavefunction::get_average_with_cartesian_effective_mass_block(), kdotp::libkdotp::wavefunction::get_cartesian_effective_mass_block_max_delta(), kdotp::libkdotp::hamiltonian::HARDWALL, kdotp::libmodelxx::grid::cartesian_grid< T, D, Nc >::L, kdotp::libmodelxx::structure::generic_structure::material_grid, kdotp::libkdotp::hamiltonian::OOMSTAR, kdotp::libmodelxx::structure::generic_structure::potential_grid, set_point_callback_privdat::scpot_calc, kdotp::libkdotp::hamiltonian::TOTAL_POTENTIAL, and write_raw_bands_file().

Referenced by alpha_efield_change_calculation_callback(), and main().

                                                                                                  {
  struct set_point_callback_privdat* spcp = (struct set_point_callback_privdat*)privdat;
  GError *gerr = NULL;
  matgrid *mg = (matgrid*)(spcp->genstruct->material_grid);
  potgrid *pg = (potgrid*)(spcp->genstruct->potential_grid);
  int L = mg->L[0];
  GString *gs=g_string_new("");
  GString *iter_dirname = g_string_new("optimizer_iteration_");
  g_string_append_printf(iter_dirname, "%lu", iteration);
  #ifdef HAVE_MPI
  g_string_append_printf(iter_dirname, "_node_%d_assignment_%u", spcp->node, assignment);
  #endif
  GFile* job_directory = g_file_get_child(spcp->base_job_directory, iter_dirname->str);
  g_string_free(iter_dirname, TRUE);
  /*make the directory and cd into it*/
  g_file_make_directory_with_parents(job_directory, NULL, &gerr);
  if(gerr != NULL) {
    if(gerr->code != G_IO_ERROR_EXISTS) {
      char* fn = g_file_get_uri(job_directory);
      fprintf(stderr, "ERROR creating the target directory for templated job (%s): %s\n", fn, gerr->message);
      g_free(fn);
      exit(5);
    }else{
      /*If the directory already exists, that's OK.*/
      g_error_free(gerr);
      gerr = NULL;
    }
  }
  /*Set the dump to go into this directory.*/
  GFile* dump_file = g_file_get_child(job_directory, "structure.griddump");
  GFile* file = g_file_get_child(job_directory, "bands.pdata");
  write_raw_bands_file(file, spcp->genstruct);
  g_object_unref(file);
  file = NULL;
  gsize wlen;

  double dopant_ierr, potential_ierr, efield_ierr;

  if(spcp->scpot_calc == NULL) {
    /*The goal is to make this not get regenerated on each loop.  The main time-eater, though, is in the potential calculation, so it's not a huge issue*/
    spcp->scpot_calc = new self_consistent_potential< ::kdotp::libkdotp::hamiltonian::cartesian_effective_mass, 1>(spcp->genstruct, ::kdotp::libkdotp::hamiltonian::HARDWALL, get_average_with_cartesian_effective_mass_block, get_cartesian_effective_mass_block_max_delta, 1e6, 1e-14);
  }

  double* eigvals=NULL;
  double* eigvecs=NULL;
  int neigs=0;
  double Ef=0;
  gerr = (spcp->scpot_calc)->perform_calculation(3, 1001, 1e-8, 1, &eigvecs, &eigvals, ::kdotp::libkdotp::hamiltonian::OOMSTAR, ::kdotp::libkdotp::hamiltonian::EPSILON, &Ef, &dopant_ierr, &potential_ierr, &efield_ierr, job_directory, 0.75);
  printf("dopant integration error: %g\npotential integration error: %g\nefield integration error: %g\n", dopant_ierr, potential_ierr, efield_ierr);

  if(gerr != NULL) {
    fprintf(stderr, "ERROR getting eigenvectors of Hamiltonian: %s\n", gerr->message);
  }else{
    printf("Got %d eigenvalues: %g, %g, %g\n", neigs, eigvals[0], eigvals[1], eigvals[2]);
    char fn[1024];
    double sum, val;
    printf("Checking normalization and writing wavefunctions:\n");
    double x;
    for(int j=0; j<3; j++) {
      //sprintf(fn, "eigvec_%g.pdata", eigvals[j]);
      printf("\t%g: ", eigvals[j]);
      g_string_printf(gs, "eigvec_%d.pdata", j);
      file = g_file_get_child(job_directory, gs->str);
      GOutputStream* gos = (GOutputStream*)g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &gerr);
      if(gerr != NULL) {
  fprintf(stderr, "ERROR opening eigenvec %d file (%s): %s\n", j, g_file_get_uri(file), gerr->message);
  exit(32);
      }
      g_string_printf(gs, "#pos(nm)\tpsi\n");
      if(!g_output_stream_write_all(gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
  fprintf(stderr, "ERROR writing to eigvec %d file (%s): %s\n", j, g_file_get_uri(file), gerr->message);
  exit(32);
      }
      sum = 0;
      for(int i=0; i<L; i++) {
  val=eigvecs[i + j*L];
  unsigned X=i;
  (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&X, &x);
  g_string_printf(gs, "%g\t%g\n", x, val);
  if(!g_output_stream_write_all(gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
    fprintf(stderr, "ERROR writing to eigvec %d file (%s): %s\n", j, g_file_get_uri(file), gerr->message);
    exit(32);
  }
  sum += val*val;
      }
      g_object_unref(file);
      if(fabs(1.0-sum) < 1e-8) {
  printf("Normalized (%g)\n", sum);
      }else{
  printf("NON-NORMALIZED (%g)\n", sum);
      }
      g_object_unref(gos);
    }
    printf("################################################################\n");
    printf("################################################################\n");
    printf("## Final output\n");
    printf("################################################################\n");
    printf("################################################################\n");
    printf("Ef=%g\n", Ef);
    struct ::potential pot;
    pot.N = (spcp->scpot_calc)->H->L;
    pot.spacing=(spcp->scpot_calc)->H->dx;

    fprintf(stderr, "pot.x=%p pot.potential=%p H->internal_potential=%p\n", (void*)pot.x, (void*)pot.potential, (void*)(spcp->scpot_calc)->H->internal_potential);
    pot.x = (double*)malloc(sizeof(double)*pot.N);
    pot.potential = (double*)malloc(sizeof(double)*pot.N);
    if((pot.x == NULL) || (pot.potential == NULL)) {
      fprintf(stderr, "ERROR: unable to allocate memory for pot x or bandedge data!\n");
      exit(5);
    }
    fprintf(stderr, "N=%d dx=%g\n", pot.N, pot.spacing);
    for(unsigned int i=0; i<(unsigned int)pot.N; i++) {
      (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&i, &(pot.x[i]));
      fprintf(stderr, "%u/%d: x=%g (&X=%p, &pot.x[%d]=%p(%p/%p))\n", X, i, pot.x[i], (void*)&i, i, (void*)&(pot.x[i]), (void*)pot.x, (void*)(spcp->scpot_calc)->H->internal_potential);
    }
    (spcp->scpot_calc)->H->get_parameter_function(TOTAL_POTENTIAL, pot.potential);
    struct mstar_wavefunction_1d *wf = mstar_wavefunction_1d_new((spcp->scpot_calc)->H->L);
    if(wf == NULL) {
      fprintf(stderr, "ERROR: unable to allocate memory for wavefunction data!\n");
      exit(5);
    }
    for(int i=0; i<wf->N; i++) {
      unsigned int X=i;
      (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&X, &(wf->points[i].x));
      (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&X, &(wf->points[i].x));
      wf->points[i].im=0;
      /*We want the first wavefunction*/
      wf->points[i].re=eigvecs[i];
    }
    /**Bands: 0->CB, 1->HH, 2->SO*/
    struct band bands[3];
    int errnum;
    for(int i=0; i<3; i++) {
      bands[i].N = (spcp->scpot_calc)->H->L;
      bands[i].spacing=(spcp->scpot_calc)->H->dx;
      bands[i].x = (double*)malloc(sizeof(double)*bands[i].N);
      bands[i].bandedge = (double*)malloc(sizeof(double)*bands[i].N);
      if((bands[i].x == NULL) || (bands[i].bandedge == NULL)) {
  fprintf(stderr, "ERROR: unable to allocate memory for pot x or bandedge data!\n");
  exit(5);
      }
      for(unsigned int j=0; j<(unsigned int)bands[i].N; j++) {
  (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&j, &(bands[i].x[j]));
      }
    }
    /*For alpha_calch.h compat, and implying nextnano compat, we add in the potential*/
    /*\note these band edge energies are relative to Ef, for compatibility with alpha_calc (and therefore with nextnano*/
    (spcp->scpot_calc)->H->get_parameter_function(EC, bands[0].bandedge);
    for(unsigned j=0; j<(spcp->scpot_calc)->H->L; j++) {
      /*Add the potential to the CB*/
      bands[0].bandedge[j] += -(pot.potential[j] + Ef);
      /*Set the HH/LH band edge*/
      bands[1].bandedge[j] = (spcp->scpot_calc)->H->matgrid->data[j]->get_property("E_v", &errnum) - pot.potential[j] - Ef;
      if(errnum != 0) fprintf(stderr, "ERROR getting property Ev at gridsite %u: %d\n", j, errnum);
      /*Subtract the Delta from the HH/LH band edge (note: HH/LH includes potential and Ef already)*/
      bands[2].bandedge[j] = bands[1].bandedge[j] - (spcp->scpot_calc)->H->matgrid->data[j]->get_property("Delta", &errnum);
      if(errnum != 0) fprintf(stderr, "ERROR getting property Delta at gridsite %u: %d\n", j, errnum);
      /**\note that the bandedge of the HH/LH band includes the potential (previous loop)*/
    }
    /*Use method 1*/
    /*First, find the ifaces.*/
    GList* ifaces=NULL;
    /*We start at 1, since we compare against the *previous* point*/
    /*While we're going through it, get Ep for the material.*/
    double* Ep_in_structure = new double[(spcp->scpot_calc)->H->L];
    for(unsigned i=1; i<(spcp->scpot_calc)->H->L; i++) {
      if((spcp->scpot_calc)->H->matgrid->data[i-1] != (spcp->scpot_calc)->H->matgrid->data[i]) {
  double *midpoint = new double;
  double x_prev, x_cur;
  unsigned prev=i-1;
  (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&prev, &x_prev);
  (spcp->scpot_calc)->H->matgrid->point_index_to_realspace(&i, &x_cur);
  /*cur and prev are fixed; the interface is halfway between.*/
  *midpoint = x_prev + (x_cur - x_prev)*0.5;
  ifaces = g_list_append(ifaces, midpoint);
  printf("Got interface: %g\n", *midpoint);
      }
      Ep_in_structure[i] = (spcp->scpot_calc)->H->matgrid->data[i]->get_property("E_p", &errnum);
      if(errnum != 0) fprintf(stderr, "ERROR getting property E_p at gridsite %u: %d\n", i, errnum);
    }
    delete[] Ep_in_structure;
    struct alpha_integrand_verificator vf1;
    struct alpha_integrand_verificator_2 vf2;
    double Ep = get_average_with_cartesian_effective_mass_block(eigvecs, 0, (spcp->scpot_calc)->H->L, Ep_in_structure);
    printf("Ep_avg=%g\n", Ep);
    double ierr_alpha, ierr_alpha_m2;
    double alpha_iface = alpha_interface_term_mstar_nostrain(wf, &bands[1], &bands[1], &bands[2], &bands[0], &pot, ifaces, Ep);
    g_list_foreach(ifaces, delete_double, NULL);
    g_list_free(ifaces);
    double alpha_efield = alpha_electric_term_mstar_nostrain(wf, &bands[1], &bands[1], &bands[2], &bands[0], &pot, &vf1, &ierr_alpha, 1e-7, 1e-7, FALSE, Ep);
    double alpha_method2 = alpha_from_del_psi2_nostrain(wf, &bands[1], &bands[1], &bands[2], &bands[0], &pot, &vf2, &ierr_alpha_m2, 1e-7, 1e-7, FALSE, Ep);
    /*Write out the band ifnormation as it'll be passed into alpah_calc.*/
    file = g_file_get_child(job_directory, "bands2.pdata");
    GOutputStream* gos = (GOutputStream*)g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &gerr);
    if(gerr != NULL) {
      fprintf(stderr, "ERROR opening bands2 file (%s): %s\n", g_file_get_uri(file), gerr->message);
      exit(32);
    }
    g_string_printf(gs, "#x(nm)\tcb(eV)\tHH/LH(eV)\tSO(eV)\tpot(eV)\tpsi^2(nm^-1)\n");
    if(!g_output_stream_write_all(gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
      fprintf(stderr, "ERROR writing to bands2 file (%s): %s\n", g_file_get_uri(file), gerr->message);
      exit(32);
    }
    for(int i=0; i<bands[0].N; i++) {
      g_string_printf(gs, "%g\t", bands[0].x[i]);
      for(int j=0; j<3; j++) {
  g_string_append_printf(gs, "%g\t", bands[j].bandedge[i]);
      }
      g_string_append_printf(gs, "%g\n", pot.potential[i]);
      g_string_append_printf(gs, "%g\n", wf->points[i].re*wf->points[i].re);
      g_string_append_printf(gs, "#x(nm)\tcb(eV)\tHH/LH(eV)\tSO(eV)\tpot(eV)\tpsi^2(nm^-1)\n");
      if(!g_output_stream_write_all(gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
  fprintf(stderr, "ERROR writing to bands2 file (%s): %s\n", g_file_get_uri(file), gerr->message);
  exit(32);
      }
    }
    g_object_unref(file);
    g_object_unref(gos);
    spcp->Ep = Ep;
    spcp->alpha_iface = alpha_iface;
    spcp->alpha_efield = alpha_efield;
    spcp->alpha_method2 = alpha_method2;

    GFile* vf1_file = g_file_get_child(job_directory, "alpha_method_1_efield_instrumentation.pdata");
    GFile* vf2_file = g_file_get_child(job_directory, "alpha_method_2_instrumentation.pdata");
    alpha_write_verificator_data(vf1_file, &vf1);
    alpha_write_verificator2_data(vf2_file, &vf2);
    alpha_free_verificator_data(&vf1);
    alpha_free_verificator2_data(&vf2);
    g_object_unref(vf1_file);
    g_object_unref(vf2_file);
    for(int i=0; i<3; i++) {
      free(bands[i].x);
      free(bands[i].bandedge);
    }
    free(pot.potential);
    free(pot.x);
    mstar_wavefunction_1d_free(wf);
    free(eigvecs);
    free(eigvals);
  }
  /*This should go away after I've vetted the spcot class for this use.*/
  delete spcp->scpot_calc;
  spcp->scpot_calc = NULL;
  g_object_unref(dump_file);
  /*If do_nofield_comparison is true, we're being called from another callback, which is writing the values out to the file.*/
  if(!spcp->do_nofield_comparison) {
    gs = g_string_assign(gs, "");
    g_string_append_printf(gs, "%lu\t%g\t%g\t%g\n", iteration, spcp->alpha_iface + spcp->alpha_efield, spcp->alpha_iface, spcp->alpha_efield);
    if(!g_output_stream_write_all(spcp->alpha_by_iteration_gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
      fprintf(stderr, "ERROR writing to alpha_by_iteration file (%s): %s\n", g_file_get_uri(spcp->alpha_by_iteration_file), gerr->message);
      exit(32);
    }
    /*Stopping memory leaks*/
    g_string_free(gs, TRUE);
  }
  return spcp->alpha_iface + spcp->alpha_efield;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void delete_double ( void *  value,
void *  pridat 
) [static]

Definition at line 65 of file oneoff_optimize_1d.c++.

Referenced by calculate_alpha_for_structure().

{delete (double*)value;}

Here is the caller graph for this function:

static void free_value ( void *  value,
void *  pridat 
) [static]

Definition at line 64 of file oneoff_optimize_1d.c++.

{free(value);}
static void gsl_error_handler ( const char *  reason,
const char *  file,
int  line,
int  gsl_errno 
) [static]

Definition at line 103 of file oneoff_optimize_1d.c++.

Referenced by main().

                                                                                                {
  //fprintf(stderr, "GSL error occured in file %s, line %d (%d: %s).  This should be caught by the calling function, or report a bug.\n", file, line, gsl_errno, reason);
}

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

We have the structure set up. Now we need to set up the optimizer.

Note:
that this is used for both set_point and calculate_alpha_for_structure.

Definition at line 107 of file oneoff_optimize_1d.c++.

References kdotp::libmodelxx::postprocessing::add_template_parameters_to_symbol_table(), set_point_callback_privdat::alpha_efield, set_point_callback_privdat::alpha_efield_0field, alpha_efield_change_calculation_callback(), set_point_callback_privdat::alpha_iface, set_point_callback_privdat::alpha_iface_0field, set_point_callback_privdat::alpha_method2, args::assignment_expr, args::assignments, args::blocksize, calculate_alpha_for_structure(), args::continuous, args::do_nofield_comparison, kdotp::libmetacalc::optimizer::digital_alloy_optimizer_1d::do_optimization(), kdotp::libmetacalc::optimizer::digital_alloy_optimizer_1d_mpi::do_optimization(), kdotp::libmetacalc::optimizer::continuous_alloy_optimizer_1d::do_optimization(), kdp::constants::e, set_point_callback_privdat::Ep, args::filestreams, kdotp::libmodelxx::structure::generic_structure_dump(), kdotp::libmodelxx::structure::generic_structure_free(), set_point_callback_privdat::genstruct, kdotp::libmodelxx::postprocessing::get_gfile_directory_for_template_state(), kdotp::libmodelxx::postprocessing::get_header_for_template_state(), kdotp::libmodelxx::postprocessing::get_string_for_template_state(), gsl_error_handler(), kdotp::libmodelxx::structure::insert_external_material(), instream, args::mat0, quikmat::mat1, args::mat1, quikmat::mat2, args::matdb, args::maxx, args::min_stepsize, args::minx, args::multiplier, args::N_blocks, args::N_starting_points, kdotp::libmodelxx::postprocessing::new_symbol_table(), args::optimizer_material, kdotp::libmodelxx::postprocessing::parameter_list_init(), kdotp::libmodelxx::continuous_structure::postprocess_structure(), process_args(), kdotp::libmodelxx::structure::read_matdb_dotcode(), args::seed_value, set_point_callback(), args::stepsize, args::template_parameters, the_structure, kdotp::libmodelxx::postprocessing::update_parameters_plus_check_if_done(), write_raw_bands_file(), quikmat::x, and yyparse().

                                {
  g_type_init();
  #ifdef HAVE_MPI
  MPI_Init(&argc, &argv);
  #endif
  gsl_set_error_handler(&gsl_error_handler);
  //yydebug = 1;
  struct args args;
  int err;
  err = process_args(argc, argv, &args);
  if(err != 0) exit(1);
  fprintf(stderr, "Got minx=%g maxx=%g stepsize=%g multiplier=%g min_stepsize=%g\n", args.minx, args.maxx, args.stepsize, args.multiplier, args.min_stepsize);
  GString *mdb_file = g_string_new(args.matdb);
  struct matdb* mdb = read_matdb_dotcode(mdb_file, &err);
  if(mdb == NULL) {
    fprintf(stderr, "ERROR reading in the materials database %s: %d\n", args.matdb, err); 
    #ifdef HAVE_MPI
    MPI_Finalize();
    #endif
    return 1;
  }

  /*Insert the fake material into the mdb.*/
  ::kdotp::libmodelxx::structure::insert_external_material(mdb, args.optimizer_material);

  GList* l;
  GError* gerr = NULL;
  GString *gs = g_string_new("");
  gsize wlen;
  GHashTable *gst = new_symbol_table();
  GString *alpha_filename = g_string_new("");
  GFile* alpha_file;
  #ifdef HAVE_MPI
  int node;
  int N_nodes;
  MPI_Comm_rank(MPI_COMM_WORLD, &node);
  MPI_Comm_size(MPI_COMM_WORLD, &N_nodes);
  #endif
  for(l=(args.filestreams); l != NULL; l=l->next) {
    parameter_list_init(args.template_parameters);
    alpha_filename = g_string_assign(alpha_filename, ((struct file_info*)(l->data))->filename->str);
    alpha_filename = g_string_append(alpha_filename, "_alpha.pdata");
    alpha_file = g_file_new_for_path(alpha_filename->str);
    g_string_free(alpha_filename, TRUE);
    GOutputStream* alpha_gos = (GOutputStream*)g_file_replace(alpha_file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &gerr);
    if(gerr != NULL) {
      fprintf(stderr, "ERROR opening alpha file (%s): %s\n", g_file_get_uri(alpha_file), gerr->message);
      exit(32);
    }
    g_string_printf(gs, "#");
    char* paramstring;
    g_string_append(gs, paramstring = get_header_for_template_state(args.template_parameters));
    g_free(paramstring);
    g_string_append_printf(gs, "\tstartstruct\tEp\talpha_iface (eVm)\talpha_efield\talpha method 1(eVm)\talpha method2(eVm)\n");
    if(!g_output_stream_write_all(alpha_gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
      fprintf(stderr, "ERROR writing to alpha file (%s): %s\n", g_file_get_uri(alpha_file), gerr->message);
      exit(32);
    }
    gerr = NULL;
    GString *gfn=g_string_new(((struct file_info*)(l->data))->filename->str);
    gfn = g_string_append(gfn, "_output/");
    do {
      add_template_parameters_to_symbol_table(gst, args.template_parameters);
      GFile* file_directory = get_gfile_directory_for_template_state(gfn->str, args.template_parameters);
      g_file_make_directory_with_parents(file_directory, NULL, &gerr);
      if(gerr != NULL) {
  if(gerr->code != G_IO_ERROR_EXISTS) {
    char* fn = g_file_get_uri(file_directory);
    fprintf(stderr, "ERROR creating the target directory for templated job (%s): %s\n", fn, gerr->message);
    g_free(fn);
    exit(5);
  }else{
    /*If the directory already exists, that's OK.*/
    g_error_free(gerr);
    gerr = NULL;
  }
      }
      for(unsigned sstruct=0; sstruct<args.N_starting_points; sstruct++) {
  /*For now, we read in the file over and over.  It's inefficient, but not *that* inefficient.*/
  instream = (GInputStream*)((struct file_info*)(l->data))->instream;
  yyparse();
  if(the_structure == NULL) {
    fprintf(stderr, "the_structure was NULL!\n");
    exit(1);
  }
  struct generic_structure *s = postprocess_structure(the_structure, mdb, gst, &gerr);
  if(gerr != NULL) {
    fprintf(stderr, "ERROR while postprocessing structure: %s\n", gerr->message);
          #ifdef HAVE_MPI
    MPI_Finalize();
          #endif
    return 5;
  }
  fprintf(stderr, "got structure!\n");

  material* markermat = new material(mdb, args.optimizer_material, NULL, 1);
  material* mat1=NULL;
  material* mat0=NULL;
  if(!(args.continuous)) {
    mat1 = new material(mdb, args.mat1.mat1, args.mat1.mat2, args.mat1.x);
    mat0 = new material(mdb, args.mat0.mat1, args.mat0.mat2, args.mat0.x);
  }

  GError *e = NULL;
  /**We have the structure set up.  Now we need to set up the optimizer.
   *\note that this is used for both set_point and calculate_alpha_for_structure.
   */
  GString *iter_dirname = g_string_new("");
  g_string_append_printf(iter_dirname, "%s_optimizer_start_%u", (args.continuous)?"continuous":"digital", sstruct);
  GFile* job_directory = g_file_get_child(file_directory, iter_dirname->str);
  g_string_free(iter_dirname, TRUE);
  g_file_make_directory_with_parents(job_directory, NULL, &gerr);
  if(gerr != NULL) {
    if(gerr->code != G_IO_ERROR_EXISTS) {
      char* fn = g_file_get_uri(job_directory);
      fprintf(stderr, "ERROR creating the target directory for templated job (%s): %s\n", fn, gerr->message);
      g_free(fn);
      exit(5);
    }else{
      /*If the directory already exists, that's OK.*/
      g_error_free(gerr);
      gerr = NULL;
    }
  }
  GString *alpha_by_iter_filename = g_string_new("alpha_sstruct");
  #ifdef HAVE_MPI
  g_string_append_printf(alpha_by_iter_filename, "_node%d", node);
  #endif
  g_string_append_printf(alpha_by_iter_filename, "=%u.pdata", sstruct);
  GFile* alpha_by_iter_file = g_file_get_child(job_directory, alpha_by_iter_filename->str);
  g_string_free(alpha_by_iter_filename, TRUE);
  GOutputStream* alpha_by_iter_gos = (GOutputStream*)g_file_replace(alpha_by_iter_file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &gerr);
  if(gerr != NULL) {
    fprintf(stderr, "ERROR opening alpha_by_iter file (%s): %s\n", g_file_get_uri(alpha_by_iter_file), gerr->message);
    exit(32);
  }
  g_string_printf(gs, "#");
  g_string_append(gs, paramstring = get_header_for_template_state(args.template_parameters));
  g_free(paramstring);
  g_string_append_printf(gs, "iteration\ttotal\tiface\tefield");
  if(args.do_nofield_comparison) {
    g_string_append_printf(gs, "total 0field\tiface 0field\tefield 0field\ttotal difference\tiface difference\tefield difference\n");
  }else{
    gs = g_string_append(gs, "\n");
  }
  if(!g_output_stream_write_all(alpha_by_iter_gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
    fprintf(stderr, "ERROR writing to alpha_by_iteration file (%s): %s\n", g_file_get_uri(alpha_by_iter_file), gerr->message);
    exit(32);
  }

  GFile* dump_file = g_file_get_child(job_directory, "structure.griddump");
  gerr = generic_structure_dump(s, dump_file);
  if(gerr != NULL) {
    fprintf(stderr, "ERROR while dumping structure: %s\n", gerr->message);
          #ifdef HAVE_MPI
    MPI_Finalize();
          #endif
    return 5;
  }
  fprintf(stderr, "got structure!\n");
  struct set_point_callback_privdat spcp = {
    s,
    NULL,
    job_directory,
    alpha_by_iter_gos,
    alpha_by_iter_file,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    args.do_nofield_comparison
    #ifdef HAVE_MPI
    N_nodes,
    node,
    #endif
  };
        #ifdef HAVE_MPI
  digital_alloy_optimizer_1d_mpi* digital_optimizer_mpi=NULL;
        #endif
  digital_alloy_optimizer_1d* optimizer=NULL;
  continuous_alloy_optimizer_1d* continuous_optimizer=NULL;
  if(args.continuous) {
    continuous_optimizer = new continuous_alloy_optimizer_1d(markermat, args.mat1.mat1, args.mat0.mat1, s, &set_point_callback, args.blocksize, continuous_alloy_optimizer_1d::MAXIMIZE_ABS, &e, (void*)&spcp, mdb, args.minx, args.maxx, args.seed_value, args.stepsize, args.N_blocks, args.assignments, args.assignment_expr);
  }else{
          #ifdef HAVE_MPI
    if(args.mpi) {
      digital_optimizer_mpi = new digital_alloy_optimizer_1d_mpi(markermat, mat1, mat0, s, &set_point_callback, args.blocksize, digital_alloy_optimizer_1d_mpi::MAXIMIZE_ABS, &e, (void*)&spcp, N_nodes, node, args.N_blocks, args.seed_value, args.assignments, args.assignment_expr, args.temperature);
    }else{
            #endif
      optimizer = new digital_alloy_optimizer_1d(markermat, mat1, mat0, s, &set_point_callback, args.blocksize, digital_alloy_optimizer_1d::MAXIMIZE_ABS, &e, (void*)&spcp, args.N_blocks, args.seed_value, args.assignments, args.assignment_expr);
      #ifdef HAVE_MPI
    }
            #endif
  }
  if(e != NULL) {
    fprintf(stderr, "ERROR setting up optimizer: %s", e->message);
          #ifdef HAVE_MPI
    MPI_Finalize();
          #endif
    return 102;
  }
  if(args.continuous) {
    e = continuous_optimizer->do_optimization(args.do_nofield_comparison?&alpha_efield_change_calculation_callback:&calculate_alpha_for_structure, (void*)&spcp, (void*)&spcp, args.multiplier, args.min_stepsize);
  }else{
    #ifdef HAVE_MPI
    if(args.mpi) {
      e = digital_optimizer_mpi->do_optimization(args.do_nofield_comparison?&alpha_efield_change_calculation_callback:&calculate_alpha_for_structure, (void*)&spcp, (void*)&spcp, args.anneal_start, args.anneal_end, args.num_anneal_steps, args.anneal_cycles, args.calculation_steps_per_annealing_step);
    }else{
      #endif
      e = optimizer->do_optimization(args.do_nofield_comparison?&alpha_efield_change_calculation_callback:&calculate_alpha_for_structure, (void*)&spcp, (void*)&spcp);
      #ifdef HAVE_MPI
    }
            #endif
  }
  if(e != NULL) {
    fprintf(stderr, "ERROR running optimizer: %s", e->message);
          #ifdef HAVE_MPI
    MPI_Finalize();
          #endif
    return 103;
  }
  gs = g_string_assign(gs, paramstring=get_string_for_template_state(args.template_parameters));
  g_free(paramstring);
  g_string_append_printf(gs, "\t%u\t%g\t%g\t%g\t%g\t%g", sstruct, spcp.Ep, spcp.alpha_iface, spcp.alpha_efield, spcp.alpha_iface + spcp.alpha_efield, spcp.alpha_method2);
  if(args.do_nofield_comparison) {
    g_string_append_printf(gs, "\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n", spcp.alpha_iface_0field, spcp.alpha_efield_0field, spcp.alpha_iface_0field + spcp.alpha_efield_0field, spcp.alpha_method2, spcp.alpha_iface - spcp.alpha_iface_0field, spcp.alpha_efield - spcp.alpha_efield_0field, (spcp.alpha_iface - spcp.alpha_iface_0field) + (spcp.alpha_efield - spcp.alpha_efield_0field));
  }else{
    gs = g_string_append(gs, "\n");
  }
  if(!g_output_stream_write_all(alpha_gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
    fprintf(stderr, "ERROR writing to alpha file (%s): %s\n", g_file_get_uri(alpha_file), gerr->message);
    exit(32);
  }
  dump_file = g_file_get_child(job_directory, "final-structure.griddump");
  gerr = generic_structure_dump(s, dump_file);
  if(gerr != NULL) {
    fprintf(stderr, "ERROR while dumping structure: %s\n", gerr->message);
          #ifdef HAVE_MPI
    MPI_Finalize();
          #endif
    return 5;
  }
  GFile* file = g_file_get_child(job_directory, "final-bands.pdata");
  write_raw_bands_file(file, spcp.genstruct);
  if(args.continuous) {
    delete continuous_optimizer;
  }else{
    delete optimizer;
  }
  g_object_unref(alpha_by_iter_gos);
  g_object_unref(alpha_by_iter_file);
  generic_structure_free(s);
      }
      g_object_unref(file_directory);
    }while(!update_parameters_plus_check_if_done(args.template_parameters));
    g_string_free(gfn, TRUE);
    g_object_unref(alpha_gos);
    g_object_unref(alpha_file);
  }
  #ifdef HAVE_MPI
  MPI_Finalize();
  #endif
  return 0;
}

Here is the call graph for this function:

void set_point_callback ( unsigned  X,
const material mat,
void *  privdat 
)

Note:
that it'll likely be faster to introduce a special routine to just change the nearest neighbors of this point.

Definition at line 375 of file oneoff_optimize_1d.c++.

References set_point_callback_privdat::scpot_calc.

Referenced by main().

                                                                        {
  struct set_point_callback_privdat* spcp = (struct set_point_callback_privdat*)privdat;
  /*We don't need to do anything if we've not yet set up the calculation (and therefore also not the hamiltonian).*/
  if(spcp->scpot_calc == NULL) return;
  /**\note that it'll likely be faster to introduce a special routine to just change the nearest neighbors of this point.*/
}

Here is the caller graph for this function:

void write_raw_bands_file ( GFile *  file,
struct generic_structure genstruct 
)

Definition at line 688 of file oneoff_optimize_1d.c++.

References kdotp::libmodelxx::grid::cartesian_grid< T, D, Nc >::data, kdp::constants::e, kdotp::libmodelxx::grid::cartesian_grid< T, D, Nc >::L, kdotp::libmodelxx::structure::generic_structure::material_grid, kdotp::libmodelxx::grid::cartesian_grid< T, D, Nc >::point_index_to_realspace(), and kdotp::libmodelxx::structure::generic_structure::potential_grid.

Referenced by calculate_alpha_for_structure(), and main().

                                                                            {
  matgrid *mg = (matgrid*)(genstruct->material_grid);
  potgrid *pg = (potgrid*)(genstruct->potential_grid);
  GString *gs = g_string_new("");
  gsize wlen;
  int L = mg->L[0];
  GError *gerr = NULL;
  GOutputStream* gos = (GOutputStream*)g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &gerr);
  if(gerr != NULL) {
    fprintf(stderr, "ERROR opening bands file (%s): %s\n", g_file_get_uri(file), gerr->message);
    exit(32);
  }
  g_string_printf(gs, "#pos(nm)\tCB\tHH/LH\tSO\tPotential\n");
  if(!g_output_stream_write_all(gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
    fprintf(stderr, "ERROR writing to bands file (%s): %s\n", g_file_get_uri(file), gerr->message);
    exit(32);
  }
  double x;
  int e;
  for(int i=0; i<L; i++) {
    e=0;
    double Eg = mg->data[i]->get_property("E_g_Gamma", &e);
    if(e != 0) fprintf(stderr, "ERROR: got error %d for property E_g_Gamma\n", e);
    e=0;
    double Ev = mg->data[i]->get_property("E_v", &e);
    if(e != 0) fprintf(stderr, "ERROR: got error %d for property E_v\n", e);
    e=0;
    double Delta = mg->data[i]->get_property("Delta", &e);
    if(e != 0) fprintf(stderr, "ERROR: got error %d for property Delta\n", e);
    unsigned X=i;
    mg->point_index_to_realspace(&X, &x);
    g_string_printf(gs, "%g\t%g\t%g\t%g\t%g\n", x, Eg+Ev, Ev, Ev-Delta, pg->data[i]);
    if(!g_output_stream_write_all(gos, gs->str, gs->len, &wlen, NULL, &gerr)) {
      fprintf(stderr, "ERROR writing to bands file (%s): %s\n", g_file_get_uri(file), gerr->message);
      exit(32);
    }
  }
  g_object_unref(gos);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int yylex ( )
void yyparse ( )

Definition at line 1416 of file structspec_parser.c++.

References kdotp::libmodelxx::grid::AND, kdotp::libmodelxx::grid::grid::box_size, kdp::constants::c, kdotp::libmodelxx::postprocessing::CONST, kdotp::libmodelxx::continuous_structure::convert_energy_to_hartree(), kdotp::libmodelxx::continuous_structure::convert_length_to_nm(), kdotp::libmodelxx::postprocessing::CROSS, kdotp::libmodelxx::grid::value::d, kdotp::libmodelxx::grid::shape::descriptor, kdotp::libmodelxx::grid::grid::dimensions, kdotp::libmodelxx::postprocessing::DIV, YYSTYPE::doping, kdotp::libmodelxx::continuous_structure::continuous_structure::dopings, kdotp::libmodelxx::postprocessing::DOT, kdotp::libmodelxx::continuous_structure::potential::E, YYSTYPE::energy, kdotp::libmodelxx::continuous_structure::potential::Evec, YYSTYPE::exp, kdotp::libmodelxx::continuous_structure::doping::f, kdotp::libmodelxx::continuous_structure::region::f, YYLTYPE::first_column, YYLTYPE::first_line, kdotp::libmodelxx::grid::FLOAT, kdotp::libmodelxx::continuous_structure::potential::function, kdotp::libmodelxx::postprocessing::function_print_tree(), YYSTYPE::fval, kdotp::libmodelxx::continuous_structure::continuous_structure::g, YYSTYPE::g, g, kdotp::libmodelxx::grid::shape::generic, kdotp::libmodelxx::grid::get_shape_from_identifier(), kdotp::libmodelxx::grid::get_string_from_shape_type(), kdotp::libmodelxx::grid::GLOBAL, YYSTYPE::gt, kdotp::libmodelxx::grid::INVALID, YYSTYPE::ival, kdotp::libmodelxx::grid::key_value::key, kdotp::libmodelxx::continuous_structure::doping::key_values, kdotp::libmodelxx::continuous_structure::continuous_structure::key_values, kdotp::libmodelxx::grid::grid::key_values, kv, YYSTYPE::kvu, kdotp::libmodelxx::grid::shape_tree::l, kdotp::libmodelxx::grid::value::l, YYLTYPE::last_column, YYLTYPE::last_line, kdotp::libmodelxx::grid::LEAF, YYSTYPE::len, YYSTYPE::list, kdotp::libmodelxx::continuous_structure::region::mat1, kdotp::libmodelxx::continuous_structure::region::mat2, kdotp::libmodelxx::postprocessing::MINUS, kdotp::libmodelxx::postprocessing::MUL, kdotp::libmodelxx::postprocessing::NEG, new_double(), new_fx(), new_fx_const(), new_fx_const_single(), new_fx_func(), new_fx_symbol(), new_int(), kdotp::libmodelxx::grid::NOT, kdotp::libmodelxx::grid::shape::op, kdotp::libmodelxx::grid::shape_tree::op, kdotp::libmodelxx::grid::OR, kdotp::libmodelxx::postprocessing::PLUS, YYSTYPE::potential, kdotp::libmodelxx::continuous_structure::continuous_structure::potential, kdotp::libmodelxx::grid::shape_tree::r, YYSTYPE::region, kdotp::libmodelxx::continuous_structure::continuous_structure::regions, kdotp::libmodelxx::grid::value::s, YYSTYPE::s, kdotp::libmodelxx::grid::grid::site_length, kdotp::libmodelxx::continuous_structure::doping::st, str, YYSTYPE::str, YYSTYPE::stree, kdotp::libmodelxx::grid::STRING, kdotp::libmodelxx::grid::key_value::t, kdotp::libmodelxx::grid::grid::t, the_structure, kdotp::libmodelxx::grid::shape::type, kdotp::libmodelxx::grid::key_value::value, kdotp::libmodelxx::grid::VECTOR, kdotp::libmodelxx::grid::VECTOR_SET, kdotp::libmodelxx::continuous_structure::region::x, kdotp::libmodelxx::grid::XOR, YY_, YY_REDUCE_PRINT, YY_STACK_PRINT, YY_SYMBOL_PRINT, YYABORT, YYACCEPT, yyalloc(), yycheck, yydefact, yydefgoto, yydestruct(), YYDPRINTF, YYEMPTY, YYEOF, yyerror(), YYFINAL, YYID, YYINITDEPTH, YYLAST, YYLEX, yylloc, YYLLOC_DEFAULT, yyalloc::yyls_alloc, yylsp, yylval, YYMAXDEPTH, yynerrs, YYNTOKENS, yypact, YYPACT_NINF, yypgoto, YYPOPSTACK, yyr1, yyr2, YYSIZE_T, yyalloc::yyss_alloc, YYSTACK_ALLOC, YYSTACK_ALLOC_MAXIMUM, YYSTACK_BYTES, YYSTACK_FREE, YYSTACK_RELOCATE, yystos, yytable, YYTABLE_NINF, YYTERROR, YYTRANSLATE, and yyalloc::yyvs_alloc.

{


    int yystate;
    /* Number of tokens to shift before error messages enabled.  */
    int yyerrstatus;

    /* The stacks and their tools:
       `yyss': related to states.
       `yyvs': related to semantic values.
       `yyls': related to locations.

       Refer to the stacks thru separate pointers, to allow yyoverflow
       to reallocate them elsewhere.  */

    /* The state stack.  */
    yytype_int16 yyssa[YYINITDEPTH];
    yytype_int16 *yyss;
    yytype_int16 *yyssp;

    /* The semantic value stack.  */
    YYSTYPE yyvsa[YYINITDEPTH];
    YYSTYPE *yyvs;
    YYSTYPE *yyvsp;

    /* The location stack.  */
    YYLTYPE yylsa[YYINITDEPTH];
    YYLTYPE *yyls;
    YYLTYPE *yylsp;

    /* The locations where the error started and ended.  */
    YYLTYPE yyerror_range[2];

    YYSIZE_T yystacksize;

  int yyn;
  int yyresult;
  /* Lookahead token as an internal (translated) token number.  */
  int yytoken;
  /* The variables used to return semantic value and location from the
     action routines.  */
  YYSTYPE yyval;
  YYLTYPE yyloc;

#if YYERROR_VERBOSE
  /* Buffer for error messages, and its allocated size.  */
  char yymsgbuf[128];
  char *yymsg = yymsgbuf;
  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif

#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))

  /* The number of symbols on the RHS of the reduced rule.
     Keep to zero when no symbol should be popped.  */
  int yylen = 0;

  yytoken = 0;
  yyss = yyssa;
  yyvs = yyvsa;
  yyls = yylsa;
  yystacksize = YYINITDEPTH;

  YYDPRINTF ((stderr, "Starting parse\n"));

  yystate = 0;
  yyerrstatus = 0;
  yynerrs = 0;
  yychar = YYEMPTY; /* Cause a token to be read.  */

  /* Initialize stack pointers.
     Waste one element of value and location stack
     so that they stay on the same level as the state stack.
     The wasted elements are never initialized.  */
  yyssp = yyss;
  yyvsp = yyvs;
  yylsp = yyls;

#if YYLTYPE_IS_TRIVIAL
  /* Initialize the default location before parsing starts.  */
  yylloc.first_line   = yylloc.last_line   = 1;
  yylloc.first_column = yylloc.last_column = 1;
#endif

  goto yysetstate;

/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate.  |
`------------------------------------------------------------*/
 yynewstate:
  /* In all cases, when you get here, the value and location stacks
     have just been pushed.  So pushing a state here evens the stacks.  */
  yyssp++;

 yysetstate:
  *yyssp = yystate;

  if (yyss + yystacksize - 1 <= yyssp)
    {
      /* Get the current used size of the three stacks, in elements.  */
      YYSIZE_T yysize = yyssp - yyss + 1;

#ifdef yyoverflow
      {
  /* Give user a chance to reallocate the stack.  Use copies of
     these so that the &'s don't force the real ones into
     memory.  */
  YYSTYPE *yyvs1 = yyvs;
  yytype_int16 *yyss1 = yyss;
  YYLTYPE *yyls1 = yyls;

  /* Each stack pointer address is followed by the size of the
     data in use in that stack, in bytes.  This used to be a
     conditional around just the two extra args, but that might
     be undefined if yyoverflow is a macro.  */
  yyoverflow (YY_("memory exhausted"),
        &yyss1, yysize * sizeof (*yyssp),
        &yyvs1, yysize * sizeof (*yyvsp),
        &yyls1, yysize * sizeof (*yylsp),
        &yystacksize);

  yyls = yyls1;
  yyss = yyss1;
  yyvs = yyvs1;
      }
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
      goto yyexhaustedlab;
# else
      /* Extend the stack our own way.  */
      if (YYMAXDEPTH <= yystacksize)
  goto yyexhaustedlab;
      yystacksize *= 2;
      if (YYMAXDEPTH < yystacksize)
  yystacksize = YYMAXDEPTH;

      {
  yytype_int16 *yyss1 = yyss;
  union yyalloc *yyptr =
    (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
  if (! yyptr)
    goto yyexhaustedlab;
  YYSTACK_RELOCATE (yyss_alloc, yyss);
  YYSTACK_RELOCATE (yyvs_alloc, yyvs);
  YYSTACK_RELOCATE (yyls_alloc, yyls);
#  undef YYSTACK_RELOCATE
  if (yyss1 != yyssa)
    YYSTACK_FREE (yyss1);
      }
# endif
#endif /* no yyoverflow */

      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;
      yylsp = yyls + yysize - 1;

      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
      (unsigned long int) yystacksize));

      if (yyss + yystacksize - 1 <= yyssp)
  YYABORT;
    }

  YYDPRINTF ((stderr, "Entering state %d\n", yystate));

  if (yystate == YYFINAL)
    YYACCEPT;

  goto yybackup;

/*-----------.
| yybackup.  |
`-----------*/
yybackup:

  /* Do appropriate processing given the current state.  Read a
     lookahead token if we need one and don't already have one.  */

  /* First try to decide what to do without reference to lookahead token.  */
  yyn = yypact[yystate];
  if (yyn == YYPACT_NINF)
    goto yydefault;

  /* Not known => get a lookahead token if don't already have one.  */

  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
  if (yychar == YYEMPTY)
    {
      YYDPRINTF ((stderr, "Reading a token: "));
      yychar = YYLEX;
    }

  if (yychar <= YYEOF)
    {
      yychar = yytoken = YYEOF;
      YYDPRINTF ((stderr, "Now at end of input.\n"));
    }
  else
    {
      yytoken = YYTRANSLATE (yychar);
      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
    }

  /* If the proper action on seeing token YYTOKEN is to reduce or to
     detect an error, take that action.  */
  yyn += yytoken;
  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (yyn == 0 || yyn == YYTABLE_NINF)
  goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }

  /* Count tokens shifted since error; after three, turn off error
     status.  */
  if (yyerrstatus)
    yyerrstatus--;

  /* Shift the lookahead token.  */
  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);

  /* Discard the shifted token.  */
  yychar = YYEMPTY;

  yystate = yyn;
  *++yyvsp = yylval;
  *++yylsp = yylloc;
  goto yynewstate;


/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state.  |
`-----------------------------------------------------------*/
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;


/*-----------------------------.
| yyreduce -- Do a reduction.  |
`-----------------------------*/
yyreduce:
  /* yyn is the number of a rule to reduce with.  */
  yylen = yyr2[yyn];

  /* If YYLEN is nonzero, implement the default value of the action:
     `$$ = $1'.

     Otherwise, the following line sets YYVAL to garbage.
     This behavior is undocumented and Bison
     users should not rely upon it.  Assigning to YYVAL
     unconditionally makes the parser a bit smaller, and it avoids a
     GCC warning that YYVAL may be used uninitialized.  */
  yyval = yyvsp[1-yylen];

  /* Default location.  */
  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
  YY_REDUCE_PRINT (yyn);
  switch (yyn)
    {
        case 2:

/* Line 1455 of yacc.c  */
#line 184 "structspec_parser.y++"
    {
  /*Note that grid info was stored in the structure when it was all read in*/
  the_structure = (yyvsp[(2) - (2)].s);
}
    break;

  case 3:

/* Line 1455 of yacc.c  */
#line 189 "structspec_parser.y++"
    {
  g = (struct grid*)malloc(sizeof(struct grid));
  g->t = (yyvsp[(3) - (13)].gt);
  g->dimensions = (yyvsp[(5) - (13)].ival);
  g->box_size = (yyvsp[(7) - (13)].list);
  g->site_length = (yyvsp[(9) - (13)].list);
  g->key_values = (yyvsp[(12) - (13)].list); 
  (yyval.g) = g;
}
    break;

  case 4:

/* Line 1455 of yacc.c  */
#line 199 "structspec_parser.y++"
    {
  struct continuous_structure *s = (struct continuous_structure*)malloc(sizeof(struct continuous_structure));
  s->key_values = (yyvsp[(3) - (7)].list);
  s->regions = (yyvsp[(4) - (7)].list);
  s->dopings = (yyvsp[(5) - (7)].list);
  s->potential = (yyvsp[(6) - (7)].list);
  s->g = g;
  (yyval.s) = s;
}
    break;

  case 5:

/* Line 1455 of yacc.c  */
#line 209 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 6:

/* Line 1455 of yacc.c  */
#line 210 "structspec_parser.y++"
    {
  (yyval.list) = g_list_append((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].potential));
}
    break;

  case 7:

/* Line 1455 of yacc.c  */
#line 214 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 8:

/* Line 1455 of yacc.c  */
#line 215 "structspec_parser.y++"
    {
  (yyval.list) = g_list_append((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].doping));
}
    break;

  case 9:

/* Line 1455 of yacc.c  */
#line 219 "structspec_parser.y++"
    {
  ((yyvsp[(3) - (9)].doping))->key_values = (yyvsp[(8) - (9)].list);
  ((yyvsp[(3) - (9)].doping))->st = (yyvsp[(5) - (9)].stree);
  (yyval.doping) = (yyvsp[(3) - (9)].doping);
}
    break;

  case 10:

/* Line 1455 of yacc.c  */
#line 225 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 11:

/* Line 1455 of yacc.c  */
#line 226 "structspec_parser.y++"
    {
  (yyval.list) = g_list_append((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].region));
}
    break;

  case 12:

/* Line 1455 of yacc.c  */
#line 230 "structspec_parser.y++"
    {
  ((yyvsp[(3) - (9)].region))->key_values = (yyvsp[(8) - (9)].list);
  ((yyvsp[(3) - (9)].region))->st = (yyvsp[(5) - (9)].stree);
  (yyval.region) = (yyvsp[(3) - (9)].region);
}
    break;

  case 13:

/* Line 1455 of yacc.c  */
#line 237 "structspec_parser.y++"
    {
  struct region *r = (struct region*)malloc(sizeof(struct region));
  r->mat1 = (yyvsp[(1) - (1)].str);
  r->mat2 = NULL;
  r->x = 1.0;
  r->f = NULL;
  (yyval.region) = r;
}
    break;

  case 14:

/* Line 1455 of yacc.c  */
#line 245 "structspec_parser.y++"
    {
  struct region *r = (struct region*)malloc(sizeof(struct region));
  r->mat1 = (yyvsp[(1) - (5)].str);
  r->mat2 = (yyvsp[(5) - (5)].str);
  r->f = (yyvsp[(3) - (5)].exp);
  /*Check if this is just a const; if it is, do it instead of a full-on function evaluation (much faster).*/
  if((yyvsp[(3) - (5)].exp)->op == kdotp::libmodelxx::postprocessing::CONST) {
    /*Make sure this is a scalar.*/
    if(((struct function_const*)r->f)->t == 1) {
      r->x = ((struct function_const*)r->f)->value[0];
    free(r->f);
    /*Flag this as not being in use.*/
    r->f = NULL;
    if(((r->x) < 0.0) || ((r->x) > 1.0)) {fprintf(stderr, "ERROR: material specification %s(%f)%s is invalid; %f is not in range [0,1]\n", (yyvsp[(1) - (5)].str), r->x, (yyvsp[(5) - (5)].str), r->x);}
    }
  }
  (yyval.region) = r;
}
    break;

  case 15:

/* Line 1455 of yacc.c  */
#line 280 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 16:

/* Line 1455 of yacc.c  */
#line 281 "structspec_parser.y++"
    {(yyval.list) = g_list_append((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].kvu));}
    break;

  case 17:

/* Line 1455 of yacc.c  */
#line 290 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 18:

/* Line 1455 of yacc.c  */
#line 291 "structspec_parser.y++"
    {(yyval.list) = (yyvsp[(1) - (1)].list);}
    break;

  case 19:

/* Line 1455 of yacc.c  */
#line 293 "structspec_parser.y++"
    {
    (yyval.list) = g_list_append((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].exp));
    GString *s = g_string_new("");
    function_print_tree((yyvsp[(3) - (3)].exp), &s, 1);
    fprintf(stderr, "***appending to fx_list: \n%s***\n", s->str);
    g_string_free(s, TRUE);
}
    break;

  case 20:

/* Line 1455 of yacc.c  */
#line 300 "structspec_parser.y++"
    {
  (yyval.list) = g_list_append(NULL, (yyvsp[(1) - (1)].exp));
  GString *s = g_string_new("");
  function_print_tree((yyvsp[(1) - (1)].exp), &s, 1);
  fprintf(stderr, "***creating new fx_list: \n%s***\n", s->str);
  g_string_free(s, TRUE);
}
    break;

  case 21:

/* Line 1455 of yacc.c  */
#line 308 "structspec_parser.y++"
    {((yyvsp[(3) - (4)].kvu))->key = ((yyvsp[(1) - (4)].str)); (yyval.kvu)=(yyvsp[(3) - (4)].kvu);}
    break;

  case 22:

/* Line 1455 of yacc.c  */
#line 309 "structspec_parser.y++"
    {kv=(struct key_value*)malloc(sizeof(struct key_value)); kv->key = NULL; kv->value.s = (yyvsp[(1) - (1)].str);  kv->t = STRING; (yyval.kvu)=kv;}
    break;

  case 23:

/* Line 1455 of yacc.c  */
#line 310 "structspec_parser.y++"
    {kv=(struct key_value*)malloc(sizeof(struct key_value)); kv->key = NULL; kv->value.s = (yyvsp[(1) - (1)].str); kv->t = STRING; (yyval.kvu)=kv;}
    break;

  case 24:

/* Line 1455 of yacc.c  */
#line 311 "structspec_parser.y++"
    {kv=(struct key_value*)malloc(sizeof(struct key_value)); kv->key =NULL; kv->value.d = (yyvsp[(1) - (1)].fval);  kv->t = FLOAT; (yyval.kvu)=kv;}
    break;

  case 25:

/* Line 1455 of yacc.c  */
#line 312 "structspec_parser.y++"
    {kv=(struct key_value*)malloc(sizeof(struct key_value)); kv->key = NULL; kv->value.l = (yyvsp[(1) - (1)].list);  kv->t = VECTOR; (yyval.kvu)=kv;}
    break;

  case 26:

/* Line 1455 of yacc.c  */
#line 313 "structspec_parser.y++"
    {kv=(struct key_value*)malloc(sizeof(struct key_value)); kv->key = NULL; kv->value.l = (yyvsp[(1) - (1)].list);  kv->t = VECTOR_SET; (yyval.kvu)=kv;}
    break;

  case 27:

/* Line 1455 of yacc.c  */
#line 315 "structspec_parser.y++"
    {
  struct shape_tree *st = (struct shape_tree*) malloc(sizeof(struct shape_tree));
  st->l = (yyvsp[(1) - (3)].stree);
  st->r = (yyvsp[(3) - (3)].stree);
  st->op = ::kdotp::libmodelxx::grid::AND;
  (yyval.stree) = st;
}
    break;

  case 28:

/* Line 1455 of yacc.c  */
#line 322 "structspec_parser.y++"
    {
  struct shape_tree* st = (struct shape_tree*) malloc(sizeof(struct shape_tree));
  st->l = (yyvsp[(1) - (3)].stree);
  st->r = (yyvsp[(3) - (3)].stree);
  st->op = ::kdotp::libmodelxx::grid::OR;
  (yyval.stree) = st;
}
    break;

  case 29:

/* Line 1455 of yacc.c  */
#line 329 "structspec_parser.y++"
    {
  struct shape_tree* st = (struct shape_tree*) malloc(sizeof(struct shape_tree));
  st->l = (yyvsp[(2) - (2)].stree);
  st->r = NULL;
  st->op = ::kdotp::libmodelxx::grid::NOT;
  (yyval.stree) = st;
}
    break;

  case 30:

/* Line 1455 of yacc.c  */
#line 336 "structspec_parser.y++"
    {
  struct shape_tree* st = (struct shape_tree*) malloc(sizeof(struct shape_tree));
  st->l = (yyvsp[(1) - (3)].stree);
  st->r = (yyvsp[(3) - (3)].stree);
  st->op = ::kdotp::libmodelxx::grid::XOR;
  (yyval.stree) = st;
}
    break;

  case 31:

/* Line 1455 of yacc.c  */
#line 343 "structspec_parser.y++"
    {(yyval.stree) = (yyvsp[(2) - (3)].stree);}
    break;

  case 32:

/* Line 1455 of yacc.c  */
#line 344 "structspec_parser.y++"
    {
  struct shape *s = (struct shape*)malloc(sizeof(struct shape));
  s->type = get_shape_from_identifier((yyvsp[(1) - (4)].str));
  s->op = kdotp::libmodelxx::grid::LEAF;
  if(s->type == ::kdotp::libmodelxx::grid::INVALID) {
    fprintf(stderr, "ERROR: shape identifier (%s) is invalid!\n", ((yyvsp[(1) - (4)].str)));
    exit(5);
  }        
  char* c = NULL;
  get_string_from_shape_type(&c, s->type);
  fprintf(stderr, "A: Got shape type %s\n", c);
  g_free(c);
  s->descriptor = (yyvsp[(3) - (4)].list);
  s->generic = true;
  (yyval.stree) = (struct shape_tree*)s;
}
    break;

  case 33:

/* Line 1455 of yacc.c  */
#line 360 "structspec_parser.y++"
    {
  struct shape *s = (struct shape*)malloc(sizeof(struct shape));
  s->op = kdotp::libmodelxx::grid::LEAF;
  s->type = get_shape_from_identifier((yyvsp[(1) - (1)].str));
  if(s->type == ::kdotp::libmodelxx::grid::INVALID) {
    fprintf(stderr, "ERROR: shape identifier (%s) is invalid!\n", ((yyvsp[(1) - (1)].str)));
    exit(5);
  }        
  if(s->type != ::kdotp::libmodelxx::grid::GLOBAL) {
    fprintf(stderr, "ERROR: shape (%s) is invalid (only the global shape does not need an argument)\n", ((yyvsp[(1) - (1)].str)));
    exit(5);
  }        
  char* c = NULL;
  get_string_from_shape_type(&c, s->type);
  fprintf(stderr, "B: Got shape type %s\n", c);
  g_free(c);
  s->descriptor = NULL; 
  s->generic = true;
  (yyval.stree) = (struct shape_tree*)s;
}
    break;

  case 34:

/* Line 1455 of yacc.c  */
#line 380 "structspec_parser.y++"
    {(yyval.list) = (yyvsp[(2) - (3)].list);}
    break;

  case 35:

/* Line 1455 of yacc.c  */
#line 382 "structspec_parser.y++"
    {(yyval.list) = g_list_append((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));}
    break;

  case 36:

/* Line 1455 of yacc.c  */
#line 383 "structspec_parser.y++"
    {(yyval.list) = g_list_append(NULL, (yyvsp[(1) - (1)].list));}
    break;

  case 37:

/* Line 1455 of yacc.c  */
#line 385 "structspec_parser.y++"
    {(yyval.list) = (yyvsp[(2) - (3)].list);}
    break;

  case 38:

/* Line 1455 of yacc.c  */
#line 387 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 39:

/* Line 1455 of yacc.c  */
#line 388 "structspec_parser.y++"
    {(yyval.list) = g_list_append((yyvsp[(1) - (3)].list), new_double((yyvsp[(3) - (3)].fval)));}
    break;

  case 40:

/* Line 1455 of yacc.c  */
#line 389 "structspec_parser.y++"
    {(yyval.list) = g_list_append(NULL, new_double((yyvsp[(1) - (1)].fval)));}
    break;

  case 41:

/* Line 1455 of yacc.c  */
#line 391 "structspec_parser.y++"
    {
  (yyval.list) = (yyvsp[(2) - (3)].list);
}
    break;

  case 42:

/* Line 1455 of yacc.c  */
#line 395 "structspec_parser.y++"
    {(yyval.list) = NULL;}
    break;

  case 43:

/* Line 1455 of yacc.c  */
#line 396 "structspec_parser.y++"
    {(yyval.list) = g_list_append((yyvsp[(1) - (3)].list), new_int((yyvsp[(3) - (3)].ival)));}
    break;

  case 44:

/* Line 1455 of yacc.c  */
#line 397 "structspec_parser.y++"
    {(yyval.list) = g_list_append(NULL, new_int((yyvsp[(1) - (1)].ival)));}
    break;

  case 45:

/* Line 1455 of yacc.c  */
#line 399 "structspec_parser.y++"
    {(yyval.fval) = convert_length_to_nm((yyvsp[(1) - (2)].fval), (yyvsp[(2) - (2)].len));}
    break;

  case 46:

/* Line 1455 of yacc.c  */
#line 400 "structspec_parser.y++"
    {(yyval.fval) = convert_energy_to_hartree((yyvsp[(1) - (2)].fval), (yyvsp[(2) - (2)].energy));}
    break;

  case 47:

/* Line 1455 of yacc.c  */
#line 401 "structspec_parser.y++"
    {fprintf(stderr, "structspec PARSER WARNING: float %g presented without units where a float with units is expected; you should specify your units!\n", (yyvsp[(1) - (1)].fval)); (yyval.fval) = (yyvsp[(1) - (1)].fval);}
    break;

  case 48:

/* Line 1455 of yacc.c  */
#line 402 "structspec_parser.y++"
    {(yyval.fval) = convert_length_to_nm((double)(yyvsp[(1) - (2)].ival), (yyvsp[(2) - (2)].len));}
    break;

  case 49:

/* Line 1455 of yacc.c  */
#line 403 "structspec_parser.y++"
    {(yyval.fval) = convert_energy_to_hartree((double)(yyvsp[(1) - (2)].ival), (yyvsp[(2) - (2)].energy));}
    break;

  case 50:

/* Line 1455 of yacc.c  */
#line 404 "structspec_parser.y++"
    {fprintf(stderr, "structspec PARSER WARNING: integer %d presented without units where a float with units is expected; you should specify your units!\n", (yyvsp[(1) - (1)].ival)); (yyval.fval) = (double)(yyvsp[(1) - (1)].ival);}
    break;

  case 51:

/* Line 1455 of yacc.c  */
#line 406 "structspec_parser.y++"
    {
  struct doping* doping = (struct doping*)malloc(sizeof(struct doping));
  g_assert(doping != NULL);
  doping->f = (yyvsp[(1) - (1)].exp);
  doping->st = NULL;
  doping->key_values = NULL;
  (yyval.doping) = doping;
}
    break;

  case 52:

/* Line 1455 of yacc.c  */
#line 415 "structspec_parser.y++"
    {(yyval.potential) = NULL;}
    break;

  case 53:

/* Line 1455 of yacc.c  */
#line 416 "structspec_parser.y++"
    {
  struct potential *pot = (struct potential*)malloc(sizeof(struct potential));
  g_assert(pot != NULL);
  pot->Evec = (yyvsp[(2) - (2)].list);
  pot->E = NULL;
  pot->function = NULL;
  (yyval.potential) = pot;
}
    break;

  case 54:

/* Line 1455 of yacc.c  */
#line 425 "structspec_parser.y++"
    {(yyval.exp) = new_fx_const_single((yyvsp[(1) - (1)].fval));}
    break;

  case 55:

/* Line 1455 of yacc.c  */
#line 426 "structspec_parser.y++"
    {(yyval.exp) = new_fx_const_single((yyvsp[(2) - (2)].fval));}
    break;

  case 56:

/* Line 1455 of yacc.c  */
#line 428 "structspec_parser.y++"
    {(yyval.exp) = new_fx_const_single((yyvsp[(1) - (1)].ival));}
    break;

  case 57:

/* Line 1455 of yacc.c  */
#line 429 "structspec_parser.y++"
    {(yyval.exp) = new_fx_const_single((yyvsp[(2) - (2)].ival));}
    break;

  case 58:

/* Line 1455 of yacc.c  */
#line 431 "structspec_parser.y++"
    {(yyval.exp) = new_fx_const(g_list_length((yyvsp[(1) - (1)].list)), (yyvsp[(1) - (1)].list));}
    break;

  case 59:

/* Line 1455 of yacc.c  */
#line 432 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::PLUS, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));}
    break;

  case 60:

/* Line 1455 of yacc.c  */
#line 433 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::MINUS, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));}
    break;

  case 61:

/* Line 1455 of yacc.c  */
#line 434 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::MUL, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));}
    break;

  case 62:

/* Line 1455 of yacc.c  */
#line 435 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::DIV, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));}
    break;

  case 63:

/* Line 1455 of yacc.c  */
#line 436 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::CROSS, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));}
    break;

  case 64:

/* Line 1455 of yacc.c  */
#line 437 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::DOT, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));}
    break;

  case 65:

/* Line 1455 of yacc.c  */
#line 438 "structspec_parser.y++"
    {(yyval.exp) = (yyvsp[(2) - (3)].exp);}
    break;

  case 66:

/* Line 1455 of yacc.c  */
#line 439 "structspec_parser.y++"
    {(yyval.exp) = new_fx(kdotp::libmodelxx::postprocessing::NEG, NULL, (yyvsp[(2) - (2)].exp));}
    break;

  case 67:

/* Line 1455 of yacc.c  */
#line 440 "structspec_parser.y++"
    {(yyval.exp) = new_fx_func((yyvsp[(1) - (4)].str), (yyvsp[(3) - (4)].exp));}
    break;

  case 68:

/* Line 1455 of yacc.c  */
#line 441 "structspec_parser.y++"
    {(yyval.exp) = new_fx_symbol((yyvsp[(1) - (1)].str));}
    break;

  case 69:

/* Line 1455 of yacc.c  */
#line 443 "structspec_parser.y++"
    {(yyval.fval) = (yyvsp[(1) - (1)].fval);}
    break;

  case 70:

/* Line 1455 of yacc.c  */
#line 444 "structspec_parser.y++"
    {(yyval.fval) = -(yyvsp[(2) - (2)].fval);}
    break;

  case 71:

/* Line 1455 of yacc.c  */
#line 445 "structspec_parser.y++"
    {(yyval.fval) = (yyvsp[(2) - (2)].fval);}
    break;

  case 72:

/* Line 1455 of yacc.c  */
#line 447 "structspec_parser.y++"
    {(yyval.ival) = (yyvsp[(1) - (1)].ival);}
    break;

  case 73:

/* Line 1455 of yacc.c  */
#line 448 "structspec_parser.y++"
    {(yyval.ival) = -(yyvsp[(2) - (2)].ival);}
    break;

  case 74:

/* Line 1455 of yacc.c  */
#line 449 "structspec_parser.y++"
    {(yyval.ival) = (yyvsp[(2) - (2)].ival);}
    break;



/* Line 1455 of yacc.c  */
#line 2344 "kdotp/structspec_parser.c++"
      default: break;
    }
  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);

  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);

  *++yyvsp = yyval;
  *++yylsp = yyloc;

  /* Now `shift' the result of the reduction.  Determine what state
     that goes to, based on the state we popped back to and the rule
     number reduced by.  */

  yyn = yyr1[yyn];

  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
    yystate = yytable[yystate];
  else
    yystate = yydefgoto[yyn - YYNTOKENS];

  goto yynewstate;


/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
  /* If not already recovering from an error, report this error.  */
  if (!yyerrstatus)
    {
      ++yynerrs;
#if ! YYERROR_VERBOSE
      yyerror (YY_("syntax error"));
#else
      {
  YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
  if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
    {
      YYSIZE_T yyalloc = 2 * yysize;
      if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
        yyalloc = YYSTACK_ALLOC_MAXIMUM;
      if (yymsg != yymsgbuf)
        YYSTACK_FREE (yymsg);
      yymsg = (char *) YYSTACK_ALLOC (yyalloc);
      if (yymsg)
        yymsg_alloc = yyalloc;
      else
        {
    yymsg = yymsgbuf;
    yymsg_alloc = sizeof yymsgbuf;
        }
    }

  if (0 < yysize && yysize <= yymsg_alloc)
    {
      (void) yysyntax_error (yymsg, yystate, yychar);
      yyerror (yymsg);
    }
  else
    {
      yyerror (YY_("syntax error"));
      if (yysize != 0)
        goto yyexhaustedlab;
    }
      }
#endif
    }

  yyerror_range[0] = yylloc;

  if (yyerrstatus == 3)
    {
      /* If just tried and failed to reuse lookahead token after an
   error, discard it.  */

      if (yychar <= YYEOF)
  {
    /* Return failure if at end of input.  */
    if (yychar == YYEOF)
      YYABORT;
  }
      else
  {
    yydestruct ("Error: discarding",
          yytoken, &yylval, &yylloc);
    yychar = YYEMPTY;
  }
    }

  /* Else will try to reuse lookahead token after shifting the error
     token.  */
  goto yyerrlab1;


/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR.  |
`---------------------------------------------------*/
yyerrorlab:

  /* Pacify compilers like GCC when the user code never invokes
     YYERROR and the label yyerrorlab therefore never appears in user
     code.  */
  if (/*CONSTCOND*/ 0)
     goto yyerrorlab;

  yyerror_range[0] = yylsp[1-yylen];
  /* Do not reclaim the symbols of the rule which action triggered
     this YYERROR.  */
  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);
  yystate = *yyssp;
  goto yyerrlab1;


/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR.  |
`-------------------------------------------------------------*/
yyerrlab1:
  yyerrstatus = 3;  /* Each real token shifted decrements this.  */

  for (;;)
    {
      yyn = yypact[yystate];
      if (yyn != YYPACT_NINF)
  {
    yyn += YYTERROR;
    if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
      {
        yyn = yytable[yyn];
        if (0 < yyn)
    break;
      }
  }

      /* Pop the current state because it cannot handle the error token.  */
      if (yyssp == yyss)
  YYABORT;

      yyerror_range[0] = *yylsp;
      yydestruct ("Error: popping",
      yystos[yystate], yyvsp, yylsp);
      YYPOPSTACK (1);
      yystate = *yyssp;
      YY_STACK_PRINT (yyss, yyssp);
    }

  *++yyvsp = yylval;

  yyerror_range[1] = yylloc;
  /* Using YYLLOC is tempting, but would change the location of
     the lookahead.  YYLOC is available though.  */
  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
  *++yylsp = yyloc;

  /* Shift the error token.  */
  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);

  yystate = yyn;
  goto yynewstate;


/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here.  |
`-------------------------------------*/
yyacceptlab:
  yyresult = 0;
  goto yyreturn;

/*-----------------------------------.
| yyabortlab -- YYABORT comes here.  |
`-----------------------------------*/
yyabortlab:
  yyresult = 1;
  goto yyreturn;

#if !defined(yyoverflow) || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here.  |
`-------------------------------------------------*/
yyexhaustedlab:
  yyerror (YY_("memory exhausted"));
  yyresult = 2;
  /* Fall through.  */
#endif

yyreturn:
  if (yychar != YYEMPTY)
     yydestruct ("Cleanup: discarding lookahead",
     yytoken, &yylval, &yylloc);
  /* Do not reclaim the symbols of the rule which action triggered
     this YYABORT or YYACCEPT.  */
  YYPOPSTACK (yylen);
  YY_STACK_PRINT (yyss, yyssp);
  while (yyssp != yyss)
    {
      yydestruct ("Cleanup: popping",
      yystos[*yyssp], yyvsp, yylsp);
      YYPOPSTACK (1);
    }
#ifndef yyoverflow
  if (yyss != yyssa)
    YYSTACK_FREE (yyss);
#endif
#if YYERROR_VERBOSE
  if (yymsg != yymsgbuf)
    YYSTACK_FREE (yymsg);
#endif
  /* Make sure YYID is used.  */
  return YYID (yyresult);
}

Here is the call graph for this function:


Variable Documentation

GInputStream* instream

Definition at line 580 of file structspec_lexer.c++.

Definition at line 205 of file structspec_parser.c++.

int yydebug
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines