PRISMS-PF  v2.1
setNonlinearEqInitialGuess.cc
Go to the documentation of this file.
1 //setNonlinearEqInitialGuess() method for MatrixFreePDE class
2 
3 #include "../../include/matrixFreePDE.h"
4 #include <deal.II/lac/solver_cg.h>
5 
6 //solve each time increment
7 template <int dim, int degree>
9 
10  //log time
11  computing_timer.enter_section("matrixFreePDE: setNonlinearEqInitialGuess");
12  Timer time;
13  char buffer[200];
14 
15  for(unsigned int fieldIndex=0; fieldIndex<fields.size(); fieldIndex++){
16  if ( (userInputs.var_eq_type[fieldIndex] == TIME_INDEPENDENT) && userInputs.var_nonlinear[fieldIndex] && userInputs.nonlinear_solver_parameters.getLaplaceInitializationFlag(fieldIndex)){
17  currentFieldIndex = fieldIndex; // Used in computeLaplaceLHS()
18 
19  computeLaplaceRHS(fieldIndex);
20 
21  for (std::map<types::global_dof_index, double>::const_iterator it=valuesDirichletSet[fieldIndex]->begin(); it!=valuesDirichletSet[fieldIndex]->end(); ++it){
22  if (residualSet[fieldIndex]->in_local_range(it->first)){
23  (*residualSet[fieldIndex])(it->first) = 0.0;
24  }
25  }
26 
27  //solver controls
28  double tol_value;
29  if (userInputs.linear_solver_parameters.getToleranceType(fieldIndex) == ABSOLUTE_RESIDUAL){
30  tol_value = userInputs.linear_solver_parameters.getToleranceValue(fieldIndex);
31  }
32  else {
33  tol_value = userInputs.linear_solver_parameters.getToleranceValue(fieldIndex)*residualSet[fieldIndex]->l2_norm();
34  }
35 
36  SolverControl solver_control(userInputs.linear_solver_parameters.getMaxIterations(fieldIndex), tol_value);
37 
38  // Currently the only allowed solver is SolverCG, the SolverType input variable is a dummy
39  SolverCG<vectorType> solver(solver_control);
40 
41  //solve
42  try{
43  if (fields[fieldIndex].type == SCALAR){
44  dU_scalar=0.0;
45  solver.solve(*this, dU_scalar, *residualSet[fieldIndex], IdentityMatrix(solutionSet[fieldIndex]->size()));
46  }
47  else {
48  dU_vector=0.0;
49  solver.solve(*this, dU_vector, *residualSet[fieldIndex], IdentityMatrix(solutionSet[fieldIndex]->size()));
50  }
51  }
52  catch (...) {
53  pcout << "\nWarning: implicit solver did not converge as per set tolerances. consider increasing maxSolverIterations or decreasing solverTolerance.\n";
54  }
55 
56  if (fields[fieldIndex].type == SCALAR){
57  *solutionSet[fieldIndex] += dU_scalar;
58  }
59  else {
60  *solutionSet[fieldIndex] += dU_vector;
61  }
62 
63  if (currentIncrement%userInputs.skip_print_steps==0){
64  double dU_norm;
65  if (fields[fieldIndex].type == SCALAR){
66  dU_norm = dU_scalar.l2_norm();
67  }
68  else {
69  dU_norm = dU_vector.l2_norm();
70  }
71  sprintf(buffer, "field '%2s' [laplace solve for initial guess]: initial residual:%12.6e, current residual:%12.6e, nsteps:%u, tolerance criterion:%12.6e, solution: %12.6e, dU: %12.6e\n", \
72  fields[fieldIndex].name.c_str(), \
73  residualSet[fieldIndex]->l2_norm(), \
74  solver_control.last_value(), \
75  solver_control.last_step(), solver_control.tolerance(), solutionSet[fieldIndex]->l2_norm(), dU_norm);
76  pcout<<buffer;
77  pcout <<std::endl;
78  }
79  }
80 
81 
82  }
83 
84  if (currentIncrement%userInputs.skip_print_steps==0){
85  pcout << "wall time: " << time.wall_time() << "s\n";
86  }
87  //log time
88  computing_timer.exit_section("matrixFreePDE: setNonlinearEqInitialGuess");
89 
90 }
91 
92 template <int dim, int degree>
93 void MatrixFreePDE<dim,degree>::computeLaplaceRHS(unsigned int fieldIndex){
94  //log time
95  computing_timer.enter_section("matrixFreePDE: computeLaplaceRHS");
96 
97  //clear residual vectors before update
98  (*residualSet[fieldIndex])=0.0;
99 
100 
101  //call to integrate and assemble
102  matrixFreeObject.cell_loop (&MatrixFreePDE<dim,degree>::getLaplaceRHS, this, *residualSet[fieldIndex], *solutionSet[fieldIndex]);
103 
104  //end log
105  computing_timer.exit_section("matrixFreePDE: computeLaplaceRHS");
106 }
107 
108 template <int dim, int degree>
109 void MatrixFreePDE<dim,degree>::getLaplaceRHS(const MatrixFree<dim,double> &data,
110  vectorType &dst,
111  const vectorType &src,
112  const std::pair<unsigned int,unsigned int> &cell_range) const{
113 
114  FEEvaluation<dim,degree> mat(data);
115  //loop over all "cells"
116  for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
117  {
118  mat.reinit (cell);
119  mat.read_dof_values(src);
120  mat.evaluate (false,true,false);
121  for (unsigned int q=0; q<mat.n_q_points; ++q){
122  mat.submit_gradient(mat.get_gradient(q),q);
123  }
124  mat.integrate (false,true);
125  mat.distribute_local_to_global (dst);
126  }
127 }
128 
129 
130 template <int dim, int degree>
131 void MatrixFreePDE<dim,degree>::getLaplaceLHS(const MatrixFree<dim,double> &data,
132  vectorType &dst,
133  const vectorType &src,
134  const std::pair<unsigned int,unsigned int> &cell_range) const{
135 
136  FEEvaluation<dim,degree> mat(data);
137  //loop over all "cells"
138  for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
139  {
140  mat.reinit (cell);
141  mat.read_dof_values(src);
142  mat.evaluate (false,true,false);
143  for (unsigned int q=0; q<mat.n_q_points; ++q){
144  mat.submit_gradient(-mat.get_gradient(q),q);
145  }
146  mat.integrate (false,true);
147  mat.distribute_local_to_global (dst);
148  }
149 }
150 
151 #include "../../include/matrixFreePDE_template_instantiations.h"
void getLaplaceRHS(const MatrixFree< dim, double > &data, vectorType &dst, const vectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
void computeLaplaceRHS(unsigned int fieldIndex)
void getLaplaceLHS(const MatrixFree< dim, double > &data, vectorType &dst, const vectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
dealii::parallel::distributed::Vector< double > vectorType
Definition: FloodFiller.h:15