diff --git a/.gitignore b/.gitignore index 807374fd7..45fc49f1e 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,18 @@ doc/manual/build doc/manual/source/_build run/results.js + +amr.out +performance.out +OutputLog +Evtime +Enzo_Build +OutputLevelInformation.out +RunFinished +DD0000/ +DD0001/ +AccelerationField.out* +TestGravityCheckResults.out* +01.out +nosetests.xml +run/**/*.png \ No newline at end of file diff --git a/README.md b/README.md index c8f1b26e8..95470ad28 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ support for Enzo Many people have contributed to the development of Enzo -- here's just a short list of the people who have recently contributed, in alphabetical order: - + * Tom Abel tabel@stanford.edu * Gabriel Altay gabriel.altay@gmail.com * James Bordner jobordner@ucsd.edu @@ -68,7 +68,7 @@ list of the people who have recently contributed, in alphabetical order: * Andrew Emerick aemerick11@gmail.com * Forrest Glines forrestglines@gmail.com * Nathan Goldbaum ngoldbau@ucsc.edu - * Philipp Grete grete@pa.msu.edu + * Philipp Grete grete@pa.msu.edu * John Forbes jcforbes@ucsc.edu * Yusuke Fujimoto yusuke.fujimoto.jp@gmail.com * Oliver Hahn hahn@phys.ethz.ch @@ -94,6 +94,7 @@ list of the people who have recently contributed, in alphabetical order: * Boon Kiat Oh bkoh@roe.ac.uk * Brian O'Shea oshea@msu.edu * Pascal Paschos ppaschos@minbari.ucsd.edu + * Jean-Claude Passy jcpassy@gmail.com * Molly Peeples molly@stsci.edu * Carolyn Peruta perutaca@msu.edu * John Regan johnanthonyregan@gmail.com @@ -102,7 +103,7 @@ list of the people who have recently contributed, in alphabetical order: * Munier Salem msalem@astro.columbia.edu * Devin Silvia devin.silvia@gmail.com * Christine Simpson csimpson@astro.columbia.edu - * Samuel Skillman samskillman@gmail.com + * Samuel Skillman samskillman@gmail.com * Stephen Skory s@skory.us * Britton Smith brittonsmith@gmail.com * Geoffrey So gsiisg@gmail.com @@ -114,5 +115,5 @@ list of the people who have recently contributed, in alphabetical order: * Peng Wang penwang@nvidia.com * John Wise jwise@physics.gatech.edu * Hao Xu haoxu.physics@gmail.com - * Alvaro Zamora alvarozamora@stanford.edu + * Alvaro Zamora alvarozamora@stanford.edu * Fen Zhao fenzhao@stanford.edu diff --git a/doc/manual/source/parameters/index.rst b/doc/manual/source/parameters/index.rst index a0aedf421..5317262c8 100644 --- a/doc/manual/source/parameters/index.rst +++ b/doc/manual/source/parameters/index.rst @@ -41,59 +41,61 @@ common convention of 0 meaning false or off and 1 for true or on. * `Initialization Parameters`_ -* `I/O Parameters`_ - - * `General I/O Parameters`_ - +* `I/O Parameters`_ + + * `General I/O Parameters`_ + * `Stopping Parameters`_ - + * `Streaming Data Format`_ - + * `Simulation Identifiers and UUIDs`_ * `Hierarchy Control Parameters`_ * `Gravity Parameters`_ - + * `General Gravity Parameters`_ - + + * `APM Gravity Parameters`_ + * `External Gravity Source`_ * `Hydrodynamics Parameters`_ - + * `General Hydrodynamics Parameters`_ - + * `Minimum Pressure Support Parameters`_ - + * `Magnetohydrodynamics (CT) Parameters`_ - + * `Magnetohydrodynamics (Dedner) Parameters`_ * `Cooling Parameters`_ - + * `Simple Cooling Options`_ - + * `Cloudy Cooling`_ - + * `The Grackle`_ * `Particle Parameters`_ * `Star Formation and Feedback Parameters`_ - + * `General Star Formation`_ - + * `Normal Star Formation`_ - + * `Molecular Hydrogen Regulated Star Formation`_ - + * `Population III Star Formation`_ - + * `Radiative Star Cluster Formation`_ - + * `Massive Black Hole Particle Formation`_ - + * `Sink Formation and Feedback`_ * `Magnetic Supernova Feedback`_ @@ -101,23 +103,23 @@ common convention of 0 meaning false or off and 1 for true or on. * `Active Particles`_ * `Radiation Parameters`_ - + * `Background Radiation Parameters`_ - + * `Radiative Transfer (Ray Tracing) Parameters`_ - + * `Radiative Transfer (FLD) Parameters`_ - + * `Radiative Transfer (FLD) Implicit Solver Parameters`_ - + * `Radiative Transfer (FLD) Split Solver Parameters`_ * `Cosmology Parameters`_ * `Massive Black Hole Physics Parameters`_ - + * `Accretion Physics`_ - + * `Feedback Physics`_ * `Shock Finding Parameters`_ @@ -131,15 +133,15 @@ common convention of 0 meaning false or off and 1 for true or on. * `Fuzzy Dark matter model`_ * `Inline Analysis`_ - + * `Inline Halo Finding`_ - + * `Inline Python`_ * `Other Parameters`_ - + * `Other External Parameters`_ - + * `Other Internal Parameters`_ * `Problem Type Parameters`_ @@ -171,7 +173,7 @@ common convention of 0 meaning false or off and 1 for true or on. * `Rotating Sphere (14)`_ * `Radiating Shock (11)`_ - + * `Free Expansion (12)`_ * `Rotating Sphere (14)`_ @@ -307,14 +309,14 @@ Initialization Parameters none ``StoreDomainBoundaryMassFlux`` (external) When turned on, this stores the cumulative mass (in solar masses) - of density fields (density, species fields, metallicity) that + of density fields (density, species fields, metallicity) that outflows from the simulation domain. This is stored directly in the output parameter files as the ``BoundaryMassFluxFieldNumbers`` and ``BoundaryMassFluxContainer`` parameters, as well as the cycle-by-cycle mass outflow in ``BoundaryMassFluxFilename``. Default : 0 (off) ``BoundaryMassFluxFilename`` (external) - The filename to output the cycle-by-cyle mass outflow from the + The filename to output the cycle-by-cyle mass outflow from the grid domain when the above parameter is ON. Default : 'boundary_mass_flux.dat' ``InitialTime`` (internal) The time, in code units, of the current step. For cosmology the @@ -389,7 +391,7 @@ I/O Parameters .. _general_io_parameters: -General I/O Parameters +General I/O Parameters ^^^^^^^^^^^^^^^^^^^^^^ There are three ways to specify the frequency of outputs: @@ -428,10 +430,10 @@ have a look at :ref:`controlling_data_output` for more information. becomes 0124). Default: RedshiftOutput ``TracerParticleDumpName`` (external) The base file name used for tracer particle outputs. - Default: + Default: ``TracerParticleDumpDir`` (external) The dir name used for tracer particle outputs. - Default: + Default: ``dtRestartDump`` Reserved for future use. ``dtHistoryDump`` @@ -486,8 +488,8 @@ have a look at :ref:`controlling_data_output` for more information. root grid. More I/O is required (to split up the grids and particles), but it is more balanced in terms of memory. ``ParallelRootGridIO`` and ``ParallelParticleIO`` MUST be set to 1 (TRUE) - for runs involving > 64 cpus! Default: 0 (FALSE). - See ``ParallelParticleIO`` in :ref:`particle_parameters`. + for runs involving > 64 cpus! Default: 0 (FALSE). + See ``ParallelParticleIO`` in :ref:`particle_parameters`. See also ``Unigrid`` in :ref:`initialization_parameters`. ``OutputTemperature`` (external) Set to 1 if you want to output a temperature field in the datasets. @@ -527,7 +529,7 @@ have a look at :ref:`controlling_data_output` for more information. ``WritePotential`` (external) When turned on, the gravitational potential is written to file. Default: 0 ``WriteGhostZones`` (external) - Should ghost zones be written to disk? Default: 0 + Should ghost zones be written to disk? Default: 0 ``ReadGhostZones`` (external) Are ghost zones present in the files on disk? Default: 0 ``VelAnyl`` (external) @@ -550,13 +552,13 @@ have a look at :ref:`controlling_data_output` for more information. integrated emissivity along the line of sight in units of 10\ :sup:`-23` erg/cm\ :sup:`2`/s. Default: ``XrayLowerCutoffkeV = 0.5``, ``XrayUpperCutoffkeV = 2.5``. -``ParticleTypeInFile`` (external) +``ParticleTypeInFile`` (external) Output ParticleType to disk? Default: 1 -``OutputParticleTypeGrouping`` (external) +``OutputParticleTypeGrouping`` (external) In the grid HDF5 groups, particles are sorted by type, and a reference is created to indicate which particle index range corresponds to each type. Default: 0 -``HierarchyFileInputFormat`` (external) +``HierarchyFileInputFormat`` (external) See :ref:`controlling_the_hierarhcy_file_output`. -``HierarchyFileOutputFormat`` (external) +``HierarchyFileOutputFormat`` (external) See :ref:`controlling_the_hierarhcy_file_output`. ``TimingCycleSkip`` (external) Controls how many cycles to skip when timing information is collected, reduced, and written out to performance.out. Default: 1 @@ -566,9 +568,9 @@ have a look at :ref:`controlling_data_output` for more information. not recommended for use at this point. Default: 0 ``CubeDump[]`` (external) not recommended for use at this point -``LocalDir`` (external) +``LocalDir`` (external) See :ref:`controlling_data_output`. -``GlobalDir`` (external) +``GlobalDir`` (external) See :ref:`controlling_data_output`. .. _stopping_parameters: @@ -601,7 +603,7 @@ Stopping Parameters See ``StopFirstTimeAtMetalEnrichedDensity``. In units of absolute metal fraction. Default: 1e-8 ``NumberOfOutputsBeforeExit`` (external) - After this many datadumps have been written, the code will exit. If + After this many datadumps have been written, the code will exit. If set to 0 (default), this option will not be used. Default: 0. ``StopCPUTime`` (external) Causes the simulation to stop if the wall time exceeds ``StopCPUTime``. @@ -826,7 +828,7 @@ Hierarchy Control Parameters If ``CellFlaggingMethod`` is 1, and you only want to refine on the slopes of certain fields then you can enter the :ref:`Field Type IDs ` of the fields you want, - separating the IDs with a space. Up to 7 Field Type IDs can be + separating the IDs with a space. Up to 7 Field Type IDs can be specified. Default: Refine on slopes of all fields. ``MinimumSlopeForRefinement`` (external) If ``CellFlaggingMethod`` is 1, then local gradients are used as the @@ -850,11 +852,11 @@ Hierarchy Control Parameters ``MinimumShearForRefinement`` (external) It is the minimum shear above which a refinement occurs if the CellFlaggingMethod is appropriately set. Default: 0 ``OldShearMethod`` (external) - If using the shear refinement criterion, setting this variable to 1 enables - the old method for calculating the shear criterion, which actually + If using the shear refinement criterion, setting this variable to 1 enables + the old method for calculating the shear criterion, which actually calculates it based on shear and vorticity and makes some assumptions about the simulations (c_s=1, etc.). However, this is necessary - if you want to reproduce some of the old enzo results + if you want to reproduce some of the old enzo results (e.g. Kritsuk et al. 2006). Default: 0 ``MetallicityRefinementMinMetallicity`` (external) For method 13 (metallicity refinement), this is the threshold @@ -908,19 +910,19 @@ Hierarchy Control Parameters the magnitude of the magnetic field. We make sure this length is covered by this number of cells. i.w. The resistive length in a MHD simulation should not be smaller than CellWidth * RefineByResistiveLengthSafetyFactor. Default: 2.0 ``MustRefineParticlesCreateParticles`` (external) - This parameter will flag dark matter particles in cosmological - initial conditions as ``MustRefineParticles``. If ``CellFlaggingMethod`` - 8 is set, AMR will be restricted to cells surrounding + This parameter will flag dark matter particles in cosmological + initial conditions as ``MustRefineParticles``. If ``CellFlaggingMethod`` + 8 is set, AMR will be restricted to cells surrounding ``MustRefineParticles``. There are several different modes for creating - ``MustRefineParticles`` with this parameter described below. Further - information on how to use dark matter ``MustRefineParticles`` in + ``MustRefineParticles`` with this parameter described below. Further + information on how to use dark matter ``MustRefineParticles`` in cosmological simulations can be found here (link). Default: 0 - 1. If the user specifies ``MustRefineParticlesLeftEdge`` and - ``MustRefineParticlesRightEdge``, dark matter particles within the - specified region are flagged. Otherwise, the code looks for an ascii + 1. If the user specifies ``MustRefineParticlesLeftEdge`` and + ``MustRefineParticlesRightEdge``, dark matter particles within the + specified region are flagged. Otherwise, the code looks for an ascii input file called MustRefineParticlesFlaggingList.in that contains a list - of particle ids to be flagged. The ids in this list must be sorted in + of particle ids to be flagged. The ids in this list must be sorted in ascending order. 2. For use with ellipsoidal masking in MUSIC initial conditions. This setting uses traditional static grids for intermediate resolution levels @@ -962,12 +964,12 @@ Hierarchy Control Parameters ``MustRefineParticlesMinimumMass`` (external) This was an experimental parameter to set a minimum for ``MustRefineParticles``. Default: 0.0 ``MustRefineParticlesRegionLeftEdge`` (external) - Bottom-left corner of a region in which dark matter particles are flagged - as ``MustRefineParticles`` in nested cosmological simulations. To be used with + Bottom-left corner of a region in which dark matter particles are flagged + as ``MustRefineParticles`` in nested cosmological simulations. To be used with ``MustRefineParticlesCreateParticles`` = 1. Default: 0.0 0.0 0.0 ``MustRefineParticlesRegionRightEdge`` (external) - Top-right corner of a region in which dark matter particles are flagged - as ``MustRefineParticles`` in nested cosmological simulations. To be used with + Top-right corner of a region in which dark matter particles are flagged + as ``MustRefineParticles`` in nested cosmological simulations. To be used with ``MustRefineParticlesCreateParticles`` = 1. Default: 0.0 0.0 0.0 ``MustRefineRegionMinRefinementLevel`` (external) Minimum level to which the rectangular solid volume defined by @@ -1004,7 +1006,7 @@ Hierarchy Control Parameters might be two lines from the text file when time is indexed by redshift: :: - + 2.05 0.493102 0.488106 0.501109 0.495102 0.490106 0.503109 10 2.00 0.493039 0.487908 0.501189 0.495039 0.489908 0.503189 10 @@ -1062,38 +1064,38 @@ Hierarchy Control Parameters This parameter is used to limit the refinement to this level in a rectangular region. Up to MAX_STATIC_REGIONS regions can be used. Default: IND_UNDEFINED -``AvoidRefineRegionLeftEdge[#]``, ``AvoidRefineRegionRightEdge[#]`` (external) +``AvoidRefineRegionLeftEdge[#]``, ``AvoidRefineRegionRightEdge[#]`` (external) These two parameters specify the two corners of a region that limits refinement to a certain level (see the previous parameter). Default: none ``MultiRefineRegionGeometry[#]`` (external) - This parameter (and the ones following) describe a physical region of the simulation box for which an + This parameter (and the ones following) describe a physical region of the simulation box for which an independent refinement maximum and minimum (separate from ``MaximumRefinementLevel``) can be specified. -``MultiRefineRegionGeometry[#]`` controls the geometry of the refined volume. Currently implemented - geometries are: (0) a rectangular region, (1) a ring of infinite height and (2) a cylinder of infinite +``MultiRefineRegionGeometry[#]`` controls the geometry of the refined volume. Currently implemented + geometries are: (0) a rectangular region, (1) a ring of infinite height and (2) a cylinder of infinite height. Up to 20 multi-refined regions may be defined (number the same as for ``StaticRefineRegion``) and each multi-refined region is labelled starting from zero. Default: -1 (no multi-regions) ``MultiRefineRegionLeftEdge[#]``, ``MultiRefineRegionRightEdge[#]`` (external) - Used when ``MultiRefineRegionGeometry[#] = 0`` and specifies the two corners in code units of a + Used when ``MultiRefineRegionGeometry[#] = 0`` and specifies the two corners in code units of a rectangular multi-region with a given maximum and minimum refinement level. Default: none. ``MultiRefineRegionCenter[#]`` (external) - Used when ``MultiRefineRegionGeometry[#] = 1 or 2`` and specifies the center of the ring or cylinder + Used when ``MultiRefineRegionGeometry[#] = 1 or 2`` and specifies the center of the ring or cylinder in code units. Default: none ``MultiRefineRegionRadius[#]`` (external) - Used when ``MultiRefineRegionGeometry[#] = 1 or 2`` and specifies the radius of the ring or cylinder - in code units. In the case of the ring, this marks the distance to the middle of the ring's thickness. + Used when ``MultiRefineRegionGeometry[#] = 1 or 2`` and specifies the radius of the ring or cylinder + in code units. In the case of the ring, this marks the distance to the middle of the ring's thickness. The thickness is specified with ``MultiRefineRegionWidth``. Default: none ``MultiRefineRegionWidth[#]`` (external) - Used when ``MultiRefineRegionGeometry[#] = 1`` and specifies the width (thickness) of the ring in + Used when ``MultiRefineRegionGeometry[#] = 1`` and specifies the width (thickness) of the ring in code units. Default: none ``MultiRefineRegionOrientation[#]`` (external) Used when ``MultiRefineRegionGeometry[#] = 1 or 2`` and is a unit vector pointing along the vertical direction of the ring or cylinder. Default: none. ``MultiRefineRegionStaggeredRefinement[#]`` (external) Used when ``MultiRefineRegionGeometry[#] = 1 or 2``. To avoid a sharp change in refinement at the edge of - the ring or cylinder, the allowed refinement is staggered from the maximum allowed value outside the - region, ``MultiRefineRegionOuterMaximumLevel``, to the maximum allowed refinement inside the region, - ``MultiRefineRegionMaximumLevel``. This parameter is the length over which that staggering occurs in + the ring or cylinder, the allowed refinement is staggered from the maximum allowed value outside the + region, ``MultiRefineRegionOuterMaximumLevel``, to the maximum allowed refinement inside the region, + ``MultiRefineRegionMaximumLevel``. This parameter is the length over which that staggering occurs in code units. Default: 0.0 (no staggering) ``MultiRefineRegionMaximumLevel[#]``, ``MultiRefineRegionMinimumLevel[#]`` (external) Maximum and minimum allowed refinement inside the region. Default: ``MaximumRefinementLevel``, 0 @@ -1118,8 +1120,8 @@ Hierarchy Control Parameters ``MaximumSubgridSize`` (external) The maximum size (volume) of a subgrid. See :ref:`running_large_simulations`. Default: 32768 ``CriticalGridRatio`` (external) - Critical grid ratio above which subgrids will be split in half along their - long axis prior to being split by the second derivative of their + Critical grid ratio above which subgrids will be split in half along their + long axis prior to being split by the second derivative of their signature. Default: 3.0 ``SubgridSizeAutoAdjust`` (external) See :ref:`running_large_simulations`. Default: 1 (TRUE) @@ -1177,7 +1179,7 @@ Hierarchy Control Parameters - + .. _gravity_parameters: Gravity Parameters @@ -1199,6 +1201,9 @@ General Gravity Parameters undergo self-gravity. ``SelfGravityGasOff`` (external) This parameter is used in conjunction with SelfGravity so that only particles contribute to potential, not gas. Default = False (i.e. gas does contribute) +``GravitySolverType`` (external) + Gravity solver to use (0: Multigrid, 1: APM). + Default: 0 ``GravitationalConstant`` (external) This is the gravitational constant to be used in code units. For cgs units it should be 4\*pi\*G. For cosmology, this value must be 1 for the @@ -1251,6 +1256,31 @@ General Gravity Parameters set to 0 if using many levels and radiative cooling is on [ignored in current version]. Default: 1 +.. _apm_gravity_parameters: + +APM Gravity Parameters +^^^^^^^^^^^^^^^^^^^^^^ + +``DepositAlsoParentGridAndSiblingsParticles`` (external) + Deposit particles also from the parent grid and the siblings. + This solves issues arising when particles are close to the grid edges. + Default: 0 + +``TimeSteppingRefinementCondition`` (external) + Additional condition constraining the time step on level *l+1* to be smaller + that the timestep on level *l* divided by the refinenemt factor. + Default: 0 + +``APMAddParentContribution`` (external) + Add the parent contribution to potential/acceleration onto the grid. + **Never turn this off except for testing/debugging**. + Default: TRUE + +``S2ParticleSize`` (external) + Size of the sphere (in cell size) used to filter the contribution of the + smallest scales to the gravitational force. + Default: 3.0 + .. _external_gravity_source: External Gravity Source @@ -1284,15 +1314,15 @@ added to the acceleration field for the baryons and particles. This fulfills the same purpose as ``PointSourceGravity`` but is more aptly named. ``ExternalGravity = 1`` turns on an alternative implementation of the NFW profile with properties - defined via the parameters ``HaloCentralDensity``, ``HaloConcentration`` and ``HaloVirialRadius``. Boxsize is assumed to be 1.0 in this case. ``ExternalGravity = 10`` gives a gravitational field defined by the logarithmic potential in Binney & Tremaine, corresponding to a disk with constant circular velocity. Default: 0 + defined via the parameters ``HaloCentralDensity``, ``HaloConcentration`` and ``HaloVirialRadius``. Boxsize is assumed to be 1.0 in this case. ``ExternalGravity = 10`` gives a gravitational field defined by the logarithmic potential in Binney & Tremaine, corresponding to a disk with constant circular velocity. Default: 0 ``ExternalGravityConstant`` (external) If ``ExternalGravity = 10``, this is the circular velocity of the disk in code units. Default: 0.0 -``ExternalGravityDensity`` +``ExternalGravityDensity`` Reserved for future use. ``ExternalGravityPosition`` (external) If ``ExternalGravity = 10``, this parameter specifies the center of the gravitational field in code units. Default: 0 0 0 ``ExternalGravityOrientation`` (external) - For ``ExternalGravity = 10``, this is the unit vector of the disk's angular momentum (e.g. a disk whose face-on view is oriented in the x-y plane would have ``ExternalGravityOrientation = 0 0 1``). Default: 0 0 0 + For ``ExternalGravity = 10``, this is the unit vector of the disk's angular momentum (e.g. a disk whose face-on view is oriented in the x-y plane would have ``ExternalGravityOrientation = 0 0 1``). Default: 0 0 0 ``ExternalGravityRadius`` (external) If ``ExternalGravity = 10``, this marks the inner radius of the disk in code units within which the velocity drops to zero. Default: 0.0 ``UniformGravity`` (external) @@ -1346,7 +1376,7 @@ General Hydrodynamics Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``UseHydro`` (external) - This flag (1 - on, 0 - off) controls whether a hydro solver is used. + This flag (1 - on, 0 - off) controls whether a hydro solver is used. Default: 1 ``HydroMethod`` (external) This integer specifies the hydrodynamics method that will be used. @@ -1404,7 +1434,7 @@ General Hydrodynamics Parameters 0 - ThirdOrderA 3 - SecondOrderC 1 - SecondOrderA 4 - FirstOrderA - 2 - SecondOrderB + 2 - SecondOrderB ``ConservativeInterpolation`` (external) This flag (1 - on, 0 - off) indicates if the interpolation should @@ -1424,8 +1454,8 @@ General Hydrodynamics Parameters 2 [reserved] 3 3,4 LLF (Local Lax-Friedrichs) 4 0,3 HLLC (Harten-Lax-van Leer with Contact) a three-wave, four-state solver with better resolution of contacts - 5 0 TwoShock - 6 4,6 HLLD + 5 0 TwoShock + 6 4,6 HLLD ================ =========== =========================== Default: 1 (HLL) for ``HydroMethod`` = 3; 5 (TwoShock) for @@ -1441,12 +1471,12 @@ General Hydrodynamics Parameters ===================== ============ =================== Reconstruction Method HydroMethod Description ===================== ============ =================== - 0 0,3,4,6 PLM (piecewise linear) + 0 0,3,4,6 PLM (piecewise linear) 1 0 PPM (piecwise parabolic) 2 [reserved] 3 [reserved] 4 [reserved] - 6 6 MUSCL-Hancock (Non Runge-Kutta) + 6 6 MUSCL-Hancock (Non Runge-Kutta) ===================== ============ =================== Default: 0 (PLM) for ``HydroMethod`` = 3; 1 (PPM) for ``HydroMethod`` = 0 @@ -1517,7 +1547,7 @@ General Hydrodynamics Parameters is either on (1) or off (0). Default: 0 ``SmallRho`` (external) Minimum value for density in code units. This is enforced in euler.F - when using the PPM solver (``HydroMethod`` = 0) or in + when using the PPM solver (``HydroMethod`` = 0) or in hydro_rk/EvolveLevel_RK.C when ``HydroMethod`` is 3 or 4. Not enforced in other hydrodynamics methods. Default: 1e-30 ``ZEUSQuadraticArtificialViscosity`` (external) @@ -1556,11 +1586,11 @@ Minimum Pressure Support Parameters Magnetohydrodynamics (CT) Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``MHD_CT_Method`` (external) +``MHD_CT_Method`` (external) Method for computing the electric field from the Riemann fluxes ========== ========================================================================== - CT Method Description + CT Method Description ========== ========================================================================== 0 None (only for debugging) 1 Balsara and Spicer 1999. First order average. @@ -1572,58 +1602,58 @@ Magnetohydrodynamics (CT) Parameters Default: 3 -``CT_AthenaDissipation`` (external) +``CT_AthenaDissipation`` (external) For the Lax-Friedrichs CT method, this is the maximum wave speed. (:math:`\alpha` in Gardiner & Stone 2005 eqn. 46). Default: 0.1 -``EquationOfState`` (external, ct only) +``EquationOfState`` (external, ct only) 0: standard adiabatic 1: Exactly isothermal equation of state. This flag removes the total energy term completely, instead computing pressure as :math:`p = c^2 \rho`. This option only works with ``HydroMethod = 6`` and ``RiemannSolver = 6`` (HLLD) as this is the only purely isothermal Riemann solver in Enzo. Default: 0 -``IsothermalSoundSpeed`` (external, ct only) +``IsothermalSoundSpeed`` (external, ct only) When ``EquationOfState = 1``, this is the sound speed used for computation of pressure. Default: 1 -``MHDCTSlopeLimiter`` (external, ct only) +``MHDCTSlopeLimiter`` (external, ct only) For computing derivatives for the reconstruction, this switches between zero slope (0), minmod (1), VanLeer (2), and characteristic (3) characteristic with primitive limiting (4). Default: 1 -``ReconstructionMethod`` (external) +``ReconstructionMethod`` (external) There are two reconstruction methods that work with MHDCT: Piecewise Linear Method (PLM) (0) and MUSCL-Hancock (6). This formulation of MUSCL-Hancock is different from the 2nd order Runga Kutta used for - ``HydroMethod = 3,4``. + ``HydroMethod = 3,4``. -``RiemannSolver`` (external) +``RiemannSolver`` (external) As with ``HydroMethod=4``, the preferred solver is HLLD (``RiemannSolver=6``). Other solvers may be released if the DOE approves them. -``MHDCTUseSpecificEnergy`` (external) +``MHDCTUseSpecificEnergy`` (external) Either specific energy is used internally (1) or conserved energy is used internally (0). Minor difference in boundary condition update, included for comparison to old solutions. Default: 1 -``MHDCTDualEnergyMethod`` (external) +``MHDCTDualEnergyMethod`` (external) When ``DualEnergyFormalism = 1``, this switches between a method that solves an additional equation for the internal energy, as - in the rest of Enzo, and method that updates the entropy. + in the rest of Enzo, and method that updates the entropy. -``MHD_WriteElectric`` (external) +``MHD_WriteElectric`` (external) Include the electric field in the output. Default: 0 -``MHD_ProjectB`` (internal) +``MHD_ProjectB`` (internal) Project magnetic fields from fine to coarse. - Should not be done in general, only used for initialization. + Should not be done in general, only used for initialization. -``MHD_ProjectE`` (internal) +``MHD_ProjectE`` (internal) Project Electric fields from fine to coarse. Used for the time evolution of the fields. @@ -1632,13 +1662,13 @@ Magnetohydrodynamics (CT) Parameters Magnetohydrodynamics (Dedner) Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following parameters are considered only when ``HydroMethod`` is 3 or 4 (and occasionally only in some test problems). +The following parameters are considered only when ``HydroMethod`` is 3 or 4 (and occasionally only in some test problems). Because many of the following parameters are not actively being tested and maintained, users are encouraged to carefully examine the code before using it. ``UsePoissonDivergenceCleaning`` (external) Enables additional divergence cleaning by solving a Poisson equation. This works on top of the standard mixed hyperbolic/parabolic divergence cleaning - and is not necessary for the proper operation of the solver. + and is not necessary for the proper operation of the solver. This works on individual grids, i.e., it's *not* a global divergence purge. Use with care as this feature is not extensively tested. No recommendation about the use of this option is made by the developers at this time. @@ -1657,7 +1687,7 @@ Because many of the following parameters are not actively being tested and maint cleaning Poisson solver. Default: 0.001 ``PoissonBoundaryType`` (external) Controls the boundary conditions for divergence - cleaning Poisson solver. 0 - Neumann (default). 1 - Dirichlet + cleaning Poisson solver. 0 - Neumann (default). 1 - Dirichlet ``UseDrivingField`` (external) This parameter is used to add external driving force as a source term in some test problems; see hydro_rk/Grid_(MHD)SourceTerms.C. Default: 0 ``DrivingEfficiency`` (external) @@ -1665,7 +1695,7 @@ Because many of the following parameters are not actively being tested and maint ``UseConstantAcceleration`` (external) This parameter is used to add constant acceleration as a source term in some set-ups; see hydro_rk/Grid_(MHD)SourceTerms.C. Default: 0 ``ConstantAcceleration[]`` (external) - This parameter is used to define the value of such acceleration; see hydro_rk/Grid_(MHD)SourceTerms.C. + This parameter is used to define the value of such acceleration; see hydro_rk/Grid_(MHD)SourceTerms.C. ``UseViscosity`` (external) This parameter is used to add viscosity and thereby update velocity in some set-ups (1 - constant viscosity, 2 - alpha viscosity); see ComputeViscosity in hydro_rk/Grid_AddViscosity.C. Default: 0 ``ViscosityCoefficient`` (external) @@ -1729,9 +1759,9 @@ Simple Cooling Options ``RadiativeCooling`` (external) This flag (1 - on, 0 - off) controls whether or not a radiative cooling module is called for each grid. There are currently several - possibilities, controlled by the value of another flag. See :ref:`cooling` + possibilities, controlled by the value of another flag. See :ref:`cooling` for more information on the various cooling methods. Default: 0 - + - If the ``MultiSpecies`` flag is off, then equilibrium cooling is assumed and one of the following two will happen. If the parameter ``GadgetCooling`` is set to 1, the primordial equilibrium code is @@ -1870,11 +1900,11 @@ creating Cloudy datasets. The Grackle ^^^^^^^^^^^ -The Grackle is an external chemistry and cooling library originally derived from -Enzo's MultiSpecies chemistry and Cloudy cooling modules. See :ref:`here ` -for a full description, including why you might use this over Enzo's internal -chemistry and cooling. For more information on Grackle parameter, see also the -`Grackle documentation `_. Note, some Grackle +The Grackle is an external chemistry and cooling library originally derived from +Enzo's MultiSpecies chemistry and Cloudy cooling modules. See :ref:`here ` +for a full description, including why you might use this over Enzo's internal +chemistry and cooling. For more information on Grackle parameter, see also the +`Grackle documentation `_. Note, some Grackle parameters have been mapped to Enzo parameters for simplicity. ``use_grackle`` (int) @@ -2011,7 +2041,7 @@ Particle Parameters fp = h5.File('particle-ids.h5', 'w') fp['particle_identifier'] = sp['particle_index'].astype('int') fp.close() - + ``ParticleSplitterFraction`` (external) An array of four values that represent the width of the splitting region in units of the original refine region set by @@ -2054,24 +2084,24 @@ General Star Formation 1 and 3 are desired, the user would specify 10 (2\ :sup:`1`\ + 2\ :sup:`3`\ ), or if methods 1, 4 and 7 are wanted, this would be 146 (2\ :sup:`1`\ + 2\ :sup:`4`\ + 2\ :sup:`7`\ ). Default: 0 - + :: 0 - Cen & Ostriker (1992) 1 - Cen & Ostriker (1992) with stocastic star formation 2 - Global Schmidt Law / Kravstov et al. (2003) 3 - Population III stars / Abel, Wise & Bryan (2007) - 4 - Sink particles: Pure sink particle or star particle with wind feedback depending on + 4 - Sink particles: Pure sink particle or star particle with wind feedback depending on choice for HydroMethod / Wang et al. (2009) 5 - Radiative star clusters / Wise & Cen (2009) 6 - [reserved for future use] 7 - Cen & Ostriker (1992) with no delay in formation 8 - Springel & Hernquist (2003) 9 - Massive Black Hole (MBH) particles insertion by hand / Kim et al. (2010) - 10 - Population III stellar tracers + 10 - Population III stellar tracers 11 - Molecular hydrogen regulated star formation 13 - Distributed stellar feedback model (So et al. 2014) - 14 - Cen & Ostriker (1992) stochastic star formation with kinetic feedback + 14 - Cen & Ostriker (1992) stochastic star formation with kinetic feedback / Simpson et al. (2015) ``StarParticleFeedback`` (external) @@ -2117,7 +2147,7 @@ General Star Formation with ``StarParticleCreation`` method = 0, 1, 2, 5, 7, 8, and 13. Default: 0. -``StarMakerPlanetaryNebulae`` (external) +``StarMakerPlanetaryNebulae`` (external) This parameter turns on thermal and chemical feedback from planetary nebulae. The mass loss and luminosity are taken from the same `fits from K. Nagamine @@ -2173,16 +2203,16 @@ The parameters below are considered in ``StarParticleCreation`` method formation based on the idea that stars have a non-negligible formation and life-time. The unit is years. Default: 1e6 ``StarMakerTimeIndependentFormation`` (external) - When used, the factor of dt / t_dyn is removed from the calculation of - the star particle mass above. Instead of the local dynamical time, the - timescale over which feedback occurs is a constant set by the parameter - ``StarMakerMinimumDynamicalTime``. This is necessary when running with - conduction as the timesteps can be very short, which causes the calculated - star particle mass to never exceed reasonable values for - ``StarMakerMinimumMass``. This prevents cold, star-forming gas from - actually forming stars, and when combined with conduction, results in too - much heat being transferred out of hot gas. When running a cosmological - simulation with conduction and star formation, one must use this otherwise + When used, the factor of dt / t_dyn is removed from the calculation of + the star particle mass above. Instead of the local dynamical time, the + timescale over which feedback occurs is a constant set by the parameter + ``StarMakerMinimumDynamicalTime``. This is necessary when running with + conduction as the timesteps can be very short, which causes the calculated + star particle mass to never exceed reasonable values for + ``StarMakerMinimumMass``. This prevents cold, star-forming gas from + actually forming stars, and when combined with conduction, results in too + much heat being transferred out of hot gas. When running a cosmological + simulation with conduction and star formation, one must use this otherwise bad things will happen. (1 - ON; 0 - OFF) Default: 0. ``StarMassEjectionFraction`` (external) The mass fraction of created stars which is returned to the gas @@ -2204,7 +2234,7 @@ The parameters below are considered in ``StarParticleCreation`` method calculating the radiation background. Default: 5e-6 ``StarFeedbackKineticFraction`` (external) Only valid for ``StarParticleFeedback`` method = 14. If set to a zero or positive - value between 0.0 and 1.0, this is the constant fraction of energy injected in kinetic + value between 0.0 and 1.0, this is the constant fraction of energy injected in kinetic form. If set to -1, then a variable kinetic fraction is used that depends on local gas density, metallicity and resolution. See Simpson et al. 2015 for details. Note, some failures may occur in -1 mode. Default 0.0 @@ -2215,29 +2245,29 @@ The parameters below are considered in ``StarParticleCreation`` method to a negative value, energy, mass and metals are injected gradually in the same way as is done for ``StarParticleFeedback`` method = 1. Default -1. ``StarMakerMinimumMassRamp`` (external) - Sets the Minimum Stellar Mass (otherwise given by StarMakerMinimumMass to + Sets the Minimum Stellar Mass (otherwise given by StarMakerMinimumMass to ramp up over time, so that a small mass can be used early in the calculation - and a higher mass later on, or vice versa. The minimum mass is "ramped" - up or down starting at StarMakerMinimumMassRampStartTime and ending - at StarMakerMinimumMassRampEndTime. The acceptable values are: + and a higher mass later on, or vice versa. The minimum mass is "ramped" + up or down starting at StarMakerMinimumMassRampStartTime and ending + at StarMakerMinimumMassRampEndTime. The acceptable values are: (1) linear evolution of mass in time (2) linear evolution of mass in redshift (3) exponential evolution of mass in time (4) exponential evolution of mass in redshift -``StarMakerMinimumMassRampStartTime`` (external) +``StarMakerMinimumMassRampStartTime`` (external) The code unit time, or redshift, to start the ramp of the StarMakerMinimumMass - Before this time the minimum mass will have a constant value given + Before this time the minimum mass will have a constant value given by StarMakerMinimumMassRampStartMass -``StarMakerMinimumMassRampEndTime`` (external) +``StarMakerMinimumMassRampEndTime`` (external) The code unit time, or redshift, to start the ramp of the StarMakerMinimumMass - After this time the minimum mass will have a constant value given + After this time the minimum mass will have a constant value given by StarMakerMinimumMassRampEndMass -``StarMakerMinimumMassRampStartMass`` (external) - The mass at which to start the ramp in the minimum stellar mass. This mass - will be used at all times before StarMakerMinimumMassRampStartTime as well. -``StarMakerMinimumMassRampEndMass`` (external) - The mass at which to end the ramp in the minimum stellar mass. This mass - will be used at all times after StarMakerMinimumMassRampEndTime as well. +``StarMakerMinimumMassRampStartMass`` (external) + The mass at which to start the ramp in the minimum stellar mass. This mass + will be used at all times before StarMakerMinimumMassRampStartTime as well. +``StarMakerMinimumMassRampEndMass`` (external) + The mass at which to end the ramp in the minimum stellar mass. This mass + will be used at all times after StarMakerMinimumMassRampEndTime as well. .. _molecular_hydrogen_regulated_star_formation_parameters: @@ -2326,7 +2356,7 @@ The parameters below are considered in ``StarParticleCreation`` method 3. Upper limit of the Pop III IMF. Default: 300 ``PopIIIInitialMassFunctionSlope`` (external) Slope of the Salpeter (high-mass) portion of the Pop III IMF. Default: -1.3 -``PopIIIInitialMassFunctionCalls`` (internal) +``PopIIIInitialMassFunctionCalls`` (internal) Number of times a Pop III mass has been drawn from the IMF. Used for restarts and reproducibility. Default: 0 ``PopIIISupernovaMustRefine`` (external) When turned on, the region around a star about to go supernova is refined to the maximum AMR level. Experimental. Default: 0 @@ -2408,7 +2438,7 @@ The parameters below are considered in ``StarParticleCreation`` method 9. Sink Formation and Feedback ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The parameters below are considered in sink creation routines: sink_maker, star_maker8, star_maker9 (and occasionally only in certain set-ups). +The parameters below are considered in sink creation routines: sink_maker, star_maker8, star_maker9 (and occasionally only in certain set-ups). Because many of the following parameters are not actively being tested and maintained, users are encouraged to carefully examine the code before using it. ``AccretionKernal`` (external) @@ -2420,7 +2450,7 @@ Because many of the following parameters are not actively being tested and maint ``MSStellarWindTurnOnMass`` (external) This parameter is used to decide whether mass increase reached the ejection threshold for StellarWindFeedback = 3 or 6 in star_maker8.C. Default: 10.0 ``BigStarFormation`` (external) - This parameter is used to turn on sink particle creation by star_maker9.C. + This parameter is used to turn on sink particle creation by star_maker9.C. ``BigStarFormationDone`` (external) In star_maker9.C, this parameter is used when we do not want to form BigStars any more. ``BigStarSeparation`` (external) @@ -2476,7 +2506,7 @@ formalism includes a correction which accounts for the vorticity of the gas based on `Krumholz et al. (2005) `__. Set to 6 to use the viscous angular momentum prescription from `DeBuhr et al. (2010) `__. - + Set to 7 to use a modified accretion rate based on the alpha-disk model of Shakura & Sunyaev (1973) This scheme is based on `Cen et al. `__. @@ -2488,8 +2518,8 @@ by Regan et al. (`2018 `__, `2019 `__ to adjust the efficiency when accretion enters the super-critical regime. The fits are based on the slim-disk model of accretion which generates inefficient feedback. Default: 1 - + .. _radiation_parameters: Radiation Parameters @@ -2583,7 +2613,7 @@ Background Radiation Parameters `_. Default: 0 :: - + 1 - Haardt & Madau spectrum with q_alpha = 1.5 2 - Haardt & Madau spectrum with q_alpha = 1.8 3 - Modified Haardt & Madau spectrum to match observations @@ -2624,20 +2654,20 @@ Background Radiation Parameters is calculated. If a UV radiation background is used in a non-cosmological simulation, this needs to be defined. Negative redshifts are permitted. Default: (undefined) -``RadiationRedshiftOn`` (external) - The redshift at which the UV +``RadiationRedshiftOn`` (external) + The redshift at which the UV background turns on. Default: 7.0. -``RadiationRedshiftFullOn`` (external) +``RadiationRedshiftFullOn`` (external) The redshift at which the UV background is at full strength. Between z = - ``RadiationRedshiftOn`` and z = ``RadiationRedshiftFullOn``, the + ``RadiationRedshiftOn`` and z = ``RadiationRedshiftFullOn``, the background is gradually ramped up to full strength. Default: 6.0. -``RadiationRedshiftDropOff`` (external) - The redshift at which the +``RadiationRedshiftDropOff`` (external) + The redshift at which the strength of the UV background is begins to gradually reduce, reaching zero by ``RadiationRedshiftOff``. Default: 0.0. -``RadiationRedshiftOff`` (external) - The redshift at which the UV +``RadiationRedshiftOff`` (external) + The redshift at which the UV background is fully off. Default: 0.0. ``TabulatedLWBackground`` (external) When on, the amplitude of the Lyman-Werner background is read from the file LW_J21.in as a function of redshift. Each line should have the redshift and LW background in units of 1e-21 erg/cm^3/s/Hz/sr. Default: 0 @@ -2805,7 +2835,7 @@ Radiative Transfer (FLD) Parameters ``RadiationFieldType = 0`` to prevent conflicts. Default: 0. *IMPORTANT*: Set ``RadiativeTransfer = 0`` to avoid conflicts with the ray tracing solver above. - Set ``RadiativeTransferOpticallyThinH2 = 0`` to avoid conflicts with the built-in optically-thin H_2 dissociating field from the ray-tracing solver. + Set ``RadiativeTransferOpticallyThinH2 = 0`` to avoid conflicts with the built-in optically-thin H_2 dissociating field from the ray-tracing solver. ``ImplicitProblem`` (external) Set to 1 to turn on the implicit FLD solver, or 3 to turn on the split FLD solver. Default: 0. @@ -2837,9 +2867,9 @@ Radiative Transfer (FLD) Implicit Solver Parameters Type of assumed radiation spectrum for radiation field, Default: 1. :: - + -1 - monochromatic spectrum at frequency h nu_{HI} = 13.6 eV - 0 - power law spectrum, (nu / nu_{HI} )^(-1.5) + 0 - power law spectrum, (nu / nu_{HI} )^(-1.5) 1 - T = 1e5 blackbody spectrum ``RadHydroChemistry`` (external) @@ -2852,7 +2882,7 @@ Radiative Transfer (FLD) Implicit Solver Parameters Default: 1. :: - + 1 - chemistry-dependent model, with case-B hydrogen II recombination coefficient. 2 - chemistry-dependent model, with case-A hydrogen II recombination coefficient. 4 - chemistry-dependent model, with case-A hydrogen II @@ -2871,7 +2901,7 @@ Radiative Transfer (FLD) Implicit Solver Parameters hydro time step). ``RadHydroDtNorm`` (external) type of p-norm to use in estimating time-accuracy for predicting - next time step. Default: 2.0. + next time step. Default: 2.0. :: @@ -2902,7 +2932,7 @@ Radiative Transfer (FLD) Implicit Solver Parameters field. Default: [0 0]. :: - + 0 - Periodic. 1 - Dirichlet. 2 - Neumann. @@ -2941,7 +2971,7 @@ Radiative Transfer (FLD) Implicit Solver Parameters time-evolved solution. Default: 0. :: - + 0 - use the solution from the previous time step (safest). 1 - use explicit Euler with only spatially-local physics (heating & cooling). 2 - use explicit Euler with all physics. @@ -2996,16 +3026,16 @@ Radiative Transfer (FLD) Split Solver Parameters Type of assumed radiation spectrum for radiation field, Default: 1. :: - + 1 - T=1e5 blackbody spectrum - 0 - power law spectrum, ( nu / nu_{HI})^(-1.5)` + 0 - power law spectrum, ( nu / nu_{HI})^(-1.5)` -1 - monochromatic spectrum at frequency h nu_{HI}= 13.6 eV -2 - monochromatic spectrum at frequency h nu_{HeI}= 24.6 eV -3 - monochromatic spectrum at frequency h nu_{HeII}= 54.4 eV ``RadHydroChemistry`` (external) Use of primordial chemistry in computing opacities and - photo-heating/photo-ionization. Default: 1. + photo-heating/photo-ionization. Default: 1. :: @@ -3225,9 +3255,9 @@ Accretion Physics fixed rate defined below. Set to 4 to to turn on accretion based on the Eddington-limited spherical Bondi-Hoyle formula, but without v_rel in the denominator. Set to 5 to turn on accretion based on - Krumholz et al.(2006) which takes vorticity into account. Set to 6 - to turn on alpha disk formalism based on DeBuhr et al.(2010). - 7 and 8 are still failed experiment. Add 10 to each of these options + Krumholz et al.(2006) which takes vorticity into account. Set to 6 + to turn on alpha disk formalism based on DeBuhr et al.(2010). + 7 and 8 are still failed experiment. Add 10 to each of these options (i.e. 11, 12, 13, 14) to ignore the Eddington limit. See ``Star_CalculateMassAccretion.C``. Default: 0 (FALSE) ``MBHAccretionRadius`` (external) @@ -3268,7 +3298,7 @@ Accretion Physics ``MBHMinDynamicalTime`` (external) Minimum dynamical time (in yr) for a MBH particle. Default: 1e7 ``MBHMinimumMass`` (external) - Minimum mass (in Msun) for a MBH particle. Default: 1e3 + Minimum mass (in Msun) for a MBH particle. Default: 1e3 .. _Feedback_physics: @@ -3280,10 +3310,10 @@ Feedback Physics - not fully tested). Set to 2 to turn on mechanical feedback of MBH particles (``MBH_JETS``, bipolar jets along the total angular momentum of gas accreted onto the MBH particle so far). Set to 3 to turn on - another version of mechanical feedback of MBH particles (``MBH_JETS``, - always directed along z-axis). Set to 4 to turn on experimental version of - mechanical feedback (`MBH_JETS`, bipolar jets along the total angular - momentum of gas accreted onto the MBH particle so far + 10 degree random + another version of mechanical feedback of MBH particles (``MBH_JETS``, + always directed along z-axis). Set to 4 to turn on experimental version of + mechanical feedback (`MBH_JETS`, bipolar jets along the total angular + momentum of gas accreted onto the MBH particle so far + 10 degree random noise). Set to 5 to turn on experimental version of mechanical feedback (``MBH_JETS``, launched at random direction). Note that, even when this parameter is set to 0, MBH particles still can be radiation sources @@ -3291,7 +3321,7 @@ Feedback Physics Default: 0 (FALSE) :: - + ``RadiativeTransfer = 0`` & ``MBHFeedback = 0`` : no feedback at all ``RadiativeTransfer = 0`` & ``MBHFeedback = 1`` : purely thermal feedback ``RadiativeTransfer = 0`` & ``MBHFeedback = 2`` : purely mechanical feedback @@ -3354,7 +3384,7 @@ For details on shock finding in Enzo see :ref:`shock_finding`. ``ShockMethod`` (external) This parameter controls the use and type of shock finding. Default: 0 - + :: 0 - Off @@ -3440,14 +3470,14 @@ Isotropic and anisotropic thermal conduction are implemented using the method of Parrish and Stone: namely, using an explicit, forward time-centered algorithm. In the anisotropic conduction, heat can only conduct along magnetic field lines. One can turn on the two types of -conduction independently, since there are situations where one might +conduction independently, since there are situations where one might want to use both. The Spitzer fraction can be also set -independently for the isotropic and anisotropic conduction. Running a -cosmological simulation with conduction on can be tricky as the timesteps -can become very short. It is recommended that you look carefully at all the -available conduction parameters. Additionally, if you intend to run with -star particles, it is highly recommended that you set the parameter, -``StarMakerTimeIndependentFormation``. See the description in +independently for the isotropic and anisotropic conduction. Running a +cosmological simulation with conduction on can be tricky as the timesteps +can become very short. It is recommended that you look carefully at all the +available conduction parameters. Additionally, if you intend to run with +star particles, it is highly recommended that you set the parameter, +``StarMakerTimeIndependentFormation``. See the description in :ref:`starparticleparameters` for more information. ``IsotropicConduction`` (external) @@ -3483,30 +3513,30 @@ Subgrid-scale (SGS) turbulence model ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following parameter allow the use of an SGS turbulence model in -Enzo, see test problem +Enzo, see test problem ``run/MHD/3D/StochasticForcing/StochasticForcing.enzo``. -It is recommended to not arbitrarily mix model terms, but either +It is recommended to not arbitrarily mix model terms, but either stick to one model family (nonlinear, dissipative, or scale-similarity) or conduct additional *a priori* test first. Best fit model coefficients based on *a priori* testing of compressible MHD turbulence for a wide range of sonic Mach numbers (0.2 to 20) can be found in Table II in `Grete et al. (2016) Physics of Plasmas 23 062317 -`_, +`_, where all models are presented in more detail. -Overall, the nonlinear model (effectively parameter free) +Overall, the nonlinear model (effectively parameter free) with an explicit 3-point stencil showed the -best performance in decaying MHD test problem, see +best performance in decaying MHD test problem, see `Grete et al. (2017) Phys. Rev. E. 95 033206 `_. ``UseSGSModel`` (external) This parameter generally turns the SGS machinery on (even though - no SGS term is added by default as every term needs a coefficient, - see below). + no SGS term is added by default as every term needs a coefficient, + see below). 1: Turn on. Default: 0 Explicit filtering @@ -3521,26 +3551,26 @@ The following three variables enable the explicit filtering of the grid-scale quantites as they are used in the SGS terms. See Table 1 in `Grete et al. (2017) Phys. Rev. E. 95 033206 -`_ for coefficients +`_ for coefficients of a discrete box filter. The recommended values correspond to a discrete representation of a box filter on a 3-point stencil. ``SGSFilterWidth`` (external) - Width (in units of cell widths) of the discrete filter. - Default: 0; + Width (in units of cell widths) of the discrete filter. + Default: 0; Recommended: 2.711; ``SGSFilterStencil`` (external) - Discrete width of filter stencil in numbers of cells. + Discrete width of filter stencil in numbers of cells. Default: 0; Recommended: 3; Maximum: 7; ``SGSFilterWeights`` (external) Symmetic filter weights that are used in the stencil. List of four floats. - First number corresponds to weight of central point X_i, + First number corresponds to weight of central point X_i, second number corresponds to weight of points X_i+1 and X_i-1, and so on. Default: 0. 0. 0. 0.; Recommended: 0.40150 0.29925 0.00000 0.0; @@ -3552,7 +3582,7 @@ Nonlinear model Coefficient for nonlinear Reynolds stress model. Default: 0; Recommended: 1; - + ``SGScoeffNLb`` (external) Coefficient for nonlinear Maxwell stress (only MHD). Default: 0; @@ -3596,7 +3626,7 @@ Scale-similarity model Coefficient for scale-similarity Reynolds stress model. Default: 0; Recommended: 0.67; - + ``SGScoeffSSb`` (external) Coefficient for scale-similarity Maxwell stress (only MHD). Default: 0; @@ -3760,7 +3790,7 @@ Other Internal Parameters ``MovieDumpNumber`` (internal) The identification number of the next movie output file. Default: 0 ``TracerParticleDumpNumber`` (internal) - The identification number of the next tracer particle output file. Default: 0 + The identification number of the next tracer particle output file. Default: 0 ``RestartDumpNumber`` Reserved for future use. ``HistoryDumpNumber`` @@ -3769,7 +3799,7 @@ Other Internal Parameters These are printed out into the restart dump parameter file. One Label is produced per baryon field with the name of that baryon field. The same labels are used to name data sets in HDF files. -``DataUnits[#]`` +``DataUnits[#]`` Reserved for future use. ``VersionNumber`` (internal) Sets the version number of the code which is written out to restart @@ -3785,7 +3815,7 @@ Problem Type Parameters causes the correct problem initializer to be called to set up the grid, and also may trigger certain boundary conditions or other problem-dependent routines to be called. The possible values are - listed below. Default: none. + listed below. Default: none. For other problem-specific parameters follow the links below. The problems marked with "hydro_rk" originate from the MUSCL solver package in the enzo installation directory @@ -3827,8 +3857,8 @@ Problem Type Description and Parameter List 50 :ref:`photontest_param` 51 Photon Test Restart 59 :ref:`stochastic_forcing_param` -60 :ref:`turbulence_param` -61 :ref:`protostellar_param` +60 :ref:`turbulence_param` +61 :ref:`protostellar_param` 62 :ref:`coolingtest_param` 63 One Zone Free Fall Test 70 Conduction Test with Hydro Off @@ -3897,11 +3927,11 @@ Shock Tube (1: unigrid and AMR) ``HydroShockTubesInitialDiscontinuity`` (external) The position of the initial discontinuity. Default: 0.5 ``HydroShockTubesSecondDiscontinuity`` (external) - The position of the second discontinuity, if a second discontinuity is + The position of the second discontinuity, if a second discontinuity is desired. Default: FLOAT_UNDEFINED, i.e. no second discontinuity. ``HydroShockTubesLeftDensity``, ``HydroShockTubesRightDensity``, ``HydroShockTubesCenterDensity`` (external) The initial gas density to the left and right of the discontinuity, - and between the discontinuities if a second discontinuity has been + and between the discontinuities if a second discontinuity has been specified with HydroShockTubesSecondDiscontinuity. Default: 1.0 for each value. ``HydroShockTubesLeftPressure``, ``HydroShockTubesRightPressure``, ``HydroShockTubesCenterPressure`` (external) @@ -3911,16 +3941,16 @@ Shock Tube (1: unigrid and AMR) each of the left, right, and center regions. ``HydroShockTubesLeftVelocityX``, ``HydroShockTubesLeftVelocityY``, ``HydroShockTubesLeftVelocityZ`` (external) - The initial gas velocity, in the x-, y-, and z-directions to the left of + The initial gas velocity, in the x-, y-, and z-directions to the left of the discontinuity. Default: 0.0 for all directions. ``HydroShockTubesRightVelocityX``, ``HydroShockTubesRightVelocityY``, ``HydroShockTubesRightVelocityZ`` (external) - The initial gas velocity, in the x-, y-, and z-directions to the right of + The initial gas velocity, in the x-, y-, and z-directions to the right of the discontinuity. Default: 0.0 for all directions. ``HydroShockTubesCenterVelocityX``, ``HydroShockTubesCenterVelocityY``, ``HydroShockTubesCenterVelocityZ`` (external) - The initial gas velocity, in the x-, y-, and z-directions between the - discontinuities, used if a second discontinuity has been specified with + The initial gas velocity, in the x-, y-, and z-directions between the + discontinuities, used if a second discontinuity has been specified with HydroShockTubesSecondDiscontinuity. Default: 1.0 for all directions. .. _wavepool_param: @@ -4027,16 +4057,16 @@ Shock in a Box (5) Implosion (6) ^^^^^^^^^^^^^ - + The implosion test sets up a converging shock problem in a square domain (x,y) \in (0, 0.3)x(0, 0.3) with gas initially at rest. Initial pressure and density is 1 everywhere except for a triangular region (0.15,0)(0.15,0) where d=0.125 and p=0.14. Reflecting boundary conditions at all boundaries. Adiabatic index gamma=1.4. - + If AMR is used, a hierarchy of subgrids (one per level) will be generated at start-up to properly resolve the initial discontinuity. - + REFERENCE: Hui Li and Z. Li, JCP 153, 596, 1999. Chang et al. JCP 160, 89, 1999. @@ -4058,10 +4088,10 @@ Implosion (6) Sedov Blast (7) ^^^^^^^^^^^^^^^ - Self-similar solution: L.I. Sedov (1946); + Self-similar solution: L.I. Sedov (1946); see also: Sedov (1959), Similarity and Dimensional Methods in Mechanics, pp. 210, 219, 228; - see also: Landau & Lifshitz, Fluid Dynamics, Sect. 99 + see also: Landau & Lifshitz, Fluid Dynamics, Sect. 99 "The Propagation of Strong Shock Waves" (1959). Experiments, terrestrial/numerical: Taylor (1941, 1949). @@ -4097,17 +4127,17 @@ Kelvin-Helmholtz Instability (8) Setting ``KHRamp`` to 0, creates the standard KH test problem where there is a discontinuous jump between the two fluids in - x-velocity and density. Random perturbations in y-velocity are the seeds + x-velocity and density. Random perturbations in y-velocity are the seeds to the KH instability resulting in growth of multiple modes of the KHI. Setting ``KHRamp`` to 1 modifies the ICs so that there is a smooth - ramp connecting the two fluids in x-velocity and density of width + ramp connecting the two fluids in x-velocity and density of width ``KHRampWidth``. A sinusoidal perturbation in y-velocity is the seed - to the KH instability resulting in only growth of k=2 modes. - These results converge in behavior as resolution is increased, whereas - the standard ICs do not. The ramped ICs are based on Robertson, Kravtsov, - Gnedin, Abel & Rudd 2010, but that work has a typo in the ramp equation, - and this implementation matches Robertson's actual ICs. + to the KH instability resulting in only growth of k=2 modes. + These results converge in behavior as resolution is increased, whereas + the standard ICs do not. The ramped ICs are based on Robertson, Kravtsov, + Gnedin, Abel & Rudd 2010, but that work has a typo in the ramp equation, + and this implementation matches Robertson's actual ICs. ``KHInnerDensity``, ``KHOuterDensity`` (external) Initial density. Default: 2.0 (inner) and 1.0 (outer) @@ -4118,8 +4148,8 @@ Kelvin-Helmholtz Instability (8) ``KHVelocityJump`` (external) The difference in velocity between the outer fluid and the inner fluid. Inner fluid will have half this value and move to the right (positive), - whereas outer fluid will have have this value and move to the left - (negative). Total fluid velocities will combine this jump with + whereas outer fluid will have have this value and move to the left + (negative). Total fluid velocities will combine this jump with KHBulkVelocity. Default: 1.0 ``KHPerturbationAmplitude`` (external) Default: 0.1 @@ -4138,8 +4168,8 @@ Kelvin-Helmholtz Instability (8) 2D/3D Noh Problem (9) ^^^^^^^^^^^^^^^^^^^^^ - - Liska & Wendroff, 2003, SIAM J. Sci. Comput. 25, 995, + + Liska & Wendroff, 2003, SIAM J. Sci. Comput. 25, 995, Section 4.5, Fig. 4.4. @@ -4777,7 +4807,7 @@ Cosmology Simulation (30) ``CosmologySimulationInitialTemperature`` (external) A uniform temperature value at ``InitialRedshift`` (needed if the initial gas energy field is not supplied). Default: 550\*((1.0 + - ``InitialRedshift``)/201)\ :sup:`2`\ + ``InitialRedshift``)/201)\ :sup:`2`\ ``CosmologySimulationOmegaBaryonNow`` (external) This is the contribution of baryonic matter to the energy density at the current epoch (z=0), relative to the value required to @@ -5037,13 +5067,13 @@ Photon Test (50) Turbulence Simulation with Stochastic Forcing (59) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Typical quasi-isothermal "turbulence-in-a-box" problem with non-static driving field. - For details on stochastic forcing, see Schmidt et al. 2009 A&A 494, 127-145 + For details on stochastic forcing, see Schmidt et al. 2009 A&A 494, 127-145 http://dx.doi.org/10.1051/0004-6361:200809967 3D simulations with MUSCL hydro and MHD solver are tested. PPM, ZEUS and MHDCT unsupported at this time. - Remember that in addition to the problem specific parameters below + Remember that in addition to the problem specific parameters below UseDrivingField = 1 has to be turned on! @@ -5098,7 +5128,7 @@ Turbulence Simulation (60) ``TurbulenceSimulationMagneticName`` (external) -``TurbulenceSimulationInitialTemperature`` (external) +``TurbulenceSimulationInitialTemperature`` (external) ``TurbulenceSimulationInitialDensity`` (external) @@ -5280,7 +5310,7 @@ Put Sink from Restart (107) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``PutSinkRestartName`` (external) - Filename to restart from. + Filename to restart from. .. _clustercoolingflow_param: @@ -5343,7 +5373,7 @@ Cluster Cooling Flow (108) ``SNIaFeedbackEnergy`` (external) Energy feedback from evolved stars (Type Ia SN). Default: 1.0 - + .. _light_boson: Light Boson Initialize @@ -5356,7 +5386,7 @@ Light Boson Initialize colliding Gaussian packets. Default: 1 ``LightBosonCenter`` (external) Specifies center position for the tests. Default: 0.5 - + .. _fdm_collapse: FDM Collapse @@ -5367,7 +5397,7 @@ containing the density field, and `GridRePsi` and `GridImPsi` which contain the real and imaginary parts of the wave function. There is a python code in run/FuzzyDarkMatter/init.py which generates a - + .. _mhd1d_param: 1D MHD Test (200) @@ -5491,7 +5521,7 @@ Galaxy Disk (207) ``HaloRadius[i]`` (external) Radius of the halo for the ith sphere. Default: 1 (all) ``HaloCoreRadius[i]`` (external) - Core radius for the ith sphere. Default: 0.1 (all) + Core radius for the ith sphere. Default: 0.1 (all) ``HaloDensity[i]`` (external) Density of the halo for the ith sphere. Default: 1 (all) ``HaloTemperature[i]`` (external) @@ -5501,7 +5531,7 @@ Galaxy Disk (207) ``HaloSpin[i]`` (external) TBD ``HaloPosition[i][j]`` (external) - Position of the Halo. + Position of the Halo. ``HaloVelocity[i][j]`` (external) Velocity of the Halo. ``DiskRadius[i]`` (external) @@ -5561,7 +5591,7 @@ CR Shock Tube (250: unigrid and AMR) ``HydroShockTubesCenterCREnDensity`` (external) In addition to setting a shock tube with two constant regions, - this version also allows for three constant regions, + this version also allows for three constant regions, with a Center region in addition to the Left and Right regions. Finally, there are two special cases -- if HydroShockTubesCenterCREnDensity is set to 123.4, then the central @@ -5611,12 +5641,12 @@ Radiation-Hydrodynamics Test 1 - Constant Fields (400) ``RadHydroTemperature`` (external) Ambient temperature. Default: 1 ``RadHydroIEnergy`` (external) - Ambient internal energy (replaces temperature, if specified). + Ambient internal energy (replaces temperature, if specified). Default: -1 ``RadHydroRadiationEnergy`` (external) Ambient radiation energy. Default: 10 ``RadHydroInitialFractionHII`` (external) - Initial fraction of ionized hydrogen (in relation to all hydrogen). + Initial fraction of ionized hydrogen (in relation to all hydrogen). Default: 0 ``RadHydroHFraction`` (external) Initial fraction of hydrogen (in relation to the total density). @@ -5702,8 +5732,8 @@ Radiation-Hydrodynamics Test 5 - Radiating Shock (404/405) ``ShockDir`` (external) Propagation coordinate for shock. {0,1,2}. Default: 0 ``CGSType`` (external) - 1 = Astrophysical Setup Parameters; - 2 = "lab" setup parameters, after Lowrie; + 1 = Astrophysical Setup Parameters; + 2 = "lab" setup parameters, after Lowrie; Default: 1 .. _rhdtest10_param: @@ -5720,7 +5750,7 @@ Radiation-Hydrodynamics Tests 10 and 11 - I-Front Tests (410/411) radiation-hydrodynamics and chemical ionization," JCP, 2009). ``RadHydroVelocity`` (external) - Initial velocity of ambient gas in the x,y,z directions. Default: 0 (all). + Initial velocity of ambient gas in the x,y,z directions. Default: 0 (all). Example RadHydroVelocity = 0.1 0.1 0.1 ``RadHydroChemistry`` (external) Number of chemical species. 1 implies hydrogen only, 3 implies @@ -5734,19 +5764,19 @@ Radiation-Hydrodynamics Tests 10 and 11 - I-Front Tests (410/411) ``RadHydroTemperature`` (external) Ambient temperature. Default: 1 ``RadHydroIEnergy`` (external) - Ambient internal energy (replaces temperature, if specified). + Ambient internal energy (replaces temperature, if specified). Default: -1 ``RadHydroRadiationEnergy`` (external) Ambient radiation energy. Default: 10 ``RadHydroInitialFractionHII`` (external) - Initial fraction of ionized hydrogen (in relation to all hydrogen). + Initial fraction of ionized hydrogen (in relation to all hydrogen). Default: 0 ``RadHydroHFraction`` (external) Initial fraction of hydrogen (in relation to the total density). - Default: 1 + Default: 1 ``RadHydroInitialFractionHeII`` (external) Initial fraction of helium II (in relation to the total helium). - Default: 0 + Default: 0 ``RadHydroInitialFractionHeIII`` (external) Initial fraction of helium III (in relation to the total helium). Default: 0 @@ -5758,7 +5788,7 @@ Radiation-Hydrodynamics Tests 10 and 11 - I-Front Tests (410/411) Default: 0 ``EtaCenter`` (external) Location of ionization source, in scaled length units, in the x,y,z - directions. Default: 0 (all). + directions. Default: 0 (all). Example EtaCenter = 0.5 0.5 0.5 .. _rhdtest12_param: @@ -5793,10 +5823,10 @@ Radiation-Hydrodynamics Test 12 - HI ionization of a clump (412) ``RadHydroRadiationEnergy`` (external) Ambient radiation energy. Default: 10 ``RadHydroInitialFractionHII`` (external) - Initial fraction of ionized hydrogen (in relation to all hydrogen). + Initial fraction of ionized hydrogen (in relation to all hydrogen). Default: 0 ``ClumpCenter`` (external) - Location of clump center, in cm, in the x,y,z directions. + Location of clump center, in cm, in the x,y,z directions. Default: 1.54285e22 1.018281e22 1.018281e22 ``ClumpRadius`` (external) Radius of clump, in cm. @@ -5835,7 +5865,7 @@ Radiation-Hydrodynamics Test 13 - HI ionization of a steep region (413) ``RadHydroRadiationEnergy`` (external) Ambient radiation energy. Default: 1e-20 ``RadHydroInitialFractionHII`` (external) - Initial fraction of ionized hydrogen (in relation to all hydrogen). + Initial fraction of ionized hydrogen (in relation to all hydrogen). Default: 0 ``EtaCenter`` (external) Center of the dense region (and ionization source), in cm, in the @@ -5872,7 +5902,7 @@ Radiation-Hydrodynamics Tests 14/15 - Cosmological HI ionization (414/415) ``RadHydroRadiationEnergy`` (external) Ambient radiation energy in erg/cm^3. Default: 1.0e-32 ``RadHydroInitialFractionHII`` (external) - Initial fraction of ionized hydrogen (in relation to all hydrogen). + Initial fraction of ionized hydrogen (in relation to all hydrogen). Default: 0 ``RadHydroOmegaBaryonNow`` (external) Default: 0.2 @@ -5881,10 +5911,9 @@ Radiation-Hydrodynamics Tests 14/15 - Cosmological HI ionization (414/415) Default: 0 ``EtaRadius`` (external) Radius of ionization source for test 415, in cells (0 implies a - single-cell source). + single-cell source). Default: 0 ``EtaCenter`` (external) Location of ionization source for test 415, in scaled length units, in the x,y,z directions. Default: 0 (all). Example EtaCenter = 0.5 0.5 0.5 - diff --git a/doc/manual/source/physics/gravity.rst b/doc/manual/source/physics/gravity.rst index ac7096ae5..ae68ac67a 100644 --- a/doc/manual/source/physics/gravity.rst +++ b/doc/manual/source/physics/gravity.rst @@ -2,9 +2,13 @@ Gravity -====================================== +======= -The current implementation of self-gravity in Enzo uses a fast Fourier + +The Multigrid solver +-------------------- + +The default implementation of self-gravity in Enzo uses a fast Fourier technique (`Hockney & Eastwood 1988 `_) to solve Poisson’s equation on the root grid on each timestep. The advantage of using this method is that @@ -24,3 +28,13 @@ number of options for specifying static gravitational fields galactic disks, and point sources). Enzo parameters relating to gravity can be found in :ref:`gravity_parameters`, and a brief description . + +The APM solver +-------------- + +Self-gravity can also be solved the Adaptive Particle-Mesh (APM) technique from +`Passy & Bryan 2014 `_. +The general idea is to split the gravitational force between a long-range component +and one or more short-range components that are non-zero only for a narrow range of wavenumbers. +More details on the algorithm can be found in the paper above. +Enzo parameters related to the APM solver are listed and briefly described in :ref:`gravity_parameters`. \ No newline at end of file diff --git a/doc/manual/source/reference/EnzoPrimaryReferences.rst b/doc/manual/source/reference/EnzoPrimaryReferences.rst index 06063c72f..c714f4839 100644 --- a/doc/manual/source/reference/EnzoPrimaryReferences.rst +++ b/doc/manual/source/reference/EnzoPrimaryReferences.rst @@ -54,7 +54,7 @@ the following two papers: two space dimensions. I - The hydrodynamic algorithms and tests. `__ by Stone and Norman, Astrophysical Journal Supplement Series (ISSN 0067-0049), vol. 80, no. 2, - June 1992, p. 753-790. + June 1992, p. 753-790. `Bibtex Entry `__ The extension of PPM to cosmology can be found here: @@ -88,7 +88,13 @@ The YT paper can be found here: * `yt: A Multi-code Analysis Toolkit for Astrophysical Simulation Data `__, by Turk, M. J.; - Smith, B. D.; Oishi, J. S.; Skory, S.; Skillman, S. W.; Abel, T.; and + Smith, B. D.; Oishi, J. S.; Skory, S.; Skillman, S. W.; Abel, T.; and Norman, M. L. The Astrophysical Journal Supplement, Volume 192, Issue 1, article id. 9 (2011) `Bibtex Entry `__. + +The paper describing the adaptive particle-mesh (APM) gravity solver can be found here: + + * `An Adaptive Particle-mesh Gravity Solver for ENZO `__, + Passy, J. C.; Bryan, G. L. The Astrophysical Journal Supplement, Volume 215, Issue 1, article id. 8, 9 pp. + `Bibtex Entry `__. diff --git a/doc/manual/source/supplementary_info/TestProblems.rst b/doc/manual/source/supplementary_info/TestProblems.rst index 22b84df06..7d56c8c92 100644 --- a/doc/manual/source/supplementary_info/TestProblems.rst +++ b/doc/manual/source/supplementary_info/TestProblems.rst @@ -1,9 +1,9 @@ -Enzo Test Problem Parameters +Enzo Test Problem Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -=================================== =================================== ======= -Directory Parameter File Source -=================================== =================================== ======= +=================================== =================================== ======= +Directory Parameter File Source +=================================== =================================== ======= GravitySolver/BinaryCollapse BinaryCollapse.enzo |link0|_ GravitySolver/GravityTest GravityTest.enzo |link1|_ GravitySolver/GravityStripTest GravityStripTest.enzo |link2|_ @@ -104,7 +104,32 @@ RadiationTransportFLD/TS2_sp TurnerStoneEquil2_sp.enzo |link96| RadiationTransport/PhotonTestAMR PhotonTestAMR.enzo |link97|_ RadiationTransport/PhotonShadowing. PhotonShadowing.enzo |link98|_ RadiationTransport/PhotonTest PhotonTest.enzo |link99|_ -=================================== =================================== ======= +APMGravitySolver/GravityTest/APMCe. APMCenterTest.enzo |link100|_ +APMGravitySolver/GravityTest/APMCo. APMCornerTest.enzo |link101|_ +APMGravitySolver/GravityTest/FastC. FastCenterTest.enzo |link102|_ +APMGravitySolver/GravityTest/FastC. FastCornerTest.enzo |link103|_ +APMGravitySolver/GravityTestSphere. APMSphere0.enzo |link104|_ +APMGravitySolver/GravityTestSphere. APMSphere1.enzo |link105|_ +APMGravitySolver/GravityTestSphere. APMSphere2.enzo |link106|_ +APMGravitySolver/GravityTestSphere. FastSphere0.enzo |link107|_ +APMGravitySolver/GravityTestSphere. FastSphere1.enzo |link108|_ +APMGravitySolver/GravityTestSphere. FastSphere2.enzo |link109|_ +APMGravitySolver/TestOrbit/APM1Ref. APM1RefLevel.enzo |link110|_ +APMGravitySolver/TestOrbit/APM1Ref. APM1RefLevelExtra.enzo |link111|_ +APMGravitySolver/TestOrbit/APM2Ref. APM2RefLevel.enzo |link112|_ +APMGravitySolver/TestOrbit/APM2Ref. APM2RefLevelExtra.enzo |link113|_ +APMGravitySolver/TestOrbit/Fast1Re. Fast1RefLevel.enzo |link114|_ +APMGravitySolver/TestOrbit/Fast1Re. Fast1RefLevelExtra.enzo |link115|_ +APMGravitySolver/TestOrbit/Fast2Re. Fast2RefLevel.enzo |link116|_ +APMGravitySolver/TestOrbit/Fast2Re. Fast2RefLevelExtra.enzo |link117|_ +APMGravitySolver/TestSelfForce/APM. APMNoSubcyce.enzo |link118|_ +APMGravitySolver/TestSelfForce/APM. APMSubcycle.enzo |link119|_ +APMGravitySolver/TestSelfForce/Fas. FastSubcycle.enzo |link120|_ +APMGravitySolver/TestSineWave/APML. APMLongP.enzo |link121|_ +APMGravitySolver/TestSineWave/APMS. APMShortP.enzo |link122|_ +APMGravitySolver/TestSineWave/Fast. FastLongP.enzo |link123|_ +APMGravitySolver/TestSineWave/Fast. FastShortP.enzo |link124|_ +=================================== =================================== ======= .. |link0| replace:: X .. _link0: https://github.com/enzo-project/enzo-dev/tree/master/run/GravitySolver/BinaryCollapse/BinaryCollapse.enzo @@ -306,3 +331,53 @@ RadiationTransport/PhotonTest PhotonTest.enzo |link99| .. _link98: https://github.com/enzo-project/enzo-dev/tree/master/run/RadiationTransport/PhotonShadowing/PhotonShadowing.enzo .. |link99| replace:: X .. _link99: https://github.com/enzo-project/enzo-dev/tree/master/run/RadiationTransport/PhotonTest/PhotonTest.enzo +.. |link100| replace:: X +.. _link100: https://github.com/enzo-project/enzo-dev/tree/master/run/APM/GravityTest/APMCenter/APMCenter.enzo +.. |link101| replace:: X +.. _link101: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTest/APMCorner/APMCorner.enzo +.. |link102| replace:: X +.. _link102: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTest/FastCenter/FastCenter.enzo +.. |link103| replace:: X +.. _link103: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTest/FastCorner/FastCorner.enzo +.. |link104| replace:: X +.. _link104: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzo +.. |link105| replace:: X +.. _link105: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzo +.. |link106| replace:: X +.. _link106: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzo +.. |link107| replace:: X +.. _link107: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzo +.. |link108| replace:: X +.. _link108: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzo +.. |link109| replace:: X +.. _link109: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzo +.. |link110| replace:: X +.. _link110: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzo +.. |link111| replace:: X +.. _link111: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzo +.. |link112| replace:: X +.. _link112: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/APMwRefLevel/APM2RefLevel.enzo +.. |link113| replace:: X +.. _link113: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM2RefLevelExtra.enzo +.. |link114| replace:: X +.. _link114: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzo +.. |link115| replace:: X +.. _link115: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzo +.. |link116| replace:: X +.. _link116: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzo +.. |link117| replace:: X +.. _link117: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzo +.. |link118| replace:: X +.. _link118: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzo +.. |link119| replace:: X +.. _link119: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzo +.. |link120| replace:: X +.. _link120: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzo +.. |link121| replace:: X +.. _link121: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/APM/TestSineWave/APMLongP/APMLongP.enzo +.. |link122| replace:: X +.. _link122: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/APM/TestSineWave/APMShortP/APMShortP.enzo +.. |link123| replace:: X +.. _link123: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/APM/TestSineWave/FastLongP/FastLongP.enzo +.. |link124| replace:: X +.. _link124: https://github.com/enzo-project/enzo-dev/tree/master/run/APMGravitySolver/APM/TestSineWave/FastShortP/FastShortP.enzo diff --git a/doc/manual/source/testproblems/index.rst b/doc/manual/source/testproblems/index.rst index 1b9263e64..d9dafbb6b 100644 --- a/doc/manual/source/testproblems/index.rst +++ b/doc/manual/source/testproblems/index.rst @@ -3,12 +3,12 @@ Enzo Test Problems =================== -The following is a list of the test problems that are available in the +The following is a list of the test problems that are available in the ``run`` subdirectory found in the Enzo repository. These problems are also the same set of problems used in the test suite. They are listed in broad categories following the directory structure. -This list however is not a complete list of all the ProblemTypes that +This list however is not a complete list of all the ProblemTypes that are available in Enzo. The test problem specific parameters can be found in the :ref:`parameters`. @@ -17,13 +17,26 @@ The test problem specific parameters can be found in the :ref:`parameters`. :maxdepth: 2 -* `Cooling`_ +* `APM Gravity Solver`_ + + * `GravityTest `_ + + * `GravityTestSphere `_ + + * `TestOrbit `_ + + * `TestSelfForce `_ + + * `TestSineWave `_ + + +* `Cooling`_ * `CoolingTest_Cloudy`_ - * `CoolingTest_Grackle`_ + * `CoolingTest_Grackle`_ - * `CoolingTest_JHW`_ + * `CoolingTest_JHW`_ * `OneZoneFreefallTest`_ @@ -32,17 +45,17 @@ The test problem specific parameters can be found in the :ref:`parameters`. * `AdiabaticExpansion`_ - * `AMRZeldovichPancake`_ - + * `AMRZeldovichPancake`_ + * `AMRZeldovichPancake_Streaming`_ - * `MHDAdiabaticExpansion_CT`_ - - * `MHDAdiabaticExpansion_Dedner`_ - - * `MHDZeldovichPancake`_ + * `MHDAdiabaticExpansion_CT`_ + + * `MHDAdiabaticExpansion_Dedner`_ - * `MHDZeldovichPancake_2_CT`_ + * `MHDZeldovichPancake`_ + + * `MHDZeldovichPancake_2_CT`_ * `MHDZeldovichPancake_2_Dedner`_ @@ -72,19 +85,19 @@ The test problem specific parameters can be found in the :ref:`parameters`. * `Gravity Solver`_ - * `BinaryCollapse`_ + * `BinaryCollapse`_ - * `BinaryCollapseMHDCT`_ + * `BinaryCollapseMHDCT`_ - * `GravityStripTest`_ + * `GravityStripTest`_ - * `GravityTest`_ + * `GravityTest `_ - * `GravityTestSphere`_ + * `GravityTestSphere `_ - * `MaximumGravityRefinementTest`_ + * `MaximumGravityRefinementTest`_ - * `TestOrbit`_ + * `TestOrbit `_ * `TestOrbitMRP`_ @@ -237,9 +250,9 @@ The test problem specific parameters can be found in the :ref:`parameters`. * `PhotonShadowing`_ * `PhotonTest`_ - - - * `PhotonTestAMR`_ + + + * `PhotonTestAMR`_ * `PhotonTestMultiFrequency`_ @@ -248,7 +261,7 @@ The test problem specific parameters can be found in the :ref:`parameters`. * `CosmoIonization_q05z10`_ * `CosmoIonization_q05z10_sp`_ - + * `CosmoIonization_q05z4`_ * `CosmoIonization_q05z4_sp`_ @@ -286,9 +299,9 @@ The test problem specific parameters can be found in the :ref:`parameters`. * `RadiationStreamY1`_ * `RadiationStreamY1_sp`_ - + * `RadiationStreamZ0`_ - + * `RadiationStreamZ0_sp`_ * `RadiationStreamZ1`_ @@ -308,6 +321,83 @@ The test problem specific parameters can be found in the :ref:`parameters`. * `StarParticle`_ +.. _APM Gravity Solver: + +APM Gravity Solver +~~~~~~~~~~~~~~~~~~ + +.. _APMGravityTest: + +GravityTest +^^^^^^^^^^^ +(Jean-Claude Passy and Greg Bryan, 2014) + +We compute the acceleration of nearly massless particles in a gravitational field created by a heavy central particle. +The dimensions of the root grid are 32x32x32, and we add one static refined grid. +We set up at the center a particle of density ρ = 1.0, and n = 5000 test particles distributed randomly in logr, +where r is the distance from the central particle. +We study two cases: + +* the refined grid covers the region [0.4375; 0.5625] such that the particle is at the center of the subgrid; +* the refined region is [0.5; 0.5625] such that the particle is deposited on the corner of the subgrid. + +.. _APMGravityTestSphere: + +GravityTestSphere +^^^^^^^^^^^^^^^^^ +(Jean-Claude Passy and Greg Bryan, 2014) + +We compute the acceleration field of three specific spherical distributions +which have an analytical solution: + +* constant density profile +* isothermal profile +* Plummer profile + +In each case, the dimensions of the root grid are 32x32x32 and the sphere radius is 0.3. +We allow up to two levels of refinement. + +.. _APMTestOrbit: + +TestOrbit +^^^^^^^^^ +(Jean-Claude Passy and Greg Bryan, 2014) + +The two-body problem with the particles initially in a circular orbit in the x–y plane. + +The central particle has a mass M1 = 1.0 and is located initially at the center of the domain. +The test particle has a mass M2 = 0.1 and is placed at a distance a = 0.3 from the central particle. + +We study four different cases: + +* particles in different levels with subcycling; +* particles in different levels without subcycling; +* particles in same level with subcycling; +* particles in same level without subcycling; + +.. _APMTestSelfForce: + +TestSelfForce +^^^^^^^^^^^^^ +(Jean-Claude Passy and Greg Bryan, 2014) + +We compute the trajectory of an isolated particle that is given an initial velocity. +If the particle does not experience any self force, its velocity should remain constant. +The root grid resolution is 16x16x16 zones and there are three static levels of refinement with coordinates [0.1875; 0.8125], [0.3125; 0.6875], and [0.40625; 0.59375]. +The particle of mass is initially located on level 0 at coordinates (0.15, 0.15, 0.15), and is given a velocity (1.0, 1.0, 1.0). +The system is evolved until t = 0.4, and we investigate two cases (with and without subcycling). + +.. _APMTestSineWave: + +TestSineWave +^^^^^^^^^^^^ +(Jean-Claude Passy and Greg Bryan, 2014) + +The only test with periodic boundary conditions. +We compute the acceleration field created by a sinusoidal baryonic density field, for a long and a short period. + +The root grid resolution is 64x64x64 zones and ee use two static levels of refinement with coordinates [0.34375; 0.65625] and [0.421875; 0.578125]. + .. _CoolingProblems: Cooling @@ -317,25 +407,25 @@ Cooling CoolingTest_Cloudy ^^^^^^^^^^^^^^^^^^ -This test problem will set up a single grid that varies smoothly in density, -metallicity, and temperature, then iterate the rate equations in the chemisty -module for 50,000 years with hydro deactivated. The code will make an -output at the end of the run that includes the cooling time. This problem +This test problem will set up a single grid that varies smoothly in density, +metallicity, and temperature, then iterate the rate equations in the chemisty +module for 50,000 years with hydro deactivated. The code will make an +output at the end of the run that includes the cooling time. This problem type did not exist in Enzo 1.5, so there is no comparison. The cooling tests will run in a few minutes on a single processor. The three parameter files are: -CoolingTest_Cloudy.enzo - uses Cloudy cooling along with the MultiSpecies = 1 chemistry. -The input data provided is a three dimensional table that varies in density, metallicity, +CoolingTest_Cloudy.enzo - uses Cloudy cooling along with the MultiSpecies = 1 chemistry. +The input data provided is a three dimensional table that varies in density, metallicity, and temperature. Cooling data files: primordial_cie.dat - CIE cooling rates for atomic H and He taken from Black (1981). solar_2008_3D_metals.h5 - input data for Cloudy cooling. -The script plot.py will plot cooling rates from the cooling test -along with the H/He cooling rate from Black (1981) and the Z = Zsun +The script plot.py will plot cooling rates from the cooling test +along with the H/He cooling rate from Black (1981) and the Z = Zsun rate from Sarazin & White (1987) @@ -343,24 +433,24 @@ rate from Sarazin & White (1987) CoolingTest_Grackle ^^^^^^^^^^^^^^^^^^^ -This test problem will set up a single grid that varies smoothly in density, -metallicity, and temperature, then iterate the rate equations in the chemisty -module for 50,000 years with hydro deactivated. The code will make an +This test problem will set up a single grid that varies smoothly in density, +metallicity, and temperature, then iterate the rate equations in the chemisty +module for 50,000 years with hydro deactivated. The code will make an output at the end of the run that includes the cooling time. The cooling tests will run in a few minutes on a single processor. The three parameter files are: -CoolingTest_Grackle.enzo - uses Grackle cooling along with the +CoolingTest_Grackle.enzo - uses Grackle cooling along with the non-equilibrium atomic H/He chemistry. Cooling data files: -primordial_cie.dat - CIE cooling rates for atomic H and He taken from +primordial_cie.dat - CIE cooling rates for atomic H and He taken from Black (1981). CloudyData_UVB=HM2012.h5 - input data for Grackle cooling. -The script plot.py will plot cooling rates from the cooling test -along with the H/He cooling rate from Black (1981) and the Z = Zsun +The script plot.py will plot cooling rates from the cooling test +along with the H/He cooling rate from Black (1981) and the Z = Zsun rate from Sarazin & White (1987) @@ -368,41 +458,41 @@ rate from Sarazin & White (1987) CoolingTest_JHW ^^^^^^^^^^^^^^^ -This test problem will set up a single grid that varies smoothly in density, -metallicity, and temperature, then iterate the rate equations in the chemisty -module for 50,000 years with hydro deactivated. The code will make an -output at the end of the run that includes the cooling time. This problem +This test problem will set up a single grid that varies smoothly in density, +metallicity, and temperature, then iterate the rate equations in the chemisty +module for 50,000 years with hydro deactivated. The code will make an +output at the end of the run that includes the cooling time. This problem type did not exist in Enzo 1.5, so there is no comparison. The cooling tests will run in a few minutes on a single processor. The three parameter files are: -CoolingTest_JHW.enzo - uses John Wise's metal cooling along with +CoolingTest_JHW.enzo - uses John Wise's metal cooling along with the MultiSpecies = 1 chemitry. Cooling data files: -primordial_cie.dat - CIE cooling rates for atomic H and He taken from +primordial_cie.dat - CIE cooling rates for atomic H and He taken from Black (1981). -cool_rates.in - analytic cooling rates for Z = 0.5 and 1 Zsun from +cool_rates.in - analytic cooling rates for Z = 0.5 and 1 Zsun from Sarazin & White (1987). metal_cool.dat - input data for John Wise's metal cooling. The script plot.py will plot cooling rates from the cooling test -along with the H/He cooling rate from Black (1981) and the Z = Zsun +along with the H/He cooling rate from Black (1981) and the Z = Zsun rate from Sarazin & White (1987) .. _OneZoneFreefallTest: OneZoneFreefallTest ^^^^^^^^^^^^^^^^^^^ -This test problem will set up a 2D grid varying in energy and metallicity. -All points have the same density, which evolves according to the analytical -solution for free-fall collapse. The timestep is calculated as a fraction of -the free-fall time. Since the timestep continually decreases, outputs are -done on cycles. This test problem can be used to test chemistry and +This test problem will set up a 2D grid varying in energy and metallicity. +All points have the same density, which evolves according to the analytical +solution for free-fall collapse. The timestep is calculated as a fraction of +the free-fall time. Since the timestep continually decreases, outputs are +done on cycles. This test problem can be used to test chemistry and cooling routines. The script, plot.py, will create plots of n vs. T (and Tdust), n -vs. f_H2, and n vs. t_cool/t_dyn. If using H2 formation on +vs. f_H2, and n vs. t_cool/t_dyn. If using H2 formation on dust grains, set dust=True on line 10. Run this script like this: python plot.py OneZoneFreefallTest.enzo @@ -419,9 +509,9 @@ AdiabaticExpansion A test for time-integration accuracy of the expansion terms (Bryan thesis 1996, Sect. 3.3.3). -.. _AMRZeldovichPancake: +.. _AMRZeldovichPancake: -AMRZeldovichPancake +AMRZeldovichPancake ^^^^^^^^^^^^^^^^^^^ This test simulates a collapsing sinusoidal cosmological pertubation @@ -474,9 +564,9 @@ Adiabatic expansion test for MHD, using Athena CT. This test differs from the PPM Adiabatic Expansion by the increased initial temperature. The extremely low floor on the PPM version makes it a poor test, since the thermal expansion is dominated by the temperature floor, rather than -physical integration. +physical integration. -This test is not entirely uniform for two reasons. +This test is not entirely uniform for two reasons. First is self gravity (actually off in this version) which causes issues at the corners of the domain as well as subgrid boundary. The second is the time-interpolation in the boundary for the subgrid, which @@ -492,9 +582,9 @@ Adiabatic expansion test for MHD, using Dedner. This test differs from the PPM Adiabatic Expansion by the increased initial temperature. The extremely low floor on the PPM version makes it a poor test, since the thermal expansion is dominated by the temperature floor, rather than -physical integration. +physical integration. -This test is not entirely uniform for two reasons. +This test is not entirely uniform for two reasons. First is self gravity (actually off in this version) which causes issues at the corners of the domain as well as subgrid boundary. The second is the time-interpolation in the boundary for the subgrid, which @@ -507,16 +597,16 @@ MHDZeldovichPancake ^^^^^^^^^^^^^^^^^^^ -.. _MHDZeldovichPancake_2_CT: +.. _MHDZeldovichPancake_2_CT: MHDZeldovichPancake_2_CT ^^^^^^^^^^^^^^^^^^^^^^^^ -This is another iteration of Zel'Dovich pancake. This is tuned to almost -reproduce the result from Collins et al 2010, as well as the Dedner run in +This is another iteration of Zel'Dovich pancake. This is tuned to almost +reproduce the result from Collins et al 2010, as well as the Dedner run in run/Cosmology/MHDZeldovichPancake_2_Dedner Slight differences with the method paper exist due to the uniform initial -distribution in the method paper. +distribution in the method paper. Neither this nor the Dedner version use Dual Energy Formalism, in order to match the temperature field as well as possible. @@ -524,12 +614,12 @@ the temperature field as well as possible. MHDZeldovichPancake_2_Dedner ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This is another iteration of Zel'Dovich pancake. This is tuned to almost -reproduce the result from Collins et al 2010, as well as the Dedner run in +This is another iteration of Zel'Dovich pancake. This is tuned to almost +reproduce the result from Collins et al 2010, as well as the Dedner run in run/Cosmology/MHDZeldovichPancake_2_Dedner Slight differences with the method paper exist due to the uniform initial -distribution in the method paper. +distribution in the method paper. Neither this nor the Dedner version use Dual Energy Formalism, in order to match the temperature field as well as possible. @@ -636,7 +726,7 @@ To run the simulation: ReionizationHydro ^^^^^^^^^^^^^^^^^ -This is a cosmology simulation that simulates reionization using the +This is a cosmology simulation that simulates reionization using the convention, non-radiative star formation and feedback and a Haardt & Madau background. It will run on 2 processors in about 20 minutes. @@ -649,7 +739,7 @@ mpirun -np 2 ./enzo.exe -d ReionizationHydro.enzo ReionizationRadHydro ^^^^^^^^^^^^^^^^^^^^ -This is a cosmology simulation that simulates reionization using the +This is a cosmology simulation that simulates reionization using the ray tracing radiation transfer method with radiating star particles and a Haardt & Madau background. It will run on 2 processors in about 40 minutes. @@ -664,7 +754,7 @@ mpirun -np 2 ./enzo.exe -d ReionizationRadHydro.enzo DrivenTurbulence3D ~~~~~~~~~~~~~~~~~~ -Unless hydromethod == 4 this will do hydrodynamic turbulence. +Unless hydromethod == 4 this will do hydrodynamic turbulence. Tom Abel 2009 This can do fixed force pattern driving as well as decaying turbulence set ups. @@ -724,7 +814,7 @@ MHDCT. A shorter test to ensure MHDCT runs. This runs in less than 5 minutes. GravityStripTest ^^^^^^^^^^^^^^^^ -.. _GravityTest: +.. _FastGravityTest: GravityTest ^^^^^^^^^^^ @@ -736,7 +826,7 @@ of the box, randomly spaced in log radius from the center, and randomly placed in angle. A single small step is taken, and the velocity is then divided by the timestep to measure the acceleration. A single subgrid is placed in the center from 0.4375 to 0.5625 -(in units where the box size is 1.0). +(in units where the box size is 1.0). This tests the acceleration of the particles from a single point mass and so can be directed compared to the r^-2 expected @@ -744,9 +834,9 @@ result. An output file is generated, called TestGravityCheckResults.out, which contains four columns with one entry for each of the 5000 particles. The columns are the radius (in units of the cell length of the most refined grid), the tangential component -of the measured force, as computed by the code, +of the measured force, as computed by the code, the radial component of the computed force, and finally -the "true" (unsoftened) force. +the "true" (unsoftened) force. The tangential component of the force should be zero; the radial component should follow the r^-2 law, but is softened @@ -767,7 +857,7 @@ with force errors at small and large radii); however, the problem with a bitwise comparison is that the positions of the 5000 particles are random (with no setable seed). -.. _GravityTestSphere: +.. _FastGravityTestSphere: GravityTestSphere ^^^^^^^^^^^^^^^^^ @@ -791,13 +881,13 @@ This test must be run on 2 cores, otherwise the problem isn't triggered. This test is to ensure that MaximumGravityRefinement is functional. As of this writing (2014-07-12) when MaximumGravityRefinement < MaximumRefinementLevel, the -wrong SiblingList is used in PrepareDensityField. +wrong SiblingList is used in PrepareDensityField. The current test creates 2 grids on Level 1, and one grid on Level 2, in which case the code tries to iterate over the SiblingList for level=1 when on level=2. This causes a seg fault. -.. _TestOrbit: +.. _FastTestOrbit: TestOrbit ^^^^^^^^^ @@ -823,8 +913,8 @@ Orbit Test Problem with MRPs (MustRefineParticles) NOTE: This version of the parameter file writes out the gravitational potential, and is intended -to be used with run/TestOrbit/make_TE_plot.py -to make a graph of total particle energy as a +to be used with run/TestOrbit/make_TE_plot.py +to make a graph of total particle energy as a function of orbit! @@ -843,7 +933,7 @@ This test simulates a blastwave in the free expansion phase. In the initial setup, the interior region has a uniform density and a linearly increasing radial velocity. The blastwave should advect outwards, and create a high entropy shell and have little oscillations -in the shock. +in the shock. This test runs to completion and creates 41 outputs. This test problem is new for version 2.0. It uses the new hydro_rk solver. @@ -857,10 +947,10 @@ InteractingBlastWaves ^^^^^^^^^^^^^^^^^^^^^ Two interacting blast waves -This is the first test problem in Woodward & Colella (1984), -JCP, 54, 115. With the outer tenths of the domain +This is the first test problem in Woodward & Colella (1984), +JCP, 54, 115. With the outer tenths of the domain overpressurized, two blast waves move in toward the center. The -boundaries are reflecting. One can see the solution by ATHENA in +boundaries are reflecting. One can see the solution by ATHENA in Stone et al. (2008), ApJS, 178, 137. .. _PressurelessCollapse: @@ -1023,11 +1113,11 @@ AMRShockPool2D Athena-RayleighTaylor ^^^^^^^^^^^^^^^^^^^^^ - -classic Raleigh Taylor setup with sharp contact + +classic Raleigh Taylor setup with sharp contact this file should work with all hydro methods -compare to +compare to http://www.astro.princeton.edu/~jstone/tests/rt/rt.html .. _DoubleMachReflection: @@ -1073,8 +1163,8 @@ The initial setup is taken from Truelove & McKee, 1999, ApJS, 120, HDMHD2DCheckOddEvenCouplingOfRiemannSolver ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Standing shock with slight density perturbation. -Look at the y-velocity to check for the effect. +Standing shock with slight density perturbation. +Look at the y-velocity to check for the effect. It is subtle because we use a small perturbation. define problem @@ -1107,7 +1197,7 @@ KelvinHelmholtz The KH Test problem creates two fluids moving antiparallel to each other in a periodic 2D grid (inner fluid and outer fluid). The inside fluid has a higher density than the outside fluid. There is a slight ramp region -in density and x-velocity connecting the two regions so there are no +in density and x-velocity connecting the two regions so there are no discontinuities in the flow. The y-velocity is perturbed with small sinusoidal perturbation. As the flows shear past each other, the KH instability is excited, which develops over time. This test watches the evolution of @@ -1188,7 +1278,7 @@ A 2d explosion test problem SedovBlastAMR ^^^^^^^^^^^^^ -AMR version of SedovBlast +AMR version of SedovBlast .. _ShockPool2D: ShockPool2D @@ -1200,22 +1290,22 @@ ShockPool2D ValidatedNonlinearKelvinHelmholtz ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Implements initial condition generator for +Implements initial condition generator for http://arxiv.org/abs/1509.03630 A Validated Nonlinear Kelvin-Helmholtz Benchmark for Numerical Hydrodynamics -Daniel Lecoanet, Michael McCourt, Eliot Quataert, Keaton J. Burns, +Daniel Lecoanet, Michael McCourt, Eliot Quataert, Keaton J. Burns, Geoffrey M. Vasil, Jeffrey S. Oishi, Benjamin P. Brown, James M. Stone, Ryan M. O'Leary (2015) -Note, this has not been tested much. -It uses the machinery for the MHD2D tests in hydro_rk. -It should also work with PPM (i.e. HydroMethod = 0) but is not setup to do Zeus (HydroMethod=1 tests). -However, HydroMethod=3 offers many options for Riemann Solvers and Slope limiting which may be interesting to test. +Note, this has not been tested much. +It uses the machinery for the MHD2D tests in hydro_rk. +It should also work with PPM (i.e. HydroMethod = 0) but is not setup to do Zeus (HydroMethod=1 tests). +However, HydroMethod=3 offers many options for Riemann Solvers and Slope limiting which may be interesting to test. To run in parallel keep the ParallelRootgridIO = 1 on. This is a code test for a limit high resolution shock captruing codes are not often optimized for. It is useful to see whether your choice of hydro method has sufficient diffusivity to give behave sensibly in -a convergence study. +a convergence study. .. _Hydro/Hydro-3D: @@ -1254,10 +1344,10 @@ may vary for the amount of wallclock time necessary. Athena-RayleighTaylor3D ^^^^^^^^^^^^^^^^^^^^^^^ -classic Raleigh Taylor setup with sharp contact +classic Raleigh Taylor setup with sharp contact this file should work with all hydro methods -compare to +compare to http://www.astro.princeton.edu/~jstone/tests/rt/rt.html .. _CollapseTestNonCosmological: @@ -1265,20 +1355,20 @@ http://www.astro.princeton.edu/~jstone/tests/rt/rt.html CollapseTestNonCosmological ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This test problem initializes a constant density sphere at the center of the box -with radius of 0.15 of the box width. The sphere is in pressure equilibrium with -its surroundings. The sphere will collapse dynamically and reach its peak density -at t ~ 5.2 in code units. Radiative cooling is turned off, so the sphere will bounce +This test problem initializes a constant density sphere at the center of the box +with radius of 0.15 of the box width. The sphere is in pressure equilibrium with +its surroundings. The sphere will collapse dynamically and reach its peak density +at t ~ 5.2 in code units. Radiative cooling is turned off, so the sphere will bounce and reach an equilibrium state. -This test runs to completion (t = 7) and produces 71 outputs in roughly an hour -on a single processor. In plot.py, we plot the evolution of the peak density versus +This test runs to completion (t = 7) and produces 71 outputs in roughly an hour +on a single processor. In plot.py, we plot the evolution of the peak density versus time create density projections for each output. -Note for comparing with Enzo 1.5 - By default, Enzo 2.0 performs 4 iterations of -the multigrid gravity solver (configurable with the PotentialIterations parameter). -However, the default number of potential iteration in Enzo 1.5 is 0 and there is -no parameter to change this. For a direct comparison, Enzo 1.5 must be compiled +Note for comparing with Enzo 1.5 - By default, Enzo 2.0 performs 4 iterations of +the multigrid gravity solver (configurable with the PotentialIterations parameter). +However, the default number of potential iteration in Enzo 1.5 is 0 and there is +no parameter to change this. For a direct comparison, Enzo 1.5 must be compiled with MAX_POTENTIAL_ITERATIONS (in macros_and_parameters.h) set to 4. .. _CollideTest: @@ -1318,23 +1408,23 @@ NFWCoolCoreCluster ^^^^^^^^^^^^^^^^^^ The NFW Cool-Core Cluster is a simulation of the cooling flow in an idealized cool-core cluster that resembles Perseus cluster. It can be a test for cooling, and -maybe gravity too. +maybe gravity too. The default set up is with a root grid of 64^3, a maximum refinement level of 12, and MinimumMassForRefinementLevelExponent of -0.2 (for better resolution, use -1.2) which can be changed based on the resolution one needs. The default set up has a static gravity and no self-gravity of the gas since the latter -is much smaller than the gravity of the dark matter and does not change much during the +is much smaller than the gravity of the dark matter and does not change much during the early stage of the cooling flow evolution. -As the cooling catastrophe happens, the temperature drops to the bottom of the cooling -function ~ 10^4 K in the center within ~1kpc with the default resolution. The size of +As the cooling catastrophe happens, the temperature drops to the bottom of the cooling +function ~ 10^4 K in the center within ~1kpc with the default resolution. The size of the region becomes smaller with higher resolution. The projected gas density shows a disk of size ~ 1kpc (inside the cooling catastrophe -region) at late times along z axis which is the direction of -the initial angular momentum of the gas. +region) at late times along z axis which is the direction of +the initial angular momentum of the gas. .. _NohProblem3D: @@ -1386,18 +1476,18 @@ angular momentum in Enzo. The test sets up a rotating gas cyclinder in the center of the box at 0.5 0.5 0.5 with an overdensity of 200. The default set up is with a root grid -of 32^3 and a single level of refinement. +of 32^3 and a single level of refinement. The cyclinder collapses towards its center and oscillates before -settling. +settling. The results signify correctness if the net change in the total angular momentum of the system is low (< 5%). The percentage change per output should be less than 1% and should decrease over time as the collapse -reaches equilibrium. +reaches equilibrium. In plots.py, we image slices in the x-direction and plot the angular -momentum evolution of the system. +momentum evolution of the system. .. _RotatingSphere: @@ -1431,24 +1521,24 @@ From Run: Ji-hoon Kim, July 2010 -This test sets up an one-dimensional Riemann problem for MHD, and has become a useful -standard test for any MHD solver. Detailed description of the initial set up can be -found in the papers above. This test problem is new for enzo2.0. It uses the new +This test sets up an one-dimensional Riemann problem for MHD, and has become a useful +standard test for any MHD solver. Detailed description of the initial set up can be +found in the papers above. This test problem is new for enzo2.0. It uses the new Stanford hydro_rk solver. -This test runs to completion while generating 12 outputs, and scripts.py will -produce the plots for Density, x-velocity, By, Internal Energy for the last snapshot -(t=0.1). This last snapshot should be compared to figure 18 from Figure 2 of Brio & +This test runs to completion while generating 12 outputs, and scripts.py will +produce the plots for Density, x-velocity, By, Internal Energy for the last snapshot +(t=0.1). This last snapshot should be compared to figure 18 from Figure 2 of Brio & Wu (1988) or Figure 15 of Wang & Abel (2009) -Success in test_briowu.py is determined by nearly exact match (5e-3) in Density and By. +Success in test_briowu.py is determined by nearly exact match (5e-3) in Density and By. .. _BrioWu-MHD-1D-MHDCT: BrioWu-MHD-1D-MHDCT ^^^^^^^^^^^^^^^^^^^ -This also serves as an Example of how to do 1D HD/MHD tests with the myriad +This also serves as an Example of how to do 1D HD/MHD tests with the myriad of shock tube problems defined in the literature .. _CR-ShockTube: @@ -1466,8 +1556,8 @@ See Pfrommer et al 2006 for information on the analytic sol'tn MHD_Metal_Advection_CT ^^^^^^^^^^^^^^^^^^^^^^ Square wave advection with a single species field. -The metals are offset by 0.25 from the density. -python plot.py will make a plot. +The metals are offset by 0.25 from the density. +python plot.py will make a plot. .. _MHD_Metal_Advection_Dedner: @@ -1489,7 +1579,7 @@ LoopAdvection_CT Advection of a magnetic field loop. Originally described by Gardiner & Stone 2005 (Journal of Computational Physics, 205,509). The multidimensional MHD analogue of a square wave advection test, -the field loop severely deforms for many CT schemes. +the field loop severely deforms for many CT schemes. .. _LoopAdvection_Dedner: @@ -1498,7 +1588,7 @@ LoopAdvection_Dedner Advection of a magnetic field loop. Originally described by Gardiner & Stone 2005 (Journal of Computational Physics, 205,509). The multidimensional MHD analogue of a square wave advection test, -the field loop severely deforms for many CT schemes. +the field loop severely deforms for many CT schemes. .. _MHD2DRotorTest: @@ -1507,8 +1597,8 @@ MHD2DRotorTest From G. Toth, J. Comput. Phys. 161 (2000) 605 -Initially discussed in - D. Balsara & D. Spicer, J. Comput. Phys. 149, 270292 (1999) +Initially discussed in + D. Balsara & D. Spicer, J. Comput. Phys. 149, 270292 (1999) Run: dcollins, July 2010 @@ -1524,10 +1614,10 @@ useful comparison. Visual comparison to the plots in Toth (2000) shows that the general morphology and extent of the Alfven wave is similar. Round contours in the mach number field indicate solid body rotation, without the artifacts seen in some other -solvers. +solvers. Success in test_rotor.py is determined by nearly exact match (1e-12) in L1 norm between -Density, Bx, P, and Mach number. +Density, Bx, P, and Mach number. This test generates 11 outputs, and snapshots for the 4 above fields for each snapshot. The 11th snapshot should be compared to figure 18 from Toth (2000) @@ -1557,7 +1647,7 @@ for complete suppression, but one does see a severe reduction in growth rate and secondary instability. Fun things to try include reducing the field strength and changing the -direction! +direction! .. _SedovBlast-MHD-2D-Fryxell: @@ -1569,30 +1659,30 @@ From Run: Ji-hoon Kim, July 2010 -This test sets up a two-dimensional blast wave problem for MHD. While the initial -condition essentially describes a circular overpressurized region in a low-pressure -magnetized medium, more detailed description of the initial set up can be found in -the papers above. This test problem is new for enzo2.0. It uses the new Stanford -hydro_rk solver. +This test sets up a two-dimensional blast wave problem for MHD. While the initial +condition essentially describes a circular overpressurized region in a low-pressure +magnetized medium, more detailed description of the initial set up can be found in +the papers above. This test problem is new for enzo2.0. It uses the new Stanford +hydro_rk solver. -Unfortunately for some users, some of the key parameters are hard-coded in -Grid_MHD2DTestInitializeGrid.C. Depending on B-field values, this test can be a -pure Sedov blast wave problem, or a Gardiner blast wave problem. The current -parameter will give Sedov blast wave solution. +Unfortunately for some users, some of the key parameters are hard-coded in +Grid_MHD2DTestInitializeGrid.C. Depending on B-field values, this test can be a +pure Sedov blast wave problem, or a Gardiner blast wave problem. The current +parameter will give Sedov blast wave solution. -(1) Setting LowerBx=LowerBy=0 will give the traditional Sedov test - with no B-field, essentially very similar to SedovBlast-AMR.enzo; +(1) Setting LowerBx=LowerBy=0 will give the traditional Sedov test + with no B-field, essentially very similar to SedovBlast-AMR.enzo; but with different hydro solver (Stanford HD/MHD) -(2) Setting LowerBx=LowerBy=5 will give the Sedov blast with the +(2) Setting LowerBx=LowerBy=5 will give the Sedov blast with the presence of B-field, very similar to SedovBlast-MHD-2D-Gardiner.enzo; but the exact setup is somewhat different (see the code) -This test runs to completion while generating 12 outputs, and scripts.py will -produce the plots and slices for Density and Pressure of the last snapshot (t=0.05). +This test runs to completion while generating 12 outputs, and scripts.py will +produce the plots and slices for Density and Pressure of the last snapshot (t=0.05). This last snapshot should be compared to Figure 29 and 30 of Fryxell (2000). -Success in test_fryxell.py is determined by nearly exact match (3e-5) in Density and -Pressure. +Success in test_fryxell.py is determined by nearly exact match (3e-5) in Density and +Pressure. .. _SedovBlast-MHD-2D-Gardiner: @@ -1604,23 +1694,23 @@ From Run: Ji-hoon Kim, July 2010 -This test sets up a two-dimensional blast wave problem for MHD, and has become a useful -standard test for any MHD solver. While the initial condition essentially describes -a circular overpressurized region in a low-pressure magnetized medium, more detailed -description of the initial set up can be found in the papers above. This test problem -is new for enzo2.0. It uses the new Stanford hydro_rk solver. +This test sets up a two-dimensional blast wave problem for MHD, and has become a useful +standard test for any MHD solver. While the initial condition essentially describes +a circular overpressurized region in a low-pressure magnetized medium, more detailed +description of the initial set up can be found in the papers above. This test problem +is new for enzo2.0. It uses the new Stanford hydro_rk solver. -Unfortunately for some users, most of the key parameters are hard-coded in -Grid_MHD2DTestInitializeGrid.C. With zero B-field, this test should be a pure Sedov -blast wave problem. +Unfortunately for some users, most of the key parameters are hard-coded in +Grid_MHD2DTestInitializeGrid.C. With zero B-field, this test should be a pure Sedov +blast wave problem. -This test runs to completion while generating 12 outputs, and scripts.py will -produce the plots for Density, x-velocity, By, Internal Energy for the last snapshot +This test runs to completion while generating 12 outputs, and scripts.py will +produce the plots for Density, x-velocity, By, Internal Energy for the last snapshot (t=0.02). This last snapshot should be compared to Figure 13 of Gardiner & Stone (2005) or Figure 16 of Wang & Abel (2009) -Success in test_gardiner.py is determined by nearly exact match (3e-5) in Density, -Pressure, Bx, and By. +Success in test_gardiner.py is determined by nearly exact match (3e-5) in Density, +Pressure, Bx, and By. .. _Wengen2-CollidingFlow: @@ -1630,7 +1720,7 @@ Wengen 2 colliding flow Reference: http://www-theorie.physik.unizh.ch/~agertz/Wengen_2/Code_tests.html Tom Abel September 2010 -Also works with magnetic fields. +Also works with magnetic fields. .. _MHD/3D: @@ -1650,7 +1740,7 @@ MHD/HD turbulence problem with stochastic forcing with subgrid-scale (SGS) turbu Philipp Grete 2014 Typical "turbulence-in-a-box" problem with non-static driving field. -For details on stochastic forcing, see Schmidt et al. 2009 A&A 494, 127-145 +For details on stochastic forcing, see Schmidt et al. 2009 A&A 494, 127-145 http://dx.doi.org/10.1051/0004-6361:200809967 For details on the SGS model, see Grete et al. (2017) Phys. Rev. E. 95 033206 https://dx.doi.org/10.1103/PhysRevE.95.033206 @@ -1722,13 +1812,13 @@ PhotonTestMultiFrequency ^^^^^^^^^^^^^^^^^^^^^^^^ This test is derived from the PhotonTest problem which is itself based on the classical HII region expansion in a uniform -static medium similar to Test 1 in Iliev et al. (2006). Rather than -a mono-chromatic source this source contains 7 frequency bins from 0.5 eV +static medium similar to Test 1 in Iliev et al. (2006). Rather than +a mono-chromatic source this source contains 7 frequency bins from 0.5 eV up to 100 eV. It can be used to test the multi-frequency photon solver. In a separate subdirectory is the optically thin version (OT) which runs with H2 and HM dissociation run in optically thin mode. -This test runs with Grackle. +This test runs with Grackle. .. _RadiationTransportFLD: @@ -1875,16 +1965,14 @@ StarParticle ~~~~~~~~~~~~ This test places a single star particle in the center of a box with uniform -gas density and thermal energy. The gas is initially at rest. The particle -will then produce feedback according to the method set for -StarParticleFeedback. +gas density and thermal energy. The gas is initially at rest. The particle +will then produce feedback according to the method set for +StarParticleFeedback. -By default, the star particle produces feedback with method 14, kinetic -feedback. An inital timestep is set to account for the large bulk velocities -created by the feedback event in the first timestep. +By default, the star particle produces feedback with method 14, kinetic +feedback. An inital timestep is set to account for the large bulk velocities +created by the feedback event in the first timestep. The particle is also set to be at rest by default, but it can be given a motion -relative to the gas with the parameter TestStarParticleStarVelocity = vx vy vz, +relative to the gas with the parameter TestStarParticleStarVelocity = vx vy vz, where vx, vy and vz have units of km/s. - - diff --git a/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzo b/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzo new file mode 100644 index 000000000..cab3e03eb --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test Problem - APM +# +# define problem +# +ProblemType = 123 // Gravity test - APM +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +PressureFree = 1 // turn off pressure +S2ParticleSize = 3.4 +GravityResolution = 1.0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +# +TestGravityCentralParticlePosition = 0.5 0.5 0.5 +TestGravityNumberOfParticles = 5000 +TestGravitySubgridLeft = 0.4375 // start of subgrid +TestGravitySubgridRight = 0.5625 // end of subgrid +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +HydroMethod = 0 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to 2 levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzotest b/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzotest new file mode 100644 index 000000000..8e253bb47 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzotest @@ -0,0 +1,13 @@ +name = 'APMCenterTest' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTest/APMCenterTest/APMGravityTest__test_gravity.py b/run/APMGravitySolver/GravityTest/APMCenterTest/APMGravityTest__test_gravity.py new file mode 100644 index 000000000..b472f869a --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCenterTest/APMGravityTest__test_gravity.py @@ -0,0 +1,41 @@ +import glob + +from yt.mods import * +from yt.testing import * +from yt.utilities.answer_testing.framework import \ + AnswerTestingTest, \ + sim_dir_load +from yt.frontends.enzo.answer_testing_support import \ + requires_outputlog + +_pf_name = os.path.basename(os.path.dirname(__file__)) + ".enzo" +_dir_name = os.path.dirname(__file__) + + +class TestAPMGravityTest(AnswerTestingTest): + _type_name = "APMGravityTest" + _attrs = () + + def __init__(self): + self.ds = None + + def run(self): + + rmsError_list = [] + for f in glob.glob('TestGravityCheckResults*'): + Data = np.loadtxt(f) + + radius = Data[:, 4] + ForceRadialComputed = Data[:, 6] + ForceRadialTrue = Data[:, 7] + + Error = (ForceRadialComputed-ForceRadialTrue)/ForceRadialTrue + indices = np.where(radius > 0.4) + rmsError_list.append(np.std(Error[indices])) + + return sum(sigma**2 for sigma in rmsError_list)**0.5 + + +@requires_outputlog(_dir_name, _pf_name) +def test_gravity_test(): + yield TestAPMGravityTest() diff --git a/run/APMGravitySolver/GravityTest/APMCenterTest/make_plot.py b/run/APMGravitySolver/GravityTest/APMCenterTest/make_plot.py new file mode 100644 index 000000000..9525113a6 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCenterTest/make_plot.py @@ -0,0 +1,26 @@ +import numpy as na +import matplotlib.pyplot as plt +import glob + + +legend_added = False +for f in glob.glob('TestGravityCheckResults*'): + Data = na.loadtxt(f) + + # Read in data from text file produced by code + radius = Data[:,4] + ForceTangentialComputed = Data[:,5] + ForceRadialComputed = Data[:,6] + ForceRadialTrue = Data[:,7] + + plt.loglog(radius, ForceRadialComputed, 'b', label='Frad', ls='None', marker='+') + plt.loglog(radius, ForceRadialTrue, 'k', label='Frad_true', ls='None', marker='.') + plt.loglog(radius, ForceTangentialComputed, 'm', label='Ftang', ls='None', marker='.') + if not legend_added: + plt.legend() + legend_added = True + +plt.xlabel('r (cells)') +plt.ylabel('Force') +plt.axis([5e-3,0.5,1e-4,1e3]) +plt.savefig('GravityTest.png') diff --git a/run/APMGravitySolver/GravityTest/APMCenterTest/notes.txt b/run/APMGravitySolver/GravityTest/APMCenterTest/notes.txt new file mode 100644 index 000000000..b34c43c37 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCenterTest/notes.txt @@ -0,0 +1 @@ +Running APM solver with central particle at the center of the subgrid diff --git a/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzo b/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzo new file mode 100644 index 000000000..1f46c72a4 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test Problem - APM +# +# define problem +# +ProblemType = 123 // Gravity test - APM +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +PressureFree = 1 // turn off pressure +S2ParticleSize = 3.4 +GravityResolution = 1.0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +# +TestGravityCentralParticlePosition = 0.5 0.5 0.5 +TestGravityNumberOfParticles = 5000 +TestGravitySubgridLeft = 0.5 // start of subgrid +TestGravitySubgridRight = 0.5625 // end of subgrid +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +HydroMethod = 0 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to 2 levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzotest b/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzotest new file mode 100644 index 000000000..28f0c888b --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzotest @@ -0,0 +1,13 @@ +name = 'APMCornerTest' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTest/APMCornerTest/make_plot.py b/run/APMGravitySolver/GravityTest/APMCornerTest/make_plot.py new file mode 100644 index 000000000..9525113a6 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCornerTest/make_plot.py @@ -0,0 +1,26 @@ +import numpy as na +import matplotlib.pyplot as plt +import glob + + +legend_added = False +for f in glob.glob('TestGravityCheckResults*'): + Data = na.loadtxt(f) + + # Read in data from text file produced by code + radius = Data[:,4] + ForceTangentialComputed = Data[:,5] + ForceRadialComputed = Data[:,6] + ForceRadialTrue = Data[:,7] + + plt.loglog(radius, ForceRadialComputed, 'b', label='Frad', ls='None', marker='+') + plt.loglog(radius, ForceRadialTrue, 'k', label='Frad_true', ls='None', marker='.') + plt.loglog(radius, ForceTangentialComputed, 'm', label='Ftang', ls='None', marker='.') + if not legend_added: + plt.legend() + legend_added = True + +plt.xlabel('r (cells)') +plt.ylabel('Force') +plt.axis([5e-3,0.5,1e-4,1e3]) +plt.savefig('GravityTest.png') diff --git a/run/APMGravitySolver/GravityTest/APMCornerTest/notes.txt b/run/APMGravitySolver/GravityTest/APMCornerTest/notes.txt new file mode 100644 index 000000000..8133bb07e --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCornerTest/notes.txt @@ -0,0 +1 @@ +Running APM solver with central particle at the corner of the subgrid diff --git a/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzo b/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzo new file mode 100644 index 000000000..93cffbb09 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test Problem - APM +# +# define problem +# +ProblemType = 123 // Gravity test - APM +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +PressureFree = 1 // turn off pressure +S2ParticleSize = 3.4 +GravityResolution = 1.0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 0 +# +TestGravityCentralParticlePosition = 0.5 0.5 0.5 +TestGravityNumberOfParticles = 5000 +TestGravitySubgridLeft = 0.4375 // start of subgrid +TestGravitySubgridRight = 0.5625 // end of subgrid +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +HydroMethod = 0 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to 2 levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzotest b/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzotest new file mode 100644 index 000000000..14a182564 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzotest @@ -0,0 +1,13 @@ +name = 'FastCenterTest' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTest/FastCenterTest/make_plot.py b/run/APMGravitySolver/GravityTest/FastCenterTest/make_plot.py new file mode 100644 index 000000000..9525113a6 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCenterTest/make_plot.py @@ -0,0 +1,26 @@ +import numpy as na +import matplotlib.pyplot as plt +import glob + + +legend_added = False +for f in glob.glob('TestGravityCheckResults*'): + Data = na.loadtxt(f) + + # Read in data from text file produced by code + radius = Data[:,4] + ForceTangentialComputed = Data[:,5] + ForceRadialComputed = Data[:,6] + ForceRadialTrue = Data[:,7] + + plt.loglog(radius, ForceRadialComputed, 'b', label='Frad', ls='None', marker='+') + plt.loglog(radius, ForceRadialTrue, 'k', label='Frad_true', ls='None', marker='.') + plt.loglog(radius, ForceTangentialComputed, 'm', label='Ftang', ls='None', marker='.') + if not legend_added: + plt.legend() + legend_added = True + +plt.xlabel('r (cells)') +plt.ylabel('Force') +plt.axis([5e-3,0.5,1e-4,1e3]) +plt.savefig('GravityTest.png') diff --git a/run/APMGravitySolver/GravityTest/FastCenterTest/notes.txt b/run/APMGravitySolver/GravityTest/FastCenterTest/notes.txt new file mode 100644 index 000000000..1f99d6a01 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCenterTest/notes.txt @@ -0,0 +1 @@ +Running fast solver with central particle at the center of the subgrid diff --git a/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzo b/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzo new file mode 100644 index 000000000..3d695137c --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test Problem - APM +# +# define problem +# +ProblemType = 123 // Gravity test - APM +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +PressureFree = 1 // turn off pressure +S2ParticleSize = 3.4 +GravityResolution = 1.0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 0 +# +TestGravityCentralParticlePosition = 0.5 0.5 0.5 +TestGravityNumberOfParticles = 5000 +TestGravitySubgridLeft = 0.5 // start of subgrid +TestGravitySubgridRight = 0.5625 // end of subgrid +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +HydroMethod = 0 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to 2 levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzotest b/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzotest new file mode 100644 index 000000000..11bc0944b --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzotest @@ -0,0 +1,13 @@ +name = 'FastCornerTest' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTest/FastCornerTest/make_plot.py b/run/APMGravitySolver/GravityTest/FastCornerTest/make_plot.py new file mode 100644 index 000000000..9525113a6 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCornerTest/make_plot.py @@ -0,0 +1,26 @@ +import numpy as na +import matplotlib.pyplot as plt +import glob + + +legend_added = False +for f in glob.glob('TestGravityCheckResults*'): + Data = na.loadtxt(f) + + # Read in data from text file produced by code + radius = Data[:,4] + ForceTangentialComputed = Data[:,5] + ForceRadialComputed = Data[:,6] + ForceRadialTrue = Data[:,7] + + plt.loglog(radius, ForceRadialComputed, 'b', label='Frad', ls='None', marker='+') + plt.loglog(radius, ForceRadialTrue, 'k', label='Frad_true', ls='None', marker='.') + plt.loglog(radius, ForceTangentialComputed, 'm', label='Ftang', ls='None', marker='.') + if not legend_added: + plt.legend() + legend_added = True + +plt.xlabel('r (cells)') +plt.ylabel('Force') +plt.axis([5e-3,0.5,1e-4,1e3]) +plt.savefig('GravityTest.png') diff --git a/run/APMGravitySolver/GravityTest/FastCornerTest/notes.txt b/run/APMGravitySolver/GravityTest/FastCornerTest/notes.txt new file mode 100644 index 000000000..5cac2b6a9 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCornerTest/notes.txt @@ -0,0 +1 @@ +Running fast solver with central particle at the corner of the subgrid diff --git a/run/APMGravitySolver/GravityTest/notes.txt b/run/APMGravitySolver/GravityTest/notes.txt new file mode 100644 index 000000000..0ae23a259 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/notes.txt @@ -0,0 +1 @@ +These directories contain a set of problems to test the performance of the APM and Fast (multigrid) gravity solvers with particles at either the center or corner of a grid. diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzo b/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzo new file mode 100644 index 000000000..379297a97 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzo @@ -0,0 +1,49 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test (Sphere) Problem +# +# define problem +# +ProblemType = 125 // Gravity test (Sphere) - APM version +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 +UnigridTranspose = 0 +GravitySolverType = 1 // 0: fast, 1: APM +DepositAlsoParentGridAndSiblingsParticles = 1 +# +TestGravitySphereInteriorDensity = 1.0 //100000.0 +TestGravitySphereExteriorDensity = 1e-10 //0.01 +TestGravitySphereRadius = 0.3 +TestGravitySphereUseBaryons = 1 +TestGravitySphereType = 0 //0: constant, 1: r**-2, 2: r**-2.25 +TestGravitySphereRefineAtStart = 1 +TestGravitySphereCenter = 0.5 0.5 0.5 +#TestGravitySphereCenter = 0.484375 0.484375 0.484375 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +WritePotential = 1 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +HydroMethod = 0 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 //6 // use up to 3 levels +MaximumGravityRefinementLevel = 2 //6 +RefineBy = 2 // refinement factor +MinimumMassForRefinement = 1.e-6 +CellFlaggingMethod = 2 +FluxCorrection = 0 +ConservativeInterpolation = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzotest b/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzotest new file mode 100644 index 000000000..4942a465a --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzotest @@ -0,0 +1,13 @@ +name = 'APMSphere0' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere0/make_plot.py b/run/APMGravitySolver/GravityTestSphere/APMSphere0/make_plot.py new file mode 100644 index 000000000..1a461cc84 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere0/make_plot.py @@ -0,0 +1,278 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import random +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +sphere_type = 0 +solver = 'APM' +data = './DD0000/data0000' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +# constant density +def phi_anal0(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/(2*Rstar) * (3-r**2/Rstar**2) + return pot + +def acc_anal0(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar*r/Rstar**3 + return acc + +# 1/r**2 +def phi_anal1(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * (1 - np.log(r/Rstar)) + return pot + +def acc_anal1(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar/Rstar * 1/r + return acc + +# Plummer +def phi_anal2(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * ( 2*np.sqrt(2)/np.sqrt(1.+r**2/Rstar**2) - 1 ) + return pot +def acc_anal2(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = 2*np.sqrt(2)*Mstar/Rstar**3 * r * (1.+r**2/Rstar**2)**-1.5 + return acc + +# Get Accelerations and Errors +def get_accelerations(data,Rho,Rstar): + + print("loading %s" % data) + pf = load(data) + pf.h.print_stats() + ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) + # Get grids per level + for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + + #---------------------------------------------------- + # Gas from AccelerationField.out + #---------------------------------------------------- + Files = glob.glob('AccelerationField.out*') + procs = [] + level_gas = [] + is_ghost_gas = [] + i_gas = [] + j_gas = [] + k_gas = [] + x_gas = [] + y_gas = [] + z_gas = [] + r_gas = [] + ax_gas = [] + ay_gas = [] + az_gas = [] + arad_gas = [] + atan_gas = [] + + for name in Files: + Data = np.loadtxt(name) + procs = procs + list(int(name[-4::])*np.ones(np.size(Data[:,0]),dtype=int)) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]) + y_gas = y_gas + list(Data[:,6]) + z_gas = z_gas + list(Data[:,7]) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + atan_gas = atan_gas + list(Data[:,12]) + arad_gas = arad_gas + list(Data[:,13]) + + procs = np.array(procs) + level_gas = np.array(level_gas) + is_ghost_gas = np.array(is_ghost_gas) + level_gas = level_gas.astype(int) + is_ghost_gas = is_ghost_gas.astype(int) + i_gas = np.array(i_gas) + j_gas = np.array(j_gas) + k_gas = np.array(k_gas) + x_gas = np.array(x_gas) + y_gas = np.array(y_gas) + z_gas = np.array(z_gas) + r_gas = np.array(r_gas) + ax_gas = np.array(ax_gas) + ay_gas = np.array(ay_gas) + az_gas = np.array(az_gas) + arad_gas = np.array(arad_gas) + atan_gas = np.array(atan_gas) + + # Remove all ghost zones + #Ind = ((is_ghost_gas == 0) | (level_gas > 0)).nonzero()[0] + Ind = [] + for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) + Ind = np.array(Ind) + + procs = procs[Ind] + level_gas = level_gas[Ind] + is_ghost_gas = is_ghost_gas[Ind] + i_gas = i_gas[Ind] + j_gas = j_gas[Ind] + k_gas = k_gas[Ind] + x_gas = x_gas[Ind] + y_gas = y_gas[Ind] + z_gas = z_gas[Ind] + r_gas = r_gas[Ind] + ax_gas = ax_gas[Ind] + ay_gas = ay_gas[Ind] + az_gas = az_gas[Ind] + arad_gas = arad_gas[Ind] + atan_gas = atan_gas[Ind] + + ngas = np.size(x_gas) + + # RMS + f_true = np.zeros(ngas) + Error1 = np.zeros(ngas) + Error2 = np.zeros(ngas) + for i in range(0,ngas,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal0(r_gas[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal1(r_gas[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_true[i] = acc_anal2(r_gas[i],Mstar,Rstar) + + Error1 = np.abs((arad_gas-f_true)/f_true) + Error2 = np.abs(atan_gas/f_true) + Mean1 = np.mean(Error1) + Mean2 = np.mean(Error2) + Rms1 = np.std(Error1) + Rms2 = np.std(Error2) + + return (ngrids_per_level,procs,level_gas,r_gas,arad_gas, + Error1,Error2,Mean1,Mean2,Rms1,Rms2) + +# Values for analytical solution +Rho = 1.0 +Rstar = 0.3 + +# Analytical solution +r_anal = np.arange(1e-3,1.1,1e-3) +n_anal = np.size(r_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal0(r_anal[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal1(r_anal[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_anal[i] = acc_anal2(r_anal[i],Mstar,Rstar) + else: + print("Wrong sphere type") + sys.exit() + +# Get accelerations, errors, etc... +(ngrids1,procs1,l1,r1,a1,er1,et1,mr1,mt1,rmsr1,rmst1) = get_accelerations(data,Rho,Rstar) + +# output relevant values +print("Radial force error = ", mr1, " +/- ", rmsr1) +print("Tangential force error = ", mt1, " +/- ", rmst1) + +# Plot +symbols = ['bx','ro','g.', 'c*'] +if (sphere_type == 0): + ylim_min = 1.1e-8 + ylim_max = 0.99 + legend_where = 'upper left' +elif (sphere_type == 1): + ylim_min = 1.1e-5 + ylim_max = 0.99 + legend_where = 'lower left' +else: + ylim_min = 1.1e-6 + ylim_max = 0.99 + legend_where = 'upper left' + +# All data (png) +# Radial acceleration +plt.figure(1) +plt.loglog(r_anal[0],f_anal[0],'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(l1)+1),1): + Ind2 = np.where(l1 == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids1[i]) + plt.loglog(r1[Ind2],a1[Ind2],symbols[i],label=txt) +plt.loglog(r_anal,f_anal,'k') + +# Limits +plt.xlim(6e-3,1.0) +if (sphere_type == 0): + plt.ylim(2e-2,2.0) +elif (sphere_type == 2): + plt.ylim(2e-2,0.7) +else: + plt.ylim(0.3,1e2) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Force}$') +plt.legend(loc=legend_where) +plt.vlines(Rstar,1e-8,1e99,'k') +plt.savefig('Force-'+str(sphere_type)+'-'+solver+'.png') + +# Errors +plt.figure(2) +plt.subplots(2,1,sharex=True) +plt.subplots_adjust(hspace=0) +plt.subplot(211) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],er1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.ylabel('$\mathrm{Radial\,error}$') +plt.subplot(212) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],et1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Tangential\,error}$') +plt.savefig('Errors-'+str(sphere_type)+'-'+solver+'.png') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere0/notes.txt b/run/APMGravitySolver/GravityTestSphere/APMSphere0/notes.txt new file mode 100644 index 000000000..8bb11d9ff --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere0/notes.txt @@ -0,0 +1 @@ +Running APM solver with sphere of constant density diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzo b/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzo new file mode 100644 index 000000000..0e50cda10 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzo @@ -0,0 +1,49 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test (Sphere) Problem +# +# define problem +# +ProblemType = 125 // Gravity test (Sphere) - APM version +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 +UnigridTranspose = 0 +GravitySolverType = 1 // 0: fast, 1: APM +DepositAlsoParentGridAndSiblingsParticles = 1 +# +TestGravitySphereInteriorDensity = 1.0 //100000.0 +TestGravitySphereExteriorDensity = 1e-10 //0.01 +TestGravitySphereRadius = 0.3 +TestGravitySphereUseBaryons = 1 +TestGravitySphereType = 1 //0: constant, 1: r**-2, 2: r**-2.25 +TestGravitySphereRefineAtStart = 1 +TestGravitySphereCenter = 0.5 0.5 0.5 +#TestGravitySphereCenter = 0.484375 0.484375 0.484375 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +WritePotential = 1 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +HydroMethod = 0 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 //6 // use up to 3 levels +MaximumGravityRefinementLevel = 2 //6 +RefineBy = 2 // refinement factor +MinimumMassForRefinement = 1.e-5 +CellFlaggingMethod = 2 +FluxCorrection = 0 +ConservativeInterpolation = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzotest b/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzotest new file mode 100644 index 000000000..3700a5609 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzotest @@ -0,0 +1,13 @@ +name = 'APMSphere1' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere1/make_plot.py b/run/APMGravitySolver/GravityTestSphere/APMSphere1/make_plot.py new file mode 100644 index 000000000..22463fd39 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere1/make_plot.py @@ -0,0 +1,278 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import random +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +sphere_type = 1 +solver = 'APM' +data = './DD0000/data0000' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +# constant density +def phi_anal0(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/(2*Rstar) * (3-r**2/Rstar**2) + return pot + +def acc_anal0(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar*r/Rstar**3 + return acc + +# 1/r**2 +def phi_anal1(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * (1 - np.log(r/Rstar)) + return pot + +def acc_anal1(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar/Rstar * 1/r + return acc + +# Plummer +def phi_anal2(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * ( 2*np.sqrt(2)/np.sqrt(1.+r**2/Rstar**2) - 1 ) + return pot +def acc_anal2(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = 2*np.sqrt(2)*Mstar/Rstar**3 * r * (1.+r**2/Rstar**2)**-1.5 + return acc + +# Get Accelerations and Errors +def get_accelerations(data,Rho,Rstar): + + print("loading %s" % data) + pf = load(data) + pf.h.print_stats() + ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) + # Get grids per level + for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + + #---------------------------------------------------- + # Gas from AccelerationField.out + #---------------------------------------------------- + Files = glob.glob('AccelerationField.out*') + procs = [] + level_gas = [] + is_ghost_gas = [] + i_gas = [] + j_gas = [] + k_gas = [] + x_gas = [] + y_gas = [] + z_gas = [] + r_gas = [] + ax_gas = [] + ay_gas = [] + az_gas = [] + arad_gas = [] + atan_gas = [] + + for name in Files: + Data = np.loadtxt(name) + procs = procs + list(int(name[-4::])*np.ones(np.size(Data[:,0]),dtype=int)) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]) + y_gas = y_gas + list(Data[:,6]) + z_gas = z_gas + list(Data[:,7]) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + atan_gas = atan_gas + list(Data[:,12]) + arad_gas = arad_gas + list(Data[:,13]) + + procs = np.array(procs) + level_gas = np.array(level_gas) + is_ghost_gas = np.array(is_ghost_gas) + level_gas = level_gas.astype(int) + is_ghost_gas = is_ghost_gas.astype(int) + i_gas = np.array(i_gas) + j_gas = np.array(j_gas) + k_gas = np.array(k_gas) + x_gas = np.array(x_gas) + y_gas = np.array(y_gas) + z_gas = np.array(z_gas) + r_gas = np.array(r_gas) + ax_gas = np.array(ax_gas) + ay_gas = np.array(ay_gas) + az_gas = np.array(az_gas) + arad_gas = np.array(arad_gas) + atan_gas = np.array(atan_gas) + + # Remove all ghost zones + #Ind = ((is_ghost_gas == 0) | (level_gas > 0)).nonzero()[0] + Ind = [] + for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) + Ind = np.array(Ind) + + procs = procs[Ind] + level_gas = level_gas[Ind] + is_ghost_gas = is_ghost_gas[Ind] + i_gas = i_gas[Ind] + j_gas = j_gas[Ind] + k_gas = k_gas[Ind] + x_gas = x_gas[Ind] + y_gas = y_gas[Ind] + z_gas = z_gas[Ind] + r_gas = r_gas[Ind] + ax_gas = ax_gas[Ind] + ay_gas = ay_gas[Ind] + az_gas = az_gas[Ind] + arad_gas = arad_gas[Ind] + atan_gas = atan_gas[Ind] + + ngas = np.size(x_gas) + + # RMS + f_true = np.zeros(ngas) + Error1 = np.zeros(ngas) + Error2 = np.zeros(ngas) + for i in range(0,ngas,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal0(r_gas[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal1(r_gas[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_true[i] = acc_anal2(r_gas[i],Mstar,Rstar) + + Error1 = np.abs((arad_gas-f_true)/f_true) + Error2 = np.abs(atan_gas/f_true) + Mean1 = np.mean(Error1) + Mean2 = np.mean(Error2) + Rms1 = np.std(Error1) + Rms2 = np.std(Error2) + + return (ngrids_per_level,procs,level_gas,r_gas,arad_gas, + Error1,Error2,Mean1,Mean2,Rms1,Rms2) + +# Values for analytical solution +Rho = 1.0 +Rstar = 0.3 + +# Analytical solution +r_anal = np.arange(1e-3,1.1,1e-3) +n_anal = np.size(r_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal0(r_anal[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal1(r_anal[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_anal[i] = acc_anal2(r_anal[i],Mstar,Rstar) + else: + print("Wrong sphere type") + sys.exit() + +# Get accelerations, errors, etc... +(ngrids1,procs1,l1,r1,a1,er1,et1,mr1,mt1,rmsr1,rmst1) = get_accelerations(data,Rho,Rstar) + +# output relevant values +print("Radial force error = ", mr1, " +/- ", rmsr1) +print("Tangential force error = ", mt1, " +/- ", rmst1) + +# Plot +symbols = ['bx','ro','g.', 'c*'] +if (sphere_type == 0): + ylim_min = 1.1e-8 + ylim_max = 0.99 + legend_where = 'upper left' +elif (sphere_type == 1): + ylim_min = 1.1e-5 + ylim_max = 0.99 + legend_where = 'lower left' +else: + ylim_min = 1.1e-6 + ylim_max = 0.99 + legend_where = 'upper left' + +# All data (png) +# Radial acceleration +plt.figure(1) +plt.loglog(r_anal[0],f_anal[0],'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(l1)+1),1): + Ind2 = np.where(l1 == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids1[i]) + plt.loglog(r1[Ind2],a1[Ind2],symbols[i],label=txt) +plt.loglog(r_anal,f_anal,'k') + +# Limits +plt.xlim(6e-3,1.0) +if (sphere_type == 0): + plt.ylim(2e-2,2.0) +elif (sphere_type == 2): + plt.ylim(2e-2,0.7) +else: + plt.ylim(0.3,1e2) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Force}$') +plt.legend(loc=legend_where) +plt.vlines(Rstar,1e-8,1e99,'k') +plt.savefig('Force-'+str(sphere_type)+'-'+solver+'.png') + +# Errors +plt.figure(2) +plt.subplots(2,1,sharex=True) +plt.subplots_adjust(hspace=0) +plt.subplot(211) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],er1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.ylabel('$\mathrm{Radial\,error}$') +plt.subplot(212) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],et1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Tangential\,error}$') +plt.savefig('Errors-'+str(sphere_type)+'-'+solver+'.png') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere1/notes.txt b/run/APMGravitySolver/GravityTestSphere/APMSphere1/notes.txt new file mode 100644 index 000000000..eae3b0007 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere1/notes.txt @@ -0,0 +1 @@ +Running APM solver with isothermal sphere diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzo b/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzo new file mode 100644 index 000000000..75d8e1513 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzo @@ -0,0 +1,49 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test (Sphere) Problem +# +# define problem +# +ProblemType = 125 // Gravity test (Sphere) - APM version +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 +UnigridTranspose = 0 +GravitySolverType = 1 // 0: fast, 1: APM +DepositAlsoParentGridAndSiblingsParticles = 1 +# +TestGravitySphereInteriorDensity = 1.0 //100000.0 +TestGravitySphereExteriorDensity = 1e-10 //0.01 +TestGravitySphereRadius = 0.3 +TestGravitySphereUseBaryons = 1 +TestGravitySphereType = 2 //0: constant, 1: r**-2, 2: r**-2.25 +TestGravitySphereRefineAtStart = 1 +TestGravitySphereCenter = 0.5 0.5 0.5 +#TestGravitySphereCenter = 0.484375 0.484375 0.484375 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +WritePotential = 1 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +HydroMethod = 0 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 //6 // use up to 3 levels +MaximumGravityRefinementLevel = 2 //6 +RefineBy = 2 // refinement factor +MinimumMassForRefinement = 3.e-6 +CellFlaggingMethod = 2 +FluxCorrection = 0 +ConservativeInterpolation = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzotest b/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzotest new file mode 100644 index 000000000..91102482d --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzotest @@ -0,0 +1,13 @@ +name = 'APMSphere2' +answer_testing_script = 'test_gravity.py' +nprocs = 1 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere2/make_plot.py b/run/APMGravitySolver/GravityTestSphere/APMSphere2/make_plot.py new file mode 100644 index 000000000..d7e4dd9fc --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere2/make_plot.py @@ -0,0 +1,278 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import random +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +sphere_type = 2 +solver = 'APM' +data = './DD0000/data0000' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +# constant density +def phi_anal0(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/(2*Rstar) * (3-r**2/Rstar**2) + return pot + +def acc_anal0(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar*r/Rstar**3 + return acc + +# 1/r**2 +def phi_anal1(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * (1 - np.log(r/Rstar)) + return pot + +def acc_anal1(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar/Rstar * 1/r + return acc + +# Plummer +def phi_anal2(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * ( 2*np.sqrt(2)/np.sqrt(1.+r**2/Rstar**2) - 1 ) + return pot +def acc_anal2(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = 2*np.sqrt(2)*Mstar/Rstar**3 * r * (1.+r**2/Rstar**2)**-1.5 + return acc + +# Get Accelerations and Errors +def get_accelerations(data,Rho,Rstar): + + print("loading %s" % data) + pf = load(data) + pf.h.print_stats() + ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) + # Get grids per level + for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + + #---------------------------------------------------- + # Gas from AccelerationField.out + #---------------------------------------------------- + Files = glob.glob('AccelerationField.out*') + procs = [] + level_gas = [] + is_ghost_gas = [] + i_gas = [] + j_gas = [] + k_gas = [] + x_gas = [] + y_gas = [] + z_gas = [] + r_gas = [] + ax_gas = [] + ay_gas = [] + az_gas = [] + arad_gas = [] + atan_gas = [] + + for name in Files: + Data = np.loadtxt(name) + procs = procs + list(int(name[-4::])*np.ones(np.size(Data[:,0]),dtype=int)) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]) + y_gas = y_gas + list(Data[:,6]) + z_gas = z_gas + list(Data[:,7]) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + atan_gas = atan_gas + list(Data[:,12]) + arad_gas = arad_gas + list(Data[:,13]) + + procs = np.array(procs) + level_gas = np.array(level_gas) + is_ghost_gas = np.array(is_ghost_gas) + level_gas = level_gas.astype(int) + is_ghost_gas = is_ghost_gas.astype(int) + i_gas = np.array(i_gas) + j_gas = np.array(j_gas) + k_gas = np.array(k_gas) + x_gas = np.array(x_gas) + y_gas = np.array(y_gas) + z_gas = np.array(z_gas) + r_gas = np.array(r_gas) + ax_gas = np.array(ax_gas) + ay_gas = np.array(ay_gas) + az_gas = np.array(az_gas) + arad_gas = np.array(arad_gas) + atan_gas = np.array(atan_gas) + + # Remove all ghost zones + #Ind = ((is_ghost_gas == 0) | (level_gas > 0)).nonzero()[0] + Ind = [] + for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) + Ind = np.array(Ind) + + procs = procs[Ind] + level_gas = level_gas[Ind] + is_ghost_gas = is_ghost_gas[Ind] + i_gas = i_gas[Ind] + j_gas = j_gas[Ind] + k_gas = k_gas[Ind] + x_gas = x_gas[Ind] + y_gas = y_gas[Ind] + z_gas = z_gas[Ind] + r_gas = r_gas[Ind] + ax_gas = ax_gas[Ind] + ay_gas = ay_gas[Ind] + az_gas = az_gas[Ind] + arad_gas = arad_gas[Ind] + atan_gas = atan_gas[Ind] + + ngas = np.size(x_gas) + + # RMS + f_true = np.zeros(ngas) + Error1 = np.zeros(ngas) + Error2 = np.zeros(ngas) + for i in range(0,ngas,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal0(r_gas[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal1(r_gas[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_true[i] = acc_anal2(r_gas[i],Mstar,Rstar) + + Error1 = np.abs((arad_gas-f_true)/f_true) + Error2 = np.abs(atan_gas/f_true) + Mean1 = np.mean(Error1) + Mean2 = np.mean(Error2) + Rms1 = np.std(Error1) + Rms2 = np.std(Error2) + + return (ngrids_per_level,procs,level_gas,r_gas,arad_gas, + Error1,Error2,Mean1,Mean2,Rms1,Rms2) + +# Values for analytical solution +Rho = 1.0 +Rstar = 0.3 + +# Analytical solution +r_anal = np.arange(1e-3,1.1,1e-3) +n_anal = np.size(r_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal0(r_anal[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal1(r_anal[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_anal[i] = acc_anal2(r_anal[i],Mstar,Rstar) + else: + print("Wrong sphere type") + sys.exit() + +# Get accelerations, errors, etc... +(ngrids1,procs1,l1,r1,a1,er1,et1,mr1,mt1,rmsr1,rmst1) = get_accelerations(data,Rho,Rstar) + +# output relevant values +print("Radial force error = ", mr1, " +/- ", rmsr1) +print("Tangential force error = ", mt1, " +/- ", rmst1) + +# Plot +symbols = ['bx','ro','g.', 'c*'] +if (sphere_type == 0): + ylim_min = 1.1e-8 + ylim_max = 0.99 + legend_where = 'upper left' +elif (sphere_type == 1): + ylim_min = 1.1e-5 + ylim_max = 0.99 + legend_where = 'lower left' +else: + ylim_min = 1.1e-6 + ylim_max = 0.99 + legend_where = 'upper left' + +# All data (png) +# Radial acceleration +plt.figure(1) +plt.loglog(r_anal[0],f_anal[0],'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(l1)+1),1): + Ind2 = np.where(l1 == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids1[i]) + plt.loglog(r1[Ind2],a1[Ind2],symbols[i],label=txt) +plt.loglog(r_anal,f_anal,'k') + +# Limits +plt.xlim(6e-3,1.0) +if (sphere_type == 0): + plt.ylim(2e-2,2.0) +elif (sphere_type == 2): + plt.ylim(2e-2,0.7) +else: + plt.ylim(0.3,1e2) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Force}$') +plt.legend(loc=legend_where) +plt.vlines(Rstar,1e-8,1e99,'k') +plt.savefig('Force-'+str(sphere_type)+'-'+solver+'.png') + +# Errors +plt.figure(2) +plt.subplots(2,1,sharex=True) +plt.subplots_adjust(hspace=0) +plt.subplot(211) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],er1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.ylabel('$\mathrm{Radial\,error}$') +plt.subplot(212) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],et1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Tangential\,error}$') +plt.savefig('Errors-'+str(sphere_type)+'-'+solver+'.png') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/GravityTestSphere/APMSphere2/notes.txt b/run/APMGravitySolver/GravityTestSphere/APMSphere2/notes.txt new file mode 100644 index 000000000..c8dd74f11 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere2/notes.txt @@ -0,0 +1 @@ +Running APM solver with Plummer sphere diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzo b/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzo new file mode 100644 index 000000000..319c4030f --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzo @@ -0,0 +1,49 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test (Sphere) Problem +# +# define problem +# +ProblemType = 125 // Gravity test (Sphere) - APM version +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 +UnigridTranspose = 0 +GravitySolverType = 0 // 0: fast, 1: APM +DepositAlsoParentGridAndSiblingsParticles = 0 +# +TestGravitySphereInteriorDensity = 1.0 //100000.0 +TestGravitySphereExteriorDensity = 1e-10 //0.01 +TestGravitySphereRadius = 0.3 +TestGravitySphereUseBaryons = 1 +TestGravitySphereType = 0 //0: constant, 1: r**-2, 2: r**-2.25 +TestGravitySphereRefineAtStart = 1 +TestGravitySphereCenter = 0.5 0.5 0.5 +#TestGravitySphereCenter = 0.484375 0.484375 0.484375 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +WritePotential = 1 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +HydroMethod = 0 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 //6 // use up to 3 levels +MaximumGravityRefinementLevel = 2 //6 +RefineBy = 2 // refinement factor +MinimumMassForRefinement = 1.e-6 +CellFlaggingMethod = 2 +FluxCorrection = 0 +ConservativeInterpolation = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzotest b/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzotest new file mode 100644 index 000000000..fcf2a5a98 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzotest @@ -0,0 +1,13 @@ +name = 'FastSphere0' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere0/make_plot.py b/run/APMGravitySolver/GravityTestSphere/FastSphere0/make_plot.py new file mode 100644 index 000000000..cbb467f29 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere0/make_plot.py @@ -0,0 +1,278 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import random +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +sphere_type = 0 +solver = 'Fast' +data = './DD0000/data0000' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +# constant density +def phi_anal0(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/(2*Rstar) * (3-r**2/Rstar**2) + return pot + +def acc_anal0(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar*r/Rstar**3 + return acc + +# 1/r**2 +def phi_anal1(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * (1 - np.log(r/Rstar)) + return pot + +def acc_anal1(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar/Rstar * 1/r + return acc + +# Plummer +def phi_anal2(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * ( 2*np.sqrt(2)/np.sqrt(1.+r**2/Rstar**2) - 1 ) + return pot +def acc_anal2(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = 2*np.sqrt(2)*Mstar/Rstar**3 * r * (1.+r**2/Rstar**2)**-1.5 + return acc + +# Get Accelerations and Errors +def get_accelerations(data,Rho,Rstar): + + print("loading %s" % data) + pf = load(data) + pf.h.print_stats() + ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) + # Get grids per level + for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + + #---------------------------------------------------- + # Gas from AccelerationField.out + #---------------------------------------------------- + Files = glob.glob('AccelerationField.out*') + procs = [] + level_gas = [] + is_ghost_gas = [] + i_gas = [] + j_gas = [] + k_gas = [] + x_gas = [] + y_gas = [] + z_gas = [] + r_gas = [] + ax_gas = [] + ay_gas = [] + az_gas = [] + arad_gas = [] + atan_gas = [] + + for name in Files: + Data = np.loadtxt(name) + procs = procs + list(int(name[-4::])*np.ones(np.size(Data[:,0]),dtype=int)) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]) + y_gas = y_gas + list(Data[:,6]) + z_gas = z_gas + list(Data[:,7]) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + atan_gas = atan_gas + list(Data[:,12]) + arad_gas = arad_gas + list(Data[:,13]) + + procs = np.array(procs) + level_gas = np.array(level_gas) + is_ghost_gas = np.array(is_ghost_gas) + level_gas = level_gas.astype(int) + is_ghost_gas = is_ghost_gas.astype(int) + i_gas = np.array(i_gas) + j_gas = np.array(j_gas) + k_gas = np.array(k_gas) + x_gas = np.array(x_gas) + y_gas = np.array(y_gas) + z_gas = np.array(z_gas) + r_gas = np.array(r_gas) + ax_gas = np.array(ax_gas) + ay_gas = np.array(ay_gas) + az_gas = np.array(az_gas) + arad_gas = np.array(arad_gas) + atan_gas = np.array(atan_gas) + + # Remove all ghost zones + #Ind = ((is_ghost_gas == 0) | (level_gas > 0)).nonzero()[0] + Ind = [] + for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) + Ind = np.array(Ind) + + procs = procs[Ind] + level_gas = level_gas[Ind] + is_ghost_gas = is_ghost_gas[Ind] + i_gas = i_gas[Ind] + j_gas = j_gas[Ind] + k_gas = k_gas[Ind] + x_gas = x_gas[Ind] + y_gas = y_gas[Ind] + z_gas = z_gas[Ind] + r_gas = r_gas[Ind] + ax_gas = ax_gas[Ind] + ay_gas = ay_gas[Ind] + az_gas = az_gas[Ind] + arad_gas = arad_gas[Ind] + atan_gas = atan_gas[Ind] + + ngas = np.size(x_gas) + + # RMS + f_true = np.zeros(ngas) + Error1 = np.zeros(ngas) + Error2 = np.zeros(ngas) + for i in range(0,ngas,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal0(r_gas[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal1(r_gas[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_true[i] = acc_anal2(r_gas[i],Mstar,Rstar) + + Error1 = np.abs((arad_gas-f_true)/f_true) + Error2 = np.abs(atan_gas/f_true) + Mean1 = np.mean(Error1) + Mean2 = np.mean(Error2) + Rms1 = np.std(Error1) + Rms2 = np.std(Error2) + + return (ngrids_per_level,procs,level_gas,r_gas,arad_gas, + Error1,Error2,Mean1,Mean2,Rms1,Rms2) + +# Values for analytical solution +Rho = 1.0 +Rstar = 0.3 + +# Analytical solution +r_anal = np.arange(1e-3,1.1,1e-3) +n_anal = np.size(r_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal0(r_anal[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal1(r_anal[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_anal[i] = acc_anal2(r_anal[i],Mstar,Rstar) + else: + print("Wrong sphere type") + sys.exit() + +# Get accelerations, errors, etc... +(ngrids1,procs1,l1,r1,a1,er1,et1,mr1,mt1,rmsr1,rmst1) = get_accelerations(data,Rho,Rstar) + +# output relevant values +print("Radial force error = ", mr1, " +/- ", rmsr1) +print("Tangential force error = ", mt1, " +/- ", rmst1) + +# Plot +symbols = ['bx','ro','g.', 'c*'] +if (sphere_type == 0): + ylim_min = 1.1e-8 + ylim_max = 0.99 + legend_where = 'upper left' +elif (sphere_type == 1): + ylim_min = 1.1e-5 + ylim_max = 0.99 + legend_where = 'lower left' +else: + ylim_min = 1.1e-6 + ylim_max = 0.99 + legend_where = 'upper left' + +# All data (png) +# Radial acceleration +plt.figure(1) +plt.loglog(r_anal[0],f_anal[0],'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(l1)+1),1): + Ind2 = np.where(l1 == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids1[i]) + plt.loglog(r1[Ind2],a1[Ind2],symbols[i],label=txt) +plt.loglog(r_anal,f_anal,'k') + +# Limits +plt.xlim(6e-3,1.0) +if (sphere_type == 0): + plt.ylim(2e-2,2.0) +elif (sphere_type == 2): + plt.ylim(2e-2,0.7) +else: + plt.ylim(0.3,1e2) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Force}$') +plt.legend(loc=legend_where) +plt.vlines(Rstar,1e-8,1e99,'k') +plt.savefig('Force-'+str(sphere_type)+'-'+solver+'.png') + +# Errors +plt.figure(2) +plt.subplots(2,1,sharex=True) +plt.subplots_adjust(hspace=0) +plt.subplot(211) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],er1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.ylabel('$\mathrm{Radial\,error}$') +plt.subplot(212) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],et1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Tangential\,error}$') +plt.savefig('Errors-'+str(sphere_type)+'-'+solver+'.png') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere0/notes.txt b/run/APMGravitySolver/GravityTestSphere/FastSphere0/notes.txt new file mode 100644 index 000000000..eae6de336 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere0/notes.txt @@ -0,0 +1 @@ +Running fast solver with sphere of constant density diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzo b/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzo new file mode 100644 index 000000000..67b0d4fef --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzo @@ -0,0 +1,49 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test (Sphere) Problem +# +# define problem +# +ProblemType = 125 // Gravity test (Sphere) - APM version +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 +UnigridTranspose = 0 +GravitySolverType = 0 // 0: fast, 1: APM +DepositAlsoParentGridAndSiblingsParticles = 0 +# +TestGravitySphereInteriorDensity = 1.0 //100000.0 +TestGravitySphereExteriorDensity = 1e-10 //0.01 +TestGravitySphereRadius = 0.3 +TestGravitySphereUseBaryons = 1 +TestGravitySphereType = 1 //0: constant, 1: r**-2, 2: r**-2.25 +TestGravitySphereRefineAtStart = 1 +TestGravitySphereCenter = 0.5 0.5 0.5 +#TestGravitySphereCenter = 0.484375 0.484375 0.484375 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +WritePotential = 1 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +HydroMethod = 0 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 //6 // use up to 3 levels +MaximumGravityRefinementLevel = 2 //6 +RefineBy = 2 // refinement factor +MinimumMassForRefinement = 1.e-5 +CellFlaggingMethod = 2 +FluxCorrection = 0 +ConservativeInterpolation = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzotest b/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzotest new file mode 100644 index 000000000..cc413d122 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzotest @@ -0,0 +1,13 @@ +name = 'FastSphere1' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere1/make_plot.py b/run/APMGravitySolver/GravityTestSphere/FastSphere1/make_plot.py new file mode 100644 index 000000000..11acee383 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere1/make_plot.py @@ -0,0 +1,278 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import random +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +sphere_type = 1 +solver = 'Fast' +data = './DD0000/data0000' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +# constant density +def phi_anal0(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/(2*Rstar) * (3-r**2/Rstar**2) + return pot + +def acc_anal0(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar*r/Rstar**3 + return acc + +# 1/r**2 +def phi_anal1(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * (1 - np.log(r/Rstar)) + return pot + +def acc_anal1(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar/Rstar * 1/r + return acc + +# Plummer +def phi_anal2(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * ( 2*np.sqrt(2)/np.sqrt(1.+r**2/Rstar**2) - 1 ) + return pot +def acc_anal2(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = 2*np.sqrt(2)*Mstar/Rstar**3 * r * (1.+r**2/Rstar**2)**-1.5 + return acc + +# Get Accelerations and Errors +def get_accelerations(data,Rho,Rstar): + + print("loading %s" % data) + pf = load(data) + pf.h.print_stats() + ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) + # Get grids per level + for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + + #---------------------------------------------------- + # Gas from AccelerationField.out + #---------------------------------------------------- + Files = glob.glob('AccelerationField.out*') + procs = [] + level_gas = [] + is_ghost_gas = [] + i_gas = [] + j_gas = [] + k_gas = [] + x_gas = [] + y_gas = [] + z_gas = [] + r_gas = [] + ax_gas = [] + ay_gas = [] + az_gas = [] + arad_gas = [] + atan_gas = [] + + for name in Files: + Data = np.loadtxt(name) + procs = procs + list(int(name[-4::])*np.ones(np.size(Data[:,0]),dtype=int)) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]) + y_gas = y_gas + list(Data[:,6]) + z_gas = z_gas + list(Data[:,7]) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + atan_gas = atan_gas + list(Data[:,12]) + arad_gas = arad_gas + list(Data[:,13]) + + procs = np.array(procs) + level_gas = np.array(level_gas) + is_ghost_gas = np.array(is_ghost_gas) + level_gas = level_gas.astype(int) + is_ghost_gas = is_ghost_gas.astype(int) + i_gas = np.array(i_gas) + j_gas = np.array(j_gas) + k_gas = np.array(k_gas) + x_gas = np.array(x_gas) + y_gas = np.array(y_gas) + z_gas = np.array(z_gas) + r_gas = np.array(r_gas) + ax_gas = np.array(ax_gas) + ay_gas = np.array(ay_gas) + az_gas = np.array(az_gas) + arad_gas = np.array(arad_gas) + atan_gas = np.array(atan_gas) + + # Remove all ghost zones + #Ind = ((is_ghost_gas == 0) | (level_gas > 0)).nonzero()[0] + Ind = [] + for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) + Ind = np.array(Ind) + + procs = procs[Ind] + level_gas = level_gas[Ind] + is_ghost_gas = is_ghost_gas[Ind] + i_gas = i_gas[Ind] + j_gas = j_gas[Ind] + k_gas = k_gas[Ind] + x_gas = x_gas[Ind] + y_gas = y_gas[Ind] + z_gas = z_gas[Ind] + r_gas = r_gas[Ind] + ax_gas = ax_gas[Ind] + ay_gas = ay_gas[Ind] + az_gas = az_gas[Ind] + arad_gas = arad_gas[Ind] + atan_gas = atan_gas[Ind] + + ngas = np.size(x_gas) + + # RMS + f_true = np.zeros(ngas) + Error1 = np.zeros(ngas) + Error2 = np.zeros(ngas) + for i in range(0,ngas,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal0(r_gas[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal1(r_gas[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_true[i] = acc_anal2(r_gas[i],Mstar,Rstar) + + Error1 = np.abs((arad_gas-f_true)/f_true) + Error2 = np.abs(atan_gas/f_true) + Mean1 = np.mean(Error1) + Mean2 = np.mean(Error2) + Rms1 = np.std(Error1) + Rms2 = np.std(Error2) + + return (ngrids_per_level,procs,level_gas,r_gas,arad_gas, + Error1,Error2,Mean1,Mean2,Rms1,Rms2) + +# Values for analytical solution +Rho = 1.0 +Rstar = 0.3 + +# Analytical solution +r_anal = np.arange(1e-3,1.1,1e-3) +n_anal = np.size(r_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal0(r_anal[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal1(r_anal[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_anal[i] = acc_anal2(r_anal[i],Mstar,Rstar) + else: + print("Wrong sphere type") + sys.exit() + +# Get accelerations, errors, etc... +(ngrids1,procs1,l1,r1,a1,er1,et1,mr1,mt1,rmsr1,rmst1) = get_accelerations(data,Rho,Rstar) + +# output relevant values +print("Radial force error = ", mr1, " +/- ", rmsr1) +print("Tangential force error = ", mt1, " +/- ", rmst1) + +# Plot +symbols = ['bx','ro','g.', 'c*'] +if (sphere_type == 0): + ylim_min = 1.1e-8 + ylim_max = 0.99 + legend_where = 'upper left' +elif (sphere_type == 1): + ylim_min = 1.1e-5 + ylim_max = 0.99 + legend_where = 'lower left' +else: + ylim_min = 1.1e-6 + ylim_max = 0.99 + legend_where = 'upper left' + +# All data (png) +# Radial acceleration +plt.figure(1) +plt.loglog(r_anal[0],f_anal[0],'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(l1)+1),1): + Ind2 = np.where(l1 == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids1[i]) + plt.loglog(r1[Ind2],a1[Ind2],symbols[i],label=txt) +plt.loglog(r_anal,f_anal,'k') + +# Limits +plt.xlim(6e-3,1.0) +if (sphere_type == 0): + plt.ylim(2e-2,2.0) +elif (sphere_type == 2): + plt.ylim(2e-2,0.7) +else: + plt.ylim(0.3,1e2) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Force}$') +plt.legend(loc=legend_where) +plt.vlines(Rstar,1e-8,1e99,'k') +plt.savefig('Force-'+str(sphere_type)+'-'+solver+'.png') + +# Errors +plt.figure(2) +plt.subplots(2,1,sharex=True) +plt.subplots_adjust(hspace=0) +plt.subplot(211) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],er1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.ylabel('$\mathrm{Radial\,error}$') +plt.subplot(212) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],et1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Tangential\,error}$') +plt.savefig('Errors-'+str(sphere_type)+'-'+solver+'.png') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere1/notes.txt b/run/APMGravitySolver/GravityTestSphere/FastSphere1/notes.txt new file mode 100644 index 000000000..a99899a80 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere1/notes.txt @@ -0,0 +1 @@ +Running fast solver with isothermal sphere diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzo b/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzo new file mode 100644 index 000000000..aa67b32e3 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzo @@ -0,0 +1,49 @@ +# +# AMR PROBLEM DEFINITION FILE: Gravity Test (Sphere) Problem +# +# define problem +# +ProblemType = 125 // Gravity test (Sphere) - APM version +TopGridRank = 3 +TopGridDimensions = 32 32 32 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 +UnigridTranspose = 0 +GravitySolverType = 0 // 0: fast, 1: APM +DepositAlsoParentGridAndSiblingsParticles = 0 +# +TestGravitySphereInteriorDensity = 1.0 //100000.0 +TestGravitySphereExteriorDensity = 1e-10 //0.01 +TestGravitySphereRadius = 0.3 +TestGravitySphereUseBaryons = 1 +TestGravitySphereType = 2 //0: constant, 1: r**-2, 2: r**-2.25 +TestGravitySphereRefineAtStart = 1 +TestGravitySphereCenter = 0.5 0.5 0.5 +#TestGravitySphereCenter = 0.484375 0.484375 0.484375 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +dtDataDump = 1e-10 +# +# set hydro parameters +# +WritePotential = 1 +CourantSafetyNumber = 0.5 // +PPMDiffusionParameter = 0 // diffusion off +HydroMethod = 0 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 //6 // use up to 3 levels +MaximumGravityRefinementLevel = 2 //6 +RefineBy = 2 // refinement factor +MinimumMassForRefinement = 3.e-6 +CellFlaggingMethod = 2 +FluxCorrection = 0 +ConservativeInterpolation = 0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzotest b/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzotest new file mode 100644 index 000000000..595ea90c3 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzotest @@ -0,0 +1,13 @@ +name = 'FastSphere2' +answer_testing_script = 'test_gravity.py' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere2/make_plot.py b/run/APMGravitySolver/GravityTestSphere/FastSphere2/make_plot.py new file mode 100644 index 000000000..977382912 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere2/make_plot.py @@ -0,0 +1,278 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import random +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +sphere_type = 2 +solver = 'Fast' +data = './DD0000/data0000' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +# constant density +def phi_anal0(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/(2*Rstar) * (3-r**2/Rstar**2) + return pot + +def acc_anal0(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar*r/Rstar**3 + return acc + +# 1/r**2 +def phi_anal1(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * (1 - np.log(r/Rstar)) + return pot + +def acc_anal1(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = Mstar/Rstar * 1/r + return acc + +# Plummer +def phi_anal2(r,Mstar,Rstar): + if (r > Rstar): + pot = -Mstar/r + else: + pot = -Mstar/Rstar * ( 2*np.sqrt(2)/np.sqrt(1.+r**2/Rstar**2) - 1 ) + return pot +def acc_anal2(r,Mstar,Rstar): + if (r > Rstar): + acc = Mstar/r**2 + else: + acc = 2*np.sqrt(2)*Mstar/Rstar**3 * r * (1.+r**2/Rstar**2)**-1.5 + return acc + +# Get Accelerations and Errors +def get_accelerations(data,Rho,Rstar): + + print("loading %s" % data) + pf = load(data) + pf.h.print_stats() + ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) + # Get grids per level + for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + + #---------------------------------------------------- + # Gas from AccelerationField.out + #---------------------------------------------------- + Files = glob.glob('AccelerationField.out*') + procs = [] + level_gas = [] + is_ghost_gas = [] + i_gas = [] + j_gas = [] + k_gas = [] + x_gas = [] + y_gas = [] + z_gas = [] + r_gas = [] + ax_gas = [] + ay_gas = [] + az_gas = [] + arad_gas = [] + atan_gas = [] + + for name in Files: + Data = np.loadtxt(name) + procs = procs + list(int(name[-4::])*np.ones(np.size(Data[:,0]),dtype=int)) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]) + y_gas = y_gas + list(Data[:,6]) + z_gas = z_gas + list(Data[:,7]) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + atan_gas = atan_gas + list(Data[:,12]) + arad_gas = arad_gas + list(Data[:,13]) + + procs = np.array(procs) + level_gas = np.array(level_gas) + is_ghost_gas = np.array(is_ghost_gas) + level_gas = level_gas.astype(int) + is_ghost_gas = is_ghost_gas.astype(int) + i_gas = np.array(i_gas) + j_gas = np.array(j_gas) + k_gas = np.array(k_gas) + x_gas = np.array(x_gas) + y_gas = np.array(y_gas) + z_gas = np.array(z_gas) + r_gas = np.array(r_gas) + ax_gas = np.array(ax_gas) + ay_gas = np.array(ay_gas) + az_gas = np.array(az_gas) + arad_gas = np.array(arad_gas) + atan_gas = np.array(atan_gas) + + # Remove all ghost zones + #Ind = ((is_ghost_gas == 0) | (level_gas > 0)).nonzero()[0] + Ind = [] + for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) + Ind = np.array(Ind) + + procs = procs[Ind] + level_gas = level_gas[Ind] + is_ghost_gas = is_ghost_gas[Ind] + i_gas = i_gas[Ind] + j_gas = j_gas[Ind] + k_gas = k_gas[Ind] + x_gas = x_gas[Ind] + y_gas = y_gas[Ind] + z_gas = z_gas[Ind] + r_gas = r_gas[Ind] + ax_gas = ax_gas[Ind] + ay_gas = ay_gas[Ind] + az_gas = az_gas[Ind] + arad_gas = arad_gas[Ind] + atan_gas = atan_gas[Ind] + + ngas = np.size(x_gas) + + # RMS + f_true = np.zeros(ngas) + Error1 = np.zeros(ngas) + Error2 = np.zeros(ngas) + for i in range(0,ngas,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal0(r_gas[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_true[i] = acc_anal1(r_gas[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_true[i] = acc_anal2(r_gas[i],Mstar,Rstar) + + Error1 = np.abs((arad_gas-f_true)/f_true) + Error2 = np.abs(atan_gas/f_true) + Mean1 = np.mean(Error1) + Mean2 = np.mean(Error2) + Rms1 = np.std(Error1) + Rms2 = np.std(Error2) + + return (ngrids_per_level,procs,level_gas,r_gas,arad_gas, + Error1,Error2,Mean1,Mean2,Rms1,Rms2) + +# Values for analytical solution +Rho = 1.0 +Rstar = 0.3 + +# Analytical solution +r_anal = np.arange(1e-3,1.1,1e-3) +n_anal = np.size(r_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + if (sphere_type == 0): + Mstar = 4/3. * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal0(r_anal[i],Mstar,Rstar) + elif (sphere_type == 1): + Mstar = 4 * np.pi * Rho * Rstar**3 + f_anal[i] = acc_anal1(r_anal[i],Mstar,Rstar) + elif (sphere_type == 2): + Mstar = 4/3. * np.pi * Rho * Rstar**3 / (2.*np.sqrt(2.)) + f_anal[i] = acc_anal2(r_anal[i],Mstar,Rstar) + else: + print("Wrong sphere type") + sys.exit() + +# Get accelerations, errors, etc... +(ngrids1,procs1,l1,r1,a1,er1,et1,mr1,mt1,rmsr1,rmst1) = get_accelerations(data,Rho,Rstar) + +# output relevant values +print("Radial force error = ", mr1, " +/- ", rmsr1) +print("Tangential force error = ", mt1, " +/- ", rmst1) + +# Plot +symbols = ['bx','ro','g.', 'c*'] +if (sphere_type == 0): + ylim_min = 1.1e-8 + ylim_max = 0.99 + legend_where = 'upper left' +elif (sphere_type == 1): + ylim_min = 1.1e-5 + ylim_max = 0.99 + legend_where = 'lower left' +else: + ylim_min = 1.1e-6 + ylim_max = 0.99 + legend_where = 'upper left' + +# All data (png) +# Radial acceleration +plt.figure(1) +plt.loglog(r_anal[0],f_anal[0],'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(l1)+1),1): + Ind2 = np.where(l1 == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids1[i]) + plt.loglog(r1[Ind2],a1[Ind2],symbols[i],label=txt) +plt.loglog(r_anal,f_anal,'k') + +# Limits +plt.xlim(6e-3,1.0) +if (sphere_type == 0): + plt.ylim(2e-2,2.0) +elif (sphere_type == 2): + plt.ylim(2e-2,0.7) +else: + plt.ylim(0.3,1e2) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Force}$') +plt.legend(loc=legend_where) +plt.vlines(Rstar,1e-8,1e99,'k') +plt.savefig('Force-'+str(sphere_type)+'-'+solver+'.png') + +# Errors +plt.figure(2) +plt.subplots(2,1,sharex=True) +plt.subplots_adjust(hspace=0) +plt.subplot(211) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],er1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.ylabel('$\mathrm{Radial\,error}$') +plt.subplot(212) +for i in range(0,int(max(l1)+1),1): + k = int(max(l1))-i + Ind2 = np.where(l1 == k) + plt.loglog(r1[Ind2],et1[Ind2],symbols[k]) +plt.vlines(Rstar,1e-8,1.0,'k') +plt.xlim(6e-3,1.0) +plt.ylim(ylim_min,ylim_max) +plt.xlabel('$r$') +plt.ylabel('$\mathrm{Tangential\,error}$') +plt.savefig('Errors-'+str(sphere_type)+'-'+solver+'.png') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/GravityTestSphere/FastSphere2/notes.txt b/run/APMGravitySolver/GravityTestSphere/FastSphere2/notes.txt new file mode 100644 index 000000000..919f78be9 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere2/notes.txt @@ -0,0 +1 @@ +Running fast solver with Plummer sphere diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzo b/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzo new file mode 100644 index 000000000..e6ca0f756 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 0 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 0.1 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzotest b/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzotest new file mode 100644 index 000000000..c5c51fc73 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'APM1RefLevel' +answer_testing_script = 'test_orbit' +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevel/make_plot.py b/run/APMGravitySolver/TestOrbit/APM1RefLevel/make_plot.py new file mode 100644 index 000000000..e0cdafae4 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevel/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 1 +diff_levels = 1 +subcycles = 0 +solver = "APM" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevel/notes.txt b/run/APMGravitySolver/TestOrbit/APM1RefLevel/notes.txt new file mode 100644 index 000000000..613890daa --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevel/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the APM solver with maximum one level of refinement and without timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzo b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzo new file mode 100644 index 000000000..a5573ae4f --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 1 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 0.1 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzotest b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzotest new file mode 100644 index 000000000..f27c08034 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'APM1RefLevelExtra' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/make_plot.py b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/make_plot.py new file mode 100644 index 000000000..233634858 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 0 +diff_levels = 1 +subcycles = 1 +solver = "APM" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/notes.txt b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/notes.txt new file mode 100644 index 000000000..9686069e9 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the APM solver with maximum one level of refinement and with timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzo b/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzo new file mode 100644 index 000000000..06cb95a98 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 0 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 1e-4 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzotest b/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzotest new file mode 100644 index 000000000..cb862b0bb --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'APM2RefLevel' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevel/make_plot.py b/run/APMGravitySolver/TestOrbit/APM2RefLevel/make_plot.py new file mode 100644 index 000000000..9a5a61caa --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevel/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 1 +diff_levels = 0 +subcycles = 0 +solver = "APM" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevel/notes.txt b/run/APMGravitySolver/TestOrbit/APM2RefLevel/notes.txt new file mode 100644 index 000000000..1780a2c55 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevel/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the APM solver with maximum two levels of refinement and without timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzo b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzo new file mode 100644 index 000000000..45e300417 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 1 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 1e-4 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzotest b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzotest new file mode 100644 index 000000000..aa2c909d0 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'APM2RefLevelExtra' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/make_plot.py b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/make_plot.py new file mode 100644 index 000000000..19d274e61 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 0 +diff_levels = 0 +subcycles = 1 +solver = "APM" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/notes.txt b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/notes.txt new file mode 100644 index 000000000..8b873caf3 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the APM solver with maximum two levels of refinement and with timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzo b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzo new file mode 100644 index 000000000..e2567a167 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 0 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 0.1 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzotest b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzotest new file mode 100644 index 000000000..8c48fcd9f --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'Fast1RefLevel' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevel/make_plot.py b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/make_plot.py new file mode 100644 index 000000000..c1d70206f --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 0 +diff_levels = 1 +subcycles = 0 +solver = "Fast" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevel/notes.txt b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/notes.txt new file mode 100644 index 000000000..cb18beb1f --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the fast solver with maximum one level of refinement and without timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzo b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzo new file mode 100644 index 000000000..bde8f2384 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 1 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 1 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 0.1 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzotest b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzotest new file mode 100644 index 000000000..e877d3e1c --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'Fast1RefLevelExtra' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/make_plot.py b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/make_plot.py new file mode 100644 index 000000000..c4575534e --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 0 +diff_levels = 1 +subcycles = 1 +solver = "Fast" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/notes.txt b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/notes.txt new file mode 100644 index 000000000..b45c6223f --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the fast solver with maximum one level of refinement and with timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzo b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzo new file mode 100644 index 000000000..17cdc4870 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 0 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 1e-4 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzotest b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzotest new file mode 100644 index 000000000..80d9a1a29 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'Fast2RefLevel' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevel/make_plot.py b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/make_plot.py new file mode 100644 index 000000000..3ff23fbb5 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 0 +diff_levels = 0 +subcycles = 0 +solver = "Fast" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevel/notes.txt b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/notes.txt new file mode 100644 index 000000000..52be6b4d6 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the fast solver with maximum two levels of refinement and without timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzo b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzo new file mode 100644 index 000000000..8bbc374fa --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzo @@ -0,0 +1,43 @@ +# +# AMR PROBLEM DEFINITION FILE: Orbit Test Problem +# +# define problem +# +ProblemType = 29 // orbit test +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# set problem parameters +# +TestOrbitRadius = 0.3 +TestOrbitCentralMass = 1.0 +TestOrbitTestMass = 0.1 +# +# set I/O and stop/start parameters +# +StopTime = 5.0 +MaximumTopGridTimeStep = 3e-3 +dtDataDump = 5.01 +# +HydroMethod = 0 +# +TimeSteppingRefinementCondition = 1 // Extra condition dt(l+1) = dt(l)/refinement +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 4 +MinimumMassForRefinement = 1e-4 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzotest b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzotest new file mode 100644 index 000000000..bec7615a2 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'Fast3RefLevelExtra' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 10 +fullsuite = True +pushsuite = False +quicksuite = False diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/make_plot.py b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/make_plot.py new file mode 100644 index 000000000..e2c3d54e7 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/make_plot.py @@ -0,0 +1,106 @@ +import numpy as na +import sys +from yt.mods import * +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from math import * +from yt.mods import * +from yt.utilities.linear_interpolators import * + +mpl.rcParams['figure.figsize'] = 6,6 +mpl.rc('xtick', labelsize=19) +mpl.rc('ytick', labelsize=19) +mpl.rcParams.update({'lines.linewidth':2.0}) +mpl.rcParams.update({'legend.numpoints': 1}) +mpl.rcParams.update({'legend.fontsize': 19}) +mpl.rcParams.update({'legend.frameon': False}) + +filename = "01.out" +zoom_box = 0 +diff_levels = 0 +subcycles = 1 +solver = "Fast" +dataname = "./DD0001/data0001" +size_dots = 2 +number_to_skip = 1 + +# legend +if (diff_levels): + line1 = "Particles in different levels" +else: + line1 = "Particles in same level" + +if (subcycles): + line2 = "with subcycling" +else: + line2 = "no subcycling" + +# nb of orbits +pf = load(dataname) +n_orbits = int(pf.current_time) +if (n_orbits > 1): + orbit_str = " orbits" +else: + orbit_str = " orbit" + +#textinfo1 = line1+"\n"+line2+"\n"+str(n_orbits)+orbit_str +#textinfo2 = solver+"\n"+str(nprocs)+proc_str +textinfo1 = line1+"\n"+line2+"\n" +textinfo2 = "\n"+solver + +with open(filename, "r") as FileIn: + xpos = [] + ypos = [] + xpos2 = [] + ypos2 = [] + for line in FileIn: + if 'id=1' in line: + lst = line.split() + xpos.append(float(lst[1])) + ypos.append(float(lst[2])) + if 'id=0' in line: + lst = line.split() + xpos2.append(float(lst[1])) + ypos2.append(float(lst[2])) + +x1 = na.array(xpos) +y1 = na.array(ypos) +x2 = na.array(xpos2) +y2 = na.array(ypos2) + +# plots orbit in x-y plane (should be a circle with zoom-in inset) +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.scatter(x1[::number_to_skip], y1[::number_to_skip], c='b', s=size_dots, lw=0, marker='.').figure +ax.scatter(x2[::number_to_skip], y2[::number_to_skip], c='r', s=size_dots, lw=0, marker='.').figure +ax.set_xlabel('x',fontsize=21) +ax.set_ylabel('y',fontsize=21) +ax.set_xlim([0.155,0.79]) +ax.set_ylim([0.182,0.818]) +ax.xaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) +ax.yaxis.set_major_locator(mpl.ticker.FixedLocator([0.2,0.3,0.4,0.5,0.6,0.7])) + +# legend +plt.text(0.16,0.735,textinfo1) +plt.text(0.16,0.20,textinfo2) + +if (zoom_box): + xbd = [0.709, 0.719] + ybd = [0.619, 0.629] + + wh = na.where((xbd[0] < x1) & (xbd[1] > x1) & (ybd[0] < y1) & (ybd[1] > y1)) + iax = zoomed_inset_axes(ax, 10, loc=1) + iax.scatter(x1[wh], y1[wh], marker='o', s=1, lw=0) + iax.xaxis.set_ticks([]) + iax.xaxis.set_label('x') + iax.yaxis.set_ticks([]) + iax.yaxis.set_label('y') + iax.set_xlim(xbd) + iax.set_ylim(ybd) + mark_inset(ax, iax, loc1=2, loc2=4, fc='none', ec='0.5') + +# Save +plt.savefig('Testorbit.png',bbox_inches='tight') +plt.close() diff --git a/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/notes.txt b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/notes.txt new file mode 100644 index 000000000..826f2e849 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/notes.txt @@ -0,0 +1 @@ +Running the same as TestOrbit but with the fast solver with maximum two levels of refinement and with timestepping according to the extra condition dt(l+1) <= dt(l)/refinement diff --git a/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzo b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzo new file mode 100644 index 000000000..e950bff83 --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzo @@ -0,0 +1,48 @@ +# +# AMR PROBLEM DEFINITION FILE: Test Self Force Problem +# +# define problem +# +ProblemType = 47 +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# Particle position and velocity +# +TestSelfForcePartciclePosition = 0.15 0.15 0.15 +TestSelfForcePartcicleVelocity = 1.0 1.0 1.0 +# set I/O and stop/start parameters +# +StopTime = 0.4 +MaximumTopGridTimeStep = 3e-3 // no subcycle=3e-3, subcycles=2.5e-2 +dtDataDump = 0.41 +# +HydroMethod = 0 +# +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +CellFlaggingMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 3 // use up to this many extra levels +RefineBy = 2 // refinement factor +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.1875 0.1875 0.1875 +StaticRefineRegionRightEdge[0] = 0.8125 0.8125 0.8125 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.3125 0.3125 0.3125 +StaticRefineRegionRightEdge[1] = 0.6875 0.6875 0.6875 +StaticRefineRegionLevel[2] = 2 +StaticRefineRegionLeftEdge[2] = 0.40625 0.40625 0.40625 +StaticRefineRegionRightEdge[2] = 0.59375 0.59375 0.59375 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzotest b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzotest new file mode 100644 index 000000000..62575a462 --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzotest @@ -0,0 +1,13 @@ +name = 'APMNoSubcycle' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/notes.txt b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/notes.txt new file mode 100644 index 000000000..8bf162c19 --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/notes.txt @@ -0,0 +1 @@ +A single particle going throught the grids with the APM solver but no subcycling. diff --git a/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzo b/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzo new file mode 100644 index 000000000..3f0010abc --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzo @@ -0,0 +1,48 @@ +# +# AMR PROBLEM DEFINITION FILE: Test Self Force Problem +# +# define problem +# +ProblemType = 47 +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +ParticleSubgridDepositMode = 0 +# +# Particle position and velocity +# +TestSelfForcePartciclePosition = 0.15 0.15 0.15 +TestSelfForcePartcicleVelocity = 1.0 1.0 1.0 +# set I/O and stop/start parameters +# +StopTime = 0.4 +MaximumTopGridTimeStep = 2.5e-2 // no subcycle=3e-3, subcycles=2.5e-2 +dtDataDump = 0.41 +# +HydroMethod = 0 +# +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +CellFlaggingMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 3 // use up to this many extra levels +RefineBy = 2 // refinement factor +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.1875 0.1875 0.1875 +StaticRefineRegionRightEdge[0] = 0.8125 0.8125 0.8125 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.3125 0.3125 0.3125 +StaticRefineRegionRightEdge[1] = 0.6875 0.6875 0.6875 +StaticRefineRegionLevel[2] = 2 +StaticRefineRegionLeftEdge[2] = 0.40625 0.40625 0.40625 +StaticRefineRegionRightEdge[2] = 0.59375 0.59375 0.59375 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzotest b/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzotest new file mode 100644 index 000000000..255e5c6ac --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzotest @@ -0,0 +1,13 @@ +name = 'APMSubcycle' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSelfForce/APMSubcycle/notes.txt b/run/APMGravitySolver/TestSelfForce/APMSubcycle/notes.txt new file mode 100644 index 000000000..3fabb4540 --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMSubcycle/notes.txt @@ -0,0 +1 @@ +A single particle going throught the grids with the APM solver and subcycling. diff --git a/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzo b/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzo new file mode 100644 index 000000000..0cf03f958 --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzo @@ -0,0 +1,48 @@ +# +# AMR PROBLEM DEFINITION FILE: Test Self Force Problem +# +# define problem +# +ProblemType = 47 +TopGridRank = 3 +TopGridDimensions = 16 16 16 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 1 // Isolated BCs +UnigridTranspose = 0 +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 0 +ParticleSubgridDepositMode = 0 +# +# Particle position and velocity +# +TestSelfForcePartciclePosition = 0.15 0.15 0.15 +TestSelfForcePartcicleVelocity = 1.0 1.0 1.0 +# set I/O and stop/start parameters +# +StopTime = 0.4 +MaximumTopGridTimeStep = 2.5e-2 // no subcycle=3e-3, subcycles=2.5e-2 +dtDataDump = 0.41 +# +HydroMethod = 0 +# +ParticleCourantSafetyNumber = 0.4 +# +# set grid refinement parameters +# +CellFlaggingMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 3 // use up to this many extra levels +RefineBy = 2 // refinement factor +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.1875 0.1875 0.1875 +StaticRefineRegionRightEdge[0] = 0.8125 0.8125 0.8125 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.3125 0.3125 0.3125 +StaticRefineRegionRightEdge[1] = 0.6875 0.6875 0.6875 +StaticRefineRegionLevel[2] = 2 +StaticRefineRegionLeftEdge[2] = 0.40625 0.40625 0.40625 +StaticRefineRegionRightEdge[2] = 0.59375 0.59375 0.59375 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzotest b/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzotest new file mode 100644 index 000000000..a1de2f25d --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzotest @@ -0,0 +1,13 @@ +name = 'FastSubcycle' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSelfForce/FastSubcycle/notes.txt b/run/APMGravitySolver/TestSelfForce/FastSubcycle/notes.txt new file mode 100644 index 000000000..51c56032b --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/FastSubcycle/notes.txt @@ -0,0 +1 @@ +A single particle going throught the grids with the Fast solver. diff --git a/run/APMGravitySolver/TestSelfForce/make_plot.py b/run/APMGravitySolver/TestSelfForce/make_plot.py new file mode 100644 index 000000000..abf0e8a1a --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/make_plot.py @@ -0,0 +1,102 @@ +import sys +import numpy as N +import matplotlib.pyplot as plt + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'lines.markersize':10.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) +matplotlib.rcParams.update({'figure.autolayout': True}) + +#-------------------------------------------------------------- +def get_offset(filename): + FileIn = open(filename, "r") + level = [] + time = [] + voffset = [] + root_cycle = [] + + rec = -1 + for line in FileIn: + if 'TopGrid' in line: + rec += 1 + if 'Level' in line: + lst = line.split() + level.append(int(lst[2][0])) + level.append(int(lst[2][0])) + if 'PARTICLE' in line: + lst = line.split() + root_cycle.append(rec) + time.append(float(lst[1])) + vx = float(lst[5]) + vy = float(lst[6]) + vz = float(lst[7]) + dv2 = (vx - 1.0)**2 + (vy - 1.0)**2 + (vz - 1.0)**2 + dv = N.sqrt(dv2/3.) + voffset.append(dv) + FileIn.close() + + level = N.array(level) + time = N.array(time) + voffset = N.array(voffset) + root_cycle = N.array(root_cycle) + + # only take the last point in a root grid cycle + Ind = [] + Ind.append(0) + for i in range(0,N.size(level),1): + if (i0)): + legen_str = 'level %i' %rec + plt.plot(time1[Ind][0],voffset1[Ind][0]/1e-4,colors1[rec],label=legen_str) + already_plot1[rec] = 1 + +for rec in range(0,N.max(level2)+1,1): + Ind = N.where(level2 == rec) + plt.plot(time2[Ind],voffset2[Ind]/1e-4,colors2[rec]) + if ((already_plot2[rec]==0) and (N.size(Ind)>0)): + legen_str = 'level %i' %rec + plt.plot(time2[Ind][0],voffset2[Ind][0]/1e-4,colors2[rec],label=legen_str) + already_plot2[rec] = 1 +plt.xlabel('$t$') +plt.ylabel('$\Delta v / 10^{-4}$') +plt.ylim(-0.1,1.5) +plt.xticks(N.arange(0.0, 0.411, 0.1)) +plt.savefig(fig_name) diff --git a/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzo b/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzo new file mode 100644 index 000000000..6fb517426 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzo @@ -0,0 +1,45 @@ +# +# AMR PROBLEM DEFINITION FILE: Poisson Sine Wave Test Problem +# AUthor: JC Passy +# +# define problem +# +ProblemType = 44 // Poisson Sine Wave +TopGridRank = 3 +TopGridDimensions = 64 64 64 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 0 // periodic BCs +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +# +# set problem parameters +# +TestGravitySineWaveAmplitude = 1.0 +TestGravitySineWavePeriod = 1.0 +TestGravitySineWaveAngle = 0.0 // degrees +TestGravitySineWaveRefineAtStart = 1 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +StopCycle = 1 +dtDataDump = 1e-10 +WritePotential = 1 +# +# set grid refinement parameters +# +HydroMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.35 0.0 0.0 +StaticRefineRegionRightEdge[0] = 0.65 1.0 1.0 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.425 0.0 0.0 +StaticRefineRegionRightEdge[1] = 0.575 1.0 1.0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzotest b/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzotest new file mode 100644 index 000000000..ba54531d0 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzotest @@ -0,0 +1,13 @@ +name = 'APMLongP' +answer_testing_script = 'test_gravity' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 2 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSineWave/APMLongP/make_plot.py b/run/APMGravitySolver/TestSineWave/APMLongP/make_plot.py new file mode 100644 index 000000000..b1782fde0 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMLongP/make_plot.py @@ -0,0 +1,191 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +period = 1.0 +solver = 'APM' +data = './DD0001/data0001' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +def anal_solution_acc(period,x): + val = 4*np.pi*period/(2.*np.pi) * np.cos(x*2*np.pi/period) + return val + + +def anal_solution_pot(period,x): + val = -4*np.pi*(period/(2.*np.pi))**2 * np.sin(x*2*np.pi/period) + return val +#-------------------------------------------------------------- + +print("loading %s" % data) +pf = load(data) +resol = pf.domain_dimensions[0] +pf.h.print_stats() +ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) +# Get grids per level +for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + +#---------------------------------------------------- +# Gas from AccelerationField.out +#---------------------------------------------------- +Files = glob.glob('AccelerationField.out*_p0000') +level_gas = [] +is_ghost_gas = [] +i_gas = [] +j_gas = [] +k_gas = [] +x_gas = [] +y_gas = [] +z_gas = [] +r_gas = [] +ax_gas = [] +ay_gas = [] +az_gas = [] + +for name in Files: + Data = np.loadtxt(name) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]+0.5) # so coordinates go from 0 to 1 instead of -0.5 to 0.5 + y_gas = y_gas + list(Data[:,6]+0.5) + z_gas = z_gas + list(Data[:,7]+0.5) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + +level_gas = np.array(level_gas) +is_ghost_gas = np.array(is_ghost_gas) +level_gas = level_gas.astype(int) +is_ghost_gas = is_ghost_gas.astype(int) +i_gas = np.array(i_gas) +j_gas = np.array(j_gas) +k_gas = np.array(k_gas) +x_gas = np.array(x_gas) +y_gas = np.array(y_gas) +z_gas = np.array(z_gas) +r_gas = np.array(r_gas) +ax_gas = np.array(ax_gas) +ay_gas = np.array(ay_gas) +az_gas = np.array(az_gas) + +# Remove all ghost zones +Ind = [] +for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) +Ind = np.array(Ind) + +level_gas = level_gas[Ind] +is_ghost_gas = is_ghost_gas[Ind] +i_gas = i_gas[Ind] +j_gas = j_gas[Ind] +k_gas = k_gas[Ind] +x_gas = x_gas[Ind] +y_gas = y_gas[Ind] +z_gas = z_gas[Ind] +r_gas = r_gas[Ind] +ax_gas = ax_gas[Ind] +ay_gas = ay_gas[Ind] +az_gas = az_gas[Ind] + +ngas = np.size(x_gas) + +# Analytical solution +x_anal = np.arange(-0.1,1.1,1e-3) +n_anal = np.size(x_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + f_anal[i] = anal_solution_acc(period,x_anal[i]) + +# RMS +f_true = np.zeros(ngas) +for i in range(0,ngas,1): + f_true[i] = anal_solution_acc(period,x_gas[i]) + +atan_gas = (ay_gas**2. + az_gas**2.)**0.5 +Error = np.abs((ax_gas-f_true)/f_true) +Mean = np.mean(Error) +Rms = np.std(Error) +Error2 = np.abs(atan_gas/f_true) +Mean2 = np.mean(Error2) +Rms2 = np.std(Error2) + +# Plot +symbols = ['bx','ro','g.', 'c*'] + +# limits +if (period == 0.2): + xmin = np.min(x_gas)-1e-2 + xmax = np.max(x_gas)+1e-2 + ymin_anal = -0.5 + ymax_anal = 0.5 + if(resol == 32): + ymin = 0.01 + ymax = 0.5 + else: + ymin = 5e-3 + ymax = 0.2 +else: # period == 1.0 + xmin = 0.28 + xmax = 0.72 + ymin_anal = -2.1 + ymax_anal = -0.5 + if (resol == 32): + ymin = 4e-4 + ymax = 1e-2 + else: + ymin = 7e-5 + ymax = 2e-3 + +# Accelerations all, png +plt.figure(1) +plt.plot(x_anal,f_anal,'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + plt.plot(x_gas[Ind],ax_gas[Ind],symbols[i],label=txt) + +plt.xlim(xmin,xmax) +if (period == 0.2): + plt.ylim(-0.5,0.5) +else: + plt.ylim(-2.1,-0.5) +plt.xlabel('$x$') +plt.ylabel('$\mathrm{Force}$') +plt.savefig('Forces-'+str(period)+'-'+solver+'.png',bbox_inches='tight') + +# Errors all, png +fig, ax1 = plt.subplots() +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + ax1.semilogy(x_gas[Ind],Error[Ind],symbols[i],label=txt) +ax1.set_xlabel('$x$') +ax1.set_ylabel('$\mathrm{Force\,Error}$') +ax1.set_xlim(xmin,xmax) + +ax2 = ax1.twinx() +ax2.plot(x_anal, f_anal, 'k--') +ax2.set_xlim(xmin,xmax) +ax2.set_ylim(ymin_anal,ymax_anal) +ax2.set_ylabel('$\mathrm{Force}$', color='k') +plt.savefig('Errors-'+str(period)+'-'+solver+'.png',bbox_inches='tight') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/TestSineWave/APMLongP/notes.txt b/run/APMGravitySolver/TestSineWave/APMLongP/notes.txt new file mode 100644 index 000000000..291dd922e --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMLongP/notes.txt @@ -0,0 +1 @@ +APM solver computing the acceleration field created by a sine wave with a long perdiod. diff --git a/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzo b/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzo new file mode 100644 index 000000000..3ef50ae87 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzo @@ -0,0 +1,45 @@ +# +# AMR PROBLEM DEFINITION FILE: Poisson Sine Wave Test Problem +# AUthor: JC Passy +# +# define problem +# +ProblemType = 44 // Poisson Sine Wave +TopGridRank = 3 +TopGridDimensions = 64 64 64 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 0 // periodic BCs +GravitySolverType = 1 +DepositAlsoParentGridAndSiblingsParticles = 1 +# +# set problem parameters +# +TestGravitySineWaveAmplitude = 1.0 +TestGravitySineWavePeriod = 0.2 +TestGravitySineWaveAngle = 0.0 // degrees +TestGravitySineWaveRefineAtStart = 1 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +StopCycle = 1 +dtDataDump = 1e-10 +WritePotential = 1 +# +# set grid refinement parameters +# +HydroMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.35 0.0 0.0 +StaticRefineRegionRightEdge[0] = 0.65 1.0 1.0 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.425 0.0 0.0 +StaticRefineRegionRightEdge[1] = 0.575 1.0 1.0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzotest b/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzotest new file mode 100644 index 000000000..9a1a05eee --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzotest @@ -0,0 +1,13 @@ +name = 'APMShortP' +answer_testing_script = 'test_gravity' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSineWave/APMShortP/make_plot.py b/run/APMGravitySolver/TestSineWave/APMShortP/make_plot.py new file mode 100644 index 000000000..8688a63a0 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMShortP/make_plot.py @@ -0,0 +1,191 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +period = 0.2 +solver = 'APM' +data = './DD0001/data0001' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +def anal_solution_acc(period,x): + val = 4*np.pi*period/(2.*np.pi) * np.cos(x*2*np.pi/period) + return val + + +def anal_solution_pot(period,x): + val = -4*np.pi*(period/(2.*np.pi))**2 * np.sin(x*2*np.pi/period) + return val +#-------------------------------------------------------------- + +print("loading %s" % data) +pf = load(data) +resol = pf.domain_dimensions[0] +pf.h.print_stats() +ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) +# Get grids per level +for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + +#---------------------------------------------------- +# Gas from AccelerationField.out +#---------------------------------------------------- +Files = glob.glob('AccelerationField.out*_p0000') +level_gas = [] +is_ghost_gas = [] +i_gas = [] +j_gas = [] +k_gas = [] +x_gas = [] +y_gas = [] +z_gas = [] +r_gas = [] +ax_gas = [] +ay_gas = [] +az_gas = [] + +for name in Files: + Data = np.loadtxt(name) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]+0.5) # so coordinates go from 0 to 1 instead of -0.5 to 0.5 + y_gas = y_gas + list(Data[:,6]+0.5) + z_gas = z_gas + list(Data[:,7]+0.5) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + +level_gas = np.array(level_gas) +is_ghost_gas = np.array(is_ghost_gas) +level_gas = level_gas.astype(int) +is_ghost_gas = is_ghost_gas.astype(int) +i_gas = np.array(i_gas) +j_gas = np.array(j_gas) +k_gas = np.array(k_gas) +x_gas = np.array(x_gas) +y_gas = np.array(y_gas) +z_gas = np.array(z_gas) +r_gas = np.array(r_gas) +ax_gas = np.array(ax_gas) +ay_gas = np.array(ay_gas) +az_gas = np.array(az_gas) + +# Remove all ghost zones +Ind = [] +for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) +Ind = np.array(Ind) + +level_gas = level_gas[Ind] +is_ghost_gas = is_ghost_gas[Ind] +i_gas = i_gas[Ind] +j_gas = j_gas[Ind] +k_gas = k_gas[Ind] +x_gas = x_gas[Ind] +y_gas = y_gas[Ind] +z_gas = z_gas[Ind] +r_gas = r_gas[Ind] +ax_gas = ax_gas[Ind] +ay_gas = ay_gas[Ind] +az_gas = az_gas[Ind] + +ngas = np.size(x_gas) + +# Analytical solution +x_anal = np.arange(-0.1,1.1,1e-3) +n_anal = np.size(x_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + f_anal[i] = anal_solution_acc(period,x_anal[i]) + +# RMS +f_true = np.zeros(ngas) +for i in range(0,ngas,1): + f_true[i] = anal_solution_acc(period,x_gas[i]) + +atan_gas = (ay_gas**2. + az_gas**2.)**0.5 +Error = np.abs((ax_gas-f_true)/f_true) +Mean = np.mean(Error) +Rms = np.std(Error) +Error2 = np.abs(atan_gas/f_true) +Mean2 = np.mean(Error2) +Rms2 = np.std(Error2) + +# Plot +symbols = ['bx','ro','g.', 'c*'] + +# limits +if (period == 0.2): + xmin = np.min(x_gas)-1e-2 + xmax = np.max(x_gas)+1e-2 + ymin_anal = -0.5 + ymax_anal = 0.5 + if(resol == 32): + ymin = 0.01 + ymax = 0.5 + else: + ymin = 5e-3 + ymax = 0.2 +else: # period == 1.0 + xmin = 0.28 + xmax = 0.72 + ymin_anal = -2.1 + ymax_anal = -0.5 + if (resol == 32): + ymin = 4e-4 + ymax = 1e-2 + else: + ymin = 7e-5 + ymax = 2e-3 + +# Accelerations all, png +plt.figure(1) +plt.plot(x_anal,f_anal,'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + plt.plot(x_gas[Ind],ax_gas[Ind],symbols[i],label=txt) + +plt.xlim(xmin,xmax) +if (period == 0.2): + plt.ylim(-0.5,0.5) +else: + plt.ylim(-2.1,-0.5) +plt.xlabel('$x$') +plt.ylabel('$\mathrm{Force}$') +plt.savefig('Forces-'+str(period)+'-'+solver+'.png',bbox_inches='tight') + +# Errors all, png +fig, ax1 = plt.subplots() +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + ax1.semilogy(x_gas[Ind],Error[Ind],symbols[i],label=txt) +ax1.set_xlabel('$x$') +ax1.set_ylabel('$\mathrm{Force\,Error}$') +ax1.set_xlim(xmin,xmax) + +ax2 = ax1.twinx() +ax2.plot(x_anal, f_anal, 'k--') +ax2.set_xlim(xmin,xmax) +ax2.set_ylim(ymin_anal,ymax_anal) +ax2.set_ylabel('$\mathrm{Force}$', color='k') +plt.savefig('Errors-'+str(period)+'-'+solver+'.png',bbox_inches='tight') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/TestSineWave/APMShortP/notes.txt b/run/APMGravitySolver/TestSineWave/APMShortP/notes.txt new file mode 100644 index 000000000..c32181b1b --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMShortP/notes.txt @@ -0,0 +1 @@ +APM solver computing the acceleration field created by a sine wave with a short perdiod. diff --git a/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzo b/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzo new file mode 100644 index 000000000..fb4fafad0 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzo @@ -0,0 +1,45 @@ +# +# AMR PROBLEM DEFINITION FILE: Poisson Sine Wave Test Problem +# AUthor: JC Passy +# +# define problem +# +ProblemType = 44 // Poisson Sine Wave +TopGridRank = 3 +TopGridDimensions = 64 64 64 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 0 // periodic BCs +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 0 +# +# set problem parameters +# +TestGravitySineWaveAmplitude = 1.0 +TestGravitySineWavePeriod = 1.0 +TestGravitySineWaveAngle = 0.0 // degrees +TestGravitySineWaveRefineAtStart = 1 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +StopCycle = 1 +dtDataDump = 1e-10 +WritePotential = 1 +# +# set grid refinement parameters +# +HydroMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.35 0.0 0.0 +StaticRefineRegionRightEdge[0] = 0.65 1.0 1.0 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.425 0.0 0.0 +StaticRefineRegionRightEdge[1] = 0.575 1.0 1.0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzotest b/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzotest new file mode 100644 index 000000000..9a42fb8ad --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzotest @@ -0,0 +1,13 @@ +name = 'FastLongP' +answer_testing_script = 'test_gravity' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSineWave/FastLongP/make_plot.py b/run/APMGravitySolver/TestSineWave/FastLongP/make_plot.py new file mode 100644 index 000000000..2f8cf0c18 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastLongP/make_plot.py @@ -0,0 +1,191 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +period = 1.0 +solver = 'Fast' +data = './DD0001/data0001' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +def anal_solution_acc(period,x): + val = 4*np.pi*period/(2.*np.pi) * np.cos(x*2*np.pi/period) + return val + + +def anal_solution_pot(period,x): + val = -4*np.pi*(period/(2.*np.pi))**2 * np.sin(x*2*np.pi/period) + return val +#-------------------------------------------------------------- + +print("loading %s" % data) +pf = load(data) +resol = pf.domain_dimensions[0] +pf.h.print_stats() +ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) +# Get grids per level +for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + +#---------------------------------------------------- +# Gas from AccelerationField.out +#---------------------------------------------------- +Files = glob.glob('AccelerationField.out*_p0000') +level_gas = [] +is_ghost_gas = [] +i_gas = [] +j_gas = [] +k_gas = [] +x_gas = [] +y_gas = [] +z_gas = [] +r_gas = [] +ax_gas = [] +ay_gas = [] +az_gas = [] + +for name in Files: + Data = np.loadtxt(name) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]+0.5) # so coordinates go from 0 to 1 instead of -0.5 to 0.5 + y_gas = y_gas + list(Data[:,6]+0.5) + z_gas = z_gas + list(Data[:,7]+0.5) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + +level_gas = np.array(level_gas) +is_ghost_gas = np.array(is_ghost_gas) +level_gas = level_gas.astype(int) +is_ghost_gas = is_ghost_gas.astype(int) +i_gas = np.array(i_gas) +j_gas = np.array(j_gas) +k_gas = np.array(k_gas) +x_gas = np.array(x_gas) +y_gas = np.array(y_gas) +z_gas = np.array(z_gas) +r_gas = np.array(r_gas) +ax_gas = np.array(ax_gas) +ay_gas = np.array(ay_gas) +az_gas = np.array(az_gas) + +# Remove all ghost zones +Ind = [] +for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) +Ind = np.array(Ind) + +level_gas = level_gas[Ind] +is_ghost_gas = is_ghost_gas[Ind] +i_gas = i_gas[Ind] +j_gas = j_gas[Ind] +k_gas = k_gas[Ind] +x_gas = x_gas[Ind] +y_gas = y_gas[Ind] +z_gas = z_gas[Ind] +r_gas = r_gas[Ind] +ax_gas = ax_gas[Ind] +ay_gas = ay_gas[Ind] +az_gas = az_gas[Ind] + +ngas = np.size(x_gas) + +# Analytical solution +x_anal = np.arange(-0.1,1.1,1e-3) +n_anal = np.size(x_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + f_anal[i] = anal_solution_acc(period,x_anal[i]) + +# RMS +f_true = np.zeros(ngas) +for i in range(0,ngas,1): + f_true[i] = anal_solution_acc(period,x_gas[i]) + +atan_gas = (ay_gas**2. + az_gas**2.)**0.5 +Error = np.abs((ax_gas-f_true)/f_true) +Mean = np.mean(Error) +Rms = np.std(Error) +Error2 = np.abs(atan_gas/f_true) +Mean2 = np.mean(Error2) +Rms2 = np.std(Error2) + +# Plot +symbols = ['bx','ro','g.', 'c*'] + +# limits +if (period == 0.2): + xmin = np.min(x_gas)-1e-2 + xmax = np.max(x_gas)+1e-2 + ymin_anal = -0.5 + ymax_anal = 0.5 + if(resol == 32): + ymin = 0.01 + ymax = 0.5 + else: + ymin = 5e-3 + ymax = 0.2 +else: # period == 1.0 + xmin = 0.28 + xmax = 0.72 + ymin_anal = -2.1 + ymax_anal = -0.5 + if (resol == 32): + ymin = 4e-4 + ymax = 1e-2 + else: + ymin = 7e-5 + ymax = 2e-3 + +# Accelerations all, png +plt.figure(1) +plt.plot(x_anal,f_anal,'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + plt.plot(x_gas[Ind],ax_gas[Ind],symbols[i],label=txt) + +plt.xlim(xmin,xmax) +if (period == 0.2): + plt.ylim(-0.5,0.5) +else: + plt.ylim(-2.1,-0.5) +plt.xlabel('$x$') +plt.ylabel('$\mathrm{Force}$') +plt.savefig('Forces-'+str(period)+'-'+solver+'.png',bbox_inches='tight') + +# Errors all, png +fig, ax1 = plt.subplots() +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + ax1.semilogy(x_gas[Ind],Error[Ind],symbols[i],label=txt) +ax1.set_xlabel('$x$') +ax1.set_ylabel('$\mathrm{Force\,Error}$') +ax1.set_xlim(xmin,xmax) + +ax2 = ax1.twinx() +ax2.plot(x_anal, f_anal, 'k--') +ax2.set_xlim(xmin,xmax) +ax2.set_ylim(ymin_anal,ymax_anal) +ax2.set_ylabel('$\mathrm{Force}$', color='k') +plt.savefig('Errors-'+str(period)+'-'+solver+'.png',bbox_inches='tight') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/TestSineWave/FastLongP/notes.txt b/run/APMGravitySolver/TestSineWave/FastLongP/notes.txt new file mode 100644 index 000000000..56d0157e6 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastLongP/notes.txt @@ -0,0 +1 @@ +Fast solver computing the acceleration field created by a sine wave with a long perdiod. diff --git a/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzo b/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzo new file mode 100644 index 000000000..7082cbfe4 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzo @@ -0,0 +1,45 @@ +# +# AMR PROBLEM DEFINITION FILE: Poisson Sine Wave Test Problem +# AUthor: JC Passy +# +# define problem +# +ProblemType = 44 // Poisson Sine Wave +TopGridRank = 3 +TopGridDimensions = 64 64 64 +SelfGravity = 1 // gravity on +TopGridGravityBoundary = 0 // periodic BCs +GravitySolverType = 0 +DepositAlsoParentGridAndSiblingsParticles = 0 +# +# set problem parameters +# +TestGravitySineWaveAmplitude = 1.0 +TestGravitySineWavePeriod = 0.2 +TestGravitySineWaveAngle = 0.0 // degrees +TestGravitySineWaveRefineAtStart = 1 +# +# set I/O and stop/start parameters +# +StopTime = 1e-10 +StopCycle = 1 +dtDataDump = 1e-10 +WritePotential = 1 +# +# set grid refinement parameters +# +HydroMethod = 0 +StaticHierarchy = 0 // dynamic hierarchy +MaximumRefinementLevel = 2 // use up to this many extra levels +RefineBy = 2 // refinement factor +CellFlaggingMethod = 0 +StaticRefineRegionLevel[0] = 0 +StaticRefineRegionLeftEdge[0] = 0.35 0.0 0.0 +StaticRefineRegionRightEdge[0] = 0.65 1.0 1.0 +StaticRefineRegionLevel[1] = 1 +StaticRefineRegionLeftEdge[1] = 0.425 0.0 0.0 +StaticRefineRegionRightEdge[1] = 0.575 1.0 1.0 +# +# set some global parameters +# +tiny_number = 1.0e-10 // fixes velocity slope problem diff --git a/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzotest b/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzotest new file mode 100644 index 000000000..bb0e0888e --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzotest @@ -0,0 +1,13 @@ +name = 'FastShortP' +answer_testing_script = 'test_gravity' +nprocs = 4 +runtime = 'short' +hydro = True +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 1 +fullsuite = True +pushsuite = True +quicksuite = True diff --git a/run/APMGravitySolver/TestSineWave/FastShortP/make_plot.py b/run/APMGravitySolver/TestSineWave/FastShortP/make_plot.py new file mode 100644 index 000000000..ec4bf7d6f --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastShortP/make_plot.py @@ -0,0 +1,191 @@ +import sys +import numpy as np +import matplotlib.pyplot as plt +from yt.mods import * +import glob + +import matplotlib +matplotlib.rc('xtick', labelsize=19) +matplotlib.rc('ytick', labelsize=19) +matplotlib.rcParams.update({'font.size': 21}) +matplotlib.rcParams.update({'lines.linewidth':2.0}) +matplotlib.rcParams.update({'legend.numpoints': 1}) +matplotlib.rcParams.update({'legend.fontsize': 19}) +matplotlib.rcParams.update({'legend.frameon': False}) + +#-------------------------------------------------------------- +period = 0.2 +solver = 'Fast' +data = './DD0001/data0001' +#-------------------------------------------------------------- + +#-------------------------------------------------------------- +def anal_solution_acc(period,x): + val = 4*np.pi*period/(2.*np.pi) * np.cos(x*2*np.pi/period) + return val + + +def anal_solution_pot(period,x): + val = -4*np.pi*(period/(2.*np.pi))**2 * np.sin(x*2*np.pi/period) + return val +#-------------------------------------------------------------- + +print("loading %s" % data) +pf = load(data) +resol = pf.domain_dimensions[0] +pf.h.print_stats() +ngrids_per_level = np.zeros(np.max(pf.h.ds.index.grid_levels)+1) +# Get grids per level +for grid in pf.h.ds.index.grids: + ngrids_per_level[grid.Level] += 1 + +#---------------------------------------------------- +# Gas from AccelerationField.out +#---------------------------------------------------- +Files = glob.glob('AccelerationField.out*_p0000') +level_gas = [] +is_ghost_gas = [] +i_gas = [] +j_gas = [] +k_gas = [] +x_gas = [] +y_gas = [] +z_gas = [] +r_gas = [] +ax_gas = [] +ay_gas = [] +az_gas = [] + +for name in Files: + Data = np.loadtxt(name) + level_gas = level_gas + list(Data[:,0]) + is_ghost_gas = is_ghost_gas + list(Data[:,1]) + i_gas = i_gas + list(Data[:,2]) + j_gas = j_gas + list(Data[:,3]) + k_gas = k_gas + list(Data[:,4]) + x_gas = x_gas + list(Data[:,5]+0.5) # so coordinates go from 0 to 1 instead of -0.5 to 0.5 + y_gas = y_gas + list(Data[:,6]+0.5) + z_gas = z_gas + list(Data[:,7]+0.5) + r_gas = r_gas + list(Data[:,8]) + ax_gas = ax_gas + list(Data[:,9]) + ay_gas = ay_gas + list(Data[:,10]) + az_gas = az_gas + list(Data[:,11]) + +level_gas = np.array(level_gas) +is_ghost_gas = np.array(is_ghost_gas) +level_gas = level_gas.astype(int) +is_ghost_gas = is_ghost_gas.astype(int) +i_gas = np.array(i_gas) +j_gas = np.array(j_gas) +k_gas = np.array(k_gas) +x_gas = np.array(x_gas) +y_gas = np.array(y_gas) +z_gas = np.array(z_gas) +r_gas = np.array(r_gas) +ax_gas = np.array(ax_gas) +ay_gas = np.array(ay_gas) +az_gas = np.array(az_gas) + +# Remove all ghost zones +Ind = [] +for i in range(0,np.size(x_gas)): + if (is_ghost_gas[i] == 0): + Ind.append(i) +Ind = np.array(Ind) + +level_gas = level_gas[Ind] +is_ghost_gas = is_ghost_gas[Ind] +i_gas = i_gas[Ind] +j_gas = j_gas[Ind] +k_gas = k_gas[Ind] +x_gas = x_gas[Ind] +y_gas = y_gas[Ind] +z_gas = z_gas[Ind] +r_gas = r_gas[Ind] +ax_gas = ax_gas[Ind] +ay_gas = ay_gas[Ind] +az_gas = az_gas[Ind] + +ngas = np.size(x_gas) + +# Analytical solution +x_anal = np.arange(-0.1,1.1,1e-3) +n_anal = np.size(x_anal) +f_anal = np.zeros(n_anal) +for i in range(0,n_anal,1): + f_anal[i] = anal_solution_acc(period,x_anal[i]) + +# RMS +f_true = np.zeros(ngas) +for i in range(0,ngas,1): + f_true[i] = anal_solution_acc(period,x_gas[i]) + +atan_gas = (ay_gas**2. + az_gas**2.)**0.5 +Error = np.abs((ax_gas-f_true)/f_true) +Mean = np.mean(Error) +Rms = np.std(Error) +Error2 = np.abs(atan_gas/f_true) +Mean2 = np.mean(Error2) +Rms2 = np.std(Error2) + +# Plot +symbols = ['bx','ro','g.', 'c*'] + +# limits +if (period == 0.2): + xmin = np.min(x_gas)-1e-2 + xmax = np.max(x_gas)+1e-2 + ymin_anal = -0.5 + ymax_anal = 0.5 + if(resol == 32): + ymin = 0.01 + ymax = 0.5 + else: + ymin = 5e-3 + ymax = 0.2 +else: # period == 1.0 + xmin = 0.28 + xmax = 0.72 + ymin_anal = -2.1 + ymax_anal = -0.5 + if (resol == 32): + ymin = 4e-4 + ymax = 1e-2 + else: + ymin = 7e-5 + ymax = 2e-3 + +# Accelerations all, png +plt.figure(1) +plt.plot(x_anal,f_anal,'k',label='$F_{\mathrm{anal}}$') +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + plt.plot(x_gas[Ind],ax_gas[Ind],symbols[i],label=txt) + +plt.xlim(xmin,xmax) +if (period == 0.2): + plt.ylim(-0.5,0.5) +else: + plt.ylim(-2.1,-0.5) +plt.xlabel('$x$') +plt.ylabel('$\mathrm{Force}$') +plt.savefig('Forces-'+str(period)+'-'+solver+'.png',bbox_inches='tight') + +# Errors all, png +fig, ax1 = plt.subplots() +for i in range(0,int(max(level_gas)+1),1): + Ind = np.where(level_gas == i) + txt = '$F_{\mathrm{rad, %i}}$ (%i grids)' %(i,ngrids_per_level[i]) + ax1.semilogy(x_gas[Ind],Error[Ind],symbols[i],label=txt) +ax1.set_xlabel('$x$') +ax1.set_ylabel('$\mathrm{Force\,Error}$') +ax1.set_xlim(xmin,xmax) + +ax2 = ax1.twinx() +ax2.plot(x_anal, f_anal, 'k--') +ax2.set_xlim(xmin,xmax) +ax2.set_ylim(ymin_anal,ymax_anal) +ax2.set_ylabel('$\mathrm{Force}$', color='k') +plt.savefig('Errors-'+str(period)+'-'+solver+'.png',bbox_inches='tight') +#---------------------------------------------------- diff --git a/run/APMGravitySolver/TestSineWave/FastShortP/notes.txt b/run/APMGravitySolver/TestSineWave/FastShortP/notes.txt new file mode 100644 index 000000000..9ec4569a9 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastShortP/notes.txt @@ -0,0 +1 @@ +Fast solver computing the acceleration field created by a sine wave with a short perdiod. diff --git a/run/GravitySolver/GravityTest/GravityTest__test_gravity.py b/run/GravitySolver/GravityTest/GravityTest__test_gravity.py index 16f6f9f69..2c1f32be7 100644 --- a/run/GravitySolver/GravityTest/GravityTest__test_gravity.py +++ b/run/GravitySolver/GravityTest/GravityTest__test_gravity.py @@ -21,9 +21,9 @@ def __init__(self): def run(self): Data = np.loadtxt("TestGravityCheckResults.out") - radius = Data[:,0] - ForceRadialComputed = Data[:,2] - ForceRadialTrue = Data[:,3] + radius = Data[:,4] + ForceRadialComputed = Data[:,6] + ForceRadialTrue = Data[:,7] Error = (ForceRadialComputed-ForceRadialTrue)/ForceRadialTrue indices = np.where((radius > 1.0) & (radius < 8.0)) diff --git a/run/test_runner.py b/run/test_runner.py index 1926df70f..fead7088f 100755 --- a/run/test_runner.py +++ b/run/test_runner.py @@ -16,6 +16,7 @@ import multiprocessing known_categories = [ + "APMGravitySolver", "Cooling", "Cosmology", "CosmologySimulation", @@ -128,7 +129,7 @@ def _get_current_version(path): def _to_walltime(ts): return "%02d:%02d:%02d" % \ - ((ts / 3600), ((ts % 3600) / 60), + ((ts / 3600), ((ts % 3600) / 60), (ts % 60)) def add_files(my_list, dirname, fns): @@ -213,19 +214,19 @@ def finalize(self, result, outfile=None, sims_not_finished=[], sim_only=False): print('(Try rerunning each/all with --time-multiplier=2)') outfile.write('Simulations which did not finish in allocated time:\n') outfile.write('(Try rerunning each/all with --time-multiplier=2)\n') - for notfin in sims_not_finished: + for notfin in sims_not_finished: print(notfin) outfile.write(notfin + '\n') outfile.write('\n') outfile.write('Tests that passed: \n') - for suc in self.successes: + for suc in self.successes: outfile.write(suc) outfile.write('\n') outfile.write('\n') outfile.write('Tests that failed:\n') - for fail in self.failures: + for fail in self.failures: for li, line in enumerate(fail.split('\\n')): if li > 0: outfile.write(' ') outfile.write(line) @@ -233,7 +234,7 @@ def finalize(self, result, outfile=None, sims_not_finished=[], sim_only=False): outfile.write('\n') outfile.write('Tests that errored:\n') - for err in self.errors: + for err in self.errors: for li, line in enumerate(err.split('\\n')): if li > 0: outfile.write(' ') outfile.write(line) @@ -284,7 +285,7 @@ def go(self, output_dir, interleaved, machine, exe_path, sim_only=False, if interleaved: for i, my_test in enumerate(self.tests): print("Preparing test: %s." % my_test['name']) - self.test_container.append(EnzoTestRun(output_dir, my_test, + self.test_container.append(EnzoTestRun(output_dir, my_test, machine, exe_path, args=self.args, plugins=self.plugins)) @@ -310,7 +311,7 @@ def prepare_all_tests(self, output_dir, machine, exe_path): print("Preparing all tests.") for i, my_test in enumerate(self.tests): print("Preparing test: %s." % my_test['name']) - self.test_container.append(EnzoTestRun(output_dir, my_test, + self.test_container.append(EnzoTestRun(output_dir, my_test, machine, exe_path, args = self.args, plugins = self.plugins, @@ -345,17 +346,17 @@ def add_test(self, fn): # its environment variables from it. local_vars = {} - # python 2/3 compatibility + # python 2/3 compatibility if sys.version_info[0] > 2: exec(open(fn).read(), {}, local_vars) else: execfile(fn, {}, local_vars) - + test_spec = variable_defaults.copy() test_spec['fullpath'] = fn test_spec['fulldir'] = os.path.dirname(fn) test_spec['run_par_file'] = os.path.basename(test_spec['fulldir']) + ".enzo" - test_spec['run_walltime'] = _to_walltime(60 * test_spec['max_time_minutes'] * + test_spec['run_walltime'] = _to_walltime(60 * test_spec['max_time_minutes'] * options.time_multiplier) for var, val in local_vars.items(): if var in known_variables: @@ -407,7 +408,7 @@ def summary(self): def save_test_summary(self): f = open(os.path.join(self.output_dir, results_filename), 'w') - self.plugins[1].finalize(None, outfile=f, sims_not_finished=self.sims_not_finished, + self.plugins[1].finalize(None, outfile=f, sims_not_finished=self.sims_not_finished, sim_only=self.sim_only) f.close() @@ -453,7 +454,7 @@ def _copy_test_files(self): shutil.copy(os.path.join(self.test_dir, version_filename), os.path.join(self.run_dir, version_filename)) if self.exe_path is not None: - os.symlink(os.path.realpath(self.exe_path), + os.symlink(os.path.realpath(self.exe_path), os.path.join(self.run_dir, self.local_exe)) else: print("%s already exists. Skipping directory." % self.test_data['name']) @@ -469,14 +470,14 @@ def _copy_test_files(self): os.symlink(os.path.realpath(self.exe_path), symlink_path) def _create_run_script(self): - template_path = os.path.join(os.path.dirname(__file__), + template_path = os.path.join(os.path.dirname(__file__), run_template_dir, machines[self.machine]['script']) template_dest = os.path.join(self.run_dir, machines[self.machine]['script']) f = open(template_path, 'r') template = f.read() f.close() for var in template_vars.keys(): - template = template.replace(('${%s}' % var), + template = template.replace(('${%s}' % var), str(self.test_data[template_vars[var]])) template = template.replace('${EXECUTABLE}', "./%s" % self.local_exe) for var, value in sorted(getattr(machine_config, self.machine, {}).items()): @@ -492,7 +493,7 @@ def run_sim(self): if os.path.exists(os.path.join(self.run_dir, 'RunFinished')): print("%s run already completed, continuing..." % self.test_data['name']) return True - + os.chdir(self.run_dir) # Download data if requested if self.test_data['hub_download'] is not None: @@ -500,11 +501,11 @@ def run_sim(self): (hub_url, self.test_data['hub_download']) os.system(command) - command = "%s %s" % (machines[self.machine]['command'], + command = "%s %s" % (machines[self.machine]['command'], machines[self.machine]['script']) sim_start_time = time.time() # Run the command. - proc = subprocess.Popen(command, shell=True, close_fds=True, + proc = subprocess.Popen(command, shell=True, close_fds=True, preexec_fn=os.setsid) print("Simulation started on %s with maximum run time of %d seconds." % \ (time.ctime(), (self.test_data['max_time_minutes'] * 60 * @@ -519,7 +520,7 @@ def run_sim(self): self.finished = False running += 1 time.sleep(1) - + sim_stop_time = time.time() if os.path.exists(os.path.join(self.run_dir, 'RunFinished')): f = open(os.path.join(self.run_dir, 'run_time'), 'w') @@ -552,9 +553,9 @@ class UnspecifiedParameter(object): if __name__ == "__main__": parser = optparse.OptionParser() parser.add_option("--clobber", dest='clobber', default=False, - action="store_true", + action="store_true", help="Recopies tests and tests from scratch.") - parser.add_option("--interleave", action='store_true', dest='interleave', + parser.add_option("--interleave", action='store_true', dest='interleave', default=False, help="Option to interleave preparation, running, and testing.") parser.add_option("-m", "--machine", dest='machine', default='local', metavar='str', @@ -563,9 +564,9 @@ class UnspecifiedParameter(object): help="Where to place the run directory") parser.add_option("--repo", dest='repository', default="../", help="Path to repository being tested.", metavar='str') - parser.add_option("--sim-only", dest='sim_only', action="store_true", + parser.add_option("--sim-only", dest='sim_only', action="store_true", default=False, help="Only run simulations.") - parser.add_option("--test-only", dest='test_only', action="store_true", + parser.add_option("--test-only", dest='test_only', action="store_true", default=False, help="Only perform tests.") parser.add_option("--time-multiplier", dest='time_multiplier', default=1.0, type=float, metavar='int', @@ -581,7 +582,7 @@ class UnspecifiedParameter(object): parser.add_option("--run-suffix", dest="run_suffix", default=None, metavar='str', help="An optional suffix to append to the test run directory. Useful to distinguish multiple runs of a given changeset.") parser.add_option("", "--bitwise", - dest="bitwise", default=None, action="store_true", + dest="bitwise", default=None, action="store_true", help="run bitwise comparison of fields? (trumps strict)") parser.add_option("", "--tolerance", dest="tolerance", default=None, metavar='int', @@ -600,7 +601,7 @@ class UnspecifiedParameter(object): # Set up a dummy env for xunit to parse. Note we are using nose's xunit, # not the one bundled in yt - env = {"NOSE_XUNIT_FILE": "nosetests.xml"} + env = {"NOSE_XUNIT_FILE": "nosetests.xml"} xunit_plugin.options(parser, env) answer_plugin = AnswerTesting() @@ -656,7 +657,7 @@ class UnspecifiedParameter(object): answer_plugin.configure(options, None) reporting_plugin.configure(options, None) - # Break out if no valid strict set + # Break out if no valid strict set if options.strict not in all_strict: sys.exit("Error: %s is not a valid strict, try --strict=[%s]" % (options.strict, ", ".join(all_strict))) @@ -706,10 +707,10 @@ class UnspecifiedParameter(object): # the path to the executable we're testing exe_path = os.path.join(options.repository, "src/enzo/enzo.exe") - # If strict is set, then use it to set tolerance and bitwise - # values for later use when the nosetests get called in + # If strict is set, then use it to set tolerance and bitwise + # values for later use when the nosetests get called in # answer_testing_support.py - # N.B. Explicitly setting tolerance and/or bitwise trumps + # N.B. Explicitly setting tolerance and/or bitwise trumps # the strict values if options.strict == 'high': @@ -744,32 +745,39 @@ class UnspecifiedParameter(object): print("") # Before starting nose test, we must create the standard - # test problems (the old ./make_new_tests.py) by copying + # test problems (the old ./make_new_tests.py) by copying # the testing template out to each Test Problem # subdirectory. - + # Do not run the standard tests on these test problems. # --GravityTest is ignored for now because it generates randomly - # placed test particles, which makes comparison from run to run + # placed test particles, which makes comparison from run to run # difficult # --ProtostellarCollapse_Std needs to be updated to current Enzo # --(AMR)ZeldovichPancake is a symmetric collapse along the x-axis, so the - # projection along it is analytically 0, but builds up noise in + # projection along it is analytically 0, but builds up noise in # different ways on different systems. There are 'test_almost_standard"s - # in Zeldovichs's directories which are just like standard without x-vel + # in Zeldovichs's directories which are just like standard without x-vel # field comparisons, which is why we leave them out here. # Same with MHD2DRotorTest ignore_list = ('GravityTest', 'ProtostellarCollapse_Std', 'ZeldovichPancake', 'AMRZeldovichPancake', - 'MHD2DRotorTest', 'Toro-6-ShockTube', 'MHDCTOrszagTangAMR', 'MHDCTOrszagTang','dm_only') - + 'MHD2DRotorTest', 'Toro-6-ShockTube', 'MHDCTOrszagTangAMR', 'MHDCTOrszagTang','dm_only', + 'GravityTest', 'GravityTestSphere', 'TestOrbit', 'TestSelfForce', 'TestSineWave', + 'CoolingTest_Cloudy', 'CoolingTest_Grackle', 'CoolingTest_JHW', 'OneZoneFreeFallTest', + 'AdiabaticExpansion', 'AMRZeldovichPancake', 'AMRZeldovichPancake_Streaming', 'MHDAdiabaticExpansion_CT', 'MHDAdiabaticExpansion_Dedner', 'MHDZeldovichPancake', 'MHDZeldovichPancake_2_CT', 'MHDZeldovichPancake_2_Dedner', 'SphericalInfall', 'ZeldovichPancake', + 'DrivenTurbulence3D', + 'FLD', + 'FuzzyDarkMatter') + template = open("test_type.py.template").read() - + test_standard_files = [] + filtered_tests = [] for root, dirs, files in os.walk("."): for fn in files: - if fn.endswith(".enzotest") and \ - os.path.basename(fn)[:-9] not in ignore_list: + if fn.endswith(".enzotest") and ('RefLevel' in fn): + filtered_tests.append(fn.split('.')[0]) simname = os.path.splitext(fn)[0] simpath = root testname = os.path.basename(fn)[:-9] @@ -779,6 +787,11 @@ class UnspecifiedParameter(object): # save the destination filename to remove it later test_standard_files.append(oname) + #import ipdb; ipdb.set_trace() + + etc2.tests = [x for x in etc2.tests if x['name'] in filtered_tests] + + #import ipdb; ipdb.set_trace() # Run the simulations and the tests etc2.go(options.output_dir, options.interleave, options.machine, exe_path, sim_only=options.sim_only, diff --git a/src/enzo/CommunicationReceiveHandler.C b/src/enzo/CommunicationReceiveHandler.C index d3323e745..b79171485 100644 --- a/src/enzo/CommunicationReceiveHandler.C +++ b/src/enzo/CommunicationReceiveHandler.C @@ -6,9 +6,9 @@ / date: August, 2003 / modified1: / -/ PURPOSE: This routine processes the receives stored in the -/ CommunicationReceive stack. Each receive is tagged with a -/ type which indicates which method to call +/ PURPOSE: This routine processes the receives stored in the +/ CommunicationReceive stack. Each receive is tagged with a +/ type which indicates which method to call / (and a record of the arguments). / ************************************************************************/ @@ -28,7 +28,7 @@ #include "ExternalBoundary.h" #include "Grid.h" #include "communication.h" - + #ifdef USE_MPI static MPI_Arg ListOfIndices[MAX_RECEIVE_BUFFERS]; static MPI_Status ListOfStatuses[MAX_RECEIVE_BUFFERS]; @@ -79,7 +79,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], MPI_Waitsome(TotalReceives, CommunicationReceiveMPI_Request, &NumberOfCompleteRequests, ListOfIndices, ListOfStatuses); -// printf("MPI: %"ISYM" %"ISYM" %"ISYM"\n", TotalReceives, +// printf("MPI: %"ISYM" %"ISYM" %"ISYM"\n", TotalReceives, // ReceivesCompletedToDate, NumberOfCompleteRequests); CommunicationTime += ReturnWallTime() - time1; @@ -101,10 +101,10 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], MyProcessorNumber, ListOfStatuses[index].MPI_ERROR, index); NoErrorSoFar = FALSE; } - fprintf(stdout, "P(%"ISYM") index %"ISYM" -- mpi error %"ISYM"\n", + fprintf(stdout, "P(%"ISYM") index %"ISYM" -- mpi error %"ISYM"\n", MyProcessorNumber, index, ListOfStatuses[index].MPI_ERROR); fprintf(stdout, "%"ISYM": Type = %"ISYM", Grid1 = %x, Request = %"ISYM", " - "DependsOn = %"ISYM"\n", index, + "DependsOn = %"ISYM"\n", index, CommunicationReceiveCallType[index], CommunicationReceiveGridOne[index], CommunicationReceiveMPI_Request[index], @@ -128,7 +128,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], } /* Loop over the receive handles, looking for completed (i.e. null) - requests associated with unprocessed (i.e. non-null) grids. + requests associated with unprocessed (i.e. non-null) grids. It's insufficient to just loop over newly completed receives because there may be some completed receives which were not processed due to dependence issues. */ @@ -143,7 +143,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], if (CommunicationReceiveGridOne[index] != NULL && CommunicationReceiveMPI_Request[index] == MPI_REQUEST_NULL) { - // fprintf(stdout, "::MPI:: %d %d %d %d %d\n", index, + // fprintf(stdout, "::MPI:: %d %d %d %d %d\n", index, // CommunicationReceiveCallType[index], // CommunicationReceiveGridOne[index], // CommunicationReceiveMPI_Request[index], @@ -151,7 +151,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], /* If this depends on an un-processed receive, then skip it. */ - if (CommunicationReceiveDependsOn[index] != + if (CommunicationReceiveDependsOn[index] != COMMUNICATION_NO_DEPENDENCE) if (CommunicationReceiveGridOne[CommunicationReceiveDependsOn[index]] != NULL) @@ -165,7 +165,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], for (dim = 0; dim < MAX_DIMENSION; dim++) EdgeOffset[dim] = CommunicationReceiveArgument[dim][index]; - + /* Handle the buffers received, calling the appropriate method. */ switch (CommunicationReceiveCallType[index]) { @@ -213,16 +213,16 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], case 10: errcode = grid_one->InterpolateAccelerations(grid_two); break; - + case 11: /* Note this one involves two calls. */ /* Project subgrid's refined fluxes to the level of this grid. */ - if (grid_one->GetProjectedBoundaryFluxes(grid_two, + if (grid_one->GetProjectedBoundaryFluxes(grid_two, SubgridFluxesRefined) == FAIL) { ENZO_FAIL("Error in grid->GetProjectedBoundaryFluxes.\n"); } - + /* Correct this grid for the refined fluxes (step #19) (this also deletes the fields in SubgridFluxesRefined). */ @@ -232,7 +232,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], isubgrid = CommunicationReceiveArgumentInt[1][index]; SUBling = CommunicationReceiveArgumentInt[2][index]; if ((errcode = grid_two->CorrectForRefinedFluxes - (SubgridFluxesEstimate[igrid][isubgrid], &SubgridFluxesRefined, + (SubgridFluxesEstimate[igrid][isubgrid], &SubgridFluxesRefined, SubgridFluxesEstimate[igrid][NumberOfSubgrids[igrid] - 1], SUBling, MetaData)) == FAIL) { ENZO_FAIL("Error in grid->CorrectForRefinedFluxes.\n"); @@ -279,7 +279,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], break; case 18: - errcode = grid_one->CommunicationSendStars(grid_two, + errcode = grid_one->CommunicationSendStars(grid_two, MyProcessorNumber); break; @@ -290,7 +290,7 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], break; case 20: - errcode = grid_one->CommunicationSendSubgridMarker(grid_two, + errcode = grid_one->CommunicationSendSubgridMarker(grid_two, MyProcessorNumber); break; #endif @@ -304,20 +304,28 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], (grid_two, MyProcessorNumber); break; + case 23: + errcode = grid_one->AddParentAccelerationFieldAPM(grid_two); + break; + + case 24: + errcode = grid_one->AddParentPotentialFieldAPM(grid_two); + break; + default: - ENZO_VFAIL("Unrecognized call type %"ISYM"\n", + ENZO_VFAIL("Unrecognized call type %"ISYM"\n", CommunicationReceiveCallType[index]) } // end: switch on call type - + /* Report error if there has been one in any of the above calls. */ - + if (errcode == FAIL) { ENZO_VFAIL("Error in CommunicationReceiveHandler, method %"ISYM"\n", CommunicationReceiveCallType[index]) - + } - + /* Mark this receive complete. */ // if this is a g:CSAPs recv, mark ALL g:CSAPs done, including this one. @@ -330,14 +338,14 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[], ReceivesCompletedToDate++; } } - } else { + } else { CommunicationReceiveGridOne[index] = NULL; //MPI_Request_free(CommunicationReceiveMPI_Request+index); ReceivesCompletedToDate++; } } // end: if statement to check if receive should be processed - + } // end: loop over all receives } // end: while loop waiting for all receives to be processed diff --git a/src/enzo/ComputeAccelerationFieldAPMGravity.C b/src/enzo/ComputeAccelerationFieldAPMGravity.C new file mode 100644 index 000000000..bd2d32910 --- /dev/null +++ b/src/enzo/ComputeAccelerationFieldAPMGravity.C @@ -0,0 +1,265 @@ +/*********************************************************************** +/ +/ COMPUTE ACCELERATION FIELD FUNCTION +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ modified1: +/ +/ PURPOSE: +/ +************************************************************************/ + +#ifdef USE_MPI +#include +#endif /* USE_MPI */ + +#include +#include +#include "ErrorExceptions.h" +#include "EnzoTiming.h" +#include "performance.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "Hierarchy.h" +#include "LevelHierarchy.h" +#include "TopGridData.h" +#include "communication.h" +#include "CommunicationUtilities.h" + +/* function prototypes */ + +int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[] = NULL, + int NumberOfSubgrids[] = NULL, + int FluxFlag = FALSE, + TopGridData* MetaData = NULL); + +/* EvolveHierarchy function */ + +int ComputeAccelerationFieldAPMGravity(HierarchyEntry *Grid, TopGridData *MetaData, + LevelHierarchyEntry *LevelArray[], int level, + ExternalBoundary *Exterior = NULL) +{ + + /* declarations */ + + int dim; + grid *CurrentGrid = Grid->GridData; + + /* Compute the refinement factor. */ + + int RefinementFactor = 1, Factors[MAX_DIMENSION]; + if (Grid->ParentGrid != NULL) { + Grid->ParentGrid->GridData->ComputeRefinementFactors(CurrentGrid, Factors); + for (dim = 0; dim < MAX_DIMENSION; dim++) { + if (Factors[dim] != 1) + RefinementFactor = Factors[dim]; + } + } + + /* Compute the acceleration (and potential) on the grid. */ + if (level == 0) { + + /* Here we calculate the acceleration field for PPM + which is assumed to be face-centered. + If Zeus is used, staggering will be done in ZeusSource.C */ + int DiffType = DIFFERENCE_TYPE_NORMAL; + if (CurrentGrid->ComputeAccelerationField(DiffType, level) == FAIL) + ENZO_FAIL("Error in grid->ComputeAccelerationField.C\n"); + + } else { + if (CurrentGrid->ComputeAccelerationFieldAPM(RefinementFactor) == FAIL) + ENZO_FAIL("Error in grid->ComputeAccelerationFieldAPM.\n"); + + /* For the TestSelfForce we may want to output the force components separately */ + if (APMAddParentContribution) { + + + /* a) Add parental acceleration. */ + /* Three-pass structure based on SetBoundaryConditions.C */ + LCAPERF_START("APMAddParentAcceleration"); + TIMER_START("APMAddParentAcceleration"); + +#ifdef FORCE_MSG_PROGRESS + CommunicationBarrier(); +#endif + + /* -------------- FIRST PASS ----------------- */ + /* Here, we just generate the calls to generate the receive buffers, + without actually doing anything. */ + + CommunicationDirection = COMMUNICATION_POST_RECEIVE; + CommunicationReceiveIndex = 0; + + if (Grid->ParentGrid != NULL) + if (CurrentGrid->AddParentAccelerationFieldAPM(Grid->ParentGrid->GridData) == FAIL) + ENZO_FAIL("Error in grid->AddParentAccelerationFieldAPM.C\n"); + + /* -------------- SECOND PASS ----------------- */ + /* Now we generate all the sends, and do all the computation + for grids which are on the same processor as well. */ + + CommunicationDirection = COMMUNICATION_SEND; + + if (Grid->ParentGrid != NULL) + if (CurrentGrid->AddParentAccelerationFieldAPM(Grid->ParentGrid->GridData) == FAIL) + ENZO_FAIL("Error in grid->AddParentAccelerationFieldAPM.C\n"); + + + /* -------------- THIRD PASS ----------------- */ + /* In this final step, we get the messages as they come in and + then match them to the methods which generate the receive + handle. */ + + if (CommunicationReceiveHandler() == FAIL) + ENZO_FAIL("CommunicationReceiveHandler() failed!\n"); + + +#ifdef FORCE_MSG_PROGRESS + CommunicationBarrier(); +#endif + + CommunicationDirection = COMMUNICATION_SEND_RECEIVE; + + TIMER_STOP("APMAddParentAcceleration"); + LCAPERF_STOP("APMAddParentAcceleration"); + + + + /* b) Add parental potential */ + /* Three-pass structure based on SetBoundaryConditions.C */ + LCAPERF_START("APMAddParentPotential"); + TIMER_START("APMAddParentPotential"); + +#ifdef FORCE_MSG_PROGRESS + CommunicationBarrier(); +#endif + + /* -------------- FIRST PASS ----------------- */ + /* Here, we just generate the calls to generate the receive buffers, + without actually doing anything. */ + + CommunicationDirection = COMMUNICATION_POST_RECEIVE; + CommunicationReceiveIndex = 0; + + if (Grid->ParentGrid != NULL) + if (CurrentGrid->AddParentPotentialFieldAPM(Grid->ParentGrid->GridData) == FAIL) + ENZO_FAIL("Error in grid->AddParentAccelerationFieldAPM.C\n"); + + /* -------------- SECOND PASS ----------------- */ + /* Now we generate all the sends, and do all the computation + for grids which are on the same processor as well. */ + + CommunicationDirection = COMMUNICATION_SEND; + + if (Grid->ParentGrid != NULL) + if (CurrentGrid->AddParentPotentialFieldAPM(Grid->ParentGrid->GridData) == FAIL) + ENZO_FAIL("Error in grid->AddParentAccelerationFieldAPM.C\n"); + + + /* -------------- THIRD PASS ----------------- */ + /* In this final step, we get the messages as they come in and + then match them to the methods which generate the receive + handle. */ + + if (CommunicationReceiveHandler() == FAIL) + ENZO_FAIL("CommunicationReceiveHandler() failed!\n"); + + +#ifdef FORCE_MSG_PROGRESS + CommunicationBarrier(); +#endif + + CommunicationDirection = COMMUNICATION_SEND_RECEIVE; + + TIMER_STOP("APMAddParentPotential"); + LCAPERF_STOP("APMAddParentPotential"); + + } // end if APMAddParentContribution + }/* end if (level == 0) */ + + /* Clear grid and particle accelerations. */ + + // CurrentGrid->ComputeEffectiveGridPositions(0.0, TRUE, 1.0); + // CurrentGrid->ClearAccelerationFieldForCells(); + CurrentGrid->ClearParticleAccelerations(); + + /* Move particles 1/2 step forward in preparation for interpolation. */ + + CurrentGrid->UpdateParticlePosition(0.5*CurrentGrid->ReturnTimeStep()); + + /* Zeus: reset grid positions to cell centers (move to faces later). */ + + // if (HydroMethod == Zeus_Hydro) + // CurrentGrid->ComputeEffectiveGridPositions(0.0, TRUE, 1.0); + + /* Interpolate the accelerations back to the grid and particles. */ + + if (level <= MaximumGravityRefinementLevel) { + CurrentGrid->InterpolateParticlePositions(CurrentGrid, DIFFERENCE_TYPE_NORMAL); + + // if (Grid->ParentGrid != NULL) + // CurrentGrid->InterpolateParticlePositions(Grid->ParentGrid->GridData, DIFFERENCE_TYPE_NORMAL); + // else + // CurrentGrid->InterpolateParticlePositions(CurrentGrid, DIFFERENCE_TYPE_NORMAL); + } + + /* Interpolate the accelerations of all grids higher than this one + to the particles and grids. */ + +#ifdef UNUSED + HierarchyEntry *Temp = Grid->ParentGrid; + int l1 = level-1; + while (Temp != NULL) { + if (l1-- <= MaximumGravityRefinementLevel) { + // if (CurrentGrid->InterpolateGridPositions(Temp->GridData) == FAIL) { + // fprintf(stderr, "Error in grid->InterpolateGridPositions.\n"); + // return FAIL; + // } + if (CurrentGrid->InterpolateParticlePositions(Temp->GridData, DIFFERENCE_TYPE_NORMAL) == FAIL) + ENZO_FAIL("Error in grid->InterpolateParticlePositons.\n"); + } + Temp = Temp->ParentGrid; + } +#endif + + /* Copy the cell accelerations to a grid. This routine really just + readjusts the size of AccelerationFieldForCells so that it is + commensurate with the rest of the baryonic grids. */ + +#if 0 + if (CurrentGrid->CopyGridAccelerationsToGrid() == FAIL) + ENZO_FAIL("Error in grid->CopyGridAccelerationsToGrid.\n"); +#endif + + /* Move particles 1/2 step backwards to return to original positions. */ + + CurrentGrid->UpdateParticlePosition(-0.5*CurrentGrid->ReturnTimeStep()); + + /* Set any boundary conditions needed (only for top grid). + For now, we'll use the same boundary conditions as the density. This is + correct for periodic B.C.'s but probably not for open B.C.'s. */ + // FIX + +#if 0 + if (Grid->ParentGrid == NULL) + if (CurrentGrid->SetGravitationalExternalBoundary(Exterior) == FAIL) + ENZO_FAIL("Error in grid->SetGravitationalExternalBoundary.\n"); +#endif + + // CurrentGrid->DeleteGravitatingMassField(); + // CurrentGrid->DeleteGridPositionAndMass(); + + /* If this is the lowest level of the hierarchy, we can delete + AccelerationField as well. */ + + // if (LevelArray[level+1] == NULL) + // CurrentGrid->DeleteAccelerationField(); + + return SUCCESS; +} diff --git a/src/enzo/DepositParticleMassField.C b/src/enzo/DepositParticleMassField.C index bf6d2f1e0..5f384da4f 100644 --- a/src/enzo/DepositParticleMassField.C +++ b/src/enzo/DepositParticleMassField.C @@ -116,3 +116,93 @@ int DepositParticleMassFieldChildren(HierarchyEntry *DepositGrid, return SUCCESS; } + + +int DepositParticleMassFieldWithParent(HierarchyEntry *Grid, TopGridData *MetaData, + ChainingMeshStructure *ChainingMesh, + FLOAT TimeMidStep) +{ + + SiblingGridList SiblingList; + int grid1; + + /* Get the time and dt for this grid. Compute time+1/2 dt. */ + + if (TimeMidStep < 0) + TimeMidStep = Grid->GridData->ReturnTime() + + 0.5*Grid->GridData->ReturnTimeStep(); + + /* Initialize the gravitating mass field only if in send-receive mode + (i.e. this routine is called only once) or if in the first of the + three communication modes (post-receive). */ + + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE || + CommunicationDirection == COMMUNICATION_SEND_RECEIVE) { + + /* Initialize the gravitating mass field parameters (if necessary). */ + + if (Grid->GridData->InitializeGravitatingMassFieldParticles(RefineBy) == FAIL) { + ENZO_FAIL("Error in grid->InitializeGravitatingMassFieldParticles.\n"); + } + + /* Clear the GravitatingMassFieldParticles. */ + + if (Grid->GridData->ClearGravitatingMassFieldParticles() == FAIL) { + ENZO_FAIL("Error in grid->ClearGravitatingMassFieldParticles.\n"); + } + } // end: if (CommunicationDirection != COMMUNICATION_SEND) + + /* Deposit particles to GravitatingMassFieldParticles in this grid. */ + + if (Grid->GridData->DepositParticlePositions(Grid->GridData, TimeMidStep, + GRAVITATING_MASS_FIELD_PARTICLES) == FAIL) { + ENZO_FAIL("Error in grid->DepositParticlePositions.\n"); + } + + /* Recursively deposit particles in children (at TimeMidStep). */ + + if (Grid->NextGridNextLevel != NULL) + if (DepositParticleMassFieldChildren(Grid, Grid->NextGridNextLevel, + TimeMidStep) == FAIL) { + ENZO_FAIL("Error in DepositParticleMassFieldChildren.\n"); + } + + /* Copy particles from parent and siblings from the upper level */ + + if (Grid->ParentGrid != NULL) { + + /* First do the parent grid */ + + if (Grid->ParentGrid->GridData->DepositParticlePositions(Grid->GridData, TimeMidStep, + GRAVITATING_MASS_FIELD_PARTICLES) == FAIL) + ENZO_FAIL("Error in grid->DepositParticlePositions: ParentGrid.\n"); + + /* Now do the siblings + Based on CommunicationTransferSubgridParticles.C + */ + + // Get a list of possible siblings from the chaining mesh + + Grid->GridData->FastSiblingLocatorFindSiblings + (ChainingMesh, &SiblingList, MetaData->LeftFaceBoundaryCondition, + MetaData->RightFaceBoundaryCondition); + + // Deposit particles from sibling + + for (grid1 = 0; grid1 < SiblingList.NumberOfSiblings; grid1++) + if (Grid->ParentGrid->GridData != SiblingList.GridList[grid1]) + if (SiblingList.GridList[grid1]->DepositParticlePositions( + Grid->GridData, TimeMidStep, GRAVITATING_MASS_FIELD_PARTICLES + ) == FAIL) + ENZO_FAIL("Error in grid->DepositParticlePositions: Sibling.\n"); + + // Cleanup + + delete [] SiblingList.GridList; + + } + + return SUCCESS; +} + + diff --git a/src/enzo/DepositPositionsTSC1d.C b/src/enzo/DepositPositionsTSC1d.C new file mode 100644 index 000000000..05433a811 --- /dev/null +++ b/src/enzo/DepositPositionsTSC1d.C @@ -0,0 +1,117 @@ +/*********************************************************************** +/ +/ DEPOSIT 1D TSC 'PARTICLES' (EITHER PERIODIC OR 'PILE-UP') +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "macros_and_parameters.h" + +/* Periodic version. */ + +void DepositPositionsPeriodicTSC1D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int Dimension[], float CellSize) +{ + int i0, i0p, i0m, n; + float dx, wx0, wxm, wxp, xpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + i0 = int(xpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + /* check for off-edge particles. */ + + if (i0 < 0 ) i0 += Dimension[0]; + if (i0 >= Dimension[0]) i0 -= Dimension[0]; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + + /* wrap indexes */ + + if (i0m < 0) i0m += Dimension[0]; + if (i0p >= Dimension[0]) i0p -= Dimension[0]; + + /* deposit mass */ + + *(Field + i0m) += wxm*(*(Mass + n)); + *(Field + i0 ) += wx0*(*(Mass + n)); + *(Field + i0p) += wxp*(*(Mass + n)); + + } // next particle + +} + +/* Particles which extend past the edge of the grid are deposit at the + edge in this version, causing mass to pile-up. */ + +void DepositPositionsPileUpTSC1D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int EffectiveStart[], int EffectiveDim[], + float CellSize) +{ + int i0, i0p, i0m, n; + float dx, wx0, wxm, wxp, xpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + i0 = int(xpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + /* check for off-edge particles. */ + + if (i0 < EffectiveStart[0] || i0 >= EffectiveDim[0]) + continue; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + + /* wrap indexes */ + + if (i0m < EffectiveStart[0]) i0m = EffectiveStart[0]; + if (i0p >= EffectiveDim[0] ) i0p = EffectiveDim[0]-1; + + /* deposit mass */ + + *(Field + i0m) += wxm*(*(Mass + n)); + *(Field + i0 ) += wx0*(*(Mass + n)); + *(Field + i0p) += wxp*(*(Mass + n)); + + } // next particle + +} diff --git a/src/enzo/DepositPositionsTSC2d.C b/src/enzo/DepositPositionsTSC2d.C new file mode 100644 index 000000000..2470c620b --- /dev/null +++ b/src/enzo/DepositPositionsTSC2d.C @@ -0,0 +1,154 @@ +/*********************************************************************** +/ +/ DEPOSIT 2D TSC 'PARTICLES' (EITHER PERIODIC OR 'PILE-UP') +/ +/ written by: Greg Bryan +/ date: May, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "macros_and_parameters.h" + +/* Periodic version. */ + +void DepositPositionsPeriodicTSC2D(float *Position[], float *Mass, + int Number, float *Field, float LeftEdge[], + int Dimension[], float CellSize) +{ + int i0, i0p, i0m, j0, j0p, j0m, n; + float dx, dy, wx0, wxm, wxp, wy0, wym, wyp, xpos, ypos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + ypos = ( (*(Position[1] + n)) - LeftEdge[1] ) / CellSize; + i0 = int(xpos); + j0 = int(ypos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + /* check for off-edge particles. */ + + if (i0 < 0 ) i0 += Dimension[0]; + if (j0 < 0 ) j0 += Dimension[1]; + if (i0 >= Dimension[0]) i0 -= Dimension[0]; + if (j0 >= Dimension[1]) j0 -= Dimension[1]; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + + /* wrap indexes */ + + if (i0m < 0) i0m += Dimension[0]; + if (j0m < 0) j0m += Dimension[1]; + if (i0p >= Dimension[0]) i0p -= Dimension[0]; + if (j0p >= Dimension[1]) j0p -= Dimension[1]; + + /* deposit mass */ + + *(Field + j0m*Dimension[0] + i0m) += wym*wxm*(*(Mass + n)); + *(Field + j0m*Dimension[0] + i0 ) += wym*wx0*(*(Mass + n)); + *(Field + j0m*Dimension[0] + i0p) += wym*wxp*(*(Mass + n)); + *(Field + j0 *Dimension[0] + i0m) += wy0*wxm*(*(Mass + n)); + *(Field + j0 *Dimension[0] + i0 ) += wy0*wx0*(*(Mass + n)); + *(Field + j0 *Dimension[0] + i0p) += wy0*wxp*(*(Mass + n)); + *(Field + j0p*Dimension[0] + i0m) += wyp*wxm*(*(Mass + n)); + *(Field + j0p*Dimension[0] + i0 ) += wyp*wx0*(*(Mass + n)); + *(Field + j0p*Dimension[0] + i0p) += wyp*wxp*(*(Mass + n)); + + } // next particle + +} + +/* Particles which extend past the edge of the grid are deposit at the + edge in this version, causing mass to pile-up. */ + +void DepositPositionsPileUpTSC2D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int EffectiveStart[], int EffectiveDim[], + int Dimension[], float CellSize) +{ + int i0, i0p, i0m, j0, j0p, j0m, n; + float dx, dy, wx0, wxm, wxp, wy0, wym, wyp, xpos, ypos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + ypos = ( (*(Position[1] + n)) - LeftEdge[1] ) / CellSize; + i0 = int(xpos); + j0 = int(ypos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + /* check for off-edge particles. */ + + if (i0 < EffectiveStart[0] || i0 >= EffectiveDim[0] || + j0 < EffectiveStart[1] || j0 >= EffectiveDim[1]) + continue; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + + /* wrap indexes */ + + if (i0m < EffectiveStart[0]) i0m = EffectiveStart[0]; + if (j0m < EffectiveStart[1]) j0m = EffectiveStart[1]; + if (i0p >= EffectiveDim[0] ) i0p = EffectiveDim[0]-1; + if (j0p >= EffectiveDim[1] ) j0p = EffectiveDim[1]-1; + + /* deposit mass */ + + *(Field + j0m*Dimension[0] + i0m) += wym*wxm*(*(Mass + n)); + *(Field + j0m*Dimension[0] + i0 ) += wym*wx0*(*(Mass + n)); + *(Field + j0m*Dimension[0] + i0p) += wym*wxp*(*(Mass + n)); + *(Field + j0 *Dimension[0] + i0m) += wy0*wxm*(*(Mass + n)); + *(Field + j0 *Dimension[0] + i0 ) += wy0*wx0*(*(Mass + n)); + *(Field + j0 *Dimension[0] + i0p) += wy0*wxp*(*(Mass + n)); + *(Field + j0p*Dimension[0] + i0m) += wyp*wxm*(*(Mass + n)); + *(Field + j0p*Dimension[0] + i0 ) += wyp*wx0*(*(Mass + n)); + *(Field + j0p*Dimension[0] + i0p) += wyp*wxp*(*(Mass + n)); + + } // next particle + +} diff --git a/src/enzo/DepositPositionsTSC3d.C b/src/enzo/DepositPositionsTSC3d.C new file mode 100644 index 000000000..83bc8a58a --- /dev/null +++ b/src/enzo/DepositPositionsTSC3d.C @@ -0,0 +1,264 @@ +/*********************************************************************** +/ +/ DEPOSIT 3D TSC 'PARTICLES' (EITHER PERIODIC OR 'PILE-UP') +/ +/ written by: Greg Bryan +/ date: May, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "macros_and_parameters.h" + +/* Use FORTRAN or C++ version? */ + +#define NO_USE_FORTRAN + +/* External defines. */ + +#ifdef USE_FORTRAN +extern "C" void FORTRAN_NAME(dep_pile_tsc3d) + (float *posx, float *posy, float *posz, float *mass, int *npositions, + float *field, float leftedge[], + int *estart1, int *estart2, int *estart3, + int *edim1, int *edim2, int *edim3, + int *dim1, int *dim2, int *dim3, float *cellsize); +#endif /* USE_FORTRAN */ + +/* Periodic version. */ + +void DepositPositionsPeriodicTSC3D(float *Position[], float *Mass, + int Number, float *Field, float LeftEdge[], + int Dimension[], float CellSize) +{ + + int dim12, i0, i0p, i0m, j0, j0p, j0m, k0, k0p, k0m, n; + float dx, dy, dz, wx0, wxm, wxp, wy0, wym, wyp, wz0, wzm, wzp, + xpos, ypos, zpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( Position[0][n] - LeftEdge[0] ) / CellSize; + ypos = ( Position[1][n] - LeftEdge[1] ) / CellSize; + zpos = ( Position[2][n] - LeftEdge[2] ) / CellSize; + + i0 = int(xpos); + j0 = int(ypos); + k0 = int(zpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + dz = zpos - float(k0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + wzm = 0.5*(0.5 - dz)*(0.5 - dz); + wzp = dz + wzm; + wz0 = 1.0 - wzp - wzm; + + /* check for off-edge particles. */ + + if (i0 < 0 ) i0 += Dimension[0]; + if (j0 < 0 ) j0 += Dimension[1]; + if (k0 < 0 ) k0 += Dimension[2]; + if (i0 >= Dimension[0]) i0 -= Dimension[0]; + if (j0 >= Dimension[1]) j0 -= Dimension[1]; + if (k0 >= Dimension[2]) k0 -= Dimension[2]; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + k0m = k0 - 1; + k0p = k0 + 1; + + /* wrap indexes */ + + if (i0m < 0) i0m += Dimension[0]; + if (j0m < 0) j0m += Dimension[1]; + if (k0m < 0) k0m += Dimension[2]; + if (i0p >= Dimension[0]) i0p -= Dimension[0]; + if (j0p >= Dimension[1]) j0p -= Dimension[1]; + if (k0p >= Dimension[2]) k0p -= Dimension[2]; + + /* deposit mass */ + + dim12 = Dimension[0]*Dimension[1]; + + Field[k0m*dim12 + j0m*Dimension[0] + i0m] += wzm*wym*wxm*Mass[n]; + Field[k0m*dim12 + j0m*Dimension[0] + i0 ] += wzm*wym*wx0*Mass[n]; + Field[k0m*dim12 + j0m*Dimension[0] + i0p] += wzm*wym*wxp*Mass[n]; + Field[k0m*dim12 + j0 *Dimension[0] + i0m] += wzm*wy0*wxm*Mass[n]; + Field[k0m*dim12 + j0 *Dimension[0] + i0 ] += wzm*wy0*wx0*Mass[n]; + Field[k0m*dim12 + j0 *Dimension[0] + i0p] += wzm*wy0*wxp*Mass[n]; + Field[k0m*dim12 + j0p*Dimension[0] + i0m] += wzm*wyp*wxm*Mass[n]; + Field[k0m*dim12 + j0p*Dimension[0] + i0 ] += wzm*wyp*wx0*Mass[n]; + Field[k0m*dim12 + j0p*Dimension[0] + i0p] += wzm*wyp*wxp*Mass[n]; + + Field[k0 *dim12 + j0m*Dimension[0] + i0m] += wz0*wym*wxm*Mass[n]; + Field[k0 *dim12 + j0m*Dimension[0] + i0 ] += wz0*wym*wx0*Mass[n]; + Field[k0 *dim12 + j0m*Dimension[0] + i0p] += wz0*wym*wxp*Mass[n]; + Field[k0 *dim12 + j0 *Dimension[0] + i0m] += wz0*wy0*wxm*Mass[n]; + Field[k0 *dim12 + j0 *Dimension[0] + i0 ] += wz0*wy0*wx0*Mass[n]; + Field[k0 *dim12 + j0 *Dimension[0] + i0p] += wz0*wy0*wxp*Mass[n]; + Field[k0 *dim12 + j0p*Dimension[0] + i0m] += wz0*wyp*wxm*Mass[n]; + Field[k0 *dim12 + j0p*Dimension[0] + i0 ] += wz0*wyp*wx0*Mass[n]; + Field[k0 *dim12 + j0p*Dimension[0] + i0p] += wz0*wyp*wxp*Mass[n]; + + Field[k0p*dim12 + j0m*Dimension[0] + i0m] += wzp*wym*wxm*Mass[n]; + Field[k0p*dim12 + j0m*Dimension[0] + i0 ] += wzp*wym*wx0*Mass[n]; + Field[k0p*dim12 + j0m*Dimension[0] + i0p] += wzp*wym*wxp*Mass[n]; + Field[k0p*dim12 + j0 *Dimension[0] + i0m] += wzp*wy0*wxm*Mass[n]; + Field[k0p*dim12 + j0 *Dimension[0] + i0 ] += wzp*wy0*wx0*Mass[n]; + Field[k0p*dim12 + j0 *Dimension[0] + i0p] += wzp*wy0*wxp*Mass[n]; + Field[k0p*dim12 + j0p*Dimension[0] + i0m] += wzp*wyp*wxm*Mass[n]; + Field[k0p*dim12 + j0p*Dimension[0] + i0 ] += wzp*wyp*wx0*Mass[n]; + Field[k0p*dim12 + j0p*Dimension[0] + i0p] += wzp*wyp*wxp*Mass[n]; + + } // next particle + +} + +/* Particles which extend past the edge of the grid are deposit at the + edge in this version, causing mass to pile-up. */ + +void DepositPositionsPileUpTSC3D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int EffectiveStart[], int EffectiveDim[], + int Dimension[], float CellSize) +{ + + // fprintf(stderr, "DepositTSC: %d %d %d\n", Dimension[0], Dimension[1], Dimension[2]); + +#ifdef USE_FORTRAN + +/* Call FORTRAN routine to do all the hard work. */ + +FORTRAN_NAME(dep_pile_tsc3d)( + Position[0], Position[1], Position[2], Mass, &Number, + Field, LeftEdge, + &EffectiveStart[0], &EffectiveStart[1], &EffectiveStart[2], + &EffectiveDim[0], &EffectiveDim[1], &EffectiveDim[2], + &Dimension[0], &Dimension[1], &Dimension[2], &CellSize); + +#else /* USE_FORTRAN */ + + int dim12, i0, i0p, i0m, j0, j0p, j0m, k0, k0p, k0m, n; + float dx, dy, dz, wx0, wxm, wxp, wy0, wym, wyp, wz0, wzm, wzp, + xpos, ypos, zpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( Position[0][n] - LeftEdge[0] ) / CellSize; + ypos = ( Position[1][n] - LeftEdge[1] ) / CellSize; + zpos = ( Position[2][n] - LeftEdge[2] ) / CellSize; + + i0 = int(xpos); + j0 = int(ypos); + k0 = int(zpos); + + /* check for off-edge particles. */ + + if (i0 < EffectiveStart[0] || i0 >= EffectiveDim[0] || + j0 < EffectiveStart[1] || j0 >= EffectiveDim[1] || + k0 < EffectiveStart[2] || k0 >= EffectiveDim[2]) { + + fprintf(stdout,"Reject particle %"ISYM" in DepositPositionsTSC3d.C: off-edge.\n", n); + continue; + } + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + dz = zpos - float(k0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + wzm = 0.5*(0.5 - dz)*(0.5 - dz); + wzp = dz + wzm; + wz0 = 1.0 - wzp - wzm; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + k0m = k0 - 1; + k0p = k0 + 1; + + /* wrap indexes */ + + if (i0m < EffectiveStart[0]) i0m = EffectiveStart[0]; + if (j0m < EffectiveStart[1]) j0m = EffectiveStart[1]; + if (k0m < EffectiveStart[2]) k0m = EffectiveStart[2]; + if (i0p >= EffectiveDim[0] ) i0p = EffectiveDim[0]-1; + if (j0p >= EffectiveDim[1] ) j0p = EffectiveDim[1]-1; + if (k0p >= EffectiveDim[2] ) k0p = EffectiveDim[2]-1; + + /* deposit mass */ + + dim12 = Dimension[0]*Dimension[1]; + + Field[k0m*dim12 + j0m*Dimension[0] + i0m] += wzm*wym*wxm*Mass[n]; + Field[k0m*dim12 + j0m*Dimension[0] + i0 ] += wzm*wym*wx0*Mass[n]; + Field[k0m*dim12 + j0m*Dimension[0] + i0p] += wzm*wym*wxp*Mass[n]; + Field[k0m*dim12 + j0 *Dimension[0] + i0m] += wzm*wy0*wxm*Mass[n]; + Field[k0m*dim12 + j0 *Dimension[0] + i0 ] += wzm*wy0*wx0*Mass[n]; + Field[k0m*dim12 + j0 *Dimension[0] + i0p] += wzm*wy0*wxp*Mass[n]; + Field[k0m*dim12 + j0p*Dimension[0] + i0m] += wzm*wyp*wxm*Mass[n]; + Field[k0m*dim12 + j0p*Dimension[0] + i0 ] += wzm*wyp*wx0*Mass[n]; + Field[k0m*dim12 + j0p*Dimension[0] + i0p] += wzm*wyp*wxp*Mass[n]; + + Field[k0 *dim12 + j0m*Dimension[0] + i0m] += wz0*wym*wxm*Mass[n]; + Field[k0 *dim12 + j0m*Dimension[0] + i0 ] += wz0*wym*wx0*Mass[n]; + Field[k0 *dim12 + j0m*Dimension[0] + i0p] += wz0*wym*wxp*Mass[n]; + Field[k0 *dim12 + j0 *Dimension[0] + i0m] += wz0*wy0*wxm*Mass[n]; + Field[k0 *dim12 + j0 *Dimension[0] + i0 ] += wz0*wy0*wx0*Mass[n]; + Field[k0 *dim12 + j0 *Dimension[0] + i0p] += wz0*wy0*wxp*Mass[n]; + Field[k0 *dim12 + j0p*Dimension[0] + i0m] += wz0*wyp*wxm*Mass[n]; + Field[k0 *dim12 + j0p*Dimension[0] + i0 ] += wz0*wyp*wx0*Mass[n]; + Field[k0 *dim12 + j0p*Dimension[0] + i0p] += wz0*wyp*wxp*Mass[n]; + + Field[k0p*dim12 + j0m*Dimension[0] + i0m] += wzp*wym*wxm*Mass[n]; + Field[k0p*dim12 + j0m*Dimension[0] + i0 ] += wzp*wym*wx0*Mass[n]; + Field[k0p*dim12 + j0m*Dimension[0] + i0p] += wzp*wym*wxp*Mass[n]; + Field[k0p*dim12 + j0 *Dimension[0] + i0m] += wzp*wy0*wxm*Mass[n]; + Field[k0p*dim12 + j0 *Dimension[0] + i0 ] += wzp*wy0*wx0*Mass[n]; + Field[k0p*dim12 + j0 *Dimension[0] + i0p] += wzp*wy0*wxp*Mass[n]; + Field[k0p*dim12 + j0p*Dimension[0] + i0m] += wzp*wyp*wxm*Mass[n]; + Field[k0p*dim12 + j0p*Dimension[0] + i0 ] += wzp*wyp*wx0*Mass[n]; + Field[k0p*dim12 + j0p*Dimension[0] + i0p] += wzp*wyp*wxp*Mass[n]; + + } // next particle + +#endif /* USE_FORTRAN */ + +} diff --git a/src/enzo/EvolveHierarchy.C b/src/enzo/EvolveHierarchy.C index 3d74566b2..8077f1421 100644 --- a/src/enzo/EvolveHierarchy.C +++ b/src/enzo/EvolveHierarchy.C @@ -30,14 +30,14 @@ / ************************************************************************/ #include "preincludes.h" - + #ifdef USE_MPI #include #endif - + #include -#include "EnzoTiming.h" +#include "EnzoTiming.h" #include "performance.h" #include "ErrorExceptions.h" #include "macros_and_parameters.h" @@ -56,75 +56,77 @@ #ifdef TRANSFER #include "ImplicitProblemABC.h" #endif - + // function prototypes - + int RebuildHierarchy(TopGridData *MetaData, - LevelHierarchyEntry *LevelArray[], int level); + LevelHierarchyEntry *LevelArray[], int level); int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], - int level, float dtLevelAbove, ExternalBoundary *Exterior + int level, float dtLevelAbove, ExternalBoundary *Exterior #ifdef TRANSFER - , ImplicitProblemABC *ImplicitSolver + , + ImplicitProblemABC *ImplicitSolver #endif - ,FLOAT dt0, SiblingGridList *SiblingGridListStorage[] - ); + , + FLOAT dt0, SiblingGridList *SiblingGridListStorage[]); int WriteAllData(char *basename, int filenumber, - HierarchyEntry *TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, + HierarchyEntry *TopGrid, TopGridData &MetaData, + ExternalBoundary *Exterior, #ifdef TRANSFER - ImplicitProblemABC *ImplicitSolver, -#endif - FLOAT WriteTime = -1); + ImplicitProblemABC *ImplicitSolver, +#endif + FLOAT WriteTime = -1); int Group_WriteAllData(char *basename, int filenumber, - HierarchyEntry *TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, + HierarchyEntry *TopGrid, TopGridData &MetaData, + ExternalBoundary *Exterior, #ifdef TRANSFER - ImplicitProblemABC *ImplicitSolver, -#endif - FLOAT WriteTime = -1, - int RestartDump = FALSE); + ImplicitProblemABC *ImplicitSolver, +#endif + FLOAT WriteTime = -1, + int RestartDump = FALSE); -int CopyOverlappingZones(grid* CurrentGrid, TopGridData *MetaData, - LevelHierarchyEntry *LevelArray[], int level); +int CopyOverlappingZones(grid *CurrentGrid, TopGridData *MetaData, + LevelHierarchyEntry *LevelArray[], int level); int TestGravityCheckResults(LevelHierarchyEntry *LevelArray[]); +int TestGravityAPMCheckResults(LevelHierarchyEntry *LevelArray[]); int TestGravitySphereCheckResults(LevelHierarchyEntry *LevelArray[]); int CheckForOutput(HierarchyEntry *TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, + ExternalBoundary *Exterior, #ifdef TRANSFER - ImplicitProblemABC *ImplicitSolver, -#endif - int Restart = FALSE); + ImplicitProblemABC *ImplicitSolver, +#endif + int Restart = FALSE); int CheckForTimeAction(LevelHierarchyEntry *LevelArray[], - TopGridData &MetaData); + TopGridData &MetaData); int CheckForResubmit(TopGridData &MetaData, int &Stop); int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); int OutputLevelInformation(FILE *fptr, TopGridData &MetaData, - LevelHierarchyEntry *LevelArray[]); + LevelHierarchyEntry *LevelArray[]); int PrepareGravitatingMassField(HierarchyEntry *Grid, TopGridData *MetaData, - LevelHierarchyEntry *LevelArray[], int level); + LevelHierarchyEntry *LevelArray[], int level); int ReduceFragmentation(HierarchyEntry &TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, - LevelHierarchyEntry *LevelArray[]); + ExternalBoundary *Exterior, + LevelHierarchyEntry *LevelArray[]); int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[] = NULL, - int NumberOfSubgrids[] = NULL, - int FluxFlag = FALSE, - TopGridData* MetaData = NULL); + int NumberOfSubgrids[] = NULL, + int FluxFlag = FALSE, + TopGridData *MetaData = NULL); double ReturnWallTime(void); int Enzo_Dims_create(int nnodes, int ndims, int *dims); -int FOF(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], - int WroteData, int FOFOnly=FALSE); +int FOF(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], + int WroteData, int FOFOnly = FALSE); int StarParticleCountOnly(LevelHierarchyEntry *LevelArray[]); -int CommunicationLoadBalanceRootGrids(LevelHierarchyEntry *LevelArray[], - int TopGridRank, int CycleNumber); +int CommunicationLoadBalanceRootGrids(LevelHierarchyEntry *LevelArray[], + int TopGridRank, int CycleNumber); int CommunicationBroadcastValue(Eint32 *Value, int BroadcastProcessor); int CommunicationBroadcastValue(Eint64 *Value, int BroadcastProcessor); int ParticleSplitter(LevelHierarchyEntry *LevelArray[], int ThisLevel, - TopGridData *MetaData); + TopGridData *MetaData); int MagneticFieldResetter(LevelHierarchyEntry *LevelArray[], int ThisLevel, - TopGridData *MetaData); + TopGridData *MetaData); void PrintMemoryUsage(char *str); int SetEvolveRefineRegion(FLOAT time); @@ -138,23 +140,18 @@ int CallPython(LevelHierarchyEntry *LevelArray[], TopGridData *MetaData, int level, int from_topgrid); #endif - - #define NO_REDUCE_FRAGMENTATION - - - int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, ExternalBoundary *Exterior, #ifdef TRANSFER - ImplicitProblemABC *ImplicitSolver, + ImplicitProblemABC *ImplicitSolver, #endif - LevelHierarchyEntry *LevelArray[], float Initialdt) + LevelHierarchyEntry *LevelArray[], float Initialdt) { - + float dt; - + int i, dim, Stop = FALSE; int StoppedByOutput = FALSE; int Restart = FALSE; @@ -168,28 +165,32 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #ifdef USE_MPI tentry = MPI_Wtime(); #endif - - if (MetaData.Time >= MetaData.StopTime ) Stop = TRUE; - if (MetaData.CycleNumber >= MetaData.StopCycle) Stop = TRUE; + + if (MetaData.Time >= MetaData.StopTime) + Stop = TRUE; + if (MetaData.CycleNumber >= MetaData.StopCycle) + Stop = TRUE; MetaData.StartCPUTime = LastCPUTime = ReturnWallTime(); MetaData.LastCycleCPUTime = 0.0; // Reset CPUTime, if it's very large (absolute UNIX time), which // was the default from before. - if (MetaData.CPUTime > 1e2*MetaData.StopCPUTime) + if (MetaData.CPUTime > 1e2 * MetaData.StopCPUTime) MetaData.CPUTime = 0.0; - + /* Attach RandomForcingFields to BaryonFields temporarily to apply BCs */ - - if (RandomForcing) { //AK + + if (RandomForcing) + { //AK Temp = LevelArray[0]; - while (Temp != NULL) { + while (Temp != NULL) + { Temp->GridData->AppendForcingToBaryonFields(); Temp = Temp->NextGridThisLevel; } Exterior->AppendForcingToBaryonFields(); } - + /* Set top grid boundary conditions. */ Temp = LevelArray[0]; @@ -204,29 +205,29 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, CommunicationDirection = COMMUNICATION_POST_RECEIVE; CommunicationReceiveCurrentDependsOn = COMMUNICATION_NO_DEPENDENCE; - while (Temp != NULL) { - if (Temp->GridData->SetExternalBoundaryValues(Exterior) == FAIL) { + while (Temp != NULL) + { + if (Temp->GridData->SetExternalBoundaryValues(Exterior) == FAIL) + { // ENZO_FAIL("Error in grid->SetExternalBoundaryValues.\n"); Exterior->Prepare(Temp->GridData); - } - if (CopyOverlappingZones(Temp->GridData, &MetaData, LevelArray, 0) - == FAIL) + if (CopyOverlappingZones(Temp->GridData, &MetaData, LevelArray, 0) == FAIL) ENZO_FAIL("Error in CopyOverlappingZones."); Temp = Temp->NextGridThisLevel; } - + CommunicationDirection = COMMUNICATION_SEND; Temp = LevelArray[0]; - while (Temp != NULL) { - if (CopyOverlappingZones(Temp->GridData, &MetaData, LevelArray, 0) - == FAIL) + while (Temp != NULL) + { + if (CopyOverlappingZones(Temp->GridData, &MetaData, LevelArray, 0) == FAIL) ENZO_FAIL("Error in CopyOverlappingZones."); Temp = Temp->NextGridThisLevel; } -#ifdef FORCE_MSG_PROGRESS +#ifdef FORCE_MSG_PROGRESS CommunicationBarrier(); #endif @@ -237,33 +238,35 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif PrintMemoryUsage("Bdry set"); - + /* Remove RandomForcingFields from BaryonFields when BCs are set. */ - - if (RandomForcing) { //AK + + if (RandomForcing) + { //AK LevelHierarchyEntry *Temp = LevelArray[0]; - while (Temp != NULL) { + while (Temp != NULL) + { Temp->GridData->DetachForcingFromBaryonFields(); Temp = Temp->NextGridThisLevel; } Exterior->DetachForcingFromBaryonFields(); } - + /* Check for output. */ - - CheckForOutput(&TopGrid, MetaData, Exterior, + + CheckForOutput(&TopGrid, MetaData, Exterior, #ifdef TRANSFER - ImplicitSolver, -#endif - Restart); + ImplicitSolver, +#endif + Restart); PrintMemoryUsage("Output"); - + /* Compute the acceleration field so ComputeTimeStep can find dtAccel. (Actually, this is a huge pain-in-the-ass, so only do it if the problem really requires it). */ - -/* + + /* if (ProblemType == 21) { PrepareGravitatingMassField(&TopGrid, &MetaData, LevelArray, 0); ComputePotentialFieldLevelZero(&MetaData, Grids, NumberOfGrids); @@ -271,38 +274,41 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } */ - /* Particle Splitter. Split particles into 13 (=1+12) child particles. The hierarchy is rebuilt inside this routine. */ - + if (MetaData.FirstTimestepAfterRestart == TRUE && - ParticleSplitterIterations > 0) { + ParticleSplitterIterations > 0) + { ParticleSplitter(LevelArray, 0, &MetaData); + } + else + { - } else { + /* Do the first grid regeneration. */ - /* Do the first grid regeneration. */ - - if(CheckpointRestart == FALSE) { + if (CheckpointRestart == FALSE) + { RebuildHierarchy(&MetaData, LevelArray, 0); } } // ENDELSE particle splitting PrintMemoryUsage("1st rebuild"); - + /* Reset magnetic fields if requested. */ - + if (MetaData.FirstTimestepAfterRestart == TRUE && ResetMagneticField == TRUE) MagneticFieldResetter(LevelArray, 0, &MetaData); /* Open the OutputLevelInformation file. */ - + FILE *LevelInfofptr; - - if (MyProcessorNumber == ROOT_PROCESSOR) { + + if (MyProcessorNumber == ROOT_PROCESSOR) + { LevelInfofptr = fopen("OutputLevelInformation.out", "w"); fclose(LevelInfofptr); } @@ -311,7 +317,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, to restrict the timesteps. Collect info here. */ StarParticleCountOnly(LevelArray); - + #ifdef USE_LCAPERF Eint32 lcaperf_iter; #endif @@ -320,24 +326,26 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, LCAPERF_END("EH"); SiblingGridList *SiblingGridListStorage[MAX_DEPTH_OF_HIERARCHY]; - for( int level=0; level < MAX_DEPTH_OF_HIERARCHY; level++ ){ + for (int level = 0; level < MAX_DEPTH_OF_HIERARCHY; level++) + { SiblingGridListStorage[level] = NULL; } - /* ====== MAIN LOOP ===== */ bool FirstLoop = true; - while (!Stop) { + while (!Stop) + { - TIMER_START("Total"); + TIMER_START("Total"); #ifdef USE_LCAPERF lcaperf_iter = MetaData.CycleNumber; static bool isFirstCall = true; - if ((lcaperf_iter % LCAPERF_DUMP_FREQUENCY)==0 || isFirstCall) lcaperf.begin("EL"); + if ((lcaperf_iter % LCAPERF_DUMP_FREQUENCY) == 0 || isFirstCall) + lcaperf.begin("EL"); isFirstCall = false; - lcaperf.attribute ("timestep",&lcaperf_iter, LCAPERF_INT); + lcaperf.attribute("timestep", &lcaperf_iter, LCAPERF_INT); lcaperf.start("EL"); #endif @@ -346,19 +354,20 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif #ifdef MEM_TRACE - fprintf(memtracePtr, "==== CYCLE %"ISYM" ====\n", MetaData.CycleNumber); -#endif + fprintf(memtracePtr, "==== CYCLE %" ISYM " ====\n", MetaData.CycleNumber); +#endif PrintMemoryUsage("Top"); /* Load balance the root grids if this isn't the initial call */ if ((CheckpointRestart == FALSE) && (!FirstLoop)) - CommunicationLoadBalanceRootGrids(LevelArray, MetaData.TopGridRank, - MetaData.CycleNumber); + CommunicationLoadBalanceRootGrids(LevelArray, MetaData.TopGridRank, + MetaData.CycleNumber); /* Output level information to log file. */ - - if (MyProcessorNumber == ROOT_PROCESSOR) { + + if (MyProcessorNumber == ROOT_PROCESSOR) + { LevelInfofptr = fopen("OutputLevelInformation.out", "a"); if (LevelInfofptr == NULL) ENZO_FAIL("Can't open OutputLevelInformation.out!"); @@ -371,28 +380,33 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, if (MyProcessorNumber == ROOT_PROCESSOR) fclose(LevelInfofptr); - + /* Compute minimum timestep on the top level. */ - - float dtProc = huge_number; + + float dtProc = huge_number; Temp = LevelArray[0]; - + // Start skipping - if(CheckpointRestart == FALSE) { - while (Temp != NULL) { + if (CheckpointRestart == FALSE) + { + while (Temp != NULL) + { float dtProcTemp = Temp->GridData->ComputeTimeStep(); dtProc = min(dtProc, dtProcTemp); Temp = Temp->NextGridThisLevel; } - dt = RootGridCourantSafetyNumber*CommunicationMinValue(dtProc); + dt = RootGridCourantSafetyNumber * CommunicationMinValue(dtProc); dt = min(MetaData.MaximumTopGridTimeStep, dt); - if (debug) fprintf(stderr, "dt, Initialdt: %g %g \n", dt, Initialdt); - if (Initialdt != 0) { - - dt = min(dt, Initialdt); - if (debug) fprintf(stderr, "dt, Initialdt: %g %g \n", dt, Initialdt); + if (debug) + fprintf(stderr, "dt, Initialdt: %g %g \n", dt, Initialdt); + if (Initialdt != 0) + { + + dt = min(dt, Initialdt); + if (debug) + fprintf(stderr, "dt, Initialdt: %g %g \n", dt, Initialdt); Initialdt = 0; } @@ -401,94 +415,104 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, if (ComovingCoordinates) for (i = 0; i < MAX_NUMBER_OF_OUTPUT_REDSHIFTS; i++) if (CosmologyOutputRedshift[i] != -1) - dt = min(1.0001*(CosmologyOutputRedshiftTime[i]-MetaData.Time), dt); + dt = min(1.0001 * (CosmologyOutputRedshiftTime[i] - MetaData.Time), dt); for (i = 0; i < MAX_TIME_ACTIONS; i++) if (TimeActionTime[i] > 0 && TimeActionType[i] > 0) - dt = min(1.0001*(TimeActionTime[i] - MetaData.Time), dt); - if (MetaData.dtDataDump > 0.0) { - while (MetaData.TimeLastDataDump+MetaData.dtDataDump < MetaData.Time) + dt = min(1.0001 * (TimeActionTime[i] - MetaData.Time), dt); + if (MetaData.dtDataDump > 0.0) + { + while (MetaData.TimeLastDataDump + MetaData.dtDataDump < MetaData.Time) MetaData.TimeLastDataDump += MetaData.dtDataDump; - dt = min(1.0001*(MetaData.TimeLastDataDump + MetaData.dtDataDump - - MetaData.Time), dt); + dt = min(1.0001 * (MetaData.TimeLastDataDump + MetaData.dtDataDump - + MetaData.Time), + dt); } /* Set the time step. If it will cause Time += dt > StopTime, then set dt = StopTime - Time */ dt = min(MetaData.StopTime - MetaData.Time, dt); - } else { - dt = dtThisLevel[0]; + } + else + { + dt = dtThisLevel[0]; } /* Set the time step. If it will cause Time += dt > StopTime, then set dt = StopTime - Time */ - + dt = min(MetaData.StopTime - MetaData.Time, dt); Temp = LevelArray[0]; // Stop skipping // Set dt from stored in CheckpointRestart - while (Temp != NULL) { + while (Temp != NULL) + { Temp->GridData->SetTimeStep(dt); Temp = Temp->NextGridThisLevel; } - + #ifdef CONFIG_TESTING - if (MyProcessorNumber == ROOT_PROCESSOR) { - printf("enzo-test: MetaData.CycleNumber %"ISYM"\n", MetaData.CycleNumber); - printf("enzo-test: dt %.14g\n",dt); - printf("enzo-test: MetaData.Time %"GOUTSYM"\n", MetaData.Time); + if (MyProcessorNumber == ROOT_PROCESSOR) + { + printf("enzo-test: MetaData.CycleNumber %" ISYM "\n", MetaData.CycleNumber); + printf("enzo-test: dt %.14g\n", dt); + printf("enzo-test: MetaData.Time %" GOUTSYM "\n", MetaData.Time); fflush(stdout); } #endif - if (MyProcessorNumber == ROOT_PROCESSOR) { - fprintf(stderr, "TopGrid dt = %"ESYM" time = %"GOUTSYM" cycle = %"ISYM, - dt, MetaData.Time, MetaData.CycleNumber); + if (MyProcessorNumber == ROOT_PROCESSOR) + { + fprintf(stderr, "TopGrid dt = %" ESYM " time = %" GOUTSYM " cycle = %" ISYM, + dt, MetaData.Time, MetaData.CycleNumber); + fprintf(stdout, "TopGrid dt = %" ESYM " time = %" GOUTSYM " cycle = %" ISYM "\n", + dt, MetaData.Time, MetaData.CycleNumber); - if (ComovingCoordinates) { - FLOAT a, dadt; - CosmologyComputeExpansionFactor(MetaData.Time, &a, &dadt); - fprintf(stderr, " z = %"GOUTSYM, (1 + InitialRedshift)/a - 1); + if (ComovingCoordinates) + { + FLOAT a, dadt; + CosmologyComputeExpansionFactor(MetaData.Time, &a, &dadt); + fprintf(stderr, " z = %" GOUTSYM, (1 + InitialRedshift) / a - 1); } fprintf(stderr, "\n"); } //} - + /* Inline halo finder */ FOF(&MetaData, LevelArray, MetaData.WroteData); - /* If provided, set RefineRegion from evolving RefineRegion - OR set MustRefineRegion from evolving MustRefineRegion + /* If provided, set RefineRegion from evolving RefineRegion + OR set MustRefineRegion from evolving MustRefineRegion OR set CoolingRefineRegion from evolving CoolingRefineRegion */ - if ((RefineRegionTimeType == 1) || (RefineRegionTimeType == 0) - || (MustRefineRegionTimeType == 1) || (MustRefineRegionTimeType == 0) - || (CoolingRefineRegionTimeType == 1) || (CoolingRefineRegionTimeType == 0)) { - if (SetEvolveRefineRegion(MetaData.Time) == FAIL) - ENZO_FAIL("Error in SetEvolveRefineRegion."); + if ((RefineRegionTimeType == 1) || (RefineRegionTimeType == 0) || (MustRefineRegionTimeType == 1) || (MustRefineRegionTimeType == 0) || (CoolingRefineRegionTimeType == 1) || (CoolingRefineRegionTimeType == 0)) + { + if (SetEvolveRefineRegion(MetaData.Time) == FAIL) + ENZO_FAIL("Error in SetEvolveRefineRegion."); } /* Set evolving stellar mass threshold */ - if (StarMakerMinimumMassRamp > 0) { - if (SetStellarMassThreshold(MetaData.Time) == FAIL) - ENZO_FAIL("Error in SetStellarMassThreshold."); + if (StarMakerMinimumMassRamp > 0) + { + if (SetStellarMassThreshold(MetaData.Time) == FAIL) + ENZO_FAIL("Error in SetStellarMassThreshold."); } /* Evolve the stochastic forcing spectrum and add * the force to the acceleration fields */ if (DrivenFlowProfile) - Forcing.Evolve(dt); + Forcing.Evolve(dt); - /* Evolve the top grid (and hence the entire hierarchy). */ + /* Evolve the top grid (and hence the entire hierarchy). */ -#ifdef USE_MPI +#ifdef USE_MPI CommunicationBarrier(); tlev0 = MPI_Wtime(); #endif - /* Zeroing out the rootgrid Emissivity before EvolveLevel is called - so when rootgrid emissivity values are calculated they are put in + /* Zeroing out the rootgrid Emissivity before EvolveLevel is called + so when rootgrid emissivity values are calculated they are put in clean rootgrid array */ #ifdef EMISSIVITY /* @@ -502,71 +526,78 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } */ #endif - + if (EvolveLevel(&MetaData, LevelArray, 0, dt, Exterior #ifdef TRANSFER - , ImplicitSolver -#endif - ,dt, SiblingGridListStorage - ) == FAIL) { - if (NumberOfProcessors == 1) { - fprintf(stderr, "Error in EvolveLevel.\n"); - fprintf(stderr, "--> Dumping data (output number %d).\n", - MetaData.DataDumpNumber); - Group_WriteAllData(MetaData.DataDumpName, MetaData.DataDumpNumber, - &TopGrid, MetaData, Exterior + , + ImplicitSolver +#endif + , + dt, SiblingGridListStorage) == FAIL) + { + if (NumberOfProcessors == 1) + { + fprintf(stderr, "Error in EvolveLevel.\n"); + fprintf(stderr, "--> Dumping data (output number %d).\n", + MetaData.DataDumpNumber); + Group_WriteAllData(MetaData.DataDumpName, MetaData.DataDumpNumber, + &TopGrid, MetaData, Exterior #ifdef TRANSFER - , ImplicitSolver -#endif - ); - } - return FAIL; + , + ImplicitSolver +#endif + ); + } + return FAIL; } - - -#ifdef USE_MPI +#ifdef USE_MPI CommunicationBarrier(); tlev1 = MPI_Wtime(); #endif - + /* Add time and check stopping criteria (steps #21 & #22) (note the topgrid is also keeping its own time but this statement will keep the two in synch). */ - + MetaData.Time += dt; MetaData.CycleNumber++; MetaData.LastCycleCPUTime = ReturnWallTime() - LastCPUTime; MetaData.CPUTime += MetaData.LastCycleCPUTime; LastCPUTime = ReturnWallTime(); - if (MyProcessorNumber == ROOT_PROCESSOR) { - - if (MetaData.Time >= MetaData.StopTime) { - if (MyProcessorNumber == ROOT_PROCESSOR) - printf("Stopping on top grid time limit.\n"); - Stop = TRUE; - } else - if (MetaData.CycleNumber >= MetaData.StopCycle) { - if (MyProcessorNumber == ROOT_PROCESSOR) - printf("Stopping on top grid cycle limit.\n"); - Stop = TRUE; - } else - if (MetaData.CPUTime >= MetaData.StopCPUTime) { - if (MyProcessorNumber == ROOT_PROCESSOR) - printf("Stopping on CPU time limit.\n"); - Stop = TRUE; - } else - if ((ReturnWallTime() - MetaData.StartCPUTime >= MetaData.dtRestartDump && - MetaData.dtRestartDump > 0) || - (MetaData.CycleNumber - MetaData.CycleLastRestartDump >= - MetaData.CycleSkipRestartDump && - MetaData.CycleSkipRestartDump > 0)) { - if (MyProcessorNumber == ROOT_PROCESSOR) - printf("Stopping to restart.\n"); - Stop = TRUE; - Restart = TRUE; - } + if (MyProcessorNumber == ROOT_PROCESSOR) + { + + if (MetaData.Time >= MetaData.StopTime) + { + if (MyProcessorNumber == ROOT_PROCESSOR) + printf("Stopping on top grid time limit.\n"); + Stop = TRUE; + } + else if (MetaData.CycleNumber >= MetaData.StopCycle) + { + if (MyProcessorNumber == ROOT_PROCESSOR) + printf("Stopping on top grid cycle limit.\n"); + Stop = TRUE; + } + else if (MetaData.CPUTime >= MetaData.StopCPUTime) + { + if (MyProcessorNumber == ROOT_PROCESSOR) + printf("Stopping on CPU time limit.\n"); + Stop = TRUE; + } + else if ((ReturnWallTime() - MetaData.StartCPUTime >= MetaData.dtRestartDump && + MetaData.dtRestartDump > 0) || + (MetaData.CycleNumber - MetaData.CycleLastRestartDump >= + MetaData.CycleSkipRestartDump && + MetaData.CycleSkipRestartDump > 0)) + { + if (MyProcessorNumber == ROOT_PROCESSOR) + printf("Stopping to restart.\n"); + Stop = TRUE; + Restart = TRUE; + } } // ENDIF ROOT_PROCESSOR CommunicationBroadcastValue(&Stop, ROOT_PROCESSOR); @@ -579,7 +610,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif PrintMemoryUsage("Pre loop rebuild"); - + if (ProblemType != 25 && Restart == FALSE) RebuildHierarchy(&MetaData, LevelArray, 0); @@ -588,18 +619,18 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #ifdef USE_MPI treb1 = MPI_Wtime(); #endif - + /* Check for time-actions. */ - + CheckForTimeAction(LevelArray, MetaData); - + /* Check for output. */ - - CheckForOutput(&TopGrid, MetaData, Exterior, + + CheckForOutput(&TopGrid, MetaData, Exterior, #ifdef TRANSFER - ImplicitSolver, -#endif - Restart); + ImplicitSolver, +#endif + Restart); /* Call inline analysis. */ @@ -610,7 +641,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif /* Check for resubmission */ - + if (!Restart) CheckForResubmit(MetaData, Stop); @@ -619,29 +650,31 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, if (Stop && !Restart) FOF(&MetaData, LevelArray, TRUE); - /* Try to cut down on memory fragmentation. */ - + /* Try to cut down on memory fragmentation. */ + #ifdef REDUCE_FRAGMENTATION - + if (MetaData.WroteData && !Stop) ReduceFragmentation(TopGrid, MetaData, Exterior, LevelArray); - + #endif /* REDUCE_FRAGMENTATION */ #ifdef USE_LCAPERF lcaperf.stop("EL"); - if (((lcaperf_iter+1) % LCAPERF_DUMP_FREQUENCY)==0) lcaperf.end("EL"); + if (((lcaperf_iter + 1) % LCAPERF_DUMP_FREQUENCY) == 0) + lcaperf.end("EL"); #endif PrintMemoryUsage("Bot"); - for ( i = 0; i < MAX_NUMBER_OF_TASKS; i++ ) { - TaskMemory[i] = -1; - } + for (i = 0; i < MAX_NUMBER_OF_TASKS; i++) + { + TaskMemory[i] = -1; + } #ifdef MEM_TRACE - /* + /* MPI_Datatype DataTypeInt = (sizeof(Eint64) == 4) ? MPI_INT : MPI_LONG_LONG_INT; MPI_Arg ThisTask; MPI_Arg TaskCount; @@ -666,18 +699,21 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, FILE *evlog; - if (MyProcessorNumber == ROOT_PROCESSOR) { + if (MyProcessorNumber == ROOT_PROCESSOR) + { evlog = fopen("Evtime", "a"); - fprintf(evlog, "%8"ISYM" %16.9e %16.9e %16.9e\n", MetaData.CycleNumber, tlev1-tlev0, treb1-treb0, tloop1-tloop0); + fprintf(evlog, "%8" ISYM " %16.9e %16.9e %16.9e\n", MetaData.CycleNumber, tlev1 - tlev0, treb1 - treb0, tloop1 - tloop0); fclose(evlog); } #ifdef MEM_TRACE Eint64 MemInUse; - if (MetaData.WroteData) { + if (MetaData.WroteData) + { MemInUse = mused(); MemInUse = CommunicationMaxValue(MemInUse); - if (MemInUse > MemoryLimit) { + if (MemInUse > MemoryLimit) + { if (MyProcessorNumber == ROOT_PROCESSOR) printf("Stopping due to memory limit.\n"); Stop = TRUE; @@ -686,20 +722,23 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif TIMER_STOP("Total"); - if ((MetaData.CycleNumber-1) % TimingCycleSkip == 0) - TIMER_WRITE(MetaData.CycleNumber); + if ((MetaData.CycleNumber - 1) % TimingCycleSkip == 0) + TIMER_WRITE(MetaData.CycleNumber); FirstLoop = false; - + /* If simulation is set to stop after writing a set number of outputs, check that here. */ - if (MetaData.NumberOfOutputsBeforeExit && MetaData.WroteData) { + if (MetaData.NumberOfOutputsBeforeExit && MetaData.WroteData) + { MetaData.OutputsLeftBeforeExit--; - if (MetaData.OutputsLeftBeforeExit <= 0) { - if (MyProcessorNumber == ROOT_PROCESSOR) { - fprintf(stderr, "Exiting after writing %"ISYM" datadumps.\n", + if (MetaData.OutputsLeftBeforeExit <= 0) + { + if (MyProcessorNumber == ROOT_PROCESSOR) + { + fprintf(stderr, "Exiting after writing %" ISYM " datadumps.\n", MetaData.NumberOfOutputsBeforeExit); - } + } Stop = TRUE; StoppedByOutput = TRUE; } @@ -708,71 +747,76 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } // ===== end of main loop ==== #ifdef USE_LCAPERF - if (((lcaperf_iter+1) % LCAPERF_DUMP_FREQUENCY)!=0) lcaperf.end("EL"); - lcaperf.attribute ("timestep",0, LCAPERF_NULL); + if (((lcaperf_iter + 1) % LCAPERF_DUMP_FREQUENCY) != 0) + lcaperf.end("EL"); + lcaperf.attribute("timestep", 0, LCAPERF_NULL); #endif MetaData.CPUTime = ReturnWallTime() - MetaData.StartCPUTime; - + /* Done, so report on current time, etc. */ - - if (MyProcessorNumber == ROOT_PROCESSOR) { - printf("Time = %9"FSYM" CycleNumber = %6"ISYM" Wallclock = %9"FSYM"\n", - MetaData.Time, MetaData.CycleNumber, MetaData.CPUTime); - printf("StopTime = %9"FSYM" StopCycle = %6"ISYM"\n", - MetaData.StopTime, MetaData.StopCycle); + + if (MyProcessorNumber == ROOT_PROCESSOR) + { + printf("Time = %9" FSYM " CycleNumber = %6" ISYM " Wallclock = %9" FSYM "\n", + MetaData.Time, MetaData.CycleNumber, MetaData.CPUTime); + printf("StopTime = %9" FSYM " StopCycle = %6" ISYM "\n", + MetaData.StopTime, MetaData.StopCycle); } - - /* If we are running problem 23, TestGravity, then check the results. */ - + + /* If we are running TestGravity problems 23/123, then check the results. */ + if (ProblemType == 23) TestGravityCheckResults(LevelArray); + if (ProblemType == 123) + TestGravityAPMCheckResults(LevelArray); if (ProblemType == 25 && NumberOfProcessors == 0) TestGravitySphereCheckResults(LevelArray); - + /* if we are doing data dumps, then do one last one */ - + if ((MetaData.dtDataDump != 0.0 || MetaData.CycleSkipDataDump != 0) && !MetaData.WroteData) //#ifdef USE_HDF5_GROUPS if (Group_WriteAllData(MetaData.DataDumpName, MetaData.DataDumpNumber, - &TopGrid, MetaData, Exterior, + &TopGrid, MetaData, Exterior, #ifdef TRANSFER - ImplicitSolver, -#endif - -666) == FAIL) + ImplicitSolver, +#endif + -666) == FAIL) ENZO_FAIL("Error in Group_WriteAllData."); -// #else -// if (WriteAllData(MetaData.DataDumpName, MetaData.DataDumpNumber, -// &TopGrid, MetaData, Exterior, -//#ifdef TRANSFER -// ImplicitSolver, -//#endif -// -666) == FAIL) { -// ENZO_FAIL("Error in WriteAllData.\n"); -// } -// #endif - + // #else + // if (WriteAllData(MetaData.DataDumpName, MetaData.DataDumpNumber, + // &TopGrid, MetaData, Exterior, + //#ifdef TRANSFER + // ImplicitSolver, + //#endif + // -666) == FAIL) { + // ENZO_FAIL("Error in WriteAllData.\n"); + // } + // #endif + /* Write a file to indicate that we're finished. */ FILE *Exit_fptr; - if (!Restart && !StoppedByOutput && MyProcessorNumber == ROOT_PROCESSOR) { + if (!Restart && !StoppedByOutput && MyProcessorNumber == ROOT_PROCESSOR) + { if ((Exit_fptr = fopen("RunFinished", "w")) == NULL) ENZO_FAIL("Error opening RunFinished."); - fprintf(Exit_fptr, "Finished on cycle %"ISYM"\n", MetaData.CycleNumber); + fprintf(Exit_fptr, "Finished on cycle %" ISYM "\n", MetaData.CycleNumber); fclose(Exit_fptr); } if (NumberOfProcessors > 1) - printf("Communication: processor %"ISYM" CommunicationTime = %"FSYM"\n", - MyProcessorNumber, CommunicationTime); - - /* done */ + printf("Communication: processor %" ISYM " CommunicationTime = %" FSYM "\n", + MyProcessorNumber, CommunicationTime); + + /* done */ #ifdef USE_MPI texit = MPI_Wtime(); #endif - + return SUCCESS; } diff --git a/src/enzo/EvolveLevel.C b/src/enzo/EvolveLevel.C index b27aabb03..a4a1aa58a 100644 --- a/src/enzo/EvolveLevel.C +++ b/src/enzo/EvolveLevel.C @@ -25,7 +25,7 @@ / modified4: January, 2004 by Alexei Kritsuk / Added support for RandomForcing / modified5: February, 2006 by Daniel Reynolds -/ Added PotentialBdry to EvolveLevel and +/ Added PotentialBdry to EvolveLevel and / PrepareDensityField calls, so that it can be used / within computing isolating BCs for self-gravity. / modified6: January, 2007 by Robert Harkness @@ -68,11 +68,11 @@ / ************************************************************************/ #include "preincludes.h" - + #ifdef USE_MPI #include "mpi.h" #endif /* USE_MPI */ - + #include #include #include @@ -100,13 +100,13 @@ #else void RunEventHooks(char *, HierarchyEntry *Grid[], TopGridData &MetaData) {} #endif - + /* function prototypes */ - + #ifdef TRANSFER #define IMPLICIT_MACRO , ImplicitSolver #else -#define IMPLICIT_MACRO +#define IMPLICIT_MACRO #endif #define EXTRA_OUTPUT_MACRO(A,B) ExtraOutput(A,LevelArray,MetaData,level,Exterior IMPLICIT_MACRO,B); @@ -116,7 +116,7 @@ int ExtraOutput(int output_flag, LevelHierarchyEntry *LevelArray[],TopGridData * #endif , char * output_string); -int ComputeDednerWaveSpeeds(TopGridData *MetaData,LevelHierarchyEntry *LevelArray[], +int ComputeDednerWaveSpeeds(TopGridData *MetaData,LevelHierarchyEntry *LevelArray[], int level, FLOAT dt0); int RebuildHierarchy(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], int level); @@ -129,8 +129,8 @@ int GenerateGridArray(LevelHierarchyEntry *LevelArray[], int level, int WriteStreamData(LevelHierarchyEntry *LevelArray[], int level, TopGridData *MetaData, int *CycleCount, int open=FALSE); int CallProblemSpecificRoutines(TopGridData * MetaData, HierarchyEntry *ThisGrid, - int GridNum, float *norm, float TopGridTimeStep, - int level, int LevelCycleCount[]); + int GridNum, float *norm, float TopGridTimeStep, + int level, int LevelCycleCount[]); #ifdef FAST_SIB int PrepareDensityField(LevelHierarchyEntry *LevelArray[], @@ -139,7 +139,7 @@ int PrepareDensityField(LevelHierarchyEntry *LevelArray[], int PrepareDensityField(LevelHierarchyEntry *LevelArray[], int level, TopGridData *MetaData, FLOAT When); #endif // end FAST_SIB - + #ifdef FAST_SIB int SetBoundaryConditions(HierarchyEntry *Grids[], int NumberOfGrids, SiblingGridList SiblingList[], @@ -163,7 +163,7 @@ int SetAccelerationBoundary(HierarchyEntry *Grids[], int NumberOfGrids, int CycleNumber); #else int SetAccelerationBoundary(HierarchyEntry *Grids[], int NumberOfGrids, - int level, TopGridData *MetaData, + int level, TopGridData *MetaData, ExternalBoundary *Exterior, LevelHierarchyEntry * Level, int CycleNumber); @@ -177,9 +177,9 @@ int UpdateFromFinerGrids(int level, HierarchyEntry *Grids[], int NumberOfGrids, TopGridData *MetaData); int CreateFluxes(HierarchyEntry *Grids[],fluxes **SubgridFluxesEstimate[], - int NumberOfGrids,int NumberOfSubgrids[]); + int NumberOfGrids,int NumberOfSubgrids[]); int FinalizeFluxes(HierarchyEntry *Grids[],fluxes **SubgridFluxesEstimate[], - int NumberOfGrids,int NumberOfSubgrids[]); + int NumberOfGrids,int NumberOfSubgrids[]); int RadiationFieldUpdate(LevelHierarchyEntry *LevelArray[], int level, TopGridData *MetaData); @@ -190,7 +190,7 @@ int OutputFromEvolveLevel(LevelHierarchyEntry *LevelArray[],TopGridData *MetaDat , ImplicitProblemABC *ImplicitSolver #endif ); - + int ComputeRandomForcingNormalization(LevelHierarchyEntry *LevelArray[], int level, TopGridData *MetaData, float * norm, float * pTopGridTimeStep); @@ -199,10 +199,10 @@ int ComputeStochasticForcing(TopGridData *MetaData, HierarchyEntry *Grids[], int NumberOfGrids); int ClusterSMBHSumGasMass(HierarchyEntry *Grids[], int NumberOfGrids, int level); -int CreateSiblingList(HierarchyEntry ** Grids, int NumberOfGrids, SiblingGridList *SiblingList, +int CreateSiblingList(HierarchyEntry ** Grids, int NumberOfGrids, SiblingGridList *SiblingList, int StaticLevelZero,TopGridData * MetaData,int level); -#ifdef FAST_SIB +#ifdef FAST_SIB int CreateSUBlingList(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], int level, SiblingGridList SiblingList[], @@ -222,14 +222,14 @@ int ActiveParticleFinalize(HierarchyEntry *Grids[], TopGridData *MetaData, int NumberOfGrids, LevelHierarchyEntry *LevelArray[], int level, int NumberOfNewActiveParticles[]); int StarParticleInitialize(HierarchyEntry *Grids[], TopGridData *MetaData, - int NumberOfGrids, LevelHierarchyEntry *LevelArray[], + int NumberOfGrids, LevelHierarchyEntry *LevelArray[], int ThisLevel, Star *&AllStars, int TotalStarParticleCountPrevious[]); int StarParticleFinalize(HierarchyEntry *Grids[], TopGridData *MetaData, - int NumberOfGrids, LevelHierarchyEntry *LevelArray[], + int NumberOfGrids, LevelHierarchyEntry *LevelArray[], int level, Star *&AllStars, int TotalStarParticleCountPrevious[], int &OutputNow); -int AdjustRefineRegion(LevelHierarchyEntry *LevelArray[], +int AdjustRefineRegion(LevelHierarchyEntry *LevelArray[], TopGridData *MetaData, int EL_level); int AdjustMustRefineParticlesRefineToLevel(TopGridData *MetaData, int EL_level); @@ -240,7 +240,7 @@ int RadiativeTransferPrepare(LevelHierarchyEntry *LevelArray[], int level, TopGridData *MetaData, Star *&AllStars, float dtLevelAbove); int RadiativeTransferCallFLD(LevelHierarchyEntry *LevelArray[], int level, - TopGridData *MetaData, Star *AllStars, + TopGridData *MetaData, Star *AllStars, ImplicitProblemABC *ImplicitSolver); #endif @@ -248,20 +248,27 @@ int ComputeDomainBoundaryMassFlux(HierarchyEntry *Grids[], int level, int NumberOfGrids, TopGridData *MetaData); +int ComputeAccelerationFieldAPMGravity(HierarchyEntry *Grid, TopGridData *MetaData, + LevelHierarchyEntry *LevelArray[], int level, + ExternalBoundary *Exterior = NULL); + +int OutputAccelerationField(HierarchyEntry *Grid, int level, int cycle_number); +int OutputGravitatingMassField(HierarchyEntry *Grid, int level, int cycle_number); + int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, float *dtThisLevelSoFar, float *dtThisLevel, float dtLevelAbove); void my_exit(int status); - + int CallPython(LevelHierarchyEntry *LevelArray[], TopGridData *MetaData, int level, int from_topgrid); int MovieCycleCount[MAX_DEPTH_OF_HIERARCHY]; double LevelWallTime[MAX_DEPTH_OF_HIERARCHY]; double LevelZoneCycleCount[MAX_DEPTH_OF_HIERARCHY]; double LevelZoneCycleCountPerProc[MAX_DEPTH_OF_HIERARCHY]; - + static float norm = 0.0; //AK static float TopGridTimeStep = 0.0; //AK #ifdef STATIC_SIBLING_LIST @@ -278,7 +285,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], #ifdef TRANSFER , ImplicitProblemABC *ImplicitSolver #endif - , FLOAT dt0, SiblingGridList *SiblingGridListStorage[] + , FLOAT dt0, SiblingGridList *SiblingGridListStorage[] ) { /* Declarations */ @@ -294,13 +301,13 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], char level_name[MAX_LINE_LENGTH]; sprintf(level_name, "Level_%02"ISYM, level); - + // Update lcaperf "level" attribute Eint32 lcaperf_level = level; #ifdef USE_LCAPERF lcaperf.attribute ("level",&lcaperf_level,LCAPERF_INT); #endif - + /* Create an array (Grids) of all the grids. */ typedef HierarchyEntry* HierarchyEntryPointer; @@ -317,12 +324,12 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Initialize the chaining mesh used in the FastSiblingLocator. */ - if (dbx) fprintf(stderr, "EL: Initialize FSL \n"); + if (dbx) fprintf(stderr, "EL: Initialize FSL \n"); SiblingGridList *SiblingList = new SiblingGridList[NumberOfGrids]; SiblingGridListStorage[level] = SiblingList; CreateSiblingList(Grids, NumberOfGrids, SiblingList, StaticLevelZero,MetaData,level); - - /* Adjust the refine region so that only the finest particles + + /* Adjust the refine region so that only the finest particles are included. We don't want the more massive particles to contaminate the high-resolution region. */ @@ -335,7 +342,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* ================================================================== */ /* For each grid: a) interpolate boundaries from its parent. b) copy any overlapping zones. */ - + if (CheckpointRestart == FALSE) { #ifdef FAST_SIB if (SetBoundaryConditions(Grids, NumberOfGrids, SiblingList, @@ -347,16 +354,16 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], ENZO_FAIL("Error in SetBoundaryConditions (SlowSib)"); #endif } - + Grids[0]->GridData->SetNumberOfColours(); /* Clear the boundary fluxes for all Grids (this will be accumulated over the subcycles below (i.e. during one current grid step) and used to by the - current grid to correct the zones surrounding this subgrid (step #18). + current grid to correct the zones surrounding this subgrid (step #18). If we're just coming in off a CheckpointRestart, instead we take the - fluxes that were stored in the file and then in the Grid object, and we + fluxes that were stored in the file and then in the Grid object, and we put them into the SubgridFluxesEstimate array. */ - + if(CheckpointRestart == TRUE) { for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { if (Grids[grid1]->GridData->FillFluxesFromStorage( @@ -374,7 +381,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], } } - + /* After we calculate the ghost zones, we can initialize streaming data files (only on level 0) */ @@ -385,7 +392,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* ================================================================== */ /* Loop over grid timesteps until the elapsed time equals the timestep from the level above (or loop once for the top level). */ - + EXTRA_OUTPUT_MACRO(1, "Before Time Loop") while ((CheckpointRestart == TRUE) @@ -393,7 +400,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], if(CheckpointRestart == FALSE) { TIMER_START(level_name); - SetLevelTimeStep(Grids, NumberOfGrids, level, + SetLevelTimeStep(Grids, NumberOfGrids, level, &dtThisLevelSoFar[level], &dtThisLevel[level], dtLevelAbove); TimeSinceRebuildHierarchy[level] += dtThisLevel[level]; @@ -409,8 +416,8 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Currently (April 2012) this is only implemented for H2REG_STAR, and MakeStars is completely ignored in all other star makers. */ - if ( (STARMAKE_METHOD(H2REG_STAR)) && - (level==0) && + if ( (STARMAKE_METHOD(H2REG_STAR)) && + (level==0) && (StarFormationOncePerRootGridTimeStep) ) { /* At top level, set Grid::MakeStars to 1 for all highest refinement level grids. */ @@ -422,7 +429,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], Temp = Temp->NextGridThisLevel; count++; } - // if(MyProcessorNumber == ROOT_PROCESSOR) + // if(MyProcessorNumber == ROOT_PROCESSOR) // fprintf(stderr,"Set MakeStars=1 for %d MaximumRefinementLevel grids.\n",count); TopGridTimeStep = LevelArray[0]->GridData->ReturnTimeStep(); @@ -438,7 +445,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], ActiveParticleInitialize(Grids, MetaData, NumberOfGrids, LevelArray, level); - + Star *AllStars = NULL; StarParticleInitialize(Grids, MetaData, NumberOfGrids, LevelArray, level, AllStars, TotalStarParticleCountPrevious); @@ -451,28 +458,28 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Initialize the radiative transfer */ TIMER_STOP(level_name); - RadiativeTransferPrepare(LevelArray, level, MetaData, AllStars, + RadiativeTransferPrepare(LevelArray, level, MetaData, AllStars, dtLevelAbove); - RadiativeTransferCallFLD(LevelArray, level, MetaData, AllStars, + RadiativeTransferCallFLD(LevelArray, level, MetaData, AllStars, ImplicitSolver); /* Solve the radiative transfer */ - + GridTime = Grids[0]->GridData->ReturnTime() + dtThisLevel[level]; EvolvePhotons(MetaData, LevelArray, AllStars, GridTime, level); TIMER_START(level_name); - + #endif /* TRANSFER */ /* trying to clear Emissivity here after FLD uses it, doesn't work */ - + CreateFluxes(Grids,SubgridFluxesEstimate,NumberOfGrids,NumberOfSubgrids); if ((HydroMethod == MHD_RK) && (level == 0)) ComputeDednerWaveSpeeds(MetaData, LevelArray, level, dt0); - - if (debug1 && HydroMethod == MHD_RK && (MyProcessorNumber == ROOT_PROCESSOR)) - fprintf(stderr, "wave speeds: timestep: %"GSYM" C_h: %"GSYM" C_p: %"GSYM"\n ", + + if (debug1 && HydroMethod == MHD_RK && (MyProcessorNumber == ROOT_PROCESSOR)) + fprintf(stderr, "wave speeds: timestep: %"GSYM" C_h: %"GSYM" C_p: %"GSYM"\n ", dt0, C_h, C_p); /* ------------------------------------------------------- */ /* Prepare the density field (including particle density). */ @@ -484,10 +491,13 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], #else // !FAST_SIB PrepareDensityField(LevelArray, level, MetaData, When); #endif // end FAST_SIB - - + + /* Set the time for evaluation of the fields, etc. */ + FLOAT EvaluateTime = LevelArray[level]->GridData->ReturnTime() + + When*LevelArray[level]->GridData->ReturnTimeStep(); + /* Prepare normalization for random forcing. Involves top grid only. */ - + ComputeRandomForcingNormalization(LevelArray, 0, MetaData, &norm, &TopGridTimeStep); @@ -504,29 +514,51 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Evolve all grids by timestep dtThisLevel. */ for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { - - CallProblemSpecificRoutines(MetaData, Grids[grid1], grid1, &norm, + + CallProblemSpecificRoutines(MetaData, Grids[grid1], grid1, &norm, TopGridTimeStep, level, LevelCycleCount); /* Gravity: compute acceleration field for grid and particles. */ if (SelfGravity) { - if (level <= MaximumGravityRefinementLevel) { + /* Default solver */ + if (GravitySolverType == GRAVITY_SOLVER_FAST) { + if (level <= MaximumGravityRefinementLevel) { + + /* Compute the potential. */ + if (level > 0) + Grids[grid1]->GridData->SolveForPotential(level); + Grids[grid1]->GridData->ComputeAccelerations(level); + Grids[grid1]->GridData->CopyPotentialToBaryonField(); + } + /* otherwise, interpolate potential from coarser grid, which is + now done in PrepareDensity. */ - /* Compute the potential. */ + } else if (GravitySolverType == GRAVITY_SOLVER_APM) { + if (ComputeAccelerationFieldAPMGravity(Grids[grid1], MetaData, LevelArray, + level, Exterior) == FAIL) { + ENZO_FAIL("Error in ComputeAccelerationFieldAPMGravity.C\n"); + } - if (level > 0) - Grids[grid1]->GridData->SolveForPotential(level); - Grids[grid1]->GridData->ComputeAccelerations(level); Grids[grid1]->GridData->CopyPotentialToBaryonField(); - } - /* otherwise, interpolate potential from coarser grid, which is - now done in PrepareDensity. */ - - } // end: if (SelfGravity) + } /* end if (GravitySolverType == GRAVITY_SOLVER_APM) */ + } /* end if (SelfGravity) /* Gravity: compute field due to preset sources. */ Grids[grid1]->GridData->ComputeAccelerationFieldExternal(); + // Diagnostic AccelerationField for test problems TestGravitySphere and TestGravitySineWave + if (ProblemType == 125 || ProblemType == 44) + if ((MetaData->Time >= MetaData->TimeLastDataDump && MetaData->dtDataDump > 0.0) || + (MetaData->CycleNumber == MetaData->CycleLastDataDump && MetaData->CycleSkipDataDump > 0)) + OutputAccelerationField(Grids[grid1],level, MetaData->DataDumpNumber-1); + + // Diagnostic particles for tests TestOrbit and TestSelfforce + if (MyProcessorNumber == ROOT_PROCESSOR) + if (ProblemType == 29 || ProblemType == 47) + if (Grids[grid1]->GridData->ReturnNumberOfParticles() > 0) + printf("Level = %i, number of particles = %i\n", + level, Grids[grid1]->GridData->ReturnNumberOfParticles()); + /* Radiation Pressure: add to acceleration field */ #ifdef TRANSFER Grids[grid1]->GridData->AddRadiationPressureAcceleration(); @@ -559,17 +591,17 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], if (QuantumPressure == 1) Grids[grid1]->GridData->SchrodingerSolver(LevelCycleCount[level]); - // Find recently-supernova stars to add them the MagneticSupernovaList + // Find recently-supernova stars to add them the MagneticSupernovaList if ((UseMagneticSupernovaFeedback) && (level == MaximumRefinementLevel)) Grids[grid1]->GridData->AddMagneticSupernovaeToList(); - /* Call hydro solver and save fluxes around subgrids. - * HD_RK and MHD_RK are the 2nd order Runge-Kutta integrations, which - * require two steps (*_1stStep and *_2ndStep) + /* Call hydro solver and save fluxes around subgrids. + * HD_RK and MHD_RK are the 2nd order Runge-Kutta integrations, which + * require two steps (*_1stStep and *_2ndStep) * and additional boundary condition calls. * All others (PPM, Zeus, MHD_Li/CT) are called from SolveHydroEquations */ - + if( HydroMethod != HD_RK && HydroMethod != MHD_RK ){ Grids[grid1]->GridData->SolveHydroEquations(LevelCycleCount[level], @@ -596,12 +628,12 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], RK2SecondStepBaryonDeposit = 1; // set this to (0/1) to (not use/use) this extra step //##### - if (RK2SecondStepBaryonDeposit && SelfGravity && UseHydro) { + if (RK2SecondStepBaryonDeposit && SelfGravity && UseHydro) { When = 0.5; #ifdef FAST_SIB PrepareDensityField(LevelArray, level, MetaData, When, SiblingGridListStorage); -#else +#else PrepareDensityField(LevelArray, level, MetaData, When); #endif // end FAST_SIB @@ -612,7 +644,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], if (RK2SecondStepBaryonDeposit && SelfGravity) { int Dummy; if (level <= MaximumGravityRefinementLevel) { - if (level > 0) + if (level > 0) Grids[grid1]->GridData->SolveForPotential(level) ; Grids[grid1]->GridData->ComputeAccelerations(level) ; } @@ -623,12 +655,12 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], } // End of loop over grids -#ifdef SAB +#ifdef SAB //Ensure the consistency of the AccelerationField SetAccelerationBoundary(Grids, NumberOfGrids,SiblingList,level, MetaData, Exterior, LevelArray[level], LevelCycleCount[level]); -#endif //SAB. +#endif //SAB. } for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { @@ -642,10 +674,10 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], Grids[grid1]->GridData->MHDRK2_2ndStep (SubgridFluxesEstimate[grid1], NumberOfSubgrids[grid1], level, Exterior); - if (UseAmbipolarDiffusion) + if (UseAmbipolarDiffusion) Grids[grid1]->GridData->AddAmbipolarDiffusion(); - if (UseResistivity) + if (UseResistivity) Grids[grid1]->GridData->AddResistivity(); } // ENDIF MHD_RK @@ -654,29 +686,29 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Add viscosity */ - if (UseViscosity) + if (UseViscosity) Grids[grid1]->GridData->AddViscosity(); } // ENDIF UseHydro }//grid }//RK hydro - + /* Solve the cooling and species rate equations. */ - + for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { Grids[grid1]->GridData->MultiSpeciesHandler(); /* Update particle positions (if present). */ - + UpdateParticlePositions(Grids[grid1]->GridData); /*Trying after solving for radiative transfer */ #ifdef EMISSIVITY - /* - clear the Emissivity of the level below, after the level below + /* + clear the Emissivity of the level below, after the level below updated the current level (it's parent) and before the next - timestep at the current level. + timestep at the current level. */ /* if (StarMakerEmissivityField > 0) { LevelHierarchyEntry *Temp; @@ -742,18 +774,18 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], Grids[grid1]->GridData->DeleteParticleAcceleration(); - if (UseFloor) + if (UseFloor) Grids[grid1]->GridData->SetFloor(); - + /* Update current problem time of this subgrid. */ - + Grids[grid1]->GridData->SetTimeNextTimestep(); - + /* If using comoving co-ordinates, do the expansion terms now. */ - + if (ComovingCoordinates) Grids[grid1]->GridData->ComovingExpansionTerms(); - + if (UseMagneticSupernovaFeedback) Grids[grid1]->GridData->MagneticSupernovaList.clear(); } //end loop over grids @@ -767,7 +799,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* For each grid: a) interpolate boundaries from the parent grid. b) copy any overlapping zones from siblings. */ - + EXTRA_OUTPUT_MACRO(2,"After SolveHydroEquations grid loop") if (UsePoissonDivergenceCleaning != 0){ @@ -777,10 +809,10 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], #else SetBoundaryConditions(Grids, NumberOfGrids, level, MetaData, Exterior, LevelArray[level]); #endif - - for (grid1 = 0; grid1 < NumberOfGrids; grid1++) + + for (grid1 = 0; grid1 < NumberOfGrids; grid1++) Grids[grid1]->GridData->PoissonSolver(level); - + } EXTRA_OUTPUT_MACRO(25,"After SBC") @@ -797,14 +829,14 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* For each grid, delete the GravitatingMassFieldParticles. */ - + for (grid1 = 0; grid1 < NumberOfGrids; grid1++) Grids[grid1]->GridData->DeleteGravitatingMassFieldParticles(); TIMER_STOP(level_name); /* ----------------------------------------- */ /* Evolve the next level down (recursively). */ - + MetaData->FirstTimestepAfterRestart = FALSE; } else { // CheckpointRestart @@ -856,8 +888,8 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Once MBH particles are inserted throughout the whole grid hierarchy, turn off MBH creation (at the bottom of the hierarchy) */ - if (STARMAKE_METHOD(MBH_PARTICLE) && (LevelArray[level+1] == NULL)) { - StarParticleCreation -= pow(2, MBH_PARTICLE); + if (STARMAKE_METHOD(MBH_PARTICLE) && (LevelArray[level+1] == NULL)) { + StarParticleCreation -= pow(2, MBH_PARTICLE); } /* ------------------------------------------------------- */ @@ -866,7 +898,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], * (b) correct for the difference between this grid's fluxes and the * subgrid's fluxes. (step #19) */ - + SUBlingList = new LevelHierarchyEntry*[NumberOfGrids]; #ifdef FAST_SIB CreateSUBlingList(MetaData, LevelArray, level, SiblingList, @@ -919,25 +951,25 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Recompute radiation field, if requested. */ RadiationFieldUpdate(LevelArray, level, MetaData); - + // //dcc cut second potential cut: Duplicate? - + // if (SelfGravity && WritePotential) { // CopyGravPotential = TRUE; // When = 0.0; - + // #ifdef FAST_SIB // PrepareDensityField(LevelArray, SiblingList, level, MetaData, When); // #else // !FAST_SIB // PrepareDensityField(LevelArray, level, MetaData, When); // #endif // end FAST_SIB - - + + // for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { // if (level <= MaximumGravityRefinementLevel) { - + // /* Compute the potential. */ - + // if (level > 0) // Grids[grid1]->GridData->SolveForPotential(level); // Grids[grid1]->GridData->CopyPotentialToBaryonField(); @@ -946,7 +978,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], // CopyGravPotential = FALSE; // } // if WritePotential - + /* Count up number of grids on this level. */ int GridMemory, NumberOfCells, CellsTotal, Particles; @@ -963,7 +995,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], /* Rebuild the Grids on the next level down. Don't bother on the last cycle, as we'll rebuild this grid soon. */ - + if (dtThisLevelSoFar[level] < dtLevelAbove) RebuildHierarchy(MetaData, LevelArray, level); @@ -973,25 +1005,25 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], if ((MetaData->StaticHierarchy == 0) && (level < MaximumRefinementLevel)) { LevelSubCycleCount[level+1] = 0; } - + } // end of loop over subcycles - + EXTRA_OUTPUT_MACRO(6, "After Subcycle Loop") if (debug) - fprintf(stdout, "EvolveLevel[%"ISYM"]: NumberOfSubCycles = %"ISYM" (%"ISYM" total, %"ISYM" sub)\n", + fprintf(stdout, "EvolveLevel[%"ISYM"]: NumberOfSubCycles = %"ISYM" (%"ISYM" total, %"ISYM" sub)\n", level, cycle, LevelCycleCount[level], LevelSubCycleCount[level]); - + /* If possible & desired, report on memory usage. */ - + ReportMemoryUsage("Memory usage report: Evolve Level"); - + #ifdef USE_LCAPERF lcaperf.attribute ("level",0,LCAPERF_NULL); #endif - + /* Clean up. */ - + delete [] NumberOfSubgrids; delete [] NumberOfNewActiveParticles; delete [] Grids; @@ -999,7 +1031,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], delete [] TotalStarParticleCountPrevious; dtThisLevel[level] = dtThisLevelSoFar[level] = 0.0; - + /* Clean up the sibling list. */ @@ -1018,5 +1050,5 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], } return SUCCESS; - + } diff --git a/src/enzo/GreensFunction.C b/src/enzo/GreensFunction.C new file mode 100644 index 000000000..23031c527 --- /dev/null +++ b/src/enzo/GreensFunction.C @@ -0,0 +1,498 @@ +#include +#include +#include +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "GreensFunction.h" + + +/* Set the number of interpolation points per two Pi stretch in the domain. */ +#define NUMBER_OF_POINTS_PER_TWOPI 20000 + +#define DONT_USE_LOCK +#define UNLOCKED 0 +#define LOCKED 1 + +static int GFLock = UNLOCKED; + + +/* function prototypes */ +void WriteListOfInts(FILE *fptr, int N, int nums[]); +int FastFourierTransform(float *buffer, int Rank, int DimensionReal[], + int Dimension[], int direction, int type); +int ComputeTable(float Min, float Max, float Step, float (*Function)(float), + float **Table, float *TableStep, float *TableMin, + float *TableMax); +extern "C" void FORTRAN_NAME(make_green)(float *green, + int *nx, int *ny, int *nz, + int *in, int *jn, int *kn, + int *nalias, + float *S2Part, int *refinement, + float *S2Table, float *S2Min, + float *S2Step, + float *SinTable, float *SinMin, + float *SinStep); + +/* Definitions of the greens_function class members */ +int greens_function::PrepareGreensFunction(int Rank, int RealDims[], int Dims[], + gravity_boundary_type BoundaryType, + int RefinementFactor) +{ + +#ifdef USE_LOCK + float a; + printf("entering GF_Prep:\n"); + while (GFLock == LOCKED) { + printf("+"); + for (int l = 0; l < 10000; l++) + a += pow(-1, l)*sin(l); + } + + GFLock = LOCKED; +#endif /* USE_LOCK */ + + int dim, i = -1, Match = FALSE; + + while (!Match && ++i < GreensFunctionMaxNumber) { + if (GFBoundary[i] == BoundaryType) { + Match = TRUE; + for (dim = 0; dim < Rank; dim++) + if (GFDimensions[i][dim] != Dims[dim]) + Match = FALSE; + } + } + + /* If found, we don't have to do any work. */ + + if (Match) { + GFInUse[i]++; + GreensFunctionThisGrid = GFFunction[i]; + GreensFunctionIndex = i; + GFLock = UNLOCKED; + return SUCCESS; + } + + /* Error check. */ + + if (GreensFunctionMaxNumber < 1) { + fprintf(stderr, "GreensFunctionMaxNumber must be > 1!\n"); + return FAIL; + } + + /* If not, we'll compute a new one and put it in the spot specified by + Index (wrapping the counter if necessary). */ + + if (GFIndex > GreensFunctionMaxNumber-1) + GFIndex = min(1, GreensFunctionMaxNumber-1); // set to 1 if possible + int nchecks = 0; + while (GFInUse[GFIndex] > 0 && nchecks++ < GreensFunctionMaxNumber) + GFIndex = (GFIndex+1) % GreensFunctionMaxNumber; + if (nchecks == GreensFunctionMaxNumber) { + fprintf(stderr, "GF: no empty GreensFunction.\n"); + return FAIL; + } + + /* Add one to index and set boundary to undefined so nobody uses or over- + runs this spot. */ + + int ThisGF = GFIndex++; + GFBoundary[ThisGF] = GravityUndefined; + GFInUse[ThisGF] = 1; + + /* If the spot is already being used, delete the old stuff. */ + + if (GFFunction[ThisGF] != NULL) { + delete GFFunction[ThisGF]; + GFTotalSize -= GFFunctionSize[ThisGF]; // reduce size by this amount + if (debug) { + printf("GreensFunction: deleting GF[%d] with dims ", ThisGF); + WriteListOfInts(stdout, Rank, GFDimensions[ThisGF]); + } + } + + /* Fill in the new spot. */ + + int size = RealDims[0]/2 + 1; + for (dim = 0; dim < Rank; dim++) { + GFDimensions[ThisGF][dim] = Dims[dim]; + if (dim > 0) + size *= RealDims[dim]; + } + GFFunctionSize[ThisGF] = size; + GFTotalSize += size; + GFFunction[ThisGF] = new float[size]; // allocate space for G.F. + if (debug) { + printf("GreensFunction: creating GF[%d] with dims ", ThisGF, size); + WriteListOfInts(stdout, Rank, Dims); + } + if (GFFunction[ThisGF] == NULL) { + fprintf(stderr, "malloc error (out of memory?)\n"); + return FAIL; + } + + /* Create the field */ + + if (BoundaryType == TopGridIsolated) { + fprintf(stderr, "isolated gravity is not supported.\n"); + return FAIL; + // if (MakeGreensFunctionTopGridIsolated(Rank, RealDims, Dims, + // GFFunction[ThisGF]) == FAIL) { + // fprintf(stderr, "Error in MakeGreensFunctionTopGridIsolated.\n"); + // return FAIL; + // } + } + else + if (MakeGreensFunction(Rank, RealDims, Dims, GFFunction[ThisGF], + BoundaryType, RefinementFactor) == FAIL) { + fprintf(stderr, "Error in MakeGreensFunction.\n"); + return FAIL; + } + + /* Set the pointer to the new function. */ + + GreensFunctionThisGrid = GFFunction[ThisGF]; + GreensFunctionIndex = ThisGF; + + /* Set the boundary type only when done. */ + + GFBoundary[ThisGF] = BoundaryType; + + if (debug) + printf("GreensFunction: finished creating GF[%d].\n", ThisGF); + +#ifdef USE_LOCK + GFLock = UNLOCKED; +#endif /* USE_LOCK */ + return SUCCESS; +} + + +int greens_function::MultiplyGreensFunction(int Rank, int RealDims[], + int Dims[], float *field) +{ + + int i, j, k, dim, fieldindex, greenindex; + + /* Find the appropriate Greens' function. If it's not present, that's + an error! */ + + if (GreensFunctionThisGrid == NULL) { + fprintf(stderr, "Green's Function not found!\n"); + return FAIL; + } + + /* Copy Dims to FullDims and set unused indexes. */ + + int FullDims[MAX_DIMENSION], FullRealDims[MAX_DIMENSION]; + + for (dim = 0; dim < Rank; dim++) { + FullDims[dim] = Dims[dim]; + FullRealDims[dim] = RealDims[dim]; + } + for (dim = Rank; dim < MAX_DIMENSION; dim++) { + FullDims[dim] = 1; + FullRealDims[dim] = 1; + } + + int nxmid = FullDims[0]/2 + 1; + + /* Multiply the fields. */ + + for (k = 0; k < FullDims[2]; k++) + for (j = 0; j < FullDims[1]; j++) { + fieldindex = (k*FullRealDims[1] + j)*FullRealDims[0]; + greenindex = (k*FullRealDims[1] + j)*nxmid; + for (i = 0; i < FullDims[0]/2+1; i++, greenindex++) { + + field[fieldindex++] *= GreensFunctionThisGrid[greenindex]; + field[fieldindex++] *= GreensFunctionThisGrid[greenindex]; + + } + } // end of loop over grids + + return SUCCESS; +} + + +int greens_function::ComputeAcceleration(int Rank, int RealDims[], int Dims[], + int Direction, float *Potential, + float *AccelerationField, + float CellWidth) +{ + + /* Copy Dims to FullDims and set unused indexes. */ + + int dim, FullDims[MAX_DIMENSION], FullRealDims[MAX_DIMENSION]; + const float Pi = 3.14159; + + for (dim = 0; dim < Rank; dim++) { + FullDims[dim] = Dims[dim]; + FullRealDims[dim] = RealDims[dim]; + } + for (dim = Rank; dim < MAX_DIMENSION; dim++) { + FullDims[dim] = 1; + FullRealDims[dim] = 1; + } + + /* Error check. */ + + if (FullDims[0]+2 != FullRealDims[0] || FullDims[1] != FullRealDims[1]) { + fprintf(stderr, "FullDims assumption failed!\n"); + return FAIL; + } + + /* Divide by CellWidth to get the acceleration units right. */ + + float factor = 2.0*Pi/float(FullDims[Direction])/CellWidth * + GravityResolution*GravityResolution*GravityResolution; + +#ifdef USE_FORTRAN + + /* Call fortran routine to do the real work. */ + + FORTRAN_NAME(mult_pot)(FullDims, FullDims+1, FullDims+2, &Direction, + AccelerationField, Potential, &factor); + +#else /* USE_FORTRAN */ + + int i, j, k, n, index = 0; + float kvalue; + + /* (i) Direction. */ + + if (Direction == 0) + for (k = 0; k < FullDims[2]; k++) + for (j = 0; j < FullDims[1]; j++) + for (i = 0; i < FullDims[0]/2+1; i++, index += 2) { + + /* Compute k. */ + + kvalue = float(i)*factor; + + /* Multiply potential by -ik. */ + + AccelerationField[index ] = Potential[index+1] * kvalue; + AccelerationField[index+1] = -Potential[index ] * kvalue; + + } + + /* (j/k) Direction. */ + + if (Direction == 1 || Direction == 2) + for (k = 0; k < FullDims[2]; k++) + for (j = 0; j < FullDims[1]; j++) { + + /* Compute k. */ + + if (Direction == 1) n = j; + if (Direction == 2) n = k; + if (n > FullDims[Direction]/2) + n -= FullDims[Direction]; + kvalue = float(n)*factor; + + /* Multiply potential by -ik. */ + + for (i = 0; i < FullDims[0]/2+1; i++, index += 2) { + + AccelerationField[index ] = Potential[index+1] * kvalue; + AccelerationField[index+1] = -Potential[index ] * kvalue; + + } + + } + +#endif /* USE_FORTRAN */ + + return SUCCESS; +} + + +void greens_function::Release() +{ + GFInUse[GreensFunctionIndex]--; +}; + + +/* Free functions and parameters definitions */ +/* S2 Particle Table values. */ +static float S2TableStep = 0.0; +static float *S2Table = NULL; +static float S2TableMin = 0.0; +static float S2TableMax = 0.0; + +/* Sin Table values. */ +static float SinTableStep = 0.0; +static float *SinTable = NULL; +static float SinTableMin = 0.0; +static float SinTableMax = 0.0; + + +int MakeGreensFunction(int Rank, int RealDims[], int Dims[], float *Function, + gravity_boundary_type BoundaryType, int RefinementFactor) +{ + +#ifdef USE_LOCK + float a; + while (GFLock == LOCKED) { + if (debug) printf("+"); + for (int l = 0; l < 10000; l++) + a += pow(-1, l)*sin(l); + } + + GFLock = LOCKED; +#endif /* USE_LOCK */ + + /* declarations */ + + int dim, FullDims[MAX_DIMENSION], FullRealDims[MAX_DIMENSION]; + + /* Error check. */ + +/* if (Rank == 2) { + fprintf(stderr, "MakeGreen: Rank == 2 not supported.\n"); + return FAIL; + } */ + + if (BoundaryType == TopGridIsolated) { + fprintf(stderr, "BoundaryType %d not supported.\n", BoundaryType); + return FAIL; + } + + if (BoundaryType == TopGridPeriodic && RefinementFactor != 1) { + fprintf(stderr, "RefinementFactor %d incompatable with TopGridPeriodic.\n", + RefinementFactor); + return FAIL; + } + + if (BoundaryType == SubGridIsolated && RefinementFactor <= 1) { + fprintf(stderr, "RefinementFactor %d incompatable with SubgridIsolated.\n", + RefinementFactor); + return FAIL; + } + + /* Copy Dims to FullDims and set unused indexes. */ + + for (dim = 0; dim < Rank; dim++) { + FullDims[dim] = Dims[dim]; + FullRealDims[dim] = RealDims[dim]; + } + for (dim = Rank; dim < MAX_DIMENSION; dim++) { + FullDims[dim] = 1; + FullRealDims[dim] = 1; + } + + /* Set some constants. */ + + const float Pi = 3.14159; + int nalias = NUMBER_IN_ALIAS_SUM; + + /* Precompute the S2 particle shape look up table. */ + + float MinimumStep = 2*Pi/NUMBER_OF_POINTS_PER_TWOPI; + float MinValue = MinimumStep*0.1; + float MaxValue = (sqrt((float(nalias)+0.5)*(float(nalias)+0.5) + + (float(nalias)+0.5)*(float(nalias)+0.5) + + (float(nalias)+0.5)*(float(nalias)+0.5) ) + 0.1) + *2*Pi*S2ParticleSize*0.5*float(RefinementFactor); + + float (*S2Function)(float); + if (Rank == 1) S2Function = &S2Function1D; + if (Rank == 2) S2Function = &S2Function2D; + if (Rank == 3) S2Function = &S2Function3D; + + if (ComputeTable(MinValue, MaxValue, MinimumStep, S2Function, + &S2Table, &S2TableStep, &S2TableMin, &S2TableMax) + == FAIL) { + fprintf(stderr, "Error in ComputeTable (S2Table).\n"); + return FAIL; + } + + /* Precompute the sin function look up table. */ + + MinimumStep = 2*Pi/NUMBER_OF_POINTS_PER_TWOPI; + MinValue = -(2.1 + float(nalias))*Pi; + MaxValue = (2.1 + float(nalias))*Pi; + + if (ComputeTable(MinValue, MaxValue, MinimumStep, &FloatSin, + &SinTable, &SinTableStep, &SinTableMin, &SinTableMax) + == FAIL) { + fprintf(stderr, "Error in ComputeTable (SinTable).\n"); + return FAIL; + } + + /* Call fortran function to compute Green's function. */ + + FORTRAN_NAME(make_green)(Function, FullDims, FullDims+1, FullDims+2, + FullRealDims, FullRealDims+1, FullRealDims+2, + &nalias, &S2ParticleSize, &RefinementFactor, + S2Table, &S2TableMin, &S2TableStep, + SinTable, &SinTableMin, &SinTableStep); + +/* #define UNUSED */ +#ifdef UNUSED + + /* Check to see what this looks like in the real domain. */ + + int i, j, k, size = 1, nxmid = FullDims[0]/2 + 1; + for (dim = 0; dim < Rank; dim++) + size *= FullRealDims[dim]; + + float *test = new float[size]; + + for (k = 0; k < FullDims[2]; k++) + for (j = 0; j < FullDims[1]; j++) + for (i = 0; i < nxmid; i++) { + *(test + k*FullRealDims[0]*FullRealDims[1] + + j*FullRealDims[0] + i*2) = + *(Function + k*nxmid*FullRealDims[1] + j*nxmid + i); + *(test + k*FullRealDims[0]*FullRealDims[1] + + j*FullRealDims[0] + i*2+1) = 0; + } + + FastFourierTransform(test, Rank, FullRealDims, FullDims, FFT_INVERSE, REAL_TO_COMPLEX); + + if (BoundaryType == SubGridIsolated) { + FILE *fptr = fopen("Green.out","w"); + for (k = 0; k < FullDims[2]; k++) + for (j = 0; j < FullDims[1]; j++) + for (i = 0; i < FullDims[0]; i++) + fprintf(fptr, "%e\n", *(test + k*FullRealDims[0]*FullRealDims[1] + + j*FullRealDims[0] + i)); + fclose(fptr); + } + + delete test; + +#endif /* UNUSED */ + +#ifdef USE_LOCK + GFLock = UNLOCKED; +#endif /* USE_LOCK */ + + return SUCCESS; +} + + +float S2Function1D(float keta2) +{ + return 2.0 / (keta2*keta2) * (1 - cos(keta2)); +} + + +float S2Function2D(float keta2) +{ + return 12.0 / pow(keta2, 4) * (2 - 2*cos(keta2) - keta2*sin(keta2)); +} + + +float S2Function3D(float keta2) +{ + return 12.0 / pow(keta2, 4) * (2 - 2*cos(keta2) - keta2*sin(keta2)); +} + + +float FloatSin(float x) +{ + return float(sin(double(x))); +} diff --git a/src/enzo/GreensFunction.h b/src/enzo/GreensFunction.h new file mode 100644 index 000000000..959f34017 --- /dev/null +++ b/src/enzo/GreensFunction.h @@ -0,0 +1,88 @@ +/*********************************************************************** +/ +/ GREENS FUNCTION CLASS +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ +/ modified1: Jean-Claude Passy +/ date: May, 2018 +/ +/ PURPOSE: +/ +************************************************************************/ +#ifndef GREENS_FUNCTION_H +#define GREENS_FUNCTION_H + +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "TopGridData.h" + +#ifdef DEFINE_STORAGE +# define EXTERN +#else /* DEFINE_STORAGE */ +# define EXTERN extern +#endif /* DEFINE_STORAGE */ + +EXTERN int GFAlreadyInitialized; // Used for initializing +EXTERN int GFDimensions[MAX_NUMBER_OF_GREENS_FUNCTIONS][MAX_DIMENSION]; +EXTERN gravity_boundary_type GFBoundary[MAX_NUMBER_OF_GREENS_FUNCTIONS]; +EXTERN float *GFFunction[MAX_NUMBER_OF_GREENS_FUNCTIONS]; +EXTERN int GFInUse[MAX_NUMBER_OF_GREENS_FUNCTIONS]; +EXTERN int GFFunctionSize[MAX_NUMBER_OF_GREENS_FUNCTIONS]; // size in floats +EXTERN int GFIndex; // index for the next GF +EXTERN int GFTotalSize; // total number of floats used + + +//! Class representing a Greens function. +class greens_function +{ + private: + + float *GreensFunctionThisGrid; // pointer for this grid. + int GreensFunctionIndex; + + public: + + //! Prepare the Greens functions + int PrepareGreensFunction(int Rank, int RealDims[], int Dims[], + gravity_boundary_type BoundaryType, + int RefinementFactor); + + + //! Multiplies the given (complex k-space) field with the appropriate G.F. + int MultiplyGreensFunction(int Rank, int RealDims[], int Dims[], float *field); + + + //! Compute the acceleration field over the k-space potential by multipling + //! with D(k). The result goes in AccelerationField. */ + int ComputeAcceleration(int Rank, int RealDims[], int Dims[], int Direction, + float *Potential, float *AccelerationField, + float CellWidth); + + + //! Release a Greens function + void Release(); +}; + + +//! Build Greens function +int MakeGreensFunction(int Rank, int RealDims[], int Dims[], float *Function, + gravity_boundary_type BoundaryType, + int RefinementFactor); + +//! S2 Particle functions. Note: 2D is NOT!!! correct. +//! It should be a generalized hypergeometric function. +float S2Function1D(float keta2); +float S2Function2D(float keta2); +float S2Function3D(float keta2); +float FloatSin(float x); // Sin function: float version. Sometimes, C sucks. + + +#endif /* GREENS_FUNCTION_H */ + + + + + diff --git a/src/enzo/Grid.h b/src/enzo/Grid.h index 80c06572c..a33635126 100644 --- a/src/enzo/Grid.h +++ b/src/enzo/Grid.h @@ -23,6 +23,7 @@ #include "FOF_allvars.h" #include "MemoryPool.h" #include "hydro_rk/SuperNova.h" +#include "GreensFunction.h" #ifdef ECUDA #include "hydro_rk/CudaMHD.h" #endif @@ -60,9 +61,6 @@ struct HierarchyEntry; // int Type; //}; - - - extern int CommunicationDirection; int FindField(int f, int farray[], int n); struct LevelHierarchyEntry; @@ -72,40 +70,40 @@ class ActiveParticle_AccretingParticle; class grid { #ifdef NEW_PROBLEM_TYPES - protected: +protected: #else - private: +private: #endif -// -// General grid class data -// - int GridRank; // number of dimensions - int GridDimension[MAX_DIMENSION]; // total dimensions of all grids - int GridStartIndex[MAX_DIMENSION]; // starting index of the active region - // (zero based) - int GridEndIndex[MAX_DIMENSION]; // stoping index of the active region - // (zero based) - FLOAT GridLeftEdge[MAX_DIMENSION]; // starting pos (active problem space) - FLOAT GridRightEdge[MAX_DIMENSION]; // ending pos (active problem space) - int GridLevel; // hierarchy level where this grid lives - float dtFixed; // current (fixed) timestep - FLOAT Time; // current problem time - FLOAT OldTime; // time corresponding to OldBaryonField - int SubgridsAreStatic; // - int ID; // Grid ID Number - int sfSeed; -// -// Baryon grid data -// - int NumberOfBaryonFields; // active baryon fields - float *BaryonField[MAX_NUMBER_OF_BARYON_FIELDS]; // pointers to arrays - float *OldBaryonField[MAX_NUMBER_OF_BARYON_FIELDS]; // pointers to old arrays + // + // General grid class data + // + int GridRank; // number of dimensions + int GridDimension[MAX_DIMENSION]; // total dimensions of all grids + int GridStartIndex[MAX_DIMENSION]; // starting index of the active region + // (zero based) + int GridEndIndex[MAX_DIMENSION]; // stoping index of the active region + // (zero based) + FLOAT GridLeftEdge[MAX_DIMENSION]; // starting pos (active problem space) + FLOAT GridRightEdge[MAX_DIMENSION]; // ending pos (active problem space) + int GridLevel; // hierarchy level where this grid lives + float dtFixed; // current (fixed) timestep + FLOAT Time; // current problem time + FLOAT OldTime; // time corresponding to OldBaryonField + int SubgridsAreStatic; // + int ID; // Grid ID Number + int sfSeed; + // + // Baryon grid data + // + int NumberOfBaryonFields; // active baryon fields + float *BaryonField[MAX_NUMBER_OF_BARYON_FIELDS]; // pointers to arrays + float *OldBaryonField[MAX_NUMBER_OF_BARYON_FIELDS]; // pointers to old arrays float *InterpolatedField[MAX_NUMBER_OF_BARYON_FIELDS]; // For RT and movies - float *RandomForcingField[MAX_DIMENSION]; // pointers to arrays //AK - int FieldType[MAX_NUMBER_OF_BARYON_FIELDS]; + float *RandomForcingField[MAX_DIMENSION]; // pointers to arrays //AK + int FieldType[MAX_NUMBER_OF_BARYON_FIELDS]; FLOAT *CellLeftEdge[MAX_DIMENSION]; FLOAT *CellWidth[MAX_DIMENSION]; - float grid_BoundaryMassFluxContainer[MAX_NUMBER_OF_BARYON_FIELDS]; // locally stores mass flux across domain boundary + float grid_BoundaryMassFluxContainer[MAX_NUMBER_OF_BARYON_FIELDS]; // locally stores mass flux across domain boundary fluxes *BoundaryFluxes; // For restart dumps @@ -113,32 +111,32 @@ class grid int NumberOfSubgrids; fluxes **SubgridFluxStorage; - float CourantSafetyNumber; // Hydro parameter - int PPMFlatteningParameter; // PPM parameter - int PPMDiffusionParameter; // PPM parameter - int PPMSteepeningParameter; // PPM parameter -// -// Particle data -// - int NumberOfParticles; - FLOAT *ParticlePosition[MAX_DIMENSION]; // pointers to position arrays - float *ParticleVelocity[MAX_DIMENSION]; // pointers to velocity arrays - float *ParticleAcceleration[MAX_DIMENSION+1]; // - float *ParticleMass; // pointer to mass array - PINT *ParticleNumber; // unique identifier - int *ParticleType; // type of particle + float CourantSafetyNumber; // Hydro parameter + int PPMFlatteningParameter; // PPM parameter + int PPMDiffusionParameter; // PPM parameter + int PPMSteepeningParameter; // PPM parameter + // + // Particle data + // + int NumberOfParticles; + FLOAT *ParticlePosition[MAX_DIMENSION]; // pointers to position arrays + float *ParticleVelocity[MAX_DIMENSION]; // pointers to velocity arrays + float *ParticleAcceleration[MAX_DIMENSION + 1]; // + float *ParticleMass; // pointer to mass array + PINT *ParticleNumber; // unique identifier + int *ParticleType; // type of particle float *ParticleAttribute[MAX_NUMBER_OF_PARTICLE_ATTRIBUTES]; -// -// Star particle data -// + // + // Star particle data + // int NumberOfStars; Star *Stars; // -// Active particle data -// - float* ActiveParticleAcceleration[MAX_DIMENSION+1]; + // Active particle data + // + float *ActiveParticleAcceleration[MAX_DIMENSION + 1]; int NumberOfActiveParticles; ActiveParticleList ActiveParticles; // At present this is synched up in CommunicationSyncNumberOfParticles. @@ -146,44 +144,47 @@ class grid // NumberOfActiveParticles are. int ActiveParticleTypeCount[MAX_ACTIVE_PARTICLE_TYPES]; -// For once-per-rootgrid-timestep star formation, the following flag -// determines whether SF is about to occur or not. It's currently -//(April 2012) only implemented for H2REG_STAR and completely -// ignored for all other star makers. + // For once-per-rootgrid-timestep star formation, the following flag + // determines whether SF is about to occur or not. It's currently + //(April 2012) only implemented for H2REG_STAR and completely + // ignored for all other star makers. int MakeStars; -// -// Gravity data -// + // + // Gravity data + // float *PotentialField; float *AccelerationField[MAX_DIMENSION]; // cell cntr acceleration at n+1/2 float *GravitatingMassField; - FLOAT GravitatingMassFieldLeftEdge[MAX_DIMENSION]; - int GravitatingMassFieldDimension[MAX_DIMENSION]; - FLOAT GravitatingMassFieldCellSize; // all dimensions must be the same - float *GravitatingMassFieldParticles; // for particles only - FLOAT GravitatingMassFieldParticlesLeftEdge[MAX_DIMENSION]; - FLOAT GravitatingMassFieldParticlesCellSize; - int GravitatingMassFieldParticlesDimension[MAX_DIMENSION]; + FLOAT GravitatingMassFieldLeftEdge[MAX_DIMENSION]; + int GravitatingMassFieldDimension[MAX_DIMENSION]; + FLOAT GravitatingMassFieldCellSize; // all dimensions must be the same + float *GravitatingMassFieldParticles; // for particles only + FLOAT GravitatingMassFieldParticlesLeftEdge[MAX_DIMENSION]; + FLOAT GravitatingMassFieldParticlesCellSize; + int GravitatingMassFieldParticlesDimension[MAX_DIMENSION]; gravity_boundary_type GravityBoundaryType; - float PotentialSum; + float PotentialSum; + // For APM solver + greens_function GreensFunction; + float *AccelerationFieldExternalAPM[MAX_DIMENSION]; // external acceleration for APM solver // // WS: total energy injection by stochastic forcing // - float* EnergyInjection; + float *EnergyInjection; // // WS: Initial phase factors and multiplicators for stochastic forcing // - float* PhaseFctInitEven; - float* PhaseFctInitOdd; - float* PhaseFctMultEven[MAX_DIMENSION]; - float* PhaseFctMultOdd[MAX_DIMENSION]; + float *PhaseFctInitEven; + float *PhaseFctInitOdd; + float *PhaseFctMultEven[MAX_DIMENSION]; + float *PhaseFctMultOdd[MAX_DIMENSION]; -// -// Top grid parallelism (for implicit solvers) -// + // + // Top grid parallelism (for implicit solvers) + // int ProcLayout[MAX_DIMENSION]; int ProcLocation[MAX_DIMENSION]; int ProcNeighbors[MAX_DIMENSION][2]; @@ -193,30 +194,30 @@ class grid #ifdef TRANSFER float MaxRadiationDt; #endif -// -// Rebuild Hierarchy Temporaries -// - int *FlaggingField; // Boolean flagging field (for refinement) + // + // Rebuild Hierarchy Temporaries + // + int *FlaggingField; // Boolean flagging field (for refinement) float *MassFlaggingField; // Used by mass flagging criteria float *ParticleMassFlaggingField; // Used by particle mass flagging criteria -// -// Parallel Information -// + // + // Parallel Information + // int ProcessorNumber; -// -// Movie Data Format -// - int TimestepsSinceCreation; // Not really since creation anymore... - // resets everytime the grid outputs + // + // Movie Data Format + // + int TimestepsSinceCreation; // Not really since creation anymore... + // resets everytime the grid outputs -// density and pressure history for one-zone collapse -// for calculating effective gamma + // density and pressure history for one-zone collapse + // for calculating effective gamma float **freefall_density; float **freefall_pressure; -// -// Friends -// + // + // Friends + // friend int ExternalBoundary::Prepare(grid *TopGrid); friend int ProtoSubgrid::CopyFlaggedZonesFromGrid(grid *Grid); friend class Star; @@ -240,212 +241,216 @@ class grid #endif #ifdef ECUDA -// -// CUDA MHD solver data -// + // + // CUDA MHD solver data + // cuMHDData MHDData; #endif +public: + // ------------------------------------------------------------------------- + // Main hydro/AMR functions + // - public: - -// ------------------------------------------------------------------------- -// Main hydro/AMR functions -// - -/* Grid constructor (Set all data to null/default state). */ + /* Grid constructor (Set all data to null/default state). */ - grid(); + grid(); -/* Grid deconstructor (free up memory usage) */ + /* Grid deconstructor (free up memory usage) */ - ~grid(); + ~grid(); -/* Read grid data from a file (returns: success/failure) */ + /* Read grid data from a file (returns: success/failure) */ - int ReadGrid(FILE *main_file_pointer, int GridID, char DataFilename[], - int ReadText = TRUE, int ReadData = TRUE); + int ReadGrid(FILE *main_file_pointer, int GridID, char DataFilename[], + int ReadText = TRUE, int ReadData = TRUE); -/* Read grid data from a group file (returns: success/failure) */ + /* Read grid data from a group file (returns: success/failure) */ #ifndef NEW_GRID_IO - int Group_ReadGrid(FILE *fptr, int GridID, HDF5_hid_t file_id, - char DataFilename[], - int ReadText, int ReadData, bool ReadParticlesOnly=false); + int Group_ReadGrid(FILE *fptr, int GridID, HDF5_hid_t file_id, + char DataFilename[], + int ReadText, int ReadData, bool ReadParticlesOnly = false); #else - int Group_ReadGrid(FILE *main_file_pointer, int GridID, HDF5_hid_t file_id, - char DataFilename[], - int ReadText = TRUE, int ReadData = TRUE, - bool ReadParticlesOnly=false, int ReadEverything = FALSE); + int Group_ReadGrid(FILE *main_file_pointer, int GridID, HDF5_hid_t file_id, + char DataFilename[], + int ReadText = TRUE, int ReadData = TRUE, + bool ReadParticlesOnly = false, int ReadEverything = FALSE); #endif - -/* Get field or particle data based on name or integer + + /* Get field or particle data based on name or integer defined in typedefs.h. Details are in Grid_CreateFieldArray.C. */ - EnzoArrayBool *CreateFieldArrayBool(field_type field); - EnzoArrayBool *CreateFieldArrayBool(char *field_name); + EnzoArrayBool *CreateFieldArrayBool(field_type field); + EnzoArrayBool *CreateFieldArrayBool(char *field_name); + + EnzoArrayInt *CreateFieldArrayInt(field_type field); + EnzoArrayInt *CreateFieldArrayInt(char *field_name); - EnzoArrayInt *CreateFieldArrayInt(field_type field); - EnzoArrayInt *CreateFieldArrayInt(char *field_name); - - EnzoArrayFloat *CreateFieldArrayFloat(field_type field); - EnzoArrayFloat *CreateFieldArrayFloat(char *field_name); - - EnzoArrayFLOAT *CreateFieldArrayFLOAT(field_type field); - EnzoArrayFLOAT *CreateFieldArrayFLOAT(char *field_name); + EnzoArrayFloat *CreateFieldArrayFloat(field_type field); + EnzoArrayFloat *CreateFieldArrayFloat(char *field_name); - EnzoArrayPINT *CreateFieldArrayPINT(field_type field); - EnzoArrayPINT *CreateFieldArrayPINT(char *field_name); + EnzoArrayFLOAT *CreateFieldArrayFLOAT(field_type field); + EnzoArrayFLOAT *CreateFieldArrayFLOAT(char *field_name); -/* Write unigrid cubes to a file (returns: success/failure) */ + EnzoArrayPINT *CreateFieldArrayPINT(field_type field); + EnzoArrayPINT *CreateFieldArrayPINT(char *field_name); - int WriteCube(char *base_name, int grid_id, int TGdims[]); + /* Write unigrid cubes to a file (returns: success/failure) */ -/* Write grid data to a file (returns: success/failure) */ + int WriteCube(char *base_name, int grid_id, int TGdims[]); - int WriteGrid(FILE *main_file_pointer, char *base_name, int grid_id); + /* Write grid data to a file (returns: success/failure) */ -/* Write grid data to a group file (returns: success/failure) */ + int WriteGrid(FILE *main_file_pointer, char *base_name, int grid_id); + + /* Write grid data to a group file (returns: success/failure) */ #ifndef NEW_GRID_IO - int Group_WriteGrid(FILE *fptr, char *base_name, int grid_id, HDF5_hid_t file_id); + int Group_WriteGrid(FILE *fptr, char *base_name, int grid_id, HDF5_hid_t file_id); #else - int Group_WriteGrid(FILE *main_file_pointer, char *base_name, int grid_id, HDF5_hid_t file_id, int WriteEverything = FALSE); + int Group_WriteGrid(FILE *main_file_pointer, char *base_name, int grid_id, HDF5_hid_t file_id, int WriteEverything = FALSE); #endif - int WriteAllFluxes(hid_t grid_node); - int WriteFluxGroup(hid_t top_group, fluxes *fluxgroup); + int WriteAllFluxes(hid_t grid_node); + int WriteFluxGroup(hid_t top_group, fluxes *fluxgroup); - int ReadAllFluxes(hid_t grid_node); - int ReadFluxGroup(hid_t top_group, fluxes *fluxgroup); + int ReadAllFluxes(hid_t grid_node); + int ReadFluxGroup(hid_t top_group, fluxes *fluxgroup); - int FillFluxesFromStorage(int *ThisNumberOfSubgrids, - fluxes ***fluxgroup) { - *ThisNumberOfSubgrids = this->NumberOfSubgrids; - *fluxgroup = this->SubgridFluxStorage; - this->SubgridFluxStorage = NULL; - if(ProcessorNumber != MyProcessorNumber) return -1; - return 0; - } - -/* Routines for writing/reading grid hierarchy information to/from + int FillFluxesFromStorage(int *ThisNumberOfSubgrids, + fluxes ***fluxgroup) + { + *ThisNumberOfSubgrids = this->NumberOfSubgrids; + *fluxgroup = this->SubgridFluxStorage; + this->SubgridFluxStorage = NULL; + if (ProcessorNumber != MyProcessorNumber) + return -1; + return 0; + } + + /* Routines for writing/reading grid hierarchy information to/from HDF5 hierarchy file */ - int WriteHierarchyInformationHDF5(char *base_name, hid_t level_group_id, int level, int ParentGridIDs[], int NumberOfDaughterGrids, int DaughterGridIDs[], int NextGridThisLevelID, int NextGridNextLevelID, FILE *log_fptr); - - int ReadHierarchyInformationHDF5(hid_t Hfile_id, int GridID, int &Task, int &NextGridThisLevelID, int &NextGridNextLevelID, char DataFilename[], FILE *log_fptr); + int WriteHierarchyInformationHDF5(char *base_name, hid_t level_group_id, int level, int ParentGridIDs[], int NumberOfDaughterGrids, int DaughterGridIDs[], int NextGridThisLevelID, int NextGridNextLevelID, FILE *log_fptr); + int ReadHierarchyInformationHDF5(hid_t Hfile_id, int GridID, int &Task, int &NextGridThisLevelID, int &NextGridNextLevelID, char DataFilename[], FILE *log_fptr); -/* Write grid data to separate files (returns: success/failure) */ + /* Write grid data to separate files (returns: success/failure) */ - int WriteGridX(FILE *main_file_pointer, char *base_name, int grid_id); + int WriteGridX(FILE *main_file_pointer, char *base_name, int grid_id); -/* Write task memory map */ + /* Write task memory map */ - int WriteMemoryMap(FILE *file_pointer, char *base_name, int grid_id); + int WriteMemoryMap(FILE *file_pointer, char *base_name, int grid_id); -/* Write grid-to-task map */ + /* Write grid-to-task map */ - int WriteTaskMap(FILE *file_pointer, char *base_name, int grid_id); + int WriteTaskMap(FILE *file_pointer, char *base_name, int grid_id); -/* Write grid hierarchy only */ + /* Write grid hierarchy only */ - int WriteStuff(FILE *main_file_pointer, char *base_name, int grid_id); + int WriteStuff(FILE *main_file_pointer, char *base_name, int grid_id); -/* Interpolate to specified time and write unigrid cube data to a file + /* Interpolate to specified time and write unigrid cube data to a file (returns: success/failure). */ - int WriteCubeInterpolate(FLOAT WriteTime, char *base_name, int grid_id, int TGdims[]); + int WriteCubeInterpolate(FLOAT WriteTime, char *base_name, int grid_id, int TGdims[]); -/* Interpolate to specified time and write grid data to a file + /* Interpolate to specified time and write grid data to a file (returns: success/failure). */ - int WriteGridInterpolate(FLOAT WriteTime, FILE *main_file_pointer, - char *base_name, int grid_id); + int WriteGridInterpolate(FLOAT WriteTime, FILE *main_file_pointer, + char *base_name, int grid_id); -/* Interpolate to specified time and write grid data to a group file + /* Interpolate to specified time and write grid data to a group file (returns: success/failure). */ - int Group_WriteGridInterpolate(FLOAT WriteTime, FILE *main_file_pointer, - char *base_name, int grid_id, HDF5_hid_t file_id); + int Group_WriteGridInterpolate(FLOAT WriteTime, FILE *main_file_pointer, + char *base_name, int grid_id, HDF5_hid_t file_id); - int ComputeVectorAnalysisFields(field_type fx, field_type fy, field_type fz, - float* &curl_x, float* &curl_y, float* &curl_z, - float* &div); + int ComputeVectorAnalysisFields(field_type fx, field_type fy, field_type fz, + float *&curl_x, float *&curl_y, float *&curl_z, + float *&div); private: - int write_dataset(int ndims, hsize_t *dims, const char *name, hid_t group, - hid_t data_type, void *data, int active_only = TRUE, - float *temp=NULL, int *grid_start_index=NULL, int *grid_end_index=NULL, - int *active_dims=NULL, int *data_dims=NULL); - int read_dataset(int ndims, hsize_t *dims, const char *name, hid_t group, - hid_t data_type, void *read_to, int copy_back_active=FALSE, - float *copy_to=NULL, int *active_dims=NULL, int *grid_start_index=NULL, - int *grid_end_index=NULL, int *data_dims=NULL); - int ReadExtraFields(hid_t group_id); -public: + int write_dataset(int ndims, hsize_t *dims, const char *name, hid_t group, + hid_t data_type, void *data, int active_only = TRUE, + float *temp = NULL, int *grid_start_index = NULL, int *grid_end_index = NULL, + int *active_dims = NULL, int *data_dims = NULL); + int read_dataset(int ndims, hsize_t *dims, const char *name, hid_t group, + hid_t data_type, void *read_to, int copy_back_active = FALSE, + float *copy_to = NULL, int *active_dims = NULL, int *grid_start_index = NULL, + int *grid_end_index = NULL, int *data_dims = NULL); + int ReadExtraFields(hid_t group_id); -/* Compute the timestep constraint for this grid +public: + /* Compute the timestep constraint for this grid (for steps #3 and #4) */ - float ComputeTimeStep(); + float ComputeTimeStep(); -/* Set the timestep in this grid to the timestep in the argument + /* Set the timestep in this grid to the timestep in the argument (for step #3) */ - void SetTimeStep(float dt) {dtFixed = dt;}; + void SetTimeStep(float dt) { dtFixed = dt; }; -/* Check timestep (dtFixed) against argument (return fail if dtFixed > dt). + /* Check timestep (dtFixed) against argument (return fail if dtFixed > dt). (for step #4) */ - int CheckTimeStep(float dt) {return ((dtFixed > dt) ? FAIL : SUCCESS);}; + int CheckTimeStep(float dt) { return ((dtFixed > dt) ? FAIL : SUCCESS); }; -/* Return time, timestep */ + /* Return time, timestep */ - FLOAT ReturnTime() {return Time;}; - FLOAT ReturnOldTime() {return OldTime;}; - float ReturnTimeStep() {return dtFixed;}; + FLOAT ReturnTime() { return Time; }; + FLOAT ReturnOldTime() { return OldTime; }; + float ReturnTimeStep() { return dtFixed; }; /* Return, set grid ID */ void SetGridID(int id) { ID = id; }; int GetGridID(void) { return ID; }; - + /* Return, set level of this grid */ int GetLevel() { return GridLevel; }; - int SetLevel(int level) { - if (level >= 0) { - GridLevel=level; + int SetLevel(int level) + { + if (level >= 0) + { + GridLevel = level; return SUCCESS; - } else { + } + else + { return FAIL; } }; /* Baryons: return field types. */ - int ReturnFieldType(int type[]) + int ReturnFieldType(int type[]) { - for (int i = 0; i < NumberOfBaryonFields; i++) type[i] = FieldType[i]; + for (int i = 0; i < NumberOfBaryonFields; i++) + type[i] = FieldType[i]; return SUCCESS; }; -/* Baryons: Interpolate (parental) grid in argument to current grid. + /* Baryons: Interpolate (parental) grid in argument to current grid. (returns success or fail). (for step #16) */ - int InterpolateBoundaryFromParent(grid *ParentGrid); + int InterpolateBoundaryFromParent(grid *ParentGrid); -/* Member functions for dealing with thermal conduction */ - int ComputeHeat(float dedt[]); /* Compute Heat */ - int ConductHeat(); /* Conduct Heat */ - float ComputeConductionTimeStep(float &dt); /* Estimate conduction time-step */ + /* Member functions for dealing with thermal conduction */ + int ComputeHeat(float dedt[]); /* Compute Heat */ + int ConductHeat(); /* Conduct Heat */ + float ComputeConductionTimeStep(float &dt); /* Estimate conduction time-step */ -/* FDM: functions for lightboson dark matter */ + /* FDM: functions for lightboson dark matter */ int ComputeQuantumTimeStep(float &dt); /* Estimate quantum time-step */ - /* Solver for Schrodinger Equation */ - int SchrodingerSolver( int nhy); + /* Solver for Schrodinger Equation */ + int SchrodingerSolver(int nhy); -/* Member functions for dealing with Cosmic Ray Diffusion */ + /* Member functions for dealing with Cosmic Ray Diffusion */ int ComputeAnisotropicCRDiffusion(); // Anisotropic CR Diffusion Method int ComputeCRDiffusion(); // Isotropic CR Diffusion Method @@ -453,1264 +458,1331 @@ class grid int ComputeCRStreaming(); // Anisotropic CR Streaming Method int ComputeCRStreamingTimeStep(float &dt); -/* Baryons: Copy current solution to Old solution (returns success/fail) + /* Baryons: Copy current solution to Old solution (returns success/fail) (for step #16) */ - int CopyBaryonFieldToOldBaryonField(); - int CopyOldBaryonFieldToBaryonField(); + int CopyBaryonFieldToOldBaryonField(); + int CopyOldBaryonFieldToBaryonField(); + /* Copy potential field to baryon potential for output purposes. */ -/* Copy potential field to baryon potential for output purposes. */ + int CopyPotentialToBaryonField(); - int CopyPotentialToBaryonField(); - -/* Baryons: Update boundary according to the external boundary values + /* Baryons: Update boundary according to the external boundary values (for step #16) */ - int SetExternalBoundaryValues(ExternalBoundary *Exterior); + int SetExternalBoundaryValues(ExternalBoundary *Exterior); -/* Baryons: solve hydro equations in this grid (returns: the fluxes of the + /* Baryons: solve hydro equations in this grid (returns: the fluxes of the subgrids in the argument). Returns SUCCESS or FAIL. (for step #16) */ - int SolveHydroEquations(int CycleNumber, int NumberOfSubgrids, - fluxes *SubgridFluxes[], int level); + int SolveHydroEquations(int CycleNumber, int NumberOfSubgrids, + fluxes *SubgridFluxes[], int level); -/* Baryons: return pointer to the BoundaryFluxes of this grid */ + /* Baryons: return pointer to the BoundaryFluxes of this grid */ - int ReturnFluxDims(fluxes &f, int RefinementFactors[]); + int ReturnFluxDims(fluxes &f, int RefinementFactors[]); -/* Baryons: prepare and clear the accumulated boundary fluxes for this grid. + /* Baryons: prepare and clear the accumulated boundary fluxes for this grid. (for step #16) */ - void PrepareBoundaryFluxes(); - void ClearBoundaryFluxes(); + void PrepareBoundaryFluxes(); + void ClearBoundaryFluxes(); -/* Baryons: projected solution in current grid to the grid in the - argument which must have a lower resolution (i.e. downsample + /* Baryons: projected solution in current grid to the grid in the + argument which must have a lower resolution (i.e. downsample the current grid to the appropriate level). (for step #18) */ - int ProjectSolutionToParentGrid(grid &ParentGrid); + int ProjectSolutionToParentGrid(grid &ParentGrid); -/* Baryons: return boundary fluxes from this grid. Downsample them to + /* Baryons: return boundary fluxes from this grid. Downsample them to the refinement factors specified in the argument. Returns FAIL or SUCCESS. (for step #19) */ - int GetProjectedBoundaryFluxes(grid *ParentGrid, fluxes &ProjectedFluxes); + int GetProjectedBoundaryFluxes(grid *ParentGrid, fluxes &ProjectedFluxes); -/* Return the refinement factors as compared to the grid in the argument + /* Return the refinement factors as compared to the grid in the argument (integer version) (for step #19) */ - void ComputeRefinementFactors(grid *SubGrid, int RefinementFactors[]) { - int dim; - for (dim = 0; dim < GridRank; dim++) RefinementFactors[dim] = - int( CellWidth[dim][0] / SubGrid->CellWidth[dim][0] + 0.5); - for (dim = GridRank; dim < MAX_DIMENSION; dim++) - RefinementFactors[dim] = 1; - }; + void ComputeRefinementFactors(grid *SubGrid, int RefinementFactors[]) + { + int dim; + for (dim = 0; dim < GridRank; dim++) + RefinementFactors[dim] = + int(CellWidth[dim][0] / SubGrid->CellWidth[dim][0] + 0.5); + for (dim = GridRank; dim < MAX_DIMENSION; dim++) + RefinementFactors[dim] = 1; + }; -/* Return the refinement factors as compared to the grid in the argument + /* Return the refinement factors as compared to the grid in the argument (float version) (for step #19) */ - void ComputeRefinementFactorsFloat(grid *SubGrid, float Factors[]) { - int dim; - for (dim = 0; dim < GridRank; dim++) Factors[dim] = - (*CellWidth[dim]) / (*(SubGrid->CellWidth[dim]));; - for (dim = GridRank; dim < MAX_DIMENSION; dim++) - Factors[dim] = 1.0; - }; + void ComputeRefinementFactorsFloat(grid *SubGrid, float Factors[]) + { + int dim; + for (dim = 0; dim < GridRank; dim++) + Factors[dim] = + (*CellWidth[dim]) / (*(SubGrid->CellWidth[dim])); + ; + for (dim = GridRank; dim < MAX_DIMENSION; dim++) + Factors[dim] = 1.0; + }; -/* Baryons: Search for redundant overlap between two sets of fluxes (other + /* Baryons: Search for redundant overlap between two sets of fluxes (other and refined). If found, set the refined fluxes equal to the initial fluxes so there will be no double corrections.(step #19) */ - void CorrectRedundantFluxes(fluxes *OtherFluxes, fluxes *InitialFluxes, - fluxes *RefinedFluxes); + void CorrectRedundantFluxes(fluxes *OtherFluxes, fluxes *InitialFluxes, + fluxes *RefinedFluxes); -/* Baryons: correct for better flux estimates produced by subgrids - (i.e given the initial flux estimates and the subgrid flux - estimates, correct the grid to account for the subgrid + /* Baryons: correct for better flux estimates produced by subgrids + (i.e given the initial flux estimates and the subgrid flux + estimates, correct the grid to account for the subgrid flux estimates). Returns SUCCESS or FAIL. (for step #19) */ - int CorrectForRefinedFluxes(fluxes *InitialFluxes, fluxes *RefinedFluxes, - fluxes *BoundaryFluxesThisTimeStep, - int SUBlingGrid, - TopGridData *MetaData); + int CorrectForRefinedFluxes(fluxes *InitialFluxes, fluxes *RefinedFluxes, + fluxes *BoundaryFluxesThisTimeStep, + int SUBlingGrid, + TopGridData *MetaData); -/* Baryons: add the fluxes pointed to by the argument to the boundary fluxes + /* Baryons: add the fluxes pointed to by the argument to the boundary fluxes of this grid (sort of for step #16). Note that the two fluxes must have the same size. */ - int AddToBoundaryFluxes(fluxes *BoundaryFluxesToBeAdded); + int AddToBoundaryFluxes(fluxes *BoundaryFluxesToBeAdded); -/* set new time (time += dt) + /* set new time (time += dt) (step #21) */ - void SetTimeNextTimestep() {Time += dtFixed;}; - void SetTimePreviousTimestep() {Time -= dtFixed;}; + void SetTimeNextTimestep() { Time += dtFixed; }; + void SetTimePreviousTimestep() { Time -= dtFixed; }; -/* set time of this grid (used in setup) */ + /* set time of this grid (used in setup) */ - void SetTime(FLOAT NewTime) {Time = NewTime;}; + void SetTime(FLOAT NewTime) { Time = NewTime; }; -/* set hydro parameters (used in setup) */ + /* set hydro parameters (used in setup) */ - void SetHydroParameters(float co, int p1, int p2, int p3) - { - CourantSafetyNumber = co; - PPMFlatteningParameter = p1; - PPMDiffusionParameter = p2; - PPMSteepeningParameter = p3; - } + void SetHydroParameters(float co, int p1, int p2, int p3) + { + CourantSafetyNumber = co; + PPMFlatteningParameter = p1; + PPMDiffusionParameter = p2; + PPMSteepeningParameter = p3; + } -/* Problem-type-specific: compute approximate ratio of pressure + /* Problem-type-specific: compute approximate ratio of pressure gradient force to gravitational force for one-zone collapse test. */ - int ComputeOneZoneCollapseFactor(float *force_factor); + int ComputeOneZoneCollapseFactor(float *force_factor); -/* Baryons: compute the pressure at the requested time. */ + /* Baryons: compute the pressure at the requested time. */ int ComputePressure(FLOAT time, float *pressure, - float MinimumSupportEnergyCoefficient=0, - int IncludeCRs=0); + float MinimumSupportEnergyCoefficient = 0, + int IncludeCRs = 0); -/* Baryons: compute the pressure at the requested time using the dual energy + /* Baryons: compute the pressure at the requested time using the dual energy formalism. */ - int ComputePressureDualEnergyFormalism(FLOAT time, float *pressure); + int ComputePressureDualEnergyFormalism(FLOAT time, float *pressure); -/* Baryons: compute the temperature. */ + /* Baryons: compute the temperature. */ - int ComputeTemperatureField(float *temperature,int IncludeCRs=0); + int ComputeTemperatureField(float *temperature, int IncludeCRs = 0); -/* Baryons: compute the temperature at the requested time using + /* Baryons: compute the temperature at the requested time using Gadget equilibrium cooling. */ - int GadgetComputeTemperature(FLOAT time, float *temperature); + int GadgetComputeTemperature(FLOAT time, float *temperature); -/* Baryons: compute the temperatre at the requested time using the dual energy + /* Baryons: compute the temperatre at the requested time using the dual energy formalism when using Gadget equilibrium cooling. */ - int GadgetComputeTemperatureDEF(FLOAT time, float *temperature); + int GadgetComputeTemperatureDEF(FLOAT time, float *temperature); -/* Baryons: compute the dust temperature. */ + /* Baryons: compute the dust temperature. */ - int ComputeDustTemperatureField(float *temperature, float *dust_temperature); + int ComputeDustTemperatureField(float *temperature, float *dust_temperature); -/* Baryons: compute X-ray emissivity in specified band. */ + /* Baryons: compute X-ray emissivity in specified band. */ - int ComputeXrayEmissivity(float *temperature, - float *xray_emissivity, float keV1, float keV2, - char *XrayFileName); + int ComputeXrayEmissivity(float *temperature, + float *xray_emissivity, float keV1, float keV2, + char *XrayFileName); -/* Baryons: compute number density of ionized elements (just O7 and O8). */ + /* Baryons: compute number density of ionized elements (just O7 and O8). */ - int ComputeElementalDensity(float *temperature, float *elemental_density, - int Type); + int ComputeElementalDensity(float *temperature, float *elemental_density, + int Type); -/* Baryons: compute the ratio of specific heats. */ + /* Baryons: compute the ratio of specific heats. */ - int ComputeGammaField(float *GammaField); + int ComputeGammaField(float *GammaField); -/* Baryons: compute the cooling time. */ + /* Baryons: compute the cooling time. */ - int ComputeCoolingTime(float *cooling_time, int CoolingTimeOnly=FALSE); + int ComputeCoolingTime(float *cooling_time, int CoolingTimeOnly = FALSE); -/* Baryons & DualEnergyFormalism: Restore consistency between total and + /* Baryons & DualEnergyFormalism: Restore consistency between total and internal energy fields. */ - int RestoreEnergyConsistency(int Region); + int RestoreEnergyConsistency(int Region); + + /* Returns some grid info. */ -/* Returns some grid info. */ + int ReturnGridInfo(int *Rank, int Dims[], FLOAT Left[], FLOAT Right[]); - int ReturnGridInfo(int *Rank, int Dims[], FLOAT Left[], FLOAT Right[]); + /* Subtracts kinetic component from total energy. */ -/* Subtracts kinetic component from total energy. */ + int ConvertTotalEnergyToGasEnergy(); - int ConvertTotalEnergyToGasEnergy(); + /* Sets the energy to provide Jean's level support (Zeus: returns coeff). */ -/* Sets the energy to provide Jean's level support (Zeus: returns coeff). */ - - int SetMinimumSupport(float &MinimumSupportEnergyCoefficient); + int SetMinimumSupport(float &MinimumSupportEnergyCoefficient); -/* Debugging support. */ + /* Debugging support. */ - int DebugCheck(const char *message = "Debug"); + int DebugCheck(const char *message = "Debug"); #ifdef EMISSIVITY - /* define function prototype as a grid member function */ - int ClearEmissivity(); - int CheckEmissivity(); + /* define function prototype as a grid member function */ + int ClearEmissivity(); + int CheckEmissivity(); #endif -// ------------------------------------------------------------------------- -// Functions used for analysis -// + // ------------------------------------------------------------------------- + // Functions used for analysis + // -/* Calculate the angular momentum of a grid (given center). */ + /* Calculate the angular momentum of a grid (given center). */ - int CalculateAngularMomentum(FLOAT Center[], float AngularMomentum[], - float MeanVelocity[], float DMVelocity[], - FLOAT CenterOfMass[], FLOAT DMCofM[]); + int CalculateAngularMomentum(FLOAT Center[], float AngularMomentum[], + float MeanVelocity[], float DMVelocity[], + FLOAT CenterOfMass[], FLOAT DMCofM[]); -/* Find and track density peaks. */ + /* Find and track density peaks. */ - int AnalyzeTrackPeaks(int level, int ReportLevel); + int AnalyzeTrackPeaks(int level, int ReportLevel); -/* Project some of the fields to a plane. */ + /* Project some of the fields to a plane. */ - int ProjectToPlane(FLOAT ProjectedFieldLeftEdge[], - FLOAT ProjectedFieldRightEdge[], - int ProjectedFieldDims[], float *ProjectedField[], - int ProjectionDimension, int ProjectionSmooth, - int NumberOfProjectedFields, int level, - int XrayUseLookupTable, float XrayLowerCutoffkeV, - float XrayUpperCutoffkeV, char *XrayFileName); + int ProjectToPlane(FLOAT ProjectedFieldLeftEdge[], + FLOAT ProjectedFieldRightEdge[], + int ProjectedFieldDims[], float *ProjectedField[], + int ProjectionDimension, int ProjectionSmooth, + int NumberOfProjectedFields, int level, + int XrayUseLookupTable, float XrayLowerCutoffkeV, + float XrayUpperCutoffkeV, char *XrayFileName); - int ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], - FLOAT ProjectedFieldRightEdge[], - int ProjectedFieldDims[], float *ProjectedField[], - int ProjectionDimension, int ProjectionSmooth, - int NumberOfProjectedFields, int level, - int MetalLinesUseLookupTable, char *MetalLinesFilename); + int ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], + FLOAT ProjectedFieldRightEdge[], + int ProjectedFieldDims[], float *ProjectedField[], + int ProjectionDimension, int ProjectionSmooth, + int NumberOfProjectedFields, int level, + int MetalLinesUseLookupTable, char *MetalLinesFilename); -/* Set the fields to zero under the active region of the specified subgrid. */ + /* Set the fields to zero under the active region of the specified subgrid. */ - int ZeroSolutionUnderSubgrid(grid *Subgrid, int FieldsToZero, - float Value = 1.0, int AllProcessors = FALSE, - int IncludeGhostZones = FALSE); + int ZeroSolutionUnderSubgrid(grid *Subgrid, int FieldsToZero, + float Value = 1.0, int AllProcessors = FALSE, + int IncludeGhostZones = FALSE); -/* Convert the grid data to particle data for output. */ + /* Convert the grid data to particle data for output. */ - int OutputAsParticleData(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], + int OutputAsParticleData(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], ListOfParticles *ParticleList[NUM_PARTICLE_TYPES], float BaseRadius); -/* Output star particles to a binary file */ + /* Output star particles to a binary file */ - int OutputStarParticleInformation(FILE *StarFile); + int OutputStarParticleInformation(FILE *StarFile); -/* Return some information about the grid. */ + /* Return some information about the grid. */ - int CollectGridInformation(int &GridMemory, float &GridVolume, - int &NumberOfCells, float &AxialRatio, - int &CellsTotal, int &Particles); + int CollectGridInformation(int &GridMemory, float &GridVolume, + int &NumberOfCells, float &AxialRatio, + int &CellsTotal, int &Particles); -/* Output grid information (for movie generation). */ + /* Output grid information (for movie generation). */ - int OutputGridMovieData(FILE *Gridfptr, FILE *DMfptr, FILE *Starfptr, - FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], - FLOAT WriteOutTime, int NumberOfPoints[3], - int NumberOfValuesPerPoint[3], - char *PointValueNames[3][20], float BaseRadius); + int OutputGridMovieData(FILE *Gridfptr, FILE *DMfptr, FILE *Starfptr, + FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], + FLOAT WriteOutTime, int NumberOfPoints[3], + int NumberOfValuesPerPoint[3], + char *PointValueNames[3][20], float BaseRadius); -/* Output movie data (sequential format) */ + /* Output movie data (sequential format) */ - int WriteNewMovieData(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], - int RootResolution, FLOAT StopTime, - AMRHDF5Writer &AmiraGrid, - int lastMovieStep, int TopGridCycle, - int WriteMe, int MovieTimestepCounter, int open, - FLOAT WriteTime, - int alreadyopened[][MAX_DEPTH_OF_HIERARCHY] = NULL, - int NumberOfStarParticlesOnProcOnLvl[][MAX_DEPTH_OF_HIERARCHY] = NULL); + int WriteNewMovieData(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], + int RootResolution, FLOAT StopTime, + AMRHDF5Writer &AmiraGrid, + int lastMovieStep, int TopGridCycle, + int WriteMe, int MovieTimestepCounter, int open, + FLOAT WriteTime, + int alreadyopened[][MAX_DEPTH_OF_HIERARCHY] = NULL, + int NumberOfStarParticlesOnProcOnLvl[][MAX_DEPTH_OF_HIERARCHY] = NULL); - int WriteNewMovieDataSeparateParticles(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], - FLOAT StopTime, AMRHDF5Writer &AmiraGrid, - int lastMovieStep, int WriteMe, - FLOAT WriteTime, int alreadyopened[], - int NumberOfStarParticlesOnProc[]); + int WriteNewMovieDataSeparateParticles(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], + FLOAT StopTime, AMRHDF5Writer &AmiraGrid, + int lastMovieStep, int WriteMe, + FLOAT WriteTime, int alreadyopened[], + int NumberOfStarParticlesOnProc[]); - int ReturnMovieTimestep() { return TimestepsSinceCreation; }; + int ReturnMovieTimestep() { return TimestepsSinceCreation; }; -/* Output tracer particle information (interpolated from baryon grid). */ + /* Output tracer particle information (interpolated from baryon grid). */ - int TracerParticleOutputData(FILE *ptr, FLOAT WriteOutTime); - -// ------------------------------------------------------------------------- -// Functions for radiative cooling and multi-species rate equations -// + int TracerParticleOutputData(FILE *ptr, FLOAT WriteOutTime); -/* Handle the selection of cooling and chemistry modules */ + // ------------------------------------------------------------------------- + // Functions for radiative cooling and multi-species rate equations + // - int MultiSpeciesHandler(); + /* Handle the selection of cooling and chemistry modules */ -/* Wrap the grackle chemistry solver. */ + int MultiSpeciesHandler(); - int GrackleWrapper(); + /* Wrap the grackle chemistry solver. */ -/* Handle the selection of shock finding algorithm */ + int GrackleWrapper(); - int ShocksHandler(); + /* Handle the selection of shock finding algorithm */ -/* Solve the radiative cooling/heating equations */ + int ShocksHandler(); - int SolveRadiativeCooling(); + /* Solve the radiative cooling/heating equations */ -/* Solve the rate equations. */ + int SolveRadiativeCooling(); - int SolveRateEquations(); + /* Solve the rate equations. */ -/* Solve the joint rate and radiative cooling/heating equations */ + int SolveRateEquations(); - int SolveRateAndCoolEquations(int RTCoupledSolverIntermediateStep); + /* Solve the joint rate and radiative cooling/heating equations */ -/* Compute densities of various species for RadiationFieldUpdate. */ + int SolveRateAndCoolEquations(int RTCoupledSolverIntermediateStep); - int RadiationComputeDensities(int level); + /* Compute densities of various species for RadiationFieldUpdate. */ -// ------------------------------------------------------------------------- -// Functions for Gadget cooling + int RadiationComputeDensities(int level); -/* Driving routine for Gadget equilibrium cooling */ + // ------------------------------------------------------------------------- + // Functions for Gadget cooling - int GadgetCalculateCooling(float *d, float *e, float *ge, - float *u, float *v, float *w, - int *in, int *jn, int *kn, - int *iexpand, hydro_method *imethod, - int *idual, int *idim, - int *is, int *js, int *ks, int *ie, int *je, - int *ke, float *dt, float *aye, - float *fh, float *utem, float *uxyz, - float *uaye, float *urho, float *utim, - float *gamma); + /* Driving routine for Gadget equilibrium cooling */ -/* Computes cooling time using gadget equilibrium cooling */ + int GadgetCalculateCooling(float *d, float *e, float *ge, + float *u, float *v, float *w, + int *in, int *jn, int *kn, + int *iexpand, hydro_method *imethod, + int *idual, int *idim, + int *is, int *js, int *ks, int *ie, int *je, + int *ke, float *dt, float *aye, + float *fh, float *utem, float *uxyz, + float *uaye, float *urho, float *utim, + float *gamma); - int GadgetCoolingTime(float *d, float *e, float *ge, - float *u, float *v, float *w, - float *cooltime, - int *in, int *jn, int *kn, - int *iexpand, hydro_method *imethod, int *idual, int *idim, - int *is, int *js, int *ks, int *ie, int *je, - int *ke, float *dt, float *aye, - float *fh, float *utem, float *uxyz, - float *uaye, float *urho, float *utim, - float *gamma); + /* Computes cooling time using gadget equilibrium cooling */ + int GadgetCoolingTime(float *d, float *e, float *ge, + float *u, float *v, float *w, + float *cooltime, + int *in, int *jn, int *kn, + int *iexpand, hydro_method *imethod, int *idual, int *idim, + int *is, int *js, int *ks, int *ie, int *je, + int *ke, float *dt, float *aye, + float *fh, float *utem, float *uxyz, + float *uaye, float *urho, float *utim, + float *gamma); -/* calculates abundances and rates using Gadget equilibrium cooling */ + /* calculates abundances and rates using Gadget equilibrium cooling */ - void Gadgetfind_abundances_and_rates(float logT, float rho, float *ne_guess); + void Gadgetfind_abundances_and_rates(float logT, float rho, float *ne_guess); -/* calculates temperature using Gadget equilibrium cooling */ + /* calculates temperature using Gadget equilibrium cooling */ - float Gadgetconvert_u_to_temp(float u, float rho, float *ne_guess); + float Gadgetconvert_u_to_temp(float u, float rho, float *ne_guess); -/* calculates cooling rates (not cooling time) using Gadget equilibrium cooling + /* calculates cooling rates (not cooling time) using Gadget equilibrium cooling and gas temperature */ - float GadgetCoolingRate(float logT, float rho, float *nelec, float redshift); + float GadgetCoolingRate(float logT, float rho, float *nelec, float redshift); -/* wrapper for GadgetCoolingRate */ + /* wrapper for GadgetCoolingRate */ - float Gadget_EquilibriumCooling(float u_old, float rho, float dt, - float *ne_guess, float *utem, float *uxyz, - float *uaye, float *urho, - float *utim, float redshift); + float Gadget_EquilibriumCooling(float u_old, float rho, float dt, + float *ne_guess, float *utem, float *uxyz, + float *uaye, float *urho, + float *utim, float redshift); -/* calculates cooling rate (not cooling time) using energy instead of temperature + /* calculates cooling rate (not cooling time) using energy instead of temperature for Gadget equil. cooling */ - float GadgetCoolingRateFromU(float u, float rho, float *ne_guess, - float redshift); + float GadgetCoolingRateFromU(float u, float rho, float *ne_guess, + float redshift); -// Functions for shock finding -// - int FindShocks(); - int FindTempSplitShocks(); - int FindVelShocks(); - int FindVelSplitShocks(); + // Functions for shock finding + // + int FindShocks(); + int FindTempSplitShocks(); + int FindVelShocks(); + int FindVelSplitShocks(); -// ------------------------------------------------------------------------- -// Functions for grid (re)generation. -// + // ------------------------------------------------------------------------- + // Functions for grid (re)generation. + // -/* Remove un-needed arrays before rebuilding. */ + /* Remove un-needed arrays before rebuilding. */ - void CleanUp(); + void CleanUp(); -/* Delete all the fields, but leave other grid data. */ + /* Delete all the fields, but leave other grid data. */ - void DeleteAllFields(); + void DeleteAllFields(); -/* Delete all the fields except for the particle data */ + /* Delete all the fields except for the particle data */ - void DeleteAllButParticles(); + void DeleteAllButParticles(); -/* Delete all the baryon fields */ + /* Delete all the baryon fields */ - void DeleteBaryonFields(); + void DeleteBaryonFields(); -/* Sum particle mass flagging fields into ProcessorNumber if particles + /* Sum particle mass flagging fields into ProcessorNumber if particles aren't local. */ - int SetParticleMassFlaggingField(int StartProc=0, int EndProc=0, int level=-1, - int ParticleMassMethod=-1, int MustRefineMethod=-1, - int *SendProcs=NULL, - int NumberOfSends=0); - int CollectParticleMassFlaggingField(void); - void ClearParticleMassFlaggingField(void); + int SetParticleMassFlaggingField(int StartProc = 0, int EndProc = 0, int level = -1, + int ParticleMassMethod = -1, int MustRefineMethod = -1, + int *SendProcs = NULL, + int NumberOfSends = 0); + int CollectParticleMassFlaggingField(void); + void ClearParticleMassFlaggingField(void); -/* Clear mass flagging field (gg #1) */ + /* Clear mass flagging field (gg #1) */ - void ClearMassFlaggingField(); + void ClearMassFlaggingField(); -/* Clear boolean flagging field (gg #0) */ + /* Clear boolean flagging field (gg #0) */ - void ClearFlaggingField(); + void ClearFlaggingField(); -/* Set boolean flagging field */ + /* Set boolean flagging field */ - int SetFlaggingField(int &NumberOfFlaggedCells, int level); + int SetFlaggingField(int &NumberOfFlaggedCells, int level); + /* Set flagging field from refine regions */ -/* Set flagging field from refine regions */ + int SetFlaggingFieldMultiRefineRegions(int level); - int SetFlaggingFieldMultiRefineRegions(int level); + /* Set flagging field from static regions */ -/* Set flagging field from static regions */ + int SetFlaggingFieldStaticRegions(int level, int &NumberOfFlaggedCells); - int SetFlaggingFieldStaticRegions(int level, int &NumberOfFlaggedCells); + /* Delete flagging field */ -/* Delete flagging field */ + void DeleteFlaggingField(); - void DeleteFlaggingField(); - -/* Particles: deposit particles living in this grid into the Mass Flagging + /* Particles: deposit particles living in this grid into the Mass Flagging field (gg #2) */ - void DepositParticlesToMassFlaggingField() {}; + void DepositParticlesToMassFlaggingField(){}; + + /* Particles: deposit particles to particle mass flagging field. */ -/* Particles: deposit particles to particle mass flagging field. */ + int DepositMustRefineParticles(int pmethod, int level, + bool KeepFlaggingField); - int DepositMustRefineParticles(int pmethod, int level, - bool KeepFlaggingField); + /* Particles: deposit regions in the feedback zone to ensure flagging */ -/* Particles: deposit regions in the feedback zone to ensure flagging */ + int DepositRefinementZone(int level, FLOAT *ParticlePosition, FLOAT RefinementRadius); - int DepositRefinementZone(int level, FLOAT* ParticlePosition, FLOAT RefinementRadius); - -/* baryons: add baryon density to mass flaggin field (so the mass flagging - field contains the mass in the cell (not the density) + /* baryons: add baryon density to mass flaggin field (so the mass flagging + field contains the mass in the cell (not the density) (gg #3) */ - int AddFieldMassToMassFlaggingField(); + int AddFieldMassToMassFlaggingField(); -/* Flag all points where we are forbidding refinement from a color field */ + /* Flag all points where we are forbidding refinement from a color field */ - int FlagCellsToAvoidRefinement(); + int FlagCellsToAvoidRefinement(); -/* Flag all points in a region where refinement is not needed */ + /* Flag all points in a region where refinement is not needed */ - int FlagCellsToAvoidRefinementRegion(int level); + int FlagCellsToAvoidRefinementRegion(int level); -/* Flag all points that require refining (and delete Mass Flagging Field). + /* Flag all points that require refining (and delete Mass Flagging Field). Returns the number of flagged cells. Returns the number of flagged cells (gg #4) */ - int FlagCellsToBeRefinedByMass(int level, int method, int RestrictFlag); + int FlagCellsToBeRefinedByMass(int level, int method, int RestrictFlag); -/* Flag all points that require refining by their slope. + /* Flag all points that require refining by their slope. Returns the number of flagged cells. Returns the number of flagged cells (gg #4) */ - int FlagCellsToBeRefinedBySlope(); + int FlagCellsToBeRefinedBySlope(); -/* Flag all points that require refining by their slope. + /* Flag all points that require refining by their slope. Returns the number of flagged cells. Returns the number of flagged cells (gg #4) */ - int FlagCellsToBeRefinedBySecondDerivative(); - -/* Flag all points that require refinging by the presence of shocks. + int FlagCellsToBeRefinedBySecondDerivative(); + + /* Flag all points that require refinging by the presence of shocks. Returns the number of flagged cells. Returns the number of flagged cells (gg #4) */ - int FlagCellsToBeRefinedByShocks(); + int FlagCellsToBeRefinedByShocks(); -/* Flag all points based on the Mach number of the shock. */ + /* Flag all points based on the Mach number of the shock. */ - int FlagCellsToBeRefinedByShockwaves(int level); + int FlagCellsToBeRefinedByShockwaves(int level); -/* Flag all points that require refining by the Jean's length criterion. */ + /* Flag all points that require refining by the Jean's length criterion. */ - int FlagCellsToBeRefinedByJeansLength(); + int FlagCellsToBeRefinedByJeansLength(); -/* Flag all points that require refining by the total Jean's length criterion. (Tom Abel 10/2010) */ + /* Flag all points that require refining by the total Jean's length criterion. (Tom Abel 10/2010) */ - int FlagCellsToBeRefinedByTotalJeansLength(); + int FlagCellsToBeRefinedByTotalJeansLength(); -/* Flag all points that require refining by the Resistive Scale length criterion. + /* Flag all points that require refining by the Resistive Scale length criterion. abs(B)/abs(curl(B)) should be larger than cell size*/ - int FlagCellsToBeRefinedByResistiveLength(); + int FlagCellsToBeRefinedByResistiveLength(); -/* Flag all points that require refining by Shear. */ + /* Flag all points that require refining by Shear. */ - int FlagCellsToBeRefinedByShear(); + int FlagCellsToBeRefinedByShear(); -/* Flag all cells for which tcool < dx/sound_speed. */ + /* Flag all cells for which tcool < dx/sound_speed. */ - int FlagCellsToBeRefinedByCoolingTime(); + int FlagCellsToBeRefinedByCoolingTime(); -/* Flag particles within the MustRefineParticles region as MustRefine Particles */ - int MustRefineParticlesFlagInRegion(); + /* Flag particles within the MustRefineParticles region as MustRefine Particles */ + int MustRefineParticlesFlagInRegion(); -/* Flag MustRefine Particles from list */ + /* Flag MustRefine Particles from list */ - int MustRefineParticlesFlagFromList(); + int MustRefineParticlesFlagFromList(); -/* Flag all cells which are within a user-specified refinement region. */ + /* Flag all cells which are within a user-specified refinement region. */ - int FlagCellsToBeRefinedByMustRefineRegion(int level); + int FlagCellsToBeRefinedByMustRefineRegion(int level); -/* Flag all cells which are above a user-specified metallicity. */ + /* Flag all cells which are above a user-specified metallicity. */ - int FlagCellsToBeRefinedByMetallicity(int level); + int FlagCellsToBeRefinedByMetallicity(int level); -/* Flag all cells which have more than a specified metal mass */ + /* Flag all cells which have more than a specified metal mass */ - int FlagCellsToBeRefinedByMetalMass(int level); + int FlagCellsToBeRefinedByMetalMass(int level); -/* Flagging all cell adjacent to a previous flagged cell. Also, remove all + /* Flagging all cell adjacent to a previous flagged cell. Also, remove all Flagged cells in the boundary zones and within one zone of the boundary. */ - int FlagBufferZones(); + int FlagBufferZones(); -/* Identify new subgrids for this grid (and prove Fermat's last theorem too) + /* Identify new subgrids for this grid (and prove Fermat's last theorem too) (gg #5) */ - void IdentifyNewSubgrids(GridList &list); + void IdentifyNewSubgrids(GridList &list); -/* Identify new subgrids for this grid (1x1x1 subgrids). + /* Identify new subgrids for this grid (1x1x1 subgrids). (gg #5) */ - void IdentifyNewSubgridsSmall(GridList &list); + void IdentifyNewSubgridsSmall(GridList &list); -/* Coalesce neighbouring subgrids */ + /* Coalesce neighbouring subgrids */ - // void CoalesceSubgrids(GridList &list); + // void CoalesceSubgrids(GridList &list); -/* Inherit properties (rank, baryon field types, etc.) from ParentGrid + /* Inherit properties (rank, baryon field types, etc.) from ParentGrid (gg # 5,6) */ - void InheritProperties(grid *ParentGrid); + void InheritProperties(grid *ParentGrid); -/* set the grid dimensions, left, right edges and cell quantities based + /* set the grid dimensions, left, right edges and cell quantities based on arguments (gg #5,6) */ - void PrepareGrid(int Rank, int Dimensions[], - FLOAT LeftEdge[], FLOAT RightEdge[], int NumParticles); + void PrepareGrid(int Rank, int Dimensions[], + FLOAT LeftEdge[], FLOAT RightEdge[], int NumParticles); -/* Allocates space for grids (dims and NumberOfBaryonFields must be set). */ + /* Allocates space for grids (dims and NumberOfBaryonFields must be set). */ - void AllocateGrids(); + void AllocateGrids(); -/* set the grid derived quantites (CellLeftEdge, CellWidth & BoundaryFluxes) */ + /* set the grid derived quantites (CellLeftEdge, CellWidth & BoundaryFluxes) */ - void PrepareGridDerivedQuantities(); + void PrepareGridDerivedQuantities(); -/* baryons: interpolate field values from the Parent Grid (gg #6). + /* baryons: interpolate field values from the Parent Grid (gg #6). Returns SUCCESS or FAIL. */ - int InterpolateFieldValues(grid *ParentGrid , - LevelHierarchyEntry * OldFineLevel, TopGridData * MetaData); + int InterpolateFieldValues(grid *ParentGrid, + LevelHierarchyEntry *OldFineLevel, TopGridData *MetaData); + /* Interpolate one radiation field. Based on InterpolateFieldValues + but removed all of the conservative stuff. */ -/* Interpolate one radiation field. Based on InterpolateFieldValues - but removed all of the conservative stuff. */ + int InterpolateRadiationFromParent(grid *ParentGrid, int Field); - int InterpolateRadiationFromParent(grid *ParentGrid, int Field); - -/* baryons: check for coincident zones between grids & copy if found. + /* baryons: check for coincident zones between grids & copy if found. (correctly includes periodic boundary conditions). */ - int CheckForOverlap(grid *OtherGrid, - boundary_type LeftFaceBoundaryCondition[], - boundary_type RightFaceBoundaryCondition[], - int (grid::*CopyFunction)(grid *OtherGrid, - FLOAT EdgeOffset[])); - - - + int CheckForOverlap(grid *OtherGrid, + boundary_type LeftFaceBoundaryCondition[], + boundary_type RightFaceBoundaryCondition[], + int (grid::*CopyFunction)(grid *OtherGrid, + FLOAT EdgeOffset[])); + /* baryons: check for subgrids adjacent to external boundary with reflecting BCs. */ -/* baryons: check for subgrids adjacent to external boundary with reflecting BCs. */ + int CheckForExternalReflections( + boundary_type LeftFaceBoundaryCondition[], + boundary_type RightFaceBoundaryCondition[]); - int CheckForExternalReflections( - boundary_type LeftFaceBoundaryCondition[], - boundary_type RightFaceBoundaryCondition[]); + /* David Collins flux correction - July 2005 */ + int CheckForSharedFace(grid *OtherGrid, + boundary_type LeftFaceBoundaryCondition[], + boundary_type RightFaceBoundaryCondition[]); -/* David Collins flux correction - July 2005 */ - int CheckForSharedFace(grid *OtherGrid, - boundary_type LeftFaceBoundaryCondition[], - boundary_type RightFaceBoundaryCondition[]); + int CheckForSharedFaceHelper(grid *OtherGrid, + FLOAT EdgeOffset[MAX_DIMENSION]); - int CheckForSharedFaceHelper(grid *OtherGrid, - FLOAT EdgeOffset[MAX_DIMENSION]); - -/* baryons: check for overlap between grids & return TRUE if it exists + /* baryons: check for overlap between grids & return TRUE if it exists (correctly includes periodic boundary conditions). */ - int CheckForPossibleOverlap(grid *OtherGrid, - boundary_type LeftFaceBoundaryCondition[], - boundary_type RightFaceBoundaryCondition[]); - int CheckForPossibleOverlapHelper(grid *OtherGrid, - FLOAT EdgeOffset[MAX_DIMENSION]); + int CheckForPossibleOverlap(grid *OtherGrid, + boundary_type LeftFaceBoundaryCondition[], + boundary_type RightFaceBoundaryCondition[]); + int CheckForPossibleOverlapHelper(grid *OtherGrid, + FLOAT EdgeOffset[MAX_DIMENSION]); -/* baryons: copy coincident zone from the (old) grid in the argument + /* baryons: copy coincident zone from the (old) grid in the argument (gg #7). Return SUCCESS or FAIL. */ - int CopyZonesFromGrid(grid *GridOnSameLevel, - FLOAT EdgeOffset[MAX_DIMENSION]); + int CopyZonesFromGrid(grid *GridOnSameLevel, + FLOAT EdgeOffset[MAX_DIMENSION]); int CopyActiveZonesFromGrid(grid *GridOnSameLevel, - FLOAT EdgeOffset[MAX_DIMENSION], int SendField); + FLOAT EdgeOffset[MAX_DIMENSION], int SendField); -/* gravity: copy coincident potential field zones from grid in the argument + /* gravity: copy coincident potential field zones from grid in the argument (gg #7). Return SUCCESS or FAIL. */ - int CopyPotentialField(grid *GridOnSameLevel, - FLOAT EdgeOffset[MAX_DIMENSION]); + int CopyPotentialField(grid *GridOnSameLevel, + FLOAT EdgeOffset[MAX_DIMENSION]); -/* baryons: check for coincident zone from the (old) grid in the argument + /* baryons: check for coincident zone from the (old) grid in the argument (gg #7). Return SUCCESS or FAIL. */ - int CopyZonesFromGridCountOnly(grid *GridOnSameLevel, int &Overlap); + int CopyZonesFromGridCountOnly(grid *GridOnSameLevel, int &Overlap); -/* Returns whether or not the subgrids of this grid are static. */ + /* Returns whether or not the subgrids of this grid are static. */ - int AreSubgridsStatic() {return SubgridsAreStatic;}; + int AreSubgridsStatic() { return SubgridsAreStatic; }; -/* Check the energy conservation. */ + /* Check the energy conservation. */ - int ComputeEnergy(float EnergySum[]); + int ComputeEnergy(float EnergySum[]); -/* These two routines add grids to the chaining mesh used in the + /* These two routines add grids to the chaining mesh used in the FastSiblingLocator method and use the chaining mesh to find possible siblings. */ - int FastSiblingLocatorAddGrid(ChainingMeshStructure *mesh); + int FastSiblingLocatorAddGrid(ChainingMeshStructure *mesh); - int FastSiblingLocatorFindSiblings(ChainingMeshStructure *mesh, - SiblingGridList *list, - boundary_type LeftBoundaryCondition[], - boundary_type RightBoundaryCondition[]); + int FastSiblingLocatorFindSiblings(ChainingMeshStructure *mesh, + SiblingGridList *list, + boundary_type LeftBoundaryCondition[], + boundary_type RightBoundaryCondition[]); - /* hack: add density squared field to grid (used in ExtractSection). */ + /* hack: add density squared field to grid (used in ExtractSection). */ - void CreateDensitySquaredField() { - int size = GridDimension[0]*GridDimension[1]*GridDimension[2]; - BaryonField[NumberOfBaryonFields] = new float[size]; - for (int i = 0; i < size; i++) - BaryonField[NumberOfBaryonFields][i] = - BaryonField[0][i]*BaryonField[0][i]; - FieldType[NumberOfBaryonFields++] = Density; - }; + void CreateDensitySquaredField() + { + int size = GridDimension[0] * GridDimension[1] * GridDimension[2]; + BaryonField[NumberOfBaryonFields] = new float[size]; + for (int i = 0; i < size; i++) + BaryonField[NumberOfBaryonFields][i] = + BaryonField[0][i] * BaryonField[0][i]; + FieldType[NumberOfBaryonFields++] = Density; + }; - void PrintBaryonFieldValues(int field, int index) - {fprintf(stdout, "Baryonfield[field = %"ISYM"][index = %"ISYM"] = %g\n", - field, index, BaryonField[field][index]);}; + void PrintBaryonFieldValues(int field, int index) + { + fprintf(stdout, "Baryonfield[field = %" ISYM "][index = %" ISYM "] = %g\n", + field, index, BaryonField[field][index]); + }; -// ------------------------------------------------------------------------- -// Functions for use with gravity. -// + // ------------------------------------------------------------------------- + // Functions for use with gravity. + // -/* Set the gravity boundary type of a grid. */ + /* Set the gravity boundary type of a grid. */ - void SetGravityParameters(gravity_boundary_type Boundary) { - GravityBoundaryType = Boundary;}; - gravity_boundary_type ReturnGravityBoundaryType() - {return GravityBoundaryType;}; + void SetGravityParameters(gravity_boundary_type Boundary) + { + GravityBoundaryType = Boundary; + }; + gravity_boundary_type ReturnGravityBoundaryType() + { + return GravityBoundaryType; + }; -/* Gravity: Initialize, the gravitating Mass Field + /* Gravity: Initialize, the gravitating Mass Field (for steps #5, #6). */ - int InitializeGravitatingMassField(int RefinementFactor); + int InitializeGravitatingMassField(int RefinementFactor); -/* Gravity: Initialize, the particle component of the mass field. */ + /* Gravity: Initialize, the particle component of the mass field. */ - int InitializeGravitatingMassFieldParticles(int RefinementFactor); + int InitializeGravitatingMassFieldParticles(int RefinementFactor); -/* Gravity: allocate & clear the GravitatingMassField. */ + /* Gravity: allocate & clear the GravitatingMassField. */ - int ClearGravitatingMassField(); + int ClearGravitatingMassField(); -/* Gravity & baryons: Copy the parent density field to the extra boundary + /* Gravity & baryons: Copy the parent density field to the extra boundary region of GravitatingMassField (if any). */ - int CopyParentToGravitatingFieldBoundary(grid *ParentGrid); + int CopyParentToGravitatingFieldBoundary(grid *ParentGrid); -/* Gravity & Particles: allocate & clear the GravitatingMassFieldParticles. */ + /* Gravity & Particles: allocate & clear the GravitatingMassFieldParticles. */ - int ClearGravitatingMassFieldParticles(); + int ClearGravitatingMassFieldParticles(); -/* Baryons: add the baryon mass to the GravitatingMassField. */ + /* Baryons: add the baryon mass to the GravitatingMassField. */ - int AddBaryonsToGravitatingMassField(); + int AddBaryonsToGravitatingMassField(); -/* Generic deposit particles/grids to grid (either GravitatingMassField or + /* Generic deposit particles/grids to grid (either GravitatingMassField or GravitatingMassFieldParticles depending on the value of DepositField). */ - int DepositPositions(FLOAT *Positions[], float *Mass, int Number, - int DepositField); + int DepositPositions(FLOAT *Positions[], float *Mass, int Number, + int DepositField); -/* deposit particles/grids to grid (if they are on the grid). */ + /* deposit particles/grids to grid (if they are on the grid). */ -/* int DepositPositionsEdgeOff(float *Positions[], float *Mass, int Number);*/ + /* int DepositPositionsEdgeOff(float *Positions[], float *Mass, int Number);*/ -/* Gravity: Difference potential to get acceleration field. */ + /* Gravity: Difference potential to get acceleration field. */ - int ComputeAccelerationField(int DifferenceType, int level); + int ComputeAccelerationField(int DifferenceType, int level); -/* Gravity: Interpolate accelerations from other grid. */ + /* Gravity: Interpolate accelerations from other grid. */ - int InterpolateAccelerations(grid *FromGrid); + int InterpolateAccelerations(grid *FromGrid); -/* Gravity: Compute particle and grid accelerations. */ + /* Gravity: Compute particle and grid accelerations. */ - int ComputeAccelerations(int level); + int ComputeAccelerations(int level); -/* Particles: add overlapping ParticleMassField to Target's + /* Particles: add overlapping ParticleMassField to Target's GravitatingMassField. */ - int CopyOverlappingMassField(grid *TargetGrid, - FLOAT EdgeOffset[MAX_DIMENSION]); + int CopyOverlappingMassField(grid *TargetGrid, + FLOAT EdgeOffset[MAX_DIMENSION]); -/* Gravity: Allocate and make initial guess for PotentialField. */ + /* Gravity: Allocate and make initial guess for PotentialField. */ - int PreparePotentialField(grid *ParentGrid); + int PreparePotentialField(grid *ParentGrid); -/* Gravity: Allocate and make initial guess for PotentialField. */ + /* Gravity: Allocate and make initial guess for PotentialField. */ - int SolveForPotential(int level, FLOAT PotentialTime = -1); + int SolveForPotential(int level, FLOAT PotentialTime = -1); -/* Gravity: Prepare the Greens Function. */ + /* Gravity: Prepare the Greens Function. */ - int PrepareGreensFunction(); - int PreparePeriodicGreensFunction(region *GreensRegion); + int PreparePeriodicGreensFunction(region *GreensRegion); -/* Gravity: Copy potential/density into/out of FFT regions. */ + /* Gravity: Copy potential/density into/out of FFT regions. */ - int PrepareFFT(region *InitialRegion, int Field, int DomainDim[]); - int FinishFFT(region *InitialRegion, int Field, int DomainDim[]); + int PrepareFFT(region *InitialRegion, int Field, int DomainDim[]); + int FinishFFT(region *InitialRegion, int Field, int DomainDim[]); -/* Gravity: set the potential boundary for isolated BC's */ + /* Gravity: set the potential boundary for isolated BC's */ - int SetIsolatedPotentialBoundary(); + int SetIsolatedPotentialBoundary(); -/* Gravity: Set the external acceleration fields. */ + /* Gravity: Set the external acceleration fields. */ - int ComputeAccelerationFieldExternal(); + int ComputeAccelerationFieldExternal(); -/* Gravity: Set the external acceleration fields from external potential. */ + /* Gravity: Set the external acceleration fields from external potential. */ - int ComputeAccelerationsFromExternalPotential(int DifferenceType, - float *ExternalPotential, - float *Field[]); + int ComputeAccelerationsFromExternalPotential(int DifferenceType, + float *ExternalPotential, + float *Field[]); -/* Gravity: Add fixed, external potential to baryons & particles. */ + /* Gravity: Add fixed, external potential to baryons & particles. */ - int AddExternalPotentialField(float *field); - + int AddExternalPotentialField(float *field); -/* Particles + Gravity: Clear ParticleAccleration. */ + /* APM Gravity: Compute accelerations for a grid*/ - int ClearParticleAccelerations(); + int ComputeAccelerationFieldAPM(int RefinmentFactor); -/* Baryons + Gravity: Interpolate the AccelerationField in FromGrid to + /* APM Gravity: Compute potential for a grid*/ + + int ComputePotentialFieldAPM(int RefinmentFactor); + + /* APM Gravity: Add acceleration from parent grid */ + + int AddParentAccelerationFieldAPM(grid *ParentGrid); + + /* APM Gravity: Add potential from parent grid */ + + int AddParentPotentialFieldAPM(grid *ParentGrid); + + /* Output particle info */ + + int OutputParticleDiagnostic(int number); + + /* Output acceleration field */ + + int OutputAccelerationField(FILE *fptr, int level); + + /* Output acceleration field */ + + int OutputGravitatingMassField(FILE *fptr, FILE *fptr2, int level); + + /* Particles + Gravity: Clear ParticleAccleration. */ + + int ClearParticleAccelerations(); + + /* Baryons + Gravity: Interpolate the AccelerationField in FromGrid to AccelerationFieldForCells at the GridPositions in this grid. */ - int InterpolateGridPositions(grid *FromGrid); + int InterpolateGridPositions(grid *FromGrid); -/* Particles + Gravity: Interpolate the AccelerationField in FromGrid to + /* Particles + Gravity: Interpolate the AccelerationField in FromGrid to ParticleAcceleration at the ParticlePositions in this grid. */ - int InterpolateParticlePositions(grid *FromGrid, int DifferenceType); - -/* Generic routine for interpolating particles/grid. */ + int InterpolateParticlePositions(grid *FromGrid, int DifferenceType); - int InterpolatePositions(FLOAT *Positions[], int dim, float *Field, - int Number); + /* Generic routine for interpolating particles/grid. */ -/* Gravity: Delete GravitatingMassField. */ + int InterpolatePositions(FLOAT *Positions[], int dim, float *Field, + int Number); - void DeleteGravitatingMassField() { - delete [] GravitatingMassField; - GravitatingMassField = NULL; - }; + /* Gravity: Delete GravitatingMassField. */ -/* Gravity: Init GravitatingMassField. */ + void DeleteGravitatingMassField() + { + delete[] GravitatingMassField; + GravitatingMassField = NULL; + }; - void InitGravitatingMassField(int size) { - GravitatingMassField = new float[size]; - } + /* Gravity: Init GravitatingMassField. */ -/* Gravity */ + void InitGravitatingMassField(int size) + { + GravitatingMassField = new float[size]; + } - int ReturnGravitatingMassFieldDimension(int dim) { - return GravitatingMassFieldDimension[dim]; - } + /* Gravity */ -/* Gravity: Delete AccelerationField. */ + int ReturnGravitatingMassFieldDimension(int dim) + { + return GravitatingMassFieldDimension[dim]; + } - void DeleteAccelerationField() { - if (!((SelfGravity || UniformGravity || PointSourceGravity || ExternalGravity))) return; - for (int dim = 0; dim < GridRank; dim++) { - delete [] AccelerationField[dim]; - AccelerationField[dim] = NULL; - } - }; + /* Gravity: Delete AccelerationField. */ -/* Gravity: Add fixed, external acceleration to baryons & particles. */ + void DeleteAccelerationField() + { + if (!((SelfGravity || UniformGravity || PointSourceGravity || ExternalGravity))) + return; + for (int dim = 0; dim < GridRank; dim++) + { + delete[] AccelerationField[dim]; + AccelerationField[dim] = NULL; + } + }; - int AddExternalAcceleration(); + /* Gravity: Add fixed, external acceleration to baryons & particles. */ -/* Gravity: deposit baryons into target GravitatingMassField. */ + int AddExternalAcceleration(); - int DepositBaryons(grid *TargetGrid, FLOAT DepositTime); + /* Gravity: deposit baryons into target GravitatingMassField. */ -// ------------------------------------------------------------------------- -// Functions for accessing various grid-based information -// - int GetGridRank() {return GridRank;} - int GetGridDimension(int Dimension) {return GridDimension[Dimension];} - int GetGridStartIndex(int Dimension) {return GridStartIndex[Dimension];} - int GetGridEndIndex(int Dimension) {return GridEndIndex[Dimension];} - int GetActiveSize() { - int dim, size; - for (dim = 0, size = 1; dim < GridRank; dim++) { - size *= GridEndIndex[dim] - GridStartIndex[dim] + 1; - } - return size; - } - int GetGridSize() { - int dim, size; - for (dim = 0, size = 1; dim < GridRank; dim++) - size *= GridDimension[dim]; - return size; - } - FLOAT GetGridLeftEdge(int Dimension) {return GridLeftEdge[Dimension];} - FLOAT GetGridRightEdge(int Dimension) {return GridRightEdge[Dimension];} - FLOAT GetCellWidth(int Dimension, int index) {return CellWidth[Dimension][index];} - FLOAT GetCellLeftEdge(int Dimension, int index) {return CellLeftEdge[Dimension][index];} + int DepositBaryons(grid *TargetGrid, FLOAT DepositTime); + // ------------------------------------------------------------------------- + // Functions for accessing various grid-based information + // + int GetGridRank() { return GridRank; } + int GetGridDimension(int Dimension) { return GridDimension[Dimension]; } + int GetGridStartIndex(int Dimension) { return GridStartIndex[Dimension]; } + int GetGridEndIndex(int Dimension) { return GridEndIndex[Dimension]; } + int GetActiveSize() + { + int dim, size; + for (dim = 0, size = 1; dim < GridRank; dim++) + { + size *= GridEndIndex[dim] - GridStartIndex[dim] + 1; + } + return size; + } + int GetGridSize() + { + int dim, size; + for (dim = 0, size = 1; dim < GridRank; dim++) + size *= GridDimension[dim]; + return size; + } + FLOAT GetGridLeftEdge(int Dimension) { return GridLeftEdge[Dimension]; } + FLOAT GetGridRightEdge(int Dimension) { return GridRightEdge[Dimension]; } + FLOAT GetCellWidth(int Dimension, int index) { return CellWidth[Dimension][index]; } + FLOAT GetCellLeftEdge(int Dimension, int index) { return CellLeftEdge[Dimension][index]; } int PrepareBoundaryMassFluxFieldNumbers(); int ComputeDomainBoundaryMassFlux(float *allgrid_BoundaryMassFluxContainer, TopGridData *MetaData); #ifdef TRANSFER -// ------------------------------------------------------------------------- -// Functions for use with coupled radiation-hydrodynamics solver. -// - void SetMaxRadiationDt(float MaxRadDt) {MaxRadiationDt = MaxRadDt;} + // ------------------------------------------------------------------------- + // Functions for use with coupled radiation-hydrodynamics solver. + // + void SetMaxRadiationDt(float MaxRadDt) { MaxRadiationDt = MaxRadDt; } #endif + // ------------------------------------------------------------------------- + // Functions for accessing specific baryon fields + // (all sources combined in the file Grid_AccessBaryonFields.C) + // + float *AccessDensity(); + float *AccessTotalEnergy(); + float *AccessGasEnergy(); + float *AccessVelocity1(); + float *AccessVelocity2(); + float *AccessVelocity3(); + float *AccessElectronDensity(); + float *AccessHIDensity(); + float *AccessHIIDensity(); + float *AccessHeIDensity(); + float *AccessHeIIDensity(); + float *AccessHeIIIDensity(); + float *AccessHMDensity(); + float *AccessH2IDensity(); + float *AccessH2IIDensity(); + float *AccessDIDensity(); + float *AccessDIIDensity(); + float *AccessHDIDensity(); + float *AccessSNColour(); + float *AccessMetallicity(); + float *AccessExtraType0(); + float *AccessExtraType1(); + float *AccessKPhHI(); + float *AccessPhotoGamma(); + float *AccessKPhHeI(); + float *AccessGammaHeI(); + float *AccessKPhHeII(); + float *AccessGammaHeII(); + float *AccessKDissH2I(); + float *AccessKPhHM(); + float *AccessKDissH2II(); + float *AccessGravPotential(); + float *AccessAcceleration0(); + float *AccessAcceleration1(); + float *AccessAcceleration2(); + float *AccessRadPressure0(); + float *AccessRadPressure1(); + float *AccessRadPressure2(); + float *AccessEmissivity0(); + float *AccessRadiationFrequency0(); + float *AccessRadiationFrequency1(); + float *AccessRadiationFrequency2(); + float *AccessRadiationFrequency3(); + float *AccessRadiationFrequency4(); + float *AccessRadiationFrequency5(); + float *AccessRadiationFrequency6(); + float *AccessRadiationFrequency7(); + float *AccessRadiationFrequency8(); + float *AccessRadiationFrequency9(); + + // ------------------------------------------------------------------------- + // Functions for accessing top-grid parallelism information + // (note: information only available/valid for this level) + // -// ------------------------------------------------------------------------- -// Functions for accessing specific baryon fields -// (all sources combined in the file Grid_AccessBaryonFields.C) -// - float* AccessDensity(); - float* AccessTotalEnergy(); - float* AccessGasEnergy(); - float* AccessVelocity1(); - float* AccessVelocity2(); - float* AccessVelocity3(); - float* AccessElectronDensity(); - float* AccessHIDensity(); - float* AccessHIIDensity(); - float* AccessHeIDensity(); - float* AccessHeIIDensity(); - float* AccessHeIIIDensity(); - float* AccessHMDensity(); - float* AccessH2IDensity(); - float* AccessH2IIDensity(); - float* AccessDIDensity(); - float* AccessDIIDensity(); - float* AccessHDIDensity(); - float* AccessSNColour(); - float* AccessMetallicity(); - float* AccessExtraType0(); - float* AccessExtraType1(); - float* AccessKPhHI(); - float* AccessPhotoGamma(); - float* AccessKPhHeI(); - float* AccessGammaHeI(); - float* AccessKPhHeII(); - float* AccessGammaHeII(); - float* AccessKDissH2I(); - float* AccessKPhHM(); - float* AccessKDissH2II(); - float* AccessGravPotential(); - float* AccessAcceleration0(); - float* AccessAcceleration1(); - float* AccessAcceleration2(); - float* AccessRadPressure0(); - float* AccessRadPressure1(); - float* AccessRadPressure2(); - float* AccessEmissivity0(); - float* AccessRadiationFrequency0(); - float* AccessRadiationFrequency1(); - float* AccessRadiationFrequency2(); - float* AccessRadiationFrequency3(); - float* AccessRadiationFrequency4(); - float* AccessRadiationFrequency5(); - float* AccessRadiationFrequency6(); - float* AccessRadiationFrequency7(); - float* AccessRadiationFrequency8(); - float* AccessRadiationFrequency9(); - - -// ------------------------------------------------------------------------- -// Functions for accessing top-grid parallelism information -// (note: information only available/valid for this level) -// - -/* Processor layout: get and set the number of procs in each + /* Processor layout: get and set the number of procs in each dim within the cartesian processor grid - (1-based, i.e. {1 1 1} defines a single-processor layout) */ - int GetProcessorLayout(int Dimension) {return ProcLayout[Dimension];} - void SetProcessorLayout(int Dimension, int procs) { - if (Dimension < 0 || Dimension > MAX_DIMENSION) - fprintf(stderr,"SetProcessorLayout: invalid Dimension.\n"); - else - if (procs > 0) ProcLayout[Dimension] = procs; - else fprintf(stderr,"SetProcessorLayout: invalid procs value.\n"); - } - -/* Processor location: get and set the location of this grid's proc + (1-based, i.e. {1 1 1} defines a single-processor layout) */ + int GetProcessorLayout(int Dimension) { return ProcLayout[Dimension]; } + void SetProcessorLayout(int Dimension, int procs) + { + if (Dimension < 0 || Dimension > MAX_DIMENSION) + fprintf(stderr, "SetProcessorLayout: invalid Dimension.\n"); + else if (procs > 0) + ProcLayout[Dimension] = procs; + else + fprintf(stderr, "SetProcessorLayout: invalid procs value.\n"); + } + + /* Processor location: get and set the location of this grid's proc within the cartesian processor grid defined in ProcLayout (0-based, i.e. {0 0 0} defines the 1st proc in each dimension) */ - int GetProcessorLocation(int Dimension) {return ProcLocation[Dimension];} - void SetProcessorLocation(int Dimension, int location) { - if (Dimension < 0 || Dimension > MAX_DIMENSION) - fprintf(stderr,"SetProcessorLocation: invalid Dimension.\n"); - else - if (location >= 0) ProcLocation[Dimension] = location; - else fprintf(stderr,"SetProcessorLocation: invalid location.\n"); - } - -/* Processor neighbors: get and set the grid IDs (not MPI process IDs) of this - grid's neighbors within the cartesian processor grid defined in ProcLayout. + int GetProcessorLocation(int Dimension) { return ProcLocation[Dimension]; } + void SetProcessorLocation(int Dimension, int location) + { + if (Dimension < 0 || Dimension > MAX_DIMENSION) + fprintf(stderr, "SetProcessorLocation: invalid Dimension.\n"); + else if (location >= 0) + ProcLocation[Dimension] = location; + else + fprintf(stderr, "SetProcessorLocation: invalid location.\n"); + } + + /* Processor neighbors: get and set the grid IDs (not MPI process IDs) of this + grid's neighbors within the cartesian processor grid defined in ProcLayout. Get... returns the {left=0,right=1} neighbor grid ID in a given dim Set... provides access to set neighbor information into the grid */ - int GetProcessorNeighbors(int Dimension, int LR) { - return ProcNeighbors[Dimension][LR];} - void SetProcessorNeighbors(int Dimension, int LR, int NBid) { - if (Dimension < 0 || Dimension > MAX_DIMENSION) - fprintf(stderr,"SetProcessorNeighbors: invalid Dimension.\n"); - else - if (LR < 0 || LR > 1) - fprintf(stderr,"SetProcessorNeighbors: invalid neighbor.\n"); - else - if (NBid >= 0) ProcNeighbors[Dimension][LR] = NBid; - else fprintf(stderr,"SetProcessorNeighbors: invalid grid ID.\n"); - } - + int GetProcessorNeighbors(int Dimension, int LR) + { + return ProcNeighbors[Dimension][LR]; + } + void SetProcessorNeighbors(int Dimension, int LR, int NBid) + { + if (Dimension < 0 || Dimension > MAX_DIMENSION) + fprintf(stderr, "SetProcessorNeighbors: invalid Dimension.\n"); + else if (LR < 0 || LR > 1) + fprintf(stderr, "SetProcessorNeighbors: invalid neighbor.\n"); + else if (NBid >= 0) + ProcNeighbors[Dimension][LR] = NBid; + else + fprintf(stderr, "SetProcessorNeighbors: invalid grid ID.\n"); + } -// ------------------------------------------------------------------------- -// Functions for use with particles. -// + // ------------------------------------------------------------------------- + // Functions for use with particles. + // -/* Particles: Deposit particles in the specified field (DepositField) of the + /* Particles: Deposit particles in the specified field (DepositField) of the TargetGrid at the given time. */ - int DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, - int DepositField); + int DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, + int DepositField); - int DepositParticlePositionsLocal(FLOAT DepositTime, int DepositField, - bool BothFlags); + int DepositParticlePositionsLocal(FLOAT DepositTime, int DepositField, + bool BothFlags); -/* Particles: add overlapping ParticleMassField to Target's + /* Particles: add overlapping ParticleMassField to Target's GravitatingMassField. */ - int AddOverlappingParticleMassField(grid *TargetGrid, - FLOAT EdgeOffset[MAX_DIMENSION]); + int AddOverlappingParticleMassField(grid *TargetGrid, + FLOAT EdgeOffset[MAX_DIMENSION]); -/* Particles: Apply particle acceleration to velocity for particles in this + /* Particles: Apply particle acceleration to velocity for particles in this grid (for step #9) */ - int UpdateParticleVelocity(float TimeStep); + int UpdateParticleVelocity(float TimeStep); -/* Particles: Update particle positions (push) + /* Particles: Update particle positions (push) (for step #13) */ - int UpdateParticlePosition(float TimeStep, int OffProcessorUpdate = FALSE); + int UpdateParticlePosition(float TimeStep, int OffProcessorUpdate = FALSE); -/* Particles: Move particles from TargetGrid to this grid. */ + /* Particles: Move particles from TargetGrid to this grid. */ - int MoveAllParticles(int NumberOfGrids, grid* TargetGrids[]); + int MoveAllParticles(int NumberOfGrids, grid *TargetGrids[]); - int MoveAllParticlesOld(int NumberOfGrids, grid* TargetGrids[]); + int MoveAllParticlesOld(int NumberOfGrids, grid *TargetGrids[]); -/* Particles: Move particles that lie within this grid from the TargetGrid + /* Particles: Move particles that lie within this grid from the TargetGrid to this grid. */ -// int MoveSubgridParticles(grid *TargetGrid); - - - int MoveSubgridParticles(grid *TargetGrid, - int *Counter, - PINT *Number, - int *Type, - float *Mass, - FLOAT *Position[], - float *Velocity[], - float *Attribute[]); + // int MoveSubgridParticles(grid *TargetGrid); + int MoveSubgridParticles(grid *TargetGrid, + int *Counter, + PINT *Number, + int *Type, + float *Mass, + FLOAT *Position[], + float *Velocity[], + float *Attribute[]); -/* Particles: same as above, but a version that is much more efficient. */ + /* Particles: same as above, but a version that is much more efficient. */ - int MoveSubgridParticlesFast(int NumberOfSubgrids, grid *ToGrids[], - int AllLocal); + int MoveSubgridParticlesFast(int NumberOfSubgrids, grid *ToGrids[], + int AllLocal); -/* Particles: Clean up moved particles (from MoveSubgridParticles). */ + /* Particles: Clean up moved particles (from MoveSubgridParticles). */ - int CleanUpMovedParticles(); + int CleanUpMovedParticles(); -/* Particles: delete accleration fields. */ + /* Particles: delete accleration fields. */ - void DeleteParticleAcceleration() { - if (!((SelfGravity || UniformGravity || PointSourceGravity))) return; - for (int dim = 0; dim < GridRank+ComputePotential; dim++) { - delete [] ParticleAcceleration[dim]; - ParticleAcceleration[dim] = NULL; - delete [] ActiveParticleAcceleration[dim]; - ActiveParticleAcceleration[dim] = NULL; - } - }; + void DeleteParticleAcceleration() + { + if (!((SelfGravity || UniformGravity || PointSourceGravity))) + return; + for (int dim = 0; dim < GridRank + ComputePotential; dim++) + { + delete[] ParticleAcceleration[dim]; + ParticleAcceleration[dim] = NULL; + delete[] ActiveParticleAcceleration[dim]; + ActiveParticleAcceleration[dim] = NULL; + } + }; -/* Particles & Gravity: Delete GravitatingMassField. */ + /* Particles & Gravity: Delete GravitatingMassField. */ - void DeleteGravitatingMassFieldParticles() { - delete [] GravitatingMassFieldParticles; - GravitatingMassFieldParticles = NULL; - GravitatingMassFieldParticlesCellSize = FLOAT_UNDEFINED; - }; + void DeleteGravitatingMassFieldParticles() + { + delete[] GravitatingMassFieldParticles; + GravitatingMassFieldParticles = NULL; + GravitatingMassFieldParticlesCellSize = FLOAT_UNDEFINED; + }; -/* Particles: return number of particles. */ + /* Particles: return number of particles. */ - int ReturnNumberOfParticles() {return NumberOfParticles;}; - int ReturnNumberOfActiveParticles() {return NumberOfActiveParticles;}; - int ReturnNumberOfActiveParticlesOfThisType(int ActiveParticleIDToFind); - ActiveParticleList& ReturnActiveParticles() {return Act\ -iveParticles;}; + int ReturnNumberOfParticles() { return NumberOfParticles; }; + int ReturnNumberOfActiveParticles() { return NumberOfActiveParticles; }; + int ReturnNumberOfActiveParticlesOfThisType(int ActiveParticleIDToFind); + ActiveParticleList &ReturnActiveParticles() { return Act\ +iveParticles; }; - int ReturnNumberOfStarParticles(void); + int ReturnNumberOfStarParticles(void); -/* Particles: set number of particles. */ + /* Particles: set number of particles. */ - void SetNumberOfParticles(int num) {NumberOfParticles = num;}; - void SetNumberOfActiveParticles(int num) {NumberOfActiveParticles = num;}; - void SetActiveParticleTypeCounts(int type, int count) - { ActiveParticleTypeCount[type] = count; }; + void SetNumberOfParticles(int num) { NumberOfParticles = num; }; + void SetNumberOfActiveParticles(int num) { NumberOfActiveParticles = num; }; + void SetActiveParticleTypeCounts(int type, int count) + { + ActiveParticleTypeCount[type] = count; + }; -/* Particles: delete particle fields and set null. */ + /* Particles: delete particle fields and set null. */ - void DeleteParticles() { - if (ParticleMass != NULL) delete [] ParticleMass; - if (ParticleNumber != NULL) delete [] ParticleNumber; - if (ParticleType != NULL) delete [] ParticleType; - ParticleMass = NULL; - ParticleNumber = NULL; - ParticleType = NULL; - for (int dim = 0; dim < GridRank; dim++) { - if (ParticlePosition[dim] != NULL) delete [] ParticlePosition[dim]; - if (ParticleVelocity[dim] != NULL) delete [] ParticleVelocity[dim]; - ParticlePosition[dim] = NULL; - ParticleVelocity[dim] = NULL; - } - for (int i = 0; i < NumberOfParticleAttributes; i++) { - if (ParticleAttribute[i] != NULL) delete [] ParticleAttribute[i]; - ParticleAttribute[i] = NULL; - } - }; + void DeleteParticles() + { + if (ParticleMass != NULL) + delete[] ParticleMass; + if (ParticleNumber != NULL) + delete[] ParticleNumber; + if (ParticleType != NULL) + delete[] ParticleType; + ParticleMass = NULL; + ParticleNumber = NULL; + ParticleType = NULL; + for (int dim = 0; dim < GridRank; dim++) + { + if (ParticlePosition[dim] != NULL) + delete[] ParticlePosition[dim]; + if (ParticleVelocity[dim] != NULL) + delete[] ParticleVelocity[dim]; + ParticlePosition[dim] = NULL; + ParticleVelocity[dim] = NULL; + } + for (int i = 0; i < NumberOfParticleAttributes; i++) + { + if (ParticleAttribute[i] != NULL) + delete[] ParticleAttribute[i]; + ParticleAttribute[i] = NULL; + } + }; - void DeleteActiveParticles() { + void DeleteActiveParticles() + { NumberOfActiveParticles = 0; this->ActiveParticles.clear(); } - void CorrectActiveParticleCounts() { + void CorrectActiveParticleCounts() + { NumberOfActiveParticles = ActiveParticles.size(); } - -/* Particles: allocate new particle fields. */ - - void AllocateNewParticles(int NumberOfNewParticles) { - ParticleMass = new float[NumberOfNewParticles]; - ParticleNumber = new PINT[NumberOfNewParticles]; - ParticleType = new int[NumberOfNewParticles]; - for (int dim = 0; dim < GridRank; dim++) { - ParticlePosition[dim] = new FLOAT[NumberOfNewParticles]; - ParticleVelocity[dim] = new float[NumberOfNewParticles]; - } - for (int i = 0; i < NumberOfParticleAttributes; i++) - ParticleAttribute[i] = new float[NumberOfNewParticles]; - }; - -/* Particles: Copy pointers passed into into grid. */ - - void SetParticlePointers(float *Mass, PINT *Number, int *Type, - FLOAT *Position[], - float *Velocity[], float *Attribute[]) { - ParticleMass = Mass; + + /* Particles: allocate new particle fields. */ + + void AllocateNewParticles(int NumberOfNewParticles) + { + ParticleMass = new float[NumberOfNewParticles]; + ParticleNumber = new PINT[NumberOfNewParticles]; + ParticleType = new int[NumberOfNewParticles]; + for (int dim = 0; dim < GridRank; dim++) + { + ParticlePosition[dim] = new FLOAT[NumberOfNewParticles]; + ParticleVelocity[dim] = new float[NumberOfNewParticles]; + } + for (int i = 0; i < NumberOfParticleAttributes; i++) + ParticleAttribute[i] = new float[NumberOfNewParticles]; + }; + + /* Particles: Copy pointers passed into into grid. */ + + void SetParticlePointers(float *Mass, PINT *Number, int *Type, + FLOAT *Position[], + float *Velocity[], float *Attribute[]) + { + ParticleMass = Mass; ParticleNumber = Number; - ParticleType = Type; - for (int dim = 0; dim < GridRank; dim++) { + ParticleType = Type; + for (int dim = 0; dim < GridRank; dim++) + { ParticlePosition[dim] = Position[dim]; ParticleVelocity[dim] = Velocity[dim]; } for (int i = 0; i < NumberOfParticleAttributes; i++) ParticleAttribute[i] = Attribute[i]; - }; + }; -/* Particles: Set new star particle index. */ + /* Particles: Set new star particle index. */ - void SetNewParticleIndex(int &NumberCount1, PINT &NumberCount2); - void SetNewActiveParticleIndex(PINT &NumberCount); + void SetNewParticleIndex(int &NumberCount1, PINT &NumberCount2); + void SetNewActiveParticleIndex(PINT &NumberCount); -/* Particles: Set new star particle index. - Old version */ + /* Particles: Set new star particle index. - Old version */ - void SetNewParticleIndexOld(int &NumberCount, int BaseNumber) { - for (int n = 0; n < NumberOfParticles; n++) + void SetNewParticleIndexOld(int &NumberCount, int BaseNumber) + { + for (int n = 0; n < NumberOfParticles; n++) if (ParticleNumber[n] == INT_UNDEFINED) - ParticleNumber[n] = BaseNumber + NumberCount++; - }; + ParticleNumber[n] = BaseNumber + NumberCount++; + }; -/* Particles: Add given number to particle index. */ + /* Particles: Add given number to particle index. */ - void AddToParticleNumber(PINT *Count) { - if (MyProcessorNumber == ProcessorNumber) - for (int n = 0; n < NumberOfParticles; n++) - ParticleNumber[n] += *Count; - *Count += NumberOfParticles; - } + void AddToParticleNumber(PINT *Count) + { + if (MyProcessorNumber == ProcessorNumber) + for (int n = 0; n < NumberOfParticles; n++) + ParticleNumber[n] += *Count; + *Count += NumberOfParticles; + } - float ReturnTotalSinkMass() { + float ReturnTotalSinkMass() + { float total = 0; double dx3 = CellWidth[0][0] * CellWidth[0][0] * CellWidth[0][0]; if (MyProcessorNumber == ProcessorNumber) for (int n = 0; n < NumberOfParticles; n++) - if (ParticleType[n] == PARTICLE_TYPE_MUST_REFINE) - total += ParticleMass[n] * dx3; + if (ParticleType[n] == PARTICLE_TYPE_MUST_REFINE) + total += ParticleMass[n] * dx3; return total; }; -/* Particles: return particle type (1 - dm, 2 - star). Note that this + /* Particles: return particle type (1 - dm, 2 - star). Note that this has now been superceded by a real particle type field. */ - int ReturnParticleType(int index) { - if (NumberOfParticleAttributes > 0 && StarParticleCreation > 0) - if (ParticleAttribute[0][index] > 0) - return PARTICLE_TYPE_STAR; - return PARTICLE_TYPE_DARK_MATTER; - } + int ReturnParticleType(int index) + { + if (NumberOfParticleAttributes > 0 && StarParticleCreation > 0) + if (ParticleAttribute[0][index] > 0) + return PARTICLE_TYPE_STAR; + return PARTICLE_TYPE_DARK_MATTER; + } -/* Particles: return particle information in structure array */ + /* Particles: return particle information in structure array */ - int ReturnParticleEntry(ParticleEntry *ParticleList); + int ReturnParticleEntry(ParticleEntry *ParticleList); -/* Particles: set mass of merged particles to be -1 */ + /* Particles: set mass of merged particles to be -1 */ - void RemoveMergedParticles(ParticleEntry *List, const int &Size, int *Flag); + void RemoveMergedParticles(ParticleEntry *List, const int &Size, int *Flag); -/* Particles: append particles belonging to this grid from a list */ + /* Particles: append particles belonging to this grid from a list */ - int AddParticlesFromList(ParticleEntry *List, const int &Size, int *AddedNewParticleNumber); - int AddOneParticleFromList(ParticleEntry *List, const int place); - int CheckGridBoundaries(FLOAT *Position); + int AddParticlesFromList(ParticleEntry *List, const int &Size, int *AddedNewParticleNumber); + int AddOneParticleFromList(ParticleEntry *List, const int place); + int CheckGridBoundaries(FLOAT *Position); -/* Particles: sort particle data in ascending order by number (id) or type. */ + /* Particles: sort particle data in ascending order by number (id) or type. */ -void SortParticlesByNumber(); -void SortActiveParticlesByNumber(); -void SortParticlesByType(); + void SortParticlesByNumber(); + void SortActiveParticlesByNumber(); + void SortParticlesByType(); -int CreateParticleTypeGrouping(hid_t ptype_dset, - hid_t ptype_dspace, - hid_t parent_group, - hid_t file_id); + int CreateParticleTypeGrouping(hid_t ptype_dset, + hid_t ptype_dspace, + hid_t parent_group, + hid_t file_id); - int ChangeParticleTypeBeforeSN(int _type, int level, - int *ParticleBufferSize=NULL); + int ChangeParticleTypeBeforeSN(int _type, int level, + int *ParticleBufferSize = NULL); -// ------------------------------------------------------------------------- -// Communication functions -// + // ------------------------------------------------------------------------- + // Communication functions + // -/* Set grid's processor number. */ + /* Set grid's processor number. */ - void SetProcessorNumber(int Proc) { + void SetProcessorNumber(int Proc) + { ProcessorNumber = Proc; }; -/* Return grid's processor number. */ + /* Return grid's processor number. */ - int ReturnProcessorNumber() { + int ReturnProcessorNumber() + { return ProcessorNumber; } -/* Send a region from a real grid to a 'fake' grid on another processor. */ + /* Send a region from a real grid to a 'fake' grid on another processor. */ - int CommunicationSendRegion(grid *ToGrid, int ToProcessor, int SendField, - int NewOrOld, int RegionStart[], int RegionDim[]); + int CommunicationSendRegion(grid *ToGrid, int ToProcessor, int SendField, + int NewOrOld, int RegionStart[], int RegionDim[]); -/* Send a region from a 'fake' grid to a real grid on another processor. */ + /* Send a region from a 'fake' grid to a real grid on another processor. */ - int CommunicationReceiveRegion(grid *ToGrid, int ToProcessor, - int SendField, int NewOrOld, - int RegionStart[], int RegionDim[], - int IncludeBoundary); + int CommunicationReceiveRegion(grid *ToGrid, int ToProcessor, + int SendField, int NewOrOld, + int RegionStart[], int RegionDim[], + int IncludeBoundary); -/* Move a grid from one processor to another. */ + /* Move a grid from one processor to another. */ int CommunicationMoveGrid(int ToProcessor, int MoveParticles = TRUE, - int DeleteAllFields = TRUE, - int MoveSubgridMarker = FALSE); - -/* Send particles from one grid to another. */ - - int CommunicationSendParticles(grid *ToGrid, int ToProcessor, - int FromStart, int FromNumber, int ToStart); - -/* Transfer particle amount level 0 grids. */ - - int CommunicationTransferParticles(grid* Grids[], int NumberOfGrids, - int ThisGridNum, int TopGridDims[], - int *&NumberToMove, - int StartIndex, int EndIndex, - particle_data *&List, - int *Layout, int *GStartIndex[], - int *GridMap, int CopyDirection); - int CommunicationTransferStars(grid* Grids[], int NumberOfGrids, - int ThisGridNum, int TopGridDims[], - int *&NumberToMove, - int StartIndex, int EndIndex, - star_data *&List, int *Layout, - int *GStartIndex[], int *GridMap, - int CopyDirection); -int CommunicationTransferActiveParticles(grid* Grids[], int NumberOfGrids, - int ThisGridNum, int TopGridDims[], int *&NumberToMove, - int StartIndex, int EndIndex, ActiveParticleList &List, - int *Layout, int *GStartIndex[], int *GridMap, int CopyDirection); - - int CollectParticles(int GridNum, int* &NumberToMove, - int &StartIndex, int &EndIndex, - particle_data* &List, int CopyDirection); - int CollectActiveParticles(int GridNum, int* &NumberToMove, - int &StartIndex, int &EndIndex, - ActiveParticleList &List, int CopyDirection); - int CollectStars(int GridNum, int* &NumberToMove, - int &StartIndex, int &EndIndex, - star_data* &List, int CopyDirection); + int DeleteAllFields = TRUE, + int MoveSubgridMarker = FALSE); + + /* Send particles from one grid to another. */ + + int CommunicationSendParticles(grid *ToGrid, int ToProcessor, + int FromStart, int FromNumber, int ToStart); + + /* Transfer particle amount level 0 grids. */ + + int CommunicationTransferParticles(grid *Grids[], int NumberOfGrids, + int ThisGridNum, int TopGridDims[], + int *&NumberToMove, + int StartIndex, int EndIndex, + particle_data *&List, + int *Layout, int *GStartIndex[], + int *GridMap, int CopyDirection); + int CommunicationTransferStars(grid *Grids[], int NumberOfGrids, + int ThisGridNum, int TopGridDims[], + int *&NumberToMove, + int StartIndex, int EndIndex, + star_data *&List, int *Layout, + int *GStartIndex[], int *GridMap, + int CopyDirection); + int CommunicationTransferActiveParticles(grid *Grids[], int NumberOfGrids, + int ThisGridNum, int TopGridDims[], int *&NumberToMove, + int StartIndex, int EndIndex, ActiveParticleList &List, + int *Layout, int *GStartIndex[], int *GridMap, int CopyDirection); + + int CollectParticles(int GridNum, int *&NumberToMove, + int &StartIndex, int &EndIndex, + particle_data *&List, int CopyDirection); + int CollectActiveParticles(int GridNum, int *&NumberToMove, + int &StartIndex, int &EndIndex, + ActiveParticleList &List, int CopyDirection); + int CollectStars(int GridNum, int *&NumberToMove, + int &StartIndex, int &EndIndex, + star_data *&List, int CopyDirection); // Only used for static hierarchies int MoveSubgridStars(int NumberOfSubgrids, grid* ToGrids[], @@ -1749,12 +1821,13 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, Assumes that info is being sent from the "other-grid" processor to the "this-grid" processor (i.e. the one that holds this object). */ - int CommunicationMethodShouldExit(grid *OtherGrid) { + int CommunicationMethodShouldExit(grid *OtherGrid) + { /* Return if neither grid lives on this processor. */ // if (NumberOfProcessors == 1) return SUCCESS; - if (MyProcessorNumber != ProcessorNumber && + if (MyProcessorNumber != ProcessorNumber && MyProcessorNumber != OtherGrid->ProcessorNumber) return SUCCESS; @@ -1764,7 +1837,7 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, if (ProcessorNumber == OtherGrid->ProcessorNumber) if (CommunicationDirection == COMMUNICATION_POST_RECEIVE || - CommunicationDirection == COMMUNICATION_RECEIVE) + CommunicationDirection == COMMUNICATION_RECEIVE) return SUCCESS; /* If in send mode then exit if the send grid is not on this processor. */ @@ -1773,7 +1846,7 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, MyProcessorNumber != OtherGrid->ProcessorNumber) return SUCCESS; - /* If in either receive phase then exit if receive grid is not on this + /* If in either receive phase then exit if receive grid is not on this processor. */ if ((CommunicationDirection == COMMUNICATION_RECEIVE || @@ -1784,25 +1857,25 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, return FAIL; /* i.e. method should not exit immediately. */ } -/* Baryons: find certain commonly used variables from the list of fields. */ + /* Baryons: find certain commonly used variables from the list of fields. */ - int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, - int &Vel2Num, int &Vel3Num, int &TENum); + int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, + int &Vel2Num, int &Vel3Num, int &TENum); - int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, - int &Vel2Num, int &Vel3Num, int &TENum, int &CRNum); + int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, + int &Vel2Num, int &Vel3Num, int &TENum, int &CRNum); - int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, - int &Vel2Num, int &Vel3Num, int &TENum, - int &B1Num, int &B2Num, int &B3Num); + int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, + int &Vel2Num, int &Vel3Num, int &TENum, + int &B1Num, int &B2Num, int &B3Num); - int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, - int &Vel2Num, int &Vel3Num, int &TENum, - int &B1Num, int &B2Num, int &B3Num, int &PhiNum); + int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, + int &Vel2Num, int &Vel3Num, int &TENum, + int &B1Num, int &B2Num, int &B3Num, int &PhiNum); int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, - int &Vel2Num, int &Vel3Num, int &TENum, - int &B1Num, int &B2Num, int &B3Num, int &PhiNum, int &CRNum); + int &Vel2Num, int &Vel3Num, int &TENum, + int &B1Num, int &B2Num, int &B3Num, int &PhiNum, int &CRNum); /* Identify driving fields */ @@ -1814,61 +1887,61 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, /* Identify colour field */ - int IdentifyColourFields(int &SNColourNum, int &MetalNum, - int &MetalIaNum, int &MetalIINum, int &MBHColourNum, - int &Galaxy1ColourNum, int &Galaxy2ColourNum); + int IdentifyColourFields(int &SNColourNum, int &MetalNum, + int &MetalIaNum, int &MetalIINum, int &MBHColourNum, + int &Galaxy1ColourNum, int &Galaxy2ColourNum); /* Identify Multi-species fields. */ - int IdentifySpeciesFields(int &DeNum, int &HINum, int &HIINum, - int &HeINum, int &HeIINum, int &HeIIINum, - int &HMNum, int &H2INum, int &H2IINum, + int IdentifySpeciesFields(int &DeNum, int &HINum, int &HIINum, + int &HeINum, int &HeIINum, int &HeIIINum, + int &HMNum, int &H2INum, int &H2IINum, int &DINum, int &DIINum, int &HDINum); /* Identify shock fields. */ - int IdentifyShockSpeciesFields(int &MachNum,int &PSTempNum, int &PSDenNum); + int IdentifyShockSpeciesFields(int &MachNum, int &PSTempNum, int &PSDenNum); // Identify Simon Glover Species Fields - int IdentifyGloverSpeciesFields(int &HIINum,int &HINum,int &H2INum, - int &DINum,int &DIINum,int &HDINum, - int &HeINum,int &HeIINum,int &HeIIINum, - int &CINum,int &CIINum,int &OINum, - int &OIINum,int &SiINum,int &SiIINum, - int &SiIIINum,int &CHINum,int &CH2INum, - int &CH3IINum,int &C2INum,int &COINum, - int &HCOIINum,int &OHINum,int &H2OINum, - int &O2INum); - -/* Zeus Solver. */ - - int ZeusSolver(float *gamma, int igamfield, int nhy, - float dx[], float dy[], float dz[], - int gravity, int NumberOfSubgrids, long_int GridGlobalStart[], - fluxes *SubgridFluxes[], - int NumberOfColours, int colnum[], int bottom, - float minsupecoef); - -/* PPM Direct Euler Solver. */ - -int SolvePPM_DE(int CycleNumber, int NumberOfSubgrids, - fluxes *SubgridFluxes[], float *CellWidthTemp[], - Elong_int GridGlobalStart[], int GravityOn, - int NumberOfColours, int colnum[], - float MinimumSupportEnergyCoefficient); - -int xEulerSweep(int k, int NumberOfSubgrids, fluxes *SubgridFluxes[], - Elong_int GridGlobalStart[], float *CellWidthTemp[], - int GravityOn, int NumberOfColours, int colnum[], float *pressure); - -int yEulerSweep(int i, int NumberOfSubgrids, fluxes *SubgridFluxes[], - Elong_int GridGlobalStart[], float *CellWidthTemp[], - int GravityOn, int NumberOfColours, int colnum[], float *pressure); - -int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], - Elong_int GridGlobalStart[], float *CellWidthTemp[], - int GravityOn, int NumberOfColours, int colnum[], float *pressure); - -// AccelerationHack + int IdentifyGloverSpeciesFields(int &HIINum, int &HINum, int &H2INum, + int &DINum, int &DIINum, int &HDINum, + int &HeINum, int &HeIINum, int &HeIIINum, + int &CINum, int &CIINum, int &OINum, + int &OIINum, int &SiINum, int &SiIINum, + int &SiIIINum, int &CHINum, int &CH2INum, + int &CH3IINum, int &C2INum, int &COINum, + int &HCOIINum, int &OHINum, int &H2OINum, + int &O2INum); + + /* Zeus Solver. */ + + int ZeusSolver(float *gamma, int igamfield, int nhy, + float dx[], float dy[], float dz[], + int gravity, int NumberOfSubgrids, long_int GridGlobalStart[], + fluxes *SubgridFluxes[], + int NumberOfColours, int colnum[], int bottom, + float minsupecoef); + + /* PPM Direct Euler Solver. */ + + int SolvePPM_DE(int CycleNumber, int NumberOfSubgrids, + fluxes *SubgridFluxes[], float *CellWidthTemp[], + Elong_int GridGlobalStart[], int GravityOn, + int NumberOfColours, int colnum[], + float MinimumSupportEnergyCoefficient); + + int xEulerSweep(int k, int NumberOfSubgrids, fluxes *SubgridFluxes[], + Elong_int GridGlobalStart[], float *CellWidthTemp[], + int GravityOn, int NumberOfColours, int colnum[], float *pressure); + + int yEulerSweep(int i, int NumberOfSubgrids, fluxes *SubgridFluxes[], + Elong_int GridGlobalStart[], float *CellWidthTemp[], + int GravityOn, int NumberOfColours, int colnum[], float *pressure); + + int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], + Elong_int GridGlobalStart[], float *CellWidthTemp[], + int GravityOn, int NumberOfColours, int colnum[], float *pressure); + + // AccelerationHack int AccelerationHack; @@ -1879,47 +1952,47 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int AttachAcceleration(); int DetachAcceleration(); - int ActualFieldType[MAX_NUMBER_OF_BARYON_FIELDS]; + int ActualFieldType[MAX_NUMBER_OF_BARYON_FIELDS]; float *ActualBaryonField[MAX_NUMBER_OF_BARYON_FIELDS]; float *ActualOldBaryonField[MAX_NUMBER_OF_BARYON_FIELDS]; float *OldAccelerationField[3]; #endif -// ------------------------------------------------------------------------- -// Functions for Specific problems (usually problem generator functions). -// + // ------------------------------------------------------------------------- + // Functions for Specific problems (usually problem generator functions). + // -/* Generalized Extra Field Grid Initializer (returns NumberOfBaryonFields) */ + /* Generalized Extra Field Grid Initializer (returns NumberOfBaryonFields) */ int InitializeTestProblemGrid(int field_counter); -/* Protostellar Collapse problem: initialize grid (returns SUCCESS or FAIL) */ + /* Protostellar Collapse problem: initialize grid (returns SUCCESS or FAIL) */ int ProtostellarCollapseInitializeGrid(float CoreDensity, - float CoreEnergy, - float CoreRadius, - float AngularVelocity); + float CoreEnergy, + float CoreRadius, + float AngularVelocity); -/* HydroShockTubes problems: initialize grid (returns SUCCESS or FAIL) */ + /* HydroShockTubes problems: initialize grid (returns SUCCESS or FAIL) */ int HydroShockTubesInitializeGrid(float InitialDiscontinuity, - float LeftDensity, float RightDensity, - float LeftVelocityX, float RightVelocityX, - float LeftVelocityY, float RightVelocityY, - float LeftVelocityZ, float RightVelocityZ, - float LeftPressure, float RightPressure); + float LeftDensity, float RightDensity, + float LeftVelocityX, float RightVelocityX, + float LeftVelocityY, float RightVelocityY, + float LeftVelocityZ, float RightVelocityZ, + float LeftPressure, float RightPressure); int HydroShockTubesInitializeGrid(float InitialDiscontinuity, - float SecondDiscontinuity, - float LeftDensity, float RightDensity, - float CenterDensity, - float LeftVelocityX, float RightVelocityX, - float CenterVelocityX, - float LeftVelocityY, float RightVelocityY, - float CenterVelocityY, - float LeftVelocityZ, float RightVelocityZ, - float CenterVelocityZ, - float LeftPressure, float RightPressure, - float CenterPressure); - -/* Cosmic Ray Shock Tube Problems: Initialize grid (returns SUCCESS or FAIL) */ + float SecondDiscontinuity, + float LeftDensity, float RightDensity, + float CenterDensity, + float LeftVelocityX, float RightVelocityX, + float CenterVelocityX, + float LeftVelocityY, float RightVelocityY, + float CenterVelocityY, + float LeftVelocityZ, float RightVelocityZ, + float CenterVelocityZ, + float LeftPressure, float RightPressure, + float CenterPressure); + + /* Cosmic Ray Shock Tube Problems: Initialize grid (returns SUCCESS or FAIL) */ int CRShockTubesInitializeGrid(float InitialDiscontinuity, float LeftDensity, float RightDensity, @@ -1952,6 +2025,15 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float LeftBz, float RightBz, float CenterBz); + /* Self Force gravity test */ + + int TestSelfForceInitializeGrid(float TestParticleMass, + int NumberOfNewParticles, + float xpos, float ypos, float zpos, + float vx, float vy, float vz); + + /* Initialize for a uniform grid (returns SUCCESS or FAIL) */ + int CRTransportTestInitializeGrid(int test_type, float center, float rho, float vx, float vy, float vz, @@ -1962,63 +2044,59 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Initialize for a uniform grid (returns SUCCESS or FAIL) */ int InitializeUniformGrid(float UniformDensity, float UniformTotalEnergy, - float UniformGasEnergy, float UniformVelocity[], - float UniformBField[], float UniformCR = 0.0); - - -/* Initialize a grid for the Double Mach reflection problem. */ + float UniformGasEnergy, float UniformVelocity[], + float UniformBField[], float UniformCR = 0.0); - int DoubleMachInitializeGrid(float d0, float e0, float u0,float v0,float w0); + /* Initialize a grid for the Double Mach reflection problem. */ + int DoubleMachInitializeGrid(float d0, float e0, float u0, float v0, float w0); -/* Initialize a grid for Implosion test problem */ + /* Initialize a grid for Implosion test problem */ int ImplosionInitializeGrid(float ImplosionDiamondDensity, - float ImplosionDiamondTotalEnergy); + float ImplosionDiamondTotalEnergy); - -/* Initialize a grid for Sedov Explosion */ + /* Initialize a grid for Sedov Explosion */ int SedovBlastInitializeGrid(float SedovBlastInitialRadius, float SedovBlastInnerTotalEnergy); - int SedovBlastInitializeGrid3D(char * fname); + int SedovBlastInitializeGrid3D(char *fname); int SedovBlastInitializeGrid3DFixedR(float dr); - -/* Initialize a grid for RadiatingShock (Sedov+Cooling) Explosion */ + /* Initialize a grid for RadiatingShock (Sedov+Cooling) Explosion */ int RadiatingShockInitializeGrid(FLOAT RadiatingShockInitialRadius, - float RadiatingShockInnerDensity, - float RadiatingShockInnerTotalEnergy, - int RadiatingShockUseDensityFluctuations, - int RadiatingShockRandomSeed, - float RadiatingShockDensityFluctuationLevel, - int RadiatingShockInitializeWithKE, - int RadiatingShockUseSedovProfile, - FLOAT RadiatingShockSedovBlastRadius, - float RadiatingShockEnergy, - float RadiatingShockPressure, - float RadiatingShockKineticEnergyFraction, - float RadiatingShockRhoZero, - float RadiatingShockVelocityZero, - int RadiatingShockRandomSeedInitialize, - FLOAT RadiatingShockCenterPosition[MAX_DIMENSION]); + float RadiatingShockInnerDensity, + float RadiatingShockInnerTotalEnergy, + int RadiatingShockUseDensityFluctuations, + int RadiatingShockRandomSeed, + float RadiatingShockDensityFluctuationLevel, + int RadiatingShockInitializeWithKE, + int RadiatingShockUseSedovProfile, + FLOAT RadiatingShockSedovBlastRadius, + float RadiatingShockEnergy, + float RadiatingShockPressure, + float RadiatingShockKineticEnergyFraction, + float RadiatingShockRhoZero, + float RadiatingShockVelocityZero, + int RadiatingShockRandomSeedInitialize, + FLOAT RadiatingShockCenterPosition[MAX_DIMENSION]); /* Initialize a grid for a rotating cylinder collapse */ int RotatingCylinderInitializeGrid(FLOAT RotatingCylinderRadius, - FLOAT RotatingCylinderCenterPosition[MAX_DIMENSION], - float RotatingCylinderLambda, - float RotatingCylinderOverdensity); + FLOAT RotatingCylinderCenterPosition[MAX_DIMENSION], + float RotatingCylinderLambda, + float RotatingCylinderOverdensity); int RotatingDiskInitializeGrid(float RDScaleRadius, - float RDScaleHeight, - float RDTemperature, - float RDDMConcentration, - float RDTotalDMMass, - float RDCentralDensity, - float RDOuterEdge); + float RDScaleHeight, + float RDTemperature, + float RDDMConcentration, + float RDTotalDMMass, + float RDCentralDensity, + float RDOuterEdge); int RotatingSphereInitializeGrid(float RotatingSphereNFWMass, float RotatingSphereNFWConcentration, @@ -2030,7 +2108,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float RotatingSphereSpinParameter, float RotatingSphereAngularMomentumExponent, int RotatingSphereUseTurbulence, - float RotatingSphereTurbulenceRMS, + float RotatingSphereTurbulenceRMS, float RotatingSphereRedshift); /* Initialize a grid for the KH instability problem. */ @@ -2042,7 +2120,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float KHInnerVx, float KHOuterVx, float KHInnerPressure, float KHOuterPressure, - int KHRandomSeed); + int KHRandomSeed); /* Initialize a grid for the KH instability problem including a ramp. */ @@ -2061,361 +2139,380 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int NohInitializeGrid(float d0, float p0, float u0); int ComputeExternalNohBoundary(); -/* Zeldovich Pancake: initial grid (returns SUCCESS or FAIL). */ + /* Zeldovich Pancake: initial grid (returns SUCCESS or FAIL). */ - int ZeldovichPancakeInitializeGrid(int ZeldovichPancakeDirection, - float ZeldovichPancakeCentralOffset, - float ZeldovichPancakeOmegaBaryonNow, - float ZeldovichPancakeOmegaCDMNow, - float ZeldovichPancakeCollapseRedshift, - float ZeldovichPancakeInitialTemperature, - float ZeldovichPancakeInitialGasVelocity, - float ZeldovichPancakeInitialUniformBField[]); + int ZeldovichPancakeInitializeGrid(int ZeldovichPancakeDirection, + float ZeldovichPancakeCentralOffset, + float ZeldovichPancakeOmegaBaryonNow, + float ZeldovichPancakeOmegaCDMNow, + float ZeldovichPancakeCollapseRedshift, + float ZeldovichPancakeInitialTemperature, + float ZeldovichPancakeInitialGasVelocity, + float ZeldovichPancakeInitialUniformBField[]); -/* 1D Pressureless Collapse: initialize grid. */ + /* 1D Pressureless Collapse: initialize grid. */ int PressurelessCollapseInitializeGrid(int PressurelessCollapseDirection, - float PressurelessCollapseInitialDensity, - int PressurelessCollapseNumberOfCells); + float PressurelessCollapseInitialDensity, + int PressurelessCollapseNumberOfCells); -/* Gravity Test: particles in isolated boundaries */ + /* Gravity Test: particles in isolated boundaries */ int TestOrbitInitializeGrid(int NumberOfTestParticles, - FLOAT TestRadius, - float CentralMass, - float TestMass, - int UseBaryons); + FLOAT TestRadius, + float CentralMass, + float TestMass, + int UseBaryons); -/* Star Particle test: initialize particle */ - int TestStarParticleInitializeGrid(float TestStarParticleStarMass, - float *Initialdt, - FLOAT TestStarParticleStarVelocity[], - FLOAT TestStarParticleStarPosition[]); + /* Star Particle test: initialize particle */ + int TestStarParticleInitializeGrid(float TestStarParticleStarMass, + float *Initialdt, + FLOAT TestStarParticleStarVelocity[], + FLOAT TestStarParticleStarPosition[]); -/* Gravity Test: initialize grid. */ + /* Gravity Test: initialize grid. */ - int TestGravityInitializeGrid(float CentralDensity, - int NumberOfNewParticles, int UseBaryons); + int TestGravityInitializeGrid(float CentralDensity, + int NumberOfNewParticles, int UseBaryons); -/* Gravity Test: check results. */ + /* Gravity Test: initialize grid. APM version */ + int TestGravityAPMInitializeGrid(float CentralDensity, + int NumberOfNewParticles, + float *CentralParticlePosition, + int UseBaryons); + /* Gravity Test: check results. */ int TestGravityCheckResults(FILE *fptr, grid *TopGrid); -/* Gravity Test Motion: initialize grid. */ + /* Gravity Test: check results. APM version */ + int TestGravityAPMCheckResults(FILE *fptr, grid *TopGrid, int level); + + /* Gravity Test Motion: initialize grid. */ int TestGravityMotionInitializeGrid(float InitialVelocity); -/* Gravity Test (Sphere): initialize grid. */ + /* Gravity Test (Sphere): initialize grid. */ - int TestGravitySphereInitializeGrid(float InteriorDensity, - float ExteriorDensity, - float SphereRadius, - int SphereType, int UseBaryons, - FLOAT SphereCenter[]); + int TestGravitySphereInitializeGrid(float InteriorDensity, + float ExteriorDensity, + float SphereRadius, + int SphereType, int UseBaryons, + FLOAT SphereCenter[]); -/* Gravity Test (Sphere): check results. */ + /* Gravity Test (Sphere): initialize grid. APM version */ + int TestGravitySphereAPMInitializeGrid(float InteriorDensity, + float ExteriorDensity, + float SphereRadius, + int SphereType, int UseBaryons, + FLOAT SphereCenter[]); + /* Gravity Test (Sphere): check results. */ int TestGravitySphereCheckResults(FILE *fptr); -/* Conduction Test: initialize grid. */ + /* Gravity Test (Sine Wave): initialize grid */ + int TestGravitySineWaveInitializeGrid(float Amplitude, + float Period, + float Angle, + int TestGravitySineWaveSubgridsAreStatic, + int TotalRefinement, + int grid_num); + + /* Conduction Test: initialize grid. */ int ConductionTestInitialize(float PulseHeight, FLOAT PulseWidth, int PulseType, FLOAT PulseCenter[MAX_DIMENSION], int FieldGeometry, float Bfield); -/* Conduction Cloud: initialize grid. */ + /* Conduction Cloud: initialize grid. */ int ConductionCloudInitialize(float CloudOverdensity, FLOAT CloudWidth, int CloudType); -/* Conducting Bubble Test: initialize grid. */ + /* Conducting Bubble Test: initialize grid. */ - int ConductionBubbleInitialize(FLOAT BubbleRadius, int PulseType, float DeltaEntropy, - float MidpointEntropy, float EntropyGradient, - float MidpointTemperature, FLOAT BubbleCenter[MAX_DIMENSION]); + int ConductionBubbleInitialize(FLOAT BubbleRadius, int PulseType, float DeltaEntropy, + float MidpointEntropy, float EntropyGradient, + float MidpointTemperature, FLOAT BubbleCenter[MAX_DIMENSION]); -/* Exploding Stratified Medium Test: initialize grid. */ + /* Exploding Stratified Medium Test: initialize grid. */ int StratifiedMediumExplosionInitialize(FLOAT BubbleRadius, int PulseType, - float ExplosionEnergy, FLOAT BubbleCenter[MAX_DIMENSION]); + float ExplosionEnergy, FLOAT BubbleCenter[MAX_DIMENSION]); -/* Spherical Infall Test: initialize grid. */ + /* Spherical Infall Test: initialize grid. */ int SphericalInfallInitializeGrid(float InitialPerturbation, int UseBaryons, - float SphericalInfallOmegaBaryonNow, - float SphericalInfallOmegaCDMNow, - int SubgridIsStatic); - + float SphericalInfallOmegaBaryonNow, + float SphericalInfallOmegaCDMNow, + int SubgridIsStatic); -/* Spherical Infall Test: get the profile from the center. */ + /* Spherical Infall Test: get the profile from the center. */ int SphericalInfallGetProfile(int level, int ReportLevel); -/* GravityEquilibriumTest: initialize grid. */ + /* GravityEquilibriumTest: initialize grid. */ int GravityEquilibriumTestInitializeGrid(float ScaleHeight); -/* CollapseTest: initialize grid. */ + /* CollapseTest: initialize grid. */ #define MAX_SPHERES 10 int CollapseTestInitializeGrid(int NumberOfSpheres, - FLOAT SphereRadius[MAX_SPHERES], - FLOAT SphereCoreRadius[MAX_SPHERES], - float SphereDensity[MAX_SPHERES], - float SphereTemperature[MAX_SPHERES], - float SphereMetallicity[MAX_SPHERES], - FLOAT SpherePosition[MAX_SPHERES][MAX_DIMENSION], - float SphereVelocity[MAX_SPHERES][MAX_DIMENSION], - float SphereFracKeplarianRot[MAX_SPHERES], - float SphereTurbulence[MAX_SPHERES], - float SphereDispersion[MAX_SPHERES], - float SphereCutOff[MAX_SPHERES], - float SphereAng1[MAX_SPHERES], - float SphereAng2[MAX_SPHERES], - int SphereNumShells[MAX_SPHERES], - int SphereType[MAX_SPHERES], - int SphereConstantPressure[MAX_SPHERES], - int SphereSmoothSurface[MAX_SPHERES], - float SphereSmoothRadius[MAX_SPHERES], - float SphereHII[MAX_SPHERES], - float SphereHeII[MAX_SPHERES], - float SphereHeIII[MAX_SPHERES], - float SphereH2I[MAX_SPHERES], - int SphereUseParticles, - float ParticleMeanDensity, - float UniformVelocity[MAX_DIMENSION], - int SphereUseColour, - int SphereUseMetals, - float InitialTemperature, - float InitialDensity, int level, - float CollapseTestInitialFractionHII, - float CollapseTestInitialFractionHeII, - float CollapseTestInitialFractionHeIII, - float CollapseTestInitialFractionHM, - float CollapseTestInitialFractionH2I, - float CollapseTestInitialFractionH2II); - - -/* Cluster: initialize grid. */ + FLOAT SphereRadius[MAX_SPHERES], + FLOAT SphereCoreRadius[MAX_SPHERES], + float SphereDensity[MAX_SPHERES], + float SphereTemperature[MAX_SPHERES], + float SphereMetallicity[MAX_SPHERES], + FLOAT SpherePosition[MAX_SPHERES][MAX_DIMENSION], + float SphereVelocity[MAX_SPHERES][MAX_DIMENSION], + float SphereFracKeplarianRot[MAX_SPHERES], + float SphereTurbulence[MAX_SPHERES], + float SphereDispersion[MAX_SPHERES], + float SphereCutOff[MAX_SPHERES], + float SphereAng1[MAX_SPHERES], + float SphereAng2[MAX_SPHERES], + int SphereNumShells[MAX_SPHERES], + int SphereType[MAX_SPHERES], + int SphereConstantPressure[MAX_SPHERES], + int SphereSmoothSurface[MAX_SPHERES], + float SphereSmoothRadius[MAX_SPHERES], + float SphereHII[MAX_SPHERES], + float SphereHeII[MAX_SPHERES], + float SphereHeIII[MAX_SPHERES], + float SphereH2I[MAX_SPHERES], + int SphereUseParticles, + float ParticleMeanDensity, + float UniformVelocity[MAX_DIMENSION], + int SphereUseColour, + int SphereUseMetals, + float InitialTemperature, + float InitialDensity, int level, + float CollapseTestInitialFractionHII, + float CollapseTestInitialFractionHeII, + float CollapseTestInitialFractionHeIII, + float CollapseTestInitialFractionHM, + float CollapseTestInitialFractionH2I, + float CollapseTestInitialFractionH2II); + + /* Cluster: initialize grid. */ int ClusterInitializeGrid(int NumberOfSpheres, - FLOAT SphereRadius[MAX_SPHERES], - FLOAT SphereCoreRadius[MAX_SPHERES], - float SphereDensity[MAX_SPHERES], - float SphereTemperature[MAX_SPHERES], - FLOAT SpherePosition[MAX_SPHERES][MAX_DIMENSION], - float SphereVelocity[MAX_SPHERES][MAX_DIMENSION], - int SphereType[MAX_SPHERES], - int SphereUseParticles, - float UniformVelocity[MAX_DIMENSION], - int SphereUseColour, - float InitialTemperature, - float ClusterInitialSpinParameter, int level); + FLOAT SphereRadius[MAX_SPHERES], + FLOAT SphereCoreRadius[MAX_SPHERES], + float SphereDensity[MAX_SPHERES], + float SphereTemperature[MAX_SPHERES], + FLOAT SpherePosition[MAX_SPHERES][MAX_DIMENSION], + float SphereVelocity[MAX_SPHERES][MAX_DIMENSION], + int SphereType[MAX_SPHERES], + int SphereUseParticles, + float UniformVelocity[MAX_DIMENSION], + int SphereUseColour, + float InitialTemperature, + float ClusterInitialSpinParameter, int level); /* CosmologySimulation: initialize grid. */ int CosmologySimulationInitializeGrid( - int InitialGridNumber, - float CosmologySimulationOmegaBaryonNow, - float CosmologySimulationOmegaCDMNow, - float CosmologySimulationInitialTemperature, - char *CosmologySimulationDensityName, - char *CosmologySimulationTotalEnergyName, - char *CosmologySimulationGasEnergyName, - char *CosmologySimulationVelocityNames[], - char *CosmologySimulationParticlePositionName, - char *CosmologySimulationParticleVelocityName, - char *CosmologySimulationParticleDisplacementName, - char *CosmologySimulationParticleMassName, - char *CosmologySimulationParticleTypeName, - char *CosmologySimulationParticlePositionNames[], - char *CosmologySimulationParticleVelocityNames[], - char *CosmologySimulationParticleDisplacementNames[], - int CosmologySimulationSubgridsAreStatic, - int TotalRefinement, - float CosmologySimulationInitialFractionHII, - float CosmologySimulationInitialFractionHeII, - float CosmologySimulationInitialFractionHeIII, - float CosmologySimulationInitialFractionHM, - float CosmologySimulationInitialFractionH2I, - float CosmologySimulationInitialFractionH2II, - float CosmologySimulationInitialFractionMetal, - float CosmologySimulationInitialFractionMetalIa, + int InitialGridNumber, + float CosmologySimulationOmegaBaryonNow, + float CosmologySimulationOmegaCDMNow, + float CosmologySimulationInitialTemperature, + char *CosmologySimulationDensityName, + char *CosmologySimulationTotalEnergyName, + char *CosmologySimulationGasEnergyName, + char *CosmologySimulationVelocityNames[], + char *CosmologySimulationParticlePositionName, + char *CosmologySimulationParticleVelocityName, + char *CosmologySimulationParticleDisplacementName, + char *CosmologySimulationParticleMassName, + char *CosmologySimulationParticleTypeName, + char *CosmologySimulationParticlePositionNames[], + char *CosmologySimulationParticleVelocityNames[], + char *CosmologySimulationParticleDisplacementNames[], + int CosmologySimulationSubgridsAreStatic, + int TotalRefinement, + float CosmologySimulationInitialFractionHII, + float CosmologySimulationInitialFractionHeII, + float CosmologySimulationInitialFractionHeIII, + float CosmologySimulationInitialFractionHM, + float CosmologySimulationInitialFractionH2I, + float CosmologySimulationInitialFractionH2II, + float CosmologySimulationInitialFractionMetal, + float CosmologySimulationInitialFractionMetalIa, #ifdef TRANSFER - float RadHydroInitialRadiationEnergy, + float RadHydroInitialRadiationEnergy, #endif - int CosmologySimulationUseMetallicityField, - PINT &CurrentNumberOfParticles, - int CosmologySimulationManuallySetParticleMassRatio, - float CosmologySimulationManualParticleMassRatio, - int CosmologySimulationCalculatePositions, - float CosmologySimulationInitialUniformBField[]); + int CosmologySimulationUseMetallicityField, + PINT &CurrentNumberOfParticles, + int CosmologySimulationManuallySetParticleMassRatio, + float CosmologySimulationManualParticleMassRatio, + int CosmologySimulationCalculatePositions, + float CosmologySimulationInitialUniformBField[]); int CosmologyReadParticles3D( - char *CosmologySimulationParticleVelocityName, - char *CosmologySimulationParticleMassName, - char *CosmologySimulationParticleTypeName, - char *CosmologySimulationParticleParticleNames[], - char *CosmologySimulationParticleVelocityNames[], - float CosmologySimulationOmegaBaryonNow, - int *Offset, int level); + char *CosmologySimulationParticleVelocityName, + char *CosmologySimulationParticleMassName, + char *CosmologySimulationParticleTypeName, + char *CosmologySimulationParticleParticleNames[], + char *CosmologySimulationParticleVelocityNames[], + float CosmologySimulationOmegaBaryonNow, + int *Offset, int level); int CosmologyInitializeParticles( - char *CosmologySimulationParticleVelocityName, - char *CosmologySimulationParticleDisplacementName, - char *CosmologySimulationParticleMassName, - char *CosmologySimulationParticleTypeName, - char *CosmologySimulationParticleVelocityNames[], - char *CosmologySimulationParticleDisplacementNames[], - float CosmologySimulationOmegaBaryonNow, - int *Offset, int level); + char *CosmologySimulationParticleVelocityName, + char *CosmologySimulationParticleDisplacementName, + char *CosmologySimulationParticleMassName, + char *CosmologySimulationParticleTypeName, + char *CosmologySimulationParticleVelocityNames[], + char *CosmologySimulationParticleDisplacementNames[], + float CosmologySimulationOmegaBaryonNow, + int *Offset, int level); /* CosmologySimulation: initialize partitioned nested grids. */ int NestedCosmologySimulationInitializeGrid( - int InitialGridNumber, - float CosmologySimulationOmegaBaryonNow, - float CosmologySimulationOmegaCDMNow, - float CosmologySimulationInitialTemperature, - char *CosmologySimulationDensityName, - char *CosmologySimulationTotalEnergyName, - char *CosmologySimulationGasEnergyName, - char *CosmologySimulationVelocityNames[], - char *CosmologySimulationParticlePositionName, - char *CosmologySimulationParticleDisplacementName, - char *CosmologySimulationParticleVelocityName, - char *CosmologySimulationParticleMassName, - char *CosmologySimulationParticleTypeName, - char *CosmologySimulationParticleVelocityNames[], - char *CosmologySimulationParticleDisplacementNames[], - int CosmologySimulationSubgridsAreStatic, - int TotalRefinement, - float CosmologySimulationInitialFractionHII, - float CosmologySimulationInitialFractionHeII, - float CosmologySimulationInitialFractionHeIII, - float CosmologySimulationInitialFractionHM, - float CosmologySimulationInitialFractionH2I, - float CosmologySimulationInitialFractionH2II, - float CosmologySimulationInitialFractionMetal, - float CosmologySimulationInitialFractionMetalIa, - int CosmologySimulationUseMetallicityField, - PINT &CurrentNumberOfParticles, - int CosmologySimulationManuallySetParticleMassRatio, - float CosmologySimulationManualParticleMassRatio, - int CosmologySimulationCalculatePositions, - FLOAT SubDomainLeftEdge[], - FLOAT SubDomainRightEdge[], - float CosmologySimulationInitialUniformBField[]); - + int InitialGridNumber, + float CosmologySimulationOmegaBaryonNow, + float CosmologySimulationOmegaCDMNow, + float CosmologySimulationInitialTemperature, + char *CosmologySimulationDensityName, + char *CosmologySimulationTotalEnergyName, + char *CosmologySimulationGasEnergyName, + char *CosmologySimulationVelocityNames[], + char *CosmologySimulationParticlePositionName, + char *CosmologySimulationParticleDisplacementName, + char *CosmologySimulationParticleVelocityName, + char *CosmologySimulationParticleMassName, + char *CosmologySimulationParticleTypeName, + char *CosmologySimulationParticleVelocityNames[], + char *CosmologySimulationParticleDisplacementNames[], + int CosmologySimulationSubgridsAreStatic, + int TotalRefinement, + float CosmologySimulationInitialFractionHII, + float CosmologySimulationInitialFractionHeII, + float CosmologySimulationInitialFractionHeIII, + float CosmologySimulationInitialFractionHM, + float CosmologySimulationInitialFractionH2I, + float CosmologySimulationInitialFractionH2II, + float CosmologySimulationInitialFractionMetal, + float CosmologySimulationInitialFractionMetalIa, + int CosmologySimulationUseMetallicityField, + PINT &CurrentNumberOfParticles, + int CosmologySimulationManuallySetParticleMassRatio, + float CosmologySimulationManualParticleMassRatio, + int CosmologySimulationCalculatePositions, + FLOAT SubDomainLeftEdge[], + FLOAT SubDomainRightEdge[], + float CosmologySimulationInitialUniformBField[]); /* Initialization for isolated galaxy sims */ int GalaxySimulationInitializeGrid( - FLOAT DiskRadius, - float GalaxyMass, - float GasMass, - FLOAT DiskPosition[MAX_DIMENSION], - FLOAT ScaleHeightz, - FLOAT ScaleHeightR, - FLOAT GalaxyTruncationRadius, - float DMConcentration, - float DiskTemperature, - float InitialTemperature, - float UniformDensity, - int GasHalo, - float GasHaloScaleRadius, - float GasHaloDensity, - float AngularMomentum[MAX_DIMENSION], - float UniformVelocity[MAX_DIMENSION], - int UseMetallicityField, - float GalaxySimulationInflowTime, - float GalaxySimulationInflowDensity, - int level, - float GalaxySimulationCR = 0.0 ); + FLOAT DiskRadius, + float GalaxyMass, + float GasMass, + FLOAT DiskPosition[MAX_DIMENSION], + FLOAT ScaleHeightz, + FLOAT ScaleHeightR, + FLOAT GalaxyTruncationRadius, + float DMConcentration, + float DiskTemperature, + float InitialTemperature, + float UniformDensity, + int GasHalo, + float GasHaloScaleRadius, + float GasHaloDensity, + float AngularMomentum[MAX_DIMENSION], + float UniformVelocity[MAX_DIMENSION], + int UseMetallicityField, + float GalaxySimulationInflowTime, + float GalaxySimulationInflowDensity, + int level, + float GalaxySimulationCR = 0.0); /* Free expansion test */ int FreeExpansionInitializeGrid(int FreeExpansionFullBox, - float FreeExpansionDensity, - double FreeExpansionEnergy, - float FreeExpansionMaxVelocity, - float FreeExpansionMass, - float FreeExpansionRadius, - float DensityUnits, float VelocityUnits, - float LengthUnits, float TimeUnits); + float FreeExpansionDensity, + double FreeExpansionEnergy, + float FreeExpansionMaxVelocity, + float FreeExpansionMass, + float FreeExpansionRadius, + float DensityUnits, float VelocityUnits, + float LengthUnits, float TimeUnits); /* Supernova restart initialize grid. */ int SupernovaRestartInitialize(float EjectaDensity, float EjectaRadius, - float EjectaThermalEnergy, - FLOAT EjectaCenter[3], int ColourField, - int *NumberOfCellsSet); + float EjectaThermalEnergy, + FLOAT EjectaCenter[3], int ColourField, + int *NumberOfCellsSet); /* Put Sink restart initialize grid. */ - int PutSinkRestartInitialize(int level ,int *NumberOfCellsSet); + int PutSinkRestartInitialize(int level, int *NumberOfCellsSet); /* PhotonTest restart initialize grid. */ - int PhotonTestRestartInitialize(int level ,int *NumberOfCellsSet); + int PhotonTestRestartInitialize(int level, int *NumberOfCellsSet); /* Free-streaming radiation test problem: initialize grid (SUCCESS or FAIL) */ - int FSMultiSourceInitializeGrid(float DensityConst, float V0Const, - float V1Const, float V2Const, float TEConst, - float RadConst, int local); + int FSMultiSourceInitializeGrid(float DensityConst, float V0Const, + float V1Const, float V2Const, float TEConst, + float RadConst, int local); /* FLD Radiation test problem: initialize grid (SUCCESS or FAIL) */ - int RadHydroConstTestInitializeGrid(int NumChem, float DensityConst, - float V0Const, float V1Const, - float V2Const, float IEConst, - float EgConst, float HMassFrac, - float InitFracHII, float InitFracHeII, - float InitFracHeIII, int local); + int RadHydroConstTestInitializeGrid(int NumChem, float DensityConst, + float V0Const, float V1Const, + float V2Const, float IEConst, + float EgConst, float HMassFrac, + float InitFracHII, float InitFracHeII, + float InitFracHeIII, int local); /* FLD Radiation ionization test problem: initialize grid (SUCCESS or FAIL) */ - int RHIonizationTestInitializeGrid(int NumChem, float DensityConst, - float V0Const, float V1Const, - float V2Const, float IEConst, - float EgConst, float HMassFrac, - float InitFracHII, float InitFracHeII, - float InitFracHeIII, int local); + int RHIonizationTestInitializeGrid(int NumChem, float DensityConst, + float V0Const, float V1Const, + float V2Const, float IEConst, + float EgConst, float HMassFrac, + float InitFracHII, float InitFracHeII, + float InitFracHeIII, int local); /* FLD Radiation clump ionization problem: initialize grid (SUCCESS or FAIL) */ - int RHIonizationClumpInitializeGrid(int NumChem, float NumDensityIn, - float NumDensityOut, float V0Const, - float V1Const, float V2Const, - float IEConstIn, float IEConstOut, - float EgConst, float HMassFrac, - float InitFracHII, float InitFracHeII, - float InitFracHeIII, float ClumpCenterX0, - float ClumpCenterX1, float ClumpCenterX2, - float ClumpRadius, int local); + int RHIonizationClumpInitializeGrid(int NumChem, float NumDensityIn, + float NumDensityOut, float V0Const, + float V1Const, float V2Const, + float IEConstIn, float IEConstOut, + float EgConst, float HMassFrac, + float InitFracHII, float InitFracHeII, + float InitFracHeIII, float ClumpCenterX0, + float ClumpCenterX1, float ClumpCenterX2, + float ClumpRadius, int local); /* FLD Rad r^{-2} density ionization problem: initialize grid (SUCCESS or FAIL) */ - int RHIonizationSteepInitializeGrid(int NumChem, float NumDensity, - float DensityRadius, float DensityCenter0, - float DensityCenter1, float DensityCenter2, - float V0Const, float V1Const, - float V2Const, float IEConst, - float EgConst, float HMassFrac, - float InitFracHII, float InitFracHeII, - float InitFracHeIII, int local); + int RHIonizationSteepInitializeGrid(int NumChem, float NumDensity, + float DensityRadius, float DensityCenter0, + float DensityCenter1, float DensityCenter2, + float V0Const, float V1Const, + float V2Const, float IEConst, + float EgConst, float HMassFrac, + float InitFracHII, float InitFracHeII, + float InitFracHeIII, int local); /* FLD Radiation test problem: cosmological HII ioniztion (SUCCESS or FAIL) */ - int CosmoIonizationInitializeGrid(int NumChem, float VxConst, float VyConst, - float VzConst, float IEConst, - float EgConst, float HMassFrac, - float InitFracHII, float InitFracHeII, - float InitFracHeIII, float OmegaBaryonNow, - int local); + int CosmoIonizationInitializeGrid(int NumChem, float VxConst, float VyConst, + float VzConst, float IEConst, + float EgConst, float HMassFrac, + float InitFracHII, float InitFracHeII, + float InitFracHeIII, float OmegaBaryonNow, + int local); /* FLD Radiation test problem: stream test (SUCCESS or FAIL) */ int RadHydroStreamTestInitializeGrid(float DensityConst, float EgConst, - int RadStreamDim, int RadStreamDir, - int local); + int RadStreamDim, int RadStreamDir, + int local); /* FLD Radiation test problem: pulse test (SUCCESS or FAIL) */ int RadHydroPulseTestInitializeGrid(float DensityConst, float EgConst, - int RadPulseDim, int local); + int RadPulseDim, int local); /* FLD Radiation test problem: grey Marshak wave test (SUCCESS or FAIL) */ - int RadHydroGreyMarshakWaveInitializeGrid(float DensityConst, float IEConst, - float EgConst, int GreyMarshDir, - int local); + int RadHydroGreyMarshakWaveInitializeGrid(float DensityConst, float IEConst, + float EgConst, int GreyMarshDir, + int local); /* FLD Radiation test problem: radiating shock test (SUCCESS or FAIL) */ - int RadHydroRadShockInitializeGrid(float DensityConst, float TEConst, - float REConst, float VelocityConst, + int RadHydroRadShockInitializeGrid(float DensityConst, float TEConst, + float REConst, float VelocityConst, int ShockDir, int local); /* Cooling test initialization */ @@ -2426,23 +2523,30 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* One-zone free-fall test initialization */ int OneZoneFreefallTestInitializeGrid(float InitialDensity, - float MinimumTemperature, - float MaximumTemperature, - float MinimumMetallicity, - float MaximumMetallicity); + float MinimumTemperature, + float MaximumTemperature, + float MinimumMetallicity, + float MaximumMetallicity); /* Solve free-fall analytical solution. */ int SolveOneZoneFreefall(); -/* Tricks for Random Forcing. */ + /* Tricks for Random Forcing. */ - int ReturnNumberOfBaryonFields(){return NumberOfBaryonFields;}; + int ReturnNumberOfBaryonFields() + { + return NumberOfBaryonFields; + }; int SetNumberOfBaryonFields(int &number) - {NumberOfBaryonFields = number; return 0;}; + { + NumberOfBaryonFields = number; + return 0; + }; int AppendForcingToBaryonFields(); int DetachForcingFromBaryonFields(); int RemoveForcingFromBaryonFields(); - int AllocateAndZeroBaryonField() { + int AllocateAndZeroBaryonField() + { if (MyProcessorNumber != ProcessorNumber) return SUCCESS; @@ -2451,150 +2555,149 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int size = this->GetGridSize(); - for (int field = 0; field < NumberOfBaryonFields; field++) { + for (int field = 0; field < NumberOfBaryonFields; field++) + { BaryonField[field] = new float[size](); } return SUCCESS; }; - int AddRandomForcing(float * norm, float dtTopGrid); - int PrepareRandomForcingNormalization(float * GlobVal, int GlobNum); + int AddRandomForcing(float *norm, float dtTopGrid); + int PrepareRandomForcingNormalization(float *GlobVal, int GlobNum); int ReadRandomForcingFields(FILE *main_file_pointer, char DataFilename[]); int AddFields(int TypesToAdd[], int NumberOfFields); - int DeleteObsoleteFields(int *ObsoleteFields, - int NumberOfObsoleteFields); - - inline bool isLocal () {return MyProcessorNumber == ProcessorNumber; }; - - private: -// int ReadRandomForcingFields(FILE *main_file_pointer); - public: - -/* TurbulenceSimulation: initialize grid. */ - -#define TURBULENCE_INIT_PARAMETERS_DECL \ - float TurbulenceSimulationInitialDensity, \ - float TurbulenceSimulationInitialDensityPerturbationAmplitude, \ - float TurbulenceSimulationInitialTemperature, \ - float TurbulenceSimulationInitialPressure, \ - float TurbulenceSimulationInitialMagneticField[], \ - char *TurbulenceSimulationMagneticNames[], \ - char *TurbulenceSimulationDensityName, \ - char *TurbulenceSimulationTotalEnergyName, \ - char *TurbulenceSimulationGasPressureName, \ - char *TurbulenceSimulationGasEnergyName, \ - char *TurbulenceSimulationVelocityNames[], \ - char *TurbulenceSimulationRandomForcingNames[], \ - int TurbulenceSimulationSubgridsAreStatic, \ - int TotalRefinement - - -#define TURBULENCE_INIT_PARAMETERS \ - TurbulenceSimulationInitialDensity, \ - TurbulenceSimulationInitialDensityPerturbationAmplitude, \ - TurbulenceSimulationInitialTemperature, \ - TurbulenceSimulationInitialPressure, \ - TurbulenceSimulationInitialMagneticField, \ - TurbulenceSimulationMagneticNames, \ - TurbulenceSimulationDensityName, \ - TurbulenceSimulationTotalEnergyName, \ - TurbulenceSimulationGasPressureName, \ - TurbulenceSimulationGasEnergyName, \ - TurbulenceSimulationVelocityNames, \ - TurbulenceSimulationRandomForcingNames, \ - TurbulenceSimulationSubgridsAreStatic, \ - TotalRefinement - - - int TurbulenceSimulationInitializeGrid(TURBULENCE_INIT_PARAMETERS_DECL); - int ComputeRandomForcingFields(int mode); - int ExtraFunction(char * message); //for debugging. + int DeleteObsoleteFields(int *ObsoleteFields, + int NumberOfObsoleteFields); + + inline bool isLocal() + { + return MyProcessorNumber == ProcessorNumber; + }; + +private: + // int ReadRandomForcingFields(FILE *main_file_pointer); +public: + /* TurbulenceSimulation: initialize grid. */ + +#define TURBULENCE_INIT_PARAMETERS_DECL \ + float TurbulenceSimulationInitialDensity, \ + float TurbulenceSimulationInitialDensityPerturbationAmplitude, \ + float TurbulenceSimulationInitialTemperature, \ + float TurbulenceSimulationInitialPressure, \ + float TurbulenceSimulationInitialMagneticField[], \ + char *TurbulenceSimulationMagneticNames[], \ + char *TurbulenceSimulationDensityName, \ + char *TurbulenceSimulationTotalEnergyName, \ + char *TurbulenceSimulationGasPressureName, \ + char *TurbulenceSimulationGasEnergyName, \ + char *TurbulenceSimulationVelocityNames[], \ + char *TurbulenceSimulationRandomForcingNames[], \ + int TurbulenceSimulationSubgridsAreStatic, \ + int TotalRefinement + +#define TURBULENCE_INIT_PARAMETERS \ + TurbulenceSimulationInitialDensity, \ + TurbulenceSimulationInitialDensityPerturbationAmplitude, \ + TurbulenceSimulationInitialTemperature, \ + TurbulenceSimulationInitialPressure, \ + TurbulenceSimulationInitialMagneticField, \ + TurbulenceSimulationMagneticNames, \ + TurbulenceSimulationDensityName, \ + TurbulenceSimulationTotalEnergyName, \ + TurbulenceSimulationGasPressureName, \ + TurbulenceSimulationGasEnergyName, \ + TurbulenceSimulationVelocityNames, \ + TurbulenceSimulationRandomForcingNames, \ + TurbulenceSimulationSubgridsAreStatic, \ + TotalRefinement + + int TurbulenceSimulationInitializeGrid(TURBULENCE_INIT_PARAMETERS_DECL); + int ComputeRandomForcingFields(int mode); + int ExtraFunction(char *message); //for debugging. // The following are private since they should only be called by // TurbulenceSimulationInitializeGrid() - private: -// int TurbulenceSimulationInitializeGrid(TURBULENCE_INIT_PARAMETERS_DECL); - public: - - /* Stochastic forcing: initialization. */ +private: + // int TurbulenceSimulationInitializeGrid(TURBULENCE_INIT_PARAMETERS_DECL); +public: + /* Stochastic forcing: initialization. */ - int DrivenFlowInitializeGrid(float StochasticFlowDensity, - float StochasticFlowPressure, float InitialBField,int SetBaryonFields); // WS + int DrivenFlowInitializeGrid(float StochasticFlowDensity, + float StochasticFlowPressure, float InitialBField, int SetBaryonFields); // WS - /* Stochastic forcing: Calculate initial phase factors and phase multiplicators + /* Stochastic forcing: Calculate initial phase factors and phase multiplicators for the inverse FT of the forcing spectrum onto a particular grid domain */ - void Phases(); // WS - - /* Stochastic forcing: Compute physical force field via inverse FT of the forcing pectrum */ - - int FTStochasticForcing(int FieldDim); // WS - - - /* START Subgrid-scale modeling framework by P. Grete */ - - // Jacobians to be used in SGS model - float *JacVel[MAX_DIMENSION][MAX_DIMENSION]; - float *JacB[MAX_DIMENSION][MAX_DIMENSION]; - - float *FilteredFields[7]; // filtered fields: rho, xyz-vel, Bxyz - - // the scale-similarity model needs mixed filtered quantities - float *FltrhoUU[6]; - float *FltBB[6]; - float *FltUB[3]; - - int SGSUtil_ComputeJacobian(float *Jac[][MAX_DIMENSION],float* field1,float* field2,float* field3); - int SGSUtil_ComputeMixedFilteredQuantities(); - int SGSUtil_FilterFields(); - - // the general functions that add the SGS terms to the dynamic eqns. - int SGS_AddEMFTerms(float **dU); - int SGS_AddMomentumTerms(float **dU); - - // the different SGS models - void SGS_AddEMF_eddy_resistivity(float **EMF); - void SGS_AddEMF_nonlinear_compressive(float **EMF); - void SGS_AddMom_nonlinear_kinetic(float **Tau); - void SGS_AddMom_nonlinear_kinetic_scaled(float **Tau); - void SGS_AddMom_nonliner_magnetic(float **Tau); - void SGS_AddMom_eddy_viscosity_scaled(float **Tau); - void SGS_AddMom_scale_similarity_kinetic(float **Tau); - void SGS_AddMom_scale_similarity_magnetic(float **Tau); - void SGS_AddEMF_scale_similarity(float **EMF); - - /* END Subgrid-scale modeling framework by P. Grete */ - -/* Comoving coordinate expansion terms. */ + void Phases(); // WS + + /* Stochastic forcing: Compute physical force field via inverse FT of the forcing pectrum */ + + int FTStochasticForcing(int FieldDim); // WS + + /* START Subgrid-scale modeling framework by P. Grete */ + + // Jacobians to be used in SGS model + float *JacVel[MAX_DIMENSION][MAX_DIMENSION]; + float *JacB[MAX_DIMENSION][MAX_DIMENSION]; + + float *FilteredFields[7]; // filtered fields: rho, xyz-vel, Bxyz + + // the scale-similarity model needs mixed filtered quantities + float *FltrhoUU[6]; + float *FltBB[6]; + float *FltUB[3]; + + int SGSUtil_ComputeJacobian(float *Jac[][MAX_DIMENSION], float *field1, float *field2, float *field3); + int SGSUtil_ComputeMixedFilteredQuantities(); + int SGSUtil_FilterFields(); + + // the general functions that add the SGS terms to the dynamic eqns. + int SGS_AddEMFTerms(float **dU); + int SGS_AddMomentumTerms(float **dU); + + // the different SGS models + void SGS_AddEMF_eddy_resistivity(float **EMF); + void SGS_AddEMF_nonlinear_compressive(float **EMF); + void SGS_AddMom_nonlinear_kinetic(float **Tau); + void SGS_AddMom_nonlinear_kinetic_scaled(float **Tau); + void SGS_AddMom_nonliner_magnetic(float **Tau); + void SGS_AddMom_eddy_viscosity_scaled(float **Tau); + void SGS_AddMom_scale_similarity_kinetic(float **Tau); + void SGS_AddMom_scale_similarity_magnetic(float **Tau); + void SGS_AddEMF_scale_similarity(float **EMF); + + /* END Subgrid-scale modeling framework by P. Grete */ + + /* Comoving coordinate expansion terms. */ int ComovingExpansionTerms(); -/* Adjust the gravity source terms for comoving coordinates. */ + /* Adjust the gravity source terms for comoving coordinates. */ int ComovingGravitySourceTerm(); -/* Star Particle handler routine. */ + /* Star Particle handler routine. */ - int StarParticleHandler(HierarchyEntry* SubgridPointer, int level, - float dtLevelAbove, float TopGridTimeStep); + int StarParticleHandler(HierarchyEntry *SubgridPointer, int level, + float dtLevelAbove, float TopGridTimeStep); - int ActiveParticleHandler(HierarchyEntry* SubgridPointer, int level, - float dtLevelAbove, int &NumberOfNewActiveParticles); + int ActiveParticleHandler(HierarchyEntry *SubgridPointer, int level, + float dtLevelAbove, int &NumberOfNewActiveParticles); - int ActiveParticleHandler_Convert(HierarchyEntry* SubgridPointer, int level, - int gridnum, int &NumberOfNewActiveParticles); + int ActiveParticleHandler_Convert(HierarchyEntry *SubgridPointer, int level, + int gridnum, int &NumberOfNewActiveParticles); int DetermineActiveParticleTypes(char **ActiveParticleType); - /* Append and detach active particles data to 'normal' particle + /* Append and detach active particles data to 'normal' particle arrays */ int AddActiveParticles(ActiveParticleList &NewParticles, - int start, int end); - int AddActiveParticle(ActiveParticleType* ThisParticle); + int start, int end); + int AddActiveParticle(ActiveParticleType *ThisParticle); int AppendActiveParticlesToList(ActiveParticleList &APArray, - int search_id); + int search_id); int DebugActiveParticles(int level); /* Create flat arrays of active particle data */ @@ -2603,14 +2706,13 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Get the active particle mass as a flat array (1D) */ - void GetActiveParticleMass(float * ActiveParticleMass); - void GetActiveParticleFixedInSpace(int * ActiveParticleFixedInSpace); - + void GetActiveParticleMass(float *ActiveParticleMass); + void GetActiveParticleFixedInSpace(int *ActiveParticleFixedInSpace); -/* Calculate the potential across the grid. */ + /* Calculate the potential across the grid. */ void CalculatePotentialField(float *PotentialField, int DensNum, float DensityUnits, - float TimeUnits, float LengthUnits); - + float TimeUnits, float LengthUnits); + /* Find the minumum of the potential in a given region */ float FindMinimumPotential(FLOAT *cellpos, FLOAT radius, float *PotentialField); @@ -2628,223 +2730,252 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Find the average temperature in the control region */ float FindAverageTemperatureinRegion(float *temperature, FLOAT *cellpos, FLOAT radius); - + /* Find the total gravitational energy in a given region */ float FindTotalGravitationalEnergy(FLOAT *cellpos, FLOAT radius, int gpotNum, int densNum, - float DensityUnits, float LengthUnits, float VelocityUnits); + float DensityUnits, float LengthUnits, float VelocityUnits); /* Find the total kinetic energy in a given region */ float FindTotalKineticEnergy(FLOAT *cellpos, FLOAT radius, int densNum, - int vel1Num, int vel2Num, int vel3Num); - + int vel1Num, int vel2Num, int vel3Num); + /* Returns averaged velocity from the 6 neighbor cells and itself */ - float* AveragedVelocityAtCell(int index, int DensNum, int Vel1Num); + float *AveragedVelocityAtCell(int index, int DensNum, int Vel1Num); /* Find the minumum of the angular momentum in a given region */ float FindAngularMomentumMinimum(FLOAT *cellpos, FLOAT radius, int DensNum, int Vel1Num, - int Vel2Num, int Vel3Num); + int Vel2Num, int Vel3Num); - -/* Particle splitter routine. */ + /* Particle splitter routine. */ int ParticleSplitter(int level, int iter, int NumberOfIDs, - long *MustRefineIDs); + long *MustRefineIDs); int CreateChildParticles(float dx, int NumberOfParticles, float *ParticleMass, - int *ParticleType, FLOAT *ParticlePosition[], - float *ParticleVelocity[], float *ParticleAttribute[], - FLOAT *CellLeftEdge[], int *GridDimension, - int MaximumNumberOfNewParticles, int iter, - int *NumberOfNewParticles); + int *ParticleType, FLOAT *ParticlePosition[], + float *ParticleVelocity[], float *ParticleAttribute[], + FLOAT *CellLeftEdge[], int *GridDimension, + int MaximumNumberOfNewParticles, int iter, + int *NumberOfNewParticles); -/* Magnetic field resetting routine. */ + /* Magnetic field resetting routine. */ int MagneticFieldResetter(int level); -/* Apply a time-action to a grid. */ + /* Apply a time-action to a grid. */ int ApplyTimeAction(int Type, float Parameter); -/* Routine to set the tracer particle velocities from the grid velocity. */ + /* Routine to set the tracer particle velocities from the grid velocity. */ int TracerParticleSetVelocity(); -/* Creates tracer particles in this grid. */ + /* Creates tracer particles in this grid. */ int TracerParticleCreateParticles(FLOAT LeftEdge[], FLOAT RightEdge[], FLOAT Spacing, PINT &TotalParticleCount); + /* ShearingBox: initialize grid. */ -/* ShearingBox: initialize grid. */ - - int ShearingBoxInitializeGrid(float ThermalMagneticRatio, float fraction, - float ShearingGeometry, - int InitialMagneticFieldConfiguration); + int ShearingBoxInitializeGrid(float ThermalMagneticRatio, float fraction, + float ShearingGeometry, + int InitialMagneticFieldConfiguration); - int ShearingBox2DInitializeGrid(float ThermalMagneticRatio, float fraction, - float ShearingGeometry, - int InitialMagneticFieldConfiguration); + int ShearingBox2DInitializeGrid(float ThermalMagneticRatio, float fraction, + float ShearingGeometry, + int InitialMagneticFieldConfiguration); - int ShearingBoxStratifiedInitializeGrid(float ThermalMagneticRatio, float fraction, - float ShearingGeometry, - int InitialMagneticFieldConfiguration); + int ShearingBoxStratifiedInitializeGrid(float ThermalMagneticRatio, float fraction, + float ShearingGeometry, + int InitialMagneticFieldConfiguration); -/* FDM: Test Problem Initialize Grid for Fuzzy Dark Matter */ + /* FDM: Test Problem Initialize Grid for Fuzzy Dark Matter */ int LightBosonInitializeGrid(float CenterPosition, int LightBosonProblemType); -/* FDM: Test Problem Initialize Grid for Fuzzy Dark Matter */ + /* FDM: Test Problem Initialize Grid for Fuzzy Dark Matter */ int FDMCollapseInitializeGrid(); -// ------------------------------------------------------------------------- -// Analysis functions for AnalysisBaseClass and it's derivatives. -// + // ------------------------------------------------------------------------- + // Analysis functions for AnalysisBaseClass and it's derivatives. + // // Flag cells that overlap a subgrid (used for analysis). int FlagRefinedCells(grid *Subgrid); - - inline int IsInVolume( Eflt32 *LeftEdge, Eflt32 *RightEdge ){ - for( int i = 0; i < GridRank; i++ ){ - if( (GridLeftEdge[i] >= RightEdge[i]) || - (GridRightEdge[i] <= LeftEdge[i]) ){ - return FALSE; + + inline int IsInVolume(Eflt32 *LeftEdge, Eflt32 *RightEdge) + { + for (int i = 0; i < GridRank; i++) + { + if ((GridLeftEdge[i] >= RightEdge[i]) || + (GridRightEdge[i] <= LeftEdge[i])) + { + return FALSE; } } - return TRUE; + return TRUE; } - inline int IsInVolume( Eflt64 *LeftEdge, Eflt64 *RightEdge ){ - for( int i = 0; i < GridRank; i++ ){ - if( (GridLeftEdge[i] >= RightEdge[i]) || - (GridRightEdge[i] <= LeftEdge[i]) ){ - return FALSE; + inline int IsInVolume(Eflt64 *LeftEdge, Eflt64 *RightEdge) + { + for (int i = 0; i < GridRank; i++) + { + if ((GridLeftEdge[i] >= RightEdge[i]) || + (GridRightEdge[i] <= LeftEdge[i])) + { + return FALSE; } } - return TRUE; + return TRUE; } - inline int IsInVolume( Eflt128 *LeftEdge, Eflt128 *RightEdge ){ - for( int i = 0; i < GridRank; i++ ){ - if( (GridLeftEdge[i] >= RightEdge[i]) || - (GridRightEdge[i] <= LeftEdge[i]) ){ - return FALSE; + inline int IsInVolume(Eflt128 *LeftEdge, Eflt128 *RightEdge) + { + for (int i = 0; i < GridRank; i++) + { + if ((GridLeftEdge[i] >= RightEdge[i]) || + (GridRightEdge[i] <= LeftEdge[i])) + { + return FALSE; } } - return TRUE; + return TRUE; } - - // Check to see if a FLOAT point is in the grid. - inline int PointInGrid( Eflt32 *point ){ - for( int i = 0; i < GridRank; i++ ){ - if( ((point[i] >= GridLeftEdge[i]) && - (point[i] < GridRightEdge[i])) == FALSE ) - return FALSE; + inline int PointInGrid(Eflt32 *point) + { + for (int i = 0; i < GridRank; i++) + { + if (((point[i] >= GridLeftEdge[i]) && + (point[i] < GridRightEdge[i])) == FALSE) + return FALSE; } return TRUE; } - inline int PointInGrid( Eflt64 *point ){ - for( int i = 0; i < GridRank; i++ ){ - if( ((point[i] >= GridLeftEdge[i]) && - (point[i] < GridRightEdge[i])) == FALSE ) - return FALSE; + inline int PointInGrid(Eflt64 *point) + { + for (int i = 0; i < GridRank; i++) + { + if (((point[i] >= GridLeftEdge[i]) && + (point[i] < GridRightEdge[i])) == FALSE) + return FALSE; } return TRUE; } - inline int PointInGrid( Eflt128 *point ){ - for( int i = 0; i < GridRank; i++ ){ - if( ((point[i] >= GridLeftEdge[i]) && - (point[i] < GridRightEdge[i])) == FALSE ) - return FALSE; + inline int PointInGrid(Eflt128 *point) + { + for (int i = 0; i < GridRank; i++) + { + if (((point[i] >= GridLeftEdge[i]) && + (point[i] < GridRightEdge[i])) == FALSE) + return FALSE; } return TRUE; } // Check to see if a FLOAT point is in the grid (excluding boundaries) - inline int PointInGridNB( Eflt32 *point ){ - for( int i = 0; i < GridRank; i++ ){ - if( ((point[i] > GridLeftEdge[i]) && - (point[i] < GridRightEdge[i])) == FALSE ) - return FALSE; + inline int PointInGridNB(Eflt32 *point) + { + for (int i = 0; i < GridRank; i++) + { + if (((point[i] > GridLeftEdge[i]) && + (point[i] < GridRightEdge[i])) == FALSE) + return FALSE; } return TRUE; } - inline int PointInGridNB( Eflt64 *point ){ - for( int i = 0; i < GridRank; i++ ){ - if( ((point[i] > GridLeftEdge[i]) && - (point[i] < GridRightEdge[i])) == FALSE ) - return FALSE; + inline int PointInGridNB(Eflt64 *point) + { + for (int i = 0; i < GridRank; i++) + { + if (((point[i] > GridLeftEdge[i]) && + (point[i] < GridRightEdge[i])) == FALSE) + return FALSE; } return TRUE; } - inline int PointInGridNB( Eflt128 *point ){ - for( int i = 0; i < GridRank; i++ ){ - if( ((point[i] > GridLeftEdge[i]) && - (point[i] < GridRightEdge[i])) == FALSE ) - return FALSE; + inline int PointInGridNB(Eflt128 *point) + { + for (int i = 0; i < GridRank; i++) + { + if (((point[i] > GridLeftEdge[i]) && + (point[i] < GridRightEdge[i])) == FALSE) + return FALSE; } return TRUE; } // Flags a 3D array where the grid overlaps. // Very similar to the FastSib stuff. (I think.) - void FlagGridArray( HierarchyEntry ***GridArray, int *dx, - float *cell_width, HierarchyEntry *my_HE ); + void FlagGridArray(HierarchyEntry ***GridArray, int *dx, + float *cell_width, HierarchyEntry *my_HE); /* Includes for analysis tools */ //#ifdef ANALYSIS_TOOLS #include "../anyl/Grid_AnalyzeClusters.h" -//#endif + //#endif #ifdef USE_PYTHON - void ConvertToNumpy(int GridID, PyArrayObject *container[], - int ParentID, int level, FLOAT WriteTime); + void ConvertToNumpy(int GridID, PyArrayObject *container[], + int ParentID, int level, FLOAT WriteTime); #endif -//------------------------------------------------------------------------ -// Methods for star formation -//------------------------------------------------------------------------ + //------------------------------------------------------------------------ + // Methods for star formation + //------------------------------------------------------------------------ - Star *ReturnStarPointer(void) { return Stars; }; - int ReturnNumberOfStars(void) { return NumberOfStars; }; - void SetNumberOfStars(int value) { NumberOfStars = value; }; + Star *ReturnStarPointer(void) + { + return Stars; + }; + int ReturnNumberOfStars(void) + { + return NumberOfStars; + }; + void SetNumberOfStars(int value) + { + NumberOfStars = value; + }; -// For once-per-rootgrid-timestep star formation. - void SetMakeStars(void) { MakeStars = 1; }; + // For once-per-rootgrid-timestep star formation. + void SetMakeStars(void) + { + MakeStars = 1; + }; /* Calculate enclosed mass within a radius */ int GetEnclosedMass(Star *star, float radius, float &mass, - float &metallicity, float &coldgas_mass, - float AvgVelocity[]); + float &metallicity, float &coldgas_mass, + float AvgVelocity[]); int GetEnclosedMass(FLOAT star_pos[], float radius, float &mass, - float &metallicity, float &coldgas_mass, - float AvgVelocity[], float &OneOverRSquaredSum); - int GetEnclosedMassInShell(Star *star, float radius0, float radius1, - float &mass, float &metallicity2, - float &metallicity3, - float &coldgas_mass, float AvgVelocity[]); + float &metallicity, float &coldgas_mass, + float AvgVelocity[], float &OneOverRSquaredSum); + int GetEnclosedMassInShell(Star *star, float radius0, float radius1, + float &mass, float &metallicity2, + float &metallicity3, + float &coldgas_mass, float AvgVelocity[]); - int RemoveParticle(int ID, bool disable=false); + int RemoveParticle(int ID, bool disable = false); int RemoveActiveParticle(PINT ID, int NewProcessorNumber); - + int AddFeedbackSphere(Star *cstar, int level, float radius, float DensityUnits, - float LengthUnits, float VelocityUnits, - float TemperatureUnits, float TimeUnits, double EjectaDensity, - double EjectaMetalDensity, double EjectaThermalEnergy, - double Q_HI, double sigma_HI, float deltaE, int &CellsModified); + float LengthUnits, float VelocityUnits, + float TemperatureUnits, float TimeUnits, double EjectaDensity, + double EjectaMetalDensity, double EjectaThermalEnergy, + double Q_HI, double sigma_HI, float deltaE, int &CellsModified); int SubtractAccretedMassFromSphere(Star *cstar, int level, float radius, float DensityUnits, - float LengthUnits, float VelocityUnits, - float TemperatureUnits, float TimeUnits, double EjectaDensity, - int &CellsModified); + float LengthUnits, float VelocityUnits, + float TemperatureUnits, float TimeUnits, double EjectaDensity, + int &CellsModified); - int MoveAllStars(int NumberOfGrids, grid* FromGrid[], int TopGridDimension); + int MoveAllStars(int NumberOfGrids, grid *FromGrid[], int TopGridDimension); - int MoveAllStarsOld(int NumberOfGrids, grid* FromGrid[], int TopGridDimension); + int MoveAllStarsOld(int NumberOfGrids, grid *FromGrid[], int TopGridDimension); int CommunicationSendStars(grid *ToGrid, int ToProcessor); int CommunicationSendActiveParticles(grid *ToGrid, int ToProcessor, bool DeleteParticles = true); - int TransferSubgridStars(int NumberOfSubgrids, grid* ToGrids[], int AllLocal); - + int TransferSubgridStars(int NumberOfSubgrids, grid *ToGrids[], int AllLocal); + int FindNewStarParticles(int level); int FindAllStarParticles(int level); @@ -2860,131 +2991,137 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int ReturnStarStatistics(int &Number, float &minLife); - int AccreteOntoAccretingParticle(ActiveParticleType* ThisParticle, - FLOAT AccretionRadius, - float* AccretionRate); - - int AccreteOntoSmartStarParticle(ActiveParticleType* ThisParticle, - FLOAT AccretionRadius, - float* AccretionRate); - - float CalculateSmartStarAccretionRate(ActiveParticleType* ThisParticle, - FLOAT AccretionRadius, - FLOAT *KernelRadius, - FLOAT *SumOfWeights); + int AccreteOntoAccretingParticle(ActiveParticleType *ThisParticle, + FLOAT AccretionRadius, + float *AccretionRate); + + int AccreteOntoSmartStarParticle(ActiveParticleType *ThisParticle, + FLOAT AccretionRadius, + float *AccretionRate); + + float CalculateSmartStarAccretionRate(ActiveParticleType *ThisParticle, + FLOAT AccretionRadius, + FLOAT *KernelRadius, + FLOAT *SumOfWeights); int CalculateSpecificQuantities(FLOAT *SinkParticlePos, FLOAT *CLEdge, - float *vgas, float msink, - float *vsink, int *numpoints); - int RemoveMassFromGrid(ActiveParticleType* ThisParticle, - FLOAT AccretionRadius, float AccretionRate, - float *AccretedMass, float *DeltaV, - FLOAT KernelRadius, FLOAT SumOfWeights, float MaxAccretionRate); + float *vgas, float msink, + float *vsink, int *numpoints); + int RemoveMassFromGrid(ActiveParticleType *ThisParticle, + FLOAT AccretionRadius, float AccretionRate, + float *AccretedMass, float *DeltaV, + FLOAT KernelRadius, FLOAT SumOfWeights, float MaxAccretionRate); int GetVorticityComponent(FLOAT *pos, FLOAT *vorticity); float CenAccretionRate(float density, FLOAT AccretionRadius, - FLOAT *pos, float *vel, float mparticle); + FLOAT *pos, float *vel, float mparticle); float ConvergentMassFlow(int DensNum, int Vel1Num, FLOAT AccretionRadius, - FLOAT *pos, float *vel, float SSmass, float Gcode, int GENum); + FLOAT *pos, float *vel, float SSmass, float Gcode, int GENum); float CalculateCirculisationSpeed(int Vel1Num, FLOAT AccretionRadius, - FLOAT *pos, float *vel); + FLOAT *pos, float *vel); FLOAT CalculateBondiHoyleRadius(float mparticle, float *vparticle, float *Temperature); int AddMassAndMomentumToAccretingParticle(float GlobalSubtractedMass, - float GlobalSubtractedMomentum[], - ActiveParticleType* ThisParticle, - LevelHierarchyEntry *LevelArray[]); + float GlobalSubtractedMomentum[], + ActiveParticleType *ThisParticle, + LevelHierarchyEntry *LevelArray[]); - int ApplyGalaxyParticleFeedback(ActiveParticleType** ThisParticle); - - int ApplyGalaxyParticleGravity(ActiveParticleType** ThisParticle); + int ApplyGalaxyParticleFeedback(ActiveParticleType **ThisParticle); - int ApplySmartStarParticleFeedback(ActiveParticleType** ThisParticle); + int ApplyGalaxyParticleGravity(ActiveParticleType **ThisParticle); -//------------------------------------------------------------------------ -// Radiative transfer methods that don't fit in the TRANSFER define -//------------------------------------------------------------------------ + int ApplySmartStarParticleFeedback(ActiveParticleType **ThisParticle); + + //------------------------------------------------------------------------ + // Radiative transfer methods that don't fit in the TRANSFER define + //------------------------------------------------------------------------ int IdentifyRadiativeTransferFields(int &kphHINum, int &gammaNum, - int &kphHeINum, int &kphHeIINum, - int &kdissH2INum, int &kphHMNum, - int &kdissH2IINum); + int &kphHeINum, int &kphHeIINum, + int &kdissH2INum, int &kphHMNum, + int &kdissH2IINum); #ifdef TRANSFER #include "PhotonGrid_Methods.h" #endif /* TRANSFER */ -//------------------------------------------------------------------------ -// Vertex interpolation (for radiative transfer and streaming data) -//------------------------------------------------------------------------ + //------------------------------------------------------------------------ + // Vertex interpolation (for radiative transfer and streaming data) + //------------------------------------------------------------------------ int ComputeVertexCenteredField(int Num); int ComputeCellCenteredField(int Num); - - float ComputeInterpolatedValue(int Num, int vci, int vcj, int vck, - float mx, float my, float mz); - + + float ComputeInterpolatedValue(int Num, int vci, int vcj, int vck, + float mx, float my, float mz); + int NeighborIndices(int index, int vi[]); int NeighborVertexIndices(int index, int vi[]); - void DeleteInterpolatedFields() { + void DeleteInterpolatedFields() + { int i; for (i = 0; i < NumberOfBaryonFields; i++) - if (InterpolatedField[i] != NULL) { - delete [] InterpolatedField[i]; - InterpolatedField[i] = NULL; + if (InterpolatedField[i] != NULL) + { + delete[] InterpolatedField[i]; + InterpolatedField[i] = NULL; } } - void ConvertColorFieldsToFractions(); - void ConvertColorFieldsFromFractions(); - -//----------------------------------------------------------------------- -// Returns radiative cooling by component -//----------------------------------------------------------------------- + void ConvertColorFieldsToFractions(); + void ConvertColorFieldsFromFractions(); + + //----------------------------------------------------------------------- + // Returns radiative cooling by component + //----------------------------------------------------------------------- int ComputeLuminosity(float *luminosity, int NumberOfLuminosityFields); - int ComputeMetalLineLuminosity(float *total_luminosity, float *all_emis, - float *temperature); + int ComputeMetalLineLuminosity(float *total_luminosity, float *all_emis, + float *temperature); + //------------------------------------------------------------------------ + // Shearing Boundary Conditions + //------------------------------------------------------------------------ -//------------------------------------------------------------------------ -// Shearing Boundary Conditions -//------------------------------------------------------------------------ - - bool isTopGrid(){ - for(int i=0; iTopGridDx[i]*1.05) return FALSE; + bool isTopGrid() + { + for (int i = 0; i < GridRank; i++) + { + if (CellWidth[i][0] < TopGridDx[i] * 0.95) + return FALSE; + if (CellWidth[i][0] > TopGridDx[i] * 1.05) + return FALSE; } - return TRUE;}; - -//------------------------------------------------------------------------ -// Misc. -//------------------------------------------------------------------------ + return TRUE; + }; + + //------------------------------------------------------------------------ + // Misc. + //------------------------------------------------------------------------ int FindMinimumParticleMass(float &min_mass, int level); int FindMassiveParticles(float min_mass, int level, FLOAT *pos[], int &npart, - int CountOnly); + int CountOnly); -//------------------------------------------------------------------------ -// Inline FOF halo finder and particle interpolation using a tree -//------------------------------------------------------------------------ + //------------------------------------------------------------------------ + // Inline FOF halo finder and particle interpolation using a tree + //------------------------------------------------------------------------ - int MoveParticlesFOF(int level, FOF_particle_data* &P, - int &Index, FOFData AllVars, float VelocityUnits, - double MassUnits, int CopyDirection); + int MoveParticlesFOF(int level, FOF_particle_data *&P, + int &Index, FOFData AllVars, float VelocityUnits, + double MassUnits, int CopyDirection); int InterpolateParticlesToGrid(FOFData *D); -//------------------------------------------------------------------------ -// Grid star particles onto the AMR mesh -//------------------------------------------------------------------------ + //------------------------------------------------------------------------ + // Grid star particles onto the AMR mesh + //------------------------------------------------------------------------ - int InterpolateStarParticlesToGrid(int NumberOfSPFields); + int InterpolateStarParticlesToGrid(int NumberOfSPFields); -//------------------------------------------------------------------------ -// new hydro & MHD routines -//------------------------------------------------------------------------ + //------------------------------------------------------------------------ + // new hydro & MHD routines + //------------------------------------------------------------------------ int ClusterSMBHFeedback(int level); int ClusterSMBHEachGridGasMass(int level); @@ -3005,41 +3142,41 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int UpdateElectronDensity(void); int UpdatePrim(float **dU, float c1, float c2); int Hydro3D(float **Prim, float **dU, float dt, - fluxes *SubgridFluxes[], int NumberOfSubgrids, - float fluxcoef, float min_coeff, int fallback); - int TurbulenceInitializeGrid(float CloudDensity, float CloudSoundSpeed, FLOAT CloudRadius, - float CloudMachNumber, float CloudAngularVelocity, float InitialBField, - int SetTurbulence, int CloudType, int TurbulenceSeed, int PutSink, - int level, int SetBaryonFields); + fluxes *SubgridFluxes[], int NumberOfSubgrids, + float fluxcoef, float min_coeff, int fallback); + int TurbulenceInitializeGrid(float CloudDensity, float CloudSoundSpeed, FLOAT CloudRadius, + float CloudMachNumber, float CloudAngularVelocity, float InitialBField, + int SetTurbulence, int CloudType, int TurbulenceSeed, int PutSink, + int level, int SetBaryonFields); int Collapse3DInitializeGrid(int n_sphere, - FLOAT r_sphere[MAX_SPHERES], - FLOAT rc_sphere[MAX_SPHERES], - float rho_sphere[MAX_SPHERES], - float p_sphere[MAX_SPHERES], - float cs_sphere[MAX_SPHERES], - FLOAT sphere_position[MAX_SPHERES][MAX_DIMENSION], - float omega_sphere[MAX_SPHERES], - int sphere_type[MAX_SPHERES], - float rho_medium, float p_medium, int level); + FLOAT r_sphere[MAX_SPHERES], + FLOAT rc_sphere[MAX_SPHERES], + float rho_sphere[MAX_SPHERES], + float p_sphere[MAX_SPHERES], + float cs_sphere[MAX_SPHERES], + FLOAT sphere_position[MAX_SPHERES][MAX_DIMENSION], + float omega_sphere[MAX_SPHERES], + int sphere_type[MAX_SPHERES], + float rho_medium, float p_medium, int level); int Collapse1DInitializeGrid(FLOAT r_sphere, - FLOAT rc_sphere, - float rho_sphere, - float p_sphere, - float cs_sphere, - float omega_sphere, - int sphere_type, - float rho_medium, float p_medium); + FLOAT rc_sphere, + float rho_sphere, + float p_sphere, + float cs_sphere, + float omega_sphere, + int sphere_type, + float rho_medium, float p_medium); int AddSelfGravity(float coef); int SourceTerms(float **dU, float min_coeff); int MHD1DTestInitializeGrid(float rhol, float rhor, - float vxl, float vxr, - float vyl, float vyr, - float vzl, float vzr, - float pl, float pr, - float Bxl, float Bxr, - float Byl, float Byr, - float Bzl, float Bzr); - int MHD1DTestWavesInitializeGrid(float rhol, + float vxl, float vxr, + float vyl, float vyr, + float vzl, float vzr, + float pl, float pr, + float Bxl, float Bxr, + float Byl, float Byr, + float Bzl, float Bzr); + int MHD1DTestWavesInitializeGrid(float rhol, float vxl, float vyl, float vzl, @@ -3047,41 +3184,41 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float Bxl, float Byl, float Bzl); - int MHD2DTestInitializeGrid(int MHD2DProblemType, - int UseColour, - float RampWidth, - float rhol, float rhou, - float vxl, float vxu, - float vyl, float vyu, - float pl, float pu, - float Bxl, float Bxu, - float Byl, float Byu, int SetBaryonFields); + int MHD2DTestInitializeGrid(int MHD2DProblemType, + int UseColour, + float RampWidth, + float rhol, float rhou, + float vxl, float vxu, + float vyl, float vyu, + float pl, float pu, + float Bxl, float Bxu, + float Byl, float Byu, int SetBaryonFields); int MHD3DTestInitializeGrid(int MHD3DProblemType, - float rhol, float rhou, - float vxl, float vxu, - float vyl, float vyu, - float pl, float pu, - float Bxl, float Bxu, - float Byl, float Byu); + float rhol, float rhou, + float vxl, float vxu, + float vyl, float vyu, + float pl, float pu, + float Bxl, float Bxu, + float Byl, float Byu); int CollapseMHD3DInitializeGrid(int n_sphere, - FLOAT r_sphere[MAX_SPHERES], - FLOAT rc_sphere[MAX_SPHERES], - float rho_sphere[MAX_SPHERES], - float p_sphere[MAX_SPHERES], - float cs_sphere[MAX_SPHERES], - FLOAT sphere_position[MAX_SPHERES][MAX_DIMENSION], - float omega_sphere[MAX_SPHERES], - float turb_sphere[MAX_SPHERES], - float Bnaught, float theta_B, - int Bdirection, - int sphere_type[MAX_SPHERES], - float rho_medium, float p_medium, int level, int SetBaryonFields); - int MHDTurbulenceInitializeGrid(float rho_medium, float cs_medium, float mach, - float Bnaught, int seed, int level, int SetBaryonFields); - int MHDDecayingRandomFieldInitializeGrid(float rho_medium, float cs_medium, float mach, - float Bnaught, int seed, - float Sindex, float Skmin, float Skmax, - int level, int SetBaryonFields); + FLOAT r_sphere[MAX_SPHERES], + FLOAT rc_sphere[MAX_SPHERES], + float rho_sphere[MAX_SPHERES], + float p_sphere[MAX_SPHERES], + float cs_sphere[MAX_SPHERES], + FLOAT sphere_position[MAX_SPHERES][MAX_DIMENSION], + float omega_sphere[MAX_SPHERES], + float turb_sphere[MAX_SPHERES], + float Bnaught, float theta_B, + int Bdirection, + int sphere_type[MAX_SPHERES], + float rho_medium, float p_medium, int level, int SetBaryonFields); + int MHDTurbulenceInitializeGrid(float rho_medium, float cs_medium, float mach, + float Bnaught, int seed, int level, int SetBaryonFields); + int MHDDecayingRandomFieldInitializeGrid(float rho_medium, float cs_medium, float mach, + float Bnaught, int seed, + float Sindex, float Skmin, float Skmax, + int level, int SetBaryonFields); int PrepareVelocityNormalization(double *v_rms, double *Volume); int NormalizeVelocities(Eflt factor); @@ -3090,49 +3227,48 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int NormalizeMagneticFields(Eflt factor); int GalaxyDiskInitializeGrid(int NumberOfHalos, - FLOAT HaloRadius[MAX_SPHERES], - FLOAT HaloCoreRadius[MAX_SPHERES], - float HaloDensity[MAX_SPHERES], - float HaloTemperature[MAX_SPHERES], - FLOAT HaloPosition[MAX_SPHERES][MAX_DIMENSION], - float HaloSpin[MAX_SPHERES], - float HaloVelocity[MAX_SPHERES][MAX_DIMENSION], - float HaloAngVel[MAX_SPHERES], - float HaloMagneticField, - FLOAT DiskRadius[MAX_SPHERES], - FLOAT DiskHeight[MAX_SPHERES], - float DiskDensity[MAX_SPHERES], - float DiskTemperature[MAX_SPHERES], - float DiskMassFraction[MAX_SPHERES], - float DiskFlaringParameter[MAX_SPHERES], - int GalaxyType[MAX_SPHERES], - int UseParticles, int UseGas, - float UniformVelocity[MAX_DIMENSION], - float MediumTemperature, float MediumDensity, int level); + FLOAT HaloRadius[MAX_SPHERES], + FLOAT HaloCoreRadius[MAX_SPHERES], + float HaloDensity[MAX_SPHERES], + float HaloTemperature[MAX_SPHERES], + FLOAT HaloPosition[MAX_SPHERES][MAX_DIMENSION], + float HaloSpin[MAX_SPHERES], + float HaloVelocity[MAX_SPHERES][MAX_DIMENSION], + float HaloAngVel[MAX_SPHERES], + float HaloMagneticField, + FLOAT DiskRadius[MAX_SPHERES], + FLOAT DiskHeight[MAX_SPHERES], + float DiskDensity[MAX_SPHERES], + float DiskTemperature[MAX_SPHERES], + float DiskMassFraction[MAX_SPHERES], + float DiskFlaringParameter[MAX_SPHERES], + int GalaxyType[MAX_SPHERES], + int UseParticles, int UseGas, + float UniformVelocity[MAX_DIMENSION], + float MediumTemperature, float MediumDensity, int level); int AGNDiskInitializeGrid(float BlackHoleMass, - int BlackHoleType, - int DiskType, - float DiskDensity, - float DiskTemperature, - FLOAT DiskRadius, - FLOAT DiskHeight, - int UseGas, int level); - int MHDRK2_1stStep(fluxes *SubgridFluxes[], - int NumberOfSubgrids, int level, - ExternalBoundary *Exterior); - int MHDRK2_2ndStep(fluxes *SubgridFluxes[], - int NumberOfSubgrids, int level, - ExternalBoundary *Exterior); + int BlackHoleType, + int DiskType, + float DiskDensity, + float DiskTemperature, + FLOAT DiskRadius, + FLOAT DiskHeight, + int UseGas, int level); + int MHDRK2_1stStep(fluxes *SubgridFluxes[], + int NumberOfSubgrids, int level, + ExternalBoundary *Exterior); + int MHDRK2_2ndStep(fluxes *SubgridFluxes[], + int NumberOfSubgrids, int level, + ExternalBoundary *Exterior); int MHD3D(float **Prim, float **dU, float dt, - fluxes *SubgridFluxes[], int NumberOfSubgrids, - float fluxcoef, float min_coeff, int fallback); + fluxes *SubgridFluxes[], int NumberOfSubgrids, + float fluxcoef, float min_coeff, int fallback); int MHDSourceTerms(float **dU, float min_coeff); int UpdateMHDPrim(float **dU, float c1, float c2); int SaveMHDSubgridFluxes(fluxes *SubgridFluxes[], int NumberOfSubgrids, - float *Flux3D[], int flux, float fluxcoef, float dt); + float *Flux3D[], int flux, float fluxcoef, float dt); int SetFloor(); - /* Poisson clean routines */ int PoissonSolver(int level); @@ -3143,32 +3279,38 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int PoissonSolverMultigrid(); int PoissonSolverCGA(int difftype, double *divB_p); - template int multA(T* input, T* output, int *MatrixStartIndex, int *MatrixEndIndex); - template int multA2(T* input, T* output, int *MatrixStartIndex, int *MatrixEndIndex); - template T dot(T *a, T *b, int size); - template int setNeumannBC(T* x, int *MatrixStartIndex, int *MatrixEndIndex,int type); - template int setDirichletBC(T* x, int *MatrixStartIndex, int *MatrixEndIndex); + template + int multA(T *input, T *output, int *MatrixStartIndex, int *MatrixEndIndex); + template + int multA2(T *input, T *output, int *MatrixStartIndex, int *MatrixEndIndex); + template + T dot(T *a, T *b, int size); + template + int setNeumannBC(T *x, int *MatrixStartIndex, int *MatrixEndIndex, int type); + template + int setDirichletBC(T *x, int *MatrixStartIndex, int *MatrixEndIndex); int PoissonCleanStep(int level); - int GetIndex(int i, int j, int k) { - return i + j*(GridDimension[0]) - + k*(GridDimension[0])*(GridDimension[1]); + int GetIndex(int i, int j, int k) + { + return i + j * (GridDimension[0]) + k * (GridDimension[0]) * (GridDimension[1]); } - - int PoissonSolverTestInitializeGrid(int TestType, float GeometryControl); - + int PoissonSolverTestInitializeGrid(int TestType, float GeometryControl); int PrintToScreenBoundaries(float *field, char *display, int direction, int slice, - int check, float diffvalue); + int check, float diffvalue); int PrintToScreenBoundaries(float *field, char *display, int direction, int slice); int PrintToScreenBoundaries(float *field, char *display); int PrintToScreenBoundaries(); int PrintToScreenBoundaries(int field); - int getField(int i){return FieldType[i];}; - + int getField(int i) + { + return FieldType[i]; + }; + int ReduceWindBoundary(); /* New particle routines */ @@ -3176,13 +3318,15 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int ReturnMaximumParticleNumber(); - int ReturnNumberOfNewParticles() { + int ReturnNumberOfNewParticles() + { int np = 0; for (int n = 0; n < NumberOfParticles; n++) - if (ParticleNumber[n] < 0) np++; + if (ParticleNumber[n] < 0) + np++; return np; }; - + /* Non-ideal effects */ int AddViscosity(); @@ -3203,38 +3347,38 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], void CudaMHDFreeGPUData(); void CudaSolveMHDEquations(fluxes *SubgridFluxes[], int NumberOfSubgrids, int renorm); void CudaMHDSweep(int dir); - void CudaMHDSaveSubgridFluxes(fluxes *SubgridFluxes[], - int NumberOfSubgrids, int dir); + void CudaMHDSaveSubgridFluxes(fluxes *SubgridFluxes[], + int NumberOfSubgrids, int dir); void CudaMHDSourceTerm(); void CudaMHDUpdatePrim(int renorm); - int CudaMHDRK2_1stStep(fluxes *SubgridFluxes[], + int CudaMHDRK2_1stStep(fluxes *SubgridFluxes[], int NumberOfSubgrids, int level, ExternalBoundary *Exterior); - int CudaMHDRK2_2ndStep(fluxes *SubgridFluxes[], + int CudaMHDRK2_2ndStep(fluxes *SubgridFluxes[], int NumberOfSubgrids, int level, ExternalBoundary *Exterior); #endif int SolveMHD_Li(int CycleNumber, int NumberOfSubgrids, - fluxes *SubgridFluxes[], float *CellWidthTemp[], - Elong_int GridGlobalStart[], int GravityOn, - int NumberOfColours, int colnum[], - float ** Fluxes); + fluxes *SubgridFluxes[], float *CellWidthTemp[], + Elong_int GridGlobalStart[], int GravityOn, + int NumberOfColours, int colnum[], + float **Fluxes); //Variables - //CenteredB is used in the Riemann solver (SolveMHDequations) and the timestep (dtMagnetic) - //MagneticField is the face centered magnetic field, and is the quantity ultimately updated by the + //CenteredB is used in the Riemann solver (SolveMHDequations) and the timestep (dtMagnetic) + //MagneticField is the face centered magnetic field, and is the quantity ultimately updated by the //CT style algorithm. - float *MagneticField[3]; + float *MagneticField[3]; float *ElectricField[3]; float *AvgElectricField[3]; float *OldMagneticField[3]; float *OldElectricField[3]; //Magnetic dimensions: MagneticDims[field][axis] int MagneticDims[3][3], ElectricDims[3][3]; - int MHDStartIndex[3][3], MHDEndIndex[3][3];//For the MagneticField - int MHDeStartIndex[3][3], MHDeEndIndex[3][3];//Electric Field - int MHDAdd[3][3]; //How much to add to Barryon Dimensions. MHDAdd[i][j]=KronikerDelta(i,j) + int MHDStartIndex[3][3], MHDEndIndex[3][3]; //For the MagneticField + int MHDeStartIndex[3][3], MHDeEndIndex[3][3]; //Electric Field + int MHDAdd[3][3]; //How much to add to Barryon Dimensions. MHDAdd[i][j]=KronikerDelta(i,j) int MagneticSize[3]; int ElectricSize[3]; @@ -3246,54 +3390,61 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float *MHDParentTemp[3]; int MHDParentTempPermanent[3]; - int MHDRefinementFactors[3]; + int MHDRefinementFactors[3]; FLOAT ParentDx, ParentDy, ParentDz; - float *DyBx, *DzBx, *DyzBx; float *DxBy, *DzBy, *DxzBy; float *DxBz, *DyBz, *DxyBz; - int * DBxFlag, *DByFlag, *DBzFlag; - - int MHD_Diagnose(char * message, float * &DivB); - inline int indexb1(int i, int j, int k) {return i+MagneticDims[0][0]*(j+MagneticDims[0][1]*k);} - inline int indexb2(int i, int j, int k) {return i+MagneticDims[1][0]*(j+MagneticDims[1][1]*k);} - inline int indexb3(int i, int j, int k) {return i+MagneticDims[2][0]*(j+MagneticDims[2][1]*k);} - int MHD_CID(LevelHierarchyEntry * OldFineLevel, TopGridData * MetaData, int Offset[], int TempDim[], int Refinement[]); - int MHD_CIDWorker(grid* OtherGrid, FLOAT EdgeOffset[MAX_DIMENSION]); - int MHD_SendOldFineGrids(LevelHierarchyEntry * OldFineLevel, grid *ParentGrid, TopGridData *MetaData); - int MHD_ProlongAllocate(int * ChildDim); - int MHD_DCheck(int * ChildDim, char * mess); + int *DBxFlag, *DByFlag, *DBzFlag; + + int MHD_Diagnose(char *message, float *&DivB); + inline int indexb1(int i, int j, int k) + { + return i + MagneticDims[0][0] * (j + MagneticDims[0][1] * k); + } + inline int indexb2(int i, int j, int k) + { + return i + MagneticDims[1][0] * (j + MagneticDims[1][1] * k); + } + inline int indexb3(int i, int j, int k) + { + return i + MagneticDims[2][0] * (j + MagneticDims[2][1] * k); + } + int MHD_CID(LevelHierarchyEntry *OldFineLevel, TopGridData *MetaData, int Offset[], int TempDim[], int Refinement[]); + int MHD_CIDWorker(grid *OtherGrid, FLOAT EdgeOffset[MAX_DIMENSION]); + int MHD_SendOldFineGrids(LevelHierarchyEntry *OldFineLevel, grid *ParentGrid, TopGridData *MetaData); + int MHD_ProlongAllocate(int *ChildDim); + int MHD_DCheck(int *ChildDim, char *mess); int MHD_ProlongFree(); void MHD_SetupDims(void); //Evolution/AMR routines int SolveMHDEquations(int CycleNumber, int NumberOfSubgrids, - fluxes *SubgridFluxes[], int level, int grid); - int ComputeElectricField(float dT, float ** Fluxes); - int MHD_Curl( int * Start, int * End, int Method); - int CenterMagneticField(int * Start = NULL, int * End = NULL); + fluxes *SubgridFluxes[], int level, int grid); + int ComputeElectricField(float dT, float **Fluxes); + int MHD_Curl(int *Start, int *End, int Method); + int CenterMagneticField(int *Start = NULL, int *End = NULL); int ClearAvgElectricField(); - int MHD_UpdateMagneticField(int level, LevelHierarchyEntry * Level, - int TimeIsBeforeSetLevelTimestep); + int MHD_UpdateMagneticField(int level, LevelHierarchyEntry *Level, + int TimeIsBeforeSetLevelTimestep); int MHD_ProjectFace(grid &ParentGrid, - boundary_type LeftFaceBoundaryCondition[], - boundary_type RightFaceBoundaryCondition[]); + boundary_type LeftFaceBoundaryCondition[], + boundary_type RightFaceBoundaryCondition[]); //Test Problems int MHDBlastInitializeGrid(float Density0, float Density1, - float Energy0, float Energy1, + float Energy0, float Energy1, float Velocity0[], float Velocity1[], float B0[], float B1[], float MetalDensity0, float MetalDensity1, int UseMetal, float MetalOffsetInX, float Radius, float MHDBlastCenter[], int LongDimension, float PerturbAmplitude, int PerturbMethod, float PerturbWavelength[], int InitStyle); - int MHDOrszagTangInitGrid(float Density,float Pressure, float V0, float B0 ); - int MHDLoopInitGrid(float LoopDensity,float Pressure, float Vx, float Vy, float Vz, float B0, FLOAT R0, + int MHDOrszagTangInitGrid(float Density, float Pressure, float V0, float B0); + int MHDLoopInitGrid(float LoopDensity, float Pressure, float Vx, float Vy, float Vz, float B0, FLOAT R0, FLOAT Center[], int CurrentAxis); - //See Grid_MHDCTEnergyToggle.C for details on these functions. float *MHDCT_temp_conserved_energy; int MHDCT_ConvertEnergyToConservedC(); @@ -3311,6 +3462,4 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], // inline int grid::TurbulenceSimulationInitializeGrid (TURBULENCE_INIT_PARAMETERS_DECL); - #endif - diff --git a/src/enzo/Grid_AddParentAccelerationFieldAPM.C b/src/enzo/Grid_AddParentAccelerationFieldAPM.C new file mode 100644 index 000000000..a84ce483e --- /dev/null +++ b/src/enzo/Grid_AddParentAccelerationFieldAPM.C @@ -0,0 +1,152 @@ +/*********************************************************************** +/ +/ GRID CLASS (ADDS PARENTAL ACCELERATION FIELD) +/ +/ written by: Greg Bryan +/ date: January, 1998 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#ifdef USE_MPI +#include "mpi.h" +#endif /* USE_MPI */ +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "communication.h" + +/* function prototypes */ + +extern "C" void FORTRAN_NAME(prolong_add)(float *source, float *dest, int *ndim, + int *sdim1, int *sdim2, int *sdim3, + int *ddim1, int *ddim2, int *ddim3, + int *start1, int *start2, int *start3, + int *refine1, int *refine2,int *refine3); + +int grid::AddParentAccelerationFieldAPM(grid *ParentGrid) +{ + + if (ParentGrid == NULL) + return FAIL; + + /* Return if this doesn't involve us. */ + + if (this->CommunicationMethodShouldExit(ParentGrid)) + return SUCCESS; + + /* Allocate space for acceleration field, if necessary. */ + int dim, size = 1; + for (dim = 0; dim < GridRank; dim++) + size *= GridDimension[dim]; + + if (MyProcessorNumber == ProcessorNumber && + CommunicationDirection != COMMUNICATION_POST_RECEIVE) + for (dim = 0; dim < GridRank; dim++) + if (AccelerationField[dim] == NULL) + ENZO_FAIL("AccelerationField must already exist.\n"); + + /* Declarations. */ + + int ParentOffset[MAX_DIMENSION], ParentStartIndex[MAX_DIMENSION], + ParentTempDim[MAX_DIMENSION], Refinement[MAX_DIMENSION], + ParentDim[MAX_DIMENSION]; + + /* Compute refinement factors. */ + + ParentGrid->ComputeRefinementFactors(this, Refinement); + + /* Set unused dims to zero. */ + + for (dim = GridRank; dim < MAX_DIMENSION; dim++) { + ParentOffset[dim] = ParentStartIndex[dim] = 0; + ParentTempDim[dim] = ParentDim[dim] = 1; + } + + /* Compute the ParentOffset (in grid units) and ParentStartIndex and + the region dim (in parent units). */ + + for (dim = 0; dim < GridRank; dim++) { + ParentOffset[dim] = nint((CellLeftEdge[dim][0] - + ParentGrid->CellLeftEdge[dim][0])/CellWidth[dim][0]); + ParentStartIndex[dim] = ParentOffset[dim]/Refinement[dim] - 1; + ParentTempDim[dim] = (ParentOffset[dim] + GridDimension[dim] - 1)/Refinement[dim] - + ParentStartIndex[dim] + 2; + ParentDim[dim] = ParentGrid->GridDimension[dim]; + if (ParentStartIndex[dim] < 0 || + ParentStartIndex[dim]+ParentTempDim[dim] > ParentDim[dim]) { + fprintf(stderr, "ParentStartIndex[%d] = %d ParentTempDim = %d(%d).\n", + dim, ParentStartIndex[dim], ParentTempDim[dim], ParentDim[dim]); + fprintf(stderr, "GridDimension = %d ParentGridDimension = %d CLE = %g PCLE = %g\n", + GridDimension[dim], ParentDim[dim], CellLeftEdge[dim][0], ParentGrid->CellLeftEdge[dim][0]); + return FAIL; + } + } + + /* Copy data from other processor if needed (modify ParentDim and + ParentStartIndex to reflect the fact that we are only coping part of + the grid. */ + + /* If posting a receive, then record details of call. */ + +#ifdef USE_MPI + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE && + ProcessorNumber != ParentGrid->ProcessorNumber) { + CommunicationReceiveGridOne[CommunicationReceiveIndex] = this; + CommunicationReceiveGridTwo[CommunicationReceiveIndex] = ParentGrid; + CommunicationReceiveCallType[CommunicationReceiveIndex] = 23; + } +#endif /* USE_MPI */ + + if (ProcessorNumber != ParentGrid->ProcessorNumber) { + ParentGrid->CommunicationSendRegion(ParentGrid, ProcessorNumber, + ACCELERATION_FIELDS, NEW_ONLY, ParentStartIndex, ParentTempDim); + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE || + CommunicationDirection == COMMUNICATION_SEND) { + + return SUCCESS; + } + for (dim = 0; dim < GridRank; dim++) { + ParentOffset[dim] -= Refinement[dim]*ParentStartIndex[dim]; + ParentDim[dim] = ParentTempDim[dim]; + } + } + + /* Return if this is not our concern. */ + + if (ProcessorNumber != MyProcessorNumber) + return SUCCESS; + + /* Interpolate */ + + for (dim = 0; dim < GridRank; dim++) + // FORTRAN_NAME(prolong_tsc_add)(ParentGrid->AccelerationField[dim], + FORTRAN_NAME(prolong_add)(ParentGrid->AccelerationField[dim], + AccelerationField[dim], &GridRank, + ParentDim, ParentDim+1, ParentDim+2, + GridDimension, GridDimension+1, GridDimension+2, + ParentOffset, ParentOffset+1, ParentOffset+2, + Refinement, Refinement+1, Refinement+2); + + /* Clean up parent. */ + + if (MyProcessorNumber != ParentGrid->ProcessorNumber) { + for (dim = 0; dim < GridRank; dim++) { + delete ParentGrid->AccelerationField[dim]; + ParentGrid->AccelerationField[dim] = NULL; + } + } + + return SUCCESS; + +} diff --git a/src/enzo/Grid_AddParentPotentialFieldAPM.C b/src/enzo/Grid_AddParentPotentialFieldAPM.C new file mode 100644 index 000000000..fa50e20b1 --- /dev/null +++ b/src/enzo/Grid_AddParentPotentialFieldAPM.C @@ -0,0 +1,168 @@ +/*********************************************************************** +/ +/ GRID CLASS (ADDS PARENTAL POTENTIAL FIELD) +/ based on Grid_AddParentAccelerationField.C +/ +/ written by: JC Passy +/ date: March, 2012 +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#ifdef USE_MPI +#include "mpi.h" +#endif /* USE_MPI */ +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "communication.h" + +/* function prototypes */ + +extern "C" void FORTRAN_NAME(prolong_add)(float *source, float *dest, int *ndim, + int *sdim1, int *sdim2, int *sdim3, + int *ddim1, int *ddim2, int *ddim3, + int *start1, int *start2, int *start3, + int *refine1, int *refine2,int *refine3); + +int grid::AddParentPotentialFieldAPM(grid *ParentGrid) +{ + + if (ParentGrid == NULL) + return FAIL; + + /* Return if this doesn't involve us. */ + + if (this->CommunicationMethodShouldExit(ParentGrid)) + return SUCCESS; + + /* Allocate space for potential field, if necessary. */ + + int dim, size = 1; + for (dim = 0; dim < GridRank; dim++) + size *= GridDimension[dim]; + + if (MyProcessorNumber == ProcessorNumber && + CommunicationDirection != COMMUNICATION_POST_RECEIVE) + for (dim = 0; dim < GridRank; dim++) + if (PotentialField == NULL) + ENZO_FAIL("PotentialField must already exist.\n") + + /* Declarations. */ + + int ParentOffset[MAX_DIMENSION], ParentStartIndex[MAX_DIMENSION], + ParentTempDim[MAX_DIMENSION], Refinement[MAX_DIMENSION], + ParentDim[MAX_DIMENSION]; + + /* Compute refinement factors. */ + + ParentGrid->ComputeRefinementFactors(this, Refinement); + + /* Set unused dims to zero. */ + + for (dim = GridRank; dim < MAX_DIMENSION; dim++) { + ParentOffset[dim] = ParentStartIndex[dim] = 0; + ParentTempDim[dim] = ParentDim[dim] = 1; + } + + /* Compute the ParentOffset (in grid units) and ParentStartIndex and + the region dim (in parent units). */ + + /* + for (dim = 0; dim < GridRank; dim++) { + ParentOffset[dim] = nint((CellLeftEdge[dim][0] - + ParentGrid->CellLeftEdge[dim][0])/CellWidth[dim][0]); + ParentStartIndex[dim] = ParentOffset[dim]/Refinement[dim] - 1; + ParentTempDim[dim] = (ParentOffset[dim] + GridDimension[dim] - 1)/Refinement[dim] - + ParentStartIndex[dim] + 2; + ParentDim[dim] = ParentGrid->GridDimension[dim]; + if (ParentStartIndex[dim] < 0 || + ParentStartIndex[dim]+ParentTempDim[dim] > ParentDim[dim]) { + fprintf(stderr, "ParentStartIndex[%d] = %d ParentTempDim = %d(%d).\n", + dim, ParentStartIndex[dim], ParentTempDim[dim], ParentDim[dim]); + fprintf(stderr, "GridDimension = %d ParentGridDimension = %d CLE = %g PCLE = %g\n", + GridDimension[dim], ParentDim[dim], CellLeftEdge[dim][0], ParentGrid->CellLeftEdge[dim][0]); + return FAIL; + } + } + */ + + // from Grid_PreparePotentialField.C + + for (dim = 0; dim < GridRank; dim++) { + ParentOffset[dim] = nint((GravitatingMassFieldLeftEdge[dim] - + ParentGrid->GravitatingMassFieldLeftEdge[dim])/ + GravitatingMassFieldCellSize); + ParentStartIndex[dim] = ParentOffset[dim]/Refinement[dim] - 1; + ParentTempDim[dim] = (ParentOffset[dim] + + GravitatingMassFieldDimension[dim]-1)/Refinement[dim] - + ParentStartIndex[dim] + 3; + ParentDim[dim] = ParentGrid->GravitatingMassFieldDimension[dim]; + if (ParentStartIndex[dim] < 0 || + ParentStartIndex[dim]+ParentTempDim[dim] > ParentDim[dim]) { + ENZO_VFAIL("ParentStartIndex[%"ISYM"] = %"ISYM" ParentTempDim = %"ISYM"(%"ISYM").\n", + dim, ParentStartIndex[dim], ParentTempDim[dim], ParentDim[dim]) + } + } + + /* Copy data from other processor if needed (modify ParentDim and + ParentStartIndex to reflect the fact that we are only coping part of + the grid. */ + + /* If posting a receive, then record details of call. */ + +#ifdef USE_MPI + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE && + ProcessorNumber != ParentGrid->ProcessorNumber) { + CommunicationReceiveGridOne[CommunicationReceiveIndex] = this; + CommunicationReceiveGridTwo[CommunicationReceiveIndex] = ParentGrid; + CommunicationReceiveCallType[CommunicationReceiveIndex] = 24; + } +#endif /* USE_MPI */ + + if (ProcessorNumber != ParentGrid->ProcessorNumber) { + ParentGrid->CommunicationSendRegion(ParentGrid, ProcessorNumber, + POTENTIAL_FIELD, NEW_ONLY, ParentStartIndex, ParentTempDim); + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE || + CommunicationDirection == COMMUNICATION_SEND) { + + return SUCCESS; + } + for (dim = 0; dim < GridRank; dim++) { + ParentOffset[dim] -= Refinement[dim]*ParentStartIndex[dim]; + ParentDim[dim] = ParentTempDim[dim]; + } + } + + /* Return if this is not our concern. */ + + if (ProcessorNumber != MyProcessorNumber) + return SUCCESS; + + /* Interpolate */ + FORTRAN_NAME(prolong_add)(ParentGrid->PotentialField, + PotentialField, &GridRank, + ParentDim, ParentDim+1, ParentDim+2, + GravitatingMassFieldDimension, + GravitatingMassFieldDimension+1, + GravitatingMassFieldDimension+2, + ParentOffset, ParentOffset+1, ParentOffset+2, + Refinement, Refinement+1, Refinement+2); + + /* Clean up parent. */ + + if (MyProcessorNumber != ParentGrid->ProcessorNumber) { + delete [] ParentGrid->PotentialField; + ParentGrid->PotentialField = NULL; + } + + return SUCCESS; + +} diff --git a/src/enzo/Grid_CleanUp.C b/src/enzo/Grid_CleanUp.C index 7b3fa6b9c..0d8ec6abe 100644 --- a/src/enzo/Grid_CleanUp.C +++ b/src/enzo/Grid_CleanUp.C @@ -12,7 +12,7 @@ #include #include - + #include "ErrorExceptions.h" #include "macros_and_parameters.h" #include "typedefs.h" @@ -21,33 +21,42 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" - + /* function prototypes */ - - + + void grid::CleanUp() { - + int i; - + for (i = 0; i < MAX_DIMENSION; i++) { delete [] ParticleAcceleration[i]; // delete [] AccelerationField[i]; - + ParticleAcceleration[i] = NULL; // AccelerationField[i] = NULL; } + + /* APM solver */ + if (GravitySolverType == GRAVITY_SOLVER_APM) { + for (i = 0; i < MAX_DIMENSION; i++) { + delete [] AccelerationFieldExternalAPM[i]; + AccelerationFieldExternalAPM[i] = NULL; + } + } + delete [] ParticleAcceleration[MAX_DIMENSION]; ParticleAcceleration[MAX_DIMENSION] = NULL; - + for (i = 0; i < MAX_NUMBER_OF_BARYON_FIELDS; i++) { delete [] OldBaryonField[i]; OldBaryonField[i] = NULL; } - + delete [] GravitatingMassField; delete [] GravitatingMassFieldParticles; - + GravitatingMassField = NULL; GravitatingMassFieldParticles = NULL; @@ -66,7 +75,7 @@ void grid::CleanUp() OldMagneticField[i] = NULL; } - + } } diff --git a/src/enzo/Grid_ComovingGravitySourceTerm.C b/src/enzo/Grid_ComovingGravitySourceTerm.C index 786cbd508..b78a374be 100644 --- a/src/enzo/Grid_ComovingGravitySourceTerm.C +++ b/src/enzo/Grid_ComovingGravitySourceTerm.C @@ -11,7 +11,7 @@ / NOTE: / ************************************************************************/ - + #include #include "ErrorExceptions.h" @@ -22,33 +22,36 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" - - + + int grid::ComovingGravitySourceTerm() { - + /* Return is this is not the right processor. */ - + if (MyProcessorNumber != ProcessorNumber) return SUCCESS; - + /* This assumes that all the equations have units as defined by CosmologyUnits. This means that GravitationalConstant must be 1. */ - - if (GravitationalConstant != 1) { + + if (GravitationalConstant != 1 && ProblemType != 44) { ENZO_FAIL("GravitationalConstant must be 1!.\n"); } - + /* Set AverageDensity (held in global_data.h). */ - + int i, j, k, gmf_index; float AverageDensity = 1.; if (ProblemType == 50 || ProblemType == 60 || ProblemType == 61) //AK AverageDensity = 0.0; - + + if (ProblemType == 44) // TestGravitySineWave JC Passy + AverageDensity = 2.0; + /* Loop over the field, subracting off the mean field. */ - + for (k = 0; k < GravitatingMassFieldDimension[2]; k++) for (j = 0; j < GravitatingMassFieldDimension[1]; j++) { gmf_index = (k*GravitatingMassFieldDimension[1] + j)* @@ -58,6 +61,6 @@ int grid::ComovingGravitySourceTerm() GravitatingMassField[gmf_index] - AverageDensity; } } - + return SUCCESS; } diff --git a/src/enzo/Grid_ComputeAccelerationFieldAPM.C b/src/enzo/Grid_ComputeAccelerationFieldAPM.C new file mode 100644 index 000000000..5af25ef61 --- /dev/null +++ b/src/enzo/Grid_ComputeAccelerationFieldAPM.C @@ -0,0 +1,339 @@ +/*********************************************************************** +/ +/ GRID CLASS (COMPUTE THE ACCLERATION FIELDS FROM THE GRAVITATING MASS FIELD) +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "GreensFunction.h" + + +/* function prototypes */ + +int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); +int NextLargestFFTSize(int dimension); +int FastFourierTransform(float *buffer, int Rank, int DimensionReal[], + int Dimension[], int direction, int type); +int ReportMemoryUsage(char *header = NULL); +extern "C" void FORTRAN_NAME(copy3d)(float *source, float *dest, + int *sdim1, int *sdim2, int *sdim3, + int *ddim1, int *ddim2, int *ddim3, + int *sstart1, int *sstart2, int *sstart3, + int *dstart1, int *dstart2, int *dststart3); + +#define INDEX_ACCEL(a,b,c) ( ((c)*GridDimension[1] + (b))*GridDimension[0] + (a) ) +#define INDEX_GRAV(a,b,c) ( ((c)*GravitatingMassFieldDimension[1] + (b))*GravitatingMassFieldDimension[0] + (a) ) +#define INDEX_FFT(a,b,c) ( ((c)*FFTDimensionReal[1] + (b))*FFTDimensionReal[0] + (a) ) + + +int grid::ComputeAccelerationFieldAPM(int RefinementFactor) +{ + + /* Return if this grid is not on this processor. */ + + if (MyProcessorNumber != ProcessorNumber) + return SUCCESS; + + /* declarations */ + + int i, j, k, dim, Zero[MAX_DIMENSION], bufferindex, gravityindex; + for (dim = 0; dim < MAX_DIMENSION; dim++) + Zero[dim] = 0; + + /* Compute adot/a at time = t+1/2dt (time-centered). */ + + FLOAT a = 1, dadt; + if (ComovingCoordinates) + if (CosmologyComputeExpansionFactor(Time+0.5*dtFixed, &a, &dadt) == FAIL) { + fprintf(stderr, "Error in CosmologyComputeExpansionFactor.\n"); + return FAIL; + } + + /* Determine the smallest possible dimensions that are: + (a) larger than or equal in size to the gravity grid and + (b) can be directly transformed. This last quantity is + implementation dependant (see NextLargestFFTSize). */ + + int FFTDimension[MAX_DIMENSION], FFTDimensionReal[MAX_DIMENSION]; + int FFTDimensionGrav[MAX_DIMENSION], FFTStartIndex[MAX_DIMENSION]; + for (dim = 0; dim < GridRank; dim++) { + FFTDimensionGrav[dim] = GravitatingMassFieldDimension[dim]; + FFTDimension[dim] = GravitatingMassFieldDimension[dim]; + FFTStartIndex[dim] = 0; + + /* If this is a topgrid periodic, then set the parameters to copy out just + the active region. */ + + if (GravityBoundaryType == TopGridPeriodic) { + FFTStartIndex[dim] = nint( (GridLeftEdge[dim] - GravitatingMassFieldLeftEdge[dim]) / GravitatingMassFieldCellSize); + FFTDimension[dim] = nint( (GridRightEdge[dim]-GridLeftEdge[dim])/GravitatingMassFieldCellSize); + FFTDimensionGrav[dim] = FFTDimension[dim]; + if (NumberOfProcessors > 1) { + fprintf(stderr, "This gravity type doesn't support parallel yet.\n"); + return FAIL; + } + } + + /* If subgrid isolated, then add one convolution kernel room for zero-padding. */ + + if (GravityBoundaryType == SubGridIsolated) + FFTDimension[dim] += nint(RefinementFactor*S2ParticleSize) + FFT_SAFETY_FACTOR; + + /* Set FFT dimension to next largest size we can do. */ + + FFTDimension[dim] = NextLargestFFTSize(FFTDimension[dim]); + FFTDimensionReal[dim] = FFTDimension[dim]; + } + + /* Add two to the declared dimensions of the FFT buffer since some + real-to-complex transforms require this. */ + + FFTDimensionReal[0] += 2; + + /* Compute the size of the FFT buffer and the gravitating field. + Also, If this is the top grid and it's periodic, check to make + sure the FFT size is exactly the same size as GravitatingMassField. */ + + int FFTSize = 1, GravSize = 1; + for (dim = 0; dim < GridRank; dim++) { + FFTSize *= FFTDimensionReal[dim]; + GravSize *= GravitatingMassFieldDimension[dim]; + if (GravityBoundaryType == TopGridPeriodic && + FFTDimension[dim] != FFTDimensionGrav[dim]) { + fprintf(stderr, "Topgrid cannot be periodic with these dimensions.\n"); + fprintf(stderr, " (see NextLargestFFTSize.cc)\n"); + return FAIL; + } + } + + /* Allocate and clear two temporary buffers for the FFT. */ + + float *buffer1 = new float[FFTSize]; + float *buffer2 = new float[FFTSize]; + if (buffer1 == NULL || buffer2 == NULL) { + fprintf(stderr, "Grid_ComputeAccelerationField: malloc error (out of memory?)\n"); + return FAIL; + } + for (i = 0; i < FFTSize; i++) + buffer1[i] = 0.0; + + /* Copy the GravitatingMassField into this buffer (first, clear unused + indexes) and multiply by the gravitational constant (and by the cell + width squared because the Green's function is unitless). */ + + float factor = GravitationalConstant*GravitatingMassFieldCellSize + *GravitatingMassFieldCellSize/a; + for (k = 0; k < FFTDimensionGrav[2]; k++) { + for (j = 0; j < FFTDimensionGrav[1]; j++) { + for (i = 0; i < FFTDimensionGrav[0]; i++) { + buffer1[INDEX_FFT(i,j,k)] = GravitatingMassField[INDEX_GRAV(i+FFTStartIndex[0], j+FFTStartIndex[1], k+FFTStartIndex[2])] * factor; + } + } + } + + /* Transform the buffer into the fourier domain (in place). */ + + if (FastFourierTransform(buffer1, GridRank, FFTDimensionReal, FFTDimension, + FFT_FORWARD, REAL_TO_COMPLEX) == FAIL) { + fprintf(stderr, "Error in FastFourierTransform (forward).\n"); + return FAIL; + } + + /* Compute appropriate Green's function (not including D(k)). */ + + if (GreensFunction.PrepareGreensFunction(GridRank, FFTDimensionReal, + FFTDimension, GravityBoundaryType, RefinementFactor) == FAIL) { + fprintf(stderr, "Error in GreensFunction->PrepareGreensFunction.\n"); + return FAIL; + } + + /* Multiply the Green's function by the transformed gravity field + and leave the result (the potential) in buffer1. */ + + if (GreensFunction.MultiplyGreensFunction(GridRank, FFTDimensionReal, + FFTDimension, buffer1) == FAIL) { + fprintf(stderr, "Error in GreensFunction->MultiplyGreensFunction.\n"); + return FAIL; + } + + //#define NO_COMPUTE_POTENTIAL_FIELD +#define COMPUTE_POTENTIAL_FIELD +#ifdef COMPUTE_POTENTIAL_FIELD + + /* Copy buffer1 in buffer3 */ + + float *buffer3 = new float[FFTSize]; + for (i = 0; i < FFTSize; i++) + buffer3[i] = buffer1[i]; + + /* Compute the potential with inverse FFT */ + + if (FastFourierTransform(buffer3, GridRank, FFTDimensionReal, + FFTDimension, FFT_INVERSE, REAL_TO_COMPLEX) == FAIL) { + fprintf(stderr, "Error in FastFourierTransform (inverse).\n"); + return FAIL; + } + + /* Allocate potential field and copy. */ + + if (PotentialField == NULL) + PotentialField = new float[GravSize]; + + for (k = 0; k < FFTDimensionGrav[2]; k++) { + for (j = 0; j < FFTDimensionGrav[1]; j++) { + for (i = 0; i < FFTDimensionGrav[0]; i++) { + PotentialField[INDEX_GRAV(i+FFTStartIndex[0], j+FFTStartIndex[1], k+FFTStartIndex[2])] = buffer3[INDEX_FFT(i,j,k)]; + } + } + } + + /* Clean up */ + + delete [] buffer3; + +#endif /* COMPUTE_POTENTIAL_FIELD */ + + /* Compute size of acceleration field. */ + + int size = GridDimension[0]*GridDimension[1]*GridDimension[2]; + + /* Compute offset between AccelerationField and accelerations in buffer2. */ + + int Offset[MAX_DIMENSION] = {0,0,0}; + for (dim = 0; dim < GridRank; dim++) { + Offset[dim] = nint((CellLeftEdge[dim][0] - GravitatingMassFieldLeftEdge[dim])/GravitatingMassFieldCellSize); + } + + /* To compute the acceleration, loop over the dimensions. + For each dimension, compute the acceleration field and copy it into + the appropriate spot in this object. */ + + for (dim = 0; dim < GridRank+ComputePotential; dim++) { + + /* If dim==GridRank then this is the potential. */ + + if (dim == GridRank) + for (i = 0; i < FFTSize; i++) + buffer2[i] = buffer1[i]; + + /* Compute the acceleration for dim in k-space and put the + the result in buffer2 and divide by cell width. */ + + else + if (GreensFunction.ComputeAcceleration(GridRank, FFTDimensionReal, FFTDimension, dim, buffer1, buffer2, GravitatingMassFieldCellSize*a) == FAIL) { + fprintf(stderr, "Error in GreensFunction->ComputeAcceleration.\n"); + return FAIL; + } + + /* Inverse transform the field. */ + + if (FastFourierTransform(buffer2, GridRank, FFTDimensionReal, + FFTDimension, FFT_INVERSE, REAL_TO_COMPLEX) == FAIL) { + fprintf(stderr, "Error in FastFourierTransform (inverse).\n"); + return FAIL; + } + + /* Allocate the accleration field (deleting it first if present). */ + + if (dim < GridRank) { + if (AccelerationField[dim] != NULL) + delete AccelerationField[dim]; + + AccelerationField[dim] = new float[size]; + if (AccelerationField[dim] == NULL) { + perror("error: "); + fprintf(stderr, "Grid_ComputeAccelerationField: malloc error: %d (out of memory?)\n", size); + return FAIL; + } + + /* Copy the acceleration field: + all grids: copy active part of buffer2 to AccelerationField. */ + /* FIX FOR GravityResolution != 1 */ + + for (k = 0; k < GridDimension[2]; k++) { + for (j = 0; j < GridDimension[1]; j++) { + for (i = 0; i < GridDimension[0]; i++) { + AccelerationField[dim][INDEX_ACCEL(i,j,k)] = + buffer2[INDEX_FFT(i+Offset[0], j+Offset[1], k+Offset[2])]; + } + } + } + + } else { + + /* Allocate potential field and copy. */ + + if (PotentialField == NULL) + PotentialField = new float[GravSize]; + + for (k = 0; k < FFTDimensionGrav[2]; k++) { + for (j = 0; j < FFTDimensionGrav[1]; j++) { + for (i = 0; i < FFTDimensionGrav[0]; i++) { + PotentialField[INDEX_GRAV(i+FFTStartIndex[0], j+FFTStartIndex[1], k+FFTStartIndex[2])] = buffer1[INDEX_FFT(i,j,k)]; + } + } + } + + + } // end: if dim < GridRank (compute accel or potential) + + } // end: loop over acceleration dims + + /* If requested, compute the gravitational potential sum now. */ + /* + if (ComputePotential) { + + int PotStart[MAX_DIMENSION], PotEnd[MAX_DIMENSION]; + float CellVolume = 1; + for (dim = 0; dim < GridRank; dim++) { + PotStart[dim] = nint((GridLeftEdge[dim] - + GravitatingMassFieldLeftEdge[dim])/ + GravitatingMassFieldCellSize); + PotEnd[dim] = nint((GridRightEdge[dim] - + GravitatingMassFieldLeftEdge[dim])/ + GravitatingMassFieldCellSize) - 1; + CellVolume *= GravitatingMassFieldCellSize; + } + if (debug) + printf("PotStart/End = %d %d %d / %d %d %d\n", PotStart[0], PotStart[1], + PotStart[2], PotEnd[0], PotEnd[1], PotEnd[2]); + + PotentialSum = 0; + for (k = PotStart[2]; k <= PotEnd[2]; k++) + for (j = PotStart[1]; j <= PotEnd[1]; j++) { + gravityindex = k*FFTDimensionGrav[0]*FFTDimensionGrav[1] + + j*FFTDimensionGrav[0] + PotStart[0]; + printf("gravityindex = %"ISYM"\n", gravityindex); + for (i = PotStart[0]; i <= PotEnd[0]; i++, gravityindex++) + PotentialSum += 0.5*PotentialField[gravityindex] * + GravitatingMassField[gravityindex]* + CellVolume; + } + } + */ + /* clean up */ + + GreensFunction.Release(); + + delete [] buffer1; + delete [] buffer2; + + return SUCCESS; +} diff --git a/src/enzo/Grid_ComputePotentialFieldAPM.C b/src/enzo/Grid_ComputePotentialFieldAPM.C new file mode 100644 index 000000000..ded2bb5b4 --- /dev/null +++ b/src/enzo/Grid_ComputePotentialFieldAPM.C @@ -0,0 +1,232 @@ +/*********************************************************************** +/ +/ GRID CLASS (COMPUTE THE ACCLERATION FIELDS FROM THE GRAVITATING MASS FIELD) +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" + +/* function prototypes */ + +int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); +int NextLargestFFTSize(int dimension); +int FastFourierTransform(float *buffer, int Rank, int DimensionReal[], + int Dimension[], int direction, int type); +int ReportMemoryUsage(char *header = NULL); +extern "C" void FORTRAN_NAME(copy3d)(float *source, float *dest, + int *sdim1, int *sdim2, int *sdim3, + int *ddim1, int *ddim2, int *ddim3, + int *sstart1, int *sstart2, int *sstart3, + int *dstart1, int *dstart2, int *dststart3); + +#define INDEX_ACCEL(a,b,c) ( ((c)*GridDimension[1] + (b))*GridDimension[0] + (a) ) +#define INDEX_GRAV(a,b,c) ( ((c)*GravitatingMassFieldDimension[1] + (b))*GravitatingMassFieldDimension[0] + (a) ) +#define INDEX_FFT(a,b,c) ( ((c)*FFTDimensionReal[1] + (b))*FFTDimensionReal[0] + (a) ) + + +int grid::ComputePotentialFieldAPM(int RefinementFactor) +{ + /* declarations */ + + int i, j, k, dim, Zero[MAX_DIMENSION], bufferindex, gravityindex; + for (dim = 0; dim < MAX_DIMENSION; dim++) + Zero[dim] = 0; + + /* Compute adot/a at time = t+1/2dt (time-centered). */ + + FLOAT a = 1, dadt; + if (ComovingCoordinates) + if (CosmologyComputeExpansionFactor(Time+0.5*dtFixed, &a, &dadt) == FAIL) { + fprintf(stderr, "Error in CosmologyComputeExpansionFactor.\n"); + return FAIL; + } + + /* Determine the smallest possible dimensions that are: + (a) larger than or equal in size to the gravity grid and + (b) can be directly transformed. This last quantity is + implementation dependant (see NextLargestFFTSize). */ + + int FFTDimension[MAX_DIMENSION], FFTDimensionReal[MAX_DIMENSION]; + int FFTDimensionGrav[MAX_DIMENSION], FFTStartIndex[MAX_DIMENSION]; + for (dim = 0; dim < GridRank; dim++) { + FFTDimensionGrav[dim] = GravitatingMassFieldDimension[dim]; + FFTDimension[dim] = GravitatingMassFieldDimension[dim]; + FFTStartIndex[dim] = 0; + + /* If this is a topgrid periodic, then set the parameters to copy out just + the active region. */ + + if (GravityBoundaryType == TopGridPeriodic) { + FFTStartIndex[dim] = nint( (GridLeftEdge[dim] - GravitatingMassFieldLeftEdge[dim]) / GravitatingMassFieldCellSize); + FFTDimension[dim] = nint( (GridRightEdge[dim]-GridLeftEdge[dim])/GravitatingMassFieldCellSize); + FFTDimensionGrav[dim] = FFTDimension[dim]; + if (NumberOfProcessors > 1) { + fprintf(stderr, "This gravity type doesn't support parallel yet.\n"); + return FAIL; + } + } + + /* If subgrid isolated, then add one convolution kernel room for zero-padding. */ + + if (GravityBoundaryType == SubGridIsolated) + FFTDimension[dim] += nint(RefinementFactor*S2ParticleSize) + FFT_SAFETY_FACTOR; + + /* Set FFT dimension to next largest size we can do. */ + + FFTDimension[dim] = NextLargestFFTSize(FFTDimension[dim]); + FFTDimensionReal[dim] = FFTDimension[dim]; + } + + /* Add two to the declared dimensions of the FFT buffer since some + real-to-complex transforms require this. */ + + FFTDimensionReal[0] += 2; + + /* Compute the size of the FFT buffer and the gravitating field. + Also, If this is the top grid and it's periodic, check to make + sure the FFT size is exactly the same size as GravitatingMassField. */ + + int FFTSize = 1, GravSize = 1; + for (dim = 0; dim < GridRank; dim++) { + FFTSize *= FFTDimensionReal[dim]; + GravSize *= GravitatingMassFieldDimension[dim]; + if (GravityBoundaryType == TopGridPeriodic && + FFTDimension[dim] != FFTDimensionGrav[dim]) { + fprintf(stderr, "Topgrid cannot be periodic with these dimensions.\n"); + fprintf(stderr, " (see NextLargestFFTSize.cc)\n"); + return FAIL; + } + } + + /* Allocate and clear two temporary buffers for the FFT. */ + + float *buffer1 = new float[FFTSize]; + float *buffer2 = new float[FFTSize]; + if (buffer1 == NULL || buffer2 == NULL) { + fprintf(stderr, "Grid_ComputeAccelerationField: malloc error (out of memory?)\n"); + return FAIL; + } + for (i = 0; i < FFTSize; i++) + buffer1[i] = 0.0; + + /* Copy the GravitatingMassField into this buffer (first, clear unused + indexes) and multiply by the gravitational constant (and by the cell + width squared because the Green's function is unitless). */ + + float factor = GravitationalConstant*GravitatingMassFieldCellSize + *GravitatingMassFieldCellSize/a; + printf("factor = %g\n", factor); + for (k = 0; k < FFTDimensionGrav[2]; k++) { + for (j = 0; j < FFTDimensionGrav[1]; j++) { + for (i = 0; i < FFTDimensionGrav[0]; i++) { + buffer1[INDEX_FFT(i,j,k)] = GravitatingMassField[INDEX_GRAV(i+FFTStartIndex[0], j+FFTStartIndex[1], k+FFTStartIndex[2])] * factor; + + } + } + } + + /* Transform the buffer into the fourier domain (in place). */ + + if (FastFourierTransform(buffer1, GridRank, FFTDimensionReal, FFTDimension, + FFT_FORWARD, REAL_TO_COMPLEX) == FAIL) { + fprintf(stderr, "Error in FastFourierTransform (forward).\n"); + return FAIL; + } + + /* Compute appropriate Green's function (not including D(k)). */ + + if (GreensFunction.PrepareGreensFunction(GridRank, FFTDimensionReal, + FFTDimension, GravityBoundaryType, RefinementFactor) == FAIL) { + fprintf(stderr, "Error in GreensFunction->PrepareGreensFunction.\n"); + return FAIL; + } + + /* Multiply the Green's function by the transformed gravity field + and leave the result (the potential) in buffer1. */ + + if (GreensFunction.MultiplyGreensFunction(GridRank, FFTDimensionReal, + FFTDimension, buffer1) == FAIL) { + fprintf(stderr, "Error in GreensFunction->MultiplyGreensFunction.\n"); + return FAIL; + } + + /* Compute the potential with inverse FFT */ + + if (FastFourierTransform(buffer1, GridRank, FFTDimensionReal, + FFTDimension, FFT_INVERSE, REAL_TO_COMPLEX) == FAIL) { + fprintf(stderr, "Error in FastFourierTransform (inverse).\n"); + return FAIL; + } + + /* Allocate potential field and copy. */ + + if (PotentialField == NULL) + PotentialField = new float[GravSize]; + + //printf("In Grid_ComputePotentialFiedlAPM.c, set phi to 7\n"); + + float maxpot = 0.0; + float minpot = 0.0; + for (k = 0; k < FFTDimensionGrav[2]; k++) { + for (j = 0; j < FFTDimensionGrav[1]; j++) { + for (i = 0; i < FFTDimensionGrav[0]; i++) { + PotentialField[INDEX_GRAV(i+FFTStartIndex[0], j+FFTStartIndex[1], k+FFTStartIndex[2])] = buffer1[INDEX_FFT(i,j,k)]; + } + } + } + + /* If requested, compute the gravitational potential sum now. */ + + int PotStart[MAX_DIMENSION], PotEnd[MAX_DIMENSION]; + float CellVolume = 1; + for (dim = 0; dim < GridRank; dim++) { + PotStart[dim] = nint((GridLeftEdge[dim] - + GravitatingMassFieldLeftEdge[dim])/ + GravitatingMassFieldCellSize); + PotEnd[dim] = nint((GridRightEdge[dim] - + GravitatingMassFieldLeftEdge[dim])/ + GravitatingMassFieldCellSize) - 1; + CellVolume *= GravitatingMassFieldCellSize; + } + + printf("PotStart/End = %d %d %d / %d %d %d\n", PotStart[0], PotStart[1], + PotStart[2], PotEnd[0], PotEnd[1], PotEnd[2]); + + PotentialSum = 0; + for (k = PotStart[2]; k <= PotEnd[2]; k++) + for (j = PotStart[1]; j <= PotEnd[1]; j++) { + gravityindex = k*FFTDimensionGrav[0]*FFTDimensionGrav[1] + + j*FFTDimensionGrav[0] + PotStart[0]; + for (i = PotStart[0]; i <= PotEnd[0]; i++, gravityindex++) + PotentialSum += 0.5*PotentialField[gravityindex] * + GravitatingMassField[gravityindex]* + CellVolume; + } + printf("PotentialSum = %g\n", PotentialSum); + + /* clean up */ + + GreensFunction.Release(); + + delete [] buffer1; + delete [] buffer2; + + return SUCCESS; +} diff --git a/src/enzo/Grid_CopyParentToGravitatingFieldBoundary.C b/src/enzo/Grid_CopyParentToGravitatingFieldBoundary.C index d30422e07..58e7f513b 100644 --- a/src/enzo/Grid_CopyParentToGravitatingFieldBoundary.C +++ b/src/enzo/Grid_CopyParentToGravitatingFieldBoundary.C @@ -55,6 +55,11 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) if (GravityBoundaryType != SubGridIsolated) return SUCCESS; + + /* Return SUCCESS if we are depositing only baryons and there is not baryonfield */ + + if (DepositAlsoParentGridAndSiblingsParticles && NumberOfBaryonFields == 0) + return SUCCESS; /* Declarations. */ @@ -76,27 +81,43 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) /* Compute the ParentOffset (in grid units) and ParentStartIndex and the region dim (in parent units). */ + + // Get the parent density if required + int DensNum, GENum, Vel1Num, Vel2Num, Vel3Num, TENum; + if (DepositAlsoParentGridAndSiblingsParticles) { // we only need the baryons + if (ParentGrid->IdentifyPhysicalQuantities(DensNum, GENum, Vel1Num, Vel2Num, + Vel3Num, TENum) == FAIL) + ENZO_FAIL("Grid_CopyParentToGravitatingFieldBoundary.C: Error in IdentifyPhysicalQuantities.\n"); + if (ParentGrid->BaryonField[DensNum] == NULL) + ENZO_FAIL("NO Density field in ParentGrid"); + } + for (dim = 0; dim < GridRank; dim++) { SubGridExtra[dim] = nint((GridLeftEdge[dim] - GravitatingMassFieldLeftEdge[dim]) - /GravitatingMassFieldCellSize); - // SubGridExtra[dim] = nint((CellLeftEdge[dim][0] - - // GravitatingMassFieldLeftEdge[dim]) - // /GravitatingMassFieldCellSize); - ParentOffset[dim] = nint((GravitatingMassFieldLeftEdge[dim] - - ParentGrid->GravitatingMassFieldLeftEdge[dim])/ - GravitatingMassFieldCellSize); - ParentStartIndex[dim] = ParentOffset[dim]/Refinement[dim] - 1; - ParentTempDim[dim] = (ParentOffset[dim] + - GravitatingMassFieldDimension[dim]-1)/Refinement[dim] - - ParentStartIndex[dim] + 3; - ParentDim[dim] = ParentGrid->GravitatingMassFieldDimension[dim]; - size *= GravitatingMassFieldDimension[dim]; + /GravitatingMassFieldCellSize); + + if (DepositAlsoParentGridAndSiblingsParticles) { // Density + ParentOffset[dim] = nint((GravitatingMassFieldLeftEdge[dim] - ParentGrid->CellLeftEdge[dim][0]) / GravitatingMassFieldCellSize); + ParentStartIndex[dim] = ParentOffset[dim]/Refinement[dim]; + ParentTempDim[dim] = (ParentOffset[dim] + GravitatingMassFieldDimension[dim])/Refinement[dim] - ParentStartIndex[dim]; + ParentDim[dim] = ParentGrid->GridDimension[dim]; + size *= GravitatingMassFieldDimension[dim]; + } + + else { // GravitatingMassField + ParentOffset[dim] = nint((GravitatingMassFieldLeftEdge[dim] - ParentGrid->GravitatingMassFieldLeftEdge[dim]) / GravitatingMassFieldCellSize); + ParentStartIndex[dim] = ParentOffset[dim]/Refinement[dim] - 1; + ParentTempDim[dim] = (ParentOffset[dim] + GravitatingMassFieldDimension[dim]-1)/Refinement[dim] - ParentStartIndex[dim] + 3; + ParentDim[dim] = ParentGrid->GravitatingMassFieldDimension[dim]; + size *= GravitatingMassFieldDimension[dim]; + } /* end if DepositAlsoParentGridAndSiblingsParticles */ + if (ParentStartIndex[dim] < 0 || - ParentStartIndex[dim]+ParentTempDim[dim] > ParentDim[dim]) { - ENZO_VFAIL("ParentStartIndex[%"ISYM"] = %"ISYM" ParentTempDim = %"ISYM"(%"ISYM").\n", - dim, ParentStartIndex[dim], ParentTempDim[dim], ParentDim[dim]) + ParentStartIndex[dim]+ParentTempDim[dim] > ParentDim[dim]) { + ENZO_VFAIL("ParentStartIndex[%"ISYM"] = %"ISYM" ParentTempDim = %"ISYM"(%"ISYM").\n", + dim, ParentStartIndex[dim], ParentTempDim[dim], ParentDim[dim]) } } @@ -115,8 +136,18 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) the grid. */ if (ProcessorNumber != ParentGrid->ProcessorNumber) { - ParentGrid->CommunicationSendRegion(ParentGrid, ProcessorNumber, - GRAVITATING_MASS_FIELD, NEW_ONLY, ParentStartIndex, ParentTempDim); + + if (DepositAlsoParentGridAndSiblingsParticles) { // Density + ParentGrid->CommunicationSendRegion(ParentGrid, ProcessorNumber, + DensNum, NEW_ONLY, + ParentStartIndex, ParentTempDim); + } + else {// GravitationalMassField + ParentGrid->CommunicationSendRegion(ParentGrid, ProcessorNumber, + GRAVITATING_MASS_FIELD, NEW_ONLY, + ParentStartIndex, ParentTempDim); + } /* end if DepositAlsoParentGridAndSiblingsParticles*/ + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE || CommunicationDirection == COMMUNICATION_SEND) return SUCCESS; @@ -136,6 +167,10 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) #define NO_INTERPOLATE_LINEAR #ifdef INTERPOLATE_LINEAR + + // If depositing baryons, don't use linear interpolation - there might not be enough cells + if (DepositAlsoParentGridAndSiblingsParticles) + ENZO_FAIL("Error in grid->CopyParentToGravitatingFieldBoundary: cannot use linear interpolation with baryons deposition\n"); FORTRAN_NAME(prolong)(ParentGrid->GravitatingMassField, GravitatingMassField, &GridRank, @@ -153,18 +188,21 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) if(ParentGrid->GravitatingMassField == NULL) ENZO_FAIL("NO GMF in PARENT"); int iparent, jparent, kparent, parentindex; for (k = 0; k < GravitatingMassFieldDimension[2]; k++) { + kparent = nint((k + ParentOffset[2])/Refinement[2]); for (j = 0; j < GravitatingMassFieldDimension[1]; j++) { + jparent = nint((j + ParentOffset[1])/Refinement[1]); parentindex = (kparent*ParentDim[1] + jparent)*ParentDim[0]; - gravityindex = (k*GravitatingMassFieldDimension[1] + j)* - GravitatingMassFieldDimension[0]; + gravityindex = (k*GravitatingMassFieldDimension[1] + j) * GravitatingMassFieldDimension[0]; for (i = 0; i < GravitatingMassFieldDimension[0]; i++, gravityindex++) { - iparent = nint((i+ParentOffset[0])/Refinement[0]); - - GravitatingMassField[gravityindex] = - ParentGrid->GravitatingMassField[parentindex+iparent]; - + iparent = nint((i+ParentOffset[0])/Refinement[0]); + + if (DepositAlsoParentGridAndSiblingsParticles) // Density + GravitatingMassField[gravityindex] = ParentGrid->BaryonField[DensNum][parentindex+iparent]; + + else // GravitationalMassField + GravitatingMassField[gravityindex] = ParentGrid->GravitatingMassField[parentindex+iparent]; } } } @@ -174,8 +212,14 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) /* Clean up parent. */ if (MyProcessorNumber != ParentGrid->ProcessorNumber) { - delete [] ParentGrid->GravitatingMassField; - ParentGrid->GravitatingMassField = NULL; + if (DepositAlsoParentGridAndSiblingsParticles) { + delete [] ParentGrid->BaryonField[DensNum]; + ParentGrid->BaryonField[DensNum] = NULL; + } + else { + delete [] ParentGrid->GravitatingMassField; + ParentGrid->GravitatingMassField = NULL; + } /* end if DepositAlsoParentGridAndSiblingsParticles */ } /* Add one to field to account for one subtracted in ComovingSourceTerm. */ @@ -183,6 +227,9 @@ int grid::CopyParentToGravitatingFieldBoundary(grid *ParentGrid) if (ComovingCoordinates) for (i = 0; i < size; i++) GravitatingMassField[i] += 1.0; + if (ProblemType == 44 && GravitySolverType == GRAVITY_SOLVER_FAST) // TestGravitySineWave + for (i = 0; i < size; i++) + GravitatingMassField[i] += 2.0; /* Clear the region of GMF that will overlap with real grid points (i.e. clear the region that we shouldn't have set in the above loop). */ diff --git a/src/enzo/Grid_DeleteAllButParticles.C b/src/enzo/Grid_DeleteAllButParticles.C index b1d2ff448..6f25469bc 100644 --- a/src/enzo/Grid_DeleteAllButParticles.C +++ b/src/enzo/Grid_DeleteAllButParticles.C @@ -12,7 +12,7 @@ #include #include - + #include "ErrorExceptions.h" #include "macros_and_parameters.h" #include "typedefs.h" @@ -21,26 +21,34 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" - + /* function prototypes */ - + void grid::DeleteAllButParticles() { - + int i; - + // this->DeleteParticles(); - + for (i = 0; i < MAX_DIMENSION; i++) { delete [] ParticleAcceleration[i]; delete [] AccelerationField[i]; - + ParticleAcceleration[i] = NULL; AccelerationField[i] = NULL; } + + if (GravitySolverType == GRAVITY_SOLVER_APM) { + for (i = 0; i < MAX_DIMENSION; i++) { + delete [] AccelerationFieldExternalAPM[i]; + AccelerationFieldExternalAPM[i] = NULL; + } + } + delete [] ParticleAcceleration[MAX_DIMENSION]; ParticleAcceleration[MAX_DIMENSION] = NULL; - + for (i = 0; i < MAX_NUMBER_OF_BARYON_FIELDS; i++) { delete [] BaryonField[i]; delete [] OldBaryonField[i]; @@ -55,13 +63,13 @@ void grid::DeleteAllButParticles() OldAccelerationField[i] = NULL; } #endif - + delete [] PotentialField; delete [] GravitatingMassField; delete [] GravitatingMassFieldParticles; - + PotentialField = NULL; GravitatingMassField = NULL; GravitatingMassFieldParticles = NULL; - + } diff --git a/src/enzo/Grid_DeleteAllFields.C b/src/enzo/Grid_DeleteAllFields.C index 8441aaaea..5f0cb1fc7 100644 --- a/src/enzo/Grid_DeleteAllFields.C +++ b/src/enzo/Grid_DeleteAllFields.C @@ -12,7 +12,7 @@ #include #include - + #include "ErrorExceptions.h" #include "macros_and_parameters.h" #include "typedefs.h" @@ -21,26 +21,34 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" - + /* function prototypes */ - + void grid::DeleteAllFields() { - + int i; - + this->DeleteParticles(); - + for (i = 0; i < MAX_DIMENSION; i++) { delete [] ParticleAcceleration[i]; delete [] AccelerationField[i]; - + ParticleAcceleration[i] = NULL; AccelerationField[i] = NULL; } + + if (GravitySolverType == GRAVITY_SOLVER_APM) { + for (i = 0; i < MAX_DIMENSION; i++) { + delete [] AccelerationFieldExternalAPM[i]; + AccelerationFieldExternalAPM[i] = NULL; + } + } + delete [] ParticleAcceleration[MAX_DIMENSION]; ParticleAcceleration[MAX_DIMENSION] = NULL; - + for (i = 0; i < MAX_NUMBER_OF_BARYON_FIELDS; i++) { delete [] BaryonField[i]; delete [] OldBaryonField[i]; @@ -55,7 +63,7 @@ void grid::DeleteAllFields() OldAccelerationField[i] = NULL; } #endif - + for(i=0;i<3;i++){ if(MagneticField[i] != NULL){ delete [] MagneticField[i]; @@ -83,9 +91,9 @@ void grid::DeleteAllFields() delete [] PotentialField; delete [] GravitatingMassField; delete [] GravitatingMassFieldParticles; - + PotentialField = NULL; GravitatingMassField = NULL; GravitatingMassFieldParticles = NULL; - + } diff --git a/src/enzo/Grid_DepositParticlePositions.C b/src/enzo/Grid_DepositParticlePositions.C index 807ac8a37..6bc19565e 100644 --- a/src/enzo/Grid_DepositParticlePositions.C +++ b/src/enzo/Grid_DepositParticlePositions.C @@ -34,129 +34,160 @@ #include "Grid.h" #include "ActiveParticle.h" #include "communication.h" - + /* function prototypes */ - +extern "C" void PFORTRAN_NAME(cic_deposit_reject)(FLOAT *posx, FLOAT *posy, + FLOAT *posz, int *ndim, int *npositions, + float *densfield, float *field, + FLOAT *leftedge, + int *dim1, int *dim2, int *dim3, float *cellsize, + float *cloudsize, + float *effectiveleft, + int *effectivestart, + int *effectivesim); + extern "C" void PFORTRAN_NAME(cic_deposit)(FLOAT *posx, FLOAT *posy, - FLOAT *posz, int *ndim, int *npositions, - float *densfield, float *field, FLOAT *leftedge, - int *dim1, int *dim2, int *dim3, float *cellsize, - float *cloudsize); + FLOAT *posz, int *ndim, int *npositions, + float *densfield, float *field, FLOAT *leftedge, + int *dim1, int *dim2, int *dim3, float *cellsize, + float *cloudsize); extern "C" void PFORTRAN_NAME(ngp_deposit)(FLOAT *posx, FLOAT *posy, - FLOAT *posz, int *ndim, int *npositions, - float *densfield, float *field, FLOAT *leftedge, - int *dim1, int *dim2, int *dim3, float *cellsize); - + FLOAT *posz, int *ndim, int *npositions, + float *densfield, float *field, FLOAT *leftedge, + int *dim1, int *dim2, int *dim3, float *cellsize); + extern "C" void PFORTRAN_NAME(smooth_deposit)(FLOAT *posx, FLOAT *posy, - FLOAT *posz, int *ndim, int *npositions, - float *densfield, float *field, FLOAT *leftedge, - int *dim1, int *dim2, int *dim3, float *cellsize, - float *rsmooth); + FLOAT *posz, int *ndim, int *npositions, + float *densfield, float *field, FLOAT *leftedge, + int *dim1, int *dim2, int *dim3, float *cellsize, + float *rsmooth); #ifdef USE_MPI -int CommunicationBufferedSend(void *buffer, int size, MPI_Datatype Type, - int Target, int Tag, MPI_Comm CommWorld, - int BufferSize); +int CommunicationBufferedSend(void *buffer, int size, MPI_Datatype Type, + int Target, int Tag, MPI_Comm CommWorld, + int BufferSize); #endif /* USE_MPI */ double ReturnWallTime(void); +void DepositPositionsPileUpTSC1D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int EffectiveStart[], int EffectiveDim[], + float CellSize); +void DepositPositionsPileUpTSC2D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int EffectiveStart[], int EffectiveDim[], + int Dimension[], float CellSize); +void DepositPositionsPileUpTSC3D(FLOAT *Position[], float *Mass, + int Number, float *Field, FLOAT LeftEdge[], + int EffectiveStart[], int EffectiveDim[], + int Dimension[], float CellSize); + /* This controls the maximum particle mass which will be deposited in the MASS_FLAGGING_FIELD. Only set in Grid_SetFlaggingField. */ - + float DepositParticleMaximumParticleMass = 0; - + int grid::DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, - int DepositField) + int DepositField) { - + /* Return if this doesn't concern us. */ - + if (TargetGrid->CommunicationMethodShouldExit(this) || (NumberOfParticles == 0 && NumberOfActiveParticles == 0)) return SUCCESS; - -// fprintf(stderr, "----DPP: MyPN = %"ISYM", PN = %"ISYM", TGPN = %"ISYM", DIR (R=1,S=2) = %"ISYM", NP = %"ISYM"\n", -// MyProcessorNumber, ProcessorNumber, TargetGrid->ProcessorNumber, CommunicationDirection, NumberOfParticles); - + + // fprintf(stderr, "----DPP: MyPN = %"ISYM", PN = %"ISYM", TGPN = %"ISYM", DIR (R=1,S=2) = %"ISYM", NP = %"ISYM"\n", + // MyProcessorNumber, ProcessorNumber, TargetGrid->ProcessorNumber, CommunicationDirection, NumberOfParticles); + /* Declarations. */ - + int dim, i, j, k, size, index1, index2; - int Dimension[] = {1,1,1}; - int OriginalDimension[] = {1,1,1}; - long_int Offset[] = {0,0,0}; - float MassFactor = 1.0, *ParticleMassTemp, *ParticleMassPointer; - FLOAT CellSize, CloudSize; - float *ParticleMassPointerSink; + int Dimension[] = {1, 1, 1}; + int OriginalDimension[] = {1, 1, 1}; + long_int Offset[] = {0, 0, 0}; + float MassFactor = 1.0, *ParticleMassTemp, *ParticleMassPointer; + float CellSize, CloudSize; + float *ParticleMassPointerSink; float TimeDifference = 0; - FLOAT LeftEdge[MAX_DIMENSION], OriginalLeftEdge[MAX_DIMENSION]; + FLOAT LeftEdge[MAX_DIMENSION], RightEdge[MAX_DIMENSION], OriginalLeftEdge[MAX_DIMENSION]; float *DepositFieldPointer, *OriginalDepositFieldPointer; /* 1) GravitatingMassField. */ - - if (DepositField == GRAVITATING_MASS_FIELD) { + + if (DepositField == GRAVITATING_MASS_FIELD) + { if (TargetGrid->GravitatingMassFieldCellSize <= 0) TargetGrid->InitializeGravitatingMassField(RefineBy); DepositFieldPointer = TargetGrid->GravitatingMassField; - CellSize = TargetGrid->GravitatingMassFieldCellSize; - CloudSize = CellWidth[0][0]; - for (dim = 0; dim < GridRank; dim++) { - LeftEdge[dim] = TargetGrid->GravitatingMassFieldLeftEdge[dim]; + CellSize = TargetGrid->GravitatingMassFieldCellSize; + CloudSize = CellWidth[0][0]; + for (dim = 0; dim < GridRank; dim++) + { + LeftEdge[dim] = TargetGrid->GravitatingMassFieldLeftEdge[dim]; Dimension[dim] = TargetGrid->GravitatingMassFieldDimension[dim]; } } - + /* 2) GravitatingMassFieldParticles. */ - - else if (DepositField == GRAVITATING_MASS_FIELD_PARTICLES) { + + else if (DepositField == GRAVITATING_MASS_FIELD_PARTICLES) + { if (TargetGrid->GravitatingMassFieldParticlesCellSize <= 0) TargetGrid->InitializeGravitatingMassFieldParticles(RefineBy); DepositFieldPointer = TargetGrid->GravitatingMassFieldParticles; - CellSize = TargetGrid->CellWidth[0][0]; - CloudSize = CellWidth[0][0]; - for (dim = 0; dim < GridRank; dim++) { - LeftEdge[dim] = TargetGrid->GravitatingMassFieldParticlesLeftEdge[dim]; + CellSize = float(TargetGrid->GravitatingMassFieldParticlesCellSize); + CloudSize = CellWidth[0][0]; + for (dim = 0; dim < GridRank; dim++) + { + LeftEdge[dim] = TargetGrid->GravitatingMassFieldParticlesLeftEdge[dim]; Dimension[dim] = TargetGrid->GravitatingMassFieldParticlesDimension[dim]; } } - + /* 3) MassFlaggingField */ - - else if (DepositField == MASS_FLAGGING_FIELD) { + + else if (DepositField == MASS_FLAGGING_FIELD) + { DepositFieldPointer = TargetGrid->MassFlaggingField; - CellSize = TargetGrid->CellWidth[0][0]; - CloudSize = CellWidth[0][0]; - for (dim = 0; dim < GridRank; dim++) { - LeftEdge[dim] = TargetGrid->CellLeftEdge[dim][0]; + CellSize = TargetGrid->CellWidth[0][0]; + CloudSize = CellWidth[0][0]; + for (dim = 0; dim < GridRank; dim++) + { + LeftEdge[dim] = TargetGrid->CellLeftEdge[dim][0]; Dimension[dim] = TargetGrid->GridDimension[dim]; } } /* 4) ParticleMassFlaggingField */ - -// else if (DepositField == PARTICLE_MASS_FLAGGING_FIELD) { -// DepositFieldPointer = TargetGrid->ParticleMassFlaggingField; -// CellSize = float(TargetGrid->CellWidth[0][0]); -// for (dim = 0; dim < GridRank; dim++) { -// LeftEdge[dim] = TargetGrid->CellLeftEdge[dim][0]; -// Dimension[dim] = TargetGrid->GridDimension[dim]; -// } -// } - + + // else if (DepositField == PARTICLE_MASS_FLAGGING_FIELD) { + // DepositFieldPointer = TargetGrid->ParticleMassFlaggingField; + // CellSize = float(TargetGrid->CellWidth[0][0]); + // for (dim = 0; dim < GridRank; dim++) { + // LeftEdge[dim] = TargetGrid->CellLeftEdge[dim][0]; + // Dimension[dim] = TargetGrid->GridDimension[dim]; + // } + // } + /* 5) error */ - - else { - ENZO_VFAIL("DepositField = %"ISYM" not recognized.\n", DepositField) - } + + else + { + ENZO_VFAIL("DepositField = %" ISYM " not recognized.\n", DepositField) + } /* If on different processors, generate a temporary field to hold the density. */ - if (ProcessorNumber != TargetGrid->ProcessorNumber) { + if (ProcessorNumber != TargetGrid->ProcessorNumber) + { /* If this is the target grid processor, then record the orginal field characteristics so we can add it in when the data arrives. */ - for (dim = 0; dim < GridRank; dim++) { + for (dim = 0; dim < GridRank; dim++) + { OriginalLeftEdge[dim] = LeftEdge[dim]; OriginalDimension[dim] = Dimension[dim]; } @@ -166,34 +197,41 @@ int grid::DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, grid where the particles reside. */ size = 1; - for (dim = 0; dim < GridRank; dim++) { - LeftEdge[dim] = (long_int((FLOAT)GridLeftEdge[dim]/CellSize)-2)*CellSize; - Offset[dim] = nlongint((LeftEdge[dim] - OriginalLeftEdge[dim])/CellSize); - if (Offset[dim] < 0) { - fprintf(stderr, "P(%d)(1): dx=%"GOUTSYM"/%"GOUTSYM" = %"GOUTSYM"\n", - MyProcessorNumber, CellSize, CellWidth[0][0], - CellSize/CellWidth[0][0]); - fprintf(stderr, "P(%d)(2): %"GOUTSYM" %"GOUTSYM" %"GOUTSYM"\n", - MyProcessorNumber, OriginalLeftEdge[0], OriginalLeftEdge[1], - OriginalLeftEdge[2]); - fprintf(stderr, "P(%d)(3): %"GOUTSYM" %"GOUTSYM" %"GOUTSYM"\n", - MyProcessorNumber, GridLeftEdge[0], GridLeftEdge[1], - GridLeftEdge[2]); - fprintf(stderr, "P(%d)(4): %"GOUTSYM" %"GOUTSYM" %"GOUTSYM"\n", - MyProcessorNumber, GridRightEdge[0], GridRightEdge[1], - GridRightEdge[2]); - fprintf(stderr, "P(%d)(5): %"GOUTSYM" %"GOUTSYM" %"GOUTSYM"\n", - MyProcessorNumber, LeftEdge[0], LeftEdge[1], LeftEdge[2]); - fprintf(stderr, "P(%d)(6): %ld %ld %ld - %ld %ld %ld\n", - MyProcessorNumber, Offset[0], Offset[1], Offset[2], - Dimension[0], Dimension[1], Dimension[2]); - fprintf(stderr, "P(%d)(7): %"GOUTSYM" %ld\n", - MyProcessorNumber, (int(GridLeftEdge[dim]/CellSize)-2)*CellSize, - int(GridLeftEdge[dim]/CellSize)); - - ENZO_VFAIL("Offset[%d] = %d < 0\n", dim, Offset[dim]) + for (dim = 0; dim < GridRank; dim++) + { + LeftEdge[dim] = (int(GridLeftEdge[dim] / CellSize) - 2) * CellSize; + LeftEdge[dim] = max(LeftEdge[dim], OriginalLeftEdge[dim]); + RightEdge[dim] = min(GridRightEdge[dim], OriginalLeftEdge[dim] * Dimension[dim] * CellSize); + Offset[dim] = nint((LeftEdge[dim] - OriginalLeftEdge[dim]) / CellSize); + if (Offset[dim] < 0) + { + fprintf(stderr, "P(%d)(1): dx=%" GOUTSYM "/%" GOUTSYM " = %" GOUTSYM "\n", + MyProcessorNumber, CellSize, CellWidth[0][0], + CellSize / CellWidth[0][0]); + fprintf(stderr, "P(%d)(2): %" GOUTSYM " %" GOUTSYM " %" GOUTSYM "\n", + MyProcessorNumber, OriginalLeftEdge[0], OriginalLeftEdge[1], + OriginalLeftEdge[2]); + fprintf(stderr, "P(%d)(3): %" GOUTSYM " %" GOUTSYM " %" GOUTSYM "\n", + MyProcessorNumber, GridLeftEdge[0], GridLeftEdge[1], + GridLeftEdge[2]); + fprintf(stderr, "P(%d)(4): %" GOUTSYM " %" GOUTSYM " %" GOUTSYM "\n", + MyProcessorNumber, GridRightEdge[0], GridRightEdge[1], + GridRightEdge[2]); + fprintf(stderr, "P(%d)(5): %" GOUTSYM " %" GOUTSYM " %" GOUTSYM "\n", + MyProcessorNumber, LeftEdge[0], LeftEdge[1], LeftEdge[2]); + fprintf(stderr, "P(%d)(6): %ld %ld %ld - %ld %ld %ld\n", + MyProcessorNumber, Offset[0], Offset[1], Offset[2], + Dimension[0], Dimension[1], Dimension[2]); + fprintf(stderr, "P(%d)(7): %" GOUTSYM " %ld\n", + MyProcessorNumber, (int(GridLeftEdge[dim] / CellSize) - 2) * CellSize, + int(GridLeftEdge[dim] / CellSize)); + + ENZO_VFAIL("Offset[%d] = %d < 0\n", dim, Offset[dim]) } - Dimension[dim] = int((GridRightEdge[dim] - LeftEdge[dim])/CellSize) + 3; + Dimension[dim] = int((RightEdge[dim] - LeftEdge[dim]) / CellSize) + 3; + if (Dimension[dim] < 3) + return SUCCESS; + size *= Dimension[dim]; } @@ -202,83 +240,88 @@ int grid::DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, #ifdef USE_MPI if (CommunicationDirection == COMMUNICATION_RECEIVE) - DepositFieldPointer = - CommunicationReceiveBuffer[CommunicationReceiveIndex]; - else { + DepositFieldPointer = + CommunicationReceiveBuffer[CommunicationReceiveIndex]; + else + { DepositFieldPointer = new float[size]; if (MyProcessorNumber == ProcessorNumber) - for (i = 0; i < size; i++) - DepositFieldPointer[i] = 0; + for (i = 0; i < size; i++) + DepositFieldPointer[i] = 0; } #endif /* USE_MPI */ } // ENDIF different processors - if (MyProcessorNumber == ProcessorNumber) { + if (MyProcessorNumber == ProcessorNumber) + { /* If using CIC-mode deposit, then set cloudsize equal to cellsize. */ if (ParticleSubgridDepositMode == CIC_DEPOSIT) CloudSize = CellSize; - + /* If the Target is this grid and the DepositField is MassFlaggingField, then multiply the Particle density by the volume to get the mass. */ if (this == TargetGrid && DepositField == MASS_FLAGGING_FIELD) for (dim = 0; dim < GridRank; dim++) - MassFactor *= CellWidth[dim][0]; - + MassFactor *= CellWidth[dim][0]; + /* If the DepositGrid and this grid are not the same, we must adjust the particle 'mass'. */ - - if (this != TargetGrid) { - + + if (this != TargetGrid) + { + /* Find the difference in resolution between this grid and TargetGrid. */ - + float RefinementFactors[MAX_DIMENSION]; this->ComputeRefinementFactorsFloat(TargetGrid, RefinementFactors); - + /* Compute the implied difference in 'mass' between particles in this grid and those in TargetGrid. */ - + for (dim = 0; dim < GridRank; dim++) - MassFactor *= RefinementFactors[dim]; - + MassFactor *= RefinementFactors[dim]; + } // ENDIF (this != TargetGrid) /* Check if we are smoothing. */ int SmoothField = (DepositPositionsParticleSmoothRadius <= CellSize) ? FALSE : TRUE; - + /* If required, Change the mass of particles in this grid. */ - - if (MassFactor != 1.0 || - ((StarParticleCreation == (1 << SINK_PARTICLE)) && - SmoothField == TRUE)) { + + if (MassFactor != 1.0 || + ((StarParticleCreation == (1 << SINK_PARTICLE)) && + SmoothField == TRUE)) + { ParticleMassTemp = new float[NumberOfParticles]; for (i = 0; i < NumberOfParticles; i++) - ParticleMassTemp[i] = ParticleMass[i]*MassFactor; + ParticleMassTemp[i] = ParticleMass[i] * MassFactor; ParticleMassPointer = ParticleMassTemp; - } else + } + else ParticleMassPointer = ParticleMass; - + /* If the target field is MASS_FLAGGING_FIELD, then set masses of particles which are too large to zero (to prevent run-away refinement). */ - + if (DepositField == MASS_FLAGGING_FIELD && - DepositParticleMaximumParticleMass > 0 && MassFactor != 1.0) + DepositParticleMaximumParticleMass > 0 && MassFactor != 1.0) for (i = 0; i < NumberOfParticles; i++) - ParticleMassPointer[i] = min(DepositParticleMaximumParticleMass, - ParticleMassPointer[i]); - + ParticleMassPointer[i] = min(DepositParticleMaximumParticleMass, + ParticleMassPointer[i]); + /* Compute difference between current time and DepositTime. */ - + TimeDifference = DepositTime - Time; - + /* Move particles to positions at Time + TimeDifference. */ - - //The second argument forces the update even if + + //The second argument forces the update even if //MyProcessor == Target->ProcessorNumber != this->ProcessorNumber this->UpdateParticlePosition(TimeDifference, TRUE); @@ -293,144 +336,197 @@ int grid::DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, /* If using sink particles, then create a second field of unsmoothed sink particles (since we don't want sink particles smoothed -- they are stellar sized). */ - /* Note that several types of particles may be appropriate for this, + /* Note that several types of particles may be appropriate for this, but they will have to be added if needed. */ - if ((this->ReturnNumberOfStarParticles() > 0) && - (StarParticleCreation == (1 << SINK_PARTICLE)) && SmoothField == TRUE) { + if ((this->ReturnNumberOfStarParticles() > 0) && + (StarParticleCreation == (1 << SINK_PARTICLE)) && SmoothField == TRUE) + { ParticleMassPointerSink = new float[NumberOfParticles]; - for (i = 0; i < NumberOfParticles; i++) { - if (ParticleType[i] == PARTICLE_TYPE_STAR) { - ParticleMassPointerSink[i] = ParticleMassPointer[i]; - ParticleMassPointer[i] = 0; - } else { - ParticleMassPointerSink[i] = 0; - } + for (i = 0; i < NumberOfParticles; i++) + { + if (ParticleType[i] == PARTICLE_TYPE_STAR) + { + ParticleMassPointerSink[i] = ParticleMassPointer[i]; + ParticleMassPointer[i] = 0; + } + else + { + ParticleMassPointerSink[i] = 0; + } } - /* Deposit sink particles (only) to field using CIC or NGP. + /* Deposit sink particles (only) to field using CIC or NGP. (only use NGP if cellsize > cloudsize - i.e. source is subgrid) */ - - if (ParticleSubgridDepositMode == NGP_DEPOSIT && CellSize > 1.5*CloudSize) { - PFORTRAN_NAME(ngp_deposit)( - ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], - &GridRank, &NumberOfParticles, ParticleMassPointerSink, DepositFieldPointer, - LeftEdge, Dimension, Dimension+1, Dimension+2, &FCellSize); - } else { - PFORTRAN_NAME(cic_deposit)( - ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], - &GridRank, &NumberOfParticles, ParticleMassPointerSink, DepositFieldPointer, - LeftEdge, Dimension, Dimension+1, Dimension+2, &FCellSize, &FCloudSize); - } - delete [] ParticleMassPointerSink; + if (ParticleSubgridDepositMode == NGP_DEPOSIT && CellSize > 1.5 * CloudSize) + { + PFORTRAN_NAME(ngp_deposit) + ( + ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], + &GridRank, &NumberOfParticles, ParticleMassPointerSink, DepositFieldPointer, + LeftEdge, Dimension, Dimension + 1, Dimension + 2, &FCellSize); + } + else + { + PFORTRAN_NAME(cic_deposit) + ( + ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], + &GridRank, &NumberOfParticles, ParticleMassPointerSink, DepositFieldPointer, + LeftEdge, Dimension, Dimension + 1, Dimension + 2, &FCellSize, &FCloudSize); + } + delete[] ParticleMassPointerSink; } - + /* Deposit particles. */ - if (SmoothField == FALSE) { - - // fprintf(stderr, "------DP Call Fortran cic_deposit with CellSize = %"GSYM"\n", CellSize); - - /* Deposit sink particles (only) to field using CIC or NGP. + if (SmoothField == FALSE) + { + + if (GravitySolverType == GRAVITY_SOLVER_FAST) + { + + // fprintf(stderr, "------DP Call Fortran cic_deposit with CellSize = %"GSYM"\n", CellSize); + + /* Deposit sink particles (only) to field using CIC or NGP. (only use NGP if cellsize > cloudsize - i.e. source is subgrid) */ - if (ParticleSubgridDepositMode == NGP_DEPOSIT && CellSize > 1.5*CloudSize) { - PFORTRAN_NAME(ngp_deposit) - (ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], - &GridRank, &NumberOfParticles, ParticleMassPointer, DepositFieldPointer, - LeftEdge, Dimension, Dimension+1, Dimension+2, &FCellSize); - } else { - PFORTRAN_NAME(cic_deposit) - (ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], - &GridRank, &NumberOfParticles, ParticleMassPointer, DepositFieldPointer, - LeftEdge, Dimension, Dimension+1, Dimension+2, &FCellSize, &FCloudSize); + if (ParticleSubgridDepositMode == NGP_DEPOSIT && CellSize > 1.5 * CloudSize) + { + PFORTRAN_NAME(ngp_deposit) + (ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], + &GridRank, &NumberOfParticles, ParticleMassPointer, DepositFieldPointer, + LeftEdge, Dimension, Dimension + 1, Dimension + 2, &CellSize); + } + else + { + PFORTRAN_NAME(cic_deposit) + (ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], + &GridRank, &NumberOfParticles, ParticleMassPointer, DepositFieldPointer, + LeftEdge, Dimension, Dimension + 1, Dimension + 2, &CellSize, &CloudSize); + } } - - } else { + else if (GravitySolverType == GRAVITY_SOLVER_APM) + { + + /* With APM solver, use TSC deposition. */ + int EffectiveStartIndex[] = {0, 0, 0}; + + if (GridRank == 1) + DepositPositionsPileUpTSC1D(ParticlePosition, ParticleMassPointer, + NumberOfParticles, DepositFieldPointer, + LeftEdge, EffectiveStartIndex, + Dimension, CellSize); + + if (GridRank == 2) + DepositPositionsPileUpTSC2D(ParticlePosition, ParticleMassPointer, + NumberOfParticles, DepositFieldPointer, + LeftEdge, EffectiveStartIndex, + Dimension, Dimension, CellSize); + + if (GridRank == 3) + DepositPositionsPileUpTSC3D(ParticlePosition, ParticleMassPointer, + NumberOfParticles, DepositFieldPointer, + LeftEdge, EffectiveStartIndex, + Dimension, Dimension, CellSize); + + } // end: if (GravitySolver == GRAVITY_SOLVER_FAST) + } + else + { // SmoothField == TRUE /* Deposit to field using large-spherical CIC, with radius of DepositPositionsParticleSmoothRadius */ - + // fprintf(stderr, "------DP Call Fortran smooth_deposit with DPPSmoothRadius = %"GSYM"\n", DepositPositionsParticleSmoothRadius); - + PFORTRAN_NAME(smooth_deposit) - (ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], &GridRank, - &NumberOfParticles, ParticleMassPointer, DepositFieldPointer, LeftEdge, - Dimension, Dimension+1, Dimension+2, &FCellSize, - &DepositPositionsParticleSmoothRadius); + (ParticlePosition[0], ParticlePosition[1], ParticlePosition[2], &GridRank, + &NumberOfParticles, ParticleMassPointer, DepositFieldPointer, LeftEdge, + Dimension, Dimension + 1, Dimension + 2, &FCellSize, + &DepositPositionsParticleSmoothRadius); } - - if ((this->ReturnNumberOfStarParticles() > 0) && - (StarParticleCreation == (1 << SINK_PARTICLE)) && SmoothField == TRUE) { - for (i = 0; i < NumberOfParticles; i++) { - if (ParticleType[i] == PARTICLE_TYPE_STAR) { + + if ((this->ReturnNumberOfStarParticles() > 0) && + (StarParticleCreation == (1 << SINK_PARTICLE)) && SmoothField == TRUE) + { + for (i = 0; i < NumberOfParticles; i++) + { + if (ParticleType[i] == PARTICLE_TYPE_STAR) + { ParticleMassPointer[i] = ParticleMassPointerSink[i]; } } - delete [] ParticleMassPointerSink; + delete[] ParticleMassPointerSink; } - if (NumberOfActiveParticles > 0) { - FLOAT** ActiveParticlePosition = new FLOAT*[GridRank]; + if (NumberOfActiveParticles > 0) + { + FLOAT **ActiveParticlePosition = new FLOAT *[GridRank]; for (dim = 0; dim < GridRank; dim++) ActiveParticlePosition[dim] = new FLOAT[NumberOfActiveParticles]; this->GetActiveParticlePosition(ActiveParticlePosition); - - float* ActiveParticleMassPointer = new float[NumberOfActiveParticles]; - for (i = 0; i < NumberOfActiveParticles; i++) { + + float *ActiveParticleMassPointer = new float[NumberOfActiveParticles]; + for (i = 0; i < NumberOfActiveParticles; i++) + { if ((MassFactor != 1.0) || (SmoothField == TRUE)) - ActiveParticleMassPointer[i] = ActiveParticles[i]->ReturnMass()*MassFactor; + ActiveParticleMassPointer[i] = ActiveParticles[i]->ReturnMass() * MassFactor; else ActiveParticleMassPointer[i] = ActiveParticles[i]->ReturnMass(); - + if (DepositField == MASS_FLAGGING_FIELD && DepositParticleMaximumParticleMass > 0 && MassFactor != 1.0) ActiveParticleMassPointer[i] = min(DepositParticleMaximumParticleMass, ParticleMassPointer[i]); } - if (SmoothField == FALSE) { - - PFORTRAN_NAME(cic_deposit)( - ActiveParticlePosition[0], ActiveParticlePosition[1], ActiveParticlePosition[2], - &GridRank, &NumberOfActiveParticles, ActiveParticleMassPointer, DepositFieldPointer, - LeftEdge, Dimension, Dimension+1, Dimension+2, &FCellSize, &FCloudSize); + if (SmoothField == FALSE) + { + PFORTRAN_NAME(cic_deposit) + ( + ActiveParticlePosition[0], ActiveParticlePosition[1], ActiveParticlePosition[2], + &GridRank, &NumberOfActiveParticles, ActiveParticleMassPointer, DepositFieldPointer, + LeftEdge, Dimension, Dimension + 1, Dimension + 2, &FCellSize, &FCloudSize); } - else { - - PFORTRAN_NAME(smooth_deposit)( - ActiveParticlePosition[0], ActiveParticlePosition[1], ActiveParticlePosition[2], - &GridRank, &NumberOfActiveParticles, ActiveParticleMassPointer, DepositFieldPointer, - LeftEdge, Dimension, Dimension+1, Dimension+2, &FCellSize, - &DepositPositionsParticleSmoothRadius); + else + { + + PFORTRAN_NAME(smooth_deposit) + ( + ActiveParticlePosition[0], ActiveParticlePosition[1], ActiveParticlePosition[2], + &GridRank, &NumberOfActiveParticles, ActiveParticleMassPointer, DepositFieldPointer, + LeftEdge, Dimension, Dimension + 1, Dimension + 2, &FCellSize, + &DepositPositionsParticleSmoothRadius); } for (dim = 0; dim < GridRank; dim++) - delete [] ActiveParticlePosition[dim]; - delete [] ActiveParticlePosition; - delete [] ActiveParticleMassPointer; + delete[] ActiveParticlePosition[dim]; + delete[] ActiveParticlePosition; + delete[] ActiveParticleMassPointer; } } // ENDIF this processor - + /* If on different processors, copy deposited field back to the target grid and add to the correct field. */ - if (ProcessorNumber != TargetGrid->ProcessorNumber) { + if (ProcessorNumber != TargetGrid->ProcessorNumber) + { #ifdef USE_MPI /* If posting a receive, then record details of call. */ - if (CommunicationDirection == COMMUNICATION_POST_RECEIVE) { - CommunicationReceiveGridOne[CommunicationReceiveIndex] = this; - CommunicationReceiveGridTwo[CommunicationReceiveIndex] = TargetGrid; + if (CommunicationDirection == COMMUNICATION_POST_RECEIVE) + { + CommunicationReceiveGridOne[CommunicationReceiveIndex] = this; + CommunicationReceiveGridTwo[CommunicationReceiveIndex] = TargetGrid; CommunicationReceiveCallType[CommunicationReceiveIndex] = 3; CommunicationReceiveArgument[0][CommunicationReceiveIndex] = DepositTime; CommunicationReceiveArgumentInt[0][CommunicationReceiveIndex] = - DepositField; + DepositField; } MPI_Status status; @@ -442,63 +538,67 @@ int grid::DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, double time1 = ReturnWallTime(); if (MyProcessorNumber == ProcessorNumber) - CommunicationBufferedSend(DepositFieldPointer, Count, DataType, - Dest, MPI_SENDREGION_TAG, - MPI_COMM_WORLD, BUFFER_IN_PLACE); + CommunicationBufferedSend(DepositFieldPointer, Count, DataType, + Dest, MPI_SENDREGION_TAG, + MPI_COMM_WORLD, BUFFER_IN_PLACE); if (MyProcessorNumber == TargetGrid->ProcessorNumber && - CommunicationDirection == COMMUNICATION_SEND_RECEIVE) - MPI_Recv(DepositFieldPointer, Count, DataType, Source, - MPI_SENDREGION_TAG, MPI_COMM_WORLD, &status); + CommunicationDirection == COMMUNICATION_SEND_RECEIVE) + MPI_Recv(DepositFieldPointer, Count, DataType, Source, + MPI_SENDREGION_TAG, MPI_COMM_WORLD, &status); if (MyProcessorNumber == TargetGrid->ProcessorNumber && - CommunicationDirection == COMMUNICATION_POST_RECEIVE) { - MPI_Irecv(DepositFieldPointer, Count, DataType, Source, - MPI_SENDREGION_TAG, MPI_COMM_WORLD, - CommunicationReceiveMPI_Request+CommunicationReceiveIndex); - CommunicationReceiveBuffer[CommunicationReceiveIndex] = - DepositFieldPointer; + CommunicationDirection == COMMUNICATION_POST_RECEIVE) + { + MPI_Irecv(DepositFieldPointer, Count, DataType, Source, + MPI_SENDREGION_TAG, MPI_COMM_WORLD, + CommunicationReceiveMPI_Request + CommunicationReceiveIndex); + CommunicationReceiveBuffer[CommunicationReceiveIndex] = + DepositFieldPointer; CommunicationReceiveDependsOn[CommunicationReceiveIndex] = - CommunicationReceiveCurrentDependsOn; + CommunicationReceiveCurrentDependsOn; CommunicationReceiveIndex++; - } + } CommunicationTime += ReturnWallTime() - time1; #endif /* USE_MPI */ if (MyProcessorNumber == TargetGrid->ProcessorNumber && - CommunicationDirection != COMMUNICATION_POST_RECEIVE) { + CommunicationDirection != COMMUNICATION_POST_RECEIVE) + { index1 = 0; for (k = 0; k < Dimension[2]; k++) - for (j = 0; j < Dimension[1]; j++) { - index2 = ((k+Offset[2])*OriginalDimension[1] + j + Offset[1])* - OriginalDimension[0] + Offset[0]; - for (i = 0; i < Dimension[0]; i++) - OriginalDepositFieldPointer[index2++] += - DepositFieldPointer[index1++]; - } + for (j = 0; j < Dimension[1]; j++) + { + index2 = ((k + Offset[2]) * OriginalDimension[1] + j + Offset[1]) * + OriginalDimension[0] + + Offset[0]; + for (i = 0; i < Dimension[0]; i++) + OriginalDepositFieldPointer[index2++] += + DepositFieldPointer[index1++]; + } - delete [] DepositFieldPointer; + delete[] DepositFieldPointer; } // end: if (MyProcessorNumber == TargetGrid->ProcessorNumber) } // end: If (ProcessorNumber != TargetGrid->ProcessorNumber) - if (MyProcessorNumber == ProcessorNumber) { + if (MyProcessorNumber == ProcessorNumber) + { /* If necessary, delete the particle mass temporary. */ if (MassFactor != 1.0) - delete [] ParticleMassTemp; + delete[] ParticleMassTemp; /* Return particles to positions at Time. */ this->UpdateParticlePosition(-TimeDifference); - } - + return SUCCESS; } diff --git a/src/enzo/Grid_InitializeGravitatingMassField.C b/src/enzo/Grid_InitializeGravitatingMassField.C index 4030d86fe..57757733b 100644 --- a/src/enzo/Grid_InitializeGravitatingMassField.C +++ b/src/enzo/Grid_InitializeGravitatingMassField.C @@ -62,26 +62,83 @@ int grid::InitializeGravitatingMassField(int RefinementFactor) 2) For the top grid, this is just twice the active grid size (isolated) 3) For the subgrid we will use the boundary zones as well as the active region and then add some padding. */ - - for (dim = 0; dim < GridRank; dim++) { - - /* Make the GravitatingMassField the size of the active region - plus the GravityBufferSize (in Parent cell units) on either size. */ - - DimTemp = GridEndIndex[dim] - GridStartIndex[dim] + 1; - // BufferSize = min(RefinementFactor*GravityBufferSize, DimTemp); - BufferSize = RefinementFactor*GravityBufferSize; - // if (int(DimTemp/4)*4 != DimTemp && RefinementFactor == 2) - BufferSize = ( (BufferSize <= NumberOfGhostZones ) ? NumberOfGhostZones + 1 : BufferSize ) ; - - GravitatingMassFieldDimension[dim] = DimTemp + - 2*max(BufferSize, NumberOfGhostZones); - GravitatingMassFieldCellSize = CellWidth[dim][0]; - GravitatingMassFieldLeftEdge[dim] = GridLeftEdge[dim] - - max(BufferSize, NumberOfGhostZones)* - GravitatingMassFieldCellSize; - } + if (GravitySolverType == GRAVITY_SOLVER_FAST) { + for (dim = 0; dim < GridRank; dim++) { + + /* Make the GravitatingMassField the size of the active region + plus the GravityBufferSize (in Parent cell units) on either size. */ + + DimTemp = GridEndIndex[dim] - GridStartIndex[dim] + 1; + // BufferSize = min(RefinementFactor*GravityBufferSize, DimTemp); + BufferSize = RefinementFactor*GravityBufferSize; + // if (int(DimTemp/4)*4 != DimTemp && RefinementFactor == 2) + + BufferSize = ( (BufferSize <= NumberOfGhostZones ) ? NumberOfGhostZones + 1 : BufferSize ) ; + + GravitatingMassFieldDimension[dim] = DimTemp + + 2*max(BufferSize, NumberOfGhostZones); + GravitatingMassFieldCellSize = CellWidth[dim][0]; + GravitatingMassFieldLeftEdge[dim] = GridLeftEdge[dim] - + max(BufferSize, NumberOfGhostZones)* + GravitatingMassFieldCellSize; + } + } else if (GravitySolverType == GRAVITY_SOLVER_APM) { + + /* Determine the size of the mass grid we'll need. + - For the top grid, this is just the active grid size plus a buffer + - For the subgrid we will use the boundary zones as well as the + active region and then add some padding. */ + + for (dim = 0; dim < GridRank; dim++) { + switch (GravityBoundaryType) { + + /* 1) TopGrid Periodic or Isolated */ + case TopGridPeriodic: + case TopGridIsolated: + DimTemp = GridEndIndex[dim] - GridStartIndex[dim] + 1; + BufferSize = RefinementFactor*GravityBufferSize; + BufferSize = ( (BufferSize <= NumberOfGhostZones ) ? NumberOfGhostZones + 1 : BufferSize ) ; + + GravitatingMassFieldDimension[dim] = DimTemp + + 2*max(BufferSize, NumberOfGhostZones); + GravitatingMassFieldCellSize = CellWidth[dim][0]; + GravitatingMassFieldLeftEdge[dim] = GridLeftEdge[dim] - + max(BufferSize, NumberOfGhostZones)* + GravitatingMassFieldCellSize; + break; + + /* 3) Subgrid */ + case SubGridIsolated:{ + + /* Compute the extra padding required to include all the mass + within one convolution kernal radius of the cells on the edge. + This is some fraction of parent grid's particle smoothing size + minues whatever buffer is already there. */ + + int SubGridExtra = max(nint(float(RefinementFactor)*S2ParticleSize*0.65 - + float(GravityResolution)* + float(GridStartIndex[dim]) ), 0); + GravitatingMassFieldDimension[dim] = + nint(float(GridDimension[dim])*GravityResolution) + + // nint(float(RefinementFactor)*S2ParticleSize) + + // FFT_SAFETY_FACTOR + + 2*SubGridExtra; + GravitatingMassFieldCellSize = CellWidth[dim][0]/GravityResolution; + GravitatingMassFieldLeftEdge[dim] = CellLeftEdge[dim][0] - + float(SubGridExtra)*GravitatingMassFieldCellSize; + break; + } + + /* 4) undefined or unknown is an error */ + case GravityUndefined: + default: + fprintf(stderr, "GravityBoundaryType undefined.\n"); + return FAIL; + + } // end switch + } // end loop over dims + } // end: if (GravitySolverType == GRAVITY_SOLVER_FAST) /* Set unused dims. */ diff --git a/src/enzo/Grid_InterpolateParticlePositions.C b/src/enzo/Grid_InterpolateParticlePositions.C index 9608f863e..5a916ddd8 100644 --- a/src/enzo/Grid_InterpolateParticlePositions.C +++ b/src/enzo/Grid_InterpolateParticlePositions.C @@ -11,7 +11,7 @@ / NOTE: THIS ROUTINE DOES NOT TRANSFER DATA BETWEEN PROCESSORS! / ************************************************************************/ - + #include #include "ErrorExceptions.h" #include "macros_and_parameters.h" @@ -26,20 +26,20 @@ /* function prototypes */ void ActiveParticleResetAccelerations(float *ActiveParticleAcceleration); - + int grid::InterpolateParticlePositions(grid *FromGrid, int DifferenceType) { - + FLOAT HoldLeftEdge[MAX_DIMENSION]; - + /* Loop over all active dimensions */ int dim, dim1; - + for (int dim = 0; dim < GridRank+ComputePotential; dim++) { - + /* Adjust the grid position if the acceleration is face-centered. */ - + if (DifferenceType == DIFFERENCE_TYPE_STAGGERED && dim != GridRank) { HoldLeftEdge[dim] = FromGrid->CellLeftEdge[dim][0]; @@ -72,21 +72,11 @@ int grid::InterpolateParticlePositions(grid *FromGrid, int DifferenceType) delete [] ActiveParticlePosition[dim1]; delete [] ActiveParticlePosition; } - - if(ProblemType==29){ - for(int i=0; iCellLeftEdge[dim][0] = HoldLeftEdge[dim]; } - + return SUCCESS; } diff --git a/src/enzo/Grid_InterpolatePositions.C b/src/enzo/Grid_InterpolatePositions.C index 9b165c0e1..cd962db99 100644 --- a/src/enzo/Grid_InterpolatePositions.C +++ b/src/enzo/Grid_InterpolatePositions.C @@ -11,7 +11,7 @@ / NOTE: / ************************************************************************/ - + #include #include #include "ErrorExceptions.h" @@ -22,50 +22,95 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" - + /* function prototypes */ - + +void InterpolatePositionsPileUpTSC1D(FLOAT *Position[], int Number, float *SumField, + float *Field, FLOAT LeftEdge[], + int EffectiveDim[], FLOAT CellSize); +void InterpolatePositionsPileUpTSC2D(FLOAT *Position[], int Number, float *SumField, + float *Field, FLOAT LeftEdge[], + int EffectiveDim[], int Dimension[], + FLOAT CellSize); +void InterpolatePositionsPileUpTSC3D(FLOAT *Position[], int Number, float *SumField, + float *Field, FLOAT LeftEdge[], + int EffectiveDim[], int Dimension[], + FLOAT CellSize); + extern "C" void PFORTRAN_NAME(cic_interp)(FLOAT *posx, FLOAT *posy, FLOAT *posz, int *ndim, int *npositions, float *sumfield, float *field, FLOAT *leftedge, int *dim1, int *dim2, int *dim3, FLOAT *cellsize); - + int grid::InterpolatePositions(FLOAT *Position[], int dim, float *Field, int Number) { if (Number == 0 || MyProcessorNumber != ProcessorNumber) return SUCCESS; - + /* Set the pointer to the AccelerationField or the PotentialField. */ - + float *InterpolationField = AccelerationField[dim]; if (dim == GridRank) InterpolationField = PotentialField; - + /* Error check. */ - + if (InterpolationField == NULL) { ENZO_VFAIL("AccelerationField[%"ISYM"] absent.\n", dim) } - + if (GravitatingMassFieldCellSize <= 0) { ENZO_FAIL("GravitatingMassFieldCellSize undefined.\n"); } - + /* Set the left edge of the field. */ - + FLOAT LeftEdge[MAX_DIMENSION]; for (int i = 0; i < GridRank; i++) LeftEdge[i] = CellLeftEdge[i][0]; // LeftEdge[i] = CellLeftEdge[i][0] - ((dim == i)? (0.5*CellWidth[i][0]) : 0); - + /* Interpolate from field. */ - - PFORTRAN_NAME(cic_interp)(Position[0], Position[1], Position[2], &GridRank, - &Number, Field, InterpolationField, LeftEdge, - GridDimension, GridDimension+1, GridDimension+2, - &GravitatingMassFieldCellSize); - + + if (GravitySolverType == GRAVITY_SOLVER_FAST) { + + PFORTRAN_NAME(cic_interp)(Position[0], Position[1], Position[2], &GridRank, + &Number, Field, InterpolationField, LeftEdge, + GridDimension, GridDimension+1, GridDimension+2, + &GravitatingMassFieldCellSize); + + } else if (GravitySolverType == GRAVITY_SOLVER_APM) { + + /* Use TSC with the APM solver. */ + + int EffectiveDimension[MAX_DIMENSION], ActualDimension[MAX_DIMENSION]; + FLOAT CellSize = GravitatingMassFieldCellSize; + int i; + + for (i = 0; i < GridRank; i++) { + EffectiveDimension[i] = GridDimension[i]; + ActualDimension[i] = GridDimension[i]; + } + + /* 1D case. */ + if (GridRank == 1) + InterpolatePositionsPileUpTSC1D(Position, Number, Field, InterpolationField, + LeftEdge, EffectiveDimension, CellSize); + + /* 2D Isolated case. */ + if (GridRank == 2) + InterpolatePositionsPileUpTSC2D(Position, Number, Field, InterpolationField, + LeftEdge, EffectiveDimension, + ActualDimension, CellSize); + + /* 3D Isolated case. */ + if (GridRank == 3) + InterpolatePositionsPileUpTSC3D(Position, Number, Field, InterpolationField, + LeftEdge, EffectiveDimension, + ActualDimension, CellSize); + } // end: if (GravitySolverType == GRAVITY_SOLVER_APM) + return SUCCESS; } diff --git a/src/enzo/Grid_OutputAccelerationField.C b/src/enzo/Grid_OutputAccelerationField.C new file mode 100644 index 000000000..f31f684ea --- /dev/null +++ b/src/enzo/Grid_OutputAccelerationField.C @@ -0,0 +1,175 @@ +/*********************************************************************** +/ +/ GRID CLASS (CHECK THE ACCELERATION FIELD) +/ +/ written by: JC Passy +/ date: March, 2013 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" + +int grid::OutputAccelerationField(FILE *fptr, int level) +{ + + if (MyProcessorNumber != ProcessorNumber) + return SUCCESS; + + /* declarations */ + + int dim,size=1; + float dist[MAX_DIMENSION], Middle[MAX_DIMENSION], Width[MAX_DIMENSION]; + int i,j,k,index; + + /* Set origins. */ + + for (dim = 0; dim < GridRank; dim++) { + Middle[dim] = 0.5*(DomainLeftEdge[dim] + DomainRightEdge[dim]); + Width[dim] = DomainRightEdge[dim] - DomainLeftEdge[dim] ; + } + + /* Compute field size (in floats). */ + + for (dim = 0; dim < GridRank; dim++) + size *= GridDimension[dim]; + + /* Diagnostic grid */ + + fprintf(fptr,"# level = %"ISYM", time = %"ESYM"\n", level, Time); + fprintf(fptr,"# GridLeftEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GridLeftEdge[0],GridLeftEdge[1],GridLeftEdge[2]); + fprintf(fptr,"# GridRightEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GridRightEdge[0],GridRightEdge[1],GridRightEdge[2]); + fprintf(fptr,"# GridStartIndex = %"ISYM" %"ISYM" %"ISYM"\n", + GridStartIndex[0],GridStartIndex[1],GridStartIndex[2]); + fprintf(fptr,"# GridEndIndex = %"ISYM" %"ISYM" %"ISYM"\n", + GridEndIndex[0],GridEndIndex[1],GridEndIndex[2]); + fprintf(fptr,"# GridDimension = %"ISYM" %"ISYM" %"ISYM"\n", + GridDimension[0],GridDimension[1],GridDimension[2]); + fprintf(fptr,"# level, is_ghost_zone, i, j, k, x, y, z, r, ax, ay, az, atan, arad\n"); + + /* Sanity check */ + + for (dim = 0; dim < GridRank; dim++) + //if (AccelerationField[dim] == NULL) { + if (!AccelerationField[dim]) { + fprintf(fptr,"AccelerationField is NULL!\n"); + return SUCCESS; + } + //ENZO_FAIL("Error in grid->OutputAccelerationField: AccelerationField is NULL!\n"); + + /* Loop over all grid cells */ + + float xpos,ypos,zpos,rpos,ax,ay,az,arad,atang,a2; + int is_ghost_zone; + + for (k = 0; k < GridDimension[2]; k++) { + for (j = 0; j < GridDimension[1]; j++) { + for (i = 0; i < GridDimension[0]; i++) { + + zpos = CellLeftEdge[2][k] + 0.5*CellWidth[2][k]; + ypos = CellLeftEdge[1][j] + 0.5*CellWidth[1][j]; + xpos = CellLeftEdge[0][i] + 0.5*CellWidth[0][i]; + + is_ghost_zone = 0; + + // Ghost zones + if ((k < GridStartIndex[2]) || (k > GridEndIndex[2]) || + (j < GridStartIndex[1]) || (j > GridEndIndex[1]) || + (i < GridStartIndex[0]) || (i > GridEndIndex[0])) + + is_ghost_zone = 1; + + // For Level 0, flag an extra zone at the boundary of the domain + if (level == 0) + if ( + (zpos < DomainLeftEdge[2]+CellWidth[2][0]) || (zpos > DomainRightEdge[2]-CellWidth[2][0]) || + (ypos < DomainLeftEdge[1]+CellWidth[1][0]) || (ypos > DomainRightEdge[1]-CellWidth[1][0]) || + (xpos < DomainLeftEdge[0]+CellWidth[0][0]) || (xpos > DomainRightEdge[0]-CellWidth[0][0]) + ) + + is_ghost_zone = 1; + + // Distance form the center + zpos -= Middle[2]; + ypos -= Middle[1]; + xpos -= Middle[0]; + + index = i + GridDimension[0]*(j + GridDimension[1]*k); + + /* Calculate force components */ + // With Zeus, it won't be perfect because of the interpolation + if (HydroMethod == Zeus_Hydro && GravitySolverType == GRAVITY_SOLVER_FAST) { + + if (i < GridEndIndex[0]) + ax = 0.5*(AccelerationField[0][index] + + AccelerationField[0][index+1]); + else + ax = AccelerationField[0][index]; + + if (j < GridEndIndex[1]) + ay = 0.5*(AccelerationField[1][index] + + AccelerationField[1][index+GridDimension[0]]); + else + ay = AccelerationField[1][index]; + + if (k < GridEndIndex[2]) + az = 0.5*(AccelerationField[2][index] + + AccelerationField[2][index+GridDimension[0]*GridDimension[1]]); + else + az = AccelerationField[2][index]; + + } else { + + ax = AccelerationField[0][index]; + ay = AccelerationField[1][index]; + az = AccelerationField[2][index]; + + } + + // If required, add external field for the APM solver + if (GravitySolverType == GRAVITY_SOLVER_APM) + if (ProblemType == 41 || ProblemType == 46) { + ax += AccelerationFieldExternalAPM[0][index]; + ay += AccelerationFieldExternalAPM[1][index]; + az += AccelerationFieldExternalAPM[2][index]; + } + + rpos = pow(xpos*xpos + ypos*ypos + zpos*zpos, 0.5); + + arad = (ax*xpos + ay*ypos + az*zpos) / rpos; + a2 = pow(ax,2.0) + pow(ay,2.0) + pow(az,2.0); + atang = sqrt(max(a2-arad*arad, 0.0)); + + /* Output results. */ + + fprintf(fptr, "%"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM"\n", + level,is_ghost_zone, + i,j,k, + xpos,ypos,zpos,rpos, + ax, ay, az, + atang, -arad); + + } + } + } //end loop grid dims + + return SUCCESS; + +} + diff --git a/src/enzo/Grid_OutputGravitatingMassField.C b/src/enzo/Grid_OutputGravitatingMassField.C new file mode 100644 index 000000000..61eec97e4 --- /dev/null +++ b/src/enzo/Grid_OutputGravitatingMassField.C @@ -0,0 +1,167 @@ +/*********************************************************************** +/ +/ Check GravitatingMassField +/ +/ written by: Passy JC +/ date: April, 2013 +/ modified1: +/ +/ +/ +************************************************************************/ + +#include +#include +#include "ErrorExceptions.h" +#include "performance.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "phys_constants.h" + +int GetUnits(float *DensityUnits, float *LengthUnits, + float *TemperatureUnits, float *TimeUnits, + float *VelocityUnits, double *MassUnits, FLOAT Time); + +int grid::OutputGravitatingMassField(FILE *fptr, FILE *fptr2, int level) +{ + + /* Return if this grid is not on this processor. */ + + if (MyProcessorNumber != ProcessorNumber) + return SUCCESS; + + /* declarations */ + + int i,j,k,index,dim; + int size_gmf = 1; + int size_gmf2 = 1; + int is_ghost_zone; + + float sum_gmf, sum_gmfp; + + /* Compute field size */ + + for (dim = 0; dim < GridRank; dim++) + size_gmf *= GravitatingMassFieldDimension[dim]; + + for (dim = 0; dim < GridRank; dim++) + size_gmf2 *= GravitatingMassFieldParticlesDimension[dim]; + + + /* Sanity check */ + + if (GravitatingMassField == NULL) + ENZO_FAIL("Error in grid->OutputGravitatingMassField: GravitatingMassField is NULL!\n"); + + if (GravitatingMassFieldParticles == NULL) + ENZO_FAIL("Error in grid->OutputGravitatingMassField: GravitatingMassFieldParticles is NULL!\n"); + + /* Headers */ + + fprintf(fptr,"# level = %"ISYM", time = %"ESYM"\n", level, Time); + fprintf(fptr,"# GridLeftEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GridLeftEdge[0],GridLeftEdge[1],GridLeftEdge[2]); + fprintf(fptr,"# GridRightEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GridRightEdge[0],GridRightEdge[1],GridRightEdge[2]); + fprintf(fptr,"# GridStartIndex = %"ISYM" %"ISYM" %"ISYM"\n", + GridStartIndex[0],GridStartIndex[1],GridStartIndex[2]); + fprintf(fptr,"# GridEndIndex = %"ISYM" %"ISYM" %"ISYM"\n", + GridEndIndex[0],GridEndIndex[1],GridEndIndex[2]); + fprintf(fptr,"# GridDimension = %"ISYM" %"ISYM" %"ISYM"\n", + GridDimension[0],GridDimension[1],GridDimension[2]); + fprintf(fptr,"# GravitatingMassFieldLeftEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GravitatingMassFieldLeftEdge[0],GravitatingMassFieldLeftEdge[1],GravitatingMassFieldLeftEdge[2]); + fprintf(fptr, "# size of GravitatingMassField = %"ISYM" = %"ISYM"x%"ISYM"x%"ISYM"\n", + size_gmf, + GravitatingMassFieldDimension[0], + GravitatingMassFieldDimension[1], + GravitatingMassFieldDimension[2]); + fprintf(fptr,"# level, i, j, k, index, GMF[index]\n"); + fflush(fptr); + + // + + fprintf(fptr2,"# level = %"ISYM", time = %"ESYM"\n", level, Time); + fprintf(fptr2,"# GridLeftEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GridLeftEdge[0],GridLeftEdge[1],GridLeftEdge[2]); + fprintf(fptr2,"# GridRightEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GridRightEdge[0],GridRightEdge[1],GridRightEdge[2]); + fprintf(fptr2,"# GridStartIndex = %"ISYM" %"ISYM" %"ISYM"\n", + GridStartIndex[0],GridStartIndex[1],GridStartIndex[2]); + fprintf(fptr2,"# GridEndIndex = %"ISYM" %"ISYM" %"ISYM"\n", + GridEndIndex[0],GridEndIndex[1],GridEndIndex[2]); + fprintf(fptr2,"# GridDimension = %"ISYM" %"ISYM" %"ISYM"\n", + GridDimension[0],GridDimension[1],GridDimension[2]); + fprintf(fptr2,"# GravitatingMassFieldLeftEdge = %"FSYM", %"FSYM", %"FSYM" \n", + GravitatingMassFieldLeftEdge[0],GravitatingMassFieldLeftEdge[1],GravitatingMassFieldLeftEdge[2]); + fprintf(fptr2, "# size of GravitatingMassField = %"ISYM" = %"ISYM"x%"ISYM"x%"ISYM"\n", + size_gmf2, + GravitatingMassFieldParticlesDimension[0], + GravitatingMassFieldParticlesDimension[1], + GravitatingMassFieldParticlesDimension[2]); + fprintf(fptr2,"# level, i, j, k, index, GMF[index]\n"); + fflush(fptr2); + + + sum_gmf = 0.0; + sum_gmfp = 0.0; + + // GMF + for (k = 0; k < GravitatingMassFieldDimension[2]; k++) { + for (j = 0; j < GravitatingMassFieldDimension[1]; j++) { + for (i = 0; i < GravitatingMassFieldDimension[0]; i++) { + + + index = i + GravitatingMassFieldDimension[0]*(j + GravitatingMassFieldDimension[1]*k); + sum_gmf += GravitatingMassField[index]; + sum_gmfp += GravitatingMassFieldParticles[index]; + + is_ghost_zone = 0; + // Ghost zones + if ((k < GridStartIndex[2]) || (k > GridEndIndex[2]) || + (j < GridStartIndex[1]) || (j > GridEndIndex[1]) || + (i < GridStartIndex[0]) || (i > GridEndIndex[0])) + + is_ghost_zone = 1; + + // For Level 0, flag an extra zone + if (level == 0) + if ((k == GridStartIndex[2]) || (k == GridEndIndex[2]) || + (j == GridStartIndex[1]) || (j == GridEndIndex[1]) || + (i == GridStartIndex[0]) || (i == GridEndIndex[0])) + + is_ghost_zone = 1; + + // GMF + if (GravitatingMassField[index] > tiny_number) { + fprintf(fptr,"%"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ESYM"\n", + level, i, j, k, index, GravitatingMassField[index]); + fflush(fptr); + } + + // GMFP + if (GravitatingMassFieldParticles[index] > tiny_number) { + fprintf(fptr2,"%"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ESYM"\n", + level, i, j, k, index, GravitatingMassFieldParticles[index]); + fflush(fptr2); + } + + + } + } + } + + // Sum + fprintf(fptr,"# total gmf: %"ESYM"\n",sum_gmf); + fflush(fptr); + fprintf(fptr2,"# total gmfp: %"ESYM"\n",sum_gmfp); + fflush(fptr2); + + return SUCCESS; + +} diff --git a/src/enzo/Grid_ProjectToPlane2.C b/src/enzo/Grid_ProjectToPlane2.C index 4afe6042f..83ad4a04e 100644 --- a/src/enzo/Grid_ProjectToPlane2.C +++ b/src/enzo/Grid_ProjectToPlane2.C @@ -28,12 +28,12 @@ #include "phys_constants.h" extern "C" void FORTRAN_NAME(projplane)( - float *grid1, float *grid2, float *flaggrid, int *iflag, + float *grid1, float *grid2, float *flaggrid, int *iflag, int *ismooth, int *gdim1, int *gdim2, int *gdim3, FLOAT *gcellsize, float *plane, int *pdim1, int *pdim2, FLOAT *pcellsize, int *projdim, int *ifield, float *weight, - FLOAT *gleft, FLOAT *gfarleft, FLOAT *gright, FLOAT *pleft, + FLOAT *gleft, FLOAT *gfarleft, FLOAT *gright, FLOAT *pleft, FLOAT *pright, int *npstart, int *npend, float *fracleft, float *fracright); int GetUnits(float *DensityUnits, float *LengthUnits, @@ -43,9 +43,9 @@ int FindField(int field, int farray[], int numfields); int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); -int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], +int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], FLOAT ProjectedFieldRightEdge[], - int ProjectedFieldDims[], float *ProjectedField[], + int ProjectedFieldDims[], float *ProjectedField[], int ProjectionDimension, int ProjectionSmooth, int NumberOfProjectedFields, int level, int MetalLinesUseLookupTable, char *MetalLinesFilename) @@ -57,9 +57,9 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], /* Projection only allowed for 3D simulations */ - if (GridRank != 3) + if (GridRank != 3) return SUCCESS; - + if (BaryonField[NumberOfBaryonFields] == NULL && level >= 0) ENZO_FAIL("UNDER_SUBGRID_FLAG field not set."); @@ -74,7 +74,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], float *spin_temp = NULL, *bright_temp = NULL, *all_luminosities = NULL; float *first_field, *second_field; float kappa, gamma_p, gamma_e, C_e, C_H, C_p, y21, v_i, ri; - + /* Check To see if grid overlaps the projected field. */ @@ -90,7 +90,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], int DensNum, GENum, TENum, Vel1Num, Vel2Num, Vel3Num; if (NumberOfBaryonFields > 0) - IdentifyPhysicalQuantities(DensNum, GENum, Vel1Num, Vel2Num, + IdentifyPhysicalQuantities(DensNum, GENum, Vel1Num, Vel2Num, Vel3Num, TENum); /* Find Multi-species fields. */ @@ -98,13 +98,13 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], int DeNum, HINum, HIINum, HeINum, HeIINum, HeIIINum, HMNum, H2INum, H2IINum, DINum, DIINum, HDINum; if (NumberOfBaryonFields > 0 && MultiSpecies) - IdentifySpeciesFields(DeNum, HINum, HIINum, HeINum, HeIINum, HeIIINum, + IdentifySpeciesFields(DeNum, HINum, HIINum, HeINum, HeIINum, HeIIINum, HMNum, H2INum, H2IINum, DINum, DIINum, HDINum); /* Find metallicity field and set flag. */ int MetallicityField = FALSE, MetalNum; - if ((MetalNum = FindField(Metallicity, FieldType, NumberOfBaryonFields)) + if ((MetalNum = FindField(Metallicity, FieldType, NumberOfBaryonFields)) != -1) MetallicityField = TRUE; else @@ -113,7 +113,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], /* Find SN Colour field and set flag */ int SNColourField = FALSE, SNColourNum; - if ((SNColourNum = FindField(SNColour, FieldType, NumberOfBaryonFields)) + if ((SNColourNum = FindField(SNColour, FieldType, NumberOfBaryonFields)) != -1) SNColourField = TRUE; else @@ -125,25 +125,25 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], /* Find the start and stop indicies in the ProjectionDimension of this grid for the projected region. */ - start = max(int((ProjectedFieldLeftEdge[ProjectionDimension] - + start = max(int((ProjectedFieldLeftEdge[ProjectionDimension] - GridLeftEdge[ProjectionDimension]) / CellWidth[ProjectionDimension][0]), 0); - stop = min(int((ProjectedFieldRightEdge[ProjectionDimension] - + stop = min(int((ProjectedFieldRightEdge[ProjectionDimension] - GridLeftEdge[ProjectionDimension]) / CellWidth[ProjectionDimension][0]), - GridEndIndex[ProjectionDimension] - + GridEndIndex[ProjectionDimension] - GridStartIndex[ProjectionDimension]); - LeftCellFraction = min(1.0 - ((ProjectedFieldLeftEdge[ProjectionDimension] - + LeftCellFraction = min(1.0 - ((ProjectedFieldLeftEdge[ProjectionDimension] - GridLeftEdge[ProjectionDimension]) / CellWidth[ProjectionDimension][0] - start), 1); - RightCellFraction = min((ProjectedFieldRightEdge[ProjectionDimension] - + RightCellFraction = min((ProjectedFieldRightEdge[ProjectionDimension] - GridLeftEdge[ProjectionDimension]) / CellWidth[ProjectionDimension][0] - stop, 1); start += GridStartIndex[ProjectionDimension]; stop += GridStartIndex[ProjectionDimension]; - if (debug) + if (debug) printf("ProjectToGrid: start = %d/%d (%5.3f) stop = %d/%d (%5.3f) " "GridLeft/Right = %5.3"FSYM"/%5.3"FSYM"\n", start, GridStartIndex[ProjectionDimension], LeftCellFraction, @@ -159,17 +159,17 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], double CellVolume; /* Set the Conversion factors for Density and X-rays. If using comoving - coordinates use solar masses and Mpc as the intrinsic units. + coordinates use solar masses and Mpc as the intrinsic units. Note: The X-ray units have been multiplied by 1.0e-20 to stop overflow. Note: The temperature field already has units of K. */ - float DensityConversion, XrayConversion, TempXrayConversion, + float DensityConversion, XrayConversion, TempXrayConversion, LuminosityConversion, dom; - DensityConversion = XrayConversion = TempXrayConversion = + DensityConversion = XrayConversion = TempXrayConversion = LuminosityConversion = CellLength; - float TemperatureUnits, DensityUnits, LengthUnits, + float TemperatureUnits, DensityUnits, LengthUnits, VelocityUnits, TimeUnits; - + GetUnits(&DensityUnits, &LengthUnits, &TemperatureUnits, &TimeUnits, &VelocityUnits, Time); @@ -204,8 +204,8 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], /* Compute the projected field cell size. */ - FLOAT ProjectedFieldCellSize = (ProjectedFieldRightEdge[0] - - ProjectedFieldLeftEdge[0])/ + FLOAT ProjectedFieldCellSize = (ProjectedFieldRightEdge[0] - + ProjectedFieldLeftEdge[0])/ FLOAT(ProjectedFieldDims[0]); /* If level < 0, then just do the star particle stuff. */ @@ -236,12 +236,12 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], /* 1) baryon density. */ if (NumberOfBaryonFields > 0) - FORTRAN_NAME(projplane)(BaryonField[0], NULL, + FORTRAN_NAME(projplane)(BaryonField[0], NULL, BaryonField[NumberOfBaryonFields], &One, &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[0], ProjectedFieldDims+adim, + ProjectedField[0], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &One, &DensityConversion, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -263,7 +263,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[1], ProjectedFieldDims+adim, + ProjectedField[1], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -286,7 +286,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[2], ProjectedFieldDims+adim, + ProjectedField[2], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -297,7 +297,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], /* 4) SN Colour weighted by density */ if (SNColourField == TRUE) { - + for (i = 0; i < size; i++) temp_field[i] = BaryonField[SNColourNum][i] / BaryonField[DensNum][i]; @@ -313,7 +313,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[3], ProjectedFieldDims+adim, + ProjectedField[3], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -335,7 +335,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], // &ProjectionSmooth, // GridDimension, GridDimension+1, // GridDimension+2, CellWidth[0], -// ProjectedField[4], ProjectedFieldDims+adim, +// ProjectedField[4], ProjectedFieldDims+adim, // ProjectedFieldDims+bdim, &ProjectedFieldCellSize, // &ProjectionDimension, &ProjType, &ConversionFactor, // GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -350,7 +350,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], for (i = 0; i < size; i++) temp_field[i] = BaryonField[DeNum][i] / BaryonField[DensNum][i]; - + first_field = temp_field; second_field = BaryonField[0]; ProjType = 4; @@ -361,7 +361,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[5], ProjectedFieldDims+adim, + ProjectedField[5], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -373,7 +373,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], if (MultiSpecies > 1) { for (i = 0; i < size; i++) - temp_field[i] = (BaryonField[H2INum][i] + BaryonField[H2IINum][i]) / + temp_field[i] = (BaryonField[H2INum][i] + BaryonField[H2IINum][i]) / BaryonField[DensNum][i]; first_field = temp_field; @@ -386,7 +386,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[6], ProjectedFieldDims+adim, + ProjectedField[6], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -405,7 +405,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], // 21 cm redshifted to box redshift [Hz] nu0 = 1.4204e9 / (1 + CurrentRedshift); - hz = 3.24044e-18 * HubbleConstantNow * + hz = 3.24044e-18 * HubbleConstantNow * sqrt(OmegaMatterNow * pow(1+CurrentRedshift, 3) + OmegaLambdaNow); Tcmb = 2.723*(1+CurrentRedshift); high_dt = 1.14e5 / @@ -424,7 +424,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], } kappa = 3.1e-11 * pow(temperature[i], 0.357) * exp(-32.0 / temperature[i]); - gamma_e = -9.607 + 0.5 * log(temperature[i]) * + gamma_e = -9.607 + 0.5 * log(temperature[i]) * exp(-pow(log(temperature[i]), 4.5) / 1800.0); gamma_e = pow(10.0, gamma_e); gamma_p = 3.2 * kappa; @@ -432,25 +432,25 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], C_H = BaryonField[HINum][i] * dom * kappa; C_e = BaryonField[DeNum][i] * dom * gamma_e; C_p = BaryonField[DeNum][i] * dom * gamma_p; - + y21 = (t_star / (A_em*temperature[i])) * (C_H + C_e + C_p); - spin_temp[i] = (t_star + Tcmb + + spin_temp[i] = (t_star + Tcmb + y21*temperature[i]) / (1+y21); - + /* Discretization as outlined in Kuhlen et al. (2005) */ // ri = 0.0; // 0 for now. Should be proper distance from midplane. // v_i = VelocityUnits * BaryonField[Vel1Num+ProjectionDimension][i] + hz*ri; // Delta_nu = nu0 * v_i / clight; // Delta_nuD = nu0 * sqrt(2*kboltz*temperature[i]/(mh*clight*clight)); -// phi = exp(-( (Delta_nu*Delta_nu) / (Delta_nuD*Delta_nuD) )) / +// phi = exp(-( (Delta_nu*Delta_nu) / (Delta_nuD*Delta_nuD) )) / // (1.77245*Delta_nuD); // line profile // Delta_tau[i] = prefactor * BaryonField[HINum][i] * phi / spin_temp[i]; /* Instead, let's use an approximation for differential brightness temperature */ - bright_temp[i] = high_dt * BaryonField[HINum][i] * + bright_temp[i] = high_dt * BaryonField[HINum][i] * (1.0 - Tcmb / spin_temp[i]); } // ENDFOR size @@ -465,7 +465,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[7], ProjectedFieldDims+adim, + ProjectedField[7], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -485,7 +485,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[8], ProjectedFieldDims+adim, + ProjectedField[8], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -517,7 +517,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[9+n], ProjectedFieldDims+adim, + ProjectedField[9+n], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -531,7 +531,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], if (MultiSpecies) { - // Based on JHW fit to Clegg et al. (1999). + // Based on JHW fit to Clegg et al. (1999). // Good between n_elec = [1e2,1e9] // Returns H-alpha line emissivity in erg cm^3 s^-1 @@ -555,7 +555,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], temp_field[i] = powf(10.0f, a0 + a1*log_temp + a2*log_temp2) * nelec*nelec; if (isnan(temp_field[i])) - printf("NaN: %d %g %g %g %g %g %g %g\n", + printf("NaN: %d %g %g %g %g %g %g %g\n", i, a0, a1, a2, temperature[i], nelec, log_temp, log_nelec); } @@ -571,7 +571,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], &ProjectionSmooth, GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], - ProjectedField[27], ProjectedFieldDims+adim, + ProjectedField[27], ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, @@ -622,7 +622,7 @@ int grid::ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], GridDimension, GridDimension+1, GridDimension+2, CellWidth[0], ProjectedField[28+n], - ProjectedFieldDims+adim, + ProjectedFieldDims+adim, ProjectedFieldDims+bdim, &ProjectedFieldCellSize, &ProjectionDimension, &ProjType, &ConversionFactor, GridLeftEdge, GridFarLeftEdge, GridRightEdge, diff --git a/src/enzo/Grid_SetParticleMassFlaggingField.C b/src/enzo/Grid_SetParticleMassFlaggingField.C index c61186c0e..39f2b3d25 100644 --- a/src/enzo/Grid_SetParticleMassFlaggingField.C +++ b/src/enzo/Grid_SetParticleMassFlaggingField.C @@ -4,9 +4,9 @@ / / written by: John Wise / date: May, 2009 -/ modified1: +/ modified1: / -/ PURPOSE: This routine sums the particle mass flagging field in a +/ PURPOSE: This routine sums the particle mass flagging field in a / non-blocking fashion. / ************************************************************************/ @@ -14,7 +14,7 @@ #ifdef USE_MPI #include "mpi.h" #endif - + #include #include #include "ErrorExceptions.h" @@ -34,10 +34,10 @@ int CommunicationBufferedSend(void *buffer, int size, MPI_Datatype Type, int Tar int Return_MPI_Tag(int grid_num, int proc); /* The following is defined in Grid_DepositParticlePositions.C. */ - + extern float DepositParticleMaximumParticleMass; - -int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, + +int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, int ParticleMassMethod, int MustRefineMethod, int *SendProcs, int NumberOfSends) { @@ -60,8 +60,8 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, return SUCCESS; // printf("--> SetPMFlag[P%"ISYM"/%"ISYM"]: level %"ISYM", grid %"ISYM", " -// "comm_dir = %"ISYM", npart = %"ISYM"\n", -// MyProcessorNumber, ProcessorNumber, level, GridNum, +// "comm_dir = %"ISYM", npart = %"ISYM"\n", +// MyProcessorNumber, ProcessorNumber, level, GridNum, // CommunicationDirection, NumberOfParticles); #ifdef USE_MPI @@ -80,9 +80,9 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, int method, NumberOfFlaggedCells; bool KeepFlaggingField; - /* Calculate the flagging field only if + /* Calculate the flagging field only if 1) this grid belongs to this grid and it's the first pass, or - 2) this grid isn't local and this processor is between StartProc + 2) this grid isn't local and this processor is between StartProc and EndProc */ @@ -107,18 +107,18 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, occupied by the high-resolution region is not refined. Thus, must-refine flagging must be done first. */ - + /* Allocate and clear mass flagging field. */ - + this->ClearParticleMassFlaggingField(); /* ==== METHOD 8: BY POSITION OF MUST-REFINE PARTICLES ==== */ - + if (MustRefineMethod >= 0 && level <= MustRefineParticlesRefineToLevel) { KeepFlaggingField = (level == MustRefineParticlesRefineToLevel); - NumberOfFlaggedCells = + NumberOfFlaggedCells = this->DepositMustRefineParticles(ParticleMassMethod, level, KeepFlaggingField); @@ -127,7 +127,7 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, } } // ENDIF MustRefineMethod - + /* ==== METHOD 4: BY PARTICLE MASS ==== */ if (ParticleMassMethod >= 0 && @@ -136,19 +136,19 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, and_flag = (level == MustRefineParticlesRefineToLevel && MustRefineParticlesCreateParticles > 0); - + /* Set the maximum particle mass to be deposited (cleared below). */ - - DepositParticleMaximumParticleMass = - 0.99999*MinimumMassForRefinement[ParticleMassMethod]*POW(RefineBy, - level*MinimumMassForRefinementLevelExponent[ParticleMassMethod]); - + if (ProblemType != 29) // not for the TestOrbit + DepositParticleMaximumParticleMass = + 0.99999*MinimumMassForRefinement[ParticleMassMethod]*POW(RefineBy, + level*MinimumMassForRefinementLevelExponent[ParticleMassMethod]); + /* Deposit particles in this grid to MassFlaggingField. */ - + this->DepositParticlePositionsLocal(this->ReturnTime(), PARTICLE_MASS_FLAGGING_FIELD, and_flag); - + DepositParticleMaximumParticleMass = 0; } // ENDIF ParticleMassMethod @@ -164,7 +164,7 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, // printf("----> SetPMFlag[P%"ISYM"/%"ISYM"]: sending %"ISYM" floats.\n", // MyProcessorNumber, ProcessorNumber, size); CommunicationBufferedSend(ParticleMassFlaggingField, size, DataType, - ProcessorNumber, MPI_SENDPMFLAG_TAG, + ProcessorNumber, MPI_SENDPMFLAG_TAG, MPI_COMM_WORLD, size*sizeof(float)); delete [] ParticleMassFlaggingField; ParticleMassFlaggingField = NULL; @@ -200,7 +200,7 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, if (Source >= StartProc && Source < EndProc) { buffer = new float[size]; - MPI_Irecv(buffer, Count, DataType, Source, MPI_SENDPMFLAG_TAG, MPI_COMM_WORLD, + MPI_Irecv(buffer, Count, DataType, Source, MPI_SENDPMFLAG_TAG, MPI_COMM_WORLD, CommunicationReceiveMPI_Request+CommunicationReceiveIndex); CommunicationReceiveGridOne[CommunicationReceiveIndex] = this; @@ -219,9 +219,9 @@ int grid::SetParticleMassFlaggingField(int StartProc, int EndProc, int level, } // ENDIF post receive #endif /* USE_MPI */ - + return SUCCESS; - + } /************************************************************************/ diff --git a/src/enzo/Grid_TestGravityAPMCheckResults.C b/src/enzo/Grid_TestGravityAPMCheckResults.C new file mode 100644 index 000000000..07ad6bb03 --- /dev/null +++ b/src/enzo/Grid_TestGravityAPMCheckResults.C @@ -0,0 +1,131 @@ +/*********************************************************************** +/ +/ GRID CLASS (CHECK THE NUMERICAL GRAVITY FORCE AGAINST ANALYTIC) - APM +/ +/ written by: Greg Bryan +/ date: July, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "phys_constants.h" + +int grid::TestGravityAPMCheckResults(FILE *fptr, grid *TopGrid, int level) +{ + + if (MyProcessorNumber != ProcessorNumber) + return SUCCESS; + + /* declarations */ + + int dim, i; + float dist[MAX_DIMENSION], Middle[MAX_DIMENSION], Width[MAX_DIMENSION]; + float r, fanalytic, fradial, ftang; + + /* Set constants. */ + + for (dim = 0; dim < GridRank; dim++) + { + Middle[dim] = 0.5 * (DomainLeftEdge[dim] + DomainRightEdge[dim]); + Width[dim] = DomainRightEdge[dim] - DomainLeftEdge[dim]; + } + + /* Set top grid cell size. */ + + float TopGridCellWidth = TopGrid->CellWidth[0][0]; + dtFixed = max(dtFixed, TopGrid->dtFixed); + + /* Diagnostic grid */ + + fprintf(fptr, "# GridLeftEdge = [%" FSYM ", %" FSYM ", %" FSYM "] \n", + GridLeftEdge[0], GridLeftEdge[1], GridLeftEdge[2]); + fprintf(fptr, "# GridRightEdge = [%" FSYM ", %" FSYM ", %" FSYM "] \n", + GridRightEdge[0], GridRightEdge[1], GridRightEdge[2]); + fprintf(fptr, "# level x y z r ftan frad fanal\n"); + + /* Loop over particles, computing radial distance from the center and + comparing the analyic force to the compute acceleration (determined + by assuming the velocity is due soley to the analytic acceleration). */ + + for (i = 1; i < NumberOfParticles; i++) + { + + /* Compute distance. */ + + r = 0.0; + fradial = 0.0; + for (dim = 0; dim < GridRank; dim++) + { + + dist[dim] = ParticlePosition[dim][i] - Middle[dim]; + if (fabs(dist[dim]) > Middle[dim] && + GravityBoundaryType != TopGridIsolated) + dist[dim] = -(Width[dim] - fabs(dist[dim])) * sign(dist[dim]); + + /* Compute distance. */ + + r += dist[dim] * dist[dim]; + + /* Compute radial component. */ + + fradial += ParticleVelocity[dim][i] / dtFixed * dist[dim]; + } + + /* Normalize radial force components. */ + + r = sqrt(r); + fradial /= r; + + /* Compute tangential component. */ + + ftang = 0.0; + for (dim = 0; dim < GridRank; dim++) + ftang += POW(ParticleVelocity[dim][i] / dtFixed, float(2.0)); + ftang = sqrt(max(ftang - fradial * fradial, 0.0)); + + /* Compute analytic acceleration. */ + + if (GridRank == 1) + fanalytic = 2.0 * pi * TopGridCellWidth; + if (GridRank == 2) + fanalytic = 2.0 / r * TopGridCellWidth * TopGridCellWidth; + if (GridRank == 3) + fanalytic = 1.0 / (r * r) * POW(TopGridCellWidth, 3); + + /* Output results. */ + + fprintf(fptr, "%" ISYM " %" FSYM " %" FSYM " %" FSYM " %" FSYM " %e %e %e\n", + level, + ParticlePosition[0][i], ParticlePosition[1][i], ParticlePosition[2][i], + r, + ftang / POW(TopGridCellWidth, 2), + -fradial / POW(TopGridCellWidth, 2), + fanalytic / POW(TopGridCellWidth, 2)); + + } // end loop over particles. + + /* If requested, set up the baryon field. */ + + if (NumberOfBaryonFields > 0) + { + + /* INCOMPLETE */ + } + + return SUCCESS; +} diff --git a/src/enzo/Grid_TestGravityAPMInitializeGrid.C b/src/enzo/Grid_TestGravityAPMInitializeGrid.C new file mode 100644 index 000000000..6d39b166a --- /dev/null +++ b/src/enzo/Grid_TestGravityAPMInitializeGrid.C @@ -0,0 +1,213 @@ +/*********************************************************************** +/ +/ GRID CLASS (INITIALIZE THE GRID FOR AN APM GRAVITY TEST) +/ +/ written by: Greg Bryan +/ date: April, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "phys_constants.h" + +/* Random number generator */ + +void mt_init(unsigned_int seed); +unsigned_long_int mt_random(); + +int grid::TestGravityAPMInitializeGrid(float CentralDensity, + int NumberOfNewParticles, + float *CentralParticlePosition, + int UseBaryons) +{ + /* declarations */ + + int dim, i, size, vel; + float phi, r, theta; + int mt_random_seed = 123456789; + int max_random = (1 << 16); + mt_init((unsigned_int)mt_random_seed); + + if (UseBaryons) + { + + /* create fields */ + + NumberOfBaryonFields = 0; + FieldType[NumberOfBaryonFields++] = Density; + FieldType[NumberOfBaryonFields++] = TotalEnergy; + if (DualEnergyFormalism) + FieldType[NumberOfBaryonFields++] = InternalEnergy; + vel = NumberOfBaryonFields; + FieldType[NumberOfBaryonFields++] = Velocity1; + if (GridRank > 1) + FieldType[NumberOfBaryonFields++] = Velocity2; + if (GridRank > 2) + FieldType[NumberOfBaryonFields++] = Velocity3; + } + + /* Return if this doesn't concern us. */ + + if (ProcessorNumber != MyProcessorNumber) + return SUCCESS; + + /* Set particles. */ + + if (NumberOfNewParticles > 0) + { + + /* Set number of particles for this grid. */ + + NumberOfParticles = NumberOfNewParticles; + + /* Allocate space. */ + + this->AllocateNewParticles(NumberOfParticles); + + /* Create random particle positions and set velocities to zero. */ + + for (dim = 0; dim < GridRank; dim++) + for (i = 1; i < NumberOfParticles; i++) + { + +#ifdef UNUSED + + ParticlePosition[dim][i] = FLOAT(mt_random() % max_random) / FLOAT(max_random); + +#endif /* UNUSED */ + + ParticleVelocity[dim][i] = 0.0; + + ParticleMass[i] = tiny_number; + } + + /* Set positions randomly distributed in log r from center. */ + + float r1 = log10(0.2 * (*CellWidth[0])); + float r2 = log10(0.45 * (DomainRightEdge[0] - DomainLeftEdge[0])); + for (i = 0; i < NumberOfParticles; i++) + { + + /* Compute random r, phi and theta. */ + + r = POW(10, (r2 - r1) * (float(mt_random() % max_random) / float(max_random)) + r1); + phi = 2.0 * pi * float(mt_random() % max_random) / float(max_random); + theta = pi * float(mt_random() % max_random) / float(max_random); + + /* Turn these into x/y/z. */ + + if (GridRank == 1) + ParticlePosition[0][i] = r * sign(phi - pi); + + if (GridRank == 2) + { + ParticlePosition[0][i] = r * cos(phi); + ParticlePosition[1][i] = r * sin(phi); + } + + if (GridRank == 3) + { + ParticlePosition[0][i] = r * sin(theta) * cos(phi); + ParticlePosition[1][i] = r * sin(theta) * sin(phi); + ParticlePosition[2][i] = r * cos(theta); + } + + /* Shift center from 0,0,0 to the middle of the volume. */ + + for (dim = 0; dim < GridRank; dim++) + ParticlePosition[dim][i] += + 0.5 * (DomainLeftEdge[dim] + DomainRightEdge[dim]); + + /* Set particle identifier. */ + + ParticleNumber[i] = i; + ParticleType[i] = PARTICLE_TYPE_DARK_MATTER; + } + + /* Set central particle (0). */ + + if (!UseBaryons) + { + + ParticleNumber[0] = 0; + ParticleType[0] = PARTICLE_TYPE_DARK_MATTER; + ParticleMass[0] = CentralDensity; + + for (dim = 0; dim < GridRank; dim++) + { + ParticleVelocity[dim][0] = 0.0; + ParticlePosition[dim][0] = CentralParticlePosition[dim]; + } + } + } + + /* If requested, set up the baryon field. */ + + if (UseBaryons) + { + + /* compute size of fields */ + + size = 1; + for (dim = 0; dim < GridRank; dim++) + size *= GridDimension[dim]; + + /* allocate fields */ + + this->AllocateGrids(); + + /* set density, total energy */ + + for (i = 0; i < size; i++) + { + BaryonField[0][i] = tiny_number; + BaryonField[1][i] = tiny_number; + } + + /* Set central density. */ + + int Middle[MAX_DIMENSION], Size[MAX_DIMENSION]; + for (dim = 0; dim < MAX_DIMENSION; dim++) + { + Middle[dim] = max(GridDimension[dim] / 2 - 1, 0); + Size[dim] = min(GridDimension[dim], 2); + } + float SpikeDensity = CentralDensity / float(Size[0] * Size[1] * Size[2]); + + for (int k = 0; k < Size[2]; k++) + for (int j = 0; j < Size[1]; j++) + for (int i = 0; i < Size[0]; i++) + BaryonField[0][(k + Middle[2]) * GridDimension[0] * GridDimension[1] + + (j + Middle[1]) * GridDimension[0] + + (i + Middle[0])] += SpikeDensity; + + /* set velocities */ + + for (dim = 0; dim < GridRank; dim++) + for (i = 0; i < size; i++) + BaryonField[vel + dim][i] = 0.0; + + /* Set internal energy if necessary. */ + + if (DualEnergyFormalism) + for (i = 0; i < size; i++) + BaryonField[2][i] = tiny_number; + } + + return SUCCESS; +} diff --git a/src/enzo/Grid_TestGravitySineWaveInitializeGrid.C b/src/enzo/Grid_TestGravitySineWaveInitializeGrid.C new file mode 100644 index 000000000..658a1a28e --- /dev/null +++ b/src/enzo/Grid_TestGravitySineWaveInitializeGrid.C @@ -0,0 +1,127 @@ +/*********************************************************************** +/ GRID CLASS (INITIALIZE THE GRID FOR THE SINE WAVE TEST) +/ +/ written by: JC Passy +/ date: June, 2013 +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#include +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "phys_constants.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" + +int grid::TestGravitySineWaveInitializeGrid(float Amplitude, + float Period, + float Angle, + int PoissonSineWaveSubgridsAreStatic, + int TotalRefinement, + int grid_num) +{ + /* declarations */ + + int dim, i, j, k, size, field, vel; + + /* Create fields */ + + NumberOfBaryonFields = 0; + FieldType[NumberOfBaryonFields++] = Density; + FieldType[NumberOfBaryonFields++] = TotalEnergy; + if (DualEnergyFormalism) + FieldType[NumberOfBaryonFields++] = InternalEnergy; + vel = NumberOfBaryonFields; + FieldType[NumberOfBaryonFields++] = Velocity1; + if (GridRank > 1) + FieldType[NumberOfBaryonFields++] = Velocity2; + if (GridRank > 2) + FieldType[NumberOfBaryonFields++] = Velocity3; + if (WritePotential) + FieldType[NumberOfBaryonFields++] = GravPotential; + + /* Set the subgrid static flag. */ + + SubgridsAreStatic = PoissonSineWaveSubgridsAreStatic; + + /* Return if this doesn't concern us. */ + + if (ProcessorNumber != MyProcessorNumber) + return SUCCESS; + + /* compute size of fields */ + size = 1; + for (dim = 0; dim < GridRank; dim++) + size *= GridDimension[dim]; + + /* allocate fields */ + for (field = 0; field < NumberOfBaryonFields; field++) + if (BaryonField[field] == NULL) + BaryonField[field] = new float[size]; + + /* Set velocities to 0 BaryonField[1,2,3] */ + for (dim = 0; dim < GridRank; dim++) + for (i = 0; i < size; i++) + BaryonField[vel+dim][i] = 0.0; + + int index; + float x,y,z; + float xtilted,dx,xtmp,mean_rho; + + int m; + + for (k = 0; k < GridDimension[2]; k++) + for (j = 0; j < GridDimension[1]; j++) + for (i = 0; i < GridDimension[0]; i++) { + + index = i + GridDimension[0]*(j + GridDimension[1]*k); + + /* Compute position */ + + x = CellLeftEdge[0][i] + 0.5*CellWidth[0][i]; + if (GridRank > 1) + y = CellLeftEdge[1][j] + 0.5*CellWidth[1][j]; + if (GridRank > 2) + z = CellLeftEdge[2][k] + 0.5*CellWidth[2][k]; + + /* Density BaryonField[0]*/ + + xtilted = x*cos(Angle*pi/180.0) + y*sin(Angle*pi/180.0); + dx = CellWidth[0][i]; + + /* Compute mean rho (volume-averaged) only for Angle = 0.0 */ + mean_rho = 0.0; + if (Angle > tiny_number) + mean_rho = Amplitude*(2.0 +sin(2*pi*xtilted/Period)); + else { + for (m = -30; m < 30; m++) { + xtmp = x + m/60*CellWidth[0][i]; + mean_rho = mean_rho + Amplitude*(2.0 +sin(2*pi*xtmp/Period)) ; + } + mean_rho = mean_rho/60.0; + } + + BaryonField[0][index] = mean_rho; + + /* Total SPECIFIC Energy BaryonField[1], don't forget the macroscopic kinetic energic */ + BaryonField[1][index] = 1.0; + } + + /* Set internal energy if necessary. */ + /* Since Velocities are set to 0, this is same as total energy */ + if (DualEnergyFormalism) + for (i = 0; i < size; i++) + BaryonField[2][i] = BaryonField[1][i]; + + return SUCCESS; +} diff --git a/src/enzo/Grid_TestGravitySphereAPMInitializeGrid.C b/src/enzo/Grid_TestGravitySphereAPMInitializeGrid.C new file mode 100644 index 000000000..37d0e9c8a --- /dev/null +++ b/src/enzo/Grid_TestGravitySphereAPMInitializeGrid.C @@ -0,0 +1,211 @@ +/*********************************************************************** +/ +/ GRID CLASS (INITIALIZE THE GRID FOR A SPHERE GRAVITY TEST) +/ +/ written by: Greg Bryan +/ date: September, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "phys_constants.h" + +int grid::TestGravitySphereAPMInitializeGrid(float SphereInteriorDensity, + float SphereExteriorDensity, + float SphereRadius, + int SphereType, + int UseBaryons, + FLOAT SphereCenter[]) +{ + /* declarations */ + + int dim, i, j, k, size, vel; + float phi, r, theta; + + if (UseBaryons) + { + + /* create fields */ + + NumberOfBaryonFields = 0; + FieldType[NumberOfBaryonFields++] = Density; + FieldType[NumberOfBaryonFields++] = TotalEnergy; + if (DualEnergyFormalism) + FieldType[NumberOfBaryonFields++] = InternalEnergy; + vel = NumberOfBaryonFields; + FieldType[NumberOfBaryonFields++] = Velocity1; + if (GridRank > 1) + FieldType[NumberOfBaryonFields++] = Velocity2; + if (GridRank > 2) + FieldType[NumberOfBaryonFields++] = Velocity3; + + if (WritePotential) + FieldType[NumberOfBaryonFields++] = GravPotential; + } + + /* Return if this doesn't concern us. */ + + if (ProcessorNumber != MyProcessorNumber) + return SUCCESS; + + /* Set particles. */ + + if (NumberOfParticles > 0) + { + + /* Allocate space. */ + + this->AllocateNewParticles(NumberOfParticles); + + /* Create random particle positions and set velocities to zero. */ + + for (dim = 0; dim < GridRank; dim++) + for (i = 1; i < NumberOfParticles; i++) + { + +#ifdef UNUSED + + ParticlePosition[dim][i] = FLOAT(rand()) / FLOAT(RAND_MAX); + +#endif /* UNUSED */ + + ParticleVelocity[dim][i] = 0.0; + + ParticleMass[i] = tiny_number; + } + + /* Set positions randomly distributed in log r from center. */ + + float r1 = log10(0.2 * CellWidth[0][0]); + float r2 = log10(0.45 * (DomainRightEdge[0] - DomainLeftEdge[0])); + for (i = 0; i < NumberOfParticles; i++) + { + + /* Compute random r, phi and theta. */ + + r = POW(10, (r2 - r1) * float(rand()) / float(RAND_MAX) + r1); + phi = 2.0 * pi * float(rand()) / float(RAND_MAX); + theta = pi * float(rand()) / float(RAND_MAX); + + /* Turn these into x/y/z. */ + + if (GridRank == 1) + ParticlePosition[0][i] = r * sign(phi - pi); + + if (GridRank == 2) + { + ParticlePosition[0][i] = r * cos(phi); + ParticlePosition[1][i] = r * sin(phi); + } + + if (GridRank == 3) + { + ParticlePosition[0][i] = r * sin(theta) * cos(phi); + ParticlePosition[1][i] = r * sin(theta) * sin(phi); + ParticlePosition[2][i] = r * cos(theta); + } + + /* Shift center from 0,0,0 to the middle of the volume. */ + + for (dim = 0; dim < GridRank; dim++) + ParticlePosition[dim][i] += SphereCenter[dim]; + + /* Set particle identifier. */ + + ParticleNumber[i] = i; + ParticleType[i] = PARTICLE_TYPE_DARK_MATTER; + } + } + + /* If requested, set up the baryon field. */ + + if (UseBaryons) + { + + /* compute size of fields */ + + size = 1; + for (dim = 0; dim < GridRank; dim++) + size *= GridDimension[dim]; + + /* allocate fields */ + + this->AllocateGrids(); + + /* Set densities. */ + + float density, r, x, y = 0, z = 0; + + for (k = 0; k < GridDimension[2]; k++) + for (j = 0; j < GridDimension[1]; j++) + for (i = 0; i < GridDimension[0]; i++) + { + + /* Compute position */ + + x = CellLeftEdge[0][i] + 0.5 * CellWidth[0][i]; + if (GridRank > 1) + y = CellLeftEdge[1][j] + 0.5 * CellWidth[1][j]; + if (GridRank > 2) + z = CellLeftEdge[2][k] + 0.5 * CellWidth[2][k]; + + /* Find distance from center. */ + + r = sqrt((x - SphereCenter[0]) * (x - SphereCenter[0]) + + (y - SphereCenter[1]) * (y - SphereCenter[1]) + + (z - SphereCenter[2]) * (z - SphereCenter[2])); + + /* set density */ + + if (r < max(SphereRadius, CellWidth[0][0])) + { + if (SphereType == 0) + density = SphereInteriorDensity; + if (SphereType == 1) + density = SphereInteriorDensity * POW(r / SphereRadius, -2); + if (SphereType == 2) + density = SphereInteriorDensity * POW(1 + POW(r / SphereRadius, 2), -2.5); + } + else + density = SphereExteriorDensity; + + BaryonField[0][k * GridDimension[0] * GridDimension[1] + + j * GridDimension[0] + i] = + density; + } + + /* Set velocities */ + + for (dim = 0; dim < GridRank; dim++) + for (i = 0; i < size; i++) + BaryonField[vel + dim][i] = 0.0; + + /* set total energy */ + + for (i = 0; i < size; i++) + BaryonField[1][i] = tiny_number; + + /* Set internal energy if necessary. */ + + if (DualEnergyFormalism) + for (i = 0; i < size; i++) + BaryonField[2][i] = tiny_number; + } + + return SUCCESS; +} diff --git a/src/enzo/Grid_TestSelfForceInitializeGrid.C b/src/enzo/Grid_TestSelfForceInitializeGrid.C new file mode 100644 index 000000000..3fab38623 --- /dev/null +++ b/src/enzo/Grid_TestSelfForceInitializeGrid.C @@ -0,0 +1,63 @@ +/*********************************************************************** +/ +/ GRID CLASS (INITIALIZE THE GRID FOR A SELFFORCE TEST) +/ +/ written by: Jean-Claude Passy +/ date: June 2013 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: FAIL or SUCCESS +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" + + +int grid::TestSelfForceInitializeGrid(float CentralDensity, + int NumberOfNewParticles, + float xpos, float ypos, float zpos, + float vx, float vy, float vz) +{ + /* declarations */ + + int dim, i, size, field, vel; + float phi, r, theta, pi = 3.14159; + + /* Return if this doesn't concern us. */ + if (ProcessorNumber != MyProcessorNumber) + return SUCCESS; + + if (NumberOfNewParticles > 0) { + + /* Set particles. */ + NumberOfParticles = NumberOfNewParticles; + + /* Allocate space. */ + this->AllocateNewParticles(NumberOfParticles); + + /* Set central particle */ + ParticleMass[0] = CentralDensity; + + ParticlePosition[0][0] = xpos; + ParticlePosition[1][0] = ypos; + ParticlePosition[2][0] = zpos; + + ParticleVelocity[0][0] = vx; + ParticleVelocity[1][0] = vy; + ParticleVelocity[2][0] = vz; + } + + return SUCCESS; +} diff --git a/src/enzo/Grid_UpdateParticleVelocity.C b/src/enzo/Grid_UpdateParticleVelocity.C index 2b12f1e90..3a4aa605d 100644 --- a/src/enzo/Grid_UpdateParticleVelocity.C +++ b/src/enzo/Grid_UpdateParticleVelocity.C @@ -11,7 +11,7 @@ / NOTE: / ************************************************************************/ - + #include #include "ErrorExceptions.h" #include "macros_and_parameters.h" @@ -21,25 +21,25 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" - + /* function prototypes */ - + #define VELOCITY_METHOD3 - + int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); - - + + int grid::UpdateParticleVelocity(float TimeStep) { - + /* Return if this doesn't concern us. */ - + if (ProcessorNumber != MyProcessorNumber) return SUCCESS; - + if ((NumberOfParticles == 0 && NumberOfActiveParticles == 0) || ParticleAcceleration[0] == NULL) return SUCCESS; - + FLOAT a = 1.0, dadt; #if defined(VELOCITY_METHOD1) || defined(VELOCITY_METHOD2) float VelocityMidStep; @@ -49,81 +49,97 @@ int grid::UpdateParticleVelocity(float TimeStep) FLOAT coef, coef1, coef2; /* If using comoving coordinates, divide by a(t) first. */ - + if (ComovingCoordinates) if (CosmologyComputeExpansionFactor(Time + TimeStep, &a, &dadt) == FAIL) { ENZO_FAIL("Error in CsomologyComputeExpansionFactors."); } - + /* Loop over dimensions. */ - + for (int dim = 0; dim < GridRank; dim++) { - + /* Error check. */ - + if (ParticleAcceleration[dim] == NULL) { ENZO_FAIL("No ParticleAcceleration present."); } - + /* Update velocities. */ - + if (ComovingCoordinates) { - + coef = 0.5*dadt/a*TimeStep; coef1 = 1.0 - coef; coef2 = 1.0 / (1.0 + coef); - + /* If using comoving coordinates, subtract the (time-centered) drag-like term and add the acceleration. The acceleration has already been divided by a(t). */ - + for (i = 0; i < NumberOfParticles; i++) { - + #ifdef VELOCITY_METHOD1 - + /* i) partially time-centered. */ - + VelocityMidStep = ParticleVelocity[dim][i] + ParticleAcceleration[dim][i]*0.5*TimeStep; - + ParticleVelocity[dim][i] += (-VelocityMidStep*dadt/a + ParticleAcceleration[dim][i]) * TimeStep; - + #endif /* VELOCITY_METHOD1 */ - + #ifdef VELOCITY_METHOD2 - + /* ii) partially backward. */ - + VelocityMidStep = ParticleVelocity[dim][i] ; - + ParticleVelocity[dim][i] += (-VelocityMidStep*dadt/a + ParticleAcceleration[dim][i]) * TimeStep; - + #endif /* VELOCITY_METHOD2 */ - + #ifdef VELOCITY_METHOD3 - + /* iii) Semi-implicit way */ - + ParticleVelocity[dim][i] = (coef1*ParticleVelocity[dim][i] + ParticleAcceleration[dim][i]*TimeStep)*coef2; - + #endif /* VELOCITY_METHOD3 */ - + } } else - + /* Otherwise, just add the acceleration. */ - + for (i = 0; i < NumberOfParticles; i++) ParticleVelocity[dim][i] += ParticleAcceleration[dim][i] * TimeStep; - - } + } + /* Some diagnostics */ + float time_now = ReturnTime(); + + // TestSelfForce: there is only one particle + if (ProblemType == 47) { + if (NumberOfParticles > 1) + ENZO_VFAIL("Error in grid->UpdateParticleVelocity, TestSelfForce: NumberofParticles is %"PISYM" > 1\n", NumberOfParticles); + + if (NumberOfParticles == 1) { + printf("PARTICLE %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM" %"ESYM"\n", + time_now, + ParticlePosition[0][0], ParticlePosition[1][0], ParticlePosition[2][0], + ParticleVelocity[0][0], ParticleVelocity[1][0], ParticleVelocity[2][0], + ParticleAcceleration[0][0], ParticleAcceleration[1][0], ParticleAcceleration[2][0]); + fflush(stdout); + } + } if (ProblemType == 29) for (i = 0; i < NumberOfParticles; i++) @@ -137,17 +153,17 @@ int grid::UpdateParticleVelocity(float TimeStep) == FAIL) { ENZO_FAIL("Error in CsomologyComputeExpansionFactors."); } - + for (i = 0; i < NumberOfActiveParticles; i++) { float* apvel = ActiveParticles[i]->ReturnVelocity(); - + for (dim = 0; dim < GridRank; dim++) { - + #ifdef VELOCITY_METHOD1 /* i) partially time-centered. */ - + VelocityMidStep = apvel[dim] + ActiveParticleAcceleration[dim][i]*0.5*TimeStep; @@ -159,7 +175,7 @@ int grid::UpdateParticleVelocity(float TimeStep) #ifdef VELOCITY_METHOD2 /* ii) partially backward. */ - + VelocityMidStep = apvel[dim]; apvel[dim] += @@ -170,7 +186,7 @@ int grid::UpdateParticleVelocity(float TimeStep) #ifdef VELOCITY_METHOD3 /* iii) Semi-implicit way */ - + apvel[dim] = (coef1*apvel[dim] + ActiveParticleAcceleration[dim][i]*TimeStep)*coef2; @@ -181,19 +197,19 @@ int grid::UpdateParticleVelocity(float TimeStep) } } else { - + /* Otherwise, just add the acceleration. */ - + for (i = 0; i < NumberOfActiveParticles; i++) { float* apvel = ActiveParticles[i]->ReturnVelocity(); - + for (dim = 0; dim < GridRank; dim++) apvel[dim] += ActiveParticleAcceleration[dim][i] * TimeStep; - + ActiveParticles[i]->SetVelocity(apvel); } } } - + return SUCCESS; } diff --git a/src/enzo/Grid_ZeusSolver.C b/src/enzo/Grid_ZeusSolver.C index d9c09baef..93d004a0c 100644 --- a/src/enzo/Grid_ZeusSolver.C +++ b/src/enzo/Grid_ZeusSolver.C @@ -56,46 +56,46 @@ c minsupecoef - coefficient for minimum pressure support (0 - not used) #include "fortran.def" -int Zeus_xTransport(float *d, float *e, float *u, float *v, float *w, +int Zeus_xTransport(float *d, float *e, float *u, float *v, float *w, int in, int jn, int kn, int rank, int is, int ie, int js, int je, int ks, int ke, float dt, float dx[], float *f1, int bottom, int nsubgrids, long_int GridGlobalStart[], - fluxes *SubgridFluxes[], int DensNum, int TENum, + fluxes *SubgridFluxes[], int DensNum, int TENum, int Vel1Num, int Vel2Num, int Vel3Num, float *BaryonField[], int NumberOfColours, int colnum[]); -int Zeus_yTransport(float *d, float *e, float *u, float *v, float *w, +int Zeus_yTransport(float *d, float *e, float *u, float *v, float *w, int in, int jn, int kn, int rank, int is, int ie, int js, int je, int ks, int ke, float dt, float dy[], float *f1, int bottom, int nsubgrids, long_int GridGlobalStart[], - fluxes *SubgridFluxes[], int DensNum, int TENum, + fluxes *SubgridFluxes[], int DensNum, int TENum, int Vel1Num, int Vel2Num, int Vel3Num, float *BaryonField[], int NumberOfColours, int colnum[]); -int Zeus_zTransport(float *d, float *e, float *u, float *v, float *w, +int Zeus_zTransport(float *d, float *e, float *u, float *v, float *w, int in, int jn, int kn, int rank, int is, int ie, int js, int je, int ks, int ke, float dt, float dz[], float *f1, int bottom, int nsubgrids, long_int GridGlobalStart[], - fluxes *SubgridFluxes[], int DensNum, int TENum, + fluxes *SubgridFluxes[], int DensNum, int TENum, int Vel1Num, int Vel2Num, int Vel3Num, float *BaryonField[], int NumberOfColours, int colnum[]); -int ZeusSource(float *d, float *e, float *u, float *v, float *w, float *p, float *cr, +int ZeusSource(float *d, float *e, float *u, float *v, float *w, float *p, float *cr, int in, int jn, int kn, int rank, int igamfield, - int is, int ie, int js, int je, int ks, int ke, + int is, int ie, int js, int je, int ks, int ke, float C1, float C2, int ipresfree, float *gamma, float dt, float pmin, float dx[], float dy[], float dz[], - int gravity, float *gr_xacc, float *gr_yacc, float *gr_zacc, + int gravity, float *gr_xacc, float *gr_yacc, float *gr_zacc, int bottom, float minsupecoef, int CRModel, float CRgamma); int ZeusFDM(float *d, float *e, float *u, float *v, float *w, float *p, int in, int jn, int kn, int rank, - int is, int ie, int js, int je, int ks, int ke, + int is, int ie, int js, int je, int ks, int ke, float C1, float C2, float *gamma, float dt, float dx[], float dy[], float dz[], - int gravity, float *gr_xacc, float *gr_yacc, float *gr_zacc, + int gravity, float *gr_xacc, float *gr_yacc, float *gr_zacc, float minsupecoef, float lapcoef); int GetUnits (float *DensityUnits, float *LengthUnits, @@ -105,8 +105,8 @@ int FindField(int field, int farray[], int numfields); int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); -int grid::ZeusSolver(float *gamma, int igamfield, int nhy, - float dx[], float dy[], float dz[], +int grid::ZeusSolver(float *gamma, int igamfield, int nhy, + float dx[], float dy[], float dz[], int gravity, int NumberOfSubgrids, long_int GridGlobalStart[], fluxes *SubgridFluxes[], int NumberOfColours, int colnum[], int bottom, @@ -131,7 +131,7 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, int size = GridDimension[0]*GridDimension[1]*GridDimension[2]; float *p = new float[size]; - + /* Find fields: density, total energy, velocity1-3 and set pointers to them Create zero fields for velocity2-3 for low-dimension runs because solver assumes they exist. */ @@ -142,7 +142,7 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, ENZO_FAIL("Cannot Find Cosmic Rays"); cr = BaryonField[CRNum]; } - + d = BaryonField[DensNum]; e = BaryonField[TENum]; u = BaryonField[Vel1Num]; @@ -205,18 +205,49 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, if (fabs(u[i]) > dx[0]/dtFixed || fabs(v[i]) > dy[0]/dtFixed || fabs(w[i]) > dz[0]/dtFixed) { - fprintf(stderr, "u,v,w,d,e=%"GSYM",%"GSYM",%"GSYM",%"GSYM",%"GSYM" dx=%"GSYM" dt=%"GSYM"\n", + fprintf(stderr, "u,v,w,d,e=%"GSYM",%"GSYM",%"GSYM",%"GSYM",%"GSYM" dx=%"GSYM" dt=%"GSYM"\n", u[i],v[i],w[i],d[i],e[i], dx[0], dtFixed); ENZO_FAIL("Velocity too fast! (pre-call)\n"); } } - + /* 1) Add source terms */ + float *AccelerationField0 = AccelerationField[0]; + float *AccelerationField1 = AccelerationField[1]; + float *AccelerationField2 = AccelerationField[2]; + + // If we use the APM solver, one must add the external contribution + float *AccelerationFieldTotalAPMZeus[MAX_DIMENSION]; + for (int dim = 0; dim < GridRank; dim++) { + AccelerationFieldTotalAPMZeus[dim] = NULL; + AccelerationFieldTotalAPMZeus[dim] = new float[size]; + } + + if (GravitySolverType == GRAVITY_SOLVER_APM) { + if (ProblemType == 41 || ProblemType == 42 || ProblemType == 43 || ProblemType == 46) { + + for (int dim = 0; dim < GridRank; dim++) { + + // Error check + if (AccelerationFieldExternalAPM[dim] == NULL) + ENZO_FAIL("External acceleration absent in grid->ZeusSolver.C\n"); + + for (i = 0; i < size; i++) { + AccelerationFieldTotalAPMZeus[dim][i] = + AccelerationField[dim][i] + AccelerationFieldExternalAPM[dim][i]; + } + } + + AccelerationField0 = AccelerationFieldTotalAPMZeus[0]; + AccelerationField1 = AccelerationFieldTotalAPMZeus[1]; + AccelerationField2 = AccelerationFieldTotalAPMZeus[2]; + } + } /* FDM: if FDM is used */ if (QuantumPressure) { - + float TemperatureUnits = 1, DensityUnits = 1, LengthUnits = 1, VelocityUnits = 1, TimeUnits = 1; @@ -235,16 +266,16 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, float hmcoef = 5.9157166856e27*TimeUnits/pow(LengthUnits/afloat,2)/FDMMass; //(hbar/m)^2/2 double lapcoef = POW(hmcoef,2)/2.; - + if (ZeusFDM(d, e, u, v, w, p, GridDimension[0], GridDimension[1], GridDimension[2], - GridRank, - is, ie, js, je, ks, ke, + GridRank, + is, ie, js, je, ks, ke, ZEUSLinearArtificialViscosity, ZEUSQuadraticArtificialViscosity, gamma, dtFixed, dx, dy, dz, - gravity, AccelerationField[0], AccelerationField[1], - AccelerationField[2], + gravity, AccelerationField0, AccelerationField1, + AccelerationField2, minsupecoef,lapcoef) == FAIL) { fprintf(stderr, "P(%"ISYM"): Error in ZeusFDM on step %"ISYM" (dt=%"GSYM")\n", MyProcessorNumber, nhy, dtFixed); fprintf(stderr, " grid dims = %"ISYM" %"ISYM" %"ISYM"\n", GridDimension[0], GridDimension[1], GridDimension[2]); @@ -253,15 +284,15 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, } else { - if (ZeusSource(d, e, u, v, w, p, cr, + if (ZeusSource(d, e, u, v, w, p, cr, GridDimension[0], GridDimension[1], GridDimension[2], GridRank, igamfield, - is, ie, js, je, ks, ke, + is, ie, js, je, ks, ke, ZEUSLinearArtificialViscosity, ZEUSQuadraticArtificialViscosity, PressureFree, gamma, dtFixed, pmin, dx, dy, dz, - gravity, AccelerationField[0], AccelerationField[1], - AccelerationField[2], + gravity, AccelerationField0, AccelerationField1, + AccelerationField2, bottom, minsupecoef, CRModel, CRgamma) == FAIL) { fprintf(stderr, "P(%"ISYM"): Error in ZeusSource on step %"ISYM" (dt=%"GSYM")\n", MyProcessorNumber, nhy, dtFixed); @@ -271,7 +302,7 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, } /* Error check */ - + float CRcs = 0.0; if (CRmaxSoundSpeed != 0.0){ // Get system of units @@ -282,7 +313,7 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, ENZO_FAIL("Error in GetUnits."); } - CRsound = CRmaxSoundSpeed/VelocityUnits; + CRsound = CRmaxSoundSpeed/VelocityUnits; CRcs = (CRgamma-1.0)/(CRsound*CRsound); } @@ -290,16 +321,16 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, if (fabs(u[i]) > dx[0]/dtFixed || fabs(v[i]) > dy[0]/dtFixed || fabs(w[i]) > dz[0]/dtFixed) { - fprintf(stderr, "u,v,w,d,e=%"GSYM",%"GSYM",%"GSYM",%"GSYM",%"GSYM" dx=%"GSYM" dt=%"GSYM"\n", + fprintf(stderr, "u,v,w,d,e=%"GSYM",%"GSYM",%"GSYM",%"GSYM",%"GSYM" dx=%"GSYM" dt=%"GSYM"\n", u[i],v[i],w[i],d[i],e[i], dx[0], dtFixed); ENZO_FAIL("Velocity too fast! (post-call)\n"); } - + /* -- density/TE floor for CR model -- */ if ( CRModel ){ if ( CRdensFloor != 0.0 && d[i] < CRdensFloor ) d[i] = CRdensFloor; - if ( CRcs != 0.0 && d[i] < CRcs*cr[i] ) d[i] = CRcs*cr[i]; // Limits sound-speed + if ( CRcs != 0.0 && d[i] < CRcs*cr[i] ) d[i] = CRcs*cr[i]; // Limits sound-speed if ( e[i] < tiny_number*1e-5 ) e[i] = tiny_number*1e-5; } // end cr model if } // end i for @@ -310,9 +341,9 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, for(n=ixyz; n <= ixyz+GridRank-1; n++) { /* Transport step - x direction */ - + if ((n % GridRank) == 0) - ret = Zeus_xTransport(d, e, u, v, w, GridDimension[0], + ret = Zeus_xTransport(d, e, u, v, w, GridDimension[0], GridDimension[1], GridDimension[2], GridRank, is, ie, js, je, ks, ke, dtFixed, dx, p, bottom, @@ -324,7 +355,7 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, /* Transport step - y direction */ if ((n % GridRank) == 1 && GridRank > 1) - ret = Zeus_yTransport(d, e, u, v, w, GridDimension[0], + ret = Zeus_yTransport(d, e, u, v, w, GridDimension[0], GridDimension[1], GridDimension[2], GridRank, is, ie, js, je, ks, ke, dtFixed, dy, p, bottom, @@ -336,7 +367,7 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, /* Transport step - z direction */ if ((n % GridRank) == 2 && GridRank > 2) - ret = Zeus_zTransport(d, e, u, v, w, GridDimension[0], + ret = Zeus_zTransport(d, e, u, v, w, GridDimension[0], GridDimension[1], GridDimension[2], GridRank, is, ie, js, je, ks, ke, dtFixed, dz, p, bottom, @@ -344,22 +375,24 @@ int grid::ZeusSolver(float *gamma, int igamfield, int nhy, SubgridFluxes, DensNum, TENum, Vel1Num, Vel2Num, Vel3Num, BaryonField, NumberOfColours, colnum); - + if (ret == FAIL) { - fprintf(stderr, "P(%"ISYM"): Error on ZeusTransport dim=%"ISYM" (Cycle = %"ISYM", dt=%"GSYM")\n", + fprintf(stderr, "P(%"ISYM"): Error on ZeusTransport dim=%"ISYM" (Cycle = %"ISYM", dt=%"GSYM")\n", MyProcessorNumber, n % GridRank, nhy, dtFixed); fprintf(stderr, " grid dims = %"ISYM" %"ISYM" %"ISYM"\n", GridDimension[0], GridDimension[1], GridDimension[2]); ENZO_FAIL("Error in ZeusSource!\n"); } - + } // end loop over n - + /* Clean up */ + for (int dim = 0; dim < GridRank; dim++) + delete [] AccelerationFieldTotalAPMZeus[dim]; delete [] p; if (GridRank < 2) delete [] v; if (GridRank < 3) delete [] w; - + return SUCCESS; } diff --git a/src/enzo/Grid_constructor.C b/src/enzo/Grid_constructor.C index 684e0de0f..4ae84103d 100644 --- a/src/enzo/Grid_constructor.C +++ b/src/enzo/Grid_constructor.C @@ -15,7 +15,7 @@ #include #include - + #include "ErrorExceptions.h" #include "list.h" #include "macros_and_parameters.h" @@ -26,12 +26,12 @@ #include "ExternalBoundary.h" #include "Grid.h" #include "hydro_rk/SuperNova.h" - + grid::grid() { - + /* clear scalars */ - + GridRank = 0; Time = 0.0; OldTime = 0.0; @@ -45,9 +45,9 @@ grid::grid() SubgridFluxStorage = NULL; NumberOfSubgrids = 1; - + /* clear MAX_DIMENSION vectors */ - + int i, j; for (i = 0; i < MAX_DIMENSION; i++) { GridDimension[i] = 1; @@ -66,12 +66,15 @@ grid::grid() RandomForcingField[i] = NULL; PhaseFctMultEven[i] = NULL; // WS PhaseFctMultOdd[i] = NULL; // WS + + if (GravitySolverType == GRAVITY_SOLVER_APM) + AccelerationFieldExternalAPM[i] = NULL; // APM solver } PhaseFctInitEven = NULL; // WS PhaseFctInitOdd = NULL; // WS if (UseSGSModel == 1) { - for (i = 0; i < MAX_DIMENSION; i++) + for (i = 0; i < MAX_DIMENSION; i++) for (j = 0; j < MAX_DIMENSION; j++) { JacVel[i][j] = NULL; JacB[i][j] = NULL; @@ -84,15 +87,15 @@ grid::grid() FltrhoUU[i] = NULL; FltBB[i] = NULL; } - for (i = 0; i < 3; i++) + for (i = 0; i < 3; i++) FltUB[i] = NULL; } ParticleAcceleration[MAX_DIMENSION] = NULL; - ActiveParticleAcceleration[MAX_DIMENSION] = NULL; - + ActiveParticleAcceleration[MAX_DIMENSION] = NULL; + /* clear MAX_NUMBER_OF_BARYON_FIELDS vectors & [][MAX_DIMENSION] matricies */ - + for (i = 0; i < MAX_NUMBER_OF_BARYON_FIELDS; i++) { BaryonField[i] = NULL; OldBaryonField[i] = NULL; @@ -118,7 +121,7 @@ grid::grid() AccelerationHack = FALSE; /* Clear miscelaneous pointers */ - + ParticleMass = NULL; ParticleNumber = NULL; ParticleType = NULL; @@ -130,9 +133,9 @@ grid::grid() ParticleAttribute[i] = NULL; BoundaryFluxes = NULL; - + /* Clear flagging field pointers */ - + ParticleMassFlaggingField = NULL; MassFlaggingField = NULL; FlaggingField = NULL; @@ -150,16 +153,16 @@ grid::grid() PausedPhotonPackages = new PhotonPackageEntry; PausedPhotonPackages->NextPackage = NULL; PausedPhotonPackages->PreviousPackage = NULL; - + PhotonPackages->Photons = 1.; - PhotonPackages->Type = 0; - PhotonPackages->Energy = 0.; - PhotonPackages->EmissionTimeInterval= 0.; - PhotonPackages->EmissionTime = 0.; - PhotonPackages->CurrentTime = 0.; - PhotonPackages->Radius = 0.; - PhotonPackages->ipix = 0; - PhotonPackages->level = 0; + PhotonPackages->Type = 0; + PhotonPackages->Energy = 0.; + PhotonPackages->EmissionTimeInterval= 0.; + PhotonPackages->EmissionTime = 0.; + PhotonPackages->CurrentTime = 0.; + PhotonPackages->Radius = 0.; + PhotonPackages->ipix = 0; + PhotonPackages->level = 0; sfSeed = 0; ID = 0; @@ -183,7 +186,7 @@ grid::grid() #endif /* Star particles */ - + NumberOfStars = 0; Stars = NULL; @@ -191,7 +194,7 @@ grid::grid() for (i=0; i 0) { fprintf(stderr, "warning: destroying live particles (%"ISYM").\n", @@ -47,7 +47,7 @@ grid::~grid() /* exit(EXIT_FAILURE); */ } #endif /* UNUSED */ - + for (i = 0; i < MAX_DIMENSION; i++) { delete [] CellLeftEdge[i]; delete [] CellWidth[i]; @@ -58,8 +58,12 @@ grid::~grid() delete [] RandomForcingField[i]; if (PhaseFctMultEven[i] != NULL) delete[] PhaseFctMultEven[i]; if (PhaseFctMultOdd[i] != NULL) delete[] PhaseFctMultOdd[i]; + + // APM solver + if (GravitySolverType == GRAVITY_SOLVER_APM) + delete [] AccelerationFieldExternalAPM[i]; } - + if (PhaseFctInitEven != NULL) delete[] PhaseFctInitEven; if (PhaseFctInitOdd != NULL) delete[] PhaseFctInitOdd; @@ -88,12 +92,12 @@ grid::~grid() if (FltrhoUU[i] != NULL) delete [] FltrhoUU[i]; FltrhoUU[i] = NULL; - + if (FltBB[i] != NULL) delete [] FltBB[i]; FltBB[i] = NULL; } - + for (i = 0; i < 3; i++) { if (FltUB[i] != NULL) delete [] FltUB[i]; @@ -102,7 +106,7 @@ grid::~grid() } delete ParticleAcceleration[MAX_DIMENSION]; - + for (i = 0; i < MAX_NUMBER_OF_BARYON_FIELDS; i++) { delete [] BaryonField[i]; delete [] OldBaryonField[i]; @@ -117,10 +121,10 @@ grid::~grid() } } #endif - + DeleteFluxes(BoundaryFluxes); delete BoundaryFluxes; - + delete [] ParticleMass; delete [] ParticleNumber; delete [] ParticleType; @@ -130,7 +134,7 @@ grid::~grid() delete [] FlaggingField; delete [] MassFlaggingField; delete [] ParticleMassFlaggingField; - + for (i = 0; i < MAX_NUMBER_OF_PARTICLE_ATTRIBUTES; i++) delete [] ParticleAttribute[i]; @@ -146,15 +150,15 @@ grid::~grid() delete [] SubgridMarker; #endif -/* +/* if (debug && GridRank > 0) { printf("grid->destructor: deleting grid with dims = "); WriteListOfInts(stdout, GridRank, GridDimension); } */ - //MHD stuff - + //MHD stuff + if( UseMHDCT ){ for(i=0;i<3;i++){ diff --git a/src/enzo/Grid_xEulerSweep.C b/src/enzo/Grid_xEulerSweep.C index ac8611bc6..0be00f780 100644 --- a/src/enzo/Grid_xEulerSweep.C +++ b/src/enzo/Grid_xEulerSweep.C @@ -111,11 +111,23 @@ int grid::xEulerSweep(int k, int NumberOfSubgrids, fluxes *SubgridFluxes[], for (i = 0; i < GridDimension[0]; i++) wslice[index2+i] = 0; - if (GravityOn) + if (GravityOn) { for (i = 0; i < GridDimension[0]; i++) { index3 = (k*GridDimension[1] + j) * GridDimension[0] + i; grslice[index2+i] = AccelerationField[dim][index3]; } + // Add external potential with APM solver. + if (GravitySolverType == GRAVITY_SOLVER_APM) { + if (ProblemType == 41 || ProblemType == 42 || ProblemType == 43 || ProblemType == 46) { + if (AccelerationFieldExternalAPM[dim] == NULL) + ENZO_FAIL("Error in grid->xEulerSweep.C: AccelerationFieldExternalAPM is NULL!\n"); + for (i = 0; i < GridDimension[0]; i++) { + index3 = (k*GridDimension[1] + j) * GridDimension[0] + i; + grslice[index2+i] += AccelerationFieldExternalAPM[dim][index3]; + } + } + } + } if (DualEnergyFormalism) for (i = 0; i < GridDimension[0]; i++) { diff --git a/src/enzo/Grid_yEulerSweep.C b/src/enzo/Grid_yEulerSweep.C index 24305c442..92d01dc09 100644 --- a/src/enzo/Grid_yEulerSweep.C +++ b/src/enzo/Grid_yEulerSweep.C @@ -109,11 +109,23 @@ int grid::yEulerSweep(int i, int NumberOfSubgrids, fluxes *SubgridFluxes[], for (j = 0; j < GridDimension[1]; j++) vslice[index2+j] = 0; - if (GravityOn) + if (GravityOn) { for (j = 0; j < GridDimension[1]; j++) { index3 = (k*GridDimension[1] + j) * GridDimension[0] + i; grslice[index2+j] = AccelerationField[dim][index3]; } + // Add external potential with APM solver. + if (GravitySolverType == GRAVITY_SOLVER_APM) { + if (ProblemType == 41 || ProblemType == 42 || ProblemType == 43 || ProblemType == 46) { + if (AccelerationFieldExternalAPM[dim] == NULL) + ENZO_FAIL("Error in grid->yEulerSweep.C: AccelerationFieldExternalAPM is NULL!\n"); + for (j = 0; j < GridDimension[1]; j++) { + index3 = (k*GridDimension[1] + j) * GridDimension[0] + i; + grslice[index2+j] += AccelerationFieldExternalAPM[dim][index3]; + } + } + } + } if (DualEnergyFormalism) for (j = 0; j < GridDimension[1]; j++) { diff --git a/src/enzo/Grid_zEulerSweep.C b/src/enzo/Grid_zEulerSweep.C index 2a51a3e9b..f1d7a83a8 100644 --- a/src/enzo/Grid_zEulerSweep.C +++ b/src/enzo/Grid_zEulerSweep.C @@ -108,11 +108,23 @@ int grid::zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], for (k = 0; k < GridDimension[2]; k++) uslice[index2+k] = 0; - if (GravityOn) + if (GravityOn) { for (k = 0; k < GridDimension[2]; k++) { index3 = (k*GridDimension[1] + j) * GridDimension[0] + i; grslice[index2+k] = AccelerationField[dim][index3]; } + // Add external potential with APM solver. + if (GravitySolverType == GRAVITY_SOLVER_APM) { + if (ProblemType == 41 || ProblemType == 42 || ProblemType == 43 || ProblemType == 46) { + if (AccelerationFieldExternalAPM[dim] == NULL) + ENZO_FAIL("Error in grid->zEulerSweep.C: AccelerationFieldExternalAPM is NULL!\n"); + for (k = 0; k < GridDimension[2]; k++) { + index3 = (k*GridDimension[1] + j) * GridDimension[0] + i; + grslice[index2+k] += AccelerationFieldExternalAPM[dim][index3]; + } + } + } + } if (DualEnergyFormalism) for (k = 0; k < GridDimension[2]; k++) { diff --git a/src/enzo/InitializeNew.C b/src/enzo/InitializeNew.C index 871a06748..4b20dd38b 100644 --- a/src/enzo/InitializeNew.C +++ b/src/enzo/InitializeNew.C @@ -16,16 +16,16 @@ / RETURNS: SUCCESS or FAIL / ************************************************************************/ - + // This routine intializes a new simulation based on the parameter file. - + #ifdef USE_MPI #include "mpi.h" #endif /* USE_MPI */ - + #include #include - + #include "ErrorExceptions.h" #include "macros_and_parameters.h" #include "typedefs.h" @@ -37,9 +37,9 @@ #include "Hierarchy.h" #include "TopGridData.h" #include "CommunicationUtilities.h" - + // Function prototypes - + int InitializeMovieFile(TopGridData &MetaData, HierarchyEntry &TopGrid); int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt); int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *Filename=NULL); @@ -47,7 +47,7 @@ void ConvertTotalEnergyToGasEnergy(HierarchyEntry *Grid); int SetDefaultGlobalValues(TopGridData &MetaData); int CommunicationPartitionGrid(HierarchyEntry *Grid, int gridnum); int CommunicationBroadcastValue(PINT *Value, int BroadcastProcessor); - + // Initialization function prototypes int LightBosonInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData);//FDM @@ -126,28 +126,28 @@ int PutSinkRestartInitialize(FILE *fptr, FILE *Outfptr, int ProtostellarCollapseInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); -int CoolingTestInitialize(FILE *fptr, FILE *Outfptr, - HierarchyEntry &TopGrid, TopGridData &MetaData); -int OneZoneFreefallTestInitialize(FILE *fptr, FILE *Outfptr, +int CoolingTestInitialize(FILE *fptr, FILE *Outfptr, + HierarchyEntry &TopGrid, TopGridData &MetaData); +int OneZoneFreefallTestInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int CosmologySimulationInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int CosmologySimulationReInitialize(HierarchyEntry *TopGrid, TopGridData &MetaData); - + int NestedCosmologySimulationInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int NestedCosmologySimulationReInitialize(HierarchyEntry *TopGrid, TopGridData &MetaData); - + int TurbulenceSimulationInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int TurbulenceSimulationReInitialize(HierarchyEntry *TopGrid, TopGridData &MetaData); - + int TracerParticleCreation(FILE *fptr, HierarchyEntry &TopGrid, TopGridData &MetaData); @@ -158,7 +158,7 @@ int ShearingBox2DInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, int ShearingBoxStratifiedInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); #ifdef TRANSFER -int PhotonTestInitialize(FILE *fptr, FILE *Outfptr, +int PhotonTestInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, bool Reinitialize=false); int PhotonTestRestartInitialize(FILE *fptr, FILE *Outfptr, @@ -198,7 +198,7 @@ int CosmoIonizationInitialize(FILE *fptr, FILE *Outfptr, #endif /* TRANSFER */ -int TurbulenceInitialize(FILE *fptr, FILE *Outfptr, +int TurbulenceInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, int SetBaryonFields); int DrivenFlowInitialize(FILE *fptr, FILE *Outfptr, @@ -215,22 +215,22 @@ int MHD1DTestWavesInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int MHD2DTestInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, int SetBaryonFields); -int MHD3DTestInitialize(FILE *fptr, FILE *Outfptr, +int MHD3DTestInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); -int CollapseMHD3DInitialize(FILE *fptr, FILE *Outfptr, +int CollapseMHD3DInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, int SetBaryonFields); -int MHDTurbulenceInitialize(FILE *fptr, FILE *Outfptr, +int MHDTurbulenceInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, int SetBaryonFields); -int MHDDecayingRandomFieldInitialize(FILE *fptr, FILE *Outfptr, +int MHDDecayingRandomFieldInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, int SetBaryonFields); -int GalaxyDiskInitialize(FILE *fptr, FILE *Outfptr, +int GalaxyDiskInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); -int AGNDiskInitialize(FILE *fptr, FILE *Outfptr, +int AGNDiskInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int FreeExpansionInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); -int PoissonSolverTestInitialize(FILE *fptr, FILE *Outfptr, +int PoissonSolverTestInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData); int MHDCT_ParameterJuggle(); //updates old style MHDCT parameter files to reflect new values @@ -241,6 +241,15 @@ int MHDOrszagTangInit(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, int MHDLoopInit(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData, ExternalBoundary &Exterior); +int TestGravityAPMInitialize(FILE *fptr, FILE *Outfptr, + HierarchyEntry &TopGrid,TopGridData &MetaData); +int TestGravitySphereAPMInitialize(FILE *fptr, FILE *Outfptr, + HierarchyEntry &TopGrid, TopGridData &MetaData); +int TestSelfForceInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, + TopGridData &MetaData); +int TestGravitySineWaveInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, + TopGridData &MetaData); + void PrintMemoryUsage(char *str); int GetUnits(float *DensityUnits, float *LengthUnits, @@ -248,32 +257,32 @@ int GetUnits(float *DensityUnits, float *LengthUnits, float *VelocityUnits, double *MassUnits, FLOAT Time); - + // Character strings - + char outfilename[] = "amr.out"; - - - - + + + + int InitializeNew(char *filename, HierarchyEntry &TopGrid, TopGridData &MetaData, ExternalBoundary &Exterior, float *Initialdt) { - - + + // Declarations - + FILE *fptr, *BCfptr, *Outfptr; int dim, i; - + // Open parameter file - + if ((fptr = fopen(filename, "r")) == NULL) { ENZO_FAIL("Error opening parameter file."); } - + // Clear OutputLog FILE *sptr; @@ -283,18 +292,18 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, } // Open output file - + if (MyProcessorNumber == ROOT_PROCESSOR) if ((Outfptr = fopen(outfilename, "w")) == NULL) { ENZO_VFAIL("Error opening parameter output file %s\n", outfilename) } - + // set the default MetaData values - + SetDefaultGlobalValues(MetaData); - + // Read the MetaData/global values from the Parameter file - + if (ReadParameterFile(fptr, MetaData, Initialdt) == FAIL) { ENZO_FAIL("Error in ReadParameterFile."); } @@ -305,7 +314,7 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, } // Set the number of particle attributes, if left unset - + if (NumberOfParticleAttributes == INT_UNDEFINED || NumberOfParticleAttributes == 0) { if (StarParticleCreation || StarParticleFeedback) { @@ -318,27 +327,27 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, } // Give unset parameters their default values - + for (dim = 0; dim < MAX_DIMENSION; dim++) { if (RefineRegionLeftEdge[dim] == FLOAT_UNDEFINED) RefineRegionLeftEdge[dim] = DomainLeftEdge[dim]; if (RefineRegionRightEdge[dim] == FLOAT_UNDEFINED) RefineRegionRightEdge[dim] = DomainRightEdge[dim]; } - + // If the problem reads in a restart dump, then skip over the following - + if (ProblemType != 40 && ProblemType != 51) { - + // Error check the rank //printf("This should only run if not a restart!"); - + if (MetaData.TopGridRank < 0 || MetaData.TopGridRank > 3) { ENZO_VFAIL("TopGridRank = %"ISYM" ill defined.\n", MetaData.TopGridRank) } - + // Error check the dimensions and at the same time add ghost zones - + for (dim = 0; dim < MetaData.TopGridRank; dim++) { if (MetaData.TopGridDims[dim] < 1 || MetaData.TopGridDims[dim] > 8192) { ENZO_VFAIL("TopGridDims[%"ISYM"] = %"ISYM" ill defined.\n", dim, @@ -347,11 +356,11 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, MetaData.TopGridDims[dim] = (MetaData.TopGridDims[dim] > 1) ? MetaData.TopGridDims[dim] + 2*NumberOfGhostZones : 1; } - + // Create the top grid, prepare it, set the time and parameters - + TopGrid.GridData = new grid; - + TopGrid.GridData->PrepareGrid(MetaData.TopGridRank, MetaData.TopGridDims, DomainLeftEdge, DomainRightEdge, MetaData.NumberOfParticles); @@ -361,69 +370,69 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, MetaData.PPMDiffusionParameter, MetaData.PPMSteepeningParameter); TopGrid.GridData->SetGravityParameters(MetaData.GravityBoundary); - + // Repair TopGridDims (subtract ghost zones added earlier) - + for (dim = 0; dim < MetaData.TopGridRank; dim++) MetaData.TopGridDims[dim] = max(MetaData.TopGridDims[dim] - 2*NumberOfGhostZones, 1); - + // Set TopGrid Hierarchy Entry - + TopGrid.NextGridThisLevel = NULL; // always true TopGrid.ParentGrid = NULL; // always true TopGrid.NextGridNextLevel = NULL; // can be reset by initializer - + } // end: if (ProblemType != 40 && ProblemType !=51) - + // Call problem initializer PrintMemoryUsage("Call problem init"); - + if (ProblemType == 0) { ENZO_FAIL("No problem specified."); } - + int ret = INT_UNDEFINED; - + if (debug) printf("InitializeNew: Starting problem initialization.\n"); - + // 1) Shocktube problem - + if (ProblemType == 1) ret = HydroShockTubesInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 2) Wave pool - + if (ProblemType == 2) ret = WavePoolInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 3) Shock pool - + if (ProblemType == 3) ret = ShockPoolInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 4) Double Mach reflection - + if (ProblemType == 4) ret = DoubleMachInitialize(fptr, Outfptr, TopGrid, MetaData, Exterior); - + // 5) ShockInABox - + if (ProblemType == 5) ret = ShockInABoxInitialize(fptr, Outfptr, TopGrid, MetaData, Exterior); - + // 6) Implosion - + if (ProblemType == 6) ret = ImplosionInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 7) SedovBlast - + if (ProblemType == 7) ret = SedovBlastInitialize(fptr, Outfptr, TopGrid, MetaData); @@ -438,19 +447,19 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, ret = NohInitialize(fptr, Outfptr, TopGrid, MetaData); // 10) RotatingCylinder - + if (ProblemType == 10) ret = RotatingCylinderInitialize(fptr, Outfptr, TopGrid, MetaData); // 11) RadiatingShock - + if (ProblemType == 11) ret = RadiatingShockInitialize(fptr, Outfptr, TopGrid, MetaData); // 12) Free expansion blast wave if (ProblemType == 12) ret = FreeExpansionInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 13) RotatingDisk if (ProblemType == 13) ret = RotatingDiskInitialize(fptr, Outfptr, TopGrid, MetaData); @@ -459,56 +468,66 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, ret = RotatingSphereInitialize(fptr, Outfptr, TopGrid, MetaData); // 20) Zeldovich Pancake - + if (ProblemType == 20) ret = ZeldovichPancakeInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 21) 1D Pressureless collapse - + if (ProblemType == 21) ret = PressurelessCollapseInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 22) Adiabatic expansion - + if (ProblemType == 22) ret = AdiabaticExpansionInitialize(fptr, Outfptr, TopGrid); - + // 23) GravityTest - + if (ProblemType == 23) ret = TestGravityInitialize(fptr, Outfptr, TopGrid, MetaData); - + + // 123) GravityTest - APM version + + if (ProblemType == 123) + ret = TestGravityAPMInitialize(fptr, Outfptr, TopGrid, MetaData); + // 24) Spherical Infall - + if (ProblemType == 24) ret = SphericalInfallInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 25) TestGravitySphere - + if (ProblemType == 25) ret = TestGravitySphereInitialize(fptr, Outfptr, TopGrid, MetaData); - + + // 125) TestGravitySphere - APM version + + if (ProblemType == 125) + ret = TestGravitySphereAPMInitialize(fptr, Outfptr, TopGrid, MetaData); + // 26) GravityEquilibriumTest - + if (ProblemType == 26) ret = GravityEquilibriumTestInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 27) CollapseTest - + if (ProblemType == 27) ret = CollapseTestInitialize(fptr, Outfptr, TopGrid, MetaData, Exterior); - + // 28) TestGravityMotion - + if (ProblemType == 28) ret = TestGravityMotion(fptr, Outfptr, TopGrid, MetaData); // 29) TestOrbit if (ProblemType == 29) ret = TestOrbitInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 30) Cosmology Simulation - + if (ProblemType == 30) { if (PartitionNestedGrids || QuantumPressure) { ret = NestedCosmologySimulationInitialize(fptr, Outfptr, TopGrid, MetaData); @@ -516,26 +535,37 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, ret = CosmologySimulationInitialize(fptr, Outfptr, TopGrid, MetaData); } } - + // 31) GalaxySimulation if (ProblemType == 31) ret = GalaxySimulationInitialize(fptr, Outfptr, TopGrid, MetaData,Exterior); // 35) Shearing Box Simulation - if (ProblemType == 35) + if (ProblemType == 35) ret = ShearingBoxInitialize(fptr, Outfptr, TopGrid, MetaData); - if (ProblemType == 36) + if (ProblemType == 36) ret = ShearingBox2DInitialize(fptr, Outfptr, TopGrid, MetaData); - if (ProblemType == 37) + if (ProblemType == 37) ret = ShearingBoxStratifiedInitialize(fptr, Outfptr, TopGrid, MetaData); - - + + // 40) Supernova Explosion from restart - + if (ProblemType == 40) ret = SupernovaRestartInitialize(fptr, Outfptr, TopGrid, MetaData, Exterior); - + + // 44) TestGravitySineWave + + if (ProblemType == 44) + ret = TestGravitySineWaveInitialize(fptr, Outfptr, TopGrid, MetaData); + + // 47) TestSelfforce on particle + + if (ProblemType == 47) + ret = TestSelfForceInitialize(fptr, Outfptr, TopGrid, MetaData); + + // 50) Photon Test #ifdef TRANSFER @@ -555,14 +585,14 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, ret = DrivenFlowInitialize(fptr, Outfptr, TopGrid, MetaData,0); // 60) Turbulence Simulation. - + if (ProblemType == 60) ret = TurbulenceSimulationInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 61) Protostellar Collapse if (ProblemType == 61) ret = ProtostellarCollapseInitialize(fptr, Outfptr, TopGrid, MetaData); - + // 62) Cooling test problem if (ProblemType == 62) ret = CoolingTestInitialize(fptr, Outfptr, TopGrid, MetaData); @@ -582,22 +612,22 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, // 73) Conducting cloud test problem if (ProblemType == 73) - ret = ConductionCloudInitialize(fptr, Outfptr, TopGrid, MetaData); + ret = ConductionCloudInitialize(fptr, Outfptr, TopGrid, MetaData); // 80) Explosion in a stratified medium if (ProblemType == 80) - ret = StratifiedMediumExplosionInitialize(fptr, Outfptr, TopGrid, MetaData); + ret = StratifiedMediumExplosionInitialize(fptr, Outfptr, TopGrid, MetaData); // 90) Test a star particle explosion if (ProblemType == 90) - ret = TestStarParticleInitialize(fptr, Outfptr, TopGrid, MetaData, + ret = TestStarParticleInitialize(fptr, Outfptr, TopGrid, MetaData, Initialdt); - + /* 101) 3D Collapse */ if (ProblemType == 101) { ret = Collapse3DInitialize(fptr, Outfptr, TopGrid, MetaData); } - + /* 102) 1D Spherical Collapse */ if (ProblemType == 102) { ret = Collapse1DInitialize(fptr, Outfptr, TopGrid, MetaData); @@ -606,20 +636,20 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, /* 103) MHD Orszag-Tang vortex */ if (ProblemType == 103) //This doesn't actually need all those arguments ret = MHDOrszagTangInit(fptr, Outfptr, TopGrid, MetaData, Exterior); - if (ProblemType == 104) + if (ProblemType == 104) ret = MHDLoopInit(fptr, Outfptr, TopGrid, MetaData, Exterior); - + /* 106) Hydro and MHD Turbulence problems/Star Formation */ if (ProblemType == 106) { ret = TurbulenceInitialize(fptr, Outfptr, TopGrid, MetaData, 0); } - + // 107) Put Sink from restart - + if (ProblemType == 107) ret = PutSinkRestartInitialize(fptr, Outfptr, TopGrid, MetaData, Exterior); - + // 108) Cluster cooling flow if (ProblemType == 108) { ret = ClusterInitialize(fptr, Outfptr, TopGrid, MetaData, Exterior); @@ -754,17 +784,17 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, // Insert new problem intializer here... - + if (ret == INT_UNDEFINED) { ENZO_VFAIL("Problem Type %"ISYM" undefined.\n", ProblemType) } - + if (ret == FAIL) { ENZO_FAIL("Error in problem initialization."); } - + /* Do some error checking */ - + if (MetaData.StopTime == FLOAT_UNDEFINED && MetaData.StopCycle == INT_UNDEFINED) ENZO_FAIL("StopTime nor StopCycle ever set."); if (MetaData.StopCycle != INT_UNDEFINED && MetaData.StopTime == FLOAT_UNDEFINED) @@ -773,7 +803,7 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, int nFields = TopGrid.GridData->ReturnNumberOfBaryonFields(); if (nFields >= MAX_NUMBER_OF_BARYON_FIELDS) { ENZO_VFAIL("NumberOfBaryonFields (%"ISYM") + 1 exceeds " - "MAX_NUMBER_OF_BARYON_FIELDS (%"ISYM").\n", + "MAX_NUMBER_OF_BARYON_FIELDS (%"ISYM").\n", nFields, MAX_NUMBER_OF_BARYON_FIELDS) } @@ -782,40 +812,40 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, if (debug) printf("Initialize Exterior\n"); - + // Initialize the exterior (unless it was set in the problem initializer) - + if (Exterior.AmIPrepared() == FALSE) { - + Exterior.Prepare(TopGrid.GridData); // set rank and dims - + if (MetaData.BoundaryConditionName != NULL) { - + if ((BCfptr = fopen(MetaData.BoundaryConditionName, "r")) == NULL) { ENZO_VFAIL("Error opening BC file: %s\n", MetaData.BoundaryConditionName) } - + fprintf(stderr, "Opened BC file mode r\n"); if (Exterior.ReadExternalBoundary(BCfptr) == FAIL) { ENZO_FAIL("Error in ReadExternalBoundary."); } fclose(BCfptr); - } else + } else { - if (debug) + if (debug) fprintf(stderr, "InitializeExternalBoundaryFace\n"); - + SimpleConstantBoundary = TRUE; - + for (dim = 0; dim < MetaData.TopGridRank; dim++) { if (MetaData.LeftFaceBoundaryCondition[dim] != periodic || MetaData.RightFaceBoundaryCondition[dim] != periodic) { SimpleConstantBoundary = FALSE; } } - + if (debug) { if (SimpleConstantBoundary) { fprintf(stderr, "SimpleConstantBoundary TRUE\n"); @@ -826,8 +856,8 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, float Dummy[TopGrid.GridData->ReturnNumberOfBaryonFields()]; for ( - int fieldIndex = 0; - fieldIndex < TopGrid.GridData->ReturnNumberOfBaryonFields(); + int fieldIndex = 0; + fieldIndex < TopGrid.GridData->ReturnNumberOfBaryonFields(); fieldIndex++ ) { Dummy[fieldIndex] = 0.0; @@ -840,45 +870,45 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, == FAIL) { ENZO_FAIL("Error in InitializeExternalBoundaryFace."); } - + // Initialize particle boundary conditions - + Exterior.InitializeExternalBoundaryParticles( MetaData.ParticleBoundaryType); - + } // end: if (MetaData.BoundaryConditionName != NULL) - + } // end of set Exterior - - + + PrintMemoryUsage("Exterior set"); - + if (debug) { fprintf(stderr, "End of set exterior\n"); } - + // Set values that were left undefined (above) - + if (MetaData.TimeLastDataDump == FLOAT_UNDEFINED) MetaData.TimeLastDataDump = MetaData.Time - MetaData.dtDataDump*1.00001; if (MetaData.TimeLastHistoryDump == FLOAT_UNDEFINED) MetaData.TimeLastHistoryDump = MetaData.Time - MetaData.dtHistoryDump; - + if (MetaData.TimeLastTracerParticleDump == FLOAT_UNDEFINED) MetaData.TimeLastTracerParticleDump = MetaData.Time - MetaData.dtTracerParticleDump; - + if (MetaData.CycleLastDataDump == INT_UNDEFINED) MetaData.CycleLastDataDump = MetaData.CycleNumber - MetaData.CycleSkipDataDump; if (MetaData.CycleLastHistoryDump == INT_UNDEFINED) MetaData.CycleLastHistoryDump = MetaData.CycleNumber - MetaData.CycleSkipHistoryDump; - + // Make changes required for Zeus solver, and turn the TotalEnergy // variable (should be renamed just Energy) into GasEnergy - + if (HydroMethod == Zeus_Hydro && ProblemType != 10 && // BWO (Rotating cylinder) ProblemType != 11 && // BWO (radiating shock) @@ -891,16 +921,16 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, ProblemType != 106 && //AK ProblemType != 108) //Yuan (Cluster) ConvertTotalEnergyToGasEnergy(&TopGrid); - - // If using StarParticles, set the number to zero + + // If using StarParticles, set the number to zero // (assuming it hasn't already been set) if (NumberOfStarParticles != 0) if (StarParticleCreation || StarParticleFeedback) NumberOfStarParticles = 0; - + // Convert minimum initial overdensity for refinement to mass // (unless MinimumMass itself was actually set) - + for (i = 0; i < MAX_FLAGGING_METHODS; i++) if (MinimumMassForRefinement[i] == FLOAT_UNDEFINED) { MinimumMassForRefinement[i] = MinimumOverDensityForRefinement[i]; @@ -909,55 +939,55 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, (DomainRightEdge[dim]-DomainLeftEdge[dim])/ float(MetaData.TopGridDims[dim]); } - + // Check for the creation of tracer particles // Tracer particles will not be created at this point if ||rgio in ON - + if (TracerParticleCreation(fptr, TopGrid, MetaData) == FAIL) { ENZO_FAIL("Error in TracerParticleCreation"); } - + // Write the MetaData/global values to the Parameter file - + if (MyProcessorNumber == ROOT_PROCESSOR) if (WriteParameterFile(Outfptr, MetaData) == FAIL) { ENZO_FAIL("Error in WriteParameterFile."); } - + if (debug) printf("InitializeNew: Initial grid hierarchy set\n"); - + // Walk the grids - + HierarchyEntry *CurrentGrid; FLOAT WT = -1.0; int GP = 1; int gridcounter = 0; - + CurrentGrid = &TopGrid; - + while (CurrentGrid != NULL) { - + if (debug) printf("InitializeNew: Partition Initial Grid %"ISYM"\n", gridcounter); - - if (CurrentGrid->NextGridThisLevel == NULL) + + if (CurrentGrid->NextGridThisLevel == NULL) CommunicationPartitionGrid(CurrentGrid, gridcounter); - + gridcounter++; - + if (PartitionNestedGrids) CurrentGrid = CurrentGrid->NextGridNextLevel; else CurrentGrid = NULL; - + } - + // For problem 30, using ParallelGridIO, // read in data only after partitioning the grid - + if (debug) if (ParallelRootGridIO == TRUE && ProblemType == 30) { if (PartitionNestedGrids) { @@ -966,9 +996,9 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, printf("InitializeNew: Re-initialize CosmologySimulation\n"); } } - + PrintMemoryUsage("Before 2nd pass"); - + if (ParallelRootGridIO == TRUE && ProblemType == 30) { if (PartitionNestedGrids) { if (NestedCosmologySimulationReInitialize(&TopGrid, MetaData) == FAIL) { @@ -980,11 +1010,11 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, } } } - + // For PhotonTest, using ParallelGridIO, initialize data only after // partitioning grid. Last argument tells it it's the 2nd pass. -#ifdef TRANSFER +#ifdef TRANSFER if (ParallelRootGridIO == TRUE && ProblemType == 50) if (PhotonTestInitialize(fptr, Outfptr, TopGrid, MetaData, true) == FAIL) ENZO_FAIL("Error in PhotonTestInitialize(2nd pass)."); @@ -995,14 +1025,14 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, if (ProblemType == 59) if (DrivenFlowInitialize(fptr, Outfptr, TopGrid, MetaData, 1) == FAIL) ENZO_FAIL("Error in DrivenFlowInitialize with SetBaryons"); - + // For problem 60, using ParallelGridIO, read in data only after // partitioning grid. - + if (ParallelRootGridIO == TRUE && ProblemType == 60) if (TurbulenceSimulationReInitialize(&TopGrid, MetaData) == FAIL) ENZO_FAIL("Error in TurbulenceSimulationReInitialize."); - + if (ProblemType == 106){ if (TurbulenceInitialize(fptr, Outfptr, TopGrid, MetaData, 1) == FAIL) { @@ -1016,8 +1046,8 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, == FAIL) { ENZO_FAIL("Error in MHD2DTestReInitialize.\n"); } - - + + if (ProblemType == 202) CollapseMHD3DInitialize(fptr, Outfptr, TopGrid, MetaData, 1); @@ -1028,7 +1058,7 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, == FAIL) { ENZO_FAIL("Error in MHDTurbulenceReInitialize.\n"); } - + // initialize the data once the topgrid has been split. if (ProblemType == 210) if (MHDDecayingRandomFieldInitialize(fptr, Outfptr, TopGrid, MetaData, 1) @@ -1037,11 +1067,11 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, } CommunicationBarrier(); - + // Close parameter files - + fclose(fptr); - + if (MyProcessorNumber == ROOT_PROCESSOR) fclose(Outfptr); @@ -1051,25 +1081,25 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, // Added the following line: CommunicationBroadcastValue(&MetaData.NumberOfParticles, ROOT_PROCESSOR); - + MetaData.FirstTimestepAfterRestart = FALSE; - + if (debug) printf("InitializeNew: Finished problem initialization.\n"); /* If requested, initialize streaming data files. */ InitializeMovieFile(MetaData, TopGrid); - + return SUCCESS; - + } - - - - + + + + void ConvertTotalEnergyToGasEnergy(HierarchyEntry *Grid) { if (Grid != NULL) { diff --git a/src/enzo/InterpolatePositionsTSC1d.C b/src/enzo/InterpolatePositionsTSC1d.C new file mode 100644 index 000000000..b57349599 --- /dev/null +++ b/src/enzo/InterpolatePositionsTSC1d.C @@ -0,0 +1,120 @@ +/*********************************************************************** +/ +/ INTERPOLATE FIELD TO 1D TSC 'PARTICLES' (EITHER PERIODIC OR 'PILE-UP') +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "macros_and_parameters.h" +#include "typedefs.h" + +/* Periodic version. */ + +void InterpolatePositionsPeriodicTSC1D(FLOAT *Position[], int Number, + float *SumField, + float *Field, FLOAT LeftEdge[], + int Dimension[], FLOAT CellSize) +{ + int i0, i0p, i0m, n; + float dx, wx0, wxm, wxp, xpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + i0 = int(xpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + /* wrap central index */ + + if (i0 < 0) i0 += Dimension[0]; + if (i0 >= Dimension[0]) i0 -= Dimension[0]; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + + /* wrap indexes */ + + if (i0m < 0) i0m += Dimension[0]; + if (i0p >= Dimension[0]) i0p -= Dimension[0]; + + /* interpolate from Field to SumField */ + + *(SumField + n) += wxm*(*(Field + i0m)) + + wx0*(*(Field + i0 )) + + wxp*(*(Field + i0p)); + + } // next particle + +} + + +/* Particles which extend past the edge of the grid are deposit at the + edge in this version, causing mass to pile-up. */ + +void InterpolatePositionsPileUpTSC1D(FLOAT *Position[], int Number, + float *SumField, + float *Field, FLOAT LeftEdge[], + int EffectiveDim[], FLOAT CellSize) +{ + int i0, i0p, i0m, n; + float dx, wx0, wxm, wxp, xpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + i0 = int(xpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + /* fix off-edge central index */ + + if (i0 < 0) i0 = 0; + if (i0 >= EffectiveDim[0]) i0 = EffectiveDim[0]-1; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + + /* fix off-edge indexes */ + + if (i0m < 0) i0m = 0; + if (i0p >= EffectiveDim[0]) i0p = EffectiveDim[0]-1; + + /* interpolate from Field to SumField */ + + *(SumField + n) += wxm*(*(Field + i0m)) + + wx0*(*(Field + i0 )) + + wxp*(*(Field + i0p)); + + } // next particle + +} diff --git a/src/enzo/InterpolatePositionsTSC2d.C b/src/enzo/InterpolatePositionsTSC2d.C new file mode 100644 index 000000000..017340452 --- /dev/null +++ b/src/enzo/InterpolatePositionsTSC2d.C @@ -0,0 +1,158 @@ +/*********************************************************************** +/ +/ INTERPOLATE FIELD TO 2D TSC 'PARTICLES' (EITHER PERIODIC OR 'PILE-UP') +/ +/ written by: Greg Bryan +/ date: May, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "macros_and_parameters.h" + +/* Periodic version. */ + +void InterpolatePositionsPeriodicTSC2D(FLOAT *Position[], int Number, + float *SumField, + float *Field, FLOAT LeftEdge[], + int Dimension[], FLOAT CellSize) +{ + int i0, i0p, i0m, j0, j0p, j0m, n; + float dx, dy, wx0, wxm, wxp, wy0, wym, wyp, xpos, ypos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + ypos = ( (*(Position[1] + n)) - LeftEdge[1] ) / CellSize; + i0 = int(xpos); + j0 = int(ypos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + /* wrap central index */ + + if (i0 < 0) i0 += Dimension[0]; + if (j0 < 0) j0 += Dimension[1]; + if (i0 >= Dimension[0]) i0 -= Dimension[0]; + if (j0 >= Dimension[1]) j0 -= Dimension[1]; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + + /* wrap indexes */ + + if (i0m < 0) i0m += Dimension[0]; + if (j0m < 0) j0m += Dimension[1]; + if (i0p >= Dimension[0]) i0p -= Dimension[0]; + if (j0p >= Dimension[1]) j0p -= Dimension[1]; + + /* interpolate from Field to SumField */ + + *(SumField + n) += wym*wxm*(*(Field + j0m*Dimension[0] + i0m)) + + wym*wx0*(*(Field + j0m*Dimension[0] + i0 )) + + wym*wxp*(*(Field + j0m*Dimension[0] + i0p)) + + wy0*wxm*(*(Field + j0 *Dimension[0] + i0m)) + + wy0*wx0*(*(Field + j0 *Dimension[0] + i0 )) + + wy0*wxp*(*(Field + j0 *Dimension[0] + i0p)) + + wyp*wxm*(*(Field + j0p*Dimension[0] + i0m)) + + wyp*wx0*(*(Field + j0p*Dimension[0] + i0 )) + + wyp*wxp*(*(Field + j0p*Dimension[0] + i0p)); + + } // next particle + +} + + +/* Particles which extend past the edge of the grid are deposit at the + edge in this version, causing mass to pile-up. */ + +void InterpolatePositionsPileUpTSC2D(FLOAT *Position[], int Number, + float *SumField, + float *Field, FLOAT LeftEdge[], + int EffectiveDim[], int Dimension[], + FLOAT CellSize) +{ + int i0, i0p, i0m, j0, j0p, j0m, n; + float dx, dy, wx0, wxm, wxp, wy0, wym, wyp, xpos, ypos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + ypos = ( (*(Position[1] + n)) - LeftEdge[1] ) / CellSize; + i0 = int(xpos); + j0 = int(ypos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + /* fix off-edge central index */ + + if (i0 < 0) i0 = 0; + if (j0 < 0) j0 = 0; + if (i0 >= EffectiveDim[0]) i0 = EffectiveDim[0]-1; + if (j0 >= EffectiveDim[1]) j0 = EffectiveDim[1]-1; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + + /* fix off-edge indexes */ + + if (i0m < 0) i0m = 0; + if (j0m < 0) j0m = 0; + if (i0p >= EffectiveDim[0]) i0p = EffectiveDim[0]-1; + if (j0p >= EffectiveDim[1]) j0p = EffectiveDim[1]-1; + + /* interpolate from Field to SumField */ + + *(SumField + n) += wym*wxm*(*(Field + j0m*Dimension[0] + i0m)) + + wym*wx0*(*(Field + j0m*Dimension[0] + i0 )) + + wym*wxp*(*(Field + j0m*Dimension[0] + i0p)) + + wy0*wxm*(*(Field + j0 *Dimension[0] + i0m)) + + wy0*wx0*(*(Field + j0 *Dimension[0] + i0 )) + + wy0*wxp*(*(Field + j0 *Dimension[0] + i0p)) + + wyp*wxm*(*(Field + j0p*Dimension[0] + i0m)) + + wyp*wx0*(*(Field + j0p*Dimension[0] + i0 )) + + wyp*wxp*(*(Field + j0p*Dimension[0] + i0p)); + + } // next particle + +} diff --git a/src/enzo/InterpolatePositionsTSC3d.C b/src/enzo/InterpolatePositionsTSC3d.C new file mode 100644 index 000000000..6578e1442 --- /dev/null +++ b/src/enzo/InterpolatePositionsTSC3d.C @@ -0,0 +1,289 @@ +/*********************************************************************** +/ +/ INTERPOLATE FIELD TO 3D TSC 'PARTICLES' (EITHER PERIODIC OR 'PILE-UP') +/ +/ written by: Greg Bryan +/ date: May, 1995 +/ modified1: +/ +/ PURPOSE: +/ +/ NOTE: +/ +************************************************************************/ + +#include +#include +#include "macros_and_parameters.h" + +/* Use FORTRAN or C++ version? */ + +#define NO_USE_FORTRAN + +/* External defines. */ + +#ifdef USE_FORTRAN +extern "C" void FORTRAN_NAME(tsc3d_period)( + float *posx, float *posy, float *posz, + int *npositions, float *sumfield, + float *field, float leftedge[], + int *dim1, int *dim2, int *dim3, + float *cellsize); +extern "C" void FORTRAN_NAME(tsc3d_pile)(float *posx, float *posy, float *posz, + int *npositions, float *sumfield, + float *field, float leftedge[], + int *edim1, int *edim2, int *edim3, + int *dim1, int *dim2, int *dim3, + float *cellsize); +#endif /* USE_FORTRAN */ + +/* Periodic version. */ + +void InterpolatePositionsPeriodicTSC3D(FLOAT *Position[], int Number, + float *SumField, + float *Field, FLOAT LeftEdge[], + int Dimension[], FLOAT CellSize) +{ + +#ifdef USE_FORTRAN + +/* Call FORTRAN routine to do all the hard work. */ + +FORTRAN_NAME(tsc3d_period)(Position[0], Position[1], Position[2], + &Number, SumField, Field, LeftEdge, + &Dimension[0], &Dimension[1], &Dimension[2], + &CellSize); + +#else /* USE_FORTRAN */ + + int dim12, i0, i0p, i0m, j0, j0p, j0m, k0, k0p, k0m, n; + float dx, dy, dz, wx0, wxm, wxp, wy0, wym, wyp, wz0, wzm, wzp, + xpos, ypos, zpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + ypos = ( (*(Position[1] + n)) - LeftEdge[1] ) / CellSize; + zpos = ( (*(Position[2] + n)) - LeftEdge[2] ) / CellSize; + + i0 = int(xpos); + j0 = int(ypos); + k0 = int(zpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + dz = zpos - float(k0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + wzm = 0.5*(0.5 - dz)*(0.5 - dz); + wzp = dz + wzm; + wz0 = 1.0 - wzp - wzm; + + /* wrap central index */ + + if (i0 < 0) i0 += Dimension[0]; + if (j0 < 0) j0 += Dimension[1]; + if (k0 < 0) k0 += Dimension[2]; + + if (i0 >= Dimension[0]) i0 -= Dimension[0]; + if (j0 >= Dimension[1]) j0 -= Dimension[1]; + if (k0 >= Dimension[2]) k0 -= Dimension[2]; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + k0m = k0 - 1; + k0p = k0 + 1; + + /* wrap indexes */ + + if (i0m < 0) i0m += Dimension[0]; + if (j0m < 0) j0m += Dimension[1]; + if (k0m < 0) k0m += Dimension[2]; + if (i0p >= Dimension[0]) i0p -= Dimension[0]; + if (j0p >= Dimension[1]) j0p -= Dimension[1]; + if (k0p >= Dimension[2]) k0p -= Dimension[2]; + + /* interpolate from Field to SumField */ + + dim12 = Dimension[0]*Dimension[1]; + + *(SumField + n) += + wzm*wym*wxm*(*(Field + k0m*dim12 + j0m*Dimension[0] + i0m)) + + wzm*wym*wx0*(*(Field + k0m*dim12 + j0m*Dimension[0] + i0 )) + + wzm*wym*wxp*(*(Field + k0m*dim12 + j0m*Dimension[0] + i0p)) + + wzm*wy0*wxm*(*(Field + k0m*dim12 + j0 *Dimension[0] + i0m)) + + wzm*wy0*wx0*(*(Field + k0m*dim12 + j0 *Dimension[0] + i0 )) + + wzm*wy0*wxp*(*(Field + k0m*dim12 + j0 *Dimension[0] + i0p)) + + wzm*wyp*wxm*(*(Field + k0m*dim12 + j0p*Dimension[0] + i0m)) + + wzm*wyp*wx0*(*(Field + k0m*dim12 + j0p*Dimension[0] + i0 )) + + wzm*wyp*wxp*(*(Field + k0m*dim12 + j0p*Dimension[0] + i0p)); + + *(SumField + n) += + wz0*wym*wxm*(*(Field + k0 *dim12 + j0m*Dimension[0] + i0m)) + + wz0*wym*wx0*(*(Field + k0 *dim12 + j0m*Dimension[0] + i0 )) + + wz0*wym*wxp*(*(Field + k0 *dim12 + j0m*Dimension[0] + i0p)) + + wz0*wy0*wxm*(*(Field + k0 *dim12 + j0 *Dimension[0] + i0m)) + + wz0*wy0*wx0*(*(Field + k0 *dim12 + j0 *Dimension[0] + i0 )) + + wz0*wy0*wxp*(*(Field + k0 *dim12 + j0 *Dimension[0] + i0p)) + + wz0*wyp*wxm*(*(Field + k0 *dim12 + j0p*Dimension[0] + i0m)) + + wz0*wyp*wx0*(*(Field + k0 *dim12 + j0p*Dimension[0] + i0 )) + + wz0*wyp*wxp*(*(Field + k0 *dim12 + j0p*Dimension[0] + i0p)); + + *(SumField + n) += + wzp*wym*wxm*(*(Field + k0p*dim12 + j0m*Dimension[0] + i0m)) + + wzp*wym*wx0*(*(Field + k0p*dim12 + j0m*Dimension[0] + i0 )) + + wzp*wym*wxp*(*(Field + k0p*dim12 + j0m*Dimension[0] + i0p)) + + wzp*wy0*wxm*(*(Field + k0p*dim12 + j0 *Dimension[0] + i0m)) + + wzp*wy0*wx0*(*(Field + k0p*dim12 + j0 *Dimension[0] + i0 )) + + wzp*wy0*wxp*(*(Field + k0p*dim12 + j0 *Dimension[0] + i0p)) + + wzp*wyp*wxm*(*(Field + k0p*dim12 + j0p*Dimension[0] + i0m)) + + wzp*wyp*wx0*(*(Field + k0p*dim12 + j0p*Dimension[0] + i0 )) + + wzp*wyp*wxp*(*(Field + k0p*dim12 + j0p*Dimension[0] + i0p)); + + } // next particle + +#endif /* USE_FORTRAN */ + +} + + +/* Particles which extend past the edge of the grid are deposit at the + edge in this version, causing mass to pile-up. */ + +void InterpolatePositionsPileUpTSC3D(FLOAT *Position[], int Number, + float *SumField, + float *Field, FLOAT LeftEdge[], + int EffectiveDim[], int Dimension[], + FLOAT CellSize) +{ + +#ifdef USE_FORTRAN + +/* Call FORTRAN routine to do all the hard work. */ + +FORTRAN_NAME(tsc3d_pile)(Position[0], Position[1], Position[2], + &Number, SumField, Field, LeftEdge, + &EffectiveDim[0], &EffectiveDim[1], &EffectiveDim[2], + &Dimension[0], &Dimension[1], &Dimension[2], + &CellSize); + +#else /* USE_FORTRAN */ + + int dim12, i0, i0p, i0m, j0, j0p, j0m, k0, k0p, k0m, n; + float dx, dy, dz, wx0, wxm, wxp, wy0, wym, wyp, wz0, wzm, wzp, + xpos, ypos, zpos; + + for (n = 0; n < Number; n++) { + + /* compute index of central cell */ + + xpos = ( (*(Position[0] + n)) - LeftEdge[0] ) / CellSize; + ypos = ( (*(Position[1] + n)) - LeftEdge[1] ) / CellSize; + zpos = ( (*(Position[2] + n)) - LeftEdge[2] ) / CellSize; + + i0 = int(xpos); + j0 = int(ypos); + k0 = int(zpos); + + /* compute the weights */ + + dx = xpos - float(i0) - 0.5; + dy = ypos - float(j0) - 0.5; + dz = zpos - float(k0) - 0.5; + + wxm = 0.5*(0.5 - dx)*(0.5 - dx); + wxp = dx + wxm; + wx0 = 1.0 - wxp - wxm; + + wym = 0.5*(0.5 - dy)*(0.5 - dy); + wyp = dy + wym; + wy0 = 1.0 - wyp - wym; + + wzm = 0.5*(0.5 - dz)*(0.5 - dz); + wzp = dz + wzm; + wz0 = 1.0 - wzp - wzm; + + /* fix off-edge central index */ + + if (i0 < 0) i0 = 0; + if (j0 < 0) j0 = 0; + if (k0 < 0) k0 = 0; + if (i0 >= EffectiveDim[0]) i0 = EffectiveDim[0]-1; + if (j0 >= EffectiveDim[1]) j0 = EffectiveDim[1]-1; + if (k0 >= EffectiveDim[2]) k0 = EffectiveDim[2]-1; + + /* determine offsets */ + + i0m = i0 - 1; + i0p = i0 + 1; + j0m = j0 - 1; + j0p = j0 + 1; + k0m = k0 - 1; + k0p = k0 + 1; + + /* fix off-edge indexes */ + + if (i0m < 0) i0m = 0; + if (j0m < 0) j0m = 0; + if (k0m < 0) k0m = 0; + if (i0p >= EffectiveDim[0]) i0p = EffectiveDim[0]-1; + if (j0p >= EffectiveDim[1]) j0p = EffectiveDim[1]-1; + if (k0p >= EffectiveDim[2]) k0p = EffectiveDim[2]-1; + + dim12 = Dimension[0]*Dimension[1]; + + /* Interpolate from field. This is split to improve performance. */ + + *(SumField + n) += + wzm*wym*wxm*(*(Field + k0m*dim12 + j0m*Dimension[0] + i0m)) + + wzm*wym*wx0*(*(Field + k0m*dim12 + j0m*Dimension[0] + i0 )) + + wzm*wym*wxp*(*(Field + k0m*dim12 + j0m*Dimension[0] + i0p)) + + wzm*wy0*wxm*(*(Field + k0m*dim12 + j0 *Dimension[0] + i0m)) + + wzm*wy0*wx0*(*(Field + k0m*dim12 + j0 *Dimension[0] + i0 )) + + wzm*wy0*wxp*(*(Field + k0m*dim12 + j0 *Dimension[0] + i0p)) + + wzm*wyp*wxm*(*(Field + k0m*dim12 + j0p*Dimension[0] + i0m)) + + wzm*wyp*wx0*(*(Field + k0m*dim12 + j0p*Dimension[0] + i0 )) + + wzm*wyp*wxp*(*(Field + k0m*dim12 + j0p*Dimension[0] + i0p)); + + *(SumField + n) += + wz0*wym*wxm*(*(Field + k0 *dim12 + j0m*Dimension[0] + i0m)) + + wz0*wym*wx0*(*(Field + k0 *dim12 + j0m*Dimension[0] + i0 )) + + wz0*wym*wxp*(*(Field + k0 *dim12 + j0m*Dimension[0] + i0p)) + + wz0*wy0*wxm*(*(Field + k0 *dim12 + j0 *Dimension[0] + i0m)) + + wz0*wy0*wx0*(*(Field + k0 *dim12 + j0 *Dimension[0] + i0 )) + + wz0*wy0*wxp*(*(Field + k0 *dim12 + j0 *Dimension[0] + i0p)) + + wz0*wyp*wxm*(*(Field + k0 *dim12 + j0p*Dimension[0] + i0m)) + + wz0*wyp*wx0*(*(Field + k0 *dim12 + j0p*Dimension[0] + i0 )) + + wz0*wyp*wxp*(*(Field + k0 *dim12 + j0p*Dimension[0] + i0p)); + + *(SumField + n) += + wzp*wym*wxm*(*(Field + k0p*dim12 + j0m*Dimension[0] + i0m)) + + wzp*wym*wx0*(*(Field + k0p*dim12 + j0m*Dimension[0] + i0 )) + + wzp*wym*wxp*(*(Field + k0p*dim12 + j0m*Dimension[0] + i0p)) + + wzp*wy0*wxm*(*(Field + k0p*dim12 + j0 *Dimension[0] + i0m)) + + wzp*wy0*wx0*(*(Field + k0p*dim12 + j0 *Dimension[0] + i0 )) + + wzp*wy0*wxp*(*(Field + k0p*dim12 + j0 *Dimension[0] + i0p)) + + wzp*wyp*wxm*(*(Field + k0p*dim12 + j0p*Dimension[0] + i0m)) + + wzp*wyp*wx0*(*(Field + k0p*dim12 + j0p*Dimension[0] + i0 )) + + wzp*wyp*wxp*(*(Field + k0p*dim12 + j0p*Dimension[0] + i0p)); + + } // next particle + +#endif /* USE_FORTRAN */ + +} diff --git a/src/enzo/Make.config.objects b/src/enzo/Make.config.objects index 8c12f89a2..971f06236 100644 --- a/src/enzo/Make.config.objects +++ b/src/enzo/Make.config.objects @@ -122,10 +122,11 @@ OBJS_CONFIG_LIB = \ ConductionTestInitialize.o \ ConvertParticles2ActiveParticles.o \ comp_accel.o \ + ComputeAccelerationFieldAPMGravity.o \ ComputePotentialFieldLevelZero.o \ ComputeRandomForcingNormalization.o \ ComputeTable.o \ - ConstructFeedbackZone.o \ + ConstructFeedbackZone.o \ Continue.o \ cool1d_cloudy.o \ cool1d_koyama.o\ @@ -164,6 +165,9 @@ OBJS_CONFIG_LIB = \ DepositBaryons.o \ DepositParticleMassField.o \ DepositParticleMassFlaggingField.o \ + DepositPositionsTSC1d.o \ + DepositPositionsTSC2d.o \ + DepositPositionsTSC3d.o \ DetermineNumberOfNodes.o \ DetermineParallelism.o \ DetermineSubgridSizeExtrema.o \ @@ -226,7 +230,7 @@ OBJS_CONFIG_LIB = \ flux_hll.o \ flux_hllc.o \ flux_twoshock.o \ - FofLib.o \ + FofLib.o \ FOF.o \ FOF_allocate.o \ FOF_cmpfunc.o \ @@ -334,6 +338,7 @@ OBJS_CONFIG_LIB = \ GrackleReadParameters.o \ GrackleWriteParameters.o \ GravityEquilibriumTestInitialize.o \ + GreensFunction.o \ Grid_AccelerationBoundaryRoutines.o \ Grid_AccessBaryonFields.o \ Grid_AccreteOntoAccretingParticle.o \ @@ -351,6 +356,8 @@ OBJS_CONFIG_LIB = \ Grid_AddOneParticleFromList.o \ Grid_AddOverlappingParticleMassField.o \ Grid_AddParticlesFromList.o \ + Grid_AddParentAccelerationFieldAPM.o \ + Grid_AddParentPotentialFieldAPM.o \ Grid_AddRandomForcing.o \ Grid_AddToBoundaryFluxes.o \ Grid_AllocateGrids.o \ @@ -404,6 +411,7 @@ OBJS_CONFIG_LIB = \ Grid_ComovingGravitySourceTerm.o \ Grid_ComputeAccelerationFieldExternal.o \ Grid_ComputeAccelerationField.o \ + Grid_ComputeAccelerationFieldAPM.o \ Grid_ComputeAccelerations.o \ Grid_ComputeAccelerationsFromExternalPotential.o \ Grid_ComputeAnisotropicCRDiffusion.o \ @@ -424,6 +432,7 @@ OBJS_CONFIG_LIB = \ Grid_ComputeLuminosity.o \ Grid_ComputeMetalLineLuminosity.o \ Grid_ComputeOneZoneCollapseFactor.o \ + Grid_ComputePotentialFieldAPM.o \ Grid_ComputePressure.o \ Grid_ComputeRandomForcingFields.o\ Grid_ComputeTemperatureField.o \ @@ -568,7 +577,9 @@ OBJS_CONFIG_LIB = \ Grid_OldStarFeedback.o \ Grid_AddStellarWind.o \ Grid_OneZoneFreefallTestInitializeGrid.o \ - Grid_OutputAsParticleData.o \ + Grid_OutputAccelerationField.o \ + Grid_OutputAsParticleData.o \ + Grid_OutputGravitatingMassField.o \ Grid_OutputStarParticleInformation.o \ Grid_ParticleSplitter.o \ Grid_PoissonSolver.o \ @@ -577,7 +588,6 @@ OBJS_CONFIG_LIB = \ Grid_PrepareBoundaryFluxes.o \ Grid_PrepareBoundaryMassFluxFieldNumbers.o \ Grid_PrepareFFT.o \ - Grid_PrepareGreensFunction.o \ Grid_PrepareGridDerivedQuantities.o \ Grid_PrepareGrid.o \ Grid_PreparePeriodicGreensFunction.o \ @@ -634,7 +644,7 @@ OBJS_CONFIG_LIB = \ Grid_SolveForPotential.o \ Grid_SolveHydroEquations.o \ Grid_SolveOneZoneFreefall.o \ - Grid_SolveMHD_Li.o \ + Grid_SolveMHD_Li.o \ Grid_SolvePPM_DE.o \ Grid_SolveRadiativeCooling.o \ Grid_SolveRateAndCoolEquations.o \ @@ -648,12 +658,17 @@ OBJS_CONFIG_LIB = \ Grid_StratifiedMediumExplosionInitialize.o \ Grid_SupernovaRestartInitialize.o \ Grid_SubtractAccretedMassFromSphere.o \ + Grid_TestGravityAPMInitializeGrid.o \ Grid_TestGravityCheckResults.o \ + Grid_TestGravityAPMCheckResults.o \ Grid_TestGravityInitializeGrid.o \ Grid_TestGravityMotionInitializeGrid.o \ + Grid_TestGravitySineWaveInitializeGrid.o \ + Grid_TestGravitySphereAPMInitializeGrid.o \ Grid_TestGravitySphereCheckResults.o \ Grid_TestGravitySphereInitializeGrid.o \ Grid_TestOrbitInitializeGrid.o \ + Grid_TestSelfForceInitializeGrid.o \ Grid_TestStarParticleInitializeGrid.o \ Grid_TracerParticleCreateParticles.o \ Grid_TracerParticleOutputData.o \ @@ -714,11 +729,14 @@ OBJS_CONFIG_LIB = \ InitializeRadiativeTransferSpectrumTable.o \ InitializeRateData.o \ InitialLoadBalanceRootGrids.o \ - init_random_seed.o \ + init_random_seed.o \ interp1d.o \ interp2d.o \ interp3d.o \ interpolate.o \ + InterpolatePositionsTSC1d.o \ + InterpolatePositionsTSC2d.o \ + InterpolatePositionsTSC3d.o \ InterpretCommandLine.o \ inteuler.o \ intlgrg.o \ @@ -740,6 +758,7 @@ OBJS_CONFIG_LIB = \ mbh_maker.o \ mcooling.o \ MakeFieldConservative.o\ + make_green.o \ MemoryAllocationRoutines.o \ MemoryPoolRoutines.o \ MersenneTwister.o \ @@ -754,6 +773,7 @@ OBJS_CONFIG_LIB = \ MultigridSolver.o \ mused.o \ NestedCosmologySimulationInitialize.o \ + NextLargestFFTSize.o \ ngpinterp.o \ ngp_deposit.o \ ngp_deposit_c.o \ @@ -764,6 +784,8 @@ OBJS_CONFIG_LIB = \ nr_st1.o \ NullProblem.o \ OneZoneFreefallTestInitialize.o \ + OutputAccelerationField.o \ + OutputGravitatingMassField.o \ OutputAsParticleData.o \ OutputCoolingTimeOnly.o \ OutputDustTemperatureOnly.o \ @@ -932,16 +954,21 @@ OBJS_CONFIG_LIB = \ star_maker9.o \ star_maker10.o \ star_maker_h2reg.o \ - star_maker_ssn.o \ + star_maker_ssn.o \ StratifiedMediumExplosionInitialize.o \ SupernovaRestartInitialize.o \ SysMkdir.o \ + TestGravityAPMInitialize.o \ TestGravityCheckResults.o \ + TestGravityAPMCheckResults.o \ TestGravityInitialize.o \ TestGravityMotion.o \ + TestGravitySineWaveInitialize.o \ + TestGravitySphereAPMInitialize.o \ TestGravitySphereCheckResults.o \ TestGravitySphereInitialize.o \ TestOrbitInitialize.o \ + TestSelfForceInitialize.o \ TestStarParticleInitialize.o \ TracerParticleCreation.o \ TransposeRegionOverlap.o \ @@ -1222,7 +1249,7 @@ OBJS_HYDRO_RK = \ hydro_rk/Riemann_HLLD_MHD.o \ hydro_rk/Riemann_LLF_MHD.o \ hydro_rk/SuperNovaSeedField.o - + # Objects for the CUDA GPU-computing support OBJS_ECUDA_ALL = \ hydro_rk/CudaMHD.o \ diff --git a/src/enzo/Make.mach.ichbiah_18_04 b/src/enzo/Make.mach.ichbiah_18_04 new file mode 100644 index 000000000..2ab0cf8a4 --- /dev/null +++ b/src/enzo/Make.mach.ichbiah_18_04 @@ -0,0 +1,108 @@ +#======================================================================= +# +# FILE: Make.mach.ichbiah_ubuntu_16_04 +# +# DESCRIPTION: Makefile settings for my desktop machine at the MPI +# +# AUTHOR: Jean-Claude Passy +# +# DATE: 2018-02-18 +# +# This configuration assumes that build-essentials, gfortran, +# OpenMPI and HDF5 have been installed using apt-get. +# +#======================================================================= + +MACH_TEXT = Use apt-get to install csh libhdf5-serial-dev gfortran openmpi-bin libopenmpi-dev +MACH_VALID = 1 +MACH_FILE = Make.mach.ichbiah_18_04 + +#----------------------------------------------------------------------- +# Install paths (local variables) +#----------------------------------------------------------------------- + +LOCAL_HDF5_INSTALL = /usr/include/hdf5/openmpi +LOCAL_GRACKLE_INSTALL = /home/jpassy/Work/Projects/External/enzo/grackle/build +LOCAL_HYPRE_INSTALL = /home/jpassy/Work/Projects/External/enzo/hypre/build + +#----------------------------------------------------------------------- +# Compiler settings +#----------------------------------------------------------------------- + +MACH_CPP = gcc # C preprocessor command + +# With MPI + +MACH_CC_MPI = mpicc # C compiler when using MPI +MACH_CXX_MPI = mpic++ # C++ compiler when using MPI +MACH_FC_MPI = mpif77 # Fortran 77 compiler when using MPI +MACH_F90_MPI = mpif90 # Fortran 90 compiler when using MPI +MACH_LD_MPI = mpic++ # Linker when using MPI + +# Without MPI + +MACH_CC_NOMPI = gcc # C compiler when not using MPI +MACH_CXX_NOMPI = g++ # C++ compiler when not using MPI +MACH_FC_NOMPI = gfortran # Fortran 77 compiler when not using MPI +MACH_F90_NOMPI = gfortran # Fortran 90 compiler when not using MPI +MACH_LD_NOMPI = g++ # Linker when not using MPI + +#----------------------------------------------------------------------- +# Machine-dependent defines +#----------------------------------------------------------------------- + +MACH_DEFINES = -DLINUX -DH5_USE_16_API + +#----------------------------------------------------------------------- +# Compiler flag settings +#----------------------------------------------------------------------- + + +MACH_CPPFLAGS = -P -traditional +MACH_CFLAGS = +MACH_CXXFLAGS = +MACH_FFLAGS = -fno-second-underscore -ffixed-line-length-132 +MACH_F90FLAGS = -fno-second-underscore +MACH_LDFLAGS = + +#----------------------------------------------------------------------- +# Optimization flags +#----------------------------------------------------------------------- + +MACH_OPT_WARN = -Wall -g +MACH_OPT_DEBUG = -g +MACH_OPT_HIGH = -O2 +MACH_OPT_AGGRESSIVE = -O3 -g + +#----------------------------------------------------------------------- +# Includes +#----------------------------------------------------------------------- + +LOCAL_INCLUDES_MPI = -I/usr/include/openmpi +LOCAL_INCLUDES_HDF5 = -I/usr/include/hdf5/openmpi +LOCAL_INCLUDES_HYPRE = -I$(LOCAL_HYPRE_INSTALL)/include +#LOCAL_INCLUDES_PAPI = # PAPI includes +LOCAL_INCLUDES_GRACKLE = -I$(LOCAL_GRACKLE_INSTALL)/include + +MACH_INCLUDES = $(LOCAL_INCLUDES_HDF5) +MACH_INCLUDES_MPI = $(LOCAL_INCLUDES_MPI) +MACH_INCLUDES_HYPRE = $(LOCAL_INCLUDES_HYPRE) +#MACH_INCLUDES_PAPI = $(LOCAL_INCLUDES_PAPI) +MACH_INCLUDES_GRACKLE = $(LOCAL_INCLUDES_GRACKLE) + +#----------------------------------------------------------------------- +# Libraries +#----------------------------------------------------------------------- + +LOCAL_LIBS_MPI = -L/usr/lib +LOCAL_LIBS_HDF5 = -L/usr/include/hdf5/openmpi/lib -lhdf5_openmpi -lz +LOCAL_LIBS_HYPRE = -L$(LOCAL_HYPRE_INSTALL)/lib -lHYPRE +#LOCAL_LIBS_PAPI = # PAPI libraries +LOCAL_LIBS_MACH = -lgfortran # Machine-dependent libraries +LOCAL_LIBS_GRACKLE = -L$(LOCAL_GRACKLE_INSTALL)/lib -lgrackle + +MACH_LIBS = $(LOCAL_LIBS_HDF5) $(LOCAL_LIBS_MACH) +MACH_LIBS_MPI = $(LOCAL_LIBS_MPI) +MACH_LIBS_HYPRE = $(LOCAL_LIBS_HYPRE) +#MACH_LIBS_PAPI = $(LOCAL_LIBS_PAPI) +MACH_LIBS_GRACKLE = $(LOCAL_LIBS_GRACKLE) diff --git a/src/enzo/Make.mach.sow-macbook b/src/enzo/Make.mach.sow-macbook new file mode 100644 index 000000000..9807d3067 --- /dev/null +++ b/src/enzo/Make.mach.sow-macbook @@ -0,0 +1,126 @@ +#======================================================================= +# +# FILE: Make.mach.sow-macbook +# +# DESCRIPTION: Makefile settings for the SoW laptop +# This was written to use: +# System OpenMPI (mpicc, mpic++) +# HDF5 installed to /usr/local/ with no additional 'configure' +# arguments +# gfortran from http://r.research.att.com/gfortran-4.2.3.dmg +# +# +# AUTHOR: Jean-Claude Passy +# +# DATE: 2018-02-18 +# +# Update: 2011-05-02 +# Default compilation in newer Xcode is now x86_64, rather than i386. +# Updated fortran flags to reperesent change. +# Changed suggested gfortran, hpc.sf.net version only build for i386. +# +#======================================================================= + +MACH_TEXT = High Sierra +MACH_VALID = 1 +MACH_FILE = Make.mach.sow-macbook + +#----------------------------------------------------------------------- +# Commands to run test executables +#----------------------------------------------------------------------- + + +#----------------------------------------------------------------------- +# Install paths (local variables) +#----------------------------------------------------------------------- + +LOCAL_PACKAGES = /usr/local + +# This will not work on OSX Lion or newer. You may wany to try installing +# openmpi via macports. +LOCAL_MPI_INSTALL = /Users/jpassy/Work/Tools/openmpi/openmpi-4.0.1/build +LOCAL_FC_INSTALL = /usr/local/gfortran +LOCAL_HDF5_INSTALL = /Users/jpassy/Work/Tools/HDF5-1.10.5 +LOCAL_SZIP_INSTALL = $(LOCAL_PACKAGES) + +#----------------------------------------------------------------------- +# Compiler settings +#----------------------------------------------------------------------- + +MACH_CPP = /usr/bin/cpp + +# With MPI + +MACH_CC_MPI = $(LOCAL_MPI_INSTALL)/bin/mpicc +MACH_CXX_MPI = $(LOCAL_MPI_INSTALL)/bin/mpicxx +MACH_FC_MPI = $(LOCAL_MPI_INSTALL)/bin/mpif77 +MACH_F90_MPI = $(LOCAL_MPI_INSTALL)/bin/mpif90 +MACH_LD_MPI = $(LOCAL_MPI_INSTALL)/bin/mpicxx +#MACH_CUDACOMPILER = /usr/local/cuda/bin/nvcc + +# Without MPI + +MACH_CC_NOMPI = gcc # C compiler when not using MPI +MACH_CXX_NOMPI = g++ # C++ compiler when not using MPI +MACH_FC_NOMPI = gfortran # Fortran 77 compiler when not using MPI +MACH_F90_NOMPI = gfortran # Fortran 90 compiler when not using MPI +MACH_LD_NOMPI = g++ # Linker when not using MPI + +#----------------------------------------------------------------------- +# Machine-dependent defines +#----------------------------------------------------------------------- + +# Note: When compiling against HDF5 version 1.8 or greater, you need to +# compile HDF5 with --with-default-api-version=v16, or Enzo with +# -DH5_USE_16_API. + +MACH_DEFINES = -DLINUX -DH5_USE_16_API + +#----------------------------------------------------------------------- +# Compiler flag settings +#----------------------------------------------------------------------- + +MACH_CPPFLAGS = -P -traditional +MACH_CFLAGS = +MACH_CXXFLAGS = +MACH_FFLAGS = -fno-second-underscore -m64 +MACH_F90FLAGS = -fno-second-underscore -m64 +MACH_LDFLAGS = +MACH_SHARED_FLAGS = -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup +MACH_SHARED_EXT = dylib + +#----------------------------------------------------------------------- +# Optimization flags +#----------------------------------------------------------------------- + +MACH_OPT_WARN = -Wall -g +MACH_OPT_DEBUG = -g +MACH_OPT_HIGH = -O2 +MACH_OPT_AGGRESSIVE = -O3 -fomit-frame-pointer -fstrict-aliasing \ +-momit-leaf-frame-pointer -fno-tree-pre -falign-loops -g + +#----------------------------------------------------------------------- +# Includes +#----------------------------------------------------------------------- + +LOCAL_INCLUDES_MPI = -I$(LOCAL_MPI_INSTALL)/include +LOCAL_INCLUDES_HDF5 = -I$(LOCAL_HDF5_INSTALL)/include +LOCAL_INCLUDES_PYTHON = -I$(LOCAL_PYTHON_INSTALL)/include/python2.7/ \ + -I$(LOCAL_PYTHON_INSTALL)/lib/python2.7/site-packages/numpy/core/include + +MACH_INCLUDES = $(LOCAL_INCLUDES_HDF5) $(LOCAL_INCLUDES_CUDA) +MACH_INCLUDES_PYTHON = $(LOCAL_INCLUDES_PYTHON) +MACH_INCLUDES_MPI = $(LOCAL_INCLUDES_MPI) +MACH_INCLUDES_HYPRE = $(LOCAL_INCLUDES_HYPRE) +MACH_INCLUDES_GRACKLE = $(LOCAL_INCLUDES_GRACKLE) + +#----------------------------------------------------------------------- +# Libraries +#----------------------------------------------------------------------- + +LOCAL_LIBS_MACH = -L$(LOCAL_FC_INSTALL)/lib -lgfortran +LOCAL_LIBS_HDF5 = -L$(LOCAL_HDF5_INSTALL)/lib -lhdf5 + +MACH_LIBS = $(LOCAL_LIBS_HDF5) $(LOCAL_LIBS_MACH) +MACH_LIBS_PYTHON = $(LOCAL_LIBS_PYTHON) +MACH_LIBS_MPI = $(LOCAL_LIBS_MPI) diff --git a/src/enzo/NextLargestFFTSize.C b/src/enzo/NextLargestFFTSize.C new file mode 100644 index 000000000..43eb8ce2b --- /dev/null +++ b/src/enzo/NextLargestFFTSize.C @@ -0,0 +1,103 @@ +/*********************************************************************** +/ +/ DETERMINE THE NEXT LARGEST AVAILABLE FFT SIZE +/ +/ written by: Greg Bryan +/ date: March, 1995 +/ modified1: +/ +/ PURPOSE: This routine returns the next largest available size for +/ an FFT transform, given the library function available. +/ +/ Supported platform FFT library +/ SGI SGI_MATH +/ CONVEX VECLIB +/ ANY FOURN (from Numerical Recipes) +/ +************************************************************************/ + +/* Some FFT packages support more than just radix-2 transforms. This, + however can use an excessive number of Green's functions. The following + define flag indicates that only radix-2 transforms should be used, even + if other options are available. */ + +// #define USE_ONLY_RADIX2 +#define LIMITED_RANGE + +#include +#include +#include "macros_and_parameters.h" + +#ifdef GOT_MACHINE +#undef GOT_MACHINE +#endif + +int NextLargestFFTSize(int dimension) +{ + + /* --------------------------------------------------------------------- */ + /* Define the available sizes for SGI's WITH SGI_MATH */ + +#if defined(IRIS4) && defined(SGI_MATH) && !defined(USE_ONLY_RADIX2) + #define RADIX235 + #define GOT_MACHINE +#endif /* IRIS4 && SGI_MATH */ + + /* --------------------------------------------------------------------- */ + /* Define the available sizes for CONVEX WITH VECLIB. */ + +#if (defined(CONVEX) || defined(SPP)) && defined(VECLIB) && !defined(USE_ONLY_RADIX2) + #define RADIX235 + #define GOT_MACHINE +#endif /* (CONVEX || SPP) && VECLIB */ + + /* --------------------------------------------------------------------- */ + /* Define the available sizes for CONVEX WITH VECLIB. */ + +#if defined(FFTW) && !defined(USE_ONLY_RADIX2) + #define RADIX235 + #define GOT_MACHINE +#endif /* (CONVEX || SPP) && VECLIB */ + + /* --------------------------------------------------------------------- */ + /* If the machine was not one of the above, use this. */ + +#ifndef GOT_MACHINE + + /* FOURN is power of 2. */ + + static int sizes[] = {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; + +#endif /* GOT_MACHINE */ + + /* If FFT radix 2,3,5. Many values over 64 were skipped. */ + +#ifdef RADIX235 + #ifdef LIMITED_RANGE + static int sizes[] = {2, 4, 8, 16, 24, 32, 40, 48, 64, 96, 128, 256, 512, 1024}; + #else /* LIMITED_RANGE */ + static int sizes[] = {1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, + 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, + 64, 100, 128, 150, 200, 256, 400, 512, 1024}; + #endif /* LIMITED_RANGE */ +#endif /* RADIX 235 */ + + /* --------------------------------------------------------------------- */ + /* Error check. */ + +#define NUM_SIZES (sizeof sizes / sizeof sizes[0]) + + if (dimension > sizes[NUM_SIZES-1]) { + fprintf(stderr, "NextLargestFFTSize: %d too large!\n", dimension); + exit(FAIL); + } + + /* Loop through available sizes. */ + + int i = 0; + while (sizes[i] < dimension && i < NUM_SIZES-1) + i++; + + return sizes[i]; + +} diff --git a/src/enzo/OutputAccelerationField.C b/src/enzo/OutputAccelerationField.C new file mode 100644 index 000000000..54ca65f04 --- /dev/null +++ b/src/enzo/OutputAccelerationField.C @@ -0,0 +1,67 @@ +/*********************************************************************** +/ +/ CHECKS THE ACCURACY OF THE GRAVITY SOLVER +/ +/ written by: JC Passy +/ date: March 2013 +/ modified1: +/ +/ PURPOSE: +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "TopGridData.h" +#include "Hierarchy.h" +#include "LevelHierarchy.h" + +/* function prototypes */ + + +char TGOutputFileName2[] = "AccelerationField.out"; + + +int OutputAccelerationField(HierarchyEntry *Grid, int level, int cycle) +{ + + /* declarations */ + + FILE *fptr; + char name[MAX_LINE_LENGTH], proc[MAX_TASK_TAG_SIZE], cycle_name[MAX_TASK_TAG_SIZE]; + + /* Open output file. */ + + strcpy(name, TGOutputFileName2); + sprintf(cycle_name, "%"TASK_TAG_FORMAT""ISYM, cycle); + strcat(name, cycle_name); + sprintf(proc, "%"TASK_TAG_FORMAT""ISYM, MyProcessorNumber); + strcat(name, "_p"); + strcat(name, proc); + + if ((fptr = fopen(name, "a")) == NULL) { + fprintf(stderr, "CheckAccelerationField:\n Error opening file %s.\n", + name); + exit(FAIL); + } + + /* For each grid on each level, check the results. */ + + if (Grid->GridData->OutputAccelerationField(fptr, level) == FAIL) + ENZO_FAIL("Error in grid->OutputAccelerationField\n"); + + /* Close output file. */ + + fclose(fptr); + + return SUCCESS; +} diff --git a/src/enzo/OutputGravitatingMassField.C b/src/enzo/OutputGravitatingMassField.C new file mode 100644 index 000000000..f4ffe3a09 --- /dev/null +++ b/src/enzo/OutputGravitatingMassField.C @@ -0,0 +1,84 @@ +/*********************************************************************** +/ +/ CHECKS GRAVITATING MASS FIELDS +/ +/ written by: JC Passy +/ date: March 2013 +/ modified1: +/ +/ PURPOSE: +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "TopGridData.h" +#include "Hierarchy.h" +#include "LevelHierarchy.h" + +/* function prototypes */ + + +char TGOutputFileName3[] = "GMF.out"; +char TGOutputFileName4[] = "GMFP.out"; + + +int OutputGravitatingMassField(HierarchyEntry *Grid, int level,int cycle) +{ + + /* declarations */ + + FILE *fptr; + char name[MAX_LINE_LENGTH], proc[MAX_TASK_TAG_SIZE], cycle_name[MAX_TASK_TAG_SIZE];; + FILE *fptr2; + char name2[MAX_LINE_LENGTH], proc2[MAX_TASK_TAG_SIZE], cycle_name2[MAX_TASK_TAG_SIZE];; + + /* Open output file. */ + + strcpy(name, TGOutputFileName3); + sprintf(cycle_name, "%"TASK_TAG_FORMAT""ISYM, cycle); + strcat(name, cycle_name); + sprintf(proc, "%"TASK_TAG_FORMAT""ISYM, MyProcessorNumber); + strcat(name, "_p"); + strcat(name, proc); + + if ((fptr = fopen(name, "a")) == NULL) { + fprintf(stderr, "OutputGravitatingMassField:\n Error opening file %s.\n", + name); + exit(FAIL); + } + + strcpy(name2, TGOutputFileName4); + sprintf(cycle_name2, "%"TASK_TAG_FORMAT""ISYM, cycle); + strcat(name2, cycle_name2); + sprintf(proc2, "%"TASK_TAG_FORMAT""ISYM, MyProcessorNumber); + strcat(name2, "_p"); + strcat(name2, proc2); + + if ((fptr2 = fopen(name2, "a")) == NULL) { + fprintf(stderr, "OutputGravitatingMassFieldParticles:\n Error opening file %s.\n", + name2); + exit(FAIL); + } + + /* For each grid on each level, check the results. */ + + if (Grid->GridData->OutputGravitatingMassField(fptr, fptr2, level) == FAIL) + ENZO_FAIL("Error in grid->OutputGravitatingMassField\n"); + + /* Close output file. */ + + fclose(fptr); + fclose(fptr2); + + return SUCCESS; +} diff --git a/src/enzo/PrepareDensityField.C b/src/enzo/PrepareDensityField.C index 9bcb83d60..239acc3d4 100644 --- a/src/enzo/PrepareDensityField.C +++ b/src/enzo/PrepareDensityField.C @@ -47,6 +47,8 @@ /* function prototypes */ int DepositParticleMassField(HierarchyEntry *Grid, FLOAT Time = -1.0); +int DepositParticleMassFieldWithParent(HierarchyEntry *Grid, TopGridData *MetaData, + ChainingMeshStructure *ChainingMesh, FLOAT Time = -1.0); int CommunicationBufferPurge(void); int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[] = NULL, @@ -84,7 +86,9 @@ int ComputePotentialFieldLevelZero(TopGridData *MetaData, int GenerateGridArray(LevelHierarchyEntry *LevelArray[], int level, HierarchyEntry **Grids[]); - +int FastSiblingLocatorInitialize(ChainingMeshStructure *Mesh, int Rank, + int TopGridDims[]); +int FastSiblingLocatorFinalize(ChainingMeshStructure *Mesh); extern int CopyPotentialFieldAverage; @@ -126,6 +130,19 @@ int PrepareDensityField(LevelHierarchyEntry *LevelArray[], int NumberOfGrids = GenerateGridArray(LevelArray, level, &Grids); SiblingGridList *SiblingList = SiblingGridListStorage[level]; + /* Create ChainingMesh for the whole level above */ + ChainingMeshStructure ChainingMesh; + HierarchyEntry **GridsUpperLevel; + int NumberOfGridsUpperLevel; + + if (level>0) { + FastSiblingLocatorInitialize(&ChainingMesh, MetaData->TopGridRank, + MetaData->TopGridDims); + NumberOfGridsUpperLevel = GenerateGridArray(LevelArray, level-1, &GridsUpperLevel); + for (grid1 = 0; grid1 < NumberOfGridsUpperLevel; grid1++) + GridsUpperLevel[grid1]->GridData->FastSiblingLocatorAddGrid(&ChainingMesh); + } + /************************************************************************/ /* Grids: Deposit particles in their GravitatingMassFieldParticles. (Do a batch of grids at a time; this is a loop over the batches) @@ -140,38 +157,67 @@ int PrepareDensityField(LevelHierarchyEntry *LevelArray[], TIME_MSG("Depositing particle mass field"); LCAPERF_START("DepositParticleMassField"); - for (StartGrid = 0; StartGrid < NumberOfGrids; StartGrid += GRIDS_PER_LOOP) { - EndGrid = min(StartGrid + GRIDS_PER_LOOP, NumberOfGrids); + if (ProblemType != 41 && ProblemType != 46) { + for (StartGrid = 0; StartGrid < NumberOfGrids; StartGrid += GRIDS_PER_LOOP) { + EndGrid = min(StartGrid + GRIDS_PER_LOOP, NumberOfGrids); - /* First, generate the receive calls. */ + /* First, generate the receive calls. */ - CommunicationReceiveIndex = 0; - CommunicationReceiveCurrentDependsOn = COMMUNICATION_NO_DEPENDENCE; - CommunicationDirection = COMMUNICATION_POST_RECEIVE; - for (grid1 = StartGrid; grid1 < EndGrid; grid1++) - DepositParticleMassField(Grids[grid1], EvaluateTime); + CommunicationReceiveIndex = 0; + CommunicationReceiveCurrentDependsOn = COMMUNICATION_NO_DEPENDENCE; + CommunicationDirection = COMMUNICATION_POST_RECEIVE; + for (grid1 = StartGrid; grid1 < EndGrid; grid1++) + + // New deposition: Only with the APM solver - CIC deposition will mess things up */ + if (DepositAlsoParentGridAndSiblingsParticles) + DepositParticleMassFieldWithParent(Grids[grid1], MetaData, &ChainingMesh, EvaluateTime); + else // normal deposition + DepositParticleMassField(Grids[grid1], EvaluateTime); #ifdef FORCE_MSG_PROGRESS - CommunicationBarrier(); + CommunicationBarrier(); #endif - if (traceMPI) - fprintf(tracePtr, "PrepareDensityField: Enter DepositParticleMassField" - " (Receive)\n"); + if (traceMPI) + fprintf(tracePtr, "PrepareDensityField: Enter DepositParticleMassField" + " (Receive)\n"); - /* Next, send data and process grids on the same processor. */ + /* Next, send data and process grids on the same processor. */ - CommunicationDirection = COMMUNICATION_SEND; - for (grid1 = StartGrid; grid1 < EndGrid; grid1++) - DepositParticleMassField(Grids[grid1], EvaluateTime); + CommunicationDirection = COMMUNICATION_SEND; + for (grid1 = StartGrid; grid1 < EndGrid; grid1++) - /* Finally, receive the data and process it. */ - - CommunicationReceiveHandler(); + // New deposition: Only with the APM solver - CIC deposition will mess things up */ + if (DepositAlsoParentGridAndSiblingsParticles) + DepositParticleMassFieldWithParent(Grids[grid1], MetaData, &ChainingMesh, EvaluateTime); + else // normal deposition + DepositParticleMassField(Grids[grid1], EvaluateTime); - } // ENDFOR grid batches - LCAPERF_STOP("DepositParticleMassField"); + /* Finally, receive the data and process it. */ + CommunicationReceiveHandler(); + } // ENDFOR grid batches + LCAPERF_STOP("DepositParticleMassField"); + } else { // Passy Binary (variables names changed) + for ( grid1 = 0; grid1 < NumberOfGrids; grid1++) { + if (Grids[grid1]->GridData-> + InitializeGravitatingMassFieldParticles(RefineBy) == FAIL) { + ENZO_FAIL("Error in grid->InitializeGravitatingMassFieldParticles.\n"); + } + + if (Grids[grid1]->GridData-> + ClearGravitatingMassFieldParticles() == FAIL) { + ENZO_FAIL("Error in grid->ClearGravitatingMassFieldParticles.\n"); + } + } + } // end if (ProblemType != 41) + + if (level > 0) { + // Finalize + FastSiblingLocatorFinalize(&ChainingMesh); + // Cleanup + delete [] GridsUpperLevel; + } #ifdef FORCE_BUFFER_PURGE CommunicationBufferPurge(); @@ -404,6 +450,10 @@ int PrepareDensityField(LevelHierarchyEntry *LevelArray[], TIMER_STOP("ComputePotentialFieldLevelZero"); LCAPERF_STOP("ComputePotentialFieldLevelZero"); } + + /* Return if not using FAST gravity solver. */ + if (GravitySolverType == GRAVITY_SOLVER_APM) + return SUCCESS; /************************************************************************/ /* Compute a first iteration of the potential and share BV's. */ diff --git a/src/enzo/PrepareGravitatingMassField.C b/src/enzo/PrepareGravitatingMassField.C index 4d3fc201e..ddd6998a4 100644 --- a/src/enzo/PrepareGravitatingMassField.C +++ b/src/enzo/PrepareGravitatingMassField.C @@ -9,7 +9,7 @@ / PURPOSE: / ************************************************************************/ - + #ifdef USE_MPI #include "mpi.h" #endif /* USE_MPI */ @@ -37,9 +37,9 @@ int CopyOverlappingParticleMassFields(grid* CurrentGrid, int level); #endif int DepositBaryons(HierarchyEntry *Grid, FLOAT When); - + /* EvolveHierarchy function */ - + int PrepareGravitatingMassField1(HierarchyEntry *Grid) { @@ -88,14 +88,14 @@ int PrepareGravitatingMassField2a(HierarchyEntry *Grid, TopGridData *MetaData, FLOAT When) #endif { - + /* declarations */ - + int grid2; grid *CurrentGrid = Grid->GridData; - + /* Baryons: deposit mass into GravitatingMassField. */ - + // IF STATEMENT HERE TO MAKE IT SO NO GAS CONTRIBUTES TO GRAVITY if(!SelfGravityGasOff){ if (DepositBaryons(Grid, When) == FAIL) { @@ -103,13 +103,13 @@ int PrepareGravitatingMassField2a(HierarchyEntry *Grid, TopGridData *MetaData, printf(" Potential calculated for the gas\n"); } } - + /* Particles: go through all the other grids on this level and add all their overlapping GravitatingMassFieldParticles to this grid's GravitatingMassField. Handle periodicity properly. */ - + // fprintf(stderr, " PGMF - CopyOverlappingParticleMassField\n"); - + #ifdef FAST_SIB for (grid2 = 0; grid2 < SiblingList[grid1].NumberOfSiblings; grid2++) if (CurrentGrid->CheckForOverlap(SiblingList[grid1].GridList[grid2], @@ -130,17 +130,17 @@ int PrepareGravitatingMassField2a(HierarchyEntry *Grid, TopGridData *MetaData, #endif /* If we are using comoving coordinates, we must adjust the source term. */ - + if (CommunicationDirection == COMMUNICATION_SEND || CommunicationDirection == COMMUNICATION_SEND_RECEIVE) { - if (ComovingCoordinates) + if (ComovingCoordinates | (ProblemType == 44 && GravitySolverType == GRAVITY_SOLVER_FAST)) if (CurrentGrid->ComovingGravitySourceTerm() == FAIL) { ENZO_FAIL("Error in grid->ComovingGravitySourceTerm.\n"); } - + } // end: if (CommunicationDirection != COMMUNICATION_SEND) - + return SUCCESS; } @@ -148,15 +148,15 @@ int PrepareGravitatingMassField2a(HierarchyEntry *Grid, TopGridData *MetaData, int PrepareGravitatingMassField2b(HierarchyEntry *Grid, int level) { - + /* declarations */ - + grid *CurrentGrid = Grid->GridData; CommunicationReceiveCurrentDependsOn = COMMUNICATION_NO_DEPENDENCE; if (level > 0) CurrentGrid->PreparePotentialField(Grid->ParentGrid->GridData); - + return SUCCESS; } diff --git a/src/enzo/ReadParameterFile.C b/src/enzo/ReadParameterFile.C index 46f06c23f..98b0f2498 100644 --- a/src/enzo/ReadParameterFile.C +++ b/src/enzo/ReadParameterFile.C @@ -545,6 +545,18 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "SelfGravity = %"ISYM, &SelfGravity); ret += sscanf(line, "SelfGravityGasOff = %"ISYM, &SelfGravityGasOff); + + ret += sscanf(line, "GravitySolverType = %"ISYM, &GravitySolverType); + ret += sscanf(line, "APMAddParentContribution = %"ISYM, &APMAddParentContribution); + ret += sscanf(line, "TimeSteppingRefinementCondition = %"ISYM, + &TimeSteppingRefinementCondition); + ret += sscanf(line, "DepositAlsoParentGridAndSiblingsParticles = %"ISYM, + &DepositAlsoParentGridAndSiblingsParticles); + ret += sscanf(line, "S2ParticleSize = %"FSYM, &S2ParticleSize); + ret += sscanf(line, "GravityResolution = %"FSYM, &GravityResolution); + ret += sscanf(line, "GreensFunctionMaxNumber = %"ISYM, &GreensFunctionMaxNumber); + ret += sscanf(line, "GreensFunctionMaxSize = %"ISYM, &GreensFunctionMaxSize); + ret += sscanf(line, "AccretionKernal = %"ISYM, &AccretionKernal); ret += sscanf(line, "GravitationalConstant = %"FSYM, &GravitationalConstant); ret += sscanf(line, "ComputePotential = %"ISYM, &ComputePotential); @@ -1406,6 +1418,8 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (strstr(line, "TestGravity" ) ) ret++; if (strstr(line, "SphericalInfall" ) ) ret++; if (strstr(line, "TestGravitySphere" ) ) ret++; + if (strstr(line, "TestGravitySineWave") ) ret++; + if (strstr(line, "TestSelfForce")) ret++; if (strstr(line, "Cluster" ) ) ret++; if (strstr(line, "CollapseTest" ) ) ret++; if (strstr(line, "Cosmology" ) ) ret++; diff --git a/src/enzo/SetDefaultGlobalValues.C b/src/enzo/SetDefaultGlobalValues.C index 7f4183926..3e463a4ff 100644 --- a/src/enzo/SetDefaultGlobalValues.C +++ b/src/enzo/SetDefaultGlobalValues.C @@ -12,30 +12,30 @@ / RETURNS: SUCCESS or FAIL / ************************************************************************/ - + // This routine intializes a new simulation based on the parameter file. // -#include "preincludes.h" +#include "preincludes.h" #include "macros_and_parameters.h" #include "typedefs.h" #include "global_data.h" #include "TopGridData.h" #include "StarParticleData.h" #include "phys_constants.h" - + /* character strings */ - + char DefaultDimUnits[] = "cm"; char *DefaultDimLabel[] = {"x", "y", "z"}; - + char DefaultRestartName[] = "restart"; char DefaultDataName[] = "data"; char DefaultHistoryName[] = "history"; char DefaultRedshiftName[] = "RedshiftOutput"; char DefaultNewMovieName[] = "MoviePack"; char DefaultTracerParticleName[] = "TracerOutput"; - + char DefaultRestartDir[] = "RS"; char DefaultDataDir[] = "DD"; char DefaultHistoryDir[] = "HD"; @@ -43,33 +43,33 @@ char DefaultRedshiftDir[] = "RD"; char DefaultTracerParticleDir[] = "TD"; char DefaultExtraName[] = "ExtraDumpXX"; char DefaultExtraDir[]="ED00"; - - - + + + int SetDefaultGlobalValues(TopGridData &MetaData) { - + /* declarations */ - + int dim, i, j; - + huge_number = 1.0e+20; tiny_number = 1.0e-20; /* set the default MetaData values. */ - + MetaData.CycleNumber = 0; MetaData.SubcycleNumber = 0; MetaData.Time = 0.0; MetaData.CPUTime = 0.0; - + MetaData.StopTime = FLOAT_UNDEFINED; // This must be set be the user MetaData.StopCycle = 100000; // 10000 timesteps MetaData.StopSteps = 10000; // 10000 timesteps MetaData.StopCPUTime = 720.0*3600.0; // 30 days MetaData.ResubmitOn = FALSE; MetaData.ResubmitCommand = NULL; - + MetaData.MaximumTopGridTimeStep = huge_number; MetaData.TimeLastRestartDump = 0.0; @@ -83,7 +83,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) MetaData.TimeLastInterpolatedDataDump = FLOAT_UNDEFINED; MetaData.dtInterpolatedDataDump = 0.0; MetaData.WroteData = FALSE; - + MetaData.CycleLastRestartDump = 0; MetaData.CycleSkipRestartDump = 0; MetaData.CycleLastDataDump = INT_UNDEFINED; @@ -93,10 +93,10 @@ int SetDefaultGlobalValues(TopGridData &MetaData) MetaData.CycleLastHistoryDump = INT_UNDEFINED; MetaData.CycleSkipHistoryDump = 0; MetaData.CycleSkipGlobalDataDump = 0; //AK - + MetaData.OutputFirstTimeAtLevel = 0; // zero is off MetaData.StopFirstTimeAtLevel = 0; // zero is off - + MetaData.NumberOfOutputsBeforeExit = 0; MetaData.OutputsLeftBeforeExit = 0; @@ -153,14 +153,14 @@ int SetDefaultGlobalValues(TopGridData &MetaData) TimeActionTime[i] = 0; TimeActionParameter[i] = FLOAT_UNDEFINED; } - + for (i = 0; i < MAX_CUBE_DUMPS; i++) { CubeDumps[i] = NULL; } - + MetaData.StaticHierarchy = TRUE; FastSiblingLocatorEntireDomain = TRUE; - + MetaData.TopGridRank = INT_UNDEFINED; for (dim = 0; dim < MAX_DIMENSION; dim++) { MetaData.TopGridDims[dim] = INT_UNDEFINED; @@ -168,23 +168,23 @@ int SetDefaultGlobalValues(TopGridData &MetaData) MetaData.RightFaceBoundaryCondition[dim] = reflecting; } MetaData.BoundaryConditionName = NULL; - + MetaData.GravityBoundary = TopGridPeriodic; #ifdef TRANSFER MetaData.RadHydroParameterFname = NULL; #endif - + MetaData.ParticleBoundaryType = periodic; // only one implemented! MetaData.NumberOfParticles = 0; // no particles - + MetaData.CourantSafetyNumber = 0.6; MetaData.PPMFlatteningParameter = 0; // off MetaData.PPMDiffusionParameter = 0; // off MetaData.PPMSteepeningParameter = 0; // off MetaData.FirstTimestepAfterRestart = TRUE; - + /* set the default global data. */ CheckpointRestart = 0; @@ -219,7 +219,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) SubgridSizeAutoAdjust = TRUE; // true for adjusting maxsize and minedge OptimalSubgridsPerProcessor = 16; // Subgrids per processor NumberOfBufferZones = 1; - + for (i = 0; i < MAX_FLAGGING_METHODS; i++) { MinimumSlopeForRefinement[i]= 0.3; SlopeFlaggingFields[i] = INT_UNDEFINED; @@ -231,7 +231,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) SecondDerivativeFlaggingFields[i] = INT_UNDEFINED; } SecondDerivativeEpsilon = 1.0e-2; - + for (dim = 0; dim < MAX_DIMENSION; dim++) { DomainLeftEdge[dim] = 0.0; DomainRightEdge[dim] = 1.0; @@ -256,14 +256,14 @@ int SetDefaultGlobalValues(TopGridData &MetaData) GalaxySimulationPreWindVelocity[dim] = 0.0; StellarWindCenterPosition[dim] = 0.5; } - if( MAX_DIMENSION > 0 ) DiskGravityAngularMomentum[MAX_DIMENSION-1] = 1.0; + if( MAX_DIMENSION > 0 ) DiskGravityAngularMomentum[MAX_DIMENSION-1] = 1.0; MultiRefineRegionMaximumOuterLevel = INT_UNDEFINED; MultiRefineRegionMinimumOuterLevel = INT_UNDEFINED; for (i = 0; i < MAX_STATIC_REGIONS; i++) { MultiRefineRegionMaximumLevel[i] = INT_UNDEFINED; MultiRefineRegionMinimumLevel[i] = 0; - MultiRefineRegionGeometry[i] = -1; + MultiRefineRegionGeometry[i] = -1; MultiRefineRegionRadius[i] = INT_UNDEFINED; MultiRefineRegionWidth[i] = 3.0; MultiRefineRegionStaggeredRefinement[i] = 0.0; @@ -374,7 +374,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) First_Pass = 0; MemoryLimit = 4000000000L; - + ExternalGravity = FALSE; // off ExternalGravityDensity = 0.0; ExternalGravityRadius = 0.0; @@ -382,7 +382,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) UniformGravity = FALSE; // off UniformGravityDirection = 0; // x-direction UniformGravityConstant = 1.0; - + PointSourceGravity = FALSE; // off PointSourceGravityConstant = 1.0; PointSourceGravityCoreRadius = 0.0; @@ -398,6 +398,14 @@ int SetDefaultGlobalValues(TopGridData &MetaData) SelfGravity = FALSE; // off SelfGravityGasOff = FALSE; // off + + GravitySolverType = GRAVITY_SOLVER_FAST; // multigrid + APMAddParentContribution = TRUE; // on + TimeSteppingRefinementCondition = 0; // Extra condition dt(l+1) <= dt(l)/refinement + DepositAlsoParentGridAndSiblingsParticles = 0; // Deposit also particles from parent and its siblings + S2ParticleSize = 3.0; // ~3 is reasonable + GravityResolution = 1.0; // equivalent to grid + AccretionKernal = FALSE; // off CopyGravPotential = FALSE; // off PotentialIterations = 4; // ~4 is reasonable @@ -406,6 +414,9 @@ int SetDefaultGlobalValues(TopGridData &MetaData) WritePotential = FALSE; ParticleSubgridDepositMode = CIC_DEPOSIT_SMALL; + GreensFunctionMaxNumber = 1; // only one at a time + GreensFunctionMaxSize = 1; // not used yet + GalaxySimulationRPSWind = 0; GalaxySimulationRPSWindShockSpeed = 0.0; GalaxySimulationRPSWindDelay = 0.0; @@ -438,8 +449,8 @@ int SetDefaultGlobalValues(TopGridData &MetaData) } UseSGSModel = 0; // off - SGSFilterStencil = 0; // the one-dimensional stencil of the complete filter - SGSNeedJacobians = 0; // set automatically in ReadParameter file + SGSFilterStencil = 0; // the one-dimensional stencil of the complete filter + SGSNeedJacobians = 0; // set automatically in ReadParameter file SGSNeedMixedFilteredQuantities = 0; // set automatically in ReadParameter file SGSFilterWidth = 0.; // off, i.e. use grid-scale quantities for (i = 0; i < 4; i++) @@ -486,7 +497,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) ShockMethod = 0; // off ShockTemperatureFloor = 1.0; // Set to 1K StorePreShockFields = 0; - FindShocksOnlyOnOutput = 0; // Find at every cycle and + FindShocksOnlyOnOutput = 0; // Find at every cycle and // during output by default. RadiationFieldType = 0; RadiationFieldRedshift = FLOAT_UNDEFINED; @@ -514,11 +525,11 @@ int SetDefaultGlobalValues(TopGridData &MetaData) CoolData.DeuteriumToHydrogenRatio = 2.0*3.4e-5; // Burles & Tytler 1998 /* - Previously, the solar metal mass fraction was 0.02041. - This is close to 0.0194 of Anders & Grevesse (1989), but significantly + Previously, the solar metal mass fraction was 0.02041. + This is close to 0.0194 of Anders & Grevesse (1989), but significantly higher than the more recent value of 0.0122 from Asplund et al. (2005). - Now, the solar metal mass fraction has been set to 0.01295, - which is consistent with the abundances used in Cloudy when generating the + Now, the solar metal mass fraction has been set to 0.01295, + which is consistent with the abundances used in Cloudy when generating the Grackle cooling tables. */ CoolData.SolarMetalFractionByMass = 0.01295; // Cloudy v13 abundances @@ -556,10 +567,10 @@ int SetDefaultGlobalValues(TopGridData &MetaData) ZEUSQuadraticArtificialViscosity = 2.0; UseMinimumPressureSupport = FALSE; MinimumPressureSupportParameter = 100.0; - + //MinimumSlopeForRefinement = 0.3; // 30% change in value MinimumShearForRefinement = 1.0; //AK - OldShearMethod = 0; + OldShearMethod = 0; MinimumPressureJumpForRefinement = 0.33; // As in PPM method paper MinimumEnergyRatioForRefinement = 0.1; // conservative! RefineByJeansLengthSafetyFactor = 4.0; @@ -567,7 +578,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) RefineByResistiveLengthSafetyFactor = 2.0; ShockwaveRefinementMinMach = 1.3; // Only above M=1.3 ShockwaveRefinementMinVelocity = 1.0e7; //1000 km/s - ShockwaveRefinementMaxLevel = 0; + ShockwaveRefinementMaxLevel = 0; MustRefineParticlesRefineToLevel = 0; MustRefineParticlesCreateParticles = 0; MustRefineParticlesRefineToLevelAutoAdjust = FALSE; @@ -655,7 +666,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) PythonTopGridSkip = 0; PythonSubcycleSkip = 1; PythonReloadScript = FALSE; - + // EnzoTiming Dump Frequency TimingCycleSkip = 1; @@ -683,9 +694,9 @@ int SetDefaultGlobalValues(TopGridData &MetaData) StarClusterRegionLeftEdge[dim] = 0.0; StarClusterRegionRightEdge[dim] = 1.0; } - + MixSpeciesAndColors = 1; //Enable SNColour field to be advected as species in MHD - + PopIIIStarMass = 100; PopIIIInitialMassFunction = FALSE; PopIIIInitialMassFunctionSeed = INT_UNDEFINED; @@ -751,7 +762,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) StarMakerMinimumMassRampStartMass = FLOAT_UNDEFINED; StarMakerMinimumMassRampEndTime = FLOAT_UNDEFINED; StarMakerMinimumMassRampEndMass = FLOAT_UNDEFINED; - + NumberOfParticleAttributes = INT_UNDEFINED; AddParticleAttributes = FALSE; LastSupernovaTime = FLOAT_UNDEFINED; @@ -842,7 +853,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) TestProblemData.HydrogenFractionByMass = 0.76; /* The DToHRatio is by mass in the code, so multiply by 2. */ - TestProblemData.DeuteriumToHydrogenRatio = 2.0*3.4e-5; // Burles & Tytler 1998 + TestProblemData.DeuteriumToHydrogenRatio = 2.0*3.4e-5; // Burles & Tytler 1998 // multispecies default values assume completely neutral gas with primordial D/H ratio TestProblemData.MultiSpecies = 0; @@ -966,7 +977,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) VelocityGradient=1.0; ShearingBoundaryDirection=-1; ShearingVelocityDirection=-1; - ShearingBoxProblemType = 0; + ShearingBoxProblemType = 0; UseMHD=0; MaxVelocityIndex = 3; @@ -1013,7 +1024,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) ResetMagneticField = FALSE; for (dim = 0; dim < MAX_DIMENSION; dim++) { ResetMagneticFieldAmplitude[dim] = 0.0; // in Gauss - } + } VelAnyl = 0; BAnyl = 0; @@ -1035,7 +1046,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) SmartStarBHJetFeedback = FALSE; SmartStarBHThermalFeedback = FALSE; SmartStarStellarRadiativeFeedback = FALSE; - + //SmartStar Feedback parameters - should be as minimal as possible SmartStarFeedbackEnergyCoupling = 0.016666; SmartStarFeedbackJetsThresholdMass = 1.0; diff --git a/src/enzo/SetLevelTimeStep.C b/src/enzo/SetLevelTimeStep.C index 9490c8cae..3a261eece 100644 --- a/src/enzo/SetLevelTimeStep.C +++ b/src/enzo/SetLevelTimeStep.C @@ -11,7 +11,7 @@ / Determine the timestep for this iteration of the loop. / ************************************************************************/ - + #include "performance.h" #include "ErrorExceptions.h" #include "macros_and_parameters.h" @@ -25,7 +25,7 @@ #include "TopGridData.h" #include "LevelHierarchy.h" - + float CommunicationMinValue(float Value); int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, @@ -38,15 +38,15 @@ int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, LCAPERF_START("SetLevelTimeStep"); // SetTimeStep() if (level == 0) { - + /* For root level, use dtLevelAbove. */ - + *dtThisLevel = dtLevelAbove; *dtThisLevelSoFar = dtLevelAbove; dtActual = dtLevelAbove; - + } else { - + /* Calculate timestep without conduction and get conduction separately later. */ int my_isotropic_conduction = IsotropicConduction; @@ -56,11 +56,11 @@ int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, dtRebuildHierarchy[level] <= 0.0; if (dynamic_hierarchy_rebuild) { - IsotropicConduction = AnisotropicConduction = FALSE; + IsotropicConduction = AnisotropicConduction = FALSE; } /* Compute the mininum timestep for all grids. */ - + *dtThisLevel = huge_number; for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { dtGrid = Grids[grid1]->GridData->ComputeTimeStep(); @@ -68,7 +68,11 @@ int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, } *dtThisLevel = CommunicationMinValue(*dtThisLevel); - /* Compute conduction timestep and use to set the number + /* Extra condition dt(l1+1) <= dt(l)/refinement for APM solver */ + if (TimeSteppingRefinementCondition) + *dtThisLevel = min(*dtThisLevel, dtLevelAbove/RefineBy); + + /* Compute conduction timestep and use to set the number of iterations without rebuiding the hierarchy. */ if (dynamic_hierarchy_rebuild) { @@ -81,7 +85,7 @@ int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, float dt_cond_temp; dt_conduction = huge_number; for (grid1 = 0; grid1 < NumberOfGrids; grid1++) { - if (Grids[grid1]->GridData->ComputeConductionTimeStep(dt_cond_temp) == FAIL) + if (Grids[grid1]->GridData->ComputeConductionTimeStep(dt_cond_temp) == FAIL) ENZO_FAIL("Error in ComputeConductionTimeStep.\n"); dt_conduction = min(dt_conduction,dt_cond_temp); } @@ -111,27 +115,27 @@ int SetLevelTimeStep(HierarchyEntry *Grids[], int NumberOfGrids, int level, *dtThisLevel = dtLimit; #endif - + /* Advance dtThisLevelSoFar (don't go over dtLevelAbove). */ - + if (*dtThisLevelSoFar+*dtThisLevel*1.05 >= dtLevelAbove) { *dtThisLevel = dtLevelAbove - *dtThisLevelSoFar; *dtThisLevelSoFar = dtLevelAbove; } else *dtThisLevelSoFar += *dtThisLevel; - + } - if (debug) - printf("Level[%"ISYM"]: dt = %"GSYM" %"GSYM" (%"GSYM"/%"GSYM")\n", + if (debug) + printf("Level[%"ISYM"]: dt = %"GSYM" %"GSYM" (%"GSYM"/%"GSYM")\n", level, *dtThisLevel, dtActual, *dtThisLevelSoFar, dtLevelAbove); - + /* Set all grid's timestep to this minimum dt. */ - + for (grid1 = 0; grid1 < NumberOfGrids; grid1++) Grids[grid1]->GridData->SetTimeStep(*dtThisLevel); - + LCAPERF_STOP("SetLevelTimeStep"); // SetTimeStep() return SUCCESS; diff --git a/src/enzo/TestGravityAPMCheckResults.C b/src/enzo/TestGravityAPMCheckResults.C new file mode 100644 index 000000000..4ed01f1a9 --- /dev/null +++ b/src/enzo/TestGravityAPMCheckResults.C @@ -0,0 +1,89 @@ +/*********************************************************************** +/ +/ CHECKS THE ACCURACY OF THE GRAVITY SOLVER - APM version +/ +/ written by: Greg Bryan +/ date: July, 1995 +/ modified1: +/ +/ PURPOSE: +/ +************************************************************************/ + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "TopGridData.h" +#include "Hierarchy.h" +#include "LevelHierarchy.h" + +/* function prototypes */ + +char TGAPMOutputFileName[] = "TestGravityCheckResults.out"; + +int TestGravityAPMCheckResults(LevelHierarchyEntry *LevelArray[]) +{ + + /* declarations */ + + int level; + FILE *fptr; + char name[MAX_LINE_LENGTH], proc[MAX_TASK_TAG_SIZE]; + + /* Open output file. */ + + strcpy(name, TGAPMOutputFileName); + if (NumberOfProcessors > 1) + { + sprintf(proc, "%" TASK_TAG_FORMAT "" ISYM, MyProcessorNumber); + strcat(name, proc); + } + if ((fptr = fopen(name, "w")) == NULL) + { + fprintf(stderr, "TestGravityAPMCheckResults:\n Error opening file %s.\n", + name); + exit(FAIL); + } + + /* Output header. */ + + fprintf(fptr, "# r f_tang f_radial f_analytic\n"); + + /* For each grid on each level, check the results. */ + + for (level = 0; level < MAX_DEPTH_OF_HIERARCHY; level++) + { + + LevelHierarchyEntry *Level = LevelArray[level]; + + while (Level != NULL) + { + + if (Level->GridData->TestGravityAPMCheckResults(fptr, + LevelArray[0]->GridData, level) == FAIL) + { + fprintf(stderr, "Error in grid->TestGravityAPMCheckResults\n"); + exit(FAIL); + } + + /* Next grid on the this level. */ + + Level = Level->NextGridThisLevel; + } + + } // end: loop over levels + + /* Close output file. */ + + fclose(fptr); + + return SUCCESS; +} diff --git a/src/enzo/TestGravityAPMInitialize.C b/src/enzo/TestGravityAPMInitialize.C new file mode 100644 index 000000000..f4c0bcf26 --- /dev/null +++ b/src/enzo/TestGravityAPMInitialize.C @@ -0,0 +1,201 @@ +/*********************************************************************** +/ +/ INITIALIZE A GRAVITY TEST - APM version +/ +/ written by: Greg Bryan +/ date: April, 1995 +/ modified1: Jean-Claude Passy, May 2018 +/ +/ PURPOSE: +/ We set up a system in which there is one grid point with mass in order +/ to see the resulting acceleration field. If finer grids are specified, +/ the mass is one grid on the subgrid as well. +/ +/ UPDATE: Following tests performed in Passy & Bryan (2014) +/ +/ RETURNS: SUCCESS or FAIL +/ +************************************************************************/ + +// This routine intializes a new simulation based on the parameter file. +// + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "Hierarchy.h" +#include "TopGridData.h" + +int TestGravityAPMInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, + TopGridData &MetaData) +{ + char *DensName = "Density"; + char *TEName = "TotalEnergy"; + char *GEName = "GasEnergy"; + char *Vel1Name = "x-velocity"; + char *Vel2Name = "y-velocity"; + char *Vel3Name = "z-velocity"; + + /* declarations */ + + char line[MAX_LINE_LENGTH]; + int dim, ret; + int NumberOfSubgridZones[MAX_DIMENSION], SubgridDims[MAX_DIMENSION]; + FLOAT LeftEdge[MAX_DIMENSION], RightEdge[MAX_DIMENSION]; + + /* Error check. */ + + if (!SelfGravity) + fprintf(stderr, "TestGravity: gravity is off!?!"); + + /* set default parameters */ + + float TestGravityDensity = 1.0; // density of central peak + float TestGravitySubgridLeft = 0.0; // start of subgrid + float TestGravitySubgridRight = 0.0; // end of subgrid + int TestGravityNumberOfParticles = 0; // number of test particles + int TestGravityUseBaryons = FALSE; + float TestGravityCentralParticlePosition[MAX_DIMENSION]; + for (dim = 0; dim < MAX_DIMENSION; dim++) + TestGravityCentralParticlePosition[dim] = 0.5 * (DomainLeftEdge[dim] + DomainRightEdge[dim]); + + /* read input from file */ + + while (fgets(line, MAX_LINE_LENGTH, fptr) != NULL) + { + + ret = 0; + + /* read parameters */ + + ret += sscanf(line, "TestGravityDensity = %" FSYM, &TestGravityDensity); + ret += sscanf(line, "TestGravitySubgridLeft = %" PSYM, + &TestGravitySubgridLeft); + ret += sscanf(line, "TestGravitySubgridRight = %" PSYM, + &TestGravitySubgridRight); + ret += sscanf(line, "TestGravityNumberOfParticles = %" ISYM, + &TestGravityNumberOfParticles); + ret += sscanf(line, "TestGravityUseBaryons = %" ISYM, + &TestGravityUseBaryons); + ret += sscanf(line, "TestGravityCentralParticlePosition = %" PSYM " %" PSYM " %" PSYM, + TestGravityCentralParticlePosition, + TestGravityCentralParticlePosition + 1, + TestGravityCentralParticlePosition + 2); + + /* if the line is suspicious, issue a warning */ + + if (ret == 0 && strstr(line, "=") && strstr(line, "TestGravity") && line[0] != '#') + fprintf(stderr, "warning: the following parameter line was not interpreted:\n%s\n", line); + + } // end input from parameter file + + /* set up grid */ + + if (TopGrid.GridData->TestGravityAPMInitializeGrid(TestGravityDensity, + TestGravityNumberOfParticles, + TestGravityCentralParticlePosition, + TestGravityUseBaryons) == FAIL) + { + ENZO_FAIL("Error in TestGravityAPMInitializeGrid.\n"); + } + + /* If requested, create a subgrid */ + + for (dim = 0; dim < MetaData.TopGridRank; dim++) + NumberOfSubgridZones[dim] = nint((TestGravitySubgridRight - TestGravitySubgridLeft) / + ((DomainRightEdge[dim] - DomainLeftEdge[dim]) / float(MetaData.TopGridDims[dim]))) * + RefineBy; + + if (NumberOfSubgridZones[0] > 0) + { + + /* create a new HierarchyEntry, attach to the top grid and fill it out */ + + HierarchyEntry *Subgrid = new HierarchyEntry; + TopGrid.NextGridNextLevel = Subgrid; + Subgrid->NextGridNextLevel = NULL; + Subgrid->NextGridThisLevel = NULL; + Subgrid->ParentGrid = &TopGrid; + + /* compute the dimensions and left/right edges for the subgrid */ + + for (dim = 0; dim < MetaData.TopGridRank; dim++) + { + SubgridDims[dim] = NumberOfSubgridZones[dim] + 2 * NumberOfGhostZones; + LeftEdge[dim] = TestGravitySubgridLeft; + RightEdge[dim] = TestGravitySubgridRight; + } + + /* create a new subgrid and initialize it */ + + Subgrid->GridData = new grid; + Subgrid->GridData->InheritProperties(TopGrid.GridData); + Subgrid->GridData->PrepareGrid(MetaData.TopGridRank, SubgridDims, + LeftEdge, RightEdge, 0); + if (Subgrid->GridData->TestGravityAPMInitializeGrid(TestGravityDensity * POW(float(RefineBy), MetaData.TopGridRank), + 0, TestGravityCentralParticlePosition, + TestGravityUseBaryons) == FAIL) + { + ENZO_FAIL("Error in TestGravityAPMInitializeGrid.\n"); + } + + /* Generate a static refine region. */ + + StaticRefineRegionLevel[0] = 0; + for (dim = 0; dim < MetaData.TopGridRank; dim++) + { + StaticRefineRegionLeftEdge[0][dim] = TestGravitySubgridLeft; + StaticRefineRegionRightEdge[0][dim] = TestGravitySubgridRight; + } + } + + /* set up field names and units */ + + int count = 0; + DataLabel[count++] = DensName; + DataLabel[count++] = TEName; + if (DualEnergyFormalism) + DataLabel[count++] = GEName; + DataLabel[count++] = Vel1Name; + DataLabel[count++] = Vel2Name; + DataLabel[count++] = Vel3Name; + + DataUnits[0] = NULL; + DataUnits[1] = NULL; + DataUnits[2] = NULL; + DataUnits[3] = NULL; + DataUnits[4] = NULL; + DataUnits[5] = NULL; + + /* Write parameters to parameter output file */ + + if (MyProcessorNumber == ROOT_PROCESSOR) + { + fprintf(Outfptr, "TestGravityDensity = %" FSYM "\n", + TestGravityDensity); + fprintf(Outfptr, "TestGravitySubgridLeft = %" GOUTSYM "\n", + TestGravitySubgridLeft); + fprintf(Outfptr, "TestGravitySubgridRight = %" GOUTSYM "\n", + TestGravitySubgridRight); + fprintf(Outfptr, "TestGravityNumberOfParticles = %" ISYM "\n", + TestGravityNumberOfParticles); + fprintf(Outfptr, "TestGravityUseBaryons = %" ISYM "\n\n", + TestGravityUseBaryons); + fprintf(Outfptr, "TestGravityCentralParticlePosition = % " ISYM "\n\n", + TestGravityUseBaryons); + fprintf(Outfptr, "TestGravityCentralParticlePosition = % " GOUTSYM " %" GOUTSYM " %" GOUTSYM "\n\n", + TestGravityCentralParticlePosition[0], + TestGravityCentralParticlePosition[1], + TestGravityCentralParticlePosition[2]); + } + + return SUCCESS; +} diff --git a/src/enzo/TestGravitySineWaveInitialize.C b/src/enzo/TestGravitySineWaveInitialize.C new file mode 100644 index 000000000..fb42c82f5 --- /dev/null +++ b/src/enzo/TestGravitySineWaveInitialize.C @@ -0,0 +1,225 @@ +/*********************************************************************** +/ +/ INITIALIZE A SINE WAVE DENSITY PROFILE TO TEST THE GRAVITY SOLVER +/ +/ written by: JC Passy +/ date: June, 2013 +/ +/ PURPOSE: +/ Set up a sine mass distribution to test the gravity solver. + +/ RETURNS: SUCCESS or FAIL +/ +************************************************************************/ + +// This routine intializes a new simulation based on the parameter file. +// + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "Hierarchy.h" +#include "TopGridData.h" + +/* function prototypes */ +void AddLevel(LevelHierarchyEntry *Array[], HierarchyEntry *Grid, int level); +int RebuildHierarchy(TopGridData *MetaData, + LevelHierarchyEntry *LevelArray[], int level); + +#define MAX_INITIAL_GRIDS 10 + +int TestGravitySineWaveInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, + TopGridData &MetaData) +{ + char *DensName = "Density"; + char *TEName = "TotalEnergy"; + char *GEName = "GasEnergy"; + char *Vel1Name = "x-velocity"; + char *Vel2Name = "y-velocity"; + char *Vel3Name = "z-velocity"; + char *GPotName = "Grav_Potential"; + + /* parameter declarations */ + + int NumberOfSubgridZones[MAX_DIMENSION], SubgridDims[MAX_DIMENSION]; + float LeftEdge[MAX_DIMENSION], RightEdge[MAX_DIMENSION]; + + /* local declarations */ + + char line[MAX_LINE_LENGTH]; + int i, dim, ret, SubgridsAreStatic; + + /* set default parameters */ + + float TestGravitySineWaveAmplitude = 1.0; + float TestGravitySineWavePeriod = 1.0; + float TestGravitySineWaveAngle = 0.0; // Inclination angle in degrees + int TestGravitySineWaveRefineAtStart = FALSE; + + /* Set default parameters: parameters, names and subgrid info */ + + int TestGravitySineWaveGridDimension[MAX_INITIAL_GRIDS][MAX_DIMENSION]; + int TestGravitySineWaveGridLevel[MAX_INITIAL_GRIDS]; + float TestGravitySineWaveGridLeftEdge[MAX_INITIAL_GRIDS][MAX_DIMENSION]; + float TestGravitySineWaveGridRightEdge[MAX_INITIAL_GRIDS][MAX_DIMENSION]; + + for (i = 0; i < MAX_INITIAL_GRIDS; i++) + TestGravitySineWaveGridLevel[i] = 1; + + for (dim = 0; dim < MetaData.TopGridRank; dim++) { + TestGravitySineWaveGridLeftEdge[0][dim] = DomainLeftEdge[dim]; + TestGravitySineWaveGridRightEdge[0][dim] = DomainRightEdge[dim]; + TestGravitySineWaveGridDimension[0][dim] = MetaData.TopGridDims[dim]; + } + + TestGravitySineWaveGridLevel[0] = 0; + + /* read input from file */ + + while (fgets(line, MAX_LINE_LENGTH, fptr) != NULL) { + + ret = 0; + + /* read parameters */ + ret += sscanf(line, "TestGravitySineWaveAmplitude = %"FSYM"", &TestGravitySineWaveAmplitude); + ret += sscanf(line, "TestGravitySineWavePeriod = %"FSYM"", &TestGravitySineWavePeriod); + ret += sscanf(line, "TestGravitySineWaveAngle = %"FSYM"", &TestGravitySineWaveAngle); + ret += sscanf(line, "TestGravitySineWaveRefineAtStart = %"ISYM"", &TestGravitySineWaveRefineAtStart); + + /* if the line is suspicious, issue a warning */ + + if (ret == 0 && strstr(line, "=") && strstr(line, "TestGravitySineWave") && + line[0] != '#' && MyProcessorNumber == ROOT_PROCESSOR) + fprintf(stderr, + "warning in TestGravitySineWaveInitialize.C: the following parameter line was not interpreted:\n%s\n", + line); + + } // end input from parameter file + + /* set the periodic boundaries */ + + for (dim = 0; dim < MetaData.TopGridRank; dim++) { + MetaData.LeftFaceBoundaryCondition[dim] = periodic; + MetaData.RightFaceBoundaryCondition[dim] = periodic; + } + + /* Set up grids from CollapseTestInitialize.C */ + + if ((MetaData.StaticHierarchy) && (TestGravitySineWaveRefineAtStart)) + ENZO_FAIL("Error in TestGravitySineWaveInitialize.C: StaticHierarchy = %"ISYM", TestGravitySiveWaveRefineAtStart = %"ISYM" \n"); + + SubgridsAreStatic = MetaData.StaticHierarchy; + + /* Initial grid */ + int level; + level = 0; + int TotalRefinement = nint(pow(FLOAT(RefineBy), TestGravitySineWaveGridLevel[level])); + if (TopGrid.GridData->TestGravitySineWaveInitializeGrid(TestGravitySineWaveAmplitude, + TestGravitySineWavePeriod, + TestGravitySineWaveAngle, + SubgridsAreStatic, + TotalRefinement, + level + ) == FAIL){ + ENZO_FAIL("Error in grid->TestGravitySineWaveInitializeGrid.\n"); + } + + /* Convert minimum initial overdensity for refinement to mass + (unless MinimumMass itself was actually set). */ + + if (MinimumMassForRefinement[0] == FLOAT_UNDEFINED) { + MinimumMassForRefinement[0] = MinimumOverDensityForRefinement[0]; + for (int dim = 0; dim < MetaData.TopGridRank; dim++) + MinimumMassForRefinement[0] *=(DomainRightEdge[dim]-DomainLeftEdge[dim])/ + float(MetaData.TopGridDims[dim]); + } + + /* If requested, refine the grid to the desired level. */ + + if (TestGravitySineWaveRefineAtStart) { + + /* Declare, initialize and fill out the LevelArray. */ + + LevelHierarchyEntry *LevelArray[MAX_DEPTH_OF_HIERARCHY]; + for (level = 0; level < MAX_DEPTH_OF_HIERARCHY; level++) + LevelArray[level] = NULL; + AddLevel(LevelArray, &TopGrid, 0); + + /* Add levels to the maximum depth or until no new levels are created, + and re-initialize the level after it is created. */ + + for (level = 0; level < MaximumRefinementLevel; level++) { + if (RebuildHierarchy(&MetaData, LevelArray, level) == FAIL) + ENZO_FAIL("Error in RebuildHierarchy.\n"); + + if (LevelArray[level+1] == NULL) + break; + LevelHierarchyEntry *Temp = LevelArray[level+1]; + while (Temp != NULL) { + TotalRefinement = nint(pow(FLOAT(RefineBy),TestGravitySineWaveGridLevel[level+1])); + if (Temp->GridData->TestGravitySineWaveInitializeGrid(TestGravitySineWaveAmplitude, + TestGravitySineWavePeriod, + TestGravitySineWaveAngle, + SubgridsAreStatic, + TotalRefinement, + level+1 + ) == FAIL){ + ENZO_FAIL("Error in grid->TurbulenceICMInitializeGrid.\n"); + } + Temp = Temp->NextGridThisLevel; + } + } /* end loop over levels */ + + /* Loop back from the bottom, restoring the consistency among levels. */ + + for (level = MaximumRefinementLevel; level > 0; level--) { + LevelHierarchyEntry *Temp = LevelArray[level]; + while (Temp != NULL) { + if (Temp->GridData->ProjectSolutionToParentGrid(*LevelArray[level-1]->GridData) == FAIL) + ENZO_FAIL("Error in grid->ProjectSolutionToParentGrid.\n"); + Temp = Temp->NextGridThisLevel; + } + } + + } /* End if (TestGravitySineWaveRefineAtStart) */ + + /* set up fields name and units */ + + int count = 0; + DataLabel[count++] = DensName; + DataLabel[count++] = TEName; + if (DualEnergyFormalism) + DataLabel[count++] = GEName; + DataLabel[count++] = Vel1Name; + DataLabel[count++] = Vel2Name; + DataLabel[count++] = Vel3Name; + if (WritePotential) + DataLabel[count++] = GPotName; + + DataUnits[0] = NULL; + DataUnits[1] = NULL; + DataUnits[2] = NULL; + DataUnits[3] = NULL; + DataUnits[4] = NULL; + DataUnits[5] = NULL; + DataUnits[6] = NULL; + + /* Write parameters to parameter output file */ + + if (MyProcessorNumber == ROOT_PROCESSOR) { + fprintf(Outfptr, "TestGravitySineWaveAmplitude = %"FSYM"\n", TestGravitySineWaveAmplitude); + fprintf(Outfptr, "TestGravitySineWavePeriod = %"FSYM"\n", TestGravitySineWavePeriod); + fprintf(Outfptr, "TestGravitySineWaveAngle = %"FSYM"\n", TestGravitySineWaveAngle); + fprintf(Outfptr, "\n"); + } + + return SUCCESS; +} diff --git a/src/enzo/TestGravitySphereAPMInitialize.C b/src/enzo/TestGravitySphereAPMInitialize.C new file mode 100644 index 000000000..e83f13d8d --- /dev/null +++ b/src/enzo/TestGravitySphereAPMInitialize.C @@ -0,0 +1,222 @@ +/*********************************************************************** +/ +/ INITIALIZE A GRAVITY TEST +/ +/ written by: Greg Bryan +/ date: September, 1995 +/ modified1: Jean-Claude Passy, June 2013 +/ +/ PURPOSE: +/ Set up a spherical mass distribution to test the gravity solver. +/ +/ UPDATE: Following tests performed in Passy & Bryan (2014). +/ Possible distributions are: +/ - uniform density (type 0) +/ - isothermal spere (type 1) +/ - Plummer sphere (type 2) +/ +/ RETURNS: SUCCESS or FAIL +/ +************************************************************************/ + +// This routine intializes a new simulation based on the parameter file. +// + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "Hierarchy.h" +#include "LevelHierarchy.h" +#include "TopGridData.h" + +void AddLevel(LevelHierarchyEntry *Array[], HierarchyEntry *Grid, int level); +int RebuildHierarchy(TopGridData *MetaData, + LevelHierarchyEntry *LevelArray[], int level); + +int TestGravitySphereAPMInitialize(FILE *fptr, FILE *Outfptr, + HierarchyEntry &TopGrid, TopGridData &MetaData) +{ + char *DensName = "Density"; + char *TEName = "TotalEnergy"; + char *GEName = "GasEnergy"; + char *Vel1Name = "x-velocity"; + char *Vel2Name = "y-velocity"; + char *Vel3Name = "z-velocity"; + char *GPotName = "Grav_Potential"; + + /* declarations */ + + char line[MAX_LINE_LENGTH]; + int dim, ret, level; + + /* Error check. */ + + if (!SelfGravity) + fprintf(stderr, "TestGravitySphere: gravity is off!?!"); + + /* set default parameters */ + + float TestGravitySphereInteriorDensity = 1.0; // density inside sphere + float TestGravitySphereExteriorDensity = tiny_number; // density outside sphere + float TestGravitySphereRadius = 0.1; + int TestGravitySphereType = 0; // uniform density + int TestGravitySphereUseBaryons = TRUE; + int TestGravitySphereRefineAtStart = FALSE; + FLOAT TestGravitySphereCenter[MAX_DIMENSION]; + for (dim = 0; dim < MAX_DIMENSION; dim++) + TestGravitySphereCenter[dim] = 0.5 * (DomainLeftEdge[dim] + DomainRightEdge[dim]); + + /* read input from file */ + + while (fgets(line, MAX_LINE_LENGTH, fptr) != NULL) + { + + ret = 0; + + /* read parameters */ + + ret += sscanf(line, "TestGravitySphereInteriorDensity = %" FSYM, + &TestGravitySphereInteriorDensity); + ret += sscanf(line, "TestGravitySphereExteriorDensity = %" FSYM, + &TestGravitySphereExteriorDensity); + ret += sscanf(line, "TestGravitySphereRadius = %" FSYM, + &TestGravitySphereRadius); + ret += sscanf(line, "TestGravitySphereType = %" ISYM, + &TestGravitySphereType); + ret += sscanf(line, "TestGravitySphereUseBaryons = %" ISYM, + &TestGravitySphereUseBaryons); + ret += sscanf(line, "TestGravitySphereRefineAtStart = %" ISYM, + &TestGravitySphereRefineAtStart); + ret += sscanf(line, "TestGravitySphereCenter = %" PSYM " %" PSYM " %" PSYM, + TestGravitySphereCenter, TestGravitySphereCenter + 1, TestGravitySphereCenter + 2); + + /* if the line is suspicious, issue a warning */ + + if (ret == 0 && strstr(line, "=") && strstr(line, "TestGravitySphere") && line[0] != '#') + fprintf(stderr, "warning: the following parameter line was not interpreted:\n%s\n", line); + + } // end input from parameter file + + /* set up grid */ + + if (TopGrid.GridData->TestGravitySphereAPMInitializeGrid(TestGravitySphereInteriorDensity, + TestGravitySphereExteriorDensity, + TestGravitySphereRadius, + TestGravitySphereType, + TestGravitySphereUseBaryons, + TestGravitySphereCenter) == FAIL) + { + ENZO_FAIL("Error in TestGravitySphereAPMInitializeGrid."); + } + + /* Convert minimum initial overdensity for refinement to mass + (unless MinimumMass itself was actually set). */ + + if (MinimumMassForRefinement[0] == FLOAT_UNDEFINED) + { + MinimumMassForRefinement[0] = MinimumOverDensityForRefinement[0]; + for (int dim = 0; dim < MetaData.TopGridRank; dim++) + MinimumMassForRefinement[0] *= (DomainRightEdge[dim] - DomainLeftEdge[dim]) / float(MetaData.TopGridDims[dim]); + } + + /* If requested, refine the grid to the desired level. */ + + if (TestGravitySphereRefineAtStart) + { + + /* Declare, initialize and fill out the LevelArray. */ + + LevelHierarchyEntry *LevelArray[MAX_DEPTH_OF_HIERARCHY]; + for (level = 0; level < MAX_DEPTH_OF_HIERARCHY; level++) + LevelArray[level] = NULL; + AddLevel(LevelArray, &TopGrid, 0); + + /* Add levels to the maximum depth or until no new levels are created, + and re-initialize the level after it is created. */ + + for (level = 0; level < MaximumRefinementLevel; level++) + { + if (RebuildHierarchy(&MetaData, LevelArray, level) == FAIL) + { + ENZO_FAIL("Error in RebuildHierarchy."); + } + if (LevelArray[level + 1] == NULL) + break; + LevelHierarchyEntry *Temp = LevelArray[level + 1]; + while (Temp != NULL) + { + if (Temp->GridData->TestGravitySphereAPMInitializeGrid(TestGravitySphereInteriorDensity, + TestGravitySphereExteriorDensity, + TestGravitySphereRadius, + TestGravitySphereType, + TestGravitySphereUseBaryons, + TestGravitySphereCenter) == FAIL) + { + ENZO_FAIL("Error in TestGravitySphereAPMInitializeGrid.") + } + Temp = Temp->NextGridThisLevel; + } + } // end: loop over levels + + /* Loop back from the bottom, restoring the consistency amoung levels. */ + + for (level = MaximumRefinementLevel; level > 0; level--) + { + LevelHierarchyEntry *Temp = LevelArray[level]; + while (Temp != NULL) + { + if (Temp->GridData->ProjectSolutionToParentGrid(*Temp->GridHierarchyEntry->ParentGrid->GridData) == FAIL) + ENZO_FAIL("Error in grid->ProjectSolutionToParentGrid."); + Temp = Temp->NextGridThisLevel; + } + } + } // end: if (TestGravitySphereRefineAtStart) + + /* set up field names and units */ + + int count = 0; + DataLabel[count++] = DensName; + DataLabel[count++] = TEName; + if (DualEnergyFormalism) + DataLabel[count++] = GEName; + DataLabel[count++] = Vel1Name; + DataLabel[count++] = Vel2Name; + DataLabel[count++] = Vel3Name; + if (WritePotential) + DataLabel[count++] = GPotName; + + for (int j = 0; j < count; j++) + DataUnits[j] = NULL; + + /* Write parameters to parameter output file */ + + if (MyProcessorNumber == ROOT_PROCESSOR) + { + fprintf(Outfptr, "TestGravitySphereInteriorDensity = %" ESYM "\n", + TestGravitySphereInteriorDensity); + fprintf(Outfptr, "TestGravitySphereExteriorDensity = %" ESYM "\n", + TestGravitySphereExteriorDensity); + fprintf(Outfptr, "TestGravitySphereRadius = %" FSYM "\n", + TestGravitySphereRadius); + fprintf(Outfptr, "TestGravitySphereType = %" ISYM "\n", + TestGravitySphereType); + fprintf(Outfptr, "TestGravitySphereUseBaryons = %" ISYM "\n", + TestGravitySphereUseBaryons); + fprintf(Outfptr, "TestGravitySphereRefineAtStart = %" ISYM "\n", + TestGravitySphereRefineAtStart); + fprintf(Outfptr, "TestGravitySphereCenter = % " GOUTSYM " %" GOUTSYM " %" GOUTSYM "\n\n", + TestGravitySphereCenter[0], + TestGravitySphereCenter[1], + TestGravitySphereCenter[2]); + } + + return SUCCESS; +} diff --git a/src/enzo/TestSelfForceInitialize.C b/src/enzo/TestSelfForceInitialize.C new file mode 100644 index 000000000..2297aa33d --- /dev/null +++ b/src/enzo/TestSelfForceInitialize.C @@ -0,0 +1,132 @@ +/*********************************************************************** +/ +/ INITIALIZE A SELFFORCE TEST +/ +/ written by: Jean-Claude Passy +/ date: June 2013 +/ modified1: +/ +/ PURPOSE: +/ +/ RETURNS: SUCCESS or FAIL +/ +************************************************************************/ + +// This routine intializes a new simulation based on the parameter file. +// + +#include +#include +#include +#include "ErrorExceptions.h" +#include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" +#include "Fluxes.h" +#include "GridList.h" +#include "ExternalBoundary.h" +#include "Grid.h" +#include "Hierarchy.h" +#include "TopGridData.h" + +int TestSelfForceInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, + TopGridData &MetaData) +{ + char *DensName = "Density"; + char *TEName = "TotalEnergy"; + char *GEName = "GasEnergy"; + char *Vel1Name = "x-velocity"; + char *Vel2Name = "y-velocity"; + char *Vel3Name = "z-velocity"; + + /* declarations */ + + char line[MAX_LINE_LENGTH]; + int dim, ret; + int NumberOfSubgridZones[MAX_DIMENSION], SubgridDims[MAX_DIMENSION]; + FLOAT LeftEdge[MAX_DIMENSION], RightEdge[MAX_DIMENSION]; + + /* Error check. */ + + if (!SelfGravity) + fprintf(stderr, "TestGravity: gravity is off!?!"); + + /* set default parameters */ + + float TestSelfForceDensity = 1.0; // density of central peak + + FLOAT TestSelfForcePartciclePositionX = 0.5; + FLOAT TestSelfForcePartciclePositionY = 0.5; + FLOAT TestSelfForcePartciclePositionZ = 0.5; + + FLOAT TestSelfForcePartcicleVelocityX = 0.0; + FLOAT TestSelfForcePartcicleVelocityY = 0.0; + FLOAT TestSelfForcePartcicleVelocityZ = 0.0; + + /* read input from file */ + + while (fgets(line, MAX_LINE_LENGTH, fptr) != NULL) { + + ret = 0; + + /* read parameters */ + + ret += sscanf(line, "TestSelfForceDensity = %"FSYM, &TestSelfForceDensity); + ret += sscanf(line, "TestSelfForcePartciclePosition = %"PSYM" %"PSYM" %"PSYM, + &TestSelfForcePartciclePositionX, + &TestSelfForcePartciclePositionY, + &TestSelfForcePartciclePositionZ); + ret += sscanf(line, "TestSelfForcePartcicleVelocity = %"PSYM" %"PSYM" %"PSYM, + &TestSelfForcePartcicleVelocityX, + &TestSelfForcePartcicleVelocityY, + &TestSelfForcePartcicleVelocityZ); + + /* if the line is suspicious, issue a warning */ + + if (ret == 0 && strstr(line, "=") && strstr(line, "TestSelfForce") + && line[0] != '#') + fprintf(stderr, "warning: the following parameter line was not interpreted:\n%s\n", line); + + } // end input from parameter file + + /* set up grid */ + + if (TopGrid.GridData->TestSelfForceInitializeGrid(TestSelfForceDensity,1, + TestSelfForcePartciclePositionX, + TestSelfForcePartciclePositionY, + TestSelfForcePartciclePositionZ, + TestSelfForcePartcicleVelocityX, + TestSelfForcePartcicleVelocityY, + TestSelfForcePartcicleVelocityZ + ) == FAIL) + ENZO_FAIL("Error in TestSelfForceInitializeGrid.\n"); + + /* set up field names and units */ + + int count = 0; + DataLabel[count++] = DensName; + DataLabel[count++] = TEName; + if (DualEnergyFormalism) + DataLabel[count++] = GEName; + DataLabel[count++] = Vel1Name; + DataLabel[count++] = Vel2Name; + DataLabel[count++] = Vel3Name; + + DataUnits[0] = NULL; + DataUnits[1] = NULL; + DataUnits[2] = NULL; + DataUnits[3] = NULL; + DataUnits[4] = NULL; + DataUnits[5] = NULL; + + /* Write parameters to parameter output file */ + + if (MyProcessorNumber == ROOT_PROCESSOR) { + + fprintf(Outfptr, "TestSelfForceDensity = %"FSYM"\n", + TestSelfForceDensity); + } + + return SUCCESS; + +} diff --git a/src/enzo/WriteParameterFile.C b/src/enzo/WriteParameterFile.C index 24891d836..f6f5d7f54 100644 --- a/src/enzo/WriteParameterFile.C +++ b/src/enzo/WriteParameterFile.C @@ -12,11 +12,11 @@ / RETURNS: SUCCESS or FAIL / ************************************************************************/ - + // This routine writes the parameter file in the argument and sets parameters // based on it. -#include "preincludes.h" +#include "preincludes.h" #include #include "macros_and_parameters.h" #include "typedefs.h" @@ -27,9 +27,9 @@ #include "Grid.h" #include "TopGridData.h" #include "ActiveParticle.h" - + /* function prototypes */ - + void WriteListOfFloats(FILE *fptr, int N, FLOAT floats[]); void WriteListOfFloats(FILE *fptr, int N, float floats[]); void WriteListOfInts(FILE *fptr, int N, int nums[]); @@ -46,17 +46,17 @@ int WritePhotonSources(FILE *fptr, FLOAT CurrentTime); int GrackleWriteParameters(FILE *fptr); int UpdateLocalDatabase(TopGridData &MetaData, int CurrentTimeID, char *dset_uuid, char *Filename); - + int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) { - + MustRefineParticlesMinimumMass *= POW(1/(float(MetaData.TopGridDims[0]) *POW(float(RefineBy), float(MustRefineParticlesRefineToLevel))),3); int dim; - + /* Compute Units. */ - + float DensityUnits = 1, LengthUnits = 1, TemperatureUnits = 1, TimeUnits = 1, VelocityUnits = 1; double MassUnits = 1; @@ -64,7 +64,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) &TimeUnits, &VelocityUnits, &MassUnits, MetaData.Time) == FAIL) { ENZO_FAIL("Error in GetUnits.\n"); } - + float rhou = 1.0, lenu = 1.0, tempu = 1.0, tu = 1.0, velu = 1.0, presu = 1.0; double massu = 1.0; if (UsePhysicalUnit) { @@ -75,7 +75,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) MustRefineParticlesMinimumMass *= massu; StarMakerOverDensityThreshold *= rhou; // StarEnergyFeedbackRate = StarEnergyFeedbackRate/pow(LengthUnits,2)*pow(TimeUnits,3); - + if (SinkMergeDistance > 1.0) SinkMergeDistance *= lenu; SmallRho *= rhou; @@ -94,12 +94,12 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) } */ - /* Check ReadParameterFile for the reason why this is commented out. + /* Check ReadParameterFile for the reason why this is commented out. - Ji-hoon Kim in Apr.2010 */ /* if (!ComovingCoordinates && UsePhysicalUnit) { for (int i = 0; i < MAX_FLAGGING_METHODS; i++) { - if (MinimumOverDensityForRefinement[i] != FLOAT_UNDEFINED) + if (MinimumOverDensityForRefinement[i] != FLOAT_UNDEFINED) MinimumOverDensityForRefinement[i] *= rhou; } } @@ -109,13 +109,13 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) /* write data to Parameter output file */ - + /* write MetaData parameters */ - + fprintf(fptr, "InitialCycleNumber = %"ISYM"\n", MetaData.CycleNumber); fprintf(fptr, "InitialTime = %"GOUTSYM"\n", MetaData.Time); fprintf(fptr, "InitialCPUTime = %"GSYM"\n\n", MetaData.CPUTime); - + fprintf(fptr, "CheckpointRestart = %"ISYM"\n", CheckpointRestart); fprintf(fptr, "StopTime = %"GOUTSYM"\n", MetaData.StopTime); fprintf(fptr, "StopCycle = %"ISYM"\n", MetaData.StopCycle); @@ -123,7 +123,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "StopCPUTime = %lg\n", MetaData.StopCPUTime); fprintf(fptr, "ResubmitOn = %"ISYM"\n", MetaData.ResubmitOn); fprintf(fptr, "ResubmitCommand = %s\n\n", MetaData.ResubmitCommand); - + fprintf(fptr, "MaximumTopGridTimeStep = %"GSYM"\n", MetaData.MaximumTopGridTimeStep); fprintf(fptr, "TimeLastRestartDump = %"GSYM"\n", MetaData.TimeLastRestartDump); @@ -132,7 +132,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "dtDataDump = %"GOUTSYM"\n", MetaData.dtDataDump); fprintf(fptr, "TimeLastHistoryDump = %"GOUTSYM"\n", MetaData.TimeLastHistoryDump); fprintf(fptr, "dtHistoryDump = %"GOUTSYM"\n\n", MetaData.dtHistoryDump); - + fprintf(fptr, "TracerParticleOn = %"ISYM"\n", TracerParticleOn); fprintf(fptr, "TracerParticleOutputVelocity = %"ISYM"\n", TracerParticleOutputVelocity); @@ -140,11 +140,11 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) MetaData.TimeLastTracerParticleDump); fprintf(fptr, "dtTracerParticleDump = %"GOUTSYM"\n", MetaData.dtTracerParticleDump); - fprintf(fptr, "TimeLastInterpolatedDataDump = %"GOUTSYM"\n", + fprintf(fptr, "TimeLastInterpolatedDataDump = %"GOUTSYM"\n", MetaData.TimeLastInterpolatedDataDump); - fprintf(fptr, "dtInterpolatedDataDump = %"GOUTSYM"\n", + fprintf(fptr, "dtInterpolatedDataDump = %"GOUTSYM"\n", MetaData.dtInterpolatedDataDump); - + fprintf(fptr, "NewMovieLeftEdge = "); WriteListOfFloats(fptr, MetaData.TopGridRank, MetaData.NewMovieLeftEdge); fprintf(fptr, "NewMovieRightEdge = "); @@ -205,20 +205,20 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "HierarchyFileInputFormat = %"ISYM"\n", HierarchyFileInputFormat); fprintf(fptr, "HierarchyFileOutputFormat = %"ISYM"\n", HierarchyFileOutputFormat); - + fprintf(fptr, "RestartDumpNumber = %"ISYM"\n", MetaData.RestartDumpNumber); fprintf(fptr, "DataDumpNumber = %"ISYM"\n", MetaData.DataDumpNumber); fprintf(fptr, "HistoryDumpNumber = %"ISYM"\n", MetaData.HistoryDumpNumber); fprintf(fptr, "TracerParticleDumpNumber = %"ISYM"\n", MetaData.TracerParticleDumpNumber); - + fprintf(fptr, "RestartDumpName = %s\n", MetaData.RestartDumpName); fprintf(fptr, "DataDumpName = %s\n", MetaData.DataDumpName); fprintf(fptr, "HistoryDumpName = %s\n", MetaData.HistoryDumpName); fprintf(fptr, "TracerParticleDumpName = %s\n", MetaData.TracerParticleDumpName); fprintf(fptr, "RedshiftDumpName = %s\n\n", MetaData.RedshiftDumpName); - + if (MetaData.RestartDumpDir != NULL) fprintf(fptr, "RestartDumpDir = %s\n", MetaData.RestartDumpDir); if (MetaData.DataDumpDir != NULL) @@ -229,12 +229,12 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "TracerParticleDumpDir = %s\n", MetaData.TracerParticleDumpDir); if (MetaData.RedshiftDumpDir != NULL) fprintf(fptr, "RedshiftDumpDir = %s\n\n", MetaData.RedshiftDumpDir); - + if (MetaData.LocalDir != NULL) fprintf(fptr, "LocalDir = %s\n", MetaData.LocalDir); if (MetaData.GlobalDir != NULL) fprintf(fptr, "GlobalDir = %s\n", MetaData.GlobalDir); - + for (dim = 0; dim < MAX_CUBE_DUMPS; dim++) if (CubeDumps[dim] != NULL) fprintf(fptr, "CubeDump[%"ISYM"] = %s\n", dim, CubeDumps[dim]); @@ -245,7 +245,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "LoadBalancingCycleSkip = %"ISYM"\n", LoadBalancingCycleSkip); fprintf(fptr, "LoadBalancingMinLevel = %"ISYM"\n", LoadBalancingMinLevel); fprintf(fptr, "LoadBalancingMaxLevel = %"ISYM"\n", LoadBalancingMaxLevel); - + fprintf(fptr, "ConductionDynamicRebuildHierarchy = %"ISYM"\n", ConductionDynamicRebuildHierarchy); fprintf(fptr, "ConductionDynamicRebuildMinLevel = %"ISYM"\n", ConductionDynamicRebuildMinLevel); for (dim = 0;dim < MAX_DEPTH_OF_HIERARCHY;dim++) { @@ -267,18 +267,18 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "TimeActionParameter[%"ISYM"] = %"GSYM"\n", dim, TimeActionParameter[dim]); } - + fprintf(fptr, "StaticHierarchy = %"ISYM"\n", MetaData.StaticHierarchy); - + fprintf(fptr, "TopGridRank = %"ISYM"\n", MetaData.TopGridRank); fprintf(fptr, "TopGridDimensions = "); WriteListOfInts(fptr, MetaData.TopGridRank, MetaData.TopGridDims); fprintf(fptr, "\n"); - + fprintf(fptr, "TopGridGravityBoundary = %"ISYM"\n", MetaData.GravityBoundary); #ifdef TRANSFER - if (MetaData.RadHydroParameterFname != NULL) + if (MetaData.RadHydroParameterFname != NULL) fprintf(fptr, "RadHydroParamfile = %s\n", MetaData.RadHydroParameterFname); #endif fprintf(fptr, "ImplicitProblem = %"ISYM"\n", ImplicitProblem); @@ -291,7 +291,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "ParticleBoundaryType = %"ISYM"\n",MetaData.ParticleBoundaryType); fprintf(fptr, "NumberOfParticles = %"PISYM" (do not modify)\n", MetaData.NumberOfParticles); - + fprintf(fptr, "CourantSafetyNumber = %"FSYM"\n", MetaData.CourantSafetyNumber); fprintf(fptr, "PPMFlatteningParameter = %"ISYM"\n", @@ -300,9 +300,9 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) MetaData.PPMDiffusionParameter); fprintf(fptr, "PPMSteepeningParameter = %"ISYM"\n\n", MetaData.PPMSteepeningParameter); - + /* write global Parameters */ - + fprintf(fptr, "ProblemType = %"ISYM"\n", ProblemType); #ifdef NEW_PROBLEM_TYPES fprintf(fptr, "ProblemTypeName = %s\n", ProblemTypeName); @@ -312,7 +312,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "tiny_number = %e\n", tiny_number); fprintf(fptr, "Gamma = %"GSYM"\n", Gamma); fprintf(fptr, "PressureFree = %"ISYM"\n", PressureFree); - /* FDM: write FDM parameters */ + /* FDM: write FDM parameters */ fprintf(fptr, "QuantumPressure = %"ISYM"\n", QuantumPressure); fprintf(fptr, "FDMMass = %"FSYM"\n", FDMMass); @@ -352,7 +352,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "ConservativeInterpolation = %"ISYM"\n", ConservativeInterpolation); fprintf(fptr, "MinimumEfficiency = %"GSYM"\n", MinimumEfficiency); fprintf(fptr, "SubgridSizeAutoAdjust = %"ISYM"\n", SubgridSizeAutoAdjust); - fprintf(fptr, "OptimalSubgridsPerProcessor = %"ISYM"\n", + fprintf(fptr, "OptimalSubgridsPerProcessor = %"ISYM"\n", OptimalSubgridsPerProcessor); fprintf(fptr, "MinimumSubgridEdge = %"ISYM"\n", MinimumSubgridEdge); fprintf(fptr, "MaximumSubgridSize = %"ISYM"\n", MaximumSubgridSize); @@ -360,17 +360,17 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "NumberOfBufferZones = %"ISYM"\n\n", NumberOfBufferZones); - fprintf(fptr, "FastSiblingLocatorEntireDomain = %"ISYM"\n", + fprintf(fptr, "FastSiblingLocatorEntireDomain = %"ISYM"\n", FastSiblingLocatorEntireDomain); - fprintf(fptr, "MustRefineRegionMinRefinementLevel = %"ISYM"\n", + fprintf(fptr, "MustRefineRegionMinRefinementLevel = %"ISYM"\n", MustRefineRegionMinRefinementLevel); - fprintf(fptr, "MetallicityRefinementMinLevel = %"ISYM"\n", + fprintf(fptr, "MetallicityRefinementMinLevel = %"ISYM"\n", MetallicityRefinementMinLevel); - fprintf(fptr, "MetallicityRefinementMinMetallicity = %"GSYM"\n", + fprintf(fptr, "MetallicityRefinementMinMetallicity = %"GSYM"\n", MetallicityRefinementMinMetallicity); - fprintf(fptr, "MetallicityRefinementMinDensity = %"GSYM"\n", + fprintf(fptr, "MetallicityRefinementMinDensity = %"GSYM"\n", MetallicityRefinementMinDensity); - + fprintf(fptr, "DomainLeftEdge = "); WriteListOfFloats(fptr, MetaData.TopGridRank, DomainLeftEdge); fprintf(fptr, "DomainRightEdge = "); @@ -438,11 +438,11 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "#TimeUnits = %"GOUTSYM"\n", TimeUnits); fprintf(fptr, "#TemperatureUnits = %"GOUTSYM"\n", TemperatureUnits); fprintf(fptr, "\n"); - + fprintf(fptr, "UniformGravity = %"ISYM"\n", UniformGravity); fprintf(fptr, "UniformGravityDirection = %"ISYM"\n", UniformGravityDirection); fprintf(fptr, "UniformGravityConstant = %"GSYM"\n", UniformGravityConstant); - + fprintf(fptr, "PointSourceGravity = %"ISYM"\n",PointSourceGravity); fprintf(fptr, "PointSourceGravityPosition = "); WriteListOfFloats(fptr, MetaData.TopGridRank, PointSourceGravityPosition); @@ -464,9 +464,9 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "DiskGravityDarkMatterR = %"GSYM"\n",DiskGravityDarkMatterR); fprintf(fptr, "DiskGravityDarkMatterDensity = %"GSYM"\n",DiskGravityDarkMatterDensity); - fprintf(fptr, "ExternalGravity = %"ISYM"\n",ExternalGravity); + fprintf(fptr, "ExternalGravity = %"ISYM"\n",ExternalGravity); fprintf(fptr, "ExternalGravityConstant = %"FSYM"\n",ExternalGravityConstant); - fprintf(fptr, "ExternalGravityRadius = %"FSYM"\n",ExternalGravityRadius); + fprintf(fptr, "ExternalGravityRadius = %"FSYM"\n",ExternalGravityRadius); fprintf(fptr, "ExternalGravityDensity = %"FSYM"\n",ExternalGravityDensity); fprintf(fptr, "ExternalGravityPosition = "); WriteListOfFloats(fptr, MetaData.TopGridRank, ExternalGravityPosition); @@ -475,6 +475,18 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "SelfGravity = %"ISYM"\n", SelfGravity); fprintf(fptr, "SelfGravityGasOff = %"ISYM"\n", SelfGravityGasOff); + + fprintf(fptr, "GravitySolverType = %"ISYM"\n", GravitySolverType); + fprintf(fptr, "APMAddParentContribution = %"ISYM"\n", APMAddParentContribution); + fprintf(fptr, "TimeSteppingRefinementCondition = %"ISYM"\n", + TimeSteppingRefinementCondition); + fprintf(fptr, "DepositAlsoParentGridAndSiblingsParticles = %"ISYM"\n", + DepositAlsoParentGridAndSiblingsParticles); + fprintf(fptr, "S2ParticleSize = %"GSYM"\n", S2ParticleSize); + fprintf(fptr, "GravityResolution = %"GSYM"\n", GravityResolution); + fprintf(fptr, "GreensFunctionMaxNumber = %"ISYM"\n", GreensFunctionMaxNumber); + fprintf(fptr, "GreensFunctionMaxSize = %"ISYM"\n", GreensFunctionMaxSize); + fprintf(fptr, "AccretionKernal = %"ISYM"\n", AccretionKernal); fprintf(fptr, "GravitationalConstant = %e\n", GravitationalConstant); @@ -485,19 +497,19 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "InlineHaloFinder = %"ISYM"\n", InlineHaloFinder); fprintf(fptr, "HaloFinderSubfind = %"ISYM"\n", HaloFinderSubfind); - fprintf(fptr, "HaloFinderCycleSkip = %"ISYM"\n", + fprintf(fptr, "HaloFinderCycleSkip = %"ISYM"\n", HaloFinderCycleSkip); - fprintf(fptr, "HaloFinderRunAfterOutput = %"ISYM"\n", + fprintf(fptr, "HaloFinderRunAfterOutput = %"ISYM"\n", HaloFinderRunAfterOutput); - fprintf(fptr, "HaloFinderOutputParticleList = %"ISYM"\n", + fprintf(fptr, "HaloFinderOutputParticleList = %"ISYM"\n", HaloFinderOutputParticleList); - fprintf(fptr, "HaloFinderMinimumSize = %"ISYM"\n", + fprintf(fptr, "HaloFinderMinimumSize = %"ISYM"\n", HaloFinderMinimumSize); fprintf(fptr, "HaloFinderLinkingLength = %"FSYM"\n", HaloFinderLinkingLength); fprintf(fptr, "HaloFinderTimestep = %"FSYM"\n", HaloFinderTimestep); - fprintf(fptr, "HaloFinderLastTime = %"PSYM"\n\n", + fprintf(fptr, "HaloFinderLastTime = %"PSYM"\n\n", HaloFinderLastTime); fprintf(fptr, "GalaxySimulationRPSWind = %"ISYM"\n",GalaxySimulationRPSWind); @@ -512,7 +524,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "GalaxySimulationPreWindTotalEnergy = %"GSYM"\n",GalaxySimulationPreWindTotalEnergy); fprintf(fptr, "GalaxySimulationPreWindVelocity = "); WriteListOfFloats(fptr, MetaData.TopGridRank, GalaxySimulationPreWindVelocity); - + fprintf(fptr, "DualEnergyFormalism = %"ISYM"\n", DualEnergyFormalism); fprintf(fptr, "DualEnergyFormalismEta1 = %e\n", DualEnergyFormalismEta1); fprintf(fptr, "DualEnergyFormalismEta2 = %e\n", DualEnergyFormalismEta2); @@ -601,7 +613,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "DustTemperatureEnd = %"FSYM"\n", RateData.DustTemperatureEnd); fprintf(fptr, "PhotoelectricHeating = %"ISYM"\n", PhotoelectricHeating); fprintf(fptr, "PhotoelectricHeatingRate = %"GSYM"\n", PhotoelectricHeatingRate); - + fprintf(fptr, "VelAnyl = %"ISYM"\n", VelAnyl); fprintf(fptr, "BAnyl = %"ISYM"\n", BAnyl); fprintf(fptr, "WriteExternalAccel = %"ISYM"\n", WriteExternalAccel); @@ -621,13 +633,13 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) if (OutputSmoothedDarkMatter < 0) fprintf(fptr, "OutputSmoothedDarkMatter = %"ISYM"\n", 0); else - fprintf(fptr, "OutputSmoothedDarkMatter = %"ISYM"\n", + fprintf(fptr, "OutputSmoothedDarkMatter = %"ISYM"\n", OutputSmoothedDarkMatter); - fprintf(fptr, "SmoothedDarkMatterNeighbors = %"ISYM"\n", + fprintf(fptr, "SmoothedDarkMatterNeighbors = %"ISYM"\n", SmoothedDarkMatterNeighbors); - fprintf(fptr, "OutputGriddedStarParticle = %"ISYM"\n", + fprintf(fptr, "OutputGriddedStarParticle = %"ISYM"\n", OutputGriddedStarParticle); - + fprintf(fptr, "ZEUSLinearArtificialViscosity = %"GSYM"\n", ZEUSLinearArtificialViscosity); fprintf(fptr, "ZEUSQuadraticArtificialViscosity = %"GSYM"\n", @@ -640,7 +652,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) RefineByJeansLengthSafetyFactor); fprintf(fptr, "JeansRefinementColdTemperature = %"FSYM"\n", JeansRefinementColdTemperature); - fprintf(fptr, "RefineByResistiveLengthSafetyFactor = %"FSYM"\n", + fprintf(fptr, "RefineByResistiveLengthSafetyFactor = %"FSYM"\n", RefineByResistiveLengthSafetyFactor); fprintf(fptr, "MustRefineParticlesRefineToLevel = %"ISYM"\n", MustRefineParticlesRefineToLevel); @@ -678,7 +690,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) ParticleSplitterMustRefineIDFile); fprintf(fptr, "ResetMagneticField = %"ISYM"\n", ResetMagneticField); - fprintf(fptr, "ResetMagneticFieldAmplitude = %"GSYM" %"GSYM" %"GSYM"\n", + fprintf(fptr, "ResetMagneticFieldAmplitude = %"GSYM" %"GSYM" %"GSYM"\n", ResetMagneticFieldAmplitude[0], ResetMagneticFieldAmplitude[1], ResetMagneticFieldAmplitude[2]); @@ -699,7 +711,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) MultiRefineRegionMaximumOuterLevel); fprintf(fptr, "MultiRefineRegionMinimumOuterLevel = %"ISYM"\n", MultiRefineRegionMinimumOuterLevel); - + for (int ireg = 0; ireg < MAX_STATIC_REGIONS; ireg++){ if (MultiRefineRegionGeometry[ireg] >= 0) { fprintf(fptr, "MultiRefineRegionMaximumLevel[%"ISYM"] = %"ISYM"\n", ireg, @@ -747,12 +759,12 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "\n"); } } - + fprintf(fptr, "ParallelRootGridIO = %"ISYM"\n", ParallelRootGridIO); fprintf(fptr, "ParallelParticleIO = %"ISYM"\n", ParallelParticleIO); fprintf(fptr, "Unigrid = %"ISYM"\n", Unigrid); fprintf(fptr, "UnigridTranspose = %"ISYM"\n", UnigridTranspose); - fprintf(fptr, "NumberOfRootGridTilesPerDimensionPerProcessor = %"ISYM"\n", + fprintf(fptr, "NumberOfRootGridTilesPerDimensionPerProcessor = %"ISYM"\n", NumberOfRootGridTilesPerDimensionPerProcessor); fprintf(fptr, "PartitionNestedGrids = %"ISYM"\n", PartitionNestedGrids); fprintf(fptr, "ExtractFieldsOnly = %"ISYM"\n", ExtractFieldsOnly); @@ -781,13 +793,13 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "SimpleConstantBoundary = %"ISYM"\n", SimpleConstantBoundary); #endif - + fprintf(fptr, "SlopeFlaggingFields =" " %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM"\n", - SlopeFlaggingFields[0], + SlopeFlaggingFields[0], SlopeFlaggingFields[1], - SlopeFlaggingFields[2], + SlopeFlaggingFields[2], SlopeFlaggingFields[3], SlopeFlaggingFields[4], SlopeFlaggingFields[5], @@ -805,9 +817,9 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "SecondDerivativeFlaggingFields =" " %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM"\n", - SecondDerivativeFlaggingFields[0], + SecondDerivativeFlaggingFields[0], SecondDerivativeFlaggingFields[1], - SecondDerivativeFlaggingFields[2], + SecondDerivativeFlaggingFields[2], SecondDerivativeFlaggingFields[3], SecondDerivativeFlaggingFields[4], SecondDerivativeFlaggingFields[5], @@ -894,15 +906,15 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) NumberOfParticleAttributes); /* Sink particles (for present day star formation) & winds */ - fprintf(fptr, "SinkMergeDistance = %"FSYM"\n", + fprintf(fptr, "SinkMergeDistance = %"FSYM"\n", SinkMergeDistance); - fprintf(fptr, "SinkMergeMass = %"FSYM"\n", + fprintf(fptr, "SinkMergeMass = %"FSYM"\n", SinkMergeMass); - fprintf(fptr, "StellarWindFeedback = %"ISYM"\n", + fprintf(fptr, "StellarWindFeedback = %"ISYM"\n", StellarWindFeedback); - fprintf(fptr, "StellarWindTurnOnMass = %"FSYM"\n", + fprintf(fptr, "StellarWindTurnOnMass = %"FSYM"\n", StellarWindTurnOnMass); - fprintf(fptr, "MSStellarWindTurnOnMass = %"FSYM"\n", + fprintf(fptr, "MSStellarWindTurnOnMass = %"FSYM"\n", MSStellarWindTurnOnMass); @@ -958,7 +970,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "SpeedOfLightTimeStepLimit = %"ISYM"\n", SpeedOfLightTimeStepLimit); fprintf(fptr, "IsothermalSoundSpeed = %"GSYM"\n",IsothermalSoundSpeed); - + fprintf(fptr, "StarClusterUseMetalField = %"ISYM"\n", StarClusterUseMetalField); fprintf(fptr, "StarClusterUnresolvedModel = %"ISYM"\n", @@ -1118,7 +1130,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "UsePhysicalUnit = %d\n", UsePhysicalUnit); fprintf(fptr, "UseFloor = %d\n", UseFloor); fprintf(fptr, "UseViscosity = %d\n", UseViscosity); - fprintf(fptr, "ViscosityCoefficient = %g\n", ViscosityCoefficient); + fprintf(fptr, "ViscosityCoefficient = %g\n", ViscosityCoefficient); fprintf(fptr, "UseAmbipolarDiffusion = %d\n", UseAmbipolarDiffusion); fprintf(fptr, "UseResistivity = %d\n", UseResistivity); fprintf(fptr, "SmallRho = %g\n", SmallRho); @@ -1129,7 +1141,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "EOSType = %d\n", EOSType); fprintf(fptr, "EOSSoundSpeed = %g\n", EOSSoundSpeed); fprintf(fptr, "EOSCriticalDensity = %g\n", EOSCriticalDensity); - fprintf(fptr, "EOSGamma = %g\n", EOSGamma); + fprintf(fptr, "EOSGamma = %g\n", EOSGamma); fprintf(fptr, "Mu = %g\n", Mu); fprintf(fptr, "DivBDampingLength = %g\n", DivBDampingLength); fprintf(fptr, "UseConstantAcceleration = %d\n", UseConstantAcceleration); @@ -1148,14 +1160,14 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "PoissonDivergenceCleaningBoundaryBuffer = %"ISYM"\n", PoissonDivergenceCleaningBoundaryBuffer); fprintf(fptr, "UsePoissonDivergenceCleaning = %"ISYM"\n", UsePoissonDivergenceCleaning); - fprintf(fptr, "PoissonDivergenceCleaningThreshold = %"GSYM"\n", + fprintf(fptr, "PoissonDivergenceCleaningThreshold = %"GSYM"\n", PoissonDivergenceCleaningThreshold); - fprintf(fptr, "PoissonApproximationThreshold = %"GSYM"\n", + fprintf(fptr, "PoissonApproximationThreshold = %"GSYM"\n", PoissonApproximationThreshold); - fprintf(fptr, "PoissonBoundaryType = %"ISYM"\n", + fprintf(fptr, "PoissonBoundaryType = %"ISYM"\n", PoissonBoundaryType); - /* Gas Drag */ + /* Gas Drag */ fprintf(fptr, "UseGasDrag = %"ISYM"\n",UseGasDrag); fprintf(fptr, "GasDragCoefficient = %"FSYM"\n",GasDragCoefficient); @@ -1166,7 +1178,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) fprintf(fptr, "ShearingBoxProblemType = %"ISYM"\n\n", ShearingBoxProblemType); /* write data which defines the boundary conditions */ - + fprintf(fptr, "LeftFaceBoundaryCondition = "); WriteListOfInts(fptr, MetaData.TopGridRank, (int*) MetaData.LeftFaceBoundaryCondition); @@ -1176,10 +1188,10 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) if (MetaData.BoundaryConditionName) fprintf(fptr, "BoundaryConditionName = %s\n\n", MetaData.BoundaryConditionName); - + /* If appropriate, write Cosmology data. */ - + if (ComovingCoordinates) { if (CosmologyWriteParameters(fptr, MetaData.StopTime, MetaData.Time) == FAIL) { @@ -1216,7 +1228,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) /* Change input physical parameters into code units */ StarMakerOverDensityThreshold /= rhou; - + if (SinkMergeDistance > 1.0) SinkMergeDistance /= lenu; SmallRho /= rhou; @@ -1236,7 +1248,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) /* if (!ComovingCoordinates && UsePhysicalUnit) { for (int i = 0; i < MAX_FLAGGING_METHODS; i++) { - if (MinimumOverDensityForRefinement[i] != FLOAT_UNDEFINED) + if (MinimumOverDensityForRefinement[i] != FLOAT_UNDEFINED) MinimumOverDensityForRefinement[i] /= rhou; } } @@ -1308,7 +1320,7 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) } /* write version info */ - + fprintf(fptr, "VersionNumber = %"FSYM"\n\n", VERSION); #ifdef USE_UUID diff --git a/src/enzo/ZeusSource.C b/src/enzo/ZeusSource.C index 8b2113085..88b1164a3 100644 --- a/src/enzo/ZeusSource.C +++ b/src/enzo/ZeusSource.C @@ -34,6 +34,8 @@ c #include #include "ErrorExceptions.h" #include "macros_and_parameters.h" +#include "typedefs.h" +#include "global_data.h" #include "fortran.def" #define IDX(a,b,c) ( ((c)*jn + (b))*in + (a) ) @@ -146,18 +148,31 @@ int ZeusSource(float *d, float *e, float *u, float *v, float *w, float *p, float /* Update velocities with acceleration */ if (gravity == 1) { + if (GravitySolverType == GRAVITY_SOLVER_FAST) { + for (i = is-2; i <= ie+3; i++) + u[IDX(i,j,k)] = u[IDX(i,j,k)] + dt*gr_xacc[IDX(i,j,k)]; - for (i = is-2; i <= ie+3; i++) - u[IDX(i,j,k)] = u[IDX(i,j,k)] + dt*gr_xacc[IDX(i,j,k)]; + if (rank > 1) + for (i = is-2; i <= ie+3; i++) + v[IDX(i,j,k)] = v[IDX(i,j,k)] + dt*gr_yacc[IDX(i,j,k)]; + + if (rank > 2) + for (i = is-2; i <= ie+3; i++) + w[IDX(i,j,k)] = w[IDX(i,j,k)] + dt*gr_zacc[IDX(i,j,k)]; + + } else if (GravitySolverType == GRAVITY_SOLVER_APM) { // APM + for (i = is-2; i <= ie+3; i++) + u[IDX(i,j,k)] = u[IDX(i,j,k)] + dt*0.5*(gr_xacc[IDX(i,j,k)]+gr_xacc[IDX(i-1,j,k)]); - if (rank > 1) - for (i = is-2; i <= ie+3; i++) - v[IDX(i,j,k)] = v[IDX(i,j,k)] + dt*gr_yacc[IDX(i,j,k)]; + if (rank > 1) + for (i = is-2; i <= ie+3; i++) + v[IDX(i,j,k)] = v[IDX(i,j,k)] + dt*0.5*(gr_yacc[IDX(i,j,k)]+gr_yacc[IDX(i,j-1,k)]); - if (rank > 2) - for (i = is-2; i <= ie+3; i++) - w[IDX(i,j,k)] = w[IDX(i,j,k)] + dt*gr_zacc[IDX(i,j,k)]; + if (rank > 2) + for (i = is-2; i <= ie+3; i++) + w[IDX(i,j,k)] = w[IDX(i,j,k)] + dt*0.5*(gr_zacc[IDX(i,j,k)]+gr_zacc[IDX(i,j,k-1)]); + } // end if (GravitySolverType == GRAVITY_SOLVER_FAST) } } // end: loop over j } // end: loop over k diff --git a/src/enzo/cic_deposit.F b/src/enzo/cic_deposit.F index 8add1fbd2..04e1cb118 100644 --- a/src/enzo/cic_deposit.F +++ b/src/enzo/cic_deposit.F @@ -78,7 +78,6 @@ subroutine cic_deposit(posx, posy, posz, ndim, npositions, c if (cloudsize .gt. cellsize) then write(6,*) "cloudsize > cellsize in cic_deposit!" - write(6,*) cloudsize, cellsize ERROR_MESSAGE endif c @@ -150,7 +149,8 @@ subroutine cic_deposit(posx, posy, posz, ndim, npositions, if (ndim .eq. 3) then c do n=1, npositions -c + + c Compute the position of the central cell c xpos = min(max((posx(n) - leftedge(1))*fact, half),edge1) @@ -162,12 +162,205 @@ subroutine cic_deposit(posx, posy, posz, ndim, npositions, i1 = int(xpos - shift,IKIND) + 1 j1 = int(ypos - shift,IKIND) + 1 k1 = int(zpos - shift,IKIND) + 1 -c + c Compute the weights c + + dx = min((REAL(i1,RKIND)+shift-xpos)*refine, 1.0_RKIND) + dy = min((REAL(j1,RKIND)+shift-ypos)*refine, 1.0_RKIND) + dz = min((REAL(k1,RKIND)+shift-zpos)*refine, 1.0_RKIND) + +c Interpolate from field into sumfield +c + field(i1 ,j1 ,k1 ) = field(i1 ,j1 ,k1 ) + + & mass(n)* dx * dy * dz + field(i1+1,j1 ,k1 ) = field(i1+1,j1 ,k1 ) + + & mass(n)*(1._RKIND-dx)* dy * dz + field(i1 ,j1+1,k1 ) = field(i1 ,j1+1,k1 ) + + & mass(n)* dx *(1._RKIND-dy)* dz + field(i1+1,j1+1,k1 ) = field(i1+1,j1+1,k1 ) + + & mass(n)*(1._RKIND-dx)*(1._RKIND-dy)* dz + field(i1 ,j1 ,k1+1) = field(i1 ,j1 ,k1+1) + + & mass(n)* dx * dy *(1._RKIND-dz) + field(i1+1,j1 ,k1+1) = field(i1+1,j1 ,k1+1) + + & mass(n)*(1._RKIND-dx)* dy *(1._RKIND-dz) + field(i1 ,j1+1,k1+1) = field(i1 ,j1+1,k1+1) + + & mass(n)* dx *(1._RKIND-dy)*(1._RKIND-dz) + field(i1+1,j1+1,k1+1) = field(i1+1,j1+1,k1+1) + + & mass(n)*(1._RKIND-dx)*(1._RKIND-dy)*(1._RKIND-dz) +c + + enddo + + endif +c + return +#endif + end + + +c======================================================================= +c/////////////////// SUBROUTINE CIC_DEPOSIT REJECT \\\\\\\\\\\\\\\\\\\\ +c + subroutine cic_deposit_reject(posx, posy, posz, ndim, npositions, + & mass, field, leftedge, + & dim1, dim2, dim3, cellsize, cloudsize, + & left_eff,start_eff,dim_eff) +#ifndef CONFIG_PFLOAT_16 +c +c PERFORMS 1/2/3D CLOUD-IN-CELL INTERPOLATION FROM FIELD TO SUMFIELD +c +c written by: JC Passy +c date: August, 2014 +c modified1: +c +c PURPOSE: Same as cic_deposit except that particles outside the EffectiveRegion +c +c INPUTS EXTRA: effectivestartindex - starting index of the grid +c +c EXTERNALS: +c +c LOCALS: +c +c----------------------------------------------------------------------- +c + implicit NONE +#include "fortran_types.def" +c +c----------------------------------------------------------------------- +c +c argument declarations +c + INTG_PREC dim1, dim2, dim3, npositions, ndim, + & start_eff(3), dim_eff(3) + P_PREC posx(npositions), posy(npositions), posz(npositions), + & leftedge(3), left_eff(3) + R_PREC mass(npositions), field(dim1, dim2, dim3), cellsize, + & cloudsize +c +c locals +c + INTG_PREC iii, jjj, kkk + INTG_PREC i1, j1, k1, n,i_eff,j_eff,k_eff + R_PREC xpos, ypos, zpos, dx, dy, dz,xpos_eff,ypos_eff,zpos_eff + P_PREC edge1, edge2, edge3, fact, shift, half, refine +c +c\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////// +c======================================================================= +c + +! write(0,*) npositions, leftedge, dim1, dim2, dim3, cellsize + + fact = 1._PKIND/cellsize + refine = cellsize/cloudsize + half = 0.5001_PKIND/refine + shift = 0.5_PKIND/refine + edge1 = REAL(dim1,PKIND) - half + edge2 = REAL(dim2,PKIND) - half + edge3 = REAL(dim3,PKIND) - half +c + if (cloudsize .gt. cellsize) then + write(6,*) "cloudsize > cellsize in cic_deposit!" + ERROR_MESSAGE + endif +c +c 1D +c + if (ndim .eq. 1) then +c + do n=1, npositions +c +c Compute the position of the central cell +c + xpos = min(max((posx(n) - leftedge(1))*fact, half), edge1) +c +c Convert this into an INTG_PREC index +c + i1 = int(xpos - shift,IKIND) + 1 +c +c Compute the weights +c + dx = min((REAL(i1,RKIND)+shift-xpos)*refine, 1.0_RKIND) +c +c Interpolate from field into sumfield +c + field(i1 ,1,1) = field(i1 ,1,1) + mass(n)*dx + field(i1+1,1,1) = field(i1+1,1,1) + mass(n)*(1._RKIND-dx) +c + enddo +c + endif +c +c 2D +c + if (ndim .eq. 2) then +c + do n=1, npositions +c +c Compute the position of the central cell +c + xpos = min(max((posx(n) - leftedge(1))*fact, half), edge1) + ypos = min(max((posy(n) - leftedge(2))*fact, half), edge2) +c +c Convert this into an INTG_PREC index +c + i1 = int(xpos - shift,IKIND) + 1 + j1 = int(ypos - shift,IKIND) + 1 +c +c Compute the weights +c + dx = min((REAL(i1,RKIND)+shift-xpos)*refine, 1.0_RKIND) + dy = min((REAL(j1,RKIND)+shift-ypos)*refine, 1.0_RKIND) +c +c Interpolate from field into sumfield +c + field(i1 ,j1 ,1) = field(i1 ,j1 ,1) + + & mass(n)* dx * dy + field(i1+1,j1 ,1) = field(i1+1,j1 ,1) + + & mass(n)*(1._RKIND-dx)* dy + field(i1 ,j1+1,1) = field(i1 ,j1+1,1) + + & mass(n)* dx *(1._RKIND-dy) + field(i1+1,j1+1,1) = field(i1+1,j1+1,1) + + & mass(n)*(1._RKIND-dx)*(1._RKIND-dy) +c + enddo +c + endif +c +c 3D +c + if (ndim .eq. 3) then +c + do n=1, npositions +c + + xpos = min(max((posx(n) - leftedge(1))*fact, half),edge1) + ypos = min(max((posy(n) - leftedge(2))*fact, half),edge2) + zpos = min(max((posz(n) - leftedge(3))*fact, half),edge3) + + i1 = int(xpos - shift,IKIND) + 1 + j1 = int(ypos - shift,IKIND) + 1 + k1 = int(zpos - shift,IKIND) + 1 + dx = min((REAL(i1,RKIND)+shift-xpos)*refine, 1.0_RKIND) dy = min((REAL(j1,RKIND)+shift-ypos)*refine, 1.0_RKIND) dz = min((REAL(k1,RKIND)+shift-zpos)*refine, 1.0_RKIND) + +c Effective positions + xpos_eff = (posx(n)-left_eff(1))*fact + ypos_eff = (posy(n)-left_eff(2))*fact + zpos_eff = (posz(n)-left_eff(3))*fact + + i_eff = int(xpos_eff + 0.5,IKIND) + j_eff = int(ypos_eff + 0.5,IKIND) + k_eff = int(zpos_eff + 0.5,IKIND) + + if (i_eff < start_eff(1) .or. i_eff >= dim_eff(1) .or. + & j_eff < start_eff(2) .or. j_eff >= dim_eff(2) .or. + & k_eff < start_eff(3) .or. k_eff >= dim_eff(3)) then +c write(6,*) 'REJECT' + goto 99 + endif c c Interpolate from field into sumfield c @@ -188,6 +381,9 @@ subroutine cic_deposit(posx, posy, posz, ndim, npositions, field(i1+1,j1+1,k1+1) = field(i1+1,j1+1,k1+1) + & mass(n)*(1._RKIND-dx)*(1._RKIND-dy)*(1._RKIND-dz) c + + 99 continue + enddo endif diff --git a/src/enzo/global_data.h b/src/enzo/global_data.h index 2a3029709..d1bee3434 100644 --- a/src/enzo/global_data.h +++ b/src/enzo/global_data.h @@ -11,7 +11,7 @@ / PURPOSE: / This is the global data, which should be held to a minimum. Any changes / in this file require changes in: WriteGlobalData, -/ ReadGlobalData and InitializeNew. +/ ReadGlobalData and InitializeNew. / This file is dual-purposed: / 1) read with DEFINE_STORAGE defined for the (single) definition / 2) read without DEFINE_STORAGE defined for external linkage @@ -48,7 +48,7 @@ EXTERN int PreviousMaxTask; EXTERN int LoadBalancingMinLevel; EXTERN int LoadBalancingMaxLevel; -/* FileDirectedOutput checks for file existence: +/* FileDirectedOutput checks for file existence: stopNow (writes, stops), outputNow, subgridcycleCount */ EXTERN int FileDirectedOutput; @@ -83,7 +83,7 @@ EXTERN int debug2; EXTERN int extract; /* Problem: 00 = None 01 = ShockTube - 02 = WavePool 03 = ShockPool + 02 = WavePool 03 = ShockPool 04 = Double-Mach reflection 05 = ShockInABox 06 = Implosion 07 = SedovBlast 08 = KelvinHelmholtz instability @@ -249,12 +249,12 @@ EXTERN char *DataUnits[MAX_NUMBER_OF_BARYON_FIELDS]; /* Region in which refinement is allowed (in problem space). */ -EXTERN FLOAT RefineRegionLeftEdge[MAX_DIMENSION], +EXTERN FLOAT RefineRegionLeftEdge[MAX_DIMENSION], RefineRegionRightEdge[MAX_DIMENSION]; EXTERN int RefineRegionAutoAdjust; EXTERN int MultiRefineRegion; -EXTERN FLOAT MultiRefineRegionLeftEdge[MAX_STATIC_REGIONS][MAX_DIMENSION], +EXTERN FLOAT MultiRefineRegionLeftEdge[MAX_STATIC_REGIONS][MAX_DIMENSION], MultiRefineRegionRightEdge[MAX_STATIC_REGIONS][MAX_DIMENSION]; EXTERN int MultiRefineRegionGeometry[MAX_STATIC_REGIONS]; EXTERN FLOAT MultiRefineRegionCenter[MAX_STATIC_REGIONS][MAX_DIMENSION]; @@ -297,6 +297,13 @@ EXTERN int SelfGravity; EXTERN int SelfGravityGasOff; EXTERN int AccretionKernal; +/* Gravity solvers and affiliated */ + +EXTERN int GravitySolverType; +EXTERN int APMAddParentContribution; // Add Acceleration/Potential from parent grid +EXTERN int TimeSteppingRefinementCondition; +EXTERN int DepositAlsoParentGridAndSiblingsParticles; + /* CopyGravPotential (TRUE or FALSE) */ EXTERN int CopyGravPotential; @@ -316,6 +323,17 @@ EXTERN int BaryonSelfGravityApproximation; EXTERN float GravitationalConstant; +/* S2 Particle size in top grid cell units (usually around 3). The S2 + particle is S(r) = A*(a/2-r) (if r < a/2, 0 otherwise). The constant + A depends on the dimension: 1D) 4/a^2, 2D) 24/(Pi*a^3) 3D) 48/(Pi*a^3). */ + +EXTERN float S2ParticleSize; + +/* Gravity resolution factor is a float indicating the comparative resolution + of the gravitational computation compared to the grid (1-2 or so). */ + +EXTERN float GravityResolution; + /* Flag to indicate if gravitational potential field should be computed and stored. */ @@ -326,13 +344,23 @@ EXTERN int ComputePotential; EXTERN int WritePotential; /* Parameter to control how particles in a subgrid are deposited in - the target grid. Options are: + the target grid. Options are: CIC_DEPOSIT - cloud in cell using cloud size equal to target grid size CIC_DEPOSIT_SMALL - CIC using cloud size equal to source grid size NGP_DEPOSIT - nearest grid point */ EXTERN int ParticleSubgridDepositMode; +/* Maximum number of GreensFunctions that will be stored in any time. + This number must be less than MAX_NUMBER_OF_GREENS_FUNCTIONS. */ + +EXTERN int GreensFunctionMaxNumber; + +/* Maximum number of words associated with GreensFunction storage + (Not currently implemented). */ + +EXTERN int GreensFunctionMaxSize; + /* Dual energy formalism (TRUE or FALSE). */ EXTERN int DualEnergyFormalism; @@ -451,25 +479,25 @@ EXTERN float CosmologySimulationUniformCR; // FIXME /* Shock Finding Method * 0: Off - default - * 1: temperature unsplit - * 2: temperature split + * 1: temperature unsplit + * 2: temperature split * 3: velocity unsplit * 4: velocity split */ -EXTERN int ShockMethod; +EXTERN int ShockMethod; EXTERN float ShockTemperatureFloor; EXTERN int StorePreShockFields; EXTERN int FindShocksOnlyOnOutput; -/* Type of radiation field. +/* Type of radiation field. 0 - none, 1 - Haardt & Madau alpha=-1.5 - 2 - H&M alpha = -1.8 + 2 - H&M alpha = -1.8 10 - homogenous internal radiation field (a la Renyue's work) */ EXTERN int RadiationFieldType; -EXTERN int AdjustUVBackground; -EXTERN int AdjustUVBackgroundHighRedshift; +EXTERN int AdjustUVBackground; +EXTERN int AdjustUVBackgroundHighRedshift; EXTERN float SetUVBAmplitude; EXTERN float SetHeIIHeatingScale; EXTERN RadiationFieldDataType RadiationData; @@ -618,7 +646,7 @@ EXTERN int SlopeFlaggingFields[MAX_FLAGGING_METHODS]; /* For CellFlaggingMethod = 2, The minimum refined mass for the ByMass refining scheme (Usually, user sets OverDensity and code sets MinimumMass but this can be - overridden by directely setting MinimumMass). + overridden by directely setting MinimumMass). The LevelExponent is used to change the minimum mass with level, the formula is MinimumMassForRefinement*pow(RefineBy, level*LevelExponent)*/ @@ -648,7 +676,7 @@ EXTERN float JeansRefinementColdTemperature; EXTERN int MustRefineParticlesRefineToLevel; /* For CellFlaggingMethod = 8, - The physical length (in pc) to which the must refine particles apply + The physical length (in pc) to which the must refine particles apply The above parameter will be automatically adjusted to match this length */ EXTERN int MustRefineParticlesRefineToLevelAutoAdjust; @@ -661,39 +689,39 @@ EXTERN float MustRefineParticlesMinimumMass; /* For CellFlaggingMethod = 8, region in which particles are flagged as MustRefine particles */ -EXTERN FLOAT MustRefineParticlesLeftEdge[MAX_DIMENSION], +EXTERN FLOAT MustRefineParticlesLeftEdge[MAX_DIMENSION], MustRefineParticlesRightEdge[MAX_DIMENSION]; /* For CellFlaggingMethod = 8, - binary switch that allows must refine particles to be created by the + binary switch that allows must refine particles to be created by the routines MustRefineParticlesFlagFromList or MustRefineParticlesFlagInRegion*/ EXTERN int MustRefineParticlesCreateParticles; -/* For CellFlaggingMethod = 9, - The minimum shear (roughly, dv accross two zones) required for +/* For CellFlaggingMethod = 9, + The minimum shear (roughly, dv accross two zones) required for refinement. */ EXTERN float MinimumShearForRefinement; -/* For CellFlaggingMethod = 9, +/* For CellFlaggingMethod = 9, Whether to use the old method for calculating shear refinement. */ EXTERN int OldShearMethod; /* For CellFlaggingMethod = 11, - The number of cells by which the Resistive length abs(B)/abs(curl(B)) + The number of cells by which the Resistive length abs(B)/abs(curl(B)) should be resolved. */ EXTERN float RefineByResistiveLengthSafetyFactor; -/* For CellFlaggingMethod = 14, +/* For CellFlaggingMethod = 14, Minimum mach number required for refinement. */ EXTERN float ShockwaveRefinementMinMach; EXTERN float ShockwaveRefinementMinVelocity; EXTERN int ShockwaveRefinementMaxLevel; -/* For CellFlaggingMethod = 15, +/* For CellFlaggingMethod = 15, Minimum second derivative required for refinement. */ EXTERN float MinimumSecondDerivativeForRefinement[MAX_FLAGGING_METHODS]; EXTERN int SecondDerivativeFlaggingFields[MAX_FLAGGING_METHODS]; @@ -811,7 +839,7 @@ EXTERN int MovieVertexCentered; EXTERN char *NewMovieName; EXTERN int NewMovieDumpNumber; EXTERN int NewMovieParticleOn; -EXTERN FLOAT *StarParticlesOnProcOnLvl_Position[128][3]; +EXTERN FLOAT *StarParticlesOnProcOnLvl_Position[128][3]; EXTERN float *StarParticlesOnProcOnLvl_Velocity[128][3], *StarParticlesOnProcOnLvl_Mass[128]; EXTERN float *StarParticlesOnProcOnLvl_Attr[128][MAX_NUMBER_OF_PARTICLE_ATTRIBUTES]; EXTERN int *StarParticlesOnProcOnLvl_Type[128]; @@ -913,7 +941,7 @@ EXTERN int NBodyDirectSummation; EXTERN int UseDrivingField; EXTERN float DrivingEfficiency; -/* Parameters to use CUDA extensions */ +/* Parameters to use CUDA extensions */ EXTERN int UseCUDA; /* End of Stanford block */ @@ -981,7 +1009,7 @@ EXTERN MPool::MemoryPool *PhotonMemoryPool; [2]: 1.0 -"- [3]: 2.0 -"- */ -EXTERN double EscapedPhotonCount[4]; +EXTERN double EscapedPhotonCount[4]; EXTERN double TotalEscapedPhotonCount[4]; EXTERN char *PhotonEscapeFilename; EXTERN int FieldsToInterpolate[MAX_NUMBER_OF_BARYON_FIELDS]; @@ -1016,7 +1044,7 @@ EXTERN int RadiativeTransferFLD; /* Implicit problem decision flag (only 0 through 3 work for now) 0 => do not use any implicit solver 1 => use the gFLDProblem module for single-group coupled FLD - 2 => use the FSProb module for free-streaming FLD radiation + 2 => use the FSProb module for free-streaming FLD radiation 3 => use the gFLDSplit module for single-group split FLD 4 => use the MFProb, multi-frequency fully implicit module 5 => use the MFSplit, multi-frequency split implicit module @@ -1103,23 +1131,23 @@ EXTERN int SpeedOfLightTimeStepLimit; // TRUE OR FALSE /* SMBH Feedback in galaxy clusters*/ EXTERN int ClusterSMBHFeedback; // TRUE OR FALSE -EXTERN float ClusterSMBHJetMdot; // JetMdot in SolarMass/yr -EXTERN float ClusterSMBHJetVelocity; // JetVelocity in km/s -EXTERN float ClusterSMBHJetRadius; // JetRadius in cellwidth +EXTERN float ClusterSMBHJetMdot; // JetMdot in SolarMass/yr +EXTERN float ClusterSMBHJetVelocity; // JetVelocity in km/s +EXTERN float ClusterSMBHJetRadius; // JetRadius in cellwidth EXTERN float ClusterSMBHJetLaunchOffset; //in cellwidth -EXTERN float ClusterSMBHStartTime; // in codeunits, usually is InitialTime of restart +EXTERN float ClusterSMBHStartTime; // in codeunits, usually is InitialTime of restart EXTERN float ClusterSMBHTramp; // in Myr -EXTERN float ClusterSMBHJetOpenAngleRadius; // in cellwidth -EXTERN float ClusterSMBHFastJetRadius; // FastJetRadius in cellwidth -EXTERN float ClusterSMBHFastJetVelocity; // FastJetVelocity in km/s -EXTERN float ClusterSMBHJetEdot; // Total feedback Edot in 10^44 ergs/s +EXTERN float ClusterSMBHJetOpenAngleRadius; // in cellwidth +EXTERN float ClusterSMBHFastJetRadius; // FastJetRadius in cellwidth +EXTERN float ClusterSMBHFastJetVelocity; // FastJetVelocity in km/s +EXTERN float ClusterSMBHJetEdot; // Total feedback Edot in 10^44 ergs/s EXTERN float ClusterSMBHKineticFraction; // fraction of kinetic feedback (0-1) EXTERN float ClusterSMBHJetAngleTheta; // from 0 to 1/2, in pi EXTERN float ClusterSMBHJetAnglePhi; // from 0 to 2, in pi EXTERN float ClusterSMBHJetPrecessionPeriod; //in Myr EXTERN int ClusterSMBHCalculateGasMass; // TRUE OR FALSE EXTERN int ClusterSMBHFeedbackSwitch; // TRUE OR FALSE -EXTERN float ClusterSMBHEnoughColdGas; // To turn jet on, in SolarMass +EXTERN float ClusterSMBHEnoughColdGas; // To turn jet on, in SolarMass EXTERN float ClusterSMBHAccretionTime; // Used only when CalculateGasMass=2 EXTERN int ClusterSMBHJetDim; // Jet dimension EXTERN float ClusterSMBHAccretionEpsilon; // Edot=epsilon*Mdot(accreted/removed)*c^2 @@ -1146,7 +1174,7 @@ EXTERN int MHDCTUseSpecificEnergy; EXTERN int WriteBoundary; EXTERN int WriteAcceleration; EXTERN int TracerParticlesAddToRestart;// forces addition of tracer particles to already initialized simulations -EXTERN int MHD_ProjectThisFace[3]; //Used for determining face projection/communication needs for +EXTERN int MHD_ProjectThisFace[3]; //Used for determining face projection/communication needs for //face centered fields EXTERN float CT_AthenaDissipation; EXTERN int MHD_WriteElectric; @@ -1182,7 +1210,7 @@ EXTERN int SmartStarStellarRadiativeFeedback; EXTERN float SmartStarFeedbackEnergyCoupling; EXTERN float SmartStarFeedbackJetsThresholdMass; EXTERN float SmartStarJetVelocity; -EXTERN float SmartStarSpin; +EXTERN float SmartStarSpin; EXTERN int SmartStarSuperEddingtonAdjustment; EXTERN float SmartStarSMSLifetime; @@ -1192,8 +1220,8 @@ EXTERN int TimingCycleSkip; // Frequency of timing data dumps. /* For the galaxy simulation boundary method */ EXTERN int GalaxySimulationRPSWind; /* GalaxySimulationRPSWind - * 0 - OFF - * 1 - Simple Shock w/ angle and delay + * 0 - OFF + * 1 - Simple Shock w/ angle and delay * 2 - Lookup table of density and velocity */ EXTERN float GalaxySimulationRPSWindShockSpeed; @@ -1205,7 +1233,7 @@ EXTERN float GalaxySimulationRPSWindVelocity[MAX_DIMENSION]; EXTERN float GalaxySimulationRPSWindPressure; EXTERN float GalaxySimulationPreWindDensity; -EXTERN float GalaxySimulationPreWindTotalEnergy; +EXTERN float GalaxySimulationPreWindTotalEnergy; EXTERN float GalaxySimulationPreWindVelocity[MAX_DIMENSION]; /* Supernova magnetic seed field */ diff --git a/src/enzo/macros_and_parameters.h b/src/enzo/macros_and_parameters.h index 4d5cb85df..054827f3d 100644 --- a/src/enzo/macros_and_parameters.h +++ b/src/enzo/macros_and_parameters.h @@ -12,14 +12,14 @@ #endif /*********************************************************************** -/ +/ / MACRO DEFINITIONS AND PARAMETERS / ************************************************************************/ #ifdef USE_PYTHON #ifndef ENZO_PYTHON_IMPORTED #define PY_ARRAY_UNIQUE_SYMBOL enzo_ARRAY_API -#define NO_IMPORT_ARRAY +#define NO_IMPORT_ARRAY #include #include "numpy/arrayobject.h" #endif @@ -80,7 +80,7 @@ #define MAX_REFINE_REGIONS 8000 -#ifdef WINDS +#ifdef WINDS #define MAX_NUMBER_OF_PARTICLE_ATTRIBUTES 7 #else #define MAX_NUMBER_OF_PARTICLE_ATTRIBUTES 4 @@ -108,6 +108,12 @@ #define NUMBER_ENZO_PARTICLE_TYPES 3 /* Dark Matter, Stars, Active Particles */ +#define FFT_SAFETY_FACTOR 2 /* at least 2 */ + +#define NUMBER_IN_ALIAS_SUM 1 + +#define MAX_NUMBER_OF_GREENS_FUNCTIONS 1000 + /* Unmodifiable Parameters */ #define MAX_DIMENSION 3 /* must be 3! */ @@ -405,10 +411,10 @@ typedef long long int HDF5_hid_t; #define ZERO_ALL_FIELDS 0 #define ZERO_UNDER_SUBGRID_FIELD 1 -/* Definitions for grid::CommunicationSend/ReceiveRegion and +/* Definitions for grid::CommunicationSend/ReceiveRegion and grid::DepositPositions */ //If MAX_EXTRA_OUTPUTS neesd to be changed, change statements in ReadParameterFile and WriteParameterFile. -#define MAX_EXTRA_OUTPUTS 10 +#define MAX_EXTRA_OUTPUTS 10 #define BARYONS_ELECTRIC -13 #define BARYONS_MAGNETIC -12 @@ -530,6 +536,11 @@ typedef long long int HDF5_hid_t; #define CIC_DEPOSIT_SMALL 1 #define NGP_DEPOSIT 2 +/* Gravity solver types */ + +#define GRAVITY_SOLVER_FAST 0 +#define GRAVITY_SOLVER_APM 1 + /* Star particle handling */ #define NORMAL_STAR 0 diff --git a/src/enzo/make_green.F b/src/enzo/make_green.F new file mode 100644 index 000000000..219ee9c5a --- /dev/null +++ b/src/enzo/make_green.F @@ -0,0 +1,266 @@ +c======================================================================= +c////////////////////// SUBROUTINE MAKE_GREEN \\\\\\\\\\\\\\\\\\\\\\\\ +c + subroutine make_green(green, nx, ny, nz, in, jn, kn, nalias, + & S2Part, refinement, + & S2Table, S2Min, S2Step, + & SinTable, SinMin, SinStep) +c +c COMPUTES OPTIMAL GREENS FUNCTION FOR TSC CLOUDS +c +c written by: Greg Bryan +c date: July, 1995 +c +c PURPOSE: Computes a greens function in k space for the isolated/periodic +c coloumb potential (on a grid). The resoluting function can +c be convolved in real space (i.e. multiplied in k-space) with +c the produce to produce a potential. This version uses the +c Hockney & Eastwood (Computer Simulation using Particles, 1980) +c optimal influence function technique (see also Eastwood and +c Brownrigg, J. Comp. Phys. 1979, 32, 24.) The influence function +c therefore depends on the other techniques used to solve for +c the gravitational force. Here we assume: +c I. The force is calculated by: Direct K-space solver +c Choices are: +c a) Direct k-space solver: D(k) = -ik +c b) A four point finite difference: +c D(k) = -2i* alpha *sin(kH/2)*cos(kH/2)/H - +c i*(1-alpha)*sin(kH )*cos(kH )/H +c c) A two point finite difference: +c D(k) = -2i*sin(kH/2)*cos(kH/2)/H +c II. The assignment scheme is: TSC +c Choices are: +c i) The NGP(p=1), CIC(p=2) or TSC(p=3) techniques: +c W(k) = (sin(kH/2)/(kH/2))^p +c NOTE: This routine assumes equal-sized zones. +c Define assignment scheme (NGP, CIC or TSC) +c Define a finite difference order (TWO_POINT_FD, FOUR_POINT_FD or +c DIRECT_KSPACE). +c The units used are such that when G(k) is multiplied by by +c d(k), the transformed density field, the result is the potential +c times the grid spacing (i.e. divide by the grid spacing to get +c the potential in the correct units). +c +c INPUTS: +c i,j,kn = real dimensions of green +c nalias = number of aliases in sum (-nalias -> +nalias) +c nx,ny,nz = active dimensions of green +c refinement = refinement factor +c S2Part = S2 particle size in grid zones +c S2Table = Table of precomputed S2 values +c S2Min = minimum x value in S2Table +c S2Step = x step in S2Table +c SinTable = Table of precomputed Sin values +c SinMin = minimum x value in SinTable +c SinStep = x step in SinTable +c +c Outputs: +c green = Greens function +c +c LOCALS: +c num_dim = number of dimensions to be used for force law +c nx,y,zmid = midpoint (+1) of the grid in each axis +c nx,y,zd2 = number of grid points divided by 2 for each axis +c +c EXTERNALS: +c +c----------------------------------------------------------------------- +c + implicit NONE +#include "fortran_types.def" +c +c arguments +c + integer in, jn, kn, nalias, nx, ny, nz, refinement + real*8 S2Min, S2Part, S2Step, SinMin, SinStep + real*8 S2Table(1), SinTable(1), green(nx/2+1, jn, kn) +c +c locals +c + integer bi, bj, bk, index, i, j, k, ii, jj, kk, + & naliasx, naliasy, naliasz, nxmid, nymid, nzmid + real*8 dksqr, keta2, kfact, kmod, rk, sk, sktop, twopi + real*8 k1, k2, k3, kx, kxbern, ky, kybern, kz, kzbern, + & sinx2, siny2, sinz2, sinxb, sinyb, sinzb, + & usqr1, usqr2, usqr3, usqrx, usqry, usqrz +c +c Define table lookup function +c + real*8 Table1, Table2, Step, Min, Tablex, TableLookUp + integer Tablei + TableLookUp(Table1, Table2, Step, Min, Tablei, Tablex) = + & Table1 + (Tablex - real(Tablei-1)*Step - Min) + & / Step * (Table2 - Table1) +c +c\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////// +c======================================================================= +c +c Set constants +c + twopi = 8.0*atan(1.0) +c +c Set maximum wavenumbers in the positive direction +c + nxmid = max(nx/2 + 1, 1) + nymid = max(ny/2 + 1, 1) + nzmid = max(nz/2 + 1, 1) +c +c Set number of aliases for each dimension +c + naliasx = nalias + naliasy = nalias + naliasz = nalias + if (nx .eq. 1) naliasx = 0 + if (ny .eq. 1) naliasy = 0 + if (nz .eq. 1) naliasz = 0 +c +c Loop over all wavenumbers and compute optimal influence function. +c First, compute SUM[U^2] (e.q. 8-45) +c + do k = 1, nz + kk = k-1 + if (k .gt. nzmid) kk = kk - nz + kz = real(kk)*twopi/real(nz) + index = int((0.5*kz - SinMin)/SinStep) + sinz2 = TableLookUp(SinTable(index), SinTable(index+1), + & SinStep, SinMin, index, 0.5*kz) +c write (6,*) sinz2, sin(0.5*kz), sinz2/sin(0.5*kz) + usqrz = 1.0 - sinz2**2 + 2.0/15.0*sinz2**4 + if (k .eq. 1) usqrz = 1.0 +c + do j = 1, ny + jj = j-1 + if (j .gt. nymid) jj = jj - ny + ky = real(jj)*twopi/real(ny) + index = int((0.5*ky - SinMin)/SinStep) + siny2 = TableLookUp(SinTable(index), SinTable(index+1), + & SinStep, SinMin, index, 0.5*ky) + usqry = 1.0 - siny2**2 + 2.0/15.0*siny2**4 + if (j .eq. 1) usqry = 1.0 +c + do i = 1, nxmid + ii = i-1 + kx = real(ii)*twopi/real(nx) + index = int((0.5*kx - SinMin)/SinStep) + sinx2 = TableLookUp(SinTable(index), SinTable(index+1), + & SinStep, SinMin, index, 0.5*kx) + usqrx = 1.0 - sinx2**2 + 2.0/15.0*sinx2**4 + if (i .eq. 1) usqrx = 1.0 +c +c Compute D^2 (eq. 8-46) +c + dksqr = kx**2 + ky**2 + kz**2 + if (dksqr .eq. 0.0) dksqr = 1.0 +c +c Clear vector sum +c + k1 = 0.0 + k2 = 0.0 + k3 = 0.0 +c +c Sum over Bernoulli (sp?) zones (c.f. eq. 8-22) +c + do bk = -naliasz, naliasz + kzbern = kz + twopi*real(bk) + do bj = -naliasy, naliasy + kybern = ky + twopi*real(bj) + do bi = -naliasx, naliasx + kxbern = kx + twopi*real(bi) +c +c Compute the modulus of k +c + kmod = sqrt(kxbern**2 + kybern**2 + kzbern**2) + if (kmod .eq. 0.0) kmod = 1.0 +c +c Compute Sk (eq. 8-41) +c + keta2 = 0.5*kmod*S2part + index = int((keta2 - S2Min)/S2Step) + sk = TableLookUp(S2Table(index), + & S2Table(index+1), S2Step, S2Min, index, keta2) + sk = sk**2 +c +c Compute R(k), the reference force +c + rk = 1.0/kmod**2 +c +c If this is a subgrid, compute Sk for the larger +c S2 particle size +c + if (refinement .ne. 1) then + keta2 = 0.5*kmod*S2Part*real(refinement) + index = int((keta2 - S2Min)/S2Step) + sktop = TableLookUp(S2Table(index), + & S2Table(index+1), S2Step, + & S2Min, index, keta2) + sk = (sk - sktop**2) + endif +c +c Lookup sin values (for next step). +c +c if (min(kxbern,kybern,kzbern) .lt. SinMin) then +c write (6,*) 'make_green: out of range:', +c & kxbern, kybern, kzbern +c stop +c endif + index = int((0.5*kxbern - SinMin)/SinStep) + sinxb = TableLookUp(SinTable(index), + & SinTable(index+1), SinStep, + & SinMin, index, 0.5*kxbern) + index = int((0.5*kybern - SinMin)/SinStep) + sinyb = TableLookUp(SinTable(index), + & SinTable(index+1), SinStep, + & SinMin, index, 0.5*kybern) + index = int((0.5*kzbern - SinMin)/SinStep) + sinzb = TableLookUp(SinTable(index), + & SinTable(index+1), SinStep, + & SinMin, index, 0.5*kzbern) +c +c Compute U^2 (eq. 8-42) +c + usqr1 = sinxb/(0.5*kxbern + tiny) + usqr2 = sinyb/(0.5*kybern + tiny) + usqr3 = sinzb/(0.5*kzbern + tiny) + if (kxbern .eq. 0.0) usqr1 = 1.0 + if (kybern .eq. 0.0) usqr2 = 1.0 + if (kzbern .eq. 0.0) usqr3 = 1.0 +c +c Combine and sum (part of HE, eq. 8-22) +c + kfact = sk*rk*(usqr1*usqr2*usqr3)**6 +c + k1 = k1 + kxbern*kfact + k2 = k2 + kybern*kfact + k3 = k3 + kzbern*kfact +c + enddo + enddo + enddo +c +c Compute G(k) (eq. 8-22) (k1,2,3 is SUM[U^2 R(k)]) +c + green(i,j,k) = -(k1*kx + k2*ky + k3*kz) + & /(dksqr*(usqrx*usqry*usqrz)**2) +c +c Approximate (poor man''s) greens function +c +c#define APPROXIMATE_GREENS_FUNCTION +#ifdef APPROXIMATE_GREENS_FUNCTION +c + green(i,j,k) = -1.0/(kx**2 + ky**2 + kz**2 + tiny) + if (real(ii*ii + jj*jj + kk*kk) .gt. + & 0.5*max(nx, ny, nz)**2) green(i,j,k) = 0.0 +c +#endif /* APPROXIMATE_GREENS_FUNCTION */ +c + enddo + enddo + enddo +c +c Clear the zero wavenumber position +c + green(1,1,1) = 0.0 +c green(1,1,1) = 1.0 +c + return + end diff --git a/src/enzo/prolong.F b/src/enzo/prolong.F index 14d89afb9..758242d44 100644 --- a/src/enzo/prolong.F +++ b/src/enzo/prolong.F @@ -140,3 +140,147 @@ subroutine prolong(source, dest, ndim, sdim1, sdim2, sdim3, c return end + +c======================================================================= +c//////////////////////// SUBROUTINE PROLONG ADD \\\\\\\\\\\\\\\\\\\\\ +c + subroutine prolong_add(source, dest, ndim, sdim1, sdim2, sdim3, + & ddim1, ddim2, ddim3, start1, start2, start3, + & refine1, refine2, refine3) +c +c MULTIGRID: PROLONG FROM SOURCE TO DEST and add it (for APM) +c +c written by: Greg Bryan +c date: January, 1998 +c modified1: +c +c PURPOSE: +c +c INPUTS: +c source - source field +c sdim1-3 - source dimension +c ddim1-3 - destination dimension +c ndim - rank of fields +c start1-3 - dest start index in destination cells +c refine1-3 - refinement factors +c +c OUTPUT ARGUMENTS: +c dest - prolonged field +c +c EXTERNALS: +c +c LOCALS: +c +c----------------------------------------------------------------------- +c + implicit NONE +#include "fortran_types.def" +c +c----------------------------------------------------------------------- +c +c argument declarations +c + INTG_PREC ddim1, ddim2, ddim3, sdim1, sdim2, sdim3, ndim, + & start1, start2, start3, refine1, refine2, refine3 + R_PREC source(sdim1, sdim2, sdim3), dest(ddim1, ddim2, ddim3) +c +c locals +c + INTG_PREC i, j, k, i1, j1, k1 + R_PREC fact1, fact2, fact3, x, y, z, dx, dy, dz, + & edge1, edge2, edge3, half + parameter (half = 0.5001_RKIND) +c +c +c\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////// +c======================================================================= +c +c Precompute some things +c +c fact1 = REAL(sdim1,RKIND)/REAL(ddim1,RKIND) +c fact2 = REAL(sdim2,RKIND)/REAL(ddim2,RKIND) +c fact3 = REAL(sdim3,RKIND)/REAL(ddim3,RKIND) + fact1 = 1._RKIND/REAL(refine1,RKIND) + fact2 = 1._RKIND/REAL(refine2,RKIND) + fact3 = 1._RKIND/REAL(refine3,RKIND) + edge1 = REAL(sdim1,RKIND) - half + edge2 = REAL(sdim2,RKIND) - half + edge3 = REAL(sdim3,RKIND) - half +c +c a) 1D +c + if (ndim .eq. 1) then + do i=1, ddim1 + x = min(max((REAL(i+start1,RKIND)-0.5_RKIND)*fact1, half), + & edge1) + i1 = int(x + 0.5_RKIND,IKIND) + dx = REAL(i1,RKIND) + 0.5_RKIND - x + dest(i,1,1) = dest(i,1,1) + + & source(i1,1,1)*dx + source(i1+1,1,1)*(1._RKIND-dx) + enddo + endif +c +c b) 2D +c + if (ndim .eq. 2) then + do j=1, ddim2 + y = min(max((REAL(j+start2,RKIND)-0.5_RKIND)*fact2, half), + & edge2) + j1 = int(y + 0.5_RKIND,IKIND) + dy = REAL(j1,RKIND) + 0.5_RKIND - y + do i=1, ddim1 + x = min(max((REAL(i+start1,RKIND)-0.5_RKIND)*fact1,half), + & edge1) + i1 = int(x + 0.5_RKIND,IKIND) + dx = REAL(i1,RKIND) + 0.5_RKIND - x + dest(i,j,1) = dest(i,j,1) + + & source(i1,j1,1)*dx*dy + + & source(i1+1,j1 ,1)*(1._RKIND-dx)* dy + + & source(i1 ,j1+1,1)* dx *(1._RKIND-dy) + + & source(i1+1,j1+1,1)*(1._RKIND-dx)*(1._RKIND-dy) + enddo + enddo + endif +c +c c) 3D +c + if (ndim .eq. 3) then + do k=1, ddim3 + z = min(max((REAL(k+start3,RKIND)-0.5_RKIND)*fact3, half), + & edge3) + k1 = int(z + 0.5_RKIND,IKIND) + dz = REAL(k1,RKIND) + 0.5_RKIND - z + do j=1, ddim2 + y = min(max((REAL(j+start2,RKIND)-0.5_RKIND)*fact2,half), + & edge2) + j1 = int(y + 0.5_RKIND,IKIND) + dy = REAL(j1,RKIND) + 0.5_RKIND - y + do i=1, ddim1 + x = min(max((REAL(i+start1,RKIND)-0.5_RKIND)*fact1, + & half), edge1) + i1 = int(x + 0.5_RKIND,IKIND) + dx = REAL(i1,RKIND) + 0.5_RKIND - x + dest(i,j,k) = dest(i,j,k) + + & source(i1 ,j1 ,k1 ) + & * dx * dy * dz + + & source(i1+1,j1 ,k1 ) + & *(1._RKIND-dx)* dy * dz + + & source(i1 ,j1+1,k1 ) + & * dx *(1._RKIND-dy)* dz + + & source(i1+1,j1+1,k1 ) + & *(1._RKIND-dx)*(1._RKIND-dy)* dz + + & source(i1 ,j1 ,k1+1) + & * dx * dy *(1._RKIND-dz) + + & source(i1+1,j1 ,k1+1) + & *(1._RKIND-dx)* dy *(1._RKIND-dz)+ + & source(i1 ,j1+1,k1+1) + & * dx *(1._RKIND-dy)*(1._RKIND-dz)+ + & source(i1+1,j1+1,k1+1) + & *(1._RKIND-dx)*(1._RKIND-dy)*(1._RKIND-dz) + enddo + enddo + enddo + endif +c + return + end