def METHOD_NAME(self, poly, value, opname="add", inside=True):
    """A generic function for doing operations restricted to inside
    or outside polygon(s).
    """
    grid = self.geometry
    grid._xtgformat1()
    if not isinstance(poly, xtgeo.xyz.Polygons):
        raise ValueError("The poly input is not a Polygons instance")
    # make a copy of the array which is used a "filter" or "proxy"
    # value will be 1 inside polygons, 0 outside. Undef cells are kept as is
    dtype = self.dtype
    proxy = self.copy()
    proxy.discrete_to_continuous()
    proxy.values *= 0.0
    cvals = gl.update_carray(proxy)
    idgroups = poly.dataframe.groupby(poly.pname)
    for id_, grp in idgroups:
        xcor = grp[poly.xname].values
        ycor = grp[poly.yname].values
        ier = _cxtgeo.grd3d_setval_poly(
            xcor,
            ycor,
            self.ncol,
            self.nrow,
            self.nlay,
            grid._coordsv,
            grid._zcornsv,
            grid._actnumsv,
            cvals,
            1,
        )
        if ier == -9:
            print(f"## Polygon no {id_ + 1} is not closed")
    gl.update_values_from_carray(proxy, cvals, np.float64, delete=True)
    proxyv = proxy.values.astype(np.int8)
    proxytarget = 1
    if not inside:
        proxytarget = 0
    if opname == "add":
        tmp = self.values.copy() + value
    elif opname == "sub":
        tmp = self.values.copy() - value
    elif opname == "mul":
        tmp = self.values.copy() * value
    elif opname == "div":
        # Dividing a map of zero is always a hazzle; try to obtain 0.0
        # as result in these cases
        if 0.0 in value:
            xtg.warn(
                "Dividing a surface with value or surface with zero "
                "elements; may get unexpected results, try to "
                "achieve zero values as result!"
            )
        with np.errstate(divide="ignore", invalid="ignore"):
            this = np.ma.filled(self.values, fill_value=1.0)
            that = np.ma.filled(value, fill_value=1.0)
            mask = np.ma.getmaskarray(self.values)
            tmp = np.true_divide(this, that)
            tmp = np.where(np.isinf(tmp), 0, tmp)
            tmp = np.nan_to_num(tmp)
            tmp = np.ma.array(tmp, mask=mask)
    elif opname == "set":
        tmp = self.values.copy() * 0 + value
    # convert tmp back to correct dtype
    tmp = tmp.astype(dtype)
    self.values[proxyv == proxytarget] = tmp[proxyv == proxytarget]
    del tmp