Exemple #1
0
msym_error_t findPermutation(msym_symmetry_operation_t *sop, int l, double (*v[l])[3], msym_thresholds_t *t, msym_permutation_t *perm){
    msym_error_t ret = MSYM_SUCCESS;
    double m[3][3];
    symmetryOperationMatrix(sop, m);
    
    perm->p = malloc(sizeof(int[l]));
    memset(perm->p, -1, sizeof(int[l])); //TODO: 2s complement
    perm->p_length = l;
    
    for(int i = 0; i < l;i++){
        int j;
        double r[3];
        mvmul(*v[i], m, r);
        for(j = 0;j < l;j++){
            if(vequal(r, *v[j],t->permutation)){
                perm->p[i] = j;
                break;
            }
        }
        if(j == l) {
            char buf[16];
            symmetryOperationName(sop, sizeof(buf), buf);
            msymSetErrorDetails("Unable to determine permutation for symmetry operation %s",buf);
            ret = MSYM_PERMUTATION_ERROR;
            goto err;
        }
    }
    if(MSYM_SUCCESS != (ret = setPermutationCycles(perm))) goto err;
    
    return ret;
    
err:
    free(perm->p);
    return ret;
}
Exemple #2
0
msym_error_t generateOrbitalTransforms(int sopsl, msym_symmetry_operation_t sops[sopsl], int l, double transform[sopsl][2*l+1][2*l+1]){
    msym_error_t ret = MSYM_SUCCESS;
    int kdim = ipow(3,l), norbs = 2*l+1;
    double (*mkron)[kdim][kdim] = malloc(sizeof(double[2][kdim][kdim]));
    double (*poly)[kdim] = malloc(sizeof(double[norbs][kdim]));
    
    for(int m = -l; m <= l;m++){
        if(MSYM_SUCCESS != (ret = orbitalPolynomial(l,m,poly[m+l]))) goto err;
        
        //Normalization
        vlnorm(kdim, poly[m+l]);
    }
    
    
    for(int i = 0;i < sopsl;i++){
        double M[3][3];
        mkron[0][0][0] = 1.0;
        symmetryOperationMatrix(&sops[i], M);
        for(int j = 0, d = 1;j < l;j++, d *= 3){
            kron(3,M,d,mkron[j%2],3*d,mkron[(j+1)%2]);
        }
        mmlmul(norbs, kdim, poly, kdim, mkron[l%2], mkron[(l+1)%2]);
        mmtlmul(norbs, kdim, mkron[(l+1)%2], norbs, poly, transform[i]);
        
        /* Scaling
        for(int j = 0; j < norbs;j++){
            double scale = vldot(kdim, poly[j], poly[j]);
            vlscale(1.0/scale, norbs, transform[i][j], transform[i][j]);
        }*/
    }
    
    
err:
    free(mkron);
    free(poly);
    return ret;
}
Exemple #3
0
msym_error_t findSymmetryOperationPermutations(int l, msym_symmetry_operation_t sops[l], msym_thresholds_t *t, msym_permutation_t **rperm){
    
    msym_error_t ret = MSYM_SUCCESS;
    //Don't block allocate this, it's a pain to keep track of the pointers
    msym_permutation_t *permutations = malloc(sizeof(msym_permutation_t[l]));
    
    for(int i = 0; i < l;i++){
        permutations[i].p = malloc(sizeof(int[l]));
        memset(permutations[i].p, -1, sizeof(int[l]));
        permutations[i].p_length = l;
    }
    
    double (*msops)[3][3] = malloc(sizeof(double[l][3][3]));
    
    for(int i = 0; i < l;i++){
        symmetryOperationMatrix(&sops[i], msops[i]);
    }
    
    for(int i = 0; i < l;i++){
        if((sops[i].type == PROPER_ROTATION && sops[i].order == 0) || sops[i].type == IDENTITY){
            for(int j = 0;j < l;j++) permutations[i].p[j] = j;
        } else {
            for(int j = 0; j < l;j++){
                int k;
                double rsop[3][3];
                mmmul(msops[i], msops[j], rsop);
                for(k = 0;k < l;k++){
                    if(mequal(rsop,msops[k],t->permutation)){
                        permutations[i].p[j] = k;
                        break;
                    }
                }
                if(k == l){
                    char buf1[16];
                    char buf2[16];
                    symmetryOperationName(&sops[i], sizeof(buf1), buf1);
                    symmetryOperationName(&sops[j], sizeof(buf2), buf2);
                    msymSetErrorDetails("Unable to determine permutation for symmetry operation %s and %s",buf1, buf2);
                    ret = MSYM_PERMUTATION_ERROR;
                    goto err;
                }
            }
        }
    }
    
    for(int i = 0; i < l;i++){
        if(MSYM_SUCCESS != (ret = setPermutationCycles(&permutations[i]))) goto err;
    }
    
    free(msops);
    *rperm = permutations;
    
    return ret;
    
err:
    free(msops);
    for(int i = 0; i < l;i++){
        free(permutations[i].p);
    }
    free(permutations);
    *rperm = NULL;
    return ret;
    
}