|
k-dot-p 0.1
|
00001 /* 00002 * materials.c++ 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 #include <stdlib.h> 00022 #include <stdio.h> 00023 #include <math.h> 00024 #include <glib.h> 00025 #include <libmodelxx/matdb.h++> 00026 #include <libmodelxx/material.h++> 00027 00028 namespace kdotp { 00029 namespace libmodelxx { 00030 namespace structure { 00031 00032 struct index_struct { 00033 double *a; 00034 GHashTable *ht; 00035 int next; 00036 }; 00037 00038 static void print_property(gpointer key, gpointer value, gpointer data) { 00039 fprintf(stderr, "key=%s value=%g\n", (char*)key, *(double*)value); 00040 } 00041 00042 int* alloc_set_int(int v) {int* ptr = (int*)malloc(sizeof(int)); *ptr = v; return ptr;} 00043 00044 /** 00045 *Indexes the properties of a material (used as a callback in a 00046 * g_hash_table_foreach call 00047 */ 00048 static void index_properties(gpointer key, gpointer value, gpointer data) { 00049 struct index_struct* idxs = (struct index_struct*)data; 00050 idxs->a[idxs->next] = *(double*)value; 00051 g_hash_table_insert(idxs->ht, g_strdup((gchar*)key), alloc_set_int(idxs->next)); 00052 (idxs->next)++; 00053 } 00054 00055 material::material(const struct matdb* mdb, const char* mat1, const char* mat2, double x) { 00056 properties = get_material(mdb, mat1, mat2, x); 00057 /*Kick out if the material specified doesn't exist.*/ 00058 if(properties == NULL) { 00059 fprintf(stderr, "ERROR in material consturctor: unable to get properties for material: %s/%g/%s\n", mat1, x, mat2); 00060 return; 00061 } 00062 int ptsize = g_hash_table_size(properties); 00063 indexed_properties = (double*)malloc(ptsize*sizeof(double)); 00064 property_indices = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); 00065 struct index_struct idxs = {indexed_properties, property_indices, 0}; 00066 /*Now we go ahead and set up the indexed hash*/ 00067 //g_hash_table_foreach(properties, print_property, NULL); 00068 if(properties == NULL) { 00069 fprintf(stderr, "material::material: properties is NULL!\n"); 00070 } 00071 if(property_indices == NULL) { 00072 fprintf(stderr, "material::material: property_indices is NULL!\n"); 00073 } 00074 g_hash_table_foreach(properties, index_properties, &idxs); 00075 //g_hash_table_foreach(properties, print_property, NULL); 00076 matname1 = g_strdup(mat1); 00077 matname2 = g_strdup(mat2); 00078 m_x = x; 00079 } 00080 00081 double material::get_property(const char* ppt, int* err) { 00082 //fprintf(stderr, "Looking up property %s: ", ppt); 00083 if(properties == NULL) { 00084 fprintf(stderr, "Error getting property %s: properties is NULL!!\n", ppt); 00085 return nan("NaN"); 00086 } 00087 double* match = (double*)g_hash_table_lookup(properties, ppt); 00088 if(match == NULL) { 00089 //fprintf(stderr, "FAILED\n"); 00090 *err = 1; 00091 return nan("NaN"); 00092 } 00093 //fprintf(stderr, "%g\n", *match); 00094 *err = 0; 00095 return *match; 00096 } 00097 00098 00099 int material::get_property_index(const char* ppt, int* err) { 00100 if(property_indices == NULL) { 00101 return -2; 00102 } 00103 int* i = (int*)g_hash_table_lookup(property_indices, ppt); 00104 if(i == NULL) {*err = 1; return -1;} 00105 *err = 0; 00106 return *i; 00107 } 00108 00109 /*For some reason, this dosn't work as a const.*/ 00110 char* material::get_name() { 00111 GString* s = g_string_new(""); 00112 if(matname2 != NULL) { 00113 g_string_printf(s, "%s(%f)%s", matname1, m_x, matname2); 00114 }else{ 00115 g_string_printf(s, "%s", matname1); 00116 } 00117 char *c = s->str; 00118 g_string_free(s, FALSE); 00119 return c; 00120 } 00121 00122 bool operator==(const material& m1, const material& m2) { 00123 if(g_strcmp0(m1.matname1, m2.matname1)) return false; 00124 if(g_strcmp0(m1.matname2, m2.matname2)) return false; 00125 return m1.m_x == m2.m_x; 00126 } 00127 bool material::operator==(const material& m2) { 00128 if(g_strcmp0(matname1, m2.matname1)) return false; 00129 if(g_strcmp0(matname2, m2.matname2)) return false; 00130 return m_x == m2.m_x; 00131 } 00132 bool operator!=(const material& m1, const material& m2) { 00133 if(!(g_strcmp0(m1.matname1, m2.matname1))) return true; 00134 if(!(g_strcmp0(m1.matname2, m2.matname2))) return true; 00135 return m1.m_x != m2.m_x; 00136 } 00137 bool material::operator!=(const material& m2) { 00138 if(!(g_strcmp0(matname1, m2.matname1))) return true; 00139 if(!(g_strcmp0(matname2, m2.matname2))) return true; 00140 return m_x != m2.m_x; 00141 } 00142 bool material::lenient_equals(const material& m2, double tolerance) { 00143 if(g_strcmp0(matname1, m2.matname1)) return false; 00144 if(g_strcmp0(matname2, m2.matname2)) return false; 00145 if(fabs(m_x - m2.m_x) > fabs(tolerance*m_x)) return false; 00146 return fabs(m_x - m2.m_x) < fabs(tolerance*m2.m_x); 00147 } 00148 00149 } 00150 } 00151 } 00152