$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

timePeriodicSignal.hh

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00025 #ifndef TIME_PERIODIC_SIGNAL_HH
00026 #define TIME_PERIODIC_SIGNAL_HH
00027 
00028 #include "core/runTimeDiagnostics.h"
00029 #include "core/util.h"
00030 #include "spline.h"
00031 #include "timePeriodicSignal.h"
00032 #include <limits>
00033 
00034 namespace plb {
00035 
00036 template<typename T>
00037 TimePeriodicSignal<T>::TimePeriodicSignal(std::string fname)
00038     : signal(fname)
00039 {
00040     std::vector<T> const& t = signal.getAbscissae();
00041     std::vector<T> const& x = signal.getOrdinates();
00042     plint n = (plint) t.size();
00043 
00044 #ifdef PLB_DEBUG
00045     T eps = 100.0 * std::numeric_limits<T>::epsilon();
00046     if (!util::fpequal(t[0], (T) 0, eps))
00047         plbLogicError("The first given value of the signal must be at time 0.0.");
00048     if (!util::fpequal(x[0], x[n-1], eps))
00049         plbLogicError("The last given value of the signal must be equal to the first one.");
00050 #endif // PLB_DEBUG
00051 
00052     period = t[n-1] - t[0];
00053 
00054 #ifdef PLB_DEBUG
00055     if (util::fpequal(period, (T) 0, eps))
00056         plbLogicError("The period must be greater than zero.");
00057 #endif // PLB_DEBUG
00058 }
00059 
00060 template<typename T>
00061 TimePeriodicSignal<T>::TimePeriodicSignal(std::vector<T> const& t, std::vector<T> const& x)
00062     : signal(t, x)
00063 {
00064     plint n = (plint) t.size();
00065     PLB_ASSERT(n >= 1);
00066 
00067 #ifdef PLB_DEBUG
00068     T eps = 100.0 * std::numeric_limits<T>::epsilon();
00069     if (!util::fpequal(t[0], (T) 0, eps))
00070         plbLogicError("The first given value of the signal must be at time 0.0.");
00071     if (!util::fpequal(x[0], x[n-1], eps))
00072         plbLogicError("The last given value of the signal must be equal to the first one.");
00073 #endif // PLB_DEBUG
00074 
00075     period = t[n-1] - t[0];
00076 
00077 #ifdef PLB_DEBUG
00078     if (util::fpequal(period, (T) 0, eps))
00079         plbLogicError("The period must be greater than zero.");
00080 #endif // PLB_DEBUG
00081 }
00082 
00083 template<typename T>
00084 TimePeriodicSignal<T>* TimePeriodicSignal<T>::clone() const {
00085     return new TimePeriodicSignal<T>(*this);
00086 }
00087 
00088 template<typename T>
00089 T TimePeriodicSignal<T>::getSignalValue(T t) const
00090 {
00091 #ifdef PLB_DEBUG
00092     static T eps = 100.0 * std::numeric_limits<T>::epsilon();
00093     if (t < (T) 0 && !util::fpequal(t, (T) 0, eps))
00094         plbLogicError("The time value must be greater equal to 0.0.");
00095 #endif // PLB_DEBUG
00096 
00097     T trel = t - (plint) (t/period) * period;
00098     return signal.getFunctionValue(trel);
00099 }
00100 
00101 template<typename T>
00102 T TimePeriodicSignal<T>::getDerivativeValue(T t) const
00103 {
00104 #ifdef PLB_DEBUG
00105     static T eps = 100.0 * std::numeric_limits<T>::epsilon();
00106     if (t < (T) 0 && !util::fpequal(t, (T) 0, eps))
00107         plbLogicError("The time value must be greater equal to 0.0.");
00108 #endif // PLB_DEBUG
00109 
00110     T trel = t - (plint) (t/period) * period;
00111     return signal.getDerivativeValue(trel);
00112 }
00113 
00114 template<typename T>
00115 T TimePeriodicSignal<T>::getSecondDerivativeValue(T t) const
00116 {
00117 #ifdef PLB_DEBUG
00118     static T eps = 100.0 * std::numeric_limits<T>::epsilon();
00119     if (t < (T) 0 && !util::fpequal(t, (T) 0, eps))
00120         plbLogicError("The time value must be greater equal to 0.0.");
00121 #endif // PLB_DEBUG
00122 
00123     T trel = t - (plint) (t/period) * period;
00124     return signal.getSecondDerivativeValue(trel);
00125 }
00126 
00127 template<typename T>
00128 T TimePeriodicSignal<T>::getThirdDerivativeValue(T t) const
00129 {
00130 #ifdef PLB_DEBUG
00131     static T eps = 100.0 * std::numeric_limits<T>::epsilon();
00132     if (t < (T) 0 && !util::fpequal(t, (T) 0, eps))
00133         plbLogicError("The time value must be greater equal to 0.0.");
00134 #endif // PLB_DEBUG
00135 
00136     T trel = t - (plint) (t/period) * period;
00137     return signal.getThirdDerivativeValue(trel);
00138 }
00139 
00140 template<typename T>
00141 T TimePeriodicSignal<T>::getIntegralValue() const
00142 {
00143     return signal.getIntegralValue();
00144 }
00145 
00146 template<typename T>
00147 T TimePeriodicSignal<T>::getIntegralValue(T tmin, T tmax) const
00148 {
00149     static T eps = 100.0 * std::numeric_limits<T>::epsilon();
00150 
00151 #ifdef PLB_DEBUG
00152     if (tmin > tmax)
00153         plbLogicError("Invalid arguments.");
00154     if (tmin < (T) 0 && !util::fpequal(tmin, (T) 0, eps))
00155         plbLogicError("Invalid arguments.");
00156     if (tmax < (T) 0 && !util::fpequal(tmax, (T) 0, eps))
00157         plbLogicError("Invalid arguments.");
00158 #endif // PLB_DEBUG
00159 
00160     if (util::fpequal(tmin, tmax, eps))
00161         return ((T) 0);
00162 
00163     T dt = tmax - tmin;
00164     plint k = (plint) (dt / period);
00165 
00166     T integral = (k == 0) ? (T) 0 : k * signal.getIntegralValue();
00167 
00168     T tmin_rel = tmin - (plint) (tmin/period) * period;
00169     T tmax_rel = tmax - (plint) (tmax/period) * period;
00170 
00171     integral += signal.getIntegralValue(tmin_rel, tmax_rel);
00172 
00173     return integral;
00174 }
00175 
00176 }  // namespace plb
00177 
00178 #endif  // TIME_PERIODIC_SIGNAL_HH