NEML2 1.4.0
Loading...
Searching...
No Matches
Factory.h
1// Copyright 2024, UChicago Argonne, LLC
2// All Rights Reserved
3// Software Name: NEML2 -- the New Engineering material Model Library, version 2
4// By: Argonne National Laboratory
5// OPEN SOURCE LICENSE (MIT)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23// THE SOFTWARE.
24#pragma once
25
26#include <filesystem>
27#include "neml2/base/NEML2Object.h"
28#include "neml2/misc/error.h"
29#include "neml2/base/OptionCollection.h"
30#include "neml2/base/DiagnosticsInterface.h"
31
32namespace neml2
33{
34// Forward decl
35class Model;
36class Driver;
37class Settings;
38
47void load_input(const std::filesystem::path & path, const std::string & additional_input = "");
48
58void reload_input(const std::filesystem::path & path, const std::string & additional_input = "");
59
69Model & get_model(const std::string & mname, bool enable_ad = true, bool force_create = true);
70
78Model &
79load_model(const std::filesystem::path & path, const std::string & mname, bool enable_ad = true);
80
89Model &
90reload_model(const std::filesystem::path & path, const std::string & mname, bool enable_ad = true);
91
99Driver & get_driver(const std::string & dname);
100
107{
108public:
110 static Factory & get();
111
128 template <class T>
129 static std::shared_ptr<T> get_object_ptr(const std::string & section,
130 const std::string & name,
132 bool force_create = true);
133
150 template <class T>
151 static T & get_object(const std::string & section,
152 const std::string & name,
154 bool force_create = true);
155
162 static void load_options(const OptionCollection & all_options);
163
165 static const OptionCollection & loaded_options();
166
168 static void clear();
169
175 static void print(std::ostream & os = std::cout);
176
177protected:
184 void create_object(const std::string & section, const OptionSet & options);
185
186private:
188 OptionCollection _all_options;
189
194 std::map<std::string, std::map<std::string, std::vector<std::shared_ptr<NEML2Object>>>> _objects;
195
197 Settings _settings;
198};
199
200template <class T>
201inline std::shared_ptr<T>
202Factory::get_object_ptr(const std::string & section,
203 const std::string & name,
205 bool force_create)
206{
207 auto & factory = Factory::get();
208
209 // Easy if it already exists
210 if (!force_create)
211 if (factory._objects.count(section) && factory._objects.at(section).count(name))
212 for (const auto & neml2_obj : factory._objects[section][name])
213 {
214 // Check for option clash
215 if (!options_compatible(neml2_obj->input_options(), additional_options))
216 continue;
217
218 // Check for object type
219 auto obj = std::dynamic_pointer_cast<T>(neml2_obj);
220 neml_assert(obj != nullptr,
221 "Found object named ",
222 name,
223 " under section ",
224 section,
225 ". But dynamic cast failed. Did you specify the correct object type?");
226
227 return obj;
228 }
229
230 // Otherwise try to create it
231 for (auto & options : factory._all_options[section])
232 if (options.first == name)
233 {
234 auto new_options = options.second;
236 factory.create_object(section, new_options);
237 break;
238 }
239
240 neml_assert(factory._objects.count(section) && factory._objects.at(section).count(name),
241 "Failed to get object named ",
242 name,
243 " under section ",
244 section);
245
246 auto obj = std::dynamic_pointer_cast<T>(factory._objects[section][name].back());
247 neml_assert(obj != nullptr, "Internal error: Factory failed to create object ", name);
248 return obj;
249}
250
251template <class T>
252inline T &
253Factory::get_object(const std::string & section,
254 const std::string & name,
256 bool force_create)
257{
258 return *Factory::get_object_ptr<T>(section, name, additional_options, force_create);
259}
260} // namespace neml2
The wrapper (decorator) for cross-referencing unresolved values at parse time.
Definition CrossRef.h:56
Definition Factory.h:107
void create_object(const std::string &section, const OptionSet &options)
Manufacture a single NEML2Object.
Definition Factory.cxx:114
static T & get_object(const std::string &section, const std::string &name, const OptionSet &additional_options=OptionSet(), bool force_create=true)
Retrive an object reference under the given section with the given object name.
Definition Factory.h:253
static std::shared_ptr< T > get_object_ptr(const std::string &section, const std::string &name, const OptionSet &additional_options=OptionSet(), bool force_create=true)
Retrive an object pointer under the given section with the given object name.
Definition Factory.h:202
static const OptionCollection & loaded_options()
Get the loaded options.
Definition Factory.cxx:107
static void load_options(const OptionCollection &all_options)
Provide all objects' options to the factory. The factory is ready to manufacture objects after this c...
Definition Factory.cxx:96
static void clear()
Destruct all the objects.
Definition Factory.cxx:140
static Factory & get()
Get the global Factory singleton.
Definition Factory.cxx:89
static void print(std::ostream &os=std::cout)
List all the manufactured objects.
Definition Factory.cxx:127
A data structure that holds options of multiple objects.
Definition OptionCollection.h:39
A custom map-like data structure. The keys are strings, and the values can be nonhomogeneously typed.
Definition OptionSet.h:100
Definition Settings.h:32
Definition CrossRef.cxx:30
Model & load_model(const std::filesystem::path &path, const std::string &mname, bool enable_ad)
A convenient function to load an input file and get a model.
Definition Factory.cxx:69
bool options_compatible(const OptionSet &opts, const OptionSet &additional_opts)
Definition OptionSet.cxx:31
void reload_input(const std::filesystem::path &path, const std::string &additional_input)
Similar to neml2::load_input, but additionally clear the Factory before loading the options,...
Definition Factory.cxx:52
Model & reload_model(const std::filesystem::path &path, const std::string &mname, bool enable_ad)
Similar to neml2::load_model, but additionally clear the Factory before loading the model,...
Definition Factory.cxx:76
Model & get_model(const std::string &mname, bool enable_ad, bool force_create)
A convenient function to manufacture a neml2::Model.
Definition Factory.cxx:59
Driver & get_driver(const std::string &dname)
A convenient function to manufacture a neml2::Driver.
Definition Factory.cxx:83
void load_input(const std::filesystem::path &path, const std::string &additional_input)
A convenient function to parse all options from an input file.
Definition Factory.cxx:35
void neml_assert(bool assertion, Args &&... args)
Definition error.h:64