{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE Trustworthy #-}
module Physics.Learn.Charge
(
Charge
, ChargeDistribution(..)
, totalCharge
, eField
, eFieldFromPointCharge
, eFieldFromLineCharge
, eFieldFromSurfaceCharge
, eFieldFromVolumeCharge
, electricFlux
, electricPotentialFromField
, electricPotentialFromCharge
)
where
import Physics.Learn.CarrotVec
( magnitude
, (*^)
, (^/)
)
import Physics.Learn.Position
( Position
, ScalarField
, VectorField
, displacement
, addFields
)
import Physics.Learn.Curve
( Curve(..)
, straightLine
, simpleLineIntegral
, dottedLineIntegral
)
import Physics.Learn.Surface
( Surface(..)
, surfaceIntegral
, dottedSurfaceIntegral
)
import Physics.Learn.Volume
( Volume(..)
, volumeIntegral
)
type Charge = Double
data ChargeDistribution = PointCharge Charge Position
| LineCharge ScalarField Curve
| SurfaceCharge ScalarField Surface
| VolumeCharge ScalarField Volume
| MultipleCharges [ChargeDistribution]
totalCharge :: ChargeDistribution -> Charge
totalCharge (PointCharge q _) = q
totalCharge (LineCharge lambda c) = simpleLineIntegral 1000 lambda c
totalCharge (SurfaceCharge sigma s) = surfaceIntegral 200 200 sigma s
totalCharge (VolumeCharge rho v) = volumeIntegral 50 50 50 rho v
totalCharge (MultipleCharges ds) = sum [totalCharge d | d <- ds]
eFieldFromPointCharge
:: Charge
-> Position
-> VectorField
eFieldFromPointCharge q r' r
= (k * q) *^ d ^/ magnitude d ** 3
where
k = 9e9
d = displacement r' r
eFieldFromLineCharge
:: ScalarField
-> Curve
-> VectorField
eFieldFromLineCharge lambda c r
= k *^ simpleLineIntegral 1000 integrand c
where
k = 9e9
integrand r' = lambda r' *^ d ^/ magnitude d ** 3
where
d = displacement r' r
eFieldFromSurfaceCharge
:: ScalarField
-> Surface
-> VectorField
eFieldFromSurfaceCharge sigma s r
= k *^ surfaceIntegral 200 200 integrand s
where
k = 9e9
integrand r' = sigma r' *^ d ^/ magnitude d ** 3
where
d = displacement r' r
eFieldFromVolumeCharge
:: ScalarField
-> Volume
-> VectorField
eFieldFromVolumeCharge rho v r
= k *^ volumeIntegral 50 50 50 integrand v
where
k = 9e9
integrand r' = rho r' *^ d ^/ magnitude d ** 3
where
d = displacement r' r
eField :: ChargeDistribution -> VectorField
eField (PointCharge q r') = eFieldFromPointCharge q r'
eField (LineCharge lam c) = eFieldFromLineCharge lam c
eField (SurfaceCharge sig s) = eFieldFromSurfaceCharge sig s
eField (VolumeCharge rho v) = eFieldFromVolumeCharge rho v
eField (MultipleCharges cds) = addFields $ map eField cds
electricFlux :: Surface -> ChargeDistribution -> Double
electricFlux surf dist = dottedSurfaceIntegral 200 200 (eField dist) surf
electricPotentialFromField :: Position
-> VectorField
-> ScalarField
electricPotentialFromField base ef r = -dottedLineIntegral 1000 ef (straightLine base r)
electricPotentialFromCharge :: ChargeDistribution -> ScalarField
electricPotentialFromCharge (PointCharge q r') = ePotFromPointCharge q r'
electricPotentialFromCharge (LineCharge lam c) = ePotFromLineCharge lam c
electricPotentialFromCharge (SurfaceCharge sig s) = ePotFromSurfaceCharge sig s
electricPotentialFromCharge (VolumeCharge rho v) = ePotFromVolumeCharge rho v
electricPotentialFromCharge (MultipleCharges cds) = addFields $ map electricPotentialFromCharge cds
ePotFromPointCharge
:: Charge
-> Position
-> ScalarField
ePotFromPointCharge q r' r
= (k * q) / magnitude d
where
k = 9e9
d = displacement r' r
ePotFromLineCharge
:: ScalarField
-> Curve
-> ScalarField
ePotFromLineCharge lambda c r
= k *^ simpleLineIntegral 1000 integrand c
where
k = 9e9
integrand r' = lambda r' / magnitude d
where
d = displacement r' r
ePotFromSurfaceCharge
:: ScalarField
-> Surface
-> ScalarField
ePotFromSurfaceCharge sigma s r
= k *^ surfaceIntegral 200 200 integrand s
where
k = 9e9
integrand r' = sigma r' / magnitude d
where
d = displacement r' r
ePotFromVolumeCharge
:: ScalarField
-> Volume
-> ScalarField
ePotFromVolumeCharge rho v r
= k *^ volumeIntegral 50 50 50 integrand v
where
k = 9e9
integrand r' = rho r' / magnitude d
where
d = displacement r' r