Esempio n. 1
0
def test_twolayer_defaults(
    update_expected_files,
    test_rcmip_forcings_scmrun,
    test_twolayer_output_dir,
    run_model_output_comparison,
):
    twolayer_default = TwoLayerModel()
    res = twolayer_default.run_scenarios(test_rcmip_forcings_scmrun)

    expected = os.path.join(test_twolayer_output_dir, "test_twolayer_defaults.csv")

    run_model_output_comparison(res, expected, update_expected_files)
Esempio n. 2
0
def test_twolayer_plus_efficacy(
    update_expected_files,
    test_rcmip_forcings_scmrun,
    test_twolayer_output_dir,
    run_model_output_comparison,
):
    twolayer_plus_efficacy = TwoLayerModel(efficacy=1.2 * ur("dimensionless"))
    res = twolayer_plus_efficacy.run_scenarios(test_rcmip_forcings_scmrun)

    expected = os.path.join(test_twolayer_output_dir, "test_twolayer_plus_efficacy.csv")

    run_model_output_comparison(res, expected, update_expected_files)
Esempio n. 3
0
def test_twolayer_plus_state_dependence(
    update_expected_files,
    test_rcmip_forcings_scmrun,
    test_twolayer_output_dir,
    run_model_output_comparison,
):
    twolayer_plus_state_dependence = TwoLayerModel(a=0.05 * ur("W/m^2/delta_degC^2"))
    res = twolayer_plus_state_dependence.run_scenarios(test_rcmip_forcings_scmrun)

    expected = os.path.join(
        test_twolayer_output_dir, "test_twolayer_plus_state_dependence.csv"
    )

    run_model_output_comparison(res, expected, update_expected_files)
    def test_get_two_layer_model_parameters(self, check_equal_pint):
        tq1 = 0.3 * ur("delta_degC/(W/m^2)")
        tq2 = 0.4 * ur("delta_degC/(W/m^2)")
        td1 = 3 * ur("yr")
        td2 = 300.0 * ur("yr")
        tefficacy = 1.2 * ur("dimensionless")

        start_paras = dict(
            d1=td1,
            d2=td2,
            q1=tq1,
            q2=tq2,
            efficacy=tefficacy,
        )

        mod_instance = self.tmodel(**start_paras)

        # for explanation of what is going on, see
        # impulse-response-equivalence.ipynb
        efficacy = tefficacy
        lambda0 = 1 / (tq1 + tq2)
        C = (td1 * td2) / (tq1 * td2 + tq2 * td1)

        a1 = lambda0 * tq1
        a2 = lambda0 * tq2
        tau1 = td1
        tau2 = td2

        C_D = (lambda0 * (tau1 * a1 + tau2 * a2) - C) / efficacy
        eta = C_D / (tau1 * a2 + tau2 * a1)

        expected = {
            "lambda0": lambda0,
            "du": C / (DENSITY_WATER * HEAT_CAPACITY_WATER),
            "dl": C_D / (DENSITY_WATER * HEAT_CAPACITY_WATER),
            "eta": eta,
            "efficacy": efficacy,
        }

        res = mod_instance.get_two_layer_parameters()

        assert res == expected

        # check circularity
        circular_params = TwoLayerModel(
            **res).get_impulse_response_parameters()
        for k, v in circular_params.items():
            check_equal_pint(v, start_paras[k])
Esempio n. 5
0
def test_two_layer_impulse_response_equivalence(two_layer_config):
    time = np.arange(1750, 2501)
    forcing = 0.3 * np.sin(time / 15 * 2 * np.pi) + 3.0 * time / time.max()

    inp = ScmRun(
        data=forcing,
        index=time,
        columns={
            "scenario": "test_scenario",
            "model": "unspecified",
            "climate_model": "junk input",
            "variable": "Effective Radiative Forcing",
            "unit": "W/m^2",
            "region": "World",
        },
    )

    twolayer = TwoLayerModel(**two_layer_config)
    res_twolayer = twolayer.run_scenarios(inp)

    impulse_response = ImpulseResponseModel(
        **twolayer.get_impulse_response_parameters())
    res_impulse_response = impulse_response.run_scenarios(inp)

    assert (res_twolayer["time"] == res_impulse_response["time"]).all()

    npt.assert_allclose(
        res_twolayer.filter(variable="Effective Radiative Forcing").values,
        res_impulse_response.filter(
            variable="Effective Radiative Forcing").values,
    )
    npt.assert_allclose(
        res_twolayer.filter(variable="Heat Uptake").values,
        res_impulse_response.filter(variable="Heat Uptake").values,
        atol=0.1,  # numerical errors?
    )
    npt.assert_allclose(
        res_twolayer.filter(variable="Surface Temperature|Upper").values,
        res_impulse_response.filter(variable="Surface Temperature").values,
        atol=0.1,  # numerical errors?
    )
    def test_calculate_next_rndt(self, check_same_unit):
        ttemp1 = 1.1
        ttemp_2 = 0.6
        tq1 = 0.5
        tq2 = 0.3
        td1 = 30
        td2 = 600
        terf = 1.2
        tefficacy = 1.13

        helper = self.tmodel(
            q1=tq1 * ur("delta_degC/(W/m^2)"),
            q2=tq2 * ur("delta_degC/(W/m^2)"),
            d1=td1 * ur("yr"),
            d2=td2 * ur("yr"),
            efficacy=tefficacy * ur("dimensionless"),
        )
        helper_twolayer = TwoLayerModel(**helper.get_two_layer_parameters())

        gh = _calculate_geoffroy_helper_parameters(
            helper_twolayer.du,
            helper_twolayer.dl,
            helper_twolayer.lambda0,
            helper_twolayer.efficacy,
            helper_twolayer.eta,
        )
        # see notebook for discussion of why this is so
        efficacy_term = (helper_twolayer.eta * (helper_twolayer.efficacy - 1) *
                         (((1 - gh["phi1"]) * ttemp1 * ur("delta_degC")) +
                          ((1 - gh["phi2"]) * ttemp_2 * ur("delta_degC"))))

        expected = (terf * ur(helper._erf_unit) -
                    ((ttemp1 + ttemp_2) * ur(helper._temp1_unit)) *
                    helper_twolayer.lambda0 - efficacy_term)
        assert str(expected.units) == "watt / meter ** 2"

        res = helper._calculate_next_rndt(ttemp1, ttemp_2, terf, tefficacy)

        npt.assert_allclose(res, expected.magnitude)

        # check internal units make sense
        check_same_unit(self.tmodel._q1_unit, self.tmodel._q2_unit)
        check_same_unit(helper_twolayer._lambda0_unit,
                        (1.0 * ur(self.tmodel._q2_unit)**-1))
        check_same_unit(
            self.tmodel._erf_unit,
            ((1.0 * ur(self.tmodel._temp1_unit) /
              (1.0 * ur(self.tmodel._q1_unit))).units),
        )
        check_same_unit(
            self.tmodel._erf_unit,
            efficacy_term.units,
        )