https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DataIO.C
Go to the documentation of this file.
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#include "DenseMatrix.h"
11#include "DataIO.h"
12#include "MooseMesh.h"
13#include "FEProblemBase.h"
14#include "NonlinearSystemBase.h"
15
16#include "libmesh/vector_value.h"
17#include "libmesh/tensor_value.h"
18#include "libmesh/fe_type.h"
19
20#include "libmesh/elem.h"
21#include "libmesh/petsc_vector.h"
22#include "libmesh/enum_solver_package.h"
23#include "libmesh/petsc_solver_exception.h"
24#include "libmesh/bounding_box.h"
25
26using namespace libMesh;
27
28template <>
29void
30dataStore(std::ostream & stream, Real & v, void * /*context*/)
31{
32 stream.write((char *)&v, sizeof(v));
33}
34
35template <>
36void
37dataStore(std::ostream & stream, std::string & v, void * /*context*/)
38{
39 // Write the size of the string
40 unsigned int size = v.size();
41 stream.write((char *)&size, sizeof(size));
42
43 // Write the string (Do not store the null byte)
44 stream.write(v.c_str(), sizeof(char) * size);
45}
46
47template <>
48void
49dataStore(std::ostream & stream, VariableName & v, void * context)
50{
51 auto & name = static_cast<std::string &>(v);
52 dataStore(stream, name, context);
53}
54
55template <>
56void
57dataStore(std::ostream & stream, UserObjectName & v, void * context)
58{
59 auto & name = static_cast<std::string &>(v);
60 dataStore(stream, name, context);
61}
62
63template <>
64void
65dataStore(std::ostream & stream, bool & v, void * /*context*/)
66{
67 stream.write((char *)&v, sizeof(v));
68}
69
70template <>
71void
72dataStore(std::ostream & stream, FEType & v, void * context)
73{
74 auto order = v.order.get_order();
75 dataStore(stream, order, context);
76
77 auto family = v.family;
78 dataStore(stream, family, context);
79
80#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
81 auto radial_order = v.radial_order.get_order();
82 dataStore(stream, radial_order, context);
83
84 auto radial_family = v.radial_family;
85 dataStore(stream, radial_family, context);
86
87 auto inf_map = v.inf_map;
88 dataStore(stream, inf_map, context);
89#endif
90
91 auto p_refinement = v.p_refinement;
92 dataStore(stream, p_refinement, context);
93}
94
95template <>
96void
97dataStore(std::ostream & stream, std::vector<bool> & v, void * context)
98{
99 for (bool b : v)
100 dataStore(stream, b, context);
101}
102
103template <>
104void
105dataStore(std::ostream & stream, RankTwoTensor & rtt, void * context)
106{
107 dataStore(stream, rtt._coords, context);
108}
109
110template <>
111void
112dataStore(std::ostream & stream, RankThreeTensor & rtht, void * context)
113{
114 dataStore(stream, rtht._vals, context);
115}
116
117template <>
118void
119dataStore(std::ostream & stream, RankFourTensor & rft, void * context)
120{
121 dataStore(stream, rft._vals, context);
122}
123
124template <>
125void
126dataStore(std::ostream & stream, ADReal & dn, void * context)
127{
128 dataStore(stream, dn.value(), context);
129
130 if (ADReal::do_derivatives)
131 {
132 auto & derivatives = dn.derivatives();
133 std::size_t size = derivatives.size();
134 dataStore(stream, size, context);
135 for (MooseIndex(size) i = 0; i < size; ++i)
136 {
137 dataStore(stream, derivatives.raw_index(i), context);
138 dataStore(stream, derivatives.raw_at(i), context);
139 }
140 }
141}
142
143template <>
144void
145dataStore(std::ostream & stream, const Elem *& e, void * context)
146{
147 // TODO: Write out the unique ID of this elem
149
150 if (e)
151 {
152 id = e->id();
154 mooseError("Can't output Elems with invalid ids!");
155 }
156
157 storeHelper(stream, id, context);
158}
159
160template <>
161void
162dataStore(std::ostream & stream, const Node *& n, void * context)
163{
164 // TODO: Write out the unique ID of this node
166
167 if (n)
168 {
169 id = n->id();
171 mooseError("Can't output Nodes with invalid ids!");
172 }
173
174 storeHelper(stream, id, context);
175}
176
177template <>
178void
179dataStore(std::ostream & stream, Elem *& e, void * context)
180{
181 // TODO: Write out the unique ID of this elem
183
184 if (e)
185 {
186 id = e->id();
188 mooseError("Can't output Elems with invalid ids!");
189 }
190
191 storeHelper(stream, id, context);
192}
193
194template <>
195void
196dataStore(std::ostream & stream, Node *& n, void * context)
197{
198 // TODO: Write out the unique ID of this node
200
201 if (n)
202 {
203 id = n->id();
205 mooseError("Can't output Nodes with invalid ids!");
206 }
207
208 storeHelper(stream, id, context);
209}
210
211template <>
212void
213dataStore(std::ostream & stream, std::stringstream & s, void * /* context */)
214{
215 const std::string & s_str = s.str();
216
217 size_t s_size = s_str.size();
218 stream.write((char *)&s_size, sizeof(s_size));
219
220 stream.write(s_str.c_str(), sizeof(char) * (s_str.size()));
221}
222
223#ifdef MOOSE_LIBTORCH_ENABLED
224template <>
225void
226dataStore(std::ostream & stream, torch::Tensor & t, void * context)
227{
228 const auto tensor = LibtorchUtils::toCPUContiguous(t);
229 mooseAssert(tensor.scalar_type() == at::kDouble,
230 "Restart storage currently supports only double tensors.");
231
232 auto rank = cast_int<unsigned int>(tensor.dim());
233 dataStore(stream, rank, nullptr);
234 for (unsigned int dim = 0; dim < rank; ++dim)
235 {
236 auto size = cast_int<unsigned int>(tensor.sizes()[dim]);
237 dataStore(stream, size, nullptr);
238 }
239
240 const auto flattened = tensor.reshape({tensor.numel()});
241 const auto t_accessor = flattened.accessor<Real, 1>();
242 for (int64_t i = 0; i < flattened.numel(); ++i)
243 {
244 Real r = t_accessor[i];
245 dataStore(stream, r, context);
246 }
247}
248#endif
249
250template <typename T>
251void
252dataStore(std::ostream & stream, TensorValue<T> & v, void * context)
253{
254 for (const auto i : make_range(Moose::dim))
255 for (const auto j : make_range(Moose::dim))
256 {
257 T r = v(i, j);
258 dataStore(stream, r, context);
259 }
260}
261
262template void dataStore(std::ostream & stream, TensorValue<Real> & v, void * context);
263template void dataStore(std::ostream & stream, TensorValue<ADReal> & v, void * context);
264
265template <typename T>
266void
267dataStore(std::ostream & stream, DenseMatrix<T> & v, void * context)
268{
269 unsigned int m = v.m();
270 unsigned int n = v.n();
271 stream.write((char *)&m, sizeof(m));
272 stream.write((char *)&n, sizeof(n));
273 for (unsigned int i = 0; i < m; i++)
274 for (unsigned int j = 0; j < n; j++)
275 {
276 T r = v(i, j);
277 dataStore(stream, r, context);
278 }
279}
280
281template void dataStore(std::ostream & stream, DenseMatrix<Real> & v, void * context);
282template void dataStore(std::ostream & stream, DenseMatrix<ADReal> & v, void * context);
283
284template <typename T>
285void
286dataStore(std::ostream & stream, VectorValue<T> & v, void * context)
287{
288 // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
289 // won't work.
290 for (const auto i : make_range(Moose::dim))
291 {
292 T r = v(i);
293 dataStore(stream, r, context);
294 }
295}
296
297template void dataStore(std::ostream & stream, VectorValue<Real> & v, void * context);
298template void dataStore(std::ostream & stream, VectorValue<ADReal> & v, void * context);
299
300void
301dataStore(std::ostream & stream, Point & p, void * context)
302{
303 for (const auto i : make_range(Moose::dim))
304 dataStore(stream, p(i), context);
305}
306
307void
308dataStore(std::ostream & stream, libMesh::BoundingBox & bbox, void * context)
309{
310 storeHelper(stream, static_cast<std::pair<Point, Point> &>(bbox), context);
311}
312
313template <>
314void
315dataStore(std::ostream & stream, libMesh::Parameters & p, void * context)
316{
317 // First store the size of the map
318 unsigned int size = p.n_parameters();
319 stream.write((char *)&size, sizeof(size));
320
321 auto it = p.begin();
322 auto end = p.end();
323
324 for (; it != end; ++it)
325 {
326 auto & key = const_cast<std::string &>(it->first);
327 auto type = it->second->type();
328
329 storeHelper(stream, key, context);
330 storeHelper(stream, type, context);
331
332#define storescalar(ptype) \
333 else if (it->second->type() == demangle(typeid(ptype).name())) storeHelper( \
334 stream, \
335 (dynamic_cast<libMesh::Parameters::Parameter<ptype> *>(MooseUtils::get(it->second)))->get(), \
336 context)
337
338 if (false)
339 ;
340 storescalar(Real);
341 storescalar(short);
342 storescalar(int);
343 storescalar(long);
344 storescalar(unsigned short);
345 storescalar(unsigned int);
346 storescalar(unsigned long);
347
348#undef storescalar
349 }
350}
351
352template <>
353void
354dataStore(std::ostream & stream,
355 std::unique_ptr<libMesh::NumericVector<Number>> & v,
356 void * context)
357{
358 // Classes may declare unique pointers to vectors as restartable data and never actually create
359 // vector instances. This happens for example in the `TimeIntegrator` class where subvector
360 // instances are only created if multiple time integrators are present
361 bool have_vector = v.get();
362 dataStore(stream, have_vector, context);
363 if (!have_vector)
364 return;
365
366 mooseAssert(context, "Needs a context of the communicator");
367 const auto & comm = *static_cast<const libMesh::Parallel::Communicator *>(context);
368 mooseAssert(&comm == &v->comm(), "Inconsistent communicator");
369
370 if (v->type() == GHOSTED)
371 mooseError("Cannot store ghosted numeric vectors");
372
373 // Store the communicator size for sanity checking later
374 unsigned int comm_size = comm.size();
375 dataStore(stream, comm_size, nullptr);
376
377 // Store the solver package so that we know what vector type to construct
378 libMesh::SolverPackage solver_package;
379 if (dynamic_cast<libMesh::PetscVector<Number> *>(v.get()))
380 solver_package = PETSC_SOLVERS;
381 else
382 mooseError("Can only store unique_ptrs of PetscVectors");
383 int solver_package_int = solver_package;
384 dataStore(stream, solver_package_int, nullptr);
385
386 // Store the sizes
387 dof_id_type size = v->size();
388 dataStore(stream, size, nullptr);
389 dof_id_type local_size = v->local_size();
390 dataStore(stream, local_size, nullptr);
391
392 // Store the vector itself
393 dataStore(stream, *v, nullptr);
394}
395
396// global load functions
397
398template <>
399void
400dataLoad(std::istream & stream, Real & v, void * /*context*/)
401{
402 stream.read((char *)&v, sizeof(v));
403}
404
405template <>
406void
407dataLoad(std::istream & stream, std::string & v, void * /*context*/)
408{
409 // Read the size of the string
410 unsigned int size = 0;
411 stream.read((char *)&size, sizeof(size));
412
413 // Resize the string data
414 v.resize(size);
415
416 // Read the string
417 stream.read(&v[0], sizeof(char) * size);
418}
419
420template <>
421void
422dataLoad(std::istream & stream, VariableName & v, void * context)
423{
424 auto & name = static_cast<std::string &>(v);
425 dataLoad(stream, name, context);
426}
427
428template <>
429void
430dataLoad(std::istream & stream, UserObjectName & v, void * context)
431{
432 auto & name = static_cast<std::string &>(v);
433 dataLoad(stream, name, context);
434}
435
436template <>
437void
438dataLoad(std::istream & stream, bool & v, void * /*context*/)
439{
440 stream.read((char *)&v, sizeof(v));
441}
442
443template <>
444void
445dataLoad(std::istream & stream, FEType & v, void * context)
446{
447 int order = 0;
448 dataLoad(stream, order, context);
449 v.order = order;
450
451 dataLoad(stream, v.family, context);
452
453#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
454 int radial_order = 0;
455 dataLoad(stream, radial_order, context);
456 v.radial_order = radial_order;
457
458 dataLoad(stream, v.radial_family, context);
459 dataLoad(stream, v.inf_map, context);
460#endif
461
462 dataLoad(stream, v.p_refinement, context);
463}
464
465template <>
466void
467dataLoad(std::istream & stream, std::vector<bool> & v, void * context)
468{
469 for (bool b : v)
470 dataLoad(stream, b, context);
471}
472
473template <>
474void
475dataLoad(std::istream & stream, ADReal & dn, void * context)
476{
477 dataLoad(stream, dn.value(), context);
478
479 if (ADReal::do_derivatives)
480 {
481 auto & derivatives = dn.derivatives();
482 std::size_t size = 0;
483 stream.read((char *)&size, sizeof(size));
484 derivatives.resize(size);
485
486 for (MooseIndex(derivatives) i = 0; i < derivatives.size(); ++i)
487 {
488 dataLoad(stream, derivatives.raw_index(i), context);
489 dataLoad(stream, derivatives.raw_at(i), context);
490 }
491 }
492}
493
494template <>
495void
496dataLoad(std::istream & stream, const Elem *& e, void * context)
497{
498 if (!context)
499 mooseError("Can only load Elem objects using a MooseMesh context!");
500
501 MooseMesh * mesh = static_cast<MooseMesh *>(context);
502
503 // TODO: Write out the unique ID of this element
505
506 loadHelper(stream, id, context);
507
509 e = mesh->elemPtr(id);
510 else
511 e = NULL;
512}
513
514template <>
515void
516dataLoad(std::istream & stream, const Node *& n, void * context)
517{
518 if (!context)
519 mooseError("Can only load Node objects using a MooseMesh context!");
520
521 MooseMesh * mesh = static_cast<MooseMesh *>(context);
522
523 // TODO: Write out the unique ID of this nodeent
525
526 loadHelper(stream, id, context);
527
529 n = mesh->nodePtr(id);
530 else
531 n = NULL;
532}
533
534template <>
535void
536dataLoad(std::istream & stream, Elem *& e, void * context)
537{
538 if (!context)
539 mooseError("Can only load Elem objects using a MooseMesh context!");
540
541 MooseMesh * mesh = static_cast<MooseMesh *>(context);
542
543 // TODO: Write out the unique ID of this element
545
546 loadHelper(stream, id, context);
547
549 e = mesh->elemPtr(id);
550 else
551 e = NULL;
552}
553
554template <>
555void
556dataLoad(std::istream & stream, Node *& n, void * context)
557{
558 if (!context)
559 mooseError("Can only load Node objects using a MooseMesh context!");
560
561 MooseMesh * mesh = static_cast<MooseMesh *>(context);
562
563 // TODO: Write out the unique ID of this nodeent
565
566 loadHelper(stream, id, context);
567
569 n = mesh->nodePtr(id);
570 else
571 n = NULL;
572}
573
574template <>
575void
576dataLoad(std::istream & stream, std::stringstream & s, void * /* context */)
577{
578 size_t s_size = 0;
579 stream.read((char *)&s_size, sizeof(s_size));
580
581 std::unique_ptr<char[]> s_s = std::make_unique<char[]>(s_size);
582 stream.read(s_s.get(), s_size);
583
584 // Clear the stringstream before loading new data into it.
585 s.str(std::string());
586 s.write(s_s.get(), s_size);
587}
588
589#ifdef MOOSE_LIBTORCH_ENABLED
590template <>
591void
592dataLoad(std::istream & stream, torch::Tensor & t, void * context)
593{
594 unsigned int rank = 0;
595 dataLoad(stream, rank, nullptr);
596
597 std::vector<int64_t> sizes(rank);
598 for (unsigned int dim = 0; dim < rank; ++dim)
599 {
600 unsigned int size = 0;
601 dataLoad(stream, size, nullptr);
602 sizes[dim] = size;
603 }
604
605 t = torch::empty(sizes, at::kDouble);
606 auto flattened = t.reshape({t.numel()});
607 auto t_accessor = flattened.accessor<Real, 1>();
608 for (int64_t i = 0; i < flattened.numel(); ++i)
609 {
610 Real r = 0;
611 dataLoad(stream, r, context);
612 t_accessor[i] = r;
613 }
614}
615#endif
616
617template <typename T>
618void
619dataLoad(std::istream & stream, TensorValue<T> & v, void * context)
620{
621 // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
622 // won't work.
623 for (const auto i : make_range(Moose::dim))
624 for (const auto j : make_range(Moose::dim))
625 {
626 T r = 0;
627 dataLoad(stream, r, context);
628 v(i, j) = r;
629 }
630}
631
632template void dataLoad(std::istream & stream, TensorValue<Real> & v, void * context);
633template void dataLoad(std::istream & stream, TensorValue<ADReal> & v, void * context);
634
635template <typename T>
636void
637dataLoad(std::istream & stream, DenseMatrix<T> & v, void * context)
638{
639 unsigned int m = 0, n = 0;
640 stream.read((char *)&m, sizeof(m));
641 stream.read((char *)&n, sizeof(n));
642 v.resize(m, n);
643 for (unsigned int i = 0; i < m; i++)
644 for (unsigned int j = 0; j < n; j++)
645 {
646 T r = 0;
647 dataLoad(stream, r, context);
648 v(i, j) = r;
649 }
650}
651
652template void dataLoad(std::istream & stream, DenseMatrix<Real> & v, void * context);
653template void dataLoad(std::istream & stream, DenseMatrix<ADReal> & v, void * context);
654
655template <typename T>
656void
657dataLoad(std::istream & stream, VectorValue<T> & v, void * context)
658{
659 // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
660 // won't work.
661 for (const auto i : make_range(Moose::dim))
662 {
663 T r = 0;
664 dataLoad(stream, r, context);
665 v(i) = r;
666 }
667}
668
669template void dataLoad(std::istream & stream, VectorValue<Real> & v, void * context);
670template void dataLoad(std::istream & stream, VectorValue<ADReal> & v, void * context);
671
672void
673dataLoad(std::istream & stream, Point & p, void * context)
674{
675 for (const auto i : make_range(Moose::dim))
676 dataLoad(stream, p(i), context);
677}
678
679void
680dataLoad(std::istream & stream, libMesh::BoundingBox & bbox, void * context)
681{
682 loadHelper(stream, static_cast<std::pair<Point, Point> &>(bbox), context);
683}
684
685template <>
686void
687dataLoad(std::istream & stream, libMesh::Parameters & p, void * context)
688{
689 p.clear();
690
691 // First read the size of the map
692 unsigned int size = 0;
693 stream.read((char *)&size, sizeof(size));
694
695 for (unsigned int i = 0; i < size; i++)
696 {
697 std::string key, type;
698 loadHelper(stream, key, context);
699 loadHelper(stream, type, context);
700
701#define loadscalar(ptype) \
702 else if (type == demangle(typeid(ptype).name())) do \
703 { \
704 ptype & value = p.set<ptype>(key); \
705 loadHelper(stream, value, context); \
706 } \
707 while (0)
708
709 if (false)
710 ;
711 loadscalar(Real);
712 loadscalar(short);
713 loadscalar(int);
714 loadscalar(long);
715 loadscalar(unsigned short);
716 loadscalar(unsigned int);
717 loadscalar(unsigned long);
718
719#undef loadscalar
720 }
721}
722
723template <>
724void
725dataLoad(std::istream & stream, std::unique_ptr<libMesh::NumericVector<Number>> & v, void * context)
726{
727 bool have_vector;
728 dataLoad(stream, have_vector, context);
729
730 if (!have_vector)
731 return;
732
733 mooseAssert(context, "Needs a context of the communicator");
734 const auto & comm = *static_cast<const libMesh::Parallel::Communicator *>(context);
735 if (v)
736 mooseAssert(&comm == &v->comm(), "Inconsistent communicator");
737
738 // Load the communicator size for consistency checks
739 unsigned int comm_size;
740 dataLoad(stream, comm_size, nullptr);
741 mooseAssert(comm.size() == comm_size, "Inconsistent communicator size");
742
743 // Load the solver package to build the vector
744 int solver_package_int;
745 dataLoad(stream, solver_package_int, nullptr);
746 libMesh::SolverPackage solver_package = static_cast<libMesh::SolverPackage>(solver_package_int);
747
748 // Load the sizes
749 dof_id_type size, local_size;
750 dataLoad(stream, size, nullptr);
751 dataLoad(stream, local_size, nullptr);
752
753 // Construct the vector given the type, only if we need to. v could be non-null here
754 // if we're advancing back and loading a backup
755 if (!v)
756 {
757 v = NumericVector<Number>::build(comm, solver_package);
758 v->init(size, local_size);
759 }
760 else
761 mooseAssert(v->type() != GHOSTED, "Cannot be ghosted");
762
763 // Make sure that the sizes are consistent; this will happen if we're calling this
764 // on a vector that has already been loaded previously
765 mooseAssert(v->size() == size, "Inconsistent size");
766 mooseAssert(v->local_size() == local_size, "Inconsistent local size");
767
768 // Now that we have an initialized vector, fill the entries
769 dataLoad(stream, *v, nullptr);
770}
771
772template <>
773void
774dataLoad(std::istream & stream, Vec & v, void * context)
775{
776 PetscInt local_size;
777 LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetLocalSize(v, &local_size));
778 PetscScalar * array;
779 LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetArray(v, &array));
780 for (PetscInt i = 0; i < local_size; i++)
781 dataLoad(stream, array[i], context);
782
783 LibmeshPetscCallA(PETSC_COMM_WORLD, VecRestoreArray(v, &array));
784}
785
786template <>
787void
788dataStore(std::ostream & stream, Vec & v, void * context)
789{
790 PetscInt local_size;
791 LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetLocalSize(v, &local_size));
792 PetscScalar * array;
793 LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetArray(v, &array));
794 for (PetscInt i = 0; i < local_size; i++)
795 dataStore(stream, array[i], context);
796
797 LibmeshPetscCallA(PETSC_COMM_WORLD, VecRestoreArray(v, &array));
798}
DualNumber< Real, DNDerivativeType, true > ADReal
void dataLoad(std::istream &stream, Real &v, void *)
Definition DataIO.C:400
void dataStore(std::ostream &stream, Real &v, void *)
Definition DataIO.C:30
void storeHelper(std::ostream &stream, P &data, void *context)
Scalar helper routine.
Definition DataIO.h:989
void loadHelper(std::istream &stream, P &data, void *context)
Scalar helper routine.
Definition DataIO.h:1081
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
unsigned int dim
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
RankThreeTensor is designed to handle any N-dimensional third order tensor, r.
T _vals[N3]
The values of the rank-three tensor stored by index=((i * LIBMESH_DIM + j) * LIBMESH_DIM + k)
unsigned int n() const
unsigned int m() const
void resize(const unsigned int new_m, const unsigned int new_n)
static constexpr dof_id_type invalid_id
dof_id_type id() const
InfMapType inf_map
OrderWrapper radial_order
OrderWrapper order
FEFamily radial_family
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
std::size_t n_parameters() const
virtual void clear()
T _coords[LIBMESH_DIM *LIBMESH_DIM]
MeshBase & mesh
torch::Tensor toCPUContiguous(const torch::Tensor &tensor)
Return a detached contiguous CPU copy of a tensor.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:165
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
uint8_t dof_id_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)