11/*
2- * MIT License
2+ * SPH-EXA
33 *
4- * Copyright (c) 2021 CSCS, ETH Zurich
5- * 2021 University of Basel
4+ * Copyright (c) 2026 CSCS, ETH Zurich, University of Zurich, University of Basel
65 *
7- * Permission is hereby granted, free of charge, to any person obtaining a copy
8- * of this software and associated documentation files (the "Software"), to deal
9- * in the Software without restriction, including without limitation the rights
10- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11- * copies of the Software, and to permit persons to whom the Software is
12- * furnished to do so, subject to the following conditions:
13- *
14- * The above copyright notice and this permission notice shall be included in all
15- * copies or substantial portions of the Software.
16- *
17- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23- * SOFTWARE.
6+ * Please, refer to the LICENSE file in the root directory.
7+ * SPDX-License-Identifier: MIT License
248 */
259
2610/* ! @file
3418#include < map>
3519
3620#include " cstone/primitives/primitives_acc.hpp"
37- #include " cstone/sfc/box.hpp"
3821#include " cstone/tree/continuum.hpp"
39- #include " sph/eos.hpp"
4022
41- #include " isim_init.hpp"
42- #include " early_sync.hpp"
43- #include " grid.hpp"
44- #include " utils.hpp"
23+ #include " radial_profile.hpp"
4524
4625namespace sphexa
4726{
4827
49- std::map<std::string, double > evrardConstants ()
28+ InitSettings evrardConstants ()
5029{
5130 return {{" gravConstant" , 1 .}, {" r" , 1 .}, {" mTotal" , 1 .}, {" gamma" , 5 . / 3 .}, {" u0" , 0.05 },
5231 {" minDt" , 1e-4 }, {" minDt_m1" , 1e-4 }, {" mui" , 10 }, {" ng0" , 100 }, {" ngmax" , 150 }};
@@ -101,22 +80,6 @@ void initEvrardFields(Dataset& d, const std::map<std::string, double>& constants
10180 d.h = std::move (h);
10281}
10382
104- template <class Vector >
105- void contractRhoProfile (Vector& x, Vector& y, Vector& z)
106- {
107- #pragma omp parallel for schedule(static)
108- for (size_t i = 0 ; i < x.size (); i++)
109- {
110- auto radius0 = std::sqrt (x[i] * x[i] + y[i] * y[i] + z[i] * z[i]);
111-
112- // multiply coordinates by sqrt(r) to generate a density profile ~ 1/r
113- auto contraction = std::sqrt (radius0);
114- x[i] *= contraction;
115- y[i] *= contraction;
116- z[i] *= contraction;
117- }
118- }
119-
12083// ! @brief Estimate SFC partition of the Evrard sphere based on approximate continuum particle counts
12184template <class KeyType , class T >
12285std::tuple<KeyType, KeyType> estimateEvrardSfcPartition (size_t cbrtNumPart, const cstone::Box<T>& box, int rank,
@@ -142,74 +105,25 @@ std::tuple<KeyType, KeyType> estimateEvrardSfcPartition(size_t cbrtNumPart, cons
142105}
143106
144107template <class Dataset >
145- class EvrardGlassSphere : public ISimInitializer <Dataset>
108+ class EvrardGlassSphere : public RadialProfile <Dataset>
146109{
147- std::string glassBlock ;
148- mutable InitSettings settings_;
110+ using Base = RadialProfile<Dataset> ;
111+ using Base:: settings_;
149112
150113public:
151114 explicit EvrardGlassSphere (std::string initBlock, std::string settingsFile, IFileReader* reader)
152- : glassBlock (std::move(initBlock))
115+ : Base (std::move(initBlock), evrardConstants(), std::move(settingsFile), reader )
153116 {
154- Dataset d;
155- settings_ = buildSettings (d, evrardConstants (), settingsFile, reader);
156117 }
157118
158119 cstone::Box<typename Dataset::RealType> init (int rank, int numRanks, size_t cbrtNumPart, Dataset& simData,
159120 IFileReader* reader) const override
160121 {
161- auto & d = simData.hydro ;
162- using KeyType = typename Dataset::KeyType;
163- using T = typename Dataset::RealType;
164-
165- std::vector<T> xBlock, yBlock, zBlock;
166- readTemplateBlock (glassBlock, reader, xBlock, yBlock, zBlock);
167- size_t blockSize = xBlock.size ();
168-
169- int multi1D = std::rint (cbrtNumPart / std::cbrt (blockSize));
170- cstone::Vec3<int > multiplicity = {multi1D, multi1D, multi1D};
171-
172- T r = settings_.at (" r" );
173- cstone::Box<T> globalBox (-r, r, cstone::BoundaryType::open);
174-
175- auto [keyStart, keyEnd] = equiDistantSfcSegments<KeyType>(rank, numRanks, 100 );
176-
177- std::vector<T> x, y, z;
178- auto t0 = std::chrono::high_resolution_clock::now ();
179- assembleCuboid<T>(keyStart, keyEnd, globalBox, multiplicity, xBlock, yBlock, zBlock, x, y, z);
180- cutSphere (r, x, y, z);
181- auto t1 = std::chrono::high_resolution_clock::now ();
182- if (rank == 0 ) std::cout << " assembly " << std::chrono::duration<float >(t1 - t0).count () << std::endl;
183-
184- size_t numParticlesGlobal = x.size ();
185- MPI_Allreduce (MPI_IN_PLACE , &numParticlesGlobal, 1 , MpiType<size_t >{}, MPI_SUM , simData.comm );
186-
187- contractRhoProfile (x, y, z);
188-
189- t0 = std::chrono::high_resolution_clock::now ();
190- d.x = x; // uploads to GPU if active
191- d.y = y;
192- d.z = z;
193- syncCoords<KeyType>(rank, numRanks, numParticlesGlobal, d.x , d.y , d.z , globalBox);
194- // 2nd call needed to reduce imbalance, 1st call is not able to fully balance number of particles per rank
195- syncCoords<KeyType>(rank, numRanks, numParticlesGlobal, d.x , d.y , d.z , globalBox);
196- t1 = std::chrono::high_resolution_clock::now ();
197- if (rank == 0 ) std::cout << " earlySync " << std::chrono::duration<float >(t1 - t0).count () << std::endl;
198-
199- d.resize (d.x .size ());
200-
201- settings_[" numParticlesGlobal" ] = double (numParticlesGlobal);
202- BuiltinWriter attributeSetter (settings_);
203- d.loadOrStoreAttributes (&attributeSetter);
204-
205- initEvrardFields (d, settings_);
206-
122+ auto radialTransform = [](auto r) { return std::sqrt (r); };
123+ auto globalBox = Base::init (rank, numRanks, cbrtNumPart, simData, reader, settings_.at (" r" ), radialTransform);
124+ initEvrardFields (simData.hydro , settings_);
207125 return globalBox;
208126 }
209-
210- void resetConstants (InitSettings newSettings) { settings_ = std::move (newSettings); }
211-
212- [[nodiscard]] const InitSettings& constants () const override { return settings_; }
213127};
214128
215129} // namespace sphexa
0 commit comments