{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE Safe #-}
module Physics.Learn.Surface
(
Surface(..)
, unitSphere
, centeredSphere
, sphere
, northernHemisphere
, disk
, shiftSurface
, surfaceIntegral
, dottedSurfaceIntegral
)
where
import Data.VectorSpace
( VectorSpace
, InnerSpace
, Scalar
)
import Physics.Learn.CarrotVec
( vec
, (^+^)
, (^-^)
, (^*)
, (^/)
, (<.>)
, (><)
, magnitude
, sumV
)
import Physics.Learn.Position
( Position
, Displacement
, VectorField
, Field
, cart
, cyl
, shiftPosition
, displacement
)
data Surface = Surface { Surface -> (Double, Double) -> Position
surfaceFunc :: (Double,Double) -> Position
, Surface -> Double
lowerLimit :: Double
, Surface -> Double
upperLimit :: Double
, Surface -> Double -> Double
lowerCurve :: Double -> Double
, Surface -> Double -> Double
upperCurve :: Double -> Double
}
unitSphere :: Surface
unitSphere :: Surface
unitSphere = ((Double, Double) -> Position)
-> Double
-> Double
-> (Double -> Double)
-> (Double -> Double)
-> Surface
Surface (\(Double
th,Double
phi) -> Double -> Double -> Double -> Position
cart (Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
phi) (Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
phi) (Double -> Double
forall a. Floating a => a -> a
cos Double
th))
Double
0 Double
forall a. Floating a => a
pi (Double -> Double -> Double
forall a b. a -> b -> a
const Double
0) (Double -> Double -> Double
forall a b. a -> b -> a
const (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
pi)
centeredSphere :: Double -> Surface
centeredSphere :: Double -> Surface
centeredSphere Double
r = ((Double, Double) -> Position)
-> Double
-> Double
-> (Double -> Double)
-> (Double -> Double)
-> Surface
Surface (\(Double
th,Double
phi) -> Double -> Double -> Double -> Position
cart (Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
phi) (Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
phi) (Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
th))
Double
0 Double
forall a. Floating a => a
pi (Double -> Double -> Double
forall a b. a -> b -> a
const Double
0) (Double -> Double -> Double
forall a b. a -> b -> a
const (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
pi)
sphere :: Double -> Position -> Surface
sphere :: Double -> Position -> Surface
sphere Double
r Position
c = ((Double, Double) -> Position)
-> Double
-> Double
-> (Double -> Double)
-> (Double -> Double)
-> Surface
Surface (\(Double
th,Double
phi) -> Vec -> Position -> Position
shiftPosition (Double -> Double -> Double -> Vec
vec (Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
phi) (Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
phi) (Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
th)) Position
c)
Double
0 Double
forall a. Floating a => a
pi (Double -> Double -> Double
forall a b. a -> b -> a
const Double
0) (Double -> Double -> Double
forall a b. a -> b -> a
const (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
pi)
northernHemisphere :: Surface
northernHemisphere :: Surface
northernHemisphere = ((Double, Double) -> Position)
-> Double
-> Double
-> (Double -> Double)
-> (Double -> Double)
-> Surface
Surface (\(Double
th,Double
phi) -> Double -> Double -> Double -> Position
cart (Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
phi) (Double -> Double
forall a. Floating a => a -> a
sin Double
th Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
phi) (Double -> Double
forall a. Floating a => a -> a
cos Double
th))
Double
0 (Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double -> Double -> Double
forall a b. a -> b -> a
const Double
0) (Double -> Double -> Double
forall a b. a -> b -> a
const (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
pi)
disk :: Double -> Surface
disk :: Double -> Surface
disk Double
radius = ((Double, Double) -> Position)
-> Double
-> Double
-> (Double -> Double)
-> (Double -> Double)
-> Surface
Surface (\(Double
s,Double
phi) -> Double -> Double -> Double -> Position
cyl Double
s Double
phi Double
0) Double
0 Double
radius (Double -> Double -> Double
forall a b. a -> b -> a
const Double
0) (Double -> Double -> Double
forall a b. a -> b -> a
const (Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
pi))
surfaceIntegral :: (VectorSpace v, Scalar v ~ Double) =>
Int
-> Int
-> Field v
-> Surface
-> v
surfaceIntegral :: forall v.
(VectorSpace v, Scalar v ~ Double) =>
Int -> Int -> Field v -> Surface -> v
surfaceIntegral Int
n1 Int
n2 Field v
field (Surface (Double, Double) -> Position
f Double
s_l Double
s_u Double -> Double
t_l Double -> Double
t_u)
= [v] -> v
forall (f :: * -> *) v. (Foldable f, AdditiveGroup v) => f v -> v
sumV ([v] -> v) -> [v] -> v
forall a b. (a -> b) -> a -> b
$ ([v] -> v) -> [[v]] -> [v]
forall a b. (a -> b) -> [a] -> [b]
map [v] -> v
forall (f :: * -> *) v. (Foldable f, AdditiveGroup v) => f v -> v
sumV ([[v]] -> [v]) -> [[v]] -> [v]
forall a b. (a -> b) -> a -> b
$ ([v] -> [Double] -> [v]) -> [[v]] -> [[Double]] -> [[v]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((v -> Double -> v) -> [v] -> [Double] -> [v]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith v -> Double -> v
forall v s. (VectorSpace v, s ~ Scalar v) => v -> s -> v
(^*)) [[v]]
aveVals (([Vec] -> [Double]) -> [[Vec]] -> [[Double]]
forall a b. (a -> b) -> [a] -> [b]
map ((Vec -> Double) -> [Vec] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Vec -> Double
forall v s. (InnerSpace v, s ~ Scalar v, Floating s) => v -> s
magnitude) [[Vec]]
areas)
where
pts :: [[Position]]
pts = [[(Double, Double) -> Position
f (Double
s,Double
t) | Double
t <- Int -> Double -> Double -> [Double]
linSpaced Int
n2 (Double -> Double
t_l Double
s) (Double -> Double
t_u Double
s)] | Double
s <- Int -> Double -> Double -> [Double]
linSpaced Int
n1 Double
s_l Double
s_u]
areas :: [[Vec]]
areas = ([Vec] -> [Vec] -> [Vec]) -> [[Vec]] -> [[Vec]] -> [[Vec]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Vec -> Vec -> Vec) -> [Vec] -> [Vec] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vec -> Vec -> Vec
(><)) [[Vec]]
dus [[Vec]]
dvs
dus :: [[Vec]]
dus = ([Position] -> [Position] -> [Vec])
-> [[Position]] -> [[Position]] -> [[Vec]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Position -> Position -> Vec) -> [Position] -> [Position] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> Position -> Vec
displacement) [[Position]]
pts ([[Position]] -> [[Position]]
forall a. HasCallStack => [a] -> [a]
tail [[Position]]
pts)
dvs :: [[Vec]]
dvs = ([Position] -> [Vec]) -> [[Position]] -> [[Vec]]
forall a b. (a -> b) -> [a] -> [b]
map (\[Position]
row -> (Position -> Position -> Vec) -> [Position] -> [Position] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> Position -> Vec
displacement [Position]
row ([Position] -> [Position]
forall a. HasCallStack => [a] -> [a]
tail [Position]
row)) [[Position]]
pts
vals :: [[v]]
vals = ([Position] -> [v]) -> [[Position]] -> [[v]]
forall a b. (a -> b) -> [a] -> [b]
map (Field v -> [Position] -> [v]
forall a b. (a -> b) -> [a] -> [b]
map Field v
field) [[Position]]
pts
halfAveVals :: [[v]]
halfAveVals = ([v] -> [v]) -> [[v]] -> [[v]]
forall a b. (a -> b) -> [a] -> [b]
map (\[v]
row -> (v -> v -> v) -> [v] -> [v] -> [v]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith v -> v -> v
forall v. (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave ([v] -> [v]
forall a. HasCallStack => [a] -> [a]
tail [v]
row) [v]
row) [[v]]
vals
aveVals :: [[v]]
aveVals = ([v] -> [v] -> [v]) -> [[v]] -> [[v]] -> [[v]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((v -> v -> v) -> [v] -> [v] -> [v]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith v -> v -> v
forall v. (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave) ([[v]] -> [[v]]
forall a. HasCallStack => [a] -> [a]
tail [[v]]
halfAveVals) [[v]]
halfAveVals
dottedSurfaceIntegral :: Int
-> Int
-> VectorField
-> Surface
-> Double
dottedSurfaceIntegral :: Int -> Int -> (Position -> Vec) -> Surface -> Double
dottedSurfaceIntegral Int
n1 Int
n2 Position -> Vec
vf (Surface (Double, Double) -> Position
f Double
s_l Double
s_u Double -> Double
t_l Double -> Double
t_u)
= [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ ([Double] -> Double) -> [[Double]] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([[Double]] -> [Double]) -> [[Double]] -> [Double]
forall a b. (a -> b) -> a -> b
$ ([Vec] -> [Vec] -> [Double]) -> [[Vec]] -> [[Vec]] -> [[Double]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Vec -> Vec -> Double) -> [Vec] -> [Vec] -> [Double]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vec -> Vec -> Double
Vec -> Vec -> Scalar Vec
forall v. InnerSpace v => v -> v -> Scalar v
(<.>)) [[Vec]]
aveVals [[Vec]]
areas
where
pts :: [[Position]]
pts = [[(Double, Double) -> Position
f (Double
s,Double
t) | Double
t <- Int -> Double -> Double -> [Double]
linSpaced Int
n2 (Double -> Double
t_l Double
s) (Double -> Double
t_u Double
s)] | Double
s <- Int -> Double -> Double -> [Double]
linSpaced Int
n1 Double
s_l Double
s_u]
areas :: [[Vec]]
areas = ([Vec] -> [Vec] -> [Vec]) -> [[Vec]] -> [[Vec]] -> [[Vec]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Vec -> Vec -> Vec) -> [Vec] -> [Vec] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vec -> Vec -> Vec
(><)) [[Vec]]
dus [[Vec]]
dvs
dus :: [[Vec]]
dus = ([Position] -> [Position] -> [Vec])
-> [[Position]] -> [[Position]] -> [[Vec]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Position -> Position -> Vec) -> [Position] -> [Position] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> Position -> Vec
displacement) [[Position]]
pts ([[Position]] -> [[Position]]
forall a. HasCallStack => [a] -> [a]
tail [[Position]]
pts)
dvs :: [[Vec]]
dvs = ([Position] -> [Vec]) -> [[Position]] -> [[Vec]]
forall a b. (a -> b) -> [a] -> [b]
map (\[Position]
row -> (Position -> Position -> Vec) -> [Position] -> [Position] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> Position -> Vec
displacement [Position]
row ([Position] -> [Position]
forall a. HasCallStack => [a] -> [a]
tail [Position]
row)) [[Position]]
pts
vals :: [[Vec]]
vals = ([Position] -> [Vec]) -> [[Position]] -> [[Vec]]
forall a b. (a -> b) -> [a] -> [b]
map ((Position -> Vec) -> [Position] -> [Vec]
forall a b. (a -> b) -> [a] -> [b]
map Position -> Vec
vf) [[Position]]
pts
halfAveVals :: [[Vec]]
halfAveVals = ([Vec] -> [Vec]) -> [[Vec]] -> [[Vec]]
forall a b. (a -> b) -> [a] -> [b]
map (\[Vec]
row -> (Vec -> Vec -> Vec) -> [Vec] -> [Vec] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vec -> Vec -> Vec
forall v. (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave ([Vec] -> [Vec]
forall a. HasCallStack => [a] -> [a]
tail [Vec]
row) [Vec]
row) [[Vec]]
vals
aveVals :: [[Vec]]
aveVals = ([Vec] -> [Vec] -> [Vec]) -> [[Vec]] -> [[Vec]] -> [[Vec]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Vec -> Vec -> Vec) -> [Vec] -> [Vec] -> [Vec]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vec -> Vec -> Vec
forall v. (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave) ([[Vec]] -> [[Vec]]
forall a. HasCallStack => [a] -> [a]
tail [[Vec]]
halfAveVals) [[Vec]]
halfAveVals
linSpaced :: Int -> Double -> Double -> [Double]
linSpaced :: Int -> Double -> Double -> [Double]
linSpaced Int
n Double
a Double
b
| Double
a Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
b = let dx :: Double
dx = (Double
b Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
a) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
in [Double
a,Double
aDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
dx..Double
b]
| Double
a Double -> Double -> Bool
forall v. (InnerSpace v, Scalar v ~ Double) => v -> v -> Bool
~~ Double
b = [Double -> Double -> Double
forall v. (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave Double
a Double
b]
| Bool
otherwise = [Char] -> [Double]
forall a. HasCallStack => [Char] -> a
error ([Char] -> [Double]) -> [Char] -> [Double]
forall a b. (a -> b) -> a -> b
$ [Char]
"linSpaced: lower limit greater than upper limit: (n,a,b) = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (Int, Double, Double) -> [Char]
forall a. Show a => a -> [Char]
show (Int
n,Double
a,Double
b)
(~~) :: (InnerSpace v, Scalar v ~ Double) => v -> v -> Bool
v
a ~~ :: forall v. (InnerSpace v, Scalar v ~ Double) => v -> v -> Bool
~~ v
b = v -> Double
forall v s. (InnerSpace v, s ~ Scalar v, Floating s) => v -> s
magnitude (v
a v -> v -> v
forall v. AdditiveGroup v => v -> v -> v
^-^ v
b) Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
tolerance
tolerance :: Double
tolerance :: Double
tolerance = Double
1e-10
ave :: (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave :: forall v. (VectorSpace v, Scalar v ~ Double) => v -> v -> v
ave v
v1 v
v2 = (v
v1 v -> v -> v
forall v. AdditiveGroup v => v -> v -> v
^+^ v
v2) v -> Double -> v
forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/ Double
2
shiftSurface :: Displacement -> Surface -> Surface
shiftSurface :: Vec -> Surface -> Surface
shiftSurface Vec
d (Surface (Double, Double) -> Position
f Double
sl Double
su Double -> Double
tl Double -> Double
tu)
= ((Double, Double) -> Position)
-> Double
-> Double
-> (Double -> Double)
-> (Double -> Double)
-> Surface
Surface (Vec -> Position -> Position
shiftPosition Vec
d (Position -> Position)
-> ((Double, Double) -> Position) -> (Double, Double) -> Position
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double, Double) -> Position
f) Double
sl Double
su Double -> Double
tl Double -> Double
tu