Page MenuHomec4science

compute_time_average.cc
No OneTemporary

File Metadata

Created
Sun, Aug 4, 16:51

compute_time_average.cc

/**
* @file compute_time_average.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Wed Jul 09 21:59:47 2014
*
* @brief This allows to compute time averages of other computes
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "lm_common.hh"
#include "compute_time_average.hh"
#include "math_tools.hh"
#include "action_manager.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template <typename Cont>
ComputeTimeAverage<Cont>::ComputeTimeAverage(const std::string & name, UInt dim):
Compute<Cont>(name,1){
window_size = 0;
ActionManager::getManager().addObject(this);
}
/* -------------------------------------------------------------------------- */
template <typename Cont>
ComputeTimeAverage<Cont>::ComputeTimeAverage(const std::string & name,
ComponentLMInterface & d):
Compute<Cont>(name,d,1){
window_size = 0;
ActionManager::getManager().addObject(this,false);
}
/* -------------------------------------------------------------------------- */
template <typename Cont>
ComputeTimeAverage<Cont>::~ComputeTimeAverage(){
}
/* -------------------------------------------------------------------------- */
template <typename Cont>
void ComputeTimeAverage<Cont>::account(Cont & cont){
int k = (current_step+window_size-1)%this->frequency;
LM_ASSERT(k >= 0 && k < (int)window_size,"this should not happen");
const UInt Dim = cont.getDim();
if (k == 0) {
this->setDim(Dim);
average_data.resize(cont.size());
for (UInt i = 0; i < cont.size(); ++i)
average_data[i].init();
}
else {
if ((this->getDim() != cont.getDim()) ||
(average_data.size() != cont.size()) ){
DUMP("inconsistency in produced data size",DBG_WARNING);
return;
}
}
for (UInt i = 0; i < cont.size(); ++i)
average_data[i].account(cont.get(i));
this->last_accounted_step = current_step;
this->last_accounted_k = k;
}
/* -------------------------------------------------------------------------- */
template <typename Cont>
void ComputeTimeAverage<Cont>::build(Cont & cont){
#ifndef LM_OPTIMIZED
int k = (current_step+window_size-1)%this->frequency;
#endif //LM_OPTIMIZED
LM_ASSERT(k == (int)window_size-1,
"time average is not tallied to correct timesteps");
LM_ASSERT(last_accounted_k == window_size-1,
"time average is not tallied to correct timesteps");
LM_ASSERT(last_accounted_step == current_step,
"time average is not tallied to correct timesteps");
const UInt Dim = cont.getDim();
this->clear();
for (UInt i = 0; i < cont.size(); ++i)
this->add(average_data[i].result(cont.getCommGroup()));
this->name_computed.clear();
for (UInt i = 0; i < Dim; ++i) {
std::stringstream str;
if (cont.name_computed.size() > i)
str << cont.name_computed[i] << "-time-avg-" << i;
else
str << "field" << i << "-time-avg-" << i;
this->name_computed.push_back(str.str());
}
}
/* -------------------------------------------------------------------------- */
template <typename _Input>
bool ComputeTimeAverage<_Input>::shouldMakeAction(){
bool sM = this->doesStageMaskMatch();
if (!sM) return false;
this->setOneStep();
if (this->end_step >= current_step &&
this->start_step <= current_step)
if (this->frequency != UINT_MAX){
int k = (current_step+window_size-1)%this->frequency;
if (k >= 0 && k < (int)window_size){
DUMP("should proceed action " << this->getID()
<< " current_step = " << current_step
<< " start " << this->start_step
<< " end " << this->end_step,DBG_INFO);
return true;
}
}
return false;
}
/* -------------------------------------------------------------------------- */
template <typename _Input>
void ComputeTimeAverage<_Input>::build(){
build_phase = true;
if (!this->input) {
DUMP("this filter has no input",DBG_WARNING);
}
else this->input->accept(*this);
}
/* -------------------------------------------------------------------------- */
template <typename _Input>
void ComputeTimeAverage<_Input>::accept(ComponentLMInterface & visitor){
//test the input of the visitor
if (ComponentLMIn<Output> * ptr
= dynamic_cast<ComponentLMIn<Output> *>(&visitor)){
//if good, first build myself
this->build();
//then allow the visitor to visit me
ptr->visit(*this);
}
}
/* -------------------------------------------------------------------------- */
template <typename _Input>
void ComputeTimeAverage<_Input>::action(){
build_phase = false;
if (!this->input) {
DUMP("this filter has no input",DBG_WARNING);
}
else this->input->accept(*this);
}
/* -------------------------------------------------------------------------- */
template <typename _Input>
void ComputeTimeAverage<_Input>::visit(ComponentLMOut<_Input> & obj){
this->copyContainerInfo(obj.getOutput());
if (obj.getOutput().getRelease() <= this->getRelease()) return;
Communicator & comm = Communicator::getCommunicator();
CommGroup group = obj.getOutput().getCommGroup();
if (comm.amIinGroup(group)){
if (build_phase) {
this->copyReleaseInfo(obj);
this->build(obj);
}
else this->account(obj);
}
}
/* -------------------------------------------------------------------------- */
/* LMDESC TIMEAVG
This computes a time averaged version of a set of reals
*/
/* LMEXAMPLE
COMPUTE disp EXTRACT INPUT md FIELD displacement\\
COMPUTE time_average TIMEAVG INPUT disp\\
*/
/* LMHERITANCE action_interface*/
template <typename _Input>
void ComputeTimeAverage<_Input>::declareParams(){
ActionInterface::declareParams();
/* LMKEYWORD WINDOW
Number of steps to be taken into account for average
Must be smaller than FREQ
*/
this->parseKeyword("WINDOW",window_size);
}
/* -------------------------------------------------------------------------- */
DECLARE_COMPUTE_REAL(ComputeTimeAverage);
__END_LIBMULTISCALE__

Event Timeline