Ejemplo n.º 1
0
Spacegroup spa_get_spacegroup( SPGCONST Cell * cell,
			       const double symprec )
{
  Cell *primitive;
  int *mapping_table;
  Spacegroup spacegroup;
  VecDBL *pure_trans;

  pure_trans = sym_get_pure_translation( cell, symprec );
  mapping_table = (int*) malloc( sizeof(int) * cell->size );
  primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec );
  free( mapping_table );
  mapping_table = NULL;
  
  if ( primitive->size > 0 ) {
    spacegroup = get_spacegroup( primitive, symprec );
  } 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;
}
Ejemplo n.º 2
0
Spacegroup spa_get_spacegroup( SPGCONST Cell * cell,
			       const double symprec )
{
  Cell *primitive;
  int *mapping_table;
  Spacegroup spacegroup;
  VecDBL *pure_trans;
  double tolerance;

  pure_trans = sym_get_pure_translation( cell, symprec );
  mapping_table = (int*) malloc( sizeof(int) * cell->size );
  primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec );
  free( mapping_table );
  mapping_table = NULL;
  /* In some case, tolerance (symprec) to find primitive lattice is reduced. */
  /* The reduced tolerance should be used to find symmetry operations. */
  tolerance = prm_get_tolerance();
  
  if ( primitive->size > -1 ) {
    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;
}
Ejemplo n.º 3
0
/* Return NULL if failed */
static Primitive * get_primitive(SPGCONST Cell * cell, const double symprec)
{
  int i, attempt;
  double tolerance;
  Primitive *primitive;
  VecDBL * pure_trans;

  debug_print("get_primitive (tolerance = %f):\n", symprec);

  primitive = NULL;
  pure_trans = NULL;

  if ((primitive = prm_alloc_primitive(cell->size)) == NULL) {
    return NULL;
  }

  tolerance = symprec;
  for (attempt = 0; attempt < 100; attempt++) {
    if ((pure_trans = sym_get_pure_translation(cell, tolerance)) == NULL) {
      goto cont;
    }

    if (pure_trans->size == 1) {
      if ((primitive->cell = get_cell_with_smallest_lattice(cell, tolerance))
	  != NULL) {
	for (i = 0; i < cell->size; i++) {
	  primitive->mapping_table[i] = i;
	}
	goto found;
      }
    } else {
      if ((primitive->cell = get_primitive_cell(primitive->mapping_table,
						cell,
						pure_trans,
						tolerance)) != NULL) {
	goto found;
      }
    }

    mat_free_VecDBL(pure_trans);

  cont:
    tolerance *= REDUCE_RATE;
    warning_print("spglib: Reduce tolerance to %f ", tolerance);
    warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  }

  prm_free_primitive(primitive);
  return NULL;

 found:
  primitive->tolerance = tolerance;
  mat_free_VecDBL(pure_trans);
  return primitive;
}
Ejemplo n.º 4
0
static Cell * refine_cell( SPGCONST Cell * cell,
			   const double symprec )
{
  int *mapping_table, *wyckoffs, *equiv_atoms;
  Cell *primitive, *bravais, *conv_prim;
  Symmetry *conv_sym;
  VecDBL *pure_trans;
  Spacegroup spacegroup;

  pure_trans = sym_get_pure_translation( cell, symprec );

  mapping_table = (int*) malloc( sizeof(int) * cell->size );
  primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec );
  free( mapping_table );
  mapping_table = NULL;
  
  if ( primitive->size == -1 ) {
    cel_free_cell( primitive );
    bravais = cel_alloc_cell( -1 );
    goto ret;
  }

  spacegroup = spa_get_spacegroup_with_primitive( primitive, symprec );
  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,
						       symprec );
  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 );
  cel_free_cell( conv_prim );
  sym_free_symmetry( conv_sym );

  cel_free_cell( primitive );

 ret:
  /* Return bravais->size = -1, if the bravais could not be found. */
  return bravais;
}
Ejemplo n.º 5
0
/* primitive cell with smallest lattice is returned. */
static Primitive get_primitive_and_pure_translation(SPGCONST Cell * cell,
						    const double symprec)
{
  int attempt, is_found = 0;
  double tolerance;
  int *mapping_table;
  Primitive primitive;

  tolerance = symprec;
  for (attempt = 0; attempt < 100; attempt++) {
    primitive.pure_trans = sym_get_pure_translation(cell, tolerance);
    if (primitive.pure_trans->size == 0) {
      mat_free_VecDBL(primitive.pure_trans);
      continue;
    }

    if (primitive.pure_trans->size == 1) {
      primitive.cell = get_cell_with_smallest_lattice(cell, tolerance);
    } else {
      mapping_table = (int*) malloc(sizeof(int) * cell->size);
      primitive.cell = get_primitive(mapping_table,
				     cell,
				     primitive.pure_trans,
				     tolerance);
      free(mapping_table);
    } 

    if (primitive.cell->size > 0) {
      is_found = 1;
      break;
    }

    cel_free_cell(primitive.cell);
    mat_free_VecDBL(primitive.pure_trans);
    
    tolerance *= REDUCE_RATE;
    warning_print("spglib: Reduce tolerance to %f ", tolerance);
    warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  }

  if (! is_found) {
    primitive.cell = cel_alloc_cell(0);
    primitive.pure_trans = mat_alloc_VecDBL(0);
  }

  return primitive;
}
Ejemplo n.º 6
0
/* primitive cell with smallest lattice is returned. */
static Cell * get_primitive_and_mapping_table(int * mapping_table,
					      SPGCONST Cell * cell,
					      const double symprec)
{
  int i, attempt;
  double tolerance;
  Cell *primitive_cell;
  VecDBL *pure_trans;

  tolerance = symprec;
  for (attempt = 0; attempt < 100; attempt++) {
    pure_trans = sym_get_pure_translation(cell, tolerance);
    if (pure_trans->size == 1) {
      primitive_cell = get_cell_with_smallest_lattice(cell, symprec);
      for (i = 0; i < cell->size; i++) {
	mapping_table[i] = i;
      }
      goto ret;
    }
    if (pure_trans->size > 1) {
      primitive_cell = get_primitive(mapping_table, cell, pure_trans, tolerance);
      if (primitive_cell->size > 0) {
	goto ret;
      }
      cel_free_cell(primitive_cell);
    }

    tolerance *= REDUCE_RATE;
    warning_print("spglib: Tolerance is reduced to %f at attempt %d\n", tolerance, attempt);
    warning_print("(line %d, %s).\n", __LINE__, __FILE__);
    mat_free_VecDBL(pure_trans);
  }

  /* not found: I hope this will not happen. */
  warning_print("spglib: Primitive cell could not be found ");
  warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  return cel_alloc_cell(0);

 ret:
  mat_free_VecDBL(pure_trans);
  set_current_tolerance(tolerance);
  return primitive_cell;
}
Ejemplo n.º 7
0
int spg_find_primitive( double lattice[3][3],
			double position[][3],
			int types[],
			const int num_atom,
			const double symprec )
{
  int i, j, num_prim_atom=0;
  int *mapping_table;
  Cell *cell, *primitive;
  VecDBL *pure_trans;

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

  /* find primitive cell */
  if ( pure_trans->size > 1 ) {
    mapping_table = (int*) malloc( sizeof(int) * cell->size );
    primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec );
    free( mapping_table );
    mapping_table = NULL;
    num_prim_atom = primitive->size;
    if ( num_prim_atom < num_atom && num_prim_atom > 0  ) {
      mat_copy_matrix_d3( lattice, primitive->lattice );
      for ( i = 0; i < primitive->size; i++ ) {
	types[i] = primitive->types[i];
	for (j=0; j<3; j++) {
	  position[i][j] = primitive->position[i][j];
	}
      }
    }
    cel_free_cell( primitive );
  } else {
    num_prim_atom = 0;
  }

  mat_free_VecDBL( pure_trans );
  cel_free_cell( cell );
    
  return num_prim_atom;
}
Ejemplo n.º 8
0
/*    was not a primitive cell. */
static int get_operation( int rot[][3][3],
			  double trans[][3],
			  SPGCONST Cell *cell,
			  const double symprec )
{
  int num_sym;
  int multi;
  int *mapping_table;
  PointSymmetry lattice_sym;
  Cell *primitive;
  VecDBL *pure_trans;

  pure_trans = sym_get_pure_translation(cell, symprec);
  multi = pure_trans->size;

  /* Lattice symmetry for input cell*/
  lattice_sym = get_lattice_symmetry( cell, symprec );
  if ( lattice_sym.size == 0 ) {
    goto err;
  }

  /* Obtain primitive cell */
  if( multi > 1 ) {
    mapping_table = (int*) malloc( sizeof(int) * cell->size );
    primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec );
    free( mapping_table );
    mapping_table = NULL;

    if ( primitive->size < 1 ) { goto err; }

    lattice_sym = transform_pointsymmetry( &lattice_sym,
    					   primitive->lattice,
    					   cell->lattice );
    if ( lattice_sym.size == 0 ) { goto err; }
  } else {
    primitive = cell;
  }

  /* Symmetry operation search for primitive cell */
  num_sym = get_space_group_operation( rot, trans, &lattice_sym,
  				       primitive, symprec );

  /* Recover symmetry operation for the input structure (overwritten) */
  if( multi > 1 ) {
    num_sym = get_operation_supercell( rot,
  				       trans,
  				       num_sym,
  				       pure_trans,
  				       cell,
  				       primitive );
    cel_free_cell( primitive );
    if ( num_sym == 0 ) { goto err; }
  }

  mat_free_VecDBL( pure_trans );
  return num_sym;

 err:
  mat_free_VecDBL( pure_trans );
  return 0;
}
Ejemplo n.º 9
0
SpglibDataset * spg_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;
  Spacegroup spacegroup;
  SpglibDataset *dataset;
  Cell *cell, *primitive;
  double inv_mat[3][3];
  Symmetry *symmetry;
  VecDBL *pure_trans;

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

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

  pure_trans = sym_get_pure_translation( cell, symprec );
  mapping_table = (int*) malloc( sizeof(int) * cell->size );
  primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec );
  mat_free_VecDBL( pure_trans );

  spacegroup = spa_get_spacegroup_with_primitive( primitive, symprec );

  /* Spacegroup type, transformation matrix, origin shift */
  if ( spacegroup.number > 0 ) {
    dataset->spacegroup_number = spacegroup.number;
    strcpy( dataset->international_symbol, spacegroup.international_short);
    strcpy( dataset->hall_symbol, spacegroup.hall_symbol);
    mat_inverse_matrix_d3( inv_mat, lattice, symprec );
    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,
			     symprec );
  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;

  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;
  free( mapping_table );
  mapping_table = NULL;

  /* Symmetry operations */
  symmetry = ref_get_refined_symmetry_operations( cell,
						  primitive->lattice,
						  &spacegroup,
						  symprec );
  cel_free_cell( cell );
  cel_free_cell( primitive );

  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 );

  return dataset;
}