/* ---------------------------------------------------------------------- */ int add_solution (struct solution *solution_ptr, LDBLE extensive, LDBLE intensive) /* ---------------------------------------------------------------------- */ { /* * Accumulate solution data in master->totals and _x variables. * * extensive is multiplication factor for solution * intensive is fraction of all multiplication factors for all solutions */ int i; struct master *master_ptr; struct species *species_ptr; /* * Add solution to global variables */ tc_x += solution_ptr->tc * intensive; ph_x += solution_ptr->ph * intensive; solution_pe_x += solution_ptr->solution_pe * intensive; mu_x += solution_ptr->mu * intensive; ah2o_x += solution_ptr->ah2o * intensive; density_x += solution_ptr->density * intensive; total_h_x += solution_ptr->total_h * extensive; total_o_x += solution_ptr->total_o * extensive; cb_x += solution_ptr->cb * extensive; mass_water_aq_x += solution_ptr->mass_water * extensive; /* * Copy totals data into primary master species */ for (i = 0; solution_ptr->totals[i].description != NULL; i++) { master_ptr = master_bsearch_primary (solution_ptr->totals[i].description); master_ptr->total += solution_ptr->totals[i].moles * extensive; } /* * Accumulate initial guesses for activities */ /*for (i=0; solution_ptr->master_activity[i].description != NULL; i++) { */ for (i = 0; i < solution_ptr->count_master_activity; i++) { if (solution_ptr->master_activity[i].description != NULL) { master_ptr = master_bsearch (solution_ptr->master_activity[i].description); if (master_ptr != NULL) { master_ptr->s->la += solution_ptr->master_activity[i].la * intensive; } } } /* * Accumulate initial guesses for log gamma */ if (pitzer_model == TRUE) { for (i = 0; i < solution_ptr->count_species_gamma; i++) { species_ptr = s_search (solution_ptr->species_gamma[i].description); if (species_ptr != NULL) { species_ptr->lg += solution_ptr->species_gamma[i].la * intensive; } } } return (OK); }
/* ---------------------------------------------------------------------- */ int Phreeqc:: build_fixed_volume_gas(void) /* ---------------------------------------------------------------------- */ { /* * Put coefficients into lists to sum iaps to test for equilibrium * Put coefficients into lists to build jacobian for * sum of partial pressures equation and * mass balance equations for elements contained in gases */ int row, col; struct master *master_ptr; struct rxn_token *rxn_ptr; struct unknown *unknown_ptr; LDBLE coef, coef_elt; if (gas_unknown == NULL) return (OK); cxxGasPhase *gas_phase_ptr = use.Get_gas_phase_ptr(); for (size_t i = 0; i < gas_phase_ptr->Get_gas_comps().size(); i++) { const cxxGasComp *comp_ptr = &(gas_phase_ptr->Get_gas_comps()[i]); int j; struct phase *phase_ptr = phase_bsearch(comp_ptr->Get_phase_name().c_str(), &j, FALSE); /* * Determine elements in gas component */ count_elts = 0; paren_count = 0; if (phase_ptr->rxn_x == NULL) continue; add_elt_list(phase_ptr->next_elt, 1.0); #define COMBINE #ifdef COMBINE change_hydrogen_in_elt_list(0); #endif /* * Build mass balance sums for each element in gas */ if (debug_prep == TRUE) { output_msg(sformatf( "\n\tMass balance summations %s.\n\n", phase_ptr->name)); } /* All elements in gas */ for (j = 0; j < count_elts; j++) { unknown_ptr = NULL; if (strcmp(elt_list[j].elt->name, "H") == 0) { unknown_ptr = mass_hydrogen_unknown; } else if (strcmp(elt_list[j].elt->name, "O") == 0) { unknown_ptr = mass_oxygen_unknown; } else { if (elt_list[j].elt->primary->in == TRUE) { unknown_ptr = elt_list[j].elt->primary->unknown; } else if (elt_list[j].elt->primary->s->secondary != NULL) { unknown_ptr = elt_list[j].elt->primary->s->secondary->unknown; } } if (unknown_ptr != NULL) { coef = elt_list[j].coef; store_mb(&(gas_unknowns[i]->moles), &(unknown_ptr->f), coef); if (debug_prep == TRUE) { output_msg(sformatf( "\t\t%-24s%10.3f\n", unknown_ptr->description, (double) coef)); } } } if (gas_phase_ptr->Get_type() == cxxGasPhase::GP_PRESSURE) { /* Total pressure of gases */ store_mb(&(phase_ptr->p_soln_x), &(gas_unknown->f), 1.0); } /* * Build jacobian sums for mass balance equations */ if (debug_prep == TRUE) { output_msg(sformatf( "\n\tJacobian summations %s.\n\n", phase_ptr->name)); } for (j = 0; j < count_elts; j++) { unknown_ptr = NULL; if (strcmp(elt_list[j].elt->name, "H") == 0) { unknown_ptr = mass_hydrogen_unknown; } else if (strcmp(elt_list[j].elt->name, "O") == 0) { unknown_ptr = mass_oxygen_unknown; } else { if (elt_list[j].elt->primary->in == TRUE) { unknown_ptr = elt_list[j].elt->primary->unknown; } else if (elt_list[j].elt->primary->s->secondary != NULL) { unknown_ptr = elt_list[j].elt->primary->s->secondary->unknown; } } if (unknown_ptr == NULL) { continue; } if (debug_prep == TRUE) { output_msg(sformatf( "\n\t%s.\n", unknown_ptr->description)); } row = unknown_ptr->number * (count_unknowns + 1); coef_elt = elt_list[j].coef; for (rxn_ptr = phase_ptr->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { if (rxn_ptr->s->secondary != NULL && rxn_ptr->s->secondary->in == TRUE) { master_ptr = rxn_ptr->s->secondary; } else if (rxn_ptr->s->primary != NULL && rxn_ptr->s->primary->in == TRUE) { master_ptr = rxn_ptr->s->primary; } else { master_ptr = master_bsearch_primary(rxn_ptr->s->name); master_ptr->s->la = -999.0; } if (debug_prep == TRUE) { output_msg(sformatf( "\t\t%s\n", master_ptr->s->name)); } if (master_ptr->unknown == NULL) { continue; } if (master_ptr->in == FALSE) { error_string = sformatf( "Element, %s, in phase, %s, is not in model.", master_ptr->elt->name, phase_ptr->name); error_msg(error_string, CONTINUE); input_error++; } col = master_ptr->unknown->number; coef = coef_elt * rxn_ptr->coef; store_jacob(&(gas_unknowns[i]->moles), &(array[row + col]), coef); if (debug_prep == TRUE) { output_msg(sformatf( "\t\t%-24s%10.3f\t%d\t%d\n", master_ptr->s->name, (double) coef, row / (count_unknowns + 1), col)); } } if (gas_phase_ptr->Get_type() == cxxGasPhase::GP_PRESSURE) { /* derivative wrt total moles of gas */ store_jacob(&(phase_ptr->fraction_x), &(array[row + gas_unknown->number]), coef_elt); if (debug_prep == TRUE) { output_msg(sformatf( "\t\t%-24s%10.3f\t%d\t%d\n", "gas moles", (double) elt_list[j].coef, row / (count_unknowns + 1), gas_unknown->number)); } } } /* * Build jacobian sums for sum of partial pressures equation */ if (gas_phase_ptr->Get_type() != cxxGasPhase::GP_PRESSURE) continue; if (debug_prep == TRUE) { output_msg(sformatf( "\n\tPartial pressure eqn %s.\n\n", phase_ptr->name)); } unknown_ptr = gas_unknown; row = unknown_ptr->number * (count_unknowns + 1); for (rxn_ptr = phase_ptr->rxn_x->token + 1; rxn_ptr->s != NULL; rxn_ptr++) { if (rxn_ptr->s != s_eminus && rxn_ptr->s->in == FALSE) { error_string = sformatf( "Element in species, %s, in phase, %s, is not in model.", rxn_ptr->s->name, phase_ptr->name); warning_msg(error_string); } else { if (rxn_ptr->s->secondary != NULL && rxn_ptr->s->secondary->in == TRUE) { master_ptr = rxn_ptr->s->secondary; } else if (rxn_ptr->s->primary != NULL && rxn_ptr->s->primary->in == TRUE) { master_ptr = rxn_ptr->s->primary; } else { master_ptr = master_bsearch_primary(rxn_ptr->s->name); if (master_ptr && master_ptr->s) { master_ptr->s->la = -999.0; } } if (master_ptr == NULL) { error_string = sformatf( "Master species for %s, in phase, %s, is not in model.", rxn_ptr->s->name, phase_ptr->name); error_msg(error_string, CONTINUE); input_error++; } else { if (debug_prep == TRUE) { output_msg(sformatf( "\t\t%s\n", master_ptr->s->name)); } if (master_ptr->unknown == NULL) { assert(false); continue; } if (master_ptr->in == FALSE) { error_string = sformatf( "Element, %s, in phase, %s, is not in model.", master_ptr->elt->name, phase_ptr->name); warning_msg(error_string); } col = master_ptr->unknown->number; coef = rxn_ptr->coef; store_jacob(&(phase_ptr->p_soln_x), &(array[row + col]), coef); if (debug_prep == TRUE) { output_msg(sformatf( "\t\t%-24s%10.3f\t%d\t%d\n", master_ptr->s->name, (double) coef, row / (count_unknowns + 1), col)); } } } } } return (OK); }