Lattice Thermal Conductivity (LTC)¶

  • utprøving av minste kvadraters metode med data fra Periodic Table
  • oblig_3_periodic_table.ipynb

14.11.2025 Sverre Stikbakke

In [1]:
# fra read_csv.jl (med tillegg)

using CSV, DataFrames, PeriodicTable, Unitful, Statistics, Plots

df = CSV.read("LTC_with_atomic_numbers.csv", DataFrame)

# Convert string like "[72, 28, 50]" → Vector{Int}
df.atomic_numbers = [eval(Meta.parse(s)) for s in df.atomic_numbers];
first(df, 5)
Out[1]:
5×3 DataFrame
RowSystemLTCatomic_numbers
String31Float64Array…
1AlAuHf2.962[13, 79, 72]
2AlGeLi12.208[13, 32, 3]
3AlSiLi2.367[13, 14, 3]
4AsNiSc15.121[33, 28, 21]
5BaBiK2.959[56, 83, 19]
In [2]:
# Info om grunnstoffer 

names(PeriodicTable)
Out[2]:
3-element Vector{Symbol}:
 :Element
 :PeriodicTable
 :elements
In [3]:
# Karbon (atomnummer 6)

elements[6]
Out[3]:
Carbon (C), number 6:
categorypolyatomic nonmetal
atomic mass12.011 u
density1.821 g/cm³
molar heat8.517 J/mol⋅K
phaseSolid
shells[2, 4]
electron configuration1s² 2s² 2p²
summaryCarbon (from Latin:carbo "coal") is a chemical element with symbol C and atomic number 6. On the periodic table, it is the first (row 2) of six elements in column (group) 14, which have in common the composition of their outer electron shell. It is nonmetallic and tetravalent—making four electrons available to form covalent chemical bonds.
discovered byAncient Egypt
sourcehttps://en.wikipedia.org/wiki/Carbon
Carbon_Spectra.jpg
In [4]:
propertynames(elements[6])
Out[4]:
(:name, :appearance, :atomic_mass, :boil, :category, :color, :cpk_hex, :density, :discovered_by, :el_config, :melt, :molar_heat, :named_by, :number, :period, :phase, :source, :spectral_img, :summary, :symbol, :xpos, :ypos, :shells)
In [5]:
# Hente ut en egenskap

#elements[6].atomic_mass
elements[1].boil
Out[5]:
20.271 K
In [6]:
# Create a new 'atomic_mass' column by mapping a function 
# over the entire 'atomic_numbers' column

df.atomic_mass = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].atomic_mass) for el in atomic_nums]
    mean(values)
end;

df.density = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].density) for el in atomic_nums]
    mean(values)
end;

df.boil = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].boil) for el in atomic_nums]
    mean(values)
end;

df.boil_max = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].boil) for el in atomic_nums]
    maximum(values)
end;

df.melt = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].melt) for el in atomic_nums]
    mean(values)
end;

df.melt_max = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].melt) for el in atomic_nums]
    maximum(values)
end;

df.melt_min = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [ustrip(elements[el].melt) for el in atomic_nums]
    minimum(values)
end;

df.atomic_num_max = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [el for el in atomic_nums]
    maximum(values)
end;

df.atomic_num_min = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [el for el in atomic_nums]
    minimum(values)
end;

df.atomic_num_avg = map(df.atomic_numbers) do atomic_nums
    # This inner part runs for each row
    values = [el for el in atomic_nums]
    mean(values)
end;
In [7]:
# Normalisere til verdi mellom 0 og 1
"""
col = df.atomic_mass
min_val = minimum(col)
max_val = maximum(col)
df.atomic_mass_norm = (col .- min_val) ./ (max_val - min_val);

col = df.LTC
min_val = minimum(col)
max_val = maximum(col)
df.LTC_norm = (col .- min_val) ./ (max_val - min_val);

col = df.density
min_val = minimum(col)
max_val = maximum(col)
df.density_norm = (col .- min_val) ./ (max_val - min_val);

col = df.boil
min_val = minimum(col)
max_val = maximum(col)
df.boil_norm = (col .- min_val) ./ (max_val - min_val);
""";
In [8]:
first(df, 5)
Out[8]:
5×13 DataFrame
RowSystemLTCatomic_numbersatomic_massdensityboilboil_maxmeltmelt_maxmelt_minatomic_num_maxatomic_num_minatomic_num_avg
String31Float64Array…Float64Float64Float64Float64Float64Float64Float64Int64Int64Float64
1AlAuHf2.962[13, 79, 72]134.14511.773620.674876.01592.272506.0933.47791354.6667
2AlGeLi12.208[13, 32, 3]35.51722.852332484.03106.0866.1731211.4453.6532316.0
3AlSiLi2.367[13, 14, 3]20.66881.854332628.03538.01024.711687.0453.6514310.0
4AsNiSc15.121[33, 28, 21]59.52365.87333NaNNaNNaNNaNNaN332127.3333
5BaBiK2.959[56, 83, 19]128.4694.717331662.332118.0627.1331000.0336.7831952.6667
In [9]:
# Fjerner rader med NaN-verdier
for col in names(df)
    df[!, col] = replace(df[!, col], NaN => missing)
end
df = dropmissing(df);
In [10]:
A = Matrix(df[!, [:atomic_mass, :atomic_num_avg, :boil, :density, :melt]]);
b = Matrix(df[!, [:LTC]]);
display(A)
display(b)
x = A \ b
203×5 Matrix{Float64}:
 134.145   54.6667  3620.67   11.77     1592.27
  35.5172  16.0     2484.0     2.85233   866.173
  20.6688  10.0     2628.0     1.85433  1024.71
 128.469   52.6667  1662.33    4.71733   627.133
 104.21    44.0     2649.67    7.22433  1362.23
 118.86    50.0     2681.0     7.72     1357.23
 120.119   50.0     2727.33    8.26267  1395.58
  73.7743  33.3333  3564.33    7.796    1593.64
 148.585   60.6667  4167.33   14.6833   1878.1
 104.105   44.0     4147.67   10.8157   2239.13
 148.8     60.6667  3304.33   10.6633   1606.23
 119.726   50.0     3328.0     9.63567  1725.93
 193.228   77.3333  3705.33   15.2167   1923.23
   ⋮                                    
 142.142   58.0     1039.0     7.4764    421.4
 119.915   49.0      992.555   5.9266    374.3
  73.559   30.8     1047.42    4.77562   513.098
  65.351   27.6      636.218   3.79902   286.024
  58.0886  26.5     3155.25    6.9145   1526.98
  91.2572  39.3333  3337.0     8.38233  1897.93
  60.644   27.3333  3728.67    6.913    2035.67
  72.1755  32.0     1069.0     5.975     593.34
  91.4985  40.0     4150.5     9.18575  2138.35
 105.296   45.3333  3508.67    8.54233  1756.26
  80.3623  35.5     4258.5     8.43725  2257.25
 103.019   44.5     4092.75    9.69625  1961.77
203×1 Matrix{Float64}:
  2.962
 12.208
  2.367
  2.959
 10.849
  9.204
  6.891
 24.564
 24.391
 25.8
 20.412
 19.509
 10.844
  ⋮
  0.386
  0.758
  1.451
  1.757
 37.282
 14.537
 36.258
 13.379
 17.717
 16.788
 14.217
 19.181
Out[10]:
5×1 Matrix{Float64}:
  1.40406717773646
 -3.2421308994880373
  0.0019499296035468338
 -5.315141099698021
  0.03274618650817724
In [11]:
# --- Predict and plot --- Ikke helt heldig med denne (?)
pred = A * x
#plot(df.LTC, pred, lw=2, label="modell", xlims=(-5,100), ylims=(-50,50))
plot(df.LTC, pred, lw=1, label="model", xlims=(-5,50), ylims=(-25,50))
scatter!(df.LTC, df.LTC, lw=2, label="data")
Out[11]:
No description has been provided for this image
In [12]:
# Nytt forsøk - sorterer data etter LTC-kolonnen
df_ltc = sort(df, :LTC);
first(df_ltc, 5)
Out[12]:
5×13 DataFrame
RowSystemLTCatomic_numbersatomic_massdensityboilboil_maxmeltmelt_maxmelt_minatomic_num_maxatomic_num_minatomic_num_avg
String31Float64Array…Float64Float64Float64Float64Float64Float64Float64Int64Int64Float64
1CsRb3_mp-11839450.182[55, 37, 37, 37]97.32721.6315956.75961.0309.762312.45301.7553741.5
2KRb3_mp-11850800.25[19, 37, 37, 37]73.87541.3645978.751032.0318.512336.7312.45371932.5
3TlBr_mp-228750.386[35, 81]142.1427.47641039.01746.0421.4577.0265.8813558.0
4K3Na_mp-11848440.41[19, 19, 19, 11]35.07120.88851063.021156.09345.261370.944336.7191117.0
5AgBr_mp-8662910.437[47, 35]93.88616.79641383.52435.0750.3651234.93265.8473541.0
In [13]:
A_ltc = Matrix(df_ltc[!, [:atomic_mass, :atomic_num_avg, :boil, :density, :melt]]);
#A_ltc = Matrix(df_ltc[!, [:boil]]);
b_ltc = Matrix(df_ltc[!, [:LTC]]);
x_ltc = A_ltc \ b_ltc;
pred_ltc = A_ltc * x_ltc;
x_ltc
Out[13]:
5×1 Matrix{Float64}:
  1.4040671777364582
 -3.2421308994880316
  0.001949929603546818
 -5.315141099698018
  0.03274618650817723
In [14]:
plot(df_ltc.LTC, pred_ltc, lw=1, label="model", xlims=(-5,50), ylims=(-25,50))
scatter!(df_ltc.LTC, df_ltc.LTC, lw=2, label="data")
Out[14]:
No description has been provided for this image