示例#1
0
文件: primitive.c 项目: alexurba/cftb
static int get_primitive_lattice_vectors_iterative( double prim_lattice[3][3],
						    SPGCONST Cell * cell,
						    const VecDBL * pure_trans,
						    const double symprec )
{
  int i, multi, attempt;
  double tolerance;
  VecDBL * vectors, * pure_trans_reduced, *tmp_vec;

  tolerance = symprec;
  pure_trans_reduced = mat_alloc_VecDBL( pure_trans->size );
  for ( i = 0; i < pure_trans->size; i++ ) {
    mat_copy_vector_d3( pure_trans_reduced->vec[i], pure_trans->vec[i] );
  }
  
  for ( attempt = 0; attempt < 100; attempt++ ) {
    multi = pure_trans_reduced->size;
    vectors = get_translation_candidates( pure_trans_reduced );

    /* Lattice of primitive cell is found among pure translation vectors */
    if ( get_primitive_lattice_vectors( prim_lattice,
					vectors,
					cell,
					tolerance ) ) {

      mat_free_VecDBL( vectors );
      mat_free_VecDBL( pure_trans_reduced );

      goto found;
    } else {

      tmp_vec = mat_alloc_VecDBL( multi );
      for ( i = 0; i < multi; i++ ) {
	mat_copy_vector_d3( tmp_vec->vec[i], pure_trans_reduced->vec[i] );
      }
      mat_free_VecDBL( pure_trans_reduced );
      pure_trans_reduced = sym_reduce_pure_translation( cell,
							tmp_vec,
							tolerance );
      debug_print("Tolerance is reduced to %f (%d), size = %d\n",
		  tolerance, attempt, pure_trans_reduced->size);

      mat_free_VecDBL( tmp_vec );
      mat_free_VecDBL( vectors );

      tolerance *= REDUCE_RATE;
    }
  }

  /* Not found */
  return 0;

 found:
#ifdef SPGWARNING
  if ( attempt > 0 ) {
    printf("spglib: Tolerance to find primitive lattice vectors was changed to %f ", tolerance);
  }
#endif
  return multi;
}
示例#2
0
VecDBL * sym_reduce_pure_translation(SPGCONST Cell * cell,
				     const VecDBL * pure_trans,
				     const double symprec)
{
  int i, multi;
  Symmetry *symmetry, *symmetry_reduced;
  VecDBL * pure_trans_reduced;
  
  multi = pure_trans->size;
  symmetry = sym_alloc_symmetry(multi);
  for (i = 0; i < multi; i++) {
    mat_copy_matrix_i3(symmetry->rot[i], identity);
    mat_copy_vector_d3(symmetry->trans[i], pure_trans->vec[i]);
  }

  symmetry_reduced = reduce_operation(cell, symmetry, symprec);
  sym_free_symmetry(symmetry);

  multi = symmetry_reduced->size;
  pure_trans_reduced = mat_alloc_VecDBL(multi);
  
  for (i = 0; i < multi; i++) {
    mat_copy_vector_d3(pure_trans_reduced->vec[i], symmetry_reduced->trans[i]);
  }
  sym_free_symmetry(symmetry_reduced);
  
  return pure_trans_reduced;
}
示例#3
0
static VecDBL * reduce_lattice_points(SPGCONST double lattice[3][3],
                                      const VecDBL *lattice_trans,
                                      const double symprec)
{
    int i, j, is_found, num_pure_trans;
    VecDBL *pure_trans, *t;

    num_pure_trans = 0;
    t = mat_alloc_VecDBL(lattice_trans->size);
    for (i = 0; i < lattice_trans->size; i++) {
        is_found = 0;
        for (j = 0; j < num_pure_trans; j++) {
            if (cel_is_overlap(lattice_trans->vec[i], t->vec[j], lattice, symprec)) {
                is_found = 1;
                break;
            }
        }
        if (! is_found) {
            mat_copy_vector_d3(t->vec[num_pure_trans], lattice_trans->vec[i]);
            num_pure_trans++;
        }
    }

    pure_trans = mat_alloc_VecDBL(num_pure_trans);
    for (i = 0; i < num_pure_trans; i++) {
        mat_copy_vector_d3(pure_trans->vec[i], t->vec[i]);
    }
    mat_free_VecDBL(t);

    return pure_trans;
}
示例#4
0
文件: spglib.c 项目: shanghui/phonopy
static void set_dataset(SpglibDataset * dataset,
			SPGCONST Cell * cell,
			SPGCONST Cell * primitive,
			SPGCONST Spacegroup * spacegroup,
			const int * mapping_table,
			const double tolerance)
{
  int i;
  double inv_mat[3][3];
  Cell *bravais;
  Symmetry *symmetry;
  
  /* Spacegroup type, transformation matrix, origin shift */
  dataset->n_atoms = cell->size;
  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);
  strcpy(dataset->setting, spacegroup->setting);
  mat_inverse_matrix_d3(inv_mat, cell->lattice, tolerance);
  mat_multiply_matrix_d3(dataset->transformation_matrix,
			 inv_mat,
			 spacegroup->bravais_lattice);
  mat_copy_vector_d3(dataset->origin_shift, spacegroup->origin_shift);

  /* 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]);
  }

  /* Wyckoff positions */
  dataset->wyckoffs = (int*) malloc(sizeof(int) * cell->size); 
  dataset->equivalent_atoms = (int*) malloc(sizeof(int) * cell->size);
  bravais = ref_get_Wyckoff_positions(dataset->wyckoffs, 
				      dataset->equivalent_atoms,
				      primitive,
				      cell,
				      spacegroup,
				      symmetry,
				      mapping_table,
				      tolerance);
  cel_free_cell(bravais);
  sym_free_symmetry(symmetry);
}
示例#5
0
static void get_Delaunay_shortest_vectors( double basis[4][3],
					   const double symprec )
{
  int i, j;
  double tmpmat[3][3], b[7][3], tmpvec[3];
  
  /* Search in the set {b1, b2, b3, b4, b1+b2, b2+b3, b3+b1} */
  for ( i = 0; i < 4; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      b[i][j] = basis[i][j];
    }
  }
  
  for ( i = 0; i < 3; i++ ) {
    b[4][i] = basis[0][i] + basis[1][i];
  }
  for ( i = 0; i < 3; i++ ) {
    b[5][i] = basis[1][i] + basis[2][i];
  }
  for ( i = 0; i < 3; i++ ) {
    b[6][i] = basis[2][i] + basis[0][i];
  }
  
  /* Bubble sort */
  for ( i = 0; i < 6; i++ ) {
    for ( j = 0; j < 6; j++ ) {
      if ( mat_norm_squared_d3( b[j] ) > mat_norm_squared_d3( b[j+1] ) ) {
	mat_copy_vector_d3( tmpvec, b[j] );
	mat_copy_vector_d3( b[j], b[j+1] );
	mat_copy_vector_d3( b[j+1], tmpvec );
      }
    }
  }

  for ( i = 2; i < 7; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      tmpmat[j][0] = b[0][j];
      tmpmat[j][1] = b[1][j];
      tmpmat[j][2] = b[i][j];
    }
    if ( mat_Dabs( mat_get_determinant_d3( tmpmat ) ) > symprec ) {
      for ( j = 0; j < 3; j++ ) {
	basis[0][j] = b[0][j];
	basis[1][j] = b[1][j];
	basis[2][j] = b[i][j];
      }
      break;
    }
  }
}
示例#6
0
/* Return NULL if failed */
static Symmetry *
copy_symmetry_upon_lattice_points(const VecDBL *pure_trans,
				  SPGCONST Symmetry *t_sym)
{
  int i, j, k, size_sym_orig;
  Symmetry *symmetry;

  symmetry = NULL;

  size_sym_orig = t_sym->size;

  if ((symmetry = sym_alloc_symmetry(pure_trans->size * size_sym_orig))
      == NULL) {
    return NULL;
  }

  for (i = 0; i < pure_trans->size; i++) {
    for (j = 0; j < size_sym_orig; j++) {
      mat_copy_matrix_i3(symmetry->rot[size_sym_orig * i + j], t_sym->rot[j]);
      mat_copy_vector_d3(symmetry->trans[size_sym_orig * i + j],
			 t_sym->trans[j]);
      for (k = 0; k < 3; k++) {
	symmetry->trans[size_sym_orig * i + j][k] += pure_trans->vec[i][k];
	symmetry->trans[size_sym_orig * i + j][k] =
	  mat_Dmod1(symmetry->trans[size_sym_orig * i + j][k]);
      }
    }
  }

  return symmetry;
}
示例#7
0
文件: spglib.c 项目: shanghui/phonopy
static int find_primitive(double lattice[3][3],
			  double position[][3],
			  int types[],
			  const int num_atom,
			  const double symprec)
{
  int i, num_prim_atom=0;
  Cell *cell, *primitive;

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

  /* find primitive cell */
  primitive = prm_get_primitive(cell, symprec);
  if (primitive->size == cell->size) { /* Already primitive */
    num_prim_atom = 0;
  } else { /* Primitive cell was found. */
    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];
	mat_copy_vector_d3(position[i], primitive->position[i]);
      }
    }
  }

  cel_free_cell(primitive);
  cel_free_cell(cell);
    
  return num_prim_atom;
}
示例#8
0
文件: spglib.c 项目: jasonlarkin/ntpl
int spg_refine_cell( double lattice[3][3],
		     double position[][3],
		     int types[],
		     const int num_atom,
		     const double symprec )
{
  int i, num_atom_bravais;
  Cell *cell, *bravais;

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

  bravais = ref_refine_cell( cell, symprec );
  cel_free_cell( cell );

  if ( bravais->size > 0 ) {
    mat_copy_matrix_d3( lattice, bravais->lattice );
    num_atom_bravais = bravais->size;
    for ( i = 0; i < bravais->size; i++ ) {
      types[i] = bravais->types[i];
      mat_copy_vector_d3( position[i], bravais->position[i] );
    }
  } else {
    num_atom_bravais = 0;
  }

  cel_free_cell( bravais );
  
  return num_atom_bravais;
}
示例#9
0
文件: primitive.c 项目: alexurba/cftb
static VecDBL * get_translation_candidates( const VecDBL * pure_trans )
{
  int i, j, multi;
  VecDBL * vectors;

  multi = pure_trans->size;
  vectors = mat_alloc_VecDBL( multi+2 );

  /* store pure translations in original cell */ 
  /* as trial primitive lattice vectors */
  for (i = 0; i < multi - 1; i++) {
    mat_copy_vector_d3( vectors->vec[i], pure_trans->vec[i + 1]);
  }

  /* store lattice translations of original cell */
  /* as trial primitive lattice vectors */
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 3; j++) {
      if (i == j) {
	vectors->vec[i+multi-1][j] = 1;
      } else {
	vectors->vec[i+multi-1][j] = 0;
      }
    }
  }

#ifdef DEBUG
  for (i = 0; i < multi + 2; i++) {
    debug_print("%d: %f %f %f\n", i + 1, vectors->vec[i][0],
		vectors->vec[i][1], vectors->vec[i][2]);
  }
#endif

  return vectors;
}
示例#10
0
/* Return spacegroup.number = 0 if failed */
static Spacegroup get_spacegroup(const int hall_number,
				 const double origin_shift[3],
				 SPGCONST double conv_lattice[3][3])
{
  Spacegroup spacegroup;
  SpacegroupType spacegroup_type;

  spacegroup.number = 0;
  spacegroup_type = spgdb_get_spacegroup_type(hall_number);

  if (spacegroup_type.number > 0) {
    mat_copy_matrix_d3(spacegroup.bravais_lattice, conv_lattice);
    mat_copy_vector_d3(spacegroup.origin_shift, origin_shift);
    spacegroup.number = spacegroup_type.number;
    spacegroup.hall_number = hall_number;
    spacegroup.pointgroup_number = spacegroup_type.pointgroup_number;
    strcpy(spacegroup.schoenflies,
	   spacegroup_type.schoenflies);
    strcpy(spacegroup.hall_symbol,
	   spacegroup_type.hall_symbol);
    strcpy(spacegroup.international,
	   spacegroup_type.international);
    strcpy(spacegroup.international_long,
	   spacegroup_type.international_full);
    strcpy(spacegroup.international_short,
	   spacegroup_type.international_short);
    strcpy(spacegroup.setting,
	   spacegroup_type.setting);
  }

  return spacegroup;
}
示例#11
0
static int refine_cell(double lattice[3][3],
		       double position[][3],
		       int types[],
		       const int num_atom,
		       const double symprec)
{
  int i, n_brv_atoms;
  SpglibDataset *dataset;

  n_brv_atoms = 0;
  dataset = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    return 0;
  }

  n_brv_atoms = dataset->n_brv_atoms;
  mat_copy_matrix_d3(lattice, dataset->brv_lattice);
  for (i = 0; i < dataset->n_brv_atoms; i++) {
    types[i] = dataset->brv_types[i];
    mat_copy_vector_d3(position[i], dataset->brv_positions[i]);
  }

  spg_free_dataset(dataset);
  
  return n_brv_atoms;
}
示例#12
0
static Cell * expand_positions(SPGCONST Cell * conv_prim,
                               SPGCONST Symmetry * conv_sym)
{
    int i, j, k, num_pure_trans;
    int num_atom;
    Cell * bravais;

    num_pure_trans = get_number_of_pure_translation(conv_sym);
    bravais = cel_alloc_cell(conv_prim->size * num_pure_trans);

    num_atom = 0;
    for (i = 0; i < conv_sym->size; i++) {
        /* Referred atoms in Bravais lattice */
        if (mat_check_identity_matrix_i3(identity, conv_sym->rot[i])) {
            for (j = 0; j < conv_prim->size; j++) {
                bravais->types[num_atom] = conv_prim->types[j];
                mat_copy_vector_d3(bravais->position[ num_atom ],
                                   conv_prim->position[j]);
                for (k = 0; k < 3; k++) {
                    bravais->position[num_atom][k] += conv_sym->trans[i][k];
                    bravais->position[num_atom][k] =
                        mat_Dmod1(bravais->position[num_atom][k]);
                }
                num_atom++;
            }
        }
    }

    mat_copy_matrix_d3(bravais->lattice, conv_prim->lattice);

    return bravais;
}
示例#13
0
static VecDBL * get_translation_candidates(const VecDBL * pure_trans)
{
  int i, j, multi;
  VecDBL * vectors;

  vectors = NULL;
  multi = pure_trans->size;

  if ((vectors = mat_alloc_VecDBL(multi + 2)) == NULL) {
    return NULL;
  }

  /* store pure translations in original cell */ 
  /* as trial primitive lattice vectors */
  for (i = 0; i < multi - 1; i++) {
    mat_copy_vector_d3(vectors->vec[i], pure_trans->vec[i + 1]);
  }

  /* store lattice translations of original cell */
  /* as trial primitive lattice vectors */
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 3; j++) {
      if (i == j) {
	vectors->vec[i+multi-1][j] = 1;
      } else {
	vectors->vec[i+multi-1][j] = 0;
      }
    }
  }

  return vectors;
}
示例#14
0
static Spacegroup get_spacegroup(SPGCONST Cell * primitive,
                                 const double symprec)
{
    int hall_number;
    double conv_lattice[3][3];
    double origin_shift[3];
    Symmetry *symmetry;
    Spacegroup spacegroup;
    SpacegroupType spacegroup_type;

    symmetry = sym_get_operation(primitive, symprec);
    if (symmetry->size == 0) {
        spacegroup.number = 0;
        warning_print("spglib: Space group could not be found ");
        warning_print("(line %d, %s).\n", __LINE__, __FILE__);
        goto ret;
    }

    hall_number = get_hall_number(origin_shift,
                                  conv_lattice,
                                  primitive,
                                  symmetry,
                                  symprec);

    if (hall_number == 0) {
        spacegroup.number = 0;
        warning_print("spglib: Space group could not be found ");
        warning_print("(line %d, %s).\n", __LINE__, __FILE__);
        goto ret;
    }

    spacegroup_type = spgdb_get_spacegroup_type(hall_number);

    if (spacegroup_type.number > 0) {
        mat_copy_matrix_d3(spacegroup.bravais_lattice, conv_lattice);
        mat_copy_vector_d3(spacegroup.origin_shift, origin_shift);
        spacegroup.number = spacegroup_type.number;
        spacegroup.hall_number = hall_number;
        spacegroup.holohedry = spacegroup_type.holohedry;
        strcpy(spacegroup.schoenflies,
               spacegroup_type.schoenflies);
        strcpy(spacegroup.hall_symbol,
               spacegroup_type.hall_symbol);
        strcpy(spacegroup.international,
               spacegroup_type.international);
        strcpy(spacegroup.international_long,
               spacegroup_type.international_full);
        strcpy(spacegroup.international_short,
               spacegroup_type.international_short);
    } else {
        spacegroup.number = 0;
        warning_print("spglib: Space group could not be found ");
        warning_print("(line %d, %s).\n", __LINE__, __FILE__);
    }

ret:
    /* spacegroup.number = 0 when space group was not found. */
    sym_free_symmetry(symmetry);
    return spacegroup;
}
示例#15
0
static Symmetry * reduce_operation(SPGCONST Cell * cell,
				   SPGCONST Symmetry * symmetry,
				   const double symprec)
{
  int i, j, num_sym;
  Symmetry * sym_reduced;
  PointSymmetry point_symmetry;
  MatINT *rot;
  VecDBL *trans;

  debug_print("reduce_operation:\n");

  point_symmetry = get_lattice_symmetry(cell, symprec);
  rot = mat_alloc_MatINT(symmetry->size);
  trans = mat_alloc_VecDBL(symmetry->size);

  num_sym = 0;
  for (i = 0; i < point_symmetry.size; i++) {
    for (j = 0; j < symmetry->size; j++) {
      if (mat_check_identity_matrix_i3(point_symmetry.rot[i],
				       symmetry->rot[j])) {
	if (is_overlap_all_atoms(symmetry->trans[j],
				 symmetry->rot[j],
				 cell,
				 symprec,
				 0)) {
	  mat_copy_matrix_i3(rot->mat[num_sym], symmetry->rot[j]);
	  mat_copy_vector_d3(trans->vec[num_sym], symmetry->trans[j]);
	  num_sym++;
	}
      }
    }
  }

  sym_reduced = sym_alloc_symmetry(num_sym);
  for (i = 0; i < num_sym; i++) {
    mat_copy_matrix_i3(sym_reduced->rot[i], rot->mat[i]);
    mat_copy_vector_d3(sym_reduced->trans[i], trans->vec[i]);
  }

  mat_free_MatINT(rot);
  mat_free_VecDBL(trans);

  debug_print("  num_sym %d -> %d\n", symmetry->size, num_sym);

  return sym_reduced;
}
示例#16
0
/* This function is heaviest in this code. */
static VecDBL * get_translation( SPGCONST int rot[3][3],
				 SPGCONST Cell *cell,
				 const double symprec,
				 const int is_identity )
{
  int i, j, min_atom_index, num_trans = 0;
  int *is_found;
  double origin[3];
  VecDBL *tmp_trans, *trans;

  tmp_trans = mat_alloc_VecDBL( cell->size );
  is_found = (int*) malloc( sizeof(int)*cell->size);
  for ( i = 0; i < cell->size; i++ ) {
    is_found[i] = 0;
  }

  /* Look for the atom index with least number of atoms within same type */
  min_atom_index = get_index_with_least_atoms( cell );

  /* Set min_atom_index as the origin to measure the distance between atoms. */
  mat_multiply_matrix_vector_id3(origin, rot, cell->position[min_atom_index]);

  
#pragma omp parallel for private( j )
  for (i = 0; i < cell->size; i++) {	/* test translation */
    if (cell->types[i] != cell->types[min_atom_index]) {
      continue;
    }

    for (j = 0; j < 3; j++) {
      tmp_trans->vec[i][j] = cell->position[i][j] - origin[j];
    }
    if ( is_overlap_all_atoms( tmp_trans->vec[i],
			       rot,
			       cell,
			       symprec,
			       is_identity ) ) {
      is_found[i] = 1;
    }
  }

  for ( i = 0; i < cell->size; i++ ) {
    num_trans += is_found[i];
  }
  trans = mat_alloc_VecDBL( num_trans );
  num_trans = 0;
  for ( i = 0; i < cell->size; i++ ) {
    if ( is_found[i] ) {
      mat_copy_vector_d3( trans->vec[num_trans], tmp_trans->vec[i] );
      num_trans++;
    }
  }

  mat_free_VecDBL( tmp_trans );
  free( is_found );
  is_found = NULL;
  
  return trans;
}
示例#17
0
/* Return 0 if failed */
static int get_exact_positions(VecDBL *positions,
                               int * equiv_atoms,
                               const Cell * conv_prim,
                               const Symmetry * conv_sym,
                               const double symprec)
{
  int i, num_indep_atoms, sum_num_atoms_in_orbits, num_atoms_in_orbits;
  int *indep_atoms;

  debug_print("get_exact_positions\n");

  indep_atoms = NULL;

  if ((indep_atoms = (int*) malloc(sizeof(int) * conv_prim->size)) == NULL) {
    warning_print("spglib: Memory could not be allocated ");
    return 0;
  }

  num_indep_atoms = 0;
  sum_num_atoms_in_orbits = 0;
  for (i = 0; i < conv_prim->size; i++) {
    /* Check if atom_i overlap to an atom already set at the exact position. */
    if (! set_equivalent_atom(positions,
                              equiv_atoms,
                              i,
                              num_indep_atoms,
                              indep_atoms,
                              conv_prim,
                              conv_sym,
                              symprec)) {
      /* No equivalent atom was found. */
      indep_atoms[num_indep_atoms] = i;
      num_indep_atoms++;
      mat_copy_vector_d3(positions->vec[i], conv_prim->position[i]);
      num_atoms_in_orbits = set_exact_location(positions->vec[i],
                                               conv_sym,
                                               conv_prim->lattice,
                                               symprec);
      if (num_atoms_in_orbits) {
        sum_num_atoms_in_orbits += num_atoms_in_orbits;
        equiv_atoms[i] = i;
      } else {
        sum_num_atoms_in_orbits = 0;
        break;
      }
    }
  }

  free(indep_atoms);
  indep_atoms = NULL;

  return sum_num_atoms_in_orbits;
}
示例#18
0
文件: spglib.c 项目: nfh/phonopy
static void set_cell(double lattice[3][3],
		     double position[][3],
		     int types[],
		     Cell * cell)
{
  int i;

  mat_copy_matrix_d3(lattice, cell->lattice);
  for (i = 0; i < cell->size; i++) {
    types[i] = cell->types[i];
    mat_copy_vector_d3(position[i], cell->position[i]);
  }
}
示例#19
0
文件: spglib.c 项目: shanghui/phonopy
int spg_get_symmetry_from_database(int rotations[192][3][3],
				   double translations[192][3],
				   const int hall_number)
{
  int i;
  Symmetry *symmetry;

  symmetry = spgdb_get_spacegroup_operations(hall_number);
  for (i = 0; i < symmetry->size; i++) {
    mat_copy_matrix_i3(rotations[i], symmetry->rot[i]);
    mat_copy_vector_d3(translations[i], symmetry->trans[i]);
  }
  return symmetry->size;
}
示例#20
0
static Symmetry * recover_operations_original(SPGCONST Symmetry *symmetry,
					      const VecDBL * pure_trans,
					      SPGCONST Cell *cell,
					      SPGCONST Cell *primitive)
{
  int i, j, k, multi;
  double inv_prim_lat[3][3], drot[3][3], trans_mat[3][3], trans_mat_inv[3][3];
  Symmetry *symmetry_orig, *sym_tmp;

  debug_print("recover_operations_original:\n");

  multi = pure_trans->size;
  sym_tmp = sym_alloc_symmetry(symmetry->size);
  symmetry_orig = sym_alloc_symmetry(symmetry->size * multi);

  mat_inverse_matrix_d3(inv_prim_lat, primitive->lattice, 0);
  mat_multiply_matrix_d3(trans_mat, inv_prim_lat, cell->lattice);
  mat_inverse_matrix_d3(trans_mat_inv, trans_mat, 0);

  for(i = 0; i < symmetry->size; i++) {
    mat_copy_matrix_i3(sym_tmp->rot[i], symmetry->rot[i]);
    mat_copy_vector_d3(sym_tmp->trans[i], symmetry->trans[i]);
  }

  for(i = 0; i < symmetry->size; i++) {
    mat_cast_matrix_3i_to_3d(drot, sym_tmp->rot[i]);
    mat_get_similar_matrix_d3(drot, drot, trans_mat, 0);
    mat_cast_matrix_3d_to_3i(sym_tmp->rot[i], drot);

    mat_multiply_matrix_vector_d3(sym_tmp->trans[i],
				  trans_mat_inv,
				  sym_tmp->trans[i]);
  }


  for(i = 0; i < symmetry->size; i++) {
    for(j = 0; j < multi; j++) {
      mat_copy_matrix_i3(symmetry_orig->rot[i * multi + j], sym_tmp->rot[i]);
      for (k = 0; k < 3; k++) {
	symmetry_orig->trans[i * multi + j][k] =
	  sym_tmp->trans[i][k] + pure_trans->vec[j][k];
      }
    }
  }

  sym_free_symmetry(sym_tmp);

  return symmetry_orig;
}
示例#21
0
文件: spglib.c 项目: nfh/phonopy
/* Return 0 if failed */
static int get_symmetry_numerical(int rotation[][3][3],
				  double translation[][3],
				  const int max_size,
				  SPGCONST double lattice[3][3],
				  SPGCONST double position[][3],
				  const int types[],
				  const int num_atom,
				  const double symprec)
{
  int i, size;
  Cell *cell;
  Symmetry *symmetry;

  size = 0;
  cell = NULL;
  symmetry = NULL;

  if ((cell = cel_alloc_cell(num_atom)) == NULL) {
    return 0;
  }

  cel_set_cell(cell, lattice, position, types);

  if ((symmetry = sym_get_operation(cell, symprec)) == NULL) {
    cel_free_cell(cell);
    return 0;
  }

  if (symmetry->size > max_size) {
    fprintf(stderr, "spglib: Indicated max size(=%d) is less than number ",
	    max_size);
    fprintf(stderr, "spglib: of symmetry operations(=%d).\n", symmetry->size);
    goto ret;
  }

  for (i = 0; i < symmetry->size; i++) {
    mat_copy_matrix_i3(rotation[i], symmetry->rot[i]);
    mat_copy_vector_d3(translation[i], symmetry->trans[i]);
  }
  size = symmetry->size;

 ret:
  sym_free_symmetry(symmetry);
  cel_free_cell(cell);

  return size;
}
示例#22
0
/* Only the atoms corresponding to those in primitive are returned. */
static Cell * get_bravais_exact_positions_and_lattice(int * wyckoffs,
        int * equiv_atoms,
        SPGCONST Spacegroup *spacegroup,
        SPGCONST Cell * primitive,
        const double symprec)
{
    int i;
    Symmetry *conv_sym;
    Cell *bravais;
    VecDBL *exact_positions;

    /* Positions of primitive atoms are represented wrt Bravais lattice */
    bravais = get_conventional_primitive(spacegroup, primitive);
    /* Symmetries in database (wrt Bravais lattice) */
    conv_sym = get_db_symmetry(spacegroup->hall_number);
    /* Lattice vectors are set. */
    get_conventional_lattice(bravais->lattice,
                             spacegroup->holohedry,
                             spacegroup->bravais_lattice);

    /* Symmetrize atomic positions of conventional unit cell */
    exact_positions = ssm_get_exact_positions(wyckoffs,
                      equiv_atoms,
                      bravais,
                      conv_sym,
                      spacegroup->hall_number,
                      symprec);
    sym_free_symmetry(conv_sym);

    if (exact_positions->size > 0) {
        for (i = 0; i < bravais->size; i++) {
            mat_copy_vector_d3(bravais->position[i], exact_positions->vec[i]);
        }
    } else {
        cel_free_cell(bravais);
        bravais = cel_alloc_cell(0);
    }

    mat_free_VecDBL(exact_positions);

    return bravais;
}
示例#23
0
/* Return 0 if failed */
static int get_symmetry_from_dataset(int rotation[][3][3],
				     double translation[][3],
				     const int max_size,
				     SPGCONST double lattice[3][3],
				     SPGCONST double position[][3],
				     const int types[],
				     const int num_atom,
				     const double symprec)
{
  int i, num_sym;
  SpglibDataset *dataset;

  num_sym = 0;
  dataset = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    return 0;
  }
  
  if (dataset->n_operations > max_size) {
    fprintf(stderr,
	    "spglib: Indicated max size(=%d) is less than number ", max_size);
    fprintf(stderr,
	    "spglib: of symmetry operations(=%d).\n", dataset->n_operations);
    goto ret;
  }

  num_sym = dataset->n_operations;
  for (i = 0; i < num_sym; i++) {
    mat_copy_matrix_i3(rotation[i], dataset->rotations[i]);
    mat_copy_vector_d3(translation[i], dataset->translations[i]);
  }
  
 ret:
  spg_free_dataset(dataset);
  return num_sym;
}
示例#24
0
static Symmetry * get_db_symmetry(const int hall_number)
{
    int i;
    int operation_index[2];
    int rot[3][3];
    double trans[3];
    Symmetry *symmetry;

    spgdb_get_operation_index(operation_index, hall_number);
    symmetry = sym_alloc_symmetry(operation_index[0]);

    for (i = 0; i < operation_index[0]; i++) {
        /* rotation matrix matching and set difference of translations */
        spgdb_get_operation(rot, trans, operation_index[1] + i);
        mat_copy_matrix_i3(symmetry->rot[i], rot);
        mat_copy_vector_d3(symmetry->trans[i], trans);
    }

    return symmetry;
}
示例#25
0
/* Return 0 if failed */
static int find_primitive(double lattice[3][3],
			  double position[][3],
			  int types[],
			  const int num_atom,
			  const double symprec)
{
  int i, num_prim_atom;
  Cell *cell;
  Primitive *primitive;

  cell = NULL;
  primitive = NULL;
  num_prim_atom = 0;

  if ((cell = cel_alloc_cell(num_atom)) == NULL) {
    return 0;
  }

  cel_set_cell(cell, lattice, position, types);

  /* find primitive cell */
  if ((primitive = prm_get_primitive(cell, symprec)) == NULL) {
    cel_free_cell(cell);
    return 0;
  }

  num_prim_atom = primitive->cell->size;
  if (num_prim_atom < num_atom && num_prim_atom > 0 ) {
    mat_copy_matrix_d3(lattice, primitive->cell->lattice);
    for (i = 0; i < primitive->cell->size; i++) {
      types[i] = primitive->cell->types[i];
      mat_copy_vector_d3(position[i], primitive->cell->position[i]);
    }
  }

  prm_free_primitive(primitive);
  cel_free_cell(cell);
    
  return num_prim_atom;
}
示例#26
0
/* Return 0 if failed */
int spg_get_symmetry_from_database(int rotations[192][3][3],
				   double translations[192][3],
				   const int hall_number)
{
  int i, size;
  Symmetry *symmetry;

  symmetry = NULL;

  if ((symmetry = spgdb_get_spacegroup_operations(hall_number)) == NULL) {
    return 0;
  }

  for (i = 0; i < symmetry->size; i++) {
    mat_copy_matrix_i3(rotations[i], symmetry->rot[i]);
    mat_copy_vector_d3(translations[i], symmetry->trans[i]);
  }
  size = symmetry->size;

  sym_free_symmetry(symmetry);

  return size;
}
示例#27
0
static Symmetry *
get_space_group_operations(SPGCONST PointSymmetry *lattice_sym,
			   SPGCONST Cell *cell,
			   const double symprec)
{
  int i, j, num_sym, total_num_sym;
  VecDBL **trans;
  Symmetry *symmetry;

  debug_print("get_space_group_operations:\n");
  
  trans = (VecDBL**) malloc(sizeof(VecDBL*) * lattice_sym->size);
  total_num_sym = 0;
  for (i = 0; i < lattice_sym->size; i++) {
    trans[i] = get_translation(lattice_sym->rot[i], cell, symprec, 0);
    total_num_sym += trans[i]->size;
  }

  symmetry = sym_alloc_symmetry(total_num_sym);
  num_sym = 0;
  for (i = 0; i < lattice_sym->size; i++) {
    for (j = 0; j < trans[i]->size; j++) {
      mat_copy_vector_d3(symmetry->trans[num_sym + j], trans[i]->vec[j]);
      mat_copy_matrix_i3(symmetry->rot[num_sym + j], lattice_sym->rot[i]);
    }
    num_sym += trans[i]->size;
  }

  for (i = 0; i < lattice_sym->size; i++) {
    mat_free_VecDBL(trans[i]);
  }
  free(trans);
  trans = NULL;

  return symmetry;
}
示例#28
0
static VecDBL * get_exact_positions(int * wyckoffs,
				    int * equiv_atoms,
				    SPGCONST Cell * bravais,
				    SPGCONST Symmetry * conv_sym,
				    const int hall_number,
				    const double symprec)
{
  int i, j, k, l, num_indep_atoms;
  double pos[3];
  int *indep_atoms;
  VecDBL *positions;

  debug_print("get_symmetrized_positions\n");

  indep_atoms = (int*) malloc(sizeof(int) * bravais->size);
  positions = mat_alloc_VecDBL(bravais->size);
  num_indep_atoms = 0;

  for (i = 0; i < bravais->size; i++) {
    /* Check if atom_i overlap to an atom already set at the exact position. */
    for (j = 0; j < num_indep_atoms; j++) {
      for (k = 0; k < conv_sym->size; k++) {
	mat_multiply_matrix_vector_id3(pos,
				       conv_sym->rot[k],
				       positions->vec[indep_atoms[j]]);
	for (l = 0; l < 3; l++) {
	  pos[l] += conv_sym->trans[k][l];
	}
	if (cel_is_overlap(pos,
			   bravais->position[i],
			   bravais->lattice,
			   symprec)) {
	  /* Equivalent atom was found. */
	  for (l = 0; l < 3; l++) {
	    pos[l] -= mat_Nint(pos[l]);
	  }
	  mat_copy_vector_d3(positions->vec[i], pos);
	  wyckoffs[i] = wyckoffs[indep_atoms[j]];
	  equiv_atoms[i] = indep_atoms[j];
	  goto escape;
	}
      }
    }
    
    /* No equivalent atom was found. */
    indep_atoms[num_indep_atoms] = i;
    num_indep_atoms++;
    mat_copy_vector_d3(positions->vec[i], bravais->position[i]);
    get_exact_location(positions->vec[i],
		       conv_sym,
		       bravais->lattice,
		       symprec);
    wyckoffs[i] = get_Wyckoff_notation(positions->vec[i],
				       conv_sym,
				       bravais->lattice,
				       hall_number,
				       symprec);
    equiv_atoms[i] = i;
  escape:
    ;
  }

  free(indep_atoms);
  indep_atoms = NULL;

  return positions;
}
示例#29
0
/* Return NULL if failed */
static Symmetry *
get_space_group_operations(SPGCONST PointSymmetry *lattice_sym,
			   SPGCONST Cell *primitive,
			   const double symprec)
{
  int i, j, num_sym, total_num_sym;
  VecDBL **trans;
  Symmetry *symmetry;

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

  trans = NULL;
  symmetry = NULL;

  if ((trans = (VecDBL**) malloc(sizeof(VecDBL*) * lattice_sym->size))
      == NULL) {
    warning_print("spglib: Memory could not be allocated ");
    return NULL;
  }

  for (i = 0; i < lattice_sym->size; i++) {
    trans[i] = NULL;
  }

  total_num_sym = 0;
  for (i = 0; i < lattice_sym->size; i++) {

    if ((trans[i] = get_translation(lattice_sym->rot[i], primitive, symprec, 0))
	!= NULL) {

      debug_print("  match translation %d/%d; tolerance = %f\n",
		  i + 1, lattice_sym->size, symprec);

      total_num_sym += trans[i]->size;
    }
  }

  if ((symmetry = sym_alloc_symmetry(total_num_sym)) == NULL) {
    goto ret;
  }

  num_sym = 0;
  for (i = 0; i < lattice_sym->size; i++) {
    if (trans[i] == NULL) {
      continue;
    }
    for (j = 0; j < trans[i]->size; j++) {
      mat_copy_vector_d3(symmetry->trans[num_sym + j], trans[i]->vec[j]);
      mat_copy_matrix_i3(symmetry->rot[num_sym + j], lattice_sym->rot[i]);
    }
    num_sym += trans[i]->size;
  }

 ret:
  for (i = 0; i < lattice_sym->size; i++) {
    if (trans[i] != NULL) {
      mat_free_VecDBL(trans[i]);
      trans[i] = NULL;
    }
  }
  free(trans);
  trans = NULL;

  return symmetry;
}
示例#30
0
/* Return NULL if failed */
static Symmetry * reduce_operation(SPGCONST Cell * primitive,
				   SPGCONST Symmetry * symmetry,
				   const double symprec,
				   const double angle_symprec)
{
  int i, j, num_sym;
  Symmetry * sym_reduced;
  PointSymmetry point_symmetry;
  MatINT *rot;
  VecDBL *trans;

  debug_print("reduce_operation:\n");

  sym_reduced = NULL;
  rot = NULL;
  trans = NULL;

  point_symmetry = get_lattice_symmetry(primitive->lattice,
					symprec,
					angle_symprec);
  if (point_symmetry.size == 0) {
    return NULL;
  }

  if ((rot = mat_alloc_MatINT(symmetry->size)) == NULL) {
    return NULL;
  }

  if ((trans = mat_alloc_VecDBL(symmetry->size)) == NULL) {
    mat_free_MatINT(rot);
    rot = NULL;
    return NULL;
  }

  num_sym = 0;
  for (i = 0; i < point_symmetry.size; i++) {
    for (j = 0; j < symmetry->size; j++) {
      if (mat_check_identity_matrix_i3(point_symmetry.rot[i],
				       symmetry->rot[j])) {
	if (is_overlap_all_atoms(symmetry->trans[j],
				 symmetry->rot[j],
				 primitive,
				 symprec,
				 0)) {
	  mat_copy_matrix_i3(rot->mat[num_sym], symmetry->rot[j]);
	  mat_copy_vector_d3(trans->vec[num_sym], symmetry->trans[j]);
	  num_sym++;
	}
      }
    }
  }

  if ((sym_reduced = sym_alloc_symmetry(num_sym)) != NULL) {
    for (i = 0; i < num_sym; i++) {
      mat_copy_matrix_i3(sym_reduced->rot[i], rot->mat[i]);
      mat_copy_vector_d3(sym_reduced->trans[i], trans->vec[i]);
    }
  }

  mat_free_MatINT(rot);
  rot = NULL;
  mat_free_VecDBL(trans);
  trans = NULL;

  return sym_reduced;
}