1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20 #ifndef LIBMESH_SYSTEM_H
21 #define LIBMESH_SYSTEM_H
22
23 // Local Includes
24 #include "libmesh/elem_range.h"
25 #include "libmesh/enum_subset_solve_mode.h" // SUBSET_ZERO
26 #include "libmesh/enum_parallel_type.h" // PARALLEL
27 #include "libmesh/fem_function_base.h"
28 #include "libmesh/libmesh_common.h"
29 #include "libmesh/parallel_object.h"
30 #include "libmesh/qoi_set.h"
31 #include "libmesh/reference_counted_object.h"
32 #include "libmesh/tensor_value.h" // For point_hessian
33 #include "libmesh/variable.h"
34
35 #ifdef LIBMESH_FORWARD_DECLARE_ENUMS
36 namespace libMesh
37 {
38 enum FEMNormType : int;
39 }
40 #else
41 #include "libmesh/enum_norm_type.h"
42 #endif
43
44 // C++ includes
45 #include <cstddef>
46 #include <set>
47 #include <vector>
48 #include <memory>
49
50 // This define may be useful in --disable-optional builds when it is
51 // possible that libmesh will not have any solvers available.
52 #if defined(LIBMESH_HAVE_PETSC) || \
53 defined(LIBMESH_HAVE_EIGEN) || \
54 defined(LIBMESH_HAVE_LASPACK) || \
55 defined(LIBMESH_TRILINOS_HAVE_AZTECOO)
56 #define LIBMESH_HAVE_SOLVER 1
57 #endif
58
59 namespace libMesh
60 {
61
62 // Forward Declarations
63 class System;
64 class EquationSystems;
65 class MeshBase;
66 class Xdr;
67 class DofMap;
68 template <typename Output> class FunctionBase;
69 class Parameters;
70 class ParameterVector;
71 class Point;
72 class SensitivityData;
73 template <typename T> class NumericVector;
74 template <typename T> class SparseMatrix;
75 template <typename T> class VectorValue;
76 typedef VectorValue<Number> NumberVectorValue;
77 typedef NumberVectorValue Gradient;
78 class SystemSubset;
79 class FEType;
80 class SystemNorm;
81
82 /**
83 * \brief Manages consistently variables, degrees of freedom, and coefficient
84 * vectors.
85 *
86 * This is the base class for classes which contain information related to any
87 * physical process that might be simulated. Such information may range from
88 * the actual solution values to algorithmic flags that may be used to control
89 * the numerical methods employed. In general, use an EquationSystems
90 * object to handle one or more of the children of this class.
91 *
92 * Especially, this class manages the variables of the differential equation,
93 * the coefficient vectors and the \p DofMap, and ensures that these are
94 * consistent. It provides storage for the solution. Furthermore, (de-)
95 * serialization functionality is provided.
96 *
97 * \author Benjamin S. Kirk
98 * \date 2003-2004
99 */
100 class System : public ReferenceCountedObject<System>,
101 public ParallelObject
102 {
103 public:
104
105 /**
106 * Constructor. Optionally initializes required
107 * data structures.
108 */
109 System (EquationSystems & es,
110 const std::string & name,
111 const unsigned int number);
112
113 /**
114 * Abstract base class to be used for system initialization.
115 * A user class derived from this class may be used to
116 * initialize the system values by attaching an object
117 * with the method \p attach_init_object.
118 */
119 class Initialization
120 {
121 public:
122 /**
123 * Destructor. Virtual because we will have virtual functions.
124 */
~Initialization()125 virtual ~Initialization () {}
126
127 /**
128 * Initialization function. This function will be called
129 * to initialize the system values upon creation and must
130 * be provided by the user in a derived class.
131 */
132 virtual void initialize () = 0;
133 };
134
135
136
137 /**
138 * Abstract base class to be used for system assembly.
139 * A user class derived from this class may be used to
140 * assemble the system by attaching an object
141 * with the method \p attach_assemble_object.
142 */
143 class Assembly
144 {
145 public:
146 /**
147 * Destructor. Virtual because we will have virtual functions.
148 */
~Assembly()149 virtual ~Assembly () {}
150
151 /**
152 * Assembly function. This function will be called
153 * to assemble the system prior to a solve and must
154 * be provided by the user in a derived class.
155 */
156 virtual void assemble () = 0;
157 };
158
159
160
161 /**
162 * Abstract base class to be used for system constraints.
163 * A user class derived from this class may be used to
164 * constrain the system by attaching an object
165 * with the method \p attach_constraint_object.
166 */
167 class Constraint
168 {
169 public:
170 /**
171 * Destructor. Virtual because we will have virtual functions.
172 */
~Constraint()173 virtual ~Constraint () {}
174
175 /**
176 * Constraint function. This function will be called
177 * to constrain the system prior to a solve and must
178 * be provided by the user in a derived class.
179 */
180 virtual void constrain () = 0;
181 };
182
183
184
185 /**
186 * Abstract base class to be used for quantities of interest.
187 * A user class derived from this class may be used to
188 * compute quantities of interest by attaching an object
189 * with the method \p attach_QOI_object.
190 */
191 class QOI
192 {
193 public:
194 /**
195 * Destructor. Virtual because we will have virtual functions.
196 */
~QOI()197 virtual ~QOI () {}
198
199 /**
200 * Quantity of interest function. This function will be called
201 * to compute quantities of interest and must be provided by the
202 * user in a derived class.
203 */
204 virtual void qoi (const QoISet & qoi_indices) = 0;
205 };
206
207
208
209 /**
210 * Abstract base class to be used for derivatives of quantities
211 * of interest. A user class derived from this class may be used
212 * to compute quantities of interest by attaching an object
213 * with the method \p attach_QOI_derivative_object.
214 */
215 class QOIDerivative
216 {
217 public:
218 /**
219 * Destructor. Virtual because we will have virtual functions.
220 */
~QOIDerivative()221 virtual ~QOIDerivative () {}
222
223 /**
224 * Quantity of interest derivative function. This function will
225 * be called to compute derivatives of quantities of interest and
226 * must be provided by the user in a derived class.
227 */
228 virtual void qoi_derivative (const QoISet & qoi_indices,
229 bool include_liftfunc,
230 bool apply_constraints) = 0;
231 };
232
233
234
235 /**
236 * Destructor.
237 */
238 virtual ~System ();
239
240 /**
241 * The type of system.
242 */
243 typedef System sys_type;
244
245 /**
246 * \returns A reference to *this.
247 */
system()248 sys_type & system () { return *this; }
249
250 /**
251 * Clear all the data structures associated with
252 * the system.
253 */
254 virtual void clear ();
255
256 /**
257 * Initializes degrees of freedom on the current mesh.
258 * Sets the
259 */
260 void init ();
261
262 /**
263 * Reinitializes degrees of freedom and other required data on the
264 * current mesh.
265 *
266 * \note The matrix is not initialized at this time since it may not
267 * be required for all applications. Should be overridden in derived
268 * classes.
269 */
270 virtual void reinit ();
271
272 /**
273 * Reinitializes the constraints for this system.
274 */
275 virtual void reinit_constraints ();
276
277 /**
278 * \returns \p true iff this system has been initialized.
279 */
280 bool is_initialized();
281
282 /**
283 * Update the local values to reflect the solution
284 * on neighboring processors.
285 */
286 virtual void update ();
287
288 /**
289 * Prepares \p matrix and \p _dof_map for matrix assembly.
290 * Does not actually assemble anything. For matrix assembly,
291 * use the \p assemble() in derived classes.
292 * Should be overridden in derived classes.
293 */
294 virtual void assemble ();
295
296 /**
297 * Calls user qoi function.
298 * Can be overridden in derived classes.
299 */
300 virtual void assemble_qoi (const QoISet & qoi_indices = QoISet());
301
302 /**
303 * Calls user qoi derivative function.
304 * Can be overridden in derived classes.
305 */
306 virtual void assemble_qoi_derivative (const QoISet & qoi_indices = QoISet(),
307 bool include_liftfunc = true,
308 bool apply_constraints = true);
309
310 /**
311 * Calls residual parameter derivative function.
312 *
313 * Library subclasses use finite differences by default.
314 *
315 * This should assemble the sensitivity rhs vectors to hold
316 * -(partial R / partial p_i), making them ready to solve
317 * the forward sensitivity equation.
318 *
319 * This method is only implemented in some derived classes.
320 */
321 virtual void assemble_residual_derivatives (const ParameterVector & parameters);
322
323 /**
324 * After calling this method, any solve will be restricted to the
325 * given subdomain. To disable this mode, call this method with \p
326 * subset being a \p nullptr.
327 */
328 virtual void restrict_solve_to (const SystemSubset * subset,
329 const SubsetSolveMode subset_solve_mode=SUBSET_ZERO);
330
331 /**
332 * Solves the system. Should be overridden in derived systems.
333 */
solve()334 virtual void solve () {}
335
336 /**
337 * Solves the sensitivity system, for the provided parameters.
338 * Must be overridden in derived systems.
339 *
340 * \returns A pair with the total number of linear iterations
341 * performed and the (sum of the) final residual norms
342 *
343 * This method is only implemented in some derived classes.
344 */
345 virtual std::pair<unsigned int, Real>
346 sensitivity_solve (const ParameterVector & parameters);
347
348 /**
349 * Assembles & solves the linear system(s) (dR/du)*u_w = sum(w_p*-dR/dp), for
350 * those parameters p contained within \p parameters weighted by the
351 * values w_p found within \p weights.
352 *
353 * \returns A pair with the total number of linear iterations
354 * performed and the (sum of the) final residual norms
355 *
356 * This method is only implemented in some derived classes.
357 */
358 virtual std::pair<unsigned int, Real>
359 weighted_sensitivity_solve (const ParameterVector & parameters,
360 const ParameterVector & weights);
361
362 /**
363 * Solves the adjoint system, for the specified qoi indices, or for
364 * every qoi if \p qoi_indices is nullptr. Must be overridden in
365 * derived systems.
366 *
367 * \returns A pair with the total number of linear iterations
368 * performed and the (sum of the) final residual norms
369 *
370 * This method is only implemented in some derived classes.
371 */
372 virtual std::pair<unsigned int, Real>
373 adjoint_solve (const QoISet & qoi_indices = QoISet());
374
375 /**
376 * Assembles & solves the linear system(s)
377 * (dR/du)^T*z_w = sum(w_p*(d^2q/dudp - d^2R/dudp*z)), for those
378 * parameters p contained within \p parameters, weighted by the
379 * values w_p found within \p weights.
380 *
381 * Assumes that adjoint_solve has already calculated z for each qoi
382 * in \p qoi_indices.
383 *
384 * \returns A pair with the total number of linear iterations
385 * performed and the (sum of the) final residual norms
386 *
387 * This method is only implemented in some derived classes.
388 */
389 virtual std::pair<unsigned int, Real>
390 weighted_sensitivity_adjoint_solve (const ParameterVector & parameters,
391 const ParameterVector & weights,
392 const QoISet & qoi_indices = QoISet());
393 /**
394 * Accessor for the adjoint_already_solved boolean
395 */
is_adjoint_already_solved()396 bool is_adjoint_already_solved() const
397 { return adjoint_already_solved;}
398
399 /**
400 * Setter for the adjoint_already_solved boolean
401 */
set_adjoint_already_solved(bool setting)402 void set_adjoint_already_solved(bool setting)
403 { adjoint_already_solved = setting;}
404
405
406 /**
407 * Solves for the derivative of each of the system's quantities of
408 * interest q in \p qoi[qoi_indices] with respect to each parameter
409 * in \p parameters, placing the result for qoi \p i and parameter
410 * \p j into \p sensitivities[i][j].
411 *
412 * \note \p parameters is a const vector, not a vector-of-const;
413 * parameter values in this vector need to be mutable for finite
414 * differencing to work.
415 *
416 * Automatically chooses the forward method for problems with more
417 * quantities of interest than parameters, or the adjoint method
418 * otherwise.
419 *
420 * This method is only usable in derived classes which override
421 * an implementation.
422 */
423 virtual void qoi_parameter_sensitivity (const QoISet & qoi_indices,
424 const ParameterVector & parameters,
425 SensitivityData & sensitivities);
426
427 /**
428 * Solves for parameter sensitivities using the adjoint method.
429 *
430 * This method is only implemented in some derived classes.
431 */
432 virtual void adjoint_qoi_parameter_sensitivity (const QoISet & qoi_indices,
433 const ParameterVector & parameters,
434 SensitivityData & sensitivities);
435
436 /**
437 * Solves for parameter sensitivities using the forward method.
438 *
439 * This method is only implemented in some derived classes.
440 */
441 virtual void forward_qoi_parameter_sensitivity (const QoISet & qoi_indices,
442 const ParameterVector & parameters,
443 SensitivityData & sensitivities);
444
445 /**
446 * For each of the system's quantities of interest q in
447 * \p qoi[qoi_indices], and for a vector of parameters p, the
448 * parameter sensitivity Hessian H_ij is defined as
449 * H_ij = (d^2 q)/(d p_i d p_j)
450 * This Hessian is the output of this method, where for each q_i,
451 * H_jk is stored in \p hessian.second_derivative(i,j,k).
452 *
453 * This method is only implemented in some derived classes.
454 */
455 virtual void qoi_parameter_hessian(const QoISet & qoi_indices,
456 const ParameterVector & parameters,
457 SensitivityData & hessian);
458
459 /**
460 * For each of the system's quantities of interest q in
461 * \p qoi[qoi_indices], and for a vector of parameters p, the
462 * parameter sensitivity Hessian H_ij is defined as
463 * H_ij = (d^2 q)/(d p_i d p_j)
464 * The Hessian-vector product, for a vector v_k in parameter space, is
465 * S_j = H_jk v_k
466 * This product is the output of this method, where for each q_i,
467 * S_j is stored in \p sensitivities[i][j].
468 *
469 * This method is only implemented in some derived classes.
470 */
471 virtual void qoi_parameter_hessian_vector_product(const QoISet & qoi_indices,
472 const ParameterVector & parameters,
473 const ParameterVector & vector,
474 SensitivityData & product);
475
476 /**
477 * \returns \p true when the other system contains
478 * identical data, up to the given threshold. Outputs
479 * some diagnostic info when \p verbose is set.
480 */
481 virtual bool compare (const System & other_system,
482 const Real threshold,
483 const bool verbose) const;
484
485 /**
486 * \returns The system name.
487 */
488 const std::string & name () const;
489
490 /**
491 * \returns The type of system, helpful in identifying
492 * which system type to use when reading equation system
493 * data from file. Should be overridden in derived classes.
494 */
system_type()495 virtual std::string system_type () const { return "Basic"; }
496
497 /**
498 * Projects arbitrary functions onto the current solution.
499 * The function value \p f and its gradient \p g are
500 * user-provided cloneable functors.
501 * A gradient \p g is only required/used for projecting onto finite
502 * element spaces with continuous derivatives.
503 * If non-default \p Parameters are to be used, they can be provided
504 * in the \p parameters argument.
505 */
506 void project_solution (FunctionBase<Number> * f,
507 FunctionBase<Gradient> * g = nullptr) const;
508
509 /**
510 * Projects arbitrary functions onto the current solution.
511 * The function value \p f and its gradient \p g are
512 * user-provided cloneable functors.
513 * A gradient \p g is only required/used for projecting onto finite
514 * element spaces with continuous derivatives.
515 * If non-default \p Parameters are to be used, they can be provided
516 * in the \p parameters argument.
517 */
518 void project_solution (FEMFunctionBase<Number> * f,
519 FEMFunctionBase<Gradient> * g = nullptr) const;
520
521 /**
522 * Projects arbitrary functions onto the current solution.
523 * The function value \p fptr and its gradient \p gptr are
524 * represented by function pointers.
525 * A gradient \p gptr is only required/used for projecting onto
526 * finite element spaces with continuous derivatives.
527 */
528 typedef Number (*ValueFunctionPointer)(const Point & p,
529 const Parameters & Parameters,
530 const std::string & sys_name,
531 const std::string & unknown_name);
532 typedef Gradient (*GradientFunctionPointer)(const Point & p,
533 const Parameters & parameters,
534 const std::string & sys_name,
535 const std::string & unknown_name);
536 void project_solution (ValueFunctionPointer fptr,
537 GradientFunctionPointer gptr,
538 const Parameters & parameters) const;
539
540 /**
541 * Projects arbitrary functions onto a vector of degree of freedom
542 * values for the current system.
543 * The function value \p f and its gradient \p g are
544 * user-provided cloneable functors.
545 * A gradient \p g is only required/used for projecting onto finite
546 * element spaces with continuous derivatives.
547 * If non-default \p Parameters are to be used, they can be provided
548 * in the \p parameters argument.
549 *
550 * Constrain the new vector using the requested adjoint rather than
551 * primal constraints if is_adjoint is non-negative.
552 */
553 void project_vector (NumericVector<Number> & new_vector,
554 FunctionBase<Number> * f,
555 FunctionBase<Gradient> * g = nullptr,
556 int is_adjoint = -1) const;
557
558 /**
559 * Projects arbitrary functions onto a vector of degree of freedom
560 * values for the current system.
561 * The function value \p f and its gradient \p g are
562 * user-provided cloneable functors.
563 * A gradient \p g is only required/used for projecting onto finite
564 * element spaces with continuous derivatives.
565 * If non-default \p Parameters are to be used, they can be provided
566 * in the \p parameters argument.
567 *
568 * Constrain the new vector using the requested adjoint rather than
569 * primal constraints if is_adjoint is non-negative.
570 */
571 void project_vector (NumericVector<Number> & new_vector,
572 FEMFunctionBase<Number> * f,
573 FEMFunctionBase<Gradient> * g = nullptr,
574 int is_adjoint = -1) const;
575
576 /**
577 * Projects arbitrary functions onto a vector of degree of freedom
578 * values for the current system.
579 * The function value \p fptr and its gradient \p gptr are
580 * represented by function pointers.
581 * A gradient \p gptr is only required/used for projecting onto
582 * finite element spaces with continuous derivatives.
583 *
584 * Constrain the new vector using the requested adjoint rather than
585 * primal constraints if is_adjoint is non-negative.
586 */
587 void project_vector (ValueFunctionPointer fptr,
588 GradientFunctionPointer gptr,
589 const Parameters & parameters,
590 NumericVector<Number> & new_vector,
591 int is_adjoint = -1) const;
592
593 /**
594 * Projects arbitrary boundary functions onto a vector of degree of
595 * freedom values for the current system.
596 * Only degrees of freedom which affect the function's trace on a
597 * boundary in the set \p b are affected.
598 * Only degrees of freedom associated with the variables listed in
599 * the vector \p variables are projected.
600 * The function value \p f and its gradient \p g are
601 * user-provided cloneable functors.
602 * A gradient \p g is only required/used for projecting onto finite
603 * element spaces with continuous derivatives.
604 * If non-default \p Parameters are to be used, they can be provided
605 * in the \p parameters argument.
606 */
607 void boundary_project_solution (const std::set<boundary_id_type> & b,
608 const std::vector<unsigned int> & variables,
609 FunctionBase<Number> * f,
610 FunctionBase<Gradient> * g = nullptr);
611
612 /**
613 * Projects arbitrary boundary functions onto a vector of degree of
614 * freedom values for the current system.
615 * Only degrees of freedom which affect the function's trace on a
616 * boundary in the set \p b are affected.
617 * Only degrees of freedom associated with the variables listed in
618 * the vector \p variables are projected.
619 * The function value \p fptr and its gradient \p gptr are
620 * represented by function pointers.
621 * A gradient \p gptr is only required/used for projecting onto
622 * finite element spaces with continuous derivatives.
623 */
624 void boundary_project_solution (const std::set<boundary_id_type> & b,
625 const std::vector<unsigned int> & variables,
626 ValueFunctionPointer fptr,
627 GradientFunctionPointer gptr,
628 const Parameters & parameters);
629
630 /**
631 * Projects arbitrary boundary functions onto a vector of degree of
632 * freedom values for the current system.
633 * Only degrees of freedom which affect the function's trace on a
634 * boundary in the set \p b are affected.
635 * Only degrees of freedom associated with the variables listed in
636 * the vector \p variables are projected.
637 * The function value \p f and its gradient \p g are
638 * user-provided cloneable functors.
639 * A gradient \p g is only required/used for projecting onto finite
640 * element spaces with continuous derivatives.
641 * If non-default \p Parameters are to be used, they can be provided
642 * in the \p parameters argument.
643 *
644 * Constrain the new vector using the requested adjoint rather than
645 * primal constraints if is_adjoint is non-negative.
646 */
647 void boundary_project_vector (const std::set<boundary_id_type> & b,
648 const std::vector<unsigned int> & variables,
649 NumericVector<Number> & new_vector,
650 FunctionBase<Number> * f,
651 FunctionBase<Gradient> * g = nullptr,
652 int is_adjoint = -1) const;
653
654 /**
655 * Projects arbitrary boundary functions onto a vector of degree of
656 * freedom values for the current system.
657 * Only degrees of freedom which affect the function's trace on a
658 * boundary in the set \p b are affected.
659 * Only degrees of freedom associated with the variables listed in
660 * the vector \p variables are projected.
661 * The function value \p fptr and its gradient \p gptr are
662 * represented by function pointers.
663 * A gradient \p gptr is only required/used for projecting onto
664 * finite element spaces with continuous derivatives.
665 *
666 * Constrain the new vector using the requested adjoint rather than
667 * primal constraints if is_adjoint is non-negative.
668 */
669 void boundary_project_vector (const std::set<boundary_id_type> & b,
670 const std::vector<unsigned int> & variables,
671 ValueFunctionPointer fptr,
672 GradientFunctionPointer gptr,
673 const Parameters & parameters,
674 NumericVector<Number> & new_vector,
675 int is_adjoint = -1) const;
676
677 /**
678 * \returns The system number.
679 */
680 unsigned int number () const;
681
682 /**
683 * Fill the input vector \p global_soln so that it contains
684 * the global solution on all processors.
685 * Requires communication with all other processors.
686 */
687 void update_global_solution (std::vector<Number> & global_soln) const;
688
689 /**
690 * Fill the input vector \p global_soln so that it contains
691 * the global solution on processor \p dest_proc.
692 * Requires communication with all other processors.
693 */
694 void update_global_solution (std::vector<Number> & global_soln,
695 const processor_id_type dest_proc) const;
696
697 /**
698 * \returns A constant reference to this systems's \p _mesh.
699 */
700 const MeshBase & get_mesh() const;
701
702 /**
703 * \returns A reference to this systems's \p _mesh.
704 */
705 MeshBase & get_mesh();
706
707 /**
708 * \returns A constant reference to this system's \p _dof_map.
709 */
710 const DofMap & get_dof_map() const;
711
712 /**
713 * \returns A writable reference to this system's \p _dof_map.
714 */
715 DofMap & get_dof_map();
716
717 /**
718 * \returns A constant reference to this system's parent EquationSystems object.
719 */
get_equation_systems()720 const EquationSystems & get_equation_systems() const { return _equation_systems; }
721
722 /**
723 * \returns A reference to this system's parent EquationSystems object.
724 */
get_equation_systems()725 EquationSystems & get_equation_systems() { return _equation_systems; }
726
727 /**
728 * \returns \p true if the system is active, \p false otherwise.
729 * An active system will be solved.
730 */
731 bool active () const;
732
733 /**
734 * Activates the system. Only active systems are solved.
735 */
736 void activate ();
737
738 /**
739 * Deactivates the system. Only active systems are solved.
740 */
741 void deactivate ();
742
743 /**
744 * Sets the system to be "basic only": i.e. advanced system
745 * components such as ImplicitSystem matrices may not be
746 * initialized. This is useful for efficiency in certain utility
747 * programs that never use System::solve(). This method must be
748 * called after the System or derived class is created but before it
749 * is initialized; e.g. from within EquationSystems::read()
750 */
751 void set_basic_system_only ();
752
753 /**
754 * Vector iterator typedefs.
755 */
756 typedef std::map<std::string, NumericVector<Number> *>::iterator vectors_iterator;
757 typedef std::map<std::string, NumericVector<Number> *>::const_iterator const_vectors_iterator;
758
759 /**
760 * Beginning of vectors container
761 */
762 vectors_iterator vectors_begin ();
763
764 /**
765 * Beginning of vectors container
766 */
767 const_vectors_iterator vectors_begin () const;
768
769 /**
770 * End of vectors container
771 */
772 vectors_iterator vectors_end ();
773
774 /**
775 * End of vectors container
776 */
777 const_vectors_iterator vectors_end () const;
778
779 /**
780 * Adds the additional vector \p vec_name to this system. All the
781 * additional vectors are similarly distributed, like the \p
782 * solution, and initialized to zero.
783 *
784 * By default vectors added by add_vector are projected to changed grids by
785 * reinit(). To zero them instead (more efficient), pass "false" as the
786 * second argument
787 */
788 NumericVector<Number> & add_vector (const std::string & vec_name,
789 const bool projections=true,
790 const ParallelType type = PARALLEL);
791
792 /**
793 * Removes the additional vector \p vec_name from this system
794 */
795 void remove_vector(const std::string & vec_name);
796
797 /**
798 * Tells the System whether or not to project the solution vector onto new
799 * grids when the system is reinitialized. The solution will be projected
800 * unless project_solution_on_reinit() = false is called.
801 */
project_solution_on_reinit(void)802 bool & project_solution_on_reinit (void)
803 { return _solution_projection; }
804
805 /**
806 * \returns \p true if this \p System has a vector associated with the
807 * given name, \p false otherwise.
808 */
809 bool have_vector (const std::string & vec_name) const;
810
811 /**
812 * \returns A const pointer to the vector if this \p System has a
813 * vector associated with the given name, \p nullptr otherwise.
814 */
815 const NumericVector<Number> * request_vector (const std::string & vec_name) const;
816
817 /**
818 * \returns A pointer to the vector if this \p System has a
819 * vector associated with the given name, \p nullptr otherwise.
820 */
821 NumericVector<Number> * request_vector (const std::string & vec_name);
822
823 /**
824 * \returns A const pointer to this system's additional vector
825 * number \p vec_num (where the vectors are counted starting with
826 * 0), or \p nullptr if the system has no such vector.
827 */
828 const NumericVector<Number> * request_vector (const unsigned int vec_num) const;
829
830 /**
831 * \returns A writable pointer to this system's additional
832 * vector number \p vec_num (where the vectors are counted starting
833 * with 0), or \p nullptr if the system has no such vector.
834 */
835 NumericVector<Number> * request_vector (const unsigned int vec_num);
836
837 /**
838 * \returns A const reference to this system's additional vector
839 * named \p vec_name. Access is only granted when the vector is already
840 * properly initialized.
841 */
842 const NumericVector<Number> & get_vector (const std::string & vec_name) const;
843
844 /**
845 * \returns A writable reference to this system's additional vector
846 * named \p vec_name. Access is only granted when the vector is already
847 * properly initialized.
848 */
849 NumericVector<Number> & get_vector (const std::string & vec_name);
850
851 /**
852 * \returns A const reference to this system's additional vector
853 * number \p vec_num (where the vectors are counted starting with
854 * 0).
855 */
856 const NumericVector<Number> & get_vector (const unsigned int vec_num) const;
857
858 /**
859 * \returns A writable reference to this system's additional
860 * vector number \p vec_num (where the vectors are counted starting
861 * with 0).
862 */
863 NumericVector<Number> & get_vector (const unsigned int vec_num);
864
865 /**
866 * \returns The name of this system's additional vector number \p
867 * vec_num (where the vectors are counted starting with 0).
868 */
869 const std::string & vector_name (const unsigned int vec_num) const;
870
871 /**
872 * \returns The name of a system vector, given a reference to that vector
873 */
874 const std::string & vector_name (const NumericVector<Number> & vec_reference) const;
875
876 /**
877 * Allows one to set the QoI index controlling whether the vector
878 * identified by vec_name represents a solution from the adjoint
879 * (qoi_num >= 0) or primal (qoi_num == -1) space. This becomes
880 * significant if those spaces have differing heterogeneous
881 * Dirichlet constraints.
882 *
883 * qoi_num == -2 can be used to indicate a vector which should not
884 * be affected by constraints during projection operations.
885 */
886 void set_vector_as_adjoint (const std::string & vec_name, int qoi_num);
887
888 /**
889 * \returns The integer describing whether the vector identified by
890 * vec_name represents a solution from an adjoint (non-negative) or
891 * the primal (-1) space.
892 */
893 int vector_is_adjoint (const std::string & vec_name) const;
894
895 /**
896 * Allows one to set the boolean controlling whether the vector
897 * identified by vec_name should be "preserved": projected to new
898 * meshes, saved, etc.
899 */
900 void set_vector_preservation (const std::string & vec_name, bool preserve);
901
902 /**
903 * \returns The boolean describing whether the vector identified by
904 * vec_name should be "preserved": projected to new meshes, saved,
905 * etc.
906 */
907 bool vector_preservation (const std::string & vec_name) const;
908
909 /**
910 * \returns A reference to one of the system's adjoint solution
911 * vectors, by default the one corresponding to the first qoi.
912 * Creates the vector if it doesn't already exist.
913 */
914 NumericVector<Number> & add_adjoint_solution(unsigned int i=0);
915
916 /**
917 * \returns A reference to one of the system's adjoint solution
918 * vectors, by default the one corresponding to the first qoi.
919 */
920 NumericVector<Number> & get_adjoint_solution(unsigned int i=0);
921
922 /**
923 * \returns A reference to one of the system's adjoint solution
924 * vectors, by default the one corresponding to the first qoi.
925 */
926 const NumericVector<Number> & get_adjoint_solution(unsigned int i=0) const;
927
928 /**
929 * \returns A reference to one of the system's solution sensitivity
930 * vectors, by default the one corresponding to the first parameter.
931 * Creates the vector if it doesn't already exist.
932 */
933 NumericVector<Number> & add_sensitivity_solution(unsigned int i=0);
934
935 /**
936 * \returns A reference to one of the system's solution sensitivity
937 * vectors, by default the one corresponding to the first parameter.
938 */
939 NumericVector<Number> & get_sensitivity_solution(unsigned int i=0);
940
941 /**
942 * \returns A reference to one of the system's solution sensitivity
943 * vectors, by default the one corresponding to the first parameter.
944 */
945 const NumericVector<Number> & get_sensitivity_solution(unsigned int i=0) const;
946
947 /**
948 * \returns A reference to one of the system's weighted sensitivity
949 * adjoint solution vectors, by default the one corresponding to the
950 * first qoi.
951 * Creates the vector if it doesn't already exist.
952 */
953 NumericVector<Number> & add_weighted_sensitivity_adjoint_solution(unsigned int i=0);
954
955 /**
956 * \returns A reference to one of the system's weighted sensitivity
957 * adjoint solution vectors, by default the one corresponding to the
958 * first qoi.
959 */
960 NumericVector<Number> & get_weighted_sensitivity_adjoint_solution(unsigned int i=0);
961
962 /**
963 * \returns A reference to one of the system's weighted sensitivity
964 * adjoint solution vectors, by default the one corresponding to the
965 * first qoi.
966 */
967 const NumericVector<Number> & get_weighted_sensitivity_adjoint_solution(unsigned int i=0) const;
968
969 /**
970 * \returns A reference to the solution of the last weighted
971 * sensitivity solve
972 * Creates the vector if it doesn't already exist.
973 */
974 NumericVector<Number> & add_weighted_sensitivity_solution();
975
976 /**
977 * \returns A reference to the solution of the last weighted
978 * sensitivity solve
979 */
980 NumericVector<Number> & get_weighted_sensitivity_solution();
981
982 /**
983 * \returns A reference to the solution of the last weighted
984 * sensitivity solve
985 */
986 const NumericVector<Number> & get_weighted_sensitivity_solution() const;
987
988 /**
989 * \returns A reference to one of the system's adjoint rhs
990 * vectors, by default the one corresponding to the first qoi.
991 * Creates the vector if it doesn't already exist.
992 */
993 NumericVector<Number> & add_adjoint_rhs(unsigned int i=0);
994
995 /**
996 * \returns A reference to one of the system's adjoint rhs
997 * vectors, by default the one corresponding to the first qoi.
998 * This what the user's QoI derivative code should assemble
999 * when setting up an adjoint problem
1000 */
1001 NumericVector<Number> & get_adjoint_rhs(unsigned int i=0);
1002
1003 /**
1004 * \returns A reference to one of the system's adjoint rhs
1005 * vectors, by default the one corresponding to the first qoi.
1006 */
1007 const NumericVector<Number> & get_adjoint_rhs(unsigned int i=0) const;
1008
1009 /**
1010 * \returns A reference to one of the system's sensitivity rhs
1011 * vectors, by default the one corresponding to the first parameter.
1012 * Creates the vector if it doesn't already exist.
1013 */
1014 NumericVector<Number> & add_sensitivity_rhs(unsigned int i=0);
1015
1016 /**
1017 * \returns A reference to one of the system's sensitivity rhs
1018 * vectors, by default the one corresponding to the first parameter.
1019 * By default these vectors are built by the library, using finite
1020 * differences, when \p assemble_residual_derivatives() is called.
1021 *
1022 * When assembled, this vector should hold
1023 * -(partial R / partial p_i)
1024 */
1025 NumericVector<Number> & get_sensitivity_rhs(unsigned int i=0);
1026
1027 /**
1028 * \returns A reference to one of the system's sensitivity rhs
1029 * vectors, by default the one corresponding to the first parameter.
1030 */
1031 const NumericVector<Number> & get_sensitivity_rhs(unsigned int i=0) const;
1032
1033 /**
1034 * \returns The number of vectors (in addition to the solution)
1035 * handled by this system
1036 * This is the size of the \p _vectors map
1037 */
1038 unsigned int n_vectors () const;
1039
1040 /**
1041 * \returns The number of matrices
1042 * handled by this system.
1043 *
1044 * This will return 0 by default but can be overridden.
1045 */
1046 virtual unsigned int n_matrices () const;
1047
1048 /**
1049 * \returns The number of variables in the system
1050 */
1051 unsigned int n_vars() const;
1052
1053 /**
1054 * \returns The number of \p VariableGroup variable groups in the system
1055 */
1056 unsigned int n_variable_groups() const;
1057
1058 /**
1059 * \returns The total number of scalar components in the system's
1060 * variables. This will equal \p n_vars() in the case of all
1061 * scalar-valued variables.
1062 */
1063 unsigned int n_components() const;
1064
1065 /**
1066 * \returns The number of degrees of freedom in the system
1067 */
1068 dof_id_type n_dofs() const;
1069
1070 /**
1071 * \returns The number of active degrees of freedom
1072 * for this System.
1073 */
1074 dof_id_type n_active_dofs() const;
1075
1076 /**
1077 * \returns The total number of constrained degrees of freedom
1078 * in the system.
1079 */
1080 dof_id_type n_constrained_dofs() const;
1081
1082 /**
1083 * \returns The number of constrained degrees of freedom
1084 * on this processor.
1085 */
1086 dof_id_type n_local_constrained_dofs() const;
1087
1088 /**
1089 * \returns The number of degrees of freedom local
1090 * to this processor
1091 */
1092 dof_id_type n_local_dofs() const;
1093
1094 /**
1095 * Adds the variable \p var to the list of variables
1096 * for this system. If \p active_subdomains is either \p nullptr
1097 * (the default) or points to an empty set, then it will be assumed that
1098 * \p var has no subdomain restrictions
1099 *
1100 * \returns The index number for the new variable.
1101 */
1102 unsigned int add_variable (const std::string & var,
1103 const FEType & type,
1104 const std::set<subdomain_id_type> * const active_subdomains = nullptr);
1105
1106 /**
1107 * Adds the variable \p var to the list of variables
1108 * for this system. Same as before, but assumes \p LAGRANGE
1109 * as default value for \p FEType.family. If \p active_subdomains is either
1110 * \p nullptr (the default) or points to an empty set, then it will be assumed
1111 * that \p var has no subdomain restrictions
1112 */
1113 unsigned int add_variable (const std::string & var,
1114 const Order order = FIRST,
1115 const FEFamily = LAGRANGE,
1116 const std::set<subdomain_id_type> * const active_subdomains = nullptr);
1117
1118 /**
1119 * Adds the variable \p var to the list of variables
1120 * for this system. If \p active_subdomains is either \p nullptr
1121 * (the default) or points to an empty set, then it will be assumed that
1122 * \p var has no subdomain restrictions
1123 *
1124 * \returns The index number for the new variable.
1125 */
1126 unsigned int add_variables (const std::vector<std::string> & vars,
1127 const FEType & type,
1128 const std::set<subdomain_id_type> * const active_subdomains = nullptr);
1129
1130 /**
1131 * Adds the variable \p var to the list of variables
1132 * for this system. Same as before, but assumes \p LAGRANGE
1133 * as default value for \p FEType.family. If \p active_subdomains is either
1134 * \p nullptr (the default) or points to an empty set, then it will be assumed that
1135 * \p var has no subdomain restrictions
1136 */
1137 unsigned int add_variables (const std::vector<std::string> & vars,
1138 const Order order = FIRST,
1139 const FEFamily = LAGRANGE,
1140 const std::set<subdomain_id_type> * const active_subdomains = nullptr);
1141
1142 /**
1143 * Return a constant reference to \p Variable \p var.
1144 */
1145 const Variable & variable (unsigned int var) const;
1146
1147 /**
1148 * Return a constant reference to \p VariableGroup \p vg.
1149 */
1150 const VariableGroup & variable_group (unsigned int vg) const;
1151
1152 /**
1153 * \returns \p true if a variable named \p var exists in this System
1154 */
1155 bool has_variable(const std::string & var) const;
1156
1157 /**
1158 * \returns The name of variable \p i.
1159 */
1160 const std::string & variable_name(const unsigned int i) const;
1161
1162 /**
1163 * \returns The variable number associated with
1164 * the user-specified variable named \p var.
1165 */
1166 unsigned short int variable_number (const std::string & var) const;
1167
1168 /**
1169 * Fills \p all_variable_numbers with all the variable numbers for the
1170 * variables that have been added to this system.
1171 */
1172 void get_all_variable_numbers(std::vector<unsigned int> & all_variable_numbers) const;
1173
1174 /**
1175 * \returns An index, starting from 0 for the first component of the
1176 * first variable, and incrementing for each component of each
1177 * (potentially vector-valued) variable in the system in order.
1178 * For systems with only scalar-valued variables, this will be the
1179 * same as \p variable_number(var)
1180 *
1181 * Irony: currently our only non-scalar-valued variable type is
1182 * SCALAR.
1183 */
1184 unsigned int variable_scalar_number (const std::string & var,
1185 unsigned int component) const;
1186
1187 /**
1188 * \returns An index, starting from 0 for the first component of the
1189 * first variable, and incrementing for each component of each
1190 * (potentially vector-valued) variable in the system in order.
1191 * For systems with only scalar-valued variables, this will be the
1192 * same as \p var_num
1193 *
1194 * Irony: currently our only non-scalar-valued variable type is
1195 * SCALAR.
1196 */
1197 unsigned int variable_scalar_number (unsigned int var_num,
1198 unsigned int component) const;
1199
1200
1201 /**
1202 * \returns The finite element type variable number \p i.
1203 */
1204 const FEType & variable_type (const unsigned int i) const;
1205
1206 /**
1207 * \returns The finite element type for variable \p var.
1208 */
1209 const FEType & variable_type (const std::string & var) const;
1210
1211 /**
1212 * \returns \p true when \p VariableGroup structures should be
1213 * automatically identified, \p false otherwise.
1214 */
1215 bool identify_variable_groups () const;
1216
1217 /**
1218 * Toggle automatic \p VariableGroup identification.
1219 */
1220 void identify_variable_groups (const bool);
1221
1222 /**
1223 * \returns A norm of variable \p var in the vector \p v, in the specified
1224 * norm (e.g. L2, L_INF, H1)
1225 */
1226 Real calculate_norm(const NumericVector<Number> & v,
1227 unsigned int var,
1228 FEMNormType norm_type,
1229 std::set<unsigned int> * skip_dimensions=nullptr) const;
1230
1231 /**
1232 * \returns A norm of the vector \p v, using \p component_norm and \p
1233 * component_scale to choose and weight the norms of each variable.
1234 */
1235 Real calculate_norm(const NumericVector<Number> & v,
1236 const SystemNorm & norm,
1237 std::set<unsigned int> * skip_dimensions=nullptr) const;
1238
1239 /**
1240 * Reads the basic data header for this System.
1241 */
1242 void read_header (Xdr & io,
1243 const std::string & version,
1244 const bool read_header=true,
1245 const bool read_additional_data=true,
1246 const bool read_legacy_format=false);
1247
1248 /**
1249 * Reads additional data, namely vectors, for this System.
1250 *
1251 * \deprecated The ability to read XDR data files in the old (aka
1252 * "legacy") XDR format has been deprecated for many years, this
1253 * capability may soon disappear altogether.
1254 */
1255 #ifdef LIBMESH_ENABLE_DEPRECATED
1256 void read_legacy_data (Xdr & io,
1257 const bool read_additional_data=true);
1258 #endif
1259
1260 /**
1261 * Reads additional data, namely vectors, for this System.
1262 * This method may safely be called on a distributed-memory mesh.
1263 */
1264 template <typename ValType>
1265 void read_serialized_data (Xdr & io,
1266 const bool read_additional_data=true);
1267 /**
1268 * Non-templated version for backward compatibility.
1269 *
1270 * Reads additional data, namely vectors, for this System.
1271 * This method may safely be called on a distributed-memory mesh.
1272 */
1273 void read_serialized_data (Xdr & io,
1274 const bool read_additional_data=true)
1275 { read_serialized_data<Number>(io, read_additional_data); }
1276
1277 /**
1278 * Read a number of identically distributed vectors. This method
1279 * allows for optimization for the multiple vector case by only communicating
1280 * the metadata once.
1281 */
1282 template <typename InValType>
1283 std::size_t read_serialized_vectors (Xdr & io,
1284 const std::vector<NumericVector<Number> *> & vectors) const;
1285
1286 /**
1287 * Non-templated version for backward compatibility.
1288 *
1289 * Read a number of identically distributed vectors. This method
1290 * allows for optimization for the multiple vector case by only communicating
1291 * the metadata once.
1292 */
read_serialized_vectors(Xdr & io,const std::vector<NumericVector<Number> * > & vectors)1293 std::size_t read_serialized_vectors (Xdr & io,
1294 const std::vector<NumericVector<Number> *> & vectors) const
1295 { return read_serialized_vectors<Number>(io, vectors); }
1296
1297 /**
1298 * Reads additional data, namely vectors, for this System.
1299 * This method may safely be called on a distributed-memory mesh.
1300 * This method will read an individual file for each processor in the simulation
1301 * where the local solution components for that processor are stored.
1302 */
1303 template <typename InValType>
1304 void read_parallel_data (Xdr & io,
1305 const bool read_additional_data);
1306
1307 /**
1308 * Non-templated version for backward compatibility.
1309 *
1310 * Reads additional data, namely vectors, for this System.
1311 * This method may safely be called on a distributed-memory mesh.
1312 * This method will read an individual file for each processor in the simulation
1313 * where the local solution components for that processor are stored.
1314 */
read_parallel_data(Xdr & io,const bool read_additional_data)1315 void read_parallel_data (Xdr & io,
1316 const bool read_additional_data)
1317 { read_parallel_data<Number>(io, read_additional_data); }
1318
1319 /**
1320 * Writes the basic data header for this System.
1321 */
1322 void write_header (Xdr & io,
1323 const std::string & version,
1324 const bool write_additional_data) const;
1325
1326 /**
1327 * Writes additional data, namely vectors, for this System.
1328 * This method may safely be called on a distributed-memory mesh.
1329 */
1330 void write_serialized_data (Xdr & io,
1331 const bool write_additional_data = true) const;
1332
1333 /**
1334 * Serialize & write a number of identically distributed vectors. This method
1335 * allows for optimization for the multiple vector case by only communicating
1336 * the metadata once.
1337 */
1338 std::size_t write_serialized_vectors (Xdr & io,
1339 const std::vector<const NumericVector<Number> *> & vectors) const;
1340
1341 /**
1342 * Writes additional data, namely vectors, for this System.
1343 * This method may safely be called on a distributed-memory mesh.
1344 * This method will create an individual file for each processor in the simulation
1345 * where the local solution components for that processor will be stored.
1346 */
1347 void write_parallel_data (Xdr & io,
1348 const bool write_additional_data) const;
1349
1350 /**
1351 * \returns A string containing information about the
1352 * system.
1353 */
1354 std::string get_info () const;
1355
1356 /**
1357 * Register a user function to use in initializing the system.
1358 */
1359 void attach_init_function (void fptr(EquationSystems & es,
1360 const std::string & name));
1361
1362 /**
1363 * Register a user class to use to initialize the system.
1364 *
1365 * \note This is exclusive with the \p attach_init_function.
1366 */
1367 void attach_init_object (Initialization & init);
1368
1369 /**
1370 * Register a user function to use in assembling the system
1371 * matrix and RHS.
1372 */
1373 void attach_assemble_function (void fptr(EquationSystems & es,
1374 const std::string & name));
1375
1376 /**
1377 * Register a user object to use in assembling the system
1378 * matrix and RHS.
1379 */
1380 void attach_assemble_object (Assembly & assemble);
1381
1382 /**
1383 * Register a user function for imposing constraints.
1384 */
1385 void attach_constraint_function (void fptr(EquationSystems & es,
1386 const std::string & name));
1387
1388 /**
1389 * Register a user object for imposing constraints.
1390 */
1391 void attach_constraint_object (Constraint & constrain);
1392
1393 /**
1394 * Register a user function for evaluating the quantities of interest,
1395 * whose values should be placed in \p System::qoi
1396 */
1397 void attach_QOI_function (void fptr(EquationSystems & es,
1398 const std::string & name,
1399 const QoISet & qoi_indices));
1400
1401 /**
1402 * Register a user object for evaluating the quantities of interest,
1403 * whose values should be placed in \p System::qoi
1404 */
1405 void attach_QOI_object (QOI & qoi);
1406
1407 /**
1408 * Register a user function for evaluating derivatives of a quantity
1409 * of interest with respect to test functions, whose values should
1410 * be placed in \p System::rhs
1411 */
1412 void attach_QOI_derivative (void fptr(EquationSystems & es,
1413 const std::string & name,
1414 const QoISet & qoi_indices,
1415 bool include_liftfunc,
1416 bool apply_constraints));
1417
1418 /**
1419 * Register a user object for evaluating derivatives of a quantity
1420 * of interest with respect to test functions, whose values should
1421 * be placed in \p System::rhs
1422 */
1423 void attach_QOI_derivative_object (QOIDerivative & qoi_derivative);
1424
1425 /**
1426 * Calls user's attached initialization function, or is overridden by
1427 * the user in derived classes.
1428 */
1429 virtual void user_initialization ();
1430
1431 /**
1432 * Calls user's attached assembly function, or is overridden by
1433 * the user in derived classes.
1434 */
1435 virtual void user_assembly ();
1436
1437 /**
1438 * Calls user's attached constraint function, or is overridden by
1439 * the user in derived classes.
1440 */
1441 virtual void user_constrain ();
1442
1443 /**
1444 * Calls user's attached quantity of interest function, or is
1445 * overridden by the user in derived classes.
1446 */
1447 virtual void user_QOI (const QoISet & qoi_indices);
1448
1449 /**
1450 * Calls user's attached quantity of interest derivative function,
1451 * or is overridden by the user in derived classes.
1452 */
1453 virtual void user_QOI_derivative (const QoISet & qoi_indices = QoISet(),
1454 bool include_liftfunc = true,
1455 bool apply_constraints = true);
1456
1457 /**
1458 * Re-update the local values when the mesh has changed.
1459 * This method takes the data updated by \p update() and
1460 * makes it up-to-date on the current mesh.
1461 */
1462 virtual void re_update ();
1463
1464 /**
1465 * Restrict vectors after the mesh has coarsened
1466 */
1467 virtual void restrict_vectors ();
1468
1469 /**
1470 * Prolong vectors after the mesh has refined
1471 */
1472 virtual void prolong_vectors ();
1473
1474 /**
1475 * Flag which tells the system to whether or not to
1476 * call the user assembly function during each call to solve().
1477 * By default, every call to solve() begins with a call to the
1478 * user assemble, so this flag is true. (For explicit systems,
1479 * "solving" the system occurs during the assembly step, so this
1480 * flag is always true for explicit systems.)
1481 *
1482 * You will only want to set this to false if you need direct
1483 * control over when the system is assembled, and are willing to
1484 * track the state of its assembly yourself. An example of such a
1485 * case is an implicit system with multiple right hand sides. In
1486 * this instance, a single assembly would likely be followed with
1487 * multiple calls to solve.
1488 *
1489 * The frequency system and Newmark system have their own versions
1490 * of this flag, called _finished_assemble, which might be able to
1491 * be replaced with this more general concept.
1492 */
1493 bool assemble_before_solve;
1494
1495 /**
1496 * Avoids use of any cached data that might affect any solve result. Should
1497 * be overridden in derived systems.
1498 */
1499 virtual void disable_cache ();
1500
1501 /**
1502 * A boolean to be set to true by systems using elem_fixed_solution,
1503 * for optional use by e.g. stabilized methods.
1504 * False by default.
1505 *
1506 * \note For FEMSystem users, if this variable is set to true, it
1507 * must be before init_data() is called.
1508 */
1509 bool use_fixed_solution;
1510
1511 /**
1512 * A member int that can be employed to indicate increased or
1513 * reduced quadrature order.
1514 *
1515 * \note For FEMSystem users, by default, when calling the
1516 * user-defined residual functions, the FEMSystem will first set up
1517 * an appropriate FEType::default_quadrature_rule() object for
1518 * performing the integration. This rule will integrate elements of
1519 * order up to 2*p+1 exactly (where p is the sum of the base FEType
1520 * and local p refinement levels), but if additional (or reduced)
1521 * quadrature accuracy is desired then this extra_quadrature_order
1522 * (default 0) will be added.
1523 */
1524 int extra_quadrature_order;
1525
1526
1527 //--------------------------------------------------
1528 // The solution and solution access members
1529
1530 /**
1531 * \returns The current solution for the specified global
1532 * DOF.
1533 */
1534 Number current_solution (const dof_id_type global_dof_number) const;
1535
1536 /**
1537 * Data structure to hold solution values.
1538 */
1539 std::unique_ptr<NumericVector<Number>> solution;
1540
1541 /**
1542 * All the values I need to compute my contribution
1543 * to the simulation at hand. Think of this as the
1544 * current solution with any ghost values needed from
1545 * other processors. This vector is necessarily larger
1546 * than the \p solution vector in the case of a parallel
1547 * simulation. The \p update() member is used to synchronize
1548 * the contents of the \p solution and \p current_local_solution
1549 * vectors.
1550 */
1551 std::unique_ptr<NumericVector<Number>> current_local_solution;
1552
1553 /**
1554 * For time-dependent problems, this is the time t at the beginning of
1555 * the current timestep.
1556 *
1557 * \note For DifferentiableSystem users: do \e not access this time
1558 * during an assembly! Use the DiffContext::time value instead to
1559 * get correct results.
1560 */
1561 Real time;
1562
1563 /**
1564 * Number of currently active quantities of interest.
1565 */
1566 unsigned int n_qois() const;
1567
1568 /**
1569 * Values of the quantities of interest. This vector needs
1570 * to be both resized and filled by the user before any quantity of
1571 * interest assembly is done and before any sensitivities are
1572 * calculated.
1573 */
1574 std::vector<Number> qoi;
1575
1576 /**
1577 * \returns The value of the solution variable \p var at the physical
1578 * point \p p in the mesh, without knowing a priori which element
1579 * contains \p p, using the degree of freedom coefficients in \p sol
1580 * (or in \p current_local_solution if \p sol is left null).
1581 *
1582 * \note This function uses \p MeshBase::sub_point_locator(); users
1583 * may or may not want to call \p MeshBase::clear_point_locator()
1584 * afterward. Also, point_locator() is expensive (N log N for
1585 * initial construction, log N for evaluations). Avoid using this
1586 * function in any context where you are already looping over
1587 * elements.
1588 *
1589 * Because the element containing \p p may lie on any processor,
1590 * this function is parallel-only.
1591 *
1592 * By default this method expects the point to reside inside the domain
1593 * and will abort if no element can be found which contains \p p. The
1594 * optional parameter \p insist_on_success can be set to false to allow
1595 * the method to return 0 when the point is not located.
1596 */
1597 Number point_value(unsigned int var, const Point & p,
1598 const bool insist_on_success = true,
1599 const NumericVector<Number> * sol = nullptr) const;
1600
1601 /**
1602 * \returns The value of the solution variable \p var at the physical
1603 * point \p p contained in local Elem \p e, using the degree of
1604 * freedom coefficients in \p sol (or in \p current_local_solution
1605 * if \p sol is left null).
1606 *
1607 * This version of point_value can be run in serial, but assumes \p e is in
1608 * the local mesh partition or is algebraically ghosted.
1609 */
1610 Number point_value(unsigned int var, const Point & p, const Elem & e,
1611 const NumericVector<Number> * sol = nullptr) const;
1612
1613 /**
1614 * Calls the version of point_value() which takes a reference.
1615 * This function exists only to prevent people from calling the
1616 * version of point_value() that has a boolean third argument, which
1617 * would result in unnecessary PointLocator calls.
1618 */
1619 Number point_value(unsigned int var, const Point & p, const Elem * e) const;
1620
1621 /**
1622 * Calls the parallel version of point_value().
1623 * This function exists only to prevent people from accidentally
1624 * calling the version of point_value() that has a boolean third
1625 * argument, which would result in incorrect output.
1626 */
1627 Number point_value(unsigned int var, const Point & p, const NumericVector<Number> * sol) const;
1628
1629 /**
1630 * \returns The gradient of the solution variable \p var at the physical
1631 * point \p p in the mesh, similarly to point_value.
1632 */
1633 Gradient point_gradient(unsigned int var, const Point & p,
1634 const bool insist_on_success = true,
1635 const NumericVector<Number> * sol = nullptr) const;
1636
1637 /**
1638 * \returns The gradient of the solution variable \p var at the physical
1639 * point \p p in local Elem \p e in the mesh, similarly to point_value.
1640 */
1641 Gradient point_gradient(unsigned int var, const Point & p, const Elem & e,
1642 const NumericVector<Number> * sol = nullptr) const;
1643
1644 /**
1645 * Calls the version of point_gradient() which takes a reference.
1646 * This function exists only to prevent people from calling the
1647 * version of point_gradient() that has a boolean third argument, which
1648 * would result in unnecessary PointLocator calls.
1649 */
1650 Gradient point_gradient(unsigned int var, const Point & p, const Elem * e) const;
1651
1652 /**
1653 * Calls the parallel version of point_gradient().
1654 * This function exists only to prevent people from accidentally
1655 * calling the version of point_gradient() that has a boolean third
1656 * argument, which would result in incorrect output.
1657 */
1658 Gradient point_gradient(unsigned int var, const Point & p, const NumericVector<Number> * sol) const;
1659
1660 /**
1661 * \returns The second derivative tensor of the solution variable \p var
1662 * at the physical point \p p in the mesh, similarly to point_value.
1663 */
1664 Tensor point_hessian(unsigned int var, const Point & p,
1665 const bool insist_on_success = true,
1666 const NumericVector<Number> * sol = nullptr) const;
1667
1668 /**
1669 * \returns The second derivative tensor of the solution variable \p var
1670 * at the physical point \p p in local Elem \p e in the mesh, similarly to
1671 * point_value.
1672 */
1673 Tensor point_hessian(unsigned int var, const Point & p, const Elem & e,
1674 const NumericVector<Number> * sol = nullptr) const;
1675
1676 /**
1677 * Calls the version of point_hessian() which takes a reference.
1678 * This function exists only to prevent people from calling the
1679 * version of point_hessian() that has a boolean third argument, which
1680 * would result in unnecessary PointLocator calls.
1681 */
1682 Tensor point_hessian(unsigned int var, const Point & p, const Elem * e) const;
1683
1684 /**
1685 * Calls the parallel version of point_hessian().
1686 * This function exists only to prevent people from accidentally
1687 * calling the version of point_hessian() that has a boolean third
1688 * argument, which would result in incorrect output.
1689 */
1690 Tensor point_hessian(unsigned int var, const Point & p, const NumericVector<Number> * sol) const;
1691
1692
1693 /**
1694 * Fills the std::set with the degrees of freedom on the local
1695 * processor corresponding the the variable number passed in.
1696 */
1697 void local_dof_indices (const unsigned int var,
1698 std::set<dof_id_type> & var_indices) const;
1699
1700 /**
1701 * Zeroes all dofs in \p v that correspond to variable number \p
1702 * var_num.
1703 */
1704 void zero_variable (NumericVector<Number> & v, unsigned int var_num) const;
1705
1706 /**
1707 * Setter and getter functions for project_with_constraints boolean
1708 */
get_project_with_constraints()1709 bool get_project_with_constraints()
1710 {
1711 return project_with_constraints;
1712 }
1713
set_project_with_constraints(bool _project_with_constraints)1714 void set_project_with_constraints(bool _project_with_constraints)
1715 {
1716 project_with_constraints = _project_with_constraints;
1717 }
1718
1719 /**
1720 * \returns A writable reference to a boolean that determines if this system
1721 * can be written to file or not. If set to \p true, then
1722 * \p EquationSystems::write will ignore this system.
1723 */
hide_output()1724 bool & hide_output() { return _hide_output; }
1725
1726 #ifdef LIBMESH_HAVE_METAPHYSICL
1727 /**
1728 * This method creates a projection matrix which corresponds to the
1729 * operation of project_vector between old and new solution spaces.
1730 *
1731 * Heterogeneous Dirichlet boundary conditions are *not* taken into
1732 * account here; if this matrix is used for prolongation (mesh
1733 * refinement) on a side with a heterogeneous BC, the newly created
1734 * degrees of freedom on that side will still match the coarse grid
1735 * approximation of the BC, not the fine grid approximation.
1736 */
1737 void projection_matrix (SparseMatrix<Number> & proj_mat) const;
1738 #endif // LIBMESH_HAVE_METAPHYSICL
1739
1740 protected:
1741
1742 /**
1743 * Initializes the data for the system.
1744 *
1745 * \note This is called before any user-supplied initialization
1746 * function so that all required storage will be available.
1747 */
1748 virtual void init_data ();
1749
1750 /**
1751 * Projects the vector defined on the old mesh onto the
1752 * new mesh.
1753 *
1754 * Constrain the new vector using the requested adjoint rather than
1755 * primal constraints if is_adjoint is non-negative.
1756 */
1757 void project_vector (NumericVector<Number> &,
1758 int is_adjoint = -1) const;
1759
1760 /**
1761 * Projects the vector defined on the old mesh onto the
1762 * new mesh. The original vector is unchanged and the new vector
1763 * is passed through the second argument.
1764 *
1765 * Constrain the new vector using the requested adjoint rather than
1766 * primal constraints if is_adjoint is non-negative.
1767 */
1768 void project_vector (const NumericVector<Number> &,
1769 NumericVector<Number> &,
1770 int is_adjoint = -1) const;
1771
1772 private:
1773 /**
1774 * This isn't a copyable object, so let's make sure nobody tries.
1775 *
1776 * We won't even bother implementing this; we'll just make sure that
1777 * the compiler doesn't implement a default.
1778 */
1779 System (const System &);
1780
1781 /**
1782 * This isn't a copyable object, so let's make sure nobody tries.
1783 *
1784 * We won't even bother implementing this; we'll just make sure that
1785 * the compiler doesn't implement a default.
1786 */
1787 System & operator=(const System &);
1788
1789 /**
1790 * Finds the discrete norm for the entries in the vector
1791 * corresponding to Dofs associated with var.
1792 */
1793 Real discrete_var_norm (const NumericVector<Number> & v,
1794 unsigned int var,
1795 FEMNormType norm_type) const;
1796
1797 /**
1798 * Reads an input vector from the stream \p io and assigns
1799 * the values to a set of \p DofObjects. This method uses
1800 * blocked input and is safe to call on a distributed memory-mesh.
1801 * Unless otherwise specified, all variables are read.
1802 *
1803 * If an entry in \p vecs is a null pointer, the corresponding data
1804 * is read (incrementing the file read location) but discarded.
1805 */
1806 template <typename iterator_type, typename InValType>
1807 std::size_t read_serialized_blocked_dof_objects (const dof_id_type n_objects,
1808 const iterator_type begin,
1809 const iterator_type end,
1810 const InValType dummy,
1811 Xdr & io,
1812 const std::vector<NumericVector<Number> *> & vecs,
1813 const unsigned int var_to_read=libMesh::invalid_uint) const;
1814
1815 /**
1816 * Reads the SCALAR dofs from the stream \p io and assigns the values
1817 * to the appropriate entries of \p vec.
1818 *
1819 * \returns The number of dofs read.
1820 *
1821 * Reads data and discards it if \p vec is a null pointer.
1822 */
1823 unsigned int read_SCALAR_dofs (const unsigned int var,
1824 Xdr & io,
1825 NumericVector<Number> * vec) const;
1826
1827 /**
1828 * Reads a vector for this System.
1829 * This method may safely be called on a distributed-memory mesh.
1830 *
1831 * \returns The length of the vector read.
1832 *
1833 * Reads data and discards it if \p vec is a null pointer.
1834 */
1835 template <typename InValType>
1836 numeric_index_type read_serialized_vector (Xdr & io,
1837 NumericVector<Number> * vec);
1838
1839 /**
1840 * Non-templated version for backward compatibility.
1841 *
1842 * Reads a vector for this System.
1843 * This method may safely be called on a distributed-memory mesh.
1844 *
1845 * \returns The length of the vector read.
1846 */
read_serialized_vector(Xdr & io,NumericVector<Number> & vec)1847 numeric_index_type read_serialized_vector (Xdr & io,
1848 NumericVector<Number> & vec)
1849 { return read_serialized_vector<Number>(io, &vec); }
1850
1851 /**
1852 * Writes an output vector to the stream \p io for a set of \p DofObjects.
1853 * This method uses blocked output and is safe to call on a distributed memory-mesh.
1854 *
1855 * \returns The number of values written
1856 */
1857 template <typename iterator_type>
1858 std::size_t write_serialized_blocked_dof_objects (const std::vector<const NumericVector<Number> *> & vecs,
1859 const dof_id_type n_objects,
1860 const iterator_type begin,
1861 const iterator_type end,
1862 Xdr & io,
1863 const unsigned int var_to_write=libMesh::invalid_uint) const;
1864
1865 /**
1866 * Writes the SCALAR dofs associated with var to the stream \p io.
1867 *
1868 * \returns The number of values written.
1869 */
1870 unsigned int write_SCALAR_dofs (const NumericVector<Number> & vec,
1871 const unsigned int var,
1872 Xdr & io) const;
1873
1874 /**
1875 * Writes a vector for this System.
1876 * This method may safely be called on a distributed-memory mesh.
1877 *
1878 * \returns The number of values written.
1879 */
1880 dof_id_type write_serialized_vector (Xdr & io,
1881 const NumericVector<Number> & vec) const;
1882
1883 /**
1884 * Function that initializes the system.
1885 */
1886 void (* _init_system_function) (EquationSystems & es,
1887 const std::string & name);
1888
1889 /**
1890 * Object that initializes the system.
1891 */
1892 Initialization * _init_system_object;
1893
1894 /**
1895 * Function that assembles the system.
1896 */
1897 void (* _assemble_system_function) (EquationSystems & es,
1898 const std::string & name);
1899
1900 /**
1901 * Object that assembles the system.
1902 */
1903 Assembly * _assemble_system_object;
1904
1905 /**
1906 * Function to impose constraints.
1907 */
1908 void (* _constrain_system_function) (EquationSystems & es,
1909 const std::string & name);
1910
1911 /**
1912 * Object that constrains the system.
1913 */
1914 Constraint * _constrain_system_object;
1915
1916 /**
1917 * Function to evaluate quantity of interest
1918 */
1919 void (* _qoi_evaluate_function) (EquationSystems & es,
1920 const std::string & name,
1921 const QoISet & qoi_indices);
1922
1923 /**
1924 * Object to compute quantities of interest.
1925 */
1926 QOI * _qoi_evaluate_object;
1927
1928 /**
1929 * Function to evaluate quantity of interest derivative
1930 */
1931 void (* _qoi_evaluate_derivative_function) (EquationSystems & es,
1932 const std::string & name,
1933 const QoISet & qoi_indices,
1934 bool include_liftfunc,
1935 bool apply_constraints);
1936
1937 /**
1938 * Object to compute derivatives of quantities of interest.
1939 */
1940 QOIDerivative * _qoi_evaluate_derivative_object;
1941
1942 /**
1943 * Data structure describing the relationship between
1944 * nodes, variables, etc... and degrees of freedom.
1945 */
1946 std::unique_ptr<DofMap> _dof_map;
1947
1948 /**
1949 * Constant reference to the \p EquationSystems object
1950 * used for the simulation.
1951 */
1952 EquationSystems & _equation_systems;
1953
1954 /**
1955 * Constant reference to the \p mesh data structure used
1956 * for the simulation.
1957 */
1958 MeshBase & _mesh;
1959
1960 /**
1961 * A name associated with this system.
1962 */
1963 const std::string _sys_name;
1964
1965 /**
1966 * The number associated with this system
1967 */
1968 const unsigned int _sys_number;
1969
1970 /**
1971 * The \p Variable in this \p System.
1972 */
1973 std::vector<Variable> _variables;
1974
1975 /**
1976 * The \p VariableGroup in this \p System.
1977 */
1978 std::vector<VariableGroup> _variable_groups;
1979
1980 /**
1981 * The variable numbers corresponding to user-specified
1982 * names, useful for name-based lookups.
1983 */
1984 std::map<std::string, unsigned short int> _variable_numbers;
1985
1986 /**
1987 * Flag stating if the system is active or not.
1988 */
1989 bool _active;
1990
1991 /**
1992 * Some systems need an arbitrary number of vectors.
1993 * This map allows names to be associated with arbitrary
1994 * vectors. All the vectors in this map will be distributed
1995 * in the same way as the solution vector.
1996 */
1997 std::map<std::string, NumericVector<Number> * > _vectors;
1998
1999 /**
2000 * Holds true if a vector by that name should be projected
2001 * onto a changed grid, false if it should be zeroed.
2002 */
2003 std::map<std::string, bool> _vector_projections;
2004
2005 /**
2006 * Holds non-negative if a vector by that name should be projected
2007 * using adjoint constraints/BCs, -1 if primal
2008 */
2009 std::map<std::string, int> _vector_is_adjoint;
2010
2011 /**
2012 * Holds the type of a vector
2013 */
2014 std::map<std::string, ParallelType> _vector_types;
2015
2016 /**
2017 * Holds true if the solution vector should be projected
2018 * onto a changed grid, false if it should be zeroed.
2019 * This is true by default.
2020 */
2021 bool _solution_projection;
2022
2023 /**
2024 * Holds true if the components of more advanced system types (e.g.
2025 * system matrices) should not be initialized.
2026 */
2027 bool _basic_system_only;
2028
2029 /**
2030 * \p true when additional vectors and variables do not require
2031 * immediate initialization, \p false otherwise.
2032 */
2033 bool _is_initialized;
2034
2035 /**
2036 * \p true when \p VariableGroup structures should be automatically
2037 * identified, \p false otherwise. Defaults to \p true.
2038 */
2039 bool _identify_variable_groups;
2040
2041 /**
2042 * This flag is used only when *reading* in a system from file.
2043 * Based on the system header, it keeps track of how many
2044 * additional vectors were actually written for this file.
2045 */
2046 unsigned int _additional_data_written;
2047
2048 /**
2049 * This vector is used only when *reading* in a system from file.
2050 * Based on the system header, it keeps track of any index remapping
2051 * between variable names in the data file and variable names in the
2052 * already-constructed system. I.e. if we have a system with
2053 * variables "A1", "A2", "B1", and "B2", but we read in a data file with
2054 * only "A1" and "B1" defined, then we don't want to try and read in
2055 * A2 or B2, and we don't want to assign A1 and B1 values to
2056 * different dof indices.
2057 */
2058 std::vector<unsigned int> _written_var_indices;
2059
2060 /**
2061 * Has the adjoint problem already been solved? If the user sets
2062 * \p adjoint_already_solved to \p true, we won't waste time solving
2063 * it again.
2064 */
2065 bool adjoint_already_solved;
2066
2067 /**
2068 * Are we allowed to write this system to file? If \p _hide_output is
2069 * \p true, then \p EquationSystems::write will ignore this system.
2070 */
2071 bool _hide_output;
2072
2073 /**
2074 * Do we want to apply constraints while projecting vectors ?
2075 */
2076 bool project_with_constraints;
2077 };
2078
2079
2080
2081 // ------------------------------------------------------------
2082 // System inline methods
2083 inline
name()2084 const std::string & System::name() const
2085 {
2086 return _sys_name;
2087 }
2088
2089
2090
2091 inline
number()2092 unsigned int System::number() const
2093 {
2094 return _sys_number;
2095 }
2096
2097
2098
2099 inline
get_mesh()2100 const MeshBase & System::get_mesh() const
2101 {
2102 return _mesh;
2103 }
2104
2105
2106
2107 inline
get_mesh()2108 MeshBase & System::get_mesh()
2109 {
2110 return _mesh;
2111 }
2112
2113
2114
2115 inline
get_dof_map()2116 const DofMap & System::get_dof_map() const
2117 {
2118 return *_dof_map;
2119 }
2120
2121
2122
2123 inline
get_dof_map()2124 DofMap & System::get_dof_map()
2125 {
2126 return *_dof_map;
2127 }
2128
2129
2130
2131 inline
active()2132 bool System::active() const
2133 {
2134 return _active;
2135 }
2136
2137
2138
2139 inline
activate()2140 void System::activate ()
2141 {
2142 _active = true;
2143 }
2144
2145
2146
2147 inline
deactivate()2148 void System::deactivate ()
2149 {
2150 _active = false;
2151 }
2152
2153
2154
2155 inline
is_initialized()2156 bool System::is_initialized ()
2157 {
2158 return _is_initialized;
2159 }
2160
2161
2162
2163 inline
set_basic_system_only()2164 void System::set_basic_system_only ()
2165 {
2166 _basic_system_only = true;
2167 }
2168
2169
2170
2171 inline
n_vars()2172 unsigned int System::n_vars() const
2173 {
2174 return cast_int<unsigned int>(_variables.size());
2175 }
2176
2177
2178
2179 inline
n_variable_groups()2180 unsigned int System::n_variable_groups() const
2181 {
2182 return cast_int<unsigned int>(_variable_groups.size());
2183 }
2184
2185
2186
2187 inline
n_components()2188 unsigned int System::n_components() const
2189 {
2190 if (_variables.empty())
2191 return 0;
2192
2193 const Variable & last = _variables.back();
2194 return last.first_scalar_number() + last.n_components();
2195 }
2196
2197
2198
2199 inline
variable(const unsigned int i)2200 const Variable & System::variable (const unsigned int i) const
2201 {
2202 libmesh_assert_less (i, _variables.size());
2203
2204 return _variables[i];
2205 }
2206
2207
2208
2209 inline
variable_group(const unsigned int vg)2210 const VariableGroup & System::variable_group (const unsigned int vg) const
2211 {
2212 libmesh_assert_less (vg, _variable_groups.size());
2213
2214 return _variable_groups[vg];
2215 }
2216
2217
2218
2219 inline
variable_name(const unsigned int i)2220 const std::string & System::variable_name (const unsigned int i) const
2221 {
2222 libmesh_assert_less (i, _variables.size());
2223
2224 return _variables[i].name();
2225 }
2226
2227
2228
2229 inline
2230 unsigned int
variable_scalar_number(const std::string & var,unsigned int component)2231 System::variable_scalar_number (const std::string & var,
2232 unsigned int component) const
2233 {
2234 return variable_scalar_number(this->variable_number(var), component);
2235 }
2236
2237
2238
2239 inline
2240 unsigned int
variable_scalar_number(unsigned int var_num,unsigned int component)2241 System::variable_scalar_number (unsigned int var_num,
2242 unsigned int component) const
2243 {
2244 return _variables[var_num].first_scalar_number() + component;
2245 }
2246
2247
2248
2249 inline
variable_type(const unsigned int i)2250 const FEType & System::variable_type (const unsigned int i) const
2251 {
2252 libmesh_assert_less (i, _variables.size());
2253
2254 return _variables[i].type();
2255 }
2256
2257
2258
2259 inline
variable_type(const std::string & var)2260 const FEType & System::variable_type (const std::string & var) const
2261 {
2262 return _variables[this->variable_number(var)].type();
2263 }
2264
2265
2266
2267 inline
identify_variable_groups()2268 bool System::identify_variable_groups () const
2269 {
2270 return _identify_variable_groups;
2271 }
2272
2273
2274
2275 inline
identify_variable_groups(const bool ivg)2276 void System::identify_variable_groups (const bool ivg)
2277 {
2278 _identify_variable_groups = ivg;
2279 }
2280
2281
2282
2283 inline
n_active_dofs()2284 dof_id_type System::n_active_dofs() const
2285 {
2286 return this->n_dofs() - this->n_constrained_dofs();
2287 }
2288
2289
2290
2291 inline
have_vector(const std::string & vec_name)2292 bool System::have_vector (const std::string & vec_name) const
2293 {
2294 return (_vectors.count(vec_name));
2295 }
2296
2297
2298
2299 inline
n_vectors()2300 unsigned int System::n_vectors () const
2301 {
2302 return cast_int<unsigned int>(_vectors.size());
2303 }
2304
2305 inline
n_matrices()2306 unsigned int System::n_matrices () const
2307 {
2308 return 0;
2309 }
2310
2311 inline
vectors_begin()2312 System::vectors_iterator System::vectors_begin ()
2313 {
2314 return _vectors.begin();
2315 }
2316
2317 inline
vectors_begin()2318 System::const_vectors_iterator System::vectors_begin () const
2319 {
2320 return _vectors.begin();
2321 }
2322
2323 inline
vectors_end()2324 System::vectors_iterator System::vectors_end ()
2325 {
2326 return _vectors.end();
2327 }
2328
2329 inline
vectors_end()2330 System::const_vectors_iterator System::vectors_end () const
2331 {
2332 return _vectors.end();
2333 }
2334
2335 inline
assemble_residual_derivatives(const ParameterVector &)2336 void System::assemble_residual_derivatives (const ParameterVector &)
2337 {
2338 libmesh_not_implemented();
2339 }
2340
2341 inline
disable_cache()2342 void System::disable_cache () { assemble_before_solve = true; }
2343
2344 inline
n_qois()2345 unsigned int System::n_qois() const
2346 {
2347 return cast_int<unsigned int>(this->qoi.size());
2348 }
2349
2350 inline
2351 std::pair<unsigned int, Real>
sensitivity_solve(const ParameterVector &)2352 System::sensitivity_solve (const ParameterVector &)
2353 {
2354 libmesh_not_implemented();
2355 }
2356
2357 inline
2358 std::pair<unsigned int, Real>
weighted_sensitivity_solve(const ParameterVector &,const ParameterVector &)2359 System::weighted_sensitivity_solve (const ParameterVector &,
2360 const ParameterVector &)
2361 {
2362 libmesh_not_implemented();
2363 }
2364
2365 inline
2366 std::pair<unsigned int, Real>
adjoint_solve(const QoISet &)2367 System::adjoint_solve (const QoISet &)
2368 {
2369 libmesh_not_implemented();
2370 }
2371
2372 inline
2373 std::pair<unsigned int, Real>
weighted_sensitivity_adjoint_solve(const ParameterVector &,const ParameterVector &,const QoISet &)2374 System::weighted_sensitivity_adjoint_solve (const ParameterVector &,
2375 const ParameterVector &,
2376 const QoISet &)
2377 {
2378 libmesh_not_implemented();
2379 }
2380
2381 inline
2382 void
adjoint_qoi_parameter_sensitivity(const QoISet &,const ParameterVector &,SensitivityData &)2383 System::adjoint_qoi_parameter_sensitivity (const QoISet &,
2384 const ParameterVector &,
2385 SensitivityData &)
2386 {
2387 libmesh_not_implemented();
2388 }
2389
2390 inline
2391 void
forward_qoi_parameter_sensitivity(const QoISet &,const ParameterVector &,SensitivityData &)2392 System::forward_qoi_parameter_sensitivity (const QoISet &,
2393 const ParameterVector &,
2394 SensitivityData &)
2395 {
2396 libmesh_not_implemented();
2397 }
2398
2399 inline
2400 void
qoi_parameter_hessian(const QoISet &,const ParameterVector &,SensitivityData &)2401 System::qoi_parameter_hessian(const QoISet &,
2402 const ParameterVector &,
2403 SensitivityData &)
2404 {
2405 libmesh_not_implemented();
2406 }
2407
2408 inline
2409 void
qoi_parameter_hessian_vector_product(const QoISet &,const ParameterVector &,const ParameterVector &,SensitivityData &)2410 System::qoi_parameter_hessian_vector_product(const QoISet &,
2411 const ParameterVector &,
2412 const ParameterVector &,
2413 SensitivityData &)
2414 {
2415 libmesh_not_implemented();
2416 }
2417
2418
2419 } // namespace libMesh
2420
2421 #endif // LIBMESH_SYSTEM_H
2422