OGS
ProcessLib::PythonBoundaryCondition Class Referencefinal

Detailed Description

A boundary condition whose values are computed by a Python script.

Definition at line 58 of file PythonBoundaryCondition.h.

#include <PythonBoundaryCondition.h>

Inheritance diagram for ProcessLib::PythonBoundaryCondition:
[legend]
Collaboration diagram for ProcessLib::PythonBoundaryCondition:
[legend]

Public Member Functions

 PythonBoundaryCondition (PythonBcData &&bc_data, unsigned const integration_order, bool const flush_stdout, unsigned const bulk_mesh_dimension, NumLib::LocalToGlobalIndexMap const &dof_table_bulk)
void getEssentialBCValues (const double t, const GlobalVector &x, NumLib::IndexValueVector< GlobalIndexType > &bc_values) const override
 Writes the values of essential BCs to bc_values.
void applyNaturalBC (const double t, std::vector< GlobalVector * > const &x, int const process_id, GlobalMatrix *K, GlobalVector &b, GlobalMatrix *Jac) override
Public Member Functions inherited from ProcessLib::BoundaryCondition
virtual void preTimestep (const double, std::vector< GlobalVector * > const &, int const)
virtual void postTimestep (const double, std::vector< GlobalVector * > const &, int const)
virtual ~BoundaryCondition ()=default

Private Member Functions

void collectPrimaryVariables (std::vector< double > &primary_variables, MeshLib::Node const &boundary_node, GlobalVector const &x) const
GlobalIndexType getDofIdx (std::size_t const boundary_node_id) const
GlobalIndexType getDofIdx (std::size_t const boundary_node_id, int const var, int const comp) const
double interpolateToHigherOrderNode (GlobalVector const &x, int const var, int const comp, MeshLib::Node const &boundary_node) const

Private Attributes

PythonBcData _bc_data
 Auxiliary data used by the local assemblers.
std::unique_ptr< NumLib::LocalToGlobalIndexMap_dof_table_boundary
 Local dof table for the boundary mesh.
std::vector< std::unique_ptr< PythonBoundaryConditionLocalAssemblerInterface > > _local_assemblers
 Local assemblers for all elements of the boundary mesh.
bool const _flush_stdout

Constructor & Destructor Documentation

◆ PythonBoundaryCondition()

ProcessLib::PythonBoundaryCondition::PythonBoundaryCondition ( PythonBcData && bc_data,
unsigned const integration_order,
bool const flush_stdout,
unsigned const bulk_mesh_dimension,
NumLib::LocalToGlobalIndexMap const & dof_table_bulk )

Definition at line 64 of file PythonBoundaryCondition.cpp.

68 : _bc_data(std::move(bc_data)), _flush_stdout(flush_stdout)
69{
70 checkConsistency(dof_table_bulk,
71 _bc_data.all_process_variables_for_this_process);
72
73 std::vector<MeshLib::Node*> const& bc_nodes =
74 _bc_data.bc_or_st_mesh.getNodes();
75 MeshLib::MeshSubset bc_mesh_subset(_bc_data.bc_or_st_mesh, bc_nodes);
76
78 dof_table_bulk.deriveBoundaryConstrainedMap(std::move(bc_mesh_subset));
79
81 PythonBoundaryConditionLocalAssembler>(
82 bulk_mesh_dimension, _bc_data.bc_or_st_mesh.getElements(),
84 NumLib::IntegrationOrder{integration_order},
85 _bc_data.bc_or_st_mesh.isAxiallySymmetric(), _bc_data);
86}
std::unique_ptr< NumLib::LocalToGlobalIndexMap > _dof_table_boundary
Local dof table for the boundary mesh.
PythonBcData _bc_data
Auxiliary data used by the local assemblers.
std::vector< std::unique_ptr< PythonBoundaryConditionLocalAssemblerInterface > > _local_assemblers
Local assemblers for all elements of the boundary mesh.
void createLocalAssemblersPython(const unsigned dimension, std::vector< MeshLib::Element * > const &mesh_elements, NumLib::LocalToGlobalIndexMap const &dof_table, std::vector< std::unique_ptr< LocalAssemblerInterface > > &local_assemblers, NumLib::IntegrationOrder const integration_order, ExtraCtorArgs &&... extra_ctor_args)
void checkConsistency(NumLib::LocalToGlobalIndexMap const &dof_table, std::vector< std::reference_wrapper< ProcessLib::ProcessVariable > > const &pvs)

References _bc_data, _dof_table_boundary, _flush_stdout, _local_assemblers, ProcessLib::BoundaryConditionAndSourceTerm::createLocalAssemblersPython(), and NumLib::LocalToGlobalIndexMap::deriveBoundaryConstrainedMap().

Member Function Documentation

◆ applyNaturalBC()

void ProcessLib::PythonBoundaryCondition::applyNaturalBC ( const double ,
std::vector< GlobalVector * > const & ,
int const ,
GlobalMatrix * ,
GlobalVector & ,
GlobalMatrix *  )
overridevirtual

Applies natural BCs (i.e. non-Dirichlet BCs) to the stiffness matrix K and the vector b.

Reimplemented from ProcessLib::BoundaryCondition.

Definition at line 239 of file PythonBoundaryCondition.cpp.

242{
243 FlushStdoutGuard guard(_flush_stdout);
244
245 try
246 {
249 _local_assemblers, *_dof_table_boundary, t, x, process_id, K, b,
250 Jac);
251 }
252 catch (MethodNotOverriddenInDerivedClassException const& /*e*/)
253 {
254 DBUG("Method `getFlux' not overridden in Python script.");
255 }
256 catch (pybind11::error_already_set const& e)
257 {
258 OGS_FATAL("Error evaluating natural BC in Python: {}", e.what());
259 }
260}
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
virtual void assemble(std::size_t const id, NumLib::LocalToGlobalIndexMap const &dof_table_boundary, double const t, std::vector< GlobalVector * > const &x, int const process_id, GlobalMatrix *K, GlobalVector &b, GlobalMatrix *Jac)=0
static void executeMemberOnDereferenced(Method method, Container const &container, Args &&... args)

References _dof_table_boundary, _flush_stdout, _local_assemblers, ProcessLib::GenericNaturalBoundaryConditionLocalAssemblerInterface::assemble(), DBUG(), NumLib::SerialExecutor::executeMemberOnDereferenced(), and OGS_FATAL.

◆ collectPrimaryVariables()

void ProcessLib::PythonBoundaryCondition::collectPrimaryVariables ( std::vector< double > & primary_variables,
MeshLib::Node const & boundary_node,
GlobalVector const & x ) const
private

Collects primary variables at the passed node from the passed GlobalVector to primary_variables.

Primary variables at higher order nodes are interpolated from base nodes if necessary, e.g., for Taylor-Hood elements.

Postcondition
primary_variables will contain the value of each component of each primary variable. Their order is determined by the d.o.f. table.

Definition at line 173 of file PythonBoundaryCondition.cpp.

176{
177 primary_variables.clear();
178 auto const num_var = _dof_table_boundary->getNumberOfVariables();
179 auto const boundary_node_id = boundary_node.getID();
180
181 for (int var = 0; var < num_var; ++var)
182 {
183 auto const num_comp =
184 _dof_table_boundary->getNumberOfVariableComponents(var);
185 for (int comp = 0; comp < num_comp; ++comp)
186 {
187 auto const dof_idx = getDofIdx(boundary_node_id, var, comp);
188
189 double const pv_value =
191 ? x[dof_idx]
192 : interpolateToHigherOrderNode(x, var, comp, boundary_node);
193
194 primary_variables.push_back(pv_value);
195 }
196 }
197}
static constexpr NUMLIB_EXPORT GlobalIndexType const nop
double interpolateToHigherOrderNode(GlobalVector const &x, int const var, int const comp, MeshLib::Node const &boundary_node) const
GlobalIndexType getDofIdx(std::size_t const boundary_node_id) const

References _dof_table_boundary, getDofIdx(), MathLib::Point3dWithID::getID(), interpolateToHigherOrderNode(), and NumLib::MeshComponentMap::nop.

Referenced by getEssentialBCValues().

◆ getDofIdx() [1/2]

GlobalIndexType ProcessLib::PythonBoundaryCondition::getDofIdx ( std::size_t const boundary_node_id) const
private

Get the d.o.f. index at the given boundary_node_id for this BC's variable and component.

Definition at line 156 of file PythonBoundaryCondition.cpp.

158{
159 MeshLib::Location const loc{_bc_data.bc_or_st_mesh.getID(),
160 MeshLib::MeshItemType::Node, boundary_node_id};
161 return _dof_table_boundary->getGlobalIndex(loc,
162 _bc_data.global_component_id);
163}

References _bc_data, _dof_table_boundary, and MeshLib::Node.

Referenced by collectPrimaryVariables(), and getEssentialBCValues().

◆ getDofIdx() [2/2]

GlobalIndexType ProcessLib::PythonBoundaryCondition::getDofIdx ( std::size_t const boundary_node_id,
int const var,
int const comp ) const
private

Get the d.o.f. index at the given boundary_node_id for the given variable and component.

Definition at line 165 of file PythonBoundaryCondition.cpp.

167{
168 MeshLib::Location const loc{_bc_data.bc_or_st_mesh.getID(),
169 MeshLib::MeshItemType::Node, boundary_node_id};
170 return _dof_table_boundary->getGlobalIndex(loc, var, comp);
171}

References _bc_data, _dof_table_boundary, and MeshLib::Node.

◆ getEssentialBCValues()

void ProcessLib::PythonBoundaryCondition::getEssentialBCValues ( const double ,
const GlobalVector & ,
NumLib::IndexValueVector< GlobalIndexType > &  ) const
overridevirtual

Writes the values of essential BCs to bc_values.

Reimplemented from ProcessLib::BoundaryCondition.

Definition at line 88 of file PythonBoundaryCondition.cpp.

91{
92 FlushStdoutGuard guard(_flush_stdout);
93 (void)guard;
94
95 auto const& boundary_mesh = _bc_data.bc_or_st_mesh;
96 auto const& boundary_nodes = boundary_mesh.getNodes();
97 auto const* bc_object = _bc_data.bc_or_st_object;
98
99 initBCValues(bc_values, boundary_nodes.size());
100
101 std::vector<double> primary_variables;
102
103 try
104 {
105 for (auto const* boundary_node : boundary_nodes)
106 {
107 auto const boundary_node_id = boundary_node->getID();
108 auto const dof_idx = getDofIdx(boundary_node_id);
109
110 if (dof_idx == NumLib::MeshComponentMap::nop)
111 {
112 // This d.o.f. has not been found. This can be the case, e.g.,
113 // for Taylor-Hood elements, where the lower order field has no
114 // d.o.f. on higher order nodes.
115 continue;
116 }
117
118 if (dof_idx < 0)
119 {
120 // For the DDC approach (e.g. with PETSc option) a negative
121 // index means that this entry is a ghost entry and should be
122 // dropped.
123 continue;
124 }
125
126 collectPrimaryVariables(primary_variables, *boundary_node, x);
127
128 auto const [apply_bc, bc_value] = bc_object->getDirichletBCValue(
129 t,
130 {(*boundary_node)[0], (*boundary_node)[1], (*boundary_node)[2]},
131 boundary_node_id, primary_variables);
132
133 if (!bc_object->isOverriddenEssential())
134 {
135 DBUG(
136 "Method `getDirichletBCValue' not overridden in Python "
137 "script.");
138 return;
139 }
140
141 if (!apply_bc)
142 {
143 continue;
144 }
145
146 bc_values.ids.emplace_back(dof_idx);
147 bc_values.values.emplace_back(bc_value);
148 }
149 }
150 catch (pybind11::error_already_set const& e)
151 {
152 OGS_FATAL("Error evaluating Dirichlet BC in Python: {}", e.what());
153 }
154}
void collectPrimaryVariables(std::vector< double > &primary_variables, MeshLib::Node const &boundary_node, GlobalVector const &x) const
void initBCValues(NumLib::IndexValueVector< GlobalIndexType > &bc_values, std::size_t const nnodes)

References _bc_data, _flush_stdout, collectPrimaryVariables(), DBUG(), getDofIdx(), NumLib::IndexValueVector< IndexType >::ids, NumLib::MeshComponentMap::nop, OGS_FATAL, and NumLib::IndexValueVector< IndexType >::values.

◆ interpolateToHigherOrderNode()

double ProcessLib::PythonBoundaryCondition::interpolateToHigherOrderNode ( GlobalVector const & x,
int const var,
int const comp,
MeshLib::Node const & boundary_node ) const
private

Interpolates the given component of the given variable to the given boundary_node.

Definition at line 199 of file PythonBoundaryCondition.cpp.

202{
203 auto const& boundary_elements =
204 _bc_data.bc_or_st_mesh.getElementsConnectedToNode(
205 boundary_node.getID());
206
207 if (boundary_elements.size() != 1)
208 {
209 DBUG(
210 "Boundary node {} is associated with {} elements in the boundary "
211 "mesh.",
212 boundary_node.getID(),
213 boundary_elements.size());
214 }
215
216 // Interpolations on all associated elements should return the same. Just
217 // pick any of them.
218 auto const& boundary_element = *boundary_elements.front();
219
220 assert(boundary_element.getNumberOfBaseNodes() <
221 boundary_element.getNumberOfNodes() &&
222 "We expect that the boundary element is a higher order element. "
223 "Otherwise no interpolation should take place.");
224
225 // Search local node id
226 auto const local_node_id_within_boundary_element =
227 getNodeIDinElement(boundary_element, &boundary_node);
228
229 auto const boundary_element_id = boundary_element.getID();
230
231 // Assumption: all boundary elements have a local assembler (in the same
232 // order)
233 auto const& loc_asm = *_local_assemblers[boundary_element_id];
234
235 return loc_asm.interpolate(local_node_id_within_boundary_element,
236 *_dof_table_boundary, x, var, comp);
237}
unsigned getNodeIDinElement(Element const &element, const MeshLib::Node *node)
Returns the position of the given node in the node array of this element.
Definition Element.cpp:213

References _bc_data, _dof_table_boundary, _local_assemblers, DBUG(), and MathLib::Point3dWithID::getID().

Referenced by collectPrimaryVariables().

Member Data Documentation

◆ _bc_data

PythonBcData ProcessLib::PythonBoundaryCondition::_bc_data
private

Auxiliary data used by the local assemblers.

Definition at line 105 of file PythonBoundaryCondition.h.

Referenced by PythonBoundaryCondition(), getDofIdx(), getDofIdx(), getEssentialBCValues(), and interpolateToHigherOrderNode().

◆ _dof_table_boundary

std::unique_ptr<NumLib::LocalToGlobalIndexMap> ProcessLib::PythonBoundaryCondition::_dof_table_boundary
private

Local dof table for the boundary mesh.

Definition at line 108 of file PythonBoundaryCondition.h.

Referenced by PythonBoundaryCondition(), applyNaturalBC(), collectPrimaryVariables(), getDofIdx(), getDofIdx(), and interpolateToHigherOrderNode().

◆ _flush_stdout

bool const ProcessLib::PythonBoundaryCondition::_flush_stdout
private

Whether or not to flush standard output before and after each call to Python code. Ensures right order of output messages and therefore simplifies debugging.

Definition at line 117 of file PythonBoundaryCondition.h.

Referenced by PythonBoundaryCondition(), applyNaturalBC(), and getEssentialBCValues().

◆ _local_assemblers

std::vector<std::unique_ptr<PythonBoundaryConditionLocalAssemblerInterface> > ProcessLib::PythonBoundaryCondition::_local_assemblers
private

Local assemblers for all elements of the boundary mesh.

Definition at line 112 of file PythonBoundaryCondition.h.

Referenced by PythonBoundaryCondition(), applyNaturalBC(), and interpolateToHigherOrderNode().


The documentation for this class was generated from the following files: