Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume rendering for octrees #2610

Merged
merged 68 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
f4ebd73
Add octree raytracing C++ code
cphyc May 26, 2020
d4c3c9a
Base stuff for cython/c++ interaction
cphyc May 26, 2020
5a075c0
Wire things up
cphyc May 26, 2020
084d126
VolumeSource is for internal API, use "create_volume_source" instead
cphyc May 26, 2020
3e5d55f
Simplifying python side
cphyc May 26, 2020
ae1dcf1
Cast ray also calls the image sampler (need tidying though)
cphyc May 26, 2020
de2782a
Move to pxd file
cphyc May 27, 2020
d76258e
Use c++ class for fixed interpolator
cphyc May 27, 2020
d3acbe8
Route call depending on backend (KDtree or Octree)
cphyc May 27, 2020
f7b1db8
Only apply gathering from volume when using the KDTree approach
cphyc May 27, 2020
3f1b4dc
Pass the right data around
cphyc May 27, 2020
555aba4
First working version
cphyc May 27, 2020
5edcfd2
Now supports trilinear interpolation!
cphyc May 28, 2020
ec7c5f1
Add caching to prevent recreation of costly ghost zones information
cphyc May 28, 2020
7cc83e5
Remove TODO
cphyc May 28, 2020
62fa6a1
Flaking
cphyc May 28, 2020
865056c
More flaking
cphyc May 28, 2020
4aeca0f
Removing debug stmts
cphyc May 28, 2020
ad726cf
Use math.h instead of cmath in an attempt to solve compilation issues
cphyc May 28, 2020
edf8d13
Correct cell ordering between Fortran/C code
cphyc May 29, 2020
9aa5517
Remove useless code + give some hints to the compiler
cphyc May 29, 2020
2fc37a3
Prevent memory leaks
cphyc May 29, 2020
e26ef97
Cast rays one by one
cphyc May 29, 2020
dd52b0f
Help compiler with optimization
cphyc Jun 8, 2020
9d54a83
Minor help for the compiler
cphyc Jun 8, 2020
a86d300
Quick fixup
cphyc Jul 1, 2020
d044c4a
Fixed interpolator is now cpp
cphyc Jul 2, 2020
ca5a44f
Fixing c++ issues
cphyc Jul 2, 2020
ba3e7f7
Black/isort passes
cphyc Jul 20, 2020
c35a5b4
Minor changes
cphyc Jul 20, 2020
5ab7000
Fix flaking
cphyc Jul 20, 2020
a8625ba
More flexible create_volume_source function
cphyc Jul 20, 2020
f0e7498
Test should pass if they agree at machine precision
cphyc Jul 20, 2020
114e534
Black is happy
cphyc Jul 20, 2020
370b83b
Include comments
cphyc Jul 20, 2020
8c4ef1f
Pass exception upwards
cphyc Jul 27, 2020
227b7e5
Add valueerror instead of assertion
cphyc Jul 27, 2020
87ad009
Remove TODO that's been done
cphyc Jul 27, 2020
a5ad26c
Use ABC instead of manually raising NotImplementedError
cphyc Jul 27, 2020
71d8466
isort-ing
cphyc Jul 27, 2020
65a405d
Black pass
cphyc Jul 27, 2020
8429979
Update yt/visualization/volume_rendering/render_source.py
cphyc Jul 20, 2020
53ad67b
Apply suggestions from code review
cphyc Jul 20, 2020
9e1dfd8
Fix isort
cphyc Jul 22, 2020
b54094d
Fix mistake in image samplers
cphyc Jul 27, 2020
2983a16
Remove erroneous exception raising
cphyc Jul 27, 2020
ab6fabf
Specify volume method
cphyc Jul 27, 2020
f0a280f
Last pass at fixing render_source errors
cphyc Jul 27, 2020
6bd49ee
black pass
cphyc Jul 27, 2020
3480760
(snow)flake
cphyc Jul 27, 2020
c768d9d
Start fixing what I broke ...
cphyc Jul 30, 2020
6a31ae5
Passing volume method as kwa
cphyc Aug 5, 2020
20faa4f
Do not forget to pass on the volume_method
cphyc Aug 5, 2020
7315cc4
Black + isort pass
cphyc Aug 5, 2020
1d8b665
Flaking
cphyc Aug 5, 2020
cde25a8
Fix off axis projection
cphyc Aug 5, 2020
5ab67f1
Merge branch master into indep-octree-raytracing
cphyc Aug 30, 2020
843bbfd
Fix isort
cphyc Aug 30, 2020
55aa3ca
Revert "Start fixing what I broke ..."
cphyc Aug 30, 2020
70a597f
More sensible naming conventions
cphyc Aug 30, 2020
d19f845
Fix pxd imports
cphyc Aug 30, 2020
acf1032
Fixing isort
cphyc Aug 30, 2020
aaf8d88
Import from API
cphyc Aug 30, 2020
9e11403
Get rid of "VolumeSource" invocations
cphyc Aug 30, 2020
cd8311b
Bump image for appveyor
cphyc Aug 30, 2020
748e7ef
Fix windows build
cphyc Aug 30, 2020
a6cf130
Revert appveyor image?
cphyc Sep 9, 2020
d4028e4
Merge branch 'master' into indep-octree-raytracing
cphyc Sep 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ environment:
- PYTHON_VERSION: "3.8"

platform:
-x64
- x64

install:
- "if not exist \"%userprofile%\\.config\\yt\" mkdir %userprofile%\\.config\\yt"
Expand Down
6 changes: 3 additions & 3 deletions doc/source/cookbook/render_two_fields.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import yt
from yt.visualization.volume_rendering.api import Scene, VolumeSource
from yt.visualization.volume_rendering.api import Scene, create_volume_source

filePath = "Sedov_3d/sedov_hdf5_chk_0003"
ds = yt.load(filePath)
Expand All @@ -15,13 +15,13 @@
cam.switch_orientation()

# add rendering of density field
dens = VolumeSource(ds, field="dens")
dens = create_volume_source(ds, field="dens")
dens.use_ghost_zones = True
sc.add_source(dens)
sc.save("density.png", sigma_clip=6)

# add rendering of x-velocity field
vel = VolumeSource(ds, field="velx")
vel = create_volume_source(ds, field="velx")
vel.use_ghost_zones = True
sc.add_source(vel)
sc.save("density_any_velocity.png", sigma_clip=6)
4 changes: 2 additions & 2 deletions doc/source/cookbook/various_lens.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import yt
from yt.visualization.volume_rendering.api import Scene, VolumeSource
from yt.visualization.volume_rendering.api import Scene, create_volume_source
import numpy as np

field = ("gas", "density")
Expand All @@ -14,7 +14,7 @@
# Follow the simple_volume_rendering cookbook for the first part of this.
ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
sc = Scene()
vol = VolumeSource(ds, field=field)
vol = create_volume_source(ds, field=field)
tf = vol.transfer_function
tf.grey_opacity = True

Expand Down
9 changes: 8 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import glob
import os
import sys
from distutils.ccompiler import get_default_compiler
from distutils.version import LooseVersion

import pkg_resources
Expand Down Expand Up @@ -45,6 +46,11 @@
else:
std_libs = ["m"]

if get_default_compiler() == "msvc":
CPP14_FLAG = ["/std:c++14"]
else:
CPP14_FLAG = ["--std=c++14"]

cythonize_aliases = {
"LIB_DIR": "yt/utilities/lib/",
"LIB_DIR_EWAH": ["yt/utilities/lib/", "yt/utilities/lib/ewahboolarray/"],
Expand All @@ -56,8 +62,9 @@
],
"STD_LIBS": std_libs,
"OMP_ARGS": omp_args,
"FIXED_INTERP": "yt/utilities/lib/fixed_interpolator.c",
"FIXED_INTERP": "yt/utilities/lib/fixed_interpolator.cpp",
"ARTIO_SOURCE": glob.glob("yt/frontends/artio/artio_headers/*.c"),
"CPP14_FLAG": CPP14_FLAG,
}

lib_exts = [
Expand Down
31 changes: 30 additions & 1 deletion yt/data_objects/index_subobjects/octree_subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import yt.geometry.particle_deposit as particle_deposit
import yt.geometry.particle_smooth as particle_smooth
from yt.data_objects.data_containers import YTSelectionContainer
from yt.funcs import mylog
from yt.funcs import issue_deprecation_warning, mylog
from yt.geometry.particle_oct_container import ParticleOctreeContainer
from yt.units.dimensions import length
from yt.units.yt_array import YTArray
Expand Down Expand Up @@ -522,6 +522,35 @@ def select_particles(self, selector, x, y, z):
mask = selector.select_points(x, y, z, 0.0)
return mask

def get_vertex_centered_data(self, fields):
_old_api = isinstance(fields, (str, tuple))
if _old_api:
message = (
"get_vertex_centered_data() requires list of fields, rather than "
"a single field as an argument."
)
issue_deprecation_warning(message)
fields = [fields]

# Make sure the field list has only unique entries
fields = list(set(fields))
new_fields = {}
cg = self.retrieve_ghost_zones(1, fields)
for field in fields:
new_fields[field] = cg[field][1:, 1:, 1:].copy()
np.add(new_fields[field], cg[field][:-1, 1:, 1:], new_fields[field])
np.add(new_fields[field], cg[field][1:, :-1, 1:], new_fields[field])
np.add(new_fields[field], cg[field][1:, 1:, :-1], new_fields[field])
np.add(new_fields[field], cg[field][:-1, 1:, :-1], new_fields[field])
np.add(new_fields[field], cg[field][1:, :-1, :-1], new_fields[field])
np.add(new_fields[field], cg[field][:-1, :-1, 1:], new_fields[field])
np.add(new_fields[field], cg[field][:-1, :-1, :-1], new_fields[field])
np.multiply(new_fields[field], 0.125, new_fields[field])

if _old_api:
return new_fields[fields[0]]
return new_fields


class OctreeSubsetBlockSlicePosition:
def __init__(self, ind, block_slice):
Expand Down
21 changes: 13 additions & 8 deletions yt/frontends/ramses/data_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,19 @@ def _fill_with_ghostzones(
selector.count_octs(self.oct_handler, self.domain_id) * self.nz ** ndim
)

(
levels,
cell_inds,
file_inds,
domains,
) = self.oct_handler.file_index_octs_with_ghost_zones(
selector, self.domain_id, cell_count
)
gz_cache = getattr(self, "_ghost_zone_cache", None)
if gz_cache:
levels, cell_inds, file_inds, domains = gz_cache
else:
gz_cache = (
levels,
cell_inds,
file_inds,
domains,
) = self.oct_handler.file_index_octs_with_ghost_zones(
selector, self.domain_id, cell_count
)
self._ghost_zone_cache = gz_cache

# Initializing data container
for field in fields:
Expand Down
80 changes: 78 additions & 2 deletions yt/frontends/stream/data_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,10 @@ class StreamOctreeSubset(OctreeSubset):
domain_id = 1
_domain_offset = 1

def __init__(self, base_region, ds, oct_handler, over_refine_factor=1):
def __init__(
self, base_region, ds, oct_handler, over_refine_factor=1, num_ghost_zones=0
):
self._over_refine_factor = over_refine_factor
self._num_zones = 1 << (over_refine_factor)
self.field_data = YTFieldData()
self.field_parameters = {}
Expand All @@ -659,7 +662,33 @@ def __init__(self, base_region, ds, oct_handler, over_refine_factor=1):
self.base_region = base_region
self.base_selector = base_region.selector

def fill(self, content, dest, selector, offset):
self._num_ghost_zones = num_ghost_zones

if num_ghost_zones > 0:
if not all(ds.periodicity):
mylog.warn("Ghost zones will wrongly assume the domain to be periodic.")
base_grid = StreamOctreeSubset(
base_region, ds, oct_handler, over_refine_factor
)
self._base_grid = base_grid

def retrieve_ghost_zones(self, ngz, fields, smoothed=False):
try:
new_subset = self._subset_with_gz
mylog.debug("Reusing previous subset with ghost zone.")
except AttributeError:
new_subset = StreamOctreeSubset(
self.base_region,
self.ds,
self.oct_handler,
self._over_refine_factor,
num_ghost_zones=ngz,
)
self._subset_with_gz = new_subset

return new_subset

def _fill_no_ghostzones(self, content, dest, selector, offset):
# Here we get a copy of the file, which we skip through and read the
# bits we want.
oct_handler = self.oct_handler
Expand All @@ -675,6 +704,37 @@ def fill(self, content, dest, selector, offset):
)
return count

def _fill_with_ghostzones(self, content, dest, selector, offset):
oct_handler = self.oct_handler
ndim = self.ds.dimensionality
cell_count = (
selector.count_octs(self.oct_handler, self.domain_id) * self.nz ** ndim
)

gz_cache = getattr(self, "_ghost_zone_cache", None)
if gz_cache:
levels, cell_inds, file_inds, domains = gz_cache
else:
gz_cache = (
levels,
cell_inds,
file_inds,
domains,
) = oct_handler.file_index_octs_with_ghost_zones(
selector, self.domain_id, cell_count
)
self._ghost_zone_cache = gz_cache
levels[:] = 0
dest.update((field, np.empty(cell_count, dtype="float64")) for field in content)
# Make references ...
oct_handler.fill_level(0, levels, cell_inds, file_inds, dest, content, offset)

def fill(self, content, dest, selector, offset):
if self._num_ghost_zones == 0:
return self._fill_no_ghostzones(content, dest, selector, offset)
else:
return self._fill_with_ghostzones(content, dest, selector, offset)


class StreamOctreeHandler(OctreeIndex):
def __init__(self, ds, dataset_type=None):
Expand Down Expand Up @@ -752,6 +812,22 @@ class StreamOctreeDataset(StreamDataset):
_field_info_class = StreamFieldInfo
_dataset_type = "stream_octree"

levelmax = None

def __init__(
self,
stream_handler,
storage_filename=None,
geometry="cartesian",
unit_system="cgs",
):
super(StreamOctreeDataset, self).__init__(
stream_handler, storage_filename, geometry, unit_system
)
# Set up levelmax
self.max_level = stream_handler.levels.max()
self.min_level = stream_handler.levels.min()


class StreamUnstructuredMesh(UnstructuredMesh):
_index_offset = 0
Expand Down
2 changes: 1 addition & 1 deletion yt/geometry/oct_container.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ cdef class OctreeContainer:
OctVisitor visitor,
int vc = ?, np.int64_t *indices = ?)
cdef Oct *next_root(self, int domain_id, int ind[3])
cdef Oct *next_child(self, int domain_id, int ind[3], Oct *parent)
cdef Oct *next_child(self, int domain_id, int ind[3], Oct *parent) except? NULL
cdef void append_domain(self, np.int64_t domain_count)
# The fill_style is the ordering, C or F, of the octs in the file. "o"
# corresponds to C, and "r" is for Fortran.
Expand Down
2 changes: 1 addition & 1 deletion yt/geometry/oct_container.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ cdef class OctreeContainer:
self.nocts += 1
return next

cdef Oct* next_child(self, int domain_id, int ind[3], Oct *parent):
cdef Oct* next_child(self, int domain_id, int ind[3], Oct *parent) except? NULL:
cdef int i
cdef Oct *next = NULL
if parent.children != NULL:
Expand Down
2 changes: 1 addition & 1 deletion yt/utilities/answer_testing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from yt.loaders import load, load_simulation
from yt.units.yt_array import YTArray, YTQuantity
from yt.visualization import particle_plots, plot_window as pw, profile_plotter
from yt.visualization.volume_rendering.scene import Scene
from yt.visualization.volume_rendering.api import Scene


def _streamline_for_io(params):
Expand Down
Loading