Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #pragma once
11 :
12 : #include "MooseError.h"
13 : #include "TwoVector.h"
14 :
15 : #include "nlohmann/json.h"
16 :
17 : #include <variant>
18 :
19 : #include "libmesh/libmesh_common.h"
20 : #include "Eigen/Core"
21 : #include "metaphysicl/dualsemidynamicsparsenumberarray.h"
22 :
23 : #include <memory>
24 :
25 : class MooseApp;
26 :
27 : /**
28 : * Type definition for a variant that can hold all the supported types for lattice attributes
29 : */
30 : typedef std::variant<int,
31 : unsigned int,
32 : std::string,
33 : Real,
34 : bool,
35 : std::vector<int>,
36 : std::vector<unsigned int>,
37 : std::vector<std::string>,
38 : std::vector<Real>,
39 : std::vector<bool>>
40 : AttributeVariant;
41 :
42 : namespace libMesh
43 : {
44 : class Point;
45 : template <typename T>
46 : class DenseVector;
47 : template <typename T>
48 : class DenseMatrix;
49 : template <typename T>
50 : class NumericVector;
51 : }
52 :
53 : // Overloads for to_json, which _must_ be overloaded in the namespace
54 : // in which the object is found in order to enable argument-dependent lookup.
55 : // See https://en.cppreference.com/w/cpp/language/adl for more information
56 : void to_json(nlohmann::json & json, const MooseApp & app); // MooseDocs:to_json
57 :
58 : namespace libMesh
59 : {
60 : void to_json(nlohmann::json & json, const Point & p);
61 : void to_json(nlohmann::json & json, const DenseVector<Real> & vector);
62 : void to_json(nlohmann::json & json, const DenseMatrix<Real> & matrix);
63 : void to_json(nlohmann::json & json, const std::unique_ptr<NumericVector<Number>> & vector);
64 : }
65 :
66 : namespace Eigen
67 : {
68 : template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
69 : void to_json(nlohmann::json & json,
70 : const Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> & matrix);
71 : }
72 :
73 : namespace nlohmann
74 : {
75 : // Serializer for AttributeVariant
76 : template <>
77 : struct adl_serializer<AttributeVariant>
78 : {
79 164 : static void to_json(json & j, const AttributeVariant & data)
80 : {
81 328 : std::visit([&j](const auto & value) { j = value; }, data);
82 164 : }
83 : };
84 :
85 : template <typename T>
86 : struct adl_serializer<std::unique_ptr<T>>
87 : {
88 : /// Serializer that will output a unique ptr if it exists. We wrap this
89 : /// with is_constructible_v so that we don't specialize types that
90 : /// don't already have a specialization. This is required for some earlier
91 : /// compilers, even though we're not using it at the moment
92 4 : static void to_json(json & j, const std::unique_ptr<T> & v)
93 : {
94 : if constexpr (std::is_constructible_v<nlohmann::json, T>)
95 : {
96 4 : if (v)
97 2 : j = *v;
98 : else
99 2 : j = nullptr;
100 : }
101 : else
102 : mooseAssert(false, "Should not get to this");
103 4 : }
104 : };
105 : }
106 :
107 : namespace MetaPhysicL
108 : {
109 : template <template <typename, size_t> class Array, typename T, size_t N>
110 : void
111 : to_json(nlohmann::json & json, const DynamicArrayWrapper<Array, T, N> & array)
112 : {
113 : for (const auto element : array)
114 : nlohmann::to_json(json, element);
115 : }
116 :
117 : template <typename T, typename I, typename N, typename ArrayWrapper>
118 : void
119 : to_json(nlohmann::json & json,
120 : const SemiDynamicSparseNumberArrayGeneric<T, I, N, ArrayWrapper> & sdsna)
121 : {
122 : to_json(json, sdsna.nude_indices());
123 : to_json(json, sdsna.nude_data());
124 : }
125 :
126 : template <typename T, typename D, bool asd>
127 : void
128 : to_json(nlohmann::json & json, const DualNumber<T, D, asd> & dn)
129 : {
130 : nlohmann::to_json(json, dn.value());
131 : to_json(json, dn.derivatives());
132 : }
133 : }
134 :
135 : namespace Eigen
136 : {
137 : template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
138 : void
139 83 : to_json(nlohmann::json & json, const Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> & matrix)
140 : {
141 : if constexpr (Rows == 1 || Cols == 1)
142 : {
143 8 : std::vector<Scalar> values(matrix.data(), matrix.data() + matrix.rows() * matrix.cols());
144 8 : nlohmann::to_json(json, values);
145 8 : }
146 : else
147 : {
148 75 : const auto nrows = matrix.rows();
149 75 : const auto ncols = matrix.cols();
150 150 : std::vector<std::vector<Scalar>> values(nrows, std::vector<Scalar>(ncols));
151 216 : for (const auto i : make_range(nrows))
152 519 : for (const auto j : make_range(ncols))
153 378 : values[i][j] = matrix(i, j);
154 75 : nlohmann::to_json(json, values);
155 75 : }
156 83 : }
157 : }
158 :
159 : template <typename T>
160 : void
161 : to_json(nlohmann::json & json, const GenericTwoVector<T> & two_vector)
162 : {
163 : to_json(json, static_cast<const Eigen::Matrix<T, 2, 1> &>(two_vector));
164 : }
|