Skip to content

Add custom formatter for Fields#3285

Open
ZedThree wants to merge 8 commits intonextfrom
field-format
Open

Add custom formatter for Fields#3285
ZedThree wants to merge 8 commits intonextfrom
field-format

Conversation

@ZedThree
Copy link
Member

Needs some more docs, but lets you write out fields:

output.write("{}", field);

and get something like:

(0, 0, 0): 0; (0, 0, 1): 1;
(0, 1, 0): 2; (0, 1, 1): 3;
(0, 2, 0): 4; (0, 2, 1): 5;
(0, 3, 0): 6; (0, 3, 1): 7;
(0, 4, 0): 8; (0, 4, 1): 9;

(1, 0, 0): 10; (1, 0, 1): 11;
(1, 1, 0): 12; (1, 1, 1): 13;
(1, 2, 0): 14; (1, 2, 1): 15;
(1, 3, 0): 16; (1, 3, 1): 17;
(1, 4, 0): 18; (1, 4, 1): 19;

(2, 0, 0): 20; (2, 0, 1): 21;
(2, 1, 0): 22; (2, 1, 1): 23;
(2, 2, 0): 24; (2, 2, 1): 25;
(2, 3, 0): 26; (2, 3, 1): 27;
(2, 4, 0): 28; (2, 4, 1): 29;

or specify a region and a floating point format:

output.write("{:r'RGN_NOX':3.1e}", field);
(1, 0, 0): 1.0e+01; (1, 0, 1): 1.1e+01;
(1, 1, 0): 1.2e+01; (1, 1, 1): 1.3e+01;
(1, 2, 0): 1.4e+01; (1, 2, 1): 1.5e+01;
(1, 3, 0): 1.6e+01; (1, 3, 1): 1.7e+01;
(1, 4, 0): 1.8e+01; (1, 4, 1): 1.9e+01;

Works on Field2D, Field3D, and FieldPerp. For the sake of an easy implementation, z points are always on a single line, then blocks of y, so a Field2D looks like:

(0, 0): 0;
(0, 1): 1;
(0, 2): 2;
(0, 3): 3;
(0, 4): 4;

(1, 0): 5;
(1, 1): 6;
(1, 2): 7;
(1, 3): 8;
(1, 4): 9;

(2, 0): 10;
(2, 1): 11;
(2, 2): 12;
(2, 3): 13;
(2, 4): 14;

and a FieldPerp:

(0, 0): 0; (0, 1): 1;

(1, 0): 10; (1, 1): 11;

(2, 0): 20; (2, 1): 21;

I need to write some docs, but are there any other options that would be useful?

@dschwoerer
Copy link
Contributor

It might be nice to not dump the whole field, if you have a large one, but do it like numpy, where it only prints the first and last 3 row in each dimension, although 4 is probably better, if there are 2 guard cells, and have an option to change it to dump everything?

@ZedThree
Copy link
Member Author

Good idea. Numpy has two related options:

threshold
Total number of array elements which trigger summarization rather than full repr (default 1000). To always use the full repr without summarization, pass sys.maxsize.

edgeitems
Number of array items in summary at beginning and end of each dimension (default 3).

So we could have something like:

  • eN to set number of elements show at beginning and end of each dimension, default to 4

and then perhaps one or both of these:

  • tN to set threshold size, below which we just show the whole array?
  • f to show full array

@mikekryjak
Copy link
Contributor

Thanks @ZedThree! I don't have suggestions beyond echoing David's idea. I assume the three numbers in brackets are X, Y and Z in that order? So when you say "Z points being on a single line", you mean that the Z axis is incremented in the horizontal direction in the console?

I would personally find it more useful to have Y increment on the vertical and X on the horizontal, and then have different blocks for Z increments. This would then mirror the physical layout of the coordinates in a tokamak. This would also make an XY Field2D show a grid of points instead of a single column. It would make it more interpretable when looking at Y boundaries which is a common use case.

@cmacmackin
Copy link
Collaborator

This looks super useful. I think it might be helpful to add an option not to print the indices, though. Sometimes they aren't needed and just make the output look cluttered.

@ZedThree
Copy link
Member Author

ZedThree commented Feb 25, 2026

Thanks @ZedThree! I don't have suggestions beyond echoing David's idea. I assume the three numbers in brackets are X, Y and Z in that order? So when you say "Z points being on a single line", you mean that the Z axis is incremented in the horizontal direction in the console?

Yes, exactly

I would personally find it more useful to have Y increment on the vertical and X on the horizontal, and then have different blocks for Z increments. This would then mirror the physical layout of the coordinates in a tokamak. This would also make an XY Field2D show a grid of points instead of a single column. It would make it more interpretable when looking at Y boundaries which is a common use case.

Hmm, this might be tricky, but I think I have a way to do this.

This looks super useful. I think it might be helpful to add an option not to print the indices, though. Sometimes they aren't needed and just make the output look cluttered.

Yup, that's easy enough.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@ZedThree
Copy link
Member Author

Still needs docs, but briefly:

You must include bout/output_bout_types.hxx header to use this, or you'll get a compile time error.

Format specification:

  • n: Don't show indices
  • r'<region name>': Use given region (default: RGN_ALL)
  • T: Transpose field so X is first dimension (default is still Z first)
  • #: Plot slices as 2D heatmap
  • e<N>: Number of elements at each edge to show
  • f: Show full field

Most of these can be combined:

// Show the whole interior of the field, transposed so blocks are (X, Y)
output.write("{:fTr'RGN_NOBNDRY'}", field);

Floating point spec must follow another ::

// Same as before, but with floating point spec
output.write("{:fTr'RGN_NOBNDRY':5.3e}", field);

// Just floating point spec
output.write("{::5.3e}", field);

Use {:#} or {:#T} for stupid inline plotting in your terminal:

image

@mikekryjak
Copy link
Contributor

Unbelievable. Thanks @ZedThree!!!

@dschwoerer
Copy link
Contributor

#: Plot slices as 2D heatmap

Will this plot x-z slices? and the number can specify which y-slice? That sounds very cool!

@ZedThree
Copy link
Member Author

Will this plot x-z slices? and the number can specify which y-slice? That sounds very cool!

I've not added that, but you should be able to do that with:

output.write("{:#T}", sliceXZ(field, y));

I did consider adding general slicing to this, but I've already spent way too long on it!

@mikekryjak
Copy link
Contributor

@ZedThree I agree that we should merge it in. SliceXZ is very interesting, I've never heard of it. Are there any other useful Field3D helper features like that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants