Solver#
Solver is a class that describes the direct problem, providing a method evaluate that returns the value of the objective function from the input parameters.
Solveris defined as a derived class ofodatse.solver.SolverBase.import odatse class Solver(odatse.solver.SolverBase): pass
Constructor
Solver class should have a constructor that takes an
Infoclass object as an argument:def __init__(self, info: odatse.Info): super().__init__(info)
It is required to call the constructor of the base class with the info object. The following instance variables are set by the constructor of the base class:
self.root_dir: pathlib.Path: Root directoryThis parameter is taken from
info.base["root_dir"], and represents the directory in whichodatseis executed. It can be used as the base location when external programs or data files are read.self.output_dir: pathlib.Path: Output directoryThis parameter is taken from
info.base["output_dir"], and used for the directory in which the result files are written. Usually, when the MPI parallelization is applied, the accumulated results are stored.self.proc_dir: pathlib.Path: Working directory for each MPI process by the formself.output_dir / str(odatse.mpi.algrank())The
evaluatemethod of Solver is called from Runner with theproc_dirdirectory set as the current directory, in which the intermediate results produced by each rank are stored. When the MPI parallelization is not used, the rank number is treated as 0.self.work_dir: pathlib.Path: An alias ofself.proc_dir.self.dimension: int: The dimension of the input parameter. It is taken frominfo.solver["dimension"]if specified, or frominfo.base["dimension"]otherwise.self.timer: dict: A dictionary for recording execution times, with the keys"prepare","run", and"post".self._name: str: The name of the solver. It is initialized to an empty string in the base class; set an appropriate name in the constructor. It is referred to through thenameproperty.
The parameters for the Solver class can be obtained from the
solverfield of theinfoobject. The required parameters should be taken and stored.evaluatemethodThe form of
evaluatemethod should be as follows:def evaluate(self, x, args=()) -> float: pass
This method evaluates the objective function at a given parameter value
xand returns the result. It takes the following arguments:x: np.ndarrayThe parameter value as an \(N\)-dimensional vector of type
numpy.ndarray.args: Tuple = ()The additional arguments passed from the Algorithm in the form of a Tuple of two integers. One is the step count that corresponds to the Monte Carlo steps for MC type algorithms, or the index of the grid point for the grid search algorithm. The other is the set number that represents the \(n\)-th iteration.
The
evaluatemethod returns the value of the objective function as a float.Note
If
evaluateraises aRuntimeErrorandignore_error = trueis specified in the[runner]section, the Runner ignores the exception and treats the objective function value asnp.nan. If the search point does not satisfy the constraints ([runner.limitation]), the solver is not called and the objective function value becomesnp.inf.Note
When the solver parallelization is used (
--nsolvegreater than 1),evaluateis called on all MPI ranks in the solver group with the samexandargs. The division of roles among the ranks should be implemented within the solver. See Two-level MPI parallelization of the solver for details.