Skip to content

Commit 53c0d54

Browse files
committed
Enhancements and simple processing function
1 parent f58e520 commit 53c0d54

File tree

3 files changed

+330
-21
lines changed

3 files changed

+330
-21
lines changed

docs/src/private_api_reference.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@ Peridynamics.displacement_bc!
7171
Peridynamics.velocity_databc!
7272
Peridynamics.forcedensity_databc!
7373
Peridynamics.NewtonRaphson
74+
Peridynamics.Study
75+
Peridynamics.submit!
76+
Peridynamics.process_each_job
7477
```

src/core/study.jl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,78 @@ function submit!(study::Study; kwargs...)
214214
print_log(stdout, msg)
215215
return nothing
216216
end
217+
218+
"""
219+
process_each_job(f::Function, study::Study, default_result::NamedTuple)
220+
221+
$(internal_api_warning())
222+
$(experimental_api_warning())
223+
224+
Apply a processing function to each successfully completed job in a parameter study.
225+
This function iterates through all jobs in the study and applies the user-defined
226+
processing function `f` to jobs that completed successfully. Failed jobs or jobs where
227+
the processing function errors will use the `default_result` instead.
228+
229+
# Arguments
230+
- `f::Function`: A processing function with signature `f(job::Job, setup::NamedTuple)`
231+
that returns a `NamedTuple` containing the processed results. The function receives:
232+
- `job`: The [`Job`](@ref) object for the simulation
233+
- `setup`: The parameter configuration `NamedTuple` for this job
234+
- `study::Study`: The study containing the jobs to process
235+
- `default_result::NamedTuple`: The default result to use when a job failed or when
236+
the processing function throws an error
237+
238+
# Returns
239+
- `Vector{<:NamedTuple}`: A vector of results with the same length as the number of
240+
jobs in the study. Each element is either the result from applying `f` or the
241+
`default_result` for failed/errored cases.
242+
243+
# Behavior
244+
- Only processes jobs where `study.sim_success[i] == true`
245+
- Failed jobs automatically receive `default_result` (warning logged)
246+
- If processing function `f` throws an error, that job receives `default_result` (error logged)
247+
- Processing is sequential (one job at a time)
248+
- All jobs in the study will have a corresponding entry in the results vector
249+
250+
# Example
251+
```julia
252+
# After running a parameter study
253+
study = Study(create_job, setups; root="my_study")
254+
submit!(study)
255+
256+
# Define a function to extract maximum displacement from results
257+
function extract_max_displacement(job::Job, setup::NamedTuple)
258+
# Read results from job output directory
259+
results_file = joinpath(job.options.root, "results_step_0010.jld2")
260+
data = load_results(results_file)
261+
max_u = maximum(norm, eachcol(data.displacement))
262+
return (; E=setup.E, velocity=setup.velocity, max_displacement=max_u)
263+
end
264+
265+
default = (; E=0.0, velocity=0.0, max_displacement=NaN)
266+
results = process_each_job(extract_max_displacement, study, default)
267+
268+
# Filter successful results
269+
successful_results = [r for r in results if !isnan(r.max_displacement)]
270+
```
271+
272+
See also: [`Study`](@ref), [`submit!`](@ref)
273+
"""
274+
function process_each_job(f::F, study::Study, default_result::NamedTuple) where {F}
275+
results = fill(default_result, length(study.jobs))
276+
for (i, job) in enumerate(study.jobs)
277+
if study.sim_success[i]
278+
setup = study.setups[i]
279+
res = try
280+
f(job, setup)
281+
catch err
282+
@error "error processing job $(job.options.root)" error=err
283+
default_result
284+
end
285+
results[i] = res
286+
else
287+
@warn "skipping processing for failed job $(job.options.root)"
288+
end
289+
end
290+
return results
291+
end

0 commit comments

Comments
 (0)