00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef MAX
00025 #define MAX(x,y) (( (x) > (y) ) ? (x) : (y))
00026 #endif
00027
00028 #include "HMWSoln.h"
00029 #include "ThermoFactory.h"
00030 #include "WaterProps.h"
00031 #include "PDSS_Water.h"
00032
00033 #include <cmath>
00034 #include <cstdlib>
00035
00036 namespace Cantera {
00037
00038
00039
00040
00041 HMWSoln::HMWSoln() :
00042 MolalityVPSSTP(),
00043 m_formPitzer(PITZERFORM_BASE),
00044 m_formPitzerTemp(PITZER_TEMP_CONSTANT),
00045 m_formGC(2),
00046 m_IionicMolality(0.0),
00047 m_maxIionicStrength(100.0),
00048 m_TempPitzerRef(298.15),
00049 m_IionicMolalityStoich(0.0),
00050 m_form_A_Debye(A_DEBYE_WATER),
00051 m_A_Debye(1.172576),
00052 m_waterSS(0),
00053 m_densWaterSS(1000.),
00054 m_waterProps(0),
00055 m_molalitiesAreCropped(false),
00056 IMS_typeCutoff_(0),
00057 IMS_X_o_cutoff_(0.2),
00058 IMS_gamma_o_min_(1.0E-5),
00059 IMS_gamma_k_min_(10.0),
00060 IMS_cCut_(0.05),
00061 IMS_slopefCut_(0.6),
00062 IMS_dfCut_(0.0),
00063 IMS_efCut_(0.0),
00064 IMS_afCut_(0.0),
00065 IMS_bfCut_(0.0),
00066 IMS_slopegCut_(0.0),
00067 IMS_dgCut_(0.0),
00068 IMS_egCut_(0.0),
00069 IMS_agCut_(0.0),
00070 IMS_bgCut_(0.0),
00071 MC_X_o_cutoff_(0.0),
00072 MC_X_o_min_(0.0),
00073 MC_slopepCut_(0.0),
00074 MC_dpCut_(0.0),
00075 MC_epCut_(0.0),
00076 MC_apCut_(0.0),
00077 MC_bpCut_(0.0),
00078 MC_cpCut_(0.0),
00079 CROP_ln_gamma_o_min(-6.0),
00080 CROP_ln_gamma_o_max(3.0),
00081 CROP_ln_gamma_k_min(-5.0),
00082 CROP_ln_gamma_k_max(15.0),
00083 m_debugCalc(0)
00084 {
00085 for (int i = 0; i < 17; i++) {
00086 elambda[i] = 0.0;
00087 elambda1[i] = 0.0;
00088 }
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098 HMWSoln::HMWSoln(std::string inputFile, std::string id) :
00099 MolalityVPSSTP(),
00100 m_formPitzer(PITZERFORM_BASE),
00101 m_formPitzerTemp(PITZER_TEMP_CONSTANT),
00102 m_formGC(2),
00103 m_IionicMolality(0.0),
00104 m_maxIionicStrength(100.0),
00105 m_TempPitzerRef(298.15),
00106 m_IionicMolalityStoich(0.0),
00107 m_form_A_Debye(A_DEBYE_WATER),
00108 m_A_Debye(1.172576),
00109 m_waterSS(0),
00110 m_densWaterSS(1000.),
00111 m_waterProps(0),
00112 m_molalitiesAreCropped(false),
00113 IMS_typeCutoff_(0),
00114 IMS_X_o_cutoff_(0.2),
00115 IMS_gamma_o_min_(1.0E-5),
00116 IMS_gamma_k_min_(10.0),
00117 IMS_cCut_(0.05),
00118 IMS_slopefCut_(0.6),
00119 IMS_dfCut_(0.0),
00120 IMS_efCut_(0.0),
00121 IMS_afCut_(0.0),
00122 IMS_bfCut_(0.0),
00123 IMS_slopegCut_(0.0),
00124 IMS_dgCut_(0.0),
00125 IMS_egCut_(0.0),
00126 IMS_agCut_(0.0),
00127 IMS_bgCut_(0.0),
00128 MC_X_o_cutoff_(0.0),
00129 MC_X_o_min_(0.0),
00130 MC_slopepCut_(0.0),
00131 MC_dpCut_(0.0),
00132 MC_epCut_(0.0),
00133 MC_apCut_(0.0),
00134 MC_bpCut_(0.0),
00135 MC_cpCut_(0.0),
00136 CROP_ln_gamma_o_min(-6.0),
00137 CROP_ln_gamma_o_max(3.0),
00138 CROP_ln_gamma_k_min(-5.0),
00139 CROP_ln_gamma_k_max(15.0),
00140 m_debugCalc(0)
00141 {
00142 for (int i = 0; i < 17; i++) {
00143 elambda[i] = 0.0;
00144 elambda1[i] = 0.0;
00145 }
00146 constructPhaseFile(inputFile, id);
00147 }
00148
00149 HMWSoln::HMWSoln(XML_Node& phaseRoot, std::string id) :
00150 MolalityVPSSTP(),
00151 m_formPitzer(PITZERFORM_BASE),
00152 m_formPitzerTemp(PITZER_TEMP_CONSTANT),
00153 m_formGC(2),
00154 m_IionicMolality(0.0),
00155 m_maxIionicStrength(100.0),
00156 m_TempPitzerRef(298.15),
00157 m_IionicMolalityStoich(0.0),
00158 m_form_A_Debye(A_DEBYE_WATER),
00159 m_A_Debye(1.172576),
00160 m_waterSS(0),
00161 m_densWaterSS(1000.),
00162 m_waterProps(0),
00163 m_molalitiesAreCropped(false),
00164 IMS_typeCutoff_(0),
00165 IMS_X_o_cutoff_(0.2),
00166 IMS_gamma_o_min_(1.0E-5),
00167 IMS_gamma_k_min_(10.0),
00168 IMS_cCut_(0.05),
00169 IMS_slopefCut_(0.6),
00170 IMS_dfCut_(0.0),
00171 IMS_efCut_(0.0),
00172 IMS_afCut_(0.0),
00173 IMS_bfCut_(0.0),
00174 IMS_slopegCut_(0.0),
00175 IMS_dgCut_(0.0),
00176 IMS_egCut_(0.0),
00177 IMS_agCut_(0.0),
00178 IMS_bgCut_(0.0),
00179 MC_X_o_cutoff_(0.0),
00180 MC_X_o_min_(0.0),
00181 MC_slopepCut_(0.0),
00182 MC_dpCut_(0.0),
00183 MC_epCut_(0.0),
00184 MC_apCut_(0.0),
00185 MC_bpCut_(0.0),
00186 MC_cpCut_(0.0),
00187 CROP_ln_gamma_o_min(-6.0),
00188 CROP_ln_gamma_o_max(3.0),
00189 CROP_ln_gamma_k_min(-5.0),
00190 CROP_ln_gamma_k_max(15.0),
00191 m_debugCalc(0)
00192 {
00193 for (int i = 0; i < 17; i++) {
00194 elambda[i] = 0.0;
00195 elambda1[i] = 0.0;
00196 }
00197 constructPhaseXML(phaseRoot, id);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 HMWSoln::HMWSoln(const HMWSoln &b) :
00207 MolalityVPSSTP(),
00208 m_formPitzer(PITZERFORM_BASE),
00209 m_formPitzerTemp(PITZER_TEMP_CONSTANT),
00210 m_formGC(2),
00211 m_IionicMolality(0.0),
00212 m_maxIionicStrength(100.0),
00213 m_TempPitzerRef(298.15),
00214 m_IionicMolalityStoich(0.0),
00215 m_form_A_Debye(A_DEBYE_WATER),
00216 m_A_Debye(1.172576),
00217 m_waterSS(0),
00218 m_densWaterSS(1000.),
00219 m_waterProps(0),
00220 m_molalitiesAreCropped(false),
00221 IMS_typeCutoff_(0),
00222 IMS_X_o_cutoff_(0.2),
00223 IMS_gamma_o_min_(1.0E-5),
00224 IMS_gamma_k_min_(10.0),
00225 IMS_cCut_(0.05),
00226 IMS_slopefCut_(0.6),
00227 IMS_dfCut_(0.0),
00228 IMS_efCut_(0.0),
00229 IMS_afCut_(0.0),
00230 IMS_bfCut_(0.0),
00231 IMS_slopegCut_(0.0),
00232 IMS_dgCut_(0.0),
00233 IMS_egCut_(0.0),
00234 IMS_agCut_(0.0),
00235 IMS_bgCut_(0.0),
00236 MC_X_o_cutoff_(0.0),
00237 MC_X_o_min_(0.0),
00238 MC_slopepCut_(0.0),
00239 MC_dpCut_(0.0),
00240 MC_epCut_(0.0),
00241 MC_apCut_(0.0),
00242 MC_bpCut_(0.0),
00243 MC_cpCut_(0.0),
00244 CROP_ln_gamma_o_min(-6.0),
00245 CROP_ln_gamma_o_max(3.0),
00246 CROP_ln_gamma_k_min(-5.0),
00247 CROP_ln_gamma_k_max(15.0),
00248 m_debugCalc(0)
00249 {
00250
00251
00252
00253
00254 *this = b;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 HMWSoln& HMWSoln::
00264 operator=(const HMWSoln &b) {
00265 if (&b != this) {
00266 MolalityVPSSTP::operator=(b);
00267 m_formPitzer = b.m_formPitzer;
00268 m_formPitzerTemp = b.m_formPitzerTemp;
00269 m_formGC = b.m_formGC;
00270 m_Aionic = b.m_Aionic;
00271 m_IionicMolality = b.m_IionicMolality;
00272 m_maxIionicStrength = b.m_maxIionicStrength;
00273 m_TempPitzerRef = b.m_TempPitzerRef;
00274 m_IionicMolalityStoich= b.m_IionicMolalityStoich;
00275 m_form_A_Debye = b.m_form_A_Debye;
00276 m_A_Debye = b.m_A_Debye;
00277
00278
00279 m_waterSS = providePDSS(0);
00280 if (!m_waterSS) {
00281 throw CanteraError("HMWSoln::operator=()", "Dynamic cast to PDSS_Water failed");
00282 }
00283
00284 m_densWaterSS = b.m_densWaterSS;
00285
00286 if (m_waterProps) {
00287 delete m_waterProps;
00288 m_waterProps = 0;
00289 }
00290 if (b.m_waterProps) {
00291 m_waterProps = new WaterProps(dynamic_cast<PDSS_Water*>(m_waterSS));
00292 }
00293
00294 m_expg0_RT = b.m_expg0_RT;
00295 m_pe = b.m_pe;
00296 m_pp = b.m_pp;
00297 m_tmpV = b.m_tmpV;
00298 m_speciesCharge_Stoich= b.m_speciesCharge_Stoich;
00299 m_Beta0MX_ij = b.m_Beta0MX_ij;
00300 m_Beta0MX_ij_L = b.m_Beta0MX_ij_L;
00301 m_Beta0MX_ij_LL = b.m_Beta0MX_ij_LL;
00302 m_Beta0MX_ij_P = b.m_Beta0MX_ij_P;
00303 m_Beta0MX_ij_coeff = b.m_Beta0MX_ij_coeff;
00304 m_Beta1MX_ij = b.m_Beta1MX_ij;
00305 m_Beta1MX_ij_L = b.m_Beta1MX_ij_L;
00306 m_Beta1MX_ij_LL = b.m_Beta1MX_ij_LL;
00307 m_Beta1MX_ij_P = b.m_Beta1MX_ij_P;
00308 m_Beta1MX_ij_coeff = b.m_Beta1MX_ij_coeff;
00309 m_Beta2MX_ij = b.m_Beta2MX_ij;
00310 m_Beta2MX_ij_L = b.m_Beta2MX_ij_L;
00311 m_Beta2MX_ij_LL = b.m_Beta2MX_ij_LL;
00312 m_Beta2MX_ij_P = b.m_Beta2MX_ij_P;
00313 m_Beta2MX_ij_coeff = b.m_Beta2MX_ij_coeff;
00314 m_Alpha1MX_ij = b.m_Alpha1MX_ij;
00315 m_Alpha2MX_ij = b.m_Alpha2MX_ij;
00316 m_CphiMX_ij = b.m_CphiMX_ij;
00317 m_CphiMX_ij_L = b.m_CphiMX_ij_L;
00318 m_CphiMX_ij_LL = b.m_CphiMX_ij_LL;
00319 m_CphiMX_ij_P = b.m_CphiMX_ij_P;
00320 m_CphiMX_ij_coeff = b.m_CphiMX_ij_coeff;
00321 m_Theta_ij = b.m_Theta_ij;
00322 m_Theta_ij_L = b.m_Theta_ij_L;
00323 m_Theta_ij_LL = b.m_Theta_ij_LL;
00324 m_Theta_ij_P = b.m_Theta_ij_P;
00325 m_Theta_ij_coeff = b.m_Theta_ij_coeff;
00326 m_Psi_ijk = b.m_Psi_ijk;
00327 m_Psi_ijk_L = b.m_Psi_ijk_L;
00328 m_Psi_ijk_LL = b.m_Psi_ijk_LL;
00329 m_Psi_ijk_P = b.m_Psi_ijk_P;
00330 m_Psi_ijk_coeff = b.m_Psi_ijk_coeff;
00331 m_Lambda_nj = b.m_Lambda_nj;
00332 m_Lambda_nj_L = b.m_Lambda_nj_L;
00333 m_Lambda_nj_LL = b.m_Lambda_nj_LL;
00334 m_Lambda_nj_P = b.m_Lambda_nj_P;
00335 m_Lambda_nj_coeff = b.m_Lambda_nj_coeff;
00336 m_lnActCoeffMolal_Scaled = b.m_lnActCoeffMolal_Scaled;
00337 m_lnActCoeffMolal_Unscaled = b.m_lnActCoeffMolal_Unscaled;
00338 m_dlnActCoeffMolaldT_Unscaled = b.m_dlnActCoeffMolaldT_Unscaled;
00339 m_d2lnActCoeffMolaldT2_Unscaled= b.m_d2lnActCoeffMolaldT2_Unscaled;
00340 m_dlnActCoeffMolaldP_Unscaled = b.m_dlnActCoeffMolaldP_Unscaled;
00341 m_dlnActCoeffMolaldT_Scaled = b.m_dlnActCoeffMolaldT_Unscaled;
00342 m_d2lnActCoeffMolaldT2_Scaled = b.m_d2lnActCoeffMolaldT2_Unscaled;
00343 m_dlnActCoeffMolaldP_Scaled = b.m_dlnActCoeffMolaldP_Unscaled;
00344
00345 m_gfunc_IJ = b.m_gfunc_IJ;
00346 m_g2func_IJ = b.m_g2func_IJ;
00347 m_hfunc_IJ = b.m_hfunc_IJ;
00348 m_h2func_IJ = b.m_h2func_IJ;
00349 m_BMX_IJ = b.m_BMX_IJ;
00350 m_BMX_IJ_L = b.m_BMX_IJ_L;
00351 m_BMX_IJ_LL = b.m_BMX_IJ_LL;
00352 m_BMX_IJ_P = b.m_BMX_IJ_P;
00353 m_BprimeMX_IJ = b.m_BprimeMX_IJ;
00354 m_BprimeMX_IJ_L = b.m_BprimeMX_IJ_L;
00355 m_BprimeMX_IJ_LL = b.m_BprimeMX_IJ_LL;
00356 m_BprimeMX_IJ_P = b.m_BprimeMX_IJ_P;
00357 m_BphiMX_IJ = b.m_BphiMX_IJ;
00358 m_BphiMX_IJ_L = b.m_BphiMX_IJ_L;
00359 m_BphiMX_IJ_LL = b.m_BphiMX_IJ_LL;
00360 m_BphiMX_IJ_P = b.m_BphiMX_IJ_P;
00361 m_Phi_IJ = b.m_Phi_IJ;
00362 m_Phi_IJ_L = b.m_Phi_IJ_L;
00363 m_Phi_IJ_LL = b.m_Phi_IJ_LL;
00364 m_Phi_IJ_P = b.m_Phi_IJ_P;
00365 m_Phiprime_IJ = b.m_Phiprime_IJ;
00366 m_PhiPhi_IJ = b.m_PhiPhi_IJ;
00367 m_PhiPhi_IJ_L = b.m_PhiPhi_IJ_L;
00368 m_PhiPhi_IJ_LL = b.m_PhiPhi_IJ_LL;
00369 m_PhiPhi_IJ_P = b.m_PhiPhi_IJ_P;
00370 m_CMX_IJ = b.m_CMX_IJ;
00371 m_CMX_IJ_L = b.m_CMX_IJ_L;
00372 m_CMX_IJ_LL = b.m_CMX_IJ_LL;
00373 m_CMX_IJ_P = b.m_CMX_IJ_P;
00374 m_gamma_tmp = b.m_gamma_tmp;
00375
00376 IMS_lnActCoeffMolal_ = b.IMS_lnActCoeffMolal_;
00377 IMS_typeCutoff_ = b.IMS_typeCutoff_;
00378 IMS_X_o_cutoff_ = b.IMS_X_o_cutoff_;
00379 IMS_gamma_o_min_ = b.IMS_gamma_o_min_;
00380 IMS_gamma_k_min_ = b.IMS_gamma_k_min_;
00381 IMS_cCut_ = b.IMS_cCut_;
00382 IMS_slopefCut_ = b.IMS_slopefCut_;
00383 IMS_dfCut_ = b.IMS_dfCut_;
00384 IMS_efCut_ = b.IMS_efCut_;
00385 IMS_afCut_ = b.IMS_afCut_;
00386 IMS_bfCut_ = b.IMS_bfCut_;
00387 IMS_slopegCut_ = b.IMS_slopegCut_;
00388 IMS_dgCut_ = b.IMS_dgCut_;
00389 IMS_egCut_ = b.IMS_egCut_;
00390 IMS_agCut_ = b.IMS_agCut_;
00391 IMS_bgCut_ = b.IMS_bgCut_;
00392 MC_X_o_cutoff_ = b.MC_X_o_cutoff_;
00393 MC_X_o_min_ = b.MC_X_o_min_;
00394 MC_slopepCut_ = b.MC_slopepCut_;
00395 MC_dpCut_ = b.MC_dpCut_;
00396 MC_epCut_ = b.MC_epCut_;
00397 MC_apCut_ = b.MC_apCut_;
00398 MC_bpCut_ = b.MC_bpCut_;
00399 MC_cpCut_ = b.MC_cpCut_;
00400 CROP_ln_gamma_o_min = b.CROP_ln_gamma_o_min;
00401 CROP_ln_gamma_o_max = b.CROP_ln_gamma_o_max;
00402 CROP_ln_gamma_k_min = b.CROP_ln_gamma_k_min;
00403 CROP_ln_gamma_k_max = b.CROP_ln_gamma_k_max;
00404 CROP_speciesCropped_ = b.CROP_speciesCropped_;
00405 m_CounterIJ = b.m_CounterIJ;
00406 m_molalitiesCropped = b.m_molalitiesCropped;
00407 m_molalitiesAreCropped= b.m_molalitiesAreCropped;
00408 m_debugCalc = b.m_debugCalc;
00409 }
00410 return *this;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 HMWSoln::HMWSoln(int testProb) :
00441 MolalityVPSSTP(),
00442 m_formPitzer(PITZERFORM_BASE),
00443 m_formPitzerTemp(PITZER_TEMP_CONSTANT),
00444 m_formGC(2),
00445 m_IionicMolality(0.0),
00446 m_maxIionicStrength(100.0),
00447 m_TempPitzerRef(298.15),
00448 m_IionicMolalityStoich(0.0),
00449 m_form_A_Debye(A_DEBYE_WATER),
00450 m_A_Debye(1.172576),
00451 m_waterSS(0),
00452 m_densWaterSS(1000.),
00453 m_waterProps(0),
00454 m_molalitiesAreCropped(false),
00455 IMS_typeCutoff_(0),
00456 IMS_X_o_cutoff_(0.2),
00457 IMS_gamma_o_min_(1.0E-5),
00458 IMS_gamma_k_min_(10.0),
00459 IMS_cCut_(0.05),
00460 IMS_slopefCut_(0.6),
00461 IMS_dfCut_(0.0),
00462 IMS_efCut_(0.0),
00463 IMS_afCut_(0.0),
00464 IMS_bfCut_(0.0),
00465 IMS_slopegCut_(0.0),
00466 IMS_dgCut_(0.0),
00467 IMS_egCut_(0.0),
00468 IMS_agCut_(0.0),
00469 IMS_bgCut_(0.0),
00470 MC_X_o_cutoff_(0.0),
00471 MC_X_o_min_(0.0),
00472 MC_slopepCut_(0.0),
00473 MC_dpCut_(0.0),
00474 MC_epCut_(0.0),
00475 MC_apCut_(0.0),
00476 MC_bpCut_(0.0),
00477 MC_cpCut_(0.0),
00478 CROP_ln_gamma_o_min(-6.0),
00479 CROP_ln_gamma_o_max(3.0),
00480 CROP_ln_gamma_k_min(-5.0),
00481 CROP_ln_gamma_k_max(15.0),
00482 m_debugCalc(0)
00483 {
00484 if (testProb != 1) {
00485 printf("unknown test problem\n");
00486 exit(EXIT_FAILURE);
00487 }
00488
00489 constructPhaseFile("HMW_NaCl.xml", "");
00490
00491 int i = speciesIndex("Cl-");
00492 int j = speciesIndex("H+");
00493 int n = i * m_kk + j;
00494 int ct = m_CounterIJ[n];
00495 m_Beta0MX_ij[ct] = 0.1775;
00496 m_Beta1MX_ij[ct] = 0.2945;
00497 m_CphiMX_ij[ct] = 0.0008;
00498 m_Alpha1MX_ij[ct]= 2.000;
00499
00500
00501 i = speciesIndex("Cl-");
00502 j = speciesIndex("Na+");
00503 n = i * m_kk + j;
00504 ct = m_CounterIJ[n];
00505 m_Beta0MX_ij[ct] = 0.0765;
00506 m_Beta1MX_ij[ct] = 0.2664;
00507 m_CphiMX_ij[ct] = 0.00127;
00508 m_Alpha1MX_ij[ct]= 2.000;
00509
00510
00511 i = speciesIndex("Cl-");
00512 j = speciesIndex("OH-");
00513 n = i * m_kk + j;
00514 ct = m_CounterIJ[n];
00515 m_Theta_ij[ct] = -0.05;
00516
00517 i = speciesIndex("H+");
00518 j = speciesIndex("Na+");
00519 n = i * m_kk + j;
00520 ct = m_CounterIJ[n];
00521 m_Theta_ij[ct] = 0.036;
00522
00523 i = speciesIndex("Na+");
00524 j = speciesIndex("OH-");
00525 n = i * m_kk + j;
00526 ct = m_CounterIJ[n];
00527 m_Beta0MX_ij[ct] = 0.0864;
00528 m_Beta1MX_ij[ct] = 0.253;
00529 m_CphiMX_ij[ct] = 0.0044;
00530 m_Alpha1MX_ij[ct]= 2.000;
00531
00532 i = speciesIndex("Cl-");
00533 j = speciesIndex("H+");
00534 int k = speciesIndex("Na+");
00535 double param = -0.004;
00536 n = i * m_kk *m_kk + j * m_kk + k ;
00537 m_Psi_ijk[n] = param;
00538 m_Psi_ijk_coeff(0,n) = param;
00539 n = i * m_kk *m_kk + k * m_kk + j ;
00540 m_Psi_ijk[n] = param;
00541 m_Psi_ijk_coeff(0,n) = param;
00542 n = j * m_kk *m_kk + i * m_kk + k ;
00543 m_Psi_ijk[n] = param;
00544 m_Psi_ijk_coeff(0,n) = param;
00545 n = j * m_kk *m_kk + k * m_kk + i ;
00546 m_Psi_ijk[n] = param;
00547 m_Psi_ijk_coeff(0,n) = param;
00548 n = k * m_kk *m_kk + j * m_kk + i ;
00549 m_Psi_ijk[n] = param;
00550 m_Psi_ijk_coeff(0,n) = param;
00551 n = k * m_kk *m_kk + i * m_kk + j ;
00552 m_Psi_ijk[n] = param;
00553 m_Psi_ijk_coeff(0,n) = param;
00554
00555 i = speciesIndex("Cl-");
00556 j = speciesIndex("Na+");
00557 k = speciesIndex("OH-");
00558 param = -0.006;
00559 n = i * m_kk *m_kk + j * m_kk + k ;
00560 m_Psi_ijk[n] = param;
00561 m_Psi_ijk_coeff(0,n) = param;
00562 n = i * m_kk *m_kk + k * m_kk + j ;
00563 m_Psi_ijk[n] = param;
00564 m_Psi_ijk_coeff(0,n) = param;
00565 n = j * m_kk *m_kk + i * m_kk + k ;
00566 m_Psi_ijk[n] = param;
00567 m_Psi_ijk_coeff(0,n) = param;
00568 n = j * m_kk *m_kk + k * m_kk + i ;
00569 m_Psi_ijk[n] = param;
00570 m_Psi_ijk_coeff(0,n) = param;
00571 n = k * m_kk *m_kk + j * m_kk + i ;
00572 m_Psi_ijk[n] = param;
00573 m_Psi_ijk_coeff(0,n) = param;
00574 n = k * m_kk *m_kk + i * m_kk + j ;
00575 m_Psi_ijk[n] = param;
00576 m_Psi_ijk_coeff(0,n) = param;
00577
00578 printCoeffs();
00579 }
00580
00581
00582
00583
00584
00585
00586 HMWSoln::~HMWSoln() {
00587 if (m_waterProps) {
00588 delete m_waterProps; m_waterProps = 0;
00589 }
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599 ThermoPhase* HMWSoln::duplMyselfAsThermoPhase() const {
00600 HMWSoln* mtp = new HMWSoln(*this);
00601 return (ThermoPhase *) mtp;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610 int HMWSoln::eosType() const {
00611 int res;
00612 switch (m_formGC) {
00613 case 0:
00614 res = cHMWSoln0;
00615 break;
00616 case 1:
00617 res = cHMWSoln1;
00618 break;
00619 case 2:
00620 res = cHMWSoln2;
00621 break;
00622 default:
00623 throw CanteraError("eosType", "Unknown type");
00624 }
00625 return res;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 doublereal HMWSoln::enthalpy_mole() const {
00635 getPartialMolarEnthalpies(DATA_PTR(m_tmpV));
00636 getMoleFractions(DATA_PTR(m_pp));
00637 double val = mean_X(DATA_PTR(m_tmpV));
00638 return val;
00639 }
00640
00641 doublereal HMWSoln::relative_enthalpy() const {
00642 getPartialMolarEnthalpies(DATA_PTR(m_tmpV));
00643 double hbar = mean_X(DATA_PTR(m_tmpV));
00644 getEnthalpy_RT(DATA_PTR(m_gamma_tmp));
00645 double RT = GasConstant * temperature();
00646 for (int k = 0; k < m_kk; k++) {
00647 m_gamma_tmp[k] *= RT;
00648 }
00649 double h0bar = mean_X(DATA_PTR(m_gamma_tmp));
00650 return (hbar - h0bar);
00651 }
00652
00653
00654
00655 doublereal HMWSoln::relative_molal_enthalpy() const {
00656 double L = relative_enthalpy();
00657 getMoleFractions(DATA_PTR(m_tmpV));
00658 double xanion = 0.0;
00659 int kcation = -1;
00660 double xcation = 0.0;
00661 int kanion = -1;
00662 const double *charge = DATA_PTR(m_speciesCharge);
00663 for (int k = 0; k < m_kk; k++) {
00664 if (charge[k] > 0.0) {
00665 if (m_tmpV[k] > xanion) {
00666 xanion = m_tmpV[k];
00667 kanion = k;
00668 }
00669 } else if (charge[k] < 0.0) {
00670 if (m_tmpV[k] > xcation) {
00671 xcation = m_tmpV[k];
00672 kcation = k;
00673 }
00674 }
00675 }
00676 if (kcation < 0 || kanion < 0) {
00677 return L;
00678 }
00679 double xuse = xcation;
00680 int kuse = kcation;
00681 double factor = 1;
00682 if (xanion < xcation) {
00683 xuse = xanion;
00684 kuse = kanion;
00685 if (charge[kcation] != 1.0) {
00686 factor = charge[kcation];
00687 }
00688 } else {
00689 if (charge[kanion] != 1.0) {
00690 factor = charge[kanion];
00691 }
00692 }
00693 xuse = xuse / factor;
00694 L = L / xuse;
00695 return L;
00696 }
00697
00698
00699
00700
00701
00702
00703
00704 doublereal HMWSoln::intEnergy_mole() const {
00705 double hh = enthalpy_mole();
00706 double pres = pressure();
00707 double molarV = 1.0/molarDensity();
00708 double uu = hh - pres * molarV;
00709 return uu;
00710 }
00711
00712
00713
00714
00715
00716
00717 doublereal HMWSoln::entropy_mole() const {
00718 getPartialMolarEntropies(DATA_PTR(m_tmpV));
00719 return mean_X(DATA_PTR(m_tmpV));
00720 }
00721
00722
00723 doublereal HMWSoln::gibbs_mole() const {
00724 getChemPotentials(DATA_PTR(m_tmpV));
00725 return mean_X(DATA_PTR(m_tmpV));
00726 }
00727
00728
00729
00730
00731
00732
00733 doublereal HMWSoln::cp_mole() const {
00734 getPartialMolarCp(DATA_PTR(m_tmpV));
00735 double val = mean_X(DATA_PTR(m_tmpV));
00736 return val;
00737 }
00738
00739
00740 doublereal HMWSoln::cv_mole() const {
00741
00742
00743 err("not implemented");
00744 return 0.0;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 doublereal HMWSoln::pressure() const {
00757 return m_Pcurrent;
00758 }
00759
00760
00761
00762
00763
00764
00765 void HMWSoln::setPressure(doublereal p) {
00766 setState_TP(temperature(), p);
00767 }
00768
00769 void HMWSoln::calcDensity() {
00770 double *vbar = &m_pp[0];
00771 getPartialMolarVolumes(vbar);
00772 double *x = &m_tmpV[0];
00773 getMoleFractions(x);
00774 doublereal vtotal = 0.0;
00775 for (int i = 0; i < m_kk; i++) {
00776 vtotal += vbar[i] * x[i];
00777 }
00778 doublereal dd = meanMolecularWeight() / vtotal;
00779 State::setDensity(dd);
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 doublereal HMWSoln::isothermalCompressibility() const {
00793 throw CanteraError("HMWSoln::isothermalCompressibility",
00794 "unimplemented");
00795 return 0.0;
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 doublereal HMWSoln::thermalExpansionCoeff() const {
00810 throw CanteraError("HMWSoln::thermalExpansionCoeff",
00811 "unimplemented");
00812 return 0.0;
00813 }
00814
00815 double HMWSoln::density() const{
00816
00817 return State::density();
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 void HMWSoln::setDensity(const doublereal rho) {
00841 double dens_old = density();
00842
00843 if (rho != dens_old) {
00844 throw CanteraError("HMWSoln::setDensity",
00845 "Density is not an independent variable");
00846 }
00847 }
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 void HMWSoln::setMolarDensity(const doublereal rho) {
00859 throw CanteraError("HMWSoln::setMolarDensity",
00860 "Density is not an independent variable");
00861 }
00862
00863
00864
00865
00866
00867
00868 void HMWSoln::setTemperature(const doublereal temp) {
00869 setState_TP(temp, m_Pcurrent);
00870 }
00871
00872
00873
00874
00875
00876
00877 void HMWSoln::setState_TP(doublereal temp, doublereal pres) {
00878 State::setTemperature(temp);
00879
00880
00881
00882 m_Pcurrent = pres;
00883
00884
00885
00886
00887
00888 updateStandardStateThermo();
00889
00890
00891
00892
00893
00894 m_densWaterSS = m_waterSS->density();
00895
00896
00897
00898
00899 calcDensity();
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 void HMWSoln::getActivityConcentrations(doublereal* c) const {
00920 double cs_solvent = standardConcentration();
00921 getActivities(c);
00922 c[0] *= cs_solvent;
00923 if (m_kk > 1) {
00924 double cs_solute = standardConcentration(1);
00925 for (int k = 1; k < m_kk; k++) {
00926 c[k] *= cs_solute;
00927 }
00928 }
00929 }
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953 doublereal HMWSoln::standardConcentration(int k) const {
00954 getStandardVolumes(DATA_PTR(m_tmpV));
00955 double mvSolvent = m_tmpV[m_indexSolvent];
00956 if (k > 0) {
00957 return m_Mnaught / mvSolvent;
00958 }
00959 return 1.0 / mvSolvent;
00960 }
00961
00962
00963
00964
00965
00966 doublereal HMWSoln::logStandardConc(int k) const {
00967 double c_solvent = standardConcentration(k);
00968 return log(c_solvent);
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 void HMWSoln::getUnitsStandardConc(double *uA, int k, int sizeUA) const {
00994 for (int i = 0; i < sizeUA; i++) {
00995 if (i == 0) uA[0] = 1.0;
00996 if (i == 1) uA[1] = -nDim();
00997 if (i == 2) uA[2] = 0.0;
00998 if (i == 3) uA[3] = 0.0;
00999 if (i == 4) uA[4] = 0.0;
01000 if (i == 5) uA[5] = 0.0;
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011 void HMWSoln::getActivities(doublereal* ac) const {
01012 updateStandardStateThermo();
01013
01014
01015
01016
01017 s_update_lnMolalityActCoeff();
01018
01019
01020
01021 for (int k = 0; k < m_kk; k++) {
01022 if (k != m_indexSolvent) {
01023 ac[k] = m_molalities[k] * exp(m_lnActCoeffMolal_Scaled[k]);
01024 }
01025 }
01026 double xmolSolvent = moleFraction(m_indexSolvent);
01027 ac[m_indexSolvent] =
01028 exp(m_lnActCoeffMolal_Scaled[m_indexSolvent]) * xmolSolvent;
01029
01030
01031
01032
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 void HMWSoln::
01047 getUnscaledMolalityActivityCoefficients(doublereal* acMolality) const {
01048 updateStandardStateThermo();
01049 A_Debye_TP(-1.0, -1.0);
01050 s_update_lnMolalityActCoeff();
01051 std::copy(m_lnActCoeffMolal_Unscaled.begin(), m_lnActCoeffMolal_Unscaled.end(), acMolality);
01052 for (int k = 0; k < m_kk; k++) {
01053 acMolality[k] = exp(acMolality[k]);
01054 }
01055 }
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 void HMWSoln::getChemPotentials(doublereal* mu) const{
01076 double xx;
01077 const double xxSmall = 1.0E-150;
01078
01079
01080
01081
01082
01083
01084 getStandardChemPotentials(mu);
01085
01086
01087
01088
01089 s_update_lnMolalityActCoeff();
01090
01091
01092
01093 doublereal RT = GasConstant * temperature();
01094 double xmolSolvent = moleFraction(m_indexSolvent);
01095 for (int k = 0; k < m_kk; k++) {
01096 if (m_indexSolvent != k) {
01097 xx = MAX(m_molalities[k], xxSmall);
01098 mu[k] += RT * (log(xx) + m_lnActCoeffMolal_Scaled[k]);
01099 }
01100 }
01101 xx = MAX(xmolSolvent, xxSmall);
01102 mu[m_indexSolvent] +=
01103 RT * (log(xx) + m_lnActCoeffMolal_Scaled[m_indexSolvent]);
01104 }
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 void HMWSoln::getPartialMolarEnthalpies(doublereal* hbar) const {
01127
01128
01129
01130 getEnthalpy_RT(hbar);
01131
01132
01133
01134 double T = temperature();
01135 double RT = GasConstant * T;
01136 for (int k = 0; k < m_kk; k++) {
01137 hbar[k] *= RT;
01138 }
01139
01140
01141
01142
01143 s_update_lnMolalityActCoeff();
01144 s_update_dlnMolalityActCoeff_dT();
01145 double RTT = RT * T;
01146 for (int k = 0; k < m_kk; k++) {
01147 hbar[k] -= RTT * m_dlnActCoeffMolaldT_Scaled[k];
01148 }
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 void HMWSoln::
01181 getPartialMolarEntropies(doublereal* sbar) const {
01182 int k;
01183
01184
01185
01186
01187 getEntropy_R(sbar);
01188
01189
01190
01191 doublereal R = GasConstant;
01192 for (k = 0; k < m_kk; k++) {
01193 sbar[k] *= R;
01194 }
01195
01196
01197
01198
01199 s_update_lnMolalityActCoeff();
01200
01201
01202
01203
01204 doublereal mm;
01205 for (k = 0; k < m_kk; k++) {
01206 if (k != m_indexSolvent) {
01207 mm = fmaxx(SmallNumber, m_molalities[k]);
01208 sbar[k] -= R * (log(mm) + m_lnActCoeffMolal_Scaled[k]);
01209 }
01210 }
01211 double xmolSolvent = moleFraction(m_indexSolvent);
01212 mm = fmaxx(SmallNumber, xmolSolvent);
01213 sbar[m_indexSolvent] -= R *(log(mm) + m_lnActCoeffMolal_Scaled[m_indexSolvent]);
01214
01215
01216
01217
01218
01219 s_update_dlnMolalityActCoeff_dT();
01220 double RT = R * temperature();
01221 for (k = 0; k < m_kk; k++) {
01222 sbar[k] -= RT * m_dlnActCoeffMolaldT_Scaled[k];
01223 }
01224 }
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 void HMWSoln::getPartialMolarVolumes(doublereal* vbar) const {
01245
01246
01247
01248 getStandardVolumes(vbar);
01249
01250
01251
01252 s_update_lnMolalityActCoeff();
01253 s_update_dlnMolalityActCoeff_dP();
01254 double T = temperature();
01255 double RT = GasConstant * T;
01256 for (int k = 0; k < m_kk; k++) {
01257 vbar[k] += RT * m_dlnActCoeffMolaldP_Scaled[k];
01258 }
01259 }
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279 void HMWSoln::getPartialMolarCp(doublereal* cpbar) const {
01280
01281
01282
01283
01284 getCp_R(cpbar);
01285
01286 for (int k = 0; k < m_kk; k++) {
01287 cpbar[k] *= GasConstant;
01288 }
01289
01290
01291
01292
01293 s_update_lnMolalityActCoeff();
01294 s_update_dlnMolalityActCoeff_dT();
01295 s_update_d2lnMolalityActCoeff_dT2();
01296 double T = temperature();
01297 double RT = GasConstant * T;
01298 double RTT = RT * T;
01299 for (int k = 0; k < m_kk; k++) {
01300 cpbar[k] -= (2.0 * RT * m_dlnActCoeffMolaldT_Scaled[k] +
01301 RTT * m_d2lnActCoeffMolaldT2_Scaled[k]);
01302 }
01303 }
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344 void HMWSoln::setParameters(int n, doublereal* const c) {
01345 }
01346
01347 void HMWSoln::getParameters(int &n, doublereal * const c) const {
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 void HMWSoln::setParametersFromXML(const XML_Node& eosdata) {
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 doublereal HMWSoln::satPressure(doublereal t) const {
01375 double p_old = pressure();
01376 double t_old = temperature();
01377 double pres = m_waterSS->satPressure(t);
01378
01379
01380
01381 m_waterSS->setState_TP(t_old, p_old);
01382 return pres;
01383 }
01384
01385
01386
01387
01388
01389
01390 double HMWSoln::speciesMolarVolume(int k) const {
01391 double vol = m_speciesSize[k];
01392 if (k == 0) {
01393 double dd = m_waterSS->density();
01394 vol = molecularWeight(0)/dd;
01395 }
01396 return vol;
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419 double HMWSoln::A_Debye_TP(double tempArg, double presArg) const {
01420 double T = temperature();
01421 double A;
01422 if (tempArg != -1.0) {
01423 T = tempArg;
01424 }
01425 double P = pressure();
01426 if (presArg != -1.0) {
01427 P = presArg;
01428 }
01429
01430 switch (m_form_A_Debye) {
01431 case A_DEBYE_CONST:
01432 A = m_A_Debye;
01433 break;
01434 case A_DEBYE_WATER:
01435 A = m_waterProps->ADebye(T, P, 0);
01436 m_A_Debye = A;
01437 break;
01438 default:
01439 printf("shouldn't be here\n");
01440 exit(EXIT_FAILURE);
01441 }
01442 return A;
01443 }
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455 double HMWSoln::dA_DebyedT_TP(double tempArg, double presArg) const {
01456 doublereal T = temperature();
01457 if (tempArg != -1.0) {
01458 T = tempArg;
01459 }
01460 doublereal P = pressure();
01461 if (presArg != -1.0) {
01462 P = presArg;
01463 }
01464 doublereal dAdT;
01465 switch (m_form_A_Debye) {
01466 case A_DEBYE_CONST:
01467 dAdT = 0.0;
01468 break;
01469 case A_DEBYE_WATER:
01470 dAdT = m_waterProps->ADebye(T, P, 1);
01471
01472 break;
01473 default:
01474 printf("shouldn't be here\n");
01475 exit(EXIT_FAILURE);
01476 }
01477 return dAdT;
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 double HMWSoln::dA_DebyedP_TP(double tempArg, double presArg) const {
01491 double T = temperature();
01492 if (tempArg != -1.0) {
01493 T = tempArg;
01494 }
01495 double P = pressure();
01496 if (presArg != -1.0) {
01497 P = presArg;
01498 }
01499 double dAdP;
01500 switch (m_form_A_Debye) {
01501 case A_DEBYE_CONST:
01502 dAdP = 0.0;
01503 break;
01504 case A_DEBYE_WATER:
01505 dAdP = m_waterProps->ADebye(T, P, 3);
01506 break;
01507 default:
01508 printf("shouldn't be here\n");
01509 exit(EXIT_FAILURE);
01510 }
01511 return dAdP;
01512 }
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525 double HMWSoln::ADebye_L(double tempArg, double presArg) const {
01526 double dAdT = dA_DebyedT_TP();
01527 double dAphidT = dAdT /3.0;
01528 double T = temperature();
01529 if (tempArg != -1.0) {
01530 T = tempArg;
01531 }
01532 double retn = dAphidT * (4.0 * GasConstant * T * T);
01533 return retn;
01534 }
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546 double HMWSoln::ADebye_V(double tempArg, double presArg) const {
01547 double dAdP = dA_DebyedP_TP();
01548 double dAphidP = dAdP /3.0;
01549 double T = temperature();
01550 if (tempArg != -1.0) {
01551 T = tempArg;
01552 }
01553 double retn = - dAphidP * (4.0 * GasConstant * T);
01554 return retn;
01555 }
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575 double HMWSoln::ADebye_J(double tempArg, double presArg) const {
01576 double T = temperature();
01577 if (tempArg != -1.0) {
01578 T = tempArg;
01579 }
01580 double A_L = ADebye_L(T, presArg);
01581 double d2 = d2A_DebyedT2_TP(T, presArg);
01582 double d2Aphi = d2 / 3.0;
01583 double retn = 2.0 * A_L / T + 4.0 * GasConstant * T * T *d2Aphi;
01584 return retn;
01585 }
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597 double HMWSoln::d2A_DebyedT2_TP(double tempArg, double presArg) const {
01598 double T = temperature();
01599 if (tempArg != -1.0) {
01600 T = tempArg;
01601 }
01602 double P = pressure();
01603 if (presArg != -1.0) {
01604 P = presArg;
01605 }
01606 double d2AdT2;
01607 switch (m_form_A_Debye) {
01608 case A_DEBYE_CONST:
01609 d2AdT2 = 0.0;
01610 break;
01611 case A_DEBYE_WATER:
01612 d2AdT2 = m_waterProps->ADebye(T, P, 2);
01613 break;
01614 default:
01615 printf("shouldn't be here\n");
01616 exit(EXIT_FAILURE);
01617 }
01618 return d2AdT2;
01619 }
01620
01621
01622
01623
01624
01625
01626
01627
01628 double HMWSoln::AionicRadius(int k) const {
01629 return m_Aionic[k];
01630 }
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640 doublereal HMWSoln::err(std::string msg) const {
01641 throw CanteraError("HMWSoln",
01642 "Unfinished func called: " + msg );
01643 return 0.0;
01644 }
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655 void HMWSoln::initLengths() {
01656 m_kk = nSpecies();
01657
01658
01659
01660
01661
01662 int leng = m_kk;
01663 m_electrolyteSpeciesType.resize(m_kk, cEST_polarNeutral);
01664 m_speciesSize.resize(leng);
01665 m_speciesCharge_Stoich.resize(leng, 0.0);
01666 m_Aionic.resize(leng, 0.0);
01667
01668 m_expg0_RT.resize(leng, 0.0);
01669 m_pe.resize(leng, 0.0);
01670 m_pp.resize(leng, 0.0);
01671 m_tmpV.resize(leng, 0.0);
01672 m_molalitiesCropped.resize(leng, 0.0);
01673
01674 int maxCounterIJlen = 1 + (leng-1) * (leng-2) / 2;
01675
01676
01677
01678
01679
01680 int TCoeffLength = 1;
01681 if (m_formPitzerTemp == PITZER_TEMP_LINEAR) {
01682 TCoeffLength = 2;
01683 } else if (m_formPitzerTemp == PITZER_TEMP_COMPLEX1) {
01684 TCoeffLength = 5;
01685 }
01686
01687 m_Beta0MX_ij.resize(maxCounterIJlen, 0.0);
01688 m_Beta0MX_ij_L.resize(maxCounterIJlen, 0.0);
01689 m_Beta0MX_ij_LL.resize(maxCounterIJlen, 0.0);
01690 m_Beta0MX_ij_P.resize(maxCounterIJlen, 0.0);
01691 m_Beta0MX_ij_coeff.resize(TCoeffLength, maxCounterIJlen, 0.0);
01692
01693 m_Beta1MX_ij.resize(maxCounterIJlen, 0.0);
01694 m_Beta1MX_ij_L.resize(maxCounterIJlen, 0.0);
01695 m_Beta1MX_ij_LL.resize(maxCounterIJlen, 0.0);
01696 m_Beta1MX_ij_P.resize(maxCounterIJlen, 0.0);
01697 m_Beta1MX_ij_coeff.resize(TCoeffLength, maxCounterIJlen, 0.0);
01698
01699 m_Beta2MX_ij.resize(maxCounterIJlen, 0.0);
01700 m_Beta2MX_ij_L.resize(maxCounterIJlen, 0.0);
01701 m_Beta2MX_ij_LL.resize(maxCounterIJlen, 0.0);
01702 m_Beta2MX_ij_P.resize(maxCounterIJlen, 0.0);
01703 m_Beta2MX_ij_coeff.resize(TCoeffLength, maxCounterIJlen, 0.0);
01704
01705 m_CphiMX_ij.resize(maxCounterIJlen, 0.0);
01706 m_CphiMX_ij_L.resize(maxCounterIJlen, 0.0);
01707 m_CphiMX_ij_LL.resize(maxCounterIJlen, 0.0);
01708 m_CphiMX_ij_P.resize(maxCounterIJlen, 0.0);
01709 m_CphiMX_ij_coeff.resize(TCoeffLength, maxCounterIJlen, 0.0);
01710
01711 m_Alpha1MX_ij.resize(maxCounterIJlen, 2.0);
01712 m_Alpha2MX_ij.resize(maxCounterIJlen, 12.0);
01713 m_Theta_ij.resize(maxCounterIJlen, 0.0);
01714 m_Theta_ij_L.resize(maxCounterIJlen, 0.0);
01715 m_Theta_ij_LL.resize(maxCounterIJlen, 0.0);
01716 m_Theta_ij_P.resize(maxCounterIJlen, 0.0);
01717 m_Theta_ij_coeff.resize(TCoeffLength, maxCounterIJlen, 0.0);
01718
01719 int n = m_kk*m_kk*m_kk;
01720 m_Psi_ijk.resize(m_kk*m_kk*m_kk, 0.0);
01721 m_Psi_ijk_L.resize(m_kk*m_kk*m_kk, 0.0);
01722 m_Psi_ijk_LL.resize(m_kk*m_kk*m_kk, 0.0);
01723 m_Psi_ijk_P.resize(m_kk*m_kk*m_kk, 0.0);
01724 m_Psi_ijk_coeff.resize(TCoeffLength, n, 0.0);
01725
01726 m_Lambda_nj.resize(leng, leng, 0.0);
01727 m_Lambda_nj_L.resize(leng, leng, 0.0);
01728 m_Lambda_nj_LL.resize(leng, leng, 0.0);
01729 m_Lambda_nj_P.resize(leng, leng, 0.0);
01730 m_Lambda_nj_coeff.resize(TCoeffLength, leng * leng, 0.0);
01731
01732 m_Mu_nnn.resize(leng, 0.0);
01733 m_Mu_nnn_L.resize(leng, 0.0);
01734 m_Mu_nnn_LL.resize(leng, 0.0);
01735 m_Mu_nnn_P.resize(leng, 0.0);
01736 m_Mu_nnn_coeff.resize(TCoeffLength, leng, 0.0);
01737
01738 m_lnActCoeffMolal_Scaled.resize(leng, 0.0);
01739 m_dlnActCoeffMolaldT_Scaled.resize(leng, 0.0);
01740 m_d2lnActCoeffMolaldT2_Scaled.resize(leng, 0.0);
01741 m_dlnActCoeffMolaldP_Scaled.resize(leng, 0.0);
01742
01743 m_lnActCoeffMolal_Unscaled.resize(leng, 0.0);
01744 m_dlnActCoeffMolaldT_Unscaled.resize(leng, 0.0);
01745 m_d2lnActCoeffMolaldT2_Unscaled.resize(leng, 0.0);
01746 m_dlnActCoeffMolaldP_Unscaled.resize(leng, 0.0);
01747
01748 m_CounterIJ.resize(m_kk*m_kk, 0);
01749
01750 m_gfunc_IJ.resize(maxCounterIJlen, 0.0);
01751 m_g2func_IJ.resize(maxCounterIJlen, 0.0);
01752 m_hfunc_IJ.resize(maxCounterIJlen, 0.0);
01753 m_h2func_IJ.resize(maxCounterIJlen, 0.0);
01754 m_BMX_IJ.resize(maxCounterIJlen, 0.0);
01755 m_BMX_IJ_L.resize(maxCounterIJlen, 0.0);
01756 m_BMX_IJ_LL.resize(maxCounterIJlen, 0.0);
01757 m_BMX_IJ_P.resize(maxCounterIJlen, 0.0);
01758 m_BprimeMX_IJ.resize(maxCounterIJlen, 0.0);
01759 m_BprimeMX_IJ_L.resize(maxCounterIJlen, 0.0);
01760 m_BprimeMX_IJ_LL.resize(maxCounterIJlen, 0.0);
01761 m_BprimeMX_IJ_P.resize(maxCounterIJlen, 0.0);
01762 m_BphiMX_IJ.resize(maxCounterIJlen, 0.0);
01763 m_BphiMX_IJ_L.resize(maxCounterIJlen, 0.0);
01764 m_BphiMX_IJ_LL.resize(maxCounterIJlen, 0.0);
01765 m_BphiMX_IJ_P.resize(maxCounterIJlen, 0.0);
01766 m_Phi_IJ.resize(maxCounterIJlen, 0.0);
01767 m_Phi_IJ_L.resize(maxCounterIJlen, 0.0);
01768 m_Phi_IJ_LL.resize(maxCounterIJlen, 0.0);
01769 m_Phi_IJ_P.resize(maxCounterIJlen, 0.0);
01770 m_Phiprime_IJ.resize(maxCounterIJlen, 0.0);
01771 m_PhiPhi_IJ.resize(maxCounterIJlen, 0.0);
01772 m_PhiPhi_IJ_L.resize(maxCounterIJlen, 0.0);
01773 m_PhiPhi_IJ_LL.resize(maxCounterIJlen, 0.0);
01774 m_PhiPhi_IJ_P.resize(maxCounterIJlen, 0.0);
01775 m_CMX_IJ.resize(maxCounterIJlen, 0.0);
01776 m_CMX_IJ_L.resize(maxCounterIJlen, 0.0);
01777 m_CMX_IJ_LL.resize(maxCounterIJlen, 0.0);
01778 m_CMX_IJ_P.resize(maxCounterIJlen, 0.0);
01779
01780 m_gamma_tmp.resize(leng, 0.0);
01781
01782 IMS_lnActCoeffMolal_.resize(m_kk, 0.0);
01783 CROP_speciesCropped_.resize(m_kk, 0);
01784
01785 counterIJ_setup();
01786 }
01787
01788
01789
01790
01791
01792
01793 void HMWSoln::s_update_lnMolalityActCoeff() const {
01794
01795
01796
01797
01798
01799
01800 calcMolalities();
01801
01802
01803
01804
01805 calcMolalitiesCropped();
01806
01807
01808
01809
01810 m_IionicMolalityStoich = 0.0;
01811 for (int k = 0; k < m_kk; k++) {
01812 double z_k = m_speciesCharge[k];
01813 double zs_k1 = m_speciesCharge_Stoich[k];
01814 if (z_k == zs_k1) {
01815 m_IionicMolalityStoich += m_molalities[k] * z_k * z_k;
01816 } else {
01817 double zs_k2 = z_k - zs_k1;
01818 m_IionicMolalityStoich
01819 += m_molalities[k] * (zs_k1 * zs_k1 + zs_k2 * zs_k2);
01820 }
01821 }
01822
01823
01824
01825
01826
01827
01828 s_updatePitzer_CoeffWRTemp();
01829
01830
01831
01832
01833 s_updateIMS_lnMolalityActCoeff();
01834
01835
01836
01837
01838 s_updatePitzer_lnMolalityActCoeff();
01839
01840 double xmolSolvent = moleFraction(m_indexSolvent);
01841 double xx = MAX(m_xmolSolventMIN, xmolSolvent);
01842 double lnActCoeffMolal0 = - log(xx) + (xx - 1.0)/xx;
01843 double lnxs = log(xx);
01844
01845 for (int k = 1; k < m_kk; k++) {
01846 CROP_speciesCropped_[k] = 0;
01847 m_lnActCoeffMolal_Unscaled[k] += IMS_lnActCoeffMolal_[k];
01848 if (m_lnActCoeffMolal_Unscaled[k] > (CROP_ln_gamma_k_max- 2.5 *lnxs)) {
01849 CROP_speciesCropped_[k] = 2;
01850 m_lnActCoeffMolal_Unscaled[k] = CROP_ln_gamma_k_max - 2.5 * lnxs;
01851 }
01852 if (m_lnActCoeffMolal_Unscaled[k] < (CROP_ln_gamma_k_min - 2.5 *lnxs)) {
01853
01854 CROP_speciesCropped_[k] = 2;
01855 m_lnActCoeffMolal_Unscaled[k] = CROP_ln_gamma_k_min - 2.5 * lnxs;
01856 }
01857 }
01858 CROP_speciesCropped_[0] = 0;
01859 m_lnActCoeffMolal_Unscaled[0] += (IMS_lnActCoeffMolal_[0] - lnActCoeffMolal0);
01860 if (m_lnActCoeffMolal_Unscaled[0] < CROP_ln_gamma_o_min) {
01861 CROP_speciesCropped_[0] = 2;
01862 m_lnActCoeffMolal_Unscaled[0] = CROP_ln_gamma_o_min;
01863 }
01864 if (m_lnActCoeffMolal_Unscaled[0] > CROP_ln_gamma_o_max) {
01865 CROP_speciesCropped_[0] = 2;
01866
01867 m_lnActCoeffMolal_Unscaled[0] = CROP_ln_gamma_o_max;
01868 }
01869 if (m_lnActCoeffMolal_Unscaled[0] > CROP_ln_gamma_o_max - 0.5 * lnxs) {
01870 CROP_speciesCropped_[0] = 2;
01871 m_lnActCoeffMolal_Unscaled[0] = CROP_ln_gamma_o_max - 0.5 * lnxs;
01872 }
01873
01874
01875
01876
01877 s_updateScaling_pHScaling();
01878 }
01879
01880
01881
01882
01883
01884 void HMWSoln::calcMolalitiesCropped() const {
01885 int i, j, k;
01886 doublereal Imax = 0.0, Itmp;
01887 doublereal Iac_max;
01888 m_molalitiesAreCropped = false;
01889
01890 for (k = 0; k < m_kk; k++) {
01891 m_molalitiesCropped[k] = m_molalities[k];
01892 double charge = m_speciesCharge[k];
01893 Itmp = m_molalities[k] * charge * charge;
01894 if (Itmp > Imax) {
01895 Imax = Itmp;
01896 }
01897 }
01898
01899 int cropMethod = 1;
01900
01901
01902 if (cropMethod == 0) {
01903
01904
01905
01906
01907 if (Imax < m_maxIionicStrength) {
01908 return;
01909 }
01910
01911 m_molalitiesAreCropped = true;
01912
01913 for (i = 1; i < (m_kk - 1); i++) {
01914 double charge_i = m_speciesCharge[i];
01915 double abs_charge_i = fabs(charge_i);
01916 if (charge_i == 0.0) {
01917 continue;
01918 }
01919 for (j = (i+1); j < m_kk; j++) {
01920 double charge_j = m_speciesCharge[j];
01921 double abs_charge_j = fabs(charge_j);
01922
01923
01924
01925
01926
01927
01928
01929
01930 if (charge_i * charge_j < 0) {
01931 Iac_max = m_maxIionicStrength;
01932
01933 if (m_molalitiesCropped[i] > m_molalitiesCropped[j]) {
01934 Imax = m_molalitiesCropped[i] * abs_charge_i * abs_charge_i;
01935 if (Imax > Iac_max) {
01936 m_molalitiesCropped[i] = Iac_max / (abs_charge_i * abs_charge_i);
01937 }
01938 Imax = m_molalitiesCropped[j] * fabs(abs_charge_j * abs_charge_i);
01939 if (Imax > Iac_max) {
01940 m_molalitiesCropped[j] = Iac_max / (abs_charge_j * abs_charge_i);
01941 }
01942 } else {
01943 Imax = m_molalitiesCropped[j] * abs_charge_j * abs_charge_j;
01944 if (Imax > Iac_max) {
01945 m_molalitiesCropped[j] = Iac_max / (abs_charge_j * abs_charge_j);
01946 }
01947 Imax = m_molalitiesCropped[i] * abs_charge_j * abs_charge_i;
01948 if (Imax > Iac_max) {
01949 m_molalitiesCropped[i] = Iac_max / (abs_charge_j * abs_charge_i);
01950 }
01951 }
01952 }
01953 }
01954 }
01955
01956
01957
01958
01959
01960 for (int times = 0; times< 10; times++) {
01961 double anion_charge = 0.0;
01962 double cation_charge = 0.0;
01963 int anion_contrib_max_i = -1;
01964 double anion_contrib_max = -1.0;
01965 int cation_contrib_max_i = -1;
01966 double cation_contrib_max = -1.0;
01967 for (i = 0; i < m_kk; i++) {
01968 double charge_i = m_speciesCharge[i];
01969 if (charge_i < 0.0) {
01970 double anion_contrib = - m_molalitiesCropped[i] * charge_i;
01971 anion_charge += anion_contrib ;
01972 if (anion_contrib > anion_contrib_max) {
01973 anion_contrib_max = anion_contrib;
01974 anion_contrib_max_i = i;
01975 }
01976 } else if (charge_i > 0.0) {
01977 double cation_contrib = m_molalitiesCropped[i] * charge_i;
01978 cation_charge += cation_contrib ;
01979 if (cation_contrib > cation_contrib_max) {
01980 cation_contrib_max = cation_contrib;
01981 cation_contrib_max_i = i;
01982 }
01983 }
01984 }
01985 double total_charge = cation_charge - anion_charge;
01986 if (total_charge > 1.0E-8) {
01987 double desiredCrop = total_charge/m_speciesCharge[cation_contrib_max_i];
01988 double maxCrop = 0.66 * m_molalitiesCropped[cation_contrib_max_i];
01989 if (desiredCrop < maxCrop) {
01990 m_molalitiesCropped[cation_contrib_max_i] -= desiredCrop;
01991 break;
01992 } else {
01993 m_molalitiesCropped[cation_contrib_max_i] -= maxCrop;
01994 }
01995 } else if (total_charge < -1.0E-8) {
01996 double desiredCrop = total_charge/m_speciesCharge[anion_contrib_max_i];
01997 double maxCrop = 0.66 * m_molalitiesCropped[anion_contrib_max_i];
01998 if (desiredCrop < maxCrop) {
01999 m_molalitiesCropped[anion_contrib_max_i] -= desiredCrop;
02000 break;
02001 } else {
02002 m_molalitiesCropped[anion_contrib_max_i] -= maxCrop;
02003 }
02004 } else {
02005 break;
02006 }
02007 }
02008 }
02009
02010 if (cropMethod == 1) {
02011 double *molF = DATA_PTR(m_gamma_tmp);
02012 getMoleFractions(molF);
02013 double xmolSolvent = molF[m_indexSolvent];
02014 if (xmolSolvent >= MC_X_o_cutoff_) {
02015 return;
02016 }
02017
02018 m_molalitiesAreCropped = true;
02019
02020 double poly = MC_apCut_ + MC_bpCut_ * xmolSolvent + MC_dpCut_* xmolSolvent * xmolSolvent;
02021 double p = xmolSolvent + MC_epCut_ + exp(- xmolSolvent/ MC_cpCut_) * poly;
02022 double denomInv = 1.0/ (m_Mnaught * p);
02023
02024 for (k = 0; k < m_kk; k++) {
02025 m_molalitiesCropped[k] = molF[k] * denomInv ;
02026 }
02027
02028
02029
02030
02031 Itmp = 0.0;
02032 for (k = 0; k < m_kk; k++) {
02033 double charge = m_speciesCharge[k];
02034 Itmp += m_molalitiesCropped[k] * charge * charge;
02035 }
02036 if (Itmp > m_maxIionicStrength) {
02037 double ratio = Itmp / m_maxIionicStrength;
02038 for (k = 0; k < m_kk; k++) {
02039 double charge = m_speciesCharge[k];
02040 if (charge != 0.0) {
02041 m_molalitiesCropped[k] *= ratio;
02042 }
02043 }
02044 }
02045 }
02046
02047 }
02048
02049
02050
02051
02052
02053
02054
02055
02056 void HMWSoln::counterIJ_setup(void) const {
02057 int n, nc, i, j;
02058 m_CounterIJ.resize(m_kk * m_kk);
02059 int counter = 0;
02060 for (i = 0; i < m_kk; i++) {
02061 n = i;
02062 nc = m_kk * i;
02063 m_CounterIJ[n] = 0;
02064 m_CounterIJ[nc] = 0;
02065 }
02066 for (i = 1; i < (m_kk - 1); i++) {
02067 n = m_kk * i + i;
02068 m_CounterIJ[n] = 0;
02069 for (j = (i+1); j < m_kk; j++) {
02070 n = m_kk * j + i;
02071 nc = m_kk * i + j;
02072 counter++;
02073 m_CounterIJ[n] = counter;
02074 m_CounterIJ[nc] = counter;
02075 }
02076 }
02077 }
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092 void HMWSoln::s_updatePitzer_CoeffWRTemp(int doDerivs) const {
02093
02094 int i, j, n, counterIJ;
02095 const double *beta0MX_coeff;
02096 const double *beta1MX_coeff;
02097 const double *beta2MX_coeff;
02098 const double *CphiMX_coeff;
02099 const double *Theta_coeff;
02100 double T = temperature();
02101 double Tr = m_TempPitzerRef;
02102 double tinv = 0.0, tln = 0.0, tlin = 0.0, tquad = 0.0;
02103 if (m_formPitzerTemp == PITZER_TEMP_LINEAR) {
02104 tlin = T - Tr;
02105 } else if (m_formPitzerTemp == PITZER_TEMP_COMPLEX1) {
02106 tlin = T - Tr;
02107 tquad = T * T - Tr * Tr;
02108 tln = log(T/ Tr);
02109 tinv = 1.0/T - 1.0/Tr;
02110 }
02111
02112 for (i = 1; i < (m_kk - 1); i++) {
02113 for (j = (i+1); j < m_kk; j++) {
02114
02115
02116
02117
02118 n = m_kk*i + j;
02119 counterIJ = m_CounterIJ[n];
02120
02121 beta0MX_coeff = m_Beta0MX_ij_coeff.ptrColumn(counterIJ);
02122 beta1MX_coeff = m_Beta1MX_ij_coeff.ptrColumn(counterIJ);
02123 beta2MX_coeff = m_Beta2MX_ij_coeff.ptrColumn(counterIJ);
02124 CphiMX_coeff = m_CphiMX_ij_coeff.ptrColumn(counterIJ);
02125 Theta_coeff = m_Theta_ij_coeff.ptrColumn(counterIJ);
02126
02127 switch (m_formPitzerTemp) {
02128 case PITZER_TEMP_CONSTANT:
02129 break;
02130 case PITZER_TEMP_LINEAR:
02131
02132 m_Beta0MX_ij[counterIJ] = beta0MX_coeff[0]
02133 + beta0MX_coeff[1]*tlin;
02134 m_Beta0MX_ij_L[counterIJ] = beta0MX_coeff[1];
02135 m_Beta0MX_ij_LL[counterIJ] = 0.0;
02136
02137 m_Beta1MX_ij[counterIJ] = beta1MX_coeff[0]
02138 + beta1MX_coeff[1]*tlin;
02139 m_Beta1MX_ij_L[counterIJ] = beta1MX_coeff[1];
02140 m_Beta1MX_ij_LL[counterIJ] = 0.0;
02141
02142 m_Beta2MX_ij[counterIJ] = beta2MX_coeff[0]
02143 + beta2MX_coeff[1]*tlin;
02144 m_Beta2MX_ij_L[counterIJ] = beta2MX_coeff[1];
02145 m_Beta2MX_ij_LL[counterIJ] = 0.0;
02146
02147 m_CphiMX_ij[counterIJ] = CphiMX_coeff[0]
02148 + CphiMX_coeff[1]*tlin;
02149 m_CphiMX_ij_L[counterIJ] = CphiMX_coeff[1];
02150 m_CphiMX_ij_LL[counterIJ] = 0.0;
02151
02152 m_Theta_ij[counterIJ] = Theta_coeff[0] + Theta_coeff[1]*tlin;
02153 m_Theta_ij_L[counterIJ] = Theta_coeff[1];
02154 m_Theta_ij_LL[counterIJ] = 0.0;
02155
02156 break;
02157
02158 case PITZER_TEMP_COMPLEX1:
02159 m_Beta0MX_ij[counterIJ] = beta0MX_coeff[0]
02160 + beta0MX_coeff[1]*tlin
02161 + beta0MX_coeff[2]*tquad
02162 + beta0MX_coeff[3]*tinv
02163 + beta0MX_coeff[4]*tln;
02164
02165 m_Beta1MX_ij[counterIJ] = beta1MX_coeff[0]
02166 + beta1MX_coeff[1]*tlin
02167 + beta1MX_coeff[2]*tquad
02168 + beta1MX_coeff[3]*tinv
02169 + beta1MX_coeff[4]*tln;
02170
02171 m_Beta2MX_ij[counterIJ] = beta2MX_coeff[0]
02172 + beta2MX_coeff[1]*tlin
02173 + beta2MX_coeff[2]*tquad
02174 + beta2MX_coeff[3]*tinv
02175 + beta2MX_coeff[4]*tln;
02176
02177 m_CphiMX_ij[counterIJ] = CphiMX_coeff[0]
02178 + CphiMX_coeff[1]*tlin
02179 + CphiMX_coeff[2]*tquad
02180 + CphiMX_coeff[3]*tinv
02181 + CphiMX_coeff[4]*tln;
02182
02183 m_Theta_ij[counterIJ] = Theta_coeff[0]
02184 + Theta_coeff[1]*tlin
02185 + Theta_coeff[2]*tquad
02186 + Theta_coeff[3]*tinv
02187 + Theta_coeff[4]*tln;
02188
02189 m_Beta0MX_ij_L[counterIJ] = beta0MX_coeff[1]
02190 + beta0MX_coeff[2]*2.0*T
02191 - beta0MX_coeff[3]/(T*T)
02192 + beta0MX_coeff[4]/T;
02193
02194 m_Beta1MX_ij_L[counterIJ] = beta1MX_coeff[1]
02195 + beta1MX_coeff[2]*2.0*T
02196 - beta1MX_coeff[3]/(T*T)
02197 + beta1MX_coeff[4]/T;
02198
02199 m_Beta2MX_ij_L[counterIJ] = beta2MX_coeff[1]
02200 + beta2MX_coeff[2]*2.0*T
02201 - beta2MX_coeff[3]/(T*T)
02202 + beta2MX_coeff[4]/T;
02203
02204 m_CphiMX_ij_L[counterIJ] = CphiMX_coeff[1]
02205 + CphiMX_coeff[2]*2.0*T
02206 - CphiMX_coeff[3]/(T*T)
02207 + CphiMX_coeff[4]/T;
02208
02209 m_Theta_ij_L[counterIJ] = Theta_coeff[1]
02210 + Theta_coeff[2]*2.0*T
02211 - Theta_coeff[3]/(T*T)
02212 + Theta_coeff[4]/T;
02213
02214 doDerivs = 2;
02215 if (doDerivs > 1) {
02216 m_Beta0MX_ij_LL[counterIJ] =
02217 + beta0MX_coeff[2]*2.0
02218 + 2.0*beta0MX_coeff[3]/(T*T*T)
02219 - beta0MX_coeff[4]/(T*T);
02220
02221 m_Beta1MX_ij_LL[counterIJ] =
02222 + beta1MX_coeff[2]*2.0
02223 + 2.0*beta1MX_coeff[3]/(T*T*T)
02224 - beta1MX_coeff[4]/(T*T);
02225
02226 m_Beta2MX_ij_LL[counterIJ] =
02227 + beta2MX_coeff[2]*2.0
02228 + 2.0*beta2MX_coeff[3]/(T*T*T)
02229 - beta2MX_coeff[4]/(T*T);
02230
02231 m_CphiMX_ij_LL[counterIJ] =
02232 + CphiMX_coeff[2]*2.0
02233 + 2.0*CphiMX_coeff[3]/(T*T*T)
02234 - CphiMX_coeff[4]/(T*T);
02235
02236 m_Theta_ij_LL[counterIJ] =
02237 + Theta_coeff[2]*2.0
02238 + 2.0*Theta_coeff[3]/(T*T*T)
02239 - Theta_coeff[4]/(T*T);
02240 }
02241
02242 #ifdef DEBUG_HKM
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252 #endif
02253 break;
02254 }
02255 }
02256 }
02257
02258
02259
02260
02261 for (i = 1; i < m_kk; i++) {
02262 if (m_speciesCharge[i] == 0.0) {
02263 for (j = 1; j < m_kk; j++) {
02264 n = i * m_kk + j;
02265 const double *Lambda_coeff = m_Lambda_nj_coeff.ptrColumn(n);
02266 switch (m_formPitzerTemp) {
02267 case PITZER_TEMP_CONSTANT:
02268 m_Lambda_nj(i,j) = Lambda_coeff[0];
02269 break;
02270 case PITZER_TEMP_LINEAR:
02271 m_Lambda_nj(i,j) = Lambda_coeff[0] + Lambda_coeff[1]*tlin;
02272 m_Lambda_nj_L(i,j) = Lambda_coeff[1];
02273 m_Lambda_nj_LL(i,j) = 0.0;
02274 case PITZER_TEMP_COMPLEX1:
02275 m_Lambda_nj(i,j) = Lambda_coeff[0]
02276 + Lambda_coeff[1]*tlin
02277 + Lambda_coeff[2]*tquad
02278 + Lambda_coeff[3]*tinv
02279 + Lambda_coeff[4]*tln;
02280
02281 m_Lambda_nj_L(i,j) = Lambda_coeff[1]
02282 + Lambda_coeff[2]*2.0*T
02283 - Lambda_coeff[3]/(T*T)
02284 + Lambda_coeff[4]/T;
02285
02286 m_Lambda_nj_LL(i,j) =
02287 Lambda_coeff[2]*2.0
02288 + 2.0*Lambda_coeff[3]/(T*T*T)
02289 - Lambda_coeff[4]/(T*T);
02290 }
02291
02292 if (j == i) {
02293 const double *Mu_coeff = m_Mu_nnn_coeff.ptrColumn(i);
02294 switch (m_formPitzerTemp) {
02295 case PITZER_TEMP_CONSTANT:
02296 m_Mu_nnn[i] = Mu_coeff[0];
02297 break;
02298 case PITZER_TEMP_LINEAR:
02299 m_Mu_nnn[i] = Mu_coeff[0] + Mu_coeff[1]*tlin;
02300 m_Mu_nnn_L[i] = Mu_coeff[1];
02301 m_Mu_nnn_LL[i] = 0.0;
02302 case PITZER_TEMP_COMPLEX1:
02303 m_Mu_nnn[i] = Mu_coeff[0]
02304 + Mu_coeff[1]*tlin
02305 + Mu_coeff[2]*tquad
02306 + Mu_coeff[3]*tinv
02307 + Mu_coeff[4]*tln;
02308
02309 m_Mu_nnn_L[i] = Mu_coeff[1]
02310 + Mu_coeff[2]*2.0*T
02311 - Mu_coeff[3]/(T*T)
02312 + Mu_coeff[4]/T;
02313
02314 m_Mu_nnn_LL[i] =
02315 Mu_coeff[2]*2.0
02316 + 2.0*Mu_coeff[3]/(T*T*T)
02317 - Mu_coeff[4]/(T*T);
02318 }
02319 }
02320 }
02321 }
02322 }
02323
02324
02325 for (i = 1; i < m_kk; i++) {
02326 for (j = 1; j < m_kk; j++) {
02327 for (int k = 1; k < m_kk; k++) {
02328 n = i * m_kk *m_kk + j * m_kk + k ;
02329 const double *Psi_coeff = m_Psi_ijk_coeff.ptrColumn(n);
02330 switch (m_formPitzerTemp) {
02331 case PITZER_TEMP_CONSTANT:
02332 m_Psi_ijk[n] = Psi_coeff[0];
02333 break;
02334 case PITZER_TEMP_LINEAR:
02335 m_Psi_ijk[n] = Psi_coeff[0] + Psi_coeff[1]*tlin;
02336 m_Psi_ijk_L[n] = Psi_coeff[1];
02337 m_Psi_ijk_LL[n] = 0.0;
02338 case PITZER_TEMP_COMPLEX1:
02339 m_Psi_ijk[n] = Psi_coeff[0]
02340 + Psi_coeff[1]*tlin
02341 + Psi_coeff[2]*tquad
02342 + Psi_coeff[3]*tinv
02343 + Psi_coeff[4]*tln;
02344
02345 m_Psi_ijk_L[n] = Psi_coeff[1]
02346 + Psi_coeff[2]*2.0*T
02347 - Psi_coeff[3]/(T*T)
02348 + Psi_coeff[4]/T;
02349
02350 m_Psi_ijk_LL[n] =
02351 Psi_coeff[2]*2.0
02352 + 2.0*Psi_coeff[3]/(T*T*T)
02353 - Psi_coeff[4]/(T*T);
02354 }
02355 }
02356 }
02357 }
02358
02359 }
02360
02361
02362
02363
02364
02365
02366
02367
02368 void HMWSoln::
02369 s_updatePitzer_lnMolalityActCoeff() const {
02370
02371
02372
02373
02374
02375 if (m_indexSolvent != 0) {
02376 printf("Wrong index solvent value!\n");
02377 exit(EXIT_FAILURE);
02378 }
02379
02380 #ifdef DEBUG_MODE
02381 int printE = 0;
02382 if (temperature() == 323.15) {
02383 printE = 0;
02384 }
02385 #endif
02386 double wateract;
02387 std::string sni, snj, snk;
02388
02389
02390
02391
02392 const double *molality = DATA_PTR(m_molalitiesCropped);
02393
02394
02395
02396 const double *charge = DATA_PTR(m_speciesCharge);
02397
02398
02399
02400
02401
02402 const double *beta0MX = DATA_PTR(m_Beta0MX_ij);
02403 const double *beta1MX = DATA_PTR(m_Beta1MX_ij);
02404 const double *beta2MX = DATA_PTR(m_Beta2MX_ij);
02405 const double *CphiMX = DATA_PTR(m_CphiMX_ij);
02406 const double *thetaij = DATA_PTR(m_Theta_ij);
02407 const double *alpha1MX = DATA_PTR(m_Alpha1MX_ij);
02408 const double *alpha2MX = DATA_PTR(m_Alpha2MX_ij);
02409
02410 const double *psi_ijk = DATA_PTR(m_Psi_ijk);
02411
02412
02413
02414 double *gamma_Unscaled = DATA_PTR(m_gamma_tmp);
02415
02416
02417
02418 double etheta[5][5], etheta_prime[5][5], sqrtIs;
02419
02420
02421
02422 double Is = 0.0;
02423
02424
02425
02426
02427 double molarcharge = 0.0;
02428
02429
02430
02431
02432 double molalitysumUncropped = 0.0;
02433
02434 double *gfunc = DATA_PTR(m_gfunc_IJ);
02435 double *g2func = DATA_PTR(m_g2func_IJ);
02436 double *hfunc = DATA_PTR(m_hfunc_IJ);
02437 double *h2func = DATA_PTR(m_h2func_IJ);
02438 double *BMX = DATA_PTR(m_BMX_IJ);
02439 double *BprimeMX = DATA_PTR(m_BprimeMX_IJ);
02440 double *BphiMX = DATA_PTR(m_BphiMX_IJ);
02441 double *Phi = DATA_PTR(m_Phi_IJ);
02442 double *Phiprime = DATA_PTR(m_Phiprime_IJ);
02443 double *Phiphi = DATA_PTR(m_PhiPhi_IJ);
02444 double *CMX = DATA_PTR(m_CMX_IJ);
02445
02446
02447 double x1, x2;
02448 double Aphi, F, zsqF;
02449 double sum1, sum2, sum3, sum4, sum5, term1;
02450 double sum_m_phi_minus_1, osmotic_coef, lnwateract;
02451
02452 int z1, z2;
02453 int n, i, j, k, m, counterIJ, counterIJ2;
02454
02455 #ifdef DEBUG_MODE
02456 if (m_debugCalc) {
02457 printf("\n Debugging information from hmw_act \n");
02458 }
02459 #endif
02460
02461
02462
02463 counterIJ_setup();
02464
02465
02466
02467
02468 for (n = 1; n < m_kk; n++) {
02469
02470 Is += charge[n] * charge[n] * molality[n];
02471
02472 molarcharge += fabs(charge[n]) * molality[n];
02473 molalitysumUncropped += m_molalities[n];
02474 }
02475 Is *= 0.5;
02476
02477
02478
02479
02480 m_IionicMolality = Is;
02481 sqrtIs = sqrt(Is);
02482 #ifdef DEBUG_MODE
02483 if (m_debugCalc) {
02484 printf(" Step 1: \n");
02485 printf(" ionic strenth = %14.7le \n total molar "
02486 "charge = %14.7le \n", Is, molarcharge);
02487 }
02488 #endif
02489
02490
02491
02492
02493
02494
02495 calc_lambdas(Is);
02496
02497
02498
02499
02500
02501
02502 #ifdef DEBUG_MODE
02503 if (m_debugCalc) {
02504 printf(" Step 2: \n");
02505 }
02506 #endif
02507 for (z1 = 1; z1 <=4; z1++) {
02508 for (z2 =1; z2 <=4; z2++) {
02509 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
02510 #ifdef DEBUG_MODE
02511 if (m_debugCalc) {
02512 printf(" z1=%3d z2=%3d E-theta(I) = %f, E-thetaprime(I) = %f\n",
02513 z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
02514 }
02515 #endif
02516 }
02517 }
02518
02519 #ifdef DEBUG_MODE
02520 if (m_debugCalc) {
02521 printf(" Step 3: \n");
02522 printf(" Species Species g(x) "
02523 " hfunc(x) \n");
02524 }
02525 #endif
02526
02527
02528
02529
02530
02531
02532
02533 for (i = 1; i < (m_kk - 1); i++) {
02534 for (j = (i+1); j < m_kk; j++) {
02535
02536
02537
02538 n = m_kk*i + j;
02539 counterIJ = m_CounterIJ[n];
02540
02541
02542
02543
02544 if (charge[i]*charge[j] < 0) {
02545
02546
02547
02548 x1 = sqrtIs * alpha1MX[counterIJ];
02549 if (x1 > 1.0E-100) {
02550 gfunc[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
02551 hfunc[counterIJ] = -2.0 *
02552 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
02553 }
02554 else {
02555 gfunc[counterIJ] = 0.0;
02556 hfunc[counterIJ] = 0.0;
02557 }
02558
02559 if (beta2MX[counterIJ] != 0.0) {
02560 x2 = sqrtIs * alpha2MX[counterIJ];
02561 if (x2 > 1.0E-100) {
02562 g2func[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
02563 h2func[counterIJ] = -2.0 *
02564 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
02565 } else {
02566 g2func[counterIJ] = 0.0;
02567 h2func[counterIJ] = 0.0;
02568 }
02569 }
02570 }
02571 else {
02572 gfunc[counterIJ] = 0.0;
02573 hfunc[counterIJ] = 0.0;
02574 }
02575 #ifdef DEBUG_MODE
02576 if (m_debugCalc) {
02577 sni = speciesName(i);
02578 snj = speciesName(j);
02579 printf(" %-16s %-16s %9.5f %9.5f \n", sni.c_str(), snj.c_str(),
02580 gfunc[counterIJ], hfunc[counterIJ]);
02581 }
02582 #endif
02583 }
02584 }
02585
02586
02587
02588
02589
02590 #ifdef DEBUG_MODE
02591 if (m_debugCalc) {
02592 printf(" Step 4: \n");
02593 printf(" Species Species BMX "
02594 "BprimeMX BphiMX \n");
02595 }
02596 #endif
02597
02598 for (i = 1; i < m_kk - 1; i++) {
02599 for (j = i+1; j < m_kk; j++) {
02600
02601
02602
02603 n = m_kk*i + j;
02604 counterIJ = m_CounterIJ[n];
02605
02606 #ifdef DEBUG_MODE
02607 if (printE) {
02608 if (counterIJ == 2) {
02609 printf("%s %s\n", speciesName(i).c_str(),
02610 speciesName(j).c_str());
02611 printf("beta0MX[%d] = %g\n", counterIJ, beta0MX[counterIJ]);
02612 printf("beta1MX[%d] = %g\n", counterIJ, beta1MX[counterIJ]);
02613 printf("beta2MX[%d] = %g\n", counterIJ, beta2MX[counterIJ]);
02614 }
02615 }
02616 #endif
02617
02618
02619
02620
02621 if (charge[i]*charge[j] < 0.0) {
02622 BMX[counterIJ] = beta0MX[counterIJ]
02623 + beta1MX[counterIJ] * gfunc[counterIJ]
02624 + beta2MX[counterIJ] * g2func[counterIJ];
02625 #ifdef DEBUG_MODE
02626 if (m_debugCalc) {
02627 printf("%d %g: %g %g %g %g\n",
02628 counterIJ, BMX[counterIJ], beta0MX[counterIJ],
02629 beta1MX[counterIJ], beta2MX[counterIJ], gfunc[counterIJ]);
02630 }
02631 #endif
02632 if (Is > 1.0E-150) {
02633 BprimeMX[counterIJ] = (beta1MX[counterIJ] * hfunc[counterIJ]/Is +
02634 beta2MX[counterIJ] * h2func[counterIJ]/Is);
02635 } else {
02636 BprimeMX[counterIJ] = 0.0;
02637 }
02638 BphiMX[counterIJ] = BMX[counterIJ] + Is*BprimeMX[counterIJ];
02639 }
02640 else {
02641 BMX[counterIJ] = 0.0;
02642 BprimeMX[counterIJ] = 0.0;
02643 BphiMX[counterIJ] = 0.0;
02644 }
02645 #ifdef DEBUG_MODE
02646 if (m_debugCalc) {
02647 sni = speciesName(i);
02648 snj = speciesName(j);
02649 printf(" %-16s %-16s %11.7f %11.7f %11.7f \n",
02650 sni.c_str(), snj.c_str(),
02651 BMX[counterIJ], BprimeMX[counterIJ], BphiMX[counterIJ] );
02652 }
02653 #endif
02654 }
02655 }
02656
02657
02658
02659
02660
02661 #ifdef DEBUG_MODE
02662 if (m_debugCalc) {
02663 printf(" Step 5: \n");
02664 printf(" Species Species CMX \n");
02665 }
02666 #endif
02667 for (i = 1; i < m_kk-1; i++) {
02668 for (j = i+1; j < m_kk; j++) {
02669
02670
02671
02672 n = m_kk*i + j;
02673 counterIJ = m_CounterIJ[n];
02674
02675
02676
02677
02678 if (charge[i]*charge[j] < 0.0) {
02679 CMX[counterIJ] = CphiMX[counterIJ]/
02680 (2.0* sqrt(fabs(charge[i]*charge[j])));
02681 }
02682 else {
02683 CMX[counterIJ] = 0.0;
02684 }
02685 #ifdef DEBUG_MODE
02686 if (printE) {
02687 if (counterIJ == 2) {
02688 printf("%s %s\n", speciesName(i).c_str(),
02689 speciesName(j).c_str());
02690 printf("CphiMX[%d] = %g\n", counterIJ, CphiMX[counterIJ]);
02691 }
02692 }
02693 #endif
02694 #ifdef DEBUG_MODE
02695 if (m_debugCalc) {
02696 sni = speciesName(i);
02697 snj = speciesName(j);
02698 printf(" %-16s %-16s %11.7f \n", sni.c_str(), snj.c_str(),
02699 CMX[counterIJ]);
02700 }
02701 #endif
02702 }
02703 }
02704
02705
02706
02707
02708
02709 #ifdef DEBUG_MODE
02710 if (m_debugCalc) {
02711 printf(" Step 6: \n");
02712 printf(" Species Species Phi_ij "
02713 " Phiprime_ij Phi^phi_ij \n");
02714 }
02715 #endif
02716 for (i = 1; i < m_kk-1; i++) {
02717 for (j = i+1; j < m_kk; j++) {
02718
02719
02720
02721 n = m_kk*i + j;
02722 counterIJ = m_CounterIJ[n];
02723
02724
02725
02726
02727 if (charge[i]*charge[j] > 0) {
02728 z1 = (int) fabs(charge[i]);
02729 z2 = (int) fabs(charge[j]);
02730 Phi[counterIJ] = thetaij[counterIJ] + etheta[z1][z2];
02731 Phiprime[counterIJ] = etheta_prime[z1][z2];
02732 Phiphi[counterIJ] = Phi[counterIJ] + Is * Phiprime[counterIJ];
02733 }
02734 else {
02735 Phi[counterIJ] = 0.0;
02736 Phiprime[counterIJ] = 0.0;
02737 Phiphi[counterIJ] = 0.0;
02738 }
02739 #ifdef DEBUG_MODE
02740 if (m_debugCalc) {
02741 sni = speciesName(i);
02742 snj = speciesName(j);
02743 printf(" %-16s %-16s %10.6f %10.6f %10.6f \n",
02744 sni.c_str(), snj.c_str(),
02745 Phi[counterIJ], Phiprime[counterIJ], Phiphi[counterIJ] );
02746 }
02747 #endif
02748 }
02749 }
02750
02751
02752
02753
02754
02755 #ifdef DEBUG_MODE
02756 if (m_debugCalc) {
02757 printf(" Step 7: \n");
02758 }
02759 #endif
02760
02761
02762
02763
02764 Aphi = m_A_Debye / 3.0;
02765 F = -Aphi * ( sqrt(Is) / (1.0 + 1.2*sqrt(Is))
02766 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
02767 #ifdef DEBUG_MODE
02768 if (printE) {
02769 printf("Aphi = %20.13g\n", Aphi);
02770 }
02771 #endif
02772 #ifdef DEBUG_MODE
02773 if (m_debugCalc) {
02774 printf(" initial value of F = %10.6f \n", F );
02775 }
02776 #endif
02777 for (i = 1; i < m_kk-1; i++) {
02778 for (j = i+1; j < m_kk; j++) {
02779
02780
02781
02782 n = m_kk*i + j;
02783 counterIJ = m_CounterIJ[n];
02784
02785
02786
02787
02788 if (charge[i]*charge[j] < 0) {
02789 F = F + molality[i]*molality[j] * BprimeMX[counterIJ];
02790 }
02791
02792
02793
02794
02795 if (charge[i]*charge[j] > 0) {
02796 F = F + molality[i]*molality[j] * Phiprime[counterIJ];
02797 }
02798 #ifdef DEBUG_MODE
02799 if (m_debugCalc) printf(" F = %10.6f \n", F );
02800 #endif
02801 }
02802 }
02803 #ifdef DEBUG_MODE
02804 if (m_debugCalc) {
02805 printf(" Step 8: Summing in All Contributions to Activity Coefficients \n");
02806 }
02807 #endif
02808
02809 for (i = 1; i < m_kk; i++) {
02810
02811
02812
02813
02814
02815
02816 if (charge[i] > 0.0 ) {
02817
02818 #ifdef DEBUG_MODE
02819 if (m_debugCalc) {
02820 sni = speciesName(i);
02821 printf(" Contributions to ln(ActCoeff_%s):\n", sni.c_str());
02822 }
02823 #endif
02824
02825 zsqF = charge[i]*charge[i]*F;
02826 #ifdef DEBUG_MODE
02827 if (m_debugCalc) {
02828 printf(" Unary term: z*z*F = %10.5f\n", zsqF);
02829 }
02830 #endif
02831 sum1 = 0.0;
02832 sum2 = 0.0;
02833 sum3 = 0.0;
02834 sum4 = 0.0;
02835 sum5 = 0.0;
02836 for (j = 1; j < m_kk; j++) {
02837
02838
02839
02840 n = m_kk*i + j;
02841 counterIJ = m_CounterIJ[n];
02842
02843 if (charge[j] < 0.0) {
02844
02845 sum1 = sum1 + molality[j]*
02846 (2.0*BMX[counterIJ] + molarcharge*CMX[counterIJ]);
02847 #ifdef DEBUG_MODE
02848 if (m_debugCalc) {
02849 snj = speciesName(j) + ":";
02850 printf(" Bin term with %-13s 2 m_j BMX = %10.5f\n", snj.c_str(),
02851 molality[j]*2.0*BMX[counterIJ]);
02852 printf(" m_j Z CMX = %10.5f\n",
02853 molality[j]* molarcharge*CMX[counterIJ]);
02854 }
02855 #endif
02856 if (j < m_kk-1) {
02857
02858
02859
02860
02861
02862 for (k = j+1; k < m_kk; k++) {
02863
02864 if (charge[k] < 0.0) {
02865 n = k + j * m_kk + i * m_kk * m_kk;
02866 sum3 = sum3 + molality[j]*molality[k]*psi_ijk[n];
02867 #ifdef DEBUG_MODE
02868 if (m_debugCalc) {
02869 if (psi_ijk[n] != 0.0) {
02870 snj = speciesName(j) + "," + speciesName(k) + ":";
02871 printf(" Psi term on %-16s m_j m_k psi_ijk = %10.5f\n", snj.c_str(),
02872 molality[j]*molality[k]*psi_ijk[n]);
02873 }
02874 }
02875 #endif
02876 }
02877 }
02878 }
02879 }
02880
02881
02882 if (charge[j] > 0.0) {
02883
02884 if (j != i) {
02885 sum2 = sum2 + molality[j]*(2.0*Phi[counterIJ]);
02886 #ifdef DEBUG_MODE
02887 if (m_debugCalc) {
02888 if ((molality[j] * Phi[counterIJ])!= 0.0) {
02889 snj = speciesName(j) + ":";
02890 printf(" Phi term with %-12s 2 m_j Phi_cc = %10.5f\n", snj.c_str(),
02891 molality[j]*(2.0*Phi[counterIJ]));
02892 }
02893 }
02894 #endif
02895 }
02896 for (k = 1; k < m_kk; k++) {
02897 if (charge[k] < 0.0) {
02898
02899
02900 n = k + j * m_kk + i * m_kk * m_kk;
02901 sum2 = sum2 + molality[j]*molality[k]*psi_ijk[n];
02902 #ifdef DEBUG_MODE
02903 if (m_debugCalc) {
02904 if (psi_ijk[n] != 0.0) {
02905 snj = speciesName(j) + "," + speciesName(k) + ":";
02906 printf(" Psi term on %-16s m_j m_k psi_ijk = %10.5f\n", snj.c_str(),
02907 molality[j]*molality[k]*psi_ijk[n]);
02908 }
02909 }
02910 #endif
02911
02912
02913
02914 n = m_kk*j + k;
02915 counterIJ2 = m_CounterIJ[n];
02916 sum4 = sum4 + (fabs(charge[i])*
02917 molality[j]*molality[k]*CMX[counterIJ2]);
02918 #ifdef DEBUG_MODE
02919 if (m_debugCalc) {
02920 if ((molality[j]*molality[k]*CMX[counterIJ2]) != 0.0) {
02921 snj = speciesName(j) + "," + speciesName(k) + ":";
02922 printf(" Tern CMX term on %-16s abs(z_i) m_j m_k CMX = %10.5f\n", snj.c_str(),
02923 fabs(charge[i])* molality[j]*molality[k]*CMX[counterIJ2]);
02924 }
02925 }
02926 #endif
02927 }
02928 }
02929 }
02930
02931
02932
02933
02934 if (charge[j] == 0) {
02935 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj(j,i);
02936 #ifdef DEBUG_MODE
02937 if (m_debugCalc) {
02938 if ((molality[j]*2.0*m_Lambda_nj(j,i)) != 0.0) {
02939 snj = speciesName(j) + ":";
02940 printf(" Lambda term with %-12s 2 m_j lam_ji = %10.5f\n", snj.c_str(),
02941 molality[j]*2.0*m_Lambda_nj(j,i));
02942 }
02943 }
02944 #endif
02945
02946
02947
02948 for (int k = 1; k < m_kk; k++) {
02949 if (charge[k] < 0.0) {
02950 int izeta = j;
02951 int jzeta = i;
02952 n = izeta * m_kk * m_kk + jzeta * m_kk + k;
02953 double zeta = psi_ijk[n];
02954 if (zeta != 0.0) {
02955 sum5 = sum5 + molality[j]*molality[k]*zeta;
02956 #ifdef DEBUG_MODE
02957 if (m_debugCalc) {
02958 snj = speciesName(j) + "," + speciesName(k) + ":";
02959 printf(" Zeta term on %-16s m_n m_a zeta_nMa = %10.5f\n", snj.c_str(),
02960 molality[j]*molality[k]*psi_ijk[n]);
02961 }
02962 #endif
02963 }
02964 }
02965 }
02966 }
02967 }
02968
02969
02970
02971
02972 m_lnActCoeffMolal_Unscaled[i] = zsqF + sum1 + sum2 + sum3 + sum4 + sum5;
02973 gamma_Unscaled[i] = exp(m_lnActCoeffMolal_Unscaled[i]);
02974 #ifdef DEBUG_MODE
02975 if (m_debugCalc) {
02976 sni = speciesName(i);
02977 printf(" Net %-16s lngamma[i] = %9.5f gamma[i]=%10.6f \n",
02978 sni.c_str(), m_lnActCoeffMolal_Unscaled[i], gamma_Unscaled[i]);
02979 }
02980 #endif
02981 }
02982
02983
02984
02985
02986
02987
02988 if (charge[i] < 0 ) {
02989
02990 #ifdef DEBUG_MODE
02991 if (m_debugCalc) {
02992 sni = speciesName(i);
02993 printf(" Contributions to ln(ActCoeff_%s):\n", sni.c_str());
02994 }
02995 #endif
02996
02997
02998 zsqF = charge[i]*charge[i]*F;
02999 #ifdef DEBUG_MODE
03000 if (m_debugCalc) {
03001 printf(" Unary term: z*z*F = %10.5f\n", zsqF);
03002 }
03003 #endif
03004 sum1 = 0.0;
03005 sum2 = 0.0;
03006 sum3 = 0.0;
03007 sum4 = 0.0;
03008 sum5 = 0.0;
03009 for (j = 1; j < m_kk; j++) {
03010
03011
03012
03013 n = m_kk*i + j;
03014 counterIJ = m_CounterIJ[n];
03015
03016
03017
03018
03019 if (charge[j] > 0) {
03020 sum1 = sum1 + molality[j]*
03021 (2.0*BMX[counterIJ]+molarcharge*CMX[counterIJ]);
03022 #ifdef DEBUG_MODE
03023 if (m_debugCalc) {
03024 snj = speciesName(j) + ":";
03025 printf(" Bin term with %-13s 2 m_j BMX = %10.5f\n", snj.c_str(),
03026 molality[j]*2.0*BMX[counterIJ]);
03027 printf(" m_j Z CMX = %10.5f\n",
03028 molality[j]* molarcharge*CMX[counterIJ]);
03029 }
03030 #endif
03031 if (j < m_kk-1) {
03032 for (k = j+1; k < m_kk; k++) {
03033
03034 if (charge[k] > 0) {
03035 n = k + j * m_kk + i * m_kk * m_kk;
03036 sum3 = sum3 + molality[j]*molality[k]*psi_ijk[n];
03037 #ifdef DEBUG_MODE
03038 if (m_debugCalc) {
03039 if (psi_ijk[n] != 0.0) {
03040 snj = speciesName(j) + "," + speciesName(k) + ":";
03041 printf(" Psi term on %-16s m_j m_k psi_ijk = %10.5f\n", snj.c_str(),
03042 molality[j]*molality[k]*psi_ijk[n]);
03043 }
03044 }
03045 #endif
03046 }
03047 }
03048 }
03049 }
03050
03051
03052
03053
03054 if (charge[j] < 0.0) {
03055
03056 if (j != i) {
03057 sum2 = sum2 + molality[j]*(2.0*Phi[counterIJ]);
03058 #ifdef DEBUG_MODE
03059 if (m_debugCalc) {
03060 if ((molality[j] * Phi[counterIJ])!= 0.0) {
03061 snj = speciesName(j) + ":";
03062 printf(" Phi term with %-12s 2 m_j Phi_aa = %10.5f\n", snj.c_str(),
03063 molality[j]*(2.0*Phi[counterIJ]));
03064 }
03065 }
03066 #endif
03067 }
03068 for (k = 1; k < m_kk; k++) {
03069 if (charge[k] > 0.0) {
03070
03071 n = k + j * m_kk + i * m_kk * m_kk;
03072 sum2 = sum2 + molality[j]*molality[k]*psi_ijk[n];
03073 #ifdef DEBUG_MODE
03074 if (m_debugCalc) {
03075 if (psi_ijk[n] != 0.0) {
03076 snj = speciesName(j) + "," + speciesName(k) + ":";
03077 printf(" Psi term on %-16s m_j m_k psi_ijk = %10.5f\n", snj.c_str(),
03078 molality[j]*molality[k]*psi_ijk[n]);
03079 }
03080 }
03081 #endif
03082
03083
03084
03085 n = m_kk*j + k;
03086 counterIJ2 = m_CounterIJ[n];
03087 sum4 = sum4 +
03088 (fabs(charge[i])*
03089 molality[j]*molality[k]*CMX[counterIJ2]);
03090 #ifdef DEBUG_MODE
03091 if (m_debugCalc) {
03092 if ((molality[j]*molality[k]*CMX[counterIJ2]) != 0.0) {
03093 snj = speciesName(j) + "," + speciesName(k) + ":";
03094 printf(" Tern CMX term on %-16s abs(z_i) m_j m_k CMX = %10.5f\n", snj.c_str(),
03095 fabs(charge[i])* molality[j]*molality[k]*CMX[counterIJ2]);
03096 }
03097 }
03098 #endif
03099 }
03100 }
03101 }
03102
03103
03104
03105
03106 if (charge[j] == 0.0) {
03107 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj(j,i);
03108 #ifdef DEBUG_MODE
03109 if (m_debugCalc) {
03110 if ((molality[j]*2.0*m_Lambda_nj(j,i)) != 0.0) {
03111 snj = speciesName(j) + ":";
03112 printf(" Lambda term with %-12s 2 m_j lam_ji = %10.5f\n", snj.c_str(),
03113 molality[j]*2.0*m_Lambda_nj(j,i));
03114 }
03115 }
03116 #endif
03117
03118
03119
03120 for (int k = 1; k < m_kk; k++) {
03121 if (charge[k] > 0.0) {
03122 int izeta = j;
03123 int jzeta = k;
03124 int kzeta = i;
03125 n = izeta * m_kk * m_kk + jzeta * m_kk + kzeta;
03126 double zeta = psi_ijk[n];
03127 if (zeta != 0.0) {
03128 sum5 = sum5 + molality[j]*molality[k]*zeta;
03129 #ifdef DEBUG_MODE
03130 if (m_debugCalc) {
03131 snj = speciesName(j) + "," + speciesName(k) + ":";
03132 printf(" Zeta term on %-16s m_n m_c zeta_ncX = %10.5f\n", snj.c_str(),
03133 molality[j]*molality[k]*psi_ijk[n]);
03134 }
03135 #endif
03136 }
03137 }
03138 }
03139 }
03140 }
03141 m_lnActCoeffMolal_Unscaled[i] = zsqF + sum1 + sum2 + sum3 + sum4 + sum5;
03142 gamma_Unscaled[i] = exp(m_lnActCoeffMolal_Unscaled[i]);
03143 #ifdef DEBUG_MODE
03144 if (m_debugCalc) {
03145 sni = speciesName(i);
03146 printf(" Net %-16s lngamma[i] = %9.5f gamma[i]=%10.6f\n",
03147 sni.c_str(), m_lnActCoeffMolal_Unscaled[i], gamma_Unscaled[i]);
03148 }
03149 #endif
03150 }
03151
03152
03153
03154
03155
03156 if (charge[i] == 0.0) {
03157 #ifdef DEBUG_MODE
03158 if (m_debugCalc) {
03159 sni = speciesName(i);
03160 printf(" Contributions to ln(ActCoeff_%s):\n", sni.c_str());
03161 }
03162 #endif
03163 sum1 = 0.0;
03164 sum3 = 0.0;
03165 for (j = 1; j < m_kk; j++) {
03166 sum1 = sum1 + molality[j]*2.0*m_Lambda_nj(i,j);
03167 #ifdef DEBUG_MODE
03168 if (m_debugCalc) {
03169 if (m_Lambda_nj(i,j) != 0.0) {
03170 snj = speciesName(j) + ":";
03171 printf(" Lambda_n term on %-16s 2 m_j lambda_n_j = %10.5f\n", snj.c_str(),
03172 molality[j]*2.0*m_Lambda_nj(i,j));
03173 }
03174 }
03175 #endif
03176
03177
03178
03179
03180 if (charge[j] > 0.0) {
03181 for (k = 1; k < m_kk; k++) {
03182 if (charge[k] < 0.0) {
03183 n = k + j * m_kk + i * m_kk * m_kk;
03184 sum3 = sum3 + molality[j]*molality[k]*psi_ijk[n];
03185 #ifdef DEBUG_MODE
03186 if (m_debugCalc) {
03187 if (psi_ijk[n] != 0.0) {
03188 snj = speciesName(j) + "," + speciesName(k) + ":";
03189 printf(" Zeta term on %-16s m_j m_k psi_ijk = %10.5f\n", snj.c_str(),
03190 molality[j]*molality[k]*psi_ijk[n]);
03191 }
03192 }
03193 #endif
03194 }
03195 }
03196 }
03197 }
03198 sum2 = 3.0 * molality[i]* molality[i] * m_Mu_nnn[i];
03199 #ifdef DEBUG_MODE
03200 if (m_debugCalc) {
03201 if (m_Mu_nnn[i] != 0.0) {
03202 printf(" Mu_nnn term 3 m_n m_n Mu_n_n = %10.5f\n",
03203 3.0 * molality[i]* molality[i] * m_Mu_nnn[i]);
03204 }
03205 }
03206 #endif
03207
03208 m_lnActCoeffMolal_Unscaled[i] = sum1 + sum2 + sum3;
03209 gamma_Unscaled[i] = exp(m_lnActCoeffMolal_Unscaled[i]);
03210 #ifdef DEBUG_MODE
03211 if (m_debugCalc) {
03212 sni = speciesName(i);
03213 printf(" Net %-16s lngamma[i] = %9.5f gamma[i]=%10.6f\n",
03214 sni.c_str(), m_lnActCoeffMolal_Unscaled[i], gamma_Unscaled[i]);
03215 }
03216 #endif
03217 }
03218
03219 }
03220 #ifdef DEBUG_MODE
03221 if (m_debugCalc) {
03222 printf(" Step 9: \n");
03223 }
03224 #endif
03225
03226
03227
03228
03229
03230 sum1 = 0.0;
03231 sum2 = 0.0;
03232 sum3 = 0.0;
03233 sum4 = 0.0;
03234 sum5 = 0.0;
03235 double sum6 = 0.0;
03236 double sum7 = 0.0;
03237
03238
03239
03240
03241
03242
03243
03244 term1 = -Aphi * pow(Is,1.5) / (1.0 + 1.2 * sqrt(Is));
03245
03246 for (j = 1; j < m_kk; j++) {
03247
03248
03249
03250 if (charge[j] > 0.0) {
03251 for (k = 1; k < m_kk; k++){
03252 if (charge[k] < 0.0) {
03253
03254
03255
03256 n = m_kk*j + k;
03257 counterIJ = m_CounterIJ[n];
03258
03259 sum1 = sum1 + molality[j]*molality[k]*
03260 (BphiMX[counterIJ] + molarcharge*CMX[counterIJ]);
03261 }
03262 }
03263
03264 for (k = j+1; k < m_kk; k++) {
03265 if (j == (m_kk-1)) {
03266
03267 printf("logic error 1 in Step 9 of hmw_act");
03268 exit(EXIT_FAILURE);
03269 }
03270 if (charge[k] > 0.0) {
03271
03272
03273
03274
03275 n = m_kk*j + k;
03276 counterIJ = m_CounterIJ[n];
03277 sum2 = sum2 + molality[j]*molality[k]*Phiphi[counterIJ];
03278 for (m = 1; m < m_kk; m++) {
03279 if (charge[m] < 0.0) {
03280
03281 n = m + k * m_kk + j * m_kk * m_kk;
03282 sum2 = sum2 +
03283 molality[j]*molality[k]*molality[m]*psi_ijk[n];
03284 }
03285 }
03286 }
03287 }
03288 }
03289
03290
03291
03292
03293 if (charge[j] < 0) {
03294 for (k = j+1; k < m_kk; k++) {
03295 if (j == m_kk-1) {
03296
03297 printf("logic error 2 in Step 9 of hmw_act");
03298 exit(EXIT_FAILURE);
03299 }
03300 if (charge[k] < 0) {
03301
03302
03303
03304
03305 n = m_kk*j + k;
03306 counterIJ = m_CounterIJ[n];
03307
03308 sum3 = sum3 + molality[j]*molality[k]*Phiphi[counterIJ];
03309 for (m = 1; m < m_kk; m++) {
03310 if (charge[m] > 0.0) {
03311 n = m + k * m_kk + j * m_kk * m_kk;
03312 sum3 = sum3 +
03313 molality[j]*molality[k]*molality[m]*psi_ijk[n];
03314 }
03315 }
03316 }
03317 }
03318 }
03319
03320
03321
03322
03323 if (charge[j] == 0) {
03324 for (k = 1; k < m_kk; k++) {
03325 if (charge[k] < 0.0) {
03326 sum4 = sum4 + molality[j]*molality[k]*m_Lambda_nj(j,k);
03327 }
03328 if (charge[k] > 0.0) {
03329 sum5 = sum5 + molality[j]*molality[k]*m_Lambda_nj(j,k);
03330 }
03331 if (charge[k] == 0.0) {
03332 if (k > j) {
03333 sum6 = sum6 + molality[j]*molality[k]*m_Lambda_nj(j,k);
03334 } else if (k == j) {
03335 sum6 = sum6 + 0.5 * molality[j]*molality[k]*m_Lambda_nj(j,k);
03336 }
03337 }
03338 if (charge[k] < 0.0) {
03339 int izeta = j;
03340 for (m = 1; m < m_kk; m++) {
03341 if (charge[m] > 0.0) {
03342 int jzeta = m;
03343 n = k + jzeta * m_kk + izeta * m_kk * m_kk;
03344 double zeta = psi_ijk[n];
03345 if (zeta != 0.0) {
03346 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta;
03347 }
03348 }
03349 }
03350 }
03351 }
03352 sum7 += molality[j]*molality[j]*molality[j]*m_Mu_nnn[j];
03353 }
03354 }
03355 sum_m_phi_minus_1 = 2.0 *
03356 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
03357
03358
03359
03360
03361 if (molalitysumUncropped > 1.0E-150) {
03362 osmotic_coef = 1.0 + (sum_m_phi_minus_1 / molalitysumUncropped);
03363 } else {
03364 osmotic_coef = 1.0;
03365 }
03366 #ifdef DEBUG_MODE
03367 if (printE) {
03368 printf("OsmCoef - 1 = %20.13g\n", osmotic_coef - 1.0);
03369 }
03370 #endif
03371 #ifdef DEBUG_MODE
03372 if (m_debugCalc) {
03373 printf(" term1=%10.6f sum1=%10.6f sum2=%10.6f "
03374 "sum3=%10.6f sum4=%10.6f sum5=%10.6f\n",
03375 term1, sum1, sum2, sum3, sum4, sum5);
03376 printf(" sum_m_phi_minus_1=%10.6f osmotic_coef=%10.6f\n",
03377 sum_m_phi_minus_1, osmotic_coef);
03378 }
03379
03380 if (m_debugCalc) {
03381 printf(" Step 10: \n");
03382 }
03383 #endif
03384 lnwateract = -(m_weightSolvent/1000.0) * molalitysumUncropped * osmotic_coef;
03385 wateract = exp(lnwateract);
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395 double xmolSolvent = moleFraction(m_indexSolvent);
03396 double xx = MAX(m_xmolSolventMIN, xmolSolvent);
03397 m_lnActCoeffMolal_Unscaled[0] = lnwateract - log(xx);
03398 #ifdef DEBUG_MODE
03399 if (m_debugCalc) {
03400 printf(" Weight of Solvent = %16.7g\n", m_weightSolvent);
03401 printf(" molalitySumUncropped = %16.7g\n", molalitysumUncropped);
03402 printf(" ln_a_water=%10.6f a_water=%10.6f\n\n",
03403 lnwateract, wateract);
03404 }
03405 #endif
03406 }
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420 void HMWSoln::s_update_dlnMolalityActCoeff_dT() const {
03421
03422
03423
03424 fbo_zero_dbl_1(DATA_PTR(m_dlnActCoeffMolaldT_Unscaled), m_kk);
03425
03426
03427
03428 s_updatePitzer_dlnMolalityActCoeff_dT();
03429
03430
03431
03432
03433
03434 for (int k = 1; k < m_kk; k++) {
03435 if (CROP_speciesCropped_[k] == 2) {
03436 m_dlnActCoeffMolaldT_Unscaled[k] = 0.0;
03437 }
03438 }
03439
03440 if (CROP_speciesCropped_[0]) {
03441 m_dlnActCoeffMolaldT_Unscaled[0] = 0.0;
03442 }
03443
03444
03445
03446
03447 s_updateScaling_pHScaling_dT();
03448
03449
03450 }
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465 void HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT() const {
03466
03467
03468
03469
03470
03471 #ifdef DEBUG_MODE
03472 m_debugCalc = 0;
03473 #endif
03474 if (m_indexSolvent != 0) {
03475 printf("Wrong index solvent value!\n");
03476 exit(EXIT_FAILURE);
03477 }
03478
03479 double d_wateract_dT;
03480 std::string sni, snj, snk;
03481
03482 const double *molality = DATA_PTR(m_molalitiesCropped);
03483 const double *charge = DATA_PTR(m_speciesCharge);
03484 const double *beta0MX_L = DATA_PTR(m_Beta0MX_ij_L);
03485 const double *beta1MX_L = DATA_PTR(m_Beta1MX_ij_L);
03486 const double *beta2MX_L = DATA_PTR(m_Beta2MX_ij_L);
03487 const double *CphiMX_L = DATA_PTR(m_CphiMX_ij_L);
03488 const double *thetaij_L = DATA_PTR(m_Theta_ij_L);
03489 const double *alpha1MX = DATA_PTR(m_Alpha1MX_ij);
03490 const double *alpha2MX = DATA_PTR(m_Alpha2MX_ij);
03491 const double *psi_ijk_L = DATA_PTR(m_Psi_ijk_L);
03492 double *d_gamma_dT_Unscaled = DATA_PTR(m_gamma_tmp);
03493
03494
03495
03496 double etheta[5][5], etheta_prime[5][5], sqrtIs;
03497
03498
03499
03500 double Is = 0.0;
03501
03502
03503
03504
03505 double molarcharge = 0.0;
03506
03507
03508
03509
03510 double molalitysum = 0.0;
03511
03512 double *gfunc = DATA_PTR(m_gfunc_IJ);
03513 double *g2func = DATA_PTR(m_g2func_IJ);
03514 double *hfunc = DATA_PTR(m_hfunc_IJ);
03515 double *h2func = DATA_PTR(m_h2func_IJ);
03516 double *BMX_L = DATA_PTR(m_BMX_IJ_L);
03517 double *BprimeMX_L= DATA_PTR(m_BprimeMX_IJ_L);
03518 double *BphiMX_L = DATA_PTR(m_BphiMX_IJ_L);
03519 double *Phi_L = DATA_PTR(m_Phi_IJ_L);
03520 double *Phiprime = DATA_PTR(m_Phiprime_IJ);
03521 double *Phiphi_L = DATA_PTR(m_PhiPhi_IJ_L);
03522 double *CMX_L = DATA_PTR(m_CMX_IJ_L);
03523
03524 double x1, x2;
03525 double Aphi, dFdT, zsqdFdT;
03526 double sum1, sum2, sum3, sum4, sum5, term1;
03527 double sum_m_phi_minus_1, d_osmotic_coef_dT, d_lnwateract_dT;
03528
03529 int z1, z2;
03530 int n, i, j, k, m, counterIJ, counterIJ2;
03531
03532 #ifdef DEBUG_MODE
03533 if (m_debugCalc) {
03534 printf("\n Debugging information from "
03535 "s_Pitzer_dlnMolalityActCoeff_dT()\n");
03536 }
03537 #endif
03538
03539
03540
03541 counterIJ_setup();
03542
03543
03544
03545
03546 for (n = 1; n < m_kk; n++) {
03547
03548 Is += charge[n] * charge[n] * molality[n];
03549
03550 molarcharge += fabs(charge[n]) * molality[n];
03551 molalitysum += molality[n];
03552 }
03553 Is *= 0.5;
03554
03555
03556
03557
03558 m_IionicMolality = Is;
03559 sqrtIs = sqrt(Is);
03560 #ifdef DEBUG_MODE
03561 if (m_debugCalc) {
03562 printf(" Step 1: \n");
03563 printf(" ionic strenth = %14.7le \n total molar "
03564 "charge = %14.7le \n", Is, molarcharge);
03565 }
03566 #endif
03567
03568
03569
03570
03571
03572
03573 calc_lambdas(Is);
03574
03575
03576
03577
03578
03579
03580 #ifdef DEBUG_MODE
03581 if (m_debugCalc) {
03582 printf(" Step 2: \n");
03583 }
03584 #endif
03585 for (z1 = 1; z1 <=4; z1++) {
03586 for (z2 =1; z2 <=4; z2++) {
03587 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
03588 #ifdef DEBUG_MODE
03589 if (m_debugCalc) {
03590 printf(" z1=%3d z2=%3d E-theta(I) = %f, E-thetaprime(I) = %f\n",
03591 z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
03592 }
03593 #endif
03594 }
03595 }
03596
03597 #ifdef DEBUG_MODE
03598 if (m_debugCalc) {
03599 printf(" Step 3: \n");
03600 printf(" Species Species g(x) "
03601 " hfunc(x) \n");
03602 }
03603 #endif
03604
03605
03606
03607
03608
03609
03610
03611 for (i = 1; i < (m_kk - 1); i++) {
03612 for (j = (i+1); j < m_kk; j++) {
03613
03614
03615
03616 n = m_kk*i + j;
03617 counterIJ = m_CounterIJ[n];
03618
03619
03620
03621 if (charge[i]*charge[j] < 0) {
03622
03623
03624
03625 x1 = sqrtIs * alpha1MX[counterIJ];
03626 if (x1 > 1.0E-100) {
03627 gfunc[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
03628 hfunc[counterIJ] = -2.0 *
03629 (1.0-(1.0 + x1 + 0.5 * x1 *x1) * exp(-x1)) / (x1 * x1);
03630 }
03631 else {
03632 gfunc[counterIJ] = 0.0;
03633 hfunc[counterIJ] = 0.0;
03634 }
03635
03636 if (beta2MX_L[counterIJ] != 0.0) {
03637 x2 = sqrtIs * alpha2MX[counterIJ];
03638 if (x2 > 1.0E-100) {
03639 g2func[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
03640 h2func[counterIJ] = -2.0 *
03641 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
03642 } else {
03643 g2func[counterIJ] = 0.0;
03644 h2func[counterIJ] = 0.0;
03645 }
03646 }
03647 }
03648 else {
03649 gfunc[counterIJ] = 0.0;
03650 hfunc[counterIJ] = 0.0;
03651 }
03652 #ifdef DEBUG_MODE
03653 if (m_debugCalc) {
03654 sni = speciesName(i);
03655 snj = speciesName(j);
03656 printf(" %-16s %-16s %9.5f %9.5f \n", sni.c_str(), snj.c_str(),
03657 gfunc[counterIJ], hfunc[counterIJ]);
03658 }
03659 #endif
03660 }
03661 }
03662
03663
03664
03665
03666
03667
03668 #ifdef DEBUG_MODE
03669 if (m_debugCalc) {
03670 printf(" Step 4: \n");
03671 printf(" Species Species BMX "
03672 "BprimeMX BphiMX \n");
03673 }
03674 #endif
03675
03676 for (i = 1; i < m_kk - 1; i++) {
03677 for (j = i+1; j < m_kk; j++) {
03678
03679
03680
03681 n = m_kk*i + j;
03682 counterIJ = m_CounterIJ[n];
03683
03684
03685
03686
03687 if (charge[i]*charge[j] < 0.0) {
03688 BMX_L[counterIJ] = beta0MX_L[counterIJ]
03689 + beta1MX_L[counterIJ] * gfunc[counterIJ]
03690 + beta2MX_L[counterIJ] * gfunc[counterIJ];
03691 #ifdef DEBUG_MODE
03692 if (m_debugCalc) {
03693 printf("%d %g: %g %g %g %g\n",
03694 counterIJ, BMX_L[counterIJ], beta0MX_L[counterIJ],
03695 beta1MX_L[counterIJ], beta2MX_L[counterIJ], gfunc[counterIJ]);
03696 }
03697 #endif
03698 if (Is > 1.0E-150) {
03699 BprimeMX_L[counterIJ] = (beta1MX_L[counterIJ] * hfunc[counterIJ]/Is +
03700 beta2MX_L[counterIJ] * h2func[counterIJ]/Is);
03701 } else {
03702 BprimeMX_L[counterIJ] = 0.0;
03703 }
03704 BphiMX_L[counterIJ] = BMX_L[counterIJ] + Is*BprimeMX_L[counterIJ];
03705 }
03706 else {
03707 BMX_L[counterIJ] = 0.0;
03708 BprimeMX_L[counterIJ] = 0.0;
03709 BphiMX_L[counterIJ] = 0.0;
03710 }
03711 #ifdef DEBUG_MODE
03712 if (m_debugCalc) {
03713 sni = speciesName(i);
03714 snj = speciesName(j);
03715 printf(" %-16s %-16s %11.7f %11.7f %11.7f \n",
03716 sni.c_str(), snj.c_str(),
03717 BMX_L[counterIJ], BprimeMX_L[counterIJ], BphiMX_L[counterIJ]);
03718 }
03719 #endif
03720 }
03721 }
03722
03723
03724
03725
03726
03727 #ifdef DEBUG_MODE
03728 if (m_debugCalc) {
03729 printf(" Step 5: \n");
03730 printf(" Species Species CMX \n");
03731 }
03732 #endif
03733 for (i = 1; i < m_kk-1; i++) {
03734 for (j = i+1; j < m_kk; j++) {
03735
03736
03737
03738 n = m_kk*i + j;
03739 counterIJ = m_CounterIJ[n];
03740
03741
03742
03743
03744 if (charge[i]*charge[j] < 0.0) {
03745 CMX_L[counterIJ] = CphiMX_L[counterIJ]/
03746 (2.0* sqrt(fabs(charge[i]*charge[j])));
03747 }
03748 else {
03749 CMX_L[counterIJ] = 0.0;
03750 }
03751 #ifdef DEBUG_MODE
03752 if (m_debugCalc) {
03753 sni = speciesName(i);
03754 snj = speciesName(j);
03755 printf(" %-16s %-16s %11.7f \n", sni.c_str(), snj.c_str(),
03756 CMX_L[counterIJ]);
03757 }
03758 #endif
03759 }
03760 }
03761
03762
03763
03764
03765
03766 #ifdef DEBUG_MODE
03767 if (m_debugCalc) {
03768 printf(" Step 6: \n");
03769 printf(" Species Species Phi_ij "
03770 " Phiprime_ij Phi^phi_ij \n");
03771 }
03772 #endif
03773 for (i = 1; i < m_kk-1; i++) {
03774 for (j = i+1; j < m_kk; j++) {
03775
03776
03777
03778 n = m_kk*i + j;
03779 counterIJ = m_CounterIJ[n];
03780
03781
03782
03783
03784 if (charge[i]*charge[j] > 0) {
03785 z1 = (int) fabs(charge[i]);
03786 z2 = (int) fabs(charge[j]);
03787
03788 Phi_L[counterIJ] = thetaij_L[counterIJ];
03789
03790 Phiprime[counterIJ] = 0.0;
03791 Phiphi_L[counterIJ] = Phi_L[counterIJ] + Is * Phiprime[counterIJ];
03792 }
03793 else {
03794 Phi_L[counterIJ] = 0.0;
03795 Phiprime[counterIJ] = 0.0;
03796 Phiphi_L[counterIJ] = 0.0;
03797 }
03798 #ifdef DEBUG_MODE
03799 if (m_debugCalc) {
03800 sni = speciesName(i);
03801 snj = speciesName(j);
03802 printf(" %-16s %-16s %10.6f %10.6f %10.6f \n",
03803 sni.c_str(), snj.c_str(),
03804 Phi_L[counterIJ], Phiprime[counterIJ], Phiphi_L[counterIJ] );
03805 }
03806 #endif
03807 }
03808 }
03809
03810
03811
03812
03813 #ifdef DEBUG_MODE
03814 if (m_debugCalc) {
03815 printf(" Step 7: \n");
03816 }
03817 #endif
03818
03819
03820
03821
03822 Aphi = m_A_Debye / 3.0;
03823
03824 double dA_DebyedT = dA_DebyedT_TP();
03825 double dAphidT = dA_DebyedT /3.0;
03826 #ifdef DEBUG_HKM
03827
03828 #endif
03829
03830
03831
03832 dFdT = -dAphidT * ( sqrt(Is) / (1.0 + 1.2*sqrt(Is))
03833 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
03834 #ifdef DEBUG_MODE
03835 if (m_debugCalc) {
03836 printf(" initial value of dFdT = %10.6f \n", dFdT );
03837 }
03838 #endif
03839 for (i = 1; i < m_kk-1; i++) {
03840 for (j = i+1; j < m_kk; j++) {
03841
03842
03843
03844 n = m_kk*i + j;
03845 counterIJ = m_CounterIJ[n];
03846
03847
03848
03849
03850 if (charge[i]*charge[j] < 0) {
03851 dFdT = dFdT + molality[i]*molality[j] * BprimeMX_L[counterIJ];
03852 }
03853
03854
03855
03856
03857 if (charge[i]*charge[j] > 0) {
03858 dFdT = dFdT + molality[i]*molality[j] * Phiprime[counterIJ];
03859 }
03860 #ifdef DEBUG_MODE
03861 if (m_debugCalc) printf(" dFdT = %10.6f \n", dFdT);
03862 #endif
03863 }
03864 }
03865 #ifdef DEBUG_MODE
03866 if (m_debugCalc) {
03867 printf(" Step 8: \n");
03868 }
03869 #endif
03870
03871 for (i = 1; i < m_kk; i++) {
03872
03873
03874
03875
03876
03877 if (charge[i] > 0 ) {
03878
03879 zsqdFdT = charge[i]*charge[i]*dFdT;
03880 sum1 = 0.0;
03881 sum2 = 0.0;
03882 sum3 = 0.0;
03883 sum4 = 0.0;
03884 sum5 = 0.0;
03885 for (j = 1; j < m_kk; j++) {
03886
03887
03888
03889 n = m_kk*i + j;
03890 counterIJ = m_CounterIJ[n];
03891
03892 if (charge[j] < 0.0) {
03893
03894 sum1 = sum1 + molality[j]*
03895 (2.0*BMX_L[counterIJ] + molarcharge*CMX_L[counterIJ]);
03896 if (j < m_kk-1) {
03897
03898
03899
03900
03901
03902 for (k = j+1; k < m_kk; k++) {
03903
03904 if (charge[k] < 0.0) {
03905 n = k + j * m_kk + i * m_kk * m_kk;
03906 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_L[n];
03907 }
03908 }
03909 }
03910 }
03911
03912
03913 if (charge[j] > 0.0) {
03914
03915 if (j != i) {
03916 sum2 = sum2 + molality[j]*(2.0*Phi_L[counterIJ]);
03917 }
03918 for (k = 1; k < m_kk; k++) {
03919 if (charge[k] < 0.0) {
03920
03921
03922 n = k + j * m_kk + i * m_kk * m_kk;
03923 sum2 = sum2 + molality[j]*molality[k]*psi_ijk_L[n];
03924
03925
03926
03927 n = m_kk*j + k;
03928 counterIJ2 = m_CounterIJ[n];
03929 sum4 = sum4 + (fabs(charge[i])*
03930 molality[j]*molality[k]*CMX_L[counterIJ2]);
03931 }
03932 }
03933 }
03934
03935
03936
03937
03938 if (charge[j] == 0) {
03939 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj_L(j,i);
03940 }
03941
03942
03943
03944 for (int k = 1; k < m_kk; k++) {
03945 if (charge[k] < 0.0) {
03946 int izeta = j;
03947 int jzeta = i;
03948 n = izeta * m_kk * m_kk + jzeta * m_kk + k;
03949 double zeta_L = psi_ijk_L[n];
03950 if (zeta_L != 0.0) {
03951 sum5 = sum5 + molality[j]*molality[k]*zeta_L;
03952 }
03953 }
03954 }
03955 }
03956
03957
03958
03959
03960 m_dlnActCoeffMolaldT_Unscaled[i] =
03961 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
03962 d_gamma_dT_Unscaled[i] = exp(m_dlnActCoeffMolaldT_Unscaled[i]);
03963 #ifdef DEBUG_MODE
03964 if (m_debugCalc) {
03965 sni = speciesName(i);
03966 printf(" %-16s lngamma[i]=%10.6f gamma[i]=%10.6f \n",
03967 sni.c_str(), m_dlnActCoeffMolaldT_Unscaled[i], d_gamma_dT_Unscaled[i]);
03968 printf(" %12g %12g %12g %12g %12g %12g\n",
03969 zsqdFdT, sum1, sum2, sum3, sum4, sum5);
03970 }
03971 #endif
03972 }
03973
03974
03975
03976
03977
03978 if (charge[i] < 0 ) {
03979
03980 zsqdFdT = charge[i]*charge[i]*dFdT;
03981 sum1 = 0.0;
03982 sum2 = 0.0;
03983 sum3 = 0.0;
03984 sum4 = 0.0;
03985 sum5 = 0.0;
03986 for (j = 1; j < m_kk; j++) {
03987
03988
03989
03990 n = m_kk*i + j;
03991 counterIJ = m_CounterIJ[n];
03992
03993
03994
03995
03996 if (charge[j] > 0) {
03997 sum1 = sum1 + molality[j]*
03998 (2.0*BMX_L[counterIJ] + molarcharge*CMX_L[counterIJ]);
03999 if (j < m_kk-1) {
04000 for (k = j+1; k < m_kk; k++) {
04001
04002 if (charge[k] > 0) {
04003 n = k + j * m_kk + i * m_kk * m_kk;
04004 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_L[n];
04005 }
04006 }
04007 }
04008 }
04009
04010
04011
04012
04013 if (charge[j] < 0.0) {
04014
04015 if (j != i) {
04016 sum2 = sum2 + molality[j]*(2.0*Phi_L[counterIJ]);
04017 }
04018 for (k = 1; k < m_kk; k++) {
04019 if (charge[k] > 0.0) {
04020
04021 n = k + j * m_kk + i * m_kk * m_kk;
04022 sum2 = sum2 + molality[j]*molality[k]*psi_ijk_L[n];
04023
04024
04025
04026 n = m_kk*j + k;
04027 counterIJ2 = m_CounterIJ[n];
04028 sum4 = sum4 +
04029 (fabs(charge[i])*
04030 molality[j]*molality[k]*CMX_L[counterIJ2]);
04031 }
04032 }
04033 }
04034
04035
04036
04037
04038 if (charge[j] == 0.0) {
04039 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj_L(j,i);
04040 for (int k = 1; k < m_kk; k++) {
04041 if (charge[k] > 0.0) {
04042 int izeta = j;
04043 int jzeta = k;
04044 int kzeta = i;
04045 n = izeta * m_kk * m_kk + jzeta * m_kk + kzeta;
04046 double zeta_L = psi_ijk_L[n];
04047 if (zeta_L != 0.0) {
04048 sum5 = sum5 + molality[j]*molality[k]*zeta_L;
04049 }
04050 }
04051 }
04052 }
04053 }
04054 m_dlnActCoeffMolaldT_Unscaled[i] =
04055 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
04056 d_gamma_dT_Unscaled[i] = exp(m_dlnActCoeffMolaldT_Unscaled[i]);
04057 #ifdef DEBUG_MODE
04058 if (m_debugCalc) {
04059 sni = speciesName(i);
04060 printf(" %-16s lngamma[i]=%10.6f gamma[i]=%10.6f\n",
04061 sni.c_str(), m_dlnActCoeffMolaldT_Unscaled[i], d_gamma_dT_Unscaled[i]);
04062 printf(" %12g %12g %12g %12g %12g %12g\n",
04063 zsqdFdT, sum1, sum2, sum3, sum4, sum5);
04064 }
04065 #endif
04066 }
04067
04068
04069
04070
04071
04072 if (charge[i] == 0.0 ) {
04073 sum1 = 0.0;
04074 sum3 = 0.0;
04075 for (j = 1; j < m_kk; j++) {
04076 sum1 = sum1 + molality[j]*2.0*m_Lambda_nj_L(i,j);
04077
04078
04079
04080 if (charge[j] > 0.0) {
04081 for (k = 1; k < m_kk; k++) {
04082 if (charge[k] < 0.0) {
04083 n = k + j * m_kk + i * m_kk * m_kk;
04084 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_L[n];
04085 }
04086 }
04087 }
04088 }
04089 sum2 = 3.0 * molality[i] * molality[i] * m_Mu_nnn_L[i];
04090 m_dlnActCoeffMolaldT_Unscaled[i] = sum1 + sum2 + sum3;
04091 d_gamma_dT_Unscaled[i] = exp(m_dlnActCoeffMolaldT_Unscaled[i]);
04092 #ifdef DEBUG_MODE
04093 if (m_debugCalc) {
04094 sni = speciesName(i);
04095 printf(" %-16s lngamma[i]=%10.6f gamma[i]=%10.6f \n",
04096 sni.c_str(), m_dlnActCoeffMolaldT_Unscaled[i], d_gamma_dT_Unscaled[i]);
04097 }
04098 #endif
04099 }
04100
04101 }
04102 #ifdef DEBUG_MODE
04103 if (m_debugCalc) {
04104 printf(" Step 9: \n");
04105 }
04106 #endif
04107
04108
04109
04110
04111 sum1 = 0.0;
04112 sum2 = 0.0;
04113 sum3 = 0.0;
04114 sum4 = 0.0;
04115 sum5 = 0.0;
04116 double sum6 = 0.0;
04117 double sum7 = 0.0;
04118
04119
04120
04121
04122
04123
04124
04125
04126 term1 = -dAphidT * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
04127
04128 for (j = 1; j < m_kk; j++) {
04129
04130
04131
04132 if (charge[j] > 0.0) {
04133 for (k = 1; k < m_kk; k++){
04134 if (charge[k] < 0.0) {
04135
04136
04137
04138 n = m_kk*j + k;
04139 counterIJ = m_CounterIJ[n];
04140
04141 sum1 = sum1 + molality[j]*molality[k]*
04142 (BphiMX_L[counterIJ] + molarcharge*CMX_L[counterIJ]);
04143 }
04144 }
04145
04146 for (k = j+1; k < m_kk; k++) {
04147 if (j == (m_kk-1)) {
04148
04149 printf("logic error 1 in Step 9 of hmw_act");
04150 exit(EXIT_FAILURE);
04151 }
04152 if (charge[k] > 0.0) {
04153
04154
04155
04156
04157 n = m_kk*j + k;
04158 counterIJ = m_CounterIJ[n];
04159 sum2 = sum2 + molality[j]*molality[k]*Phiphi_L[counterIJ];
04160 for (m = 1; m < m_kk; m++) {
04161 if (charge[m] < 0.0) {
04162
04163 n = m + k * m_kk + j * m_kk * m_kk;
04164 sum2 = sum2 +
04165 molality[j]*molality[k]*molality[m]*psi_ijk_L[n];
04166 }
04167 }
04168 }
04169 }
04170 }
04171
04172
04173
04174
04175 if (charge[j] < 0) {
04176 for (k = j+1; k < m_kk; k++) {
04177 if (j == m_kk-1) {
04178
04179 printf("logic error 2 in Step 9 of hmw_act");
04180 exit(EXIT_FAILURE);
04181 }
04182 if (charge[k] < 0) {
04183
04184
04185
04186
04187 n = m_kk*j + k;
04188 counterIJ = m_CounterIJ[n];
04189
04190 sum3 = sum3 + molality[j]*molality[k]*Phiphi_L[counterIJ];
04191 for (m = 1; m < m_kk; m++) {
04192 if (charge[m] > 0.0) {
04193 n = m + k * m_kk + j * m_kk * m_kk;
04194 sum3 = sum3 +
04195 molality[j]*molality[k]*molality[m]*psi_ijk_L[n];
04196 }
04197 }
04198 }
04199 }
04200 }
04201
04202
04203
04204
04205 if (charge[j] == 0) {
04206 for (k = 1; k < m_kk; k++) {
04207 if (charge[k] < 0.0) {
04208 sum4 = sum4 + molality[j]*molality[k]*m_Lambda_nj_L(j,k);
04209 }
04210 if (charge[k] > 0.0) {
04211 sum5 = sum5 + molality[j]*molality[k]*m_Lambda_nj_L(j,k);
04212 }
04213 if (charge[k] == 0.0) {
04214 if (k > j) {
04215 sum6 = sum6 + molality[j]*molality[k]*m_Lambda_nj_L(j,k);
04216 } else if (k == j) {
04217 sum6 = sum6 + 0.5 * molality[j]*molality[k]*m_Lambda_nj_L(j,k);
04218 }
04219 }
04220 if (charge[k] < 0.0) {
04221 int izeta = j;
04222 for (m = 1; m < m_kk; m++) {
04223 if (charge[m] > 0.0) {
04224 int jzeta = m;
04225 n = k + jzeta * m_kk + izeta * m_kk * m_kk;
04226 double zeta_L = psi_ijk_L[n];
04227 if (zeta_L != 0.0) {
04228 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_L;
04229 }
04230 }
04231 }
04232 }
04233 }
04234 sum7 += molality[j]*molality[j]*molality[j]*m_Mu_nnn_L[j];
04235 }
04236 }
04237 sum_m_phi_minus_1 = 2.0 *
04238 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
04239
04240
04241
04242
04243 if (molalitysum > 1.0E-150) {
04244 d_osmotic_coef_dT = 0.0 + (sum_m_phi_minus_1 / molalitysum);
04245 } else {
04246 d_osmotic_coef_dT = 0.0;
04247 }
04248 #ifdef DEBUG_MODE
04249 if (m_debugCalc) {
04250 printf(" term1=%10.6f sum1=%10.6f sum2=%10.6f "
04251 "sum3=%10.6f sum4=%10.6f sum5=%10.6f\n",
04252 term1, sum1, sum2, sum3, sum4, sum5);
04253 printf(" sum_m_phi_minus_1=%10.6f d_osmotic_coef_dT =%10.6f\n",
04254 sum_m_phi_minus_1, d_osmotic_coef_dT);
04255 }
04256
04257 if (m_debugCalc) {
04258 printf(" Step 10: \n");
04259 }
04260 #endif
04261 d_lnwateract_dT = -(m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dT;
04262 d_wateract_dT = exp(d_lnwateract_dT);
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273 m_dlnActCoeffMolaldT_Unscaled[0] = d_lnwateract_dT;
04274 #ifdef DEBUG_MODE
04275 if (m_debugCalc) {
04276 printf(" d_ln_a_water_dT = %10.6f d_a_water_dT=%10.6f\n\n",
04277 d_lnwateract_dT, d_wateract_dT);
04278 }
04279 #endif
04280 }
04281
04282
04283
04284
04285
04286
04287 void HMWSoln::s_update_d2lnMolalityActCoeff_dT2() const {
04288
04289
04290
04291 fbo_zero_dbl_1(DATA_PTR(m_d2lnActCoeffMolaldT2_Unscaled), m_kk);
04292
04293
04294
04295 s_updatePitzer_d2lnMolalityActCoeff_dT2();
04296
04297
04298
04299
04300
04301 for (int k = 1; k < m_kk; k++) {
04302 if (CROP_speciesCropped_[k] == 2) {
04303 m_d2lnActCoeffMolaldT2_Unscaled[k] = 0.0;
04304 }
04305 }
04306
04307 if (CROP_speciesCropped_[0]) {
04308 m_d2lnActCoeffMolaldT2_Unscaled[0] = 0.0;
04309 }
04310
04311
04312
04313
04314 s_updateScaling_pHScaling_dT2();
04315 }
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338 void HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2() const {
04339
04340
04341
04342
04343
04344 #ifdef DEBUG_MODE
04345 m_debugCalc = 0;
04346 #endif
04347 if (m_indexSolvent != 0) {
04348 printf("Wrong index solvent value!\n");
04349 exit(EXIT_FAILURE);
04350 }
04351
04352 std::string sni, snj, snk;
04353
04354 const double *molality = DATA_PTR(m_molalitiesCropped);
04355 const double *charge = DATA_PTR(m_speciesCharge);
04356 const double *beta0MX_LL= DATA_PTR(m_Beta0MX_ij_LL);
04357 const double *beta1MX_LL= DATA_PTR(m_Beta1MX_ij_LL);
04358 const double *beta2MX_LL= DATA_PTR(m_Beta2MX_ij_LL);
04359 const double *CphiMX_LL = DATA_PTR(m_CphiMX_ij_LL);
04360 const double *thetaij_LL= DATA_PTR(m_Theta_ij_LL);
04361 const double *alpha1MX = DATA_PTR(m_Alpha1MX_ij);
04362 const double *alpha2MX = DATA_PTR(m_Alpha2MX_ij);
04363 const double *psi_ijk_LL= DATA_PTR(m_Psi_ijk_LL);
04364
04365
04366
04367
04368 double etheta[5][5], etheta_prime[5][5], sqrtIs;
04369
04370
04371
04372 double Is = 0.0;
04373
04374
04375
04376
04377 double molarcharge = 0.0;
04378
04379
04380
04381
04382 double molalitysum = 0.0;
04383
04384 double *gfunc = DATA_PTR(m_gfunc_IJ);
04385 double *g2func = DATA_PTR(m_g2func_IJ);
04386 double *hfunc = DATA_PTR(m_hfunc_IJ);
04387 double *h2func = DATA_PTR(m_h2func_IJ);
04388 double *BMX_LL = DATA_PTR(m_BMX_IJ_LL);
04389 double *BprimeMX_LL=DATA_PTR(m_BprimeMX_IJ_LL);
04390 double *BphiMX_LL= DATA_PTR(m_BphiMX_IJ_LL);
04391 double *Phi_LL = DATA_PTR(m_Phi_IJ_LL);
04392 double *Phiprime = DATA_PTR(m_Phiprime_IJ);
04393 double *Phiphi_LL= DATA_PTR(m_PhiPhi_IJ_LL);
04394 double *CMX_LL = DATA_PTR(m_CMX_IJ_LL);
04395
04396
04397 double x1, x2;
04398 double d2FdT2, zsqd2FdT2;
04399 double sum1, sum2, sum3, sum4, sum5, term1;
04400 double sum_m_phi_minus_1, d2_osmotic_coef_dT2, d2_lnwateract_dT2;
04401
04402 int z1, z2;
04403 int n, i, j, k, m, counterIJ, counterIJ2;
04404
04405 #ifdef DEBUG_MODE
04406 if (m_debugCalc) {
04407 printf("\n Debugging information from "
04408 "s_Pitzer_d2lnMolalityActCoeff_dT2()\n");
04409 }
04410 #endif
04411
04412
04413
04414 counterIJ_setup();
04415
04416
04417
04418
04419
04420 for (n = 1; n < m_kk; n++) {
04421
04422 Is += charge[n] * charge[n] * molality[n];
04423
04424 molarcharge += fabs(charge[n]) * molality[n];
04425 molalitysum += molality[n];
04426 }
04427 Is *= 0.5;
04428
04429
04430
04431
04432 m_IionicMolality = Is;
04433 sqrtIs = sqrt(Is);
04434 #ifdef DEBUG_MODE
04435 if (m_debugCalc) {
04436 printf(" Step 1: \n");
04437 printf(" ionic strenth = %14.7le \n total molar "
04438 "charge = %14.7le \n", Is, molarcharge);
04439 }
04440 #endif
04441
04442
04443
04444
04445
04446
04447 calc_lambdas(Is);
04448
04449
04450
04451
04452
04453
04454 #ifdef DEBUG_MODE
04455 if (m_debugCalc) {
04456 printf(" Step 2: \n");
04457 }
04458 #endif
04459 for (z1 = 1; z1 <=4; z1++) {
04460 for (z2 =1; z2 <=4; z2++) {
04461 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
04462 #ifdef DEBUG_MODE
04463 if (m_debugCalc) {
04464 printf(" z1=%3d z2=%3d E-theta(I) = %f, E-thetaprime(I) = %f\n",
04465 z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
04466 }
04467 #endif
04468 }
04469 }
04470
04471 #ifdef DEBUG_MODE
04472 if (m_debugCalc) {
04473 printf(" Step 3: \n");
04474 printf(" Species Species g(x) "
04475 " hfunc(x) \n");
04476 }
04477 #endif
04478
04479
04480
04481
04482
04483
04484
04485 for (i = 1; i < (m_kk - 1); i++) {
04486 for (j = (i+1); j < m_kk; j++) {
04487
04488
04489
04490 n = m_kk*i + j;
04491 counterIJ = m_CounterIJ[n];
04492
04493
04494
04495 if (charge[i]*charge[j] < 0) {
04496
04497
04498
04499 x1 = sqrtIs * alpha1MX[counterIJ];
04500 if (x1 > 1.0E-100) {
04501 gfunc[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 *x1);
04502 hfunc[counterIJ] = -2.0*
04503 (1.0-(1.0 + x1 + 0.5*x1 * x1) * exp(-x1)) / (x1 * x1);
04504 }
04505 else {
04506 gfunc[counterIJ] = 0.0;
04507 hfunc[counterIJ] = 0.0;
04508 }
04509
04510 if (beta2MX_LL[counterIJ] != 0.0) {
04511 x2 = sqrtIs * alpha2MX[counterIJ];
04512 if (x2 > 1.0E-100) {
04513 g2func[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
04514 h2func[counterIJ] = -2.0 *
04515 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
04516 } else {
04517 g2func[counterIJ] = 0.0;
04518 h2func[counterIJ] = 0.0;
04519 }
04520 }
04521 }
04522 else {
04523 gfunc[counterIJ] = 0.0;
04524 hfunc[counterIJ] = 0.0;
04525 }
04526 #ifdef DEBUG_MODE
04527 if (m_debugCalc) {
04528 sni = speciesName(i);
04529 snj = speciesName(j);
04530 printf(" %-16s %-16s %9.5f %9.5f \n", sni.c_str(), snj.c_str(),
04531 gfunc[counterIJ], hfunc[counterIJ]);
04532 }
04533 #endif
04534 }
04535 }
04536
04537
04538
04539
04540
04541 #ifdef DEBUG_MODE
04542 if (m_debugCalc) {
04543 printf(" Step 4: \n");
04544 printf(" Species Species BMX "
04545 "BprimeMX BphiMX \n");
04546 }
04547 #endif
04548
04549 for (i = 1; i < m_kk - 1; i++) {
04550 for (j = i+1; j < m_kk; j++) {
04551
04552
04553
04554 n = m_kk*i + j;
04555 counterIJ = m_CounterIJ[n];
04556
04557
04558
04559
04560 if (charge[i]*charge[j] < 0.0) {
04561 BMX_LL[counterIJ] = beta0MX_LL[counterIJ]
04562 + beta1MX_LL[counterIJ] * gfunc[counterIJ]
04563 + beta2MX_LL[counterIJ] * g2func[counterIJ];
04564 #ifdef DEBUG_MODE
04565 if (m_debugCalc) {
04566 printf("%d %g: %g %g %g %g\n",
04567 counterIJ, BMX_LL[counterIJ], beta0MX_LL[counterIJ],
04568 beta1MX_LL[counterIJ], beta2MX_LL[counterIJ], gfunc[counterIJ]);
04569 }
04570 #endif
04571 if (Is > 1.0E-150) {
04572 BprimeMX_LL[counterIJ] = (beta1MX_LL[counterIJ] * hfunc[counterIJ]/Is +
04573 beta2MX_LL[counterIJ] * h2func[counterIJ]/Is);
04574 } else {
04575 BprimeMX_LL[counterIJ] = 0.0;
04576 }
04577 BphiMX_LL[counterIJ] = BMX_LL[counterIJ] + Is*BprimeMX_LL[counterIJ];
04578 }
04579 else {
04580 BMX_LL[counterIJ] = 0.0;
04581 BprimeMX_LL[counterIJ] = 0.0;
04582 BphiMX_LL[counterIJ] = 0.0;
04583 }
04584 #ifdef DEBUG_MODE
04585 if (m_debugCalc) {
04586 sni = speciesName(i);
04587 snj = speciesName(j);
04588 printf(" %-16s %-16s %11.7f %11.7f %11.7f \n",
04589 sni.c_str(), snj.c_str(),
04590 BMX_LL[counterIJ], BprimeMX_LL[counterIJ], BphiMX_LL[counterIJ]);
04591 }
04592 #endif
04593 }
04594 }
04595
04596
04597
04598
04599
04600 #ifdef DEBUG_MODE
04601 if (m_debugCalc) {
04602 printf(" Step 5: \n");
04603 printf(" Species Species CMX \n");
04604 }
04605 #endif
04606 for (i = 1; i < m_kk-1; i++) {
04607 for (j = i+1; j < m_kk; j++) {
04608
04609
04610
04611 n = m_kk*i + j;
04612 counterIJ = m_CounterIJ[n];
04613
04614
04615
04616
04617 if (charge[i]*charge[j] < 0.0) {
04618 CMX_LL[counterIJ] = CphiMX_LL[counterIJ]/
04619 (2.0* sqrt(fabs(charge[i]*charge[j])));
04620 } else {
04621 CMX_LL[counterIJ] = 0.0;
04622 }
04623 #ifdef DEBUG_MODE
04624 if (m_debugCalc) {
04625 sni = speciesName(i);
04626 snj = speciesName(j);
04627 printf(" %-16s %-16s %11.7f \n", sni.c_str(), snj.c_str(),
04628 CMX_LL[counterIJ]);
04629 }
04630 #endif
04631 }
04632 }
04633
04634
04635
04636
04637
04638 #ifdef DEBUG_MODE
04639 if (m_debugCalc) {
04640 printf(" Step 6: \n");
04641 printf(" Species Species Phi_ij "
04642 " Phiprime_ij Phi^phi_ij \n");
04643 }
04644 #endif
04645 for (i = 1; i < m_kk-1; i++) {
04646 for (j = i+1; j < m_kk; j++) {
04647
04648
04649
04650 n = m_kk*i + j;
04651 counterIJ = m_CounterIJ[n];
04652
04653
04654
04655
04656 if (charge[i]*charge[j] > 0) {
04657 z1 = (int) fabs(charge[i]);
04658 z2 = (int) fabs(charge[j]);
04659
04660
04661 Phi_LL[counterIJ] = thetaij_LL[counterIJ];
04662
04663 Phiprime[counterIJ] = 0.0;
04664
04665
04666 Phiphi_LL[counterIJ] = Phi_LL[counterIJ];
04667 }
04668 else {
04669 Phi_LL[counterIJ] = 0.0;
04670 Phiprime[counterIJ] = 0.0;
04671 Phiphi_LL[counterIJ] = 0.0;
04672 }
04673 #ifdef DEBUG_MODE
04674 if (m_debugCalc) {
04675 sni = speciesName(i);
04676 snj = speciesName(j);
04677
04678
04679
04680 printf(" %-16s %-16s %10.6f %10.6f %10.6f \n",
04681 sni.c_str(), snj.c_str(),
04682 Phi_LL[counterIJ], Phiprime[counterIJ], Phiphi_LL[counterIJ] );
04683 }
04684 #endif
04685 }
04686 }
04687
04688
04689
04690
04691 #ifdef DEBUG_MODE
04692 if (m_debugCalc) {
04693 printf(" Step 7: \n");
04694 }
04695 #endif
04696
04697
04698
04699
04700
04701
04702
04703
04704 double d2AphidT2 = d2A_DebyedT2_TP() / 3.0;
04705 #ifdef DEBUG_HKM
04706
04707 #endif
04708
04709
04710
04711
04712
04713 d2FdT2 = -d2AphidT2 * ( sqrt(Is) / (1.0 + 1.2*sqrt(Is))
04714 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
04715 #ifdef DEBUG_MODE
04716 if (m_debugCalc) {
04717 printf(" initial value of d2FdT2 = %10.6f \n", d2FdT2 );
04718 }
04719 #endif
04720 for (i = 1; i < m_kk-1; i++) {
04721 for (j = i+1; j < m_kk; j++) {
04722
04723
04724
04725 n = m_kk*i + j;
04726 counterIJ = m_CounterIJ[n];
04727
04728
04729
04730
04731 if (charge[i]*charge[j] < 0) {
04732 d2FdT2 = d2FdT2 + molality[i]*molality[j] * BprimeMX_LL[counterIJ];
04733 }
04734
04735
04736
04737
04738 if (charge[i]*charge[j] > 0) {
04739 d2FdT2 = d2FdT2 + molality[i]*molality[j] * Phiprime[counterIJ];
04740 }
04741 #ifdef DEBUG_MODE
04742 if (m_debugCalc) printf(" d2FdT2 = %10.6f \n", d2FdT2);
04743 #endif
04744 }
04745 }
04746 #ifdef DEBUG_MODE
04747 if (m_debugCalc) {
04748 printf(" Step 8: \n");
04749 }
04750 #endif
04751
04752 for (i = 1; i < m_kk; i++) {
04753
04754
04755
04756
04757
04758 if (charge[i] > 0 ) {
04759
04760 zsqd2FdT2 = charge[i]*charge[i]*d2FdT2;
04761 sum1 = 0.0;
04762 sum2 = 0.0;
04763 sum3 = 0.0;
04764 sum4 = 0.0;
04765 sum5 = 0.0;
04766 for (j = 1; j < m_kk; j++) {
04767
04768
04769
04770 n = m_kk*i + j;
04771 counterIJ = m_CounterIJ[n];
04772
04773 if (charge[j] < 0.0) {
04774
04775 sum1 = sum1 + molality[j]*
04776 (2.0*BMX_LL[counterIJ] + molarcharge*CMX_LL[counterIJ]);
04777 if (j < m_kk-1) {
04778
04779
04780
04781
04782
04783 for (k = j+1; k < m_kk; k++) {
04784
04785 if (charge[k] < 0.0) {
04786 n = k + j * m_kk + i * m_kk * m_kk;
04787 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_LL[n];
04788 }
04789 }
04790 }
04791 }
04792
04793
04794 if (charge[j] > 0.0) {
04795
04796 if (j != i) {
04797 sum2 = sum2 + molality[j]*(2.0*Phi_LL[counterIJ]);
04798 }
04799 for (k = 1; k < m_kk; k++) {
04800 if (charge[k] < 0.0) {
04801
04802
04803 n = k + j * m_kk + i * m_kk * m_kk;
04804 sum2 = sum2 + molality[j]*molality[k]*psi_ijk_LL[n];
04805
04806
04807
04808 n = m_kk*j + k;
04809 counterIJ2 = m_CounterIJ[n];
04810 sum4 = sum4 + (fabs(charge[i])*
04811 molality[j]*molality[k]*CMX_LL[counterIJ2]);
04812 }
04813 }
04814 }
04815
04816
04817
04818
04819 if (charge[j] == 0) {
04820 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj_LL(j,i);
04821
04822
04823
04824 for (int k = 1; k < m_kk; k++) {
04825 if (charge[k] < 0.0) {
04826 int izeta = j;
04827 int jzeta = i;
04828 n = izeta * m_kk * m_kk + jzeta * m_kk + k;
04829 double zeta_LL = psi_ijk_LL[n];
04830 if (zeta_LL != 0.0) {
04831 sum5 = sum5 + molality[j]*molality[k]*zeta_LL;
04832 }
04833 }
04834 }
04835 }
04836 }
04837
04838
04839
04840
04841 m_d2lnActCoeffMolaldT2_Unscaled[i] =
04842 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
04843 #ifdef DEBUG_MODE
04844 if (m_debugCalc) {
04845 sni = speciesName(i);
04846 printf(" %-16s d2lngammadT2[i]=%10.6f \n",
04847 sni.c_str(), m_d2lnActCoeffMolaldT2_Unscaled[i]);
04848 printf(" %12g %12g %12g %12g %12g %12g\n",
04849 zsqd2FdT2, sum1, sum2, sum3, sum4, sum5);
04850 }
04851 #endif
04852 }
04853
04854
04855
04856
04857
04858
04859 if (charge[i] < 0 ) {
04860
04861 zsqd2FdT2 = charge[i]*charge[i]*d2FdT2;
04862 sum1 = 0.0;
04863 sum2 = 0.0;
04864 sum3 = 0.0;
04865 sum4 = 0.0;
04866 sum5 = 0.0;
04867 for (j = 1; j < m_kk; j++) {
04868
04869
04870
04871 n = m_kk*i + j;
04872 counterIJ = m_CounterIJ[n];
04873
04874
04875
04876
04877 if (charge[j] > 0) {
04878 sum1 = sum1 + molality[j]*
04879 (2.0*BMX_LL[counterIJ] + molarcharge*CMX_LL[counterIJ]);
04880 if (j < m_kk-1) {
04881 for (k = j+1; k < m_kk; k++) {
04882
04883 if (charge[k] > 0) {
04884 n = k + j * m_kk + i * m_kk * m_kk;
04885 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_LL[n];
04886 }
04887 }
04888 }
04889 }
04890
04891
04892
04893
04894 if (charge[j] < 0.0) {
04895
04896 if (j != i) {
04897 sum2 = sum2 + molality[j]*(2.0*Phi_LL[counterIJ]);
04898 }
04899 for (k = 1; k < m_kk; k++) {
04900 if (charge[k] > 0.0) {
04901
04902 n = k + j * m_kk + i * m_kk * m_kk;
04903 sum2 = sum2 + molality[j]*molality[k]*psi_ijk_LL[n];
04904
04905
04906
04907 n = m_kk*j + k;
04908 counterIJ2 = m_CounterIJ[n];
04909 sum4 = sum4 +
04910 (fabs(charge[i])*
04911 molality[j]*molality[k]*CMX_LL[counterIJ2]);
04912 }
04913 }
04914 }
04915
04916
04917
04918
04919 if (charge[j] == 0.0) {
04920 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj_LL(j,i);
04921
04922
04923
04924 for (int k = 1; k < m_kk; k++) {
04925 if (charge[k] > 0.0) {
04926 int izeta = j;
04927 int jzeta = k;
04928 int kzeta = i;
04929 n = izeta * m_kk * m_kk + jzeta * m_kk + kzeta;
04930 double zeta_LL = psi_ijk_LL[n];
04931 if (zeta_LL != 0.0) {
04932 sum5 = sum5 + molality[j]*molality[k]*zeta_LL;
04933 }
04934 }
04935 }
04936 }
04937 }
04938 m_d2lnActCoeffMolaldT2_Unscaled[i] =
04939 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
04940 #ifdef DEBUG_MODE
04941 if (m_debugCalc) {
04942 sni = speciesName(i);
04943 printf(" %-16s d2lngammadT2[i]=%10.6f\n",
04944 sni.c_str(), m_d2lnActCoeffMolaldT2_Unscaled[i]);
04945 printf(" %12g %12g %12g %12g %12g %12g\n",
04946 zsqd2FdT2, sum1, sum2, sum3, sum4, sum5);
04947 }
04948 #endif
04949 }
04950
04951
04952
04953
04954
04955 if (charge[i] == 0.0 ) {
04956 sum1 = 0.0;
04957 sum3 = 0.0;
04958 for (j = 1; j < m_kk; j++) {
04959 sum1 = sum1 + molality[j]*2.0*m_Lambda_nj_LL(i,j);
04960
04961
04962
04963 if (charge[j] > 0.0) {
04964 for (k = 1; k < m_kk; k++) {
04965 if (charge[k] < 0.0) {
04966 n = k + j * m_kk + i * m_kk * m_kk;
04967 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_LL[n];
04968 }
04969 }
04970 }
04971 }
04972 sum2 = 3.0 * molality[i] * molality[i] * m_Mu_nnn_LL[i];
04973 m_d2lnActCoeffMolaldT2_Unscaled[i] = sum1 + sum2 + sum3;
04974 #ifdef DEBUG_MODE
04975 if (m_debugCalc) {
04976 sni = speciesName(i);
04977 printf(" %-16s d2lngammadT2[i]=%10.6f \n",
04978 sni.c_str(), m_d2lnActCoeffMolaldT2_Unscaled[i]);
04979 }
04980 #endif
04981 }
04982
04983 }
04984 #ifdef DEBUG_MODE
04985 if (m_debugCalc) {
04986 printf(" Step 9: \n");
04987 }
04988 #endif
04989
04990
04991
04992
04993
04994 sum1 = 0.0;
04995 sum2 = 0.0;
04996 sum3 = 0.0;
04997 sum4 = 0.0;
04998 sum5 = 0.0;
04999 double sum6 = 0.0;
05000 double sum7 = 0.0;
05001
05002
05003
05004
05005
05006
05007
05008
05009 term1 = -d2AphidT2 * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
05010
05011 for (j = 1; j < m_kk; j++) {
05012
05013
05014
05015 if (charge[j] > 0.0) {
05016 for (k = 1; k < m_kk; k++){
05017 if (charge[k] < 0.0) {
05018
05019
05020
05021 n = m_kk*j + k;
05022 counterIJ = m_CounterIJ[n];
05023
05024 sum1 = sum1 + molality[j]*molality[k]*
05025 (BphiMX_LL[counterIJ] + molarcharge*CMX_LL[counterIJ]);
05026 }
05027 }
05028
05029 for (k = j+1; k < m_kk; k++) {
05030 if (j == (m_kk-1)) {
05031
05032 printf("logic error 1 in Step 9 of hmw_act");
05033 exit(EXIT_FAILURE);
05034 }
05035 if (charge[k] > 0.0) {
05036
05037
05038
05039
05040 n = m_kk*j + k;
05041 counterIJ = m_CounterIJ[n];
05042 sum2 = sum2 + molality[j]*molality[k]*Phiphi_LL[counterIJ];
05043 for (m = 1; m < m_kk; m++) {
05044 if (charge[m] < 0.0) {
05045
05046 n = m + k * m_kk + j * m_kk * m_kk;
05047 sum2 = sum2 +
05048 molality[j]*molality[k]*molality[m]*psi_ijk_LL[n];
05049 }
05050 }
05051 }
05052 }
05053 }
05054
05055
05056
05057
05058 if (charge[j] < 0) {
05059 for (k = j+1; k < m_kk; k++) {
05060 if (j == m_kk-1) {
05061
05062 printf("logic error 2 in Step 9 of hmw_act");
05063 exit(EXIT_FAILURE);
05064 }
05065 if (charge[k] < 0) {
05066
05067
05068
05069
05070 n = m_kk*j + k;
05071 counterIJ = m_CounterIJ[n];
05072
05073 sum3 = sum3 + molality[j]*molality[k]*Phiphi_LL[counterIJ];
05074 for (m = 1; m < m_kk; m++) {
05075 if (charge[m] > 0.0) {
05076 n = m + k * m_kk + j * m_kk * m_kk;
05077 sum3 = sum3 +
05078 molality[j]*molality[k]*molality[m]*psi_ijk_LL[n];
05079 }
05080 }
05081 }
05082 }
05083 }
05084
05085
05086
05087
05088 if (charge[j] == 0) {
05089 for (k = 1; k < m_kk; k++) {
05090 if (charge[k] < 0.0) {
05091 sum4 = sum4 + molality[j]*molality[k]*m_Lambda_nj_LL(j,k);
05092 }
05093 if (charge[k] > 0.0) {
05094 sum5 = sum5 + molality[j]*molality[k]*m_Lambda_nj_LL(j,k);
05095 }
05096 if (charge[k] == 0.0) {
05097 if (k > j) {
05098 sum6 = sum6 + molality[j]*molality[k]*m_Lambda_nj_LL(j,k);
05099 } else if (k == j) {
05100 sum6 = sum6 + 0.5 * molality[j]*molality[k]*m_Lambda_nj_LL(j,k);
05101 }
05102 }
05103 if (charge[k] < 0.0) {
05104 int izeta = j;
05105 for (m = 1; m < m_kk; m++) {
05106 if (charge[m] > 0.0) {
05107 int jzeta = m;
05108 n = k + jzeta * m_kk + izeta * m_kk * m_kk;
05109 double zeta_LL = psi_ijk_LL[n];
05110 if (zeta_LL != 0.0) {
05111 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_LL;
05112 }
05113 }
05114 }
05115 }
05116 }
05117
05118 sum7 += molality[j] * molality[j] * molality[j] * m_Mu_nnn_LL[j];
05119 }
05120 }
05121 sum_m_phi_minus_1 = 2.0 *
05122 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
05123
05124
05125
05126
05127 if (molalitysum > 1.0E-150) {
05128 d2_osmotic_coef_dT2 = 0.0 + (sum_m_phi_minus_1 / molalitysum);
05129 } else {
05130 d2_osmotic_coef_dT2 = 0.0;
05131 }
05132 #ifdef DEBUG_MODE
05133 if (m_debugCalc) {
05134 printf(" term1=%10.6f sum1=%10.6f sum2=%10.6f "
05135 "sum3=%10.6f sum4=%10.6f sum5=%10.6f\n",
05136 term1, sum1, sum2, sum3, sum4, sum5);
05137 printf(" sum_m_phi_minus_1=%10.6f d2_osmotic_coef_dT2=%10.6f\n",
05138 sum_m_phi_minus_1, d2_osmotic_coef_dT2);
05139 }
05140
05141 if (m_debugCalc) {
05142 printf(" Step 10: \n");
05143 }
05144 #endif
05145 d2_lnwateract_dT2 = -(m_weightSolvent/1000.0) * molalitysum * d2_osmotic_coef_dT2;
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155 m_d2lnActCoeffMolaldT2_Unscaled[0] = d2_lnwateract_dT2;
05156
05157 #ifdef DEBUG_MODE
05158 if (m_debugCalc) {
05159 double d2_wateract_dT2 = exp(d2_lnwateract_dT2);
05160 printf(" d2_ln_a_water_dT2 = %10.6f d2_a_water_dT2=%10.6f\n\n",
05161 d2_lnwateract_dT2, d2_wateract_dT2);
05162 }
05163 #endif
05164 }
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180 void HMWSoln::s_update_dlnMolalityActCoeff_dP() const {
05181
05182 fbo_zero_dbl_1(DATA_PTR(m_dlnActCoeffMolaldP_Unscaled), m_kk);
05183
05184 s_updatePitzer_dlnMolalityActCoeff_dP();
05185
05186
05187 for (int k = 1; k < m_kk; k++) {
05188 if (CROP_speciesCropped_[k] == 2) {
05189 m_dlnActCoeffMolaldP_Unscaled[k] = 0.0;
05190 }
05191 }
05192
05193 if (CROP_speciesCropped_[0]) {
05194 m_dlnActCoeffMolaldP_Unscaled[0] = 0.0;
05195 }
05196
05197
05198 s_updateScaling_pHScaling_dP();
05199 }
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217
05218
05219 void HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP() const {
05220
05221
05222
05223
05224
05225 #ifdef DEBUG_MODE
05226 m_debugCalc = 0;
05227 #endif
05228 if (m_indexSolvent != 0) {
05229 printf("Wrong index solvent value!\n");
05230 exit(EXIT_FAILURE);
05231 }
05232
05233 double d_wateract_dP;
05234 std::string sni, snj, snk;
05235
05236 const double *molality = DATA_PTR(m_molalitiesCropped);
05237 const double *charge = DATA_PTR(m_speciesCharge);
05238 const double *beta0MX_P = DATA_PTR(m_Beta0MX_ij_P);
05239 const double *beta1MX_P = DATA_PTR(m_Beta1MX_ij_P);
05240 const double *beta2MX_P = DATA_PTR(m_Beta2MX_ij_P);
05241 const double *CphiMX_P = DATA_PTR(m_CphiMX_ij_P);
05242 const double *thetaij_P = DATA_PTR(m_Theta_ij_P);
05243 const double *alpha1MX = DATA_PTR(m_Alpha1MX_ij);
05244 const double *alpha2MX = DATA_PTR(m_Alpha2MX_ij);
05245 const double *psi_ijk_P = DATA_PTR(m_Psi_ijk_P);
05246
05247
05248
05249
05250 double etheta[5][5], etheta_prime[5][5], sqrtIs;
05251
05252
05253
05254 double Is = 0.0;
05255
05256
05257
05258
05259 double molarcharge = 0.0;
05260
05261
05262
05263
05264 double molalitysum = 0.0;
05265
05266 double *gfunc = DATA_PTR(m_gfunc_IJ);
05267 double *g2func = DATA_PTR(m_g2func_IJ);
05268 double *hfunc = DATA_PTR(m_hfunc_IJ);
05269 double *h2func = DATA_PTR(m_h2func_IJ);
05270 double *BMX_P = DATA_PTR(m_BMX_IJ_P);
05271 double *BprimeMX_P= DATA_PTR(m_BprimeMX_IJ_P);
05272 double *BphiMX_P = DATA_PTR(m_BphiMX_IJ_P);
05273 double *Phi_P = DATA_PTR(m_Phi_IJ_P);
05274 double *Phiprime = DATA_PTR(m_Phiprime_IJ);
05275 double *Phiphi_P = DATA_PTR(m_PhiPhi_IJ_P);
05276 double *CMX_P = DATA_PTR(m_CMX_IJ_P);
05277
05278 double x1, x2;
05279 double Aphi, dFdP, zsqdFdP;
05280 double sum1, sum2, sum3, sum4, sum5, term1;
05281 double sum_m_phi_minus_1, d_osmotic_coef_dP, d_lnwateract_dP;
05282
05283 int z1, z2;
05284 int n, i, j, k, m, counterIJ, counterIJ2;
05285
05286 double currTemp = temperature();
05287 double currPres = pressure();
05288
05289 #ifdef DEBUG_MODE
05290 if (m_debugCalc) {
05291 printf("\n Debugging information from "
05292 "s_Pitzer_dlnMolalityActCoeff_dP()\n");
05293 }
05294 #endif
05295
05296
05297
05298 counterIJ_setup();
05299
05300
05301
05302
05303 for (n = 1; n < m_kk; n++) {
05304
05305 Is += charge[n] * charge[n] * molality[n];
05306
05307 molarcharge += fabs(charge[n]) * molality[n];
05308 molalitysum += molality[n];
05309 }
05310 Is *= 0.5;
05311
05312
05313
05314
05315 m_IionicMolality = Is;
05316 sqrtIs = sqrt(Is);
05317 #ifdef DEBUG_MODE
05318 if (m_debugCalc) {
05319 printf(" Step 1: \n");
05320 printf(" ionic strenth = %14.7le \n total molar "
05321 "charge = %14.7le \n", Is, molarcharge);
05322 }
05323 #endif
05324
05325
05326
05327
05328
05329
05330 calc_lambdas(Is);
05331
05332
05333
05334
05335
05336
05337
05338 #ifdef DEBUG_MODE
05339 if (m_debugCalc) {
05340 printf(" Step 2: \n");
05341 }
05342 #endif
05343 for (z1 = 1; z1 <=4; z1++) {
05344 for (z2 =1; z2 <=4; z2++) {
05345 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
05346 #ifdef DEBUG_MODE
05347 if (m_debugCalc) {
05348 printf(" z1=%3d z2=%3d E-theta(I) = %f, E-thetaprime(I) = %f\n",
05349 z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
05350 }
05351 #endif
05352 }
05353 }
05354
05355 #ifdef DEBUG_MODE
05356 if (m_debugCalc) {
05357 printf(" Step 3: \n");
05358 printf(" Species Species g(x) "
05359 " hfunc(x) \n");
05360 }
05361 #endif
05362
05363
05364
05365
05366
05367
05368
05369 for (i = 1; i < (m_kk - 1); i++) {
05370 for (j = (i+1); j < m_kk; j++) {
05371
05372
05373
05374 n = m_kk*i + j;
05375 counterIJ = m_CounterIJ[n];
05376
05377
05378
05379 if (charge[i]*charge[j] < 0) {
05380
05381
05382
05383 x1 = sqrtIs * alpha1MX[counterIJ];
05384 if (x1 > 1.0E-100) {
05385 gfunc[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
05386 hfunc[counterIJ] = -2.0*
05387 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
05388 }
05389 else {
05390 gfunc[counterIJ] = 0.0;
05391 hfunc[counterIJ] = 0.0;
05392 }
05393
05394 if (beta2MX_P[counterIJ] != 0.0) {
05395 x2 = sqrtIs * alpha2MX[counterIJ];
05396 if (x2 > 1.0E-100) {
05397 g2func[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
05398 h2func[counterIJ] = -2.0 *
05399 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
05400 } else {
05401 g2func[counterIJ] = 0.0;
05402 h2func[counterIJ] = 0.0;
05403 }
05404 }
05405 }
05406 else {
05407 gfunc[counterIJ] = 0.0;
05408 hfunc[counterIJ] = 0.0;
05409 }
05410 #ifdef DEBUG_MODE
05411 if (m_debugCalc) {
05412 sni = speciesName(i);
05413 snj = speciesName(j);
05414 printf(" %-16s %-16s %9.5f %9.5f \n", sni.c_str(), snj.c_str(),
05415 gfunc[counterIJ], hfunc[counterIJ]);
05416 }
05417 #endif
05418 }
05419 }
05420
05421
05422
05423
05424
05425
05426 #ifdef DEBUG_MODE
05427 if (m_debugCalc) {
05428 printf(" Step 4: \n");
05429 printf(" Species Species BMX "
05430 "BprimeMX BphiMX \n");
05431 }
05432 #endif
05433
05434 for (i = 1; i < m_kk - 1; i++) {
05435 for (j = i+1; j < m_kk; j++) {
05436
05437
05438
05439 n = m_kk*i + j;
05440 counterIJ = m_CounterIJ[n];
05441
05442
05443
05444
05445 if (charge[i]*charge[j] < 0.0) {
05446 BMX_P[counterIJ] = beta0MX_P[counterIJ]
05447 + beta1MX_P[counterIJ] * gfunc[counterIJ]
05448 + beta2MX_P[counterIJ] * g2func[counterIJ];
05449 #ifdef DEBUG_MODE
05450 if (m_debugCalc) {
05451 printf("%d %g: %g %g %g %g\n",
05452 counterIJ, BMX_P[counterIJ], beta0MX_P[counterIJ],
05453 beta1MX_P[counterIJ], beta2MX_P[counterIJ], gfunc[counterIJ]);
05454 }
05455 #endif
05456 if (Is > 1.0E-150) {
05457 BprimeMX_P[counterIJ] = (beta1MX_P[counterIJ] * hfunc[counterIJ]/Is +
05458 beta2MX_P[counterIJ] * h2func[counterIJ]/Is);
05459 } else {
05460 BprimeMX_P[counterIJ] = 0.0;
05461 }
05462 BphiMX_P[counterIJ] = BMX_P[counterIJ] + Is*BprimeMX_P[counterIJ];
05463 }
05464 else {
05465 BMX_P[counterIJ] = 0.0;
05466 BprimeMX_P[counterIJ] = 0.0;
05467 BphiMX_P[counterIJ] = 0.0;
05468 }
05469 #ifdef DEBUG_MODE
05470 if (m_debugCalc) {
05471 sni = speciesName(i);
05472 snj = speciesName(j);
05473 printf(" %-16s %-16s %11.7f %11.7f %11.7f \n",
05474 sni.c_str(), snj.c_str(),
05475 BMX_P[counterIJ], BprimeMX_P[counterIJ], BphiMX_P[counterIJ]);
05476 }
05477 #endif
05478 }
05479 }
05480
05481
05482
05483
05484
05485 #ifdef DEBUG_MODE
05486 if (m_debugCalc) {
05487 printf(" Step 5: \n");
05488 printf(" Species Species CMX \n");
05489 }
05490 #endif
05491 for (i = 1; i < m_kk-1; i++) {
05492 for (j = i+1; j < m_kk; j++) {
05493
05494
05495
05496 n = m_kk*i + j;
05497 counterIJ = m_CounterIJ[n];
05498
05499
05500
05501
05502 if (charge[i]*charge[j] < 0.0) {
05503 CMX_P[counterIJ] = CphiMX_P[counterIJ]/
05504 (2.0* sqrt(fabs(charge[i]*charge[j])));
05505 }
05506 else {
05507 CMX_P[counterIJ] = 0.0;
05508 }
05509 #ifdef DEBUG_MODE
05510 if (m_debugCalc) {
05511 sni = speciesName(i);
05512 snj = speciesName(j);
05513 printf(" %-16s %-16s %11.7f \n", sni.c_str(), snj.c_str(),
05514 CMX_P[counterIJ]);
05515 }
05516 #endif
05517 }
05518 }
05519
05520
05521
05522
05523
05524 #ifdef DEBUG_MODE
05525 if (m_debugCalc) {
05526 printf(" Step 6: \n");
05527 printf(" Species Species Phi_ij "
05528 " Phiprime_ij Phi^phi_ij \n");
05529 }
05530 #endif
05531 for (i = 1; i < m_kk-1; i++) {
05532 for (j = i+1; j < m_kk; j++) {
05533
05534
05535
05536 n = m_kk*i + j;
05537 counterIJ = m_CounterIJ[n];
05538
05539
05540
05541
05542 if (charge[i]*charge[j] > 0) {
05543 z1 = (int) fabs(charge[i]);
05544 z2 = (int) fabs(charge[j]);
05545
05546 Phi_P[counterIJ] = thetaij_P[counterIJ];
05547
05548 Phiprime[counterIJ] = 0.0;
05549 Phiphi_P[counterIJ] = Phi_P[counterIJ] + Is * Phiprime[counterIJ];
05550 }
05551 else {
05552 Phi_P[counterIJ] = 0.0;
05553 Phiprime[counterIJ] = 0.0;
05554 Phiphi_P[counterIJ] = 0.0;
05555 }
05556 #ifdef DEBUG_MODE
05557 if (m_debugCalc) {
05558 sni = speciesName(i);
05559 snj = speciesName(j);
05560 printf(" %-16s %-16s %10.6f %10.6f %10.6f \n",
05561 sni.c_str(), snj.c_str(),
05562 Phi_P[counterIJ], Phiprime[counterIJ], Phiphi_P[counterIJ] );
05563 }
05564 #endif
05565 }
05566 }
05567
05568
05569
05570
05571 #ifdef DEBUG_MODE
05572 if (m_debugCalc) {
05573 printf(" Step 7: \n");
05574 }
05575 #endif
05576
05577
05578
05579
05580 Aphi = m_A_Debye / 3.0;
05581
05582 double dA_DebyedP = dA_DebyedP_TP(currTemp, currPres);
05583 double dAphidP = dA_DebyedP /3.0;
05584 #ifdef DEBUG_MODE
05585
05586 #endif
05587
05588
05589
05590 dFdP = -dAphidP * ( sqrt(Is) / (1.0 + 1.2*sqrt(Is))
05591 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
05592 #ifdef DEBUG_MODE
05593 if (m_debugCalc) {
05594 printf(" initial value of dFdP = %10.6f \n", dFdP );
05595 }
05596 #endif
05597 for (i = 1; i < m_kk-1; i++) {
05598 for (j = i+1; j < m_kk; j++) {
05599
05600
05601
05602 n = m_kk*i + j;
05603 counterIJ = m_CounterIJ[n];
05604
05605
05606
05607
05608 if (charge[i]*charge[j] < 0) {
05609 dFdP = dFdP + molality[i]*molality[j] * BprimeMX_P[counterIJ];
05610 }
05611
05612
05613
05614
05615 if (charge[i]*charge[j] > 0) {
05616 dFdP = dFdP + molality[i]*molality[j] * Phiprime[counterIJ];
05617 }
05618 #ifdef DEBUG_MODE
05619 if (m_debugCalc) printf(" dFdP = %10.6f \n", dFdP);
05620 #endif
05621 }
05622 }
05623 #ifdef DEBUG_MODE
05624 if (m_debugCalc) {
05625 printf(" Step 8: \n");
05626 }
05627 #endif
05628
05629
05630 for (i = 1; i < m_kk; i++) {
05631
05632
05633
05634
05635
05636 if (charge[i] > 0 ) {
05637
05638 zsqdFdP = charge[i]*charge[i]*dFdP;
05639 sum1 = 0.0;
05640 sum2 = 0.0;
05641 sum3 = 0.0;
05642 sum4 = 0.0;
05643 sum5 = 0.0;
05644 for (j = 1; j < m_kk; j++) {
05645
05646
05647
05648 n = m_kk*i + j;
05649 counterIJ = m_CounterIJ[n];
05650
05651 if (charge[j] < 0.0) {
05652
05653 sum1 = sum1 + molality[j]*
05654 (2.0*BMX_P[counterIJ] + molarcharge*CMX_P[counterIJ]);
05655 if (j < m_kk-1) {
05656
05657
05658
05659
05660
05661 for (k = j+1; k < m_kk; k++) {
05662
05663 if (charge[k] < 0.0) {
05664 n = k + j * m_kk + i * m_kk * m_kk;
05665 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_P[n];
05666 }
05667 }
05668 }
05669 }
05670
05671
05672 if (charge[j] > 0.0) {
05673
05674 if (j != i) {
05675 sum2 = sum2 + molality[j]*(2.0*Phi_P[counterIJ]);
05676 }
05677 for (k = 1; k < m_kk; k++) {
05678 if (charge[k] < 0.0) {
05679
05680
05681 n = k + j * m_kk + i * m_kk * m_kk;
05682 sum2 = sum2 + molality[j]*molality[k]*psi_ijk_P[n];
05683
05684
05685
05686 n = m_kk*j + k;
05687 counterIJ2 = m_CounterIJ[n];
05688 sum4 = sum4 + (fabs(charge[i])*
05689 molality[j]*molality[k]*CMX_P[counterIJ2]);
05690 }
05691 }
05692 }
05693
05694
05695
05696
05697 if (charge[j] == 0) {
05698 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj_P(j,i);
05699
05700
05701
05702 for (int k = 1; k < m_kk; k++) {
05703 if (charge[k] < 0.0) {
05704 int izeta = j;
05705 int jzeta = i;
05706 n = izeta * m_kk * m_kk + jzeta * m_kk + k;
05707 double zeta_P = psi_ijk_P[n];
05708 if (zeta_P != 0.0) {
05709 sum5 = sum5 + molality[j]*molality[k]*zeta_P;
05710 }
05711 }
05712 }
05713 }
05714 }
05715
05716
05717
05718
05719
05720 m_dlnActCoeffMolaldP_Unscaled[i] =
05721 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
05722
05723 #ifdef DEBUG_MODE
05724 if (m_debugCalc) {
05725 sni = speciesName(i);
05726 printf(" %-16s lngamma[i]=%10.6f \n",
05727 sni.c_str(), m_dlnActCoeffMolaldP_Unscaled[i]);
05728 printf(" %12g %12g %12g %12g %12g %12g\n",
05729 zsqdFdP, sum1, sum2, sum3, sum4, sum5);
05730 }
05731 #endif
05732 }
05733
05734
05735
05736
05737
05738
05739 if (charge[i] < 0) {
05740
05741 zsqdFdP = charge[i]*charge[i]*dFdP;
05742 sum1 = 0.0;
05743 sum2 = 0.0;
05744 sum3 = 0.0;
05745 sum4 = 0.0;
05746 sum5 = 0.0;
05747 for (j = 1; j < m_kk; j++) {
05748
05749
05750
05751 n = m_kk*i + j;
05752 counterIJ = m_CounterIJ[n];
05753
05754
05755
05756
05757 if (charge[j] > 0) {
05758 sum1 = sum1 + molality[j]*
05759 (2.0*BMX_P[counterIJ] + molarcharge*CMX_P[counterIJ]);
05760 if (j < m_kk-1) {
05761 for (k = j+1; k < m_kk; k++) {
05762
05763 if (charge[k] > 0) {
05764 n = k + j * m_kk + i * m_kk * m_kk;
05765 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_P[n];
05766 }
05767 }
05768 }
05769 }
05770
05771
05772
05773
05774 if (charge[j] < 0.0) {
05775
05776 if (j != i) {
05777 sum2 = sum2 + molality[j]*(2.0*Phi_P[counterIJ]);
05778 }
05779 for (k = 1; k < m_kk; k++) {
05780 if (charge[k] > 0.0) {
05781
05782 n = k + j * m_kk + i * m_kk * m_kk;
05783 sum2 = sum2 + molality[j]*molality[k]*psi_ijk_P[n];
05784
05785
05786
05787 n = m_kk*j + k;
05788 counterIJ2 = m_CounterIJ[n];
05789 sum4 = sum4 +
05790 (fabs(charge[i])*
05791 molality[j]*molality[k]*CMX_P[counterIJ2]);
05792 }
05793 }
05794 }
05795
05796
05797
05798
05799 if (charge[j] == 0.0) {
05800 sum5 = sum5 + molality[j]*2.0*m_Lambda_nj_P(j,i);
05801
05802
05803
05804 for (int k = 1; k < m_kk; k++) {
05805 if (charge[k] > 0.0) {
05806 int izeta = j;
05807 int jzeta = k;
05808 int kzeta = i;
05809 n = izeta * m_kk * m_kk + jzeta * m_kk + kzeta;
05810 double zeta_P = psi_ijk_P[n];
05811 if (zeta_P != 0.0) {
05812 sum5 = sum5 + molality[j]*molality[k]*zeta_P;
05813 }
05814 }
05815 }
05816 }
05817 }
05818 m_dlnActCoeffMolaldP_Unscaled[i] =
05819 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
05820 #ifdef DEBUG_MODE
05821 if (m_debugCalc) {
05822 sni = speciesName(i);
05823 printf(" %-16s lndactcoeffmolaldP[i]=%10.6f \n",
05824 sni.c_str(), m_dlnActCoeffMolaldP_Unscaled[i]);
05825 printf(" %12g %12g %12g %12g %12g %12g\n",
05826 zsqdFdP, sum1, sum2, sum3, sum4, sum5);
05827 }
05828 #endif
05829 }
05830
05831
05832
05833
05834 if (charge[i] == 0.0) {
05835 sum1 = 0.0;
05836 sum3 = 0.0;
05837 for (j = 1; j < m_kk; j++) {
05838 sum1 += molality[j]*2.0*m_Lambda_nj_P(i,j);
05839
05840
05841
05842 if (charge[j] > 0.0) {
05843 for (k = 1; k < m_kk; k++) {
05844 if (charge[k] < 0.0) {
05845 n = k + j * m_kk + i * m_kk * m_kk;
05846 sum3 = sum3 + molality[j]*molality[k]*psi_ijk_P[n];
05847 }
05848 }
05849 }
05850 }
05851 sum2 = 3.0 * molality[i] * molality[i] * m_Mu_nnn_P[i];
05852 m_dlnActCoeffMolaldP_Unscaled[i] = sum1 + sum2 + sum3;
05853 #ifdef DEBUG_MODE
05854 if (m_debugCalc) {
05855 sni = speciesName(i);
05856 printf(" %-16s dlnActCoeffMolaldP[i]=%10.6f \n",
05857 sni.c_str(), m_dlnActCoeffMolaldP_Unscaled[i]);
05858 }
05859 #endif
05860 }
05861
05862 }
05863 #ifdef DEBUG_MODE
05864 if (m_debugCalc) {
05865 printf(" Step 9: \n");
05866 }
05867 #endif
05868
05869
05870
05871
05872
05873 sum1 = 0.0;
05874 sum2 = 0.0;
05875 sum3 = 0.0;
05876 sum4 = 0.0;
05877 sum5 = 0.0;
05878 double sum6 = 0.0;
05879 double sum7 = 0.0;
05880
05881
05882
05883
05884
05885
05886
05887
05888 term1 = -dAphidP * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
05889
05890 for (j = 1; j < m_kk; j++) {
05891
05892
05893
05894 if (charge[j] > 0.0) {
05895 for (k = 1; k < m_kk; k++){
05896 if (charge[k] < 0.0) {
05897
05898
05899
05900 n = m_kk*j + k;
05901 counterIJ = m_CounterIJ[n];
05902
05903 sum1 = sum1 + molality[j]*molality[k]*
05904 (BphiMX_P[counterIJ] + molarcharge*CMX_P[counterIJ]);
05905 }
05906 }
05907
05908 for (k = j+1; k < m_kk; k++) {
05909 if (j == (m_kk-1)) {
05910
05911 printf("logic error 1 in Step 9 of hmw_act");
05912 exit(EXIT_FAILURE);
05913 }
05914 if (charge[k] > 0.0) {
05915
05916
05917
05918
05919 n = m_kk*j + k;
05920 counterIJ = m_CounterIJ[n];
05921 sum2 = sum2 + molality[j]*molality[k]*Phiphi_P[counterIJ];
05922 for (m = 1; m < m_kk; m++) {
05923 if (charge[m] < 0.0) {
05924
05925 n = m + k * m_kk + j * m_kk * m_kk;
05926 sum2 = sum2 +
05927 molality[j]*molality[k]*molality[m]*psi_ijk_P[n];
05928 }
05929 }
05930 }
05931 }
05932 }
05933
05934
05935
05936
05937
05938 if (charge[j] < 0) {
05939 for (k = j+1; k < m_kk; k++) {
05940 if (j == m_kk-1) {
05941
05942 printf("logic error 2 in Step 9 of hmw_act");
05943 exit(EXIT_FAILURE);
05944 }
05945 if (charge[k] < 0) {
05946
05947
05948
05949
05950 n = m_kk*j + k;
05951 counterIJ = m_CounterIJ[n];
05952
05953 sum3 = sum3 + molality[j]*molality[k]*Phiphi_P[counterIJ];
05954 for (m = 1; m < m_kk; m++) {
05955 if (charge[m] > 0.0) {
05956 n = m + k * m_kk + j * m_kk * m_kk;
05957 sum3 = sum3 +
05958 molality[j]*molality[k]*molality[m]*psi_ijk_P[n];
05959 }
05960 }
05961 }
05962 }
05963 }
05964
05965
05966
05967
05968 if (charge[j] == 0) {
05969 for (k = 1; k < m_kk; k++) {
05970 if (charge[k] < 0.0) {
05971 sum4 = sum4 + molality[j]*molality[k]*m_Lambda_nj_P(j,k);
05972 }
05973 if (charge[k] > 0.0) {
05974 sum5 = sum5 + molality[j]*molality[k]*m_Lambda_nj_P(j,k);
05975 }
05976 if (charge[k] == 0.0) {
05977 if (k > j) {
05978 sum6 = sum6 + molality[j]*molality[k]*m_Lambda_nj_P(j,k);
05979 } else if (k == j) {
05980 sum6 = sum6 + 0.5 * molality[j]*molality[k]*m_Lambda_nj_P(j,k);
05981 }
05982 }
05983 if (charge[k] < 0.0) {
05984 int izeta = j;
05985 for (m = 1; m < m_kk; m++) {
05986 if (charge[m] > 0.0) {
05987 int jzeta = m;
05988 n = k + jzeta * m_kk + izeta * m_kk * m_kk;
05989 double zeta_P = psi_ijk_P[n];
05990 if (zeta_P != 0.0) {
05991 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_P;
05992 }
05993 }
05994 }
05995 }
05996 }
05997
05998 sum7 += molality[j] * molality[j] * molality[j] * m_Mu_nnn_P[j];
05999 }
06000 }
06001 sum_m_phi_minus_1 = 2.0 *
06002 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
06003
06004
06005
06006
06007
06008 if (molalitysum > 1.0E-150) {
06009 d_osmotic_coef_dP = 0.0 + (sum_m_phi_minus_1 / molalitysum);
06010 } else {
06011 d_osmotic_coef_dP = 0.0;
06012 }
06013 #ifdef DEBUG_MODE
06014 if (m_debugCalc) {
06015 printf(" term1=%10.6f sum1=%10.6f sum2=%10.6f "
06016 "sum3=%10.6f sum4=%10.6f sum5=%10.6f\n",
06017 term1, sum1, sum2, sum3, sum4, sum5);
06018 printf(" sum_m_phi_minus_1=%10.6f d_osmotic_coef_dP =%10.6f\n",
06019 sum_m_phi_minus_1, d_osmotic_coef_dP);
06020 }
06021
06022 if (m_debugCalc) {
06023 printf(" Step 10: \n");
06024 }
06025 #endif
06026 d_lnwateract_dP = -(m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dP;
06027 d_wateract_dP = exp(d_lnwateract_dP);
06028
06029
06030
06031
06032
06033
06034
06035
06036
06037
06038 m_dlnActCoeffMolaldP_Unscaled[0] = d_lnwateract_dP;
06039 #ifdef DEBUG_MODE
06040 if (m_debugCalc) {
06041 printf(" d_ln_a_water_dP = %10.6f d_a_water_dP=%10.6f\n\n",
06042 d_lnwateract_dP, d_wateract_dP);
06043 }
06044 #endif
06045
06046 }
06047
06048
06049
06050
06051
06052
06053
06054
06055
06056
06057
06058 void HMWSoln::calc_lambdas(double is) const {
06059 double aphi, dj, jfunc, jprime, t, x, zprod;
06060 int i, ij, j;
06061
06062
06063
06064
06065
06066
06067 double c1 = 4.581, c2 = 0.7237, c3 = 0.0120, c4 = 0.528;
06068
06069 aphi = 0.392;
06070 #ifdef DEBUG_MODE
06071 if (m_debugCalc) {
06072 printf(" Is = %g\n", is);
06073 }
06074 #endif
06075 if (is < 1.0E-150) {
06076 for (i = 0; i < 17; i++) {
06077 elambda[i] = 0.0;
06078 elambda1[i] = 0.0;
06079 }
06080 return;
06081 }
06082
06083
06084
06085
06086
06087 for (i=1; i<=4; i++) {
06088 for (j=i; j<=4; j++) {
06089 ij = i*j;
06090
06091
06092
06093 zprod = (double)ij;
06094
06095
06096
06097 x = 6.0* zprod * aphi * sqrt(is);
06098
06099 jfunc = x / (4.0 + c1*pow(x,-c2)*exp(-c3*pow(x,c4)));
06100
06101 t = c3 * c4 * pow(x,c4);
06102 dj = c1* pow(x,(-c2-1.0)) * (c2+t) * exp(-c3*pow(x,c4));
06103 jprime = (jfunc/x)*(1.0 + jfunc*dj);
06104
06105 elambda[ij] = zprod*jfunc / (4.0*is);
06106 elambda1[ij] = (3.0*zprod*zprod*aphi*jprime/(4.0*sqrt(is))
06107 - elambda[ij])/is;
06108 #ifdef DEBUG_MODE
06109 if (m_debugCalc) {
06110 printf(" ij = %d, elambda = %g, elambda1 = %g\n",
06111 ij, elambda[ij], elambda1[ij]);
06112 }
06113 #endif
06114 }
06115 }
06116 }
06117
06118
06119
06120
06121
06122
06123
06124
06125
06126
06127 void HMWSoln::calc_thetas(int z1, int z2,
06128 double *etheta, double *etheta_prime) const {
06129 int i, j;
06130 double f1, f2;
06131
06132
06133
06134
06135
06136 i = abs(z1);
06137 j = abs(z2);
06138
06139 #ifdef DEBUG_MODE
06140 if (i > 4 || j > 4) {
06141 printf("we shouldn't be here\n");
06142 exit(EXIT_FAILURE);
06143 }
06144 #endif
06145
06146 if ((i == 0) || (j == 0)) {
06147 printf("ERROR calc_thetas called with one species being neutral\n");
06148 exit(EXIT_FAILURE);
06149 }
06150
06151
06152
06153
06154
06155 if (z1*z2 < 0) {
06156 *etheta = 0.0;
06157 *etheta_prime = 0.0;
06158 }
06159
06160
06161
06162 else {
06163 f1 = (double)i / (2.0 * j);
06164 f2 = (double)j / (2.0 * i);
06165 *etheta = elambda[i*j] - f1*elambda[j*j] - f2*elambda[i*i];
06166 *etheta_prime = elambda1[i*j] - f1*elambda1[j*j] - f2*elambda1[i*i];
06167 }
06168 }
06169
06170
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180 void HMWSoln::s_updateIMS_lnMolalityActCoeff() const {
06181 int k;
06182 double tmp;
06183
06184
06185
06186
06187
06188 calcMolalities();
06189
06190 double xmolSolvent = moleFraction(m_indexSolvent);
06191 double xx = MAX(m_xmolSolventMIN, xmolSolvent);
06192 if (IMS_typeCutoff_ == 0) {
06193 for (k = 1; k < m_kk; k++) {
06194 IMS_lnActCoeffMolal_[k]= 0.0;
06195 }
06196 IMS_lnActCoeffMolal_[m_indexSolvent] = - log(xx) + (xx - 1.0)/xx;
06197 return;
06198 } else if (IMS_typeCutoff_ == 1) {
06199 if (xmolSolvent > 3.0 * IMS_X_o_cutoff_/2.0 ) {
06200 for (k = 1; k < m_kk; k++) {
06201 IMS_lnActCoeffMolal_[k]= 0.0;
06202 }
06203 IMS_lnActCoeffMolal_[m_indexSolvent] = - log(xx) + (xx - 1.0)/xx;
06204 return;
06205 } else if (xmolSolvent < IMS_X_o_cutoff_/2.0) {
06206 tmp = log(xx * IMS_gamma_k_min_);
06207 for (k = 1; k < m_kk; k++) {
06208 IMS_lnActCoeffMolal_[k]= tmp;
06209 }
06210 IMS_lnActCoeffMolal_[m_indexSolvent] = log(IMS_gamma_o_min_);
06211 return;
06212 } else {
06213
06214
06215
06216 double xminus = xmolSolvent - IMS_X_o_cutoff_/2.0;
06217 double xminus2 = xminus * xminus;
06218 double xminus3 = xminus2 * xminus;
06219 double x_o_cut2 = IMS_X_o_cutoff_ * IMS_X_o_cutoff_;
06220 double x_o_cut3 = x_o_cut2 * IMS_X_o_cutoff_;
06221
06222 double h2 = 3.5 * xminus2 / IMS_X_o_cutoff_ - 2.0 * xminus3 / x_o_cut2;
06223 double h2_prime = 7.0 * xminus / IMS_X_o_cutoff_ - 6.0 * xminus2 / x_o_cut2;
06224
06225 double h1 = (1.0 - 3.0 * xminus2 / x_o_cut2 + 2.0 * xminus3/ x_o_cut3);
06226 double h1_prime = (- 6.0 * xminus / x_o_cut2 + 6.0 * xminus2/ x_o_cut3);
06227
06228 double h1_g = h1 / IMS_gamma_o_min_;
06229 double h1_g_prime = h1_prime / IMS_gamma_o_min_;
06230
06231 double alpha = 1.0 / ( exp(1.0) * IMS_gamma_k_min_);
06232 double h1_f = h1 * alpha;
06233 double h1_f_prime = h1_prime * alpha;
06234
06235 double f = h2 + h1_f;
06236 double f_prime = h2_prime + h1_f_prime;
06237
06238 double g = h2 + h1_g;
06239 double g_prime = h2_prime + h1_g_prime;
06240
06241 tmp = (xmolSolvent/ g * g_prime + (1.0-xmolSolvent) / f * f_prime);
06242 double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
06243 double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
06244
06245 tmp = log(xmolSolvent) + lngammak;
06246 for (k = 1; k < m_kk; k++) {
06247 IMS_lnActCoeffMolal_[k]= tmp;
06248 }
06249 IMS_lnActCoeffMolal_[m_indexSolvent] = lngammao;
06250 }
06251 }
06252
06253 else if (IMS_typeCutoff_ == 2) {
06254 if (xmolSolvent > IMS_X_o_cutoff_) {
06255 for (k = 1; k < m_kk; k++) {
06256 IMS_lnActCoeffMolal_[k]= 0.0;
06257 }
06258 IMS_lnActCoeffMolal_[m_indexSolvent] = - log(xx) + (xx - 1.0)/xx;
06259 return;
06260 } else {
06261
06262 double xoverc = xmolSolvent/IMS_cCut_;
06263 double eterm = std::exp(-xoverc);
06264
06265 double fptmp = IMS_bfCut_ - IMS_afCut_ / IMS_cCut_ - IMS_bfCut_*xoverc
06266 + 2.0*IMS_dfCut_*xmolSolvent - IMS_dfCut_*xmolSolvent*xoverc;
06267 double f_prime = 1.0 + eterm*fptmp;
06268 double f = xmolSolvent + IMS_efCut_
06269 + eterm * (IMS_afCut_ + xmolSolvent * (IMS_bfCut_ + IMS_dfCut_*xmolSolvent));
06270
06271 double gptmp = IMS_bgCut_ - IMS_agCut_ / IMS_cCut_ - IMS_bgCut_*xoverc
06272 + 2.0*IMS_dgCut_*xmolSolvent - IMS_dgCut_*xmolSolvent*xoverc;
06273 double g_prime = 1.0 + eterm*gptmp;
06274 double g = xmolSolvent + IMS_egCut_
06275 + eterm * (IMS_agCut_ + xmolSolvent * (IMS_bgCut_ + IMS_dgCut_*xmolSolvent));
06276
06277 tmp = (xmolSolvent / g * g_prime + (1.0 - xmolSolvent) / f * f_prime);
06278 double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
06279 double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
06280
06281 tmp = log(xx) + lngammak;
06282 for (k = 1; k < m_kk; k++) {
06283 IMS_lnActCoeffMolal_[k]= tmp;
06284 }
06285 IMS_lnActCoeffMolal_[m_indexSolvent] = lngammao;
06286 }
06287 }
06288 return;
06289 }
06290
06291
06292
06293
06294
06295
06296 void HMWSoln::printCoeffs() const {
06297 int i, j, k;
06298 std::string sni, snj;
06299 calcMolalities();
06300 const double *charge = DATA_PTR(m_speciesCharge);
06301 double *molality = DATA_PTR(m_molalitiesCropped);
06302 double *moleF = DATA_PTR(m_tmpV);
06303
06304
06305
06306
06307 s_updatePitzer_CoeffWRTemp(2);
06308 getMoleFractions(moleF);
06309
06310 printf("Index Name MoleF MolalityCropped Charge\n");
06311 for (k = 0; k < m_kk; k++) {
06312 sni = speciesName(k);
06313 printf("%2d %-16s %14.7le %14.7le %5.1f \n",
06314 k, sni.c_str(), moleF[k], molality[k], charge[k]);
06315 }
06316
06317 printf("\n Species Species beta0MX "
06318 "beta1MX beta2MX CphiMX alphaMX thetaij \n");
06319 for (i = 1; i < m_kk - 1; i++) {
06320 sni = speciesName(i);
06321 for (j = i+1; j < m_kk; j++) {
06322 snj = speciesName(j);
06323 int n = i * m_kk + j;
06324 int ct = m_CounterIJ[n];
06325 printf(" %-16s %-16s %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f \n",
06326 sni.c_str(), snj.c_str(),
06327 m_Beta0MX_ij[ct], m_Beta1MX_ij[ct],
06328 m_Beta2MX_ij[ct], m_CphiMX_ij[ct],
06329 m_Alpha1MX_ij[ct], m_Theta_ij[ct] );
06330
06331
06332 }
06333 }
06334
06335 printf("\n Species Species Species "
06336 "psi \n");
06337 for (i = 1; i < m_kk; i++) {
06338 sni = speciesName(i);
06339 for (j = 1; j < m_kk; j++) {
06340 snj = speciesName(j);
06341 for (k = 1; k < m_kk; k++) {
06342 std::string snk = speciesName(k);
06343 int n = k + j * m_kk + i * m_kk * m_kk;
06344 if (m_Psi_ijk[n] != 0.0) {
06345 printf(" %-16s %-16s %-16s %9.5f \n",
06346 sni.c_str(), snj.c_str(),
06347 snk.c_str(), m_Psi_ijk[n]);
06348 }
06349 }
06350 }
06351 }
06352 }
06353
06354
06355
06356
06357
06358
06359
06360
06361 void HMWSoln::applyphScale(doublereal *acMolality) const {
06362 if (m_pHScalingType == PHSCALE_PITZER) {
06363 return;
06364 }
06365 AssertTrace(m_pHScalingType == PHSCALE_NBS);
06366 doublereal lnGammaClMs2 = s_NBS_CLM_lnMolalityActCoeff();
06367 doublereal lnGammaCLMs1 = m_lnActCoeffMolal_Unscaled[m_indexCLM];
06368 doublereal afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
06369 for (int k = 0; k < m_kk; k++) {
06370 acMolality[k] *= exp(m_speciesCharge[k] * afac);
06371 }
06372 }
06373
06374
06375
06376
06377
06378
06379
06380
06381 void HMWSoln::s_updateScaling_pHScaling() const {
06382 if (m_pHScalingType == PHSCALE_PITZER) {
06383 fvo_copy_dbl_1(m_lnActCoeffMolal_Scaled, m_lnActCoeffMolal_Unscaled, m_kk);
06384 return;
06385 }
06386 AssertTrace(m_pHScalingType == PHSCALE_NBS);
06387 doublereal lnGammaClMs2 = s_NBS_CLM_lnMolalityActCoeff();
06388 doublereal lnGammaCLMs1 = m_lnActCoeffMolal_Unscaled[m_indexCLM];
06389 doublereal afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
06390 for (int k = 0; k < m_kk; k++) {
06391 m_lnActCoeffMolal_Scaled[k] = m_lnActCoeffMolal_Unscaled[k] + m_speciesCharge[k] * afac;
06392 }
06393 }
06394
06395
06396
06397
06398
06399
06400
06401 void HMWSoln::s_updateScaling_pHScaling_dT() const {
06402 if (m_pHScalingType == PHSCALE_PITZER) {
06403 fvo_copy_dbl_1(m_dlnActCoeffMolaldT_Scaled, m_dlnActCoeffMolaldT_Unscaled, m_kk);
06404 return;
06405 }
06406 AssertTrace(m_pHScalingType == PHSCALE_NBS);
06407 doublereal dlnGammaClM_dT_s2 = s_NBS_CLM_dlnMolalityActCoeff_dT();
06408 doublereal dlnGammaCLM_dT_s1 = m_dlnActCoeffMolaldT_Unscaled[m_indexCLM];
06409 doublereal afac = -1.0 *(dlnGammaClM_dT_s2 - dlnGammaCLM_dT_s1);
06410 for (int k = 0; k < m_kk; k++) {
06411 m_dlnActCoeffMolaldT_Scaled[k] = m_dlnActCoeffMolaldT_Unscaled[k] + m_speciesCharge[k] * afac;
06412 }
06413 }
06414
06415
06416
06417
06418
06419
06420
06421 void HMWSoln::s_updateScaling_pHScaling_dT2() const {
06422 if (m_pHScalingType == PHSCALE_PITZER) {
06423 fvo_copy_dbl_1(m_d2lnActCoeffMolaldT2_Scaled, m_d2lnActCoeffMolaldT2_Unscaled, m_kk);
06424 return;
06425 }
06426 AssertTrace(m_pHScalingType == PHSCALE_NBS);
06427 doublereal d2lnGammaClM_dT2_s2 = s_NBS_CLM_d2lnMolalityActCoeff_dT2();
06428 doublereal d2lnGammaCLM_dT2_s1 = m_d2lnActCoeffMolaldT2_Unscaled[m_indexCLM];
06429 doublereal afac = -1.0 *(d2lnGammaClM_dT2_s2 - d2lnGammaCLM_dT2_s1);
06430 for (int k = 0; k < m_kk; k++) {
06431 m_d2lnActCoeffMolaldT2_Scaled[k] = m_d2lnActCoeffMolaldT2_Unscaled[k] + m_speciesCharge[k] * afac;
06432 }
06433 }
06434
06435
06436
06437
06438
06439
06440 void HMWSoln::s_updateScaling_pHScaling_dP() const {
06441 if (m_pHScalingType == PHSCALE_PITZER) {
06442 fvo_copy_dbl_1(m_dlnActCoeffMolaldP_Scaled, m_dlnActCoeffMolaldP_Unscaled, m_kk);
06443 return;
06444 }
06445 AssertTrace(m_pHScalingType == PHSCALE_NBS);
06446 doublereal dlnGammaClM_dP_s2 = s_NBS_CLM_dlnMolalityActCoeff_dP();
06447 doublereal dlnGammaCLM_dP_s1 = m_dlnActCoeffMolaldP_Unscaled[m_indexCLM];
06448 doublereal afac = -1.0 *(dlnGammaClM_dP_s2 - dlnGammaCLM_dP_s1);
06449 for (int k = 0; k < m_kk; k++) {
06450 m_dlnActCoeffMolaldP_Scaled[k] = m_dlnActCoeffMolaldP_Unscaled[k] + m_speciesCharge[k] * afac;
06451 }
06452 }
06453
06454
06455
06456
06457
06458 doublereal HMWSoln::s_NBS_CLM_lnMolalityActCoeff() const {
06459 doublereal sqrtIs = sqrt(m_IionicMolality);
06460 doublereal A = m_A_Debye;
06461 doublereal lnGammaClMs2 = - A * sqrtIs /(1.0 + 1.5 * sqrtIs);
06462 return lnGammaClMs2;
06463 }
06464
06465
06466
06467
06468
06469 doublereal HMWSoln::s_NBS_CLM_dlnMolalityActCoeff_dT() const {
06470 doublereal sqrtIs = sqrt(m_IionicMolality);
06471 doublereal dAdT = dA_DebyedT_TP();
06472 doublereal d_lnGammaClM_dT = - dAdT * sqrtIs /(1.0 + 1.5 * sqrtIs);
06473 return d_lnGammaClM_dT;
06474 }
06475
06476
06477
06478
06479
06480 doublereal HMWSoln::s_NBS_CLM_d2lnMolalityActCoeff_dT2() const {
06481 doublereal sqrtIs = sqrt(m_IionicMolality);
06482 doublereal d2AdT2 = d2A_DebyedT2_TP();
06483 doublereal d_lnGammaClM_dT2 = - d2AdT2 * sqrtIs /(1.0 + 1.5 * sqrtIs);
06484 return d_lnGammaClM_dT2;
06485 }
06486
06487
06488
06489
06490
06491 doublereal HMWSoln::s_NBS_CLM_dlnMolalityActCoeff_dP() const {
06492 doublereal sqrtIs = sqrt(m_IionicMolality);
06493 doublereal dAdP = dA_DebyedP_TP();
06494 doublereal d_lnGammaClM_dP = - dAdP * sqrtIs /(1.0 + 1.5 * sqrtIs);
06495 return d_lnGammaClM_dP;
06496 }
06497
06498 int HMWSoln::debugPrinting() {
06499 #ifdef DEBUG_MODE
06500 return m_debugCalc;
06501 #else
06502 return 0;
06503 #endif
06504 }
06505
06506 }
06507