Arjen Markus (17 june 2004) Here is a first almost trivial example of how Tcl could be used to facilitate certain physical computations ... I hope I can make this grow into a more serious package ;)

AM (18 june 2004) One thing that might be very useful in such a package: a short explanation of the various procedures and constants, especially if you are using it interactively. BTW, the unit converter is a much better way to achieve the unit conversions I haphazardly implemented here.

AM (25 june 2004) An improved version (note the laziness with regard to unit conversion) of the original script. What I added:

• One extra relation, the velocity of sound in gases
• The superposition principle for linear phenomena such as the diffusion of a substance

``` # physics.tcl --
#    formulas
#
#    Simple example:
#    Conversion of temperature to absolute temperature
#    In many formulas you need to specify the absolute temperature
#    rather than the temperature most people are used to (degrees
#    centigrade or the infamous degrees Fahrenheit).
#    Mistakes are easily made ... so include the unit in the value.
#
#    Note:
#    In this implementation I have been less than consistent
#    in the use of unit conversions. I mainly wanted to get
#    something working ;)
#

# physics --
#    Namespace for the physical computations
#
namespace eval ::physics {

#
#
variable gas_constant 8.3143 ;# J/mol.K

namespace export abs_temperature     wien_wavelength \
velocity_sound_gas  diffusivePoint1d \
superpose
}

# Conversions --
#    Set of conversion procedures
#
proc ::physics::Conv_K_K   {t} {return \$t}
proc ::physics::Conv_oC_K  {t} {expr {\$t+273.15}}
proc ::physics::Conv_oF_K  {t} {Conv_oC_K [Conv_oF_oC \$t]}
proc ::physics::Conv_oF_oC {t} {expr {5.0*\$t/9.0+32.0}}

# abs_temperature --
#    Return the absolute temperature
#
# Arguments:
#    temp         (Relative) temperature
#
# Result:
#    The temperature in kelvin (no capital, there was only one
#    lord Kelvin, AFAIK :)
#
proc ::physics::abs_temperature {temp} {

if { [llength \$temp] == 2 } {
set temp [Conv_[lindex \$temp 1]_K [lindex \$temp 0]]
}
list \$temp K
}

# wien_wavelength --
#    Return the wave length at which a perfect black body emits most
#    energy, given the temperature
#
# Arguments:
#    temp         (Relative) temperature
#
# Result:
#    The wave length in micrometers (um)
#
proc ::physics::wien_wavelength {temp} {
list [expr {2898.0/[lindex [abs_temperature \$temp] 0]}] um
}

# velocity_sound_gas --
#    Return the (approximate) velocity of sound in gas,
#    given the kind of gas and the temperature
#
# Arguments:
#    cpcv         Ratio of cp and cv or "mono", "di", "poly" for
#                 the type of molecules the gas consists of
#    molarw       Molar weight (g/mol)
#    temp         Temperature (K)
# Result:
#    The sound velocity in m/s
#
proc ::physics::velocity_sound_gas {cpcv molarw temp} {
variable gas_constant

set abstemp [lindex [abs_temperature \$temp] 0]
set molarw  [expr {\$molarw/1000.0}]
switch -- \$cpcv {
"mono" { set cpcv 1.66 }
"di"   { set cpcv 1.4 }
"poly" { set cpcv 1.3 }
}
set csound [expr {sqrt(\$cpcv*\$gas_constant*\$abstemp/\$molarw)}]
list \$csound "m/s"
}

# diffusivePoint1d --
#    Create a function that describes the concentration from a
#    point source under diffusion in one dimension
#
# Arguments:
#    name         Name of the function to create
#    diff         Diffusion coefficient (m/s2)
#    mass         Mass that was released
#    pos          Position of the release point
# Result:
#    Name of the function
#
proc ::physics::diffusivePoint1d {name diff mass pos} {
proc ::physics::\$name {x t} \
[string map [list %diff \$diff %mass \$mass %pos \$pos] {
expr {%mass/sqrt(4.0*3.1415926*%diff*\$t)*exp(-(\$x-%pos)*(\$x-%pos)/4.0/\$t/%diff)}
}]
return ::physics::\$name
}

# superpose --
#    Create a function that computes the sum of the individual
#    functions - the superposition principle
#
# Arguments:
#    name         Name of the function to create
#    args         List of one or more functions to superpose
# Result:
#    Name of the function
#
proc ::physics::superpose {name args} {
set body "expr {"
set arglist [info args [lindex \$args 0]]
set values  "\\$[join \$arglist " \$"]"

foreach fnc \$args {
append body "+\[\$fnc \$values\]"
}
append body "}"

proc ::physics::\$name \$arglist \$body
return ::physics::\$name
}

# main --
#    A simple demonstration
#
namespace import ::physics::*

puts "20 degrees centigrade = [abs_temperature {20 oC}]"
puts "50 degrees Fahrenheit = [abs_temperature {50 oF}]"
puts "At 20 degrees centigrade a black body emits most
energy with a wave length of [wien_wavelength {20 oC}]"

puts "Velocity of sound in air at 20 oC: \
[velocity_sound_gas di 28.9 {20 oC}]"

#
# Use a fairly large diffusion coefficient:
# otherwise the concentration will be nearly zero
# and we risk underflow
# (I ought to use larger times ;)
#
set pointsrc  [diffusivePoint1d point1 1.0 1.0e3 0.0]
set pointsrc2 [diffusivePoint1d point2 1.0 1.0e3 4.0]
foreach t {0.1 0.3 1.0 3.0 10.0} {
puts "t=\$t: concentration = [\$pointsrc 1.0 \$t]"
}
foreach x {0.1 0.3 1.0 2.0 3.0} {
puts "x=\$x: concentration = [\$pointsrc \$x 1.0]"
}

puts "Two sources:"
set all [superpose twopoints \$pointsrc \$pointsrc2]
foreach x {0.1 0.3 1.0 2.0 3.0 3.9 4.0 4.1 5.0 6.0} {
puts "x=\$x: concentration = [\$all \$x 1.0] (= sum of [\$pointsrc \$x 1.0] and [\$pointsrc2 \$x 1.0])"
}```

How does this relate to Unit converter and Unit math ?

AM Closely - though my intentions are different than "merely" converting from one unit to another. I want to make the unit an integral part of the quantity's value. This way I can use such quantities in all kinds of simple computations (that is, computations that do not require the solution of partial differential equations and the like).

Something like: I want to know the density of sea water at a given temperature and salinity - so use one of the constitutional equations that people have developed.

VPT - have you seen Frink http://futureboy.homeip.net/frinkdocs/ ? I'm sorry I gave the wrong link. You should find this one more relevant.

AM I know Frink, but that does not relate to the subject of this page (unless I horribly screwed up the code above, which I did not check with Frink, I admit ...).

AM Ah, another kind of Frink :). No, I did not know that one. Printed the information ...

 Category Physics Category Science