8 #include "casm/external/Eigen/Dense"
9 #include "casm/external/qhull/libqhullcpp/QhullFacetList.h"
10 #include "casm/external/qhull/libqhullcpp/QhullVertexSet.h"
15 template class DataFormatter<std::pair<std::string, std::pair<bool, bool>>>;
30 double _singular_value_tol,
double _bottom_facet_tol)
31 : m_selection(_selection),
32 m_comp_calculator(_comp_calculator.
clone()),
33 m_energy_calculator(_energy_calculator.
clone()) {
52 PCA pca(mat.topRows(Ncomp), _singular_value_tol);
58 orgQhull::PointCoordinates points(reduced_mat.rows(),
"");
61 points.append(reduced_mat.size(), reduced_mat.data());
64 std::string qh_command =
"";
65 m_hull.runQhull(points.comment().c_str(), points.dimension(), points.count(),
66 &*points.coordinates(), qh_command.c_str());
69 if (
m_hull.hasQhullMessage()) {
70 std::cerr <<
"\nQhull message:\n" <<
m_hull.qhullMessage();
71 m_hull.clearQhullMessage();
72 throw std::runtime_error(
"Qhull Error (see message)");
87 auto begin =
m_hull.facetList().begin();
88 auto end =
m_hull.facetList().end();
89 int dim =
m_hull.dimension();
91 Eigen::Map<const Eigen::VectorXd> outnorm((*begin).hyperplane().begin(),
94 for (
auto facet_it = begin; facet_it != end; ++facet_it) {
96 new (&outnorm) Eigen::Map<const Eigen::VectorXd>(
97 (*facet_it).hyperplane().begin(), dim);
98 b = -outnorm(dim - 1);
100 if (b > _bottom_facet_tol) {
110 orgQhull::QhullVertexSet vertices = (*facet_it).first.vertices();
111 for (
auto vertex_it = vertices.begin(); vertex_it != vertices.end();
138 const orgQhull::QhullPoint &point)
const {
140 std::advance(it,
point.id());
146 const orgQhull::QhullVertex &vertex)
const {
158 int dim =
m_hull.dimension();
159 Eigen::Map<const Eigen::VectorXd> reduced_hyperplane(
160 facet.hyperplane().begin(), dim);
163 Eigen::VectorXd::Constant(dim - 1, reduced_hyperplane(dim - 1));
165 return _mu.cwiseQuotient(
expand().leftCols(dim - 1) *
166 reduced_hyperplane.head(dim - 1));
179 hyperplane.head(
mu.size()) =
mu.cwiseInverse();
180 hyperplane(
mu.size()) = 1.0;
181 hyperplane.normalize();
191 Eigen::Map<const Eigen::VectorXd> reduced_vertex_point(it->point().begin(),
194 double offset = reduced_hyperplane.dot(reduced_vertex_point);
196 if (offset > max_offset) {
248 orgQhull::QhullPoint qpoint(_reduced_point.size(), _reduced_point.data());
256 a = -(facet_it->first).distance(qpoint);
257 b = facet_it->second;
266 namespace Hull_impl {
273 typedef std::map<std::string, std::pair<bool, bool>> CheckMap;
275 CheckMap invalid_data;
279 invalid_data[
config.name()] = std::make_pair(
284 if (invalid_data.size()) {
285 std::cerr <<
"Invalid data for hull construction:\n";
289 Formatter(
"configname",
"",
290 [](CheckMap::value_type v) {
return v.first; }),
291 Formatter(
"composition",
"",
292 [](CheckMap::value_type v) {
293 return v.second.first ?
"OK" :
"invalid";
295 Formatter(
"energy",
"", [](CheckMap::value_type v) {
296 return v.second.second ?
"OK" :
"invalid";
299 std::cerr << f(invalid_data.begin(), invalid_data.end()) <<
"\n";
301 std::stringstream ss;
302 ss <<
"Error in Hull(): Invalid composition or energy data. \n"
303 "Make sure you have set composition axes, all selected "
305 "have calculation results, and you have set your chemical reference.";
306 throw std::runtime_error(ss.str());
boost::iterator_range< iterator > selected()
const Eigen::Transpose< const Eigen::MatrixXd > expand() const
Orthogonal transformation matrix from a point in the dimension-reduced comp/energy space to the full ...
const Configuration & configuration(const orgQhull::QhullPoint &point) const
Return the configuration corresponding to any point.
std::set< orgQhull::QhullVertex, CompareVertex > m_bottom_vertices
Eigen::VectorXd reduced_point(const Configuration &config) const
Return a vector corresponding to the coordinate of a given configuration in the reduced composition/e...
std::vector< std::pair< orgQhull::QhullFacet, double > > m_bottom_facets
const Configuration & groundstate(const Eigen::VectorXd &mu) const
Return the 0K ground state corresponding to the input chemical potential.
DB::Selection< Configuration > m_selection
Hull(const DB::Selection< Configuration > &_selection, const CompCalculator &_comp_calculator=ConfigIO::SpeciesFrac(), const EnergyCalculator &_energy_calculator=ConfigIO::formation_energy_per_species(), double _singular_value_tol=1e-14, double _bottom_facet_tol=1e-14)
Constructor for convex hull in composition/energy space.
const Eigen::MatrixXd & reduce() const
Orthogonal transformation matrix from a point in full comp/energy space to dimension-reduced comp/ene...
notstd::cloneable_ptr< EnergyCalculator > m_energy_calculator
Eigen::VectorXd mu(const orgQhull::QhullFacet facet) const
Return the chemical potential corresponding to a facet.
Eigen::VectorXd composition(const Configuration &config) const
Use the CompCalculator to return the composition of a Configuration.
double dist_to_hull(const Configuration &config) const
The distance a Configuration is above the hull along the energy axis.
double energy(const Configuration &config) const
Use the EnergyCalculator to return the energy of a Configuration.
Eigen::VectorXd point(const Configuration &config) const
Return a vector corresponding to the coordinate of a given configuration in full composition/energy s...
notstd::cloneable_ptr< CompCalculator > m_comp_calculator
const orgQhull::Qhull & data() const
const Access the hull object directly
Principle component analysis.
Eigen::MatrixXd reduce() const
Orthogonal transformation matrix from a point in full [input...] space to dimension-reduced [range(in...
ConfigIO::GenericConfigFormatter< jsonParser > config()
void _validate_input(const DB::Selection< Configuration > &selection, const Hull::CompCalculator &comp_calculator, const Hull::EnergyCalculator &energy_calculator)
Print informational message and throw exception if input data is not valid.
T min(const T &A, const T &B)
Eigen::MatrixXd pad(const Eigen::MatrixXd &M, int n)
Construct a matrix consisting of blocks M and Identity(n,n)
INDEX_TYPE Index
For long integer indexing:
T max(const T &A, const T &B)
std::unique_ptr< T > clone(const T &obj)