6#include <deal.II/base/exceptions.h>
7#include <deal.II/matrix_free/evaluation_flags.h>
16#include <prismspf/config.h>
61 using EvalFlags = dealii::EvaluationFlags::EvaluationFlags;
67 std::set<Types::Index> _field_indices = {},
124 return id < other.
id;
139 dealii::ExcMessage(
"A valid solve type must be selected (Constant | "
140 "Explicit | Linear | Newton)\n"));
142 dealii::ExcMessage(
"This solve block must manage at least 1 field.\n"));
150 "Every field in a newton solve should appear "
151 "in the residual (RHS) expression.\n"));
152 AssertThrow(dep_it_rhs->second.flag != EvalFlags::nothing,
154 "Every field in a newton solve should appear "
155 "in the residual (RHS) expression.\n"));
159 "Every field in a newton solve should appear as a Delta term"
160 "in the residual Jacobian (LHS) expression.\n"));
161 AssertThrow(dep_it_lhs->second.src_flag != EvalFlags::nothing,
163 "Every field in a newton solve should appear as a Delta term"
164 "in the residual Jacobian (LHS) expression.\n"));
174 AssertThrow(dep_it_rhs->second.flag == EvalFlags::nothing,
176 "The current value of a field should never appear "
177 "in the RHS of a solve that is not type Newton.\n"));
188 "Every field in a linear solve should appear "
189 "in the (LHS) expression. Be sure to use the src_flag.\n"));
190 AssertThrow(dep_it_lhs->second.src_flag != EvalFlags::nothing,
192 "Every field in a linear solve should appear "
193 "in the (LHS) expression. Be sure to use the src_flag.\n"));
199 dealii::ExcMessage(
"Explicit solves do not have an LHS, "
200 "and should have no LHS dependencies.\n"));
205 dealii::ExcMessage(
"Constant \"solves\" do not have an RHS or LHS, "
206 "and should have no dependencies.\n"));
210 AssertThrow(dependency.src_flag == EvalFlags::nothing,
212 "Trial/Change terms should not appear in RHS expressions.\n"));
218 <<
"Error found during validation of solve block with id " <<
id <<
"\n";
223inline const std::vector<SolveBlock> &
225 const std::vector<FieldAttributes> &field_attributes)
229 std::set<std::string> field_names;
230 for (
const auto &field_attribute : field_attributes)
232 AssertThrow(field_names.find(field_attribute.name) == field_names.end(),
233 dealii::ExcMessage(
"Each field must have a unique name.\n"));
234 field_names.insert(field_attribute.name);
238 for (
const auto &solve_block : solve_blocks)
240 solve_block.validate();
245 for (
const auto &solve_block : solve_blocks)
247 AssertThrow(ids.find(solve_block.id) == ids.end(),
248 dealii::ExcMessage(
"Each solve block must have a unique id.\n"));
249 ids.insert(solve_block.id);
254 std::set<unsigned int> field_indices;
255 for (
unsigned int i = 0; i < field_attributes.size(); ++i)
257 field_indices.insert(i);
259 for (
const auto &solve_block : solve_blocks)
261 for (
unsigned int field_index : solve_block.field_indices)
263 size_t erased = field_indices.erase(field_index);
264 AssertThrow(erased == 1,
265 dealii::ExcMessage(
"Each field should be managed by exactly one "
266 "solve block. The field with index " +
267 std::to_string(field_index) +
268 " is anomalously assigned to solve block " +
269 std::to_string(solve_block.id) +
".\n"));
272 std::string remaining_fields;
273 for (
unsigned int field_index : field_indices)
275 remaining_fields.append(std::to_string(field_index) +
": " +
276 field_attributes[field_index].name +
"\n");
279 field_indices.empty(),
281 "Every field should be managed by exactly one solve block. The following "
282 "fields are not managed by any solve block:\n" +
288 std::set<unsigned int> valid_field_indices;
289 for (
unsigned int i = 0; i < field_attributes.size(); ++i)
291 valid_field_indices.insert(i);
293 for (
const auto &solve_block : solve_blocks)
295 for (
const auto &[field_index, dependency] : solve_block.dependencies_rhs)
298 valid_field_indices.find(field_index) != valid_field_indices.end(),
299 dealii::ExcMessage(
"The RHS dependencies of solve block with id " +
300 std::to_string(solve_block.id) +
301 " refer to a field index that is out of range.\n"));
303 for (
const auto &[field_index, dependency] : solve_block.dependencies_lhs)
306 valid_field_indices.find(field_index) != valid_field_indices.end(),
307 dealii::ExcMessage(
"The LHS dependencies of solve block with id " +
308 std::to_string(solve_block.id) +
309 " refer to a field index that is out of range.\n"));
317 std::set<unsigned int> solved_field_indices;
318 for (
const auto &solve_block : solve_blocks)
320 for (
const auto &[field_index, dependency] : solve_block.dependencies_rhs)
322 if (dependency.flag != EvalFlags::nothing &&
325 AssertThrow(solved_field_indices.find(field_index) !=
326 solved_field_indices.end(),
328 "Solve block with id " + std::to_string(solve_block.id) +
329 " has an rhs dependency on the current value of field \"" +
330 field_attributes[field_index].name +
"\" with index " +
331 std::to_string(field_index) +
332 " which is not solved in a previous solve block. This is not "
336 for (
const auto &[field_index, dependency] : solve_block.dependencies_lhs)
338 if (dependency.flag != EvalFlags::nothing &&
341 AssertThrow(solved_field_indices.find(field_index) !=
342 solved_field_indices.end(),
344 "Solve block with id " + std::to_string(solve_block.id) +
345 " has a lhs dependency on the current value of field \"" +
346 field_attributes[field_index].name +
"\" with index " +
347 std::to_string(field_index) +
348 " which is not solved in a previous solve block. This is not "
352 for (
unsigned int field_index : solve_block.field_indices)
354 solved_field_indices.insert(field_index);
364PRISMS_PF_END_NAMESPACE
static dealii::ConditionalOStream & pout_base()
Generic parallel output stream. Used for essential information in release and debug mode.
Definition conditional_ostreams.cc:44
Structure to hold the attributes of a solve-block.
Definition solve_block.h:59
LinearSolverParameters linear_solver_parameters
Linear solver parameters. Only used for linear and newton solve blocks.
Definition solve_block.h:113
SolveType solve_type
PDE type (Constant | Explicit | Linear | Newton).
Definition solve_block.h:87
SolveTiming solve_timing
This is used to determine whether to initialize the solution vector with the initial conditions or ju...
Definition solve_block.h:93
int id
Unique identifier. Use this in 'if' statements or switch cases in equations lhs and rhs.
Definition solve_block.h:82
SolveBlock(int _id=-1, SolveType _solve_type=Explicit, SolveTiming _solve_timing=Primary, std::set< Types::Index > _field_indices={}, DependencyMap _dependencies_rhs={}, DependencyMap _dependencies_lhs={})
Definition solve_block.h:64
TensorRank FieldType
Definition solve_block.h:62
DependencyMap dependencies_rhs
Dependencies for the rhs equation(s)
Definition solve_block.h:103
dealii::EvaluationFlags::EvaluationFlags EvalFlags
Definition solve_block.h:61
DependencyMap dependencies_lhs
Dependencies for the lhs equation(s)
Definition solve_block.h:107
void validate() const
Definition solve_block.h:132
NonlinearSolverParameters nonlinear_solver_parameters
Linear solver parameters. Only used for linear and newton solve blocks.
Definition solve_block.h:119
bool operator<(const SolveBlock &other) const
Definition solve_block.h:122
std::set< Types::Index > field_indices
Indices of the fields to be solved in this block.
Definition solve_block.h:98
std::map< Types::Index, Dependency > DependencyMap
Definition dependencies.h:129
Definition conditional_ostreams.cc:20
SolveBlock SolveGroup
Definition solve_block.h:360
SolveTiming
Enum describing when each block of fields gets solved.
Definition solve_block.h:28
@ Uninitialized
Definition solve_block.h:40
@ Primary
Primary fields are initialized explicitly through initial conditions rather than through the solver o...
Definition solve_block.h:33
@ NucleationRate
NucleationRate fields are only solved on nucleation attempt and output increments.
Definition solve_block.h:49
@ PostProcess
PostProcess fields are only solved on output increments.
Definition solve_block.h:44
@ Initialized
Definition solve_block.h:34
@ Secondary
Secondary fields are only evaluated by the pde solver on every increment, not initialized by a separa...
Definition solve_block.h:39
const std::vector< SolveBlock > & validate_solve_blocks(const std::vector< SolveBlock > &solve_blocks, const std::vector< FieldAttributes > &field_attributes)
Definition solve_block.h:224
Struct that stores relevant linear solve information of a certain solve block.
Definition linear_solve_parameters.h:25
Struct that stores relevant nonlinear solve information of a certain field.
Definition nonlinear_solve_parameters.h:20
SolveType
Type of PDE that is being solved.
Definition type_enums.h:17
@ Linear
Definition type_enums.h:33
@ Newton
Definition type_enums.h:43
@ Constant
Definition type_enums.h:21
@ Explicit
Definition type_enums.h:26
TensorRank
Tensor rank of the field.
Definition type_enums.h:52