Hypnotoad: double precision and y-boundary guard cells#1647
Conversation
Previously, for nonorthogonal grids the starting positions (points along the separatrix) were refined only when the grid was being created in the core. This commit moves the refinement to a position (previously commented-out) in grid_region_nonorth which ensures it is done in every case. This makes non-orthogonal grid generation more robust, especially around x-points.
When create_grid fails, sometimes it changes some options and tries calling create_grid again. Previously the 'simple' setting was not being passed through to the new calls.
Previously Hypnotoad would use the version from idllib if that was in the $IDL_PATH.
The quantity 'H' is the y-derivative of qinty, but qinty is an integral in y. Instead of calculating numerically the integral and derivative, just set 'H' equal to the integrand. This removes errors at the y-boundaries.
When calculating 'bxcvz' the integrated shear 'sinty' was used. This commit updates to use 'I' instead, so that when 'I' is set to zero for orthogonal coordinates the curvature is calculated consistently.
Calculate and save values at user-chosen number of guard cells beyond the end of the grid at the divertor targets. Default value is 0 to ensure compatibility with older versions of BOUT++ that don't check the (newly added) 'y_boundary_guards' value in grid files.
Change my_int_y to make its result zero at the first grid point, i.e. subtract the contribution of the lower y-boundary guard cells (which then have negative values in the result). Make qinty, sinty consistent on open surfaces, by setting them to zero at the first y-grid point in the domain for open flux-surface regions. This makes the results the same when the number of y-boundary guard cells is changed.
Previously Hypnotoad used single precision floats in most places. Using double precision improves reproducibility of grids by reducing rouding errors. In particular rounding errors due to limited precision (e.g. in interpolations) are amplified by numerical derivatives; there are some quantities, e.g. zShift (aka qinty) that require interpolation, then differentiation, then integration so that errors can accumulate quite badly. To ensure double precision: - pass /DOUBLE argument to all calls to INTERPOLATE - use double precision for constants, by entering them with a 'D', e.g. 1.5D*f... - use DBLARR instead of FLTARR to create arrays
Makes results more consistent with/without y-boundary guard cells.
|
Thanks @johnomotani this looks good. My one worry is what happens if a new grid with |
|
@bendudson I think the BOUT-dev/src/mesh/data/gridfromfile.cxx Lines 200 to 210 in 1c8d769 Single null cases with 0 or I can't think of a way to check more strictly? I meant to make people think before using grids with BOUT-dev/tools/tokamak_grids/gridgen/hypnotoad.pro Lines 1072 to 1075 in 3049f4a |
| SURFACE, data.jpar0, tit="Input Jpar0", chars=2 | ||
| SURFACE, jpar, tit="New Jpar0", chars=2 | ||
| PLOT, data.jpar0[0,*], tit="jpar at x=0. Solid=input", yr=[MIN([data.jpar0[0,*],jpar[0,*]]), $ | ||
| PLOT, data.jpar0[0,*], tit="jpar at x=0.D Solid=input", yr=[MIN([data.jpar0[0,*],jpar[0,*]]), $ |
There was a problem hiding this comment.
This 0.D probably not needed, though doesn't hurt
|
Actually, I just noticed that |
Don't need double precision specification in a plot label.
| start_ri[i] = ri1 | ||
| start_zi[i] = zi1 | ||
| ENDFOR | ||
| ;FOR i=0, np-1 DO BEGIN |
There was a problem hiding this comment.
Is this refinement not needed, or does it lead to incorrect results?
There was a problem hiding this comment.
I thought it was not needed, because I switched on refinement in grid_region_nonorth. Looking again, they're not quite the same thing, because the refinement I switched on is of the line after interpolating onto the poloidal grid, whereas this was for the line that is input to the interpolation. I guess more refinement should never hurt and might help, so I'll put back this stage of refinement (possibly at the beginning of grid_region_nonorth if that reduces code duplication.
| @@ -1450,20 +1516,20 @@ FUNCTION create_nonorthogonal, F, R, Z, in_settings, critical=critical, $ | |||
| ;; REPEAT BEGIN | |||
There was a problem hiding this comment.
I guess all this commented out code can be removed?
|
|
||
| ; Use finite-differencing | ||
| ;di = 2. | ||
| ;di = 2.DD |
There was a problem hiding this comment.
DD? Anyway this commented-out code can go I think.
bendudson
left a comment
There was a problem hiding this comment.
Thanks @johnomotani that's a lot of changes!
Previously was done before calling grid_region_nonorth in the closed-field line only case (though this was recently commented out), but not in other cases. Now done for all cases.
If y_boundary_guards>0, then write 'MYG=y_boundary_guards' into the grid file. This ensures that checks present in BOUT++ versions earlier than 4.3 will only allow compatible grids to be read; i.e. single null with y_boundary_guards=0 or MYG, or double null with y_boundary_guards=0.
|
With the last commit I pushed, Hypnotoad writes |
|
@bendudson: In ca936c6 I turned back on the grid refinement that I commented out before, but moved into |
bendudson
left a comment
There was a problem hiding this comment.
Thanks @johnomotani !
Agreed a way to test these grids would be nice, but is a problem for another PR. This one is definitely an improvement.
Adds the option to write y-boundary guard cells from Hypnotoad. This includes the 'upper' target in double null configurations; the number of y-points in the gridfile may therefore be
ny+2*n_yguardsin single-null orny+4*n_yguardsin double null configurations. Requires the updates toGridFilein #1646 to read these grid files correctly ifn_yguards != 0, so the number of y-guards defaults to zero.Upgrades Hypnotoad to use double-precision arithmetic everywhere. The motivation for this is that the change to number of y-boundary guard cells changes some of the indexing in Hypnotoad, which effectively chages some of the rounding errors. I generated one grid file with a version of Hypnotoad with double-precision but without the y-boundary changes here and another with this version: the relative errors between the two were mostly below
1.e-6, butbxcvxandShiftTorsionwere~3e-6. That was for an 'orthogonal' grid - field-aligned grids were significantly worse because of the integrated shear appearing in metric components. Comparing the single-precision version innextto the double precision (with or without the y-boundary changes) the relative errors are up to1.8in the metric components!Also a few other fixes:
simplesetting ifcreate_gridis re-rungen_surfacetogen_surface_hypnotoadso it doesn't get masked by the version fromidllib(only matters becausegen_surface_hypnotoadneeded changing in this PR)Hwas calculated as the y-derivative ofqinty, butqintyis a y-integral, so can just setHfrom the integrandIinstead ofsintyso that when writing out x-z orthogonal (non-field-aligned) grids the curvature does not include the integrated shear (the option to write x-z orthogonal output setsI=0)nnpolwas re-calculated wrongly. This did not cause a problem because the value would always be too big, and only had the effect of making a few output arrays too long (but they were just filled with harmless zeros).beta- not sure this is a fix as such, but smoothing propagates differences from the boundary points further into the grid and made it harder to compare grids with/without y-boundary guard cells - hopefully with double precisionbetawon't be too noisy.