Exemple #1
0
    def divergence_theorem_test(self):
        "Test that the total input equals the total flux through the boundary."
        grid = self.grid

        inputs = PISM.HydrologyInputs()

        inputs.no_model_mask = None
        inputs.geometry = self.geometry
        inputs.basal_melt_rate = self.zero
        inputs.ice_sliding_speed = self.zero
        inputs.surface_input_rate = self.surface_input_rate

        dt = self.model.max_timestep(0).value()
        self.model.update(0, dt, inputs)

        flux_magnitude = PISM.IceModelVec2S(grid, "flux_magnitude",
                                            PISM.WITHOUT_GHOSTS)

        flux_magnitude.set_to_magnitude(self.model.flux())

        # Compute the total input. This approximates a double integral, hence
        # the "dx dy" factor.
        total_input = self.model.surface_input_rate().sum() * (grid.dx() *
                                                               grid.dy())

        # Compute the total flux through the grounding line. This is not
        # exactly what we want, but it's close. It would be better to use the
        # flux on the staggered grid as computed internally, but the flux
        # magnitude will do, especially in the dx=dy case. This approximates a
        # line integral over the grounding line, hence the dx factor below.
        total_flux = 0.0
        cell_type = self.geometry.cell_type
        with PISM.vec.Access(nocomm=[cell_type, flux_magnitude]):
            for (i, j) in grid.points():
                if cell_type.ice_free_ocean(
                        i, j) and cell_type.next_to_grounded_ice(i, j):
                    total_flux += flux_magnitude[i, j] * grid.dx()

        total_flux = PISM.GlobalSum(ctx.com, total_flux)

        # This is the relative error. Note that it is not sensitive to the
        # value of hydrology.steady.volume_ratio.
        relative_error = np.fabs(total_input - total_flux) / total_input

        assert relative_error < 1e-5
        ctx.log.message(1, "relative error: {}\n".format(relative_error))
Exemple #2
0
    def report(self):
        """Compares computed and exact solution values and displays a summary report."""
        grid = self.grid

        ssa_stdout = self.ssa.stdout_report()
        PISM.verbPrintf(3, grid.com, ssa_stdout)

        maxvecerr = 0.0
        avvecerr = 0.0
        avuerr = 0.0
        avverr = 0.0
        maxuerr = 0.0
        maxverr = 0.0

        if (self.config.get_boolean("basal_resistance.pseudo_plastic.enabled")
                and self.config.get_double("basal_resistance.pseudo_plastic.q")
                != 1.0):
            PISM.verbPrintf(
                1, grid.com,
                "WARNING: numerical errors not valid for pseudo-plastic till\n"
            )
        PISM.verbPrintf(
            1, grid.com,
            "NUMERICAL ERRORS in velocity relative to exact solution:\n")

        vel_ssa = self.ssa.velocity()

        vel_ssa.begin_access()

        exactvelmax = 0
        gexactvelmax = 0
        for (i, j) in self.grid.points():
            x = grid.x(i)
            y = grid.y(j)
            (uexact, vexact) = self.exactSolution(i, j, x, y)
            exactnormsq = math.sqrt(uexact * uexact + vexact * vexact)
            exactvelmax = max(exactnormsq, exactvelmax)
            solution = vel_ssa[i, j]
            uerr = abs(solution.u - uexact)
            verr = abs(solution.v - vexact)
            avuerr += uerr
            avverr += verr
            maxuerr = max(maxuerr, uerr)
            maxverr = max(maxverr, verr)
            vecerr = math.sqrt(uerr * uerr + verr * verr)
            maxvecerr = max(maxvecerr, vecerr)
            avvecerr = avvecerr + vecerr

        vel_ssa.end_access()

        N = grid.Mx() * grid.My()
        gexactvelmax = PISM.GlobalMax(grid.com, exactvelmax)
        gmaxuerr = PISM.GlobalMax(grid.com, maxuerr)
        gmaxverr = PISM.GlobalMax(grid.com, maxverr)
        gavuerr = PISM.GlobalSum(grid.com, avuerr) / N
        gavverr = PISM.GlobalSum(grid.com, avverr) / N
        gmaxvecerr = PISM.GlobalMax(grid.com, maxvecerr)
        gavvecerr = PISM.GlobalSum(grid.com, avvecerr) / N

        sys = grid.ctx().unit_system()

        m_year = PISM.UnitConverter(sys, "m / second", "m / year")

        if abs(gexactvelmax) > 0.0:
            relative_vel_error = (gavvecerr / gexactvelmax) * 100.0
        else:
            relative_vel_error = 0.0

        PISM.verbPrintf(
            1, grid.com,
            "velocity  :  maxvector   prcntavvec      maxu      maxv       avu       avv\n"
        )
        PISM.verbPrintf(1, grid.com,
                        "           %11.4f%13.5f%10.4f%10.4f%10.4f%10.4f\n",
                        m_year(gmaxvecerr), relative_vel_error,
                        m_year(gmaxuerr), m_year(gmaxverr), m_year(gavuerr),
                        m_year(gavverr))
        PISM.verbPrintf(1, grid.com, "NUM ERRORS DONE\n")