LCOV - code coverage report
Current view: top level - src/kokkos/systems - KokkosSystem.K (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #31730 (e8b711) with base e0c998 Lines: 309 315 98.1 %
Date: 2025-10-29 16:49:47 Functions: 15 16 93.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://www.mooseframework.org
       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             : #include "KokkosSystem.h"
      11             : #include "KokkosNodalBCBase.h"
      12             : 
      13             : #include "MooseMesh.h"
      14             : #include "Assembly.h"
      15             : #include "NonlinearSystemBase.h"
      16             : #include "FEProblemBase.h"
      17             : 
      18             : #include "libmesh/system.h"
      19             : 
      20             : namespace Moose
      21             : {
      22             : namespace Kokkos
      23             : {
      24             : 
      25        1482 : System::System(SystemBase & system)
      26        1126 :   : MeshHolder(*system.mesh().getKokkosMesh()),
      27        1126 :     AssemblyHolder(system.feProblem().kokkosAssembly()),
      28        1126 :     _system(system),
      29        1126 :     _mesh(system.mesh()),
      30        1126 :     _dof_map(system.dofMap()),
      31        1126 :     _comm(system.dofMap().comm()),
      32        1126 :     _num_vars(system.system().n_vars()),
      33        1126 :     _num_local_dofs(system.system().n_local_dofs()),
      34        4504 :     _num_ghost_dofs(system.dofMap().get_send_list().size())
      35             : {
      36        1482 :   setupVariables();
      37        1482 :   setupDofs();
      38             : 
      39        1482 :   if (dynamic_cast<NonlinearSystemBase *>(&_system))
      40             :   {
      41         741 :     setupSparsity();
      42         741 :     checkNodalBCs();
      43             :   }
      44             : 
      45        1482 :   _qp_solutions.create(MAX_TAG);
      46        1482 :   _qp_solutions_grad.create(MAX_TAG);
      47        1482 : }
      48             : 
      49             : void
      50        1482 : System::setupVariables()
      51             : {
      52        1482 :   auto & sys = _system.system();
      53             : 
      54        1482 :   _var_fe_types.create(_num_vars);
      55        1482 :   _var_subdomain_active.create(_num_vars, _mesh.meshSubdomains().size());
      56             : 
      57        2906 :   for (unsigned int var = 0; var < _num_vars; ++var)
      58             :   {
      59        1424 :     _var_fe_types[var] = kokkosAssembly().getFETypeID(sys.variable_type(var));
      60             : 
      61        2910 :     for (auto subdomain : _mesh.meshSubdomains())
      62        1486 :       _var_subdomain_active(var, kokkosMesh().getContiguousSubdomainID(subdomain)) =
      63        1124 :           sys.variable(var).active_on_subdomain(subdomain);
      64             :   }
      65             : 
      66        1482 :   _var_fe_types.copyToDevice();
      67        1482 :   _var_subdomain_active.copyToDevice();
      68             : 
      69             :   // Set coupling
      70             : 
      71        1482 :   auto nl_system = dynamic_cast<NonlinearSystemBase *>(&_system);
      72             : 
      73        1482 :   if (nl_system)
      74             :   {
      75         741 :     _coupling.create(_num_vars);
      76             : 
      77         741 :     std::map<unsigned int, std::vector<unsigned int>> coupling;
      78             : 
      79         741 :     auto & ce = _system.feProblem().couplingEntries(0, nl_system->number());
      80             : 
      81        2076 :     for (const auto & [ivar, jvar] : ce)
      82        1335 :       if (ivar->number() != jvar->number())
      83         378 :         coupling[ivar->number()].push_back(jvar->number());
      84             : 
      85        1698 :     for (unsigned int var = 0; var < _num_vars; ++var)
      86         957 :       _coupling[var] = coupling[var];
      87             : 
      88         741 :     _coupling.copyToDevice();
      89         741 :   }
      90        1482 : }
      91             : 
      92             : void
      93        1482 : System::setupDofs()
      94             : {
      95        1482 :   auto & sys = _system.system();
      96             : 
      97        1482 :   auto num_elems = kokkosMesh().getContiguousElementMap().size();
      98        1482 :   auto num_nodes = kokkosMesh().getContiguousNodeMap().size();
      99             : 
     100        1482 :   _residual_tag_active.create(MAX_TAG);
     101        1482 :   _residual_tag_active = false;
     102             : 
     103        1482 :   _matrix_tag_active.create(MAX_TAG);
     104        1482 :   _matrix_tag_active = false;
     105             : 
     106        1482 :   _vectors.create(MAX_TAG);
     107        1482 :   _matrices.create(MAX_TAG);
     108             : 
     109        1482 :   _local_elem_dof_index.create(_num_vars);
     110        1482 :   _local_node_dof_index.create(_num_vars);
     111        1482 :   _local_to_global_dof_index.create(_num_local_dofs + _num_ghost_dofs);
     112             : 
     113        1482 :   _max_dofs_per_elem.create(_num_vars);
     114        1482 :   _max_dofs_per_elem = 0;
     115             : 
     116        1482 :   auto solution = dynamic_cast<PetscVector<Number> *>(sys.current_local_solution.get());
     117             : 
     118        1482 :   std::vector<dof_id_type> dof_indices;
     119             : 
     120        2906 :   for (unsigned int var = 0; var < _num_vars; ++var)
     121             :   {
     122       73976 :     for (auto & [elem, id] : kokkosMesh().getContiguousElementMap())
     123             :     {
     124       72552 :       _dof_map.dof_indices(elem, dof_indices, var);
     125             : 
     126      124355 :       _max_dofs_per_elem[var] =
     127       51803 :           std::max(_max_dofs_per_elem[var], static_cast<unsigned int>(dof_indices.size()));
     128             :     }
     129             : 
     130        1424 :     _local_elem_dof_index[var].create(num_elems, _max_dofs_per_elem[var]);
     131        1424 :     _local_elem_dof_index[var] = libMesh::DofObject::invalid_id;
     132             : 
     133        1424 :     _local_node_dof_index[var].create(num_nodes);
     134        1424 :     _local_node_dof_index[var] = libMesh::DofObject::invalid_id;
     135             : 
     136       73976 :     for (auto & [elem, id] : kokkosMesh().getContiguousElementMap())
     137             :     {
     138       72552 :       _dof_map.dof_indices(elem, dof_indices, var);
     139             : 
     140      349830 :       for (unsigned int dof = 0; dof < dof_indices.size(); ++dof)
     141             :       {
     142      277278 :         _local_elem_dof_index[var](id, dof) = solution->map_global_to_local_index(dof_indices[dof]);
     143      277278 :         _local_to_global_dof_index[_local_elem_dof_index[var](id, dof)] = dof_indices[dof];
     144             :       }
     145             :     }
     146             : 
     147      106418 :     for (auto & [node, id] : kokkosMesh().getContiguousNodeMap())
     148      104994 :       if (node->processor_id() == _comm.rank())
     149             :       {
     150      102994 :         _dof_map.dof_indices(node, dof_indices, var);
     151             : 
     152      102994 :         if (dof_indices.size())
     153             :         {
     154       80815 :           for (unsigned int i = 1; i < dof_indices.size(); ++i)
     155           0 :             if (dof_indices[i] != dof_indices[i - 1] + 1)
     156           0 :               mooseError("Kokkos system error: a variable has multiple DOFs on a node, but the DOF "
     157             :                          "indices are discontiguous. This is not supported.");
     158             : 
     159       80815 :           _local_node_dof_index[var][id] = solution->map_global_to_local_index(dof_indices[0]);
     160             :         }
     161             :       }
     162             :   }
     163             : 
     164        1482 :   _local_elem_dof_index.copyToDeviceNested();
     165        1482 :   _local_node_dof_index.copyToDeviceNested();
     166        1482 :   _local_to_global_dof_index.copyToDevice();
     167             : 
     168        1482 :   _max_dofs_per_elem.copyToDevice();
     169             : 
     170             :   // Setup DOF communication maps
     171             : 
     172        1482 :   auto num_procs = _comm.size();
     173             : 
     174        2964 :   std::vector<std::vector<dof_id_type>> send_list(num_procs);
     175        1482 :   std::vector<std::vector<dof_id_type>> recv_list(num_procs);
     176             : 
     177        3115 :   for (auto dof : _dof_map.get_send_list())
     178        1633 :     recv_list[_dof_map.dof_owner(dof)].push_back(dof);
     179             : 
     180        3476 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     181        1994 :     _comm.scatter(recv_list, send_list[proc], proc);
     182             : 
     183        1482 :   _local_comm_list.create(num_procs);
     184        1482 :   _ghost_comm_list.create(num_procs);
     185             : 
     186        3476 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     187             :   {
     188        1994 :     _local_comm_list[proc].create(send_list[proc].size());
     189        1994 :     _ghost_comm_list[proc].create(recv_list[proc].size());
     190             : 
     191        3627 :     for (dof_id_type i = 0; i < send_list[proc].size(); ++i)
     192        1633 :       _local_comm_list[proc][i] = solution->map_global_to_local_index(send_list[proc][i]);
     193             : 
     194        3627 :     for (dof_id_type i = 0; i < recv_list[proc].size(); ++i)
     195        1633 :       _ghost_comm_list[proc][i] = solution->map_global_to_local_index(recv_list[proc][i]);
     196             :   }
     197             : 
     198        1482 :   _local_comm_list.copyToDeviceNested();
     199        1482 :   _ghost_comm_list.copyToDeviceNested();
     200        1482 : }
     201             : 
     202             : void
     203         741 : System::setupSparsity()
     204             : {
     205         741 :   auto pattern = _dof_map.get_sparsity_pattern();
     206             : 
     207         741 :   std::vector<PetscInt> col_idx;
     208         741 :   std::vector<PetscInt> row_idx;
     209        1482 :   std::vector<PetscInt> row_ptr = {0};
     210             : 
     211       61158 :   for (dof_id_type r = _dof_map.first_dof(); r < _dof_map.end_dof(); ++r)
     212             :   {
     213       60417 :     auto & cols = pattern->get_sparsity_pattern().at(r - _dof_map.first_dof());
     214             : 
     215      643010 :     for (auto col : cols)
     216             :     {
     217      582593 :       col_idx.push_back(col);
     218      582593 :       row_idx.push_back(r);
     219             :     }
     220             : 
     221       60417 :     row_ptr.push_back(col_idx.size());
     222             :   }
     223             : 
     224         741 :   auto num_procs = _comm.size();
     225             : 
     226        2964 :   std::vector<std::vector<PetscInt>> send_cols(num_procs), send_num_cols(num_procs);
     227        2223 :   std::vector<std::vector<PetscInt>> recv_cols(num_procs), recv_num_cols(num_procs);
     228             : 
     229        1738 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     230        2200 :     for (auto r : _local_comm_list[proc])
     231             :     {
     232       15049 :       for (PetscInt c = row_ptr[r]; c < row_ptr[r + 1]; ++c)
     233       13846 :         send_cols[proc].push_back(col_idx[c]);
     234             : 
     235        1203 :       send_num_cols[proc].push_back(row_ptr[r + 1] - row_ptr[r]);
     236             :     }
     237             : 
     238        1738 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     239             :   {
     240         997 :     _comm.scatter(send_cols, recv_cols[proc], proc);
     241         997 :     _comm.scatter(send_num_cols, recv_num_cols[proc], proc);
     242             :   }
     243             : 
     244        2223 :   std::vector<PetscInt> col(num_procs), row(num_procs);
     245             : 
     246        1944 :   for (auto r : _dof_map.get_send_list())
     247             :   {
     248        1203 :     auto proc = _dof_map.dof_owner(r);
     249        1203 :     auto n_cols = recv_num_cols[proc][row[proc]++];
     250             : 
     251       15049 :     for (PetscInt c = 0; c < n_cols; ++c)
     252             :     {
     253       13846 :       col_idx.push_back(recv_cols[proc][col[proc]++]);
     254       13846 :       row_idx.push_back(r);
     255             :     }
     256             : 
     257        1203 :     row_ptr.push_back(col_idx.size());
     258             :   }
     259             : 
     260         741 :   _sparsity.col_idx = col_idx;
     261         741 :   _sparsity.row_idx = row_idx;
     262         741 :   _sparsity.row_ptr = row_ptr;
     263         741 : }
     264             : 
     265             : void
     266         741 : System::checkNodalBCs()
     267             : {
     268         741 :   auto & nl_system = static_cast<NonlinearSystemBase &>(_system);
     269             : 
     270         741 :   _nbc_residual_tag_dof.create(MAX_TAG);
     271         741 :   _nbc_matrix_tag_dof.create(MAX_TAG);
     272             : 
     273        1966 :   for (auto bc : nl_system.getKokkosNodalBCWarehouse().getActiveObjects())
     274             :   {
     275        1225 :     auto nbc = static_cast<NodalBCBase *>(bc.get());
     276             : 
     277        1225 :     std::set<TagID> extra_vector_tags;
     278        1225 :     std::set<TagID> extra_matrix_tags;
     279             : 
     280        3675 :     if (nbc->isParamValid("extra_vector_tags"))
     281         384 :       for (auto tag : nbc->getParam<std::vector<TagName>>("extra_vector_tags"))
     282          96 :         extra_vector_tags.insert(_system.feProblem().getVectorTagID(tag));
     283             : 
     284        3675 :     if (nbc->isParamValid("extra_matrix_tags"))
     285         372 :       for (auto tag : nbc->getParam<std::vector<TagName>>("extra_matrix_tags"))
     286         120 :         extra_matrix_tags.insert(_system.feProblem().getMatrixTagID(tag));
     287             : 
     288        1225 :     getNodalBCDofs(nbc, _nbc_dof);
     289             : 
     290        1321 :     for (auto tag : extra_vector_tags)
     291          96 :       getNodalBCDofs(nbc, _nbc_residual_tag_dof[tag]);
     292             : 
     293        1345 :     for (auto tag : extra_matrix_tags)
     294         120 :       getNodalBCDofs(nbc, _nbc_matrix_tag_dof[tag]);
     295        1225 :   }
     296             : 
     297         741 :   _nbc_dof.copyToDevice();
     298         741 :   _nbc_residual_tag_dof.copyToDeviceNested();
     299         741 :   _nbc_matrix_tag_dof.copyToDeviceNested();
     300         741 : }
     301             : 
     302             : void
     303        1441 : System::getNodalBCDofs(const NodalBCBase * nbc, Array<bool> & dofs)
     304             : {
     305        1441 :   auto var = nbc->variable().number();
     306             : 
     307        1441 :   if (!dofs.isAlloc())
     308             :   {
     309         837 :     dofs.create(_num_local_dofs + _num_ghost_dofs);
     310         837 :     dofs = false;
     311             :   }
     312             : 
     313        9914 :   for (auto node : nbc->getContiguousNodes())
     314        9914 :     dofs[_local_node_dof_index[var][node]] = true;
     315             : 
     316             :   // Let remote processes know about ghost DOFs associated with nodal BCs not to compute
     317             :   // residual on them
     318             : 
     319        1441 :   auto num_procs = _comm.size();
     320             : 
     321        4323 :   std::vector<std::vector<char>> send(num_procs), recv(num_procs);
     322             : 
     323        3382 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     324        4294 :     for (auto dof : _local_comm_list[proc])
     325        2353 :       send[proc].push_back(dofs[dof]);
     326             : 
     327        3382 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     328        1941 :     _comm.scatter(send, recv[proc], proc);
     329             : 
     330        3382 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     331        4294 :     for (dof_id_type i = 0; i < _ghost_comm_list[proc].size(); ++i)
     332        2353 :       dofs[_ghost_comm_list[proc][i]] = recv[proc][i];
     333        1441 : }
     334             : 
     335             : void
     336      154788 : System::sync(const MemcpyKind dir)
     337             : {
     338      154788 :   if (dir == MemcpyKind::HOST_TO_DEVICE)
     339             :   {
     340      194202 :     for (auto tag : _active_solution_tags)
     341             :     {
     342      116808 :       auto & vector = _system.getVector(tag);
     343             : 
     344      116808 :       _vectors[tag].create(vector, *this, false);
     345      116808 :       _vectors[tag].copyToDevice();
     346             :     }
     347             : 
     348      157702 :     for (auto tag : _active_residual_tags)
     349             :     {
     350       80308 :       auto & vector = _system.getVector(tag);
     351             : 
     352       80308 :       _vectors[tag].create(vector, *this, true);
     353       80308 :       _vectors[tag] = 0;
     354             :     }
     355             : 
     356       82073 :     for (auto tag : _active_matrix_tags)
     357             :     {
     358        4679 :       auto & matrix = _system.getMatrix(tag);
     359             : 
     360        4679 :       _matrices[tag].create(matrix, *this);
     361        4679 :       _matrices[tag] = 0;
     362             :     }
     363             : 
     364       77394 :     _vectors.copyToDevice();
     365       77394 :     _matrices.copyToDevice();
     366             :   }
     367       77394 :   else if (dir == MemcpyKind::DEVICE_TO_HOST)
     368             :   {
     369      194202 :     for (auto tag : _active_solution_tags)
     370      116808 :       _vectors[tag].restore();
     371             : 
     372      157702 :     for (auto tag : _active_residual_tags)
     373       80308 :       _vectors[tag].close();
     374             : 
     375       82073 :     for (auto tag : _active_matrix_tags)
     376        4679 :       _matrices[tag].close();
     377             :   }
     378      154788 : }
     379             : 
     380             : void
     381       21944 : System::sync(const std::set<TagID> & tags, const MemcpyKind dir)
     382             : {
     383       21944 :   if (dir == MemcpyKind::HOST_TO_DEVICE)
     384             :   {
     385       21964 :     for (auto tag : tags)
     386             :     {
     387       10992 :       if (!_system.hasVector(tag))
     388        1889 :         continue;
     389             : 
     390        9103 :       auto & vector = _system.getVector(tag);
     391             : 
     392        9103 :       _vectors[tag].create(vector, *this, false);
     393        9103 :       _vectors[tag].copyToDevice();
     394             :     }
     395             : 
     396       10972 :     _vectors.copyToDevice();
     397             :   }
     398       10972 :   else if (dir == MemcpyKind::DEVICE_TO_HOST)
     399             :   {
     400       21964 :     for (auto tag : tags)
     401             :     {
     402       10992 :       if (!_system.hasVector(tag))
     403        1889 :         continue;
     404             : 
     405        9103 :       _vectors[tag].copyToHost();
     406        9103 :       _vectors[tag].restore();
     407             :     }
     408             :   }
     409       21944 : }
     410             : 
     411             : void
     412           0 : System::sync(const std::vector<TagID> & tags, const MemcpyKind dir)
     413             : {
     414           0 :   sync(std::set<TagID>(tags.begin(), tags.end()), dir);
     415           0 : }
     416             : 
     417             : void
     418       14388 : System::sync(const TagID tag, const MemcpyKind dir)
     419             : {
     420       28776 :   sync(std::set<TagID>{tag}, dir);
     421       14388 : }
     422             : 
     423             : void
     424       77394 : System::setActiveVariables(const std::set<MooseVariableFieldBase *> & vars)
     425             : {
     426       77394 :   std::set<unsigned int> active_variables;
     427             : 
     428      180740 :   for (auto var : vars)
     429      103346 :     if (var->sys().number() == _system.number())
     430      103346 :       for (unsigned int i = 0; i < var->count(); ++i)
     431       51673 :         active_variables.insert(var->number() + i);
     432             : 
     433       77394 :   _active_variables = active_variables;
     434       77394 : }
     435             : 
     436             : void
     437       77394 : System::setActiveSolutionTags(const std::set<TagID> & tags)
     438             : {
     439       77394 :   if (!_active_variables.size())
     440       34489 :     return;
     441             : 
     442       42905 :   std::set<TagID> active_solution_tags;
     443             : 
     444      237772 :   for (auto tag : tags)
     445      194867 :     if (_system.hasVector(tag))
     446      116808 :       active_solution_tags.insert(tag);
     447             : 
     448       42905 :   _active_solution_tags = active_solution_tags;
     449       42905 : }
     450             : 
     451             : void
     452       26756 : System::setActiveResidualTags(const std::set<TagID> & tags)
     453             : {
     454       26756 :   std::set<TagID> active_residual_tags;
     455             : 
     456      107064 :   for (auto tag : tags)
     457       80308 :     if (_system.hasVector(tag))
     458             :     {
     459       80308 :       active_residual_tags.insert(tag);
     460       80308 :       _residual_tag_active[tag] = true;
     461             :     }
     462             : 
     463       26756 :   _active_residual_tags = active_residual_tags;
     464             : 
     465       26756 :   _residual_tag_active.copyToDevice();
     466       26756 : }
     467             : 
     468             : void
     469        4437 : System::setActiveMatrixTags(const std::set<TagID> & tags)
     470             : {
     471        4437 :   std::set<TagID> active_matrix_tags;
     472             : 
     473       13300 :   for (auto tag : tags)
     474        8863 :     if (_system.hasMatrix(tag))
     475             :     {
     476        4679 :       active_matrix_tags.insert(tag);
     477        4679 :       _matrix_tag_active[tag] = true;
     478             :     }
     479             : 
     480        4437 :   _active_matrix_tags = active_matrix_tags;
     481             : 
     482        4437 :   _matrix_tag_active.copyToDevice();
     483        4437 : }
     484             : 
     485             : void
     486       77394 : System::reinit()
     487             : {
     488      194202 :   for (auto tag : _active_solution_tags)
     489             :   {
     490      116808 :     if (!_qp_solutions[tag].isAlloc())
     491        1831 :       _qp_solutions[tag].create(_mesh.meshSubdomains().size(), _num_vars);
     492             : 
     493      116808 :     if (!_qp_solutions_grad[tag].isAlloc())
     494        1831 :       _qp_solutions_grad[tag].create(_mesh.meshSubdomains().size(), _num_vars);
     495             : 
     496      238312 :     for (auto subdomain : _mesh.meshSubdomains())
     497             :     {
     498      121504 :       auto sid = kokkosMesh().getContiguousSubdomainID(subdomain);
     499             : 
     500      266265 :       for (auto var : _active_variables)
     501             :       {
     502      144761 :         if (!_var_subdomain_active(var, sid))
     503         204 :           continue;
     504             : 
     505      144557 :         if (!_qp_solutions[tag](sid, var).isAlloc())
     506        2197 :           _qp_solutions[tag](sid, var).createDevice(kokkosAssembly().getNumQps(sid));
     507             : 
     508      144557 :         if (!_qp_solutions_grad[tag](sid, var).isAlloc())
     509        2197 :           _qp_solutions_grad[tag](sid, var).createDevice(kokkosAssembly().getNumQps(sid));
     510             :       }
     511             :     }
     512             : 
     513      116808 :     _qp_solutions[tag].copyToDevice();
     514      116808 :     _qp_solutions_grad[tag].copyToDevice();
     515             :   }
     516             : 
     517       77394 :   _qp_solutions.copyToDevice();
     518       77394 :   _qp_solutions_grad.copyToDevice();
     519             : 
     520       77394 :   dof_id_type num_elems = kokkosMesh().getContiguousElementMap().size();
     521             : 
     522      218380 :   _thread.resize({kokkosAssembly().getMaxQpsPerElem(),
     523             :                   num_elems,
     524       63592 :                   _active_variables.size(),
     525       63592 :                   _active_solution_tags.size()});
     526             : 
     527       77394 :   ::Kokkos::RangePolicy<ExecSpace, ::Kokkos::IndexType<ThreadID>> policy(0, _thread.size());
     528       77394 :   ::Kokkos::parallel_for(policy, *this);
     529       77394 :   ::Kokkos::fence();
     530       77394 : }
     531             : 
     532             : KOKKOS_FUNCTION void
     533    42835772 : System::operator()(const ThreadID tid) const
     534             : {
     535    42835772 :   auto qp = _thread(tid, 0);
     536    42835772 :   auto elem = _thread(tid, 1);
     537    42835772 :   auto var = _active_variables(_thread(tid, 2));
     538    42835772 :   auto tag = _active_solution_tags(_thread(tid, 3));
     539             : 
     540    42835772 :   auto info = kokkosMesh().getElementInfo(elem);
     541    42835772 :   auto sid = info.subdomain;
     542    42835772 :   auto elem_type = info.type;
     543             : 
     544    42835772 :   if (!_var_subdomain_active(var, sid))
     545        1936 :     return;
     546             : 
     547    42833836 :   auto fe_type = _var_fe_types[var];
     548    42833836 :   auto num_dofs = kokkosAssembly().getNumDofs(elem_type, fe_type);
     549    42833836 :   auto num_qps = kokkosAssembly().getNumQps(info);
     550    42833836 :   auto qp_offset = kokkosAssembly().getQpOffset(info);
     551             : 
     552    42833836 :   if (qp >= num_qps)
     553           0 :     return;
     554             : 
     555    42833836 :   auto & phi = kokkosAssembly().getPhi(sid, elem_type, fe_type);
     556    42833836 :   auto & grad_phi = kokkosAssembly().getGradPhi(sid, elem_type, fe_type);
     557    42833836 :   auto jacobian = kokkosAssembly().getJacobian(info, qp);
     558             : 
     559    42833836 :   Real value = 0;
     560    42833836 :   Real3 grad = 0;
     561             : 
     562   248688012 :   for (unsigned int i = 0; i < num_dofs; ++i)
     563             :   {
     564   205854176 :     auto vector = getVectorDofValue(getElemLocalDofIndex(elem, i, var), tag);
     565             : 
     566   205854176 :     value += vector * phi(i, qp);
     567   205854176 :     grad += vector * (jacobian * grad_phi(i, qp));
     568             :   }
     569             : 
     570    42833836 :   getVectorQpValue(info, qp_offset + qp, var, tag) = value;
     571    42833836 :   getVectorQpGrad(info, qp_offset + qp, var, tag) = grad;
     572             : }
     573             : 
     574             : } // namespace Kokkos
     575             : } // namespace Moose

Generated by: LCOV version 1.14