diff --git a/ChemistryLib/PhreeqcIO.cpp b/ChemistryLib/PhreeqcIO.cpp index 9944e6aa9fd91e9bd6bca0870e85f5a2c8d208df..b3e7bc2236111212977c2a0cd44abddc1fd766bc 100644 --- a/ChemistryLib/PhreeqcIO.cpp +++ b/ChemistryLib/PhreeqcIO.cpp @@ -242,81 +242,83 @@ std::ostream& operator<<(std::ostream& os, PhreeqcIO const& phreeqc_io) os << reaction_rates << "\n"; } - std::size_t const num_chemical_systems = - phreeqc_io._mesh.getNumberOfBaseNodes(); - - auto const chemical_system_map = - *phreeqc_io._mesh.getProperties() - .template getPropertyVector<std::size_t>( - "bulk_node_ids", MeshLib::MeshItemType::Node, 1); - - for (std::size_t local_id = 0; local_id < num_chemical_systems; ++local_id) + for (std::size_t mesh_item_id = 0; + mesh_item_id < phreeqc_io.chemical_system_index_map.size(); + ++mesh_item_id) { - auto const global_id = chemical_system_map[local_id]; - os << "SOLUTION " << global_id + 1 << "\n"; - phreeqc_io._chemical_system->aqueous_solution->print(os, local_id); - - auto const& dump = phreeqc_io._dump; - if (dump) + auto const& local_chemical_system = + phreeqc_io.chemical_system_index_map[mesh_item_id]; + for (std::size_t ip = 0; ip < local_chemical_system.size(); ++ip) { - auto const& aqueous_solutions_prev = dump->aqueous_solutions_prev; - if (!aqueous_solutions_prev.empty()) + auto const& chemical_system_id = local_chemical_system[ip]; + + os << "SOLUTION " << chemical_system_id + 1 << "\n"; + phreeqc_io._chemical_system->aqueous_solution->print( + os, chemical_system_id); + + auto const& dump = phreeqc_io._dump; + if (dump) { - os << aqueous_solutions_prev[local_id] << "\n\n"; + auto const& aqueous_solutions_prev = + dump->aqueous_solutions_prev; + if (!aqueous_solutions_prev.empty()) + { + os << aqueous_solutions_prev[chemical_system_id] << "\n\n"; + } } - } - os << "USE solution none" << "\n"; - os << "END" << "\n\n"; + os << "USE solution none" << "\n"; + os << "END" << "\n\n"; - os << "USE solution " << global_id + 1 << "\n\n"; + os << "USE solution " << chemical_system_id + 1 << "\n\n"; - auto const& equilibrium_reactants = - phreeqc_io._chemical_system->equilibrium_reactants; - if (!equilibrium_reactants.empty()) - { - os << "EQUILIBRIUM_PHASES " << global_id + 1 << "\n"; - for (auto const& equilibrium_reactant : equilibrium_reactants) + auto const& equilibrium_reactants = + phreeqc_io._chemical_system->equilibrium_reactants; + if (!equilibrium_reactants.empty()) { - equilibrium_reactant.print(os, global_id); + os << "EQUILIBRIUM_PHASES " << chemical_system_id + 1 << "\n"; + for (auto const& equilibrium_reactant : equilibrium_reactants) + { + equilibrium_reactant.print(os, chemical_system_id); + } + os << "\n"; } - os << "\n"; - } - auto const& kinetic_reactants = - phreeqc_io._chemical_system->kinetic_reactants; - if (!kinetic_reactants.empty()) - { - os << "KINETICS " << global_id + 1 << "\n"; - for (auto const& kinetic_reactant : kinetic_reactants) + auto const& kinetic_reactants = + phreeqc_io._chemical_system->kinetic_reactants; + if (!kinetic_reactants.empty()) { - kinetic_reactant.print(os, global_id); + os << "KINETICS " << chemical_system_id + 1 << "\n"; + for (auto const& kinetic_reactant : kinetic_reactants) + { + kinetic_reactant.print(os, chemical_system_id); + } + os << "-steps " << phreeqc_io._dt << "\n" << "\n"; } - os << "-steps " << phreeqc_io._dt << "\n" << "\n"; - } - auto const& surface = phreeqc_io._surface; - if (!surface.empty()) - { - os << "SURFACE " << global_id + 1 << "\n"; - std::size_t aqueous_solution_id = - dump->aqueous_solutions_prev.empty() - ? global_id + 1 - : num_chemical_systems + global_id + 1; - os << "-equilibrate with solution " << aqueous_solution_id << "\n"; - os << "-sites_units DENSITY" - << "\n"; - os << surface << "\n"; - os << "SAVE solution " << global_id + 1 << "\n"; - } + auto const& surface = phreeqc_io._surface; + if (!surface.empty()) + { + os << "SURFACE " << chemical_system_id + 1 << "\n"; + std::size_t aqueous_solution_id = + dump->aqueous_solutions_prev.empty() + ? chemical_system_id + 1 + : phreeqc_io._num_chemical_systems + + chemical_system_id + 1; + os << "-equilibrate with solution " << aqueous_solution_id << "\n"; + os << "-sites_units DENSITY" << "\n"; + os << surface << "\n"; + os << "SAVE solution " << chemical_system_id + 1 << "\n"; + } - os << "END" << "\n\n"; + os << "END" << "\n\n"; + } } auto const& dump = phreeqc_io._dump; if (dump) { - dump->print(os, num_chemical_systems); + dump->print(os, phreeqc_io._num_chemical_systems); } return os; @@ -371,150 +373,157 @@ std::istream& operator>>(std::istream& in, PhreeqcIO& phreeqc_io) auto const& surface = phreeqc_io._surface; int const num_skipped_lines = surface.empty() ? 1 : 2; - std::size_t const num_chemical_systems = - phreeqc_io._mesh.getNumberOfBaseNodes(); - - auto const chemical_system_map = - *phreeqc_io._mesh.getProperties() - .template getPropertyVector<std::size_t>( - "bulk_node_ids", MeshLib::MeshItemType::Node, 1); - - for (std::size_t local_id = 0; local_id < num_chemical_systems; ++local_id) + for (std::size_t mesh_item_id = 0; + mesh_item_id < phreeqc_io.chemical_system_index_map.size(); + ++mesh_item_id) { - auto const global_id = chemical_system_map[local_id]; - // Skip equilibrium calculation result of initial solution - for (int i = 0; i < num_skipped_lines; ++i) + auto const& local_chemical_system = + phreeqc_io.chemical_system_index_map[mesh_item_id]; + for (std::size_t ip = 0; ip < local_chemical_system.size(); ++ip) { - in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); - } + auto const& chemical_system_id = local_chemical_system[ip]; - // Get calculation result of the solution after the reaction - if (!std::getline(in, line)) - { - OGS_FATAL( - "Error when reading calculation result of Solution {:d} after " - "the reaction.", - global_id); - } + // Skip equilibrium calculation result of initial solution + for (int i = 0; i < num_skipped_lines; ++i) + { + in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); + } - std::vector<double> accepted_items; - std::vector<std::string> items; - boost::trim_if(line, boost::is_any_of("\t ")); - boost::algorithm::split(items, line, boost::is_any_of("\t "), - boost::token_compress_on); - for (int item_id = 0; item_id < static_cast<int>(items.size()); - ++item_id) - { - if (std::find(dropped_item_ids.begin(), dropped_item_ids.end(), - item_id) == dropped_item_ids.end()) + // Get calculation result of the solution after the reaction + if (!std::getline(in, line)) { - double value; - try - { - value = std::stod(items[item_id]); - } - catch (const std::invalid_argument& e) - { - OGS_FATAL( - "Invalid argument. Could not convert string '{:s}' to " - "double for chemical system {:d}, column {:d}. " - "Exception " - "'{:s}' was thrown.", - items[item_id], global_id, item_id, e.what()); - } - catch (const std::out_of_range& e) + OGS_FATAL( + "Error when reading calculation result of Solution {:d} " + "after " + "the reaction.", + chemical_system_id); + } + + std::vector<double> accepted_items; + std::vector<std::string> items; + boost::trim_if(line, boost::is_any_of("\t ")); + boost::algorithm::split(items, line, boost::is_any_of("\t "), + boost::token_compress_on); + for (int item_id = 0; item_id < static_cast<int>(items.size()); + ++item_id) + { + if (std::find(dropped_item_ids.begin(), dropped_item_ids.end(), + item_id) == dropped_item_ids.end()) { - OGS_FATAL( - "Out of range error. Could not convert string '{:s}' " - "to " - "double for chemical system {:d}, column {:d}. " - "Exception " - "'{:s}' was thrown.", - items[item_id], global_id, item_id, e.what()); + double value; + try + { + value = std::stod(items[item_id]); + } + catch (const std::invalid_argument& e) + { + OGS_FATAL( + "Invalid argument. Could not convert string '{:s}' " + "to double for chemical system {:d}, column {:d}. " + "Exception '{:s}' was thrown.", + items[item_id], chemical_system_id + 1, item_id, + e.what()); + } + catch (const std::out_of_range& e) + { + OGS_FATAL( + "Out of range error. Could not convert string " + "'{:s}' to double for chemical system {:d}, column " + "{:d}. Exception '{:s}' was thrown.", + items[item_id], chemical_system_id + 1, item_id, + e.what()); + } + accepted_items.push_back(value); } - accepted_items.push_back(value); } - } - assert(accepted_items.size() == output.accepted_items.size()); - - auto& aqueous_solution = phreeqc_io._chemical_system->aqueous_solution; - auto& components = aqueous_solution->components; - auto& equilibrium_reactants = - phreeqc_io._chemical_system->equilibrium_reactants; - auto& kinetic_reactants = - phreeqc_io._chemical_system->kinetic_reactants; - auto& user_punch = phreeqc_io._user_punch; - for (int item_id = 0; item_id < static_cast<int>(accepted_items.size()); - ++item_id) - { - auto const& accepted_item = output.accepted_items[item_id]; - auto const& item_name = accepted_item.name; + assert(accepted_items.size() == output.accepted_items.size()); + + auto& aqueous_solution = + phreeqc_io._chemical_system->aqueous_solution; + auto& components = aqueous_solution->components; + auto& equilibrium_reactants = + phreeqc_io._chemical_system->equilibrium_reactants; + auto& kinetic_reactants = + phreeqc_io._chemical_system->kinetic_reactants; + auto& user_punch = phreeqc_io._user_punch; + for (int item_id = 0; + item_id < static_cast<int>(accepted_items.size()); + ++item_id) + { + auto const& accepted_item = output.accepted_items[item_id]; + auto const& item_name = accepted_item.name; - auto compare_by_name = [&item_name](auto const& item) { - return item.name == item_name; - }; + auto compare_by_name = [&item_name](auto const& item) { + return item.name == item_name; + }; - switch (accepted_item.item_type) - { - case ItemType::pH: + switch (accepted_item.item_type) { - // Update pH value - aqueous_solution->pH->set(local_id, + case ItemType::pH: + { + // Update pH value + aqueous_solution->pH->set(chemical_system_id, + accepted_items[item_id]); + break; + } + case ItemType::pe: + { + // Update pe value + (*aqueous_solution->pe)[chemical_system_id] = + accepted_items[item_id]; + break; + } + case ItemType::Component: + { + // Update component concentrations + auto& component = BaseLib::findElementOrError( + components.begin(), components.end(), + compare_by_name, + "Could not find component '" + item_name + "'."); + component.amount->set(chemical_system_id, accepted_items[item_id]); - break; - } - case ItemType::pe: - { - // Update pe value - (*aqueous_solution->pe)[global_id] = - accepted_items[item_id]; - break; - } - case ItemType::Component: - { - // Update component concentrations - auto& component = BaseLib::findElementOrError( - components.begin(), components.end(), compare_by_name, - "Could not find component '" + item_name + "'."); - component.amount->set(local_id, accepted_items[item_id]); - break; - } - case ItemType::EquilibriumReactant: - { - // Update amounts of equilibrium reactant - auto& equilibrium_reactant = BaseLib::findElementOrError( - equilibrium_reactants.begin(), - equilibrium_reactants.end(), compare_by_name, - "Could not find equilibrium reactant '" + item_name + - "'."); - (*equilibrium_reactant.amount)[global_id] = - accepted_items[item_id]; - break; - } - case ItemType::KineticReactant: - { - // Update amounts of kinetic reactants - auto& kinetic_reactant = BaseLib::findElementOrError( - kinetic_reactants.begin(), kinetic_reactants.end(), - compare_by_name, - "Could not find kinetic reactant '" + item_name + "'."); - (*kinetic_reactant.amount)[global_id] = - accepted_items[item_id]; - break; - } - case ItemType::SecondaryVariable: - { - assert(user_punch); - auto& secondary_variables = user_punch->secondary_variables; - // Update values of secondary variables - auto& secondary_variable = BaseLib::findElementOrError( - secondary_variables.begin(), secondary_variables.end(), - compare_by_name, - "Could not find secondary variable '" + item_name + - "'."); - (*secondary_variable.value)[global_id] = - accepted_items[item_id]; - break; + break; + } + case ItemType::EquilibriumReactant: + { + // Update amounts of equilibrium reactant + auto& equilibrium_reactant = + BaseLib::findElementOrError( + equilibrium_reactants.begin(), + equilibrium_reactants.end(), compare_by_name, + "Could not find equilibrium reactant '" + + item_name + "'."); + (*equilibrium_reactant.amount)[chemical_system_id] = + accepted_items[item_id]; + break; + } + case ItemType::KineticReactant: + { + // Update amounts of kinetic reactants + auto& kinetic_reactant = BaseLib::findElementOrError( + kinetic_reactants.begin(), kinetic_reactants.end(), + compare_by_name, + "Could not find kinetic reactant '" + item_name + + "'."); + (*kinetic_reactant.amount)[chemical_system_id] = + accepted_items[item_id]; + break; + } + case ItemType::SecondaryVariable: + { + assert(user_punch); + auto& secondary_variables = + user_punch->secondary_variables; + // Update values of secondary variables + auto& secondary_variable = BaseLib::findElementOrError( + secondary_variables.begin(), + secondary_variables.end(), compare_by_name, + "Could not find secondary variable '" + item_name + + "'."); + (*secondary_variable.value)[chemical_system_id] = + accepted_items[item_id]; + break; + } } } }