Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "ThreadedElementLoop.h" 13 : #include "MooseObjectTagWarehouse.h" 14 : 15 : #include "libmesh/elem_range.h" 16 : 17 : // Forward declarations 18 : class FEProblemBase; 19 : class NonlinearSystemBase; 20 : class IntegratedBCBase; 21 : class DGKernelBase; 22 : class InterfaceKernelBase; 23 : class TimeKernel; 24 : class KernelBase; 25 : class Kernel; 26 : class ResidualObject; 27 : class FVElementalKernel; 28 : class HDGKernel; 29 : 30 : class NonlinearThread : public ThreadedElementLoop<ConstElemRange> 31 : { 32 : public: 33 : NonlinearThread(FEProblemBase & fe_problem); 34 : 35 : // Splitting Constructor 36 : NonlinearThread(NonlinearThread & x, Threads::split split); 37 : 38 : virtual ~NonlinearThread(); 39 : 40 : virtual void operator()(const ConstElemRange & range, bool bypass_threading = false) override; 41 : 42 : virtual void subdomainChanged() override; 43 : virtual void onElement(const Elem * elem) override; 44 : virtual void onBoundary(const Elem * elem, 45 : unsigned int side, 46 : BoundaryID bnd_id, 47 : const Elem * lower_d_elem = nullptr) override; 48 : virtual void onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id) override; 49 : virtual void onInternalSide(const Elem * elem, unsigned int side) override; 50 : virtual void postElement(const Elem * /*elem*/) override; 51 : virtual void post() override; 52 : bool shouldComputeInternalSide(const Elem & elem, const Elem & neighbor) const override; 53 : 54 : protected: 55 : /** 56 : * Reinitialize variables and materials on a face 57 : * @param fe_problem The finite element problem to call reinit methods on 58 : * @param tid The thread ID for which we should reinit variables and materials 59 : * @param elem The element we are reiniting 60 : * @param side The element side corresponding to the face we are reiniting 61 : * @param bnd_id If provided, materials associated with this boundary ID will be reinit'd 62 : * @param lower_d_elem If provided, lower dimensional variables coincident with the element face 63 : * will be reinit'd 64 : */ 65 : void prepareFace(const Elem * elem, 66 : unsigned int side, 67 : BoundaryID bnd_id = Moose::INVALID_BOUNDARY_ID, 68 : const Elem * lower_d_elem = nullptr); 69 : 70 : ///@{ 71 : /// Base class version just calls compute on each object for the element 72 : virtual void computeOnElement(); 73 : virtual void computeOnBoundary(BoundaryID bnd_id, const Elem * lower_d_elem); 74 : virtual void computeOnInterface(BoundaryID bnd_id); 75 : virtual void computeOnInternalFace(const Elem * neighbor); 76 : virtual void computeOnInternalFace() = 0; 77 : ///@} 78 : 79 : /** 80 : * Will dispatch to computeResidual/computeJacobian/computeResidualAndJacobian based on the 81 : * derived class 82 : */ 83 : virtual void compute(ResidualObject & ro) = 0; 84 : 85 : ///@{ 86 : /// Defaults to forwarding to the residual object class 87 : virtual void compute(KernelBase & kernel); 88 : virtual void compute(FVElementalKernel & kernel); 89 : virtual void compute(IntegratedBCBase & bc); 90 : virtual void compute(DGKernelBase & dg, const Elem * neighbor); 91 : virtual void compute(InterfaceKernelBase & ik); 92 : ///@} 93 : 94 : /** 95 : * Add neighbor residual/Jacobian into assembly global data 96 : */ 97 : virtual void accumulateNeighbor() = 0; 98 : 99 : /** 100 : * Add neighbor and lower residual/Jacobian into assembly global data 101 : */ 102 : virtual void accumulateNeighborLower() = 0; 103 : 104 : /** 105 : * Add lower-d residual/Jacobian into assembly global data 106 : */ 107 : virtual void accumulateLower() = 0; 108 : 109 : /** 110 : * Add element residual/Jacobian into assembly global data 111 : */ 112 : virtual void accumulate() = 0; 113 : 114 : /** 115 : * Determine the objects we will actually compute based on vector/matrix tag information 116 : */ 117 : virtual void determineObjectWarehouses() = 0; 118 : 119 : /// Print information about the loop, mostly order of execution of objects 120 : void printGeneralExecutionInformation() const override; 121 : 122 : /// Print list of specific objects executed on each block and in which order 123 : void printBlockExecutionInformation() const override; 124 : 125 : /// Print list of specific objects executed on each boundary and in which order 126 : void printBoundaryExecutionInformation(const unsigned int bid) const override; 127 : 128 : /// Return what the loops is meant to compute 129 0 : virtual std::string objectType() const { return ""; }; 130 : 131 : NonlinearSystemBase & _nl; 132 : unsigned int _num_cached; 133 : 134 : /// Reference to BC storage structures 135 : MooseObjectTagWarehouse<IntegratedBCBase> & _integrated_bcs; 136 : 137 : MooseObjectWarehouse<IntegratedBCBase> * _ibc_warehouse; 138 : 139 : /// Reference to DGKernel storage structure 140 : MooseObjectTagWarehouse<DGKernelBase> & _dg_kernels; 141 : 142 : MooseObjectWarehouse<DGKernelBase> * _dg_warehouse; 143 : 144 : /// Reference to interface kernel storage structure 145 : MooseObjectTagWarehouse<InterfaceKernelBase> & _interface_kernels; 146 : 147 : MooseObjectWarehouse<InterfaceKernelBase> * _ik_warehouse; 148 : 149 : ///@{ 150 : /// Reference to Kernel storage structures 151 : MooseObjectTagWarehouse<KernelBase> & _kernels; 152 : 153 : MooseObjectWarehouse<KernelBase> * _tag_kernels; 154 : ///@} 155 : 156 : ///@{ 157 : /// Reference to HDGKernel storage structures 158 : MooseObjectTagWarehouse<HDGKernel> & _hdg_kernels; 159 : 160 : MooseObjectWarehouse<HDGKernel> * _hdg_warehouse; 161 : ///@} 162 : 163 : /// Current subdomain FVElementalKernels 164 : std::vector<FVElementalKernel *> _fv_kernels; 165 : 166 : /// Whether there are any active residual objects; otherwise we will do an early return 167 : const bool _has_active_objects; 168 : 169 : private: 170 : /// Whether DG kernels should be executed for a given elem-neighbor pairing. This is determined by 171 : /// calling down to our parent (\p ThreadedElementLoop) class's \p shouldComputeOnInternalSide 172 : /// method which checks things like whether the elem id is less than the neighbor id such that we 173 : /// make sure we do not execute DGKernels twice on the same face 174 : mutable bool _should_execute_dg; 175 : };