13 #include "libmesh/string_to_enum.h" 14 #include "libmesh/mesh_tools.h" 15 #include "libmesh/parallel_sync.h" 22 "Base class to compute K_ij (a measure of advective flux from node i to node j) " 23 "and R+ and R- (which quantify amount of antidiffusion to add) in the " 24 "Kuzmin-Turek FEM-TVD multidimensional scheme");
25 MooseEnum flux_limiter_type(
"MinMod VanLeer MC superbee None",
"VanLeer");
28 "Type of flux limiter to use. 'None' means that no antidiffusion " 29 "will be added in the Kuzmin-Turek scheme");
31 "allowable_MB_wastage",
33 "allowable_MB_wastage > 0.0",
34 "This object will issue a memory warning if the internal node-numbering data structure " 35 "wastes more than allowable_MB_wastage megabytes. This data structure uses sequential " 36 "node-numbering which is optimized for speed rather than memory efficiency");
43 { rm_params.
set<
unsigned short>(
"layers") = 2; });
51 _resizing_needed(true),
59 _u_nodal_computed_by_thread(),
62 _my_pid(processor_id()),
67 _allowable_MB_wastage(getParam<
Real>(
"allowable_MB_wastage"))
72 "The AdvectiveFluxCalculator UserObject " +
name() +
73 " execute_on parameter must include, at least, 'linear'. This is to ensure that " 74 "this UserObject computes all necessary quantities just before the Kernels evaluate " 96 if (this->
hasBlocks(elem->subdomain_id()))
97 for (
unsigned i = 0; i < elem->n_nodes(); ++i)
101 if (this->
hasBlocks(elem->subdomain_id()))
102 for (
unsigned i = 0; i < elem->n_nodes(); ++i)
103 for (
unsigned j = 0;
j < elem->n_nodes(); ++
j)
113 "In at least one processor, the sequential node-numbering internal data structure used " 115 name() +
" is using memory inefficiently.\nThe memory wasted is " +
117 " megabytes.\n The node-numbering data structure has been optimized for speed at the " 118 "expense of memory, but that may not be an appropriate optimization for your case, " 119 "because the node numbering is not close to sequential in your case.\n");
124 _kij[sequential_i].assign(
140 if (this->
hasBlocks(elem->subdomain_id()))
141 for (
unsigned i = 0; i < elem->n_nodes(); ++i)
157 const std::vector<dof_id_type> con_i =
159 const std::size_t num_con_i = con_i.size();
161 for (std::size_t
j = 0;
j < con_i.size(); ++
j)
164 const std::size_t num_con_j =
232 for (
unsigned qp = 0; qp <
_qrule->n_points(); ++qp)
255 const std::size_t num_con_i =
257 for (std::size_t
j = 0;
j < num_con_i; ++
j)
258 _kij[sequential_i][
j] += afc._kij[sequential_i][
j];
264 _u_nodal[sequential_i] = afc._u_nodal[sequential_i];
284 const std::vector<dof_id_type> & con_i =
286 const std::size_t num_con_i = con_i.size();
287 _dij[sequential_i].assign(num_con_i, 0.0);
288 _dDij_dKij[sequential_i].assign(num_con_i, 0.0);
289 _dDij_dKji[sequential_i].assign(num_con_i, 0.0);
290 _dDii_dKij[sequential_i].assign(num_con_i, 0.0);
291 _dDii_dKji[sequential_i].assign(num_con_i, 0.0);
292 const unsigned index_i_to_i =
294 for (std::size_t
j = 0;
j < num_con_i; ++
j)
297 if (sequential_i == sequential_j)
299 const unsigned index_j_to_i =
302 const Real kji =
_kij[sequential_j][index_j_to_i];
303 if ((kij <= kji) && (kij < 0.0))
305 _dij[sequential_i][
j] = -kij;
309 else if ((kji <= kij) && (kji < 0.0))
311 _dij[sequential_i][
j] = -kji;
316 _dij[sequential_i][
j] = 0.0;
317 _dij[sequential_i][index_i_to_i] -=
_dij[sequential_i][
j];
325 const std::vector<dof_id_type> & con_i =
327 const std::size_t num_con_i = con_i.size();
328 _lij[sequential_i].assign(num_con_i, 0.0);
329 for (std::size_t
j = 0;
j < num_con_i; ++
j)
346 const std::vector<dof_id_type> & con_i =
348 const unsigned num_con_i = con_i.size();
349 _fa[sequential_i].assign(num_con_i, 0.0);
350 _dfa[sequential_i].resize(num_con_i);
353 for (std::size_t
j = 0;
j < num_con_i; ++
j)
355 for (
const auto & global_k : con_i)
356 _dfa[sequential_i][
j][global_k] = 0;
359 const unsigned num_con_j = con_j.size();
360 for (
const auto & global_k : con_j)
361 _dfa[sequential_i][
j][global_k] = 0;
362 _dFij_dKik[sequential_i][
j].assign(num_con_i, 0.0);
363 _dFij_dKjk[sequential_i][
j].assign(num_con_j, 0.0);
371 const std::vector<dof_id_type> & con_i =
373 const std::size_t num_con_i = con_i.size();
374 for (std::size_t
j = 0;
j < num_con_i; ++
j)
377 if (sequential_i == sequential_j)
379 const unsigned index_j_to_i =
382 const Real Lji =
_lij[sequential_j][index_j_to_i];
388 Real prefactor = 0.0;
389 std::vector<Real> dprefactor_du(num_con_i,
391 std::vector<Real> dprefactor_dKij(
393 Real dprefactor_dKji = 0;
396 if (Lji <=
_rP[sequential_i] * Dij)
399 dprefactor_dKij[
j] +=
_dDij_dKji[sequential_j][index_j_to_i];
400 dprefactor_dKji += 1.0 +
_dDij_dKij[sequential_j][index_j_to_i];
404 prefactor =
_rP[sequential_i] * Dij;
405 for (std::size_t ind_j = 0; ind_j < num_con_i; ++ind_j)
406 dprefactor_du[ind_j] =
_drP[sequential_i][ind_j] * Dij;
408 dprefactor_dKji +=
_rP[sequential_i] *
_dDij_dKji[sequential_i][
j];
409 for (std::size_t ind_j = 0; ind_j < num_con_i; ++ind_j)
410 dprefactor_dKij[ind_j] +=
_drP_dk[sequential_i][ind_j] * Dij;
415 if (Lji <=
_rM[sequential_i] * Dij)
418 dprefactor_dKij[
j] +=
_dDij_dKji[sequential_j][index_j_to_i];
419 dprefactor_dKji += 1.0 +
_dDij_dKij[sequential_j][index_j_to_i];
423 prefactor =
_rM[sequential_i] * Dij;
424 for (std::size_t ind_j = 0; ind_j < num_con_i; ++ind_j)
425 dprefactor_du[ind_j] =
_drM[sequential_i][ind_j] * Dij;
427 dprefactor_dKji +=
_rM[sequential_i] *
_dDij_dKji[sequential_i][
j];
428 for (std::size_t ind_j = 0; ind_j < num_con_i; ++ind_j)
429 dprefactor_dKij[ind_j] +=
_drM_dk[sequential_i][ind_j] * Dij;
432 _fa[sequential_i][
j] = prefactor * (u_i - u_j);
433 _dfa[sequential_i][
j][global_i] = prefactor;
434 _dfa[sequential_i][
j][global_j] = -prefactor;
435 for (std::size_t ind_j = 0; ind_j < num_con_i; ++ind_j)
438 dprefactor_du[ind_j] * (u_i - u_j);
439 _dFij_dKik[sequential_i][
j][ind_j] += dprefactor_dKij[ind_j] * (u_i - u_j);
441 _dFij_dKjk[sequential_i][
j][index_j_to_i] += dprefactor_dKji * (u_i - u_j);
448 const std::vector<dof_id_type> & con_i =
450 const std::size_t num_con_i = con_i.size();
451 for (std::size_t
j = 0;
j < num_con_i; ++
j)
454 if (sequential_i == sequential_j)
456 const unsigned index_j_to_i =
458 if (
_lij[sequential_j][index_j_to_i] <
_lij[sequential_i][
j])
460 _fa[sequential_i][
j] = -
_fa[sequential_j][index_j_to_i];
461 for (
const auto & dof_deriv :
_dfa[sequential_j][index_j_to_i])
462 _dfa[sequential_i][
j][dof_deriv.first] = -dof_deriv.second;
463 for (std::size_t
k = 0;
k < num_con_i; ++
k)
465 const std::size_t num_con_j =
467 for (std::size_t
k = 0;
k < num_con_j; ++
k)
490 const std::vector<dof_id_type> & con_i =
492 const std::size_t num_con_i = con_i.size();
494 for (std::size_t
j = 0;
j < num_con_i; ++
j)
497 const std::vector<dof_id_type> & con_j =
507 const std::vector<dof_id_type> & con_i =
509 const size_t num_con_i = con_i.size();
512 for (std::size_t
j = 0;
j < num_con_i; ++
j)
522 for (
const auto & dof_deriv :
_dfa[sequential_i][
j])
523 _dflux_out_du[sequential_i][dof_deriv.first] -= dof_deriv.second;
527 if (sequential_j == sequential_i)
535 if (sequential_j == sequential_i)
536 for (
unsigned k = 0;
k < con_i.size(); ++
k)
538 const unsigned index_k_to_i =
544 const unsigned index_j_to_i =
558 std::vector<Real> & dlimited_du,
559 std::vector<Real> & dlimited_dk)
const 562 dlimited_du.assign(num_con, 0.0);
563 dlimited_dk.assign(num_con, 0.0);
566 std::vector<Real> dp_du;
567 std::vector<Real> dp_dk;
572 std::vector<Real> dq_du;
573 std::vector<Real> dq_dk;
576 const Real r = q / p;
582 for (std::size_t
j = 0;
j < num_con; ++
j)
584 const Real dr_du = dq_du[
j] / p - q * dp_du[
j] / p2;
585 const Real dr_dk = dq_dk[
j] / p - q * dp_dk[
j] / p2;
586 dlimited_du[
j] = dlimited_dr * dr_du;
587 dlimited_dk[
j] = dlimited_dr * dr_dk;
594 std::vector<Real> & dlimited_du,
595 std::vector<Real> & dlimited_dk)
const 598 dlimited_du.assign(num_con, 0.0);
599 dlimited_dk.assign(num_con, 0.0);
602 std::vector<Real> dp_du;
603 std::vector<Real> dp_dk;
608 std::vector<Real> dq_du;
609 std::vector<Real> dq_dk;
612 const Real r = q / p;
618 for (std::size_t
j = 0;
j < num_con; ++
j)
620 const Real dr_du = dq_du[
j] / p - q * dp_du[
j] / p2;
621 const Real dr_dk = dq_dk[
j] / p - q * dp_dk[
j] / p2;
622 dlimited_du[
j] = dlimited_dr * dr_du;
623 dlimited_dk[
j] = dlimited_dr * dr_dk;
636 if ((
a >= 0.0 &&
b <= 0.0) || (a <= 0.0 && b >= 0.0))
638 const Real s = (
a > 0.0 ? 1.0 : -1.0);
642 const Real dlbl = (
b >= 0.0 ? 1.0 : -1.0);
655 dlimited_db = s * dlbl;
661 limited = s * 2 * lal * lbl / (lal + lbl);
662 dlimited_db = s * 2 * lal * (dlbl / (lal + lbl) - lbl * dlbl /
std::pow(lal + lbl, 2));
668 if (2 * lal <= av && lal <= lbl)
671 limited = s * 2.0 * lal;
674 else if (2 * lbl <= av && lbl <= lal)
677 limited = s * 2.0 * lbl;
678 dlimited_db = s * 2.0 * dlbl;
687 dlimited_db = s * 0.5 * dlbl;
693 const Real term1 = std::min(2.0 * lal, lbl);
694 const Real term2 = std::min(lal, 2.0 * lbl);
697 if (2.0 * lal <= lbl)
699 limited = s * 2 * lal;
705 dlimited_db = s * dlbl;
710 if (lal <= 2.0 * lbl)
717 limited = s * 2.0 * lbl;
718 dlimited_db = s * 2.0 * dlbl;
728 const std::map<dof_id_type, Real> &
734 const std::vector<std::vector<Real>> &
758 the_map[node_j] = 0.0;
764 std::vector<Real> & derivs,
765 std::vector<Real> & dpqdk)
const 771 const std::vector<dof_id_type> con_i =
773 const std::size_t num_con = con_i.size();
779 derivs.assign(num_con, 0.0);
780 dpqdk.assign(num_con, 0.0);
783 for (std::size_t
j = 0;
j < num_con; ++
j)
786 if (sequential_j == sequential_i)
788 const Real kentry =
_kij[sequential_i][
j];
792 const Real ujminusi = u_j - u_i;
795 switch (pq_plus_minus)
799 if (ujminusi < 0.0 && kentry < 0.0)
801 result += kentry * ujminusi;
803 derivs[i_index_i] -= kentry;
804 dpqdk[
j] += ujminusi;
810 if (ujminusi > 0.0 && kentry < 0.0)
812 result += kentry * ujminusi;
814 derivs[i_index_i] -= kentry;
815 dpqdk[
j] += ujminusi;
821 if (ujminusi > 0.0 && kentry > 0.0)
823 result += kentry * ujminusi;
825 derivs[i_index_i] -= kentry;
826 dpqdk[
j] += ujminusi;
832 if (ujminusi < 0.0 && kentry > 0.0)
834 result += kentry * ujminusi;
836 derivs[i_index_i] -= kentry;
837 dpqdk[
j] += ujminusi;
865 if (this->
hasBlocks(elem->subdomain_id()))
872 for (
unsigned i = 0; i < elem->n_nodes(); ++i)
882 auto nodes_action_functor = [
this](
processor_id_type pid,
const std::vector<dof_id_type> & nts)
894 const std::size_t num_nodes = kv.second.size();
895 for (
unsigned i = 0; i < num_nodes; ++i)
901 const std::size_t num_nodes = kv.second.size();
902 for (
unsigned i = 0; i < num_nodes; ++i)
909 if (this->
hasBlocks(elem->subdomain_id()))
915 _pairs_to_receive[elem_pid] = std::vector<std::pair<dof_id_type, dof_id_type>>();
916 for (
unsigned i = 0; i < elem->n_nodes(); ++i)
917 for (
unsigned j = 0;
j < elem->n_nodes(); ++
j)
919 std::pair<dof_id_type, dof_id_type> the_pair(elem->node_id(i), elem->node_id(
j));
929 auto pairs_action_functor =
930 [
this](
processor_id_type pid,
const std::vector<std::pair<dof_id_type, dof_id_type>> & pts)
942 const std::size_t num_pairs = kv.second.size();
943 for (
unsigned i = 0; i < num_pairs; ++i)
953 const std::size_t num_pairs = kv.second.size();
954 for (
unsigned i = 0; i < num_pairs; ++i)
967 std::map<processor_id_type, std::vector<Real>> unodal_to_send;
971 unodal_to_send[pid] = std::vector<Real>();
972 for (
const auto & nd : kv.second)
973 unodal_to_send[pid].push_back(
_u_nodal[nd]);
976 auto unodal_action_functor =
979 const std::size_t msg_size = unodal_received.size();
981 "Message size, " << msg_size
982 <<
", incompatible with nodes_to_receive, which has size " 984 for (
unsigned i = 0; i < msg_size; ++i)
987 Parallel::push_parallel_vector_data(this->
comm(), unodal_to_send, unodal_action_functor);
990 std::map<processor_id_type, std::vector<Real>> kij_to_send;
994 kij_to_send[pid] = std::vector<Real>();
995 for (
const auto & pr : kv.second)
996 kij_to_send[pid].push_back(
_kij[pr.first][pr.second]);
999 auto kij_action_functor = [
this](
processor_id_type pid,
const std::vector<Real> & kij_received)
1001 const std::size_t msg_size = kij_received.size();
1003 "Message size, " << msg_size
1004 <<
", incompatible with pairs_to_receive, which has size " 1006 for (
unsigned i = 0; i < msg_size; ++i)
1009 Parallel::push_parallel_vector_data(this->
comm(), kij_to_send, kij_action_functor);
unsigned getValence(dof_id_type node_i) const
Returns the valence of the global node i Valence is the number of times the node is encountered in a ...
std::vector< std::vector< Real > > _dDij_dKij
dDij_dKij[i][j] = d(D[i][j])/d(K[i][j]) for i!=j
void clear()
clear all data in readiness for adding global nodes and connections
std::vector< bool > _u_nodal_computed_by_thread
_u_nodal_computed_by_thread(i) = true if _u_nodal[i] has been computed in execute() by the thread on ...
virtual void finalize() override
std::vector< std::vector< std::vector< Real > > > _dFij_dKjk
dFij_dKjk[sequential_i][j][k] = d(fa[sequential_i][j])/d(K[sequential_j][k]).
FluxLimiterTypeEnum
Determines Flux Limiter type (Page 135 of Kuzmin and Turek) "None" means that limitFlux=0 always...
dof_id_type globalID(dof_id_type sequential_node_ID) const
Return the global node ID (node number in the mesh) corresponding to the provided sequential node ID...
Real getFluxOut(dof_id_type node_i) const
Returns the flux out of lobal node id.
const MooseArray< Real > & _coord
virtual void meshChanged()
static InputParameters validParams()
void limitFlux(Real a, Real b, Real &limited, Real &dlimited_db) const
flux limiter, L, on Page 135 of Kuzmin and Turek
std::vector< std::vector< std::map< dof_id_type, Real > > > _dfa
dfa[sequential_i][j][global_k] = d(fa[sequential_i][j])/du[global_k].
std::vector< std::map< dof_id_type, Real > > _dflux_out_du
_dflux_out_du[i][j] = d(flux_out[i])/d(u[j]).
virtual void execute() override
void addConnection(dof_id_type global_node_from, dof_id_type global_node_to)
Specifies that global_node_to is connected to global_node_from.
dof_id_type sequentialID(dof_id_type global_node_ID) const
Return the sequential node ID corresponding to the global node ID This is guaranteed to lie in the ra...
const std::vector< dof_id_type > & sequentialConnectionsToSequentialID(dof_id_type sequential_node_ID) const
Return all the nodes (sequential node IDs) connected to the given sequential node ID All elements of ...
const Parallel::Communicator & comm() const
Real rMinus(dof_id_type sequential_i, std::vector< Real > &dlimited_du, std::vector< Real > &dlimited_dk) const
Returns the value of R_{i}^{-}, Eqn (49) of KT.
void finalizeAddingConnections()
Signal that all global node IDs have been added to the internal data structures.
unsigned indexOfGlobalConnection(dof_id_type global_node_ID_from, dof_id_type global_node_ID_to) const
Return the index of global_node_ID_to in the globalConnectionsToGlobalID(global_node_ID_from) vector...
virtual void executeOnElement(dof_id_type global_i, dof_id_type global_j, unsigned local_i, unsigned local_j, unsigned qp)
This is called by multiple times in execute() in a double loop over _current_elem's nodes (local_i an...
std::vector< std::vector< Real > > _dij
Vectors used in finalize()
std::size_t _number_of_nodes
Number of nodes held by the _connections object.
std::vector< Real > _flux_out
_flux_out[i] = flux of "heat" from sequential node i
std::vector< std::vector< std::vector< Real > > > _dflux_out_dKjk
_dflux_out_dKjk[sequential_i][j][k] = d(flux_out[sequential_i])/d(K[j][k]).
std::vector< std::vector< Real > > _dDii_dKij
dDii_dKij[i][j] = d(D[i][i])/d(K[i][j])
virtual const std::string & name() const
void mooseWarning(Args &&... args) const
std::vector< std::vector< Real > > _dDii_dKji
dDii_dKji[i][j] = d(D[i][i])/d(K[j][i])
Real PQPlusMinus(dof_id_type sequential_i, const PQPlusMinusEnum pq_plus_minus, std::vector< Real > &derivs, std::vector< Real > &dpq_dk) const
Returns the value of P_{i}^{+}, P_{i}^{-}, Q_{i}^{+} or Q_{i}^{-} (depending on pq_plus_minus) which ...
const std::vector< dof_id_type > & globalConnectionsToSequentialID(dof_id_type sequential_node_ID) const
Return all the nodes (global node IDs) connected to the given sequential node ID. ...
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
uint8_t processor_id_type
bool contains(const std::string &value) const
processor_id_type n_processors() const
std::size_t sizeSequential() const
Return the size of _sequential_id, for checking memory efficiency.
static InputParameters validParams()
Base class to compute Advective fluxes.
enum AdvectiveFluxCalculatorBase::FluxLimiterTypeEnum _flux_limiter_type
PorousFlowConnectedNodes _connections
Holds the sequential and global nodal IDs, and info regarding mesh connections between them...
bool _resizing_needed
whether _kij, etc, need to be sized appropriately (and valence recomputed) at the start of the timest...
std::map< processor_id_type, std::vector< dof_id_type > > _nodes_to_send
_nodes_to_send[proc_id] = list of sequential nodal IDs.
std::vector< std::vector< Real > > _drM_dk
drM_dk[i][j] = d(rM[i])/d(K[i][j]). Here j indexes the j^th node connected to i
const std::map< dof_id_type, Real > & getdFluxOutdu(dof_id_type node_i) const
Returns r where r[j] = d(flux out of global node i)/du(global node j) used in Jacobian computations...
std::vector< std::vector< Real > > _drM
drM[i][j] = d(rM[i])/d(u[j]). Here j indexes the j^th node connected to i
const std::vector< std::vector< Real > > & getdFluxOutdKjk(dof_id_type node_i) const
Returns r where r[j][k] = d(flux out of global node i)/dK[connected node j][connected node k] used in...
void paramError(const std::string ¶m, Args... args) const
Real rPlus(dof_id_type sequential_i, std::vector< Real > &dlimited_du, std::vector< Real > &dlimited_dk) const
Returns the value of R_{i}^{+}, Eqn (49) of KT.
const ExecFlagType EXEC_LINEAR
std::map< processor_id_type, std::vector< std::pair< dof_id_type, dof_id_type > > > _pairs_to_send
_pairs_to_send[proc_id] indicates the k(i, j) pairs that we will send to proc_id _pairs_to_send is fi...
std::string stringify(const T &t)
std::vector< Real > _u_nodal
_u_nodal[i] = value of _u at sequential node number i
processor_id_type _my_pid
processor ID of this object
virtual void exchangeGhostedInfo()
Sends and receives multi-processor information regarding u_nodal and k_ij.
const ExecFlagEnum & _execute_enum
const Real _allowable_MB_wastage
A mooseWarning is issued if mb_wasted = (_connections.sizeSequential() - _connections.numNodes()) * 4 / 1048576 > _allowable_MB_wastage.
virtual Real computeVelocity(unsigned i, unsigned j, unsigned qp) const =0
Computes the transfer velocity between current node i and current node j at the current qp in the cur...
virtual Real computeU(unsigned i) const =0
Computes the value of u at the local node id of the current element (_current_elem) ...
std::size_t numNodes() const
number of nodes known by this class
std::vector< std::vector< Real > > _drP_dk
drP_dk[i][j] = d(rP[i])/d(K[i][j]). Here j indexes the j^th node connected to i
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const QBase *const & _qrule
const Elem *const & _current_elem
std::vector< std::vector< std::vector< Real > > > _dFij_dKik
dFij_dKik[sequential_i][j][k] = d(fa[sequential_i][j])/d(K[sequential_i][k]).
FEProblemBase & _fe_problem
AdvectiveFluxCalculatorBase(const InputParameters ¶meters)
const MooseArray< Real > & _JxW
std::vector< std::vector< Real > > _lij
virtual void buildCommLists()
When using multiple processors, other processors will compute:
std::vector< std::vector< Real > > _kij
Kuzmin-Turek K_ij matrix.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::map< processor_id_type, std::vector< dof_id_type > > _nodes_to_receive
_nodes_to_receive[proc_id] = list of sequential nodal IDs.
PQPlusMinusEnum
Signals to the PQPlusMinus method what should be computed.
std::map< processor_id_type, std::vector< std::pair< dof_id_type, dof_id_type > > > _pairs_to_receive
_pairs_to_receive[proc_id] indicates the k(i, j) pairs that will be sent to us from proc_id _pairs_to...
const std::vector< dof_id_type > & globalConnectionsToGlobalID(dof_id_type global_node_ID) const
Return all the nodes (global node IDs) connected to the given global node ID.
void finalizeAddingGlobalNodes()
Signal that all global node IDs have been added to the internal data structures.
virtual void timestepSetup() override
bool hasBlocks(const SubdomainName &name) const
void zeroedConnection(std::map< dof_id_type, Real > &the_map, dof_id_type node_i) const
Clears the_map, then, using _kij, constructs the_map so that the_map[node_id] = 0.0 for all node_id connected with node_i.
virtual void meshChanged() override
virtual void initialize() override
const ConstElemRange & getNonlinearEvaluableElementRange()
std::vector< unsigned > _valence
_valence[i] = number of times, in a loop over elements seen by this processor (viz, including ghost elements) and are part of the block-restricted blocks of this UserObject, that the sequential node i is encountered
std::vector< std::vector< Real > > _dDij_dKji
dDij_dKji[i][j] = d(D[i][j])/d(K[j][i]) for i!=j
virtual void threadJoin(const UserObject &uo) override
MooseUnits pow(const MooseUnits &, int)
std::vector< std::vector< Real > > _fa
fa[sequential_i][j] sequential_j is the j^th connection to sequential_i
static const std::string k
void addGlobalNode(dof_id_type global_node_ID)
Add the given global_node_ID to the internal data structures If the global node ID has already been a...
std::vector< std::vector< Real > > _drP
drP[i][j] = d(rP[i])/d(u[j]). Here j indexes the j^th node connected to i
unsigned indexOfSequentialConnection(dof_id_type sequential_node_ID_from, dof_id_type sequential_node_ID_to) const
Return the index of sequential_node_ID_to in the sequentialConnectionsToSequentialID(sequential_node_...