module Circuit where import Complex import Maybe import List -------------------------------------------------------------------------------- data Device = Device { devtype :: DevType , devname :: Int , devnode :: [Int] , devvalue :: Double } deriving (Show, Eq) data DevType = ADM | VSRC | ISRC | CCVS0 | CCVS1 | VCVS | CCCS | VCCS deriving (Eq, Show, Read, Ord, Bounded, Enum) data SimType = OP | TRANS deriving (Eq, Show, Read, Ord, Bounded, Enum) data ESim = ESim { simInfo :: SimInfo , nrSteps :: Double , trSteps :: Double , nrData :: [Double] , trData :: [Double] } deriving (Show) defaultESim = (ESim (SimInfo OP [] [] [] 0) 0 0 [] []) data SimInfo = SimInfo { simType :: SimType , nNODE :: [Int] , nSRC :: [Int] , simParam :: [Double] , temp :: Double } deriving (Show) --- device models --- level 0 -- N+ N- NC+ NC- value -- 1 2 3 4 adm1 :: Int -> Int -> Int -> Double -> ESim -> [Device] adm1 name p1 p2 v z0 | (simType (simInfo z0)) == OP = [(Device ADM name [p1,p2] v)] | (simType (simInfo z0)) == TRANS = [(Device ADM name [p1,p2] v)] | otherwise = error "adm : No internal model defined" vsrc1 :: Int -> Int -> Int -> Double -> ESim -> [Device] vsrc1 name p1 p2 v z0 | (simType (simInfo z0)) == OP = [(Device VSRC name [p1,p2] v)] | (simType (simInfo z0)) == TRANS = [(Device VSRC name [p1,p2] v)] | otherwise = error "vdc : No internal model defined" -- ideal current source -- p1 ---(<-)---p2 isrc1 :: Int -> Int -> Int -> Double -> ESim -> [Device] isrc1 name p1 p2 v z0 | (simType (simInfo z0)) == OP = [(Device ISRC name [p1,p2] v)] | (simType (simInfo z0)) == TRANS = [(Device ISRC name [p1,p2] v)] | otherwise = error "idc : No internal model defined" vccs1 :: Int -> Int -> Int -> Int -> Int -> Double -> ESim -> [Device] vccs1 name p1 p2 p3 p4 v z0 | (simType (simInfo z0)) == OP = [(Device VCCS name [p1,p2,p3,p4] (1/v))] | (simType (simInfo z0)) == TRANS = [(Device VCCS name [p1,p2,p3,p4] (1/v))] | otherwise = error "vccs : No internal model defined" vcvs1 :: Int -> Int -> Int -> Int -> Int -> Double -> ESim -> [Device] vcvs1 name p1 p2 p3 p4 v z0 | (simType (simInfo z0)) == OP = [(Device VCVS name [p1,p2,p3,p4] v)] | (simType (simInfo z0)) == TRANS = [(Device VCVS name [p1,p2,p3,p4] v)] | otherwise = error "vcvs : No internal model defined" ccvs1 :: Int -> Int -> Int -> Int -> Int -> Double -> ESim -> [Device] ccvs1 name p1 p2 p3 p4 v z0 | (simType (simInfo z0)) == OP = [(Device CCVS0 name [p1,p2,p3,p4] v)] ++ [(Device CCVS1 (name * 100) [p1,p2,p3,p4] 0)] | (simType (simInfo z0)) == TRANS = [(Device CCVS0 name [p1,p2,p3,p4] v)] ++ [(Device CCVS1 (name * 100) [p1,p2,p3,p4] 0)] | otherwise = error "ccvs : No internal model defined" cccs1 :: Int -> Int -> Int -> Int -> Int -> Double -> ESim -> [Device] cccs1 name p1 p2 p3 p4 v z0 | (simType (simInfo z0)) == OP = [(Device CCCS name [p1,p2,p3,p4] (1 / v))] | (simType (simInfo z0)) == TRANS = [(Device CCCS name [p1,p2,p3,p4] (1 / v))] | otherwise = error "cccs : No internal model defined" -------------------------------------------------------------------------------- -- Level 1 Devices res1 :: Int -> Int -> Int -> Double -> ESim -> [Device] res1 name p1 p2 v z0 | (simType (simInfo z0)) == OP = (adm1 name p1 p2 (1 / v) z0) | (simType (simInfo z0)) == TRANS = (adm1 name p1 p2 (1 / v) z0) | otherwise = error "res: No internal model defined" data Gmin = Gmin { gtlim :: Double --default 5 , gsteps :: Double --default 8 } deriving (Show) defaultGmin = Gmin 5 8 -- resistor with Gmin support res2 :: Int -> Int -> Int -> Double -> Gmin -> ESim -> [Device] res2 name p1 p2 rp g0 z0 | (simType (simInfo z0)) == OP = (res1 name p1 p2 r z0) | (simType (simInfo z0)) == TRANS = (res1 name p1 p2 r z0) | otherwise = error "res2 : No internal model defined" --- Model Equations ------------------------------------------ where r = 1 / (1 / rp + gmin) gmin | nrSteps z0 < gsteps g0 && trSteps z0 < gtlim g0 = 1 / 10**(12 / gsteps g0 * nrSteps z0) | otherwise = 1 / 10.0**12 -------------------------------------------------------- ind1 :: Int ->Int -> Int -> Double -> ESim -> [Device] ind1 name p1 p2 v z0 | (simType (simInfo z0)) == OP = (adm1 (nn!!0) p1 (ii!!0) 0 z0) ++ (vsrc1 (nn!!1) (ii!!0) p2 0 z0) | (simType (simInfo z0)) == TRANS = (adm1 (nn!!0) p1 (ii!!0) (1 / req) z0) ++ (vsrc1 (nn!!1) (ii!!0) p2 veq z0) | otherwise = error "ind: No internal model defined" --- Model Equations ------------------------------------------ where req = v / (simParam (simInfo z0))!!0 veq = -1 * req * (ivsrc (nn!!1) (trData z0)) -- Helper Programs ------------------------------------- nn = [(name * 100)..] ii = [(name * 100)..] ivsrc src z = (z!!((idx src j) + ((length i) - 1))) where idx n l = fromJust (elemIndex n l) vnode node z | node == 0 = 0 | otherwise = z!!(nn' - 1) where nn' = fromJust (elemIndex node i) j = nSRC (simInfo z0) i = nNODE (simInfo z0) -------------------------------------------------------- cap1 :: Int -> Int -> Int -> Double -> ESim -> [Device] cap1 name p1 p2 v z0 | (simType (simInfo z0)) == OP = (adm1 (nn!!0) p1 p2 0 z0) ++ (isrc1 (nn!!1) p1 p2 0 z0) | (simType (simInfo z0)) == TRANS = (adm1 (nn!!0) p1 p2 geq z0) ++ (isrc1 (nn!!1) p1 p2 ieq z0) | otherwise = error "cap: No internal model defined" --- Model Equations ----------------------------------------- where geq = v / (simParam (simInfo z0))!!0 ieq = geq * (vp1 - vp2) vp1 = vnode p1 (trData z0) vp2 = vnode p2 (trData z0) -- Helper Programs ------------------------------------- nn = [(name * 100)..] ii = [(name * 100)..] ivsrc src z = (z!!((idx src j) + ((length i) - 1))) where idx n l = fromJust (elemIndex n l) vnode node z | node == 0 = 0 | otherwise = z!!(nn' - 1) where nn' = fromJust (elemIndex node i) j = nSRC (simInfo z0) i = nNODE (simInfo z0) -------------------------------------------------------- -- intrinsic diode model -- pin: (p1)--!<--(p2) dio1 :: Int -> Int -> Int -> ESim -> [Device] dio1 name p1 p2 z0 | (simType (simInfo z0)) == OP = (adm1 (nn!!0) p1 p2 geq z0) ++ (isrc1 (nn!!1) p1 p2 ieq2 z0) | (simType (simInfo z0)) == TRANS = (adm1 (nn!!0) p1 p2 geq z0) ++ (isrc1 (nn!!1) p1 p2 ieq2 z0) | otherwise = error "dio1: No internal model defined" --- Model Equations ------------------------------------------ where geq = gd (vp2 - vp1) ieq2 = 1 * (ieq (vp2 - vp1)) vp1 = vnode p1 (nrData z0) vp2 = vnode p2 (nrData z0) -- Diode Model is = 1e-14 n = 1.0 isr = 0.0 nr = 2.0 ee = exp 1 vt = 0.025875 ieq vd = (idd vd) - (gd vd) * vd idd vd = is * ((ee**(vd / (n * vt))) - 1) + isr * ((ee**(vd / (nr * vt))) - 1) gd vd = (is / (n * vt)) * ee**(vd / (n * vt)) + (is / (nr * vt)) * ee**(vd / (nr * vt)) -- Helper Programs ------------------------------------- nn = [(name * 100)..] ii = [(name * 100)..] ivsrc src z = (z!!((idx src j) + ((length i) - 1))) where idx n l = fromJust (elemIndex n l) vnode node z | node == 0 = 0 | otherwise = z!!(nn' - 1) where nn' = fromJust (elemIndex node i) j = nSRC (simInfo z0) i = nNODE (simInfo z0) -------------------------------------------------------- -- intrinsic (Ebers-Moll) bipolar junction transistor (NPN) -- Pin C(p1) B(p2) E(p3) npn1 :: Int -> Int -> Int -> Int -> ESim -> [Device] npn1 name p1 p2 p3 z0 | (simType (simInfo z0)) == OP = (dio1 (nn!!0) p1 p2 z0) ++ (dio1 (nn!!1) p3 p2 z0) ++ (isrc1 (nn!!2) p2 p1 icc z0) ++ (isrc1 (nn!!3) p2 p3 iee z0) | (simType (simInfo z0)) == TRANS = (dio1 (nn!!0) p1 p2 z0) ++ (dio1 (nn!!1) p3 p2 z0) ++ (isrc1 (nn!!2) p2 p1 icc z0) ++ (isrc1 (nn!!3) p2 p3 iee z0) | otherwise = error "dio: No internal model defined" --- Model Equations ------------------------------------------ where ar = 0.7 af = 0.995 icc = af * (idd (vp2 - vp3)) iee = ar * (idd (vp2 - vp1)) is = 1e-14 ee = exp 1 n = 1.0 vt = 0.02587 idd vd = is * ((ee**(vd / (n * vt))) - 1) vp1 = vnode p1 (nrData z0) vp2 = vnode p2 (nrData z0) vp3 = vnode p3 (nrData z0) -- Helper Programs ------------------------------------- nn = [(name * 100)..] ii = [(name * 100)..] ivsrc src z = (z!!((idx src j) + ((length i) - 1))) where idx n l = fromJust (elemIndex n l) vnode node z | node == 0 = 0 | otherwise = z!!(nn' - 1) where nn' = fromJust (elemIndex node i) j = nSRC (simInfo z0) i = nNODE (simInfo z0) -------------------------------------------------------- data VStep = VStep { vlim :: Double --default 40 , tlim :: Double --default 5 , steps :: Double --default 8 } deriving (Show) defaultVStep = VStep 40 5 8 -- voltage source with voltage stepping support. vsrc2 :: Int -> Int -> Int -> Double -> VStep -> ESim -> [Device] vsrc2 name p1 p2 vp v0 z0 | (simType (simInfo z0)) == OP = (vsrc1 name p1 p2 v z0) | (simType (simInfo z0)) == TRANS = (vsrc1 name p1 p2 v z0) | otherwise = error "vsrc2 : No internal model defined" --- Model Equations ------------------------------------------ where v = vp * vstep vstep | abs vp > vlim v0 && nrSteps z0 < steps v0 && trSteps z0 < tlim v0 = nrSteps z0 / steps v0 | otherwise = 1.0 --vn = abs (abs (vp1 - vp2) - abs vp) --vp1 = vnode p1 (trData z0) --vp2 = vnode p2 (trData z0) -- Helper Programs ------------------------------------- nn = [(name * 100)..] ii = [(name * 100)..] ivsrc src z = (z!!((idx src j) + ((length i) - 1))) where idx n l = fromJust (elemIndex n l) vnode node z | node == 0 = 0 | otherwise = z!!(nn' - 1) where nn' = fromJust (elemIndex node i) j = nSRC (simInfo z0) i = nNODE (simInfo z0) -------------------------------------------------------- -- sine wave no voltage stepping. vsrc3 :: Int -> Int -> Int -> Double ->Double -> ESim -> [Device] vsrc3 name p1 p2 vp f z0 | (simType (simInfo z0)) == OP = (vsrc1 name p1 p2 0 z0) | (simType (simInfo z0)) == TRANS = (vsrc1 name p1 p2 v z0) | otherwise = error "vsrc2 : No internal model defined" --- Model Equations ------------------------------------------ where v = vp * (sin trad) trad = (2 * pi / t) * tt * (trSteps z0) tt = (simParam (simInfo z0))!!0 t = 1 / f -------------------------------------------------------- -- sinewave with voltage stepping vsrc4 :: Int -> Int -> Int -> Double ->Double -> VStep -> ESim -> [Device] vsrc4 name p1 p2 vp f v0 z0 | (simType (simInfo z0)) == OP = (vsrc2 name p1 p2 0 v0 z0) | (simType (simInfo z0)) == TRANS = (vsrc2 name p1 p2 v v0 z0) | otherwise = error "vsrc2 : No internal model defined" --- Model Equations ------------------------------------------ where v = vp * (sin trad) trad = (2 * pi / t) * tt * (trSteps z0) tt = (simParam (simInfo z0))!!0 t = 1 / f -------------------------------------------------------- -- vsrc5 - piecewise voltage source without voltage stepping. vsrc5 :: Int -> Int -> Int -> [(Double,Double)] -> ESim -> [Device] vsrc5 name p1 p2 vl z0 | (simType (simInfo z0)) == OP = (vsrc1 name p1 p2 0 z0) | (simType (simInfo z0)) == TRANS = (vsrc1 name p1 p2 v z0) | otherwise = error "vsrc5 : No internal model defined" --- Model Equations ------------------------------------------ where v = vp (zl (trSteps z0)) vl --vp _ [] = fst (last vl) vp z (v:vs) | z == 0 = fst v | length (v:vs) == 1 = fst (last vl) | z < snd (head vs) / tt && slope > 0 = fst v + ((z - snd v / tt) * slope) | z < snd (head vs) / tt && slope < 0 = fst v + ((z - snd v / tt) * slope) | otherwise = vp z vs where slope = (fst (head vs) - fst v) / ((snd (head vs) / tt) - snd v / tt) tt = (simParam (simInfo z0))!!0 end = truncate ((snd (last vl)) / tt) zl tr = 0 + (fromInteger ((truncate tr) `rem` end)) -------------------------------------------------------- -- vsrc6 - piecewise voltage source with voltage stepping. vsrc6 :: Int -> Int -> Int -> [(Double,Double)] -> VStep -> ESim -> [Device] vsrc6 name p1 p2 vl v0 z0 | (simType (simInfo z0)) == OP = (vsrc2 name p1 p2 0 v0 z0) | (simType (simInfo z0)) == TRANS = (vsrc2 name p1 p2 v v0 z0) | otherwise = error "vsrc6 : No internal model defined" --- Model Equations ------------------------------------------ where v = vp (zl (trSteps z0)) vl vp z (v:vs) | z <= (snd v / tt) = fst v | length (v:vs) == 1 = fst (last vl) | z < snd (head vs) / tt && slope > 0 = fst v + ((z - snd v / tt) * slope) | z < snd (head vs) / tt && slope < 0 = fst v + ((z - snd v / tt) * slope) | otherwise = vp z vs where slope = (fst (head vs) - fst v) / ((snd (head vs) / tt) - snd v / tt) tt = (simParam (simInfo z0))!!0 end = truncate ((snd (last vl)) / tt) zl tr = 0 + (fromInteger ((truncate tr) `rem` end)) -------------------------------------------------------- -- ideal transformer trf1 :: Int -> Int -> Int -> Int -> Int -> Double -> ESim -> [Device] trf1 name p1 p2 p3 p4 a z0 | (simType (simInfo z0)) == OP = (vcvs1 (nn!!0) (ii!!0) p3 p2 p1 a z0) ++ (cccs1 (nn!!1) p1 p2 p4 (ii!!0) a z0) | (simType (simInfo z0)) == TRANS = (vcvs1 (nn!!0) (ii!!0) p3 p2 p1 a z0) ++ (cccs1 (nn!!1) p1 p2 p4 (ii!!0) a z0) | otherwise = error "trf1 : No internal model defined" --- Model Equations ------------------------------------------ where -- Helper Programs ------------------------------------- nn = [(name * 100)..] ii = [(name * 100)..] ivsrc src z = (z!!((idx src j) + ((length i) - 1))) where idx n l = fromJust (elemIndex n l) vnode node z | node == 0 = 0 | otherwise = z!!(nn' - 1) where nn' = fromJust (elemIndex node i) j = nSRC (simInfo z0) i = nNODE (simInfo z0) --------------------------------------------------------