IFEM  90A354
SIMCoupledSI.h
Go to the documentation of this file.
1 // $Id$
2 //==============================================================================
12 //==============================================================================
13 
14 #ifndef SIM_COUPLED_SI_H_
15 #define SIM_COUPLED_SI_H_
16 
17 #include "SIMCoupled.h"
18 #include "SIMenums.h"
19 #include "MatVec.h"
20 #include "TimeStep.h"
21 #include "Functions.h"
22 #include "Utilities.h"
23 #include "IFEM.h"
24 #include <tinyxml2.h>
25 
26 
31 template<class T1, class T2>
32 class SIMCoupledSI : public SIMCoupled<T1,T2>
33 {
34 public:
36  SIMCoupledSI(T1& s1, T2& s2) : SIMCoupled<T1,T2>(s1,s2)
37  {
38  maxIter = 50;
39  maxItFunc = nullptr;
40  noStg = aitken = false;
41  omega = omega0 = 0.0;
42  }
43 
45  virtual ~SIMCoupledSI() { delete maxItFunc; }
46 
48  virtual void enableStaggering(bool enable = true) { noStg = !enable; }
49 
51  virtual const Vector& getAitkenResidual() const
52  {
53  static Vector empty;
54  return empty;
55  }
56 
58  virtual const Vector& getRelaxationVector() const
59  {
60  static Vector empty;
61  return empty;
62  }
63 
65  virtual void setRelaxedSolution(const Vector&) {}
66 
68  virtual bool solveStep(TimeStep& tp, bool firstS1 = true)
69  {
70  if (tp.multiSteps())
71  this->S1.getProcessAdm().cout <<"\n step="<< tp.step
72  <<" time="<< tp.time.t << std::endl;
73 
74  int maxit = this->getMaxit(tp.step);
75  SIM::ConvStatus conv = SIM::OK;
76  for (tp.iter = 0; tp.iter <= maxit && conv != SIM::CONVERGED; tp.iter++)
77  {
78  SIM::ConvStatus status1 = SIM::OK, status2 = SIM::OK;
79  if (firstS1 && (status1 = this->S1.solveIteration(tp)) <= SIM::DIVERGED)
80  return false;
81 
82  if ((status2 = this->S2.solveIteration(tp)) <= SIM::DIVERGED)
83  return false;
84 
85  if (!firstS1 && (status1 = this->S1.solveIteration(tp)) <= SIM::DIVERGED)
86  return false;
87 
88  if ((conv = this->checkConvergence(tp,status1,status2)) <= SIM::DIVERGED)
89  return false;
90 
91  if (omega0 != 0.0) {
92  if (tp.iter > 0) {
93  // Calculation of Aitken acceleration factor
94  if (aitken) {
95  Vector r1 = this->getAitkenResidual();
96  r1 -= prevRes;
97  omega *= -prevRes.dot(r1) / r1.dot(r1);
98  if (fabs(omega) < 1e-6) {
99  std::cerr <<"\n ** Relaxation weight "<< omega <<" too small,"
100  <<" resetting to default "<< omega0 << std::endl;
101  omega = omega0;
102  }
103  }
104 
105  // Perform relaxation
106  IFEM::cout <<", omega="<< omega;
107  prevSol *= 1.0 - omega;
108  prevSol.add(this->getRelaxationVector(), omega);
110  } else {
111  omega = omega0;
112  prevSol = this->getRelaxationVector();
113  }
114  if (aitken)
115  prevRes = this->getAitkenResidual();
116  }
117  IFEM::cout << std::endl;
118  }
119 
120  this->S1.postSolve(tp);
121  this->S2.postSolve(tp);
122  tp.time.first = false;
123 
124  return true;
125  }
126 
129  SIM::ConvStatus status1,
130  SIM::ConvStatus status2)
131  {
132  if (status1 == status2)
133  return status1;
134 
135  if (status1 == SIM::FAILURE || status2 == SIM::FAILURE)
136  return SIM::FAILURE;
137 
138  if (status1 == SIM::DIVERGED || status2 == SIM::DIVERGED)
139  return SIM::DIVERGED;
140 
141  return SIM::OK;
142  }
143 
144 protected:
146  void parseIterations(const tinyxml2::XMLElement* elem)
147  {
148  IFEM::cout <<"\tUsing sub-iterations\n";
149 
150  std::string func;
151  if (utl::getAttribute(elem,"maxFunc",func) ||
152  utl::getAttribute(elem,"max",func))
153  if (func.find_first_of('t') != std::string::npos)
154  {
155  IFEM::cout <<"\t\tmax = ";
156  maxItFunc = utl::parseTimeFunc(func.c_str(),"expression");
157  }
158 
159  if (!maxItFunc && utl::getAttribute(elem,"max",maxIter))
160  IFEM::cout <<"\t\tmax = "<< maxIter << std::endl;
161 
162  if ((utl::getAttribute(elem,"relax",omega) ||
163  utl::getAttribute(elem,"omega",omega)) && omega != 0.0) {
164  IFEM::cout <<"\t\trelaxation = "<< omega;
165  if (utl::getAttribute(elem,"aitken",aitken) && aitken)
166  IFEM::cout <<" (aitken)";
167  IFEM::cout << std::endl;
168  omega0 = omega;
169  }
170  }
171 
173  int getMaxit(int iStep = 0) const
174  {
175  if (noStg)
176  return 0; // staggering is disabled
177  else if (maxItFunc)
178  return static_cast<int>((*maxItFunc)(iStep));
179 
180  return maxIter;
181  }
182 
183 private:
184  int maxIter;
186  bool noStg;
187 
188  double omega0;
189  double omega;
190  bool aitken;
191 
194 };
195 
196 #endif
Specific function implementations.
Initialization of the IFEM library.
Global algebraic operations on index 1-based matrices and vectors.
Coupled SIM solver class template.
Various enums for simulation scope.
Class for encapsulation of general time stepping parameters.
static const double T1[2]
1-point rule coordinates.
Definition: TriangleQuadrature.C:19
Various utility methods.
static utl::LogStream cout
Combined standard out for parallel processes.
Definition: IFEM.h:62
Template class for semi-implicitly coupled simulators.
Definition: SIMCoupledSI.h:33
Vector prevRes
Previous residual used for aitken-acceleration factor.
Definition: SIMCoupledSI.h:193
bool aitken
If true, Aitken-acceleration is enabled.
Definition: SIMCoupledSI.h:190
int getMaxit(int iStep=0) const
Returns the maximum number of sub-iteration cycles.
Definition: SIMCoupledSI.h:173
int maxIter
Maximum number of iterations.
Definition: SIMCoupledSI.h:184
double omega
Current relaxation parameter.
Definition: SIMCoupledSI.h:189
virtual const Vector & getRelaxationVector() const
Returns solution to use for relaxation.
Definition: SIMCoupledSI.h:58
virtual void setRelaxedSolution(const Vector &)
Sets the relaxed solution.
Definition: SIMCoupledSI.h:65
virtual const Vector & getAitkenResidual() const
Returns residual to use for aitken acceleration.
Definition: SIMCoupledSI.h:51
virtual void enableStaggering(bool enable=true)
Enable/disable the staggering iteration cycles.
Definition: SIMCoupledSI.h:48
void parseIterations(const tinyxml2::XMLElement *elem)
Parses sub-iteration setup from an XML tag.
Definition: SIMCoupledSI.h:146
SIMCoupledSI(T1 &s1, T2 &s2)
The constructor forwards to the parent class constructor.
Definition: SIMCoupledSI.h:36
virtual bool solveStep(TimeStep &tp, bool firstS1=true)
Computes the solution for the current time step.
Definition: SIMCoupledSI.h:68
bool noStg
If true, sub-iterations is disabled.
Definition: SIMCoupledSI.h:186
virtual ~SIMCoupledSI()
The destructor deletes the max iteration function.
Definition: SIMCoupledSI.h:45
virtual SIM::ConvStatus checkConvergence(const TimeStep &, SIM::ConvStatus status1, SIM::ConvStatus status2)
Override this method to add additional convergence criteria.
Definition: SIMCoupledSI.h:128
Vector prevSol
Previous solution for relaxed field.
Definition: SIMCoupledSI.h:192
double omega0
Initial relaxation parameter.
Definition: SIMCoupledSI.h:188
ScalarFunc * maxItFunc
Maximum number of iterations as a function.
Definition: SIMCoupledSI.h:185
Template class for coupled simulators.
Definition: SIMCoupled.h:35
T1 & S1
First substep.
Definition: SIMCoupled.h:193
T2 & S2
Second substep.
Definition: SIMCoupled.h:194
Scalar-valued unary function of a scalar value.
Definition: Function.h:127
Class for encapsulation of general time stepping parameters.
Definition: TimeStep.h:31
int step
Time step counter.
Definition: TimeStep.h:72
bool multiSteps() const
Returns true if the simulation consists of several time steps.
Definition: TimeStep.C:184
TimeDomain time
Time domain data.
Definition: TimeStep.h:74
int & iter
Iteration counter.
Definition: TimeStep.h:73
A vector class with some added algebraic operations.
Definition: matrix.h:64
vector< T > & add(const std::vector< T > &X, const T &alfa=T(1), unsigned int ofsx=0, int stridex=1, unsigned int ofsy=0, int stridey=1)
Add the given vector X scaled by alfa to *this.
Definition: matrix.h:1562
T dot(const T *v, size_t nv, size_t off1=0, int inc1=1, size_t off2=0, int inc2=1) const
Dot product between *this and another vector.
Definition: matrix.h:1502
ConvStatus
Enum defining the various convergence statuses that may occur.
Definition: SIMenums.h:50
int getAttribute(const tinyxml2::XMLElement *xml, const char *att, bool &val)
Extracts a boolean attribute value from the specified XML-element.
Definition: Utilities.C:188
ScalarFunc * parseTimeFunc(const char *func, const std::string &type="expression", Real eps=Real(1.0e-8))
Creates a time function by parsing a character string.
Definition: Functions.C:943
char first
If true, this is the first load/time step.
Definition: TimeDomain.h:29
double t
Current time (or pseudo time, load parameter)
Definition: TimeDomain.h:24