From b7184faf532b11afc567557903c113cbe7cbc63a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 25 Jul 2011 14:37:52 +0200 Subject: Finish symmetry tests and update table one last time --- doc/twin-calculator.odt | Bin 19816 -> 20883 bytes doc/twin-calculator.pdf | Bin 47007 -> 48187 bytes src/symmetry.c | 70 ++++++++++++++++++-- src/symmetry.h | 4 +- tests/symmetry_check.c | 168 +++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 222 insertions(+), 20 deletions(-) diff --git a/doc/twin-calculator.odt b/doc/twin-calculator.odt index 56282572..3feba7fe 100644 Binary files a/doc/twin-calculator.odt and b/doc/twin-calculator.odt differ diff --git a/doc/twin-calculator.pdf b/doc/twin-calculator.pdf index d1bfc9fd..6d3dd582 100644 Binary files a/doc/twin-calculator.pdf and b/doc/twin-calculator.pdf differ diff --git a/src/symmetry.c b/src/symmetry.c index e9c7d642..10c41ba7 100644 --- a/src/symmetry.c +++ b/src/symmetry.c @@ -456,7 +456,7 @@ static SymOpList *make_4mm() SymOpList *new = new_symoplist(); add_symop(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1), 4); /* 4 // l */ add_symop(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,1), 2); /* m -| l */ - new->name = strdup("4mmm"); + new->name = strdup("4mm"); return expand_ops(new); } @@ -843,7 +843,7 @@ SymOpList *get_pointgroup(const char *sym) if ( strcmp(sym, "23") == 0 ) return make_23(); if ( strcmp(sym, "m-3") == 0 ) return make_m3bar(); if ( strcmp(sym, "432") == 0 ) return make_432(); - if ( strcmp(sym, "-432") == 0 ) return make_4bar3m(); + if ( strcmp(sym, "-43m") == 0 ) return make_4bar3m(); if ( strcmp(sym, "m-3m") == 0 ) return make_m3barm(); ERROR("Unknown point group '%s'\n", sym); @@ -1057,6 +1057,13 @@ static int ops_equal(const struct sym_op *op, } +static int struct_ops_equal(const struct sym_op *op1, const struct sym_op *op2) +{ + return ops_equal(op1, op2->h, op2->k, op2->l); +} + + + /* Return true if a*b = ans */ static int check_mult(const struct sym_op *ans, const struct sym_op *a, const struct sym_op *b) @@ -1079,6 +1086,39 @@ static int check_mult(const struct sym_op *ans, } +/* Check that every operation in "target" is also in "source" */ +int is_subgroup(const SymOpList *source, const SymOpList *target) +{ + int n_src, n_tgt; + int i; + + n_src = num_ops(source); + n_tgt = num_ops(target); + + for ( i=0; iops[i], + &source->ops[j] ) ) + { + found = 1; + break; + } + + } + + if ( !found ) return 0; + + } + + return 1; +} + + /** * get_ambiguities: * @source: The "source" symmetry, a %SymOpList @@ -1100,10 +1140,23 @@ SymOpList *get_ambiguities(const SymOpList *source, const SymOpList *target) SymOpList *src_reordered; SymOpMask *used; char *name; + int index; n_src = num_ops(source); n_tgt = num_ops(target); + if ( !is_subgroup(source, target) ) { + ERROR("'%s' is not a subgroup of '%s'\n", + symmetry_name(target), symmetry_name(source)); + return NULL; + } + + if ( n_src % n_tgt != 0 ) { + ERROR("Subgroup index would be fractional.\n"); + return NULL; + } + index = n_src / n_tgt; + src_reordered = new_symoplist(); used = new_symopmask(source); @@ -1205,6 +1258,15 @@ SymOpList *get_ambiguities(const SymOpList *source, const SymOpList *target) twins = new_symoplist(); for ( i=0; imask[i] == 0 ) continue; + if ( determinant(&src_reordered->ops[i]) < 0 ) { + /* A mirror or inversion turned up in the list. + * That means that no pure rotational ambiguity can + * account for this subgroup relationship. */ + free_symoplist(twins); + free_symopmask(used); + free_symoplist(src_reordered); + return NULL; + } add_copied_op(twins, &src_reordered->ops[i]); } @@ -1309,13 +1371,13 @@ void describe_symmetry(const SymOpList *s) n = num_equivs(s, NULL); - STATUS("%10s :", symmetry_name(s)); + STATUS("%15s :", symmetry_name(s)); for ( i=0; iops[i]); STATUS(" %6s", name); free(name); - if ( (i!=0) && (i%8==0) ) STATUS("\n%10s ", ""); + if ( (i!=0) && (i%8==0) ) STATUS("\n%15s ", ""); } STATUS("\n"); } diff --git a/src/symmetry.h b/src/symmetry.h index 7ad93ece..c91864bb 100644 --- a/src/symmetry.h +++ b/src/symmetry.h @@ -47,7 +47,9 @@ extern void get_equiv(const SymOpList *ops, const SymOpMask *m, int idx, signed int h, signed int k, signed int l, signed int *he, signed int *ke, signed int *le); -extern SymOpList *get_ambiguities(const SymOpList *source, const SymOpList *target); +extern SymOpList *get_ambiguities(const SymOpList *source, + const SymOpList *target); +extern int is_subgroup(const SymOpList *source, const SymOpList *target); extern int is_centrosymmetric(const SymOpList *s); extern const char *symmetry_name(const SymOpList *ops); diff --git a/tests/symmetry_check.c b/tests/symmetry_check.c index a83b0d53..2e47bf83 100644 --- a/tests/symmetry_check.c +++ b/tests/symmetry_check.c @@ -17,11 +17,72 @@ #include #include +#include #include "../src/symmetry.h" #include "../src/utils.h" +static void find_all_ambiguities(const char *first, ...) +{ + va_list vp; + int i; + const char *arg; + SymOpList *test[32]; + int n = 0; + + test[n++] = get_pointgroup(first); + + va_start(vp, first); + + + do { + + arg = va_arg(vp, const char *); + if ( arg != NULL ) { + test[n++] = get_pointgroup(arg); + } + + } while ( arg != NULL ); + + for ( i=0; i