source: src/helpers.cpp@ 28c351

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 28c351 was a67d19, checked in by Frederik Heber <heber@…>, 15 years ago

Huge change: Log() << Verbose(.) --> DoLog(.) && (Log() << Verbose(.) << ...);

Most of the files are affected, but this is necessary as if DoLog() says verbosity is not enough, all the stream operators won"t get executed which saves substantial amount of computation time.

Signed-off-by: Frederik Heber <heber@…>

  • Property mode set to 100755
File size: 7.6 KB
Line 
1/** \file helpers.cpp
2 *
3 * Implementation of some auxiliary functions for memory dis-/allocation and so on
4 */
5
6
7#include "helpers.hpp"
8#include "log.hpp"
9#include "memoryusageobserver.hpp"
10
11/********************************************** helpful functions *********************************/
12
13
14/** Asks for a double value and checks input
15 * \param *text question
16 */
17double ask_value(const char *text)
18{
19 double test = 0.1439851348959832147598734598273456723948652983045928346598365;
20 do {
21 DoLog(0) && (Log() << Verbose(0) << text);
22 cin >> test;
23 } while (test == 0.1439851348959832147598734598273456723948652983045928346598365);
24 return test;
25};
26
27/** Output of a debug message to stderr.
28 * \param *P Problem at hand, points to ParallelSimulationData#me
29 * \param output output string
30 */
31#ifdef HAVE_DEBUG
32void debug_in(const char *output, const char *file, const int line) {
33 if (output) fprintf(stderr,"DEBUG: in %s at line %i: %s\n", file, line, output);
34}
35#else
36void debug_in(const char *output, const char *file, const int line) {} // print nothing
37#endif
38
39/** modulo operator for doubles.
40 * \param *b pointer to double
41 * \param lower_bound lower bound
42 * \param upper_bound upper bound
43 */
44void bound(double *b, double lower_bound, double upper_bound)
45{
46 double step = (upper_bound - lower_bound);
47 while (*b >= upper_bound)
48 *b -= step;
49 while (*b < lower_bound)
50 *b += step;
51};
52
53/** Returns the power of \a n with respect to \a base.
54 * \param base basis
55 * \param n power
56 * \return \f$base^n\f$
57 */
58int pot(int base, int n)
59{
60 int res = 1;
61 int j;
62 for (j=n;j--;)
63 res *= base;
64 return res;
65};
66
67/** Counts lines in file.
68 * Note we are scanning lines from current position, not from beginning.
69 * \param InputFile file to be scanned.
70 */
71int CountLinesinFile(ifstream &InputFile)
72{
73 char *buffer = Malloc<char>(MAXSTRINGSIZE, "CountLinesinFile: *buffer");
74 int lines=0;
75
76 int PositionMarker = InputFile.tellg(); // not needed as Inputfile is copied, given by value, not by ref
77 // count the number of lines, i.e. the number of fragments
78 InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
79 InputFile.getline(buffer, MAXSTRINGSIZE);
80 while(!InputFile.eof()) {
81 InputFile.getline(buffer, MAXSTRINGSIZE);
82 lines++;
83 }
84 InputFile.seekg(PositionMarker, ios::beg);
85 Free(&buffer);
86 return lines;
87};
88
89/** Returns a string with \a i prefixed with 0s to match order of total number of molecules in digits.
90 * \param FragmentNumber total number of fragments to determine necessary number of digits
91 * \param digits number to create with 0 prefixed
92 * \return allocated(!) char array with number in digits, ten base.
93 */
94char *FixedDigitNumber(const int FragmentNumber, const int digits)
95{
96 char *returnstring;
97 int number = FragmentNumber;
98 int order = 0;
99 while (number != 0) { // determine number of digits needed
100 number = (int)floor(((double)number / 10.));
101 order++;
102 //Log() << Verbose(0) << "Number is " << number << ", order is " << order << "." << endl;
103 }
104 // allocate string
105 returnstring = Malloc<char>(order + 2, "FixedDigitNumber: *returnstring");
106 // terminate and fill string array from end backward
107 returnstring[order] = '\0';
108 number = digits;
109 for (int i=order;i--;) {
110 returnstring[i] = '0' + (char)(number % 10);
111 number = (int)floor(((double)number / 10.));
112 }
113 //Log() << Verbose(0) << returnstring << endl;
114 return returnstring;
115};
116
117/** Tests whether a given string contains a valid number or not.
118 * \param *string
119 * \return true - is a number, false - is not a valid number
120 */
121bool IsValidNumber( const char *string)
122{
123 int ptr = 0;
124 if ((string[ptr] == '.') || (string[ptr] == '-')) // number may be negative or start with dot
125 ptr++;
126 if ((string[ptr] >= '0') && (string[ptr] <= '9'))
127 return true;
128 return false;
129};
130
131/** Blows the 6-dimensional \a cell_size array up to a full NDIM by NDIM matrix.
132 * \param *symm 6-dim array of unique symmetric matrix components
133 * \return allocated NDIM*NDIM array with the symmetric matrix
134 */
135double * ReturnFullMatrixforSymmetric(const double * const symm)
136{
137 double *matrix = Malloc<double>(NDIM * NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
138 matrix[0] = symm[0];
139 matrix[1] = symm[1];
140 matrix[2] = symm[3];
141 matrix[3] = symm[1];
142 matrix[4] = symm[2];
143 matrix[5] = symm[4];
144 matrix[6] = symm[3];
145 matrix[7] = symm[4];
146 matrix[8] = symm[5];
147 return matrix;
148};
149
150/** Calculate the inverse of a 3x3 matrix.
151 * \param *matrix NDIM_NDIM array
152 */
153double * InverseMatrix( const double * const A)
154{
155 double *B = Malloc<double>(NDIM * NDIM, "Vector::InverseMatrix: *B");
156 double detA = RDET3(A);
157 double detAReci;
158
159 for (int i=0;i<NDIM*NDIM;++i)
160 B[i] = 0.;
161 // calculate the inverse B
162 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular
163 detAReci = 1./detA;
164 B[0] = detAReci*RDET2(A[4],A[5],A[7],A[8]); // A_11
165 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]); // A_12
166 B[2] = detAReci*RDET2(A[1],A[2],A[4],A[5]); // A_13
167 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]); // A_21
168 B[4] = detAReci*RDET2(A[0],A[2],A[6],A[8]); // A_22
169 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]); // A_23
170 B[6] = detAReci*RDET2(A[3],A[4],A[6],A[7]); // A_31
171 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32
172 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33
173 }
174 return B;
175};
176
177/** hard-coded determinant of a 3x3 matrix.
178 * \param a[9] matrix
179 * \return \f$det(a)\f$
180 */
181double RDET3(const double a[NDIM*NDIM])
182{
183 return ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3]);
184};
185
186/** hard-coded determinant of a 2x2 matrix.
187 * \param a[4] matrix
188 * \return \f$det(a)\f$
189 */
190double RDET2(const double a[4])
191{
192 return ((a[0])*(a[3])-(a[1])*(a[2]));
193};
194
195/** hard-coded determinant of a 2x2 matrix.
196 * \param a0 (0,0) entry of matrix
197 * \param a1 (0,1) entry of matrix
198 * \param a2 (1,0) entry of matrix
199 * \param a3 (1,1) entry of matrix
200 * \return \f$det(a)\f$
201 */
202double RDET2(const double a0, const double a1, const double a2, const double a3)
203{
204 return ((a0)*(a3)-(a1)*(a2));
205};
206
207/** Comparison function for GSL heapsort on distances in two molecules.
208 * \param *a
209 * \param *b
210 * \return <0, \a *a less than \a *b, ==0 if equal, >0 \a *a greater than \a *b
211 */
212int CompareDoubles (const void * a, const void * b)
213{
214 if (*(double *)a > *(double *)b)
215 return -1;
216 else if (*(double *)a < *(double *)b)
217 return 1;
218 else
219 return 0;
220};
221
222
223/** Allocates a memory range using malloc().
224 * Prints the provided error message in case of a failure.
225 *
226 * \param number of memory slices of type X to allocate
227 * \param failure message which is printed if the allocation fails
228 * \return pointer to the allocated memory range, will be NULL if a failure occurred
229 */
230template <> char* Malloc<char>(size_t size, const char* output)
231{
232 char* buffer = NULL;
233 buffer = (char*) malloc(sizeof(char) * (size + 1));
234 for (size_t i = size; i--;)
235 buffer[i] = (i % 2 == 0) ? 'p': 'c';
236 buffer[size] = '\0';
237
238 if (buffer != NULL) {
239 MemoryUsageObserver::getInstance()->addMemory(buffer, size);
240 } else {
241 Log() << Verbose(0) << "Malloc for datatype " << typeid(char).name()
242 << " failed - pointer is NULL: " << output << endl;
243 }
244
245 return buffer;
246};
247
248/**
249 * Frees all memory registered by the memory observer and calls exit(225) afterwards.
250 */
251void performCriticalExit() {
252 map<void*, size_t> pointers = MemoryUsageObserver::getInstance()->getPointersToAllocatedMemory();
253 for (map<void*, size_t>::iterator runner = pointers.begin(); runner != pointers.end(); runner++) {
254 Free(((void**) &runner->first));
255 }
256
257 exit(255);
258}
Note: See TracBrowser for help on using the repository browser.