<commit_before>/* This file is part of the Palabos library.
 *
 * Copyright (C) 2011-2015 FlowKit Sarl
 * Route d'Oron 2
 * 1010 Lausanne, Switzerland
 * E-mail contact: contact@flowkit.com
 *
 * The most recent release of Palabos can be downloaded at
 * <http://www.palabos.org/>
 *
 * The library Palabos is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * The library 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* Code 1.1 in the Palabos tutorial
 */

#include "palabos2D.h"
#ifndef PLB_PRECOMPILED // Unless precompiled version is used,
#include "palabos2D.hh"   // include full template code
#endif

#include <vector>
#include <cmath>
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace plb;
using namespace std;

typedef double T;
#define DESCRIPTOR plb::descriptors::D2Q9Descriptor
#define PI 3.14159265

// ---------------------------------------------
// Includes of acoustics resources
#include "acoustics/acoustics2D.h"
using namespace plb_acoustics;
typedef vector<T> Row;
typedef vector< Row > Matrix;
// ---------------------------------------------

T rho0 = 1.;
T deltaRho = 1.e-4;
T lattice_speed_sound = 1/sqrt(3);

int main(int argc, char* argv[]) {
    plbInit(&argc, &argv);
    global::directories().setOutputDir("./tmp/");

    plint numCores = global::mpi().getSize();
    pcout << "Number of MPI threads: " << numCores << std::endl;

    const plint maxIter = 120000; // 120000 Iterate during 1000 steps.
    const plint nx = 1000;       // Choice of lattice dimensions.
    const plint ny = 1000;
    const T omega = 1.98;        // Choice of the relaxation parameter

    pcout << "Total iteration: " << maxIter << std::endl;
    MultiBlockLattice2D<T, DESCRIPTOR> lattice(nx, ny, new CompleteBGKdynamics<T,DESCRIPTOR>(omega));

    Array<T,2> u0((T)0,(T)0);

    // Initialize constant density everywhere.
    initializeAtEquilibrium(lattice, lattice.getBoundingBox(), rho0, u0);

    lattice.initialize();

    plint size_square = 2;
    Box2D square(nx/2 - size_square/2, nx/2 + size_square/2,
    ny/2 - size_square/2, ny/2 + size_square/2);
    defineDynamics(lattice, square, new BounceBack<T,DESCRIPTOR>((T)999));

    // Anechoic Condition
    T rhoBar_target = 0;
    Array<T,2> j_target(0.15/std::sqrt(3), 0.0/std::sqrt(3));
    T size_anechoic_buffer = 30;
    // Define Anechoic Boards
    defineAnechoicBoards(nx, ny, lattice, size_anechoic_buffer,
	  omega, j_target, j_target, j_target, j_target,
	  rhoBar_target, rhoBar_target, rhoBar_target, rhoBar_target);

    Box2D cima(0, nx, ny - 1, ny);
    //defineDynamics(lattice, cima, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D baixo(0, nx, 0, 1);
    //defineDynamics(lattice, baixo, new BounceBack<T,DESCRIPTOR>(rho0));

    // Main loop over time iterations.
    Box2D wall_top(0, nx-1, ny-1, ny-1);
    defineDynamics(lattice, wall_top, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D wall_bottom(0, nx-1, 0, 0);
    defineDynamics(lattice, wall_bottom, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D wall_left(0, 0, 0, ny-1);
    defineDynamics(lattice, wall_left, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D wall_right(nx-1, nx-1, 0, ny-1);
    /*AnechoicDynamics<T,DESCRIPTOR> *anechoicDynamics =
    new AnechoicDynamics<T,DESCRIPTOR>(omega);
    T delta;
    anechoicDynamics->setDelta(delta);
    anechoicDynamics->setRhoBar_target(rhoBar_target);
    anechoicDynamics->setJ_target(j_target);
    //defineDynamics(lattice, wall_top, anechoicDynamics);
    //defineDynamics(lattice, wall_bottom, anechoicDynamics);
    //defineDynamics(lattice, wall_left, anechoicDynamics);
    //defineDynamics(lattice, wall_right, anechoicDynamics);*/

    // parameters to FW-HS
    Array<T, 2> center((plint) nx/2, (plint) ny/2);
    plint distance_center =  200;
    // total number of points
    plint total_points_fwhs = distance_center*2*4;
    Matrix matrix_sfwh_pressure(total_points_fwhs, Row(maxIter + 2));
    for (plint iT=0; iT <= maxIter; iT++) {

        // Capturing density matrix
        stringstream ss_density;
        ss_density << "data/" << iT << "_density.dat";
        plb_ofstream density_file(ss_density.str().c_str());
        density_file << setprecision(10) << *computeDensity(lattice) << endl;
        density_file.close();

        // Capturing velocity in x
        stringstream ss_velocity_x;
        ss_velocity_x << "data/" << iT << "_velocity_x.dat";
        plb_ofstream velocity_x_file(ss_velocity_x.str().c_str());
        velocity_x_file << setprecision(10) << *computeVelocityComponent(lattice, 0) << endl;
        velocity_x_file.close();

        // Capturing velocity in y
        stringstream ss_velocity_y;
        ss_velocity_y << "data/" << iT << "_velocity_y.dat";
        plb_ofstream velocity_y_file(ss_velocity_y.str().c_str());
        velocity_y_file << setprecision(10) << *computeVelocityComponent(lattice, 1) << endl;
        velocity_y_file.close();

       if (iT%100==0) {  // Write an image every 40th time step.
            pcout << "iT= " << iT << endl;

            if (iT>=0){
                /*ImageWriter<T> imageWriter("leeloo");
                imageWriter.writeScaledGif(createFileName("velocity", iT, 6),
                                   *computeVelocityComponent(lattice, 1));
                imageWriter.writeGif(createFileName("density", iT, 6),
                *computeDensity(lattice), (T) rho0 + -0.001, (T) rho0 + 0.001); //(T) rho0 + -0.001, (T) rho0 + 0.001);*/
            }
            /*plb_ofstream matrix_pressure_file("matrix_pressure.dat");
            if (iT == 30000){
                matrix_pressure_file << setprecision(10) <<
            }*/

            /*ImageWriter<T> imageWriter("leeloo");
            imageWriter.writeScaledGif(createFileName("u", iT, 6),
                               *computeVelocityNorm(lattice) );*/

           // imageWriter.writeScaledGif(createFileName("u", iT, 6), *computeVorticity(*computeVelocity(lattice)));
            //imageWriter.writeScaledGif(createFileName("u", iT, 6), *computeDensity(lattice));
           //imageWriter.writeGif(createFileName("u", iT, 6), *computeDensity(lattice), (T) rho0 - deltaRho/1000, (T) rho0 + deltaRho/1000);
             pcout << " energy ="
                  << setprecision(10) << getStoredAverageEnergy<T>(lattice)
                  << " rho ="
                  << getStoredAverageDensity<T>(lattice)
                  << " max_velocity ="
                  << setprecision(10) << getStoredMaxVelocity<T>(lattice)
                  << endl;
        }

        // Execute lattice Boltzmann iteration.
        lattice.collideAndStream();

    }

}
<commit_msg>getter points fw-h surface done<commit_after>/* This file is part of the Palabos library.
 *
 * Copyright (C) 2011-2015 FlowKit Sarl
 * Route d'Oron 2
 * 1010 Lausanne, Switzerland
 * E-mail contact: contact@flowkit.com
 *
 * The most recent release of Palabos can be downloaded at
 * <http://www.palabos.org/>
 *
 * The library Palabos is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * The library 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* Code 1.1 in the Palabos tutorial
 */

#include "palabos2D.h"
#ifndef PLB_PRECOMPILED // Unless precompiled version is used,
#include "palabos2D.hh"   // include full template code
#endif

#include <vector>
#include <cmath>
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace plb;
using namespace std;

typedef double T;
#define DESCRIPTOR plb::descriptors::D2Q9Descriptor
#define PI 3.14159265

// ---------------------------------------------
// Includes of acoustics resources
#include "acoustics/acoustics2D.h"
using namespace plb_acoustics;
typedef vector<T> Row;
typedef vector< Row > Matrix;
// ---------------------------------------------

T rho0 = 1.;
T deltaRho = 1.e-4;
T lattice_speed_sound = 1/sqrt(3);

int main(int argc, char* argv[]) {
    plbInit(&argc, &argv);
    global::directories().setOutputDir("./tmp/");

    plint numCores = global::mpi().getSize();
    pcout << "Number of MPI threads: " << numCores << std::endl;

    const plint maxIter = 15000; // 120000. 5400 keeps
    const plint nx = 1000;       // Choice of lattice dimensions.
    const plint ny = 1000;
    const T omega = 1.98;        // Choice of the relaxation parameter

    pcout << "Total iteration: " << maxIter << std::endl;
    MultiBlockLattice2D<T, DESCRIPTOR> lattice(nx, ny, new CompleteBGKdynamics<T,DESCRIPTOR>(omega));

    Array<T,2> u0((T)0,(T)0);

    // Initialize constant density everywhere.
    initializeAtEquilibrium(lattice, lattice.getBoundingBox(), rho0, u0);

    lattice.initialize();

    plint size_square = 2;
    Box2D square(nx/2 - size_square/2, nx/2 + size_square/2,
    ny/2 - size_square/2, ny/2 + size_square/2);
    defineDynamics(lattice, square, new BounceBack<T,DESCRIPTOR>((T)999));

    // Anechoic Condition
    T rhoBar_target = 0;
    Array<T,2> j_target(0.15/std::sqrt(3), 0.0/std::sqrt(3));
    T size_anechoic_buffer = 30;
    // Define Anechoic Boards
    defineAnechoicBoards(nx, ny, lattice, size_anechoic_buffer,
	  omega, j_target, j_target, j_target, j_target,
	  rhoBar_target, rhoBar_target, rhoBar_target, rhoBar_target);

    Box2D cima(0, nx, ny - 1, ny);
    //defineDynamics(lattice, cima, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D baixo(0, nx, 0, 1);
    //defineDynamics(lattice, baixo, new BounceBack<T,DESCRIPTOR>(rho0));

    Box2D wall_top(0, nx-1, ny-1, ny-1);
    defineDynamics(lattice, wall_top, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D wall_bottom(0, nx-1, 0, 0);
    defineDynamics(lattice, wall_bottom, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D wall_left(0, 0, 0, ny-1);
    defineDynamics(lattice, wall_left, new BounceBack<T,DESCRIPTOR>(rho0));
    Box2D wall_right(nx-1, nx-1, 0, ny-1);
    /*AnechoicDynamics<T,DESCRIPTOR> *anechoicDynamics =
    new AnechoicDynamics<T,DESCRIPTOR>(omega);
    T delta;
    anechoicDynamics->setDelta(delta);
    anechoicDynamics->setRhoBar_target(rhoBar_target);
    anechoicDynamics->setJ_target(j_target);
    //defineDynamics(lattice, wall_top, anechoicDynamics);
    //defineDynamics(lattice, wall_bottom, anechoicDynamics);
    //defineDynamics(lattice, wall_left, anechoicDynamics);
    //defineDynamics(lattice, wall_right, anechoicDynamics);*/

    // parameters to FW-HS
    Array<T, 2> center((plint) nx/2, (plint) ny/2);
    plint distance_center =  200;
    // total number of points
    plint start_transient_iteration = 5400;
    plint total_points_fwhs = distance_center*2*4;
    Matrix matrix_sfwh_pressure(total_points_fwhs, Row(maxIter - start_transient_iteration + 2));
    Matrix matrix_sfwh_velocity_x(total_points_fwhs, Row(maxIter - start_transient_iteration + 2));
    Matrix matrix_sfwh_velocity_y(total_points_fwhs, Row(maxIter - start_transient_iteration + 2));
    // Main loop over time iterations.
    for (plint iT=0; iT <= maxIter; iT++) {

        if (iT >= start_transient_iteration){

            plint point_surface = 0;
            // to face 1 (left)
            for (plint y = center[1] - distance_center; y < center[1] + distance_center; y++){
                plint x = center[0] - distance_center;
                matrix_sfwh_pressure[point_surface][0] = x;
                matrix_sfwh_pressure[point_surface][1] = y;
                matrix_sfwh_velocity_x[point_surface][0] = x;
                matrix_sfwh_velocity_x[point_surface][1] = y;
                matrix_sfwh_velocity_y[point_surface][0] = x;
                matrix_sfwh_velocity_y[point_surface][1] = y;
                matrix_sfwh_pressure[point_surface][iT - start_transient_iteration + 2] = (lattice.get(x, y).computeDensity())/3;
                Array<T, 2> velocities((T) 9999, (T) 9999);
                lattice.get(x, y).computeVelocity(velocities);
                matrix_sfwh_velocity_x[point_surface][iT - start_transient_iteration + 2] = velocities[0];
                matrix_sfwh_velocity_y[point_surface][iT - start_transient_iteration + 2] = velocities[1];
                point_surface++;
            }
            // to face 2 (top)
            for (plint x = center[0] - distance_center; x < center[0] + distance_center; x++){
                plint y = center[1] + distance_center;
                matrix_sfwh_pressure[point_surface][0] = x;
                matrix_sfwh_pressure[point_surface][1] = y;
                matrix_sfwh_velocity_x[point_surface][0] = x;
                matrix_sfwh_velocity_x[point_surface][1] = y;
                matrix_sfwh_velocity_y[point_surface][0] = x;
                matrix_sfwh_velocity_y[point_surface][1] = y;
                matrix_sfwh_pressure[point_surface][iT - start_transient_iteration + 2] = (lattice.get(x, y).computeDensity())/3;
                Array<T, 2> velocities((T) 9999, (T) 9999);
                lattice.get(x, y).computeVelocity(velocities);
                matrix_sfwh_velocity_x[point_surface][iT - start_transient_iteration + 2] = velocities[0];
                matrix_sfwh_velocity_y[point_surface][iT - start_transient_iteration + 2] = velocities[1];
                point_surface++;
            }
            // to face 3 (right)
            for (plint y = center[1] + distance_center; y > center[1] - distance_center; y--){
                plint x = center[1] + distance_center;
                matrix_sfwh_pressure[point_surface][0] = x;
                matrix_sfwh_pressure[point_surface][1] = y;
                matrix_sfwh_velocity_x[point_surface][0] = x;
                matrix_sfwh_velocity_x[point_surface][1] = y;
                matrix_sfwh_velocity_y[point_surface][0] = x;
                matrix_sfwh_velocity_y[point_surface][1] = y;
                matrix_sfwh_pressure[point_surface][iT - start_transient_iteration + 2] = (lattice.get(x, y).computeDensity())/3;
                Array<T, 2> velocities((T) 9999, (T) 9999);
                lattice.get(x, y).computeVelocity(velocities);
                matrix_sfwh_velocity_x[point_surface][iT - start_transient_iteration + 2] = velocities[0];
                matrix_sfwh_velocity_y[point_surface][iT - start_transient_iteration + 2] = velocities[1];
                point_surface++;
            }
            // to face 4 (bottom)
            for (plint x = center[0] + distance_center; x > center[0] - distance_center; x--){
                plint y = center[1] - distance_center;
                matrix_sfwh_pressure[point_surface][0] = x;
                matrix_sfwh_pressure[point_surface][1] = y;
                matrix_sfwh_velocity_x[point_surface][0] = x;
                matrix_sfwh_velocity_x[point_surface][1] = y;
                matrix_sfwh_velocity_y[point_surface][0] = x;
                matrix_sfwh_velocity_y[point_surface][1] = y;
                matrix_sfwh_pressure[point_surface][iT - start_transient_iteration + 2] = (lattice.get(x, y).computeDensity())/3;
                Array<T, 2> velocities((T) 9999, (T) 9999);
                lattice.get(x, y).computeVelocity(velocities);
                matrix_sfwh_velocity_x[point_surface][iT - start_transient_iteration + 2] = velocities[0];
                matrix_sfwh_velocity_y[point_surface][iT - start_transient_iteration + 2] = velocities[1];
                point_surface++;
            }

        }

       if (iT%100==0) {  // Write an image every 40th time step.
            pcout << "iT= " << iT << endl;

            /*if (iT>=0){
                ImageWriter<T> imageWriter("leeloo");
                imageWriter.writeScaledGif(createFileName("velocity", iT, 6),
                                   *computeVelocityComponent(lattice, 0));
                imageWriter.writeGif(createFileName("density", iT, 6),
                *computeDensity(lattice), (T) rho0 + -0.001, (T) rho0 + 0.001); //(T) rho0 + -0.001, (T) rho0 + 0.001);
            }
            plb_ofstream matrix_pressure_file("matrix_pressure.dat");
            if (iT == 30000){
                matrix_pressure_file << setprecision(10) <<
            }*/

            /*ImageWriter<T> imageWriter("leeloo");
            imageWriter.writeScaledGif(createFileName("u", iT, 6),
                               *computeVelocityNorm(lattice) );*/

           // imageWriter.writeScaledGif(createFileName("u", iT, 6), *computeVorticity(*computeVelocity(lattice)));
            //imageWriter.writeScaledGif(createFileName("u", iT, 6), *computeDensity(lattice));
           //imageWriter.writeGif(createFileName("u", iT, 6), *computeDensity(lattice), (T) rho0 - deltaRho/1000, (T) rho0 + deltaRho/1000);
             pcout << " energy ="
                  << setprecision(10) << getStoredAverageEnergy<T>(lattice)
                  << " rho ="
                  << getStoredAverageDensity<T>(lattice)
                  << " max_velocity ="
                  << setprecision(10) << getStoredMaxVelocity<T>(lattice)
                  << endl;
        }

        // Execute lattice Boltzmann iteration.
        lattice.collideAndStream();

    }

    plb_ofstream sfwh_pressure_file("data_sfwh/sfwh_pressure.dat");
    plb_ofstream sfwh_velocity_x_file("data_sfwh/sfwh_velocity_x.dat");
    plb_ofstream sfwh_velocity_y_file("data_sfwh/sfwh_velocity_y.dat");
    for (plint point = 0; point < total_points_fwhs; point++){
        for (plint time_step = 0; time_step < maxIter - start_transient_iteration + 2; time_step++){
            sfwh_pressure_file <<  setprecision(10) << matrix_sfwh_pressure[point][time_step] << " ";
            sfwh_velocity_x_file <<  setprecision(10) << matrix_sfwh_velocity_x[point][time_step] << " ";
            sfwh_velocity_y_file <<  setprecision(10) << matrix_sfwh_velocity_y[point][time_step] << " ";
        }
        sfwh_pressure_file << endl;
        sfwh_velocity_x_file << endl;
        sfwh_velocity_y_file << endl;
    }
    sfwh_pressure_file.close();
    sfwh_velocity_x_file.close();
    sfwh_velocity_y_file.close();
}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library 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 2 of the License, or (at your option) any later version.
//
//  This library 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 this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
/////////////////////////////////////////////////////////////////////////

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR

#include "iodev/iodev.h"

  Bit16u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp16(Bit16u port)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
    BX_DEBUG(("inp16(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  Bit16u ret16 = BX_INP(port, 2);
  return ret16;
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp16(Bit16u port, Bit16u value)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
    BX_DEBUG(("outp16(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  BX_OUTP(port, value, 2);
}

  Bit32u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp32(Bit16u port)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
    BX_DEBUG(("inp32(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  Bit32u ret32 = BX_INP(port, 4);
  return ret32;
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp32(Bit16u port, Bit32u value)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
    BX_DEBUG(("outp32(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  BX_OUTP(port, value, 4);
}

  Bit8u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp8(Bit16u port)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
    BX_DEBUG(("inp8(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  Bit8u ret8 = BX_INP(port, 1);
  return ret8;
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp8(Bit16u port, Bit8u value)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
    BX_DEBUG(("outp8(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  BX_OUTP(port, value, 1);
}

bx_bool BX_CPU_C::allow_io(Bit16u port, unsigned len)
{
  /* If CPL <= IOPL, then all IO portesses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL())))
  {
    if (BX_CPU_THIS_PTR tr.cache.valid==0 ||
       (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_386_TSS &&
        BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_386_TSS))
    {
      BX_ERROR(("allow_io(): TR doesn't point to a valid 32bit TSS, TR.TYPE=%u", BX_CPU_THIS_PTR tr.cache.type));
      return(0);
    }

    if (BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled < 103) {
      BX_ERROR(("allow_io(): TR.limit < 103"));
      return(0);
    }

    Bit16u io_base = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + 102);

    if ((io_base + port/8) >= BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled) {
      BX_ERROR(("allow_io(): IO port %x (len %d) outside TSS IO permission map (base=%x, limit=%x) #GP(0)",
        port, len, io_base, BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled));
      return(0);
    }

    Bit16u permission16 = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + io_base + port/8);

    unsigned bit_index = port & 0x7;
    unsigned mask = (1 << len) - 1;
    if ((permission16 >> bit_index) & mask)
      return(0);
  }

#if BX_X86_DEBUGGER
  iobreakpoint_match(port, len);
#endif

  return(1);
}
<commit_msg>Change error message level<commit_after>/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library 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 2 of the License, or (at your option) any later version.
//
//  This library 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 this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
/////////////////////////////////////////////////////////////////////////

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR

#include "iodev/iodev.h"

  Bit16u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp16(Bit16u port)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
    BX_DEBUG(("inp16(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  Bit16u ret16 = BX_INP(port, 2);
  return ret16;
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp16(Bit16u port, Bit16u value)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
    BX_DEBUG(("outp16(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  BX_OUTP(port, value, 2);
}

  Bit32u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp32(Bit16u port)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
    BX_DEBUG(("inp32(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  Bit32u ret32 = BX_INP(port, 4);
  return ret32;
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp32(Bit16u port, Bit32u value)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
    BX_DEBUG(("outp32(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  BX_OUTP(port, value, 4);
}

  Bit8u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp8(Bit16u port)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
    BX_DEBUG(("inp8(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  Bit8u ret8 = BX_INP(port, 1);
  return ret8;
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp8(Bit16u port, Bit8u value)
{
  if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
    BX_DEBUG(("outp8(): I/O access not allowed !"));
    exception(BX_GP_EXCEPTION, 0, 0);
  }

  BX_OUTP(port, value, 1);
}

bx_bool BX_CPU_C::allow_io(Bit16u port, unsigned len)
{
  /* If CPL <= IOPL, then all IO portesses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL())))
  {
    if (BX_CPU_THIS_PTR tr.cache.valid==0 ||
       (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_386_TSS &&
        BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_386_TSS))
    {
      BX_ERROR(("allow_io(): TR doesn't point to a valid 32bit TSS, TR.TYPE=%u", BX_CPU_THIS_PTR tr.cache.type));
      return(0);
    }

    if (BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled < 103) {
      BX_ERROR(("allow_io(): TR.limit < 103"));
      return(0);
    }

    Bit16u io_base = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + 102);

    if ((io_base + port/8) >= BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled) {
      BX_DEBUG(("allow_io(): IO port %x (len %d) outside TSS IO permission map (base=%x, limit=%x) #GP(0)",
        port, len, io_base, BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled));
      return(0);
    }

    Bit16u permission16 = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + io_base + port/8);

    unsigned bit_index = port & 0x7;
    unsigned mask = (1 << len) - 1;
    if ((permission16 >> bit_index) & mask)
      return(0);
  }

#if BX_X86_DEBUGGER
  iobreakpoint_match(port, len);
#endif

  return(1);
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2012 The PECOS Development Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Version 2 GNU General
// Public License as published by the Free Software Foundation.
//
// This program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301 USA
//
//-----------------------------------------------------------------------el-
//
// $Id$
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#include "simulation.h"

namespace GRINS
{

  Simulation::Simulation( const GetPot& input,
			  SimulationBuilder& sim_builder )
    :  _mesh( sim_builder.build_mesh(input) ),
       _equation_system( new libMesh::EquationSystems( *_mesh ) ),
       _solver( sim_builder.build_solver(input) ),
       _system_name( input("screen-options/system_name", "GRINS" ) ),
       _multiphysics_system( &(_equation_system->add_system<MultiphysicsSystem>( _system_name )) ),
       _vis( sim_builder.build_vis(input) ),
       _qoi( sim_builder.build_qoi(input) ),
       _print_mesh_info( input("screen-options/print_mesh_info", false ) ),
       _print_log_info( input("screen-options/print_log_info", false ) ),
    _print_equation_system_info( input("screen-options/print_equation_system_info", false ) ),
    _print_qoi( input("screen-options/print_qoi", false ) ),
    _output_vis( input("vis-options/output_vis", false ) ),
    _output_residual( input( "vis-options/output_residual", false ) )
  {
    // Only print libMesh logging info if the user requests it
    libMesh::perflog.disable_logging();
    if( this->_print_log_info ) libMesh::perflog.enable_logging();

    PhysicsList physics_list = sim_builder.build_physics(input);

    _multiphysics_system->attach_physics_list( physics_list );

    _multiphysics_system->read_input_options( input );

    // This *must* be done before equation_system->init
    this->attach_dirichlet_bc_funcs( sim_builder.build_dirichlet_bcs(), _multiphysics_system );

    _solver->initialize( input, _equation_system, _multiphysics_system );

    // This *must* be done after equation_system->init in order to get variable indices
    this->attach_neumann_bc_funcs( sim_builder.build_neumann_bcs( *_equation_system ), _multiphysics_system );

    // If the user actually asks for a QoI, then we add it.
    if( this->_qoi.use_count() > 0 )
      {
	// This *must* be done after equation_system->init in order to get variable indices
	this->_qoi->init(input, *_multiphysics_system );

	/*! \todo We're missing the qoi's init_context call by putting it after equation_system->init,
	  but we also need to be able to get system variable numbers... */
	/* Note that we are effectively transfering ownership of the qoi pointer because
	   it will be cloned in _multiphysics_system and all the calculations are done there. */

	_multiphysics_system->attach_qoi( &(*(this->_qoi)) );
      }

    this->check_for_restart( input );

    return;
  }

  Simulation::~Simulation()
  {
    return;
  }

  void Simulation::run()
  {
    this->print_sim_info();

    SolverContext context;
    context.system = _multiphysics_system;
    context.equation_system = _equation_system;
    context.vis = _vis;
    context.output_vis = _output_vis;
    context.output_residual = _output_residual;

    _solver->solve( context );

    if( this->_print_qoi )
      {
	_multiphysics_system->assemble_qoi( libMesh::QoISet( *_multiphysics_system ) );
	const QoIBase* my_qoi = libmesh_cast_ptr<const QoIBase*>(this->_multiphysics_system->get_qoi());
	my_qoi->output_qoi( std::cout );
      }

    return;
  }

  void Simulation::print_sim_info()
  {
    // Print mesh info if the user wants it
    if( this->_print_mesh_info ) this->_mesh->print_info();

    // Print info if requested
    if( this->_print_equation_system_info ) this->_equation_system->print_info();

    return;
  }

  std::tr1::shared_ptr<libMesh::EquationSystems> Simulation::get_equation_system()
  {
    return _equation_system;
  }

  Number Simulation::get_qoi( unsigned int qoi_index ) const
  {
    const QoIBase* qoi = libmesh_cast_ptr<const QoIBase*>(this->_multiphysics_system->get_qoi());
    /*! \todo Hard coded to 1 qoi. Need to update to handle multiple qois. */
    return qoi->get_qoi(0);
  }

  void Simulation::check_for_restart( const GetPot& input )
  {
    const std::string restart_file = input( "restart-options/restart_file", "none" );

    // Most of this was pulled from FIN-S
    if (restart_file != "none")
      {
	std::cout << " ====== Restarting from " << restart_file << std::endl;

	// Must have correct file type to restart
	if (restart_file.rfind(".xdr") < restart_file.size())
	  _equation_system->read(restart_file,libMeshEnums::DECODE,
				 //EquationSystems::READ_HEADER |  // Allow for thermochemistry upgrades
				 EquationSystems::READ_DATA |
				 EquationSystems::READ_ADDITIONAL_DATA);

	else if  (restart_file.rfind(".xda") < restart_file.size())
	  _equation_system->read(restart_file,libMeshEnums::READ,
				 //EquationSystems::READ_HEADER |  // Allow for thermochemistry upgrades
				 EquationSystems::READ_DATA |
				 EquationSystems::READ_ADDITIONAL_DATA);

	else
	  {
	    std::cerr << "Error: Restart filename must have .xdr or .xda extension!" << std::endl;
	    libmesh_error();
	  }

	const std::string system_name = input("screen-options/system_name", "GRINS" );

	MultiphysicsSystem& system =
	  _equation_system->get_system<MultiphysicsSystem>(system_name);

	// Update the old data
	system.update();
      }

    return;
  }

  void Simulation::attach_neumann_bc_funcs( std::map< std::string, NBCContainer > neumann_bcs,
					    MultiphysicsSystem* system )
  {
    //_neumann_bc_funcs = neumann_bcs;

    if( neumann_bcs.size() > 0 )
      {
	for( std::map< std::string, NBCContainer >::iterator bc = neumann_bcs.begin();
	     bc != neumann_bcs.end();
	     bc++ )
	  {
	    std::tr1::shared_ptr<Physics> physics = system->get_physics( bc->first );
	    physics->attach_neumann_bound_func( bc->second );
	  }
      }

    return;
  }

  void Simulation::attach_dirichlet_bc_funcs( std::multimap< PhysicsName, DBCContainer > dbc_map,
					      MultiphysicsSystem* system )
  {
    for( std::multimap< PhysicsName, DBCContainer >::const_iterator it = dbc_map.begin();
	 it != dbc_map.end();
	 it++ )
      {
	std::tr1::shared_ptr<Physics> physics = system->get_physics( it->first );

	physics->attach_dirichlet_bound_func( it->second );
      }
    return;
  }

#ifdef GRINS_USE_GRVY_TIMERS
  void Simulation::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
  {
    this->_multiphysics_system->attach_grvy_timer( grvy_timer );
    return;
  }
#endif

} // namespace GRINS
<commit_msg>[GRINS]: Use the bloody index that's passed in. *facepalm*<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2012 The PECOS Development Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Version 2 GNU General
// Public License as published by the Free Software Foundation.
//
// This program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301 USA
//
//-----------------------------------------------------------------------el-
//
// $Id$
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#include "simulation.h"

namespace GRINS
{

  Simulation::Simulation( const GetPot& input,
			  SimulationBuilder& sim_builder )
    :  _mesh( sim_builder.build_mesh(input) ),
       _equation_system( new libMesh::EquationSystems( *_mesh ) ),
       _solver( sim_builder.build_solver(input) ),
       _system_name( input("screen-options/system_name", "GRINS" ) ),
       _multiphysics_system( &(_equation_system->add_system<MultiphysicsSystem>( _system_name )) ),
       _vis( sim_builder.build_vis(input) ),
       _qoi( sim_builder.build_qoi(input) ),
       _print_mesh_info( input("screen-options/print_mesh_info", false ) ),
       _print_log_info( input("screen-options/print_log_info", false ) ),
    _print_equation_system_info( input("screen-options/print_equation_system_info", false ) ),
    _print_qoi( input("screen-options/print_qoi", false ) ),
    _output_vis( input("vis-options/output_vis", false ) ),
    _output_residual( input( "vis-options/output_residual", false ) )
  {
    // Only print libMesh logging info if the user requests it
    libMesh::perflog.disable_logging();
    if( this->_print_log_info ) libMesh::perflog.enable_logging();

    PhysicsList physics_list = sim_builder.build_physics(input);

    _multiphysics_system->attach_physics_list( physics_list );

    _multiphysics_system->read_input_options( input );

    // This *must* be done before equation_system->init
    this->attach_dirichlet_bc_funcs( sim_builder.build_dirichlet_bcs(), _multiphysics_system );

    _solver->initialize( input, _equation_system, _multiphysics_system );

    // This *must* be done after equation_system->init in order to get variable indices
    this->attach_neumann_bc_funcs( sim_builder.build_neumann_bcs( *_equation_system ), _multiphysics_system );

    // If the user actually asks for a QoI, then we add it.
    if( this->_qoi.use_count() > 0 )
      {
	// This *must* be done after equation_system->init in order to get variable indices
	this->_qoi->init(input, *_multiphysics_system );

	/*! \todo We're missing the qoi's init_context call by putting it after equation_system->init,
	  but we also need to be able to get system variable numbers... */
	/* Note that we are effectively transfering ownership of the qoi pointer because
	   it will be cloned in _multiphysics_system and all the calculations are done there. */

	_multiphysics_system->attach_qoi( &(*(this->_qoi)) );
      }

    this->check_for_restart( input );

    return;
  }

  Simulation::~Simulation()
  {
    return;
  }

  void Simulation::run()
  {
    this->print_sim_info();

    SolverContext context;
    context.system = _multiphysics_system;
    context.equation_system = _equation_system;
    context.vis = _vis;
    context.output_vis = _output_vis;
    context.output_residual = _output_residual;

    _solver->solve( context );

    if( this->_print_qoi )
      {
	_multiphysics_system->assemble_qoi( libMesh::QoISet( *_multiphysics_system ) );
	const QoIBase* my_qoi = libmesh_cast_ptr<const QoIBase*>(this->_multiphysics_system->get_qoi());
	my_qoi->output_qoi( std::cout );
      }

    return;
  }

  void Simulation::print_sim_info()
  {
    // Print mesh info if the user wants it
    if( this->_print_mesh_info ) this->_mesh->print_info();

    // Print info if requested
    if( this->_print_equation_system_info ) this->_equation_system->print_info();

    return;
  }

  std::tr1::shared_ptr<libMesh::EquationSystems> Simulation::get_equation_system()
  {
    return _equation_system;
  }

  Number Simulation::get_qoi( unsigned int qoi_index ) const
  {
    const QoIBase* qoi = libmesh_cast_ptr<const QoIBase*>(this->_multiphysics_system->get_qoi());
    return qoi->get_qoi(qoi_index);
  }

  void Simulation::check_for_restart( const GetPot& input )
  {
    const std::string restart_file = input( "restart-options/restart_file", "none" );

    // Most of this was pulled from FIN-S
    if (restart_file != "none")
      {
	std::cout << " ====== Restarting from " << restart_file << std::endl;

	// Must have correct file type to restart
	if (restart_file.rfind(".xdr") < restart_file.size())
	  _equation_system->read(restart_file,libMeshEnums::DECODE,
				 //EquationSystems::READ_HEADER |  // Allow for thermochemistry upgrades
				 EquationSystems::READ_DATA |
				 EquationSystems::READ_ADDITIONAL_DATA);

	else if  (restart_file.rfind(".xda") < restart_file.size())
	  _equation_system->read(restart_file,libMeshEnums::READ,
				 //EquationSystems::READ_HEADER |  // Allow for thermochemistry upgrades
				 EquationSystems::READ_DATA |
				 EquationSystems::READ_ADDITIONAL_DATA);

	else
	  {
	    std::cerr << "Error: Restart filename must have .xdr or .xda extension!" << std::endl;
	    libmesh_error();
	  }

	const std::string system_name = input("screen-options/system_name", "GRINS" );

	MultiphysicsSystem& system =
	  _equation_system->get_system<MultiphysicsSystem>(system_name);

	// Update the old data
	system.update();
      }

    return;
  }

  void Simulation::attach_neumann_bc_funcs( std::map< std::string, NBCContainer > neumann_bcs,
					    MultiphysicsSystem* system )
  {
    //_neumann_bc_funcs = neumann_bcs;

    if( neumann_bcs.size() > 0 )
      {
	for( std::map< std::string, NBCContainer >::iterator bc = neumann_bcs.begin();
	     bc != neumann_bcs.end();
	     bc++ )
	  {
	    std::tr1::shared_ptr<Physics> physics = system->get_physics( bc->first );
	    physics->attach_neumann_bound_func( bc->second );
	  }
      }

    return;
  }

  void Simulation::attach_dirichlet_bc_funcs( std::multimap< PhysicsName, DBCContainer > dbc_map,
					      MultiphysicsSystem* system )
  {
    for( std::multimap< PhysicsName, DBCContainer >::const_iterator it = dbc_map.begin();
	 it != dbc_map.end();
	 it++ )
      {
	std::tr1::shared_ptr<Physics> physics = system->get_physics( it->first );

	physics->attach_dirichlet_bound_func( it->second );
      }
    return;
  }

#ifdef GRINS_USE_GRVY_TIMERS
  void Simulation::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
  {
    this->_multiphysics_system->attach_grvy_timer( grvy_timer );
    return;
  }
#endif

} // namespace GRINS
<|endoftext|>


<commit_before>// Copyright 2016 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <queue>
#include <string>

#include "re2/prefilter.h"
#include "re2/re2.h"

using re2::StringPiece;
using std::string;

// NOT static, NOT signed.
uint8_t dummy = 0;

void Test(StringPiece pattern, const RE2::Options& options, StringPiece text) {
  RE2 re(pattern, options);
  if (!re.ok())
    return;

  // Don't waste time fuzzing high-size programs.
  // They can cause bug reports due to fuzzer timeouts.
  int size = re.ProgramSize();
  if (size > 9999)
    return;
  int rsize = re.ReverseProgramSize();
  if (rsize > 9999)
    return;

  // Don't waste time fuzzing high-fanout programs.
  // They can cause bug reports due to fuzzer timeouts.
  std::map<int, int> histogram;
  int fanout = re.ProgramFanout(&histogram);
  if (fanout > 9)
    return;
  int rfanout = re.ReverseProgramFanout(&histogram);
  if (rfanout > 9)
    return;

  // Don't waste time fuzzing programs with large substrings.
  // They can cause bug reports due to fuzzer timeouts when they
  // are repetitions (e.g. hundreds of NUL bytes) and matching is
  // unanchored. And they aren't interesting for fuzzing purposes.
  std::unique_ptr<re2::Prefilter> prefilter(re2::Prefilter::FromRE2(&re));
  if (prefilter == nullptr)
    return;
  std::queue<re2::Prefilter*> nodes;
  nodes.push(prefilter.get());
  while (!nodes.empty()) {
    re2::Prefilter* node = nodes.front();
    nodes.pop();
    if (node->op() == re2::Prefilter::ATOM) {
      if (node->atom().size() > 9)
        return;
    } else if (node->op() == re2::Prefilter::AND ||
               node->op() == re2::Prefilter::OR) {
      for (re2::Prefilter* sub : *node->subs())
        nodes.push(sub);
    }
  }

  if (re.NumberOfCapturingGroups() == 0) {
    // Avoid early return due to too many arguments.
    StringPiece sp = text;
    RE2::FullMatch(sp, re);
    RE2::PartialMatch(sp, re);
    RE2::Consume(&sp, re);
    sp = text;  // Reset.
    RE2::FindAndConsume(&sp, re);
  } else {
    // Okay, we have at least one capturing group...
    // Try conversion for variously typed arguments.
    StringPiece sp = text;
    short s;
    RE2::FullMatch(sp, re, &s);
    long l;
    RE2::PartialMatch(sp, re, &l);
    float f;
    RE2::Consume(&sp, re, &f);
    sp = text;  // Reset.
    double d;
    RE2::FindAndConsume(&sp, re, &d);
  }

  string s = string(text);
  RE2::Replace(&s, re, "");
  s = string(text);  // Reset.
  RE2::GlobalReplace(&s, re, "");

  string min, max;
  re.PossibleMatchRange(&min, &max, /*maxlen=*/9);

  // Exercise some other API functionality.
  dummy += re.NamedCapturingGroups().size();
  dummy += re.CapturingGroupNames().size();
  dummy += RE2::QuoteMeta(pattern).size();
}

// Entry point for libFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  if (size == 0 || size > 999)
    return 0;

  // Crudely limit the use of ., \p, \P, \d, \D, \s, \S, \w and \W.
  // Otherwise, we will waste time on inputs that have long runs of various
  // character classes. The fuzzer has shown itself to be easily capable of
  // generating such patterns that fall within the other limits, but result
  // in timeouts nonetheless. The marginal cost is high - even more so when
  // counted repetition is involved - whereas the marginal benefit is zero.
  // TODO(junyer): Handle [:isalnum:] et al. when they start to cause pain.
  int cc = 0;
  for (size_t i = 0; i < size; i++) {
    if (data[i] == '.')
      cc++;
    if (data[i] != '\\')
      continue;
    i++;
    if (i >= size)
      break;
    if (data[i] == 'p' || data[i] == 'P' ||
        data[i] == 'd' || data[i] == 'D' ||
        data[i] == 's' || data[i] == 'S' ||
        data[i] == 'w' || data[i] == 'W')
      cc++;
  }
  if (cc > 9)
    return 0;

  // The one-at-a-time hash by Bob Jenkins.
  uint32_t hash = 0;
  for (size_t i = 0; i < size; i++) {
    hash += data[i];
    hash += (hash << 10);
    hash ^= (hash >> 6);
  }
  hash += (hash << 3);
  hash ^= (hash >> 11);
  hash += (hash << 15);

  RE2::Options options;
  options.set_log_errors(false);
  options.set_max_mem(64 << 20);
  options.set_encoding(hash & 1 ? RE2::Options::EncodingLatin1
                                : RE2::Options::EncodingUTF8);
  options.set_posix_syntax(hash & 2);
  options.set_longest_match(hash & 4);
  options.set_literal(hash & 8);
  options.set_never_nl(hash & 16);
  options.set_dot_nl(hash & 32);
  options.set_never_capture(hash & 64);
  options.set_case_sensitive(hash & 128);
  options.set_perl_classes(hash & 256);
  options.set_word_boundary(hash & 512);
  options.set_one_line(hash & 1024);

  const char* ptr = reinterpret_cast<const char*>(data);
  int len = static_cast<int>(size);

  StringPiece pattern(ptr, len);
  StringPiece text(ptr, len);
  Test(pattern, options, text);

  return 0;
}
<commit_msg>Make the fuzzer handle \p and \P specially.<commit_after>// Copyright 2016 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <queue>
#include <string>

#include "re2/prefilter.h"
#include "re2/re2.h"

using re2::StringPiece;
using std::string;

// NOT static, NOT signed.
uint8_t dummy = 0;

void Test(StringPiece pattern, const RE2::Options& options, StringPiece text) {
  RE2 re(pattern, options);
  if (!re.ok())
    return;

  // Don't waste time fuzzing high-size programs.
  // They can cause bug reports due to fuzzer timeouts.
  int size = re.ProgramSize();
  if (size > 9999)
    return;
  int rsize = re.ReverseProgramSize();
  if (rsize > 9999)
    return;

  // Don't waste time fuzzing high-fanout programs.
  // They can cause bug reports due to fuzzer timeouts.
  std::map<int, int> histogram;
  int fanout = re.ProgramFanout(&histogram);
  if (fanout > 9)
    return;
  int rfanout = re.ReverseProgramFanout(&histogram);
  if (rfanout > 9)
    return;

  // Don't waste time fuzzing programs with large substrings.
  // They can cause bug reports due to fuzzer timeouts when they
  // are repetitions (e.g. hundreds of NUL bytes) and matching is
  // unanchored. And they aren't interesting for fuzzing purposes.
  std::unique_ptr<re2::Prefilter> prefilter(re2::Prefilter::FromRE2(&re));
  if (prefilter == nullptr)
    return;
  std::queue<re2::Prefilter*> nodes;
  nodes.push(prefilter.get());
  while (!nodes.empty()) {
    re2::Prefilter* node = nodes.front();
    nodes.pop();
    if (node->op() == re2::Prefilter::ATOM) {
      if (node->atom().size() > 9)
        return;
    } else if (node->op() == re2::Prefilter::AND ||
               node->op() == re2::Prefilter::OR) {
      for (re2::Prefilter* sub : *node->subs())
        nodes.push(sub);
    }
  }

  if (re.NumberOfCapturingGroups() == 0) {
    // Avoid early return due to too many arguments.
    StringPiece sp = text;
    RE2::FullMatch(sp, re);
    RE2::PartialMatch(sp, re);
    RE2::Consume(&sp, re);
    sp = text;  // Reset.
    RE2::FindAndConsume(&sp, re);
  } else {
    // Okay, we have at least one capturing group...
    // Try conversion for variously typed arguments.
    StringPiece sp = text;
    short s;
    RE2::FullMatch(sp, re, &s);
    long l;
    RE2::PartialMatch(sp, re, &l);
    float f;
    RE2::Consume(&sp, re, &f);
    sp = text;  // Reset.
    double d;
    RE2::FindAndConsume(&sp, re, &d);
  }

  string s = string(text);
  RE2::Replace(&s, re, "");
  s = string(text);  // Reset.
  RE2::GlobalReplace(&s, re, "");

  string min, max;
  re.PossibleMatchRange(&min, &max, /*maxlen=*/9);

  // Exercise some other API functionality.
  dummy += re.NamedCapturingGroups().size();
  dummy += re.CapturingGroupNames().size();
  dummy += RE2::QuoteMeta(pattern).size();
}

// Entry point for libFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  if (size == 0 || size > 999)
    return 0;

  // Crudely limit the use of ., \p, \P, \d, \D, \s, \S, \w and \W.
  // Otherwise, we will waste time on inputs that have long runs of various
  // character classes. The fuzzer has shown itself to be easily capable of
  // generating such patterns that fall within the other limits, but result
  // in timeouts nonetheless. The marginal cost is high - even more so when
  // counted repetition is involved - whereas the marginal benefit is zero.
  // TODO(junyer): Handle [:isalnum:] et al. when they start to cause pain.
  int char_class = 0;
  int backslash_p = 0;  // very expensive, so handle specially
  for (size_t i = 0; i < size; i++) {
    if (data[i] == '.')
      char_class++;
    if (data[i] != '\\')
      continue;
    i++;
    if (i >= size)
      break;
    if (data[i] == 'p' || data[i] == 'P' ||
        data[i] == 'd' || data[i] == 'D' ||
        data[i] == 's' || data[i] == 'S' ||
        data[i] == 'w' || data[i] == 'W')
      char_class++;
    if (data[i] == 'p' || data[i] == 'P')
      backslash_p++;
  }
  if (char_class > 9)
    return 0;
  if (backslash_p > 1)
    return 0;

  // The one-at-a-time hash by Bob Jenkins.
  uint32_t hash = 0;
  for (size_t i = 0; i < size; i++) {
    hash += data[i];
    hash += (hash << 10);
    hash ^= (hash >> 6);
  }
  hash += (hash << 3);
  hash ^= (hash >> 11);
  hash += (hash << 15);

  RE2::Options options;
  options.set_log_errors(false);
  options.set_max_mem(64 << 20);
  options.set_encoding(hash & 1 ? RE2::Options::EncodingLatin1
                                : RE2::Options::EncodingUTF8);
  options.set_posix_syntax(hash & 2);
  options.set_longest_match(hash & 4);
  options.set_literal(hash & 8);
  options.set_never_nl(hash & 16);
  options.set_dot_nl(hash & 32);
  options.set_never_capture(hash & 64);
  options.set_case_sensitive(hash & 128);
  options.set_perl_classes(hash & 256);
  options.set_word_boundary(hash & 512);
  options.set_one_line(hash & 1024);

  const char* ptr = reinterpret_cast<const char*>(data);
  int len = static_cast<int>(size);

  StringPiece pattern(ptr, len);
  StringPiece text(ptr, len);
  Test(pattern, options, text);

  return 0;
}
<|endoftext|>


<commit_before>/* The Next Great Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

/* This library 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 2.1 of the License, or (at your option) any later version. */

/* This library 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 this library; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

//
Miscellaneous Example 8 - Meshfree Interpolation Utilities.

//
// LibMesh provides some utilities for pointcloud-type interpolation, as
// demonstrated in this example.

// Example include files
#include "libmesh/libmesh.h"
#include "libmesh/meshfree_interpolation.h"
#include "libmesh/mesh.h"
#include "libmesh/equation_systems.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/tecplot_io.h"
#include "libmesh/threads.h"
#include "meshless_interpolation_function.h"

// C++ includes
#include <cstdlib>

// Bring in everything from the libMesh namespace
using namespace libMesh;

void create_random_point_cloud (const unsigned int Npts,
				std::vector<Point> &pts,
				const Real max_range = 10)
{
  std::cout << "Generating "<< Npts << " point cloud...";
  pts.resize(Npts);

  for (size_t i=0;i<Npts;i++)
    {
      pts[i](0) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](1) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](2) = max_range * (std::rand() % 1000) / Real(1000);
    }
  std::cout << "done\n";
}

Real exact_solution_u (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x*x   +
	  y*y*y*y +
	  z*z*z*z*z);
}

Real exact_solution_v (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x   +
	  y*y +
	  z*z*z);
}

Number exact_value (const Point& p,
                    const Parameters&,
                    const std::string&,
                    const std::string&)
{
  return exact_solution_v(p);
}

// We now define the function which provides the
// initialization routines for the "Convection-Diffusion"
// system.  This handles things like setting initial
// conditions and boundary conditions.
void init_sys(EquationSystems& es,
              const std::string& system_name)
{
  // Get a reference to the Convection-Diffusion system object.
  System & system =
    es.get_system<System>(system_name);

  system.project_solution(exact_value, NULL, es.parameters);
}

int main(int argc, char** argv)
{
  // Initialize libMesh.
  LibMeshInit init (argc, argv);
  {
    // Demonstration case 1
    {
      std::vector<Point>       tgt_pts;
      std::vector<Number>      tgt_data;
      std::vector<std::string> field_vars;

      field_vars.push_back("u");
      field_vars.push_back("v");

      InverseDistanceInterpolation<3> idi (/* n_interp_pts = */ 8,
					   /* power =        */ 2);

      idi.set_field_variables (field_vars);

      create_random_point_cloud (1e5,
				 idi.get_source_points());

      // Explicitly set the data values we will interpolate from
      {
	const std::vector<Point> &src_pts  (idi.get_source_points());
	std::vector<Real>        &src_vals (idi.get_source_vals());

	src_vals.clear(); src_vals.reserve(src_pts.size());

	for (std::vector<Point>::const_iterator pt_it=src_pts.begin();
	     pt_it != src_pts.end(); ++pt_it)
	  {
	    src_vals.push_back (exact_solution_u (*pt_it));
	    src_vals.push_back (exact_solution_v (*pt_it));
	  }
      }

      std::cout << idi;

      // Interpolate to some other random points, and evaluate the result
      {
	create_random_point_cloud (10,
				   tgt_pts);

	idi.interpolate_field_data (field_vars,
				    tgt_pts,
				    tgt_data);

	std::vector<Number>::const_iterator v_it=tgt_data.begin();

	for (std::vector<Point>::const_iterator  p_it=tgt_pts.begin();
	     p_it!=tgt_pts.end(); ++p_it)
	  {
	    std::cout << "\nAt target point " << *p_it
		      << "\n u_interp=" << *v_it
		      << ", u_exact="  << exact_solution_u(*p_it);
	    ++v_it;
	    std::cout << "\n v_interp=" << *v_it
		      << ", v_exact="  << exact_solution_v(*p_it)
		      << std::endl;
	    ++v_it;
	  }
      }
    }

    // Demonstration case 2
    {
      Mesh mesh_a, mesh_b;

      mesh_a.read("struct.ucd.gz"); mesh_b.read("unstruct.ucd.gz");

      // Create equation systems objects.
      EquationSystems
	es_a(mesh_a), es_b(mesh_b);

      System
	&sys_a = es_a.add_system<System>("src_system"),
	&sys_b = es_b.add_system<System>("dest_system");

      sys_a.add_variable ("Cp", FIRST);
      sys_b.add_variable ("Cp", FIRST);

      sys_a.attach_init_function (init_sys);
      es_a.init();

      // Write out the initial conditions.
      TecplotIO(mesh_a).write_equation_systems ("src.dat",
						es_a);

      InverseDistanceInterpolation<3> idi (/* n_interp_pts = */ 4,
					   /* power =        */ 2);

      std::vector<Point>  &src_pts  (idi.get_source_points());
      std::vector<Number> &src_vals (idi.get_source_vals());
      std::vector<std::string> field_vars;
      field_vars.push_back("Cp");
      idi.set_field_variables(field_vars);

      // We now will loop over every node in the source mesh
      // and add it to a source point list, along with the solution
      {
	MeshBase::const_node_iterator nd  = mesh_a.local_nodes_begin();
	MeshBase::const_node_iterator end = mesh_a.local_nodes_end();

	for (; nd!=end; ++nd)
	  {
	    const Node *node(*nd);
	    src_pts.push_back(*node);
	    src_vals.push_back(sys_a.current_solution(node->dof_number(0,0,0)));
	  }
      }

      // We have only set local values - prepare for use by gathering remote gata
      idi.prepare_for_use();

      // Create a MeshlessInterpolationFunction that uses our InverseDistanceInterpolation
      // object.  Since each MeshlessInterpolationFunction shares the same InverseDistanceInterpolation
      // object in a threaded environment we must also provide a locking mechanism.
      Threads::spin_mutex mutex;
      MeshlessInterpolationFunction mif(idi, mutex);

      // project the solution onto system b
      es_b.init();
      sys_b.project_solution (&mif);

      // Write the result
      TecplotIO(mesh_b).write_equation_systems ("dest.dat",
						es_b);
    }

  }
  return 0;
}
<commit_msg>skip for DIM=1,2<commit_after>/* The Next Great Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

/* This library 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 2.1 of the License, or (at your option) any later version. */

/* This library 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 this library; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

//
Miscellaneous Example 8 - Meshfree Interpolation Utilities.

//
// LibMesh provides some utilities for pointcloud-type interpolation, as
// demonstrated in this example.

// Example include files
#include "libmesh/libmesh.h"
#include "libmesh/meshfree_interpolation.h"
#include "libmesh/mesh.h"
#include "libmesh/equation_systems.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/tecplot_io.h"
#include "libmesh/threads.h"
#include "meshless_interpolation_function.h"

// C++ includes
#include <cstdlib>

// Bring in everything from the libMesh namespace
using namespace libMesh;

void create_random_point_cloud (const unsigned int Npts,
				std::vector<Point> &pts,
				const Real max_range = 10)
{
  std::cout << "Generating "<< Npts << " point cloud...";
  pts.resize(Npts);

  for (size_t i=0;i<Npts;i++)
    {
      pts[i](0) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](1) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](2) = max_range * (std::rand() % 1000) / Real(1000);
    }
  std::cout << "done\n";
}

Real exact_solution_u (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x*x   +
	  y*y*y*y +
	  z*z*z*z*z);
}

Real exact_solution_v (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x   +
	  y*y +
	  z*z*z);
}

Number exact_value (const Point& p,
                    const Parameters&,
                    const std::string&,
                    const std::string&)
{
  return exact_solution_v(p);
}

// We now define the function which provides the
// initialization routines for the "Convection-Diffusion"
// system.  This handles things like setting initial
// conditions and boundary conditions.
void init_sys(EquationSystems& es,
              const std::string& system_name)
{
  // Get a reference to the Convection-Diffusion system object.
  System & system =
    es.get_system<System>(system_name);

  system.project_solution(exact_value, NULL, es.parameters);
}

int main(int argc, char** argv)
{
#if LIBMESH_DIM != 3
  std::cout << "This example requires 3D support - skipping.\n";
  return 77;
#endif

  // Initialize libMesh.
  LibMeshInit init (argc, argv);
  {
    // Demonstration case 1
    {
      std::vector<Point>       tgt_pts;
      std::vector<Number>      tgt_data;
      std::vector<std::string> field_vars;

      field_vars.push_back("u");
      field_vars.push_back("v");

      InverseDistanceInterpolation<3> idi (/* n_interp_pts = */ 8,
					   /* power =        */ 2);

      idi.set_field_variables (field_vars);

      create_random_point_cloud (1e5,
				 idi.get_source_points());

      // Explicitly set the data values we will interpolate from
      {
	const std::vector<Point> &src_pts  (idi.get_source_points());
	std::vector<Real>        &src_vals (idi.get_source_vals());

	src_vals.clear(); src_vals.reserve(src_pts.size());

	for (std::vector<Point>::const_iterator pt_it=src_pts.begin();
	     pt_it != src_pts.end(); ++pt_it)
	  {
	    src_vals.push_back (exact_solution_u (*pt_it));
	    src_vals.push_back (exact_solution_v (*pt_it));
	  }
      }

      std::cout << idi;

      // Interpolate to some other random points, and evaluate the result
      {
	create_random_point_cloud (10,
				   tgt_pts);

	idi.interpolate_field_data (field_vars,
				    tgt_pts,
				    tgt_data);

	std::vector<Number>::const_iterator v_it=tgt_data.begin();

	for (std::vector<Point>::const_iterator  p_it=tgt_pts.begin();
	     p_it!=tgt_pts.end(); ++p_it)
	  {
	    std::cout << "\nAt target point " << *p_it
		      << "\n u_interp=" << *v_it
		      << ", u_exact="  << exact_solution_u(*p_it);
	    ++v_it;
	    std::cout << "\n v_interp=" << *v_it
		      << ", v_exact="  << exact_solution_v(*p_it)
		      << std::endl;
	    ++v_it;
	  }
      }
    }

    // Demonstration case 2
    {
      Mesh mesh_a, mesh_b;

      mesh_a.read("struct.ucd.gz"); mesh_b.read("unstruct.ucd.gz");

      // Create equation systems objects.
      EquationSystems
	es_a(mesh_a), es_b(mesh_b);

      System
	&sys_a = es_a.add_system<System>("src_system"),
	&sys_b = es_b.add_system<System>("dest_system");

      sys_a.add_variable ("Cp", FIRST);
      sys_b.add_variable ("Cp", FIRST);

      sys_a.attach_init_function (init_sys);
      es_a.init();

      // Write out the initial conditions.
      TecplotIO(mesh_a).write_equation_systems ("src.dat",
						es_a);

      InverseDistanceInterpolation<3> idi (/* n_interp_pts = */ 4,
					   /* power =        */ 2);

      std::vector<Point>  &src_pts  (idi.get_source_points());
      std::vector<Number> &src_vals (idi.get_source_vals());
      std::vector<std::string> field_vars;
      field_vars.push_back("Cp");
      idi.set_field_variables(field_vars);

      // We now will loop over every node in the source mesh
      // and add it to a source point list, along with the solution
      {
	MeshBase::const_node_iterator nd  = mesh_a.local_nodes_begin();
	MeshBase::const_node_iterator end = mesh_a.local_nodes_end();

	for (; nd!=end; ++nd)
	  {
	    const Node *node(*nd);
	    src_pts.push_back(*node);
	    src_vals.push_back(sys_a.current_solution(node->dof_number(0,0,0)));
	  }
      }

      // We have only set local values - prepare for use by gathering remote gata
      idi.prepare_for_use();

      // Create a MeshlessInterpolationFunction that uses our InverseDistanceInterpolation
      // object.  Since each MeshlessInterpolationFunction shares the same InverseDistanceInterpolation
      // object in a threaded environment we must also provide a locking mechanism.
      Threads::spin_mutex mutex;
      MeshlessInterpolationFunction mif(idi, mutex);

      // project the solution onto system b
      es_b.init();
      sys_b.project_solution (&mif);

      // Write the result
      TecplotIO(mesh_b).write_equation_systems ("dest.dat",
						es_b);
    }

  }
  return 0;
}
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(1)

class MinStack {
public:
    void push(int number) {
        if (elements_.empty()) {
            elements_.emplace(0);
            stack_min_ = number;
        } else {
            elements_.emplace(static_cast<int64_t>(number) - stack_min_);
            if (number < stack_min_) {
                stack_min_ = number; // Update min.
            }
        }
    }

    void pop() {
        auto diff = elements_.top();
        elements_.pop();
        if (diff < 0) {
            stack_min_ -= diff; // Restore previous min.
        }
    }

    int top() {
        if (elements_.top() > 0) {
            return stack_min_ + elements_.top();
        } else {
            return stack_min_;
        }
    }

    int getMin() {
        return stack_min_;
    }

private:
    stack<int64_t> elements_;
    int stack_min_;
};

// Time:  O(n)
// Space: O(n)
class MinStack2 {
public:
    void push(int number) {
        if (cached_min_with_count_.empty() || cached_min_with_count_.top().first > number) {
            cached_min_with_count_.emplace(number, 1);
        } else if (cached_min_with_count_.top().first == number) {
            ++cached_min_with_count_.top().second;
        }
        elements_.emplace(number);
    }

    void pop() {
        if (!elements_.empty()) {
            if (!cached_min_with_count_.empty() &&
                cached_min_with_count_.top().first == elements_.top()) {
                if (--cached_min_with_count_.top().second == 0) {
                    cached_min_with_count_.pop();
                }
            }
            auto number = elements_.top();
            elements_.pop();
        }
    }

    int top() {
        return elements_.top();
    }

    int getMin() {
        if (!cached_min_with_count_.empty()) {
            return cached_min_with_count_.top().first;
        }
    }

private:
    stack<int> elements_;
    stack<pair<int, int>> cached_min_with_count_;
};
<commit_msg>Update min-stack.cpp<commit_after>// Time:  O(n)
// Space: O(1)

class MinStack {
public:
    void push(int number) {
        if (elements_.empty()) {
            elements_.emplace(0);
            stack_min_ = number;
        } else {
            elements_.emplace(static_cast<int64_t>(number) - stack_min_);
            if (number < stack_min_) {
                stack_min_ = number; // Update min.
            }
        }
    }

    void pop() {
        auto diff = elements_.top();
        elements_.pop();
        if (diff < 0) {
            stack_min_ -= diff; // Restore previous min.
        }
    }

    int top() {
        if (elements_.top() > 0) {
            return stack_min_ + elements_.top();
        } else {
            return stack_min_;
        }
    }

    int getMin() {
        return stack_min_;
    }

private:
    stack<int64_t> elements_;
    int stack_min_;
};

// Time:  O(n)
// Space: O(n)
class MinStack2 {
public:
    void push(int number) {
        if (cached_min_with_count_.empty() || cached_min_with_count_.top().first > number) {
            cached_min_with_count_.emplace(number, 1);
        } else if (cached_min_with_count_.top().first == number) {
            ++cached_min_with_count_.top().second;
        }
        elements_.emplace(number);
    }

    void pop() {
        if (cached_min_with_count_.top().first == elements_.top()) {
            if (--cached_min_with_count_.top().second == 0) {
                cached_min_with_count_.pop();
            }
        }
        elements_.pop();
    }

    int top() {
        return elements_.top();
    }

    int getMin() {
        return cached_min_with_count_.top().first;
    }

private:
    stack<int> elements_;
    stack<pair<int, int>> cached_min_with_count_;
};
<|endoftext|>


<commit_before>/******************************************************************************

  This source file is part of the TEM tomography project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "CentralWidget.h"
#include "ui_CentralWidget.h"

#include <pqView.h>
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkContextMouseEvent.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkEventQtSlotConnect.h>
#include <vtkFloatArray.h>
#include <vtkImageData.h>
#include <vtkIntArray.h>
#include <vtkMathUtilities.h>
#include <vtkObjectFactory.h>
#include <vtkPlotBar.h>
#include <vtkPointData.h>
#include <vtkSMSourceProxy.h>
#include <vtkSMViewProxy.h>
#include <vtkTable.h>
#include <vtkTransform2D.h>
#include <vtkTrivialProducer.h>
#include <vtkContext2D.h>
#include <vtkPen.h>

#include <QtDebug>
#include <QThread>

#include "ActiveObjects.h"
#include "ComputeHistogram.h"
#include "DataSource.h"
#include "ModuleContour.h"
#include "ModuleManager.h"
#include "Utilities.h"

#ifdef DAX_DEVICE_ADAPTER
# include "dax/ModuleStreamingContour.h"
#endif

namespace TEM
{

//-----------------------------------------------------------------------------
// This is just here for now - quick and dirty historgram calculations...
void PopulateHistogram(vtkImageData *input, vtkTable *output)
{
  // The output table will have the twice the number of columns, they will be
  // the x and y for input column. This is the bin centers, and the population.
  double minmax[2] = { 0.0, 0.0 };
  const int numberOfBins = 256;

  // The bin values are the centers, extending +/- half an inc either side
  switch (input->GetScalarType())
    {
    vtkTemplateMacro(
          TEM::GetScalarRange(reinterpret_cast<VTK_TT *>(input->GetPointData()->GetScalars()->GetVoidPointer(0)),
                         input->GetPointData()->GetScalars()->GetNumberOfTuples(),
                         minmax));
    default:
      break;
    }
  if (minmax[0] == minmax[1])
    {
    minmax[1] = minmax[0] + 1.0;
    }

  double inc = (minmax[1] - minmax[0]) / numberOfBins;
  double halfInc = inc / 2.0;
  vtkSmartPointer<vtkFloatArray> extents =
      vtkFloatArray::SafeDownCast(
        output->GetColumnByName(vtkStdString("image_extents").c_str()));
  if (!extents)
    {
    extents = vtkSmartPointer<vtkFloatArray>::New();
    extents->SetName(vtkStdString("image_extents").c_str());
    }
  extents->SetNumberOfTuples(numberOfBins);
  double min = minmax[0] + halfInc;
  for (int j = 0; j < numberOfBins; ++j)
    {
    extents->SetValue(j, min + j * inc);
    }
  vtkSmartPointer<vtkIntArray> populations =
      vtkIntArray::SafeDownCast(
        output->GetColumnByName(vtkStdString("image_pops").c_str()));
  if (!populations)
    {
    populations = vtkSmartPointer<vtkIntArray>::New();
    populations->SetName(vtkStdString("image_pops").c_str());
    }
  populations->SetNumberOfTuples(numberOfBins);
  int *pops = static_cast<int *>(populations->GetVoidPointer(0));
  for (int k = 0; k < numberOfBins; ++k)
    {
    pops[k] = 0;
    }

  switch (input->GetScalarType())
    {
    vtkTemplateMacro(
          TEM::CalculateHistogram(reinterpret_cast<VTK_TT *>(input->GetPointData()->GetScalars()->GetVoidPointer(0)),
                             input->GetPointData()->GetScalars()->GetNumberOfTuples(),
                             minmax[0], pops, inc, numberOfBins));
    default:
      cout << "UpdateFromFile: Unknown data type" << endl;
    }

#ifndef NDEBUG
  vtkIdType total = 0;
  for (int i = 0; i < numberOfBins; ++i)
    total += pops[i];
  assert(total == input->GetPointData()->GetScalars()->GetNumberOfTuples());
#endif

  output->AddColumn(extents.GetPointer());
  output->AddColumn(populations.GetPointer());
}

// Quick background thread for the histogram calculation.
class HistogramWorker : public QThread
{
  Q_OBJECT

  void run();

public:
  HistogramWorker(QObject *p = 0) : QThread(p) {}

  vtkSmartPointer<vtkImageData> input;
  vtkSmartPointer<vtkTable> output;
};

void HistogramWorker::run()
{
  if (input && output)
    {
    PopulateHistogram(input.Get(), output.Get());
    }
}

class CentralWidget::CWInternals
{
public:
  Ui::CentralWidget Ui;
};

class vtkHistogramMarker : public vtkPlot
{
public:
  static vtkHistogramMarker * New();
  double PositionX;

  bool Paint(vtkContext2D *painter)
  {
    vtkNew<vtkPen> pen;
    pen->SetColor(255, 0, 0, 255);
    pen->SetWidth(2.0);
    painter->ApplyPen(pen.Get());
    painter->DrawLine(PositionX, 0, PositionX, 1e9);
    return true;
  }
};
vtkStandardNewMacro(vtkHistogramMarker);

class vtkChartHistogram : public vtkChartXY
{
public:
  static vtkChartHistogram * New();

  bool MouseDoubleClickEvent(const vtkContextMouseEvent &mouse);

  vtkNew<vtkTransform2D> Transform;
  double PositionX;
  vtkNew<vtkHistogramMarker> Marker;
};

vtkStandardNewMacro(vtkChartHistogram)

bool vtkChartHistogram::MouseDoubleClickEvent(const vtkContextMouseEvent &m)
{
  // Determine the location of the click, and emit something we can listen to!
  vtkPlotBar *histo = 0;
  if (this->GetNumberOfPlots() > 0)
    {
    histo = vtkPlotBar::SafeDownCast(this->GetPlot(0));
    }
  if (!histo)
    {
    return false;
    }
  this->CalculateUnscaledPlotTransform(histo->GetXAxis(), histo->GetYAxis(),
                                       this->Transform.Get());
  vtkVector2f pos;
  this->Transform->InverseTransformPoints(m.GetScenePos().GetData(), pos.GetData(),
                                          1);
  this->PositionX = pos.GetX();
  this->Marker->PositionX = this->PositionX;
  this->Marker->Modified();
  this->Scene->SetDirty(true);
  if (this->GetNumberOfPlots() == 1)
    {
    this->AddPlot(this->Marker.Get());
    }
  this->InvokeEvent(vtkCommand::CursorChangedEvent);
  return true;
}

//-----------------------------------------------------------------------------
CentralWidget::CentralWidget(QWidget* parentObject, Qt::WindowFlags wflags)
  : Superclass(parentObject, wflags),
    Internals(new CentralWidget::CWInternals()),
    Worker(NULL)
{
  this->Internals->Ui.setupUi(this);

  QList<int> sizes;
  sizes << 200 << 200;
  this->Internals->Ui.splitter->setSizes(sizes);
  this->Internals->Ui.splitter->setStretchFactor(0, 0);
  this->Internals->Ui.splitter->setStretchFactor(1, 1);

  // Set up our little chart.
  this->Histogram
      ->SetInteractor(this->Internals->Ui.histogramWidget->GetInteractor());
  this->Internals->Ui.histogramWidget
      ->SetRenderWindow(this->Histogram->GetRenderWindow());
  vtkChartHistogram* chart = this->Chart.Get();
  this->Histogram->GetScene()->AddItem(chart);
  chart->SetBarWidthFraction(0.95);
  chart->SetRenderEmpty(true);
  chart->SetAutoAxes(false);
  chart->GetAxis(vtkAxis::LEFT)->SetTitle("");
  chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("");
  chart->GetAxis(vtkAxis::LEFT)->SetBehavior(vtkAxis::FIXED);
  chart->GetAxis(vtkAxis::LEFT)->SetRange(0.0001, 10);
  chart->GetAxis(vtkAxis::LEFT)->SetMinimumLimit(1);
  chart->GetAxis(vtkAxis::LEFT)->SetLogScale(true);

  this->EventLink->Connect(chart, vtkCommand::CursorChangedEvent, this,
                           SLOT(histogramClicked(vtkObject*)));
}

//-----------------------------------------------------------------------------
CentralWidget::~CentralWidget()
{
}

//-----------------------------------------------------------------------------
void CentralWidget::setDataSource(DataSource* source)
{
  if (this->ADataSource)
    {
    this->disconnect(this->ADataSource);
    }
  this->ADataSource = source;
  if (source)
    {
    this->connect(source, SIGNAL(dataChanged()), SLOT(refreshHistogram()));
    }

  // Whenever the data source changes clear the plot, and then populate when
  // ready (or use the cached histogram values.
  this->Chart->ClearPlots();

  if (!source)
    {
    return;
    }

  // Get the actual data source, build a histogram out of it.
  vtkTrivialProducer *t = vtkTrivialProducer::SafeDownCast(
    source->producer()->GetClientSideObject());
  vtkImageData *data = vtkImageData::SafeDownCast(t->GetOutputDataObject(0));

  // Check our cache, and use that if appopriate (or update it).
  if (this->HistogramCache.contains(data))
    {
    vtkTable *cachedTable = this->HistogramCache[data];
    if (cachedTable->GetMTime() > data->GetMTime())
      {
      this->setHistogramTable(cachedTable);
      return;
      }
    else
      {
      // Should this ever happen? Do we want to support this? -- YES!!!
      //qDebug() << "Image data changed after histogram calculation.";
      //return;
      this->HistogramCache.remove(data);
      }
    }

  // Calculate a histogram.
  vtkNew<vtkTable> table;
  this->HistogramCache[data] = table.Get();

  if (!this->Worker)
    {
    this->Worker = new HistogramWorker(this);
    connect(this->Worker, SIGNAL(finished()), SLOT(histogramReady()));
    }
  else if (this->Worker->isRunning())
    {
    // FIXME: Queue, abort, something.
    qDebug() << "Worker already running, skipping this one.";
    return;
    }
  this->Worker->input = data;
  this->Worker->output = table.Get();
  this->Worker->start();
}

void CentralWidget::refreshHistogram()
{
  this->setDataSource(this->ADataSource);
}

void CentralWidget::histogramReady()
{
  if (!this->Worker || !this->Worker->input || !this->Worker->output)
    return;

  this->setHistogramTable(this->Worker->output.Get());

  this->Worker->input = NULL;
  this->Worker->output = NULL;
}

void CentralWidget::histogramClicked(vtkObject *caller)
{
  //qDebug() << "Histogram clicked at" << this->Chart->PositionX
  //         << "making this a great spot to ask for an isosurface at value"
  //         << this->Chart->PositionX;
  Q_ASSERT(this->ADataSource);

  vtkSMViewProxy* view = ActiveObjects::instance().activeView();
  if (!view)
    {
    return;
    }

  // Use active ModuleContour is possible. Otherwise, find the first existing
  // ModuleContour instance or just create a new one, if none exists.
#ifdef DAX_DEVICE_ADAPTER
  typedef ModuleStreamingContour ModuleContourType;
#else
  typedef ModuleContour ModuleContourType;
#endif

  ModuleContourType* contour = qobject_cast<ModuleContourType*>(
    ActiveObjects::instance().activeModule());
  if (!contour)
    {
    QList<ModuleContourType*> contours =
      ModuleManager::instance().findModules<ModuleContourType*>(this->ADataSource, view);
    if (contours.size() == 0)
      {
      contour = qobject_cast<ModuleContourType*>(ModuleManager::instance().createAndAddModule(
          "Contour", this->ADataSource, view));
      }
    else
      {
      contour = contours[0];
      }
    ActiveObjects::instance().setActiveModule(contour);
    }
  Q_ASSERT(contour);
  contour->setIsoValue(this->Chart->PositionX);
  TEM::convert<pqView*>(view)->render();
}

void CentralWidget::setHistogramTable(vtkTable *table)
{
  this->Chart->ClearPlots();
  vtkPlot *plot = this->Chart->AddPlot(vtkChart::BAR);
  plot->SetInputData(table, "image_extents", "image_pops");
  plot->SetColor(0, 0, 255, 255);
  vtkDataArray *arr =
      vtkDataArray::SafeDownCast(table->GetColumnByName("image_pops"));
  if (arr)
    {
    double max = log10(arr->GetRange()[1]);
    vtkAxis *axis = this->Chart->GetAxis(vtkAxis::LEFT);
    axis->SetUnscaledMinimum(1.0);
    axis->SetMaximumLimit(max + 2.0);
    axis->SetMaximum(static_cast<int>(max) + 1.0);
    }
}

} // end of namespace TEM

#include "CentralWidget.moc"
<commit_msg>Don't use an outline with the histogram<commit_after>/******************************************************************************

  This source file is part of the TEM tomography project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "CentralWidget.h"
#include "ui_CentralWidget.h"

#include <pqView.h>
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkContextMouseEvent.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkEventQtSlotConnect.h>
#include <vtkFloatArray.h>
#include <vtkImageData.h>
#include <vtkIntArray.h>
#include <vtkMathUtilities.h>
#include <vtkObjectFactory.h>
#include <vtkPlotBar.h>
#include <vtkPointData.h>
#include <vtkSMSourceProxy.h>
#include <vtkSMViewProxy.h>
#include <vtkTable.h>
#include <vtkTransform2D.h>
#include <vtkTrivialProducer.h>
#include <vtkContext2D.h>
#include <vtkPen.h>

#include <QtDebug>
#include <QThread>

#include "ActiveObjects.h"
#include "ComputeHistogram.h"
#include "DataSource.h"
#include "ModuleContour.h"
#include "ModuleManager.h"
#include "Utilities.h"

#ifdef DAX_DEVICE_ADAPTER
# include "dax/ModuleStreamingContour.h"
#endif

namespace TEM
{

//-----------------------------------------------------------------------------
// This is just here for now - quick and dirty historgram calculations...
void PopulateHistogram(vtkImageData *input, vtkTable *output)
{
  // The output table will have the twice the number of columns, they will be
  // the x and y for input column. This is the bin centers, and the population.
  double minmax[2] = { 0.0, 0.0 };
  const int numberOfBins = 256;

  // The bin values are the centers, extending +/- half an inc either side
  switch (input->GetScalarType())
    {
    vtkTemplateMacro(
          TEM::GetScalarRange(reinterpret_cast<VTK_TT *>(input->GetPointData()->GetScalars()->GetVoidPointer(0)),
                         input->GetPointData()->GetScalars()->GetNumberOfTuples(),
                         minmax));
    default:
      break;
    }
  if (minmax[0] == minmax[1])
    {
    minmax[1] = minmax[0] + 1.0;
    }

  double inc = (minmax[1] - minmax[0]) / numberOfBins;
  double halfInc = inc / 2.0;
  vtkSmartPointer<vtkFloatArray> extents =
      vtkFloatArray::SafeDownCast(
        output->GetColumnByName(vtkStdString("image_extents").c_str()));
  if (!extents)
    {
    extents = vtkSmartPointer<vtkFloatArray>::New();
    extents->SetName(vtkStdString("image_extents").c_str());
    }
  extents->SetNumberOfTuples(numberOfBins);
  double min = minmax[0] + halfInc;
  for (int j = 0; j < numberOfBins; ++j)
    {
    extents->SetValue(j, min + j * inc);
    }
  vtkSmartPointer<vtkIntArray> populations =
      vtkIntArray::SafeDownCast(
        output->GetColumnByName(vtkStdString("image_pops").c_str()));
  if (!populations)
    {
    populations = vtkSmartPointer<vtkIntArray>::New();
    populations->SetName(vtkStdString("image_pops").c_str());
    }
  populations->SetNumberOfTuples(numberOfBins);
  int *pops = static_cast<int *>(populations->GetVoidPointer(0));
  for (int k = 0; k < numberOfBins; ++k)
    {
    pops[k] = 0;
    }

  switch (input->GetScalarType())
    {
    vtkTemplateMacro(
          TEM::CalculateHistogram(reinterpret_cast<VTK_TT *>(input->GetPointData()->GetScalars()->GetVoidPointer(0)),
                             input->GetPointData()->GetScalars()->GetNumberOfTuples(),
                             minmax[0], pops, inc, numberOfBins));
    default:
      cout << "UpdateFromFile: Unknown data type" << endl;
    }

#ifndef NDEBUG
  vtkIdType total = 0;
  for (int i = 0; i < numberOfBins; ++i)
    total += pops[i];
  assert(total == input->GetPointData()->GetScalars()->GetNumberOfTuples());
#endif

  output->AddColumn(extents.GetPointer());
  output->AddColumn(populations.GetPointer());
}

// Quick background thread for the histogram calculation.
class HistogramWorker : public QThread
{
  Q_OBJECT

  void run();

public:
  HistogramWorker(QObject *p = 0) : QThread(p) {}

  vtkSmartPointer<vtkImageData> input;
  vtkSmartPointer<vtkTable> output;
};

void HistogramWorker::run()
{
  if (input && output)
    {
    PopulateHistogram(input.Get(), output.Get());
    }
}

class CentralWidget::CWInternals
{
public:
  Ui::CentralWidget Ui;
};

class vtkHistogramMarker : public vtkPlot
{
public:
  static vtkHistogramMarker * New();
  double PositionX;

  bool Paint(vtkContext2D *painter)
  {
    vtkNew<vtkPen> pen;
    pen->SetColor(255, 0, 0, 255);
    pen->SetWidth(2.0);
    painter->ApplyPen(pen.Get());
    painter->DrawLine(PositionX, 0, PositionX, 1e9);
    return true;
  }
};
vtkStandardNewMacro(vtkHistogramMarker);

class vtkChartHistogram : public vtkChartXY
{
public:
  static vtkChartHistogram * New();

  bool MouseDoubleClickEvent(const vtkContextMouseEvent &mouse);

  vtkNew<vtkTransform2D> Transform;
  double PositionX;
  vtkNew<vtkHistogramMarker> Marker;
};

vtkStandardNewMacro(vtkChartHistogram)

bool vtkChartHistogram::MouseDoubleClickEvent(const vtkContextMouseEvent &m)
{
  // Determine the location of the click, and emit something we can listen to!
  vtkPlotBar *histo = 0;
  if (this->GetNumberOfPlots() > 0)
    {
    histo = vtkPlotBar::SafeDownCast(this->GetPlot(0));
    }
  if (!histo)
    {
    return false;
    }
  this->CalculateUnscaledPlotTransform(histo->GetXAxis(), histo->GetYAxis(),
                                       this->Transform.Get());
  vtkVector2f pos;
  this->Transform->InverseTransformPoints(m.GetScenePos().GetData(), pos.GetData(),
                                          1);
  this->PositionX = pos.GetX();
  this->Marker->PositionX = this->PositionX;
  this->Marker->Modified();
  this->Scene->SetDirty(true);
  if (this->GetNumberOfPlots() == 1)
    {
    this->AddPlot(this->Marker.Get());
    }
  this->InvokeEvent(vtkCommand::CursorChangedEvent);
  return true;
}

//-----------------------------------------------------------------------------
CentralWidget::CentralWidget(QWidget* parentObject, Qt::WindowFlags wflags)
  : Superclass(parentObject, wflags),
    Internals(new CentralWidget::CWInternals()),
    Worker(NULL)
{
  this->Internals->Ui.setupUi(this);

  QList<int> sizes;
  sizes << 200 << 200;
  this->Internals->Ui.splitter->setSizes(sizes);
  this->Internals->Ui.splitter->setStretchFactor(0, 0);
  this->Internals->Ui.splitter->setStretchFactor(1, 1);

  // Set up our little chart.
  this->Histogram
      ->SetInteractor(this->Internals->Ui.histogramWidget->GetInteractor());
  this->Internals->Ui.histogramWidget
      ->SetRenderWindow(this->Histogram->GetRenderWindow());
  vtkChartHistogram* chart = this->Chart.Get();
  this->Histogram->GetScene()->AddItem(chart);
  chart->SetBarWidthFraction(1.0);
  chart->SetRenderEmpty(true);
  chart->SetAutoAxes(false);
  chart->GetAxis(vtkAxis::LEFT)->SetTitle("");
  chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("");
  chart->GetAxis(vtkAxis::LEFT)->SetBehavior(vtkAxis::FIXED);
  chart->GetAxis(vtkAxis::LEFT)->SetRange(0.0001, 10);
  chart->GetAxis(vtkAxis::LEFT)->SetMinimumLimit(1);
  chart->GetAxis(vtkAxis::LEFT)->SetLogScale(true);

  this->EventLink->Connect(chart, vtkCommand::CursorChangedEvent, this,
                           SLOT(histogramClicked(vtkObject*)));
}

//-----------------------------------------------------------------------------
CentralWidget::~CentralWidget()
{
}

//-----------------------------------------------------------------------------
void CentralWidget::setDataSource(DataSource* source)
{
  if (this->ADataSource)
    {
    this->disconnect(this->ADataSource);
    }
  this->ADataSource = source;
  if (source)
    {
    this->connect(source, SIGNAL(dataChanged()), SLOT(refreshHistogram()));
    }

  // Whenever the data source changes clear the plot, and then populate when
  // ready (or use the cached histogram values.
  this->Chart->ClearPlots();

  if (!source)
    {
    return;
    }

  // Get the actual data source, build a histogram out of it.
  vtkTrivialProducer *t = vtkTrivialProducer::SafeDownCast(
    source->producer()->GetClientSideObject());
  vtkImageData *data = vtkImageData::SafeDownCast(t->GetOutputDataObject(0));

  // Check our cache, and use that if appopriate (or update it).
  if (this->HistogramCache.contains(data))
    {
    vtkTable *cachedTable = this->HistogramCache[data];
    if (cachedTable->GetMTime() > data->GetMTime())
      {
      this->setHistogramTable(cachedTable);
      return;
      }
    else
      {
      // Should this ever happen? Do we want to support this? -- YES!!!
      //qDebug() << "Image data changed after histogram calculation.";
      //return;
      this->HistogramCache.remove(data);
      }
    }

  // Calculate a histogram.
  vtkNew<vtkTable> table;
  this->HistogramCache[data] = table.Get();

  if (!this->Worker)
    {
    this->Worker = new HistogramWorker(this);
    connect(this->Worker, SIGNAL(finished()), SLOT(histogramReady()));
    }
  else if (this->Worker->isRunning())
    {
    // FIXME: Queue, abort, something.
    qDebug() << "Worker already running, skipping this one.";
    return;
    }
  this->Worker->input = data;
  this->Worker->output = table.Get();
  this->Worker->start();
}

void CentralWidget::refreshHistogram()
{
  this->setDataSource(this->ADataSource);
}

void CentralWidget::histogramReady()
{
  if (!this->Worker || !this->Worker->input || !this->Worker->output)
    return;

  this->setHistogramTable(this->Worker->output.Get());

  this->Worker->input = NULL;
  this->Worker->output = NULL;
}

void CentralWidget::histogramClicked(vtkObject *caller)
{
  //qDebug() << "Histogram clicked at" << this->Chart->PositionX
  //         << "making this a great spot to ask for an isosurface at value"
  //         << this->Chart->PositionX;
  Q_ASSERT(this->ADataSource);

  vtkSMViewProxy* view = ActiveObjects::instance().activeView();
  if (!view)
    {
    return;
    }

  // Use active ModuleContour is possible. Otherwise, find the first existing
  // ModuleContour instance or just create a new one, if none exists.
#ifdef DAX_DEVICE_ADAPTER
  typedef ModuleStreamingContour ModuleContourType;
#else
  typedef ModuleContour ModuleContourType;
#endif

  ModuleContourType* contour = qobject_cast<ModuleContourType*>(
    ActiveObjects::instance().activeModule());
  if (!contour)
    {
    QList<ModuleContourType*> contours =
      ModuleManager::instance().findModules<ModuleContourType*>(this->ADataSource, view);
    if (contours.size() == 0)
      {
      contour = qobject_cast<ModuleContourType*>(ModuleManager::instance().createAndAddModule(
          "Contour", this->ADataSource, view));
      }
    else
      {
      contour = contours[0];
      }
    ActiveObjects::instance().setActiveModule(contour);
    }
  Q_ASSERT(contour);
  contour->setIsoValue(this->Chart->PositionX);
  TEM::convert<pqView*>(view)->render();
}

void CentralWidget::setHistogramTable(vtkTable *table)
{
  this->Chart->ClearPlots();
  vtkPlot *plot = this->Chart->AddPlot(vtkChart::BAR);
  plot->SetInputData(table, "image_extents", "image_pops");
  plot->SetColor(0, 0, 255, 255);
  plot->GetPen()->SetLineType(vtkPen::NO_PEN);
  vtkDataArray *arr =
      vtkDataArray::SafeDownCast(table->GetColumnByName("image_pops"));
  if (arr)
    {
    double max = log10(arr->GetRange()[1]);
    vtkAxis *axis = this->Chart->GetAxis(vtkAxis::LEFT);
    axis->SetUnscaledMinimum(1.0);
    axis->SetMaximumLimit(max + 2.0);
    axis->SetMaximum(static_cast<int>(max) + 1.0);
    }
}

} // end of namespace TEM

#include "CentralWidget.moc"
<|endoftext|>


<commit_before>#include "core/value.h"
#include "types/array.h"

namespace clever {

void* ArrayType::allocData(CLEVER_TYPE_CTOR_ARGS) const
{
	ArrayObject* arr = new ArrayObject();
	std::vector<Value*>& vec = arr->getData();

	for (size_t i = 0, j = args->size(); i < j; ++i) {
		Value* val = new Value();

		val->copy(args->at(i));

		vec.push_back(val);
	}

	return arr;
}

void ArrayType::deallocData(void* data)
{
	ArrayObject* arr = static_cast<ArrayObject*>(data);
	std::vector<Value*>& vec = arr->getData();

	for (size_t i = 0, j = vec.size(); i < j; ++i) {
		vec[i]->delRef();
	}
}

void ArrayType::dump(const void* value, std::ostream& out) const
{
	Value::DataValue* data = static_cast<Value::DataValue*>(const_cast<void*>(value));
	ArrayObject* arr = static_cast<ArrayObject*>(data->obj->getObj());
	std::vector<Value*>& vec = arr->getData();

	out << "[";

	for (size_t i = 0, j = vec.size(); i < j; ++i) {
		vec.at(i)->dump(out);
		if (i < j-1) {
			out << ", ";
		}
	}

	out << "]";
}

} // clever
<commit_msg>- Fixed memory leak<commit_after>#include "core/value.h"
#include "types/array.h"

namespace clever {

void* ArrayType::allocData(CLEVER_TYPE_CTOR_ARGS) const
{
	ArrayObject* arr = new ArrayObject();
	std::vector<Value*>& vec = arr->getData();

	for (size_t i = 0, j = args->size(); i < j; ++i) {
		Value* val = new Value();

		val->copy(args->at(i));

		vec.push_back(val);
	}

	return arr;
}

void ArrayType::deallocData(void* data)
{
	ArrayObject* arr = static_cast<ArrayObject*>(data);
	std::vector<Value*>& vec = arr->getData();

	for (size_t i = 0, j = vec.size(); i < j; ++i) {
		vec[i]->delRef();
	}

	delete arr;
}

void ArrayType::dump(const void* value, std::ostream& out) const
{
	Value::DataValue* data = static_cast<Value::DataValue*>(const_cast<void*>(value));
	ArrayObject* arr = static_cast<ArrayObject*>(data->obj->getObj());
	std::vector<Value*>& vec = arr->getData();

	out << "[";

	for (size_t i = 0, j = vec.size(); i < j; ++i) {
		vec.at(i)->dump(out);
		if (i < j-1) {
			out << ", ";
		}
	}

	out << "]";
}

} // clever
<|endoftext|>