Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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 *trans;

#ifdef _OPENMP
  int num_min_type_atoms;
  int *min_type_atoms;
  double vec[3];
#endif

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

#ifdef _OPENMP
  if (cell->size < NUM_ATOMS_CRITERION_FOR_OPENMP) {
    search_translation_part(is_found,
			    cell,
			    rot,
			    min_atom_index,
			    origin,
			    symprec,
			    is_identity);
  } else {
    /* Collect indices of atoms with the type where the minimum number */
    /* of atoms belong. */
    min_type_atoms = (int*) malloc(sizeof(int)*cell->size);
    num_min_type_atoms = 0;
    for (i = 0; i < cell->size; i++) {
      if (cell->types[i] == cell->types[min_atom_index]) {
	min_type_atoms[num_min_type_atoms] = i;
	num_min_type_atoms++;
      }
    }
#pragma omp parallel for private(j, vec)
    for (i = 0; i < num_min_type_atoms; i++) {
      for (j = 0; j < 3; j++) {
	vec[j] = cell->position[min_type_atoms[i]][j] - origin[j];
      }
      if (is_overlap_all_atoms(vec,
			       rot,
			       cell,
			       symprec,
			       is_identity)) {
	is_found[min_type_atoms[i]] = 1;
      }
    }

    free(min_type_atoms);
  }
#else
  search_translation_part(is_found,
			  cell,
			  rot,
			  min_atom_index,
			  origin,
			  symprec,
			  is_identity);
#endif

  
  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]) {
      for (j = 0; j < 3; j++) {
	trans->vec[num_trans][j] = cell->position[i][j] - origin[j];
      }
      num_trans++;
    }
  }

  free(is_found);
  is_found = NULL;
  
  return trans;
}
Ejemplo n.º 3
0
/* Return NULL if failed */
static VecDBL * get_translation(SPGCONST int rot[3][3],
				SPGCONST Cell *cell,
				const double symprec,
				const int is_identity)
{
  int i, j, k, min_atom_index, num_trans;
  int *is_found;
  double origin[3];
  VecDBL *trans;

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

  num_trans = 0;
  is_found = NULL;
  trans = NULL;

#ifdef _OPENMP
  int num_min_type_atoms;
  int *min_type_atoms;
  double vec[3];

  min_type_atoms = NULL;
#endif

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

  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);
  if (min_atom_index == -1) {
    debug_print("spglib: get_index_with_least_atoms failed.\n");
    goto ret;
  }

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

#ifdef _OPENMP
  if (cell->size < NUM_ATOMS_CRITERION_FOR_OPENMP) {
    num_trans = search_translation_part(is_found,
					cell,
					rot,
					min_atom_index,
					origin,
					symprec,
					is_identity);
    if (num_trans == 0) {
      goto ret;
    }
  } else {
    /* Collect indices of atoms with the type where the minimum number */
    /* of atoms belong. */
    if ((min_type_atoms = (int*) malloc(sizeof(int)*cell->size)) == NULL) {
      warning_print("spglib: Memory could not be allocated ");
      goto ret;
    }

    num_min_type_atoms = 0;
    for (i = 0; i < cell->size; i++) {
      if (cell->types[i] == cell->types[min_atom_index]) {
	min_type_atoms[num_min_type_atoms] = i;
	num_min_type_atoms++;
      }
    }
#pragma omp parallel for private(j, vec)
    for (i = 0; i < num_min_type_atoms; i++) {
      for (j = 0; j < 3; j++) {
	vec[j] = cell->position[min_type_atoms[i]][j] - origin[j];
      }
      if (is_overlap_all_atoms(vec,
			       rot,
			       cell,
			       symprec,
			       is_identity)) {
	is_found[min_type_atoms[i]] = 1;
      }
    }

    free(min_type_atoms);
    min_type_atoms = NULL;

    for (i = 0; i < cell->size; i++) {
      num_trans += is_found[i];
    }
  }
#else
  num_trans = search_translation_part(is_found,
				      cell,
				      rot,
				      min_atom_index,
				      origin,
				      symprec,
				      is_identity);
  if (num_trans == 0) {
    goto ret;
  }
#endif

  if ((trans = mat_alloc_VecDBL(num_trans)) == NULL) {
    goto ret;
  }

  k = 0;
  for (i = 0; i < cell->size; i++) {
    if (is_found[i]) {
      for (j = 0; j < 3; j++) {
	trans->vec[k][j] = cell->position[i][j] - origin[j];
      }
      k++;
    }
  }

 ret:
  free(is_found);
  is_found = NULL;

  return trans;
}