Module Models

Overview

Introduction PV module models are mathematical representations of how a photovoltaic module converts irradiance and temperature into electrical output (current, voltage, and power). In practical system modeling, the module model is the layer that connects weather and geometry inputs to AC energy estimates, clipping risk, degradation analysis, and financial forecasts. The most common physical framework is the single-diode model, which approximates PV cell behavior with a current source, a diode, and parasitic resistances. In production workflows, these equations are widely implemented through pvlib-python, and this category exposes key pvlib methods in spreadsheet-friendly form.

This category is especially important because small modeling choices can produce large annual-energy and revenue differences. A mismatch between parameter-extraction assumptions and solver assumptions can bias maximum-power predictions. A simplified loss stack can either understate or overstate net production, especially when portfolio comparisons rely on one number like performance ratio or P50 yield. Teams that need defensible results typically separate the problem into layers: derive physically consistent model parameters, solve operating points robustly, and then apply bankable system-level derates.

The calculators in this category align to exactly that workflow. CALCPARAMS_DESOTO and CALCPARAMS_PVSYST translate irradiance and temperature into single-diode coefficients. SINGLEDIODE solves the equation to produce IV key points. MAX_POWER_POINT focuses directly on the optimal operating point, while V_FROM_I solves for voltage at a specified current. In parallel, the Sandia path uses SAPM_EFF_IRRAD to form effective irradiance and SAPM to compute key IV outputs using SAPM coefficients. Finally, PVWATTS_LOSSES converts component-level derates into a total system loss percentage. Together, these tools support both engineering-grade physical modeling and decision-grade portfolio analysis.

From a business perspective, this category supports three high-value objectives: improving forecast credibility, accelerating scenario analysis, and increasing auditability. Forecast credibility improves when assumptions are explicit and physically coherent. Scenario analysis accelerates because the calculators are modular and can be chained in tabular models. Auditability improves because each output can be traced to a specific equation family and parameter set, which is essential in lender technical reviews and internal investment committees.

When to Use It Use this category when the job is to convert irradiance and temperature into realistic module power outputs, not just to apply a single blanket derate. A typical signal that these functions are needed is when project decisions depend on thermal sensitivity, low-light behavior, row-level mismatch assumptions, or technology-specific model choices.

One common job is utility-scale yield forecasting with technology-specific detail. An analyst receives TMY weather data and module datasheet/test parameters and must estimate annual DC production under different module options (for example, mono-PERC versus thin-film). The De Soto or PVsyst parameter route is used first: CALCPARAMS_DESOTO for De Soto assumptions, or CALCPARAMS_PVSYST when PVsyst-style parameterization is preferred. Then SINGLEDIODE or MAX_POWER_POINT provides operating points for each timestep. If inverter loading ratio studies require current-constrained evaluations, V_FROM_I is used for voltage-at-current checks. This path is ideal when the question is “Which module and DC/AC configuration gives better annual and shoulder-hour performance?”

Another common job is portfolio screening where speed and comparability matter more than deep device physics. Early-stage developers often need fast, consistent assumptions across many sites before committing to detailed simulation. In that case, PVWATTS_LOSSES is used to build standardized loss stacks (soiling, wiring, mismatch, availability, and age) that are directly comparable across opportunities. This does not replace IV modeling, but it provides a normalized “net-loss layer” that supports quick go/no-go ranking and sensitivity sweeps.

A third frequent job is operations and performance diagnostics. During underperformance investigations, teams often need to test whether measured string behavior is physically plausible under current weather conditions. CALCPARAMS_DESOTO or CALCPARAMS_PVSYST computes expected single-diode parameters at the observed irradiance/temperature; SINGLEDIODE then yields expected IV landmarks. If SCADA provides operating current but not module-level voltage certainty, V_FROM_I helps estimate expected voltage behavior at that current. MAX_POWER_POINT helps isolate whether MPP tracking appears consistent with modeled capability.

This category is also used when teams adopt the Sandia modeling pathway for modules with known SAPM coefficients. SAPM_EFF_IRRAD maps POA direct/diffuse irradiance, airmass, and AOI to effective irradiance at the cell level; SAPM then computes key IV points and power. This is valuable when spectral and angle-of-incidence effects need to be captured with coefficient-based empirical detail.

In short, use this category when decisions depend on either physical consistency or transparent model decomposition. Avoid relying on a single simplified loss percentage alone when choices hinge on temperature response, recombination effects, or electrical operating constraints.

How It Works The category combines two major modeling families from pvlib: single-diode equation methods and Sandia empirical methods, plus a system-loss aggregation model. Core references are in pvlib.pvsystem.

At the center is the single-diode equation, commonly expressed as

I = I_L - I_0\left[\exp\left(\frac{V + I R_s}{nN_sV_{th}}\right)-1\right] - \frac{V + I R_s}{R_{sh}},

where I_L is photocurrent, I_0 is diode saturation current, R_s is series resistance, R_{sh} is shunt resistance, and nN_sV_{th} is the thermal/ideality term. This equation is implicit in I and V, so practical modeling requires stable numerical or semi-analytic solvers.

CALCPARAMS_DESOTO and CALCPARAMS_PVSYST do not solve the IV curve by themselves; they compute the five coefficients needed by downstream solvers at each irradiance-temperature condition. The key distinction is parameterization philosophy:

  • De Soto route (CALCPARAMS_DESOTO): widely used for physically motivated translation from reference-condition parameters to operating conditions, including bandgap temperature dependencies.
  • PVsyst route (CALCPARAMS_PVSYST): follows PVsyst-oriented assumptions, including shunt-resistance behavior and optional recombination-related terms often relevant to some thin-film behaviors.

After coefficients are known, SINGLEDIODE computes canonical IV landmarks such as I_{sc}, V_{oc}, I_{mp}, V_{mp}, and P_{mp}. MAX_POWER_POINT directly finds (I_{mp},V_{mp},P_{mp}) and can use solver options such as Brent methods for robustness. V_FROM_I inverts the relation at a specified current to retrieve voltage, useful in string-operating diagnostics and controller constraints.

For maximum power specifically, the conceptual optimization target is

P(V)=V\,I(V),\qquad V_{mp}=\arg\max_V P(V),\qquad I_{mp}=I(V_{mp}).

Because I(V) itself is governed by the implicit single-diode equation, stable root-finding is central to numerical reliability. In practice, solver choice can affect runtime and edge-case behavior more than central-case results.

The Sandia path is structured differently. SAPM_EFF_IRRAD first constructs effective irradiance from direct and diffuse POA components adjusted by spectral and incidence-angle modifiers. A simplified conceptual form is

E_e = E_b\,f_2(\text{AOI})\,f_1(AM_a) + f_d\,E_d,

where E_b and E_d are beam and diffuse POA irradiance, AM_a is absolute airmass, and the functions are coefficient-based correction terms. SAPM then uses E_e, temperature, and module coefficients to compute key IV quantities and maximum power. This coefficient-driven approach can be very effective when reliable SAPM parameter sets are available.

PVWATTS_LOSSES is not an IV solver; it is a multiplicative derate combiner used in NREL PVWatts-style workflows. If losses are L_i in percent, total retained fraction is

f_{\text{retained}}=\prod_i\left(1-\frac{L_i}{100}\right),

and total losses are

L_{\text{total}}=100\,(1-f_{\text{retained}}).

This matters because simply summing percentages can overstate losses when multiple derates are sequentially applied.

Important assumptions and checks for this category:

  • Units must remain consistent: irradiance in W/m², temperature in °C where expected by interface wrappers, and resistances in ohms.
  • Parameter provenance matters: De Soto inputs, PVsyst inputs, and SAPM coefficient sets are not interchangeable without conversion.
  • Solver settings can influence convergence speed and sometimes edge behavior near extreme operating points.
  • Loss modeling scope should be explicit: PVWATTS_LOSSES captures system-level derates, not internal IV physics.

The practical strength of this category is composability: one can chain parameter calculation, IV solving, MPP extraction, and final derating in a transparent pipeline that remains aligned with pvlib’s reference implementations.

Practical Example Consider a developer evaluating a 75 MWdc project with two module options and a financing deadline. The team needs a decision in one week: select the module that maximizes annual net revenue while controlling uncertainty in shoulder-hour performance.

Step 1: Build weather-to-module inputs. The team starts with site POA irradiance components, cell temperature estimates, and airmass series. They define module reference parameters for both candidates, including whichever parameter family is available from vendor data and third-party tests.

Step 2: Run two parallel physical pathways for cross-checking. For each hourly point, they compute single-diode coefficients via CALCPARAMS_DESOTO for one baseline and CALCPARAMS_PVSYST for a sensitivity case. This allows comparison of model-family dependence, which is useful when lenders ask about methodology robustness.

Step 3: Solve electrical operating points. They run SINGLEDIODE to obtain IV key points and MAX_POWER_POINT to verify MPP consistency in a direct solver-focused path. If a subset of hours has current-constrained conditions from plant controls, V_FROM_I computes expected voltage at those currents and flags any unrealistic operating regions.

Step 4: Execute Sandia coefficient pathway for modules with validated SAPM sets. They compute effective irradiance using SAPM_EFF_IRRAD, then derive IV/power outputs with SAPM. This creates an empirical counterpart to the single-diode route and helps determine whether module ranking is stable across modeling approaches.

Step 5: Apply system derates consistently across scenarios. The team sets a shared loss stack (soiling, mismatch, wiring, availability, and age assumptions) and computes total loss with PVWATTS_LOSSES. This ensures that differences between module scenarios are driven by module behavior rather than inconsistent derating arithmetic.

Step 6: Aggregate decision metrics. They summarize annual DC energy, clipped energy sensitivity, quarterly shoulder-hour contribution, and downside cases under high-temperature weeks. Because all pathways are modular, they can quickly isolate why one candidate outperforms: lower thermal penalty, better low-light effective irradiance response, or superior MPP stability.

Step 7: Present decision narrative. The selected module is the one that wins net-revenue weighted metrics and remains robust across De Soto/PVsyst/SAPM comparisons. The team can document assumptions at each stage and defend them in technical due diligence.

This workflow demonstrates Boardflare’s dual pillar strategy in action: physically grounded engineering calculators for model fidelity and spreadsheet-operable structures for fast commercial decision-making.

How to Choose The most reliable selection method is to choose by modeling task, then by available parameter set, then by required output granularity. The table below maps each function to its best-fit job.

Decision Need Recommended Function Best Input Context Main Output Strengths Limits / Cautions
Convert irradiance + temperature into single-diode coefficients using De Soto assumptions CALCPARAMS_DESOTO Reference single-diode parameters with De Soto-compatible terms I_L, I_0, R_s, R_{sh}, nN_sV_{th} Physically interpretable, widely used in PV modeling chains Requires consistent reference parameters; wrong provenance can bias results
Convert irradiance + temperature into single-diode coefficients using PVsyst assumptions CALCPARAMS_PVSYST PVsyst-style module parameter sets I_L, I_0, R_s, R_{sh}, nN_sV_{th} Aligns with PVsyst-oriented assumptions and variants Not interchangeable with De Soto inputs without care
Solve full IV key points from single-diode coefficients SINGLEDIODE Coefficients already computed at operating condition I_{sc},V_{oc},I_{mp},V_{mp},P_{mp},I_x,I_{xx} Complete electrical snapshot in one call Solver choice and numeric conditions matter in edge cases
Extract only maximum-power operating point MAX_POWER_POINT Single-diode coefficients with optional recombination terms I_{mp},V_{mp},P_{mp} Focused MPP solution; useful for dispatch and clipping studies Less comprehensive than full IV landmark output
Compute voltage for a known operating current V_FROM_I Current target + single-diode coefficients Voltage at specified current Ideal for diagnostics and controller-constrained states Depends on realistic coefficient values and solver behavior
Convert POA components to effective irradiance in SAPM framework SAPM_EFF_IRRAD POA direct/diffuse, airmass, AOI, SAPM coefficients Effective irradiance Captures spectral and AOI modifiers in empirical form Needs credible SAPM coefficients
Compute SAPM IV points and power SAPM Effective irradiance, temperature, SAPM module coefficients IV key points and power Strong empirical pathway with established parameter sets Coefficient quality determines reliability
Combine system-level loss percentages PVWATTS_LOSSES Derate assumptions by loss component Total percent loss Fast, transparent, portfolio-comparable Not a replacement for physical IV modeling

Use this decision flow for most projects:

graph TD
    A[Start: What result is needed?] --> B{Need physical IV behavior?}
    B -- No --> C[Use PVWATTS_LOSSES for loss stack]
    B -- Yes --> D{Have SAPM coefficients?}
    D -- Yes --> E[Run SAPM_EFF_IRRAD]
    E --> F[Run SAPM]
    D -- No --> G{Have De Soto or PVsyst params?}
    G -- De Soto --> H[Run CALCPARAMS_DESOTO]
    G -- PVsyst --> I[Run CALCPARAMS_PVSYST]
    H --> J[Run SINGLEDIODE or MAX_POWER_POINT]
    I --> J
    J --> K{Need voltage at fixed current?}
    K -- Yes --> L[Run V_FROM_I]
    K -- No --> M[Use MPP/IV outputs directly]

Practical selection guidance:

  • Choose SINGLEDIODE when complete IV landmarks are required for engineering reports.
  • Choose MAX_POWER_POINT when optimization and dispatch analysis center on P_{mp} rather than full curve descriptors.
  • Choose V_FROM_I when current is known from controls or measurements and voltage must be inferred.
  • Choose SAPM_EFF_IRRAD + SAPM when a validated SAPM coefficient set exists and spectral/AOI treatment is desired.
  • Choose PVWATTS_LOSSES as a standardized derate layer, not as a substitute for module physics.

Teams usually get the best results by using both pillars together: physical model pathways for technical fidelity and standardized loss aggregation for comparability across business scenarios.

CALCPARAMS_DESOTO

This function translates reference single-diode parameters to operating conditions using the De Soto photovoltaic module model. It adjusts the light-generated current, diode saturation current, shunt resistance, and thermal-voltage term for the supplied irradiance and cell temperature while preserving the series resistance reference value.

A key relationship in the model is the irradiance and temperature adjustment of photocurrent:

I_L = \frac{G}{G_{ref}} \left(I_{L,ref} + \alpha_{sc}(T_c - T_{ref})\right)

The returned values are ordered as photocurrent, saturation current, series resistance, shunt resistance, and nN_sV_{th}. These outputs are intended to be passed directly into the single-diode solvers such as singlediode or max_power_point.

Excel Usage

=CALCPARAMS_DESOTO(effective_irradiance, temp_cell, alpha_sc, a_ref, I_L_ref, I_o_ref, R_sh_ref, R_s, EgRef, dEgdT, irrad_ref, temp_ref)
  • effective_irradiance (float, required): Irradiance converted to photocurrent (W/m^2).
  • temp_cell (float, required): Average cell temperature (C).
  • alpha_sc (float, required): Short-circuit current temp coefficient (A/C).
  • a_ref (float, required): Modified diode ideality factor term at reference (V).
  • I_L_ref (float, required): Light-generated current at reference (A).
  • I_o_ref (float, required): Diode saturation current at reference (A).
  • R_sh_ref (float, required): Shunt resistance at reference (ohms).
  • R_s (float, required): Series resistance at reference (ohms).
  • EgRef (float, optional, default: 1.121): Energy bandgap at reference temperature (eV).
  • dEgdT (float, optional, default: -0.0002677): Temperature dependence of energy bandgap (1/K).
  • irrad_ref (float, optional, default: 1000): Reference irradiance (W/m^2).
  • temp_ref (float, optional, default: 25): Reference cell temperature (C).

Returns (list[list]): 2D list containing [[photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth]], or an error string.

Example 1: Standard test conditions

Inputs:

effective_irradiance temp_cell alpha_sc a_ref I_L_ref I_o_ref R_sh_ref R_s EgRef dEgdT irrad_ref temp_ref
1000 25 0.004 1.5 5.5 2e-10 300 0.5 1.121 -0.0002677 1000 25

Excel formula:

=CALCPARAMS_DESOTO(1000, 25, 0.004, 1.5, 5.5, 2e-10, 300, 0.5, 1.121, -0.0002677, 1000, 25)

Expected output:

Result
5.5 2e-10 0.5 300 1.5
Example 2: Default reference constants

Inputs:

effective_irradiance temp_cell alpha_sc a_ref I_L_ref I_o_ref R_sh_ref R_s
1000 25 0.004 1.5 5.5 2e-10 300 0.5

Excel formula:

=CALCPARAMS_DESOTO(1000, 25, 0.004, 1.5, 5.5, 2e-10, 300, 0.5)

Expected output:

Result
5.5 2e-10 0.5 300 1.5
Example 3: Reduced irradiance and warmer cell

Inputs:

effective_irradiance temp_cell alpha_sc a_ref I_L_ref I_o_ref R_sh_ref R_s EgRef dEgdT irrad_ref temp_ref
800 45 0.004 1.5 5.5 2e-10 300 0.5 1.121 -0.0002677 1000 25

Excel formula:

=CALCPARAMS_DESOTO(800, 45, 0.004, 1.5, 5.5, 2e-10, 300, 0.5, 1.121, -0.0002677, 1000, 25)

Expected output:

Result
4.464 4.69768e-9 0.5 375 1.60062
Example 4: Cool cell at elevated irradiance

Inputs:

effective_irradiance temp_cell alpha_sc a_ref I_L_ref I_o_ref R_sh_ref R_s EgRef dEgdT irrad_ref temp_ref
1100 10 0.004 1.5 5.5 2e-10 300 0.5 1.121 -0.0002677 1000 25

Excel formula:

=CALCPARAMS_DESOTO(1100, 10, 0.004, 1.5, 5.5, 2e-10, 300, 0.5, 1.121, -0.0002677, 1000, 25)

Expected output:

Result
5.984 1.41199e-11 0.5 272.727 1.42453

Python Code

Show Code
from pvlib.pvsystem import calcparams_desoto as result_func

def calcparams_desoto(effective_irradiance, temp_cell, alpha_sc, a_ref, I_L_ref, I_o_ref, R_sh_ref, R_s, EgRef=1.121, dEgdT=-0.0002677, irrad_ref=1000, temp_ref=25):
    """
    Calculate five single-diode model parameter values using the De Soto model.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.calcparams_desoto.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        effective_irradiance (float): Irradiance converted to photocurrent (W/m^2).
        temp_cell (float): Average cell temperature (C).
        alpha_sc (float): Short-circuit current temp coefficient (A/C).
        a_ref (float): Modified diode ideality factor term at reference (V).
        I_L_ref (float): Light-generated current at reference (A).
        I_o_ref (float): Diode saturation current at reference (A).
        R_sh_ref (float): Shunt resistance at reference (ohms).
        R_s (float): Series resistance at reference (ohms).
        EgRef (float, optional): Energy bandgap at reference temperature (eV). Default is 1.121.
        dEgdT (float, optional): Temperature dependence of energy bandgap (1/K). Default is -0.0002677.
        irrad_ref (float, optional): Reference irradiance (W/m^2). Default is 1000.
        temp_ref (float, optional): Reference cell temperature (C). Default is 25.

    Returns:
        list[list]: 2D list containing [[photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth]], or an error string.
    """
    try:
        irrad = float(effective_irradiance)
        tc = float(temp_cell)
        asc = float(alpha_sc)
        ar = float(a_ref)
        ilr = float(I_L_ref)
        ior = float(I_o_ref)
        rshr = float(R_sh_ref)
        rs = float(R_s)

        eg = float(EgRef) if EgRef is not None else 1.121
        dt = float(dEgdT) if dEgdT is not None else -0.0002677
        ir = float(irrad_ref) if irrad_ref is not None else 1000.0
        tr = float(temp_ref) if temp_ref is not None else 25.0

        # Returns tuple: photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth
        res = result_func(
            effective_irradiance=irrad,
            temp_cell=tc,
            alpha_sc=asc,
            a_ref=ar,
            I_L_ref=ilr,
            I_o_ref=ior,
            R_sh_ref=rshr,
            R_s=rs,
            EgRef=eg,
            dEgdT=dt,
            irrad_ref=ir,
            temp_ref=tr
        )

        return [[float(v) for v in res]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Irradiance converted to photocurrent (W/m^2).
Average cell temperature (C).
Short-circuit current temp coefficient (A/C).
Modified diode ideality factor term at reference (V).
Light-generated current at reference (A).
Diode saturation current at reference (A).
Shunt resistance at reference (ohms).
Series resistance at reference (ohms).
Energy bandgap at reference temperature (eV).
Temperature dependence of energy bandgap (1/K).
Reference irradiance (W/m^2).
Reference cell temperature (C).

CALCPARAMS_PVSYST

This function converts PVsyst reference module parameters into the operating-condition coefficients required by the single-diode equation. It accounts for irradiance, cell temperature, the PVsyst diode-factor model, and the irradiance dependence of shunt resistance.

The thermal-voltage term returned by the model is based on the diode factor, cells in series, and cell temperature:

nN_sV_{th} = \gamma N_s \frac{k_B T_c}{q}

The five outputs are returned in the order photocurrent, saturation current, series resistance, shunt resistance, and nN_sV_{th}. These values are typically used as inputs to singlediode, max_power_point, or related IV-curve calculations.

Excel Usage

=CALCPARAMS_PVSYST(effective_irradiance, temp_cell, alpha_sc, gamma_ref, mu_gamma, I_L_ref, I_o_ref, R_sh_ref, R_sh_zero, R_s, cells_in_series, R_sh_exp, eg_ref, irrad_ref, temp_ref)
  • effective_irradiance (float, required): Irradiance converted to photocurrent (W/m^2).
  • temp_cell (float, required): Average cell temperature (C).
  • alpha_sc (float, required): Short-circuit current temp coefficient (A/C).
  • gamma_ref (float, required): Diode ideality factor (unitless).
  • mu_gamma (float, required): Temp coefficient for ideality factor (1/K).
  • I_L_ref (float, required): Light-generated current at reference (A).
  • I_o_ref (float, required): Diode saturation current at reference (A).
  • R_sh_ref (float, required): Shunt resistance at reference (ohms).
  • R_sh_zero (float, required): Shunt resistance at zero irradiance (ohms).
  • R_s (float, required): Series resistance at reference (ohms).
  • cells_in_series (int, required): Number of cells in series.
  • R_sh_exp (float, optional, default: 5.5): Exponent for shunt resistance.
  • eg_ref (float, optional, default: 1.121): Energy bandgap at reference temperature (eV).
  • irrad_ref (float, optional, default: 1000): Reference irradiance (W/m^2).
  • temp_ref (float, optional, default: 25): Reference cell temperature (C).

Returns (list[list]): 2D list containing [[photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth]], or an error string.

Example 1: PVsyst parameter calculation at standard conditions

Inputs:

effective_irradiance temp_cell alpha_sc gamma_ref mu_gamma I_L_ref I_o_ref R_sh_ref R_sh_zero R_s cells_in_series R_sh_exp eg_ref irrad_ref temp_ref
1000 25 0.005 1.1 0.001 6 1e-9 400 1000 0.3 60 5.5 1.121 1000 25

Excel formula:

=CALCPARAMS_PVSYST(1000, 25, 0.005, 1.1, 0.001, 6, 1e-9, 400, 1000, 0.3, 60, 5.5, 1.121, 1000, 25)

Expected output:

Result
6 1e-9 0.3 400 1.69571
Example 2: Default optional PVsyst constants

Inputs:

effective_irradiance temp_cell alpha_sc gamma_ref mu_gamma I_L_ref I_o_ref R_sh_ref R_sh_zero R_s cells_in_series
1000 25 0.005 1.1 0.001 6 1e-9 400 1000 0.3 60

Excel formula:

=CALCPARAMS_PVSYST(1000, 25, 0.005, 1.1, 0.001, 6, 1e-9, 400, 1000, 0.3, 60)

Expected output:

Result
6 1e-9 0.3 400 1.69571
Example 3: Warm cell with reduced irradiance

Inputs:

effective_irradiance temp_cell alpha_sc gamma_ref mu_gamma I_L_ref I_o_ref R_sh_ref R_sh_zero R_s cells_in_series R_sh_exp eg_ref irrad_ref temp_ref
750 45 0.005 1.1 0.001 6 1e-9 400 1000 0.3 60 5.5 1.121 1000 25

Excel formula:

=CALCPARAMS_PVSYST(750, 45, 0.005, 1.1, 0.001, 6, 1e-9, 400, 1000, 0.3, 60, 5.5, 1.121, 1000, 25)

Expected output:

Result
4.575 1.40654e-8 0.3 407.276 1.84236
Example 4: Cool cell at elevated irradiance

Inputs:

effective_irradiance temp_cell alpha_sc gamma_ref mu_gamma I_L_ref I_o_ref R_sh_ref R_sh_zero R_s cells_in_series R_sh_exp eg_ref irrad_ref temp_ref
1100 15 0.005 1.1 0.001 6 1e-9 400 1000 0.3 60 5.5 1.121 1000 25

Excel formula:

=CALCPARAMS_PVSYST(1100, 15, 0.005, 1.1, 0.001, 6, 1e-9, 400, 1000, 0.3, 60, 5.5, 1.121, 1000, 25)

Expected output:

Result
6.545 2.25033e-10 0.3 398.958 1.62394

Python Code

Show Code
from pvlib.pvsystem import calcparams_pvsyst as result_func

def calcparams_pvsyst(effective_irradiance, temp_cell, alpha_sc, gamma_ref, mu_gamma, I_L_ref, I_o_ref, R_sh_ref, R_sh_zero, R_s, cells_in_series, R_sh_exp=5.5, eg_ref=1.121, irrad_ref=1000, temp_ref=25):
    """
    Calculate five single-diode parameter values using the PVsyst v6 model.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.calcparams_pvsyst.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        effective_irradiance (float): Irradiance converted to photocurrent (W/m^2).
        temp_cell (float): Average cell temperature (C).
        alpha_sc (float): Short-circuit current temp coefficient (A/C).
        gamma_ref (float): Diode ideality factor (unitless).
        mu_gamma (float): Temp coefficient for ideality factor (1/K).
        I_L_ref (float): Light-generated current at reference (A).
        I_o_ref (float): Diode saturation current at reference (A).
        R_sh_ref (float): Shunt resistance at reference (ohms).
        R_sh_zero (float): Shunt resistance at zero irradiance (ohms).
        R_s (float): Series resistance at reference (ohms).
        cells_in_series (int): Number of cells in series.
        R_sh_exp (float, optional): Exponent for shunt resistance. Default is 5.5.
        eg_ref (float, optional): Energy bandgap at reference temperature (eV). Default is 1.121.
        irrad_ref (float, optional): Reference irradiance (W/m^2). Default is 1000.
        temp_ref (float, optional): Reference cell temperature (C). Default is 25.

    Returns:
        list[list]: 2D list containing [[photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth]], or an error string.
    """
    try:
        irrad = float(effective_irradiance)
        tc = float(temp_cell)
        asc = float(alpha_sc)
        gr = float(gamma_ref)
        mg = float(mu_gamma)
        ilr = float(I_L_ref)
        ior = float(I_o_ref)
        rshr = float(R_sh_ref)
        rs_v = float(R_s)
        nc = int(cells_in_series)

        rsh0 = float(R_sh_zero) if R_sh_zero is not None else 1000.0
        rexp = float(R_sh_exp) if R_sh_exp is not None else 5.5
        eg = float(eg_ref) if eg_ref is not None else 1.121
        ir = float(irrad_ref) if irrad_ref is not None else 1000.0
        tr = float(temp_ref) if temp_ref is not None else 25.0

        res = result_func(
            effective_irradiance=irrad,
            temp_cell=tc,
            alpha_sc=asc,
            gamma_ref=gr,
            mu_gamma=mg,
            I_L_ref=ilr,
            I_o_ref=ior,
            R_sh_ref=rshr,
            R_sh_0=rsh0,
            R_s=rs_v,
            cells_in_series=nc,
            R_sh_exp=rexp,
            EgRef=eg,
            irrad_ref=ir,
            temp_ref=tr
        )

        return [[float(v) for v in res]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Irradiance converted to photocurrent (W/m^2).
Average cell temperature (C).
Short-circuit current temp coefficient (A/C).
Diode ideality factor (unitless).
Temp coefficient for ideality factor (1/K).
Light-generated current at reference (A).
Diode saturation current at reference (A).
Shunt resistance at reference (ohms).
Shunt resistance at zero irradiance (ohms).
Series resistance at reference (ohms).
Number of cells in series.
Exponent for shunt resistance.
Energy bandgap at reference temperature (eV).
Reference irradiance (W/m^2).
Reference cell temperature (C).

MAX_POWER_POINT

This function finds the point on a photovoltaic IV curve where electrical power is maximized for a given set of single-diode model coefficients. It is a focused alternative to singlediode when only the maximum-power operating point is needed.

The objective is to maximize electrical power along the curve:

P = I V

The function returns the current, voltage, and power at the maximum power point as [i_{mp}, v_{mp}, p_{mp}]. Optional thin-film parameters can be provided to account for recombination effects in CdTe and amorphous-silicon models.

Excel Usage

=MAX_POWER_POINT(photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth, d_mu_tau, ns_vbi, mpp_solver)
  • photocurrent (float, required): Photo-generated current (A).
  • saturation_current (float, required): Diode reverse saturation current (A).
  • resistance_series (float, required): Series resistance (ohms).
  • resistance_shunt (float, required): Shunt resistance (ohms).
  • nNsVth (float, required): Product of ideality factor, cells in series, and thermal voltage (V).
  • d_mu_tau (float, optional, default: 0): PVsyst recombination parameter for thin-film modules (V).
  • ns_vbi (float, optional, default: 1000000): PVsyst builtin voltage parameter for thin-film modules (V).
  • mpp_solver (str, optional, default: “brentq”): Numerical solver method.

Returns (list[list]): 2D list [[i_mp, v_mp, p_mp]], or an error string.

Example 1: Standard MPP calculation

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth mpp_solver
5.5 2e-10 0.5 300 1.5 brentq

Excel formula:

=MAX_POWER_POINT(5.5, 2e-10, 0.5, 300, 1.5, "brentq")

Expected output:

Result
5.11038 29.057 148.492
Example 2: Standard MPP using Newton solver

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth mpp_solver
5.5 2e-10 0.5 300 1.5 newton

Excel formula:

=MAX_POWER_POINT(5.5, 2e-10, 0.5, 300, 1.5, "newton")

Expected output:

Result
5.11038 29.057 148.492
Example 3: Higher series resistance lowers power

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth mpp_solver
5.5 2e-10 0.9 300 1.5 brentq

Excel formula:

=MAX_POWER_POINT(5.5, 2e-10, 0.9, 300, 1.5, "brentq")

Expected output:

Result
5.06449 27.2753 138.135
Example 4: Lower shunt resistance case

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth mpp_solver
5.5 2e-10 0.5 150 1.5 brentq

Excel formula:

=MAX_POWER_POINT(5.5, 2e-10, 0.5, 150, 1.5, "brentq")

Expected output:

Result
5.01612 29.0464 145.7

Python Code

Show Code
from pvlib.pvsystem import max_power_point as result_func
import numpy as np

def max_power_point(photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth, d_mu_tau=0, ns_vbi=1000000, mpp_solver='brentq'):
    """
    Calculate the maximum power point (MPP) from single-diode equation coefficients.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.max_power_point.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        photocurrent (float): Photo-generated current (A).
        saturation_current (float): Diode reverse saturation current (A).
        resistance_series (float): Series resistance (ohms).
        resistance_shunt (float): Shunt resistance (ohms).
        nNsVth (float): Product of ideality factor, cells in series, and thermal voltage (V).
        d_mu_tau (float, optional): PVsyst recombination parameter for thin-film modules (V). Default is 0.
        ns_vbi (float, optional): PVsyst builtin voltage parameter for thin-film modules (V). Default is 1000000.
        mpp_solver (str, optional): Numerical solver method. Valid options: Newton, Brentq, Chandrupatla. Default is 'brentq'.

    Returns:
        list[list]: 2D list [[i_mp, v_mp, p_mp]], or an error string.
    """
    try:
        il = float(photocurrent)
        i0 = float(saturation_current)
        rs = float(resistance_series)
        rsh = float(resistance_shunt)
        nv = float(nNsVth)

        d2mt = float(d_mu_tau) if d_mu_tau is not None else 0.0
        nvb = float(ns_vbi) if ns_vbi is not None else np.inf
        meth = str(mpp_solver) if mpp_solver is not None else "brentq"

        res = result_func(
            photocurrent=il,
            saturation_current=i0,
            resistance_series=rs,
            resistance_shunt=rsh,
            nNsVth=nv,
            d2mutau=d2mt,
            NsVbi=nvb,
            method=meth
        )

        # res has keys: i_mp, v_mp, p_mp
        out = [float(res['i_mp']), float(res['v_mp']), float(res['p_mp'])]
        return [out]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Photo-generated current (A).
Diode reverse saturation current (A).
Series resistance (ohms).
Shunt resistance (ohms).
Product of ideality factor, cells in series, and thermal voltage (V).
PVsyst recombination parameter for thin-film modules (V).
PVsyst builtin voltage parameter for thin-film modules (V).
Numerical solver method.

PVWATTS_LOSSES

This function combines multiple PV system loss assumptions into a single total derate percentage using the PVWatts compounding-loss formulation. Each input is a percentage loss for one mechanism such as soiling, shading, mismatch, or equipment availability.

PVWatts multiplies the retained fractions for each loss component and converts the remaining derate back to a total loss percentage:

L_{total}(\%) = 100 \left[1 - \prod_i \left(1 - \frac{L_i}{100}\right)\right]

Because the model compounds retained performance, the total loss is not simply the arithmetic sum of the inputs except in very small-loss approximations.

Excel Usage

=PVWATTS_LOSSES(soiling, shading, snow, mismatch, wiring, connections, lid, nameplate_rating, age, availability)
  • soiling (float, optional, default: 2): Loss due to soiling (%).
  • shading (float, optional, default: 3): Loss due to shading (%).
  • snow (float, optional, default: 0): Loss due to snow (%).
  • mismatch (float, optional, default: 2): Loss due to mismatch (%).
  • wiring (float, optional, default: 2): Loss due to wiring (%).
  • connections (float, optional, default: 0.5): Loss due to connections (%).
  • lid (float, optional, default: 1.5): Light induced degradation (%).
  • nameplate_rating (float, optional, default: 1): Nameplate rating loss (%).
  • age (float, optional, default: 0): Loss due to age (%).
  • availability (float, optional, default: 3): Loss due to availability (%).

Returns (float): Total system losses (%), or an error string.

Example 1: Standard PVWatts default losses

Inputs:

soiling shading snow mismatch wiring connections lid nameplate_rating age availability
2 3 0 2 2 0.5 1.5 1 0 3

Excel formula:

=PVWATTS_LOSSES(2, 3, 0, 2, 2, 0.5, 1.5, 1, 0, 3)

Expected output:

14.0757

Example 2: No modeled losses

Inputs:

soiling shading snow mismatch wiring connections lid nameplate_rating age availability
0 0 0 0 0 0 0 0 0 0

Excel formula:

=PVWATTS_LOSSES(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

Expected output:

0

Example 3: Single age loss component

Inputs:

soiling shading snow mismatch wiring connections lid nameplate_rating age availability
0 0 0 0 0 0 0 0 5 0

Excel formula:

=PVWATTS_LOSSES(0, 0, 0, 0, 0, 0, 0, 0, 5, 0)

Expected output:

5

Example 4: Higher aggregate project losses

Inputs:

soiling shading snow mismatch wiring connections lid nameplate_rating age availability
5 8 1 3 2.5 1 2 1.5 1 4

Excel formula:

=PVWATTS_LOSSES(5, 8, 1, 3, 2.5, 1, 2, 1.5, 1, 4)

Expected output:

25.6764

Python Code

Show Code
from pvlib.pvsystem import pvwatts_losses as result_func

def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2, connections=0.5, lid=1.5, nameplate_rating=1, age=0, availability=3):
    """
    Implement NREL's PVWatts system loss model.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.pvwatts_losses.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        soiling (float, optional): Loss due to soiling (%). Default is 2.
        shading (float, optional): Loss due to shading (%). Default is 3.
        snow (float, optional): Loss due to snow (%). Default is 0.
        mismatch (float, optional): Loss due to mismatch (%). Default is 2.
        wiring (float, optional): Loss due to wiring (%). Default is 2.
        connections (float, optional): Loss due to connections (%). Default is 0.5.
        lid (float, optional): Light induced degradation (%). Default is 1.5.
        nameplate_rating (float, optional): Nameplate rating loss (%). Default is 1.
        age (float, optional): Loss due to age (%). Default is 0.
        availability (float, optional): Loss due to availability (%). Default is 3.

    Returns:
        float: Total system losses (%), or an error string.
    """
    try:
        l_soiling = float(soiling) if soiling is not None else 2.0
        l_shading = float(shading) if shading is not None else 3.0
        l_snow = float(snow) if snow is not None else 0.0
        l_mismatch = float(mismatch) if mismatch is not None else 2.0
        l_wiring = float(wiring) if wiring is not None else 2.0
        l_conn = float(connections) if connections is not None else 0.5
        l_lid = float(lid) if lid is not None else 1.5
        l_nameplate = float(nameplate_rating) if nameplate_rating is not None else 1.0
        l_age = float(age) if age is not None else 0.0
        l_avail = float(availability) if availability is not None else 3.0

        res = result_func(
            soiling=l_soiling,
            shading=l_shading,
            snow=l_snow,
            mismatch=l_mismatch,
            wiring=l_wiring,
            connections=l_conn,
            lid=l_lid,
            nameplate_rating=l_nameplate,
            age=l_age,
            availability=l_avail
        )

        return float(res)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Loss due to soiling (%).
Loss due to shading (%).
Loss due to snow (%).
Loss due to mismatch (%).
Loss due to wiring (%).
Loss due to connections (%).
Light induced degradation (%).
Nameplate rating loss (%).
Loss due to age (%).
Loss due to availability (%).

SAPM

This function evaluates the Sandia Photovoltaic Array Performance Model to generate the principal operating points of a module IV curve from effective irradiance, cell temperature, and a dictionary of SAPM module coefficients.

The result summarizes the curve with short-circuit current, maximum-power current and voltage, open-circuit voltage, and the auxiliary shape points I_x and I_{xx}. The peak electrical output is represented by:

P_{mp} = I_{mp} V_{mp}

Module coefficients must be supplied as a 2D list of key-value pairs, for example [["C0", 1.0], ["Isco", 6.0]]. The wrapper converts that list into the dict-like structure required by pvlib.

Excel Usage

=SAPM(effective_irradiance, temp_cell, module_params, temperature_ref, irradiance_ref)
  • effective_irradiance (float, required): Irradiance reaching the cells (W/m^2).
  • temp_cell (float, required): Cell temperature (C).
  • module_params (list[list], required): 2D list of SAPM parameters [[‘key’, value], …].
  • temperature_ref (float, optional, default: 25): Reference temperature (C).
  • irradiance_ref (float, optional, default: 1000): Reference irradiance (W/m^2).

Returns (list[list]): 2D list [[i_sc, i_mp, v_oc, v_mp, p_mp, i_x, i_xx]], or an error string.

Example 1: Standard SAPM points

Inputs:

effective_irradiance temp_cell module_params
1000 25 C0 1.012
C1 -0.012
C2 0
C3 0
Isco 6
Impo 5.5
Voco 36
Vmpo 30
Aisc 0.001
Aimp 0.0005
Bvoco -0.12
Mbvoc 0
Bvmpo -0.1
Mbvmp 0
N 1.2
Cells_in_series 60
IXO 5.8
IXXO 5.3
C4 1
C5 0
C6 1
C7 0

Excel formula:

=SAPM(1000, 25, {"C0",1.012;"C1",-0.012;"C2",0;"C3",0;"Isco",6;"Impo",5.5;"Voco",36;"Vmpo",30;"Aisc",0.001;"Aimp",0.0005;"Bvoco",-0.12;"Mbvoc",0;"Bvmpo",-0.1;"Mbvmp",0;"N",1.2;"Cells_in_series",60;"IXO",5.8;"IXXO",5.3;"C4",1;"C5",0;"C6",1;"C7",0})

Expected output:

Result
6 5.5 36 30 165 5.8 5.3
Example 2: Lower irradiance operating points

Inputs:

effective_irradiance temp_cell module_params
800 25 C0 1.012
C1 -0.012
C2 0
C3 0
Isco 6
Impo 5.5
Voco 36
Vmpo 30
Aisc 0.001
Aimp 0.0005
Bvoco -0.12
Mbvoc 0
Bvmpo -0.1
Mbvmp 0
N 1.2
Cells_in_series 60
IXO 5.8
IXXO 5.3
C4 1
C5 0
C6 1
C7 0

Excel formula:

=SAPM(800, 25, {"C0",1.012;"C1",-0.012;"C2",0;"C3",0;"Isco",6;"Impo",5.5;"Voco",36;"Vmpo",30;"Aisc",0.001;"Aimp",0.0005;"Bvoco",-0.12;"Mbvoc",0;"Bvmpo",-0.1;"Mbvmp",0;"N",1.2;"Cells_in_series",60;"IXO",5.8;"IXXO",5.3;"C4",1;"C5",0;"C6",1;"C7",0})

Expected output:

Result
4.8 4.41056 35.5872 30 132.317 4.64 4.24
Example 3: Warmer cell temperature case

Inputs:

effective_irradiance temp_cell module_params
1000 45 C0 1.012
C1 -0.012
C2 0
C3 0
Isco 6
Impo 5.5
Voco 36
Vmpo 30
Aisc 0.001
Aimp 0.0005
Bvoco -0.12
Mbvoc 0
Bvmpo -0.1
Mbvmp 0
N 1.2
Cells_in_series 60
IXO 5.8
IXXO 5.3
C4 1
C5 0
C6 1
C7 0

Excel formula:

=SAPM(1000, 45, {"C0",1.012;"C1",-0.012;"C2",0;"C3",0;"Isco",6;"Impo",5.5;"Voco",36;"Vmpo",30;"Aisc",0.001;"Aimp",0.0005;"Bvoco",-0.12;"Mbvoc",0;"Bvmpo",-0.1;"Mbvmp",0;"N",1.2;"Cells_in_series",60;"IXO",5.8;"IXXO",5.3;"C4",1;"C5",0;"C6",1;"C7",0})

Expected output:

Result
6.12 5.555 33.6 28 155.54 5.916 5.353
Example 4: Lowercase cell-series alias is accepted

Inputs:

effective_irradiance temp_cell module_params
1000 25 C0 1.012
C1 -0.012
C2 0
C3 0
Isco 6
Impo 5.5
Voco 36
Vmpo 30
Aisc 0.001
Aimp 0.0005
Bvoco -0.12
Mbvoc 0
Bvmpo -0.1
Mbvmp 0
N 1.2
cells_in_series 60
IXO 5.8
IXXO 5.3
C4 1
C5 0
C6 1
C7 0

Excel formula:

=SAPM(1000, 25, {"C0",1.012;"C1",-0.012;"C2",0;"C3",0;"Isco",6;"Impo",5.5;"Voco",36;"Vmpo",30;"Aisc",0.001;"Aimp",0.0005;"Bvoco",-0.12;"Mbvoc",0;"Bvmpo",-0.1;"Mbvmp",0;"N",1.2;"cells_in_series",60;"IXO",5.8;"IXXO",5.3;"C4",1;"C5",0;"C6",1;"C7",0})

Expected output:

Result
6 5.5 36 30 165 5.8 5.3

Python Code

Show Code
from pvlib.pvsystem import sapm as result_func
import pandas as pd

def sapm(effective_irradiance, temp_cell, module_params, temperature_ref=25, irradiance_ref=1000):
    """
    Sandia Photovoltaic Array Performance Model (SAPM) solver.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.sapm.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        effective_irradiance (float): Irradiance reaching the cells (W/m^2).
        temp_cell (float): Cell temperature (C).
        module_params (list[list]): 2D list of SAPM parameters [['key', value], ...].
        temperature_ref (float, optional): Reference temperature (C). Default is 25.
        irradiance_ref (float, optional): Reference irradiance (W/m^2). Default is 1000.

    Returns:
        list[list]: 2D list [[i_sc, i_mp, v_oc, v_mp, p_mp, i_x, i_xx]], or an error string.
    """
    try:
      def to2d(x):
        return [[x]] if not isinstance(x, list) else x

      irrad = float(effective_irradiance)
      tc = float(temp_cell)

      module_params = to2d(module_params)
      if not isinstance(module_params, list) or not all(isinstance(row, list) for row in module_params):
        return "Error: module_params must be a 2D list of key-value pairs"

      key_aliases = {
        "cells_in_series": "Cells_in_Series",
        "cells_in_Series": "Cells_in_Series",
        "Cells_in_series": "Cells_in_Series"
      }

      mod_dict = {}
      for row in module_params:
        if len(row) >= 2:
          key = str(row[0]).strip()
          key = key_aliases.get(key, key)
          val = row[1]
          try:
            val = float(val)
          except (TypeError, ValueError):
            pass
          mod_dict[key] = val

      t_ref = float(temperature_ref) if temperature_ref is not None else 25.0
      i_ref = float(irradiance_ref) if irradiance_ref is not None else 1000.0

      res = result_func(
        effective_irradiance=irrad,
        temp_cell=tc,
        module=mod_dict,
        temperature_ref=t_ref,
        irradiance_ref=i_ref
      )

      if isinstance(res, pd.DataFrame):
        row_res = res.iloc[0].to_dict()
      elif isinstance(res, dict):
        row_res = dict(res)
      else:
        # Some versions of pvlib return an OrderedDict or other mapping-like object
        # which may not implement to_dict(). Fall back to dict() conversion.
        if hasattr(res, "to_dict"):
          row_res = res.to_dict()
        else:
          try:
            row_res = dict(res)
          except Exception:
            row_res = {}

      out = [
        float(row_res.get('i_sc', 0)),
        float(row_res.get('i_mp', 0)),
        float(row_res.get('v_oc', 0)),
        float(row_res.get('v_mp', 0)),
        float(row_res.get('p_mp', 0)),
        float(row_res.get('i_x', 0)),
        float(row_res.get('i_xx', 0))
      ]
      return [out]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Irradiance reaching the cells (W/m^2).
Cell temperature (C).
2D list of SAPM parameters [['key', value], ...].
Reference temperature (C).
Reference irradiance (W/m^2).

SAPM_EFF_IRRAD

This function converts plane-of-array direct and diffuse irradiance into the effective irradiance actually absorbed by module cells under the Sandia model. It applies both a spectral adjustment based on absolute airmass and an incidence-angle modifier based on angle of incidence.

The SAPM effective irradiance relationship is:

E_e = f_1(AM_a) \left(E_b f_2(AOI) + f_d E_d\right)

Here f_1 is the spectral response polynomial, f_2 is the angle-of-incidence modifier, and f_d is the diffuse fraction coefficient. Supply the required coefficients as a 2D list of key-value pairs such as [["A0", 1.0], ["B0", 1.0], ["FD", 1.0]].

Excel Usage

=SAPM_EFF_IRRAD(poa_direct, poa_diffuse, airmass_absolute, aoi, module_params)
  • poa_direct (float, required): Direct irradiance on the plane of array (W/m^2).
  • poa_diffuse (float, required): Diffuse irradiance on the plane of array (W/m^2).
  • airmass_absolute (float, required): Absolute airmass (unitless).
  • aoi (float, required): Angle of incidence (degrees).
  • module_params (list[list], required): 2D list of SAPM coefficients [[‘key’, value], …].

Returns (float): Effective irradiance (W/m^2), or an error string.

Example 1: Standard Effective Irradiance

Inputs:

poa_direct poa_diffuse airmass_absolute aoi module_params
800 100 1.5 30 A0 1
A1 0
A2 0
A3 0
A4 0
B0 1
B1 0
B2 0
B3 0
B4 0
B5 0
FD 1

Excel formula:

=SAPM_EFF_IRRAD(800, 100, 1.5, 30, {"A0",1;"A1",0;"A2",0;"A3",0;"A4",0;"B0",1;"B1",0;"B2",0;"B3",0;"B4",0;"B5",0;"FD",1})

Expected output:

900

Example 2: Diffuse-only irradiance case

Inputs:

poa_direct poa_diffuse airmass_absolute aoi module_params
0 200 1.5 30 A0 1
A1 0
A2 0
A3 0
A4 0
B0 1
B1 0
B2 0
B3 0
B4 0
B5 0
FD 1

Excel formula:

=SAPM_EFF_IRRAD(0, 200, 1.5, 30, {"A0",1;"A1",0;"A2",0;"A3",0;"A4",0;"B0",1;"B1",0;"B2",0;"B3",0;"B4",0;"B5",0;"FD",1})

Expected output:

200

Example 3: Reduced diffuse fraction coefficient

Inputs:

poa_direct poa_diffuse airmass_absolute aoi module_params
700 100 1.5 30 A0 1
A1 0
A2 0
A3 0
A4 0
B0 1
B1 0
B2 0
B3 0
B4 0
B5 0
FD 0.8

Excel formula:

=SAPM_EFF_IRRAD(700, 100, 1.5, 30, {"A0",1;"A1",0;"A2",0;"A3",0;"A4",0;"B0",1;"B1",0;"B2",0;"B3",0;"B4",0;"B5",0;"FD",0.8})

Expected output:

780

Example 4: Spectral scaling below unity

Inputs:

poa_direct poa_diffuse airmass_absolute aoi module_params
800 100 1.5 30 A0 0.95
A1 0
A2 0
A3 0
A4 0
B0 1
B1 0
B2 0
B3 0
B4 0
B5 0
FD 1

Excel formula:

=SAPM_EFF_IRRAD(800, 100, 1.5, 30, {"A0",0.95;"A1",0;"A2",0;"A3",0;"A4",0;"B0",1;"B1",0;"B2",0;"B3",0;"B4",0;"B5",0;"FD",1})

Expected output:

855

Python Code

Show Code
from pvlib.pvsystem import sapm_effective_irradiance as result_func

def sapm_eff_irrad(poa_direct, poa_diffuse, airmass_absolute, aoi, module_params):
    """
    Calculate SAPM effective irradiance accounting for spectral and incidence losses.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.sapm_effective_irradiance.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        poa_direct (float): Direct irradiance on the plane of array (W/m^2).
        poa_diffuse (float): Diffuse irradiance on the plane of array (W/m^2).
        airmass_absolute (float): Absolute airmass (unitless).
        aoi (float): Angle of incidence (degrees).
        module_params (list[list]): 2D list of SAPM coefficients [['key', value], ...].

    Returns:
        float: Effective irradiance (W/m^2), or an error string.
    """
    try:
      def to2d(x):
        return [[x]] if not isinstance(x, list) else x

      eb = float(poa_direct)
      ed = float(poa_diffuse)
      am = float(airmass_absolute)
      ao = float(aoi)

      module_params = to2d(module_params)
      if not isinstance(module_params, list) or not all(isinstance(row, list) for row in module_params):
        return "Error: module_params must be a 2D list of key-value pairs"

      mod_dict = {}
      for row in module_params:
        if len(row) >= 2:
          key = str(row[0]).strip()
          val = row[1]
          try:
            val = float(val)
          except (TypeError, ValueError):
            pass
          mod_dict[key] = val

      res = result_func(
        poa_direct=eb,
        poa_diffuse=ed,
        airmass_absolute=am,
        aoi=ao,
        module=mod_dict
      )

      return float(res)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Direct irradiance on the plane of array (W/m^2).
Diffuse irradiance on the plane of array (W/m^2).
Absolute airmass (unitless).
Angle of incidence (degrees).
2D list of SAPM coefficients [['key', value], ...].

SINGLEDIODE

This function solves the photovoltaic single-diode equation for the principal operating points on an IV curve. It is the core electrical model used after weather and module parameters have been translated into single-diode coefficients.

The governing equation is:

I = I_L - I_0 \left[\exp\left(\frac{V + I R_s}{n N_s V_{th}}\right) - 1\right] - \frac{V + I R_s}{R_{sh}}

From those coefficients the function returns i_{sc}, v_{oc}, i_{mp}, v_{mp}, p_{mp}, i_x, and i_{xx}. Different numerical methods can be selected depending on the tradeoff between speed and convergence robustness.

Excel Usage

=SINGLEDIODE(photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth, sd_solver)
  • photocurrent (float, required): Light-generated current (A). Must be >= 0.
  • saturation_current (float, required): Diode saturation current (A). Must be > 0.
  • resistance_series (float, required): Series resistance (ohms). Must be >= 0.
  • resistance_shunt (float, required): Shunt resistance (ohms). Must be > 0.
  • nNsVth (float, required): Product of ideality factor, cells in series, and thermal voltage (V). Must be > 0.
  • sd_solver (str, optional, default: “lambertw”): Root-finding algorithm.

Returns (list[list]): 2D list [[i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx]], or an error string.

Example 1: Standard IV key points

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth sd_solver
5.5 2e-10 0.5 300 1.5 lambertw

Excel formula:

=SINGLEDIODE(5.5, 2e-10, 0.5, 300, 1.5, "lambertw")

Expected output:

Result
5.49085 36.0231 5.11038 29.057 148.492 5.43071 3.62124
Example 2: Standard IV key points using Newton solver

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth sd_solver
5.5 2e-10 0.5 300 1.5 newton

Excel formula:

=SINGLEDIODE(5.5, 2e-10, 0.5, 300, 1.5, "newton")

Expected output:

Result
5.49085 36.0231 5.11038 29.057 148.492 5.43071 3.62124
Example 3: Lower shunt resistance reduces fill factor

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth sd_solver
5.5 2e-10 0.5 150 1.5 lambertw

Excel formula:

=SINGLEDIODE(5.5, 2e-10, 0.5, 150, 1.5, "lambertw")

Expected output:

Result
5.48173 35.9893 5.01612 29.0464 145.7 5.36197 3.56516
Example 4: Higher series resistance case

Inputs:

photocurrent saturation_current resistance_series resistance_shunt nNsVth sd_solver
5.5 2e-10 0.9 300 1.5 lambertw

Excel formula:

=SINGLEDIODE(5.5, 2e-10, 0.9, 300, 1.5, "lambertw")

Expected output:

Result
5.48355 36.0231 5.06449 27.2753 138.135 5.42284 3.28872

Python Code

Show Code
from pvlib.pvsystem import singlediode as result_func

def singlediode(photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth, sd_solver='lambertw'):
    """
    Solve the single-diode equation to obtain a photovoltaic IV curve and its key operating points.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.singlediode.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        photocurrent (float): Light-generated current (A). Must be >= 0.
        saturation_current (float): Diode saturation current (A). Must be > 0.
        resistance_series (float): Series resistance (ohms). Must be >= 0.
        resistance_shunt (float): Shunt resistance (ohms). Must be > 0.
        nNsVth (float): Product of ideality factor, cells in series, and thermal voltage (V). Must be > 0.
        sd_solver (str, optional): Root-finding algorithm. Valid options: Lambert W, Newton, Brentq, Chandrupatla. Default is 'lambertw'.

    Returns:
        list[list]: 2D list [[i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx]], or an error string.
    """
    try:
        il = float(photocurrent)
        i0 = float(saturation_current)
        rs = float(resistance_series)
        rsh = float(resistance_shunt)
        nv = float(nNsVth)

        if il < 0: return "Error: photocurrent must be >= 0"
        if i0 <= 0: return "Error: saturation_current must be > 0"
        if rs < 0: return "Error: resistance_series must be >= 0"
        if rsh <= 0: return "Error: resistance_shunt must be > 0"
        if nv <= 0: return "Error: nNsVth must be > 0"

        meth = str(sd_solver) if sd_solver is not None else "lambertw"

        res = result_func(
            photocurrent=il,
            saturation_current=i0,
            resistance_series=rs,
            resistance_shunt=rsh,
            nNsVth=nv,
            method=meth
        )

        # res has keys: i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx
        out = [
            float(res['i_sc']),
            float(res['v_oc']),
            float(res['i_mp']),
            float(res['v_mp']),
            float(res['p_mp']),
            float(res['i_x']),
            float(res['i_xx'])
        ]
        return [out]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Light-generated current (A). Must be >= 0.
Diode saturation current (A). Must be > 0.
Series resistance (ohms). Must be >= 0.
Shunt resistance (ohms). Must be > 0.
Product of ideality factor, cells in series, and thermal voltage (V). Must be > 0.
Root-finding algorithm.

V_FROM_I

This function computes the device voltage corresponding to a specified operating current under the single-diode model. It is useful when a current setpoint is already known and only the matching voltage on the IV curve is required.

The calculation inverts the single-diode relationship

I = I_L - I_0 \left[\exp\left(\frac{V + I R_s}{n N_s V_{th}}\right) - 1\right] - \frac{V + I R_s}{R_{sh}}

to solve for V at the requested current. When shunt resistance is effectively infinite the solution can simplify, while finite-shunt cases use the selected numerical method.

Excel Usage

=V_FROM_I(current, photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth, vfi_solver)
  • current (float, required): Operating current (A).
  • photocurrent (float, required): Light-generated current (A).
  • saturation_current (float, required): Diode saturation current (A).
  • resistance_series (float, required): Series resistance (ohms).
  • resistance_shunt (float, required): Shunt resistance (ohms). Use a large value for infinite.
  • nNsVth (float, required): Product of ideality factor, cells in series, and thermal voltage (V).
  • vfi_solver (str, optional, default: “lambertw”): Numerical solver method.

Returns (float): The device voltage (V), or an error string.

Example 1: Voltage at typical Imp

Inputs:

current photocurrent saturation_current resistance_series resistance_shunt nNsVth vfi_solver
5.09341 5.5 2e-10 0.5 300 1.5 lambertw

Excel formula:

=V_FROM_I(5.09341, 5.5, 2e-10, 0.5, 300, 1.5, "lambertw")

Expected output:

29.151

Example 2: Voltage at zero current approximates Voc

Inputs:

current photocurrent saturation_current resistance_series resistance_shunt nNsVth vfi_solver
0 5.5 2e-10 0.5 300 1.5 lambertw

Excel formula:

=V_FROM_I(0, 5.5, 2e-10, 0.5, 300, 1.5, "lambertw")

Expected output:

36.0231

Example 3: Voltage at typical Imp using Newton solver

Inputs:

current photocurrent saturation_current resistance_series resistance_shunt nNsVth vfi_solver
5.09341 5.5 2e-10 0.5 300 1.5 newton

Excel formula:

=V_FROM_I(5.09341, 5.5, 2e-10, 0.5, 300, 1.5, "newton")

Expected output:

29.151

Example 4: Voltage at operating current with higher series resistance

Inputs:

current photocurrent saturation_current resistance_series resistance_shunt nNsVth vfi_solver
5.09341 5.5 2e-10 0.9 300 1.5 lambertw

Excel formula:

=V_FROM_I(5.09341, 5.5, 2e-10, 0.9, 300, 1.5, "lambertw")

Expected output:

27.1137

Python Code

Show Code
from pvlib.pvsystem import v_from_i as result_func

def v_from_i(current, photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth, vfi_solver='lambertw'):
    """
    Calculate device voltage at a given current for the single-diode model.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.v_from_i.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        current (float): Operating current (A).
        photocurrent (float): Light-generated current (A).
        saturation_current (float): Diode saturation current (A).
        resistance_series (float): Series resistance (ohms).
        resistance_shunt (float): Shunt resistance (ohms). Use a large value for infinite.
        nNsVth (float): Product of ideality factor, cells in series, and thermal voltage (V).
        vfi_solver (str, optional): Numerical solver method. Valid options: Lambert W, Newton, Brentq, Chandrupatla. Default is 'lambertw'.

    Returns:
        float: The device voltage (V), or an error string.
    """
    try:
        i = float(current)
        il = float(photocurrent)
        i0 = float(saturation_current)
        rs_v = float(resistance_series)
        rsh = float(resistance_shunt)
        nv = float(nNsVth)

        meth = str(vfi_solver) if vfi_solver is not None else "lambertw"

        res = result_func(
            current=i,
            photocurrent=il,
            saturation_current=i0,
            resistance_series=rs_v,
            resistance_shunt=rsh,
            nNsVth=nv,
            method=meth
        )

        return float(res)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Operating current (A).
Light-generated current (A).
Diode saturation current (A).
Series resistance (ohms).
Shunt resistance (ohms). Use a large value for infinite.
Product of ideality factor, cells in series, and thermal voltage (V).
Numerical solver method.