/// Returns Ok(None) if the potential does not support this method.
Returns Ok(None) if the potential does not support this method.
Returns Ok ( None ) if the potential does not support this method .
fn do_cg_relax_with_param_optimization(
    pot: &dyn PotentialBuilder,
    cg_settings: &cfg::Cg,
    snapshot_fn: SnapshotFn,
    parameters: Option<&cfg::Parameters>,
    lattice_relax_settings: Option<&cfg::LatticeRelax>,
    coords: &Coords,
    meta: CommonMeta,
) -> FailResult<Option<Coords>>
{Ok({
    let bond_diff_fn = match pot.parallel(true).initialize_bond_diff_fn(&coords, meta.sift())? {
        None => return Ok(None),
        Some(f) => f,
    };
    // Object that encapsulates the coordinate conversion logic for param optimization
    let param_helper = match (parameters, lattice_relax_settings) {
        // lattice-based takes precedence
        (_, Some(cfg)) => {
            Rc::new(RelaxationOptimizationHelper::LatticeBased(LatticeOptimizationHelper::new(cfg, coords.lattice())))
        },
        (Some(cfg), None) => {
            Rc::new(RelaxationOptimizationHelper::ParamBased(ParamOptimizationHelper::new(cfg, coords.lattice())))
        },
        (None, None) => unreachable!("checked beforehand"),
    };
    let (mut cg, stop_condition_cereal) = cg_builder_from_config(cg_settings);
    // Make the stop condition and output representative of the cartesian forces.
    cg.output_fn(get_param_opt_output_fn(param_helper.clone(), log_cg_output));
    cg.output_fn({
        let param_helper = param_helper.clone();
        move |state: cg::AlgorithmState<'_>| {
            snapshot_fn.maybe_save_snapshot(&state, param_helper.unflatten_coords(state.position))
        }
    });
    cg.stop_condition({
        let param_helper = param_helper.clone();
        let mut stop_condition_imp = stop_condition_cereal.to_function();
        move |state: cg::AlgorithmState<'_>| {
            // HACK: to avoid code duplication, use the stop conditions built into rsp2_minimize,
            //       but feed them modified data.  I know that the stop condition won't look at
            //       most of these fields since I maintain both crates...          - ML
            let cg::AlgorithmState {
                iterations, value, position, gradient, direction, alpha,
                ..
            } = state;
            let (d_carts, d_params) = param_helper.unflatten_grad(position, gradient);
            let mut gradient = d_carts.flat().to_vec();
            // FIXME HACK: include the parameter forces in the list, scaled to an intrinsic
            //             quantity, so that they are checked by a "max-grad" constraint.
            // The proper solution is to make a new replacement for
            // rsp2_minimize::cg::stop_condition::Simple that has a "stress-max" variant.
            gradient.extend(d_params.into_iter().map(|x| x / d_carts.len() as f64));
            let gradient = &gradient[..];
            stop_condition_imp(cg::AlgorithmState {
                iterations, value, position, gradient, direction, alpha,
                // HACK: To make matters even worse, we can't just replace the `gradient` field
                //       of state due to lifetime issues. We must construct a new one, and there
                //       is no public API for doing that (and I'm not sure I want to provide one).
                //
                //       So for now this field is `#[doc(hidden)] pub`...
                __no_full_destructure: (),
            })
        }
    });
    trace!("Incorporating parameter optimization into relaxation");
    let relaxed_flat = {
         cg.run(
            &param_helper.flatten_coords(&coords),
            {
                let helper = param_helper.clone();
                crate::cmd::param_optimization::OptimizingDiffFn { helper, bond_diff_fn, meta }
            },
        ).unwrap().position
    };
    Some(param_helper.unflatten_coords(&relaxed_flat[..]))
})}
fn do_cg_relax_with_param_optimization ( pot : & dyn PotentialBuilder , cg_settings : & cfg :: Cg , snapshot_fn : SnapshotFn , parameters : Option < & cfg :: Parameters > , lattice_relax_settings : Option < & cfg :: LatticeRelax > , coords : & Coords , meta : CommonMeta , ) -> FailResult < Option < Coords > > { Ok ( { let bond_diff_fn = match pot . parallel ( true ) . initialize_bond_diff_fn ( & coords , meta . sift ( ) ) ? { None => return Ok ( None ) , Some ( f ) => f , } ; // Object that encapsulates the coordinate conversion logic for param optimization let param_helper = match ( parameters , lattice_relax_settings ) { // lattice-based takes precedence ( _ , Some ( cfg ) ) => { Rc :: new ( RelaxationOptimizationHelper :: LatticeBased ( LatticeOptimizationHelper :: new ( cfg , coords . lattice ( ) ) ) ) } , ( Some ( cfg ) , None ) => { Rc :: new ( RelaxationOptimizationHelper :: ParamBased ( ParamOptimizationHelper :: new ( cfg , coords . lattice ( ) ) ) ) } , ( None , None ) => unreachable ! ( " " ) , } ; let ( mut cg , stop_condition_cereal ) = cg_builder_from_config ( cg_settings ) ; // Make the stop condition and output representative of the cartesian forces. cg . output_fn ( get_param_opt_output_fn ( param_helper . clone ( ) , log_cg_output ) ) ; cg . output_fn ( { let param_helper = param_helper . clone ( ) ; move | state : cg :: AlgorithmState < ' _ > | { snapshot_fn . maybe_save_snapshot ( & state , param_helper . unflatten_coords ( state . position ) ) } } ) ; cg . stop_condition ( { let param_helper = param_helper . clone ( ) ; let mut stop_condition_imp = stop_condition_cereal . to_function ( ) ; move | state : cg :: AlgorithmState < ' _ > | { // HACK: to avoid code duplication, use the stop conditions built into rsp2_minimize, //       but feed them modified data.  I know that the stop condition won't look at //       most of these fields since I maintain both crates...          - ML let cg :: AlgorithmState { iterations , value , position , gradient , direction , alpha , .. } = state ; let ( d_carts , d_params ) = param_helper . unflatten_grad ( position , gradient ) ; let mut gradient = d_carts . flat ( ) . to_vec ( ) ; // FIXME HACK: include the parameter forces in the list, scaled to an intrinsic //             quantity, so that they are checked by a "max-grad" constraint. // The proper solution is to make a new replacement for // rsp2_minimize::cg::stop_condition::Simple that has a "stress-max" variant. gradient . extend ( d_params . into_iter ( ) . map ( | x | x / d_carts . len ( ) as f64 ) ) ; let gradient = & gradient [ .. ] ; stop_condition_imp ( cg :: AlgorithmState { iterations , value , position , gradient , direction , alpha , // HACK: To make matters even worse, we can't just replace the `gradient` field //       of state due to lifetime issues. We must construct a new one, and there //       is no public API for doing that (and I'm not sure I want to provide one). // //       So for now this field is `#[doc(hidden)] pub`... __no_full_destructure : ( ) , } ) } } ) ; trace ! ( " " ) ; let relaxed_flat = { cg . run ( & param_helper . flatten_coords ( & coords ) , { let helper = param_helper . clone ( ) ; crate :: cmd :: param_optimization :: OptimizingDiffFn { helper , bond_diff_fn , meta } } , ) . unwrap ( ) . position } ; Some ( param_helper . unflatten_coords ( & relaxed_flat [ .. ] ) ) } ) }
Returns Ok(None) if the potential does not support this method.
Returns Ok ( None ) if the potential does not support this method .
pot
&dyn PotentialBuilder
cg_settings
&cfg::Cg
snapshot_fn
SnapshotFn
parameters
Option<&cfg::Parameters>
lattice_relax_settings
Option<&cfg::LatticeRelax>
coords
&Coords
meta
CommonMeta