Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/escomma/AC.hs

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


--------------------------------------------------------------------------------
module AC where

import Circuit
import Array
import List
import Matrix.Complex.LU
import Complex 

---- Y node admittance matrix
---- v vector of unknown voltages
---- i equivalent current source vector

--- Build matrix Y of Yv = i
mk_Y :: [([Int], [Double])] -> [Double] -> Array (Int, Int) (Complex Double)       
mk_Y (e:es) param = array ((1, 1), (n, n)) 
          ([((i, j), z i j) | i <- [1..n], j <- [1..n]])
            where z i j | i <= m && j <= m 
                             = yy_1 i j (admList (e:es))
                        | i > m || j > m 
                             = yy_2 i j (srcList (e:es))
                        | otherwise = 0
                  
                  yy_2 _ _ [] = 0
                  yy_2 i j (e:es) | typeDev (fst e) == tVAC    
                                    = vsrc i j (e:es) + yy_2 i j es
                                  | otherwise = yy_2 i j es                              
                  yy_1 _ _ [] = 0
                  yy_1 i j (e:es) | typeDev (fst e) == tRES
                                    = adm i j (e:es) + yy_1 i j es
                                  | typeDev (fst e) == tCAP
                                    = cap i j (e:es) + yy_1 i j es 
                                  | typeDev (fst e) == tIND
                                    = ind i j (e:es) + yy_1 i j es 
                                  | otherwise = yy_1 i j es
                               
                  adm m n (e:es) | m == nodez 1 (fst e) && n == nodez 2 (fst e) 
                                      = -1 * (((snd e)!!0) :+ 0) 
                                 | n == nodez 1 (fst e) && m == nodez 2 (fst e) 
                                      = -1 * (((snd e)!!0) :+ 0)   
                                 | n == m && (n == nodez 1 (fst e) || 
                                   m == nodez 2 (fst e))   
                                      = (((snd e)!!0) :+ 0)
                                 | otherwise = 0
 
                  ind m n (e:es) | m == nodez 1 (fst e) && n == nodez 2 (fst e) 
                                      = -1.0 / (0 :+ (xL ((snd e)!!0))) 
                                 | n == nodez 1 (fst e) && m == nodez 2 (fst e) 
                                      = -1.0 / (0 :+ (xL ((snd e)!!0)))
                                 | n == m && (n == nodez 1 (fst e) || 
                                   m == nodez 2 (fst e))   
                                      = 1.0 / (0 :+ (xL ((snd e)!!0)))
                                 | otherwise = 0
 
                  cap m n (e:es) | m == nodez 1 (fst e) && n == nodez 2 (fst e) 
                                      = -1.0 / (0 :+ (xC ((snd e)!!0))) 
                                 | n == nodez 1 (fst e) && m == nodez 2 (fst e) 
                                      = -1.0 / (0 :+ (xC ((snd e)!!0))) 
                                 | n == m && (n == nodez 1 (fst e) || 
                                   m == nodez 2 (fst e))   
                                      = 1.0 / (0 :+ (xC ((snd e)!!0))) 
                                 | otherwise = 0
                               
                  vsrc i j (e:es) | length es == (u - i) && 
                                            j == nodez 1 (fst e) = 1
                                  | length es == (u - i) && 
                                            j == nodez 2 (fst e) = 1
                                  | length es == (u - j) && 
                                            i == nodez 1 (fst e) = 1
                                  | length es == (u - j) && 
                                            i == nodez 2 (fst e) = -1
                                  | otherwise = 0      
                  
                  m = ncol (e:es)
                  n = nrow (e:es) 
                  u = m + length (srcList (e:es))
                  freq = param!!pFREQ 
                  xC value = -1.0 / (value * 2 * pi  * freq) 
                  xL value = value * 2 * pi * freq
                 
--------------------------------------------------------------------------------
--- Build vector i of Yv = i
mk_i :: [([Int], [Double])] -> [Double] -> Array Int (Complex Double)    
mk_i (e:es) param = array (1, n) ([(j, z j) | j <- [1..n]])
          where z j | j <= m = ii_1 j (srcList (e:es)) 
                    | otherwise = ii_2 j (srcList (e:es))
                
                ii_1 _ [] = 0
                ii_1 j (e:es) | typeDev (fst e) == tIAC 
                                = isrc j (e:es) + ii_1 j es
                              | otherwise = ii_1 j es 
                
                ii_2 _ [] = 0
                ii_2 j (e:es) | typeDev (fst e) == tVAC 
                                = vsrc j (e:es) + ii_2 j es
                              | otherwise = ii_2 j es 
                
                vsrc j (v:vs) | length vs == (u - j) = ((snd v)!!0):+0      
                              | otherwise = 0 
                 
                isrc j (i:is) | j == nodez 1 (fst i) = (((snd i)!!0) :+ 0) 
                              | j == nodez 2 (fst i) = -1 * (((snd i)!!0) :+ 0)  
                              | otherwise = 0
                              
                m = ncol (e:es)
                n = nrow (e:es)
                u = m + length (srcList (e:es))
                          
--- Utilities
typeDev [] = 0
typeDev parm1 = parm1!!0

nodez _ [] = 0   
nodez n parm1 = parm1!!n
                
nodeList [] = []
nodeList (n:ns) = nub (union (tail $ fst n) (nodeList ns)) 

ncol netlist = length (nodeList netlist) - 1
nrow netlist = ncol netlist + length (srcList netlist) 
               - length (isrcList netlist)

srcList [] = []
srcList netlist = vsrcList netlist ++ isrcList netlist

admList [] = []
admList netlist = resList netlist ++ indList netlist ++ capList netlist 


resList :: [([Int], [Double])] -> [([Int], [Double])]
resList [] = []
resList (n:ns) | typeDev (fst n) == tRES = n : resList ns
               | otherwise = resList ns

capList :: [([Int], [Double])] -> [([Int], [Double])]
capList [] = []
capList (n:ns) | typeDev (fst n) == tCAP = n : capList ns
               | otherwise = capList ns

indList :: [([Int], [Double])] -> [([Int], [Double])]
indList [] = []
indList (n:ns) | typeDev (fst n) == tIND = n : indList ns
               | otherwise = indList ns


vsrcList :: [([Int], [Double])] -> [([Int], [Double])]
vsrcList [] = []
vsrcList (n:ns) | typeDev (fst n) == tVAC = n : vsrcList ns
                | otherwise = vsrcList ns

isrcList :: [([Int], [Double])] -> [([Int], [Double])]
isrcList [] = []
isrcList (n:ns) | typeDev (fst n) ==  tISRC = n : isrcList ns
                | otherwise = isrcList ns

-------------------------------------------------------------------------------
--- Solve v of Yv = i

pFREQ :: Int
pFREQ = 0

pPHASE :: Int
pPHASE = 1

acCalc :: [([Int], [Double])] -> [Double] -> Array Int (Complex Double)    
acCalc netlist param = psolve (mk_Y netlist param) (mk_i netlist param)


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].