Esempio n. 1
0
static int l_uc_C(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;

	lua_pushvector(L, new Vector(uc->C()));
	return 1;
}
Esempio n. 2
0
void Crystal::generate_reflections(double min_d)
{
    bp.clear();
    UnitCell reciprocal = uc->get_reciprocal();

    // set upper limit for iteration of Miller indices
    // TODO: smarter algorithm, like in uctbx::unit_cell::max_miller_indices()
    int max_h = 20;
    int max_k = 20;
    int max_l = 20;
    if (fabs(uc->alpha - M_PI/2) < 1e-9 && fabs(uc->beta - M_PI/2) < 1e-9 &&
                                          fabs(uc->gamma - M_PI/2) < 1e-9) {
        max_h = (int) (uc->a / min_d);
        max_k = (int) (uc->b / min_d);
        max_l = (int) (uc->c / min_d);
    }
    // Don't generate too many reflections (it could happen
    // when user chooses Q instead of 2T, or puts wrong wavelength)
    if (max_h * max_k * max_l > 8000)
        max_h = max_k = max_l = 20;

    for (int h = 0; h != max_h+1; h = inc_neg(h))
        for (int k = 0; k != max_k+1; k = inc_neg(k))
            for (int l = (h==0 && k==0 ? 1 : 0); l != max_l+1; l = inc_neg(l)) {
                double d = 1 / reciprocal.calculate_distance(h, k, l);
                //double d = uc->calculate_d(h, k, l); // the same
                if (d < min_d)
                    continue;

                // check for systematic absence
                if (is_sys_absent(sg_ops, h, k, l))
                    continue;

                Miller hkl = { h, k, l };
                bool found = false;
                for (vector<PlanesWithSameD>::iterator i = bp.begin();
                        i != bp.end(); ++i) {
                    if (fabs(d - i->d) < 1e-9) {
                        i->add(hkl, sg_ops);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    PlanesWithSameD new_p;
                    new_p.planes.push_back(Plane(hkl));
                    new_p.d = d;
                    new_p.lpf = 0.;
                    new_p.intensity = 0.;
                    new_p.enabled = true;
                    bp.push_back(new_p);
                }
            }
    sort(bp.begin(), bp.end());
    old_min_d = min_d;
}
Esempio n. 3
0
/// Returns the lowest and highest d-Value in the list. Uses UnitCell and HKL
/// for calculation to prevent problems with potentially inconsistent d-Values
/// in Peak.
std::pair<double, double> SortHKL::getDLimits(const std::vector<Peak> &peaks,
                                              const UnitCell &cell) const {
  auto dLimitIterators = std::minmax_element(
      peaks.begin(), peaks.end(), [cell](const Peak &lhs, const Peak &rhs) {
        return cell.d(lhs.getHKL()) < cell.d(rhs.getHKL());
      });

  return std::make_pair(cell.d((*dLimitIterators.first).getHKL()),
                        cell.d((*dLimitIterators.second).getHKL()));
}
Esempio n. 4
0
static int l_uc_addatomreduced(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;
	
	Atom* a = lua_toatom(L, 2);
	if(!a) return 0;
	
	uc->addAtomReducedCoorinates(a);
	return 0;
}
Esempio n. 5
0
// Adjust matrix of current model
void CellAnglesPopup::adjustCurrentMatrix(int angleIndex, double value)
{
	// Get current model and set new angle in cell
	Model* model = parent_.aten().currentModelOrFrame();
	if (model)
	{
		UnitCell cell = model->cell();
		cell.setAngle(angleIndex, value);
		CommandNode::run(Commands::CellAxes, "ddddddddd", cell.parameter(UnitCell::CellAX), cell.parameter(UnitCell::CellAY), cell.parameter(UnitCell::CellAZ), cell.parameter(UnitCell::CellBX), cell.parameter(UnitCell::CellBY), cell.parameter(UnitCell::CellBZ),  cell.parameter(UnitCell::CellCX), cell.parameter(UnitCell::CellCY), cell.parameter(UnitCell::CellCZ)); 
	}
}
Esempio n. 6
0
static int l_uc_translate(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;
	
	int x = lua_tointeger(L, 2);
	int y = lua_tointeger(L, 3);
	int z = lua_tointeger(L, 4);

	uc->translate(x, y, z);
	return 0;
}
Esempio n. 7
0
static int l_uc_g2r(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;
	
	Vector v;
	lua_makevector(L, 2, v);

	Vector b = uc->globalToReduced(v);
	lua_pushvector(L, new Vector(b));
	return 1;
}
Esempio n. 8
0
static int l_uc_applyoperator(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;

	if(lua_isfunction(L, 2))
	{
		uc->applyOperator(L, 2);
		return 0;
	}
	if(lua_isstring(L, 2))
	{
		if(!uc->applyOperator(lua_tostring(L, 2)))
			return luaL_error(L, "Failed to apply `%s'\n", lua_tostring(L, 2));
	}
	return 0;
}
Esempio n. 9
0
void general_ewald_sum(UnitCell &uc, const Vector3d &a1, const Vector3d &a2, const Vector3d &a3, const Vector3i &Rcutoff)
{
    int N = uc.size();
    const double sigma = M_PI;

    // renormalize electron occupation
    double unrenorm_Ne = 0, Ne = 0;
    for (UnitCell::iterator it = uc.begin(); it < uc.end(); ++it) {
        unrenorm_Ne += it->ne;
        Ne += it->C;
    }
    for (UnitCell::iterator it = uc.begin(); it < uc.end(); ++it) 
        it->ne *= Ne/unrenorm_Ne;

    // get reciprocal vectors
    Vector3d b1, b2, b3;
    double uc_vol = a1.dot(a2.cross(a3));
    b1 = 2*M_PI*a2.cross(a3)/uc_vol;
    b2 = 2*M_PI*a3.cross(a1)/uc_vol;
    b3 = 2*M_PI*a1.cross(a2)/uc_vol;
    
    // Ewald sum
    double Vs, Vl;
    Vector3d k;
    for (int id = 0; id < N; ++id) {
        Vs = 0; Vl = 0;
        for (int m = -Rcutoff[0]; m < Rcutoff[0]; ++m)
            for (int n = -Rcutoff[1]; n < Rcutoff[1]; ++n)
                for (int l = -Rcutoff[2]; l < Rcutoff[2]; ++l) {
                    k = n*b1 + m*b2 + l*b3;
                    double ksquare = k.dot(k);
                    for (int i = 0; i < N; ++i) {
                        double dR = (uc[id].r - (uc[i].r + m*a1 + n*a2 + l*a3)).norm();
                        // for long-range terms
                        if ( !(m == 0 && n == 0 && l == 0) )
                            Vl += 4*M_PI/uc_vol*(uc[i].C-uc[i].ne)/ksquare * cos(k.dot(uc[id].r-uc[i].r)) * exp(-pow(sigma,2)*ksquare/2.);
                        
                        // for short-range terms
                        if ( !(m == 0 && n == 0 && l == 0 && i == id) )
                            Vs += (uc[i].C - uc[i].ne) / dR * erfc(dR/sqrt(2)/sigma);
                    }
                }
        uc[id].V = Vs + Vl - (uc[id].C - uc[id].ne)*sqrt(2/M_PI)/sigma;
    }
}
Esempio n. 10
0
static int l_uc_al2bv(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;
	
	double v[6];
	for(int i=0; i<6; i++)
	{
		v[i] = lua_tonumber(L, i+2);
		if(v[i] == 0)
			return luaL_error(L, "UnitCell:anglesLengthsToBasisVectors requires 6 numbers");
	}
	
	uc->anglesLengthsToBasisVectors(
		v[0], v[1], v[2],
		v[3], v[4], v[5]);
	return 0;
}
Esempio n. 11
0
void PawleyFunction::setPeakPositions(std::string centreName, double zeroShift,
                                      const UnitCell &cell) const {
  for (size_t i = 0; i < m_hkls.size(); ++i) {
    double centre = getTransformedCenter(cell.d(m_hkls[i]));

    m_peakProfileComposite->getFunction(i)
        ->setParameter(centreName, centre + zeroShift);
  }
}
Esempio n. 12
0
void Crystal::toggleUnitCell()
{
  if (m_molecule->unitCell()) {
    m_molecule->setUnitCell(NULL);
    m_molecule->emitChanged(Molecule::UnitCell | Molecule::Removed);
  }
  else {
    UnitCell *cell = new UnitCell;
    cell->setCellParameters(static_cast<Real>(3.0),
                            static_cast<Real>(3.0),
                            static_cast<Real>(3.0),
                            static_cast<Real>(90.0) * DEG_TO_RAD,
                            static_cast<Real>(90.0) * DEG_TO_RAD,
                            static_cast<Real>(90.0) * DEG_TO_RAD);
    m_molecule->setUnitCell(cell);
    m_molecule->emitChanged(Molecule::UnitCell | Molecule::Added);
    editUnitCell();
  }
}
Esempio n. 13
0
static int l_uc_copy(lua_State* L)
{
	UnitCell* uc = lua_tounitcell(L, 1);
	if(!uc) return 0;
	
	UnitCell* uc2 = new UnitCell();//uc->A(), uc->B(), uc->C());
	
	uc2->r2g = uc->r2g;
	uc2->g2r = uc->g2r;
	
	uc2->setA(uc->A());
	uc2->setB(uc->B());
	uc2->setC(uc->C());
	
	for(unsigned int i=0; i<uc->atoms.size(); i++)
	{
		uc2->addAtomGlobalCoorinates(new Atom(*uc->atoms[i]));
	}
	lua_pushunitcell(L, uc2);
	return 1;
}
Esempio n. 14
0
// Wrap a vector in an Orthorombic UnitCell
static Vector3D wrap_orthorombic(const UnitCell& cell, const Vector3D& vect) {
    Vector3D res;
    res[0] = static_cast<float>(vect[0] - round(vect[0]/cell.a())*cell.a());
    res[1] = static_cast<float>(vect[1] - round(vect[1]/cell.b())*cell.b());
    res[2] = static_cast<float>(vect[2] - round(vect[2]/cell.c())*cell.c());
    return res;
}
Esempio n. 15
0
// Wrap a vector in an Orthorombic UnitCell
static Vector3D wrap_triclinic(const UnitCell& cell, const Vector3D& vect) {
    Vector3D res = vect;

    auto mat = cell.matricial();
    for (size_t i=2 ; i != static_cast<size_t>(-1) ; i--) {
        while (fabs(res[i]) > mat[i][i]/2) {
            if (res[i] < 0) {
                res[0] += static_cast<float>(mat[i][0]);
                res[1] += static_cast<float>(mat[i][1]);
                res[2] += static_cast<float>(mat[i][2]);
            } else {
                res[0] -= static_cast<float>(mat[i][0]);
                res[1] -= static_cast<float>(mat[i][1]);
                res[2] -= static_cast<float>(mat[i][2]);
            }
        }
    }
    return res;
}
Esempio n. 16
0
TEST(UnitCellTest, cellParameters)
{
  Real a = static_cast<Real>(2.0);
  Real b = static_cast<Real>(3.0);
  Real c = static_cast<Real>(4.0);
  Real alpha = static_cast<Real>(70 * DEG_TO_RAD);
  Real beta = static_cast<Real>(120 * DEG_TO_RAD);
  Real gamma = static_cast<Real>(85 * DEG_TO_RAD);

  UnitCell unitCell;
  unitCell.setCellParameters(a, b, c, alpha, beta, gamma);
  EXPECT_FLOAT_EQ(static_cast<float>(a), static_cast<float>(unitCell.a()));
  EXPECT_FLOAT_EQ(static_cast<float>(b), static_cast<float>(unitCell.b()));
  EXPECT_FLOAT_EQ(static_cast<float>(c), static_cast<float>(unitCell.c()));
  EXPECT_FLOAT_EQ(static_cast<float>(alpha),
                  static_cast<float>(unitCell.alpha()));
  EXPECT_FLOAT_EQ(static_cast<float>(beta),
                  static_cast<float>(unitCell.beta()));
  EXPECT_FLOAT_EQ(static_cast<float>(gamma),
                  static_cast<float>(unitCell.gamma()));
}
Esempio n. 17
0
int main()
{
  UnitCell cell;
  
  cout << " orthorhombic cell: " << endl;
  cell.set(D3vector(4.,0.,0.),D3vector(0.,5.,0.),D3vector(0.,0.,7.));
  cout << cell << endl;
  
  D3vector v;
  
  const int n = 100000;
  const double d = 10.0;
  int count;
  
  count = 0;
  for ( int i = 0; i < n; i++ )
  {
    // generate a random vector in a box of size d x d x d
    double x0 = drand48() - 0.5;
    double x1 = drand48() - 0.5;
    double x2 = drand48() - 0.5;
    v = d * D3vector(x0,x1,x2);
    
    if ( cell.in_ws(v) )
      count++;
    cell.fold_in_ws(v);
    if ( !cell.in_ws(v) )
      cout << v << endl;
  }
  cout << " volume ratio: " << cell.volume() / (d*d*d)
       << "  computed: " << count/((double) n) << endl << endl;;
  
  cout << " FCC cell: " << endl;
  cell.set(D3vector(4,4,0),D3vector(0,4,4),D3vector(4,0,4));  
  cout << cell << endl;
  
  count = 0;
  for ( int i = 0; i < n; i++ )
  {
    // generate a random vector in a box of size d x d x d
    double x0 = drand48() - 0.5;
    double x1 = drand48() - 0.5;
    double x2 = drand48() - 0.5;
    v = d * D3vector(x0,x1,x2);
    
    if ( cell.in_ws(v) )
      count++;
    cell.fold_in_ws(v);
    if ( !cell.in_ws(v) )
      cout << v << endl;
  }
  cout << " volume ratio: " << cell.volume() / (d*d*d)
       << "  computed: " << count/((double) n) << endl << endl;;
  
  cout << " BCC cell: " << endl;
  cell.set(D3vector(4,4,-4),D3vector(-4, 4,4),D3vector(4,-4,4));  
  cout << cell << endl;
  
  count = 0;
  for ( int i = 0; i < n; i++ )
  {
    // generate a random vector in a box of size d x d x d
    double x0 = drand48() - 0.5;
    double x1 = drand48() - 0.5;
    double x2 = drand48() - 0.5;
    v = d * D3vector(x0,x1,x2);
    
    if ( cell.in_ws(v) )
      count++;
    cell.fold_in_ws(v);
    if ( !cell.in_ws(v) )
      cout << v << endl;
  }
  cout << " volume ratio: " << cell.volume() / (d*d*d)
       << "  computed: " << count/((double) n) << endl << endl;;
  
  cout << " Monoclinic cell: " << endl;
  cell.set(D3vector(4,0,0.1),D3vector(0.2, 4,0),D3vector(0.1,0.3,4));  
  cout << cell << endl;
  
  // Check matrix multiplication function
  double ztest[9];
  cell.matmult3x3(cell.amat(),cell.amat_inv(),ztest);
  for ( int i = 0; i < 9; i++ )
    cout << " ztest[" << i << "]=" << ztest[i] << endl;
  
  count = 0;
  for ( int i = 0; i < n; i++ )
  {
    // generate a random vector in a box of size d x d x d
    double x0 = drand48() - 0.5;
    double x1 = drand48() - 0.5;
    double x2 = drand48() - 0.5;
    v = d * D3vector(x0,x1,x2);
    
    if ( cell.in_ws(v) )
      count++;
    cell.fold_in_ws(v);
    if ( !cell.in_ws(v) )
      cout << v << endl;
  }
  cout << " volume ratio: " << cell.volume() / (d*d*d)
       << "  computed: " << count/((double) n) << endl << endl;
       
  // test UnitCell::included_in function
  UnitCell rcell;
  rcell.set(D3vector(4,4,0),D3vector(0,4,4),D3vector(4,0,4));  
  cell.set(D3vector(4,5,0),D3vector(0,4,4),D3vector(4,0,4));
  cout << " rcell: " << rcell << endl;
  cout << " cell: " << cell << endl;
  cout << " cell is";
  if ( !rcell.encloses(cell) ) cout << " not";
  cout << " included in rcell" << endl;
  
  rcell.set(D3vector(4,4,0),D3vector(0,4,4),D3vector(4,0,4));  
  cout << " rcell: " << rcell << endl;
  cell.set(D3vector(3.8,3.8,0),D3vector(0,3.8,3.8),D3vector(3.8,0,3.8));
  cout << " cell: " << cell << endl;
  cout << " cell is";
  if ( !rcell.encloses(cell) ) cout << " not";
  cout << " included in rcell" << endl; 
}
/** Returns a new UnitCell-object with crystal system constraints taken into
 *account
 *
 *  This method constructs a new UnitCell-object based on the values of the
 *supplied cell,
 *  but takes into account the constraints of the crystal system. For
 *monoclinic, a unique b-axis is assumed.
 *
 *  It's useful for "cleaning" user input.
 *
 * @param unitCell :: UnitCell-object which should be constrained
 * @param crystalSystem :: Crystal system which is used for constraints
 * @return UnitCell-object with applied constraints
 */
UnitCell PoldiCreatePeaksFromCell::getConstrainedUnitCell(
    const UnitCell &unitCell,
    const PointGroup::CrystalSystem &crystalSystem) const {
  switch (crystalSystem) {
  case PointGroup::Cubic:
    return UnitCell(unitCell.a(), unitCell.a(), unitCell.a());
  case PointGroup::Tetragonal:
    return UnitCell(unitCell.a(), unitCell.a(), unitCell.c());
  case PointGroup::Orthorhombic:
    return UnitCell(unitCell.a(), unitCell.b(), unitCell.c());
  case PointGroup::Monoclinic:
    return UnitCell(unitCell.a(), unitCell.b(), unitCell.c(), 90.0,
                    unitCell.beta(), 90.0);
  case PointGroup::Hexagonal:
    return UnitCell(unitCell.a(), unitCell.a(), unitCell.c(), 90.0, 90.0,
                    120.0);
  case PointGroup::Trigonal:
    return UnitCell(unitCell.a(), unitCell.a(), unitCell.a(), unitCell.alpha(),
                    unitCell.alpha(), unitCell.alpha());
  default:
    return UnitCell(unitCell);
  }
}
/// Returns the largest possible lattice spacing for the given cell.
double
PoldiCreatePeaksFromCell::getLargestDValue(const UnitCell &unitCell) const {
  return std::max(std::max(unitCell.a(), unitCell.b()), unitCell.c());
}
Esempio n. 20
0
/// Convenience function for checking compatibility of a cell metric with the
/// space group, see Group::isInvariant.
bool SpaceGroup::isAllowedUnitCell(const UnitCell &cell) const {
  return isInvariant(cell.getG());
}