-
Notifications
You must be signed in to change notification settings - Fork 106
WIP: Petsc matrix operators for FCI #3330
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
Open
bendudson
wants to merge
21
commits into
next
Choose a base branch
from
petsc-operators
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
289ddf2
PetscOperators: FCI operators using PETSc
bendudson c73c29a
PetscOperators: Splitting out PetscMapping
bendudson 724572a
Mesh::get Arrays of int and BoutReal
bendudson af65816
PetscOperators: Implement operators from CSR input
bendudson 8a3af0c
PetscOperators: Operate on Field3Ds
bendudson 2b71259
PetscOperators: Add documentation and error checking
bendudson e8f562f
Array: Add static fromValues(initializer_list) method
bendudson 8ba9503
PetscOperators: mapping fixes and unit tests
bendudson 16e2768
PetscOperator: Add diagonal and transpose methods
bendudson 5182ac4
PetscOperators: map matrix rows in boundary if present
bendudson 1e7aabe
Merge branch 'next' into petsc-operators
bendudson 68428b3
PetscOperators: Add BOUT_HAS_PETSC guards
bendudson 2c45584
PetscMapping: Add localSize and globalSize
bendudson d859712
PetscOperator: Handle standard CSR and variations
bendudson 350eba5
PetscOperators: Fix unit tests
bendudson fb34b2a
PetscOperator: Use bout::petsc::UniqueVec and UniqueMat
bendudson 1c48e71
examples/fci-operators
bendudson d5e1218
PetscOperators::Parallel::Div_par_K_Grad_par
bendudson 9a44ff8
WIP: Sub-cell sampling
bendudson 3992b8c
fci-operators example: Don't include mesh file
bendudson d2f26bb
PetscOperators: Specify dV is Field3D
bendudson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| cmake_minimum_required(VERSION 3.13) | ||
|
|
||
| project(fci-operators LANGUAGES CXX) | ||
|
|
||
| if(NOT TARGET bout++::bout++) | ||
| find_package(bout++ REQUIRED) | ||
| endif() | ||
|
|
||
| bout_add_example( | ||
| fci-operators | ||
| SOURCES fci_operators_example.cxx | ||
| DATA_DIRS data | ||
| EXTRA_FILES rotating-ellipse.py makeplots.py | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| [mesh] | ||
| file = "rotating-ellipse-20x8x20.fci.nc" | ||
|
|
||
| [mesh:paralleltransform] | ||
| type = fci |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #include "bout/bout.hxx" | ||
| #include "bout/difops.hxx" | ||
| #include "bout/field.hxx" | ||
| #include "bout/field3d.hxx" | ||
| #include "bout/field_factory.hxx" | ||
| #include "bout/globals.hxx" | ||
| #include "bout/options.hxx" | ||
| #include "bout/petsc_operators.hxx" | ||
|
|
||
| int main(int argc, char** argv) { | ||
| BoutInitialise(argc, argv); | ||
|
|
||
| const PetscOperators ops(bout::globals::mesh); | ||
|
|
||
| // Parallel operators | ||
| const auto parallel = ops.getParallel(); | ||
|
|
||
| // Test field | ||
| Field3D f = FieldFactory::get()->create3D("sin(y) + cos(z)"); | ||
| bout::globals::mesh->communicate(f); | ||
| f.applyParallelBoundary("parallel_dirichlet_o2"); | ||
|
|
||
| Field3D f_neumann = FieldFactory::get()->create3D("sin(y) + cos(z)"); | ||
| bout::globals::mesh->communicate(f_neumann); | ||
| f_neumann.applyParallelBoundary("parallel_neumann_o1"); | ||
|
|
||
| Options dump; | ||
| dump["f"] = f; | ||
| dump["dV"] = parallel.dV; | ||
|
|
||
| dump["grad_par_op"] = parallel.Grad_par(f); | ||
| dump["grad_par_yud"] = Grad_par(f); | ||
|
|
||
| dump["div_par_op"] = parallel.Div_par(f); | ||
|
|
||
| auto* coords = bout::globals::mesh->getCoordinates(); | ||
| bout::globals::mesh->communicate(coords->Bxy); | ||
| coords->Bxy.applyParallelBoundary("parallel_neumann_o1"); | ||
| dump["div_par_yud"] = Div_par(f); | ||
|
|
||
| dump["div_par_grad_par_op"] = parallel.Div_par_Grad_par(f_neumann); | ||
| dump["div_par_grad_par_yud"] = Div_par_K_Grad_par(1.0, f_neumann); | ||
|
|
||
| bout::writeDefaultOutputFile(dump); | ||
|
|
||
| BoutFinalise(); | ||
| return 0; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| from boutdata import collect | ||
| import matplotlib.pyplot as plt | ||
| import numpy as np | ||
|
|
||
| path = "data" | ||
|
|
||
| grad_par_op = collect("grad_par_op", path=path) | ||
| grad_par_yud = collect("grad_par_yud", path=path) | ||
|
|
||
| div_par_op = collect("div_par_op", path=path) | ||
| div_par_yud = collect("div_par_yud", path=path) | ||
|
|
||
| dV = collect("dV", path=path) # Cell volume | ||
|
|
||
| # Integrate divergence | ||
| op_div_int = np.sum((dV * div_par_op)[2:-2, :, :]) | ||
| yud_div_int = np.sum((dV * div_par_yud)[2:-2, :, :]) | ||
|
|
||
| print(f"Div_par volume integral Op: {op_div_int} Yup/down: {yud_div_int}") | ||
|
|
||
| div_par_grad_par_op = collect("div_par_grad_par_op", path=path) | ||
| div_par_grad_par_yud = collect("div_par_grad_par_yud", path=path) | ||
|
|
||
| # Integrate divergence | ||
| op_div2_int = np.sum((dV * div_par_grad_par_op)[2:-2, :, :]) | ||
| yud_div2_int = np.sum((dV * div_par_grad_par_yud)[2:-2, :, :]) | ||
|
|
||
| print(f"Div_par_Grad_par volume integral Op: {op_div2_int} Yup/down: {yud_div2_int}") | ||
|
|
||
|
|
||
| def plot_comparison(a, alabel, b, blabel): | ||
| fig, axs = plt.subplots(1, 3, figsize=(10, 3)) | ||
| vmax = max([np.amax(a), np.amax(b)]) | ||
| vmin = min([np.amin(a), np.amin(b)]) | ||
|
|
||
| cs = axs[0].contourf(a, vmin=vmin, vmax=vmax) | ||
| fig.colorbar(cs, ax=axs[0]) | ||
| axs[0].set_title(alabel) | ||
|
|
||
| axs[1].contourf(b, vmin=vmin, vmax=vmax) | ||
| axs[1].set_title(blabel) | ||
|
|
||
| cs = axs[2].contourf(a - b) | ||
| axs[2].set_title("Difference") | ||
| fig.colorbar(cs, ax=axs[2]) | ||
|
|
||
| return fig | ||
|
|
||
|
|
||
| fig = plot_comparison( | ||
| grad_par_op[2:-2, 2, :], "Operator", grad_par_yud[2:-2, 2, :], "Yup/down" | ||
| ) | ||
| fig.suptitle("Parallel Gradient") | ||
| fig.tight_layout() | ||
| fig.savefig("gradient.pdf") | ||
| fig.savefig("gradient.png") | ||
|
|
||
| fig = plot_comparison( | ||
| div_par_op[2:-2, 2, :], | ||
| f"Operator [integral {op_div_int:.2e}]", | ||
| div_par_yud[2:-2, 2, :], | ||
| f"Yup/down [integral {yud_div_int:.2e}]", | ||
| ) | ||
| fig.suptitle("Parallel Divergence") | ||
| fig.tight_layout() | ||
| fig.savefig("divergence.pdf") | ||
| fig.savefig("divergence.png") | ||
|
|
||
| fig = plot_comparison( | ||
| div_par_grad_par_op[2:-2, 2, :], | ||
| f"Operator [integral {op_div2_int:.2e}]", | ||
| div_par_grad_par_yud[2:-2, 2, :], | ||
| f"Yup/down [integral {yud_div2_int:.2e}]", | ||
| ) | ||
| fig.suptitle("Parallel diffusion") | ||
| fig.tight_layout() | ||
| fig.savefig("diffusion.pdf") | ||
| fig.savefig("diffusion.png") | ||
|
|
||
|
|
||
| plt.show() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| #!/usr/bin/env python | ||
|
|
||
| # Create grids for a rotating ellipse stellarator, based on curvilinear grids | ||
|
|
||
| import numpy as np | ||
|
|
||
| import zoidberg | ||
|
|
||
| ############################################################################# | ||
| # Define the magnetic field | ||
|
|
||
| # Length in y after which the coils return to their starting (R,Z) locations | ||
| yperiod = 2.0 * np.pi / 5 | ||
|
|
||
| xcentre = 2.0 | ||
|
|
||
| magnetic_field = zoidberg.field.RotatingEllipse( | ||
| xcentre=xcentre, # Major radius of axis [m] | ||
| radius=0.8, # Minor radius of the coils [m] | ||
| I_coil=0.4, # Coil current | ||
| yperiod=yperiod, | ||
| Btor=1.0, # Toroidal magnetic field | ||
| ) | ||
|
|
||
| ############################################################################# | ||
| # Create the inner flux surface, starting at a point at phi=0 | ||
| # To do this we need to define the y locations of the poloidal points | ||
| # where we will construct grids | ||
|
|
||
| start_r = xcentre + 0.4 | ||
| start_z = 0.0 | ||
|
|
||
| nslices = 8 # Number of poloidal slices | ||
| ycoords = np.linspace(0, yperiod, nslices) | ||
| npoints = 20 # Points per poloidal slice | ||
|
|
||
| rzcoord, ycoords = zoidberg.fieldtracer.trace_poincare( | ||
| magnetic_field, start_r, start_z, yperiod, y_slices=ycoords, revs=npoints, nover=1 | ||
| ) | ||
|
|
||
| inner_lines = [] | ||
| for i in range(nslices): | ||
| r = rzcoord[:, i, 0, 0] | ||
| z = rzcoord[:, i, 0, 1] | ||
| line = zoidberg.rzline.line_from_points(r, z) | ||
| # Re-map the points so they're approximately uniform in distance along the surface | ||
| # Note that this results in some motion of the line | ||
| line = line.equallySpaced() | ||
| inner_lines.append(line) | ||
|
|
||
| # Now have a list of y coordinates (ycoords) and inner lines (inner_lines) | ||
|
|
||
| ############################################################################# | ||
| # Generate a fixed circle for the outer boundary | ||
|
|
||
| outer_line = zoidberg.rzline.circle(R0=xcentre, r=0.6) | ||
|
|
||
| ############################################################################# | ||
| # Now have inner and outer boundaries for each poloidal grid | ||
| # Generate a grid on each poloidal slice using the elliptic grid generator | ||
|
|
||
| nx = 20 | ||
| nz = 20 | ||
|
|
||
| pol_grids = [ | ||
| zoidberg.poloidal_grid.grid_elliptic(inner_line, outer_line, nx, nz) | ||
| for inner_line in inner_lines | ||
| ] | ||
|
|
||
| ############################################################################# | ||
| # Create a grid, then calculate forward and backward maps | ||
|
|
||
| grid = zoidberg.grid.Grid(pol_grids, ycoords, yperiod, yperiodic=True) | ||
|
|
||
| samples_per_dim = 5 # Sub-sampling in each cell | ||
|
|
||
| maps = zoidberg.make_maps(grid, magnetic_field, samples_per_dim=samples_per_dim) | ||
|
|
||
| ############################################################################# | ||
| # Interpolation weights | ||
|
|
||
| weight_vars = zoidberg.weights.calculate_parallel_map_operators(maps) | ||
| maps.update(weight_vars) | ||
| # Remove sub-sampled maps from output | ||
| for var in [ | ||
| "forward_xt_primes", | ||
| "forward_zt_primes", | ||
| "backward_xt_primes", | ||
| "backward_zt_primes", | ||
| "subcell_weights", | ||
| ]: | ||
| maps.pop(var, None) | ||
|
|
||
| ############################################################################# | ||
| # Write grid file | ||
|
|
||
| filename = f"rotating-ellipse-{nx}x{nslices}x{nz}-s{samples_per_dim}.fci.nc" | ||
|
|
||
| print(f"Writing to grid file '{filename}'") | ||
| zoidberg.write_maps( | ||
| grid, magnetic_field, maps, gridfile=filename, new_names=False, metric2d=False | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
warning: no header providing "bout::writeDefaultOutputFile" is directly included [misc-include-cleaner]
examples/fci-operators/fci_operators_example.cxx:7: