NEML2 2.0.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
25#pragma once
26
27#include <filesystem>
28#include <iostream>
29
30#include "neml2/misc/errors.h"
31#include "neml2/base/InputFile.h"
32
33namespace neml2
34{
35// Forward decl
36class Settings;
37class Factory;
38class NEML2Object;
39class Solver;
40class Data;
41class Model;
42class Driver;
43class WorkScheduler;
44
51{
52public:
54
56 InputFile & input_file() { return _input_file; }
57
59 const InputFile & input_file() const { return _input_file; }
60
62 const std::shared_ptr<Settings> & settings() const { return _input_file.settings(); }
63
65 bool has_object(const std::string & section, const std::string & name);
66
83 template <class T>
84 std::shared_ptr<T> get_object(const std::string & section,
85 const std::string & name,
86 const OptionSet & additional_options = OptionSet(),
87 bool force_create = true);
88
90 template <class T = Solver>
91 std::shared_ptr<T> get_solver(const std::string & name);
93 template <class T = Data>
94 std::shared_ptr<T> get_data(const std::string & name);
96 template <class T = Model>
97 std::shared_ptr<T> get_model(const std::string & name);
99 template <class T = Driver>
100 std::shared_ptr<T> get_driver(const std::string & name);
102 template <class T = WorkScheduler>
103 std::shared_ptr<T> get_scheduler(const std::string & name);
104
106 void clear();
107
113 void print(std::ostream & os = std::cout);
114
115protected:
122 void create_object(const std::string & section, const OptionSet & options);
123
124private:
126 bool options_compatible(const std::shared_ptr<NEML2Object> & obj, const OptionSet & opts) const;
127
129 InputFile _input_file;
130
135 std::map<std::string, std::map<std::string, std::vector<std::shared_ptr<NEML2Object>>>> _objects;
136};
137
138template <class T>
139std::shared_ptr<T>
140Factory::get_object(const std::string & section,
141 const std::string & name,
142 const OptionSet & additional_options,
143 bool force_create)
144{
145 if (input_file().data().empty())
146 throw FactoryException("The input file is empty.");
147
148 // Easy if it already exists
149 if (!force_create)
150 if (_objects.count(section) && _objects.at(section).count(name))
151 for (const auto & neml2_obj : _objects[section][name])
152 {
153 // Check for option clash
154 if (!options_compatible(neml2_obj, additional_options))
155 continue;
156
157 // Check for object type
158 auto obj = std::dynamic_pointer_cast<T>(neml2_obj);
159 if (!obj)
160 throw FactoryException(
161 "Found object named " + name + " under section " + section +
162 ". But dynamic cast failed. Did you specify the correct object type?");
163
164 return obj;
165 }
166
167 // Otherwise try to create it
168 for (const auto & options : _input_file[section])
169 if (options.first == name)
170 {
171 auto new_options = options.second;
172 new_options.set<Factory *>("_factory") = this;
173 new_options.set<std::shared_ptr<Settings>>("_settings") = settings();
174 new_options += additional_options;
175 create_object(section, new_options);
176 break;
177 }
178
179 if (!_objects.count(section) || !_objects.at(section).count(name))
180 throw FactoryException("Failed to get object named " + name + " under section " + section +
181 ". Check to make sure the object is defined in the input file.");
182
183 auto obj = std::dynamic_pointer_cast<T>(_objects[section][name].back());
184
185 if (!obj)
186 throw FactoryException("Internal error: Factory failed to create object " + name);
187
188 return obj;
189}
190
191template <class T>
192std::shared_ptr<T>
193Factory::get_solver(const std::string & name)
194{
195 return get_object<T>("Solvers", name);
196}
197
198template <class T>
199std::shared_ptr<T>
200Factory::get_data(const std::string & name)
201{
202 return get_object<T>("Data", name);
203}
204
205template <class T>
206std::shared_ptr<T>
207Factory::get_model(const std::string & name)
208{
209 return get_object<T>("Models", name);
210}
211
212template <class T>
213std::shared_ptr<T>
214Factory::get_driver(const std::string & name)
215{
216 return get_object<T>("Drivers", name);
217}
218
219template <class T>
220std::shared_ptr<T>
221Factory::get_scheduler(const std::string & name)
222{
223 return get_object<T>("Schedulers", name);
224}
225} // namespace neml2
Definition errors.h:73
Definition Factory.h:51
std::shared_ptr< T > get_object(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:140
std::shared_ptr< T > get_driver(const std::string &name)
Get a driver by its name.
Definition Factory.h:214
std::shared_ptr< T > get_data(const std::string &name)
Get a data by its name.
Definition Factory.h:200
void create_object(const std::string &section, const OptionSet &options)
Manufacture a single NEML2Object.
Definition Factory.cxx:46
const std::shared_ptr< Settings > & settings() const
Global settings.
Definition Factory.h:62
Factory(InputFile)
Definition Factory.cxx:33
std::shared_ptr< T > get_model(const std::string &name)
Get a model by its name.
Definition Factory.h:207
std::shared_ptr< T > get_scheduler(const std::string &name)
Get a scheduler by its name.
Definition Factory.h:221
bool has_object(const std::string &section, const std::string &name)
Check if an object with the given name exists under the given section.
Definition Factory.cxx:40
InputFile & input_file()
Get the input file.
Definition Factory.h:56
const InputFile & input_file() const
Get the input file.
Definition Factory.h:59
void clear()
Delete all factories and destruct all the objects.
Definition Factory.cxx:87
std::shared_ptr< T > get_solver(const std::string &name)
Get a solver by its name.
Definition Factory.h:193
void print(std::ostream &os=std::cout)
List all the manufactured objects.
Definition Factory.cxx:74
A data structure that holds options of multiple objects.
Definition InputFile.h:37
const std::shared_ptr< Settings > & settings() const
Get global settings.
Definition InputFile.h:42
A custom map-like data structure. The keys are strings, and the values can be nonhomogeneously typed.
Definition OptionSet.h:51
Definition DiagnosticsInterface.cxx:30
std::string name(ElasticConstant p)
Definition ElasticityConverter.cxx:30