https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ADNodalBC.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 "ADNodalBC.h"
11#include "NodalBCBase.h"
12#include "ADDirichletBCBase.h"
13
14// MOOSE includes
15#include "Assembly.h"
16#include "SubProblem.h"
17#include "SystemBase.h"
18#include "MooseVariableFE.h"
19#include "MooseVariableScalar.h"
20#include "FEProblemBase.h"
21
22#include "libmesh/quadrature.h"
23
24template <typename T, typename Base>
27{
28 return Base::validParams();
29}
30
31template <>
34{
36 // The below parameters are useful for vector Nodal BCs
37 params.addParam<bool>("set_x_comp", true, "Whether to set the x-component of the variable");
38 params.addParam<bool>("set_y_comp", true, "Whether to set the y-component of the variable");
39 params.addParam<bool>("set_z_comp", true, "Whether to set the z-component of the variable");
40 return params;
41}
42
43template <>
46{
48 // The below parameters are useful for vector Nodal BCs
49 params.addParam<bool>("set_x_comp", true, "Whether to set the x-component of the variable");
50 params.addParam<bool>("set_y_comp", true, "Whether to set the y-component of the variable");
51 params.addParam<bool>("set_z_comp", true, "Whether to set the z-component of the variable");
52 return params;
53}
54
55template <typename T, typename Base>
57 : Base(parameters),
59 true,
60 "variable",
61 Moose::VarKindType::VAR_SOLVER,
62 std::is_same_v<T, Real> ? Moose::VarFieldType::VAR_FIELD_STANDARD
63 : std::is_same_v<T, RealVectorValue>
64 ? Moose::VarFieldType::VAR_FIELD_VECTOR
65 : Moose::VarFieldType::VAR_FIELD_ARRAY),
67 _var(*this->mooseVariable()),
68 _current_node(_var.node()),
69 _u(_var.adNodalValue()),
70 _undisplaced_assembly(_fe_problem.assembly(_tid, _sys.number()))
71{
72 if constexpr (std::is_same_v<T, RealVectorValue>)
73 {
74 _set_components.resize(Moose::dim);
75 _set_components[0] = this->template getParam<bool>("set_x_comp");
76 _set_components[1] = this->template getParam<bool>("set_y_comp");
77 _set_components[2] = this->template getParam<bool>("set_z_comp");
78 }
79 else
80 _set_components.resize(_var.count(), true);
81
82 _subproblem.haveADObjects(true);
83
84 addMooseVariableDependency(this->mooseVariable());
85}
86
87namespace
88{
89template <typename T>
90const T &
91conversionHelper(const T & value, const unsigned int)
92{
93 return value;
94}
95
96template <typename T>
97const T &
98conversionHelper(const VectorValue<T> & value, const unsigned int i)
99{
100 return value(i);
101}
102
103template <typename T>
104const T &
105conversionHelper(const Eigen::Matrix<T, Eigen::Dynamic, 1> & value, const unsigned int i)
106{
107 return value(i);
108}
109}
110
111template <typename T, typename Base>
112void
114 const std::vector<dof_id_type> & dof_indices)
115{
116 mooseAssert(dof_indices.size() <= _set_components.size(),
117 "The number of dof indices must be less than the number of settable components");
118
119 for (const auto i : index_range(dof_indices))
120 if (_set_components[i])
121 setResidual(_sys, conversionHelper(residual, i), dof_indices[i]);
122}
123
124template <typename T, typename Base>
125template <typename ADResidual>
126void
127ADNodalBCTempl<T, Base>::addJacobian(const ADResidual & residual,
128 const std::vector<dof_id_type> & dof_indices)
129{
130 mooseAssert(dof_indices.size() <= _set_components.size(),
131 "The number of dof indices must be less than the number of settable components");
132 if (!std::is_same_v<T, RealVectorValue>)
133 mooseAssert(dof_indices.size() == _var.count(),
134 "The number of dof indices should match the variable count");
135
136 for (const auto i : index_range(dof_indices))
137 if (_set_components[i])
138 // If we store into the displaced assembly for nodal bc objects the data never actually makes
139 // it into the global Jacobian. A nodal bc replaces its own row, so the row must not be
140 // distributed by constraints (e.g. a hanging node) onto the rows of other dofs
141 this->addJacobianWithoutConstraints(_undisplaced_assembly,
142 Moose::Span(&conversionHelper(residual, i), 1),
143 Moose::Span(&dof_indices[i], 1),
144 /*scaling_factor=*/1);
145}
146
147template <typename T, typename Base>
148void
150{
151 const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
152 if (dof_indices.empty())
153 return;
154
155 const auto residual = MetaPhysicL::raw_value(computeQpResidual());
156
157 addResidual(residual, dof_indices);
158}
159
160template <typename T, typename Base>
161void
163{
164 const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
165 if (dof_indices.empty())
166 return;
167
168 const auto residual = computeQpResidual();
169
170 addJacobian(residual, dof_indices);
171}
172
173template <typename T, typename Base>
174void
176{
177 const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
178 if (dof_indices.empty())
179 return;
180
181 const auto residual = computeQpResidual();
182
183 addResidual(MetaPhysicL::raw_value(residual), dof_indices);
184 addJacobian(residual, dof_indices);
185}
186
187template <typename T, typename Base>
188void
190{
191 // Only need to do this once because AD does all the derivatives at once
192 if (jvar_num == _var.number())
193 computeJacobian();
194}
195
196template <typename T, typename Base>
197void
199{
200 // scalar coupling will have been included in the all-at-once handling in computeOffDiagJacobian
201}
202
static InputParameters validParams()
An interface for accessing Moose::Functors for systems that care about automatic differentiation,...
Base class for deriving any automatic differentiation boundary condition of a integrated type.
Definition ADNodalBC.h:22
static InputParameters validParams()
Definition ADNodalBC.C:26
void computeJacobian() override final
Definition ADNodalBC.C:162
void computeResidual() override final
Definition ADNodalBC.C:149
void computeOffDiagJacobian(unsigned int jvar) override final
Definition ADNodalBC.C:189
void computeOffDiagJacobianScalar(unsigned int jvar) override final
Definition ADNodalBC.C:198
void addResidual(const T &residual, const std::vector< dof_id_type > &dof_indices)
process the residual into the global data structures
Definition ADNodalBC.C:113
ADNodalBCTempl(const InputParameters &parameters)
Definition ADNodalBC.C:56
void addJacobian(const ADResidual &residual, const std::vector< dof_id_type > &dof_indices)
process the Jacobian into the global data structures
Definition ADNodalBC.C:127
void computeResidualAndJacobian() override
Definition ADNodalBC.C:175
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
Interface for objects that need to get values of MooseVariables.
Replacement for std::span which we only get in c++20.
static InputParameters validParams()
Definition NodalBCBase.C:13
auto raw_value(const Eigen::Map< T > &in)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:175
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)