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
00031
00032 double pK1 = -6.34969247686806;
00033 double pK2 = -10.2502636844309;
00034 double pH = 0;
00035
00036
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
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
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
00068 double pH = compute_ph( wA4, wB4, pK1, pK2 );
00069
00070
00071 pH_dsim.set_value_as_double(pH);
00072 }
00073
00074
00075
00076 double compute_ph( double wA4, double wB4, double pK1, double pK2 )
00077 {
00078
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
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
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 }