Page MenuHomec4science

step_solver.hpp
No OneTemporary

File Metadata

Created
Thu, Aug 15, 03:46

step_solver.hpp

/* =============================================================================
Copyright (c) 2014 - 2016
F. Georget <fabieng@princeton.edu> Princeton University
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
============================================================================= */
#ifndef SPECMICP_SPECMICP_STEPSOLVER_HPP
#define SPECMICP_SPECMICP_STEPSOLVER_HPP
/*!
* \file specmicp/problem_solver/step_solver.hpp
* \brief Solve a series of problem
*
* It provides a common interface to solve a succession of similar problem.
*/
#include "specmicp_common/types.hpp"
#include "specmicp_common/pimpl_ptr.hpp"
#include <functional>
#include <memory>
namespace specmicp {
struct AdimensionalSystemConstraints;
struct AdimensionalSystemSolution;
class AdimensionalSystemSolutionExtractor;
struct AdimensionalSystemSolverOptions;
class ReactantBox;
namespace database {
struct DataContainer;
} // end namespace database
namespace units {
struct UnitsSet;
} // end namespace units
//! \brief The current status of the computation
enum class StepProblemStatus
{
OK, //!< Continue the computation
Stop, //!< The computation finished correctly
Error //!< An error occured, the computation was aborted
};
//! \brief A function of this type check when the computation must be stopped
using stepper_stop_condition_f =
std::function<StepProblemStatus (
uindex_t,
const AdimensionalSystemSolutionExtractor&
)>;
//! \brief A function of this type computes the next set of constraints
//!
//! return : status of the computation
//! param :
//! - uindex_t [in] : the current step id
//! - const AdimensionalSystemSolutionExtractor& [in] : the previous solution
//! - AdimensionalSystemConstraints& [out] : the set of constraints to update
using stepper_next_step_f =
std::function<StepProblemStatus (
uindex_t,
const AdimensionalSystemSolutionExtractor&,
AdimensionalSystemConstraints&
)>;
//! \brief A function of this type output the solution at each step
using stepper_output_f =
std::function<StepProblemStatus (
uindex_t,
const AdimensionalSystemSolutionExtractor&
)>;
//! \brief A step problem
//!
//! A step problem is a series of computations, each only slightly different.
class SPECMICP_DLL_PUBLIC StepProblem
{
public:
StepProblem();
StepProblem(stepper_next_step_f updater,
stepper_stop_condition_f stopper,
AdimensionalSystemConstraints&& constraints
);
StepProblem(StepProblem&& other);
~StepProblem();
// Setter
// ======
//! \brief Set how to compute the next set of constraints
void set_constraint_updater(stepper_next_step_f updater);
//! \brief Set how to end the computation
void set_stop_condition(stepper_stop_condition_f stopper);
//! \brief Stop the problem when cnt == max_step
void set_stop_condition_step(uindex_t stop_step);
//! \brief Set initial constraints
void set_initial_constraints(ReactantBox& reactant_box, bool modify_db=true);
//! \brief Return true if the problem is correctly initialized
bool is_valid();
// Getter
// ======
AdimensionalSystemConstraints get_constraints() const;
//! \brief Update constraints
StepProblemStatus update_constraints(
uindex_t cnt,
const AdimensionalSystemSolution * const solution
);
//! \brief Check if the computation is finished
//!
//! \param cnt current step
//! \param solution current solution
StepProblemStatus check_stop_condition(
uindex_t cnt,
const AdimensionalSystemSolution * const solution
);
//! \brief Return the database
std::shared_ptr<database::DataContainer> get_database();
//! \brief Return the units
const units::UnitsSet& get_units();
private:
StepProblem(const StepProblem& other) = delete;
StepProblem& operator=(const StepProblem& other) = delete;
struct SPECMICP_DLL_LOCAL StepProblemImpl;
utils::pimpl_ptr<StepProblemImpl> m_impl;
};
//! \brief Run a step problem
//!
//! This is the 'loop' algorithm which solves every step.
class SPECMICP_DLL_PUBLIC StepProblemRunner
{
public:
StepProblemRunner();
StepProblemRunner(StepProblemRunner&& other);
~StepProblemRunner();
//! \brief Set an initial solution to warmastart the computation (optional)
void set_warmstart_solution(const AdimensionalSystemSolution& solution);
void set_warmstart_solution(AdimensionalSystemSolution&& solution);
//! \brief Set the specmicp solver options
void set_solver_options(AdimensionalSystemSolverOptions& opts);
//! \brief Set the callback to save the solution at each step
void set_step_output(stepper_output_f output);
//! \brief Return a reference to the solver options
AdimensionalSystemSolverOptions& get_solver_options();
//! \brief Return the solution
const AdimensionalSystemSolution& get_solution() const;
//! \brief Solve the problem
StepProblemStatus run(StepProblem& problem);
private:
StepProblemRunner(const StepProblem& other) = delete;
StepProblemRunner& operator=(const StepProblem& other) = delete;
struct SPECMICP_DLL_LOCAL StepProblemRunnerImpl;
utils::pimpl_ptr<StepProblemRunnerImpl> m_impl;
//! \brief Return the solution
const AdimensionalSystemSolution * const get_ptr_solution() const;
};
// Simple functors to use as constraint updaters
//! \brief Update the total concentration at each step
//!
//! \param update_concentration update to the total concentrations
//!
//! The update must be a vector Nc x 1
class StepTotalConcentration
{
public:
StepTotalConcentration(
const Eigen::Ref<Vector>& update_concentration
):
m_update(update_concentration)
{}
StepTotalConcentration(
Vector&& update_concentration
):
m_update(update_concentration)
{}
StepProblemStatus operator() (
uindex_t cnt,
const AdimensionalSystemSolutionExtractor& _,
AdimensionalSystemConstraints& constraints);
private:
Vector m_update;
};
} // end namespace specmicp
#endif // SPECMICP_SPECMICP_STEPSOLVER_HPP

Event Timeline