@@ -453,77 +453,76 @@ function run_node_multiscale!(
453453 node_ratio = node. timestep / Day (1 )
454454
455455 # Check if the model needs to run this timestep
456- if (1 + (i- 1 ) % node_ratio) != node_ratio
456+ if (1 + (i - 1 ) % node_ratio) != node_ratio
457457
458458 # TODO : This does prevent the node form being updated by two different parents but probably should be changed
459- if any ([p. simulation_id[1 ] >= node. simulation_id[1 ] for p in node. parent])
459+ if any ([p. simulation_id[1 ] > node. simulation_id[1 ] for p in node. parent])
460460 node. simulation_id[1 ] += 1
461461 end
462- return nothing
463- end
464-
465- # run!(status(object), dependency_node, meteo, constants, extra)
466- # Check if all the parents have been called before the child:
467- if ! AbstractTrees. isroot (node) && any ([p. simulation_id[1 ] <= node. simulation_id[1 ] for p in node. parent])
468- # If not, this node should be called via another parent
469- return nothing
470- end
462+ else
471463
472- node_statuses = status (object)[node. scale] # Get the status of the nodes at the current scale
473- models_at_scale = models[node. scale]
464+ # run!(status(object), dependency_node, meteo, constants, extra)
465+ # Check if all the parents have been called before the child:
466+ if ! AbstractTrees. isroot (node) && any ([p. simulation_id[1 ] <= node. simulation_id[1 ] for p in node. parent])
467+ # If not, this node should be called via another parent
468+ return nothing
469+ end
474470
475- # TODO : is empty check should be pre simulation
476- if isnothing (node. timestep_mapping_data) || isempty (node. timestep_mapping_data)
477- # Samuel : this is the happy path, no further timestep mapping checks needed
471+ node_statuses = status (object)[node. scale] # Get the status of the nodes at the current scale
472+ models_at_scale = models[node. scale]
478473
479- for st in node_statuses # for each node status at the current scale (potentially in parallel over nodes)
480- # Actual call to the model:
481- run! (node. value, models_at_scale, st, meteo, constants, extra)
482- end
483- node. simulation_id[1 ] += 1 # increment the simulation id, to remember that the model has been called already
474+ # TODO : is empty check should be pre simulation
475+ if isnothing (node. timestep_mapping_data) || isempty (node. timestep_mapping_data)
476+ # Samuel : this is the happy path, no further timestep mapping checks needed
484477
485- # Recursively visit the children (soft dependencies only, hard dependencies are handled by the model itself):
486- for child in node. children
487- # ! check if we can run this safely in a @floop loop. I would say no,
488- # ! because we are running a parallel computation above already, modifying the node.simulation_id,
489- # ! which is not thread-safe yet.
490- run_node_multiscale! (object, child, i, models, meteo, constants, extra, check, executor)
491- end
492- else
493- # we have a child with a different timestep than the parent,
494- # which requires accumulation/reduce and running only some of the time
495-
496- for st in node_statuses
497- run! (node. value, models_at_scale, st, meteo, constants, extra)
498- # TODO do the accumulation
499- # then write into the child's status if need be ?
500- for tmst in node. timestep_mapping_data
501- ratio = Int (tmst. node_to. timestep / node. timestep)
502- # TODO assert etc.
503- # do the accumulation for each variable
504- accumulation_index = 1 + ((i- 1 )% ratio)
505- tmst. mapping_data[node_id (st. node)][accumulation_index] = st[tmst. variable_from]
506-
507- # if we have completed a *full* cycle, then presumably we need to write out the value to
508- # the mapped model
509- # A full cycle isn't just the ratio to the parent, it's the ratio to the finest-grained timestep
510- if accumulation_index == ratio
511- node_statuses_to = status (object)[tmst. node_to. scale]
512-
513- # TODO : INCORRECT in a scale with multiple mtg nodes
514- for st_to in node_statuses_to
515- # TODO might be able to catch mapping_function type incompatibility errors and make them clearer
516- st_to[tmst. variable_to] = tmst. mapping_function (tmst. mapping_data[node_id (st. node)])
478+ for st in node_statuses # for each node status at the current scale (potentially in parallel over nodes)
479+ # Actual call to the model:
480+ run! (node. value, models_at_scale, st, meteo, constants, extra)
481+ end
482+ node. simulation_id[1 ] += 1 # increment the simulation id, to remember that the model has been called already
483+
484+ # Recursively visit the children (soft dependencies only, hard dependencies are handled by the model itself):
485+ for child in node. children
486+ # ! check if we can run this safely in a @floop loop. I would say no,
487+ # ! because we are running a parallel computation above already, modifying the node.simulation_id,
488+ # ! which is not thread-safe yet.
489+ run_node_multiscale! (object, child, i, models, meteo, constants, extra, check, executor)
490+ end
491+ else
492+ # we have a child with a different timestep than the parent,
493+ # which requires accumulation/reduce and running only some of the time
494+
495+ for st in node_statuses
496+ run! (node. value, models_at_scale, st, meteo, constants, extra)
497+ # TODO do the accumulation
498+ # then write into the child's status if need be ?
499+ for tmst in node. timestep_mapping_data
500+ ratio = Int (tmst. node_to. timestep / node. timestep)
501+ # TODO assert etc. This is all assuming the ratio is an integer, whereas it can be, like 1/7
502+ # do the accumulation for each variable
503+ index = Int (i* Day (1 ) / node. timestep)
504+ accumulation_index = 1 + ((index - 1 ) % ratio)
505+ tmst. mapping_data[node_id (st. node)][accumulation_index] = st[tmst. variable_from]
506+
507+ # if we have completed a *full* cycle, then presumably we need to write out the value to
508+ # the mapped model
509+ # A full cycle isn't just the ratio to the parent, it's the ratio to the finest-grained timestep
510+ if accumulation_index == ratio
511+ node_statuses_to = status (object)[tmst. node_to. scale]
512+
513+ # TODO : INCORRECT in a scale with multiple mtg nodes
514+ for st_to in node_statuses_to
515+ # TODO might be able to catch mapping_function type incompatibility errors and make them clearer
516+ st_to[tmst. variable_to] = tmst. mapping_function (tmst. mapping_data[node_id (st. node)])
517+ end
517518 end
518519 end
519- end
520- end
521-
522- node. simulation_id[1 ] += 1
520+ end
523521
524- for child in node. children
525-
526- run_node_multiscale! (object, child, i, models, meteo, constants, extra, check, executor)
522+ node. simulation_id[1 ] += 1
527523 end
528524 end
525+ for child in node. children
526+ run_node_multiscale! (object, child, i, models, meteo, constants, extra, check, executor)
527+ end
529528end
0 commit comments