OGS
ProcessLib::PythonBoundaryCondition Class Referencefinal

Detailed Description

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

Definition at line 57 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 71 of file PythonBoundaryCondition.cpp.

75 : _bc_data(std::move(bc_data)), _flush_stdout(flush_stdout)
76{
77 checkConsistency(dof_table_bulk,
79
80 std::vector<MeshLib::Node*> const& bc_nodes =
82 MeshLib::MeshSubset bc_mesh_subset(_bc_data.bc_or_st_mesh, bc_nodes);
83
85 dof_table_bulk.deriveBoundaryConstrainedMap(std::move(bc_mesh_subset));
86
88 PythonBoundaryConditionLocalAssembler>(
89 bulk_mesh_dimension, _bc_data.bc_or_st_mesh.getElements(),
91 NumLib::IntegrationOrder{integration_order},
93}
A subset of nodes on a single mesh.
Definition MeshSubset.h:26
bool isAxiallySymmetric() const
Definition Mesh.h:137
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:106
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:109
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)
MeshLib::Mesh const & bc_or_st_mesh
The domain, where this BC or ST will be applied.
Definition BcOrStData.h:46
std::vector< std::reference_wrapper< ProcessVariable > > const & all_process_variables_for_this_process
Definition BcOrStData.h:51

References _bc_data, _dof_table_boundary, _local_assemblers, ProcessLib::BoundaryConditionAndSourceTerm::Python::BcOrStData< BcOrStPythonSideInterface >::all_process_variables_for_this_process, ProcessLib::BoundaryConditionAndSourceTerm::Python::BcOrStData< BcOrStPythonSideInterface >::bc_or_st_mesh, ProcessLib::BoundaryConditionAndSourceTerm::createLocalAssemblersPython(), NumLib::LocalToGlobalIndexMap::deriveBoundaryConstrainedMap(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNodes(), and MeshLib::Mesh::isAxiallySymmetric().

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 246 of file PythonBoundaryCondition.cpp.

249{
250 FlushStdoutGuard guard(_flush_stdout);
251
252 try
253 {
256 _local_assemblers, *_dof_table_boundary, t, x, process_id, K, b,
257 Jac);
258 }
259 catch (MethodNotOverriddenInDerivedClassException const& /*e*/)
260 {
261 DBUG("Method `getFlux' not overridden in Python script.");
262 }
263 catch (pybind11::error_already_set const& e)
264 {
265 OGS_FATAL("Error evaluating natural BC in Python: {}", e.what());
266 }
267}
#define OGS_FATAL(...)
Definition Error.h:26
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
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 180 of file PythonBoundaryCondition.cpp.

183{
184 primary_variables.clear();
185 auto const num_var = _dof_table_boundary->getNumberOfVariables();
186 auto const boundary_node_id = boundary_node.getID();
187
188 for (int var = 0; var < num_var; ++var)
189 {
190 auto const num_comp =
191 _dof_table_boundary->getNumberOfVariableComponents(var);
192 for (int comp = 0; comp < num_comp; ++comp)
193 {
194 auto const dof_idx = getDofIdx(boundary_node_id, var, comp);
195
196 double const pv_value =
198 ? x[dof_idx]
199 : interpolateToHigherOrderNode(x, var, comp, boundary_node);
200
201 primary_variables.push_back(pv_value);
202 }
203 }
204}
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

◆ 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 172 of file PythonBoundaryCondition.cpp.

174{
176 MeshLib::MeshItemType::Node, boundary_node_id};
177 return _dof_table_boundary->getGlobalIndex(loc, var, comp);
178}

References _bc_data, _dof_table_boundary, ProcessLib::BoundaryConditionAndSourceTerm::Python::BcOrStData< BcOrStPythonSideInterface >::bc_or_st_mesh, MeshLib::Mesh::getID(), 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 95 of file PythonBoundaryCondition.cpp.

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

References _bc_data, _flush_stdout, ProcessLib::BoundaryConditionAndSourceTerm::Python::BcOrStData< BcOrStPythonSideInterface >::bc_or_st_mesh, ProcessLib::BoundaryConditionAndSourceTerm::Python::BcOrStData< BcOrStPythonSideInterface >::bc_or_st_object, collectPrimaryVariables(), DBUG(), getDofIdx(), MeshLib::Mesh::getNodes(), NumLib::IndexValueVector< typename >::ids, NumLib::MeshComponentMap::nop, OGS_FATAL, and NumLib::IndexValueVector< typename >::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 206 of file PythonBoundaryCondition.cpp.

209{
210 auto const& boundary_elements =
212 boundary_node.getID());
213
214 if (boundary_elements.size() != 1)
215 {
216 DBUG(
217 "Boundary node {} is associated with {} elements in the boundary "
218 "mesh.",
219 boundary_node.getID(),
220 boundary_elements.size());
221 }
222
223 // Interpolations on all associated elements should return the same. Just
224 // pick any of them.
225 auto const& boundary_element = *boundary_elements.front();
226
227 assert(boundary_element.getNumberOfBaseNodes() <
228 boundary_element.getNumberOfNodes() &&
229 "We expect that the boundary element is a higher order element. "
230 "Otherwise no interpolation should take place.");
231
232 // Search local node id
233 auto const local_node_id_within_boundary_element =
234 getNodeIDinElement(boundary_element, &boundary_node);
235
236 auto const boundary_element_id = boundary_element.getID();
237
238 // Assumption: all boundary elements have a local assembler (in the same
239 // order)
240 auto const& loc_asm = *_local_assemblers[boundary_element_id];
241
242 return loc_asm.interpolate(local_node_id_within_boundary_element,
243 *_dof_table_boundary, x, var, comp);
244}
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
Definition Mesh.cpp:256
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:206

References _bc_data, _dof_table_boundary, _local_assemblers, ProcessLib::BoundaryConditionAndSourceTerm::Python::BcOrStData< BcOrStPythonSideInterface >::bc_or_st_mesh, DBUG(), MeshLib::Mesh::getElementsConnectedToNode(), 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 104 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 107 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 116 of file PythonBoundaryCondition.h.

Referenced by 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 111 of file PythonBoundaryCondition.h.

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


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