Page MenuHomec4science

filter_threshold.cc
No OneTemporary

File Metadata

Created
Wed, Jul 10, 00:18

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 "filter_threshold.hh"
#include "filter_manager.hh"
#include "lib_continuum.hh"
#include "lib_dd.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "ref_point_data.hh"
#include "sstream"
#include <limits>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
FilterID sillyID(
"You forgot to set the parameter 'COMPUTE' which is a mandatory field");
/* -------------------------------------------------------------------------- */
FilterThreshold::FilterThreshold(const std::string &name)
: Filter(name), min(std::numeric_limits<Real>::max()),
max(-std::numeric_limits<Real>::max()), compute(sillyID),
out_compute("") {}
/* -------------------------------------------------------------------------- */
void FilterThreshold::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::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);
}
LM_TOIMPLEMENT;
// this->out_compute.copyReleaseInfo(cont);
this->out_compute.copyContainerInfo(cont);
}
/* -------------------------------------------------------------------------- */
template <bool has_min, bool has_max, typename _Input>
void FilterThreshold::buildMinMax(_Input &cont) {
auto &output = this->getOutput().get().cast<_Input::RefSubSet>();
output.empty();
this->out_compute.empty();
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();
auto it_points = cont.begin();
auto it_comp_vals = in_comp->begin();
auto end_points = cont.end();
auto end_comp_vals = in_comp->end();
UInt counter = 0;
for (; it_points != end_points; ++it_points, ++it_comp_vals) {
auto val = *it_comp_vals;
auto point = *it_points;
bool add_this = true;
if (has_min) {
add_this &= this->min <= val;
}
if (has_max) {
add_this &= this->max >= val;
}
if (add_this) {
output.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 */
void FilterThreshold::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