k-dot-p 0.1

continuous_structure.c++

Go to the documentation of this file.
00001 /*
00002  *
00003 
00004  Copyright (C) 2009 Joseph Pingenot
00005 
00006  This program is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU Affero General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  This program is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  GNU Affero General Public License for more details.
00015 
00016  You should have received a copy of the GNU Affero General Public License
00017  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <math.h>
00023 #include <glib.h>
00024 #include <libmodelxx/continuous_structure.h++>
00025 #include <libmodelxx/matdb.h++>
00026 #include <libmodelxx/material.h++>
00027 #include <libmodelxx/generic_structure.h++>
00028 #include <libmodelxx/function_specification.h++>
00029 
00030 namespace kdotp {
00031   namespace libmodelxx {
00032     namespace continuous_structure {
00033       #define CONTINUOUS_STRUCTURE_GERROR_DOMAIN 321
00034 
00035       static GError* callback_convert_type(double* location, double* values, int t, void* privdat) {
00036   for(int i=0; i<t; i++) {
00037     location[i] = values[i];
00038   }
00039   if(t == 0) {
00040     location[0] = values[0];
00041     return g_error_new(CONTINUOUS_STRUCTURE_GERROR_DOMAIN, 1, "::kdotp::libmodelxx::continuous_structure.c++::callback_convert_type:: warning: function data type boolean is invalid!");
00042   }
00043   if(t < 0) {
00044     return g_error_new(CONTINUOUS_STRUCTURE_GERROR_DOMAIN, 2, "::kdotp::libmodelxx::continuous_structure.c++::callback_convert_type:: warning: function data type is INVALID!");
00045   }
00046   return NULL;
00047       }
00048 
00049       struct callback_get_material_privdat {
00050   char* mat1;
00051   char* mat2;
00052   const struct structure::matdb* mdb;
00053       };
00054 
00055       static GError* callback_get_material(structure::material** location, double* values, int t, void* privdat) {
00056   struct callback_get_material_privdat* p = (struct callback_get_material_privdat*)privdat;
00057   if(t != 1) {
00058     return g_error_new(CONTINUOUS_STRUCTURE_GERROR_DOMAIN, 1, "::kdotp::libmodelxx::continuous_structure.c++::callback_get_material: ERROR: I have no idea how to convert a vector to a material composed of (%s) and (%s)!", p->mat1, p->mat2);
00059   }
00060   fprintf(stderr, "Got material from function: %s(%g)%s\n", p->mat1, values[0], p->mat2);
00061   if((values[0] < 0) || (values[0] > 1)) return g_error_new(CONTINUOUS_STRUCTURE_GERROR_DOMAIN, 2, "::kdotp::libmodelxx::continuous_structure.c++::callback_get_material: ERROR: invalid percentage from function (material would be (%s)(%g)(%s))!", p->mat1, values[0], p->mat2);
00062   location[0] = new structure::material(p->mdb, p->mat1, p->mat2, values[0]);
00063   if(location[0] == NULL) return g_error_new(CONTINUOUS_STRUCTURE_GERROR_DOMAIN, 3, "::kdotp::libmodelxx::continuous_structure.c++::callback_get_material: ERROR: Error getting material from function: (material would be (%s)(%g)(%s))!", p->mat1, values[0], p->mat2);
00064   return NULL;
00065       }
00066 
00067       struct structure::generic_structure* postprocess_structure(struct continuous_structure *s, const struct structure::matdb* mdb, GHashTable* global_symbol_table, GError **gerr) {
00068   struct structure::generic_structure* ngs;
00069   if((ngs = structure::generic_structure_new(s->g)) == NULL) {
00070     *gerr = g_error_new(CONTINUOUS_STRUCTURE_DOMAIN, 1, "kdotp::libmodelxx::continouous_structure::postprocess_structure: failed to set up new generic structure (got NULL)");
00071     return NULL;
00072   }
00073   int err=0;
00074   GList* l;
00075   GError *e = NULL;
00076   struct region* r;
00077   int i=0;
00078   for(l=s->regions; l!=NULL; l=l->next) {
00079     fprintf(stderr, "region %d:", i);
00080     r = (struct region*)(l->data);
00081     if(((r->st)=postprocess_shape_tree(r->st, s->g->dimensions)) == NULL) {
00082       *gerr = g_error_new(CONTINUOUS_STRUCTURE_DOMAIN, 100+err, "kdotp::libmodelxx::continuous_structure::postprocess_structure failed to set up a region shape tree (error in postprocess_shape_tree (error %d))", err);
00083       structure::generic_structure_free(ngs);
00084       return NULL;
00085     }
00086     /*Set up the specified material.*/
00087     if(r->f == NULL) {
00088       (r->m) = new structure::material(mdb, r->mat1, r->mat2, r->x);
00089       if((r->m) == NULL) {
00090         *gerr = g_error_new(CONTINUOUS_STRUCTURE_DOMAIN, 2, "kdotp::libmodelxx::continuous_structure::postprocess_structure failed to set up constat material (%s(%f)%s)", r->mat1, r->x, r->mat2);
00091         structure::generic_structure_free(ngs);
00092         return NULL;
00093       }
00094       /*Set the material*/
00095       e = set_value_in_grid(ngs->g->t, ngs->g->dimensions, ngs->material_grid, r->st, r->m, global_symbol_table);
00096       if(e != NULL) {
00097         g_propagate_prefixed_error(gerr, e, "kdotp::libmodelxx::continuous_structure.c++::postprocess_structure: got error setting material in grid (mat1=%s mat2=%s x=%f): ", r->mat1, r->mat2, r->x);
00098       }
00099     }else{
00100       GString *s = g_string_new("");
00101       function_print_tree(r->f, &s, 0);
00102       fprintf(stderr, "Got r->f tree:%s\n", s->str);
00103       g_string_free(s, TRUE);
00104       struct callback_get_material_privdat pd;
00105       pd.mat1 = r->mat1;
00106       pd.mat2 = r->mat2;
00107       pd.mdb = mdb;
00108       e = set_value_in_grid(ngs->g->t, ngs->g->dimensions, ngs->material_grid, r->st, r->f, global_symbol_table, callback_get_material, &pd);
00109       if(e != NULL) {
00110         g_propagate_prefixed_error(gerr, e, "kdotp::libmodelxx::continuous_structure.c++::postprocess_structure: got error setting material in grid with function: ");
00111       }
00112     }
00113     fprintf(stderr, " (set material in grid)");
00114     i++;
00115     fprintf(stderr, "\n");
00116   }
00117   struct doping *d;
00118   for(l=s->dopings; l!=NULL; l=l->next) {
00119     d=(struct doping*)(l->data);
00120     if(((d->st)=postprocess_shape_tree(d->st, s->g->dimensions)) == NULL) {
00121       *gerr = g_error_new(CONTINUOUS_STRUCTURE_DOMAIN, 100+err, "kdotp::libmodelxx::continuous_structure::postprocess_structure failed to set up a doping shape tree (error in postprocess_shape_tree (error %d))", err);
00122       structure::generic_structure_free(ngs);
00123       return NULL;
00124     }
00125     GString *s = g_string_new("");
00126     function_print_tree(d->f, &s, 0);
00127     fprintf(stderr, "Got d->f tree:%s\n", s->str);
00128     g_string_free(s, TRUE);
00129     e = set_value_in_grid(ngs->g->t, ngs->g->dimensions, ngs->doping_grid, d->st, d->f, global_symbol_table, callback_convert_type, NULL);
00130     if(e != NULL) {
00131       g_propagate_prefixed_error(gerr, e, "kdotp::libmodelxx::continuous_structure.c++::postprocess_structure: got error setting doping in grid: ");
00132     }
00133   }
00134   struct potential *p;
00135   for(l=s->potential; l != NULL; l=l->next) {
00136     //TODO!!
00137   }
00138         return ngs;
00139       }
00140 
00141       void print_structure(const struct continuous_structure *s) {
00142   fprintf(stderr, "================================================================\n");
00143   fprintf(stderr, "Grid data:\n");
00144   fprintf(stderr, "Regions:\n");
00145       }
00146 
00147       enum length length_from_str(const char* str) {
00148   if(!strcmp(str, "nm")) return NANOMETER;
00149   else if(!strcmp(str, "A")) return ANGSTROM;
00150   else if(!strcmp(str, "um")) return MICROMETER;
00151   else if(!strcmp(str, "mm")) return MILLIMETER;
00152   else if(!strcmp(str, "cm")) return CENTIMETER;
00153   else if(!strcmp(str, "m")) return METER;
00154   return UNKNOWN_LENGTH;
00155       }
00156 
00157       const char* str_from_length(enum length l) {
00158   switch(l) {
00159   case NANOMETER:
00160     return "nm";
00161   case ANGSTROM:
00162     return "A";
00163   case MICROMETER:
00164     return "um";
00165   case MILLIMETER:
00166     return "mm";
00167   case CENTIMETER:
00168     return "cm";
00169   case METER:
00170     return "m";
00171   default:
00172     return "<unknown unit of length>";
00173   }
00174       }
00175 
00176       enum energy energy_from_str(const char* str) {
00177   if(!strcmp(str, "eV")) return EVOLT;
00178   else if(!strcmp(str, "J")) return JOULE;
00179   else if(!strcmp(str, "erg")) return ERG;
00180   else if(!strcmp(str, "Eh")) return HARTREE;
00181   return UNKNOWN_ENERGY;
00182       }
00183 
00184       const char* str_from_energy(enum energy e) {
00185   switch(e) {
00186   case EVOLT:
00187     return "eV";
00188   case JOULE:
00189     return "J";
00190   case ERG:
00191     return "erg";
00192   case HARTREE:
00193     return "Eh";
00194   default:
00195     return "<unknown unit of energy>";
00196   }
00197       }
00198 
00199       double convert_length_to_nm(double len, enum length unit) {
00200   switch(unit) {
00201   case NANOMETER:
00202     return len;
00203   case ANGSTROM:
00204     return len/10.0;
00205   case MICROMETER:
00206     return len*1.0e3;
00207   case MILLIMETER:
00208     return len*1.0e6;
00209   case CENTIMETER:
00210     return len*1.0e7;
00211   case METER:
00212     return len*1.0e9;
00213   default:
00214     fprintf(stderr, "kdotp::libmodelxx::continuous_structure::convert_length_to_nm: ERROR while converting units: unknown unit of length (%s)\n", str_from_length(unit));
00215     return nan("NaN");
00216   }
00217       }
00218 
00219       /*From NIST*/
00220       double convert_energy_to_hartree(double en, enum energy unit) {
00221   switch(unit) {
00222   case HARTREE:
00223     return en;
00224   case EVOLT:
00225     return en*3.674932540e-2;
00226   case JOULE:
00227     return en*2.29371269e17;
00228   case ERG:
00229     /*From wikipedia: 1 erg = 1e-7 J */
00230     return en*2.29371269e10;
00231   default:
00232     fprintf(stderr, "kdotp::libmodelxx::continuous_structure::convert_energy_to_hartree: ERROR while converting units: unknown unit of energy (%s)\n", str_from_energy(unit));
00233     return nan("NaN");
00234   }
00235       }
00236 
00237     }
00238   }
00239 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines