Commit 37201bed authored by pmla's avatar pmla
Browse files

Fixed folder structure

parent c705e8d0
Loading
Loading
Loading
Loading

src/PTM/compute_ptm_atom.cpp

deleted100644 → 0
+0 −307
Original line number Diff line number Diff line
/* ----------------------------------------------------------------------
         LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
         http://lammps.sandia.gov, Sandia National Laboratories
         Steve Plimpton, sjplimp@sandia.gov

         Copyright (2003) Sandia Corporation.	Under the terms of Contract
         DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
         certain rights in this software.	This software is distributed
under
         the GNU General Public License.

         See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------
         Contributing author: PM Larsen (MIT)
------------------------------------------------------------------------- */

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>

#include "atom.h"
#include "comm.h"
#include "compute_ptm_atom.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h"
#include "pair.h"
#include "update.h"

#include "ptm_functions.h"

#define MAX_NEIGHBORS 30
#define NUM_COLUMNS 7
#define UNKNOWN 0
#define OTHER 8

using namespace LAMMPS_NS;

static const char cite_user_ptm_package[] =
    "USER-PTM package:\n\n"
    "@Article{larsen2016ptm,\n"
    " author={Larsen, Peter Mahler and Schmidt, S{\o}ren and Schi{\o}tz, "
    "Jakob},\n"
    " title={Robust structural identification via polyhedral template "
    "matching},\n"
    " journal={Modelling~Simul.~Mater.~Sci.~Eng.},\n"
    " year={2016},\n"
    " number={5},\n"
    " volume={24},\n"
    " pages={055007},\n"
    " DOI = {10.1088/0965-0393/24/5/055007}"
    "}\n\n";

/* ---------------------------------------------------------------------- */

ComputePTMAtom::ComputePTMAtom(LAMMPS *lmp, int narg, char **arg)
    : Compute(lmp, narg, arg), list(NULL), output(NULL) {
  if (narg != 5)
    error->all(FLERR, "Illegal compute ptm/atom command");

  char *structures = arg[3];
  char *ptr = structures;

  const char *strings[] = {"fcc",  "hcp",  "bcc", "ico",    "sc",
                           "dcub", "dhex", "all", "default"};
  int32_t flags[] = {
      PTM_CHECK_FCC,
      PTM_CHECK_HCP,
      PTM_CHECK_BCC,
      PTM_CHECK_ICO,
      PTM_CHECK_SC,
      PTM_CHECK_DCUB,
      PTM_CHECK_DHEX,
      PTM_CHECK_ALL,
      PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_BCC | PTM_CHECK_ICO};

  input_flags = 0;
  while (*ptr != '\0') {

    bool found = false;
    for (int i = 0; i < 9; i++) {
      int len = strlen(strings[i]);
      if (strncmp(ptr, strings[i], len) == 0) {
        input_flags |= flags[i];
        ptr += len;
        found = true;
        break;
      }
    }

    if (!found)
      error->all(FLERR,
                 "Illegal compute ptm/atom command (invalid structure type)");

    if (*ptr == '\0')
      break;

    if (*ptr != '-')
      error->all(FLERR,
                 "Illegal compute ptm/atom command (invalid structure type)");

    ptr++;
  }

  double threshold = force->numeric(FLERR, arg[4]);
  if (threshold < 0.0)
    error->all(FLERR,
               "Illegal compute ptm/atom command (threshold is negative)");
  rmsd_threshold = threshold;
  if (rmsd_threshold == 0)
    rmsd_threshold = INFINITY;

  peratom_flag = 1;
  size_peratom_cols = NUM_COLUMNS;
  create_attribute = 1;
  nmax = 0;
}

/* ---------------------------------------------------------------------- */

ComputePTMAtom::~ComputePTMAtom() { memory->destroy(output); }

/* ---------------------------------------------------------------------- */

void ComputePTMAtom::init() {
  if (force->pair == NULL)
    error->all(FLERR, "Compute ptm/atom requires a pair style be defined");

  int count = 0;
  for (int i = 0; i < modify->ncompute; i++)
    if (strcmp(modify->compute[i]->style, "ptm/atom") == 0)
      count++;
  if (count > 1 && comm->me == 0)
    error->warning(FLERR, "More than one compute ptm/atom defined");

  // need an occasional full neighbor list

  int irequest = neighbor->request(this, instance_me);
  neighbor->requests[irequest]->pair = 0;
  neighbor->requests[irequest]->compute = 1;
  neighbor->requests[irequest]->half = 0;
  neighbor->requests[irequest]->full = 1;
  neighbor->requests[irequest]->occasional = 1;
}

/* ---------------------------------------------------------------------- */

void ComputePTMAtom::init_list(int id, NeighList *ptr) { list = ptr; }

/* ---------------------------------------------------------------------- */

typedef struct {
  int index;
  double d;
} ptmnbr_t;

static bool sorthelper_compare(ptmnbr_t const &a, ptmnbr_t const &b) {
  return a.d < b.d;
}

static int get_neighbors(double *pos, int jnum, int *jlist, double **x,
                         double (*nbr)[3]) {

  ptmnbr_t *nbr_order = new ptmnbr_t[jnum];

  for (int jj = 0; jj < jnum; jj++) {
    int j = jlist[jj];
    j &= NEIGHMASK;

    double dx = pos[0] - x[j][0];
    double dy = pos[1] - x[j][1];
    double dz = pos[2] - x[j][2];
    double rsq = dx * dx + dy * dy + dz * dz;

    nbr_order[jj].index = j;
    nbr_order[jj].d = rsq;
  }

  std::sort(nbr_order, nbr_order + jnum, &sorthelper_compare);
  int num_nbrs = std::min(MAX_NEIGHBORS, jnum);

  nbr[0][0] = nbr[0][1] = nbr[0][2] = 0;
  for (int jj = 0; jj < num_nbrs; jj++) {

    int j = nbr_order[jj].index;
    nbr[jj + 1][0] = x[j][0] - pos[0];
    nbr[jj + 1][1] = x[j][1] - pos[1];
    nbr[jj + 1][2] = x[j][2] - pos[2];
  }

  delete[] nbr_order;
  return num_nbrs;
}

void ComputePTMAtom::compute_peratom() {
  // PTM global initialization.  If already initialized this function does
  // nothing.
  ptm_initialize_global();

  // initialize PTM local storage
  ptm_local_handle_t local_handle = ptm_initialize_local();

  invoked_peratom = update->ntimestep;

  // grow arrays if necessary
  if (atom->nmax > nmax) {
    memory->destroy(output);
    nmax = atom->nmax;

    memory->create(output, nmax, NUM_COLUMNS, "ptm:ptm_output");
    array_atom = output;
  }

  // invoke full neighbor list (will copy or build if necessary)
  neighbor->build_one(list);

  int inum = list->inum;
  int *ilist = list->ilist;
  int *numneigh = list->numneigh;
  int **firstneigh = list->firstneigh;

  double **x = atom->x;
  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  for (int ii = 0; ii < inum; ii++) {

    int i = ilist[ii];
    output[i][0] = UNKNOWN;
    if (!(mask[i] & groupbit))
      continue;

    double *pos = x[i];

    int *jlist = firstneigh[i];
    int jnum = numneigh[i];
    if (jnum <= 0)
      continue;

    // get neighbours ordered by increasing distance
    double nbr[MAX_NEIGHBORS + 1][3];
    int num_nbrs = get_neighbors(pos, jnum, jlist, x, nbr);

    // check that we have enough neighbours for the desired structure types
    int32_t flags = 0;
    if (num_nbrs >= PTM_NUM_NBRS_SC && (input_flags & PTM_CHECK_SC))
      flags |= PTM_CHECK_SC;
    if (num_nbrs >= PTM_NUM_NBRS_FCC && (input_flags & PTM_CHECK_FCC))
      flags |= PTM_CHECK_FCC;
    if (num_nbrs >= PTM_NUM_NBRS_HCP && (input_flags & PTM_CHECK_HCP))
      flags |= PTM_CHECK_HCP;
    if (num_nbrs >= PTM_NUM_NBRS_ICO && (input_flags & PTM_CHECK_ICO))
      flags |= PTM_CHECK_ICO;
    if (num_nbrs >= PTM_NUM_NBRS_BCC && (input_flags & PTM_CHECK_BCC))
      flags |= PTM_CHECK_BCC;
    if (num_nbrs >= PTM_NUM_NBRS_DCUB && (input_flags & PTM_CHECK_DCUB))
      flags |= PTM_CHECK_DCUB;
    if (num_nbrs >= PTM_NUM_NBRS_DHEX && (input_flags & PTM_CHECK_DHEX))
      flags |= PTM_CHECK_DHEX;

    // now run PTM
    int8_t mapping[MAX_NEIGHBORS + 1];
    int32_t type, alloy_type;
    double scale, rmsd, interatomic_distance, lattice_constant;
    double q[4], F[9], F_res[3], U[9], P[9];
    ptm_index(local_handle, flags, num_nbrs + 1, nbr, NULL, true, &type,
              &alloy_type, &scale, &rmsd, q, F, F_res, U, P, mapping,
              &interatomic_distance, &lattice_constant);

    if (rmsd > rmsd_threshold) {
      type = PTM_MATCH_NONE;
    }

    // printf("%d type=%d rmsd=%f\n", i, type, rmsd);

    if (type == PTM_MATCH_NONE)
      type = OTHER;

    output[i][0] = type;
    output[i][1] = rmsd;
    output[i][2] = interatomic_distance;
    output[i][3] = q[0];
    output[i][4] = q[1];
    output[i][5] = q[2];
    output[i][6] = q[3];
  }

  // printf("finished ptm analysis\n");
  ptm_uninitialize_local(local_handle);
}

/* ----------------------------------------------------------------------
         memory usage of local atom-based array
------------------------------------------------------------------------- */

double ComputePTMAtom::memory_usage() {
  double bytes = nmax * NUM_COLUMNS * sizeof(double);
  bytes += nmax * sizeof(double);
  return bytes;
}

src/PTM/compute_ptm_atom.h

deleted100644 → 0
+0 −48
Original line number Diff line number Diff line
/* -*- c++ -*- ----------------------------------------------------------
   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
   http://lammps.sandia.gov, Sandia National Laboratories
   Steve Plimpton, sjplimp@sandia.gov

   Copyright (2003) Sandia Corporation.  Under the terms of Contract
   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
   certain rights in this software.  This software is distributed under
   the GNU General Public License.

   See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */

#ifdef COMPUTE_CLASS

ComputeStyle(ptm/atom,ComputePTMAtom)

#else

#ifndef LMP_COMPUTE_PTM_ATOM_H
#define LMP_COMPUTE_PTM_ATOM_H

#include "compute.h"

namespace LAMMPS_NS {

class ComputePTMAtom : public Compute {
 public:
  ComputePTMAtom(class LAMMPS *, int, char **);
  ~ComputePTMAtom();
  void init();
  void init_list(int, class NeighList *);
  void compute_peratom();
  double memory_usage();

 private:
  int nmax;
  int32_t input_flags;
  double rmsd_threshold;
  class NeighList *list;
  double **output;
};

}

#endif
#endif

src/PTM/ptm_constants.h

deleted100644 → 0
+0 −174
Original line number Diff line number Diff line
#ifndef PTM_CONSTANTS_H
#define PTM_CONSTANTS_H

//------------------------------------
//    definitions
//------------------------------------
#define PTM_NO_ERROR	0


#define PTM_CHECK_FCC	(1 << 0)
#define PTM_CHECK_HCP	(1 << 1)
#define PTM_CHECK_BCC	(1 << 2)
#define PTM_CHECK_ICO	(1 << 3)
#define PTM_CHECK_SC	(1 << 4)
#define PTM_CHECK_DCUB	(1 << 5)
#define PTM_CHECK_DHEX	(1 << 6)
#define PTM_CHECK_NONDIAMOND	(PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC)
#define PTM_CHECK_ALL	(PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC | PTM_CHECK_DCUB | PTM_CHECK_DHEX)

#define PTM_MATCH_NONE	0
#define PTM_MATCH_FCC	1
#define PTM_MATCH_HCP	2
#define PTM_MATCH_BCC	3
#define PTM_MATCH_ICO	4
#define PTM_MATCH_SC	5
#define PTM_MATCH_DCUB	6
#define PTM_MATCH_DHEX	7

#define PTM_ALLOY_NONE		0
#define PTM_ALLOY_PURE		1
#define PTM_ALLOY_L10		2
#define PTM_ALLOY_L12_CU	3
#define PTM_ALLOY_L12_AU	4
#define PTM_ALLOY_B2		5
#define PTM_ALLOY_SIC		6


#define PTM_MAX_INPUT_POINTS 35
#define PTM_MAX_NBRS	16
#define PTM_MAX_POINTS	(PTM_MAX_NBRS + 1)
#define PTM_MAX_FACETS	28	//2 * PTM_MAX_NBRS - 4
#define PTM_MAX_EDGES   42	//3 * PTM_MAX_NBRS - 6


//------------------------------------
//    number of neighbours
//------------------------------------
#define PTM_NUM_NBRS_FCC 12
#define PTM_NUM_NBRS_HCP 12
#define PTM_NUM_NBRS_BCC 14
#define PTM_NUM_NBRS_ICO 12
#define PTM_NUM_NBRS_SC  6
#define PTM_NUM_NBRS_DCUB  16
#define PTM_NUM_NBRS_DHEX  16

#define PTM_NUM_POINTS_FCC  (PTM_NUM_NBRS_FCC + 1)
#define PTM_NUM_POINTS_HCP  (PTM_NUM_NBRS_HCP + 1)
#define PTM_NUM_POINTS_BCC  (PTM_NUM_NBRS_BCC + 1)
#define PTM_NUM_POINTS_ICO  (PTM_NUM_NBRS_ICO + 1)
#define PTM_NUM_POINTS_SC   (PTM_NUM_NBRS_SC  + 1)
#define PTM_NUM_POINTS_DCUB (PTM_NUM_NBRS_DCUB  + 1)
#define PTM_NUM_POINTS_DHEX (PTM_NUM_NBRS_DHEX  + 1)

const int ptm_num_nbrs[8] = {0, PTM_NUM_NBRS_FCC, PTM_NUM_NBRS_HCP, PTM_NUM_NBRS_BCC, PTM_NUM_NBRS_ICO, PTM_NUM_NBRS_SC, PTM_NUM_NBRS_DCUB, PTM_NUM_NBRS_DHEX};

//------------------------------------
//    template structures
//------------------------------------

//these point sets have barycentre {0, 0, 0} and are scaled such that the mean neighbour distance is 1

const double ptm_template_fcc[PTM_NUM_POINTS_FCC][3] = {	{  0.            ,  0.            ,  0.             },
								{  0.            ,  0.707106781187,  0.707106781187 },
								{  0.            , -0.707106781187, -0.707106781187 },
								{  0.            ,  0.707106781187, -0.707106781187 },
								{  0.            , -0.707106781187,  0.707106781187 },
								{  0.707106781187,  0.            ,  0.707106781187 },
								{ -0.707106781187,  0.            , -0.707106781187 },
								{  0.707106781187,  0.            , -0.707106781187 },
								{ -0.707106781187,  0.            ,  0.707106781187 },
								{  0.707106781187,  0.707106781187,  0.             },
								{ -0.707106781187, -0.707106781187,  0.             },
								{  0.707106781187, -0.707106781187,  0.             },
								{ -0.707106781187,  0.707106781187,  0.             }	};

const double ptm_template_hcp[PTM_NUM_POINTS_HCP][3] = {	{  0.            ,  0.            ,  0.             },
								{  0.707106781186,  0.            ,  0.707106781186 },
								{ -0.235702260395, -0.942809041583, -0.235702260395 },
								{  0.707106781186,  0.707106781186,  0.             },
								{ -0.235702260395, -0.235702260395, -0.942809041583 },
								{  0.            ,  0.707106781186,  0.707106781186 },
								{ -0.942809041583, -0.235702260395, -0.235702260395 },
								{ -0.707106781186,  0.707106781186,  0.             },
								{  0.            ,  0.707106781186, -0.707106781186 },
								{  0.707106781186,  0.            , -0.707106781186 },
								{  0.707106781186, -0.707106781186,  0.             },
								{ -0.707106781186,  0.            ,  0.707106781186 },
								{  0.            , -0.707106781186,  0.707106781186 }	};

const double ptm_template_bcc[PTM_NUM_POINTS_BCC][3] = {	{  0.            ,  0.            ,  0.             },
								{ -0.541451884327, -0.541451884327, -0.541451884327 },
								{  0.541451884327,  0.541451884327,  0.541451884327 },
								{  0.541451884327, -0.541451884327, -0.541451884327 },
								{ -0.541451884327,  0.541451884327,  0.541451884327 },
								{ -0.541451884327,  0.541451884327, -0.541451884327 },
								{  0.541451884327, -0.541451884327,  0.541451884327 },
								{ -0.541451884327, -0.541451884327,  0.541451884327 },
								{  0.541451884327,  0.541451884327, -0.541451884327 },
								{  0.            ,  0.            , -1.082903768655 },
								{  0.            ,  0.            ,  1.082903768655 },
								{  0.            , -1.082903768655,  0.             },
								{  0.            ,  1.082903768655,  0.             },
								{ -1.082903768655,  0.            ,  0.             },
								{  1.082903768655,  0.            ,  0.             }	};

const double ptm_template_ico[PTM_NUM_POINTS_ICO][3] = {	{  0.            ,  0.            ,  0.             },
								{  0.            ,  0.525731112119,  0.850650808352 },
								{  0.            , -0.525731112119, -0.850650808352 },
								{  0.            ,  0.525731112119, -0.850650808352 },
								{  0.            , -0.525731112119,  0.850650808352 },
								{ -0.525731112119, -0.850650808352,  0.             },
								{  0.525731112119,  0.850650808352,  0.             },
								{  0.525731112119, -0.850650808352,  0.             },
								{ -0.525731112119,  0.850650808352,  0.             },
								{ -0.850650808352,  0.            , -0.525731112119 },
								{  0.850650808352,  0.            ,  0.525731112119 },
								{  0.850650808352,  0.            , -0.525731112119 },
								{ -0.850650808352,  0.            ,  0.525731112119 }	};

const double ptm_template_sc[PTM_NUM_POINTS_SC][3] = {		{  0.            ,  0.            ,  0.             },
								{  0.            ,  0.            , -1.             },
								{  0.            ,  0.            ,  1.             },
								{  0.            , -1.            ,  0.             },
								{  0.            ,  1.            ,  0.             },
								{ -1.            ,  0.            ,  0.             },
								{  1.            ,  0.            ,  0.             }	};

const double ptm_template_dcub[PTM_NUM_POINTS_DCUB][3] = {	{  0.            ,  0.            ,  0.             },
								{ -0.391491627053,  0.391491627053,  0.391491627053 },
								{ -0.391491627053, -0.391491627053, -0.391491627053 },
								{  0.391491627053, -0.391491627053,  0.391491627053 },
								{  0.391491627053,  0.391491627053, -0.391491627053 },
								{ -0.782983254107,  0.            ,  0.782983254107 },
								{ -0.782983254107,  0.782983254107,  0.             },
								{  0.            ,  0.782983254107,  0.782983254107 },
								{ -0.782983254107, -0.782983254107,  0.             },
								{ -0.782983254107,  0.            , -0.782983254107 },
								{  0.            , -0.782983254107, -0.782983254107 },
								{  0.            , -0.782983254107,  0.782983254107 },
								{  0.782983254107, -0.782983254107,  0.             },
								{  0.782983254107,  0.            ,  0.782983254107 },
								{  0.            ,  0.782983254107, -0.782983254107 },
								{  0.782983254107,  0.            , -0.782983254107 },
								{  0.782983254107,  0.782983254107,  0.             }	};

const double ptm_template_dhex[PTM_NUM_POINTS_DHEX][3] = {	{  0.            ,  0.            ,  0.             },
								{ -0.391491627053, -0.391491627053, -0.391491627053 },
								{  0.391491627053, -0.391491627053,  0.391491627053 },
								{ -0.391491627053,  0.391491627053,  0.391491627053 },
								{  0.391491627053,  0.391491627053, -0.391491627053 },
								{ -0.260994418036, -1.043977672142, -0.260994418036 },
								{ -1.043977672142, -0.260994418036, -0.260994418036 },
								{ -0.260994418036, -0.260994418036, -1.043977672142 },
								{  0.782983254107,  0.            ,  0.782983254107 },
								{  0.782983254107, -0.782983254107,  0.             },
								{  0.            , -0.782983254107,  0.782983254107 },
								{  0.            ,  0.782983254107,  0.782983254107 },
								{ -0.782983254107,  0.782983254107,  0.             },
								{ -0.782983254107,  0.            ,  0.782983254107 },
								{  0.782983254107,  0.782983254107,  0.             },
								{  0.            ,  0.782983254107, -0.782983254107 },
								{  0.782983254107,  0.            , -0.782983254107 }	};
#endif

src/PTM/ptm_functions.h

deleted100644 → 0
+0 −27
Original line number Diff line number Diff line
#ifndef PTM_FUNCTIONS_H
#define PTM_FUNCTIONS_H

#include <stdint.h>
#include <stdbool.h>
#include "ptm_initialize_data.h"
#include "ptm_constants.h"


//------------------------------------
//    function declarations
//------------------------------------
#ifdef __cplusplus
extern "C" {
#endif


int ptm_index(	ptm_local_handle_t local_handle, int32_t flags, int num_points, double (*atomic_positions)[3], int32_t* atomic_numbers, bool topological_ordering,	//inputs
		int32_t* p_type, int32_t* p_alloy_type, double* p_scale, double* p_rmsd, double* q, double* F, double* F_res, double* U, double* P, int8_t* mapping, double* p_interatomic_distance, double* p_lattice_constant);	//outputs


#ifdef __cplusplus
}
#endif

#endif

src/USER-PTM/alloy_types.cpp

deleted100644 → 0
+0 −101
Original line number Diff line number Diff line
#include <algorithm>
#include "ptm_constants.h"
#include "initialize_data.h"


#define NUM_ALLOY_TYPES 3
static uint32_t typedata[NUM_ALLOY_TYPES][3] = {
	{PTM_MATCH_FCC, PTM_ALLOY_L10,    0x000001fe},
	{PTM_MATCH_FCC, PTM_ALLOY_L12_CU, 0x0000001e},
	{PTM_MATCH_FCC, PTM_ALLOY_L12_AU, 0x00001ffe},
};

static bool test_pure(int num_nbrs, int32_t* numbers)
{
	for (int i=1;i<num_nbrs + 1;i++)
		if (numbers[i] != numbers[0])
			return false;
	return true;
}

static bool test_binary(int num_nbrs, int32_t* numbers)
{
	int a = numbers[0], b = -1;
	for (int i=1;i<num_nbrs + 1;i++)
	{
		if (numbers[i] != a)
		{
			if (b == -1)
				b = numbers[i];
			else if (numbers[i] != b)
				return false;
		}
	}

	return true;
}

static bool test_shell_structure(const refdata_t* ref, int8_t* mapping, int32_t* numbers, int num_inner)
{
	int8_t binary[PTM_MAX_POINTS];
	for (int i=0;i<ref->num_nbrs+1;i++)
		binary[i] = numbers[mapping[i]] == numbers[0] ? 0 : 1;

	for (int i=1;i<num_inner + 1;i++)
		if (binary[i] == binary[0])
			return false;

	for (int i=num_inner+1;i<ref->num_nbrs+1;i++)
		if (binary[i] != binary[0])
			return false;

	return true;
}

static int32_t canonical_alloy_representation(const refdata_t* ref, int8_t* mapping, int32_t* numbers)
{
	int8_t binary[PTM_MAX_POINTS];
	for (int i=0;i<ref->num_nbrs+1;i++)
		binary[i] = numbers[mapping[i]] == numbers[0] ? 0 : 1;

	int8_t temp[PTM_MAX_POINTS];
	uint32_t best = 0xFFFFFFFF;
	for (int j=0;j<ref->num_mappings;j++)
	{
		for (int i=0;i<ref->num_nbrs+1;i++)
			temp[ref->mapping[j][i]] = binary[i];

		uint32_t code = 0;
		for (int i=0;i<ref->num_nbrs+1;i++)
			code |= (temp[i] << i);

		best = std::min(best, code);
	}

	return best;
}

int32_t find_alloy_type(const refdata_t* ref, int8_t* mapping, int32_t* numbers)
{
	if (test_pure(ref->num_nbrs, numbers))
		return PTM_ALLOY_PURE;

	if (!test_binary(ref->num_nbrs, numbers))
		return PTM_ALLOY_NONE;

	uint32_t code = canonical_alloy_representation(ref, mapping, numbers);
	for (int i=0;i<NUM_ALLOY_TYPES;i++)
		if ((uint32_t)ref->type == typedata[i][0] && code == typedata[i][2])
			return typedata[i][1];

	if (ref->type == PTM_MATCH_BCC)
		if (test_shell_structure(ref, mapping, numbers, 8))
			return PTM_ALLOY_B2;

	if (ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)
		if (test_shell_structure(ref, mapping, numbers, 4))
			return PTM_ALLOY_SIC;

	return PTM_ALLOY_NONE;
}
Loading