def test_PWCModelRunFD(self): times = self.smr.times xs, gross_Us, gross_Fs, gross_Rs \ = self.smr.fake_gross_discretized_output(times) pwc_mr_fd = PWCModelRunFD.from_gross_fluxes(self.smr.model.time_symbol, times, self.smr.start_values, gross_Us, gross_Fs, gross_Rs) meths = [ "solve", "acc_gross_external_input_vector", "acc_net_external_input_vector", "acc_gross_external_output_vector", "acc_net_external_output_vector", "acc_gross_internal_flux_matrix", "acc_net_internal_flux_matrix" ] for meth in meths: with self.subTest(): ref = getattr(self.smr, meth)() res = getattr(pwc_mr_fd, meth)() self.assertTrue( np.allclose(ref, res, rtol=3e-02) # For this linear constant model # the error should actually be zero # and is only due to numerical inaccuracy. ) plot_stocks_and_fluxes([self.smr, pwc_mr_fd], 'stocks_and_fluxes.pdf')
def load_us(self): out = self.load_xs_Us_Fs_Rs() xs, Us, Fs, Rs = out times = self.time_agg.data.filled() nr_pools = self.model_structure.nr_pools data = np.nan * np.ones((len(times), nr_pools)) try: us = PWCMRFD.reconstruct_us( times, Us.data.filled(), ) data[:-1, ...] = us except (PWCModelRunFDError, ValueError, OverflowError) as e: error = str(e) print(error, flush=True) return data
def load_Bs(self, integration_method='solve_ivp', nr_nodes=None, check_success=True): out = self.load_xs_Us_Fs_Rs() xs, Us, Fs, Rs = out times = self.time_agg.data.filled() nr_pools = self.model_structure.nr_pools data = np.nan * np.ones((len(times), nr_pools, nr_pools)) # # try: # Bs = PWCMRFD.reconstruct_Bs( Bs, max_abs_err, max_rel_err = PWCMRFD.reconstruct_Bs( times, xs.data.filled()[0], Us.data.filled(), Fs.data.filled(), Rs.data.filled(), xs.data.filled(), integration_method, nr_nodes, check_success) data[:-1, ...] = Bs return data, max_abs_err, max_rel_err
def test_reconstruction_accuracy(self): smr = self.smr xs, gross_Us, gross_Fs, gross_Rs =\ smr.fake_gross_discretized_output(smr.times) # integration_method = 'solve_ivp' pwc_mr_fd = PWCModelRunFD.from_gross_fluxes(smr.model.time_symbol, smr.times, xs[0, :], gross_Us, gross_Fs, gross_Rs) with self.subTest(): self.assertTrue( np.allclose(smr.solve(), pwc_mr_fd.solve(), rtol=1e-03)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_external_input_vector(), pwc_mr_fd.acc_gross_external_input_vector(), rtol=1e-4)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_external_output_vector(), pwc_mr_fd.acc_gross_external_output_vector(), rtol=1e-4)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_internal_flux_matrix(), pwc_mr_fd.acc_gross_internal_flux_matrix(), rtol=1e-4)) # integration_method = 'trapezoidal' # nr_nodes = 3 result in insufficient accuracy pwc_mr_fd = PWCModelRunFD.from_gross_fluxes( smr.model.time_symbol, smr.times, xs[0, :], gross_Us, gross_Fs, gross_Rs, integration_method='trapezoidal', nr_nodes=3) with self.subTest(): self.assertFalse( np.allclose(smr.solve(), pwc_mr_fd.solve(), rtol=1e-03)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_external_input_vector(), pwc_mr_fd.acc_gross_external_input_vector(), rtol=1e-04)) with self.subTest(): self.assertFalse( np.allclose(smr.acc_gross_external_output_vector(), pwc_mr_fd.acc_gross_external_output_vector(), rtol=1e-04)) with self.subTest(): self.assertFalse( np.allclose(smr.acc_gross_internal_flux_matrix(), pwc_mr_fd.acc_gross_internal_flux_matrix(), rtol=1e-04)) # integration_method = 'trapezoidal' # nr_nodes = 3 result in insufficient accuracy pwc_mr_fd = PWCModelRunFD.from_gross_fluxes( smr.model.time_symbol, smr.times, xs[0, :], gross_Us, gross_Fs, gross_Rs, integration_method='trapezoidal', nr_nodes=151) with self.subTest(): self.assertTrue( np.allclose(smr.solve(), pwc_mr_fd.solve(), rtol=1e-03)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_external_input_vector(), pwc_mr_fd.acc_gross_external_input_vector(), rtol=1e-04)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_external_output_vector(), pwc_mr_fd.acc_gross_external_output_vector(), rtol=1e-04)) with self.subTest(): self.assertTrue( np.allclose(smr.acc_gross_internal_flux_matrix(), pwc_mr_fd.acc_gross_internal_flux_matrix(), rtol=1e-04))
def create_model_run(self, errors=False): out = self.load_xs_Us_Fs_Rs() xs, Us, Fs, Rs = out # print(self.time_agg.data) # print(xs.data) # print(Fs.data) # print(Rs.data) # print(Us.data) # input() times = self.time_agg.data.filled() # times = np.arange(len(self.time_agg.data)) if (xs.data.mask.sum() + Fs.data.mask.sum() + Us.data.mask.sum() + Rs.data.mask.sum() == 0): pwc_mr_fd = PWCMRFD.from_gross_fluxes( symbols("t"), times, xs.data.filled()[0], # xs.data.filled(), Us.data.filled(), Fs.data.filled(), Rs.data.filled(), # xs.data.filled() ) else: pwc_mr_fd = None if errors: err_dict = {} soln = pwc_mr_fd.solve() soln_pwc_mr_fd = Variable(data=soln, unit=self.stock_unit) abs_err = soln_pwc_mr_fd.absolute_error(xs) rel_err = soln_pwc_mr_fd.relative_error(xs) err_dict["stocks"] = {"abs_err": abs_err, "rel_err": rel_err} Us_pwc_mr_fd = Variable( name="acc_gross_external_input_vector", data=pwc_mr_fd.acc_gross_external_input_vector(), unit=self.stock_unit, ) abs_err = Us_pwc_mr_fd.absolute_error(Us) rel_err = Us_pwc_mr_fd.relative_error(Us) err_dict["acc_gross_external_inputs"] = { "abs_err": abs_err, "rel_err": rel_err, } Rs_pwc_mr_fd = Variable( name="acc_gross_external_output_vector", data=pwc_mr_fd.acc_gross_external_output_vector(), unit=self.stock_unit, ) abs_err = Rs_pwc_mr_fd.absolute_error(Rs) rel_err = Rs_pwc_mr_fd.relative_error(Rs) err_dict["acc_gross_external_outputs"] = { "abs_err": abs_err, "rel_err": rel_err, } Fs_pwc_mr_fd = Variable( name="acc_gross_internal_flux_matrix", data=pwc_mr_fd.acc_gross_internal_flux_matrix(), unit=self.stock_unit, ) abs_err = Fs_pwc_mr_fd.absolute_error(Fs) rel_err = Fs_pwc_mr_fd.relative_error(Fs) err_dict["acc_gross_internal_fluxes"] = { "abs_err": abs_err, "rel_err": rel_err, } return pwc_mr_fd, err_dict else: return pwc_mr_fd
sub_ds = ds.isel(lat=lat, lon=lon, prob=prob) sub_ds # + # load the corresponding model run # convert monthly time steps to daily time steps, each month comprising 31 days data_times = np.arange(len(sub_ds["time"])) * 31 start_values = sub_ds["start_values"] us = sub_ds["us"] Bs = sub_ds["Bs"] pwc_mr = PWCModelRunFD.from_Bs_and_us(symbols("t"), data_times, start_values.values, Bs[:-1], us[:-1], state_variables=sub_ds.pool.values) # - fig, ax = plt.subplots(figsize=(8, 8)) pwc_mr.model.plot_pools_and_fluxes(ax, legend=False) _ = ax.set_title("CARDAMOM") # compute the solution #soln = pwc_mr.solve() soln = sub_ds["solution"].values # + fig, axes = plt.subplots(ncols=2, nrows=3, figsize=(18, 12))
# load the corresponding model runs # convert monthly time steps to daily time steps, each month comprising 31 days data_times_m = np.arange(len(sub_ds_m["time"])) * 31 data_times_y0 = np.arange(len(sub_ds_y0["time"])) * 31 * 12 data_times_y6 = np.arange(len(sub_ds_y6["time"])) * 31 * 12 # + # monthly start_values_m = sub_ds_m["start_values"] us_m = sub_ds_m["us"] Bs_m = sub_ds_m["Bs"] pwc_mr_m = PWCModelRunFD.from_Bs_and_us(symbols("t"), data_times_m, start_values_m.values, Bs_m[:-1], us_m[:-1], state_variables=sub_ds_m.pool.values) # yearly (Jan) start_values_y0 = sub_ds_y0["start_values"] us_y0 = sub_ds_y0["us"] Bs_y0 = sub_ds_y0["Bs"] pwc_mr_y0 = PWCModelRunFD.from_Bs_and_us(symbols("t"), data_times_y0, start_values_y0.values, Bs_y0[:-1], us_y0[:-1], state_variables=sub_ds_y0.pool.values)
def func(ds_single_site): data_times = ds_single_site.times.data #.compute() start_values = ds_single_site.start_values.data #.compute() Bs = ds_single_site.Bs.data[:-1] #.compute() us = ds_single_site.us.data[:-1] #.compute() mr = PWCModelRunFD.from_Bs_and_us(symbols('t'), data_times, start_values, Bs, us) coords_time = ds_single_site.time coords_pool = ds_single_site.pool data_vars = dict() soln = mr.solve() data_vars['soln'] = xr.DataArray( data=soln, dims=['time', 'pool'], coords={ 'time': coords_time, 'pool': coords_pool }, attrs={'units': ds_single_site.start_values.attrs['units']}) mav = mr.age_moment_vector(1) / 365.25 data_vars['mean_age_vector'] = xr.DataArray(data=mav, dims=['time', 'pool'], coords={ 'time': coords_time, 'pool': coords_pool }, attrs={'units': 'yr'}) msa = mr.system_age_moment(1) / 365.25 data_vars['mean_system_age'] = xr.DataArray(data=msa, dims=['time'], coords={'time': coords_time}, attrs={'units': 'yr'}) asdv = np.sqrt(mr.age_moment_vector(2)) / 365.25 data_vars['age_standard_deviation_vector'] = xr.DataArray( data=asdv, dims=['time', 'pool'], coords={ 'time': coords_time, 'pool': coords_pool }, attrs={'units': 'yr'}) sasd = np.sqrt(mr.system_age_moment(2)) / 365.25 data_vars['system_age_standard_deviation'] = xr.DataArray( data=sasd, dims=['time'], coords={'time': coords_time}, attrs={'units': 'yr'}) res = xr.Dataset(coords={ 'time': coords_time, 'pool': coords_pool }, data_vars=data_vars) return res
def create_model_run(self, integration_method='solve_ivp', nr_nodes=None, errors=False, check_success=True): out = self.load_xs_Us_Fs_Rs() xs, Us, Fs, Rs = out # print(self.time_agg.data) # print(xs.data) # print(Fs.data) # print(Rs.data) # print(Us.data) # input() times = self.time_agg.data.filled() # times = np.arange(len(self.time_agg.data)) if (xs.data.mask.sum() + Fs.data.mask.sum() + Us.data.mask.sum() + Rs.data.mask.sum() == 0): pwc_mr_fd = PWCMRFD.from_gross_fluxes(symbols("t"), times, xs.data.filled()[0], Us.data.filled(), Fs.data.filled(), Rs.data.filled(), xs.data.filled(), integration_method, nr_nodes, check_success) else: pwc_mr_fd = None if errors: # print('Computing reconstruction errors') err_dict = {} # print(' solution error') soln = pwc_mr_fd.solve() soln_pwc_mr_fd = Variable(name="stocks", data=soln, unit=self.stock_unit) abs_err = soln_pwc_mr_fd.absolute_error(xs) rel_err = soln_pwc_mr_fd.relative_error(xs) err_dict["stocks"] = { "abs_err": abs_err.max(), "rel_err": rel_err.max() } # print(' input fluxes error') Us_pwc_mr_fd = Variable( name="acc_gross_external_input_vector", data=pwc_mr_fd.acc_gross_external_input_vector(), unit=self.stock_unit, ) abs_err = Us_pwc_mr_fd.absolute_error(Us) rel_err = Us_pwc_mr_fd.relative_error(Us) err_dict["acc_gross_external_inputs"] = { "abs_err": abs_err.max(), "rel_err": rel_err.max(), } # print(' output fluxes error') Rs_pwc_mr_fd = Variable( name="acc_gross_external_output_vector", data=pwc_mr_fd.acc_gross_external_output_vector(), unit=self.stock_unit, ) abs_err = Rs_pwc_mr_fd.absolute_error(Rs) rel_err = Rs_pwc_mr_fd.relative_error(Rs) err_dict["acc_gross_external_outputs"] = { "abs_err": abs_err.max(), "rel_err": rel_err.max(), } # print(' internal fluxes error') Fs_pwc_mr_fd = Variable( name="acc_gross_internal_flux_matrix", data=pwc_mr_fd.acc_gross_internal_flux_matrix(), unit=self.stock_unit, ) abs_err = Fs_pwc_mr_fd.absolute_error(Fs) rel_err = Fs_pwc_mr_fd.relative_error(Fs) err_dict["acc_gross_internal_fluxes"] = { "abs_err": abs_err.max(), "rel_err": rel_err.max(), } abs_err.argmax() rel_err.argmax() # print('done') return pwc_mr_fd, err_dict else: return pwc_mr_fd, dict()