tgrain.c: specify write precision in header - granular - granular dynamics simulation
 (HTM) git clone git://src.adamsgaard.dk/granular
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 828052591c1463144a4df91161a1c9a1749eefbe
 (DIR) parent 63c202266c5d9e8a17e8923c0d51f99fa9de1c98
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Thu, 18 Mar 2021 10:41:58 +0100
       
       grain.c: specify write precision in header
       
       write format should be strict, read is flexible
       
       Diffstat:
         M grain.c                             |      46 ++++++++++++++++++++++++-------
         M grain.h                             |       4 +++-
       
       2 files changed, 39 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/grain.c b/grain.c
       t@@ -1,10 +1,22 @@
        #include <stdio.h>
       +#include <stdlib.h>
        #include <math.h>
       +#include <err.h>
        #include "granular.h"
        #include "util.h"
        #include "grain.h"
        #include "arrays.h"
        
       +#define FLOATPREC 17
       +
       +struct grain *
       +grain_new(void)
       +{
       +        struct grain *g = malloc(sizeof(*g));
       +        grain_defaults(g);
       +        return g;
       +}
       +
        void
        grain_defaults(struct grain *g)
        {
       t@@ -47,7 +59,7 @@ print_padded_nd_double(FILE *stream, const double *arr)
                
                for (i = 0; i < ND; i++)
                        if (i < ND)
       -                        fprintf(stream, "%.17g\t", arr[i]);
       +                        fprintf(stream, "%.*g\t", FLOATPREC, arr[i]);
                        else
                                fprintf(stream, "0.0\t");
        }
       t@@ -67,7 +79,7 @@ print_padded_nd_int(FILE *stream, const size_t *arr)
        void
        grain_print(FILE *stream, const struct grain *g)
        {
       -        fprintf(stream, "%.17g\t", g->radius);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->radius);
                print_padded_nd_double(stream, g->pos);
                print_padded_nd_double(stream, g->vel);
                print_padded_nd_double(stream, g->acc);
       t@@ -78,23 +90,37 @@ grain_print(FILE *stream, const struct grain *g)
                print_padded_nd_double(stream, g->torque);
                print_padded_nd_double(stream, g->disp);
                print_padded_nd_double(stream, g->forceext);
       -        fprintf(stream, "%.17g\t", g->density);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->density);
                fprintf(stream, "%ld\t", g->fixed);
                fprintf(stream, "%ld\t", g->rotating);
                fprintf(stream, "%ld\t", g->enabled);
       -        fprintf(stream, "%.17g\t", g->youngs_modulus);
       -        fprintf(stream, "%.17g\t", g->poissons_ratio);
       -        fprintf(stream, "%.17g\t", g->friction_coeff);
       -        fprintf(stream, "%.17g\t", g->tensile_strength);
       -        fprintf(stream, "%.17g\t", g->shear_strength);
       -        fprintf(stream, "%.17g\t", g->fracture_toughness);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->youngs_modulus);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->poissons_ratio);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->friction_coeff);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->tensile_strength);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->shear_strength);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->fracture_toughness);
                print_padded_nd_int(stream, g->gridpos);
                fprintf(stream, "%ld\t", g->ncontacts);
                print_padded_nd_double(stream, g->contact_stress);
       -        fprintf(stream, "%.17g\t", g->thermal_energy);
       +        fprintf(stream, "%.*g\t", FLOATPREC, g->thermal_energy);
                fprintf(stream, "%ld\n", g->color);
        }
        
       +struct grain *
       +grain_read(char *line)
       +{
       +        struct grain *g = malloc(sizeof(*g));
       +
       +        if (sscanf(line, "%lg\t", &g->radius) != 1)
       +                errx(1, "%s: could not read line: %s", __func__, line);
       +
       +        if (grain_check_values(g))
       +                errx(1, "%s: invalid values in grain line: %s", __func__, line);
       +
       +        return g;
       +}
       +
        int
        grain_check_values(const struct grain *g)
        {
 (DIR) diff --git a/grain.h b/grain.h
       t@@ -33,9 +33,11 @@ struct grain {
                size_t color;
        };
        
       -void grain_init(struct grain *g);
       +struct grain * grain_new(void);
       +void grain_defaults(struct grain *g);
        
        void grain_print(FILE *stream, const struct grain *g);
       +struct grain * grain_read(char *line);
        
        int grain_check_values(const struct grain *g);