Пример #1
0
static Cell * refine_cell(SPGCONST Cell * cell,
                          const double symprec)
{
    int *wyckoffs, *equiv_atoms;
    double tolerance;
    Cell *primitive, *bravais, *conv_prim;
    Symmetry *conv_sym;
    Spacegroup spacegroup;

    debug_print("refine_cell:\n");

    primitive = prm_get_primitive(cell, symprec);

    if (primitive->size == 0) {
        cel_free_cell(primitive);
        bravais = cel_alloc_cell(0);
        goto end;
    }

    tolerance = prm_get_current_tolerance();
    spacegroup = spa_get_spacegroup_with_primitive(primitive, tolerance);

    wyckoffs = (int*)malloc(sizeof(int) * primitive->size);
    equiv_atoms = (int*)malloc(sizeof(int) * primitive->size);
    conv_prim = get_bravais_exact_positions_and_lattice(wyckoffs,
                equiv_atoms,
                &spacegroup,
                primitive,
                tolerance);
    free(equiv_atoms);
    equiv_atoms = NULL;
    free(wyckoffs);
    wyckoffs = NULL;

    conv_sym = get_db_symmetry(spacegroup.hall_number);
    bravais = expand_positions(conv_prim, conv_sym);

    debug_print("primitive cell in refine_cell:\n");
    debug_print_matrix_d3(primitive->lattice);
    debug_print("conventional lattice in refine_cell:\n");
    debug_print_matrix_d3(conv_prim->lattice);
    debug_print("bravais lattice in refine_cell:\n");
    debug_print_matrix_d3(bravais->lattice);

    cel_free_cell(conv_prim);
    sym_free_symmetry(conv_sym);
    cel_free_cell(primitive);

end:  /* Return bravais->size = 0, if the bravais could not be found. */
    return bravais;
}
Пример #2
0
Spacegroup spa_get_spacegroup(SPGCONST Cell * cell,
                              const double symprec)
{
    double tolerance;
    Cell *primitive;
    Spacegroup spacegroup;

    primitive = prm_get_primitive(cell, symprec);
    tolerance = prm_get_current_tolerance();

    if (primitive->size > 0) {
        spacegroup = get_spacegroup(primitive, tolerance);
    } else {
        spacegroup.number = 0;
        warning_print("spglib: Space group could not be found ");
        warning_print("(line %d, %s).\n", __LINE__, __FILE__);
    }
    cel_free_cell(primitive);

    return spacegroup;
}
Пример #3
0
/*---------*/
static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
				   SPGCONST double position[][3],
				   const int types[],
				   const int num_atom,
				   const double symprec)
{
  int attempt;
  int *mapping_table;
  double tolerance, tolerance_from_prim;
  Spacegroup spacegroup;
  SpglibDataset *dataset;
  Cell *cell, *primitive;

  dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset));
  dataset->spacegroup_number = 0;
  strcpy(dataset->international_symbol, "");
  strcpy(dataset->hall_symbol, "");
  strcpy(dataset->setting, "");
  dataset->origin_shift[0] = 0;
  dataset->origin_shift[1] = 0;
  dataset->origin_shift[2] = 0;
  dataset->n_atoms = 0;
  dataset->wyckoffs = NULL;
  dataset->equivalent_atoms = NULL;
  dataset->n_operations = 0;
  dataset->rotations = NULL;
  dataset->translations = NULL;

  mapping_table = (int*) malloc(sizeof(int) * num_atom);

  cell = cel_alloc_cell(num_atom);
  cel_set_cell(cell, lattice, position, types);

  tolerance = symprec;
  for (attempt = 0; attempt < 100; attempt++) {
    primitive = prm_get_primitive_and_mapping_table(mapping_table,
						    cell,
						    tolerance);
    if (primitive->size > 0) {
      tolerance_from_prim = prm_get_current_tolerance();
      spacegroup = spa_get_spacegroup_with_primitive(primitive,
						     tolerance_from_prim);
      if (spacegroup.number > 0) {
	set_dataset(dataset,
		    cell,
		    primitive,
		    &spacegroup,
		    mapping_table,
		    tolerance_from_prim);
	cel_free_cell(primitive);
	break;
      }
    }
    
    tolerance *= REDUCE_RATE;
    cel_free_cell(primitive);
    
    warning_print("  Attempt %d tolerance = %f failed.", attempt, tolerance);
    warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
  }

  free(mapping_table);
  mapping_table = NULL;
  cel_free_cell(cell);

  return dataset;
}
Пример #4
0
static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
				   SPGCONST double position[][3],
				   const int types[],
				   const int num_atom,
				   const double symprec)
{
  int i, j;
  int *mapping_table, *wyckoffs, *equiv_atoms, *equiv_atoms_prim;
  double tolerance;
  Spacegroup spacegroup;
  SpglibDataset *dataset;
  Cell *cell, *primitive;
  double inv_mat[3][3];
  Symmetry *symmetry;

  dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset));

  cell = cel_alloc_cell(num_atom);
  cel_set_cell(cell, lattice, position, types);

  mapping_table = (int*) malloc(sizeof(int) * cell->size);
  primitive = prm_get_primitive_with_mapping_table(mapping_table,
						   cell,
						   symprec);
  tolerance = prm_get_current_tolerance();
  spacegroup = spa_get_spacegroup_with_primitive(primitive, tolerance);

  if (spacegroup.number > 0) {
    /* Spacegroup type, transformation matrix, origin shift */
    dataset->spacegroup_number = spacegroup.number;
    dataset->hall_number = spacegroup.hall_number;
    strcpy(dataset->international_symbol, spacegroup.international_short);
    strcpy(dataset->hall_symbol, spacegroup.hall_symbol);
    mat_inverse_matrix_d3(inv_mat, lattice, tolerance);
    mat_multiply_matrix_d3(dataset->transformation_matrix,
			   inv_mat,
			   spacegroup.bravais_lattice);
    mat_copy_vector_d3(dataset->origin_shift, spacegroup.origin_shift);

    /* Wyckoff positions */
    wyckoffs = (int*) malloc(sizeof(int) * primitive->size);
    equiv_atoms_prim = (int*) malloc(sizeof(int) * primitive->size);
    for (i = 0; i < primitive->size; i++) {
      wyckoffs[i] = -1;
      equiv_atoms_prim[i] = -1;
    }
    ref_get_Wyckoff_positions(wyckoffs, 
			      equiv_atoms_prim,
			      primitive,
			      &spacegroup,
			      tolerance);
    dataset->n_atoms = cell->size;
    dataset->wyckoffs = (int*) malloc(sizeof(int) * cell->size); 
    for (i = 0; i < cell->size; i++) {
      dataset->wyckoffs[i] = wyckoffs[mapping_table[i]];
    }
    
    free(wyckoffs);
    wyckoffs = NULL;

    /* Equivalent atoms */
    dataset->equivalent_atoms = (int*) malloc(sizeof(int) * cell->size);
    equiv_atoms = (int*) malloc(sizeof(int) * primitive->size);
    for (i = 0; i < primitive->size; i++) {
      for (j = 0; j < cell->size; j++) {
	if (mapping_table[j] == equiv_atoms_prim[i]) {
	  equiv_atoms[i] = j;
	  break;
	}
      }
    }
    for (i = 0; i < cell->size; i++) {
      dataset->equivalent_atoms[i] = equiv_atoms[mapping_table[i]];
    }
    free(equiv_atoms);
    equiv_atoms = NULL;

    free(equiv_atoms_prim);
    equiv_atoms_prim = NULL;

    /* Symmetry operations */
    symmetry = ref_get_refined_symmetry_operations(cell,
						   primitive,
						   &spacegroup,
						   tolerance);
    dataset->rotations = (int (*)[3][3]) malloc(sizeof(int[3][3]) * symmetry->size);
    dataset->translations = (double (*)[3]) malloc(sizeof(double[3]) * symmetry->size);
    dataset->n_operations = symmetry->size;
    for (i = 0; i < symmetry->size; i++) {
      mat_copy_matrix_i3(dataset->rotations[i], symmetry->rot[i]);
      mat_copy_vector_d3(dataset->translations[i], symmetry->trans[i]);
    }
    sym_free_symmetry(symmetry);

  } else {
    dataset->spacegroup_number = 0;
  }

  free(mapping_table);
  mapping_table = NULL;

  cel_free_cell(primitive);

  if (dataset->spacegroup_number == 0) {
    strcpy(dataset->international_symbol, "");
    strcpy(dataset->hall_symbol, "");
    dataset->origin_shift[0] = 0;
    dataset->origin_shift[1] = 0;
    dataset->origin_shift[2] = 0;
    dataset->n_atoms = 0;
    dataset->wyckoffs = NULL;
    dataset->equivalent_atoms = NULL;
    dataset->n_operations = 0;
    dataset->rotations = NULL;
    dataset->translations = NULL;
  }
  
  cel_free_cell(cell);
  return dataset;
}