LCOV - code coverage report
Current view: top level - src/tensor_computes - LBMBoundaryCondition.C (source / functions) Hit Total Coverage
Test: idaholab/swift: #92 (25e020) with base b3cd84 Lines: 0 38 0.0 %
Date: 2025-09-10 17:10:32 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /**********************************************************************/
       2             : /*                    DO NOT MODIFY THIS HEADER                       */
       3             : /*             Swift, a Fourier spectral solver for MOOSE             */
       4             : /*                                                                    */
       5             : /*            Copyright 2024 Battelle Energy Alliance, LLC            */
       6             : /*                        ALL RIGHTS RESERVED                         */
       7             : /**********************************************************************/
       8             : 
       9             : #include "LBMBoundaryCondition.h"
      10             : #include "LatticeBoltzmannProblem.h"
      11             : #include "LatticeBoltzmannStencilBase.h"
      12             : 
      13             : InputParameters
      14           0 : LBMBoundaryCondition::validParams()
      15             : {
      16           0 :   InputParameters params = LatticeBoltzmannOperator::validParams();
      17           0 :   MooseEnum boundary("top bottom left right front back wall");
      18           0 :   params.addRequiredParam<MooseEnum>(
      19             :       "boundary", boundary, "Edges/Faces where boundary condition is applied.");
      20           0 :   params.addClassDescription("LBMBoundaryCondition object.");
      21           0 :   return params;
      22           0 : }
      23             : 
      24           0 : LBMBoundaryCondition::LBMBoundaryCondition(const InputParameters & parameters)
      25             :   : LatticeBoltzmannOperator(parameters),
      26           0 :     _grid_size(_lb_problem.getGridSize()),
      27           0 :     _boundary(getParam<MooseEnum>("boundary").getEnum<Boundary>())
      28             : {
      29             :   /**
      30             :    * Nodes that are adjacent to boundary will be set to 2, this will later be used in determining
      31             :    * the nodes for bounce-back
      32             :    * This will be achieved by shifting the mesh around in streaming directions and finding where
      33             :    * boundary hit happens
      34             :    */
      35             :   // if (_lb_problem.isBinaryMedia())
      36             :   // {
      37             :   //   auto new_mesh = _mesh.getBinaryMesh().clone();
      38             :   //   for (int64_t ic = 1; ic < _stencil._q; ic++)
      39             :   //   {
      40             :   //     int64_t ex = _stencil._ex[ic].item<int64_t>();
      41             :   //     int64_t ey = _stencil._ey[ic].item<int64_t>();
      42             :   //     int64_t ez = _stencil._ez[ic].item<int64_t>();
      43             :   //     torch::Tensor shifted_mesh = torch::roll(new_mesh, {ex, ey, ez}, {0, 1, 2});
      44             :   //     torch::Tensor adjacent_to_boundary = (shifted_mesh == 0) & (new_mesh == 1);
      45             :   //     new_mesh.masked_fill_(adjacent_to_boundary, 2);
      46             :   //   }
      47             :   //   // Deep copy new mesh
      48             :   //   // MooseTensor::printField(new_mesh, 1, 0);
      49             :   //   _mesh.setBinaryMesh(new_mesh);
      50             :   // }
      51             : 
      52             :   // if (_lb_problem.isBinaryMedia() && _domain.getDim() != 3)
      53             :   //   LBMBoundaryCondition::buildBoundaryIndices();
      54           0 : }
      55             : 
      56             : #if 0
      57             : int64_t
      58             : LBMBoundaryCondition::countNumberofBoundaries()
      59             : {
      60             :   /**
      61             :    * For efficiency, we count the number of boundaries first
      62             :    */
      63             : 
      64             :   LBMBoundaryCondition::determineBoundaryTypes();
      65             : 
      66             :   int64_t k = 0;
      67             :   int64_t num_of_boundaries = 0;
      68             :   for (int64_t i = 0; i < _shape_q[0]; i++)
      69             :     for (int64_t j = 0; j < _shape_q[1]; j++)
      70             :       for (int64_t ic = 0; ic < _shape_q[3]; ic++)
      71             :       {
      72             :         // Avoid calling item() repeatedly
      73             :         int64_t boundary_type = _boundary_types[i][j][k].item<int64_t>();
      74             : 
      75             :         if (boundary_type != -1)
      76             :         {
      77             :           int64_t if_stream_index = _all_boundary_types.size(0) * ic + boundary_type;
      78             : 
      79             :           // when streaming along ic is NOT possible at i, j, k i.e zero
      80             :           if (_if_stream[if_stream_index].item<int64_t>() == 0)
      81             :           {
      82             :             num_of_boundaries++;
      83             :           }
      84             :         }
      85             :       }
      86             : 
      87             :   return num_of_boundaries;
      88             : }
      89             : 
      90             : void
      91             : LBMBoundaryCondition::buildBoundaryIndices()
      92             : {
      93             :   /**
      94             :    * Building boundary indices
      95             :    */
      96             :   // const torch::Tensor & mesh_expanded =
      97             :   // _mesh.getBinaryMesh().unsqueeze(3).expand(expected_shape); auto mask = (mesh_expanded == 2) &
      98             :   // (_u == 0); _boundary_indices = torch::nonzero(mask); _boundary_indices =
      99             :   // _boundary_indices.to(MooseTensor::intTensorOptions());
     100             : 
     101             :   int64_t num_of_boundaries = countNumberofBoundaries();
     102             : 
     103             :   // initialize boundary indices
     104             :   _boundary_indices = torch::zeros({num_of_boundaries, 4}, MooseTensor::intTensorOptions());
     105             : 
     106             :   int64_t row_index = 0;
     107             :   int64_t k = 0;
     108             :   for (int64_t i = 0; i < _shape_q[0]; i++)
     109             :     for (int64_t j = 0; j < _shape_q[1]; j++)
     110             :       for (int64_t ic = 0; ic < _shape_q[3]; ic++)
     111             :       {
     112             :         // Avoid calling item() repeatedly
     113             :         int64_t boundary_type = _boundary_types[i][j][k].item<int64_t>();
     114             : 
     115             :         if (boundary_type != -1)
     116             :         {
     117             :           int64_t if_stream_index = _all_boundary_types.size(0) * ic + boundary_type;
     118             : 
     119             :           // when streaming along ic is NOT possible at i, j, k i.e zero
     120             :           if (_if_stream[if_stream_index].item<int64_t>() == 0)
     121             :           {
     122             :             _boundary_indices[row_index] = torch::tensor(
     123             :                 {i, j, k, _stencil._op[ic].item<int64_t>()}, MooseTensor::intTensorOptions());
     124             :             row_index++;
     125             :           }
     126             :         }
     127             :       }
     128             : }
     129             : 
     130             : void
     131             : LBMBoundaryCondition::determineBoundaryTypes()
     132             : {
     133             :   /**
     134             :    * Scan the binary domain in a 3x3 window to determine boundary types
     135             :    * D2Q9 only
     136             :    */
     137             : 
     138             :   const torch::Tensor & binary_mesh = _lb_problem.getBinaryMedia();
     139             :   _boundary_types =
     140             :       torch::zeros({_shape[0], _shape[1], _shape[2]}, MooseTensor::intTensorOptions());
     141             : 
     142             :   _boundary_types.fill_(-1);
     143             : 
     144             :   // changes the order of D2Q9
     145             :   std::vector<int64_t> d2q9_order_to_new_order{7, 3, 6, 4, 0, 2, 8, 1, 5};
     146             : 
     147             :   int64_t k = 0;
     148             : 
     149             :   for (int64_t i = 0; i < _shape[0]; i++)
     150             :     for (int64_t j = 0; j < _shape[1]; j++)
     151             :     {
     152             :       if (binary_mesh[i][j][k].item<int64_t>() != 0)
     153             :       {
     154             :         // assembling binary string
     155             :         std::string string_of_binary_digits;
     156             :         // search in all directions
     157             :         for (int64_t ic = 0; ic < _stencil._q; ic++)
     158             :         {
     159             :           int64_t i_prime = i + _stencil._ex[d2q9_order_to_new_order[ic]].item<int64_t>();
     160             :           int64_t j_prime = j + _stencil._ey[d2q9_order_to_new_order[ic]].item<int64_t>();
     161             : 
     162             :           // ensuring periodicity
     163             :           i_prime = (i_prime < 0) ? i_prime + _shape[0] : i_prime;
     164             :           i_prime = (i_prime >= _shape[0]) ? i_prime - _shape[0] : i_prime;
     165             : 
     166             :           j_prime = (j_prime < 0) ? j_prime + _shape[1] : j_prime;
     167             :           j_prime = (j_prime >= _shape[1]) ? j_prime - _shape[1] : j_prime;
     168             : 
     169             :           //
     170             :           if (binary_mesh[i_prime][j_prime][k].item<int64_t>() == 0)
     171             :             string_of_binary_digits += '0';
     172             :           else
     173             :             string_of_binary_digits += '1';
     174             :         }
     175             : 
     176             :         // convert binary to decimal
     177             :         std::bitset<32> binary(string_of_binary_digits);
     178             :         int64_t decimal_number = binary.to_ulong();
     179             :         if (decimal_number != 511)
     180             :         {
     181             :           auto comparison_result = (_all_boundary_types == decimal_number);
     182             :           bool is_decimal_number_in_boundary_types = torch::any(comparison_result).item<bool>();
     183             : 
     184             :           if (!is_decimal_number_in_boundary_types)
     185             :           {
     186             :             std::string error_message =
     187             :                 "Boundary type " + std::to_string(decimal_number) + " is not found";
     188             :             mooseError(error_message);
     189             :           }
     190             :           else
     191             :           {
     192             :             // the index where boundary type matches decimal_number
     193             :             int64_t index = torch::nonzero(comparison_result).item<int64_t>();
     194             : 
     195             :             _boundary_types[i][j][k] = index;
     196             :           }
     197             :         }
     198             :       }
     199             :     }
     200             : }
     201             : #endif
     202             : 
     203             : void
     204           0 : LBMBoundaryCondition::computeBuffer()
     205             : {
     206           0 :   switch (_boundary)
     207             :   {
     208           0 :     case Boundary::top:
     209           0 :       topBoundary();
     210           0 :       break;
     211           0 :     case Boundary::bottom:
     212           0 :       bottomBoundary();
     213           0 :       break;
     214           0 :     case Boundary::left:
     215           0 :       leftBoundary();
     216           0 :       break;
     217           0 :     case Boundary::right:
     218           0 :       rightBoundary();
     219           0 :       break;
     220           0 :     case Boundary::front:
     221           0 :       frontBoundary();
     222           0 :       break;
     223           0 :     case Boundary::back:
     224           0 :       backBoundary();
     225           0 :       break;
     226           0 :     case Boundary::wall:
     227           0 :       wallBoundary();
     228           0 :       break;
     229           0 :     default:
     230           0 :       mooseError("Undefined boundary names");
     231             :   }
     232           0 :   _lb_problem.maskedFillSolids(_u, 0);
     233           0 : }

Generated by: LCOV version 1.14