Skip to content
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

Coordinates: Replacing sqrt(g_22) with JB #3027

Draft
wants to merge 2 commits into
base: refactor-coordinates
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions include/bout/coordinates.hxx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
/**************************************************************************
* Describes coordinate systems
*
* ChangeLog
* =========
*
* 2014-11-10 Ben Dudson <[email protected]>
* * Created by separating metric from Mesh
*
*
**************************************************************************
* Copyright 2014 B.D.Dudson
* Copyright 2014 - 2024 BOUT++ contributors
*
* Contact: Ben Dudson, [email protected]
* Contact: Ben Dudson, [email protected]
*
* This file is part of BOUT++.
*
Expand Down Expand Up @@ -239,6 +233,8 @@ public:
FieldMetric& J() const;

///< Magnitude of B = nabla z times nabla x
///< Note: This should always be positive
///< for both right- and left-handed coordinates.
const FieldMetric& Bxy() const { return Bxy_; }

void setJ(const FieldMetric& J);
Expand Down Expand Up @@ -389,6 +385,19 @@ public:
const FieldMetric& Grad2_par2_DDY_invSg(CELL_LOC outloc,
const std::string& method) const;

/// Calculate 1 / (J |B|)
/// This is cached as it is used frequently in parallel operators.
///
/// In a Clebsch coordinate system
/// B = (1 / J) e_y
/// so the unit vector along the magnetic field is:
/// b = B / |B| = (1 / ( J |B| )) e_y
/// so e.g.
/// Grad_par = b dot Grad = (1 / J |B|) d / dy.
///
/// Note: In a right-handed Clebsch coordinate system
/// this is 1 / sqrt(g_22) i.e. positive.
/// In a left-handed coordinate system it is negative.
const FieldMetric& invSg() const;

ChristoffelSymbols& christoffel_symbols();
Expand Down Expand Up @@ -466,6 +475,8 @@ private:

FieldMetric getUnaligned(const std::string& name, BoutReal default_value);

/// Recalculate magnetic field magnitude Bxy = |B|
/// Note: Always positive
FieldMetric recalculateBxy() const;

/// Non-uniform meshes. Need to use DDX, DDY
Expand Down
6 changes: 4 additions & 2 deletions src/mesh/coordinates.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,8 @@ MetricTensor::FieldMetric Coordinates::recalculateJacobian() const {
}

MetricTensor::FieldMetric Coordinates::recalculateBxy() const {
return sqrt(g_22()) / J();
// Note: J may be negative, by return is always positive
return sqrt(g_22()) / abs(J());
}

void Coordinates::setParallelTransform(Options* mesh_options) {
Expand Down Expand Up @@ -1452,7 +1453,7 @@ GValues& Coordinates::g_values() const {
const Coordinates::FieldMetric& Coordinates::invSg() const {
if (invSgCache == nullptr) {
auto ptr = std::make_unique<FieldMetric>();
(*ptr) = 1.0 / sqrt(g_22());
(*ptr) = 1.0 / (J() * Bxy());
invSgCache = std::move(ptr);
}
return *invSgCache;
Expand Down Expand Up @@ -1502,6 +1503,7 @@ void Coordinates::setJ(const FieldMetric& J) {

void Coordinates::setBxy(FieldMetric Bxy) {
//TODO: Calculate Bxy and check value is close
// Also check that Bxy is positive
Bxy_ = std::move(Bxy);
localmesh->communicate(Bxy_);
}
Expand Down
28 changes: 15 additions & 13 deletions src/mesh/difops.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* Various differential operators defined on BOUT grid
*
**************************************************************************
* Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu
* Copyright 2010 - 2024 BOUT++ contributors
*
* Contact: Ben Dudson, [email protected]
* Contact: Ben Dudson, [email protected]
*
* This file is part of BOUT++.
*
Expand Down Expand Up @@ -104,7 +104,9 @@ Field3D Grad_parP(const Field3D& apar, const Field3D& f) {
for (int x = 1; x <= mesh->LocalNx - 2; x++) {
for (int y = mesh->ystart; y <= mesh->yend; y++) {
for (int z = 0; z < ncz; z++) {
BoutReal by = 1. / sqrt(metric->g_22(x, y, z));

// Note: by is negative in a left-handed coordinate system
BoutReal by = 1. / (metric->J(x, y, z) * metric->Bxy(x, y, z));
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
BoutReal by = 1. / (metric->J(x, y, z) * metric->Bxy(x, y, z));
BoutReal by = 1. / (metric->J(x, y, z) * metric->Bxy()(x, y, z));

// Z indices zm and zp
int const zm = (z - 1 + ncz) % ncz;
int const zp = (z + 1) % ncz;
Expand Down Expand Up @@ -258,14 +260,13 @@ Field3D Div_par(const Field3D& f, const Field3D& v) {
BoutReal const vR = 0.5 * (v(i, j, k) + v.yup()(i, j + 1, k));

// Calculate flux at right boundary (y+1/2)
// Note: Magnitude of B at the midpoint used rather than J/sqrt(g_22)
BoutReal const fluxRight =
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
fR * vR * (coord->J(i, j, k) + coord->J(i, j + 1, k))
/ (sqrt(coord->g_22(i, j, k)) + sqrt(coord->g_22(i, j + 1, k)));
fR * vR * 2 / (coord->Bxy(i, j, k) + coord->Bxy(i, j + 1, k));
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fR * vR * 2 / (coord->Bxy(i, j, k) + coord->Bxy(i, j + 1, k));
fR * vR * 2 / (coord->Bxy()(i, j, k) + coord->Bxy()(i, j + 1, k));


// Calculate at left boundary (y-1/2)
BoutReal const fluxLeft =
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
fL * vL * (coord->J(i, j, k) + coord->J(i, j - 1, k))
/ (sqrt(coord->g_22(i, j, k)) + sqrt(coord->g_22(i, j - 1, k)));
fL * vL * 2 / (coord->Bxy(i, j, k) + coord->Bxy(i, j - 1, k));
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
ZedThree marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fL * vL * 2 / (coord->Bxy(i, j, k) + coord->Bxy(i, j - 1, k));
fL * vL * 2 / (coord->Bxy()(i, j, k) + coord->Bxy()(i, j - 1, k));


result(i, j, k) =
(fluxRight - fluxLeft) / (coord->dy(i, j, k) * coord->J(i, j, k));
Expand All @@ -285,7 +286,7 @@ Field3D Div_par_flux(const Field3D& v, const Field3D& f, CELL_LOC outloc,
auto Bxy_floc = f.getCoordinates()->Bxy();

if (!f.hasParallelSlices()) {
return metric->Bxy() * FDDY(v, f / Bxy_floc, outloc, method) / sqrt(metric->g_22());
return FDDY(v, f / Bxy_floc, outloc, method) / metric->J();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it really be Bxy_floc? I thought this term comes from the curvi-linear geometry, and thus should be independent of B (for non clebsch)

}

// Need to modify yup and ydown fields
Expand All @@ -294,7 +295,7 @@ Field3D Div_par_flux(const Field3D& v, const Field3D& f, CELL_LOC outloc,
f_B.splitParallelSlices();
f_B.yup() = f.yup() / Bxy_floc;
f_B.ydown() = f.ydown() / Bxy_floc;
return metric->Bxy() * FDDY(v, f_B, outloc, method) / sqrt(metric->g_22());
return FDDY(v, f_B, outloc, method) / metric->J();
Comment on lines 296 to +298
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

}

Field3D Div_par_flux(const Field3D& v, const Field3D& f, const std::string& method,
Expand Down Expand Up @@ -478,7 +479,8 @@ Coordinates::FieldMetric b0xGrad_dot_Grad(const Field2D& phi, const Field2D& A,

// Upwind A using these velocities
Coordinates::FieldMetric result = VDDX(vx, A, outloc) + VDDY(vy, A, outloc);
result /= metric->J() * sqrt(metric->g_22());
result /= SQ(metric->J())
* metric->Bxy(); // J^2 B same sign for left & right handed coordinates
Comment on lines +482 to +483
Copy link
Contributor

Choose a reason for hiding this comment

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

move comment above to avoid strange formatting?


ASSERT1(result.getLocation() == outloc);

Expand Down Expand Up @@ -519,7 +521,7 @@ Field3D b0xGrad_dot_Grad(const Field2D& phi, const Field3D& A, CELL_LOC outloc)

Field3D result = VDDX(vx, A, outloc) + VDDY(vy, A, outloc) + VDDZ(vz, A, outloc);

result /= (metric->J() * sqrt(metric->g_22()));
result /= SQ(metric->J()) * metric->Bxy(); // J^2 B

#if BOUT_USE_TRACK
result.name = "b0xGrad_dot_Grad(" + phi.name + "," + A.name + ")";
Expand Down Expand Up @@ -554,7 +556,7 @@ Field3D b0xGrad_dot_Grad(const Field3D& p, const Field2D& A, CELL_LOC outloc) {

Field3D result = VDDX(vx, A, outloc) + VDDY(vy, A, outloc);

result /= (metric->J() * sqrt(metric->g_22()));
result /= SQ(metric->J()) * metric->Bxy(); // J^2 B

#if BOUT_USE_TRACK
result.name = "b0xGrad_dot_Grad(" + p.name + "," + A.name + ")";
Expand Down Expand Up @@ -595,7 +597,7 @@ Field3D b0xGrad_dot_Grad(const Field3D& phi, const Field3D& A, CELL_LOC outloc)

Field3D result = VDDX(vx, A, outloc) + VDDY(vy, A, outloc) + VDDZ(vz, A, outloc);

result /= (metric->J() * sqrt(metric->g_22()));
result /= SQ(metric->J()) * metric->Bxy(); // J^2 B
Copy link
Contributor

Choose a reason for hiding this comment

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

Is that not only true for Clebsch?


#if BOUT_USE_TRACK
result.name = "b0xGrad_dot_Grad(" + phi.name + "," + A.name + ")";
Expand Down