ph_sensor.cc

Go to the documentation of this file.
00001 
00011 #include "ph_sensor.h"
00012 #include <math.h>
00013 
00014 
00015 double compute_ph( double wA4, double wB4, double pK1, double pK2 );
00016 double compute_ph_rhs( double pH, double wA4, double wB4, double pK1, double pK2 );
00017 
00018 
00019 ph_sensor::ph_sensor(dsim_model_setup *setup) : dsim_model(setup)
00020 {
00021 }
00022 
00023 ph_sensor::~ph_sensor()
00024 {
00025 }
00026         
00028 void ph_sensor::initialize_data()
00029 {               
00030     // Parameter initial values
00031     
00032     double pK1  = -6.34969247686806;
00033     double pK2  = -10.2502636844309;
00034     double pH   = 0;
00035 
00036     // Two parameters and the pH output
00037     pK1_dsim = create_parameter("pK1",  sd_type_double, &pK1,   1,1,    "", "Parameter 1");     pK1_dsim.mark_telemetry();
00038     pK2_dsim = create_parameter("pK2",  sd_type_double, &pK2,   1,1,    "", "Parameter 2");     pK2_dsim.mark_telemetry();
00039     pH_dsim  = create_output("pH",      sd_type_double, &pH,    1,1,    "", "pH measurement");   pH_dsim.mark_telemetry();
00040 
00041     // Thismeans only call initialize_timestep - no rhs()
00042     configure_timestep(true,false,false);
00043 }
00044 
00049 void ph_sensor::initialization_complete()
00050 {
00051     wA4_dsim    = parent()->request_local_variable("wA4");
00052     wB4_dsim    = parent()->request_local_variable("wB4");
00053 }
00054 
00059 void ph_sensor::initialize_timestep()
00060 {
00061     // Get values of dsim variables
00062     double wA4 = wA4_dsim.value_as_double();
00063     double wB4 = wB4_dsim.value_as_double();
00064     double pK1 = pK1_dsim.value_as_double();
00065     double pK2 = pK2_dsim.value_as_double();
00066     
00067     // Compute the ph output value
00068     double pH = compute_ph( wA4, wB4, pK1, pK2 );
00069     
00070     // Set the output variable    
00071     pH_dsim.set_value_as_double(pH);
00072 }
00073 
00074 
00075 // Secant method
00076 double compute_ph( double wA4, double wB4, double pK1, double pK2 )
00077 {
00078     // This insures a change of sign from the initial pH of 0
00079     const double pH_00 = -1;
00080     const double tol = 1e-3;
00081         double fOld = compute_ph_rhs( pH_00, wA4, wB4, pK1, pK2 );
00082     
00083     double pH = 0;      
00084         double delta = pH - pH_00;
00085         double fNew;
00086         int n = 0;
00087         
00088     // Limited to 100 interations
00089         while( fabs(delta) > tol )
00090         {
00091                 fNew  = compute_ph_rhs( pH, wA4, wB4, pK1, pK2 );
00092                 
00093                 delta = -fNew/((fNew-fOld)/delta);
00094         
00095         fOld = fNew;
00096                 
00097                 pH   += delta;  
00098         
00099         n++;
00100         
00101         if( n > 100) break;
00102         }
00103     return pH;
00104 }
00105 
00106 // Right hand side for the secant method
00107 double compute_ph_rhs( double pH, double wA4, double wB4, double pK1, double pK2 )
00108 {
00109     double y   = wA4 + pow(10,pH-14) - pow(10,-pH)
00110                + wB4*(1 + 2*pow(10,pH-pK2))/(1 + pow(10,pK1-pH) + pow(10,pH-pK2));
00111 
00112     return y;
00113 }
00114 
00115 
00116 extern "C"
00117 {
00118     dsim_model *PHSensor(void *setup);
00119 
00120         dsim_model *PHSensor(void *setup)
00121         {
00122                 return new ph_sensor((dsim_model_setup *)setup);
00123         }
00124         
00125 }
 All Classes Files Functions Variables