1 #include "atom.h" 2 3 using namespace Vipster; 4 atomFmtRelative(AtomFmt f)5bool Vipster::atomFmtRelative(AtomFmt f) 6 { 7 return f<=AtomFmt::Alat; 8 } 9 atomFmtAbsolute(AtomFmt f)10bool Vipster::atomFmtAbsolute(AtomFmt f) 11 { 12 return !atomFmtRelative(f); 13 } 14 operator ==(const AtomProperties & p1,const AtomProperties & p2)15bool Vipster::operator==(const AtomProperties &p1, const AtomProperties &p2) 16 { 17 return std::tie(p1.charge, p1.flags, p1.forces) 18 == 19 std::tie(p2.charge, p2.flags, p2.forces); 20 } 21 makeConverter(const AtomContext & source,const AtomContext & target)22detail::CoordConverter Vipster::detail::makeConverter(const AtomContext &source, 23 const AtomContext &target) 24 { 25 switch(source.fmt){ 26 case AtomFmt::Crystal: 27 switch(target.fmt){ 28 case AtomFmt::Crystal: 29 if(source.cell == target.cell){ 30 return [](const Vec &v){return v;}; 31 }else{ 32 return [&](const Vec &v){return v * (source.cell->matrix * source.cell->dimension) 33 * (target.cell->inverse / target.cell->dimension);}; 34 } 35 case AtomFmt::Alat: 36 return [&](const Vec &v){return v * (source.cell->matrix * source.cell->dimension) 37 / target.cell->dimension;}; 38 default: 39 return [&](const Vec &v){return v * (source.cell->matrix * source.cell->dimension) 40 * detail::AtomContext::fromAngstrom[target.fmt];}; 41 } 42 case AtomFmt::Alat: 43 switch(target.fmt){ 44 case AtomFmt::Crystal: 45 if(source.cell->dimension == target.cell->dimension){ 46 return [&](const Vec &v){return v * target.cell->inverse;}; 47 }else{ 48 return [&](const Vec &v){return v * source.cell->dimension 49 * (target.cell->inverse / target.cell->dimension);}; 50 } 51 case AtomFmt::Alat: 52 if(source.cell->dimension == target.cell->dimension){ 53 return [](const Vec &v){return v;}; 54 }else{ 55 return [&](const Vec &v){return v * source.cell->dimension / target.cell->dimension;}; 56 } 57 default: 58 return [&](const Vec &v){return v * source.cell->dimension 59 * detail::AtomContext::fromAngstrom[target.fmt];}; 60 } 61 default: // absolute coordinates 62 switch(target.fmt){ 63 case AtomFmt::Crystal: 64 return [&](const Vec &v){return v * detail::AtomContext::toAngstrom[source.fmt] 65 * (target.cell->inverse / target.cell->dimension);}; 66 case AtomFmt::Alat: 67 return [&](const Vec &v){return v * detail::AtomContext::toAngstrom[source.fmt] 68 / target.cell->dimension;}; 69 default: 70 if(source.fmt == target.fmt){ 71 return [](const Vec &v){return v;}; 72 }else{ 73 return [&](const Vec &v){return v * detail::AtomContext::toAngstrom[source.fmt] 74 * detail::AtomContext::fromAngstrom[target.fmt];}; 75 } 76 } 77 } 78 } 79