{-# LANGUAGE Safe #-}

module Main where

import Datatypes
import Assembly
import Common
import Element

import qualified Data.List as L

u0 :: Displacements
u0 = replicate 36 0

-- testCST :: Displacements -> Element
-- testCST = createElement
--           NeoHookean
--           [Properties (Bulk 250),Properties (Shear 0.3)]
--           [Node 0 [1,0,-1]
--           ,Node 1 [0,1,-1]
--           ,Node 2 [0,0,-1]
--           ,Node 3 [1,0,1]
--           ,Node 4 [0,1,1]
--           ,Node 5 [0,0,1]]
--           dndξcst
--           wscst
--           ipscst

-- testCST2 :: Displacements -> Element
-- testCST2 = createElement
--            NeoHookean
--            [Properties (Bulk 250),Properties (Shear 0.3)]
--            [Node 0 [1,0,-1]
--            ,Node 6 [1,1,-1]
--            ,Node 1 [0,1,-1]
--            ,Node 3 [1,0,1]
--            ,Node 7 [1,1,1]
--            ,Node 4 [0,1,1]]
--            dndξcst
--            wscst
--            ipscst

-- bcsCST :: [DOFBC]
-- bcsCST = [DOFBC 2 1 (-1e-1)
--          ,DOFBC 2 2 (-1e-1)
--          ,DOFBC 5 1 (-1e-1)
--          ,DOFBC 5 2 (-1e-1)
--          ,DOFBC 0 1      0
--          ,DOFBC 0 2      0
--          ,DOFBC 3 1      0
--          ,DOFBC 3 2      0]

-- bcsCST2 :: [DOFBC]
-- bcsCST2 = [DOFBC i 3 0 | i <- [0..2]]

props :: [Properties]
props = [Properties (Bulk 250),Properties (Shear 0.3)]

testBrick :: Displacements -> Element
testBrick = createElement NeoHookean props [Node 0 [-1,-1,-1],Node 1 [1,-1,-1],Node 2 [1,1,-1],Node 3 [-1,1,-1],Node 4 [-1,-1,1],Node 5 [1,-1,1],Node 6 [1,1,1],Node 7 [-1,1,1]] dndξbrick wsbrick ipsbrick

testBrick2 :: Displacements -> Element
testBrick2 = createElement NeoHookean props [Node 1 [1,-1,-1],Node 8 [3,-1,-1],Node 9 [3,1,-1],Node 2 [1,1,-1],Node 5 [1,-1,1],Node 10 [3,-1,1],Node 11 [3,1,1],Node 6 [1,1,1]] dndξbrick wsbrick ipsbrick

bcsbrick :: [DOFBC]
bcsbrick = [DOFBC 0 1 0
           ,DOFBC 0 2 0
           ,DOFBC 0 3 0
           ,DOFBC 4 1 0
           ,DOFBC 4 2 0
           ,DOFBC 4 3 0
           ,DOFBC 3 1 1
           ,DOFBC 7 1 1
           ,DOFBC 1 1 0
           ,DOFBC 1 2 0
           ,DOFBC 1 3 0
           ,DOFBC 5 1 0
           ,DOFBC 5 2 0
           ,DOFBC 5 3 0
           ,DOFBC 2 1 1
           ,DOFBC 6 1 1
           ,DOFBC 8 1 0
           ,DOFBC 8 2 0
           ,DOFBC 8 3 0
           ,DOFBC 9 1 1
           ,DOFBC 10 1 0
           ,DOFBC 10 2 0
           ,DOFBC 10 3 0
           ,DOFBC 11 1 1]

bcsoneelemshear :: [DOFBC]
bcsoneelemshear =
  [DOFBC 0 1 0
  ,DOFBC 0 2 0
  ,DOFBC 0 3 0
  ,DOFBC 4 1 0
  ,DOFBC 4 2 0
  ,DOFBC 4 3 0
  ,DOFBC 3 1 1
  ,DOFBC 7 1 1
  ,DOFBC 1 1 0
  ,DOFBC 1 2 0
  ,DOFBC 1 3 0
  ,DOFBC 5 1 0
  ,DOFBC 5 2 0
  ,DOFBC 5 3 0
  ,DOFBC 2 1 1
  ,DOFBC 6 1 1]

bcsoneelemtension :: [DOFBC]
bcsoneelemtension =
  [DOFBC 0 1 0
  ,DOFBC 4 1 0
  ,DOFBC 3 1 0
  ,DOFBC 7 1 0
  ,DOFBC 1 1 1
  ,DOFBC 5 1 1
  ,DOFBC 2 1 1
  ,DOFBC 6 1 1]

ellist :: [Displacements -> Element]
ellist = [testBrick]

writeDat :: FilePath -> [[([Double],Double)]] -> IO ()
writeDat fo vals = writeFile fo (unlines (concatMap (map (\(c,v) -> unwords (map show c ++ [show v]))) vals))

main :: IO ()
main =
  let uten = solveNewtonRaphson ellist bcsoneelemtension u0
      ushear = solveNewtonRaphson ellist bcsoneelemshear u0
      elemten = updateNodalCoords ellist uten
      elemshear = updateNodalCoords ellist ushear
      -- strains = calcStrain ipsbrick elems
      -- stresses = map (\(eid,e) -> (eid,map (\x -> map (\i -> map (\j -> calcStressX props NeoHookean e x i j) indrange) indrange) genξsbrick)) (zip [1..] elems)
      σ11ten = map (\(en,e) -> let {nodes = elnode en; xs = (L.transpose . map coords) nodes} in map (\ξ -> (genfξ nξbrick ξ xs, calcStressX props NeoHookean e ξ 1 1)) genξsbrick) (zip elemten (elDisps ellist uten))
      σ11shear = map (\(en,e) -> let {nodes = elnode en; xs = (L.transpose . map coords) nodes} in map (\ξ -> (genfξ nξbrick ξ xs, calcStressX props NeoHookean e ξ 1 1)) genξsbrick) (zip elemshear (elDisps ellist ushear))
  in
    writeDat "oneelemshearstress.dat" σ11shear >> writeDat "oneelemtenstress.dat" σ11ten
