Line data Source code
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 : #include <iostream>
26 :
27 : #include "neml2/base/LabeledAxisAccessor.h"
28 : #include "neml2/misc/assertions.h"
29 : #include "neml2/misc/string_utils.h"
30 :
31 : namespace neml2
32 : {
33 : std::vector<std::string>
34 0 : reserved_subaxis_names()
35 : {
36 0 : return {STATE, OLD_STATE, FORCES, OLD_FORCES, RESIDUAL, PARAMETERS};
37 0 : }
38 :
39 1 : LabeledAxisAccessor::operator std::vector<std::string>() const
40 : {
41 1 : std::vector<std::string> v(_item_names.begin(), _item_names.end());
42 1 : return v;
43 : }
44 :
45 : std::string
46 416 : LabeledAxisAccessor::str() const
47 : {
48 416 : return utils::stringify(*this);
49 : }
50 :
51 : bool
52 27739 : LabeledAxisAccessor::empty() const
53 : {
54 27739 : return _item_names.empty();
55 : }
56 :
57 : size_t
58 18754 : LabeledAxisAccessor::size() const
59 : {
60 18754 : return _item_names.size();
61 : }
62 :
63 : const std::string &
64 17361 : LabeledAxisAccessor::operator[](size_t i) const
65 : {
66 17361 : return _item_names[i];
67 : }
68 :
69 : LabeledAxisAccessor
70 154 : LabeledAxisAccessor::with_suffix(const std::string & suffix) const
71 : {
72 154 : auto new_names = _item_names;
73 154 : new_names.back() += suffix;
74 308 : return new_names;
75 154 : }
76 :
77 : LabeledAxisAccessor
78 2145 : LabeledAxisAccessor::append(const LabeledAxisAccessor & axis) const
79 : {
80 2145 : return axis.prepend(*this);
81 : }
82 :
83 : LabeledAxisAccessor
84 29874 : LabeledAxisAccessor::prepend(const LabeledAxisAccessor & axis) const
85 : {
86 29874 : auto new_names = axis._item_names;
87 29874 : new_names.insert(new_names.end(), _item_names.begin(), _item_names.end());
88 59748 : return new_names;
89 29874 : }
90 :
91 : LabeledAxisAccessor
92 2539 : LabeledAxisAccessor::slice(int64_t n) const
93 : {
94 2539 : n = n < 0 ? int64_t(size()) + n : n;
95 2539 : neml_assert(size() >= std::size_t(n), "cannot apply slice");
96 2539 : std::vector<std::string> new_names(_item_names.begin() + n, _item_names.end());
97 5078 : return new_names;
98 2539 : }
99 :
100 : LabeledAxisAccessor
101 1563 : LabeledAxisAccessor::slice(int64_t n1, int64_t n2) const
102 : {
103 1563 : n1 = n1 < 0 ? int64_t(size()) + n1 : n1;
104 1563 : n2 = n2 < 0 ? int64_t(size()) + n2 : n2;
105 1563 : neml_assert(size() >= std::size_t(n1), "cannot apply slice");
106 1563 : neml_assert(size() >= std::size_t(n2), "cannot apply slice");
107 1563 : std::vector<std::string> new_names(_item_names.begin() + n1, _item_names.begin() + n2);
108 3126 : return new_names;
109 1563 : }
110 :
111 : LabeledAxisAccessor
112 133 : LabeledAxisAccessor::remount(const LabeledAxisAccessor & axis, int64_t n) const
113 : {
114 133 : return slice(n).prepend(axis);
115 : }
116 :
117 : bool
118 1561 : LabeledAxisAccessor::start_with(const LabeledAxisAccessor & axis) const
119 : {
120 1561 : return slice(0, int64_t(axis.size())) == axis;
121 : }
122 :
123 : bool
124 827 : LabeledAxisAccessor::is_state() const
125 : {
126 827 : return start_with(STATE);
127 : }
128 :
129 : bool
130 163 : LabeledAxisAccessor::is_old_state() const
131 : {
132 163 : return start_with(OLD_STATE);
133 : }
134 :
135 : bool
136 167 : LabeledAxisAccessor::is_force() const
137 : {
138 167 : return start_with(FORCES);
139 : }
140 :
141 : bool
142 47 : LabeledAxisAccessor::is_old_force() const
143 : {
144 47 : return start_with(OLD_FORCES);
145 : }
146 :
147 : bool
148 134 : LabeledAxisAccessor::is_residual() const
149 : {
150 134 : return start_with(RESIDUAL);
151 : }
152 :
153 : bool
154 88 : LabeledAxisAccessor::is_parameter() const
155 : {
156 88 : return start_with(PARAMETERS);
157 : }
158 :
159 : LabeledAxisAccessor
160 0 : LabeledAxisAccessor::current() const
161 : {
162 0 : neml_assert(_item_names.size() >= 1, "variable name length must be at least 1");
163 0 : if (start_with(OLD_STATE))
164 0 : return remount(STATE);
165 0 : if (start_with(OLD_FORCES))
166 0 : return remount(FORCES);
167 0 : throw NEMLException("Unable to find current counterpart of variable named '" +
168 0 : utils::stringify(*this) + "'");
169 : }
170 :
171 : LabeledAxisAccessor
172 85 : LabeledAxisAccessor::old() const
173 : {
174 85 : neml_assert(_item_names.size() >= 1, "variable name length must be at least 1");
175 85 : if (start_with(STATE))
176 35 : return remount(OLD_STATE);
177 50 : if (start_with(FORCES))
178 50 : return remount(OLD_FORCES);
179 0 : throw NEMLException("Unable to find old counterpart of variable named '" +
180 0 : utils::stringify(*this) + "'");
181 : }
182 :
183 : void
184 87605 : LabeledAxisAccessor::validate_item_name(const std::string & name) const
185 : {
186 87605 : neml_assert(!name.empty(), "Empty item variable name");
187 87605 : const auto x = name.find_first_of(" .,;/\t\n\v\f\r");
188 87605 : neml_assert(x == std::string::npos,
189 : "Invalid item name: ",
190 : name,
191 : ". The item names cannot contain whitespace, '.', ',', ';', or '/'.");
192 87604 : }
193 :
194 : bool
195 7389 : operator!=(const LabeledAxisAccessor & a, const LabeledAxisAccessor & b)
196 : {
197 7389 : return a.vec() != b.vec();
198 : }
199 :
200 : bool
201 69108 : operator==(const LabeledAxisAccessor & a, const LabeledAxisAccessor & b)
202 : {
203 69108 : return a.vec() == b.vec();
204 : }
205 :
206 : bool
207 493587 : operator<(const LabeledAxisAccessor & a, const LabeledAxisAccessor & b)
208 : {
209 493587 : return a.vec() < b.vec();
210 : }
211 :
212 : std::ostream &
213 2652 : operator<<(std::ostream & os, const LabeledAxisAccessor & accessor)
214 : {
215 8691 : for (size_t i = 0; i < accessor.vec().size(); i++)
216 : {
217 6039 : if (i != 0)
218 3387 : os << "/";
219 6039 : os << accessor.vec()[i];
220 : }
221 2652 : return os;
222 : }
223 : } // namespace neml2
|