k-dot-p 0.1

matdb.c++

Go to the documentation of this file.
00001 /*
00002  * matdb: generic materials database information.
00003 
00004 
00005 
00006  Copyright (C) 2009 Joseph Pingenot
00007 
00008  This program is free software: you can redistribute it and/or modify
00009  it under the terms of the GNU Affero General Public License as published by
00010  the Free Software Foundation, either version 3 of the License, or
00011  (at your option) any later version.
00012 
00013  This program is distributed in the hope that it will be useful,
00014  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  GNU Affero General Public License for more details.
00017 
00018  You should have received a copy of the GNU Affero General Public License
00019  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <math.h>
00026 #include <glib.h>
00027 #include <libmodelxx/matdb.h++>
00028 
00029 
00030 namespace kdotp {
00031   namespace libmodelxx {
00032     namespace structure {
00033 
00034       static void print_property(gpointer key, gpointer value, gpointer user_data) {
00035   fprintf(stderr, "\t\t%s=%g:\n", (char*)key, *(double*)value);
00036       }
00037       static void print_inner_bowing(gpointer key, gpointer value, gpointer user_data) {
00038   struct matdb_bowing *bowing = (struct matdb_bowing*)value;
00039   fprintf(stderr, "\tbowing %s:%s[%s:%s]:\n", bowing->from->str, bowing->to->str, (char*)user_data, (char*)key);
00040   g_hash_table_foreach(bowing->properties, &print_property, NULL);
00041       }
00042       static void print_material(gpointer key, gpointer value, gpointer user_data) {
00043   struct matdb_material *mat = (struct matdb_material*)value;
00044   fprintf(stderr, "\tmaterial %s(%s):\n", mat->name->str, (char*)key);
00045   g_hash_table_foreach(mat->properties, &print_property, NULL);
00046       }
00047       static void print_bowing(gpointer key, gpointer value, gpointer user_data) {
00048   GHashTable *ht = (GHashTable*)value;
00049   g_hash_table_foreach(ht, &print_inner_bowing, key);
00050       }
00051 
00052       void print_matdb(const struct matdb *mdb) {
00053   fprintf(stderr, "matdb:\n");
00054   g_hash_table_foreach(mdb->materials, &print_material, NULL);
00055   g_hash_table_foreach(mdb->bowings, &print_bowing, NULL);
00056       }
00057 
00058       void destroy_material_gpointer(gpointer data) {
00059   destroy_material((struct matdb_material *)data);
00060       }
00061       void destroy_bowing_gpointer(gpointer data) {
00062   destroy_bowing((struct matdb_bowing *)data);
00063       }
00064       void destroy_material(struct matdb_material *mat) {
00065 #ifdef DEBUG
00066   fprintf(stderr, "destroy_material\n");
00067 #endif
00068   g_string_free(mat->name, TRUE);
00069   g_hash_table_unref(mat->properties);
00070   free(mat);
00071       }
00072       void destroy_bowing(struct matdb_bowing *bow) {
00073 #ifdef DEBUG
00074   fprintf(stderr, "destroy_bowing\n");
00075 #endif
00076   g_string_free(bow->from, TRUE);
00077   g_string_free(bow->to, TRUE);
00078   g_hash_table_unref(bow->properties);
00079   free(bow);
00080       }
00081 
00082       double* new_double(double d) {double* D = (double*)malloc(sizeof(double)); *D = d; return D;}
00083 
00084       struct foreach_datum {
00085   GHashTable *new_table;
00086   GHashTable *mat2_ppts;
00087   GHashTable *bowings;
00088   char* mat1;
00089   char* mat2;
00090   double x;
00091       };
00092 
00093       /*Bowing definition from Vurgaftman*/
00094       double interpolate_with_bowing(double mat1, double mat2, double bow, double x) {
00095   return x*mat1 + (1-x)*mat2 - x*(1-x)*bow;
00096       }
00097 
00098       double interpolate_without_bowing(double mat1, double mat2, double x) {
00099   return x*mat1 + (1-x)*mat2;
00100       }
00101 
00102       void clone_each_property(gpointer key, gpointer value, gpointer data) {
00103   char* ppt = (char*)key;
00104   double* val1 = (double*)value;
00105   struct foreach_datum* fd = (struct foreach_datum*)data;
00106   double* val2;
00107   double* bow;
00108   double result;
00109   if(fd->mat2_ppts != NULL) {
00110     if(fd->mat2_ppts == NULL) {
00111       fprintf(stderr, "matdb.c++::clone_each_property: fd->mat2_ppts is NULL\n");
00112     }
00113     val2 = (double*)g_hash_table_lookup(fd->mat2_ppts, ppt);
00114     if(val2 == NULL) {
00115       fprintf(stderr, "matdb.c::clone_each_property: WARNING material %s in material %s is not set in %s; skipping for their alloy.\n", ppt, fd->mat1, fd->mat2);
00116       return;
00117     }else{
00118       
00119       if((fd->bowings == NULL) || ((bow = (double*)g_hash_table_lookup(fd->bowings, ppt)) == NULL)) {
00120         result = interpolate_without_bowing(*val1, *val2, fd->x);
00121       }else{
00122         result = interpolate_with_bowing(*val1, *val2, *bow, fd->x);
00123       }
00124     }
00125   } else {
00126     val2=NULL;
00127     result = *val1;
00128   }
00129   g_hash_table_insert(fd->new_table, g_strdup(ppt), new_double(result));
00130       }
00131 
00132       GHashTable* get_material(const struct matdb* matdb, const char* mat1, const char* mat2, double x) {
00133   if((x < 0) || (x>1)) {
00134     fprintf(stderr, "matdb::get_material: material %s(%f)%s doesn't exist: x not in range [0, 1]\n", mat1, x, mat2);
00135     return NULL;
00136   }
00137   if(((!(fabs(x-1.0)) < 1e-8) && (mat2 == NULL))){
00138     fprintf(stderr, "matdb::get_material: material %s(%f)%s doesn't exist: x!=1 and mat2 is NULL\n", mat1, x, mat2);
00139     return NULL;
00140   }
00141   struct foreach_datum fd;
00142   void* rv;
00143   if(matdb->materials == NULL) {
00144     fprintf(stderr, "matdb.c++::get_material: matdb->materials is NULL\n");
00145   }
00146   rv = g_hash_table_lookup(matdb->materials, mat1);
00147   GHashTable *ppts1 = NULL;
00148   if(rv == NULL) {
00149     fprintf(stderr, "matdb::get_material: unable to find material %s in materials database!\n", mat1);
00150     return NULL;
00151   } else {
00152     ppts1 = ((struct matdb_material*)rv)->properties;
00153   }
00154   if(mat2 == NULL) {
00155     fd.mat2_ppts = NULL;
00156   } else {
00157     rv = g_hash_table_lookup(matdb->materials, mat2);
00158     if(rv == NULL) {
00159       fprintf(stderr, "matdb::get_material: unable to find material %s in materials database!\n", mat2);
00160       return NULL;
00161     }
00162     fd.mat2_ppts = ((struct matdb_material*)rv)->properties;
00163   }
00164   fd.new_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
00165   /*We cast away the const-ness; we need to store these in a struct.*/
00166   fd.mat1 = (char*)mat1;
00167   fd.mat2 = (char*)mat2;
00168   fd.x = x;
00169   rv = NULL;
00170   /*Look up and set bowings, if they exist.*/
00171   if(mat2 != NULL) {
00172     if(matdb->bowings == NULL) {
00173       fprintf(stderr, "matdb.c++::get_material: matdb->bowings is NULL\n");
00174     }
00175     GHashTable *ht = (GHashTable*)g_hash_table_lookup(matdb->bowings, mat1);
00176     if(ht != NULL) {
00177       rv = g_hash_table_lookup(ht, mat2);
00178       if(rv != NULL) {
00179         fd.bowings = ((struct matdb_bowing*)rv)->properties;
00180       }else{
00181         fd.bowings = NULL;
00182       }
00183     }else{
00184       fd.bowings = NULL;
00185     }
00186   }else{
00187     fd.bowings = NULL;
00188   }
00189   g_hash_table_foreach(ppts1, clone_each_property, &fd);
00190   /*Everything else is someone else's pointers, so we don't have to free anything.*/
00191   return fd.new_table;
00192       }
00193 
00194       double get_property1(const struct matdb* matdb, const char* ppt, const char* mat, int* err) {
00195   void* rv;
00196   GHashTable *ppts1;
00197   if(matdb->materials == NULL) {
00198     fprintf(stderr, "matdb.c++::get_property1: matdb->materials is NULL\n");
00199   }
00200   rv = g_hash_table_lookup(matdb->materials, mat);
00201   if(rv == NULL) {
00202     fprintf(stderr, "matdb::get_material: unable to find material %s in materials database!\n", mat);
00203     *err = 1;
00204     return nan("NaN");
00205   } else {
00206     ppts1 = ((struct matdb_material*)rv)->properties;
00207   }
00208   if(ppts1 == NULL) {
00209     fprintf(stderr, "matdb.c++::get_property1: ppts1 is NULL\n");
00210   }
00211   rv = g_hash_table_lookup(ppts1, ppt);
00212   if(rv == NULL) {
00213     fprintf(stderr, "matdb.c::get_property2: unable to find property %s in material %s\n", ppt, mat);
00214     *err = 4;
00215     return nan("NaN");
00216   }
00217   *err = 0;
00218   return *(double*)rv;
00219       }
00220       double get_property2(const struct matdb* matdb, const char* ppt, const char* mat1, const char* mat2, double x, int* err){
00221   if((x < 0) || (x>0) || ((x != 1.0) && (mat2 == NULL))){
00222     fprintf(stderr, "matdb::get_material: material %s(%e)%s doesn't exist: x not in range [0, 1], or x==1 and mat2 is NULL\n", mat1, x, mat2);
00223     *err = 1;
00224     return nan("NaN");
00225   }
00226   void* rv;
00227   if(matdb->materials == NULL) {
00228     fprintf(stderr, "matdb.c++::get_property2: matdb->materials is NULL\n");
00229   }
00230   rv = g_hash_table_lookup(matdb->materials, mat1);
00231   GHashTable *ppts1 = NULL;
00232   if(rv == NULL) {
00233     fprintf(stderr, "matdb::get_property2: unable to find material %s in materials database!\n", mat1);
00234     *err = 2;
00235     return nan("NaN");
00236   } else {
00237     ppts1 = ((struct matdb_material*)rv)->properties;
00238   }
00239   GHashTable *ppts2;
00240   if(mat2 == NULL) {
00241     ppts2 = NULL;
00242   } else {
00243     if(matdb->materials == NULL) {
00244       fprintf(stderr, "matdb.c++::get_property2: matdb->materials is NULL\n");
00245     }
00246     rv = g_hash_table_lookup(matdb->materials, mat2);
00247     if(rv == NULL) {
00248       fprintf(stderr, "matdb::get_property2: unable to find material %s in materials database!\n", mat2);
00249       *err = 3;
00250       return nan("NaN");
00251     }
00252     ppts2 = ((struct matdb_material*)rv)->properties;
00253   }
00254   rv = NULL;
00255   GHashTable *bowings;
00256   /*Look up and set bowings, if they exist.*/
00257   if(mat2 != NULL) {
00258     if(matdb->bowings == NULL) {
00259       fprintf(stderr, "matdb.c++::get_property2: matdb->bowings is NULL\n");
00260     }
00261     GHashTable *ht = (GHashTable*)g_hash_table_lookup(matdb->bowings, mat1);
00262     if(ht != NULL) {
00263       rv = g_hash_table_lookup(ht, mat2);
00264       if(rv != NULL) {
00265         bowings = ((struct matdb_bowing*)rv)->properties;
00266       }else{
00267         bowings = NULL;
00268       }
00269     }else{
00270       bowings = NULL;
00271     }
00272   }else{
00273     bowings=NULL;
00274   }
00275   if(ppts1 == NULL) {
00276     fprintf(stderr, "matdb.c++::get_property2: ppts1 is NULL\n");
00277   }
00278   rv = g_hash_table_lookup(ppts1, ppt);
00279   if(rv == NULL) {
00280     fprintf(stderr, "matdb.c::get_property2: unable to find property %s in material %s\n", ppt, mat1);
00281     *err = 4;
00282     return nan("NaN");
00283   }
00284   double* val1 = (double*)rv;
00285   double* val2;
00286   double* bow;
00287   double result;
00288   if(ppts2 != NULL) {
00289     val2 = (double*)g_hash_table_lookup(ppts2, ppt);
00290     if(val2 == NULL) {
00291       fprintf(stderr, "matdb.c::clone_each_property: WARNING material %s in material %s is not set in %s; skipping for their alloy.\n", ppt, mat1, mat2);
00292       *err = 5;
00293       return nan("NaN");
00294     }else{
00295       if(bowings == NULL) {
00296         fprintf(stderr, "matdb.c++::get_property2: bowings is NULL\n");
00297       }
00298       if((bow = (double*)g_hash_table_lookup(bowings, ppt)) == NULL) {
00299         result = interpolate_without_bowing(*val1, *val2, x);
00300       }else{
00301         result = interpolate_with_bowing(*val1, *val2, *bow, x);
00302       }
00303     }
00304   } else {
00305     val2=NULL;
00306     result = *val1;
00307   }
00308   /*Everything is someone else's pointers, so we don't have to free anything.*/
00309   *err = 0;
00310   return result;
00311       }
00312       double get_bowing(const struct matdb* matdb, const char* ppt, const char* mat1, const char* mat2, int* err) {
00313   void *rv;
00314   GHashTable *bowings;
00315   /*Look up and set bowings, if they exist.*/
00316   if(matdb->bowings == NULL) {
00317     fprintf(stderr, "matdb.c++::get_bowing: bowings is NULL\n");
00318   }
00319   GHashTable *ht = (GHashTable*)g_hash_table_lookup(matdb->bowings, mat1);
00320   if(ht != NULL) {
00321     rv = g_hash_table_lookup(ht, mat2);
00322     if(rv != NULL) {
00323       bowings = ((struct matdb_bowing*)rv)->properties;
00324     }else{
00325       *err = 1;
00326       return nan("NaN");
00327     }
00328   }else{
00329     *err = 2;
00330     return nan("NaN");
00331   }
00332   double* bow;
00333   if(bowings == NULL) {
00334     fprintf(stderr, "matdb.c++::get_bowing: bowings is NULL\n");
00335   }
00336   if((bow = (double*)g_hash_table_lookup(bowings, ppt)) == NULL) {
00337     *err = 3;
00338     return nan("NaN");
00339   }
00340   *err = 0;
00341   return *bow;
00342       }
00343 
00344       void insert_external_material(struct matdb* matdb, const char* matname) {
00345   struct matdb_material* mat = (struct matdb_material*)malloc(sizeof(struct matdb_material));
00346   /*Create an empty hash table for the fake material.*/
00347   mat->name = g_string_new(matname);
00348   GString* s = g_string_new(matname);
00349   mat->properties = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
00350   g_hash_table_insert(matdb->materials, s->str, mat);
00351   g_string_free(s, FALSE);
00352       }
00353 
00354 
00355     }
00356   }
00357 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines