LCOV - code coverage report
Current view: top level - src/kokkos/systems - KokkosSystem.K (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 6f668f Lines: 305 306 99.7 %
Date: 2025-09-22 20:01:15 Functions: 14 14 100.0 %
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        1386 : System::System(SystemBase & system)
      26        1054 :   : MeshHolder(*system.mesh().getKokkosMesh()),
      27        1054 :     AssemblyHolder(system.feProblem().kokkosAssembly()),
      28        1054 :     _system(system),
      29        1054 :     _mesh(system.mesh()),
      30        1054 :     _dof_map(system.dofMap()),
      31        1054 :     _comm(system.dofMap().comm()),
      32        1054 :     _num_vars(system.system().n_vars()),
      33        1054 :     _num_local_dofs(system.system().n_local_dofs()),
      34        4216 :     _num_ghost_dofs(system.dofMap().get_send_list().size())
      35             : {
      36        1386 :   setupVariables();
      37        1386 :   setupDofs();
      38             : 
      39        1386 :   if (dynamic_cast<NonlinearSystemBase *>(&_system))
      40             :   {
      41         693 :     setupSparsity();
      42         693 :     checkNodalBCs();
      43             :   }
      44             : 
      45        1386 :   _qp_solutions.create(MAX_TAG);
      46        1386 :   _qp_solutions_grad.create(MAX_TAG);
      47        1386 : }
      48             : 
      49             : void
      50        1386 : System::setupVariables()
      51             : {
      52        1386 :   auto & sys = _system.system();
      53             : 
      54        1386 :   _var_fe_types.create(_num_vars);
      55        1386 :   _var_subdomain_active.create(_num_vars, _mesh.meshSubdomains().size());
      56             : 
      57        2568 :   for (unsigned int var = 0; var < _num_vars; ++var)
      58             :   {
      59        1182 :     _var_fe_types[var] = kokkosAssembly().getFETypeID(sys.variable_type(var));
      60             : 
      61        2426 :     for (auto subdomain : _mesh.meshSubdomains())
      62        1244 :       _var_subdomain_active(var, kokkosMesh().getContiguousSubdomainID(subdomain)) =
      63         940 :           sys.variable(var).active_on_subdomain(subdomain);
      64             :   }
      65             : 
      66        1386 :   _var_fe_types.copyToDevice();
      67        1386 :   _var_subdomain_active.copyToDevice();
      68             : 
      69             :   // Set coupling
      70             : 
      71        1386 :   auto nl_system = dynamic_cast<NonlinearSystemBase *>(&_system);
      72             : 
      73        1386 :   if (nl_system)
      74             :   {
      75         693 :     _coupling.create(_num_vars);
      76             : 
      77         693 :     std::map<unsigned int, std::vector<unsigned int>> coupling;
      78             : 
      79         693 :     auto & ce = _system.feProblem().couplingEntries(0, nl_system->number());
      80             : 
      81        1980 :     for (const auto & [ivar, jvar] : ce)
      82        1287 :       if (ivar->number() != jvar->number())
      83         378 :         coupling[ivar->number()].push_back(jvar->number());
      84             : 
      85        1602 :     for (unsigned int var = 0; var < _num_vars; ++var)
      86         909 :       _coupling[var] = coupling[var];
      87             : 
      88         693 :     _coupling.copyToDevice();
      89         693 :   }
      90        1386 : }
      91             : 
      92             : void
      93        1386 : System::setupDofs()
      94             : {
      95        1386 :   auto & sys = _system.system();
      96             : 
      97        1386 :   auto num_elems = kokkosMesh().getContiguousElementMap().size();
      98        1386 :   auto num_nodes = kokkosMesh().getContiguousNodeMap().size();
      99             : 
     100        1386 :   _residual_tag_active.create(MAX_TAG);
     101        1386 :   _residual_tag_active = false;
     102             : 
     103        1386 :   _matrix_tag_active.create(MAX_TAG);
     104        1386 :   _matrix_tag_active = false;
     105             : 
     106        1386 :   _vectors.create(MAX_TAG);
     107        1386 :   _matrices.create(MAX_TAG);
     108             : 
     109        1386 :   _local_elem_dof_index.create(_num_vars);
     110        1386 :   _local_node_dof_index.create(_num_vars);
     111        1386 :   _local_to_global_dof_index.create(_num_local_dofs + _num_ghost_dofs);
     112             : 
     113        1386 :   _max_dofs_per_elem.create(_num_vars);
     114        1386 :   _max_dofs_per_elem = 0;
     115             : 
     116        1386 :   auto solution = dynamic_cast<PetscVector<Number> *>(sys.current_local_solution.get());
     117             : 
     118        1386 :   std::vector<dof_id_type> dof_indices;
     119             : 
     120        2568 :   for (unsigned int var = 0; var < _num_vars; ++var)
     121             :   {
     122       57584 :     for (auto & [elem, id] : kokkosMesh().getContiguousElementMap())
     123             :     {
     124       56402 :       _dof_map.dof_indices(elem, dof_indices, var);
     125             : 
     126       96640 :       _max_dofs_per_elem[var] =
     127       40238 :           std::max(_max_dofs_per_elem[var], static_cast<unsigned int>(dof_indices.size()));
     128             :     }
     129             : 
     130        1182 :     _local_elem_dof_index[var].create(num_elems, _max_dofs_per_elem[var]);
     131        1182 :     _local_elem_dof_index[var] = libMesh::DofObject::invalid_id;
     132             : 
     133        1182 :     _local_node_dof_index[var].create(num_nodes);
     134        1182 :     _local_node_dof_index[var] = libMesh::DofObject::invalid_id;
     135             : 
     136       57584 :     for (auto & [elem, id] : kokkosMesh().getContiguousElementMap())
     137             :     {
     138       56402 :       _dof_map.dof_indices(elem, dof_indices, var);
     139             : 
     140      267440 :       for (unsigned int dof = 0; dof < dof_indices.size(); ++dof)
     141             :       {
     142      211038 :         _local_elem_dof_index[var](id, dof) = solution->map_global_to_local_index(dof_indices[dof]);
     143      211038 :         _local_to_global_dof_index[_local_elem_dof_index[var](id, dof)] = dof_indices[dof];
     144             :       }
     145             :     }
     146             : 
     147       71750 :     for (auto & [node, id] : kokkosMesh().getContiguousNodeMap())
     148       70568 :       if (node->processor_id() == _comm.rank())
     149             :       {
     150       69142 :         _dof_map.dof_indices(node, dof_indices, var);
     151             : 
     152       69142 :         if (dof_indices.size())
     153       67815 :           _local_node_dof_index[var][id] = solution->map_global_to_local_index(dof_indices[0]);
     154             :       }
     155             :   }
     156             : 
     157        1386 :   _local_elem_dof_index.copyToDeviceNested();
     158        1386 :   _local_node_dof_index.copyToDeviceNested();
     159        1386 :   _local_to_global_dof_index.copyToDevice();
     160             : 
     161        1386 :   _max_dofs_per_elem.copyToDevice();
     162             : 
     163             :   // Setup DOF communication maps
     164             : 
     165        1386 :   auto num_procs = _comm.size();
     166             : 
     167        2772 :   std::vector<std::vector<dof_id_type>> send_list(num_procs);
     168        1386 :   std::vector<std::vector<dof_id_type>> recv_list(num_procs);
     169             : 
     170        2805 :   for (auto dof : _dof_map.get_send_list())
     171        1419 :     recv_list[_dof_map.dof_owner(dof)].push_back(dof);
     172             : 
     173        3252 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     174        1866 :     _comm.scatter(recv_list, send_list[proc], proc);
     175             : 
     176        1386 :   _local_comm_list.create(num_procs);
     177        1386 :   _ghost_comm_list.create(num_procs);
     178             : 
     179        3252 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     180             :   {
     181        1866 :     _local_comm_list[proc].create(send_list[proc].size());
     182        1866 :     _ghost_comm_list[proc].create(recv_list[proc].size());
     183             : 
     184        3285 :     for (dof_id_type i = 0; i < send_list[proc].size(); ++i)
     185        1419 :       _local_comm_list[proc][i] = solution->map_global_to_local_index(send_list[proc][i]);
     186             : 
     187        3285 :     for (dof_id_type i = 0; i < recv_list[proc].size(); ++i)
     188        1419 :       _ghost_comm_list[proc][i] = solution->map_global_to_local_index(recv_list[proc][i]);
     189             :   }
     190             : 
     191        1386 :   _local_comm_list.copyToDeviceNested();
     192        1386 :   _ghost_comm_list.copyToDeviceNested();
     193        1386 : }
     194             : 
     195             : void
     196         693 : System::setupSparsity()
     197             : {
     198         693 :   auto pattern = _dof_map.get_sparsity_pattern();
     199             : 
     200         693 :   std::vector<PetscInt> col_idx;
     201         693 :   std::vector<PetscInt> row_idx;
     202        1386 :   std::vector<PetscInt> row_ptr = {0};
     203             : 
     204       54240 :   for (dof_id_type r = _dof_map.first_dof(); r < _dof_map.end_dof(); ++r)
     205             :   {
     206       53547 :     auto & cols = pattern->get_sparsity_pattern().at(r - _dof_map.first_dof());
     207             : 
     208      551150 :     for (auto col : cols)
     209             :     {
     210      497603 :       col_idx.push_back(col);
     211      497603 :       row_idx.push_back(r);
     212             :     }
     213             : 
     214       53547 :     row_ptr.push_back(col_idx.size());
     215             :   }
     216             : 
     217         693 :   auto num_procs = _comm.size();
     218             : 
     219        2772 :   std::vector<std::vector<PetscInt>> send_cols(num_procs), send_num_cols(num_procs);
     220        2079 :   std::vector<std::vector<PetscInt>> recv_cols(num_procs), recv_num_cols(num_procs);
     221             : 
     222        1626 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     223        2042 :     for (auto r : _local_comm_list[proc])
     224             :     {
     225       13657 :       for (PetscInt c = row_ptr[r]; c < row_ptr[r + 1]; ++c)
     226       12548 :         send_cols[proc].push_back(col_idx[c]);
     227             : 
     228        1109 :       send_num_cols[proc].push_back(row_ptr[r + 1] - row_ptr[r]);
     229             :     }
     230             : 
     231        1626 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     232             :   {
     233         933 :     _comm.scatter(send_cols, recv_cols[proc], proc);
     234         933 :     _comm.scatter(send_num_cols, recv_num_cols[proc], proc);
     235             :   }
     236             : 
     237        2079 :   std::vector<PetscInt> col(num_procs), row(num_procs);
     238             : 
     239        1802 :   for (auto r : _dof_map.get_send_list())
     240             :   {
     241        1109 :     auto proc = _dof_map.dof_owner(r);
     242        1109 :     auto n_cols = recv_num_cols[proc][row[proc]++];
     243             : 
     244       13657 :     for (PetscInt c = 0; c < n_cols; ++c)
     245             :     {
     246       12548 :       col_idx.push_back(recv_cols[proc][col[proc]++]);
     247       12548 :       row_idx.push_back(r);
     248             :     }
     249             : 
     250        1109 :     row_ptr.push_back(col_idx.size());
     251             :   }
     252             : 
     253         693 :   _sparsity.col_idx = col_idx;
     254         693 :   _sparsity.row_idx = row_idx;
     255         693 :   _sparsity.row_ptr = row_ptr;
     256         693 : }
     257             : 
     258             : void
     259         693 : System::checkNodalBCs()
     260             : {
     261         693 :   auto & nl_system = static_cast<NonlinearSystemBase &>(_system);
     262             : 
     263         693 :   _nbc_residual_tag_dof.create(MAX_TAG);
     264         693 :   _nbc_matrix_tag_dof.create(MAX_TAG);
     265             : 
     266        1894 :   for (auto bc : nl_system.getKokkosNodalBCWarehouse().getActiveObjects())
     267             :   {
     268        1201 :     auto nbc = static_cast<NodalBCBase *>(bc.get());
     269             : 
     270        1201 :     std::set<TagID> extra_vector_tags;
     271        1201 :     std::set<TagID> extra_matrix_tags;
     272             : 
     273        3603 :     if (nbc->isParamValid("extra_vector_tags"))
     274         384 :       for (auto tag : nbc->getParam<std::vector<TagName>>("extra_vector_tags"))
     275          96 :         extra_vector_tags.insert(_system.feProblem().getVectorTagID(tag));
     276             : 
     277        3603 :     if (nbc->isParamValid("extra_matrix_tags"))
     278         372 :       for (auto tag : nbc->getParam<std::vector<TagName>>("extra_matrix_tags"))
     279         120 :         extra_matrix_tags.insert(_system.feProblem().getMatrixTagID(tag));
     280             : 
     281        1201 :     getNodalBCDofs(nbc, _nbc_dof);
     282             : 
     283        1297 :     for (auto tag : extra_vector_tags)
     284          96 :       getNodalBCDofs(nbc, _nbc_residual_tag_dof[tag]);
     285             : 
     286        1321 :     for (auto tag : extra_matrix_tags)
     287         120 :       getNodalBCDofs(nbc, _nbc_matrix_tag_dof[tag]);
     288        1201 :   }
     289             : 
     290         693 :   _nbc_dof.copyToDevice();
     291         693 :   _nbc_residual_tag_dof.copyToDeviceNested();
     292         693 :   _nbc_matrix_tag_dof.copyToDeviceNested();
     293         693 : }
     294             : 
     295             : void
     296        1417 : System::getNodalBCDofs(const NodalBCBase * nbc, Array<bool> & dofs)
     297             : {
     298        1417 :   auto var = nbc->variable().number();
     299             : 
     300        1417 :   if (!dofs.isAlloc())
     301             :   {
     302         825 :     dofs.create(_num_local_dofs + _num_ghost_dofs);
     303         825 :     dofs = false;
     304             :   }
     305             : 
     306        9670 :   for (auto node : nbc->getContiguousNodes())
     307        9670 :     dofs[_local_node_dof_index[var][node]] = true;
     308             : 
     309             :   // Let remote processes know about ghost DOFs associated with nodal BCs not to compute
     310             :   // residual on them
     311             : 
     312        1417 :   auto num_procs = _comm.size();
     313             : 
     314        4251 :   std::vector<std::vector<char>> send(num_procs), recv(num_procs);
     315             : 
     316        3326 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     317        4214 :     for (auto dof : _local_comm_list[proc])
     318        2305 :       send[proc].push_back(dofs[dof]);
     319             : 
     320        3326 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     321        1909 :     _comm.scatter(send, recv[proc], proc);
     322             : 
     323        3326 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     324        4214 :     for (dof_id_type i = 0; i < _ghost_comm_list[proc].size(); ++i)
     325        2305 :       dofs[_ghost_comm_list[proc][i]] = recv[proc][i];
     326        1417 : }
     327             : 
     328             : void
     329      127148 : System::sync(const MemcpyKind dir)
     330             : {
     331      127148 :   if (dir == MemcpyKind::HOST_TO_DEVICE)
     332             :   {
     333      154045 :     for (auto tag : _active_variable_tags)
     334             :     {
     335       90471 :       auto & vector = _system.getVector(tag);
     336             : 
     337       90471 :       _vectors[tag].create(vector, *this, false);
     338       90471 :       _vectors[tag].copyToDevice();
     339             :     }
     340             : 
     341      145127 :     for (auto tag : _active_residual_tags)
     342             :     {
     343       81553 :       auto & vector = _system.getVector(tag);
     344             : 
     345       81553 :       _vectors[tag].create(vector, *this, true);
     346       81553 :       _vectors[tag] = 0;
     347             :     }
     348             : 
     349       68228 :     for (auto tag : _active_matrix_tags)
     350             :     {
     351        4654 :       auto & matrix = _system.getMatrix(tag);
     352             : 
     353        4654 :       _matrices[tag].create(matrix, *this);
     354        4654 :       _matrices[tag] = 0;
     355             :     }
     356             : 
     357       63574 :     _vectors.copyToDevice();
     358       63574 :     _matrices.copyToDevice();
     359             :   }
     360       63574 :   else if (dir == MemcpyKind::DEVICE_TO_HOST)
     361             :   {
     362      154045 :     for (auto tag : _active_variable_tags)
     363       90471 :       _vectors[tag].restore();
     364             : 
     365      145127 :     for (auto tag : _active_residual_tags)
     366       81553 :       _vectors[tag].close();
     367             : 
     368       68228 :     for (auto tag : _active_matrix_tags)
     369        4654 :       _matrices[tag].close();
     370             :   }
     371      127148 : }
     372             : 
     373             : void
     374        7556 : System::sync(const std::set<TagID> & tags, const MemcpyKind dir)
     375             : {
     376        7556 :   if (dir == MemcpyKind::HOST_TO_DEVICE)
     377             :   {
     378        7576 :     for (auto tag : tags)
     379             :     {
     380        3798 :       if (!_system.hasVector(tag))
     381        1889 :         continue;
     382             : 
     383        1909 :       auto & vector = _system.getVector(tag);
     384             : 
     385        1909 :       _vectors[tag].create(vector, *this, false);
     386        1909 :       _vectors[tag].copyToDevice();
     387             :     }
     388             : 
     389        3778 :     _vectors.copyToDevice();
     390             :   }
     391        3778 :   else if (dir == MemcpyKind::DEVICE_TO_HOST)
     392             :   {
     393        7576 :     for (auto tag : tags)
     394             :     {
     395        3798 :       if (!_system.hasVector(tag))
     396        1889 :         continue;
     397             : 
     398        1909 :       _vectors[tag].copyToHost();
     399        1909 :       _vectors[tag].restore();
     400             :     }
     401             :   }
     402        7556 : }
     403             : 
     404             : void
     405       63574 : System::setActiveVariables(const std::set<MooseVariableFieldBase *> & vars)
     406             : {
     407       63574 :   std::set<unsigned int> active_variables;
     408             : 
     409      137330 :   for (auto var : vars)
     410       73756 :     if (var->sys().number() == _system.number())
     411       73756 :       for (unsigned int i = 0; i < var->count(); ++i)
     412       36878 :         active_variables.insert(var->number() + i);
     413             : 
     414       63574 :   _active_variables = active_variables;
     415       63574 : }
     416             : 
     417             : void
     418       63574 : System::setActiveVariableTags(const std::set<TagID> & tags)
     419             : {
     420       63574 :   if (!_active_variables.size())
     421       30153 :     return;
     422             : 
     423       33421 :   std::set<TagID> active_variable_tags;
     424             : 
     425      186266 :   for (auto tag : tags)
     426      152845 :     if (_system.hasVector(tag))
     427       90471 :       active_variable_tags.insert(tag);
     428             : 
     429       33421 :   _active_variable_tags = active_variable_tags;
     430       33421 : }
     431             : 
     432             : void
     433       27177 : System::setActiveResidualTags(const std::set<TagID> & tags)
     434             : {
     435       27177 :   std::set<TagID> active_residual_tags;
     436             : 
     437      108730 :   for (auto tag : tags)
     438       81553 :     if (_system.hasVector(tag))
     439             :     {
     440       81553 :       active_residual_tags.insert(tag);
     441       81553 :       _residual_tag_active[tag] = true;
     442             :     }
     443             : 
     444       27177 :   _active_residual_tags = active_residual_tags;
     445             : 
     446       27177 :   _residual_tag_active.copyToDevice();
     447       27177 : }
     448             : 
     449             : void
     450        4410 : System::setActiveMatrixTags(const std::set<TagID> & tags)
     451             : {
     452        4410 :   std::set<TagID> active_matrix_tags;
     453             : 
     454       13250 :   for (auto tag : tags)
     455        8840 :     if (_system.hasMatrix(tag))
     456             :     {
     457        4654 :       active_matrix_tags.insert(tag);
     458        4654 :       _matrix_tag_active[tag] = true;
     459             :     }
     460             : 
     461        4410 :   _active_matrix_tags = active_matrix_tags;
     462             : 
     463        4410 :   _matrix_tag_active.copyToDevice();
     464        4410 : }
     465             : 
     466             : void
     467       63574 : System::reinit()
     468             : {
     469      154045 :   for (auto tag : _active_variable_tags)
     470             :   {
     471       90471 :     if (!_qp_solutions[tag].isAlloc())
     472        1415 :       _qp_solutions[tag].create(_mesh.meshSubdomains().size(), _num_vars);
     473             : 
     474       90471 :     if (!_qp_solutions_grad[tag].isAlloc())
     475        1415 :       _qp_solutions_grad[tag].create(_mesh.meshSubdomains().size(), _num_vars);
     476             : 
     477      185642 :     for (auto subdomain : _mesh.meshSubdomains())
     478             :     {
     479       95171 :       auto sid = kokkosMesh().getContiguousSubdomainID(subdomain);
     480             : 
     481      197795 :       for (auto var : _active_variables)
     482             :       {
     483      102624 :         if (!_var_subdomain_active(var, sid))
     484         204 :           continue;
     485             : 
     486      102420 :         if (!_qp_solutions[tag](sid, var).isAlloc())
     487        1641 :           _qp_solutions[tag](sid, var).createDevice(kokkosAssembly().getNumQps(sid));
     488             : 
     489      102420 :         if (!_qp_solutions_grad[tag](sid, var).isAlloc())
     490        1641 :           _qp_solutions_grad[tag](sid, var).createDevice(kokkosAssembly().getNumQps(sid));
     491             :       }
     492             :     }
     493             : 
     494       90471 :     _qp_solutions[tag].copyToDevice();
     495       90471 :     _qp_solutions_grad[tag].copyToDevice();
     496             :   }
     497             : 
     498       63574 :   _qp_solutions.copyToDevice();
     499       63574 :   _qp_solutions_grad.copyToDevice();
     500             : 
     501       63574 :   dof_id_type num_elems = kokkosMesh().getContiguousElementMap().size();
     502             : 
     503      178748 :   _thread.resize({kokkosAssembly().getMaxQpsPerElem(),
     504             :                   num_elems,
     505       51600 :                   _active_variables.size(),
     506       51600 :                   _active_variable_tags.size()});
     507             : 
     508       63574 :   ::Kokkos::RangePolicy<ExecSpace, ::Kokkos::IndexType<ThreadID>> policy(0, _thread.size());
     509       63574 :   ::Kokkos::parallel_for(policy, *this);
     510       63574 :   ::Kokkos::fence();
     511       63574 : }
     512             : 
     513             : KOKKOS_FUNCTION void
     514    18230688 : System::operator()(const ThreadID tid) const
     515             : {
     516    18230688 :   auto qp = _thread(tid, 0);
     517    18230688 :   auto elem = _thread(tid, 1);
     518    18230688 :   auto var = _active_variables(_thread(tid, 2));
     519    18230688 :   auto tag = _active_variable_tags(_thread(tid, 3));
     520             : 
     521    18230688 :   auto info = kokkosMesh().getElementInfo(elem);
     522    18230688 :   auto sid = info.subdomain;
     523    18230688 :   auto elem_type = info.type;
     524             : 
     525    18230688 :   if (!_var_subdomain_active(var, sid))
     526        1936 :     return;
     527             : 
     528    18228752 :   auto fe_type = _var_fe_types[var];
     529    18228752 :   auto num_dofs = kokkosAssembly().getNumDofs(elem_type, fe_type);
     530    18228752 :   auto num_qps = kokkosAssembly().getNumQps(info);
     531    18228752 :   auto qp_offset = kokkosAssembly().getQpOffset(info);
     532             : 
     533    18228752 :   if (qp >= num_qps)
     534           0 :     return;
     535             : 
     536    18228752 :   auto & phi = kokkosAssembly().getPhi(sid, elem_type, fe_type);
     537    18228752 :   auto & grad_phi = kokkosAssembly().getGradPhi(sid, elem_type, fe_type);
     538    18228752 :   auto jacobian = kokkosAssembly().getJacobian(info, qp);
     539             : 
     540    18228752 :   Real value = 0;
     541    18228752 :   Real3 grad = 0;
     542             : 
     543    96004640 :   for (unsigned int i = 0; i < num_dofs; ++i)
     544             :   {
     545    77775888 :     auto vector = getVectorDofValue(getElemLocalDofIndex(elem, i, var), tag);
     546             : 
     547    77775888 :     value += vector * phi(i, qp);
     548    77775888 :     grad += vector * (jacobian * grad_phi(i, qp));
     549             :   }
     550             : 
     551    18228752 :   getVectorQpValue(info, qp_offset + qp, var, tag) = value;
     552    18228752 :   getVectorQpGrad(info, qp_offset + qp, var, tag) = grad;
     553             : }
     554             : 
     555             : } // namespace Kokkos
     556             : } // namespace Moose

Generated by: LCOV version 1.14