AddCoupledSolidKinSpeciesAction::AddCoupledSolidKinSpeciesAction(const InputParameters & params) : Action(params), _primary_species(getParam<std::vector<NonlinearVariableName>>("primary_species")), _secondary_species(getParam<std::vector<AuxVariableName>>("secondary_species")), _kinetic_species_involved(_primary_species.size()), _weights(_primary_species.size()), _input_reactions(getParam<std::string>("kin_reactions")), _logk(getParam<std::vector<Real>>("log10_keq")), _r_area(getParam<std::vector<Real>>("specific_reactive_surface_area")), _ref_kconst(getParam<std::vector<Real>>("kinetic_rate_constant")), _e_act(getParam<std::vector<Real>>("activation_energy")), _gas_const(getParam<Real>("gas_constant")), _ref_temp(getParam<std::vector<Real>>("reference_temperature")), _sys_temp(getParam<std::vector<VariableName>>("system_temperature")) { // Note: as the reaction syntax has changed, check to see if the old syntax has // been used and throw an informative error. The number of = signs should be one // more than the number of commas, while the smallest number of spaces possible is 2 bool old_syntax = false; if (std::count(_input_reactions.begin(), _input_reactions.end(), '=') != std::count(_input_reactions.begin(), _input_reactions.end(), ',') + 1) old_syntax = true; if (std::count(_input_reactions.begin(), _input_reactions.end(), ' ') < 2) old_syntax = true; if (old_syntax) mooseError("Old solid kinetic reaction syntax present.\nReactions should now be comma " "separated, and must have spaces between species and +/-/= operators.\n" "See #9972 for details"); // Parse the kinetic reactions pcrecpp::RE re_reactions("(.+?)" // A single reaction (any character until the comma delimiter) "(?:,\\s*|$)" // comma or end of string , pcrecpp::RE_Options().set_extended(true)); pcrecpp::RE re_terms("(\\S+)"); pcrecpp::RE re_coeff_and_species("(?: \\(? (.*?) \\)? )" // match the leading coefficent "([A-Za-z].*)" // match the species , pcrecpp::RE_Options().set_extended(true)); pcrecpp::StringPiece input(_input_reactions); pcrecpp::StringPiece single_reaction, term; std::string single_reaction_str; // Parse reaction network to extract each individual reaction while (re_reactions.FindAndConsume(&input, &single_reaction_str)) _reactions.push_back(single_reaction_str); _num_reactions = _reactions.size(); if (_num_reactions == 0) mooseError("No solid kinetic reaction provided!"); // Start parsing each reaction for (unsigned int i = 0; i < _num_reactions; ++i) { single_reaction = _reactions[i]; // Capture all of the terms std::string species, coeff_str; Real coeff; int sign = 1; bool secondary = false; std::vector<Real> local_stos; std::vector<VariableName> local_species_list; // Find every single term in this reaction (species and operators) while (re_terms.FindAndConsume(&single_reaction, &term)) { // Separating the stoichiometric coefficients from species if (re_coeff_and_species.PartialMatch(term, &coeff_str, &species)) { if (coeff_str.length()) coeff = std::stod(coeff_str); else coeff = 1.0; coeff *= sign; if (secondary) _solid_kinetic_species.push_back(species); else { local_stos.push_back(coeff); local_species_list.push_back(species); } } // Finding the operators and assign value of -1.0 to "-" sign else if (term == "+" || term == "=" || term == "-") { if (term == "-") { sign = -1; term = "+"; } if (term == "=") secondary = true; } else mooseError("Error parsing term: ", term.as_string()); } _stos.push_back(local_stos); _primary_species_involved.push_back(local_species_list); } // Start picking out primary species and coupled primary species and assigning // corresponding stoichiomentric coefficients for (unsigned int i = 0; i < _primary_species.size(); ++i) for (unsigned int j = 0; j < _num_reactions; ++j) { for (unsigned int k = 0; k < _primary_species_involved[j].size(); ++k) if (_primary_species_involved[j][k] == _primary_species[i]) { _weights[i].push_back(_stos[j][k]); _kinetic_species_involved[i].push_back(_solid_kinetic_species[j]); } } // Print out details of the solid kinetic reactions to the console _console << "Solid kinetic reactions:\n"; for (unsigned int i = 0; i < _num_reactions; ++i) _console << " Reaction " << i + 1 << ": " << _reactions[i] << "\n"; _console << "\n"; // Check that all secondary species read from the reaction network have been added // as AuxVariables. Note: can't sort the _solid_kinetic_species vector as it throws // out the species and coefficient vectors so use std::is_permutation if (!std::is_permutation( _secondary_species.begin(), _secondary_species.end(), _solid_kinetic_species.begin())) mooseError("All solid kinetic species must be added as secondary species"); // Check that the size of property vectors is equal to the number of reactions if (_logk.size() != _num_reactions) mooseError("The number of values entered for log10_keq is not equal to the number of solid " "kinetic reactions"); if (_r_area.size() != _num_reactions) mooseError("The number of values entered for specific_reactive_surface_area is not equal to " "the number of solid kinetic reactions"); if (_ref_kconst.size() != _num_reactions) mooseError("The number of values entered for kinetic_rate_constant is not equal to the number " "of solid kinetic reactions"); if (_e_act.size() != _num_reactions) mooseError("The number of values entered for activation_energy is not equal to the number of " "solid kinetic reactions"); if (_ref_temp.size() != _num_reactions) mooseError("The number of values entered for reference_temperature is not equal to the number " "of solid kinetic reactions"); }
void AddCoupledEqSpeciesKernelsAction::act() { // Reading primary species and reaction network from the input file std::vector<NonlinearVariableName> vars = getParam<std::vector<NonlinearVariableName>>("primary_species"); std::string reactions = getParam<std::string>("reactions"); // Getting ready for the parsing system pcrecpp::RE re_reactions( "(.*?)" // the reaction network (any character until the equilibrium coefficient appears) "\\s" // word boundary "(" // start capture "-?" // optional minus sign "\\d+(?:\\.\\d*)?" // digits followed by optional decimal and more 0 or more digits ")" "\\b" // word boundary "(?:\\s+|$)" // eat the whitespace , pcrecpp::RE_Options().set_extended(true)); pcrecpp::RE re_terms("(\\S+)"); pcrecpp::RE re_coeff_and_species("(?: \\(? (.*?) \\)? )" // match the leading coefficent "([A-Za-z].*)" // match the species , pcrecpp::RE_Options().set_extended(true)); pcrecpp::StringPiece input(reactions); pcrecpp::StringPiece single_reaction, term; Real equal_coeff; std::vector<std::vector<bool>> primary_participation(vars.size()); std::vector<string> eq_species; std::vector<Real> weight; std::vector<Real> eq_const; std::vector<std::vector<Real>> sto_u(vars.size()); std::vector<std::vector<std::vector<Real>>> sto_v(vars.size()); std::vector<std::vector<std::vector<VariableName>>> coupled_v(vars.size()); std::vector<std::vector<Real>> stos; std::vector<std::vector<std::string>> primary_species_involved; unsigned int n_reactions = 0; // Start parsing // Going into every single reaction std::ostringstream oss; while (re_reactions.FindAndConsume(&input, &single_reaction, &equal_coeff)) { n_reactions += 1; oss << "\n\n" << n_reactions << "_th reaction: " << single_reaction << std::endl; eq_const.push_back(equal_coeff); oss << "\nEquilibrium: " << eq_const[n_reactions - 1] << std::endl; // capture all of the terms std::string species, coeff_str; Real coeff; int sign = 1; bool secondary = false; std::vector<Real> local_stos; std::vector<std::string> local_species_list; // Going to find every single term in this reaction, sto_species combos and operators while (re_terms.FindAndConsume(&single_reaction, &term)) { // Separating the sto from species if (re_coeff_and_species.PartialMatch(term, &coeff_str, &species)) { if (coeff_str.length()) { std::istringstream iss(coeff_str); iss >> coeff; } else coeff = 1.0; coeff *= sign; if (secondary) eq_species.push_back(species); else { local_stos.push_back(coeff); local_species_list.push_back(species); oss << "\nSpecies: " << species << "\n" << "Coeff: " << coeff << std::endl; } } // Finding the operators and assign value of -1.0 to "-" sign else if (term == "+" || term == "=" || term == "-")