コード例 #1
0
ファイル: primitive.c プロジェクト: alexurba/cftb
static Cell * get_cell_with_smallest_lattice( SPGCONST Cell * cell,
					      const double symprec )
{
  int i, j;
  double min_lat[3][3], trans_mat[3][3], inv_lat[3][3];
  Cell * smallest_cell;

  if ( lat_smallest_lattice_vector( min_lat,
				    cell->lattice,
				    symprec ) ) {
    mat_inverse_matrix_d3( inv_lat, min_lat, 0 );
    mat_multiply_matrix_d3( trans_mat, inv_lat, cell->lattice );
    smallest_cell = cel_alloc_cell( cell->size );
    mat_copy_matrix_d3( smallest_cell->lattice, min_lat );
    for ( i = 0; i < cell->size; i++ ) {
      smallest_cell->types[i] = cell->types[i];
      mat_multiply_matrix_vector_d3( smallest_cell->position[i],
				     trans_mat, cell->position[i] );
      for ( j = 0; j < 3; j++ ) {
	cell->position[i][j] -= mat_Nint( cell->position[i][j] );
      }
    }
  } else {
    smallest_cell = cel_alloc_cell( -1 );
  }

  return smallest_cell;
}
コード例 #2
0
ファイル: primitive.c プロジェクト: alexurba/cftb
/* If primitive could not be found, primitive->size = -1 is returned. */
static Cell * get_primitive( int * mapping_table,
			     SPGCONST Cell * cell,
			     const VecDBL * pure_trans,
			     const double symprec )
{
  int multi;
  double prim_lattice[3][3];
  Cell * primitive;

  /* Primitive lattice vectors are searched. */
  /* To be consistent, sometimes tolerance is decreased iteratively. */
  /* The descreased tolerance is stored in 'static double tolerance'. */
  multi = get_primitive_lattice_vectors_iterative( prim_lattice,
						   cell,
						   pure_trans,
						   symprec );
  if ( ! multi  ) {
    goto not_found;
  }

  primitive = cel_alloc_cell( cell->size / multi );

  if ( ! lat_smallest_lattice_vector( primitive->lattice,
				      prim_lattice,
				      symprec ) ) {
    cel_free_cell( primitive );
    goto not_found;
  }

  /* Fit atoms into new primitive cell */
  if ( ! trim_cell( primitive, mapping_table, cell, symprec ) ) {
    cel_free_cell( primitive );
    goto not_found;
  }

  debug_print("Original cell lattice.\n");
  debug_print_matrix_d3(cell->lattice);
  debug_print("Found primitive lattice after choosing least axes.\n");
  debug_print_matrix_d3(primitive->lattice);
  debug_print("Number of atoms in primitive cell: %d\n", primitive->size);
  debug_print("Volume: original %f --> primitive %f\n",
	      mat_get_determinant_d3(cell->lattice),
	      mat_get_determinant_d3(primitive->lattice));

  /* found */
  return primitive;

 not_found:
  primitive = cel_alloc_cell( -1 );
  warning_print("spglib: Primitive cell could not found ");
  warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  return primitive;
}
コード例 #3
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
int spg_get_ir_kpoints( int map[],
			SPGCONST double kpoints[][3],
			const int num_kpoint,
			SPGCONST double lattice[3][3],
			SPGCONST double position[][3],
			const int types[],
			const int num_atom,
			const int is_time_reversal,
			const double symprec )
{
  Symmetry *symmetry;
  Cell *cell;
  int num_ir_kpoint;

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

  num_ir_kpoint = kpt_get_irreducible_kpoints( map, kpoints, num_kpoint,
					       lattice, symmetry,
					       is_time_reversal, symprec );


  cel_free_cell( cell );
  sym_free_symmetry( symmetry );

  return num_ir_kpoint;
}
コード例 #4
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
int spg_get_ir_reciprocal_mesh( int grid_point[][3],
				int map[],
				const int mesh[3],
				const int is_shift[3],
				const int is_time_reversal,
				SPGCONST double lattice[3][3],
				SPGCONST double position[][3],
				const int types[],
				const int num_atom,
				const double symprec )
{
  Symmetry *symmetry;
  Cell *cell;
  int num_ir;

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

  num_ir = kpt_get_irreducible_reciprocal_mesh( grid_point,
						map,
						mesh,
						is_shift,
						is_time_reversal,
						lattice,
						symmetry,
						symprec );


  cel_free_cell( cell );
  sym_free_symmetry( symmetry );

  return num_ir;
}
コード例 #5
0
ファイル: spglib.c プロジェクト: vanceeasleaf/phonopy
static int get_schoenflies(char symbol[10],
			   SPGCONST double lattice[3][3],
			   SPGCONST double position[][3],
			   const int types[],
			   const int num_atom,
			   const double symprec)
{
  Cell *cell;
  Primitive *primitive;
  Spacegroup spacegroup;

  cell = NULL;
  primitive = NULL;
  spacegroup.number = 0;

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

  if ((primitive = spa_get_spacegroup(&spacegroup, cell, symprec)) != NULL) {
    prm_free_primitive(primitive);
    if (spacegroup.number > 0) {
      strcpy(symbol, spacegroup.schoenflies);
    }
  }

  cel_free_cell(cell);

  return spacegroup.number;
}
コード例 #6
0
ファイル: refinement.c プロジェクト: etp12/avogadro
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;
}
コード例 #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
ファイル: refinement.c プロジェクト: etp12/avogadro
static Cell * get_conventional_primitive(SPGCONST Spacegroup * spacegroup,
        SPGCONST Cell * primitive)
{
    int i, j;
    double inv_brv[3][3], trans_mat[3][3];
    Cell * conv_prim;

    conv_prim = cel_alloc_cell(primitive->size);

    mat_inverse_matrix_d3(inv_brv, spacegroup->bravais_lattice, 0);
    mat_multiply_matrix_d3(trans_mat, inv_brv, primitive->lattice);

    for (i = 0; i < primitive->size; i++) {
        conv_prim->types[i] = primitive->types[i];
        mat_multiply_matrix_vector_d3(conv_prim->position[i],
                                      trans_mat,
                                      primitive->position[i]);
        for (j = 0; j < 3; j++) {
            conv_prim->position[i][j] -= spacegroup->origin_shift[j];
            conv_prim->position[i][j] -= mat_Nint(conv_prim->position[i][j]);
        }
    }

    return conv_prim;
}
コード例 #9
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;
}
コード例 #10
0
ファイル: primitive.c プロジェクト: kassali-kamel/spglib
/* If primitive could not be found, primitive->size = 0 is returned. */
static Cell * get_primitive(int * mapping_table,
			    SPGCONST Cell * cell,
			    const VecDBL * pure_trans,
			    const double symprec)
{
  int multi;
  double prim_lattice[3][3];
  Cell * primitive_cell;

  debug_print("get_primitive:\n");

  /* Primitive lattice vectors are searched. */
  /* To be consistent, sometimes tolerance is decreased iteratively. */
  /* The descreased tolerance is stored in 'static double tolerance'. */
  multi = get_primitive_lattice_vectors_iterative(prim_lattice,
						  cell,
						  pure_trans,
						  symprec);
  if (! multi) {
    goto not_found;
  }

  primitive_cell = cel_alloc_cell(cell->size / multi);

  if (! lat_smallest_lattice_vector(primitive_cell->lattice,
				    prim_lattice,
				    symprec)) {
    cel_free_cell(primitive_cell);
    goto not_found;
  }

  /* Fit atoms into new primitive cell */
  if (! trim_cell(primitive_cell, mapping_table, cell, symprec)) {
    cel_free_cell(primitive_cell);
    goto not_found;
  }

  /* found */
  return primitive_cell;

 not_found:
  primitive_cell = cel_alloc_cell(0);
  warning_print("spglib: Primitive cell could not be found ");
  warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  return primitive_cell;
}
コード例 #11
0
ファイル: cell.c プロジェクト: Algerien1970/avogadro
Cell * cel_copy_cell( SPGCONST Cell * cell )
{
  Cell * cell_new;
  
  cell_new = cel_alloc_cell( cell->size );
  cel_set_cell( cell_new,
		cell->lattice,
		cell->position,
		cell->types );
  return cell_new;
}
コード例 #12
0
ファイル: refinement.c プロジェクト: etp12/avogadro
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;
}
コード例 #13
0
ファイル: primitive.c プロジェクト: kassali-kamel/spglib
/* 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;
}
コード例 #14
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;
}
コード例 #15
0
ファイル: refinement.c プロジェクト: alexurba/cftb
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;
}
コード例 #16
0
ファイル: cell.c プロジェクト: dlonie/XtalComp
Cell * cel_copy_cell(const Cell * cell)
{
  Cell * cell_new;

  cell_new = NULL;

  if ((cell_new = cel_alloc_cell(cell->size)) == NULL) {
    return NULL;
  }

  cel_set_cell(cell_new,
               cell->lattice,
               cell->position,
               cell->types);

  return cell_new;
}
コード例 #17
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
int spg_get_max_multiplicity( SPGCONST double lattice[3][3],
			      SPGCONST double position[][3],
			      const int types[],
			      const int num_atom,
			      const double symprec )
{
  Cell *cell;
  int num_max_multi;

  cell = cel_alloc_cell( num_atom );
  cel_set_cell( cell, lattice, position, types );
  /* 48 is the magic number, which is the number of rotations */
  /* in the highest point symmetry Oh. */
  num_max_multi = sym_get_multiplicity( cell, symprec ) * 48;
  cel_free_cell( cell );

  return num_max_multi;
}
コード例 #18
0
ファイル: primitive.c プロジェクト: kassali-kamel/spglib
/* 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;
}
コード例 #19
0
ファイル: refinement.c プロジェクト: etp12/avogadro
/* 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;
}
コード例 #20
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
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;
}
コード例 #21
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
int spg_get_multiplicity( SPGCONST double lattice[3][3],
			  SPGCONST double position[][3],
			  const int types[],
			  const int num_atom,
			  const double symprec )
{
  Symmetry *symmetry;
  Cell *cell;
  int size;

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

  size = symmetry->size;

  cel_free_cell( cell );
  sym_free_symmetry( symmetry );

  return size;
}
コード例 #22
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
int spg_get_schoenflies( char symbol[10],
			 SPGCONST double lattice[3][3],
			 SPGCONST double position[][3],
			 const int types[], const int num_atom,
			 const double symprec )
{
  Cell *cell;
  Spacegroup spacegroup;

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

  spacegroup = spa_get_spacegroup( cell, symprec );
  if ( spacegroup.number > 0 ) {
    strcpy(symbol, spacegroup.schoenflies);
  }

  cel_free_cell( cell );

  return spacegroup.number;
}
コード例 #23
0
ファイル: spglib.c プロジェクト: vanceeasleaf/phonopy
/* 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;
}
コード例 #24
0
ファイル: primitive.c プロジェクト: CarstenTUBT/spglib
/* Return NULL if failed */
static Cell * get_cell_with_smallest_lattice(SPGCONST Cell * cell,
					     const double symprec)
{
  int i, j;
  double min_lat[3][3], trans_mat[3][3], inv_lat[3][3];
  Cell * smallest_cell;

  debug_print("get_cell_with_smallest_lattice:\n");
  
  smallest_cell = NULL;

  if (!lat_smallest_lattice_vector(min_lat,
				   cell->lattice,
				   symprec)) {
    goto err;
  }

  mat_inverse_matrix_d3(inv_lat, min_lat, 0);
  mat_multiply_matrix_d3(trans_mat, inv_lat, cell->lattice);

  if ((smallest_cell = cel_alloc_cell(cell->size)) == NULL) {
    goto err;
  }

  mat_copy_matrix_d3(smallest_cell->lattice, min_lat);
  for (i = 0; i < cell->size; i++) {
    smallest_cell->types[i] = cell->types[i];
    mat_multiply_matrix_vector_d3(smallest_cell->position[i],
				  trans_mat, cell->position[i]);
    for (j = 0; j < 3; j++) {
      cell->position[i][j] = mat_Dmod1(cell->position[i][j]);
    }
  }

  return smallest_cell;

 err:
  return NULL;
}
コード例 #25
0
ファイル: spglib.c プロジェクト: akashneo/pymatgen
static int get_symmetry_with_collinear_spin(int rotation[][3][3],
					    double translation[][3],
					    const int max_size,
					    SPGCONST double lattice[3][3],
					    SPGCONST double position[][3],
					    const int types[],
					    const double spins[],
					    const int num_atom,
					    const double symprec)
{
  int i, j, size;
  Symmetry *symmetry;
  Cell *cell;

  cell = cel_alloc_cell(num_atom);
  cel_set_cell(cell, lattice, position, types);
  symmetry = spn_get_collinear_operation(cell, spins, symprec);
  
  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);
    sym_free_symmetry(symmetry);
    return 0;
  }

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

  size = symmetry->size;

  cel_free_cell(cell);
  sym_free_symmetry(symmetry);

  return size;
}
コード例 #26
0
ファイル: spglib.c プロジェクト: vanceeasleaf/phonopy
/* Return NULL if failed */
static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
				   SPGCONST double position[][3],
				   const int types[],
				   const int num_atom,
				   const int hall_number,
				   const double symprec)
{
  Spacegroup spacegroup;
  SpacegroupType spacegroup_type;
  SpglibDataset *dataset;
  Cell *cell;
  Primitive *primitive;

  spacegroup.number = 0;
  dataset = NULL;
  cell = NULL;
  primitive = NULL;

  if ((dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset))) == NULL) {
    warning_print("spglib: Memory could not be allocated.");
    return NULL;
  }

  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;
  dataset->n_brv_atoms = 0;
  dataset->brv_positions = NULL;
  dataset->brv_types = NULL;

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

  cel_set_cell(cell, lattice, position, types);

  primitive = spa_get_spacegroup(&spacegroup, cell, symprec);

  if ((spacegroup.number > 0) && (primitive != NULL)) {

    /* With hall_number > 0, specific choice is searched. */
    if (hall_number > 0) {
      spacegroup_type = spgdb_get_spacegroup_type(hall_number);
      if (spacegroup.number == spacegroup_type.number) {
	spacegroup = spa_get_spacegroup_with_hall_number(primitive,
							 hall_number);
      } else {
	goto err;
      }

      if (spacegroup.number == 0) {
	goto err;
      }
    }

    if (spacegroup.number > 0) {
      if ((set_dataset(dataset,
		       cell,
		       primitive->cell,
		       &spacegroup,
		       primitive->mapping_table,
		       primitive->tolerance)) == 0) {
	goto err;
      }
    }
  }

  cel_free_cell(cell);
  prm_free_primitive(primitive);

  return dataset;

 err:
  cel_free_cell(cell);
  prm_free_primitive(primitive);
  free(dataset);
  dataset = NULL;
  return NULL;
}
コード例 #27
0
ファイル: spglib.c プロジェクト: jasonlarkin/ntpl
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;
}
コード例 #28
0
ファイル: spglib.c プロジェクト: vanceeasleaf/phonopy
/* Return 0 if failed */
static int get_symmetry_with_collinear_spin(int rotation[][3][3],
					    double translation[][3],
					    int equivalent_atoms[],
					    const int max_size,
					    SPGCONST double lattice[3][3],
					    SPGCONST double position[][3],
					    const int types[],
					    const double spins[],
					    const int num_atom,
					    const double symprec)
{
  int i, size;
  Symmetry *symmetry, *sym_nonspin;
  Cell *cell;
  SpglibDataset *dataset;

  size = 0;
  symmetry = NULL;
  sym_nonspin = NULL;
  cell = NULL;
  dataset = NULL;

  if ((cell = cel_alloc_cell(num_atom)) == NULL) {
    goto err;
  }

  cel_set_cell(cell, lattice, position, types);

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    cel_free_cell(cell);
    goto err;
  }

  if ((sym_nonspin = sym_alloc_symmetry(dataset->n_operations)) == NULL) {
    spg_free_dataset(dataset);
    cel_free_cell(cell);
    goto err;
  }

  for (i = 0; i < dataset->n_operations; i++) {
    mat_copy_matrix_i3(sym_nonspin->rot[i], dataset->rotations[i]);
    mat_copy_vector_d3(sym_nonspin->trans[i], dataset->translations[i]);
  }
  spg_free_dataset(dataset);

  if ((symmetry = spn_get_collinear_operations(equivalent_atoms,
					       sym_nonspin,
					       cell,
					       spins,
					       symprec)) == NULL) {
    sym_free_symmetry(sym_nonspin);
    cel_free_cell(cell);
    goto err;
  }

  sym_free_symmetry(sym_nonspin);
  
  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);
    sym_free_symmetry(symmetry);
    goto err;
  }

  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;

  cel_free_cell(cell);
  sym_free_symmetry(symmetry);

  return size;

 err:
  return 0;
}
コード例 #29
0
ファイル: spglib.c プロジェクト: nfh/phonopy
static int get_standardized_cell(double lattice[3][3],
				 double position[][3],
				 int types[],
				 const int num_atom,
				 const int to_primitive,
				 const double symprec)
{
  int num_std_atom;
  SpglibDataset *dataset;
  Cell *std_cell, *cell;
  Centering centering;

  num_std_atom = 0;
  dataset = NULL;
  std_cell = NULL;
  cell = NULL;

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

  if (to_primitive) {
    if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) {
      goto err;
    }
    if (dataset->hall_number == 433 ||
	dataset->hall_number == 436 ||
	dataset->hall_number == 444 ||
	dataset->hall_number == 450 ||
	dataset->hall_number == 452 ||
	dataset->hall_number == 458 ||
	dataset->hall_number == 460) {
      centering = R_CENTER;
    }
  } else {
    centering = PRIMITIVE;
  }

  if ((cell = cel_alloc_cell(num_atom)) == NULL) {
    spg_free_dataset(dataset);
    goto err;
  }
  
  cel_set_cell(cell, lattice, position, types);
  std_cell = spa_transform_to_primitive(cell,
					dataset->transformation_matrix,
					centering,
					symprec);
  spg_free_dataset(dataset);
  cel_free_cell(cell);

  if (std_cell == NULL) {
    goto err;
  }

  set_cell(lattice, position, types, std_cell);
  num_std_atom = std_cell->size;

  cel_free_cell(std_cell);

  return num_std_atom;

 err:
  return 0;
}
コード例 #30
0
ファイル: cell.c プロジェクト: dlonie/XtalComp
/* Return NULL if failed */
static Cell * trim_cell(int * mapping_table,
                        SPGCONST double trimmed_lattice[3][3],
                        const Cell * cell,
                        const double symprec)
{
  int i, index_atom, ratio;
  Cell *trimmed_cell;
  VecDBL * position;
  int *overlap_table;

  position = NULL;
  overlap_table = NULL;
  trimmed_cell = NULL;

  ratio = abs(mat_Nint(mat_get_determinant_d3(cell->lattice) /
                       mat_get_determinant_d3(trimmed_lattice)));

  /* Check if cell->size is dividable by ratio */
  if ((cell->size / ratio) * ratio != cell->size) {
    return NULL;
  }

  if ((trimmed_cell = cel_alloc_cell(cell->size / ratio)) == NULL) {
    return NULL;
  }

  if ((position = translate_atoms_in_trimmed_lattice(cell,
                                                     trimmed_lattice))
      == NULL) {
    cel_free_cell(trimmed_cell);
    trimmed_cell = NULL;
    goto err;
  }

  mat_copy_matrix_d3(trimmed_cell->lattice, trimmed_lattice);

  if ((overlap_table = get_overlap_table(position,
                                         cell->size,
                                         cell->types,
                                         trimmed_cell,
                                         symprec)) == NULL) {
    mat_free_VecDBL(position);
    position = NULL;
    cel_free_cell(trimmed_cell);
    trimmed_cell = NULL;
    goto err;
  }

  index_atom = 0;
  for (i = 0; i < cell->size; i++) {
    if (overlap_table[i] == i) {
      mapping_table[i] = index_atom;
      trimmed_cell->types[index_atom] = cell->types[i];
      index_atom++;
    } else {
      mapping_table[i] = mapping_table[overlap_table[i]];
    }
  }

  set_positions(trimmed_cell,
                position,
                mapping_table,
                overlap_table);

  mat_free_VecDBL(position);
  position = NULL;
  free(overlap_table);

  return trimmed_cell;

 err:
  return NULL;
}