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 "MooseArray.h" 13 : #include "MooseTypes.h" 14 : #include "MeshChangedInterface.h" 15 : #include "MooseVariableDataBase.h" 16 : #include "TheWarehouse.h" 17 : 18 : #include "libmesh/tensor_tools.h" 19 : #include "libmesh/vector_value.h" 20 : #include "libmesh/tensor_value.h" 21 : #include "libmesh/type_n_tensor.h" 22 : #include "libmesh/fe_type.h" 23 : #include "libmesh/dof_map.h" 24 : #include "libmesh/enum_fe_family.h" 25 : #include "SubProblem.h" 26 : 27 : #include <functional> 28 : #include <vector> 29 : 30 : class FaceInfo; 31 : class SystemBase; 32 : class TimeIntegrator; 33 : class Assembly; 34 : 35 : template <typename> 36 : class MooseVariableFV; 37 : 38 : namespace libMesh 39 : { 40 : class QBase; 41 : } 42 : 43 : namespace Moose 44 : { 45 : template <typename T> 46 : void 47 1547756239 : initDofIndices(T & data, const Elem & elem) 48 : { 49 1547756239 : if (data._prev_elem != &elem) 50 : { 51 282976158 : data._dof_map.dof_indices(&elem, data._dof_indices, data._var_num); 52 282976158 : data._prev_elem = &elem; 53 : } 54 1547756239 : } 55 : } 56 : 57 : namespace 58 : { 59 : template <typename T, typename T2> 60 : void 61 195907008 : assignForAllQps(const T & value, T2 & array, const unsigned int nqp) 62 : { 63 393985036 : for (const auto qp : make_range(nqp)) 64 198078028 : array[qp] = value; 65 195907008 : } 66 : } 67 : 68 : template <typename OutputType> 69 : class MooseVariableDataFV : public MooseVariableDataBase<OutputType>, public MeshChangedInterface 70 : { 71 : public: 72 : // type for gradient, second and divergence of template class OutputType 73 : typedef typename libMesh::TensorTools::IncrementRank<OutputType>::type OutputGradient; 74 : typedef typename libMesh::TensorTools::IncrementRank<OutputGradient>::type OutputSecond; 75 : typedef typename libMesh::TensorTools::DecrementRank<OutputType>::type OutputDivergence; 76 : 77 : // shortcut for types storing values on quadrature points 78 : typedef MooseArray<OutputType> FieldVariableValue; 79 : typedef MooseArray<OutputGradient> FieldVariableGradient; 80 : typedef MooseArray<OutputSecond> FieldVariableSecond; 81 : typedef MooseArray<OutputType> FieldVariableCurl; 82 : typedef MooseArray<OutputDivergence> FieldVariableDivergence; 83 : 84 : // shape function type for the template class OutputType 85 : typedef typename Moose::ShapeType<OutputType>::type OutputShape; 86 : 87 : // type for gradient, second and divergence of shape functions of template class OutputType 88 : typedef typename libMesh::TensorTools::IncrementRank<OutputShape>::type OutputShapeGradient; 89 : typedef typename libMesh::TensorTools::IncrementRank<OutputShapeGradient>::type OutputShapeSecond; 90 : typedef typename libMesh::TensorTools::DecrementRank<OutputShape>::type OutputShapeDivergence; 91 : 92 : // DoF value type for the template class OutputType 93 : typedef typename Moose::DOFType<OutputType>::type OutputData; 94 : typedef MooseArray<OutputData> DoFValue; 95 : 96 : MooseVariableDataFV(const MooseVariableFV<OutputType> & var, 97 : SystemBase & sys, 98 : THREAD_ID tid, 99 : Moose::ElementType element_type, 100 : const Elem * const & elem); 101 : 102 0 : bool isNodal() const override { return false; } 103 0 : bool hasDoFsOnNodes() const override { return false; } 104 344 : libMesh::FEContinuity getContinuity() const override { return libMesh::DISCONTINUOUS; } 105 : 106 : /** 107 : * Returns whether this data structure needs automatic differentiation calculations 108 : */ 109 0 : bool needsAD() const { return _need_ad; } 110 : 111 : /** 112 : * Set the geometry type before calculating variables values 113 : * @param gm_type The type type of geometry; either Volume or Face 114 : */ 115 : void setGeometry(Moose::GeometryType gm_type); 116 : 117 : //////////////// Heavy lifting computational routines ////////////////////////////// 118 : 119 : /** 120 : * compute the variable values 121 : */ 122 : void computeValuesFace(const FaceInfo & fi); 123 : 124 : /** 125 : * compute the variable values 126 : */ 127 : void computeValues(); 128 : 129 : /** 130 : * compute AD things 131 : */ 132 : void computeAD(const unsigned int num_dofs, const unsigned int nqp); 133 : 134 : ///////////////////////////// Shape functions ///////////////////////////////////// 135 : 136 : /** 137 : * The current element 138 : */ 139 992 : const Elem * const & currentElem() const { return _elem; } 140 : 141 : /** 142 : * prepare the initial condition 143 : */ 144 : void prepareIC(); 145 : 146 : //////////////////////////////////// Solution getters ///////////////////////////////////// 147 : 148 : /** 149 : * Local solution value 150 : */ 151 : const FieldVariableValue & sln(Moose::SolutionState state) const; 152 : 153 : /** 154 : * Local time derivative of solution gradient getter 155 : */ 156 : const FieldVariableGradient & gradSlnDot() const; 157 : 158 : /** 159 : * Local second time derivative of solution gradient getter 160 : */ 161 : const FieldVariableGradient & gradSlnDotDot() const; 162 : 163 : /** 164 : * Local solution second spatial derivative getter 165 : * @param state The state of the simulation: current, old, older, previous nl 166 : */ 167 : const FieldVariableSecond & secondSln(Moose::SolutionState state) const; 168 : 169 : /** 170 : * Local solution curl getter 171 : * @param state The state of the simulation: current, old, older 172 : */ 173 : const FieldVariableCurl & curlSln(Moose::SolutionState state) const; 174 : 175 18370 : const ADTemplateVariableValue<OutputType> & adSln() const 176 : { 177 18370 : _need_ad = _need_ad_u = true; 178 18370 : return _ad_u; 179 : } 180 : 181 1310 : const ADTemplateVariableGradient<OutputType> & adGradSln() const 182 : { 183 1310 : _need_ad = _need_ad_grad_u = true; 184 1310 : return _ad_grad_u; 185 : } 186 : 187 0 : const ADTemplateVariableGradient<OutputType> & adGradSlnDot() const 188 : { 189 0 : mooseError("Gradient of time derivative not yet implemented for FV"); 190 : } 191 : 192 0 : const ADTemplateVariableSecond<OutputType> & adSecondSln() const 193 : { 194 0 : _need_ad = _need_ad_second_u = true; 195 0 : return _ad_second_u; 196 : } 197 : 198 : const ADTemplateVariableValue<OutputType> & adUDot() const; 199 : 200 : const ADTemplateVariableValue<OutputType> & adUDotDot() const; 201 : 202 : const FieldVariableValue & uDot() const; 203 : 204 : const FieldVariableValue & uDotDot() const; 205 : 206 : const FieldVariableValue & uDotOld() const; 207 : 208 : const FieldVariableValue & uDotDotOld() const; 209 : 210 0 : const VariableValue & duDotDu() const 211 : { 212 0 : _need_du_dot_du = true; 213 0 : return _du_dot_du; 214 : } 215 : 216 0 : const VariableValue & duDotDotDu() const 217 : { 218 0 : _need_du_dotdot_du = true; 219 0 : return _du_dotdot_du; 220 : } 221 : 222 : /** 223 : * Set local DOF values and evaluate the values on quadrature points 224 : */ 225 : void setDofValues(const DenseVector<OutputData> & values); 226 : 227 : ///@{ 228 : /** 229 : * dof value setters 230 : */ 231 : void setDofValue(const OutputData & value, unsigned int index); 232 : ///@} 233 : 234 : OutputData 235 : getElementalValue(const Elem * elem, Moose::SolutionState state, unsigned int idx = 0) const; 236 : 237 : ///////////////////////////// dof indices /////////////////////////////////////////////// 238 : 239 : void getDofIndices(const Elem * elem, std::vector<dof_id_type> & dof_indices) const; 240 : const std::vector<dof_id_type> & dofIndices() const; 241 : unsigned int numberOfDofs() const; 242 21029473 : void clearDofIndices() 243 : { 244 21029473 : _dof_indices.clear(); 245 21029473 : _prev_elem = nullptr; 246 21029473 : } 247 : 248 : /////////////////////////// DoF value getters ///////////////////////////////////// 249 : 250 : const DoFValue & dofValuesDot() const; 251 : const DoFValue & dofValuesDotOld() const; 252 : const DoFValue & dofValuesDotDot() const; 253 : const DoFValue & dofValuesDotDotOld() const; 254 : const MooseArray<libMesh::Number> & dofValuesDuDotDu() const; 255 : const MooseArray<libMesh::Number> & dofValuesDuDotDotDu() const; 256 : 257 : /** 258 : * Return the AD dof values 259 : */ 260 : const MooseArray<ADReal> & adDofValues() const; 261 : 262 : /** 263 : * Return the AD dof time derivatives 264 : */ 265 : const MooseArray<ADReal> & adDofValuesDot() const; 266 : 267 : /////////////////////////////// Increment stuff /////////////////////////////////////// 268 : 269 : /** 270 : * Increment getter 271 : * @return The increment 272 : */ 273 0 : const FieldVariableValue & increment() const { return _increment; } 274 : 275 : /** 276 : * Compute and store incremental change in solution at QPs based on increment_vec 277 : */ 278 : void computeIncrementAtQps(const libMesh::NumericVector<libMesh::Number> & increment_vec); 279 : 280 : /// checks if a Dirichlet BC exists on this face 281 0 : bool hasDirichletBC() const { return _has_dirichlet_bc; } 282 : 283 : void meshChanged() override; 284 : 285 : protected: 286 0 : virtual const MooseVariableFV<OutputType> & var() const override { return _var; } 287 : 288 : private: 289 : void initializeSolnVars(); 290 : 291 : /** 292 : * Helper methods for assigning nodal values from their corresponding solution values (dof 293 : * values as they're referred to here in this class). These methods are only truly meaningful 294 : * for nodal basis families 295 : */ 296 : void fetchADDoFValues(); 297 : 298 : /** 299 : * Helper method that tells us whether it's safe to compute _ad_u_dot 300 : */ 301 : bool safeToComputeADUDot() const; 302 : 303 : /// A const reference to the owning MooseVariableFV object 304 : const MooseVariableFV<OutputType> & _var; 305 : 306 : const libMesh::FEType & _fe_type; 307 : 308 : const unsigned int _var_num; 309 : 310 : const Assembly & _assembly; 311 : 312 : /// The element type this object is storing data for. This is either Element, Neighbor, or Lower 313 : Moose::ElementType _element_type; 314 : 315 : /// Continuity type of the variable 316 : libMesh::FEContinuity _continuity; 317 : 318 : /// Increment in the variable used in dampers 319 : FieldVariableValue _increment; 320 : 321 : /// A zero AD variable 322 : const ADReal _ad_zero; 323 : 324 : /// SolutionState second_u flags 325 : mutable bool _need_second; 326 : mutable bool _need_second_old; 327 : mutable bool _need_second_older; 328 : mutable bool _need_second_previous_nl; 329 : 330 : /// curl flags 331 : mutable bool _need_curl; 332 : mutable bool _need_curl_old; 333 : mutable bool _need_curl_older; 334 : 335 : /// AD flags 336 : mutable bool _need_ad; 337 : mutable bool _need_ad_u; 338 : mutable bool _need_ad_u_dot; 339 : mutable bool _need_ad_u_dotdot; 340 : mutable bool _need_ad_grad_u; 341 : mutable bool _need_ad_grad_u_dot; 342 : mutable bool _need_ad_second_u; 343 : 344 : /// grad_u dots 345 : FieldVariableGradient _grad_u_dot; 346 : FieldVariableGradient _grad_u_dotdot; 347 : 348 : /// second_u 349 : FieldVariableSecond _second_u; 350 : FieldVariableSecond _second_u_old; 351 : FieldVariableSecond _second_u_older; 352 : FieldVariableSecond _second_u_previous_nl; 353 : 354 : /// curl_u 355 : FieldVariableCurl _curl_u; 356 : FieldVariableCurl _curl_u_old; 357 : FieldVariableCurl _curl_u_older; 358 : 359 : /// AD u 360 : ADTemplateVariableValue<OutputShape> _ad_u; 361 : ADTemplateVariableGradient<OutputShape> _ad_grad_u; 362 : ADTemplateVariableSecond<OutputShape> _ad_second_u; 363 : MooseArray<ADReal> _ad_dof_values; 364 : MooseArray<ADReal> _ad_dofs_dot; 365 : MooseArray<ADReal> _ad_dofs_dotdot; 366 : ADTemplateVariableValue<OutputShape> _ad_u_dot; 367 : ADTemplateVariableValue<OutputShape> _ad_u_dotdot; 368 : ADTemplateVariableGradient<OutputShape> _ad_grad_u_dot; 369 : 370 : // time derivatives 371 : 372 : /// u_dot (time derivative) 373 : FieldVariableValue _u_dot; 374 : 375 : /// u_dotdot (second time derivative) 376 : FieldVariableValue _u_dotdot; 377 : 378 : /// u_dot_old (time derivative) 379 : FieldVariableValue _u_dot_old; 380 : 381 : /// u_dotdot_old (second time derivative) 382 : FieldVariableValue _u_dotdot_old; 383 : 384 : /// derivative of u_dot wrt u 385 : VariableValue _du_dot_du; 386 : 387 : /// derivative of u_dotdot wrt u 388 : VariableValue _du_dotdot_du; 389 : 390 : /// Pointer to time integrator 391 : const TimeIntegrator * const _time_integrator; 392 : 393 : /// The current elem. This has to be a reference because the current elem will be constantly 394 : /// changing. If we initialized this to point to one elem, then in the next calculation we would 395 : /// be pointing to the wrong place! 396 : const Elem * const & _elem; 397 : /// used to keep track of when dof indices are out of date 398 : mutable const Elem * _prev_elem = nullptr; 399 : 400 : const std::vector<dof_id_type> & initDofIndices(); 401 : 402 : /// if this variable has a dirichlet bc defined on a particular face 403 : bool _has_dirichlet_bc; 404 : 405 : /// Whether this variable is being calculated on a displaced system 406 : const bool _displaced; 407 : 408 : /// The quadrature rule 409 : const libMesh::QBase * _qrule; 410 : 411 : /// A dummy ADReal variable 412 12748 : ADReal _ad_real_dummy = 0; 413 : 414 : /// Cached warehouse query for FVElementalKernels 415 : TheWarehouse::QueryCache<> _fv_elemental_kernel_query_cache; 416 : /// Cached warehouse query for FVFluxKernels 417 : TheWarehouse::QueryCache<> _fv_flux_kernel_query_cache; 418 : 419 : using MooseVariableDataBase<OutputType>::_sys; 420 : using MooseVariableDataBase<OutputType>::_subproblem; 421 : using MooseVariableDataBase<OutputType>::_need_vector_tag_dof_u; 422 : using MooseVariableDataBase<OutputType>::_need_matrix_tag_dof_u; 423 : using MooseVariableDataBase<OutputType>::_vector_tags_dof_u; 424 : using MooseVariableDataBase<OutputType>::_matrix_tags_dof_u; 425 : using MooseVariableDataBase<OutputType>::_vector_tag_u; 426 : using MooseVariableDataBase<OutputType>::_need_vector_tag_u; 427 : using MooseVariableDataBase<OutputType>::_vector_tag_grad; 428 : using MooseVariableDataBase<OutputType>::_need_vector_tag_grad; 429 : using MooseVariableDataBase<OutputType>::_matrix_tag_u; 430 : using MooseVariableDataBase<OutputType>::_need_matrix_tag_u; 431 : using MooseVariableDataBase<OutputType>::_dof_indices; 432 : using MooseVariableDataBase<OutputType>::_has_dof_values; 433 : using MooseVariableDataBase<OutputType>::fetchDoFValues; 434 : using MooseVariableDataBase<OutputType>::assignNodalValue; 435 : using MooseVariableDataBase<OutputType>::zeroSizeDofValues; 436 : using MooseVariableDataBase<OutputType>::_solution_tag; 437 : using MooseVariableDataBase<OutputType>::_old_solution_tag; 438 : using MooseVariableDataBase<OutputType>::_older_solution_tag; 439 : using MooseVariableDataBase<OutputType>::_previous_nl_solution_tag; 440 : using MooseVariableDataBase<OutputType>::_dof_map; 441 : using MooseVariableDataBase<OutputType>::_need_u_dot; 442 : using MooseVariableDataBase<OutputType>::_need_u_dotdot; 443 : using MooseVariableDataBase<OutputType>::_need_u_dot_old; 444 : using MooseVariableDataBase<OutputType>::_need_u_dotdot_old; 445 : using MooseVariableDataBase<OutputType>::_need_du_dot_du; 446 : using MooseVariableDataBase<OutputType>::_need_du_dotdot_du; 447 : using MooseVariableDataBase<OutputType>::_need_grad_dot; 448 : using MooseVariableDataBase<OutputType>::_need_grad_dotdot; 449 : using MooseVariableDataBase<OutputType>::_need_dof_values_dot; 450 : using MooseVariableDataBase<OutputType>::_need_dof_values_dotdot; 451 : using MooseVariableDataBase<OutputType>::_need_dof_values_dot_old; 452 : using MooseVariableDataBase<OutputType>::_need_dof_values_dotdot_old; 453 : using MooseVariableDataBase<OutputType>::_need_dof_du_dot_du; 454 : using MooseVariableDataBase<OutputType>::_need_dof_du_dotdot_du; 455 : using MooseVariableDataBase<OutputType>::_dof_values_dot; 456 : using MooseVariableDataBase<OutputType>::_dof_values_dotdot; 457 : using MooseVariableDataBase<OutputType>::_dof_values_dot_old; 458 : using MooseVariableDataBase<OutputType>::_dof_values_dotdot_old; 459 : using MooseVariableDataBase<OutputType>::_dof_du_dot_du; 460 : using MooseVariableDataBase<OutputType>::_dof_du_dotdot_du; 461 : using MooseVariableDataBase<OutputType>::_tid; 462 : using MooseVariableDataBase<OutputType>::_nodal_value_dot; 463 : using MooseVariableDataBase<OutputType>::_nodal_value_dotdot; 464 : using MooseVariableDataBase<OutputType>::_nodal_value_dot_old; 465 : using MooseVariableDataBase<OutputType>::_nodal_value_dotdot_old; 466 : using MooseVariableDataBase<OutputType>::_required_vector_tags; 467 : 468 : friend void Moose::initDofIndices<>(MooseVariableDataFV<OutputType> &, const Elem &); 469 : }; 470 : 471 : /////////////////////// General template definitions ////////////////////////////////////// 472 : 473 : template <typename OutputType> 474 : const MooseArray<ADReal> & 475 0 : MooseVariableDataFV<OutputType>::adDofValues() const 476 : { 477 0 : _need_ad = true; 478 0 : return _ad_dof_values; 479 : } 480 : 481 : template <typename OutputType> 482 : const MooseArray<ADReal> & 483 0 : MooseVariableDataFV<OutputType>::adDofValuesDot() const 484 : { 485 0 : _need_ad = _need_ad_u_dot = true; 486 0 : return _ad_dofs_dot; 487 : } 488 : 489 : template <typename OutputType> 490 : inline bool 491 28875299 : MooseVariableDataFV<OutputType>::safeToComputeADUDot() const 492 : { 493 : // If we don't have a time integrator then we have no way to calculate _ad_u_dot because we rely 494 : // on calls to TimeIntegrator::computeADTimeDerivatives. Another potential situation where 495 : // _ad_u_dot computation is potentially troublesome is if we are an auxiliary variable which uses 496 : // the auxiliary system copy of the time integrator. Some derived time integrator classes do setup 497 : // in their solve() method, and that solve() method only happens for the nonlinear system copy of 498 : // the time integrator. 499 28875299 : return _time_integrator && (_var.kind() == Moose::VAR_SOLVER); 500 : } 501 : 502 : template <typename OutputType> 503 : inline const ADTemplateVariableValue<OutputType> & 504 380 : MooseVariableDataFV<OutputType>::adUDot() const 505 : { 506 380 : _need_ad = _need_ad_u_dot = true; 507 : 508 380 : if (!safeToComputeADUDot()) 509 : // We will just copy the value of _u_dot into _ad_u_dot 510 0 : _need_u_dot = true; 511 : 512 380 : return _ad_u_dot; 513 : } 514 : 515 : template <typename OutputType> 516 : const ADTemplateVariableValue<OutputType> & 517 13 : MooseVariableDataFV<OutputType>::adUDotDot() const 518 : { 519 : // Generally speaking, we need u dot information when computing u dot dot 520 13 : adUDot(); 521 : 522 13 : _need_ad = _need_ad_u_dotdot = true; 523 : 524 13 : if (!safeToComputeADUDot()) 525 : // We will just copy the value of _u_dotdot into _ad_u_dotdot 526 0 : _need_u_dotdot = true; 527 : 528 13 : return _ad_u_dotdot; 529 : } 530 : 531 : template <typename OutputType> 532 : const std::vector<dof_id_type> & 533 1224270588 : MooseVariableDataFV<OutputType>::dofIndices() const 534 : { 535 1224270588 : return const_cast<MooseVariableDataFV<OutputType> *>(this)->initDofIndices(); 536 : } 537 : 538 : template <typename OutputType> 539 : unsigned int 540 176144 : MooseVariableDataFV<OutputType>::numberOfDofs() const 541 : { 542 176144 : return dofIndices().size(); 543 : }