Peano
Loading...
Searching...
No Matches
InsertParticlesFromHDF5File.py
Go to the documentation of this file.
1# This file is part of the Peano project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from peano4.solversteps.ActionSet import ActionSet
4
5import jinja2
6
8
10
11import numpy as np
12
13
15 def __init__(self, particle_set, filename):
16 """!
17
18 Read position from HDF5 and insert particles
19
20
21 Read an HDF5 file and insert particles into the simulation box. This is
22 typically used to read an Initial Condition file.
23
24 particle_set: ParticleSet
25
26 filename: String
27 Name of the HDF5 file that we want to read.
28
29 @TODO implement some bool checks, e.g. is this a cosmological simulation?
30 hydro scheme?
31
32 """
33 super(InsertParticlesFromHDF5File, self).__init__(
34 descend_invocation_order=1, parallel=False
35 )
36
37 self.d = {}
38 self.d["PARTICLE"] = particle_set.particle_model.name
39 self.d["PARTICLES_CONTAINER"] = particle_set.name
40 self._filename = filename
41
42 __Template_TouchCellFirstTime = jinja2.Template(
43 """
44 // ----------------------------------------------------------------------------------
45 // Start of snippet template in python/swift2/input/InsertParticlesFromHDF5File.py
46 // ----------------------------------------------------------------------------------
47
48 if ( not marker.hasBeenRefined() and not marker.willBeRefined() ) {
49 tarch::multicore::Lock lock( _semaphore );
50
51 /*
52 * List of particles that overlap with the current cell.
53 */
54
55 using namespace ::swift2::kernels::legacy::kernelHydro; // for kernel_gamma
56
57 std::list< tarch::la::Vector<Dimensions,double> > coords = _fileReaderHDF5.getParticlesWithinVoxel( marker.x(), marker.h(), true );
58
59 /* Retrieve the rest of fields for same set of particles */
60 std::vector< tarch::la::Vector<Dimensions,double> > VelocityWithinVoxel = _fileReaderHDF5.getVelocityWithinVoxel();
61 std::vector <double> MassWithinVoxel = _fileReaderHDF5.getMassWithinVoxel();
62 std::vector <double> SmoothingLengthWithinVoxel = _fileReaderHDF5.getSmoothingLengthWithinVoxel();
63 std::vector <double> InternalEnergyWithinVoxel = _fileReaderHDF5.getInternalEnergyWithinVoxel();
64 std::vector <int> PartidWithinVoxel = _fileReaderHDF5.getParticleIDsWithinVoxel();
65
66 int indexEntry = 0;
67 const double SmlMin = globaldata::{{PARTICLE}}::getSmlMin();
68 const double SmlMax = globaldata::{{PARTICLE}}::getSmlMax();
69
70
71 // Now loop over these particle coordinates
72 for (auto& p: coords) {
73
74 // Create a particle pointer
75 globaldata::{{PARTICLE}}* newParticle = new globaldata::{{PARTICLE}}();
76
77 // Initialise the particle with x=coords and SearchRadius=0
78 toolbox::particles::init(*newParticle, p, 0.0);
79 _particleNumberOnThisTree++;
80
81 /*
82 * Initialise the full set of particle attributes
83 */
84
85 tarch::la::Vector<Dimensions,double> Velocity;
86 /* Density is not encoded in all SWIFT HDF5 IC files as it is recomputed
87 by the density loop anyway. Here we just initialse to an arbitrary value */
88 double Density = 1.0;
89 double Mass = MassWithinVoxel[indexEntry];
90 double SmoothingLength = SmoothingLengthWithinVoxel[indexEntry];
91 double InternalEnergy = InternalEnergyWithinVoxel[indexEntry];
92 int ParticleID = PartidWithinVoxel[indexEntry];
93
94 if (SmoothingLength > SmlMax){
95 logWarning("InsertParticlesFromHDF5File.py",
96 "particle smoothing length > global smoothing length max;"
97 << " h= " << SmoothingLength << " h_max= " << SmlMax <<
98 "setting it to 0.9 * Max");
99 SmoothingLength = 0.9 * SmlMax;
100 }
101
102 /*
103 * Other attributes not set in HDF5 file
104 */
105
106 tarch::la::Vector<Dimensions,double> acceleration;
107
108 /* Compute the pressure from the EoS */
109 const double Pressure = ::swift2::kernels::legacy::eos::gas_pressure_from_internal_energy( Density, InternalEnergy );
110
111 /* Sound speed */
112 const double Soundspeed = ::swift2::kernels::legacy::eos::gas_soundspeed_from_internal_energy( InternalEnergy );
113
114 /* Now set the values */
115 newParticle->setV ( Velocity );
116 newParticle->setDensity ( Density );
117 newParticle->setMass ( Mass );
118 newParticle->setSmoothingLength( SmoothingLength );
119
120 newParticle->setSmlIterLeftBound(SmlMin);
121 newParticle->setSmlIterRightBound(SmlMax);
122
123 newParticle->setU ( InternalEnergy );
124
125 /*
126 * Initialize remaining fields
127 * @TODO some of these should be initialised elsewhere to keep this
128 * initialisation script general for any hydro scheme, etc.
129 * See swift2::kernels::legacy::first_init_particle()
130 */
131
132 /* Internal search radius used by Peano.
133 * We set the maximum allowed value, R = grid_size/2. */
134 tarch::la::Vector<Dimensions,double> GridSize = marker.h();
135 const double GridSize_x = GridSize(0);
136 const double searchRadiusGlobal = SmlMax * kernel_gamma;
137
138 if (tarch::la::greater(searchRadiusGlobal, 0.5 * GridSize_x)) {
139 std::ostringstream out;
140 out << " Global upper limit for search radius is > mesh size. You need to increase your cell size" <<
141 " or reduce hydro_h_max in your project python file." <<
142 " GridSize:" << GridSize_x <<
143 " max global search radius: " << searchRadiusGlobal;
144 logError("InsertParticlesFromHDF5File.py:", out.str());
145 }
146
147 newParticle->setSearchRadius( searchRadiusGlobal );
148
149 newParticle->setPressure ( Pressure );
150 newParticle->setSoundSpeed( Soundspeed );
151
152 // Vectors
153 for (int d=0; d<Dimensions; d++) {
154 newParticle->setA(d,0);
155#if Dimensions > 2
156 newParticle->setRot_v(d, 0);
157#endif
158 }
159
160#if Dimensions <= 2
161 /* For 2D sims, we only get one component */
162 newParticle->setRot_v(0);
163#endif
164
165 /* Initialise the "extended" arrays */
166 newParticle->setV_full( newParticle->getV() );
167 newParticle->setU_full( newParticle->getU() );
168
169 newParticle->setUDot (0.0);
170 newParticle->setHDot (0.0);
171 newParticle->setWcount(0.0);
172 newParticle->setF(0.0);
173 newParticle->setRho_dh(0.0);
174 newParticle->setWcount_dh(0.0);
175
176
177// newParticle->setTimeStepSize(GLOBAL_TIME_STEP_SIZE);
178 newParticle->setSmoothingLengthIterCount(0);
179
180 // Artificial viscosity scheme
181 newParticle->setDiv_v (0.0);
182 newParticle->setV_sig_AV(2.0 * newParticle->getSoundSpeed());
183 newParticle->setBalsara (0.0);
184
185 // Set particle id
186#if PeanoDebug > 0
187 newParticle->setPartid( ParticleID );
188#endif
189
190 /*
191 * All particle attributes for SPH have thus been set
192 */
193
194 indexEntry++;
195
196 toolbox::particles::insertParticleIntoCell(
197 marker,
198 newParticle,
199 fineGridVertices{{PARTICLE}}Set,
200 _spacetreeId
201 );
202 }
203
204 logDebug( "touchVertexFirstTime(...)", "assigned " << coords.size() << " particle(s) to vertex "
205 << marker.toString() << " on tree " << _spacetreeId );
206
207 }
208 // -----------------------------------------------------------------------------
209 // End of snippet template in python/swift2/input/InsertParticlesFromHDF5File.py
210 // -----------------------------------------------------------------------------
211"""
212 )
213
214 __Template_EndTraversal = jinja2.Template(
215 """
216 // -------------------------------------------------------------------------------
217 // Start of snippet template in python/swift2/input/InsertParticlesFromHDF5File.py
218 // -------------------------------------------------------------------------------
219
220 if (_particleNumberOnThisTree==0) {
221 logWarning( "endIteration()", "inserted " << _particleNumberOnThisTree << " particle(s) on tree " << _spacetreeId );
222 }
223 else {
224 logInfo( "endIteration()", "inserted " << _particleNumberOnThisTree << " particle(s) on tree " << _spacetreeId << " (boundary vertices might host redundant particle data)" );
225 }
226 #if !defined(Parallel) and !defined(SharedMemoryParallelisation)
227 assertion( _particleNumberOnThisTree>0 );
228 #endif
229
230 // -----------------------------------------------------------------------------
231 // End of snippet template in python/swift2/input/InsertParticlesFromHDF5File.py
232 // -----------------------------------------------------------------------------
233"""
234 )
235
236 def get_body_of_operation(self, operation_name):
237 result = "\n"
238 if operation_name == ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
239 result = self.__Template_TouchCellFirstTime.render(**self.d)
240 if operation_name == ActionSet.OPERATION_END_TRAVERSAL:
241 result = self.__Template_EndTraversal.render(**self.d)
242 return result
243
245 return " return std::vector< peano4::grid::GridControlEvent >();\n"
246
248 return __name__.replace(".py", "").replace(".", "_")
249
251 return False
252
253 def get_includes(self):
254 result = jinja2.Template(
255 """
256#include "tarch/multicore/multicore.h"
257#include "tarch/multicore/Lock.h"
258#include "vertexdata/{{PARTICLES_CONTAINER}}.h"
259#include "globaldata/{{PARTICLE}}.h"
260#include "toolbox/particles/particles.h"
261#include "toolbox/particles/FileReaderHDF5.h"
262#include "toolbox/particles/ParticleFactory.h"
263
264#include "Constants.h"
265
266#include "swift2/kernels/legacy/kernel_hydro.h"
267#include "swift2/kernels/legacy/equation_of_state.h"
268
269#include <fstream>
270#include <string>
271#include <vector>
272"""
273 )
274 return result.render(**self.d)
275
276 def get_static_initialisations(self, full_qualified_classname):
277 return (
278 """
279tarch::multicore::BooleanSemaphore """
280 + full_qualified_classname
281 + """::_semaphore;
282toolbox::particles::FileReaderHDF5 """
283 + full_qualified_classname
284 + """::_fileReaderHDF5;
285"""
286 )
287
289 return (
290 """
291 _particleNumberOnThisTree = 0;
292 _spacetreeId = treeNumber;
293
294 tarch::multicore::Lock lock( _semaphore );
295
296 if ( _fileReaderHDF5.empty() )
297 _fileReaderHDF5.readHDF5File( \""""
298 + self._filename
299 + """\" );
300"""
301 )
302
303 def get_attributes(self):
304 return """
305 static tarch::multicore::BooleanSemaphore _semaphore;
306
307 int _particleNumberOnThisTree;
308 int _spacetreeId;
309 static toolbox::particles::FileReaderHDF5 _fileReaderHDF5;
310"""
Default superclass for any data model in Peano which is stored within the grid.
Definition DaStGen2.py:47
Action set (reactions to events)
Definition ActionSet.py:6
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
__init__(self, particle_set, filename)
Read position from HDF5 and insert particles.
get_attributes(self)
Return attributes as copied and pasted into the generated class.