SIRIUS 7.5.0
Electronic structure library and applications
simulation_parameters.cpp
Go to the documentation of this file.
1// Copyright (c) 2013-2021 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file simulation_parameters.cpp
21 *
22 * \brief Contains implementation of sirius::Simulation_parameters class.
23 */
24
27#include "context/input_schema.hpp"
28
29#include <unordered_set>
30#include <iterator>
31#include <sstream>
32
33namespace sirius {
34template <typename T>
35static std::ostringstream
36option_print_vector__(const std::vector<T>& vec)
37{
38 std::ostringstream out;
39 if (!vec.empty()) {
40 out << "[" << vec[0];
41 for (auto i = 0u; i < vec.size(); i++) {
42 out << ", " << vec[i];
43 }
44 out << "]";
45 }
46 return out;
47}
48/// Compose JSON dictionary with default parameters based on input schema.
49/** Traverse the JSON schema and add nodes with default parameters to the output dictionary. The nodes without
50 * default parameters are ignored. Still, user has a possibility to add the missing nodes later by providing a
51 * corresponding input JSON dictionary. See compose_json() function. */
52void
53compose_default_json(nlohmann::json const& schema__, nlohmann::json& output__)
54{
55 for (auto it : schema__.items()) {
56 auto key = it.key();
57 /* this is a final node with the description of the data type */
58 if (it.value().contains("type") && it.value()["type"] != "object") {
59 /* check if default parameter is present */
60 if (it.value().contains("default")) {
61 output__[key] = it.value()["default"];
62 }
63 } else { /* otherwise continue to traverse the shcema */
64 if (!output__.contains(key)) {
65 output__[key] = nlohmann::json{};
66 }
67 if (it.value().contains("properties")) {
68 compose_default_json(it.value()["properties"], output__[key]);
69 }
70 }
71 }
72}
73
74/// Append the input dictionary to the existing dictionary.
75/** Use JSON schema to traverse the existing dictionary and add on top the values from the input dictionary. In this
76 * way we can add missing nodes which were not defined in the existing dictionary. */
77void
78compose_json(nlohmann::json const& schema__, nlohmann::json const& in__, nlohmann::json& inout__)
79{
80 std::unordered_set<std::string> visited;
81
82 for (auto it : in__.items()) {
83 visited.insert(it.key());
84 }
85
86 for (auto it : schema__.items()) {
87 auto key = it.key();
88
89 // Remove visited items.
90 auto found = visited.find(key);
91 if (found != visited.end()) {
92 visited.erase(found);
93 }
94
95 /* this is a final node with the description of the data type */
96 if (it.value().contains("type") && it.value()["type"] != "object") {
97 if (in__.contains(key)) {
98 /* copy the new input */
99 inout__[key] = in__[key];
100 }
101 } else { /* otherwise continue to traverse the shcema */
102 if (it.value().contains("properties")) {
103 compose_json(it.value()["properties"], in__.contains(key) ? in__[key] : nlohmann::json{}, inout__[key]);
104 } else if (in__.contains(key)) {
105 inout__[key] = in__[key];
106 } else {
107 inout__[key] = nlohmann::json();
108 }
109 }
110 }
111
112 // Emit warnings about keys that were set but unused.
113 if (!visited.empty()) {
114 std::stringstream ss;
115 ss << "The following configuration parameters were not recognized and ignored: ";
116 std::copy(visited.begin(), visited.end(), std::ostream_iterator<std::string>(ss, " "));
117 RTE_WARNING(ss)
118 }
119}
120
121Config::Config()
122{
123 /* initialize JSON dictionary with default parameters */
124 compose_default_json(sirius::input_schema["properties"], this->dict_);
125}
126
127void
128Config::import(nlohmann::json const& in__)
129{
130 /* overwrite the parameters by the values from the input dictionary */
131 compose_json(sirius::input_schema["properties"], in__, this->dict_);
132}
133
134/// Get all possible options for initializing sirius. It is a json dictionary.
135nlohmann::json const&
137{
138 if (input_schema.size() == 0) {
139 throw std::runtime_error("Dictionary not initialized\n");
140 }
141 return input_schema;
142}
143
144/// Get all possible options of a given input section. It is a json dictionary.
145nlohmann::json const&
146get_section_options(std::string const& section__)
147{
148 if (input_schema.size() == 0) {
149 throw std::runtime_error("Dictionary not initialized\n");
150 }
151 return input_schema["properties"][section__]["properties"];
152}
153
154void
155Simulation_parameters::import(std::string const& str__)
156{
157 auto json = read_json_from_file_or_string(str__);
158 import(json);
159}
160
161void
162Simulation_parameters::import(nlohmann::json const& dict__)
163{
164 cfg_.import(dict__);
165}
166
167void
169{
170 cfg_.control().processing_unit(args__.value("control.processing_unit", cfg_.control().processing_unit()));
171 cfg_.control().mpi_grid_dims(args__.value("control.mpi_grid_dims", cfg_.control().mpi_grid_dims()));
172 cfg_.control().std_evp_solver_name(
173 args__.value("control.std_evp_solver_name", cfg_.control().std_evp_solver_name()));
174 cfg_.control().gen_evp_solver_name(
175 args__.value("control.gen_evp_solver_name", cfg_.control().gen_evp_solver_name()));
176 cfg_.control().fft_mode(args__.value("control.fft_mode", cfg_.control().fft_mode()));
177 cfg_.control().verbosity(args__.value("control.verbosity", cfg_.control().verbosity()));
178 cfg_.control().verification(args__.value("control.verification", cfg_.control().verification()));
179
180 cfg_.parameters().ngridk(args__.value("parameters.ngridk", cfg_.parameters().ngridk()));
181 cfg_.parameters().gamma_point(args__.value("parameters.gamma_point", cfg_.parameters().gamma_point()));
182 cfg_.parameters().pw_cutoff(args__.value("parameters.pw_cutoff", cfg_.parameters().pw_cutoff()));
183 cfg_.parameters().gk_cutoff(args__.value("parameters.gk_cutoff", cfg_.parameters().gk_cutoff()));
184
185 cfg_.iterative_solver().early_restart(
186 args__.value("iterative_solver.early_restart", cfg_.iterative_solver().early_restart()));
187 cfg_.mixer().beta(args__.value("mixer.beta", cfg_.mixer().beta()));
188 cfg_.mixer().type(args__.value("mixer.type", cfg_.mixer().type()));
189}
190
191void
192Simulation_parameters::core_relativity(std::string name__)
193{
194 cfg_.parameters().core_relativity(name__);
195 core_relativity_ = get_relativity_t(name__);
196}
197
198void
199Simulation_parameters::valence_relativity(std::string name__)
200{
201 cfg_.parameters().valence_relativity(name__);
202 valence_relativity_ = get_relativity_t(name__);
203}
204
205void
206Simulation_parameters::processing_unit(std::string name__)
207{
208 /* set the default value */
209 if (name__ == "auto") {
210 if (acc::num_devices() > 0) {
211 name__ = "gpu";
212 } else {
213 name__ = "cpu";
214 }
215 }
216 cfg_.control().processing_unit(name__);
217 processing_unit_ = sddk::get_device_t(name__);
218}
219
220void
221Simulation_parameters::smearing(std::string name__)
222{
223 cfg_.parameters().smearing(name__);
224 smearing_ = smearing::get_smearing_t(name__);
225}
226
227void
228Simulation_parameters::electronic_structure_method(std::string name__)
229{
230 cfg_.parameters().electronic_structure_method(name__);
231
232 std::map<std::string, electronic_structure_method_t> m = {
235
236 if (m.count(name__) == 0) {
237 std::stringstream s;
238 s << "wrong type of electronic structure method: " << name__;
239 RTE_THROW(s);
240 }
242}
243} // namespace sirius
sddk::device_t processing_unit_
Type of the processing unit.
smearing::smearing_t smearing_
Type of occupation numbers smearing.
relativity_t valence_relativity_
Type of relativity for valence states.
void import(std::string const &str__)
Import parameters from a file or a serialized json string.
Config cfg_
All user-provided paramters are stored here.
relativity_t core_relativity_
Type of relativity for core states.
electronic_structure_method_t electronic_structure_method_
Type of electronic structure method.
Simple command line arguments handler.
Definition: cmd_args.hpp:39
T value(std::string const key__) const
Get a value or terminate if key is not found.
Definition: cmd_args.hpp:113
Contains declaration and implementation of mpi::Communicator class.
int num_devices()
Get the number of devices.
Definition: acc.cpp:32
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
Definition: acc.hpp:320
Namespace of the SIRIUS library.
Definition: sirius.f90:5
@ full_potential_lapwlo
Full potential linearized augmented plane waves with local orbitals.
@ pseudopotential
Pseudopotential (ultrasoft, norm-conserving, PAW).
void compose_json(nlohmann::json const &schema__, nlohmann::json const &in__, nlohmann::json &inout__)
Append the input dictionary to the existing dictionary.
nlohmann::json const & get_section_options(std::string const &section__)
Get all possible options of a given input section. It is a json dictionary.
void compose_default_json(nlohmann::json const &schema__, nlohmann::json &output__)
Compose JSON dictionary with default parameters based on input schema.
nlohmann::json const & get_options_dictionary()
Get all possible options for initializing sirius. It is a json dictionary.
Contains definition and implementation of sirius::Simulation_parameters class.