MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
NonlinearSystem Class Reference

#include <NonlinearSystem.h>

+ Collaboration diagram for NonlinearSystem:

Public Member Functions

int apply ()
 
vector_type compute_at (const vector_type &x)
 
int compute_jacobians (const vector_type &x, bool compute_inverse=true)
 
void correction_step ()
 Makes the first guess. After this call the Newton method. More...
 
bool find_roots_gnewton (double tolerance=1e-7, size_t max_iter=50)
 Find roots using Newton-Raphson method. More...
 
template<typename T >
void initialize (const T &x)
 
 NonlinearSystem (size_t systemSize)
 
value_type slope (unsigned int which_dimen)
 Compute the slope of function in given dimension. More...
 
int system (const vector_type &x, vector_type &f)
 
string to_string ()
 

Public Attributes

double dx_
 
vector_type f_
 
matrix_type invJ_
 
bool is_f_positive_
 
bool is_jacobian_valid_
 
matrix_type J_
 
ReacInfo ri
 
const size_t size_
 
vector_type slopes_
 
vector_type x1
 
vector_type x2
 
vector_type x_
 

Detailed Description

Definition at line 88 of file NonlinearSystem.h.

Constructor & Destructor Documentation

NonlinearSystem::NonlinearSystem ( size_t  systemSize)
inline

Definition at line 93 of file NonlinearSystem.h.

93  : size_( systemSize )
94  {
95  f_.resize( size_, 0);
96  slopes_.resize( size_, 0);
97  x_.resize( size_, 0 );
98 
99  J_.resize( size_, size_, 0);
100  invJ_.resize( size_, size_, 0);
101 
102  x2.resize( size_, 0);
103  x1.resize( size_, 0);
104 
105  ri.nVec.resize( size_ );
106  dx_ = sqrt( numeric_limits<double>::epsilon() );
107  }
const size_t size_
vector_type slopes_
vector< double > nVec
matrix_type invJ_

Member Function Documentation

int NonlinearSystem::apply ( )
inline

Definition at line 116 of file NonlinearSystem.h.

117  {
118  return system(x_, f_);
119  }
int system(const vector_type &x, vector_type &f)
vector_type NonlinearSystem::compute_at ( const vector_type x)
inline

Definition at line 109 of file NonlinearSystem.h.

110  {
111  vector_type result( size_ );
112  system(x, result);
113  return result;
114  }
int system(const vector_type &x, vector_type &f)
ublas::vector< value_type > vector_type
const size_t size_
int NonlinearSystem::compute_jacobians ( const vector_type x,
bool  compute_inverse = true 
)
inline

Definition at line 121 of file NonlinearSystem.h.

References inverse().

122  {
123  for( size_t i = 0; i < size_; i++)
124  for( size_t j = 0; j < size_; j++)
125  {
126  vector_type temp = x;
127  temp[j] += dx_;
128  J_(i, j) = (compute_at(temp)[i] - compute_at(x)[i]) / dx_;
129  }
130 
131  // is_jacobian_valid_ = true;
132  // Keep the inverted J_ ready
133  //if(is_jacobian_valid_ and compute_inverse )
134  if( compute_inverse )
135  inverse( J_, invJ_ );
136 
137  return 0;
138  }
bool inverse(const ublas::matrix< T > &input, ublas::matrix< T > &inverse)
vector_type compute_at(const vector_type &x)
ublas::vector< value_type > vector_type
const size_t size_
matrix_type invJ_

+ Here is the call graph for this function:

void NonlinearSystem::correction_step ( )
inline

Makes the first guess. After this call the Newton method.

Definition at line 279 of file NonlinearSystem.h.

280  {
281  // Get the jacobian at current point. Notice that in this method, we
282  // don't have to compute inverse of jacobian
283 
284  vector_type direction( size_ );
285 
286  // Now take the largest step possible such that the value of system at
287  // (x_ - step ) is lower than the value of system as x_.
288  vector_type nextState( size_ );
289 
290  apply();
291 
292  unsigned int i = 0;
293 
294  double factor = 1e-2;
295  while( true )
296  {
297  i += 1;
298  compute_jacobians( x_, false );
299  // Make a move in either side of direction. In whichever direction
300  // the function decreases.
301  direction = ublas::prod( J_, f_ );
302  nextState = x_ - factor * direction;
303  if( ublas::norm_2( compute_at( nextState ) ) >= ublas::norm_2(compute_at(x_)))
304  factor = factor / 2.0;
305  else
306  {
307  cerr << "Correction term applied ";
308  x_ = nextState;
309  apply();
310  break;
311  }
312 
313  if ( i > 20 )
314  break;
315  }
316  }
vector_type compute_at(const vector_type &x)
ublas::vector< value_type > vector_type
int compute_jacobians(const vector_type &x, bool compute_inverse=true)
const size_t size_
bool NonlinearSystem::find_roots_gnewton ( double  tolerance = 1e-7,
size_t  max_iter = 50 
)
inline

Find roots using Newton-Raphson method.

Parameters
tolerance1e-7
max_iterMaximum number of iteration allowed , default 100
Returns
If successful, return true. Check the variable x_ at which the system f_ is close to zero (within the tolerance).

Definition at line 225 of file NonlinearSystem.h.

226  {
227  //tolerance = sqrt( numeric_limits<double>::epsilon() );
228  double norm2OfDiff = 1.0;
229  size_t iter = 0;
230  int status = apply();
231 
232  while( ublas::norm_2(f_) >= tolerance )
233  {
234  iter += 1;
235  compute_jacobians( x_, true );
236  vector_type correction = ublas::prod( invJ_, f_ );
237  x_ -= correction;
238 
239  // If could not compute the value of system successfully.
240  status = apply();
241  if( 0 != status )
242  return false;
243 
244  if( iter >= max_iter )
245  break;
246 
247  }
248 
249  ri.nIter = iter;
250 
251  if( iter >= max_iter )
252  return false;
253 
254  return true;
255  }
ublas::vector< value_type > vector_type
int compute_jacobians(const vector_type &x, bool compute_inverse=true)
matrix_type invJ_
template<typename T >
void NonlinearSystem::initialize ( const T &  x)
inline

Definition at line 141 of file NonlinearSystem.h.

References init().

142  {
144  init.resize(size_, 0);
145 
146  for( size_t i = 0; i < size_; i++)
147  init[i] = x[i];
148 
149  x_ = init;
150  apply();
151 
152  compute_jacobians( init );
153  }
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
Definition: main.cpp:150
ublas::vector< value_type > vector_type
int compute_jacobians(const vector_type &x, bool compute_inverse=true)
const size_t size_

+ Here is the call graph for this function:

value_type NonlinearSystem::slope ( unsigned int  which_dimen)
inline

Compute the slope of function in given dimension.

Parameters
which_dimenThe index of dimension.
Returns
Slope.

Definition at line 264 of file NonlinearSystem.h.

265  {
266  vector_type x = x_;
267  x[which_dimen] += dx_;
268  // x1 and x2 holds the f_ of system at x_ and x (which is x +
269  // some step)
270  system( x_, x1 );
271  system( x, x2 );
272  return ublas::norm_2( (x2 - x1)/dx_ );
273  }
int system(const vector_type &x, vector_type &f)
ublas::vector< value_type > vector_type
int NonlinearSystem::system ( const vector_type x,
vector_type f 
)
inline

Definition at line 168 of file NonlinearSystem.h.

169  {
170  int num_consv = ri.num_mols - ri.rank;
171  for ( size_t i = 0; i < ri.num_mols; ++i )
172  {
173  double temp = x[i] * x[i] ;
174 
175 #if 0
176  // if overflow
177  if ( std::isnan( temp ) or std::isinf( temp ) )
178  {
179  cerr << "Failed: ";
180  for( auto v : ri.nVec ) cerr << v << ", ";
181  cerr << endl;
182  return -1;
183  }
184 #endif
185  ri.nVec[i] = temp;
186  }
187 
188  vector< double > vels;
189  ri.pool->updateReacVelocities( &ri.nVec[0], vels );
190 
191  assert( vels.size() == static_cast< unsigned int >( ri.num_reacs ) );
192 
193  // y = Nr . v
194  // Note that Nr is row-echelon: diagonal and above.
195  for ( int i = 0; i < ri.rank; ++i )
196  {
197  double temp = 0;
198  for ( int j = i; j < ri.num_reacs; ++j )
199  temp += ri.Nr(i, j ) * vels[j];
200  f[i] = temp ;
201  }
202 
203  // dT = gamma.S - T
204  for ( int i = 0; i < num_consv; ++i )
205  {
206  double dT = - ri.T[i];
207  for ( size_t j = 0; j < ri.num_mols; ++j )
208  dT += ri.gamma(i, j) * x[j] * x[j];
209 
210  f[ i + ri.rank] = dT ;
211  }
212  return 0;
213  }
size_t num_mols
VoxelPools * pool
ublas::matrix< value_type > gamma
vector< double > nVec
ublas::matrix< value_type > Nr
double * T
void updateReacVelocities(const double *s, vector< double > &v) const
Definition: VoxelPools.cpp:350
string NonlinearSystem::to_string ( )
inline

Definition at line 155 of file NonlinearSystem.h.

156  {
157  stringstream ss;
158 
159  ss << "=======================================================";
160  ss << endl << setw(25) << "State of system: " ;
161  ss << " Argument: " << x_ << " Value : " << f_;
162  ss << endl << setw(25) << "Jacobian: " << J_;
163  ss << endl << setw(25) << "Inverse Jacobian: " << invJ_;
164  ss << endl;
165  return ss.str();
166  }
matrix_type invJ_

Member Data Documentation

double NonlinearSystem::dx_

Definition at line 321 of file NonlinearSystem.h.

vector_type NonlinearSystem::f_

Definition at line 323 of file NonlinearSystem.h.

matrix_type NonlinearSystem::invJ_

Definition at line 327 of file NonlinearSystem.h.

bool NonlinearSystem::is_f_positive_

Definition at line 330 of file NonlinearSystem.h.

bool NonlinearSystem::is_jacobian_valid_

Definition at line 329 of file NonlinearSystem.h.

matrix_type NonlinearSystem::J_

Definition at line 326 of file NonlinearSystem.h.

ReacInfo NonlinearSystem::ri

Definition at line 335 of file NonlinearSystem.h.

const size_t NonlinearSystem::size_

Definition at line 319 of file NonlinearSystem.h.

vector_type NonlinearSystem::slopes_

Definition at line 325 of file NonlinearSystem.h.

vector_type NonlinearSystem::x1

Definition at line 333 of file NonlinearSystem.h.

vector_type NonlinearSystem::x2

Definition at line 333 of file NonlinearSystem.h.

vector_type NonlinearSystem::x_

Definition at line 324 of file NonlinearSystem.h.


The documentation for this class was generated from the following file: