source: src/Formula.cpp@ 574ddc1

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 574ddc1 was 6f43ab, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Added a class that allow simple handling of molecules formulas

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 * Formula.cpp
3 *
4 * Created on: Jul 21, 2010
5 * Author: crueger
6 */
7
8#include "Formula.hpp"
9
10#include <sstream>
11
12#include "World.hpp"
13#include "periodentafel.hpp"
14#include "element.hpp"
15#include "Helpers/Assert.hpp"
16
17using namespace std;
18
19Formula::Formula() :
20 numElements(0)
21{}
22
23Formula::Formula(const Formula &src) :
24 elementCounts(src.elementCounts),
25 numElements(src.numElements)
26{}
27
28Formula::~Formula()
29{}
30
31Formula &Formula::operator=(const Formula &rhs){
32 // No self-assignment check needed
33 elementCounts=rhs.elementCounts;
34 numElements=rhs.numElements;
35 return *this;
36}
37
38std::string Formula::toString() const{
39 stringstream sstr;
40 for(const_reverse_iterator iter=rbegin();iter!=rend();++iter){
41 sstr << (*iter).first->symbol << (*iter).second;
42 }
43 return sstr.str();
44}
45
46bool Formula::checkOut(ostream *output) const{
47 bool result = true;
48 int No = 1;
49
50 if (output != NULL) {
51 *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
52 *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
53 for(const_iterator iter=begin(); iter!=end();++iter){
54 (*iter).first->No = No;
55 result = result && (*iter).first->Checkout(output, No++, (*iter).second);
56 }
57 return result;
58 } else
59 return false;
60}
61
62unsigned int Formula::getElementCount(){
63 return numElements;
64}
65
66bool Formula::hasElement(const element *element) const{
67 ASSERT(element,"Invalid pointer in Formula::hasElement(element*)");
68 return hasElement(element->getNumber());
69}
70
71bool Formula::hasElement(atomicNumber_t Z) const{
72 ASSERT(Z>0,"Invalid atomic Number");
73 ASSERT(World::getInstance().getPeriode()->FindElement(Z),"No Element with this number in Periodentafel");
74 return elementCounts.size()>=Z && elementCounts[Z-1];
75}
76
77bool Formula::hasElement(const string &shorthand) const{
78 element * element = World::getInstance().getPeriode()->FindElement(shorthand);
79 return hasElement(element);
80}
81
82void Formula::operator+=(const element *element){
83 ASSERT(element,"Invalid pointer in increment of Formula");
84 operator+=(element->getNumber());
85}
86
87void Formula::operator+=(atomicNumber_t Z){
88 ASSERT(Z>0,"Invalid atomic Number");
89 ASSERT(World::getInstance().getPeriode()->FindElement(Z),"No Element with this number in Periodentafel");
90 elementCounts.resize(Z); // No-op when we already have the right size
91 // might need to update number of elements
92 if(!elementCounts[Z-1]){
93 numElements++;
94 }
95 elementCounts[Z-1]++; // atomic numbers start at 1
96}
97
98void Formula::operator+=(const string &shorthand){
99 element * element = World::getInstance().getPeriode()->FindElement(shorthand);
100 operator+=(element);
101}
102
103void Formula::operator-=(const element *element){
104 ASSERT(element,"Invalid pointer in decrement of Formula");
105 operator-=(element->getNumber());
106}
107
108void Formula::operator-=(atomicNumber_t Z){
109 ASSERT(Z>0,"Invalid atomic Number");
110 ASSERT(World::getInstance().getPeriode()->FindElement(Z),"No Element with this number in Periodentafel");
111 ASSERT(elementCounts.size()>=Z && elementCounts[Z-1], "Element not in Formula upon decrement");
112 elementCounts[Z-1]--; // atomic numbers start at 1
113 // might need to update number of elements
114 if(!elementCounts[Z-1]){
115 numElements--;
116 }
117}
118
119void Formula::operator-=(const string &shorthand){
120 element * element = World::getInstance().getPeriode()->FindElement(shorthand);
121 operator-=(element);
122}
123
124const unsigned int &Formula::operator[](const element *element) const{
125 ASSERT(element,"Invalid pointer in access of Formula");
126 return operator[](element->getNumber());
127}
128
129const unsigned int &Formula::operator[](atomicNumber_t Z) const{
130 ASSERT(Z>0,"Invalid atomic Number");
131 ASSERT(World::getInstance().getPeriode()->FindElement(Z),"No Element with this number in Periodentafel");
132 elementCounts.resize(Z); // No-op when we already have the right size
133 return elementCounts[Z-1]; // atomic numbers start at 1
134}
135
136const unsigned int &Formula::operator[](string shorthand) const{
137 element * element = World::getInstance().getPeriode()->FindElement(shorthand);
138 return operator[](element);
139}
140
141bool Formula::operator==(const Formula &rhs) const{
142 // quick check... number of elements used
143 if(numElements != rhs.numElements){
144 return false;
145 }
146 // slow check: all elements
147 // direct access to internal structure means all element-counts have to be compared
148 // this avoids access to periodentafel to find elements though and is probably faster
149 // in total
150 return equal(elementCounts.begin(),
151 elementCounts.end(),
152 rhs.elementCounts.begin());
153}
154
155bool Formula::operator!=(const Formula &rhs) const{
156 return !operator==(rhs);
157}
158
159Formula::iterator Formula::begin(){
160 return iterator(elementCounts,0);
161}
162Formula::const_iterator Formula::begin() const{
163 return const_iterator(elementCounts,0);
164}
165Formula::iterator Formula::end(){
166 return iterator(elementCounts);
167}
168Formula::const_iterator Formula::end() const{
169 return const_iterator(elementCounts);
170}
171
172Formula::reverse_iterator Formula::rbegin(){
173 return reverse_iterator(end());
174}
175Formula::const_reverse_iterator Formula::rbegin() const{
176 return const_reverse_iterator(end());
177}
178Formula::reverse_iterator Formula::rend(){
179 return reverse_iterator(begin());
180}
181Formula::const_reverse_iterator Formula::rend() const{
182 return const_reverse_iterator(begin());
183}
184
185/**************** Iterator structure ********************/
186
187template <class result_type>
188Formula::_iterator<result_type>::_iterator(set_t &_set) :
189 set(&_set)
190{
191 pos=set->size();
192}
193
194template <class result_type>
195Formula::_iterator<result_type>::_iterator(set_t &_set,size_t _pos) :
196 set(&_set),pos(_pos)
197{
198 ASSERT(pos<=set->size(),"invalid position in iterator construction");
199 while(pos<set->size() && (*set)[pos]!=0) ++pos;
200}
201
202template <class result_type>
203Formula::_iterator<result_type>::~_iterator(){}
204
205template <class result_type>
206Formula::_iterator<result_type>&
207Formula::_iterator<result_type>::operator=(const _iterator<result_type> &rhs){
208 set=rhs.set;
209 pos=rhs.pos;
210 return *this;
211}
212
213template <class result_type>
214bool
215Formula::_iterator<result_type>::operator==(const _iterator<result_type> &rhs){
216 return set==rhs.set && pos==rhs.pos;
217}
218
219template <class result_type>
220bool
221Formula::_iterator<result_type>::operator!=(const _iterator<result_type> &rhs){
222 return !operator==(rhs);
223}
224
225template <class result_type>
226Formula::_iterator<result_type>
227Formula::_iterator<result_type>::operator++(){
228 ASSERT(pos!=set->size(),"Incrementing Formula::iterator beyond end");
229 while(pos<set->size() && (*set)[pos]!=0) ++pos;
230 return *this;
231}
232
233template <class result_type>
234Formula::_iterator<result_type>
235Formula::_iterator<result_type>::operator--(){
236 ASSERT(pos!=0,"Decrementing Formula::iterator beyobd begin");
237 while(pos>0 && (*set)[pos]!=0) ++pos;
238 return *this;
239}
240
241template <class result_type>
242result_type
243Formula::_iterator<result_type>::operator*(){
244 element *element = World::getInstance().getPeriode()->FindElement(pos+1);
245 ASSERT(element,"Element with position of iterator not found");
246 return make_pair(element,(*set)[pos]);
247}
248
249template <class result_type>
250result_type*
251Formula::_iterator<result_type>::operator->(){
252 // no one can keep this value around, so a static is ok to avoid temporaries
253 static value_type value=make_pair(reinterpret_cast<element*>(0),0); // no default constructor for std::pair
254 element *element = World::getInstance().getPeriode()->FindElement(pos+1);
255 ASSERT(element,"Element with position of iterator not found");
256 value = make_pair(element,(*set)[pos]);
257 return &value;
258}
259
260/********************** I/O of Formulas ************************************************/
261
262std::ostream &operator<<(std::ostream &ost,const Formula &formula){
263 ost << formula.toString();
264 return ost;
265}
Note: See TracBrowser for help on using the repository browser.