34 template <
typename NodalRowVectorType>
38 double const& integration_weight_)
43 NodalRowVectorType
const N;
49 template <
typename ShapeFunction,
typename IntegrationMethod,
int GlobalDim>
61 bool is_axially_symmetric,
62 unsigned const integration_order,
69 unsigned const n_integration_points =
72 auto const shape_matrices =
77 for (
unsigned ip = 0; ip < n_integration_points; ip++)
82 shape_matrices[ip].integralMeasure *
83 shape_matrices[ip].detJ);
87 void assemble(std::size_t
const source_term_element_id,
97 unsigned const num_integration_points =
100 auto const num_nodes = ShapeFunction::NPOINTS;
101 auto const num_comp_total =
105 typename ShapeMatricesType::template MatrixType<ShapeFunction::NPOINTS,
107 primary_variables_mat(num_nodes, num_comp_total);
108 for (
int var = 0; var < num_var; ++var)
110 auto const num_comp =
112 for (
int comp = 0; comp < num_comp; ++comp)
114 auto const global_component =
117 for (
unsigned element_node_id = 0; element_node_id < num_nodes;
120 auto const boundary_node_id =
131 "No d.o.f. found for (node={:d}, var={:d}, "
133 "That might be due to the use of mixed FEM ansatz "
134 "functions, which is currently not supported by "
135 "the implementation of Python BCs. That excludes, "
136 "e.g., the HM process.",
137 boundary_node_id, var, comp);
139 primary_variables_mat(element_node_id, global_component) =
147 Eigen::MatrixXd::Zero(num_nodes, num_nodes * num_comp_total);
148 std::vector<double> prim_vars_data(num_comp_total);
151 for (
unsigned ip = 0; ip < num_integration_points; ip++)
154 auto const& N = ip_data.N;
155 auto const& coords = fe.interpolateCoordinates(N);
157 prim_vars = N * primary_variables_mat;
159 auto const& w = ip_data.integration_weight;
160 auto const flux_dflux =
162 auto const& flux = flux_dflux.first;
163 auto const& dflux = flux_dflux.second;
164 local_rhs.noalias() += N * (flux * w);
166 if (
static_cast<int>(dflux.size()) != num_comp_total)
173 "The Python source term must return the derivative of "
174 "the flux w.r.t. each primary variable. {:d} components "
175 "expected. {:d} components returned from Python.",
176 num_comp_total, dflux.size());
181 for (
int comp = 0; comp < num_comp_total; ++comp)
184 auto const left = comp * num_nodes;
185 auto const width = num_nodes;
186 auto const height = num_nodes;
189 local_Jac.block(top, left, width, height).noalias() -=
190 ip_data.N.transpose() * (dflux[comp] * w) * N;
195 auto const& indices_specific_component =
196 dof_table_source_term(source_term_element_id,
199 b.
add(indices_specific_component, local_rhs);
205 source_term_element_id, dof_table_source_term);
207 indices_specific_component, indices_all_components};
208 Jac->
add(rci, local_Jac);
220 Eigen::aligned_allocator<IntegrationPointData<NodalRowVectorType>>>
int add(IndexType row, IndexType col, double val)
Global vector based on Eigen vector.
void add(IndexType rowId, double v)
add entry
std::size_t getID() const
virtual const Node * getNode(unsigned idx) const =0
int getGlobalComponent(int const variable_id, int const component_id) const
int getNumberOfVariables() const
GlobalIndexType getGlobalIndex(MeshLib::Location const &l, int const variable_id, int const component_id) const
int getNumberOfVariableComponents(int variable_id) const
int getNumberOfGlobalComponents() const
static NUMLIB_EXPORT GlobalIndexType const nop
typename ShapeMatricesType::NodalRowVectorType NodalRowVectorType
std::vector< IntegrationPointData< NodalRowVectorType >, Eigen::aligned_allocator< IntegrationPointData< NodalRowVectorType > > > _ip_data
typename ShapeMatricesType::NodalMatrixType NodalMatrixType
void assemble(std::size_t const source_term_element_id, NumLib::LocalToGlobalIndexMap const &dof_table_source_term, double const t, const GlobalVector &x, GlobalVector &b, GlobalMatrix *Jac) override
PythonSourceTermLocalAssembler(MeshLib::Element const &e, std::size_t const, bool is_axially_symmetric, unsigned const integration_order, PythonSourceTermData const &data)
MeshLib::Element const & _element
IntegrationMethod const _integration_method
bool const _is_axially_symmetric
PythonSourceTermData const & _data
ShapeMatrixPolicyType< ShapeFunction, GlobalDim > ShapeMatricesType
virtual std::pair< double, std::vector< double > > getFlux(double, std::array< double, 3 > const &, std::vector< double > const &) const =0
Eigen::Map< const Vector > toVector(std::vector< double > const &data, Eigen::VectorXd::Index size)
Creates an Eigen mapped vector from the given data vector.
NumLib::TemplateIsoparametric< ShapeFunction, ShapeMatricesType > createIsoparametricFiniteElement(MeshLib::Element const &e)
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType
NodalRowVectorType const N
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
double const integration_weight
IntegrationPointData(NodalRowVectorType const &N_, double const &integration_weight_)
Groups data used by source terms, in particular by the local assemblers.
std::size_t const source_term_mesh_id
Mesh ID of the entire domain.
PythonSourceTermPythonSideInterface * source_term_object
Python object computing source term values.
int const global_component_id