Flow123d  release_2.2.0-914-gf1a3a4f
linear_ode_analytic.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file linear_ode_analytic.cc
15  * @brief
16  */
17 
19 #include "input/accessors.hh"
20 #include "input/factory.hh"
21 #include "system/sys_profiler.hh"
22 
23 FLOW123D_FORCE_LINK_IN_CHILD(linearODEAnalytic)
24 
25 
26 using namespace Input::Type;
27 
28 const Record & LinearODEAnalytic::get_input_type() {
29  return Record("LinearODEAnalytic", "Evaluate analytic solution of the system of ODEs.")
31  .close();
32 }
33 
35  Input::register_class< LinearODEAnalytic, Input::Record >("LinearODEAnalytic") +
37 
39 {
40 }
41 
43 {
44 }
45 
46 void LinearODEAnalytic::update_solution(arma::vec& init_vector, arma::vec& output_vec)
47 {
48  if(step_changed_)
49  {
51  step_changed_ = false;
52  }
53 
54  output_vec = solution_matrix_ * init_vector;
55 }
56 
58 {
59  START_TIMER("ODEAnalytic::compute_matrix");
60 
61  OLD_ASSERT(system_matrix_.n_cols == system_matrix_.n_rows, "Matrix is not square.");
63 
64  double exponential, temp;
65  for(unsigned int i = 0; i < solution_matrix_.n_rows; i++)
66  {
67  exponential = std::exp(system_matrix_(i,i) * step_);
68  for(unsigned int j = 0; j < solution_matrix_.n_cols; j++)
69  {
70  temp = 1.0;
71  if( (i != j) && (system_matrix_(i,i) != 0.0) )
72  temp = -system_matrix_(j,i)/system_matrix_(i,i);
73 
74  solution_matrix_(j,i) = (1-exponential)*temp;
75  }
76  solution_matrix_(i,i) = exponential;
77  }
78 }
79 
80 bool LinearODEAnalytic::evaluate_time_constraint(double &time_constraint)
81 {
82  if (!system_matrix_changed_) return false;
83 
84  system_matrix_changed_ = false;
85 
86  // set time constraint to 1/max(diag(reaction_matrix_))
87  time_constraint = 0;
88  for (unsigned int k=0; k<system_matrix_.n_rows; k++)
89  time_constraint = std::max(time_constraint, -system_matrix_(k,k));
90 
91  time_constraint = 1 / time_constraint;
92 
93  return true;
94 }
arma::mat system_matrix_
the square matrix of ODE system
arma::mat solution_matrix_
The solution is computed only by a matrix multiplication (standard fundamental matrix).
This class implements the analytic solution of a system of linear ODEs with constant matrix...
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:598
Abstract linear system class.
Definition: equation.hh:37
static const Input::Type::Record & get_input_type()
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
#define OLD_ASSERT(...)
Definition: global_defs.h:131
bool evaluate_time_constraint(double &time_constraint) override
Estimate upper bound for time step. Return true if constraint was set.
bool system_matrix_changed_
Indicates that the system_matrix_ was recently updated.
static Input::Type::Abstract & get_input_type()
void update_solution(arma::vec &init_vector, arma::vec &output_vec) override
Updates solution of the ODEs system.
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
#define START_TIMER(tag)
Starts a timer with specified tag.
static const int registrar
Registrar of class to factory.
bool step_changed_
flag is true if the step has been changed
~LinearODEAnalytic(void)
Destructor.
double step_
the step of the numerical method
LinearODEAnalytic()
Default constructor is possible because the input record is not needed.
Record type proxy class.
Definition: type_record.hh:182
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180