示例#1
0
static PointSymmetry get_lattice_symmetry(SPGCONST Cell *cell,
					  const double symprec)
{
  int i, j, k, num_sym;
  int axes[3][3];
  double lattice[3][3], min_lattice[3][3];
  double metric[3][3], metric_orig[3][3];
  PointSymmetry lattice_sym;

  debug_print("get_lattice_symmetry:\n");

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

  mat_get_metric(metric_orig, min_lattice);

  num_sym = 0;
  for (i = 0; i < 26; i++) {
    for (j = 0; j < 26; j++) {
      for (k = 0; k < 26; k++) {
	set_axes(axes, i, j, k);
	if (! ((mat_get_determinant_i3(axes) == 1) ||
	       (mat_get_determinant_i3(axes) == -1))) {
	  continue;
	}
	mat_multiply_matrix_di3(lattice, min_lattice, axes);
	mat_get_metric(metric, lattice);
	
	if (is_identity_metric(metric, metric_orig, symprec)) {
	  mat_copy_matrix_i3(lattice_sym.rot[num_sym], axes);
	  num_sym++;
	}
	  
	if (num_sym > 48) {
	  warning_print("spglib: Too many lattice symmetries was found.\n");
	  warning_print("        Tolerance may be too large ");
	  warning_print("(line %d, %s).\n", __LINE__, __FILE__);
	  goto err;
	}
      }
    }
  }

  lattice_sym.size = num_sym;
  return transform_pointsymmetry(&lattice_sym,
				 cell->lattice,
				 min_lattice);
  
 err:
  lattice_sym.size = 0;
  return lattice_sym;
}
示例#2
0
static PointSymmetry get_lattice_symmetry(SPGCONST double cell_lattice[3][3],
					  const double symprec,
					  const double angle_symprec)
{
  int i, j, k, attempt, num_sym;
  double angle_tol;
  int axes[3][3];
  double lattice[3][3], min_lattice[3][3];
  double metric[3][3], metric_orig[3][3];
  PointSymmetry lattice_sym;

  debug_print("get_lattice_symmetry:\n");

  lattice_sym.size = 0;

  if (! del_delaunay_reduce(min_lattice, cell_lattice, symprec)) {
    goto err;
  }

  mat_get_metric(metric_orig, min_lattice);
  angle_tol = angle_symprec;

  for (attempt = 0; attempt < 100; attempt++) {
    num_sym = 0;
    for (i = 0; i < 26; i++) {
      for (j = 0; j < 26; j++) {
	for (k = 0; k < 26; k++) {
	  set_axes(axes, i, j, k);
	  if (! ((mat_get_determinant_i3(axes) == 1) ||
		 (mat_get_determinant_i3(axes) == -1))) {
	    continue;
	  }
	  mat_multiply_matrix_di3(lattice, min_lattice, axes);
	  mat_get_metric(metric, lattice);

	  if (is_identity_metric(metric, metric_orig, symprec, angle_tol)) {
	    if (num_sym > 47) {
	      angle_tol *= ANGLE_REDUCE_RATE;
	      warning_print("spglib: Too many lattice symmetries was found.\n");
	      warning_print("        Reduce angle tolerance to %f", angle_tol);
	      warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
	      goto next_attempt;
	    }

	    mat_copy_matrix_i3(lattice_sym.rot[num_sym], axes);
	    num_sym++;
	  }
	}
      }
    }

    if (num_sym < 49 || angle_tol < 0) {
      lattice_sym.size = num_sym;
      return transform_pointsymmetry(&lattice_sym, cell_lattice, min_lattice);
    }

  next_attempt:
    ;
  }

 err:
  debug_print("get_lattice_symmetry failed.\n");
  return lattice_sym;
}
示例#3
0
/*    was not a primitive cell. */
static Symmetry * get_operations(SPGCONST Cell *cell,
				 const double symprec)
{
  int i, j, attempt;
  double tolerance;
  PointSymmetry lattice_sym;
  Symmetry *symmetry, *symmetry_orig, *symmetry_reduced;
  Primitive primitive;

  debug_print("get_operations:\n");

  symmetry_orig = NULL;

  lattice_sym = get_lattice_symmetry(cell, symprec);
  if (lattice_sym.size == 0) {
    debug_print("get_lattice_symmetry failed.\n");
    goto end;
  }

  primitive = prm_get_primitive_and_pure_translations(cell, symprec);
  if (primitive.cell->size == 0) {
    goto deallocate_and_end;
  }

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

  
  symmetry = get_space_group_operations(&lattice_sym,
					primitive.cell,
					symprec);
  if (symmetry->size > 48) {
    tolerance = symprec;
    for (attempt = 0; attempt < 100; attempt++) {
      tolerance *= REDUCE_RATE;
      warning_print("spglib: number of symmetry operations for primitive cell > 48 was found. (line %d, %s).\n", __LINE__, __FILE__);
      warning_print("tolerance is reduced to %f\n", tolerance);
      symmetry_reduced = reduce_operation(primitive.cell,
					  symmetry,
					  tolerance);
      sym_free_symmetry(symmetry);
      symmetry = symmetry_reduced;
      if (symmetry_reduced->size > 48) {
	;
      } else {
	break;
      }
    }
  }

  symmetry_orig = recover_operations_original(symmetry,
					      primitive.pure_trans,
					      cell,
					      primitive.cell);
  sym_free_symmetry(symmetry);

  for (i = 0; i < symmetry_orig->size; i++) {
    for (j = 0; j < 3; j++) {
      symmetry_orig->trans[i][j] -= mat_Nint(symmetry_orig->trans[i][j]);
    }
  }

 deallocate_and_end:
  cel_free_cell(primitive.cell);
  mat_free_VecDBL(primitive.pure_trans);

 end:
  if (! symmetry_orig) {
    symmetry_orig = sym_alloc_symmetry(0);
  }
  return symmetry_orig;
}
示例#4
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;
}