funkalicious 0.1

lp_wavefunction.h

Go to the documentation of this file.
00001 /*
00002 ** wavefunction.h
00003 ** 
00004 
00005     Copyright (C) 2009 Joseph Pingenot
00006 
00007     This program is free software: you can redistribute it and/or modify
00008     it under the terms of the GNU Affero General Public License as published by
00009     the Free Software Foundation, either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU Affero General Public License for more details.
00016 
00017     You should have received a copy of the GNU Affero General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 ** Made by Johnny Q. Hacker
00021 ** Login   <solarion@nathan>
00022 ** 
00023 ** Started on  Tue Nov 17 22:28:05 2009 Johnny Q. Hacker
00024 ** Last update Tue Nov 17 22:28:05 2009 Johnny Q. Hacker
00025 */
00026 
00027 #include <glib-2.0/glib.h>
00028 #include <gio/gio.h>
00029 #include <libdotcode/function_parser.h>
00030 #include <libdotcode/binary_data_common.h>
00031 #include <libpostproc/density_common.h>
00032 
00033 #ifndef     WAVEFUNCTION_H_
00034 # define    WAVEFUNCTION_H_
00035 
00036 #ifdef __cplusplus
00037 extern "C" {
00038 #endif
00039 
00040 
00041 /*For clarity, X, Y, and Z specify respective array indices.*/
00042 enum coord {X, Y, Z};
00043 
00044 struct wavefunction {
00045   GFile* file;
00046   double charge;
00047   int N[3];
00048   double dx[3];
00049   int bands;
00050   struct wavefunc_header header;
00051   double* storage;
00052 };
00053 
00054 struct density {
00055   int N[3];
00056   double dx[3];
00057   double* storage;
00058 };
00059 
00060 
00061 /**Gets a new density with a double-resolution grid, using an average for interpolation
00062  *\param original original density
00063  *\param auto_scale flags on which dimension to use to scale: 1->Y 2->Y 4->Z (combine for multiple directions)
00064  *\return pointer to a density, or NULL if memory allocation failed.
00065  *\note the new grid doesn't add an outside row of new sites; it only places a new grid site between two existing ones
00066  */
00067   struct density* get_double_resolution_density(const struct density* original, int auto_scale);
00068 
00069 /**Gets a new density with a half-resolution grid, using an average for assignment
00070  *\param original original density
00071  *\param e pointer to pointer to Gerror in which to store the error information
00072  *\param auto_scale flags on which dimension to use to scale: 1->Y 2->Y 4->Z (combine for multiple directions)
00073  *\return pointer to a density, or NULL if memory allocation failed.
00074  *\note the new grid doesn't add an outside row of new sites; it only places a new grid site between two existing ones
00075  */
00076   struct density* get_half_resolution_density(const struct density* original, GError **e, int auto_scale);
00077 
00078 /**Gets a density from a list of *loaded* wavefunctions
00079  *\param list the list of *loaded* wavefunction structures.
00080  *\param err pointer to a pointer in which to store the GError (if
00081  *there's an error)
00082  *\returns a density that is the sum of the individual wavefunctions.
00083  *\note Wavefunctions must be *loaded* before calling this function!
00084  *\note The charge is used! If you just want pre-normalized |psi|^2,
00085  *set charge to 1.
00086  */
00087 struct density* get_density_for_list_of_wavefunctions(GList *list, GError **err);
00088 /**Loads the wavefunctions from the respective GFiles.
00089  *\param wf_list List of wavefunctions
00090  *\param err pointer to a pointer in which to store the GError (if
00091  *there's an error)
00092 */
00093 void load_wavefunctions(GList* wf_list, GError** err);
00094 void init_density(struct density* d, double initial_value);
00095 void add_to_density(struct density* d, struct wavefunction* wf);
00096 /**Puts a density into *one section* of a metadensity.
00097  *\param md the target meta_density
00098  *\param d the source density
00099  *\param Nn an array of ints representing the number of neighbors in
00100  *each direction.
00101  *\param x location of this block to be inserted.
00102  *\param y location of this block to be inserted.
00103  *\param z location of this block to be inserted.
00104  *\param invert_x if true, the x-coordinates are read backwards from
00105  *the source.
00106  *\param invert_y if true, the y-coordinates are read backwards from
00107  *the source.
00108  *\param invert_z if true, the z-coordinates are read backwards from
00109  *the source.
00110  *\param offsets offset in grid sites between neighborsa
00111  */
00112   void put_density_into_metadensity(struct density* md, const struct density* d, const int *Nn, int x, int y, int z, gboolean invert_x, gboolean invert_y, gboolean invert_z, const unsigned* offsets);
00113 /**Writes out a single, ascii density slice or the entire box.
00114  *\param c the coordinate to output
00115  *\param index pointer to an int containing the index which should be
00116  *written out
00117  *\param d the density to be written
00118  *\param filename pointer to a pointer to a char, to provide the
00119  *filename of the written file.
00120  *\param err pointer to a pointer to a GError, for returning any error
00121  *info
00122  *\param location base directory to output, or NULL if cwd. If index
00123  *is NULL, this is the file to write the dump into.
00124  *\param sepchar character to use to separate the columns in the
00125  *output
00126  *\return nothing
00127  */
00128 void write_density_slice(enum coord c, const int* index, const struct density* d, char** filename, GError **err, GFile *location, char sepchar, const char* coord_units, const char* density_units);
00129 void write_density_sweep(enum coord c, const struct density* d, char** filename, GError **err, GFile* location, gboolean sweep_log);
00130 void write_density_line(enum coord axis, const int* gridsite, const struct density* d, char** filename, GError **err, GFile *location, char sepchar, const char* coord_units, const char* density_units);
00131 
00132 void density_mul_by_const(struct density* d, double c);
00133 /**Gets a block of the meta_density back out.
00134  *\param md the meta denstiy
00135  *\param d an initialized density the sizeo f one block
00136  *\param buffzone the buffer zone size around the meta_density
00137  *\param Mn the number of neighbors in each direction
00138  *\param x the x-coordinate of the block
00139  *\param y the y-coordinate of the block
00140  *\param z the z-coordinate of the block
00141  *\param offsets offset in grid sites between neighborsa
00142  */
00143   void get_density_from_metadensity(const struct density* md, struct density* d, const int* buffzone, const int *Nn, int x, int y, int z, const unsigned* offsets);
00144 
00145 /**Writes the density into a povray visualization.
00146  *\param d the density to be written out
00147  *\param towrite the file into which the povray visualization should be written
00148  *\paarm err pointer to a pointer to a GError, used to "return" a GError pointer if an error ocurred.
00149  */
00150 void write_density_povray(const struct density* d, GFile *towrite, int pixel_strategy, GError **err);
00151 
00152 /**Expands a density box using material mat
00153  *\param od the original density
00154  *\param I a 3-int array indicating how many grid sites to expand outward.
00155  *\param value a double containing the value of the density throughout the new region
00156  *\returns a pointer to a new density.
00157  */
00158 struct density* expand_density_box_with_value(const struct density* od, const int* I, double value, GError **err);
00159 /**Expands a density box using the value from the outermost grid site.
00160  *\param od the original density
00161  *\param I a 3-int array containing the number of grid sites to expand
00162  *outwards
00163  */
00164 struct density* expand_density_box(const struct density* od, const int* I, GError **err);
00165 
00166 struct density* new_density(const int* N, const double* dx, double intial_value);
00167 struct density* new_density_copy(const struct density* orig);
00168 void free_density(struct density* d);
00169   int op_density_to_density(struct density* to, enum density_op op, const struct density* from);
00170   /**Executes the specified callback
00171    *\param d density struct
00172    *\param callback pointer to function to call
00173    *\param privdat private data for the callback
00174    *\return nothing
00175    */
00176   void density_execute_callback(const struct density* d, void (*callback)(int x, int y, int z, const struct density*d, void* privdat), void* privdat);
00177   /**same, but takes two density functions*/
00178   void density_2_execute_callback(const struct density* d1, const struct density* d2, void (*callback)(int x, int y, int z, const struct density* d1, const struct density* d2, void* privdat), void* privdat);
00179   /**OpenMP-parallelized callback executors.
00180    *This is identical to the serial executors above, but parallelized with OpenMP.  The most obvious effect is a slight change in the API: the executor itself is passed an *array* of pointers to void. The callback itself still accepts a pointer to void (not a pointer to a pointer to void).  The specified callback is executed in an OpenMP parallelized for loop (on the z index, for whatever that matters).  Each thread is assigned (by thread number) a pointer to void to use as its privdat argument to the callback.  Each thread, then, executes the callback on its specified points (subject to OpenMP scheduling; no guarantees can be made with regard to order) with the same callback privdat pointer.  See the density_get_max function for an example of how to use this.
00181    *\param d density struct
00182    *\param callback pointer to function to call
00183    *\param privdat array of private data pointers for the callback, one per thread.
00184    *\param x_report array of ints, one per thread.  Set to 1 if a thread is executed, and is left untouched otherwise.
00185    *\return nothing
00186    */
00187   void density_execute_callback_parallel(const struct density* d, void (*callback)(int x, int y, int z, const struct density*d, void* privdat), void** privdat, int* x_report);
00188   void density_2_execute_callback_parallel(const struct density* d1, const struct density* d2, void (*callback)(int x, int y, int z, const struct density* d1, const struct density* d2, void* privdat), void** privdat, int* x_report);
00189 
00190 
00191   /**returns the maximum percent (at the point) difference between two densities, or NaN if the dimensions differ
00192    *\param d1 density to compare
00193    *\param d2 density to compare
00194    *\param scaleby 
00195    * if 3, use scaling to scale before comparing (the difference will be multiplied by this value)
00196    * if 2, get diff as percent of global maximum of d2
00197    * if 1, get diff as percent of global maximum of d1
00198    * if 0, get diff as percent of local value in d1.
00199    * if -1, get diff as percent of local value in d2.
00200    *\param scaling value to use for scaling if scaleby==3, else ignored
00201    */
00202   double density_get_max_abs_delta_pct(const struct density* d1, const struct density* d2, int scaleby, double scaling);
00203   /**returns the minimum percent (at the point) difference between two densities, or NaN if the dimensions differ
00204    *\param d1 density to compare
00205    *\param d2 density to compare
00206    *\param scaleby 
00207    * if 3, use scaling to scale before comparing (the difference will be multiplied by this value)
00208    * if 2, get diff as percent of global maximum of d2
00209    * if 1, get diff as percent of global maximum of d1
00210    * if 0, get diff as percent of local value in d1.
00211    * if -1, get diff as percent of local value in d2.
00212    *\param scaling value to use for scaling if scaleby==3, else ignored
00213    */
00214   double density_get_min_abs_delta_pct(const struct density* d1, const struct density* d2, int scaleby, double scaling);
00215   /**Gets the maximum value in the density
00216    *\param d density to inspect
00217    *\param abs if true, compare absolute value instead of raw value.
00218    *\return the maximum value in d
00219    */
00220   double density_get_max(const struct density* d, int abs);
00221   double density_get_max_and_loc(const struct density* d, int abs, int* location);
00222   /**Gets the minimum value in the density
00223    *\param d density to inspect
00224    *\param abs if true, compare absolute value instead of raw value.
00225    *\return the minimum value in d
00226    */
00227   double density_get_min(const struct density* d, int abs);
00228   double density_get_min_and_loc(const struct density* d, int abs, int* location);
00229 
00230 struct dotcode_grid* dotcode_grid_from_density(const struct density *d, GError **err);
00231 long unsigned int get_density_storage_index_(unsigned int x, unsigned int y, unsigned int z, unsigned int Nx, unsigned int Ny);
00232 
00233   /**gets pointer to the cell at this location
00234    *\param x  coordinate
00235    *\param y  coordinate
00236    *\param z  coordinate
00237    *\param d  density structure
00238    *\return pointer to the density value at the specified point
00239    *\note no error checking is performed
00240    */
00241   double* get_density_storage_at_(unsigned x, unsigned y, unsigned z,struct density* d);
00242   /**gets const pointer to the cell at this location
00243    *\param x  coordinate
00244    *\param y  coordinate
00245    *\param z  coordinate
00246    *\param d  density structure
00247    *\return const pointer to the density value at the specified point
00248    *\note no error checking is performed
00249    */
00250   const double* get_density_storage_at_c_(unsigned x, unsigned y, unsigned z, const struct density* d);
00251 
00252   /**Evaluates an integral of the density using GSL and a spline fit.
00253    *\param z_error_estimate: pointer to a double in which to store the estimated integration error from the final integration along z, or NULL if the error isn't to be saved.
00254    *\param y_error_estimate: pointer to an array (of size wf->N[2], one for each z point) of doubles in which to store the estimated integration error for each y integral, or NULL if the error isn't to be saved.
00255    *\param x_error_estimate: pointer to an array (of size wf->N[1]*wf->N[2], one for each (y, z) pairing) of doubles in which to store the estimated error for each x integral, or NULL if the error isn't to be saved.
00256    *\param abserr the requested absolute error (see GSL documentation)
00257    *\param relerr the requested relative error (see GSL documentation)
00258    *\param d the density over which to integrate
00259    *\param f a function to call at each point (if NULL, does nothing).
00260    *\param privdat private data to pass to f.
00261    *\return the integral
00262    *\note d will be fit to a cubic spline before integration.
00263    *\note THIS IS BROKEN
00264    */
00265   double density_integrate_spline(double* z_error_estimate, double* y_error_estimate, double* x_error_estimate, double relerr, double abserr, const struct density* d, double (*f)(double x, double y, double z, void* privdat), void* privdat);
00266 
00267   /**Evaluates an integral of the density using GSL and a spline fit, parallelized with OpenMP on the z coordinate
00268    *\param d the density over which to integrate
00269    *\param f a function to call at each point (if NULL, does nothing).
00270    *\param privdat array of private data to pass to the callback (one for each thread, indexed by omp_get_thread_num()).
00271    *\return the integral
00272    *\note d will be fit to a cubic spline before integration.
00273    *\note the same f can be used for both the single- and multi-threaded functions.
00274    *\note if privdat is NULL, NULL will be passed to f (this saves you having to allocate an array of NULLs
00275    *\note THIS IS SUPER-BROKEN
00276    */
00277   double density_integrate_spline_parallel(const struct density* d, double (*f)(double x, double y, double z, void* privdat), void** privdat);
00278 
00279   /**Evaluates an integral of the density using GSL and a simple summing mechanism: sum goes inwards from both ends, assuming that each end is a minimum.
00280    *\param d the density over which to integrate
00281    *\param f a function to call at each point (if NULL, does nothing).
00282    *\param privdat array of private data to pass to the callback (one for each thread, indexed by omp_get_thread_num()).
00283    *\return the integral
00284    *\note d will be fit to a cubic spline before integration.
00285    *\note the same f can be used for both the single- and multi-threaded functions.
00286    *\note if privdat is NULL, NULL will be passed to f (this saves you having to allocate an array of NULLs
00287    */
00288   double density_integrate_sum(const struct density* d, double (*f)(double x, double y, double z, void* privdat), void* privdat);
00289   double density_integrate_sum_parallel(const struct density* d, double (*f)(double x, double y, double z, void* privdat), void** privdat);
00290 
00291 
00292 #ifdef __cplusplus
00293 }
00294 #endif
00295 
00296 #endif      /* !WAVEFUNCTION_H_ */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines