1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
#ifndef UnitCellParameters_H_
#define UnitCellParameters_H_
#include "SimTKmolmodel.h" // Actually this could just need simtkcommon or some such..
#include <array>
#include <vector>
//typedef SimTK::Vec<3,int> iVec3;
typedef std::array<int, 3> iVec3; // This is not really a vector, it is an array. But I think it should work fine for us.
class UnitCellParameters{
private:
enum AbcMins : size_t {
A,
B,
C
};
bool valid;
double a,b,c;
double alpha, beta, gamma;
int na, aMax, nb, bMax, nc, cMax;
SimTK::Mat33 orthogonalizationMatrix;
SimTK::Mat33 deOrthogonalizationMatrix;
std::array<int, 3> abcMins;
public:
void setDefaultParameters();
void setDeOrthogonalizationMatrix ();
SimTK::Mat33 getDeOrthogonalizationMatrix () const ;
//SimTK::Vec3 multiplyMat33TimesVec3 (const SimTK::Mat33 myMat33 , const SimTK::Vec3 myVec3 ) ;
// takes a cartesian vector, returns a vector in fractional coordinates
SimTK::Vec3 convertCartesianVectorToFractionalVector (const SimTK::Vec3 &cartesianVector) const ;
// takes a fractional vector, drops the integer part and returns only the fractional part:
SimTK::Vec3 convertFractionalVectorToFractionFromLowerLeft (const SimTK::Vec3 & fractionalVector) const ;
// Rounds fractional vector to nearest integers
iVec3 convertCartesianVectorToNearestIndexVector (const SimTK::Vec3 & cartesianVector) const;
// Truncates fractional vector components to find integer vector.
iVec3 convertFractionalVectorToLowerIndexVector (const SimTK::Vec3 & fractionalVector) const;
// first calls convertCartesianVectorToFractionalVector, then calls convertFractionalVectorToLowerIndexVector:
iVec3 convertCartesianVectorToLowerIndexVector (const SimTK::Vec3 & cartesianVector) const;
// Checks whether the given fractional vector is inside the unit cell.
bool fractionalVectorIsInsideMapBoundaries(const SimTK::Vec3 & fractionalVector);
// Default constructor. Mainly, just sets valid to false.
UnitCellParameters();
double angleInRange (const double angleInDegrees) ;
// makes sure the n is more unity, and that nMax-nMin+1 = n. Usable on a,b,c dimensions
void validateNnMinnMax(const int n, const int nMin, const int nMax);
// validates inputAngle, dies if out of reasonable range.
int getNa() const {return na;};
int getNb() const {return nb;};
int getNc() const {return nc;};
double geta() const {return a;};
double getb() const {return b;};
double getc() const {return c;};
double getaMin() const {return abcMins[AbcMins::A];};
double getbMin() const {return abcMins[AbcMins::B];};
double getcMin() const {return abcMins[AbcMins::C];};
double getaMax() const {return aMax;};
double getbMax() const {return bMax;};
double getcMax() const {return cMax;};
int calcMaxFrequencyDoublingsX ();
int calcMaxFrequencyDoublingsY ();
int calcMaxFrequencyDoublingsZ ();
double getMinHalfWavelengthX () ;
double getMinHalfWavelengthY () ;
double getMinHalfWavelengthZ () ;
double getMaxHalfWavelengthX () {return (geta()*(getNa()-1));};// The longest half-wavelength is the width of the unit cell.
double getMaxHalfWavelengthY () {return (getb()*(getNb()-1));};// The longest half-wavelength is the width of the unit cell.
double getMaxHalfWavelengthZ () {return (getc()*(getNc()-1));};// The longest half-wavelength is the width of the unit cell.
void setAlphaUsingDegrees(double inputAngle);
double getAlpha();
void setBetaUsingDegrees(double inputAngle);
double getBeta();
void setGammaUsingDegrees(double inputAngle);
void setabc(const double mya, const double myb, const double myc);
double getGamma();
// calls validateNnMinnMax three times for validation, then sets the corresponding unit cell parameters:
void setN (const int myna, const int myaMin,const int myaMax,const int mynb,const int mybMin,const int mybMax,const int mync,const int mycMin,const int mycMax);
// Dies if valid = 0. This can be called liberally whenever we want to use any parameters.
bool exitIfNotValid() const;
// Runs checks on the parameters:
void validate();
// This returns the nonorthogonal basis vector va, in orthogonal (cartesian) coordinates.
// fractionalMagnitude counts number of a's from origin. Can be negative. For now, we allow this to even access points outside the provided density map.
// if fractionalMagnitude argument is unity (default), magnitude of va is a.
// if fractionalMagnitude argument is anything else, magnitude of va is fractionalMagnitude * a
SimTK::Vec3 va (const double fractionalMagnitude = 1);
SimTK::Vec3 vb (const double fractionalMagnitude = 1);
// From http://www.webmineral.com/help/CellDimensions.shtml#.XWjGX5MzYmJ
double totalVolume ();
double volume ();
SimTK::Vec3 vc (const double fractionalMagnitude = 1);
};
#endif
|