source: src/atom.cpp@ 943d02

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 943d02 was 943d02, checked in by Frederik Heber <heber@…>, 17 years ago

molecuilder reads and stored ion velocities

Class atom has new variables velocity vector v and integer FixedIon. These are parse during config:load(), and stored via atom:Output() (but only if norm of v is above MYEPSILON), values are copied to son atoms/nodes in AddCopyAtom and AddHydrogenAtom (there: no fancy splitting of the vector as done with the InBondVector)

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/** \file atom.cpp
2 *
3 * Function implementations for the class atom.
4 *
5 */
6
7#include "molecules.hpp"
8
9/************************************* Functions for class atom *************************************/
10
11/** Constructor of class atom.
12 */
13atom::atom()
14{
15 Name = NULL;
16 previous = NULL;
17 next = NULL;
18 father = this; // generally, father is itself
19 Ancestor = NULL;
20 type = NULL;
21 sort = NULL;
22 FixedIon = 0;
23 nr = -1;
24 GraphNr = -1;
25 ComponentNr = NULL;
26 SeparationVertex = false;
27 LowpointNr = -1;
28};
29
30/** Destructor of class atom.
31 */
32atom::~atom()
33{
34 Free((void **)&Name, "atom::~atom: *Name");
35 Free((void **)&ComponentNr, "atom::~atom: *ComponentNr");
36};
37
38
39/** Climbs up the father list until NULL, last is returned.
40 * \return true father, i.e. whose father points to itself, NULL if it could not be found or has none (added hydrogen)
41 */
42atom *atom::GetTrueFather()
43{
44 atom *walker = this;
45 do {
46 if (walker == walker->father) // top most father is the one that points on itself
47 break;
48 walker = walker->father;
49 } while (walker != NULL);
50 return walker;
51};
52
53/** Output of a single atom.
54 * \param ElementNo cardinal number of the element
55 * \param AtomNo cardinal number among these atoms of the same element
56 * \param *out stream to output to
57 */
58bool atom::Output(int ElementNo, int AtomNo, ofstream *out) const
59{
60 if (out != NULL) {
61 *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t" << fixed << setprecision(9) << showpoint;
62 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
63 *out << "\t" << FixedIon;
64 if (v.Norm() > MYEPSILON)
65 *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
66 *out << " # Number in molecule " << nr << endl;
67 return true;
68 } else
69 return false;
70};
71
72/** Output of a single atom as one lin in xyz file.
73 * \param *out stream to output to
74 */
75bool atom::OutputXYZLine(ofstream *out) const
76{
77 if (out != NULL) {
78 *out << type->symbol << "\t" << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2] << "\t" << endl;
79 return true;
80 } else
81 return false;
82};
83
84ostream & operator << (ostream &ost, atom &a)
85{
86 ost << "[" << a.Name << "|" << &a << "]";
87 return ost;
88};
89
90/** Compares the indices of \a this atom with a given \a ptr.
91 * \param ptr atom to compare index against
92 * \return true - this one's is smaller, false - not
93 */
94bool atom::Compare(atom &ptr)
95{
96 if (nr < ptr.nr)
97 return true;
98 else
99 return false;
100};
101
102bool operator < (atom &a, atom &b)
103{
104 return a.Compare(b);
105};
106
107/******************************** Functions for class AtomStackClass ********************************/
108
109/** Constructor of class AtomStackClass.
110 */
111AtomStackClass::AtomStackClass(int dimension)
112{
113 CurrentLastEntry = 0;
114 CurrentFirstEntry = 0;
115 NextFreeField = 0;
116 EntryCount = dimension;
117 StackList = (atom **) Malloc(sizeof(atom *)*EntryCount, "AtomStackClass::AtomStackClass: **StackList");
118};
119
120/** Destructor of class AtomStackClass.
121 */
122AtomStackClass::~AtomStackClass()
123{
124 Free((void **)&StackList, "AtomStackClass::AtomStackClass: **StackList");
125};
126
127/** Pushes an object onto the stack.
128 * \param *object atom to be pushed on stack
129 * \return true - sucess, false - failure, meaning stack field was occupied
130 */
131bool AtomStackClass::Push(atom *object)
132{
133 if (!IsFull()) { // check whether free field is really not occupied
134 StackList[NextFreeField] = object;
135 CurrentLastEntry = NextFreeField;
136 NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
137 return true;
138 } else {
139 cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
140 return false;
141 }
142};
143
144/** Pops first/oldest atom from stack.
145 * First in, last out.
146 * \return atom pointer from stack, NULL - if failure (no atom pointer in field)
147 */
148atom *AtomStackClass::PopFirst()
149{
150 atom *Walker = NULL;
151 if (!IsEmpty()) {
152 Walker = StackList[CurrentFirstEntry];
153 if (Walker == NULL)
154 cerr << "ERROR: Stack's field is empty!" << endl;
155 StackList[CurrentFirstEntry] = NULL;
156 if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
157 CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
158 } else {
159 CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
160 CurrentLastEntry = CurrentFirstEntry;
161 }
162 } else
163 cerr << "ERROR: Stack is empty!" << endl;
164 return Walker;
165};
166
167/** Pops last atom from stack.
168 * First in, first out.
169 * \return atom pointer from stack, NULL - if failure (no atom pointer in field)
170 */
171atom *AtomStackClass::PopLast()
172{
173 atom *Walker = NULL;
174 if (!IsEmpty()) {
175 Walker = StackList[CurrentLastEntry];
176 StackList[CurrentLastEntry] = NULL;
177 if (Walker == NULL)
178 cerr << "ERROR: Stack's field is empty!" << endl;
179 NextFreeField = CurrentLastEntry;
180 if (CurrentLastEntry != CurrentFirstEntry) // has there been more than one item on stack
181 CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
182 } else {
183 cerr << "ERROR: Stack is empty!" << endl;
184 }
185 return Walker;
186};
187
188/** Removes a certain item from the stack.
189 * Item is seeked between \a CurrentFirstEntry and \a CurrentLastEntry, if found, place in stack is NULL'd and
190 * all subsequent items shifted by one position downward (with wrapping taken into account).
191 * \param *ptr adress of item
192 * \return true - item was removed, false - item was not found
193 */
194bool AtomStackClass::RemoveItem(atom *ptr)
195{
196 bool found = false;
197 cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
198 int i=CurrentFirstEntry;
199 if (!IsEmpty())
200 do {
201 if (StackList[i] == ptr) { // if item found, remove
202 cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
203 found = true;
204 StackList[i] = NULL;
205 }
206 if ((found) && (StackList[i] != NULL)) { // means we have to shift (and not the removed item)
207 if (i == 0) { // we are down to first item in stack, have to put onto last item
208 cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
209 StackList[EntryCount-1] = StackList[0];
210 } else {
211 cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
212 StackList[i-1] = StackList[i];
213 }
214 }
215 i=((i + 1) % EntryCount); // step on
216 } while (i!=NextFreeField);
217 else
218 cerr << "ERROR: Stack is already empty!" << endl;
219 if (found) {
220 NextFreeField = CurrentLastEntry;
221 if (CurrentLastEntry != CurrentFirstEntry) // has there been more than one item on stack
222 CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
223 }
224 return found;
225};
226
227/** Test the functionality of the stack.
228 * \param *out ofstream for debugging
229 * \param *test one item to put on stack
230 * \return true - all tests worked correctly
231 */
232void AtomStackClass::TestImplementation(ofstream *out, atom *test)
233{
234 atom *Walker = test;
235 *out << Verbose(1) << "Testing the snake stack..." << endl;
236 for (int i=0;i<EntryCount;i++) {
237 *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
238 Push(Walker);
239 Walker=Walker->next;
240 }
241 *out << endl;
242 Output(out);
243 if (IsFull())
244 *out << "Stack is full as supposed to be!" << endl;
245 else
246 *out << "ERROR: Stack is not as full as supposed to be!" << endl;
247 //if (StackList[(EntryCount+1)/2] != NULL) {
248 *out << "Removing element in the middle ..." << endl;
249 RemoveItem(StackList[(EntryCount+1)/2]);
250 Output(out);
251 //}
252 //if (StackList[CurrentFirstEntry] != NULL) {
253 *out << "Removing first element ..." << endl;
254 RemoveItem(StackList[CurrentFirstEntry]);
255 Output(out);
256 //}
257 //if (StackList[CurrentLastEntry] != NULL) {
258 *out << "Removing last element ..." << endl;
259 RemoveItem(StackList[CurrentLastEntry]);
260 Output(out);
261 //}
262 *out << "Clearing stack ... " << endl;
263 ClearStack();
264 Output(out);
265 if (IsEmpty())
266 *out << "Stack is empty as supposed to be!" << endl;
267 else
268 *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
269 *out << "done." << endl;
270};
271
272/** Puts contents of stack into ofstream \a *out.
273 * \param *out ofstream for output
274 */
275void AtomStackClass::Output(ofstream *out) const
276{
277 *out << "Contents of Stack: ";
278 for(int i=0;i<EntryCount;i++) {
279 *out << "\t";
280 if (i == CurrentFirstEntry)
281 *out << " 1";
282 if (i == CurrentLastEntry)
283 *out << " "<< EntryCount;
284 if (i == NextFreeField)
285 *out << " F";
286 *out << ": " << StackList[i];
287 }
288 *out << endl;
289};
290
291/** Checks whether stack is empty.
292 * Simply checks whether AtomStackClass::NextFreeField is equal to AtomStackClass::CurrentFirstEntry and
293 * AtomStackClass::CurrentFirstEntry is equal to AtomStackClass::CurrentLastEntry.
294 * \return true - empty, false - not
295 */
296bool AtomStackClass::IsEmpty()
297{
298 return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
299};
300
301/** Checks whether stack is full.
302 * Simply checks whether AtomStackClass::NextFreeField is equal to AtomStackClass::CurrentFirstEntry and
303 * AtomStackClass::CurrentFirstEntry is _not_ equal to AtomStackClass::CurrentLastEntry.
304 * \return true - full, false - not
305 */
306bool AtomStackClass::IsFull()
307{
308 return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
309};
310
311/** Returns number of items on stack.
312 * Simply returns difference between AtomStackClass::Stacklist entry AtomStackClass::CurrentEntry-1.
313 * \return number of items on stack
314 * \warning will never return correct item count if stack is full, i.e. count would be AtomStackClass::EntryCount.
315 */
316int AtomStackClass::ItemCount()
317{
318 //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
319 return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
320};
321
322/** Clears the stack from all atoms.
323 * \return true - sucess, false - failure
324 */
325void AtomStackClass::ClearStack()
326{
327 for(int i=0;i<EntryCount; i++)
328 StackList[i] = NULL;
329 CurrentFirstEntry = 0;
330 CurrentLastEntry = 0;
331 NextFreeField = 0;
332};
333
Note: See TracBrowser for help on using the repository browser.