gimme-alpha 0.1

matdb.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libmodeling/matdb.h>
Include dependency graph for matdb.c:

Go to the source code of this file.

Classes

struct  property_passthru

Defines

#define ALLOY_PERCENT_MAX_FIELD_LENGTH   9

Functions

static guint g_string_hash2 (gconstpointer p)
static gboolean g_string_equal2 (gconstpointer a, gconstpointer b)
static void destroy_double (gpointer data)
static void destroy_gstring (gpointer data)
static void destroy_hashtable (gpointer data)
static void print_property (gpointer key, gpointer value, gpointer user_data)
static void print_inner_bowing (gpointer key, gpointer value, gpointer user_data)
static void print_material (gpointer key, gpointer value, gpointer user_data)
static void print_bowing (gpointer key, gpointer value, gpointer user_data)
void print_matdb (const struct matdb *mdb)
double get_alloy_param (const struct matdb *mdb, const char *mat1, const char *mat2, double x, const char *param, int *err)
double get_material_param (const struct matdb *mdb, const char *mat, const char *param, int *err)
void set_material_param (struct matdb *mdb, const char *mat, const char *param, double value, int *err)
void set_bowing_param (struct matdb *mdb, const char *mat1, const char *mat2, const char *param, double value, int *err)
double get_param (const struct matdb *mdb, const char *mat1, const char *mat2, double x, const char *param, int *err)
struct matdbmatdb_new ()
void canonicalize_alloy_args (char **mat1, char **mat2, double *x)
GString * canonicalize_alloy (char **mat1, char **mat2, double *x)
static void assemble_properties_foreach (gpointer key, gpointer data, gpointer private)
struct materialget_alloy (const struct matdb *mdb, const char *mat1, const char *mat2, double x)
void matdb_destroy (struct matdb *mdb)

Define Documentation

#define ALLOY_PERCENT_MAX_FIELD_LENGTH   9

Definition at line 28 of file matdb.c.

Referenced by canonicalize_alloy().


Function Documentation

static void assemble_properties_foreach ( gpointer  key,
gpointer  data,
gpointer  private 
) [static]

Definition at line 364 of file matdb.c.

References alloy_bowed(), alloy_linear(), property_passthru::bowings, property_passthru::ppts2, and property_passthru::x.

Referenced by get_alloy().

                                                                                       {
  struct property_passthru *pt = (struct property_passthru*)private;
  double *v;
  double *v2;
  double *bow = NULL;
  /*Make sure the property is set for material 2.*/
  if((v2 = g_hash_table_lookup(pt->ppts2, (GString*)key)) == NULL) return;
  if(pt->bowings != NULL) bow = g_hash_table_lookup(pt->bowings, (GString*)key);
  v = (double*)malloc(sizeof(double));
  if(bow != NULL) {
    *v = alloy_bowed(*(double*)key, *v2, *bow, pt->x);
  }else{
    *v = alloy_linear(*(double*)key, *v2, pt->x);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

GString* canonicalize_alloy ( char **  mat1,
char **  mat2,
double *  x 
)

Definition at line 337 of file matdb.c.

References ALLOY_PERCENT_MAX_FIELD_LENGTH, and canonicalize_alloy_args().

Referenced by get_alloy().

                                                                 {
  if(((*x) < 0) || ((*x) > 1)) return NULL;
  GString *name;
  char x1[ALLOY_PERCENT_MAX_FIELD_LENGTH];
  char x2[ALLOY_PERCENT_MAX_FIELD_LENGTH];
  canonicalize_alloy_args(mat1, mat2, x);
  snprintf(x1, ALLOY_PERCENT_MAX_FIELD_LENGTH, "%.5f", *x);
  snprintf(x2, ALLOY_PERCENT_MAX_FIELD_LENGTH, "%.5f", (1.0-(*x)));
  x1[ALLOY_PERCENT_MAX_FIELD_LENGTH-1]='\0';
  x2[ALLOY_PERCENT_MAX_FIELD_LENGTH-1]='\0';
  name = g_string_new(*mat1);
  name = g_string_append(name, "_");
  name = g_string_append(name, x1);
  name = g_string_append(name, "/");
  name = g_string_append(name, *mat2);
  name = g_string_append(name, "_");
  name = g_string_append(name, x2);
  return name;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void canonicalize_alloy_args ( char **  mat1,
char **  mat2,
double *  x 
)

Definition at line 327 of file matdb.c.

Referenced by canonicalize_alloy().

                                                                  {
  if(((*x) < 0) || ((*x) > 1)) return;
  char* t;
  if(strcmp(*mat1, *mat2) >= 0) {
    t = *mat1;
    *mat1 = *mat2;
    *mat2 = t;
    *x = 1.0-(*x);
  }
}

Here is the caller graph for this function:

static void destroy_double ( gpointer  data) [static]

Definition at line 38 of file matdb.c.

Referenced by get_alloy(), set_bowing_param(), and set_material_param().

                                         {
  free((double*)data);
}

Here is the caller graph for this function:

static void destroy_gstring ( gpointer  data) [static]

Definition at line 41 of file matdb.c.

Referenced by get_alloy(), matdb_new(), set_bowing_param(), and set_material_param().

                                          {
  g_string_free((GString*)data, TRUE);
}

Here is the caller graph for this function:

static void destroy_hashtable ( gpointer  data) [static]

Definition at line 44 of file matdb.c.

Referenced by matdb_new(), and set_bowing_param().

                                            {
  g_hash_table_destroy((GHashTable*)data);
}

Here is the caller graph for this function:

static gboolean g_string_equal2 ( gconstpointer  a,
gconstpointer  b 
) [static]

Definition at line 34 of file matdb.c.

References str.

Referenced by get_alloy(), matdb_new(), set_bowing_param(), and set_material_param().

                                                                  {
  return g_str_equal(((GString*)a)->str, ((GString*)b)->str);
}

Here is the caller graph for this function:

static guint g_string_hash2 ( gconstpointer  p) [static]

Definition at line 30 of file matdb.c.

References str.

Referenced by get_alloy(), matdb_new(), set_bowing_param(), and set_material_param().

                                             {
  return g_str_hash(((GString*)p)->str);
}

Here is the caller graph for this function:

struct material* get_alloy ( const struct matdb mdb,
const char *  mat1,
const char *  mat2,
double  x 
) [read]

Definition at line 380 of file matdb.c.

References assemble_properties_foreach(), property_passthru::bowings, matdb::bowings, canonicalize_alloy(), destroy_double(), destroy_gstring(), property_passthru::final_ppts, g_string_equal2(), g_string_hash2(), matdb::materials, material::name, property_passthru::ppts2, material::storage, and property_passthru::x.

                                                                                                  {
  struct material* m;
  if((m= (struct material*)malloc(sizeof(struct material))) == NULL) return NULL;
  if((m->storage = (struct alloy_storage*)malloc(sizeof(struct alloy_storage))) == NULL) {
    free(m);
    return NULL;
  }
  char *mt1 = (char*)mat1;
  char *mt2 = (char*)mat2;
  double ex = x;
  m->name = canonicalize_alloy(&mt1, &mt2, &ex);
  
  if(m->name == NULL) {
    free((struct material*)(m->storage));
    free(m);
    return NULL;
  }
  GString *m1 = g_string_new(mat1);
  GString *m2 = g_string_new(mat2);
  GHashTable *ppts1 = g_hash_table_lookup(mdb->materials, m1);
  GHashTable *ppts2 = g_hash_table_lookup(mdb->materials, m2);
  GHashTable *bowings = g_hash_table_lookup(mdb->bowings, m1);
  if(bowings != NULL) bowings = g_hash_table_lookup(bowings, m2);
  GHashTable *final_ppts = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_double);
  if((m->name == NULL) || (final_ppts == NULL) || (ppts1 == NULL) || (ppts2 == NULL)) {
    g_string_free(m1, TRUE);
    g_string_free(m2, TRUE);
    if(final_ppts != NULL) g_hash_table_destroy(final_ppts);
    free((struct material*)(m->storage));
    free(m);
    return NULL;
  }
  struct property_passthru pt;
  pt.ppts2 = ppts2;
  pt.bowings = bowings;
  pt.final_ppts = final_ppts;
  pt.x = ex;
  g_hash_table_foreach(ppts1, assemble_properties_foreach, &pt);
  g_string_free(m1, TRUE);
  g_string_free(m2, TRUE);
  ((struct alloy_storage*)m->storage)->ppts = final_ppts;
  ((struct alloy_storage*)m->storage)->mat1 = m1;
  ((struct alloy_storage*)m->storage)->mat2 = m2;
  ((struct alloy_storage*)m->storage)->x = ex;
  return m;
}

Here is the call graph for this function:

double get_alloy_param ( const struct matdb mdb,
const char *  mat1,
const char *  mat2,
double  x,
const char *  param,
int *  err 
)

Definition at line 81 of file matdb.c.

References alloy_bowed(), alloy_linear(), matdb::bowings, matdb::materials, and unlikely.

Referenced by get_alloy_early_1_n2_1_b(), get_alloy_early_1_n2_2_l(), get_param(), set_get_alloy_1_2_1_b(), and set_get_alloy_1_2_2_l().

                                                                                                                           {
  //fprintf(stderr, "get_alloy_param(%s, %s, %g, %s):", mat1, mat2, x, param);
  GString* m1 = g_string_new(mat1);
  GString* m2 = g_string_new(mat2);
  GString* p = g_string_new(param);
  GHashTable *ppts;
  GHashTable *ppts1;
  GHashTable *ppts2;
  double *v1;
  double *v2;
  double *bow = NULL;
  /*is a hash indexed by the first material, containing a hash indexed
   * by the second material.*/
  if((ppts = g_hash_table_lookup(mdb->bowings, m1)) == NULL) {
    /*If there's no bowing param, we just use a linear interpolation.*/
    if((ppts = g_hash_table_lookup(mdb->bowings, m2)) != NULL) {
      ppts = g_hash_table_lookup(ppts, m1);
    }
  }else{
    ppts = g_hash_table_lookup(ppts, m2);
  }
  if(ppts != NULL) {
    bow = g_hash_table_lookup(ppts, p);
  }
  if(unlikely((ppts1 = g_hash_table_lookup(mdb->materials, m1)) == NULL)) {
    *err = 2;
    g_string_free(m1, TRUE);
    g_string_free(m2, TRUE);
    g_string_free(p, TRUE);
    return 0;
  }else{
    if(unlikely((v1 = g_hash_table_lookup(ppts1, p)) == NULL)) {
      *err = 3;
      g_string_free(m1, TRUE);
      g_string_free(m2, TRUE);
      g_string_free(p, TRUE);
      return 0;
    }
  }
  if(unlikely((ppts2 = g_hash_table_lookup(mdb->materials, m2)) == NULL)) {
    *err = 4;
    g_string_free(m1, TRUE);
    g_string_free(m2, TRUE);
    g_string_free(p, TRUE);
    return 0;
  }else{
    if(unlikely((v2 = g_hash_table_lookup(ppts2, p)) == NULL)) {
      *err = 5;
      g_string_free(m1, TRUE);
      g_string_free(m2, TRUE);
      g_string_free(p, TRUE);
      return 0;
    }
  }
  *err = 0;
  if(bow != NULL) {
    //fprintf(stderr, "bow=%g alloy=%g\n", *bow, alloy_bowed(*v1, *v2, *bow, x));
    g_string_free(m1, TRUE);
    g_string_free(m2, TRUE);
    g_string_free(p, TRUE);
    return alloy_bowed(*v1, *v2, *bow, x);
  }else{
    //fprintf(stderr, "bow=[none] alloy=%g\n", alloy_linear(*v1, *v2, x));
    g_string_free(m1, TRUE);
    g_string_free(m2, TRUE);
    g_string_free(p, TRUE);
    return alloy_linear(*v1, *v2, x);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

double get_material_param ( const struct matdb mdb,
const char *  mat,
const char *  param,
int *  err 
)

Definition at line 156 of file matdb.c.

References likely, matdb::materials, and unlikely.

Referenced by get_alloy_early_1_n2_1_b(), get_alloy_early_1_n2_2_l(), get_param(), set_get_alloy_1_2_1_b(), set_get_alloy_1_2_2_l(), set_get_material_1_1(), set_get_material_1_2(), set_get_material_2_1(), and set_get_material_2_2().

                                                                                                 {
  GString* m = g_string_new(mat);
  GString* p = g_string_new(param);
  GHashTable *ppts;
  double* v;
  //fprintf(stderr, "get_material_param: m=%s p=%s\n", m->str, p->str);
  ppts = g_hash_table_lookup(mdb->materials, m);
  if(likely(ppts != NULL)) {
    if(unlikely((v = g_hash_table_lookup(ppts, p)) == NULL)) {
      *err = 2;
      g_string_free(m, TRUE);
      g_string_free(p, TRUE);
      return 0;
    }
  }else{
    *err = 1;
    g_string_free(m, TRUE);
    g_string_free(p, TRUE);
    return 0;
  }
  *err = 0;
  g_string_free(m, TRUE);
  g_string_free(p, TRUE);
  return *v;
}

Here is the caller graph for this function:

double get_param ( const struct matdb mdb,
const char *  mat1,
const char *  mat2,
double  x,
const char *  param,
int *  err 
)

Definition at line 305 of file matdb.c.

References get_alloy_param(), and get_material_param().

                                                                                                                     {
  if(mat2 == NULL) return get_material_param(mdb, mat1, param, err);
  else return get_alloy_param(mdb, mat1, mat2, x, param, err);
}

Here is the call graph for this function:

void matdb_destroy ( struct matdb mdb)

Definition at line 427 of file matdb.c.

References matdb::materials.

Referenced by destroy_matdb().

                                      {
  g_hash_table_destroy(mdb->materials);
  g_hash_table_destroy(mdb->materials);
}

Here is the caller graph for this function:

struct matdb* matdb_new ( ) [read]

Definition at line 310 of file matdb.c.

References matdb::bowings, destroy_gstring(), destroy_hashtable(), g_string_equal2(), g_string_hash2(), matdb::materials, and mdb.

Referenced by create_matdb().

                          {
  struct matdb* mdb = (struct matdb*)malloc(sizeof(struct matdb));
  if(mdb == NULL) return NULL;
  mdb->materials = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_hashtable);
  if(mdb->materials == NULL) {
    free(mdb);
    return NULL;
  }
  mdb->bowings = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_hashtable);
  if(mdb->bowings == NULL) {
    g_hash_table_destroy(mdb->materials);
    free(mdb);
    return NULL;
  }
  return mdb;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_bowing ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 62 of file matdb.c.

References print_inner_bowing().

Referenced by print_matdb().

                                                                           {
  g_hash_table_foreach((GHashTable*)value, &print_inner_bowing, key);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_inner_bowing ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 52 of file matdb.c.

References print_property(), and str.

Referenced by print_bowing().

                                                                                 {
  fprintf(stderr, "\t%s/%s:\n", ((GString*) key)->str, ((GString*)user_data)->str);
  g_hash_table_foreach((GHashTable*)value, &print_property, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void print_matdb ( const struct matdb mdb)

Definition at line 66 of file matdb.c.

References matdb::bowings, matdb::materials, print_bowing(), and print_material().

                                          {
  fprintf(stderr, "matdb/MATERIALS:\n");
  g_hash_table_foreach(mdb->materials, &print_material, NULL);
  fprintf(stderr, "matdb/BOWINGS:\n");
  g_hash_table_foreach(mdb->bowings, &print_bowing, NULL);
}

Here is the call graph for this function:

static void print_material ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 57 of file matdb.c.

References print_property(), and str.

Referenced by print_matdb().

                                                                             {
  fprintf(stderr, "\tmaterial %s:\n", ((GString*)key)->str);
  g_hash_table_foreach((GHashTable*)value, &print_property, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_property ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 48 of file matdb.c.

Referenced by print_inner_bowing(), and print_material().

                                                                             {
  fprintf(stderr, "\t\t%s=%g:\n", (char*)key, *(double*)value);
}

Here is the caller graph for this function:

void set_bowing_param ( struct matdb mdb,
const char *  mat1,
const char *  mat2,
const char *  param,
double  value,
int *  err 
)

Definition at line 226 of file matdb.c.

References matdb::bowings, destroy_double(), destroy_gstring(), destroy_hashtable(), g_string_equal2(), g_string_hash2(), matdb::materials, and unlikely.

Referenced by get_alloy_early_1_n2_1_b(), and set_get_alloy_1_2_1_b().

                                                                                                                        {
  //fprintf(stderr, "set_bowing_param(%s, %s, %s, %g) ", mat1, mat2, param, value);
  GString *p = g_string_new(param);
  GString *p2 = g_string_new(param);
  GString *m1 = g_string_new(mat1);
  GString *m2 = g_string_new(mat2);
  /*for the 2nd-level table*/
  GString *m1_2 = g_string_new(mat1);
  GString *m2_2 = g_string_new(mat2);
  GHashTable *ppts;
  GHashTable *ppts2;
  double *v;
  /*First, ensure that the property has been set for both m1 and mat2.*/
  if(unlikely((ppts = g_hash_table_lookup(mdb->materials, m1)) == NULL)){
    //fprintf(stderr, "!mat1 (err1)\n");
    *err = 1;
    return;
  }
  if(unlikely((v = g_hash_table_lookup(ppts, p)) == NULL)){
    //fprintf(stderr, "!mat1/param (err2)\n");
    *err = 2;
    return;
  }
  if(unlikely((ppts2 = g_hash_table_lookup(mdb->materials, m2)) == NULL)){
    //fprintf(stderr, "!mat2 (err3)\n");
    *err = 3;
    return;
  }
  if(unlikely((v = g_hash_table_lookup(ppts2, p)) == NULL)){
    //fprintf(stderr, "!mat2/param (err4)\n");
    *err = 4;
    return;
  }
  GHashTable *l2_table;
  GHashTable *l2_table2;
  /*We ensure that the bowings are set for both m1->m2 and m2->m1*/
  if((l2_table = g_hash_table_lookup(mdb->bowings, m1)) == NULL) {
    /*Make a new structure.*/
    l2_table = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_hashtable);
    g_hash_table_insert(mdb->bowings, m1, l2_table);
  }else{
    g_string_free(m1, TRUE);
  }
  /*Make sure that, if need be, there's a struct for the other way.*/
  if((l2_table2 = g_hash_table_lookup(mdb->bowings, m2)) == NULL) {
    /*Make a new structure.*/
    l2_table2 = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_hashtable);
    g_hash_table_insert(mdb->bowings, m2, l2_table2);
  }else{
    g_string_free(m2, TRUE);
  }
  /*We can't just have m1,m2 and m2,m1 point to the same hash
   * table; Otherwise, on deletion (and therefore on inserting
   * duplicate data), the structure will be freed/destroyed twice!
   */
  if((ppts = g_hash_table_lookup(l2_table, m2_2)) == NULL) {
    /*Need to make a hash for the properties.*/
    ppts = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_double);
    g_hash_table_insert(l2_table, m2_2, ppts);
  }else{
    g_string_free(m2_2, TRUE);
  }
  if((ppts2 = g_hash_table_lookup(l2_table2, m1_2)) == NULL) {
    /*Need to make a hash for the properties.*/
    ppts2 = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_double);
    g_hash_table_insert(l2_table2, m1_2, ppts2);
  }else{
    g_string_free(m1_2, TRUE);
  }
  /*Now we can insert the value into the ppts.*/
  double *v1 = (double*)malloc(sizeof(double));
  double *v2 = (double*)malloc(sizeof(double));
  *v1 = *v2 = value;
  g_hash_table_insert(ppts, p, v1);
  g_hash_table_insert(ppts2, p2, v2);
  *err = 0;
  //fprintf(stderr, "\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void set_material_param ( struct matdb mdb,
const char *  mat,
const char *  param,
double  value,
int *  err 
)

Definition at line 187 of file matdb.c.

References destroy_double(), destroy_gstring(), g_string_equal2(), g_string_hash2(), matdb::materials, and unlikely.

Referenced by set_get_material_1_1(), set_get_material_1_2(), set_get_material_2_1(), and set_get_material_2_2().

                                                                                                       {
  GString *p = g_string_new(param);
  GString *m = g_string_new(mat);
  GHashTable *ppts;
  //fprintf(stderr, "set_material_param: m=%s p=%s, value=%g\n", m->str, p->str, value);
  if((ppts = g_hash_table_lookup(mdb->materials, m)) == NULL) {
    /*Make a new structure.*/
    ppts = g_hash_table_new_full(g_string_hash2, g_string_equal2, destroy_gstring, destroy_double);
    g_hash_table_insert(mdb->materials, m, ppts);
  }else{
    g_string_free(m, TRUE);
  }
  double *v = (double*)malloc(sizeof(double));
  if(v == NULL) {
    *err = 1;
    g_string_free(m, TRUE);
    g_string_free(p, TRUE);
    return;
  }
  #ifdef DEBUG
  if(unlikely(g_hash_table_lookup(ppts, p) != NULL)) {
    *err = 3;
  }else{
  #endif
    *err = 0;
  #ifdef DEBUG
  }
  #endif
  *v = value;
  g_hash_table_insert(ppts, p, v);
}

Here is the call graph for this function:

Here is the caller graph for this function:

 All Classes Files Functions Variables Enumerations Enumerator Defines