k-dot-p 0.1

grid.h++

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 
00021 #ifndef GRID_HXX__
00022 #define GRID_HXX__
00023 
00024 #include <glib.h>
00025 #include <libmodelxx/shapes.h++>
00026 #include <libmodelxx/material.h++>
00027 #include <libmodelxx/key_values.h++>
00028 #include <libmodelxx/cartesian_grid.h++>
00029 #include <libmodelxx/function_specification.h++>
00030 
00031 #define GERROR_DOMAIN_LIBMODELXX_GRID 56932
00032 
00033 namespace kdotp {
00034   namespace libmodelxx {
00035     namespace grid {
00036 
00037       enum grid_type {
00038   CARTESIAN
00039       };
00040       
00041       struct grid {
00042   enum grid_type t;
00043   /*GList containing pointers to GLists of floats (i.e. is a set of vectors
00044    *Is used to map out the extent of the grid to be used*/
00045   /*Pointer to a list of pointers to ints; size of box in gridsites*/
00046   GList *box_size;
00047   /*Pointer to a list of doubles; size of a gridsite in nm*/
00048   GList *site_length;
00049   int dimensions;
00050   /*Storage for raw key/value information from the input file*/
00051   GList *key_values;
00052       };
00053 
00054       struct point {
00055   /*Grid used to deal with this point*/
00056   struct grid *g;
00057   /*Array used to store the point data*/
00058   double *x;
00059       };
00060 
00061       /**
00062        *Sets up a grid that has been read in from a file
00063        *\param g grid structure from the input file
00064        *\return int error code:
00065        * 0: success
00066        */
00067 
00068       /**
00069        *Creates the grid on which we're going to hang the semiconductor.
00070        *\arg g pointer to the raw grid structure from the structspec
00071        *\arg err pointer to a GError containing the error.
00072        *\return pointer to the new grid class
00073        *\note the default material is NULL; this will help us find
00074        *        any unassigned places.
00075        *\note Error values;
00076        *        NULL if successful
00077        *        1 if there were too many/few dimensions specified
00078        *        2 if the grid type is unsupported.
00079        */
00080       template<typename T, unsigned Nc=1>
00081       void* set_up_grid(struct grid* g, T defvalue, GError **err) {
00082   switch(g->t) {
00083   case CARTESIAN:
00084     switch(g->dimensions){
00085     case 1:
00086       return new cartesian_grid<T, 1, Nc>(g->box_size, g->site_length, defvalue);
00087       break;
00088     case 2:
00089       return new cartesian_grid<T, 2, Nc>(g->box_size, g->site_length, defvalue);
00090       break;
00091     case 3:
00092       return new cartesian_grid<T, 3, Nc>(g->box_size, g->site_length, defvalue);
00093       break;
00094     default:
00095       *err = g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 1, "kdotp::libmodelxx::continuous_structure::set_up_grid: ERROR setting up cartesian grid: bad number of dimensions (%d); must be in range (1, 3).", g->dimensions);
00096       return NULL;
00097     }
00098     break;
00099   default:
00100     *err = g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 2, "kdotp::libmodelxx::continuous_structure::set_up_grid: ERROR no such grid (numeric equivalent is %d)\n\tThis is almost certainly a programming error and/or an input error (shouldn't have let the bad input through)", g->t);
00101   }
00102   return NULL;
00103       }
00104 
00105       template<typename T, unsigned Nc=1>
00106       GError* free_grid_class(enum grid_type t, int dims, void* grid_class) {
00107   switch(t) {
00108   case CARTESIAN:
00109     switch(dims){
00110     case 1:
00111       delete (cartesian_grid<T, 1, Nc>*)grid_class;
00112       return NULL;
00113     case 2:
00114       delete (cartesian_grid<T, 2, Nc>*)grid_class;
00115       return NULL;
00116     case 3:
00117       delete (cartesian_grid<T, 3, Nc>*)grid_class;
00118       return NULL;
00119     default:
00120       return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 1, "kdotp::libmodelxx::continuous_structure::free_grid: ERROR freeing cartesian grid: bad number of dimensions (%d); must be in range (1, 3).", dims);
00121     }
00122     break;
00123   default:
00124     return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 2, "kdotp::libmodelxx::continuous_structure::free_grid: ERROR no such grid (numeric equivalent is %d)\n\tThis is almost certainly a programming error and/or an input error (shouldn't have let the bad input through)", t);
00125   }
00126   return NULL;
00127       }
00128 
00129 
00130 
00131       /**
00132        ** Generic set_region
00133        *\param s shape_tree
00134        *\param m material
00135        *\return 0 if success
00136        */
00137       template<typename T, unsigned Nc=1>
00138       GError* set_value_in_grid(enum grid_type t, int dims, void* grid_class, const struct shape_tree* st, T value, GHashTable* global_symbol_table) {
00139   int err = 0;
00140   switch(t){
00141   case CARTESIAN:
00142     switch(dims){
00143     case 1:
00144       if((err=static_cast<cartesian_grid<T, 1, Nc>*>(grid_class)->set_points(st, &value, global_symbol_table)) != 0) {
00145         return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 10+err, "kdotp::libmodelxx::grid::set_value_in_grid: failed to execute set_points in 1D cartesian grid; err %d", err);
00146       }
00147       return NULL;
00148     case 2:
00149       if((err=static_cast<cartesian_grid<T, 2, Nc>*>(grid_class)->set_points(st, &value, global_symbol_table)) != 0) {
00150         return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 10+err, "kdotp::libmodelxx::grid::set_value_in_grid: failed to execute set_points in 2D cartesian grid; err %d", err);
00151       }
00152       return NULL;
00153     case 3:
00154       if((err=static_cast<cartesian_grid<T, 3, Nc>*>(grid_class)->set_points(st, &value, global_symbol_table)) != 0) {
00155         return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 10+err, "kdotp::libmodelxx::grid::set_value_in_grid: failed to execute set_points in 3D cartesian grid; err %d", err);
00156       }
00157       return NULL;
00158     default:
00159       return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 1, "kdotp::libmodelxx::grid::set_value_in_grid: ERROR setting up cartesian grid: bad number of dimensions (%d); must be in range (1, 3).\n", dims);
00160     }
00161     break;
00162   default:
00163     return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 2, "kdotp::libmodelxx::grid::set_value_in_grid: ERROR no such grid (numeric equivalent is %d)\n\tThis is almost certainly a programming error and/or an input error (shouldn't have let the bad input through)\n", t);
00164   }
00165   return NULL;
00166       }
00167 
00168       /**
00169        **set_region from an expression and a conversion from a double
00170        *\param s shape_tree
00171        *\param m material
00172        *\return 0 if success
00173        */
00174       template<typename T, unsigned Nc=1>
00175       GError* set_value_in_grid(enum grid_type t, int dims, void* grid_class, const struct shape_tree* st, struct ::kdotp::libmodelxx::postprocessing::function_exp *exp, GHashTable* global_symbol_table, GError*(*set_location_from_double)(T*, double*, int, void*), void* privdat) {
00176   GError *err=NULL, *e=NULL;
00177   switch(t){
00178   case CARTESIAN:
00179     switch(dims){
00180     case 1:
00181       if((err=static_cast<cartesian_grid<T, 1, Nc>*>(grid_class)->set_points(st, exp, global_symbol_table, set_location_from_double, privdat)) != NULL) {
00182         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::set_value_in_grid(expression): failed to execute set_points in 1D cartesian grid: ");
00183         return err;
00184       }
00185       return NULL;
00186     case 2:
00187       if((err=static_cast<cartesian_grid<T, 2, Nc>*>(grid_class)->set_points(st, exp, global_symbol_table, set_location_from_double, privdat)) != NULL) {
00188         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::set_value_in_grid(expression): failed to execute set_points in 2D cartesian grid: ");
00189         return err;
00190       }
00191       return NULL;
00192     case 3:
00193       if((err=static_cast<cartesian_grid<T, 3, Nc>*>(grid_class)->set_points(st, exp, global_symbol_table, set_location_from_double, privdat)) != NULL) {
00194         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::set_value_in_grid(expression): failed to execute set_points in 3D cartesian grid: ");
00195         return err;
00196       }
00197       return NULL;
00198     default:
00199       return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 1, "kdotp::libmodelxx::grid::set_value_in_grid(expression): ERROR setting up cartesian grid: bad number of dimensions (%d); must be in range (1, 3).\n", dims);
00200     }
00201     break;
00202   default:
00203     return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 2, "kdotp::libmodelxx::grid::set_value_in_grid(expression): ERROR no such grid (numeric equivalent is %d)\n\tThis is almost certainly a programming error and/or an input error (shouldn't have let the bad input through)\n", t);
00204   }
00205   return NULL;
00206       }
00207 
00208 
00209       template<typename T, unsigned Nc=1>
00210       GError* dump_grid(GOutputStream* gos, enum grid_type t, int dims, void* grid_class, char* (*t_to_str)(T*)) {
00211   GError *err=NULL, *e=NULL;
00212       switch(t){
00213   case CARTESIAN:
00214     switch(dims){
00215     case 1:
00216       if((err=static_cast<cartesian_grid<T, 1, Nc>*>(grid_class)->dump(gos, t_to_str))) {
00217         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::dump_grid(expression): failed to dump 1D cartesian grid: ");
00218         return err;
00219       }
00220       return NULL;
00221     case 2:
00222       if((err=static_cast<cartesian_grid<T, 2, Nc>*>(grid_class)->dump(gos, t_to_str))) {
00223         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::dump_grid(expression): failed to dump 2D cartesian grid: ");
00224         return err;
00225       }
00226       return NULL;
00227     case 3:
00228       if((err=static_cast<cartesian_grid<T, 3, Nc>*>(grid_class)->dump(gos, t_to_str))) {
00229         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::dump_grid(expression): failed to dump 3D cartesian grid: ");
00230         return err;
00231       }
00232       return NULL;
00233     default:
00234       return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 1, "kdotp::libmodelxx::grid::dump_grid(expression): ERROR setting up cartesian grid: bad number of dimensions (%d); must be in range (1, 3).\n", dims);
00235     }
00236     break;
00237   default:
00238     return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 2, "kdotp::libmodelxx::grid::dump_grid(expression): ERROR no such grid (numeric equivalent is %d)\n\tThis is almost certainly a programming error and/or an input error (shouldn't have let the bad input through)\n", t);
00239   }
00240   return NULL;
00241       }
00242 
00243       template<typename T, unsigned Nc=1>
00244       GError* dump_indexed_grid(GOutputStream* gos, enum grid_type t, int dims, void* grid_class, bool is_same(T*, T*), char* (*t_to_str)(T*)) {
00245   GError *err=NULL, *e=NULL;
00246   switch(t){
00247   case CARTESIAN:
00248     switch(dims){
00249     case 1:
00250       if((err=static_cast<cartesian_grid<T, 1, Nc>*>(grid_class)->dump_indexed(gos, is_same, t_to_str))) {
00251         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::dump_indexed_grid(expression): failed to dump indexed 1D cartesian grid: ");
00252         return err;
00253       }
00254       return NULL;
00255     case 2:
00256       if((err=static_cast<cartesian_grid<T, 2, Nc>*>(grid_class)->dump_indexed(gos, is_same, t_to_str))) {
00257         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::dump_indexed_grid(expression): failed to dump indexed 2D cartesian grid: ");
00258         return err;
00259       }
00260       return NULL;
00261     case 3:
00262       if((err=static_cast<cartesian_grid<T, 3, Nc>*>(grid_class)->dump_indexed(gos, is_same, t_to_str))) {
00263         g_propagate_prefixed_error(&e, err, "kdotp::libmodelxx::grid::dump_indexed_grid(expression): failed to dump indexed 3D cartesian grid: ");
00264         return err;
00265       }
00266       return NULL;
00267     default:
00268       return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 1, "kdotp::libmodelxx::grid::dump_indexed_grid(expression): ERROR setting up cartesian grid: bad number of dimensions (%d); must be in range (1, 3).\n", dims);
00269     }
00270     break;
00271   default:
00272     return g_error_new(GERROR_DOMAIN_LIBMODELXX_GRID, 2, "kdotp::libmodelxx::grid::dump_indexed_grid(expression): ERROR no such grid (numeric equivalent is %d)\n\tThis is almost certainly a programming error and/or an input error (shouldn't have let the bad input through)\n", t);
00273   }
00274   return NULL;
00275       }
00276   
00277 
00278     }
00279   }
00280 }
00281 
00282 
00283 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines