diff --git a/.editorconfig b/.editorconfig index 7e9b8b8..0e6b965 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,10 @@ insert_final_newline = false indent_size = 2 max_line_length= 80 +[*.nix] +indent_size = 2 +max_line_length= 80 + [*.fs] max_line_length= 120 @@ -21,6 +25,7 @@ fsharp_space_before_uppercase_invocation = true fsharp_blank_lines_around_nested_multiline_expressions = false fsharp_newline_between_type_definition_and_members = false fsharp_multiline_bracket_style = stroustrup +fsharp_multi_line_lambda_closing_newline = true fsharp_array_or_list_multiline_formatter = character_width fsharp_max_array_or_list_width = 70 diff --git a/shell.nix b/shell.nix index 22029d1..01aee42 100644 --- a/shell.nix +++ b/shell.nix @@ -2,15 +2,19 @@ with import { }; let dotnet-sdk = dotnet-sdk_9; in -mkShell { - buildInputs = [ - netcdf +mkShell rec { + packages = [ bun dotnet-sdk + fsautocomplete + fantomas + ]; + + buildInputs = [ + netcdf + stdenv.cc.cc.lib ]; DOTNET_ROOT = "${dotnet-sdk}/share/dotnet"; - shellHook = '' - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${stdenv.cc.cc.lib}/lib; - ''; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; } diff --git a/src/Grid.fs b/src/Grid.fs index f97f352..69da993 100644 --- a/src/Grid.fs +++ b/src/Grid.fs @@ -9,7 +9,7 @@ open ProjNet.FSharp open MessagePack open MBrace.FsPickler //open FsKDTree -open KdTree // C# version +open KdTree // NOTE: C# version open Types @@ -21,8 +21,8 @@ type Elem = NodeIdx * NodeIdx * NodeIdx type Node = float * float type Pos = float * float -type Leaf<'a> = { Pos : Pos; Data : 'a } -type Field = (float * float) [] +type Leaf<'a> = { Pos: Pos; Data: 'a } +type Field = (float * float) array type Cell = NodeIdx * NodeIdx * NodeIdx @@ -30,16 +30,15 @@ type IGrid = abstract getVertex: int -> Vertex abstract getCell: int -> Cell abstract getCellVertices: int -> Vertex * Vertex * Vertex - abstract getVertices: unit -> Vertex [] - abstract getCells: unit -> Cell [] + abstract getVertices: unit -> Vertex array + abstract getCells: unit -> Cell array abstract getBoundingBox: unit -> BBox -type Grid = - { - Elem: Elem array - Nodes: Node array - BBox: BBox - } +type Grid = { + Elem: Elem array + Nodes: Node array + BBox: BBox +} with interface IGrid with member this.getVertex n = this.Nodes[n] member this.getCell n = this.Elem[n] @@ -49,34 +48,30 @@ type Grid = member this.getVertices() = this.Nodes member this.getCells() = this.Elem member this.getBoundingBox() = this.BBox - static member empty = - { - Elem = Array.empty - Nodes = Array.empty - BBox = BBox.empty - } + static member empty = { Elem = Array.empty; Nodes = Array.empty; BBox = BBox.empty } -type ElemsAroundNode = Map -type NodesAroundNode = Map +type ElemsAroundNode = Map +type NodesAroundNode = Map +type ElemsAroundElem = Map -type NeighborIndex = - { - ElemsAroundNode: ElemsAroundNode - NodesAroundNode: NodesAroundNode - } - static member empty = { ElemsAroundNode = Map.empty; NodesAroundNode = Map.empty } +type NeighborIndex = { + ElemsAroundNode: ElemsAroundNode + NodesAroundNode: NodesAroundNode + ElemsAroundElem: ElemsAroundElem +} with + static member empty = { ElemsAroundNode = Map.empty; NodesAroundNode = Map.empty; ElemsAroundElem = Map.empty } type private Ean = Map // NOTE(SimenLK): The amount of items to be stored in the trees leafs // let treeLeafSize = LeafNodeSize 64 -let private createTree (points: Leaf []) = - let tree = KdTree(2, KdTree.Math.DoubleMath()) +let private createTree (points: Leaf array) = + let tree = KdTree (2, KdTree.Math.DoubleMath ()) points - |> Array.iter (fun a -> tree.Add([| fst a.Pos; snd a.Pos |], a.Data) |> ignore) + |> Array.iter (fun a -> tree.Add ([| fst a.Pos; snd a.Pos |], a.Data) |> ignore) if points.Length > 0 then - tree.Balance() + tree.Balance () else Log.Warning $"Empty kd-tree" tree @@ -89,12 +84,9 @@ let private makeElemsSurroundingNodeMap (elem: Elem array) : ElemsAroundNode = elem |> Array.fold (fun (n, acc) (a, b, c) -> - let acc' = - acc - |> addElIdx a n - |> addElIdx b n - |> addElIdx c n - n + 1, acc') + let acc' = acc |> addElIdx a n |> addElIdx b n |> addElIdx c n + n + 1, acc' + ) (0, Map.empty) |> snd |> Map.mapValues toArray @@ -108,12 +100,9 @@ let private makeElemsSurroundingNodeMap' (elem: Elem array) : ElemsAroundNode = elem |> Array.fold (fun (n, acc) (a, b, c) -> - let acc' = - acc - |> addElemIdx a n - |> addElemIdx b n - |> addElemIdx c n - n + 1, acc') + let acc' = acc |> addElemIdx a n |> addElemIdx b n |> addElemIdx c n + n + 1, acc' + ) (0, Map.empty) |> snd |> Map.mapValues toArray @@ -124,13 +113,26 @@ let private makeNodesSurroudingNodeMap (n2e: ElemsAroundNode) (elem: Elem array) n |> Array.collect (fun x -> let n1, n2, n3 = elem[x] - [| n1; n2; n3 |]) - |> Array.distinct) + [| n1; n2; n3 |] + ) + |> Array.distinct + ) -let getSurrounding (idx: Map) (a, b, c) = - [| idx[a]; idx[b]; idx[c] |] - |> Array.concat - |> Array.distinct +let private makeElemsSurroundingElemMap (ean: ElemsAroundNode) (elem: Elem array) : ElemsAroundElem = + elem + |> Array.mapi (fun elemIdx (n1, n2, n3) -> + // For each element, find all elements that share any of its nodes + let surroundingElems = + [| ean[n1]; ean[n2]; ean[n3] |] + |> Array.concat + |> Array.distinct + |> Array.filter (fun x -> x <> elemIdx) // Remove self + elemIdx, surroundingElems + ) + |> Map.ofArray + +let getSurrounding (idx: Map) (a, b, c) = + [| idx[a]; idx[b]; idx[c] |] |> Array.concat |> Array.distinct let makeNeighborIndex (grid: IGrid) = let elem = grid.getCells () @@ -138,14 +140,17 @@ let makeNeighborIndex (grid: IGrid) = { ElemsAroundNode = ean NodesAroundNode = makeNodesSurroudingNodeMap ean elem + ElemsAroundElem = makeElemsSurroundingElemMap ean elem } let getElemsSurroundingNode (idx: NeighborIndex) n = idx.ElemsAroundNode[n] let getNodesSurroundingNode (idx: NeighborIndex) n = idx.NodesAroundNode[n] -let getNodesSurroundingElem (idx: NeighborIndex) (grid: Grid) e = - getSurrounding idx.NodesAroundNode grid.Elem[e] +let getNodesSurroundingElem (idx: NeighborIndex) e = idx.ElemsAroundElem[e] + +// let getNodesSurroundingElem (idx: NeighborIndex) (grid: Grid) e = + // getSurrounding idx.NodesAroundNode grid.Elem[e] let getElemsSurroundingElem (idx: NeighborIndex) (grid: Grid) e = getSurrounding idx.ElemsAroundNode grid.Elem[e] @@ -182,69 +187,68 @@ let bboxToLngLat (coordsys: CoordinateSystem) b = let projectBBox proj b = let x0, y0 = proj (b.minX, b.minY) let x1, y1 = proj (b.maxX, b.maxY) - { minX = x0; maxX = x1; minY = y0; maxY = y1; center = proj b.center } + { + minX = x0 + maxX = x1 + minY = y0 + maxY = y1 + center = proj b.center + } -let projectGrid proj (grid: Grid) : Grid = - { grid with +let projectGrid proj (grid: Grid) : Grid = { + grid with Nodes = grid.Nodes |> Array.Parallel.map proj BBox = projectBBox proj grid.BBox - } +} let rescaleGrid (factor: float) (grid: Grid) : Grid = let nodes' = grid.Nodes |> Array.Parallel.map (fun (x, y) -> factor * x, factor * y) let bbox' = calcBBox nodes' - { grid with - Nodes = nodes' - BBox = bbox' - } + { grid with Nodes = nodes'; BBox = bbox' } let translateGrid (x0, y0) grid = let nodes' = grid.Nodes |> Array.Parallel.map (fun (x, y) -> x + x0, y + y0) let bbox' = calcBBox nodes' - { grid with - Nodes = nodes' - BBox = bbox' - } + { grid with Nodes = nodes'; BBox = bbox' } let toWebMercator (coordsys: CoordinateSystem) (grid: Grid) = let toWebMercator = makeTransform coordsys CoordSys.EPSG3857 - let s = System.Diagnostics.Stopwatch.StartNew() + let s = System.Diagnostics.Stopwatch.StartNew () let g = grid |> projectGrid toWebMercator.project - s.Stop() + s.Stop () Log.Debug $"Reprojected grid: {s.ElapsedMilliseconds} ms" g let toLonLat (coordsys: CoordinateSystem) (grid: Grid) = let toLonLat = makeTransform coordsys CoordSys.WGS84 - let s = System.Diagnostics.Stopwatch.StartNew() + let s = System.Diagnostics.Stopwatch.StartNew () let g = grid |> projectGrid toLonLat.project - s.Stop() + s.Stop () Log.Debug $"Reprojected grid: {s.ElapsedMilliseconds} ms" g let private chomp (l: string) = l.Split ' ' |> Array.filter ((<>) "") // TODO: pattern match and compare sizes for more flex -let private readGrdHeader (h: string []) = +let private readGrdHeader (h: string[]) = let parse x = (chomp x)[3] |> int try let nodes = parse h[0] let nele = parse h[1] - Some(nodes, nele) - with - | _ -> None + Some (nodes, nele) + with _ -> + None let private readObcHeader (h: string) = try (chomp h)[4] |> int |> Some - with - | _ -> None + with _ -> + None -let private reader (parser: string [] -> 'a) (f: string array) = +let private reader (parser: string[] -> 'a) (f: string array) = try f |> Array.map (chomp >> parser) |> Some - with - | e -> + with e -> Log.Error e.Message None @@ -282,13 +286,13 @@ let readGrdFile (filename: string) = let elem = readElem els let nodes = readNodes nds let toGrid e n = { Elem = e; Nodes = n; BBox = calcBBox n } - toGrid elem <*> nodes) + toGrid elem <*> nodes + ) let readObcFile (filename: string) = let f = System.IO.File.ReadAllLines filename let hdr, rest = Array.splitAt 1 f - readObcHeader hdr[0] - |> Option.bind (fun _ -> readObc rest) + readObcHeader hdr[0] |> Option.bind (fun _ -> readObc rest) module Boundary = let normalizeElement (a, b, c) = @@ -302,11 +306,8 @@ module Boundary = match Map.tryFind edge a with | Some v -> Map.add edge (n :: v) a | None -> Map.add edge [ n ] a - let appendEdges a (n, x: Edge []) = - a - |> appendEdge (n, x[0]) - |> appendEdge (n, x[1]) - |> appendEdge (n, x[2]) + let appendEdges a (n, x: Edge[]) = + a |> appendEdge (n, x[0]) |> appendEdge (n, x[1]) |> appendEdge (n, x[2]) grid.Elem |> Array.mapi normElIdx |> Array.fold appendEdges Map.empty @@ -324,8 +325,7 @@ module Boundary = |> Map.mapValues (fun x -> List.head x, List.last x) let makeBoundaryByElementMap (edgeMap: Map) = - edgeMap - |> Map.fold (fun a k v -> Map.add v k a) Map.empty + edgeMap |> Map.fold (fun a k v -> Map.add v k a) Map.empty let getBoundaryNodesArray (edgeMap: Map) = edgeMap @@ -345,8 +345,7 @@ module Util = (x0 + x1 + x2) / 3f, (y0 + y1 + y2) / 3f static member calcArea((x0, y0), (x1, y1), (x2, y2)) = - x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1) - |> (*) 0.5 + x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1) |> (*) 0.5 // static member calcArea((x0, y0), (x1, y1), (x2, y2)) = // x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1) @@ -364,20 +363,20 @@ module Util = let Sy = det Tx T2 E |> (*) 0.5 let a = det Tx Ty E let b = det Tx Ty T2 - if abs a < 1.0e-12 then failwith "co-linear vertices" + if abs a < 1.0e-12 then + failwith "co-linear vertices" let S2 = (Sx, Sy) |> square let r = (b / a + S2 / (a * a)) |> sqrt Sx / a, Sy / a, r - static member propToNodal (nIdx: NeighborIndex) (s: float []) = + static member propToNodal (nIdx: NeighborIndex) (s: float[]) = [| 0 .. nIdx.NodesAroundNode.Count - 1 |] // total number of nodes |> Array.Parallel.map (fun i -> let ns = nIdx.ElemsAroundNode[i] - ns - |> Array.fold (fun a n -> s[n] + a) 0. - |> (*) (1. / float ns.Length)) + ns |> Array.fold (fun a n -> s[n] + a) 0. |> (*) (1. / float ns.Length) + ) - static member speedToNodal (nIdx: NeighborIndex) (s: (float * float) []) = + static member speedToNodal (nIdx: NeighborIndex) (s: (float * float)[]) = [| 0 .. nIdx.NodesAroundNode.Count - 1 |] // total number of nodes |> Array.Parallel.map (fun i -> let ns = nIdx.ElemsAroundNode[i] @@ -385,11 +384,13 @@ module Util = |> Array.fold (fun a n -> let u, v = s[n] - sqrt (u * u + v * v) + a) + sqrt (u * u + v * v) + a + ) 0. - |> (*) (1. / float ns.Length)) + |> (*) (1. / float ns.Length) + ) - static member velocityToNodal (nIdx: NeighborIndex) (s: (float * float) []) = + static member velocityToNodal (nIdx: NeighborIndex) (s: (float * float)[]) = [| 0 .. nIdx.NodesAroundNode.Count - 1 |] // total number of nodes |> Array.Parallel.map (fun i -> let ns = nIdx.ElemsAroundNode[i] @@ -398,9 +399,11 @@ module Util = |> Array.fold (fun (au, av) n -> let u, v = s[n] - u + au, v + av) + u + au, v + av + ) (0., 0.) - |> fun (u, v) -> u / n, v / n) + |> fun (u, v) -> u / n, v / n + ) type Node = static member calcNodeControlArea (idx: NeighborIndex) (grid: IGrid) = @@ -419,8 +422,10 @@ module Util = let centroid = Element.calcCentroid (p0, p1, p2) let a1 = Element.calcArea (p0', p1', p2') let a2 = Element.calcArea (p1', centroid, p2') - a1 + a2) - |> Array.sum) + a1 + a2 + ) + |> Array.sum + ) static member calcNodeArea (idx: NeighborIndex) (grid: IGrid) = let nodes = grid.getVertices () @@ -428,7 +433,8 @@ module Util = |> Array.Parallel.map (fun n -> getElemsSurroundingNode idx n |> Array.map (grid.getCellVertices >> Element.calcArea) - |> Array.sum) + |> Array.sum + ) let calcCentroids (grid: IGrid) = let n = grid.getVertices () @@ -437,12 +443,12 @@ module Util = let p0 = n[a] let p1 = n[b] let p2 = n[c] - Element.calcCentroid (p0, p1, p2)) + Element.calcCentroid (p0, p1, p2) + ) let inline isInsideTriangle (x, y, z) p = let sign (p1x, p1y) (p2x, p2y) (p3x, p3y) = - (p1x - p3x) * (p2y - p3y) - - (p2x - p3x) * (p1y - p3y) + (p1x - p3x) * (p2y - p3y) - (p2x - p3x) * (p1y - p3y) let d1 = sign p x y let d2 = sign p y z @@ -458,7 +464,8 @@ module Util = grid.getVertices () |> Array.mapi (fun i v -> let x, y = v - { Pos = x, y; Data = i }) + { Pos = x, y; Data = i } + ) // |> create2DTree treeLeafSize |> createTree @@ -466,12 +473,10 @@ module Util = let buildNearestElementTree (grid: IGrid) = grid.getCells () |> Array.mapi (fun i _ -> - let pos = - i - |> grid.getCellVertices - |> Element.calcCentroid - // |> fun (x, y) -> { X = x; Y = y } - { Pos = pos; Data = i }) + let pos = i |> grid.getCellVertices |> Element.calcCentroid + // |> fun (x, y) -> { X = x; Y = y } + { Pos = pos; Data = i } + ) // |> create2DTree treeLeafSize |> createTree @@ -487,14 +492,15 @@ module Util = // else None) let tryFindElement (grid: IGrid) (tree: KdTree) ((p0, p1): float * float) = - tree.GetNearestNeighbours([| p0; p1 |], 1) + tree.GetNearestNeighbours ([| p0; p1 |], 1) |> Array.tryHead |> Option.bind (fun leaf -> let vx = grid.getCellVertices leaf.Value if isInsideTriangle vx (p0, p1) then Some leaf.Value else - None) + None + ) // type private IdxTree = Tree array, Node> // type private NodeIdxTree = Tree array, Node> @@ -503,22 +509,20 @@ type private NodeIdxTree = KdTree [] type BinGrid = { - [] hash : byte[] - [] vertices : (float * float)[] - [] cells : (int * int * int)[] + [] + hash: byte[] + [] + vertices: (float * float)[] + [] + cells: (int * int * int)[] } with - member this.toGrid (): Grid = - { - Nodes = this.vertices - Elem = this.cells - BBox = calcBBox this.vertices - } + member this.toGrid() : Grid = { Nodes = this.vertices; Elem = this.cells; BBox = calcBBox this.vertices } type ExtendedGrid(grid: IGrid) = let mutable nodeTree: NodeIdxTree option = None let mutable elementTree: IdxTree option = None let mutable neighborIndex: NeighborIndex option = None - let mutable centroids: Vertex [] option = None + let mutable centroids: Vertex[] option = None let mutable gridHash: byte[] = [||] let getNeighborIdx () = @@ -542,12 +546,11 @@ type ExtendedGrid(grid: IGrid) = member this.Grid = grid - member this.ToGrid() = - { - Nodes = this.Grid.getVertices () - Elem = this.Grid.getCells () - BBox = this.Grid.getBoundingBox () - } + member this.ToGrid() = { + Nodes = this.Grid.getVertices () + Elem = this.Grid.getCells () + BBox = this.Grid.getBoundingBox () + } member this.initNeighborIndex(?cache: string) = @@ -567,7 +570,7 @@ type ExtendedGrid(grid: IGrid) = member this.nearestNode(p0: float, p1: float) = let nearest (tree: KdTree<_, _>) = - tree.GetNearestNeighbours([| p0; p1 |], 1) + tree.GetNearestNeighbours ([| p0; p1 |], 1) |> Array.tryHead |> Option.map (fun l -> l.Value) match nodeTree with @@ -580,32 +583,38 @@ type ExtendedGrid(grid: IGrid) = this.nearestNode p |> Option.bind (fun n -> this.getElemsSurroundingNode n - |> Array.fold (fun (a: int option) e -> - if a.IsNone then - let vx = this.Grid.getCellVertices e - if Util.isInsideTriangle vx p then Some n else None - else a) None - ) + |> Array.fold + (fun (a: int option) e -> + if a.IsNone then + let vx = this.Grid.getCellVertices e + if Util.isInsideTriangle vx p then Some n else None + else + a + ) + None + ) member private this.tryFindElementTwice (grid: IGrid) (tree: IdxTree) ((p0, p1): float * float as p) = Util.tryFindElement grid tree p |> Option.orElse ( - tree.GetNearestNeighbours([| p0; p1 |], 1) + tree.GetNearestNeighbours ([| p0; p1 |], 1) |> Array.tryHead |> Option.bind (fun leaf -> this.getElemsSurroundingElem leaf.Value |> Array.tryFind (fun eIdx -> let vx = this.Grid.getCellVertices eIdx - Util.isInsideTriangle vx p)) + Util.isInsideTriangle vx p + ) ) + ) member this.tryGetElement p = elementTree - |> Option.bind (fun tree -> - this.tryFindElementTwice grid tree p) + |> Option.bind (fun tree -> this.tryFindElementTwice grid tree p) |> Option.orElseWith (fun () -> this.initElementTree () - this.tryFindElementTwice grid elementTree.Value p) + this.tryFindElementTwice grid elementTree.Value p + ) member this.tryGetElementSloppy(p0, p1 as p) = match elementTree with @@ -621,18 +630,18 @@ type ExtendedGrid(grid: IGrid) = member this.getHash() = if gridHash.Length = 0 then - let bg : BinGrid = { + let bg: BinGrid = { hash = [||] vertices = (this :> IGrid).getVertices () cells = (this :> IGrid).getCells () } - let bytes = MessagePackSerializer.Serialize(bg) - let sha1 = System.Security.Cryptography.SHA1.Create() + let bytes = MessagePackSerializer.Serialize (bg) + let sha1 = System.Security.Cryptography.SHA1.Create () gridHash <- sha1.ComputeHash bytes gridHash member this.getHashString() = - this.getHash() |> Convert.ToHexStringLower + this.getHash () |> Convert.ToHexStringLower member this.getCentroids() = match centroids with @@ -647,12 +656,10 @@ type ExtendedGrid(grid: IGrid) = Util.Element.calcCircumscribedCircle triangle member this.getElemsSurroundingNode n = - getNeighborIdx () - |> fun idx -> idx.ElemsAroundNode[n] + getNeighborIdx () |> fun idx -> idx.ElemsAroundNode[n] member this.getNodesSurroundingNode n = - getNeighborIdx () - |> fun idx -> idx.NodesAroundNode[n] + getNeighborIdx () |> fun idx -> idx.NodesAroundNode[n] member this.getNodesSurroundingElem e = let idx = getNeighborIdx () @@ -665,35 +672,34 @@ type ExtendedGrid(grid: IGrid) = getSurrounding idx.ElemsAroundNode elem member this.saveNeighborIndex(fname: string) = - let binarySerializer = FsPickler.CreateBinarySerializer() + let binarySerializer = FsPickler.CreateBinarySerializer () let nix = getNeighborIdx () let pickle = binarySerializer.Pickle nix - IO.File.WriteAllBytes(fname, pickle) + IO.File.WriteAllBytes (fname, pickle) member this.loadNeighborIndex(fname: string) = - let binarySerializer = FsPickler.CreateBinarySerializer() + let binarySerializer = FsPickler.CreateBinarySerializer () if IO.File.Exists fname then let pickle = IO.File.ReadAllBytes fname - neighborIndex <- - binarySerializer.UnPickle pickle - |> Some + neighborIndex <- binarySerializer.UnPickle pickle |> Some true else false member this.saveNodeTree(fname: string) = - let binarySerializer = FsPickler.CreateBinarySerializer() + let binarySerializer = FsPickler.CreateBinarySerializer () let tree = nodeTree |> Option.defaultWith (fun () -> this.initNodeTree () - nodeTree.Value) + nodeTree.Value + ) let pickle = binarySerializer.Pickle tree - IO.File.WriteAllBytes(fname, pickle) + IO.File.WriteAllBytes (fname, pickle) member this.loadNodeTree(fname: string) = - let binarySerializer = FsPickler.CreateBinarySerializer() + let binarySerializer = FsPickler.CreateBinarySerializer () if IO.File.Exists fname then let pickle = IO.File.ReadAllBytes fname nodeTree <- binarySerializer.UnPickle pickle |> Some @@ -702,18 +708,19 @@ type ExtendedGrid(grid: IGrid) = false member this.saveElementTree(fname: string) = - let binarySerializer = FsPickler.CreateBinarySerializer() + let binarySerializer = FsPickler.CreateBinarySerializer () let tree = elementTree |> Option.defaultWith (fun () -> this.initElementTree () - elementTree.Value) + elementTree.Value + ) let pickle = binarySerializer.Pickle tree - IO.File.WriteAllBytes(fname, pickle) + IO.File.WriteAllBytes (fname, pickle) member this.loadElementTree(fname: string) = - let binarySerializer = FsPickler.CreateBinarySerializer() + let binarySerializer = FsPickler.CreateBinarySerializer () if IO.File.Exists fname then let pickle = IO.File.ReadAllBytes fname elementTree <- binarySerializer.UnPickle pickle |> Some diff --git a/src/Oceanbox.FvcomKit.fsproj b/src/Oceanbox.FvcomKit.fsproj index 40a19cd..1054c27 100644 --- a/src/Oceanbox.FvcomKit.fsproj +++ b/src/Oceanbox.FvcomKit.fsproj @@ -5,6 +5,7 @@ net9.0 true Oceanbox.FvcomKit + linux-x64 5.12.2