From 240bf4f69511a2b6242d23321686f32498afa255 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Thu, 10 Oct 2024 11:48:16 +0100 Subject: [PATCH 01/98] Extract function tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy) to new file examples/common.hxx --- CMakeLists.txt | 1 + examples/6field-simple/elm_6f.cxx | 22 ++---------- examples/common.hxx | 36 +++++++++++++++++++ examples/conducting-wall-mode/cwm.cxx | 21 ++--------- examples/dalf3/dalf3.cxx | 24 ++----------- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 24 ++----------- examples/laplacexy/alfven-wave/alfven.cxx | 20 ++--------- examples/wave-slab/wave_slab.cxx | 20 ++--------- 8 files changed, 49 insertions(+), 119 deletions(-) create mode 100644 examples/common.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bad0fa2d1..54b04964ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,6 +360,7 @@ set(BOUT_SOURCES ./src/mesh/g_values.cxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx + examples/common.hxx ) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index a38a1420e2..12c780d3ea 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -6,7 +6,7 @@ * T. Xia *******************************************************************************/ -#include "bout/bout.hxx" +#include "../common.hxx" #include "bout/constants.hxx" #include "bout/derivs.hxx" #include "bout/initialprofiles.hxx" @@ -1051,25 +1051,7 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(B0 * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); - coord->setBxy(B0); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/examples/common.hxx b/examples/common.hxx new file mode 100644 index 0000000000..faec23bc60 --- /dev/null +++ b/examples/common.hxx @@ -0,0 +1,36 @@ + +#ifndef BOUT_COMMON_HXX +#define BOUT_COMMON_HXX + +#include "bout/bout.hxx" + +inline Coordinates* tokamak_coordinates(Coordinates* coord, const FieldMetric& Rxy, + const FieldMetric& Bpxy, const FieldMetric& hthe, + const FieldMetric& I, const FieldMetric& B, + const FieldMetric& Btxy) { + + const auto g11 = SQ(Rxy * Bpxy); + const auto g22 = 1.0 / SQ(hthe); + const auto g33 = SQ(I) * g11 + SQ(B) / g11; + const auto g12 = 0.0; + const auto g13 = -I * g11; + const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); + + const auto g_11 = 1.0 / g11 + SQ(I * Rxy); + const auto g_22 = SQ(B * hthe / Bpxy); + const auto g_33 = Rxy * Rxy; + const auto g_12 = sbp * Btxy * hthe * I * Rxy / Bpxy; + const auto g_13 = I * Rxy * Rxy; + const auto g_23 = Btxy * hthe * Rxy / Bpxy; + + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + + coord->setJ(hthe / Bpxy); + coord->setBxy(B); + + return coord; +} + + +#endif //BOUT_COMMON_HXX diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 6442e37857..8fb8c6edf1 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -4,6 +4,7 @@ * Mode discoverd by H.L. Berk et. al. 1993 * Model version in the code created by M. Umansky and J. Myra. *******************************************************************************/ +#include "../common.hxx" #include #include @@ -146,26 +147,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - /**************** CALCULATE METRICS ******************/ + tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, coord->Bxy(), Btxy); - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(coord->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(coord->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); /**************** SET EVOLVING VARIABLES *************/ diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 7f73ed56d7..47bda3f2e5 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -18,6 +18,7 @@ * ****************************************************************/ +#include "../common.hxx" #include #include @@ -245,28 +246,7 @@ class DALF3 : public PhysicsModel { coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); - /////////////////////////////////////////////////// - // CALCULATE METRICS - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(B0 * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); - coord->setBxy(B0); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 747d1f8f6e..065456d66c 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -28,7 +28,7 @@ /*******************************************************************************/ -#include +#include "../common.hxx" #include #include #include @@ -1090,27 +1090,7 @@ class ELMpb : public PhysicsModel { rmp_Psi = 0.0; } - /**************** CALCULATE METRICS ******************/ - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(B0 * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - metric->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - metric->setJ(hthe / Bpxy); - metric->setBxy(B0); + tokamak_coordinates(metric, Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index a4894e2cb5..18c1154668 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -1,4 +1,5 @@ +#include "../common.hxx" #include #include #include @@ -202,24 +203,7 @@ class Alfven : public PhysicsModel { sbp = -1.0; } - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(sinty) * g11 + SQ(coord->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -sinty * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(sinty * Rxy); - const auto g_22 = SQ(coord->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * sinty * Rxy / Bpxy; - const auto g_13 = sinty * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, sinty, coord->Bxy(), Btxy, sbp); } }; diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 0bf4f1a9e7..68031dce38 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -10,6 +10,7 @@ */ +#include "../common.hxx" #include class WaveTest : public PhysicsModel { @@ -31,24 +32,7 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto g11 = pow(Rxy * Bpxy, 2.0); - const auto g22 = 1.0 / pow(hthe, 2.0); - const auto g33 = pow(I, 2.0) * g11 + pow(coords->Bxy(), 2.0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + (pow(I * Rxy, 2.0)); - const auto g_22 = pow(coords->Bxy() * hthe / Bpxy, 2.0); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coords->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coords->setJ(hthe / Bpxy); + tokamak_coordinates(coords, Rxy, Bpxy, hthe, I, coords->Bxy(), Btxy); solver->add(f, "f"); solver->add(g, "g"); From ef81a05675a92fa6544824ee638c0587dffc6cd6 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Thu, 10 Oct 2024 13:09:58 +0100 Subject: [PATCH 02/98] Use function in more examples elm-pb laplacexy/laplace_perp gyro-gem example (using zero for I parameter) alfven-wave example (using sinty for I parameter) --- examples/constraints/alfven-wave/alfven.cxx | 23 ++------------------ examples/elm-pb/elm_pb.cxx | 24 ++------------------- examples/gyro-gem/gem.cxx | 24 ++------------------- examples/laplacexy/laplace_perp/test.cxx | 23 ++------------------ 4 files changed, 8 insertions(+), 86 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 2c12c9a568..fd63099483 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -2,7 +2,7 @@ #include #include #include -#include +#include "../../common.hxx" /// Fundamental constants const BoutReal PI = 3.14159265; @@ -199,26 +199,7 @@ class Alfven : public PhysicsModel { sbp = -1.0; } - // Calculate metric components - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(sinty) * g11 + SQ(coord->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -sinty * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(sinty * Rxy); - const auto g_22 = SQ(coord->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * sinty * Rxy / Bpxy; - const auto g_13 = sinty * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, sinty, coord->Bxy(), Btxy, sbp); } }; diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 675970b3a8..78d514ef36 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -5,7 +5,7 @@ * Can also include the Vpar compressional term *******************************************************************************/ -#include +#include "../common.hxx" #include #include #include @@ -1031,27 +1031,7 @@ class ELMpb : public PhysicsModel { rmp_Psi = 0.0; } - /**************** CALCULATE METRICS ******************/ - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(B0 * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - metric->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - metric->setJ(hthe / Bpxy); - metric->setBxy(B0); + tokamak_coordinates(metric, Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index cad585beb4..0d716cd486 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -10,7 +10,7 @@ ****************************************************************/ #include -#include +#include "../common.hxx" #include #include @@ -367,27 +367,7 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); - // Metric components - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(Bxy) / g11; - const auto g12 = 0.0; - const auto g13 = 0.; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11; - const auto g_22 = SQ(Bxy * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = 0.; - const auto g_13 = 0.; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); - coord->setBxy(Bxy); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); // Set B field vector diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 7b98f85ef5..78a99ce526 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -1,4 +1,4 @@ -#include +#include "../../common.hxx" #include #include @@ -24,26 +24,7 @@ int main(int argc, char** argv) { Coordinates* coord = mesh->getCoordinates(); - // Calculate metrics - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(B0 * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); - coord->setBxy(B0); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// From 53d4f98a569feb332f6f3dd68ad0d9aceed55010 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 11 Oct 2024 12:16:23 +0100 Subject: [PATCH 03/98] Move and rename "examples/common.hxx" to "include/bout/tokamak_coordinates.hxx" --- CMakeLists.txt | 2 +- examples/6field-simple/elm_6f.cxx | 2 +- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/dalf3/dalf3.cxx | 2 +- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 1 + examples/elm-pb/elm_pb.cxx | 2 +- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 2 +- .../common.hxx => include/bout/tokamak_coordinates.hxx | 8 ++++---- 12 files changed, 15 insertions(+), 14 deletions(-) rename examples/common.hxx => include/bout/tokamak_coordinates.hxx (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54b04964ca..cf0bedf020 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,7 +360,7 @@ set(BOUT_SOURCES ./src/mesh/g_values.cxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx - examples/common.hxx + include/bout/tokamak_coordinates.hxx ) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 12c780d3ea..c92ac95adf 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -6,7 +6,7 @@ * T. Xia *******************************************************************************/ -#include "../common.hxx" +#include "bout/tokamak_coordinates.hxx" #include "bout/constants.hxx" #include "bout/derivs.hxx" #include "bout/initialprofiles.hxx" diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 8fb8c6edf1..2924577e96 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -4,7 +4,7 @@ * Mode discoverd by H.L. Berk et. al. 1993 * Model version in the code created by M. Umansky and J. Myra. *******************************************************************************/ -#include "../common.hxx" +#include #include #include diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index fd63099483..d3de008f80 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -1,8 +1,8 @@ +#include #include #include #include -#include "../../common.hxx" /// Fundamental constants const BoutReal PI = 3.14159265; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 47bda3f2e5..63b605aa53 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -18,7 +18,7 @@ * ****************************************************************/ -#include "../common.hxx" +#include #include #include diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 065456d66c..e105dc6fe9 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -42,6 +42,7 @@ #include +#include #include #include #include diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 78d514ef36..4ee09be3ab 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -5,7 +5,7 @@ * Can also include the Vpar compressional term *******************************************************************************/ -#include "../common.hxx" +#include #include #include #include diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 0d716cd486..bbc53e3fe2 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -9,8 +9,8 @@ * This version uses global parameters for collisionality etc. ****************************************************************/ +#include #include -#include "../common.hxx" #include #include diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 18c1154668..c4d488946d 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -1,5 +1,5 @@ -#include "../common.hxx" +#include #include #include #include diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 78a99ce526..169eadd51f 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -1,4 +1,4 @@ -#include "../../common.hxx" +#include #include #include diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 68031dce38..0bed1de0f3 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -10,7 +10,7 @@ */ -#include "../common.hxx" +#include #include class WaveTest : public PhysicsModel { diff --git a/examples/common.hxx b/include/bout/tokamak_coordinates.hxx similarity index 88% rename from examples/common.hxx rename to include/bout/tokamak_coordinates.hxx index faec23bc60..e145da4df2 100644 --- a/examples/common.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -1,8 +1,8 @@ -#ifndef BOUT_COMMON_HXX -#define BOUT_COMMON_HXX +#ifndef BOUT_TOKAMAK_COORDINATES_HXX +#define BOUT_TOKAMAK_COORDINATES_HXX -#include "bout/bout.hxx" +#include "bout.hxx" inline Coordinates* tokamak_coordinates(Coordinates* coord, const FieldMetric& Rxy, const FieldMetric& Bpxy, const FieldMetric& hthe, @@ -33,4 +33,4 @@ inline Coordinates* tokamak_coordinates(Coordinates* coord, const FieldMetric& R } -#endif //BOUT_COMMON_HXX +#endif //BOUT_TOKAMAK_COORDINATES_HXX From f5f93debc46f3fd78b9b0a55e5138156f35defbd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 11 Oct 2024 13:52:56 +0100 Subject: [PATCH 04/98] Use function `tokamak_coordinates` in tests --- tests/MMS/GBS/gbs.cxx | 20 ++------------- tests/MMS/elm-pb/elm_pb.cxx | 24 ++---------------- tests/MMS/tokamak/tokamak.cxx | 20 ++------------- .../test-drift-instability/2fluid.cxx | 23 ++--------------- .../test-interchange-instability/2fluid.cxx | 23 ++--------------- .../integrated/test-laplacexy/loadmetric.cxx | 25 ++----------------- 6 files changed, 12 insertions(+), 123 deletions(-) diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 9fed76c119..b3a863b10c 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -17,6 +17,7 @@ #include #include #include +#include int GBS::init(bool restarting) { Options* opt = Options::getRoot(); @@ -348,24 +349,7 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(sinty) * g11 + SQ(coords->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -sinty * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(sinty * Rxy); - const auto g_22 = SQ(coords->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * sinty * Rxy / Bpxy; - const auto g_13 = sinty * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; - - coords->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coords->setJ(hthe / Bpxy); + tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 851b2d2a69..3f5a5e1341 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -9,7 +9,7 @@ * *******************************************************************************/ -#include +#include #include #include #include @@ -415,27 +415,7 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - /**************** CALCULATE METRICS ******************/ - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B0) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + (SQ(I * Rxy)); - const auto g_22 = SQ(B0 * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coords->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coords->setJ(hthe / Bpxy); - coords->setBxy(B0); + tokamak_coordinates(coords, Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 74c89bb95d..9e1f03123b 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -8,6 +8,7 @@ #include #include +#include #include class TokamakMMS : public PhysicsModel { @@ -80,24 +81,7 @@ class TokamakMMS : public PhysicsModel { sbp = -1.0; } - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(sinty) * g11 + SQ(coords->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -sinty * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(sinty * Rxy); - const auto g_22 = SQ(coords->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * sinty * Rxy / Bpxy; - const auto g_13 = sinty * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; - - coords->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coords->setJ(hthe / Bpxy); + tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index f7b072cae5..58ad311417 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -3,7 +3,7 @@ * Same as Maxim's version of BOUT - simplified 2-fluid for benchmarking *******************************************************************************/ -#include +#include #include #include @@ -215,26 +215,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - /**************** CALCULATE METRICS ******************/ - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(coord->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(coord->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, coord->Bxy(), Btxy); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index cddc81e91c..f785d1f9d9 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -3,7 +3,7 @@ * Same as Maxim's version of BOUT - simplified 2-fluid for benchmarking *******************************************************************************/ -#include +#include #include #include @@ -137,26 +137,7 @@ class Interchange : public PhysicsModel { Btxy /= (bmag / 1.e4); coord->setBxy(coord->Bxy() / (bmag / 1.e4)); - /**************** CALCULATE METRICS ******************/ - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(coord->Bxy()) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(coord->Bxy() * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); + tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, coord->Bxy(), Btxy); // Tell BOUT++ which variables to evolve SOLVE_FOR2(rho, Ni); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 3fccd4acce..9cb1a28a42 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -1,8 +1,4 @@ -#include "bout/field2d.hxx" -#include "bout/globals.hxx" -#include "bout/mesh.hxx" -#include "bout/output.hxx" -#include "bout/utils.hxx" +#include #include "loadmetric.hxx" @@ -49,22 +45,5 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto g11 = pow(Rxy * Bpxy, 2); - const auto g22 = 1.0 / pow(hthe, 2); - const auto g33 = pow(sinty, 2) * g11 + pow(coords->Bxy(), 2) / g11; - const auto g12 = 0.0; - const auto g13 = -sinty * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + pow(sinty * Rxy, 2); - const auto g_22 = pow(coords->Bxy() * hthe / Bpxy, 2); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * sinty * Rxy / Bpxy; - const auto g_13 = sinty * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; - - coords->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coords->setJ(hthe / Bpxy); + tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } From a5dab54f2dc4587a0a9b57840979b27a9017b9d8 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 15 Oct 2024 12:14:17 +0100 Subject: [PATCH 05/98] Make function `tokamak_coordinates` provide the Coordinates object (rather than passing one to it for it to modify). --- examples/6field-simple/elm_6f.cxx | 39 +++++++------- examples/conducting-wall-mode/cwm.cxx | 18 +++++-- examples/constraints/alfven-wave/alfven.cxx | 31 ++++++----- examples/dalf3/dalf3.cxx | 6 +-- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 52 +++++++++---------- examples/elm-pb/elm_pb.cxx | 6 +-- examples/gyro-gem/gem.cxx | 7 ++- examples/laplacexy/alfven-wave/alfven.cxx | 30 +++++------ examples/laplacexy/laplace_perp/test.cxx | 4 +- examples/wave-slab/wave_slab.cxx | 5 +- include/bout/tokamak_coordinates.hxx | 10 ++-- .../test-drift-instability/2fluid.cxx | 14 ++--- .../test-interchange-instability/2fluid.cxx | 14 ++--- 13 files changed, 118 insertions(+), 118 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index c92ac95adf..570bdfc610 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -378,9 +378,6 @@ class Elm_6f : public PhysicsModel { int init(bool restarting) override { bool noshear; - // Get the metric tensor - Coordinates* coord = mesh->getCoordinates(); - output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); @@ -700,21 +697,6 @@ class Elm_6f : public PhysicsModel { I = 0.0; } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(I); - - } else { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += I * b0xcv.x; - } - I = 0.0; // I disappears from metric - } - ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -867,7 +849,7 @@ class Elm_6f : public PhysicsModel { Btxy /= Bbar; B0 /= Bbar; hthe /= Lbar; - coord->setDx(coord->dx() / (Lbar * Lbar * Bbar)); + Field2D dx; I *= Lbar * Lbar * Bbar; if ((!T0_fake_prof) && n0_fake_prof) { @@ -1051,7 +1033,24 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + coord->setDx(dx / (Lbar * Lbar * Bbar)); + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + coord->setIntShiftTorsion(I); + + } else { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += I * b0xcv.x; + } + I = 0.0; // I disappears from metric + } + // Set B field vector diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 2924577e96..28a52ee6a8 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -65,8 +65,12 @@ class CWM : public PhysicsModel { coord = mesh->getCoordinates(); // Load metrics - GRID_LOAD(Rxy, Zxy, Bpxy, Btxy, hthe); - coord->setDx(mesh->get("dpsi")); + mesh->get(Rxy, "Rxy"); + mesh->get(Zxy, "Zxy"); + mesh->get(Bpxy, "Bpxy"); + mesh->get(Btxy, "Btxy"); + mesh->get(hthe, "hthe"); + Field2D dx = mesh->get("dpsi"); mesh->get(I, "sinty"); // Load normalisation values @@ -137,17 +141,21 @@ class CWM : public PhysicsModel { Rxy /= rho_s; hthe /= rho_s; I *= rho_s * rho_s * (bmag / 1e4) * ShearFactor; - coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); + + dx /= (rho_s * rho_s * (bmag / 1e4)); // Normalise magnetic field Bpxy /= (bmag / 1.e4); Btxy /= (bmag / 1.e4); - coord->setBxy(coord->Bxy() / (bmag / 1.e4)); + + Field2D Bxy = mesh->get("Bxy"); + Bxy /= (bmag / 1.e4); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, coord->Bxy(), Btxy); + coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord->setDx(dx); /**************** SET EVOLVING VARIABLES *************/ diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index d3de008f80..d6f1124695 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -163,27 +163,12 @@ class Alfven : public PhysicsModel { Field2D Rxy, Bpxy, Btxy, hthe, sinty; GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics - // Get the coordinates object - Coordinates* coord = mesh->getCoordinates(); - - // Checking for dpsi and qinty used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coord->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } - Rxy /= Lnorm; hthe /= Lnorm; sinty *= SQ(Lnorm) * Bnorm; - coord->setDx(coord->dx() / (SQ(Lnorm) * Bnorm)); Bpxy /= Bnorm; Btxy /= Bnorm; - coord->setBxy(coord->Bxy() / Bnorm); // Check type of parallel transform std::string ptstr = @@ -199,7 +184,21 @@ class Alfven : public PhysicsModel { sbp = -1.0; } - tokamak_coordinates(coord, Rxy, Bpxy, hthe, sinty, coord->Bxy(), Btxy, sbp); + Field2D Bxy = mesh->get("Bxy"); + Bxy /= Bnorm; + + auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + + // Checking for dpsi and qinty used in BOUT grids + Field2D dx; + if (!mesh->get(dx, "dpsi")) { + output << "\tUsing dpsi as the x grid spacing\n"; + coord->setDx(dx); // Only use dpsi if found + } else { + // dx will have been read already from the grid + output << "\tUsing dx as the x grid spacing\n"; + } + coord->setDx(dx / (SQ(Lnorm) * Bnorm)); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 63b605aa53..e0802fe5a0 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -167,8 +167,6 @@ class DALF3 : public PhysicsModel { return 1; } - Coordinates* coord = mesh->getCoordinates(); - // SHIFTED RADIAL COORDINATES // Check type of parallel transform @@ -244,9 +242,9 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); + auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); - tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy); + coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index e105dc6fe9..8f26c81b6e 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -28,7 +28,6 @@ /*******************************************************************************/ -#include "../common.hxx" #include #include #include @@ -42,12 +41,12 @@ #include -#include #include #include #include #include #include +#include #include // Defines BOUT_FOR_RAJA @@ -360,7 +359,6 @@ class ELMpb : public PhysicsModel { // Note: The rhs() function needs to be public so that RAJA can use CUDA int init(bool restarting) override { - Coordinates* metric = mesh->getCoordinates(); output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); @@ -821,21 +819,6 @@ class ELMpb : public PhysicsModel { I = 0.0; } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(I); - - } else { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += I * b0xcv.x; - } - I = 0.0; // I disappears from metric - } - ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -963,7 +946,7 @@ class ELMpb : public PhysicsModel { Btxy /= Bbar; B0 /= Bbar; hthe /= Lbar; - metric->setDx(metric->dx() / (Lbar * Lbar * Bbar)); + I *= Lbar * Lbar * Bbar; if (constn0) { @@ -1091,8 +1074,6 @@ class ELMpb : public PhysicsModel { rmp_Psi = 0.0; } - tokamak_coordinates(metric, Rxy, Bpxy, hthe, I, B0, Btxy); - // Set B field vector B0vec.covariant = false; @@ -1230,6 +1211,25 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); + auto* metric = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + metric->setIntShiftTorsion(I); + + } else { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += I * b0xcv.x; + } + I = 0.0; // I disappears from metric + } + + metric->setDx(metric->dx() / (Lbar * Lbar * Bbar)); + return 0; } @@ -1662,12 +1662,12 @@ class ELMpb : public PhysicsModel { #endif }; - // Terms which are not yet single index operators - // Note: Terms which are included in the single index loop - // may be commented out here, to allow comparison/testing + // Terms which are not yet single index operators + // Note: Terms which are included in the single index loop + // may be commented out here, to allow comparison/testing - //////////////////////////////////////////////////// - // Parallel electric field + //////////////////////////////////////////////////// + // Parallel electric field #if not EVOLVE_JPAR // Vector potential diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 4ee09be3ab..3bbb556762 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -301,8 +301,6 @@ class ELMpb : public PhysicsModel { int init(bool restarting) override { bool noshear; - Coordinates* metric = mesh->getCoordinates(); - output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); @@ -333,6 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux + auto* metric = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely // implemented. Parallel boundary conditions are especially likely to be wrong. @@ -1031,8 +1031,6 @@ class ELMpb : public PhysicsModel { rmp_Psi = 0.0; } - tokamak_coordinates(metric, Rxy, Bpxy, hthe, I, B0, Btxy); - // Set B field vector B0vec.covariant = false; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index bbc53e3fe2..c11ff36899 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -355,8 +355,6 @@ class GEM : public PhysicsModel { ////////////////////////////////// // Metric tensor components - coord = mesh->getCoordinates(); - // Normalise hthe /= Lbar; // parallel derivatives normalised to Lperp @@ -365,9 +363,10 @@ class GEM : public PhysicsModel { Bxy /= Bbar; Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); - tokamak_coordinates(coord, Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); + coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); + + coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); // Set B field vector diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index c4d488946d..a17023be6b 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -174,26 +174,12 @@ class Alfven : public PhysicsModel { Field2D Rxy, Bpxy, Btxy, hthe, sinty; GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics - Coordinates* coord = mesh->getCoordinates(); // Metric tensor - - // Checking for dpsi and qinty used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coord->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } - Rxy /= Lnorm; hthe /= Lnorm; sinty *= SQ(Lnorm) * Bnorm; - coord->setDx(coord->dx() / (SQ(Lnorm) * Bnorm)); Bpxy /= Bnorm; Btxy /= Bnorm; - coord->setBxy(coord->Bxy() / Bnorm); // Calculate metric components sinty = 0.0; // I disappears from metric for shifted coordinates @@ -203,7 +189,21 @@ class Alfven : public PhysicsModel { sbp = -1.0; } - tokamak_coordinates(coord, Rxy, Bpxy, hthe, sinty, coord->Bxy(), Btxy, sbp); + Field2D Bxy = mesh->get("Bxy"); + Bxy /= Bnorm; + + auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + + // Checking for dpsi and qinty used in BOUT grids + Field2D dx; + if (!mesh->get(dx, "dpsi")) { + output << "\tUsing dpsi as the x grid spacing\n"; + coord->setDx(dx); // Only use dpsi if found + } else { + // dx will have been read already from the grid + output << "\tUsing dx as the x grid spacing\n"; + } + coord->setDx(dx / (SQ(Lnorm) * Bnorm)); } }; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 169eadd51f..672f473ff3 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,9 +22,7 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - Coordinates* coord = mesh->getCoordinates(); - - tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, B0, Btxy); + tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 0bed1de0f3..89ac381244 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -16,13 +16,12 @@ class WaveTest : public PhysicsModel { public: int init(bool UNUSED(restarting)) { - auto* coords = mesh->getCoordinates(); Field2D Rxy, Bpxy, Btxy, hthe, I; GRID_LOAD(Rxy); GRID_LOAD(Bpxy); GRID_LOAD(Btxy); GRID_LOAD(hthe); - coords->setBxy(mesh->get("Bxy")); + const auto& Bxy = mesh->get("Bxy"); int ShiftXderivs = 0; mesh->get(ShiftXderivs, "false"); if (ShiftXderivs) { @@ -32,7 +31,7 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - tokamak_coordinates(coords, Rxy, Bpxy, hthe, I, coords->Bxy(), Btxy); + auto* coords = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index e145da4df2..711f291404 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -4,10 +4,13 @@ #include "bout.hxx" -inline Coordinates* tokamak_coordinates(Coordinates* coord, const FieldMetric& Rxy, +inline Coordinates* tokamak_coordinates(Mesh* mesh, const FieldMetric& Rxy, const FieldMetric& Bpxy, const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, - const FieldMetric& Btxy) { + const FieldMetric& Btxy, + const BoutReal& sbp = 1.0) // Sign of Bp +{ + auto* coord = mesh->getCoordinates(); const auto g11 = SQ(Rxy * Bpxy); const auto g22 = 1.0 / SQ(hthe); @@ -21,7 +24,7 @@ inline Coordinates* tokamak_coordinates(Coordinates* coord, const FieldMetric& R const auto g_33 = Rxy * Rxy; const auto g_12 = sbp * Btxy * hthe * I * Rxy / Bpxy; const auto g_13 = I * Rxy * Rxy; - const auto g_23 = Btxy * hthe * Rxy / Bpxy; + const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); @@ -32,5 +35,4 @@ inline Coordinates* tokamak_coordinates(Coordinates* coord, const FieldMetric& R return coord; } - #endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 58ad311417..608a9bbe18 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -88,15 +88,11 @@ class TwoFluid : public PhysicsModel { b0xcv.covariant = false; // Read contravariant components mesh->get(b0xcv, "bxcv"); // b0xkappa terms - // Coordinate system - coord = mesh->getCoordinates(); - // Load metrics GRID_LOAD(Rxy); GRID_LOAD(Bpxy); GRID_LOAD(Btxy); GRID_LOAD(hthe); - coord->setDx(mesh->get("dpsi")); mesh->get(I, "sinty"); // Load normalisation values @@ -204,18 +200,22 @@ class TwoFluid : public PhysicsModel { Rxy /= rho_s; hthe /= rho_s; I *= rho_s * rho_s * (bmag / 1e4) * ShearFactor; - coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); // Normalise magnetic field Bpxy /= (bmag / 1.e4); Btxy /= (bmag / 1.e4); - coord->setBxy(coord->Bxy() / (bmag / 1.e4)); // calculate pressures pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, coord->Bxy(), Btxy); + Field2D Bxy = mesh->get("Bxy"); + Bxy /= (bmag / 1.e4); + + coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + + coord->setDx(mesh->get("dpsi")); + coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index f785d1f9d9..59bff36d99 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -56,15 +56,11 @@ class Interchange : public PhysicsModel { b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY - // Coordinate system - coord = mesh->getCoordinates(); - // Load metrics GRID_LOAD(Rxy); GRID_LOAD(Bpxy); GRID_LOAD(Btxy); GRID_LOAD(hthe); - coord->setDx(mesh->get("dpsi")); mesh->get(I, "sinty"); // Load normalisation values @@ -130,14 +126,18 @@ class Interchange : public PhysicsModel { Rxy /= rho_s; hthe /= rho_s; I *= rho_s * rho_s * (bmag / 1e4) * ShearFactor; - coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); // Normalise magnetic field Bpxy /= (bmag / 1.e4); Btxy /= (bmag / 1.e4); - coord->setBxy(coord->Bxy() / (bmag / 1.e4)); - tokamak_coordinates(coord, Rxy, Bpxy, hthe, I, coord->Bxy(), Btxy); + Field2D Bxy = mesh->get("Bxy"); + Bxy /= (bmag / 1.e4); + + coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + + coord->setDx(mesh->get("dpsi")); + coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); // Tell BOUT++ which variables to evolve SOLVE_FOR2(rho, Ni); From 7f5d78b933b315d0e8cf4fc8c8b390c46df582a7 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 4 Nov 2024 09:47:01 +0000 Subject: [PATCH 06/98] Bxy and dx may be Field2D or Field3D --- examples/conducting-wall-mode/cwm.cxx | 4 ++-- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 28a52ee6a8..01850be418 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -70,7 +70,7 @@ class CWM : public PhysicsModel { mesh->get(Bpxy, "Bpxy"); mesh->get(Btxy, "Btxy"); mesh->get(hthe, "hthe"); - Field2D dx = mesh->get("dpsi"); + FieldMetric dx = mesh->get("dpsi"); mesh->get(I, "sinty"); // Load normalisation values @@ -148,7 +148,7 @@ class CWM : public PhysicsModel { Bpxy /= (bmag / 1.e4); Btxy /= (bmag / 1.e4); - Field2D Bxy = mesh->get("Bxy"); + FieldMetric Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); // Set nu diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index d6f1124695..717fec7021 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -184,7 +184,7 @@ class Alfven : public PhysicsModel { sbp = -1.0; } - Field2D Bxy = mesh->get("Bxy"); + FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index a17023be6b..01faa3702c 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -189,7 +189,7 @@ class Alfven : public PhysicsModel { sbp = -1.0; } - Field2D Bxy = mesh->get("Bxy"); + FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); From a62318393758dc95527ad6a79766ffd28ccc07cd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 12:11:21 +0000 Subject: [PATCH 07/98] Make tokamak_coordinates a method on new class TokamakCoordinatesFactory --- CMakeLists.txt | 2 +- examples/6field-simple/elm_6f.cxx | 4 +- examples/conducting-wall-mode/cwm.cxx | 4 +- examples/constraints/alfven-wave/alfven.cxx | 4 +- examples/dalf3/dalf3.cxx | 4 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 4 +- examples/elm-pb/elm_pb.cxx | 4 +- examples/gyro-gem/gem.cxx | 4 +- examples/laplacexy/alfven-wave/alfven.cxx | 4 +- examples/laplacexy/laplace_perp/test.cxx | 4 +- examples/wave-slab/wave_slab.cxx | 4 +- include/bout/tokamak_coordinates.hxx | 38 ----------------- include/bout/tokamak_coordinates_factory.hxx | 42 +++++++++++++++++++ tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- .../test-drift-instability/2fluid.cxx | 4 +- .../test-interchange-instability/2fluid.cxx | 4 +- .../integrated/test-laplacexy/loadmetric.cxx | 2 +- 18 files changed, 70 insertions(+), 66 deletions(-) delete mode 100644 include/bout/tokamak_coordinates.hxx create mode 100644 include/bout/tokamak_coordinates_factory.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index cf0bedf020..6cb42c2f5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,7 +360,7 @@ set(BOUT_SOURCES ./src/mesh/g_values.cxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx - include/bout/tokamak_coordinates.hxx + ./include/bout/tokamak_coordinates_factory.hxx ) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 570bdfc610..0bd38211e6 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -6,7 +6,6 @@ * T. Xia *******************************************************************************/ -#include "bout/tokamak_coordinates.hxx" #include "bout/constants.hxx" #include "bout/derivs.hxx" #include "bout/initialprofiles.hxx" @@ -16,6 +15,7 @@ #include "bout/msg_stack.hxx" #include "bout/physicsmodel.hxx" #include "bout/sourcex.hxx" +#include "bout/tokamak_coordinates_factory.hxx" #include @@ -1033,7 +1033,7 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 01850be418..f26f0b4087 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -4,8 +4,8 @@ * Mode discoverd by H.L. Berk et. al. 1993 * Model version in the code created by M. Umansky and J. Myra. *******************************************************************************/ -#include #include +#include #include #include @@ -154,7 +154,7 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 717fec7021..4744a22e89 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -1,8 +1,8 @@ -#include #include #include #include +#include /// Fundamental constants const BoutReal PI = 3.14159265; @@ -187,7 +187,7 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index e0802fe5a0..42272ecd26 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -18,8 +18,8 @@ * ****************************************************************/ -#include #include +#include #include #include @@ -242,7 +242,7 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 8f26c81b6e..2d509ba82c 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include // Defines BOUT_FOR_RAJA @@ -1211,7 +1211,7 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - auto* metric = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* metric = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 3bbb556762..1afba7f1ca 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -5,7 +5,6 @@ * Can also include the Vpar compressional term *******************************************************************************/ -#include #include #include #include @@ -15,6 +14,7 @@ #include #include #include +#include #include #include @@ -331,7 +331,7 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - auto* metric = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* metric = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index c11ff36899..806ee36a39 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -9,8 +9,8 @@ * This version uses global parameters for collisionality etc. ****************************************************************/ -#include #include +#include #include #include @@ -364,7 +364,7 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); + coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 01faa3702c..2f92ad7bf1 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -1,10 +1,10 @@ -#include #include #include #include #include #include +#include /// Fundamental constants const BoutReal PI = 3.14159265; @@ -192,7 +192,7 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto* coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 672f473ff3..9336e3cf49 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -22,7 +22,7 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 89ac381244..730a31c043 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -10,8 +10,8 @@ */ -#include #include +#include class WaveTest : public PhysicsModel { public: @@ -31,7 +31,7 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - auto* coords = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + auto* coords = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx deleted file mode 100644 index 711f291404..0000000000 --- a/include/bout/tokamak_coordinates.hxx +++ /dev/null @@ -1,38 +0,0 @@ - -#ifndef BOUT_TOKAMAK_COORDINATES_HXX -#define BOUT_TOKAMAK_COORDINATES_HXX - -#include "bout.hxx" - -inline Coordinates* tokamak_coordinates(Mesh* mesh, const FieldMetric& Rxy, - const FieldMetric& Bpxy, const FieldMetric& hthe, - const FieldMetric& I, const FieldMetric& B, - const FieldMetric& Btxy, - const BoutReal& sbp = 1.0) // Sign of Bp -{ - auto* coord = mesh->getCoordinates(); - - const auto g11 = SQ(Rxy * Bpxy); - const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B) / g11; - const auto g12 = 0.0; - const auto g13 = -I * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); - - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); - const auto g_22 = SQ(B * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe / Bpxy); - coord->setBxy(B); - - return coord; -} - -#endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx new file mode 100644 index 0000000000..2c936249b9 --- /dev/null +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -0,0 +1,42 @@ + +#ifndef BOUT_TOKAMAK_COORDINATES_FACTORY_HXX +#define BOUT_TOKAMAK_COORDINATES_FACTORY_HXX + +#include "bout.hxx" + +class TokamakCoordinatesFactory { + +public: + static Coordinates* make_tokamak_coordinates(Mesh* mesh, const FieldMetric& Rxy, + const FieldMetric& Bpxy, const FieldMetric& hthe, + const FieldMetric& I, const FieldMetric& B, + const FieldMetric& Btxy, + const BoutReal& sbp = 1.0) // Sign of Bp + { + auto* coord = mesh->getCoordinates(); + + const auto g11 = SQ(Rxy * Bpxy); + const auto g22 = 1.0 / SQ(hthe); + const auto g33 = SQ(I) * g11 + SQ(B) / g11; + const auto g12 = 0.0; + const auto g13 = -I * g11; + const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); + + const auto g_11 = 1.0 / g11 + SQ(I * Rxy); + const auto g_22 = SQ(B * hthe / Bpxy); + const auto g_33 = Rxy * Rxy; + const auto g_12 = sbp * Btxy * hthe * I * Rxy / Bpxy; + const auto g_13 = I * Rxy * Rxy; + const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; + + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + + coord->setJ(hthe / Bpxy); + coord->setBxy(B); + + return coord; + } +}; + +#endif //BOUT_TOKAMAK_COORDINATES_FACTORY_HXX diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index b3a863b10c..64b52f7249 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,7 +349,7 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + TokamakCoordinatesFactory().make_tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 3f5a5e1341..a1290d08a8 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,7 +415,7 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - tokamak_coordinates(coords, Rxy, Bpxy, hthe, I, B0, Btxy); + TokamakCoordinatesFactory().make_tokamak_coordinates(coords, Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 608a9bbe18..28f0e727ca 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -3,8 +3,8 @@ * Same as Maxim's version of BOUT - simplified 2-fluid for benchmarking *******************************************************************************/ -#include #include +#include #include #include @@ -212,7 +212,7 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 59bff36d99..446da593fe 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -3,7 +3,7 @@ * Same as Maxim's version of BOUT - simplified 2-fluid for benchmarking *******************************************************************************/ -#include +#include #include #include @@ -134,7 +134,7 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - coord = tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 9cb1a28a42..e693b17446 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,5 +45,5 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + TokamakCoordinatesFactory().make_tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } From 5304237c0868dd9fa98bfb512b44bf919e0a2754 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 12:22:07 +0000 Subject: [PATCH 08/98] Add constructor (taking mesh as parameter) --- examples/6field-simple/elm_6f.cxx | 2 +- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/dalf3/dalf3.cxx | 2 +- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 2 +- examples/elm-pb/elm_pb.cxx | 2 +- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 2 +- include/bout/tokamak_coordinates_factory.hxx | 12 +++++++++--- tests/integrated/test-drift-instability/2fluid.cxx | 2 +- .../test-interchange-instability/2fluid.cxx | 2 +- 13 files changed, 21 insertions(+), 15 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 0bd38211e6..415f7342c2 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,7 +1033,7 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index f26f0b4087..8bab881e9d 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -154,7 +154,7 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 4744a22e89..e4aec50e47 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,7 +187,7 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 42272ecd26..d6bd7fff48 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,7 +242,7 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 2d509ba82c..91fc3ef753 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,7 +1211,7 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - auto* metric = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* metric = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 1afba7f1ca..2fa03e6d01 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,7 +331,7 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - auto* metric = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + auto* metric = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 806ee36a39..cfe4dcbcd8 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,7 +364,7 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); + coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 2f92ad7bf1..e4381c8309 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,7 +192,7 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto* coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 9336e3cf49..8f23d1c21b 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,7 +22,7 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, B0, Btxy); + TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 730a31c043..0813d91075 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,7 +31,7 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - auto* coords = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + auto* coords = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 2c936249b9..54fde453a2 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -7,13 +7,19 @@ class TokamakCoordinatesFactory { public: - static Coordinates* make_tokamak_coordinates(Mesh* mesh, const FieldMetric& Rxy, + + Mesh* mesh_m; + + TokamakCoordinatesFactory(Mesh* mesh) : mesh_m(mesh) { + } + + Coordinates* make_tokamak_coordinates(const FieldMetric& Rxy, const FieldMetric& Bpxy, const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, const FieldMetric& Btxy, - const BoutReal& sbp = 1.0) // Sign of Bp + const BoutReal& sbp = 1.0) const // Sign of Bp { - auto* coord = mesh->getCoordinates(); + auto* coord = mesh_m->getCoordinates(); const auto g11 = SQ(Rxy * Bpxy); const auto g22 = 1.0 / SQ(hthe); diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 28f0e727ca..c4037691a4 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,7 +212,7 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 446da593fe..37150cb6ee 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,7 +134,7 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - coord = TokamakCoordinatesFactory().make_tokamak_coordinates(mesh, Rxy, Bpxy, hthe, I, Bxy, Btxy); + coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); From cb88cf62bbb88b255ce56356b52916ba939d0d79 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 14:05:50 +0000 Subject: [PATCH 09/98] Assign tokamak_coordinates_factory to variable --- examples/6field-simple/elm_6f.cxx | 3 ++- examples/conducting-wall-mode/cwm.cxx | 3 ++- examples/constraints/alfven-wave/alfven.cxx | 3 ++- examples/dalf3/dalf3.cxx | 3 ++- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 3 ++- examples/elm-pb/elm_pb.cxx | 3 ++- examples/gyro-gem/gem.cxx | 3 ++- examples/laplacexy/alfven-wave/alfven.cxx | 3 ++- examples/laplacexy/laplace_perp/test.cxx | 3 ++- examples/wave-slab/wave_slab.cxx | 3 ++- tests/MMS/GBS/gbs.cxx | 3 ++- tests/MMS/elm-pb/elm_pb.cxx | 3 ++- tests/integrated/test-drift-instability/2fluid.cxx | 3 ++- tests/integrated/test-interchange-instability/2fluid.cxx | 3 ++- tests/integrated/test-laplacexy/loadmetric.cxx | 3 ++- 15 files changed, 30 insertions(+), 15 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 415f7342c2..65d197296f 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,7 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 8bab881e9d..f4d9c48a3a 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -154,7 +154,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index e4aec50e47..31d6b014d0 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,7 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index d6bd7fff48..c13786e231 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,7 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 91fc3ef753..7865d6984e 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,7 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - auto* metric = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 2fa03e6d01..85a0b20f49 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,7 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - auto* metric = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index cfe4dcbcd8..e0813d2191 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,7 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index e4381c8309..a918c991a3 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,7 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto* coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 8f23d1c21b..b4eaec14a3 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,7 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 0813d91075..d17ab8a084 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,7 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - auto* coords = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + auto* coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 64b52f7249..8e44690c90 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,7 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - TokamakCoordinatesFactory().make_tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index a1290d08a8..db94c13fe7 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,7 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - TokamakCoordinatesFactory().make_tokamak_coordinates(coords, Rxy, Bpxy, hthe, I, B0, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index c4037691a4..ea42545abc 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,7 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 37150cb6ee..1e452ade86 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,7 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - coord = TokamakCoordinatesFactory(mesh).make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index e693b17446..b0977f68d3 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,5 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - TokamakCoordinatesFactory().make_tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } From 28e6221ea0f91aeecf5ad5f6f1cb522f4928cbd9 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 14:09:32 +0000 Subject: [PATCH 10/98] Field mesh_m should be private --- include/bout/tokamak_coordinates_factory.hxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 54fde453a2..4616471989 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -6,10 +6,12 @@ class TokamakCoordinatesFactory { -public: - +private: + Mesh* mesh_m; +public: + TokamakCoordinatesFactory(Mesh* mesh) : mesh_m(mesh) { } From e266784d5f02b789cddc1519083a5a8485b8d5b8 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 14:35:39 +0000 Subject: [PATCH 11/98] Rename variable (Sign of Bp) --- include/bout/tokamak_coordinates_factory.hxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 4616471989..8727039c5a 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -19,7 +19,7 @@ public: const FieldMetric& Bpxy, const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, const FieldMetric& Btxy, - const BoutReal& sbp = 1.0) const // Sign of Bp + const BoutReal& sign_of_bp = 1.0) const { auto* coord = mesh_m->getCoordinates(); @@ -28,14 +28,14 @@ public: const auto g33 = SQ(I) * g11 + SQ(B) / g11; const auto g12 = 0.0; const auto g13 = -I * g11; - const auto g23 = -sbp * Btxy / (hthe * Bpxy * Rxy); + const auto g23 = -sign_of_bp * Btxy / (hthe * Bpxy * Rxy); const auto g_11 = 1.0 / g11 + SQ(I * Rxy); const auto g_22 = SQ(B * hthe / Bpxy); const auto g_33 = Rxy * Rxy; - const auto g_12 = sbp * Btxy * hthe * I * Rxy / Bpxy; + const auto g_12 = sign_of_bp * Btxy * hthe * I * Rxy / Bpxy; const auto g_13 = I * Rxy * Rxy; - const auto g_23 = sbp * Btxy * hthe * Rxy / Bpxy; + const auto g_23 = sign_of_bp * Btxy * hthe * Rxy / Bpxy; coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); From ab2defd3fa0c0675a66d71e695eb401eaccd5cd2 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 15:00:32 +0000 Subject: [PATCH 12/98] Prefer const ref --- examples/6field-simple/elm_6f.cxx | 4 ++-- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- examples/dalf3/dalf3.cxx | 4 ++-- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 4 ++-- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 4 ++-- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 4 ++-- tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- tests/integrated/test-drift-instability/2fluid.cxx | 2 +- tests/integrated/test-interchange-instability/2fluid.cxx | 2 +- tests/integrated/test-laplacexy/loadmetric.cxx | 2 +- 15 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 65d197296f..e191859d7b 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index f4d9c48a3a..21c6bdbb06 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -154,7 +154,7 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 31d6b014d0..664a225e2e 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index c13786e231..0f1a68705f 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 7865d6984e..6eef704294 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 85a0b20f49..ff5a876988 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index e0813d2191..1e9f7f8914 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,7 +364,7 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index a918c991a3..a995a110d3 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index b4eaec14a3..e4d018df4e 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,7 +22,7 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index d17ab8a084..c47a7ca3a7 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - auto* coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 8e44690c90..984c058cee 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,7 +349,7 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index db94c13fe7..872b662eb0 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,7 +415,7 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index ea42545abc..2215829c46 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,7 +212,7 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 1e452ade86..b6f08261bf 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,7 +134,7 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index b0977f68d3..54c694edee 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } From e9561f88b1f21fdba7bc306ae73bd9dba00c05e4 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 15:27:54 +0000 Subject: [PATCH 13/98] Make Rxy a member variable of TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 +-- examples/conducting-wall-mode/cwm.cxx | 4 +-- examples/constraints/alfven-wave/alfven.cxx | 4 +-- examples/dalf3/dalf3.cxx | 4 +-- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 4 +-- examples/elm-pb/elm_pb.cxx | 6 ++-- examples/gyro-gem/gem.cxx | 4 +-- examples/laplacexy/alfven-wave/alfven.cxx | 4 +-- examples/laplacexy/laplace_perp/test.cxx | 4 +-- examples/wave-slab/wave_slab.cxx | 4 +-- include/bout/tokamak_coordinates_factory.hxx | 28 ++++++++++--------- tests/MMS/GBS/gbs.cxx | 4 +-- tests/MMS/elm-pb/elm_pb.cxx | 4 +-- .../test-drift-instability/2fluid.cxx | 4 +-- .../test-interchange-instability/2fluid.cxx | 4 +-- .../integrated/test-laplacexy/loadmetric.cxx | 4 +-- 16 files changed, 46 insertions(+), 44 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index e191859d7b..0330d0a295 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 21c6bdbb06..7afda082f0 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -154,8 +154,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 664a225e2e..5d91d67d14 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 0f1a68705f..206137a985 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 6eef704294..959b54df9a 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index ff5a876988..a8cd89d476 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely @@ -662,7 +662,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -Rxy * Bpxy * Dphi0 / B0; + V0 = -tokamak_coordinates_factory.Rxy() * Bpxy * Dphi0 / B0; if (simple_rmp) { include_rmp = true; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 1e9f7f8914..edffe87e08 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,8 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, 0.0, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, 0.0, Bxy, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index a995a110d3..c05c03351c 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index e4d018df4e..77d2adedc3 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,8 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index c47a7ca3a7..3f7a59b558 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 8727039c5a..70df035b92 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -8,34 +8,33 @@ class TokamakCoordinatesFactory { private: - Mesh* mesh_m; + Mesh& mesh_m; + const FieldMetric& Rxy_m; public: - TokamakCoordinatesFactory(Mesh* mesh) : mesh_m(mesh) { - } + TokamakCoordinatesFactory(Mesh& mesh, const FieldMetric& Rxy) : mesh_m(mesh), Rxy_m(Rxy) {} - Coordinates* make_tokamak_coordinates(const FieldMetric& Rxy, - const FieldMetric& Bpxy, const FieldMetric& hthe, + Coordinates* make_tokamak_coordinates(const FieldMetric& Bpxy, const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, const FieldMetric& Btxy, const BoutReal& sign_of_bp = 1.0) const { - auto* coord = mesh_m->getCoordinates(); + auto* coord = mesh_m.getCoordinates(); - const auto g11 = SQ(Rxy * Bpxy); + const auto g11 = SQ(Rxy() * Bpxy); const auto g22 = 1.0 / SQ(hthe); const auto g33 = SQ(I) * g11 + SQ(B) / g11; const auto g12 = 0.0; const auto g13 = -I * g11; - const auto g23 = -sign_of_bp * Btxy / (hthe * Bpxy * Rxy); + const auto g23 = -sign_of_bp * Btxy / (hthe * Bpxy * Rxy()); - const auto g_11 = 1.0 / g11 + SQ(I * Rxy); + const auto g_11 = 1.0 / g11 + SQ(I * Rxy()); const auto g_22 = SQ(B * hthe / Bpxy); - const auto g_33 = Rxy * Rxy; - const auto g_12 = sign_of_bp * Btxy * hthe * I * Rxy / Bpxy; - const auto g_13 = I * Rxy * Rxy; - const auto g_23 = sign_of_bp * Btxy * hthe * Rxy / Bpxy; + const auto g_33 = Rxy() * Rxy(); + const auto g_12 = sign_of_bp * Btxy * hthe * I * Rxy() / Bpxy; + const auto g_13 = I * Rxy() * Rxy(); + const auto g_23 = sign_of_bp * Btxy * hthe * Rxy() / Bpxy; coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); @@ -45,6 +44,9 @@ public: return coord; } + + const FieldMetric& Rxy() const { return Rxy_m; } + }; #endif //BOUT_TOKAMAK_COORDINATES_FACTORY_HXX diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 984c058cee..5cbcd051bc 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 872b662eb0..b6677d188d 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 2215829c46..ecac68f271 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index b6f08261bf..ad3f4ba7ce 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,8 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 54c694edee..89fc7ccb6a 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } From e00cbd86903a1d853481e332bf2f8e5b392b27be Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 15:48:34 +0000 Subject: [PATCH 14/98] Get coordinates from TokamakCoordinatesFactory instead of mesh->getCoordinates() --- examples/conducting-wall-mode/cwm.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 7afda082f0..9af2399f94 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -62,8 +62,6 @@ class CWM : public PhysicsModel { // Load 2D profiles (set to zero if not found) GRID_LOAD(Ni0, Te0); - coord = mesh->getCoordinates(); - // Load metrics mesh->get(Rxy, "Rxy"); mesh->get(Zxy, "Zxy"); From e04e7fd5efc94e0aac71d6749e35c7e1803f6aa7 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 16:25:11 +0000 Subject: [PATCH 15/98] Rxy has to be of type Field2D --- include/bout/tokamak_coordinates_factory.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 70df035b92..66554b6bb4 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -9,11 +9,11 @@ class TokamakCoordinatesFactory { private: Mesh& mesh_m; - const FieldMetric& Rxy_m; + const Field2D& Rxy_m; public: - TokamakCoordinatesFactory(Mesh& mesh, const FieldMetric& Rxy) : mesh_m(mesh), Rxy_m(Rxy) {} + TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy) : mesh_m(mesh), Rxy_m(Rxy) {} Coordinates* make_tokamak_coordinates(const FieldMetric& Bpxy, const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, @@ -45,7 +45,7 @@ public: return coord; } - const FieldMetric& Rxy() const { return Rxy_m; } + const Field2D& Rxy() const { return Rxy_m; } }; From 43ba0941df6e0b8da731166bb9aa70c61968b78a Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 16:28:47 +0000 Subject: [PATCH 16/98] Make Bpxy a member variable of TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 ++-- examples/conducting-wall-mode/cwm.cxx | 4 ++-- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- examples/dalf3/dalf3.cxx | 4 ++-- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 6 +++--- examples/gyro-gem/gem.cxx | 4 ++-- examples/laplacexy/alfven-wave/alfven.cxx | 4 ++-- examples/laplacexy/laplace_perp/test.cxx | 4 ++-- examples/wave-slab/wave_slab.cxx | 4 ++-- include/bout/tokamak_coordinates_factory.hxx | 20 ++++++++++--------- tests/MMS/GBS/gbs.cxx | 4 ++-- tests/MMS/elm-pb/elm_pb.cxx | 4 ++-- .../test-drift-instability/2fluid.cxx | 4 ++-- .../test-interchange-instability/2fluid.cxx | 4 ++-- .../integrated/test-laplacexy/loadmetric.cxx | 4 ++-- 16 files changed, 42 insertions(+), 40 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 0330d0a295..142aefd8ad 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 9af2399f94..5878166241 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -152,8 +152,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 5d91d67d14..1833ec2cf6 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 206137a985..6f3e18a17d 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 959b54df9a..57a1cf5f50 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index a8cd89d476..503bc6c314 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely @@ -662,7 +662,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates_factory.Rxy() * Bpxy * Dphi0 / B0; + V0 = -tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Bpxy() * Dphi0 / B0; if (simple_rmp) { include_rmp = true; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index edffe87e08..4ee1320417 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,8 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, 0.0, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, 0.0, Bxy, Btxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index c05c03351c..1313fc127f 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, Btxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 77d2adedc3..2a2923b3bb 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,8 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 3f7a59b558..f810e0fb0d 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 66554b6bb4..a0f5c92e99 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -10,42 +10,44 @@ private: Mesh& mesh_m; const Field2D& Rxy_m; + const Field2D& Bpxy_m; public: + TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy) + : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy) {} - TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy) : mesh_m(mesh), Rxy_m(Rxy) {} - - Coordinates* make_tokamak_coordinates(const FieldMetric& Bpxy, const FieldMetric& hthe, + Coordinates* make_tokamak_coordinates(const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, const FieldMetric& Btxy, const BoutReal& sign_of_bp = 1.0) const { auto* coord = mesh_m.getCoordinates(); - const auto g11 = SQ(Rxy() * Bpxy); + const auto g11 = SQ(Rxy() * Bpxy()); const auto g22 = 1.0 / SQ(hthe); const auto g33 = SQ(I) * g11 + SQ(B) / g11; const auto g12 = 0.0; const auto g13 = -I * g11; - const auto g23 = -sign_of_bp * Btxy / (hthe * Bpxy * Rxy()); + const auto g23 = -sign_of_bp * Btxy / (hthe * Bpxy() * Rxy()); const auto g_11 = 1.0 / g11 + SQ(I * Rxy()); - const auto g_22 = SQ(B * hthe / Bpxy); + const auto g_22 = SQ(B * hthe / Bpxy()); const auto g_33 = Rxy() * Rxy(); - const auto g_12 = sign_of_bp * Btxy * hthe * I * Rxy() / Bpxy; + const auto g_12 = sign_of_bp * Btxy * hthe * I * Rxy() / Bpxy(); const auto g_13 = I * Rxy() * Rxy(); - const auto g_23 = sign_of_bp * Btxy * hthe * Rxy() / Bpxy; + const auto g_23 = sign_of_bp * Btxy * hthe * Rxy() / Bpxy(); coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - coord->setJ(hthe / Bpxy); + coord->setJ(hthe / Bpxy()); coord->setBxy(B); return coord; } const Field2D& Rxy() const { return Rxy_m; } + const Field2D& Bpxy() const { return Bpxy_m; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 5cbcd051bc..e62ac1ad11 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), Btxy, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index b6677d188d..299c8ccf7b 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index ecac68f271..a23fa567de 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index ad3f4ba7ce..e0ca8112da 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,8 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 89fc7ccb6a..97b8262362 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), Btxy, sbp); } From f1f9c7585c41c5c13855c060577344b29ca4a3cb Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 19:39:07 +0000 Subject: [PATCH 17/98] Make Btxy a member variable of TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 ++-- examples/conducting-wall-mode/cwm.cxx | 4 ++-- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- examples/dalf3/dalf3.cxx | 4 ++-- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 4 ++-- examples/gyro-gem/gem.cxx | 4 ++-- examples/laplacexy/alfven-wave/alfven.cxx | 4 ++-- examples/laplacexy/laplace_perp/test.cxx | 4 ++-- examples/wave-slab/wave_slab.cxx | 4 ++-- include/bout/tokamak_coordinates_factory.hxx | 13 +++++++------ tests/MMS/GBS/gbs.cxx | 4 ++-- tests/MMS/elm-pb/elm_pb.cxx | 4 ++-- tests/integrated/test-drift-instability/2fluid.cxx | 4 ++-- .../test-interchange-instability/2fluid.cxx | 4 ++-- tests/integrated/test-laplacexy/loadmetric.cxx | 4 ++-- 16 files changed, 37 insertions(+), 36 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 142aefd8ad..446cc4c3e4 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 5878166241..63c8629d50 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -152,8 +152,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 1833ec2cf6..9cfe2938ef 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 6f3e18a17d..a744de78bd 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 57a1cf5f50..24d81b6f65 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 503bc6c314..038c2e572c 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 4ee1320417..a5bf60c518 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,8 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, 0.0, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, 0.0, Bxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 1313fc127f..bdc4745263 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 2a2923b3bb..d8c77a3d4f 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,8 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index f810e0fb0d..4b29ee9122 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index a0f5c92e99..dea8a309d4 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -11,14 +11,14 @@ private: Mesh& mesh_m; const Field2D& Rxy_m; const Field2D& Bpxy_m; + const Field2D& Btxy_m; public: - TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy) - : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy) {} + TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy) + : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy) {} Coordinates* make_tokamak_coordinates(const FieldMetric& hthe, const FieldMetric& I, const FieldMetric& B, - const FieldMetric& Btxy, const BoutReal& sign_of_bp = 1.0) const { auto* coord = mesh_m.getCoordinates(); @@ -28,14 +28,14 @@ public: const auto g33 = SQ(I) * g11 + SQ(B) / g11; const auto g12 = 0.0; const auto g13 = -I * g11; - const auto g23 = -sign_of_bp * Btxy / (hthe * Bpxy() * Rxy()); + const auto g23 = -sign_of_bp * Btxy() / (hthe * Bpxy() * Rxy()); const auto g_11 = 1.0 / g11 + SQ(I * Rxy()); const auto g_22 = SQ(B * hthe / Bpxy()); const auto g_33 = Rxy() * Rxy(); - const auto g_12 = sign_of_bp * Btxy * hthe * I * Rxy() / Bpxy(); + const auto g_12 = sign_of_bp * Btxy() * hthe * I * Rxy() / Bpxy(); const auto g_13 = I * Rxy() * Rxy(); - const auto g_23 = sign_of_bp * Btxy * hthe * Rxy() / Bpxy(); + const auto g_23 = sign_of_bp * Btxy() * hthe * Rxy() / Bpxy(); coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); @@ -48,6 +48,7 @@ public: const Field2D& Rxy() const { return Rxy_m; } const Field2D& Bpxy() const { return Bpxy_m; } + const Field2D& Btxy() const { return Btxy_m; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index e62ac1ad11..1b0b6a40b8 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 299c8ccf7b..288131114e 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index a23fa567de..fce5335752 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index e0ca8112da..079c7f9cc2 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,8 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy, Btxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 97b8262362..ad3749b944 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), Btxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), sbp); } From e41dc928cefc2213303f7737ba54a1a7e5e28e14 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 20:00:24 +0000 Subject: [PATCH 18/98] Make B a member variable of TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 ++-- examples/conducting-wall-mode/cwm.cxx | 4 ++-- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- examples/dalf3/dalf3.cxx | 4 ++-- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 4 ++-- examples/gyro-gem/gem.cxx | 4 ++-- examples/laplacexy/alfven-wave/alfven.cxx | 4 ++-- examples/laplacexy/laplace_perp/test.cxx | 4 ++-- examples/wave-slab/wave_slab.cxx | 4 ++-- include/bout/tokamak_coordinates_factory.hxx | 15 +++++++++------ tests/MMS/GBS/gbs.cxx | 4 ++-- tests/MMS/elm-pb/elm_pb.cxx | 4 ++-- .../integrated/test-drift-instability/2fluid.cxx | 4 ++-- .../test-interchange-instability/2fluid.cxx | 4 ++-- tests/integrated/test-laplacexy/loadmetric.cxx | 4 ++-- 16 files changed, 39 insertions(+), 36 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 446cc4c3e4..7dcb7d20b3 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 63c8629d50..ea983ba0c3 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -152,8 +152,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 9cfe2938ef..55f9eeb9cc 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index a744de78bd..9b505aeced 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 24d81b6f65..bf91a46a93 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 038c2e572c..4b004cf80d 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index a5bf60c518..51a9419a1c 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,8 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, 0.0, Bxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, 0.0); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index bdc4745263..659590f03c 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, Bxy, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index d8c77a3d4f..aa23d0c8b7 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,8 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); + tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 4b29ee9122..9a1490ba67 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index dea8a309d4..b9b284d55d 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -12,26 +12,28 @@ private: const Field2D& Rxy_m; const Field2D& Bpxy_m; const Field2D& Btxy_m; + const FieldMetric& B_m; public: - TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy) - : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy) {} + + TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy, const FieldMetric& B) + : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy), B_m(B) {} Coordinates* make_tokamak_coordinates(const FieldMetric& hthe, - const FieldMetric& I, const FieldMetric& B, + const FieldMetric& I, const BoutReal& sign_of_bp = 1.0) const { auto* coord = mesh_m.getCoordinates(); const auto g11 = SQ(Rxy() * Bpxy()); const auto g22 = 1.0 / SQ(hthe); - const auto g33 = SQ(I) * g11 + SQ(B) / g11; + const auto g33 = SQ(I) * g11 + SQ(B()) / g11; const auto g12 = 0.0; const auto g13 = -I * g11; const auto g23 = -sign_of_bp * Btxy() / (hthe * Bpxy() * Rxy()); const auto g_11 = 1.0 / g11 + SQ(I * Rxy()); - const auto g_22 = SQ(B * hthe / Bpxy()); + const auto g_22 = SQ(B() * hthe / Bpxy()); const auto g_33 = Rxy() * Rxy(); const auto g_12 = sign_of_bp * Btxy() * hthe * I * Rxy() / Bpxy(); const auto g_13 = I * Rxy() * Rxy(); @@ -41,7 +43,7 @@ public: CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); coord->setJ(hthe / Bpxy()); - coord->setBxy(B); + coord->setBxy(B()); return coord; } @@ -49,6 +51,7 @@ public: const Field2D& Rxy() const { return Rxy_m; } const Field2D& Bpxy() const { return Bpxy_m; } const Field2D& Btxy() const { return Btxy_m; } + const FieldMetric& B() const { return B_m; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 1b0b6a40b8..1738a78b15 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy()); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 288131114e..52fdc08def 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, B0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index fce5335752..faa2c93033 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 079c7f9cc2..0f92020beb 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,8 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I, Bxy); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index ad3749b944..02f2af526d 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, coords->Bxy(), sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy()); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); } From a2be200edf1775ad6c5b0a2cefd2ec564180c34f Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 6 Nov 2024 20:26:08 +0000 Subject: [PATCH 19/98] Make hthe a member variable of TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 ++-- examples/conducting-wall-mode/cwm.cxx | 4 ++-- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- examples/dalf3/dalf3.cxx | 4 ++-- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 4 ++-- examples/gyro-gem/gem.cxx | 4 ++-- examples/laplacexy/alfven-wave/alfven.cxx | 4 ++-- examples/laplacexy/laplace_perp/test.cxx | 4 ++-- examples/wave-slab/wave_slab.cxx | 4 ++-- include/bout/tokamak_coordinates_factory.hxx | 21 ++++++++++--------- tests/MMS/GBS/gbs.cxx | 4 ++-- tests/MMS/elm-pb/elm_pb.cxx | 4 ++-- .../test-drift-instability/2fluid.cxx | 4 ++-- .../test-interchange-instability/2fluid.cxx | 4 ++-- .../integrated/test-laplacexy/loadmetric.cxx | 4 ++-- 16 files changed, 41 insertions(+), 40 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 7dcb7d20b3..1dc94af3de 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index ea983ba0c3..eb28f8b033 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -152,8 +152,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 55f9eeb9cc..a087da8fc2 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 9b505aeced..9b4796931f 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index bf91a46a93..e018e473aa 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(I); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 4b004cf80d..1ba920e215 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(I); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 51a9419a1c..c7508a7bc9 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,8 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, 0.0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(0.0); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 659590f03c..2b31d74dc7 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index aa23d0c8b7..ca5d5681ef 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,8 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); - tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); + tokamak_coordinates_factory.make_tokamak_coordinates(I); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 9a1490ba67..e8a654c808 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(I); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index b9b284d55d..410911b0f7 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -13,36 +13,36 @@ private: const Field2D& Bpxy_m; const Field2D& Btxy_m; const FieldMetric& B_m; + const FieldMetric& hthe_m; public: - TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy, const FieldMetric& B) - : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy), B_m(B) {} + TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy, const FieldMetric& B, const FieldMetric& hthe) + : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy), B_m(B), hthe_m(hthe) {} - Coordinates* make_tokamak_coordinates(const FieldMetric& hthe, - const FieldMetric& I, + Coordinates* make_tokamak_coordinates(const FieldMetric& I, const BoutReal& sign_of_bp = 1.0) const { auto* coord = mesh_m.getCoordinates(); const auto g11 = SQ(Rxy() * Bpxy()); - const auto g22 = 1.0 / SQ(hthe); + const auto g22 = 1.0 / SQ(hthe()); const auto g33 = SQ(I) * g11 + SQ(B()) / g11; const auto g12 = 0.0; const auto g13 = -I * g11; - const auto g23 = -sign_of_bp * Btxy() / (hthe * Bpxy() * Rxy()); + const auto g23 = -sign_of_bp * Btxy() / (hthe() * Bpxy() * Rxy()); const auto g_11 = 1.0 / g11 + SQ(I * Rxy()); - const auto g_22 = SQ(B() * hthe / Bpxy()); + const auto g_22 = SQ(B() * hthe() / Bpxy()); const auto g_33 = Rxy() * Rxy(); - const auto g_12 = sign_of_bp * Btxy() * hthe * I * Rxy() / Bpxy(); + const auto g_12 = sign_of_bp * Btxy() * hthe() * I * Rxy() / Bpxy(); const auto g_13 = I * Rxy() * Rxy(); - const auto g_23 = sign_of_bp * Btxy() * hthe * Rxy() / Bpxy(); + const auto g_23 = sign_of_bp * Btxy() * hthe() * Rxy() / Bpxy(); coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - coord->setJ(hthe / Bpxy()); + coord->setJ(hthe() / Bpxy()); coord->setBxy(B()); return coord; @@ -52,6 +52,7 @@ public: const Field2D& Bpxy() const { return Bpxy_m; } const Field2D& Btxy() const { return Btxy_m; } const FieldMetric& B() const { return B_m; } + const FieldMetric& hthe() const { return hthe_m; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 1738a78b15..495950ba2c 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy()); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 52fdc08def..85b90229c7 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(I); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index faa2c93033..336cba9159 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 0f92020beb..6a703eca85 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,8 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 02f2af526d..785a64acfa 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy()); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(hthe, sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); } From 32560929f13b3093e0db0e328dfe4c73f619f9dc Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 8 Nov 2024 11:09:17 +0000 Subject: [PATCH 20/98] Make I a member variable of TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 ++-- examples/conducting-wall-mode/cwm.cxx | 4 ++-- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- examples/dalf3/dalf3.cxx | 4 ++-- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 4 ++-- examples/gyro-gem/gem.cxx | 4 ++-- examples/laplacexy/alfven-wave/alfven.cxx | 4 ++-- examples/laplacexy/laplace_perp/test.cxx | 4 ++-- examples/wave-slab/wave_slab.cxx | 4 ++-- include/bout/tokamak_coordinates_factory.hxx | 19 ++++++++++--------- tests/MMS/GBS/gbs.cxx | 4 ++-- tests/MMS/elm-pb/elm_pb.cxx | 4 ++-- .../test-drift-instability/2fluid.cxx | 4 ++-- .../test-interchange-instability/2fluid.cxx | 4 ++-- .../integrated/test-laplacexy/loadmetric.cxx | 4 ++-- 16 files changed, 40 insertions(+), 39 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 1dc94af3de..66582e851a 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1033,8 +1033,8 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index eb28f8b033..3a9151bd02 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -152,8 +152,8 @@ class CWM : public PhysicsModel { // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(dx); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index a087da8fc2..c70ae79bf7 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -187,8 +187,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, sinty); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 9b4796931f..bd22733d6f 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -242,8 +242,8 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index e018e473aa..3a0d6c62ff 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1211,8 +1211,8 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 1ba920e215..58cb3c7348 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -331,8 +331,8 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index c7508a7bc9..556a0759b4 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -364,8 +364,8 @@ class GEM : public PhysicsModel { Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(0.0); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, 0.0); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 2b31d74dc7..6535ca2f88 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -192,8 +192,8 @@ class Alfven : public PhysicsModel { FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, sinty); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index ca5d5681ef..920bee3635 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -22,8 +22,8 @@ int main(int argc, char** argv) { mesh->get(hthe, "hthe"); // m mesh->get(I, "sinty"); // m^-2 T^-1 - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); - tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + tokamak_coordinates_factory.make_tokamak_coordinates(); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index e8a654c808..b23af3e375 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -31,8 +31,8 @@ class WaveTest : public PhysicsModel { mesh->get(I, "sinty"); } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 410911b0f7..055927bbaa 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -14,29 +14,29 @@ private: const Field2D& Btxy_m; const FieldMetric& B_m; const FieldMetric& hthe_m; + const FieldMetric& I_m; public: - TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy, const FieldMetric& B, const FieldMetric& hthe) - : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy), B_m(B), hthe_m(hthe) {} + TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy, const FieldMetric& B, const FieldMetric& hthe, const FieldMetric& I) + : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy), B_m(B), hthe_m(hthe), I_m(I) {} - Coordinates* make_tokamak_coordinates(const FieldMetric& I, - const BoutReal& sign_of_bp = 1.0) const + Coordinates* make_tokamak_coordinates(const BoutReal& sign_of_bp = 1.0) const { auto* coord = mesh_m.getCoordinates(); const auto g11 = SQ(Rxy() * Bpxy()); const auto g22 = 1.0 / SQ(hthe()); - const auto g33 = SQ(I) * g11 + SQ(B()) / g11; + const auto g33 = SQ(I()) * g11 + SQ(B()) / g11; const auto g12 = 0.0; - const auto g13 = -I * g11; + const auto g13 = -I() * g11; const auto g23 = -sign_of_bp * Btxy() / (hthe() * Bpxy() * Rxy()); - const auto g_11 = 1.0 / g11 + SQ(I * Rxy()); + const auto g_11 = 1.0 / g11 + SQ(I() * Rxy()); const auto g_22 = SQ(B() * hthe() / Bpxy()); const auto g_33 = Rxy() * Rxy(); - const auto g_12 = sign_of_bp * Btxy() * hthe() * I * Rxy() / Bpxy(); - const auto g_13 = I * Rxy() * Rxy(); + const auto g_12 = sign_of_bp * Btxy() * hthe() * I() * Rxy() / Bpxy(); + const auto g_13 = I() * Rxy() * Rxy(); const auto g_23 = sign_of_bp * Btxy() * hthe() * Rxy() / Bpxy(); coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), @@ -53,6 +53,7 @@ public: const Field2D& Btxy() const { return Btxy_m; } const FieldMetric& B() const { return B_m; } const FieldMetric& hthe() const { return hthe_m; } + const FieldMetric& I() const { return I_m; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 495950ba2c..d9c61254f6 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe, sinty); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 85b90229c7..dc586c0535 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 336cba9159..5e73c7f928 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 6a703eca85..5abf0bc187 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -134,8 +134,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 785a64acfa..949e673b11 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(sinty, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe, sinty); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); } From 7fd82e43cd143e6e9906ce14beb5ea9f0290b9ba Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 8 Nov 2024 15:37:13 +0000 Subject: [PATCH 21/98] Load values for metric quantities (from mesh) inside TokamakCoordinatesFactory constructor. --- examples/6field-simple/elm_6f.cxx | 21 +----- examples/conducting-wall-mode/cwm.cxx | 45 +++++------ examples/constraints/alfven-wave/alfven.cxx | 40 +++++----- examples/dalf3/dalf3.cxx | 19 +---- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 17 +---- examples/elm-pb/elm_pb.cxx | 19 +---- examples/gyro-gem/gem.cxx | 42 +++++------ examples/laplacexy/alfven-wave/alfven.cxx | 25 +------ examples/laplacexy/laplace_perp/test.cxx | 13 +--- examples/wave-slab/wave_slab.cxx | 20 ++--- include/bout/tokamak_coordinates_factory.hxx | 74 ++++++++++++------- tests/MMS/GBS/gbs.cxx | 4 +- tests/MMS/elm-pb/elm_pb.cxx | 4 +- .../test-drift-instability/2fluid.cxx | 4 +- .../test-interchange-instability/2fluid.cxx | 14 +--- .../integrated/test-laplacexy/loadmetric.cxx | 4 +- 16 files changed, 139 insertions(+), 226 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 66582e851a..76966c306b 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -235,9 +235,6 @@ class Elm_6f : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, B0, hthe; - Field2D I; // Shear factor BoutReal LnLambda; // ln(Lambda) /// Ion mass @@ -367,7 +364,7 @@ class Elm_6f : public PhysicsModel { result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * B0; + result -= bracket(Psi, f, bm_mag) * tokamak_coordinates_factory.getBxy(); } } @@ -393,20 +390,6 @@ class Elm_6f : public PhysicsModel { b0xcv.covariant = false; // Read contravariant components mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - // Load metrics - if (mesh->get(Rxy, "Rxy")) { // m - output_error.write("Error: Cannot read Rxy from grid\n"); - return 1; - } - if (mesh->get(Bpxy, "Bpxy")) { // T - output_error.write("Error: Cannot read Bpxy from grid\n"); - return 1; - } - mesh->get(Btxy, "Btxy"); // T - mesh->get(B0, "Bxy"); // T - mesh->get(hthe, "hthe"); // m - mesh->get(I, "sinty"); // m^-2 T^-1 - ////////////////////////////////////////////////////////////// // Read parameters from the options file // @@ -1033,7 +1016,7 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(dx / (Lbar * Lbar * Bbar)); diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 3a9151bd02..f8aadb2595 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -29,8 +29,7 @@ class CWM : public PhysicsModel { // Phi boundary conditions Field3D dphi_bc_ydown, dphi_bc_yup; - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, hthe, Zxy; + Field2D Zxy; // parameters BoutReal Te_x, Ni_x, Vi_x, bmag, rho_s, fmei, AA, ZZ; @@ -55,21 +54,13 @@ class CWM : public PhysicsModel { std::unique_ptr phiSolver{nullptr}; int init(bool UNUSED(restarting)) override { - Field2D I; // Shear factor /************* LOAD DATA FROM GRID FILE ****************/ // Load 2D profiles (set to zero if not found) GRID_LOAD(Ni0, Te0); - // Load metrics - mesh->get(Rxy, "Rxy"); - mesh->get(Zxy, "Zxy"); - mesh->get(Bpxy, "Bpxy"); - mesh->get(Btxy, "Btxy"); - mesh->get(hthe, "hthe"); FieldMetric dx = mesh->get("dpsi"); - mesh->get(I, "sinty"); // Load normalisation values GRID_LOAD(Te_x, Ni_x, bmag); @@ -127,6 +118,10 @@ class CWM : public PhysicsModel { hthe0 / rho_s); } + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + coord->setDx(dx); + /************** NORMALISE QUANTITIES *****************/ output.write("\tNormalising to rho_s = {:e}\n", rho_s); @@ -136,26 +131,32 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - Rxy /= rho_s; - hthe /= rho_s; - I *= rho_s * rho_s * (bmag / 1e4) * ShearFactor; + + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; + tokamak_coordinates_factory.set_Rxy(new_Rxy); + + FieldMetric new_hthe = tokamak_coordinates_factory.get_hthe() / rho_s; + tokamak_coordinates_factory.set_hthe(new_hthe); + + FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * rho_s * rho_s * (bmag / 1e4) * ShearFactor; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); dx /= (rho_s * rho_s * (bmag / 1e4)); // Normalise magnetic field - Bpxy /= (bmag / 1.e4); - Btxy /= (bmag / 1.e4); - FieldMetric Bxy = mesh->get("Bxy"); - Bxy /= (bmag / 1.e4); + Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / (bmag / 1.e4); + tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + + Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / (bmag / 1.e4); + tokamak_coordinates_factory.set_Btxy(new_Btxy); + + Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / (bmag / 1.e4); + tokamak_coordinates_factory.set_Bxy(new_Bxy); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - coord->setDx(dx); - /**************** SET EVOLVING VARIABLES *************/ @@ -163,7 +164,7 @@ class CWM : public PhysicsModel { // add evolving variables to the communication object SOLVE_FOR(rho, te); - SAVE_ONCE(Rxy, Bpxy, Btxy, Zxy, hthe); + SAVE_ONCE(tokamak_coordinates_factory.get_Rxy(), tokamak_coordinates_factory.get_Bpxy(), tokamak_coordinates_factory.get_Btxy(), Zxy, tokamak_coordinates_factory.get_hthe()); SAVE_ONCE(nu_hat, hthe0); // Create a solver for the Laplacian diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index c70ae79bf7..40215bced7 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -159,16 +159,29 @@ class Alfven : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - // Load metric coefficients from the mesh - Field2D Rxy, Bpxy, Btxy, hthe, sinty; - GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics - Rxy /= Lnorm; - hthe /= Lnorm; - sinty *= SQ(Lnorm) * Bnorm; + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - Bpxy /= Bnorm; - Btxy /= Bnorm; + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lnorm;; + tokamak_coordinates_factory.set_Rxy(new_Rxy); + + FieldMetric new_hthe = tokamak_coordinates_factory.get_hthe() / Lnorm;; + tokamak_coordinates_factory.set_hthe(new_hthe); + + FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * SQ(Lnorm) * Bnorm; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + + BoutReal sbp = 1.0; // Sign of Bp + if (min(tokamak_coordinates_factory.get_Bpxy(), true) < 0.0) { + sbp = -1.0; + } + + Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bnorm; + tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + + Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bnorm; + tokamak_coordinates_factory.set_Btxy(new_Btxy); // Check type of parallel transform std::string ptstr = @@ -176,20 +189,13 @@ class Alfven : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Using shifted metric method - sinty = 0.0; // I disappears from metric - } - - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); // I disappears from metric } FieldMetric Bxy = mesh->get("Bxy"); Bxy /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, sinty); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); - // Checking for dpsi and qinty used in BOUT grids Field2D dx; if (!mesh->get(dx, "dpsi")) { diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index bd22733d6f..356ad71536 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -100,23 +100,6 @@ class DALF3 : public PhysicsModel { b0xcv.covariant = false; // Read contravariant components mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, hthe; - Field2D I; // Shear factor - - if (mesh->get(Rxy, "Rxy")) { // m - output_error.write("Error: Cannot read Rxy from grid\n"); - return 1; - } - if (mesh->get(Bpxy, "Bpxy")) { // T - output_error.write("Error: Cannot read Bpxy from grid\n"); - return 1; - } - mesh->get(Btxy, "Btxy"); // T - mesh->get(B0, "Bxy"); // T - mesh->get(hthe, "hthe"); // m - mesh->get(I, "sinty"); // m^-2 T^-1 - ////////////////////////////////////////////////////////////// // Options @@ -242,7 +225,7 @@ class DALF3 : public PhysicsModel { Btxy /= Bnorm; B0 /= Bnorm; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 3a0d6c62ff..b09136b3fd 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -288,10 +288,6 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, B0, hthe; - Field2D I; // Shear factor - const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass const BoutReal Me = 9.1094e-31; // Electron mass @@ -375,17 +371,6 @@ class ELMpb : public PhysicsModel { b0xcv.covariant = false; // Read contravariant components mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - // Load metrics - if (mesh->get(Rxy, "Rxy") != 0) { // m - throw BoutException("Error: Cannot read Rxy from grid\n"); - } - if (mesh->get(Bpxy, "Bpxy") != 0) { // T - throw BoutException("Error: Cannot read Bpxy from grid\n"); - } - mesh->get(Btxy, "Btxy"); // T - mesh->get(B0, "Bxy"); // T - mesh->get(hthe, "hthe"); // m - mesh->get(I, "sinty"); // m^-2 T^-1 mesh->get(Psixy, "psixy"); // get Psi mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux @@ -1211,7 +1196,7 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); ////////////////////////////////////////////////////////////// diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 58cb3c7348..8b4d64f584 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -230,10 +230,6 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, B0, hthe; - Field2D I; // Shear factor - const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass const BoutReal Me = 9.1094e-31; // Electron mass @@ -316,22 +312,11 @@ class ELMpb : public PhysicsModel { b0xcv.covariant = false; // Read contravariant components mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - // Load metrics - if (mesh->get(Rxy, "Rxy")) { // m - throw BoutException("Error: Cannot read Rxy from grid\n"); - } - if (mesh->get(Bpxy, "Bpxy")) { // T - throw BoutException("Error: Cannot read Bpxy from grid\n"); - } - mesh->get(Btxy, "Btxy"); // T - mesh->get(B0, "Bxy"); // T - mesh->get(hthe, "hthe"); // m - mesh->get(I, "sinty"); // m^-2 T^-1 mesh->get(Psixy, "psixy"); // get Psi mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); // Set locations of staggered variables @@ -662,7 +647,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Bpxy() * Dphi0 / B0; + V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / B0; if (simple_rmp) { include_rmp = true; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 556a0759b4..96fbe67b5b 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -182,17 +182,6 @@ class GEM : public PhysicsModel { flat_temp = options["flat_temp"].withDefault(-1.0); flat_dens = options["flat_dens"].withDefault(-1.0); - ////////////////////////////////// - // Read profiles - - // Mesh - Field2D Rxy, Bpxy, Btxy, Bxy, hthe; - GRID_LOAD(Rxy); // Major radius [m] - GRID_LOAD(Bpxy); // Poloidal B field [T] - GRID_LOAD(Btxy); // Toroidal B field [T] - GRID_LOAD(Bxy); // Total B field [T] - GRID_LOAD(hthe); // Poloidal arc length [m / radian] - GRID_LOAD(Te0); // Electron temperature in eV GRID_LOAD(Ni0); // Ion number density in 10^20 m^-3 @@ -253,9 +242,12 @@ class GEM : public PhysicsModel { Tbar = options["Tbar"].withDefault(Tbar); // Override in options file SAVE_ONCE(Tbar); // Timescale in seconds + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { - Bbar = max(Bxy, true); + Bbar = max(tokamak_coordinates_factory.get_Bxy(), true); } } Bbar = options["Bbar"].withDefault(Bbar); // Override in options file @@ -352,20 +344,24 @@ class GEM : public PhysicsModel { output << "\tNormalised rho_e = " << rho_e << endl; output << "\tNormalised rho_i = " << rho_i << endl; - ////////////////////////////////// - // Metric tensor components - // Normalise - hthe /= Lbar; // parallel derivatives normalised to Lperp - Bpxy /= Bbar; - Btxy /= Bbar; - Bxy /= Bbar; + // parallel derivatives normalised to Lperp + FieldMetric new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; + tokamak_coordinates_factory.set_hthe(new_hthe); - Rxy /= rho_s; // Perpendicular derivatives normalised to rho_s + Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; + tokamak_coordinates_factory.set_Bxy(new_Bxy); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, 0.0); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bbar; + tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + + Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bbar; + tokamak_coordinates_factory.set_Btxy(new_Btxy); + + // Perpendicular derivatives normalised to rho_s + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; + tokamak_coordinates_factory.set_Rxy(new_Rxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); @@ -373,7 +369,7 @@ class GEM : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = Bpxy / hthe; + B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); B0vec.z = 0.; // Precompute this for use in RHS diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 6535ca2f88..4adb771c54 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -170,30 +170,9 @@ class Alfven : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - // Load metric coefficients from the mesh - Field2D Rxy, Bpxy, Btxy, hthe, sinty; - GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics - Rxy /= Lnorm; - hthe /= Lnorm; - sinty *= SQ(Lnorm) * Bnorm; - - Bpxy /= Bnorm; - Btxy /= Bnorm; - - // Calculate metric components - sinty = 0.0; // I disappears from metric for shifted coordinates - - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - FieldMetric Bxy = mesh->get("Bxy"); - Bxy /= Bnorm; - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, sinty); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 920bee3635..259acb0e91 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -7,24 +7,17 @@ using bout::globals::mesh; int main(int argc, char** argv) { + BoutInitialise(argc, argv); /////////////////////////////////////// bool calc_metric; calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { - // Read metric tensor - Field2D Rxy, Btxy, Bpxy, B0, hthe, I; - mesh->get(Rxy, "Rxy"); // m - mesh->get(Btxy, "Btxy"); // T - mesh->get(Bpxy, "Bpxy"); // T - mesh->get(B0, "Bxy"); // T - mesh->get(hthe, "hthe"); // m - mesh->get(I, "sinty"); // m^-2 T^-1 - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.make_tokamak_coordinates(); } + /////////////////////////////////////// // Read an analytic input diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index b23af3e375..8091238304 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -16,23 +16,17 @@ class WaveTest : public PhysicsModel { public: int init(bool UNUSED(restarting)) { - Field2D Rxy, Bpxy, Btxy, hthe, I; - GRID_LOAD(Rxy); - GRID_LOAD(Bpxy); - GRID_LOAD(Btxy); - GRID_LOAD(hthe); - const auto& Bxy = mesh->get("Bxy"); + + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + int ShiftXderivs = 0; mesh->get(ShiftXderivs, "false"); if (ShiftXderivs) { // No integrated shear in metric - I = 0.0; - } else { - mesh->get(I, "sinty"); - } - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + } solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 055927bbaa..b98bb60908 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -9,51 +9,69 @@ class TokamakCoordinatesFactory { private: Mesh& mesh_m; - const Field2D& Rxy_m; - const Field2D& Bpxy_m; - const Field2D& Btxy_m; - const FieldMetric& B_m; - const FieldMetric& hthe_m; - const FieldMetric& I_m; + Field2D Rxy_m; + Field2D Bpxy_m; + Field2D Btxy_m; + Field2D Bxy_m; + FieldMetric hthe_m; + FieldMetric ShearFactor_m; + FieldMetric sign_of_bp; + public: - TokamakCoordinatesFactory(Mesh& mesh, const Field2D& Rxy, const Field2D& Bpxy, const Field2D& Btxy, const FieldMetric& B, const FieldMetric& hthe, const FieldMetric& I) - : mesh_m(mesh), Rxy_m(Rxy), Bpxy_m(Bpxy), Btxy_m(Btxy), B_m(B), hthe_m(hthe), I_m(I) {} + TokamakCoordinatesFactory(Mesh& mesh) + : mesh_m(mesh) { + + mesh.get(Rxy_m, "Rxy"); + // mesh->get(Zxy, "Zxy"); + mesh.get(Bpxy_m, "Bpxy"); + mesh.get(Btxy_m, "Btxy"); + mesh.get(Bxy_m, "Bxy"); + mesh.get(hthe_m, "hthe"); + mesh.get(ShearFactor_m, "sinty"); + } - Coordinates* make_tokamak_coordinates(const BoutReal& sign_of_bp = 1.0) const + Coordinates* make_tokamak_coordinates() { auto* coord = mesh_m.getCoordinates(); - const auto g11 = SQ(Rxy() * Bpxy()); - const auto g22 = 1.0 / SQ(hthe()); - const auto g33 = SQ(I()) * g11 + SQ(B()) / g11; + const auto g11 = SQ(Rxy_m * Bpxy_m); + const auto g22 = 1.0 / SQ(hthe_m); + const auto g33 = SQ(ShearFactor_m) * g11 + SQ(Bxy_m) / g11; const auto g12 = 0.0; - const auto g13 = -I() * g11; - const auto g23 = -sign_of_bp * Btxy() / (hthe() * Bpxy() * Rxy()); + const auto g13 = -ShearFactor_m * g11; + const auto g23 = -sign_of_bp * Btxy_m / (hthe_m * Bpxy_m * Rxy_m); - const auto g_11 = 1.0 / g11 + SQ(I() * Rxy()); - const auto g_22 = SQ(B() * hthe() / Bpxy()); - const auto g_33 = Rxy() * Rxy(); - const auto g_12 = sign_of_bp * Btxy() * hthe() * I() * Rxy() / Bpxy(); - const auto g_13 = I() * Rxy() * Rxy(); - const auto g_23 = sign_of_bp * Btxy() * hthe() * Rxy() / Bpxy(); + const auto g_11 = 1.0 / g11 + SQ(ShearFactor_m * Rxy_m); + const auto g_22 = SQ(Bxy_m * hthe_m / Bpxy_m); + const auto g_33 = Rxy_m * Rxy_m; + const auto g_12 = sign_of_bp * Btxy_m * hthe_m * ShearFactor_m * Rxy_m / Bpxy_m; + const auto g_13 = ShearFactor_m * Rxy_m * Rxy_m; + const auto g_23 = sign_of_bp * Btxy_m * hthe_m * Rxy_m / Bpxy_m; coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - coord->setJ(hthe() / Bpxy()); - coord->setBxy(B()); + coord->setJ(hthe_m / Bpxy_m); + coord->setBxy(Bxy_m); return coord; } - const Field2D& Rxy() const { return Rxy_m; } - const Field2D& Bpxy() const { return Bpxy_m; } - const Field2D& Btxy() const { return Btxy_m; } - const FieldMetric& B() const { return B_m; } - const FieldMetric& hthe() const { return hthe_m; } - const FieldMetric& I() const { return I_m; } + const Field2D& get_Rxy() const { return Rxy_m; } + const Field2D& get_Bpxy() const { return Bpxy_m; } + const Field2D& get_Btxy() const { return Btxy_m; } + const Field2D& get_Bxy() const { return Bxy_m; } + const FieldMetric& get_hthe() const { return hthe_m; } + const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } + + void set_Rxy(Field2D Rxy) { Rxy_m = Rxy; } + void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } + void set_Bxy(Field2D& Bxy) { Bxy_m = Bxy; } + void set_Bpxy(Field2D& Bpxy) { Bpxy_m = Bpxy; } + void set_Btxy(Field2D& Btxy) { Btxy_m = Btxy; } + void set_hthe(FieldMetric& hthe) { hthe_m = hthe; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index d9c61254f6..8928c05e59 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -349,8 +349,8 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe, sinty); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, coords->Bxy(), hthe, sinty); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index dc586c0535..ebe7511a75 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, B0, hthe, I); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, B0, hthe, I); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); // Set B field vector diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 5e73c7f928..9042d92abe 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -212,8 +212,8 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, I); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 5abf0bc187..42e769b2e7 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -26,9 +26,6 @@ class Interchange : public PhysicsModel { // Derived 3D variables Field3D phi; - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, hthe; - // Parameters BoutReal Te_x, Ti_x, Ni_x, bmag, rho_s, AA, ZZ, wci; @@ -56,13 +53,6 @@ class Interchange : public PhysicsModel { b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY - // Load metrics - GRID_LOAD(Rxy); - GRID_LOAD(Bpxy); - GRID_LOAD(Btxy); - GRID_LOAD(hthe); - mesh->get(I, "sinty"); - // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); @@ -134,8 +124,8 @@ class Interchange : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, Bxy, hthe, I); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, I); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); coord->setDx(mesh->get("dpsi")); coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 949e673b11..4cb3bc97c9 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -45,6 +45,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { sbp = -1.0; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, Rxy, Bpxy, Btxy, coords->Bxy(), hthe, sinty); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, coords->Bxy(), hthe, sinty); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); } From 1189daddef7edb0ff10dcf597a81a0fea79b47fe Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 8 Nov 2024 16:21:53 +0000 Subject: [PATCH 22/98] More fixes --- examples/6field-simple/elm_6f.cxx | 122 +++++++++++-------- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/gyro-gem/gem.cxx | 2 +- include/bout/tokamak_coordinates_factory.hxx | 12 +- 5 files changed, 78 insertions(+), 62 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 76966c306b..0152469ebb 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -235,6 +235,8 @@ class Elm_6f : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + BoutReal LnLambda; // ln(Lambda) /// Ion mass @@ -364,7 +366,7 @@ class Elm_6f : public PhysicsModel { result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * tokamak_coordinates_factory.getBxy(); + result -= bracket(Psi, f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); } } @@ -675,9 +677,10 @@ class Elm_6f : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += I * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; } - I = 0.0; + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } ////////////////////////////////////////////////////////////// @@ -820,20 +823,32 @@ class Elm_6f : public PhysicsModel { dump.add(sp_length, "sp_length", 1); } - J0 = SI::mu0 * Lbar * J0 / B0; + J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); b0xcv.x /= Bbar; b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - Rxy /= Lbar; - Bpxy /= Bbar; - Btxy /= Bbar; - B0 /= Bbar; - hthe /= Lbar; + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lbar; + tokamak_coordinates_factory.set_Rxy(new_Rxy); + + Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bbar; + tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + + Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bbar; + tokamak_coordinates_factory.set_Btxy(new_Btxy); + + Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; + tokamak_coordinates_factory.set_Bxy(new_Bxy); + + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; + tokamak_coordinates_factory.set_hthe(new_hthe); + + FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * Lbar * Lbar * Bbar; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + Field2D dx; - I *= Lbar * Lbar * Bbar; if ((!T0_fake_prof) && n0_fake_prof) { N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); @@ -900,7 +915,7 @@ class Elm_6f : public PhysicsModel { q95 = q95_input; // use a constant for test } else { if (local_q) { - q95 = abs(hthe * Btxy / (Bpxy)) * q_alpha; + q95 = abs(tokamak_coordinates_factory.get_hthe() * tokamak_coordinates_factory.get_Btxy() / tokamak_coordinates_factory.get_Bpxy()) * q_alpha; } else { output.write("\tUsing q profile from grid.\n"); if (mesh->get(q95, "q")) { @@ -1016,7 +1031,6 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); coord->setDx(dx / (Lbar * Lbar * Bbar)); @@ -1025,14 +1039,16 @@ class Elm_6f : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(I); + coord->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); } else { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += I * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; } - I = 0.0; // I disappears from metric + // I disappears from metric + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } @@ -1040,22 +1056,22 @@ class Elm_6f : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = Bpxy / hthe; + B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); B0vec.z = 0.; // Set V0vec field vector V0vec.covariant = false; V0vec.x = 0.; - V0vec.y = Vp0 / hthe; - V0vec.z = Vt0 / Rxy; + V0vec.y = Vp0 / tokamak_coordinates_factory.get_hthe(); + V0vec.z = Vt0 / tokamak_coordinates_factory.get_Rxy(); // Set V0eff field vector V0eff.covariant = false; V0eff.x = 0.; - V0eff.y = -(Btxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / hthe; - V0eff.z = (Bpxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / Rxy; + V0eff.y = -(tokamak_coordinates_factory.get_Btxy() / (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy())) * (Vp0 * tokamak_coordinates_factory.get_Btxy() - Vt0 * tokamak_coordinates_factory.get_Bpxy()) / tokamak_coordinates_factory.get_hthe(); + V0eff.z = (tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy())) * (Vp0 * tokamak_coordinates_factory.get_Btxy() - Vt0 * tokamak_coordinates_factory.get_Bpxy()) / tokamak_coordinates_factory.get_Rxy(); Pe.setBoundary("P"); Pi.setBoundary("P"); @@ -1097,10 +1113,10 @@ class Elm_6f : public PhysicsModel { if (diamag && diamag_phi0) { if (experiment_Er) { // get phi0 from grid file mesh->get(phi0, "Phi_0"); - phi0 /= B0 * Lbar * Va; + phi0 /= tokamak_coordinates_factory.get_Bxy() * Lbar * Va; } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -Upara0 * Pi0 / B0 / N0; + phi0 = -Upara0 * Pi0 / tokamak_coordinates_factory.get_Bxy() / N0; } SAVE_ONCE(phi0); } @@ -1110,7 +1126,7 @@ class Elm_6f : public PhysicsModel { SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); SAVE_ONCE(Tibar, Tebar, Nbar); - SAVE_ONCE(Va, B0); + SAVE_ONCE(Va, tokamak_coordinates_factory.get_Bxy()); SAVE_ONCE(Ti0, Te0, N0); // Create a solver for the Laplacian @@ -1133,13 +1149,13 @@ class Elm_6f : public PhysicsModel { Field2D logn0 = laplace_alpha * N0; Field3D Ntemp; Ntemp = N0; - ubyn = U * B0 / Ntemp; + ubyn = U * tokamak_coordinates_factory.get_Bxy() / Ntemp; // Phi should be consistent with U if (laplace_alpha <= 0.0) { - phi = phiSolver->solve(ubyn) / B0; + phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.get_Bxy(); } else { phiSolver->setCoefC(logn0); - phi = phiSolver->solve(ubyn) / B0; + phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.get_Bxy(); } } @@ -1213,9 +1229,9 @@ class Elm_6f : public PhysicsModel { // Field2D lap_temp=0.0; Field2D logn0 = laplace_alpha * N0; - ubyn = U * B0 / N0; + ubyn = U * tokamak_coordinates_factory.get_Bxy() / N0; if (diamag) { - ubyn -= Upara0 / N0 * Delp2(Pi) / B0; + ubyn -= Upara0 / N0 * Delp2(Pi) / tokamak_coordinates_factory.get_Bxy(); mesh->communicate(ubyn); ubyn.applyBoundary(); } @@ -1223,7 +1239,7 @@ class Elm_6f : public PhysicsModel { if (laplace_alpha > 0.0) { phiSolver->setCoefC(logn0); } - phi = phiSolver->solve(ubyn) / B0; + phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.get_Bxy(); mesh->communicate(phi); @@ -1319,9 +1335,9 @@ class Elm_6f : public PhysicsModel { if (compress0) { if (nonlinear) { - Vepar = Vipar - B0 * (Jpar) / N_tmp * Vepara; + Vepar = Vipar - tokamak_coordinates_factory.get_Bxy() * (Jpar) / N_tmp * Vepara; } else { - Vepar = Vipar - B0 * (Jpar) / N0 * Vepara; + Vepar = Vipar - tokamak_coordinates_factory.get_Bxy() * (Jpar) / N0 * Vepara; Vepar.applyBoundary(); mesh->communicate(Vepar); } @@ -1359,13 +1375,13 @@ class Elm_6f : public PhysicsModel { ddt(Psi) = 0.0; if (spitzer_resist) { - ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta_spitzer * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.get_Bxy() * phi) / tokamak_coordinates_factory.get_Bxy() - eta_spitzer * Jpar; } else { - ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.get_Bxy() * phi) / tokamak_coordinates_factory.get_Bxy() - eta * Jpar; } if (diamag) { - ddt(Psi) -= bracket(B0 * phi0, Psi, bm_exb); // Equilibrium flow + ddt(Psi) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Psi, bm_exb); // Equilibrium flow } // Hyper-resistivity @@ -1382,18 +1398,18 @@ class Elm_6f : public PhysicsModel { ddt(U) = 0.0; - ddt(U) = -SQ(B0) * bracket(Psi, J0, bm_mag) * B0; // Grad j term + ddt(U) = -SQ(tokamak_coordinates_factory.get_Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates_factory.get_Bxy(); // Grad j term ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term - ddt(U) += SQ(B0) * Grad_parP(Jpar); // b dot grad j + ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar); // b dot grad j if (diamag) { - ddt(U) -= bracket(B0 * phi0, U, bm_exb); // Equilibrium flow + ddt(U) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, U, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(U) -= bracket(B0 * phi, U, bm_exb); // Advection + ddt(U) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, U, bm_exb); // Advection } // parallel hyper-viscous diffusion for vector potential @@ -1445,18 +1461,18 @@ class Elm_6f : public PhysicsModel { ddt(Ni) = 0.0; - ddt(Ni) -= bracket(B0 * phi, N0, bm_exb); + ddt(Ni) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, N0, bm_exb); if (diamag) { - ddt(Ni) -= bracket(B0 * phi0, Ni, bm_exb); // Equilibrium flow + ddt(Ni) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Ni, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ni) -= bracket(B0 * phi, Ni, bm_exb); // Advection + ddt(Ni) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Ni, bm_exb); // Advection } if (compress0) { - ddt(Ni) -= N0 * B0 * Grad_parP(Vipar / B0); + ddt(Ni) -= N0 * tokamak_coordinates_factory.get_Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.get_Bxy()); } // 4th order Parallel diffusion terms @@ -1475,18 +1491,18 @@ class Elm_6f : public PhysicsModel { ddt(Ti) = 0.0; - ddt(Ti) -= bracket(B0 * phi, Ti0, bm_exb); + ddt(Ti) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Ti0, bm_exb); if (diamag) { - ddt(Ti) -= bracket(phi0 * B0, Ti, bm_exb); // Equilibrium flow + ddt(Ti) -= bracket(phi0 * tokamak_coordinates_factory.get_Bxy(), Ti, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ti) -= bracket(phi * B0, Ti, bm_exb); // Advection + ddt(Ti) -= bracket(phi * tokamak_coordinates_factory.get_Bxy(), Ti, bm_exb); // Advection } if (compress0) { - ddt(Ti) -= 2.0 / 3.0 * Ti0 * B0 * Grad_parP(Vipar / B0); + ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates_factory.get_Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.get_Bxy()); } if (diffusion_par > 0.0) { @@ -1511,18 +1527,18 @@ class Elm_6f : public PhysicsModel { ddt(Te) = 0.0; - ddt(Te) -= bracket(B0 * phi, Te0, bm_exb); + ddt(Te) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Te0, bm_exb); if (diamag) { - ddt(Te) -= bracket(B0 * phi0, Te, bm_exb); // Equilibrium flow + ddt(Te) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Te, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Te) -= bracket(B0 * phi, Te, bm_exb); // Advection + ddt(Te) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Te, bm_exb); // Advection } if (compress0) { - ddt(Te) -= 2.0 / 3.0 * Te0 * B0 * Grad_parP(Vepar / B0); + ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates_factory.get_Bxy() * Grad_parP(Vepar / tokamak_coordinates_factory.get_Bxy()); } if (diffusion_par > 0.0) { @@ -1545,14 +1561,14 @@ class Elm_6f : public PhysicsModel { ddt(Vipar) = 0.0; ddt(Vipar) -= Vipara * Grad_parP(P) / N0; - ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * B0 / N0; + ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * tokamak_coordinates_factory.get_Bxy() / N0; if (diamag) { - ddt(Vipar) -= bracket(B0 * phi0, Vipar, bm_exb); + ddt(Vipar) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Vipar, bm_exb); } if (nonlinear) { - ddt(Vipar) -= bracket(B0 * phi, Vipar, bm_exb); + ddt(Vipar) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Vipar, bm_exb); } // parallel hyper-viscous diffusion for vector potential diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index f8aadb2595..da907788ee 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -135,7 +135,7 @@ class CWM : public PhysicsModel { Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; tokamak_coordinates_factory.set_Rxy(new_Rxy); - FieldMetric new_hthe = tokamak_coordinates_factory.get_hthe() / rho_s; + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / rho_s; tokamak_coordinates_factory.set_hthe(new_hthe); FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * rho_s * rho_s * (bmag / 1e4) * ShearFactor; diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 40215bced7..7302c9a627 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -166,7 +166,7 @@ class Alfven : public PhysicsModel { Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lnorm;; tokamak_coordinates_factory.set_Rxy(new_Rxy); - FieldMetric new_hthe = tokamak_coordinates_factory.get_hthe() / Lnorm;; + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lnorm;; tokamak_coordinates_factory.set_hthe(new_hthe); FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * SQ(Lnorm) * Bnorm; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 96fbe67b5b..5486e1725e 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -347,7 +347,7 @@ class GEM : public PhysicsModel { // Normalise // parallel derivatives normalised to Lperp - FieldMetric new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; tokamak_coordinates_factory.set_hthe(new_hthe); Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index b98bb60908..d83d4ad0ec 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -13,9 +13,9 @@ private: Field2D Bpxy_m; Field2D Btxy_m; Field2D Bxy_m; - FieldMetric hthe_m; + Field2D hthe_m; FieldMetric ShearFactor_m; - FieldMetric sign_of_bp; + BoutReal sign_of_bp; public: @@ -63,15 +63,15 @@ public: const Field2D& get_Bpxy() const { return Bpxy_m; } const Field2D& get_Btxy() const { return Btxy_m; } const Field2D& get_Bxy() const { return Bxy_m; } - const FieldMetric& get_hthe() const { return hthe_m; } + const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } void set_Rxy(Field2D Rxy) { Rxy_m = Rxy; } - void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } - void set_Bxy(Field2D& Bxy) { Bxy_m = Bxy; } void set_Bpxy(Field2D& Bpxy) { Bpxy_m = Bpxy; } void set_Btxy(Field2D& Btxy) { Btxy_m = Btxy; } - void set_hthe(FieldMetric& hthe) { hthe_m = hthe; } + void set_Bxy(Field2D& Bxy) { Bxy_m = Bxy; } + void set_hthe(Field2D& hthe) { hthe_m = hthe; } + void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } }; From b7d1bff5e352787b4832495eb1da14642ed1ab75 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 18:03:07 +0000 Subject: [PATCH 23/98] Getters for Rxy, Bpxy, Btxy, Bxy, and hthe cannot be const as `DataFileFacade.addOnce` method does not take const arguments. --- include/bout/tokamak_coordinates_factory.hxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index d83d4ad0ec..40573219f0 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -59,11 +59,11 @@ public: return coord; } - const Field2D& get_Rxy() const { return Rxy_m; } - const Field2D& get_Bpxy() const { return Bpxy_m; } - const Field2D& get_Btxy() const { return Btxy_m; } - const Field2D& get_Bxy() const { return Bxy_m; } - const Field2D& get_hthe() const { return hthe_m; } + Field2D& get_Rxy() { return Rxy_m; } + Field2D& get_Bpxy() { return Bpxy_m; } + Field2D& get_Btxy() { return Btxy_m; } + Field2D& get_Bxy() { return Bxy_m; } + Field2D& get_hthe() { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } void set_Rxy(Field2D Rxy) { Rxy_m = Rxy; } From 47fbd3f7a32f2600bf9e275398758b46c0765286 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 18:08:26 +0000 Subject: [PATCH 24/98] Fixes to dalf3 example --- examples/dalf3/dalf3.cxx | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 356ad71536..523cc6d19a 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -150,6 +150,9 @@ class DALF3 : public PhysicsModel { return 1; } + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + // SHIFTED RADIAL COORDINATES // Check type of parallel transform @@ -158,8 +161,9 @@ class DALF3 : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system - b0xcv.z += I * b0xcv.x; - I = 0.0; // I disappears from metric + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + FieldMetric new_ShearFactor = 0.0; // I disappears from metric + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } /////////////////////////////////////////////////// @@ -218,15 +222,24 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - Rxy /= rho_s; - hthe /= rho_s; - I *= rho_s * rho_s * Bnorm; - Bpxy /= Bnorm; - Btxy /= Bnorm; - B0 /= Bnorm; - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; + tokamak_coordinates_factory.set_Rxy(new_Rxy); + + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / rho_s; + tokamak_coordinates_factory.set_hthe(new_hthe); + + FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * rho_s * rho_s * Bnorm; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + + Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bnorm; + tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + + Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bnorm; + tokamak_coordinates_factory.set_Btxy(new_Btxy); + + Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bnorm; + tokamak_coordinates_factory.set_Bxy(new_Bxy); coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); From a45cb001cbf5fcf37b4345de32dbc3e793a2a6a5 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 21:21:59 +0000 Subject: [PATCH 25/98] Fixes to elm_pb example --- examples/elm-pb/elm_pb.cxx | 141 ++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 63 deletions(-) diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 8b4d64f584..5174b56646 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -230,6 +230,8 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass const BoutReal Me = 9.1094e-31; // Electron mass @@ -316,7 +318,6 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); // Set locations of staggered variables @@ -647,7 +648,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / B0; + V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); if (simple_rmp) { include_rmp = true; @@ -742,9 +743,10 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += I * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; } - I = 0.0; + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } ////////////////////////////////////////////////////////////// @@ -752,14 +754,15 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(I); + metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); } else { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += I * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; } - I = 0.0; // I disappears from metric + FieldMetric new_ShearFactor = 0.0; // I disappears from metric + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } ////////////////////////////////////////////////////////////// @@ -875,7 +878,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / B0; + J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -884,13 +887,25 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - Rxy /= Lbar; - Bpxy /= Bbar; - Btxy /= Bbar; - B0 /= Bbar; - hthe /= Lbar; + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lbar; + tokamak_coordinates_factory.set_Rxy(new_Rxy); + + Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bbar; + tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + + Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bbar; + tokamak_coordinates_factory.set_Btxy(new_Btxy); + + Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; + tokamak_coordinates_factory.set_Bxy(new_Bxy); + + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; + tokamak_coordinates_factory.set_hthe(new_hthe); + + FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * Lbar * Lbar * Bbar; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + metric->setDx(metric->dx() / (Lbar * Lbar * Bbar)); - I *= Lbar * Lbar * Bbar; if (constn0) { T0_fake_prof = false; @@ -1021,15 +1036,15 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = Bpxy / hthe; + B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; + V0net.y = tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Btxy() * tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_hthe() * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory.get_Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1052,8 +1067,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); - gradparB = Grad_par(B0) / B0; + beta = tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (0.5 + (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates_factory.get_Bxy()) / tokamak_coordinates_factory.get_Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1086,10 +1101,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / B0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / B0 / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy() / N0; } SAVE_ONCE(phi0); } @@ -1098,7 +1113,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, B0); + SAVE_ONCE(Va, tokamak_coordinates_factory.get_Bxy()); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { @@ -1165,10 +1180,10 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; + result -= bracket(interp_to(Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); } } @@ -1304,12 +1319,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / B0; + phi -= 0.5 * dnorm * P / tokamak_coordinates_factory.get_Bxy(); } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates_factory.get_Bxy()) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1454,9 +1469,9 @@ class ELMpb : public PhysicsModel { if (evolve_jpar) { // Jpar - Field3D B0U = B0 * U; + Field3D B0U = tokamak_coordinates_factory.get_Bxy() * U; mesh->communicate(B0U); - ddt(Jpar) = -Grad_parP(B0U, loc) / B0 + eta * Delp2(Jpar); + ddt(Jpar) = -Grad_parP(B0U, loc) / tokamak_coordinates_factory.get_Bxy() + eta * Delp2(Jpar); if (relax_j_vac) { // Make ddt(Jpar) relax to zero. @@ -1465,16 +1480,16 @@ class ELMpb : public PhysicsModel { } } else { // Vector potential - ddt(Psi) = -Grad_parP(phi * B0, loc) / B0 + eta * Jpar; + ddt(Psi) = -Grad_parP(phi * tokamak_coordinates_factory.get_Bxy(), loc) / tokamak_coordinates_factory.get_Bxy() + eta * Jpar; if (eHall) { // electron parallel pressure ddt(Psi) += 0.25 * delta_i - * (Grad_parP(B0 * P, loc) / B0 - + bracket(interp_to(P0, loc), Psi, bm_mag) * B0); + * (Grad_parP(tokamak_coordinates_factory.get_Bxy() * P, loc) / tokamak_coordinates_factory.get_Bxy() + + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates_factory.get_Bxy()); } if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * B0; + ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates_factory.get_Bxy(); } if (withflow) { // net flow @@ -1482,7 +1497,7 @@ class ELMpb : public PhysicsModel { } if (diamag_grad_t) { // grad_par(T_e) correction - ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; + ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates_factory.get_Bxy(); } if (hyperresist > 0.0) { // Hyper-resistivity @@ -1520,15 +1535,15 @@ class ELMpb : public PhysicsModel { Psi_loc = interp_to(Psi, CELL_CENTRE, "RGN_ALL"); Psi_loc.applyBoundary(); // Grad j term - ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); + ddt(U) = SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); if (include_rmp) { - ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } ddt(U) += b0xcv * Grad(P); // curvature term if (!nogradparj) { // Parallel current term - ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j } if (withflow && K_H_term) { // K_H_term @@ -1544,7 +1559,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(U) -= bracket(phi, U, bm_exb) * B0; + ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates_factory.get_Bxy(); } // Viscosity terms @@ -1588,11 +1603,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); + Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates_factory.get_Bxy() * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(B0 * phi); + Dperp2Phi = Delp2(tokamak_coordinates_factory.get_Bxy() * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1604,35 +1619,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); + bracketPhi0P = bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(tokamak_coordinates_factory.get_Bxy() * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; - Field3D B0phi = B0 * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); - Field3D B0phi0 = B0 * phi0; + Field3D B0phi0 = tokamak_coordinates_factory.get_Bxy() * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates_factory.get_Bxy(); if (nonlinear) { - Field3D B0phi = B0 * phi; + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates_factory.get_Bxy(); } } @@ -1662,7 +1677,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(P) -= bracket(phi, P, bm_exb) * B0; + ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates_factory.get_Bxy(); } } @@ -1707,7 +1722,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates_factory.get_Bxy(); // Advection } } @@ -1798,7 +1813,7 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1807,7 +1822,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * B0 * B0); + invU->setCoefB(-SQ(gamma) * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -1815,9 +1830,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = B0 * phi3; + Field3D B0phi3 = tokamak_coordinates_factory.get_Bxy() * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates_factory.get_Bxy(); ddt(Psi).applyBoundary(); return 0; @@ -1849,14 +1864,14 @@ class ELMpb : public PhysicsModel { Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = B0 * phi; + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / B0; + Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates_factory.get_Bxy(); JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) - + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) + + SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); From 70eb2197a114eeee5537e9e988e46b1a500256cd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 21:49:20 +0000 Subject: [PATCH 26/98] Fix typo (double semicolons) --- examples/constraints/alfven-wave/alfven.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 7302c9a627..cc313ecaef 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -163,10 +163,10 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lnorm;; + Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lnorm; tokamak_coordinates_factory.set_Rxy(new_Rxy); - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lnorm;; + Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lnorm; tokamak_coordinates_factory.set_hthe(new_hthe); FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * SQ(Lnorm) * Bnorm; From 0cc5dac15ced2377ca0e8f42ac7b88f43fb8a4ab Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 21:51:18 +0000 Subject: [PATCH 27/98] Assign value to new (const) variable because the function is marked const. --- examples/elm-pb/elm_pb.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 5174b56646..002fb45979 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -1180,10 +1180,11 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(interp_to(Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); + const auto Bxy = tokamak_coordinates_factory.get_Bxy(); + result -= bracket(interp_to(Psi, loc), f, bm_mag) * Bxy; if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * Bxy; } } From 34c823966403b4bdb437ebc01500d92f55301a11 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 22:19:24 +0000 Subject: [PATCH 28/98] Getters for Rxy, Bpxy, Btxy, Bxy, and hthe can be const but need to copy value to a non-const variable to pass to `DataFileFacade.addOnce` method. --- examples/6field-simple/elm_6f.cxx | 3 ++- examples/conducting-wall-mode/cwm.cxx | 6 +++++- examples/elm-pb/elm_pb.cxx | 3 ++- include/bout/tokamak_coordinates_factory.hxx | 10 +++++----- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 0152469ebb..f770837374 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1126,7 +1126,8 @@ class Elm_6f : public PhysicsModel { SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); SAVE_ONCE(Tibar, Tebar, Nbar); - SAVE_ONCE(Va, tokamak_coordinates_factory.get_Bxy()); + Field2D tmp = tokamak_coordinates_factory.get_Bxy(); + SAVE_ONCE(Va, tmp); SAVE_ONCE(Ti0, Te0, N0); // Create a solver for the Laplacian diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index da907788ee..f9aae313e1 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -164,7 +164,11 @@ class CWM : public PhysicsModel { // add evolving variables to the communication object SOLVE_FOR(rho, te); - SAVE_ONCE(tokamak_coordinates_factory.get_Rxy(), tokamak_coordinates_factory.get_Bpxy(), tokamak_coordinates_factory.get_Btxy(), Zxy, tokamak_coordinates_factory.get_hthe()); + Field2D Rxy = tokamak_coordinates_factory.get_Rxy(); + Field2D Bpxy = tokamak_coordinates_factory.get_Bpxy(); + Field2D Btxy = tokamak_coordinates_factory.get_Btxy(); + Field2D hthe = tokamak_coordinates_factory.get_hthe(); + SAVE_ONCE(Rxy, Bpxy, Btxy, Zxy, hthe); SAVE_ONCE(nu_hat, hthe0); // Create a solver for the Laplacian diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 002fb45979..db78c74c98 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -1113,7 +1113,8 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, tokamak_coordinates_factory.get_Bxy()); + Field2D tmp = tokamak_coordinates_factory.get_Bxy(); + SAVE_ONCE(Va, tmp); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 40573219f0..d83d4ad0ec 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -59,11 +59,11 @@ public: return coord; } - Field2D& get_Rxy() { return Rxy_m; } - Field2D& get_Bpxy() { return Bpxy_m; } - Field2D& get_Btxy() { return Btxy_m; } - Field2D& get_Bxy() { return Bxy_m; } - Field2D& get_hthe() { return hthe_m; } + const Field2D& get_Rxy() const { return Rxy_m; } + const Field2D& get_Bpxy() const { return Bpxy_m; } + const Field2D& get_Btxy() const { return Btxy_m; } + const Field2D& get_Bxy() const { return Bxy_m; } + const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } void set_Rxy(Field2D Rxy) { Rxy_m = Rxy; } From defefb900da2646cf82269a62f9b15a958a988da Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 22:52:45 +0000 Subject: [PATCH 29/98] Fixes to elm_pb_outerloop example --- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index b09136b3fd..914854dc39 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -704,7 +704,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -Rxy * Bpxy * Dphi0 / B0; + V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); if (simple_rmp) { include_rmp = true; @@ -799,9 +799,10 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += I * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; } - I = 0.0; + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } ////////////////////////////////////////////////////////////// @@ -917,7 +918,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / B0; + J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; From a07e508048f43b1788e8f91b4ffe347d2d23eadd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sat, 9 Nov 2024 21:52:47 +0000 Subject: [PATCH 30/98] Extract method TokamakCoordinatesFactory.normalise() --- examples/6field-simple/elm_6f.cxx | 18 +--------------- examples/conducting-wall-mode/cwm.cxx | 22 +------------------- include/bout/tokamak_coordinates_factory.hxx | 15 +++++++------ 3 files changed, 11 insertions(+), 44 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index f770837374..b69d220826 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -830,23 +830,7 @@ class Elm_6f : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lbar; - tokamak_coordinates_factory.set_Rxy(new_Rxy); - - Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bbar; - tokamak_coordinates_factory.set_Bpxy(new_Bpxy); - - Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bbar; - tokamak_coordinates_factory.set_Btxy(new_Btxy); - - Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; - tokamak_coordinates_factory.set_Bxy(new_Bxy); - - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; - tokamak_coordinates_factory.set_hthe(new_hthe); - - FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * Lbar * Lbar * Bbar; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + tokamak_coordinates_factory.normalise(Lbar, Bbar); Field2D dx; diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index f9aae313e1..edbacd69b8 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -131,29 +131,9 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; - tokamak_coordinates_factory.set_Rxy(new_Rxy); - - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / rho_s; - tokamak_coordinates_factory.set_hthe(new_hthe); - - FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * rho_s * rho_s * (bmag / 1e4) * ShearFactor; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); dx /= (rho_s * rho_s * (bmag / 1e4)); - // Normalise magnetic field - - Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / (bmag / 1.e4); - tokamak_coordinates_factory.set_Bpxy(new_Bpxy); - - Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / (bmag / 1.e4); - tokamak_coordinates_factory.set_Btxy(new_Btxy); - - Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / (bmag / 1.e4); - tokamak_coordinates_factory.set_Bxy(new_Bxy); - // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index d83d4ad0ec..cb99b598d0 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -59,6 +59,15 @@ public: return coord; } + void normalise(BoutReal Bbar, BoutReal Lbar) { + Rxy_m /= Lbar; + Bpxy_m /= Bbar; + Btxy_m / Bbar; + Bxy_m / Bbar; + hthe_m / Lbar; + ShearFactor_m *= Lbar * Lbar * Bbar; + } + const Field2D& get_Rxy() const { return Rxy_m; } const Field2D& get_Bpxy() const { return Bpxy_m; } const Field2D& get_Btxy() const { return Btxy_m; } @@ -66,12 +75,6 @@ public: const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } - void set_Rxy(Field2D Rxy) { Rxy_m = Rxy; } - void set_Bpxy(Field2D& Bpxy) { Bpxy_m = Bpxy; } - void set_Btxy(Field2D& Btxy) { Btxy_m = Btxy; } - void set_Bxy(Field2D& Bxy) { Bxy_m = Bxy; } - void set_hthe(Field2D& hthe) { hthe_m = hthe; } - void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } }; From 382884d09a84df15df96b6d76852487f90c771d9 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 11:46:29 +0000 Subject: [PATCH 31/98] Fix TokamakCoordinatesFactory method calls in elm_pb --- tests/MMS/elm-pb/elm_pb.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index ebe7511a75..ae0777e82f 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -415,8 +415,8 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, B0, hthe, I); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(); // Set B field vector From 52734552caf8ff56752b93e2847ead09d346cd54 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 11:47:52 +0000 Subject: [PATCH 32/98] Add dx to TokamakCoordinatesFactory.normalise() method --- examples/conducting-wall-mode/cwm.cxx | 1 - include/bout/tokamak_coordinates_factory.hxx | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index edbacd69b8..a5f330cec8 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -132,7 +132,6 @@ class CWM : public PhysicsModel { // Normalise geometry tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); - dx /= (rho_s * rho_s * (bmag / 1e4)); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index cb99b598d0..c853fcff00 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -15,6 +15,7 @@ private: Field2D Bxy_m; Field2D hthe_m; FieldMetric ShearFactor_m; + FieldMetric dx_m; BoutReal sign_of_bp; @@ -30,6 +31,7 @@ public: mesh.get(Bxy_m, "Bxy"); mesh.get(hthe_m, "hthe"); mesh.get(ShearFactor_m, "sinty"); + mesh.get(dx_m, "dpsi"); } Coordinates* make_tokamak_coordinates() @@ -59,13 +61,14 @@ public: return coord; } - void normalise(BoutReal Bbar, BoutReal Lbar) { + void normalise(BoutReal Lbar, BoutReal Bbar) { Rxy_m /= Lbar; Bpxy_m /= Bbar; Btxy_m / Bbar; Bxy_m / Bbar; hthe_m / Lbar; ShearFactor_m *= Lbar * Lbar * Bbar; + dx_m /= Lbar * Lbar * Bbar; } const Field2D& get_Rxy() const { return Rxy_m; } From eba046e6545c43a11e6ba6c8c0861578ff850b71 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 11:51:05 +0000 Subject: [PATCH 33/98] Use extracted methods in more examples and tests --- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 8 +----- tests/MMS/GBS/gbs.cxx | 26 ++++++------------- tests/MMS/GBS/mms-slab2d.py | 10 +------ tests/MMS/GBS/mms-slab3d.py | 10 +------ tests/MMS/tokamak/tokamak.cxx | 22 ++++++---------- .../test-drift-instability/2fluid.cxx | 16 +++--------- .../test-interchange-instability/2fluid.cxx | 17 ++---------- .../integrated/test-laplacexy/loadmetric.cxx | 23 ++++++---------- 8 files changed, 32 insertions(+), 100 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 914854dc39..2ab96abcfb 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -927,13 +927,7 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - Rxy /= Lbar; - Bpxy /= Bbar; - Btxy /= Bbar; - B0 /= Bbar; - hthe /= Lbar; - - I *= Lbar * Lbar * Bbar; + tokamak_coordinates_factory.normalise(Lbar, Bbar); if (constn0) { T0_fake_prof = false; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 8928c05e59..235d4083d3 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -314,9 +314,6 @@ int GBS::init(bool restarting) { } void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - // Load metric coefficients from the mesh - Field2D Rxy, Bpxy, Btxy, hthe, sinty; - GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics // Checking for dpsi and qinty used in BOUT grids Field2D dx; @@ -328,14 +325,15 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { output << "\tUsing dx as the x grid spacing\n"; } - Rxy /= Lnorm; - hthe /= Lnorm; - sinty *= SQ(Lnorm) * Bnorm; - coords->setDx(coords->dx() / (SQ(Lnorm) * Bnorm)); + BoutReal sbp = 1.0; // Sign of Bp + if (min(Bpxy, true) < 0.0) { + sbp = -1.0; + } + + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(); - Bpxy /= Bnorm; - Btxy /= Bnorm; - coords->setBxy(coords->Bxy() / Bnorm); + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // Calculate metric components bool ShiftXderivs; @@ -343,14 +341,6 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { if (ShiftXderivs) { sinty = 0.0; // I disappears from metric } - - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, coords->Bxy(), hthe, sinty); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); } // just define a macro for V_E dot Grad diff --git a/tests/MMS/GBS/mms-slab2d.py b/tests/MMS/GBS/mms-slab2d.py index 215e711a53..443517ab07 100644 --- a/tests/MMS/GBS/mms-slab2d.py +++ b/tests/MMS/GBS/mms-slab2d.py @@ -78,15 +78,7 @@ def C(f): bxcvz = 100 # Curvature -# Normalise - -Rxy /= rho_s0 -Bpxy /= Bnorm -Btxy /= Bnorm -Bxy /= Bnorm -hthe /= rho_s0 - -dx /= rho_s0**2 * Bnorm +tokamak_coordinates_factory.normalise(rho_s0, Bnorm); bxcvz *= rho_s0**2 diff --git a/tests/MMS/GBS/mms-slab3d.py b/tests/MMS/GBS/mms-slab3d.py index 2f958cfa69..cafff0ba76 100644 --- a/tests/MMS/GBS/mms-slab3d.py +++ b/tests/MMS/GBS/mms-slab3d.py @@ -79,15 +79,7 @@ def C(f): estatic = True -# Normalise - -Rxy /= rho_s0 -Bpxy /= Bnorm -Btxy /= Bnorm -Bxy /= Bnorm -hthe /= rho_s0 - -dx /= rho_s0**2 * Bnorm +tokamak_coordinates_factory.normalise(rho_s0, Bnorm); bxcvz *= rho_s0**2 diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 9e1f03123b..1b271ae23a 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -60,14 +60,15 @@ class TokamakMMS : public PhysicsModel { output << "\tUsing dx as the x grid spacing\n"; } - Rxy /= Lnorm; - hthe /= Lnorm; - sinty *= SQ(Lnorm) * Bnorm; - coords->setDx(coords->dx() / (SQ(Lnorm) * Bnorm)); + BoutReal sbp = 1.0; // Sign of Bp + if (min(Bpxy, true) < 0.0) { + sbp = -1.0; + } + + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(); - Bpxy /= Bnorm; - Btxy /= Bnorm; - coords->setBxy(coords->Bxy() / Bnorm); + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // Calculate metric components bool ShiftXderivs; @@ -75,13 +76,6 @@ class TokamakMMS : public PhysicsModel { if (ShiftXderivs) { sinty = 0.0; // I disappears from metric } - - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - tokamak_coordinates(coords, Rxy, Bpxy, hthe, sinty, coords->Bxy(), Btxy, sbp); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 9042d92abe..fb713fff78 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -196,15 +196,6 @@ class TwoFluid : public PhysicsModel { b0xcv.y *= rho_s * rho_s; b0xcv.z *= rho_s * rho_s; - // Normalise geometry - Rxy /= rho_s; - hthe /= rho_s; - I *= rho_s * rho_s * (bmag / 1e4) * ShearFactor; - - // Normalise magnetic field - Bpxy /= (bmag / 1.e4); - Btxy /= (bmag / 1.e4); - // calculate pressures pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; @@ -212,11 +203,10 @@ class TwoFluid : public PhysicsModel { Field2D Bxy = mesh->get("Bxy"); Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, I); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - coord->setDx(mesh->get("dpsi")); - coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 42e769b2e7..0fb6ff05dc 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -112,23 +112,10 @@ class Interchange : public PhysicsModel { b0xcv.y *= rho_s * rho_s; b0xcv.z *= rho_s * rho_s; - // Normalise geometry - Rxy /= rho_s; - hthe /= rho_s; - I *= rho_s * rho_s * (bmag / 1e4) * ShearFactor; - - // Normalise magnetic field - Bpxy /= (bmag / 1.e4); - Btxy /= (bmag / 1.e4); - - Field2D Bxy = mesh->get("Bxy"); - Bxy /= (bmag / 1.e4); - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, I); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); - coord->setDx(mesh->get("dpsi")); - coord->setDx(coord->dx() / (rho_s * rho_s * (bmag / 1e4))); + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); // Tell BOUT++ which variables to evolve SOLVE_FOR2(rho, Ni); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 4cb3bc97c9..c277df9ffe 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -22,14 +22,15 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { } Field2D qinty; - Rxy /= Lnorm; - hthe /= Lnorm; - sinty *= SQ(Lnorm) * Bnorm; - coords->setDx(coords->dx() / (SQ(Lnorm) * Bnorm)); + BoutReal sbp = 1.0; // Sign of Bp + if (min(Bpxy, true) < 0.0) { + sbp = -1.0; + } + + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(); - Bpxy /= Bnorm; - Btxy /= Bnorm; - coords->setBxy(coords->Bxy() / Bnorm); + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // Calculate metric components std::string ptstr; @@ -39,12 +40,4 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { if (ptstr == "shifted") { sinty = 0.0; // I disappears from metric } - - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, coords->Bxy(), hthe, sinty); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); } From a31b2bb77677e219440235c41c6f39c8e6ed90c5 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 12:46:31 +0000 Subject: [PATCH 34/98] Extract method setShearFactor() --- examples/wave-slab/wave_slab.cxx | 8 ------ include/bout/tokamak_coordinates_factory.hxx | 26 ++++++++++++++++++++ tests/MMS/GBS/gbs.cxx | 8 ------ tests/MMS/tokamak/tokamak.cxx | 7 ------ 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 8091238304..0088a4338d 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -20,14 +20,6 @@ class WaveTest : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(); - int ShiftXderivs = 0; - mesh->get(ShiftXderivs, "false"); - if (ShiftXderivs) { - // No integrated shear in metric - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - } - solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index c853fcff00..e13e2c32d3 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -34,8 +34,34 @@ public: mesh.get(dx_m, "dpsi"); } + void setShearFactor() { +// bool ShiftXderivs = mesh_m.get("shiftXderivs", false); TODO: Create overload for mesh->get(name, default_value) to return bool or int + int ShiftXderivs = 0; + mesh_m.get(ShiftXderivs, "false"); +// const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); + if (ShiftXderivs) { + // No integrated shear in metric + ShearFactor_m = 0.0; + } +// if (ShiftXderivs) { +// if (mesh->IncIntShear) { +// // BOUT-06 style, using d/dx = d/dpsi + I * d/dz +// coords->setIntShiftTorsion(I); +// +// } else { +// // Dimits style, using local coordinate system +// if (include_curvature) { +// b0xcv.z += I * b0xcv.x; +// } +// I = 0.0; // I disappears from metric +// } +// } + } + Coordinates* make_tokamak_coordinates() { + setShearFactor(); + auto* coord = mesh_m.getCoordinates(); const auto g11 = SQ(Rxy_m * Bpxy_m); diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 235d4083d3..976d3f4e84 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -335,14 +335,6 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - // Calculate metric components - bool ShiftXderivs; - Options::getRoot()->get("shiftXderivs", ShiftXderivs, false); // Read global flag - if (ShiftXderivs) { - sinty = 0.0; // I disappears from metric - } -} - // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 1b271ae23a..e438341190 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -69,13 +69,6 @@ class TokamakMMS : public PhysicsModel { coords = tokamak_coordinates_factory.make_tokamak_coordinates(); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - - // Calculate metric components - bool ShiftXderivs; - Options::getRoot()->get("shiftXderivs", ShiftXderivs, false); // Read global flag - if (ShiftXderivs) { - sinty = 0.0; // I disappears from metric - } } private: From 7e395f4c91c0fb6c33d2cf648bcc99619be9e6ea Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 12:47:26 +0000 Subject: [PATCH 35/98] Restore ShearFactor setter on TokamakCoordinatesFactory --- include/bout/tokamak_coordinates_factory.hxx | 1 + 1 file changed, 1 insertion(+) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index e13e2c32d3..b72e543324 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -104,6 +104,7 @@ public: const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } + void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } }; From c883dcbdc2409335c2402883a8256cce4e49f903 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 12:47:58 +0000 Subject: [PATCH 36/98] Use extracted methods in alfven-wave example --- examples/constraints/alfven-wave/alfven.cxx | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index cc313ecaef..6a1db09a0c 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -160,28 +160,15 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lnorm; - tokamak_coordinates_factory.set_Rxy(new_Rxy); - - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lnorm; - tokamak_coordinates_factory.set_hthe(new_hthe); - - FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * SQ(Lnorm) * Bnorm; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - BoutReal sbp = 1.0; // Sign of Bp if (min(tokamak_coordinates_factory.get_Bpxy(), true) < 0.0) { sbp = -1.0; } - Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bnorm; - tokamak_coordinates_factory.set_Bpxy(new_Bpxy); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bnorm; - tokamak_coordinates_factory.set_Btxy(new_Btxy); + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // Check type of parallel transform std::string ptstr = From 22e17f1b8611a83b45e145ebbfa92dc7b6c3bfbd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 12:54:01 +0000 Subject: [PATCH 37/98] Extract method TokamakCoordinatesFactory.get_sign_of_bp() --- examples/constraints/alfven-wave/alfven.cxx | 7 +------ include/bout/tokamak_coordinates_factory.hxx | 10 +++++++++- tests/MMS/GBS/gbs.cxx | 7 +------ tests/MMS/tokamak/tokamak.cxx | 7 +------ tests/integrated/test-laplacexy/loadmetric.cxx | 7 +------ 5 files changed, 13 insertions(+), 25 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 6a1db09a0c..3cc0a769b0 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -160,12 +160,7 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - BoutReal sbp = 1.0; // Sign of Bp - if (min(tokamak_coordinates_factory.get_Bpxy(), true) < 0.0) { - sbp = -1.0; - } - - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index b72e543324..4cab399242 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -16,7 +16,6 @@ private: Field2D hthe_m; FieldMetric ShearFactor_m; FieldMetric dx_m; - BoutReal sign_of_bp; public: @@ -58,10 +57,19 @@ public: // } } + BoutReal get_sign_of_bp() { + if (min(Bpxy_m, true) < 0.0) { + return -1.0; + } + return 1.0; + } + Coordinates* make_tokamak_coordinates() { setShearFactor(); + BoutReal sign_of_bp = get_sign_of_bp(); + auto* coord = mesh_m.getCoordinates(); const auto g11 = SQ(Rxy_m * Bpxy_m); diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 976d3f4e84..baa7d23495 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -325,12 +325,7 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { output << "\tUsing dx as the x grid spacing\n"; } - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index e438341190..745bf67b89 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -60,12 +60,7 @@ class TokamakMMS : public PhysicsModel { output << "\tUsing dx as the x grid spacing\n"; } - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index c277df9ffe..6bfcf632e1 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -22,12 +22,7 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { } Field2D qinty; - BoutReal sbp = 1.0; // Sign of Bp - if (min(Bpxy, true) < 0.0) { - sbp = -1.0; - } - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh, sbp); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); From fe6cc63c55b7f0dad7e30159731d565132277038 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 13:10:09 +0000 Subject: [PATCH 38/98] Use extracted method TokamakCoordinatesFactory.normalise() in more places --- examples/dalf3/dalf3.cxx | 21 +------------------ .../elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ++-- examples/elm-pb/elm_pb.cxx | 20 +----------------- examples/gyro-gem/gem.cxx | 21 +------------------ tests/MMS/elm-pb/elm_pb.cxx | 8 +------ 5 files changed, 6 insertions(+), 68 deletions(-) diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 523cc6d19a..7ee2b5dbae 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -222,26 +222,7 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; - tokamak_coordinates_factory.set_Rxy(new_Rxy); - - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / rho_s; - tokamak_coordinates_factory.set_hthe(new_hthe); - - FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * rho_s * rho_s * Bnorm; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - - Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bnorm; - tokamak_coordinates_factory.set_Bpxy(new_Bpxy); - - Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bnorm; - tokamak_coordinates_factory.set_Btxy(new_Btxy); - - Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bnorm; - tokamak_coordinates_factory.set_Bxy(new_Bxy); - - coord->setDx(coord->dx() / (rho_s * rho_s * Bnorm)); + tokamak_coordinates_factory.normalise(rho_s, Bnorm); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 2ab96abcfb..b789b2b6b9 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1194,6 +1194,8 @@ class ELMpb : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); + tokamak_coordinates_factory.normalise(Lbar, Bbar); + ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -1209,8 +1211,6 @@ class ELMpb : public PhysicsModel { I = 0.0; // I disappears from metric } - metric->setDx(metric->dx() / (Lbar * Lbar * Bbar)); - return 0; } diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index db78c74c98..b316fc2693 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -887,25 +887,7 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / Lbar; - tokamak_coordinates_factory.set_Rxy(new_Rxy); - - Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bbar; - tokamak_coordinates_factory.set_Bpxy(new_Bpxy); - - Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bbar; - tokamak_coordinates_factory.set_Btxy(new_Btxy); - - Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; - tokamak_coordinates_factory.set_Bxy(new_Bxy); - - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; - tokamak_coordinates_factory.set_hthe(new_hthe); - - FieldMetric new_ShearFactor = tokamak_coordinates_factory.get_ShearFactor() * Lbar * Lbar * Bbar; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - - metric->setDx(metric->dx() / (Lbar * Lbar * Bbar)); + tokamak_coordinates_factory.normalise(Lbar, Bbar); if (constn0) { T0_fake_prof = false; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 5486e1725e..a67030d954 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -344,26 +344,7 @@ class GEM : public PhysicsModel { output << "\tNormalised rho_e = " << rho_e << endl; output << "\tNormalised rho_i = " << rho_i << endl; - // Normalise - - // parallel derivatives normalised to Lperp - Field2D new_hthe = tokamak_coordinates_factory.get_hthe() / Lbar; - tokamak_coordinates_factory.set_hthe(new_hthe); - - Field2D new_Bxy = tokamak_coordinates_factory.get_Bxy() / Bbar; - tokamak_coordinates_factory.set_Bxy(new_Bxy); - - Field2D new_Bpxy = tokamak_coordinates_factory.get_Bpxy() / Bbar; - tokamak_coordinates_factory.set_Bpxy(new_Bpxy); - - Field2D new_Btxy = tokamak_coordinates_factory.get_Btxy() / Bbar; - tokamak_coordinates_factory.set_Btxy(new_Btxy); - - // Perpendicular derivatives normalised to rho_s - Field2D new_Rxy = tokamak_coordinates_factory.get_Rxy() / rho_s; - tokamak_coordinates_factory.set_Rxy(new_Rxy); - - coord->setDx(coord->dx() / (rho_s * rho_s * Bbar)); + tokamak_coordinates_factory.normalise(Lbar, Bbar); // Set B field vector diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index ae0777e82f..645b4de97a 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -384,13 +384,7 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - Rxy /= Lbar; - Bpxy /= Bbar; - Btxy /= Bbar; - B0 /= Bbar; - hthe /= Lbar; - coords->setDx(coords->dx() / (Lbar * Lbar * Bbar)); - I *= Lbar * Lbar * Bbar; + tokamak_coordinates_factory.normalise(Lbar, Bbar); BoutReal pnorm = max(P0, true); // Maximum over all processors From 4ee074f71fe4c3e8fd26103c40614b7b280420ea Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 13:12:52 +0000 Subject: [PATCH 39/98] Reorder (instantiate TokamakCoordinatesFactory before first use) Also remove duplicated line. --- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index b789b2b6b9..08632920f4 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -704,6 +704,9 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); + V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); if (simple_rmp) { @@ -1191,11 +1194,6 @@ class ELMpb : public PhysicsModel { } Jpar2.setBoundary("J"); - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); - - tokamak_coordinates_factory.normalise(Lbar, Bbar); - ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES From e6625e811cec7ad52edcd305c677533ddcf1df15 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 13:57:35 +0000 Subject: [PATCH 40/98] Use new getters and setters elm_pb_outerloop --- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 08632920f4..2635c84667 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -706,7 +706,7 @@ class ELMpb : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); - + V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); if (simple_rmp) { @@ -1061,15 +1061,15 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = Bpxy / hthe; + B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; + V0net.y = tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Btxy() * tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_hthe() * B0 * B0) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory.get_B0(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1092,8 +1092,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); - gradparB = Grad_par(B0) / B0; + beta = tokamak_coordinates_factory.get_B0() * tokamak_coordinates_factory.get_B0() / (0.5 + (tokamak_coordinates_factory.get_B0() * tokamak_coordinates_factory.get_B0() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates_factory.get_B0()) / tokamak_coordinates_factory.get_B0(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1126,10 +1126,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / B0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_B0(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / B0 / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_B0() / N0; } SAVE_ONCE(phi0); } else { @@ -1140,7 +1140,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, B0); + SAVE_ONCE(Va, tokamak_coordinates_factory.get_B0()); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { @@ -1172,7 +1172,7 @@ class ELMpb : public PhysicsModel { } // if(diamag) { - // phi -= 0.5*dnorm * P / B0; + // phi -= 0.5*dnorm * P / tokamak_coordinates_factory.get_B0(); //} } @@ -1199,14 +1199,16 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(I); + metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); } else { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += I * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; } - I = 0.0; // I disappears from metric + // I disappears from metric + FieldMetric new_ShearFactor = 0.0; + tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } return 0; From 0c00e37241bef6232569ea6fe2dce4445794fdf1 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 14:04:29 +0000 Subject: [PATCH 41/98] More use of new getters and setters elm_pb_outerloop --- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 2635c84667..d843bdc262 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1066,10 +1066,10 @@ class ELMpb : public PhysicsModel { V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Btxy() * tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_hthe() * B0 * B0) * Dphi0; + V0net.y = tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Btxy() * tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_hthe() * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory.get_B0(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory.get_Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1092,8 +1092,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates_factory.get_B0() * tokamak_coordinates_factory.get_B0() / (0.5 + (tokamak_coordinates_factory.get_B0() * tokamak_coordinates_factory.get_B0() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates_factory.get_B0()) / tokamak_coordinates_factory.get_B0(); + beta = tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (0.5 + (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates_factory.get_Bxy()) / tokamak_coordinates_factory.get_Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1126,10 +1126,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_B0(); + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_B0() / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy() / N0; } SAVE_ONCE(phi0); } else { @@ -1140,7 +1140,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, tokamak_coordinates_factory.get_B0()); + SAVE_ONCE(Va, tokamak_coordinates_factory.get_Bxy()); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { @@ -1172,7 +1172,7 @@ class ELMpb : public PhysicsModel { } // if(diamag) { - // phi -= 0.5*dnorm * P / tokamak_coordinates_factory.get_B0(); + // phi -= 0.5*dnorm * P / tokamak_coordinates_factory.get_Bxy(); //} } @@ -1224,10 +1224,10 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; + result -= bracket(interp_to(Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); } } @@ -1363,12 +1363,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / B0; + phi -= 0.5 * dnorm * P / tokamak_coordinates_factory.get_Bxy(); } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates_factory.get_Bxy()) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1519,7 +1519,7 @@ class ELMpb : public PhysicsModel { auto P0_acc = Field2DAccessor<>(P0); auto J0_acc = Field2DAccessor<>(J0); auto phi0_acc = Field2DAccessor<>(phi0); - auto B0_acc = Field2DAccessor<>(B0); + auto B0_acc = Field2DAccessor<>(tokamak_coordinates_factory.get_Bxy()); // Evolving fields auto P_acc = FieldAccessor<>(P); @@ -1536,17 +1536,17 @@ class ELMpb : public PhysicsModel { #endif #if EVOLVE_JPAR - Field3D B0U = B0 * U; + Field3D B0U = tokamak_coordinates_factory.get_Bxy() * U; mesh->communicate(B0U); auto B0U_acc = FieldAccessor<>(B0U); #else - Field3D B0phi = B0 * phi; + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); auto B0phi_acc = FieldAccessor<>(B0phi); #if EHALL - Field3D B0P = B0 * P; - mesh->communicate(B0 * P); + Field3D B0P = tokamak_coordinates_factory.get_Bxy() * P; + mesh->communicate(tokamak_coordinates_factory.get_Bxy() * P); auto B0P_acc = FieldAccessor<>(B0P); #endif // EHALL #endif // EVOLVE_JPAR @@ -1669,7 +1669,7 @@ class ELMpb : public PhysicsModel { } // if (diamag_grad_t) { // grad_par(T_e) correction - // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; + // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates_factory.get_Bxy(); // } // if (hyperresist > 0.0) { // Hyper-resistivity @@ -1706,16 +1706,16 @@ class ELMpb : public PhysicsModel { // Vorticity equation // Grad j term - // ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); + // ddt(U) = SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); // if (include_rmp) { - // ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + // ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); // } ddt(U) += b0xcv * Grad(P); // curvature term // if (!nogradparj) { // Parallel current term - // ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + // ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j // } if (withflow && K_H_term) { // K_H_term @@ -1731,7 +1731,7 @@ class ELMpb : public PhysicsModel { } // if (nonlinear) { // Advection - // ddt(U) -= bracket(phi, U, bm_exb) * B0; + // ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates_factory.get_Bxy(); // } // Viscosity terms @@ -1775,11 +1775,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); + Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates_factory.get_Bxy() * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(B0 * phi); + Dperp2Phi = Delp2(tokamak_coordinates_factory.get_Bxy() * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1791,35 +1791,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); + bracketPhi0P = bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(tokamak_coordinates_factory.get_Bxy() * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; - Field3D B0phi = B0 * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); - Field3D B0phi0 = B0 * phi0; + Field3D B0phi0 = tokamak_coordinates_factory.get_Bxy() * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates_factory.get_Bxy(); if (nonlinear) { - Field3D B0phi = B0 * phi; + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates_factory.get_Bxy(); } } @@ -1849,7 +1849,7 @@ class ELMpb : public PhysicsModel { } // if (nonlinear) { // Advection - // ddt(P) -= bracket(phi, P, bm_exb) * B0; + // ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates_factory.get_Bxy(); // } // Parallel diffusion terms @@ -1896,7 +1896,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates_factory.get_Bxy(); // Advection } } @@ -1986,7 +1986,7 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1995,7 +1995,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * B0 * B0); + invU->setCoefB(-SQ(gamma) * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -2003,9 +2003,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = B0 * phi3; + Field3D B0phi3 = tokamak_coordinates_factory.get_Bxy() * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates_factory.get_Bxy(); ddt(Psi).applyBoundary(); return 0; @@ -2037,14 +2037,14 @@ class ELMpb : public PhysicsModel { Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = B0 * phi; + Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / B0; + Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates_factory.get_Bxy(); JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) - + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) + + SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); From 39e727b8e2aee7885da8283b8031763d1ba5ecb0 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 14:20:36 +0000 Subject: [PATCH 42/98] Get Bxy from the Coordinates object --- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 86 ++++++++++--------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index d843bdc262..79fe4e7280 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1140,7 +1140,8 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, tokamak_coordinates_factory.get_Bxy()); + Field2D Bxy = tokamak_coordinates_factory.get_Bxy(); + SAVE_ONCE(Va, Bxy); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { @@ -1172,7 +1173,7 @@ class ELMpb : public PhysicsModel { } // if(diamag) { - // phi -= 0.5*dnorm * P / tokamak_coordinates_factory.get_Bxy(); + // phi -= 0.5*dnorm * P / metric->Bxy(); //} } @@ -1223,11 +1224,13 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); + const auto& B0 = mesh->getCoordinates()->Bxy(); + if (nonlinear) { - result -= bracket(interp_to(Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); + result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; } } @@ -1363,12 +1366,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / tokamak_coordinates_factory.get_Bxy(); + phi -= 0.5 * dnorm * P / metric->Bxy(); } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates_factory.get_Bxy()) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * metric->Bxy()) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1519,7 +1522,8 @@ class ELMpb : public PhysicsModel { auto P0_acc = Field2DAccessor<>(P0); auto J0_acc = Field2DAccessor<>(J0); auto phi0_acc = Field2DAccessor<>(phi0); - auto B0_acc = Field2DAccessor<>(tokamak_coordinates_factory.get_Bxy()); + FieldMetric Bxy = metric->Bxy(); + auto B0_acc = Field2DAccessor<>(Bxy); // Evolving fields auto P_acc = FieldAccessor<>(P); @@ -1536,17 +1540,17 @@ class ELMpb : public PhysicsModel { #endif #if EVOLVE_JPAR - Field3D B0U = tokamak_coordinates_factory.get_Bxy() * U; + Field3D B0U = metric->Bxy() * U; mesh->communicate(B0U); auto B0U_acc = FieldAccessor<>(B0U); #else - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + Field3D B0phi = metric->Bxy() * phi; mesh->communicate(B0phi); auto B0phi_acc = FieldAccessor<>(B0phi); #if EHALL - Field3D B0P = tokamak_coordinates_factory.get_Bxy() * P; - mesh->communicate(tokamak_coordinates_factory.get_Bxy() * P); + Field3D B0P = metric->Bxy() * P; + mesh->communicate(metric->Bxy() * P); auto B0P_acc = FieldAccessor<>(B0P); #endif // EHALL #endif // EVOLVE_JPAR @@ -1669,7 +1673,7 @@ class ELMpb : public PhysicsModel { } // if (diamag_grad_t) { // grad_par(T_e) correction - // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates_factory.get_Bxy(); + // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / metric->Bxy(); // } // if (hyperresist > 0.0) { // Hyper-resistivity @@ -1731,7 +1735,7 @@ class ELMpb : public PhysicsModel { } // if (nonlinear) { // Advection - // ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates_factory.get_Bxy(); + // ddt(U) -= bracket(phi, U, bm_exb) * metric->Bxy(); // } // Viscosity terms @@ -1775,11 +1779,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates_factory.get_Bxy() * phi0)); + Dperp2Phi0 = Field3D(Delp2(metric->Bxy() * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(tokamak_coordinates_factory.get_Bxy() * phi); + Dperp2Phi = Delp2(metric->Bxy() * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1791,35 +1795,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Pi, bm_exb); + bracketPhi0P = bracket(metric->Bxy() * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(tokamak_coordinates_factory.get_Bxy() * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(metric->Bxy() * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / metric->Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / metric->Bxy(); + Field3D B0phi = metric->Bxy() * phi; mesh->communicate(B0phi); - Field3D B0phi0 = tokamak_coordinates_factory.get_Bxy() * phi0; + Field3D B0phi0 = metric->Bxy() * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / metric->Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / metric->Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / metric->Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / metric->Bxy(); if (nonlinear) { - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + Field3D B0phi = metric->Bxy() * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / metric->Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / metric->Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / metric->Bxy(); } } @@ -1849,7 +1853,7 @@ class ELMpb : public PhysicsModel { } // if (nonlinear) { // Advection - // ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates_factory.get_Bxy(); + // ddt(P) -= bracket(phi, P, bm_exb) * metric->Bxy(); // } // Parallel diffusion terms @@ -1896,7 +1900,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates_factory.get_Bxy(); // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * metric->Bxy(); // Advection } } @@ -1984,9 +1988,11 @@ class ELMpb : public PhysicsModel { } mesh->communicate(Jrhs, ddt(P)); + + Coordinates* metric = mesh->getCoordinates(); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * metric->Bxy() * metric.Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1995,7 +2001,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()); + invU->setCoefB(-SQ(gamma) * metric->Bxy() * metric->Bxy()); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -2003,9 +2009,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = tokamak_coordinates_factory.get_Bxy() * phi3; + Field3D B0phi3 = metric->Bxy() * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates_factory.get_Bxy(); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / metric->Bxy(); ddt(Psi).applyBoundary(); return 0; @@ -2034,17 +2040,19 @@ class ELMpb : public PhysicsModel { mesh->communicate(phi, Jpar); + Coordinates* metric = mesh->getCoordinates(); + Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + Field3D B0phi = metric->Bxy() * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates_factory.get_Bxy(); + Field3D JPsi = -Grad_par(B0phi, loc) / metric->Bxy(); JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) - + SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(metric->Bxy()) * Grad_par(Jpar, CELL_CENTRE) + + SQ(metric->Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); From 73f8ec706fe6c58e857c4b5d97467ad920ade0a3 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 14:55:21 +0000 Subject: [PATCH 43/98] Bxy has to be of type Field2D, so get from TokamakCoordinatesFactory object --- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 79fe4e7280..819652369b 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -288,6 +288,8 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass const BoutReal Me = 9.1094e-31; // Electron mass @@ -704,7 +706,6 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); @@ -1522,7 +1523,7 @@ class ELMpb : public PhysicsModel { auto P0_acc = Field2DAccessor<>(P0); auto J0_acc = Field2DAccessor<>(J0); auto phi0_acc = Field2DAccessor<>(phi0); - FieldMetric Bxy = metric->Bxy(); + Field2D Bxy = tokamak_coordinates_factory.get_Bxy(); auto B0_acc = Field2DAccessor<>(Bxy); // Evolving fields @@ -1992,7 +1993,7 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); Field3D U1 = ddt(U); - U1 += (gamma * metric->Bxy() * metric.Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; From 27cb92955331c4cb924a1f433e9b46ce591d15a8 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 17:10:35 +0000 Subject: [PATCH 44/98] Bxy is now normalised in TokamakCoordinatesFactory.normalise() --- examples/constraints/alfven-wave/alfven.cxx | 3 --- tests/integrated/test-drift-instability/2fluid.cxx | 3 --- 2 files changed, 6 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 3cc0a769b0..5d859a1b65 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -175,9 +175,6 @@ class Alfven : public PhysicsModel { tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); // I disappears from metric } - FieldMetric Bxy = mesh->get("Bxy"); - Bxy /= Bnorm; - // Checking for dpsi and qinty used in BOUT grids Field2D dx; if (!mesh->get(dx, "dpsi")) { diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index fb713fff78..cb4091ada4 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -200,9 +200,6 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - Field2D Bxy = mesh->get("Bxy"); - Bxy /= (bmag / 1.e4); - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(); From 6f0cab24df1907e9f4e01ab339e95cd770ecd9cf Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 17:24:27 +0000 Subject: [PATCH 45/98] Move b0xcv to TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 25 ++---------------- include/bout/tokamak_coordinates_factory.hxx | 27 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index b69d220826..6dbfcb1fec 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -36,8 +36,7 @@ class Elm_6f : public PhysicsModel { // 2D inital profiles /// Current and pressure Field2D J0, P0; - /// Curvature term - Vector2D b0xcv; + /// When diamagnetic terms used Field2D phi0; @@ -140,7 +139,7 @@ class Elm_6f : public PhysicsModel { BoutReal const_cse; // options - bool include_curvature, include_jpar0, compress0; + bool include_jpar0, compress0; bool evolve_pressure, continuity, gyroviscous; Field3D diff_radial, ddx_ni, ddx_n0; BoutReal diffusion_coef_Hmode0, diffusion_coef_Hmode1; @@ -375,7 +374,6 @@ class Elm_6f : public PhysicsModel { protected: int init(bool restarting) override { - bool noshear; output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); @@ -388,10 +386,6 @@ class Elm_6f : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - ////////////////////////////////////////////////////////////// // Read parameters from the options file // @@ -471,7 +465,6 @@ class Elm_6f : public PhysicsModel { options["phi_constraint"].doc("Use solver constraint for phi").withDefault(false); // Effects to include/exclude - include_curvature = options["include_curvature"].withDefault(true); include_jpar0 = options["include_jpar0"].withDefault(true); evolve_pressure = options["evolve_pressure"].withDefault(true); @@ -549,8 +542,6 @@ class Elm_6f : public PhysicsModel { .doc("Scale diamagnetic effects by this factor") .withDefault(1.0); - noshear = options["noshear"].withDefault(false); - relax_j_vac = options["relax_j_vac"].doc("Relax vacuum current to zero").withDefault(false); relax_j_tconst = options["relax_j_tconst"].withDefault(0.1); @@ -667,22 +658,10 @@ class Elm_6f : public PhysicsModel { phi_curv = options["phi_curv"].doc("Compressional ExB terms").withDefault(true); g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); - if (!include_curvature) { - b0xcv = 0.0; - } - if (!include_jpar0) { J0 = 0.0; } - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - } - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - } - ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 4cab399242..d116f09059 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -16,6 +16,7 @@ private: Field2D hthe_m; FieldMetric ShearFactor_m; FieldMetric dx_m; + Vector2D b0xcv_m; // Curvature term public: @@ -31,6 +32,9 @@ public: mesh.get(hthe_m, "hthe"); mesh.get(ShearFactor_m, "sinty"); mesh.get(dx_m, "dpsi"); + + b0xcv_m.covariant = false; // Read contravariant components + mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } void setShearFactor() { @@ -42,6 +46,29 @@ public: // No integrated shear in metric ShearFactor_m = 0.0; } + +// bool include_curvature = options["include_curvature"].withDefault(true); +// const bool include_curvature = mesh_m.get("include_curvature", true); //TODO: Create overload for mesh->get(name, default_value) to return bool or int + bool include_curvature = 0; + mesh_m.get(include_curvature, "true"); + if (!include_curvature) { + b0xcv_m = 0.0; + } + +// const bool noshear = mesh_m.get("noshear", false); //TODO: Create overload for mesh->get(name, default_value) to return bool or int +// const bool noshear = mesh_m.get("noshear", false); + bool noshear = 0; + mesh_m.get(noshear, "false"); + mesh_m.get("noshear", false); + if (noshear) { + if (include_curvature) { + b0xcv_m.z += ShearFactor_m * b0xcv_m.x; + } + ShearFactor_m = 0.0; + } + +// TODO: Do we need to include the following logic? + // if (ShiftXderivs) { // if (mesh->IncIntShear) { // // BOUT-06 style, using d/dx = d/dpsi + I * d/dz From 58606f785344a5485170b7082fd2f3935a648cb4 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 17:35:07 +0000 Subject: [PATCH 46/98] Normalise b0xcv (magnetic curvature term) --- include/bout/tokamak_coordinates_factory.hxx | 3 +++ .../test-drift-instability/2fluid.cxx | 23 ------------------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index d116f09059..66ae4d13cd 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -33,6 +33,7 @@ public: mesh.get(ShearFactor_m, "sinty"); mesh.get(dx_m, "dpsi"); + // Load magnetic curvature term b0xcv_m.covariant = false; // Read contravariant components mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } @@ -130,6 +131,8 @@ public: hthe_m / Lbar; ShearFactor_m *= Lbar * Lbar * Bbar; dx_m /= Lbar * Lbar * Bbar; + + b0xcv_m.z += ShearFactor_m * b0xcv_m.x; } const Field2D& get_Rxy() const { return Rxy_m; } diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index cb4091ada4..2e46628051 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -23,7 +23,6 @@ class TwoFluid : public PhysicsModel { Field2D Ni0, Ti0, Te0, Vi0, phi0, Ve0, rho0, Ajpar0; // Staggered versions of initial profiles Field2D Ni0_maybe_ylow, Te0_maybe_ylow; - Vector2D b0xcv; // for curvature terms // 3D evolving fields Field3D rho, Te, Ni, Ajpar, Vi, Ti; @@ -41,9 +40,6 @@ class TwoFluid : public PhysicsModel { Field3D pei, pe; Field2D pei0, pe0; - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, hthe; - // parameters BoutReal Te_x, Ti_x, Ni_x, Vi_x, bmag, rho_s, fmei, AA, ZZ; BoutReal lambda_ei, lambda_ii; @@ -84,17 +80,6 @@ class TwoFluid : public PhysicsModel { GRID_LOAD(rho0); GRID_LOAD(Ajpar0); - // Load magnetic curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // b0xkappa terms - - // Load metrics - GRID_LOAD(Rxy); - GRID_LOAD(Bpxy); - GRID_LOAD(Btxy); - GRID_LOAD(hthe); - mesh->get(I, "sinty"); - // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); @@ -137,14 +122,6 @@ class TwoFluid : public PhysicsModel { (*globalOptions)["aparsolver"].setConditionallyUsed(); } - /************* SHIFTED RADIAL COORDINATES ************/ - - const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); - if (ShiftXderivs) { - ShearFactor = 0.0; // I disappears from metric - b0xcv.z += I * b0xcv.x; - } - /************** CALCULATE PARAMETERS *****************/ rho_s = 1.02 * sqrt(AA * Te_x) / ZZ / bmag; From 397d50e8f5ea291be84eac08838deabbf0933c5f Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 18:09:00 +0000 Subject: [PATCH 47/98] dx is now normalised in TokamakCoordinatesFactory.normalise() --- examples/constraints/alfven-wave/alfven.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 5d859a1b65..1030d5950c 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -184,7 +184,6 @@ class Alfven : public PhysicsModel { // dx will have been read already from the grid output << "\tUsing dx as the x grid spacing\n"; } - coord->setDx(dx / (SQ(Lnorm) * Bnorm)); } }; From 19843b02fe0984311147371d95581573ceeab868 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 18:11:28 +0000 Subject: [PATCH 48/98] Make make_tokamak_coordinates method take optional boolean argument shifted_metric_method and then pass to private method setShearFactor(). --- examples/constraints/alfven-wave/alfven.cxx | 5 +- include/bout/tokamak_coordinates_factory.hxx | 84 +++++++++----------- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 1030d5950c..a3944ccea8 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -169,10 +169,9 @@ class Alfven : public PhysicsModel { std::string ptstr = Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); + const bool shifted_metric_method = false; if (lowercase(ptstr) == "shifted") { - // Using shifted metric method - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); // I disappears from metric + shifted_metric_method = true; } // Checking for dpsi and qinty used in BOUT grids diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 66ae4d13cd..783b5b53bd 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -38,51 +38,12 @@ public: mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } - void setShearFactor() { -// bool ShiftXderivs = mesh_m.get("shiftXderivs", false); TODO: Create overload for mesh->get(name, default_value) to return bool or int - int ShiftXderivs = 0; - mesh_m.get(ShiftXderivs, "false"); -// const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); - if (ShiftXderivs) { - // No integrated shear in metric - ShearFactor_m = 0.0; - } - -// bool include_curvature = options["include_curvature"].withDefault(true); -// const bool include_curvature = mesh_m.get("include_curvature", true); //TODO: Create overload for mesh->get(name, default_value) to return bool or int - bool include_curvature = 0; - mesh_m.get(include_curvature, "true"); - if (!include_curvature) { - b0xcv_m = 0.0; - } + void setShearFactor(const bool shifted_metric_method = false) { -// const bool noshear = mesh_m.get("noshear", false); //TODO: Create overload for mesh->get(name, default_value) to return bool or int -// const bool noshear = mesh_m.get("noshear", false); - bool noshear = 0; - mesh_m.get(noshear, "false"); - mesh_m.get("noshear", false); - if (noshear) { - if (include_curvature) { - b0xcv_m.z += ShearFactor_m * b0xcv_m.x; - } + if (shifted_metric_method) { + // No integrated shear in metric ShearFactor_m = 0.0; } - -// TODO: Do we need to include the following logic? - -// if (ShiftXderivs) { -// if (mesh->IncIntShear) { -// // BOUT-06 style, using d/dx = d/dpsi + I * d/dz -// coords->setIntShiftTorsion(I); -// -// } else { -// // Dimits style, using local coordinate system -// if (include_curvature) { -// b0xcv.z += I * b0xcv.x; -// } -// I = 0.0; // I disappears from metric -// } -// } } BoutReal get_sign_of_bp() { @@ -92,9 +53,9 @@ public: return 1.0; } - Coordinates* make_tokamak_coordinates() + Coordinates* make_tokamak_coordinates(const bool shifted_metric_method = false) { - setShearFactor(); + setShearFactor(shifted_metric_method); BoutReal sign_of_bp = get_sign_of_bp(); @@ -132,7 +93,40 @@ public: ShearFactor_m *= Lbar * Lbar * Bbar; dx_m /= Lbar * Lbar * Bbar; - b0xcv_m.z += ShearFactor_m * b0xcv_m.x; + // bool include_curvature = options["include_curvature"].withDefault(true); + // const bool include_curvature = mesh_m.get("include_curvature", true); //TODO: Create overload for mesh->get(name, default_value) to return bool or int + bool include_curvature = 0; + mesh_m.get(include_curvature, "true"); + if (!include_curvature) { + b0xcv_m = 0.0; + } + + // const bool noshear = mesh_m.get("noshear", false); //TODO: Create overload for mesh->get(name, default_value) to return bool or int + // const bool noshear = mesh_m.get("noshear", false); + bool noshear = 0; + mesh_m.get(noshear, "false"); + mesh_m.get("noshear", false); + if (noshear) { + if (include_curvature) { + b0xcv_m.z += ShearFactor_m * b0xcv_m.x; + } + ShearFactor_m = 0.0; + } + + // TODO: Do we need to include the following logic? + // if (ShiftXderivs) { + // if (mesh->IncIntShear) { + // // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + // coords->setIntShiftTorsion(I); + // + // } else { + // // Dimits style, using local coordinate system + // if (include_curvature) { + // b0xcv.z += I * b0xcv.x; + // } + // I = 0.0; // I disappears from metric + // } + // } } const Field2D& get_Rxy() const { return Rxy_m; } From 42df7b62247038c9897c03847e741f3c2e73d58b Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 19:28:11 +0000 Subject: [PATCH 49/98] dx is now normalised in TokamakCoordinatesFactory.normalise() --- examples/6field-simple/elm_6f.cxx | 1 - examples/laplacexy/alfven-wave/alfven.cxx | 1 - 2 files changed, 2 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 6dbfcb1fec..e96457f865 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -995,7 +995,6 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - coord->setDx(dx / (Lbar * Lbar * Bbar)); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 4adb771c54..1ef8a7f029 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -183,7 +183,6 @@ class Alfven : public PhysicsModel { // dx will have been read already from the grid output << "\tUsing dx as the x grid spacing\n"; } - coord->setDx(dx / (SQ(Lnorm) * Bnorm)); } }; From a86df4e0588c764e574b99b1ebbd0419f5a1dc98 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 20:11:14 +0000 Subject: [PATCH 50/98] Normalise b0xcv (magnetic curvature term) moved to normalise() method on TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 4 ---- examples/dalf3/dalf3.cxx | 4 ---- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ---- examples/elm-pb/elm_pb.cxx | 4 ---- include/bout/tokamak_coordinates_factory.hxx | 5 +++++ tests/MMS/elm-pb/elm_pb.cxx | 4 ---- tests/integrated/test-drift-instability/2fluid.cxx | 5 ----- tests/integrated/test-interchange-instability/2fluid.cxx | 7 +------ 8 files changed, 6 insertions(+), 31 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index e96457f865..d3d539ea2a 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -805,10 +805,6 @@ class Elm_6f : public PhysicsModel { J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; - tokamak_coordinates_factory.normalise(Lbar, Bbar); Field2D dx; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 7ee2b5dbae..d62aba2813 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -217,10 +217,6 @@ class DALF3 : public PhysicsModel { hyper_viscosity /= wci * SQ(SQ(rho_s)); viscosity_par /= wci * SQ(rho_s); - b0xcv.x /= Bnorm; - b0xcv.y *= rho_s * rho_s; - b0xcv.z *= rho_s * rho_s; - // Metrics tokamak_coordinates_factory.normalise(rho_s, Bnorm); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 819652369b..761e6a23ab 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -927,10 +927,6 @@ class ELMpb : public PhysicsModel { V0 = V0 / Va; Dphi0 *= Tbar; - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; - tokamak_coordinates_factory.normalise(Lbar, Bbar); if (constn0) { diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index b316fc2693..7e4fa74011 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -883,10 +883,6 @@ class ELMpb : public PhysicsModel { V0 = V0 / Va; Dphi0 *= Tbar; - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; - tokamak_coordinates_factory.normalise(Lbar, Bbar); if (constn0) { diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 783b5b53bd..e427dbf55b 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -93,6 +93,11 @@ public: ShearFactor_m *= Lbar * Lbar * Bbar; dx_m /= Lbar * Lbar * Bbar; + // Normalise curvature term + b0xcv_m.x /= Bbar; + b0xcv_m.y *= Lbar * Lbar; + b0xcv_m.z *= Lbar * Lbar; + // bool include_curvature = options["include_curvature"].withDefault(true); // const bool include_curvature = mesh_m.get("include_curvature", true); //TODO: Create overload for mesh->get(name, default_value) to return bool or int bool include_curvature = 0; diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 645b4de97a..2914eae885 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -380,10 +380,6 @@ class ELMpb : public PhysicsModel { J0 = -MU0 * Lbar * J0 / B0; P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; - tokamak_coordinates_factory.normalise(Lbar, Bbar); BoutReal pnorm = max(P0, true); // Maximum over all processors diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 2e46628051..a6de41fce6 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -168,11 +168,6 @@ class TwoFluid : public PhysicsModel { phi0 /= Te_x; Vi0 /= Vi_x; - // Normalise curvature term - b0xcv.x /= (bmag / 1e4); - b0xcv.y *= rho_s * rho_s; - b0xcv.z *= rho_s * rho_s; - // calculate pressures pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 0fb6ff05dc..9e63164a17 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -107,13 +107,8 @@ class Interchange : public PhysicsModel { Ti0 /= Te_x; Te0 /= Te_x; - // Normalise curvature term - b0xcv.x /= (bmag / 1e4); - b0xcv.y *= rho_s * rho_s; - b0xcv.z *= rho_s * rho_s; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(Lnorm, Bnorm); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); From d953304b033c0b2825df9527ac10a3debd2f3e79 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 20:07:45 +0000 Subject: [PATCH 51/98] Pass arguments noshear include_curvature to make_tokamak_coordinates method --- examples/6field-simple/elm_6f.cxx | 25 +++--- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 10 +-- examples/elm-pb/elm_pb.cxx | 23 ++---- include/bout/tokamak_coordinates_factory.hxx | 77 +++++++------------ .../test-drift-instability/2fluid.cxx | 9 +++ .../test-interchange-instability/2fluid.cxx | 4 +- 6 files changed, 57 insertions(+), 91 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index d3d539ea2a..6938de9324 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -139,7 +139,7 @@ class Elm_6f : public PhysicsModel { BoutReal const_cse; // options - bool include_jpar0, compress0; + bool include_curvature, include_jpar0, compress0; bool evolve_pressure, continuity, gyroviscous; Field3D diff_radial, ddx_ni, ddx_n0; BoutReal diffusion_coef_Hmode0, diffusion_coef_Hmode1; @@ -374,6 +374,7 @@ class Elm_6f : public PhysicsModel { protected: int init(bool restarting) override { + bool noshear; output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); @@ -465,6 +466,7 @@ class Elm_6f : public PhysicsModel { options["phi_constraint"].doc("Use solver constraint for phi").withDefault(false); // Effects to include/exclude + include_curvature = options["include_curvature"].withDefault(true); include_jpar0 = options["include_jpar0"].withDefault(true); evolve_pressure = options["evolve_pressure"].withDefault(true); @@ -542,6 +544,8 @@ class Elm_6f : public PhysicsModel { .doc("Scale diamagnetic effects by this factor") .withDefault(1.0); + noshear = options["noshear"].withDefault(false); + relax_j_vac = options["relax_j_vac"].doc("Relax vacuum current to zero").withDefault(false); relax_j_tconst = options["relax_j_tconst"].withDefault(0.1); @@ -662,6 +666,13 @@ class Elm_6f : public PhysicsModel { J0 = 0.0; } + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (!mesh->IncIntShear) { + noshear = true; + } + ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -990,7 +1001,7 @@ class Elm_6f : public PhysicsModel { /**************** CALCULATE METRICS ******************/ - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -998,18 +1009,8 @@ class Elm_6f : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz coord->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); - - } else { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - } - // I disappears from metric - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } - // Set B field vector B0vec.covariant = false; diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 761e6a23ab..108ef3fd23 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -706,7 +706,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); @@ -801,14 +801,6 @@ class ELMpb : public PhysicsModel { J0 = 0.0; } - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - } - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); - } - ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 7e4fa74011..ecbed0390a 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -318,8 +318,6 @@ class ELMpb : public PhysicsModel { mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(); - // Set locations of staggered variables // Note, use of staggered grids in elm-pb is untested and may not be completely // implemented. Parallel boundary conditions are especially likely to be wrong. @@ -465,8 +463,6 @@ class ELMpb : public PhysicsModel { experiment_Er = options["experiment_Er"].withDefault(false); - noshear = options["noshear"].withDefault(false); - relax_j_vac = options["relax_j_vac"] .doc("Relax vacuum current to zero") .withDefault(false); @@ -741,28 +737,19 @@ class ELMpb : public PhysicsModel { J0 = 0.0; } - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - } - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + // Dimits style, using local coordinate system + if (include_curvature and !mesh->IncIntShear) { + noshear = true; } + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); - - } else { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - } - FieldMetric new_ShearFactor = 0.0; // I disappears from metric - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } ////////////////////////////////////////////////////////////// diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index e427dbf55b..2a30fdcb92 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -32,19 +32,15 @@ public: mesh.get(hthe_m, "hthe"); mesh.get(ShearFactor_m, "sinty"); mesh.get(dx_m, "dpsi"); - - // Load magnetic curvature term - b0xcv_m.covariant = false; // Read contravariant components - mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } - void setShearFactor(const bool shifted_metric_method = false) { - - if (shifted_metric_method) { - // No integrated shear in metric - ShearFactor_m = 0.0; - } - } + // void setShearFactor(const bool noshear = false) { + // + // if (shifted_metric_method) { + // // No integrated shear in metric + // ShearFactor_m = 0.0; + // } + // } BoutReal get_sign_of_bp() { if (min(Bpxy_m, true) < 0.0) { @@ -53,9 +49,7 @@ public: return 1.0; } - Coordinates* make_tokamak_coordinates(const bool shifted_metric_method = false) - { - setShearFactor(shifted_metric_method); + Coordinates* make_tokamak_coordinates(const bool noshear, const bool include_curvature) { BoutReal sign_of_bp = get_sign_of_bp(); @@ -81,57 +75,41 @@ public: coord->setJ(hthe_m / Bpxy_m); coord->setBxy(Bxy_m); - return coord; - } - - void normalise(BoutReal Lbar, BoutReal Bbar) { - Rxy_m /= Lbar; - Bpxy_m /= Bbar; - Btxy_m / Bbar; - Bxy_m / Bbar; - hthe_m / Lbar; - ShearFactor_m *= Lbar * Lbar * Bbar; - dx_m /= Lbar * Lbar * Bbar; - - // Normalise curvature term - b0xcv_m.x /= Bbar; - b0xcv_m.y *= Lbar * Lbar; - b0xcv_m.z *= Lbar * Lbar; - - // bool include_curvature = options["include_curvature"].withDefault(true); - // const bool include_curvature = mesh_m.get("include_curvature", true); //TODO: Create overload for mesh->get(name, default_value) to return bool or int - bool include_curvature = 0; - mesh_m.get(include_curvature, "true"); if (!include_curvature) { b0xcv_m = 0.0; } - // const bool noshear = mesh_m.get("noshear", false); //TODO: Create overload for mesh->get(name, default_value) to return bool or int - // const bool noshear = mesh_m.get("noshear", false); - bool noshear = 0; - mesh_m.get(noshear, "false"); - mesh_m.get("noshear", false); if (noshear) { if (include_curvature) { b0xcv_m.z += ShearFactor_m * b0xcv_m.x; } ShearFactor_m = 0.0; } - - // TODO: Do we need to include the following logic? - // if (ShiftXderivs) { - // if (mesh->IncIntShear) { - // // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - // coords->setIntShiftTorsion(I); - // - // } else { + // if (ShiftXderivs and not!mesh->IncIntShear) { // // Dimits style, using local coordinate system // if (include_curvature) { // b0xcv.z += I * b0xcv.x; // } // I = 0.0; // I disappears from metric // } - // } + + return coord; + } + + void normalise(BoutReal Lbar, BoutReal Bbar) { + + Rxy_m /= Lbar; + Bpxy_m /= Bbar; + Btxy_m / Bbar; + Bxy_m / Bbar; + hthe_m / Lbar; + ShearFactor_m *= Lbar * Lbar * Bbar; + dx_m /= Lbar * Lbar * Bbar; + + // Normalise curvature term + b0xcv_m.x /= Bbar; + b0xcv_m.y *= Lbar * Lbar; + b0xcv_m.z *= Lbar * Lbar; } const Field2D& get_Rxy() const { return Rxy_m; } @@ -142,7 +120,6 @@ public: const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } - }; #endif //BOUT_TOKAMAK_COORDINATES_FACTORY_HXX diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index a6de41fce6..7cdde63166 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -122,6 +122,15 @@ class TwoFluid : public PhysicsModel { (*globalOptions)["aparsolver"].setConditionallyUsed(); } + /************* SHIFTED RADIAL COORDINATES ************/ + + const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); + if (ShiftXderivs) { +//todo: set noshear=true; + //ShearFactor = 0.0; // I disappears from metric + //b0xcv.z += I * b0xcv.x; + } + /************** CALCULATE PARAMETERS *****************/ rho_s = 1.02 * sqrt(AA * Te_x) / ZZ / bmag; diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 9e63164a17..0f9c4c0211 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -78,10 +78,10 @@ class Interchange : public PhysicsModel { /************* SHIFTED RADIAL COORDINATES ************/ + bool noshear = false; const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { - ShearFactor = 0.0; // I disappears from metric - b0xcv.z += I * b0xcv.x; + noshear = true; } /************** CALCULATE PARAMETERS *****************/ From 31d07d62e0361adc5d92482016931fbeb03b1bde Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 20:16:19 +0000 Subject: [PATCH 52/98] Further fixes to `Pass arguments noshear include_curvature to make_tokamak_coordinates method` --- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/dalf3/dalf3.cxx | 5 +---- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 11 +++-------- tests/integrated/test-drift-instability/2fluid.cxx | 4 +--- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index a5f330cec8..5fd48f6912 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -92,7 +92,7 @@ class CWM : public PhysicsModel { "identity"); if (lowercase(ptstr) == "shifted") { - ShearFactor = 0.0; // I disappears from metric + noshear = true; } /************** CALCULATE PARAMETERS *****************/ diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index d62aba2813..fb13dfaac0 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -160,10 +160,7 @@ class DALF3 : public PhysicsModel { Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); if (lowercase(ptstr) == "shifted") { - // Dimits style, using local coordinate system - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - FieldMetric new_ShearFactor = 0.0; // I disappears from metric - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); + noshear = true; } /////////////////////////////////////////////////// diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 108ef3fd23..4a06f1cb83 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -706,6 +706,9 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } + if (!mesh->IncIntShear) { + noshear = true; + } const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); @@ -1191,14 +1194,6 @@ class ELMpb : public PhysicsModel { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); - } else { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; - } - // I disappears from metric - FieldMetric new_ShearFactor = 0.0; - tokamak_coordinates_factory.set_ShearFactor(new_ShearFactor); } return 0; diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 7cdde63166..560ac811ac 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -126,9 +126,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { -//todo: set noshear=true; - //ShearFactor = 0.0; // I disappears from metric - //b0xcv.z += I * b0xcv.x; + noshear = true; } /************** CALCULATE PARAMETERS *****************/ From aad6afc54a6828f7278ad60228bafbbef9bebff1 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 20:17:37 +0000 Subject: [PATCH 53/98] Remove unused method set_ShearFactor() --- include/bout/tokamak_coordinates_factory.hxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 2a30fdcb92..1cc063779e 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -118,8 +118,6 @@ public: const Field2D& get_Bxy() const { return Bxy_m; } const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } - - void set_ShearFactor(FieldMetric& shearFactor) { ShearFactor_m = shearFactor; } }; #endif //BOUT_TOKAMAK_COORDINATES_FACTORY_HXX From 2e4e46fb2cff938fea88294d755594312e612018 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 20:43:39 +0000 Subject: [PATCH 54/98] More fixes --- examples/6field-simple/elm_6f.cxx | 15 +++++++-------- examples/dalf3/dalf3.cxx | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 6938de9324..0a2395b61b 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -666,13 +666,6 @@ class Elm_6f : public PhysicsModel { J0 = 0.0; } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - if (!mesh->IncIntShear) { - noshear = true; - } - ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -999,8 +992,14 @@ class Elm_6f : public PhysicsModel { dump.add(eta, "eta", 0); } - /**************** CALCULATE METRICS ******************/ + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + if (!mesh->IncIntShear) { + noshear = true; + } + + /**************** CALCULATE METRICS ******************/ const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); ////////////////////////////////////////////////////////////// diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index fb13dfaac0..1cb4afce81 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -150,9 +150,6 @@ class DALF3 : public PhysicsModel { return 1; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - // SHIFTED RADIAL COORDINATES // Check type of parallel transform @@ -163,6 +160,9 @@ class DALF3 : public PhysicsModel { noshear = true; } + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + /////////////////////////////////////////////////// // Normalisation From 1cdc3b7b029e695c0e44c751d571613a0be62009 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 20:48:32 +0000 Subject: [PATCH 55/98] Finish: Move b0xcv to TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 2 +- examples/dalf3/dalf3.cxx | 4 ---- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 4 ---- examples/elm-pb/elm_pb.cxx | 4 ---- include/bout/tokamak_coordinates_factory.hxx | 5 +++++ tests/MMS/elm-pb/elm_pb.cxx | 4 ---- tests/integrated/test-interchange-instability/2fluid.cxx | 3 --- 7 files changed, 6 insertions(+), 20 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 0a2395b61b..b395b33957 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1359,7 +1359,7 @@ class Elm_6f : public PhysicsModel { ddt(U) = -SQ(tokamak_coordinates_factory.get_Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates_factory.get_Bxy(); // Grad j term - ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term + ddt(U) += 2.0 * Upara1 * tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar); // b dot grad j diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 1cb4afce81..1552a9432d 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -96,10 +96,6 @@ class DALF3 : public PhysicsModel { Pe0 = 2. * Charge * Ni0 * Te0; // Electron pressure in Pascals SAVE_ONCE(Pe0); - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - ////////////////////////////////////////////////////////////// // Options diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 4a06f1cb83..7124be7676 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -369,10 +369,6 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - mesh->get(Psixy, "psixy"); // get Psi mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index ecbed0390a..df2e956659 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -310,10 +310,6 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - mesh->get(Psixy, "psixy"); // get Psi mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 1cc063779e..eaa3af8709 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -32,6 +32,10 @@ public: mesh.get(hthe_m, "hthe"); mesh.get(ShearFactor_m, "sinty"); mesh.get(dx_m, "dpsi"); + + // Load magnetic curvature term + b0xcv_m.covariant = false; // Read contravariant components + mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } // void setShearFactor(const bool noshear = false) { @@ -116,6 +120,7 @@ public: const Field2D& get_Bpxy() const { return Bpxy_m; } const Field2D& get_Btxy() const { return Btxy_m; } const Field2D& get_Bxy() const { return Bxy_m; } + const Vector2D& get_b0xcv() const { return b0xcv_m; } const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } }; diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 2914eae885..68d209d473 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -152,10 +152,6 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - // Load metrics if (mesh->get(Rxy, "Rxy")) { // m output_error.write("Error: Cannot read Rxy from grid\n"); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 0f9c4c0211..91cfd03dd4 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -47,9 +47,6 @@ class Interchange : public PhysicsModel { GRID_LOAD(Ti0); GRID_LOAD(Te0); - // Load magnetic curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // b0xkappa terms b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY From 38d75012caa440b389259c9797e298698f7bb950 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 21:02:27 +0000 Subject: [PATCH 56/98] Further fixes to `Pass arguments noshear include_curvature to make_tokamak_coordinates method` --- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 12 ++-- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 2 +- include/bout/tokamak_coordinates_factory.hxx | 8 --- tests/MMS/GBS/gbs.cxx | 3 +- tests/MMS/elm-pb/elm_pb.cxx | 61 ++++++------------- tests/MMS/tokamak/tokamak.cxx | 5 +- .../test-drift-instability/2fluid.cxx | 2 +- .../integrated/test-laplacexy/loadmetric.cxx | 6 +- 12 files changed, 34 insertions(+), 73 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 5fd48f6912..8df10fd9ea 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -119,7 +119,7 @@ class CWM : public PhysicsModel { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) coord->setDx(dx); /************** NORMALISE QUANTITIES *****************/ diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index a3944ccea8..f8a301ee2f 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -160,20 +160,18 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); - - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - // Check type of parallel transform std::string ptstr = Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); - const bool shifted_metric_method = false; if (lowercase(ptstr) == "shifted") { - shifted_metric_method = true; + noshear = true; } + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); + // Checking for dpsi and qinty used in BOUT grids Field2D dx; if (!mesh->get(dx, "dpsi")) { diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index a67030d954..8428769c74 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -243,7 +243,7 @@ class GEM : public PhysicsModel { SAVE_ONCE(Tbar); // Timescale in seconds auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 1ef8a7f029..a9d785cebf 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -172,7 +172,7 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); // Checking for dpsi and qinty used in BOUT grids Field2D dx; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 259acb0e91..2768e1c396 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -15,7 +15,7 @@ int main(int argc, char** argv) { calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.make_tokamak_coordinates(); + tokamak_coordinates_factory.make_tokamak_coordinates(true, true); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 0088a4338d..e1f1cf2c5f 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -18,7 +18,7 @@ class WaveTest : public PhysicsModel { int init(bool UNUSED(restarting)) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index eaa3af8709..ccbbe256d4 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -38,14 +38,6 @@ public: mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } - // void setShearFactor(const bool noshear = false) { - // - // if (shifted_metric_method) { - // // No integrated shear in metric - // ShearFactor_m = 0.0; - // } - // } - BoutReal get_sign_of_bp() { if (min(Bpxy_m, true) < 0.0) { return -1.0; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index baa7d23495..c1c90c603e 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -326,8 +326,7 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { } const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(); - + coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // just define a macro for V_E dot Grad diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 68d209d473..eca331608f 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -114,10 +114,6 @@ class ELMpb : public PhysicsModel { BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) BoutReal ehyperviscos; // electron Hyper-viscosity coefficient - // Metric coefficients - Field2D Rxy, Bpxy, Btxy, B0, hthe; - Field2D I; // Shear factor - bool mms; // True if testing with Method of Manufactured Solutions const BoutReal MU0 = 4.0e-7 * PI; @@ -152,22 +148,6 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals - // Load metrics - if (mesh->get(Rxy, "Rxy")) { // m - output_error.write("Error: Cannot read Rxy from grid\n"); - return 1; - } - if (mesh->get(Bpxy, "Bpxy")) { // T - output_error.write("Error: Cannot read Bpxy from grid\n"); - return 1; - } - mesh->get(Btxy, "Btxy"); // T - mesh->get(B0, "Bxy"); // T - mesh->get(hthe, "hthe"); // m - mesh->get(I, "sinty"); // m^-2 T^-1 - - Coordinates* coords = mesh->getCoordinates(); - ////////////////////////////////////////////////////////////// // Read parameters from the options file // @@ -302,24 +282,6 @@ class ELMpb : public PhysicsModel { phi_solver = Laplacian::create(); - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - bool ShiftXderivs; - globalOptions->get("shiftXderivs", ShiftXderivs, false); // Read global flag - if (ShiftXderivs) { - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coords->setIntShiftTorsion(I); - - } else { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += I * b0xcv.x; - } - I = 0.0; // I disappears from metric - } - } ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -376,8 +338,6 @@ class ELMpb : public PhysicsModel { J0 = -MU0 * Lbar * J0 / B0; P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); - tokamak_coordinates_factory.normalise(Lbar, Bbar); - BoutReal pnorm = max(P0, true); // Maximum over all processors vacuum_pressure *= pnorm; // Get pressure from fraction @@ -401,8 +361,27 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + if (!mesh->IncIntShear) { + noshear = true; + } + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + tokamak_coordinates_factory.normalise(Lbar, Bbar); + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + bool ShiftXderivs; + globalOptions->get("shiftXderivs", ShiftXderivs, false); // Read global flag + if (ShiftXderivs) { + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + coord->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); + } + } // Set B field vector diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 745bf67b89..b04d3c716f 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -44,9 +44,6 @@ class TokamakMMS : public PhysicsModel { return 0; } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - // Load metric coefficients from the mesh - Field2D Rxy, Bpxy, Btxy, hthe, sinty; - GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics Coordinates* coords = mesh->getCoordinates(); @@ -61,7 +58,7 @@ class TokamakMMS : public PhysicsModel { } const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 560ac811ac..f65d97cf71 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -180,7 +180,7 @@ class TwoFluid : public PhysicsModel { pe0 = Te0 * Ni0; const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 6bfcf632e1..5d473c9fe9 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -3,14 +3,10 @@ #include "loadmetric.hxx" void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - // Load metric coefficients from the mesh - Field2D Rxy, Bpxy, Btxy, hthe, sinty; auto mesh = bout::globals::mesh; auto coords = mesh->getCoordinates(); - GRID_LOAD5(Rxy, Bpxy, Btxy, hthe, sinty); // Load metrics - // Checking for dpsi and qinty used in BOUT grids Field2D dx; if (!mesh->get(dx, "dpsi")) { @@ -23,7 +19,7 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { Field2D qinty; const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) tokamak_coordinates_factory.normalise(Lnorm, Bnorm); From 3a445dff766c73f8ca304cd00926a8060b8826da Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 21:17:40 +0000 Subject: [PATCH 57/98] dx is now normalised in TokamakCoordinatesFactory.normalise() --- examples/6field-simple/elm_6f.cxx | 3 +-- examples/conducting-wall-mode/cwm.cxx | 7 +++---- examples/constraints/alfven-wave/alfven.cxx | 10 --------- examples/laplacexy/alfven-wave/alfven.cxx | 13 ++---------- tests/MMS/GBS/gbs.cxx | 12 +---------- tests/MMS/tokamak/tokamak.cxx | 15 +------------ .../integrated/test-laplacexy/loadmetric.cxx | 21 ++++--------------- 7 files changed, 12 insertions(+), 69 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index b395b33957..de5d52c47e 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -374,6 +374,7 @@ class Elm_6f : public PhysicsModel { protected: int init(bool restarting) override { + bool noshear; output.write("Solving high-beta flute reduced equations\n"); @@ -811,8 +812,6 @@ class Elm_6f : public PhysicsModel { tokamak_coordinates_factory.normalise(Lbar, Bbar); - Field2D dx; - if ((!T0_fake_prof) && n0_fake_prof) { N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 8df10fd9ea..9e25d02e67 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -55,13 +55,13 @@ class CWM : public PhysicsModel { int init(bool UNUSED(restarting)) override { + bool noshear; + /************* LOAD DATA FROM GRID FILE ****************/ // Load 2D profiles (set to zero if not found) GRID_LOAD(Ni0, Te0); - FieldMetric dx = mesh->get("dpsi"); - // Load normalisation values GRID_LOAD(Te_x, Ni_x, bmag); @@ -119,8 +119,7 @@ class CWM : public PhysicsModel { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) - coord->setDx(dx); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); /************** NORMALISE QUANTITIES *****************/ diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index f8a301ee2f..94c41f11b7 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -171,16 +171,6 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - - // Checking for dpsi and qinty used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coord->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } } }; diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index a9d785cebf..360dffb430 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -171,18 +171,9 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); - - // Checking for dpsi and qinty used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coord->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index c1c90c603e..2b3844767f 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -315,18 +315,8 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - // Checking for dpsi and qinty used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coords->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // just define a macro for V_E dot Grad diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index b04d3c716f..5ffa8b466b 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -45,21 +45,8 @@ class TokamakMMS : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - Coordinates* coords = mesh->getCoordinates(); - - // Checking for dpsi used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coords->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); - + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 5d473c9fe9..2bcd5e15b6 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -5,23 +5,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto mesh = bout::globals::mesh; - auto coords = mesh->getCoordinates(); - - // Checking for dpsi and qinty used in BOUT grids - Field2D dx; - if (!mesh->get(dx, "dpsi")) { - output << "\tUsing dpsi as the x grid spacing\n"; - coords->setDx(dx); // Only use dpsi if found - } else { - // dx will have been read already from the grid - output << "\tUsing dx as the x grid spacing\n"; - } - Field2D qinty; - - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) - - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // Calculate metric components std::string ptstr; @@ -31,4 +14,8 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { if (ptstr == "shifted") { sinty = 0.0; // I disappears from metric } + + const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } From 1878107c69d7178c8cf4ee3f41d5842b3cc400ab Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 21:19:26 +0000 Subject: [PATCH 58/98] Declare variable noshear --- examples/constraints/alfven-wave/alfven.cxx | 2 ++ examples/elm-pb/elm_pb.cxx | 1 + tests/MMS/elm-pb/elm_pb.cxx | 3 +++ tests/integrated/test-laplacexy/loadmetric.cxx | 4 +++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 94c41f11b7..a59a59c901 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -160,6 +160,8 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { + bool noshear; + // Check type of parallel transform std::string ptstr = Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index df2e956659..9cd9ae46fe 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -297,6 +297,7 @@ class ELMpb : public PhysicsModel { protected: int init(bool restarting) override { + bool noshear; output.write("Solving high-beta flute reduced equations\n"); diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index eca331608f..11cf39ff81 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -137,6 +137,9 @@ class ELMpb : public PhysicsModel { public: int init(bool restarting) { + + bool noshear; + output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 2bcd5e15b6..8befc451be 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -4,6 +4,8 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { + bool noshear; + auto mesh = bout::globals::mesh; // Calculate metric components @@ -12,7 +14,7 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { // Convert to lower case for comparison ptstr = lowercase(ptstr); if (ptstr == "shifted") { - sinty = 0.0; // I disappears from metric + noshear = true; } const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); From 1016401fbbd6727bffdfa79d88c846b28a68ac2f Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 21:21:55 +0000 Subject: [PATCH 59/98] Further small fixes --- examples/laplacexy/laplace_perp/test.cxx | 2 +- tests/integrated/test-interchange-instability/2fluid.cxx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 2768e1c396..5cd024650e 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -15,7 +15,7 @@ int main(int argc, char** argv) { calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); } /////////////////////////////////////// diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 91cfd03dd4..b94d38103a 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -106,7 +106,6 @@ class Interchange : public PhysicsModel { const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); // Tell BOUT++ which variables to evolve From bf00451f00800c689eb31ae3062f42aa6ccca60a Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 21:37:35 +0000 Subject: [PATCH 60/98] Declare variable noshear --- examples/dalf3/dalf3.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 1552a9432d..f7dc4ab964 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -84,6 +84,8 @@ class DALF3 : public PhysicsModel { protected: int init(bool UNUSED(restarting)) override { + bool noshear; + ///////////////////////////////////////////////////// // Load data from the grid From 1e3ada627c9cdafc4126b918830234c6104fd004 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Sun, 10 Nov 2024 21:40:19 +0000 Subject: [PATCH 61/98] noshear and include_curvature variables don't exist in gem example --- examples/gyro-gem/gem.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 8428769c74..bb53a71514 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -243,7 +243,7 @@ class GEM : public PhysicsModel { SAVE_ONCE(Tbar); // Timescale in seconds auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { From 7a618ff59045b2b278561fc252ec0b53c4d99294 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 11 Nov 2024 09:47:16 +0000 Subject: [PATCH 62/98] TokamakCoordinatesFactory instance can't be const --- examples/laplacexy/alfven-wave/alfven.cxx | 3 ++- tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- tests/MMS/tokamak/tokamak.cxx | 2 +- tests/integrated/test-drift-instability/2fluid.cxx | 2 +- tests/integrated/test-interchange-instability/2fluid.cxx | 2 +- tests/integrated/test-laplacexy/loadmetric.cxx | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 360dffb430..be9e216d9b 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -171,7 +171,8 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 2b3844767f..413c1318c1 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -315,7 +315,7 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 11cf39ff81..1723c815e6 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -370,7 +370,7 @@ class ELMpb : public PhysicsModel { noshear = true; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); tokamak_coordinates_factory.normalise(Lbar, Bbar); diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 5ffa8b466b..3994621f1c 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -45,7 +45,7 @@ class TokamakMMS : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index f65d97cf71..da7582a50f 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -179,7 +179,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index b94d38103a..c5e8f778ad 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -104,7 +104,7 @@ class Interchange : public PhysicsModel { Ti0 /= Te_x; Te0 /= Te_x; - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 8befc451be..4827d3535b 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -17,7 +17,7 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { noshear = true; } - const auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); } From 8bf978e63b9a588dc661f7b4b4c82bed351447d8 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 18 Nov 2024 13:00:29 +0000 Subject: [PATCH 63/98] include_curvature variable doesn't exist in test-drift-instability/2fluid example. Declare variable noshear --- tests/integrated/test-drift-instability/2fluid.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index da7582a50f..3699b71b6e 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -124,6 +124,7 @@ class TwoFluid : public PhysicsModel { /************* SHIFTED RADIAL COORDINATES ************/ + bool noshear = false; const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { noshear = true; @@ -180,8 +181,7 @@ class TwoFluid : public PhysicsModel { pe0 = Te0 * Ni0; auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature) - + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); /**************** SET EVOLVING VARIABLES *************/ From 1e3eb2a6e305e7c052078a45e680720c6b601d14 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 18 Nov 2024 13:03:59 +0000 Subject: [PATCH 64/98] Fix: Move b0xcv to TokamakCoordinatesFactory --- tests/integrated/test-drift-instability/2fluid.cxx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 3699b71b6e..91125317f1 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -58,6 +58,8 @@ class TwoFluid : public PhysicsModel { FieldGroup comms; // Group of variables for communications + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + Coordinates* coord; // Coordinate system CELL_LOC maybe_ylow; @@ -180,7 +182,6 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); @@ -337,8 +338,8 @@ class TwoFluid : public PhysicsModel { if (evolve_te) { ddt(Te) -= vE_Grad(Te0, phi) + vE_Grad(Te, phi0) + vE_Grad(Te, phi); ddt(Te) -= Vpar_Grad_par(Ve, Te0) + Vpar_Grad_par(Ve0, Te) + Vpar_Grad_par(Ve, Te); - ddt(Te) += 1.333 * Te0 * (V_dot_Grad(b0xcv, pe) / Ni0 - V_dot_Grad(b0xcv, phi)); - ddt(Te) += 3.333 * Te0 * V_dot_Grad(b0xcv, Te); + ddt(Te) += 1.333 * Te0 * (V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), pe) / Ni0 - V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), phi)); + ddt(Te) += 3.333 * Te0 * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), Te); ddt(Te) += (0.6666667 / Ni0) * Div_par_K_Grad_par(kapa_Te, Te); } @@ -349,8 +350,8 @@ class TwoFluid : public PhysicsModel { ddt(Ti) -= vE_Grad(Ti0, phi) + vE_Grad(Ti, phi0) + vE_Grad(Ti, phi); ddt(Ti) -= Vpar_Grad_par(Vi, Ti0) + Vpar_Grad_par(Vi0, Ti) + Vpar_Grad_par(Vi, Ti); ddt(Ti) += - 1.333 * (Ti0 * V_dot_Grad(b0xcv, pe) / Ni0 - Ti * V_dot_Grad(b0xcv, phi)); - ddt(Ti) -= 3.333 * Ti0 * V_dot_Grad(b0xcv, Ti); + 1.333 * (Ti0 * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), pe) / Ni0 - Ti * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), phi)); + ddt(Ti) -= 3.333 * Ti0 * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), Ti); ddt(Ti) += (0.6666667 / Ni0) * Div_par_K_Grad_par(kapa_Ti, Ti); } From 3da9f1765dbe9596fc6bf85a94d876accb3bb560 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 09:48:31 +0000 Subject: [PATCH 65/98] Set ShearFactor before using it --- include/bout/tokamak_coordinates_factory.hxx | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index ccbbe256d4..6b7834ff63 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -49,6 +49,24 @@ public: BoutReal sign_of_bp = get_sign_of_bp(); + if (!include_curvature) { + b0xcv_m = 0.0; + } + + if (noshear) { + if (include_curvature) { + b0xcv_m.z += ShearFactor_m * b0xcv_m.x; + } + ShearFactor_m = 0.0; + } + // if (ShiftXderivs and not!mesh->IncIntShear) { + // // Dimits style, using local coordinate system + // if (include_curvature) { + // b0xcv.z += I * b0xcv.x; + // } + // I = 0.0; // I disappears from metric + // } + auto* coord = mesh_m.getCoordinates(); const auto g11 = SQ(Rxy_m * Bpxy_m); @@ -71,24 +89,6 @@ public: coord->setJ(hthe_m / Bpxy_m); coord->setBxy(Bxy_m); - if (!include_curvature) { - b0xcv_m = 0.0; - } - - if (noshear) { - if (include_curvature) { - b0xcv_m.z += ShearFactor_m * b0xcv_m.x; - } - ShearFactor_m = 0.0; - } - // if (ShiftXderivs and not!mesh->IncIntShear) { - // // Dimits style, using local coordinate system - // if (include_curvature) { - // b0xcv.z += I * b0xcv.x; - // } - // I = 0.0; // I disappears from metric - // } - return coord; } From 1db3688ef4c240cabdd38ae28b15ef95d718a228 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 09:51:15 +0000 Subject: [PATCH 66/98] Extract method set_shearfactor_and_curvature_term() --- include/bout/tokamak_coordinates_factory.hxx | 41 ++++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 6b7834ff63..7a1eced50b 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -49,23 +49,7 @@ public: BoutReal sign_of_bp = get_sign_of_bp(); - if (!include_curvature) { - b0xcv_m = 0.0; - } - - if (noshear) { - if (include_curvature) { - b0xcv_m.z += ShearFactor_m * b0xcv_m.x; - } - ShearFactor_m = 0.0; - } - // if (ShiftXderivs and not!mesh->IncIntShear) { - // // Dimits style, using local coordinate system - // if (include_curvature) { - // b0xcv.z += I * b0xcv.x; - // } - // I = 0.0; // I disappears from metric - // } + set_shearfactor_and_curvature_term(noshear, include_curvature); auto* coord = mesh_m.getCoordinates(); @@ -92,6 +76,29 @@ public: return coord; } + void set_shearfactor_and_curvature_term(const bool noshear, const bool include_curvature) { + + if (!include_curvature) { + b0xcv_m = 0.0; + } + + if (noshear) { + if (include_curvature) { + b0xcv_m.z += ShearFactor_m * b0xcv_m.x; + } + ShearFactor_m = 0.0; + } + + // if (ShiftXderivs and not!mesh->IncIntShear) { + // // Dimits style, using local coordinate system + // if (include_curvature) { + // b0xcv.z += I * b0xcv.x; + // } + // I = 0.0; // I disappears from metric + // } + + } + void normalise(BoutReal Lbar, BoutReal Bbar) { Rxy_m /= Lbar; From 85df36c42a836bf2b7192430ae4babad6f9d4db2 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 09:56:54 +0000 Subject: [PATCH 67/98] clang-tidy: directly include headers --- include/bout/tokamak_coordinates_factory.hxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 7a1eced50b..9506b2e1e5 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -3,6 +3,12 @@ #define BOUT_TOKAMAK_COORDINATES_FACTORY_HXX #include "bout.hxx" +#include "bout/utils.hxx" +#include "bout/bout_types.hxx" +#include "bout/christoffel_symbols.hxx" +#include "bout/vector2d.hxx" +#include "bout/field2d.hxx" +#include "bout/coordinates.hxx" class TokamakCoordinatesFactory { From b02df20aaf875565a797cdaad40db7471bb7e241 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 10:29:05 +0000 Subject: [PATCH 68/98] Access b0xcv (curvature term) through getter --- examples/dalf3/dalf3.cxx | 6 +++--- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 13 ++++--------- examples/elm-pb/elm_pb.cxx | 13 ++++--------- tests/MMS/elm-pb/elm_pb.cxx | 13 +++++-------- .../test-interchange-instability/2fluid.cxx | 10 ++++------ 5 files changed, 20 insertions(+), 35 deletions(-) diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index f7dc4ab964..134d30e623 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -53,7 +53,6 @@ class DALF3 : public PhysicsModel { Field3D phi, apar, jpar; Field2D B0, Pe0, Jpar0; - Vector2D b0xcv; Field2D eta; // Collisional damping (resistivity) BoutReal beta_hat, mu_hat; @@ -81,6 +80,8 @@ class DALF3 : public PhysicsModel { std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) Field2D phi2D; // Axisymmetric potential, used when split_n0=true + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + protected: int init(bool UNUSED(restarting)) override { @@ -158,7 +159,6 @@ class DALF3 : public PhysicsModel { noshear = true; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); /////////////////////////////////////////////////// @@ -265,7 +265,7 @@ class DALF3 : public PhysicsModel { Field3D Kappa(const Field3D& f) { if (curv_kappa) { // Use the b0xcv vector from grid file - return -2. * b0xcv * Grad(f) / B0; + return -2. * tokamak_coordinates_factory.get_b0xcv() * Grad(f) / B0; } return 2. * bracket(log(B0), f, bm); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 7124be7676..71a4bb9ba8 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -96,7 +96,6 @@ class ELMpb : public PhysicsModel { private: // 2D inital profiles Field2D J0, P0; // Current and pressure - Vector2D b0xcv; // Curvature term Field2D beta; // Used for Vpar terms Coordinates::FieldMetric gradparB; Field2D phi0; // When diamagnetic terms used @@ -792,10 +791,6 @@ class ELMpb : public PhysicsModel { } } - if (!include_curvature) { - b0xcv = 0.0; - } - if (!include_jpar0) { J0 = 0.0; } @@ -1696,7 +1691,7 @@ class ELMpb : public PhysicsModel { // ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); // } - ddt(U) += b0xcv * Grad(P); // curvature term + ddt(U) += tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term // if (!nogradparj) { // Parallel current term // ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j @@ -1872,7 +1867,7 @@ class ELMpb : public PhysicsModel { ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); if (phi_curv) { - ddt(P) -= 2. * beta * b0xcv * Grad(phi); + ddt(P) -= 2. * beta * tokamak_coordinates_factory.get_b0xcv() * Grad(phi); } // Vpar equation @@ -1972,7 +1967,7 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); Field3D U1 = ddt(U); - U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * tokamak_coordinates_factory.get_b0xcv()) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -2031,7 +2026,7 @@ class ELMpb : public PhysicsModel { JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(metric->Bxy()) * Grad_par(Jpar, CELL_CENTRE) + Field3D JU = tokamak_coordinates_factory.get_b0xcv() * Grad(ddt(P)) - SQ(metric->Bxy()) * Grad_par(Jpar, CELL_CENTRE) + SQ(metric->Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 9cd9ae46fe..11d4f34c50 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -38,7 +38,6 @@ class ELMpb : public PhysicsModel { private: // 2D inital profiles Field2D J0, P0; // Current and pressure - Vector2D b0xcv; // Curvature term Field2D beta; // Used for Vpar terms Coordinates::FieldMetric gradparB; Field2D phi0; // When diamagnetic terms used @@ -726,10 +725,6 @@ class ELMpb : public PhysicsModel { } } - if (!include_curvature) { - b0xcv = 0.0; - } - if (!include_jpar0) { J0 = 0.0; } @@ -1504,7 +1499,7 @@ class ELMpb : public PhysicsModel { ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } - ddt(U) += b0xcv * Grad(P); // curvature term + ddt(U) += tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term if (!nogradparj) { // Parallel current term ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j @@ -1678,7 +1673,7 @@ class ELMpb : public PhysicsModel { ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); if (phi_curv) { - ddt(P) -= 2. * beta * b0xcv * Grad(phi); + ddt(P) -= 2. * beta * tokamak_coordinates_factory.get_b0xcv() * Grad(phi); } // Vpar equation @@ -1777,7 +1772,7 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * tokamak_coordinates_factory.get_b0xcv()) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1834,7 +1829,7 @@ class ELMpb : public PhysicsModel { JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) + Field3D JU = tokamak_coordinates_factory.get_b0xcv() * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) + SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 1723c815e6..529d279e49 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -29,7 +29,6 @@ class ELMpb : public PhysicsModel { private: // 2D inital profiles Field2D J0, P0; // Current and pressure - Vector2D b0xcv; // Curvature term Field2D beta, gradparB; // Used for Vpar terms Field2D phi0; // When diamagnetic terms used @@ -122,6 +121,9 @@ class ELMpb : public PhysicsModel { // Communication objects FieldGroup comms; + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + + // Parallel gradient along perturbed field-line const Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) { Field3D result; @@ -272,10 +274,6 @@ class ELMpb : public PhysicsModel { OPTION(globalOptions->getSection("solver"), mms, false); - if (!include_curvature) { - b0xcv = 0.0; - } - if (!include_jpar0) { J0 = 0.0; } @@ -370,7 +368,6 @@ class ELMpb : public PhysicsModel { noshear = true; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); tokamak_coordinates_factory.normalise(Lbar, Bbar); @@ -565,7 +562,7 @@ class ELMpb : public PhysicsModel { ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); // Grad j term - ddt(U) += b0xcv * Grad(P); // curvature term + ddt(U) += tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term // Parallel current term ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j @@ -615,7 +612,7 @@ class ELMpb : public PhysicsModel { ddt(P) -= beta * Div_par_CtoL(Vpar); if (phi_curv) { - ddt(P) -= 2. * beta * b0xcv * Grad(phi); + ddt(P) -= 2. * beta * tokamak_coordinates_factory.get_b0xcv() * Grad(phi); } // Vpar equation diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index c5e8f778ad..c0078e03a2 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -18,7 +18,6 @@ class Interchange : public PhysicsModel { // 2D initial profiles Field2D Ni0, Ti0, Te0; - Vector2D b0xcv; // for curvature terms // 3D evolving fields Field3D rho, Ni; @@ -34,6 +33,8 @@ class Interchange : public PhysicsModel { Coordinates* coord; + TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + protected: int init(bool UNUSED(restarting)) override { Field2D I; // Shear factor @@ -47,9 +48,6 @@ class Interchange : public PhysicsModel { GRID_LOAD(Ti0); GRID_LOAD(Te0); - - b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY - // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); @@ -104,7 +102,7 @@ class Interchange : public PhysicsModel { Ti0 /= Te_x; Te0 /= Te_x; - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); +// b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY // TODO: Check if needed coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); @@ -134,7 +132,7 @@ class Interchange : public PhysicsModel { ddt(Ni) = -b0xGrad_dot_Grad(phi, Ni0) / coord->Bxy(); // VORTICITY - ddt(rho) = 2.0 * coord->Bxy() * b0xcv * Grad(pei); + ddt(rho) = 2.0 * coord->Bxy() * tokamak_coordinates_factory.get_b0xcv() * Grad(pei); return (0); } From ebcce8c3039ba8e9ac32fe3a3af409d95b1bfa2d Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 10:54:27 +0000 Subject: [PATCH 69/98] Fix tests gbs and conducting-wall-mode/cwm - don't redefine coords object --- examples/conducting-wall-mode/cwm.cxx | 2 +- tests/MMS/GBS/gbs.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 9e25d02e67..c576a8932a 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -119,7 +119,7 @@ class CWM : public PhysicsModel { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); /************** NORMALISE QUANTITIES *****************/ diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 413c1318c1..a678c06a53 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -316,7 +316,7 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); // just define a macro for V_E dot Grad From 2d228ceae655b896f260600f381f470fb8905595 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 10:59:44 +0000 Subject: [PATCH 70/98] Initialise noshear to false --- examples/conducting-wall-mode/cwm.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index c576a8932a..76b7237bea 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -55,7 +55,7 @@ class CWM : public PhysicsModel { int init(bool UNUSED(restarting)) override { - bool noshear; + bool noshear = false; /************* LOAD DATA FROM GRID FILE ****************/ From 192b45c4e15bf468f561f6824a61d71302a75cc3 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 11:02:53 +0000 Subject: [PATCH 71/98] Must call tokamak_coordinates_factory.normalise() before tokamak_coordinates_factory.make_tokamak_coordinates() --- examples/conducting-wall-mode/cwm.cxx | 3 +-- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/dalf3/dalf3.cxx | 3 +-- examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 17 ++++++++--------- examples/elm-pb/elm_pb.cxx | 3 +-- examples/gyro-gem/gem.cxx | 6 +++--- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- tests/MMS/tokamak/tokamak.cxx | 2 +- .../test-drift-instability/2fluid.cxx | 2 +- .../test-interchange-instability/2fluid.cxx | 2 +- tests/integrated/test-laplacexy/loadmetric.cxx | 2 +- 13 files changed, 22 insertions(+), 26 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 76b7237bea..1a6bb4e095 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -119,7 +119,6 @@ class CWM : public PhysicsModel { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); /************** NORMALISE QUANTITIES *****************/ @@ -131,11 +130,11 @@ class CWM : public PhysicsModel { // Normalise geometry tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); - /**************** SET EVOLVING VARIABLES *************/ // Tell BOUT++ which variables to evolve diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index a59a59c901..0e38e183e4 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -171,8 +171,8 @@ class Alfven : public PhysicsModel { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 134d30e623..2f800ad825 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -159,8 +159,6 @@ class DALF3 : public PhysicsModel { noshear = true; } - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); - /////////////////////////////////////////////////// // Normalisation @@ -214,6 +212,7 @@ class DALF3 : public PhysicsModel { // Metrics tokamak_coordinates_factory.normalise(rho_s, Bnorm); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 71a4bb9ba8..05fb9363e0 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -704,6 +704,14 @@ class ELMpb : public PhysicsModel { if (!mesh->IncIntShear) { noshear = true; } + + if (mesh->get(Bbar, "bmag") != 0) { // Typical magnetic field + Bbar = 1.0; + } + if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale + Lbar = 1.0; + } + tokamak_coordinates_factory.normalise(Lbar, Bbar); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); @@ -798,13 +806,6 @@ class ELMpb : public PhysicsModel { ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES - if (mesh->get(Bbar, "bmag") != 0) { // Typical magnetic field - Bbar = 1.0; - } - if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale - Lbar = 1.0; - } - Va = sqrt(Bbar * Bbar / (MU0 * density * Mi)); Tbar = Lbar / Va; @@ -913,8 +914,6 @@ class ELMpb : public PhysicsModel { V0 = V0 / Va; Dphi0 *= Tbar; - tokamak_coordinates_factory.normalise(Lbar, Bbar); - if (constn0) { T0_fake_prof = false; n0_fake_prof = false; diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 11d4f34c50..f73c7ff677 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -734,8 +734,6 @@ class ELMpb : public PhysicsModel { noshear = true; } - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); - ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -863,6 +861,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= Tbar; tokamak_coordinates_factory.normalise(Lbar, Bbar); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); if (constn0) { T0_fake_prof = false; diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index bb53a71514..f577254e94 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -243,7 +243,6 @@ class GEM : public PhysicsModel { SAVE_ONCE(Tbar); // Timescale in seconds auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { @@ -253,6 +252,9 @@ class GEM : public PhysicsModel { Bbar = options["Bbar"].withDefault(Bbar); // Override in options file SAVE_ONCE(Bbar); + tokamak_coordinates_factory.normalise(Lbar, Bbar); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); @@ -344,8 +346,6 @@ class GEM : public PhysicsModel { output << "\tNormalised rho_e = " << rho_e << endl; output << "\tNormalised rho_i = " << rho_i << endl; - tokamak_coordinates_factory.normalise(Lbar, Bbar); - // Set B field vector B0vec.covariant = false; diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index be9e216d9b..617e7bee31 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -173,8 +173,8 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index a678c06a53..d6795fbe37 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -316,8 +316,8 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 529d279e49..e8d946e3b6 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -368,8 +368,8 @@ class ELMpb : public PhysicsModel { noshear = true; } - coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); tokamak_coordinates_factory.normalise(Lbar, Bbar); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 3994621f1c..da3b75acb6 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -46,8 +46,8 @@ class TokamakMMS : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 91125317f1..a1d3bea5b7 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -182,8 +182,8 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index c0078e03a2..4f024aebcb 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -103,8 +103,8 @@ class Interchange : public PhysicsModel { Te0 /= Te_x; // b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY // TODO: Check if needed - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); // Tell BOUT++ which variables to evolve SOLVE_FOR2(rho, Ni); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 4827d3535b..c3151abbec 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -18,6 +18,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); } From bff47348e55ada87771f6ff2c544c8c97c4fa579 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 11:51:26 +0000 Subject: [PATCH 72/98] Pass (optional) ShearFactor parameter to TokamakCoordinatesFactory.normalise() --- examples/conducting-wall-mode/cwm.cxx | 2 +- include/bout/tokamak_coordinates_factory.hxx | 4 ++-- tests/integrated/test-drift-instability/2fluid.cxx | 2 +- tests/integrated/test-interchange-instability/2fluid.cxx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 1a6bb4e095..98637059e0 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -129,7 +129,7 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); // Set nu diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 9506b2e1e5..6b2a3650f8 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -105,14 +105,14 @@ public: } - void normalise(BoutReal Lbar, BoutReal Bbar) { + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor=1.0) { Rxy_m /= Lbar; Bpxy_m /= Bbar; Btxy_m / Bbar; Bxy_m / Bbar; hthe_m / Lbar; - ShearFactor_m *= Lbar * Lbar * Bbar; + ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; dx_m /= Lbar * Lbar * Bbar; // Normalise curvature term diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index a1d3bea5b7..745dbe818a 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -182,7 +182,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 4f024aebcb..2a5aa3f133 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -103,7 +103,7 @@ class Interchange : public PhysicsModel { Te0 /= Te_x; // b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY // TODO: Check if needed - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4); + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); // Tell BOUT++ which variables to evolve From a3156c98a3c34fbb14d92ffdd3c3ebc9d750a769 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 13:40:43 +0000 Subject: [PATCH 73/98] Fix mix up between the two shear factor variables --- include/bout/tokamak_coordinates_factory.hxx | 1 - tests/integrated/test-drift-instability/2fluid.cxx | 2 +- tests/integrated/test-interchange-instability/2fluid.cxx | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 6b2a3650f8..68a617838a 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -92,7 +92,6 @@ public: if (include_curvature) { b0xcv_m.z += ShearFactor_m * b0xcv_m.x; } - ShearFactor_m = 0.0; } // if (ShiftXderivs and not!mesh->IncIntShear) { diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 745dbe818a..dbe0dfca35 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -66,7 +66,6 @@ class TwoFluid : public PhysicsModel { protected: int init(bool UNUSED(restarting)) override { - Field2D I; // Shear factor output.write("Solving 6-variable 2-fluid equations\n"); @@ -129,6 +128,7 @@ class TwoFluid : public PhysicsModel { bool noshear = false; const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { + ShearFactor = 0.0; // I disappears from metric noshear = true; } diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 2a5aa3f133..815bd85101 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -37,7 +37,6 @@ class Interchange : public PhysicsModel { protected: int init(bool UNUSED(restarting)) override { - Field2D I; // Shear factor output << "Solving 2-variable equations\n"; @@ -76,6 +75,7 @@ class Interchange : public PhysicsModel { bool noshear = false; const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { + ShearFactor = 0.0; // I disappears from metric noshear = true; } From c52c7e0eccf28c0c5f807cb96e1cdcb641db20de Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 19 Nov 2024 15:21:21 +0000 Subject: [PATCH 74/98] Make variable const --- include/bout/tokamak_coordinates_factory.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 68a617838a..a4ebcc65fc 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -53,7 +53,7 @@ public: Coordinates* make_tokamak_coordinates(const bool noshear, const bool include_curvature) { - BoutReal sign_of_bp = get_sign_of_bp(); + const BoutReal sign_of_bp = get_sign_of_bp(); set_shearfactor_and_curvature_term(noshear, include_curvature); From f7532aa8a75d4c38e36ebc253c33a194cb5642bd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Thu, 21 Nov 2024 12:05:28 +0000 Subject: [PATCH 75/98] Fix: "Must call tokamak_coordinates_factory.normalise() before tokamak_coordinates_factory.make_tokamak_coordinates()" --- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/elm-pb/elm_pb.cxx | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 0e38e183e4..3ac5ecb067 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -172,7 +172,7 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); } }; diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index f73c7ff677..4f19fb573c 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -734,14 +734,6 @@ class ELMpb : public PhysicsModel { noshear = true; } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); - } - ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -863,6 +855,15 @@ class ELMpb : public PhysicsModel { tokamak_coordinates_factory.normalise(Lbar, Bbar); const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); + } + if (constn0) { T0_fake_prof = false; n0_fake_prof = false; From dfedefbae2280c7e2a9ab46051dc47568e6eb519 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Thu, 21 Nov 2024 17:42:05 +0000 Subject: [PATCH 76/98] Fix TokamakCoordinatesFactory: Set dx --- include/bout/tokamak_coordinates_factory.hxx | 1 + 1 file changed, 1 insertion(+) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index a4ebcc65fc..3b59fbec3a 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -78,6 +78,7 @@ public: coord->setJ(hthe_m / Bpxy_m); coord->setBxy(Bxy_m); + coord->setDx(dx_m); return coord; } From 183af00b6397d320e2bfa136baff9f5dfb3082cb Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 22 Nov 2024 16:15:20 +0000 Subject: [PATCH 77/98] Fix syntax typo (compound assignments operators in normalise() method) --- include/bout/tokamak_coordinates_factory.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 3b59fbec3a..cfa2706c62 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -109,9 +109,9 @@ public: Rxy_m /= Lbar; Bpxy_m /= Bbar; - Btxy_m / Bbar; - Bxy_m / Bbar; - hthe_m / Lbar; + Btxy_m /= Bbar; + Bxy_m /= Bbar; + hthe_m /= Lbar; ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; dx_m /= Lbar * Lbar * Bbar; From 8410df2f60aa236bb1b7356358e0817c4bc17585 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 22 Nov 2024 16:51:01 +0000 Subject: [PATCH 78/98] Remove b0xcv (curvature term) from TokamakCoordinatesFactory --- examples/6field-simple/elm_6f.cxx | 35 ++++++++++++++-- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/dalf3/dalf3.cxx | 15 ++++++- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 40 ++++++++++++++++--- examples/elm-pb/elm_pb.cxx | 40 +++++++++++++++---- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 2 +- include/bout/tokamak_coordinates_factory.hxx | 39 ++---------------- tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/GBS/mms-slab2d.py | 10 ++++- tests/MMS/GBS/mms-slab3d.py | 10 ++++- tests/MMS/elm-pb/elm_pb.cxx | 28 +++++++++++-- tests/MMS/tokamak/tokamak.cxx | 2 +- .../test-drift-instability/2fluid.cxx | 21 +++++++--- .../test-interchange-instability/2fluid.cxx | 23 +++++++++-- .../integrated/test-laplacexy/loadmetric.cxx | 2 +- 19 files changed, 203 insertions(+), 76 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index de5d52c47e..7afdb6a31b 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -36,7 +36,8 @@ class Elm_6f : public PhysicsModel { // 2D inital profiles /// Current and pressure Field2D J0, P0; - + /// Curvature term + Vector2D b0xcv; /// When diamagnetic terms used Field2D phi0; @@ -388,6 +389,10 @@ class Elm_6f : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + ////////////////////////////////////////////////////////////// // Read parameters from the options file // @@ -663,10 +668,30 @@ class Elm_6f : public PhysicsModel { phi_curv = options["phi_curv"].doc("Compressional ExB terms").withDefault(true); g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); + if (!include_curvature) { + b0xcv = 0.0; + } + if (!include_jpar0) { J0 = 0.0; } + if (noshear) { + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + } + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (not mesh->IncIntShear) { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + } + ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -812,6 +837,10 @@ class Elm_6f : public PhysicsModel { tokamak_coordinates_factory.normalise(Lbar, Bbar); + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; + if ((!T0_fake_prof) && n0_fake_prof) { N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); @@ -999,7 +1028,7 @@ class Elm_6f : public PhysicsModel { } /**************** CALCULATE METRICS ******************/ - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -1358,7 +1387,7 @@ class Elm_6f : public PhysicsModel { ddt(U) = -SQ(tokamak_coordinates_factory.get_Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates_factory.get_Bxy(); // Grad j term - ddt(U) += 2.0 * Upara1 * tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term + ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar); // b dot grad j diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 98637059e0..a3b1720da7 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -130,7 +130,7 @@ class CWM : public PhysicsModel { // Normalise geometry tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 3ac5ecb067..2b9b2beb91 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -172,7 +172,7 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 2f800ad825..8bba66d656 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -53,6 +53,7 @@ class DALF3 : public PhysicsModel { Field3D phi, apar, jpar; Field2D B0, Pe0, Jpar0; + Vector2D b0xcv; Field2D eta; // Collisional damping (resistivity) BoutReal beta_hat, mu_hat; @@ -99,6 +100,10 @@ class DALF3 : public PhysicsModel { Pe0 = 2. * Charge * Ni0 * Te0; // Electron pressure in Pascals SAVE_ONCE(Pe0); + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + ////////////////////////////////////////////////////////////// // Options @@ -156,6 +161,8 @@ class DALF3 : public PhysicsModel { Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); if (lowercase(ptstr) == "shifted") { + // Dimits style, using local coordinate system + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; noshear = true; } @@ -210,9 +217,13 @@ class DALF3 : public PhysicsModel { hyper_viscosity /= wci * SQ(SQ(rho_s)); viscosity_par /= wci * SQ(rho_s); + b0xcv.x /= Bnorm; + b0xcv.y *= rho_s * rho_s; + b0xcv.z *= rho_s * rho_s; + // Metrics tokamak_coordinates_factory.normalise(rho_s, Bnorm); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); @@ -264,7 +275,7 @@ class DALF3 : public PhysicsModel { Field3D Kappa(const Field3D& f) { if (curv_kappa) { // Use the b0xcv vector from grid file - return -2. * tokamak_coordinates_factory.get_b0xcv() * Grad(f) / B0; + return -2. * b0xcv * Grad(f) / B0; } return 2. * bracket(log(B0), f, bm); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 05fb9363e0..7edfbe8e38 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -96,6 +96,7 @@ class ELMpb : public PhysicsModel { private: // 2D inital profiles Field2D J0, P0; // Current and pressure + Vector2D b0xcv; // Curvature term Field2D beta; // Used for Vpar terms Coordinates::FieldMetric gradparB; Field2D phi0; // When diamagnetic terms used @@ -368,6 +369,10 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + mesh->get(Psixy, "psixy"); // get Psi mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux @@ -712,7 +717,7 @@ class ELMpb : public PhysicsModel { Lbar = 1.0; } tokamak_coordinates_factory.normalise(Lbar, Bbar); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); @@ -799,10 +804,30 @@ class ELMpb : public PhysicsModel { } } + if (!include_curvature) { + b0xcv = 0.0; + } + if (!include_jpar0) { J0 = 0.0; } + if (noshear) { + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + } + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (not mesh->IncIntShear) { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + } + ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -914,6 +939,11 @@ class ELMpb : public PhysicsModel { V0 = V0 / Va; Dphi0 *= Tbar; + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; + + if (constn0) { T0_fake_prof = false; n0_fake_prof = false; @@ -1690,7 +1720,7 @@ class ELMpb : public PhysicsModel { // ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); // } - ddt(U) += tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term + ddt(U) += b0xcv * Grad(P); // curvature term // if (!nogradparj) { // Parallel current term // ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j @@ -1866,7 +1896,7 @@ class ELMpb : public PhysicsModel { ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); if (phi_curv) { - ddt(P) -= 2. * beta * tokamak_coordinates_factory.get_b0xcv() * Grad(phi); + ddt(P) -= 2. * beta * b0xcv * Grad(phi); } // Vpar equation @@ -1966,7 +1996,7 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); Field3D U1 = ddt(U); - U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * tokamak_coordinates_factory.get_b0xcv()) * Grad(P); + U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -2025,7 +2055,7 @@ class ELMpb : public PhysicsModel { JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = tokamak_coordinates_factory.get_b0xcv() * Grad(ddt(P)) - SQ(metric->Bxy()) * Grad_par(Jpar, CELL_CENTRE) + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(metric->Bxy()) * Grad_par(Jpar, CELL_CENTRE) + SQ(metric->Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 4f19fb573c..2b4603e9c8 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -38,6 +38,7 @@ class ELMpb : public PhysicsModel { private: // 2D inital profiles Field2D J0, P0; // Current and pressure + Vector2D b0xcv; // Curvature term Field2D beta; // Used for Vpar terms Coordinates::FieldMetric gradparB; Field2D phi0; // When diamagnetic terms used @@ -310,6 +311,10 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + mesh->get(Psixy, "psixy"); // get Psi mesh->get(Psiaxis, "psi_axis"); // axis flux mesh->get(Psibndry, "psi_bndry"); // edge flux @@ -725,13 +730,28 @@ class ELMpb : public PhysicsModel { } } + if (!include_curvature) { + b0xcv = 0.0; + } + if (!include_jpar0) { J0 = 0.0; } - // Dimits style, using local coordinate system - if (include_curvature and !mesh->IncIntShear) { - noshear = true; + if (noshear) { + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + } + + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + if (not mesh->IncIntShear) { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } } ////////////////////////////////////////////////////////////// @@ -852,8 +872,12 @@ class ELMpb : public PhysicsModel { V0 = V0 / Va; Dphi0 *= Tbar; + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; + tokamak_coordinates_factory.normalise(Lbar, Bbar); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); ////////////////////////////////////////////////////////////// @@ -1499,7 +1523,7 @@ class ELMpb : public PhysicsModel { ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } - ddt(U) += tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term + ddt(U) += b0xcv * Grad(P); // curvature term if (!nogradparj) { // Parallel current term ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j @@ -1673,7 +1697,7 @@ class ELMpb : public PhysicsModel { ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); if (phi_curv) { - ddt(P) -= 2. * beta * tokamak_coordinates_factory.get_b0xcv() * Grad(phi); + ddt(P) -= 2. * beta * b0xcv * Grad(phi); } // Vpar equation @@ -1772,7 +1796,7 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * tokamak_coordinates_factory.get_b0xcv()) * Grad(P); + U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1829,7 +1853,7 @@ class ELMpb : public PhysicsModel { JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = tokamak_coordinates_factory.get_b0xcv() * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) + SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index f577254e94..111898d4fa 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -253,7 +253,7 @@ class GEM : public PhysicsModel { SAVE_ONCE(Bbar); tokamak_coordinates_factory.normalise(Lbar, Bbar); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(true); beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 617e7bee31..8b1b4a836e 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -174,7 +174,7 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true); } }; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 5cd024650e..7d3c8972c4 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -15,7 +15,7 @@ int main(int argc, char** argv) { calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index e1f1cf2c5f..6ac11568e3 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -18,7 +18,7 @@ class WaveTest : public PhysicsModel { int init(bool UNUSED(restarting)) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index cfa2706c62..5cc9765153 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -22,7 +22,6 @@ private: Field2D hthe_m; FieldMetric ShearFactor_m; FieldMetric dx_m; - Vector2D b0xcv_m; // Curvature term public: @@ -38,10 +37,6 @@ public: mesh.get(hthe_m, "hthe"); mesh.get(ShearFactor_m, "sinty"); mesh.get(dx_m, "dpsi"); - - // Load magnetic curvature term - b0xcv_m.covariant = false; // Read contravariant components - mesh.get(b0xcv_m, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 } BoutReal get_sign_of_bp() { @@ -51,11 +46,13 @@ public: return 1.0; } - Coordinates* make_tokamak_coordinates(const bool noshear, const bool include_curvature) { + Coordinates* make_tokamak_coordinates(const bool noshear) { const BoutReal sign_of_bp = get_sign_of_bp(); - set_shearfactor_and_curvature_term(noshear, include_curvature); + if (noshear) { + ShearFactor_m = 0.0; + } auto* coord = mesh_m.getCoordinates(); @@ -83,28 +80,6 @@ public: return coord; } - void set_shearfactor_and_curvature_term(const bool noshear, const bool include_curvature) { - - if (!include_curvature) { - b0xcv_m = 0.0; - } - - if (noshear) { - if (include_curvature) { - b0xcv_m.z += ShearFactor_m * b0xcv_m.x; - } - } - - // if (ShiftXderivs and not!mesh->IncIntShear) { - // // Dimits style, using local coordinate system - // if (include_curvature) { - // b0xcv.z += I * b0xcv.x; - // } - // I = 0.0; // I disappears from metric - // } - - } - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor=1.0) { Rxy_m /= Lbar; @@ -114,18 +89,12 @@ public: hthe_m /= Lbar; ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; dx_m /= Lbar * Lbar * Bbar; - - // Normalise curvature term - b0xcv_m.x /= Bbar; - b0xcv_m.y *= Lbar * Lbar; - b0xcv_m.z *= Lbar * Lbar; } const Field2D& get_Rxy() const { return Rxy_m; } const Field2D& get_Bpxy() const { return Bpxy_m; } const Field2D& get_Btxy() const { return Btxy_m; } const Field2D& get_Bxy() const { return Bxy_m; } - const Vector2D& get_b0xcv() const { return b0xcv_m; } const Field2D& get_hthe() const { return hthe_m; } const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } }; diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index d6795fbe37..f0a74c88cf 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -317,7 +317,7 @@ void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(true); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/GBS/mms-slab2d.py b/tests/MMS/GBS/mms-slab2d.py index 443517ab07..215e711a53 100644 --- a/tests/MMS/GBS/mms-slab2d.py +++ b/tests/MMS/GBS/mms-slab2d.py @@ -78,7 +78,15 @@ def C(f): bxcvz = 100 # Curvature -tokamak_coordinates_factory.normalise(rho_s0, Bnorm); +# Normalise + +Rxy /= rho_s0 +Bpxy /= Bnorm +Btxy /= Bnorm +Bxy /= Bnorm +hthe /= rho_s0 + +dx /= rho_s0**2 * Bnorm bxcvz *= rho_s0**2 diff --git a/tests/MMS/GBS/mms-slab3d.py b/tests/MMS/GBS/mms-slab3d.py index cafff0ba76..2f958cfa69 100644 --- a/tests/MMS/GBS/mms-slab3d.py +++ b/tests/MMS/GBS/mms-slab3d.py @@ -79,7 +79,15 @@ def C(f): estatic = True -tokamak_coordinates_factory.normalise(rho_s0, Bnorm); +# Normalise + +Rxy /= rho_s0 +Bpxy /= Bnorm +Btxy /= Bnorm +Bxy /= Bnorm +hthe /= rho_s0 + +dx /= rho_s0**2 * Bnorm bxcvz *= rho_s0**2 diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index e8d946e3b6..cccd9ec2c1 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -29,6 +29,7 @@ class ELMpb : public PhysicsModel { private: // 2D inital profiles Field2D J0, P0; // Current and pressure + Vector2D b0xcv; // Curvature term Field2D beta, gradparB; // Used for Vpar terms Field2D phi0; // When diamagnetic terms used @@ -274,6 +275,10 @@ class ELMpb : public PhysicsModel { OPTION(globalOptions->getSection("solver"), mms, false); + if (!include_curvature) { + b0xcv = 0.0; + } + if (!include_jpar0) { J0 = 0.0; } @@ -283,6 +288,19 @@ class ELMpb : public PhysicsModel { phi_solver = Laplacian::create(); + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES + + bool ShiftXderivs; + globalOptions->get("shiftXderivs", ShiftXderivs, false); // Read global flag + if (ShiftXderivs) { + if (not mesh->IncIntShear) { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + } + } ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -339,6 +357,10 @@ class ELMpb : public PhysicsModel { J0 = -MU0 * Lbar * J0 / B0; P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; + BoutReal pnorm = max(P0, true); // Maximum over all processors vacuum_pressure *= pnorm; // Get pressure from fraction @@ -369,7 +391,7 @@ class ELMpb : public PhysicsModel { } tokamak_coordinates_factory.normalise(Lbar, Bbar); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, include_curvature); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -562,7 +584,7 @@ class ELMpb : public PhysicsModel { ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); // Grad j term - ddt(U) += tokamak_coordinates_factory.get_b0xcv() * Grad(P); // curvature term + ddt(U) += b0xcv * Grad(P); // curvature term // Parallel current term ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j @@ -612,7 +634,7 @@ class ELMpb : public PhysicsModel { ddt(P) -= beta * Div_par_CtoL(Vpar); if (phi_curv) { - ddt(P) -= 2. * beta * tokamak_coordinates_factory.get_b0xcv() * Grad(phi); + ddt(P) -= 2. * beta * b0xcv * Grad(phi); } // Vpar equation diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index da3b75acb6..bf066179fb 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -47,7 +47,7 @@ class TokamakMMS : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, true); + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index dbe0dfca35..f2fa3ebb91 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -23,6 +23,7 @@ class TwoFluid : public PhysicsModel { Field2D Ni0, Ti0, Te0, Vi0, phi0, Ve0, rho0, Ajpar0; // Staggered versions of initial profiles Field2D Ni0_maybe_ylow, Te0_maybe_ylow; + Vector2D b0xcv; // for curvature terms // 3D evolving fields Field3D rho, Te, Ni, Ajpar, Vi, Ti; @@ -81,6 +82,10 @@ class TwoFluid : public PhysicsModel { GRID_LOAD(rho0); GRID_LOAD(Ajpar0); + // Load magnetic curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // b0xkappa terms + // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); @@ -129,6 +134,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; noshear = true; } @@ -178,12 +184,17 @@ class TwoFluid : public PhysicsModel { phi0 /= Te_x; Vi0 /= Vi_x; + // Normalise curvature term + b0xcv.x /= (bmag / 1e4); + b0xcv.y *= rho_s * rho_s; + b0xcv.z *= rho_s * rho_s; + // calculate pressures pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); /**************** SET EVOLVING VARIABLES *************/ @@ -338,8 +349,8 @@ class TwoFluid : public PhysicsModel { if (evolve_te) { ddt(Te) -= vE_Grad(Te0, phi) + vE_Grad(Te, phi0) + vE_Grad(Te, phi); ddt(Te) -= Vpar_Grad_par(Ve, Te0) + Vpar_Grad_par(Ve0, Te) + Vpar_Grad_par(Ve, Te); - ddt(Te) += 1.333 * Te0 * (V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), pe) / Ni0 - V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), phi)); - ddt(Te) += 3.333 * Te0 * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), Te); + ddt(Te) += 1.333 * Te0 * (V_dot_Grad(b0xcv, pe) / Ni0 - V_dot_Grad(b0xcv, phi)); + ddt(Te) += 3.333 * Te0 * V_dot_Grad(b0xcv, Te); ddt(Te) += (0.6666667 / Ni0) * Div_par_K_Grad_par(kapa_Te, Te); } @@ -350,8 +361,8 @@ class TwoFluid : public PhysicsModel { ddt(Ti) -= vE_Grad(Ti0, phi) + vE_Grad(Ti, phi0) + vE_Grad(Ti, phi); ddt(Ti) -= Vpar_Grad_par(Vi, Ti0) + Vpar_Grad_par(Vi0, Ti) + Vpar_Grad_par(Vi, Ti); ddt(Ti) += - 1.333 * (Ti0 * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), pe) / Ni0 - Ti * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), phi)); - ddt(Ti) -= 3.333 * Ti0 * V_dot_Grad(tokamak_coordinates_factory.get_b0xcv(), Ti); + 1.333 * (Ti0 * V_dot_Grad(b0xcv, pe) / Ni0 - Ti * V_dot_Grad(b0xcv, phi)); + ddt(Ti) -= 3.333 * Ti0 * V_dot_Grad(b0xcv, Ti); ddt(Ti) += (0.6666667 / Ni0) * Div_par_K_Grad_par(kapa_Ti, Ti); } diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 815bd85101..8df63b3301 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -18,6 +18,7 @@ class Interchange : public PhysicsModel { // 2D initial profiles Field2D Ni0, Ti0, Te0; + Vector2D b0xcv; // for curvature terms // 3D evolving fields Field3D rho, Ni; @@ -47,6 +48,12 @@ class Interchange : public PhysicsModel { GRID_LOAD(Ti0); GRID_LOAD(Te0); + // Load magnetic curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // b0xkappa terms + + b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY + // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); @@ -93,6 +100,13 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } + tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + + if (ShiftXderivs) { + b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + } + /************** NORMALISE QUANTITIES *****************/ output.write("\tNormalising to rho_s = {:e}\n", rho_s); @@ -102,9 +116,10 @@ class Interchange : public PhysicsModel { Ti0 /= Te_x; Te0 /= Te_x; -// b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY // TODO: Check if needed - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + // Normalise curvature term + b0xcv.x /= (bmag / 1e4); + b0xcv.y *= rho_s * rho_s; + b0xcv.z *= rho_s * rho_s; // Tell BOUT++ which variables to evolve SOLVE_FOR2(rho, Ni); @@ -132,7 +147,7 @@ class Interchange : public PhysicsModel { ddt(Ni) = -b0xGrad_dot_Grad(phi, Ni0) / coord->Bxy(); // VORTICITY - ddt(rho) = 2.0 * coord->Bxy() * tokamak_coordinates_factory.get_b0xcv() * Grad(pei); + ddt(rho) = 2.0 * coord->Bxy() * b0xcv * Grad(pei); return (0); } diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index c3151abbec..ef76de8018 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -19,5 +19,5 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, true); + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); } From a50a51c8c87f61635329df02dce941e553ed4811 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 4 Dec 2024 11:48:28 +0000 Subject: [PATCH 79/98] Make TokamakCoordinatesFactory.normalise() private and call in make_tokamak_coordinates() method --- examples/6field-simple/elm_6f.cxx | 13 ++++--- examples/conducting-wall-mode/cwm.cxx | 4 +- examples/constraints/alfven-wave/alfven.cxx | 4 +- examples/dalf3/dalf3.cxx | 4 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 3 +- examples/elm-pb/elm_pb.cxx | 3 +- examples/gyro-gem/gem.cxx | 3 +- examples/laplacexy/alfven-wave/alfven.cxx | 4 +- include/bout/tokamak_coordinates_factory.hxx | 37 +++++++++---------- tests/MMS/GBS/gbs.cxx | 3 +- tests/MMS/elm-pb/elm_pb.cxx | 3 +- tests/MMS/tokamak/tokamak.cxx | 4 +- .../test-drift-instability/2fluid.cxx | 4 +- .../test-interchange-instability/2fluid.cxx | 4 +- .../integrated/test-laplacexy/loadmetric.cxx | 3 +- 15 files changed, 46 insertions(+), 50 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 7afdb6a31b..043aa80f44 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -835,8 +835,6 @@ class Elm_6f : public PhysicsModel { J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); - tokamak_coordinates_factory.normalise(Lbar, Bbar); - b0xcv.x /= Bbar; b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; @@ -906,7 +904,10 @@ class Elm_6f : public PhysicsModel { q95 = q95_input; // use a constant for test } else { if (local_q) { - q95 = abs(tokamak_coordinates_factory.get_hthe() * tokamak_coordinates_factory.get_Btxy() / tokamak_coordinates_factory.get_Bpxy()) * q_alpha; + q95 = abs(tokamak_coordinates_factory.get_hthe() + * tokamak_coordinates_factory.get_Btxy() + / tokamak_coordinates_factory.get_Bpxy()) + * q_alpha; } else { output.write("\tUsing q profile from grid.\n"); if (mesh->get(q95, "q")) { @@ -1028,8 +1029,9 @@ class Elm_6f : public PhysicsModel { } /**************** CALCULATE METRICS ******************/ - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); - + const auto& coord = + tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); + ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -1191,6 +1193,7 @@ class Elm_6f : public PhysicsModel { return 0; } + int rhs(BoutReal UNUSED(t)) override { Coordinates* coord = mesh->getCoordinates(); diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index a3b1720da7..1fc55597fe 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -129,8 +129,8 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, + bmag / 1e4, ShearFactor); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 2b9b2beb91..93c5d1abc2 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -171,8 +171,8 @@ class Alfven : public PhysicsModel { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + const auto& coord = + tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lnorm, Bnorm); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 8bba66d656..cb27d905b3 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -222,8 +222,8 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - tokamak_coordinates_factory.normalise(rho_s, Bnorm); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + const auto& coord = + tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, Bnorm); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 7edfbe8e38..5d6f1dca4f 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -716,8 +716,7 @@ class ELMpb : public PhysicsModel { if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale Lbar = 1.0; } - tokamak_coordinates_factory.normalise(Lbar, Bbar); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 2b4603e9c8..03bac5c569 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -876,8 +876,7 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - tokamak_coordinates_factory.normalise(Lbar, Bbar); - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 111898d4fa..eee64f8473 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -252,8 +252,7 @@ class GEM : public PhysicsModel { Bbar = options["Bbar"].withDefault(Bbar); // Override in options file SAVE_ONCE(Bbar); - tokamak_coordinates_factory.normalise(Lbar, Bbar); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(true); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, Lbar, Bbar); beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 8b1b4a836e..fbe1de3e9d 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -173,8 +173,8 @@ class Alfven : public PhysicsModel { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true); + const auto& coord = + tokamak_coordinates_factory.make_tokamak_coordinates(true, Lnorm, Bnorm); } }; diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index 5cc9765153..def2be950e 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -3,17 +3,16 @@ #define BOUT_TOKAMAK_COORDINATES_FACTORY_HXX #include "bout.hxx" -#include "bout/utils.hxx" #include "bout/bout_types.hxx" #include "bout/christoffel_symbols.hxx" -#include "bout/vector2d.hxx" -#include "bout/field2d.hxx" #include "bout/coordinates.hxx" +#include "bout/field2d.hxx" +#include "bout/utils.hxx" +#include "bout/vector2d.hxx" class TokamakCoordinatesFactory { private: - Mesh& mesh_m; Field2D Rxy_m; Field2D Bpxy_m; @@ -23,11 +22,19 @@ private: FieldMetric ShearFactor_m; FieldMetric dx_m; + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { -public: + Rxy_m /= Lbar; + Bpxy_m /= Bbar; + Btxy_m /= Bbar; + Bxy_m /= Bbar; + hthe_m /= Lbar; + ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; + dx_m /= Lbar * Lbar * Bbar; + } - TokamakCoordinatesFactory(Mesh& mesh) - : mesh_m(mesh) { +public: + TokamakCoordinatesFactory(Mesh& mesh) : mesh_m(mesh) { mesh.get(Rxy_m, "Rxy"); // mesh->get(Zxy, "Zxy"); @@ -46,7 +53,10 @@ public: return 1.0; } - Coordinates* make_tokamak_coordinates(const bool noshear) { + Coordinates* make_tokamak_coordinates(const bool noshear, BoutReal Lbar, BoutReal Bbar, + BoutReal ShearFactor = 1.0) { + + normalise(Lbar, Bbar, ShearFactor); const BoutReal sign_of_bp = get_sign_of_bp(); @@ -80,17 +90,6 @@ public: return coord; } - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor=1.0) { - - Rxy_m /= Lbar; - Bpxy_m /= Bbar; - Btxy_m /= Bbar; - Bxy_m /= Bbar; - hthe_m /= Lbar; - ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; - dx_m /= Lbar * Lbar * Bbar; - } - const Field2D& get_Rxy() const { return Rxy_m; } const Field2D& get_Bpxy() const { return Bpxy_m; } const Field2D& get_Btxy() const { return Btxy_m; } diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index f0a74c88cf..34fa681945 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -316,8 +316,7 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(true); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, Lnorm, Bnorm); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index cccd9ec2c1..2342b6c69e 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -390,8 +390,7 @@ class ELMpb : public PhysicsModel { noshear = true; } - tokamak_coordinates_factory.normalise(Lbar, Bbar); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index bf066179fb..2559fbcbd1 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -46,8 +46,8 @@ class TokamakMMS : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(true); + auto coords = + tokamak_coordinates_factory.make_tokamak_coordinates(true, Lnorm, Bnorm); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index f2fa3ebb91..022ae55314 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -193,8 +193,8 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, + bmag / 1e4, ShearFactor); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 8df63b3301..385d98f235 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -100,8 +100,8 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } - tokamak_coordinates_factory.normalise(rho_s, bmag / 1e4, ShearFactor); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, + bmag / 1e4, ShearFactor); if (ShiftXderivs) { b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index ef76de8018..437c42b3b8 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -18,6 +18,5 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { } auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - tokamak_coordinates_factory.normalise(Lnorm, Bnorm); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear); + auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lnorm, Bnorm); } From ca83f7afd28a44780c700e7f1f219845dc2d07c6 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 4 Dec 2024 12:25:27 +0000 Subject: [PATCH 80/98] Rename TokamakCoordinatesFactory getters --- examples/6field-simple/elm_6f.cxx | 92 +++++++-------- examples/conducting-wall-mode/cwm.cxx | 8 +- examples/dalf3/dalf3.cxx | 2 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 36 +++--- examples/elm-pb/elm_pb.cxx | 108 +++++++++--------- examples/gyro-gem/gem.cxx | 4 +- include/bout/tokamak_coordinates_factory.hxx | 12 +- .../test-drift-instability/2fluid.cxx | 2 +- .../test-interchange-instability/2fluid.cxx | 2 +- 9 files changed, 135 insertions(+), 131 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 043aa80f44..6a51fc4221 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -366,7 +366,7 @@ class Elm_6f : public PhysicsModel { result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * tokamak_coordinates_factory.get_Bxy(); + result -= bracket(Psi, f, bm_mag) * tokamak_coordinates_factory.Bxy(); } } @@ -678,7 +678,7 @@ class Elm_6f : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } } @@ -688,7 +688,7 @@ class Elm_6f : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } } @@ -832,7 +832,7 @@ class Elm_6f : public PhysicsModel { dump.add(sp_length, "sp_length", 1); } - J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); + J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates_factory.Bxy(); P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); b0xcv.x /= Bbar; @@ -904,9 +904,9 @@ class Elm_6f : public PhysicsModel { q95 = q95_input; // use a constant for test } else { if (local_q) { - q95 = abs(tokamak_coordinates_factory.get_hthe() - * tokamak_coordinates_factory.get_Btxy() - / tokamak_coordinates_factory.get_Bpxy()) + q95 = abs(tokamak_coordinates_factory.hthe() + * tokamak_coordinates_factory.Btxy() + / tokamak_coordinates_factory.Bpxy()) * q_alpha; } else { output.write("\tUsing q profile from grid.\n"); @@ -1037,29 +1037,29 @@ class Elm_6f : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); + coord->setIntShiftTorsion(tokamak_coordinates_factory.ShearFactor()); } // Set B field vector B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); + B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); B0vec.z = 0.; // Set V0vec field vector V0vec.covariant = false; V0vec.x = 0.; - V0vec.y = Vp0 / tokamak_coordinates_factory.get_hthe(); - V0vec.z = Vt0 / tokamak_coordinates_factory.get_Rxy(); + V0vec.y = Vp0 / tokamak_coordinates_factory.hthe(); + V0vec.z = Vt0 / tokamak_coordinates_factory.Rxy(); // Set V0eff field vector V0eff.covariant = false; V0eff.x = 0.; - V0eff.y = -(tokamak_coordinates_factory.get_Btxy() / (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy())) * (Vp0 * tokamak_coordinates_factory.get_Btxy() - Vt0 * tokamak_coordinates_factory.get_Bpxy()) / tokamak_coordinates_factory.get_hthe(); - V0eff.z = (tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy())) * (Vp0 * tokamak_coordinates_factory.get_Btxy() - Vt0 * tokamak_coordinates_factory.get_Bpxy()) / tokamak_coordinates_factory.get_Rxy(); + V0eff.y = -(tokamak_coordinates_factory.Btxy() / (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy())) * (Vp0 * tokamak_coordinates_factory.Btxy() - Vt0 * tokamak_coordinates_factory.Bpxy()) / tokamak_coordinates_factory.hthe(); + V0eff.z = (tokamak_coordinates_factory.Bpxy() / (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy())) * (Vp0 * tokamak_coordinates_factory.Btxy() - Vt0 * tokamak_coordinates_factory.Bpxy()) / tokamak_coordinates_factory.Rxy(); Pe.setBoundary("P"); Pi.setBoundary("P"); @@ -1101,10 +1101,10 @@ class Elm_6f : public PhysicsModel { if (diamag && diamag_phi0) { if (experiment_Er) { // get phi0 from grid file mesh->get(phi0, "Phi_0"); - phi0 /= tokamak_coordinates_factory.get_Bxy() * Lbar * Va; + phi0 /= tokamak_coordinates_factory.Bxy() * Lbar * Va; } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -Upara0 * Pi0 / tokamak_coordinates_factory.get_Bxy() / N0; + phi0 = -Upara0 * Pi0 / tokamak_coordinates_factory.Bxy() / N0; } SAVE_ONCE(phi0); } @@ -1114,7 +1114,7 @@ class Elm_6f : public PhysicsModel { SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); SAVE_ONCE(Tibar, Tebar, Nbar); - Field2D tmp = tokamak_coordinates_factory.get_Bxy(); + Field2D tmp = tokamak_coordinates_factory.Bxy(); SAVE_ONCE(Va, tmp); SAVE_ONCE(Ti0, Te0, N0); @@ -1138,13 +1138,13 @@ class Elm_6f : public PhysicsModel { Field2D logn0 = laplace_alpha * N0; Field3D Ntemp; Ntemp = N0; - ubyn = U * tokamak_coordinates_factory.get_Bxy() / Ntemp; + ubyn = U * tokamak_coordinates_factory.Bxy() / Ntemp; // Phi should be consistent with U if (laplace_alpha <= 0.0) { - phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.get_Bxy(); + phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.Bxy(); } else { phiSolver->setCoefC(logn0); - phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.get_Bxy(); + phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.Bxy(); } } @@ -1219,9 +1219,9 @@ class Elm_6f : public PhysicsModel { // Field2D lap_temp=0.0; Field2D logn0 = laplace_alpha * N0; - ubyn = U * tokamak_coordinates_factory.get_Bxy() / N0; + ubyn = U * tokamak_coordinates_factory.Bxy() / N0; if (diamag) { - ubyn -= Upara0 / N0 * Delp2(Pi) / tokamak_coordinates_factory.get_Bxy(); + ubyn -= Upara0 / N0 * Delp2(Pi) / tokamak_coordinates_factory.Bxy(); mesh->communicate(ubyn); ubyn.applyBoundary(); } @@ -1229,7 +1229,7 @@ class Elm_6f : public PhysicsModel { if (laplace_alpha > 0.0) { phiSolver->setCoefC(logn0); } - phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.get_Bxy(); + phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.Bxy(); mesh->communicate(phi); @@ -1325,9 +1325,9 @@ class Elm_6f : public PhysicsModel { if (compress0) { if (nonlinear) { - Vepar = Vipar - tokamak_coordinates_factory.get_Bxy() * (Jpar) / N_tmp * Vepara; + Vepar = Vipar - tokamak_coordinates_factory.Bxy() * (Jpar) / N_tmp * Vepara; } else { - Vepar = Vipar - tokamak_coordinates_factory.get_Bxy() * (Jpar) / N0 * Vepara; + Vepar = Vipar - tokamak_coordinates_factory.Bxy() * (Jpar) / N0 * Vepara; Vepar.applyBoundary(); mesh->communicate(Vepar); } @@ -1365,13 +1365,13 @@ class Elm_6f : public PhysicsModel { ddt(Psi) = 0.0; if (spitzer_resist) { - ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.get_Bxy() * phi) / tokamak_coordinates_factory.get_Bxy() - eta_spitzer * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.Bxy() * phi) / tokamak_coordinates_factory.Bxy() - eta_spitzer * Jpar; } else { - ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.get_Bxy() * phi) / tokamak_coordinates_factory.get_Bxy() - eta * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.Bxy() * phi) / tokamak_coordinates_factory.Bxy() - eta * Jpar; } if (diamag) { - ddt(Psi) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Psi, bm_exb); // Equilibrium flow + ddt(Psi) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Psi, bm_exb); // Equilibrium flow } // Hyper-resistivity @@ -1388,18 +1388,18 @@ class Elm_6f : public PhysicsModel { ddt(U) = 0.0; - ddt(U) = -SQ(tokamak_coordinates_factory.get_Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates_factory.get_Bxy(); // Grad j term + ddt(U) = -SQ(tokamak_coordinates_factory.Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates_factory.Bxy(); // Grad j term ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term - ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar); // b dot grad j + ddt(U) += SQ(tokamak_coordinates_factory.Bxy()) * Grad_parP(Jpar); // b dot grad j if (diamag) { - ddt(U) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, U, bm_exb); // Equilibrium flow + ddt(U) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, U, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(U) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, U, bm_exb); // Advection + ddt(U) -= bracket(tokamak_coordinates_factory.Bxy() * phi, U, bm_exb); // Advection } // parallel hyper-viscous diffusion for vector potential @@ -1451,18 +1451,18 @@ class Elm_6f : public PhysicsModel { ddt(Ni) = 0.0; - ddt(Ni) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, N0, bm_exb); + ddt(Ni) -= bracket(tokamak_coordinates_factory.Bxy() * phi, N0, bm_exb); if (diamag) { - ddt(Ni) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Ni, bm_exb); // Equilibrium flow + ddt(Ni) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Ni, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ni) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Ni, bm_exb); // Advection + ddt(Ni) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Ni, bm_exb); // Advection } if (compress0) { - ddt(Ni) -= N0 * tokamak_coordinates_factory.get_Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.get_Bxy()); + ddt(Ni) -= N0 * tokamak_coordinates_factory.Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.Bxy()); } // 4th order Parallel diffusion terms @@ -1481,18 +1481,18 @@ class Elm_6f : public PhysicsModel { ddt(Ti) = 0.0; - ddt(Ti) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Ti0, bm_exb); + ddt(Ti) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Ti0, bm_exb); if (diamag) { - ddt(Ti) -= bracket(phi0 * tokamak_coordinates_factory.get_Bxy(), Ti, bm_exb); // Equilibrium flow + ddt(Ti) -= bracket(phi0 * tokamak_coordinates_factory.Bxy(), Ti, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ti) -= bracket(phi * tokamak_coordinates_factory.get_Bxy(), Ti, bm_exb); // Advection + ddt(Ti) -= bracket(phi * tokamak_coordinates_factory.Bxy(), Ti, bm_exb); // Advection } if (compress0) { - ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates_factory.get_Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.get_Bxy()); + ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates_factory.Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.Bxy()); } if (diffusion_par > 0.0) { @@ -1517,18 +1517,18 @@ class Elm_6f : public PhysicsModel { ddt(Te) = 0.0; - ddt(Te) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Te0, bm_exb); + ddt(Te) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Te0, bm_exb); if (diamag) { - ddt(Te) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Te, bm_exb); // Equilibrium flow + ddt(Te) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Te, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Te) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Te, bm_exb); // Advection + ddt(Te) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Te, bm_exb); // Advection } if (compress0) { - ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates_factory.get_Bxy() * Grad_parP(Vepar / tokamak_coordinates_factory.get_Bxy()); + ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates_factory.Bxy() * Grad_parP(Vepar / tokamak_coordinates_factory.Bxy()); } if (diffusion_par > 0.0) { @@ -1551,14 +1551,14 @@ class Elm_6f : public PhysicsModel { ddt(Vipar) = 0.0; ddt(Vipar) -= Vipara * Grad_parP(P) / N0; - ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * tokamak_coordinates_factory.get_Bxy() / N0; + ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * tokamak_coordinates_factory.Bxy() / N0; if (diamag) { - ddt(Vipar) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Vipar, bm_exb); + ddt(Vipar) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Vipar, bm_exb); } if (nonlinear) { - ddt(Vipar) -= bracket(tokamak_coordinates_factory.get_Bxy() * phi, Vipar, bm_exb); + ddt(Vipar) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Vipar, bm_exb); } // parallel hyper-viscous diffusion for vector potential diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 1fc55597fe..c869ea69ec 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -141,10 +141,10 @@ class CWM : public PhysicsModel { // add evolving variables to the communication object SOLVE_FOR(rho, te); - Field2D Rxy = tokamak_coordinates_factory.get_Rxy(); - Field2D Bpxy = tokamak_coordinates_factory.get_Bpxy(); - Field2D Btxy = tokamak_coordinates_factory.get_Btxy(); - Field2D hthe = tokamak_coordinates_factory.get_hthe(); + Field2D Rxy = tokamak_coordinates_factory.Rxy(); + Field2D Bpxy = tokamak_coordinates_factory.Bpxy(); + Field2D Btxy = tokamak_coordinates_factory.Btxy(); + Field2D hthe = tokamak_coordinates_factory.hthe(); SAVE_ONCE(Rxy, Bpxy, Btxy, Zxy, hthe); SAVE_ONCE(nu_hat, hthe0); diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index cb27d905b3..fdfc48db2a 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -162,7 +162,7 @@ class DALF3 : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; noshear = true; } diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 5d6f1dca4f..4ac9774ac2 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -718,7 +718,7 @@ class ELMpb : public PhysicsModel { } const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); - V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); + V0 = -tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Bpxy() * Dphi0 / tokamak_coordinates_factory.Bxy(); if (simple_rmp) { include_rmp = true; @@ -813,7 +813,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } } @@ -823,7 +823,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } } @@ -933,7 +933,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); + J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.Bxy(); P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -1072,15 +1072,17 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); + B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Btxy() * tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_hthe() * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Dphi0; + V0net.y = + tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Btxy() * tokamak_coordinates_factory.Bpxy() / (tokamak_coordinates_factory.hthe() * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory.get_Bxy(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory + .Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1103,8 +1105,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (0.5 + (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates_factory.get_Bxy()) / tokamak_coordinates_factory.get_Bxy(); + beta = tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (0.5 + (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates_factory.Bxy()) / tokamak_coordinates_factory.Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1137,10 +1139,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy(); + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy() / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy() / N0; } SAVE_ONCE(phi0); } else { @@ -1151,7 +1153,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - Field2D Bxy = tokamak_coordinates_factory.get_Bxy(); + Field2D Bxy = tokamak_coordinates_factory.Bxy(); SAVE_ONCE(Va, Bxy); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); @@ -1211,7 +1213,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); + metric->setIntShiftTorsion(tokamak_coordinates_factory.ShearFactor()); } @@ -1525,7 +1527,7 @@ class ELMpb : public PhysicsModel { auto P0_acc = Field2DAccessor<>(P0); auto J0_acc = Field2DAccessor<>(J0); auto phi0_acc = Field2DAccessor<>(phi0); - Field2D Bxy = tokamak_coordinates_factory.get_Bxy(); + Field2D Bxy = tokamak_coordinates_factory.Bxy(); auto B0_acc = Field2DAccessor<>(Bxy); // Evolving fields @@ -1713,16 +1715,16 @@ class ELMpb : public PhysicsModel { // Vorticity equation // Grad j term - // ddt(U) = SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); + // ddt(U) = SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); // if (include_rmp) { - // ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + // ddt(U) += SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); // } ddt(U) += b0xcv * Grad(P); // curvature term // if (!nogradparj) { // Parallel current term - // ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + // ddt(U) -= SQ(tokamak_coordinates_factory.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j // } if (withflow && K_H_term) { // K_H_term diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 03bac5c569..3a3ac0fe9c 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -645,7 +645,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Bpxy() * Dphi0 / tokamak_coordinates_factory.get_Bxy(); + V0 = -tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Bpxy() * Dphi0 / tokamak_coordinates_factory.Bxy(); if (simple_rmp) { include_rmp = true; @@ -740,7 +740,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } } @@ -750,7 +750,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } } @@ -867,7 +867,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.get_Bxy(); + J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.Bxy(); P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -884,7 +884,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); + metric->setIntShiftTorsion(tokamak_coordinates_factory.ShearFactor()); } if (constn0) { @@ -1016,15 +1016,17 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); + B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = tokamak_coordinates_factory.get_Rxy() * tokamak_coordinates_factory.get_Btxy() * tokamak_coordinates_factory.get_Bpxy() / (tokamak_coordinates_factory.get_hthe() * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Dphi0; + V0net.y = + tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Btxy() * tokamak_coordinates_factory.Bpxy() / (tokamak_coordinates_factory.hthe() * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory.get_Bxy(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory + .Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1047,8 +1049,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (0.5 + (tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates_factory.get_Bxy()) / tokamak_coordinates_factory.get_Bxy(); + beta = tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (0.5 + (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates_factory.Bxy()) / tokamak_coordinates_factory.Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1081,10 +1083,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy(); + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.get_Bxy() / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy() / N0; } SAVE_ONCE(phi0); } @@ -1093,7 +1095,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - Field2D tmp = tokamak_coordinates_factory.get_Bxy(); + Field2D tmp = tokamak_coordinates_factory.Bxy(); SAVE_ONCE(Va, tmp); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); @@ -1161,7 +1163,7 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); if (nonlinear) { - const auto Bxy = tokamak_coordinates_factory.get_Bxy(); + const auto Bxy = tokamak_coordinates_factory.Bxy(); result -= bracket(interp_to(Psi, loc), f, bm_mag) * Bxy; if (include_rmp) { @@ -1301,12 +1303,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / tokamak_coordinates_factory.get_Bxy(); + phi -= 0.5 * dnorm * P / tokamak_coordinates_factory.Bxy(); } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates_factory.get_Bxy()) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates_factory.Bxy()) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1451,9 +1453,9 @@ class ELMpb : public PhysicsModel { if (evolve_jpar) { // Jpar - Field3D B0U = tokamak_coordinates_factory.get_Bxy() * U; + Field3D B0U = tokamak_coordinates_factory.Bxy() * U; mesh->communicate(B0U); - ddt(Jpar) = -Grad_parP(B0U, loc) / tokamak_coordinates_factory.get_Bxy() + eta * Delp2(Jpar); + ddt(Jpar) = -Grad_parP(B0U, loc) / tokamak_coordinates_factory.Bxy() + eta * Delp2(Jpar); if (relax_j_vac) { // Make ddt(Jpar) relax to zero. @@ -1462,16 +1464,16 @@ class ELMpb : public PhysicsModel { } } else { // Vector potential - ddt(Psi) = -Grad_parP(phi * tokamak_coordinates_factory.get_Bxy(), loc) / tokamak_coordinates_factory.get_Bxy() + eta * Jpar; + ddt(Psi) = -Grad_parP(phi * tokamak_coordinates_factory.Bxy(), loc) / tokamak_coordinates_factory.Bxy() + eta * Jpar; if (eHall) { // electron parallel pressure ddt(Psi) += 0.25 * delta_i - * (Grad_parP(tokamak_coordinates_factory.get_Bxy() * P, loc) / tokamak_coordinates_factory.get_Bxy() - + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates_factory.get_Bxy()); + * (Grad_parP(tokamak_coordinates_factory.Bxy() * P, loc) / tokamak_coordinates_factory.Bxy() + + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates_factory.Bxy()); } if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates_factory.get_Bxy(); + ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates_factory.Bxy(); } if (withflow) { // net flow @@ -1479,7 +1481,7 @@ class ELMpb : public PhysicsModel { } if (diamag_grad_t) { // grad_par(T_e) correction - ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates_factory.get_Bxy(); + ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates_factory.Bxy(); } if (hyperresist > 0.0) { // Hyper-resistivity @@ -1517,15 +1519,15 @@ class ELMpb : public PhysicsModel { Psi_loc = interp_to(Psi, CELL_CENTRE, "RGN_ALL"); Psi_loc.applyBoundary(); // Grad j term - ddt(U) = SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); + ddt(U) = SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); if (include_rmp) { - ddt(U) += SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + ddt(U) += SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } ddt(U) += b0xcv * Grad(P); // curvature term if (!nogradparj) { // Parallel current term - ddt(U) -= SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + ddt(U) -= SQ(tokamak_coordinates_factory.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j } if (withflow && K_H_term) { // K_H_term @@ -1541,7 +1543,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates_factory.Bxy(); } // Viscosity terms @@ -1585,11 +1587,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates_factory.get_Bxy() * phi0)); + Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates_factory.Bxy() * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(tokamak_coordinates_factory.get_Bxy() * phi); + Dperp2Phi = Delp2(tokamak_coordinates_factory.Bxy() * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1601,35 +1603,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(tokamak_coordinates_factory.get_Bxy() * phi0, Pi, bm_exb); + bracketPhi0P = bracket(tokamak_coordinates_factory.Bxy() * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(tokamak_coordinates_factory.get_Bxy() * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(tokamak_coordinates_factory.Bxy() * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates_factory.Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.Bxy(); + Field3D B0phi = tokamak_coordinates_factory.Bxy() * phi; mesh->communicate(B0phi); - Field3D B0phi0 = tokamak_coordinates_factory.get_Bxy() * phi0; + Field3D B0phi0 = tokamak_coordinates_factory.Bxy() * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates_factory.Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates_factory.Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates_factory.Bxy(); if (nonlinear) { - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + Field3D B0phi = tokamak_coordinates_factory.Bxy() * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.get_Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates_factory.get_Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates_factory.Bxy(); } } @@ -1659,7 +1661,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates_factory.get_Bxy(); + ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates_factory.Bxy(); } } @@ -1704,7 +1706,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates_factory.get_Bxy(); // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates_factory.Bxy(); // Advection } } @@ -1795,7 +1797,7 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1804,7 +1806,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * tokamak_coordinates_factory.get_Bxy() * tokamak_coordinates_factory.get_Bxy()); + invU->setCoefB(-SQ(gamma) * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -1812,9 +1814,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = tokamak_coordinates_factory.get_Bxy() * phi3; + Field3D B0phi3 = tokamak_coordinates_factory.Bxy() * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates_factory.get_Bxy(); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates_factory.Bxy(); ddt(Psi).applyBoundary(); return 0; @@ -1846,14 +1848,14 @@ class ELMpb : public PhysicsModel { Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = tokamak_coordinates_factory.get_Bxy() * phi; + Field3D B0phi = tokamak_coordinates_factory.Bxy() * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates_factory.get_Bxy(); + Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates_factory.Bxy(); JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.get_Bxy()) * Grad_par(Jpar, CELL_CENTRE) - + SQ(tokamak_coordinates_factory.get_Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.Bxy()) * Grad_par(Jpar, CELL_CENTRE) + + SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index eee64f8473..be92ddea0a 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -246,7 +246,7 @@ class GEM : public PhysicsModel { if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { - Bbar = max(tokamak_coordinates_factory.get_Bxy(), true); + Bbar = max(tokamak_coordinates_factory.Bxy(), true); } } Bbar = options["Bbar"].withDefault(Bbar); // Override in options file @@ -349,7 +349,7 @@ class GEM : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.get_Bpxy() / tokamak_coordinates_factory.get_hthe(); + B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); B0vec.z = 0.; // Precompute this for use in RHS diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates_factory.hxx index def2be950e..5690d4fdab 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates_factory.hxx @@ -90,12 +90,12 @@ public: return coord; } - const Field2D& get_Rxy() const { return Rxy_m; } - const Field2D& get_Bpxy() const { return Bpxy_m; } - const Field2D& get_Btxy() const { return Btxy_m; } - const Field2D& get_Bxy() const { return Bxy_m; } - const Field2D& get_hthe() const { return hthe_m; } - const FieldMetric& get_ShearFactor() const { return ShearFactor_m; } + const Field2D& Rxy() const { return Rxy_m; } + const Field2D& Bpxy() const { return Bpxy_m; } + const Field2D& Btxy() const { return Btxy_m; } + const Field2D& Bxy() const { return Bxy_m; } + const Field2D& hthe() const { return hthe_m; } + const FieldMetric& ShearFactor() const { return ShearFactor_m; } }; #endif //BOUT_TOKAMAK_COORDINATES_FACTORY_HXX diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 022ae55314..23dbb7e837 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -134,7 +134,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; noshear = true; } diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 385d98f235..843797e365 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -104,7 +104,7 @@ class Interchange : public PhysicsModel { bmag / 1e4, ShearFactor); if (ShiftXderivs) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; } /************** NORMALISE QUANTITIES *****************/ From a83193bafdddb68ec2dc93694d200e16945ef80d Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 16 Dec 2024 18:18:10 +0000 Subject: [PATCH 81/98] Rename class and method class `TokamakCoordinatesFactory` renamed to `TokamakCoordinates` method `tokamak_coordinates_factory` renamed to `tokamak_coordinates` --- CMakeLists.txt | 2 +- examples/6field-simple/elm_6f.cxx | 99 ++++++++------- examples/conducting-wall-mode/cwm.cxx | 16 +-- examples/constraints/alfven-wave/alfven.cxx | 6 +- examples/dalf3/dalf3.cxx | 8 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 41 +++---- examples/elm-pb/elm_pb.cxx | 113 +++++++++--------- examples/gyro-gem/gem.cxx | 10 +- examples/laplacexy/alfven-wave/alfven.cxx | 7 +- examples/laplacexy/laplace_perp/test.cxx | 6 +- examples/wave-slab/wave_slab.cxx | 6 +- ...es_factory.hxx => tokamak_coordinates.hxx} | 12 +- tests/MMS/GBS/gbs.cxx | 4 +- tests/MMS/elm-pb/elm_pb.cxx | 8 +- tests/MMS/tokamak/tokamak.cxx | 4 +- .../test-drift-instability/2fluid.cxx | 9 +- .../test-interchange-instability/2fluid.cxx | 10 +- .../integrated/test-laplacexy/loadmetric.cxx | 4 +- 18 files changed, 182 insertions(+), 183 deletions(-) rename include/bout/{tokamak_coordinates_factory.hxx => tokamak_coordinates.hxx} (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cb42c2f5a..c561e91fa5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,7 +360,7 @@ set(BOUT_SOURCES ./src/mesh/g_values.cxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx - ./include/bout/tokamak_coordinates_factory.hxx + ./include/bout/tokamak_coordinates.hxx ) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 6a51fc4221..88bf18b4b0 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -15,7 +15,7 @@ #include "bout/msg_stack.hxx" #include "bout/physicsmodel.hxx" #include "bout/sourcex.hxx" -#include "bout/tokamak_coordinates_factory.hxx" +#include "bout/tokamak_coordinates.hxx" #include @@ -235,7 +235,7 @@ class Elm_6f : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); BoutReal LnLambda; // ln(Lambda) @@ -366,7 +366,7 @@ class Elm_6f : public PhysicsModel { result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * tokamak_coordinates_factory.Bxy(); + result -= bracket(Psi, f, bm_mag) * tokamak_coordinates.Bxy(); } } @@ -678,7 +678,7 @@ class Elm_6f : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } } @@ -688,7 +688,7 @@ class Elm_6f : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } } @@ -832,7 +832,7 @@ class Elm_6f : public PhysicsModel { dump.add(sp_length, "sp_length", 1); } - J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates_factory.Bxy(); + J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates.Bxy(); P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); b0xcv.x /= Bbar; @@ -904,9 +904,9 @@ class Elm_6f : public PhysicsModel { q95 = q95_input; // use a constant for test } else { if (local_q) { - q95 = abs(tokamak_coordinates_factory.hthe() - * tokamak_coordinates_factory.Btxy() - / tokamak_coordinates_factory.Bpxy()) + q95 = abs(tokamak_coordinates.hthe() + * tokamak_coordinates.Btxy() + / tokamak_coordinates.Bpxy()) * q_alpha; } else { output.write("\tUsing q profile from grid.\n"); @@ -1029,37 +1029,36 @@ class Elm_6f : public PhysicsModel { } /**************** CALCULATE METRICS ******************/ - const auto& coord = - tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); + const auto& coord = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_coordinates_factory.ShearFactor()); + coord->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); } // Set B field vector B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); + B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); B0vec.z = 0.; // Set V0vec field vector V0vec.covariant = false; V0vec.x = 0.; - V0vec.y = Vp0 / tokamak_coordinates_factory.hthe(); - V0vec.z = Vt0 / tokamak_coordinates_factory.Rxy(); + V0vec.y = Vp0 / tokamak_coordinates.hthe(); + V0vec.z = Vt0 / tokamak_coordinates.Rxy(); // Set V0eff field vector V0eff.covariant = false; V0eff.x = 0.; - V0eff.y = -(tokamak_coordinates_factory.Btxy() / (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy())) * (Vp0 * tokamak_coordinates_factory.Btxy() - Vt0 * tokamak_coordinates_factory.Bpxy()) / tokamak_coordinates_factory.hthe(); - V0eff.z = (tokamak_coordinates_factory.Bpxy() / (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy())) * (Vp0 * tokamak_coordinates_factory.Btxy() - Vt0 * tokamak_coordinates_factory.Bpxy()) / tokamak_coordinates_factory.Rxy(); + V0eff.y = -(tokamak_coordinates.Btxy() / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) / tokamak_coordinates.hthe(); + V0eff.z = (tokamak_coordinates.Bpxy() / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) / tokamak_coordinates.Rxy(); Pe.setBoundary("P"); Pi.setBoundary("P"); @@ -1101,10 +1100,10 @@ class Elm_6f : public PhysicsModel { if (diamag && diamag_phi0) { if (experiment_Er) { // get phi0 from grid file mesh->get(phi0, "Phi_0"); - phi0 /= tokamak_coordinates_factory.Bxy() * Lbar * Va; + phi0 /= tokamak_coordinates.Bxy() * Lbar * Va; } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -Upara0 * Pi0 / tokamak_coordinates_factory.Bxy() / N0; + phi0 = -Upara0 * Pi0 / tokamak_coordinates.Bxy() / N0; } SAVE_ONCE(phi0); } @@ -1114,7 +1113,7 @@ class Elm_6f : public PhysicsModel { SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); SAVE_ONCE(Tibar, Tebar, Nbar); - Field2D tmp = tokamak_coordinates_factory.Bxy(); + Field2D tmp = tokamak_coordinates.Bxy(); SAVE_ONCE(Va, tmp); SAVE_ONCE(Ti0, Te0, N0); @@ -1138,13 +1137,13 @@ class Elm_6f : public PhysicsModel { Field2D logn0 = laplace_alpha * N0; Field3D Ntemp; Ntemp = N0; - ubyn = U * tokamak_coordinates_factory.Bxy() / Ntemp; + ubyn = U * tokamak_coordinates.Bxy() / Ntemp; // Phi should be consistent with U if (laplace_alpha <= 0.0) { - phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.Bxy(); + phi = phiSolver->solve(ubyn) / tokamak_coordinates.Bxy(); } else { phiSolver->setCoefC(logn0); - phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.Bxy(); + phi = phiSolver->solve(ubyn) / tokamak_coordinates.Bxy(); } } @@ -1219,9 +1218,9 @@ class Elm_6f : public PhysicsModel { // Field2D lap_temp=0.0; Field2D logn0 = laplace_alpha * N0; - ubyn = U * tokamak_coordinates_factory.Bxy() / N0; + ubyn = U * tokamak_coordinates.Bxy() / N0; if (diamag) { - ubyn -= Upara0 / N0 * Delp2(Pi) / tokamak_coordinates_factory.Bxy(); + ubyn -= Upara0 / N0 * Delp2(Pi) / tokamak_coordinates.Bxy(); mesh->communicate(ubyn); ubyn.applyBoundary(); } @@ -1229,7 +1228,7 @@ class Elm_6f : public PhysicsModel { if (laplace_alpha > 0.0) { phiSolver->setCoefC(logn0); } - phi = phiSolver->solve(ubyn) / tokamak_coordinates_factory.Bxy(); + phi = phiSolver->solve(ubyn) / tokamak_coordinates.Bxy(); mesh->communicate(phi); @@ -1325,9 +1324,9 @@ class Elm_6f : public PhysicsModel { if (compress0) { if (nonlinear) { - Vepar = Vipar - tokamak_coordinates_factory.Bxy() * (Jpar) / N_tmp * Vepara; + Vepar = Vipar - tokamak_coordinates.Bxy() * (Jpar) / N_tmp * Vepara; } else { - Vepar = Vipar - tokamak_coordinates_factory.Bxy() * (Jpar) / N0 * Vepara; + Vepar = Vipar - tokamak_coordinates.Bxy() * (Jpar) / N0 * Vepara; Vepar.applyBoundary(); mesh->communicate(Vepar); } @@ -1365,13 +1364,13 @@ class Elm_6f : public PhysicsModel { ddt(Psi) = 0.0; if (spitzer_resist) { - ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.Bxy() * phi) / tokamak_coordinates_factory.Bxy() - eta_spitzer * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() - eta_spitzer * Jpar; } else { - ddt(Psi) = -Grad_parP(tokamak_coordinates_factory.Bxy() * phi) / tokamak_coordinates_factory.Bxy() - eta * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() - eta * Jpar; } if (diamag) { - ddt(Psi) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Psi, bm_exb); // Equilibrium flow + ddt(Psi) -= bracket(tokamak_coordinates.Bxy() * phi0, Psi, bm_exb); // Equilibrium flow } // Hyper-resistivity @@ -1388,18 +1387,18 @@ class Elm_6f : public PhysicsModel { ddt(U) = 0.0; - ddt(U) = -SQ(tokamak_coordinates_factory.Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates_factory.Bxy(); // Grad j term + ddt(U) = -SQ(tokamak_coordinates.Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates.Bxy(); // Grad j term ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term - ddt(U) += SQ(tokamak_coordinates_factory.Bxy()) * Grad_parP(Jpar); // b dot grad j + ddt(U) += SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar); // b dot grad j if (diamag) { - ddt(U) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, U, bm_exb); // Equilibrium flow + ddt(U) -= bracket(tokamak_coordinates.Bxy() * phi0, U, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(U) -= bracket(tokamak_coordinates_factory.Bxy() * phi, U, bm_exb); // Advection + ddt(U) -= bracket(tokamak_coordinates.Bxy() * phi, U, bm_exb); // Advection } // parallel hyper-viscous diffusion for vector potential @@ -1451,18 +1450,18 @@ class Elm_6f : public PhysicsModel { ddt(Ni) = 0.0; - ddt(Ni) -= bracket(tokamak_coordinates_factory.Bxy() * phi, N0, bm_exb); + ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi, N0, bm_exb); if (diamag) { - ddt(Ni) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Ni, bm_exb); // Equilibrium flow + ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi0, Ni, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ni) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Ni, bm_exb); // Advection + ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi, Ni, bm_exb); // Advection } if (compress0) { - ddt(Ni) -= N0 * tokamak_coordinates_factory.Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.Bxy()); + ddt(Ni) -= N0 * tokamak_coordinates.Bxy() * Grad_parP(Vipar / tokamak_coordinates.Bxy()); } // 4th order Parallel diffusion terms @@ -1481,18 +1480,18 @@ class Elm_6f : public PhysicsModel { ddt(Ti) = 0.0; - ddt(Ti) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Ti0, bm_exb); + ddt(Ti) -= bracket(tokamak_coordinates.Bxy() * phi, Ti0, bm_exb); if (diamag) { - ddt(Ti) -= bracket(phi0 * tokamak_coordinates_factory.Bxy(), Ti, bm_exb); // Equilibrium flow + ddt(Ti) -= bracket(phi0 * tokamak_coordinates.Bxy(), Ti, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ti) -= bracket(phi * tokamak_coordinates_factory.Bxy(), Ti, bm_exb); // Advection + ddt(Ti) -= bracket(phi * tokamak_coordinates.Bxy(), Ti, bm_exb); // Advection } if (compress0) { - ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates_factory.Bxy() * Grad_parP(Vipar / tokamak_coordinates_factory.Bxy()); + ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates.Bxy() * Grad_parP(Vipar / tokamak_coordinates.Bxy()); } if (diffusion_par > 0.0) { @@ -1517,18 +1516,18 @@ class Elm_6f : public PhysicsModel { ddt(Te) = 0.0; - ddt(Te) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Te0, bm_exb); + ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi, Te0, bm_exb); if (diamag) { - ddt(Te) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Te, bm_exb); // Equilibrium flow + ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi0, Te, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Te) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Te, bm_exb); // Advection + ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi, Te, bm_exb); // Advection } if (compress0) { - ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates_factory.Bxy() * Grad_parP(Vepar / tokamak_coordinates_factory.Bxy()); + ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates.Bxy() * Grad_parP(Vepar / tokamak_coordinates.Bxy()); } if (diffusion_par > 0.0) { @@ -1551,14 +1550,14 @@ class Elm_6f : public PhysicsModel { ddt(Vipar) = 0.0; ddt(Vipar) -= Vipara * Grad_parP(P) / N0; - ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * tokamak_coordinates_factory.Bxy() / N0; + ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * tokamak_coordinates.Bxy() / N0; if (diamag) { - ddt(Vipar) -= bracket(tokamak_coordinates_factory.Bxy() * phi0, Vipar, bm_exb); + ddt(Vipar) -= bracket(tokamak_coordinates.Bxy() * phi0, Vipar, bm_exb); } if (nonlinear) { - ddt(Vipar) -= bracket(tokamak_coordinates_factory.Bxy() * phi, Vipar, bm_exb); + ddt(Vipar) -= bracket(tokamak_coordinates.Bxy() * phi, Vipar, bm_exb); } // parallel hyper-viscous diffusion for vector potential diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index c869ea69ec..6d9a3d5d21 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -5,7 +5,7 @@ * Model version in the code created by M. Umansky and J. Myra. *******************************************************************************/ #include -#include +#include #include #include @@ -118,7 +118,7 @@ class CWM : public PhysicsModel { hthe0 / rho_s); } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates = TokamakCoordinates(*mesh); /************** NORMALISE QUANTITIES *****************/ @@ -129,8 +129,8 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, - bmag / 1e4, ShearFactor); + coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, + ShearFactor); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); @@ -141,10 +141,10 @@ class CWM : public PhysicsModel { // add evolving variables to the communication object SOLVE_FOR(rho, te); - Field2D Rxy = tokamak_coordinates_factory.Rxy(); - Field2D Bpxy = tokamak_coordinates_factory.Bpxy(); - Field2D Btxy = tokamak_coordinates_factory.Btxy(); - Field2D hthe = tokamak_coordinates_factory.hthe(); + Field2D Rxy = tokamak_coordinates.Rxy(); + Field2D Bpxy = tokamak_coordinates.Bpxy(); + Field2D Btxy = tokamak_coordinates.Btxy(); + Field2D hthe = tokamak_coordinates.hthe(); SAVE_ONCE(Rxy, Bpxy, Btxy, Zxy, hthe); SAVE_ONCE(nu_hat, hthe0); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 93c5d1abc2..40fb0eecc9 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -2,7 +2,7 @@ #include #include #include -#include +#include /// Fundamental constants const BoutReal PI = 3.14159265; @@ -170,9 +170,9 @@ class Alfven : public PhysicsModel { noshear = true; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates = TokamakCoordinates(*mesh); const auto& coord = - tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lnorm, Bnorm); + tokamak_coordinates.make_coordinates(noshear, Lnorm, Bnorm); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index fdfc48db2a..d2217926f5 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -19,7 +19,7 @@ ****************************************************************/ #include -#include +#include #include #include @@ -81,7 +81,7 @@ class DALF3 : public PhysicsModel { std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) Field2D phi2D; // Axisymmetric potential, used when split_n0=true - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); protected: int init(bool UNUSED(restarting)) override { @@ -162,7 +162,7 @@ class DALF3 : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; noshear = true; } @@ -223,7 +223,7 @@ class DALF3 : public PhysicsModel { // Metrics const auto& coord = - tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, Bnorm); + tokamak_coordinates.make_coordinates(noshear, rho_s, Bnorm); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 4ac9774ac2..78b2c0d2fb 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include // Defines BOUT_FOR_RAJA @@ -288,7 +288,7 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass @@ -716,9 +716,10 @@ class ELMpb : public PhysicsModel { if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale Lbar = 1.0; } - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); + const auto& metric = + tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); - V0 = -tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Bpxy() * Dphi0 / tokamak_coordinates_factory.Bxy(); + V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 / tokamak_coordinates.Bxy(); if (simple_rmp) { include_rmp = true; @@ -813,7 +814,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } } @@ -823,7 +824,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } } @@ -933,7 +934,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.Bxy(); + J0 = -MU0 * Lbar * J0 / tokamak_coordinates.Bxy(); P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -1072,16 +1073,16 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); + B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; V0net.y = - tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Btxy() * tokamak_coordinates_factory.Bpxy() / (tokamak_coordinates_factory.hthe() * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()) * Dphi0; + tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() * tokamak_coordinates.Bpxy() / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory + U0 = B0vec * Curl(V0net) / tokamak_coordinates .Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1105,8 +1106,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (0.5 + (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates_factory.Bxy()) / tokamak_coordinates_factory.Bxy(); + beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates.Bxy()) / tokamak_coordinates.Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1139,10 +1140,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy(); + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy() / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy() / N0; } SAVE_ONCE(phi0); } else { @@ -1153,7 +1154,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - Field2D Bxy = tokamak_coordinates_factory.Bxy(); + Field2D Bxy = tokamak_coordinates.Bxy(); SAVE_ONCE(Va, Bxy); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); @@ -1213,7 +1214,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates_factory.ShearFactor()); + metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); } @@ -1527,7 +1528,7 @@ class ELMpb : public PhysicsModel { auto P0_acc = Field2DAccessor<>(P0); auto J0_acc = Field2DAccessor<>(J0); auto phi0_acc = Field2DAccessor<>(phi0); - Field2D Bxy = tokamak_coordinates_factory.Bxy(); + Field2D Bxy = tokamak_coordinates.Bxy(); auto B0_acc = Field2DAccessor<>(Bxy); // Evolving fields @@ -1715,16 +1716,16 @@ class ELMpb : public PhysicsModel { // Vorticity equation // Grad j term - // ddt(U) = SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); + // ddt(U) = SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); // if (include_rmp) { - // ddt(U) += SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + // ddt(U) += SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); // } ddt(U) += b0xcv * Grad(P); // curvature term // if (!nogradparj) { // Parallel current term - // ddt(U) -= SQ(tokamak_coordinates_factory.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + // ddt(U) -= SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j // } if (withflow && K_H_term) { // K_H_term diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 3a3ac0fe9c..e321d3672a 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -230,7 +230,7 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass @@ -645,7 +645,7 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Bpxy() * Dphi0 / tokamak_coordinates_factory.Bxy(); + V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 / tokamak_coordinates.Bxy(); if (simple_rmp) { include_rmp = true; @@ -740,7 +740,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } } @@ -750,7 +750,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } } @@ -867,7 +867,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / tokamak_coordinates_factory.Bxy(); + J0 = -MU0 * Lbar * J0 / tokamak_coordinates.Bxy(); P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -876,7 +876,8 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - const auto& metric = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); + const auto& metric = + tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// @@ -884,7 +885,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates_factory.ShearFactor()); + metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); } if (constn0) { @@ -1016,16 +1017,16 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); + B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; V0net.y = - tokamak_coordinates_factory.Rxy() * tokamak_coordinates_factory.Btxy() * tokamak_coordinates_factory.Bpxy() / (tokamak_coordinates_factory.hthe() * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()) * Dphi0; + tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() * tokamak_coordinates.Bpxy() / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates_factory + U0 = B0vec * Curl(V0net) / tokamak_coordinates .Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1049,8 +1050,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (0.5 + (tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates_factory.Bxy()) / tokamak_coordinates_factory.Bxy(); + beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); + gradparB = Grad_par(tokamak_coordinates.Bxy()) / tokamak_coordinates.Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1083,10 +1084,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy(); + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy(); } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates_factory.Bxy() / N0; + phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy() / N0; } SAVE_ONCE(phi0); } @@ -1095,7 +1096,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - Field2D tmp = tokamak_coordinates_factory.Bxy(); + Field2D tmp = tokamak_coordinates.Bxy(); SAVE_ONCE(Va, tmp); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); @@ -1163,7 +1164,7 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); if (nonlinear) { - const auto Bxy = tokamak_coordinates_factory.Bxy(); + const auto Bxy = tokamak_coordinates.Bxy(); result -= bracket(interp_to(Psi, loc), f, bm_mag) * Bxy; if (include_rmp) { @@ -1303,12 +1304,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / tokamak_coordinates_factory.Bxy(); + phi -= 0.5 * dnorm * P / tokamak_coordinates.Bxy(); } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates_factory.Bxy()) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates.Bxy()) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1453,9 +1454,9 @@ class ELMpb : public PhysicsModel { if (evolve_jpar) { // Jpar - Field3D B0U = tokamak_coordinates_factory.Bxy() * U; + Field3D B0U = tokamak_coordinates.Bxy() * U; mesh->communicate(B0U); - ddt(Jpar) = -Grad_parP(B0U, loc) / tokamak_coordinates_factory.Bxy() + eta * Delp2(Jpar); + ddt(Jpar) = -Grad_parP(B0U, loc) / tokamak_coordinates.Bxy() + eta * Delp2(Jpar); if (relax_j_vac) { // Make ddt(Jpar) relax to zero. @@ -1464,16 +1465,16 @@ class ELMpb : public PhysicsModel { } } else { // Vector potential - ddt(Psi) = -Grad_parP(phi * tokamak_coordinates_factory.Bxy(), loc) / tokamak_coordinates_factory.Bxy() + eta * Jpar; + ddt(Psi) = -Grad_parP(phi * tokamak_coordinates.Bxy(), loc) / tokamak_coordinates.Bxy() + eta * Jpar; if (eHall) { // electron parallel pressure ddt(Psi) += 0.25 * delta_i - * (Grad_parP(tokamak_coordinates_factory.Bxy() * P, loc) / tokamak_coordinates_factory.Bxy() - + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates_factory.Bxy()); + * (Grad_parP(tokamak_coordinates.Bxy() * P, loc) / tokamak_coordinates.Bxy() + + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates.Bxy()); } if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates_factory.Bxy(); + ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates.Bxy(); } if (withflow) { // net flow @@ -1481,7 +1482,7 @@ class ELMpb : public PhysicsModel { } if (diamag_grad_t) { // grad_par(T_e) correction - ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates_factory.Bxy(); + ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates.Bxy(); } if (hyperresist > 0.0) { // Hyper-resistivity @@ -1519,15 +1520,15 @@ class ELMpb : public PhysicsModel { Psi_loc = interp_to(Psi, CELL_CENTRE, "RGN_ALL"); Psi_loc.applyBoundary(); // Grad j term - ddt(U) = SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); + ddt(U) = SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); if (include_rmp) { - ddt(U) += SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + ddt(U) += SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } ddt(U) += b0xcv * Grad(P); // curvature term if (!nogradparj) { // Parallel current term - ddt(U) -= SQ(tokamak_coordinates_factory.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + ddt(U) -= SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j } if (withflow && K_H_term) { // K_H_term @@ -1543,7 +1544,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates_factory.Bxy(); + ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates.Bxy(); } // Viscosity terms @@ -1587,11 +1588,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates_factory.Bxy() * phi0)); + Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates.Bxy() * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(tokamak_coordinates_factory.Bxy() * phi); + Dperp2Phi = Delp2(tokamak_coordinates.Bxy() * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1603,35 +1604,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(tokamak_coordinates_factory.Bxy() * phi0, Pi, bm_exb); + bracketPhi0P = bracket(tokamak_coordinates.Bxy() * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(tokamak_coordinates_factory.Bxy() * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(tokamak_coordinates.Bxy() * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates_factory.Bxy(); - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.Bxy(); - Field3D B0phi = tokamak_coordinates_factory.Bxy() * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); + Field3D B0phi = tokamak_coordinates.Bxy() * phi; mesh->communicate(B0phi); - Field3D B0phi0 = tokamak_coordinates_factory.Bxy() * phi0; + Field3D B0phi0 = tokamak_coordinates.Bxy() * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates_factory.Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates_factory.Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates_factory.Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates.Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates.Bxy(); if (nonlinear) { - Field3D B0phi = tokamak_coordinates_factory.Bxy() * phi; + Field3D B0phi = tokamak_coordinates.Bxy() * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates_factory.Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates_factory.Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates_factory.Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates.Bxy(); } } @@ -1661,7 +1662,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates_factory.Bxy(); + ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates.Bxy(); } } @@ -1706,7 +1707,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates_factory.Bxy(); // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates.Bxy(); // Advection } } @@ -1797,7 +1798,7 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1806,7 +1807,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * tokamak_coordinates_factory.Bxy() * tokamak_coordinates_factory.Bxy()); + invU->setCoefB(-SQ(gamma) * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -1814,9 +1815,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = tokamak_coordinates_factory.Bxy() * phi3; + Field3D B0phi3 = tokamak_coordinates.Bxy() * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates_factory.Bxy(); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates.Bxy(); ddt(Psi).applyBoundary(); return 0; @@ -1848,14 +1849,14 @@ class ELMpb : public PhysicsModel { Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = tokamak_coordinates_factory.Bxy() * phi; + Field3D B0phi = tokamak_coordinates.Bxy() * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates_factory.Bxy(); + Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates.Bxy(); JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates_factory.Bxy()) * Grad_par(Jpar, CELL_CENTRE) - + SQ(tokamak_coordinates_factory.Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates.Bxy()) * Grad_par(Jpar, CELL_CENTRE) + + SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index be92ddea0a..5f401528f9 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -10,7 +10,7 @@ ****************************************************************/ #include -#include +#include #include #include @@ -242,17 +242,17 @@ class GEM : public PhysicsModel { Tbar = options["Tbar"].withDefault(Tbar); // Override in options file SAVE_ONCE(Tbar); // Timescale in seconds - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates = TokamakCoordinates(*mesh); if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { - Bbar = max(tokamak_coordinates_factory.Bxy(), true); + Bbar = max(tokamak_coordinates.Bxy(), true); } } Bbar = options["Bbar"].withDefault(Bbar); // Override in options file SAVE_ONCE(Bbar); - coord = tokamak_coordinates_factory.make_tokamak_coordinates(true, Lbar, Bbar); + coord = tokamak_coordinates.make_coordinates(true, Lbar, Bbar); beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); @@ -349,7 +349,7 @@ class GEM : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates_factory.Bpxy() / tokamak_coordinates_factory.hthe(); + B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); B0vec.z = 0.; // Precompute this for use in RHS diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index fbe1de3e9d..375c213132 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -4,7 +4,7 @@ #include #include #include -#include +#include /// Fundamental constants const BoutReal PI = 3.14159265; @@ -172,9 +172,8 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = - tokamak_coordinates_factory.make_tokamak_coordinates(true, Lnorm, Bnorm); + auto tokamak_coordinates = TokamakCoordinates(*mesh); + const auto& coord = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); } }; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 7d3c8972c4..485e321eb6 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -14,8 +14,8 @@ int main(int argc, char** argv) { bool calc_metric; calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coord = tokamak_coordinates_factory.make_tokamak_coordinates(true); + auto tokamak_coordinates = TokamakCoordinates(*mesh); + const auto& coord = tokamak_coordinates.make_coordinates(true); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 6ac11568e3..efc3977084 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -11,14 +11,14 @@ */ #include -#include +#include class WaveTest : public PhysicsModel { public: int init(bool UNUSED(restarting)) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - const auto& coords = tokamak_coordinates_factory.make_tokamak_coordinates(true); + auto tokamak_coordinates = TokamakCoordinates(*mesh); + const auto& coords = tokamak_coordinates.make_coordinates(true); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates_factory.hxx b/include/bout/tokamak_coordinates.hxx similarity index 88% rename from include/bout/tokamak_coordinates_factory.hxx rename to include/bout/tokamak_coordinates.hxx index 5690d4fdab..7a9833c025 100644 --- a/include/bout/tokamak_coordinates_factory.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -1,6 +1,6 @@ -#ifndef BOUT_TOKAMAK_COORDINATES_FACTORY_HXX -#define BOUT_TOKAMAK_COORDINATES_FACTORY_HXX +#ifndef BOUT_TOKAMAK_COORDINATES_HXX +#define BOUT_TOKAMAK_COORDINATES_HXX #include "bout.hxx" #include "bout/bout_types.hxx" @@ -10,7 +10,7 @@ #include "bout/utils.hxx" #include "bout/vector2d.hxx" -class TokamakCoordinatesFactory { +class TokamakCoordinates { private: Mesh& mesh_m; @@ -34,7 +34,7 @@ private: } public: - TokamakCoordinatesFactory(Mesh& mesh) : mesh_m(mesh) { + TokamakCoordinates(Mesh& mesh) : mesh_m(mesh) { mesh.get(Rxy_m, "Rxy"); // mesh->get(Zxy, "Zxy"); @@ -53,7 +53,7 @@ public: return 1.0; } - Coordinates* make_tokamak_coordinates(const bool noshear, BoutReal Lbar, BoutReal Bbar, + Coordinates* make_coordinates(const bool noshear, BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor = 1.0) { normalise(Lbar, Bbar, ShearFactor); @@ -98,4 +98,4 @@ public: const FieldMetric& ShearFactor() const { return ShearFactor_m; } }; -#endif //BOUT_TOKAMAK_COORDINATES_FACTORY_HXX +#endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index 34fa681945..eb14696cc4 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -315,8 +315,8 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - coords = tokamak_coordinates_factory.make_tokamak_coordinates(true, Lnorm, Bnorm); + auto tokamak_coordinates = TokamakCoordinates(*mesh); + coords = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 2342b6c69e..ae97d7d347 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -122,7 +122,7 @@ class ELMpb : public PhysicsModel { // Communication objects FieldGroup comms; - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); // Parallel gradient along perturbed field-line @@ -297,7 +297,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates_factory.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.get_ShearFactor() * b0xcv.x; } } } @@ -390,7 +390,7 @@ class ELMpb : public PhysicsModel { noshear = true; } - coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lbar, Bbar); + coords = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -400,7 +400,7 @@ class ELMpb : public PhysicsModel { if (ShiftXderivs) { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_coordinates_factory.get_ShearFactor()); + coord->setIntShiftTorsion(tokamak_coordinates.get_ShearFactor()); } } diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 2559fbcbd1..acffdcf882 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -45,9 +45,9 @@ class TokamakMMS : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + auto tokamak_coordinates = TokamakCoordinates(*mesh); auto coords = - tokamak_coordinates_factory.make_tokamak_coordinates(true, Lnorm, Bnorm); + tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 23dbb7e837..f8c38cebe0 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -4,7 +4,7 @@ *******************************************************************************/ #include -#include +#include #include #include @@ -59,7 +59,7 @@ class TwoFluid : public PhysicsModel { FieldGroup comms; // Group of variables for communications - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); Coordinates* coord; // Coordinate system @@ -134,7 +134,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; noshear = true; } @@ -193,8 +193,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, - bmag / 1e4, ShearFactor); + coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 843797e365..3845e7d050 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -3,7 +3,7 @@ * Same as Maxim's version of BOUT - simplified 2-fluid for benchmarking *******************************************************************************/ -#include +#include #include #include @@ -34,7 +34,7 @@ class Interchange : public PhysicsModel { Coordinates* coord; - TokamakCoordinatesFactory tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); protected: int init(bool UNUSED(restarting)) override { @@ -100,11 +100,11 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } - coord = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, rho_s, - bmag / 1e4, ShearFactor); + coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, + ShearFactor); if (ShiftXderivs) { - b0xcv.z += tokamak_coordinates_factory.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; } /************** NORMALISE QUANTITIES *****************/ diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 437c42b3b8..a25c92baae 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -17,6 +17,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { noshear = true; } - auto tokamak_coordinates_factory = TokamakCoordinatesFactory(*mesh); - auto coords = tokamak_coordinates_factory.make_tokamak_coordinates(noshear, Lnorm, Bnorm); + auto tokamak_coordinates = TokamakCoordinates(*mesh); + auto coords = tokamak_coordinates.make_coordinates(noshear, Lnorm, Bnorm); } From a029aa730a915177153f3c853076d5b3c21364e0 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 16 Dec 2024 19:00:55 +0000 Subject: [PATCH 82/98] Move implementation of TokamakCoordinates class out of header file --- CMakeLists.txt | 1 + include/bout/tokamak_coordinates.hxx | 68 +++------------------------ src/mesh/tokamak_coordinates.cxx | 69 ++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 61 deletions(-) create mode 100644 src/mesh/tokamak_coordinates.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index c561e91fa5..3d431d2dcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,6 +361,7 @@ set(BOUT_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx ./include/bout/tokamak_coordinates.hxx + ./src/mesh/tokamak_coordinates.cxx ) diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 7a9833c025..cb84549424 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -10,9 +10,11 @@ #include "bout/utils.hxx" #include "bout/vector2d.hxx" + class TokamakCoordinates { private: + Mesh& mesh_m; Field2D Rxy_m; Field2D Bpxy_m; @@ -22,73 +24,17 @@ private: FieldMetric ShearFactor_m; FieldMetric dx_m; - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor); - Rxy_m /= Lbar; - Bpxy_m /= Bbar; - Btxy_m /= Bbar; - Bxy_m /= Bbar; - hthe_m /= Lbar; - ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; - dx_m /= Lbar * Lbar * Bbar; - } + BoutReal get_sign_of_bp(); -public: - TokamakCoordinates(Mesh& mesh) : mesh_m(mesh) { - mesh.get(Rxy_m, "Rxy"); - // mesh->get(Zxy, "Zxy"); - mesh.get(Bpxy_m, "Bpxy"); - mesh.get(Btxy_m, "Btxy"); - mesh.get(Bxy_m, "Bxy"); - mesh.get(hthe_m, "hthe"); - mesh.get(ShearFactor_m, "sinty"); - mesh.get(dx_m, "dpsi"); - } +public: - BoutReal get_sign_of_bp() { - if (min(Bpxy_m, true) < 0.0) { - return -1.0; - } - return 1.0; - } + TokamakCoordinates(Mesh& mesh); Coordinates* make_coordinates(const bool noshear, BoutReal Lbar, BoutReal Bbar, - BoutReal ShearFactor = 1.0) { - - normalise(Lbar, Bbar, ShearFactor); - - const BoutReal sign_of_bp = get_sign_of_bp(); - - if (noshear) { - ShearFactor_m = 0.0; - } - - auto* coord = mesh_m.getCoordinates(); - - const auto g11 = SQ(Rxy_m * Bpxy_m); - const auto g22 = 1.0 / SQ(hthe_m); - const auto g33 = SQ(ShearFactor_m) * g11 + SQ(Bxy_m) / g11; - const auto g12 = 0.0; - const auto g13 = -ShearFactor_m * g11; - const auto g23 = -sign_of_bp * Btxy_m / (hthe_m * Bpxy_m * Rxy_m); - - const auto g_11 = 1.0 / g11 + SQ(ShearFactor_m * Rxy_m); - const auto g_22 = SQ(Bxy_m * hthe_m / Bpxy_m); - const auto g_33 = Rxy_m * Rxy_m; - const auto g_12 = sign_of_bp * Btxy_m * hthe_m * ShearFactor_m * Rxy_m / Bpxy_m; - const auto g_13 = ShearFactor_m * Rxy_m * Rxy_m; - const auto g_23 = sign_of_bp * Btxy_m * hthe_m * Rxy_m / Bpxy_m; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe_m / Bpxy_m); - coord->setBxy(Bxy_m); - coord->setDx(dx_m); - - return coord; - } + BoutReal ShearFactor = 1.0); const Field2D& Rxy() const { return Rxy_m; } const Field2D& Bpxy() const { return Bpxy_m; } diff --git a/src/mesh/tokamak_coordinates.cxx b/src/mesh/tokamak_coordinates.cxx new file mode 100644 index 0000000000..6613d61cb1 --- /dev/null +++ b/src/mesh/tokamak_coordinates.cxx @@ -0,0 +1,69 @@ +#include + + +void TokamakCoordinates::normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { + + Rxy_m /= Lbar; + Bpxy_m /= Bbar; + Btxy_m /= Bbar; + Bxy_m /= Bbar; + hthe_m /= Lbar; + ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; + dx_m /= Lbar * Lbar * Bbar; + } + + TokamakCoordinates::TokamakCoordinates(Mesh& mesh) : mesh_m(mesh) { + + mesh.get(Rxy_m, "Rxy"); + // mesh->get(Zxy, "Zxy"); + mesh.get(Bpxy_m, "Bpxy"); + mesh.get(Btxy_m, "Btxy"); + mesh.get(Bxy_m, "Bxy"); + mesh.get(hthe_m, "hthe"); + mesh.get(ShearFactor_m, "sinty"); + mesh.get(dx_m, "dpsi"); + } + + BoutReal TokamakCoordinates::get_sign_of_bp() { + if (min(Bpxy_m, true) < 0.0) { + return -1.0; + } + return 1.0; + } + + Coordinates* TokamakCoordinates::make_coordinates(const bool noshear, BoutReal Lbar, + BoutReal Bbar, BoutReal ShearFactor) { + + normalise(Lbar, Bbar, ShearFactor); + + const BoutReal sign_of_bp = get_sign_of_bp(); + + if (noshear) { + ShearFactor_m = 0.0; + } + + auto* coord = mesh_m.getCoordinates(); + + const auto g11 = SQ(Rxy_m * Bpxy_m); + const auto g22 = 1.0 / SQ(hthe_m); + const auto g33 = SQ(ShearFactor_m) * g11 + SQ(Bxy_m) / g11; + const auto g12 = 0.0; + const auto g13 = -ShearFactor_m * g11; + const auto g23 = -sign_of_bp * Btxy_m / (hthe_m * Bpxy_m * Rxy_m); + + const auto g_11 = 1.0 / g11 + SQ(ShearFactor_m * Rxy_m); + const auto g_22 = SQ(Bxy_m * hthe_m / Bpxy_m); + const auto g_33 = Rxy_m * Rxy_m; + const auto g_12 = sign_of_bp * Btxy_m * hthe_m * ShearFactor_m * Rxy_m / Bpxy_m; + const auto g_13 = ShearFactor_m * Rxy_m * Rxy_m; + const auto g_23 = sign_of_bp * Btxy_m * hthe_m * Rxy_m / Bpxy_m; + + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + + coord->setJ(hthe_m / Bpxy_m); + coord->setBxy(Bxy_m); + coord->setDx(dx_m); + + return coord; + } From 4b5ab57ed5f356cabba157cd6e63e197ddba3c3f Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 16 Dec 2024 19:56:47 +0000 Subject: [PATCH 83/98] Apply clang-format changes --- examples/6field-simple/elm_6f.cxx | 47 +++++--- examples/conducting-wall-mode/cwm.cxx | 3 +- examples/constraints/alfven-wave/alfven.cxx | 3 +- examples/dalf3/dalf3.cxx | 3 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 40 ++++--- examples/elm-pb/elm_pb.cxx | 71 +++++++----- examples/laplacexy/alfven-wave/alfven.cxx | 1 - include/bout/tokamak_coordinates.hxx | 6 +- src/mesh/tokamak_coordinates.cxx | 107 +++++++++--------- tests/MMS/elm-pb/elm_pb.cxx | 3 +- tests/MMS/tokamak/tokamak.cxx | 5 +- .../test-interchange-instability/2fluid.cxx | 3 +- 12 files changed, 159 insertions(+), 133 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 88bf18b4b0..d6d7e1ca3e 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -904,8 +904,7 @@ class Elm_6f : public PhysicsModel { q95 = q95_input; // use a constant for test } else { if (local_q) { - q95 = abs(tokamak_coordinates.hthe() - * tokamak_coordinates.Btxy() + q95 = abs(tokamak_coordinates.hthe() * tokamak_coordinates.Btxy() / tokamak_coordinates.Bpxy()) * q_alpha; } else { @@ -1021,7 +1020,6 @@ class Elm_6f : public PhysicsModel { dump.add(eta, "eta", 0); } - ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES if (!mesh->IncIntShear) { @@ -1057,8 +1055,14 @@ class Elm_6f : public PhysicsModel { V0eff.covariant = false; V0eff.x = 0.; - V0eff.y = -(tokamak_coordinates.Btxy() / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) / tokamak_coordinates.hthe(); - V0eff.z = (tokamak_coordinates.Bpxy() / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) / tokamak_coordinates.Rxy(); + V0eff.y = -(tokamak_coordinates.Btxy() + / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) + * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) + / tokamak_coordinates.hthe(); + V0eff.z = (tokamak_coordinates.Bpxy() + / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) + * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) + / tokamak_coordinates.Rxy(); Pe.setBoundary("P"); Pi.setBoundary("P"); @@ -1364,13 +1368,16 @@ class Elm_6f : public PhysicsModel { ddt(Psi) = 0.0; if (spitzer_resist) { - ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() - eta_spitzer * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() + - eta_spitzer * Jpar; } else { - ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() - eta * Jpar; + ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() + - eta * Jpar; } if (diamag) { - ddt(Psi) -= bracket(tokamak_coordinates.Bxy() * phi0, Psi, bm_exb); // Equilibrium flow + ddt(Psi) -= + bracket(tokamak_coordinates.Bxy() * phi0, Psi, bm_exb); // Equilibrium flow } // Hyper-resistivity @@ -1387,14 +1394,16 @@ class Elm_6f : public PhysicsModel { ddt(U) = 0.0; - ddt(U) = -SQ(tokamak_coordinates.Bxy()) * bracket(Psi, J0, bm_mag) * tokamak_coordinates.Bxy(); // Grad j term + ddt(U) = -SQ(tokamak_coordinates.Bxy()) * bracket(Psi, J0, bm_mag) + * tokamak_coordinates.Bxy(); // Grad j term ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term ddt(U) += SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar); // b dot grad j if (diamag) { - ddt(U) -= bracket(tokamak_coordinates.Bxy() * phi0, U, bm_exb); // Equilibrium flow + ddt(U) -= + bracket(tokamak_coordinates.Bxy() * phi0, U, bm_exb); // Equilibrium flow } if (nonlinear) { @@ -1453,7 +1462,8 @@ class Elm_6f : public PhysicsModel { ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi, N0, bm_exb); if (diamag) { - ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi0, Ni, bm_exb); // Equilibrium flow + ddt(Ni) -= + bracket(tokamak_coordinates.Bxy() * phi0, Ni, bm_exb); // Equilibrium flow } if (nonlinear) { @@ -1461,7 +1471,8 @@ class Elm_6f : public PhysicsModel { } if (compress0) { - ddt(Ni) -= N0 * tokamak_coordinates.Bxy() * Grad_parP(Vipar / tokamak_coordinates.Bxy()); + ddt(Ni) -= + N0 * tokamak_coordinates.Bxy() * Grad_parP(Vipar / tokamak_coordinates.Bxy()); } // 4th order Parallel diffusion terms @@ -1483,7 +1494,8 @@ class Elm_6f : public PhysicsModel { ddt(Ti) -= bracket(tokamak_coordinates.Bxy() * phi, Ti0, bm_exb); if (diamag) { - ddt(Ti) -= bracket(phi0 * tokamak_coordinates.Bxy(), Ti, bm_exb); // Equilibrium flow + ddt(Ti) -= + bracket(phi0 * tokamak_coordinates.Bxy(), Ti, bm_exb); // Equilibrium flow } if (nonlinear) { @@ -1491,7 +1503,8 @@ class Elm_6f : public PhysicsModel { } if (compress0) { - ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates.Bxy() * Grad_parP(Vipar / tokamak_coordinates.Bxy()); + ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates.Bxy() + * Grad_parP(Vipar / tokamak_coordinates.Bxy()); } if (diffusion_par > 0.0) { @@ -1519,7 +1532,8 @@ class Elm_6f : public PhysicsModel { ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi, Te0, bm_exb); if (diamag) { - ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi0, Te, bm_exb); // Equilibrium flow + ddt(Te) -= + bracket(tokamak_coordinates.Bxy() * phi0, Te, bm_exb); // Equilibrium flow } if (nonlinear) { @@ -1527,7 +1541,8 @@ class Elm_6f : public PhysicsModel { } if (compress0) { - ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates.Bxy() * Grad_parP(Vepar / tokamak_coordinates.Bxy()); + ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates.Bxy() + * Grad_parP(Vepar / tokamak_coordinates.Bxy()); } if (diffusion_par > 0.0) { diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 6d9a3d5d21..ee434e300d 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -129,8 +129,7 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, - ShearFactor); + coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 40fb0eecc9..f3dd0d8a66 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -171,8 +171,7 @@ class Alfven : public PhysicsModel { } auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coord = - tokamak_coordinates.make_coordinates(noshear, Lnorm, Bnorm); + const auto& coord = tokamak_coordinates.make_coordinates(noshear, Lnorm, Bnorm); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index d2217926f5..700de90ad8 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -222,8 +222,7 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - const auto& coord = - tokamak_coordinates.make_coordinates(noshear, rho_s, Bnorm); + const auto& coord = tokamak_coordinates.make_coordinates(noshear, rho_s, Bnorm); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 78b2c0d2fb..47564d9f0a 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -716,10 +716,10 @@ class ELMpb : public PhysicsModel { if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale Lbar = 1.0; } - const auto& metric = - tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); + const auto& metric = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); - V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 / tokamak_coordinates.Bxy(); + V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 + / tokamak_coordinates.Bxy(); if (simple_rmp) { include_rmp = true; @@ -943,7 +943,6 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - if (constn0) { T0_fake_prof = false; n0_fake_prof = false; @@ -1078,12 +1077,15 @@ class ELMpb : public PhysicsModel { V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = - tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() * tokamak_coordinates.Bpxy() / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) * Dphi0; + V0net.y = tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() + * tokamak_coordinates.Bpxy() + / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() + * tokamak_coordinates.Bxy()) + * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates - .Bxy(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) + / tokamak_coordinates.Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1106,7 +1108,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); + beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() + / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); gradparB = Grad_par(tokamak_coordinates.Bxy()) / tokamak_coordinates.Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); @@ -1215,7 +1218,6 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); - } return 0; @@ -1653,12 +1655,12 @@ class ELMpb : public PhysicsModel { #endif }; - // Terms which are not yet single index operators - // Note: Terms which are included in the single index loop - // may be commented out here, to allow comparison/testing + // Terms which are not yet single index operators + // Note: Terms which are included in the single index loop + // may be commented out here, to allow comparison/testing - //////////////////////////////////////////////////// - // Parallel electric field + //////////////////////////////////////////////////// + // Parallel electric field #if not EVOLVE_JPAR // Vector potential @@ -1906,7 +1908,8 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * metric->Bxy(); // Advection + ddt(Vpar) -= + bracket(interp_to(phi, loc), Vpar, bm_exb) * metric->Bxy(); // Advection } } @@ -1994,11 +1997,12 @@ class ELMpb : public PhysicsModel { } mesh->communicate(Jrhs, ddt(P)); - + Coordinates* metric = mesh->getCoordinates(); Field3D U1 = ddt(U); - U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index e321d3672a..c81b4a5367 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -645,7 +645,8 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 / tokamak_coordinates.Bxy(); + V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 + / tokamak_coordinates.Bxy(); if (simple_rmp) { include_rmp = true; @@ -876,9 +877,7 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - const auto& metric = - tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); - + const auto& metric = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES @@ -1022,12 +1021,15 @@ class ELMpb : public PhysicsModel { V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = - tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() * tokamak_coordinates.Bpxy() / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) * Dphi0; + V0net.y = tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() + * tokamak_coordinates.Bpxy() + / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() + * tokamak_coordinates.Bxy()) + * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) / tokamak_coordinates - .Bxy(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) + / tokamak_coordinates.Bxy(); // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1050,7 +1052,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); + beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() + / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); gradparB = Grad_par(tokamak_coordinates.Bxy()) / tokamak_coordinates.Bxy(); output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); @@ -1465,16 +1468,20 @@ class ELMpb : public PhysicsModel { } } else { // Vector potential - ddt(Psi) = -Grad_parP(phi * tokamak_coordinates.Bxy(), loc) / tokamak_coordinates.Bxy() + eta * Jpar; + ddt(Psi) = + -Grad_parP(phi * tokamak_coordinates.Bxy(), loc) / tokamak_coordinates.Bxy() + + eta * Jpar; if (eHall) { // electron parallel pressure - ddt(Psi) += 0.25 * delta_i - * (Grad_parP(tokamak_coordinates.Bxy() * P, loc) / tokamak_coordinates.Bxy() - + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates.Bxy()); + ddt(Psi) += + 0.25 * delta_i + * (Grad_parP(tokamak_coordinates.Bxy() * P, loc) / tokamak_coordinates.Bxy() + + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates.Bxy()); } if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates.Bxy(); + ddt(Psi) -= + bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates.Bxy(); } if (withflow) { // net flow @@ -1522,13 +1529,15 @@ class ELMpb : public PhysicsModel { // Grad j term ddt(U) = SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); if (include_rmp) { - ddt(U) += SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + ddt(U) += + SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } ddt(U) += b0xcv * Grad(P); // curvature term if (!nogradparj) { // Parallel current term - ddt(U) -= SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + ddt(U) -= + SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j } if (withflow && K_H_term) { // K_H_term @@ -1612,14 +1621,18 @@ class ELMpb : public PhysicsModel { bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) -= + 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) -= + 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); Field3D B0phi = tokamak_coordinates.Bxy() * phi; mesh->communicate(B0phi); Field3D B0phi0 = tokamak_coordinates.Bxy() * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) += + 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) += + 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates.Bxy(); ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates.Bxy(); @@ -1630,8 +1643,10 @@ class ELMpb : public PhysicsModel { bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) -= + 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); + ddt(U) += + 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates.Bxy(); } } @@ -1707,7 +1722,8 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * tokamak_coordinates.Bxy(); // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) + * tokamak_coordinates.Bxy(); // Advection } } @@ -1798,7 +1814,9 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) + * Grad_par(Jrhs, CELL_CENTRE) + + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1855,8 +1873,9 @@ class ELMpb : public PhysicsModel { JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates.Bxy()) * Grad_par(Jpar, CELL_CENTRE) - + SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = + b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates.Bxy()) * Grad_par(Jpar, CELL_CENTRE) + + SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 375c213132..5de216bfb5 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -171,7 +171,6 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates = TokamakCoordinates(*mesh); const auto& coord = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); } diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index cb84549424..151618a5d8 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -10,11 +10,9 @@ #include "bout/utils.hxx" #include "bout/vector2d.hxx" - class TokamakCoordinates { private: - Mesh& mesh_m; Field2D Rxy_m; Field2D Bpxy_m; @@ -28,13 +26,11 @@ private: BoutReal get_sign_of_bp(); - public: - TokamakCoordinates(Mesh& mesh); Coordinates* make_coordinates(const bool noshear, BoutReal Lbar, BoutReal Bbar, - BoutReal ShearFactor = 1.0); + BoutReal ShearFactor = 1.0); const Field2D& Rxy() const { return Rxy_m; } const Field2D& Bpxy() const { return Bpxy_m; } diff --git a/src/mesh/tokamak_coordinates.cxx b/src/mesh/tokamak_coordinates.cxx index 6613d61cb1..c5e395a2fd 100644 --- a/src/mesh/tokamak_coordinates.cxx +++ b/src/mesh/tokamak_coordinates.cxx @@ -1,69 +1,68 @@ #include - void TokamakCoordinates::normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { - Rxy_m /= Lbar; - Bpxy_m /= Bbar; - Btxy_m /= Bbar; - Bxy_m /= Bbar; - hthe_m /= Lbar; - ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; - dx_m /= Lbar * Lbar * Bbar; - } - - TokamakCoordinates::TokamakCoordinates(Mesh& mesh) : mesh_m(mesh) { - - mesh.get(Rxy_m, "Rxy"); - // mesh->get(Zxy, "Zxy"); - mesh.get(Bpxy_m, "Bpxy"); - mesh.get(Btxy_m, "Btxy"); - mesh.get(Bxy_m, "Bxy"); - mesh.get(hthe_m, "hthe"); - mesh.get(ShearFactor_m, "sinty"); - mesh.get(dx_m, "dpsi"); + Rxy_m /= Lbar; + Bpxy_m /= Bbar; + Btxy_m /= Bbar; + Bxy_m /= Bbar; + hthe_m /= Lbar; + ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; + dx_m /= Lbar * Lbar * Bbar; +} + +TokamakCoordinates::TokamakCoordinates(Mesh& mesh) : mesh_m(mesh) { + + mesh.get(Rxy_m, "Rxy"); + // mesh->get(Zxy, "Zxy"); + mesh.get(Bpxy_m, "Bpxy"); + mesh.get(Btxy_m, "Btxy"); + mesh.get(Bxy_m, "Bxy"); + mesh.get(hthe_m, "hthe"); + mesh.get(ShearFactor_m, "sinty"); + mesh.get(dx_m, "dpsi"); +} + +BoutReal TokamakCoordinates::get_sign_of_bp() { + if (min(Bpxy_m, true) < 0.0) { + return -1.0; } + return 1.0; +} - BoutReal TokamakCoordinates::get_sign_of_bp() { - if (min(Bpxy_m, true) < 0.0) { - return -1.0; - } - return 1.0; - } - - Coordinates* TokamakCoordinates::make_coordinates(const bool noshear, BoutReal Lbar, - BoutReal Bbar, BoutReal ShearFactor) { +Coordinates* TokamakCoordinates::make_coordinates(const bool noshear, BoutReal Lbar, + BoutReal Bbar, BoutReal ShearFactor) { - normalise(Lbar, Bbar, ShearFactor); + normalise(Lbar, Bbar, ShearFactor); - const BoutReal sign_of_bp = get_sign_of_bp(); + const BoutReal sign_of_bp = get_sign_of_bp(); - if (noshear) { - ShearFactor_m = 0.0; - } + if (noshear) { + ShearFactor_m = 0.0; + } - auto* coord = mesh_m.getCoordinates(); + auto* coord = mesh_m.getCoordinates(); - const auto g11 = SQ(Rxy_m * Bpxy_m); - const auto g22 = 1.0 / SQ(hthe_m); - const auto g33 = SQ(ShearFactor_m) * g11 + SQ(Bxy_m) / g11; - const auto g12 = 0.0; - const auto g13 = -ShearFactor_m * g11; - const auto g23 = -sign_of_bp * Btxy_m / (hthe_m * Bpxy_m * Rxy_m); + const auto g11 = SQ(Rxy_m * Bpxy_m); + const auto g22 = 1.0 / SQ(hthe_m); + const auto g33 = SQ(ShearFactor_m) * g11 + SQ(Bxy_m) / g11; + const auto g12 = 0.0; + const auto g13 = -ShearFactor_m * g11; + const auto g23 = -sign_of_bp * Btxy_m / (hthe_m * Bpxy_m * Rxy_m); - const auto g_11 = 1.0 / g11 + SQ(ShearFactor_m * Rxy_m); - const auto g_22 = SQ(Bxy_m * hthe_m / Bpxy_m); - const auto g_33 = Rxy_m * Rxy_m; - const auto g_12 = sign_of_bp * Btxy_m * hthe_m * ShearFactor_m * Rxy_m / Bpxy_m; - const auto g_13 = ShearFactor_m * Rxy_m * Rxy_m; - const auto g_23 = sign_of_bp * Btxy_m * hthe_m * Rxy_m / Bpxy_m; + const auto g_11 = 1.0 / g11 + SQ(ShearFactor_m * Rxy_m); + const auto g_22 = SQ(Bxy_m * hthe_m / Bpxy_m); + const auto g_33 = Rxy_m * Rxy_m; + const auto g_12 = sign_of_bp * Btxy_m * hthe_m * ShearFactor_m * Rxy_m / Bpxy_m; + const auto g_13 = ShearFactor_m * Rxy_m * Rxy_m; + const auto g_23 = sign_of_bp * Btxy_m * hthe_m * Rxy_m / Bpxy_m; - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - coord->setJ(hthe_m / Bpxy_m); - coord->setBxy(Bxy_m); - coord->setDx(dx_m); + coord->setJ(hthe_m / Bpxy_m); + coord->setBxy(Bxy_m); + coord->setDx(dx_m); - return coord; - } + return coord; +} diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index ae97d7d347..a4881838c1 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -9,7 +9,6 @@ * *******************************************************************************/ -#include #include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include #include #include @@ -124,7 +124,6 @@ class ELMpb : public PhysicsModel { TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); - // Parallel gradient along perturbed field-line const Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) { Field3D result; diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index acffdcf882..a22a574969 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -8,8 +8,8 @@ #include #include -#include #include +#include class TokamakMMS : public PhysicsModel { public: @@ -46,8 +46,7 @@ class TokamakMMS : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - auto coords = - tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); + auto coords = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); } private: diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 3845e7d050..15d4df6790 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -100,8 +100,7 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } - coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, - ShearFactor); + coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); if (ShiftXderivs) { b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; From 4f2446f8a45faef2126b7c19d8bd1f11321861ef Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 13 Jan 2025 12:24:09 +0000 Subject: [PATCH 84/98] Copy values to local variables --- examples/6field-simple/elm_6f.cxx | 91 ++++++----- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 129 ++++++++-------- examples/elm-pb/elm_pb.cxx | 141 +++++++++--------- 3 files changed, 173 insertions(+), 188 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index d6d7e1ca3e..7d98b52562 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1041,28 +1041,29 @@ class Elm_6f : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); + + auto Bpxy = tokamak_coordinates.Bpxy(); + auto hthe = tokamak_coordinates.hthe(); + auto Rxy = tokamak_coordinates.Rxy(); + auto Btxy = tokamak_coordinates.Btxy(); + auto B0 = tokamak_coordinates.Bxy(); + + B0vec.y = Bpxy / hthe; B0vec.z = 0.; // Set V0vec field vector V0vec.covariant = false; V0vec.x = 0.; - V0vec.y = Vp0 / tokamak_coordinates.hthe(); - V0vec.z = Vt0 / tokamak_coordinates.Rxy(); + V0vec.y = Vp0 / hthe; + V0vec.z = Vt0 / Rxy; // Set V0eff field vector V0eff.covariant = false; V0eff.x = 0.; - V0eff.y = -(tokamak_coordinates.Btxy() - / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) - * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) - / tokamak_coordinates.hthe(); - V0eff.z = (tokamak_coordinates.Bpxy() - / (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy())) - * (Vp0 * tokamak_coordinates.Btxy() - Vt0 * tokamak_coordinates.Bpxy()) - / tokamak_coordinates.Rxy(); + V0eff.y = -(Btxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / hthe; + V0eff.z = (Bpxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / Rxy; Pe.setBoundary("P"); Pi.setBoundary("P"); @@ -1222,9 +1223,12 @@ class Elm_6f : public PhysicsModel { // Field2D lap_temp=0.0; Field2D logn0 = laplace_alpha * N0; - ubyn = U * tokamak_coordinates.Bxy() / N0; + + auto B0 = tokamak_coordinates.Bxy(); + + ubyn = U * B0 / N0; if (diamag) { - ubyn -= Upara0 / N0 * Delp2(Pi) / tokamak_coordinates.Bxy(); + ubyn -= Upara0 / N0 * Delp2(Pi) / B0; mesh->communicate(ubyn); ubyn.applyBoundary(); } @@ -1232,7 +1236,7 @@ class Elm_6f : public PhysicsModel { if (laplace_alpha > 0.0) { phiSolver->setCoefC(logn0); } - phi = phiSolver->solve(ubyn) / tokamak_coordinates.Bxy(); + phi = phiSolver->solve(ubyn) / B0; mesh->communicate(phi); @@ -1328,9 +1332,9 @@ class Elm_6f : public PhysicsModel { if (compress0) { if (nonlinear) { - Vepar = Vipar - tokamak_coordinates.Bxy() * (Jpar) / N_tmp * Vepara; + Vepar = Vipar - B0 * (Jpar) / N_tmp * Vepara; } else { - Vepar = Vipar - tokamak_coordinates.Bxy() * (Jpar) / N0 * Vepara; + Vepar = Vipar - B0 * (Jpar) / N0 * Vepara; Vepar.applyBoundary(); mesh->communicate(Vepar); } @@ -1368,16 +1372,13 @@ class Elm_6f : public PhysicsModel { ddt(Psi) = 0.0; if (spitzer_resist) { - ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() - - eta_spitzer * Jpar; + ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta_spitzer * Jpar; } else { - ddt(Psi) = -Grad_parP(tokamak_coordinates.Bxy() * phi) / tokamak_coordinates.Bxy() - - eta * Jpar; + ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta * Jpar; } if (diamag) { - ddt(Psi) -= - bracket(tokamak_coordinates.Bxy() * phi0, Psi, bm_exb); // Equilibrium flow + ddt(Psi) -= bracket(B0 * phi0, Psi, bm_exb); // Equilibrium flow } // Hyper-resistivity @@ -1394,20 +1395,18 @@ class Elm_6f : public PhysicsModel { ddt(U) = 0.0; - ddt(U) = -SQ(tokamak_coordinates.Bxy()) * bracket(Psi, J0, bm_mag) - * tokamak_coordinates.Bxy(); // Grad j term + ddt(U) = -SQ(B0) * bracket(Psi, J0, bm_mag) * B0; // Grad j term ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term - ddt(U) += SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar); // b dot grad j + ddt(U) += SQ(B0) * Grad_parP(Jpar); // b dot grad j if (diamag) { - ddt(U) -= - bracket(tokamak_coordinates.Bxy() * phi0, U, bm_exb); // Equilibrium flow + ddt(U) -= bracket(B0 * phi0, U, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(U) -= bracket(tokamak_coordinates.Bxy() * phi, U, bm_exb); // Advection + ddt(U) -= bracket(B0 * phi, U, bm_exb); // Advection } // parallel hyper-viscous diffusion for vector potential @@ -1459,20 +1458,18 @@ class Elm_6f : public PhysicsModel { ddt(Ni) = 0.0; - ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi, N0, bm_exb); + ddt(Ni) -= bracket(B0 * phi, N0, bm_exb); if (diamag) { - ddt(Ni) -= - bracket(tokamak_coordinates.Bxy() * phi0, Ni, bm_exb); // Equilibrium flow + ddt(Ni) -= bracket(B0 * phi0, Ni, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ni) -= bracket(tokamak_coordinates.Bxy() * phi, Ni, bm_exb); // Advection + ddt(Ni) -= bracket(B0 * phi, Ni, bm_exb); // Advection } if (compress0) { - ddt(Ni) -= - N0 * tokamak_coordinates.Bxy() * Grad_parP(Vipar / tokamak_coordinates.Bxy()); + ddt(Ni) -= N0 * B0 * Grad_parP(Vipar / B0); } // 4th order Parallel diffusion terms @@ -1491,20 +1488,18 @@ class Elm_6f : public PhysicsModel { ddt(Ti) = 0.0; - ddt(Ti) -= bracket(tokamak_coordinates.Bxy() * phi, Ti0, bm_exb); + ddt(Ti) -= bracket(B0 * phi, Ti0, bm_exb); if (diamag) { - ddt(Ti) -= - bracket(phi0 * tokamak_coordinates.Bxy(), Ti, bm_exb); // Equilibrium flow + ddt(Ti) -= bracket(phi0 * B0, Ti, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Ti) -= bracket(phi * tokamak_coordinates.Bxy(), Ti, bm_exb); // Advection + ddt(Ti) -= bracket(phi * B0, Ti, bm_exb); // Advection } if (compress0) { - ddt(Ti) -= 2.0 / 3.0 * Ti0 * tokamak_coordinates.Bxy() - * Grad_parP(Vipar / tokamak_coordinates.Bxy()); + ddt(Ti) -= 2.0 / 3.0 * Ti0 * B0 * Grad_parP(Vipar / B0); } if (diffusion_par > 0.0) { @@ -1529,20 +1524,18 @@ class Elm_6f : public PhysicsModel { ddt(Te) = 0.0; - ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi, Te0, bm_exb); + ddt(Te) -= bracket(B0 * phi, Te0, bm_exb); if (diamag) { - ddt(Te) -= - bracket(tokamak_coordinates.Bxy() * phi0, Te, bm_exb); // Equilibrium flow + ddt(Te) -= bracket(B0 * phi0, Te, bm_exb); // Equilibrium flow } if (nonlinear) { - ddt(Te) -= bracket(tokamak_coordinates.Bxy() * phi, Te, bm_exb); // Advection + ddt(Te) -= bracket(B0 * phi, Te, bm_exb); // Advection } if (compress0) { - ddt(Te) -= 2.0 / 3.0 * Te0 * tokamak_coordinates.Bxy() - * Grad_parP(Vepar / tokamak_coordinates.Bxy()); + ddt(Te) -= 2.0 / 3.0 * Te0 * B0 * Grad_parP(Vepar / B0); } if (diffusion_par > 0.0) { @@ -1565,14 +1558,14 @@ class Elm_6f : public PhysicsModel { ddt(Vipar) = 0.0; ddt(Vipar) -= Vipara * Grad_parP(P) / N0; - ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * tokamak_coordinates.Bxy() / N0; + ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * B0 / N0; if (diamag) { - ddt(Vipar) -= bracket(tokamak_coordinates.Bxy() * phi0, Vipar, bm_exb); + ddt(Vipar) -= bracket(B0 * phi0, Vipar, bm_exb); } if (nonlinear) { - ddt(Vipar) -= bracket(tokamak_coordinates.Bxy() * phi, Vipar, bm_exb); + ddt(Vipar) -= bracket(B0 * phi, Vipar, bm_exb); } // parallel hyper-viscous diffusion for vector potential diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 47564d9f0a..6f4dbb8b10 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -718,8 +718,13 @@ class ELMpb : public PhysicsModel { } const auto& metric = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); - V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 - / tokamak_coordinates.Bxy(); + auto Bpxy = tokamak_coordinates.Bpxy(); + auto hthe = tokamak_coordinates.hthe(); + auto Rxy = tokamak_coordinates.Rxy(); + auto Btxy = tokamak_coordinates.Btxy(); + auto B0 = tokamak_coordinates.Bxy(); + + V0 = -Rxy * Bpxy * Dphi0 / B0; if (simple_rmp) { include_rmp = true; @@ -934,7 +939,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / tokamak_coordinates.Bxy(); + J0 = -MU0 * Lbar * J0 / B0; P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -1072,20 +1077,15 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); + B0vec.y = Bpxy / hthe; B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() - * tokamak_coordinates.Bpxy() - / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() - * tokamak_coordinates.Bxy()) - * Dphi0; + V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) - / tokamak_coordinates.Bxy(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1108,9 +1108,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() - / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates.Bxy()) / tokamak_coordinates.Bxy(); + beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); + gradparB = Grad_par(B0) / B0; output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1143,10 +1142,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy(); + phi0 = -0.5 * dnorm * P0 / B0; } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy() / N0; + phi0 = -0.5 * dnorm * P0 / B0 / N0; } SAVE_ONCE(phi0); } else { @@ -1157,8 +1156,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - Field2D Bxy = tokamak_coordinates.Bxy(); - SAVE_ONCE(Va, Bxy); + SAVE_ONCE(Va, B0); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { @@ -1190,7 +1188,7 @@ class ELMpb : public PhysicsModel { } // if(diamag) { - // phi -= 0.5*dnorm * P / metric->Bxy(); + // phi -= 0.5*dnorm * P / B0; //} } @@ -1232,7 +1230,7 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); - const auto& B0 = mesh->getCoordinates()->Bxy(); + auto B0 = tokamak_coordinates.Bxy(); if (nonlinear) { result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; @@ -1253,6 +1251,8 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); + auto B0 = tokamak_coordinates.Bxy(); + //////////////////////////////////////////// // Transitions from 0 in core to 1 in vacuum if (nonlinear) { @@ -1374,12 +1374,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / metric->Bxy(); + phi -= 0.5 * dnorm * P / B0; } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * metric->Bxy()) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1530,8 +1530,7 @@ class ELMpb : public PhysicsModel { auto P0_acc = Field2DAccessor<>(P0); auto J0_acc = Field2DAccessor<>(J0); auto phi0_acc = Field2DAccessor<>(phi0); - Field2D Bxy = tokamak_coordinates.Bxy(); - auto B0_acc = Field2DAccessor<>(Bxy); + auto B0_acc = Field2DAccessor<>(B0); // Evolving fields auto P_acc = FieldAccessor<>(P); @@ -1548,17 +1547,17 @@ class ELMpb : public PhysicsModel { #endif #if EVOLVE_JPAR - Field3D B0U = metric->Bxy() * U; + Field3D B0U = B0 * U; mesh->communicate(B0U); auto B0U_acc = FieldAccessor<>(B0U); #else - Field3D B0phi = metric->Bxy() * phi; + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); auto B0phi_acc = FieldAccessor<>(B0phi); #if EHALL - Field3D B0P = metric->Bxy() * P; - mesh->communicate(metric->Bxy() * P); + Field3D B0P = B0 * P; + mesh->communicate(B0 * P); auto B0P_acc = FieldAccessor<>(B0P); #endif // EHALL #endif // EVOLVE_JPAR @@ -1681,7 +1680,7 @@ class ELMpb : public PhysicsModel { } // if (diamag_grad_t) { // grad_par(T_e) correction - // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / metric->Bxy(); + // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; // } // if (hyperresist > 0.0) { // Hyper-resistivity @@ -1718,16 +1717,16 @@ class ELMpb : public PhysicsModel { // Vorticity equation // Grad j term - // ddt(U) = SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); + // ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); // if (include_rmp) { - // ddt(U) += SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + // ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); // } ddt(U) += b0xcv * Grad(P); // curvature term // if (!nogradparj) { // Parallel current term - // ddt(U) -= SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + // ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j // } if (withflow && K_H_term) { // K_H_term @@ -1743,7 +1742,7 @@ class ELMpb : public PhysicsModel { } // if (nonlinear) { // Advection - // ddt(U) -= bracket(phi, U, bm_exb) * metric->Bxy(); + // ddt(U) -= bracket(phi, U, bm_exb) * B0; // } // Viscosity terms @@ -1787,11 +1786,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(metric->Bxy() * phi0)); + Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(metric->Bxy() * phi); + Dperp2Phi = Delp2(B0 * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1803,35 +1802,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(metric->Bxy() * phi0, Pi, bm_exb); + bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(metric->Bxy() * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / metric->Bxy(); - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / metric->Bxy(); - Field3D B0phi = metric->Bxy() * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); - Field3D B0phi0 = metric->Bxy() * phi0; + Field3D B0phi0 = B0 * phi0; mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / metric->Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / metric->Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / metric->Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / metric->Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; if (nonlinear) { - Field3D B0phi = metric->Bxy() * phi; + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / metric->Bxy(); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / metric->Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / metric->Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; } } @@ -1861,7 +1860,7 @@ class ELMpb : public PhysicsModel { } // if (nonlinear) { // Advection - // ddt(P) -= bracket(phi, P, bm_exb) * metric->Bxy(); + // ddt(P) -= bracket(phi, P, bm_exb) * B0; // } // Parallel diffusion terms @@ -1908,8 +1907,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= - bracket(interp_to(phi, loc), Vpar, bm_exb) * metric->Bxy(); // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection } } @@ -1998,11 +1996,11 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); - Coordinates* metric = mesh->getCoordinates(); - Field3D U1 = ddt(U); - U1 += (gamma * metric->Bxy() * metric->Bxy()) * Grad_par(Jrhs, CELL_CENTRE) - + (gamma * b0xcv) * Grad(P); + + auto B0 = tokamak_coordinates.Bxy(); + + U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -2011,7 +2009,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * metric->Bxy() * metric->Bxy()); + invU->setCoefB(-SQ(gamma) * B0 * B0); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -2019,9 +2017,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = metric->Bxy() * phi3; + Field3D B0phi3 = B0 * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / metric->Bxy(); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; ddt(Psi).applyBoundary(); return 0; @@ -2050,19 +2048,20 @@ class ELMpb : public PhysicsModel { mesh->communicate(phi, Jpar); - Coordinates* metric = mesh->getCoordinates(); - Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = metric->Bxy() * phi; + + auto B0 = tokamak_coordinates.Bxy(); + + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / metric->Bxy(); + Field3D JPsi = -Grad_par(B0phi, loc) / B0; JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(metric->Bxy()) * Grad_par(Jpar, CELL_CENTRE) - + SQ(metric->Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) + + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index c81b4a5367..04cb5316f4 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -1016,20 +1016,22 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); + + auto Bpxy = tokamak_coordinates.Bpxy(); + auto hthe = tokamak_coordinates.hthe(); + auto Rxy = tokamak_coordinates.Rxy(); + auto Btxy = tokamak_coordinates.Btxy(); + auto B0 = tokamak_coordinates.Bxy(); + + B0vec.y = Bpxy / hthe; B0vec.z = 0.; V0net.covariant = false; // presentation for net flow V0net.x = 0.; - V0net.y = tokamak_coordinates.Rxy() * tokamak_coordinates.Btxy() - * tokamak_coordinates.Bpxy() - / (tokamak_coordinates.hthe() * tokamak_coordinates.Bxy() - * tokamak_coordinates.Bxy()) - * Dphi0; + V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; V0net.z = -Dphi0; - U0 = B0vec * Curl(V0net) - / tokamak_coordinates.Bxy(); // get 0th vorticity for Kelvin-Holmholtz term + U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term /**************** SET EVOLVING VARIABLES *************/ @@ -1052,9 +1054,8 @@ class ELMpb : public PhysicsModel { SOLVE_FOR(Vpar); comms.add(Vpar); - beta = tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() - / (0.5 + (tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy() / (g * P0))); - gradparB = Grad_par(tokamak_coordinates.Bxy()) / tokamak_coordinates.Bxy(); + beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); + gradparB = Grad_par(B0) / B0; output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); } else { @@ -1087,10 +1088,10 @@ class ELMpb : public PhysicsModel { // Diamagnetic phi0 if (diamag_phi0) { if (constn0) { - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy(); + phi0 = -0.5 * dnorm * P0 / B0; } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / tokamak_coordinates.Bxy() / N0; + phi0 = -0.5 * dnorm * P0 / B0 / N0; } SAVE_ONCE(phi0); } @@ -1099,8 +1100,7 @@ class ELMpb : public PhysicsModel { // everything needed to recover physical units SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); - Field2D tmp = tokamak_coordinates.Bxy(); - SAVE_ONCE(Va, tmp); + SAVE_ONCE(Va, B0); SAVE_ONCE(Dphi0, U0); SAVE_ONCE(V0); if (!constn0) { @@ -1166,12 +1166,13 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); + auto B0 = tokamak_coordinates.Bxy(); + if (nonlinear) { - const auto Bxy = tokamak_coordinates.Bxy(); - result -= bracket(interp_to(Psi, loc), f, bm_mag) * Bxy; + result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * Bxy; + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; } } @@ -1186,6 +1187,8 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); + auto B0 = tokamak_coordinates.Bxy(); + //////////////////////////////////////////// // Transitions from 0 in core to 1 in vacuum if (nonlinear) { @@ -1307,12 +1310,12 @@ class ELMpb : public PhysicsModel { } if (diamag) { - phi -= 0.5 * dnorm * P / tokamak_coordinates.Bxy(); + phi -= 0.5 * dnorm * P / B0; } } else { ubyn = U / N0; if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * tokamak_coordinates.Bxy()) * Delp2(P); + ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); mesh->communicate(ubyn); } // Invert laplacian for phi @@ -1457,9 +1460,9 @@ class ELMpb : public PhysicsModel { if (evolve_jpar) { // Jpar - Field3D B0U = tokamak_coordinates.Bxy() * U; + Field3D B0U = B0 * U; mesh->communicate(B0U); - ddt(Jpar) = -Grad_parP(B0U, loc) / tokamak_coordinates.Bxy() + eta * Delp2(Jpar); + ddt(Jpar) = -Grad_parP(B0U, loc) / B0 + eta * Delp2(Jpar); if (relax_j_vac) { // Make ddt(Jpar) relax to zero. @@ -1468,20 +1471,16 @@ class ELMpb : public PhysicsModel { } } else { // Vector potential - ddt(Psi) = - -Grad_parP(phi * tokamak_coordinates.Bxy(), loc) / tokamak_coordinates.Bxy() - + eta * Jpar; + ddt(Psi) = -Grad_parP(phi * B0, loc) / B0 + eta * Jpar; if (eHall) { // electron parallel pressure - ddt(Psi) += - 0.25 * delta_i - * (Grad_parP(tokamak_coordinates.Bxy() * P, loc) / tokamak_coordinates.Bxy() - + bracket(interp_to(P0, loc), Psi, bm_mag) * tokamak_coordinates.Bxy()); + ddt(Psi) += 0.25 * delta_i + * (Grad_parP(B0 * P, loc) / B0 + + bracket(interp_to(P0, loc), Psi, bm_mag) * B0); } if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= - bracket(interp_to(phi0, loc), Psi, bm_exb) * tokamak_coordinates.Bxy(); + ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * B0; } if (withflow) { // net flow @@ -1489,7 +1488,7 @@ class ELMpb : public PhysicsModel { } if (diamag_grad_t) { // grad_par(T_e) correction - ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / tokamak_coordinates.Bxy(); + ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; } if (hyperresist > 0.0) { // Hyper-resistivity @@ -1527,17 +1526,15 @@ class ELMpb : public PhysicsModel { Psi_loc = interp_to(Psi, CELL_CENTRE, "RGN_ALL"); Psi_loc.applyBoundary(); // Grad j term - ddt(U) = SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); + ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); if (include_rmp) { - ddt(U) += - SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); } ddt(U) += b0xcv * Grad(P); // curvature term if (!nogradparj) { // Parallel current term - ddt(U) -= - SQ(tokamak_coordinates.Bxy()) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j } if (withflow && K_H_term) { // K_H_term @@ -1553,7 +1550,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(U) -= bracket(phi, U, bm_exb) * tokamak_coordinates.Bxy(); + ddt(U) -= bracket(phi, U, bm_exb) * B0; } // Viscosity terms @@ -1597,11 +1594,11 @@ class ELMpb : public PhysicsModel { Pi = 0.5 * P; Pi0 = 0.5 * P0; - Dperp2Phi0 = Field3D(Delp2(tokamak_coordinates.Bxy() * phi0)); + Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); Dperp2Phi0.applyBoundary(); mesh->communicate(Dperp2Phi0); - Dperp2Phi = Delp2(tokamak_coordinates.Bxy() * phi); + Dperp2Phi = Delp2(B0 * phi); Dperp2Phi.applyBoundary(); mesh->communicate(Dperp2Phi); @@ -1613,41 +1610,35 @@ class ELMpb : public PhysicsModel { Dperp2Pi.applyBoundary(); mesh->communicate(Dperp2Pi); - bracketPhi0P = bracket(tokamak_coordinates.Bxy() * phi0, Pi, bm_exb); + bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); bracketPhi0P.applyBoundary(); mesh->communicate(bracketPhi0P); - bracketPhiP0 = bracket(tokamak_coordinates.Bxy() * phi, Pi0, bm_exb); + bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); bracketPhiP0.applyBoundary(); mesh->communicate(bracketPhiP0); - ddt(U) -= - 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) -= - 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); - Field3D B0phi = tokamak_coordinates.Bxy() * phi; + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); - Field3D B0phi0 = tokamak_coordinates.Bxy() * phi0; + Field3D B0phi0 = B0 * phi0; mesh->communicate(B0phi0); - ddt(U) += - 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) += - 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / tokamak_coordinates.Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / tokamak_coordinates.Bxy(); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; if (nonlinear) { - Field3D B0phi = tokamak_coordinates.Bxy() * phi; + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); bracketPhiP = bracket(B0phi, Pi, bm_exb); bracketPhiP.applyBoundary(); mesh->communicate(bracketPhiP); - ddt(U) -= - 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) += - 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / tokamak_coordinates.Bxy(); - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / tokamak_coordinates.Bxy(); + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; } } @@ -1677,7 +1668,7 @@ class ELMpb : public PhysicsModel { } if (nonlinear) { // Advection - ddt(P) -= bracket(phi, P, bm_exb) * tokamak_coordinates.Bxy(); + ddt(P) -= bracket(phi, P, bm_exb) * B0; } } @@ -1722,8 +1713,7 @@ class ELMpb : public PhysicsModel { ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) - * tokamak_coordinates.Bxy(); // Advection + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection } } @@ -1814,9 +1804,10 @@ class ELMpb : public PhysicsModel { mesh->communicate(Jrhs, ddt(P)); Field3D U1 = ddt(U); - U1 += (gamma * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()) - * Grad_par(Jrhs, CELL_CENTRE) - + (gamma * b0xcv) * Grad(P); + + auto B0 = tokamak_coordinates.Bxy(); + + U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); // Second matrix, solving Alfven wave dynamics static std::unique_ptr invU{nullptr}; @@ -1825,7 +1816,7 @@ class ELMpb : public PhysicsModel { } invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * tokamak_coordinates.Bxy() * tokamak_coordinates.Bxy()); + invU->setCoefB(-SQ(gamma) * B0 * B0); ddt(U) = invU->solve(U1); ddt(U).applyBoundary(); @@ -1833,9 +1824,9 @@ class ELMpb : public PhysicsModel { Field3D phi3 = phiSolver->solve(ddt(U)); mesh->communicate(phi3); phi3.applyBoundary("neumann"); - Field3D B0phi3 = tokamak_coordinates.Bxy() * phi3; + Field3D B0phi3 = B0 * phi3; mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / tokamak_coordinates.Bxy(); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; ddt(Psi).applyBoundary(); return 0; @@ -1867,15 +1858,17 @@ class ELMpb : public PhysicsModel { Field3D JP = -b0xGrad_dot_Grad(phi, P0); JP.setBoundary("P"); JP.applyBoundary(); - Field3D B0phi = tokamak_coordinates.Bxy() * phi; + + auto B0 = tokamak_coordinates.Bxy(); + + Field3D B0phi = B0 * phi; mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / tokamak_coordinates.Bxy(); + Field3D JPsi = -Grad_par(B0phi, loc) / B0; JPsi.setBoundary("Psi"); JPsi.applyBoundary(); - Field3D JU = - b0xcv * Grad(ddt(P)) - SQ(tokamak_coordinates.Bxy()) * Grad_par(Jpar, CELL_CENTRE) - + SQ(tokamak_coordinates.Bxy()) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) + + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); JU.setBoundary("U"); JU.applyBoundary(); From 89bc5894d272319fc0e791ea2bb73ab1b9e78290 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 13 Jan 2025 13:36:03 +0000 Subject: [PATCH 85/98] Fix: Add new parameters Lbar and Bbar to make_coordinates method call --- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 485e321eb6..09f168f4de 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -15,7 +15,7 @@ int main(int argc, char** argv) { calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coord = tokamak_coordinates.make_coordinates(true); + const auto& coord = tokamak_coordinates.make_coordinates(true, 1.0, 1.0); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index efc3977084..af7295b1f3 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -18,7 +18,7 @@ class WaveTest : public PhysicsModel { int init(bool UNUSED(restarting)) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coords = tokamak_coordinates.make_coordinates(true); + const auto& coords = tokamak_coordinates.make_coordinates(true, 1.0, 1.0); solver->add(f, "f"); solver->add(g, "g"); From 1b192b2a6fdbcb323ae61814c25b291108daaa72 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 13 Jan 2025 13:36:47 +0000 Subject: [PATCH 86/98] const qualifier in parameter declaration has no effect --- include/bout/tokamak_coordinates.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 151618a5d8..d07cc4bbb8 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -29,7 +29,7 @@ private: public: TokamakCoordinates(Mesh& mesh); - Coordinates* make_coordinates(const bool noshear, BoutReal Lbar, BoutReal Bbar, + Coordinates* make_coordinates(bool noshear, BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor = 1.0); const Field2D& Rxy() const { return Rxy_m; } From 60940af827160599199e1ba66253af5751b1d5af Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 13 Jan 2025 16:25:31 +0000 Subject: [PATCH 87/98] Fix "Copy values to local variables" --- examples/6field-simple/elm_6f.cxx | 31 ++++++++++++++----------------- examples/elm-pb/elm_pb.cxx | 17 ++++++++--------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 7d98b52562..80a614838b 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -832,7 +832,13 @@ class Elm_6f : public PhysicsModel { dump.add(sp_length, "sp_length", 1); } - J0 = SI::mu0 * Lbar * J0 / tokamak_coordinates.Bxy(); + auto Bpxy = tokamak_coordinates.Bpxy(); + auto hthe = tokamak_coordinates.hthe(); + auto Rxy = tokamak_coordinates.Rxy(); + auto Btxy = tokamak_coordinates.Btxy(); + auto B0 = tokamak_coordinates.Bxy(); + + J0 = SI::mu0 * Lbar * J0 / B0; P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); b0xcv.x /= Bbar; @@ -904,9 +910,7 @@ class Elm_6f : public PhysicsModel { q95 = q95_input; // use a constant for test } else { if (local_q) { - q95 = abs(tokamak_coordinates.hthe() * tokamak_coordinates.Btxy() - / tokamak_coordinates.Bpxy()) - * q_alpha; + q95 = abs(hthe * Btxy / (Bpxy)) * q_alpha; } else { output.write("\tUsing q profile from grid.\n"); if (mesh->get(q95, "q")) { @@ -1042,12 +1046,6 @@ class Elm_6f : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - auto Bpxy = tokamak_coordinates.Bpxy(); - auto hthe = tokamak_coordinates.hthe(); - auto Rxy = tokamak_coordinates.Rxy(); - auto Btxy = tokamak_coordinates.Btxy(); - auto B0 = tokamak_coordinates.Bxy(); - B0vec.y = Bpxy / hthe; B0vec.z = 0.; @@ -1105,10 +1103,10 @@ class Elm_6f : public PhysicsModel { if (diamag && diamag_phi0) { if (experiment_Er) { // get phi0 from grid file mesh->get(phi0, "Phi_0"); - phi0 /= tokamak_coordinates.Bxy() * Lbar * Va; + phi0 /= B0 * Lbar * Va; } else { // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -Upara0 * Pi0 / tokamak_coordinates.Bxy() / N0; + phi0 = -Upara0 * Pi0 / B0 / N0; } SAVE_ONCE(phi0); } @@ -1118,8 +1116,7 @@ class Elm_6f : public PhysicsModel { SAVE_ONCE(J0, P0); SAVE_ONCE(density, Lbar, Bbar, Tbar); SAVE_ONCE(Tibar, Tebar, Nbar); - Field2D tmp = tokamak_coordinates.Bxy(); - SAVE_ONCE(Va, tmp); + SAVE_ONCE(Va, B0); SAVE_ONCE(Ti0, Te0, N0); // Create a solver for the Laplacian @@ -1142,13 +1139,13 @@ class Elm_6f : public PhysicsModel { Field2D logn0 = laplace_alpha * N0; Field3D Ntemp; Ntemp = N0; - ubyn = U * tokamak_coordinates.Bxy() / Ntemp; + ubyn = U * B0 / Ntemp; // Phi should be consistent with U if (laplace_alpha <= 0.0) { - phi = phiSolver->solve(ubyn) / tokamak_coordinates.Bxy(); + phi = phiSolver->solve(ubyn) / B0; } else { phiSolver->setCoefC(logn0); - phi = phiSolver->solve(ubyn) / tokamak_coordinates.Bxy(); + phi = phiSolver->solve(ubyn) / B0; } } diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 04cb5316f4..b380042235 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -645,8 +645,13 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - V0 = -tokamak_coordinates.Rxy() * tokamak_coordinates.Bpxy() * Dphi0 - / tokamak_coordinates.Bxy(); + auto Bpxy = tokamak_coordinates.Bpxy(); + auto hthe = tokamak_coordinates.hthe(); + auto Rxy = tokamak_coordinates.Rxy(); + auto Btxy = tokamak_coordinates.Btxy(); + auto B0 = tokamak_coordinates.Bxy(); + + V0 = -Rxy * Bpxy * Dphi0 / B0; if (simple_rmp) { include_rmp = true; @@ -868,7 +873,7 @@ class ELMpb : public PhysicsModel { Field2D Te; Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / tokamak_coordinates.Bxy(); + J0 = -MU0 * Lbar * J0 / B0; P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); V0 = V0 / Va; Dphi0 *= Tbar; @@ -1017,12 +1022,6 @@ class ELMpb : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - auto Bpxy = tokamak_coordinates.Bpxy(); - auto hthe = tokamak_coordinates.hthe(); - auto Rxy = tokamak_coordinates.Rxy(); - auto Btxy = tokamak_coordinates.Btxy(); - auto B0 = tokamak_coordinates.Bxy(); - B0vec.y = Bpxy / hthe; B0vec.z = 0.; From 07b8e14525b56d2592b71cb522dbe5a8c7641927 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 14 Jan 2025 11:48:10 +0000 Subject: [PATCH 88/98] Make TokamakCoordinates a struct rather than a class and its methods free functions. --- CMakeLists.txt | 1 - examples/6field-simple/elm_6f.cxx | 20 +- examples/conducting-wall-mode/cwm.cxx | 8 +- examples/dalf3/dalf3.cxx | 2 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 24 +- examples/elm-pb/elm_pb.cxx | 1106 ++++++++--------- examples/gyro-gem/gem.cxx | 4 +- include/bout/tokamak_coordinates.hxx | 104 +- src/mesh/tokamak_coordinates.cxx | 68 - .../test-drift-instability/2fluid.cxx | 2 +- .../test-interchange-instability/2fluid.cxx | 2 +- 11 files changed, 660 insertions(+), 681 deletions(-) delete mode 100644 src/mesh/tokamak_coordinates.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d431d2dcc..c561e91fa5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,7 +361,6 @@ set(BOUT_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx ./include/bout/tokamak_coordinates.hxx - ./src/mesh/tokamak_coordinates.cxx ) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 80a614838b..dc67d54958 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -366,7 +366,7 @@ class Elm_6f : public PhysicsModel { result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * tokamak_coordinates.Bxy(); + result -= bracket(Psi, f, bm_mag) * tokamak_coordinates.Bxy; } } @@ -678,7 +678,7 @@ class Elm_6f : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; } } @@ -688,7 +688,7 @@ class Elm_6f : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; } } @@ -832,11 +832,11 @@ class Elm_6f : public PhysicsModel { dump.add(sp_length, "sp_length", 1); } - auto Bpxy = tokamak_coordinates.Bpxy(); - auto hthe = tokamak_coordinates.hthe(); - auto Rxy = tokamak_coordinates.Rxy(); - auto Btxy = tokamak_coordinates.Btxy(); - auto B0 = tokamak_coordinates.Bxy(); + auto Bpxy = tokamak_coordinates.Bpxy; + auto hthe = tokamak_coordinates.hthe; + auto Rxy = tokamak_coordinates.Rxy; + auto Btxy = tokamak_coordinates.Btxy; + auto B0 = tokamak_coordinates.Bxy; J0 = SI::mu0 * Lbar * J0 / B0; P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); @@ -1038,7 +1038,7 @@ class Elm_6f : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); + coord->setIntShiftTorsion(tokamak_coordinates.ShearFactor); } // Set B field vector @@ -1221,7 +1221,7 @@ class Elm_6f : public PhysicsModel { // Field2D lap_temp=0.0; Field2D logn0 = laplace_alpha * N0; - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; ubyn = U * B0 / N0; if (diamag) { diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index ee434e300d..44223851d7 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -140,10 +140,10 @@ class CWM : public PhysicsModel { // add evolving variables to the communication object SOLVE_FOR(rho, te); - Field2D Rxy = tokamak_coordinates.Rxy(); - Field2D Bpxy = tokamak_coordinates.Bpxy(); - Field2D Btxy = tokamak_coordinates.Btxy(); - Field2D hthe = tokamak_coordinates.hthe(); + Field2D Rxy = tokamak_coordinates.Rxy; + Field2D Bpxy = tokamak_coordinates.Bpxy; + Field2D Btxy = tokamak_coordinates.Btxy; + Field2D hthe = tokamak_coordinates.hthe; SAVE_ONCE(Rxy, Bpxy, Btxy, Zxy, hthe); SAVE_ONCE(nu_hat, hthe0); diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 700de90ad8..594b01e236 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -162,7 +162,7 @@ class DALF3 : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; noshear = true; } diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 6f4dbb8b10..cfe3cbbbc6 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -718,11 +718,11 @@ class ELMpb : public PhysicsModel { } const auto& metric = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); - auto Bpxy = tokamak_coordinates.Bpxy(); - auto hthe = tokamak_coordinates.hthe(); - auto Rxy = tokamak_coordinates.Rxy(); - auto Btxy = tokamak_coordinates.Btxy(); - auto B0 = tokamak_coordinates.Bxy(); + auto Bpxy = tokamak_coordinates.Bpxy; + auto hthe = tokamak_coordinates.hthe; + auto Rxy = tokamak_coordinates.Rxy; + auto Btxy = tokamak_coordinates.Btxy; + auto B0 = tokamak_coordinates.Bxy; V0 = -Rxy * Bpxy * Dphi0 / B0; @@ -819,7 +819,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; } } @@ -829,7 +829,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; } } @@ -1215,7 +1215,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); + metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor); } return 0; @@ -1230,7 +1230,7 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; if (nonlinear) { result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; @@ -1251,7 +1251,7 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; //////////////////////////////////////////// // Transitions from 0 in core to 1 in vacuum @@ -1998,7 +1998,7 @@ class ELMpb : public PhysicsModel { Field3D U1 = ddt(U); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); @@ -2052,7 +2052,7 @@ class ELMpb : public PhysicsModel { JP.setBoundary("P"); JP.applyBoundary(); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; Field3D B0phi = B0 * phi; mesh->communicate(B0phi); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index b380042235..48adcfaefc 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -506,655 +506,655 @@ class ELMpb : public PhysicsModel { laplacexy->setCoefs(1.0, 0.0); phi2D = 0.0; // Starting guess phi2D.setBoundary("phi"); - } - - // Radial smoothing - smooth_j_x = options["smooth_j_x"].doc("Smooth Jpar in x").withDefault(false); - - // Jpar boundary region - jpar_bndry_width = options["jpar_bndry_width"] - .doc("Number of cells near the boundary where jpar = 0") - .withDefault(-1); - - sheath_boundaries = options["sheath_boundaries"] - .doc("Apply sheath boundaries in Y?") - .withDefault(false); - - // Parallel differencing - parallel_lr_diff = - options["parallel_lr_diff"] - .doc("Use left and right shifted stencils for parallel differences?") - .withDefault(false); + } - // RMP-related options - include_rmp = options["include_rmp"] - .doc("Read RMP field rmp_A from grid?") - .withDefault(false); + // Radial smoothing + smooth_j_x = options["smooth_j_x"].doc("Smooth Jpar in x").withDefault(false); - simple_rmp = - options["simple_rmp"].doc("Include a simple RMP model?").withDefault(false); - rmp_factor = options["rmp_factor"].withDefault(1.0); - rmp_ramp = options["rmp_ramp"].withDefault(-1.0); - rmp_freq = options["rmp_freq"].withDefault(-1.0); - rmp_rotate = options["rmp_rotate"].withDefault(0.0); - - // Vacuum region control - vacuum_pressure = - options["vacuum_pressure"] - .doc("Fraction of peak pressure, below which is considered vacuum.") - .withDefault(0.02); - vacuum_trans = - options["vacuum_trans"] - .doc("Vacuum boundary transition width, as fraction of peak pressure.") - .withDefault(0.005); - - // Resistivity and hyper-resistivity options - vac_lund = - options["vac_lund"].doc("Lundquist number in vacuum region").withDefault(0.0); - core_lund = - options["core_lund"].doc("Lundquist number in core region").withDefault(0.0); - hyperresist = options["hyperresist"].withDefault(-1.0); - ehyperviscos = options["ehyperviscos"].withDefault(-1.0); - spitzer_resist = options["spitzer_resist"] - .doc("Use Spitzer resistivity?") - .withDefault(false); - Zeff = options["Zeff"].withDefault(2.0); // Z effective - - // Inner boundary damping - damp_width = options["damp_width"] - .doc("Width of the radial damping regions, in grid cells") - .withDefault(0); - damp_t_const = - options["damp_t_const"] - .doc("Time constant for damping in radial regions. Normalised time units.") - .withDefault(0.1); - - // Viscosity and hyper-viscosity - viscos_par = options["viscos_par"].doc("Parallel viscosity").withDefault(-1.0); - viscos_perp = options["viscos_perp"].doc("Perpendicular viscosity").withDefault(-1.0); - hyperviscos = options["hyperviscos"].doc("Radial hyperviscosity").withDefault(-1.0); - - diffusion_par = - options["diffusion_par"].doc("Parallel pressure diffusion").withDefault(-1.0); - diffusion_p4 = options["diffusion_p4"] - .doc("parallel hyper-viscous diffusion for pressure") - .withDefault(-1.0); - diffusion_u4 = options["diffusion_u4"] - .doc("parallel hyper-viscous diffusion for vorticity") - .withDefault(-1.0); - diffusion_a4 = options["diffusion_a4"] - .doc("parallel hyper-viscous diffusion for vector potential") - .withDefault(-1.0); - - // heating factor in pressure - // heating power in pressure - heating_P = options["heating_P"].withDefault(-1.0); - // the percentage of radial grid points for heating profile radial - // width in pressure - hp_width = options["hp_width"].withDefault(0.1); - // the percentage of radial grid points for heating profile radial - // domain in pressure - hp_length = options["hp_length"].withDefault(0.04); - - // sink factor in pressure - // sink in pressure - sink_P = options["sink_P"].withDefault(-1.0); - // the percentage of radial grid points for sink profile radial - // width in pressure - sp_width = options["sp_width"].withDefault(0.05); - // the percentage of radial grid points for sink profile radial - // domain in pressure - sp_length = options["sp_length"].withDefault(0.04); - - // left edge sink factor in vorticity - // left edge sink in vorticity - sink_Ul = options["sink_Ul"].withDefault(-1.0); - // the percentage of left edge radial grid points for sink profile - // radial width in vorticity - su_widthl = options["su_widthl"].withDefault(0.06); - // the percentage of left edge radial grid points for sink profile - // radial domain in vorticity - su_lengthl = options["su_lengthl"].withDefault(0.15); - - // right edge sink factor in vorticity - // right edge sink in vorticity - sink_Ur = options["sink_Ur"].withDefault(-1.0); - // the percentage of right edge radial grid points for sink profile - // radial width in vorticity - su_widthr = options["su_widthr"].withDefault(0.06); - // the percentage of right edge radial grid points for sink profile - // radial domain in vorticity - su_lengthr = options["su_lengthr"].withDefault(0.15); - - // Compressional terms - phi_curv = - options["phi_curv"].doc("ExB compression in P equation?").withDefault(true); - g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); - - x = (Psixy - Psiaxis) / (Psibndry - Psiaxis); - - if (experiment_Er) { // get er from experiment - mesh->get(Dphi0, "Epsi"); - diamag_phi0 = false; - K_H_term = false; - } else { - Dphi0 = -D_min - 0.5 * D_0 * (1.0 - tanh(D_s * (x - x0))); - } + // Jpar boundary region + jpar_bndry_width = options["jpar_bndry_width"] + .doc("Number of cells near the boundary where jpar = 0") + .withDefault(-1); - if (sign < 0) { // change flow direction - Dphi0 *= -1; - } + sheath_boundaries = options["sheath_boundaries"] + .doc("Apply sheath boundaries in Y?") + .withDefault(false); - auto Bpxy = tokamak_coordinates.Bpxy(); - auto hthe = tokamak_coordinates.hthe(); - auto Rxy = tokamak_coordinates.Rxy(); - auto Btxy = tokamak_coordinates.Btxy(); - auto B0 = tokamak_coordinates.Bxy(); + // Parallel differencing + parallel_lr_diff = + options["parallel_lr_diff"] + .doc("Use left and right shifted stencils for parallel differences?") + .withDefault(false); + + // RMP-related options + include_rmp = options["include_rmp"] + .doc("Read RMP field rmp_A from grid?") + .withDefault(false); + + simple_rmp = + options["simple_rmp"].doc("Include a simple RMP model?").withDefault(false); + rmp_factor = options["rmp_factor"].withDefault(1.0); + rmp_ramp = options["rmp_ramp"].withDefault(-1.0); + rmp_freq = options["rmp_freq"].withDefault(-1.0); + rmp_rotate = options["rmp_rotate"].withDefault(0.0); + + // Vacuum region control + vacuum_pressure = + options["vacuum_pressure"] + .doc("Fraction of peak pressure, below which is considered vacuum.") + .withDefault(0.02); + vacuum_trans = + options["vacuum_trans"] + .doc("Vacuum boundary transition width, as fraction of peak pressure.") + .withDefault(0.005); + + // Resistivity and hyper-resistivity options + vac_lund = + options["vac_lund"].doc("Lundquist number in vacuum region").withDefault(0.0); + core_lund = + options["core_lund"].doc("Lundquist number in core region").withDefault(0.0); + hyperresist = options["hyperresist"].withDefault(-1.0); + ehyperviscos = options["ehyperviscos"].withDefault(-1.0); + spitzer_resist = options["spitzer_resist"] + .doc("Use Spitzer resistivity?") + .withDefault(false); + Zeff = options["Zeff"].withDefault(2.0); // Z effective + + // Inner boundary damping + damp_width = options["damp_width"] + .doc("Width of the radial damping regions, in grid cells") + .withDefault(0); + damp_t_const = + options["damp_t_const"] + .doc("Time constant for damping in radial regions. Normalised time units.") + .withDefault(0.1); + + // Viscosity and hyper-viscosity + viscos_par = options["viscos_par"].doc("Parallel viscosity").withDefault(-1.0); + viscos_perp = options["viscos_perp"].doc("Perpendicular viscosity").withDefault(-1.0); + hyperviscos = options["hyperviscos"].doc("Radial hyperviscosity").withDefault(-1.0); + + diffusion_par = + options["diffusion_par"].doc("Parallel pressure diffusion").withDefault(-1.0); + diffusion_p4 = options["diffusion_p4"] + .doc("parallel hyper-viscous diffusion for pressure") + .withDefault(-1.0); + diffusion_u4 = options["diffusion_u4"] + .doc("parallel hyper-viscous diffusion for vorticity") + .withDefault(-1.0); + diffusion_a4 = options["diffusion_a4"] + .doc("parallel hyper-viscous diffusion for vector potential") + .withDefault(-1.0); + + // heating factor in pressure + // heating power in pressure + heating_P = options["heating_P"].withDefault(-1.0); + // the percentage of radial grid points for heating profile radial + // width in pressure + hp_width = options["hp_width"].withDefault(0.1); + // the percentage of radial grid points for heating profile radial + // domain in pressure + hp_length = options["hp_length"].withDefault(0.04); + + // sink factor in pressure + // sink in pressure + sink_P = options["sink_P"].withDefault(-1.0); + // the percentage of radial grid points for sink profile radial + // width in pressure + sp_width = options["sp_width"].withDefault(0.05); + // the percentage of radial grid points for sink profile radial + // domain in pressure + sp_length = options["sp_length"].withDefault(0.04); + + // left edge sink factor in vorticity + // left edge sink in vorticity + sink_Ul = options["sink_Ul"].withDefault(-1.0); + // the percentage of left edge radial grid points for sink profile + // radial width in vorticity + su_widthl = options["su_widthl"].withDefault(0.06); + // the percentage of left edge radial grid points for sink profile + // radial domain in vorticity + su_lengthl = options["su_lengthl"].withDefault(0.15); + + // right edge sink factor in vorticity + // right edge sink in vorticity + sink_Ur = options["sink_Ur"].withDefault(-1.0); + // the percentage of right edge radial grid points for sink profile + // radial width in vorticity + su_widthr = options["su_widthr"].withDefault(0.06); + // the percentage of right edge radial grid points for sink profile + // radial domain in vorticity + su_lengthr = options["su_lengthr"].withDefault(0.15); + + // Compressional terms + phi_curv = + options["phi_curv"].doc("ExB compression in P equation?").withDefault(true); + g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); + + x = (Psixy - Psiaxis) / (Psibndry - Psiaxis); + + if (experiment_Er) { // get er from experiment + mesh->get(Dphi0, "Epsi"); + diamag_phi0 = false; + K_H_term = false; + } else { + Dphi0 = -D_min - 0.5 * D_0 * (1.0 - tanh(D_s * (x - x0))); + } - V0 = -Rxy * Bpxy * Dphi0 / B0; + if (sign < 0) { // change flow direction + Dphi0 *= -1; + } - if (simple_rmp) { - include_rmp = true; - } + auto Bpxy = tokamak_coordinates.Bpxy; + auto hthe = tokamak_coordinates.hthe; + auto Rxy = tokamak_coordinates.Rxy; + auto Btxy = tokamak_coordinates.Btxy; + auto B0 = tokamak_coordinates.Bxy; - // toroidal and poloidal mode numbers - const int rmp_n = - options["rmp_n"].doc("Simple RMP toroidal mode number").withDefault(3); - const int rmp_m = - options["rmp_m"].doc("Simple RMP poloidal mode number").withDefault(9); - const int rmp_polwid = options["rmp_polwid"] - .doc("Poloidal width (-ve -> full, fraction of 2pi)") - .withDefault(-1.0); - const int rmp_polpeak = options["rmp_polpeak"] - .doc("Peak poloidal location (fraction of 2pi)") - .withDefault(0.5); - rmp_vac_mask = - options["rmp_vac_mask"].doc("Should a vacuum mask be applied?").withDefault(true); - // Divide n by the size of the domain - const int zperiod = globalOptions["zperiod"].withDefault(1); + V0 = -Rxy * Bpxy * Dphi0 / B0; - if (include_rmp) { - // Including external field coils. - if (simple_rmp) { - // Use a fairly simple form for the perturbation - Field2D pol_angle; - if (mesh->get(pol_angle, "pol_angle")) { - output_warn.write(" ***WARNING: need poloidal angle for simple RMP\n"); - include_rmp = false; - } else { - if ((rmp_n % zperiod) != 0) { - output_warn.write( - " ***WARNING: rmp_n ({:d}) not a multiple of zperiod ({:d})\n", rmp_n, - zperiod); - } + if (simple_rmp) { + include_rmp = true; + } - output.write("\tMagnetic perturbation: n = {:d}, m = {:d}, magnitude {:e} Tm\n", - rmp_n, rmp_m, rmp_factor); - - rmp_Psi0 = 0.0; - if (mesh->lastX()) { - // Set the outer boundary - for (int jx = mesh->LocalNx - 4; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - - BoutReal angle = - rmp_m * pol_angle(jx, jy) - + rmp_n * ((BoutReal)jz) * mesh->getCoordinates()->dz(jx, jy, jz); - rmp_Psi0(jx, jy, jz) = - (((BoutReal)(jx - 4)) / ((BoutReal)(mesh->LocalNx - 5))) - * rmp_factor * cos(angle); - if (rmp_polwid > 0.0) { - // Multiply by a Gaussian in poloidal angle - BoutReal gx = - ((pol_angle(jx, jy) / (2. * PI)) - rmp_polpeak) / rmp_polwid; - rmp_Psi0(jx, jy, jz) *= exp(-gx * gx); - } + // toroidal and poloidal mode numbers + const int rmp_n = + options["rmp_n"].doc("Simple RMP toroidal mode number").withDefault(3); + const int rmp_m = + options["rmp_m"].doc("Simple RMP poloidal mode number").withDefault(9); + const int rmp_polwid = options["rmp_polwid"] + .doc("Poloidal width (-ve -> full, fraction of 2pi)") + .withDefault(-1.0); + const int rmp_polpeak = options["rmp_polpeak"] + .doc("Peak poloidal location (fraction of 2pi)") + .withDefault(0.5); + rmp_vac_mask = + options["rmp_vac_mask"].doc("Should a vacuum mask be applied?").withDefault(true); + // Divide n by the size of the domain + const int zperiod = globalOptions["zperiod"].withDefault(1); + + if (include_rmp) { + // Including external field coils. + if (simple_rmp) { + // Use a fairly simple form for the perturbation + Field2D pol_angle; + if (mesh->get(pol_angle, "pol_angle")) { + output_warn.write(" ***WARNING: need poloidal angle for simple RMP\n"); + include_rmp = false; + } else { + if ((rmp_n % zperiod) != 0) { + output_warn.write( + " ***WARNING: rmp_n ({:d}) not a multiple of zperiod ({:d})\n", rmp_n, + zperiod); + } + + output.write("\tMagnetic perturbation: n = {:d}, m = {:d}, magnitude {:e} Tm\n", + rmp_n, rmp_m, rmp_factor); + + rmp_Psi0 = 0.0; + if (mesh->lastX()) { + // Set the outer boundary + for (int jx = mesh->LocalNx - 4; jx < mesh->LocalNx; jx++) { + for (int jy = 0; jy < mesh->LocalNy; jy++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { + + BoutReal angle = + rmp_m * pol_angle(jx, jy) + + rmp_n * ((BoutReal) jz) * mesh->getCoordinates()->dz(jx, jy, jz); + rmp_Psi0(jx, jy, jz) = + (((BoutReal) (jx - 4)) / ((BoutReal) (mesh->LocalNx - 5))) + * rmp_factor * cos(angle); + if (rmp_polwid > 0.0) { + // Multiply by a Gaussian in poloidal angle + BoutReal gx = + ((pol_angle(jx, jy) / (2. * PI)) - rmp_polpeak) / rmp_polwid; + rmp_Psi0(jx, jy, jz) *= exp(-gx * gx); + } + } + } + } + } + + // Now have a simple model for Psi due to coils at the outer boundary + // Need to calculate Psi inside the domain, enforcing j = 0 + + Jpar = 0.0; + auto psiLap = std::unique_ptr{Laplacian::create(nullptr, loc)}; + psiLap->setInnerBoundaryFlags(INVERT_AC_GRAD); // Zero gradient inner BC + psiLap->setOuterBoundaryFlags(INVERT_SET); // Set to rmp_Psi0 on outer boundary + rmp_Psi0 = psiLap->solve(Jpar, rmp_Psi0); + mesh->communicate(rmp_Psi0); } - } + } else { + // Load perturbation from grid file. + include_rmp = !mesh->get(rmp_Psi0, "rmp_A"); // Only include if found + if (!include_rmp) { + output_warn.write("WARNING: Couldn't read 'rmp_A' from grid file\n"); + } + // Multiply by factor + rmp_Psi0 *= rmp_factor; } - } - - // Now have a simple model for Psi due to coils at the outer boundary - // Need to calculate Psi inside the domain, enforcing j = 0 + } - Jpar = 0.0; - auto psiLap = std::unique_ptr{Laplacian::create(nullptr, loc)}; - psiLap->setInnerBoundaryFlags(INVERT_AC_GRAD); // Zero gradient inner BC - psiLap->setOuterBoundaryFlags(INVERT_SET); // Set to rmp_Psi0 on outer boundary - rmp_Psi0 = psiLap->solve(Jpar, rmp_Psi0); - mesh->communicate(rmp_Psi0); + if (!include_curvature) { + b0xcv = 0.0; } - } else { - // Load perturbation from grid file. - include_rmp = !mesh->get(rmp_Psi0, "rmp_A"); // Only include if found - if (!include_rmp) { - output_warn.write("WARNING: Couldn't read 'rmp_A' from grid file\n"); + + if (!include_jpar0) { + J0 = 0.0; } - // Multiply by factor - rmp_Psi0 *= rmp_factor; - } - } - if (!include_curvature) { - b0xcv = 0.0; - } + if (noshear) { + if (include_curvature) { + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + } + } - if (!include_jpar0) { - J0 = 0.0; - } + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; - } - } + if (not mesh->IncIntShear) { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + } + } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES + ////////////////////////////////////////////////////////////// + // NORMALISE QUANTITIES - if (not mesh->IncIntShear) { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; - } - } + if (mesh->get(Bbar, "bmag")) { // Typical magnetic field + Bbar = 1.0; + } + if (mesh->get(Lbar, "rmag")) { // Typical length scale + Lbar = 1.0; + } - ////////////////////////////////////////////////////////////// - // NORMALISE QUANTITIES + Va = sqrt(Bbar * Bbar / (MU0 * density * Mi)); - if (mesh->get(Bbar, "bmag")) { // Typical magnetic field - Bbar = 1.0; - } - if (mesh->get(Lbar, "rmag")) { // Typical length scale - Lbar = 1.0; - } + Tbar = Lbar / Va; - Va = sqrt(Bbar * Bbar / (MU0 * density * Mi)); + dnorm = dia_fact * Mi / (2. * 1.602e-19 * Bbar * Tbar); - Tbar = Lbar / Va; + delta_i = AA * 60.67 * 5.31e5 / sqrt(density / 1e6) / (Lbar * 100.0); - dnorm = dia_fact * Mi / (2. * 1.602e-19 * Bbar * Tbar); + output.write("Normalisations: Bbar = {:e} T Lbar = {:e} m\n", Bbar, Lbar); + output.write(" Va = {:e} m/s Tbar = {:e} s\n", Va, Tbar); + output.write(" dnorm = {:e}\n", dnorm); + output.write(" Resistivity\n"); - delta_i = AA * 60.67 * 5.31e5 / sqrt(density / 1e6) / (Lbar * 100.0); + if (gyroviscous) { + omega_i = 9.58e7 * Zeff * Bbar; + Upara2 = 0.5 / (Tbar * omega_i); + output.write("Upara2 = {:e} Omega_i = {:e}\n", Upara2, omega_i); + } - output.write("Normalisations: Bbar = {:e} T Lbar = {:e} m\n", Bbar, Lbar); - output.write(" Va = {:e} m/s Tbar = {:e} s\n", Va, Tbar); - output.write(" dnorm = {:e}\n", dnorm); - output.write(" Resistivity\n"); + if (eHall) { + output.write(" delta_i = {:e} AA = {:e} \n", delta_i, AA); + } - if (gyroviscous) { - omega_i = 9.58e7 * Zeff * Bbar; - Upara2 = 0.5 / (Tbar * omega_i); - output.write("Upara2 = {:e} Omega_i = {:e}\n", Upara2, omega_i); - } + if (vac_lund > 0.0) { + output.write(" Vacuum Tau_R = {:e} s eta = {:e} Ohm m\n", vac_lund * Tbar, + MU0 * Lbar * Lbar / (vac_lund * Tbar)); + vac_resist = 1. / vac_lund; + } else { + output.write(" Vacuum - Zero resistivity -\n"); + vac_resist = 0.0; + } + if (core_lund > 0.0) { + output.write(" Core Tau_R = {:e} s eta = {:e} Ohm m\n", + core_lund * Tbar, MU0 * Lbar * Lbar / (core_lund * Tbar)); + core_resist = 1. / core_lund; + } else { + output.write(" Core - Zero resistivity -\n"); + core_resist = 0.0; + } - if (eHall) { - output.write(" delta_i = {:e} AA = {:e} \n", delta_i, AA); - } + if (hyperresist > 0.0) { + output.write(" Hyper-resistivity coefficient: {:e}\n", hyperresist); + } - if (vac_lund > 0.0) { - output.write(" Vacuum Tau_R = {:e} s eta = {:e} Ohm m\n", vac_lund * Tbar, - MU0 * Lbar * Lbar / (vac_lund * Tbar)); - vac_resist = 1. / vac_lund; - } else { - output.write(" Vacuum - Zero resistivity -\n"); - vac_resist = 0.0; - } - if (core_lund > 0.0) { - output.write(" Core Tau_R = {:e} s eta = {:e} Ohm m\n", - core_lund * Tbar, MU0 * Lbar * Lbar / (core_lund * Tbar)); - core_resist = 1. / core_lund; - } else { - output.write(" Core - Zero resistivity -\n"); - core_resist = 0.0; - } + if (ehyperviscos > 0.0) { + output.write(" electron Hyper-viscosity coefficient: {:e}\n", ehyperviscos); + } - if (hyperresist > 0.0) { - output.write(" Hyper-resistivity coefficient: {:e}\n", hyperresist); - } + if (hyperviscos > 0.0) { + output.write(" Hyper-viscosity coefficient: {:e}\n", hyperviscos); + SAVE_ONCE(hyper_mu_x); + } - if (ehyperviscos > 0.0) { - output.write(" electron Hyper-viscosity coefficient: {:e}\n", ehyperviscos); - } + if (diffusion_par > 0.0) { + output.write(" diffusion_par: {:e}\n", diffusion_par); + SAVE_ONCE(diffusion_par); + } - if (hyperviscos > 0.0) { - output.write(" Hyper-viscosity coefficient: {:e}\n", hyperviscos); - SAVE_ONCE(hyper_mu_x); - } + // xqx: parallel hyper-viscous diffusion for pressure + if (diffusion_p4 > 0.0) { + output.write(" diffusion_p4: {:e}\n", diffusion_p4); + SAVE_ONCE(diffusion_p4); + } - if (diffusion_par > 0.0) { - output.write(" diffusion_par: {:e}\n", diffusion_par); - SAVE_ONCE(diffusion_par); - } + // xqx: parallel hyper-viscous diffusion for vorticity + if (diffusion_u4 > 0.0) { + output.write(" diffusion_u4: {:e}\n", diffusion_u4); + SAVE_ONCE(diffusion_u4) + } - // xqx: parallel hyper-viscous diffusion for pressure - if (diffusion_p4 > 0.0) { - output.write(" diffusion_p4: {:e}\n", diffusion_p4); - SAVE_ONCE(diffusion_p4); - } + // xqx: parallel hyper-viscous diffusion for vector potential + if (diffusion_a4 > 0.0) { + output.write(" diffusion_a4: {:e}\n", diffusion_a4); + SAVE_ONCE(diffusion_a4); + } - // xqx: parallel hyper-viscous diffusion for vorticity - if (diffusion_u4 > 0.0) { - output.write(" diffusion_u4: {:e}\n", diffusion_u4); - SAVE_ONCE(diffusion_u4) - } + if (heating_P > 0.0) { + output.write(" heating_P(watts): {:e}\n", heating_P); - // xqx: parallel hyper-viscous diffusion for vector potential - if (diffusion_a4 > 0.0) { - output.write(" diffusion_a4: {:e}\n", diffusion_a4); - SAVE_ONCE(diffusion_a4); - } + output.write(" hp_width(%%): {:e}\n", hp_width); - if (heating_P > 0.0) { - output.write(" heating_P(watts): {:e}\n", heating_P); + output.write(" hp_length(%%): {:e}\n", hp_length); - output.write(" hp_width(%%): {:e}\n", hp_width); + SAVE_ONCE(heating_P, hp_width, hp_length); + } - output.write(" hp_length(%%): {:e}\n", hp_length); + if (sink_P > 0.0) { + output.write(" sink_P(rate): {:e}\n", sink_P); + output.write(" sp_width(%%): {:e}\n", sp_width); + output.write(" sp_length(%%): {:e}\n", sp_length); - SAVE_ONCE(heating_P, hp_width, hp_length); - } + SAVE_ONCE(sink_P, sp_width, sp_length); + } - if (sink_P > 0.0) { - output.write(" sink_P(rate): {:e}\n", sink_P); - output.write(" sp_width(%%): {:e}\n", sp_width); - output.write(" sp_length(%%): {:e}\n", sp_length); + if (K_H_term) { + output.write(" keep K-H term\n"); + } else { + output.write(" drop K-H term\n"); + } - SAVE_ONCE(sink_P, sp_width, sp_length); - } + Field2D Te; + Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - if (K_H_term) { - output.write(" keep K-H term\n"); - } else { - output.write(" drop K-H term\n"); - } + J0 = -MU0 * Lbar * J0 / B0; + P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); + V0 = V0 / Va; + Dphi0 *= Tbar; - Field2D Te; - Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; - J0 = -MU0 * Lbar * J0 / B0; - P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); - V0 = V0 / Va; - Dphi0 *= Tbar; + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES - const auto& metric = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor); + } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES + if (constn0) { + T0_fake_prof = false; + n0_fake_prof = false; + } else { + Nbar = 1.0; + Tibar = 1000.0; + Tebar = 1000.0; + + if ((!T0_fake_prof) && n0_fake_prof) { + N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); + + Ti0 = P0 / N0 / 2.0; + Te0 = Ti0; + } else if (T0_fake_prof) { + Ti0 = Tconst; + Te0 = Ti0; + N0 = P0 / (Ti0 + Te0); + } else { + if (mesh->get(N0, "Niexp")) { // N_i0 + throw BoutException("Error: Cannot read Ni0 from grid\n"); + } - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor()); - } + if (mesh->get(Ti0, "Tiexp")) { // T_i0 + throw BoutException("Error: Cannot read Ti0 from grid\n"); + } - if (constn0) { - T0_fake_prof = false; - n0_fake_prof = false; - } else { - Nbar = 1.0; - Tibar = 1000.0; - Tebar = 1000.0; - - if ((!T0_fake_prof) && n0_fake_prof) { - N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); - - Ti0 = P0 / N0 / 2.0; - Te0 = Ti0; - } else if (T0_fake_prof) { - Ti0 = Tconst; - Te0 = Ti0; - N0 = P0 / (Ti0 + Te0); - } else { - if (mesh->get(N0, "Niexp")) { // N_i0 - throw BoutException("Error: Cannot read Ni0 from grid\n"); + if (mesh->get(Te0, "Teexp")) { // T_e0 + throw BoutException("Error: Cannot read Te0 from grid\n"); + } + N0 /= Nbar; + Ti0 /= Tibar; + Te0 /= Tebar; + } } - if (mesh->get(Ti0, "Tiexp")) { // T_i0 - throw BoutException("Error: Cannot read Ti0 from grid\n"); + if (gyroviscous) { + Dperp2Phi0.setLocation(CELL_CENTRE); + Dperp2Phi0.setBoundary("phi"); + Dperp2Phi.setLocation(CELL_CENTRE); + Dperp2Phi.setBoundary("phi"); + GradPhi02.setLocation(CELL_CENTRE); + GradPhi02.setBoundary("phi"); + GradcPhi.setLocation(CELL_CENTRE); + GradcPhi.setBoundary("phi"); + Dperp2Pi0.setLocation(CELL_CENTRE); + Dperp2Pi0.setBoundary("P"); + Dperp2Pi.setLocation(CELL_CENTRE); + Dperp2Pi.setBoundary("P"); + bracketPhi0P.setLocation(CELL_CENTRE); + bracketPhi0P.setBoundary("P"); + bracketPhiP0.setLocation(CELL_CENTRE); + bracketPhiP0.setBoundary("P"); + if (nonlinear) { + GradPhi2.setLocation(CELL_CENTRE); + GradPhi2.setBoundary("phi"); + bracketPhiP.setLocation(CELL_CENTRE); + bracketPhiP.setBoundary("P"); + } } - if (mesh->get(Te0, "Teexp")) { // T_e0 - throw BoutException("Error: Cannot read Te0 from grid\n"); - } - N0 /= Nbar; - Ti0 /= Tibar; - Te0 /= Tebar; - } - } + BoutReal pnorm = max(P0, true); // Maximum over all processors - if (gyroviscous) { - Dperp2Phi0.setLocation(CELL_CENTRE); - Dperp2Phi0.setBoundary("phi"); - Dperp2Phi.setLocation(CELL_CENTRE); - Dperp2Phi.setBoundary("phi"); - GradPhi02.setLocation(CELL_CENTRE); - GradPhi02.setBoundary("phi"); - GradcPhi.setLocation(CELL_CENTRE); - GradcPhi.setBoundary("phi"); - Dperp2Pi0.setLocation(CELL_CENTRE); - Dperp2Pi0.setBoundary("P"); - Dperp2Pi.setLocation(CELL_CENTRE); - Dperp2Pi.setBoundary("P"); - bracketPhi0P.setLocation(CELL_CENTRE); - bracketPhi0P.setBoundary("P"); - bracketPhiP0.setLocation(CELL_CENTRE); - bracketPhiP0.setBoundary("P"); - if (nonlinear) { - GradPhi2.setLocation(CELL_CENTRE); - GradPhi2.setBoundary("phi"); - bracketPhiP.setLocation(CELL_CENTRE); - bracketPhiP.setBoundary("P"); - } - } + vacuum_pressure *= pnorm; // Get pressure from fraction + vacuum_trans *= pnorm; - BoutReal pnorm = max(P0, true); // Maximum over all processors + // Transitions from 0 in core to 1 in vacuum + vac_mask = (1.0 - tanh((P0 - vacuum_pressure) / vacuum_trans)) / 2.0; - vacuum_pressure *= pnorm; // Get pressure from fraction - vacuum_trans *= pnorm; + if (spitzer_resist) { + // Use Spitzer resistivity + output.write("\tTemperature: {:e} -> {:e} [eV]\n", min(Te), max(Te)); + eta = 0.51 * 1.03e-4 * Zeff * 20. + * pow(Te, -1.5); // eta in Ohm-m. NOTE: ln(Lambda) = 20 + output.write("\tSpitzer resistivity: {:e} -> {:e} [Ohm m]\n", min(eta), max(eta)); + eta /= MU0 * Va * Lbar; + output.write("\t -> Lundquist {:e} -> {:e}\n", 1.0 / max(eta), 1.0 / min(eta)); + } else { + // transition from 0 for large P0 to resistivity for small P0 + eta = core_resist + (vac_resist - core_resist) * vac_mask; + } - // Transitions from 0 in core to 1 in vacuum - vac_mask = (1.0 - tanh((P0 - vacuum_pressure) / vacuum_trans)) / 2.0; - - if (spitzer_resist) { - // Use Spitzer resistivity - output.write("\tTemperature: {:e} -> {:e} [eV]\n", min(Te), max(Te)); - eta = 0.51 * 1.03e-4 * Zeff * 20. - * pow(Te, -1.5); // eta in Ohm-m. NOTE: ln(Lambda) = 20 - output.write("\tSpitzer resistivity: {:e} -> {:e} [Ohm m]\n", min(eta), max(eta)); - eta /= MU0 * Va * Lbar; - output.write("\t -> Lundquist {:e} -> {:e}\n", 1.0 / max(eta), 1.0 / min(eta)); - } else { - // transition from 0 for large P0 to resistivity for small P0 - eta = core_resist + (vac_resist - core_resist) * vac_mask; - } + eta = interp_to(eta, loc); - eta = interp_to(eta, loc); + SAVE_ONCE(eta); - SAVE_ONCE(eta); + if (include_rmp) { + // Normalise RMP quantities - if (include_rmp) { - // Normalise RMP quantities + rmp_Psi0 /= Bbar * Lbar; - rmp_Psi0 /= Bbar * Lbar; + rmp_ramp /= Tbar; + rmp_freq *= Tbar; + rmp_rotate *= Tbar; - rmp_ramp /= Tbar; - rmp_freq *= Tbar; - rmp_rotate *= Tbar; + rmp_Psi = rmp_Psi0; + rmp_dApdt = 0.0; - rmp_Psi = rmp_Psi0; - rmp_dApdt = 0.0; + bool apar_changing = false; - bool apar_changing = false; + output.write("Including magnetic perturbation\n"); + if (rmp_ramp > 0.0) { + output.write("\tRamping up over period t = {:e} ({:e} ms)\n", rmp_ramp, + rmp_ramp * Tbar * 1000.); + apar_changing = true; + } + if (rmp_freq > 0.0) { + output.write("\tOscillating with frequency f = {:e} ({:e} kHz)\n", rmp_freq, + rmp_freq / Tbar / 1000.); + apar_changing = true; + } + if (rmp_rotate != 0.0) { + output.write("\tRotating with a frequency f = {:e} ({:e} kHz)\n", rmp_rotate, + rmp_rotate / Tbar / 1000.); + apar_changing = true; + } - output.write("Including magnetic perturbation\n"); - if (rmp_ramp > 0.0) { - output.write("\tRamping up over period t = {:e} ({:e} ms)\n", rmp_ramp, - rmp_ramp * Tbar * 1000.); - apar_changing = true; - } - if (rmp_freq > 0.0) { - output.write("\tOscillating with frequency f = {:e} ({:e} kHz)\n", rmp_freq, - rmp_freq / Tbar / 1000.); - apar_changing = true; - } - if (rmp_rotate != 0.0) { - output.write("\tRotating with a frequency f = {:e} ({:e} kHz)\n", rmp_rotate, - rmp_rotate / Tbar / 1000.); - apar_changing = true; - } + if (apar_changing) { + SAVE_REPEAT(rmp_Psi, rmp_dApdt); + } else { + SAVE_ONCE(rmp_Psi); + } + } else { + rmp_Psi = 0.0; + } - if (apar_changing) { - SAVE_REPEAT(rmp_Psi, rmp_dApdt); - } else { - SAVE_ONCE(rmp_Psi); - } - } else { - rmp_Psi = 0.0; - } + // Set B field vector - // Set B field vector + B0vec.covariant = false; + B0vec.x = 0.; - B0vec.covariant = false; - B0vec.x = 0.; + B0vec.y = Bpxy / hthe; + B0vec.z = 0.; - B0vec.y = Bpxy / hthe; - B0vec.z = 0.; + V0net.covariant = false; // presentation for net flow + V0net.x = 0.; + V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; + V0net.z = -Dphi0; - V0net.covariant = false; // presentation for net flow - V0net.x = 0.; - V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; - V0net.z = -Dphi0; + U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term - U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term + /**************** SET EVOLVING VARIABLES *************/ - /**************** SET EVOLVING VARIABLES *************/ + // Tell BOUT which variables to evolve + SOLVE_FOR(U, P); - // Tell BOUT which variables to evolve - SOLVE_FOR(U, P); + if (evolve_jpar) { + output.write("Solving for jpar: Inverting to get Psi\n"); + SOLVE_FOR(Jpar); + SAVE_REPEAT(Psi); + } else { + output.write("Solving for Psi, Differentiating to get jpar\n"); + SOLVE_FOR(Psi); + SAVE_REPEAT(Jpar); + } - if (evolve_jpar) { - output.write("Solving for jpar: Inverting to get Psi\n"); - SOLVE_FOR(Jpar); - SAVE_REPEAT(Psi); - } else { - output.write("Solving for Psi, Differentiating to get jpar\n"); - SOLVE_FOR(Psi); - SAVE_REPEAT(Jpar); - } + if (compress) { + output.write("Including compression (Vpar) effects\n"); - if (compress) { - output.write("Including compression (Vpar) effects\n"); + SOLVE_FOR(Vpar); + comms.add(Vpar); - SOLVE_FOR(Vpar); - comms.add(Vpar); + beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); + gradparB = Grad_par(B0) / B0; - beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); - gradparB = Grad_par(B0) / B0; + output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); + } else { + Vpar = 0.0; + } - output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); - } else { - Vpar = 0.0; - } + if (phi_constraint) { + // Implicit Phi solve using IDA - if (phi_constraint) { - // Implicit Phi solve using IDA + if (!solver->constraints()) { + throw BoutException("Cannot constrain. Run again with phi_constraint=false.\n"); + } - if (!solver->constraints()) { - throw BoutException("Cannot constrain. Run again with phi_constraint=false.\n"); - } + solver->constraint(phi, C_phi, "phi"); - solver->constraint(phi, C_phi, "phi"); + // Set preconditioner + setPrecon(&ELMpb::precon_phi); - // Set preconditioner - setPrecon(&ELMpb::precon_phi); + } else { + // Phi solved in RHS (explicitly) + SAVE_REPEAT(phi); - } else { - // Phi solved in RHS (explicitly) - SAVE_REPEAT(phi); + // Set preconditioner + setPrecon(&ELMpb::precon); - // Set preconditioner - setPrecon(&ELMpb::precon); + // Set Jacobian + setJacobian((jacobianfunc) & ELMpb::jacobian); + } - // Set Jacobian - setJacobian((jacobianfunc)&ELMpb::jacobian); - } + // Diamagnetic phi0 + if (diamag_phi0) { + if (constn0) { + phi0 = -0.5 * dnorm * P0 / B0; + } else { + // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift + phi0 = -0.5 * dnorm * P0 / B0 / N0; + } + SAVE_ONCE(phi0); + } - // Diamagnetic phi0 - if (diamag_phi0) { - if (constn0) { - phi0 = -0.5 * dnorm * P0 / B0; - } else { - // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / B0 / N0; - } - SAVE_ONCE(phi0); - } + // Add some equilibrium quantities and normalisations + // everything needed to recover physical units + SAVE_ONCE(J0, P0); + SAVE_ONCE(density, Lbar, Bbar, Tbar); + SAVE_ONCE(Va, B0); + SAVE_ONCE(Dphi0, U0); + SAVE_ONCE(V0); + if (!constn0) { + SAVE_ONCE(Ti0, Te0, N0); + } - // Add some equilibrium quantities and normalisations - // everything needed to recover physical units - SAVE_ONCE(J0, P0); - SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, B0); - SAVE_ONCE(Dphi0, U0); - SAVE_ONCE(V0); - if (!constn0) { - SAVE_ONCE(Ti0, Te0, N0); - } + // Create a solver for the Laplacian + phiSolver = Laplacian::create(&globalOptions["phiSolver"]); - // Create a solver for the Laplacian - phiSolver = Laplacian::create(&globalOptions["phiSolver"]); + aparSolver = Laplacian::create(&globalOptions["aparSolver"], loc); - aparSolver = Laplacian::create(&globalOptions["aparSolver"], loc); + /////////////// CHECK VACUUM /////////////////////// + // In vacuum region, initial vorticity should equal zero - /////////////// CHECK VACUUM /////////////////////// - // In vacuum region, initial vorticity should equal zero + if (!restarting) { + // Only if not restarting: Check initial perturbation - if (!restarting) { - // Only if not restarting: Check initial perturbation + // Set U to zero where P0 < vacuum_pressure + U = where(P0 - vacuum_pressure, U, 0.0); - // Set U to zero where P0 < vacuum_pressure - U = where(P0 - vacuum_pressure, U, 0.0); + if (constn0) { + ubyn = U; + // Phi should be consistent with U + phi = phiSolver->solve(ubyn); + } else { + ubyn = U / N0; + phiSolver->setCoefC(N0); + phi = phiSolver->solve(ubyn); + } - if (constn0) { - ubyn = U; - // Phi should be consistent with U - phi = phiSolver->solve(ubyn); - } else { - ubyn = U / N0; - phiSolver->setCoefC(N0); - phi = phiSolver->solve(ubyn); - } + // if(diamag) { + // phi -= 0.5*dnorm * P / B0; + //} + } - // if(diamag) { - // phi -= 0.5*dnorm * P / B0; - //} - } + /************** SETUP COMMUNICATIONS **************/ - /************** SETUP COMMUNICATIONS **************/ + comms.add(U, P); - comms.add(U, P); + phi.setBoundary("phi"); // Set boundary conditions + tmpU2.setBoundary("U"); + tmpP2.setBoundary("P"); + tmpA2.setBoundary("J"); - phi.setBoundary("phi"); // Set boundary conditions - tmpU2.setBoundary("U"); - tmpP2.setBoundary("P"); - tmpA2.setBoundary("J"); + if (evolve_jpar) { + comms.add(Jpar); + } else { + comms.add(Psi); + // otherwise Need to communicate Jpar separately + Jpar.setBoundary("J"); + } + Jpar2.setBoundary("J"); - if (evolve_jpar) { - comms.add(Jpar); - } else { - comms.add(Psi); - // otherwise Need to communicate Jpar separately - Jpar.setBoundary("J"); + return 0; } - Jpar2.setBoundary("J"); - - return 0; - } // Parallel gradient along perturbed field-line Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) const { @@ -1165,7 +1165,7 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; if (nonlinear) { result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; @@ -1186,7 +1186,7 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; //////////////////////////////////////////// // Transitions from 0 in core to 1 in vacuum @@ -1804,7 +1804,7 @@ class ELMpb : public PhysicsModel { Field3D U1 = ddt(U); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); @@ -1858,7 +1858,7 @@ class ELMpb : public PhysicsModel { JP.setBoundary("P"); JP.applyBoundary(); - auto B0 = tokamak_coordinates.Bxy(); + auto B0 = tokamak_coordinates.Bxy; Field3D B0phi = B0 * phi; mesh->communicate(B0phi); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 5f401528f9..c2462cffe0 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -246,7 +246,7 @@ class GEM : public PhysicsModel { if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { - Bbar = max(tokamak_coordinates.Bxy(), true); + Bbar = max(tokamak_coordinates.Bxy, true); } } Bbar = options["Bbar"].withDefault(Bbar); // Override in options file @@ -349,7 +349,7 @@ class GEM : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates.Bpxy() / tokamak_coordinates.hthe(); + B0vec.y = tokamak_coordinates.Bpxy / tokamak_coordinates.hthe; B0vec.z = 0.; // Precompute this for use in RHS diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index d07cc4bbb8..775ce6401c 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -10,34 +10,82 @@ #include "bout/utils.hxx" #include "bout/vector2d.hxx" -class TokamakCoordinates { - -private: - Mesh& mesh_m; - Field2D Rxy_m; - Field2D Bpxy_m; - Field2D Btxy_m; - Field2D Bxy_m; - Field2D hthe_m; - FieldMetric ShearFactor_m; - FieldMetric dx_m; - - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor); - - BoutReal get_sign_of_bp(); - -public: - TokamakCoordinates(Mesh& mesh); - - Coordinates* make_coordinates(bool noshear, BoutReal Lbar, BoutReal Bbar, - BoutReal ShearFactor = 1.0); - - const Field2D& Rxy() const { return Rxy_m; } - const Field2D& Bpxy() const { return Bpxy_m; } - const Field2D& Btxy() const { return Btxy_m; } - const Field2D& Bxy() const { return Bxy_m; } - const Field2D& hthe() const { return hthe_m; } - const FieldMetric& ShearFactor() const { return ShearFactor_m; } +struct TokamakCoordinates { + Field2D Rxy; + Field2D Bpxy; + Field2D Btxy; + Field2D Bxy; + Field2D hthe; + FieldMetric ShearFactor; + FieldMetric dx; + + TokamakCoordinates(Mesh &mesh) { + mesh.get(Rxy, "Rxy"); + // mesh->get(Zxy, "Zxy"); + mesh.get(Bpxy, "Bpxy"); + mesh.get(Btxy, "Btxy"); + mesh.get(Bxy, "Bxy"); + mesh.get(hthe, "hthe"); + mesh.get(ShearFactor, "sinty"); + mesh.get(dx, "dpsi"); + } + + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { + Rxy /= Lbar; + Bpxy /= Bbar; + Btxy /= Bbar; + Bxy /= Bbar; + hthe /= Lbar; + ShearFactor *= Lbar * Lbar * Bbar * ShearFactor; + dx /= Lbar * Lbar * Bbar; + } }; +BoutReal get_sign_of_bp(Field2D Bpxy) { + if (min(Bpxy, true) < 0.0) { + return -1.0; + } + return 1.0; +} + +Coordinates* make_coordinates(Mesh& mesh, const bool noshear, BoutReal Lbar, + BoutReal Bbar, BoutReal ShearFactor = 1.0) { + + tokamakCoordinates.normalise(Lbar, Bbar, ShearFactor); + + const BoutReal sign_of_bp = get_sign_of_bp(tokamakCoordinates.Bpxy); + + if (noshear) { + ShearFactor = 0.0; + } + + auto *coord = mesh.getCoordinates(); + + const auto g11 = SQ(tokamakCoordinates.Rxy * tokamakCoordinates.Bpxy); + const auto g22 = 1.0 / SQ(tokamakCoordinates.hthe); + const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamakCoordinates.Bxy) / g11; + const auto g12 = 0.0; + const auto g13 = -ShearFactor * g11; + const auto g23 = -sign_of_bp * tokamakCoordinates.Btxy / + (tokamakCoordinates.hthe * tokamakCoordinates.Bpxy * tokamakCoordinates.Rxy); + + const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamakCoordinates.Rxy); + const auto g_22 = SQ(tokamakCoordinates.Bxy * tokamakCoordinates.hthe / tokamakCoordinates.Bpxy); + const auto g_33 = tokamakCoordinates.Rxy * tokamakCoordinates.Rxy; + const auto g_12 = + sign_of_bp * tokamakCoordinates.Btxy * tokamakCoordinates.hthe * ShearFactor * tokamakCoordinates.Rxy / + tokamakCoordinates.Bpxy; + const auto g_13 = ShearFactor * tokamakCoordinates.Rxy * tokamakCoordinates.Rxy; + const auto g_23 = sign_of_bp * tokamakCoordinates.Btxy * tokamakCoordinates.hthe * tokamakCoordinates.Rxy / + tokamakCoordinates.Bpxy; + + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + + + coord->setJ(tokamakCoordinates.hthe / tokamakCoordinates.Bpxy); + coord->setBxy(tokamakCoordinates.Bxy); + coord->setDx(tokamakCoordinates.dx); +} + #endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/src/mesh/tokamak_coordinates.cxx b/src/mesh/tokamak_coordinates.cxx deleted file mode 100644 index c5e395a2fd..0000000000 --- a/src/mesh/tokamak_coordinates.cxx +++ /dev/null @@ -1,68 +0,0 @@ -#include - -void TokamakCoordinates::normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { - - Rxy_m /= Lbar; - Bpxy_m /= Bbar; - Btxy_m /= Bbar; - Bxy_m /= Bbar; - hthe_m /= Lbar; - ShearFactor_m *= Lbar * Lbar * Bbar * ShearFactor; - dx_m /= Lbar * Lbar * Bbar; -} - -TokamakCoordinates::TokamakCoordinates(Mesh& mesh) : mesh_m(mesh) { - - mesh.get(Rxy_m, "Rxy"); - // mesh->get(Zxy, "Zxy"); - mesh.get(Bpxy_m, "Bpxy"); - mesh.get(Btxy_m, "Btxy"); - mesh.get(Bxy_m, "Bxy"); - mesh.get(hthe_m, "hthe"); - mesh.get(ShearFactor_m, "sinty"); - mesh.get(dx_m, "dpsi"); -} - -BoutReal TokamakCoordinates::get_sign_of_bp() { - if (min(Bpxy_m, true) < 0.0) { - return -1.0; - } - return 1.0; -} - -Coordinates* TokamakCoordinates::make_coordinates(const bool noshear, BoutReal Lbar, - BoutReal Bbar, BoutReal ShearFactor) { - - normalise(Lbar, Bbar, ShearFactor); - - const BoutReal sign_of_bp = get_sign_of_bp(); - - if (noshear) { - ShearFactor_m = 0.0; - } - - auto* coord = mesh_m.getCoordinates(); - - const auto g11 = SQ(Rxy_m * Bpxy_m); - const auto g22 = 1.0 / SQ(hthe_m); - const auto g33 = SQ(ShearFactor_m) * g11 + SQ(Bxy_m) / g11; - const auto g12 = 0.0; - const auto g13 = -ShearFactor_m * g11; - const auto g23 = -sign_of_bp * Btxy_m / (hthe_m * Bpxy_m * Rxy_m); - - const auto g_11 = 1.0 / g11 + SQ(ShearFactor_m * Rxy_m); - const auto g_22 = SQ(Bxy_m * hthe_m / Bpxy_m); - const auto g_33 = Rxy_m * Rxy_m; - const auto g_12 = sign_of_bp * Btxy_m * hthe_m * ShearFactor_m * Rxy_m / Bpxy_m; - const auto g_13 = ShearFactor_m * Rxy_m * Rxy_m; - const auto g_23 = sign_of_bp * Btxy_m * hthe_m * Rxy_m / Bpxy_m; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - coord->setJ(hthe_m / Bpxy_m); - coord->setBxy(Bxy_m); - coord->setDx(dx_m); - - return coord; -} diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index f8c38cebe0..121c0ef5b6 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -134,7 +134,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; noshear = true; } diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 15d4df6790..92ae050d00 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -103,7 +103,7 @@ class Interchange : public PhysicsModel { coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); if (ShiftXderivs) { - b0xcv.z += tokamak_coordinates.ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; } /************** NORMALISE QUANTITIES *****************/ From e6bf57285ec8db74d6a1c9b1184498a185583639 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 14 Jan 2025 13:54:33 +0000 Subject: [PATCH 89/98] Rename make_coordinates() to set_tokamak_coordinates_on_mesh() and don't return anything --- examples/6field-simple/elm_6f.cxx | 2 +- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/dalf3/dalf3.cxx | 2 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 2 +- examples/elm-pb/elm_pb.cxx | 1932 +++++++++-------- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 3 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 4 +- include/bout/tokamak_coordinates.hxx | 4 +- tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- tests/MMS/tokamak/tokamak.cxx | 4 +- .../test-drift-instability/2fluid.cxx | 2 +- .../test-interchange-instability/2fluid.cxx | 2 +- .../integrated/test-laplacexy/loadmetric.cxx | 2 +- 17 files changed, 989 insertions(+), 982 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index dc67d54958..feaefccb60 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -1031,7 +1031,7 @@ class Elm_6f : public PhysicsModel { } /**************** CALCULATE METRICS ******************/ - const auto& coord = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 44223851d7..4e8f6a2cae 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -129,7 +129,7 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index f3dd0d8a66..c88e3603aa 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -171,7 +171,7 @@ class Alfven : public PhysicsModel { } auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coord = tokamak_coordinates.make_coordinates(noshear, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, Lnorm, Bnorm); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 594b01e236..c938410595 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -222,7 +222,7 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - const auto& coord = tokamak_coordinates.make_coordinates(noshear, rho_s, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, Bnorm); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index cfe3cbbbc6..3848b654d5 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -716,7 +716,7 @@ class ELMpb : public PhysicsModel { if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale Lbar = 1.0; } - const auto& metric = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); auto Bpxy = tokamak_coordinates.Bpxy; auto hthe = tokamak_coordinates.hthe; diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 48adcfaefc..05d94afa6d 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -36,476 +36,478 @@ BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_xout", "none"); /// 3-field ELM simulation class ELMpb : public PhysicsModel { private: - // 2D inital profiles - Field2D J0, P0; // Current and pressure - Vector2D b0xcv; // Curvature term - Field2D beta; // Used for Vpar terms - Coordinates::FieldMetric gradparB; - Field2D phi0; // When diamagnetic terms used - Field2D Psixy, x; - Coordinates::FieldMetric U0; // 0th vorticity of equilibrium flow, - // radial flux coordinate, normalized radial flux coordinate - - bool constn0; - // the total height, average width and center of profile of N0 - BoutReal n0_height, n0_ave, n0_width, n0_center, n0_bottom_x, Nbar, Tibar, Tebar; - - BoutReal Tconst; // the ampitude of constant temperature - - Field2D N0, Ti0, Te0, Ne0; // number density and temperature - Field2D Pi0, Pe0; - Field2D q95; - Field3D ubyn; - bool n0_fake_prof, T0_fake_prof; - - // B field vectors - Vector2D B0vec; // B0 field vector - - // V0 field vectors - Vector2D V0net; // net flow - - // 3D evolving variables - Field3D U, Psi, P, Vpar, Psi_loc; - - // Derived 3D variables - Field3D Jpar, phi; // Parallel current, electric potential - - Field3D Jpar2; // Delp2 of Parallel current - - Field3D tmpP2; // Grad2_par2new of pressure - Field3D tmpU2; // Grad2_par2new of Parallel vorticity - Field3D tmpA2; // Grad2_par2new of Parallel vector potential - - // Constraint - Field3D C_phi; - - // Parameters - BoutReal density; // Number density [m^-3] - BoutReal Bbar, Lbar, Tbar, Va; // Normalisation constants - BoutReal dnorm; // For diamagnetic terms: 1 / (2. * wci * Tbar) - BoutReal dia_fact; // Multiply diamagnetic term by this - BoutReal delta_i; // Normalized ion skin depth - BoutReal omega_i; // ion gyrofrequency - - BoutReal diffusion_p4; // xqx: parallel hyper-viscous diffusion for pressure - BoutReal diffusion_u4; // xqx: parallel hyper-viscous diffusion for vorticity - BoutReal diffusion_a4; // xqx: parallel hyper-viscous diffusion for vector potential - - BoutReal diffusion_par; // Parallel pressure diffusion - BoutReal heating_P; // heating power in pressure - BoutReal hp_width; // heating profile radial width in pressure - BoutReal hp_length; // heating radial domain in pressure - BoutReal sink_P; // sink in pressure - BoutReal sp_width; // sink profile radial width in pressure - BoutReal sp_length; // sink radial domain in pressure - - BoutReal sink_Ul; // left edge sink in vorticity - BoutReal su_widthl; // left edge sink profile radial width in vorticity - BoutReal su_lengthl; // left edge sink radial domain in vorticity - - BoutReal sink_Ur; // right edge sink in vorticity - BoutReal su_widthr; // right edge sink profile radial width in vorticity - BoutReal su_lengthr; // right edge sink radial domain in vorticity - - BoutReal viscos_par; // Parallel viscosity - BoutReal viscos_perp; // Perpendicular viscosity - BoutReal hyperviscos; // Hyper-viscosity (radial) - Field3D hyper_mu_x; // Hyper-viscosity coefficient - - Field3D Dperp2Phi0, Dperp2Phi, GradPhi02, - GradPhi2; // Temporary variables for gyroviscous - Field3D GradparPhi02, GradparPhi2, GradcPhi, GradcparPhi; - Field3D Dperp2Pi0, Dperp2Pi, bracketPhi0P, bracketPhiP0, bracketPhiP; - BoutReal Upara2; - - // options - bool include_curvature, include_jpar0, compress; - bool evolve_pressure, gyroviscous; - - BoutReal vacuum_pressure; - BoutReal vacuum_trans; // Transition width - Field3D vac_mask; - - bool nonlinear; - bool evolve_jpar; - BoutReal g; // Only if compressible - bool phi_curv; - - // Poisson brackets: b0 x Grad(f) dot Grad(g) / B = [f, g] - // Method to use: BRACKET_ARAKAWA, BRACKET_STD or BRACKET_SIMPLE - /* - * Bracket method - * - * BRACKET_STD - Same as b0xGrad_dot_Grad, methods in BOUT.inp - * BRACKET_SIMPLE - Subset of terms, used in BOUT-06 - * BRACKET_ARAKAWA - Arakawa central differencing (2nd order) - * BRACKET_CTU - 1st order upwind method - * - */ - - // Bracket method for advection terms - BRACKET_METHOD bm_exb; - BRACKET_METHOD bm_mag; - int bm_exb_flag; - int bm_mag_flag; - /* BRACKET_METHOD bm_ExB = BRACKET_STD; - BRACKET_METHOD bm_mflutter = BRACKET_STD; */ - - bool diamag; - bool diamag_grad_t; // Grad_par(Te) term in Psi equation - bool diamag_phi0; // Include the diamagnetic equilibrium phi0 - - bool eHall; - BoutReal AA; // ion mass in units of the proton mass; AA=Mi/Mp - - // net flow, Er=-R*Bp*Dphi0,Dphi0=-D_min-0.5*D_0*(1.0-tanh(D_s*(x-x0))) - Field2D V0; // net flow amplitude - Field2D Dphi0; // differential potential to flux - BoutReal D_0; // potential amplitude - BoutReal D_s; // shear parameter - BoutReal x0; // velocity peak location - BoutReal sign; // direction of flow - BoutReal Psiaxis, Psibndry; - bool withflow; - bool K_H_term; // Kelvin-Holmhotz term - Field2D perp; // for test - BoutReal D_min; // constant in flow - - // for C_mod - bool experiment_Er; // read in total Er from experiment - - bool nogradparj; - bool filter_z; - int filter_z_mode; - int low_pass_z; - bool zonal_flow; - bool zonal_field; - bool zonal_bkgd; - - bool split_n0; // Solve the n=0 component of potential + // 2D inital profiles + Field2D J0, P0; // Current and pressure + Vector2D b0xcv; // Curvature term + Field2D beta; // Used for Vpar terms + Coordinates::FieldMetric gradparB; + Field2D phi0; // When diamagnetic terms used + Field2D Psixy, x; + Coordinates::FieldMetric U0; // 0th vorticity of equilibrium flow, + // radial flux coordinate, normalized radial flux coordinate + + bool constn0; + // the total height, average width and center of profile of N0 + BoutReal n0_height, n0_ave, n0_width, n0_center, n0_bottom_x, Nbar, Tibar, Tebar; + + BoutReal Tconst; // the ampitude of constant temperature + + Field2D N0, Ti0, Te0, Ne0; // number density and temperature + Field2D Pi0, Pe0; + Field2D q95; + Field3D ubyn; + bool n0_fake_prof, T0_fake_prof; + + // B field vectors + Vector2D B0vec; // B0 field vector + + // V0 field vectors + Vector2D V0net; // net flow + + // 3D evolving variables + Field3D U, Psi, P, Vpar, Psi_loc; + + // Derived 3D variables + Field3D Jpar, phi; // Parallel current, electric potential + + Field3D Jpar2; // Delp2 of Parallel current + + Field3D tmpP2; // Grad2_par2new of pressure + Field3D tmpU2; // Grad2_par2new of Parallel vorticity + Field3D tmpA2; // Grad2_par2new of Parallel vector potential + + // Constraint + Field3D C_phi; + + // Parameters + BoutReal density; // Number density [m^-3] + BoutReal Bbar, Lbar, Tbar, Va; // Normalisation constants + BoutReal dnorm; // For diamagnetic terms: 1 / (2. * wci * Tbar) + BoutReal dia_fact; // Multiply diamagnetic term by this + BoutReal delta_i; // Normalized ion skin depth + BoutReal omega_i; // ion gyrofrequency + + BoutReal diffusion_p4; // xqx: parallel hyper-viscous diffusion for pressure + BoutReal diffusion_u4; // xqx: parallel hyper-viscous diffusion for vorticity + BoutReal diffusion_a4; // xqx: parallel hyper-viscous diffusion for vector potential + + BoutReal diffusion_par; // Parallel pressure diffusion + BoutReal heating_P; // heating power in pressure + BoutReal hp_width; // heating profile radial width in pressure + BoutReal hp_length; // heating radial domain in pressure + BoutReal sink_P; // sink in pressure + BoutReal sp_width; // sink profile radial width in pressure + BoutReal sp_length; // sink radial domain in pressure + + BoutReal sink_Ul; // left edge sink in vorticity + BoutReal su_widthl; // left edge sink profile radial width in vorticity + BoutReal su_lengthl; // left edge sink radial domain in vorticity + + BoutReal sink_Ur; // right edge sink in vorticity + BoutReal su_widthr; // right edge sink profile radial width in vorticity + BoutReal su_lengthr; // right edge sink radial domain in vorticity + + BoutReal viscos_par; // Parallel viscosity + BoutReal viscos_perp; // Perpendicular viscosity + BoutReal hyperviscos; // Hyper-viscosity (radial) + Field3D hyper_mu_x; // Hyper-viscosity coefficient + + Field3D Dperp2Phi0, Dperp2Phi, GradPhi02, + GradPhi2; // Temporary variables for gyroviscous + Field3D GradparPhi02, GradparPhi2, GradcPhi, GradcparPhi; + Field3D Dperp2Pi0, Dperp2Pi, bracketPhi0P, bracketPhiP0, bracketPhiP; + BoutReal Upara2; + + // options + bool include_curvature, include_jpar0, compress; + bool evolve_pressure, gyroviscous; + + BoutReal vacuum_pressure; + BoutReal vacuum_trans; // Transition width + Field3D vac_mask; + + bool nonlinear; + bool evolve_jpar; + BoutReal g; // Only if compressible + bool phi_curv; + + // Poisson brackets: b0 x Grad(f) dot Grad(g) / B = [f, g] + // Method to use: BRACKET_ARAKAWA, BRACKET_STD or BRACKET_SIMPLE + /* + * Bracket method + * + * BRACKET_STD - Same as b0xGrad_dot_Grad, methods in BOUT.inp + * BRACKET_SIMPLE - Subset of terms, used in BOUT-06 + * BRACKET_ARAKAWA - Arakawa central differencing (2nd order) + * BRACKET_CTU - 1st order upwind method + * + */ + + // Bracket method for advection terms + BRACKET_METHOD bm_exb; + BRACKET_METHOD bm_mag; + int bm_exb_flag; + int bm_mag_flag; + /* BRACKET_METHOD bm_ExB = BRACKET_STD; + BRACKET_METHOD bm_mflutter = BRACKET_STD; */ + + bool diamag; + bool diamag_grad_t; // Grad_par(Te) term in Psi equation + bool diamag_phi0; // Include the diamagnetic equilibrium phi0 + + bool eHall; + BoutReal AA; // ion mass in units of the proton mass; AA=Mi/Mp + + // net flow, Er=-R*Bp*Dphi0,Dphi0=-D_min-0.5*D_0*(1.0-tanh(D_s*(x-x0))) + Field2D V0; // net flow amplitude + Field2D Dphi0; // differential potential to flux + BoutReal D_0; // potential amplitude + BoutReal D_s; // shear parameter + BoutReal x0; // velocity peak location + BoutReal sign; // direction of flow + BoutReal Psiaxis, Psibndry; + bool withflow; + bool K_H_term; // Kelvin-Holmhotz term + Field2D perp; // for test + BoutReal D_min; // constant in flow + + // for C_mod + bool experiment_Er; // read in total Er from experiment + + bool nogradparj; + bool filter_z; + int filter_z_mode; + int low_pass_z; + bool zonal_flow; + bool zonal_field; + bool zonal_bkgd; + + bool split_n0; // Solve the n=0 component of potential #if BOUT_HAS_HYPRE - std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) + std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) #else - std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) + std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) #endif - Field2D phi2D; // Axisymmetric phi + Field2D phi2D; // Axisymmetric phi - bool relax_j_vac; - BoutReal relax_j_tconst; // Time-constant for j relax + bool relax_j_vac; + BoutReal relax_j_tconst; // Time-constant for j relax - bool smooth_j_x; // Smooth Jpar in the x direction + bool smooth_j_x; // Smooth Jpar in the x direction - int jpar_bndry_width; // Zero jpar in a boundary region + int jpar_bndry_width; // Zero jpar in a boundary region - bool sheath_boundaries; // Apply sheath boundaries in Y + bool sheath_boundaries; // Apply sheath boundaries in Y - bool parallel_lr_diff; // Use left and right shifted stencils for parallel differences + bool parallel_lr_diff; // Use left and right shifted stencils for parallel differences - bool phi_constraint; // Solver for phi using a solver constraint + bool phi_constraint; // Solver for phi using a solver constraint - bool include_rmp; // Include RMP coil perturbation - bool simple_rmp; // Just use a simple form for the perturbation + bool include_rmp; // Include RMP coil perturbation + bool simple_rmp; // Just use a simple form for the perturbation - BoutReal rmp_factor; // Multiply amplitude by this factor - BoutReal rmp_ramp; // Ramp-up time for RMP [s]. negative -> instant - BoutReal rmp_freq; // Amplitude oscillation frequency [Hz] (negative -> no oscillation) - BoutReal rmp_rotate; // Rotation rate [Hz] - bool rmp_vac_mask; - Field3D rmp_Psi0; // Parallel vector potential from Resonant Magnetic Perturbation (RMP) - // coils - Field3D rmp_Psi; // Value used in calculations - Field3D rmp_dApdt; // Time variation + BoutReal rmp_factor; // Multiply amplitude by this factor + BoutReal rmp_ramp; // Ramp-up time for RMP [s]. negative -> instant + BoutReal rmp_freq; // Amplitude oscillation frequency [Hz] (negative -> no oscillation) + BoutReal rmp_rotate; // Rotation rate [Hz] + bool rmp_vac_mask; + Field3D rmp_Psi0; // Parallel vector potential from Resonant Magnetic Perturbation (RMP) + // coils + Field3D rmp_Psi; // Value used in calculations + Field3D rmp_dApdt; // Time variation - BoutReal vac_lund, core_lund; // Lundquist number S = (Tau_R / Tau_A). -ve -> infty - BoutReal vac_resist, core_resist; // The resistivities (just 1 / S) - Field3D eta; // Resistivity profile (1 / S) - bool spitzer_resist; // Use Spitzer formula for resistivity - BoutReal Zeff; // Z effective for resistivity formula + BoutReal vac_lund, core_lund; // Lundquist number S = (Tau_R / Tau_A). -ve -> infty + BoutReal vac_resist, core_resist; // The resistivities (just 1 / S) + Field3D eta; // Resistivity profile (1 / S) + bool spitzer_resist; // Use Spitzer formula for resistivity + BoutReal Zeff; // Z effective for resistivity formula - BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) - BoutReal ehyperviscos; // electron Hyper-viscosity coefficient + BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) + BoutReal ehyperviscos; // electron Hyper-viscosity coefficient - int damp_width; // Width of inner damped region - BoutReal damp_t_const; // Timescale of damping + int damp_width; // Width of inner damped region + BoutReal damp_t_const; // Timescale of damping - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); - const BoutReal MU0 = 4.0e-7 * PI; - const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass - const BoutReal Me = 9.1094e-31; // Electron mass - const BoutReal mi_me = Mi / Me; + const BoutReal MU0 = 4.0e-7 * PI; + const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass + const BoutReal Me = 9.1094e-31; // Electron mass + const BoutReal mi_me = Mi / Me; - // Communication objects - FieldGroup comms; + // Communication objects + FieldGroup comms; - /// Solver for inverting Laplacian - std::unique_ptr phiSolver{nullptr}; - std::unique_ptr aparSolver{nullptr}; + /// Solver for inverting Laplacian + std::unique_ptr phiSolver{nullptr}; + std::unique_ptr aparSolver{nullptr}; - const Field2D N0tanh(BoutReal n0_height, BoutReal n0_ave, BoutReal n0_width, - BoutReal n0_center, BoutReal n0_bottom_x) { - Field2D result; - result.allocate(); + const Field2D N0tanh(BoutReal n0_height, BoutReal n0_ave, BoutReal n0_width, + BoutReal n0_center, BoutReal n0_bottom_x) { + Field2D result; + result.allocate(); - BoutReal Grid_NX, Grid_NXlimit; // the grid number on x, and the - BoutReal Jysep; - mesh->get(Grid_NX, "nx"); - mesh->get(Jysep, "jyseps1_1"); - Grid_NXlimit = n0_bottom_x * Grid_NX; - output.write("Jysep1_1 = {:d} Grid number = {:e}\n", int(Jysep), Grid_NX); + BoutReal Grid_NX, Grid_NXlimit; // the grid number on x, and the + BoutReal Jysep; + mesh->get(Grid_NX, "nx"); + mesh->get(Jysep, "jyseps1_1"); + Grid_NXlimit = n0_bottom_x * Grid_NX; + output.write("Jysep1_1 = {:d} Grid number = {:e}\n", int(Jysep), Grid_NX); - if (Jysep > 0.) { // for single null geometry - BoutReal Jxsep, Jysep2; - mesh->get(Jxsep, "ixseps1"); - mesh->get(Jysep2, "jyseps2_2"); + if (Jysep > 0.) { // for single null geometry + BoutReal Jxsep, Jysep2; + mesh->get(Jxsep, "ixseps1"); + mesh->get(Jysep2, "jyseps2_2"); - for (auto i : result) { - BoutReal mgx = mesh->GlobalX(i.x()); - BoutReal xgrid_num = (Jxsep + 1.) / Grid_NX; + for (auto i: result) { + BoutReal mgx = mesh->GlobalX(i.x()); + BoutReal xgrid_num = (Jxsep + 1.) / Grid_NX; - int globaly = mesh->getGlobalYIndex(i.y()); + int globaly = mesh->getGlobalYIndex(i.y()); - if (mgx > xgrid_num || (globaly <= int(Jysep) - 2) - || (globaly > int(Jysep2) + 2)) { - mgx = xgrid_num; + if (mgx > xgrid_num || (globaly <= int(Jysep) - 2) + || (globaly > int(Jysep2) + 2)) { + mgx = xgrid_num; + } + BoutReal rlx = mgx - n0_center; + BoutReal temp = exp(rlx / n0_width); + BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); + result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; + } + } else { // circular geometry + for (auto i: result) { + BoutReal mgx = mesh->GlobalX(i.x()); + BoutReal xgrid_num = Grid_NXlimit / Grid_NX; + if (mgx > xgrid_num) { + mgx = xgrid_num; + } + BoutReal rlx = mgx - n0_center; + BoutReal temp = exp(rlx / n0_width); + BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); + result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; + } } - BoutReal rlx = mgx - n0_center; - BoutReal temp = exp(rlx / n0_width); - BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); - result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; - } - } else { // circular geometry - for (auto i : result) { - BoutReal mgx = mesh->GlobalX(i.x()); - BoutReal xgrid_num = Grid_NXlimit / Grid_NX; - if (mgx > xgrid_num) { - mgx = xgrid_num; - } - BoutReal rlx = mgx - n0_center; - BoutReal temp = exp(rlx / n0_width); - BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); - result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; - } - } - mesh->communicate(result); + mesh->communicate(result); - return result; - } + return result; + } protected: - int init(bool restarting) override { + int init(bool restarting) override { - bool noshear; + bool noshear; - output.write("Solving high-beta flute reduced equations\n"); - output.write("\tFile : {:s}\n", __FILE__); - output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); + Coordinates *metric = mesh->getCoordinates(); - ////////////////////////////////////////////////////////////// - // Load data from the grid + output.write("Solving high-beta flute reduced equations\n"); + output.write("\tFile : {:s}\n", __FILE__); + output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); - // Load 2D profiles - mesh->get(J0, "Jpar0"); // A / m^2 - mesh->get(P0, "pressure"); // Pascals + ////////////////////////////////////////////////////////////// + // Load data from the grid - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + // Load 2D profiles + mesh->get(J0, "Jpar0"); // A / m^2 + mesh->get(P0, "pressure"); // Pascals - mesh->get(Psixy, "psixy"); // get Psi - mesh->get(Psiaxis, "psi_axis"); // axis flux - mesh->get(Psibndry, "psi_bndry"); // edge flux + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - // Set locations of staggered variables - // Note, use of staggered grids in elm-pb is untested and may not be completely - // implemented. Parallel boundary conditions are especially likely to be wrong. - if (mesh->StaggerGrids) { - loc = CELL_YLOW; - } else { - loc = CELL_CENTRE; - } - Jpar.setLocation(loc); - Vpar.setLocation(loc); - Psi.setLocation(loc); - eta.setLocation(loc); - Psi_loc.setBoundary("Psi_loc"); - - ////////////////////////////////////////////////////////////// - auto& globalOptions = Options::root(); - auto& options = globalOptions["highbeta"]; - - constn0 = options["constn0"].withDefault(true); - // use the hyperbolic profile of n0. If both n0_fake_prof and - // T0_fake_prof are false, use the profiles from grid file - n0_fake_prof = options["n0_fake_prof"].withDefault(false); - // the total height of profile of N0, in percentage of Ni_x - n0_height = options["n0_height"].withDefault(0.4); - // the center or average of N0, in percentage of Ni_x - n0_ave = options["n0_ave"].withDefault(0.01); - // the width of the gradient of N0,in percentage of x - n0_width = options["n0_width"].withDefault(0.1); - // the grid number of the center of N0, in percentage of x - n0_center = options["n0_center"].withDefault(0.633); - // the start of flat region of N0 on SOL side, in percentage of x - n0_bottom_x = options["n0_bottom_x"].withDefault(0.81); - T0_fake_prof = options["T0_fake_prof"].withDefault(false); - // the amplitude of constant temperature, in percentage - Tconst = options["Tconst"].withDefault(-1.0); - - density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); - - evolve_jpar = options["evolve_jpar"] - .doc("If true, evolve J rather than Psi") - .withDefault(false); - phi_constraint = options["phi_constraint"] - .doc("Use solver constraint for phi?") - .withDefault(false); - - // Effects to include/exclude - include_curvature = options["include_curvature"].withDefault(true); - include_jpar0 = options["include_jpar0"].withDefault(true); - evolve_pressure = options["evolve_pressure"].withDefault(true); - nogradparj = options["nogradparj"].withDefault(false); - - compress = options["compress"] - .doc("Include compressibility effects (evolve Vpar)?") - .withDefault(false); - gyroviscous = options["gyroviscous"].withDefault(false); - nonlinear = options["nonlinear"].doc("Include nonlinear terms?").withDefault(false); - - // option for ExB Poisson Bracket - bm_exb_flag = options["bm_exb_flag"] - .doc("ExB Poisson bracket method. 0=standard;1=simple;2=arakawa") - .withDefault(0); - switch (bm_exb_flag) { - case 0: { - bm_exb = BRACKET_STD; - output << "\tBrackets for ExB: default differencing\n"; - break; - } - case 1: { - bm_exb = BRACKET_SIMPLE; - output << "\tBrackets for ExB: simplified operator\n"; - break; - } - case 2: { - bm_exb = BRACKET_ARAKAWA; - output << "\tBrackets for ExB: Arakawa scheme\n"; - break; - } - case 3: { - bm_exb = BRACKET_CTU; - output << "\tBrackets for ExB: Corner Transport Upwind method\n"; - break; - } - default: - throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); - } + mesh->get(Psixy, "psixy"); // get Psi + mesh->get(Psiaxis, "psi_axis"); // axis flux + mesh->get(Psibndry, "psi_bndry"); // edge flux - bm_mag_flag = - options["bm_mag_flag"].doc("magnetic flutter Poisson Bracket").withDefault(0); - switch (bm_mag_flag) { - case 0: { - bm_mag = BRACKET_STD; - output << "\tBrackets: default differencing\n"; - break; - } - case 1: { - bm_mag = BRACKET_SIMPLE; - output << "\tBrackets: simplified operator\n"; - break; - } - case 2: { - bm_mag = BRACKET_ARAKAWA; - output << "\tBrackets: Arakawa scheme\n"; - break; - } - case 3: { - bm_mag = BRACKET_CTU; - output << "\tBrackets: Corner Transport Upwind method\n"; - break; - } - default: - throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); - } + // Set locations of staggered variables + // Note, use of staggered grids in elm-pb is untested and may not be completely + // implemented. Parallel boundary conditions are especially likely to be wrong. + if (mesh->StaggerGrids) { + loc = CELL_YLOW; + } else { + loc = CELL_CENTRE; + } + Jpar.setLocation(loc); + Vpar.setLocation(loc); + Psi.setLocation(loc); + eta.setLocation(loc); + Psi_loc.setBoundary("Psi_loc"); + + ////////////////////////////////////////////////////////////// + auto &globalOptions = Options::root(); + auto &options = globalOptions["highbeta"]; + + constn0 = options["constn0"].withDefault(true); + // use the hyperbolic profile of n0. If both n0_fake_prof and + // T0_fake_prof are false, use the profiles from grid file + n0_fake_prof = options["n0_fake_prof"].withDefault(false); + // the total height of profile of N0, in percentage of Ni_x + n0_height = options["n0_height"].withDefault(0.4); + // the center or average of N0, in percentage of Ni_x + n0_ave = options["n0_ave"].withDefault(0.01); + // the width of the gradient of N0,in percentage of x + n0_width = options["n0_width"].withDefault(0.1); + // the grid number of the center of N0, in percentage of x + n0_center = options["n0_center"].withDefault(0.633); + // the start of flat region of N0 on SOL side, in percentage of x + n0_bottom_x = options["n0_bottom_x"].withDefault(0.81); + T0_fake_prof = options["T0_fake_prof"].withDefault(false); + // the amplitude of constant temperature, in percentage + Tconst = options["Tconst"].withDefault(-1.0); + + density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); + + evolve_jpar = options["evolve_jpar"] + .doc("If true, evolve J rather than Psi") + .withDefault(false); + phi_constraint = options["phi_constraint"] + .doc("Use solver constraint for phi?") + .withDefault(false); + + // Effects to include/exclude + include_curvature = options["include_curvature"].withDefault(true); + include_jpar0 = options["include_jpar0"].withDefault(true); + evolve_pressure = options["evolve_pressure"].withDefault(true); + nogradparj = options["nogradparj"].withDefault(false); + + compress = options["compress"] + .doc("Include compressibility effects (evolve Vpar)?") + .withDefault(false); + gyroviscous = options["gyroviscous"].withDefault(false); + nonlinear = options["nonlinear"].doc("Include nonlinear terms?").withDefault(false); + + // option for ExB Poisson Bracket + bm_exb_flag = options["bm_exb_flag"] + .doc("ExB Poisson bracket method. 0=standard;1=simple;2=arakawa") + .withDefault(0); + switch (bm_exb_flag) { + case 0: { + bm_exb = BRACKET_STD; + output << "\tBrackets for ExB: default differencing\n"; + break; + } + case 1: { + bm_exb = BRACKET_SIMPLE; + output << "\tBrackets for ExB: simplified operator\n"; + break; + } + case 2: { + bm_exb = BRACKET_ARAKAWA; + output << "\tBrackets for ExB: Arakawa scheme\n"; + break; + } + case 3: { + bm_exb = BRACKET_CTU; + output << "\tBrackets for ExB: Corner Transport Upwind method\n"; + break; + } + default: + throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); + } - eHall = options["eHall"] + bm_mag_flag = + options["bm_mag_flag"].doc("magnetic flutter Poisson Bracket").withDefault(0); + switch (bm_mag_flag) { + case 0: { + bm_mag = BRACKET_STD; + output << "\tBrackets: default differencing\n"; + break; + } + case 1: { + bm_mag = BRACKET_SIMPLE; + output << "\tBrackets: simplified operator\n"; + break; + } + case 2: { + bm_mag = BRACKET_ARAKAWA; + output << "\tBrackets: Arakawa scheme\n"; + break; + } + case 3: { + bm_mag = BRACKET_CTU; + output << "\tBrackets: Corner Transport Upwind method\n"; + break; + } + default: + throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); + } + + eHall = options["eHall"] .doc("electron Hall or electron parallel pressue gradient effects?") .withDefault(false); - AA = options["AA"].doc("ion mass in units of proton mass").withDefault(1.0); - - diamag = options["diamag"].doc("Diamagnetic effects?").withDefault(false); - diamag_grad_t = options["diamag_grad_t"] - .doc("Grad_par(Te) term in Psi equation") - .withDefault(diamag); - diamag_phi0 = - options["diamag_phi0"].doc("Include equilibrium phi0").withDefault(diamag); - dia_fact = options["dia_fact"] - .doc("Scale diamagnetic effects by this factor") - .withDefault(1.0); - - // withflow or not - withflow = options["withflow"].withDefault(false); - // keep K-H term - K_H_term = options["K_H_term"].withDefault(true); - // velocity magnitude - D_0 = options["D_0"].withDefault(0.0); - // flowshear - D_s = options["D_s"].withDefault(0.0); - // flow location - x0 = options["x0"].withDefault(0.0); - // flow direction, -1 means negative electric field - sign = options["sign"].withDefault(1.0); - // a constant - D_min = options["D_min"].withDefault(3000.0); - - experiment_Er = options["experiment_Er"].withDefault(false); - - relax_j_vac = options["relax_j_vac"] - .doc("Relax vacuum current to zero") - .withDefault(false); - relax_j_tconst = options["relax_j_tconst"] - .doc("Time constant for relaxation of vacuum current. Alfven " - "(normalised) units") - .withDefault(0.1); - - // Toroidal filtering - filter_z = options["filter_z"] - .doc("Filter a single toroidal mode number? The mode to keep is " - "filter_z_mode.") - .withDefault(false); - filter_z_mode = options["filter_z_mode"] - .doc("Single toroidal mode number to keep") - .withDefault(1); - low_pass_z = options["low_pass_z"].doc("Low-pass filter").withDefault(-1); - zonal_flow = options["zonal_flow"] - .doc("Keep zonal (n=0) component of potential?") - .withDefault(false); - zonal_field = options["zonal_field"] - .doc("Keep zonal (n=0) component of magnetic potential?") - .withDefault(false); - zonal_bkgd = options["zonal_bkgd"] - .doc("Evolve zonal (n=0) pressure profile?") - .withDefault(false); - - // n = 0 electrostatic potential solve - split_n0 = options["split_n0"] - .doc("Solve zonal (n=0) component of potential using LaplaceXY?") - .withDefault(false); - if (split_n0) { - // Create an XY solver for n=0 component + AA = options["AA"].doc("ion mass in units of proton mass").withDefault(1.0); + + diamag = options["diamag"].doc("Diamagnetic effects?").withDefault(false); + diamag_grad_t = options["diamag_grad_t"] + .doc("Grad_par(Te) term in Psi equation") + .withDefault(diamag); + diamag_phi0 = + options["diamag_phi0"].doc("Include equilibrium phi0").withDefault(diamag); + dia_fact = options["dia_fact"] + .doc("Scale diamagnetic effects by this factor") + .withDefault(1.0); + + // withflow or not + withflow = options["withflow"].withDefault(false); + // keep K-H term + K_H_term = options["K_H_term"].withDefault(true); + // velocity magnitude + D_0 = options["D_0"].withDefault(0.0); + // flowshear + D_s = options["D_s"].withDefault(0.0); + // flow location + x0 = options["x0"].withDefault(0.0); + // flow direction, -1 means negative electric field + sign = options["sign"].withDefault(1.0); + // a constant + D_min = options["D_min"].withDefault(3000.0); + + experiment_Er = options["experiment_Er"].withDefault(false); + + relax_j_vac = options["relax_j_vac"] + .doc("Relax vacuum current to zero") + .withDefault(false); + relax_j_tconst = options["relax_j_tconst"] + .doc("Time constant for relaxation of vacuum current. Alfven " + "(normalised) units") + .withDefault(0.1); + + // Toroidal filtering + filter_z = options["filter_z"] + .doc("Filter a single toroidal mode number? The mode to keep is " + "filter_z_mode.") + .withDefault(false); + filter_z_mode = options["filter_z_mode"] + .doc("Single toroidal mode number to keep") + .withDefault(1); + low_pass_z = options["low_pass_z"].doc("Low-pass filter").withDefault(-1); + zonal_flow = options["zonal_flow"] + .doc("Keep zonal (n=0) component of potential?") + .withDefault(false); + zonal_field = options["zonal_field"] + .doc("Keep zonal (n=0) component of magnetic potential?") + .withDefault(false); + zonal_bkgd = options["zonal_bkgd"] + .doc("Evolve zonal (n=0) pressure profile?") + .withDefault(false); + + // n = 0 electrostatic potential solve + split_n0 = options["split_n0"] + .doc("Solve zonal (n=0) component of potential using LaplaceXY?") + .withDefault(false); + if (split_n0) { + // Create an XY solver for n=0 component #if BOUT_HAS_HYPRE - laplacexy = bout::utils::make_unique(mesh); + laplacexy = bout::utils::make_unique(mesh); #else - laplacexy = bout::utils::make_unique(mesh); + laplacexy = bout::utils::make_unique(mesh); #endif - // Set coefficients for Boussinesq solve - laplacexy->setCoefs(1.0, 0.0); - phi2D = 0.0; // Starting guess - phi2D.setBoundary("phi"); + // Set coefficients for Boussinesq solve + laplacexy->setCoefs(1.0, 0.0); + phi2D = 0.0; // Starting guess + phi2D.setBoundary("phi"); } // Radial smoothing @@ -1225,675 +1227,675 @@ class ELMpb : public PhysicsModel { rmp_Psi = (t / rmp_ramp) * rmp_Psi0; // Linear ramp rmp_dApdt = rmp_Psi0 / rmp_ramp; - } else { - rmp_Psi = rmp_Psi0; - rmp_dApdt = 0.0; - } + } else { + rmp_Psi = rmp_Psi0; + rmp_dApdt = 0.0; + } - if (rmp_freq > 0.0) { - // Oscillating the amplitude + if (rmp_freq > 0.0) { + // Oscillating the amplitude - rmp_dApdt = rmp_dApdt * sin(2. * PI * rmp_freq * t) - + rmp_Psi * (2. * PI * rmp_freq) * cos(2. * PI * rmp_freq * t); + rmp_dApdt = rmp_dApdt * sin(2. * PI * rmp_freq * t) + + rmp_Psi * (2. * PI * rmp_freq) * cos(2. * PI * rmp_freq * t); - rmp_Psi *= sin(2. * PI * rmp_freq * t); - } + rmp_Psi *= sin(2. * PI * rmp_freq * t); + } - if (rmp_rotate != 0.0) { - // Rotate toroidally at given frequency + if (rmp_rotate != 0.0) { + // Rotate toroidally at given frequency - shiftZ(rmp_Psi, 2 * PI * rmp_rotate * t); - shiftZ(rmp_dApdt, 2 * PI * rmp_rotate * t); + shiftZ(rmp_Psi, 2 * PI * rmp_rotate * t); + shiftZ(rmp_dApdt, 2 * PI * rmp_rotate * t); - // Add toroidal rotation term. CHECK SIGN + // Add toroidal rotation term. CHECK SIGN - rmp_dApdt += DDZ(rmp_Psi) * 2 * PI * rmp_rotate; - } + rmp_dApdt += DDZ(rmp_Psi) * 2 * PI * rmp_rotate; + } - // Set to zero in the core - if (rmp_vac_mask) { - rmp_Psi *= vac_mask; - } - } else { - // Set to zero in the core region - if (rmp_vac_mask) { - // Only in vacuum -> skin current -> diffuses inwards - rmp_Psi = rmp_Psi0 * vac_mask; + // Set to zero in the core + if (rmp_vac_mask) { + rmp_Psi *= vac_mask; + } + } else { + // Set to zero in the core region + if (rmp_vac_mask) { + // Only in vacuum -> skin current -> diffuses inwards + rmp_Psi = rmp_Psi0 * vac_mask; + } + } + + mesh->communicate(rmp_Psi); } - } - mesh->communicate(rmp_Psi); - } + //////////////////////////////////////////// + // Inversion - //////////////////////////////////////////// - // Inversion + if (evolve_jpar) { + // Invert laplacian for Psi + Psi = aparSolver->solve(Jpar); + mesh->communicate(Psi); + } - if (evolve_jpar) { - // Invert laplacian for Psi - Psi = aparSolver->solve(Jpar); - mesh->communicate(Psi); - } + if (phi_constraint) { + // Phi being solved as a constraint - if (phi_constraint) { - // Phi being solved as a constraint + Field3D Ctmp = phi; + Ctmp.setBoundary("phi"); // Look up boundary conditions for phi + Ctmp.applyBoundary(); + Ctmp -= phi; // Now contains error in the boundary - Field3D Ctmp = phi; - Ctmp.setBoundary("phi"); // Look up boundary conditions for phi - Ctmp.applyBoundary(); - Ctmp -= phi; // Now contains error in the boundary + C_phi = Delp2(phi) - U; // Error in the bulk + C_phi.setBoundaryTo(Ctmp); - C_phi = Delp2(phi) - U; // Error in the bulk - C_phi.setBoundaryTo(Ctmp); + } else { - } else { + if (constn0) { + if (split_n0) { + //////////////////////////////////////////// + // Boussinesq, split + // Split into axisymmetric and non-axisymmetric components + Field2D Vort2D = DC(U); // n=0 component - if (constn0) { - if (split_n0) { - //////////////////////////////////////////// - // Boussinesq, split - // Split into axisymmetric and non-axisymmetric components - Field2D Vort2D = DC(U); // n=0 component + // Applies boundary condition for "phi". + phi2D.applyBoundary(t); - // Applies boundary condition for "phi". - phi2D.applyBoundary(t); + // Solve axisymmetric (n=0) part + phi2D = laplacexy->solve(Vort2D, phi2D); - // Solve axisymmetric (n=0) part - phi2D = laplacexy->solve(Vort2D, phi2D); + // Solve non-axisymmetric part + phi = phiSolver->solve(U - Vort2D); - // Solve non-axisymmetric part - phi = phiSolver->solve(U - Vort2D); + phi += phi2D; // Add axisymmetric part + } else { + phi = phiSolver->solve(U); + } - phi += phi2D; // Add axisymmetric part - } else { - phi = phiSolver->solve(U); + if (diamag) { + phi -= 0.5 * dnorm * P / B0; + } + } else { + ubyn = U / N0; + if (diamag) { + ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); + mesh->communicate(ubyn); + } + // Invert laplacian for phi + phiSolver->setCoefC(N0); + phi = phiSolver->solve(ubyn); + } + // Apply a boundary condition on phi for target plates + phi.applyBoundary(); + mesh->communicate(phi); } - if (diamag) { - phi -= 0.5 * dnorm * P / B0; - } - } else { - ubyn = U / N0; - if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); - mesh->communicate(ubyn); - } - // Invert laplacian for phi - phiSolver->setCoefC(N0); - phi = phiSolver->solve(ubyn); - } - // Apply a boundary condition on phi for target plates - phi.applyBoundary(); - mesh->communicate(phi); - } + if (!evolve_jpar) { + // Get J from Psi + Jpar = Delp2(Psi); + if (include_rmp) { + Jpar += Delp2(rmp_Psi); + } - if (!evolve_jpar) { - // Get J from Psi - Jpar = Delp2(Psi); - if (include_rmp) { - Jpar += Delp2(rmp_Psi); - } + Jpar.applyBoundary(); + mesh->communicate(Jpar); + + if (jpar_bndry_width > 0) { + // Zero j in boundary regions. Prevents vorticity drive + // at the boundary + + for (int i = 0; i < jpar_bndry_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + Jpar(i, j, k) = 0.0; + } + if (mesh->lastX()) { + Jpar(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + } + } + } + } - Jpar.applyBoundary(); - mesh->communicate(Jpar); - - if (jpar_bndry_width > 0) { - // Zero j in boundary regions. Prevents vorticity drive - // at the boundary - - for (int i = 0; i < jpar_bndry_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - Jpar(i, j, k) = 0.0; - } - if (mesh->lastX()) { - Jpar(mesh->LocalNx - 1 - i, j, k) = 0.0; - } + // Smooth j in x + if (smooth_j_x) { + Jpar = smooth_x(Jpar); + Jpar.applyBoundary(); + + // Recommunicate now smoothed + mesh->communicate(Jpar); } - } - } - } - // Smooth j in x - if (smooth_j_x) { - Jpar = smooth_x(Jpar); - Jpar.applyBoundary(); + // Get Delp2(J) from J + Jpar2 = Delp2(Jpar); - // Recommunicate now smoothed - mesh->communicate(Jpar); - } + Jpar2.applyBoundary(); + mesh->communicate(Jpar2); - // Get Delp2(J) from J - Jpar2 = Delp2(Jpar); - - Jpar2.applyBoundary(); - mesh->communicate(Jpar2); - - if (jpar_bndry_width > 0) { - // Zero jpar2 in boundary regions. Prevents vorticity drive - // at the boundary - - for (int i = 0; i < jpar_bndry_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - Jpar2(i, j, k) = 0.0; - } - if (mesh->lastX()) { - Jpar2(mesh->LocalNx - 1 - i, j, k) = 0.0; - } + if (jpar_bndry_width > 0) { + // Zero jpar2 in boundary regions. Prevents vorticity drive + // at the boundary + + for (int i = 0; i < jpar_bndry_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + Jpar2(i, j, k) = 0.0; + } + if (mesh->lastX()) { + Jpar2(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + } + } + } } - } } - } - } - //////////////////////////////////////////////////// - // Sheath boundary conditions - // Normalised and linearised, since here we have only pressure - // rather than density and temperature. Applying a boundary - // to Jpar so that Jpar = sqrt(mi/me)/(2*pi) * phi - // + //////////////////////////////////////////////////// + // Sheath boundary conditions + // Normalised and linearised, since here we have only pressure + // rather than density and temperature. Applying a boundary + // to Jpar so that Jpar = sqrt(mi/me)/(2*pi) * phi + // - if (sheath_boundaries) { + if (sheath_boundaries) { - // Need to shift into field-aligned coordinates before applying - // parallel boundary conditions + // Need to shift into field-aligned coordinates before applying + // parallel boundary conditions - auto phi_fa = toFieldAligned(phi); - auto P_fa = toFieldAligned(P); - auto Jpar_fa = toFieldAligned(Jpar); + auto phi_fa = toFieldAligned(phi); + auto P_fa = toFieldAligned(P); + auto Jpar_fa = toFieldAligned(Jpar); - // At y = ystart (lower boundary) + // At y = ystart (lower boundary) - for (RangeIterator r = mesh->iterateBndryLowerY(); !r.isDone(); r++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { + for (RangeIterator r = mesh->iterateBndryLowerY(); !r.isDone(); r++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { - // Zero-gradient potential - BoutReal const phisheath = phi_fa(r.ind, mesh->ystart, jz); + // Zero-gradient potential + BoutReal const phisheath = phi_fa(r.ind, mesh->ystart, jz); - BoutReal jsheath = -(sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; + BoutReal jsheath = -(sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; - // Apply boundary condition half-way between cells - for (int jy = mesh->ystart - 1; jy >= 0; jy--) { - // Neumann conditions - P_fa(r.ind, jy, jz) = P_fa(r.ind, mesh->ystart, jz); - phi_fa(r.ind, jy, jz) = phisheath; - // Dirichlet condition on Jpar - Jpar_fa(r.ind, jy, jz) = 2. * jsheath - Jpar_fa(r.ind, mesh->ystart, jz); - } - } - } + // Apply boundary condition half-way between cells + for (int jy = mesh->ystart - 1; jy >= 0; jy--) { + // Neumann conditions + P_fa(r.ind, jy, jz) = P_fa(r.ind, mesh->ystart, jz); + phi_fa(r.ind, jy, jz) = phisheath; + // Dirichlet condition on Jpar + Jpar_fa(r.ind, jy, jz) = 2. * jsheath - Jpar_fa(r.ind, mesh->ystart, jz); + } + } + } + + // At y = yend (upper boundary) - // At y = yend (upper boundary) + for (RangeIterator r = mesh->iterateBndryUpperY(); !r.isDone(); r++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { - for (RangeIterator r = mesh->iterateBndryUpperY(); !r.isDone(); r++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { + // Zero-gradient potential + BoutReal const phisheath = phi_fa(r.ind, mesh->yend, jz); - // Zero-gradient potential - BoutReal const phisheath = phi_fa(r.ind, mesh->yend, jz); + BoutReal jsheath = (sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; - BoutReal jsheath = (sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; + // Apply boundary condition half-way between cells + for (int jy = mesh->yend + 1; jy < mesh->LocalNy; jy++) { + // Neumann conditions + P_fa(r.ind, jy, jz) = P_fa(r.ind, mesh->yend, jz); + phi_fa(r.ind, jy, jz) = phisheath; + // Dirichlet condition on Jpar + // WARNING: this is not correct if staggered grids are used + ASSERT3(not mesh->StaggerGrids); + Jpar_fa(r.ind, jy, jz) = 2. * jsheath - Jpar_fa(r.ind, mesh->yend, jz); + } + } + } - // Apply boundary condition half-way between cells - for (int jy = mesh->yend + 1; jy < mesh->LocalNy; jy++) { - // Neumann conditions - P_fa(r.ind, jy, jz) = P_fa(r.ind, mesh->yend, jz); - phi_fa(r.ind, jy, jz) = phisheath; - // Dirichlet condition on Jpar - // WARNING: this is not correct if staggered grids are used - ASSERT3(not mesh->StaggerGrids); - Jpar_fa(r.ind, jy, jz) = 2. * jsheath - Jpar_fa(r.ind, mesh->yend, jz); - } + // Shift back from field aligned coordinates + phi = fromFieldAligned(phi_fa); + P = fromFieldAligned(P_fa); + Jpar = fromFieldAligned(Jpar_fa); } - } - // Shift back from field aligned coordinates - phi = fromFieldAligned(phi_fa); - P = fromFieldAligned(P_fa); - Jpar = fromFieldAligned(Jpar_fa); - } + //////////////////////////////////////////////////// + // Parallel electric field - //////////////////////////////////////////////////// - // Parallel electric field + if (evolve_jpar) { + // Jpar + Field3D B0U = B0 * U; + mesh->communicate(B0U); + ddt(Jpar) = -Grad_parP(B0U, loc) / B0 + eta * Delp2(Jpar); - if (evolve_jpar) { - // Jpar - Field3D B0U = B0 * U; - mesh->communicate(B0U); - ddt(Jpar) = -Grad_parP(B0U, loc) / B0 + eta * Delp2(Jpar); + if (relax_j_vac) { + // Make ddt(Jpar) relax to zero. - if (relax_j_vac) { - // Make ddt(Jpar) relax to zero. + ddt(Jpar) -= vac_mask * Jpar / relax_j_tconst; + } + } else { + // Vector potential + ddt(Psi) = -Grad_parP(phi * B0, loc) / B0 + eta * Jpar; - ddt(Jpar) -= vac_mask * Jpar / relax_j_tconst; - } - } else { - // Vector potential - ddt(Psi) = -Grad_parP(phi * B0, loc) / B0 + eta * Jpar; - - if (eHall) { // electron parallel pressure - ddt(Psi) += 0.25 * delta_i - * (Grad_parP(B0 * P, loc) / B0 - + bracket(interp_to(P0, loc), Psi, bm_mag) * B0); - } + if (eHall) { // electron parallel pressure + ddt(Psi) += 0.25 * delta_i + * (Grad_parP(B0 * P, loc) / B0 + + bracket(interp_to(P0, loc), Psi, bm_mag) * B0); + } - if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * B0; - } + if (diamag_phi0) { // Equilibrium flow + ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * B0; + } - if (withflow) { // net flow - ddt(Psi) -= V_dot_Grad(V0net, Psi); - } + if (withflow) { // net flow + ddt(Psi) -= V_dot_Grad(V0net, Psi); + } - if (diamag_grad_t) { // grad_par(T_e) correction - ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; - } + if (diamag_grad_t) { // grad_par(T_e) correction + ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; + } - if (hyperresist > 0.0) { // Hyper-resistivity - ddt(Psi) -= eta * hyperresist * Delp2(Jpar); - } + if (hyperresist > 0.0) { // Hyper-resistivity + ddt(Psi) -= eta * hyperresist * Delp2(Jpar); + } - if (ehyperviscos > 0.0) { // electron Hyper-viscosity coefficient - ddt(Psi) -= eta * ehyperviscos * Delp2(Jpar2); - } + if (ehyperviscos > 0.0) { // electron Hyper-viscosity coefficient + ddt(Psi) -= eta * ehyperviscos * Delp2(Jpar2); + } - // Parallel hyper-viscous diffusion for vector potential - if (diffusion_a4 > 0.0) { - tmpA2 = D2DY2(Psi); - mesh->communicate(tmpA2); - tmpA2.applyBoundary(); - ddt(Psi) -= diffusion_a4 * D2DY2(tmpA2); - } + // Parallel hyper-viscous diffusion for vector potential + if (diffusion_a4 > 0.0) { + tmpA2 = D2DY2(Psi); + mesh->communicate(tmpA2); + tmpA2.applyBoundary(); + ddt(Psi) -= diffusion_a4 * D2DY2(tmpA2); + } - // Vacuum solution - if (relax_j_vac) { - // Calculate the J and Psi profile we're aiming for - Field3D Jtarget = Jpar * (1.0 - vac_mask); // Zero in vacuum + // Vacuum solution + if (relax_j_vac) { + // Calculate the J and Psi profile we're aiming for + Field3D Jtarget = Jpar * (1.0 - vac_mask); // Zero in vacuum - // Invert laplacian for Psi - Field3D Psitarget = aparSolver->solve(Jtarget); + // Invert laplacian for Psi + Field3D Psitarget = aparSolver->solve(Jtarget); - // Add a relaxation term in the vacuum - ddt(Psi) = - ddt(Psi) * (1. - vac_mask) - (Psi - Psitarget) * vac_mask / relax_j_tconst; - } - } + // Add a relaxation term in the vacuum + ddt(Psi) = + ddt(Psi) * (1. - vac_mask) - (Psi - Psitarget) * vac_mask / relax_j_tconst; + } + } - //////////////////////////////////////////////////// - // Vorticity equation - Psi_loc = interp_to(Psi, CELL_CENTRE, "RGN_ALL"); - Psi_loc.applyBoundary(); - // Grad j term - ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); - if (include_rmp) { - ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); - } + //////////////////////////////////////////////////// + // Vorticity equation + Psi_loc = interp_to(Psi, CELL_CENTRE, "RGN_ALL"); + Psi_loc.applyBoundary(); + // Grad j term + ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi_loc, J0, CELL_CENTRE); + if (include_rmp) { + ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + } - ddt(U) += b0xcv * Grad(P); // curvature term + ddt(U) += b0xcv * Grad(P); // curvature term - if (!nogradparj) { // Parallel current term - ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j - } + if (!nogradparj) { // Parallel current term + ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + } - if (withflow && K_H_term) { // K_H_term - ddt(U) -= b0xGrad_dot_Grad(phi, U0); - } + if (withflow && K_H_term) { // K_H_term + ddt(U) -= b0xGrad_dot_Grad(phi, U0); + } - if (diamag_phi0) { // Equilibrium flow - ddt(U) -= b0xGrad_dot_Grad(phi0, U); - } + if (diamag_phi0) { // Equilibrium flow + ddt(U) -= b0xGrad_dot_Grad(phi0, U); + } - if (withflow) { // net flow - ddt(U) -= V_dot_Grad(V0net, U); - } + if (withflow) { // net flow + ddt(U) -= V_dot_Grad(V0net, U); + } - if (nonlinear) { // Advection - ddt(U) -= bracket(phi, U, bm_exb) * B0; - } + if (nonlinear) { // Advection + ddt(U) -= bracket(phi, U, bm_exb) * B0; + } - // Viscosity terms + // Viscosity terms - if (viscos_par > 0.0) { // Parallel viscosity - ddt(U) += viscos_par * Grad2_par2(U); - } + if (viscos_par > 0.0) { // Parallel viscosity + ddt(U) += viscos_par * Grad2_par2(U); + } - if (diffusion_u4 > 0.0) { - tmpU2 = D2DY2(U); - mesh->communicate(tmpU2); - tmpU2.applyBoundary(); - ddt(U) -= diffusion_u4 * D2DY2(tmpU2); - } + if (diffusion_u4 > 0.0) { + tmpU2 = D2DY2(U); + mesh->communicate(tmpU2); + tmpU2.applyBoundary(); + ddt(U) -= diffusion_u4 * D2DY2(tmpU2); + } - if (viscos_perp > 0.0) { - ddt(U) += viscos_perp * Delp2(U); // Perpendicular viscosity - } + if (viscos_perp > 0.0) { + ddt(U) += viscos_perp * Delp2(U); // Perpendicular viscosity + } - // Hyper-viscosity - if (hyperviscos > 0.0) { - // Calculate coefficient. + // Hyper-viscosity + if (hyperviscos > 0.0) { + // Calculate coefficient. - hyper_mu_x = hyperviscos * metric->g_11() * SQ(metric->dx()) - * abs(metric->g11() * D2DX2(U)) / (abs(U) + 1e-3); - hyper_mu_x.applyBoundary("dirichlet"); // Set to zero on all boundaries + hyper_mu_x = hyperviscos * metric->g_11() * SQ(metric->dx()) + * abs(metric->g11() * D2DX2(U)) / (abs(U) + 1e-3); + hyper_mu_x.applyBoundary("dirichlet"); // Set to zero on all boundaries - ddt(U) += hyper_mu_x * metric->g11() * D2DX2(U); + ddt(U) += hyper_mu_x * metric->g11() * D2DX2(U); - if (first_run) { // Print out maximum values of viscosity used on this processor - output.write(" Hyper-viscosity values:\n"); - output.write(" Max mu_x = {:e}, Max_DC mu_x = {:e}\n", max(hyper_mu_x), - max(DC(hyper_mu_x))); - } - } + if (first_run) { // Print out maximum values of viscosity used on this processor + output.write(" Hyper-viscosity values:\n"); + output.write(" Max mu_x = {:e}, Max_DC mu_x = {:e}\n", max(hyper_mu_x), + max(DC(hyper_mu_x))); + } + } - if (gyroviscous) { - - Field3D Pi; - Field2D Pi0; - Pi = 0.5 * P; - Pi0 = 0.5 * P0; - - Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); - Dperp2Phi0.applyBoundary(); - mesh->communicate(Dperp2Phi0); - - Dperp2Phi = Delp2(B0 * phi); - Dperp2Phi.applyBoundary(); - mesh->communicate(Dperp2Phi); - - Dperp2Pi0 = Field3D(Delp2(Pi0)); - Dperp2Pi0.applyBoundary(); - mesh->communicate(Dperp2Pi0); - - Dperp2Pi = Delp2(Pi); - Dperp2Pi.applyBoundary(); - mesh->communicate(Dperp2Pi); - - bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); - bracketPhi0P.applyBoundary(); - mesh->communicate(bracketPhi0P); - - bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); - bracketPhiP0.applyBoundary(); - mesh->communicate(bracketPhiP0); - - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - Field3D B0phi0 = B0 * phi0; - mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; - - if (nonlinear) { - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - bracketPhiP = bracket(B0phi, Pi, bm_exb); - bracketPhiP.applyBoundary(); - mesh->communicate(bracketPhiP); + if (gyroviscous) { - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; - } - } + Field3D Pi; + Field2D Pi0; + Pi = 0.5 * P; + Pi0 = 0.5 * P0; + + Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); + Dperp2Phi0.applyBoundary(); + mesh->communicate(Dperp2Phi0); + + Dperp2Phi = Delp2(B0 * phi); + Dperp2Phi.applyBoundary(); + mesh->communicate(Dperp2Phi); + + Dperp2Pi0 = Field3D(Delp2(Pi0)); + Dperp2Pi0.applyBoundary(); + mesh->communicate(Dperp2Pi0); + + Dperp2Pi = Delp2(Pi); + Dperp2Pi.applyBoundary(); + mesh->communicate(Dperp2Pi); + + bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); + bracketPhi0P.applyBoundary(); + mesh->communicate(bracketPhi0P); + + bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); + bracketPhiP0.applyBoundary(); + mesh->communicate(bracketPhiP0); + + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + Field3D B0phi0 = B0 * phi0; + mesh->communicate(B0phi0); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; - // left edge sink terms - if (sink_Ul > 0.0) { - ddt(U) -= sink_Ul * sink_tanhxl(P0, U, su_widthl, su_lengthl); // core sink - } + if (nonlinear) { + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + bracketPhiP = bracket(B0phi, Pi, bm_exb); + bracketPhiP.applyBoundary(); + mesh->communicate(bracketPhiP); + + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; + } + } - // right edge sink terms - if (sink_Ur > 0.0) { - ddt(U) -= sink_Ur * sink_tanhxr(P0, U, su_widthr, su_lengthr); // sol sink - } + // left edge sink terms + if (sink_Ul > 0.0) { + ddt(U) -= sink_Ul * sink_tanhxl(P0, U, su_widthl, su_lengthl); // core sink + } - //////////////////////////////////////////////////// - // Pressure equation + // right edge sink terms + if (sink_Ur > 0.0) { + ddt(U) -= sink_Ur * sink_tanhxr(P0, U, su_widthr, su_lengthr); // sol sink + } - ddt(P) = 0.0; - if (evolve_pressure) { - ddt(P) -= b0xGrad_dot_Grad(phi, P0); + //////////////////////////////////////////////////// + // Pressure equation - if (diamag_phi0) { // Equilibrium flow - ddt(P) -= b0xGrad_dot_Grad(phi0, P); - } + ddt(P) = 0.0; + if (evolve_pressure) { + ddt(P) -= b0xGrad_dot_Grad(phi, P0); - if (withflow) { // net flow - ddt(P) -= V_dot_Grad(V0net, P); - } + if (diamag_phi0) { // Equilibrium flow + ddt(P) -= b0xGrad_dot_Grad(phi0, P); + } - if (nonlinear) { // Advection - ddt(P) -= bracket(phi, P, bm_exb) * B0; - } - } + if (withflow) { // net flow + ddt(P) -= V_dot_Grad(V0net, P); + } - // Parallel diffusion terms + if (nonlinear) { // Advection + ddt(P) -= bracket(phi, P, bm_exb) * B0; + } + } - if (diffusion_par > 0.0) { // Parallel diffusion - ddt(P) += diffusion_par * Grad2_par2(P); - } + // Parallel diffusion terms - if (diffusion_p4 > 0.0) { // parallel hyper-viscous diffusion for pressure - tmpP2 = D2DY2(P); - mesh->communicate(tmpP2); - tmpP2.applyBoundary(); - ddt(P) = diffusion_p4 * D2DY2(tmpP2); - } + if (diffusion_par > 0.0) { // Parallel diffusion + ddt(P) += diffusion_par * Grad2_par2(P); + } - if (heating_P > 0.0) { // heating source terms - BoutReal pnorm = P0(0, 0); - ddt(P) += heating_P * source_expx2(P0, 2. * hp_width, 0.5 * hp_length) - * (Tbar / pnorm); // heat source - ddt(P) += (100. * source_tanhx(P0, hp_width, hp_length) + 0.01) * metric->g11() - * D2DX2(P) * (Tbar / Lbar / Lbar); // radial diffusion - } + if (diffusion_p4 > 0.0) { // parallel hyper-viscous diffusion for pressure + tmpP2 = D2DY2(P); + mesh->communicate(tmpP2); + tmpP2.applyBoundary(); + ddt(P) = diffusion_p4 * D2DY2(tmpP2); + } - if (sink_P > 0.0) { // sink terms - ddt(P) -= sink_P * sink_tanhxr(P0, P, sp_width, sp_length) * Tbar; // sink - } + if (heating_P > 0.0) { // heating source terms + BoutReal pnorm = P0(0, 0); + ddt(P) += heating_P * source_expx2(P0, 2. * hp_width, 0.5 * hp_length) + * (Tbar / pnorm); // heat source + ddt(P) += (100. * source_tanhx(P0, hp_width, hp_length) + 0.01) * metric->g11() + * D2DX2(P) * (Tbar / Lbar / Lbar); // radial diffusion + } - //////////////////////////////////////////////////// - // Compressional effects + if (sink_P > 0.0) { // sink terms + ddt(P) -= sink_P * sink_tanhxr(P0, P, sp_width, sp_length) * Tbar; // sink + } - if (compress) { + //////////////////////////////////////////////////// + // Compressional effects - ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); + if (compress) { - if (phi_curv) { - ddt(P) -= 2. * beta * b0xcv * Grad(phi); - } + ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); - // Vpar equation + if (phi_curv) { + ddt(P) -= 2. * beta * b0xcv * Grad(phi); + } - ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); + // Vpar equation - if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection - } - } + ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); - if (filter_z) { - // Filter out all except filter_z_mode + if (nonlinear) { + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection + } + } - if (evolve_jpar) { - ddt(Jpar) = filter(ddt(Jpar), filter_z_mode); - } else { - ddt(Psi) = filter(ddt(Psi), filter_z_mode); - } + if (filter_z) { + // Filter out all except filter_z_mode - ddt(U) = filter(ddt(U), filter_z_mode); - ddt(P) = filter(ddt(P), filter_z_mode); - } + if (evolve_jpar) { + ddt(Jpar) = filter(ddt(Jpar), filter_z_mode); + } else { + ddt(Psi) = filter(ddt(Psi), filter_z_mode); + } - if (low_pass_z > 0) { - // Low-pass filter, keeping n up to low_pass_z - if (evolve_jpar) { - ddt(Jpar) = lowPass(ddt(Jpar), low_pass_z, zonal_field); - } else { - ddt(Psi) = lowPass(ddt(Psi), low_pass_z, zonal_field); - } - ddt(U) = lowPass(ddt(U), low_pass_z, zonal_flow); - ddt(P) = lowPass(ddt(P), low_pass_z, zonal_bkgd); - } + ddt(U) = filter(ddt(U), filter_z_mode); + ddt(P) = filter(ddt(P), filter_z_mode); + } - if (damp_width > 0) { - for (int i = 0; i < damp_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - ddt(U)(i, j, k) -= U(i, j, k) / damp_t_const; + if (low_pass_z > 0) { + // Low-pass filter, keeping n up to low_pass_z + if (evolve_jpar) { + ddt(Jpar) = lowPass(ddt(Jpar), low_pass_z, zonal_field); + } else { + ddt(Psi) = lowPass(ddt(Psi), low_pass_z, zonal_field); } - if (mesh->lastX()) { - ddt(U)(mesh->LocalNx - 1 - i, j, k) -= - U(mesh->LocalNx - 1 - i, j, k) / damp_t_const; + ddt(U) = lowPass(ddt(U), low_pass_z, zonal_flow); + ddt(P) = lowPass(ddt(P), low_pass_z, zonal_bkgd); + } + + if (damp_width > 0) { + for (int i = 0; i < damp_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + ddt(U)(i, j, k) -= U(i, j, k) / damp_t_const; + } + if (mesh->lastX()) { + ddt(U)(mesh->LocalNx - 1 - i, j, k) -= + U(mesh->LocalNx - 1 - i, j, k) / damp_t_const; + } + } + } } - } } - } - } - first_run = false; + first_run = false; - return 0; - } + return 0; + } - /******************************************************************************* - * Preconditioner - * - * o System state in variables (as in rhs function) - * o Values to be inverted in time derivatives - * - * o Return values should be in time derivatives - * - * enable by setting solver / use_precon = true in BOUT.inp - *******************************************************************************/ - - int precon(BoutReal UNUSED(t), BoutReal gamma, BoutReal UNUSED(delta)) { - // First matrix, applying L - mesh->communicate(ddt(Psi)); - Field3D Jrhs = Delp2(ddt(Psi)); - Jrhs.applyBoundary("neumann"); - - if (jpar_bndry_width > 0) { - // Boundary in jpar - if (mesh->firstX()) { - for (int i = jpar_bndry_width; i >= 0; i--) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - Jrhs(i, j, k) = 0.5 * Jrhs(i + 1, j, k); + /******************************************************************************* + * Preconditioner + * + * o System state in variables (as in rhs function) + * o Values to be inverted in time derivatives + * + * o Return values should be in time derivatives + * + * enable by setting solver / use_precon = true in BOUT.inp + *******************************************************************************/ + + int precon(BoutReal UNUSED(t), BoutReal gamma, BoutReal UNUSED(delta)) { + // First matrix, applying L + mesh->communicate(ddt(Psi)); + Field3D Jrhs = Delp2(ddt(Psi)); + Jrhs.applyBoundary("neumann"); + + if (jpar_bndry_width > 0) { + // Boundary in jpar + if (mesh->firstX()) { + for (int i = jpar_bndry_width; i >= 0; i--) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + Jrhs(i, j, k) = 0.5 * Jrhs(i + 1, j, k); + } + } + } } - } - } - } - if (mesh->lastX()) { - for (int i = mesh->LocalNx - jpar_bndry_width - 1; i < mesh->LocalNx; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - Jrhs(i, j, k) = 0.5 * Jrhs(i - 1, j, k); + if (mesh->lastX()) { + for (int i = mesh->LocalNx - jpar_bndry_width - 1; i < mesh->LocalNx; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + Jrhs(i, j, k) = 0.5 * Jrhs(i - 1, j, k); + } + } + } } - } } - } - } - mesh->communicate(Jrhs, ddt(P)); + mesh->communicate(Jrhs, ddt(P)); - Field3D U1 = ddt(U); + Field3D U1 = ddt(U); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_coordinates.Bxy; - U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); - // Second matrix, solving Alfven wave dynamics - static std::unique_ptr invU{nullptr}; - if (!invU) { - invU = InvertPar::create(); - } + // Second matrix, solving Alfven wave dynamics + static std::unique_ptr invU{nullptr}; + if (!invU) { + invU = InvertPar::create(); + } - invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * B0 * B0); - ddt(U) = invU->solve(U1); - ddt(U).applyBoundary(); - - // Third matrix, applying U - Field3D phi3 = phiSolver->solve(ddt(U)); - mesh->communicate(phi3); - phi3.applyBoundary("neumann"); - Field3D B0phi3 = B0 * phi3; - mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; - ddt(Psi).applyBoundary(); - - return 0; - } + invU->setCoefA(1.); + invU->setCoefB(-SQ(gamma) * B0 * B0); + ddt(U) = invU->solve(U1); + ddt(U).applyBoundary(); + + // Third matrix, applying U + Field3D phi3 = phiSolver->solve(ddt(U)); + mesh->communicate(phi3); + phi3.applyBoundary("neumann"); + Field3D B0phi3 = B0 * phi3; + mesh->communicate(B0phi3); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; + ddt(Psi).applyBoundary(); + + return 0; + } - /******************************************************************************* - * Jacobian-vector multiply - * - * Input - * System state is in (P, Psi, U) - * Vector v is in (F_P, F_Psi, F_U) - * Output - * Jacobian-vector multiplied Jv should be in (P, Psi, U) - * - * NOTE: EXPERIMENTAL - * enable by setting solver / use_jacobian = true in BOUT.inp - *******************************************************************************/ + /******************************************************************************* + * Jacobian-vector multiply + * + * Input + * System state is in (P, Psi, U) + * Vector v is in (F_P, F_Psi, F_U) + * Output + * Jacobian-vector multiplied Jv should be in (P, Psi, U) + * + * NOTE: EXPERIMENTAL + * enable by setting solver / use_jacobian = true in BOUT.inp + *******************************************************************************/ - int jacobian(BoutReal UNUSED(t)) { - // Communicate - mesh->communicate(ddt(P), ddt(Psi), ddt(U)); + int jacobian(BoutReal UNUSED(t)) { + // Communicate + mesh->communicate(ddt(P), ddt(Psi), ddt(U)); - phi = phiSolver->solve(ddt(U)); + phi = phiSolver->solve(ddt(U)); - Jpar = Delp2(ddt(Psi)); + Jpar = Delp2(ddt(Psi)); - mesh->communicate(phi, Jpar); + mesh->communicate(phi, Jpar); - Field3D JP = -b0xGrad_dot_Grad(phi, P0); - JP.setBoundary("P"); - JP.applyBoundary(); + Field3D JP = -b0xGrad_dot_Grad(phi, P0); + JP.setBoundary("P"); + JP.applyBoundary(); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_coordinates.Bxy; - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / B0; - JPsi.setBoundary("Psi"); - JPsi.applyBoundary(); + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + Field3D JPsi = -Grad_par(B0phi, loc) / B0; + JPsi.setBoundary("Psi"); + JPsi.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) - + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); - JU.setBoundary("U"); - JU.applyBoundary(); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) + + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + JU.setBoundary("U"); + JU.applyBoundary(); - // Put result into time-derivatives + // Put result into time-derivatives - ddt(P) = JP; - ddt(Psi) = JPsi; - ddt(U) = JU; + ddt(P) = JP; + ddt(Psi) = JPsi; + ddt(U) = JU; - return 0; - } + return 0; + } - /******************************************************************************* - * Preconditioner for when phi solved as a constraint - * Currently only possible with the IDA solver - * - * o System state in variables (as in rhs function) - * o Values to be inverted in F_vars - * - * o Return values should be in vars (overwriting system state) - *******************************************************************************/ - - int precon_phi(BoutReal UNUSED(t), BoutReal UNUSED(cj), BoutReal UNUSED(delta)) { - ddt(phi) = phiSolver->solve(C_phi - ddt(U)); - return 0; - } + /******************************************************************************* + * Preconditioner for when phi solved as a constraint + * Currently only possible with the IDA solver + * + * o System state in variables (as in rhs function) + * o Values to be inverted in F_vars + * + * o Return values should be in vars (overwriting system state) + *******************************************************************************/ + + int precon_phi(BoutReal UNUSED(t), BoutReal UNUSED(cj), BoutReal UNUSED(delta)) { + ddt(phi) = phiSolver->solve(C_phi - ddt(U)); + return 0; + } }; BOUTMAIN(ELMpb); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index c2462cffe0..fee892f501 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -252,7 +252,7 @@ class GEM : public PhysicsModel { Bbar = options["Bbar"].withDefault(Bbar); // Override in options file SAVE_ONCE(Bbar); - coord = tokamak_coordinates.make_coordinates(true, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 5de216bfb5..5df141cede 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -172,7 +172,8 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coord = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); + Coordinates* coord = mesh->getCoordinates(); // Metric tensor } }; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 09f168f4de..5cb1aa6e5f 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -15,7 +15,7 @@ int main(int argc, char** argv) { calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coord = tokamak_coordinates.make_coordinates(true, 1.0, 1.0); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, 1.0, 1.0); } /////////////////////////////////////// diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index af7295b1f3..1ff52a926b 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -18,7 +18,9 @@ class WaveTest : public PhysicsModel { int init(bool UNUSED(restarting)) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - const auto& coords = tokamak_coordinates.make_coordinates(true, 1.0, 1.0); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, 1.0, 1.0); + + auto* coords = mesh->getCoordinates(); solver->add(f, "f"); solver->add(g, "g"); diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 775ce6401c..1c40d8f4ef 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -48,8 +48,8 @@ BoutReal get_sign_of_bp(Field2D Bpxy) { return 1.0; } -Coordinates* make_coordinates(Mesh& mesh, const bool noshear, BoutReal Lbar, - BoutReal Bbar, BoutReal ShearFactor = 1.0) { +void set_tokamak_coordinates_on_mesh(TokamakCoordinates& tokamakCoordinates, Mesh& mesh, const bool noshear, + BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor = 1.0) { tokamakCoordinates.normalise(Lbar, Bbar, ShearFactor); diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index eb14696cc4..b480bce11d 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -316,7 +316,7 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - coords = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index a4881838c1..70c0d65112 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -389,7 +389,7 @@ class ELMpb : public PhysicsModel { noshear = true; } - coords = tokamak_coordinates.make_coordinates(noshear, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index a22a574969..5ee1e1b865 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -46,7 +46,9 @@ class TokamakMMS : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_coordinates = TokamakCoordinates(*mesh); - auto coords = tokamak_coordinates.make_coordinates(true, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); + + Coordinates* coords = mesh->getCoordinates(); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 121c0ef5b6..c3a5a27eea 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -193,7 +193,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 92ae050d00..9b22b79ef9 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -100,7 +100,7 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } - coord = tokamak_coordinates.make_coordinates(noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); if (ShiftXderivs) { b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index a25c92baae..245472875f 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -18,5 +18,5 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { } auto tokamak_coordinates = TokamakCoordinates(*mesh); - auto coords = tokamak_coordinates.make_coordinates(noshear, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); } From 2ee750f49955fb8cb2d0ae0b53ed0f43deaac6b5 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 15 Jan 2025 10:34:07 +0000 Subject: [PATCH 90/98] Restore mesh->getCoordinates() calls since TokamakCoordinates function now doesn't return Coordinates. --- examples/6field-simple/elm_6f.cxx | 3 +++ examples/conducting-wall-mode/cwm.cxx | 3 +++ examples/constraints/alfven-wave/alfven.cxx | 3 +++ examples/dalf3/dalf3.cxx | 2 ++ examples/elm-pb-outerloop/elm_pb_outerloop.cxx | 1 + examples/elm-pb/elm_pb.cxx | 2 +- examples/gyro-gem/gem.cxx | 1 + examples/laplacexy/laplace_perp/test.cxx | 1 + tests/integrated/test-drift-instability/2fluid.cxx | 1 + tests/integrated/test-interchange-instability/2fluid.cxx | 1 + tests/integrated/test-laplacexy/loadmetric.cxx | 1 + 11 files changed, 18 insertions(+), 1 deletion(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index feaefccb60..65365f8d9f 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -378,6 +378,9 @@ class Elm_6f : public PhysicsModel { bool noshear; + // Get the metric tensor + Coordinates* coord = mesh->getCoordinates(); + output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 4e8f6a2cae..638208f6e4 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -62,6 +62,9 @@ class CWM : public PhysicsModel { // Load 2D profiles (set to zero if not found) GRID_LOAD(Ni0, Te0); + coord = mesh->getCoordinates(); + + // Load normalisation values GRID_LOAD(Te_x, Ni_x, bmag); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index c88e3603aa..24f0f41eea 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -160,6 +160,9 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { + // Get the coordinates object + Coordinates* coord = mesh->getCoordinates(); + bool noshear; // Check type of parallel transform diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index c938410595..bb40d6fd4e 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -154,6 +154,8 @@ class DALF3 : public PhysicsModel { return 1; } + Coordinates* coord = mesh->getCoordinates(); + // SHIFTED RADIAL COORDINATES // Check type of parallel transform diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 3848b654d5..02218be8db 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -357,6 +357,7 @@ class ELMpb : public PhysicsModel { // Note: The rhs() function needs to be public so that RAJA can use CUDA int init(bool restarting) override { + Coordinates* metric = mesh->getCoordinates(); output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 05d94afa6d..8d61f44d9a 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -300,7 +300,7 @@ class ELMpb : public PhysicsModel { bool noshear; - Coordinates *metric = mesh->getCoordinates(); + Coordinates* metric = mesh->getCoordinates(); output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index fee892f501..9930f99b5f 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -345,6 +345,7 @@ class GEM : public PhysicsModel { output << "\tNormalised rho_e = " << rho_e << endl; output << "\tNormalised rho_i = " << rho_i << endl; + coord = mesh->getCoordinates(); // Set B field vector B0vec.covariant = false; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 5cb1aa6e5f..c0aabc1f01 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -18,6 +18,7 @@ int main(int argc, char** argv) { set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, 1.0, 1.0); } + Coordinates* coord = mesh->getCoordinates(); /////////////////////////////////////// // Read an analytic input diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index c3a5a27eea..c564cac2eb 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -86,6 +86,7 @@ class TwoFluid : public PhysicsModel { b0xcv.covariant = false; // Read contravariant components mesh->get(b0xcv, "bxcv"); // b0xkappa terms + coord = mesh->getCoordinates(); // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 9b22b79ef9..b5327b73bb 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -54,6 +54,7 @@ class Interchange : public PhysicsModel { b0xcv *= -1.0; // NOTE: THIS IS FOR 'OLD' GRID FILES ONLY + coord = mesh->getCoordinates(); // Load normalisation values GRID_LOAD(Te_x); GRID_LOAD(Ti_x); diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 245472875f..d34209f998 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -7,6 +7,7 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { bool noshear; auto mesh = bout::globals::mesh; + auto coords = mesh->getCoordinates(); // Calculate metric components std::string ptstr; From 3e88db42ca24d9ea5dfa1adca9046b5ad91e1f28 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Wed, 15 Jan 2025 14:56:10 +0000 Subject: [PATCH 91/98] Rename struct TokamakCoordinates to TokamakOptions --- examples/6field-simple/elm_6f.cxx | 24 ++-- examples/conducting-wall-mode/cwm.cxx | 12 +- examples/constraints/alfven-wave/alfven.cxx | 4 +- examples/dalf3/dalf3.cxx | 6 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 28 ++-- examples/elm-pb/elm_pb.cxx | 128 +++++++++--------- examples/gyro-gem/gem.cxx | 8 +- examples/laplacexy/alfven-wave/alfven.cxx | 4 +- examples/laplacexy/laplace_perp/test.cxx | 4 +- examples/wave-slab/wave_slab.cxx | 4 +- include/bout/coordinates.hxx | 4 +- include/bout/tokamak_coordinates.hxx | 44 +++--- tests/MMS/GBS/gbs.cxx | 4 +- tests/MMS/elm-pb/elm_pb.cxx | 6 +- tests/MMS/tokamak/tokamak.cxx | 4 +- .../test-drift-instability/2fluid.cxx | 6 +- .../test-interchange-instability/2fluid.cxx | 6 +- .../integrated/test-laplacexy/loadmetric.cxx | 4 +- 18 files changed, 150 insertions(+), 150 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 65365f8d9f..185f795e06 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -235,7 +235,7 @@ class Elm_6f : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); BoutReal LnLambda; // ln(Lambda) @@ -366,7 +366,7 @@ class Elm_6f : public PhysicsModel { result = Grad_par(f, loc); if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * tokamak_coordinates.Bxy; + result -= bracket(Psi, f, bm_mag) * tokamak_options.Bxy; } } @@ -681,7 +681,7 @@ class Elm_6f : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } @@ -691,7 +691,7 @@ class Elm_6f : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } @@ -835,11 +835,11 @@ class Elm_6f : public PhysicsModel { dump.add(sp_length, "sp_length", 1); } - auto Bpxy = tokamak_coordinates.Bpxy; - auto hthe = tokamak_coordinates.hthe; - auto Rxy = tokamak_coordinates.Rxy; - auto Btxy = tokamak_coordinates.Btxy; - auto B0 = tokamak_coordinates.Bxy; + auto Bpxy = tokamak_options.Bpxy; + auto hthe = tokamak_options.hthe; + auto Rxy = tokamak_options.Rxy; + auto Btxy = tokamak_options.Btxy; + auto B0 = tokamak_options.Bxy; J0 = SI::mu0 * Lbar * J0 / B0; P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); @@ -1034,14 +1034,14 @@ class Elm_6f : public PhysicsModel { } /**************** CALCULATE METRICS ******************/ - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_coordinates.ShearFactor); + coord->setIntShiftTorsion(tokamak_options.I); } // Set B field vector @@ -1224,7 +1224,7 @@ class Elm_6f : public PhysicsModel { // Field2D lap_temp=0.0; Field2D logn0 = laplace_alpha * N0; - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; ubyn = U * B0 / N0; if (diamag) { diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 638208f6e4..3c17b2c3e4 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -121,7 +121,7 @@ class CWM : public PhysicsModel { hthe0 / rho_s); } - auto tokamak_coordinates = TokamakCoordinates(*mesh); + auto tokamak_options = TokamakOptions(*mesh); /************** NORMALISE QUANTITIES *****************/ @@ -132,7 +132,7 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); @@ -143,10 +143,10 @@ class CWM : public PhysicsModel { // add evolving variables to the communication object SOLVE_FOR(rho, te); - Field2D Rxy = tokamak_coordinates.Rxy; - Field2D Bpxy = tokamak_coordinates.Bpxy; - Field2D Btxy = tokamak_coordinates.Btxy; - Field2D hthe = tokamak_coordinates.hthe; + Field2D Rxy = tokamak_options.Rxy; + Field2D Bpxy = tokamak_options.Bpxy; + Field2D Btxy = tokamak_options.Btxy; + Field2D hthe = tokamak_options.hthe; SAVE_ONCE(Rxy, Bpxy, Btxy, Zxy, hthe); SAVE_ONCE(nu_hat, hthe0); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 24f0f41eea..dfad393ded 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -173,8 +173,8 @@ class Alfven : public PhysicsModel { noshear = true; } - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, Lnorm, Bnorm); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, Lnorm, Bnorm); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index bb40d6fd4e..e70c15cf87 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -81,7 +81,7 @@ class DALF3 : public PhysicsModel { std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) Field2D phi2D; // Axisymmetric potential, used when split_n0=true - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); protected: int init(bool UNUSED(restarting)) override { @@ -164,7 +164,7 @@ class DALF3 : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; noshear = true; } @@ -224,7 +224,7 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, Bnorm); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 02218be8db..27862af4d3 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -288,7 +288,7 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass @@ -717,13 +717,13 @@ class ELMpb : public PhysicsModel { if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale Lbar = 1.0; } - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); - auto Bpxy = tokamak_coordinates.Bpxy; - auto hthe = tokamak_coordinates.hthe; - auto Rxy = tokamak_coordinates.Rxy; - auto Btxy = tokamak_coordinates.Btxy; - auto B0 = tokamak_coordinates.Bxy; + auto Bpxy = tokamak_options.Bpxy; + auto hthe = tokamak_options.hthe; + auto Rxy = tokamak_options.Rxy; + auto Btxy = tokamak_options.Btxy; + auto B0 = tokamak_options.Bxy; V0 = -Rxy * Bpxy * Dphi0 / B0; @@ -820,7 +820,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } @@ -830,7 +830,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } @@ -1216,7 +1216,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor); + metric->setIntShiftTorsion(tokamak_options.ShearFactor); } return 0; @@ -1231,7 +1231,7 @@ class ELMpb : public PhysicsModel { Field3D result = Grad_par(f, loc); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; if (nonlinear) { result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; @@ -1252,7 +1252,7 @@ class ELMpb : public PhysicsModel { Coordinates* metric = mesh->getCoordinates(); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; //////////////////////////////////////////// // Transitions from 0 in core to 1 in vacuum @@ -1999,7 +1999,7 @@ class ELMpb : public PhysicsModel { Field3D U1 = ddt(U); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); @@ -2053,7 +2053,7 @@ class ELMpb : public PhysicsModel { JP.setBoundary("P"); JP.applyBoundary(); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; Field3D B0phi = B0 * phi; mesh->communicate(B0phi); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 8d61f44d9a..a94e1e95a5 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -230,7 +230,7 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass @@ -336,8 +336,8 @@ class ELMpb : public PhysicsModel { Psi_loc.setBoundary("Psi_loc"); ////////////////////////////////////////////////////////////// - auto &globalOptions = Options::root(); - auto &options = globalOptions["highbeta"]; + auto& globalOptions = Options::root(); + auto& options = globalOptions["highbeta"]; constn0 = options["constn0"].withDefault(true); // use the hyperbolic profile of n0. If both n0_fake_prof and @@ -647,11 +647,11 @@ class ELMpb : public PhysicsModel { Dphi0 *= -1; } - auto Bpxy = tokamak_coordinates.Bpxy; - auto hthe = tokamak_coordinates.hthe; - auto Rxy = tokamak_coordinates.Rxy; - auto Btxy = tokamak_coordinates.Btxy; - auto B0 = tokamak_coordinates.Bxy; + auto Bpxy = tokamak_options.Bpxy; + auto hthe = tokamak_options.hthe; + auto Rxy = tokamak_options.Rxy; + auto Btxy = tokamak_options.Btxy; + auto B0 = tokamak_options.Bxy; V0 = -Rxy * Bpxy * Dphi0 / B0; @@ -748,7 +748,7 @@ class ELMpb : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } @@ -758,7 +758,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } @@ -884,14 +884,14 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_coordinates.ShearFactor); + metric->setIntShiftTorsion(tokamak_options.ShearFactor); } if (constn0) { @@ -1158,76 +1158,76 @@ class ELMpb : public PhysicsModel { return 0; } - // Parallel gradient along perturbed field-line - Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) const { + // Parallel gradient along perturbed field-line + Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) const { - if (loc == CELL_DEFAULT) { - loc = f.getLocation(); - } + if (loc == CELL_DEFAULT) { + loc = f.getLocation(); + } - Field3D result = Grad_par(f, loc); + Field3D result = Grad_par(f, loc); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; - if (nonlinear) { - result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; + if (nonlinear) { + result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; - if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; - } - } + if (include_rmp) { + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; + } + } - return result; - } + return result; + } - bool first_run = true; // For printing out some diagnostics first time around + bool first_run = true; // For printing out some diagnostics first time around - int rhs(BoutReal t) override { - // Perform communications - mesh->communicate(comms); + int rhs(BoutReal t) override { + // Perform communications + mesh->communicate(comms); - Coordinates* metric = mesh->getCoordinates(); + Coordinates *metric = mesh->getCoordinates(); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; - //////////////////////////////////////////// - // Transitions from 0 in core to 1 in vacuum - if (nonlinear) { - vac_mask = (1.0 - tanh(((P0 + P) - vacuum_pressure) / vacuum_trans)) / 2.0; + //////////////////////////////////////////// + // Transitions from 0 in core to 1 in vacuum + if (nonlinear) { + vac_mask = (1.0 - tanh(((P0 + P) - vacuum_pressure) / vacuum_trans)) / 2.0; - // Update resistivity - if (spitzer_resist) { - // Use Spitzer formula - Field3D Te; - Te = (P0 + P) * Bbar * Bbar / (4. * MU0) / (density * 1.602e-19); // eV + // Update resistivity + if (spitzer_resist) { + // Use Spitzer formula + Field3D Te; + Te = (P0 + P) * Bbar * Bbar / (4. * MU0) / (density * 1.602e-19); // eV - // eta in Ohm-m. ln(Lambda) = 20 - eta = interp_to(0.51 * 1.03e-4 * Zeff * 20. * pow(Te, -1.5), loc); + // eta in Ohm-m. ln(Lambda) = 20 + eta = interp_to(0.51 * 1.03e-4 * Zeff * 20. * pow(Te, -1.5), loc); - // Normalised eta - eta /= MU0 * Va * Lbar; - } else { - // Use specified core and vacuum Lundquist numbers - eta = core_resist + (vac_resist - core_resist) * vac_mask; - } - eta = interp_to(eta, loc); - } + // Normalised eta + eta /= MU0 * Va * Lbar; + } else { + // Use specified core and vacuum Lundquist numbers + eta = core_resist + (vac_resist - core_resist) * vac_mask; + } + eta = interp_to(eta, loc); + } - //////////////////////////////////////////// - // Resonant Magnetic Perturbation code + //////////////////////////////////////////// + // Resonant Magnetic Perturbation code - if (include_rmp) { + if (include_rmp) { - if ((rmp_ramp > 0.0) || (rmp_freq > 0.0) || (rmp_rotate != 0.0)) { - // Need to update the RMP terms + if ((rmp_ramp > 0.0) || (rmp_freq > 0.0) || (rmp_rotate != 0.0)) { + // Need to update the RMP terms - if ((rmp_ramp > 0.0) && (t < rmp_ramp)) { - // Still in ramp phase + if ((rmp_ramp > 0.0) && (t < rmp_ramp)) { + // Still in ramp phase - rmp_Psi = (t / rmp_ramp) * rmp_Psi0; // Linear ramp + rmp_Psi = (t / rmp_ramp) * rmp_Psi0; // Linear ramp - rmp_dApdt = rmp_Psi0 / rmp_ramp; - } else { + rmp_dApdt = rmp_Psi0 / rmp_ramp; + } else { rmp_Psi = rmp_Psi0; rmp_dApdt = 0.0; } @@ -1806,7 +1806,7 @@ class ELMpb : public PhysicsModel { Field3D U1 = ddt(U); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); @@ -1860,7 +1860,7 @@ class ELMpb : public PhysicsModel { JP.setBoundary("P"); JP.applyBoundary(); - auto B0 = tokamak_coordinates.Bxy; + auto B0 = tokamak_options.Bxy; Field3D B0phi = B0 * phi; mesh->communicate(B0phi); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 9930f99b5f..61e395520a 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -242,17 +242,17 @@ class GEM : public PhysicsModel { Tbar = options["Tbar"].withDefault(Tbar); // Override in options file SAVE_ONCE(Tbar); // Timescale in seconds - auto tokamak_coordinates = TokamakCoordinates(*mesh); + auto tokamak_options = TokamakOptions(*mesh); if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { - Bbar = max(tokamak_coordinates.Bxy, true); + Bbar = max(tokamak_options.Bxy, true); } } Bbar = options["Bbar"].withDefault(Bbar); // Override in options file SAVE_ONCE(Bbar); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); @@ -350,7 +350,7 @@ class GEM : public PhysicsModel { B0vec.covariant = false; B0vec.x = 0.; - B0vec.y = tokamak_coordinates.Bpxy / tokamak_coordinates.hthe; + B0vec.y = tokamak_options.Bpxy / tokamak_options.hthe; B0vec.z = 0.; // Precompute this for use in RHS diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index 5df141cede..b71699ae14 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -171,8 +171,8 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); Coordinates* coord = mesh->getCoordinates(); // Metric tensor } }; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index c0aabc1f01..3079d7ca9a 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -14,8 +14,8 @@ int main(int argc, char** argv) { bool calc_metric; calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, 1.0, 1.0); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, 1.0, 1.0); } Coordinates* coord = mesh->getCoordinates(); diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 1ff52a926b..b7277e0b6c 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -17,8 +17,8 @@ class WaveTest : public PhysicsModel { public: int init(bool UNUSED(restarting)) { - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, 1.0, 1.0); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, 1.0, 1.0); auto* coords = mesh->getCoordinates(); diff --git a/include/bout/coordinates.hxx b/include/bout/coordinates.hxx index 954f65d272..4ae3ac0740 100644 --- a/include/bout/coordinates.hxx +++ b/include/bout/coordinates.hxx @@ -500,9 +500,9 @@ private: /* /// Standard coordinate system for tokamak simulations -class TokamakCoordinates : public Coordinates { +class TokamakOptions : public Coordinates { public: - TokamakCoordinates(Mesh *mesh) : Coordinates(mesh) { + TokamakOptions(Mesh *mesh) : Coordinates(mesh) { } private: diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 1c40d8f4ef..85f6d3a48a 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -10,7 +10,7 @@ #include "bout/utils.hxx" #include "bout/vector2d.hxx" -struct TokamakCoordinates { +struct TokamakOptions { Field2D Rxy; Field2D Bpxy; Field2D Btxy; @@ -19,7 +19,7 @@ struct TokamakCoordinates { FieldMetric ShearFactor; FieldMetric dx; - TokamakCoordinates(Mesh &mesh) { + TokamakOptions(Mesh& mesh) { mesh.get(Rxy, "Rxy"); // mesh->get(Zxy, "Zxy"); mesh.get(Bpxy, "Bpxy"); @@ -48,12 +48,12 @@ BoutReal get_sign_of_bp(Field2D Bpxy) { return 1.0; } -void set_tokamak_coordinates_on_mesh(TokamakCoordinates& tokamakCoordinates, Mesh& mesh, const bool noshear, - BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor = 1.0) { +void set_tokamak_coordinates_on_mesh(TokamakOptions& tokamak_options, Mesh& mesh, const bool noshear, BoutReal Lbar, + BoutReal Bbar, BoutReal ShearFactor = 1.0) { - tokamakCoordinates.normalise(Lbar, Bbar, ShearFactor); + tokamak_options.normalise(Lbar, Bbar, ShearFactor); - const BoutReal sign_of_bp = get_sign_of_bp(tokamakCoordinates.Bpxy); + const BoutReal sign_of_bp = get_sign_of_bp(tokamak_options.Bpxy); if (noshear) { ShearFactor = 0.0; @@ -61,31 +61,31 @@ void set_tokamak_coordinates_on_mesh(TokamakCoordinates& tokamakCoordinates, Mes auto *coord = mesh.getCoordinates(); - const auto g11 = SQ(tokamakCoordinates.Rxy * tokamakCoordinates.Bpxy); - const auto g22 = 1.0 / SQ(tokamakCoordinates.hthe); - const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamakCoordinates.Bxy) / g11; + const auto g11 = SQ(tokamak_options.Rxy * tokamak_options.Bpxy); + const auto g22 = 1.0 / SQ(tokamak_options.hthe); + const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamak_options.Bxy) / g11; const auto g12 = 0.0; const auto g13 = -ShearFactor * g11; - const auto g23 = -sign_of_bp * tokamakCoordinates.Btxy / - (tokamakCoordinates.hthe * tokamakCoordinates.Bpxy * tokamakCoordinates.Rxy); + const auto g23 = -sign_of_bp * tokamak_options.Btxy / + (tokamak_options.hthe * tokamak_options.Bpxy * tokamak_options.Rxy); - const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamakCoordinates.Rxy); - const auto g_22 = SQ(tokamakCoordinates.Bxy * tokamakCoordinates.hthe / tokamakCoordinates.Bpxy); - const auto g_33 = tokamakCoordinates.Rxy * tokamakCoordinates.Rxy; + const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamak_options.Rxy); + const auto g_22 = SQ(tokamak_options.Bxy * tokamak_options.hthe / tokamak_options.Bpxy); + const auto g_33 = tokamak_options.Rxy * tokamak_options.Rxy; const auto g_12 = - sign_of_bp * tokamakCoordinates.Btxy * tokamakCoordinates.hthe * ShearFactor * tokamakCoordinates.Rxy / - tokamakCoordinates.Bpxy; - const auto g_13 = ShearFactor * tokamakCoordinates.Rxy * tokamakCoordinates.Rxy; - const auto g_23 = sign_of_bp * tokamakCoordinates.Btxy * tokamakCoordinates.hthe * tokamakCoordinates.Rxy / - tokamakCoordinates.Bpxy; + sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * ShearFactor * tokamak_options.Rxy / + tokamak_options.Bpxy; + const auto g_13 = ShearFactor * tokamak_options.Rxy * tokamak_options.Rxy; + const auto g_23 = sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * tokamak_options.Rxy / + tokamak_options.Bpxy; coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - coord->setJ(tokamakCoordinates.hthe / tokamakCoordinates.Bpxy); - coord->setBxy(tokamakCoordinates.Bxy); - coord->setDx(tokamakCoordinates.dx); + coord->setJ(tokamak_options.hthe / tokamak_options.Bpxy); + coord->setBxy(tokamak_options.Bxy); + coord->setDx(tokamak_options.dx); } #endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index b480bce11d..e5ebf2fa92 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -315,8 +315,8 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 70c0d65112..7de2451947 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -122,7 +122,7 @@ class ELMpb : public PhysicsModel { // Communication objects FieldGroup comms; - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); // Parallel gradient along perturbed field-line const Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) { @@ -296,7 +296,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_coordinates.get_ShearFactor() * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } } } @@ -389,7 +389,7 @@ class ELMpb : public PhysicsModel { noshear = true; } - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index 5ee1e1b865..b80f18d863 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -45,8 +45,8 @@ class TokamakMMS : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); Coordinates* coords = mesh->getCoordinates(); } diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index c564cac2eb..427ec14981 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -59,7 +59,7 @@ class TwoFluid : public PhysicsModel { FieldGroup comms; // Group of variables for communications - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); Coordinates* coord; // Coordinate system @@ -135,7 +135,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; noshear = true; } @@ -194,7 +194,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index b5327b73bb..884333faa1 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -34,7 +34,7 @@ class Interchange : public PhysicsModel { Coordinates* coord; - TokamakCoordinates tokamak_coordinates = TokamakCoordinates(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); protected: int init(bool UNUSED(restarting)) override { @@ -101,10 +101,10 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); if (ShiftXderivs) { - b0xcv.z += tokamak_coordinates.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; } /************** NORMALISE QUANTITIES *****************/ diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index d34209f998..addbd6ec54 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -18,6 +18,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { noshear = true; } - auto tokamak_coordinates = TokamakCoordinates(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_coordinates, *mesh, true, Lnorm, Bnorm); + auto tokamak_options = TokamakOptions(*mesh); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); } From dd0cff9885b936fa782c50fce94d935869f0f947 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 17 Feb 2025 16:06:59 +0000 Subject: [PATCH 92/98] Fix naming clash (Rename 'ShearFactor' back to 'I') --- examples/6field-simple/elm_6f.cxx | 4 +- examples/dalf3/dalf3.cxx | 2 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 96 +++++++++---------- examples/elm-pb/elm_pb.cxx | 4 +- include/bout/tokamak_coordinates.hxx | 8 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- .../test-drift-instability/2fluid.cxx | 2 +- 7 files changed, 58 insertions(+), 60 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 185f795e06..fb5a73f968 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -681,7 +681,7 @@ class Elm_6f : public PhysicsModel { if (noshear) { if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.I * b0xcv.x; } } @@ -691,7 +691,7 @@ class Elm_6f : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.I * b0xcv.x; } } diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index e70c15cf87..d9cbe30669 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -164,7 +164,7 @@ class DALF3 : public PhysicsModel { if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.I * b0xcv.x; noshear = true; } diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 27862af4d3..6d40a6eeec 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -565,57 +565,57 @@ class ELMpb : public PhysicsModel { laplacexy->setCoefs(1.0, 0.0); phi2D = 0.0; // Starting guess phi2D.setBoundary("phi"); - } - - // Radial smoothing - smooth_j_x = options["smooth_j_x"].doc("Smooth Jpar in x").withDefault(false); - - // Jpar boundary region - jpar_bndry_width = options["jpar_bndry_width"] - .doc("Number of cells near the boundary where jpar = 0") - .withDefault(-1); + } - sheath_boundaries = options["sheath_boundaries"] - .doc("Apply sheath boundaries in Y?") - .withDefault(false); + // Radial smoothing + smooth_j_x = options["smooth_j_x"].doc("Smooth Jpar in x").withDefault(false); - // Parallel differencing - parallel_lr_diff = - options["parallel_lr_diff"] - .doc("Use left and right shifted stencils for parallel differences?") - .withDefault(false); + // Jpar boundary region + jpar_bndry_width = options["jpar_bndry_width"] + .doc("Number of cells near the boundary where jpar = 0") + .withDefault(-1); - // RMP-related options - include_rmp = options["include_rmp"] - .doc("Read RMP field rmp_A from grid?") - .withDefault(false); + sheath_boundaries = options["sheath_boundaries"] + .doc("Apply sheath boundaries in Y?") + .withDefault(false); - simple_rmp = - options["simple_rmp"].doc("Include a simple RMP model?").withDefault(false); - rmp_factor = options["rmp_factor"].withDefault(1.0); - rmp_ramp = options["rmp_ramp"].withDefault(-1.0); - rmp_freq = options["rmp_freq"].withDefault(-1.0); - rmp_rotate = options["rmp_rotate"].withDefault(0.0); - - // Vacuum region control - vacuum_pressure = - options["vacuum_pressure"] - .doc("Fraction of peak pressure, below which is considered vacuum.") - .withDefault(0.02); - vacuum_trans = - options["vacuum_trans"] - .doc("Vacuum boundary transition width, as fraction of peak pressure.") - .withDefault(0.005); - - // Resistivity and hyper-resistivity options - vac_lund = - options["vac_lund"].doc("Lundquist number in vacuum region").withDefault(0.0); - core_lund = - options["core_lund"].doc("Lundquist number in core region").withDefault(0.0); - hyperresist = - options["hyperresist"].doc("Hyper-resistivity coefficient").withDefault(-1.0); - ehyperviscos = options["ehyperviscos"] - .doc("electron Hyper-viscosity coefficient") + // Parallel differencing + parallel_lr_diff = + options["parallel_lr_diff"] + .doc("Use left and right shifted stencils for parallel differences?") + .withDefault(false); + + // RMP-related options + include_rmp = options["include_rmp"] + .doc("Read RMP field rmp_A from grid?") + .withDefault(false); + + simple_rmp = + options["simple_rmp"].doc("Include a simple RMP model?").withDefault(false); + rmp_factor = options["rmp_factor"].withDefault(1.0); + rmp_ramp = options["rmp_ramp"].withDefault(-1.0); + rmp_freq = options["rmp_freq"].withDefault(-1.0); + rmp_rotate = options["rmp_rotate"].withDefault(0.0); + + // Vacuum region control + vacuum_pressure = + options["vacuum_pressure"] + .doc("Fraction of peak pressure, below which is considered vacuum.") + .withDefault(0.02); + vacuum_trans = + options["vacuum_trans"] + .doc("Vacuum boundary transition width, as fraction of peak pressure.") + .withDefault(0.005); + + // Resistivity and hyper-resistivity options + vac_lund = + options["vac_lund"].doc("Lundquist number in vacuum region").withDefault(0.0); + core_lund = + options["core_lund"].doc("Lundquist number in core region").withDefault(0.0); + hyperresist = + options["hyperresist"].doc("Hyper-resistivity coefficient").withDefault(-1.0); + ehyperviscos = options["ehyperviscos"] + .doc("electron Hyper-viscosity coefficient") .withDefault(-1.0); spitzer_resist = options["spitzer_resist"] .doc("Use Spitzer resistivity?") @@ -1216,7 +1216,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_options.ShearFactor); + metric->setIntShiftTorsion(tokamak_options.I); } return 0; diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index a94e1e95a5..c5926fb916 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -758,7 +758,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.I * b0xcv.x; } } @@ -891,7 +891,7 @@ class ELMpb : public PhysicsModel { if (mesh->IncIntShear) { // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_options.ShearFactor); + metric->setIntShiftTorsion(tokamak_options.I); } if (constn0) { diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 85f6d3a48a..ba96a237cb 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -16,9 +16,8 @@ struct TokamakOptions { Field2D Btxy; Field2D Bxy; Field2D hthe; - FieldMetric ShearFactor; + FieldMetric I; FieldMetric dx; - TokamakOptions(Mesh& mesh) { mesh.get(Rxy, "Rxy"); // mesh->get(Zxy, "Zxy"); @@ -26,17 +25,16 @@ struct TokamakOptions { mesh.get(Btxy, "Btxy"); mesh.get(Bxy, "Bxy"); mesh.get(hthe, "hthe"); - mesh.get(ShearFactor, "sinty"); + mesh.get(I, "sinty"); mesh.get(dx, "dpsi"); } - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { Rxy /= Lbar; Bpxy /= Bbar; Btxy /= Bbar; Bxy /= Bbar; hthe /= Lbar; - ShearFactor *= Lbar * Lbar * Bbar * ShearFactor; + I *= Lbar * Lbar * Bbar * ShearFactor; dx /= Lbar * Lbar * Bbar; } }; diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 7de2451947..141787be1b 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -296,7 +296,7 @@ class ELMpb : public PhysicsModel { if (not mesh->IncIntShear) { // Dimits style, using local coordinate system if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.I * b0xcv.x; } } } diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index 427ec14981..dd6e68218a 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -135,7 +135,7 @@ class TwoFluid : public PhysicsModel { const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; + b0xcv.z += tokamak_options.I * b0xcv.x; noshear = true; } From 6ebc748d26765ccc3ac0e19c5483722b5b5fbffd Mon Sep 17 00:00:00 2001 From: tomc271 Date: Mon, 17 Feb 2025 16:06:59 +0000 Subject: [PATCH 93/98] Pass no shear condition to set_tokamak_coordinates_on_mesh() as an (optional) integer parameter rather than a boolean Suggested on PR. --- examples/6field-simple/elm_6f.cxx | 2835 ++++++++------- examples/conducting-wall-mode/cwm.cxx | 6 +- examples/constraints/alfven-wave/alfven.cxx | 8 +- examples/dalf3/dalf3.cxx | 7 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 3232 ++++++++--------- examples/elm-pb/elm_pb.cxx | 36 +- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 10 +- include/bout/tokamak_coordinates.hxx | 8 +- tests/MMS/GBS/gbs.cxx | 897 ++--- tests/MMS/elm-pb/elm_pb.cxx | 39 +- tests/MMS/tokamak/tokamak.cxx | 10 +- .../test-drift-instability/2fluid.cxx | 4 +- .../test-interchange-instability/2fluid.cxx | 9 +- .../integrated/test-laplacexy/loadmetric.cxx | 18 +- 17 files changed, 3554 insertions(+), 3571 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index fb5a73f968..201e4d61ed 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -23,1634 +23,1627 @@ constexpr BoutReal eV_K = 11605.0; // 1eV = 11605K class Elm_6f : public PhysicsModel { - /// The total height, average width and center of profile of N0 - BoutReal n0_height, n0_ave, n0_width, n0_center, n0_bottom_x; - /// The ampitude of congstant temperature - BoutReal Tconst; - - /// Test the effect of first order term of invert Laplace function - BoutReal laplace_alpha; - /// The ratio of Ti0/Te0 - BoutReal Tau_ie; - - // 2D inital profiles - /// Current and pressure - Field2D J0, P0; - /// Curvature term - Vector2D b0xcv; - /// When diamagnetic terms used - Field2D phi0; - - /// Number density and temperature for ions and electrons - Field2D N0, Ti0, Te0, Ne0; - Field2D Pi0, Pe0; - Field2D q95; - BoutReal q95_input; - bool local_q; - BoutReal q_alpha; - bool n0_fake_prof, T0_fake_prof; - /// Charge number of ion - BoutReal Zi; - - /// B0 field vector - Vector2D B0vec; - - // V0 field vectors - /// V0 field vector in convection - Vector2D V0vec; - /// Effective V0 field vector in Ohm's law - Vector2D V0eff; - - // 3D evolving variables - Field3D U, Psi, P, Pi, Pe; - Field3D Ni, Te, Ti, Ne; - Field3D Vipar, Vepar; - - // Derived 3D variables - Field3D Jpar, phi; // Parallel current, electric potential - - Field3D Ajpar; // Parallel current, electric potential - bool emass; - BoutReal emass_inv; // inverse of electron mass - BoutReal coef_jpar; - BoutReal delta_e; // Normalized electron skin depth - BoutReal delta_e_inv; // inverse normalized electron skin depth - BoutReal gyroAlv; // Normalized ion current coef - Field3D ubyn; - - Field3D Jpar2; // Delp2 of Parallel current - Field3D tmpA2; // Grad2_par2new of Parallel vector potential - Field3D tmpN2, tmpTi2, tmpTe2, tmpVp2; // Grad2_par2new of Parallel density - - // Constraint - Field3D C_phi; - - // Parameters - BoutReal density; // Number density [m^-3] - BoutReal Bbar, Lbar, Tbar, Va; // Normalisation constants - BoutReal Nbar, Tibar, Tebar; - BoutReal dia_fact; // Multiply diamagnetic term by this - - BoutReal diffusion_par; // Parallel thermal conductivity - BoutReal diffusion_perp; // Perpendicular thermal conductivity (>0 open) - BoutReal diffusion_n4, diffusion_ti4, - diffusion_te4; // M: 4th Parallel density diffusion - BoutReal diffusion_v4; - BoutReal diffusion_u4; // xqx: parallel hyper-viscous diffusion for vorticity - - BoutReal heating_P; // heating power in pressure - BoutReal hp_width; // heating profile radial width in pressure - BoutReal hp_length; // heating radial domain in pressure - BoutReal sink_vp; // sink in pressure - BoutReal sp_width; // sink profile radial width in pressure - BoutReal sp_length; // sink radial domain in pressure - - BoutReal sink_Ul; // left edge sink in vorticity - BoutReal su_widthl; // left edge sink profile radial width in vorticity - BoutReal su_lengthl; // left edge sink radial domain in vorticity - - BoutReal sink_Ur; // right edge sink in vorticity - BoutReal su_widthr; // right edge sink profile radial width in vorticity - BoutReal su_lengthr; // right edge sink radial domain in vorticity - - BoutReal viscos_par; // Parallel viscosity - BoutReal viscos_perp; // Perpendicular viscosity - BoutReal hyperviscos; // Hyper-viscosity (radial) - Field3D hyper_mu_x; // Hyper-viscosity coefficient - - Field3D Dperp2Phi0, Dperp2Phi, GradPhi02, - GradPhi2; // Temporary variables for gyroviscous - Field3D GradparPhi02, GradparPhi2, GradcPhi, GradcparPhi; - Field3D Dperp2Pi0, Dperp2Pi, bracketPhi0P, bracketPhiP0, bracketPhiP; - - BoutReal Psipara1, Upara0, - Upara1; // Temporary normalization constants for all the equations - BoutReal Upara2, Upara3, Nipara1; - BoutReal Tipara1, Tipara2; - BoutReal Tepara1, Tepara2, Tepara3, Tepara4; - BoutReal Vepara, Vipara; - BoutReal Low_limit; // To limit the negative value of total density and temperatures - - Field3D Te_tmp, Ti_tmp, N_tmp; // to avoid the negative value of total value - BoutReal gamma_i_BC, gamma_e_BC; // sheath energy transmission factors - int Sheath_width; - Field3D c_se, Jpar_sh, q_se, q_si, vth_et, - c_set; // variables for sheath boundary conditions - Field2D vth_e0, c_se0, Jpar_sh0; - BoutReal const_cse; - - // options - bool include_curvature, include_jpar0, compress0; - bool evolve_pressure, continuity, gyroviscous; - Field3D diff_radial, ddx_ni, ddx_n0; - BoutReal diffusion_coef_Hmode0, diffusion_coef_Hmode1; - Field3D eta_i0, pi_ci; - - BoutReal vacuum_pressure; - BoutReal vacuum_trans; // Transition width - Field3D vac_mask; - - bool nonlinear; - bool evolve_jpar; - BoutReal g; // Only if compressible - bool phi_curv; - - // Poisson brackets: b0 x Grad(f) dot Grad(g) / B = [f, g] - // Method to use: BRACKET_ARAKAWA, BRACKET_STD or BRACKET_SIMPLE - BRACKET_METHOD bm_exb, bm_mag; // Bracket method for advection terms - int bracket_method_exb, bracket_method_mag; - - bool diamag; - bool energy_flux, energy_exch; // energy flux term - bool diamag_phi0; // Include the diamagnetic equilibrium phi0 - bool thermal_force; // Include the thermal flux term in Ohm's law - bool eHall; - BoutReal AA; // ion mass in units of the proton mass; AA=Mi/Mp - - BoutReal Vt0; // equilibrium toroidal flow normalized to Alfven velocity - BoutReal Vp0; // equilibrium poloidal flow normalized to Alfven velocity - - bool experiment_Er; // read in phi_0 from experiment - Field2D V0, Dphi0; // net flow amplitude, differential potential to flux - Vector2D V0net; // net flow - - bool nogradparj; - bool filter_z; - int filter_z_mode; - int low_pass_z; - bool zonal_flow; - bool zonal_field; - bool zonal_bkgd; - bool relax_j_vac; - BoutReal relax_j_tconst; // Time-constant for j relax - Field3D Psitarget; // The (moving) target to relax to - - bool smooth_j_x; // Smooth Jpar in the x direction - BoutReal filter_nl; - - int jpar_bndry_width; // Zero jpar in a boundary region - - bool parallel_lagrange; // Use (semi-) Lagrangian method for parallel derivatives - bool parallel_project; // Use Apar to project field-lines - - //******************** - - Field3D Xip_x, Xip_z; // Displacement of y+1 (in cell index space) - - Field3D Xim_x, Xim_z; // Displacement of y-1 (in cell index space) - - bool phi_constraint; // Solver for phi using a solver constraint - - BoutReal vac_lund, core_lund; // Lundquist number S = (Tau_R / Tau_A). -ve -> infty - BoutReal vac_resist, core_resist; // The resistivities (just 1 / S) - Field3D eta; // Resistivity profile (1 / S) - bool spitzer_resist; // Use Spitzer formula for resistivity - - Field3D eta_spitzer; // Resistivity profile (kg*m^3 / S / C^2) - Field3D nu_i; // Ion collision frequency profile (1 / S) - Field3D nu_e; // Electron collision frequency profile (1 / S) - Field3D vth_i; // Ion Thermal Velocity profile (M / S) - Field3D vth_e; // Electron Thermal Velocity profile (M / S) - Field3D kappa_par_i; // Ion Thermal Conductivity profile (kg&M / S^2) - Field3D kappa_par_e; // Electron Thermal Conductivity profile (kg*M / S^2) - Field2D omega_ci, omega_ce; // cyclotron frequency - Field3D kappa_perp_i; // Ion perpendicular Thermal Conductivity profile (kg&M / S^2) - // Electron perpendicular Thermal Conductivity profile (kg*M / S^2) - Field3D kappa_perp_e; - - bool output_transfer; // output the results of energy transfer - bool output_ohm; // output the results of the terms in Ohm's law - bool output_flux_par; // output the results of parallel particle and heat flux - // Maxwell stress, Reynolds stress, ion diamagbetic and curvature term - Field3D T_M, T_R, T_ID, T_C, T_G; - Field3D ohm_phi, ohm_hall, ohm_thermal; - // particle flux, ion and elelctron heat flux - Field3D gamma_par_i, heatf_par_i, heatf_par_e; - - BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) - BoutReal ehyperviscos; // electron Hyper-viscosity coefficient - Field3D hyper_eta_x; // Radial resistivity profile - Field3D hyper_eta_z; // Toroidal resistivity profile - - int damp_width; // Width of inner damped region - BoutReal damp_t_const; // Timescale of damping - - TokamakOptions tokamak_options = TokamakOptions(*mesh); - - BoutReal LnLambda; // ln(Lambda) - - /// Ion mass - BoutReal Mi = SI::amu; - - /// Communication objects - FieldGroup comms; - - /// Solver for inverting Laplacian - std::unique_ptr phiSolver{nullptr}; - std::unique_ptr aparSolver{nullptr}; - - /// For printing out some diagnostics first time around - bool first_run = true; - - Field3D field_larger(const Field3D& f, const BoutReal limit) { - Field3D result; - result.allocate(); - - for (auto i : result) { - if (f[i] >= limit) { - result[i] = f[i]; - } else { - result[i] = limit; - } + /// The total height, average width and center of profile of N0 + BoutReal n0_height, n0_ave, n0_width, n0_center, n0_bottom_x; + /// The ampitude of congstant temperature + BoutReal Tconst; + + /// Test the effect of first order term of invert Laplace function + BoutReal laplace_alpha; + /// The ratio of Ti0/Te0 + BoutReal Tau_ie; + + // 2D inital profiles + /// Current and pressure + Field2D J0, P0; + /// Curvature term + Vector2D b0xcv; + /// When diamagnetic terms used + Field2D phi0; + + /// Number density and temperature for ions and electrons + Field2D N0, Ti0, Te0, Ne0; + Field2D Pi0, Pe0; + Field2D q95; + BoutReal q95_input; + bool local_q; + BoutReal q_alpha; + bool n0_fake_prof, T0_fake_prof; + /// Charge number of ion + BoutReal Zi; + + /// B0 field vector + Vector2D B0vec; + + // V0 field vectors + /// V0 field vector in convection + Vector2D V0vec; + /// Effective V0 field vector in Ohm's law + Vector2D V0eff; + + // 3D evolving variables + Field3D U, Psi, P, Pi, Pe; + Field3D Ni, Te, Ti, Ne; + Field3D Vipar, Vepar; + + // Derived 3D variables + Field3D Jpar, phi; // Parallel current, electric potential + + Field3D Ajpar; // Parallel current, electric potential + bool emass; + BoutReal emass_inv; // inverse of electron mass + BoutReal coef_jpar; + BoutReal delta_e; // Normalized electron skin depth + BoutReal delta_e_inv; // inverse normalized electron skin depth + BoutReal gyroAlv; // Normalized ion current coef + Field3D ubyn; + + Field3D Jpar2; // Delp2 of Parallel current + Field3D tmpA2; // Grad2_par2new of Parallel vector potential + Field3D tmpN2, tmpTi2, tmpTe2, tmpVp2; // Grad2_par2new of Parallel density + + // Constraint + Field3D C_phi; + + // Parameters + BoutReal density; // Number density [m^-3] + BoutReal Bbar, Lbar, Tbar, Va; // Normalisation constants + BoutReal Nbar, Tibar, Tebar; + BoutReal dia_fact; // Multiply diamagnetic term by this + + BoutReal diffusion_par; // Parallel thermal conductivity + BoutReal diffusion_perp; // Perpendicular thermal conductivity (>0 open) + BoutReal diffusion_n4, diffusion_ti4, + diffusion_te4; // M: 4th Parallel density diffusion + BoutReal diffusion_v4; + BoutReal diffusion_u4; // xqx: parallel hyper-viscous diffusion for vorticity + + BoutReal heating_P; // heating power in pressure + BoutReal hp_width; // heating profile radial width in pressure + BoutReal hp_length; // heating radial domain in pressure + BoutReal sink_vp; // sink in pressure + BoutReal sp_width; // sink profile radial width in pressure + BoutReal sp_length; // sink radial domain in pressure + + BoutReal sink_Ul; // left edge sink in vorticity + BoutReal su_widthl; // left edge sink profile radial width in vorticity + BoutReal su_lengthl; // left edge sink radial domain in vorticity + + BoutReal sink_Ur; // right edge sink in vorticity + BoutReal su_widthr; // right edge sink profile radial width in vorticity + BoutReal su_lengthr; // right edge sink radial domain in vorticity + + BoutReal viscos_par; // Parallel viscosity + BoutReal viscos_perp; // Perpendicular viscosity + BoutReal hyperviscos; // Hyper-viscosity (radial) + Field3D hyper_mu_x; // Hyper-viscosity coefficient + + Field3D Dperp2Phi0, Dperp2Phi, GradPhi02, + GradPhi2; // Temporary variables for gyroviscous + Field3D GradparPhi02, GradparPhi2, GradcPhi, GradcparPhi; + Field3D Dperp2Pi0, Dperp2Pi, bracketPhi0P, bracketPhiP0, bracketPhiP; + + BoutReal Psipara1, Upara0, + Upara1; // Temporary normalization constants for all the equations + BoutReal Upara2, Upara3, Nipara1; + BoutReal Tipara1, Tipara2; + BoutReal Tepara1, Tepara2, Tepara3, Tepara4; + BoutReal Vepara, Vipara; + BoutReal Low_limit; // To limit the negative value of total density and temperatures + + Field3D Te_tmp, Ti_tmp, N_tmp; // to avoid the negative value of total value + BoutReal gamma_i_BC, gamma_e_BC; // sheath energy transmission factors + int Sheath_width; + Field3D c_se, Jpar_sh, q_se, q_si, vth_et, + c_set; // variables for sheath boundary conditions + Field2D vth_e0, c_se0, Jpar_sh0; + BoutReal const_cse; + + // options + bool include_curvature, include_jpar0, compress0; + bool evolve_pressure, continuity, gyroviscous; + Field3D diff_radial, ddx_ni, ddx_n0; + BoutReal diffusion_coef_Hmode0, diffusion_coef_Hmode1; + Field3D eta_i0, pi_ci; + + BoutReal vacuum_pressure; + BoutReal vacuum_trans; // Transition width + Field3D vac_mask; + + bool nonlinear; + bool evolve_jpar; + BoutReal g; // Only if compressible + bool phi_curv; + + // Poisson brackets: b0 x Grad(f) dot Grad(g) / B = [f, g] + // Method to use: BRACKET_ARAKAWA, BRACKET_STD or BRACKET_SIMPLE + BRACKET_METHOD bm_exb, bm_mag; // Bracket method for advection terms + int bracket_method_exb, bracket_method_mag; + + bool diamag; + bool energy_flux, energy_exch; // energy flux term + bool diamag_phi0; // Include the diamagnetic equilibrium phi0 + bool thermal_force; // Include the thermal flux term in Ohm's law + bool eHall; + BoutReal AA; // ion mass in units of the proton mass; AA=Mi/Mp + + BoutReal Vt0; // equilibrium toroidal flow normalized to Alfven velocity + BoutReal Vp0; // equilibrium poloidal flow normalized to Alfven velocity + + bool experiment_Er; // read in phi_0 from experiment + Field2D V0, Dphi0; // net flow amplitude, differential potential to flux + Vector2D V0net; // net flow + + bool nogradparj; + bool filter_z; + int filter_z_mode; + int low_pass_z; + bool zonal_flow; + bool zonal_field; + bool zonal_bkgd; + bool relax_j_vac; + BoutReal relax_j_tconst; // Time-constant for j relax + Field3D Psitarget; // The (moving) target to relax to + + bool smooth_j_x; // Smooth Jpar in the x direction + BoutReal filter_nl; + + int jpar_bndry_width; // Zero jpar in a boundary region + + bool parallel_lagrange; // Use (semi-) Lagrangian method for parallel derivatives + bool parallel_project; // Use Apar to project field-lines + + //******************** + + Field3D Xip_x, Xip_z; // Displacement of y+1 (in cell index space) + + Field3D Xim_x, Xim_z; // Displacement of y-1 (in cell index space) + + bool phi_constraint; // Solver for phi using a solver constraint + + BoutReal vac_lund, core_lund; // Lundquist number S = (Tau_R / Tau_A). -ve -> infty + BoutReal vac_resist, core_resist; // The resistivities (just 1 / S) + Field3D eta; // Resistivity profile (1 / S) + bool spitzer_resist; // Use Spitzer formula for resistivity + + Field3D eta_spitzer; // Resistivity profile (kg*m^3 / S / C^2) + Field3D nu_i; // Ion collision frequency profile (1 / S) + Field3D nu_e; // Electron collision frequency profile (1 / S) + Field3D vth_i; // Ion Thermal Velocity profile (M / S) + Field3D vth_e; // Electron Thermal Velocity profile (M / S) + Field3D kappa_par_i; // Ion Thermal Conductivity profile (kg&M / S^2) + Field3D kappa_par_e; // Electron Thermal Conductivity profile (kg*M / S^2) + Field2D omega_ci, omega_ce; // cyclotron frequency + Field3D kappa_perp_i; // Ion perpendicular Thermal Conductivity profile (kg&M / S^2) + // Electron perpendicular Thermal Conductivity profile (kg*M / S^2) + Field3D kappa_perp_e; + + bool output_transfer; // output the results of energy transfer + bool output_ohm; // output the results of the terms in Ohm's law + bool output_flux_par; // output the results of parallel particle and heat flux + // Maxwell stress, Reynolds stress, ion diamagbetic and curvature term + Field3D T_M, T_R, T_ID, T_C, T_G; + Field3D ohm_phi, ohm_hall, ohm_thermal; + // particle flux, ion and elelctron heat flux + Field3D gamma_par_i, heatf_par_i, heatf_par_e; + + BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) + BoutReal ehyperviscos; // electron Hyper-viscosity coefficient + Field3D hyper_eta_x; // Radial resistivity profile + Field3D hyper_eta_z; // Toroidal resistivity profile + + int damp_width; // Width of inner damped region + BoutReal damp_t_const; // Timescale of damping + + TokamakOptions tokamak_options = TokamakOptions(*mesh); + + BoutReal LnLambda; // ln(Lambda) + + /// Ion mass + BoutReal Mi = SI::amu; + + /// Communication objects + FieldGroup comms; + + /// Solver for inverting Laplacian + std::unique_ptr phiSolver{nullptr}; + std::unique_ptr aparSolver{nullptr}; + + /// For printing out some diagnostics first time around + bool first_run = true; + + Field3D field_larger(const Field3D &f, const BoutReal limit) { + Field3D result; + result.allocate(); + + for (auto i: result) { + if (f[i] >= limit) { + result[i] = f[i]; + } else { + result[i] = limit; + } + } + mesh->communicate(result); + return result; } - mesh->communicate(result); - return result; - } - Field3D Grad2_par2new(const Field3D& f) { - /* - * This function implements d2/dy2 where y is the poloidal coordinate theta - */ + Field3D Grad2_par2new(const Field3D &f) { + /* + * This function implements d2/dy2 where y is the poloidal coordinate theta + */ - TRACE("Grad2_par2new( Field3D )"); + TRACE("Grad2_par2new( Field3D )"); - Field3D result = D2DY2(f); + Field3D result = D2DY2(f); #if BOUT_USE_TRACK - result.name = "Grad2_par2new(" + f.name + ")"; + result.name = "Grad2_par2new(" + f.name + ")"; #endif - return result; - } - - Field2D N0tanh(BoutReal n0_height, BoutReal n0_ave, BoutReal n0_width, - BoutReal n0_center, BoutReal n0_bottom_x) { - Field2D result; - result.allocate(); - - BoutReal Grid_NX, Grid_NXlimit; // the grid number on x, and the - BoutReal Jysep; - mesh->get(Grid_NX, "nx"); - mesh->get(Jysep, "jyseps1_1"); - Grid_NXlimit = n0_bottom_x * Grid_NX; - output.write("Jysep1_1 = {:d} Grid number = {:e}\n", int(Jysep), Grid_NX); - - if (Jysep > 0.) { // for single null geometry - - BoutReal Jxsep, Jysep2; - mesh->get(Jxsep, "ixseps1"); - mesh->get(Jysep2, "jyseps2_2"); - - for (int jx = 0; jx < mesh->LocalNx; jx++) { - BoutReal mgx = mesh->GlobalX(jx); - BoutReal xgrid_num = (Jxsep + 1.) / Grid_NX; - // output.write("mgx = {:e} xgrid_num = {:e}\n", mgx); - for (int jy = 0; jy < mesh->LocalNy; jy++) { - int globaly = mesh->getGlobalYIndex(jy); - // output.write("local y = {:d}; global y: {:d}\n", jy, globaly); - if (mgx > xgrid_num || (globaly <= int(Jysep) - 2) - || (globaly > int(Jysep2) + 2)) { - mgx = xgrid_num; - } - BoutReal rlx = mgx - n0_center; - BoutReal temp = exp(rlx / n0_width); - BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); - result(jx, jy) = 0.5 * (1.0 - dampr) * n0_height + n0_ave; - } - } - } else { // circular geometry - for (int jx = 0; jx < mesh->LocalNx; jx++) { - BoutReal mgx = mesh->GlobalX(jx); - BoutReal xgrid_num = Grid_NXlimit / Grid_NX; - if (mgx > xgrid_num) { - mgx = xgrid_num; - } - BoutReal rlx = mgx - n0_center; - BoutReal temp = exp(rlx / n0_width); - BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); - for (int jy = 0; jy < mesh->LocalNy; jy++) { - result(jx, jy) = 0.5 * (1.0 - dampr) * n0_height + n0_ave; - } - } - } + return result; + } + + Field2D N0tanh(BoutReal n0_height, BoutReal n0_ave, BoutReal n0_width, + BoutReal n0_center, BoutReal n0_bottom_x) { + Field2D result; + result.allocate(); + + BoutReal Grid_NX, Grid_NXlimit; // the grid number on x, and the + BoutReal Jysep; + mesh->get(Grid_NX, "nx"); + mesh->get(Jysep, "jyseps1_1"); + Grid_NXlimit = n0_bottom_x * Grid_NX; + output.write("Jysep1_1 = {:d} Grid number = {:e}\n", int(Jysep), Grid_NX); + + if (Jysep > 0.) { // for single null geometry + + BoutReal Jxsep, Jysep2; + mesh->get(Jxsep, "ixseps1"); + mesh->get(Jysep2, "jyseps2_2"); + + for (int jx = 0; jx < mesh->LocalNx; jx++) { + BoutReal mgx = mesh->GlobalX(jx); + BoutReal xgrid_num = (Jxsep + 1.) / Grid_NX; + // output.write("mgx = {:e} xgrid_num = {:e}\n", mgx); + for (int jy = 0; jy < mesh->LocalNy; jy++) { + int globaly = mesh->getGlobalYIndex(jy); + // output.write("local y = {:d}; global y: {:d}\n", jy, globaly); + if (mgx > xgrid_num || (globaly <= int(Jysep) - 2) + || (globaly > int(Jysep2) + 2)) { + mgx = xgrid_num; + } + BoutReal rlx = mgx - n0_center; + BoutReal temp = exp(rlx / n0_width); + BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); + result(jx, jy) = 0.5 * (1.0 - dampr) * n0_height + n0_ave; + } + } + } else { // circular geometry + for (int jx = 0; jx < mesh->LocalNx; jx++) { + BoutReal mgx = mesh->GlobalX(jx); + BoutReal xgrid_num = Grid_NXlimit / Grid_NX; + if (mgx > xgrid_num) { + mgx = xgrid_num; + } + BoutReal rlx = mgx - n0_center; + BoutReal temp = exp(rlx / n0_width); + BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); + for (int jy = 0; jy < mesh->LocalNy; jy++) { + result(jx, jy) = 0.5 * (1.0 - dampr) * n0_height + n0_ave; + } + } + } - mesh->communicate(result); + mesh->communicate(result); - return result; - } + return result; + } - // Parallel gradient along perturbed field-line - Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) { - TRACE("Grad_parP"); + // Parallel gradient along perturbed field-line + Field3D Grad_parP(const Field3D &f, CELL_LOC loc = CELL_DEFAULT) { + TRACE("Grad_parP"); - Field3D result; + Field3D result; - if (parallel_lagrange || parallel_project) { - // Moving stencil locations + if (parallel_lagrange || parallel_project) { + // Moving stencil locations - ASSERT2((not mesh->StaggerGrids) or loc == CELL_DEFAULT or loc == f.getLocation()); + ASSERT2((not mesh->StaggerGrids) or loc == CELL_DEFAULT or loc == f.getLocation()); - Field3D fp, fm; // Interpolated on + and - y locations + Field3D fp, fm; // Interpolated on + and - y locations - fp = interpolate(f, Xip_x, Xip_z); - fm = interpolate(f, Xim_x, Xim_z); + fp = interpolate(f, Xip_x, Xip_z); + fm = interpolate(f, Xim_x, Xim_z); - Coordinates* coord = mesh->getCoordinates(); + Coordinates *coord = mesh->getCoordinates(); - result.allocate(); - for (auto i : result) { - result[i] = - (fp[i.yp()] - fm[i.ym()]) / (2. * coord->dy()[i] * sqrt(coord->g_22()[i])); - } - } else { - result = Grad_par(f, loc); + result.allocate(); + for (auto i: result) { + result[i] = + (fp[i.yp()] - fm[i.ym()]) / (2. * coord->dy()[i] * sqrt(coord->g_22()[i])); + } + } else { + result = Grad_par(f, loc); - if (nonlinear) { - result -= bracket(Psi, f, bm_mag) * tokamak_options.Bxy; - } - } + if (nonlinear) { + result -= bracket(Psi, f, bm_mag) * tokamak_options.Bxy; + } + } - return result; - } + return result; + } protected: - int init(bool restarting) override { - - bool noshear; - - // Get the metric tensor - Coordinates* coord = mesh->getCoordinates(); - - output.write("Solving high-beta flute reduced equations\n"); - output.write("\tFile : {:s}\n", __FILE__); - output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); - - ////////////////////////////////////////////////////////////// - // Load data from the grid - - // Load 2D profiles - mesh->get(J0, "Jpar0"); // A / m^2 - mesh->get(P0, "pressure"); // Pascals - - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - - ////////////////////////////////////////////////////////////// - // Read parameters from the options file - // - // Options.get ( NAME, VARIABLE, DEFAULT VALUE) - // - // or if NAME = "VARIABLE" then just - // - // OPTION(VARIABLE, DEFAULT VALUE) - // - // Prints out what values are assigned - ///////////////////////////////////////////////////////////// - - auto& globalOptions = Options::root(); - auto& options = globalOptions["highbeta"]; - - n0_fake_prof = options["n0_fake_prof"] - .doc("use the hyperbolic profile of n0. If both n0_fake_prof and " - "T0_fake_prof are " - "false, use the profiles from grid file") - .withDefault(false); - n0_height = options["n0_height"] - .doc("the total height of profile of N0, in percentage of Ni_x") - .withDefault(0.4); - n0_ave = options["n0_ave"] - .doc("the center or average of N0, in percentage of Ni_x") - .withDefault(0.01); - n0_width = options["n0_width"] - .doc("the width of the gradient of N0,in percentage of x") - .withDefault(0.1); - n0_center = options["n0_center"] - .doc("the grid number of the center of N0, in percentage of x") - .withDefault(0.633); - n0_bottom_x = - options["n0_bottom_x"] - .doc("the start of flat region of N0 on SOL side, in percentage of x") - .withDefault(0.81); - T0_fake_prof = options["T0_fake_prof"].doc("").withDefault(false); - Tconst = options["Tconst"] - .doc("the amplitude of constant temperature, in percentage") - .withDefault(-1.0); - - experiment_Er = options["experiment_Er"].withDefault(false); - - laplace_alpha = options["laplace_alpha"] - .doc("test parameter for the cross term of invert Lapalace") - .withDefault(1.0); - Low_limit = options["Low_limit"] - .doc("limit the negative value of total quantities") - .withDefault(1.0e-10); - q95_input = options["q95_input"] - .doc("input q95 as a constant, if <0 use profile from grid") - .withDefault(5.0); - local_q = options["local_q"] - .doc("Using magnetic field to calculate q profile?") - .withDefault(false); - q_alpha = options["q_alpha"] - .doc("flux-limiting coefficient, typical value is [0.03, 3]") - .withDefault(1.0); - - gamma_i_BC = options["gamma_i_BC"] - .doc("sheath energy transmission factor for ion") - .withDefault(-1.0); - gamma_e_BC = options["gamma_e_BC"] - .doc("sheath energy transmission factor for electron") - .withDefault(-1.0); - Sheath_width = options["Sheath_width"] - .doc("Sheath boundary width in grid number") - .withDefault(1); - - density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); - Zi = options["Zi"].doc("ion charge number").withDefault(1); - continuity = options["continuity"].doc("use continuity equation").withDefault(false); - - evolve_jpar = - options["evolve_jpar"].doc("If true, evolve J raher than Psi").withDefault(false); - phi_constraint = - options["phi_constraint"].doc("Use solver constraint for phi").withDefault(false); - - // Effects to include/exclude - include_curvature = options["include_curvature"].withDefault(true); - include_jpar0 = options["include_jpar0"].withDefault(true); - evolve_pressure = options["evolve_pressure"].withDefault(true); - - compress0 = options["compress0"].withDefault(false); - nonlinear = options["nonlinear"].withDefault(false); - - // int bracket_method; - bracket_method_exb = options["bracket_method_exb"].withDefault(0); - switch (bracket_method_exb) { - case 0: { - bm_exb = BRACKET_STD; - output << "\tBrackets for ExB: default differencing\n"; - break; - } - case 1: { - bm_exb = BRACKET_SIMPLE; - output << "\tBrackets for ExB: simplified operator\n"; - break; - } - case 2: { - bm_exb = BRACKET_ARAKAWA; - output << "\tBrackets for ExB: Arakawa scheme\n"; - break; - } - case 3: { - bm_exb = BRACKET_CTU; - output << "\tBrackets for ExB: Corner Transport Upwind method\n"; - break; - } - default: - output << "ERROR: Invalid choice of bracket method. Must be 0 - 3\n"; - return 1; - } + int init(bool restarting) override { + + bool noshear; + + // Get the metric tensor + Coordinates *coord = mesh->getCoordinates(); + + output.write("Solving high-beta flute reduced equations\n"); + output.write("\tFile : {:s}\n", __FILE__); + output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); + + ////////////////////////////////////////////////////////////// + // Load data from the grid + + // Load 2D profiles + mesh->get(J0, "Jpar0"); // A / m^2 + mesh->get(P0, "pressure"); // Pascals + + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + + ////////////////////////////////////////////////////////////// + // Read parameters from the options file + // + // Options.get ( NAME, VARIABLE, DEFAULT VALUE) + // + // or if NAME = "VARIABLE" then just + // + // OPTION(VARIABLE, DEFAULT VALUE) + // + // Prints out what values are assigned + ///////////////////////////////////////////////////////////// + + auto &globalOptions = Options::root(); + auto &options = globalOptions["highbeta"]; + + n0_fake_prof = options["n0_fake_prof"] + .doc("use the hyperbolic profile of n0. If both n0_fake_prof and " + "T0_fake_prof are " + "false, use the profiles from grid file") + .withDefault(false); + n0_height = options["n0_height"] + .doc("the total height of profile of N0, in percentage of Ni_x") + .withDefault(0.4); + n0_ave = options["n0_ave"] + .doc("the center or average of N0, in percentage of Ni_x") + .withDefault(0.01); + n0_width = options["n0_width"] + .doc("the width of the gradient of N0,in percentage of x") + .withDefault(0.1); + n0_center = options["n0_center"] + .doc("the grid number of the center of N0, in percentage of x") + .withDefault(0.633); + n0_bottom_x = + options["n0_bottom_x"] + .doc("the start of flat region of N0 on SOL side, in percentage of x") + .withDefault(0.81); + T0_fake_prof = options["T0_fake_prof"].doc("").withDefault(false); + Tconst = options["Tconst"] + .doc("the amplitude of constant temperature, in percentage") + .withDefault(-1.0); + + experiment_Er = options["experiment_Er"].withDefault(false); + + laplace_alpha = options["laplace_alpha"] + .doc("test parameter for the cross term of invert Lapalace") + .withDefault(1.0); + Low_limit = options["Low_limit"] + .doc("limit the negative value of total quantities") + .withDefault(1.0e-10); + q95_input = options["q95_input"] + .doc("input q95 as a constant, if <0 use profile from grid") + .withDefault(5.0); + local_q = options["local_q"] + .doc("Using magnetic field to calculate q profile?") + .withDefault(false); + q_alpha = options["q_alpha"] + .doc("flux-limiting coefficient, typical value is [0.03, 3]") + .withDefault(1.0); + + gamma_i_BC = options["gamma_i_BC"] + .doc("sheath energy transmission factor for ion") + .withDefault(-1.0); + gamma_e_BC = options["gamma_e_BC"] + .doc("sheath energy transmission factor for electron") + .withDefault(-1.0); + Sheath_width = options["Sheath_width"] + .doc("Sheath boundary width in grid number") + .withDefault(1); + + density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); + Zi = options["Zi"].doc("ion charge number").withDefault(1); + continuity = options["continuity"].doc("use continuity equation").withDefault(false); + + evolve_jpar = + options["evolve_jpar"].doc("If true, evolve J raher than Psi").withDefault(false); + phi_constraint = + options["phi_constraint"].doc("Use solver constraint for phi").withDefault(false); + + // Effects to include/exclude + include_curvature = options["include_curvature"].withDefault(true); + include_jpar0 = options["include_jpar0"].withDefault(true); + evolve_pressure = options["evolve_pressure"].withDefault(true); + + compress0 = options["compress0"].withDefault(false); + nonlinear = options["nonlinear"].withDefault(false); + + // int bracket_method; + bracket_method_exb = options["bracket_method_exb"].withDefault(0); + switch (bracket_method_exb) { + case 0: { + bm_exb = BRACKET_STD; + output << "\tBrackets for ExB: default differencing\n"; + break; + } + case 1: { + bm_exb = BRACKET_SIMPLE; + output << "\tBrackets for ExB: simplified operator\n"; + break; + } + case 2: { + bm_exb = BRACKET_ARAKAWA; + output << "\tBrackets for ExB: Arakawa scheme\n"; + break; + } + case 3: { + bm_exb = BRACKET_CTU; + output << "\tBrackets for ExB: Corner Transport Upwind method\n"; + break; + } + default: + output << "ERROR: Invalid choice of bracket method. Must be 0 - 3\n"; + return 1; + } - // int bracket_method; - bracket_method_mag = options["bracket_method_mag"].withDefault(2); - switch (bracket_method_mag) { - case 0: { - bm_mag = BRACKET_STD; - output << "\tBrackets: default differencing\n"; - break; - } - case 1: { - bm_mag = BRACKET_SIMPLE; - output << "\tBrackets: simplified operator\n"; - break; - } - case 2: { - bm_mag = BRACKET_ARAKAWA; - output << "\tBrackets: Arakawa scheme\n"; - break; - } - case 3: { - bm_mag = BRACKET_CTU; - output << "\tBrackets: Corner Transport Upwind method\n"; - break; - } - default: - output << "ERROR: Invalid choice of bracket method. Must be 0 - 3\n"; - return 1; - } + // int bracket_method; + bracket_method_mag = options["bracket_method_mag"].withDefault(2); + switch (bracket_method_mag) { + case 0: { + bm_mag = BRACKET_STD; + output << "\tBrackets: default differencing\n"; + break; + } + case 1: { + bm_mag = BRACKET_SIMPLE; + output << "\tBrackets: simplified operator\n"; + break; + } + case 2: { + bm_mag = BRACKET_ARAKAWA; + output << "\tBrackets: Arakawa scheme\n"; + break; + } + case 3: { + bm_mag = BRACKET_CTU; + output << "\tBrackets: Corner Transport Upwind method\n"; + break; + } + default: + output << "ERROR: Invalid choice of bracket method. Must be 0 - 3\n"; + return 1; + } - AA = options["AA"].doc("ion mass in units of proton mass").withDefault(1.0); - Mi *= AA; + AA = options["AA"].doc("ion mass in units of proton mass").withDefault(1.0); + Mi *= AA; - emass = options["emass"] + emass = options["emass"] .doc("including electron inertial, electron mass") .withDefault(false); - emass_inv = options["emass_inv"].doc("inverse of electron mass").withDefault(1.0); - - diamag = options["diamag"].doc("Diamagnetic effects?").withDefault(false); - diamag_phi0 = - options["diamag_phi0"].doc("Include equilibrium phi0").withDefault(diamag); - dia_fact = options["dia_fact"] - .doc("Scale diamagnetic effects by this factor") - .withDefault(1.0); - - noshear = options["noshear"].withDefault(false); - - relax_j_vac = - options["relax_j_vac"].doc("Relax vacuum current to zero").withDefault(false); - relax_j_tconst = options["relax_j_tconst"].withDefault(0.1); - - // Toroidal filtering - filter_z = options["filter_z"].doc("Filter a single n").withDefault(false); - filter_z_mode = options["filter_z_mode"].withDefault(1); - low_pass_z = options["low_pass_z"].doc("Low pass filter. < 0 -> off").withDefault(-1); - zonal_flow = options["zonal_flow"].withDefault(false); // zonal flow filter - zonal_field = options["zonal_field"].withDefault(false); // zonal field filter - zonal_bkgd = options["zonal_bkgd"].withDefault(false); // zonal background P filter - - filter_nl = options["filter_nl"].doc("zonal background P filter").withDefault(-1); - - // Radial smoothing - smooth_j_x = options["smooth_j_x"].doc("Smooth Jpar in x").withDefault(false); - - // Jpar boundary region - jpar_bndry_width = options["jpar_bndry_width"].withDefault(-1); - - // Parallel differencing - parallel_lagrange = options["parallel_lagrange"] - .doc("Use a (semi-) Lagrangian method for Grad_parP") - .withDefault(false); - parallel_project = options["parallel_project"].withDefault(false); - - // Vacuum region control - vacuum_pressure = - options["vacuum_pressure"].doc("Fraction of peak pressure").withDefault(0.02); - vacuum_trans = - options["vacuum_trans"].doc("Transition width in pressure").withDefault(0.005); - - // Resistivity and hyper-resistivity options - vac_lund = - options["vac_lund"].doc("Lundquist number in vacuum region").withDefault(0.0); - core_lund = - options["core_lund"].doc("Lundquist number in core region").withDefault(0.0); - hyperresist = options["hyperresist"].withDefault(-1.0); - ehyperviscos = options["ehyperviscos"].withDefault(-1.0); - spitzer_resist = - options["spitzer_resist"].doc("Use Spitzer resistivity?").withDefault(false); - - // Inner boundary damping - damp_width = options["damp_width"].withDefault(0); - damp_t_const = options["damp_t_const"].withDefault(0.1); - - // Viscosity and hyper-viscosity - viscos_par = options["viscos_par"].doc("Parallel viscosity").withDefault(-1.0); - viscos_perp = options["viscos_perp"].doc("Perpendicular viscosity").withDefault(-1.0); - hyperviscos = options["hyperviscos"].doc("Radial hyperviscosity").withDefault(-1.0); - - diffusion_par = - options["diffusion_par"].doc("Parallel temperature diffusion").withDefault(-1.0); - diffusion_n4 = - options["diffusion_n4"].doc("4th Parallel density diffusion").withDefault(-1.0); - diffusion_ti4 = options["diffusion_ti4"] - .doc("4th Parallel ion temperature diffusion") - .withDefault(-1.0); - diffusion_te4 = options["diffusion_te4"] - .doc("4th Parallel electron temperature diffusion") - .withDefault(-1.0); - diffusion_u4 = options["diffusion_u4"] - .doc("parallel hyper-viscous diffusion for vorticity") - .withDefault(-1.0); - diffusion_v4 = options["diffusion_v4"] - .doc("4th order Parallel ion velocity diffusion (< 0 = none)") - .withDefault(-1.0); - - // heating factor in pressure - heating_P = options["heating_P"].doc("heating power in pressure").withDefault(-1.0); - // - hp_width = options["hp_width"] - .doc("the percentage of radial grid points for heating profile radial " - "width in pressure") - .withDefault(0.1); - hp_length = options["hp_length"] - .doc("the percentage of radial grid points for heating profile " - "radial domain in pressure") - .withDefault(0.04); - - // sink factor in pressure - sink_vp = options["sink_vp"].doc("sink in pressure").withDefault(-1.0); - sp_width = options["sp_width"] - .doc("the percentage of radial grid points for sink profile radial " - "width in pressure") - .withDefault(0.05); - sp_length = options["sp_length"] - .doc("the percentage of radial grid points for sink profile radial " - "domain in pressure") - .withDefault(0.04); - - // left edge sink factor in vorticity - sink_Ul = options["sink_Ul"].doc("left edge sink in vorticity").withDefault(-1.0); - su_widthl = options["su_widthl"] - .doc("the percentage of left edge radial grid points for sink " - "profile radial width in vorticity") - .withDefault(0.06); - su_lengthl = options["su_lengthl"] - .doc("the percentage of left edge radial grid points for sink " - "profile radial domain in vorticity") - .withDefault(0.15); - - // right edge sink factor in vorticity - // right edge sink in vorticity - sink_Ur = options["sink_Ur"].doc("").withDefault(-1.0); - // the percentage of right edge radial grid points for sink profile - // radial width in vorticity - su_widthr = options["su_widthr"].doc("").withDefault(0.06); - // the percentage of right edge radial grid points for sink profile - // radial domain in vorticity - su_lengthr = options["su_lengthr"].doc("").withDefault(0.15); - - // Compressional terms - phi_curv = options["phi_curv"].doc("Compressional ExB terms").withDefault(true); - g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); - - if (!include_curvature) { - b0xcv = 0.0; - } + emass_inv = options["emass_inv"].doc("inverse of electron mass").withDefault(1.0); - if (!include_jpar0) { - J0 = 0.0; - } + diamag = options["diamag"].doc("Diamagnetic effects?").withDefault(false); + diamag_phi0 = + options["diamag_phi0"].doc("Include equilibrium phi0").withDefault(diamag); + dia_fact = options["dia_fact"] + .doc("Scale diamagnetic effects by this factor") + .withDefault(1.0); - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_options.I * b0xcv.x; - } - } + noshear = options["noshear"].withDefault(false); - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES + relax_j_vac = + options["relax_j_vac"].doc("Relax vacuum current to zero").withDefault(false); + relax_j_tconst = options["relax_j_tconst"].withDefault(0.1); - if (not mesh->IncIntShear) { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += tokamak_options.I * b0xcv.x; - } - } + // Toroidal filtering + filter_z = options["filter_z"].doc("Filter a single n").withDefault(false); + filter_z_mode = options["filter_z_mode"].withDefault(1); + low_pass_z = options["low_pass_z"].doc("Low pass filter. < 0 -> off").withDefault(-1); + zonal_flow = options["zonal_flow"].withDefault(false); // zonal flow filter + zonal_field = options["zonal_field"].withDefault(false); // zonal field filter + zonal_bkgd = options["zonal_bkgd"].withDefault(false); // zonal background P filter - ////////////////////////////////////////////////////////////// - // NORMALISE QUANTITIES + filter_nl = options["filter_nl"].doc("zonal background P filter").withDefault(-1); - if (mesh->get(Bbar, "bmag")) { // Typical magnetic field - Bbar = 1.0; - } - if (mesh->get(Lbar, "rmag")) { // Typical length scale - Lbar = 1.0; - } + // Radial smoothing + smooth_j_x = options["smooth_j_x"].doc("Smooth Jpar in x").withDefault(false); - if (mesh->get(Tibar, "Ti_x")) { // Typical ion temperature scale - Tibar = 1.0; - } + // Jpar boundary region + jpar_bndry_width = options["jpar_bndry_width"].withDefault(-1); - if (mesh->get(Tebar, "Te_x")) { // Typical electron temperature scale - Tebar = 1.0; - } + // Parallel differencing + parallel_lagrange = options["parallel_lagrange"] + .doc("Use a (semi-) Lagrangian method for Grad_parP") + .withDefault(false); + parallel_project = options["parallel_project"].withDefault(false); + + // Vacuum region control + vacuum_pressure = + options["vacuum_pressure"].doc("Fraction of peak pressure").withDefault(0.02); + vacuum_trans = + options["vacuum_trans"].doc("Transition width in pressure").withDefault(0.005); + + // Resistivity and hyper-resistivity options + vac_lund = + options["vac_lund"].doc("Lundquist number in vacuum region").withDefault(0.0); + core_lund = + options["core_lund"].doc("Lundquist number in core region").withDefault(0.0); + hyperresist = options["hyperresist"].withDefault(-1.0); + ehyperviscos = options["ehyperviscos"].withDefault(-1.0); + spitzer_resist = + options["spitzer_resist"].doc("Use Spitzer resistivity?").withDefault(false); + + // Inner boundary damping + damp_width = options["damp_width"].withDefault(0); + damp_t_const = options["damp_t_const"].withDefault(0.1); + + // Viscosity and hyper-viscosity + viscos_par = options["viscos_par"].doc("Parallel viscosity").withDefault(-1.0); + viscos_perp = options["viscos_perp"].doc("Perpendicular viscosity").withDefault(-1.0); + hyperviscos = options["hyperviscos"].doc("Radial hyperviscosity").withDefault(-1.0); + + diffusion_par = + options["diffusion_par"].doc("Parallel temperature diffusion").withDefault(-1.0); + diffusion_n4 = + options["diffusion_n4"].doc("4th Parallel density diffusion").withDefault(-1.0); + diffusion_ti4 = options["diffusion_ti4"] + .doc("4th Parallel ion temperature diffusion") + .withDefault(-1.0); + diffusion_te4 = options["diffusion_te4"] + .doc("4th Parallel electron temperature diffusion") + .withDefault(-1.0); + diffusion_u4 = options["diffusion_u4"] + .doc("parallel hyper-viscous diffusion for vorticity") + .withDefault(-1.0); + diffusion_v4 = options["diffusion_v4"] + .doc("4th order Parallel ion velocity diffusion (< 0 = none)") + .withDefault(-1.0); + + // heating factor in pressure + heating_P = options["heating_P"].doc("heating power in pressure").withDefault(-1.0); + // + hp_width = options["hp_width"] + .doc("the percentage of radial grid points for heating profile radial " + "width in pressure") + .withDefault(0.1); + hp_length = options["hp_length"] + .doc("the percentage of radial grid points for heating profile " + "radial domain in pressure") + .withDefault(0.04); + + // sink factor in pressure + sink_vp = options["sink_vp"].doc("sink in pressure").withDefault(-1.0); + sp_width = options["sp_width"] + .doc("the percentage of radial grid points for sink profile radial " + "width in pressure") + .withDefault(0.05); + sp_length = options["sp_length"] + .doc("the percentage of radial grid points for sink profile radial " + "domain in pressure") + .withDefault(0.04); + + // left edge sink factor in vorticity + sink_Ul = options["sink_Ul"].doc("left edge sink in vorticity").withDefault(-1.0); + su_widthl = options["su_widthl"] + .doc("the percentage of left edge radial grid points for sink " + "profile radial width in vorticity") + .withDefault(0.06); + su_lengthl = options["su_lengthl"] + .doc("the percentage of left edge radial grid points for sink " + "profile radial domain in vorticity") + .withDefault(0.15); + + // right edge sink factor in vorticity + // right edge sink in vorticity + sink_Ur = options["sink_Ur"].doc("").withDefault(-1.0); + // the percentage of right edge radial grid points for sink profile + // radial width in vorticity + su_widthr = options["su_widthr"].doc("").withDefault(0.06); + // the percentage of right edge radial grid points for sink profile + // radial domain in vorticity + su_lengthr = options["su_lengthr"].doc("").withDefault(0.15); + + // Compressional terms + phi_curv = options["phi_curv"].doc("Compressional ExB terms").withDefault(true); + g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); + + if (!include_curvature) { + b0xcv = 0.0; + } - if (mesh->get(Nbar, "Nixexp")) { // Typical ion density scale - Nbar = 1.0; - } - Nbar *= 1.e20 / density; + if (!include_jpar0) { + J0 = 0.0; + } - Tau_ie = Tibar / Tebar; + BoutReal shearFactor = 1.0; + if (noshear) { + if (include_curvature) { + b0xcv.z += tokamak_options.I * b0xcv.x; + } + shearFactor = 0.0; + } - Va = sqrt(Bbar * Bbar / (SI::mu0 * Mi * Nbar * density)); + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES - Tbar = Lbar / Va; + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + coord->setIntShiftTorsion(tokamak_options.I); - output.write("Normalisations: Bbar = {:e} T Lbar = {:e} m\n", Bbar, Lbar); - output.write(" Va = {:e} m/s Tbar = {:e} s\n", Va, Tbar); - output.write(" Nbar = {:e} * {:e} m^-3\n", Nbar, density); - output.write("Tibar = {:e} eV Tebar = {:e} eV Ti/Te = {:e}\n", Tibar, Tebar, - Tau_ie); - output.write(" Resistivity\n"); + } else { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_options.I * b0xcv.x; + } + shearFactor = 0.0; // I disappears from metric + } - Upara0 = SI::kb * Tebar * eV_K / (Zi * SI::qe * Bbar * Va * Lbar); - Upara1 = SI::kb * Tebar * eV_K / Mi / Va / Va; - output.write("vorticity cinstant: Upara0 = {:e} Upara1 = {:e}\n", Upara0, Upara1); + ////////////////////////////////////////////////////////////// + // NORMALISE QUANTITIES - if (diamag) { - Nipara1 = SI::kb * Tibar * eV_K / (Zi * SI::qe * Bbar * Lbar * Va); - Tipara2 = Nipara1; - Tepara2 = SI::kb * Tebar * eV_K / (SI::qe * Bbar * Lbar * Va); - Tepara3 = Bbar / (SI::qe * SI::mu0 * Nbar * density * Lbar * Va); - output.write("Nipara1 = {:e} Tipara2 = {:e}\n", Nipara1, Tipara2); - output.write("Tepara2 = {:e} Tepara3 = {:e}\n", Tepara2, Tepara3); - } + if (mesh->get(Bbar, "bmag")) { // Typical magnetic field + Bbar = 1.0; + } + if (mesh->get(Lbar, "rmag")) { // Typical length scale + Lbar = 1.0; + } - if (compress0) { - output.write("Including compression (Vipar) effects\n"); - Vipara = SI::mu0 * SI::kb * Nbar * density * Tebar * eV_K / (Bbar * Bbar); - Vepara = Bbar / (SI::mu0 * Zi * SI::qe * Nbar * density * Lbar * Va); - output.write("Normalized constant for Vipar : Vipara = {:e}\n", Vipara); - output.write("Normalized constant for Vepar : Vepara = {:e}\n", Vepara); - } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lbar, Bbar, shearFactor); - if (diffusion_par > 0.0) { - Tipara1 = 2.0 / 3.0 / (Lbar * Va); - Tepara1 = Tipara1 / Zi; - } + if (mesh->get(Tibar, "Ti_x")) { // Typical ion temperature scale + Tibar = 1.0; + } - if (vac_lund > 0.0) { - output.write(" Vacuum Tau_R = {:e} s eta = {:e} Ohm m\n", vac_lund * Tbar, - SI::mu0 * Lbar * Lbar / (vac_lund * Tbar)); - vac_resist = 1. / vac_lund; - } else { - output.write(" Vacuum - Zero resistivity -\n"); - vac_resist = 0.0; - } - if (core_lund > 0.0) { - output.write(" Core Tau_R = {:e} s eta = {:e} Ohm m\n", - core_lund * Tbar, SI::mu0 * Lbar * Lbar / (core_lund * Tbar)); - core_resist = 1. / core_lund; - } else { - output.write(" Core - Zero resistivity -\n"); - core_resist = 0.0; - } + if (mesh->get(Tebar, "Te_x")) { // Typical electron temperature scale + Tebar = 1.0; + } - if (hyperresist > 0.0) { - output.write(" Hyper-resistivity coefficient: {:e}\n", hyperresist); - dump.add(hyper_eta_x, "hyper_eta_x", 1); - dump.add(hyper_eta_z, "hyper_eta_z", 1); - } + if (mesh->get(Nbar, "Nixexp")) { // Typical ion density scale + Nbar = 1.0; + } + Nbar *= 1.e20 / density; - if (ehyperviscos > 0.0) { - output.write(" electron Hyper-viscosity coefficient: {:e}\n", ehyperviscos); - } + Tau_ie = Tibar / Tebar; - if (hyperviscos > 0.0) { - output.write(" Hyper-viscosity coefficient: {:e}\n", hyperviscos); - dump.add(hyper_mu_x, "hyper_mu_x", 1); - } + Va = sqrt(Bbar * Bbar / (SI::mu0 * Mi * Nbar * density)); - if (diffusion_par > 0.0) { - output.write(" diffusion_par: {:e}\n", diffusion_par); - dump.add(diffusion_par, "diffusion_par", 0); - } + Tbar = Lbar / Va; - // 4th order diffusion of p - if (diffusion_n4 > 0.0) { - output.write(" diffusion_n4: {:e}\n", diffusion_n4); - dump.add(diffusion_n4, "diffusion_n4", 0); - } + output.write("Normalisations: Bbar = {:e} T Lbar = {:e} m\n", Bbar, Lbar); + output.write(" Va = {:e} m/s Tbar = {:e} s\n", Va, Tbar); + output.write(" Nbar = {:e} * {:e} m^-3\n", Nbar, density); + output.write("Tibar = {:e} eV Tebar = {:e} eV Ti/Te = {:e}\n", Tibar, Tebar, + Tau_ie); + output.write(" Resistivity\n"); - // 4th order diffusion of Ti - if (diffusion_ti4 > 0.0) { - output.write(" diffusion_ti4: {:e}\n", diffusion_ti4); - dump.add(diffusion_ti4, "diffusion_ti4", 0); - } + Upara0 = SI::kb * Tebar * eV_K / (Zi * SI::qe * Bbar * Va * Lbar); + Upara1 = SI::kb * Tebar * eV_K / Mi / Va / Va; + output.write("vorticity cinstant: Upara0 = {:e} Upara1 = {:e}\n", Upara0, Upara1); - // 4th order diffusion of Te - if (diffusion_te4 > 0.0) { - output.write(" diffusion_te4: {:e}\n", diffusion_te4); - dump.add(diffusion_te4, "diffusion_te4", 0); - } + if (diamag) { + Nipara1 = SI::kb * Tibar * eV_K / (Zi * SI::qe * Bbar * Lbar * Va); + Tipara2 = Nipara1; + Tepara2 = SI::kb * Tebar * eV_K / (SI::qe * Bbar * Lbar * Va); + Tepara3 = Bbar / (SI::qe * SI::mu0 * Nbar * density * Lbar * Va); + output.write("Nipara1 = {:e} Tipara2 = {:e}\n", Nipara1, Tipara2); + output.write("Tepara2 = {:e} Tepara3 = {:e}\n", Tepara2, Tepara3); + } - // 4th order diffusion of Vipar - if (diffusion_v4 > 0.0) { - output.write(" diffusion_v4: {:e}\n", diffusion_v4); - dump.add(diffusion_v4, "diffusion_v4", 0); - } + if (compress0) { + output.write("Including compression (Vipar) effects\n"); + Vipara = SI::mu0 * SI::kb * Nbar * density * Tebar * eV_K / (Bbar * Bbar); + Vepara = Bbar / (SI::mu0 * Zi * SI::qe * Nbar * density * Lbar * Va); + output.write("Normalized constant for Vipar : Vipara = {:e}\n", Vipara); + output.write("Normalized constant for Vepar : Vepara = {:e}\n", Vepara); + } - // parallel hyper-viscous diffusion for vorticity - if (diffusion_u4 > 0.0) { - output.write(" diffusion_u4: {:e}\n", diffusion_u4); - dump.add(diffusion_u4, "diffusion_u4", 0); - } + if (diffusion_par > 0.0) { + Tipara1 = 2.0 / 3.0 / (Lbar * Va); + Tepara1 = Tipara1 / Zi; + } - if (sink_vp > 0.0) { - output.write(" sink_vp(rate): {:e}\n", sink_vp); - dump.add(sink_vp, "sink_vp", 1); + if (vac_lund > 0.0) { + output.write(" Vacuum Tau_R = {:e} s eta = {:e} Ohm m\n", vac_lund * Tbar, + SI::mu0 * Lbar * Lbar / (vac_lund * Tbar)); + vac_resist = 1. / vac_lund; + } else { + output.write(" Vacuum - Zero resistivity -\n"); + vac_resist = 0.0; + } + if (core_lund > 0.0) { + output.write(" Core Tau_R = {:e} s eta = {:e} Ohm m\n", + core_lund * Tbar, SI::mu0 * Lbar * Lbar / (core_lund * Tbar)); + core_resist = 1. / core_lund; + } else { + output.write(" Core - Zero resistivity -\n"); + core_resist = 0.0; + } - output.write(" sp_width(%%): {:e}\n", sp_width); - dump.add(sp_width, "sp_width", 1); + if (hyperresist > 0.0) { + output.write(" Hyper-resistivity coefficient: {:e}\n", hyperresist); + dump.add(hyper_eta_x, "hyper_eta_x", 1); + dump.add(hyper_eta_z, "hyper_eta_z", 1); + } - output.write(" sp_length(%%): {:e}\n", sp_length); - dump.add(sp_length, "sp_length", 1); - } + if (ehyperviscos > 0.0) { + output.write(" electron Hyper-viscosity coefficient: {:e}\n", ehyperviscos); + } - auto Bpxy = tokamak_options.Bpxy; - auto hthe = tokamak_options.hthe; - auto Rxy = tokamak_options.Rxy; - auto Btxy = tokamak_options.Btxy; - auto B0 = tokamak_options.Bxy; - - J0 = SI::mu0 * Lbar * J0 / B0; - P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); - - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; - - if ((!T0_fake_prof) && n0_fake_prof) { - N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); - - Ti0 = P0 / N0 / 2.0; - Te0 = Ti0; - } else if (T0_fake_prof) { - Ti0 = Tconst; - Te0 = Ti0; - N0 = P0 / (Ti0 + Te0); - } else { - if (mesh->get(N0, "Niexp")) { // N_i0 - output_error.write("Error: Cannot read Ni0 from grid\n"); - return 1; - } - - if (mesh->get(Ti0, "Tiexp")) { // T_i0 - output_error.write("Error: Cannot read Ti0 from grid\n"); - return 1; - } - - if (mesh->get(Te0, "Teexp")) { // T_e0 - output_error.write("Error: Cannot read Te0 from grid\n"); - return 1; - } - N0 /= Nbar; - Ti0 /= Tibar; - Te0 /= Tebar; - } + if (hyperviscos > 0.0) { + output.write(" Hyper-viscosity coefficient: {:e}\n", hyperviscos); + dump.add(hyper_mu_x, "hyper_mu_x", 1); + } - Ne0 = Zi * N0; // quasi-neutral condition - Pi0 = N0 * Ti0; - Pe0 = Ne0 * Te0; + if (diffusion_par > 0.0) { + output.write(" diffusion_par: {:e}\n", diffusion_par); + dump.add(diffusion_par, "diffusion_par", 0); + } - nu_e.setBoundary("kappa"); - if (spitzer_resist) { - eta_spitzer.setBoundary("kappa"); - } - if (diffusion_par > 0.0) { - nu_i.setBoundary("kappa"); - vth_i.setBoundary("kappa"); - vth_e.setBoundary("kappa"); - kappa_par_i.setBoundary("kappa"); - kappa_par_e.setBoundary("kappa"); - kappa_perp_i.setBoundary("kappa"); - kappa_perp_e.setBoundary("kappa"); - } + // 4th order diffusion of p + if (diffusion_n4 > 0.0) { + output.write(" diffusion_n4: {:e}\n", diffusion_n4); + dump.add(diffusion_n4, "diffusion_n4", 0); + } - if (compress0) { - eta_i0.setBoundary("Ti"); - pi_ci.setBoundary("Ti"); - } + // 4th order diffusion of Ti + if (diffusion_ti4 > 0.0) { + output.write(" diffusion_ti4: {:e}\n", diffusion_ti4); + dump.add(diffusion_ti4, "diffusion_ti4", 0); + } - BoutReal pnorm = max(P0, true); // Maximum over all processors + // 4th order diffusion of Te + if (diffusion_te4 > 0.0) { + output.write(" diffusion_te4: {:e}\n", diffusion_te4); + dump.add(diffusion_te4, "diffusion_te4", 0); + } - vacuum_pressure *= pnorm; // Get pressure from fraction - vacuum_trans *= pnorm; + // 4th order diffusion of Vipar + if (diffusion_v4 > 0.0) { + output.write(" diffusion_v4: {:e}\n", diffusion_v4); + dump.add(diffusion_v4, "diffusion_v4", 0); + } - // Transitions from 0 in core to 1 in vacuum - vac_mask = (1.0 - tanh((P0 - vacuum_pressure) / vacuum_trans)) / 2.0; + // parallel hyper-viscous diffusion for vorticity + if (diffusion_u4 > 0.0) { + output.write(" diffusion_u4: {:e}\n", diffusion_u4); + dump.add(diffusion_u4, "diffusion_u4", 0); + } - if (diffusion_par > 0.0) { - if (q95_input > 0) { - q95 = q95_input; // use a constant for test - } else { - if (local_q) { - q95 = abs(hthe * Btxy / (Bpxy)) * q_alpha; - } else { - output.write("\tUsing q profile from grid.\n"); - if (mesh->get(q95, "q")) { - output.write( - "Cannot get q profile from grid!\nPlease run addqprofile.pro first\n"); - return 1; - } - } - } - output.write("\tlocal max q: {:e}\n", max(q95)); - output.write("\tlocal min q: {:e}\n", min(q95)); - } + if (sink_vp > 0.0) { + output.write(" sink_vp(rate): {:e}\n", sink_vp); + dump.add(sink_vp, "sink_vp", 1); - LnLambda = - 24.0 - - log(pow(Zi * Nbar * density / 1.e6, 0.5) * pow(Tebar, -1.0)); // xia: ln Lambda - output.write("\tlog Lambda: {:e}\n", LnLambda); - - nu_e = 2.91e-6 * LnLambda * ((N0)*Nbar * density / 1.e6) - * pow(Te0 * Tebar, -1.5); // nu_e in 1/S. - output.write("\telectron collision rate: {:e} -> {:e} [1/s]\n", min(nu_e), max(nu_e)); - // nu_e.applyBoundary(); - // mesh->communicate(nu_e); - - if (diffusion_par > 0.0) { - - output.write("\tion thermal noramlized constant: Tipara1 = {:e}\n", Tipara1); - output.write("\telectron normalized thermal constant: Tepara1 = {:e}\n", Tepara1); - // xqx addition, begin - // Use Spitzer thermal conductivities - nu_i = 4.80e-8 * (Zi * Zi * Zi * Zi / sqrt(AA)) * LnLambda - * ((N0)*Nbar * density / 1.e6) * pow(Ti0 * Tibar, -1.5); // nu_i in 1/S. - // output.write("\tCoulomb Logarithm: {:e} \n", max(LnLambda)); - output.write("\tion collision rate: {:e} -> {:e} [1/s]\n", min(nu_i), max(nu_i)); - - // nu_i.applyBoundary(); - // mesh->communicate(nu_i); - - vth_i = 9.79e3 * sqrt((Ti0)*Tibar / AA); // vth_i in m/S. - output.write("\tion thermal velocity: {:e} -> {:e} [m/s]\n", min(vth_i), - max(vth_i)); - // vth_i.applyBoundary(); - // mesh->communicate(vth_i); - vth_e = 4.19e5 * sqrt((Te0)*Tebar); // vth_e in m/S. - output.write("\telectron thermal velocity: {:e} -> {:e} [m/s]\n", min(vth_e), - max(vth_e)); - // vth_e.applyBoundary(); - // mesh->communicate(vth_e); - } + output.write(" sp_width(%%): {:e}\n", sp_width); + dump.add(sp_width, "sp_width", 1); - if (compress0) { - eta_i0 = 0.96 * Pi0 * Tau_ie * nu_i * Tbar; - output.write("\tCoefficients of parallel viscocity: {:e} -> {:e} [kg/(m s)]\n", - min(eta_i0), max(eta_i0)); - } + output.write(" sp_length(%%): {:e}\n", sp_length); + dump.add(sp_length, "sp_length", 1); + } - if (diffusion_par > 0.0) { - kappa_par_i = 3.9 * vth_i * vth_i / nu_i; // * 1.e4; - kappa_par_e = 3.2 * vth_e * vth_e / nu_e; // * 1.e4; - - output.write("\tion thermal conductivity: {:e} -> {:e} [m^2/s]\n", min(kappa_par_i), - max(kappa_par_i)); - output.write("\telectron thermal conductivity: {:e} -> {:e} [m^2/s]\n", - min(kappa_par_e), max(kappa_par_e)); - - output.write("\tnormalized ion thermal conductivity: {:e} -> {:e} \n", - min(kappa_par_i * Tipara1), max(kappa_par_i * Tipara1)); - output.write("\tnormalized electron thermal conductivity: {:e} -> {:e} \n", - min(kappa_par_e * Tepara1), max(kappa_par_e * Tepara1)); - - Field3D kappa_par_i_fl, kappa_par_e_fl; - - kappa_par_i_fl = vth_i * (q95 * Lbar); // * 1.e2; - kappa_par_e_fl = vth_e * (q95 * Lbar); // * 1.e2; - - kappa_par_i *= kappa_par_i_fl / (kappa_par_i + kappa_par_i_fl); - kappa_par_i *= Tipara1 * N0; - output.write("\tUsed normalized ion thermal conductivity: {:e} -> {:e} \n", - min(kappa_par_i), max(kappa_par_i)); - // kappa_par_i.applyBoundary(); - // mesh->communicate(kappa_par_i); - kappa_par_e *= kappa_par_e_fl / (kappa_par_e + kappa_par_e_fl); - kappa_par_e *= Tepara1 * N0 / Zi; - output.write("\tUsed normalized electron thermal conductivity: {:e} -> {:e} \n", - min(kappa_par_e), max(kappa_par_e)); - // kappa_par_e.applyBoundary(); - // mesh->communicate(kappa_par_e); - - dump.add(kappa_par_i, "kappa_par_i", 1); - dump.add(kappa_par_e, "kappa_par_e", 1); - } + auto Bpxy = tokamak_options.Bpxy; + auto hthe = tokamak_options.hthe; + auto Rxy = tokamak_options.Rxy; + auto Btxy = tokamak_options.Btxy; + auto B0 = tokamak_options.Bxy; - if (spitzer_resist) { - // Use Spitzer resistivity - output.write("\n\tSpizter parameters"); - // output.write("\tTemperature: {:e} -> {:e} [eV]\n", min(Te), max(Te)); - eta_spitzer = 0.51 * 1.03e-4 * Zi * LnLambda - * pow(Te0 * Tebar, -1.5); // eta in Ohm-m. NOTE: ln(Lambda) = 20 - output.write("\tSpitzer resistivity: {:e} -> {:e} [Ohm m]\n", min(eta_spitzer), - max(eta_spitzer)); - eta_spitzer /= SI::mu0 * Va * Lbar; - // eta_spitzer.applyBoundary(); - // mesh->communicate(eta_spitzer); - output.write("\t -> Lundquist {:e} -> {:e}\n", 1.0 / max(eta_spitzer), - 1.0 / min(eta_spitzer)); - dump.add(eta_spitzer, "eta_spitzer", 1); - } else { - // transition from 0 for large P0 to resistivity for small P0 - eta = core_resist + (vac_resist - core_resist) * vac_mask; - eta_spitzer = 0.; - dump.add(eta, "eta", 0); - } + J0 = SI::mu0 * Lbar * J0 / B0; + P0 = P0 / (SI::kb * (Tibar + Tebar) * eV_K / 2. * Nbar * density); - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - if (!mesh->IncIntShear) { - noshear = true; - } + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; - /**************** CALCULATE METRICS ******************/ - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, Lbar, Bbar); + if ((!T0_fake_prof) && n0_fake_prof) { + N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES + Ti0 = P0 / N0 / 2.0; + Te0 = Ti0; + } else if (T0_fake_prof) { + Ti0 = Tconst; + Te0 = Ti0; + N0 = P0 / (Ti0 + Te0); + } else { + if (mesh->get(N0, "Niexp")) { // N_i0 + output_error.write("Error: Cannot read Ni0 from grid\n"); + return 1; + } - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_options.I); - } + if (mesh->get(Ti0, "Tiexp")) { // T_i0 + output_error.write("Error: Cannot read Ti0 from grid\n"); + return 1; + } - // Set B field vector + if (mesh->get(Te0, "Teexp")) { // T_e0 + output_error.write("Error: Cannot read Te0 from grid\n"); + return 1; + } + N0 /= Nbar; + Ti0 /= Tibar; + Te0 /= Tebar; + } - B0vec.covariant = false; - B0vec.x = 0.; + Ne0 = Zi * N0; // quasi-neutral condition + Pi0 = N0 * Ti0; + Pe0 = Ne0 * Te0; - B0vec.y = Bpxy / hthe; - B0vec.z = 0.; + nu_e.setBoundary("kappa"); + if (spitzer_resist) { + eta_spitzer.setBoundary("kappa"); + } + if (diffusion_par > 0.0) { + nu_i.setBoundary("kappa"); + vth_i.setBoundary("kappa"); + vth_e.setBoundary("kappa"); + kappa_par_i.setBoundary("kappa"); + kappa_par_e.setBoundary("kappa"); + kappa_perp_i.setBoundary("kappa"); + kappa_perp_e.setBoundary("kappa"); + } - // Set V0vec field vector + if (compress0) { + eta_i0.setBoundary("Ti"); + pi_ci.setBoundary("Ti"); + } - V0vec.covariant = false; - V0vec.x = 0.; - V0vec.y = Vp0 / hthe; - V0vec.z = Vt0 / Rxy; + BoutReal pnorm = max(P0, true); // Maximum over all processors + + vacuum_pressure *= pnorm; // Get pressure from fraction + vacuum_trans *= pnorm; + + // Transitions from 0 in core to 1 in vacuum + vac_mask = (1.0 - tanh((P0 - vacuum_pressure) / vacuum_trans)) / 2.0; + + if (diffusion_par > 0.0) { + if (q95_input > 0) { + q95 = q95_input; // use a constant for test + } else { + if (local_q) { + q95 = abs(hthe * Btxy / (Bpxy)) * q_alpha; + } else { + output.write("\tUsing q profile from grid.\n"); + if (mesh->get(q95, "q")) { + output.write( + "Cannot get q profile from grid!\nPlease run addqprofile.pro first\n"); + return 1; + } + } + } + output.write("\tlocal max q: {:e}\n", max(q95)); + output.write("\tlocal min q: {:e}\n", min(q95)); + } - // Set V0eff field vector + LnLambda = + 24.0 + - log(pow(Zi * Nbar * density / 1.e6, 0.5) * pow(Tebar, -1.0)); // xia: ln Lambda + output.write("\tlog Lambda: {:e}\n", LnLambda); + + nu_e = 2.91e-6 * LnLambda * ((N0) * Nbar * density / 1.e6) + * pow(Te0 * Tebar, -1.5); // nu_e in 1/S. + output.write("\telectron collision rate: {:e} -> {:e} [1/s]\n", min(nu_e), max(nu_e)); + // nu_e.applyBoundary(); + // mesh->communicate(nu_e); + + if (diffusion_par > 0.0) { + + output.write("\tion thermal noramlized constant: Tipara1 = {:e}\n", Tipara1); + output.write("\telectron normalized thermal constant: Tepara1 = {:e}\n", Tepara1); + // xqx addition, begin + // Use Spitzer thermal conductivities + nu_i = 4.80e-8 * (Zi * Zi * Zi * Zi / sqrt(AA)) * LnLambda + * ((N0) * Nbar * density / 1.e6) * pow(Ti0 * Tibar, -1.5); // nu_i in 1/S. + // output.write("\tCoulomb Logarithm: {:e} \n", max(LnLambda)); + output.write("\tion collision rate: {:e} -> {:e} [1/s]\n", min(nu_i), max(nu_i)); + + // nu_i.applyBoundary(); + // mesh->communicate(nu_i); + + vth_i = 9.79e3 * sqrt((Ti0) * Tibar / AA); // vth_i in m/S. + output.write("\tion thermal velocity: {:e} -> {:e} [m/s]\n", min(vth_i), + max(vth_i)); + // vth_i.applyBoundary(); + // mesh->communicate(vth_i); + vth_e = 4.19e5 * sqrt((Te0) * Tebar); // vth_e in m/S. + output.write("\telectron thermal velocity: {:e} -> {:e} [m/s]\n", min(vth_e), + max(vth_e)); + // vth_e.applyBoundary(); + // mesh->communicate(vth_e); + } - V0eff.covariant = false; - V0eff.x = 0.; - V0eff.y = -(Btxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / hthe; - V0eff.z = (Bpxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / Rxy; + if (compress0) { + eta_i0 = 0.96 * Pi0 * Tau_ie * nu_i * Tbar; + output.write("\tCoefficients of parallel viscocity: {:e} -> {:e} [kg/(m s)]\n", + min(eta_i0), max(eta_i0)); + } - Pe.setBoundary("P"); - Pi.setBoundary("P"); + if (diffusion_par > 0.0) { + kappa_par_i = 3.9 * vth_i * vth_i / nu_i; // * 1.e4; + kappa_par_e = 3.2 * vth_e * vth_e / nu_e; // * 1.e4; + + output.write("\tion thermal conductivity: {:e} -> {:e} [m^2/s]\n", min(kappa_par_i), + max(kappa_par_i)); + output.write("\telectron thermal conductivity: {:e} -> {:e} [m^2/s]\n", + min(kappa_par_e), max(kappa_par_e)); + + output.write("\tnormalized ion thermal conductivity: {:e} -> {:e} \n", + min(kappa_par_i * Tipara1), max(kappa_par_i * Tipara1)); + output.write("\tnormalized electron thermal conductivity: {:e} -> {:e} \n", + min(kappa_par_e * Tepara1), max(kappa_par_e * Tepara1)); + + Field3D kappa_par_i_fl, kappa_par_e_fl; + + kappa_par_i_fl = vth_i * (q95 * Lbar); // * 1.e2; + kappa_par_e_fl = vth_e * (q95 * Lbar); // * 1.e2; + + kappa_par_i *= kappa_par_i_fl / (kappa_par_i + kappa_par_i_fl); + kappa_par_i *= Tipara1 * N0; + output.write("\tUsed normalized ion thermal conductivity: {:e} -> {:e} \n", + min(kappa_par_i), max(kappa_par_i)); + // kappa_par_i.applyBoundary(); + // mesh->communicate(kappa_par_i); + kappa_par_e *= kappa_par_e_fl / (kappa_par_e + kappa_par_e_fl); + kappa_par_e *= Tepara1 * N0 / Zi; + output.write("\tUsed normalized electron thermal conductivity: {:e} -> {:e} \n", + min(kappa_par_e), max(kappa_par_e)); + // kappa_par_e.applyBoundary(); + // mesh->communicate(kappa_par_e); + + dump.add(kappa_par_i, "kappa_par_i", 1); + dump.add(kappa_par_e, "kappa_par_e", 1); + } - /**************** SET EVOLVING VARIABLES *************/ + if (spitzer_resist) { + // Use Spitzer resistivity + output.write("\n\tSpizter parameters"); + // output.write("\tTemperature: {:e} -> {:e} [eV]\n", min(Te), max(Te)); + eta_spitzer = 0.51 * 1.03e-4 * Zi * LnLambda + * pow(Te0 * Tebar, -1.5); // eta in Ohm-m. NOTE: ln(Lambda) = 20 + output.write("\tSpitzer resistivity: {:e} -> {:e} [Ohm m]\n", min(eta_spitzer), + max(eta_spitzer)); + eta_spitzer /= SI::mu0 * Va * Lbar; + // eta_spitzer.applyBoundary(); + // mesh->communicate(eta_spitzer); + output.write("\t -> Lundquist {:e} -> {:e}\n", 1.0 / max(eta_spitzer), + 1.0 / min(eta_spitzer)); + dump.add(eta_spitzer, "eta_spitzer", 1); + } else { + // transition from 0 for large P0 to resistivity for small P0 + eta = core_resist + (vac_resist - core_resist) * vac_mask; + eta_spitzer = 0.; + dump.add(eta, "eta", 0); + } - // Tell BOUT which variables to evolve - SOLVE_FOR(U, Ni, Ti, Te, Psi); + /**************** CALCULATE METRICS ******************/ - SAVE_REPEAT(Jpar, P, Vepar); + // Set B field vector - if (parallel_lagrange) { - // Evolving the distortion of the flux surfaces (Ideal-MHD only!) - SOLVE_FOR(Xip_x, Xip_z, Xim_x, Xim_z); - } + B0vec.covariant = false; + B0vec.x = 0.; + B0vec.y = Bpxy / hthe; + B0vec.z = 0.; - if (parallel_project) { - // Add Xi to the dump file - SAVE_REPEAT(Xip_x, Xip_z, Xim_x, Xim_z); - } + // Set V0vec field vector - if (compress0) { - SOLVE_FOR(Vipar); - if (!restarting) { - Vipar = 0.0; - } - } + V0vec.covariant = false; + V0vec.x = 0.; + V0vec.y = Vp0 / hthe; + V0vec.z = Vt0 / Rxy; - if (phi_constraint) { - // Implicit Phi solve using IDA - solver->constraint(phi, C_phi, "phi"); + // Set V0eff field vector - } else { - // Phi solved in RHS (explicitly) - SAVE_REPEAT(phi); - } + V0eff.covariant = false; + V0eff.x = 0.; + V0eff.y = -(Btxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / hthe; + V0eff.z = (Bpxy / (B0 * B0)) * (Vp0 * Btxy - Vt0 * Bpxy) / Rxy; - // Diamagnetic phi0 - if (diamag && diamag_phi0) { - if (experiment_Er) { // get phi0 from grid file - mesh->get(phi0, "Phi_0"); - phi0 /= B0 * Lbar * Va; - } else { - // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -Upara0 * Pi0 / B0 / N0; - } - SAVE_ONCE(phi0); - } + Pe.setBoundary("P"); + Pi.setBoundary("P"); - // Add some equilibrium quantities and normalisations - // everything needed to recover physical units - SAVE_ONCE(J0, P0); - SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Tibar, Tebar, Nbar); - SAVE_ONCE(Va, B0); - SAVE_ONCE(Ti0, Te0, N0); + /**************** SET EVOLVING VARIABLES *************/ - // Create a solver for the Laplacian - phiSolver = Laplacian::create(&globalOptions["phiSolver"]); + // Tell BOUT which variables to evolve + SOLVE_FOR(U, Ni, Ti, Te, Psi); - aparSolver = Laplacian::create(&globalOptions["aparSolver"]); + SAVE_REPEAT(Jpar, P, Vepar); - /////////////// CHECK VACUUM /////////////////////// - // In vacuum region, initial vorticity should equal zero + if (parallel_lagrange) { + // Evolving the distortion of the flux surfaces (Ideal-MHD only!) + SOLVE_FOR(Xip_x, Xip_z, Xim_x, Xim_z); + } - ubyn.setBoundary("U"); + if (parallel_project) { + // Add Xi to the dump file + SAVE_REPEAT(Xip_x, Xip_z, Xim_x, Xim_z); + } - if (!restarting) { - // Only if not restarting: Check initial perturbation + if (compress0) { + SOLVE_FOR(Vipar); + if (!restarting) { + Vipar = 0.0; + } + } - // Set U to zero where P0 < vacuum_pressure - U = where(P0 - vacuum_pressure, U, 0.0); + if (phi_constraint) { + // Implicit Phi solve using IDA + solver->constraint(phi, C_phi, "phi"); - // Field2D lap_temp = 0.0; - Field2D logn0 = laplace_alpha * N0; - Field3D Ntemp; - Ntemp = N0; - ubyn = U * B0 / Ntemp; - // Phi should be consistent with U - if (laplace_alpha <= 0.0) { - phi = phiSolver->solve(ubyn) / B0; - } else { - phiSolver->setCoefC(logn0); - phi = phiSolver->solve(ubyn) / B0; - } - } + } else { + // Phi solved in RHS (explicitly) + SAVE_REPEAT(phi); + } - /************** SETUP COMMUNICATIONS **************/ + // Diamagnetic phi0 + if (diamag && diamag_phi0) { + if (experiment_Er) { // get phi0 from grid file + mesh->get(phi0, "Phi_0"); + phi0 /= B0 * Lbar * Va; + } else { + // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift + phi0 = -Upara0 * Pi0 / B0 / N0; + } + SAVE_ONCE(phi0); + } - comms.add(U); - comms.add(Ni); - comms.add(Ti); - comms.add(Te); - if (!emass) { - comms.add(Psi); - } else { - comms.add(Ajpar); - } + // Add some equilibrium quantities and normalisations + // everything needed to recover physical units + SAVE_ONCE(J0, P0); + SAVE_ONCE(density, Lbar, Bbar, Tbar); + SAVE_ONCE(Tibar, Tebar, Nbar); + SAVE_ONCE(Va, B0); + SAVE_ONCE(Ti0, Te0, N0); + + // Create a solver for the Laplacian + phiSolver = Laplacian::create(&globalOptions["phiSolver"]); + + aparSolver = Laplacian::create(&globalOptions["aparSolver"]); + + /////////////// CHECK VACUUM /////////////////////// + // In vacuum region, initial vorticity should equal zero + + ubyn.setBoundary("U"); + + if (!restarting) { + // Only if not restarting: Check initial perturbation + + // Set U to zero where P0 < vacuum_pressure + U = where(P0 - vacuum_pressure, U, 0.0); + + // Field2D lap_temp = 0.0; + Field2D logn0 = laplace_alpha * N0; + Field3D Ntemp; + Ntemp = N0; + ubyn = U * B0 / Ntemp; + // Phi should be consistent with U + if (laplace_alpha <= 0.0) { + phi = phiSolver->solve(ubyn) / B0; + } else { + phiSolver->setCoefC(logn0); + phi = phiSolver->solve(ubyn) / B0; + } + } - if (compress0) { - comms.add(Vipar); - Vepar.setBoundary("Vipar"); - } + /************** SETUP COMMUNICATIONS **************/ - if (diffusion_u4 > 0.0) { - tmpA2.setBoundary("J"); - } + comms.add(U); + comms.add(Ni); + comms.add(Ti); + comms.add(Te); + if (!emass) { + comms.add(Psi); + } else { + comms.add(Ajpar); + } - if (diffusion_n4 > 0.0) { - tmpN2.setBoundary("Ni"); - } + if (compress0) { + comms.add(Vipar); + Vepar.setBoundary("Vipar"); + } - if (diffusion_ti4 > 0.0) { - tmpTi2.setBoundary("Ti"); - } + if (diffusion_u4 > 0.0) { + tmpA2.setBoundary("J"); + } - if (diffusion_te4 > 0.0) { - tmpTe2.setBoundary("Te"); - } + if (diffusion_n4 > 0.0) { + tmpN2.setBoundary("Ni"); + } - if (diffusion_v4 > 0.0) { - tmpVp2.setBoundary("Vipar"); - } + if (diffusion_ti4 > 0.0) { + tmpTi2.setBoundary("Ti"); + } - phi.setBoundary("phi"); // Set boundary conditions + if (diffusion_te4 > 0.0) { + tmpTe2.setBoundary("Te"); + } - P.setBoundary("P"); - Jpar.setBoundary("J"); - Jpar2.setBoundary("J"); + if (diffusion_v4 > 0.0) { + tmpVp2.setBoundary("Vipar"); + } - return 0; - } + phi.setBoundary("phi"); // Set boundary conditions - int rhs(BoutReal UNUSED(t)) override { + P.setBoundary("P"); + Jpar.setBoundary("J"); + Jpar2.setBoundary("J"); - Coordinates* coord = mesh->getCoordinates(); + return 0; + } - // Perform communications - mesh->communicate(comms); + int rhs(BoutReal UNUSED(t)) override { - // Inversion - Pi = Ni * Ti0 + N0 * Ti; - if (nonlinear) { - Pi += Ni * Ti; - } - mesh->communicate(Pi); + Coordinates *coord = mesh->getCoordinates(); - Pe = Zi * (Ni * Te0 + N0 * Te); - if (nonlinear) { - Pe += Zi * Ni * Te; - } - mesh->communicate(Pe); + // Perform communications + mesh->communicate(comms); - P = Tau_ie * Pi + Pe; - mesh->communicate(P); + // Inversion + Pi = Ni * Ti0 + N0 * Ti; + if (nonlinear) { + Pi += Ni * Ti; + } + mesh->communicate(Pi); - // Field2D lap_temp=0.0; - Field2D logn0 = laplace_alpha * N0; + Pe = Zi * (Ni * Te0 + N0 * Te); + if (nonlinear) { + Pe += Zi * Ni * Te; + } + mesh->communicate(Pe); - auto B0 = tokamak_options.Bxy; + P = Tau_ie * Pi + Pe; + mesh->communicate(P); - ubyn = U * B0 / N0; - if (diamag) { - ubyn -= Upara0 / N0 * Delp2(Pi) / B0; - mesh->communicate(ubyn); - ubyn.applyBoundary(); - } - // Invert laplacian for phi - if (laplace_alpha > 0.0) { - phiSolver->setCoefC(logn0); - } - phi = phiSolver->solve(ubyn) / B0; - - mesh->communicate(phi); - - if (emass) { - Field2D acoeff = -delta_e_inv * N0 * N0; - if (compress0) { - Psi = aparSolver->solve(acoeff * Ajpar - gyroAlv * Vipar); - } else { - Psi = aparSolver->solve(acoeff * Ajpar); - } - mesh->communicate(Psi); - } + // Field2D lap_temp=0.0; + Field2D logn0 = laplace_alpha * N0; - BoutReal N_tmp1; - N_tmp1 = Low_limit; - N_tmp = field_larger(N0 + Ni, N_tmp1); - - BoutReal Te_tmp1, Ti_tmp1; - Te_tmp1 = Low_limit; - Ti_tmp1 = Low_limit; - - Ti_tmp = field_larger(Ti0 + Ti, Ti_tmp1); - Te_tmp = field_larger(Te0 + Te, Te_tmp1); - - // vac_mask transitions from 0 in core to 1 in vacuum - if (nonlinear) { - vac_mask = (1.0 - tanh(((P0 + P) - vacuum_pressure) / vacuum_trans)) / 2.0; - // Update resistivity - if (spitzer_resist) { - // Use Spitzer formula - eta_spitzer = 0.51 * 1.03e-4 * Zi * LnLambda - * pow(Te_tmp * Tebar, -1.5); // eta in Ohm-m. ln(Lambda) = 20 - eta_spitzer /= SI::mu0 * Va * Lbar; - } else { - eta = core_resist + (vac_resist - core_resist) * vac_mask; - } - - nu_e = 2.91e-6 * LnLambda * (N_tmp * Nbar * density / 1.e6) - * pow(Te_tmp * Tebar, -1.5); // nu_e in 1/S. - - if (diffusion_par > 0.0) { - // Use Spitzer thermal conductivities - - nu_i = 4.80e-8 * (Zi * Zi * Zi * Zi / sqrt(AA)) * LnLambda - * (N_tmp * Nbar * density / 1.e6) - * pow(Ti_tmp * Tibar, -1.5); // nu_i in 1/S. - vth_i = 9.79e3 * sqrt(Ti_tmp * Tibar / AA); // vth_i in m/S. - vth_e = 4.19e5 * sqrt(Te_tmp * Tebar); // vth_e in m/S. - } - - if (diffusion_par > 0.0) { - kappa_par_i = 3.9 * vth_i * vth_i / nu_i; // * 1.e4; - kappa_par_e = 3.2 * vth_e * vth_e / nu_e; // * 1.e4; - - Field3D kappa_par_i_fl, kappa_par_e_fl; - - kappa_par_i_fl = vth_i * (q95 * Lbar); // * 1.e2; - kappa_par_e_fl = vth_e * (q95 * Lbar); // * 1.e2; - - kappa_par_i *= kappa_par_i_fl / (kappa_par_i + kappa_par_i_fl); - kappa_par_i *= Tipara1 * N_tmp; - kappa_par_e *= kappa_par_e_fl / (kappa_par_e + kappa_par_e_fl); - kappa_par_e *= Tepara1 * N_tmp * Zi; - } - } + auto B0 = tokamak_options.Bxy; - Jpar = -Delp2(Psi); - Jpar.applyBoundary(); - mesh->communicate(Jpar); + ubyn = U * B0 / N0; + if (diamag) { + ubyn -= Upara0 / N0 * Delp2(Pi) / B0; + mesh->communicate(ubyn); + ubyn.applyBoundary(); + } + // Invert laplacian for phi + if (laplace_alpha > 0.0) { + phiSolver->setCoefC(logn0); + } + phi = phiSolver->solve(ubyn) / B0; - if (jpar_bndry_width > 0) { - // Zero j in boundary regions. Prevents vorticity drive - // at the boundary + mesh->communicate(phi); - for (int i = 0; i < jpar_bndry_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - Jpar(i, j, k) = 0.0; + if (emass) { + Field2D acoeff = -delta_e_inv * N0 * N0; + if (compress0) { + Psi = aparSolver->solve(acoeff * Ajpar - gyroAlv * Vipar); + } else { + Psi = aparSolver->solve(acoeff * Ajpar); } - if (mesh->lastX()) { - Jpar(mesh->LocalNx - 1 - i, j, k) = 0.0; - } - } + mesh->communicate(Psi); } - } - } - // Smooth j in x - if (smooth_j_x) { - Jpar = smooth_x(Jpar); - } + BoutReal N_tmp1; + N_tmp1 = Low_limit; + N_tmp = field_larger(N0 + Ni, N_tmp1); + + BoutReal Te_tmp1, Ti_tmp1; + Te_tmp1 = Low_limit; + Ti_tmp1 = Low_limit; + + Ti_tmp = field_larger(Ti0 + Ti, Ti_tmp1); + Te_tmp = field_larger(Te0 + Te, Te_tmp1); + + // vac_mask transitions from 0 in core to 1 in vacuum + if (nonlinear) { + vac_mask = (1.0 - tanh(((P0 + P) - vacuum_pressure) / vacuum_trans)) / 2.0; + // Update resistivity + if (spitzer_resist) { + // Use Spitzer formula + eta_spitzer = 0.51 * 1.03e-4 * Zi * LnLambda + * pow(Te_tmp * Tebar, -1.5); // eta in Ohm-m. ln(Lambda) = 20 + eta_spitzer /= SI::mu0 * Va * Lbar; + } else { + eta = core_resist + (vac_resist - core_resist) * vac_mask; + } - if (compress0) { - if (nonlinear) { - Vepar = Vipar - B0 * (Jpar) / N_tmp * Vepara; - } else { - Vepar = Vipar - B0 * (Jpar) / N0 * Vepara; - Vepar.applyBoundary(); - mesh->communicate(Vepar); - } - } + nu_e = 2.91e-6 * LnLambda * (N_tmp * Nbar * density / 1.e6) + * pow(Te_tmp * Tebar, -1.5); // nu_e in 1/S. - // Get Delp2(J) from J - Jpar2 = -Delp2(Jpar); + if (diffusion_par > 0.0) { + // Use Spitzer thermal conductivities - Jpar2.applyBoundary(); - mesh->communicate(Jpar2); + nu_i = 4.80e-8 * (Zi * Zi * Zi * Zi / sqrt(AA)) * LnLambda + * (N_tmp * Nbar * density / 1.e6) + * pow(Ti_tmp * Tibar, -1.5); // nu_i in 1/S. + vth_i = 9.79e3 * sqrt(Ti_tmp * Tibar / AA); // vth_i in m/S. + vth_e = 4.19e5 * sqrt(Te_tmp * Tebar); // vth_e in m/S. + } + + if (diffusion_par > 0.0) { + kappa_par_i = 3.9 * vth_i * vth_i / nu_i; // * 1.e4; + kappa_par_e = 3.2 * vth_e * vth_e / nu_e; // * 1.e4; - if (jpar_bndry_width > 0) { - // Zero jpar2 in boundary regions. Prevents vorticity drive - // at the boundary + Field3D kappa_par_i_fl, kappa_par_e_fl; - for (int i = 0; i < jpar_bndry_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - Jpar2(i, j, k) = 0.0; + kappa_par_i_fl = vth_i * (q95 * Lbar); // * 1.e2; + kappa_par_e_fl = vth_e * (q95 * Lbar); // * 1.e2; + + kappa_par_i *= kappa_par_i_fl / (kappa_par_i + kappa_par_i_fl); + kappa_par_i *= Tipara1 * N_tmp; + kappa_par_e *= kappa_par_e_fl / (kappa_par_e + kappa_par_e_fl); + kappa_par_e *= Tepara1 * N_tmp * Zi; } - if (mesh->lastX()) { - Jpar2(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + + Jpar = -Delp2(Psi); + Jpar.applyBoundary(); + mesh->communicate(Jpar); + + if (jpar_bndry_width > 0) { + // Zero j in boundary regions. Prevents vorticity drive + // at the boundary + + for (int i = 0; i < jpar_bndry_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + Jpar(i, j, k) = 0.0; + } + if (mesh->lastX()) { + Jpar(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + } + } } - } } - } - } - //////////////////////////////////////////////////// - // Parallel electric field - { - TRACE("ddt(Psi)"); + // Smooth j in x + if (smooth_j_x) { + Jpar = smooth_x(Jpar); + } + + if (compress0) { + if (nonlinear) { + Vepar = Vipar - B0 * (Jpar) / N_tmp * Vepara; + } else { + Vepar = Vipar - B0 * (Jpar) / N0 * Vepara; + Vepar.applyBoundary(); + mesh->communicate(Vepar); + } + } - ddt(Psi) = 0.0; + // Get Delp2(J) from J + Jpar2 = -Delp2(Jpar); + + Jpar2.applyBoundary(); + mesh->communicate(Jpar2); + + if (jpar_bndry_width > 0) { + // Zero jpar2 in boundary regions. Prevents vorticity drive + // at the boundary + + for (int i = 0; i < jpar_bndry_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + Jpar2(i, j, k) = 0.0; + } + if (mesh->lastX()) { + Jpar2(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + } + } + } + } - if (spitzer_resist) { - ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta_spitzer * Jpar; - } else { - ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta * Jpar; - } + //////////////////////////////////////////////////// + // Parallel electric field + { + TRACE("ddt(Psi)"); - if (diamag) { - ddt(Psi) -= bracket(B0 * phi0, Psi, bm_exb); // Equilibrium flow - } + ddt(Psi) = 0.0; - // Hyper-resistivity - if (hyperresist > 0.0) { - ddt(Psi) += hyperresist * Delp2(Jpar); - } - } + if (spitzer_resist) { + ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta_spitzer * Jpar; + } else { + ddt(Psi) = -Grad_parP(B0 * phi) / B0 - eta * Jpar; + } - //////////////////////////////////////////////////// - // Vorticity equation + if (diamag) { + ddt(Psi) -= bracket(B0 * phi0, Psi, bm_exb); // Equilibrium flow + } - { - TRACE("ddt(U)"); + // Hyper-resistivity + if (hyperresist > 0.0) { + ddt(Psi) += hyperresist * Delp2(Jpar); + } + } - ddt(U) = 0.0; + //////////////////////////////////////////////////// + // Vorticity equation - ddt(U) = -SQ(B0) * bracket(Psi, J0, bm_mag) * B0; // Grad j term + { + TRACE("ddt(U)"); - ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term + ddt(U) = 0.0; - ddt(U) += SQ(B0) * Grad_parP(Jpar); // b dot grad j + ddt(U) = -SQ(B0) * bracket(Psi, J0, bm_mag) * B0; // Grad j term - if (diamag) { - ddt(U) -= bracket(B0 * phi0, U, bm_exb); // Equilibrium flow - } + ddt(U) += 2.0 * Upara1 * b0xcv * Grad(P); // curvature term - if (nonlinear) { - ddt(U) -= bracket(B0 * phi, U, bm_exb); // Advection - } + ddt(U) += SQ(B0) * Grad_parP(Jpar); // b dot grad j - // parallel hyper-viscous diffusion for vector potential - if (diffusion_u4 > 0.0) { - tmpA2 = Grad2_par2new(Psi); - mesh->communicate(tmpA2); - tmpA2.applyBoundary(); - ddt(U) -= diffusion_u4 * Grad2_par2new(tmpA2); - } + if (diamag) { + ddt(U) -= bracket(B0 * phi0, U, bm_exb); // Equilibrium flow + } - // Viscosity terms - if (viscos_par > 0.0) { - ddt(U) += viscos_par * Grad2_par2(U); // Parallel viscosity - } + if (nonlinear) { + ddt(U) -= bracket(B0 * phi, U, bm_exb); // Advection + } - if (hyperviscos > 0.0) { - // Calculate coefficient. + // parallel hyper-viscous diffusion for vector potential + if (diffusion_u4 > 0.0) { + tmpA2 = Grad2_par2new(Psi); + mesh->communicate(tmpA2); + tmpA2.applyBoundary(); + ddt(U) -= diffusion_u4 * Grad2_par2new(tmpA2); + } - hyper_mu_x = hyperviscos * coord->g_11() * SQ(coord->dx()) - * abs(coord->g11() * D2DX2(U)) / (abs(U) + 1e-3); - hyper_mu_x.applyBoundary("dirichlet"); // Set to zero on all boundaries + // Viscosity terms + if (viscos_par > 0.0) { + ddt(U) += viscos_par * Grad2_par2(U); // Parallel viscosity + } - ddt(U) += hyper_mu_x * coord->g11() * D2DX2(U); + if (hyperviscos > 0.0) { + // Calculate coefficient. - if (first_run) { - // Print out maximum values of viscosity used on this processor - output.write(" Hyper-viscosity values:\n"); - output.write(" Max mu_x = {:e}, Max_DC mu_x = {:e}\n", max(hyper_mu_x), - max(DC(hyper_mu_x))); - } - } + hyper_mu_x = hyperviscos * coord->g_11() * SQ(coord->dx()) + * abs(coord->g11() * D2DX2(U)) / (abs(U) + 1e-3); + hyper_mu_x.applyBoundary("dirichlet"); // Set to zero on all boundaries - // left edge sink terms - if (sink_Ul > 0.0) { - ddt(U) -= sink_Ul * sink_tanhxl(P0, U, su_widthl, su_lengthl); // core sink - } + ddt(U) += hyper_mu_x * coord->g11() * D2DX2(U); - // right edge sink terms - if (sink_Ur > 0.0) { - ddt(U) -= sink_Ur * sink_tanhxr(P0, U, su_widthr, su_lengthr); // sol sink - } - } + if (first_run) { + // Print out maximum values of viscosity used on this processor + output.write(" Hyper-viscosity values:\n"); + output.write(" Max mu_x = {:e}, Max_DC mu_x = {:e}\n", max(hyper_mu_x), + max(DC(hyper_mu_x))); + } + } - /////////////////////////////////////////////// - // number density equation + // left edge sink terms + if (sink_Ul > 0.0) { + ddt(U) -= sink_Ul * sink_tanhxl(P0, U, su_widthl, su_lengthl); // core sink + } - { - TRACE("ddt(Ni)"); + // right edge sink terms + if (sink_Ur > 0.0) { + ddt(U) -= sink_Ur * sink_tanhxr(P0, U, su_widthr, su_lengthr); // sol sink + } + } - ddt(Ni) = 0.0; + /////////////////////////////////////////////// + // number density equation - ddt(Ni) -= bracket(B0 * phi, N0, bm_exb); + { + TRACE("ddt(Ni)"); - if (diamag) { - ddt(Ni) -= bracket(B0 * phi0, Ni, bm_exb); // Equilibrium flow - } + ddt(Ni) = 0.0; - if (nonlinear) { - ddt(Ni) -= bracket(B0 * phi, Ni, bm_exb); // Advection - } + ddt(Ni) -= bracket(B0 * phi, N0, bm_exb); - if (compress0) { - ddt(Ni) -= N0 * B0 * Grad_parP(Vipar / B0); - } + if (diamag) { + ddt(Ni) -= bracket(B0 * phi0, Ni, bm_exb); // Equilibrium flow + } - // 4th order Parallel diffusion terms - if (diffusion_n4 > 0.0) { - tmpN2 = Grad2_par2new(Ni); - mesh->communicate(tmpN2); - tmpN2.applyBoundary(); - ddt(Ni) -= diffusion_n4 * Grad2_par2new(tmpN2); - } - } + if (nonlinear) { + ddt(Ni) -= bracket(B0 * phi, Ni, bm_exb); // Advection + } - /////////////////////////////////////////////// - // ion temperature equation - { - TRACE("ddt(Ti)"); + if (compress0) { + ddt(Ni) -= N0 * B0 * Grad_parP(Vipar / B0); + } - ddt(Ti) = 0.0; + // 4th order Parallel diffusion terms + if (diffusion_n4 > 0.0) { + tmpN2 = Grad2_par2new(Ni); + mesh->communicate(tmpN2); + tmpN2.applyBoundary(); + ddt(Ni) -= diffusion_n4 * Grad2_par2new(tmpN2); + } + } - ddt(Ti) -= bracket(B0 * phi, Ti0, bm_exb); + /////////////////////////////////////////////// + // ion temperature equation + { + TRACE("ddt(Ti)"); - if (diamag) { - ddt(Ti) -= bracket(phi0 * B0, Ti, bm_exb); // Equilibrium flow - } + ddt(Ti) = 0.0; - if (nonlinear) { - ddt(Ti) -= bracket(phi * B0, Ti, bm_exb); // Advection - } + ddt(Ti) -= bracket(B0 * phi, Ti0, bm_exb); - if (compress0) { - ddt(Ti) -= 2.0 / 3.0 * Ti0 * B0 * Grad_parP(Vipar / B0); - } + if (diamag) { + ddt(Ti) -= bracket(phi0 * B0, Ti, bm_exb); // Equilibrium flow + } - if (diffusion_par > 0.0) { - ddt(Ti) += kappa_par_i * Grad2_par2(Ti) / N0; // Parallel diffusion - ddt(Ti) += Grad_par(kappa_par_i) * Grad_par(Ti) / N0; - } + if (nonlinear) { + ddt(Ti) -= bracket(phi * B0, Ti, bm_exb); // Advection + } - // 4th order Parallel diffusion terms - if (diffusion_ti4 > 0.0) { - tmpTi2 = Grad2_par2new(Ti); - mesh->communicate(tmpTi2); - tmpTi2.applyBoundary(); - ddt(Ti) -= diffusion_ti4 * Grad2_par2new(tmpTi2); - } - } + if (compress0) { + ddt(Ti) -= 2.0 / 3.0 * Ti0 * B0 * Grad_parP(Vipar / B0); + } - /////////////////////////////////////////////// - // electron temperature equation + if (diffusion_par > 0.0) { + ddt(Ti) += kappa_par_i * Grad2_par2(Ti) / N0; // Parallel diffusion + ddt(Ti) += Grad_par(kappa_par_i) * Grad_par(Ti) / N0; + } - { - TRACE("ddt(Te)"); + // 4th order Parallel diffusion terms + if (diffusion_ti4 > 0.0) { + tmpTi2 = Grad2_par2new(Ti); + mesh->communicate(tmpTi2); + tmpTi2.applyBoundary(); + ddt(Ti) -= diffusion_ti4 * Grad2_par2new(tmpTi2); + } + } - ddt(Te) = 0.0; + /////////////////////////////////////////////// + // electron temperature equation - ddt(Te) -= bracket(B0 * phi, Te0, bm_exb); + { + TRACE("ddt(Te)"); - if (diamag) { - ddt(Te) -= bracket(B0 * phi0, Te, bm_exb); // Equilibrium flow - } + ddt(Te) = 0.0; - if (nonlinear) { - ddt(Te) -= bracket(B0 * phi, Te, bm_exb); // Advection - } + ddt(Te) -= bracket(B0 * phi, Te0, bm_exb); - if (compress0) { - ddt(Te) -= 2.0 / 3.0 * Te0 * B0 * Grad_parP(Vepar / B0); - } + if (diamag) { + ddt(Te) -= bracket(B0 * phi0, Te, bm_exb); // Equilibrium flow + } - if (diffusion_par > 0.0) { - ddt(Te) += kappa_par_e * Grad2_par2(Te) / N0; // Parallel diffusion - ddt(Te) += Grad_par(kappa_par_e) * Grad_par(Te) / N0; - } + if (nonlinear) { + ddt(Te) -= bracket(B0 * phi, Te, bm_exb); // Advection + } - if (diffusion_te4 > 0.0) { - tmpTe2 = Grad2_par2new(Te); - mesh->communicate(tmpTe2); - tmpTe2.applyBoundary(); - ddt(Te) -= diffusion_te4 * Grad2_par2new(tmpTe2); - } - } + if (compress0) { + ddt(Te) -= 2.0 / 3.0 * Te0 * B0 * Grad_parP(Vepar / B0); + } - ////////////////////////////////////////////////////////////////////// - if (compress0) { // parallel velocity equation - TRACE("ddt(Vipar)"); + if (diffusion_par > 0.0) { + ddt(Te) += kappa_par_e * Grad2_par2(Te) / N0; // Parallel diffusion + ddt(Te) += Grad_par(kappa_par_e) * Grad_par(Te) / N0; + } - ddt(Vipar) = 0.0; + if (diffusion_te4 > 0.0) { + tmpTe2 = Grad2_par2new(Te); + mesh->communicate(tmpTe2); + tmpTe2.applyBoundary(); + ddt(Te) -= diffusion_te4 * Grad2_par2new(tmpTe2); + } + } - ddt(Vipar) -= Vipara * Grad_parP(P) / N0; - ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * B0 / N0; + ////////////////////////////////////////////////////////////////////// + if (compress0) { // parallel velocity equation + TRACE("ddt(Vipar)"); - if (diamag) { - ddt(Vipar) -= bracket(B0 * phi0, Vipar, bm_exb); - } + ddt(Vipar) = 0.0; - if (nonlinear) { - ddt(Vipar) -= bracket(B0 * phi, Vipar, bm_exb); - } + ddt(Vipar) -= Vipara * Grad_parP(P) / N0; + ddt(Vipar) += Vipara * bracket(Psi, P0, bm_mag) * B0 / N0; - // parallel hyper-viscous diffusion for vector potential - if (diffusion_v4 > 0.0) { - tmpVp2 = Grad2_par2new(Vipar); - mesh->communicate(tmpVp2); - tmpVp2.applyBoundary(); - ddt(Vipar) -= diffusion_v4 * Grad2_par2new(tmpVp2); - } + if (diamag) { + ddt(Vipar) -= bracket(B0 * phi0, Vipar, bm_exb); + } - if (sink_vp > 0.0) { - Field2D V0tmp = 0.; - ddt(Vipar) -= sink_vp * sink_tanhxl(V0tmp, Vipar, sp_width, sp_length); // sink - } - } + if (nonlinear) { + ddt(Vipar) -= bracket(B0 * phi, Vipar, bm_exb); + } - /////////////////////////////////////////////////////////////////////// + // parallel hyper-viscous diffusion for vector potential + if (diffusion_v4 > 0.0) { + tmpVp2 = Grad2_par2new(Vipar); + mesh->communicate(tmpVp2); + tmpVp2.applyBoundary(); + ddt(Vipar) -= diffusion_v4 * Grad2_par2new(tmpVp2); + } - if (filter_z) { - // Filter out all except filter_z_mode - TRACE("filter_z"); + if (sink_vp > 0.0) { + Field2D V0tmp = 0.; + ddt(Vipar) -= sink_vp * sink_tanhxl(V0tmp, Vipar, sp_width, sp_length); // sink + } + } - ddt(Psi) = filter(ddt(Psi), filter_z_mode); + /////////////////////////////////////////////////////////////////////// - ddt(U) = filter(ddt(U), filter_z_mode); + if (filter_z) { + // Filter out all except filter_z_mode + TRACE("filter_z"); - ddt(Ni) = filter(ddt(Ni), filter_z_mode); + ddt(Psi) = filter(ddt(Psi), filter_z_mode); - ddt(Ti) = filter(ddt(Ti), filter_z_mode); + ddt(U) = filter(ddt(U), filter_z_mode); - ddt(Te) = filter(ddt(Te), filter_z_mode); + ddt(Ni) = filter(ddt(Ni), filter_z_mode); - if (compress0) { - ddt(Vipar) = filter(ddt(Vipar), filter_z_mode); - } - } + ddt(Ti) = filter(ddt(Ti), filter_z_mode); - /////////////////////////////////////////////////////////////////////// + ddt(Te) = filter(ddt(Te), filter_z_mode); - if (low_pass_z > 0) { - // Low-pass filter, keeping n up to low_pass_z - TRACE("low_pass_z"); + if (compress0) { + ddt(Vipar) = filter(ddt(Vipar), filter_z_mode); + } + } - if (!emass) { - ddt(Psi) = lowPass(ddt(Psi), low_pass_z, zonal_field); - } else { - ddt(Ajpar) = lowPass(ddt(Ajpar), low_pass_z, zonal_field); - } + /////////////////////////////////////////////////////////////////////// - ddt(U) = lowPass(ddt(U), low_pass_z, zonal_flow); + if (low_pass_z > 0) { + // Low-pass filter, keeping n up to low_pass_z + TRACE("low_pass_z"); - ddt(Ti) = lowPass(ddt(Ti), low_pass_z, zonal_bkgd); - ddt(Te) = lowPass(ddt(Te), low_pass_z, zonal_bkgd); - ddt(Ni) = lowPass(ddt(Ni), low_pass_z, zonal_bkgd); + if (!emass) { + ddt(Psi) = lowPass(ddt(Psi), low_pass_z, zonal_field); + } else { + ddt(Ajpar) = lowPass(ddt(Ajpar), low_pass_z, zonal_field); + } - if (compress0) { - ddt(Vipar) = lowPass(ddt(Vipar), low_pass_z, zonal_bkgd); - } - } + ddt(U) = lowPass(ddt(U), low_pass_z, zonal_flow); - if (damp_width > 0) { - for (int i = 0; i < damp_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - ddt(U)(i, j, k) -= U(i, j, k) / damp_t_const; + ddt(Ti) = lowPass(ddt(Ti), low_pass_z, zonal_bkgd); + ddt(Te) = lowPass(ddt(Te), low_pass_z, zonal_bkgd); + ddt(Ni) = lowPass(ddt(Ni), low_pass_z, zonal_bkgd); + + if (compress0) { + ddt(Vipar) = lowPass(ddt(Vipar), low_pass_z, zonal_bkgd); } - if (mesh->lastX()) { - ddt(U)(mesh->LocalNx - 1 - i, j, k) -= - U(mesh->LocalNx - 1 - i, j, k) / damp_t_const; + } + + if (damp_width > 0) { + for (int i = 0; i < damp_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + ddt(U)(i, j, k) -= U(i, j, k) / damp_t_const; + } + if (mesh->lastX()) { + ddt(U)(mesh->LocalNx - 1 - i, j, k) -= + U(mesh->LocalNx - 1 - i, j, k) / damp_t_const; + } + } + } } - } } - } - } - if (filter_nl > 0) { - TRACE("filter_nl"); - ddt(Ni) = nl_filter(ddt(Ni), filter_nl); - } + if (filter_nl > 0) { + TRACE("filter_nl"); + ddt(Ni) = nl_filter(ddt(Ni), filter_nl); + } - first_run = false; + first_run = false; - return 0; - } + return 0; + } }; BOUTMAIN(Elm_6f) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 3c17b2c3e4..961c37cb1e 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -55,8 +55,6 @@ class CWM : public PhysicsModel { int init(bool UNUSED(restarting)) override { - bool noshear = false; - /************* LOAD DATA FROM GRID FILE ****************/ // Load 2D profiles (set to zero if not found) @@ -95,7 +93,7 @@ class CWM : public PhysicsModel { "identity"); if (lowercase(ptstr) == "shifted") { - noshear = true; + ShearFactor = 0.0; // I disappears from metric } /************** CALCULATE PARAMETERS *****************/ @@ -132,7 +130,7 @@ class CWM : public PhysicsModel { Te0 /= Te_x; // Normalise geometry - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, rho_s, bmag / 1e4, ShearFactor); // Set nu nu = nu_hat * Ni0 / pow(Te0, 1.5); diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index dfad393ded..144c434807 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -163,18 +163,18 @@ class Alfven : public PhysicsModel { // Get the coordinates object Coordinates* coord = mesh->getCoordinates(); - bool noshear; - // Check type of parallel transform std::string ptstr = Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); + BoutReal shearFactor = 1.0; if (lowercase(ptstr) == "shifted") { - noshear = true; + // Using shifted metric method + shearFactor = 0.0; // I disappears from metric } auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm, shearFactor); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index d9cbe30669..3081f91f80 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -86,8 +86,6 @@ class DALF3 : public PhysicsModel { protected: int init(bool UNUSED(restarting)) override { - bool noshear; - ///////////////////////////////////////////////////// // Load data from the grid @@ -162,10 +160,11 @@ class DALF3 : public PhysicsModel { std::string ptstr = Options::root()["mesh"]["paralleltransform"]["type"].withDefault("identity"); + BoutReal shearFactor = 1.0; if (lowercase(ptstr) == "shifted") { // Dimits style, using local coordinate system b0xcv.z += tokamak_options.I * b0xcv.x; - noshear = true; + shearFactor = 0.0; // I disappears from metric } /////////////////////////////////////////////////// @@ -224,7 +223,7 @@ class DALF3 : public PhysicsModel { b0xcv.z *= rho_s * rho_s; // Metrics - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, rho_s, Bnorm, shearFactor); SOLVE_FOR3(Vort, Pe, Vpar); comms.add(Vort, Pe, Vpar); diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 6d40a6eeec..c9ba1c0ce2 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -94,477 +94,477 @@ BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_xout", "none"); /// 3-field ELM simulation class ELMpb : public PhysicsModel { private: - // 2D inital profiles - Field2D J0, P0; // Current and pressure - Vector2D b0xcv; // Curvature term - Field2D beta; // Used for Vpar terms - Coordinates::FieldMetric gradparB; - Field2D phi0; // When diamagnetic terms used - Field2D Psixy, x; - Coordinates::FieldMetric U0; // 0th vorticity of equilibrium flow, - // radial flux coordinate, normalized radial flux coordinate - - bool constn0; - // the total height, average width and center of profile of N0 - BoutReal n0_height, n0_ave, n0_width, n0_center, n0_bottom_x, Nbar, Tibar, Tebar; - - BoutReal Tconst; // the ampitude of constant temperature - - Field2D N0, Ti0, Te0, Ne0; // number density and temperature - Field2D Pi0, Pe0; - Field2D q95; - Field3D ubyn; - bool n0_fake_prof, T0_fake_prof; - - // B field vectors - Vector2D B0vec; // B0 field vector - - // V0 field vectors - Vector2D V0net; // net flow - - // 3D evolving variables - Field3D U, Psi, P, Vpar; - - // Derived 3D variables - Field3D Jpar, phi; // Parallel current, electric potential - - Field3D Jpar2; // Delp2 of Parallel current - - Field3D tmpP2; // Grad2_par2new of pressure - Field3D tmpU2; // Grad2_par2new of Parallel vorticity - Field3D tmpA2; // Grad2_par2new of Parallel vector potential - - // Constraint - Field3D C_phi; - - // Parameters - BoutReal density; // Number density [m^-3] - BoutReal Bbar, Lbar, Tbar, Va; // Normalisation constants - BoutReal dnorm; // For diamagnetic terms: 1 / (2. * wci * Tbar) - BoutReal dia_fact; // Multiply diamagnetic term by this - BoutReal delta_i; // Normalized ion skin depth - BoutReal omega_i; // ion gyrofrequency - - BoutReal diffusion_p4; // parallel hyper-viscous diffusion for pressure - BoutReal diffusion_u4; // parallel hyper-viscous diffusion for vorticity - BoutReal diffusion_a4; // parallel hyper-viscous diffusion for vector potential - - BoutReal diffusion_par; // Parallel pressure diffusion - BoutReal heating_P; // heating power in pressure - BoutReal hp_width; // heating profile radial width in pressure - BoutReal hp_length; // heating radial domain in pressure - BoutReal sink_P; // sink in pressure - BoutReal sp_width; // sink profile radial width in pressure - BoutReal sp_length; // sink radial domain in pressure - - BoutReal sink_Ul; // left edge sink in vorticity - BoutReal su_widthl; // left edge sink profile radial width in vorticity - BoutReal su_lengthl; // left edge sink radial domain in vorticity - - BoutReal sink_Ur; // right edge sink in vorticity - BoutReal su_widthr; // right edge sink profile radial width in vorticity - BoutReal su_lengthr; // right edge sink radial domain in vorticity - - BoutReal viscos_par; // Parallel viscosity - BoutReal viscos_perp; // Perpendicular viscosity - BoutReal hyperviscos; // Hyper-viscosity (radial) - Field3D hyper_mu_x; // Hyper-viscosity coefficient - - Field3D Dperp2Phi0, Dperp2Phi, GradPhi02, - GradPhi2; // Temporary variables for gyroviscous - Field3D GradparPhi02, GradparPhi2, GradcPhi, GradcparPhi; - Field3D Dperp2Pi0, Dperp2Pi, bracketPhi0P, bracketPhiP0, bracketPhiP; - BoutReal Upara2; - - // options - bool include_curvature, include_jpar0, compress; - bool evolve_pressure, gyroviscous; - - BoutReal vacuum_pressure; - BoutReal vacuum_trans; // Transition width - Field3D vac_mask; - - bool nonlinear; - bool evolve_jpar; - BoutReal g; // Only if compressible - bool phi_curv; - - // Poisson brackets: b0 x Grad(f) dot Grad(g) / B = [f, g] - // Method to use: BRACKET_ARAKAWA, BRACKET_STD or BRACKET_SIMPLE - /* - * Bracket method - * - * BRACKET_STD - Same as b0xGrad_dot_Grad, methods in BOUT.inp - * BRACKET_SIMPLE - Subset of terms, used in BOUT-06 - * BRACKET_ARAKAWA - Arakawa central differencing (2nd order) - * BRACKET_CTU - 1st order upwind method - * - */ - - // Bracket method for advection terms - BRACKET_METHOD bm_exb; - BRACKET_METHOD bm_mag; - int bm_exb_flag; - int bm_mag_flag; - /* BRACKET_METHOD bm_ExB = BRACKET_STD; - BRACKET_METHOD bm_mflutter = BRACKET_STD; */ - - bool diamag; - bool diamag_grad_t; // Grad_par(Te) term in Psi equation - bool diamag_phi0; // Include the diamagnetic equilibrium phi0 - - bool eHall; - BoutReal AA; // ion mass in units of the proton mass; AA=Mi/Mp - - // net flow, Er=-R*Bp*Dphi0,Dphi0=-D_min-0.5*D_0*(1.0-tanh(D_s*(x-x0))) - Field2D V0; // net flow amplitude - Field2D Dphi0; // differential potential to flux - BoutReal D_0; // potential amplitude - BoutReal D_s; // shear parameter - BoutReal x0; // velocity peak location - BoutReal sign; // direction of flow - BoutReal Psiaxis, Psibndry; - bool withflow; - bool K_H_term; // Kelvin-Holmhotz term - Field2D perp; // for test - BoutReal D_min; // constant in flow - - // for C_mod - bool experiment_Er; // read in total Er from experiment - - bool nogradparj; - bool filter_z; - int filter_z_mode; - int low_pass_z; - bool zonal_flow; - bool zonal_field; - bool zonal_bkgd; - - bool split_n0; // Solve the n=0 component of potential + // 2D inital profiles + Field2D J0, P0; // Current and pressure + Vector2D b0xcv; // Curvature term + Field2D beta; // Used for Vpar terms + Coordinates::FieldMetric gradparB; + Field2D phi0; // When diamagnetic terms used + Field2D Psixy, x; + Coordinates::FieldMetric U0; // 0th vorticity of equilibrium flow, + // radial flux coordinate, normalized radial flux coordinate + + bool constn0; + // the total height, average width and center of profile of N0 + BoutReal n0_height, n0_ave, n0_width, n0_center, n0_bottom_x, Nbar, Tibar, Tebar; + + BoutReal Tconst; // the ampitude of constant temperature + + Field2D N0, Ti0, Te0, Ne0; // number density and temperature + Field2D Pi0, Pe0; + Field2D q95; + Field3D ubyn; + bool n0_fake_prof, T0_fake_prof; + + // B field vectors + Vector2D B0vec; // B0 field vector + + // V0 field vectors + Vector2D V0net; // net flow + + // 3D evolving variables + Field3D U, Psi, P, Vpar; + + // Derived 3D variables + Field3D Jpar, phi; // Parallel current, electric potential + + Field3D Jpar2; // Delp2 of Parallel current + + Field3D tmpP2; // Grad2_par2new of pressure + Field3D tmpU2; // Grad2_par2new of Parallel vorticity + Field3D tmpA2; // Grad2_par2new of Parallel vector potential + + // Constraint + Field3D C_phi; + + // Parameters + BoutReal density; // Number density [m^-3] + BoutReal Bbar, Lbar, Tbar, Va; // Normalisation constants + BoutReal dnorm; // For diamagnetic terms: 1 / (2. * wci * Tbar) + BoutReal dia_fact; // Multiply diamagnetic term by this + BoutReal delta_i; // Normalized ion skin depth + BoutReal omega_i; // ion gyrofrequency + + BoutReal diffusion_p4; // parallel hyper-viscous diffusion for pressure + BoutReal diffusion_u4; // parallel hyper-viscous diffusion for vorticity + BoutReal diffusion_a4; // parallel hyper-viscous diffusion for vector potential + + BoutReal diffusion_par; // Parallel pressure diffusion + BoutReal heating_P; // heating power in pressure + BoutReal hp_width; // heating profile radial width in pressure + BoutReal hp_length; // heating radial domain in pressure + BoutReal sink_P; // sink in pressure + BoutReal sp_width; // sink profile radial width in pressure + BoutReal sp_length; // sink radial domain in pressure + + BoutReal sink_Ul; // left edge sink in vorticity + BoutReal su_widthl; // left edge sink profile radial width in vorticity + BoutReal su_lengthl; // left edge sink radial domain in vorticity + + BoutReal sink_Ur; // right edge sink in vorticity + BoutReal su_widthr; // right edge sink profile radial width in vorticity + BoutReal su_lengthr; // right edge sink radial domain in vorticity + + BoutReal viscos_par; // Parallel viscosity + BoutReal viscos_perp; // Perpendicular viscosity + BoutReal hyperviscos; // Hyper-viscosity (radial) + Field3D hyper_mu_x; // Hyper-viscosity coefficient + + Field3D Dperp2Phi0, Dperp2Phi, GradPhi02, + GradPhi2; // Temporary variables for gyroviscous + Field3D GradparPhi02, GradparPhi2, GradcPhi, GradcparPhi; + Field3D Dperp2Pi0, Dperp2Pi, bracketPhi0P, bracketPhiP0, bracketPhiP; + BoutReal Upara2; + + // options + bool include_curvature, include_jpar0, compress; + bool evolve_pressure, gyroviscous; + + BoutReal vacuum_pressure; + BoutReal vacuum_trans; // Transition width + Field3D vac_mask; + + bool nonlinear; + bool evolve_jpar; + BoutReal g; // Only if compressible + bool phi_curv; + + // Poisson brackets: b0 x Grad(f) dot Grad(g) / B = [f, g] + // Method to use: BRACKET_ARAKAWA, BRACKET_STD or BRACKET_SIMPLE + /* + * Bracket method + * + * BRACKET_STD - Same as b0xGrad_dot_Grad, methods in BOUT.inp + * BRACKET_SIMPLE - Subset of terms, used in BOUT-06 + * BRACKET_ARAKAWA - Arakawa central differencing (2nd order) + * BRACKET_CTU - 1st order upwind method + * + */ + + // Bracket method for advection terms + BRACKET_METHOD bm_exb; + BRACKET_METHOD bm_mag; + int bm_exb_flag; + int bm_mag_flag; + /* BRACKET_METHOD bm_ExB = BRACKET_STD; + BRACKET_METHOD bm_mflutter = BRACKET_STD; */ + + bool diamag; + bool diamag_grad_t; // Grad_par(Te) term in Psi equation + bool diamag_phi0; // Include the diamagnetic equilibrium phi0 + + bool eHall; + BoutReal AA; // ion mass in units of the proton mass; AA=Mi/Mp + + // net flow, Er=-R*Bp*Dphi0,Dphi0=-D_min-0.5*D_0*(1.0-tanh(D_s*(x-x0))) + Field2D V0; // net flow amplitude + Field2D Dphi0; // differential potential to flux + BoutReal D_0; // potential amplitude + BoutReal D_s; // shear parameter + BoutReal x0; // velocity peak location + BoutReal sign; // direction of flow + BoutReal Psiaxis, Psibndry; + bool withflow; + bool K_H_term; // Kelvin-Holmhotz term + Field2D perp; // for test + BoutReal D_min; // constant in flow + + // for C_mod + bool experiment_Er; // read in total Er from experiment + + bool nogradparj; + bool filter_z; + int filter_z_mode; + int low_pass_z; + bool zonal_flow; + bool zonal_field; + bool zonal_bkgd; + + bool split_n0; // Solve the n=0 component of potential #if BOUT_HAS_HYPRE - std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) + std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) #else - std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) + std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) #endif - Field2D phi2D; // Axisymmetric phi + Field2D phi2D; // Axisymmetric phi - bool relax_j_vac; - BoutReal relax_j_tconst; // Time-constant for j relax + bool relax_j_vac; + BoutReal relax_j_tconst; // Time-constant for j relax - bool smooth_j_x; // Smooth Jpar in the x direction + bool smooth_j_x; // Smooth Jpar in the x direction - int jpar_bndry_width; // Zero jpar in a boundary region + int jpar_bndry_width; // Zero jpar in a boundary region - bool sheath_boundaries; // Apply sheath boundaries in Y + bool sheath_boundaries; // Apply sheath boundaries in Y - bool parallel_lr_diff; // Use left and right shifted stencils for parallel differences + bool parallel_lr_diff; // Use left and right shifted stencils for parallel differences - bool phi_constraint; // Solver for phi using a solver constraint + bool phi_constraint; // Solver for phi using a solver constraint - bool include_rmp; // Include RMP coil perturbation - bool simple_rmp; // Just use a simple form for the perturbation + bool include_rmp; // Include RMP coil perturbation + bool simple_rmp; // Just use a simple form for the perturbation - BoutReal rmp_factor; // Multiply amplitude by this factor - BoutReal rmp_ramp; // Ramp-up time for RMP [s]. negative -> instant - BoutReal rmp_freq; // Amplitude oscillation frequency [Hz] (negative -> no oscillation) - BoutReal rmp_rotate; // Rotation rate [Hz] - bool rmp_vac_mask; - Field3D rmp_Psi0; // Parallel vector potential from Resonant Magnetic Perturbation (RMP) - // coils - Field3D rmp_Psi; // Value used in calculations - Field3D rmp_dApdt; // Time variation + BoutReal rmp_factor; // Multiply amplitude by this factor + BoutReal rmp_ramp; // Ramp-up time for RMP [s]. negative -> instant + BoutReal rmp_freq; // Amplitude oscillation frequency [Hz] (negative -> no oscillation) + BoutReal rmp_rotate; // Rotation rate [Hz] + bool rmp_vac_mask; + Field3D rmp_Psi0; // Parallel vector potential from Resonant Magnetic Perturbation (RMP) + // coils + Field3D rmp_Psi; // Value used in calculations + Field3D rmp_dApdt; // Time variation - BoutReal vac_lund, core_lund; // Lundquist number S = (Tau_R / Tau_A). -ve -> infty - BoutReal vac_resist, core_resist; // The resistivities (just 1 / S) - Field3D eta; // Resistivity profile (1 / S) - bool spitzer_resist; // Use Spitzer formula for resistivity - BoutReal Zeff; // Z effective for resistivity formula + BoutReal vac_lund, core_lund; // Lundquist number S = (Tau_R / Tau_A). -ve -> infty + BoutReal vac_resist, core_resist; // The resistivities (just 1 / S) + Field3D eta; // Resistivity profile (1 / S) + bool spitzer_resist; // Use Spitzer formula for resistivity + BoutReal Zeff; // Z effective for resistivity formula - BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) - BoutReal ehyperviscos; // electron Hyper-viscosity coefficient + BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) + BoutReal ehyperviscos; // electron Hyper-viscosity coefficient - int damp_width; // Width of inner damped region - BoutReal damp_t_const; // Timescale of damping + int damp_width; // Width of inner damped region + BoutReal damp_t_const; // Timescale of damping - TokamakOptions tokamak_options = TokamakOptions(*mesh); + TokamakOptions tokamak_options = TokamakOptions(*mesh); - const BoutReal MU0 = 4.0e-7 * PI; - const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass - const BoutReal Me = 9.1094e-31; // Electron mass - const BoutReal mi_me = Mi / Me; + const BoutReal MU0 = 4.0e-7 * PI; + const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass + const BoutReal Me = 9.1094e-31; // Electron mass + const BoutReal mi_me = Mi / Me; - // Communication objects - FieldGroup comms; + // Communication objects + FieldGroup comms; - /// Solver for inverting Laplacian - std::unique_ptr phiSolver{nullptr}; - std::unique_ptr aparSolver{nullptr}; + /// Solver for inverting Laplacian + std::unique_ptr phiSolver{nullptr}; + std::unique_ptr aparSolver{nullptr}; - const Field2D N0tanh(BoutReal n0_height, BoutReal n0_ave, BoutReal n0_width, - BoutReal n0_center, BoutReal n0_bottom_x) { - Field2D result; - result.allocate(); + const Field2D N0tanh(BoutReal n0_height, BoutReal n0_ave, BoutReal n0_width, + BoutReal n0_center, BoutReal n0_bottom_x) { + Field2D result; + result.allocate(); - BoutReal Grid_NX, Grid_NXlimit; // the grid number on x, and the - BoutReal Jysep; - mesh->get(Grid_NX, "nx"); - mesh->get(Jysep, "jyseps1_1"); - Grid_NXlimit = n0_bottom_x * Grid_NX; - output.write("Jysep1_1 = {:d} Grid number = {:e}\n", int(Jysep), Grid_NX); + BoutReal Grid_NX, Grid_NXlimit; // the grid number on x, and the + BoutReal Jysep; + mesh->get(Grid_NX, "nx"); + mesh->get(Jysep, "jyseps1_1"); + Grid_NXlimit = n0_bottom_x * Grid_NX; + output.write("Jysep1_1 = {:d} Grid number = {:e}\n", int(Jysep), Grid_NX); - if (Jysep > 0.) { // for single null geometry - BoutReal Jxsep, Jysep2; - mesh->get(Jxsep, "ixseps1"); - mesh->get(Jysep2, "jyseps2_2"); + if (Jysep > 0.) { // for single null geometry + BoutReal Jxsep, Jysep2; + mesh->get(Jxsep, "ixseps1"); + mesh->get(Jysep2, "jyseps2_2"); - for (auto i : result) { - BoutReal mgx = mesh->GlobalX(i.x()); - BoutReal xgrid_num = (Jxsep + 1.) / Grid_NX; + for (auto i: result) { + BoutReal mgx = mesh->GlobalX(i.x()); + BoutReal xgrid_num = (Jxsep + 1.) / Grid_NX; - int globaly = mesh->getGlobalYIndex(i.y()); + int globaly = mesh->getGlobalYIndex(i.y()); - if (mgx > xgrid_num || (globaly <= int(Jysep) - 2) - || (globaly > int(Jysep2) + 2)) { - mgx = xgrid_num; - } - BoutReal rlx = mgx - n0_center; - BoutReal temp = exp(rlx / n0_width); - BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); - result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; - } - } else { // circular geometry - for (auto i : result) { - BoutReal mgx = mesh->GlobalX(i.x()); - BoutReal xgrid_num = Grid_NXlimit / Grid_NX; - if (mgx > xgrid_num) { - mgx = xgrid_num; + if (mgx > xgrid_num || (globaly <= int(Jysep) - 2) + || (globaly > int(Jysep2) + 2)) { + mgx = xgrid_num; + } + BoutReal rlx = mgx - n0_center; + BoutReal temp = exp(rlx / n0_width); + BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); + result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; + } + } else { // circular geometry + for (auto i: result) { + BoutReal mgx = mesh->GlobalX(i.x()); + BoutReal xgrid_num = Grid_NXlimit / Grid_NX; + if (mgx > xgrid_num) { + mgx = xgrid_num; + } + BoutReal rlx = mgx - n0_center; + BoutReal temp = exp(rlx / n0_width); + BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); + result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; + } } - BoutReal rlx = mgx - n0_center; - BoutReal temp = exp(rlx / n0_width); - BoutReal dampr = ((temp - 1.0 / temp) / (temp + 1.0 / temp)); - result[i] = 0.5 * (1.0 - dampr) * n0_height + n0_ave; - } - } - mesh->communicate(result); + mesh->communicate(result); - return result; - } + return result; + } public: - // Note: The rhs() function needs to be public so that RAJA can use CUDA + // Note: The rhs() function needs to be public so that RAJA can use CUDA - int init(bool restarting) override { - Coordinates* metric = mesh->getCoordinates(); + int init(bool restarting) override { + Coordinates *metric = mesh->getCoordinates(); - output.write("Solving high-beta flute reduced equations\n"); - output.write("\tFile : {:s}\n", __FILE__); - output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); + output.write("Solving high-beta flute reduced equations\n"); + output.write("\tFile : {:s}\n", __FILE__); + output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); - ////////////////////////////////////////////////////////////// - // Load data from the grid + ////////////////////////////////////////////////////////////// + // Load data from the grid - // Load 2D profiles - mesh->get(J0, "Jpar0"); // A / m^2 - mesh->get(P0, "pressure"); // Pascals + // Load 2D profiles + mesh->get(J0, "Jpar0"); // A / m^2 + mesh->get(P0, "pressure"); // Pascals - // Load curvature term - b0xcv.covariant = false; // Read contravariant components - mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 + // Load curvature term + b0xcv.covariant = false; // Read contravariant components + mesh->get(b0xcv, "bxcv"); // mixed units x: T y: m^-2 z: m^-2 - mesh->get(Psixy, "psixy"); // get Psi - mesh->get(Psiaxis, "psi_axis"); // axis flux - mesh->get(Psibndry, "psi_bndry"); // edge flux + mesh->get(Psixy, "psixy"); // get Psi + mesh->get(Psiaxis, "psi_axis"); // axis flux + mesh->get(Psibndry, "psi_bndry"); // edge flux - // Set locations of staggered variables - // Note, use of staggered grids in elm-pb is untested and may not be completely - // implemented. Parallel boundary conditions are especially likely to be wrong. - if (mesh->StaggerGrids) { - loc = CELL_YLOW; - } else { - loc = CELL_CENTRE; - } - Jpar.setLocation(loc); - Vpar.setLocation(loc); - Psi.setLocation(loc); - eta.setLocation(loc); - - ////////////////////////////////////////////////////////////// - auto& globalOptions = Options::root(); - auto& options = globalOptions["highbeta"]; - - constn0 = options["constn0"].withDefault(true); - // use the hyperbolic profile of n0. If both n0_fake_prof and - // T0_fake_prof are false, use the profiles from grid file - n0_fake_prof = options["n0_fake_prof"].withDefault(false); - // the total height of profile of N0, in percentage of Ni_x - n0_height = options["n0_height"].withDefault(0.4); - // the center or average of N0, in percentage of Ni_x - n0_ave = options["n0_ave"].withDefault(0.01); - // the width of the gradient of N0,in percentage of x - n0_width = options["n0_width"].withDefault(0.1); - // the grid number of the center of N0, in percentage of x - n0_center = options["n0_center"].withDefault(0.633); - // the start of flat region of N0 on SOL side, in percentage of x - n0_bottom_x = options["n0_bottom_x"].withDefault(0.81); - T0_fake_prof = options["T0_fake_prof"].withDefault(false); - // the amplitude of constant temperature, in percentage - Tconst = options["Tconst"].withDefault(-1.0); - - density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); - - evolve_jpar = - options["evolve_jpar"].doc("If true, evolve J raher than Psi").withDefault(false); - phi_constraint = options["phi_constraint"] - .doc("Use solver constraint for phi?") - .withDefault(false); - - // Effects to include/exclude - include_curvature = options["include_curvature"].withDefault(true); - include_jpar0 = options["include_jpar0"].withDefault(true); - evolve_pressure = options["evolve_pressure"].withDefault(true); - nogradparj = options["nogradparj"].withDefault(false); - - compress = options["compress"] - .doc("Include compressibility effects (evolve Vpar)?") - .withDefault(false); - gyroviscous = options["gyroviscous"].withDefault(false); - nonlinear = options["nonlinear"].doc("Include nonlinear terms?").withDefault(false); - - // option for ExB Poisson Bracket - bm_exb_flag = options["bm_exb_flag"] - .doc("ExB Poisson bracket method. 0=standard;1=simple;2=arakawa") - .withDefault(0); - switch (bm_exb_flag) { - case 0: { - bm_exb = BRACKET_STD; - output << "\tBrackets for ExB: default differencing\n"; - break; - } - case 1: { - bm_exb = BRACKET_SIMPLE; - output << "\tBrackets for ExB: simplified operator\n"; - break; - } - case 2: { - bm_exb = BRACKET_ARAKAWA; - output << "\tBrackets for ExB: Arakawa scheme\n"; - break; - } - case 3: { - bm_exb = BRACKET_CTU; - output << "\tBrackets for ExB: Corner Transport Upwind method\n"; - break; - } - default: - throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); - } + // Set locations of staggered variables + // Note, use of staggered grids in elm-pb is untested and may not be completely + // implemented. Parallel boundary conditions are especially likely to be wrong. + if (mesh->StaggerGrids) { + loc = CELL_YLOW; + } else { + loc = CELL_CENTRE; + } + Jpar.setLocation(loc); + Vpar.setLocation(loc); + Psi.setLocation(loc); + eta.setLocation(loc); + + ////////////////////////////////////////////////////////////// + auto &globalOptions = Options::root(); + auto &options = globalOptions["highbeta"]; + + constn0 = options["constn0"].withDefault(true); + // use the hyperbolic profile of n0. If both n0_fake_prof and + // T0_fake_prof are false, use the profiles from grid file + n0_fake_prof = options["n0_fake_prof"].withDefault(false); + // the total height of profile of N0, in percentage of Ni_x + n0_height = options["n0_height"].withDefault(0.4); + // the center or average of N0, in percentage of Ni_x + n0_ave = options["n0_ave"].withDefault(0.01); + // the width of the gradient of N0,in percentage of x + n0_width = options["n0_width"].withDefault(0.1); + // the grid number of the center of N0, in percentage of x + n0_center = options["n0_center"].withDefault(0.633); + // the start of flat region of N0 on SOL side, in percentage of x + n0_bottom_x = options["n0_bottom_x"].withDefault(0.81); + T0_fake_prof = options["T0_fake_prof"].withDefault(false); + // the amplitude of constant temperature, in percentage + Tconst = options["Tconst"].withDefault(-1.0); + + density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); + + evolve_jpar = + options["evolve_jpar"].doc("If true, evolve J raher than Psi").withDefault(false); + phi_constraint = options["phi_constraint"] + .doc("Use solver constraint for phi?") + .withDefault(false); - bm_mag_flag = - options["bm_mag_flag"].doc("magnetic flutter Poisson Bracket").withDefault(0); - switch (bm_mag_flag) { - case 0: { - bm_mag = BRACKET_STD; - output << "\tBrackets: default differencing\n"; - break; - } - case 1: { - bm_mag = BRACKET_SIMPLE; - output << "\tBrackets: simplified operator\n"; - break; - } - case 2: { - bm_mag = BRACKET_ARAKAWA; - output << "\tBrackets: Arakawa scheme\n"; - break; - } - case 3: { - bm_mag = BRACKET_CTU; - output << "\tBrackets: Corner Transport Upwind method\n"; - break; - } - default: - throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); - } + // Effects to include/exclude + include_curvature = options["include_curvature"].withDefault(true); + include_jpar0 = options["include_jpar0"].withDefault(true); + evolve_pressure = options["evolve_pressure"].withDefault(true); + nogradparj = options["nogradparj"].withDefault(false); + + compress = options["compress"] + .doc("Include compressibility effects (evolve Vpar)?") + .withDefault(false); + gyroviscous = options["gyroviscous"].withDefault(false); + nonlinear = options["nonlinear"].doc("Include nonlinear terms?").withDefault(false); + + // option for ExB Poisson Bracket + bm_exb_flag = options["bm_exb_flag"] + .doc("ExB Poisson bracket method. 0=standard;1=simple;2=arakawa") + .withDefault(0); + switch (bm_exb_flag) { + case 0: { + bm_exb = BRACKET_STD; + output << "\tBrackets for ExB: default differencing\n"; + break; + } + case 1: { + bm_exb = BRACKET_SIMPLE; + output << "\tBrackets for ExB: simplified operator\n"; + break; + } + case 2: { + bm_exb = BRACKET_ARAKAWA; + output << "\tBrackets for ExB: Arakawa scheme\n"; + break; + } + case 3: { + bm_exb = BRACKET_CTU; + output << "\tBrackets for ExB: Corner Transport Upwind method\n"; + break; + } + default: + throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); + } + + bm_mag_flag = + options["bm_mag_flag"].doc("magnetic flutter Poisson Bracket").withDefault(0); + switch (bm_mag_flag) { + case 0: { + bm_mag = BRACKET_STD; + output << "\tBrackets: default differencing\n"; + break; + } + case 1: { + bm_mag = BRACKET_SIMPLE; + output << "\tBrackets: simplified operator\n"; + break; + } + case 2: { + bm_mag = BRACKET_ARAKAWA; + output << "\tBrackets: Arakawa scheme\n"; + break; + } + case 3: { + bm_mag = BRACKET_CTU; + output << "\tBrackets: Corner Transport Upwind method\n"; + break; + } + default: + throw BoutException("Invalid choice of bracket method. Must be 0 - 3\n"); + } - eHall = options["eHall"] + eHall = options["eHall"] .doc("electron Hall or electron parallel pressue gradient effects?") .withDefault(false); - AA = options["AA"].doc("ion mass in units of proton mass").withDefault(1.0); - - diamag = options["diamag"].doc("Diamagnetic effects?").withDefault(false); - diamag_grad_t = options["diamag_grad_t"] - .doc("Grad_par(Te) term in Psi equation") - .withDefault(diamag); - diamag_phi0 = - options["diamag_phi0"].doc("Include equilibrium phi0").withDefault(diamag); - dia_fact = options["dia_fact"] - .doc("Scale diamagnetic effects by this factor") - .withDefault(1.0); - - // withflow or not - withflow = options["withflow"].withDefault(false); - // keep K-H term - K_H_term = options["K_H_term"].withDefault(true); - // velocity magnitude - D_0 = options["D_0"].withDefault(0.0); - // flowshear - D_s = options["D_s"].withDefault(0.0); - // flow location - x0 = options["x0"].withDefault(0.0); - // flow direction, -1 means negative electric field - sign = options["sign"].withDefault(1.0); - // a constant - D_min = options["D_min"].withDefault(3000.0); - - experiment_Er = options["experiment_Er"].withDefault(false); - - bool noshear = options["noshear"].withDefault(false); - - relax_j_vac = options["relax_j_vac"] - .doc("Relax vacuum current to zero") - .withDefault(false); - relax_j_tconst = options["relax_j_tconst"] - .doc("Time constant for relaxation of vacuum current. Alfven " - "(normalised) units") - .withDefault(0.1); - - // Toroidal filtering - filter_z = options["filter_z"] - .doc("Filter a single toroidal mode number? The mode to keep is " - "filter_z_mode.") - .withDefault(false); - filter_z_mode = options["filter_z_mode"] - .doc("Single toroidal mode number to keep") - .withDefault(1); - low_pass_z = options["low_pass_z"].doc("Low-pass filter").withDefault(-1); - zonal_flow = options["zonal_flow"] - .doc("Keep zonal (n=0) component of potential?") - .withDefault(false); - zonal_field = options["zonal_field"] - .doc("Keep zonal (n=0) component of magnetic potential?") - .withDefault(false); - zonal_bkgd = options["zonal_bkgd"] - .doc("Evolve zonal (n=0) pressure profile?") - .withDefault(false); - - // n = 0 electrostatic potential solve - split_n0 = options["split_n0"] - .doc("Solve zonal (n=0) component of potential using LaplaceXY?") - .withDefault(false); - if (split_n0) { - // Create an XY solver for n=0 component + AA = options["AA"].doc("ion mass in units of proton mass").withDefault(1.0); + + diamag = options["diamag"].doc("Diamagnetic effects?").withDefault(false); + diamag_grad_t = options["diamag_grad_t"] + .doc("Grad_par(Te) term in Psi equation") + .withDefault(diamag); + diamag_phi0 = + options["diamag_phi0"].doc("Include equilibrium phi0").withDefault(diamag); + dia_fact = options["dia_fact"] + .doc("Scale diamagnetic effects by this factor") + .withDefault(1.0); + + // withflow or not + withflow = options["withflow"].withDefault(false); + // keep K-H term + K_H_term = options["K_H_term"].withDefault(true); + // velocity magnitude + D_0 = options["D_0"].withDefault(0.0); + // flowshear + D_s = options["D_s"].withDefault(0.0); + // flow location + x0 = options["x0"].withDefault(0.0); + // flow direction, -1 means negative electric field + sign = options["sign"].withDefault(1.0); + // a constant + D_min = options["D_min"].withDefault(3000.0); + + experiment_Er = options["experiment_Er"].withDefault(false); + + bool noshear = options["noshear"].withDefault(false); + + relax_j_vac = options["relax_j_vac"] + .doc("Relax vacuum current to zero") + .withDefault(false); + relax_j_tconst = options["relax_j_tconst"] + .doc("Time constant for relaxation of vacuum current. Alfven " + "(normalised) units") + .withDefault(0.1); + + // Toroidal filtering + filter_z = options["filter_z"] + .doc("Filter a single toroidal mode number? The mode to keep is " + "filter_z_mode.") + .withDefault(false); + filter_z_mode = options["filter_z_mode"] + .doc("Single toroidal mode number to keep") + .withDefault(1); + low_pass_z = options["low_pass_z"].doc("Low-pass filter").withDefault(-1); + zonal_flow = options["zonal_flow"] + .doc("Keep zonal (n=0) component of potential?") + .withDefault(false); + zonal_field = options["zonal_field"] + .doc("Keep zonal (n=0) component of magnetic potential?") + .withDefault(false); + zonal_bkgd = options["zonal_bkgd"] + .doc("Evolve zonal (n=0) pressure profile?") + .withDefault(false); + + // n = 0 electrostatic potential solve + split_n0 = options["split_n0"] + .doc("Solve zonal (n=0) component of potential using LaplaceXY?") + .withDefault(false); + if (split_n0) { + // Create an XY solver for n=0 component #if BOUT_HAS_HYPRE - laplacexy = bout::utils::make_unique(mesh); + laplacexy = bout::utils::make_unique(mesh); #else - laplacexy = bout::utils::make_unique(mesh); + laplacexy = bout::utils::make_unique(mesh); #endif - // Set coefficients for Boussinesq solve - laplacexy->setCoefs(1.0, 0.0); - phi2D = 0.0; // Starting guess - phi2D.setBoundary("phi"); + // Set coefficients for Boussinesq solve + laplacexy->setCoefs(1.0, 0.0); + phi2D = 0.0; // Starting guess + phi2D.setBoundary("phi"); } // Radial smoothing @@ -616,1479 +616,1469 @@ class ELMpb : public PhysicsModel { options["hyperresist"].doc("Hyper-resistivity coefficient").withDefault(-1.0); ehyperviscos = options["ehyperviscos"] .doc("electron Hyper-viscosity coefficient") - .withDefault(-1.0); - spitzer_resist = options["spitzer_resist"] - .doc("Use Spitzer resistivity?") - .withDefault(false); - Zeff = options["Zeff"].withDefault(2.0); // Z effective - - // Inner boundary damping - damp_width = options["damp_width"] - .doc("Width of the radial damping regions, in grid cells") - .withDefault(0); - damp_t_const = - options["damp_t_const"] - .doc("Time constant for damping in radial regions. Normalised time units.") - .withDefault(0.1); - - // Viscosity and hyper-viscosity - viscos_par = options["viscos_par"].doc("Parallel viscosity").withDefault(-1.0); - viscos_perp = options["viscos_perp"].doc("Perpendicular viscosity").withDefault(-1.0); - hyperviscos = options["hyperviscos"].doc("Radial hyperviscosity").withDefault(-1.0); - - diffusion_par = - options["diffusion_par"].doc("Parallel pressure diffusion").withDefault(-1.0); - diffusion_p4 = options["diffusion_p4"] - .doc("parallel hyper-viscous diffusion for pressure") - .withDefault(-1.0); - diffusion_u4 = options["diffusion_u4"] - .doc("parallel hyper-viscous diffusion for vorticity") - .withDefault(-1.0); - diffusion_a4 = options["diffusion_a4"] - .doc("parallel hyper-viscous diffusion for vector potential") - .withDefault(-1.0); - - // heating factor in pressure - // heating power in pressure - heating_P = options["heating_P"].withDefault(-1.0); - // the percentage of radial grid points for heating profile radial - // width in pressure - hp_width = options["hp_width"].withDefault(0.1); - // the percentage of radial grid points for heating profile radial - // domain in pressure - hp_length = options["hp_length"].withDefault(0.04); - - // sink factor in pressure - // sink in pressure - sink_P = options["sink_P"].withDefault(-1.0); - // the percentage of radial grid points for sink profile radial - // width in pressure - sp_width = options["sp_width"].withDefault(0.05); - // the percentage of radial grid points for sink profile radial - // domain in pressure - sp_length = options["sp_length"].withDefault(0.04); - - // left edge sink factor in vorticity - // left edge sink in vorticity - sink_Ul = options["sink_Ul"].withDefault(-1.0); - // the percentage of left edge radial grid points for sink profile - // radial width in vorticity - su_widthl = options["su_widthl"].withDefault(0.06); - // the percentage of left edge radial grid points for sink profile - // radial domain in vorticity - su_lengthl = options["su_lengthl"].withDefault(0.15); - - // right edge sink factor in vorticity - // right edge sink in vorticity - sink_Ur = options["sink_Ur"].withDefault(-1.0); - // the percentage of right edge radial grid points for sink profile - // radial width in vorticity - su_widthr = options["su_widthr"].withDefault(0.06); - // the percentage of right edge radial grid points for sink profile - // radial domain in vorticity - su_lengthr = options["su_lengthr"].withDefault(0.15); - - // Compressional terms - phi_curv = - options["phi_curv"].doc("ExB compression in P equation?").withDefault(true); - g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); - - x = (Psixy - Psiaxis) / (Psibndry - Psiaxis); - - if (experiment_Er) { // get er from experiment - mesh->get(Dphi0, "Epsi"); - diamag_phi0 = false; - K_H_term = false; - } else { - Dphi0 = -D_min - 0.5 * D_0 * (1.0 - tanh(D_s * (x - x0))); - } + .withDefault(-1.0); + spitzer_resist = options["spitzer_resist"] + .doc("Use Spitzer resistivity?") + .withDefault(false); + Zeff = options["Zeff"].withDefault(2.0); // Z effective + + // Inner boundary damping + damp_width = options["damp_width"] + .doc("Width of the radial damping regions, in grid cells") + .withDefault(0); + damp_t_const = + options["damp_t_const"] + .doc("Time constant for damping in radial regions. Normalised time units.") + .withDefault(0.1); + + // Viscosity and hyper-viscosity + viscos_par = options["viscos_par"].doc("Parallel viscosity").withDefault(-1.0); + viscos_perp = options["viscos_perp"].doc("Perpendicular viscosity").withDefault(-1.0); + hyperviscos = options["hyperviscos"].doc("Radial hyperviscosity").withDefault(-1.0); + + diffusion_par = + options["diffusion_par"].doc("Parallel pressure diffusion").withDefault(-1.0); + diffusion_p4 = options["diffusion_p4"] + .doc("parallel hyper-viscous diffusion for pressure") + .withDefault(-1.0); + diffusion_u4 = options["diffusion_u4"] + .doc("parallel hyper-viscous diffusion for vorticity") + .withDefault(-1.0); + diffusion_a4 = options["diffusion_a4"] + .doc("parallel hyper-viscous diffusion for vector potential") + .withDefault(-1.0); + + // heating factor in pressure + // heating power in pressure + heating_P = options["heating_P"].withDefault(-1.0); + // the percentage of radial grid points for heating profile radial + // width in pressure + hp_width = options["hp_width"].withDefault(0.1); + // the percentage of radial grid points for heating profile radial + // domain in pressure + hp_length = options["hp_length"].withDefault(0.04); + + // sink factor in pressure + // sink in pressure + sink_P = options["sink_P"].withDefault(-1.0); + // the percentage of radial grid points for sink profile radial + // width in pressure + sp_width = options["sp_width"].withDefault(0.05); + // the percentage of radial grid points for sink profile radial + // domain in pressure + sp_length = options["sp_length"].withDefault(0.04); + + // left edge sink factor in vorticity + // left edge sink in vorticity + sink_Ul = options["sink_Ul"].withDefault(-1.0); + // the percentage of left edge radial grid points for sink profile + // radial width in vorticity + su_widthl = options["su_widthl"].withDefault(0.06); + // the percentage of left edge radial grid points for sink profile + // radial domain in vorticity + su_lengthl = options["su_lengthl"].withDefault(0.15); + + // right edge sink factor in vorticity + // right edge sink in vorticity + sink_Ur = options["sink_Ur"].withDefault(-1.0); + // the percentage of right edge radial grid points for sink profile + // radial width in vorticity + su_widthr = options["su_widthr"].withDefault(0.06); + // the percentage of right edge radial grid points for sink profile + // radial domain in vorticity + su_lengthr = options["su_lengthr"].withDefault(0.15); + + // Compressional terms + phi_curv = + options["phi_curv"].doc("ExB compression in P equation?").withDefault(true); + g = options["gamma"].doc("Ratio of specific heats").withDefault(5.0 / 3.0); + + x = (Psixy - Psiaxis) / (Psibndry - Psiaxis); + + if (experiment_Er) { // get er from experiment + mesh->get(Dphi0, "Epsi"); + diamag_phi0 = false; + K_H_term = false; + } else { + Dphi0 = -D_min - 0.5 * D_0 * (1.0 - tanh(D_s * (x - x0))); + } - if (sign < 0) { // change flow direction - Dphi0 *= -1; - } + if (sign < 0) { // change flow direction + Dphi0 *= -1; + } - if (!mesh->IncIntShear) { - noshear = true; - } + if (mesh->get(Bbar, "bmag") != 0) { // Typical magnetic field + Bbar = 1.0; + } + if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale + Lbar = 1.0; + } - if (mesh->get(Bbar, "bmag") != 0) { // Typical magnetic field - Bbar = 1.0; - } - if (mesh->get(Lbar, "rmag") != 0) { // Typical length scale - Lbar = 1.0; - } - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); + ////////////////////////////////////////////////////////////// + // SHIFTED RADIAL COORDINATES - auto Bpxy = tokamak_options.Bpxy; - auto hthe = tokamak_options.hthe; - auto Rxy = tokamak_options.Rxy; - auto Btxy = tokamak_options.Btxy; - auto B0 = tokamak_options.Bxy; + BoutReal shearFactor = 1.0; + if (!noshear && mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + metric->setIntShiftTorsion(tokamak_options.I); - V0 = -Rxy * Bpxy * Dphi0 / B0; + } else { + // Dimits style, using local coordinate system + if (include_curvature) { + b0xcv.z += tokamak_options.I * b0xcv.x; + } + shearFactor = 0.0; // I disappears from metric + } - if (simple_rmp) { - include_rmp = true; - } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lbar, Bbar, shearFactor); - // toroidal and poloidal mode numbers - const int rmp_n = - options["rmp_n"].doc("Simple RMP toroidal mode number").withDefault(3); - const int rmp_m = - options["rmp_m"].doc("Simple RMP poloidal mode number").withDefault(9); - const int rmp_polwid = options["rmp_polwid"] - .doc("Poloidal width (-ve -> full, fraction of 2pi)") - .withDefault(-1.0); - const int rmp_polpeak = options["rmp_polpeak"] - .doc("Peak poloidal location (fraction of 2pi)") - .withDefault(0.5); - rmp_vac_mask = - options["rmp_vac_mask"].doc("Should a vacuum mask be applied?").withDefault(true); - // Divide n by the size of the domain - const int zperiod = globalOptions["zperiod"].withDefault(1); - - if (include_rmp) { - // Including external field coils. - if (simple_rmp) { - // Use a fairly simple form for the perturbation - Field2D pol_angle; - if (mesh->get(pol_angle, "pol_angle") != 0) { - output_warn.write(" ***WARNING: need poloidal angle for simple RMP\n"); - include_rmp = false; - } else { - if ((rmp_n % zperiod) != 0) { - output_warn.write( - " ***WARNING: rmp_n ({:d}) not a multiple of zperiod ({:d})\n", rmp_n, - zperiod); - } - - output.write("\tMagnetic perturbation: n = {:d}, m = {:d}, magnitude {:e} Tm\n", - rmp_n, rmp_m, rmp_factor); - - rmp_Psi0 = 0.0; - if (mesh->lastX()) { - // Set the outer boundary - for (int jx = mesh->LocalNx - 4; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { + auto Bpxy = tokamak_options.Bpxy; + auto hthe = tokamak_options.hthe; + auto Rxy = tokamak_options.Rxy; + auto Btxy = tokamak_options.Btxy; + auto B0 = tokamak_options.Bxy; - BoutReal angle = - rmp_m * pol_angle(jx, jy) - + rmp_n * ((BoutReal)jz) * mesh->getCoordinates()->dz(jx, jy, jz); - rmp_Psi0(jx, jy, jz) = - (((BoutReal)(jx - 4)) / ((BoutReal)(mesh->LocalNx - 5))) - * rmp_factor * cos(angle); - if (rmp_polwid > 0.0) { - // Multiply by a Gaussian in poloidal angle - BoutReal gx = - ((pol_angle(jx, jy) / (2. * PI)) - rmp_polpeak) / rmp_polwid; - rmp_Psi0(jx, jy, jz) *= exp(-gx * gx); - } - } - } - } - } - - // Now have a simple model for Psi due to coils at the outer boundary - // Need to calculate Psi inside the domain, enforcing j = 0 - - Jpar = 0.0; - auto psiLap = std::unique_ptr{Laplacian::create(nullptr, loc)}; - psiLap->setInnerBoundaryFlags(INVERT_AC_GRAD); // Zero gradient inner BC - psiLap->setOuterBoundaryFlags(INVERT_SET); // Set to rmp_Psi0 on outer boundary - rmp_Psi0 = psiLap->solve(Jpar, rmp_Psi0); - mesh->communicate(rmp_Psi0); - } - } else { - // Load perturbation from grid file. - include_rmp = mesh->get(rmp_Psi0, "rmp_A") == 0; // Only include if found - if (!include_rmp) { - output_warn.write("WARNING: Couldn't read 'rmp_A' from grid file\n"); - } - // Multiply by factor - rmp_Psi0 *= rmp_factor; - } - } + V0 = -Rxy * Bpxy * Dphi0 / B0; - if (!include_curvature) { - b0xcv = 0.0; - } + if (simple_rmp) { + include_rmp = true; + } - if (!include_jpar0) { - J0 = 0.0; - } + // toroidal and poloidal mode numbers + const int rmp_n = + options["rmp_n"].doc("Simple RMP toroidal mode number").withDefault(3); + const int rmp_m = + options["rmp_m"].doc("Simple RMP poloidal mode number").withDefault(9); + const int rmp_polwid = options["rmp_polwid"] + .doc("Poloidal width (-ve -> full, fraction of 2pi)") + .withDefault(-1.0); + const int rmp_polpeak = options["rmp_polpeak"] + .doc("Peak poloidal location (fraction of 2pi)") + .withDefault(0.5); + rmp_vac_mask = + options["rmp_vac_mask"].doc("Should a vacuum mask be applied?").withDefault(true); + // Divide n by the size of the domain + const int zperiod = globalOptions["zperiod"].withDefault(1); + + if (include_rmp) { + // Including external field coils. + if (simple_rmp) { + // Use a fairly simple form for the perturbation + Field2D pol_angle; + if (mesh->get(pol_angle, "pol_angle") != 0) { + output_warn.write(" ***WARNING: need poloidal angle for simple RMP\n"); + include_rmp = false; + } else { + if ((rmp_n % zperiod) != 0) { + output_warn.write( + " ***WARNING: rmp_n ({:d}) not a multiple of zperiod ({:d})\n", rmp_n, + zperiod); + } + + output.write("\tMagnetic perturbation: n = {:d}, m = {:d}, magnitude {:e} Tm\n", + rmp_n, rmp_m, rmp_factor); + + rmp_Psi0 = 0.0; + if (mesh->lastX()) { + // Set the outer boundary + for (int jx = mesh->LocalNx - 4; jx < mesh->LocalNx; jx++) { + for (int jy = 0; jy < mesh->LocalNy; jy++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { + + BoutReal angle = + rmp_m * pol_angle(jx, jy) + + rmp_n * ((BoutReal) jz) * mesh->getCoordinates()->dz(jx, jy, jz); + rmp_Psi0(jx, jy, jz) = + (((BoutReal) (jx - 4)) / ((BoutReal) (mesh->LocalNx - 5))) + * rmp_factor * cos(angle); + if (rmp_polwid > 0.0) { + // Multiply by a Gaussian in poloidal angle + BoutReal gx = + ((pol_angle(jx, jy) / (2. * PI)) - rmp_polpeak) / rmp_polwid; + rmp_Psi0(jx, jy, jz) *= exp(-gx * gx); + } + } + } + } + } + + // Now have a simple model for Psi due to coils at the outer boundary + // Need to calculate Psi inside the domain, enforcing j = 0 + + Jpar = 0.0; + auto psiLap = std::unique_ptr{Laplacian::create(nullptr, loc)}; + psiLap->setInnerBoundaryFlags(INVERT_AC_GRAD); // Zero gradient inner BC + psiLap->setOuterBoundaryFlags(INVERT_SET); // Set to rmp_Psi0 on outer boundary + rmp_Psi0 = psiLap->solve(Jpar, rmp_Psi0); + mesh->communicate(rmp_Psi0); + } + } else { + // Load perturbation from grid file. + include_rmp = mesh->get(rmp_Psi0, "rmp_A") == 0; // Only include if found + if (!include_rmp) { + output_warn.write("WARNING: Couldn't read 'rmp_A' from grid file\n"); + } + // Multiply by factor + rmp_Psi0 *= rmp_factor; + } + } - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; - } - } + if (!include_curvature) { + b0xcv = 0.0; + } - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES + if (!include_jpar0) { + J0 = 0.0; + } - if (not mesh->IncIntShear) { - // Dimits style, using local coordinate system - if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; - } - } - ////////////////////////////////////////////////////////////// - // NORMALISE QUANTITIES + ////////////////////////////////////////////////////////////// + // NORMALISE QUANTITIES - Va = sqrt(Bbar * Bbar / (MU0 * density * Mi)); + Va = sqrt(Bbar * Bbar / (MU0 * density * Mi)); - Tbar = Lbar / Va; + Tbar = Lbar / Va; - dnorm = dia_fact * Mi / (2. * 1.602e-19 * Bbar * Tbar); + dnorm = dia_fact * Mi / (2. * 1.602e-19 * Bbar * Tbar); - delta_i = AA * 60.67 * 5.31e5 / sqrt(density / 1e6) / (Lbar * 100.0); + delta_i = AA * 60.67 * 5.31e5 / sqrt(density / 1e6) / (Lbar * 100.0); - output.write("Normalisations: Bbar = {:e} T Lbar = {:e} m\n", Bbar, Lbar); - output.write(" Va = {:e} m/s Tbar = {:e} s\n", Va, Tbar); - output.write(" dnorm = {:e}\n", dnorm); - output.write(" Resistivity\n"); + output.write("Normalisations: Bbar = {:e} T Lbar = {:e} m\n", Bbar, Lbar); + output.write(" Va = {:e} m/s Tbar = {:e} s\n", Va, Tbar); + output.write(" dnorm = {:e}\n", dnorm); + output.write(" Resistivity\n"); - if (gyroviscous) { - omega_i = 9.58e7 * Zeff * Bbar; - Upara2 = 0.5 / (Tbar * omega_i); - output.write("Upara2 = {:e} Omega_i = {:e}\n", Upara2, omega_i); - } + if (gyroviscous) { + omega_i = 9.58e7 * Zeff * Bbar; + Upara2 = 0.5 / (Tbar * omega_i); + output.write("Upara2 = {:e} Omega_i = {:e}\n", Upara2, omega_i); + } - if (eHall) { - output.write(" delta_i = {:e} AA = {:e} \n", delta_i, AA); - } + if (eHall) { + output.write(" delta_i = {:e} AA = {:e} \n", delta_i, AA); + } - if (vac_lund > 0.0) { - output.write(" Vacuum Tau_R = {:e} s eta = {:e} Ohm m\n", vac_lund * Tbar, - MU0 * Lbar * Lbar / (vac_lund * Tbar)); - vac_resist = 1. / vac_lund; - } else { - output.write(" Vacuum - Zero resistivity -\n"); - vac_resist = 0.0; - } - if (core_lund > 0.0) { - output.write(" Core Tau_R = {:e} s eta = {:e} Ohm m\n", - core_lund * Tbar, MU0 * Lbar * Lbar / (core_lund * Tbar)); - core_resist = 1. / core_lund; - } else { - output.write(" Core - Zero resistivity -\n"); - core_resist = 0.0; - } + if (vac_lund > 0.0) { + output.write(" Vacuum Tau_R = {:e} s eta = {:e} Ohm m\n", vac_lund * Tbar, + MU0 * Lbar * Lbar / (vac_lund * Tbar)); + vac_resist = 1. / vac_lund; + } else { + output.write(" Vacuum - Zero resistivity -\n"); + vac_resist = 0.0; + } + if (core_lund > 0.0) { + output.write(" Core Tau_R = {:e} s eta = {:e} Ohm m\n", + core_lund * Tbar, MU0 * Lbar * Lbar / (core_lund * Tbar)); + core_resist = 1. / core_lund; + } else { + output.write(" Core - Zero resistivity -\n"); + core_resist = 0.0; + } - if (hyperresist > 0.0) { - output.write(" Hyper-resistivity coefficient: {:e}\n", hyperresist); - } + if (hyperresist > 0.0) { + output.write(" Hyper-resistivity coefficient: {:e}\n", hyperresist); + } - if (ehyperviscos > 0.0) { - output.write(" electron Hyper-viscosity coefficient: {:e}\n", ehyperviscos); - } + if (ehyperviscos > 0.0) { + output.write(" electron Hyper-viscosity coefficient: {:e}\n", ehyperviscos); + } - if (hyperviscos > 0.0) { - output.write(" Hyper-viscosity coefficient: {:e}\n", hyperviscos); - SAVE_ONCE(hyper_mu_x); - } + if (hyperviscos > 0.0) { + output.write(" Hyper-viscosity coefficient: {:e}\n", hyperviscos); + SAVE_ONCE(hyper_mu_x); + } - if (diffusion_par > 0.0) { - output.write(" diffusion_par: {:e}\n", diffusion_par); - SAVE_ONCE(diffusion_par); - } + if (diffusion_par > 0.0) { + output.write(" diffusion_par: {:e}\n", diffusion_par); + SAVE_ONCE(diffusion_par); + } - // xqx: parallel hyper-viscous diffusion for pressure - if (diffusion_p4 > 0.0) { - output.write(" diffusion_p4: {:e}\n", diffusion_p4); - SAVE_ONCE(diffusion_p4); - } + // xqx: parallel hyper-viscous diffusion for pressure + if (diffusion_p4 > 0.0) { + output.write(" diffusion_p4: {:e}\n", diffusion_p4); + SAVE_ONCE(diffusion_p4); + } - // xqx: parallel hyper-viscous diffusion for vorticity - if (diffusion_u4 > 0.0) { - output.write(" diffusion_u4: {:e}\n", diffusion_u4); - SAVE_ONCE(diffusion_u4) - } + // xqx: parallel hyper-viscous diffusion for vorticity + if (diffusion_u4 > 0.0) { + output.write(" diffusion_u4: {:e}\n", diffusion_u4); + SAVE_ONCE(diffusion_u4) + } - // xqx: parallel hyper-viscous diffusion for vector potential - if (diffusion_a4 > 0.0) { - output.write(" diffusion_a4: {:e}\n", diffusion_a4); - SAVE_ONCE(diffusion_a4); - } + // xqx: parallel hyper-viscous diffusion for vector potential + if (diffusion_a4 > 0.0) { + output.write(" diffusion_a4: {:e}\n", diffusion_a4); + SAVE_ONCE(diffusion_a4); + } - if (heating_P > 0.0) { - output.write(" heating_P(watts): {:e}\n", heating_P); + if (heating_P > 0.0) { + output.write(" heating_P(watts): {:e}\n", heating_P); - output.write(" hp_width(%%): {:e}\n", hp_width); + output.write(" hp_width(%%): {:e}\n", hp_width); - output.write(" hp_length(%%): {:e}\n", hp_length); + output.write(" hp_length(%%): {:e}\n", hp_length); - SAVE_ONCE(heating_P, hp_width, hp_length); - } + SAVE_ONCE(heating_P, hp_width, hp_length); + } - if (sink_P > 0.0) { - output.write(" sink_P(rate): {:e}\n", sink_P); - output.write(" sp_width(%%): {:e}\n", sp_width); - output.write(" sp_length(%%): {:e}\n", sp_length); + if (sink_P > 0.0) { + output.write(" sink_P(rate): {:e}\n", sink_P); + output.write(" sp_width(%%): {:e}\n", sp_width); + output.write(" sp_length(%%): {:e}\n", sp_length); - SAVE_ONCE(sink_P, sp_width, sp_length); - } + SAVE_ONCE(sink_P, sp_width, sp_length); + } - if (K_H_term) { - output.write(" keep K-H term\n"); - } else { - output.write(" drop K-H term\n"); - } + if (K_H_term) { + output.write(" keep K-H term\n"); + } else { + output.write(" drop K-H term\n"); + } - Field2D Te; - Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV + Field2D Te; + Te = P0 / (2.0 * density * 1.602e-19); // Temperature in eV - J0 = -MU0 * Lbar * J0 / B0; - P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); - V0 = V0 / Va; - Dphi0 *= Tbar; + J0 = -MU0 * Lbar * J0 / B0; + P0 = 2.0 * MU0 * P0 / (Bbar * Bbar); + V0 = V0 / Va; + Dphi0 *= Tbar; - b0xcv.x /= Bbar; - b0xcv.y *= Lbar * Lbar; - b0xcv.z *= Lbar * Lbar; + b0xcv.x /= Bbar; + b0xcv.y *= Lbar * Lbar; + b0xcv.z *= Lbar * Lbar; - if (constn0) { - T0_fake_prof = false; - n0_fake_prof = false; - } else { - Nbar = 1.0; - Tibar = 1000.0; - Tebar = 1000.0; + if (constn0) { + T0_fake_prof = false; + n0_fake_prof = false; + } else { + Nbar = 1.0; + Tibar = 1000.0; + Tebar = 1000.0; + + if ((!T0_fake_prof) && n0_fake_prof) { + N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); + + Ti0 = P0 / N0 / 2.0; + Te0 = Ti0; + } else if (T0_fake_prof) { + Ti0 = Tconst; + Te0 = Ti0; + N0 = P0 / (Ti0 + Te0); + } else { + if (mesh->get(N0, "Niexp") != 0) { // N_i0 + throw BoutException("Error: Cannot read Ni0 from grid\n"); + } - if ((!T0_fake_prof) && n0_fake_prof) { - N0 = N0tanh(n0_height * Nbar, n0_ave * Nbar, n0_width, n0_center, n0_bottom_x); + if (mesh->get(Ti0, "Tiexp") != 0) { // T_i0 + throw BoutException("Error: Cannot read Ti0 from grid\n"); + } - Ti0 = P0 / N0 / 2.0; - Te0 = Ti0; - } else if (T0_fake_prof) { - Ti0 = Tconst; - Te0 = Ti0; - N0 = P0 / (Ti0 + Te0); - } else { - if (mesh->get(N0, "Niexp") != 0) { // N_i0 - throw BoutException("Error: Cannot read Ni0 from grid\n"); + if (mesh->get(Te0, "Teexp") != 0) { // T_e0 + throw BoutException("Error: Cannot read Te0 from grid\n"); + } + N0 /= Nbar; + Ti0 /= Tibar; + Te0 /= Tebar; + } } - if (mesh->get(Ti0, "Tiexp") != 0) { // T_i0 - throw BoutException("Error: Cannot read Ti0 from grid\n"); + if (gyroviscous) { + Dperp2Phi0.setLocation(CELL_CENTRE); + Dperp2Phi0.setBoundary("phi"); + Dperp2Phi.setLocation(CELL_CENTRE); + Dperp2Phi.setBoundary("phi"); + GradPhi02.setLocation(CELL_CENTRE); + GradPhi02.setBoundary("phi"); + GradcPhi.setLocation(CELL_CENTRE); + GradcPhi.setBoundary("phi"); + Dperp2Pi0.setLocation(CELL_CENTRE); + Dperp2Pi0.setBoundary("P"); + Dperp2Pi.setLocation(CELL_CENTRE); + Dperp2Pi.setBoundary("P"); + bracketPhi0P.setLocation(CELL_CENTRE); + bracketPhi0P.setBoundary("P"); + bracketPhiP0.setLocation(CELL_CENTRE); + bracketPhiP0.setBoundary("P"); + if (nonlinear) { + GradPhi2.setLocation(CELL_CENTRE); + GradPhi2.setBoundary("phi"); + bracketPhiP.setLocation(CELL_CENTRE); + bracketPhiP.setBoundary("P"); + } } - if (mesh->get(Te0, "Teexp") != 0) { // T_e0 - throw BoutException("Error: Cannot read Te0 from grid\n"); - } - N0 /= Nbar; - Ti0 /= Tibar; - Te0 /= Tebar; - } - } + BoutReal pnorm = max(P0, true); // Maximum over all processors - if (gyroviscous) { - Dperp2Phi0.setLocation(CELL_CENTRE); - Dperp2Phi0.setBoundary("phi"); - Dperp2Phi.setLocation(CELL_CENTRE); - Dperp2Phi.setBoundary("phi"); - GradPhi02.setLocation(CELL_CENTRE); - GradPhi02.setBoundary("phi"); - GradcPhi.setLocation(CELL_CENTRE); - GradcPhi.setBoundary("phi"); - Dperp2Pi0.setLocation(CELL_CENTRE); - Dperp2Pi0.setBoundary("P"); - Dperp2Pi.setLocation(CELL_CENTRE); - Dperp2Pi.setBoundary("P"); - bracketPhi0P.setLocation(CELL_CENTRE); - bracketPhi0P.setBoundary("P"); - bracketPhiP0.setLocation(CELL_CENTRE); - bracketPhiP0.setBoundary("P"); - if (nonlinear) { - GradPhi2.setLocation(CELL_CENTRE); - GradPhi2.setBoundary("phi"); - bracketPhiP.setLocation(CELL_CENTRE); - bracketPhiP.setBoundary("P"); - } - } + vacuum_pressure *= pnorm; // Get pressure from fraction + vacuum_trans *= pnorm; - BoutReal pnorm = max(P0, true); // Maximum over all processors - - vacuum_pressure *= pnorm; // Get pressure from fraction - vacuum_trans *= pnorm; - - // Transitions from 0 in core to 1 in vacuum - vac_mask = (1.0 - tanh((P0 - vacuum_pressure) / vacuum_trans)) / 2.0; - - if (spitzer_resist) { - // Use Spitzer resistivity - output.write("\tTemperature: {:e} -> {:e} [eV]\n", min(Te), max(Te)); - eta = 0.51 * 1.03e-4 * Zeff * 20. - * pow(Te, -1.5); // eta in Ohm-m. NOTE: ln(Lambda) = 20 - output.write("\tSpitzer resistivity: {:e} -> {:e} [Ohm m]\n", min(eta), max(eta)); - eta /= MU0 * Va * Lbar; - output.write("\t -> Lundquist {:e} -> {:e}\n", 1.0 / max(eta), 1.0 / min(eta)); - } else { - // transition from 0 for large P0 to resistivity for small P0 - eta = core_resist + (vac_resist - core_resist) * vac_mask; - } + // Transitions from 0 in core to 1 in vacuum + vac_mask = (1.0 - tanh((P0 - vacuum_pressure) / vacuum_trans)) / 2.0; - eta = interp_to(eta, loc); - - SAVE_ONCE(eta); - - if (include_rmp) { - // Normalise RMP quantities - - rmp_Psi0 /= Bbar * Lbar; - - rmp_ramp /= Tbar; - rmp_freq *= Tbar; - rmp_rotate *= Tbar; - - rmp_Psi = rmp_Psi0; - rmp_dApdt = 0.0; - - bool apar_changing = false; - - output.write("Including magnetic perturbation\n"); - if (rmp_ramp > 0.0) { - output.write("\tRamping up over period t = {:e} ({:e} ms)\n", rmp_ramp, - rmp_ramp * Tbar * 1000.); - apar_changing = true; - } - if (rmp_freq > 0.0) { - output.write("\tOscillating with frequency f = {:e} ({:e} kHz)\n", rmp_freq, - rmp_freq / Tbar / 1000.); - apar_changing = true; - } - if (rmp_rotate != 0.0) { - output.write("\tRotating with a frequency f = {:e} ({:e} kHz)\n", rmp_rotate, - rmp_rotate / Tbar / 1000.); - apar_changing = true; - } - - if (apar_changing) { - SAVE_REPEAT(rmp_Psi, rmp_dApdt); - } else { - SAVE_ONCE(rmp_Psi); - } - } else { - rmp_Psi = 0.0; - } + if (spitzer_resist) { + // Use Spitzer resistivity + output.write("\tTemperature: {:e} -> {:e} [eV]\n", min(Te), max(Te)); + eta = 0.51 * 1.03e-4 * Zeff * 20. + * pow(Te, -1.5); // eta in Ohm-m. NOTE: ln(Lambda) = 20 + output.write("\tSpitzer resistivity: {:e} -> {:e} [Ohm m]\n", min(eta), max(eta)); + eta /= MU0 * Va * Lbar; + output.write("\t -> Lundquist {:e} -> {:e}\n", 1.0 / max(eta), 1.0 / min(eta)); + } else { + // transition from 0 for large P0 to resistivity for small P0 + eta = core_resist + (vac_resist - core_resist) * vac_mask; + } - // Set B field vector + eta = interp_to(eta, loc); - B0vec.covariant = false; - B0vec.x = 0.; - B0vec.y = Bpxy / hthe; - B0vec.z = 0.; + SAVE_ONCE(eta); - V0net.covariant = false; // presentation for net flow - V0net.x = 0.; - V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; - V0net.z = -Dphi0; + if (include_rmp) { + // Normalise RMP quantities - U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term + rmp_Psi0 /= Bbar * Lbar; - /**************** SET EVOLVING VARIABLES *************/ + rmp_ramp /= Tbar; + rmp_freq *= Tbar; + rmp_rotate *= Tbar; - // Tell BOUT which variables to evolve - SOLVE_FOR(U, P); + rmp_Psi = rmp_Psi0; + rmp_dApdt = 0.0; - if (evolve_jpar) { - output.write("Solving for jpar: Inverting to get Psi\n"); - SOLVE_FOR(Jpar); - SAVE_REPEAT(Psi); - } else { - output.write("Solving for Psi, Differentiating to get jpar\n"); - SOLVE_FOR(Psi); - SAVE_REPEAT(Jpar); - } + bool apar_changing = false; - if (compress) { - output.write("Including compression (Vpar) effects\n"); + output.write("Including magnetic perturbation\n"); + if (rmp_ramp > 0.0) { + output.write("\tRamping up over period t = {:e} ({:e} ms)\n", rmp_ramp, + rmp_ramp * Tbar * 1000.); + apar_changing = true; + } + if (rmp_freq > 0.0) { + output.write("\tOscillating with frequency f = {:e} ({:e} kHz)\n", rmp_freq, + rmp_freq / Tbar / 1000.); + apar_changing = true; + } + if (rmp_rotate != 0.0) { + output.write("\tRotating with a frequency f = {:e} ({:e} kHz)\n", rmp_rotate, + rmp_rotate / Tbar / 1000.); + apar_changing = true; + } - SOLVE_FOR(Vpar); - comms.add(Vpar); + if (apar_changing) { + SAVE_REPEAT(rmp_Psi, rmp_dApdt); + } else { + SAVE_ONCE(rmp_Psi); + } + } else { + rmp_Psi = 0.0; + } - beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); - gradparB = Grad_par(B0) / B0; + // Set B field vector - output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); - } else { - Vpar = 0.0; - } + B0vec.covariant = false; + B0vec.x = 0.; + B0vec.y = Bpxy / hthe; + B0vec.z = 0.; - if (phi_constraint) { - // Implicit Phi solve using IDA + V0net.covariant = false; // presentation for net flow + V0net.x = 0.; + V0net.y = Rxy * Btxy * Bpxy / (hthe * B0 * B0) * Dphi0; + V0net.z = -Dphi0; - if (!solver->constraints()) { - throw BoutException("Cannot constrain. Run again with phi_constraint=false.\n"); - } + U0 = B0vec * Curl(V0net) / B0; // get 0th vorticity for Kelvin-Holmholtz term - solver->constraint(phi, C_phi, "phi"); + /**************** SET EVOLVING VARIABLES *************/ - // Set preconditioner - setPrecon(&ELMpb::precon_phi); + // Tell BOUT which variables to evolve + SOLVE_FOR(U, P); - } else { - // Phi solved in RHS (explicitly) - SAVE_REPEAT(phi); + if (evolve_jpar) { + output.write("Solving for jpar: Inverting to get Psi\n"); + SOLVE_FOR(Jpar); + SAVE_REPEAT(Psi); + } else { + output.write("Solving for Psi, Differentiating to get jpar\n"); + SOLVE_FOR(Psi); + SAVE_REPEAT(Jpar); + } - // Set preconditioner - setPrecon(&ELMpb::precon); + if (compress) { + output.write("Including compression (Vpar) effects\n"); - // Set Jacobian - setJacobian((jacobianfunc)&ELMpb::jacobian); - } + SOLVE_FOR(Vpar); + comms.add(Vpar); - // Diamagnetic phi0 - if (diamag_phi0) { - if (constn0) { - phi0 = -0.5 * dnorm * P0 / B0; - } else { - // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift - phi0 = -0.5 * dnorm * P0 / B0 / N0; - } - SAVE_ONCE(phi0); - } else { - phi0 = 0.0; - } + beta = B0 * B0 / (0.5 + (B0 * B0 / (g * P0))); + gradparB = Grad_par(B0) / B0; - // Add some equilibrium quantities and normalisations - // everything needed to recover physical units - SAVE_ONCE(J0, P0); - SAVE_ONCE(density, Lbar, Bbar, Tbar); - SAVE_ONCE(Va, B0); - SAVE_ONCE(Dphi0, U0); - SAVE_ONCE(V0); - if (!constn0) { - SAVE_ONCE(Ti0, Te0, N0); - } + output.write("Beta in range {:e} -> {:e}\n", min(beta), max(beta)); + } else { + Vpar = 0.0; + } - // Create a solver for the Laplacian - phiSolver = Laplacian::create(&globalOptions["phiSolver"]); + if (phi_constraint) { + // Implicit Phi solve using IDA - aparSolver = Laplacian::create(&globalOptions["aparSolver"], loc); + if (!solver->constraints()) { + throw BoutException("Cannot constrain. Run again with phi_constraint=false.\n"); + } - /////////////// CHECK VACUUM /////////////////////// - // In vacuum region, initial vorticity should equal zero + solver->constraint(phi, C_phi, "phi"); - if (!restarting) { - // Only if not restarting: Check initial perturbation + // Set preconditioner + setPrecon(&ELMpb::precon_phi); - // Set U to zero where P0 < vacuum_pressure - U = where(P0 - vacuum_pressure, U, 0.0); + } else { + // Phi solved in RHS (explicitly) + SAVE_REPEAT(phi); - if (constn0) { - ubyn = U; - // Phi should be consistent with U - phi = phiSolver->solve(ubyn); - } else { - ubyn = U / N0; - phiSolver->setCoefC(N0); - phi = phiSolver->solve(ubyn); - } + // Set preconditioner + setPrecon(&ELMpb::precon); - // if(diamag) { - // phi -= 0.5*dnorm * P / B0; - //} - } + // Set Jacobian + setJacobian((jacobianfunc) & ELMpb::jacobian); + } - /************** SETUP COMMUNICATIONS **************/ + // Diamagnetic phi0 + if (diamag_phi0) { + if (constn0) { + phi0 = -0.5 * dnorm * P0 / B0; + } else { + // Stationary equilibrium plasma. ExB velocity balances diamagnetic drift + phi0 = -0.5 * dnorm * P0 / B0 / N0; + } + SAVE_ONCE(phi0); + } else { + phi0 = 0.0; + } - comms.add(U, P); + // Add some equilibrium quantities and normalisations + // everything needed to recover physical units + SAVE_ONCE(J0, P0); + SAVE_ONCE(density, Lbar, Bbar, Tbar); + SAVE_ONCE(Va, B0); + SAVE_ONCE(Dphi0, U0); + SAVE_ONCE(V0); + if (!constn0) { + SAVE_ONCE(Ti0, Te0, N0); + } - phi.setBoundary("phi"); // Set boundary conditions - tmpU2.setBoundary("U"); - tmpP2.setBoundary("P"); - tmpA2.setBoundary("J"); + // Create a solver for the Laplacian + phiSolver = Laplacian::create(&globalOptions["phiSolver"]); - if (evolve_jpar) { - comms.add(Jpar); - } else { - comms.add(Psi); - // otherwise Need to communicate Jpar separately - Jpar.setBoundary("J"); - } - Jpar2.setBoundary("J"); + aparSolver = Laplacian::create(&globalOptions["aparSolver"], loc); - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES + /////////////// CHECK VACUUM /////////////////////// + // In vacuum region, initial vorticity should equal zero - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_options.I); - } + if (!restarting) { + // Only if not restarting: Check initial perturbation - return 0; - } + // Set U to zero where P0 < vacuum_pressure + U = where(P0 - vacuum_pressure, U, 0.0); - // Parallel gradient along perturbed field-line - Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) const { + if (constn0) { + ubyn = U; + // Phi should be consistent with U + phi = phiSolver->solve(ubyn); + } else { + ubyn = U / N0; + phiSolver->setCoefC(N0); + phi = phiSolver->solve(ubyn); + } - if (loc == CELL_DEFAULT) { - loc = f.getLocation(); - } + // if(diamag) { + // phi -= 0.5*dnorm * P / B0; + //} + } + + /************** SETUP COMMUNICATIONS **************/ - Field3D result = Grad_par(f, loc); + comms.add(U, P); - auto B0 = tokamak_options.Bxy; + phi.setBoundary("phi"); // Set boundary conditions + tmpU2.setBoundary("U"); + tmpP2.setBoundary("P"); + tmpA2.setBoundary("J"); - if (nonlinear) { - result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; + if (evolve_jpar) { + comms.add(Jpar); + } else { + comms.add(Psi); + // otherwise Need to communicate Jpar separately + Jpar.setBoundary("J"); + } + Jpar2.setBoundary("J"); - if (include_rmp) { - result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; - } + return 0; } - return result; - } + // Parallel gradient along perturbed field-line + Field3D Grad_parP(const Field3D &f, CELL_LOC loc = CELL_DEFAULT) const { - bool first_run = true; // For printing out some diagnostics first time around + if (loc == CELL_DEFAULT) { + loc = f.getLocation(); + } - int rhs(BoutReal t) override { - // Perform communications - mesh->communicate(comms); + Field3D result = Grad_par(f, loc); - Coordinates* metric = mesh->getCoordinates(); + auto B0 = tokamak_options.Bxy; - auto B0 = tokamak_options.Bxy; + if (nonlinear) { + result -= bracket(interp_to(Psi, loc), f, bm_mag) * B0; - //////////////////////////////////////////// - // Transitions from 0 in core to 1 in vacuum - if (nonlinear) { - vac_mask = (1.0 - tanh(((P0 + P) - vacuum_pressure) / vacuum_trans)) / 2.0; + if (include_rmp) { + result -= bracket(interp_to(rmp_Psi, loc), f, bm_mag) * B0; + } + } - // Update resistivity - if (spitzer_resist) { - // Use Spitzer formula - Field3D Te; - Te = (P0 + P) * Bbar * Bbar / (4. * MU0) / (density * 1.602e-19); // eV + return result; + } - // eta in Ohm-m. ln(Lambda) = 20 - eta = interp_to(0.51 * 1.03e-4 * Zeff * 20. * pow(Te, -1.5), loc); + bool first_run = true; // For printing out some diagnostics first time around - // Normalised eta - eta /= MU0 * Va * Lbar; - } else { - // Use specified core and vacuum Lundquist numbers - eta = core_resist + (vac_resist - core_resist) * vac_mask; - } - eta = interp_to(eta, loc); - } + int rhs(BoutReal t) override { + // Perform communications + mesh->communicate(comms); - //////////////////////////////////////////// - // Resonant Magnetic Perturbation code + Coordinates *metric = mesh->getCoordinates(); - if (include_rmp) { + auto B0 = tokamak_options.Bxy; - if ((rmp_ramp > 0.0) || (rmp_freq > 0.0) || (rmp_rotate != 0.0)) { - // Need to update the RMP terms + //////////////////////////////////////////// + // Transitions from 0 in core to 1 in vacuum + if (nonlinear) { + vac_mask = (1.0 - tanh(((P0 + P) - vacuum_pressure) / vacuum_trans)) / 2.0; - if ((rmp_ramp > 0.0) && (t < rmp_ramp)) { - // Still in ramp phase + // Update resistivity + if (spitzer_resist) { + // Use Spitzer formula + Field3D Te; + Te = (P0 + P) * Bbar * Bbar / (4. * MU0) / (density * 1.602e-19); // eV - rmp_Psi = (t / rmp_ramp) * rmp_Psi0; // Linear ramp + // eta in Ohm-m. ln(Lambda) = 20 + eta = interp_to(0.51 * 1.03e-4 * Zeff * 20. * pow(Te, -1.5), loc); - rmp_dApdt = rmp_Psi0 / rmp_ramp; - } else { - rmp_Psi = rmp_Psi0; - rmp_dApdt = 0.0; + // Normalised eta + eta /= MU0 * Va * Lbar; + } else { + // Use specified core and vacuum Lundquist numbers + eta = core_resist + (vac_resist - core_resist) * vac_mask; + } + eta = interp_to(eta, loc); } - if (rmp_freq > 0.0) { - // Oscillating the amplitude + //////////////////////////////////////////// + // Resonant Magnetic Perturbation code - rmp_dApdt = rmp_dApdt * sin(2. * PI * rmp_freq * t) - + rmp_Psi * (2. * PI * rmp_freq) * cos(2. * PI * rmp_freq * t); + if (include_rmp) { - rmp_Psi *= sin(2. * PI * rmp_freq * t); - } + if ((rmp_ramp > 0.0) || (rmp_freq > 0.0) || (rmp_rotate != 0.0)) { + // Need to update the RMP terms - if (rmp_rotate != 0.0) { - // Rotate toroidally at given frequency + if ((rmp_ramp > 0.0) && (t < rmp_ramp)) { + // Still in ramp phase - shiftZ(rmp_Psi, 2 * PI * rmp_rotate * t); - shiftZ(rmp_dApdt, 2 * PI * rmp_rotate * t); + rmp_Psi = (t / rmp_ramp) * rmp_Psi0; // Linear ramp - // Add toroidal rotation term. CHECK SIGN + rmp_dApdt = rmp_Psi0 / rmp_ramp; + } else { + rmp_Psi = rmp_Psi0; + rmp_dApdt = 0.0; + } - rmp_dApdt += DDZ(rmp_Psi) * 2 * PI * rmp_rotate; - } + if (rmp_freq > 0.0) { + // Oscillating the amplitude - // Set to zero in the core - if (rmp_vac_mask) { - rmp_Psi *= vac_mask; - } - } else { - // Set to zero in the core region - if (rmp_vac_mask) { - // Only in vacuum -> skin current -> diffuses inwards - rmp_Psi = rmp_Psi0 * vac_mask; - } - } + rmp_dApdt = rmp_dApdt * sin(2. * PI * rmp_freq * t) + + rmp_Psi * (2. * PI * rmp_freq) * cos(2. * PI * rmp_freq * t); - mesh->communicate(rmp_Psi); - } + rmp_Psi *= sin(2. * PI * rmp_freq * t); + } - //////////////////////////////////////////// - // Inversion + if (rmp_rotate != 0.0) { + // Rotate toroidally at given frequency - if (evolve_jpar) { - // Invert laplacian for Psi - Psi = aparSolver->solve(Jpar); - mesh->communicate(Psi); - } + shiftZ(rmp_Psi, 2 * PI * rmp_rotate * t); + shiftZ(rmp_dApdt, 2 * PI * rmp_rotate * t); + + // Add toroidal rotation term. CHECK SIGN - if (phi_constraint) { - // Phi being solved as a constraint + rmp_dApdt += DDZ(rmp_Psi) * 2 * PI * rmp_rotate; + } - Field3D Ctmp = phi; - Ctmp.setBoundary("phi"); // Look up boundary conditions for phi - Ctmp.applyBoundary(); - Ctmp -= phi; // Now contains error in the boundary + // Set to zero in the core + if (rmp_vac_mask) { + rmp_Psi *= vac_mask; + } + } else { + // Set to zero in the core region + if (rmp_vac_mask) { + // Only in vacuum -> skin current -> diffuses inwards + rmp_Psi = rmp_Psi0 * vac_mask; + } + } - C_phi = Delp2(phi) - U; // Error in the bulk - C_phi.setBoundaryTo(Ctmp); + mesh->communicate(rmp_Psi); + } - } else { + //////////////////////////////////////////// + // Inversion - if (constn0) { - if (split_n0) { - //////////////////////////////////////////// - // Boussinesq, split - // Split into axisymmetric and non-axisymmetric components - Field2D Vort2D = DC(U); // n=0 component + if (evolve_jpar) { + // Invert laplacian for Psi + Psi = aparSolver->solve(Jpar); + mesh->communicate(Psi); + } - // Applies boundary condition for "phi". - phi2D.applyBoundary(t); + if (phi_constraint) { + // Phi being solved as a constraint - // Solve axisymmetric (n=0) part - phi2D = laplacexy->solve(Vort2D, phi2D); + Field3D Ctmp = phi; + Ctmp.setBoundary("phi"); // Look up boundary conditions for phi + Ctmp.applyBoundary(); + Ctmp -= phi; // Now contains error in the boundary - // Solve non-axisymmetric part - phi = phiSolver->solve(U - Vort2D); + C_phi = Delp2(phi) - U; // Error in the bulk + C_phi.setBoundaryTo(Ctmp); - phi += phi2D; // Add axisymmetric part } else { - phi = phiSolver->solve(U); - } - if (diamag) { - phi -= 0.5 * dnorm * P / B0; - } - } else { - ubyn = U / N0; - if (diamag) { - ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); - mesh->communicate(ubyn); + if (constn0) { + if (split_n0) { + //////////////////////////////////////////// + // Boussinesq, split + // Split into axisymmetric and non-axisymmetric components + Field2D Vort2D = DC(U); // n=0 component + + // Applies boundary condition for "phi". + phi2D.applyBoundary(t); + + // Solve axisymmetric (n=0) part + phi2D = laplacexy->solve(Vort2D, phi2D); + + // Solve non-axisymmetric part + phi = phiSolver->solve(U - Vort2D); + + phi += phi2D; // Add axisymmetric part + } else { + phi = phiSolver->solve(U); + } + + if (diamag) { + phi -= 0.5 * dnorm * P / B0; + } + } else { + ubyn = U / N0; + if (diamag) { + ubyn -= 0.5 * dnorm / (N0 * B0) * Delp2(P); + mesh->communicate(ubyn); + } + // Invert laplacian for phi + phiSolver->setCoefC(N0); + phi = phiSolver->solve(ubyn); + } + // Apply a boundary condition on phi for target plates + phi.applyBoundary(); + mesh->communicate(phi); } - // Invert laplacian for phi - phiSolver->setCoefC(N0); - phi = phiSolver->solve(ubyn); - } - // Apply a boundary condition on phi for target plates - phi.applyBoundary(); - mesh->communicate(phi); - } - if (!evolve_jpar) { - // Get J from Psi - Jpar = Delp2(Psi); - if (include_rmp) { - Jpar += Delp2(rmp_Psi); - } - - Jpar.applyBoundary(); - mesh->communicate(Jpar); - - if (jpar_bndry_width > 0) { - // Zero j in boundary regions. Prevents vorticity drive - // at the boundary - - for (int i = 0; i < jpar_bndry_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - Jpar(i, j, k) = 0.0; - } - if (mesh->lastX()) { - Jpar(mesh->LocalNx - 1 - i, j, k) = 0.0; - } + if (!evolve_jpar) { + // Get J from Psi + Jpar = Delp2(Psi); + if (include_rmp) { + Jpar += Delp2(rmp_Psi); } - } - } - } - - // Smooth j in x - if (smooth_j_x) { - Jpar = smooth_x(Jpar); - Jpar.applyBoundary(); - - // Recommunicate now smoothed - mesh->communicate(Jpar); - } - - // Get Delp2(J) from J - Jpar2 = Delp2(Jpar); - - Jpar2.applyBoundary(); - mesh->communicate(Jpar2); - - if (jpar_bndry_width > 0) { - // Zero jpar2 in boundary regions. Prevents vorticity drive - // at the boundary - - for (int i = 0; i < jpar_bndry_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - Jpar2(i, j, k) = 0.0; - } - if (mesh->lastX()) { - Jpar2(mesh->LocalNx - 1 - i, j, k) = 0.0; - } + + Jpar.applyBoundary(); + mesh->communicate(Jpar); + + if (jpar_bndry_width > 0) { + // Zero j in boundary regions. Prevents vorticity drive + // at the boundary + + for (int i = 0; i < jpar_bndry_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + Jpar(i, j, k) = 0.0; + } + if (mesh->lastX()) { + Jpar(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + } + } + } } - } - } - } - } - //////////////////////////////////////////////////// - // Sheath boundary conditions - // Normalised and linearised, since here we have only pressure - // rather than density and temperature. Applying a boundary - // to Jpar so that Jpar = sqrt(mi/me)/(2*pi) * phi - // + // Smooth j in x + if (smooth_j_x) { + Jpar = smooth_x(Jpar); + Jpar.applyBoundary(); - if (sheath_boundaries) { + // Recommunicate now smoothed + mesh->communicate(Jpar); + } - // At y = ystart (lower boundary) + // Get Delp2(J) from J + Jpar2 = Delp2(Jpar); + + Jpar2.applyBoundary(); + mesh->communicate(Jpar2); + + if (jpar_bndry_width > 0) { + // Zero jpar2 in boundary regions. Prevents vorticity drive + // at the boundary + + for (int i = 0; i < jpar_bndry_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + Jpar2(i, j, k) = 0.0; + } + if (mesh->lastX()) { + Jpar2(mesh->LocalNx - 1 - i, j, k) = 0.0; + } + } + } + } + } + } - for (RangeIterator r = mesh->iterateBndryLowerY(); !r.isDone(); r++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { + //////////////////////////////////////////////////// + // Sheath boundary conditions + // Normalised and linearised, since here we have only pressure + // rather than density and temperature. Applying a boundary + // to Jpar so that Jpar = sqrt(mi/me)/(2*pi) * phi + // - // Zero-gradient potential - BoutReal phisheath = phi(r.ind, mesh->ystart, jz); + if (sheath_boundaries) { - BoutReal jsheath = -(sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; + // At y = ystart (lower boundary) - // Apply boundary condition half-way between cells - for (int jy = mesh->ystart - 1; jy >= 0; jy--) { - // Neumann conditions - P(r.ind, jy, jz) = P(r.ind, mesh->ystart, jz); - phi(r.ind, jy, jz) = phisheath; - // Dirichlet condition on Jpar - Jpar(r.ind, jy, jz) = 2. * jsheath - Jpar(r.ind, mesh->ystart, jz); - } - } - } + for (RangeIterator r = mesh->iterateBndryLowerY(); !r.isDone(); r++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { - // At y = yend (upper boundary) + // Zero-gradient potential + BoutReal phisheath = phi(r.ind, mesh->ystart, jz); - for (RangeIterator r = mesh->iterateBndryUpperY(); !r.isDone(); r++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { + BoutReal jsheath = -(sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; - // Zero-gradient potential - BoutReal phisheath = phi(r.ind, mesh->yend, jz); + // Apply boundary condition half-way between cells + for (int jy = mesh->ystart - 1; jy >= 0; jy--) { + // Neumann conditions + P(r.ind, jy, jz) = P(r.ind, mesh->ystart, jz); + phi(r.ind, jy, jz) = phisheath; + // Dirichlet condition on Jpar + Jpar(r.ind, jy, jz) = 2. * jsheath - Jpar(r.ind, mesh->ystart, jz); + } + } + } + + // At y = yend (upper boundary) - BoutReal jsheath = (sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; + for (RangeIterator r = mesh->iterateBndryUpperY(); !r.isDone(); r++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { - // Apply boundary condition half-way between cells - for (int jy = mesh->yend + 1; jy < mesh->LocalNy; jy++) { - // Neumann conditions - P(r.ind, jy, jz) = P(r.ind, mesh->yend, jz); - phi(r.ind, jy, jz) = phisheath; - // Dirichlet condition on Jpar - // WARNING: this is not correct if staggered grids are used - ASSERT3(not mesh->StaggerGrids); - Jpar(r.ind, jy, jz) = 2. * jsheath - Jpar(r.ind, mesh->yend, jz); - } + // Zero-gradient potential + BoutReal phisheath = phi(r.ind, mesh->yend, jz); + + BoutReal jsheath = (sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; + + // Apply boundary condition half-way between cells + for (int jy = mesh->yend + 1; jy < mesh->LocalNy; jy++) { + // Neumann conditions + P(r.ind, jy, jz) = P(r.ind, mesh->yend, jz); + phi(r.ind, jy, jz) = phisheath; + // Dirichlet condition on Jpar + // WARNING: this is not correct if staggered grids are used + ASSERT3(not mesh->StaggerGrids); + Jpar(r.ind, jy, jz) = 2. * jsheath - Jpar(r.ind, mesh->yend, jz); + } + } + } } - } - } - //////////////////////////////////////////////////// - // Check that settings match compile-time switches - - CHECK_SETTING(EVOLVE_JPAR, evolve_jpar); - CHECK_SETTING(RELAX_J_VAC, relax_j_vac); - CHECK_SETTING(EHALL, eHall); - CHECK_SETTING(DIAMAG_PHI0, diamag_phi0); - CHECK_SETTING(DIAMAG_GRAD_T, diamag_grad_t); - CHECK_SETTING(HYPERRESIST, hyperresist > 0.0); // Check that it is enabled or disabled - CHECK_SETTING(EHYPERVISCOS, ehyperviscos > 0.0); - CHECK_SETTING(INCLUDE_RMP, include_rmp); - CHECK_SETTING(GRADPARJ, !nogradparj); // Note: Can't negate macro argument - CHECK_SETTING(VISCOS_PERP, viscos_perp > 0.0); - CHECK_SETTING(EVOLVE_PRESSURE, evolve_pressure); - CHECK_SETTING(NONLINEAR, nonlinear); - - //////////////////////////////////////////////////// - // Create accessors for direct access to the data - - // Equilibrium (2D) fields - auto P0_acc = Field2DAccessor<>(P0); - auto J0_acc = Field2DAccessor<>(J0); - auto phi0_acc = Field2DAccessor<>(phi0); - auto B0_acc = Field2DAccessor<>(B0); - - // Evolving fields - auto P_acc = FieldAccessor<>(P); - auto Psi_acc = FieldAccessor<>(Psi); - auto U_acc = FieldAccessor<>(U); - - // Derived fields - auto Jpar_acc = FieldAccessor<>(Jpar); - auto phi_acc = FieldAccessor<>(phi); - auto eta_acc = FieldAccessor<>(eta); + //////////////////////////////////////////////////// + // Check that settings match compile-time switches + + CHECK_SETTING(EVOLVE_JPAR, evolve_jpar); + CHECK_SETTING(RELAX_J_VAC, relax_j_vac); + CHECK_SETTING(EHALL, eHall); + CHECK_SETTING(DIAMAG_PHI0, diamag_phi0); + CHECK_SETTING(DIAMAG_GRAD_T, diamag_grad_t); + CHECK_SETTING(HYPERRESIST, hyperresist > 0.0); // Check that it is enabled or disabled + CHECK_SETTING(EHYPERVISCOS, ehyperviscos > 0.0); + CHECK_SETTING(INCLUDE_RMP, include_rmp); + CHECK_SETTING(GRADPARJ, !nogradparj); // Note: Can't negate macro argument + CHECK_SETTING(VISCOS_PERP, viscos_perp > 0.0); + CHECK_SETTING(EVOLVE_PRESSURE, evolve_pressure); + CHECK_SETTING(NONLINEAR, nonlinear); + + //////////////////////////////////////////////////// + // Create accessors for direct access to the data + + // Equilibrium (2D) fields + auto P0_acc = Field2DAccessor<>(P0); + auto J0_acc = Field2DAccessor<>(J0); + auto phi0_acc = Field2DAccessor<>(phi0); + auto B0_acc = Field2DAccessor<>(B0); + + // Evolving fields + auto P_acc = FieldAccessor<>(P); + auto Psi_acc = FieldAccessor<>(Psi); + auto U_acc = FieldAccessor<>(U); + + // Derived fields + auto Jpar_acc = FieldAccessor<>(Jpar); + auto phi_acc = FieldAccessor<>(phi); + auto eta_acc = FieldAccessor<>(eta); #if EHYPERVISCOS - auto Jpar2_acc = FieldAccessor<>(Jpar2); + auto Jpar2_acc = FieldAccessor<>(Jpar2); #endif #if EVOLVE_JPAR - Field3D B0U = B0 * U; - mesh->communicate(B0U); - auto B0U_acc = FieldAccessor<>(B0U); + Field3D B0U = B0 * U; + mesh->communicate(B0U); + auto B0U_acc = FieldAccessor<>(B0U); #else - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - auto B0phi_acc = FieldAccessor<>(B0phi); + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + auto B0phi_acc = FieldAccessor<>(B0phi); #if EHALL - Field3D B0P = B0 * P; - mesh->communicate(B0 * P); - auto B0P_acc = FieldAccessor<>(B0P); + Field3D B0P = B0 * P; + mesh->communicate(B0 * P); + auto B0P_acc = FieldAccessor<>(B0P); #endif // EHALL #endif // EVOLVE_JPAR #if RELAX_J_VAC - auto vac_mask_acc = FieldAccessor<>(vac_mask); + auto vac_mask_acc = FieldAccessor<>(vac_mask); #endif #if INCLUDE_RMP - auto rmp_Psi_acc = FieldAccessor<>(rmp_Psi); + auto rmp_Psi_acc = FieldAccessor<>(rmp_Psi); #endif - //////////////////////////////////////////////////// - // Start loop over a region of the mesh - // If RAJA is not available, this will fall back to BOUT_FOR - // - // Note: Capture all class member variables into local scope - // or an illegal memory access may occur on GPUs + //////////////////////////////////////////////////// + // Start loop over a region of the mesh + // If RAJA is not available, this will fall back to BOUT_FOR + // + // Note: Capture all class member variables into local scope + // or an illegal memory access may occur on GPUs - BOUT_FOR_RAJA( - i, Jpar.getRegion("RGN_NOBNDRY"), - CAPTURE(delta_i, hyperresist, relax_j_tconst, dnorm, ehyperviscos, viscos_perp)) { - int i2d = static_cast(i) / Jpar_acc.mesh_nz; // An index for 2D objects + BOUT_FOR_RAJA( + i, Jpar.getRegion("RGN_NOBNDRY"), + CAPTURE(delta_i, hyperresist, relax_j_tconst, dnorm, ehyperviscos, viscos_perp)) { + int i2d = static_cast(i) / Jpar_acc.mesh_nz; // An index for 2D objects - //////////////////////////////////////////////////// - // Parallel electric field + //////////////////////////////////////////////////// + // Parallel electric field #if EVOLVE_JPAR - // Evolving parallel current ddt(Jpar) + // Evolving parallel current ddt(Jpar) - ddt(Jpar_acc)[i] = -Grad_par(B0U_acc, i) / B0_acc[i2d] - + eta_acc[i] * Delp2(Jpar_acc, i) + ddt(Jpar_acc)[i] = -Grad_par(B0U_acc, i) / B0_acc[i2d] + + eta_acc[i] * Delp2(Jpar_acc, i) - - EVAL_IF(RELAX_J_VAC, // Relax current to zero - vac_mask_acc[i] * Jpar_acc[i] / relax_j_tconst); + - EVAL_IF(RELAX_J_VAC, // Relax current to zero + vac_mask_acc[i] * Jpar_acc[i] / relax_j_tconst); #else - // Evolve vector potential ddt(psi) - ddt(Psi_acc)[i] = -GRAD_PARP(B0phi_acc) / B0_acc[i2d] + eta_acc[i] * Jpar_acc[i] + // Evolve vector potential ddt(psi) + ddt(Psi_acc)[i] = -GRAD_PARP(B0phi_acc) / B0_acc[i2d] + eta_acc[i] * Jpar_acc[i] - + EVAL_IF(EHALL, // electron parallel pressure - 0.25 * delta_i - * (GRAD_PARP(B0P_acc) / B0_acc[i2d] - + bracket(P0_acc, Psi_acc, i) * B0_acc[i2d])) + + EVAL_IF(EHALL, // electron parallel pressure + 0.25 * delta_i + * (GRAD_PARP(B0P_acc) / B0_acc[i2d] + + bracket(P0_acc, Psi_acc, i) * B0_acc[i2d])) - - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow - bracket(phi0_acc, Psi_acc, i) * B0_acc[i2d]) + - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow + bracket(phi0_acc, Psi_acc, i) * B0_acc[i2d]) - + EVAL_IF(DIAMAG_GRAD_T, // grad_par(T_e) correction - 1.71 * dnorm * 0.5 * GRAD_PARP(P_acc) / B0_acc[i2d]) + + EVAL_IF(DIAMAG_GRAD_T, // grad_par(T_e) correction + 1.71 * dnorm * 0.5 * GRAD_PARP(P_acc) / B0_acc[i2d]) - - EVAL_IF(HYPERRESIST, // Hyper-resistivity - eta_acc[i] * hyperresist * Delp2(Jpar_acc, i)) + - EVAL_IF(HYPERRESIST, // Hyper-resistivity + eta_acc[i] * hyperresist * Delp2(Jpar_acc, i)) - - EVAL_IF(EHYPERVISCOS, // electron Hyper-viscosity - eta_acc[i] * ehyperviscos * Delp2(Jpar2_acc, i)); + - EVAL_IF(EHYPERVISCOS, // electron Hyper-viscosity + eta_acc[i] * ehyperviscos * Delp2(Jpar2_acc, i)); #endif - //////////////////////////////////////////////////// - // Vorticity equation + //////////////////////////////////////////////////// + // Vorticity equation - ddt(U_acc)[i] = - SQ(B0_acc[i2d]) * b0xGrad_dot_Grad(Psi_acc, J0_acc, i) + ddt(U_acc)[i] = + SQ(B0_acc[i2d]) * b0xGrad_dot_Grad(Psi_acc, J0_acc, i) - + EVAL_IF(INCLUDE_RMP, // External magnetic field perturbation - SQ(B0_acc[i2d]) * b0xGrad_dot_Grad(rmp_Psi_acc, J0_acc, i)) + + EVAL_IF(INCLUDE_RMP, // External magnetic field perturbation + SQ(B0_acc[i2d]) * b0xGrad_dot_Grad(rmp_Psi_acc, J0_acc, i)) - - EVAL_IF(GRADPARJ, // Parallel current term - SQ(B0_acc[i2d]) * GRAD_PARP(Jpar_acc)) + - EVAL_IF(GRADPARJ, // Parallel current term + SQ(B0_acc[i2d]) * GRAD_PARP(Jpar_acc)) - - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow - b0xGrad_dot_Grad(phi0_acc, U_acc, i)) + - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow + b0xGrad_dot_Grad(phi0_acc, U_acc, i)) - - EVAL_IF(NONLINEAR, // Advection - bracket(phi_acc, U_acc, i) * B0_acc[i2d]) + - EVAL_IF(NONLINEAR, // Advection + bracket(phi_acc, U_acc, i) * B0_acc[i2d]) - + EVAL_IF(VISCOS_PERP, // Perpendicular viscosity - viscos_perp * Delp2(U_acc, i)); + + EVAL_IF(VISCOS_PERP, // Perpendicular viscosity + viscos_perp * Delp2(U_acc, i)); - //////////////////////////////////////////////////// - // Pressure equation + //////////////////////////////////////////////////// + // Pressure equation #if EVOLVE_PRESSURE - ddt(P_acc)[i] = -b0xGrad_dot_Grad(phi_acc, P0_acc, i) + ddt(P_acc)[i] = -b0xGrad_dot_Grad(phi_acc, P0_acc, i) - - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow - b0xGrad_dot_Grad(phi0_acc, P_acc, i)) + - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow + b0xGrad_dot_Grad(phi0_acc, P_acc, i)) - - EVAL_IF(NONLINEAR, // Advection - bracket(phi_acc, P_acc, i) * B0_acc[i2d]); + - EVAL_IF(NONLINEAR, // Advection + bracket(phi_acc, P_acc, i) * B0_acc[i2d]); #else - ddt(P_acc)[i] = 0.0; + ddt(P_acc)[i] = 0.0; #endif - }; + }; - // Terms which are not yet single index operators - // Note: Terms which are included in the single index loop - // may be commented out here, to allow comparison/testing + // Terms which are not yet single index operators + // Note: Terms which are included in the single index loop + // may be commented out here, to allow comparison/testing - //////////////////////////////////////////////////// - // Parallel electric field + //////////////////////////////////////////////////// + // Parallel electric field #if not EVOLVE_JPAR - // Vector potential - // ddt(Psi) = -Grad_parP(phi, loc) + eta * Jpar; + // Vector potential + // ddt(Psi) = -Grad_parP(phi, loc) + eta * Jpar; - // if (eHall) { // electron parallel pressure - // ddt(Psi) += 0.25 * delta_i - // * (Grad_parP(P, loc) - // + bracket(interp_to(P0, loc), Psi, bm_mag)); - // } + // if (eHall) { // electron parallel pressure + // ddt(Psi) += 0.25 * delta_i + // * (Grad_parP(P, loc) + // + bracket(interp_to(P0, loc), Psi, bm_mag)); + // } - // if (diamag_phi0) { // Equilibrium flow - // ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb); - // } + // if (diamag_phi0) { // Equilibrium flow + // ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb); + // } - if (withflow) { // net flow - ddt(Psi) -= V_dot_Grad(V0net, Psi); - } + if (withflow) { // net flow + ddt(Psi) -= V_dot_Grad(V0net, Psi); + } - // if (diamag_grad_t) { // grad_par(T_e) correction - // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; - // } + // if (diamag_grad_t) { // grad_par(T_e) correction + // ddt(Psi) += 1.71 * dnorm * 0.5 * Grad_parP(P, loc) / B0; + // } - // if (hyperresist > 0.0) { // Hyper-resistivity - // ddt(Psi) -= eta * hyperresist * Delp2(Jpar); - // } + // if (hyperresist > 0.0) { // Hyper-resistivity + // ddt(Psi) -= eta * hyperresist * Delp2(Jpar); + // } - // if (ehyperviscos > 0.0) { // electron Hyper-viscosity coefficient - // ddt(Psi) -= eta * ehyperviscos * Delp2(Jpar2); - // } + // if (ehyperviscos > 0.0) { // electron Hyper-viscosity coefficient + // ddt(Psi) -= eta * ehyperviscos * Delp2(Jpar2); + // } - // Parallel hyper-viscous diffusion for vector potential - if (diffusion_a4 > 0.0) { - tmpA2 = D2DY2(Psi); - mesh->communicate(tmpA2); - tmpA2.applyBoundary(); - ddt(Psi) -= diffusion_a4 * D2DY2(tmpA2); - } + // Parallel hyper-viscous diffusion for vector potential + if (diffusion_a4 > 0.0) { + tmpA2 = D2DY2(Psi); + mesh->communicate(tmpA2); + tmpA2.applyBoundary(); + ddt(Psi) -= diffusion_a4 * D2DY2(tmpA2); + } - // Vacuum solution - if (relax_j_vac) { - // Calculate the J and Psi profile we're aiming for - Field3D Jtarget = Jpar * (1.0 - vac_mask); // Zero in vacuum + // Vacuum solution + if (relax_j_vac) { + // Calculate the J and Psi profile we're aiming for + Field3D Jtarget = Jpar * (1.0 - vac_mask); // Zero in vacuum - // Invert laplacian for Psi - Field3D Psitarget = aparSolver->solve(Jtarget); + // Invert laplacian for Psi + Field3D Psitarget = aparSolver->solve(Jtarget); - // Add a relaxation term in the vacuum - ddt(Psi) = - ddt(Psi) * (1. - vac_mask) - (Psi - Psitarget) * vac_mask / relax_j_tconst; - } + // Add a relaxation term in the vacuum + ddt(Psi) = + ddt(Psi) * (1. - vac_mask) - (Psi - Psitarget) * vac_mask / relax_j_tconst; + } #endif - //////////////////////////////////////////////////// - // Vorticity equation + //////////////////////////////////////////////////// + // Vorticity equation - // Grad j term - // ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); + // Grad j term + // ddt(U) = SQ(B0) * b0xGrad_dot_Grad(Psi, J0, CELL_CENTRE); - // if (include_rmp) { - // ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); - // } + // if (include_rmp) { + // ddt(U) += SQ(B0) * b0xGrad_dot_Grad(rmp_Psi, J0, CELL_CENTRE); + // } - ddt(U) += b0xcv * Grad(P); // curvature term + ddt(U) += b0xcv * Grad(P); // curvature term - // if (!nogradparj) { // Parallel current term - // ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j - // } + // if (!nogradparj) { // Parallel current term + // ddt(U) -= SQ(B0) * Grad_parP(Jpar, CELL_CENTRE); // b dot grad j + // } - if (withflow && K_H_term) { // K_H_term - ddt(U) -= b0xGrad_dot_Grad(phi, U0); - } - - // if (diamag_phi0) { // Equilibrium flow - // ddt(U) -= b0xGrad_dot_Grad(phi0, U); - // } + if (withflow && K_H_term) { // K_H_term + ddt(U) -= b0xGrad_dot_Grad(phi, U0); + } - if (withflow) { // net flow - ddt(U) -= V_dot_Grad(V0net, U); - } + // if (diamag_phi0) { // Equilibrium flow + // ddt(U) -= b0xGrad_dot_Grad(phi0, U); + // } - // if (nonlinear) { // Advection - // ddt(U) -= bracket(phi, U, bm_exb) * B0; - // } + if (withflow) { // net flow + ddt(U) -= V_dot_Grad(V0net, U); + } - // Viscosity terms + // if (nonlinear) { // Advection + // ddt(U) -= bracket(phi, U, bm_exb) * B0; + // } - if (viscos_par > 0.0) { // Parallel viscosity - ddt(U) += viscos_par * Grad2_par2(U); - } + // Viscosity terms - if (diffusion_u4 > 0.0) { - tmpU2 = D2DY2(U); - mesh->communicate(tmpU2); - tmpU2.applyBoundary(); - ddt(U) -= diffusion_u4 * D2DY2(tmpU2); - } + if (viscos_par > 0.0) { // Parallel viscosity + ddt(U) += viscos_par * Grad2_par2(U); + } - // if (viscos_perp > 0.0) { // Perpendicular viscosity - // ddt(U) += viscos_perp * Delp2(U); - // } + if (diffusion_u4 > 0.0) { + tmpU2 = D2DY2(U); + mesh->communicate(tmpU2); + tmpU2.applyBoundary(); + ddt(U) -= diffusion_u4 * D2DY2(tmpU2); + } - // Hyper-viscosity - if (hyperviscos > 0.0) { - // Calculate coefficient. + // if (viscos_perp > 0.0) { // Perpendicular viscosity + // ddt(U) += viscos_perp * Delp2(U); + // } - hyper_mu_x = hyperviscos * metric->g_11() * SQ(metric->dx()) - * abs(metric->g11() * D2DX2(U)) / (abs(U) + 1e-3); - hyper_mu_x.applyBoundary("dirichlet"); // Set to zero on all boundaries + // Hyper-viscosity + if (hyperviscos > 0.0) { + // Calculate coefficient. - ddt(U) += hyper_mu_x * metric->g11() * D2DX2(U); + hyper_mu_x = hyperviscos * metric->g_11() * SQ(metric->dx()) + * abs(metric->g11() * D2DX2(U)) / (abs(U) + 1e-3); + hyper_mu_x.applyBoundary("dirichlet"); // Set to zero on all boundaries - if (first_run) { // Print out maximum values of viscosity used on this processor - output.write(" Hyper-viscosity values:\n"); - output.write(" Max mu_x = {:e}, Max_DC mu_x = {:e}\n", max(hyper_mu_x), - max(DC(hyper_mu_x))); - } - } + ddt(U) += hyper_mu_x * metric->g11() * D2DX2(U); - if (gyroviscous) { - - Field3D Pi; - Field2D Pi0; - Pi = 0.5 * P; - Pi0 = 0.5 * P0; - - Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); - Dperp2Phi0.applyBoundary(); - mesh->communicate(Dperp2Phi0); - - Dperp2Phi = Delp2(B0 * phi); - Dperp2Phi.applyBoundary(); - mesh->communicate(Dperp2Phi); - - Dperp2Pi0 = Field3D(Delp2(Pi0)); - Dperp2Pi0.applyBoundary(); - mesh->communicate(Dperp2Pi0); - - Dperp2Pi = Delp2(Pi); - Dperp2Pi.applyBoundary(); - mesh->communicate(Dperp2Pi); - - bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); - bracketPhi0P.applyBoundary(); - mesh->communicate(bracketPhi0P); - - bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); - bracketPhiP0.applyBoundary(); - mesh->communicate(bracketPhiP0); - - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - Field3D B0phi0 = B0 * phi0; - mesh->communicate(B0phi0); - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; - - if (nonlinear) { - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - bracketPhiP = bracket(B0phi, Pi, bm_exb); - bracketPhiP.applyBoundary(); - mesh->communicate(bracketPhiP); - - ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; - ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; - ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; - } - } + if (first_run) { // Print out maximum values of viscosity used on this processor + output.write(" Hyper-viscosity values:\n"); + output.write(" Max mu_x = {:e}, Max_DC mu_x = {:e}\n", max(hyper_mu_x), + max(DC(hyper_mu_x))); + } + } - // left edge sink terms - if (sink_Ul > 0.0) { - ddt(U) -= sink_Ul * sink_tanhxl(P0, U, su_widthl, su_lengthl); // core sink - } + if (gyroviscous) { + + Field3D Pi; + Field2D Pi0; + Pi = 0.5 * P; + Pi0 = 0.5 * P0; + + Dperp2Phi0 = Field3D(Delp2(B0 * phi0)); + Dperp2Phi0.applyBoundary(); + mesh->communicate(Dperp2Phi0); + + Dperp2Phi = Delp2(B0 * phi); + Dperp2Phi.applyBoundary(); + mesh->communicate(Dperp2Phi); + + Dperp2Pi0 = Field3D(Delp2(Pi0)); + Dperp2Pi0.applyBoundary(); + mesh->communicate(Dperp2Pi0); + + Dperp2Pi = Delp2(Pi); + Dperp2Pi.applyBoundary(); + mesh->communicate(Dperp2Pi); + + bracketPhi0P = bracket(B0 * phi0, Pi, bm_exb); + bracketPhi0P.applyBoundary(); + mesh->communicate(bracketPhi0P); + + bracketPhiP0 = bracket(B0 * phi, Pi0, bm_exb); + bracketPhiP0.applyBoundary(); + mesh->communicate(bracketPhiP0); + + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi0, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * bracket(Pi0, Dperp2Phi, bm_exb) / B0; + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + Field3D B0phi0 = B0 * phi0; + mesh->communicate(B0phi0); + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi0, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi0, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhi0P) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP0) / B0; + + if (nonlinear) { + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + bracketPhiP = bracket(B0phi, Pi, bm_exb); + bracketPhiP.applyBoundary(); + mesh->communicate(bracketPhiP); + + ddt(U) -= 0.5 * Upara2 * bracket(Pi, Dperp2Phi, bm_exb) / B0; + ddt(U) += 0.5 * Upara2 * bracket(B0phi, Dperp2Pi, bm_exb) / B0; + ddt(U) -= 0.5 * Upara2 * Delp2(bracketPhiP) / B0; + } + } - // right edge sink terms - if (sink_Ur > 0.0) { - ddt(U) -= sink_Ur * sink_tanhxr(P0, U, su_widthr, su_lengthr); // sol sink - } + // left edge sink terms + if (sink_Ul > 0.0) { + ddt(U) -= sink_Ul * sink_tanhxl(P0, U, su_widthl, su_lengthl); // core sink + } - //////////////////////////////////////////////////// - // Pressure equation + // right edge sink terms + if (sink_Ur > 0.0) { + ddt(U) -= sink_Ur * sink_tanhxr(P0, U, su_widthr, su_lengthr); // sol sink + } - if (evolve_pressure) { + //////////////////////////////////////////////////// + // Pressure equation - // ddt(P) -= b0xGrad_dot_Grad(phi, P0); + if (evolve_pressure) { - // if (diamag_phi0) { // Equilibrium flow - // ddt(P) -= b0xGrad_dot_Grad(phi0, P); - // } + // ddt(P) -= b0xGrad_dot_Grad(phi, P0); - if (withflow) { // net flow - ddt(P) -= V_dot_Grad(V0net, P); - } + // if (diamag_phi0) { // Equilibrium flow + // ddt(P) -= b0xGrad_dot_Grad(phi0, P); + // } - // if (nonlinear) { // Advection - // ddt(P) -= bracket(phi, P, bm_exb) * B0; - // } + if (withflow) { // net flow + ddt(P) -= V_dot_Grad(V0net, P); + } - // Parallel diffusion terms + // if (nonlinear) { // Advection + // ddt(P) -= bracket(phi, P, bm_exb) * B0; + // } - if (diffusion_par > 0.0) { // Parallel diffusion - ddt(P) += diffusion_par * Grad2_par2(P); - } + // Parallel diffusion terms - if (diffusion_p4 > 0.0) { - tmpP2 = D2DY2(P); - mesh->communicate(tmpP2); - tmpP2.applyBoundary(); - ddt(P) = diffusion_p4 * D2DY2(tmpP2); - } + if (diffusion_par > 0.0) { // Parallel diffusion + ddt(P) += diffusion_par * Grad2_par2(P); + } - // heating source terms - if (heating_P > 0.0) { - BoutReal pnorm = P0(0, 0); - ddt(P) += heating_P * source_expx2(P0, 2. * hp_width, 0.5 * hp_length) - * (Tbar / pnorm); // heat source - ddt(P) += (100. * source_tanhx(P0, hp_width, hp_length) + 0.01) * metric->g11() - * D2DX2(P) * (Tbar / Lbar / Lbar); // radial diffusion - } + if (diffusion_p4 > 0.0) { + tmpP2 = D2DY2(P); + mesh->communicate(tmpP2); + tmpP2.applyBoundary(); + ddt(P) = diffusion_p4 * D2DY2(tmpP2); + } - // sink terms - if (sink_P > 0.0) { - ddt(P) -= sink_P * sink_tanhxr(P0, P, sp_width, sp_length) * Tbar; // sink - } - } + // heating source terms + if (heating_P > 0.0) { + BoutReal pnorm = P0(0, 0); + ddt(P) += heating_P * source_expx2(P0, 2. * hp_width, 0.5 * hp_length) + * (Tbar / pnorm); // heat source + ddt(P) += (100. * source_tanhx(P0, hp_width, hp_length) + 0.01) * metric->g11() + * D2DX2(P) * (Tbar / Lbar / Lbar); // radial diffusion + } - //////////////////////////////////////////////////// - // Compressional effects + // sink terms + if (sink_P > 0.0) { + ddt(P) -= sink_P * sink_tanhxr(P0, P, sp_width, sp_length) * Tbar; // sink + } + } - if (compress) { + //////////////////////////////////////////////////// + // Compressional effects - ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); + if (compress) { - if (phi_curv) { - ddt(P) -= 2. * beta * b0xcv * Grad(phi); - } + ddt(P) -= beta * Div_par(Vpar, CELL_CENTRE); - // Vpar equation + if (phi_curv) { + ddt(P) -= 2. * beta * b0xcv * Grad(phi); + } - ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); + // Vpar equation - if (nonlinear) { - ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection - } - } + ddt(Vpar) = -0.5 * (Grad_par(P, loc) + Grad_par(P0, loc)); - if (filter_z) { - // Filter out all except filter_z_mode + if (nonlinear) { + ddt(Vpar) -= bracket(interp_to(phi, loc), Vpar, bm_exb) * B0; // Advection + } + } - if (evolve_jpar) { - ddt(Jpar) = filter(ddt(Jpar), filter_z_mode); - } else { - ddt(Psi) = filter(ddt(Psi), filter_z_mode); - } - ddt(U) = filter(ddt(U), filter_z_mode); - ddt(P) = filter(ddt(P), filter_z_mode); - } + if (filter_z) { + // Filter out all except filter_z_mode - if (low_pass_z > 0) { - // Low-pass filter, keeping n up to low_pass_z - if (evolve_jpar) { - ddt(Jpar) = lowPass(ddt(Jpar), low_pass_z, zonal_field); - } else { - ddt(Psi) = lowPass(ddt(Psi), low_pass_z, zonal_field); - } - ddt(U) = lowPass(ddt(U), low_pass_z, zonal_flow); - ddt(P) = lowPass(ddt(P), low_pass_z, zonal_bkgd); - } + if (evolve_jpar) { + ddt(Jpar) = filter(ddt(Jpar), filter_z_mode); + } else { + ddt(Psi) = filter(ddt(Psi), filter_z_mode); + } + ddt(U) = filter(ddt(U), filter_z_mode); + ddt(P) = filter(ddt(P), filter_z_mode); + } - if (damp_width > 0) { - for (int i = 0; i < damp_width; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - if (mesh->firstX()) { - ddt(U)(i, j, k) -= U(i, j, k) / damp_t_const; + if (low_pass_z > 0) { + // Low-pass filter, keeping n up to low_pass_z + if (evolve_jpar) { + ddt(Jpar) = lowPass(ddt(Jpar), low_pass_z, zonal_field); + } else { + ddt(Psi) = lowPass(ddt(Psi), low_pass_z, zonal_field); } - if (mesh->lastX()) { - ddt(U)(mesh->LocalNx - 1 - i, j, k) -= - U(mesh->LocalNx - 1 - i, j, k) / damp_t_const; + ddt(U) = lowPass(ddt(U), low_pass_z, zonal_flow); + ddt(P) = lowPass(ddt(P), low_pass_z, zonal_bkgd); + } + + if (damp_width > 0) { + for (int i = 0; i < damp_width; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + if (mesh->firstX()) { + ddt(U)(i, j, k) -= U(i, j, k) / damp_t_const; + } + if (mesh->lastX()) { + ddt(U)(mesh->LocalNx - 1 - i, j, k) -= + U(mesh->LocalNx - 1 - i, j, k) / damp_t_const; + } + } + } } - } } - } + + first_run = false; + + return 0; } - first_run = false; + /******************************************************************************* + * Preconditioner + * + * o System state in variables (as in rhs function) + * o Values to be inverted in time derivatives + * + * o Return values should be in time derivatives + * + * enable by setting solver / use_precon = true in BOUT.inp + *******************************************************************************/ - return 0; - } + int precon(BoutReal UNUSED(t), BoutReal gamma, BoutReal UNUSED(delta)) { + // First matrix, applying L + mesh->communicate(ddt(Psi)); + Field3D Jrhs = Delp2(ddt(Psi)); + Jrhs.applyBoundary("neumann"); - /******************************************************************************* - * Preconditioner - * - * o System state in variables (as in rhs function) - * o Values to be inverted in time derivatives - * - * o Return values should be in time derivatives - * - * enable by setting solver / use_precon = true in BOUT.inp - *******************************************************************************/ - - int precon(BoutReal UNUSED(t), BoutReal gamma, BoutReal UNUSED(delta)) { - // First matrix, applying L - mesh->communicate(ddt(Psi)); - Field3D Jrhs = Delp2(ddt(Psi)); - Jrhs.applyBoundary("neumann"); - - if (jpar_bndry_width > 0) { - // Boundary in jpar - if (mesh->firstX()) { - for (int i = jpar_bndry_width; i >= 0; i--) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - Jrhs(i, j, k) = 0.5 * Jrhs(i + 1, j, k); + if (jpar_bndry_width > 0) { + // Boundary in jpar + if (mesh->firstX()) { + for (int i = jpar_bndry_width; i >= 0; i--) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + Jrhs(i, j, k) = 0.5 * Jrhs(i + 1, j, k); + } + } + } } - } - } - } - if (mesh->lastX()) { - for (int i = mesh->LocalNx - jpar_bndry_width - 1; i < mesh->LocalNx; i++) { - for (int j = 0; j < mesh->LocalNy; j++) { - for (int k = 0; k < mesh->LocalNz; k++) { - Jrhs(i, j, k) = 0.5 * Jrhs(i - 1, j, k); + if (mesh->lastX()) { + for (int i = mesh->LocalNx - jpar_bndry_width - 1; i < mesh->LocalNx; i++) { + for (int j = 0; j < mesh->LocalNy; j++) { + for (int k = 0; k < mesh->LocalNz; k++) { + Jrhs(i, j, k) = 0.5 * Jrhs(i - 1, j, k); + } + } + } } - } } - } - } - mesh->communicate(Jrhs, ddt(P)); + mesh->communicate(Jrhs, ddt(P)); + + Field3D U1 = ddt(U); - Field3D U1 = ddt(U); + auto B0 = tokamak_options.Bxy; - auto B0 = tokamak_options.Bxy; + U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + + // Second matrix, solving Alfven wave dynamics + static std::unique_ptr invU{nullptr}; + if (!invU) { + invU = InvertPar::create(); + } - U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(P); + invU->setCoefA(1.); + invU->setCoefB(-SQ(gamma) * B0 * B0); + ddt(U) = invU->solve(U1); + ddt(U).applyBoundary(); - // Second matrix, solving Alfven wave dynamics - static std::unique_ptr invU{nullptr}; - if (!invU) { - invU = InvertPar::create(); + // Third matrix, applying U + Field3D phi3 = phiSolver->solve(ddt(U)); + mesh->communicate(phi3); + phi3.applyBoundary("neumann"); + Field3D B0phi3 = B0 * phi3; + mesh->communicate(B0phi3); + ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; + ddt(Psi).applyBoundary(); + + return 0; } - invU->setCoefA(1.); - invU->setCoefB(-SQ(gamma) * B0 * B0); - ddt(U) = invU->solve(U1); - ddt(U).applyBoundary(); - - // Third matrix, applying U - Field3D phi3 = phiSolver->solve(ddt(U)); - mesh->communicate(phi3); - phi3.applyBoundary("neumann"); - Field3D B0phi3 = B0 * phi3; - mesh->communicate(B0phi3); - ddt(Psi) = ddt(Psi) - gamma * Grad_par(B0phi3, loc) / B0; - ddt(Psi).applyBoundary(); - - return 0; - } + /******************************************************************************* + * Jacobian-vector multiply + * + * Input + * System state is in (P, Psi, U) + * Vector v is in (F_P, F_Psi, F_U) + * Output + * Jacobian-vector multiplied Jv should be in (P, Psi, U) + * + * NOTE: EXPERIMENTAL + * enable by setting solver / use_jacobian = true in BOUT.inp + *******************************************************************************/ - /******************************************************************************* - * Jacobian-vector multiply - * - * Input - * System state is in (P, Psi, U) - * Vector v is in (F_P, F_Psi, F_U) - * Output - * Jacobian-vector multiplied Jv should be in (P, Psi, U) - * - * NOTE: EXPERIMENTAL - * enable by setting solver / use_jacobian = true in BOUT.inp - *******************************************************************************/ + int jacobian(BoutReal UNUSED(t)) { + // Communicate + mesh->communicate(ddt(P), ddt(Psi), ddt(U)); - int jacobian(BoutReal UNUSED(t)) { - // Communicate - mesh->communicate(ddt(P), ddt(Psi), ddt(U)); + phi = phiSolver->solve(ddt(U)); - phi = phiSolver->solve(ddt(U)); + Jpar = Delp2(ddt(Psi)); - Jpar = Delp2(ddt(Psi)); + mesh->communicate(phi, Jpar); - mesh->communicate(phi, Jpar); + Field3D JP = -b0xGrad_dot_Grad(phi, P0); + JP.setBoundary("P"); + JP.applyBoundary(); - Field3D JP = -b0xGrad_dot_Grad(phi, P0); - JP.setBoundary("P"); - JP.applyBoundary(); + auto B0 = tokamak_options.Bxy; - auto B0 = tokamak_options.Bxy; + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + Field3D JPsi = -Grad_par(B0phi, loc) / B0; + JPsi.setBoundary("Psi"); + JPsi.applyBoundary(); - Field3D B0phi = B0 * phi; - mesh->communicate(B0phi); - Field3D JPsi = -Grad_par(B0phi, loc) / B0; - JPsi.setBoundary("Psi"); - JPsi.applyBoundary(); + Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) + + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); + JU.setBoundary("U"); + JU.applyBoundary(); - Field3D JU = b0xcv * Grad(ddt(P)) - SQ(B0) * Grad_par(Jpar, CELL_CENTRE) - + SQ(B0) * b0xGrad_dot_Grad(ddt(Psi), J0, CELL_CENTRE); - JU.setBoundary("U"); - JU.applyBoundary(); + // Put result into time-derivatives - // Put result into time-derivatives + ddt(P) = JP; + ddt(Psi) = JPsi; + ddt(U) = JU; - ddt(P) = JP; - ddt(Psi) = JPsi; - ddt(U) = JU; + return 0; + } - return 0; - } + /******************************************************************************* + * Preconditioner for when phi solved as a constraint + * Currently only possible with the IDA solver + * + * o System state in variables (as in rhs function) + * o Values to be inverted in F_vars + * + * o Return values should be in vars (overwriting system state) + *******************************************************************************/ - /******************************************************************************* - * Preconditioner for when phi solved as a constraint - * Currently only possible with the IDA solver - * - * o System state in variables (as in rhs function) - * o Values to be inverted in F_vars - * - * o Return values should be in vars (overwriting system state) - *******************************************************************************/ - - int precon_phi(BoutReal UNUSED(t), BoutReal UNUSED(cj), BoutReal UNUSED(delta)) { - ddt(phi) = phiSolver->solve(C_phi - ddt(U)); - return 0; - } + int precon_phi(BoutReal UNUSED(t), BoutReal UNUSED(cj), BoutReal UNUSED(delta)) { + ddt(phi) = phiSolver->solve(C_phi - ddt(U)); + return 0; + } }; BOUTMAIN(ELMpb); diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index c5926fb916..7b02a13823 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -300,7 +300,7 @@ class ELMpb : public PhysicsModel { bool noshear; - Coordinates* metric = mesh->getCoordinates(); + Coordinates *metric = mesh->getCoordinates(); output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); @@ -336,8 +336,8 @@ class ELMpb : public PhysicsModel { Psi_loc.setBoundary("Psi_loc"); ////////////////////////////////////////////////////////////// - auto& globalOptions = Options::root(); - auto& options = globalOptions["highbeta"]; + auto &globalOptions = Options::root(); + auto &options = globalOptions["highbeta"]; constn0 = options["constn0"].withDefault(true); // use the hyperbolic profile of n0. If both n0_fake_prof and @@ -466,6 +466,8 @@ class ELMpb : public PhysicsModel { experiment_Er = options["experiment_Er"].withDefault(false); + noshear = options["noshear"].withDefault(false); + relax_j_vac = options["relax_j_vac"] .doc("Relax vacuum current to zero") .withDefault(false); @@ -746,22 +748,24 @@ class ELMpb : public PhysicsModel { J0 = 0.0; } - if (noshear) { - if (include_curvature) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; - } - } - ////////////////////////////////////////////////////////////// // SHIFTED RADIAL COORDINATES - if (not mesh->IncIntShear) { + BoutReal shearFactor = 1.0; + if (!noshear && mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + metric->setIntShiftTorsion(tokamak_options.I); + + } else { // Dimits style, using local coordinate system if (include_curvature) { b0xcv.z += tokamak_options.I * b0xcv.x; } + shearFactor = 0.0; // I disappears from metric } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lbar, Bbar, shearFactor); + ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -884,16 +888,6 @@ class ELMpb : public PhysicsModel { b0xcv.y *= Lbar * Lbar; b0xcv.z *= Lbar * Lbar; - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); - - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - metric->setIntShiftTorsion(tokamak_options.I); - } - if (constn0) { T0_fake_prof = false; n0_fake_prof = false; @@ -1159,7 +1153,7 @@ class ELMpb : public PhysicsModel { } // Parallel gradient along perturbed field-line - Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) const { + Field3D Grad_parP(const Field3D &f, CELL_LOC loc = CELL_DEFAULT) const { if (loc == CELL_DEFAULT) { loc = f.getLocation(); diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index 61e395520a..d8245a683b 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -252,7 +252,7 @@ class GEM : public PhysicsModel { Bbar = options["Bbar"].withDefault(Bbar); // Override in options file SAVE_ONCE(Bbar); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lbar, Bbar); beta_e = 4.e-7 * PI * max(p_e, true) / (Bbar * Bbar); SAVE_ONCE(beta_e); diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index b71699ae14..fd286fc550 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -172,7 +172,7 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm); Coordinates* coord = mesh->getCoordinates(); // Metric tensor } }; diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 3079d7ca9a..723097f2f3 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -15,7 +15,7 @@ int main(int argc, char** argv) { calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, 1.0, 1.0); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, 1.0, 1.0); } Coordinates* coord = mesh->getCoordinates(); diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index b7277e0b6c..02c17d0378 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -18,7 +18,15 @@ class WaveTest : public PhysicsModel { int init(bool UNUSED(restarting)) { auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, 1.0, 1.0); + + int ShiftXderivs = 0; + mesh->get(ShiftXderivs, "false"); + BoutReal shearFactor = 1.0; + if (ShiftXderivs) { + // No integrated shear in metric + shearFactor = 0.0; + } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, 1.0, 1.0, shearFactor); auto* coords = mesh->getCoordinates(); diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index ba96a237cb..00c19606bc 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -46,17 +46,13 @@ BoutReal get_sign_of_bp(Field2D Bpxy) { return 1.0; } -void set_tokamak_coordinates_on_mesh(TokamakOptions& tokamak_options, Mesh& mesh, const bool noshear, BoutReal Lbar, - BoutReal Bbar, BoutReal ShearFactor = 1.0) { +void set_tokamak_coordinates_on_mesh(TokamakOptions& tokamak_options, Mesh& mesh, BoutReal Lbar, + BoutReal Bbar, BoutReal ShearFactor = 0.0) { tokamak_options.normalise(Lbar, Bbar, ShearFactor); const BoutReal sign_of_bp = get_sign_of_bp(tokamak_options.Bpxy); - if (noshear) { - ShearFactor = 0.0; - } - auto *coord = mesh.getCoordinates(); const auto g11 = SQ(tokamak_options.Rxy * tokamak_options.Bpxy); diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index e5ebf2fa92..af29357f83 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -20,482 +20,489 @@ #include int GBS::init(bool restarting) { - Options* opt = Options::getRoot(); - coords = mesh->getCoordinates(); - - // Switches in model section - Options* optgbs = opt->getSection("GBS"); - OPTION(optgbs, ionvis, false); - if (ionvis) { - OPTION(optgbs, Ti, 10); // Ion temperature [eV] - } - OPTION(optgbs, elecvis, false); // Include electron viscosity? - OPTION(optgbs, resistivity, true); // Include resistivity? - OPTION(optgbs, estatic, true); // Electrostatic? - - // option for ExB Poisson Bracket - int bm_exb_flag; - OPTION(optgbs, bm_exb_flag, 2); // Arakawa default - switch (bm_exb_flag) { - case 0: { - bm_exb = BRACKET_STD; - output << "\tBrackets for ExB: default differencing\n"; - break; - } - case 1: { - bm_exb = BRACKET_SIMPLE; - output << "\tBrackets for ExB: simplified operator\n"; - break; - } - case 2: { - bm_exb = BRACKET_ARAKAWA; - output << "\tBrackets for ExB: Arakawa scheme\n"; - break; - } - case 3: { - bm_exb = BRACKET_CTU; - output << "\tBrackets for ExB: Corner Transport Upwind method\n"; - break; - } - default: - output << "ERROR: Invalid choice of bracket method. Must be 0 - 3\n"; - return 1; - } - - OPTION(opt->getSection("solver"), mms, false); - - if (ionvis) { - SAVE_REPEAT(Gi); - } - if (elecvis) { - SAVE_REPEAT(Ge); - } - if (resistivity) { - SAVE_REPEAT(nu); - } - - // Normalisation - OPTION(optgbs, Tnorm, 100); // Reference temperature [eV] - OPTION(optgbs, Nnorm, 1e19); // Reference density [m^-3] - OPTION(optgbs, Bnorm, 1.0); // Reference magnetic field [T] - OPTION(optgbs, AA, 2.0); // Ion mass - - output.write("Normalisation Te={:e}, Ne={:e}, B={:e}\n", Tnorm, Nnorm, Bnorm); - SAVE_ONCE4(Tnorm, Nnorm, Bnorm, AA); // Save - - Cs0 = sqrt(SI::qe * Tnorm / (AA * SI::Mp)); // Reference sound speed [m/s] - Omega_ci = SI::qe * Bnorm / (AA * SI::Mp); // Ion cyclotron frequency [1/s] - rho_s0 = Cs0 / Omega_ci; - - mi_me = AA * SI::Mp / SI::Me; - beta_e = SI::qe * Tnorm * Nnorm / (SQ(Bnorm) / SI::mu0); - - output.write("\tmi_me={:e}, beta_e={:e}\n", mi_me, beta_e); - SAVE_ONCE2(mi_me, beta_e); - - output.write("\t Cs={:e}, rho_s={:e}, Omega_ci={:e}\n", Cs0, rho_s0, Omega_ci); - SAVE_ONCE3(Cs0, rho_s0, Omega_ci); - - // Collision times - BoutReal Coulomb = 6.6 - 0.5 * log(Nnorm * 1e-20) + 1.5 * log(Tnorm); - tau_e0 = 1. / (2.91e-6 * (Nnorm / 1e6) * Coulomb * pow(Tnorm, -3. / 2)); - tau_i0 = sqrt(AA) / (4.80e-8 * (Nnorm / 1e6) * Coulomb * pow(Tnorm, -3. / 2)); - - output.write("\ttau_e0={:e}, tau_i0={:e}\n", tau_e0, tau_i0); - - // Get switches from each variable section - Options* optne = opt->getSection("Ne"); - optne->get("evolve", evolve_Ne, true); - optne->get("D", Dn, 1e-3); - optne->get("H", Hn, -1.0); - if (mms) { - Sn = 0.0; - } else { - std::string source; - optne->get("source", source, "0.0"); - Sn = FieldFactory::get()->create3D(source, NULL, mesh); - Sn /= Omega_ci; - SAVE_ONCE(Sn); - } - - Options* optte = opt->getSection("Te"); - optte->get("evolve", evolve_Te, true); - optte->get("D", Dte, 1e-3); - optte->get("H", Hte, -1.0); - if (mms) { - Sp = 0.0; - } else { - std::string source; - optte->get("source", source, "0.0"); - Sp = FieldFactory::get()->create3D(source, NULL, mesh); - Sp /= Omega_ci; - SAVE_ONCE(Sp); - } - - Options* optvort = opt->getSection("Vort"); - optvort->get("evolve", evolve_Vort, true); - optvort->get("D", Dvort, 1e-3); - optvort->get("H", Hvort, -1.0); - - Options* optve = opt->getSection("VePsi"); - optve->get("evolve", evolve_Ve, true); - optve->get("D", Dve, 1e-3); - optve->get("H", Hve, -1.0); - - Options* optvi = opt->getSection("Vi"); - optvi->get("evolve", evolve_Vi, true); - optvi->get("D", Dvi, 1e-3); - optvi->get("H", Hvi, -1.0); - - OPTION(optgbs, parallel, true); - if (!parallel) { - // No parallel dynamics - evolve_Ve = false; - evolve_Vi = false; - } - - // If evolving, add to solver. Otherwise, set to an initial (fixed) value. - if (evolve_Ne) { - solver->add(Ne, "Ne"); - evars.add(Ne); - } else { - initial_profile("Ne", Ne); - SAVE_ONCE(Ne); - } - if (evolve_Vort) { - solver->add(Vort, "Vort"); - evars.add(Vort); - } else { - initial_profile("Vort", Vort); - SAVE_ONCE(Vort); - } - if (evolve_Ve) { - solver->add(VePsi, "VePsi"); - evars.add(VePsi); - } else { - initial_profile("VePsi", VePsi); - SAVE_ONCE(VePsi); - } - if (evolve_Vi) { - solver->add(Vi, "Vi"); - evars.add(Vi); - } else { - initial_profile("Vi", Vi); - SAVE_ONCE(Vi); - } - if (evolve_Te) { - solver->add(Te, "Te"); - evars.add(Te); - } else { - initial_profile("Te", Te); - SAVE_ONCE(Te); - } - - if (evolve_Ve && (!estatic)) { - SAVE_REPEAT2(psi, Ve); - } - - // Load metric tensor from the mesh, passing length and B field normalisations - LoadMetric(rho_s0, Bnorm); - - if (!restarting) { - bool startprofiles; - OPTION(optgbs, startprofiles, true); - if (startprofiles) { - // Read profiles from the mesh - Field2D NeMesh; - if (mesh->get(NeMesh, "Ne0")) { - output << "\nHERE\n"; - // No Ne0. Try Ni0 - if (mesh->get(NeMesh, "Ni0")) { - output << "WARNING: Neither Ne0 nor Ni0 found in mesh input\n"; + Options *opt = Options::getRoot(); + coords = mesh->getCoordinates(); + + // Switches in model section + Options *optgbs = opt->getSection("GBS"); + OPTION(optgbs, ionvis, false); + if (ionvis) { + OPTION(optgbs, Ti, 10); // Ion temperature [eV] + } + OPTION(optgbs, elecvis, false); // Include electron viscosity? + OPTION(optgbs, resistivity, true); // Include resistivity? + OPTION(optgbs, estatic, true); // Electrostatic? + + // option for ExB Poisson Bracket + int bm_exb_flag; + OPTION(optgbs, bm_exb_flag, 2); // Arakawa default + switch (bm_exb_flag) { + case 0: { + bm_exb = BRACKET_STD; + output << "\tBrackets for ExB: default differencing\n"; + break; + } + case 1: { + bm_exb = BRACKET_SIMPLE; + output << "\tBrackets for ExB: simplified operator\n"; + break; + } + case 2: { + bm_exb = BRACKET_ARAKAWA; + output << "\tBrackets for ExB: Arakawa scheme\n"; + break; } - } - NeMesh *= 1e20; // Convert to m^-3 - - Field2D TeMesh; - if (mesh->get(TeMesh, "Te0")) { - // No Te0 - output << "WARNING: Te0 not found in mesh\n"; - } - Field3D ViMesh; - mesh->get(ViMesh, "Vi0"); - - // Normalise - NeMesh /= Nnorm; - TeMesh /= Tnorm; - ViMesh /= Cs0; - - // Add profiles in the mesh file - Ne += NeMesh; - Te += TeMesh; - Vi += ViMesh; + case 3: { + bm_exb = BRACKET_CTU; + output << "\tBrackets for ExB: Corner Transport Upwind method\n"; + break; + } + default: + output << "ERROR: Invalid choice of bracket method. Must be 0 - 3\n"; + return 1; } - // Check for negatives - if (min(Ne, true) < 0.0) { - throw BoutException("Starting density is negative"); + OPTION(opt->getSection("solver"), mms, false); + + if (ionvis) { + SAVE_REPEAT(Gi); } - if (max(Ne, true) < 1e-5) { - throw BoutException("Starting density is too small"); + if (elecvis) { + SAVE_REPEAT(Ge); } - if (min(Te, true) < 0.0) { - throw BoutException("Starting temperature is negative"); + if (resistivity) { + SAVE_REPEAT(nu); } - if (max(Te, true) < 1e-5) { - throw BoutException("Starting temperature is too small"); + + // Normalisation + OPTION(optgbs, Tnorm, 100); // Reference temperature [eV] + OPTION(optgbs, Nnorm, 1e19); // Reference density [m^-3] + OPTION(optgbs, Bnorm, 1.0); // Reference magnetic field [T] + OPTION(optgbs, AA, 2.0); // Ion mass + + output.write("Normalisation Te={:e}, Ne={:e}, B={:e}\n", Tnorm, Nnorm, Bnorm); + SAVE_ONCE4(Tnorm, Nnorm, Bnorm, AA); // Save + + Cs0 = sqrt(SI::qe * Tnorm / (AA * SI::Mp)); // Reference sound speed [m/s] + Omega_ci = SI::qe * Bnorm / (AA * SI::Mp); // Ion cyclotron frequency [1/s] + rho_s0 = Cs0 / Omega_ci; + + mi_me = AA * SI::Mp / SI::Me; + beta_e = SI::qe * Tnorm * Nnorm / (SQ(Bnorm) / SI::mu0); + + output.write("\tmi_me={:e}, beta_e={:e}\n", mi_me, beta_e); + SAVE_ONCE2(mi_me, beta_e); + + output.write("\t Cs={:e}, rho_s={:e}, Omega_ci={:e}\n", Cs0, rho_s0, Omega_ci); + SAVE_ONCE3(Cs0, rho_s0, Omega_ci); + + // Collision times + BoutReal Coulomb = 6.6 - 0.5 * log(Nnorm * 1e-20) + 1.5 * log(Tnorm); + tau_e0 = 1. / (2.91e-6 * (Nnorm / 1e6) * Coulomb * pow(Tnorm, -3. / 2)); + tau_i0 = sqrt(AA) / (4.80e-8 * (Nnorm / 1e6) * Coulomb * pow(Tnorm, -3. / 2)); + + output.write("\ttau_e0={:e}, tau_i0={:e}\n", tau_e0, tau_i0); + + // Get switches from each variable section + Options *optne = opt->getSection("Ne"); + optne->get("evolve", evolve_Ne, true); + optne->get("D", Dn, 1e-3); + optne->get("H", Hn, -1.0); + if (mms) { + Sn = 0.0; + } else { + std::string source; + optne->get("source", source, "0.0"); + Sn = FieldFactory::get()->create3D(source, NULL, mesh); + Sn /= Omega_ci; + SAVE_ONCE(Sn); } - } - SAVE_REPEAT(phi); + Options *optte = opt->getSection("Te"); + optte->get("evolve", evolve_Te, true); + optte->get("D", Dte, 1e-3); + optte->get("H", Hte, -1.0); + if (mms) { + Sp = 0.0; + } else { + std::string source; + optte->get("source", source, "0.0"); + Sp = FieldFactory::get()->create3D(source, NULL, mesh); + Sp /= Omega_ci; + SAVE_ONCE(Sp); + } - phi.setBoundary("phi"); // For Y boundaries (if any) + Options *optvort = opt->getSection("Vort"); + optvort->get("evolve", evolve_Vort, true); + optvort->get("D", Dvort, 1e-3); + optvort->get("H", Hvort, -1.0); + + Options *optve = opt->getSection("VePsi"); + optve->get("evolve", evolve_Ve, true); + optve->get("D", Dve, 1e-3); + optve->get("H", Hve, -1.0); + + Options *optvi = opt->getSection("Vi"); + optvi->get("evolve", evolve_Vi, true); + optvi->get("D", Dvi, 1e-3); + optvi->get("H", Hvi, -1.0); + + OPTION(optgbs, parallel, true); + if (!parallel) { + // No parallel dynamics + evolve_Ve = false; + evolve_Vi = false; + } - // Curvature - OPTION(optgbs, curv_method, 1); // Get the method to use + // If evolving, add to solver. Otherwise, set to an initial (fixed) value. + if (evolve_Ne) { + solver->add(Ne, "Ne"); + evars.add(Ne); + } else { + initial_profile("Ne", Ne); + SAVE_ONCE(Ne); + } + if (evolve_Vort) { + solver->add(Vort, "Vort"); + evars.add(Vort); + } else { + initial_profile("Vort", Vort); + SAVE_ONCE(Vort); + } + if (evolve_Ve) { + solver->add(VePsi, "VePsi"); + evars.add(VePsi); + } else { + initial_profile("VePsi", VePsi); + SAVE_ONCE(VePsi); + } + if (evolve_Vi) { + solver->add(Vi, "Vi"); + evars.add(Vi); + } else { + initial_profile("Vi", Vi); + SAVE_ONCE(Vi); + } + if (evolve_Te) { + solver->add(Te, "Te"); + evars.add(Te); + } else { + initial_profile("Te", Te); + SAVE_ONCE(Te); + } - switch (curv_method) { - case 0: // bxcv vector, upwinding - case 1: { // bxcv vector, central differencing - bxcv.covariant = false; // Read contravariant components - GRID_LOAD(bxcv); // Specified components of b0 x kappa + if (evolve_Ve && (!estatic)) { + SAVE_REPEAT2(psi, Ve); + } - bool ShiftXderivs; - Options::getRoot()->get("shiftXderivs", ShiftXderivs, false); // Read global flag - if (ShiftXderivs) { - Field2D sinty; - GRID_LOAD(sinty); - bxcv.z += sinty * bxcv.x; + // Load metric tensor from the mesh, passing length and B field normalisations + LoadMetric(rho_s0, Bnorm); + + if (!restarting) { + bool startprofiles; + OPTION(optgbs, startprofiles, true); + if (startprofiles) { + // Read profiles from the mesh + Field2D NeMesh; + if (mesh->get(NeMesh, "Ne0")) { + output << "\nHERE\n"; + // No Ne0. Try Ni0 + if (mesh->get(NeMesh, "Ni0")) { + output << "WARNING: Neither Ne0 nor Ni0 found in mesh input\n"; + } + } + NeMesh *= 1e20; // Convert to m^-3 + + Field2D TeMesh; + if (mesh->get(TeMesh, "Te0")) { + // No Te0 + output << "WARNING: Te0 not found in mesh\n"; + } + Field3D ViMesh; + mesh->get(ViMesh, "Vi0"); + + // Normalise + NeMesh /= Nnorm; + TeMesh /= Tnorm; + ViMesh /= Cs0; + + // Add profiles in the mesh file + Ne += NeMesh; + Te += TeMesh; + Vi += ViMesh; + } + + // Check for negatives + if (min(Ne, true) < 0.0) { + throw BoutException("Starting density is negative"); + } + if (max(Ne, true) < 1e-5) { + throw BoutException("Starting density is too small"); + } + if (min(Te, true) < 0.0) { + throw BoutException("Starting temperature is negative"); + } + if (max(Te, true) < 1e-5) { + throw BoutException("Starting temperature is too small"); + } } - // Normalise curvature - bxcv.x /= Bnorm; - bxcv.y /= rho_s0 * rho_s0; - bxcv.z *= rho_s0 * rho_s0; - break; - } - case 2: { // logB, read from input - GRID_LOAD(logB); - mesh->communicate(logB); - SAVE_ONCE(logB); - break; - } - case 3: { // logB, taken from mesh - logB = log(coords->Bxy()); - break; - } - default: - throw BoutException("Invalid value for curv_method"); - }; - - // Phi solver - phiSolver = Laplacian::create(opt->getSection("phiSolver")); - aparSolver = Laplacian::create(opt->getSection("aparSolver")); - - dx4 = SQ(SQ(coords->dx())); - dy4 = SQ(SQ(coords->dy())); - dz4 = SQ(SQ(coords->dz())); - - SAVE_REPEAT(Ve); - - output.write("dx = {:e}, dy = {:e}, dz = {:e}\n", (coords->dx())(2, 2), - (coords->dy())(2, 2), coords->dz()); - output.write("g11 = {:e}, g22 = {:e}, g33 = {:e}\n", coords->g11(2, 2), - coords->g22(2, 2), coords->g33(2, 2)); - output.write("g12 = {:e}, g23 = {:e}\n", coords->g12(2, 2), coords->g23(2, 2)); - output.write("g_11 = {:e}, g_22 = {:e}, g_33 = {:e}\n", coords->g_11(2, 2), - coords->g_22(2, 2), coords->g_33(2, 2)); - output.write("g_12 = {:e}, g_23 = {:e}\n", coords->g_12(2, 2), coords->g_23(2, 2)); - - std::shared_ptr gen = - FieldFactory::get()->parse("source", Options::getRoot()->getSection("ne")); - output << "Ne::source = " << gen->str() << endl; - - return 0; + + SAVE_REPEAT(phi); + + phi.setBoundary("phi"); // For Y boundaries (if any) + + // Curvature + OPTION(optgbs, curv_method, 1); // Get the method to use + + switch (curv_method) { + case 0: // bxcv vector, upwinding + case 1: { // bxcv vector, central differencing + bxcv.covariant = false; // Read contravariant components + GRID_LOAD(bxcv); // Specified components of b0 x kappa + + bool ShiftXderivs; + Options::getRoot()->get("shiftXderivs", ShiftXderivs, false); // Read global flag + if (ShiftXderivs) { + Field2D sinty; + GRID_LOAD(sinty); + bxcv.z += sinty * bxcv.x; + } + // Normalise curvature + bxcv.x /= Bnorm; + bxcv.y /= rho_s0 * rho_s0; + bxcv.z *= rho_s0 * rho_s0; + break; + } + case 2: { // logB, read from input + GRID_LOAD(logB); + mesh->communicate(logB); + SAVE_ONCE(logB); + break; + } + case 3: { // logB, taken from mesh + logB = log(coords->Bxy()); + break; + } + default: + throw BoutException("Invalid value for curv_method"); + }; + + // Phi solver + phiSolver = Laplacian::create(opt->getSection("phiSolver")); + aparSolver = Laplacian::create(opt->getSection("aparSolver")); + + dx4 = SQ(SQ(coords->dx())); + dy4 = SQ(SQ(coords->dy())); + dz4 = SQ(SQ(coords->dz())); + + SAVE_REPEAT(Ve); + + output.write("dx = {:e}, dy = {:e}, dz = {:e}\n", (coords->dx())(2, 2), + (coords->dy())(2, 2), coords->dz()); + output.write("g11 = {:e}, g22 = {:e}, g33 = {:e}\n", coords->g11(2, 2), + coords->g22(2, 2), coords->g33(2, 2)); + output.write("g12 = {:e}, g23 = {:e}\n", coords->g12(2, 2), coords->g23(2, 2)); + output.write("g_11 = {:e}, g_22 = {:e}, g_33 = {:e}\n", coords->g_11(2, 2), + coords->g_22(2, 2), coords->g_33(2, 2)); + output.write("g_12 = {:e}, g_23 = {:e}\n", coords->g_12(2, 2), coords->g_23(2, 2)); + + std::shared_ptr gen = + FieldFactory::get()->parse("source", Options::getRoot()->getSection("ne")); + output << "Ne::source = " << gen->str() << endl; + + return 0; } void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); + auto tokamak_options = TokamakOptions(*mesh); + + bool ShiftXderivs; + BoutReal shearFactor = 1.0; + Options::getRoot()->get("shiftXderivs", ShiftXderivs, false); // Read global flag + if (ShiftXderivs) { + shearFactor = 0.0; // I disappears from metric + } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm, shearFactor); // just define a macro for V_E dot Grad #define vE_Grad(f, p) (bracket(p, f, bm_exb)) -int GBS::rhs(BoutReal t) { - - output.print("TIME = {:e}\r", t); // Bypass logging, only to stdout - - // Communicate evolving variables - mesh->communicate(evars); - - // Floor small values - Te = floor(Te, 1e-3); - Ne = floor(Ne, 1e-3); - - // Solve phi from Vorticity - if (mms) { - // Solve for potential, adding a source term - Field3D phiS = FieldFactory::get()->create3D("phi:source", Options::getRoot(), mesh, - CELL_CENTRE, t); - phi = phiSolver->solve(Vort + phiS); - } else { - phi = phiSolver->solve(Vort); - } - - if (estatic) { - // Electrostatic - Ve = VePsi; - mesh->communicate(Ve); - } else { - aparSolver->setCoefA(-Ne * 0.5 * mi_me * beta_e); - psi = aparSolver->solve(Ne * (Vi - VePsi)); - - Ve = VePsi - 0.5 * mi_me * beta_e * psi; - mesh->communicate(psi, Ve); - } - - // Communicate auxilliary variables - mesh->communicate(phi); - - // Y boundary condition on phi - phi.applyBoundary(); - - // Stress tensor - - Field3D tau_e = Omega_ci * tau_e0 * pow(Te, 1.5) / Ne; // Normalised collision time - - Gi = 0.0; - if (ionvis) { - Field3D tau_i = Omega_ci * tau_i0 * pow(Ti, 1.5) / Ne; - Gi = -(0.96 * Ti * Ne * tau_i) * (2. * Grad_par(Vi) + C(phi) / coords->Bxy()); - mesh->communicate(Gi); - Gi.applyBoundary("neumann"); - } else { - mesh->communicate(Gi); - } - - Field3D logNe = log(Ne); - mesh->communicate(logNe); - - Ge = 0.0; - if (elecvis) { - Ge = -(0.73 * Te * Ne * tau_e) - * (2. * Grad_par(Ve) - + (5. * C(Te) + 5. * Te * C(logNe) + C(phi)) / coords->Bxy()); - mesh->communicate(Ge); - Ge.applyBoundary("neumann"); - } else { - mesh->communicate(Ge); - } - - // Collisional damping (normalised) - nu = 1. / (1.96 * Ne * tau_e * mi_me); - - Field3D Pe = Ne * Te; - - if (evolve_Ne) { - // Density - ddt(Ne) = -vE_Grad(Ne, phi) // ExB term - + (2. / coords->Bxy()) * (C(Pe) - Ne * C(phi)) // Perpendicular compression - + D(Ne, Dn) + H(Ne, Hn); - - if (parallel) { - ddt(Ne) -= - Ne * Grad_par(Ve) + Vpar_Grad_par(Ve, Ne); // Parallel compression, advection - } + int GBS::rhs(BoutReal t) { - if (!mms) { - // Source term - ddt(Ne) += Sn * where(Sn, 1.0, Ne); - } - } - - if (evolve_Te) { - // Electron temperature - ddt(Te) = -vE_Grad(Te, phi) - + (4. / 3.) * (Te / coords->Bxy()) - * ((7. / 2.) * C(Te) + (Te / Ne) * C(Ne) - C(phi)) - + D(Te, Dte) + H(Te, Hte); - - if (parallel) { - ddt(Te) -= Vpar_Grad_par(Ve, Te); - ddt(Te) += (2. / 3.) * Te - * (0.71 * Grad_par(Vi) - 1.71 * Grad_par(Ve) - + 0.71 * (Vi - Ve) * Grad_par(logNe)); - } + output.print("TIME = {:e}\r", t); // Bypass logging, only to stdout - if (!mms) { - // Source term. Note: Power source, so divide by Ne - ddt(Te) += Sp * where(Sp, 1.0, Te * Ne) / Ne; + // Communicate evolving variables + mesh->communicate(evars); - // Source of particles shouldn't include energy, so Ne*Te=const - // hence ddt(Te) = -(Te/Ne)*ddt(Ne) - ddt(Te) -= (Te / Ne) * Sn * where(Sn, 1.0, 0.0); - } - } - - if (evolve_Vort) { - // Vorticity - ddt(Vort) = -vE_Grad(Vort, phi) // ExB term - + 2. * coords->Bxy() * C(Pe) / Ne + coords->Bxy() * C(Gi) / (3. * Ne) - + D(Vort, Dvort) + H(Vort, Hvort); - - if (parallel) { - Field3D delV = Vi - Ve; - mesh->communicate(delV); - ddt(Vort) -= Vpar_Grad_par(Vi, Vort); // Parallel advection - ddt(Vort) += SQ(coords->Bxy()) * (Grad_par(delV) + (Vi - Ve) * Grad_par(logNe)); - } - } + // Floor small values + Te = floor(Te, 1e-3); + Ne = floor(Ne, 1e-3); - if (evolve_Ve) { - // Electron velocity + // Solve phi from Vorticity + if (mms) { + // Solve for potential, adding a source term + Field3D phiS = FieldFactory::get()->create3D("phi:source", Options::getRoot(), mesh, + CELL_CENTRE, t); + phi = phiSolver->solve(Vort + phiS); + } else { + phi = phiSolver->solve(Vort); + } - ddt(VePsi) = - -vE_Grad(Ve, phi) - Vpar_Grad_par(Ve, Ve) - mi_me * (2. / 3.) * Grad_par(Ge) - - mi_me * nu * (Ve - Vi) + mi_me * Grad_par(phi) - - mi_me * (Te * Grad_par(logNe) + 1.71 * Grad_par(Te)) + D(Ve, Dve) + H(Ve, Hve); - } + if (estatic) { + // Electrostatic + Ve = VePsi; + mesh->communicate(Ve); + } else { + aparSolver->setCoefA(-Ne * 0.5 * mi_me * beta_e); + psi = aparSolver->solve(Ne * (Vi - VePsi)); - if (evolve_Vi) { - // Ion velocity + Ve = VePsi - 0.5 * mi_me * beta_e * psi; + mesh->communicate(psi, Ve); + } - ddt(Vi) = -vE_Grad(Vi, phi) - Vpar_Grad_par(Vi, Vi) - (2. / 3.) * Grad_par(Gi) - - (Grad_par(Te) + Te * Grad_par(logNe)) // Parallel pressure - + D(Vi, Dvi) + H(Vi, Hvi); - } + // Communicate auxilliary variables + mesh->communicate(phi); - return 0; -} + // Y boundary condition on phi + phi.applyBoundary(); -const Field3D GBS::C(const Field3D& f) { // Curvature operator - Field3D g; //Temporary in case we need to communicate - switch (curv_method) { - case 0: - g = f; - mesh->communicate(g); - return V_dot_Grad(bxcv, g); - case 1: - g = f; - mesh->communicate(g); - return bxcv * Grad(g); - } - return coords->Bxy() * bracket(logB, f, BRACKET_ARAKAWA); -} + // Stress tensor -const Field3D GBS::D(const Field3D& f, BoutReal d) { // Diffusion operator - if (d < 0.0) { - return 0.0; - } - return d * Delp2(f); -} + Field3D tau_e = Omega_ci * tau_e0 * pow(Te, 1.5) / Ne; // Normalised collision time -const Field3D GBS::H(const Field3D& f, BoutReal h) { // Numerical hyper-diffusion operator - if (h < 0.0) { - return 0.0; - } - return -h * (dx4 * D4DX4(f) + dz4 * D4DZ4(f)); // + dy4*D4DY4(f) -} + Gi = 0.0; + if (ionvis) { + Field3D tau_i = Omega_ci * tau_i0 * pow(Ti, 1.5) / Ne; + Gi = -(0.96 * Ti * Ne * tau_i) * (2. * Grad_par(Vi) + C(phi) / coords->Bxy()); + mesh->communicate(Gi); + Gi.applyBoundary("neumann"); + } else { + mesh->communicate(Gi); + } + + Field3D logNe = log(Ne); + mesh->communicate(logNe); + + Ge = 0.0; + if (elecvis) { + Ge = -(0.73 * Te * Ne * tau_e) + * (2. * Grad_par(Ve) + + (5. * C(Te) + 5. * Te * C(logNe) + C(phi)) / coords->Bxy()); + mesh->communicate(Ge); + Ge.applyBoundary("neumann"); + } else { + mesh->communicate(Ge); + } + + // Collisional damping (normalised) + nu = 1. / (1.96 * Ne * tau_e * mi_me); + + Field3D Pe = Ne * Te; + + if (evolve_Ne) { + // Density + ddt(Ne) = -vE_Grad(Ne, phi) // ExB term + + (2. / coords->Bxy()) * (C(Pe) - Ne * C(phi)) // Perpendicular compression + + D(Ne, Dn) + H(Ne, Hn); + + if (parallel) { + ddt(Ne) -= + Ne * Grad_par(Ve) + Vpar_Grad_par(Ve, Ne); // Parallel compression, advection + } + + if (!mms) { + // Source term + ddt(Ne) += Sn * where(Sn, 1.0, Ne); + } + } + + if (evolve_Te) { + // Electron temperature + ddt(Te) = -vE_Grad(Te, phi) + + (4. / 3.) * (Te / coords->Bxy()) + * ((7. / 2.) * C(Te) + (Te / Ne) * C(Ne) - C(phi)) + + D(Te, Dte) + H(Te, Hte); + + if (parallel) { + ddt(Te) -= Vpar_Grad_par(Ve, Te); + ddt(Te) += (2. / 3.) * Te + * (0.71 * Grad_par(Vi) - 1.71 * Grad_par(Ve) + + 0.71 * (Vi - Ve) * Grad_par(logNe)); + } + + if (!mms) { + // Source term. Note: Power source, so divide by Ne + ddt(Te) += Sp * where(Sp, 1.0, Te * Ne) / Ne; + + // Source of particles shouldn't include energy, so Ne*Te=const + // hence ddt(Te) = -(Te/Ne)*ddt(Ne) + ddt(Te) -= (Te / Ne) * Sn * where(Sn, 1.0, 0.0); + } + } + + if (evolve_Vort) { + // Vorticity + ddt(Vort) = -vE_Grad(Vort, phi) // ExB term + + 2. * coords->Bxy() * C(Pe) / Ne + coords->Bxy() * C(Gi) / (3. * Ne) + + D(Vort, Dvort) + H(Vort, Hvort); + + if (parallel) { + Field3D delV = Vi - Ve; + mesh->communicate(delV); + ddt(Vort) -= Vpar_Grad_par(Vi, Vort); // Parallel advection + ddt(Vort) += SQ(coords->Bxy()) * (Grad_par(delV) + (Vi - Ve) * Grad_par(logNe)); + } + } + + if (evolve_Ve) { + // Electron velocity + + ddt(VePsi) = + -vE_Grad(Ve, phi) - Vpar_Grad_par(Ve, Ve) - mi_me * (2. / 3.) * Grad_par(Ge) + - mi_me * nu * (Ve - Vi) + mi_me * Grad_par(phi) + - mi_me * (Te * Grad_par(logNe) + 1.71 * Grad_par(Te)) + D(Ve, Dve) + H(Ve, Hve); + } + + if (evolve_Vi) { + // Ion velocity + + ddt(Vi) = -vE_Grad(Vi, phi) - Vpar_Grad_par(Vi, Vi) - (2. / 3.) * Grad_par(Gi) + - (Grad_par(Te) + Te * Grad_par(logNe)) // Parallel pressure + + D(Vi, Dvi) + H(Vi, Hvi); + } + + return 0; + } + + const Field3D GBS::C(const Field3D &f) { // Curvature operator + Field3D g; //Temporary in case we need to communicate + switch (curv_method) { + case 0: + g = f; + mesh->communicate(g); + return V_dot_Grad(bxcv, g); + case 1: + g = f; + mesh->communicate(g); + return bxcv * Grad(g); + } + return coords->Bxy() * bracket(logB, f, BRACKET_ARAKAWA); + } + + const Field3D GBS::D(const Field3D &f, BoutReal d) { // Diffusion operator + if (d < 0.0) { + return 0.0; + } + return d * Delp2(f); + } + + const Field3D GBS::H(const Field3D &f, BoutReal h) { // Numerical hyper-diffusion operator + if (h < 0.0) { + return 0.0; + } + return -h * (dx4 * D4DX4(f) + dz4 * D4DZ4(f)); // + dy4*D4DY4(f) + } // Standard main() function -BOUTMAIN(GBS); + BOUTMAIN(GBS); diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 141787be1b..4aad345967 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -114,6 +114,8 @@ class ELMpb : public PhysicsModel { BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) BoutReal ehyperviscos; // electron Hyper-viscosity coefficient + TokamakOptions tokamak_options = TokamakOptions(*mesh); + bool mms; // True if testing with Method of Manufactured Solutions const BoutReal MU0 = 4.0e-7 * PI; @@ -122,8 +124,6 @@ class ELMpb : public PhysicsModel { // Communication objects FieldGroup comms; - TokamakOptions tokamak_options = TokamakOptions(*mesh); - // Parallel gradient along perturbed field-line const Field3D Grad_parP(const Field3D& f, CELL_LOC loc = CELL_DEFAULT) { Field3D result; @@ -139,9 +139,6 @@ class ELMpb : public PhysicsModel { public: int init(bool restarting) { - - bool noshear; - output.write("Solving high-beta flute reduced equations\n"); output.write("\tFile : {:s}\n", __FILE__); output.write("\tCompiled: {:s} at {:s}\n", __DATE__, __TIME__); @@ -153,6 +150,8 @@ class ELMpb : public PhysicsModel { mesh->get(J0, "Jpar0"); // A / m^2 mesh->get(P0, "pressure"); // Pascals + Coordinates* coords = mesh->getCoordinates(); + ////////////////////////////////////////////////////////////// // Read parameters from the options file // @@ -292,15 +291,23 @@ class ELMpb : public PhysicsModel { bool ShiftXderivs; globalOptions->get("shiftXderivs", ShiftXderivs, false); // Read global flag + BoutReal shearFactor = 1.0; if (ShiftXderivs) { - if (not mesh->IncIntShear) { + if (mesh->IncIntShear) { + // BOUT-06 style, using d/dx = d/dpsi + I * d/dz + coords->setIntShiftTorsion(tokamak_options.I); + + } else { // Dimits style, using local coordinate system if (include_curvature) { b0xcv.z += tokamak_options.I * b0xcv.x; } + shearFactor = 0.0; // I disappears from metric } } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lbar, Bbar, shearFactor); + ////////////////////////////////////////////////////////////// // NORMALISE QUANTITIES @@ -383,26 +390,6 @@ class ELMpb : public PhysicsModel { dump.add(eta, "eta", 0); - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - if (!mesh->IncIntShear) { - noshear = true; - } - - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lbar, Bbar); - - ////////////////////////////////////////////////////////////// - // SHIFTED RADIAL COORDINATES - - bool ShiftXderivs; - globalOptions->get("shiftXderivs", ShiftXderivs, false); // Read global flag - if (ShiftXderivs) { - if (mesh->IncIntShear) { - // BOUT-06 style, using d/dx = d/dpsi + I * d/dz - coord->setIntShiftTorsion(tokamak_coordinates.get_ShearFactor()); - } - } - // Set B field vector B0vec.covariant = false; diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index b80f18d863..e5f0babc82 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -46,9 +46,17 @@ class TokamakMMS : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); Coordinates* coords = mesh->getCoordinates(); + + bool ShiftXderivs; + BoutReal shearFactor = 1.0; + Options::getRoot()->get("shiftXderivs", ShiftXderivs, false); // Read global flag + if (ShiftXderivs) { + shearFactor = 0.0; // I disappears from metric + } + + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm, shearFactor); } private: diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index dd6e68218a..e0ab0e8ce6 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -131,12 +131,10 @@ class TwoFluid : public PhysicsModel { /************* SHIFTED RADIAL COORDINATES ************/ - bool noshear = false; const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric b0xcv.z += tokamak_options.I * b0xcv.x; - noshear = true; } /************** CALCULATE PARAMETERS *****************/ @@ -194,7 +192,7 @@ class TwoFluid : public PhysicsModel { pei0 = (Ti0 + Te0) * Ni0; pe0 = Te0 * Ni0; - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, rho_s, bmag / 1e4, ShearFactor); /**************** SET EVOLVING VARIABLES *************/ diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index 884333faa1..c5bf22b11e 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -80,11 +80,10 @@ class Interchange : public PhysicsModel { /************* SHIFTED RADIAL COORDINATES ************/ - bool noshear = false; const bool ShiftXderivs = (*globalOptions)["ShiftXderivs"].withDefault(false); if (ShiftXderivs) { ShearFactor = 0.0; // I disappears from metric - noshear = true; + b0xcv.z += tokamak_options.I * b0xcv.x; } /************** CALCULATE PARAMETERS *****************/ @@ -101,11 +100,7 @@ class Interchange : public PhysicsModel { hthe0 / rho_s); } - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, noshear, rho_s, bmag / 1e4, ShearFactor); - - if (ShiftXderivs) { - b0xcv.z += tokamak_options.ShearFactor * b0xcv.x; - } + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, rho_s, bmag / 1e4, ShearFactor); /************** NORMALISE QUANTITIES *****************/ diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index addbd6ec54..979fd10031 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -4,20 +4,30 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - bool noshear; - auto mesh = bout::globals::mesh; auto coords = mesh->getCoordinates(); + // Checking for dpsi and qinty used in BOUT grids + Field2D dx; + if (!mesh->get(dx, "dpsi")) { + output << "\tUsing dpsi as the x grid spacing\n"; + coords->setDx(dx); // Only use dpsi if found + } else { + // dx will have been read already from the grid + output << "\tUsing dx as the x grid spacing\n"; + } + Field2D qinty; + // Calculate metric components std::string ptstr; Options::getRoot()->get("mesh:paralleltransform", ptstr, "identity"); // Convert to lower case for comparison ptstr = lowercase(ptstr); + BoutReal shearFactor = 1.0; if (ptstr == "shifted") { - noshear = true; + shearFactor = 0.0; // I disappears from metric } auto tokamak_options = TokamakOptions(*mesh); - set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, true, Lnorm, Bnorm); + set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm, shearFactor); } From 3d6b2c12915bba68e24b44bece56db3f59826cf9 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Fri, 21 Feb 2025 15:39:33 +0000 Subject: [PATCH 94/98] If no value is specified for dpsi, set TokamakOptions.dx to mesh.getCoordinates()->dx() --- include/bout/tokamak_coordinates.hxx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 00c19606bc..519d85b6d4 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -18,7 +18,8 @@ struct TokamakOptions { Field2D hthe; FieldMetric I; FieldMetric dx; - TokamakOptions(Mesh& mesh) { + + TokamakOptions(Mesh &mesh) { mesh.get(Rxy, "Rxy"); // mesh->get(Zxy, "Zxy"); mesh.get(Bpxy, "Bpxy"); @@ -26,8 +27,11 @@ struct TokamakOptions { mesh.get(Bxy, "Bxy"); mesh.get(hthe, "hthe"); mesh.get(I, "sinty"); - mesh.get(dx, "dpsi"); + if (mesh.get(dx, "dpsi")) { + dx = mesh.getCoordinates()->dx(); + } } + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { Rxy /= Lbar; Bpxy /= Bbar; @@ -46,7 +50,7 @@ BoutReal get_sign_of_bp(Field2D Bpxy) { return 1.0; } -void set_tokamak_coordinates_on_mesh(TokamakOptions& tokamak_options, Mesh& mesh, BoutReal Lbar, +void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor = 0.0) { tokamak_options.normalise(Lbar, Bbar, ShearFactor); From ac26ef9178c02b09433a0ca95ccbe9ebc11e50f5 Mon Sep 17 00:00:00 2001 From: tomc271 <58003025+tomc271@users.noreply.github.com> Date: Fri, 21 Feb 2025 17:29:17 +0000 Subject: [PATCH 95/98] Apply black changes --- tests/integrated/test_suite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integrated/test_suite b/tests/integrated/test_suite index 307a8d84b3..77ad7882c4 100755 --- a/tests/integrated/test_suite +++ b/tests/integrated/test_suite @@ -188,7 +188,7 @@ class Test(threading.Thread): self.output += "\n(It is likely that a timeout occured)" else: # ❌ Failed - print("\u274C", end="") # No newline + print("\u274c", end="") # No newline print(" %7.3f s" % (time.time() - self.local.start_time), flush=True) def _cost(self): From 0d3b79baa74cf1542636664fe4d71dc9072df30f Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 18 Mar 2025 11:06:55 +0000 Subject: [PATCH 96/98] Move implementations to new tokamak_coordinates.cxx file --- CMakeLists.txt | 1 + include/bout/tokamak_coordinates.hxx | 62 +++------------------------ src/mesh/tokamak_coordinates.cxx | 64 ++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 56 deletions(-) create mode 100644 src/mesh/tokamak_coordinates.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index dc1371fbe9..13d316420a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -362,6 +362,7 @@ set(BOUT_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/include/bout/revision.hxx ${CMAKE_CURRENT_BINARY_DIR}/include/bout/version.hxx ./include/bout/tokamak_coordinates.hxx + ./src/mesh/tokamak_coordinates.cxx ) diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 519d85b6d4..83ee2a6614 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -4,11 +4,10 @@ #include "bout.hxx" #include "bout/bout_types.hxx" -#include "bout/christoffel_symbols.hxx" -#include "bout/coordinates.hxx" #include "bout/field2d.hxx" -#include "bout/utils.hxx" -#include "bout/vector2d.hxx" +#include "bout/metric_tensor.hxx" + +using FieldMetric = MetricTensor::FieldMetric; struct TokamakOptions { Field2D Rxy; @@ -19,18 +18,7 @@ struct TokamakOptions { FieldMetric I; FieldMetric dx; - TokamakOptions(Mesh &mesh) { - mesh.get(Rxy, "Rxy"); - // mesh->get(Zxy, "Zxy"); - mesh.get(Bpxy, "Bpxy"); - mesh.get(Btxy, "Btxy"); - mesh.get(Bxy, "Bxy"); - mesh.get(hthe, "hthe"); - mesh.get(I, "sinty"); - if (mesh.get(dx, "dpsi")) { - dx = mesh.getCoordinates()->dx(); - } - } + TokamakOptions(Mesh &mesh); void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { Rxy /= Lbar; @@ -43,47 +31,9 @@ struct TokamakOptions { } }; -BoutReal get_sign_of_bp(Field2D Bpxy) { - if (min(Bpxy, true) < 0.0) { - return -1.0; - } - return 1.0; -} +BoutReal get_sign_of_bp(const Field2D& Bpxy); void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, - BoutReal Bbar, BoutReal ShearFactor = 0.0) { - - tokamak_options.normalise(Lbar, Bbar, ShearFactor); - - const BoutReal sign_of_bp = get_sign_of_bp(tokamak_options.Bpxy); - - auto *coord = mesh.getCoordinates(); - - const auto g11 = SQ(tokamak_options.Rxy * tokamak_options.Bpxy); - const auto g22 = 1.0 / SQ(tokamak_options.hthe); - const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamak_options.Bxy) / g11; - const auto g12 = 0.0; - const auto g13 = -ShearFactor * g11; - const auto g23 = -sign_of_bp * tokamak_options.Btxy / - (tokamak_options.hthe * tokamak_options.Bpxy * tokamak_options.Rxy); - - const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamak_options.Rxy); - const auto g_22 = SQ(tokamak_options.Bxy * tokamak_options.hthe / tokamak_options.Bpxy); - const auto g_33 = tokamak_options.Rxy * tokamak_options.Rxy; - const auto g_12 = - sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * ShearFactor * tokamak_options.Rxy / - tokamak_options.Bpxy; - const auto g_13 = ShearFactor * tokamak_options.Rxy * tokamak_options.Rxy; - const auto g_23 = sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * tokamak_options.Rxy / - tokamak_options.Bpxy; - - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - - - coord->setJ(tokamak_options.hthe / tokamak_options.Bpxy); - coord->setBxy(tokamak_options.Bxy); - coord->setDx(tokamak_options.dx); -} + BoutReal Bbar, BoutReal ShearFactor = 0.0); #endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/src/mesh/tokamak_coordinates.cxx b/src/mesh/tokamak_coordinates.cxx new file mode 100644 index 0000000000..4db92bc88f --- /dev/null +++ b/src/mesh/tokamak_coordinates.cxx @@ -0,0 +1,64 @@ + +#include "bout/tokamak_coordinates.hxx" +#include "bout/bout.hxx" +#include "bout/bout_types.hxx" +#include "bout/field2d.hxx" +#include "bout/utils.hxx" + +BoutReal get_sign_of_bp(const Field2D& Bpxy) { + if (min(Bpxy, true) < 0.0) { + return -1.0; + } + return 1.0; +} + +TokamakOptions::TokamakOptions(Mesh &mesh) { + mesh.get(Rxy, "Rxy"); + // mesh->get(Zxy, "Zxy"); + mesh.get(Bpxy, "Bpxy"); + mesh.get(Btxy, "Btxy"); + mesh.get(Bxy, "Bxy"); + mesh.get(hthe, "hthe"); + mesh.get(I, "sinty"); + if (mesh.get(dx, "dpsi")) { + dx = mesh.getCoordinates()->dx(); + } +} + +void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, + BoutReal + Bbar, BoutReal + ShearFactor) { + + tokamak_options.normalise(Lbar, Bbar, ShearFactor); + + const BoutReal sign_of_bp = get_sign_of_bp(tokamak_options.Bpxy); + + auto *coord = mesh.getCoordinates(); + + const auto g11 = SQ(tokamak_options.Rxy * tokamak_options.Bpxy); + const auto g22 = 1.0 / SQ(tokamak_options.hthe); + const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamak_options.Bxy) / g11; + const auto g12 = 0.0; + const auto g13 = -ShearFactor * g11; + const auto g23 = -sign_of_bp * tokamak_options.Btxy / + (tokamak_options.hthe * tokamak_options.Bpxy * tokamak_options.Rxy); + + const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamak_options.Rxy); + const auto g_22 = SQ(tokamak_options.Bxy * tokamak_options.hthe / tokamak_options.Bpxy); + const auto g_33 = tokamak_options.Rxy * tokamak_options.Rxy; + const auto g_12 = + sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * ShearFactor * tokamak_options.Rxy / + tokamak_options.Bpxy; + const auto g_13 = ShearFactor * tokamak_options.Rxy * tokamak_options.Rxy; + const auto g_23 = sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * tokamak_options.Rxy / + tokamak_options.Bpxy; + + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + + + coord->setJ(tokamak_options.hthe / tokamak_options.Bpxy); + coord->setBxy(tokamak_options.Bxy); + coord->setDx(tokamak_options.dx); +} \ No newline at end of file From 2f99a73aba0392164d34f59cde95feab6cabdd47 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 18 Mar 2025 13:51:16 +0000 Subject: [PATCH 97/98] Move TokamakOptions to `bout` namespace --- examples/6field-simple/elm_6f.cxx | 2 +- examples/conducting-wall-mode/cwm.cxx | 2 +- examples/constraints/alfven-wave/alfven.cxx | 2 +- examples/dalf3/dalf3.cxx | 2 +- .../elm-pb-outerloop/elm_pb_outerloop.cxx | 2 +- examples/elm-pb/elm_pb.cxx | 2 +- examples/gyro-gem/gem.cxx | 2 +- examples/laplacexy/alfven-wave/alfven.cxx | 2 +- examples/laplacexy/laplace_perp/test.cxx | 2 +- examples/wave-slab/wave_slab.cxx | 2 +- include/bout/tokamak_coordinates.hxx | 56 +++++------ src/mesh/tokamak_coordinates.cxx | 92 ++++++++++--------- tests/MMS/GBS/gbs.cxx | 2 +- tests/MMS/elm-pb/elm_pb.cxx | 2 +- tests/MMS/tokamak/tokamak.cxx | 2 +- .../test-drift-instability/2fluid.cxx | 2 +- .../test-interchange-instability/2fluid.cxx | 2 +- .../integrated/test-laplacexy/loadmetric.cxx | 2 +- 18 files changed, 94 insertions(+), 86 deletions(-) diff --git a/examples/6field-simple/elm_6f.cxx b/examples/6field-simple/elm_6f.cxx index 201e4d61ed..88f2830d99 100644 --- a/examples/6field-simple/elm_6f.cxx +++ b/examples/6field-simple/elm_6f.cxx @@ -235,7 +235,7 @@ class Elm_6f : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); BoutReal LnLambda; // ln(Lambda) diff --git a/examples/conducting-wall-mode/cwm.cxx b/examples/conducting-wall-mode/cwm.cxx index 961c37cb1e..6a5d7e1252 100644 --- a/examples/conducting-wall-mode/cwm.cxx +++ b/examples/conducting-wall-mode/cwm.cxx @@ -119,7 +119,7 @@ class CWM : public PhysicsModel { hthe0 / rho_s); } - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); /************** NORMALISE QUANTITIES *****************/ diff --git a/examples/constraints/alfven-wave/alfven.cxx b/examples/constraints/alfven-wave/alfven.cxx index 144c434807..5fc9a08475 100644 --- a/examples/constraints/alfven-wave/alfven.cxx +++ b/examples/constraints/alfven-wave/alfven.cxx @@ -173,7 +173,7 @@ class Alfven : public PhysicsModel { shearFactor = 0.0; // I disappears from metric } - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm, shearFactor); } }; diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 3081f91f80..96ee6cd10e 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -81,7 +81,7 @@ class DALF3 : public PhysicsModel { std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) Field2D phi2D; // Axisymmetric potential, used when split_n0=true - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); protected: int init(bool UNUSED(restarting)) override { diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index c9ba1c0ce2..1300cb6421 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -288,7 +288,7 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 7b02a13823..b8a8bd41b9 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -230,7 +230,7 @@ class ELMpb : public PhysicsModel { int damp_width; // Width of inner damped region BoutReal damp_t_const; // Timescale of damping - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); const BoutReal MU0 = 4.0e-7 * PI; const BoutReal Mi = 2.0 * 1.6726e-27; // Ion mass diff --git a/examples/gyro-gem/gem.cxx b/examples/gyro-gem/gem.cxx index d8245a683b..3eb7f6fcca 100644 --- a/examples/gyro-gem/gem.cxx +++ b/examples/gyro-gem/gem.cxx @@ -242,7 +242,7 @@ class GEM : public PhysicsModel { Tbar = options["Tbar"].withDefault(Tbar); // Override in options file SAVE_ONCE(Tbar); // Timescale in seconds - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); if (mesh->get(Bbar, "Bbar")) { if (mesh->get(Bbar, "bmag")) { diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index fd286fc550..7cca9bc171 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -171,7 +171,7 @@ class Alfven : public PhysicsModel { void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm); Coordinates* coord = mesh->getCoordinates(); // Metric tensor } diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 723097f2f3..87d4b5ecb0 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -14,7 +14,7 @@ int main(int argc, char** argv) { bool calc_metric; calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, 1.0, 1.0); } diff --git a/examples/wave-slab/wave_slab.cxx b/examples/wave-slab/wave_slab.cxx index 02c17d0378..ff2d9b821f 100644 --- a/examples/wave-slab/wave_slab.cxx +++ b/examples/wave-slab/wave_slab.cxx @@ -17,7 +17,7 @@ class WaveTest : public PhysicsModel { public: int init(bool UNUSED(restarting)) { - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); int ShiftXderivs = 0; mesh->get(ShiftXderivs, "false"); diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 83ee2a6614..0f08436162 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -9,31 +9,35 @@ using FieldMetric = MetricTensor::FieldMetric; -struct TokamakOptions { - Field2D Rxy; - Field2D Bpxy; - Field2D Btxy; - Field2D Bxy; - Field2D hthe; - FieldMetric I; - FieldMetric dx; - - TokamakOptions(Mesh &mesh); - - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { - Rxy /= Lbar; - Bpxy /= Bbar; - Btxy /= Bbar; - Bxy /= Bbar; - hthe /= Lbar; - I *= Lbar * Lbar * Bbar * ShearFactor; - dx /= Lbar * Lbar * Bbar; - } -}; - -BoutReal get_sign_of_bp(const Field2D& Bpxy); - -void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, - BoutReal Bbar, BoutReal ShearFactor = 0.0); +namespace bout { + + struct TokamakOptions { + Field2D Rxy; + Field2D Bpxy; + Field2D Btxy; + Field2D Bxy; + Field2D hthe; + FieldMetric I; + FieldMetric dx; + + TokamakOptions(Mesh &mesh); + + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { + Rxy /= Lbar; + Bpxy /= Bbar; + Btxy /= Bbar; + Bxy /= Bbar; + hthe /= Lbar; + I *= Lbar * Lbar * Bbar * ShearFactor; + dx /= Lbar * Lbar * Bbar; + } + }; + + BoutReal get_sign_of_bp(const Field2D &Bpxy); + + void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, + BoutReal Bbar, BoutReal ShearFactor = 0.0); + +} #endif //BOUT_TOKAMAK_COORDINATES_HXX diff --git a/src/mesh/tokamak_coordinates.cxx b/src/mesh/tokamak_coordinates.cxx index 4db92bc88f..fcc250747c 100644 --- a/src/mesh/tokamak_coordinates.cxx +++ b/src/mesh/tokamak_coordinates.cxx @@ -5,60 +5,64 @@ #include "bout/field2d.hxx" #include "bout/utils.hxx" -BoutReal get_sign_of_bp(const Field2D& Bpxy) { - if (min(Bpxy, true) < 0.0) { - return -1.0; + +namespace bout { + + BoutReal get_sign_of_bp(const Field2D &Bpxy) { + if (min(Bpxy, true) < 0.0) { + return -1.0; + } + return 1.0; } - return 1.0; -} -TokamakOptions::TokamakOptions(Mesh &mesh) { - mesh.get(Rxy, "Rxy"); - // mesh->get(Zxy, "Zxy"); - mesh.get(Bpxy, "Bpxy"); - mesh.get(Btxy, "Btxy"); - mesh.get(Bxy, "Bxy"); - mesh.get(hthe, "hthe"); - mesh.get(I, "sinty"); - if (mesh.get(dx, "dpsi")) { - dx = mesh.getCoordinates()->dx(); + TokamakOptions::TokamakOptions(Mesh &mesh) { + mesh.get(Rxy, "Rxy"); + // mesh->get(Zxy, "Zxy"); + mesh.get(Bpxy, "Bpxy"); + mesh.get(Btxy, "Btxy"); + mesh.get(Bxy, "Bxy"); + mesh.get(hthe, "hthe"); + mesh.get(I, "sinty"); + if (mesh.get(dx, "dpsi")) { + dx = mesh.getCoordinates()->dx(); + } } -} -void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, - BoutReal - Bbar, BoutReal - ShearFactor) { + void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, + BoutReal + Bbar, BoutReal + ShearFactor) { - tokamak_options.normalise(Lbar, Bbar, ShearFactor); + tokamak_options.normalise(Lbar, Bbar, ShearFactor); - const BoutReal sign_of_bp = get_sign_of_bp(tokamak_options.Bpxy); + const BoutReal sign_of_bp = get_sign_of_bp(tokamak_options.Bpxy); - auto *coord = mesh.getCoordinates(); + auto *coord = mesh.getCoordinates(); - const auto g11 = SQ(tokamak_options.Rxy * tokamak_options.Bpxy); - const auto g22 = 1.0 / SQ(tokamak_options.hthe); - const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamak_options.Bxy) / g11; - const auto g12 = 0.0; - const auto g13 = -ShearFactor * g11; - const auto g23 = -sign_of_bp * tokamak_options.Btxy / - (tokamak_options.hthe * tokamak_options.Bpxy * tokamak_options.Rxy); + const auto g11 = SQ(tokamak_options.Rxy * tokamak_options.Bpxy); + const auto g22 = 1.0 / SQ(tokamak_options.hthe); + const auto g33 = SQ(ShearFactor) * g11 + SQ(tokamak_options.Bxy) / g11; + const auto g12 = 0.0; + const auto g13 = -ShearFactor * g11; + const auto g23 = -sign_of_bp * tokamak_options.Btxy / + (tokamak_options.hthe * tokamak_options.Bpxy * tokamak_options.Rxy); - const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamak_options.Rxy); - const auto g_22 = SQ(tokamak_options.Bxy * tokamak_options.hthe / tokamak_options.Bpxy); - const auto g_33 = tokamak_options.Rxy * tokamak_options.Rxy; - const auto g_12 = - sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * ShearFactor * tokamak_options.Rxy / - tokamak_options.Bpxy; - const auto g_13 = ShearFactor * tokamak_options.Rxy * tokamak_options.Rxy; - const auto g_23 = sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * tokamak_options.Rxy / - tokamak_options.Bpxy; + const auto g_11 = 1.0 / g11 + SQ(ShearFactor * tokamak_options.Rxy); + const auto g_22 = SQ(tokamak_options.Bxy * tokamak_options.hthe / tokamak_options.Bpxy); + const auto g_33 = tokamak_options.Rxy * tokamak_options.Rxy; + const auto g_12 = + sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * ShearFactor * tokamak_options.Rxy / + tokamak_options.Bpxy; + const auto g_13 = ShearFactor * tokamak_options.Rxy * tokamak_options.Rxy; + const auto g_23 = sign_of_bp * tokamak_options.Btxy * tokamak_options.hthe * tokamak_options.Rxy / + tokamak_options.Bpxy; - coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), - CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); + coord->setMetricTensor(ContravariantMetricTensor(g11, g22, g33, g12, g13, g23), + CovariantMetricTensor(g_11, g_22, g_33, g_12, g_13, g_23)); - coord->setJ(tokamak_options.hthe / tokamak_options.Bpxy); - coord->setBxy(tokamak_options.Bxy); - coord->setDx(tokamak_options.dx); + coord->setJ(tokamak_options.hthe / tokamak_options.Bpxy); + coord->setBxy(tokamak_options.Bxy); + coord->setDx(tokamak_options.dx); + } } \ No newline at end of file diff --git a/tests/MMS/GBS/gbs.cxx b/tests/MMS/GBS/gbs.cxx index af29357f83..5ea46173c6 100644 --- a/tests/MMS/GBS/gbs.cxx +++ b/tests/MMS/GBS/gbs.cxx @@ -315,7 +315,7 @@ int GBS::init(bool restarting) { void GBS::LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); bool ShiftXderivs; BoutReal shearFactor = 1.0; diff --git a/tests/MMS/elm-pb/elm_pb.cxx b/tests/MMS/elm-pb/elm_pb.cxx index 4aad345967..aef522b462 100644 --- a/tests/MMS/elm-pb/elm_pb.cxx +++ b/tests/MMS/elm-pb/elm_pb.cxx @@ -114,7 +114,7 @@ class ELMpb : public PhysicsModel { BoutReal hyperresist; // Hyper-resistivity coefficient (in core only) BoutReal ehyperviscos; // electron Hyper-viscosity coefficient - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); bool mms; // True if testing with Method of Manufactured Solutions diff --git a/tests/MMS/tokamak/tokamak.cxx b/tests/MMS/tokamak/tokamak.cxx index e5f0babc82..2c64218d5e 100644 --- a/tests/MMS/tokamak/tokamak.cxx +++ b/tests/MMS/tokamak/tokamak.cxx @@ -45,7 +45,7 @@ class TokamakMMS : public PhysicsModel { } void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); Coordinates* coords = mesh->getCoordinates(); diff --git a/tests/integrated/test-drift-instability/2fluid.cxx b/tests/integrated/test-drift-instability/2fluid.cxx index e0ab0e8ce6..291978fe6e 100644 --- a/tests/integrated/test-drift-instability/2fluid.cxx +++ b/tests/integrated/test-drift-instability/2fluid.cxx @@ -59,7 +59,7 @@ class TwoFluid : public PhysicsModel { FieldGroup comms; // Group of variables for communications - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); Coordinates* coord; // Coordinate system diff --git a/tests/integrated/test-interchange-instability/2fluid.cxx b/tests/integrated/test-interchange-instability/2fluid.cxx index c5bf22b11e..b12340610e 100644 --- a/tests/integrated/test-interchange-instability/2fluid.cxx +++ b/tests/integrated/test-interchange-instability/2fluid.cxx @@ -34,7 +34,7 @@ class Interchange : public PhysicsModel { Coordinates* coord; - TokamakOptions tokamak_options = TokamakOptions(*mesh); + bout::TokamakOptions tokamak_options = bout::TokamakOptions(*mesh); protected: int init(bool UNUSED(restarting)) override { diff --git a/tests/integrated/test-laplacexy/loadmetric.cxx b/tests/integrated/test-laplacexy/loadmetric.cxx index 979fd10031..a3e01acde8 100644 --- a/tests/integrated/test-laplacexy/loadmetric.cxx +++ b/tests/integrated/test-laplacexy/loadmetric.cxx @@ -28,6 +28,6 @@ void LoadMetric(BoutReal Lnorm, BoutReal Bnorm) { shearFactor = 0.0; // I disappears from metric } - auto tokamak_options = TokamakOptions(*mesh); + auto tokamak_options = bout::TokamakOptions(*mesh); set_tokamak_coordinates_on_mesh(tokamak_options, *mesh, Lnorm, Bnorm, shearFactor); } From 10c1abe2e3a7e762149844a3c26fb119b651c9f1 Mon Sep 17 00:00:00 2001 From: tomc271 Date: Tue, 18 Mar 2025 14:12:27 +0000 Subject: [PATCH 98/98] Also move implementation of normalise() method to cxx file --- include/bout/tokamak_coordinates.hxx | 10 +--------- src/mesh/tokamak_coordinates.cxx | 10 ++++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/bout/tokamak_coordinates.hxx b/include/bout/tokamak_coordinates.hxx index 0f08436162..f13e718787 100644 --- a/include/bout/tokamak_coordinates.hxx +++ b/include/bout/tokamak_coordinates.hxx @@ -22,15 +22,7 @@ namespace bout { TokamakOptions(Mesh &mesh); - void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { - Rxy /= Lbar; - Bpxy /= Bbar; - Btxy /= Bbar; - Bxy /= Bbar; - hthe /= Lbar; - I *= Lbar * Lbar * Bbar * ShearFactor; - dx /= Lbar * Lbar * Bbar; - } + void normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor); }; BoutReal get_sign_of_bp(const Field2D &Bpxy); diff --git a/src/mesh/tokamak_coordinates.cxx b/src/mesh/tokamak_coordinates.cxx index fcc250747c..e5a7636b7d 100644 --- a/src/mesh/tokamak_coordinates.cxx +++ b/src/mesh/tokamak_coordinates.cxx @@ -28,6 +28,16 @@ namespace bout { } } + void TokamakOptions::normalise(BoutReal Lbar, BoutReal Bbar, BoutReal ShearFactor) { + Rxy /= Lbar; + Bpxy /= Bbar; + Btxy /= Bbar; + Bxy /= Bbar; + hthe /= Lbar; + I *= Lbar * Lbar * Bbar * ShearFactor; + dx /= Lbar * Lbar * Bbar; + } + void set_tokamak_coordinates_on_mesh(TokamakOptions &tokamak_options, Mesh &mesh, BoutReal Lbar, BoutReal Bbar, BoutReal