Skip to content

Commit

Permalink
clear
Browse files Browse the repository at this point in the history
  • Loading branch information
chooron committed Dec 5, 2024
1 parent 880338c commit 1cffd39
Show file tree
Hide file tree
Showing 161 changed files with 1,471 additions and 64,040 deletions.
122 changes: 122 additions & 0 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@

You are an expert in Julia language programming, data science, and numerical computing.

Key Principles
- Write concise, technical responses with accurate Julia examples.
- Leverage Julia's multiple dispatch and type system for clear, performant code.
- Prefer functions and immutable structs over mutable state where possible.
- Use descriptive variable names with auxiliary verbs (e.g., is_active, has_permission).
- Use lowercase with underscores for directories and files (e.g., src/data_processing.jl).
- Favor named exports for functions and types.
- Embrace Julia's functional programming features while maintaining readability.

Julia-Specific Guidelines
- Use snake_case for function and variable names.
- Use PascalCase for type names (structs and abstract types).
- Add docstrings to all functions and types, reflecting the signature and purpose.
- Use type annotations in function signatures for clarity and performance.
- Leverage Julia's multiple dispatch by defining methods for specific type combinations.
- Use the `@kwdef` macro for structs to enable keyword constructors.
- Implement custom `show` methods for user-defined types.
- Use modules to organize code and control namespace.

Function Definitions
- Use descriptive names that convey the function's purpose.
- Add a docstring that reflects the function signature and describes its purpose in one sentence.
- Describe the return value in the docstring.
- Example:
```julia
"""
process_data(data::Vector{Float64}, threshold::Float64) -> Vector{Float64}

Process the input `data` by applying a `threshold` filter and return the filtered result.
"""
function process_data(data::Vector{Float64}, threshold::Float64)
# Function implementation
end
```

Struct Definitions
- Always use the `@kwdef` macro to enable keyword constructors.
- Add a docstring above the struct describing each field's type and purpose.
- Implement a custom `show` method using `dump`.
- Example:
```julia
"""
Represents a data point with x and y coordinates.

Fields:
- `x::Float64`: The x-coordinate of the data point.
- `y::Float64`: The y-coordinate of the data point.
"""
@kwdef struct DataPoint
x::Float64
y::Float64
end

Base.show(io::IO, obj::DataPoint) = dump(io, obj; maxdepth=1)
```

Error Handling and Validation
- Use Julia's exception system for error handling.
- Create custom exception types for specific error cases.
- Use guard clauses to handle preconditions and invalid states early.
- Implement proper error logging and user-friendly error messages.
- Example:
```julia
struct InvalidInputError <: Exception
msg::String
end

function process_positive_number(x::Number)
x <= 0 && throw(InvalidInputError("Input must be positive"))
# Process the number
end
```

Performance Optimization
- Use type annotations to avoid type instabilities.
- Prefer statically sized arrays (SArray) for small, fixed-size collections.
- Use views (@views macro) to avoid unnecessary array copies.
- Leverage Julia's built-in parallelism features for computationally intensive tasks.
- Use benchmarking tools (BenchmarkTools.jl) to identify and optimize bottlenecks.

Testing
- Use the `Test` module for unit testing.
- Create one top-level `@testset` block per test file.
- Write test cases of increasing difficulty with comments explaining what is being tested.
- Use individual `@test` calls for each assertion, not for blocks.
- Example:
```julia
using Test

@testset "MyModule tests" begin
# Test basic functionality
@test add(2, 3) == 5

# Test edge cases
@test add(0, 0) == 0
@test add(-1, 1) == 0

# Test type stability
@test typeof(add(2.0, 3.0)) == Float64
end
```

Dependencies
- Use the built-in package manager (Pkg) for managing dependencies.
- Specify version constraints in the Project.toml file.
- Consider using compatibility bounds (e.g., "Package" = "1.2, 2") to balance stability and updates.

Code Organization
- Use modules to organize related functionality.
- Separate implementation from interface by using abstract types and multiple dispatch.
- Use include() to split large modules into multiple files.
- Follow a consistent project structure (e.g., src/, test/, docs/).

Documentation
- Write comprehensive docstrings for all public functions and types.
- Use Julia's built-in documentation system (Documenter.jl) for generating documentation.
- Include examples in docstrings to demonstrate usage.
- Keep documentation up-to-date with code changes.

17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "julia",
"request": "launch",
"name": "Run active Julia file",
"program": "${file}",
"stopOnEntry": false,
"cwd": "${workspaceFolder}",
"juliaEnv": "${command:activeJuliaEnvironment}"
}
]
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.fontSize": 16
}
114 changes: 114 additions & 0 deletions DesignMind.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# LumpedHydro.jl 设计思路

## 这个包的目标是什么?

- 适用于概念性水文模型搭建,以及物理耦合的深度学习模型搭建
- 继承superflex和MARRMoT各自的优缺点,构建新的水文模型构建框架,具体来说:
- 沿用superflex的构建框架,即element,node,network等
- 沿用MARRMoT的flux function构建思路,使不同计算模块实现分类管理
- **保证各模块的随机组合的可行性,当前计算模块可粗略分为SnowWater, SoilWater和RoutingStore三种**
- 提供区域多模型按权重预测(Node),提供半分布式水文模型搭建(Network)

## 这个包的使用风格应该是什么样子的?

`flux -> Element -> Node -> Network`

- Function根据参数不同分派不同函数计算

```
baseflow(i::NamedTuple, p::NamedTuple, sf::Function)
```
- 让概念性水文模型的搭建像torch,lux这样,每个中间通量的计算都应该是一个层

```julia
model = build_unit(
name=name,
elements=elements
)

model = Unit(
name=name,
surface=surf_ele,
soil=soil_eles,
route=route_ele,
)
```
- 每个element又是由多个flux function所组成的,包中已经内置了大量的flux function和构成的element

```
func1 = flux_func(input...;params...)
element = Element(
func1,
func2;
params...,
config...
)
```
- 构建模型中,应该有构建合理性的校验和提示功能,主要的提示功能就是对模型各层计算数据是否存在缺失的功能,并对于缺失的模块提出增加建议
- 深度学习模型嵌入应该是作为特殊的function进行嵌入
- Element是由多个function组合而成,要保证能使用既有的func也能使用自定义的func
- 一般而言模型自身不携带任何数据,一般通过外界参数输入或参数估计器输入

## Unit的特性

- unit将分为三个基础层:~~surface,soil,route~~ snow,surface, soil, free water, route
- surface层可以对应于,深度学习模型的input层,其中可能就是简单的信息传输,也可能会存在融雪模块需要ode计算
- soil层可以包含多个element层,通常土壤的element都会认为时非线性水库,通常需要ode模块求解
- route层由于lagflux的限制,无法参与其他element进行联合计算,同样部分route层也会涉及ode计算

### Surface层特性

- surface层接受气象要素的输入,包括降雨,潜在蒸发,气温,日照时常等
- surface层的输出,全部统一名称为infiltration
- surface层还可以考虑一些不透水的情况,直接产出地表径流

### Soil层特性

- 受水箱模型的启发,soil层设计为可以包括多个element,设定为上下层等土壤分层
- soil层第一层的输入需要与surface层对接,所以接受变量必须为infiltration
- soil层会根据层数得出不同数量的出流量,每个层基本对应一个中间计算模块
- 水文模型的核心计算模块,通常代表模型的基本输入
- 模型输出为flow,包括:
1. 单一flow,如Exphydro
2. Fastflow和Slowflow, 如GR4J
3. Surfaceflow, Interflow, Baseflow三层
- 模型输入需要统一,比如Infiltration,Pet

### State Element的特性(或者是需求)

influxes, outfluxes, statefluxes

state elmement 有时候会有需求,即添加input flux和output flux从而灵活改变state flux的计算结果,

但是这种可能会引入一些难以命名的变量(m50)


## 以后的一种构建方式

```julia

bucket = @hydrobucket begin
@varaibles a b c d e f
@parameters k1 k2

@fluxes begin
b ~ a + k1
c ~ b + k2
[e, f] ~ model([b, c])
end

@states begin
d ~ b - c
end
end

route = @hydroroute begin
@variables q
@parameters k
q ~ k * d
end

model = @hydromodel begin
bucket, route
end
```
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

62 changes: 0 additions & 62 deletions Project.toml

This file was deleted.

50 changes: 0 additions & 50 deletions README.md

This file was deleted.

Loading

0 comments on commit 1cffd39

Please sign in to comment.