def _set_polar_grid_auto(self, n1=None, n2=None, n3=None, grid_type=None,
                             zmin=None, zmax=None, rmin=None, rmax=None, min_spacing=1.e-8):

        if self.star.radius is None:
            raise Exception("The central source radius need to be defined "
                            "before the grid can be set up")

        if grid_type is 'spherical':
            n_r, n_theta, n_phi = n1, n2, n3
        elif grid_type is 'cylindrical':
            n_r, n_z, n_phi = n1, n2, n3
        else:
            raise Exception("Unknown grid type: %s" % grid_type)

        # Find minimum and maximum radius if not specified
        if rmin is None:
            if len(self.disks) == 0 and len(self.envelopes) == 0:
                rmin = self.star.radius
            else:
                rmin_values = ([disk.rmin for disk in self.disks] +
                               [envelope.rmin for envelope in self.envelopes] +
                               [ambient.rmin for ambient in self.ambients])
                rmin = _min_none(*rmin_values)

        if rmax is None:
            rmax_values = [2. * self.star.radius]
            rmax_values += ([disk.rmax for disk in self.disks] +
                            [envelope.rmax for envelope in self.envelopes] +
                            [ambient.rmax for ambient in self.ambients])
            rmax = _max_none(*rmax_values)

        if rmax < rmin:
            logger.warn("Grid rmax < rmin, model will consist only of central star")
            rmin = self.star.radius
            rmax = 2. * self.star.radius

        if np.isnan(rmin):
            raise Exception("R_min is NaN")

        if np.isnan(rmax):
            raise Exception("R_max is NaN")

        if rmin == 0:
            raise ValueError("R_min is 0, so cannot set up the grid cell "
                             "walls automatically. Use set_%s_polar_grid()"
                             " instead to specify the cell wall positions"
                             "." % grid_type)

        # RADIAL WALLS

        # Set first wall to be at half the stellar radius to avoid any
        # numerical problems. Set second wall to be the disk inner radius.

        r_wall = [self.star.radius / 2., rmin]

        # Define a radial grid to compute the midplane column density on
        r = np.logspace(-20., np.log10((rmax - rmin) / rmin), 100000) * rmin + rmin

        # We need the first point to be exactly at the inner radius
        r[0] = rmin

        # Get cumulative midplane optical depth
        tau_midplane = self.get_midplane_tau(r)

        # Find where the second wall after rmin would be if grid cells were
        # spaced equally
        r_next_real = rmin * ((rmax / rmin) ** (1. / n_r) - 1.)

        # Find where the second wall would be if we put it at tau=0.1
        if tau_midplane[-1] <= 0.1:
            r_next_tau = rmax - rmin
        else:
            r_next_tau = np.interp(0.1, tau_midplane, r) - rmin

        # Pick the smallest
        rnext = min(r_next_real, r_next_tau)

        # Make sure rnext isn't too small
        if rmin * (1. + min_spacing) > rnext + rmin:
            logger.warn("Spacing of inner radial cells is too small, resetting to {0}".format(min_spacing))
            rnext = rmin * min_spacing

        # Define wall positions
        r_wall = np.hstack([0., np.logspace(np.log10(rnext / rmin), np.log10((rmax - rmin) / rmin), n_r - 1)]) * rmin + rmin
        r_wall = np.hstack([0., r_wall])

        if grid_type is 'spherical':

            # THETA WALLS
            t_wall = np.linspace(0, pi, n_theta + 1)
            t_wall = t_wall + np.sin(2 * t_wall) / 6.

        elif grid_type is 'cylindrical':

            # Z WALLS

            if not zmax:
                zmax = rmax

            if zmin is None and len(self.disks) > 0:
                zmin = np.inf
                for disk in self.disks:
                    zmin = min(zmin, disk.scale_height_at(rmin))

            if zmin is not None:

                if n_z % 2 == 0:
                    n_zn = n_z / 2
                    z_wall1 = np.linspace(zmin * 0.1, zmin * 0.9, 10)
                    z_wall2 = np.logspace(np.log10(zmin),
                                          np.log10(zmax),
                                          n_zn - 10)
                    z_wall = np.hstack([z_wall1, z_wall2])
                    z_wall = np.hstack([-z_wall[::-1], z_wall])
                else:
                    n_zn = (n_z - 1) / 2
                    z_wall1 = np.linspace(zmin * 0.1, zmin * 0.9, 10)
                    z_wall2 = np.logspace(np.log10(zmin),
                                          np.log10(zmax),
                                          n_zn - 10)
                    z_wall = np.hstack([z_wall1, z_wall2])
                    z_wall = np.hstack([-z_wall[::-1], 0., z_wall])

            else:

                z_wall = np.linspace(-zmax, zmax, n_z + 1)

        # PHI WALLS
        p_wall = np.linspace(0., 2. * pi, n_phi + 1)

        if grid_type is 'spherical':
            return SphericalPolarGrid(r_wall, t_wall, p_wall)
        else:
            return CylindricalPolarGrid(r_wall, z_wall, p_wall)

    # ACCRETION
dataset/ETHPy150Open hyperion-rt/hyperion/hyperion/model/analytical_yso_model.py/AnalyticalYSOModel._set_polar_grid_auto/original