def test_coords_ground_shadows(): # Create base params params = { 'axis_azimuth': 0, 'n_pvrows': 2, 'pvrow_height': 2.5, 'pvrow_width': 2., 'gcr': 0.4, 'cut': {0: {'front': 5}, 1: {'back': 3}} } # Timeseries parameters for testing solar_zenith = np.array([20., 45.]) solar_azimuth = np.array([70., 200.]) surface_tilt = np.array([10., 70.]) surface_azimuth = np.array([90., 270.]) # Plot simple ordered pv array ordered_pvarray = OrderedPVArray(**params) ordered_pvarray.fit(solar_zenith, solar_azimuth, surface_tilt, surface_azimuth) expected_gnd_shadow_coords = [ [([-1.89924929, 0.19163641], [0., 0.]), ([0.18914857, 1.51846431], [0., 0.])], [([3.10075071, 5.19163641], [0., 0.]), ([5.18914857, 6.51846431], [0., 0.])] ] gnd_shadow_coords = [shadow.coords.as_array for shadow in ordered_pvarray.ts_ground.shadows] np.testing.assert_almost_equal( expected_gnd_shadow_coords, gnd_shadow_coords)
def test_plot_ordered_pvarray(): """Test that ordered pv array plotting works correctly""" is_ci = os.environ.get('CI', False) if not is_ci: import matplotlib.pyplot as plt # Create base params params = { 'n_pvrows': 3, 'pvrow_height': 2.5, 'pvrow_width': 2., 'surface_azimuth': 90., # east oriented modules / point right 'axis_azimuth': 0., # axis of rotation towards North 'surface_tilt': 20., 'gcr': 0.4, 'solar_zenith': 20., 'solar_azimuth': 90., # sun located in the east 'rho_ground': 0.2, 'rho_front_pvrow': 0.01, 'rho_back_pvrow': 0.03 } # Plot simple ordered pv array ordered_pvarray = OrderedPVArray.transform_from_dict_of_scalars(params) f, ax = plt.subplots() ordered_pvarray.plot(ax) plt.show() # Plot discretized ordered pv array params.update({'cut': {0: {'front': 5}, 1: {'back': 3}}, 'surface_azimuth': 270.}) # point left ordered_pvarray = OrderedPVArray.transform_from_dict_of_scalars(params) f, ax = plt.subplots() ordered_pvarray.plot(ax) plt.show()
def test_coords_cut_points(): # Create base params params = { 'axis_azimuth': 0, 'n_pvrows': 2, 'pvrow_height': 2.5, 'pvrow_width': 2., 'gcr': 0.4, 'cut': {0: {'front': 5}, 1: {'back': 3}} } # Timeseries parameters for testing solar_zenith = np.array([20., 45.]) solar_azimuth = np.array([70., 200.]) surface_tilt = np.array([10., 70.]) surface_azimuth = np.array([90., 270.]) # Plot simple ordered pv array ordered_pvarray = OrderedPVArray(**params) ordered_pvarray.fit(solar_zenith, solar_azimuth, surface_tilt, surface_azimuth) expected_cut_point_coords = [ [[14.17820455, -0.90992559], [0., 0.]], [[19.17820455, 4.09007441], [0., 0.]]] cut_pt_coords = [cut_point.as_array for cut_point in ordered_pvarray.ts_ground.cut_point_coords] np.testing.assert_almost_equal( expected_cut_point_coords, cut_pt_coords)
def test_ordered_pvarray_from_dict(params): """Test that can successfully create ordered pvarray from parameters dict, and that the axis azimuth convention works correctly (via normal vector) """ pvarray = OrderedPVArray.transform_from_dict_of_scalars(params) # Test that ground is created successfully assert isinstance(pvarray.ground, PVGround) # TODO: check why this is not matching exactly: hint = look at length # of ground shaded surfaces, some small tolerance may be chipped away np.testing.assert_allclose(pvarray.ground.length, MAX_X_GROUND - MIN_X_GROUND) # Test the front and back sides assert len(pvarray.pvrows) == 3 np.testing.assert_array_equal( pvarray.pvrows[0].front.n_vector, -pvarray.pvrows[0].back.n_vector) assert pvarray.pvrows[0].front.shaded_length == 0 assert pvarray.gcr == params['gcr'] assert np.abs(pvarray.rotation_vec) == params['surface_tilt'] assert pvarray.pvrows[0].front.n_vector[0] > 0 distance_between_pvrows = \ pvarray.pvrows[1].centroid.x - pvarray.pvrows[0].centroid.x assert distance_between_pvrows == 5.0 # Orient the array the other way params.update({'surface_azimuth': 270.}) pvarray = OrderedPVArray.transform_from_dict_of_scalars(params) assert pvarray.pvrows[0].front.n_vector[0] < 0
def test_orderedpvarray_neighbors(params): """Check that pvrow neighbors are determined correctly""" pvarray_right = OrderedPVArray.from_dict(params) params.update({'surface_azimuth': 270}) pvarray_left = OrderedPVArray.from_dict(params) # Check l1 = [None, 0, 1] l2 = [1, 2, None] np.testing.assert_array_equal(pvarray_right.front_neighbors, l2) np.testing.assert_array_equal(pvarray_right.back_neighbors, l1) np.testing.assert_array_equal(pvarray_left.front_neighbors, l1) np.testing.assert_array_equal(pvarray_left.back_neighbors, l2)
def test_run_fast_and_full_modes_sequentially(params, fn_report_example): """Make sure that can run fast and full modes one after the other without making the engine crash""" # Irradiance inputs timestamps = dt.datetime(2019, 6, 11, 11) DNI = 1000. DHI = 100. # Prepare some engine inputs pvarray = OrderedPVArray.init_from_dict(params) fast_mode_pvrow_index = 1 fast_mode_segment_index = 0 # Create engine object eng = PVEngine(pvarray, fast_mode_pvrow_index=fast_mode_pvrow_index, fast_mode_segment_index=fast_mode_segment_index) # Fit engine eng.fit(timestamps, DNI, DHI, params['solar_zenith'], params['solar_azimuth'], params['surface_tilt'], params['surface_azimuth'], params['rho_ground']) # Run fast mode def fn_report(pvarray): return (pvarray.ts_pvrows[1].back.get_param_weighted('qinc')) qinc_fast = eng.run_fast_mode(fn_build_report=fn_report) # Run full mode report = eng.run_full_mode(fn_build_report=fn_report_example) np.testing.assert_allclose(qinc_fast, 119.095285) np.testing.assert_allclose(report['qinc_back'], 116.49050349491)
def fit_and_plot(data: DataFrame, pvarray_params: dict, date: Union[str, int], with_index: bool = False): "Method to debug a pvfactors pvarray, plots the model at idx" data_idx = data.loc[date] if type(date) is str else data.iloc[date] params = { 'axis_azimuth': pvarray_params['axis_azimuth'], 'gcr': pvarray_params['gcr'], 'n_pvrows': pvarray_params['n_pvrows'], 'pvrow_height': pvarray_params['pvrow_height'], 'pvrow_width': pvarray_params['pvrow_width'], 'solar_azimuth': data_idx['azimuth'], 'solar_zenith': data_idx['zenith'], 'surface_azimuth': pvarray_params['surface_azimuth'], 'surface_tilt': pvarray_params['surface_tilt'], 'cut': pvarray_params['cut'] } pvarray = OrderedPVArray.fit_from_dict_of_scalars(params) ax = plot_idx(pvarray, 0, with_index) if type(date) is int: date = data.index[date] date = f'{date.hour}h {date.day} {date.month_name()[0:3]} {date.year}' ax.set_title(date) return pvarray
def test_fast_mode_8760(params, df_inputs_clearsky_8760): """Test fast mode with 1 PV row to make sure that is consistent after the vectorization update: should get exact same values """ # Get MET data df_inputs = df_inputs_clearsky_8760 timestamps = df_inputs.index dni = df_inputs.dni.values dhi = df_inputs.dhi.values solar_zenith = df_inputs.solar_zenith.values solar_azimuth = df_inputs.solar_azimuth.values surface_tilt = df_inputs.surface_tilt.values surface_azimuth = df_inputs.surface_azimuth.values # Run simulation for only 1 PV row params.update({'n_pvrows': 1}) # Run engine pvarray = OrderedPVArray.init_from_dict(params) eng = PVEngine(pvarray) eng.fit(timestamps, dni, dhi, solar_zenith, solar_azimuth, surface_tilt, surface_azimuth, params['rho_ground']) qinc = eng.run_fast_mode( fn_build_report=lambda pvarray: (pvarray.ts_pvrows[0].back.get_param_weighted('qinc')), pvrow_index=0) # Check than annual energy on back is consistent np.testing.assert_allclose(np.nansum(qinc) / 1e3, 342.848005)
def test_ordered_pvarray_gnd_pvrow_shadow_casting_left(params_direct_shading): params_direct_shading.update({ 'solar_azimuth': 270, 'surface_azimuth': 270 }) # Test front shading on right ordered_pvarray = OrderedPVArray.from_dict(params_direct_shading) ordered_pvarray.cast_shadows() # Check shadow casting on ground assert len(ordered_pvarray.ground.list_segments[0].shaded_collection. list_surfaces) == 1 assert len(ordered_pvarray.ground.list_segments[0].illum_collection. list_surfaces) == 2 assert ordered_pvarray.ground.length == MAX_X_GROUND - MIN_X_GROUND assert ordered_pvarray.illum_side == 'front' np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].front.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].front.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].front.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].back.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].back.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].back.shaded_length, 0.)
def test_ordered_pvarray_gnd_pvrow_shadow_casting_back(params_direct_shading): params_direct_shading.update({'solar_azimuth': 270, 'surface_tilt': 120}) # Test front shading on right ordered_pvarray = OrderedPVArray.from_dict(params_direct_shading) ordered_pvarray.cast_shadows() assert ordered_pvarray.illum_side == 'back' # Check shadow casting on ground assert len(ordered_pvarray.ground.list_segments[0].shaded_collection. list_surfaces) == 1 assert len(ordered_pvarray.ground.list_segments[0].illum_collection. list_surfaces) == 2 assert ordered_pvarray.ground.length == MAX_X_GROUND - MIN_X_GROUND # Shading length should be identical as in previous test for front surface, # but now with back surface np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].back.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].back.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].back.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].front.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].front.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].front.shaded_length, 0.)
def test_vfcalculator_aoi_methods(params): """Check that calculation of vf_aoi_matrix makes sense when using faoi function is passed: all NREL-like vfs should sum up to 1 when taking many integration points""" # Prepare pv array params.update({'cut': {0: {'front': 3}, 1: {'back': 2}}}) pvarray = OrderedPVArray.fit_from_dict_of_scalars(params) n_timestamps = 1 # Using an excessive number of integration points to prove that # calculation converges n_integration_sections = 10000 # Create vf calculator def faoi_fn(aoi_angles): return np.ones_like(aoi_angles) vfcalculator = VFCalculator( faoi_fn, faoi_fn, n_aoi_integral_sections=n_integration_sections) vfcalculator.fit(n_timestamps) vf_aoi_matrix = vfcalculator.build_ts_vf_aoi_matrix(pvarray, None) # Check that correct size assert vf_aoi_matrix.shape == (47, 47, 1) list_pvrow_idx = [] for pvrow in pvarray.ts_pvrows: tmp = [surf.index for surf in pvrow.all_ts_surfaces if surf.length[0] > 0] list_pvrow_idx += tmp summed_pvrow_vf_aoi_values = np.squeeze( np.sum(vf_aoi_matrix, axis=1)[list_pvrow_idx, :]) expected_summed_pvrow_vf_aoi_values = np.ones(9) np.testing.assert_allclose(summed_pvrow_vf_aoi_values, expected_summed_pvrow_vf_aoi_values, atol=0, rtol=1.1e-3)
def test_time_ordered_pvarray(params): # params.update({'surface_tilt': 0}) from pvfactors.viewfactors import VFCalculator import time n = 100 list_elapsed = [] for _ in range(n): tic = time.time() pvarray = OrderedPVArray.from_dict(params) pvarray.cast_shadows() # time consuming in pvarray creation pvarray.cuts_for_pvrow_view() pvarray.index_all_surfaces() # sr = pvarray.surface_registry # vm = pvarray.view_matrix vm, om = pvarray._build_view_matrix() geom_dict = pvarray.dict_surfaces calculator = VFCalculator() # number 1 time consuming, triples run time vf_matrix = calculator.get_vf_matrix(geom_dict, vm, om, pvarray.pvrows) toc = time.time() list_elapsed.append(toc - tic) print("\nAvg time elapsed: {} s".format(np.mean(list_elapsed)))
def test_fast_mode_loop_like(params): """Test value of older and decomissioned loop like fast mode""" # Prepare some engine inputs irradiance_model = HybridPerezOrdered() pvarray = OrderedPVArray.init_from_dict( params, param_names=irradiance_model.params) fast_mode_pvrow_index = 1 # Create engine object eng = PVEngine(pvarray, irradiance_model=irradiance_model, fast_mode_pvrow_index=fast_mode_pvrow_index) # Irradiance inputs timestamps = dt.datetime(2019, 6, 11, 11) DNI = 1000. DHI = 100. # Fit engine eng.fit(timestamps, DNI, DHI, params['solar_zenith'], params['solar_azimuth'], params['surface_tilt'], params['surface_azimuth'], params['rho_ground']) # Checks np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'], DNI) # Run timestep pvarray = _fast_mode_with_loop(eng.pvarray, eng.irradiance, eng.vf_calculator, fast_mode_pvrow_index, 0) # Checks assert isinstance(pvarray, OrderedPVArray) np.testing.assert_almost_equal( pvarray.pvrows[1].back.get_param_weighted('qinc'), 119.0505580124769)
def test_vfcalculator_no_aoi_functions(params): """Check that the VF calculator calculates aoi losses with diffuse reflection values when no faoi_fn is passed""" # Prepare pv array params.update({'cut': {0: {'front': 3}, 1: {'back': 2}}}) pvarray = OrderedPVArray.fit_from_dict_of_scalars(params) n_timestamps = 1 # Create calculator without faoi functions vfcalculator = VFCalculator() vfcalculator.fit(n_timestamps) # Run calculation of view factors first vf_matrix = vfcalculator.build_ts_vf_matrix(pvarray) # Make sure that the matrix was saved assert np.sum(vfcalculator.vf_matrix) > 0 # Compute reflectivity rho_mat = np.tile([0.03] * (pvarray.n_ts_surfaces + 1), (1, pvarray.n_ts_surfaces + 1, 1)).T assert rho_mat.shape == (pvarray.n_ts_surfaces + 1, pvarray.n_ts_surfaces + 1, 1) vf_aoi_matrix = vfcalculator.build_ts_vf_aoi_matrix(pvarray, rho_mat) # Check that correct size assert vf_aoi_matrix.shape == (47, 47, 1) np.testing.assert_allclose(vf_matrix * 0.97, vf_aoi_matrix)
def test_pvengine_float_inputs_perez(params): """Test that PV engine works for float inputs""" irradiance_model = HybridPerezOrdered() pvarray = OrderedPVArray.init_from_dict(params) eng = PVEngine(pvarray, irradiance_model=irradiance_model) # Irradiance inputs timestamps = dt.datetime(2019, 6, 11, 11) DNI = 1000. DHI = 100. # Fit engine eng.fit(timestamps, DNI, DHI, params['solar_zenith'], params['solar_azimuth'], params['surface_tilt'], params['surface_azimuth'], params['rho_ground']) # Checks np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'], DNI) # Run timestep pvarray = eng.run_full_mode_timestep(0) # Checks assert isinstance(pvarray, OrderedPVArray) np.testing.assert_almost_equal( pvarray.pvrows[0].front.get_param_weighted('qinc'), 1110.1164773159298) np.testing.assert_almost_equal( pvarray.pvrows[1].front.get_param_weighted('qinc'), 1110.595903991) np.testing.assert_almost_equal( pvarray.pvrows[2].front.get_param_weighted('qinc'), 1112.37717553) np.testing.assert_almost_equal( pvarray.pvrows[1].back.get_param_weighted('qinc'), 116.49050349491208)
def test_param_names(params): param_names = ['qinc'] pvarray = OrderedPVArray.transform_from_dict_of_scalars( params, param_names=param_names) # Set all surfaces parameters to 1 pvarray.update_params({'qinc': 1}) # Check that all surfaces of the correct surface params all_surfaces = pvarray.all_surfaces for surf in all_surfaces: assert surf.param_names == param_names assert surf.get_param('qinc') == 1 # Check weighted values np.testing.assert_almost_equal( pvarray.ground.get_param_weighted('qinc'), 1) np.testing.assert_almost_equal( pvarray.ground.get_param_ww('qinc'), pvarray.ground.length) for pvrow in pvarray.pvrows: # Front np.testing.assert_almost_equal( pvrow.front.get_param_weighted('qinc'), 1) np.testing.assert_almost_equal( pvrow.front.get_param_ww('qinc'), pvrow.front.length) # Back np.testing.assert_almost_equal( pvrow.back.get_param_weighted('qinc'), 1) np.testing.assert_almost_equal( pvrow.back.get_param_ww('qinc'), pvrow.back.length)
def test_ordered_pvarray_gnd_pvrow_shadow_casting_right(params_direct_shading): # Test front shading on right ordered_pvarray = OrderedPVArray.transform_from_dict_of_scalars( params_direct_shading) # Check shadow casting on ground assert len(ordered_pvarray.ground.list_segments[0] .shaded_collection.list_surfaces) == 2 assert len(ordered_pvarray.ground.list_segments[0] .illum_collection.list_surfaces) == 4 np.testing.assert_allclose(ordered_pvarray.ground.length, MAX_X_GROUND - MIN_X_GROUND) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].front.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].front.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].front.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].back.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].back.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].back.shaded_length, 0.)
def test_surface_params(params): surface_params = ['qinc'] pvarray = OrderedPVArray.from_dict(params, surface_params=surface_params) pvarray.cast_shadows() pvarray.cuts_for_pvrow_view() # Set all surfaces parameters to 1 pvarray.update_params({'qinc': 1}) # Check that all surfaces of the correct surface params all_surfaces = pvarray.all_surfaces for surf in all_surfaces: assert surf.surface_params == surface_params assert surf.get_param('qinc') == 1 # Check weighted values np.testing.assert_almost_equal(pvarray.ground.get_param_weighted('qinc'), 1) np.testing.assert_almost_equal(pvarray.ground.get_param_ww('qinc'), pvarray.ground.length) for pvrow in pvarray.pvrows: # Front np.testing.assert_almost_equal(pvrow.front.get_param_weighted('qinc'), 1) np.testing.assert_almost_equal(pvrow.front.get_param_ww('qinc'), pvrow.front.length) # Back np.testing.assert_almost_equal(pvrow.back.get_param_weighted('qinc'), 1) np.testing.assert_almost_equal(pvrow.back.get_param_ww('qinc'), pvrow.back.length)
def test_pvengine_float_inputs_iso(params): """Test that PV engine works for float inputs""" irradiance_model = IsotropicOrdered() pvarray = OrderedPVArray.init_from_dict(params) eng = PVEngine(pvarray, irradiance_model=irradiance_model) # Irradiance inputs timestamps = dt.datetime(2019, 6, 11, 11) DNI = 1000. DHI = 100. # Fit engine eng.fit(timestamps, DNI, DHI, params['solar_zenith'], params['solar_azimuth'], params['surface_tilt'], params['surface_azimuth'], params['rho_ground']) # Checks np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'], DNI) # Run timestep pvarray = eng.run_full_mode_timestep(0) # Checks assert isinstance(pvarray, OrderedPVArray) np.testing.assert_almost_equal( pvarray.pvrows[0].front.get_param_weighted('qinc'), 1099.22245374) np.testing.assert_almost_equal( pvarray.pvrows[1].front.get_param_weighted('qinc'), 1099.6948573) np.testing.assert_almost_equal( pvarray.pvrows[2].front.get_param_weighted('qinc'), 1102.76149246)
def test_pvengine_ts_inputs_perez(params_serial, df_inputs_serial_calculation, fn_report_example): """Test that PV engine works for timeseries inputs""" # Break up inputs (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, dhi) = breakup_df_inputs(df_inputs_serial_calculation) albedo = params_serial['rho_ground'] # Create engine irradiance_model = HybridPerezOrdered() pvarray = OrderedPVArray.init_from_dict( params_serial, param_names=irradiance_model.params) eng = PVEngine(pvarray, irradiance_model=irradiance_model) # Fit engine eng.fit(timestamps, dni, dhi, solar_zenith, solar_azimuth, surface_tilt, surface_azimuth, albedo) # Run all timesteps report = eng.run_full_mode(fn_build_report=fn_report_example) # Check values np.testing.assert_array_almost_equal(report['qinc_front'], [1066.272392, 1065.979824]) np.testing.assert_array_almost_equal(report['qinc_back'], [135.897106, 136.01297]) np.testing.assert_array_almost_equal(report['iso_front'], [42.816637, 42.780206]) np.testing.assert_array_almost_equal(report['iso_back'], [1.727308, 1.726535])
def test_discretization_ordered_pvarray(discr_params): pvarray = OrderedPVArray.from_dict(discr_params) pvrows = pvarray.pvrows assert len(pvrows[0].front.list_segments) == 5 assert len(pvrows[0].back.list_segments) == 1 assert len(pvrows[1].back.list_segments) == 3 assert len(pvrows[1].front.list_segments) == 2
def test_pvengine_float_inputs_perez_transparency_spacing_fast(params): """Test that module transparency and spacing are having the expected effect to calculated PV back side irradiance""" # Irradiance inputs timestamps = dt.datetime(2019, 6, 11, 11) DNI = 1000. DHI = 100. # --- with 0 transparency and spacing # Create models irr_params = {'module_transparency': 0., 'module_spacing_ratio': 0.} irradiance_model = HybridPerezOrdered(**irr_params) pvarray = OrderedPVArray.init_from_dict(params) eng = PVEngine(pvarray, irradiance_model=irradiance_model) # Fit engine eng.fit(timestamps, DNI, DHI, params['solar_zenith'], params['solar_azimuth'], params['surface_tilt'], params['surface_azimuth'], params['rho_ground']) # Run timestep def fn_report(pvarray): return (pvarray.ts_pvrows[1].back.get_param_weighted('qinc')) no_spacing_transparency_back_qinc = \ eng.run_fast_mode(fn_build_report=fn_report, pvrow_index=1) # --- with non-0 transparency and spacing # Create models irr_params = {'module_transparency': 0.1, 'module_spacing_ratio': 0.1} irradiance_model = HybridPerezOrdered(**irr_params) pvarray = OrderedPVArray.init_from_dict(params) eng = PVEngine(pvarray, irradiance_model=irradiance_model) # Fit engine eng.fit(timestamps, DNI, DHI, params['solar_zenith'], params['solar_azimuth'], params['surface_tilt'], params['surface_azimuth'], params['rho_ground']) # Run timestep w_spacing_transparency_back_qinc = \ eng.run_fast_mode(fn_build_report=fn_report, pvrow_index=1) # Checks expected_back_qinc = 134.7143531 # higher than when params are 0 np.testing.assert_almost_equal(w_spacing_transparency_back_qinc, expected_back_qinc) assert no_spacing_transparency_back_qinc < w_spacing_transparency_back_qinc
def run_pvfactors_simulation(data: DataFrame, pvarray_params: dict) -> OrderedPVArray: "Fit and run simulation" pvarray = OrderedPVArray.init_from_dict(pvarray_params) engine = PVEngine(pvarray) pvarray = engine.fit(data.index, data.dni, data.dhi, data.zenith, data.azimuth, data.surface_tilt, data.surface_azimuth, data.albedo) fn_build_report = lambda pvarray: pvarray return engine.run_full_mode(fn_build_report)
def test_ordered_pvarray_gnd_shadow_casting(params): """Test shadow casting on ground, no inter-row shading""" # Test front shading on right ordered_pvarray = OrderedPVArray.transform_from_dict_of_scalars(params) # Check shadow casting on ground assert len(ordered_pvarray.ground.list_segments[0] .shaded_collection.list_surfaces) == 3 assert len(ordered_pvarray.ground.list_segments[0] .illum_collection.list_surfaces) == 7 assert ordered_pvarray.ground.shaded_length == 6.385066634855473
def test_ordered_pvarray_gnd_pvrow_shadow_casting_back_n_seg( params_direct_shading): params_direct_shading.update({ 'cut': { 1: { 'back': 7 } }, 'solar_azimuth': 270, 'surface_tilt': 120 }) # Test front shading on right ordered_pvarray = OrderedPVArray.from_dict(params_direct_shading) ordered_pvarray.cast_shadows() # Check shadow casting on ground assert len(ordered_pvarray.ground.list_segments[0].shaded_collection. list_surfaces) == 1 assert len(ordered_pvarray.ground.list_segments[0].illum_collection. list_surfaces) == 2 assert ordered_pvarray.ground.length == MAX_X_GROUND - MIN_X_GROUND assert ordered_pvarray.illum_side == 'back' # Shading length should be identical as in previous test for front surface, # but now with back surface np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].back.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].back.shaded_length, 0.33333333333333254) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].back.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[2].front.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[1].front.shaded_length, 0.) np.testing.assert_almost_equal( ordered_pvarray.pvrows[0].front.shaded_length, 0.) # Test individual segments center_row = ordered_pvarray.pvrows[1] list_pvsegments = center_row.back.list_segments fully_shaded_segment = list_pvsegments[-1] partial_shaded_segment = list_pvsegments[-2] assert fully_shaded_segment.illum_collection.is_empty np.testing.assert_almost_equal( fully_shaded_segment.shaded_collection.length, list_pvsegments[0].length) assert partial_shaded_segment.shaded_collection.length > 0 assert partial_shaded_segment.illum_collection.length > 0 sum_lengths = (partial_shaded_segment.illum_collection.length + partial_shaded_segment.shaded_collection.length) np.testing.assert_almost_equal(sum_lengths, list_pvsegments[0].length)
def test_view_matrix_flat(params): # Make flat params.update({'surface_tilt': 0}) # Create pvarray pvarray = OrderedPVArray.transform_from_dict_of_scalars(params) # Build view matrix vm = pvarray.view_matrix assert vm.shape[0] == pvarray.n_surfaces + 1 np.testing.assert_array_equal(vm, vm_flat_orderedpvarray)