PRISMS-PF  v2.1
variableContainer.cc
Go to the documentation of this file.
1 // All of the methods for the 'variableContainer' class
2 #include "../../include/variableContainer.h"
3 
4 template <int dim, int degree, typename T>
5 variableContainer<dim,degree,T>::variableContainer(const dealii::MatrixFree<dim,double> &data, std::vector<variable_info> _varInfoList, std::vector<variable_info> _varChangeInfoList)
6 {
7  varInfoList = _varInfoList;
8  varChangeInfoList = _varChangeInfoList;
9 
10  num_var = varInfoList.size();
11 
12  for (unsigned int i=0; i < num_var; i++){
13  if (varInfoList[i].var_needed){
14  if (varInfoList[i].is_scalar){
15  dealii::FEEvaluation<dim,degree,degree+1,1,double> var(data, i);
16  scalar_vars.push_back(var);
17  }
18  else {
19  dealii::FEEvaluation<dim,degree,degree+1,dim,double> var(data, i);
20  vector_vars.push_back(var);
21  }
22  }
23 
24  if (varChangeInfoList[i].var_needed){
25  if (varChangeInfoList[i].is_scalar){
26  dealii::FEEvaluation<dim,degree,degree+1,1,double> var(data, i);
27  scalar_change_in_vars.push_back(var);
28  }
29  else {
30  dealii::FEEvaluation<dim,degree,degree+1,dim,double> var(data, i);
31  vector_change_in_vars.push_back(var);
32  }
33  }
34  }
35 }
36 
37 template <int dim, int degree, typename T>
38 variableContainer<dim,degree,T>::variableContainer(const dealii::MatrixFree<dim,double> &data, std::vector<variable_info> _varInfoList)
39 {
40  varInfoList = _varInfoList;
41 
42  num_var = varInfoList.size();
43 
44  for (unsigned int i=0; i < num_var; i++){
45  if (varInfoList[i].var_needed){
46  if (varInfoList[i].is_scalar){
47  dealii::FEEvaluation<dim,degree,degree+1,1,double> var(data, i);
48  scalar_vars.push_back(var);
49  }
50  else {
51  dealii::FEEvaluation<dim,degree,degree+1,dim,double> var(data, i);
52  vector_vars.push_back(var);
53  }
54  }
55  }
56 }
57 
58 // Variant of the constructor where it reads from a fixed index of "data", used for post-processing
59 template <int dim, int degree, typename T>
60 variableContainer<dim,degree,T>::variableContainer(const dealii::MatrixFree<dim,double> &data, std::vector<variable_info> _varInfoList, unsigned int fixed_index)
61 {
62  varInfoList = _varInfoList;
63 
64  num_var = varInfoList.size();
65 
66  for (unsigned int i=0; i < num_var; i++){
67  if (varInfoList[i].var_needed){
68  if (varInfoList[i].is_scalar){
69  dealii::FEEvaluation<dim,degree,degree+1,1,double> var(data, fixed_index);
70  scalar_vars.push_back(var);
71  }
72  else {
73  dealii::FEEvaluation<dim,degree,degree+1,dim,double> var(data, fixed_index);
74  vector_vars.push_back(var);
75  }
76  }
77  }
78 }
79 
80 template <int dim, int degree, typename T>
81 void variableContainer<dim,degree,T>::get_JxW(dealii::AlignedVector<T> & JxW){
82 
83  if (scalar_vars.size() > 0){
84  scalar_vars[0].fill_JxW_values(JxW);
85  }
86  else if (vector_vars.size() > 0){
87  scalar_change_in_vars[0].fill_JxW_values(JxW);
88  }
89  else if (scalar_change_in_vars.size() > 0){
90  vector_vars[0].fill_JxW_values(JxW);
91  }
92  else {
93  vector_change_in_vars[0].fill_JxW_values(JxW);
94  }
95 }
96 
97 template <int dim, int degree, typename T>
99  if (scalar_vars.size() > 0){
100  return scalar_vars[0].n_q_points;
101  }
102  else if (vector_vars.size() > 0){
103  return vector_vars[0].n_q_points;
104  }
105  else if (scalar_change_in_vars.size() > 0){
106  return scalar_change_in_vars[0].n_q_points;
107  }
108  else {
109  return vector_change_in_vars[0].n_q_points;
110  }
111 }
112 
113 template <int dim, int degree, typename T>
115 
116  if (scalar_vars.size() > 0){
117  return scalar_vars[0].quadrature_point(q_point);
118  }
119  else if (vector_vars.size() > 0){
120  return vector_vars[0].quadrature_point(q_point);
121  }
122  else if (scalar_change_in_vars.size() > 0){
123  return scalar_change_in_vars[0].quadrature_point(q_point);
124  }
125  else {
126  return vector_change_in_vars[0].quadrature_point(q_point);
127  }
128 }
129 
130 template <int dim, int degree, typename T>
131 void variableContainer<dim,degree,T>::reinit_and_eval(const std::vector<vectorType*> &src, unsigned int cell){
132 
133  for (unsigned int i=0; i<num_var; i++){
134  if (varInfoList[i].var_needed){
135  if (varInfoList[i].is_scalar) {
136  scalar_vars[varInfoList[i].scalar_or_vector_index].reinit(cell);
137  scalar_vars[varInfoList[i].scalar_or_vector_index].read_dof_values(*src[i]);
138  scalar_vars[varInfoList[i].scalar_or_vector_index].evaluate(varInfoList[i].need_value, varInfoList[i].need_gradient, varInfoList[i].need_hessian);
139  }
140  else {
141  vector_vars[varInfoList[i].scalar_or_vector_index].reinit(cell);
142  vector_vars[varInfoList[i].scalar_or_vector_index].read_dof_values(*src[i]);
143  vector_vars[varInfoList[i].scalar_or_vector_index].evaluate(varInfoList[i].need_value, varInfoList[i].need_gradient, varInfoList[i].need_hessian);
144  }
145  }
146  }
147 }
148 
149 /**
150 * This is specialized for the LHS where there will be only one change in the solution needed.
151 * The RHS method takes the src as a vector of vectorTypes.
152 */
153 template <int dim, int degree, typename T>
154 void variableContainer<dim,degree,T>::reinit_and_eval_change_in_solution(const vectorType &src, unsigned int cell, unsigned int var_being_solved){
155 
156  if (varChangeInfoList[var_being_solved].is_scalar) {
157  scalar_change_in_vars[0].reinit(cell);
158  scalar_change_in_vars[0].read_dof_values(src);
159  scalar_change_in_vars[0].evaluate(varChangeInfoList[var_being_solved].need_value, varChangeInfoList[var_being_solved].need_gradient, varChangeInfoList[var_being_solved].need_hessian);
160  }
161  else {
162  vector_change_in_vars[0].reinit(cell);
163  vector_change_in_vars[0].read_dof_values(src);
164  vector_change_in_vars[0].evaluate(varChangeInfoList[var_being_solved].need_value, varChangeInfoList[var_being_solved].need_gradient, varChangeInfoList[var_being_solved].need_hessian);
165  }
166 
167 }
168 
169 
170 template <int dim, int degree, typename T>
171 void variableContainer<dim,degree,T>::reinit_and_eval_LHS(const vectorType &src, const std::vector<vectorType*> solutionSet, unsigned int cell, unsigned int var_being_solved){
172 
173  for (unsigned int i=0; i<num_var; i++){
174  if (varInfoList[i].var_needed){
175  if (varInfoList[i].is_scalar) {
176  scalar_vars[varInfoList[i].scalar_or_vector_index].reinit(cell);
177  if (i == var_being_solved ){
178  scalar_vars[varInfoList[i].scalar_or_vector_index].read_dof_values(src);
179  }
180  else{
181  scalar_vars[varInfoList[i].scalar_or_vector_index].read_dof_values(*solutionSet[i]);
182  }
183  scalar_vars[varInfoList[i].scalar_or_vector_index].evaluate(varInfoList[i].need_value, varInfoList[i].need_gradient, varInfoList[i].need_hessian);
184  }
185  else {
186  vector_vars[varInfoList[i].scalar_or_vector_index].reinit(cell);
187  if (i == var_being_solved){
188  vector_vars[varInfoList[i].scalar_or_vector_index].read_dof_values(src);
189  }
190  else {
191  vector_vars[varInfoList[i].scalar_or_vector_index].read_dof_values(*solutionSet[i]);
192  }
193  vector_vars[varInfoList[i].scalar_or_vector_index].evaluate(varInfoList[i].need_value, varInfoList[i].need_gradient, varInfoList[i].need_hessian);
194  }
195  }
196  }
197 
198 }
199 
200 template <int dim, int degree, typename T>
202 
203  for (unsigned int i=0; i<num_var; i++){
204  if (varInfoList[i].var_needed){
205  if (varInfoList[i].is_scalar) {
206  scalar_vars[varInfoList[i].scalar_or_vector_index].reinit(cell);
207  }
208  else {
209  vector_vars[varInfoList[i].scalar_or_vector_index].reinit(cell);
210  }
211  }
212  }
213 }
214 
215 
216 template <int dim, int degree, typename T>
218 
219  for (unsigned int i=0; i<num_var; i++){
220  if (varInfoList[i].value_residual || varInfoList[i].gradient_residual){
221  if (varInfoList[i].is_scalar) {
222  scalar_vars[varInfoList[i].scalar_or_vector_index].integrate(varInfoList[i].value_residual, varInfoList[i].gradient_residual);
223  scalar_vars[varInfoList[i].scalar_or_vector_index].distribute_local_to_global(*dst[i]);
224  }
225  else {
226  vector_vars[varInfoList[i].scalar_or_vector_index].integrate(varInfoList[i].value_residual, varInfoList[i].gradient_residual);
227  vector_vars[varInfoList[i].scalar_or_vector_index].distribute_local_to_global(*dst[i]);
228  }
229  }
230  }
231 }
232 
233 template <int dim, int degree, typename T>
235 
236  //integrate
237  if (varChangeInfoList[var_being_solved].is_scalar) {
238  scalar_change_in_vars[0].integrate(varChangeInfoList[var_being_solved].value_residual, varChangeInfoList[var_being_solved].gradient_residual);
239  scalar_change_in_vars[0].distribute_local_to_global(dst);
240  }
241  else {
242  vector_change_in_vars[0].integrate(varChangeInfoList[var_being_solved].value_residual, varChangeInfoList[var_being_solved].gradient_residual);
243  vector_change_in_vars[0].distribute_local_to_global(dst);
244  }
245 }
246 
247 // Need to add index checking to these functions so that an error is thrown if the index wasn't set
248 template <int dim, int degree, typename T>
249 T variableContainer<dim,degree,T>::get_scalar_value(unsigned int global_variable_index) const
250 {
251  if (varInfoList[global_variable_index].need_value){
252  return scalar_vars[varInfoList[global_variable_index].scalar_or_vector_index].get_value(q_point);
253  }
254  else {
255  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
256  abort();
257  }
258 }
259 
260 template <int dim, int degree, typename T>
261 dealii::Tensor<1, dim, T > variableContainer<dim,degree,T>::get_scalar_gradient(unsigned int global_variable_index) const
262 {
263  if (varInfoList[global_variable_index].need_gradient){
264  return scalar_vars[varInfoList[global_variable_index].scalar_or_vector_index].get_gradient(q_point);
265  }
266  else {
267  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
268  abort();
269  }
270 }
271 
272 template <int dim, int degree, typename T>
273 dealii::Tensor<2, dim, T > variableContainer<dim,degree,T>::get_scalar_hessian(unsigned int global_variable_index) const
274 {
275  if (varInfoList[global_variable_index].need_hessian){
276  return scalar_vars[varInfoList[global_variable_index].scalar_or_vector_index].get_hessian(q_point);
277  }
278  else {
279  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
280  abort();
281  }
282 }
283 
284 template <int dim, int degree, typename T>
285 dealii::Tensor<1, dim, T > variableContainer<dim,degree,T>::get_vector_value(unsigned int global_variable_index) const
286 {
287  if (varInfoList[global_variable_index].need_value){
288  return vector_vars[varInfoList[global_variable_index].scalar_or_vector_index].get_value(q_point);
289  }
290  else {
291  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
292  abort();
293  }
294 }
295 
296 template <int dim, int degree, typename T>
297 dealii::Tensor<2, dim, T > variableContainer<dim,degree,T>::get_vector_gradient(unsigned int global_variable_index) const
298 {
299  if (varInfoList[global_variable_index].need_gradient){
300  return vector_vars[varInfoList[global_variable_index].scalar_or_vector_index].get_gradient(q_point);
301  }
302  else {
303  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
304  abort();
305  }
306 }
307 
308 template <int dim, int degree, typename T>
309 dealii::Tensor<3, dim, T > variableContainer<dim,degree,T>::get_vector_hessian(unsigned int global_variable_index) const
310 {
311  if (varInfoList[global_variable_index].need_hessian){
312  return vector_vars[varInfoList[global_variable_index].scalar_or_vector_index].get_hessian(q_point);
313  }
314  else {
315  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
316  abort();
317  }
318 }
319 
320 // Need to add index checking to these functions so that an error is thrown if the index wasn't set
321 template <int dim, int degree, typename T>
322 T variableContainer<dim,degree,T>::get_change_in_scalar_value(unsigned int global_variable_index) const
323 {
324  if (varChangeInfoList[global_variable_index].need_value){
325  return scalar_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].get_value(q_point);
326  }
327  else {
328  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
329  abort();
330  }
331 }
332 
333 template <int dim, int degree, typename T>
334 dealii::Tensor<1, dim, T > variableContainer<dim,degree,T>::get_change_in_scalar_gradient(unsigned int global_variable_index) const
335 {
336  if (varChangeInfoList[global_variable_index].need_gradient){
337  return scalar_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].get_gradient(q_point);
338  }
339  else {
340  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
341  abort();
342  }
343 }
344 
345 template <int dim, int degree, typename T>
346 dealii::Tensor<2, dim, T > variableContainer<dim,degree,T>::get_change_in_scalar_hessian(unsigned int global_variable_index) const
347 {
348  if (varChangeInfoList[global_variable_index].need_hessian){
349  return scalar_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].get_hessian(q_point);
350  }
351  else {
352  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
353  abort();
354  }
355 }
356 
357 template <int dim, int degree, typename T>
358 dealii::Tensor<1, dim, T > variableContainer<dim,degree,T>::get_change_in_vector_value(unsigned int global_variable_index) const
359 {
360  if (varChangeInfoList[global_variable_index].need_value){
361  return vector_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].get_value(q_point);
362  }
363  else {
364  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
365  abort();
366  }
367 }
368 
369 template <int dim, int degree, typename T>
370 dealii::Tensor<2, dim, T > variableContainer<dim,degree,T>::get_change_in_vector_gradient(unsigned int global_variable_index) const
371 {
372  if (varChangeInfoList[global_variable_index].need_gradient){
373  return vector_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].get_gradient(q_point);
374  }
375  else {
376  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
377  abort();
378  }
379 }
380 
381 template <int dim, int degree, typename T>
382 dealii::Tensor<3, dim, T > variableContainer<dim,degree,T>::get_change_in_vector_hessian(unsigned int global_variable_index) const
383 {
384  if (varChangeInfoList[global_variable_index].need_hessian){
385  return vector_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].get_hessian(q_point);
386  }
387  else {
388  std::cerr << "PRISMS-PF Error: Attempted access of a variable value that was not marked as needed in 'parameters.in'. Double-check the indices in user functions where a variable value is requested." << std::endl;
389  abort();
390  }
391 }
392 
393 // The methods to set the residual terms
394 template <int dim, int degree, typename T>
395 void variableContainer<dim,degree,T>::set_scalar_value_term_RHS(unsigned int global_variable_index, T val){
396  scalar_vars[varInfoList[global_variable_index].scalar_or_vector_index].submit_value(val,q_point);
397 }
398 
399 template <int dim, int degree, typename T>
400 void variableContainer<dim,degree,T>::set_scalar_gradient_term_RHS(unsigned int global_variable_index, dealii::Tensor<1, dim, T > grad){
401  scalar_vars[varInfoList[global_variable_index].scalar_or_vector_index].submit_gradient(grad,q_point);
402 }
403 
404 template <int dim, int degree, typename T>
405 void variableContainer<dim,degree,T>::set_vector_value_term_RHS(unsigned int global_variable_index, dealii::Tensor<1, dim, T > val){
406  vector_vars[varInfoList[global_variable_index].scalar_or_vector_index].submit_value(val,q_point);
407 }
408 template <int dim, int degree, typename T>
409 void variableContainer<dim,degree,T>::set_vector_gradient_term_RHS(unsigned int global_variable_index, dealii::Tensor<2, dim, T > grad){
410  vector_vars[varInfoList[global_variable_index].scalar_or_vector_index].submit_gradient(grad,q_point);
411 }
412 
413 template <int dim, int degree, typename T>
414 void variableContainer<dim,degree,T>::set_scalar_value_term_LHS(unsigned int global_variable_index, T val){
415  scalar_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].submit_value(val,q_point);
416 }
417 
418 template <int dim, int degree, typename T>
419 void variableContainer<dim,degree,T>::set_scalar_gradient_term_LHS(unsigned int global_variable_index, dealii::Tensor<1, dim, T > grad){
420  scalar_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].submit_gradient(grad,q_point);
421 }
422 
423 template <int dim, int degree, typename T>
424 void variableContainer<dim,degree,T>::set_vector_value_term_LHS(unsigned int global_variable_index, dealii::Tensor<1, dim, T > val){
425  vector_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].submit_value(val,q_point);
426 }
427 template <int dim, int degree, typename T>
428 void variableContainer<dim,degree,T>::set_vector_gradient_term_LHS(unsigned int global_variable_index, dealii::Tensor<2, dim, T > grad){
429  vector_change_in_vars[varChangeInfoList[global_variable_index].scalar_or_vector_index].submit_gradient(grad,q_point);
430 }
431 
void reinit_and_eval_change_in_solution(const vectorType &src, unsigned int cell, unsigned int var_being_solved)
void set_vector_gradient_term_LHS(unsigned int global_variable_index, dealii::Tensor< 2, dim, T > grad)
void reinit(unsigned int cell)
dealii::Tensor< 2, dim, T > get_change_in_vector_gradient(unsigned int global_variable_index) const
void integrate_and_distribute(std::vector< vectorType *> &dst)
void set_scalar_value_term_LHS(unsigned int global_variable_index, T val)
void integrate_and_distribute_change_in_solution_LHS(vectorType &dst, const unsigned int var_being_solved)
void set_scalar_value_term_RHS(unsigned int global_variable_index, T val)
void get_JxW(dealii::AlignedVector< T > &JxW)
void set_scalar_gradient_term_RHS(unsigned int global_variable_index, dealii::Tensor< 1, dim, T > grad)
variableContainer(const dealii::MatrixFree< dim, double > &data, std::vector< variable_info > _varInfoList, std::vector< variable_info > _varChangeInfoList)
dealii::Tensor< 1, dim, T > get_vector_value(unsigned int global_variable_index) const
dealii::Tensor< 2, dim, T > get_vector_gradient(unsigned int global_variable_index) const
dealii::Tensor< 3, dim, T > get_vector_hessian(unsigned int global_variable_index) const
void set_vector_value_term_LHS(unsigned int global_variable_index, dealii::Tensor< 1, dim, T > val)
dealii::parallel::distributed::Vector< double > vectorType
dealii::Tensor< 2, dim, T > get_change_in_scalar_hessian(unsigned int global_variable_index) const
dealii::Tensor< 1, dim, T > get_scalar_gradient(unsigned int global_variable_index) const
dealii::Tensor< 2, dim, T > get_scalar_hessian(unsigned int global_variable_index) const
void reinit_and_eval(const std::vector< vectorType *> &src, unsigned int cell)
unsigned int get_num_q_points()
void reinit_and_eval_LHS(const vectorType &src, const std::vector< vectorType *> solutionSet, unsigned int cell, unsigned int var_being_solved)
void set_vector_value_term_RHS(unsigned int global_variable_index, dealii::Tensor< 1, dim, T > val)
dealii::Tensor< 1, dim, T > get_change_in_vector_value(unsigned int global_variable_index) const
dealii::Tensor< 3, dim, T > get_change_in_vector_hessian(unsigned int global_variable_index) const
T get_scalar_value(unsigned int global_variable_index) const
dealii::Point< dim, T > get_q_point_location()
T get_change_in_scalar_value(unsigned int global_variable_index) const
dealii::Tensor< 1, dim, T > get_change_in_scalar_gradient(unsigned int global_variable_index) const
void set_scalar_gradient_term_LHS(unsigned int global_variable_index, dealii::Tensor< 1, dim, T > grad)
void set_vector_gradient_term_RHS(unsigned int global_variable_index, dealii::Tensor< 2, dim, T > grad)