"""Methods to manage boundary conditions"""frompyro.utilimportmsg# keep track of whether the BCs are solid walls (passed into the# Riemann solver).bc_solid={}bc_solid["outflow"]=Falsebc_solid["periodic"]=Falsebc_solid["reflect"]=Truebc_solid["reflect-even"]=Truebc_solid["reflect-odd"]=Truebc_solid["dirichlet"]=Truebc_solid["neumann"]=Falseext_bcs={}
[docs]defdefine_bc(bc_type,function,is_solid=False):""" use this to extend the types of boundary conditions supported on a solver-by-solver basis. Here we pass in the reference to a function that can be called with the data that needs to be filled. is_solid indicates whether it should be interpreted as a solid wall (no flux through the BC)" """bc_solid[bc_type]=is_solidext_bcs[bc_type]=function
[docs]classBCProp:""" A simple container to hold properties of the boundary conditions. """def__init__(self,xl_prop,xr_prop,yl_prop,yr_prop):self.xl=xl_propself.xr=xr_propself.yl=yl_propself.yr=yr_prop
[docs]defbc_is_solid(bc):""" return a container class indicating which boundaries are solid walls """solid=BCProp(int(bc_solid[bc.xlb]),int(bc_solid[bc.xrb]),int(bc_solid[bc.ylb]),int(bc_solid[bc.yrb]))returnsolid
[docs]classBC:"""Boundary condition container -- hold the BCs on each boundary for a single variable. For Neumann and Dirichlet BCs, a function callback can be stored for inhomogeous BCs. This function should provide the value on the physical boundary (not cell center). This is evaluated on the relevant edge when the __init__ routine is called. For this reason, you need to pass in a grid object. Note: this only ensures that the first ghost cells is consistent with the BC value. """def__init__(self,*,xlb="outflow",xrb="outflow",ylb="outflow",yrb="outflow",xl_func=None,xr_func=None,yl_func=None,yr_func=None,grid=None,odd_reflect_dir=""):""" Create the BC object. Parameters ---------- xlb : {'outflow', 'periodic', 'reflect', 'reflect-even', 'reflect-odd', 'dirichlet', 'neumann', user-defined}, optional The type of boundary condition to enforce on the lower x boundary. user-defined requires one to have defined a new boundary condition type using define_bc() xrb : {'outflow', 'periodic', 'reflect', 'reflect-even', 'reflect-odd', 'dirichlet', 'neumann', user-defined}, optional The type of boundary condition to enforce on the upper x boundary. user-defined requires one to have defined a new boundary condition type using define_bc() ylb : {'outflow', 'periodic', 'reflect', 'reflect-even', 'reflect-odd', 'dirichlet', 'neumann', user-defined}, optional The type of boundary condition to enforce on the lower y boundary. user-defined requires one to have defined a new boundary condition type using define_bc() yrb : {'outflow', 'periodic', 'reflect', 'reflect-even', 'reflect-odd', 'dirichlet', 'neumann', user-defined}, optional The type of boundary condition to enforce on the upper y boundary. user-defined requires one to have defined a new boundary condition type using define_bc() odd_reflect_dir : {'x', 'y'}, optional The direction along which reflection should be odd (sign changes). If not specified, a boundary condition of 'reflect' will always be set to 'reflect-even' xl_func : function, optional A function, f(y), that provides the value of the Dirichlet or Neumann BC on the -x physical boundary. xr_func : function, optional A function, f(y), that provides the value of the Dirichlet or Neumann BC on the +x physical boundary. yl_func : function, optional A function, f(x), that provides the value of the Dirichlet or Neumann BC on the -y physical boundary. yr_func : function, optional A function, f(x), that provides the value of the Dirichlet or Neumann BC on the +y physical boundary. grid : a Grid2d object, optional The grid object is used for evaluating the function to define the boundary values for inhomogeneous Dirichlet and Neumann BCs. It is required if any functions are passed in. """# note: "reflect" is ambiguous and will be converted into# either reflect-even (the default) or reflect-odd if# odd_reflect_dir specifies the corresponding direction ("x",# "y")valid=list(bc_solid.keys())# -x boundaryifxlbinvalid:self.xlb=xlbifself.xlb=="reflect":self.xlb=_set_reflect(odd_reflect_dir,"x")else:msg.fail(f"ERROR: xlb = {xlb} invalid BC")# +x boundaryifxrbinvalid:self.xrb=xrbifself.xrb=="reflect":self.xrb=_set_reflect(odd_reflect_dir,"x")else:msg.fail(f"ERROR: xrb = {xrb} invalid BC")# -y boundaryifylbinvalid:self.ylb=ylbifself.ylb=="reflect":self.ylb=_set_reflect(odd_reflect_dir,"y")else:msg.fail(f"ERROR: ylb = {ylb} invalid BC")# +y boundaryifyrbinvalid:self.yrb=yrbifself.yrb=="reflect":self.yrb=_set_reflect(odd_reflect_dir,"y")else:msg.fail(f"ERROR: yrb = {yrb} invalid BC")# periodic checksif((xlb=="periodic"andxrb!="periodic")or(xrb=="periodic"andxlb!="periodic")):msg.fail("ERROR: both xlb and xrb must be periodic")if((ylb=="periodic"andyrb!="periodic")or(yrb=="periodic"andylb!="periodic")):msg.fail("ERROR: both ylb and yrb must be periodic")# inhomogeneous functions for Dirichlet or Neumannself.xl_value=self.xr_value=self.yl_value=self.yr_value=Noneifxl_funcisnotNone:self.xl_value=xl_func(grid.y)ifxr_funcisnotNone:self.xr_value=xr_func(grid.y)ifyl_funcisnotNone:self.yl_value=yl_func(grid.x)ifyr_funcisnotNone:self.yr_value=yr_func(grid.x)def__str__(self):""" print out some basic information about the BC object """string=f"BCs: -x: {self.xlb} +x: {self.xrb} -y: {self.ylb} +y: {self.yrb}"returnstring