Conceptual Models > Program coupling
Selected Output
dlparkhurst:
The parameters found by "so" are defined in the advect.pqi SELECTED_OUTPUT definition! The default state, and other variables for SELECTED_OUTPUT 1 are removed by the -reset false option in advect.pqi. (all SELECTED_OUTPUT n, with n != 1, do not have any default variables.) The variables are extracted and written to the AdvectBMI_cpp.chem.txt file in a block of code of AdvectBMI_cpp.cpp. There is nothing different about the way the BMI version and the original PhreeqcRM operate; BMIPhreeqcRM is a subclass of PhreeqcRM, which means all of the capabilities of PhreeqcRM are included in BMIPhreeqcRM.
dlparkhurst:
To expand on the previous post. You can do exactly the same calls to methods with BMIPhreeqcRM as the you could with PhreeqcRM. With PhreeqcRM, the plan was to define SELECTED_OUTPUT/USER_PUNCH data blocks in the phreeeqc input file (like advect.pqi); then you could extract the values with the PhreeqcRM method GetSelectedOutput and associated methods to select the selected-output file, retrieve the headings, the list of selected output files, and others.
With BMIPhreeqcRM, the same PhreeqcRM methods are available, plus, you can extract the selected output data with GetValue("Selected_output"...), which is exactly equivalent to GetSelectedOutput. The additional capabilities of BMI stem from AddOutputVars, where entire sets out output variables, like moles of the EQUILIBRIUM_PHASES, SOLID_SOLUTIONs, KINETICS reactants, total concentrations of elements, and others can be specified to saved for retrieval with the method GetValue. So, look at the documentation for AddOutputVars for the variables that are saved by default, and the ones that can be added (molalities of individual aqueous species, for example).
AddOutputVars uses the SELECTED_OUTPUT definition 333 to process the AddOutputVars. So, you could process the internally generated SELECTED_OUTPUT 333 with the PhreeqcRM methods. However, it is simpler to use GetValue to retrieve the individual variables (without all the processing of the array "so"). The list of variables that can be retrieved by GetValue can be obtained with the BMIPhreeqcRM method GetOutputVars.
GeeqC:
Thank you for the detailed response!
I am trying to keep this short. I define the initial solution and selected output within the code using "std::ostringstream oss;" and RunString, and then load it to the module (InitialPhreeqc2Module). The user punch calculates molarities [mol/L]. A single output variable "sel" (resp. "so") is practical, as it can be used to export all selected output values in one step to a .csv spreadsheet (using a data exporter class).
I have tried all of your suggestions (setting reset to "false", using "getValues", using "AddOutputVars", etc.) but the selected output keeps defaulting to the standard parameters. Therefore, I cannot access the calculated molarities.
I am not sure which documentation you refer to. The documentation indicated in the BMIPhreeqcRM package (Parkhurst and Wissmeier, 2015; Charlton and Parkhurst, 2011) was published before BMIPhreeqcRM. Or do you mean the test files?
dlparkhurst:
Documentation can be found in the directory Doxygen\html.
All I can say is that for the example AdvectBMI_cpp.cpp, SELECTED_OUTPUT 1 and USER_PUNCH 1 are defined in the input file advect.pqi. AdvectBMI_cpp retrieves and processes the variables in that selected output definition with the following code. The code is general to allow for processing multiple SELECTED_OUTPUT definitions, but omitting the internally generated SELECTED_OUTPUT 333.
--- Code: ---int selected_output_count;
brm.GetValue("SelectedOutputCount", selected_output_count);
for (int isel = 0; isel < selected_output_count; isel++)
{
std::ostringstream oss;
// Loop through possible multiple selected output definitions
brm.SetValue("NthSelectedOutput", isel);
oss << "Selected output sequence number: " << isel << "\n";
int n_user;
brm.GetValue("CurrentSelectedOutputUserNumber", n_user);
if (n_user == 333) continue; // Skip internal SELECTED_OUTPUT
oss << "Selected output user number: " << n_user << "\n";
// Get array of selected output values
int col;
brm.GetValue("SelectedOutputColumnCount", col);
int bmi_row_count;
brm.GetValue("SelectedOutputRowCount", bmi_row_count);
// Get selected output
std::vector<double> so;
brm.GetValue("SelectedOutput", so);
// Get headings
std::vector<std::string> headings;
brm.GetValue("SelectedOutputHeadings", headings);
// Print results
for (int i = 0; i < bmi_row_count / 2; i++)
{
oss << "Cell number " << i << "\n";
oss << " Calculated Density: " << density[i] << "\n";
oss << " Calculated Volume: " << volume[i] << "\n";
oss << " Components: " << "\n";
for (int j = 0; j < ncomps; j++)
{
oss << " " << j << " " << components[j] << ": " << c[j * nxyz + i] << "\n";
}
oss << " Selected output: " << "\n";
for (int j = 0; j < col; j++)
{
oss << " " << j << " " << headings[j] << ": " << so[j * nxyz + i] << "\n";
}
}
brm.OutputMessage(oss.str());
...
}
--- End code ---
dlparkhurst:
Altenatively, you could also use PhreeqcRM methods (which are available in a BMIPhreeqcRM instance). The example Advect_cpp.cpp performs the same tasks as the previous post with the following code:
--- Code: ---if (print_chemistry_on != 0)
{
{
std::ostringstream oss;
oss << "Current distribution of cells for workers\n";
oss << "Worker First cell Last Cell\n";
int n;
n = phreeqc_rm.GetThreadCount() * phreeqc_rm.GetMpiTasks();
for (int i = 0; i < n; i++)
{
oss << i << " " << phreeqc_rm.GetStartCell()[i] << " "
<< phreeqc_rm.GetEndCell()[i] << "\n";
}
phreeqc_rm.OutputMessage(oss.str());
}
for (int isel = 0; isel < phreeqc_rm.GetSelectedOutputCount(); isel++)
{
// Loop through possible multiple selected output definitions
int n_user = phreeqc_rm.GetNthSelectedOutputUserNumber(isel);
status = phreeqc_rm.SetCurrentSelectedOutputUserNumber(n_user);
std::cerr << "Selected output sequence number: " << isel << "\n";
std::cerr << "Selected output user number: " << n_user << "\n";
// Get double array of selected output values
std::vector<double> so;
int col = phreeqc_rm.GetSelectedOutputColumnCount();
status = phreeqc_rm.GetSelectedOutput(so);
// Print results
//for (int i = 0; i < phreeqc_rm.GetSelectedOutputRowCount() / 2; i++)
for (int i = 0; i < 1; i++)
{
std::cerr << "Cell number " << i << "\n";
std::cerr << " Calculated Density: " << density[i] << "\n";
std::cerr << " Volume: " << volume[i] << "\n";
std::cerr << " Components: " << "\n";
for (int j = 0; j < ncomps; j++)
{
std::cerr << " " << j << " " << components[j] << ": " << c[j * nxyz + i] << "\n";
}
std::vector<std::string> headings;
headings.resize(col);
std::cerr << " Selected output: " << "\n";
for (int j = 0; j < col; j++)
{
status = phreeqc_rm.GetSelectedOutputHeading(j, headings[j]);
std::cerr << " " << j << " " << headings[j] << ": " << so[j * nxyz + i] << "\n";
}
}
}
}
--- End code ---
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version