diff --git a/.circleci/config.yml b/.circleci/config.yml index 11ac6d32b..58a251db8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -119,7 +119,7 @@ commands: make precision-$prec make particles-$part make clean - make -j 4 || (make show-config ; exit 1) + make -j 4 || (cat out.compile ; make show-config ; exit 1) done ; done # return this to default make precision-64 @@ -135,19 +135,19 @@ commands: make integers-$inte make particle-id-$pids make clean - make -j 4 || (make show-config ; exit 1) + make -j 4 || (cat out.compile ; make show-config ; exit 1) done ; done make integers-64 make particle-id-64 # test without mpi make use-mpi-no make clean - make -j 4 || (make show-config ; exit 1) + make -j 4 || (cat out.compile ; make show-config ; exit 1) make use-mpi-yes # test ray-tracing make photon-no make clean - make -j 4 || (make show-config ; exit 1) + make -j 4 || (cat out.compile ; make show-config ; exit 1) build-docs: description: "Test the docs build." diff --git a/.gitignore b/.gitignore index d3a43c4ed..c44e67c06 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,18 @@ src/P-GroupFinder/P-GroupFinder doc/manual/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 a5e218374..85567e609 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 cc365474b..2e8c5d3a9 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)`_ @@ -300,14 +302,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 @@ -382,7 +384,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: @@ -421,10 +423,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`` @@ -479,8 +481,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. @@ -520,7 +522,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) @@ -543,13 +545,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 @@ -559,9 +561,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: @@ -594,7 +596,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``. @@ -819,7 +821,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 @@ -843,11 +845,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 @@ -901,19 +903,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 @@ -955,12 +957,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 @@ -997,7 +999,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 @@ -1055,38 +1057,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 @@ -1111,8 +1113,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) @@ -1170,7 +1172,7 @@ Hierarchy Control Parameters - + .. _gravity_parameters: Gravity Parameters @@ -1192,6 +1194,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 @@ -1244,6 +1249,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 @@ -1277,15 +1307,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) @@ -1339,7 +1369,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. @@ -1397,7 +1427,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 @@ -1417,8 +1447,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 @@ -1434,12 +1464,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 @@ -1510,7 +1540,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) @@ -1549,11 +1579,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. @@ -1565,58 +1595,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. @@ -1625,13 +1655,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. @@ -1650,7 +1680,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) @@ -1658,7 +1688,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) @@ -1722,9 +1752,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 @@ -1863,11 +1893,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) @@ -2004,7 +2034,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 @@ -2047,24 +2077,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) @@ -2110,7 +2140,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 @@ -2166,16 +2196,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 @@ -2197,7 +2227,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 @@ -2208,29 +2238,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: @@ -2319,7 +2349,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 @@ -2401,7 +2431,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) @@ -2413,7 +2443,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) @@ -2469,7 +2499,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. `__. @@ -2481,8 +2511,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 @@ -2576,7 +2606,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 @@ -2617,20 +2647,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 @@ -2788,7 +2818,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. @@ -2820,9 +2850,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) @@ -2835,7 +2865,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 @@ -2854,7 +2884,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. :: @@ -2885,7 +2915,7 @@ Radiative Transfer (FLD) Implicit Solver Parameters field. Default: [0 0]. :: - + 0 - Periodic. 1 - Dirichlet. 2 - Neumann. @@ -2924,7 +2954,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. @@ -2979,16 +3009,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. :: @@ -3208,9 +3238,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) @@ -3251,7 +3281,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: @@ -3263,10 +3293,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 @@ -3274,7 +3304,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 @@ -3337,7 +3367,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 @@ -3402,14 +3432,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) @@ -3445,30 +3475,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 @@ -3483,26 +3513,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; @@ -3514,7 +3544,7 @@ Nonlinear model Coefficient for nonlinear Reynolds stress model. Default: 0; Recommended: 1; - + ``SGScoeffNLb`` (external) Coefficient for nonlinear Maxwell stress (only MHD). Default: 0; @@ -3558,7 +3588,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; @@ -3722,7 +3752,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`` @@ -3731,7 +3761,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 @@ -3747,7 +3777,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 @@ -3789,8 +3819,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 @@ -3859,11 +3889,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) @@ -3873,16 +3903,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: @@ -3989,16 +4019,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. @@ -4020,10 +4050,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). @@ -4059,17 +4089,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) @@ -4080,8 +4110,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 @@ -4100,8 +4130,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. @@ -4739,7 +4769,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 @@ -4999,13 +5029,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! @@ -5060,7 +5090,7 @@ Turbulence Simulation (60) ``TurbulenceSimulationMagneticName`` (external) -``TurbulenceSimulationInitialTemperature`` (external) +``TurbulenceSimulationInitialTemperature`` (external) ``TurbulenceSimulationInitialDensity`` (external) @@ -5242,7 +5272,7 @@ Put Sink from Restart (107) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``PutSinkRestartName`` (external) - Filename to restart from. + Filename to restart from. .. _clustercoolingflow_param: @@ -5305,7 +5335,7 @@ Cluster Cooling Flow (108) ``SNIaFeedbackEnergy`` (external) Energy feedback from evolved stars (Type Ia SN). Default: 1.0 - + .. _light_boson: Light Boson Initialize @@ -5318,7 +5348,7 @@ Light Boson Initialize colliding Gaussian packets. Default: 1 ``LightBosonCenter`` (external) Specifies center position for the tests. Default: 0.5 - + .. _fdm_collapse: FDM Collapse @@ -5329,7 +5359,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) @@ -5453,7 +5483,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) @@ -5463,7 +5493,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) @@ -5523,7 +5553,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 @@ -5573,12 +5603,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). @@ -5664,8 +5694,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: @@ -5682,7 +5712,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 @@ -5696,19 +5726,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 @@ -5720,7 +5750,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: @@ -5755,10 +5785,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. @@ -5797,7 +5827,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 @@ -5834,7 +5864,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 @@ -5843,10 +5873,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/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..0df0490f5 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCenterTest/APMCenterTest.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTest-APMCenter' +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/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..7b35d53a0 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/APMCornerTest/APMCornerTest.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTest-APMCorner' +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/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..4c2e458b1 --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCenterTest/FastCenterTest.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTest-FastCenter' +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/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..c99d2051f --- /dev/null +++ b/run/APMGravitySolver/GravityTest/FastCornerTest/FastCornerTest.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTest-FastCorner' +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/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..82eee8002 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere0/APMSphere0.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTestSphere-APMSphere0' +answer_testing_script = None +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/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..490ea01ec --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere1/APMSphere1.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTestSphere-FastSphere1' +answer_testing_script = None +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/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..4f04bb1c6 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/APMSphere2/APMSphere2.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTestSphere-APMSphere2' +answer_testing_script = None +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/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..482763335 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere0/FastSphere0.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTestSphere-FastSphere0' +answer_testing_script = None +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/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..490ea01ec --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere1/FastSphere1.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTestSphere-FastSphere1' +answer_testing_script = None +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/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..dec551d01 --- /dev/null +++ b/run/APMGravitySolver/GravityTestSphere/FastSphere2/FastSphere2.enzotest @@ -0,0 +1,13 @@ +name = 'APMGravityTestSphere-FastSphere2' +answer_testing_script = None +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/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..b569c5251 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevel/APM1RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-APM2' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..97bf7c6b0 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM1RefLevelExtra/APM1RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-APM1' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..c2eff4f26 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevel/APM2RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-APM4' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..6eda4f2b5 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/APM2RefLevelExtra/APM2RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-APM3' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..b2458053f --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevel/Fast1RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-Fast2' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..b3606fe97 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast1RefLevelExtra/Fast1RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-Fast1' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..5dbf018d2 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevel/Fast2RefLevel.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-Fast4' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..330f16208 --- /dev/null +++ b/run/APMGravitySolver/TestOrbit/Fast2RefLevelExtra/Fast2RefLevelExtra.enzotest @@ -0,0 +1,13 @@ +name = 'TestOrbit-Fast3' +answer_testing_script = None +nprocs = 4 +runtime = 'short' +hydro = False +gravity = True +AMR = True +dimensionality = 3 +author = 'Jean-Claude Passy' +max_time_minutes = 5 +fullsuite = True +pushsuite = True +quicksuite = True 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..39f4cc7ce --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMNoSubcycle/APMNoSubcycle.enzotest @@ -0,0 +1,13 @@ +name = 'TestSelfForce-APM-no-sub' +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..e287962ee --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/APMSubcycle/APMSubcycle.enzotest @@ -0,0 +1,13 @@ +name = 'TestSelfForce-APM-sub' +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..179bee08a --- /dev/null +++ b/run/APMGravitySolver/TestSelfForce/FastSubcycle/FastSubcycle.enzotest @@ -0,0 +1,13 @@ +name = 'TestSelfForce-Fast' +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..e5a2a8b72 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMLongP/APMLongP.enzotest @@ -0,0 +1,13 @@ +name = 'TestSineWave-LongP-APM' +answer_testing_script = None +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/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..4f76bccd4 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/APMShortP/APMShortP.enzotest @@ -0,0 +1,13 @@ +name = 'TestSineWave-ShortP-APM' +answer_testing_script = None +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..a4a0f82f6 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastLongP/FastLongP.enzotest @@ -0,0 +1,13 @@ +name = 'TestSineWave-LongP-Fast' +answer_testing_script = None +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..b824703d8 --- /dev/null +++ b/run/APMGravitySolver/TestSineWave/FastShortP/FastShortP.enzotest @@ -0,0 +1,13 @@ +name = 'TestSineWave-ShortP-Fast' +answer_testing_script = None +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/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..97b6dd7f2 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,9 +56,9 @@ #ifdef TRANSFER #include "ImplicitProblemABC.h" #endif - + // function prototypes - + int RebuildHierarchy(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], int level); @@ -72,18 +72,18 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], int WriteAllData(char *basename, int filenumber, HierarchyEntry *TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, + ExternalBoundary *Exterior, #ifdef TRANSFER ImplicitProblemABC *ImplicitSolver, -#endif +#endif FLOAT WriteTime = -1); int Group_WriteAllData(char *basename, int filenumber, HierarchyEntry *TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, + ExternalBoundary *Exterior, #ifdef TRANSFER ImplicitProblemABC *ImplicitSolver, -#endif +#endif FLOAT WriteTime = -1, int RestartDump = FALSE); @@ -92,10 +92,10 @@ int CopyOverlappingZones(grid* CurrentGrid, TopGridData *MetaData, int TestGravityCheckResults(LevelHierarchyEntry *LevelArray[]); int TestGravitySphereCheckResults(LevelHierarchyEntry *LevelArray[]); int CheckForOutput(HierarchyEntry *TopGrid, TopGridData &MetaData, - ExternalBoundary *Exterior, + ExternalBoundary *Exterior, #ifdef TRANSFER ImplicitProblemABC *ImplicitSolver, -#endif +#endif int Restart = FALSE); int CheckForTimeAction(LevelHierarchyEntry *LevelArray[], TopGridData &MetaData); @@ -114,17 +114,17 @@ int CommunicationReceiveHandler(fluxes **SubgridFluxesEstimate[] = NULL, TopGridData* MetaData = NULL); double ReturnWallTime(void); int Enzo_Dims_create(int nnodes, int ndims, int *dims); -int FOF(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], +int FOF(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], int WroteData, int FOFOnly=FALSE); int StarParticleCountOnly(LevelHierarchyEntry *LevelArray[]); -int CommunicationLoadBalanceRootGrids(LevelHierarchyEntry *LevelArray[], +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,13 +138,13 @@ 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 @@ -152,9 +152,9 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif LevelHierarchyEntry *LevelArray[], float Initialdt) { - + float dt; - + int i, dim, Stop = FALSE; int StoppedByOutput = FALSE; int Restart = FALSE; @@ -168,7 +168,7 @@ 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; MetaData.StartCPUTime = LastCPUTime = ReturnWallTime(); @@ -178,9 +178,9 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, // was the default from before. if (MetaData.CPUTime > 1e2*MetaData.StopCPUTime) MetaData.CPUTime = 0.0; - + /* Attach RandomForcingFields to BaryonFields temporarily to apply BCs */ - + if (RandomForcing) { //AK Temp = LevelArray[0]; while (Temp != NULL) { @@ -189,7 +189,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } Exterior->AppendForcingToBaryonFields(); } - + /* Set top grid boundary conditions. */ Temp = LevelArray[0]; @@ -215,7 +215,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, ENZO_FAIL("Error in CopyOverlappingZones."); Temp = Temp->NextGridThisLevel; } - + CommunicationDirection = COMMUNICATION_SEND; Temp = LevelArray[0]; @@ -226,7 +226,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, Temp = Temp->NextGridThisLevel; } -#ifdef FORCE_MSG_PROGRESS +#ifdef FORCE_MSG_PROGRESS CommunicationBarrier(); #endif @@ -237,9 +237,9 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif PrintMemoryUsage("Bdry set"); - + /* Remove RandomForcingFields from BaryonFields when BCs are set. */ - + if (RandomForcing) { //AK LevelHierarchyEntry *Temp = LevelArray[0]; while (Temp != NULL) { @@ -248,21 +248,21 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } Exterior->DetachForcingFromBaryonFields(); } - + /* Check for output. */ - - CheckForOutput(&TopGrid, MetaData, Exterior, + + CheckForOutput(&TopGrid, MetaData, Exterior, #ifdef TRANSFER ImplicitSolver, -#endif +#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); @@ -274,7 +274,7 @@ 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) { @@ -283,7 +283,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } else { /* Do the first grid regeneration. */ - + if(CheckpointRestart == FALSE) { RebuildHierarchy(&MetaData, LevelArray, 0); } @@ -291,17 +291,17 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } // 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) { LevelInfofptr = fopen("OutputLevelInformation.out", "w"); fclose(LevelInfofptr); @@ -311,7 +311,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, to restrict the timesteps. Collect info here. */ StarParticleCountOnly(LevelArray); - + #ifdef USE_LCAPERF Eint32 lcaperf_iter; #endif @@ -347,17 +347,17 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #ifdef MEM_TRACE fprintf(memtracePtr, "==== CYCLE %"ISYM" ====\n", MetaData.CycleNumber); -#endif +#endif PrintMemoryUsage("Top"); /* Load balance the root grids if this isn't the initial call */ if ((CheckpointRestart == FALSE) && (!FirstLoop)) - CommunicationLoadBalanceRootGrids(LevelArray, MetaData.TopGridRank, + CommunicationLoadBalanceRootGrids(LevelArray, MetaData.TopGridRank, MetaData.CycleNumber); /* Output level information to log file. */ - + if (MyProcessorNumber == ROOT_PROCESSOR) { LevelInfofptr = fopen("OutputLevelInformation.out", "a"); if (LevelInfofptr == NULL) @@ -371,12 +371,12 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, if (MyProcessorNumber == ROOT_PROCESSOR) fclose(LevelInfofptr); - + /* Compute minimum timestep on the top level. */ - + float dtProc = huge_number; Temp = LevelArray[0]; - + // Start skipping if(CheckpointRestart == FALSE) { while (Temp != NULL) { @@ -390,7 +390,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, 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; @@ -416,13 +416,13 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, 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 @@ -432,7 +432,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, Temp->GridData->SetTimeStep(dt); Temp = Temp->NextGridThisLevel; } - + #ifdef CONFIG_TESTING if (MyProcessorNumber == ROOT_PROCESSOR) { printf("enzo-test: MetaData.CycleNumber %"ISYM"\n", MetaData.CycleNumber); @@ -445,6 +445,8 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, 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; @@ -454,41 +456,41 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, 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) + if (SetEvolveRefineRegion(MetaData.Time) == FAIL) ENZO_FAIL("Error in SetEvolveRefineRegion."); } /* Set evolving stellar mass threshold */ if (StarMakerMinimumMassRamp > 0) { - if (SetStellarMassThreshold(MetaData.Time) == FAIL) + 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). */ -#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,7 +504,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } */ #endif - + if (EvolveLevel(&MetaData, LevelArray, 0, dt, Exterior #ifdef TRANSFER , ImplicitSolver @@ -517,7 +519,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, &TopGrid, MetaData, Exterior #ifdef TRANSFER , ImplicitSolver -#endif +#endif ); } return FAIL; @@ -525,15 +527,15 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, -#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; @@ -541,7 +543,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, LastCPUTime = ReturnWallTime(); if (MyProcessorNumber == ROOT_PROCESSOR) { - + if (MetaData.Time >= MetaData.StopTime) { if (MyProcessorNumber == ROOT_PROCESSOR) printf("Stopping on top grid time limit.\n"); @@ -559,7 +561,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, } else if ((ReturnWallTime() - MetaData.StartCPUTime >= MetaData.dtRestartDump && MetaData.dtRestartDump > 0) || - (MetaData.CycleNumber - MetaData.CycleLastRestartDump >= + (MetaData.CycleNumber - MetaData.CycleLastRestartDump >= MetaData.CycleSkipRestartDump && MetaData.CycleSkipRestartDump > 0)) { if (MyProcessorNumber == ROOT_PROCESSOR) @@ -579,7 +581,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif PrintMemoryUsage("Pre loop rebuild"); - + if (ProblemType != 25 && Restart == FALSE) RebuildHierarchy(&MetaData, LevelArray, 0); @@ -588,17 +590,17 @@ 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 +#endif Restart); /* Call inline analysis. */ @@ -610,7 +612,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #endif /* Check for resubmission */ - + if (!Restart) CheckForResubmit(MetaData, Stop); @@ -620,12 +622,12 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, FOF(&MetaData, LevelArray, TRUE); /* 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 @@ -690,7 +692,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, 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) { @@ -699,7 +701,7 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, if (MyProcessorNumber == ROOT_PROCESSOR) { fprintf(stderr, "Exiting after writing %"ISYM" datadumps.\n", MetaData.NumberOfOutputsBeforeExit); - } + } Stop = TRUE; StoppedByOutput = TRUE; } @@ -713,46 +715,46 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, #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 we are running problem 23, TestGravity, then check the results. */ - - if (ProblemType == 23) + + /* If we are running TestGravity problems 23/123, then check the results. */ + + if (ProblemType == 23 || ProblemType == 123) TestGravityCheckResults(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 + ImplicitSolver, +#endif -666) == FAIL) ENZO_FAIL("Error in Group_WriteAllData."); // #else // if (WriteAllData(MetaData.DataDumpName, MetaData.DataDumpNumber, -// &TopGrid, MetaData, Exterior, +// &TopGrid, MetaData, Exterior, //#ifdef TRANSFER -// ImplicitSolver, -//#endif +// ImplicitSolver, +//#endif // -666) == FAIL) { // ENZO_FAIL("Error in WriteAllData.\n"); // } // #endif - + /* Write a file to indicate that we're finished. */ FILE *Exit_fptr; @@ -767,12 +769,12 @@ int EvolveHierarchy(HierarchyEntry &TopGrid, TopGridData &MetaData, 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 c918fcbdd..41933d063 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; @@ -728,20 +760,20 @@ 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(); + Grids[grid1]->GridData->MagneticSupernovaList.clear(); ActiveParticleFinalize(Grids, MetaData, NumberOfGrids, LevelArray, level, NumberOfNewActiveParticles); @@ -753,7 +785,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){ @@ -763,10 +795,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") @@ -783,14 +815,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 @@ -842,8 +874,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); } /* ------------------------------------------------------- */ @@ -852,7 +884,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, @@ -905,25 +937,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(); @@ -932,7 +964,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], // CopyGravPotential = FALSE; // } // if WritePotential - + /* Count up number of grids on this level. */ int GridMemory, NumberOfCells, CellsTotal, Particles; @@ -949,7 +981,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); @@ -959,25 +991,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; @@ -985,7 +1017,7 @@ int EvolveLevel(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], delete [] TotalStarParticleCountPrevious; dtThisLevel[level] = dtThisLevelSoFar[level] = 0.0; - + /* Clean up the sibling list. */ @@ -1004,5 +1036,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 6a8023953..e7c9ea309 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 @@ -91,7 +92,7 @@ class grid float dtFixed; // current (fixed) timestep FLOAT Time; // current problem time FLOAT OldTime; // time corresponding to OldBaryonField - int SubgridsAreStatic; // + int SubgridsAreStatic; // int ID; // Grid ID Number int sfSeed; // @@ -123,7 +124,7 @@ class grid int NumberOfParticles; FLOAT *ParticlePosition[MAX_DIMENSION]; // pointers to position arrays float *ParticleVelocity[MAX_DIMENSION]; // pointers to velocity arrays - float *ParticleAcceleration[MAX_DIMENSION+1]; // + float *ParticleAcceleration[MAX_DIMENSION+1]; // float *ParticleMass; // pointer to mass array PINT *ParticleNumber; // unique identifier int *ParticleType; // type of particle @@ -154,7 +155,7 @@ class grid // // Gravity data -// +// float *PotentialField; float *AccelerationField[MAX_DIMENSION]; // cell cntr acceleration at n+1/2 float *GravitatingMassField; @@ -168,6 +169,11 @@ class grid gravity_boundary_type GravityBoundaryType; float PotentialSum; +// For APM solver + greens_function GreensFunction; + float *AccelerationFieldExternalAPM[MAX_DIMENSION]; // external acceleration for APM solver + + // // WS: total energy injection by stochastic forcing @@ -206,7 +212,7 @@ class grid // // Movie Data Format // - int TimestepsSinceCreation; // Not really since creation anymore... + int TimestepsSinceCreation; // Not really since creation anymore... // resets everytime the grid outputs // density and pressure history for one-zone collapse @@ -263,23 +269,23 @@ class grid /* Read grid data from a file (returns: success/failure) */ - int ReadGrid(FILE *main_file_pointer, int GridID, char DataFilename[], + 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) */ #ifndef NEW_GRID_IO - int Group_ReadGrid(FILE *fptr, int GridID, HDF5_hid_t file_id, + 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, + int Group_ReadGrid(FILE *main_file_pointer, int GridID, HDF5_hid_t file_id, char DataFilename[], - int ReadText = TRUE, int ReadData = TRUE, + 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); @@ -287,10 +293,10 @@ class grid 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); @@ -327,11 +333,11 @@ class grid 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); @@ -359,7 +365,7 @@ class grid /* Interpolate to specified time and write grid data to a file (returns: success/failure). */ - int WriteGridInterpolate(FLOAT WriteTime, FILE *main_file_pointer, + 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 @@ -373,7 +379,7 @@ class grid float* &div); private: - int write_dataset(int ndims, hsize_t *dims, const char *name, hid_t group, + 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); @@ -409,7 +415,7 @@ class grid 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) { @@ -423,7 +429,7 @@ class grid /* Baryons: return field types. */ - int ReturnFieldType(int type[]) + int ReturnFieldType(int type[]) { for (int i = 0; i < NumberOfBaryonFields; i++) type[i] = FieldType[i]; return SUCCESS; @@ -442,12 +448,12 @@ class grid /* FDM: functions for lightboson dark matter */ int ComputeQuantumTimeStep(float &dt); /* Estimate quantum time-step */ - /* Solver for Schrodinger Equation */ + /* Solver for Schrodinger Equation */ int SchrodingerSolver( int nhy); /* Member functions for dealing with Cosmic Ray Diffusion */ - int ComputeCRDiffusion(); // CR Diffusion Method + int ComputeCRDiffusion(); // CR Diffusion Method int ComputeCRDiffusionTimeStep(float &dt); /* Baryons: Copy current solution to Old solution (returns success/fail) @@ -470,7 +476,7 @@ class grid subgrids in the argument). Returns SUCCESS or FAIL. (for step #16) */ - int SolveHydroEquations(int CycleNumber, int NumberOfSubgrids, + int SolveHydroEquations(int CycleNumber, int NumberOfSubgrids, fluxes *SubgridFluxes[], int level); /* Baryons: return pointer to the BoundaryFluxes of this grid */ @@ -483,8 +489,8 @@ class grid 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) */ @@ -502,7 +508,7 @@ class grid void ComputeRefinementFactors(grid *SubGrid, int RefinementFactors[]) { int dim; - for (dim = 0; dim < GridRank; dim++) RefinementFactors[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; @@ -513,7 +519,7 @@ class grid void ComputeRefinementFactorsFloat(grid *SubGrid, float Factors[]) { int dim; - for (dim = 0; dim < GridRank; dim++) Factors[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; @@ -523,12 +529,12 @@ class grid 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, + 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 + (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) */ @@ -555,7 +561,7 @@ class grid /* set hydro parameters (used in setup) */ - void SetHydroParameters(float co, int p1, int p2, int p3) + void SetHydroParameters(float co, int p1, int p2, int p3) { CourantSafetyNumber = co; PPMFlatteningParameter = p1; @@ -563,7 +569,7 @@ class grid 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); @@ -630,7 +636,7 @@ gradient force to gravitational force for one-zone collapse test. */ int ConvertTotalEnergyToGasEnergy(); /* Sets the energy to provide Jean's level support (Zeus: returns coeff). */ - + int SetMinimumSupport(float &MinimumSupportEnergyCoefficient); /* Debugging support. */ @@ -659,24 +665,24 @@ gradient force to gravitational force for one-zone collapse test. */ /* Project some of the fields to a plane. */ - int ProjectToPlane(FLOAT ProjectedFieldLeftEdge[], + int ProjectToPlane(FLOAT ProjectedFieldLeftEdge[], FLOAT ProjectedFieldRightEdge[], - int ProjectedFieldDims[], float *ProjectedField[], + int ProjectedFieldDims[], float *ProjectedField[], int ProjectionDimension, int ProjectionSmooth, int NumberOfProjectedFields, int level, int XrayUseLookupTable, float XrayLowerCutoffkeV, float XrayUpperCutoffkeV, char *XrayFileName); - int ProjectToPlane2(FLOAT ProjectedFieldLeftEdge[], + int 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); /* Set the fields to zero under the active region of the specified subgrid. */ - int ZeroSolutionUnderSubgrid(grid *Subgrid, int FieldsToZero, + int ZeroSolutionUnderSubgrid(grid *Subgrid, int FieldsToZero, float Value = 1.0, int AllProcessors = FALSE, int IncludeGhostZones = FALSE); @@ -692,7 +698,7 @@ gradient force to gravitational force for one-zone collapse test. */ /* Return some information about the grid. */ - int CollectGridInformation(int &GridMemory, float &GridVolume, + int CollectGridInformation(int &GridMemory, float &GridVolume, int &NumberOfCells, float &AxialRatio, int &CellsTotal, int &Particles); @@ -706,18 +712,18 @@ gradient force to gravitational force for one-zone collapse test. */ /* Output movie data (sequential format) */ - int WriteNewMovieData(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], - int RootResolution, FLOAT StopTime, + int WriteNewMovieData(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], + int RootResolution, FLOAT StopTime, AMRHDF5Writer &AmiraGrid, - int lastMovieStep, int TopGridCycle, - int WriteMe, int MovieTimestepCounter, int open, + int lastMovieStep, int TopGridCycle, + int WriteMe, int MovieTimestepCounter, int open, FLOAT WriteTime, - int alreadyopened[][MAX_DEPTH_OF_HIERARCHY] = NULL, + int alreadyopened[][MAX_DEPTH_OF_HIERARCHY] = NULL, int NumberOfStarParticlesOnProcOnLvl[][MAX_DEPTH_OF_HIERARCHY] = NULL); - int WriteNewMovieDataSeparateParticles(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], + int WriteNewMovieDataSeparateParticles(FLOAT RegionLeftEdge[], FLOAT RegionRightEdge[], FLOAT StopTime, AMRHDF5Writer &AmiraGrid, - int lastMovieStep, int WriteMe, + int lastMovieStep, int WriteMe, FLOAT WriteTime, int alreadyopened[], int NumberOfStarParticlesOnProc[]); @@ -767,7 +773,7 @@ gradient force to gravitational force for one-zone collapse test. */ 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 *iexpand, hydro_method *imethod, int *idual, int *idim, int *is, int *js, int *ks, int *ie, int *je, int *ke, float *dt, float *aye, @@ -797,7 +803,7 @@ gradient force to gravitational force for one-zone collapse test. */ 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); @@ -805,14 +811,14 @@ gradient force to gravitational force for one-zone collapse test. */ /* wrapper for GadgetCoolingRate */ float Gadget_EquilibriumCooling(float u_old, float rho, float dt, - float *ne_guess, float *utem, float *uxyz, + 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 GadgetCoolingRateFromU(float u, float rho, float *ne_guess, float redshift); // Functions for shock finding @@ -845,9 +851,9 @@ gradient force to gravitational force for one-zone collapse test. */ /* Sum particle mass flagging fields into ProcessorNumber if particles aren't local. */ - int SetParticleMassFlaggingField(int StartProc=0, int EndProc=0, int level=-1, + int SetParticleMassFlaggingField(int StartProc=0, int EndProc=0, int level=-1, int ParticleMassMethod=-1, int MustRefineMethod=-1, - int *SendProcs=NULL, + int *SendProcs=NULL, int NumberOfSends=0); int CollectParticleMassFlaggingField(void); void ClearParticleMassFlaggingField(void); @@ -890,9 +896,9 @@ gradient force to gravitational force for one-zone collapse test. */ /* Particles: deposit regions in the feedback zone to ensure flagging */ 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) + field contains the mass in the cell (not the density) (gg #3) */ int AddFieldMassToMassFlaggingField(); @@ -922,7 +928,7 @@ gradient force to gravitational force for one-zone collapse test. */ (gg #4) */ 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) */ @@ -941,7 +947,7 @@ gradient force to gravitational force for one-zone collapse test. */ 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(); @@ -1000,7 +1006,7 @@ gradient force to gravitational force for one-zone collapse test. */ /* set the grid dimensions, left, right edges and cell quantities based on arguments (gg #5,6) */ - void PrepareGrid(int Rank, int Dimensions[], + void PrepareGrid(int Rank, int Dimensions[], FLOAT LeftEdge[], FLOAT RightEdge[], int NumParticles); /* Allocates space for grids (dims and NumberOfBaryonFields must be set). */ @@ -1014,12 +1020,12 @@ gradient force to gravitational force for one-zone collapse test. */ /* baryons: interpolate field values from the Parent Grid (gg #6). Returns SUCCESS or FAIL. */ - int InterpolateFieldValues(grid *ParentGrid , + int InterpolateFieldValues(grid *ParentGrid , LevelHierarchyEntry * OldFineLevel, TopGridData * MetaData); /* Interpolate one radiation field. Based on InterpolateFieldValues - but removed all of the conservative stuff. */ + but removed all of the conservative stuff. */ int InterpolateRadiationFromParent(grid *ParentGrid, int Field); @@ -1032,7 +1038,7 @@ gradient force to gravitational force for one-zone collapse test. */ int (grid::*CopyFunction)(grid *OtherGrid, FLOAT EdgeOffset[])); - + @@ -1062,7 +1068,7 @@ gradient force to gravitational force for one-zone collapse test. */ /* baryons: copy coincident zone from the (old) grid in the argument (gg #7). Return SUCCESS or FAIL. */ - int CopyZonesFromGrid(grid *GridOnSameLevel, + int CopyZonesFromGrid(grid *GridOnSameLevel, FLOAT EdgeOffset[MAX_DIMENSION]); int CopyActiveZonesFromGrid(grid *GridOnSameLevel, @@ -1071,7 +1077,7 @@ gradient force to gravitational force for one-zone collapse test. */ /* gravity: copy coincident potential field zones from grid in the argument (gg #7). Return SUCCESS or FAIL. */ - int CopyPotentialField(grid *GridOnSameLevel, + int CopyPotentialField(grid *GridOnSameLevel, FLOAT EdgeOffset[MAX_DIMENSION]); /* baryons: check for coincident zone from the (old) grid in the argument @@ -1104,13 +1110,13 @@ gradient force to gravitational force for one-zone collapse test. */ int size = GridDimension[0]*GridDimension[1]*GridDimension[2]; BaryonField[NumberOfBaryonFields] = new float[size]; for (int i = 0; i < size; i++) - BaryonField[NumberOfBaryonFields][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", + {fprintf(stdout, "Baryonfield[field = %"ISYM"][index = %"ISYM"] = %g\n", field, index, BaryonField[field][index]);}; // ------------------------------------------------------------------------- @@ -1121,7 +1127,7 @@ gradient force to gravitational force for one-zone collapse test. */ void SetGravityParameters(gravity_boundary_type Boundary) { GravityBoundaryType = Boundary;}; - gravity_boundary_type ReturnGravityBoundaryType() + gravity_boundary_type ReturnGravityBoundaryType() {return GravityBoundaryType;}; /* Gravity: Initialize, the gravitating Mass Field @@ -1153,7 +1159,7 @@ gradient force to gravitational force for one-zone collapse test. */ /* 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 DepositPositions(FLOAT *Positions[], float *Mass, int Number, int DepositField); /* deposit particles/grids to grid (if they are on the grid). */ @@ -1172,10 +1178,10 @@ gradient force to gravitational force for one-zone collapse test. */ int ComputeAccelerations(int level); -/* Particles: add overlapping ParticleMassField to Target's +/* Particles: add overlapping ParticleMassField to Target's GravitatingMassField. */ - int CopyOverlappingMassField(grid *TargetGrid, + int CopyOverlappingMassField(grid *TargetGrid, FLOAT EdgeOffset[MAX_DIMENSION]); /* Gravity: Allocate and make initial guess for PotentialField. */ @@ -1188,7 +1194,6 @@ gradient force to gravitational force for one-zone collapse test. */ /* Gravity: Prepare the Greens Function. */ - int PrepareGreensFunction(); int PreparePeriodicGreensFunction(region *GreensRegion); /* Gravity: Copy potential/density into/out of FFT regions. */ @@ -1213,7 +1218,34 @@ gradient force to gravitational force for one-zone collapse test. */ /* Gravity: Add fixed, external potential to baryons & particles. */ int AddExternalPotentialField(float *field); - + +/* APM Gravity: Compute accelerations for a grid*/ + + int ComputeAccelerationFieldAPM(int RefinmentFactor); + +/* 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. */ @@ -1231,13 +1263,13 @@ gradient force to gravitational force for one-zone collapse test. */ /* Generic routine for interpolating particles/grid. */ - int InterpolatePositions(FLOAT *Positions[], int dim, float *Field, + int InterpolatePositions(FLOAT *Positions[], int dim, float *Field, int Number); /* Gravity: Delete GravitatingMassField. */ void DeleteGravitatingMassField() { - delete [] GravitatingMassField; + delete [] GravitatingMassField; GravitatingMassField = NULL; }; @@ -1310,7 +1342,7 @@ gradient force to gravitational force for one-zone collapse test. */ // ------------------------------------------------------------------------- -// Functions for accessing specific baryon fields +// Functions for accessing specific baryon fields // (all sources combined in the file Grid_AccessBaryonFields.C) // float* AccessDensity(); @@ -1369,15 +1401,15 @@ gradient force to gravitational force for one-zone collapse test. */ // (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) */ + (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; + if (procs > 0) ProcLayout[Dimension] = procs; else fprintf(stderr,"SetProcessorLayout: invalid procs value.\n"); } @@ -1389,25 +1421,25 @@ gradient force to gravitational force for one-zone collapse test. */ 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"); + 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. + 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) { + 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"); + 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"); + if (NBid >= 0) ProcNeighbors[Dimension][LR] = NBid; + else fprintf(stderr,"SetProcessorNeighbors: invalid grid ID.\n"); } @@ -1418,19 +1450,19 @@ gradient force to gravitational force for one-zone collapse test. */ /* Particles: Deposit particles in the specified field (DepositField) of the TargetGrid at the given time. */ - int DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, + int DepositParticlePositions(grid *TargetGrid, FLOAT DepositTime, int DepositField); 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, + 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) */ @@ -1487,7 +1519,7 @@ gradient force to gravitational force for one-zone collapse test. */ /* Particles & Gravity: Delete GravitatingMassField. */ void DeleteGravitatingMassFieldParticles() { - delete [] GravitatingMassFieldParticles; + delete [] GravitatingMassFieldParticles; GravitatingMassFieldParticles = NULL; GravitatingMassFieldParticlesCellSize = FLOAT_UNDEFINED; }; @@ -1527,7 +1559,7 @@ iveParticles;}; for (int i = 0; i < NumberOfParticleAttributes; i++) { if (ParticleAttribute[i] != NULL) delete [] ParticleAttribute[i]; ParticleAttribute[i] = NULL; - } + } }; void DeleteActiveParticles() { @@ -1538,7 +1570,7 @@ iveParticles;}; void CorrectActiveParticleCounts() { NumberOfActiveParticles = ActiveParticles.size(); } - + /* Particles: allocate new particle fields. */ void AllocateNewParticles(int NumberOfNewParticles) { @@ -1556,7 +1588,7 @@ iveParticles;}; /* Particles: Copy pointers passed into into grid. */ void SetParticlePointers(float *Mass, PINT *Number, int *Type, - FLOAT *Position[], + FLOAT *Position[], float *Velocity[], float *Attribute[]) { ParticleMass = Mass; ParticleNumber = Number; @@ -1577,7 +1609,7 @@ iveParticles;}; /* Particles: Set new star particle index. - Old version */ void SetNewParticleIndexOld(int &NumberCount, int BaseNumber) { - for (int n = 0; n < NumberOfParticles; n++) + for (int n = 0; n < NumberOfParticles; n++) if (ParticleNumber[n] == INT_UNDEFINED) ParticleNumber[n] = BaseNumber + NumberCount++; }; @@ -1636,7 +1668,7 @@ int CreateParticleTypeGrouping(hid_t ptype_dset, hid_t parent_group, hid_t file_id); - int ChangeParticleTypeBeforeSN(int _type, int level, + int ChangeParticleTypeBeforeSN(int _type, int level, int *ParticleBufferSize=NULL); // ------------------------------------------------------------------------- @@ -1657,56 +1689,56 @@ int CreateParticleTypeGrouping(hid_t ptype_dset, /* Send a region from a real grid to a 'fake' grid on another processor. */ - int CommunicationSendRegion(grid *ToGrid, int ToProcessor, int SendField, + 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. */ - int CommunicationReceiveRegion(grid *ToGrid, int ToProcessor, - int SendField, int NewOrOld, + int CommunicationReceiveRegion(grid *ToGrid, int ToProcessor, + int SendField, int NewOrOld, int RegionStart[], int RegionDim[], int IncludeBoundary); /* Move a grid from one processor to another. */ int CommunicationMoveGrid(int ToProcessor, int MoveParticles = TRUE, - int DeleteAllFields = TRUE, + int DeleteAllFields = TRUE, int MoveSubgridMarker = FALSE); /* Send particles from one grid to another. */ - int CommunicationSendParticles(grid *ToGrid, int ToProcessor, + 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, + 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 *&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, + 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, + int CollectStars(int GridNum, int* &NumberToMove, + int &StartIndex, int &EndIndex, star_data* &List, int CopyDirection); // Only used for static hierarchies @@ -1714,17 +1746,17 @@ int CommunicationTransferActiveParticles(grid* Grids[], int NumberOfGrids, int AllLocal); int MoveSubgridActiveParticles(int NumberOfSubgrids, grid* ToGrids[], int AllLocal); - int TransferSubgridParticles(grid* Subgrids[], int NumberOfSubgrids, - int* &NumberToMove, int StartIndex, - int EndIndex, particle_data* &List, + int TransferSubgridParticles(grid* Subgrids[], int NumberOfSubgrids, + int* &NumberToMove, int StartIndex, + int EndIndex, particle_data* &List, bool KeepLocal, bool ParticlesAreLocal, int CopyDirection, int IncludeGhostZones = FALSE, int CountOnly = FALSE); - int TransferSubgridStars(grid* Subgrids[], int NumberOfSubgrids, - int* &NumberToMove, int StartIndex, - int EndIndex, star_data* &List, + int TransferSubgridStars(grid* Subgrids[], int NumberOfSubgrids, + int* &NumberToMove, int StartIndex, + int EndIndex, star_data* &List, bool KeepLocal, bool ParticlesAreLocal, int CopyDirection, int IncludeGhostZones = FALSE); @@ -1750,7 +1782,7 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, /* Return if neither grid lives on this processor. */ // if (NumberOfProcessors == 1) return SUCCESS; - if (MyProcessorNumber != ProcessorNumber && + if (MyProcessorNumber != ProcessorNumber && MyProcessorNumber != OtherGrid->ProcessorNumber) return SUCCESS; @@ -1769,7 +1801,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 || @@ -1782,17 +1814,17 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, /* Baryons: find certain commonly used variables from the list of fields. */ - int IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, + 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 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 IdentifyPhysicalQuantities(int &DensNum, int &GENum, int &Vel1Num, int &Vel2Num, int &Vel3Num, int &TENum, int &B1Num, int &B2Num, int &B3Num, int &PhiNum); @@ -1810,13 +1842,13 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, /* Identify colour field */ - int IdentifyColourFields(int &SNColourNum, int &MetalNum, + 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 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); @@ -1837,8 +1869,8 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, /* Zeus Solver. */ - int ZeusSolver(float *gamma, int igamfield, int nhy, - float dx[], float dy[], float dz[], + 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, @@ -1846,22 +1878,22 @@ int TransferSubgridActiveParticles(grid* Subgrids[], int NumberOfSubgrids, /* PPM Direct Euler Solver. */ -int SolvePPM_DE(int CycleNumber, int NumberOfSubgrids, +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 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 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 zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], + Elong_int GridGlobalStart[], float *CellWidthTemp[], int GravityOn, int NumberOfColours, int colnum[], float *pressure); // AccelerationHack @@ -1939,10 +1971,18 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float LeftCRDensity, float RightCRDensity, float CenterCRDensity); +/* 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 InitializeUniformGrid(float UniformDensity, float UniformTotalEnergy, - float UniformGasEnergy, float UniformVelocity[], + float UniformGasEnergy, float UniformVelocity[], float UniformBField[], float UniformCR = 0.0); @@ -1993,9 +2033,9 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float RotatingCylinderOverdensity); int RotatingDiskInitializeGrid(float RDScaleRadius, - float RDScaleHeight, + float RDScaleHeight, float RDTemperature, - float RDDMConcentration, + float RDDMConcentration, float RDTotalDMMass, float RDCentralDensity, float RDOuterEdge); @@ -2066,36 +2106,61 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int UseBaryons); /* Star Particle test: initialize particle */ - int TestStarParticleInitializeGrid(float TestStarParticleStarMass, + int TestStarParticleInitializeGrid(float TestStarParticleStarMass, float *Initialdt, FLOAT TestStarParticleStarVelocity[], - FLOAT TestStarParticleStarPosition[]); + FLOAT TestStarParticleStarPosition[]); /* Gravity Test: initialize grid. */ + int TestGravityInitializeGrid(float CentralDensity, + int NumberOfNewParticles, + float *CentralParticlePosition, + int UseBaryons); - int TestGravityInitializeGrid(float CentralDensity, - int NumberOfNewParticles, int UseBaryons); + /* Gravity Test: initialize grid. APM version */ + int TestGravityAPMInitializeGrid(float CentralDensity, + int NumberOfNewParticles, + float CentralParticlePositionX, + float CentralParticlePositionY, + float CentralParticlePositionZ, + int UseBaryons); -/* Gravity Test: check results. */ + /* Gravity Test: check results. */ + int TestGravityCheckResults(FILE *fptr, grid *TopGrid, int level); - int TestGravityCheckResults(FILE *fptr, grid *TopGrid); -/* Gravity Test Motion: initialize grid. */ + + /* 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); + /* 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); @@ -2106,7 +2171,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Conducting Bubble Test: initialize grid. */ - int ConductionBubbleInitialize(FLOAT BubbleRadius, int PulseType, float DeltaEntropy, + int ConductionBubbleInitialize(FLOAT BubbleRadius, int PulseType, float DeltaEntropy, float MidpointEntropy, float EntropyGradient, float MidpointTemperature, FLOAT BubbleCenter[MAX_DIMENSION]); @@ -2163,13 +2228,13 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float UniformVelocity[MAX_DIMENSION], int SphereUseColour, int SphereUseMetals, - float InitialTemperature, + float InitialTemperature, float InitialDensity, int level, - float CollapseTestInitialFractionHII, + float CollapseTestInitialFractionHII, float CollapseTestInitialFractionHeII, - float CollapseTestInitialFractionHeIII, + float CollapseTestInitialFractionHeIII, float CollapseTestInitialFractionHM, - float CollapseTestInitialFractionH2I, + float CollapseTestInitialFractionH2I, float CollapseTestInitialFractionH2II); @@ -2186,7 +2251,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int SphereUseParticles, float UniformVelocity[MAX_DIMENSION], int SphereUseColour, - float InitialTemperature, + float InitialTemperature, float ClusterInitialSpinParameter, int level); /* CosmologySimulation: initialize grid. */ @@ -2288,9 +2353,9 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], FLOAT DiskRadius, float GalaxyMass, float GasMass, - FLOAT DiskPosition[MAX_DIMENSION], + FLOAT DiskPosition[MAX_DIMENSION], FLOAT ScaleHeightz, - FLOAT ScaleHeightR, + FLOAT ScaleHeightR, FLOAT GalaxyTruncationRadius, float DMConcentration, float DiskTemperature, @@ -2300,8 +2365,8 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float GasHaloScaleRadius, float GasHaloDensity, float AngularMomentum[MAX_DIMENSION], - float UniformVelocity[MAX_DIMENSION], - int UseMetallicityField, + float UniformVelocity[MAX_DIMENSION], + int UseMetallicityField, float GalaxySimulationInflowTime, float GalaxySimulationInflowDensity, int level, @@ -2319,7 +2384,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Supernova restart initialize grid. */ int SupernovaRestartInitialize(float EjectaDensity, float EjectaRadius, - float EjectaThermalEnergy, + float EjectaThermalEnergy, FLOAT EjectaCenter[3], int ColourField, int *NumberOfCellsSet); @@ -2330,53 +2395,53 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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, + 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, + 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, + 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, + 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 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, + 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 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) */ @@ -2389,12 +2454,12 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int RadPulseDim, int local); /* FLD Radiation test problem: grey Marshak wave test (SUCCESS or FAIL) */ - int RadHydroGreyMarshakWaveInitializeGrid(float DensityConst, float IEConst, + 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, + int RadHydroRadShockInitializeGrid(float DensityConst, float TEConst, float REConst, float VelocityConst, int ShockDir, int local); @@ -2442,9 +2507,9 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int ReadRandomForcingFields(FILE *main_file_pointer, char DataFilename[]); int AddFields(int TypesToAdd[], int NumberOfFields); - int DeleteObsoleteFields(int *ObsoleteFields, + int DeleteObsoleteFields(int *ObsoleteFields, int NumberOfObsoleteFields); - + inline bool isLocal () {return MyProcessorNumber == ProcessorNumber; }; private: @@ -2520,7 +2585,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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]; @@ -2529,11 +2594,11 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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); @@ -2544,7 +2609,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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. */ @@ -2590,7 +2655,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Calculate the potential across the grid. */ void CalculatePotentialField(float *PotentialField, int DensNum, float DensityUnits, float TimeUnits, float LengthUnits); - + /* Find the minumum of the potential in a given region */ float FindMinimumPotential(FLOAT *cellpos, FLOAT radius, float *PotentialField); @@ -2608,7 +2673,7 @@ 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); @@ -2616,7 +2681,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Find the total kinetic energy in a given region */ float FindTotalKineticEnergy(FLOAT *cellpos, FLOAT radius, int densNum, int vel1Num, int vel2Num, int vel3Num); - + /* Returns averaged velocity from the 6 neighbor cells and itself */ float* AveragedVelocityAtCell(int index, int DensNum, int Vel1Num); @@ -2625,7 +2690,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float FindAngularMomentumMinimum(FLOAT *cellpos, FLOAT radius, int DensNum, int Vel1Num, int Vel2Num, int Vel3Num); - + /* Particle splitter routine. */ int ParticleSplitter(int level, int iter, int NumberOfIDs, @@ -2634,8 +2699,8 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int CreateChildParticles(float dx, int NumberOfParticles, float *ParticleMass, int *ParticleType, FLOAT *ParticlePosition[], float *ParticleVelocity[], float *ParticleAttribute[], - FLOAT *CellLeftEdge[], int *GridDimension, - int MaximumNumberOfNewParticles, int iter, + FLOAT *CellLeftEdge[], int *GridDimension, + int MaximumNumberOfNewParticles, int iter, int *NumberOfNewParticles); /* Magnetic field resetting routine. */ @@ -2658,16 +2723,16 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* ShearingBox: initialize grid. */ - int ShearingBoxInitializeGrid(float ThermalMagneticRatio, float fraction, - float ShearingGeometry, + int ShearingBoxInitializeGrid(float ThermalMagneticRatio, float fraction, + float ShearingGeometry, int InitialMagneticFieldConfiguration); - int ShearingBox2DInitializeGrid(float ThermalMagneticRatio, float fraction, - float ShearingGeometry, + int ShearingBox2DInitializeGrid(float ThermalMagneticRatio, float fraction, + float ShearingGeometry, int InitialMagneticFieldConfiguration); - int ShearingBoxStratifiedInitializeGrid(float ThermalMagneticRatio, float fraction, - float ShearingGeometry, + int ShearingBoxStratifiedInitializeGrid(float ThermalMagneticRatio, float fraction, + float ShearingGeometry, int InitialMagneticFieldConfiguration); /* FDM: Test Problem Initialize Grid for Fuzzy Dark Matter */ @@ -2680,7 +2745,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], // 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]) || @@ -2792,29 +2857,29 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], /* Calculate enclosed mass within a radius */ int GetEnclosedMass(Star *star, float radius, float &mass, - float &metallicity, float &coldgas_mass, + float &metallicity, float &coldgas_mass, float AvgVelocity[]); int GetEnclosedMass(FLOAT star_pos[], float radius, float &mass, - float &metallicity, float &coldgas_mass, + float &metallicity, float &coldgas_mass, float AvgVelocity[], float &OneOverRSquaredSum); - int GetEnclosedMassInShell(Star *star, float radius0, float radius1, - float &mass, float &metallicity2, + 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 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, + 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, + float LengthUnits, float VelocityUnits, + float TemperatureUnits, float TimeUnits, double EjectaDensity, int &CellsModified); int MoveAllStars(int NumberOfGrids, grid* FromGrid[], int TopGridDimension); @@ -2824,7 +2889,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int CommunicationSendStars(grid *ToGrid, int ToProcessor); int CommunicationSendActiveParticles(grid *ToGrid, int ToProcessor, bool DeleteParticles = true); int TransferSubgridStars(int NumberOfSubgrids, grid* ToGrids[], int AllLocal); - + int FindNewStarParticles(int level); int FindAllStarParticles(int level); @@ -2840,20 +2905,20 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int ReturnStarStatistics(int &Number, float &minLife); - int AccreteOntoAccretingParticle(ActiveParticleType* ThisParticle, + int AccreteOntoAccretingParticle(ActiveParticleType* ThisParticle, FLOAT AccretionRadius, float* AccretionRate); - - int AccreteOntoSmartStarParticle(ActiveParticleType* ThisParticle, + + int AccreteOntoSmartStarParticle(ActiveParticleType* ThisParticle, FLOAT AccretionRadius, float* AccretionRate); float CalculateSmartStarAccretionRate(ActiveParticleType* ThisParticle, - FLOAT AccretionRadius, + FLOAT AccretionRadius, FLOAT *KernelRadius, FLOAT *SumOfWeights); int CalculateSpecificQuantities(FLOAT *SinkParticlePos, FLOAT *CLEdge, - float *vgas, float msink, + float *vgas, float msink, float *vsink, int *numpoints); int RemoveMassFromGrid(ActiveParticleType* ThisParticle, FLOAT AccretionRadius, float AccretionRate, @@ -2869,12 +2934,12 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], FLOAT *pos, float *vel); FLOAT CalculateBondiHoyleRadius(float mparticle, float *vparticle, float *Temperature); int AddMassAndMomentumToAccretingParticle(float GlobalSubtractedMass, - float GlobalSubtractedMomentum[], + float GlobalSubtractedMomentum[], ActiveParticleType* ThisParticle, LevelHierarchyEntry *LevelArray[]); int ApplyGalaxyParticleFeedback(ActiveParticleType** ThisParticle); - + int ApplyGalaxyParticleGravity(ActiveParticleType** ThisParticle); int ApplySmartStarParticleFeedback(ActiveParticleType** ThisParticle); @@ -2884,7 +2949,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], //------------------------------------------------------------------------ int IdentifyRadiativeTransferFields(int &kphHINum, int &gammaNum, - int &kphHeINum, int &kphHeIINum, + int &kphHeINum, int &kphHeIINum, int &kdissH2INum, int &kphHMNum, int &kdissH2IINum); @@ -2898,10 +2963,10 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int ComputeVertexCenteredField(int Num); int ComputeCellCenteredField(int Num); - - float ComputeInterpolatedValue(int Num, int vci, int vcj, int vck, + + 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[]); @@ -2914,15 +2979,15 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], } } - void ConvertColorFieldsToFractions(); - void ConvertColorFieldsFromFractions(); - + void ConvertColorFieldsToFractions(); + void ConvertColorFieldsFromFractions(); + //----------------------------------------------------------------------- // Returns radiative cooling by component //----------------------------------------------------------------------- int ComputeLuminosity(float *luminosity, int NumberOfLuminosityFields); - int ComputeMetalLineLuminosity(float *total_luminosity, float *all_emis, + int ComputeMetalLineLuminosity(float *total_luminosity, float *all_emis, float *temperature); @@ -2936,7 +3001,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], if (CellWidth[i][0]>TopGridDx[i]*1.05) return FALSE; } return TRUE;}; - + //------------------------------------------------------------------------ // Misc. //------------------------------------------------------------------------ @@ -2950,8 +3015,8 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], // Inline FOF halo finder and particle interpolation using a tree //------------------------------------------------------------------------ - int MoveParticlesFOF(int level, FOF_particle_data* &P, - int &Index, FOFData AllVars, float VelocityUnits, + int MoveParticlesFOF(int level, FOF_particle_data* &P, + int &Index, FOFData AllVars, float VelocityUnits, double MassUnits, int CopyDirection); int InterpolateParticlesToGrid(FOFData *D); @@ -2960,7 +3025,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], // Grid star particles onto the AMR mesh //------------------------------------------------------------------------ - int InterpolateStarParticlesToGrid(int NumberOfSPFields); + int InterpolateStarParticlesToGrid(int NumberOfSPFields); //------------------------------------------------------------------------ // new hydro & MHD routines @@ -2987,9 +3052,9 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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, + int TurbulenceInitializeGrid(float CloudDensity, float CloudSoundSpeed, FLOAT CloudRadius, float CloudMachNumber, float CloudAngularVelocity, float InitialBField, - int SetTurbulence, int CloudType, int TurbulenceSeed, int PutSink, + int SetTurbulence, int CloudType, int TurbulenceSeed, int PutSink, int level, int SetBaryonFields); int Collapse3DInitializeGrid(int n_sphere, FLOAT r_sphere[MAX_SPHERES], @@ -3019,7 +3084,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float Bxl, float Bxr, float Byl, float Byr, float Bzl, float Bzr); - int MHD1DTestWavesInitializeGrid(float rhol, + int MHD1DTestWavesInitializeGrid(float rhol, float vxl, float vyl, float vzl, @@ -3027,7 +3092,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float Bxl, float Byl, float Bzl); - int MHD2DTestInitializeGrid(int MHD2DProblemType, + int MHD2DTestInitializeGrid(int MHD2DProblemType, int UseColour, float RampWidth, float rhol, float rhou, @@ -3050,17 +3115,17 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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 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, + 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 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); @@ -3095,12 +3160,12 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], float DiskDensity, float DiskTemperature, FLOAT DiskRadius, - FLOAT DiskHeight, + FLOAT DiskHeight, int UseGas, int level); - int MHDRK2_1stStep(fluxes *SubgridFluxes[], + int MHDRK2_1stStep(fluxes *SubgridFluxes[], int NumberOfSubgrids, int level, ExternalBoundary *Exterior); - int MHDRK2_2ndStep(fluxes *SubgridFluxes[], + int MHDRK2_2ndStep(fluxes *SubgridFluxes[], int NumberOfSubgrids, int level, ExternalBoundary *Exterior); int MHD3D(float **Prim, float **dU, float dt, @@ -3131,24 +3196,24 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], int PoissonCleanStep(int level); - int GetIndex(int i, int j, int k) { + 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 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 ReduceWindBoundary(); /* New particle routines */ @@ -3162,7 +3227,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], if (ParticleNumber[n] < 0) np++; return np; }; - + /* Non-ideal effects */ int AddViscosity(); @@ -3183,14 +3248,14 @@ 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 @@ -3203,9 +3268,9 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], //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 + //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]; @@ -3229,15 +3294,15 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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 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]); @@ -3270,7 +3335,7 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], 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 MHDLoopInitGrid(float LoopDensity,float Pressure, float Vx, float Vy, float Vz, float B0, FLOAT R0, FLOAT Center[], int CurrentAxis); @@ -3293,4 +3358,3 @@ int zEulerSweep(int j, int NumberOfSubgrids, fluxes *SubgridFluxes[], #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_TestGravityAPMInitializeGrid.C b/src/enzo/Grid_TestGravityAPMInitializeGrid.C new file mode 100644 index 000000000..708b6b5d8 --- /dev/null +++ b/src/enzo/Grid_TestGravityAPMInitializeGrid.C @@ -0,0 +1,207 @@ +/*********************************************************************** +/ +/ GRID CLASS (INITIALIZE THE GRID FOR A GRAVITY TEST) - APM version +/ +/ written by: Greg Bryan +/ date: April, 1995 +/ modified1: Jean-Claude Passy, May 2018 +/ +/ PURPOSE: +/ +/ UPDATE: Following tests performed in Passy & Bryan (2014) +/ +/ 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 CentralParticlePositionX, + float CentralParticlePositionY, + float CentralParticlePositionZ, + int UseBaryons) +{ + /* declarations */ + + int dim, i, size, field, 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++) { + + 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; + + ParticlePosition[0][0] = CentralParticlePositionX; + ParticlePosition[1][0] = CentralParticlePositionY; + ParticlePosition[2][0] = CentralParticlePositionZ; + + for (dim = 0; dim < GridRank; dim++) + ParticleVelocity[dim][0] = 0.0; + } + + } + + /* 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 */ + + for (field = 0; field < NumberOfBaryonFields; field++) + if (BaryonField[field] == NULL) + BaryonField[field] = new float[size]; + + /* 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_TestGravityCheckResults.C b/src/enzo/Grid_TestGravityCheckResults.C index f7bd114da..1dcd52cb1 100644 --- a/src/enzo/Grid_TestGravityCheckResults.C +++ b/src/enzo/Grid_TestGravityCheckResults.C @@ -11,7 +11,7 @@ / RETURNS: FAIL or SUCCESS / ************************************************************************/ - + #include #include #include @@ -24,94 +24,108 @@ #include "ExternalBoundary.h" #include "Grid.h" #include "phys_constants.h" - -int grid::TestGravityCheckResults(FILE *fptr, grid *TopGrid) + + +int grid::TestGravityCheckResults(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, "%"FSYM" %e %e %e\n", r/TopGridCellWidth, ftang, - -fradial, fanalytic); - + + 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_TestGravityInitializeGrid.C b/src/enzo/Grid_TestGravityInitializeGrid.C index 4159f410a..37aa4dd88 100644 --- a/src/enzo/Grid_TestGravityInitializeGrid.C +++ b/src/enzo/Grid_TestGravityInitializeGrid.C @@ -11,7 +11,7 @@ / RETURNS: FAIL or SUCCESS / ************************************************************************/ - + #include #include #include @@ -26,26 +26,27 @@ #include "phys_constants.h" /* Random number generator */ - + void mt_init(unsigned_int seed); unsigned_long_int mt_random(); - + int grid::TestGravityInitializeGrid(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; @@ -58,128 +59,129 @@ int grid::TestGravityInitializeGrid(float CentralDensity, 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++) { - ParticlePosition[dim][0] = 0.5*(DomainLeftEdge[dim] + - DomainRightEdge[dim]); - ParticleVelocity[dim][0] = 0.0; + 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++) @@ -188,20 +190,20 @@ int grid::TestGravityInitializeGrid(float CentralDensity, (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..8f0df9cc4 --- /dev/null +++ b/src/enzo/Grid_TestGravitySphereAPMInitializeGrid.C @@ -0,0 +1,199 @@ +/*********************************************************************** +/ +/ GRID CLASS (INITIALIZE THE GRID FOR A SPHERE GRAVITY TEST) +/ +/ written by: Greg Bryan +/ date: September, 1995 +/ modified1: Jean-Claude Passy, June 2013 +/ +/ 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::TestGravitySphereAPMInitializeGrid(float SphereInteriorDensity, + float SphereExteriorDensity, + float SphereRadius, + int SphereType, + int UseBaryons, + float SphereCenter[]) +{ + /* declarations */ + + int dim, i, j, k, size, vel, field; + float phi, r, theta, pi = 3.14159; + + 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++) { + + 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 */ + + for (field = 0; field < NumberOfBaryonFields; field++) + if (BaryonField[field] == NULL) + BaryonField[field] = new float[size]; + + /* 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; + else if (SphereType == 1) + density = SphereInteriorDensity*POW(r/SphereRadius, -2); + else if (SphereType == 2) + density = SphereInteriorDensity*POW((1+POW(r/SphereRadius,2)),-2.5); + else + ENZO_VFAIL("Error in Grid_TestGravitySphereInitializeGrid.C: wrong type (%"ISYM") chosen.\n", SphereType); + } + 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_TestGravitySphereInitializeGrid.C b/src/enzo/Grid_TestGravitySphereInitializeGrid.C index ce836614f..9fa752fce 100644 --- a/src/enzo/Grid_TestGravitySphereInitializeGrid.C +++ b/src/enzo/Grid_TestGravitySphereInitializeGrid.C @@ -11,7 +11,7 @@ / RETURNS: FAIL or SUCCESS / ************************************************************************/ - + #include #include #include @@ -23,24 +23,25 @@ #include "GridList.h" #include "ExternalBoundary.h" #include "Grid.h" -#include "phys_constants.h" - +#include "phys_constants.h" + int grid::TestGravitySphereInitializeGrid(float SphereInteriorDensity, - float SphereExteriorDensity, - float SphereRadius, - int SphereType, - int UseBaryons, - FLOAT SphereCenter[]) + float SphereExteriorDensity, + float SphereRadius, + int SphereType, + int UseBaryons, + float SphereCenter[]) { /* declarations */ - + int dim, i, j, k, size, vel; float phi, r, theta; - - if (UseBaryons) { - + + if (UseBaryons) + { + /* create fields */ - + NumberOfBaryonFields = 0; FieldType[NumberOfBaryonFields++] = Density; FieldType[NumberOfBaryonFields++] = TotalEnergy; @@ -55,154 +56,156 @@ int grid::TestGravitySphereInitializeGrid(float SphereInteriorDensity, if (WritePotential) FieldType[NumberOfBaryonFields++] = GravPotential; - } - + /* Return if this doesn't concern us. */ - + if (ProcessorNumber != MyProcessorNumber) return SUCCESS; - + /* Set particles. */ - - if (NumberOfParticles > 0) { - + + 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++) { - + for (i = 1; i < NumberOfParticles; i++) + { + #ifdef UNUSED - - ParticlePosition[dim][i] = FLOAT(rand())/FLOAT(RAND_MAX); - + + ParticlePosition[dim][i] = FLOAT(rand()) / FLOAT(RAND_MAX); + #endif /* UNUSED */ - - ParticleVelocity[dim][i] = 0.0; - - ParticleMass[i] = tiny_number; - + + 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++) { - + + 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); - + + 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); + 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); + + 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]; - + ParticlePosition[dim][i] += SphereCenter[dim]; + /* Set particle identifier. */ - + ParticleNumber[i] = i; - ParticleType[i] = PARTICLE_TYPE_DARK_MATTER; - + ParticleType[i] = PARTICLE_TYPE_DARK_MATTER; } - } - + /* If requested, set up the baryon field. */ - - if (UseBaryons) { - + + 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(r/SphereRadius, - float(-2.25)); - } - else - density = SphereExteriorDensity; - - BaryonField[0][k*GridDimension[0]*GridDimension[1] + - j*GridDimension[0] + i] = - density; - } - + 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; - + 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; - + 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 b46b21da5..a5d50f119 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, double hmcoef = 5.9157166856e27*TimeUnits/POW(LengthUnits,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 e47f8491d..a9d339a1d 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 @@ -124,28 +124,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); @@ -156,7 +156,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, @@ -196,7 +196,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, @@ -213,22 +213,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 @@ -239,6 +239,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, @@ -246,32 +255,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; @@ -281,18 +290,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."); } @@ -303,7 +312,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) { @@ -316,27 +325,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, @@ -345,11 +354,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); @@ -359,69 +368,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); @@ -436,19 +445,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); @@ -457,56 +466,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); @@ -514,26 +533,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 @@ -553,14 +583,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); @@ -580,22 +610,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); @@ -604,20 +634,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); @@ -749,17 +779,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) @@ -768,7 +798,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) } @@ -777,40 +807,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"); @@ -821,8 +851,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; @@ -835,45 +865,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) @@ -886,16 +916,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]; @@ -904,55 +934,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) { @@ -961,9 +991,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) { @@ -975,11 +1005,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)."); @@ -990,14 +1020,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) { @@ -1011,8 +1041,8 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, == FAIL) { ENZO_FAIL("Error in MHD2DTestReInitialize.\n"); } - - + + if (ProblemType == 202) CollapseMHD3DInitialize(fptr, Outfptr, TopGrid, MetaData, 1); @@ -1023,7 +1053,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) @@ -1032,11 +1062,11 @@ int InitializeNew(char *filename, HierarchyEntry &TopGrid, } CommunicationBarrier(); - + // Close parameter files - + fclose(fptr); - + if (MyProcessorNumber == ROOT_PROCESSOR) fclose(Outfptr); @@ -1046,25 +1076,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 15f650163..d46b8833e 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\ @@ -163,6 +164,9 @@ OBJS_CONFIG_LIB = \ DepositBaryons.o \ DepositParticleMassField.o \ DepositParticleMassFlaggingField.o \ + DepositPositionsTSC1d.o \ + DepositPositionsTSC2d.o \ + DepositPositionsTSC3d.o \ DetermineNumberOfNodes.o \ DetermineParallelism.o \ DetermineSubgridSizeExtrema.o \ @@ -225,7 +229,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 \ @@ -331,6 +335,7 @@ OBJS_CONFIG_LIB = \ gFLDSplit_SetupSystem.o \ gFLDSplit_WriteParameters.o \ GravityEquilibriumTestInitialize.o \ + GreensFunction.o \ Grid_AccelerationBoundaryRoutines.o \ Grid_AccessBaryonFields.o \ Grid_AccreteOntoAccretingParticle.o \ @@ -348,6 +353,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 \ @@ -401,6 +408,7 @@ OBJS_CONFIG_LIB = \ Grid_ComovingGravitySourceTerm.o \ Grid_ComputeAccelerationFieldExternal.o \ Grid_ComputeAccelerationField.o \ + Grid_ComputeAccelerationFieldAPM.o \ Grid_ComputeAccelerations.o \ Grid_ComputeAccelerationsFromExternalPotential.o \ Grid_ComputeCellCenteredField.o \ @@ -418,6 +426,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 \ @@ -561,7 +570,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 \ @@ -570,7 +581,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 \ @@ -627,7 +637,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 \ @@ -641,12 +651,16 @@ OBJS_CONFIG_LIB = \ Grid_StratifiedMediumExplosionInitialize.o \ Grid_SupernovaRestartInitialize.o \ Grid_SubtractAccretedMassFromSphere.o \ + Grid_TestGravityAPMInitializeGrid.o \ Grid_TestGravityCheckResults.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 \ @@ -707,11 +721,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 \ @@ -733,6 +750,7 @@ OBJS_CONFIG_LIB = \ mbh_maker.o \ mcooling.o \ MakeFieldConservative.o\ + make_green.o \ MemoryAllocationRoutines.o \ MemoryPoolRoutines.o \ MersenneTwister.o \ @@ -747,6 +765,7 @@ OBJS_CONFIG_LIB = \ MultigridSolver.o \ mused.o \ NestedCosmologySimulationInitialize.o \ + NextLargestFFTSize.o \ ngpinterp.o \ ngp_deposit.o \ ngp_deposit_c.o \ @@ -757,6 +776,8 @@ OBJS_CONFIG_LIB = \ nr_st1.o \ NullProblem.o \ OneZoneFreefallTestInitialize.o \ + OutputAccelerationField.o \ + OutputGravitatingMassField.o \ OutputAsParticleData.o \ OutputCoolingTimeOnly.o \ OutputDustTemperatureOnly.o \ @@ -925,16 +946,20 @@ 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 \ TestGravityInitialize.o \ TestGravityMotion.o \ + TestGravitySineWaveInitialize.o \ + TestGravitySphereAPMInitialize.o \ TestGravitySphereCheckResults.o \ TestGravitySphereInitialize.o \ TestOrbitInitialize.o \ + TestSelfForceInitialize.o \ TestStarParticleInitialize.o \ TracerParticleCreation.o \ TransposeRegionOverlap.o \ @@ -1225,7 +1250,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 \ @@ -1236,6 +1261,4 @@ OBJS_ECUDA_ALL = \ hydro_rk/Grid_CudaMHDRK2_2ndStep.o \ cuPPM.o \ CUDAUtil.o \ - SaveSubgridFluxCUDA.o - - + SaveSubgridFluxCUDA.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..7d9a26c40 --- /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)/local +#LOCAL_HYPRE_INSTALL = /usr + +#----------------------------------------------------------------------- +# 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..0ffa36df8 --- /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 = /Applications/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 c11c146fe..ce77ef369 100644 --- a/src/enzo/ReadParameterFile.C +++ b/src/enzo/ReadParameterFile.C @@ -16,11 +16,11 @@ / RETURNS: SUCCESS or FAIL / ************************************************************************/ - + // This routine reads the parameter file in the argument and sets parameters // based on it. -#include "preincludes.h" +#include "preincludes.h" #include #include #include @@ -32,18 +32,18 @@ #include "ExternalBoundary.h" #include "Grid.h" #include "TopGridData.h" -#include "hydro_rk/EOS.h" +#include "hydro_rk/EOS.h" #include "CosmologyParameters.h" #include "phys_constants.h" #include "ActiveParticle.h" /* This variable is declared here and only used in Grid_ReadGrid. */ - + /* function prototypes */ -void my_exit(int status); +void my_exit(int status); int ReadListOfFloats(FILE *fptr, int N, float floats[]); int ReadListOfInts(FILE *fptr, int N, int nums[]); int CosmologyReadParameters(FILE *fptr, FLOAT *StopTime, FLOAT *InitTime); @@ -58,8 +58,8 @@ int GetUnits(float *DensityUnits, float *LengthUnits, float *VelocityUnits, double *MassUnits, FLOAT Time); int CosmologyComputeExpansionFactor(FLOAT time, FLOAT *a, FLOAT *dadt); int ReadEvolveRefineFile(void); - -int CheckShearingBoundaryConsistency(TopGridData &MetaData); + +int CheckShearingBoundaryConsistency(TopGridData &MetaData); void get_uuid(char *buffer); int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) @@ -67,7 +67,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* declarations */ - + char line[MAX_LINE_LENGTH]; int i, dim, ret, int_dummy; float TempFloat, float_dummy; @@ -78,29 +78,29 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) char **active_particle_types; active_particle_types = new char*[MAX_ACTIVE_PARTICLE_TYPES]; int active_particles = 0; - + /* read until out of lines */ rewind(fptr); - while ((fgets(line, MAX_LINE_LENGTH, fptr) != NULL) + while ((fgets(line, MAX_LINE_LENGTH, fptr) != NULL) && (comment_count < 2)) { ret = 0; - + /* read MetaData parameters */ - + ret += sscanf(line, "InitialCycleNumber = %"ISYM, &MetaData.CycleNumber); ret += sscanf(line, "InitialTime = %"PSYM, &MetaData.Time); ret += sscanf(line, "InitialCPUTime = %lf", &MetaData.CPUTime); ret += sscanf(line, "Initialdt = %"FSYM, Initialdt); - + ret += sscanf(line, "CheckpointRestart = %"ISYM, &CheckpointRestart); ret += sscanf(line, "StopTime = %"PSYM, &MetaData.StopTime); ret += sscanf(line, "StopCycle = %"ISYM, &MetaData.StopCycle); ret += sscanf(line, "StopSteps = %"ISYM, &MetaData.StopSteps); ret += sscanf(line, "StopCPUTime = %"FSYM, &MetaData.StopCPUTime); ret += sscanf(line, "ResubmitOn = %"ISYM, &MetaData.ResubmitOn); - if (sscanf(line, "ResubmitCommand = %s", dummy) == 1) + if (sscanf(line, "ResubmitCommand = %s", dummy) == 1) MetaData.ResubmitCommand = dummy; ret += sscanf(line, "MaximumTopGridTimeStep = %"FSYM, @@ -115,7 +115,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "TimeLastHistoryDump = %"PSYM, &MetaData.TimeLastHistoryDump); ret += sscanf(line, "dtHistoryDump = %"PSYM, &MetaData.dtHistoryDump); - + ret += sscanf(line, "TracerParticleOn = %"ISYM, &TracerParticleOn); ret += sscanf(line, "TracerParticleOutputVelocity = %"ISYM, &TracerParticleOutputVelocity); ret += sscanf(line, "WriteGhostZones = %"ISYM, &WriteGhostZones); @@ -128,15 +128,15 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &MetaData.dtTracerParticleDump); ret += sscanf(line, "TimeLastInterpolatedDataDump = %"PSYM, &MetaData.TimeLastInterpolatedDataDump); - ret += sscanf(line, "dtInterpolatedDataDump = %"PSYM, + ret += sscanf(line, "dtInterpolatedDataDump = %"PSYM, &MetaData.dtInterpolatedDataDump); - - ret += sscanf(line, "NewMovieLeftEdge = %"PSYM" %"PSYM" %"PSYM, + + ret += sscanf(line, "NewMovieLeftEdge = %"PSYM" %"PSYM" %"PSYM, MetaData.NewMovieLeftEdge, - MetaData.NewMovieLeftEdge+1, + MetaData.NewMovieLeftEdge+1, MetaData.NewMovieLeftEdge+2); - ret += sscanf(line, "NewMovieRightEdge = %"PSYM" %"PSYM" %"PSYM, - MetaData.NewMovieRightEdge, + ret += sscanf(line, "NewMovieRightEdge = %"PSYM" %"PSYM" %"PSYM, + MetaData.NewMovieRightEdge, MetaData.NewMovieRightEdge+1, MetaData.NewMovieRightEdge+2); @@ -178,26 +178,26 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &EnrichedMetalFraction); /* Subcycle directed output */ - ret += sscanf(line, "SubcycleSkipDataDump = %"ISYM, + ret += sscanf(line, "SubcycleSkipDataDump = %"ISYM, &MetaData.SubcycleSkipDataDump); - ret += sscanf(line, "SubcycleLastDataDump = %"ISYM, + ret += sscanf(line, "SubcycleLastDataDump = %"ISYM, &MetaData.SubcycleLastDataDump); - ret += sscanf(line, "SubcycleNumber = %"ISYM, + ret += sscanf(line, "SubcycleNumber = %"ISYM, &MetaData.SubcycleNumber); ret += sscanf(line,"FileDirectedOutput = %"ISYM, &FileDirectedOutput); ret += sscanf(line,"HierarchyFileInputFormat = %"ISYM, - &HierarchyFileInputFormat); + &HierarchyFileInputFormat); ret += sscanf(line,"HierarchyFileOutputFormat = %"ISYM, - &HierarchyFileOutputFormat); + &HierarchyFileOutputFormat); ret += sscanf(line, "RestartDumpNumber = %"ISYM, &MetaData.RestartDumpNumber); ret += sscanf(line, "DataDumpNumber = %"ISYM, &MetaData.DataDumpNumber); ret += sscanf(line, "HistoryDumpNumber = %"ISYM, &MetaData.HistoryDumpNumber); ret += sscanf(line, "TracerParticleDumpNumber = %"ISYM, &MetaData.TracerParticleDumpNumber); - + if (sscanf(line, "RestartDumpName = %s", dummy) == 1) MetaData.RestartDumpName = dummy; if (sscanf(line, "DataDumpName = %s", dummy) == 1) @@ -208,7 +208,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) MetaData.TracerParticleDumpName = dummy; if (sscanf(line, "RedshiftDumpName = %s", dummy) == 1) MetaData.RedshiftDumpName = dummy; - + if (sscanf(line, "RestartDumpDir = %s", dummy) == 1) MetaData.RestartDumpDir = dummy; if (sscanf(line, "DataDumpDir = %s", dummy) == 1) @@ -219,12 +219,12 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) MetaData.TracerParticleDumpDir = dummy; if (sscanf(line, "RedshiftDumpDir = %s", dummy) == 1) MetaData.RedshiftDumpDir = dummy; - + if (sscanf(line, "LocalDir = %s", dummy) == 1) MetaData.LocalDir = dummy; if (sscanf(line, "GlobalDir = %s", dummy) == 1) MetaData.GlobalDir = dummy; - + if (sscanf(line, "CubeDump[%"ISYM"] = %s", &dim, dummy) == 2) { ret++; CubeDumps[dim] = dummy; if (dim >= MAX_CUBE_DUMPS) { @@ -238,10 +238,10 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "LoadBalancingCycleSkip = %"ISYM, &LoadBalancingCycleSkip); ret += sscanf(line, "LoadBalancingMinLevel = %"ISYM, &LoadBalancingMinLevel); ret += sscanf(line, "LoadBalancingMaxLevel = %"ISYM, &LoadBalancingMaxLevel); - - ret += sscanf(line, "ConductionDynamicRebuildHierarchy = %"ISYM, + + ret += sscanf(line, "ConductionDynamicRebuildHierarchy = %"ISYM, &ConductionDynamicRebuildHierarchy); - ret += sscanf(line, "ConductionDynamicRebuildMinLevel = %"ISYM, + ret += sscanf(line, "ConductionDynamicRebuildMinLevel = %"ISYM, &ConductionDynamicRebuildMinLevel); if (sscanf(line, "RebuildHierarchyCycleSkip[%"ISYM"] =", &int_dummy) == 1) { if (int_dummy > MAX_DEPTH_OF_HIERARCHY) { @@ -267,16 +267,16 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (sscanf(line, "TimeActionParameter[%"ISYM"] = ", &dim) == 1) ret += sscanf(line, "TimeActionParameter[%"ISYM"] = %"FSYM, &dim, TimeActionParameter+dim); - + ret += sscanf(line, "StaticHierarchy = %"ISYM, &MetaData.StaticHierarchy); - + ret += sscanf(line, "TopGridRank = %"ISYM, &MetaData.TopGridRank); ret += sscanf(line, "TopGridDimensions = %"ISYM" %"ISYM" %"ISYM, MetaData.TopGridDims, MetaData.TopGridDims+1, MetaData.TopGridDims+2); - + ret += sscanf(line, "TopGridGravityBoundary = %"ISYM, &MetaData.GravityBoundary); - + #ifdef TRANSFER if (sscanf(line, "RadHydroParamfile = %s", dummy) == 1) MetaData.RadHydroParameterFname = dummy; @@ -284,7 +284,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "ImplicitProblem = %"ISYM, &ImplicitProblem); ret += sscanf(line, "RadiativeTransferFLD = %"ISYM, &RadiativeTransferFLD); #ifdef EMISSIVITY - ret += sscanf(line, "StarMakerEmissivityField = %"ISYM, + ret += sscanf(line, "StarMakerEmissivityField = %"ISYM, &StarMakerEmissivityField); ret += sscanf(line, "uv_param = %"FSYM, &uv_param); #endif @@ -293,7 +293,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &MetaData.ParticleBoundaryType); ret += sscanf(line, "NumberOfParticles = %"PISYM, &MetaData.NumberOfParticles); - + ret += sscanf(line, "CourantSafetyNumber = %"FSYM, &MetaData.CourantSafetyNumber); ret += sscanf(line, "PPMFlatteningParameter = %"ISYM, @@ -302,9 +302,9 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &MetaData.PPMDiffusionParameter); ret += sscanf(line, "PPMSteepeningParameter = %"ISYM, &MetaData.PPMSteepeningParameter); - + /* read global Parameters */ - + ret += sscanf(line, "ProblemType = %"ISYM, &ProblemType); #ifdef NEW_PROBLEM_TYPES if (sscanf(line, "ProblemTypeName = %s", dummy) == 1) { @@ -343,7 +343,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &ConservativeInterpolation); ret += sscanf(line, "MinimumEfficiency = %"FSYM, &MinimumEfficiency); ret += sscanf(line, "SubgridSizeAutoAdjust = %"ISYM, &SubgridSizeAutoAdjust); - ret += sscanf(line, "OptimalSubgridsPerProcessor = %"ISYM, + ret += sscanf(line, "OptimalSubgridsPerProcessor = %"ISYM, &OptimalSubgridsPerProcessor); ret += sscanf(line, "MinimumSubgridEdge = %"ISYM, &MinimumSubgridEdge); ret += sscanf(line, "MaximumSubgridSize = %"ISYM, &MaximumSubgridSize); @@ -354,9 +354,9 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &MustRefineRegionMinRefinementLevel); ret += sscanf(line, "MetallicityRefinementMinLevel = %"ISYM, &MetallicityRefinementMinLevel); - ret += sscanf(line, "MetallicityRefinementMinMetallicity = %"FSYM, + ret += sscanf(line, "MetallicityRefinementMinMetallicity = %"FSYM, &MetallicityRefinementMinMetallicity); - ret += sscanf(line, "MetallicityRefinementMinDensity = %"FSYM, + ret += sscanf(line, "MetallicityRefinementMinDensity = %"FSYM, &MetallicityRefinementMinDensity); ret += sscanf(line, "DomainLeftEdge = %"PSYM" %"PSYM" %"PSYM, DomainLeftEdge, @@ -378,14 +378,14 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "MustRefineRegionRightEdge = %"PSYM" %"PSYM" %"PSYM, MustRefineRegionRightEdge, MustRefineRegionRightEdge+1, MustRefineRegionRightEdge+2); - + /* Parameters for the MultiRefineRegion mechanics */ - + ret += sscanf(line, "MultiRefineRegionMaximumOuterLevel = %"ISYM, &MultiRefineRegionMaximumOuterLevel); ret += sscanf(line, "MultiRefineRegionMinimumOuterLevel = %"ISYM, &MultiRefineRegionMinimumOuterLevel); - if (sscanf(line, "MultiRefineRegionMaximumLevel[%"ISYM"] = %"ISYM, &dim, &int_dummy) == 2) + if (sscanf(line, "MultiRefineRegionMaximumLevel[%"ISYM"] = %"ISYM, &dim, &int_dummy) == 2) { - if (dim > MAX_STATIC_REGIONS-1) + if (dim > MAX_STATIC_REGIONS-1) ENZO_VFAIL("MultiRefineRegion number %"ISYM" (MAX_STATIC_REGIONS) > MAX allowed\n", dim); ret++; MultiRefineRegionMaximumLevel[dim] = int_dummy; @@ -479,7 +479,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) DataLabel[dim] = dummy; if (sscanf(line, "DataUnits[%"ISYM"] = %s\n", &dim, dummy) == 2) DataUnits[dim] = dummy; - + ret += sscanf(line, "StoreDomainBoundaryMassFlux = %"ISYM, &StoreDomainBoundaryMassFlux); if (sscanf(line, "BoundaryMassFluxFilename = %s", dummy) == 1) { BoundaryMassFluxFilename = dummy; @@ -493,13 +493,13 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (sscanf(line, "BoundaryMassFluxContainer[%"ISYM"] = %"FSYM, &dim, &float_dummy)){ BoundaryMassFluxContainer[dim] = float_dummy; ret++; } - + ret += sscanf(line, "UniformGravity = %"ISYM, &UniformGravity); ret += sscanf(line, "UniformGravityDirection = %"ISYM, &UniformGravityDirection); ret += sscanf(line, "UniformGravityConstant = %"FSYM, &UniformGravityConstant); - + ret += sscanf(line, "PointSourceGravity = %"ISYM,&PointSourceGravity); ret += sscanf(line, "PointSourceGravityPosition = %"PSYM" %"PSYM" %"PSYM, PointSourceGravityPosition, PointSourceGravityPosition+1, @@ -508,7 +508,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &PointSourceGravityConstant); ret += sscanf(line, "PointSourceGravityCoreRadius = %"FSYM, &PointSourceGravityCoreRadius); - + ret += sscanf(line, "DiskGravity = %"ISYM,&DiskGravity); ret += sscanf(line, "DiskGravityPosition = %"PSYM" %"PSYM" %"PSYM, DiskGravityPosition, DiskGravityPosition+1, DiskGravityPosition+2); @@ -530,12 +530,24 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "ExternalGravityPosition = %"PSYM" %"PSYM" %"PSYM, ExternalGravityPosition, ExternalGravityPosition+1, ExternalGravityPosition+2); - ret += sscanf(line, "ExternalGravityOrientation = %"FSYM" %"FSYM" %"FSYM, - ExternalGravityOrientation, ExternalGravityOrientation+1, + ret += sscanf(line, "ExternalGravityOrientation = %"FSYM" %"FSYM" %"FSYM, + ExternalGravityOrientation, ExternalGravityOrientation+1, ExternalGravityOrientation+2); 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); @@ -543,7 +555,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "WritePotential = %"ISYM, &WritePotential); ret += sscanf(line, "ParticleSubgridDepositMode = %"ISYM, &ParticleSubgridDepositMode); ret += sscanf(line, "WriteAcceleration = %"ISYM, &WriteAcceleration); - + ret += sscanf(line, "DualEnergyFormalism = %"ISYM, &DualEnergyFormalism); ret += sscanf(line, "DualEnergyFormalismEta1 = %"FSYM, &DualEnergyFormalismEta1); @@ -569,7 +581,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) DrivenFlowVelocity, DrivenFlowVelocity+1, DrivenFlowVelocity+2); ret += sscanf(line, "DrivenFlowAutoCorrl = %"FSYM"%"FSYM"%"FSYM, DrivenFlowAutoCorrl, DrivenFlowAutoCorrl+1, DrivenFlowAutoCorrl+2); - + ret += sscanf(line, "UseSGSModel = %"ISYM, &UseSGSModel); ret += sscanf(line, "SGSFilterStencil = %"ISYM, &SGSFilterStencil); ret += sscanf(line, "SGSFilterWidth = %"FSYM, &SGSFilterWidth); @@ -605,9 +617,9 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret++; } ret += sscanf(line, "UVbackground = %d", &grackle_data->UVbackground); - ret += sscanf(line, "Compton_xray_heating = %d", + ret += sscanf(line, "Compton_xray_heating = %d", &grackle_data->Compton_xray_heating); - ret += sscanf(line, "LWbackground_intensity = %lf", + ret += sscanf(line, "LWbackground_intensity = %lf", &grackle_data->LWbackground_intensity); ret += sscanf(line, "LWbackground_sawtooth_suppression = %d", &grackle_data->LWbackground_sawtooth_suppression); @@ -634,7 +646,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret++; } - ret += sscanf(line, "CRModel = %"ISYM, &CRModel); + ret += sscanf(line, "CRModel = %"ISYM, &CRModel); ret += sscanf(line, "CRDiffusion = %"ISYM, &CRDiffusion); ret += sscanf(line, "CRkappa = %"FSYM, &CRkappa); ret += sscanf(line, "CRCourantSafetyNumber = %"FSYM, &CRCourantSafetyNumber); @@ -656,7 +668,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "AdjustUVBackgroundHighRedshift = %"ISYM, &AdjustUVBackgroundHighRedshift); ret += sscanf(line, "SetUVBAmplitude = %"FSYM, &SetUVBAmplitude); ret += sscanf(line, "SetHeIIHeatingScale = %"FSYM, &SetHeIIHeatingScale); - ret += sscanf(line, "RadiationFieldLevelRecompute = %"ISYM, &RadiationFieldLevelRecompute); + ret += sscanf(line, "RadiationFieldLevelRecompute = %"ISYM, &RadiationFieldLevelRecompute); ret += sscanf(line, "RadiationShield = %"ISYM, &RadiationData.RadiationShield); ret += sscanf(line, "RadiationSpectrumNormalization = %"FSYM, &CoolData.f3); ret += sscanf(line, "RadiationSpectrumSlope = %"FSYM, &CoolData.alpha0); @@ -686,18 +698,18 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "OutputTemperature = %"ISYM, &OutputTemperature); ret += sscanf(line, "OutputDustTemperature = %"ISYM, &OutputDustTemperature); - ret += sscanf(line, "OutputSmoothedDarkMatter = %"ISYM, + ret += sscanf(line, "OutputSmoothedDarkMatter = %"ISYM, &OutputSmoothedDarkMatter); - ret += sscanf(line, "SmoothedDarkMatterNeighbors = %"ISYM, + ret += sscanf(line, "SmoothedDarkMatterNeighbors = %"ISYM, &SmoothedDarkMatterNeighbors); - ret += sscanf(line, "OutputGriddedStarParticle = %"ISYM, + ret += sscanf(line, "OutputGriddedStarParticle = %"ISYM, &OutputGriddedStarParticle); ret += sscanf(line, "ZEUSQuadraticArtificialViscosity = %"FSYM, &ZEUSQuadraticArtificialViscosity); ret += sscanf(line, "ZEUSLinearArtificialViscosity = %"FSYM, &ZEUSLinearArtificialViscosity); - + ret += sscanf(line, "UseMinimumPressureSupport = %"ISYM, &UseMinimumPressureSupport); ret += sscanf(line, "MinimumPressureSupportParameter = %"FSYM, @@ -713,7 +725,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "MustRefineParticlesCreateParticles = %"ISYM, &MustRefineParticlesCreateParticles); ret += sscanf(line, "MustRefineParticlesLeftEdge = %"PSYM" %"PSYM" %"PSYM, - MustRefineParticlesLeftEdge, MustRefineParticlesLeftEdge+1, + MustRefineParticlesLeftEdge, MustRefineParticlesLeftEdge+1, MustRefineParticlesLeftEdge+2); ret += sscanf(line, "MustRefineParticlesRightEdge = %"PSYM" %"PSYM" %"PSYM, MustRefineParticlesRightEdge, MustRefineParticlesRightEdge+1, @@ -744,7 +756,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &dim, AvoidRefineRegionRightEdge[dim], AvoidRefineRegionRightEdge[dim]+1, AvoidRefineRegionRightEdge[dim]+2); - + if (sscanf(line, "StaticRefineRegionLevel[%"ISYM"] = %"ISYM,&dim,&int_dummy) == 2){ if (dim > MAX_STATIC_REGIONS-1) { ENZO_VFAIL("StaticRegion number %"ISYM" > MAX allowed\n", dim) @@ -764,11 +776,11 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &dim, StaticRefineRegionRightEdge[dim], StaticRefineRegionRightEdge[dim]+1, StaticRefineRegionRightEdge[dim]+2); - + ret += sscanf(line, "ParallelRootGridIO = %"ISYM, &ParallelRootGridIO); - + ret += sscanf(line, "ParallelParticleIO = %"ISYM, &ParallelParticleIO); - + ret += sscanf(line, "Unigrid = %"ISYM, &Unigrid); ret += sscanf(line, "UnigridTranspose = %"ISYM, &UnigridTranspose); ret += sscanf(line, "NumberOfRootGridTilesPerDimensionPerProcessor = %"ISYM, &NumberOfRootGridTilesPerDimensionPerProcessor); @@ -776,11 +788,11 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &UserDefinedRootGridLayout[1], &UserDefinedRootGridLayout[2]); ret += sscanf(line, "PartitionNestedGrids = %"ISYM, &PartitionNestedGrids); - + ret += sscanf(line, "ExtractFieldsOnly = %"ISYM, &ExtractFieldsOnly); - + ret += sscanf(line, "CubeDumpEnabled = %"ISYM, &CubeDumpEnabled); - + ret += sscanf(line, "Debug1 = %"ISYM, &debug1); ret += sscanf(line, "Debug2 = %"ISYM, &debug2); @@ -805,43 +817,43 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "SlopeFlaggingFields = " " %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM, - SlopeFlaggingFields+0, + SlopeFlaggingFields+0, SlopeFlaggingFields+1, - SlopeFlaggingFields+2, + SlopeFlaggingFields+2, SlopeFlaggingFields+3, SlopeFlaggingFields+4, SlopeFlaggingFields+5, SlopeFlaggingFields+6); - - ret += sscanf(line, "MinimumSlopeForRefinement = " + + ret += sscanf(line, "MinimumSlopeForRefinement = " " %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM, - + MinimumSlopeForRefinement+0, MinimumSlopeForRefinement+1, MinimumSlopeForRefinement+2, MinimumSlopeForRefinement+3, - MinimumSlopeForRefinement+4, + MinimumSlopeForRefinement+4, MinimumSlopeForRefinement+5, MinimumSlopeForRefinement+6); ret += sscanf(line, "SecondDerivativeFlaggingFields = " " %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM" %"ISYM, - SecondDerivativeFlaggingFields+0, + SecondDerivativeFlaggingFields+0, SecondDerivativeFlaggingFields+1, - SecondDerivativeFlaggingFields+2, + SecondDerivativeFlaggingFields+2, SecondDerivativeFlaggingFields+3, SecondDerivativeFlaggingFields+4, SecondDerivativeFlaggingFields+5, SecondDerivativeFlaggingFields+6); - - ret += sscanf(line, "MinimumSecondDerivativeForRefinement = " + + ret += sscanf(line, "MinimumSecondDerivativeForRefinement = " " %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM, - + MinimumSecondDerivativeForRefinement+0, MinimumSecondDerivativeForRefinement+1, MinimumSecondDerivativeForRefinement+2, MinimumSecondDerivativeForRefinement+3, - MinimumSecondDerivativeForRefinement+4, + MinimumSecondDerivativeForRefinement+4, MinimumSecondDerivativeForRefinement+5, MinimumSecondDerivativeForRefinement+6); @@ -850,21 +862,21 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "MinimumOverDensityForRefinement = " " %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM, - MinimumOverDensityForRefinement+0, + MinimumOverDensityForRefinement+0, MinimumOverDensityForRefinement+1, - MinimumOverDensityForRefinement+2, + MinimumOverDensityForRefinement+2, MinimumOverDensityForRefinement+3, - MinimumOverDensityForRefinement+4, + MinimumOverDensityForRefinement+4, MinimumOverDensityForRefinement+5, MinimumOverDensityForRefinement+6); ret += sscanf(line, "MinimumMassForRefinement = " " %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM, - MinimumMassForRefinement+0, + MinimumMassForRefinement+0, MinimumMassForRefinement+1, - MinimumMassForRefinement+2, + MinimumMassForRefinement+2, MinimumMassForRefinement+3, - MinimumMassForRefinement+4, + MinimumMassForRefinement+4, MinimumMassForRefinement+5, MinimumMassForRefinement+6); @@ -906,17 +918,17 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &NumberOfParticleAttributes); /* read data which defines the boundary conditions */ - + ret += sscanf(line, "LeftFaceBoundaryCondition = %"ISYM" %"ISYM" %"ISYM, MetaData.LeftFaceBoundaryCondition, MetaData.LeftFaceBoundaryCondition+1, MetaData.LeftFaceBoundaryCondition+2); - + ret += sscanf(line, "RightFaceBoundaryCondition = %"ISYM" %"ISYM" %"ISYM, MetaData.RightFaceBoundaryCondition, MetaData.RightFaceBoundaryCondition+1, MetaData.RightFaceBoundaryCondition+2); - + if (sscanf(line, "BoundaryConditionName = %s", dummy) == 1) MetaData.BoundaryConditionName = dummy; @@ -936,9 +948,9 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) MetaData.InitialConditionsUUID = dummy; ret++; } - + /* Check version number. */ - + if (sscanf(line, "VersionNumber = %"FSYM, &TempFloat) == 1) { ret++; if (fabs(TempFloat - VERSION) >= 1.0e-3 && @@ -960,7 +972,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "GalaxySimulationPreWindTotalEnergy = %"FSYM,&GalaxySimulationPreWindTotalEnergy); ret += sscanf(line, "GalaxySimulationPreWindVelocity = %"PSYM" %"PSYM" %"PSYM, GalaxySimulationPreWindVelocity,GalaxySimulationPreWindVelocity+1,GalaxySimulationPreWindVelocity+2); - + /* Read star particle parameters. */ ret += sscanf(line, "StarMakerTypeIaSNe = %"ISYM, @@ -991,53 +1003,53 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) &StarEnergyToThermalFeedback); ret += sscanf(line, "StarEnergyToStellarUV = %"FSYM, &StarEnergyToStellarUV); ret += sscanf(line, "StarEnergyToQuasarUV = %"FSYM, &StarEnergyToQuasarUV); - ret += sscanf(line, "StarFeedbackKineticFraction = %"FSYM, + ret += sscanf(line, "StarFeedbackKineticFraction = %"FSYM, &StarFeedbackKineticFraction); - ret += sscanf(line, "StarMakerExplosionDelayTime = %"FSYM, + ret += sscanf(line, "StarMakerExplosionDelayTime = %"FSYM, &StarMakerExplosionDelayTime); ret += sscanf(line, "StarFeedbackDistRadius = %"ISYM, &StarFeedbackDistRadius); ret += sscanf(line, "StarFeedbackDistCellStep = %"ISYM, &StarFeedbackDistCellStep); ret += sscanf(line, "StarMakerUseJeansMass = %"ISYM, &StarMakerUseJeansMass); - - ret += sscanf(line, "StarClusterUseMetalField = %"ISYM, + + ret += sscanf(line, "StarClusterUseMetalField = %"ISYM, &StarClusterUseMetalField); - ret += sscanf(line, "StarClusterMinDynamicalTime = %"FSYM, + ret += sscanf(line, "StarClusterMinDynamicalTime = %"FSYM, &StarClusterMinDynamicalTime); - ret += sscanf(line, "StarClusterHeliumIonization = %"ISYM, + ret += sscanf(line, "StarClusterHeliumIonization = %"ISYM, &StarClusterHeliumIonization); - ret += sscanf(line, "StarClusterUnresolvedModel = %"ISYM, + ret += sscanf(line, "StarClusterUnresolvedModel = %"ISYM, &StarClusterUnresolvedModel); - ret += sscanf(line, "StarClusterIonizingLuminosity = %lf", + ret += sscanf(line, "StarClusterIonizingLuminosity = %lf", &StarClusterIonizingLuminosity); ret += sscanf(line, "StarClusterSNEnergy = %lf", &StarClusterSNEnergy); ret += sscanf(line, "StarClusterSNRadius = %"FSYM, &StarClusterSNRadius); - ret += sscanf(line, "StarClusterFormEfficiency = %"FSYM, + ret += sscanf(line, "StarClusterFormEfficiency = %"FSYM, &StarClusterFormEfficiency); - ret += sscanf(line, "StarClusterMinimumMass = %"FSYM, + ret += sscanf(line, "StarClusterMinimumMass = %"FSYM, &StarClusterMinimumMass); ret += sscanf(line, "StarClusterCombineRadius = %"FSYM, &StarClusterCombineRadius); ret += sscanf(line, "StarClusterRegionLeftEdge = %"FSYM" %"FSYM" %"FSYM, - StarClusterRegionLeftEdge, StarClusterRegionLeftEdge+1, + StarClusterRegionLeftEdge, StarClusterRegionLeftEdge+1, StarClusterRegionLeftEdge+2); ret += sscanf(line, "StarClusterRegionRightEdge = %"FSYM" %"FSYM" %"FSYM, - StarClusterRegionRightEdge, StarClusterRegionRightEdge+1, + StarClusterRegionRightEdge, StarClusterRegionRightEdge+1, StarClusterRegionRightEdge+2); ret += sscanf(line, "PopIIIStarMass = %"FSYM, &PopIIIStarMass); - ret += sscanf(line, "PopIIIInitialMassFunction = %"ISYM, + ret += sscanf(line, "PopIIIInitialMassFunction = %"ISYM, &PopIIIInitialMassFunction); - ret += sscanf(line, "PopIIIInitialMassFunctionSeed = %"ISYM, + ret += sscanf(line, "PopIIIInitialMassFunctionSeed = %"ISYM, &PopIIIInitialMassFunctionSeed); - ret += sscanf(line, "PopIIIInitialMassFunctionCalls = %"ISYM, + ret += sscanf(line, "PopIIIInitialMassFunctionCalls = %"ISYM, &PopIIIInitialMassFunctionCalls); ret += sscanf(line, "PopIIIMassRange = %"FSYM" %"FSYM, &PopIIILowerMassCutoff, &PopIIIUpperMassCutoff); - ret += sscanf(line, "PopIIIInitialMassFunctionSlope = %"FSYM, + ret += sscanf(line, "PopIIIInitialMassFunctionSlope = %"FSYM, &PopIIIInitialMassFunctionSlope); ret += sscanf(line, "PopIIIBlackHoles = %"ISYM, &PopIIIBlackHoles); - ret += sscanf(line, "PopIIIBHLuminosityEfficiency = %"FSYM, + ret += sscanf(line, "PopIIIBHLuminosityEfficiency = %"FSYM, &PopIIIBHLuminosityEfficiency); ret += sscanf(line, "PopIIIOverDensityThreshold = %"FSYM, &PopIIIOverDensityThreshold); @@ -1046,13 +1058,13 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "PopIIIMetalCriticalFraction = %"FSYM, &PopIIIMetalCriticalFraction); ret += sscanf(line, "PopIIISupernovaRadius = %"FSYM, &PopIIISupernovaRadius); - ret += sscanf(line, "PopIIISupernovaUseColour = %"ISYM, + ret += sscanf(line, "PopIIISupernovaUseColour = %"ISYM, &PopIIISupernovaUseColour); ret += sscanf(line, "PopIIISupernovaMustRefine = %"ISYM, &PopIIISupernovaMustRefine); ret += sscanf(line, "PopIIISupernovaMustRefineResolution = %"ISYM, &PopIIISupernovaMustRefineResolution); - ret += sscanf(line, "PopIIIHeliumIonization = %"ISYM, + ret += sscanf(line, "PopIIIHeliumIonization = %"ISYM, &PopIIIHeliumIonization); ret += sscanf(line, "PopIIIColorDensityThreshold = %"FSYM, @@ -1156,8 +1168,8 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "AngularVelocity = %"FSYM, &AngularVelocity); ret += sscanf(line, "VelocityGradient = %"FSYM, &VelocityGradient); ret += sscanf(line, "ShearingVelocityDirection = %"ISYM, &ShearingVelocityDirection); - ret += sscanf(line, "ShearingBoxProblemType = %"ISYM, &ShearingBoxProblemType); - + ret += sscanf(line, "ShearingBoxProblemType = %"ISYM, &ShearingBoxProblemType); + #ifdef STAGE_INPUT sscanf(line, "LocalPath = %s\n", LocalPath); @@ -1181,11 +1193,11 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "InlineHaloFinder = %"ISYM, &InlineHaloFinder); ret += sscanf(line, "HaloFinderSubfind = %"ISYM, &HaloFinderSubfind); - ret += sscanf(line, "HaloFinderOutputParticleList = %"ISYM, + ret += sscanf(line, "HaloFinderOutputParticleList = %"ISYM, &HaloFinderOutputParticleList); - ret += sscanf(line, "HaloFinderRunAfterOutput = %"ISYM, + ret += sscanf(line, "HaloFinderRunAfterOutput = %"ISYM, &HaloFinderRunAfterOutput); - ret += sscanf(line, "HaloFinderLinkingLength = %"FSYM, + ret += sscanf(line, "HaloFinderLinkingLength = %"FSYM, &HaloFinderLinkingLength); ret += sscanf(line, "HaloFinderMinimumSize = %"ISYM, &HaloFinderMinimumSize); ret += sscanf(line, "HaloFinderCycleSkip = %"ISYM, &HaloFinderCycleSkip); @@ -1198,7 +1210,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* Sink particles (for present day star formation) & winds */ - ret += sscanf(line, "SinkMergeDistance = %"FSYM, &SinkMergeDistance); + ret += sscanf(line, "SinkMergeDistance = %"FSYM, &SinkMergeDistance); ret += sscanf(line, "SinkMergeMass = %"FSYM, &SinkMergeMass); ret += sscanf(line, "StellarWindFeedback = %"ISYM, &StellarWindFeedback); ret += sscanf(line, "StellarWindTurnOnMass = %"FSYM, &StellarWindTurnOnMass); @@ -1211,7 +1223,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* Read MHD Paramters */ ret += sscanf(line, "UsePoissonDivergenceCleaning = %"ISYM"", &UsePoissonDivergenceCleaning); - ret += sscanf(line, "PoissonDivergenceCleaningBoundaryBuffer = %"ISYM"", + ret += sscanf(line, "PoissonDivergenceCleaningBoundaryBuffer = %"ISYM"", &PoissonDivergenceCleaningBoundaryBuffer); ret += sscanf(line, "PoissonDivergenceCleaningThreshold = %"FSYM, &PoissonDivergenceCleaningThreshold); ret += sscanf(line, "PoissonApproximationThreshold = %"FSYM, &PoissonApproximationThreshold); @@ -1220,7 +1232,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "UseDivergenceCleaning = %"ISYM"", &UsePoissonDivergenceCleaning); ret += sscanf(line, "DivergenceCleaningBoundaryBuffer = %"ISYM"", &PoissonDivergenceCleaningBoundaryBuffer); ret += sscanf(line, "DivergenceCleaningThreshold = %"FSYM, &PoissonDivergenceCleaningThreshold); - + ret += sscanf(line, "AngularVelocity = %"FSYM, &AngularVelocity); ret += sscanf(line, "VelocityGradient = %"FSYM, &VelocityGradient); @@ -1233,7 +1245,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "Theta_Limiter = %"FSYM, &Theta_Limiter); ret += sscanf(line, "UseFloor = %"ISYM"", &UseFloor); ret += sscanf(line, "UseViscosity = %"ISYM"", &UseViscosity); - ret += sscanf(line, "ViscosityCoefficient = %"FSYM, &ViscosityCoefficient); + ret += sscanf(line, "ViscosityCoefficient = %"FSYM, &ViscosityCoefficient); ret += sscanf(line, "UseAmbipolarDiffusion = %"ISYM"", &UseAmbipolarDiffusion); ret += sscanf(line, "UseResistivity = %"ISYM"", &UseResistivity); ret += sscanf(line, "SmallRho = %"FSYM, &SmallRho); @@ -1310,7 +1322,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line,"tiny_pressure = %"FSYM,&tiny_pressure); ret += sscanf(line,"MHD_CT_Method = %"ISYM,&MHD_CT_Method); - + ret += sscanf(line,"NumberOfGhostZones = %"ISYM,&NumberOfGhostZones); ret += sscanf(line,"MHD_ProjectB = %"ISYM,&MHD_ProjectB); ret += sscanf(line,"MHD_ProjectE = %"ISYM,&MHD_ProjectE); @@ -1350,7 +1362,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ParticleSplitterCenterRegion+2, ParticleSplitterCenterRegion+3); ret += sscanf(line, "ResetMagneticField = %"ISYM, &ResetMagneticField); - ret += sscanf(line, "ResetMagneticFieldAmplitude = %"GSYM" %"GSYM" %"GSYM, + ret += sscanf(line, "ResetMagneticFieldAmplitude = %"GSYM" %"GSYM" %"GSYM, ResetMagneticFieldAmplitude, ResetMagneticFieldAmplitude+1, ResetMagneticFieldAmplitude+2); @@ -1369,7 +1381,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line, "SmartStarBHThermalFeedback = %"ISYM, &SmartStarBHThermalFeedback); ret += sscanf(line, "SmartStarBHRadiativeFeedback = %"ISYM, &SmartStarBHRadiativeFeedback); ret += sscanf(line, "SmartStarStellarRadiativeFeedback = %"ISYM, &SmartStarStellarRadiativeFeedback); - + ret += sscanf(line, "SmartStarFeedbackEnergyCoupling = %"FSYM, &SmartStarFeedbackEnergyCoupling); ret += sscanf(line, "SmartStarFeedbackJetsThresholdMass = %"FSYM, &SmartStarFeedbackJetsThresholdMass); ret += sscanf(line, "SmartStarSMSLifetime = %"FSYM, &SmartStarSMSLifetime); @@ -1385,15 +1397,15 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ret += sscanf(line,"MagneticSupernovaDuration = %"FSYM, &MagneticSupernovaDuration); /* If the dummy char space was used, then make another. */ - + if (*dummy != 0) { dummy = new char[MAX_LINE_LENGTH]; dummy[0] = 0; ret++; } - + /* check to see if the line belongs to one of the test problems */ - + if (strstr(line, "ShockTube") ) ret++; if (strstr(line, "WavePool" ) ) ret++; if (strstr(line, "ShockPool") ) ret++; @@ -1418,6 +1430,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++; @@ -1425,7 +1439,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (strstr(line, "TracerParticleCreation")) ret++; if (strstr(line, "TurbulenceSimulation")) ret++; if (strstr(line, "ProtostellarCollapse")) ret++; - if (strstr(line, "GalaxySimulation") + if (strstr(line, "GalaxySimulation") && !strstr(line,"RPSWind") && !strstr(line,"PreWind") ) ret++; if (strstr(line, "AgoraRestart")) ret++; if (strstr(line, "ConductionTest")) ret++; @@ -1435,7 +1449,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (strstr(line, "OneZoneFreefall")) ret++; if (strstr(line, "ShearingBox")) ret++; if (strstr(line, "PoissonSolverTest")) ret++; - /* 7.22.10 - CBH: Added 5 following lines to avoid runtime warnings from + /* 7.22.10 - CBH: Added 5 following lines to avoid runtime warnings from extra params previously added to code (but not read_params) by others.*/ if (strstr(line, "Cloudy") ) ret++; if (strstr(line, "IsothermalSoundSpeed")) ret++; @@ -1458,11 +1472,11 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (strstr(line, "\"\"\"") ) comment_count++; /* if the line is suspicious, issue a warning */ - + if (ret == 0 && strstr(line, "=") != NULL && line[0] != '#') if (MyProcessorNumber == ROOT_PROCESSOR) fprintf(stderr, "warning: the following parameter line was not interpreted:\n%s", line); - + } // Enable the active particles that were selected. @@ -1474,7 +1488,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) delete [] active_particle_types[i]; } delete [] active_particle_types; - + // HierarchyFile IO sanity check // Note that although I only do not allow HierarchyFileInputFormat=2 @@ -1485,8 +1499,8 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if ((HierarchyFileOutputFormat < 0) || (HierarchyFileOutputFormat > 2)) ENZO_FAIL("Invalid HierarchyFileOutputFormat. Must be 0 (HDF5), 1 (ASCII), or 2 (both).") - - // While we're examining the hierarchy, check that the MultiRefinedRegion doesn't demand more refinement that we've got + + // While we're examining the hierarchy, check that the MultiRefinedRegion doesn't demand more refinement that we've got for (int ireg = 0; ireg < MAX_STATIC_REGIONS; ireg++) if (MultiRefineRegionGeometry[ireg] >= 0) if (MultiRefineRegionMaximumLevel[ireg] > MaximumRefinementLevel) @@ -1495,12 +1509,12 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* clean up */ - + delete [] dummy; rewind(fptr); -/* If stochastic forcing is used, initialize the object +/* If stochastic forcing is used, initialize the object * but only if it is not a fresh simulation*/ if (DrivenFlowProfile && MetaData.Time != 0.) { for (dim = 0; dim < MetaData.TopGridRank; dim++) @@ -1520,15 +1534,15 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* In order to use filtered fields we need additional ghost zones */ if (SGSFilterStencil/2 + 2 > NumberOfGhostZones) ENZO_FAIL("SGS filtering needs additional ghost zones!\n"); - + // all these models are calculated based on the partial derivatives of // the primitive quantities if (SGScoeffERS2M2Star != 0. || SGScoeffEVStarEnS2Star != 0. || - SGScoeffEnS2StarTrace != 0. || - SGScoeffNLemfCompr != 0. || - SGScoeffNLu != 0. || - SGScoeffNLuNormedEnS2Star != 0. || + SGScoeffEnS2StarTrace != 0. || + SGScoeffNLemfCompr != 0. || + SGScoeffNLu != 0. || + SGScoeffNLuNormedEnS2Star != 0. || SGScoeffNLb != 0.) SGSNeedJacobians = 1; @@ -1555,7 +1569,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) parameters aren't used for PPM_LagrangeRemap and Zeus. */ if (HydroMethod == PPM_DirectEuler) { - if (RiemannSolver == INT_UNDEFINED) + if (RiemannSolver == INT_UNDEFINED) RiemannSolver = TwoShock; if (ReconstructionMethod == INT_UNDEFINED) ReconstructionMethod = PPM; @@ -1571,14 +1585,14 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) } if (RiemannSolver == -HLL) RiemannSolver = HLL; } else if (HydroMethod == HD_RK || HydroMethod == MHD_RK) { - if (RiemannSolver == INT_UNDEFINED) + if (RiemannSolver == INT_UNDEFINED) RiemannSolver = HLL; if (ReconstructionMethod == INT_UNDEFINED) ReconstructionMethod = PLM; } else if (HydroMethod == MHD_Li ) - if (RiemannSolver == INT_UNDEFINED) + if (RiemannSolver == INT_UNDEFINED) RiemannSolver = HLLD; if (ReconstructionMethod == INT_UNDEFINED) ReconstructionMethod = PLM; @@ -1612,7 +1626,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if(MyProcessorNumber == ROOT_PROCESSOR ) { fprintf(stderr, "WARNING: UseGasDrag != 0 yet HM=MHD_RK \n"); fprintf(stderr, "WARNING: setting UseGasDrag = 0. I.e no Gas drag included. \n"); - UseGasDrag = 0; + UseGasDrag = 0; } } @@ -1623,9 +1637,9 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) for (i = 0; i < MAX_STATIC_REGIONS; i++) if (StaticRefineRegionLevel[i] != INT_UNDEFINED) CosmologySimulationNumberOfInitialGrids++; - + /* If we have turned on Comoving coordinates, read cosmology parameters. */ - + if (ComovingCoordinates) { // Always output temperature in cosmology runs @@ -1648,7 +1662,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) // if not, alert user. if(AnisotropicConduction==TRUE && UseMHD==0){ ENZO_FAIL("AnisotropicConduction can only be used if MHD is turned on!\n"); - } + } if(AnisotropicConduction==TRUE && MetaData.TopGridRank < 2){ ENZO_FAIL("AnisotropicConduction can only be used if TopGridRank is >= 2!\n"); } @@ -1659,11 +1673,11 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* - if (EOSType == 3) // an isothermal equation of state implies the adiabatic index = 1 - Gamma = 1; + if (EOSType == 3) // an isothermal equation of state implies the adiabatic index = 1 + Gamma = 1; */ - /* convert MustRefineParticlesMinimumMass from a mass into a density, + /* convert MustRefineParticlesMinimumMass from a mass into a density, ASSUMING CUBE simulation space */ MustRefineParticlesMinimumMass /= POW(1/(float(MetaData.TopGridDims[0]) *POW(float(RefineBy), float(MustRefineParticlesRefineToLevel))),3); @@ -1671,20 +1685,20 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* Use Physical units stuff */ - float DensityUnits = 1.0, LengthUnits = 1.0, TemperatureUnits = 1.0, + float DensityUnits = 1.0, LengthUnits = 1.0, TemperatureUnits = 1.0, TimeUnits = 1.0, VelocityUnits = 1.0, PressureUnits = 1.0; double MassUnits = 1.0; if (UsePhysicalUnit) { - GetUnits(&DensityUnits, &LengthUnits, &TemperatureUnits, &TimeUnits, &VelocityUnits, + GetUnits(&DensityUnits, &LengthUnits, &TemperatureUnits, &TimeUnits, &VelocityUnits, &MassUnits, MetaData.Time); PressureUnits = DensityUnits*pow(VelocityUnits,2); /*IMOPORTANT: If change anything here must change both equivilant parts in WriteParameterFile.C as well */ /* Change input physical parameters into code units */ - MustRefineParticlesMinimumMass /= MassUnits; + MustRefineParticlesMinimumMass /= MassUnits; StarMakerOverDensityThreshold /= DensityUnits; // StarEnergyFeedbackRate = StarEnergyFeedbackRate/pow(LengthUnits,2)*pow(TimeUnits,3); - + if (SinkMergeDistance > 1.0) SinkMergeDistance /= LengthUnits; //printf(" \n SinkMergeDistance = %"FSYM"\n \n", SinkMergeDistance); @@ -1698,7 +1712,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (debug && (HydroMethod == HD_RK || HydroMethod == MHD_RK)) printf("smallrho=%g, smallp=%g, smalleint=%g, DensityUnits = %g, PressureUnits=%g, MaximumAlvenSpeed=%g\n", SmallRho, SmallP, SmallEint,DensityUnits, PressureUnits, MaximumAlvenSpeed); - for (int i = 0; i < MAX_FLAGGING_METHODS; i++) + for (int i = 0; i < MAX_FLAGGING_METHODS; i++) if (MinimumMassForRefinement[i] != FLOAT_UNDEFINED) { MinimumMassForRefinement[i] /= MassUnits; } @@ -1709,21 +1723,21 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) } - /* For !restart, this only ruins the units because MinimumOverDensityForRefinement is already + /* For !restart, this only ruins the units because MinimumOverDensityForRefinement is already set in SetDefaultGlobalValues and not FLOAT_UNDEFINED. - For restart, MinimumOverDensityForRefinement is not even needs to be read because only - MinimumMassForRefinement is used for CellFlagging. + For restart, MinimumOverDensityForRefinement is not even needs to be read because only + MinimumMassForRefinement is used for CellFlagging. So, why did we have to do this in the first place? - Ji-hoon Kim in Apr.2010 (The counterpart in WriteParameterFile is also commented out) */ //##### /* - if (!ComovingCoordinates && UsePhysicalUnit) - for (int i = 0; i < MAX_FLAGGING_METHODS; i++) + if (!ComovingCoordinates && UsePhysicalUnit) + for (int i = 0; i < MAX_FLAGGING_METHODS; i++) if (MinimumOverDensityForRefinement[i] != FLOAT_UNDEFINED) { MinimumOverDensityForRefinement[i] /= DensityUnits; } */ - + /* If TimeType is 0 or 1 for RefineRegion, MustRefineRegion, or CoolingRefineRegion, read in the input file. */ if ((RefineRegionTimeType == 0) || (RefineRegionTimeType == 1) || (MustRefineRegionTimeType == 0) || (MustRefineRegionTimeType == 1) @@ -1739,7 +1753,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) #ifdef USE_GRACKLE - /* If using Grackle chemistry and cooling library, override all other + /* If using Grackle chemistry and cooling library, override all other cooling machinery and do a translation of some of the parameters. */ if (use_grackle == TRUE) { // grackle_data->with_radiative_cooling already set @@ -1776,7 +1790,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) grackle_data->use_radiative_transfer = (Eint32) RadiativeTransfer; // grackle_data->radiative_transfer_coupled_rate_solver set in RadiativeTransferReadParameters // grackle_data->radiative_transfer_hydrogen_only set in RadiativeTransferReadParameters - + // Initialize units structure. FLOAT a_value, dadt; a_value = 1.0; @@ -1787,7 +1801,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ENZO_FAIL("Error in GetUnits.\n"); } if (ComovingCoordinates) { - if (CosmologyComputeExpansionFactor(MetaData.Time, &a_value, + if (CosmologyComputeExpansionFactor(MetaData.Time, &a_value, &dadt) == FAIL) { ENZO_FAIL("Error in CosmologyComputeExpansionFactors.\n"); } @@ -1841,7 +1855,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) // initialize Gadget equilibrium cooling if (InitializeGadgetEquilibriumCoolData(MetaData.Time) == FAIL) { ENZO_FAIL("Error in InitializeGadgetEquilibriumCoolData."); - } + } } /* If set, initialize the RadiativeCooling and RateEquations data. */ @@ -1851,8 +1865,8 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) ENZO_FAIL("Error in InitializeRateData."); } } - - if (MultiSpecies == 0 && + + if (MultiSpecies == 0 && MetalCooling == 0 && GadgetEquilibriumCooling == 0 && RadiativeCooling > 0) { @@ -1862,30 +1876,30 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) } /* If using the internal radiation field, initialize it. */ - - if (RadiationFieldType == 11) - RadiationData.RadiationShield = TRUE; + + if (RadiationFieldType == 11) + RadiationData.RadiationShield = TRUE; else if (RadiationFieldType == 10) - RadiationData.RadiationShield = FALSE; + RadiationData.RadiationShield = FALSE; if ((RadiationFieldType >= 10 && RadiationFieldType <= 11) || RadiationData.RadiationShield == TRUE) if (InitializeRadiationFieldData(MetaData.Time) == FAIL) { ENZO_FAIL("Error in InitializeRadiationFieldData."); } - + #ifdef USE_GRACKLE } // else (if Grackle == TRUE) #endif - /* If using MBHFeedback = 2 to 5 (Star->FeedbackFlag = MBH_JETS), + /* If using MBHFeedback = 2 to 5 (Star->FeedbackFlag = MBH_JETS), you need MBHParticleIO for angular momentum */ - if (MBHFeedback >= 2 && MBHFeedback <= 5) + if (MBHFeedback >= 2 && MBHFeedback <= 5) MBHParticleIO = TRUE; /* Turn off DualEnergyFormalism for zeus hydro (and a few other things). */ - + if (HydroMethod == Zeus_Hydro) { ConservativeInterpolation = FALSE; DualEnergyFormalism = FALSE; @@ -1897,7 +1911,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* Set some star feedback parameters. */ - if ((STARFEED_METHOD(NORMAL_STAR) || STARFEED_METHOD(UNIGRID_STAR)) && + if ((STARFEED_METHOD(NORMAL_STAR) || STARFEED_METHOD(UNIGRID_STAR)) && (StarFeedbackDistRadius > 0)) { // Calculate number of cells in the shape over which to distribute feedback. @@ -1921,7 +1935,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) StarFeedbackDistTotalCells); } } - + /* For rk_hydro, we need to set some variables */ if (DualEnergyFormalism) { @@ -1957,7 +1971,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) MaximumGravityRefinementLevel = min(MaximumGravityRefinementLevel, MaximumRefinementLevel); - + /* If MultiSpecies < 2, we can't simulate Pop III star formation */ if (MultiSpecies < 2 && STARMAKE_METHOD(POP3_STAR)) { @@ -1969,7 +1983,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) /* Use the value in MaximumParticleRefinementLevel to set the smoothing radius for the particles, to be used to Grid_DepositPositions. */ - + if (MaximumParticleRefinementLevel >= 0) DepositPositionsParticleSmoothRadius = (DomainRightEdge[0] - DomainLeftEdge[0])/ @@ -1977,14 +1991,14 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) POW(float(RefineBy), float(MaximumParticleRefinementLevel))); else DepositPositionsParticleSmoothRadius = 0; - - + + // PPMDiffusion causes an out-of-bounds condition as currently written // The following is an over-ride to force PPMDiffusion OFF. This has // been fixed in this latest version (AK). -// NOTE: The fix keeps the code from crashing, but is not a proper +// NOTE: The fix keeps the code from crashing, but is not a proper // implementation of PPM diffusion. The reason why is that Enzo typically // uses 3 ghost zones, and the correct PPM diffusion implementation requires // 4 parameters. SO, you should not use this parameter for, e.g., cosmology @@ -2002,7 +2016,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) printf("WARNING! Setting MetaData.PPMDiffusionParameter = 0\n"); MetaData.PPMDiffusionParameter = 0; } - + if (PartitionNestedGrids == 1) { if (MyProcessorNumber == ROOT_PROCESSOR) printf("WARNING! PartitionNestedGrids = 1 forces Parallel IO = 1\n"); @@ -2020,7 +2034,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if ((MetaData.GravityBoundary != TopGridPeriodic) && (UnigridTranspose)) { /* it turns out that Robert Harkness' unigrid transpose stuff is incompatible with the top - grid isolated gravity boundary conditions. I'm not 100 percent sure why this is - in the + grid isolated gravity boundary conditions. I'm not 100 percent sure why this is - in the meantime, just double-check to make sure that if one tries to use the isolated boundary conditions when the unigrid transpose stuff is on, the code crashes loudly. -- BWO, 26 June 2008 */ @@ -2035,7 +2049,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (ABS(MetaData.dtRestartDump - 3600.0*5) / (3600.0*5) < tol && ABS(MetaData.TimeLastRestartDump) < tol) { if (MyProcessorNumber == ROOT_PROCESSOR) - fprintf(stderr, + fprintf(stderr, "==================================================\n" "-> Turning off restart dumps because the previous\n" "default was set to 5 hours but not used. To avoid this warning,\n" @@ -2050,12 +2064,12 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) int method; bool TurnOnParticleMassRefinement = false; - for (method = 0; method < MAX_FLAGGING_METHODS; method++) + for (method = 0; method < MAX_FLAGGING_METHODS; method++) if (CellFlaggingMethod[method] == 8) { TurnOnParticleMassRefinement = true; break; } - for (method = 0; method < MAX_FLAGGING_METHODS; method++) + for (method = 0; method < MAX_FLAGGING_METHODS; method++) if (CellFlaggingMethod[method] == 4) { TurnOnParticleMassRefinement = false; break; @@ -2102,7 +2116,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) if (OutputParticleTypeGrouping && (!ParticleTypeInFile)) { OutputParticleTypeGrouping = FALSE; } - + // if (WritePotential && ComovingCoordinates && SelfGravity) { if (WritePotential && SelfGravity) { CopyGravPotential = TRUE; @@ -2112,24 +2126,24 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) MetaData.OutputsLeftBeforeExit = MetaData.NumberOfOutputsBeforeExit; if (MyProcessorNumber == ROOT_PROCESSOR) { - + if ( MetaData.GlobalDir != NULL ) { fprintf(stderr, "Output to Global Dir %s\n", MetaData.GlobalDir); } - + if ( MetaData.LocalDir != NULL ) { fprintf(stderr, "Output to Local Dir %s\n", MetaData.LocalDir); } } - + if ( (MetaData.GlobalDir != NULL) && (MetaData.LocalDir != NULL) ) { ENZO_FAIL("Cannot select GlobalDir AND LocalDir!\n"); } - + char *cwd_buffer = new char[MAX_LINE_LENGTH]; size_t cwd_buffer_len = MAX_LINE_LENGTH; - + if ( (MetaData.GlobalDir == NULL) && (MetaData.LocalDir == NULL) ) { /*if(getcwd(cwd_buffer, cwd_buffer_len) == NULL) { fprintf(stderr, "GETCWD call FAILED\n"); @@ -2138,7 +2152,7 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) fprintf(stderr,"CWD %s\n", cwd_buffer); */ /* No one seems to want GlobalDir to default to abspath(CWD). I'm leaving - the code here in case you do. MJT */ + the code here in case you do. MJT */ strcpy(cwd_buffer, "."); MetaData.GlobalDir = cwd_buffer; if (MyProcessorNumber == ROOT_PROCESSOR) @@ -2150,13 +2164,13 @@ int ReadParameterFile(FILE *fptr, TopGridData &MetaData, float *Initialdt) MetaData.SimulationUUID = new char[MAX_LINE_LENGTH]; get_uuid(MetaData.SimulationUUID); } - + for (int i=0; i 0) - - + + return SUCCESS; } diff --git a/src/enzo/SetDefaultGlobalValues.C b/src/enzo/SetDefaultGlobalValues.C index 3060ce161..585b1f376 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++) @@ -476,13 +487,13 @@ int SetDefaultGlobalValues(TopGridData &MetaData) CRCourantSafetyNumber = 0.5; CRFeedback = 0.0; // no stellar feedback into CRs CRdensFloor = 0.0; // off - CRmaxSoundSpeed = 0.0; // off + CRmaxSoundSpeed = 0.0; // off CRgamma = 4.0/3.0; // relativistic, adiabatic gas CosmologySimulationUniformCR= 1e-20; // FIXME 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; @@ -510,11 +521,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 @@ -582,10 +593,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; @@ -593,7 +604,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; @@ -681,7 +692,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) PythonTopGridSkip = 0; PythonSubcycleSkip = 1; PythonReloadScript = FALSE; - + // EnzoTiming Dump Frequency TimingCycleSkip = 1; @@ -709,9 +720,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; @@ -777,7 +788,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) StarMakerMinimumMassRampStartMass = FLOAT_UNDEFINED; StarMakerMinimumMassRampEndTime = FLOAT_UNDEFINED; StarMakerMinimumMassRampEndMass = FLOAT_UNDEFINED; - + NumberOfParticleAttributes = INT_UNDEFINED; AddParticleAttributes = FALSE; LastSupernovaTime = FLOAT_UNDEFINED; @@ -868,7 +879,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; @@ -992,7 +1003,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) VelocityGradient=1.0; ShearingBoundaryDirection=-1; ShearingVelocityDirection=-1; - ShearingBoxProblemType = 0; + ShearingBoxProblemType = 0; UseMHD=0; MaxVelocityIndex = 3; @@ -1039,7 +1050,7 @@ int SetDefaultGlobalValues(TopGridData &MetaData) ResetMagneticField = FALSE; for (dim = 0; dim < MAX_DIMENSION; dim++) { ResetMagneticFieldAmplitude[dim] = 0.0; // in Gauss - } + } VelAnyl = 0; BAnyl = 0; @@ -1060,7 +1071,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/TestGravityAPMInitialize.C b/src/enzo/TestGravityAPMInitialize.C new file mode 100644 index 000000000..e30163854 --- /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->TestGravityInitializeGrid(TestGravityDensity, + TestGravityNumberOfParticles, + TestGravityCentralParticlePosition, + TestGravityUseBaryons) == FAIL) + { + ENZO_FAIL("Error in TestGravityInitializeGrid.\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->TestGravityInitializeGrid(TestGravityDensity * POW(float(RefineBy), MetaData.TopGridRank), + 0, TestGravityCentralParticlePosition, + TestGravityUseBaryons) == FAIL) + { + ENZO_FAIL("Error in TestGravityInitializeGrid.\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/TestGravityCheckResults.C b/src/enzo/TestGravityCheckResults.C index 41869f8bd..7c6d00b4b 100644 --- a/src/enzo/TestGravityCheckResults.C +++ b/src/enzo/TestGravityCheckResults.C @@ -9,7 +9,7 @@ / PURPOSE: / ************************************************************************/ - + #include #include #include @@ -24,24 +24,24 @@ #include "TopGridData.h" #include "Hierarchy.h" #include "LevelHierarchy.h" - + /* function prototypes */ - - + + char TGOutputFileName[] = "TestGravityCheckResults.out"; - - + + int TestGravityCheckResults(LevelHierarchyEntry *LevelArray[]) { - + /* declarations */ - + int level; FILE *fptr; char name[MAX_LINE_LENGTH], proc[MAX_TASK_TAG_SIZE]; - + /* Open output file. */ - + strcpy(name, TGOutputFileName); if (NumberOfProcessors > 1) { sprintf(proc, "%"TASK_TAG_FORMAT""ISYM, MyProcessorNumber); @@ -52,36 +52,36 @@ int TestGravityCheckResults(LevelHierarchyEntry *LevelArray[]) 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->TestGravityCheckResults(fptr, - LevelArray[0]->GridData) == FAIL) { + LevelArray[0]->GridData, level) == FAIL) { fprintf(stderr, "Error in grid->TestGravityCheckResults\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/TestGravityInitialize.C b/src/enzo/TestGravityInitialize.C index 3c7c9b2b6..434ab1640 100644 --- a/src/enzo/TestGravityInitialize.C +++ b/src/enzo/TestGravityInitialize.C @@ -14,10 +14,10 @@ / RETURNS: SUCCESS or FAIL / ************************************************************************/ - + // This routine intializes a new simulation based on the parameter file. // - + #include #include #include @@ -31,123 +31,134 @@ #include "Grid.h" #include "Hierarchy.h" #include "TopGridData.h" - + int TestGravityInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, - TopGridData &MetaData) + TopGridData &MetaData) { char *DensName = "Density"; - char *TEName = "TotalEnergy"; - char *GEName = "GasEnergy"; + 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]; + + 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 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) { - + + 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, "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] != '#') + + 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->TestGravityInitializeGrid(TestGravityDensity, - TestGravityNumberOfParticles, - TestGravityUseBaryons - ) == FAIL){ + TestGravityNumberOfParticles, + TestGravityCentralParticlePosition, + TestGravityUseBaryons) == FAIL) + { ENZO_FAIL("Error in TestGravityInitializeGrid.\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) { - + 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; + + HierarchyEntry *Subgrid = new HierarchyEntry; + TopGrid.NextGridNextLevel = Subgrid; Subgrid->NextGridNextLevel = NULL; Subgrid->NextGridThisLevel = NULL; - Subgrid->ParentGrid = &TopGrid; - + 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; + + 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->TestGravityInitializeGrid(TestGravityDensity* - POW(float(RefineBy), MetaData.TopGridRank), 0, TestGravityUseBaryons) - == FAIL) { + LeftEdge, RightEdge, 0); + if (Subgrid->GridData->TestGravityInitializeGrid(TestGravityDensity * POW(float(RefineBy), MetaData.TopGridRank), + 0, + TestGravityCentralParticlePosition, + TestGravityUseBaryons) == FAIL) + { ENZO_FAIL("Error in TestGravityInitializeGrid.\n"); - } - + } + /* Generate a static refine region. */ - + StaticRefineRegionLevel[0] = 0; - for (dim = 0; dim < MetaData.TopGridRank; dim++) { + 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; @@ -156,30 +167,35 @@ int TestGravityInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, 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); + + 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 = "); + 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..40c2e57d6 --- /dev/null +++ b/src/enzo/TestGravitySphereAPMInitialize.C @@ -0,0 +1,215 @@ +/*********************************************************************** +/ +/ 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->TestGravitySphereInitializeGrid(TestGravitySphereInteriorDensity, + TestGravitySphereExteriorDensity, + TestGravitySphereRadius, + TestGravitySphereType, + TestGravitySphereUseBaryons, + TestGravitySphereCenter + ) == FAIL){ + ENZO_FAIL("Error in TestGravitySphereInitializeGrid."); + } + + /* 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->TestGravitySphereInitializeGrid(TestGravitySphereInteriorDensity, + TestGravitySphereExteriorDensity, + TestGravitySphereRadius, + TestGravitySphereType, + TestGravitySphereUseBaryons, + TestGravitySphereCenter + ) == FAIL) { + ENZO_FAIL("Error in TestGravitySphereInitializeGrid.") + } + 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 #include #include @@ -33,13 +39,12 @@ #define DEFINE_STORAGE #include "TestGravitySphereGlobalData.h" #undef DEFINE_STORAGE - - + + void AddLevel(LevelHierarchyEntry *Array[], HierarchyEntry *Grid, int level); int RebuildHierarchy(TopGridData *MetaData, LevelHierarchyEntry *LevelArray[], int level); -void WriteListOfFloats(FILE *fptr, int N, FLOAT floats[]); - + int TestGravitySphereInitialize(FILE *fptr, FILE *Outfptr, HierarchyEntry &TopGrid, TopGridData &MetaData) { @@ -50,197 +55,127 @@ int TestGravitySphereInitialize(FILE *fptr, FILE *Outfptr, char *Vel2Name = "y-velocity"; char *Vel3Name = "z-velocity"; char *GPotName = "Grav_Potential"; - + /* declarations */ - + char line[MAX_LINE_LENGTH]; int dim, ret, level; - int NumberOfSubgridZones[MAX_DIMENSION], SubgridDims[MAX_DIMENSION]; - FLOAT LeftEdge[MAX_DIMENSION], RightEdge[MAX_DIMENSION]; - + /* Error check. */ - + if (!SelfGravity) fprintf(stderr, "TestGravitySphere: gravity is off!?!"); - + /* set default parameters */ - - TestGravitySphereInteriorDensity = 1.0; // density inside sphere - TestGravitySphereExteriorDensity = tiny_number; // outside sphere - TestGravitySphereRadius = 0.1; - TestGravitySphereType = 0; // uniform density - FLOAT TestGravitySphereSubgridLeft = 0.0; // start of subgrid - FLOAT TestGravitySphereSubgridRight = 0.0; // end of subgrid + + 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]; + float TestGravitySphereCenter[MAX_DIMENSION]; for (dim = 0; dim < MAX_DIMENSION; dim++) - TestGravitySphereCenter[dim] = 0.5*(DomainLeftEdge[dim] + - DomainRightEdge[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); + &TestGravitySphereInteriorDensity); ret += sscanf(line, "TestGravitySphereExteriorDensity = %"FSYM, - &TestGravitySphereExteriorDensity); + &TestGravitySphereExteriorDensity); ret += sscanf(line, "TestGravitySphereRadius = %"FSYM, - &TestGravitySphereRadius); + &TestGravitySphereRadius); ret += sscanf(line, "TestGravitySphereType = %"ISYM, - &TestGravitySphereType); - ret += sscanf(line, "TestGravitySphereSubgridLeft = %"PSYM, - &TestGravitySphereSubgridLeft); - ret += sscanf(line, "TestGravitySphereSubgridRight = %"PSYM, - &TestGravitySphereSubgridRight); + &TestGravitySphereType); ret += sscanf(line, "TestGravitySphereUseBaryons = %"ISYM, - &TestGravitySphereUseBaryons); + &TestGravitySphereUseBaryons); ret += sscanf(line, "TestGravitySphereRefineAtStart = %"ISYM, - &TestGravitySphereRefineAtStart); - ret += sscanf(line, "TestGravitySphereCenter = %"PSYM" %"PSYM" %"PSYM, - TestGravitySphereCenter, TestGravitySphereCenter+1, - TestGravitySphereCenter+2); - + &TestGravitySphereRefineAtStart); + /* if the line is suspicious, issue a warning */ - - if (ret == 0 && strstr(line, "=") && strstr(line, "TestGravitySphere") - && line[0] != '#') + + 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->TestGravitySphereInitializeGrid( - TestGravitySphereInteriorDensity, - TestGravitySphereExteriorDensity, - TestGravitySphereRadius, - TestGravitySphereType, - TestGravitySphereUseBaryons, - TestGravitySphereCenter - ) == FAIL){ + + if (TopGrid.GridData->TestGravitySphereInitializeGrid(TestGravitySphereInteriorDensity, + TestGravitySphereExteriorDensity, + TestGravitySphereRadius, + TestGravitySphereType, + TestGravitySphereUseBaryons, + TestGravitySphereCenter + ) == FAIL){ ENZO_FAIL("Error in TestGravitySphereInitializeGrid."); } - + /* 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]); + 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."); + ENZO_FAIL("Error in RebuildHierarchy."); } if (LevelArray[level+1] == NULL) - break; + break; LevelHierarchyEntry *Temp = LevelArray[level+1]; while (Temp != NULL) { - if (Temp->GridData->TestGravitySphereInitializeGrid( - TestGravitySphereInteriorDensity, - TestGravitySphereExteriorDensity, - TestGravitySphereRadius, - TestGravitySphereType, - TestGravitySphereUseBaryons, - TestGravitySphereCenter - ) == FAIL) { - ENZO_FAIL("Error in TestGravitySphereInitializeGrid."); - } - Temp = Temp->NextGridThisLevel; + if (Temp->GridData->TestGravitySphereInitializeGrid(TestGravitySphereInteriorDensity, + TestGravitySphereExteriorDensity, + TestGravitySphereRadius, + TestGravitySphereType, + TestGravitySphereUseBaryons, + TestGravitySphereCenter + ) == FAIL) { + ENZO_FAIL("Error in TestGravitySphereInitializeGrid.") + } + 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; + if (Temp->GridData->ProjectSolutionToParentGrid(*Temp->GridHierarchyEntry->ParentGrid->GridData) == FAIL) + ENZO_FAIL("Error in grid->ProjectSolutionToParentGrid."); + Temp = Temp->NextGridThisLevel; } } - } // end: if (TestGravitySphereRefineAtStart) - - /* If requested, create a subgrid */ - - for (dim = 0; dim < MetaData.TopGridRank; dim++) - NumberOfSubgridZones[dim] = - nint((TestGravitySphereSubgridRight - TestGravitySphereSubgridLeft)/ - ((DomainRightEdge[dim] - DomainLeftEdge[dim] )/ - FLOAT(MetaData.TopGridDims[dim]))) - *RefineBy; - - if (NumberOfSubgridZones[0] > 0) { - - /* Error check */ - - if (TestGravitySphereRefineAtStart) { - ENZO_FAIL("Cannot RefineAtStart AND create subgrid."); - } - - /* 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] = TestGravitySphereSubgridLeft; - RightEdge[dim] = TestGravitySphereSubgridRight; - } - - /* 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->TestGravitySphereInitializeGrid( - TestGravitySphereInteriorDensity, - TestGravitySphereExteriorDensity, - TestGravitySphereRadius, - TestGravitySphereType, - TestGravitySphereUseBaryons, - TestGravitySphereCenter) - == FAIL) { - ENZO_FAIL("Error in TestGravitySphereInitializeGrid."); - } - } - + /* set up field names and units */ - + int count = 0; DataLabel[count++] = DensName; DataLabel[count++] = TEName; @@ -249,38 +184,33 @@ int TestGravitySphereInitialize(FILE *fptr, FILE *Outfptr, DataLabel[count++] = Vel1Name; DataLabel[count++] = Vel2Name; DataLabel[count++] = Vel3Name; - - if (WritePotential){ + if (WritePotential) DataLabel[count++] = GPotName; - } - for (int j = 0; j +#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 a564b16d3..aa526b004 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[]); @@ -45,17 +45,17 @@ int WritePhotonSources(FILE *fptr, FLOAT CurrentTime); #endif /* TRANSFER */ 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; @@ -63,7 +63,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) { @@ -74,7 +74,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; @@ -93,12 +93,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; } } @@ -108,13 +108,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); @@ -122,7 +122,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); @@ -131,7 +131,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); @@ -139,11 +139,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 = "); @@ -204,20 +204,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) @@ -228,12 +228,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]); @@ -244,7 +244,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++) { @@ -266,18 +266,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); @@ -290,7 +290,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", @@ -299,9 +299,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); @@ -311,7 +311,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); @@ -350,7 +350,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); @@ -358,17 +358,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 = "); @@ -436,11 +436,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); @@ -462,9 +462,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); @@ -473,6 +473,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); @@ -483,19 +495,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); @@ -510,7 +522,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); @@ -609,7 +621,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); @@ -629,13 +641,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", @@ -648,7 +660,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); @@ -686,7 +698,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]); @@ -707,7 +719,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, @@ -755,12 +767,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); @@ -789,13 +801,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], @@ -813,9 +825,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], @@ -902,15 +914,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); @@ -966,7 +978,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", @@ -1126,7 +1138,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); @@ -1137,7 +1149,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); @@ -1156,14 +1168,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); @@ -1174,7 +1186,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); @@ -1184,10 +1196,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) { @@ -1218,7 +1230,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; @@ -1238,7 +1250,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,11 +1320,11 @@ int WriteParameterFile(FILE *fptr, TopGridData &MetaData, char *name = NULL) } /* write version info */ - + fprintf(fptr, "VersionNumber = %"FSYM"\n\n", VERSION); if (name != NULL) UpdateLocalDatabase(MetaData, ID, dset_uuid, name); - + return SUCCESS; } 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 50a25fa8c..cd6b1386a 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; @@ -443,25 +471,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; @@ -610,7 +638,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)*/ @@ -640,7 +668,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; @@ -653,39 +681,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]; @@ -803,7 +831,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]; @@ -904,7 +932,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 */ @@ -972,7 +1000,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]; @@ -1007,7 +1035,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 @@ -1094,23 +1122,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 @@ -1137,7 +1165,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; @@ -1172,7 +1200,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; @@ -1182,8 +1210,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; @@ -1195,7 +1223,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 92f3c802c..6f795d6cc 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! */ @@ -403,10 +409,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 @@ -528,6 +534,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