fix: initial commit
This commit is contained in:
73
.build/Build.fs
Normal file
73
.build/Build.fs
Normal file
@@ -0,0 +1,73 @@
|
||||
open Fake.Core
|
||||
open Fake.IO
|
||||
open Farmer
|
||||
open Farmer.Builders
|
||||
|
||||
open Helpers
|
||||
|
||||
initializeContext()
|
||||
|
||||
let srcPath = Path.getFullName "src"
|
||||
let testPath = Path.getFullName "test"
|
||||
let libPath = None
|
||||
|
||||
let distPath = Path.getFullName "dist"
|
||||
let packPath = Path.getFullName "packages"
|
||||
let versionFile = Path.getFullName ".version"
|
||||
|
||||
Target.create "Clean" (fun _ -> Shell.cleanDir distPath)
|
||||
|
||||
Target.create "InstallClient" (fun _ ->
|
||||
run npm "install" "."
|
||||
run dotnet "tool restore" "."
|
||||
)
|
||||
|
||||
Target.create "Bundle" (fun _ ->
|
||||
run dotnet $"publish -c Release -o {distPath}" srcPath
|
||||
)
|
||||
|
||||
Target.create "BundleDebug" (fun _ ->
|
||||
run dotnet $"publish -c Debug -o {distPath}" srcPath
|
||||
)
|
||||
|
||||
Target.create "Pack" (fun _ ->
|
||||
match libPath with
|
||||
| Some p -> run dotnet $"pack -c Release -o {packPath}" p
|
||||
| None -> ()
|
||||
)
|
||||
|
||||
Target.create "Run" (fun _ -> run dotnet "watch run" srcPath)
|
||||
|
||||
Target.create "Format" (fun _ ->
|
||||
run dotnet "fantomas . -r" "src"
|
||||
)
|
||||
|
||||
Target.create "Test" (fun _ ->
|
||||
if System.IO.Directory.Exists testPath then
|
||||
run dotnet "run" testPath
|
||||
else ()
|
||||
)
|
||||
|
||||
open Fake.Core.TargetOperators
|
||||
|
||||
let dependencies = [
|
||||
"Clean"
|
||||
==> "InstallClient"
|
||||
==> "Bundle"
|
||||
|
||||
"Clean"
|
||||
==> "BundleDebug"
|
||||
|
||||
"Clean"
|
||||
==> "Test"
|
||||
|
||||
"Clean"
|
||||
==> "InstallClient"
|
||||
==> "Run"
|
||||
|
||||
"Clean"
|
||||
==> "Pack"
|
||||
]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args = runOrDefault args
|
||||
105
.build/Helpers.fs
Normal file
105
.build/Helpers.fs
Normal file
@@ -0,0 +1,105 @@
|
||||
module Helpers
|
||||
|
||||
open Fake.Core
|
||||
|
||||
let initializeContext () =
|
||||
let execContext = Context.FakeExecutionContext.Create false "build.fsx" [ ]
|
||||
Context.setExecutionContext (Context.RuntimeContext.Fake execContext)
|
||||
|
||||
module Proc =
|
||||
module Parallel =
|
||||
open System
|
||||
|
||||
let locker = obj()
|
||||
|
||||
let colors =
|
||||
[| ConsoleColor.Blue
|
||||
ConsoleColor.Yellow
|
||||
ConsoleColor.Magenta
|
||||
ConsoleColor.Cyan
|
||||
ConsoleColor.DarkBlue
|
||||
ConsoleColor.DarkYellow
|
||||
ConsoleColor.DarkMagenta
|
||||
ConsoleColor.DarkCyan |]
|
||||
|
||||
let print color (colored: string) (line: string) =
|
||||
lock locker
|
||||
(fun () ->
|
||||
let currentColor = Console.ForegroundColor
|
||||
Console.ForegroundColor <- color
|
||||
Console.Write colored
|
||||
Console.ForegroundColor <- currentColor
|
||||
Console.WriteLine line)
|
||||
|
||||
let onStdout index name (line: string) =
|
||||
let color = colors.[index % colors.Length]
|
||||
if isNull line then
|
||||
print color $"{name}: --- END ---" ""
|
||||
else if String.isNotNullOrEmpty line then
|
||||
print color $"{name}: " line
|
||||
|
||||
let onStderr name (line: string) =
|
||||
let color = ConsoleColor.Red
|
||||
if isNull line |> not then
|
||||
print color $"{name}: " line
|
||||
|
||||
let redirect (index, (name, createProcess)) =
|
||||
createProcess
|
||||
|> CreateProcess.redirectOutputIfNotRedirected
|
||||
|> CreateProcess.withOutputEvents (onStdout index name) (onStderr name)
|
||||
|
||||
let printStarting indexed =
|
||||
for (index, (name, c: CreateProcess<_>)) in indexed do
|
||||
let color = colors.[index % colors.Length]
|
||||
let wd =
|
||||
c.WorkingDirectory
|
||||
|> Option.defaultValue ""
|
||||
let exe = c.Command.Executable
|
||||
let args = c.Command.Arguments.ToStartInfo
|
||||
print color $"{name}: {wd}> {exe} {args}" ""
|
||||
|
||||
let run cs =
|
||||
cs
|
||||
|> Seq.toArray
|
||||
|> Array.indexed
|
||||
|> fun x -> printStarting x; x
|
||||
|> Array.map redirect
|
||||
|> Array.Parallel.map Proc.run
|
||||
|
||||
let createProcess exe arg dir =
|
||||
CreateProcess.fromRawCommandLine exe arg
|
||||
|> CreateProcess.withWorkingDirectory dir
|
||||
|> CreateProcess.ensureExitCode
|
||||
|
||||
let dotnet = createProcess "dotnet"
|
||||
let npm =
|
||||
let npmPath =
|
||||
match ProcessUtils.tryFindFileOnPath "npm" with
|
||||
| Some path -> path
|
||||
| None ->
|
||||
"npm was not found in path. Please install it and make sure it's available from your path. " +
|
||||
"See https://safe-stack.github.io/docs/quickstart/#install-pre-requisites for more info"
|
||||
|> failwith
|
||||
|
||||
createProcess npmPath
|
||||
|
||||
let run proc arg dir =
|
||||
proc arg dir
|
||||
|> Proc.run
|
||||
|> ignore
|
||||
|
||||
let runParallel processes =
|
||||
processes
|
||||
|> Proc.Parallel.run
|
||||
|> ignore
|
||||
|
||||
let runOrDefault args =
|
||||
try
|
||||
match args with
|
||||
| [| target |] -> Target.runOrDefault target
|
||||
| _ ->
|
||||
Target.runOrDefault "Run"
|
||||
0
|
||||
with e ->
|
||||
printfn "%A" e
|
||||
1
|
||||
18
.config/dotnet-tools.json
Normal file
18
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"fable": {
|
||||
"version": "3.7.0",
|
||||
"commands": [
|
||||
"fable"
|
||||
]
|
||||
},
|
||||
"fantomas-tool": {
|
||||
"version": "4.6.4",
|
||||
"commands": [
|
||||
"fantomas"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
29
.devcontainer/Dockerfile
Normal file
29
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:7.0
|
||||
|
||||
# Add keys and sources lists
|
||||
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash
|
||||
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" \
|
||||
| tee /etc/apt/sources.list.d/yarn.list
|
||||
|
||||
# Install node, 7zip, yarn, git, process tools
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y nodejs p7zip-full git procps ssh-client
|
||||
|
||||
# Clean up
|
||||
RUN apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install dotnet tools
|
||||
RUN dotnet tool install fable -g
|
||||
|
||||
# Trouble brewing
|
||||
RUN rm /etc/ssl/openssl.cnf
|
||||
|
||||
# add dotnet tools to path to pick up fake and paket installation
|
||||
ENV PATH="/root/.dotnet/tools:${PATH}"
|
||||
|
||||
# Copy endpoint specific user settings into container to specify
|
||||
# .NET Core should be used as the runtime.
|
||||
COPY settings.vscode.json /root/.vscode-remote/data/Machine/settings.json
|
||||
11
.devcontainer/devcontainer.json
Normal file
11
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "SAFE",
|
||||
"dockerFile": "Dockerfile",
|
||||
"appPort": [8080, 8085],
|
||||
"extensions": [
|
||||
"ionide.ionide-fsharp",
|
||||
"ms-dotnettools.csharp",
|
||||
"editorconfig.editorconfig",
|
||||
"msjsdiag.debugger-for-chrome"
|
||||
]
|
||||
}
|
||||
3
.devcontainer/settings.vscode.json
Normal file
3
.devcontainer/settings.vscode.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"FSharp.fsacRuntime":"netcore"
|
||||
}
|
||||
32
.editorconfig
Normal file
32
.editorconfig
Normal file
@@ -0,0 +1,32 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = false
|
||||
|
||||
[*.fs]
|
||||
max_line_length=120
|
||||
# Feliz style
|
||||
fsharp_single_argument_web_mode=true
|
||||
fsharp_space_before_colon=false
|
||||
fsharp_max_if_then_else_short_width=60
|
||||
fsharp_max_infix_operator_expression=50
|
||||
fsharp_max_record_width=70
|
||||
fsharp_max_record_number_of_items=1
|
||||
fsharp_max_array_or_list_width=70
|
||||
fsharp_max_array_or_list_number_of_items=1
|
||||
fsharp_max_value_binding_width=70
|
||||
fsharp_max_function_binding_width=40
|
||||
fsharp_max_dot_get_expression_width=50
|
||||
fsharp_multiline_block_brackets_on_same_column=true
|
||||
fsharp_newline_between_type_definition_and_members=false
|
||||
fsharp_max_elmish_width=40
|
||||
fsharp_align_function_signature_to_indentation=false
|
||||
fsharp_alternative_long_member_definitions=false
|
||||
fsharp_multi_line_lambda_closing_newline=false
|
||||
fsharp_disable_elmish_syntax=false
|
||||
fsharp_keep_indent_in_branch=false
|
||||
fsharp_blank_lines_around_nested_multiline_expressions=false
|
||||
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
.fable/
|
||||
.fake/
|
||||
.vs/
|
||||
.idea/
|
||||
.ionide/
|
||||
obj/
|
||||
bin/
|
||||
packages/
|
||||
node_modules/
|
||||
src/Client/public/js/
|
||||
release.cmd
|
||||
release.sh
|
||||
*.orig
|
||||
*.DotSettings.user
|
||||
deploy/
|
||||
dist/
|
||||
build/
|
||||
*.db
|
||||
build.fsx.lock
|
||||
_*.yaml
|
||||
*.txt
|
||||
*.nc
|
||||
__pycache__/
|
||||
7
.gitlab-ci.yml
Normal file
7
.gitlab-ci.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
variables:
|
||||
SKIP_TESTS: "true"
|
||||
|
||||
include:
|
||||
- project: oceanbox/gitlab-ci
|
||||
ref: main
|
||||
file: Dotnet.gitlab-ci.yml
|
||||
41
.releaserc.yaml
Normal file
41
.releaserc.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- name: develop
|
||||
prerelease: true
|
||||
|
||||
plugins:
|
||||
- '@semantic-release/commit-analyzer'
|
||||
- '@semantic-release/release-notes-generator'
|
||||
- - '@semantic-release/changelog'
|
||||
- changelogFile: RELEASE_NOTES.md
|
||||
changelogTitle: "# Changelog"
|
||||
- - 'semantic-release-dotnet'
|
||||
- paths: [ "src/*.fsproj", "src/*/*.fsproj" ]
|
||||
- - '@semantic-release/exec'
|
||||
- generateNotesCmd: "echo ${nextRelease.version} > .version"
|
||||
- - '@semantic-release/git'
|
||||
- message: "chore(release): ${nextRelease.version}\n\n${nextRelease.notes}"
|
||||
assets: [ "RELEASE_NOTES.md", ".version", "src/*.fsproj", "src/*/*.fsproj" ]
|
||||
- - '@semantic-release/gitlab'
|
||||
- assets: []
|
||||
|
||||
analyzeCommits:
|
||||
- path: "@semantic-release/commit-analyzer"
|
||||
releaseRules:
|
||||
- type: "fix"
|
||||
release: "patch"
|
||||
- type: "patch"
|
||||
release: "patch"
|
||||
- type: "feat"
|
||||
release: "minor"
|
||||
- type: "feature"
|
||||
release: "minor"
|
||||
- type: "minor"
|
||||
release: "minor"
|
||||
- type: "breaking"
|
||||
release: "major"
|
||||
- type: "major"
|
||||
release: "major"
|
||||
|
||||
|
||||
16
Build.fsproj
Normal file
16
Build.fsproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include=".build/Helpers.fs" />
|
||||
<Compile Include=".build/Build.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fake.Core.Target" Version="6.0.0" />
|
||||
<PackageReference Include="Fake.DotNet.Cli" Version="6.0.0" />
|
||||
<PackageReference Include="Fake.IO.FileSystem" Version="6.0.0" />
|
||||
<PackageReference Include="Farmer" Version="1.7.18" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM mcr.microsoft.com/dotnet/runtime:7.0
|
||||
RUN rm /etc/ssl/openssl.cnf
|
||||
|
||||
COPY deploy/ /app
|
||||
|
||||
WORKDIR /app
|
||||
CMD /app/PLACEHOLDER
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Serit Tromsø AS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
78
Plume.sln
Normal file
78
Plume.sln
Normal file
@@ -0,0 +1,78 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27004.2005
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8B183FC4-61F3-451E-9646-F849F33ACE83}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
README.md = README.md
|
||||
LICENSE = LICENSE
|
||||
Dockerfile = Dockerfile
|
||||
.gitlab-ci.yml = .gitlab-ci.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Build", "Build.fsproj", "{E80EC2D8-321A-4AED-9601-95C502E60BBB}"
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "src", "src/Plume.fsproj", "{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}"
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "test", "test\Tests.fsproj", "{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E80EC2D8-321A-4AED-9601-95C502E60BBB}.Release|x86.Build.0 = Release|Any CPU
|
||||
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Release|x64.Build.0 = Release|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{29E5EE19-A0AC-4F82-BC87-F2C68D213FC9}.Release|x86.Build.0 = Release|Any CPU
|
||||
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Release|x64.Build.0 = Release|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{07149E52-9FBD-4D7E-BCB0-C766ACF45A05}.Release|x86.Build.0 = Release|Any CPU
|
||||
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D4A0CC03-C315-43E6-B329-2720C527BF58}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
9
README.md
Normal file
9
README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Plume
|
||||
|
||||
## Run
|
||||
|
||||
`dotnet run`
|
||||
|
||||
## Build
|
||||
|
||||
`dotnet run Bundle`
|
||||
1
RELEASE_NOTES.md
Normal file
1
RELEASE_NOTES.md
Normal file
@@ -0,0 +1 @@
|
||||
# Changelog
|
||||
7105
package-lock.json
generated
Normal file
7105
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
package.json
Normal file
11
package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@semantic-release/changelog": "^6.0.1",
|
||||
"@semantic-release/exec": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/gitlab": "^7.0.4",
|
||||
"semantic-release-dotnet": "^1.0.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
255
src/Main.fs
Normal file
255
src/Main.fs
Normal file
@@ -0,0 +1,255 @@
|
||||
module Main
|
||||
|
||||
open System
|
||||
open Plume
|
||||
open Serilog
|
||||
open Serilog.Events
|
||||
open Argu
|
||||
open Model
|
||||
open Microsoft.Research.Science.Data.NetCDF4
|
||||
open Tools
|
||||
open Settings
|
||||
|
||||
let configureSerilog level =
|
||||
let n =
|
||||
match level with
|
||||
| 0 -> LogEventLevel.Error
|
||||
| 1 -> LogEventLevel.Warning
|
||||
| 2 -> LogEventLevel.Information
|
||||
| 3 -> LogEventLevel.Debug
|
||||
| _ -> LogEventLevel.Verbose
|
||||
LoggerConfiguration()
|
||||
.MinimumLevel.Is(n)
|
||||
.WriteTo.Console()
|
||||
.CreateLogger()
|
||||
|
||||
type Arguments =
|
||||
| Log_Level of level: int
|
||||
| Plumetemp of float
|
||||
| Plumesalt of float
|
||||
| Theta of float
|
||||
| Phi of float
|
||||
| Transport of float
|
||||
| Radius of float
|
||||
| Homogeneous
|
||||
| Depth of float
|
||||
| Atemp of float
|
||||
| Asalt of float
|
||||
| Auvel of float
|
||||
| Avvel of float
|
||||
| [<MainCommand; ExactlyOnce; Last>] File of file: string
|
||||
interface IArgParserTemplate with
|
||||
member this.Usage =
|
||||
match this with
|
||||
| Log_Level _ -> "0=Error, 1=Warning, 2=Info, 3=Debug, 4=Verbose"
|
||||
| Plumetemp _ -> "Initial plume temperature"
|
||||
| Plumesalt _ -> "Initial plume salinity"
|
||||
| Theta _ -> "Initial angle to horizontal"
|
||||
| Phi _ -> "Initial angle to north"
|
||||
| Transport _ -> "Initial plume transport"
|
||||
| Radius _ -> "Initial plume radius"
|
||||
| Homogeneous -> "simulate plume in homogeneous water column"
|
||||
| Depth _ -> "Water column depth to be used in homogeneous case"
|
||||
| Atemp _ -> "Ambient water temperature to be used in homogeneous case"
|
||||
| Asalt _ -> "Ambient water salinity to be used in homogeneous case"
|
||||
| Auvel _ -> "Ambient velocity in x-direction"
|
||||
| Avvel _ -> "Ambient velocity in y-direction"
|
||||
| File _ -> "file"
|
||||
|
||||
let colorizer =
|
||||
function
|
||||
| ErrorCode.HelpText -> None
|
||||
| _ -> Some ConsoleColor.Red
|
||||
|
||||
let errorHandler = ProcessExiter(colorizer = colorizer)
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
let parser =
|
||||
ArgumentParser.Create<Arguments>(programName = "Plume", errorHandler = errorHandler)
|
||||
let args = parser.Parse argv
|
||||
|
||||
Log.Logger <- configureSerilog (args.GetResult(Log_Level, defaultValue = 2))
|
||||
Log.Information $"File is {args.GetResult File}"
|
||||
let outfile = args.GetResult File
|
||||
|
||||
// let nodeidx = 100000
|
||||
// let cellidx = 197187
|
||||
// let surrnodes = [| 98648; 100001; 101378; 101377; 99999; 98648 |] // Must be closed and in counterclockwise direction
|
||||
let alpha = 0.125 //Tangential entrainment coefficient
|
||||
let beta = 0.6 //Normal entrainment coefficient
|
||||
let rhoref = 1000.0
|
||||
let ambient =
|
||||
if args.Contains Homogeneous then
|
||||
let depth = args.GetResult (Depth, 100.0)
|
||||
let Ta = args.GetResult Atemp
|
||||
let Sa = args.GetResult Asalt
|
||||
let Va = args.GetResult (Avvel, 0.0)
|
||||
let Ua = args. GetResult (Auvel, 0.0)
|
||||
{
|
||||
temp = [| Ta; Ta |]
|
||||
salt = [| Sa; Sa |]
|
||||
gztemp = [| 0.0; 0.0 |]
|
||||
gzsalt = [| 0.0; 0.0 |]
|
||||
z = [| 0.0; -100 |]
|
||||
zeta = 0.0
|
||||
gradpres = (0.0, 0.0)
|
||||
u = [| Ua; Ua |]
|
||||
v = [| Va; Va |]
|
||||
}
|
||||
else
|
||||
let nodeidx = 993441
|
||||
let cellidx = 1908691
|
||||
let surrnodes = [| 993012; 993442; 993875; 993874; 993873; 993872; 993440; 993012 |] // Must be closed and in counterclockwise direction
|
||||
let timeidx = 0
|
||||
let nc = NetCDFDataSet.Open("PO8_0038.nc")
|
||||
let temp0 =
|
||||
let tmp0 =
|
||||
nc["temp"]
|
||||
.GetData([| timeidx; 0; nodeidx |], [| 1; 34; 1 |])
|
||||
:?> single [,,]
|
||||
|> Array3D.map float
|
||||
let tmp1 = tmp0[0, *, 0]
|
||||
Array.concat [|
|
||||
[| Array.head tmp1 |]
|
||||
tmp1
|
||||
[| Array.last tmp1 |]
|
||||
|]
|
||||
let salt0 =
|
||||
let tmp0 =
|
||||
nc["salinity"]
|
||||
.GetData([| timeidx; 0; nodeidx |], [| 1; 34; 1 |])
|
||||
:?> single [,,]
|
||||
|> Array3D.map float
|
||||
let tmp1 = tmp0[0, *, 0]
|
||||
Array.concat [|
|
||||
[| Array.head tmp1 |]
|
||||
tmp1
|
||||
[| Array.last tmp1 |]
|
||||
|]
|
||||
let siglay0 =
|
||||
let tmp0 =
|
||||
nc["siglay"]
|
||||
.GetData([| 0; nodeidx |], [| 34; 1 |])
|
||||
:?> single [,]
|
||||
|> Array2D.map float
|
||||
let tmp1 = tmp0[*, 0]
|
||||
Array.concat [|
|
||||
[| 0.0 |]
|
||||
tmp1
|
||||
[| -1.0 |]
|
||||
|]
|
||||
let h0 =
|
||||
nc[ "h" ].GetData([| nodeidx |], [| 1 |]) :?> single []
|
||||
|> Array.map float
|
||||
|> Array.head
|
||||
let zeta0 =
|
||||
let tmp0 =
|
||||
nc[ "zeta" ].GetData([| 0; nodeidx |], [| 1; 1 |]) :?> single [,]
|
||||
|> Array2D.map float
|
||||
tmp0[0, 0]
|
||||
let surrzeta =
|
||||
let tmp =
|
||||
surrnodes
|
||||
|> Array.map (fun n ->
|
||||
nc[ "zeta" ].GetData([| 0; n |], [| 1; 1 |]) :?> single [,]
|
||||
|> Array2D.map float)
|
||||
tmp |> Array.map (fun z -> z[0, 0])
|
||||
let surrpos =
|
||||
surrnodes
|
||||
|> Array.map (fun n ->
|
||||
nc[ "x" ].GetData([| n |], [| 1 |]) :?> single []
|
||||
|> Array.head
|
||||
|> float,
|
||||
nc[ "y" ].GetData([| n |], [| 1 |]) :?> single []
|
||||
|> Array.head
|
||||
|> float)
|
||||
let pos =
|
||||
(nc[ "x" ].GetData([| nodeidx |], [| 1 |]) :?> single []
|
||||
|> Array.head
|
||||
|> float,
|
||||
nc[ "y" ].GetData([| nodeidx |], [| 1 |]) :?> single []
|
||||
|> Array.head
|
||||
|> float)
|
||||
let u0 =
|
||||
let tmp0 =
|
||||
nc["u"]
|
||||
.GetData([| timeidx; 0; cellidx |], [| 1; 34; 1 |])
|
||||
:?> single [,,]
|
||||
|> Array3D.map float
|
||||
let tmp1 = tmp0[0, *, 0]
|
||||
Array.concat [|
|
||||
[| Array.head tmp1 |]
|
||||
tmp1
|
||||
[| Array.last tmp1 |]
|
||||
|]
|
||||
let v0 =
|
||||
let tmp0 =
|
||||
nc["v"]
|
||||
.GetData([| timeidx; 0; cellidx |], [| 1; 34; 1 |])
|
||||
:?> single [,,]
|
||||
|> Array3D.map float
|
||||
let tmp1 = tmp0[0, *, 0]
|
||||
Array.concat [|
|
||||
[| Array.head tmp1 |]
|
||||
tmp1
|
||||
[| Array.last tmp1 |]
|
||||
|]
|
||||
let z0 =
|
||||
siglay0
|
||||
|> Array.map (fun s -> (zeta0 + h0) * s + zeta0)
|
||||
let surrpres = surrzeta |> Array.map (fun z -> 9.81 * z)
|
||||
let gpres = hGradient surrpres surrpos pos
|
||||
let dTdz = vGradient temp0 z0
|
||||
let dSdz = vGradient salt0 z0
|
||||
|
||||
{
|
||||
temp = temp0
|
||||
salt = salt0
|
||||
gztemp = dTdz
|
||||
gzsalt = dSdz
|
||||
z = z0
|
||||
zeta = zeta0
|
||||
gradpres = gpres
|
||||
u = u0
|
||||
v = v0
|
||||
}
|
||||
|
||||
writeAmbient ambient "ambient.txt"
|
||||
|
||||
// printfn $"length gztemp = {ambient.gztemp.Length}"
|
||||
|
||||
// writeVar ambient.temp ambient.z "temp.txt"
|
||||
// writeVar ambient.salt ambient.z "salt.txt"
|
||||
// writeVar ambient.u ambient.z "u.txt"
|
||||
// writeVar ambient.v ambient.z "v.txt"
|
||||
// writeVar ambient.gztemp ambient.z "dtemp.txt"
|
||||
// writeVar ambient.gzsalt ambient.z "dsalt.txt"
|
||||
|
||||
|
||||
let h = - (Array.last ambient.z)
|
||||
let z0 = - h + 2.0
|
||||
|
||||
let U = args.GetResult Transport //Initial volume transport
|
||||
let R0 = args.GetResult Radius //Outlet radius
|
||||
let theta = args.GetResult Theta //Initial angle to horizontal
|
||||
let phi = args.GetResult Phi //Initial angle to north
|
||||
let w0 = U / (3.1415 * R0 * R0) //Initial plume velocity
|
||||
let T0 = args.GetResult Plumetemp // Initial outlet temperature and salinity
|
||||
let S0 = args.GetResult Plumesalt
|
||||
let inivals =
|
||||
{temp = [| T0|]
|
||||
salt = [| S0|]
|
||||
theta = [| theta |]
|
||||
phi = [| phi |]
|
||||
v = [| w0 |]
|
||||
R = [| R0 |]
|
||||
z = [| z0 |]
|
||||
x = [| 0.0 |]
|
||||
y = [| 0.0 |]
|
||||
}
|
||||
|
||||
let ds = (ambient.zeta + h) / 100.0
|
||||
let solution = solver inivals ambient rhoref alpha beta ds
|
||||
writeSolution solution outfile
|
||||
0
|
||||
178
src/Model.fs
Normal file
178
src/Model.fs
Normal file
@@ -0,0 +1,178 @@
|
||||
module Plume.Model
|
||||
|
||||
open System.Reflection.Metadata
|
||||
open Oceanbox.FvcomKit.Thredds
|
||||
open Serilog
|
||||
open System
|
||||
|
||||
type AmbientData =
|
||||
{
|
||||
temp: float []
|
||||
salt: float []
|
||||
gztemp: float []
|
||||
gzsalt: float []
|
||||
z: float []
|
||||
zeta: float
|
||||
gradpres: float * float
|
||||
u: float []
|
||||
v: float []
|
||||
}
|
||||
|
||||
type ModelSolution =
|
||||
{
|
||||
temp: float []
|
||||
salt: float []
|
||||
theta: float []
|
||||
phi: float []
|
||||
v: float []
|
||||
R: float []
|
||||
z: float []
|
||||
x: float []
|
||||
y: float []
|
||||
}
|
||||
|
||||
let eq_of_state (temp: float) (salt: float) =
|
||||
let tmp1 =
|
||||
(salt ** 3) * 6.76786136E-6
|
||||
- (salt ** 2) * 4.8249614E-4
|
||||
+ salt * 8.14876577E-1
|
||||
- 0.22584586
|
||||
let tmp2 =
|
||||
tmp1
|
||||
* ((temp ** 3) * 1.667E-8 - (temp ** 2) * 8.164E-7
|
||||
+ temp * 1.803E-5)
|
||||
let tmp3 =
|
||||
tmp2 + 1.0 - (temp ** 3) * 1.0843E-6
|
||||
+ (temp ** 2) * 9.8185E-5
|
||||
- temp * 4.786E-3
|
||||
let tmp4 =
|
||||
tmp3
|
||||
* ((salt ** 3) * 6.76786136E-6
|
||||
- (salt ** 2) * 4.8249614E-4
|
||||
+ salt * 8.14876577E-1
|
||||
+ 3.895414E-2)
|
||||
let tmp5 =
|
||||
tmp4
|
||||
- ((temp - 3.98) ** 2) * (temp + 283.0)
|
||||
/ (503.57 * (temp + 67.26))
|
||||
tmp5 + 1000.0
|
||||
|
||||
let ambientWmass (za: float []) (Ta: float []) (Sa: float []) (zp: float) =
|
||||
let i1 =
|
||||
za
|
||||
|> Array.mapi (fun i z -> i, z)
|
||||
|> Array.filter (fun (_, z) -> z <= zp)
|
||||
|> Array.head
|
||||
|> fst
|
||||
let i2 =
|
||||
za
|
||||
|> Array.mapi (fun i z -> i, z)
|
||||
|> Array.filter (fun (_, z) -> z >= zp)
|
||||
|> Array.last
|
||||
|> fst
|
||||
if i1 = i2 then
|
||||
Ta[i1], Sa[i1]
|
||||
else
|
||||
let ct1 = (Ta[i1] - Ta[i2]) / (za[i1] - za[i2])
|
||||
let ct2 = Ta[i1] - ct1 * za[i1]
|
||||
let T = ct1 * zp + ct2
|
||||
let cs1 = (Sa[i1] - Sa[i2]) / (za[i1] - za[i2])
|
||||
let cs2 = Sa[i1] - cs1 * za[i1]
|
||||
let S = cs1 * zp + cs2
|
||||
T, S
|
||||
|
||||
let zstep
|
||||
(s0: ModelSolution)
|
||||
(awm: AmbientData)
|
||||
(rhoref: float)
|
||||
(alpha: float)
|
||||
(beta: float)
|
||||
(ds: float)
|
||||
=
|
||||
let z = Array.last s0.z
|
||||
let ua, va = ambientWmass awm.z awm.u awm.v z
|
||||
let Ta, Sa = ambientWmass awm.z awm.temp awm.salt z
|
||||
let dTz, dSz = ambientWmass awm.z awm.gztemp awm.gzsalt z
|
||||
let T0 = Array.last s0.temp
|
||||
let S0 = Array.last s0.salt
|
||||
let v0 = Array.last s0.v
|
||||
let R0 = Array.last s0.R
|
||||
let theta0 = Array.last s0.theta
|
||||
let phi0 = Array.last s0.phi
|
||||
let vat = ( ua * (sin phi0) + va * (cos phi0) ) * (cos theta0) // ambient velocity tangential to plume
|
||||
let van = ( ua * (sin phi0) + va * (cos phi0) ) * (sin theta0) // ambient velocity normal to plume (in theta direction)
|
||||
let vanh = ua * (cos phi0) - va * (sin phi0) //ambient velocity normal to plume (in phi direction)
|
||||
printfn $"vanh = {vanh}"
|
||||
printfn $"van = {van}"
|
||||
printfn $"vat = {vat}"
|
||||
printfn $"ua = {ua}"
|
||||
printfn $"va = {va}"
|
||||
printfn $"theta = {theta0}"
|
||||
printfn $"phi = {phi0}"
|
||||
let ve = alpha * abs (v0 - vat) + beta * ( abs van + abs vanh) //entrainment velocity
|
||||
printfn $"ve = {ve}"
|
||||
let delpt = ( (fst awm.gradpres) * (sin phi0) + (snd awm.gradpres) * (cos phi0) ) * (cos theta0) //pressure gradient tangential to plume
|
||||
let delpn = ( (fst awm.gradpres) * (sin phi0) + (snd awm.gradpres) * (cos phi0) ) * (sin theta0) //pressure gradient normal to plume (in theta direaction)
|
||||
let delph = (fst awm.gradpres) * (cos phi0) - (snd awm.gradpres) * (sin phi0) //pressure gradient normal to plume (in phi direction)
|
||||
let rho = eq_of_state T0 S0
|
||||
let rhoa = eq_of_state Ta Sa
|
||||
let gp = 9.81 * (rhoa - rho) / rhoref
|
||||
let dr2v = 2.0 * R0 * ve
|
||||
// Continuity equation
|
||||
let r2v = R0 * R0 * v0 + dr2v * ds
|
||||
// Momentum equation in tangential direction
|
||||
let r2v2 = R0 * R0 * v0 * v0 + dr2v * vat * ds + R0 * R0 * (gp * (sin theta0) - delpt) * ds
|
||||
// Momentum equation in normal (theta) direction
|
||||
let theta = theta0 + ( -dr2v * van + R0 * R0 * ( gp * (cos theta0) - delpn ) ) * ds / r2v2
|
||||
// Momentum equation in horizontal (phi) direction
|
||||
let phi = phi0 + ( dr2v * vanh - delph) * ds / (r2v2 * (cos theta0) )
|
||||
// Equations for temperature and salinity
|
||||
let r2vt = R0 * R0 * ( v0 * (Ta - T0) + dTz * (sin theta0))
|
||||
let r2vs = R0 * R0 * ( v0 * (Sa - S0) + dSz * (sin theta0))
|
||||
let T = Ta - r2vt / r2v
|
||||
let S = Sa - r2vs / r2v
|
||||
let v = r2v2 / r2v
|
||||
let R = r2v / v |> sqrt
|
||||
{
|
||||
temp = Array.append s0.temp [| T |]
|
||||
salt = Array.append s0.salt [| S |]
|
||||
theta = Array.append s0.theta [| theta |]
|
||||
phi = Array.append s0.phi [| phi |]
|
||||
v = Array.append s0.v [| v |]
|
||||
R = Array.append s0.R [| R |]
|
||||
z = Array.append s0.z [| (Array.last s0.z) + ds * (sin theta) |]
|
||||
x = Array.append s0.x [| (Array.last s0.x) + ds * (cos theta) * (sin phi) |]
|
||||
y = Array.append s0.y [| (Array.last s0.y) + ds * (cos theta) * (cos phi) |]
|
||||
}
|
||||
|
||||
let writeSolution (sol: ModelSolution) (filename: string) =
|
||||
let datastring =
|
||||
sol.temp
|
||||
|> Array.mapi (fun i _ ->
|
||||
$"{sol.temp[i]} {sol.salt[i]} {sol.theta[i]} {sol.phi[i]} {sol.v[i]} {sol.R[i]} {sol.z[i]} {sol.x[i]} {sol.y[i]}")
|
||||
IO.File.WriteAllLines(filename, datastring)
|
||||
|
||||
let solver
|
||||
(s0: ModelSolution)
|
||||
(awm: AmbientData)
|
||||
(rhoref: float)
|
||||
(alpha: float)
|
||||
(beta: float)
|
||||
(ds: float)
|
||||
=
|
||||
let rec solvez (sol: ModelSolution) =
|
||||
let solution = zstep sol awm rhoref alpha beta ds
|
||||
writeSolution solution "sol.txt"
|
||||
// Log.Information $"z = {Array.last solution.z}"
|
||||
if Array.last solution.theta < 0.0 || Array.last solution.z >= awm.zeta || Array.last solution.v < 0.0 then
|
||||
solution
|
||||
else
|
||||
solvez solution
|
||||
solvez s0
|
||||
|
||||
let writeAmbient (amb: AmbientData) (filename: string) =
|
||||
let datastring =
|
||||
amb.temp
|
||||
|> Array.mapi (fun i _ ->
|
||||
$"{amb.temp[i]} {amb.salt[i]} {amb.gztemp[i]} {amb.gzsalt[i]} {amb.z[i]} {amb.u[i]} {amb.v[i]}")
|
||||
IO.File.WriteAllLines(filename, datastring)
|
||||
24
src/Plume.fsproj
Normal file
24
src/Plume.fsproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Settings.fs" />
|
||||
<Compile Include="Tools.fs" />
|
||||
<Compile Include="Model.fs" />
|
||||
<Compile Include="Main.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Argu" Version="6.1.1" />
|
||||
<PackageReference Include="FSharp.Data" Version="5.0.2" />
|
||||
<PackageReference Include="FSharpPlus" Version="1.4.0" />
|
||||
<PackageReference Include="Oceanbox.FvcomKit" Version="5.3.0" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="5.2.2" />
|
||||
<PackageReference Include="Thoth.Json.Net" Version="11.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
23
src/Settings.fs
Normal file
23
src/Settings.fs
Normal file
@@ -0,0 +1,23 @@
|
||||
module Settings
|
||||
|
||||
open System.IO
|
||||
open Thoth.Json.Net
|
||||
open Serilog
|
||||
|
||||
type Settings = { Setting: string }
|
||||
|
||||
let tryGetEnv =
|
||||
System.Environment.GetEnvironmentVariable
|
||||
>> function
|
||||
| null
|
||||
| "" -> None
|
||||
| x -> Some x
|
||||
|
||||
let appsettings =
|
||||
let settings = System.IO.File.ReadAllText "appsettings.json"
|
||||
|
||||
match Decode.Auto.fromString<Settings> settings with
|
||||
| Ok s -> s
|
||||
| Error e -> failwith e
|
||||
|
||||
sprintf "AppSettings: %A" appsettings |> Log.Debug
|
||||
84
src/Tools.fs
Normal file
84
src/Tools.fs
Normal file
@@ -0,0 +1,84 @@
|
||||
module Plume.Tools
|
||||
|
||||
open System
|
||||
|
||||
let private triangleArea (x: float * float * float) (y: float * float * float) =
|
||||
let x1, x2, x3 = x
|
||||
let y1, y2, y3 = y
|
||||
let a = (x2 - x1) ** 2 + (y2 - y1) ** 2 |> sqrt
|
||||
let b = (x3 - x2) ** 2 + (y3 - y2) ** 2 |> sqrt
|
||||
let c = (x1 - x3) ** 2 + (y1 - y3) ** 2 |> sqrt
|
||||
let s = (a + b + c) / 2.0
|
||||
s * (s - a) * (s - b) * (s - c) |> sqrt
|
||||
|
||||
let polygonArea (pos: (float * float) []) (cpos: float * float) =
|
||||
let x, y = Array.unzip pos
|
||||
let x0, y0 = cpos
|
||||
let xx = Array.pairwise x
|
||||
let yy = Array.pairwise y
|
||||
[| 0 .. xx.Length - 1 |]
|
||||
|> Array.map (fun n -> triangleArea (fst xx[n], snd xx[n], x0) (fst yy[n], snd yy[n], y0))
|
||||
|> Array.sum
|
||||
|
||||
let hGradient (var: float []) (pos: (float * float) []) (cpos: float * float) =
|
||||
let x, y = Array.unzip pos
|
||||
let dx =
|
||||
x
|
||||
|> Array.pairwise
|
||||
|> Array.map (fun (x1, x2) -> x2 - x1)
|
||||
let dy =
|
||||
y
|
||||
|> Array.pairwise
|
||||
|> Array.map (fun (y1, y2) -> y2 - y1)
|
||||
let mvar =
|
||||
var
|
||||
|> Array.pairwise
|
||||
|> Array.map (fun (v1, v2) -> (v1 + v2) / 2.0)
|
||||
let parea = polygonArea pos cpos
|
||||
let gx =
|
||||
let intx =
|
||||
mvar
|
||||
|> Array.mapi (fun i v -> v * dx[i])
|
||||
|> Array.sum
|
||||
-intx / parea
|
||||
let gy =
|
||||
let inty =
|
||||
mvar
|
||||
|> Array.mapi (fun i v -> v * dy[i])
|
||||
|> Array.sum
|
||||
inty / parea
|
||||
gx, gy
|
||||
|
||||
let vGradient (var: float []) (z: float []) =
|
||||
let var2 = Array.pairwise var
|
||||
let z2 = Array.pairwise z
|
||||
let gz1 =
|
||||
[| 0 .. z2.Length - 1 |]
|
||||
|> Array.map (fun n ->
|
||||
(fst var2[n] - snd var2[n])
|
||||
/ (fst z2[n] - snd z2[n]))
|
||||
|> Array.pairwise
|
||||
let zz =
|
||||
z2
|
||||
|> Array.map (fun (k1, k2) -> (k1 + k2) / 2.0)
|
||||
|> Array.pairwise
|
||||
let gz2 =
|
||||
[| 0 .. var.Length - 3 |]
|
||||
|> Array.map (fun n ->
|
||||
(fst gz1[n] - snd gz1[n])
|
||||
/ (fst zz[n] - snd zz[n])
|
||||
* z[n]
|
||||
+ (snd gz1[n])
|
||||
- (fst gz1[n] - snd gz1[n])
|
||||
/ (fst zz[n] - snd zz[n])
|
||||
* (snd zz[n]))
|
||||
Array.concat [|
|
||||
[| gz2[0] |]
|
||||
gz2
|
||||
[| gz2[gz2.Length - 1] |]
|
||||
|]
|
||||
|
||||
let writeVar (var: float []) (coord: float []) (filename: string) =
|
||||
let data = Array.zip var coord
|
||||
let datastring = data |> Array.map (fun (v, c) -> $"{v} {c}")
|
||||
IO.File.WriteAllLines(filename, datastring)
|
||||
3
src/appsettings.json
Normal file
3
src/appsettings.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"Setting" : "example setting"
|
||||
}
|
||||
314
src/packages.lock.json
Normal file
314
src/packages.lock.json
Normal file
@@ -0,0 +1,314 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net7.0": {
|
||||
"Argu": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.1.1, )",
|
||||
"resolved": "6.1.1",
|
||||
"contentHash": "5SBLYihaZ6/YNpRU+0v0QLsCk7ABmOWNOUwkXVUql2w7kJ6Hi4AFhgIv5XLTtxTid5/xrJAL+PglQkNcjANCJg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.3.2",
|
||||
"System.Configuration.ConfigurationManager": "4.4.0"
|
||||
}
|
||||
},
|
||||
"FSharp.Core": {
|
||||
"type": "Direct",
|
||||
"requested": "[7.0.400, )",
|
||||
"resolved": "7.0.400",
|
||||
"contentHash": "kJQ7TBQqd1d2VoODSgwFSAaApaBN0Fuu8mZt2XExmd3UzUxLjUsMn5Y5XhpsUWdnxOL8amp7VFg7cwhPllR4Qw=="
|
||||
},
|
||||
"FSharp.Data": {
|
||||
"type": "Direct",
|
||||
"requested": "[5.0.2, )",
|
||||
"resolved": "5.0.2",
|
||||
"contentHash": "eQBiOwlk6p8nVehcrxRK/22BwZXzJ2IkHXuqjIZ9Km0bH90WhBoF7OFdLWenc6dYizQmKv3qKIMCkKfVBepi0A==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "5.0.1"
|
||||
}
|
||||
},
|
||||
"FSharpPlus": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.4.0, )",
|
||||
"resolved": "1.4.0",
|
||||
"contentHash": "He6WVVTZpeMQNBlFHniemTSCWITKgwLIgmznNt2kw0U9G/xWSx7USdssGXd2FGmcpk2FlHInYZNwUw848tI0SQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.6"
|
||||
}
|
||||
},
|
||||
"Oceanbox.FvcomKit": {
|
||||
"type": "Direct",
|
||||
"requested": "[5.3.0, )",
|
||||
"resolved": "5.3.0",
|
||||
"contentHash": "fJce+14np0YQWPeQVM+kMxRlfTMm8ZieLbJf97rlvxlYojL8qApFWoLmIu7b7J1qT++5uI7O+zTdsBYxDrfEFg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "7.0.300",
|
||||
"FSharp.Data": "6.2.0",
|
||||
"FSharpPlus": "1.4.1",
|
||||
"FsPickler": "5.3.2",
|
||||
"KDTree": "1.4.1",
|
||||
"MathNet.Numerics.FSharp": "5.0.0",
|
||||
"ProjNet.FSharp": "5.0.1",
|
||||
"Serilog": "3.0.0-dev-01921",
|
||||
"Serilog.Sinks.Console": "4.1.1-dev-00907",
|
||||
"Serilog.Sinks.Seq": "5.2.3-dev-00262",
|
||||
"Thoth.Json.Net": "11.0.0",
|
||||
"sdslite": "2.6.0"
|
||||
}
|
||||
},
|
||||
"Serilog": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.12.0, )",
|
||||
"resolved": "2.12.0",
|
||||
"contentHash": "xaiJLIdu6rYMKfQMYUZgTy8YK7SMZjB4Yk50C/u//Z4OsvxkUfSPJy4nknfvwAC34yr13q7kcyh4grbwhSxyZg=="
|
||||
},
|
||||
"Serilog.Sinks.Console": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "K6N5q+5fetjnJPvCmkWOpJ/V8IEIoMIB1s86OzBrbxwTyHxdx3pmz4H+8+O/Dc/ftUX12DM1aynx/dDowkwzqg==",
|
||||
"dependencies": {
|
||||
"Serilog": "2.10.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.Seq": {
|
||||
"type": "Direct",
|
||||
"requested": "[5.2.2, )",
|
||||
"resolved": "5.2.2",
|
||||
"contentHash": "1Csmo5ua7NKUe0yXUx+zsRefjAniPWcXFhUXxXG8pwo0iMiw2gjn9SOkgYnnxbgWqmlGv236w0N/dHc2v5XwMg==",
|
||||
"dependencies": {
|
||||
"Serilog": "2.12.0",
|
||||
"Serilog.Formatting.Compact": "1.1.0",
|
||||
"Serilog.Sinks.File": "5.0.0",
|
||||
"Serilog.Sinks.PeriodicBatching": "3.1.0"
|
||||
}
|
||||
},
|
||||
"Thoth.Json.Net": {
|
||||
"type": "Direct",
|
||||
"requested": "[11.0.0, )",
|
||||
"resolved": "11.0.0",
|
||||
"contentHash": "ugheFKMHRO3ReobCENha5J6uexPrp+Bn2d+WEcFbXaA77sNBWtTlx2StB+7lX8prMqdvO5uqlPeHlg+9dSpkNg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.1.6",
|
||||
"Newtonsoft.Json": "11.0.2"
|
||||
}
|
||||
},
|
||||
"DynamicInterop": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.9.1",
|
||||
"contentHash": "n21+Hd+tceX8lgaOosPV+Pne+YqnZUd5RLW3OhnsVxWRzYXiAIAKmKweHIePYeY+fmcn3N5tjkJyQUccFuL3bg=="
|
||||
},
|
||||
"Fable.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.1.6",
|
||||
"contentHash": "w6M1F0zoLk4kTFc1Lx6x1Ft6BD3QwRe0eaLiinAqbjVkcF+iK+NiXGJO+a6q9RAF9NCg0vI48Xku7aNeqG4JVw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.1"
|
||||
}
|
||||
},
|
||||
"FsPickler": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.3.2",
|
||||
"contentHash": "LFtxXpQNor8az1ez3rN9oz2cqf/06i9yTrPyJ9R83qLEpFAU7Of0WL2hoSXzLHer4lh+6mO1NV4VQFiBzNRtjw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.3.2",
|
||||
"System.Reflection.Emit.Lightweight": "4.3.0"
|
||||
}
|
||||
},
|
||||
"KdTree": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.4.1",
|
||||
"contentHash": "yWbb35v/V9y88SLLMUPTlAN3pQEoPhDfZf9PApFnlU4kLtwVQ75U9vW5mW4/alQnLBuLKWBKcy4W5xK95mYsuA=="
|
||||
},
|
||||
"MathNet.Numerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "pg1W2VwaEQMAiTpGK840hZgzavnqjlCMTVSbtVCXVyT+7AX4mc1o89SPv4TBlAjhgCOo9c1Y+jZ5m3ti2YgGgA=="
|
||||
},
|
||||
"MathNet.Numerics.FSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "lKYhd68fReW5odX/q+Uzxw3357Duq3zmvkYvnZVqqcc2r/EmrYGDoOdUGuHnhfr8yj9V34js5gQH/7IWcxZJxg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.2",
|
||||
"MathNet.Numerics": "5.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"Microsoft.NETCore.Targets": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "11.0.2",
|
||||
"contentHash": "IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ=="
|
||||
},
|
||||
"ProjNET": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.0",
|
||||
"contentHash": "iMJG8qpGJ8SjFrB044O8wgo0raAWCdG1Bvly0mmVcjzsrexDHhC+dUct6Wb1YwQtupMBjSTWq7Fn00YeNErprA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3",
|
||||
"System.Numerics.Vectors": "4.5.0"
|
||||
}
|
||||
},
|
||||
"ProjNet.FSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.1",
|
||||
"contentHash": "Hu+LwA9rlcEqIcrNK3c2FEV8R8Twdvn7eMM3ynwYBsrmp1d8kr+oETBnp5K7z30YutuH8nQYUuLVFU8ps/QYHg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.2",
|
||||
"FSharp.Data": "4.2.8",
|
||||
"FSharpPlus": "1.3.0-CI02744",
|
||||
"ProjNet": "2.0.0"
|
||||
}
|
||||
},
|
||||
"SDSLite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.6.0",
|
||||
"contentHash": "P7C+1k5m4ggkSY+QYbs5B8BpD2kIWaaZ+hpfEMEThVFTcWPWj+L/o0cmWAlJVE5c2VHptSmOd7hnMHbFLmlcbA==",
|
||||
"dependencies": {
|
||||
"DynamicInterop": "0.9.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Formatting.Compact": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "pNroKVjo+rDqlxNG5PXkRLpfSCuDOBY0ri6jp9PLe505ljqwhwZz8ospy2vWhQlFu5GkIesh3FcDs4n7sWZODA==",
|
||||
"dependencies": {
|
||||
"Serilog": "2.8.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.File": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "uwV5hdhWPwUH1szhO8PJpFiahqXmzPzJT/sOijH/kFgUx+cyoDTMM8MHD0adw9+Iem6itoibbUXHYslzXsLEAg==",
|
||||
"dependencies": {
|
||||
"Serilog": "2.10.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.PeriodicBatching": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.1.0",
|
||||
"contentHash": "NDWR7m3PalVlGEq3rzoktrXikjFMLmpwF0HI4sowo8YDdU+gqPlTHlDQiOGxHfB0sTfjPA9JjA7ctKG9zqjGkw==",
|
||||
"dependencies": {
|
||||
"Serilog": "2.0.0"
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "gWwQv/Ug1qWJmHCmN17nAbxJYmQBM/E94QxKLksvUiiKB1Ld3Sc/eK1lgmbSjDFxkQhVuayI/cGFZhpBSodLrg==",
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "4.4.0"
|
||||
}
|
||||
},
|
||||
"System.IO": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Text.Encoding": "4.3.0",
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
|
||||
},
|
||||
"System.Reflection": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.IO": "4.3.0",
|
||||
"System.Reflection.Primitives": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Reflection.Emit.ILGeneration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==",
|
||||
"dependencies": {
|
||||
"System.Reflection": "4.3.0",
|
||||
"System.Reflection.Primitives": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Reflection.Emit.Lightweight": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==",
|
||||
"dependencies": {
|
||||
"System.Reflection": "4.3.0",
|
||||
"System.Reflection.Emit.ILGeneration": "4.3.0",
|
||||
"System.Reflection.Primitives": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Reflection.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
|
||||
},
|
||||
"System.Text.Encoding": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/readdat.py
Normal file
64
src/readdat.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import numpy as np
|
||||
|
||||
def readfile (filename):
|
||||
fid = open(filename, 'r')
|
||||
data = fid.readlines()
|
||||
fid.close()
|
||||
temp = []
|
||||
z = []
|
||||
for n in np.arange(len(data)):
|
||||
line = data[n].split(' ')
|
||||
z.append(float(line[1]))
|
||||
temp.append(float(line[0]))
|
||||
return temp, z
|
||||
|
||||
def readambient (filename = 'ambient.txt'):
|
||||
fid = open(filename, 'r')
|
||||
data = fid.readlines()
|
||||
fid.close()
|
||||
temp = []
|
||||
salt = []
|
||||
gztemp = []
|
||||
gzsalt = []
|
||||
z = []
|
||||
u = []
|
||||
v = []
|
||||
for n in np.arange(len(data)):
|
||||
line = data[n].split(' ')
|
||||
temp.append(float(line[0]))
|
||||
salt.append(float(line[1]))
|
||||
gztemp.append(float(line[2]))
|
||||
gzsalt.append(float(line[3]))
|
||||
z.append(float(line[4]))
|
||||
u.append(float(line[5]))
|
||||
v.append(float(line[6]))
|
||||
return temp, salt, gztemp, gzsalt, z, u, v
|
||||
|
||||
def readdata(filename):
|
||||
fid = open(filename, 'r')
|
||||
data = fid.readlines()
|
||||
fid.close()
|
||||
temp = []
|
||||
salt = []
|
||||
theta = []
|
||||
phi = []
|
||||
v = []
|
||||
R = []
|
||||
z = []
|
||||
x = []
|
||||
y = []
|
||||
for n in np.arange(len(data)):
|
||||
line = data[n].split(' ')
|
||||
temp.append(float(line[0]))
|
||||
salt.append(float(line[1]))
|
||||
theta.append(float(line[2]))
|
||||
phi.append(float(line[3]))
|
||||
v.append(float(line[4]))
|
||||
R.append(float(line[5]))
|
||||
z.append(float(line[6]))
|
||||
x.append(float(line[7]))
|
||||
y.append(float(line[8]))
|
||||
return temp, salt, theta, phi, v, R, z, x, y
|
||||
|
||||
|
||||
|
||||
18
test/Tests.fs
Normal file
18
test/Tests.fs
Normal file
@@ -0,0 +1,18 @@
|
||||
module Tests
|
||||
|
||||
open Expecto
|
||||
|
||||
let server =
|
||||
testList
|
||||
"Server"
|
||||
[
|
||||
testCase "Adding valid Todo"
|
||||
<| fun _ ->
|
||||
let expectedResult = Ok()
|
||||
Expect.equal (Ok()) expectedResult "Result should be ok"
|
||||
]
|
||||
|
||||
let all = testList "All" [ server ]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main _ = runTests defaultConfig all
|
||||
16
test/Tests.fsproj
Normal file
16
test/Tests.fsproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Tests.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\src\Plume.fsproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Expecto" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user