Rooftop Solar Assessment¶
Distributed rooftop photovoltaic potential analysis and adoption modeling for building stocks. Access via Workflows > Rooftop Solar Assessment.
The wizard evaluates rooftop PV deployment at the individual building level, combining geospatial building footprint data, solar resource databases, and panel performance models to compute per-building and aggregated PV potential. It then projects technology adoption over time using four complementary diffusion models, and feeds the selected adoption trajectory into the ESFEX optimizer as a time-varying virtual generator. The methodology follows rooftop suitability assessment practices [55] and distributed generation adoption modeling [54], with cost assumptions from [48] and diffusion dynamics from [53].
The analysis engine is provided by the rooftex library for building-level PV assessment and the esfex.models.adoption_models module for adoption curve generation.
The wizard is organized in two phases:
- Phase A (Steps 1-5): Rooftop Potential. Define the geographic domain, fetch building and solar data, configure panel and roof parameters, run the per-building analysis, and review results.
- Phase B (Steps 6-9): Adoption Modeling & Integration. Gather macroeconomic data, run four adoption models (logistic, Bass, techno-economic, agent-based), compare scenarios, and apply the selected curve to the ESFEX model.
Phase A -- Rooftop Potential Assessment¶
Step 1: Domain Definition¶
Define the geographic bounding box that covers the area of interest.
Two input methods:
- Draw on map: Click "Draw Rectangle", then click and drag directly on the map. The wizard minimizes itself so the full map is visible during drawing. Once the rectangle is completed, the wizard restores itself and displays the captured coordinates.
- Manual entry: Enter South latitude, North latitude, West longitude, and East longitude directly in the coordinate spinboxes (6 decimal places). Click "Apply" to validate.
The wizard displays the approximate domain area in km squared, computed using spherical distance:
where \(\bar{\phi} = (\phi_S + \phi_N)/2\) is the midpoint latitude.
Show on Map: After coordinates are set, click to visualize the domain rectangle on the map and fit the view to its extent.
Tips:
- The domain should cover the urban or peri-urban area where rooftop PV deployment is being assessed. Larger domains require longer data fetching and analysis times.
- North must be greater than South, and East must be greater than West.
Step 2: Data Sources¶
Fetch building footprint and solar resource data from external databases. Both datasets must be successfully loaded before proceeding to the next step.
Building footprints:
| Source | Description |
|---|---|
| Overture Maps | Open dataset with global building footprints. Best coverage in urban areas. |
| Microsoft ML Buildings | Machine learning-derived footprints from satellite imagery. Over 1.2 billion buildings worldwide. |
| Google Open Buildings | Google's ML-derived dataset. Best coverage in Africa, South/Southeast Asia, and Latin America. |
Click Fetch Buildings to download building footprints within the domain. The operation runs in a background thread with a progress bar. The status displays the total number of buildings retrieved and the fraction with height data (needed for shading analysis). Buildings with height information enable more accurate inter-building shading estimation.
Solar resource:
| Source | API Key Required | Description |
|---|---|---|
| PVGIS | No | EU Joint Research Centre Photovoltaic Geographical Information System. Covers Europe, Africa, and parts of Asia. |
| NSRDB | Yes | NREL National Solar Radiation Database. Covers the Americas and parts of South Asia. |
Select a reference year (2005-2024, default 2022) and click Fetch Solar Data to download hourly solar resource data (GHI, DNI, DHI) for the domain center. When NSRDB is selected, an API key text field appears -- enter your NREL API key (available at developer.nrel.gov).
Tips:
- Overture Maps provides the most consistent global coverage. Use Microsoft ML Buildings when Overture has sparse data in your region.
- PVGIS does not require authentication and is the easiest option for European, African, and Asian locations. Use NSRDB for the Americas.
- The reference year should be a recent year with typical weather conditions. Avoid years with unusual cloud patterns or extreme events.
Step 3: Panel & Roof Configuration¶
Configure PV panel specifications, roof suitability criteria, and shading analysis parameters. All fields have sensible defaults and can be adjusted to reflect available module technology and local building characteristics.
Panel specifications:
| Parameter | Range | Default | Unit | Description |
|---|---|---|---|---|
| Module efficiency | 5-50% | 21% | fraction | PV cell conversion efficiency under standard test conditions. Commercial crystalline silicon modules are typically 17-23%. |
| Module power | 100-800 | 400 | W | Nominal power output per module under STC. |
| Module area | 0.5-5.0 | 2.0 | m squared | Physical area of one PV module. |
| Performance ratio | 50-99% | 80% | fraction | System-level derating factor accounting for inverter losses, wiring, soiling, and thermal effects. Rooftop systems are typically 75-85% [48]. |
| System losses | 0-50% | 14% | fraction | Additional losses from mismatch, aging, and availability. Combined with PR for total derate. |
Roof suitability:
| Parameter | Range | Default | Unit | Description |
|---|---|---|---|---|
| Suitable fraction | 5-100% | 30% | fraction | Fraction of total roof area usable for PV panels, accounting for obstructions, setbacks, vents, and unfavorable orientations [55]. Typical range: 20-50%. |
| Min building area | 1-500 | 20 | m squared | Buildings with footprint area smaller than this threshold are excluded as too small for viable PV installation. |
| Default tilt | 0-60 | 0 (auto) | degrees | Panel tilt angle. When set to 0, the wizard auto-computes the optimal tilt as the absolute value of the site latitude (rule of thumb for annual yield maximization). |
| Default azimuth | 0-360 | 180 | degrees | Panel azimuth. 180 degrees is south-facing (optimal in the northern hemisphere). The wizard automatically adjusts to 0 degrees (north-facing) for southern hemisphere locations. |
Shading analysis:
| Parameter | Range | Default | Unit | Description |
|---|---|---|---|---|
| Enable shading | -- | On | -- | When enabled, the analysis computes inter-building shading losses using building heights and solar position throughout the year. Requires buildings with height data. |
| Search radius | 10-500 | 50 | m | Maximum distance to consider neighboring buildings as potential shadow casters. Larger radii improve accuracy but increase computation time. |
Tips:
- For flat commercial rooftops, increase the suitable fraction to 40-50%. For pitched residential roofs, 20-30% is more realistic.
- Setting default tilt to 0 (auto) provides a good estimate. Override for specific installation scenarios such as flat-roof ballasted systems (typically 10-15 degrees).
- Disable shading analysis for rapid preliminary assessments or when building height data is unavailable.
Step 4: Analysis¶
Click Run Analysis to execute the rooftop PV assessment pipeline. The wizard displays a configuration summary before starting, showing the number of buildings, solar data source, panel parameters, and roof criteria.
Analysis pipeline:
- Solar position computation: Computes hourly solar zenith and azimuth angles for the site using pvlib.
- Plane-of-array irradiance: Decomposes global, direct, and diffuse irradiance onto the tilted module surface using the isotropic transposition model.
- Building filtering: Excludes buildings with usable roof area (footprint area times suitable fraction) below the minimum area threshold.
- Module fitting: Calculates how many modules fit on each building's usable roof area: \(n = A_{\text{usable}} / A_{\text{module}}\).
- Shading analysis: (If enabled) For each building, identifies taller neighbors within the search radius. Samples 36 representative solar positions across the year and estimates shadow reach using simplified geometry (see RSP-8). The shading factor reduces the building's annual yield proportionally.
- Per-building yield: Computes annual energy yield per building as the product of POA irradiance, module efficiency, usable area, performance ratio, system loss factor, and shading factor (see RSP-2).
- Aggregation: Sums per-building results into total capacity (kWp), annual yield (MWh/yr), average capacity factor, and average specific yield.
The analysis runs on a background thread with a progress bar and real-time log output. A Cancel button is available for interruption. Upon completion, the log displays summary statistics.
Tips:
- For domains with thousands of buildings, the analysis may take several minutes. The progress bar updates every 100 buildings.
- Buildings without height data still receive PV capacity estimates but are excluded from the shading calculation.
Step 5: Results¶
Summary statistics and export options for the completed analysis.
Summary statistics:
| Metric | Description |
|---|---|
| Total Buildings | Number of buildings in the domain |
| Suitable Buildings | Number of buildings meeting the minimum area and suitability criteria |
| Total Usable Roof Area | Aggregated usable roof area across all suitable buildings (m squared) |
| Total Installed Capacity | Aggregated PV nameplate capacity (kWp) |
| Annual Energy Yield | Total expected annual energy production (MWh/yr) |
| Average Capacity Factor | Mean ratio of actual output to nameplate capacity across all suitable buildings (%) |
| Average Specific Yield | Mean energy production per unit capacity (kWh/kWp/yr). Typical range: 1,000-1,800 depending on location and climate. |
Actions:
| Action | Description |
|---|---|
| Show on Map | Display suitable buildings on the map as a color-coded GeoJSON overlay. Per-building capacity (kW), annual yield (kWh), specific yield, usable roof area, and shading loss are accessible by hovering. Buildings are reprojected to WGS84 for display. |
| Export GeoJSON | Save the full building-level results as a georeferenced GeoJSON file, including geometry, capacity, yield, specific yield, roof area, shading loss, and suitability flag. |
| Export CSV | Save a tabular summary with one row per building: building_id, usable_roof_area_m2, capacity_kw, annual_kwh, specific_yield_kwh_kwp, shading_loss, suitable. |
Phase B -- Adoption Modeling & Integration¶
Step 6: Macroeconomic Data¶
Fetch and configure macroeconomic parameters that drive the adoption models. Data can be auto-fetched by country or entered manually.
Country detection:
Click Detect to auto-identify the country from the domain bounding box (reverse geocoding). Alternatively, enter the ISO-3 country code directly (e.g., CUB, USA, DEU).
Auto-fetch: Click Fetch All to query three data sources in parallel background threads:
| Source | Data Retrieved |
|---|---|
| World Bank | GDP per capita (USD), urbanization rate (%), population |
| IMF | GDP growth rate, inflation rate |
| IRENA | PV system cost ($/kW), cost learning trajectory [48] |
Fetched values populate the form fields automatically. If any source fails, partial results are still applied and the status indicates which sources encountered errors.
Editable parameters:
| Parameter | Range | Default | Unit | Description |
|---|---|---|---|---|
| GDP per capita | 100-200,000 | 5,000 | USD | Gross domestic product per capita. Higher GDP correlates with greater rooftop PV adoption. |
| Electricity tariff | 0.001-2.000 | 0.15 | $/kWh | Retail electricity price. Higher tariffs improve PV economic attractiveness. |
| PV system cost | 100-10,000 | 1,200 | $/kW | Current installed cost of rooftop PV (modules + inverter + BOS + installation). |
| Learning rate | 1-50% | 20% | fraction | Cost reduction per cumulative capacity doubling. Historical solar PV learning rate is approximately 20% [48]. |
| Urbanization | 0-100 | 75 | % | Urban population fraction. Affects the density of suitable rooftops. |
| Population | 1,000-2B | 1,000,000 | -- | Total population in the analysis region. |
| Discount rate | 1-50% | 8% | fraction | Real discount rate for economic calculations. |
| Inflation rate | -5% to 50% | 3% | fraction | Annual consumer price inflation rate. |
| GDP growth rate | -10% to 20% | 3% | fraction | Annual real GDP growth rate for macro-variable projections. |
Tips:
- Start with auto-fetched values and adjust to reflect local conditions. Official statistics may lag reality by 1-2 years.
- The electricity tariff is the single most influential parameter on adoption speed. Use the effective residential tariff (including taxes and subsidies).
- PV system cost should include all balance-of-system costs, not just module price.
Step 7: Adoption Models¶
Configure and run four adoption modeling methods. Each method projects year-by-year rooftop PV penetration from a base year to a target year, bounded by the technical maximum capacity computed in Phase A.
Time horizon:
| Setting | Range | Default | Description |
|---|---|---|---|
| Base year | 2020-2040 | 2025 | Start year for the adoption projection. |
| Target year | 2030-2080 | 2050 | End year for the adoption projection. |
Method selection: Enable or disable each of the four methods via checkboxes (all enabled by default):
- Logistic regression -- Macro-economic drivers determine adoption probability through a logistic function of GDP, tariff, PV cost, and urbanization (see RSP-4).
- Bass diffusion -- Classic innovation/imitation model [53] with external influence (innovation coefficient \(p\)) and internal influence (imitation coefficient \(q\)) (see RSP-6).
- Techno-economic -- Adoption as a sigmoid function of the gap between the electricity tariff and the levelized cost of rooftop PV, updated yearly as PV costs decline (see RSP-5).
- Agent-based model (ABM) -- Heterogeneous household agents with income-dependent discount rates, spatial neighbor effects, and stochastic awareness growth [54] (see RSP-7).
Presets: A preset selector provides three parameter configurations:
| Preset | Logistic | Bass (p, q) | Techno-Econ | ABM |
|---|---|---|---|---|
| Conservative | beta_0=-4.0, beta_policy=0.2 | p=0.02, q=0.25 | sensitivity=10 | w_econ=0.6, threshold=0.6 |
| Moderate | defaults | p=0.03, q=0.38 | sensitivity=15 | defaults |
| Aggressive | beta_0=-2.0, beta_policy=0.8 | p=0.05, q=0.50 | sensitivity=20 | w_econ=0.4, threshold=0.4 |
Validation data: Optional historical data for model calibration and visual comparison. Three input methods:
| Source | Description |
|---|---|
| Fetch IRENA | Download historical installed solar capacity for the detected country from IRENA statistics. |
| Import CSV | Load a CSV file with columns year and capacity_mw. |
| Manual input | Open a dialog with a 10-row table for typing year/capacity pairs. |
Click Run Models to execute all selected methods in a background thread. The log displays each method as it runs and the final installed capacity at the target year.
Tips:
- Run all four methods for an initial comparison, then focus on the 1-2 methods that best match validation data.
- The Bass diffusion model is well-suited when historical data is available for calibrating \(p\) and \(q\). The ABM is best when spatial clustering of adoption is important.
- Use Conservative presets for risk-averse planning and Aggressive presets for optimistic scenarios.
Step 8: Scenario Comparison¶
Compare adoption curves from all computed methods on a single chart and select one for integration.
Adoption chart:
A matplotlib line chart plots installed capacity (MW) versus year for each method, using distinct colors. The ABM curve includes a shaded confidence band (10th-90th percentile across stochastic iterations). If validation data was loaded in Step 7, observed data points are overlaid as scatter markers for visual comparison.
Curve selection:
Radio buttons list each method with its final capacity at the target year. Select the method that best represents the expected adoption trajectory. The selection determines which curve is applied to the ESFEX model in Step 9.
Summary table:
A table displays installed capacity for each method at every 5th year and the final year, enabling quick numerical comparison across scenarios.
Export options:
| Format | Content |
|---|---|
| Export PNG | Save the comparison chart as a 150 DPI PNG image. |
| Export CSV | Save all curves as a CSV file with columns: year, method_penetration, method_capacity_mw (for each method). |
Step 9: Grid Integration¶
Apply the selected adoption curve to the ESFEX model or export analysis results for external use.
Selected curve summary: Displays the chosen method name, projection period, final penetration fraction, and final installed capacity (MW).
Option A -- Apply to ESFEX Model:
Click Apply to Model to write adoption parameters into the GUI model's rooftop solar configuration. The wizard translates the adoption curve into the RooftopSolarConfig structure by:
- Extracting initial adoption (penetration at base year) and maximum adoption (penetration at target year, with low/medium/high scenarios at 0.6x, 1.0x, and 1.3x of the final value).
- Estimating the adoption rate from the slope at the curve midpoint.
- Computing per-node system counts and average system sizes from the Phase A building analysis.
- Setting system cost, performance ratio, and degradation rate from the macroeconomic and panel configuration data.
- Enabling rooftop solar simulation in the system settings.
The applied configuration creates a time-varying virtual generator in the ESFEX optimization model, where the available capacity at each planning year follows the selected adoption trajectory.
Option B -- Export Files:
| Export | Format | Content |
|---|---|---|
| Adoption Curves | CSV | All methods: year, penetration fraction, installed capacity (MW) per method. |
| Macro Data | JSON | Full macroeconomic data snapshot (GDP, tariff, costs, rates). |
| Model Parameters | JSON | Per-method fitted parameters, final penetration, and final capacity. |
| Buildings Analysis | CSV | Per-building results from Phase A: building_id, capacity_kw, annual_kwh, specific_yield, usable_roof_area, suitable. |
Mathematical Formulations¶
Specific Yield (RSP-1)¶
| Symbol | Unit | Description |
|---|---|---|
| \(Y_{\text{sp}}\) | kWh/kWp/yr | Annual energy production per unit of installed peak capacity |
| \(E_{\text{annual}}\) | kWh/yr | Total annual energy yield of the PV system |
| \(P_{\text{peak}}\) | kWp | Nameplate (peak) capacity under standard test conditions |
Specific yield is the primary metric for comparing solar resource quality across locations. Values typically range from 1,000 kWh/kWp/yr in northern Europe to 1,800+ kWh/kWp/yr in sunbelt regions.
Building PV Capacity (RSP-2)¶
| Symbol | Unit | Description |
|---|---|---|
| \(P_b\) | kW | PV capacity installable on building \(b\) |
| \(A_{\text{roof}}\) | m squared | Building footprint area |
| \(f_{\text{suitable}}\) | -- | Fraction of roof area usable for PV (0-1). Accounts for setbacks, vents, HVAC, skylights, and unfavorable orientations [55]. |
| \(A_{\text{module}}\) | m squared | Physical area of one PV module |
| \(P_{\text{module}}\) | kW | Rated power of one PV module |
The suitable fraction \(f_{\text{suitable}}\) is the key parameter governing how much of a building's total roof area can actually host PV panels. Studies report values of 0.22-0.50 depending on building type, with 0.30 as a reasonable central estimate for mixed urban building stocks [55].
Annual Energy Yield (RSP-3)¶
| Symbol | Unit | Description |
|---|---|---|
| \(E_b\) | kWh/yr | Annual energy yield of building \(b\) |
| \(I_{\text{POA}}\) | kWh/m squared/yr | Annual plane-of-array irradiation (sum of hourly values) |
| \(\eta_{\text{module}}\) | -- | Module conversion efficiency (fraction) |
| \(A_{\text{usable}}\) | m squared | Usable roof area: \(A_{\text{roof}} \times f_{\text{suitable}}\) |
| \(PR\) | -- | Performance ratio: system-level derating for inverter, wiring, thermal, and soiling losses |
| \(L_{\text{sys}}\) | -- | System losses fraction (mismatch, aging, availability) |
| \(L_{\text{shade}}\) | -- | Shading loss fraction from inter-building shadows (see RSP-8) |
The performance ratio \(PR\) captures the gap between ideal module output and real system output. It is the most commonly used quality metric for PV installations, with values of 0.75-0.85 typical for well-designed rooftop systems [48].
Logistic Adoption (RSP-4)¶
where
| Symbol | Default | Description |
|---|---|---|
| \(K\) | from Phase A | Technical maximum rooftop capacity (MW) |
| \(\beta_0\) | -3.0 | Intercept (baseline propensity) |
| \(\beta_{\text{GDP}}\) | 0.00005 | GDP per capita coefficient (higher GDP promotes adoption) |
| \(\beta_{\text{tariff}}\) | 8.0 | Electricity tariff coefficient (higher tariff promotes adoption) |
| \(\beta_{\text{cost}}\) | -0.001 | PV system cost coefficient (higher cost discourages adoption) |
| \(\beta_{\text{urban}}\) | 0.02 | Urbanization coefficient |
| \(\beta_{\text{policy}}\) | 0.5 | Policy incentive factor |
Macro-economic variables are projected forward at each year: GDP grows at the configured growth rate, tariffs escalate at half the inflation rate, and PV cost declines at approximately 4% per year (or follows the IRENA trajectory if available).
Techno-Economic Adoption (RSP-5)¶
where
| Symbol | Default | Unit | Description |
|---|---|---|---|
| \(\alpha\) | 15.0 | 1/($/kWh) | Price sensitivity: steepness of the sigmoid response to the tariff-LCOE gap |
| \(\tau(t)\) | -- | $/kWh | Retail electricity tariff at year \(t\) |
| \(C_{\text{PV}}(t)\) | -- | $/kW | PV system cost at year \(t\) |
| \(r\) | 0.08 | -- | Discount rate |
| \(n\) | 25 | years | System lifetime |
| \(Y_{\text{sp}}\) | -- | kWh/kWp/yr | Specific yield (irradiance times performance ratio) |
| \(\delta\) | 0.005 | 1/yr | Annual panel degradation rate |
Adoption follows a sigmoid function of the gap between the electricity tariff and the PV levelized cost. As PV costs decline over time (learning curve), the gap widens and adoption accelerates. When \(\tau > LCOE\), rooftop PV is economically attractive, driving the sigmoid past 50% penetration.
Bass Diffusion (RSP-6)¶
| Symbol | Default | Description |
|---|---|---|
| \(p\) | 0.03 | Innovation coefficient (external influence: advertising, policy, media). Typical range for energy technologies: 0.01-0.05. |
| \(q\) | 0.38 | Imitation coefficient (internal influence: word-of-mouth, neighbor effects). Typical range: 0.20-0.50 [53]. |
| \(K\) | from Phase A | Market potential (maximum capacity, MW) |
The Bass model [53] captures the classic S-curve dynamics of technology diffusion: early adoption driven by innovators (coefficient \(p\)), followed by acceleration as imitators adopt through social influence (coefficient \(q\)). The ratio \(q/p\) determines the asymmetry of the S-curve. If an initial penetration is specified (e.g., 1%), the model solves for the time offset \(t_0\) such that \(F(t_0)\) matches the initial value.
ABM Adoption Probability (RSP-7)¶
Each agent \(a\) evaluates a weighted utility function at each time step:
Agent \(a\) adopts when \(U_a(t) > \theta_a\), where \(\theta_a\) is a stochastic threshold drawn from \(\mathcal{N}(\theta, 0.05)\).
Economic component:
where \(LCOE_a\) uses the agent's personal discount rate, derived from income: \(r_a = r \cdot \bar{I} / I_a\), clipped to [0.02, 0.30]. Lower-income agents have higher personal discount rates, reflecting limited access to capital.
Social component:
Neighbor proximity is computed using a kd-tree spatial index. The neighbor radius (default 1 km) determines the spatial range of peer influence.
Awareness component:
Awareness follows a logistic growth curve (slow at first, then accelerating), reflecting growing public familiarity with rooftop PV technology over time.
| Parameter | Default | Description |
|---|---|---|
| \(w_{\text{econ}}\) | 0.5 | Weight for economic utility |
| \(w_{\text{social}}\) | 0.3 | Weight for social (peer) utility |
| \(w_{\text{aware}}\) | 0.2 | Weight for awareness utility |
| \(\theta\) | 0.5 | Adoption threshold (mean) |
| \(n_{\text{agents}}\) | 1,000 | Number of household agents |
| \(n_{\text{iter}}\) | 20 | Stochastic iterations for confidence bounds |
| Neighbor radius | 1.0 km | Spatial range for peer effects |
Agents' incomes are drawn from \(\mathcal{N}(\bar{I}, 0.5\bar{I})\) clipped to \([0.1\bar{I}, 5\bar{I}]\). The model runs \(n_{\text{iter}}\) iterations; penetration is reported as the mean, with 10th and 90th percentile confidence bounds [54].
Shading Loss Factor (RSP-8)¶
where \(N_{\text{sampled}} = 36\) representative solar positions (12 months times 3 hours per day) are evaluated. For each sample, shadow geometry is computed:
| Symbol | Description |
|---|---|
| \(L_{\text{shade}}\) | Fraction of sampled time steps where the building is shaded (0-1) |
| \(h_{\text{neighbor}}\) | Height of the neighboring (taller) building (m) |
| \(h_{\text{building}}\) | Height of the target building (m) |
| \(\alpha_{\text{solar}}\) | Solar elevation angle (degrees) |
| \(S_{\text{length}}\) | Horizontal shadow length cast by the height difference (m) |
A building is considered shaded at a given time step if a taller neighbor within the search radius casts a shadow whose length exceeds the inter-building distance and whose direction (opposite to the solar azimuth) aligns with the target building (dot product > 0.5). Only buildings taller by at least 1 meter are considered.
Scripting¶
All wizard computations are available as Python functions for batch processing and Jupyter notebooks:
from esfex.visualization.workflows.solar_analysis import (
AnalysisConfig,
SolarRooftopAnalyzer,
)
from esfex.models.adoption_models import (
MacroeconomicData,
run_logistic_adoption,
run_bass_diffusion,
run_techno_economic,
run_abm_adoption,
fit_adoption_to_rooftop_config,
)
# Phase A: Rooftop potential (requires buildings GeoDataFrame and solar data)
config = AnalysisConfig(
module_efficiency=0.21,
module_power_w=400,
module_area_m2=2.0,
performance_ratio=0.80,
system_losses=0.14,
suitable_fraction=0.30,
min_building_area_m2=20.0,
enable_shading=True,
shading_search_radius_m=50.0,
)
# Phase B: Adoption modeling
macro = MacroeconomicData(
country_iso="CUB",
gdp_per_capita=9500.0,
electricity_tariff=0.12,
pv_system_cost=1100.0,
urbanization_pct=77.0,
population=11_000_000,
discount_rate=0.08,
)
max_mw = 150.0 # from Phase A analysis summary
logistic = run_logistic_adoption(macro, max_mw, base_year=2025, target_year=2050)
bass = run_bass_diffusion(max_mw, base_year=2025, target_year=2050, p=0.03, q=0.38)
techno = run_techno_economic(macro, max_mw, avg_irradiance_kwh_m2=1700.0)
abm = run_abm_adoption(macro, max_mw, n_agents=2000, n_iterations=30)
for curve in [logistic, bass, techno, abm]:
print(f"{curve.method}: {curve.capacity_mw[-1]:.1f} MW by {curve.years[-1]}")
# Integration: convert curve to ESFEX rooftop config
config_dict = fit_adoption_to_rooftop_config(
curve=bass,
macro=macro,
num_nodes=1,
systems_per_node=[5000],
avg_system_size=[5.2],
)
print(f"Adoption rate (medium): {config_dict['adoption_rates']['medium']:.3f}")
See the Adoption Models API and Solar Analysis API for full parameter documentation.