6#include <deal.II/base/exceptions.h>
7#include <deal.II/matrix_free/evaluation_flags.h>
15#include <prismspf/config.h>
60 using EvalFlags = dealii::EvaluationFlags::EvaluationFlags;
66 std::set<Types::Index> _field_indices = {},
123 return id < other.
id;
138 dealii::ExcMessage(
"A valid solve type must be selected (Constant | "
139 "Explicit | Linear | Newton)\n"));
141 dealii::ExcMessage(
"This solve block must manage at least 1 field.\n"));
149 "Every field in a newton solve should appear "
150 "in the residual (RHS) expression.\n"));
151 AssertThrow(dep_it_rhs->second.flag != EvalFlags::nothing,
153 "Every field in a newton solve should appear "
154 "in the residual (RHS) expression.\n"));
158 "Every field in a newton solve should appear as a Delta term"
159 "in the residual Jacobian (LHS) expression.\n"));
160 AssertThrow(dep_it_lhs->second.src_flag != EvalFlags::nothing,
162 "Every field in a newton solve should appear as a Delta term"
163 "in the residual Jacobian (LHS) expression.\n"));
173 AssertThrow(dep_it_rhs->second.flag == EvalFlags::nothing,
175 "The current value of a field should never appear "
176 "in the RHS of a solve that is not type Newton.\n"));
187 "Every field in a linear solve should appear "
188 "in the (LHS) expression. Be sure to use the src_flag.\n"));
189 AssertThrow(dep_it_lhs->second.src_flag != EvalFlags::nothing,
191 "Every field in a linear solve should appear "
192 "in the (LHS) expression. Be sure to use the src_flag.\n"));
198 dealii::ExcMessage(
"Explicit solves do not have an LHS, "
199 "and should have no LHS dependencies.\n"));
204 dealii::ExcMessage(
"Constant \"solves\" do not have an RHS or LHS, "
205 "and should have no dependencies.\n"));
209 AssertThrow(dependency.src_flag == EvalFlags::nothing,
211 "Trial/Change terms should not appear in RHS expressions.\n"));
217 <<
"Error found during validation of solve block with id " <<
id <<
"\n";
222inline const std::vector<SolveBlock> &
224 const std::vector<FieldAttributes> &field_attributes)
228 std::set<std::string> field_names;
229 for (
const auto &field_attribute : field_attributes)
231 AssertThrow(field_names.find(field_attribute.name) == field_names.end(),
232 dealii::ExcMessage(
"Each field must have a unique name.\n"));
233 field_names.insert(field_attribute.name);
237 for (
const auto &solve_block : solve_blocks)
239 solve_block.validate();
244 for (
const auto &solve_block : solve_blocks)
246 AssertThrow(ids.find(solve_block.id) == ids.end(),
247 dealii::ExcMessage(
"Each solve block must have a unique id.\n"));
248 ids.insert(solve_block.id);
253 std::set<unsigned int> field_indices;
254 for (
unsigned int i = 0; i < field_attributes.size(); ++i)
256 field_indices.insert(i);
258 for (
const auto &solve_block : solve_blocks)
260 for (
unsigned int field_index : solve_block.field_indices)
262 size_t erased = field_indices.erase(field_index);
263 AssertThrow(erased == 1,
264 dealii::ExcMessage(
"Each field should be managed by exactly one "
265 "solve block. The field with index " +
266 std::to_string(field_index) +
267 " is anomalously assigned to solve block " +
268 std::to_string(solve_block.id) +
".\n"));
271 std::string remaining_fields;
272 for (
unsigned int field_index : field_indices)
274 remaining_fields.append(std::to_string(field_index) +
": " +
275 field_attributes[field_index].name +
"\n");
278 field_indices.empty(),
280 "Every field should be managed by exactly one solve block. The following "
281 "fields are not managed by any solve block:\n" +
287 std::set<unsigned int> valid_field_indices;
288 for (
unsigned int i = 0; i < field_attributes.size(); ++i)
290 valid_field_indices.insert(i);
292 for (
const auto &solve_block : solve_blocks)
294 for (
const auto &[field_index, dependency] : solve_block.dependencies_rhs)
297 valid_field_indices.find(field_index) != valid_field_indices.end(),
298 dealii::ExcMessage(
"The RHS dependencies of solve block with id " +
299 std::to_string(solve_block.id) +
300 " refer to a field index that is out of range.\n"));
302 for (
const auto &[field_index, dependency] : solve_block.dependencies_lhs)
305 valid_field_indices.find(field_index) != valid_field_indices.end(),
306 dealii::ExcMessage(
"The LHS dependencies of solve block with id " +
307 std::to_string(solve_block.id) +
308 " refer to a field index that is out of range.\n"));
316 std::set<unsigned int> solved_field_indices;
317 for (
const auto &solve_block : solve_blocks)
319 for (
const auto &[field_index, dependency] : solve_block.dependencies_rhs)
321 if (dependency.flag != EvalFlags::nothing &&
324 AssertThrow(solved_field_indices.find(field_index) !=
325 solved_field_indices.end(),
327 "Solve block with id " + std::to_string(solve_block.id) +
328 " has an rhs dependency on the current value of field \"" +
329 field_attributes[field_index].name +
"\" with index " +
330 std::to_string(field_index) +
331 " which is not solved in a previous solve block. This is not "
335 for (
const auto &[field_index, dependency] : solve_block.dependencies_lhs)
337 if (dependency.flag != EvalFlags::nothing &&
340 AssertThrow(solved_field_indices.find(field_index) !=
341 solved_field_indices.end(),
343 "Solve block with id " + std::to_string(solve_block.id) +
344 " has a lhs dependency on the current value of field \"" +
345 field_attributes[field_index].name +
"\" with index " +
346 std::to_string(field_index) +
347 " which is not solved in a previous solve block. This is not "
351 for (
unsigned int field_index : solve_block.field_indices)
353 solved_field_indices.insert(field_index);
363PRISMS_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:58
LinearSolverParameters linear_solver_parameters
Linear solver parameters. Only used for linear and newton solve blocks.
Definition solve_block.h:112
SolveType solve_type
PDE type (Constant | Explicit | Linear | Newton).
Definition solve_block.h:86
SolveTiming solve_timing
This is used to determine whether to initialize the solution vector with the initial conditions or ju...
Definition solve_block.h:92
int id
Unique identifier. Use this in 'if' statements or switch cases in equations lhs and rhs.
Definition solve_block.h:81
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:63
TensorRank FieldType
Definition solve_block.h:61
DependencyMap dependencies_rhs
Dependencies for the rhs equation(s)
Definition solve_block.h:102
dealii::EvaluationFlags::EvaluationFlags EvalFlags
Definition solve_block.h:60
DependencyMap dependencies_lhs
Dependencies for the lhs equation(s)
Definition solve_block.h:106
void validate() const
Definition solve_block.h:131
NonlinearSolverParameters nonlinear_solver_parameters
Linear solver parameters. Only used for linear and newton solve blocks.
Definition solve_block.h:118
bool operator<(const SolveBlock &other) const
Definition solve_block.h:121
std::set< Types::Index > field_indices
Indices of the fields to be solved in this block.
Definition solve_block.h:97
std::map< Types::Index, Dependency > DependencyMap
Definition dependencies.h:129
Definition conditional_ostreams.cc:20
SolveBlock SolveGroup
Definition solve_block.h:359
SolveTiming
Enum describing when each block of fields gets solved.
Definition solve_block.h:27
@ Uninitialized
Definition solve_block.h:39
@ Primary
Primary fields are initialized explicitly through initial conditions rather than through the solver o...
Definition solve_block.h:32
@ NucleationRate
NucleationRate fields are only solved on nucleation attempt and output increments.
Definition solve_block.h:48
@ PostProcess
PostProcess fields are only solved on output increments.
Definition solve_block.h:43
@ Initialized
Definition solve_block.h:33
@ Secondary
Secondary fields are only evaluated by the pde solver on every increment, not initialized by a separa...
Definition solve_block.h:38
const std::vector< SolveBlock > & validate_solve_blocks(const std::vector< SolveBlock > &solve_blocks, const std::vector< FieldAttributes > &field_attributes)
Definition solve_block.h:223
Struct that stores relevant linear solve information of a certain solve block.
Definition solve_parameters.h:29
Struct that stores relevant nonlinear solve information of a certain field.
Definition solve_parameters.h:145
TensorRank
Tensor rank of the field.
Definition type_enums.h:52
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