-
Notifications
You must be signed in to change notification settings - Fork 56
Hide boundary points in figure #391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This PR removed the unrelated files in #361 and set the shown points as a variable of Euler1DApp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Provide an option to select the amount of data to plot. It can serve as a way to fall back to the original behavior.
- Rename
plot_pointtoxindices. - Fix CI errors.
Please fix the CI failures. A prominent one is test failures on the array size: https://github.com/solvcon/modmesh/actions/runs/10025477375/job/27708689299?pr=391#step:11:285 :
=================================== FAILURES ===================================
____________________ ShockTubeTC.test_field_with_numerical _____________________
self = <test_onedim_euler.ShockTubeTC testMethod=test_field_with_numerical>
def test_field_with_numerical(self):
self.st.build_numerical(xmin=-1, xmax=1, ncoord=21,
time_increment=0.05)
self.st.build_field(t=0.0)
self.assertIsInstance(self.st.svr, euler1d.Euler1DSolver)
> self.assertEqual(len(self.st.coord), 11)
E AssertionError: 9 != 11
tests/test_onedim_euler.py:110: AssertionError
=========================== short test summary info ============================
FAILED tests/test_onedim_euler.py::ShockTubeTC::test_field_with_numerical - AssertionError: 9 != 11
=================== 1 failed, 181 passed, 5 skipped in 6.72s ===================
make: *** [pytest] Error 1
The test fails because you changed the length of the array.
modmesh/app/euler1d.py
Outdated
| self.interval = self.solver_config.get_var("timer_interval", "value") | ||
| self.max_steps = self.solver_config.get_var("max_steps", "value") | ||
| self.profiling = self.solver_config.get_var("profiling", "value") | ||
| ncoord = self.solver_config.get_var("ncoord", "value") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@j8xixo12 With this PR I realized that self.solver_config.get_var() is too wordy. The lengthy API makes it hard to quickly write and understand code.
Please propose a new design of SolverConfig and PlotConfig in the discussions. We can probably consider __getattr__() or __getitem__()
@Gene0315 please provide an option to keep existing behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Gene0315 You can use the inline comment for focused discussions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@j8xixo12 Any comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will create a discussion and propose a new design in the discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will create a discussion and propose a new design in the discussion.
Thanks, @j8xixo12 . Maybe creating an issue describing what we know and may be done can help.
modmesh/app/euler1d.py
Outdated
| self.max_steps = self.solver_config.get_var("max_steps", "value") | ||
| self.profiling = self.solver_config.get_var("profiling", "value") | ||
| ncoord = self.solver_config.get_var("ncoord", "value") | ||
| self.plot_point = np.linspace(2, (ncoord - 3), num=((ncoord - 3) // 2), dtype=int) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A convention of short-living temporary variables is _. The two lines can be changed to:
_ = self.solver_config.get_var("ncoord", "value")
self.xindices = np.linspace(2, (_ - 3), num=((_ - 3) // 2), dtype=int)plot_point is not a good attribute name because the content is not points but indices of the coordinate (1D point) arrays.
Are these two the same questions? Do you mean to provide it as an option such as "ncoord" or "max step" in qt window?
It is ok.
But I don't know how to check whether I solve the CI error correctly. Maybe I can create a PR in my own repo again before I upload the new code here? |
Yes they are similar. No, the options only need to be in the code. We do not need them to be in the GUI yet.
You can turn on Github Actions in your own repository and you will see the CI runs when you push to your repository. You do not need a PR for the CI runs in your repository. You should also run the tests locally to reproduce the failures on your development machine for fixing them. |
I'm so confused how to set the
How can I run the check tests in my laptop? Is it feasable to run the |
Something like: def set_solver_config(self, keep_edge=False):
# ...
if keep_edge:
# create self.xindices including the edge points.
else:
_ = self.solver_config.get_var("ncoord", "value")
self.xindices = np.linspace(2, (_ - 3), num=((_ - 3) // 2), dtype=int)In this way you can allow a configuring function to turn on If you want to make the option available in GUI, the flag
The Line 116 in 6a9888d
They are used in Github Actions too. |
|
@yungyuc I passed all the checks finally! But, I don't know what I have to do next. Could you give me some tips? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yungyuc I passed all the checks finally! But, I don't know what I have to do next. Could you give me some tips?
Congratulations! Passing all checks means your code starts to work. Then we can start code review.
Please address the following points:
- Remove the redundant
startup.py. - Use a more specific code comment than "Use the numerical solver".
- Remove all unnecessary add/removal/change of blank lines and white spaces.
- It makes more sense to calculate
numfromstartandstop. - There should be only one call to
np.linspace(). The conditional (if/else) should be used to calculate the arguments to the helper. - The
xindicesattribute should be created in the initialization helperEuler1DSolver.init_solver()of the objectself.svr. - Reduce the change to the code in the function
update_lines().
@j8xixo12 Could you please also help take a look?
startup.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is redundant file, please remove.
modmesh/onedim/euler1d.py
Outdated
| self.svr.xindices = np.linspace( | ||
| 2, (_ - 3), num=((_ - 3) // 2), dtype=int | ||
| ) | ||
| # Use the numerical solver. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please be more specific about what you meant. "Use the numerical solver" is not a clear statement.
modmesh/onedim/euler1d.py
Outdated
| :param coord: If None, take the coordinate from the numerical solver. | ||
| :return: None | ||
| """ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This insertion of a blank line is not necessary. Do you introduce unnecessary/unrelated change of blank lines and whitespaces in a patch (i.e., checkins/PR).
tests/test_onedim_euler.py
Outdated
| self.st.build_numerical(xmin=-1, xmax=1, ncoord=21, | ||
| time_increment=0.05) | ||
| self.st.build_field(t=0.0) | ||
| self.st.build_field(t=0.0, keep_edge=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix of the unit tests by the addition of the single argument is good.
modmesh/onedim/euler1d.py
Outdated
|
|
||
| if None is coord: | ||
| coord = self.svr.coord[::2] # Use the numerical solver. | ||
| _ = self.svr.ncoord |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 9 lines of code is mouthy. Please use the follow code instead (please make proper adjustment if needed because I didn't test it myself):
_ = self.svr.ncoord
start = 0 if keep_edge else 2
stop = _ - stop - 1
num = # It makes more sense to calculate from start and stop
xindices = np.linspace(start, stop, num=num, dtype='int32')
modmesh/onedim/euler1d.py
Outdated
| _ = self.svr.ncoord | ||
| if keep_edge: | ||
| self.svr.xindices = np.linspace( | ||
| 0, (_ - 1), num=((_ + 1) // 2), dtype=int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes more sense to calculate num from start and stop.
modmesh/onedim/euler1d.py
Outdated
| coord = self.svr.coord[::2] # Use the numerical solver. | ||
| _ = self.svr.ncoord | ||
| if keep_edge: | ||
| self.svr.xindices = np.linspace( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The xindices attribute should be created in the initialization helper Euler1DSolver.init_solver() of the object self.svr:
modmesh/modmesh/onedim/euler1d.py
Line 36 in 214b474
| def init_solver(xmin, xmax, ncoord, time_increment, gamma): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not add attributes outside the class. It will be very difficult for a maintainer to keep track of where attributes are added, if they are not created in an organized way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not add attributes outside the class. It will be very difficult for a maintainer to keep track of where attributes are added, if they are not created in an organized way.
@yungyuc I agree that we shouldn't add attributes outside the class, but I failed to create the xindices in the Euler1DCore
modmesh/modmesh/onedim/euler1d.py
Line 38 in 214b474
| svr = _impl.Euler1DCore(ncoord=ncoord, time_increment=time_increment) |
I tried to add the
xindices in| void Euler1DCore::initialize_data(size_t ncoord) |
like
m_coord in| m_coord = SimpleArray<double>(/*length*/ ncoord); |
but I'm confused how to add it because I cannot decide its size in the begining.
Or, maybe I misunderstand what you want me to do? Can you give me some suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.svr is a Euler1DSolver object. You can create xindices after
modmesh/modmesh/onedim/euler1d.py
Line 28 in 214b474
| self._core = self.init_solver(xmin, xmax, ncoord, time_increment, |
The code may be like:
def __init__(self, xmin, xmax, ncoord, time_increment=0.05):
self._core = self.init_solver(xmin, xmax, ncoord, time_increment,
gamma=1.4)
self.xindices = ...
# gamma is 1.4 for air.You may consider to let Euler1DSolver.__init__() take a new argument for keep_edge, if necessary.
modmesh/app/euler1d.py
Outdated
| internal_energy[::2])) | ||
| self.entropy.update(adata=self.st.entropy_field, | ||
| ndata=self.st.svr.entropy[::2]) | ||
| self.density.update( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please simplify the code like:
_s = self.st.svr.xindices
self.density.update(adata=self.st.density_field,
ndata=self.st.svr.density[_s])In this way, you do not change the original code by too much. It will be easier to keep track of the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change of line breaking is not necessary for updating the slicing (from [::2] to [_s]). Please revert it to the original style.
That is, since the original style is:
self.pressure.update(adata=self.st.pressure_field,
ndata=self.st.svr.pressure[::2])instead of writing (with the different line breaking):
self.pressure.update(
adata=self.st.density_field,
ndata=self.st.svr.density[_s]
)write
self.pressure.update(adata=self.st.pressure_field,
ndata=self.st.svr.pressure[_s])The unnecessary change will baffle future maintainers. Style matters. Don't change the style when changing the logic, and vice versa. Change of logic and that of style should not take place at the same time.
|
@yungyuc I tried to revise the code like what you mentioned above. Could you take a look at it? I'm not sure whether the code is fine now. Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some old issues were not handled and there are also new issues. Please fix.
-
app/euler1d.py:747: Do not change the line breaking (style). This has been request in the previous review. -
onedim/euler1d.py:324: Do not create a new object forxindicesinself.svrwhen updating the value. Instead, force to use the existing one by writingself.svr.xindices[...]. -
onedim/euler1d.py:320: Why duplicate code?
modmesh/app/euler1d.py
Outdated
| internal_energy[::2])) | ||
| self.entropy.update(adata=self.st.entropy_field, | ||
| ndata=self.st.svr.entropy[::2]) | ||
| self.density.update( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change of line breaking is not necessary for updating the slicing (from [::2] to [_s]). Please revert it to the original style.
That is, since the original style is:
self.pressure.update(adata=self.st.pressure_field,
ndata=self.st.svr.pressure[::2])instead of writing (with the different line breaking):
self.pressure.update(
adata=self.st.density_field,
ndata=self.st.svr.density[_s]
)write
self.pressure.update(adata=self.st.pressure_field,
ndata=self.st.svr.pressure[_s])The unnecessary change will baffle future maintainers. Style matters. Don't change the style when changing the logic, and vice versa. Change of logic and that of style should not take place at the same time.
modmesh/onedim/euler1d.py
Outdated
| start = 0 if keep_edge else 2 | ||
| stop = _ if keep_edge else (_ - 2) | ||
| num = (stop - start) // 2 + 1 | ||
| self.svr.xindices = np.linspace(start, stop, num, dtype='int32') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write self.svr.xindices[...] = np.linspace(start, stop, num, dtype='int32'). Note that the first ... in [] is ellipsis. By using the ellipsis, you are using the xindices created in the solver object instead of creating a new one and replacing the existing one.
modmesh/onedim/euler1d.py
Outdated
| if None is coord: | ||
| coord = self.svr.coord[::2] # Use the numerical solver. | ||
| if coord is None: | ||
| _ = self.svr.ncoord - 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to repeat the same code here and in line 32?
Sorry, in my understanding, passing
In previous code, I want to know the size of |
yungyuc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. It now looks perfect!
Following the issue #361
The PR hides the boundary points.
Features: The plotting hides the unreasonable points on the boundary.
Strength: It makes the figure look nicer without changing the solution data.
Weakness: It is better to calculate the correct values on the boundary and show them on the boundary.