forked from lijiext/lammps
770 lines
30 KiB
C++
770 lines
30 KiB
C++
// The type of filter used should be determined by the
|
|
// integrator since filtering much match the time integration scheme
|
|
|
|
|
|
#ifndef TIME_FILTER_H
|
|
#define TIME_FILTER_H
|
|
|
|
#include <set>
|
|
|
|
#include "ATC_TypeDefs.h"
|
|
#include "MatrixLibrary.h"
|
|
#include "ATC_Error.h"
|
|
|
|
namespace ATC {
|
|
|
|
// forward declarations
|
|
class ATC_Method;
|
|
class TimeFilter;
|
|
|
|
/**
|
|
* @class TimeFilterManager
|
|
* @brief Handles parsing and parameter storage for time filters
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterManager
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
class TimeFilterManager {
|
|
|
|
public:
|
|
|
|
/** enumeration for the functional form underlying the filter */
|
|
enum TimeFilterType {
|
|
NO_FILTER=0, // default
|
|
EXPONENTIAL_FILTER,
|
|
STEP_FILTER
|
|
};
|
|
|
|
/** enumeration for the functional form underlying the filter */
|
|
enum FilterIntegrationType {
|
|
INSTANTANEOUS=0, //default
|
|
CRANK_NICHOLSON,
|
|
IMPLICIT_EXPLICIT,
|
|
EXPLICIT_IMPLICIT,
|
|
EXPLICIT,
|
|
IMPLICIT,
|
|
IMPLICIT_UPDATE
|
|
};
|
|
|
|
// constructor
|
|
TimeFilterManager(ATC_Method * atc);
|
|
|
|
// destructor
|
|
~TimeFilterManager();
|
|
|
|
/** parser/modifier */
|
|
bool modify(int narg, char **arg);
|
|
|
|
/** pre time integration */
|
|
void initialize();
|
|
|
|
/** get filter base function */
|
|
TimeFilterType filter_type() const {return filterType_;};
|
|
|
|
/** return filtering time scale */
|
|
double filter_scale() const {return filterScale_;};
|
|
|
|
/** check if dynamics should be filtering */
|
|
bool filter_dynamics() const {return useFilter_;};
|
|
|
|
/** check if variables should be filtered */
|
|
bool filter_variables() const {return (useFilter_ || equilibrateFilter_);};
|
|
|
|
/** flag for if reset is needed */
|
|
bool need_reset() const {return needReset_;};
|
|
|
|
/** flag if ending equilibration */
|
|
bool end_equilibrate() const {return endEquilibrate_;};
|
|
|
|
/** get pointer to ATC transfer methods */
|
|
ATC_Method * atc() {return atc_;};
|
|
|
|
/** construct the appropriate time filter */
|
|
TimeFilter * construct(const FilterIntegrationType type = CRANK_NICHOLSON);
|
|
|
|
protected:
|
|
|
|
TimeFilterManager(){};
|
|
|
|
/** pointer to access ATC methods */
|
|
ATC_Method * atc_;
|
|
|
|
/** description of underlying function form of filter */
|
|
TimeFilterType filterType_;
|
|
|
|
/** filtering time scale */
|
|
double filterScale_;
|
|
|
|
/** flag to see if filtering is active */
|
|
bool useFilter_;
|
|
|
|
/** flag to see if we are equilibrating the filtered variables */
|
|
bool equilibrateFilter_;
|
|
|
|
/** flag to reset data */
|
|
bool needReset_;
|
|
|
|
/** flag to denote switch from equilibration to integration */
|
|
bool endEquilibrate_;
|
|
|
|
/** set to store all time filters for later deletion */
|
|
std::set<TimeFilter * > timeFilterSet_;
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilter
|
|
* @brief Base class for various temporal filters of atomistic quantities
|
|
* default behavior is no filter
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilter
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
|
|
class TimeFilter {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilter(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilter(){};
|
|
|
|
/** pre time integration */
|
|
virtual void initialize(){};
|
|
|
|
/** pre time integration with a target for an initial condition */
|
|
virtual void initialize(const MATRIX & target){initialize();};
|
|
|
|
/** Step 1:
|
|
apply first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt)
|
|
{ TimeFilter::unFilteredQuantityOld_ = unFilteredQuantity;}
|
|
|
|
/** Step 2:
|
|
apply second step in a time filter update in pre integration phase */
|
|
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** Step 3:
|
|
apply first step in a time filter update in post integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt)
|
|
{ filteredQuantity = unFilteredQuantity;};
|
|
|
|
/** Step 4:
|
|
apply second step in a time filter update in post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt)
|
|
{ filteredQuantity = unFilteredQuantity;}
|
|
|
|
/** coefficient multipling unfiltered terms in apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return 0.;};
|
|
|
|
/** coefficient multipling old filtered terms in apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return 0.;};
|
|
|
|
/** coefficient multipling unfiltered terms in apply_post_step1 method */
|
|
virtual double unfiltered_coefficient_post_s1(double dt){return 0.;};
|
|
|
|
/** coefficient multipling old filtered terms in apply_post_step1 method */
|
|
virtual double filtered_coefficient_post_s1(double dt){return 0.;};
|
|
|
|
/** coefficient multipling unfiltered terms in apply_pre_step2 method */
|
|
virtual double unfiltered_coefficient_pre_s2(double dt){return 0.;};
|
|
|
|
/** coefficient multipling old filtered terms in apply_pre_step2 method */
|
|
virtual double filtered_coefficient_pre_s2(double dt){return 0.;};
|
|
|
|
/** coefficient multipling unfiltered terms in apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s2(double dt){return 0.;};
|
|
|
|
/** coefficient multipling old filtered terms in apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s2(double dt){return 0.;};
|
|
|
|
/** rate of filtered quantity to be called in post integration phase */
|
|
virtual void rate(MATRIX & rate,
|
|
const MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt = 0.0)
|
|
{ rate = 1/dt*(unFilteredQuantity - TimeFilter::unFilteredQuantityOld_);};
|
|
|
|
protected:
|
|
|
|
TimeFilter(){};
|
|
|
|
/** pointer to access ATC methods */
|
|
ATC_Method * atc_;
|
|
|
|
/** filtering time scale */
|
|
double filterScale_;
|
|
|
|
/** filter type */
|
|
TimeFilterManager::TimeFilterType filterType_;
|
|
|
|
/** member data to track old unfiltered values */
|
|
DENS_MAT unFilteredQuantityOld_;
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterExponential
|
|
* @brief Base class for filters using an exponential kernel,
|
|
* derived classes implement specific integration schemes
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterExponential
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
class TimeFilterExponential : public TimeFilter {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterExponential(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterExponential(){};
|
|
/** apply first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** apply second step in a time filter update in pre integration phase */
|
|
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** apply first step in a time filter update in post integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** apply second step in a time filter update in post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** time rate of filtered quantity */
|
|
virtual void rate(MATRIX & rate,
|
|
const MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
double dt = 0)
|
|
{ double tau = TimeFilter::filterScale_;
|
|
rate = 1/tau*(unfilteredQuantity - filteredQuantity); };
|
|
|
|
protected:
|
|
|
|
TimeFilterExponential(){};
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// filter integration functions not associated
|
|
// with any particular class
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
void update_filter(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
MATRIX & unfilteredQuantityOld,
|
|
double tau,
|
|
double dt)
|
|
{
|
|
filteredQuantity *= 1./(1./dt+1./(2*tau))*((1./dt-1./(2*tau)));
|
|
filteredQuantity += 1./(1./dt+1./(2*tau))*( 1./(2*tau)*(unfilteredQuantity+unfilteredQuantityOld));
|
|
unfilteredQuantityOld = unfilteredQuantity;
|
|
}
|
|
|
|
void add_to_filter(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
MATRIX & unfilteredQuantityOld,
|
|
double tau,
|
|
double dt)
|
|
{
|
|
filteredQuantity += 1./(1./dt+1./(2.*tau))*( 1./(2.*tau))*unfilteredQuantity;
|
|
unfilteredQuantityOld += unfilteredQuantity;
|
|
};
|
|
|
|
double unfiltered_coef(double tau, double dt)
|
|
{ return 1./(1./dt+1./(2.*tau))*( 1./(2.*tau)); };
|
|
|
|
double filtered_coef(double tau, double dt)
|
|
{ return 1./(1./dt+1./(2.*tau))*( 1./dt-1./(2*tau) ); };
|
|
|
|
void update_filter_implicit(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
double tau,
|
|
double dt)
|
|
{
|
|
filteredQuantity /= 1.0 + dt/tau;
|
|
filteredQuantity += (dt)/(tau+dt)*unfilteredQuantity;
|
|
}
|
|
|
|
void add_to_filter_implicit(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
double tau,
|
|
double dt)
|
|
{ filteredQuantity += (1./(1.+dt/tau))*(dt/tau)*unfilteredQuantity; };
|
|
|
|
double unfiltered_coef_implicit(double tau, double dt)
|
|
{ return (1./(1.+dt/tau))*(dt/tau); };
|
|
|
|
double filtered_coef_implicit(double tau, double dt)
|
|
{ return (1./(1.+dt/tau)); };
|
|
|
|
void update_filter_explicit(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
double tau,
|
|
double dt)
|
|
{
|
|
filteredQuantity *= (1.-(dt/tau));
|
|
filteredQuantity += (dt/tau)*unfilteredQuantity;
|
|
}
|
|
|
|
void add_to_filter_explicit(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
double tau,
|
|
double dt)
|
|
{ filteredQuantity += (dt/tau)*unfilteredQuantity; };
|
|
|
|
double unfiltered_coef_explicit(double tau, double dt)
|
|
{ return (dt/tau); };
|
|
|
|
double filtered_coef_explicit(double tau, double dt)
|
|
{ return (1.-(dt/tau)); };
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterCrankNicolson
|
|
* @brief Time Filter using Crank-Nicolson advancement of filtered quantity ODE's
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterCrankNicolson
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
class TimeFilterCrankNicolson : public TimeFilterExponential {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterCrankNicolson(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterCrankNicolson(){};
|
|
|
|
/** pre time integration */
|
|
virtual void initialize(){throw ATC_Error("TimeFilterCrankNicolson::initialize() an initial condition is required for this time filter");};
|
|
|
|
/** pre time integration with an initial condition */
|
|
virtual void initialize(const MATRIX & target);
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter(filteredQuantity,unFilteredQuantity,unFilteredQuantityOld_,TimeFilter::filterScale_,dt); };
|
|
|
|
/** applies first step in a time filter update after the pre integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ add_to_filter(filteredQuantity,unFilteredQuantity,unFilteredQuantityOld_,TimeFilter::filterScale_,dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter(filteredQuantity,unFilteredQuantity,unFilteredQuantityOld_,TimeFilter::filterScale_,dt); };
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return unfiltered_coef(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return filtered_coef(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s2(double dt){return unfiltered_coef(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s2(double dt){return filtered_coef(TimeFilter::filterScale_,dt);};
|
|
|
|
protected:
|
|
|
|
TimeFilterCrankNicolson();
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterExplicit
|
|
* @brief Time Filter using explicit advancement of filtered quantity ODE's
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterExplicit
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
class TimeFilterExplicit : public TimeFilterExponential {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterExplicit(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterExplicit(){};
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** applies first step in a time filter update after the pre integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ add_to_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return unfiltered_coef_explicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return filtered_coef_explicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s2(double dt){return unfiltered_coef_explicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s2(double dt){return filtered_coef_explicit(TimeFilter::filterScale_,dt);};
|
|
|
|
protected:
|
|
|
|
TimeFilterExplicit();
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterImplicit
|
|
* @brief Time Filter using implicit advancement of filtered quantity ODE's
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterImplicit
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
class TimeFilterImplicit : public TimeFilterExponential {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterImplicit(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterImplicit(){};
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return filtered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s2(double dt){return unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s2(double dt){return filtered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
protected:
|
|
|
|
TimeFilterImplicit();
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterImplicitExplicit
|
|
* @brief Time Filter using two-step implicit/explicit advancement of filtered quantity ODE's
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterImplicitExplicit
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
class TimeFilterImplicitExplicit : public TimeFilterExponential {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterImplicitExplicit(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterImplicitExplicit(){};
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,0.5*dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,0.5*dt); };
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return unfiltered_coef_implicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return filtered_coef_implicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s2(double dt){return unfiltered_coef_explicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s2(double dt){return filtered_coef_explicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
protected:
|
|
|
|
TimeFilterImplicitExplicit();
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterExplicitImplicit
|
|
* @brief Time Filter using two-step explicit/implicit advancement of filtered quantity ODE's
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterExplicitImplicit
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
class TimeFilterExplicitImplicit : public TimeFilterExponential {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterExplicitImplicit(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterExplicitImplicit(){};
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,0.5*dt); };
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ add_to_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,0.5*dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,0.5*dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ add_to_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,0.5*dt); };
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return unfiltered_coef_explicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return filtered_coef_explicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s1(double dt){return unfiltered_coef_implicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s1(double dt){return filtered_coef_implicit(TimeFilter::filterScale_,0.5*dt);};
|
|
|
|
protected:
|
|
|
|
TimeFilterExplicitImplicit();
|
|
|
|
};
|
|
|
|
/**
|
|
* @class TimeFilterImplicitUpdate
|
|
* @brief Time Filter using implicit advancement of filtered quantity ODE's but adds on contribution at the end of the second step
|
|
*/
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterImplicitUpdate
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
class TimeFilterImplicitUpdate : public TimeFilterExponential {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterImplicitUpdate(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterImplicitUpdate(){};
|
|
|
|
/** applies first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** applies second step in a time filter update in the post integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
MATRIX const & unFilteredQuantity,
|
|
double dt)
|
|
{ add_to_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
|
virtual double unfiltered_coefficient_pre_s1(double dt){return unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_pre_step1 method */
|
|
virtual double filtered_coefficient_pre_s1(double dt){return filtered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
|
virtual double unfiltered_coefficient_post_s1(double dt){return unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
/** return coefficient multipling old filtered terms in the apply_post_step2 method */
|
|
virtual double filtered_coefficient_post_s1(double dt){return filtered_coef_implicit(TimeFilter::filterScale_,dt);};
|
|
|
|
protected:
|
|
|
|
TimeFilterImplicitUpdate();
|
|
|
|
};
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TimeFilterStep
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
class TimeFilterStep : public TimeFilter {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
TimeFilterStep(TimeFilterManager & timeFilterManager);
|
|
|
|
// destructor
|
|
virtual ~TimeFilterStep(){};
|
|
|
|
/** pre time integration */
|
|
virtual void initialize(const MATRIX & target);
|
|
|
|
/** apply first step in a time filter update in the pre integration phase */
|
|
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** apply second step in a time filter update in pre integration phase */
|
|
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** apply first step in a time filter update in post integration phase */
|
|
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt) {};
|
|
|
|
/** apply second step in a time filter update in post integration phase */
|
|
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
|
const MATRIX & unFilteredQuantity,
|
|
double dt)
|
|
{ update_filter(filteredQuantity, unFilteredQuantity,
|
|
TimeFilter::unFilteredQuantityOld_, TimeFilter::filterScale_, dt);
|
|
}
|
|
|
|
/** time rate of filtered quantity */
|
|
virtual void rate(MATRIX & rate,
|
|
const MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
double dt = 0)
|
|
{ rate = 1/elapsedTime_*(unfilteredQuantity - filteredQuantity); }
|
|
|
|
protected:
|
|
|
|
TimeFilterStep(){};
|
|
|
|
double elapsedTime_;
|
|
|
|
void update_filter(MATRIX & filteredQuantity,
|
|
const MATRIX & unfilteredQuantity,
|
|
MATRIX & unfilteredQuantitySum,
|
|
double tau,
|
|
double dt)
|
|
{
|
|
|
|
// this average and the next
|
|
if (elapsedTime_ == 0.0) { // a reset
|
|
elapsedTime_ = dt;
|
|
unfilteredQuantitySum = unfilteredQuantity*dt;
|
|
filteredQuantity = unfilteredQuantity;
|
|
}
|
|
else { // a running average
|
|
elapsedTime_ += dt;
|
|
unfilteredQuantitySum += unfilteredQuantity*dt;
|
|
filteredQuantity = unfilteredQuantitySum;
|
|
filteredQuantity /= elapsedTime_;
|
|
}
|
|
if (elapsedTime_ >= tau && tau > 0) {
|
|
elapsedTime_ = 0.0;
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|