4#ifndef boundary_parameters_h
5#define boundary_parameters_h
7#include <deal.II/base/point.h>
8#include <deal.II/base/types.h>
9#include <deal.II/base/utilities.h>
11#include <boost/algorithm/string/predicate.hpp>
13#include <prismspf/config.h>
14#include <prismspf/core/conditional_ostreams.h>
15#include <prismspf/core/exceptions.h>
16#include <prismspf/core/type_enums.h>
17#include <prismspf/core/types.h>
18#include <prismspf/core/variable_attributes.h>
25PRISMS_PF_BEGIN_NAMESPACE
44 NON_UNIFORM_DIRICHLET,
54 return boundary_condition_map == other.boundary_condition_map &&
55 dirichlet_value_map == other.dirichlet_value_map;
62 std::map<dealii::types::boundary_id, type> boundary_condition_map;
65 std::map<dealii::types::boundary_id, double> dirichlet_value_map;
70 [[nodiscard]] std::string
75 case type::UNDEFINED_BOUNDARY:
76 return "UNDEFINED_BOUNDARY";
85 case type::NON_UNIFORM_DIRICHLET:
86 return "NON_UNIFORM_DIRICHLET";
87 case type::NON_UNIFORM_NEUMANN:
88 return "NON_UNIFORM_NEUMANN";
102 using BoundaryConditionMap =
103 std::map<types::index, std::map<unsigned int, boundaryCondition>>;
104 using BCList = std::map<types::index, std::map<unsigned int, std::string>>;
105 using PinnedPointMap = std::map<types::index, std::pair<double, dealii::Point<dim>>>;
112 const std::map<unsigned int, variableAttributes> &var_attributes);
119 const types::index &index_2)
const;
133 PinnedPointMap pinned_point_list;
137 BoundaryConditionMap boundary_condition_list;
144 set_boundary(
const std::string &BC_string,
145 const types::index &index,
146 const unsigned int &component);
152 validate_boundary_conditions()
const;
158 const std::map<unsigned int, variableAttributes> &var_attributes)
160 for (
const auto &[index, variable] : var_attributes)
164 if (variable.field_type == fieldType::VECTOR)
166 for (
unsigned int i = 0; i < dim; i++)
168 if (variable.is_postprocess)
170 set_boundary(
"NATURAL", variable.field_index, i);
174 AssertThrow(BC_list.find(variable.field_index) != BC_list.end(),
175 dealii::ExcMessage(
"Invalid entry"));
176 AssertThrow(BC_list.at(variable.field_index).find(i) !=
177 BC_list.at(variable.field_index).end(),
178 dealii::ExcMessage(
"Invalid entry"));
179 AssertThrow(!BC_list.at(variable.field_index).at(i).empty(),
181 "Boundary conditions must be specified "
182 "for all components in all vector field."));
184 set_boundary(BC_list.at(variable.field_index).at(i),
185 variable.field_index,
192 if (variable.is_postprocess)
194 set_boundary(
"NATURAL", variable.field_index, 0);
198 AssertThrow(BC_list.find(variable.field_index) != BC_list.end(),
199 dealii::ExcMessage(
"Invalid entry"));
200 AssertThrow(BC_list.at(variable.field_index).find(0) !=
201 BC_list.at(variable.field_index).end(),
202 dealii::ExcMessage(
"Invalid entry"));
203 AssertThrow(!BC_list.at(variable.field_index).at(0).empty(),
204 dealii::ExcMessage(
"Boundary conditions must be specified "
205 "for all scalar fields."));
207 set_boundary(BC_list.at(variable.field_index).at(0),
208 variable.field_index,
215 validate_boundary_conditions();
220#ifdef ADDITIONAL_OPTIMIZATIONS
223 for (
const auto &[index_1, variable_1] : var_attributes)
226 if (variable_1.duplicate_field_index != numbers::invalid_index)
230 if (variable_1.is_postprocess)
235 const auto field_type_1 = variable_1.field_type;
237 for (
const auto &[index_2, variable_2] : var_attributes)
239 if (variable_2.is_postprocess)
244 bool is_duplicate =
false;
246 const auto field_type_2 = variable_2.field_type;
248 is_duplicate = field_type_1 == field_type_2 &&
249 check_duplicate_boundary_conditions(index_1, index_2);
254 <<
"Field " << variable_1.name <<
" has the same boundary conditions as "
255 << variable_2.name <<
". Using optimizations...\n";
256 variable_2.duplicate_field_index = index_1;
266 const types::index &index_1,
267 const types::index &index_2)
const
270 if (index_1 == index_2)
275 Assert(boundary_condition_list.find(index_1) != boundary_condition_list.end(),
276 dealii::ExcMessage(
"Invalid entry for index = " + std::to_string(index_1)));
277 Assert(boundary_condition_list.find(index_2) != boundary_condition_list.end(),
278 dealii::ExcMessage(
"Invalid entry for index = " + std::to_string(index_2)));
280 bool is_duplicate =
false;
283 const auto &boundary_condition_1 = boundary_condition_list.at(index_1);
284 const auto &boundary_condition_2 = boundary_condition_list.at(index_2);
286 is_duplicate = boundary_condition_1 == boundary_condition_2;
289 if (pinned_point_list.find(index_1) != pinned_point_list.end() &&
290 pinned_point_list.find(index_2) != pinned_point_list.end())
293 is_duplicate && pinned_point_list.at(index_1) == pinned_point_list.at(index_2);
304 <<
"================================================\n"
305 <<
" Boundary Parameters\n"
306 <<
"================================================\n";
308 for (
const auto &[index, component_map] : boundary_condition_list)
311 for (
const auto &[component, boundary_condition] : component_map)
314 for (
const auto &[domain_id, boundary_type] :
315 boundary_condition.boundary_condition_map)
318 <<
" Boundary id: " << domain_id <<
" "
319 <<
"Condition: " << boundary_condition.to_string(boundary_type);
320 if (boundary_type == boundaryCondition::type::DIRICHLET)
323 <<
" = " << boundary_condition.dirichlet_value_map.at(domain_id);
330 if (!pinned_point_list.empty())
334 for (
const auto &[index, point_value_map] : pinned_point_list)
338 <<
" Value: " << point_value_map.first <<
"\n"
339 <<
" Point: " << point_value_map.second <<
"\n";
347 const types::index &index,
348 const unsigned int &component)
351 auto BC_string_list = dealii::Utilities::split_string_list(BC_string);
356 BC_string_list.size() == 1 || BC_string_list.size() ==
static_cast<size_t>(2 * dim),
357 dealii::ExcMessage(
"Either 1 or 2*dim boundary conditions must be specified."));
361 if (BC_string_list.size() == 1)
363 BC_string_list.resize(
static_cast<size_t>(2 * dim), BC_string_list[0]);
368 for (
unsigned int i = 0; i < (2 * dim); i++)
370 if (boost::iequals(BC_string_list[i],
"NATURAL"))
372 condition.boundary_condition_map.emplace(i, boundaryCondition::type::NATURAL);
374 else if (boost::iequals(BC_string_list[i].substr(0, 9),
"DIRICHLET"))
376 condition.boundary_condition_map.emplace(i, boundaryCondition::type::DIRICHLET);
377 std::string dirichlet_value =
378 BC_string_list[i].substr(10, BC_string_list[i].size());
379 dirichlet_value = dealii::Utilities::trim(dirichlet_value);
380 condition.dirichlet_value_map.emplace(i,
381 dealii::Utilities::string_to_double(
384 else if (boost::iequals(BC_string_list[i],
"PERIODIC"))
386 condition.boundary_condition_map.emplace(i, boundaryCondition::type::PERIODIC);
388 else if (boost::iequals(BC_string_list[i].substr(0, 7),
"NEUMANN"))
390 AssertThrow(
false, FeatureNotImplemented(
"Neumann boundary conditions"));
392 else if (boost::iequals(BC_string_list[i],
"NON_UNIFORM_DIRICHLET"))
394 condition.boundary_condition_map
395 .emplace(i, boundaryCondition::type::NON_UNIFORM_DIRICHLET);
397 else if (boost::iequals(BC_string_list[i],
"NON_UNIFORM_NEUMANN"))
400 FeatureNotImplemented(
"Nonuniform neumann boundary conditions"));
405 dealii::ExcMessage(
"Invalid boundary condition " +
412 AssertThrow(boost::iequals(BC_string_list[i],
"PERIODIC") ==
413 boost::iequals(BC_string_list[i + 1],
"PERIODIC"),
414 dealii::ExcMessage(
"Periodic boundary condition must be "
415 "specified on both sides of domain"));
419 boundary_condition_list[index].emplace(component, condition);
427 for (
const auto &[index, point_value_map] : pinned_point_list)
429 const auto point = point_value_map.second;
430 bool on_vertex =
false;
431 if constexpr (dim == 1)
433 const dealii::Point<1> vertex_1(0);
435 on_vertex = point == vertex_1;
437 else if constexpr (dim == 2)
439 const dealii::Point<2> vertex_1(0, 0);
441 on_vertex = point == vertex_1;
443 else if constexpr (dim == 3)
445 const dealii::Point<3> vertex_1(0, 0, 0);
447 on_vertex = point == vertex_1;
451 AssertThrow(
false, UnreachableCode());
454 AssertThrow(on_vertex, dealii::ExcMessage(
"Pinned point must be on the origin"));
458 std::vector<bool> periodic_ids(
static_cast<dealii::types::boundary_id
>(2 * dim),
false);
459 for (
const auto &[index, component_map] : boundary_condition_list)
461 for (
const auto &[component, boundary_condition] : component_map)
463 for (
const auto &[domain_id, boundary_type] :
464 boundary_condition.boundary_condition_map)
466 if (boundary_type == boundaryCondition::type::PERIODIC)
468 periodic_ids[domain_id] =
true;
473 for (
const auto &[index, component_map] : boundary_condition_list)
475 for (
const auto &[component, boundary_condition] : component_map)
477 for (
const auto &[domain_id, boundary_type] :
478 boundary_condition.boundary_condition_map)
480 if (boundary_type != boundaryCondition::type::PERIODIC &&
481 periodic_ids[domain_id])
486 "All fields for a given domain id (side) must have periodic "
487 "boundary conditions if any field has periodic boundary "
495PRISMS_PF_END_NAMESPACE
static dealii::ConditionalOStream & pout_verbose()
Verbose parallel output stream. Used for additional information in debug mode.
Definition conditional_ostreams.cc:41
static dealii::ConditionalOStream & pout_summary()
Log output stream for writing a summary.log file.
Definition conditional_ostreams.cc:22
Struct that stores relevant information for boundary conditions of a certain field.
Definition boundary_parameters.h:32
std::string to_string(type i) const
Enum to string for type.
Definition boundary_parameters.h:71
bool operator==(const boundaryCondition &other) const
Test for equality of two boundary conditions.
Definition boundary_parameters.h:52
type
Type of boundary condition.
Definition boundary_parameters.h:38
Struct that holds boundary parameters.
Definition boundary_parameters.h:100
void postprocess_and_validate(const std::map< unsigned int, variableAttributes > &var_attributes)
Postprocess and validate parameters.
Definition boundary_parameters.h:157
bool check_duplicate_boundary_conditions(const types::index &index_1, const types::index &index_2) const
Check whether the boundary conditions for two fields are the same.
Definition boundary_parameters.h:265
void print_parameter_summary() const
Print parameters to summary.log.
Definition boundary_parameters.h:301