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

SteadyState solver robustness updates #74

Merged
merged 9 commits into from
Oct 12, 2023
Merged

Conversation

sjdaines
Copy link
Member

@sjdaines sjdaines commented Oct 2, 2023

New options for SteadyState.solve_ptc (ie apply to each outer timestep):

  • SteadyState.RestartSmallValuesCallback that provides a callback function with signature

    rsvc(state, tmodel, deltat, model, modeldata)
    

    that modifies state to reset variables with values < modify_threshold to value modify_val, hence restarting the Newton solve from modify_val on the next iteration.

    Add to step_callbacks list eg

    restart_small_values_callback = PALEOmodel.SteadyState.RestartSmallValuesCallback(
        modeldata.solver_view_all.stateexplicit;
        exclude_variables=["atm.N_mr", "atm.CH21_mr"], # exclude variables that do actually reach values < threshold
        modify_threshold = mr_threshold,
        modify_val = 1e-30,
    )
    
    PALEOmodel.SteadyState.steadystate_ptcForwardDiff(
        ...
        step_callbacks = [restart_small_values_callback, ],
        ...
    )
    
  • CheckValuesCallback (provides additional conditions to accept a timestep), provides a callback function with signature

    cvc(state, tmodel, deltat, model, modeldata)::Bool
    

    that checks variables have check_min_threshold < values < check_max_threshold and rejects timestep if not.

    Add to ``check_callbacks` list, eg

    check_small_values_callback = PALEOmodel.SteadyState.CheckValuesCallback(
      modeldata.solver_view_all.stateexplicit;
      exclude_variables=["atm.N_mr"], # exclude variables that do actually reach values < threshold
      check_min_value = 2*mr_threshold,
      verbose=false,
    )  
    
    PALEOmodel.SteadyState.steadystate_ptcForwardDiff(
        ...
        check_callbacks = [check_small_values_callback, ],    
        ...
    )
    

New options for use with NLsolve.jl ie apply to each Newton iteration (add to solvekwargs argument):

  • SolverFunctions.StepClampMultAll! callback (restricts Newton step size to multiple or fraction mr_maxstep of current value, as well as projecting new value to bounded region mr_min - mr_max)
    Requires https://github.com/PALEOtoolkit/NLsolve.jl project_region branch, with new option apply_step! to NLsolve:

    PALEOmodel.SteadyState.steadystate_ptcForwardDiff(
        ...
        solvekwargs = (apply_step! =  SolverFunctions.StepClampMultAll!(mr_threshold, mr_max, mr_maxstep), ...)
        ...
    )
    
  • Add sparse linear solvers adapted to NLsolve interface (linsolve argument, supplied via solvekwargs)

     PALEOmodel.SteadyState.steadystate_ptcForwardDiff(
        ...
        solvekwargs = (linsolve = PALEOmodel.SolverFunctions.SparseLinsolveUMFPACK(), ...) # UMFPACK with iterative refinement reenabled
        ...
    )
    
    PALEOmodel.SteadyState.steadystate_ptcForwardDiff(
        ...
        solvekwargs = (linsolve = PALEOmodel.SolverFunctions.SparseLinsolveSparspak64x2() , ...) # high accuracy quad precision lu factorisation
        ...
    )
    

Provides a callback function with signature

    rsvc(state, tmodel, deltat, model, modeldata)

that modifies `state` to reset variables with values < `modify_threshold`
to value `modify_val`, hence restarting the Newton solve from
`modify_val` on the next iteration.
Provides a callback function with signature

    cvc(state, tmodel, deltat, model, modeldata)::Bool

that checks variables have `check_min_threshold` < values < `check_max_threshold`.
Requires https://github.com/PALEOtoolkit/NLsolve.jl newton_robustness branch,
with new option to NLsolve:
- apply_step! =  SolverFunctions.StepClampMultAll!(...)
SolverFunctions.SparseLinsolveUMFPACK
SolverFunctions.SparseLinsolveSparspak64x2
This also reveals a Julia issue (JuliaSparse/SparseArrays.jl#454),
where
    MultiFloats.Float64x2.(A)
doesn't preserve structural nonzeros
@sjdaines sjdaines changed the title Add SteadyState.RestartSmallValuesCallback SteadyState solver robustness fixed Oct 11, 2023
@sjdaines sjdaines changed the title SteadyState solver robustness fixed SteadyState solver robustness fixes Oct 11, 2023
@sjdaines sjdaines changed the title SteadyState solver robustness fixes SteadyState solver robustness updates Oct 12, 2023
@sjdaines sjdaines merged commit 5436736 into main Oct 12, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant