123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- // describe elements
- #include "stdafx.h"
- #include "Element.h"
- namespace OTSDATA
- {
- #pragma warning(disable: 4835)
- const CString CElement::theElementNameList{ _T("H,He")
- _T(",Li,Be,B,C,N,O,F,Ne")
- _T(",Na,Mg,Al,Si,P,S,Cl,Ar")
- _T(",K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr")
- _T(",Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe")
- _T(",Cs,Ba,La")
- _T(",Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu")
- _T(",Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn")
- _T(",Fr,Ra,Ac")
- _T(",Th,Pa,U,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Lr") };
- std::vector<CString> CElement::m_theElementNameVector;
-
- #pragma warning(default: 4835)
- // CElementChemistry
- // constructor
- CElementChemistry::CElementChemistry()
- {
- // initialization
- Init();
- }
- CElementChemistry::CElementChemistry(CString a_strName, const double a_dPercentage)
- : m_strName(a_strName)
- , m_dPercentage(a_dPercentage)
- {
- }
- // copy constructor
- CElementChemistry::CElementChemistry(const CElementChemistry& a_oSource)
- {
- // can't copy itself
- if (&a_oSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(a_oSource);
- }
- // copy constructor
- CElementChemistry::CElementChemistry(CElementChemistry* a_poSource)
- {
- // input check
- ASSERT(a_poSource);
- if (!a_poSource)
- {
- return;
- }
- // can't copy itself
- if (a_poSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(*a_poSource);
- }
- // =operator
- CElementChemistry& CElementChemistry::operator=(const CElementChemistry& a_oSource)
- {
- // cleanup
- Cleanup();
- // copy the class data over
- Duplicate(a_oSource);
- // return class
- return *this;
- }
- // ==operator
- BOOL CElementChemistry::operator==(const CElementChemistry& a_oSource)
- {
- // return test result
- return m_strName.Compare(a_oSource.m_strName) == 0 &&
- abs(m_dPercentage - a_oSource.m_dPercentage) < MIN_DOUBLE_VALUE;
- }
- // detractor
- CElementChemistry::~CElementChemistry()
- {
- Cleanup();
- }
- // CElementChemistry member functions
- // serialization
-
- /*void CElementChemistry::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)
- {
- xmls::xString xStrName;
- xmls::xDouble xPercentage;
- xmls::Slo slo;
- slo.Register("StrName", &xStrName);
- slo.Register("Percentage", &xPercentage);
- if (isStoring)
- {
- xStrName = m_strName;
- xPercentage = m_dPercentage;
- slo.Serialize(true, classDoc, rootNode);
- }
- else
- {
- slo.Serialize(false, classDoc, rootNode);
- m_strName=xStrName.value().c_str();
- xPercentage = m_dPercentage;
-
- }
- }*/
- // protected
- // cleanup
- void CElementChemistry::Cleanup()
- {
- // nothing needs to be done at the moment
- }
- // initialization
- void CElementChemistry::Init()
- {
- m_strName = _T("");
- m_dPercentage = 0.0;
- }
- // duplication
- void CElementChemistry::Duplicate(const CElementChemistry& a_oSource)
- {
- // initialization
- Init();
- // copy data over
- m_strName = a_oSource.m_strName;
- m_dPercentage = a_oSource.m_dPercentage;
- }
- // CElementArea
-
- // public:
- CElementArea::CElementArea() // constructor
- {
- // initialization
- Init();
- }
- CElementArea::CElementArea(const CElementArea& a_oSource) // copy constructor
- {
- // can't copy itself
- if (&a_oSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(a_oSource);
- }
- CElementArea::CElementArea(CElementArea* a_poSource) // copy constructor
- {
- // input check
- ASSERT(a_poSource);
- if (!a_poSource)
- {
- return;
- }
- // can't copy itself
- if (a_poSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(*a_poSource);
- }
- CElementArea& CElementArea::operator=(const CElementArea& a_oSource) // =operator
- {
- // cleanup
- Cleanup();
- // copy the class data over
- Duplicate(a_oSource);
- // return class
- return *this;
- }
- BOOL CElementArea::operator==(const CElementArea& a_oSource) // ==operator
- {
- // element chemistry list
- if ((int)m_listCElementChemistries.size() == (int)a_oSource.m_listCElementChemistries.size())
- {
- return FALSE;
- }
- for (int i = 0; i< (int)m_listCElementChemistries.size(); i++)
- {
- if (!(m_listCElementChemistries[i] == a_oSource.m_listCElementChemistries[i]))
- {
- return FALSE;
- }
- }
- // return test result
- return abs(m_dArea - a_oSource.m_dArea) < MIN_DOUBLE_VALUE;
-
- }
- CElementArea::~CElementArea() // detractor
- {
- Cleanup();
- }
- // serialization
-
- // element chemistry list
- void CElementArea::SetElementList(CElementChemistriesList a_listElementChemistries)
- {
- for (auto pElementChemisty : a_listElementChemistries)
- {
- CElementChemistryPtr pElementChemistyNew = CElementChemistryPtr(new CElementChemistry(*pElementChemisty.get()));
- m_listCElementChemistries.push_back(pElementChemistyNew);
- }
- }
-
- // protected:
- // cleanup
- void CElementArea::Cleanup()
- {
- m_listCElementChemistries.clear();
- }
- // initialization
- void CElementArea::Init()
- {
- m_listCElementChemistries.clear();
- }
- // duplication
- void CElementArea::Duplicate(const CElementArea& a_oSource)
- {
- // initialization
- Init();
- // copy data over
- m_dArea = a_oSource.m_dArea;
- SetElementList(a_oSource.m_listCElementChemistries);
- }
- // CElement
-
- // constructor
- CElement::CElement()
- {
- // initialization
- Init();
- }
- CElement::CElement(long a_nAtomNum)
- {
- // initialization
- Init();
- // assign class member
- if (a_nAtomNum >= ATOMIC_NUMBER_MIN && a_nAtomNum <= ATOMIC_NUMBER_MAX)
- {
- m_nAtomNum = a_nAtomNum;
- }
- }
- CElement::CElement(CString a_strName)
- {
- // initialization
- Init();
- // try to find matched name
- //InitNamesList();
- for(int i = 0; i < ATOMIC_NUMBER_MAX; ++i)
- {
- if (ELEMENT_NAMES[i].Compare(a_strName) == 0)
- {
- // got it
- m_nAtomNum = i + 1;
- break;
- }
- }
- }
- // copy constructor
- CElement::CElement(const CElement& a_oSource)
- {
- // can't copy itself
- if (&a_oSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(a_oSource);
- }
- // copy constructor
- CElement::CElement(CElement* a_poSource)
- {
- // input check
- ASSERT(a_poSource);
- if (!a_poSource)
- {
- return;
- }
- // can't copy itself
- if (a_poSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(*a_poSource);
- }
- // =operator
- CElement& CElement::operator=(const CElement& a_oSource)
- {
- // cleanup
- Cleanup();
- // copy the class data over
- Duplicate(a_oSource);
- // return class
- return *this;
- }
- // ==operator
- BOOL CElement::operator==(const CElement& a_oSource)
- {
- // return test result
- return m_nAtomNum == a_oSource.m_nAtomNum && abs(m_dPercentage - a_oSource.m_dPercentage) < MIN_DOUBLE_VALUE;
- }
- // destructor
- CElement::~CElement()
- {
- // cleanup
- Cleanup();
- }
- // CElement member functions
- // serialization
-
- // percentage
- void CElement::SetPercentage(double a_dPercentage)
- {
- if (a_dPercentage >= PERCENTAGE_MIN && a_dPercentage <= PERCENTAGE_MAX)
- {
- m_dPercentage = a_dPercentage;
- }
- }
- double CElement::GetMolarPercentage()
- {
- double dMolarPercentage = MIN_DOUBLE_VALUE;
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- double dAtomWeight = GetAtomWeight();
- dMolarPercentage = m_dPercentage / dAtomWeight;
- }
- return dMolarPercentage;
- }
- // name
- CString CElement::GetName()
- {
- CString strName = _T("");
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return strName;
- }
- strName = ELEMENT_NAMES[m_nAtomNum - 1];
- return strName;
- }
- CString CElement::GetName(long a_nAtomNum)
- {
- CString strName = _T("");
- if (a_nAtomNum < 0 || a_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return strName;
- }
- strName = ELEMENT_NAMES[a_nAtomNum - 1];
- return strName;
- }
- long CElement::GetAtomicNum(CString a_strName)
- {
- long nNum = -1;
- for (int i = 0; i < ATOMIC_NUMBER_MAX; i++)
- {
- if (a_strName.CompareNoCase(ELEMENT_NAMES[i]) == 0)
- {
- nNum = (i + 1);
- break;
- }
- }
- return nNum;
- }
- // atomic weight
- double CElement::GetAtomWeight()
- {
- double dAtomWeight = ATOMIC_WEIGHT_INVALID;
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return dAtomWeight;
- }
- dAtomWeight = ELEMENT_ATOMIC_WEIGHT_VALUES[m_nAtomNum - 1];
- return dAtomWeight;
- }
- double CElement::GetAtomWeight(long a_nAtomNum)
- {
- double dAtomWeight = ATOMIC_WEIGHT_INVALID;
- if (a_nAtomNum < 0 || a_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return dAtomWeight;
- }
- dAtomWeight = ELEMENT_ATOMIC_WEIGHT_VALUES[a_nAtomNum - 1];
- return dAtomWeight;
- }
- double CElement::GetAtomWeight(CString a_strName)
- {
- double dAtomWeight = ATOMIC_WEIGHT_INVALID;
- for (int i = 0; i < ATOMIC_NUMBER_MAX; i++)
- {
- if (a_strName.CompareNoCase(ELEMENT_NAMES[i]) == 0)
- {
- dAtomWeight = ELEMENT_ATOMIC_WEIGHT_VALUES[i];
- break;
- }
- }
- return dAtomWeight;
- }
- // energy values
- double CElement::GetEnergyValueK()
- {
- double dEnergyValueK = ENERGY_VALUE_INVALID;
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return dEnergyValueK;
- }
- dEnergyValueK = ELEMENT_ENERGY_VALUES_K[m_nAtomNum - 1];
- return dEnergyValueK;
- }
- double CElement::GetEnergyValueL()
- {
- double dEnergyValueL = ENERGY_VALUE_INVALID;
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return dEnergyValueL;
- }
- dEnergyValueL = ELEMENT_ENERGY_VALUES_L[m_nAtomNum - 1];
- return dEnergyValueL;
- }
-
- double CElement::GetEnergyValueM()
- {
- double dEnergyValueM = ENERGY_VALUE_INVALID;
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return dEnergyValueM;
- }
- dEnergyValueM = ELEMENT_ENERGY_VALUES_M[m_nAtomNum - 1];
- return dEnergyValueM;
- }
- std::vector<double> CElement::GetEnergyValues()
- {
- std::vector<double> vEnergyValues;
- if (m_nAtomNum < 0 || m_nAtomNum >= ATOMIC_NUMBER_MAX)
- {
- return vEnergyValues;
- }
- double dEnergyValue = ELEMENT_ENERGY_VALUES_K[m_nAtomNum - 1];
- vEnergyValues.push_back(dEnergyValue);
- dEnergyValue = ELEMENT_ENERGY_VALUES_L[m_nAtomNum - 1];
- vEnergyValues.push_back(dEnergyValue);
- dEnergyValue = ELEMENT_ENERGY_VALUES_M[m_nAtomNum - 1];
- vEnergyValues.push_back(dEnergyValue);
- return vEnergyValues;
- }
-
- std::vector<CString>& CElement::GetElementNameList()
- {
- if (CElement::m_theElementNameVector.empty())
- {
- int tokenPos = 0;
- auto strToken = theElementNameList.Tokenize(_T(","), tokenPos);
- while (!strToken.IsEmpty())
- {
- CElement::m_theElementNameVector.push_back(strToken);
- strToken = theElementNameList.Tokenize(_T(","), tokenPos);
- }
- }
- return CElement::m_theElementNameVector;
- }
- CElementChemistriesList CElement::ExtractElementChemistrys(CString a_strSource)
- {
- CElementChemistriesList listElementChemistrys;
- std::vector<CString>& vElementNames = GetElementNameList();
- // separate the source strings into strings
- CString strSeperator = _T("\n");
- std::vector<CString> vLineStrings = CElement::SplitString(a_strSource, strSeperator);
- // strings to elements
- const long ELEMENT_STRING_NUMBER = 3;
- const long EXTRA_CHAR_NUMBER = 6;
- long count = 1;
- for (auto& str : vLineStrings)
- {
- str.Trim(_T("\n"));
- if (str.GetLength() <= EXTRA_CHAR_NUMBER)
- {
- continue;
- }
- strSeperator = _T(",");
- std::vector<CString> vStrings = CElement::SplitString(str, strSeperator);
- if (vStrings.size() == ELEMENT_STRING_NUMBER)
- {
- // create an element chemistry data
- CElementChemistryPtr oElementChemistry = CElementChemistryPtr(new CElementChemistry());
- // name (extra char "Quant=")
- CString strTemp = vStrings[0];
- long nNameStringLength = strTemp.GetLength();
- // invalid name string?
- if (nNameStringLength <= EXTRA_CHAR_NUMBER)
- {
- continue;
- }
- // element name
- CString strName = strTemp.Right(nNameStringLength - EXTRA_CHAR_NUMBER);
- // make sure the element name is valid
- auto itr = std::find(vElementNames.begin(), vElementNames.end(), strName);
- if (itr == vElementNames.end())
- {
- // invalid element name
- continue;
- }
- oElementChemistry->SetName(strName);
- // percentage
- double dPercentge = _tstof(vStrings[2]);
- oElementChemistry->SetPercentage(dPercentge);
- listElementChemistrys.push_back(oElementChemistry);
- }
- }
- return listElementChemistrys;
- }
-
- void CElement::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)
- {
- // atomic number
- xmls::xLong xnAtomNum;
- // percentage
- xmls::xDouble xdPercentage;
- xmls::xString xEleName;
- xmls::Slo slo;
- slo.Register("ElementName", &xEleName);
- slo.Register("AtomNum", &xnAtomNum);
- slo.Register("Percentage", &xdPercentage);
- if (isStoring)
- {
- xEleName = this->GetName();
- xnAtomNum = m_nAtomNum;
- xdPercentage = m_dPercentage;
- slo.Serialize(true, classDoc, rootNode);
- }
- else
- {
- slo.Serialize(false, classDoc, rootNode);
- m_nAtomNum = xnAtomNum.value();
- m_dPercentage = xdPercentage.value();
- }
- }
- // cleanup
- void CElement::Cleanup()
- {
- // nothing needs to be done at the moment
- }
- // initialization
- void CElement::Init()
- {
- m_nAtomNum = ATOMIC_NUMBER_INVALID;
- m_dPercentage = PERCENTAGE_DEFAULT;
- }
- // duplication
- void CElement::Duplicate(const CElement& a_oSource)
- {
- // initialization
- Init();
- // copy data over
- m_nAtomNum = a_oSource.m_nAtomNum;
- m_dPercentage = a_oSource.m_dPercentage;
- }
- // const CString& a_sSource
- // LPCTSTR a_sSep -- separator
- std::vector<CString> CElement::SplitString(const CString& a_strSource, LPCTSTR a_strSep)
- {
- // string list
- std::vector<CString> listString;
- // source string
- CString strSource = a_strSource;
- // find the first separator
- int nPosLast = 0;
- auto nPos = strSource.Find(a_strSep, nPosLast);
- // found the separator?
- while (nPos >= nPosLast)
- {
- // there is no string between two seperator if nPos == nPosLast
- if (nPos == nPosLast)
- {
- listString.push_back(_T(""));
- nPosLast++;
- }
- else
- {
- // get the string between two separator
- CString strValue = strSource.Mid(nPosLast, nPos - nPosLast);
- strValue.Trim();
- // add the string into the string list
- listString.push_back(strValue);
- nPosLast = nPos + 1;
- }
- // try to find the next separator
- nPos = strSource.Find(a_strSep, nPosLast);
- }
- // push the last one into the string list
- CString strLastValue = strSource.Right(strSource.GetLength() - nPosLast);
- strLastValue.Trim();
- listString.push_back(strLastValue);
- // return the string list
- return listString;
- }
- double CElementChemistry::GetMolarPercentage()
- {
- // molar percentage
- double dMolarPercentage = 0.0;
- // get atomic weight of the element
- double dAtomWeight = CElement::GetAtomWeight(m_strName);
- // make sure atomic weight is valid
- if (dAtomWeight > 0.0)
- {
- // calculate molar percentage
- dMolarPercentage = m_dPercentage / dAtomWeight;
- }
- return dMolarPercentage;
- }
- void CElementChemistry::SetMolarPercentage(double a_dMolarPer)
- {
- // get atomic weight of the element
- double dAtomWeight = CElement::GetAtomWeight(m_strName);
- // set percentage
- m_dPercentage = a_dMolarPer * dAtomWeight / 100.0;
- }
- }
|