优化点5,6
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
# Fracture Well UI Redesign Plan
|
||||
|
||||
## Problem Summary
|
||||
|
||||
Current `Wells` page structure is not suitable for the following scenario:
|
||||
|
||||
- reservoir may contain zero fracture wells
|
||||
- reservoir may contain one fracture well
|
||||
- reservoir may contain multiple fracture wells
|
||||
- `num_fracture_wells` must equal the fracture-well count
|
||||
- `welloc{i,1}` stores perforation coordinates for fracture well `i`
|
||||
- perforation coordinates are often fracture coordinates, but they may also be independent coordinates
|
||||
- fracture engineering input can stay unified in `fracture.input_content`
|
||||
- perforation data cannot be merged into one shared array, otherwise multiple fracture wells cannot be distinguished
|
||||
|
||||
The current controller only reads and writes the first entry of `c.wells.welloc`, so the present UI effectively assumes only one fracture well.
|
||||
|
||||
## Current Constraint In Existing Code
|
||||
|
||||
Existing runtime logic already supports multiple fracture wells in principle:
|
||||
|
||||
- `run_case.m`
|
||||
- `build_fracture_wells(...)` loops over `num_fracture_wells`
|
||||
- original case files
|
||||
- example case 7 uses `num_fracture_wells = 6`
|
||||
- `welloc{1}` to `welloc{6}` are defined separately
|
||||
- `well2` also has 6 rows and matches them one by one
|
||||
|
||||
The main mismatch is in the GUI/controller layer:
|
||||
|
||||
- `FractureWellLocationTable` is a single table
|
||||
- controller uses `unwrapFirstCell(c.wells.welloc)`
|
||||
- controller writes back with `replaceFirstCell(...)`
|
||||
|
||||
So the GUI schema is the real bottleneck.
|
||||
|
||||
## Recommended UI Principle
|
||||
|
||||
Do not organize the fracture-well section as:
|
||||
|
||||
- one table for all perforation coordinates only
|
||||
|
||||
Instead organize it as:
|
||||
|
||||
- one summary table for fracture well definitions
|
||||
- one detail editor for the currently selected fracture well's perforation coordinates
|
||||
|
||||
This is the safest structure because:
|
||||
|
||||
- it supports `0 / 1 / N` fracture wells
|
||||
- each fracture well keeps its own `welloc{i,1}`
|
||||
- `well2(i,:)` and `welloc{i,1}` can stay naturally linked by row index
|
||||
- fracture geometry remains independent in `fracture.input_content`
|
||||
|
||||
## Recommended Data Mapping
|
||||
|
||||
### Keep These Backend Fields
|
||||
|
||||
Keep the runtime/backend idea below:
|
||||
|
||||
```matlab
|
||||
c.wells.num_fracture_wells
|
||||
c.wells.well2
|
||||
c.wells.welloc
|
||||
```
|
||||
|
||||
Recommended interpretation:
|
||||
|
||||
- `c.wells.num_fracture_wells = size(c.wells.well2, 1)`
|
||||
- `c.wells.welloc{i,1}` is the perforation coordinate matrix of fracture well `i`
|
||||
- `size(c.wells.welloc, 1)` should equal `size(c.wells.well2, 1)`
|
||||
|
||||
Recommended invariant:
|
||||
|
||||
```matlab
|
||||
num_fracture_wells == size(well2,1) == numel(welloc)
|
||||
```
|
||||
|
||||
### Suggested Meaning Of `well2`
|
||||
|
||||
Treat `well2` as the fracture-well summary table only.
|
||||
|
||||
Recommended editable columns:
|
||||
|
||||
1. `well_name`
|
||||
2. `rw`
|
||||
3. `skin`
|
||||
4. `welltype`
|
||||
|
||||
Recommended non-editable or derived columns:
|
||||
|
||||
1. `nperf`
|
||||
2. `perf_index`
|
||||
|
||||
Reason:
|
||||
|
||||
- `nperf` is derived from `welloc{i,1}`
|
||||
- `perf_index` is generated by `findWelloc(...)`
|
||||
- these two should not be manually edited in the GUI
|
||||
|
||||
If keeping the current 6-column backend shape for compatibility, then GUI can still display 6 columns, but:
|
||||
|
||||
- column 2 `nperf` should be read-only
|
||||
- column 3 `perf_index` should be read-only or hidden
|
||||
|
||||
## Recommended Wells Page Layout
|
||||
|
||||
### Section A: Conventional Wells
|
||||
|
||||
Keep existing `Well1Table`.
|
||||
|
||||
This remains for ordinary wells already handled by `handle_well1(...)`.
|
||||
|
||||
### Section B: Fracture Wells Summary
|
||||
|
||||
Repurpose current `Well2Table` into a fracture-well summary table.
|
||||
|
||||
Recommended label:
|
||||
|
||||
- `Fracture Wells`
|
||||
|
||||
Recommended columns:
|
||||
|
||||
1. `well_name`
|
||||
2. `rw`
|
||||
3. `skin`
|
||||
4. `welltype`
|
||||
5. `nperf` optional read-only display
|
||||
|
||||
Buttons:
|
||||
|
||||
- `Add Fracture Well`
|
||||
- `Delete Fracture Well`
|
||||
|
||||
Behavior:
|
||||
|
||||
- add one row to `well2`
|
||||
- also create one empty `welloc{i,1} = []`
|
||||
- delete row `i` from both `well2` and `welloc`
|
||||
- after any add/delete:
|
||||
- `num_fracture_wells = size(well2,1)`
|
||||
|
||||
### Section C: Perforation Detail Editor
|
||||
|
||||
Do not keep one generic `FractureWellLocationTable` without context.
|
||||
|
||||
Replace it conceptually with:
|
||||
|
||||
- one selector showing which fracture well is being edited
|
||||
- one table that edits only that well's perforation coordinates
|
||||
|
||||
Recommended controls:
|
||||
|
||||
1. `SelectedFracWellDropDown` or `SelectedFracWellListBox`
|
||||
2. `FractureWellLocationTable`
|
||||
3. `Add Perf Row`
|
||||
4. `Delete Perf Row`
|
||||
5. optional helper text label
|
||||
|
||||
Recommended table columns:
|
||||
|
||||
1. `x`
|
||||
2. `y`
|
||||
3. `z`
|
||||
|
||||
Behavior:
|
||||
|
||||
- when user selects fracture well `i`
|
||||
- table shows `welloc{i,1}`
|
||||
- when table changes
|
||||
- write back to `welloc{i,1}`
|
||||
- when no fracture well exists
|
||||
- disable this table and show hint text like:
|
||||
- `No fracture well is defined. Please add a fracture well first.`
|
||||
|
||||
This is the key redesign.
|
||||
|
||||
## Relationship Between Fracture Input And Perforation Input
|
||||
|
||||
These two parts should stay separate in the UI.
|
||||
|
||||
### Fracture Tab
|
||||
|
||||
Keep:
|
||||
|
||||
- `fracture.input_content`
|
||||
|
||||
This is for fracture geometry/engineering input.
|
||||
|
||||
### Wells Tab
|
||||
|
||||
Keep separate:
|
||||
|
||||
- fracture-well summary
|
||||
- per-well perforation coordinates
|
||||
|
||||
Reason:
|
||||
|
||||
- fractures describe the reservoir fracture system
|
||||
- perforations describe where a specific fracture well connects to the model
|
||||
- one fracture well may connect to one or more fracture coordinates
|
||||
- perforation coordinates may match fracture coordinates, but not always
|
||||
|
||||
So they should not be merged into the same editable widget.
|
||||
|
||||
## Whether `num_fracture_wells` Should Be A Separate UI Field
|
||||
|
||||
Recommendation:
|
||||
|
||||
- do not expose `num_fracture_wells` as an independent editable numeric field
|
||||
|
||||
Instead:
|
||||
|
||||
- derive it automatically from fracture-well summary row count
|
||||
|
||||
Reason:
|
||||
|
||||
- avoids inconsistency
|
||||
- user only manages actual fracture-well rows
|
||||
- controller maintains `num_fracture_wells`
|
||||
|
||||
## Recommended App Designer Changes
|
||||
|
||||
These are the parts you should change manually in `.mlapp`.
|
||||
|
||||
### Minimum Change Version
|
||||
|
||||
If you want the smallest UI change:
|
||||
|
||||
1. keep `Well1Table`
|
||||
2. keep `Well2Table`
|
||||
3. keep `FractureWellLocationTable`
|
||||
4. add one selector control above `FractureWellLocationTable`
|
||||
- name suggestion: `SelectedFracWellDropDown`
|
||||
5. change labels so that:
|
||||
- `Well2Label` -> `Fracture Wells`
|
||||
- `WellLocationLabel` -> `Perforation Coordinates`
|
||||
6. change `FractureWellLocationTable` columns from one generic column to three columns:
|
||||
- `x`, `y`, `z`
|
||||
7. add a small note label:
|
||||
- `Each fracture well has its own perforation coordinate list.`
|
||||
|
||||
This is the recommended minimum viable fix.
|
||||
|
||||
### Better Version
|
||||
|
||||
If you can slightly improve layout:
|
||||
|
||||
Use a 3-block layout in `WellsTab`:
|
||||
|
||||
1. top-left: `Well1Table`
|
||||
2. top-right: `Well2Table`
|
||||
3. bottom-wide: selected fracture well perforation editor
|
||||
|
||||
This will be clearer than the current four unrelated tables.
|
||||
|
||||
## Recommended Table Definitions
|
||||
|
||||
### `Well1Table`
|
||||
|
||||
No major structural change required.
|
||||
|
||||
### `Well2Table`
|
||||
|
||||
Recommended columns:
|
||||
|
||||
1. `well_name`
|
||||
2. `rw`
|
||||
3. `skin`
|
||||
4. `welltype`
|
||||
|
||||
Optional extra read-only columns:
|
||||
|
||||
5. `nperf`
|
||||
|
||||
If you want to keep backend compatibility without changing much controller code later, you may still visually keep 6 columns:
|
||||
|
||||
1. `well_name`
|
||||
2. `nperf` read-only
|
||||
3. `perf_index` hidden or read-only expression
|
||||
4. `rw`
|
||||
5. `skin`
|
||||
6. `welltype`
|
||||
|
||||
But from user experience perspective, 4 editable columns are better.
|
||||
|
||||
### `FractureWellLocationTable`
|
||||
|
||||
Recommended columns:
|
||||
|
||||
1. `x`
|
||||
2. `y`
|
||||
3. `z`
|
||||
|
||||
Each row is one perforation point for the currently selected fracture well.
|
||||
|
||||
## Controller Change Direction
|
||||
|
||||
When you later modify `EDFMAppController.m`, the well section should change conceptually as follows.
|
||||
|
||||
### Current Wrong Logic
|
||||
|
||||
```matlab
|
||||
obj.setTableValue('FractureWellLocationTable', obj.unwrapFirstCell(c.wells.welloc));
|
||||
...
|
||||
fractureWellLocation = obj.getNumericTableValue('FractureWellLocationTable', obj.unwrapFirstCell(c.wells.welloc));
|
||||
c.wells.welloc = obj.replaceFirstCell(c.wells.welloc, fractureWellLocation);
|
||||
c.wells.num_fracture_wells = numel(c.wells.welloc);
|
||||
```
|
||||
|
||||
This only handles the first fracture well.
|
||||
|
||||
### Target Logic
|
||||
|
||||
Need a selected index such as:
|
||||
|
||||
```matlab
|
||||
selectedFracWellIndex
|
||||
```
|
||||
|
||||
Read UI:
|
||||
|
||||
```matlab
|
||||
c.wells.well2 = ...
|
||||
c.wells.num_fracture_wells = size(c.wells.well2,1);
|
||||
ensure c.wells.welloc has same length
|
||||
c.wells.welloc{selectedFracWellIndex,1} = currentPerfTable
|
||||
```
|
||||
|
||||
Write UI:
|
||||
|
||||
```matlab
|
||||
set Well2Table from c.wells.well2
|
||||
refresh fracture-well selector items
|
||||
load FractureWellLocationTable from c.wells.welloc{selectedFracWellIndex,1}
|
||||
```
|
||||
|
||||
## Validation Rules To Add
|
||||
|
||||
When this section is later coded, these checks are recommended:
|
||||
|
||||
1. `size(well2,1) == numel(welloc)`
|
||||
2. `num_fracture_wells == size(well2,1)`
|
||||
3. each `welloc{i,1}` must be empty or an `N x 3` numeric matrix
|
||||
4. if `well2(i,1)` is empty, generate default name like `wf1`, `wf2`
|
||||
5. when no fracture well exists:
|
||||
- `well2 = {}`
|
||||
- `welloc = {}`
|
||||
- `num_fracture_wells = 0`
|
||||
6. if user deletes a fracture well, also delete its perforation list
|
||||
|
||||
## Practical Recommendation
|
||||
|
||||
For your current stage, the best balance is:
|
||||
|
||||
1. fracture geometry remains in `FractureTab`
|
||||
2. ordinary wells remain in `Well1Table`
|
||||
3. fracture wells use `Well2Table`
|
||||
4. perforations are edited through one selected-well detail table
|
||||
5. `num_fracture_wells` is auto-derived, not manually entered
|
||||
|
||||
This will match both:
|
||||
|
||||
- the old case-script logic
|
||||
- the future GUI editing logic
|
||||
|
||||
And it also naturally supports the case where there is no fracture well.
|
||||
|
||||
## Manual UI Rename Suggestions
|
||||
|
||||
Suggested visible labels:
|
||||
|
||||
- `Well1Label` -> `Conventional Wells`
|
||||
- `Well2Label` -> `Fracture Wells`
|
||||
- `WellLocationLabel` -> `Perforation Coordinates`
|
||||
- `ScheduleLabel` keep as `Schedule`
|
||||
|
||||
Suggested new control names if you add them:
|
||||
|
||||
- `SelectedFracWellDropDown`
|
||||
- `SelectedFracWellDropDownLabel`
|
||||
- `FracWellHintLabel`
|
||||
|
||||
## Conclusion
|
||||
|
||||
The main point is:
|
||||
|
||||
- fracture information can stay unified in `fracture.input_content`
|
||||
- perforation information must be stored per fracture well
|
||||
- therefore the GUI must be changed from "one perforation table" to "fracture-well summary + selected-well perforation detail"
|
||||
|
||||
That is the most stable and least confusing design for the current codebase.
|
||||
Reference in New Issue
Block a user