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 onExternalSide(const Elem * elem, unsigned int side) override; 51 : virtual void postElement(const Elem * /*elem*/) override; 52 : virtual void post() override; 53 : bool shouldComputeInternalSide(const Elem & elem, const Elem & neighbor) const override; 54 : 55 : protected: 56 : /** 57 : * Reinitialize variables and materials on a face 58 : * @param fe_problem The finite element problem to call reinit methods on 59 : * @param tid The thread ID for which we should reinit variables and materials 60 : * @param elem The element we are reiniting 61 : * @param side The element side corresponding to the face we are reiniting 62 : * @param bnd_id If provided, materials associated with this boundary ID will be reinit'd 63 : * @param lower_d_elem If provided, lower dimensional variables coincident with the element face 64 : * will be reinit'd 65 : */ 66 : void prepareFace(const Elem * elem, 67 : unsigned int side, 68 : BoundaryID bnd_id = Moose::INVALID_BOUNDARY_ID, 69 : const Elem * lower_d_elem = nullptr); 70 : 71 : ///@{ 72 : /// Base class version just calls compute on each object for the element 73 : virtual void computeOnElement(); 74 : virtual void computeOnBoundary(BoundaryID bnd_id, const Elem * lower_d_elem); 75 : virtual void computeOnInterface(BoundaryID bnd_id); 76 : virtual void computeOnInternalFace(const Elem * neighbor); 77 : virtual void computeOnInternalFace() = 0; 78 : ///@} 79 : 80 : /** 81 : * Will dispatch to computeResidual/computeJacobian/computeResidualAndJacobian based on the 82 : * derived class 83 : */ 84 : virtual void compute(ResidualObject & ro) = 0; 85 : 86 : ///@{ 87 : /// Defaults to forwarding to the residual object class 88 : virtual void compute(KernelBase & kernel); 89 : virtual void compute(FVElementalKernel & kernel); 90 : virtual void compute(IntegratedBCBase & bc); 91 : virtual void compute(DGKernelBase & dg, const Elem * neighbor); 92 : virtual void compute(InterfaceKernelBase & ik); 93 : ///@} 94 : 95 : /** 96 : * Add neighbor residual/Jacobian into assembly global data 97 : */ 98 : virtual void accumulateNeighbor() = 0; 99 : 100 : /** 101 : * Add neighbor and lower residual/Jacobian into assembly global data 102 : */ 103 : virtual void accumulateNeighborLower() = 0; 104 : 105 : /** 106 : * Add lower-d residual/Jacobian into assembly global data 107 : */ 108 : virtual void accumulateLower() = 0; 109 : 110 : /** 111 : * Add element residual/Jacobian into assembly global data 112 : */ 113 : virtual void accumulate() = 0; 114 : 115 : /** 116 : * Determine the objects we will actually compute based on vector/matrix tag information 117 : */ 118 : virtual void determineObjectWarehouses() = 0; 119 : 120 : /// Print information about the loop, mostly order of execution of objects 121 : void printGeneralExecutionInformation() const override; 122 : 123 : /// Print list of specific objects executed on each block and in which order 124 : void printBlockExecutionInformation() const override; 125 : 126 : /// Print list of specific objects executed on each boundary and in which order 127 : void printBoundaryExecutionInformation(const unsigned int bid) const override; 128 : 129 : /// Return what the loops is meant to compute 130 0 : virtual std::string objectType() const { return ""; }; 131 : 132 : /// Reference to the underlying NonlinearSystemBase 133 : NonlinearSystemBase & _nl; 134 : 135 : unsigned int _num_cached; 136 : 137 : /// Reference to BC storage structures 138 : MooseObjectTagWarehouse<IntegratedBCBase> & _integrated_bcs; 139 : 140 : MooseObjectWarehouse<IntegratedBCBase> * _ibc_warehouse; 141 : 142 : /// Reference to DGKernel storage structure 143 : MooseObjectTagWarehouse<DGKernelBase> & _dg_kernels; 144 : 145 : MooseObjectWarehouse<DGKernelBase> * _dg_warehouse; 146 : 147 : /// Reference to interface kernel storage structure 148 : MooseObjectTagWarehouse<InterfaceKernelBase> & _interface_kernels; 149 : 150 : MooseObjectWarehouse<InterfaceKernelBase> * _ik_warehouse; 151 : 152 : ///@{ 153 : /// Reference to Kernel storage structures 154 : MooseObjectTagWarehouse<KernelBase> & _kernels; 155 : 156 : MooseObjectWarehouse<KernelBase> * _tag_kernels; 157 : ///@} 158 : 159 : ///@{ 160 : /// Reference to HDGKernel storage structures 161 : MooseObjectTagWarehouse<HDGKernel> & _hdg_kernels; 162 : 163 : MooseObjectWarehouse<HDGKernel> * _hdg_warehouse; 164 : ///@} 165 : 166 : /// Current subdomain FVElementalKernels 167 : std::vector<FVElementalKernel *> _fv_kernels; 168 : 169 : /// Whether there are any active residual objects; otherwise we will do an early return 170 : const bool _has_active_objects; 171 : 172 : private: 173 : /// Whether DG kernels should be executed for a given elem-neighbor pairing. This is determined by 174 : /// calling down to our parent (\p ThreadedElementLoop) class's \p shouldComputeOnInternalSide 175 : /// method which checks things like whether the elem id is less than the neighbor id such that we 176 : /// make sure we do not execute DGKernels twice on the same face 177 : mutable bool _should_execute_dg; 178 : /// Whether the subdomain has DGKernels 179 : bool _subdomain_has_dg; 180 : /// Whether the subdomain has HDGKernels 181 : bool _subdomain_has_hdg; 182 : };