From 56c1d092f816ed8967b81153d2bdb046fd8c8502 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 18 Oct 2010 15:50:23 -0400 Subject: [PATCH] Add prelimiary check_* code for each *.h file in sawsim.nw. --- src/sawsim.nw | 418 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 341 insertions(+), 77 deletions(-) diff --git a/src/sawsim.nw b/src/sawsim.nw index 9e666be..3f810b7 100644 --- a/src/sawsim.nw +++ b/src/sawsim.nw @@ -742,6 +742,7 @@ and unfolding models are defined in Appendix \ref{sec.k_models}. <>= #define k_B 1.3806503e-23 /* J/K */ + @ @@ -1259,6 +1260,7 @@ We include [[math.h]], so don't forget to link to the libm with `-lm'. #include "tension_model.h" #include "parse.h" #include "accel_k.h" + @ <>= @@ -1343,6 +1345,7 @@ We also define a macro for our [[check]] unit testing -(received-expected)/expected, max_err, #received, \ expected, received); \ } while(0) + @ <>= @@ -2049,6 +2052,7 @@ void free_parsed_list(int num, char **string_array) Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. <>= +<> <> <> <> @@ -2073,10 +2077,10 @@ Here we check to make sure the various functions work as expected, using \citeta <>= Suite *test_suite (void) { - Suite *s = suite_create ("k model"); + Suite *s = suite_create ("parse"); <> - <> + <> return s; } @ @@ -2150,7 +2154,7 @@ END_TEST <>= TCase *tc_parse_list_string = tcase_create("parse list string"); @ -<>= +<>= //tcase_add_test(tc_parse_list_string, test_next_delim_index); tcase_add_test(tc_parse_list_string, test_parse_list_null); tcase_add_test(tc_parse_list_string, test_parse_list_single_simple); @@ -2184,7 +2188,6 @@ Here we check to make sure the various functions work as expected, using \citeta @ <>= -<> <> <> <> @@ -2196,17 +2199,15 @@ Here we check to make sure the various functions work as expected, using \citeta Suite *test_suite (void) { Suite *s = suite_create ("sawsim"); - <> <> <> <> <> - <> - <> - <> - <> - <> + <> + <> + <> + <> /* tcase_add_checked_fixture(tc_strip_address, @@ -2230,54 +2231,6 @@ int main(void) } @ -\subsection{F tests} -<>= -<> -@ -<>= -<> -@ -<>= -<> -@ - -<>= -<> - -START_TEST(test_wlc_at_zero) -{ - double T=1.0, L=1.0, p=0.1, x=0.0, lim=1e-30; - fail_unless(abs(wlc(x, T, p, L)) < lim, \ - "abs(wlc(x=%g,T=%g,p=%g,L=%g)) = %g >= %g", - x, T, p, L, abs(wlc(x, T, p, L)), lim); -} -END_TEST - -START_TEST(test_wlc_at_half) -{ - double T=1.0, L=1.0, p=0.1*k_B, x=0.5; - /* prefactor = k_B T / p = k_B 1.0 / (k_B*0.1) = 10.0 J/nm = 10.0e21 pN - * nonlinear term = 0.25 (1/(1-x/L)^2-1) = 0.25(1/.25 - 1) - * = 0.25 * 3 = 3/4 - * linear term = x/L = 0.5 - * nonlinear + linear = 0.75 + 0.5 = 1.25 - * wlc = 10e21*1.25 = 12.5e21 - */ - fail_unless(wlc(x, T, p, L)-12.5e21 < 1e16, - "wlc(%g, %g, %g, %g) = %g != %g", - x, T, p, L, wlc(x, T, p, L), 12.5e21); -} -END_TEST -@ -<>= -TCase *tc_wlc = tcase_create("WLC"); -@ - -<>= -tcase_add_test(tc_wlc, test_wlc_at_zero); -tcase_add_test(tc_wlc, test_wlc_at_half); -suite_add_tcase(s, tc_wlc); -@ \subsection{Model tests} @@ -2318,7 +2271,7 @@ END_TEST <>= TCase *tc_determine_dt = tcase_create("Determine dt"); @ -<>= +<>= tcase_add_test(tc_determine_dt, test_determine_dt_linear_k); suite_add_tcase(s, tc_determine_dt); @ @@ -2327,21 +2280,21 @@ suite_add_tcase(s, tc_determine_dt); @ <>= @ -<>= +<>= @ <>= @ <>= @ -<>= +<>= @ <>= @ <>= @ -<>= +<>= @ @@ -2810,6 +2763,7 @@ double length_scale = 1e-10; /* HACK */ Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. <>= +<> <> <> <
> @@ -3316,6 +3270,7 @@ The user must free the data pointed to by the node on their own. Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. <>= +<> <> <> <
> @@ -3613,6 +3568,7 @@ The [[while]] loop around [[wait]] protects [[wait]] from interrupting signals. Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. <>= +<> <> <> <> @@ -3640,7 +3596,7 @@ Suite *test_suite (void) Suite *s = suite_create ("string eval"); <> - <> + <> return s; } @ @@ -3658,7 +3614,7 @@ START_TEST(test_invalid_command) FILE *in, *out; char input[80], output[80]={}; string_eval_setup(&in, &out); - sprintf(input, "print ABCDefg\n"); + sprintf(input, "print undefined_name__traceback_should_be_printed_to_stderr\n"); string_eval(in, out, input, 80, output); string_eval_teardown(&in, &out); } @@ -3705,7 +3661,7 @@ END_TEST <>= TCase *tc_string_eval = tcase_create("string_eval"); @ -<>= +<>= tcase_add_test(tc_string_eval, test_setup_teardown); tcase_add_test_raise_signal(tc_string_eval, test_invalid_command, SIGKILL); tcase_add_test(tc_string_eval, test_simple_eval); @@ -3728,6 +3684,7 @@ The number of evaluation calls could be drastically reduced, however, by impleme <>= #ifndef ACCEL_K_H #define ACCEL_K_H +<> double accel_k(k_func_t *k, double F, environment_t *env, void *params); void free_accels(); #endif /* ACCEL_K_H */ @@ -3735,11 +3692,12 @@ void free_accels(); <>= NW_SAWSIM_MODS += accel_k -#CHECK_BINS += check_accel_k -check_accel_k_MODS = +CHECK_BINS += check_accel_k +check_accel_k_MODS = interp k_model parse string_eval tavl @ <>= +<> #include /* assert() */ #include /* realloc(), free(), NULL */ #include "global.h" /* environment_t */ @@ -3815,6 +3773,77 @@ double accel_k(k_func_t *k, double F, environment_t *env, void *params) } @ +\subsection{Unit tests} + +Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. +<>= +<> +<> +<> +<> +<> +<
> +@ + +<>= +#include /* EXIT_SUCCESS, EXIT_FAILURE */ +#include /* sprintf() */ +#include /* assert() */ +#include /* exp() */ +#include /* errno, ERANGE */ +<> +#include "global.h" +#include "k_model.h" +#include "accel_k.h" + +@ + +<>= +<> +<> +@ + +<>= +Suite *test_suite (void) +{ + Suite *s = suite_create ("accelerated k model"); + <> + + <> + return s; +} +@ + +<>= +TCase *tc_accel_k = tcase_create("accelerated k model"); +@ + +<>= +tcase_add_test(tc_accel_k, test_accel_k_accuracy); +suite_add_tcase(s, tc_accel_k); +@ + +<>= +START_TEST(test_accel_k_accuracy) +{ + double k, k_accel, F, Fm=0.0, FM=300e-12, dF=0.5e-12; + k_func_t *k_func = bell_k; + char *param_strings[] = {"3.3e-4", "0.25e-9"}; + void *params = string_create_bell_param_t(param_strings); + environment_t env = {}; + env.T = 300.0; + + for(F=Fm; F <= FM; F+=dF) { + k = k_func(F, &env, params); + k_accel = accel_k(k_func, F, &env, params); + CHECK_ERR(1e-8, k, k_accel); + } + destroy_bell_param_t(params); +} +END_TEST + +@ + \section{Tension models} \label{sec.tension_models} @@ -3841,8 +3870,8 @@ The interface is defined in [[tension_model.h]], the implementation in [[tension <>= NW_SAWSIM_MODS += tension_model -#CHECK_BINS += check_tension_model -check_tension_model_MODS = +CHECK_BINS += check_tension_model +check_tension_model_MODS = list tension_balance @ <>= TENSION_MODEL_MODS = tension_model parse list tension_balance @@ -4381,14 +4410,13 @@ $$ $$ where $L=Nl$ is the total length of the chain, and $\mathcal{L}(\alpha) \equiv \coth{\alpha} - \frac{1}{\alpha}$ is the Langevin function\citep{hatfield99}. <>= -double langevin(double x, void *params) +static double langevin(double x, void *params) { if (x==0) return 0; return 1.0/tanh(x) - 1/x; } -<> -<> -double inv_langevin(double x) + +static double inv_langevin(double x) { double lb=0.0, ub=1.0, ret; oneD_bracket(&langevin, NULL, x, 1.0, &lb, &ub); @@ -4396,13 +4424,14 @@ double inv_langevin(double x) return ret; } -double fjc(double x, double T, double l, int N) +static double fjc(double x, double T, double l, int N) { double L = l*(double)N; if (x == 0) return 0; //printf("x %g\tL%g\tx/L %g\n", x, L, x/L); return k_B*T/l * inv_langevin(x/L); } + @ <>= @@ -4896,6 +4925,239 @@ void get_options(int argc, char **argv, environment_t *env, } @ +\subsection{Tension model unit tests} + +Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. +<>= +<> +<> +<> +<> +<> +<
> +@ + +<>= +#include /* EXIT_SUCCESS, EXIT_FAILURE */ +#include /* sprintf() */ +#include /* assert() */ +#include /* exp() */ +#include /* errno, ERANGE */ +<> +#include "global.h" +#include "list.h" +#include "tension_balance.h" /* oneD_*() */ +#include "tension_model.h" +@ + +<>= +<> +<> +<> +<> +<> +<> +<> +@ + +<>= +Suite *test_suite (void) +{ + Suite *s = suite_create ("tension model"); + <> + <> + <> + <> + <> + + <> + <> + <> + <> + <> + return s; +} +@ + +\subsubsection{Constant} + +<>= +TCase *tc_const_tension = tcase_create("Constant tension"); +@ + +<>= +tcase_add_test(tc_const_tension, test_const_tension_create_destroy); +suite_add_tcase(s, tc_const_tension); +@ + +<>= +START_TEST(test_const_tension_create_destroy) +{ + char *tension[] = {"1","2.2", "3"}; + char *params[] = {tension[0]}; + void *p = NULL; + int i; + for( i=0; i < sizeof(tension)/sizeof(char *); i++) { + params[0] = tension[i]; + p = string_create_const_tension_param_t(params); + destroy_const_tension_param_t(p); + } +} +END_TEST + +@ TODO: In order to test the constant tension handler itself, we'd +have to construct a group. + + +\subsubsection{Hooke} + +<>= +TCase *tc_hooke = tcase_create("Hooke"); +@ + +<>= +tcase_add_test(tc_hooke, test_hooke_create_destroy); +suite_add_tcase(s, tc_hooke); + +@ + +<>= +START_TEST(test_hooke_create_destroy) +{ + char *k[] = {"1","2.2", "3"}; + char *params[] = {k[0]}; + void *p = NULL; + int i; + for( i=0; i < sizeof(k)/sizeof(char *); i++) { + params[0] = k[i]; + p = string_create_hooke_param_t(params); + destroy_hooke_param_t(p); + } +} +END_TEST + +@ TODO: In order to test the Hooke tension handler itself, we'd +have to construct a group. + + +\subsubsection{Worm-like chain} + +<>= +TCase *tc_wlc = tcase_create("WLC"); +@ + +<>= +tcase_add_test(tc_wlc, test_wlc_at_zero); +tcase_add_test(tc_wlc, test_wlc_at_half); +suite_add_tcase(s, tc_wlc); + +@ + +<>= +<> +START_TEST(test_wlc_at_zero) +{ + double T=1.0, L=1.0, p=0.1, x=0.0, lim=1e-30; + fail_unless(abs(wlc(x, T, p, L)) < lim, \ + "abs(wlc(x=%g,T=%g,p=%g,L=%g)) = %g >= %g", + x, T, p, L, abs(wlc(x, T, p, L)), lim); +} +END_TEST + +START_TEST(test_wlc_at_half) +{ + double T=1.0, L=1.0, p=0.1*k_B, x=0.5; + /* prefactor = k_B T / p = k_B 1.0 / (k_B*0.1) = 10.0 J/nm = 10.0e21 pN + * nonlinear term = 0.25 (1/(1-x/L)^2-1) = 0.25(1/.25 - 1) + * = 0.25 * 3 = 3/4 + * linear term = x/L = 0.5 + * nonlinear + linear = 0.75 + 0.5 = 1.25 + * wlc = 10e21*1.25 = 12.5e21 + */ + fail_unless(wlc(x, T, p, L)-12.5e21 < 1e16, + "wlc(%g, %g, %g, %g) = %g != %g", + x, T, p, L, wlc(x, T, p, L), 12.5e21); +} +END_TEST + +@ + + +\subsubsection{Freely-jointed chain} + +<>= +TCase *tc_fjc = tcase_create("FJC"); +@ + +<>= +tcase_add_test(tc_fjc, test_fjc_at_zero); +tcase_add_test(tc_fjc, test_fjc_at_half); +suite_add_tcase(s, tc_fjc); + +@ + +<>= +<> +START_TEST(test_fjc_at_zero) +{ + int N=10; + double T=1.0, l=1.0, p=0.1, x=0.0, lim=1e-30; + fail_unless(abs(fjc(x, T, l, N)) < lim, \ + "abs(fjc(x=%g,T=%g,l=%g,N=%d)) = %g >= %g", + x, T, l, N, abs(fjc(x, T, l, N)), lim); +} +END_TEST + +START_TEST(test_fjc_at_half) +{ + int N = 10; + double T=1.0/k_B, l=1.0, x=5.0; + /* prefactor = k_B T / l = k_B (1.0/k_B) / 1.0 = 1.0 J/nm = 1.0e21 pN + * nonlinear term = 0.25 (1/(1-x/L)^2-1) = 0.25(1/.25 - 1) + * = 0.25 * 3 = 3/4 + * linear term = x/L = 0.5 + * nonlinear + linear = 0.75 + 0.5 = 1.25 + * fjc = 10e21*1.25 = 12.5e21 + */ + fail_unless(fjc(x, T, l, N)-12.5e21 < 1e16, + "fjc(%g, %g, %g, %d) = %g != %g", + x, T, l, N, fjc(x, T, l, N), 12.5e21); +} +END_TEST + +@ + + +\subsubsection{Piston} + +<>= +TCase *tc_piston = tcase_create("Piston"); +@ + +<>= +tcase_add_test(tc_piston, test_piston_create_destroy); +suite_add_tcase(s, tc_piston); + +@ + +<>= +START_TEST(test_piston_create_destroy) +{ + char *L[] = {"1","2.2", "3"}; + char *params[] = {L[0]}; + void *p = NULL; + int i; + for( i=0; i < sizeof(L)/sizeof(char *); i++) { + params[0] = L[i]; + p = string_create_piston_tension_param_t(params); + destroy_piston_tension_param_t(p); + } +} +END_TEST + +@ TODO: In order to test the piston tension handler itself, we'd +have to construct a group. + \section{Unfolding rate models} \label{sec.k_models} @@ -5824,6 +6086,7 @@ Initialized with Titin I27 parameters\citep{carrion-vazquez99a}. Here we check to make sure the various functions work as expected, using \citetalias{sw:check}. <>= +<> <> <> <> @@ -5993,10 +6256,10 @@ END_TEST <>= @ -<>= +<>= @ -<>= +<>= @ <>= @@ -6314,6 +6577,7 @@ DOC_DIR = doc # Modules (X.c, X.h) defined in the noweb file NW_SAWSIM_MODS = +# Check binaries (check_*) defined in the noweb file CHECK_BINS = # Modules defined outside the noweb file FREE_SAWSIM_MODS = interp tavl @@ -6420,7 +6684,7 @@ $(CHECK_BINS:%=$(BIN_DIR)/%) : $$(subst $(BIN_DIR),$(BUILD_DIR),$$@).c \ gcc -g -o $@ $< $(@:$(BIN_DIR)/check_%=$(BUILD_DIR)/%.c) \ $(patsubst %,$(BUILD_DIR)/%.c,$($(subst $(BIN_DIR)/,,$@_MODS)))\ $(CHECK_LIBS:%=-l%) -# todo: clean up the required modules to +# TODO: clean up the required modules too $(CHECK_BINS:%=clean_%) : rm -f $(@:clean_%=$(BIN_DIR)/%) $(@:clean_%=$(BUILD_DIR)/%.c) -- 2.26.2