LCOV - code coverage report
Current view: top level - src/kokkos/systems - KokkosSystem.K (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 304 311 97.7 %
Date: 2026-05-29 20:35:17 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::Kokkos
      21             : {
      22             : 
      23        8666 : System::System(SystemBase & system)
      24        2462 :   : PerfGraphInterface(system.feProblem().getMooseApp().perfGraph(), "KokkosSystem"),
      25        2462 :     MeshHolder(*system.mesh().getKokkosMesh()),
      26        2462 :     AssemblyHolder(system.feProblem().kokkosAssembly()),
      27        2462 :     _system(system),
      28        2462 :     _mesh(system.mesh()),
      29        2462 :     _dof_map(system.dofMap()),
      30        2462 :     _comm(system.dofMap().comm()),
      31        2462 :     _num_vars(system.system().n_vars()),
      32        2462 :     _num_local_dofs(system.system().n_local_dofs()),
      33       17234 :     _num_ghost_dofs(system.dofMap().get_send_list().size())
      34             : {
      35        4530 :   setupVariables();
      36        4530 :   setupDofs();
      37             : 
      38        4530 :   if (dynamic_cast<NonlinearSystemBase *>(&_system))
      39             :   {
      40        2265 :     setupSparsity();
      41        2265 :     setupNodalBCDofs();
      42             :   }
      43             : 
      44        4530 :   _qp_solutions.create(MAX_TAG);
      45        4530 :   _qp_solutions_grad.create(MAX_TAG);
      46        4530 : }
      47             : 
      48             : void
      49        4530 : System::setupVariables()
      50             : {
      51        4530 :   auto & sys = _system.system();
      52             : 
      53        4530 :   _var_fe_types.create(_num_vars);
      54        4530 :   _var_subdomain_active.create(_num_vars, kokkosMesh().getNumSubdomains());
      55             : 
      56        8482 :   for (unsigned int var = 0; var < _num_vars; ++var)
      57             :   {
      58        3952 :     _var_fe_types[var] = kokkosAssembly().getFETypeID(sys.variable_type(var));
      59             : 
      60        8941 :     for (auto subdomain : _mesh.meshSubdomains())
      61        4989 :       _var_subdomain_active(var, kokkosMesh().getContiguousSubdomainID(subdomain)) =
      62        2707 :           sys.variable(var).active_on_subdomain(subdomain);
      63             :   }
      64             : 
      65        4530 :   _var_fe_types.copyToDevice();
      66        4530 :   _var_subdomain_active.copyToDevice();
      67             : 
      68             :   // Set coupling
      69             : 
      70        4530 :   auto nl_system = dynamic_cast<NonlinearSystemBase *>(&_system);
      71             : 
      72        4530 :   if (nl_system)
      73             :   {
      74        2265 :     _coupling.create(_num_vars);
      75             : 
      76        2265 :     std::map<unsigned int, std::vector<unsigned int>> coupling;
      77             : 
      78        2265 :     auto & ce = _system.feProblem().couplingEntries(0, nl_system->number());
      79             : 
      80        5479 :     for (const auto & [ivar, jvar] : ce)
      81        3214 :       if (ivar->number() != jvar->number())
      82         718 :         coupling[ivar->number()].push_back(jvar->number());
      83             : 
      84        4761 :     for (unsigned int var = 0; var < _num_vars; ++var)
      85        2496 :       _coupling[var] = coupling[var];
      86             : 
      87        2265 :     _coupling.copyToDevice();
      88        2265 :   }
      89        4530 : }
      90             : 
      91             : void
      92        4530 : System::setupDofs()
      93             : {
      94        4530 :   auto & sys = _system.system();
      95             : 
      96        4530 :   auto num_elems = kokkosMesh().getNumLocalElements();
      97        4530 :   auto num_nodes = kokkosMesh().getNumLocalNodes();
      98             : 
      99        4530 :   _residual_tag_active.create(MAX_TAG);
     100        4530 :   _residual_tag_active = false;
     101             : 
     102        4530 :   _matrix_tag_active.create(MAX_TAG);
     103        4530 :   _matrix_tag_active = false;
     104             : 
     105        4530 :   _vectors.create(MAX_TAG);
     106        4530 :   _matrices.create(MAX_TAG);
     107             : 
     108        4530 :   _local_elem_dof_index.create(_num_vars);
     109        4530 :   _local_node_dof_index.create(_num_vars);
     110        4530 :   _local_to_global_dof_index.create(_num_local_dofs + _num_ghost_dofs);
     111             : 
     112        4530 :   _max_dofs_per_elem.create(_num_vars);
     113        4530 :   _max_dofs_per_elem = 0;
     114             : 
     115        4530 :   auto solution = dynamic_cast<PetscVector<Number> *>(sys.current_local_solution.get());
     116             : 
     117             : #ifdef MOOSE_ENABLE_KOKKOS_GPU
     118             :   // Kokkos array thinks OpenMP clause is device code when using OpenMP backend
     119        2068 : #pragma omp parallel for
     120             : #endif
     121        4604 :   for (unsigned int var = 0; var < _num_vars; ++var)
     122             :   {
     123        2142 :     std::vector<dof_id_type> dof_indices;
     124             : 
     125      802810 :     for (const auto elem : _mesh.getMesh().active_local_element_ptr_range())
     126             :     {
     127      800668 :       _dof_map.dof_indices(elem, dof_indices, var);
     128             : 
     129     1601336 :       _max_dofs_per_elem[var] =
     130      800668 :           std::max(_max_dofs_per_elem[var], static_cast<unsigned int>(dof_indices.size()));
     131        2142 :     }
     132             : 
     133        2142 :     _local_elem_dof_index[var].create(num_elems, _max_dofs_per_elem[var]);
     134        2142 :     _local_elem_dof_index[var] = libMesh::DofObject::invalid_id;
     135             : 
     136        2142 :     _local_node_dof_index[var].create(num_nodes);
     137        2142 :     _local_node_dof_index[var] = libMesh::DofObject::invalid_id;
     138             : 
     139      802810 :     for (const auto elem : _mesh.getMesh().active_local_element_ptr_range())
     140             :     {
     141      800668 :       const auto id = kokkosMesh().getContiguousElementID(elem);
     142             : 
     143      800668 :       _dof_map.dof_indices(elem, dof_indices, var);
     144             : 
     145     4003776 :       for (unsigned int dof = 0; dof < dof_indices.size(); ++dof)
     146             :       {
     147     3203108 :         _local_elem_dof_index[var](id, dof) = solution->map_global_to_local_index(dof_indices[dof]);
     148     3203108 :         _local_to_global_dof_index[_local_elem_dof_index[var](id, dof)] = dof_indices[dof];
     149             :       }
     150        2142 :     }
     151             : 
     152      876425 :     for (const auto node : kokkosMesh().getLocalNodes())
     153      874283 :       if (node->processor_id() == _comm.rank())
     154             :       {
     155      866542 :         const auto id = kokkosMesh().getContiguousNodeID(node);
     156             : 
     157      866542 :         _dof_map.dof_indices(node, dof_indices, var);
     158             : 
     159      866542 :         if (dof_indices.size())
     160             :         {
     161      840007 :           for (unsigned int i = 1; i < dof_indices.size(); ++i)
     162           0 :             if (dof_indices[i] != dof_indices[i - 1] + 1)
     163           0 :               mooseError("Kokkos system error: a variable has multiple DOFs on a node, but the DOF "
     164             :                          "indices are discontiguous. This is not supported.");
     165             : 
     166      840007 :           _local_node_dof_index[var][id] = solution->map_global_to_local_index(dof_indices[0]);
     167             :         }
     168             :       }
     169        2142 :   }
     170             : 
     171        4530 :   _local_elem_dof_index.copyToDeviceNested();
     172        4530 :   _local_node_dof_index.copyToDeviceNested();
     173        4530 :   _local_to_global_dof_index.copyToDevice();
     174             : 
     175        4530 :   _max_dofs_per_elem.copyToDevice();
     176             : 
     177             :   // Setup DOF communication maps
     178             : 
     179        4530 :   auto num_procs = _comm.size();
     180             : 
     181        9060 :   std::vector<std::vector<dof_id_type>> send_list(num_procs);
     182        4530 :   std::vector<std::vector<dof_id_type>> recv_list(num_procs);
     183             : 
     184       18120 :   for (auto dof : _dof_map.get_send_list())
     185       13590 :     recv_list[_dof_map.dof_owner(dof)].push_back(dof);
     186             : 
     187       11276 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     188        6746 :     _comm.scatter(recv_list, send_list[proc], proc);
     189             : 
     190        4530 :   _local_comm_list.create(num_procs);
     191        4530 :   _ghost_comm_list.create(num_procs);
     192             : 
     193       11276 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     194             :   {
     195        6746 :     _local_comm_list[proc].create(send_list[proc].size());
     196        6746 :     _ghost_comm_list[proc].create(recv_list[proc].size());
     197             : 
     198       20336 :     for (dof_id_type i = 0; i < send_list[proc].size(); ++i)
     199       13590 :       _local_comm_list[proc][i] = solution->map_global_to_local_index(send_list[proc][i]);
     200             : 
     201       20336 :     for (dof_id_type i = 0; i < recv_list[proc].size(); ++i)
     202       13590 :       _ghost_comm_list[proc][i] = solution->map_global_to_local_index(recv_list[proc][i]);
     203             :   }
     204             : 
     205        4530 :   _local_comm_list.copyToDeviceNested();
     206        4530 :   _ghost_comm_list.copyToDeviceNested();
     207        4530 : }
     208             : 
     209             : void
     210        2265 : System::setupSparsity()
     211             : {
     212        2265 :   auto pattern = _dof_map.get_sparsity_pattern();
     213             : 
     214        2265 :   if (!pattern)
     215           0 :     return;
     216             : 
     217        2265 :   std::vector<PetscInt> col_idx;
     218        2265 :   std::vector<PetscInt> row_idx;
     219        4530 :   std::vector<PetscInt> row_ptr = {0};
     220             : 
     221      168901 :   for (dof_id_type r = _dof_map.first_dof(); r < _dof_map.end_dof(); ++r)
     222             :   {
     223      166636 :     auto & cols = pattern->get_sparsity_pattern().at(r - _dof_map.first_dof());
     224             : 
     225     1840262 :     for (auto col : cols)
     226             :     {
     227     1673626 :       col_idx.push_back(col);
     228     1673626 :       row_idx.push_back(r);
     229             :     }
     230             : 
     231      166636 :     row_ptr.push_back(col_idx.size());
     232             :   }
     233             : 
     234        2265 :   auto num_procs = _comm.size();
     235             : 
     236        9060 :   std::vector<std::vector<PetscInt>> send_cols(num_procs), send_num_cols(num_procs);
     237        6795 :   std::vector<std::vector<PetscInt>> recv_cols(num_procs), recv_num_cols(num_procs);
     238             : 
     239        5638 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     240        8495 :     for (auto r : _local_comm_list[proc])
     241             :     {
     242       62452 :       for (PetscInt c = row_ptr[r]; c < row_ptr[r + 1]; ++c)
     243       57330 :         send_cols[proc].push_back(col_idx[c]);
     244             : 
     245        5122 :       send_num_cols[proc].push_back(row_ptr[r + 1] - row_ptr[r]);
     246             :     }
     247             : 
     248        5638 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     249             :   {
     250        3373 :     _comm.scatter(send_cols, recv_cols[proc], proc);
     251        3373 :     _comm.scatter(send_num_cols, recv_num_cols[proc], proc);
     252             :   }
     253             : 
     254        6795 :   std::vector<PetscInt> col(num_procs), row(num_procs);
     255             : 
     256        7387 :   for (auto r : _dof_map.get_send_list())
     257             :   {
     258        5122 :     auto proc = _dof_map.dof_owner(r);
     259        5122 :     auto n_cols = recv_num_cols[proc][row[proc]++];
     260             : 
     261       62452 :     for (PetscInt c = 0; c < n_cols; ++c)
     262             :     {
     263       57330 :       col_idx.push_back(recv_cols[proc][col[proc]++]);
     264       57330 :       row_idx.push_back(r);
     265             :     }
     266             : 
     267        5122 :     row_ptr.push_back(col_idx.size());
     268             :   }
     269             : 
     270        2265 :   _sparsity.col_idx = col_idx;
     271        2265 :   _sparsity.row_idx = row_idx;
     272        2265 :   _sparsity.row_ptr = row_ptr;
     273        2265 : }
     274             : 
     275             : void
     276        2265 : System::setupNodalBCDofs()
     277             : {
     278        2265 :   auto & nl_system = static_cast<NonlinearSystemBase &>(_system);
     279             : 
     280        2265 :   _nbc_matrix_tag_dof.create(MAX_TAG);
     281             : 
     282        5674 :   for (auto bc : nl_system.getKokkosNodalBCWarehouse().getActiveObjects())
     283             :   {
     284        3409 :     auto nbc = static_cast<NodalBCBase *>(bc.get());
     285             : 
     286        3409 :     auto matrix_tags = nbc->getMatrixTags({});
     287             : 
     288       10414 :     for (auto tag : matrix_tags)
     289        7005 :       getNodalBCDofs(nbc, _nbc_matrix_tag_dof[tag]);
     290        3409 :   }
     291             : 
     292        2265 :   _nbc_matrix_tag_dof.copyToDeviceNested();
     293        2265 : }
     294             : 
     295             : void
     296        7005 : System::getNodalBCDofs(const NodalBCBase * nbc, Array<bool> & dofs)
     297             : {
     298        7005 :   auto var = nbc->variable().number();
     299             : 
     300        7005 :   if (!dofs.isAlloc())
     301             :   {
     302        3740 :     dofs.create(_num_local_dofs + _num_ghost_dofs);
     303        3740 :     dofs = false;
     304             :   }
     305             : 
     306       46189 :   for (auto node : nbc->getContiguousNodes())
     307       46189 :     dofs[_local_node_dof_index[var][node]] = true;
     308             : 
     309             :   // Let remote processes know about ghost DOFs associated with nodal BCs not to contribute on them
     310             : 
     311        7005 :   auto num_procs = _comm.size();
     312             : 
     313       21015 :   std::vector<std::vector<char>> send(num_procs), recv(num_procs);
     314             : 
     315       17426 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     316       25889 :     for (auto dof : _local_comm_list[proc])
     317       15468 :       send[proc].push_back(dofs[dof]);
     318             : 
     319       17426 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     320       10421 :     _comm.scatter(send, recv[proc], proc);
     321             : 
     322       17426 :   for (processor_id_type proc = 0; proc < num_procs; proc++)
     323       25889 :     for (dof_id_type i = 0; i < _ghost_comm_list[proc].size(); ++i)
     324       15468 :       dofs[_ghost_comm_list[proc][i]] = recv[proc][i];
     325        7005 : }
     326             : 
     327             : void
     328      639568 : System::sync(const MemcpyType dir)
     329             : {
     330      639568 :   if (dir == MemcpyType::HOST_TO_DEVICE)
     331             :   {
     332     1030772 :     for (auto tag : _active_solution_tags)
     333             :     {
     334      710988 :       auto & vector = _system.getVector(tag);
     335             : 
     336      710988 :       _vectors[tag].create(vector, *this, false);
     337      710988 :       _vectors[tag].copyToDevice();
     338             :     }
     339             : 
     340      696731 :     for (auto tag : _active_residual_tags)
     341             :     {
     342      376947 :       auto & vector = _system.getVector(tag);
     343             : 
     344      376947 :       _vectors[tag].create(vector, *this, true);
     345      376947 :       _vectors[tag].copyToDevice();
     346             :     }
     347             : 
     348      335937 :     for (auto tag : _active_matrix_tags)
     349             :     {
     350       16153 :       auto & matrix = _system.getMatrix(tag);
     351             : 
     352             :       {
     353       48459 :         TIME_SECTION("MatSetPreallocation", 1);
     354       16153 :         _matrices[tag].create(matrix, *this);
     355       16153 :       }
     356             : 
     357       16153 :       _matrices[tag] = 0;
     358             :     }
     359             : 
     360      319784 :     _vectors.copyToDevice();
     361      319784 :     _matrices.copyToDevice();
     362             :   }
     363      319784 :   else if (dir == MemcpyType::DEVICE_TO_HOST)
     364             :   {
     365     1030772 :     for (auto tag : _active_solution_tags)
     366      710988 :       _vectors[tag].restore();
     367             : 
     368      696731 :     for (auto tag : _active_residual_tags)
     369      376947 :       _vectors[tag].close();
     370             : 
     371      335937 :     for (auto tag : _active_matrix_tags)
     372             :     {
     373       48459 :       TIME_SECTION("MatSetValues", 1);
     374       16153 :       _matrices[tag].close();
     375       16153 :     }
     376             :   }
     377      639568 : }
     378             : 
     379             : void
     380       50946 : System::sync(const std::set<TagID> & tags, const MemcpyType dir)
     381             : {
     382       50946 :   if (dir == MemcpyType::HOST_TO_DEVICE)
     383             :   {
     384       50976 :     for (auto tag : tags)
     385             :     {
     386       25503 :       if (!_system.hasVector(tag))
     387        4368 :         continue;
     388             : 
     389       21135 :       auto & vector = _system.getVector(tag);
     390             : 
     391       21135 :       _vectors[tag].create(vector, *this, false);
     392       21135 :       _vectors[tag].copyToDevice();
     393             :     }
     394             : 
     395       25473 :     _vectors.copyToDevice();
     396             :   }
     397       25473 :   else if (dir == MemcpyType::DEVICE_TO_HOST)
     398             :   {
     399       50976 :     for (auto tag : tags)
     400             :     {
     401       25503 :       if (!_system.hasVector(tag))
     402        4368 :         continue;
     403             : 
     404       21135 :       _vectors[tag].copyToHost();
     405       21135 :       _vectors[tag].restore();
     406             :     }
     407             :   }
     408       50946 : }
     409             : 
     410             : void
     411           0 : System::sync(const std::vector<TagID> & tags, const MemcpyType dir)
     412             : {
     413           0 :   sync(std::set<TagID>(tags.begin(), tags.end()), dir);
     414           0 : }
     415             : 
     416             : void
     417       33474 : System::sync(const TagID tag, const MemcpyType dir)
     418             : {
     419       66948 :   sync(std::set<TagID>{tag}, dir);
     420       33474 : }
     421             : 
     422             : void
     423      190102 : System::setActiveVariables(const std::set<MooseVariableFieldBase *> & vars)
     424             : {
     425      190102 :   std::set<unsigned int> active_variables;
     426             : 
     427      475512 :   for (auto var : vars)
     428      285410 :     if (var->sys().number() == _system.number())
     429      285410 :       for (unsigned int i = 0; i < var->count(); ++i)
     430      142705 :         active_variables.insert(var->number() + i);
     431             : 
     432      190102 :   _active_variables = active_variables;
     433      190102 : }
     434             : 
     435             : void
     436      319784 : System::setActiveSolutionTags(const std::set<TagID> & tags)
     437             : {
     438      319784 :   std::set<TagID> active_solution_tags;
     439             : 
     440     1689934 :   for (auto tag : tags)
     441     1370150 :     if (_system.hasVector(tag))
     442      710988 :       active_solution_tags.insert(tag);
     443             : 
     444      319784 :   _active_solution_tags = active_solution_tags;
     445      319784 : }
     446             : 
     447             : void
     448      131257 : System::setActiveResidualTags(const std::set<TagID> & tags)
     449             : {
     450      131257 :   std::set<TagID> active_residual_tags;
     451             : 
     452      508204 :   for (auto tag : tags)
     453      376947 :     if (_system.hasVector(tag))
     454             :     {
     455      376947 :       active_residual_tags.insert(tag);
     456      376947 :       _residual_tag_active[tag] = true;
     457             :     }
     458             : 
     459      131257 :   _active_residual_tags = active_residual_tags;
     460             : 
     461      131257 :   _residual_tag_active.copyToDevice();
     462      131257 : }
     463             : 
     464             : void
     465       15791 : System::setActiveMatrixTags(const std::set<TagID> & tags)
     466             : {
     467       15791 :   std::set<TagID> active_matrix_tags;
     468             : 
     469       47237 :   for (auto tag : tags)
     470       31446 :     if (_system.hasMatrix(tag))
     471             :     {
     472       16153 :       active_matrix_tags.insert(tag);
     473       16153 :       _matrix_tag_active[tag] = true;
     474             :     }
     475             : 
     476       15791 :   _active_matrix_tags = active_matrix_tags;
     477             : 
     478       15791 :   _matrix_tag_active.copyToDevice();
     479       15791 : }
     480             : 
     481             : void
     482      190102 : System::reinit()
     483             : {
     484      615312 :   for (auto tag : _active_solution_tags)
     485             :   {
     486      425210 :     if (!_qp_solutions[tag].isAlloc())
     487        6477 :       _qp_solutions[tag].create(kokkosMesh().getNumSubdomains(), _num_vars);
     488             : 
     489      425210 :     if (!_qp_solutions_grad[tag].isAlloc())
     490        6477 :       _qp_solutions_grad[tag].create(kokkosMesh().getNumSubdomains(), _num_vars);
     491             : 
     492      873085 :     for (auto subdomain : _mesh.meshSubdomains())
     493             :     {
     494      447875 :       auto sid = kokkosMesh().getContiguousSubdomainID(subdomain);
     495             : 
     496      824077 :       for (auto var : _active_variables)
     497             :       {
     498      376202 :         if (!_var_subdomain_active(var, sid))
     499         626 :           continue;
     500             : 
     501      375576 :         if (!_qp_solutions[tag](sid, var).isAlloc())
     502        6547 :           _qp_solutions[tag](sid, var).createDevice(kokkosAssembly().getNumQps(sid));
     503             : 
     504      375576 :         if (!_qp_solutions_grad[tag](sid, var).isAlloc())
     505        6547 :           _qp_solutions_grad[tag](sid, var).createDevice(kokkosAssembly().getNumQps(sid));
     506             :       }
     507             :     }
     508             : 
     509      425210 :     _qp_solutions[tag].copyToDevice();
     510      425210 :     _qp_solutions_grad[tag].copyToDevice();
     511             :   }
     512             : 
     513      190102 :   _qp_solutions.copyToDevice();
     514      190102 :   _qp_solutions_grad.copyToDevice();
     515             : 
     516      190102 :   dof_id_type num_elems = kokkosMesh().getNumLocalElements();
     517             : 
     518      190102 :   _thread.resize(kokkosAssembly().getMaxQpsPerElem(),
     519             :                  num_elems,
     520             :                  _active_variables.size(),
     521             :                  _active_solution_tags.size());
     522             : 
     523      190102 :   ::Kokkos::RangePolicy<ExecSpace, ::Kokkos::IndexType<ThreadID>> policy(0, _thread.size());
     524      190102 :   ::Kokkos::parallel_for(policy, *this);
     525      190102 :   ::Kokkos::fence();
     526      190102 : }
     527             : 
     528             : KOKKOS_FUNCTION void
     529    67877944 : System::operator()(const ThreadID tid) const
     530             : {
     531    67877944 :   auto qp = _thread(tid, 0);
     532    67877944 :   auto elem = _thread(tid, 1);
     533    67877944 :   auto var = _active_variables(_thread(tid, 2));
     534    67877944 :   auto tag = _active_solution_tags(_thread(tid, 3));
     535             : 
     536    67877944 :   auto info = kokkosMesh().getElementInfo(elem);
     537    67877944 :   auto sid = info.subdomain;
     538    67877944 :   auto elem_type = info.type;
     539             : 
     540    67877944 :   if (!_var_subdomain_active(var, sid))
     541        3872 :     return;
     542             : 
     543    67874072 :   auto fe_type = _var_fe_types[var];
     544    67874072 :   auto num_dofs = kokkosAssembly().getNumDofs(elem_type, fe_type);
     545    67874072 :   auto num_qps = kokkosAssembly().getNumQps(info);
     546    67874072 :   auto qp_offset = kokkosAssembly().getQpOffset(info);
     547             : 
     548    67874072 :   if (qp >= num_qps)
     549           0 :     return;
     550             : 
     551    67874072 :   auto & phi = kokkosAssembly().getPhi(sid, elem_type, fe_type);
     552    67874072 :   auto & grad_phi = kokkosAssembly().getGradPhi(sid, elem_type, fe_type);
     553    67874072 :   auto jacobian = kokkosAssembly().getJacobian(info, qp);
     554             : 
     555    67874072 :   Real value = 0;
     556    67874072 :   Real3 grad = 0;
     557             : 
     558   371598020 :   for (unsigned int i = 0; i < num_dofs; ++i)
     559             :   {
     560   303723948 :     auto vector = getVectorDofValue(getElemLocalDofIndex(elem, i, var), tag);
     561             : 
     562   303723948 :     value += vector * phi(i, qp);
     563   303723948 :     grad += vector * (jacobian * grad_phi(i, qp));
     564             :   }
     565             : 
     566    67874072 :   getVectorQpValue(info, qp_offset + qp, var, tag) = value;
     567    67874072 :   getVectorQpGrad(info, qp_offset + qp, var, tag) = grad;
     568             : }
     569             : 
     570             : } // namespace Moose::Kokkos

Generated by: LCOV version 1.14