<commit_before>/*! \file boundary_conditions.cpp
 *  \brief Definitions of the boundary conditions for various tests.
           Functions are members of the Grid3D class. */

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include"grid3D.h"
#include"io.h"
#include"error_handling.h"
#include"mpi_routines.h"


/*! \fn void Set_Boundary_Conditions(parameters P)
 *  \brief Set the boundary conditions based on info in the parameters structure. */
void Grid3D::Set_Boundary_Conditions(parameters P) {

#ifndef MPI_CHOLLA

  int flags[6] = {0,0,0,0,0,0};

  // Check for custom boundary conditions and set boundary flags
  if(Check_Custom_Boundary(&flags[0], P))
  {
    Custom_Boundary(P.custom_bcnd);
  }

  // set regular boundaries
  if(H.nx>1) {
    Set_Boundaries(0, flags);
    Set_Boundaries(1, flags);
  }
  if(H.ny>1) {
    Set_Boundaries(2, flags);
    Set_Boundaries(3, flags);
  }
  if(H.nz>1) {
    Set_Boundaries(4, flags);
    Set_Boundaries(5, flags);
  }

#else  /*MPI_CHOLLA*/

  /*Set boundaries, including MPI exchanges*/
  Set_Boundaries_MPI(P);

#endif /*MPI_CHOLLA*/
}


/*! \fn int Check_Custom_Boundary(int *flags, struct parameters P)
 *  \brief Check for custom boundary conditions and set boundary flags. */
int Grid3D::Check_Custom_Boundary(int *flags, struct parameters P)
{

  /*check if any boundary is a custom boundary*/
  /*if yes, then return 1*/
  /*if no, then return 0*/
  /*additionally, set a flag for each boundary*/
  
  if(H.nx>1)
  {
    *(flags+0) = P.xl_bcnd;
    *(flags+1) = P.xu_bcnd;
  }
  if(H.ny>1)
  {
    *(flags+2) = P.yl_bcnd;
    *(flags+3) = P.yu_bcnd;
  }
  if(H.nz>1)
  {
    *(flags+4) = P.zl_bcnd;
    *(flags+5) = P.zu_bcnd;  
  }

  for (int i=0; i<6; i++)
  {
    if (!( (flags[i]>=0)&&(flags[i]<=5) ) )
    {
      chprintf("Invalid boundary conditions. Must select between 1 (periodic), 2 (reflective), 3 (transmissive), 4 (custom), 5 (mpi).\n");
      chexit(0);
    }
    if (flags[i] == 4) {
      /*custom boundaries*/
      return 1;
    }
  }  
  /*no custom boundaries*/
  return 0;
}



/*! \fn void Set_Boundaries(int dir, int flags[])
 *  \brief Apply boundary conditions to the grid. */
void Grid3D::Set_Boundaries(int dir, int flags[])
{
  int i, j, k;
  int imin[3] = {0,0,0};
  int imax[3] = {H.nx,H.ny,H.nz};
  Real a[3]   = {1,1,1};  //sign of momenta
  int idx;    //index of a real cell
  int gidx;   //index of a ghost cell

#ifdef   MPI_CHOLLA
  /*if the cell face is an mpi boundary, exit */
  if(flags[dir]==5)
    return;
#endif /*MPI_CHOLLA*/

  //get the extents of the ghost region we are initializing
  Set_Boundary_Extents(dir, &imin[0], &imax[0]);

  /*set ghost cells*/
  for (k=imin[2]; k<imax[2]; k++) {
    for (j=imin[1]; j<imax[1]; j++) {
      for (i=imin[0]; i<imax[0]; i++) {

        //reset sign of momenta
        a[0] = 1.;
        a[1] = 1.;
        a[2] = 1.;

        //find the ghost cell index
        gidx = i + j*H.nx + k*H.nx*H.ny; 

        //find the corresponding real cell index and momenta signs
        idx  = Set_Boundary_Mapping(i,j,k,flags,&a[0]);
        
        //idx will be >= 0 if the boundary mapping function has
        //not set this ghost cell by hand, for instance for analytical 
        //boundary conditions
        //
        //Otherwise, the boundary mapping function will set idx<0
        //if this ghost cell has been set by hand
        if(idx>=0)
        {
          //set the ghost cell value
          C.density[gidx]    = C.density[idx];
          C.momentum_x[gidx] = C.momentum_x[idx]*a[0];
          C.momentum_y[gidx] = C.momentum_y[idx]*a[1];
          C.momentum_z[gidx] = C.momentum_z[idx]*a[2];
          C.Energy[gidx]     = C.Energy[idx];
          #ifdef DE
          C.GasEnergy[gidx]  = C.GasEnergy[idx];
          #endif
        }
      }
    }
  }
}


/*! \fn Set_Boundary_Extents(int dir, int *imin, int *imax)
 *  \brief Set the extents of the ghost region we are initializing. */
void Grid3D::Set_Boundary_Extents(int dir, int *imin, int *imax)
{
  int il, iu, jl, ju, kl, ku;
  jl = 0;
  ju = H.ny;
  kl = 0;
  ku = H.nz;
  if (H.ny > 1) {
    jl = H.n_ghost;
    ju = H.ny-H.n_ghost;
  }
  if (H.nz > 1) {
    kl = H.n_ghost;<commit_msg>restricted inflow in transmissive boundary conditions<commit_after>/*! \file boundary_conditions.cpp
 *  \brief Definitions of the boundary conditions for various tests.
           Functions are members of the Grid3D class. */

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include"grid3D.h"
#include"io.h"
#include"error_handling.h"
#include"mpi_routines.h"


/*! \fn void Set_Boundary_Conditions(parameters P)
 *  \brief Set the boundary conditions based on info in the parameters structure. */
void Grid3D::Set_Boundary_Conditions(parameters P) {

#ifndef MPI_CHOLLA

  int flags[6] = {0,0,0,0,0,0};

  // Check for custom boundary conditions and set boundary flags
  if(Check_Custom_Boundary(&flags[0], P))
  {
    Custom_Boundary(P.custom_bcnd);
  }

  // set regular boundaries
  if(H.nx>1) {
    Set_Boundaries(0, flags);
    Set_Boundaries(1, flags);
  }
  if(H.ny>1) {
    Set_Boundaries(2, flags);
    Set_Boundaries(3, flags);
  }
  if(H.nz>1) {
    Set_Boundaries(4, flags);
    Set_Boundaries(5, flags);
  }

#else  /*MPI_CHOLLA*/

  /*Set boundaries, including MPI exchanges*/
  Set_Boundaries_MPI(P);

#endif /*MPI_CHOLLA*/
}


/*! \fn int Check_Custom_Boundary(int *flags, struct parameters P)
 *  \brief Check for custom boundary conditions and set boundary flags. */
int Grid3D::Check_Custom_Boundary(int *flags, struct parameters P)
{

  /*check if any boundary is a custom boundary*/
  /*if yes, then return 1*/
  /*if no, then return 0*/
  /*additionally, set a flag for each boundary*/
  
  if(H.nx>1)
  {
    *(flags+0) = P.xl_bcnd;
    *(flags+1) = P.xu_bcnd;
  }
  if(H.ny>1)
  {
    *(flags+2) = P.yl_bcnd;
    *(flags+3) = P.yu_bcnd;
  }
  if(H.nz>1)
  {
    *(flags+4) = P.zl_bcnd;
    *(flags+5) = P.zu_bcnd;  
  }

  for (int i=0; i<6; i++)
  {
    if (!( (flags[i]>=0)&&(flags[i]<=5) ) )
    {
      chprintf("Invalid boundary conditions. Must select between 1 (periodic), 2 (reflective), 3 (transmissive), 4 (custom), 5 (mpi).\n");
      chexit(0);
    }
    if (flags[i] == 4) {
      /*custom boundaries*/
      return 1;
    }
  }  
  /*no custom boundaries*/
  return 0;
}



/*! \fn void Set_Boundaries(int dir, int flags[])
 *  \brief Apply boundary conditions to the grid. */
void Grid3D::Set_Boundaries(int dir, int flags[])
{
  int i, j, k;
  int imin[3] = {0,0,0};
  int imax[3] = {H.nx,H.ny,H.nz};
  Real a[3]   = {1,1,1};  //sign of momenta
  int idx;    //index of a real cell
  int gidx;   //index of a ghost cell

#ifdef   MPI_CHOLLA
  /*if the cell face is an mpi boundary, exit */
  if(flags[dir]==5)
    return;
#endif /*MPI_CHOLLA*/

  //get the extents of the ghost region we are initializing
  Set_Boundary_Extents(dir, &imin[0], &imax[0]);

  /*set ghost cells*/
  for (k=imin[2]; k<imax[2]; k++) {
    for (j=imin[1]; j<imax[1]; j++) {
      for (i=imin[0]; i<imax[0]; i++) {

        //reset sign of momenta
        a[0] = 1.;
        a[1] = 1.;
        a[2] = 1.;

        //find the ghost cell index
        gidx = i + j*H.nx + k*H.nx*H.ny; 

        //find the corresponding real cell index and momenta signs
        idx  = Set_Boundary_Mapping(i,j,k,flags,&a[0]);

        
        //idx will be >= 0 if the boundary mapping function has
        //not set this ghost cell by hand, for instance for analytical 
        //boundary conditions
        //
        //Otherwise, the boundary mapping function will set idx<0
        //if this ghost cell has been set by hand
        if(idx>=0)
        {
          //set the ghost cell value
          C.density[gidx]    = C.density[idx];
          C.momentum_x[gidx] = C.momentum_x[idx]*a[0];
          C.momentum_y[gidx] = C.momentum_y[idx]*a[1];
          C.momentum_z[gidx] = C.momentum_z[idx]*a[2];
          C.Energy[gidx]     = C.Energy[idx];
          #ifdef DE
          C.GasEnergy[gidx]  = C.GasEnergy[idx];
          #endif

          //for outflow boundaries, set momentum to restrict inflow
          if (flags[dir] == 3) {
            if (dir == 0) {
              C.momentum_x[gidx] = fmin(C.momentum_x[gidx], 0.0);
            }
            if (dir == 1) {
              C.momentum_x[gidx] = fmax(C.momentum_x[gidx], 0.0);
            }
            if (dir == 2) {
              C.momentum_y[gidx] = fmin(C.momentum_y[gidx], 0.0);
            }
            if (dir == 3) {
              C.momentum_y[gidx] = fmax(C.momentum_y[gidx], 0.0);
            }
            if (dir == 4) {
              C.momentum_z[gidx] = fmin(C.momentum_z[gidx], 0.0);
            }
            if (dir == 5) {
              C.momentum_z[gidx] = fmax(C.momentum_z[gidx], 0.0);
            }
          }

          
        }
      }
    }
  }
}


/*! \fn Set_Boundary_Extents(int dir, int *imin, int *imax)
 *  \brief Set the extents of the ghost region we are initializing. */
void Grid3D::Set_Boundary_Extents(int dir, int *imin, int *imax)
{
  int il, iu, jl, ju, kl, ku;
  jl = 0;
  ju = H.ny;
  kl = 0;
  ku = H.nz;
  if (H.ny > 1) {
    jl = H.n_ghost;
    ju = H.ny-H.n_ghost;
  }
  if (H.nz > 1) {
    kl = H.n_ghost;
{'fraction_non_alphanumeric': 0.1535064095658731, 'fraction_numerical': 0.019713454702143703, 'mean_word_length': 2.3467916366258113, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4982564', 'n_tokens_mistral': 3684, 'n_tokens_neox': 3492, 'n_words': 899}