Skip to content

Commit 6c69d6a

Browse files
committed
Add optional boolean parameter communicate to Coordinates setters and MetricTensor inverse() method
Add method Coordinates::communicateMetricTensor() and call after constructing Coordinates to avoid circular dependency (between Mesh and Coordinates) as a result of the setter methods calling communicate()
1 parent 15cffda commit 6c69d6a

5 files changed

Lines changed: 64 additions & 33 deletions

File tree

include/bout/coordinates.hxx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ public:
108108
const BoutReal& J(int x, int y) const { return J()(x, y); }
109109
#endif
110110

111-
void setDx(FieldMetric dx);
112-
void setDy(FieldMetric dy);
113-
void setDz(FieldMetric dz);
111+
void setDx(FieldMetric dx, const bool communicate = true);
112+
void setDy(FieldMetric dy, const bool communicate = true);
113+
void setDz(FieldMetric dz, const bool communicate = true);
114114

115115
void setD1_dx(FieldMetric d1_dx) { d1_dx_ = std::move(d1_dx); }
116116
void setD1_dy(FieldMetric d1_dy) { d1_dy_ = std::move(d1_dy); }
@@ -235,15 +235,17 @@ public:
235235
void setMetricTensor(const ContravariantMetricTensor& contravariant_metric_tensor,
236236
const CovariantMetricTensor& covariant_metric_tensor);
237237

238+
void communicateMetricTensor();
239+
238240
///< Coordinate system Jacobian, so volume of cell is J*dx*dy*dz
239241
FieldMetric& J() const;
240242

241243
///< Magnitude of B = nabla z times nabla x
242244
const FieldMetric& Bxy() const { return Bxy_; }
243245

244-
void setJ(const FieldMetric& J);
246+
void setJ(const FieldMetric& J, const bool communicate = true);
245247

246-
void setBxy(FieldMetric Bxy);
248+
void setBxy(FieldMetric Bxy, const bool communicate = true);
247249

248250
/// d pitch angle / dx. Needed for vector differentials (Curl)
249251
const FieldMetric& ShiftTorsion() const { return ShiftTorsion_; }

include/bout/mesh.hxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,8 @@ public:
653653
inserted.first->second->recalculateAndReset(recalculate_staggered,
654654
force_interpolate_from_centre);
655655

656+
inserted.first->second->communicateMetricTensor();
657+
656658
return inserted.first->second;
657659
}
658660

include/bout/metric_tensor.hxx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public:
6161
g23_m = metric_tensor.g23();
6262
}
6363

64-
MetricTensor inverse(const std::string& region = "RGN_ALL");
64+
MetricTensor inverse(const std::string& region = "RGN_ALL", const bool communicate = true);
6565

6666
// Transforms the MetricTensor by applying the given function to every component
6767
template <class F>
@@ -74,8 +74,11 @@ public:
7474
g23_m = function(g23_m);
7575
}
7676

77+
void communicate() const;
78+
7779
private:
7880
FieldMetric g11_m, g22_m, g33_m, g12_m, g13_m, g23_m;
81+
7982
};
8083

8184
class CovariantMetricTensor : public MetricTensor {

src/mesh/coordinates.cxx

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,9 @@ void Coordinates::interpolateFromCoordinates(Options* mesh_options,
501501
checkCovariant();
502502

503503
setJ(interpolateAndExtrapolate(coords_in->J(), location, true, true, false,
504-
transform.get()));
504+
transform.get()), false);
505505
setBxy(interpolateAndExtrapolate(coords_in->Bxy(), location, true, true, false,
506-
transform.get()));
506+
transform.get()), false);
507507

508508
bout::checkFinite(J(), "The Jacobian", "RGN_NOCORNERS");
509509
bout::checkPositive(J(), "The Jacobian", "RGN_NOCORNERS");
@@ -567,9 +567,9 @@ void Coordinates::readFromMesh(Options* mesh_options, const std::string& suffix)
567567
dy_ = interpolateAndExtrapolate(dy_, location, extrapolate_x, extrapolate_y, false,
568568
transform.get());
569569

570-
setDx(dx_);
571-
setDy(dy_);
572-
setDz(dz_);
570+
setDx(dx_, false);
571+
setDy(dy_, false);
572+
setDz(dz_, false);
573573

574574
// grid data source has staggered fields, so read instead of interpolating
575575
// Diagonal components of metric tensor g^{ij} (default to 1)
@@ -618,7 +618,7 @@ void Coordinates::readFromMesh(Options* mesh_options, const std::string& suffix)
618618
output_warn.write("\tWARNING! Covariant components of metric tensor set manually. "
619619
"Contravariant components NOT recalculated\n");
620620
} else {
621-
covariantMetricTensor.setMetricTensor(contravariantMetricTensor.inverse());
621+
covariantMetricTensor.setMetricTensor(contravariantMetricTensor.inverse("RGN_ALL", false));
622622
output_warn.write("Not all covariant components of metric tensor found. "
623623
"Calculating all from the contravariant tensor\n");
624624
}
@@ -639,15 +639,15 @@ void Coordinates::readFromMesh(Options* mesh_options, const std::string& suffix)
639639
const auto J_from_file = getAtLoc(localmesh, "J", suffix, location);
640640
// Compare calculated and loaded values
641641
output_warn.write("\tMaximum difference in J is {:e}\n", max(abs(J() - J_from_file)));
642-
setJ(J_from_file);
642+
setJ(J_from_file, false);
643643

644644
communicate(J());
645645
}
646646

647647
// More robust to extrapolate derived quantities directly, rather than
648648
// deriving from extrapolated covariant metric components
649649
setJ(interpolateAndExtrapolate(J(), location, extrapolate_x, extrapolate_y, false,
650-
transform.get()));
650+
transform.get()), false);
651651

652652
// Check jacobian
653653
bout::checkFinite(J(), "J" + suffix, "RGN_NOCORNERS");
@@ -662,15 +662,15 @@ void Coordinates::readFromMesh(Options* mesh_options, const std::string& suffix)
662662
"Calculating from metric tensor\n",
663663
suffix);
664664
// Re-evaluate Bxy using new J
665-
setBxy(recalculateBxy());
665+
setBxy(recalculateBxy(), false);
666666
} else {
667667
const auto Bcalc = getAtLoc(localmesh, "Bxy", suffix, location);
668-
setBxy(Bcalc);
668+
setBxy(Bcalc, false);
669669
output_warn.write("\tMaximum difference in Bxy is {:e}\n", max(abs(Bxy() - Bcalc)));
670670
}
671671

672672
setBxy(interpolateAndExtrapolate(Bxy(), location, extrapolate_x, extrapolate_y, false,
673-
transform.get()));
673+
transform.get()), false);
674674

675675
// Check Bxy
676676
bout::checkFinite(Bxy(), "Bxy" + suffix, "RGN_NOCORNERS");
@@ -762,31 +762,34 @@ const Field2D& Coordinates::zlength() const {
762762
return *zlength_cache;
763763
}
764764

765-
void Coordinates::setDx(FieldMetric dx) {
765+
void Coordinates::setDx(FieldMetric dx, const bool communicate) {
766766
if (min(abs(dx)) < 1e-8) {
767767
throw BoutException("dx magnitude less than 1e-8");
768768
}
769-
770769
dx_ = std::move(dx);
771-
localmesh->communicate(dx_);
770+
if (communicate) {
771+
localmesh->communicate(dx_);
772+
}
772773
}
773774

774-
void Coordinates::setDy(FieldMetric dy) {
775+
void Coordinates::setDy(FieldMetric dy, const bool communicate) {
775776
if (min(abs(dy)) < 1e-8) {
776777
throw BoutException("dy magnitude less than 1e-8");
777778
}
778-
779779
dy_ = std::move(dy);
780-
localmesh->communicate(dy_);
780+
if (communicate) {
781+
localmesh->communicate(dy_);
782+
}
781783
}
782784

783-
void Coordinates::setDz(FieldMetric dz) {
785+
void Coordinates::setDz(FieldMetric dz, const bool communicate) {
784786
if (min(abs(dz)) < 1e-8) {
785787
throw BoutException("dz magnitude less than 1e-8");
786788
}
787-
788789
dz_ = std::move(dz);
789-
localmesh->communicate(dz_);
790+
if (communicate) {
791+
localmesh->communicate(dz_);
792+
}
790793
}
791794

792795
void Coordinates::recalculateAndReset(bool recalculate_staggered,
@@ -1491,19 +1494,23 @@ FieldMetric& Coordinates::J() const {
14911494
return *jacobian_cache;
14921495
}
14931496

1494-
void Coordinates::setJ(const FieldMetric& J) {
1497+
void Coordinates::setJ(const FieldMetric& J, const bool communicate) {
14951498
bout::checkFinite(J, "J", "RGN_NOCORNERS");
14961499
bout::checkPositive(J, "J", "RGN_NOCORNERS");
14971500

14981501
//TODO: Calculate J and check value is close
14991502
jacobian_cache = std::make_unique<FieldMetric>(J);
1500-
localmesh->communicate(*jacobian_cache);
1503+
if (communicate) {
1504+
localmesh->communicate(*jacobian_cache);
1505+
}
15011506
}
15021507

1503-
void Coordinates::setBxy(FieldMetric Bxy) {
1508+
void Coordinates::setBxy(FieldMetric Bxy, const bool communicate) {
15041509
//TODO: Calculate Bxy and check value is close
15051510
Bxy_ = std::move(Bxy);
1506-
localmesh->communicate(Bxy_);
1511+
if (communicate) {
1512+
localmesh->communicate(Bxy_);
1513+
}
15071514
}
15081515

15091516
void Coordinates::setContravariantMetricTensor(
@@ -1529,3 +1536,8 @@ void Coordinates::setMetricTensor(
15291536
contravariantMetricTensor.setMetricTensor(contravariant_metric_tensor);
15301537
covariantMetricTensor.setMetricTensor(covariant_metric_tensor);
15311538
}
1539+
1540+
void Coordinates::communicateMetricTensor() {
1541+
contravariantMetricTensor.communicate();
1542+
covariantMetricTensor.communicate();
1543+
}

src/mesh/metric_tensor.cxx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void MetricTensor::check(int ystart) {
7272
}
7373
}
7474

75-
MetricTensor MetricTensor::inverse(const std::string& region) {
75+
MetricTensor MetricTensor::inverse(const std::string& region, const bool communicate) {
7676

7777
TRACE("MetricTensor::inverse");
7878

@@ -124,7 +124,19 @@ MetricTensor MetricTensor::inverse(const std::string& region) {
124124

125125
output_info.write("\tMaximum error in off-diagonal inversion is {:e}\n",
126126
off_diagonal_maxerr);
127-
128-
g_11.getMesh()->communicate(g_11, g_22, g_33, g_12, g_13, g_23);
127+
if (communicate) {
128+
MetricTensor::communicate();
129+
}
129130
return MetricTensor(g_11, g_22, g_33, g_12, g_13, g_23);
130131
}
132+
133+
void MetricTensor::communicate() const {
134+
// copy to non-const variables (because communicate() cannot take const references)
135+
auto tmp = g11_m;
136+
auto tmp2 = g22_m;
137+
auto tmp3 = g33_m;
138+
auto tmp4 = g12_m;
139+
auto tmp5 = g13_m;
140+
auto tmp6 = g23_m;
141+
g11_m.getMesh()->communicate(tmp, tmp2, tmp3, tmp4, tmp5, tmp6);
142+
}

0 commit comments

Comments
 (0)