• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

step/stepcore

  • sources
  • kde-4.12
  • kdeedu
  • step
  • stepcore
eulersolver.cc
Go to the documentation of this file.
1 /* This file is part of StepCore library.
2  Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
3 
4  StepCore library is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  StepCore library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with StepCore; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include "eulersolver.h"
20 #include "util.h"
21 
22 #include <cmath>
23 #include <cstring>
24 #include <QtGlobal>
25 
26 namespace StepCore {
27 
28 STEPCORE_META_OBJECT(GenericEulerSolver, QT_TRANSLATE_NOOP("ObjectClass", "GenericEulerSolver"), QT_TR_NOOP("Generic Euler solver"), MetaObject::ABSTRACT, STEPCORE_SUPER_CLASS(Solver),)
29 STEPCORE_META_OBJECT(EulerSolver, QT_TRANSLATE_NOOP("ObjectClass", "EulerSolver"), QT_TR_NOOP("Non-adaptive Euler solver"), 0, STEPCORE_SUPER_CLASS(GenericEulerSolver),)
30 STEPCORE_META_OBJECT(AdaptiveEulerSolver, QT_TRANSLATE_NOOP("ObjectClass", "AdaptiveEulerSolver"), QT_TR_NOOP("Adaptive Euler solver"), 0, STEPCORE_SUPER_CLASS(GenericEulerSolver),)
31 
32 void GenericEulerSolver::init()
33 {
34  _yerr.resize(_dimension);
35  _ytemp.resize(_dimension);
36  _ydiff.resize(_dimension);
37  _ytempvar.resize(_dimension);
38  _ydiffvar.resize(_dimension);
39 }
40 
41 void GenericEulerSolver::fini()
42 {
43 }
44 
45 int GenericEulerSolver::doCalcFn(double* t, const VectorXd* y,
46  const VectorXd* yvar, VectorXd* f, VectorXd* fvar)
47 {
48  int ret = _function(*t, y->data(), yvar?yvar->data():0,
49  f ? f->data() : _ydiff.data(),
50  fvar?fvar->data():0, _params);
51  //if(f != NULL) std::memcpy(f, _ydiff, _dimension*sizeof(*f));
52  return ret;
53 }
54 
55 int GenericEulerSolver::doStep(double t, double stepSize, VectorXd* y, VectorXd* yvar)
56 {
57  _localError = 0;
58  _localErrorRatio = 0;
59 
60  //int ret = _function(t, y, _ydiff, _params);
61  //if(ret != OK) return ret;
62 
63  VectorXd* ytempvar = yvar ? &_ytempvar : 0;
64  VectorXd* ydiffvar = yvar ? &_ydiffvar : 0;
65 
66  // Error estimation: integration with timestep = stepSize
67  _yerr = - *y - stepSize*_ydiff;
68  // First integration with timestep = stepSize/2
69  _ytemp = *y + (stepSize/2)*_ydiff;
70 
71  if(yvar) { // error calculation
72  *ytempvar = (yvar->cwise().sqrt()+(stepSize/2)*(*ydiffvar)).cwise().square();
73  }
74 
75  int ret = _function(t + stepSize/2, _ytemp.data(), ytempvar?ytempvar->data():0,
76  _ydiff.data(), ydiffvar?ydiffvar->data():0, _params);
77  if(ret != OK) return ret;
78 
79  for(int i=0; i<_dimension; ++i) {
80  // Second integration with timestep = stepSize/2
81  _ytemp[i] += stepSize/2*_ydiff[i];
82  // Error estimation and solution improve
83  _yerr[i] += _ytemp[i];
84  // Solution improvement
85  _ytemp[i] += _yerr[i];
86  // Maximal error calculation
87  double error = fabs(_yerr[i]);
88  if(error > _localError) _localError = error;
89  // Maximal error ration calculation
90  double errorRatio = error / (_toleranceAbs + _toleranceRel * fabs(_ytemp[i]));
91  if(errorRatio > _localErrorRatio) _localErrorRatio = errorRatio;
92  }
93 
94  if(_localErrorRatio > 1.1) return ToleranceError;
95 
96  // XXX
97  ret = _function(t + stepSize, _ytemp.data(), ytempvar?ytempvar->data():0,
98  _ydiff.data(), ydiffvar?ydiffvar->data():0, _params);
99  if(ret != OK) return ret;
100 
101  *y = _ytemp;
102 
103  if(yvar) { // error calculation
104  // XXX: Strictly speaking yerr are correlated between steps.
105  // For now we are using the following formula which
106  // assumes that yerr are equal and correlated on adjacent steps
107  // TODO: improve this formula
108  *yvar = (ytempvar->cwise().sqrt()+(stepSize/2)*(*ydiffvar)).cwise().square()
109  + 3*_yerr.cwise().square();
110  }
111 
112  return OK;
113 }
114 
115 int GenericEulerSolver::doEvolve(double* t, double t1, VectorXd* y, VectorXd* yvar)
116 {
117  // XXX: add better checks
118  // XXX: replace asserts by error codes here
119  // or by check in world
120  // XXX: do the same checks in doStep
121  STEPCORE_ASSERT_NOABORT(*t + _stepSize != *t);
122  STEPCORE_ASSERT_NOABORT(*t != t1);
123 
124  #ifndef NDEBUG
125  double realStepSize = fmin( _stepSize, t1 - *t );
126  #endif
127 
128  const double S = 0.9;
129  int result;
130 
131  VectorXd* ydiffvar = yvar ? &_ydiffvar : 0;
132 
133  result = _function(*t, y->data(), yvar?yvar->data():0, _ydiff.data(), ydiffvar?ydiffvar->data():0, _params);
134  if(result != OK) return result;
135 
136  while(*t < t1) {
137  STEPCORE_ASSERT_NOABORT(t1-*t > realStepSize/1000);
138 
139  //double t11 = _stepSize < t1-*t ? *t + _stepSize : t1;
140  double t11 = t1 - *t > _stepSize*1.01 ? *t + _stepSize : t1;
141  result = doStep(*t, t11 - *t, y, yvar);
142 
143  if(result != OK && result != ToleranceError) return result;
144 
145  if(_adaptive) {
146  if(_localErrorRatio > 1.1) {
147  double r = S / _localErrorRatio;
148  if(r<0.2) r = 0.2;
149  _stepSize *= r;
150  } else if(_localErrorRatio < 0.5) {
151  double r = S / pow(_localErrorRatio, 0.5);
152  if(r>5.0) r = 5.0;
153  if(r<1.0) r = 1.0;
154  double newStepSize = _stepSize*r;
155  if(newStepSize < t1 - t11) _stepSize = newStepSize;
156  }
157  if(result != OK) {
158  result = _function(*t, y->data(), yvar?yvar->data():0, _ydiff.data(),
159  ydiffvar?ydiffvar->data():0, _params);
160  if(result != OK) return result;
161  continue;
162  }
163  } else {
164  if(result != OK) return ToleranceError;
165  }
166 
167  *t = t11;
168  }
169  return OK;
170 }
171 
172 } // namespace StepCore
173 
StepCore::Solver::_stepSize
double _stepSize
Definition: solver.h:157
StepCore::GenericEulerSolver::doStep
int doStep(double t, double stepSize, VectorXd *y, VectorXd *yvar)
Definition: eulersolver.cc:55
STEPCORE_ASSERT_NOABORT
#define STEPCORE_ASSERT_NOABORT(expr)
Definition: util.h:58
StepCore::GenericEulerSolver::_yerr
VectorXd _yerr
Definition: eulersolver.h:70
StepCore::Solver::_toleranceAbs
double _toleranceAbs
Definition: solver.h:158
StepCore::GenericEulerSolver::_ytemp
VectorXd _ytemp
Definition: eulersolver.h:71
StepCore::GenericEulerSolver::_adaptive
bool _adaptive
Definition: eulersolver.h:69
StepCore::GenericEulerSolver::fini
void fini()
Definition: eulersolver.cc:41
StepCore::STEPCORE_SUPER_CLASS
STEPCORE_SUPER_CLASS(CollisionSolver)
StepCore::Solver::OK
Definition: solver.h:142
StepCore::Solver::_localErrorRatio
double _localErrorRatio
Definition: solver.h:161
StepCore::QT_TRANSLATE_NOOP
QT_TRANSLATE_NOOP("ObjectClass","GJKCollisionSolver")
StepCore::Solver::_params
void * _params
Definition: solver.h:155
StepCore::Solver::_localError
double _localError
Definition: solver.h:160
StepCore::MetaObject::ABSTRACT
Class is abstract.
Definition: object.h:180
StepCore::Solver::_toleranceRel
double _toleranceRel
Definition: solver.h:159
util.h
Internal file.
StepCore::QT_TR_NOOP
QT_TR_NOOP("Errors class for CoulombForce")
StepCore::GenericEulerSolver::doEvolve
int doEvolve(double *t, double t1, VectorXd *y, VectorXd *yvar)
Integrate.
Definition: eulersolver.cc:115
StepCore::GenericEulerSolver::_ydiffvar
VectorXd _ydiffvar
Definition: eulersolver.h:74
StepCore::Solver::_function
Function _function
Definition: solver.h:154
StepCore::Solver::_dimension
int _dimension
Definition: solver.h:153
StepCore::GenericEulerSolver::doCalcFn
int doCalcFn(double *t, const VectorXd *y, const VectorXd *yvar=0, VectorXd *f=0, VectorXd *fvar=0)
Calculate function value.
Definition: eulersolver.cc:45
StepCore::GenericEulerSolver::_ydiff
VectorXd _ydiff
Definition: eulersolver.h:72
StepCore::Solver::ToleranceError
Definition: solver.h:143
StepCore::STEPCORE_META_OBJECT
STEPCORE_META_OBJECT(CollisionSolver, QT_TRANSLATE_NOOP("ObjectClass","CollisionSolver"),"CollisionSolver", MetaObject::ABSTRACT, STEPCORE_SUPER_CLASS(Object), STEPCORE_PROPERTY_RW(double, toleranceAbs, QT_TRANSLATE_NOOP("PropertyName","toleranceAbs"), STEPCORE_UNITS_1, QT_TR_NOOP("Allowed absolute tolerance"), toleranceAbs, setToleranceAbs) STEPCORE_PROPERTY_R_D(double, localError, QT_TRANSLATE_NOOP("PropertyName","localError"), STEPCORE_UNITS_1, QT_TR_NOOP("Maximal local error during last step"), localError)) STEPCORE_META_OBJECT(GJKCollisionSolver
eulersolver.h
GenericEulerSolver, EulerSolver and AdaptiveEulerSolver classes.
StepCore::AdaptiveEulerSolver
Adaptive Euler solver.
Definition: eulersolver.h:93
StepCore::GenericEulerSolver::_ytempvar
VectorXd _ytempvar
Definition: eulersolver.h:73
StepCore::VectorXd
Eigen::VectorXd VectorXd
Definition: vector.h:38
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:43:06 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

step/stepcore

Skip menu "step/stepcore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal