Skip to content

Commit

Permalink
fix(dynamic): Add dynamic simulation and calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkelkp authored and mostaphaRoudsari committed Apr 14, 2022
1 parent a84fc00 commit 8f734b0
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 24 deletions.
47 changes: 24 additions & 23 deletions pollination/three_phase/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from pollination.honeybee_radiance.translate import CreateRadianceFolderGrid
from pollination.honeybee_radiance.sky import CreateSkyDome, CreateSkyMatrix
from pollination.honeybee_radiance.sun import CreateSunMatrix, ParseSunUpHours
from pollination.honeybee_radiance.multiphase import CreateOctreesGrids
from pollination.honeybee_radiance.multiphase import PrepareDynamic

from .two_phase.entry import TwoPhaseEntryPoint
from .two_phase.dynamic.entry import DynamicGroup
from .three_phase.preparation import ThreePhaseInputsPreparation
from .three_phase.calculation import ThreePhaseMatrixCalculation

Expand Down Expand Up @@ -164,42 +165,42 @@ def create_direct_sky(
}
]

@task(template=CreateOctreesGrids, needs=[create_rad_folder, generate_sunpath])
def create_octrees_grids(
@task(template=PrepareDynamic, needs=[create_rad_folder, generate_sunpath])
def prepare_dynamic(
self, model=create_rad_folder._outputs.model_folder,
sunpath=generate_sunpath._outputs.sunpath, phase='3', cpu_count=cpu_count,
cpus_per_grid=3, min_sensor_count=min_sensor_count
sunpath=generate_sunpath._outputs.sunpath, phase=3, cpu_count=cpu_count,
cpus_per_grid=3, min_sensor_count=min_sensor_count, static='include'
):
return [
{
'from': CreateOctreesGrids()._outputs.scene_folder,
'from': PrepareDynamic()._outputs.scene_folder,
'to': 'resources/octrees'
},
{
'from': CreateOctreesGrids()._outputs.grid_folder,
'from': PrepareDynamic()._outputs.grid_folder,
'to': 'resources/grid'
},
{
'from': CreateOctreesGrids()._outputs.scene_info
'from': PrepareDynamic()._outputs.scene_info
},
{
'from': CreateOctreesGrids()._outputs.two_phase_info
'from': PrepareDynamic()._outputs.two_phase_info
}
]

@task(
template=TwoPhaseEntryPoint,
loop=create_octrees_grids._outputs.two_phase_info,
template=DynamicGroup,
loop=prepare_dynamic._outputs.two_phase_info,
needs=[
create_rad_folder, create_octrees_grids,
create_rad_folder, prepare_dynamic,
create_total_sky, create_direct_sky, create_sky_dome,
generate_sunpath
],
sub_folder='calcs/2_phase/{{item.identifier}}',
sub_paths={
'octree': '{{item.octree}}',
'octree_direct': '{{item.octree_direct}}',
'octree_direct_sun': '{{item.octree_direct_sun}}',
'octree_file': '{{item.octree}}',
'octree_file_direct': '{{item.octree_direct}}',
'octree_file_with_suns': '{{item.octree_direct_sun}}',
'sensor_grids_folder': '{{item.sensor_grids_folder}}'
}
)
Expand All @@ -208,10 +209,10 @@ def calculate_two_phase_matrix(
identifier='{{item.identifier}}',
radiance_parameters=radiance_parameters,
sensor_grids_info='{{item.sensor_grids_info}}',
sensor_grids_folder=create_octrees_grids._outputs.grid_folder,
octree=create_octrees_grids._outputs.scene_folder,
octree_direct=create_octrees_grids._outputs.scene_folder,
octree_direct_sun=create_octrees_grids._outputs.scene_folder,
sensor_grids_folder=prepare_dynamic._outputs.grid_folder,
octree_file=prepare_dynamic._outputs.scene_folder,
octree_file_direct=prepare_dynamic._outputs.scene_folder,
octree_file_with_suns=prepare_dynamic._outputs.scene_folder,
sky_dome=create_sky_dome._outputs.sky_dome,
total_sky=create_total_sky._outputs.sky_matrix,
direct_sky=create_direct_sky._outputs.sky_matrix,
Expand All @@ -224,7 +225,7 @@ def calculate_two_phase_matrix(
@task(
template=ThreePhaseInputsPreparation,
needs=[
create_rad_folder, create_octrees_grids,
create_rad_folder, prepare_dynamic,
create_total_sky, create_sky_dome
],
sub_folder='calcs/3_phase/',
Expand All @@ -235,7 +236,7 @@ def calculate_two_phase_matrix(
def prepare_three_phase(
self,
model_folder=create_rad_folder._outputs.model_folder,
octree=create_octrees_grids._outputs.scene_folder,
octree=prepare_dynamic._outputs.scene_folder,
sky_dome=create_sky_dome._outputs.sky_dome,
bsdf_folder=create_rad_folder._outputs.bsdf_folder,
dmtx_group_params=dmtx_group_params
Expand All @@ -260,7 +261,7 @@ def prepare_three_phase(
@task(
template=ThreePhaseMatrixCalculation,
needs=[
create_rad_folder, create_octrees_grids,
create_rad_folder, prepare_dynamic,
create_total_sky, create_sky_dome,
prepare_three_phase
],
Expand All @@ -278,7 +279,7 @@ def calculate_three_phase_matrix_total(
receivers=create_rad_folder._outputs.receivers,
view_mtx_rad_params=view_mtx_rad_params,
daylight_mtx_rad_params=daylight_mtx_rad_params,
octree=create_octrees_grids._outputs.scene_folder,
octree=prepare_dynamic._outputs.scene_folder,
sky_dome=create_sky_dome._outputs.sky_dome,
sky_matrix=create_total_sky._outputs.sky_matrix,
bsdf_folder=create_rad_folder._outputs.bsdf_folder,
Expand Down
146 changes: 146 additions & 0 deletions pollination/three_phase/two_phase/dynamic/_raytracing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
"""Raytracing DAG for annual daylight."""

from pollination_dsl.dag import Inputs, DAG, task
from dataclasses import dataclass

from pollination.honeybee_radiance.contrib import DaylightContribution
from pollination.honeybee_radiance.coefficient import DaylightCoefficient
from pollination.honeybee_radiance.sky import AddRemoveSkyMatrix


@dataclass
class DynamicRayTracing(DAG):
# inputs

radiance_parameters = Inputs.str(
description='The radiance parameters for ray tracing',
default='-ab 2 -ad 5000 -lw 2e-05'
)

octree_file = Inputs.file(
description='Octree that describes the scene for indirect studies. This octree '
'includes all the scene with default modifiers except for the aperture groups '
'other the one that is the source for this calculation will be blacked out.',
extensions=['oct']
)

octree_file_direct = Inputs.file(
description='Octree that describes the scene for direct studies. This octree '
'is similar to the octree for indirect studies with the difference that the '
'matrials for the scene are set to black.',
extensions=['oct']
)

octree_file_with_suns = Inputs.file(
description='A blacked out octree that includes the sunpath. This octree is '
'used for calculating the contribution from direct sunlight.',
extensions=['oct']
)

grid_name = Inputs.str(
description='Sensor grid file name. This is useful to rename the final result '
'file to {grid_name}.ill'
)

sensor_grid = Inputs.file(
description='Sensor grid file.',
extensions=['pts']
)

sensor_count = Inputs.int(
description='Number of sensors in the input sensor grid.'
)

sun_modifiers = Inputs.file(
description='A file with sun modifiers.'
)

sky_matrix = Inputs.file(
description='Path to total sky matrix file.'
)

sky_matrix_direct = Inputs.file(
description='Path to direct skymtx file (i.e. gendaymtx -d).'
)

sky_dome = Inputs.file(
description='Path to sky dome file.'
)

bsdfs = Inputs.folder(
description='Folder containing any BSDF files needed for ray tracing.',
optional=True
)

@task(template=DaylightContribution)
def direct_sunlight(
self,
radiance_parameters=radiance_parameters,
fixed_radiance_parameters='-aa 0.0 -I -faf -ab 0 -dc 1.0 -dt 0.0 -dj 0.0 -dr 0',
sensor_count=sensor_count,
modifiers=sun_modifiers,
sensor_grid=sensor_grid,
scene_file=octree_file_with_suns,
bsdf_folder=bsdfs
):
return [
{
'from': DaylightContribution()._outputs.result_file,
'to': 'direct_sunlight.ill'
}
]

@task(template=DaylightCoefficient)
def direct_sky(
self,
radiance_parameters=radiance_parameters,
fixed_radiance_parameters='-aa 0.0 -I -ab 1 -c 1 -faf',
sensor_count=sensor_count,
sky_matrix=sky_matrix_direct, sky_dome=sky_dome,
sensor_grid=sensor_grid,
scene_file=octree_file_direct,
bsdf_folder=bsdfs
):
return [
{
'from': DaylightCoefficient()._outputs.result_file,
'to': 'direct_sky.ill'
}
]

@task(template=DaylightCoefficient)
def total_sky(
self,
radiance_parameters=radiance_parameters,
fixed_radiance_parameters='-aa 0.0 -I -c 1 -faf',
sensor_count=sensor_count,
sky_matrix=sky_matrix, sky_dome=sky_dome,
sensor_grid=sensor_grid,
scene_file=octree_file,
bsdf_folder=bsdfs
):
return [
{
'from': DaylightCoefficient()._outputs.result_file,
'to': 'total_sky.ill'
}
]

@task(
template=AddRemoveSkyMatrix,
needs=[direct_sunlight, total_sky, direct_sky]
)
def output_matrix_math(
self,
name=grid_name,
direct_sky_matrix=direct_sky._outputs.result_file,
total_sky_matrix=total_sky._outputs.result_file,
sunlight_matrix=direct_sunlight._outputs.result_file,
conversion='47.4 119.9 11.6'
):
return [
{
'from': AddRemoveSkyMatrix()._outputs.results_file,
'to': '../final/{{self.name}}.ill'
}
]
129 changes: 129 additions & 0 deletions pollination/three_phase/two_phase/dynamic/entry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from pollination_dsl.dag import Inputs, DAG, task
from pollination_dsl.dag.inputs import ItemType
from dataclasses import dataclass
from pollination.honeybee_radiance.grid import MergeFolderData

from ._raytracing import DynamicRayTracing


@dataclass
class DynamicGroup(DAG):
"""Dynamic entry point.
This two phase workflow also includes the extra phase for accurately calculating the
direct sunlight.
"""

# inputs
identifier = Inputs.str(
description='Identifier for this two-phase study. This value is usually the '
'identifier of the aperture group or is set to __static__ for the static '
'apertures in the model.', default='__static__'
)

radiance_parameters = Inputs.str(
description='The radiance parameters for ray tracing.',
default='-ab 2 -ad 5000 -lw 2e-05'
)

sensor_grids_info = Inputs.list(
description='A list with sensor grids information.',
items_type=ItemType.JSONObject
)

sensor_grids_folder = Inputs.folder(
description='Corresponding sensor grid folder to sensor grids info.'
)

octree_file = Inputs.file(
description='Octree that describes the scene for indirect studies. This octree '
'includes all the scene with default modifiers except for the aperture groups '
'other the one that is the source for this calculation will be blacked out.',
extensions=['oct']
)

octree_file_direct = Inputs.file(
description='Octree that describes the scene for direct studies. This octree '
'is similar to the octree for indirect studies with the difference that the '
'matrials for the scene are set to black.',
extensions=['oct']
)

octree_file_with_suns = Inputs.file(
description='A blacked out octree that includes the sunpath. This octree is '
'used for calculating the contribution from direct sunlight.',
extensions=['oct']
)

sky_dome = Inputs.file(
description='A sky dome for daylight coefficient studies.'
)

total_sky = Inputs.file(
description='Sky matrix with both sun and sky components.'
)

direct_sky = Inputs.file(
description='Sky matrix with sun only.'
)

sun_modifiers = Inputs.file(
description='The list of sun modifiers that are included in octree_direct_sun.'
)

bsdf_folder = Inputs.folder(
description='The folder from Radiance model folder that includes the BSDF files.'
'You only need to include the in-scene BSDFs for the two phase calculation.',
optional=True
)

results_folder = Inputs.str(
description='An optional string to define the folder that the outputs should be '
'copied to. You can use this input to copy the final results to a folder other '
'then the subfolder for this DAG', default='results'
)

@task(
template=DynamicRayTracing,
loop=sensor_grids_info,
# create a subfolder for each grid
sub_folder='initial_results/{{item.full_id}}',
# sensor_grid sub_path
sub_paths={'sensor_grid': '{{item.full_id}}.pts'}
)
def two_phase_raytracing(
self,
radiance_parameters=radiance_parameters,
octree_file=octree_file,
octree_file_direct=octree_file_direct,
octree_file_with_suns=octree_file_with_suns,
grid_name='{{item.full_id}}',
sensor_grid=sensor_grids_folder,
sensor_count='{{item.count}}',
sky_matrix=total_sky,
sky_matrix_direct=direct_sky,
sky_dome=sky_dome,
sun_modifiers=sun_modifiers,
bsdfs=bsdf_folder
):
pass

@task(
template=MergeFolderData,
needs=[two_phase_raytracing],
sub_paths={
'dist_info': '_redist_info.json'
}
)
def restructure_results(
self, identifier=identifier,
input_folder='initial_results/final',
extension='ill', dist_info=sensor_grids_folder,
results_folder=results_folder
):
return [
{
'from': MergeFolderData()._outputs.output_folder,
'to': '{{self.results_folder}}/{{self.identifier}}'
}
]
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pollination-honeybee-radiance==0.21.0
pollination-honeybee-radiance==0.22.2

0 comments on commit 8f734b0

Please sign in to comment.