[Yt-svn] yt: Renamed TwoPointFunctions
hg at spacepope.org
hg at spacepope.org
Sat Aug 21 17:03:24 PDT 2010
hg Repository: yt
details: yt/rev/d9f25e82c2d7
changeset: 1970:d9f25e82c2d7
user: Matthew Turk <matthewturk at gmail.com>
date:
Sat Aug 21 17:03:18 2010 -0700
description:
Renamed TwoPointFunctions
diffstat:
yt/lagos/TwoPointFunctions.py | 854 --------------------------------------------
yt/lagos/__init__.py | 2 +-
yt/lagos/two_point_functions.py | 854 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 855 insertions(+), 855 deletions(-)
diffs (truncated from 1728 to 300 lines):
diff -r d8c6ec9dcb57 -r d9f25e82c2d7 yt/lagos/TwoPointFunctions.py
--- a/yt/lagos/TwoPointFunctions.py Sat Aug 21 09:24:02 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,854 +0,0 @@
-"""
-Two Point Functions Framework.
-
-Author: Stephen Skory <stephenskory at yahoo.com>
-Affiliation: UCSD Physics/CASS
-Homepage: http://yt.enzotools.org/
-License:
- Copyright (C) 2010 Stephen Skory. All Rights Reserved.
-
- This file is part of yt.
-
- yt is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-from yt.lagos import *
-from yt.math_utils import *
-from yt.performance_counters import yt_counters, time_function
-try:
- from yt.extensions.kdtree import *
-except ImportError:
- mylog.debug("The Fortran kD-Tree did not import correctly.")
-
-import math, sys, itertools, inspect, types, time
-from collections import defaultdict
-
-sep = 12
-
-class TwoPointFunctions(ParallelAnalysisInterface):
- def __init__(self, pf, fields, left_edge=None, right_edge=None,
- total_values=1000000, comm_size=10000, length_type="lin",
- length_number=10, length_range=None, vol_ratio = 1,
- salt=0):
- r""" Initialize a two point functions object.
-
- Parameters
- ----------
- total_values : Integer
- How many total (global) pair calculations to run for each of the
- functions specified. Default: 1000000.
- comm_size : Integer
- How entries are sent during communication. Default: 10000.
- length_type : String
- Controls the even spacing of the rulers lengths in
- logarithmic or linear space, set by "log" or "lin", respectively.
- Default: "lin".
- length_number : Integer
- Sets how many lengths to create, evenly spaced by the above
- parameter. Default: 10.
- length_range : Float
- A min/max pair for the range of values to search the over
- the simulational volume. Default: [sqrt(3)dx, 1/2*shortest box edge],
- where dx is the smallest grid cell size.
- vol_ratio : Integer
- How to multiply-assign subvolumes to the parallel
- tasks. This number must be an integer factor of the total number of tasks or
- very bad things will happen. The default value of 1 will assign one task
- to each subvolume, and there will be an equal number of subvolumes as tasks.
- A value of 2 will assign two tasks to each subvolume and there will be
- one-half as many subvolumes as tasks.
- A value equal to the number of parallel tasks will result in each task
- owning a complete copy of all the fields data, meaning each task will be
- operating on the identical full volume.
- Setting it to -1 will automatically adjust it such that each task
- owns the entire volume. Default = 1.
- salt : Integer
- A number that will be added to the random number generator
- seed. Use this if a different random series of numbers is desired when
- keeping everything else constant from this set: (MPI task count,
- number of ruler lengths, ruler min/max, number of functions,
- number of point pairs per ruler length). Default = 0.
-
- Examples
- --------
- >>> tpf = TwoPointFunctions(pf, ["x-velocity", "y-velocity", "z-velocity"],
- ... total_values=1e5, comm_size=10000,
- ... length_number=10, length_range=[1./128, .5],
- ... length_type="log")
- """
- try:
- fKD
- except NameError:
- raise ImportError("You need to install the Forthon kD-Tree")
- self._fsets = []
- self.fields = fields
- # MPI stuff.
- self.size = self._mpi_get_size()
- self.mine = self._mpi_get_rank()
- self.vol_ratio = vol_ratio
- if self.vol_ratio == -1:
- self.vol_ratio = self.size
- self.total_values = int(total_values / self.size)
- # For communication.
- self.recv_hooks = []
- self.send_hooks = []
- self.done_hooks = []
- self.comm_size = min(int(comm_size), self.total_values)
- self.pf = pf
- self.nlevels = pf.h.max_level
- self.period = self.pf['DomainRightEdge'] - self.pf['DomainLeftEdge']
- self.min_edge = min(self.period)
- self.hierarchy = pf.h
- self.center = (pf["DomainRightEdge"] + pf["DomainLeftEdge"])/2.0
- # Figure out the range of ruler lengths.
- if length_range == None:
- length_range = [math.sqrt(3) * self.pf.h.get_smallest_dx(),
- self.min_edge/2.]
- else:
- if len(length_range) != 2:
- raise ValueError("length_range must have two values.")
- if length_range[1] <= length_range[0]:
- raise ValueError("length_range[1] must be larger than length_range[0]")
- if length_range[1] > self.min_edge/2.:
- length_range[1] = self.min_edge/2.
- mylog.info("Automatically adjusting length_range[1] to half the shortest box edge.")
- if length_range[0] == -1 or length_range[0] == -1.:
- mylog.info("Automatically adjusting length_range[0] to %1.5e." % \
- (math.sqrt(3) * self.pf.h.get_smallest_dx()))
- length_range[0] = math.sqrt(3) * self.pf.h.get_smallest_dx()
- # Make the list of ruler lengths.
- if length_type == "lin":
- self.lengths = na.linspace(length_range[0], length_range[1],
- length_number)
- elif length_type == "log":
- self.lengths = na.logspace(math.log10(length_range[0]),
- math.log10(length_range[1]), length_number)
- else:
- # Something went wrong.
- raise SyntaxError("length_type is either \"lin\" or \"log\".")
- # Subdivide the volume.
- if not left_edge or not right_edge:
- self.left_edge = self.pf['DomainLeftEdge']
- self.right_edge = self.pf['DomainRightEdge']
- padded, self.LE, self.RE, self.ds = self._partition_hierarchy_3d(padding=0.,
- rank_ratio = self.vol_ratio)
- else:
- self.left_edge = left_edge
- self.right_edge = right_edge
- # We do this twice, first with no 'buffer' to get the unbuffered
- # self.LE/RE, and then second to get a buffered self.ds.
- padded, self.LE, self.RE, temp = \
- self._partition_region_3d(left_edge, right_edge,
- rank_ratio=self.vol_ratio)
- padded, temp, temp, self.ds = \
- self._partition_region_3d(left_edge - self.lengths[-1], \
- right_edge + self.lengths[-1], rank_ratio=self.vol_ratio)
- mylog.info("LE %s RE %s %s" % (str(self.LE), str(self.RE), str(self.ds)))
- self.width = self.ds.right_edge - self.ds.left_edge
- self.mt = na.random.mtrand.RandomState(seed = 1234 * self.mine + salt)
-
- def add_function(self, function, out_labels, sqrt, corr_norm=None):
- r"""Add a function to the list that will be evaluated at the
- generated pairs of points.
-
- Parameters
- ----------
- function : Function
- The two point function of the form fcn(a, b, r1, r2, vec).
- out_labels : List of strings
- A list of strings labeling the outputs of the function.
- sqrt : List of booleans
- A list of booleans which when True will square-root the corresponding
- element of the output in the text output (write_out_means()).
- corr_norm : Float
- Used when calculating two point correlations. If set, the output
- of the function is divided by this number. Default = None.
-
- Examples
- --------
- >>> f1 = tpf.add_function(function=rms_vel, out_labels=['RMSvdiff'],
- ... sqrt=[True])
- """
- fargs = inspect.getargspec(function)
- if len(fargs.args) != 5:
- raise SyntaxError("The function %s needs five arguments." %\
- function.__name__)
- out_labels = list(out_labels)
- if len(out_labels) < 1:
- raise SyntaxError("Please specify at least one out_labels for function %s." %\
- function.__name__)
- sqrt = list(sqrt)
- if len(sqrt) != len(out_labels):
- raise SyntaxError("Please have the same number of elements in out_labels as in sqrt for function %s." %\
- function.__name__)
- self._fsets.append(FcnSet(self, function, self.min_edge,
- out_labels, sqrt,corr_norm))
- return self._fsets[-1]
-
- def __getitem__(self, key):
- return self._fsets[key]
-
- def run_generator(self):
- r"""After all the functions have been added, run the generator.
-
- Examples
- --------
- >>> tpf.run_generator()
- """
- yt_counters("run_generator")
- # We need a function!
- if len(self._fsets) == 0:
- mylog.error("You need to add at least one function!")
- return None
- # Do all the startup tasks to get the grid points.
- if self.nlevels == 0:
- yt_counters("build_sort")
- self._build_sort_array()
- self.sort_done = False
- yt_counters("build_sort")
- else:
- yt_counters("init_kd_tree")
- self._init_kd_tree()
- self.sort_done = True
- yt_counters("init_kd_tree")
- # Store the fields.
- self.stored_fields = {}
- yt_counters("getting data")
- for field in self.fields:
- self.stored_fields[field] = self.ds[field].copy()
- self.ds.clear_data()
- # If the arrays haven't been sorted yet and need to be, do that.
- if not self.sort_done:
- for field in self.fields:
- self.stored_fields[field] = self.stored_fields[field][self.sort]
- del self.sort
- self.sort_done = True
- yt_counters("getting data")
- self._build_fields_vals()
- yt_counters("big loop over lengths")
- t_waiting = 0.
- for bigloop, length in enumerate(self.lengths):
- self._build_points_array()
- if self.mine == 0:
- mylog.info("Doing length %1.5e" % length)
- # Things stop when this value below equals total_values.
- self.generated_points = 0
- self.gen_array = na.zeros(self.size, dtype='int64')
- self.comm_cycle_count = 0
- self.final_comm_cycle_count = 0
- self.sent_done = False
- self._setup_done_hooks_on_root()
- # While everyone else isn't done or I'm not done, we loop.
- while self._should_cycle():
- self._setup_recv_arrays()
- self._send_arrays()
- t0 = time.time()
- self._mpi_Request_Waitall(self.send_hooks)
- self._mpi_Request_Waitall(self.recv_hooks)
- t1 = time.time()
- t_waiting += (t1-t0)
- if (self.recv_points < -1.).any() or (self.recv_points > 1.).any(): # or \
- #(na.abs(na.log10(na.abs(self.recv_points))) > 20).any():
- raise ValueError("self.recv_points is no good!")
- self.points = self.recv_points.copy()
- self.fields_vals = self.recv_fields_vals.copy()
- self.gen_array = self.recv_gen_array.copy()
- self._eval_points(length)
- self.gen_array[self.mine] = self.generated_points
- self.comm_cycle_count += 1
- if self.generated_points == self.total_values:
- self._send_done_to_root()
- if self.mine == 0:
- mylog.info("Length (%d of %d) %1.5e took %d communication cycles to complete." % \
- (bigloop+1, len(self.lengths), length, self.comm_cycle_count))
- yt_counters("big loop over lengths")
- if self.nlevels >= 1:
- del fKD.pos, fKD.qv_many, fKD.nn_tags
- free_tree(0) # Frees the kdtree object.
- yt_counters("allsum")
- self._allsum_bin_hits()
- mylog.info("Spent %f seconds waiting for communication." % t_waiting)
- yt_counters("allsum")
- yt_counters("run_generator")
-
- def _init_kd_tree(self):
- """
- Builds the kd tree of grid center points.
- """
- # Grid cell centers.
- mylog.info("Multigrid: Building kD-Tree.")
- xp = self.ds["x"]
- yp = self.ds["y"]
- zp = self.ds["z"]
- fKD.pos = na.asfortranarray(na.empty((3,xp.size), dtype='float64'))
- fKD.pos[0, :] = xp[:]
- fKD.pos[1, :] = yp[:]
More information about the yt-svn
mailing list