~scottydelicious666/brewtarget/brewtarget

« back to all changes in this revision

Viewing changes to Algorithms.cpp

  • Committer: Philip Greggory Lee
  • Date: 2009-08-23 16:53:43 UTC
  • Revision ID: git-v1:f8d1a25135bd92f06c46c562293800e4faa42c61
Made a src/ and ui/ directory and moved everything.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Algorithms.cpp is part of Brewtarget, and is Copyright Philip G. Lee
3
 
 * (rocketman768@gmail.com), 2009.
4
 
 *
5
 
 * Brewtarget is free software: you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation, either version 3 of the License, or
8
 
 * (at your option) any later version.
9
 
 
10
 
 * Brewtarget is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
 */
18
 
 
19
 
#include <cmath>
20
 
#include <math.h>
21
 
#include "Algorithms.h"
22
 
 
23
 
double* PlatoFromSG_20C20C = 0;
24
 
unsigned int PlatoFromSG_20C20C_order;
25
 
double* waterDensityPoly_C = 0;
26
 
unsigned int waterDensityPoly_C_order = 0;
27
 
 
28
 
void initVars()
29
 
{
30
 
   if( PlatoFromSG_20C20C == 0 )
31
 
   {
32
 
      PlatoFromSG_20C20C = new double[4];
33
 
      PlatoFromSG_20C20C_order = 3;
34
 
      PlatoFromSG_20C20C[0] = -616.868;
35
 
      PlatoFromSG_20C20C[1] = 1111.14;
36
 
      PlatoFromSG_20C20C[2] = -630.272;
37
 
      PlatoFromSG_20C20C[3] = 135.997;
38
 
   }
39
 
 
40
 
   if( waterDensityPoly_C == 0 )
41
 
   {
42
 
      waterDensityPoly_C = new double[4];
43
 
      waterDensityPoly_C_order = 3;
44
 
      waterDensityPoly_C[0] = 0.999924134;
45
 
      waterDensityPoly_C[1] = 3.113930471e-5;
46
 
      waterDensityPoly_C[2] = 6.268385468e-6;
47
 
      waterDensityPoly_C[3] = 1.80544064e-8;
48
 
   }
49
 
}
50
 
 
51
 
inline double intPow( double base, unsigned int pow )
52
 
{
53
 
   double ret = 1;
54
 
   for(; pow > 0; pow--)
55
 
      ret *= base;
56
 
 
57
 
   return ret;
58
 
}
59
 
 
60
 
// NOTE: order is the ORDER of the polynomial, NOT THE SIZE of the poly array.
61
 
double polyEval( double* poly, unsigned int order, double x )
62
 
{
63
 
   double ret = 0.0;
64
 
 
65
 
   for( ; order > 0; --order )
66
 
   {
67
 
      ret += poly[order] * intPow( x, order );
68
 
   }
69
 
   ret += poly[0];
70
 
 
71
 
   return ret;
72
 
}
73
 
 
74
 
// Root finding of a polynomial via the secant method. Returns HUGE_VAL on failure.
75
 
double rootFind( double* poly, unsigned int order, double x0, double x1 )
76
 
{
77
 
   double guesses[] = { x0, x1 };
78
 
   double newGuess;
79
 
   double maxAllowableSeparation = fabs( x0 - x1 ) * 1e3;
80
 
 
81
 
   while( fabs( guesses[0] - guesses[1] ) > ROOT_PRECISION )
82
 
   {
83
 
      newGuess = guesses[1] - (guesses[1] - guesses[0]) * polyEval( poly, order, guesses[1]) / ( polyEval( poly, order, guesses[1]) - polyEval( poly, order, guesses[0]) );
84
 
 
85
 
      guesses[0] = guesses[1];
86
 
      guesses[1] = newGuess;
87
 
 
88
 
      if( fabs( guesses[0] - guesses[1] ) > maxAllowableSeparation )
89
 
         return HUGE_VAL;
90
 
   }
91
 
 
92
 
   return newGuess;
93
 
}
94
 
 
95
 
double SG_20C20C_toPlato( double sg )
96
 
{
97
 
   initVars();
98
 
   return polyEval(PlatoFromSG_20C20C, PlatoFromSG_20C20C_order, sg );
99
 
}
100
 
 
101
 
double PlatoToSG_20C20C( double plato )
102
 
{
103
 
   initVars();
104
 
   double poly[PlatoFromSG_20C20C_order+1];
105
 
 
106
 
   // Copy the polynomial, cuz we need to alter it.
107
 
   for( int i = 0; i <= PlatoFromSG_20C20C_order; ++i )
108
 
   {
109
 
      poly[i] = PlatoFromSG_20C20C[i];
110
 
   }
111
 
 
112
 
   // After this, finding the root of the polynomial will be finding the SG.
113
 
   poly[0] -= plato;
114
 
 
115
 
   return rootFind( poly, PlatoFromSG_20C20C_order, 1.000, 1.050 );
116
 
}
117
 
 
118
 
double getWaterDensity_kgL( double celsius )
119
 
{
120
 
   initVars();
121
 
   return polyEval(waterDensityPoly_C, waterDensityPoly_C_order, celsius);
122
 
}
 
 
b'\\ No newline at end of file'