Tutorial 2 - Building a cable design
This tutorial demonstrates how to model a typical medium-voltage single-core power cable using the LineCableModels.jl
package. The objective is to build a complete representation of a single-core 18/30 kV cable with a 1000 mm² aluminum conductor and 35 mm² copper screen.
Tutorial outline
- Introduction
- Getting started
- Cable dimensions
- Using the cable constructors
- Core and main insulation
- Examining the cable parameters (RLC)
- Saving the cable design
- PSCAD Export
- Conclusion
Introduction
Single-core power cables have a complex structure consisting of multiple concentric layers, each with specific geometric and material properties – for example, a cable of type NA2XS(FL)2Y 18/30 is shown here. Prior to building actual transmission line models that incorporate cables as part of the transmission system, e.g. for EMT simulations, power flow, harmonics, protection studies etc., it is necessary to determine the base (or DC) electrical parameters of the cable itself.
This tutorial covers:
- Creating a detailed
CableDesign
with all its components. - Examining the main electrical parameters (R, L, C) of the cable core
ConductorGroup
and mainInsulatorGroup
. - Examining the equivalent electromagnetic properties of every
CableComponent
(core, sheath, jacket). - Saving the cable design to a
CablesLibrary
for future use. - Assigning
CableDesign
objects to aLineCableSystem
and exporting the model to PSCAD for EMT analysis.
Getting started
Load the package and set up the environment:
using DataFrames
using LineCableModels
Initialize materials library with default values:
materials_db = MaterialsLibrary(add_defaults = true)
list_materialslibrary(materials_db)
Row | name | rho | eps_r | mu_r | T0 | alpha |
---|---|---|---|---|---|---|
String | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | pe | 1.97e14 | 2.3 | 1.0 | 20.0 | 0.0 |
2 | polyacrylate | 5300.0 | 32.3 | 1.0 | 20.0 | 0.0 |
3 | semicon1 | 1000.0 | 1000.0 | 1.0 | 20.0 | 0.0 |
4 | copper | 1.7241e-8 | 1.0 | 0.999994 | 20.0 | 0.00393 |
5 | xlpe | 1.97e14 | 2.5 | 1.0 | 20.0 | 0.0 |
6 | pec | 2.22045e-16 | 1.0 | 1.0 | 20.0 | 0.0 |
7 | air | Inf | 1.0 | 1.0 | 20.0 | 0.0 |
8 | semicon2 | 500.0 | 1000.0 | 1.0 | 20.0 | 0.0 |
9 | aluminum | 2.8264e-8 | 1.0 | 1.00002 | 20.0 | 0.00429 |
# Alternatively, it can be loaded from the example file built in the previous tutorial:
load_materialslibrary!(
materials_db,
file_name = "materials_library.json",
)
Cable dimensions
The cable under consideration is a medium-voltage, stranded aluminum conductor cable with XLPE insulation, copper wire concentric screens, water-blocking tape, and PE jacket that is rated for 18/30 kV systems. This information is typically found in the cable datasheet and is fully described in the code type under standards HD 620 10C [10] or DIN VDE 0276-620 [11]:
NA2XS(FL)2Y
-----------
│ │ │ │
│ │ │ └── 2Y: Outer sheath of polyethylene (PE)
│ │ └── (FL): Longitudinal watertight protection
│ │
│ └── 2XS: XLPE insulation with screen of copper wires
└── NA: Aluminum conductor
After some research, it is found that a typical cable of this type has the following configuration:
num_co_wires = 61 # number of core wires
num_sc_wires = 49 # number of screen wires
d_core = 38.1e-3 # nominal core overall diameter
d_w = 4.7e-3 # nominal strand diameter of the core
t_sc_in = 0.6e-3 # nominal internal semicon thickness
t_ins = 8e-3 # nominal main insulation thickness
t_sc_out = 0.3e-3 # nominal external semicon thickness
d_ws = .95e-3 # nominal wire screen diameter
t_cut = 0.1e-3 # nominal thickness of the copper tape (around wire screens)
w_cut = 10e-3 # nominal width of copper tape
t_wbt = .3e-3 # nominal thickness of the water blocking tape
t_sct = .3e-3 # nominal thickness of the semiconductive tape
t_alt = .15e-3 # nominal thickness of the aluminum tape
t_pet = .05e-3 # nominal thickness of the pe face in the aluminum tape
t_jac = 2.4e-3 # nominal PE jacket thickness
The cable structure is summarized in a table for better visualization, with dimensions in milimiters:
Row | layer | thickness | diameter |
---|---|---|---|
String | Any | Float64 | |
1 | Conductor | - | 38.1 |
2 | Inner semiconductive tape | 0.3 | 38.7 |
3 | Inner semiconductor | 0.6 | 39.9 |
4 | Main insulation | 8.0 | 55.9 |
5 | Outer semiconductor | 0.3 | 56.5 |
6 | Outer semiconductive tape | 0.3 | 57.1 |
7 | Wire screen | 0.95 | 59.0 |
8 | Copper tape | 0.1 | 59.2 |
9 | Water-blocking tape | 0.3 | 59.8 |
10 | Aluminum tape | 0.15 | 60.1 |
11 | PE with aluminum face | 0.05 | 60.2 |
12 | PE jacket | 2.4 | 65.0 |
Using the cable constructors
The LineCableModels.DataModel
module implements a carefully designed component hierarchy that mirrors the physical construction of power cables while maintaining the mathematical relationships required for accurate electrical modeling.
CableDesign
├── CableComponent
│ ├── conductor_group::ConductorGroup <: AbstractConductorPart
│ │ ├── layers::Vector{AbstractConductorPart}
│ │ │ ├── WireArray
│ │ │ ├── Tubular
│ │ │ ├── Strip
│ │ │ └── …
│ ├── conductor_props::Material
│ ├── insulator_group::InsulatorGroup <: AbstractInsulatorPart
│ │ ├── layers::Vector{AbstractInsulatorPart}
│ │ │ ├── Insulator
│ │ │ ├── Semicon
│ │ │ └── …
│ └── insulator_props::Material
⋮
├── CableComponent
│ ├── …
⋮ ⋮
Cable designs
The CableDesign
object is the main container for all cable components. It encapsulates the entire cable structure and provides methods for calculating global cable properties.
Cable components
Each CableComponent
represents a functional group of the cable (core, sheath, armor, outer), organized into a conductor group and an insulator group with their respective effective material properties. This structure is designed to provide precise calculation of electromagnetic parameters.
Conductor groups
The ConductorGroup
object serves as a specialized container for organizing AbstractConductorPart
elements in layers. It calculates equivalent resistance (R) and inductance (L) values for all contained conductive elements, handling the complexity of different geometrical arrangements.
AbstractConductorPart implementations
- The
WireArray
object models stranded cores and screens with helical patterns and circular cross-sections. - The
Tubular
object represents simple tubular conductors with straightforward parameter calculations. - The
Strip
object models conductor tapes following helical patterns with rectangular cross-sections.
Insulator groups
The InsulatorGroup
object organizes AbstractInsulatorPart
elements in concentric layers, calculating the equivalent capacitance (C) and conductance (G) parameters.
AbstractInsulatorPart implementations
- The
Insulator
object represents dielectric layers with very high resistivity. - The
Semicon
object models semiconducting layers with intermediate resistivity and high permittivity.
The hierarchical structure enables accurate calculation of equivalent circuit parameters by:
- Computing geometry-specific parameters at the
AbstractConductorPart
andAbstractInsulatorPart
levels. - Aggregating these into equivalent parameters within
ConductorGroup
andInsulatorGroup
. - Converting the composite structure into an equivalent coaxial model by matching lumped circuit quantities (R, L, C, G) to effective electromagnetic properties (ρ, ε, µ) at the
CableComponent
level. The effective properties are stored in dedicatedMaterial
objects.
Core and main insulation
The core consists of a 4-layer AAAC stranded conductor with 61 wires arranged in (1/6/12/18/24) pattern, with respective lay ratios of (15/13.5/12.5/11) [12]. Stranded conductors are modeled using the WireArray
object, which handles the helical pattern and twisting effects via the calc_helical_params
method.
Initialize the conductor object and assign the central wire:
material = get_material(materials_db, "aluminum")
core = ConductorGroup(WireArray(0, Diameter(d_w), 1, 0, material))
1-element ConductorGroup: [radius_in=0.0, radius_ext=0.00235, cross_section=1.735e-5, resistance=0.001629, gmr=0.00183]
└─WireArray: [radius_in=0.0, radius_ext=0.00235, cross_section=1.735e-5, resistance=0.001629, gmr=0.00183]
The addto_conductorgroup!
method internally passes the radius_ext
of the existing object to the radius_in
argument of the new conductor. This enables easy stacking of multiple layers without redundancy. Moreover, the Diameter
method is a convenience function that converts the diameter to radius at the constructor level. This maintains alignment with manufacturer specifications while enabling internal calculations to use radius values directly. This approach eliminates repetitive unit conversions and potential sources of implementation error.
Add the subsequent layers of wires and inspect the object:
addto_conductorgroup!(core, WireArray, Diameter(d_w), 6, 15, material)
addto_conductorgroup!(core, WireArray, Diameter(d_w), 12, 13.5, material)
addto_conductorgroup!(core, WireArray, Diameter(d_w), 18, 12.5, material)
addto_conductorgroup!(core, WireArray, Diameter(d_w), 24, 11, material)
5-element ConductorGroup: [radius_in=0.0, radius_ext=0.02115, cross_section=0.001058, resistance=2.757e-5, gmr=0.01633]
├─WireArray: [radius_in=0.0, radius_ext=0.00235, cross_section=1.735e-5, resistance=0.001629, gmr=0.00183]
├─WireArray: [radius_in=0.00235, radius_ext=0.00705, cross_section=0.0001041, resistance=0.0002774, gmr=0.005414]
├─WireArray: [radius_in=0.00705, radius_ext=0.01175, cross_section=0.0002082, resistance=0.0001394, gmr=0.01009]
├─WireArray: [radius_in=0.01175, radius_ext=0.01645, cross_section=0.0003123, resistance=9.332e-5, gmr=0.01478]
└─WireArray: [radius_in=0.01645, radius_ext=0.02115, cross_section=0.0004164, resistance=7.059e-5, gmr=0.01948]
Inner semiconductor
The inner semiconductor layer ensures uniform electric field distribution between the conductor and insulation, eliminating air gaps and reducing field concentrations. An optional semiconductive tape is often used to ensure core uniformity and enhanced adherence.
The Thickness
type is a convenience wrapper that simplifies layer construction. When used in a constructor, it automatically calculates the outer radius by adding the thickness to the inner radius (which is inherited from the previous layer's outer radius).
Inner semiconductive tape:
material = get_material(materials_db, "polyacrylate")
main_insu = InsulatorGroup(Semicon(core, Thickness(t_sct), material))
1-element InsulatorGroup: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
└─Semicon: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, resistance=1.32e8, gmr=0.02135, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
Inner semiconductor (1000 Ω.m as per IEC 840):
material = get_material(materials_db, "semicon1")
addto_insulatorgroup!(main_insu, Semicon, Thickness(t_sc_in), material)
2-element InsulatorGroup: [radius_in=0.02115, radius_ext=0.02205, cross_section=0.0001221, shunt_capacitance=2.149e-7, shunt_conductance=0.06146]
├─Semicon: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, resistance=1.32e8, gmr=0.02135, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
└─Semicon: [radius_in=0.02145, radius_ext=0.02205, cross_section=8.2e-5, resistance=1.22e7, gmr=0.02185, shunt_capacitance=2.017e-6, shunt_conductance=0.2278]
Main insulation
XLPE (cross-linked polyethylene) is the standard insulation material for modern medium and high voltage cables due to its excellent dielectric properties.
Add the insulation layer:
material = get_material(materials_db, "pe")
addto_insulatorgroup!(main_insu, Insulator, Thickness(t_ins), material)
3-element InsulatorGroup: [radius_in=0.02115, radius_ext=0.03005, cross_section=0.001432, shunt_capacitance=4.134e-10, shunt_conductance=3.774e-13]
├─Semicon: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, resistance=1.32e8, gmr=0.02135, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
├─Semicon: [radius_in=0.02145, radius_ext=0.02205, cross_section=8.2e-5, resistance=1.22e7, gmr=0.02185, shunt_capacitance=2.017e-6, shunt_conductance=0.2278]
└─Insulator: [radius_in=0.02205, radius_ext=0.03005, cross_section=0.001309, resistance=1.504e17, gmr=0.02752, shunt_capacitance=4.134e-10, shunt_conductance=1.03e-13]
Outer semiconductor
Similar to the inner semiconductor, the outer semiconductor provides a uniform transition from insulation to the metallic screen.
Outer semiconductor (500 Ω.m as per IEC 840):
material = get_material(materials_db, "semicon2")
addto_insulatorgroup!(main_insu, Semicon, Thickness(t_sc_out), material)
4-element InsulatorGroup: [radius_in=0.02115, radius_ext=0.03035, cross_section=0.001488, shunt_capacitance=4.134e-10, shunt_conductance=3.908e-13]
├─Semicon: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, resistance=1.32e8, gmr=0.02135, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
├─Semicon: [radius_in=0.02145, radius_ext=0.02205, cross_section=8.2e-5, resistance=1.22e7, gmr=0.02185, shunt_capacitance=2.017e-6, shunt_conductance=0.2278]
├─Insulator: [radius_in=0.02205, radius_ext=0.03005, cross_section=0.001309, resistance=1.504e17, gmr=0.02752, shunt_capacitance=4.134e-10, shunt_conductance=1.03e-13]
└─Semicon: [radius_in=0.03005, radius_ext=0.03035, cross_section=5.693e-5, resistance=8.783e6, gmr=0.03025, shunt_capacitance=5.6e-6, shunt_conductance=1.265]
Outer semiconductive tape:
material = get_material(materials_db, "polyacrylate")
addto_insulatorgroup!(main_insu, Semicon, Thickness(t_sct), material)
5-element InsulatorGroup: [radius_in=0.02115, radius_ext=0.03065, cross_section=0.001546, shunt_capacitance=4.134e-10, shunt_conductance=5.307e-13]
├─Semicon: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, resistance=1.32e8, gmr=0.02135, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
├─Semicon: [radius_in=0.02145, radius_ext=0.02205, cross_section=8.2e-5, resistance=1.22e7, gmr=0.02185, shunt_capacitance=2.017e-6, shunt_conductance=0.2278]
├─Insulator: [radius_in=0.02205, radius_ext=0.03005, cross_section=0.001309, resistance=1.504e17, gmr=0.02752, shunt_capacitance=4.134e-10, shunt_conductance=1.03e-13]
├─Semicon: [radius_in=0.03005, radius_ext=0.03035, cross_section=5.693e-5, resistance=8.783e6, gmr=0.03025, shunt_capacitance=5.6e-6, shunt_conductance=1.265]
└─Semicon: [radius_in=0.03035, radius_ext=0.03065, cross_section=5.749e-5, resistance=9.219e7, gmr=0.03055, shunt_capacitance=1.827e-7, shunt_conductance=0.1205]
Group core-related components:
core_cc = CableComponent("core", core, main_insu)
10-element CableComponent "core":
├─ 5-element ConductorGroup: [radius_in=0.0, radius_ext=0.02115, cross_section=0.001058, resistance=2.757e-5, gmr=0.01633]
│ ├─ Effective properties: [rho=3.874e-8, eps_r=0.0, mu_r=1.035, alpha=0.00429]
│ ├─── WireArray: [radius_in=0.0, radius_ext=0.00235, cross_section=1.735e-5, resistance=0.001629, gmr=0.00183]
│ ├─── WireArray: [radius_in=0.00235, radius_ext=0.00705, cross_section=0.0001041, resistance=0.0002774, gmr=0.005414]
│ ├─── WireArray: [radius_in=0.00705, radius_ext=0.01175, cross_section=0.0002082, resistance=0.0001394, gmr=0.01009]
│ ├─── WireArray: [radius_in=0.01175, radius_ext=0.01645, cross_section=0.0003123, resistance=9.332e-5, gmr=0.01478]
│ └─── WireArray: [radius_in=0.01645, radius_ext=0.02115, cross_section=0.0004164, resistance=7.059e-5, gmr=0.01948]
└─ 5-element InsulatorGroup: [radius_in=0.02115, radius_ext=0.03065, cross_section=0.001546, shunt_capacitance=4.134e-10, shunt_conductance=5.307e-13]
├─ Effective properties: [rho=3.191e13, eps_r=2.757, mu_r=1.278, alpha=0.0]
├─── Semicon: [radius_in=0.02115, radius_ext=0.02145, cross_section=4.015e-5, shunt_capacitance=1.276e-7, shunt_conductance=0.08417]
├─── Semicon: [radius_in=0.02145, radius_ext=0.02205, cross_section=8.2e-5, shunt_capacitance=2.017e-6, shunt_conductance=0.2278]
├─── Insulator: [radius_in=0.02205, radius_ext=0.03005, cross_section=0.001309, shunt_capacitance=4.134e-10, shunt_conductance=1.03e-13]
├─── Semicon: [radius_in=0.03005, radius_ext=0.03035, cross_section=5.693e-5, shunt_capacitance=5.6e-6, shunt_conductance=1.265]
└─── Semicon: [radius_in=0.03035, radius_ext=0.03065, cross_section=5.749e-5, shunt_capacitance=1.827e-7, shunt_conductance=0.1205]
With the core parts properly defined, the CableDesign
object is initialized with nominal data from the datasheet. This includes voltage ratings and reference electrical parameters that will be used to benchmark the design.
Define the nominal values and instantiate the CableDesign
with the core_cc
component:
cable_id = "tutorial2"
datasheet_info = NominalData(
designation_code = "NA2XS(FL)2Y",
U0 = 18.0, # Phase-to-ground voltage [kV]
U = 30.0, # Phase-to-phase voltage [kV]
conductor_cross_section = 1000.0, # [mm²]
screen_cross_section = 35.0, # [mm²]
resistance = 0.0291, # DC resistance [Ω/km]
capacitance = 0.39, # Capacitance [μF/km]
inductance = 0.3, # Inductance in trifoil [mH/km]
)
cable_design = CableDesign(cable_id, core_cc, nominal_data = datasheet_info)
1-element CableDesign "tutorial2", with nominal values: [resistance=0.0291, inductance=0.3, capacitance=0.39]
└─ Component "core":
├─ ConductorGroup: [radius_in=0.0, radius_ext=0.02115, rho=3.874e-8, eps_r=0.0, mu_r=1.035, alpha=0.00429]
└─ InsulatorGroup: [radius_in=0.02115, radius_ext=0.03065, rho=3.191e13, eps_r=2.757, mu_r=1.278, alpha=0.0]
At this point, it becomes possible to preview the cable design:
plt1 = preview_cabledesign(cable_design)
Wire screens
The metallic screen (typically copper) serves multiple purposes:
- Provides a return path for fault currents.
- Ensures radial symmetry of the electric field.
- Acts as electrical shielding.
- Provides mechanical protection.
Build the wire screens on top of the previous layer:
lay_ratio = 10 # typical value for wire screens
material = get_material(materials_db, "copper")
screen_con =
ConductorGroup(WireArray(main_insu, Diameter(d_ws), num_sc_wires, lay_ratio, material))
1-element ConductorGroup: [radius_in=0.03065, radius_ext=0.0316, cross_section=3.473e-5, resistance=0.0005203, gmr=0.03078]
└─WireArray: [radius_in=0.03065, radius_ext=0.0316, cross_section=3.473e-5, resistance=0.0005203, gmr=0.03078]
Add the equalizing copper tape wrapping the wire screen:
addto_conductorgroup!(screen_con, Strip, Thickness(t_cut), w_cut, lay_ratio, material)
2-element ConductorGroup: [radius_in=0.03065, radius_ext=0.0317, cross_section=3.573e-5, resistance=0.0005058, gmr=0.0308]
├─WireArray: [radius_in=0.03065, radius_ext=0.0316, cross_section=3.473e-5, resistance=0.0005203, gmr=0.03078]
└─Strip: [radius_in=0.0316, radius_ext=0.0317, cross_section=1.0e-6, resistance=0.01807, gmr=0.03167]
Water blocking tape over screen:
material = get_material(materials_db, "polyacrylate")
screen_insu = InsulatorGroup(Semicon(screen_con, Thickness(t_wbt), material))
1-element InsulatorGroup: [radius_in=0.0317, radius_ext=0.032, cross_section=6.004e-5, shunt_capacitance=1.908e-7, shunt_conductance=0.1259]
└─Semicon: [radius_in=0.0317, radius_ext=0.032, cross_section=6.004e-5, resistance=8.828e7, gmr=0.0319, shunt_capacitance=1.908e-7, shunt_conductance=0.1259]
Group sheath components and assign to design:
sheath_cc = CableComponent("sheath", screen_con, screen_insu)
addto_cabledesign!(cable_design, sheath_cc)
2-element CableDesign "tutorial2", with nominal values: [resistance=0.0291, inductance=0.3, capacitance=0.39]
├─ Component "core":
│ ├─ ConductorGroup: [radius_in=0.0, radius_ext=0.02115, rho=3.874e-8, eps_r=0.0, mu_r=1.035, alpha=0.00429]
│ └─ InsulatorGroup: [radius_in=0.02115, radius_ext=0.03065, rho=3.191e13, eps_r=2.757, mu_r=1.278, alpha=0.0]
└─ Component "sheath":
├─ ConductorGroup: [radius_in=0.03065, radius_ext=0.0317, rho=1.04e-7, eps_r=0.0, mu_r=2.601, alpha=0.00393]
└─ InsulatorGroup: [radius_in=0.0317, radius_ext=0.032, rho=5300.0, eps_r=32.3, mu_r=1.103, alpha=0.0]
Examine the newly added components:
plt2 = preview_cabledesign(cable_design)
Outer jacket components
Modern cables often include an aluminum tape as moisture barrier and PE (polyethylene) outer jacket for mechanical protection.
Add the aluminum foil (moisture barrier):
material = get_material(materials_db, "aluminum")
jacket_con = ConductorGroup(Tubular(screen_insu, Thickness(t_alt), material))
1-element ConductorGroup: [radius_in=0.032, radius_ext=0.03215, cross_section=3.023e-5, resistance=0.000935, gmr=0.0321]
└─Tubular: [radius_in=0.032, radius_ext=0.03215, cross_section=3.023e-5, resistance=0.000935, gmr=0.0321]
PE layer after aluminum foil:
material = get_material(materials_db, "pe")
jacket_insu = InsulatorGroup(Insulator(jacket_con, Thickness(t_pet), material))
1-element InsulatorGroup: [radius_in=0.03215, radius_ext=0.0322, cross_section=1.011e-5, shunt_capacitance=8.234e-8, shunt_conductance=2.052e-11]
└─Insulator: [radius_in=0.03215, radius_ext=0.0322, cross_section=1.011e-5, resistance=1.949e19, gmr=0.03218, shunt_capacitance=8.234e-8, shunt_conductance=2.052e-11]
PE jacket (outer mechanical protection):
material = get_material(materials_db, "pe")
addto_insulatorgroup!(jacket_insu, Insulator, Thickness(t_jac), material)
2-element InsulatorGroup: [radius_in=0.03215, radius_ext=0.0346, cross_section=0.0005138, shunt_capacitance=1.742e-9, shunt_conductance=4.343e-13]
├─Insulator: [radius_in=0.03215, radius_ext=0.0322, cross_section=1.011e-5, resistance=1.949e19, gmr=0.03218, shunt_capacitance=8.234e-8, shunt_conductance=2.052e-11]
└─Insulator: [radius_in=0.0322, radius_ext=0.0346, cross_section=0.0005037, resistance=3.911e17, gmr=0.03381, shunt_capacitance=1.78e-9, shunt_conductance=4.437e-13]
To facilitate data entry, it is possible to call the addto_cabledesign!
method directly on the ConductorGroup
and InsulatorGroup
constituents of the component to include, without instantiating the CableComponent
first.
Assign the jacket parts directly to the design:
addto_cabledesign!(cable_design, "jacket", jacket_con, jacket_insu)
3-element CableDesign "tutorial2", with nominal values: [resistance=0.0291, inductance=0.3, capacitance=0.39]
├─ Component "core":
│ ├─ ConductorGroup: [radius_in=0.0, radius_ext=0.02115, rho=3.874e-8, eps_r=0.0, mu_r=1.035, alpha=0.00429]
│ └─ InsulatorGroup: [radius_in=0.02115, radius_ext=0.03065, rho=3.191e13, eps_r=2.757, mu_r=1.278, alpha=0.0]
├─ Component "sheath":
│ ├─ ConductorGroup: [radius_in=0.03065, radius_ext=0.0317, rho=1.04e-7, eps_r=0.0, mu_r=2.601, alpha=0.00393]
│ └─ InsulatorGroup: [radius_in=0.0317, radius_ext=0.032, rho=5300.0, eps_r=32.3, mu_r=1.103, alpha=0.0]
└─ Component "jacket":
├─ ConductorGroup: [radius_in=0.032, radius_ext=0.03215, rho=2.826e-8, eps_r=0.0, mu_r=1.0, alpha=0.00429]
└─ InsulatorGroup: [radius_in=0.03215, radius_ext=0.0346, rho=1.97e14, eps_r=2.3, mu_r=1.0, alpha=0.0]
Inspect the finished cable design:
plt3 = preview_cabledesign(cable_design)
Examining the cable parameters (RLC)
In this section, the cable design is examined and the calculated parameters are compared with datasheet values. LineCableModels.jl
provides methods to analyze the design in different levels of detail.
Compare with datasheet information (R, L, C values):
core_df = cabledesign_todf(cable_design, :core)
Row | parameter | computed | nominal | percent_diff |
---|---|---|---|---|
String | Float64 | Float64 | Float64 | |
1 | R [Ω/km] | 0.0275677 | 0.0291 | 5.2658 |
2 | L [mH/km] | 0.287184 | 0.3 | 4.27206 |
3 | C [μF/km] | 0.413357 | 0.39 | 5.98903 |
Obtain the equivalent electromagnetic properties of the cable:
components_df = cabledesign_todf(cable_design, :components)
Row | property | core | sheath | jacket |
---|---|---|---|---|
Symbol | Float64 | Float64 | Float64 | |
1 | radius_in_con | 0.0 | 0.03065 | 0.032 |
2 | radius_ext_con | 0.02115 | 0.0317 | 0.03215 |
3 | rho_con | 3.8741e-8 | 1.0402e-7 | 2.8264e-8 |
4 | alpha_con | 0.00429 | 0.00393 | 0.00429 |
5 | mu_con | 1.03464 | 2.60116 | 1.00002 |
6 | radius_ext_ins | 0.03065 | 0.032 | 0.0346 |
7 | eps_ins | 2.75653 | 32.3 | 2.3 |
8 | mu_ins | 1.27844 | 1.10328 | 1.0 |
9 | loss_factor_ins | 4.08655e-6 | 2100.02 | 7.93428e-7 |
Get detailed description of all cable parts:
detailed_df = cabledesign_todf(cable_design, :detailed)
Row | property | core, cond. layer 1 | core, cond. layer 2 | core, cond. layer 3 | core, cond. layer 4 | core, cond. layer 5 | core, ins. layer 1 | core, ins. layer 2 | core, ins. layer 3 | core, ins. layer 4 | core, ins. layer 5 | sheath, cond. layer 1 | sheath, cond. layer 2 | sheath, ins. layer 1 | jacket, cond. layer 1 | jacket, ins. layer 1 | jacket, ins. layer 2 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
String | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | Any | |
1 | type | wirearray | wirearray | wirearray | wirearray | wirearray | semicon | semicon | insulator | semicon | semicon | wirearray | strip | semicon | tubular | insulator | insulator |
2 | radius_in | 0 | 0.00235 | 0.00705 | 0.01175 | 0.01645 | 0.02115 | 0.02145 | 0.02205 | 0.03005 | 0.03035 | 0.03065 | 0.0316 | 0.0317 | 0.032 | 0.03215 | 0.0322 |
3 | radius_ext | 0.00235 | 0.00705 | 0.01175 | 0.01645 | 0.02115 | 0.02145 | 0.02205 | 0.03005 | 0.03035 | 0.03065 | 0.0316 | 0.0317 | 0.032 | 0.03215 | 0.0322 | 0.0346 |
4 | diam_in | 0 | 0.0047 | 0.0141 | 0.0235 | 0.0329 | 0.0423 | 0.0429 | 0.0441 | 0.0601 | 0.0607 | 0.0613 | 0.0632 | 0.0634 | 0.064 | 0.0643 | 0.0644 |
5 | diam_ext | 0.0047 | 0.0141 | 0.0235 | 0.0329 | 0.0423 | 0.0429 | 0.0441 | 0.0601 | 0.0607 | 0.0613 | 0.0632 | 0.0634 | 0.064 | 0.0643 | 0.0644 | 0.0692 |
6 | thickness | 0.00235 | 0.0047 | 0.0047 | 0.0047 | 0.0047 | 0.0003 | 0.0006 | 0.008 | 0.0003 | 0.0003 | 0.00095 | 0.0001 | 0.0003 | 0.00015 | 5.0e-5 | 0.0024 |
7 | cross_section | 1.73494e-5 | 0.000104097 | 0.000208193 | 0.00031229 | 0.000416387 | 4.01496e-5 | 8.19956e-5 | 0.00130942 | 5.69257e-5 | 5.74911e-5 | 3.47323e-5 | 1.0e-6 | 6.00358e-5 | 3.023e-5 | 1.01081e-5 | 0.00050366 |
8 | num_wires | 1 | 6 | 12 | 18 | 24 | missing | missing | missing | missing | missing | 49 | missing | missing | missing | missing | missing |
9 | resistance | 0.0016291 | 0.000277408 | 0.000139386 | 9.33203e-5 | 7.05933e-5 | 1.32006e8 | 1.21958e7 | 1.50449e17 | 8.78339e6 | 9.21881e7 | 0.000520317 | 0.0180718 | 8.82806e7 | 0.000934966 | 1.94894e19 | 3.91137e17 |
10 | alpha | 0.00429 | 0.00429 | 0.00429 | 0.00429 | 0.00429 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.00393 | 0.00393 | 0.0 | 0.00429 | 0.0 | 0.0 |
11 | gmr | 0.00183017 | 0.00541405 | 0.0100888 | 0.0147807 | 0.0194766 | 0.0213502 | 0.0218509 | 0.0275196 | 0.0302502 | 0.0305502 | 0.0307835 | 0.0316667 | 0.0319002 | 0.0321 | 0.0321833 | 0.0338096 |
12 | gmr/radius | 0.778796 | 0.76795 | 0.858622 | 0.89852 | 0.920881 | 0.995349 | 0.990971 | 0.915793 | 0.996711 | 0.996743 | 0.974161 | 0.998949 | 0.99688 | 0.998446 | 0.999483 | 0.977155 |
13 | shunt_capacitance | missing | missing | missing | missing | missing | 1.2758e-7 | 2.01655e-6 | 4.13357e-10 | 5.60029e-6 | 1.82686e-7 | missing | missing | 1.90773e-7 | missing | 8.23389e-8 | 1.77994e-9 |
14 | shunt_conductance | missing | missing | missing | missing | missing | 0.0841696 | 0.227751 | 1.03035e-13 | 1.265 | 0.120526 | missing | missing | 0.12586 | missing | 2.0524e-11 | 4.43672e-13 |
Saving the cable design
Designs can be saved to a library for future use. The CablesLibrary
is a container for storing multiple cable designs, allowing for easy access and reuse in different projects. Lirabry management is performed using the list_cableslibrary
, store_cableslibrary!
, and save_cableslibrary
functions.
Store the cable design and inspect the library contents:
library = CablesLibrary()
store_cableslibrary!(library, cable_design)
list_cableslibrary(library)
Row | cable_id | nominal_data | components |
---|---|---|---|
String | String | String | |
1 | tutorial2 | NominalData("NA2XS(FL)2Y", 18.0, 30.0, 1000.0, 35.0, nothing, 0.0291, 0.39, 0.3) | core, sheath, jacket |
Save to file for later use:
output_file = joinpath(@__DIR__, "cables_library.json")
save_cableslibrary(library, file_name = output_file);
Cables library saved to: cables_library.json
Defining a cable system
A cable system is a collection of cables with defined positions, length and environmental characteristics. The LineCableSystem
object is the main container for all cable systems, and it allows the definition of multiple cables in different configurations (e.g., trifoil, flat etc.). This object is the entry point for all system-related calculations and analyses.
Earth model
The earth return path significantly affects cable impedance calculations and needs to be properly modeled. In this tutorial, only a basic model with typical soil properties is defined. This will be further elaborated in the subsequent tutorials.
Define a frequency-dependent earth model (1 Hz to 1 MHz):
f = 10.0 .^ range(0, stop = 6, length = 10) # Frequency range
earth_params = EarthModel(f, 100.0, 10.0, 1.0) # 100 Ω·m resistivity, εr=10, μr=1
EarthModel with 1 horizontal earth layer (homogeneous) and 10 frequency samples
├─ Layer 1 (air): [rho_g=Inf, epsr_g=1.0, mur_g=1.0, t=∞]
└─ Layer 2: [rho_g=100.0, epsr_g=10.0, mur_g=1.0, t=∞]
Frequency-dependent model: CP model
No equivalent homogeneous model
Earth model base (DC) properties:
earthmodel_todf_df = earthmodel_todf(earth_params)
Row | rho_g | epsr_g | mur_g | thickness |
---|---|---|---|---|
Float64 | Float64 | Float64 | Float64 | |
1 | Inf | 1.0 | 1.0 | Inf |
2 | 100.0 | 10.0 | 1.0 | Inf |
Three-phase system in trifoil configuration
This section ilustrates the construction of a cable system with three identical cables arranged in a trifoil formation.
Define system center point (underground at 1 m depth) and the trifoil positions
x0 = 0
y0 = -1
xa, ya, xb, yb, xc, yc = trifoil_formation(x0, y0, 0.035)
(0, -0.9696891108675446, -0.035, -1.0303108891324553, 0.035, -1.0303108891324553)
Initialize the LineCableSystem
with the first cable (phase A):
cabledef = CableDef(cable_design, xa, ya, Dict("core" => 1, "sheath" => 0, "jacket" => 0))
cable_system = LineCableSystem("tutorial2", 20.0, earth_params, 1000.0, cabledef)
LineCableSystem "tutorial2": [T=20.0, line_length=1000.0, num_cables=1, num_phases=1]
├─ EarthModel: 1 horizontal homogeneous layer, CP model
└─ 1-element CableDef:
└─ CableDesign "tutorial2": [horz=0.0, vert=-0.9697, conn=(core→1, sheath→0, jacket→0)]
Add remaining cables (phases B and C):
addto_linecablesystem!(cable_system, cable_design, xb, yb,
Dict("core" => 2, "sheath" => 0, "jacket" => 0),
)
addto_linecablesystem!(
cable_system, cable_design, xc, yc,
Dict("core" => 3, "sheath" => 0, "jacket" => 0),
)
LineCableSystem "tutorial2": [T=20.0, line_length=1000.0, num_cables=3, num_phases=3]
├─ EarthModel: 1 horizontal homogeneous layer, CP model
└─ 3-element CableDef:
├─ CableDesign "tutorial2": [horz=0.0, vert=-0.9697, conn=(core→1, sheath→0, jacket→0)]
├─ CableDesign "tutorial2": [horz=-0.035, vert=-1.03, conn=(core→2, sheath→0, jacket→0)]
└─ CableDesign "tutorial2": [horz=0.035, vert=-1.03, conn=(core→3, sheath→0, jacket→0)]
The addto_linecablesystem!
function allows the specification of phase mapping for each cable. The Dict
argument maps the cable components to their respective phases, where core
is the conductor, sheath
is the screen, and jacket
is the outer jacket. The values (1, 2, 3) represent the phase numbers (A, B, C) in this case. Components mapped to phase 0 will be Kron-eliminated (grounded). Components set to the same phase will be bundled into an equivalent phase.
Cable system preview
In this section the complete three-phase cable system is examined.
Display system details:
system_df = linecablesystem_todf(cable_system)
Row | cable_id | horz | vert | phase_mapping |
---|---|---|---|---|
String | Number | Number | String | |
1 | tutorial2 | 0 | -0.969689 | core: 1, sheath: 0, jacket: 0 |
2 | tutorial2 | -0.035 | -1.03031 | core: 2, sheath: 0, jacket: 0 |
3 | tutorial2 | 0.035 | -1.03031 | core: 3, sheath: 0, jacket: 0 |
Visualize the cross-section of the three-phase system:
plt4 = preview_linecablesystem(cable_system, zoom_factor = 0.15)
PSCAD Export
The final step showcases how to export the model for electromagnetic transient simulations in PSCAD.
Export to PSCAD input file:
output_file = joinpath(@__DIR__, "tutorial2_export.pscx")
export_file = export_pscad_lcp(cable_system, file_name = output_file);
PSCAD file saved to: tutorial2_export.pscx
Conclusion
This tutorial has demonstrated how to:
- Create a detailed model of a complex power cable with multiple concentric layers.
- Calculate and analyze the cable base parameters (R, L, C).
- Design a three-phase cable system in trifoil arrangement.
- Export the model for further analysis in specialized software.
LineCableModels.jl
provides a powerful framework for accurate power cable modeling with a physically meaningful representation of all cable components. This approach ensures that electromagnetic parameters are calculated with high precision. Now you can go ahead and run these cable simulations like a boss!
🏠 Back to Tutorials