Page MenuHomec4science

filter_threshold.cc
No OneTemporary

File Metadata

Created
Sun, Aug 4, 15:16

filter_threshold.cc

/**
* @file filter_threshold.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
*
* @date Wed Jul 09 21:59:47 2014
*
* @brief This filter allows to select DOFs based on a threhold criterion
*
* @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 "filter_threshold.hh"
#include <limits>
#include "sstream"
#include "filter_manager.hh"
#include "lib_md.hh"
#include "lib_dd.hh"
#include "lib_continuum.hh"
#include "ref_point_data.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
FilterID sillyID("You forgot to set the parameter 'COMPUTE' which is a mandatory field");
template<typename _Input>
FilterThreshold<_Input>::FilterThreshold(const FilterID name, FilterInterface & f)
:Filter<_Input>(name,f),
min(lm_real_max),
max(-lm_real_max),
compute(sillyID),
out_compute("", 1)
{}
/* -------------------------------------------------------------------------- */
template<typename _Input>
FilterThreshold<_Input>::FilterThreshold(const FilterID name, DomainInterface & d)
:Filter<_Input>(name,d),
min(std::numeric_limits<Real>::max()),
max(-std::numeric_limits<Real>::max()),
compute(sillyID),
out_compute("", 1)
{}
/* -------------------------------------------------------------------------- */
template<typename _Input>
FilterThreshold<_Input>::FilterThreshold(const FilterID name, UInt dim)
:Filter<_Input>(name,dim),
min(std::numeric_limits<Real>::max()),
max(-std::numeric_limits<Real>::max()),
compute(sillyID),
out_compute("", 1)
{}
/* -------------------------------------------------------------------------- */
template<typename _Input>
void FilterThreshold<_Input>::init() {
if (this->compute == sillyID) {
LM_FATAL("You did not specify an input compute for the FilterThreshold '"
<< this->getID() << "'. the parameter COMPUTE is mandatory");
}
std::stringstream out_compute_name;
out_compute_name << this->compute << ":" << this->getID();
this->out_compute.setID(out_compute_name.str());
this->out_compute.name_computed.push_back(out_compute_name.str());
bool has_min = this->min != std::numeric_limits<Real>::max();
bool has_max = -this->max != std::numeric_limits<Real>::max();
if (has_min && has_max) {
if (this->min > this->max) {
LM_FATAL("The mininum threshold you specified is larger than the maximum "
<< "for FilterThreshold '" << this->getID() <<"'.");
}
} else if (!has_min && !has_max) {
LM_FATAL("You forgot to specify a threshold value for FilterThreshold '"
<< this->getID() << "'. You have to specify at least a min or a "
<< "max value.");
}
//register my compute
FilterManager::getManager().addObject(&this->out_compute, false);
}
/* -------------------------------------------------------------------------- */
template<typename _Input>
void FilterThreshold<_Input>::build(_Input & cont) {
// choose the right builder
const bool has_min = this->min != std::numeric_limits<Real>::max();
const bool has_max = -this->max != std::numeric_limits<Real>::max();
if (has_min && has_max) {
this->template buildMinMax<true, true>(cont);
} else if (has_min && !has_max) {
this->template buildMinMax<true, false>(cont);
} else if (!has_min && has_max) {
this->template buildMinMax<false, true>(cont);
}
this->out_compute.copyReleaseInfo(cont);
this->out_compute.copyContainerInfo(cont);
}
/* -------------------------------------------------------------------------- */
template<typename _Input>
template<bool has_min, bool has_max>
void FilterThreshold<_Input>::buildMinMax(_Input & cont) {
this->empty();
this->out_compute.empty();
typename _Input::iterator points = cont.getIterator();
typename _Input::Ref point;
ComputeInterface * in_comp =
dynamic_cast<ComputeInterface*>(FilterManager::getManager().getObject(this->compute));
// check size and dimension of the input compute
LM_ASSERT(in_comp->getDim()==1, "The compute '" << this->compute
<< "', which is used as input for the FilterThreshold '"
<< this->getID() <<"' is not scalar (but should be).");
// this forces the in_compute to compute itself if it isn't done yet
in_comp->build();
typename ComputeInterface::iterator comp_vals = in_comp->getIterator();
Real val;
UInt counter = 0;
for(point = points.getFirst(), val = comp_vals.getFirst();
! points.end();
point = points.getNext(), val = comp_vals.getNext()) {
bool add_this = true;
if (has_min) {
add_this &= this->min <= val;
}
if (has_max) {
add_this &= this->max >= val;
}
if (add_this) {
this->add(point);
this->out_compute.add(val);
counter++;
}
}
DUMP("nb_points after threshold = " << counter, DBG_INFO);
}
/* -------------------------------------------------------------------------- */
/* LMDESC THRESHOLD
Given an input and a compute, this filter will return a filtered version of
the input, and create a compute with the name "<compute\_name>:<filter\_name>
which allows to make filters based on compute results without repaying the
price of the compute for the filtered points/elements. The keyword COMPUTE
is mandatory.
*/
/* LMEXAMPLE FILTER clownorama THRESHOLD INPUT md COMPUTE centrosymmetry MIN 12 MAX 24 */
template<typename _Input>
void FilterThreshold<_Input>::declareParams() {
/* LMKEYWORD COMPUTE
specify which compute should be used to filter
*/
this->parseKeyword("COMPUTE", compute);
/* LMKEYWORD MAX
specify a maximum threshold
*/
this->parseKeyword("MAX", max,-lm_real_max);
/* LMKEYWORD MIN
specify a minimum threshold
*/
this->parseKeyword("MIN", min,lm_real_max);
}
/* -------------------------------------------------------------------------- */
DECLARE_FILTER(FilterThreshold,LIST_ATOM_MODEL);
DECLARE_FILTER(FilterThreshold,LIST_CONTINUUM_MODEL);
DECLARE_FILTER(FilterThreshold,LIST_DD_MODEL);
DECLARE_FILTER_REFPOINT(FilterThreshold);
DECLARE_FILTER_GENERIC_MESH(FilterThreshold);
__END_LIBMULTISCALE__

Event Timeline