PhreeqcUsers Discussion Forum

Registrations currently disabled due to excessive spam. Please email phreeqcusers at gmail.com to request an account.
Welcome Guest
 

  • Forum Home
  • Login
  • Register

  • PhreeqcUsers Discussion Forum »
  • Conceptual Models »
  • Program coupling »
  • Selected Output
« previous next »
  • Print
Pages: [1]   Go Down

Author Topic: Selected Output  (Read 16323 times)

GeeqC

  • Top Contributor
  • Posts: 153
Selected Output
« on: 06/02/25 21:56 »
I noticed that the selected output function no longer works if BMIPhreeqcRM is used instead of PhreeqcRM. This means that the user punch cannot be retrieved anymore.

Or is there a way that I can still get the selected output in BMIPhreeqcRM?
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #1 on: 06/02/25 23:57 »
Does it work with the test cases?
Logged

GeeqC

  • Top Contributor
  • Posts: 153
Re: Selected Output
« Reply #2 on: 08/02/25 13:16 »
Indeed, it works with the test cases. And also with my own code I get a selected output. But there, only a default selection of parameters appears. It seems the pre-defined selected output does not work anymore in BMIPhreeqcRM:

oss << "SELECTED_OUTPUT 1" << "\n";
    oss << "-user_punch true " << "\n";
    oss << "-temperature true " << "\n";
    oss << "-pH true " << "\n";
    oss << "-alkalinity true " << "\n";
... etc.

In the examples I can see that individual parameters are read by "GetValue". But is there still an option to pre-define the selected output (sel)?
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #3 on: 08/02/25 15:46 »
The test case AdvectBMI_cpp.cpp shows how to extract all of the selected output data. The key method is below, but the example shows how to cycle through all selected output definitions.

Code: [Select]
// Get selected output
std::vector<double> so;
brm.GetValue("SelectedOutput", so);

SELECTED_OUTPUT 1 is defined in advect.bmi. The results for cell 19 are found near the end of the output file AdvectBMI_cpp.chem.txt.

Code: [Select]
Cell number 19
     Calculated Density: 0.99832
     Calculated Volume:  0.199758
     Components:
          0 H: 110.679
          1 O: 55.3438
          2 Charge: -3.37139e-16
          3 Ca: 0
          4 Cl: 0
          5 K: 0.000196302
          6 N: 0.0011964
          7 Na: 0.0010001
     Selected output:
          0 Na(mol/kgw): 0.00100311
          1 Cl(mol/kgw): 0
          2 K(mol/kgw): 0.000196893
          3 Ca(mol/kgw): 0
          4 Temperature: 20
          5 Pressure: 2
          6 Hyd_K: 0
Logged

GeeqC

  • Top Contributor
  • Posts: 153
Re: Selected Output
« Reply #4 on: 09/02/25 00:08 »
The example AdvectBMI_cpp.cpp does not show explicitly how the selected output parameters are pre-defined. Specific parameters are extracted by GetValue. But the AddOutputVars function is inactivated. The parameters that are saved in the SelectedOutput variable "so" seem to default to some standard parameters.

It seems this works fundamentally different in BMIPhreeqcRM than in PhreeqcRM.
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #5 on: 09/02/25 14:52 »
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.
« Last Edit: 09/02/25 17:45 by dlparkhurst »
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #6 on: 09/02/25 18:09 »
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.
Logged

GeeqC

  • Top Contributor
  • Posts: 153
Re: Selected Output
« Reply #7 on: 10/02/25 08:07 »
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?
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #8 on: 10/02/25 17:16 »
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: [Select]
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());
...
}
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #9 on: 10/02/25 17:21 »
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: [Select]
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";
}
}
}
}
Logged

dlparkhurst

  • Global Moderator
  • *****
  • Posts: 4296
Re: Selected Output
« Reply #10 on: 10/02/25 22:42 »
Perhaps you are not defining the SELECTED_OUTPUT data block to the workers. When you RunString with the definition, you must run it through the workers.
Logged

GeeqC

  • Top Contributor
  • Posts: 153
Re: Selected Output
« Reply #11 on: 11/02/25 13:57 »
Yes, it works! The problem was indeed that I did not set the index to the selected output correctly, e.g.: rm.SetValue("NthSelectedOutput", SelectedOutput1_index);

The index also has to be re-set in the time loop after the cells are updated in the transport step.

I found the detailed documentation as .html in the Doxygen folder, which I will be consulting in the future.

Thanks very much for your patience!
Logged

  • Print
Pages: [1]   Go Up
« previous next »
  • PhreeqcUsers Discussion Forum »
  • Conceptual Models »
  • Program coupling »
  • Selected Output
 

  • SMF 2.0.19 | SMF © 2021, Simple Machines | Terms and Policies
  • XHTML
  • RSS
  • WAP2