<commit_before>// Copyright (C) 1999-2016
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"

#include <tkInt.h>

#include "pannertrue.h"
#include "util.h"

// Tk Canvas Widget Function Declarations

int PannerTrueColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int,
			      Tcl_Obj *const []);

// PannerTrueColor Specs

static Tk_CustomOption tagsOption = {
  Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static Tk_ConfigSpec pannerTrueColorSpecs[] = {

  {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "panner",
   Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1",
   Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1",
   Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256",
   Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256",
   Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw",
   Tk_Offset(WidgetOptions, anchor), 0, NULL},
  {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL,
   0, TK_CONFIG_NULL_OK, &tagsOption},

  {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica",
   Tk_Offset(WidgetOptions, helvetica), 0, NULL},
  {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier",
   Tk_Offset(WidgetOptions, courier), 0, NULL},
  {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times",
   Tk_Offset(WidgetOptions, times), 0, NULL},

  {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL},
};

// Tk Static Structure

static Tk_ItemType pannerTrueColorType = {
  (char*)"pannertruecolor",            // name
  sizeof(WidgetOptions),        // size
  PannerTrueColorCreateProc,    // configProc
  pannerTrueColorSpecs,         // configSpecs
  WidgetConfigProc,             // configProc
  WidgetCoordProc,              // coordProc
  WidgetDeleteProc,             // deleteProc
  WidgetDisplayProc,            // displayProc
  0,                            // alwaysRedraw
  WidgetPointProc,              // pointProc
  WidgetAreaProc,               // areaProc
  WidgetPostscriptProc,         // postscriptProc
  WidgetScaleProc,              // scaleProc
  WidgetTranslateProc,          // translateProc
  (Tk_ItemIndexProc*)NULL,      // indexProc
  WidgetICursorProc,            // icursorProc
  (Tk_ItemSelectionProc*)NULL,  // selectionProc
  (Tk_ItemInsertProc*)NULL,     // insertProc
  (Tk_ItemDCharsProc*)NULL,     // dCharsProc
  (Tk_ItemType*)NULL            // nextPtr
};

// Non-Member Functions

int PannerTrueColor_Init(Tcl_Interp* interp)
{
  Tk_CreateItemType(&pannerTrueColorType);
  return TCL_OK;
}

int PannerTrueColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas,
			      Tk_Item* item, int argc, Tcl_Obj *const argv[])
{
  PannerTrueColor* panner = new PannerTrueColor(interp, canvas, item);

  // and set default configuration

  if (panner->configure(argc, (const char**)argv, 0) != TCL_OK) {
    delete panner;
    Tcl_AppendResult(interp, " error occured while creating pannerTrueColor.",
		     NULL);
    return TCL_ERROR;
  }

  return TCL_OK;
}

PannerTrueColor::PannerTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
  : Panner(i, c, item)
{
  configSpecs = pannerTrueColorSpecs;  // panner configure options
}

void PannerTrueColor::clearPixmap()
{
  XImage* xmap = XGetImage(display, pixmap, 0, 0,
			   options->width, options->height,
			   AllPlanes, ZPixmap);
  if (!xmap) {
    internalError("Panner: Unable to Create XImage");
    return;
  }

  memset(xmap->data, 255, xmap->bytes_per_line * xmap->height);

  TkPutImage(NULL, 0, display, pixmap, widgetGC, xmap,
	     0, 0, 0, 0, options->width, options->height);
  XDestroyImage(xmap);
}
<commit_msg>fixed USE_TK_STUBS problem with tk widget inilalization<commit_after>// Copyright (C) 1999-2016
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"

#include <tkInt.h>

#include "pannertrue.h"
#include "util.h"

// Tk Canvas Widget Function Declarations

int PannerTrueColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int,
			      Tcl_Obj *const []);

// PannerTrueColor Specs

static Tk_CustomOption tagsOption = {
  NULL, NULL, NULL
};

static Tk_ConfigSpec pannerTrueColorSpecs[] = {

  {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "panner",
   Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1",
   Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1",
   Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256",
   Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256",
   Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL},
  {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw",
   Tk_Offset(WidgetOptions, anchor), 0, NULL},
  {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL,
   0, TK_CONFIG_NULL_OK, &tagsOption},

  {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica",
   Tk_Offset(WidgetOptions, helvetica), 0, NULL},
  {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier",
   Tk_Offset(WidgetOptions, courier), 0, NULL},
  {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times",
   Tk_Offset(WidgetOptions, times), 0, NULL},

  {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL},
};

// Tk Static Structure

static Tk_ItemType pannerTrueColorType = {
  (char*)"pannertruecolor",            // name
  sizeof(WidgetOptions),        // size
  PannerTrueColorCreateProc,    // configProc
  pannerTrueColorSpecs,         // configSpecs
  WidgetConfigProc,             // configProc
  WidgetCoordProc,              // coordProc
  WidgetDeleteProc,             // deleteProc
  WidgetDisplayProc,            // displayProc
  0,                            // alwaysRedraw
  WidgetPointProc,              // pointProc
  WidgetAreaProc,               // areaProc
  WidgetPostscriptProc,         // postscriptProc
  WidgetScaleProc,              // scaleProc
  WidgetTranslateProc,          // translateProc
  (Tk_ItemIndexProc*)NULL,      // indexProc
  WidgetICursorProc,            // icursorProc
  (Tk_ItemSelectionProc*)NULL,  // selectionProc
  (Tk_ItemInsertProc*)NULL,     // insertProc
  (Tk_ItemDCharsProc*)NULL,     // dCharsProc
  (Tk_ItemType*)NULL            // nextPtr
};

// Non-Member Functions

int PannerTrueColor_Init(Tcl_Interp* interp)
{
  tagsOption.parseProc = Tk_CanvasTagsParseProc;
  tagsOption.printProc = Tk_CanvasTagsPrintProc;

  Tk_CreateItemType(&pannerTrueColorType);
  return TCL_OK;
}

int PannerTrueColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas,
			      Tk_Item* item, int argc, Tcl_Obj *const argv[])
{
  PannerTrueColor* panner = new PannerTrueColor(interp, canvas, item);

  // and set default configuration

  if (panner->configure(argc, (const char**)argv, 0) != TCL_OK) {
    delete panner;
    Tcl_AppendResult(interp, " error occured while creating pannerTrueColor.",
		     NULL);
    return TCL_ERROR;
  }

  return TCL_OK;
}

PannerTrueColor::PannerTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
  : Panner(i, c, item)
{
  configSpecs = pannerTrueColorSpecs;  // panner configure options
}

void PannerTrueColor::clearPixmap()
{
  XImage* xmap = XGetImage(display, pixmap, 0, 0,
			   options->width, options->height,
			   AllPlanes, ZPixmap);
  if (!xmap) {
    internalError("Panner: Unable to Create XImage");
    return;
  }

  memset(xmap->data, 255, xmap->bytes_per_line * xmap->height);

  TkPutImage(NULL, 0, display, pixmap, widgetGC, xmap,
	     0, 0, 0, 0, options->width, options->height);
  XDestroyImage(xmap);
}
<|endoftext|>


<commit_before>/***************************************************************************
 *  tools/benchmark_disks.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2009 Johannes Singler <singler@ira.uka.de>
 *  Copyright (C) 2013 Timo Bingmann <tb@panthema.net>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

/*
  This programm will benchmark the disks configured via .stxxl disk
  configuration files. The block manager is used to read and write blocks using
  the different allocation strategies.
*/

/*
   example gnuplot command for the output of this program:
   (x-axis: offset in GiB, y-axis: bandwidth in MiB/s)

   plot \
        "disk.log" using ($2/1024):($7) w l title "read", \
        "disk.log" using ($2/1024):($4)  w l title "write"
 */

#include <iomanip>
#include <vector>

#include <stxxl/io>
#include <stxxl/mng>
#include <stxxl/bits/common/cmdline.h>

using stxxl::timestamp;

#ifdef BLOCK_ALIGN
 #undef BLOCK_ALIGN
#endif

#define BLOCK_ALIGN  4096

#define POLL_DELAY 1000

#define CHECK_AFTER_READ 0

#define MB (1024 * 1024)

template <typename AllocStrategy>
int benchmark_disks_alloc(stxxl::uint64 length, stxxl::uint64 step_size,
                          std::string optrw)
{
    stxxl::uint64 offset = 0, endpos = offset + length;

    if (length == 0)
        endpos = std::numeric_limits<stxxl::uint64>::max();

    bool do_read = (optrw.find('r') != std::string::npos);
    bool do_write = (optrw.find('w') != std::string::npos);

    // construct block type

    const unsigned raw_block_size = 8 * MB;
    const unsigned block_size = raw_block_size / sizeof(int);

    typedef stxxl::typed_block<raw_block_size, unsigned> block_type;
    typedef stxxl::BID<raw_block_size> BID_type;

    if (step_size == 0)
        step_size = raw_block_size * stxxl::config::get_instance()->disks_number();

    stxxl::uint64 num_blocks_per_step = stxxl::div_ceil(step_size, raw_block_size);
    step_size = num_blocks_per_step * raw_block_size;

    block_type * buffer = new block_type[num_blocks_per_step];
    stxxl::request_ptr * reqs = new stxxl::request_ptr[num_blocks_per_step];
    std::vector<BID_type> blocks;
    double totaltimeread = 0, totaltimewrite = 0;
    stxxl::int64 totalsizeread = 0, totalsizewrite = 0;

    std::cout << "# Step size: "
              << stxxl::add_IEC_binary_multiplier(step_size, "B") << " ("
              << num_blocks_per_step << " blocks of "
              << stxxl::add_IEC_binary_multiplier(raw_block_size, "B") << ")"
              << " using " << AllocStrategy().name()
              << std::endl;

    // touch data, so it is actually allcoated
    for (unsigned j = 0; j < num_blocks_per_step; ++j)
        for (unsigned i = 0; i < block_size; ++i)
            buffer[j][i] = j * block_size + i;

    try {
        AllocStrategy alloc;
        while (offset < endpos)
        {
            const stxxl::int64 current_step_size = std::min<stxxl::int64>(step_size, endpos - offset);
#if CHECK_AFTER_READ
            const stxxl::int64 current_step_size_int = current_step_size / sizeof(int);
#endif
            const stxxl::uint64 current_num_blocks_per_step = stxxl::div_ceil(current_step_size, raw_block_size);

            std::cout << "Offset    " << std::setw(7) << offset / MB << " MiB: " << std::fixed;

            stxxl::unsigned_type num_total_blocks = blocks.size();
            blocks.resize(num_total_blocks + current_num_blocks_per_step);
            stxxl::block_manager::get_instance()->new_blocks(alloc, blocks.begin() + num_total_blocks, blocks.end());

            double begin = timestamp(), end, elapsed;

            if (do_write)
            {
                for (unsigned j = 0; j < current_num_blocks_per_step; j++)
                    reqs[j] = buffer[j].write(blocks[num_total_blocks + j]);

                wait_all(reqs, current_num_blocks_per_step);

                end = timestamp();
                elapsed = end - begin;
                totalsizewrite += current_step_size;
                totaltimewrite += elapsed;
            }
            else
                elapsed = 0.0;

            std::cout << std::setw(5) << std::setprecision(1) << (double(current_step_size) / MB / elapsed) << " MiB/s write, ";

            begin = timestamp();

            if (do_read)
            {
                for (unsigned j = 0; j < current_num_blocks_per_step; j++)
                    reqs[j] = buffer[j].read(blocks[num_total_blocks + j]);

                wait_all(reqs, current_num_blocks_per_step);

                end = timestamp();
                elapsed = end - begin;
                totalsizeread += current_step_size;
                totaltimeread += elapsed;
            }
            else
                elapsed = 0.0;

            std::cout << std::setw(5) << std::setprecision(1) << (double(current_step_size) / MB / elapsed) << " MiB/s read" << std::endl;

#if CHECK_AFTER_READ
            for (unsigned j = 0; j < current_num_blocks_per_step; j++)
            {
                for (unsigned i = 0; i < block_size; i++)
                {
                    if (buffer[j][i] != j * block_size + i)
                    {
                        int ibuf = i / current_step_size_int;
                        int pos = i % current_step_size_int;

                        std::cout << "Error on disk " << ibuf << " position " << std::hex << std::setw(8) << offset + pos * sizeof(int)
                                  << "  got: " << std::hex << std::setw(8) << buffer[j][i] << " wanted: " << std::hex << std::setw(8) << (j * block_size + i)
                                  << std::dec << std::endl;

                        i = (ibuf + 1) * current_step_size_int; // jump to next
                    }
                }
            }
#endif

            offset += current_step_size;
        }
    }
    catch (const std::exception & ex)
    {
        std::cout << std::endl;
        STXXL_ERRMSG(ex.what());
    }

    std::cout << "=============================================================================================" << std::endl;
    std::cout << "# Average over " << std::setw(7) << totalsizewrite / MB << " MiB: ";
    std::cout << std::setw(5) << std::setprecision(1) << (double(totalsizewrite) / MB / totaltimewrite) << " MiB/s write, ";
    std::cout << std::setw(5) << std::setprecision(1) << (double(totalsizeread) / MB / totaltimeread) << " MiB/s read" << std::endl;

    delete[] reqs;
    delete[] buffer;

    return 0;
}

int benchmark_disks(int argc, char * argv[])
{
    // parse command line

    stxxl::cmdline_parser cp;

    stxxl::uint64 length, step_size = 0;
    std::string optrw = "rw", allocstr;

    cp.add_param_bytes("size", "Amount of data to write/read from disks (e.g. 10GiB)", length);
    cp.add_opt_param_bytes("step", "Size of data written/read in one step (default: D * 8MiB)", step_size);
    cp.add_opt_param_string("r|w", "Only read or write blocks (default: both write and read)", optrw);
    cp.add_opt_param_string("alloc", "Block allocation strategy: RC, SR, FR, striping. (default: RC)", allocstr);

    cp.set_description(
        "This program will benchmark the disks configured by the standard "
        ".stxxl disk configuration files mechanism. Blocks of 8 MiB are "
        "written and/or read in sequence using the block manager. The step "
        "size describes how many blocks are written/read in one step. The "
        "are taken from block_manager using given the specified allocation "
        "strategy. If size == 0, then writing/reading operation are done "
        "until an error occurs. "
        );

    if (!cp.process(argc, argv))
        return -1;

    if (allocstr.size())
    {
        if (allocstr == "RC")
            return benchmark_disks_alloc<stxxl::RC>(length, step_size, optrw);
        if (allocstr == "SR")
            return benchmark_disks_alloc<stxxl::SR>(length, step_size, optrw);
        if (allocstr == "FR")
            return benchmark_disks_alloc<stxxl::FR>(length, step_size, optrw);
        if (allocstr == "striping")
            return benchmark_disks_alloc<stxxl::striping>(length, step_size, optrw);

        std::cout << "Unknown allocation strategy '" << allocstr << "'" << std::endl;
        cp.print_usage();
        return -1;
    }

    return benchmark_disks_alloc<STXXL_DEFAULT_ALLOC_STRATEGY>(length, step_size, optrw);
}
<commit_msg>Changing benchmark_disks command line parameters to --batch <block count>.<commit_after>/***************************************************************************
 *  tools/benchmark_disks.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2009 Johannes Singler <singler@ira.uka.de>
 *  Copyright (C) 2013 Timo Bingmann <tb@panthema.net>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

/*
  This programm will benchmark the disks configured via .stxxl disk
  configuration files. The block manager is used to read and write blocks using
  the different allocation strategies.
*/

/*
   example gnuplot command for the output of this program:
   (x-axis: offset in GiB, y-axis: bandwidth in MiB/s)

   plot \
        "disk.log" using ($2/1024):($7) w l title "read", \
        "disk.log" using ($2/1024):($4)  w l title "write"
 */

#include <iomanip>
#include <vector>

#include <stxxl/io>
#include <stxxl/mng>
#include <stxxl/bits/common/cmdline.h>

using stxxl::timestamp;

#ifdef BLOCK_ALIGN
 #undef BLOCK_ALIGN
#endif

#define BLOCK_ALIGN  4096

#define POLL_DELAY 1000

#define CHECK_AFTER_READ 0

#define MB (1024 * 1024)

template <typename AllocStrategy>
int benchmark_disks_alloc(stxxl::uint64 length, stxxl::uint64 batch_size,
                          std::string optrw)
{
    stxxl::uint64 offset = 0, endpos = offset + length;

    if (length == 0)
        endpos = std::numeric_limits<stxxl::uint64>::max();

    bool do_read = (optrw.find('r') != std::string::npos);
    bool do_write = (optrw.find('w') != std::string::npos);

    // construct block type

    const unsigned raw_block_size = 8 * MB;
    const unsigned block_size = raw_block_size / sizeof(int);

    typedef stxxl::typed_block<raw_block_size, unsigned> block_type;
    typedef stxxl::BID<raw_block_size> BID_type;

    if (batch_size == 0)
        batch_size = stxxl::config::get_instance()->disks_number();

    // calculate total bytes processed in a batch
    batch_size = raw_block_size * batch_size;

    stxxl::uint64 num_blocks_per_batch = stxxl::div_ceil(batch_size, raw_block_size);
    batch_size = num_blocks_per_batch * raw_block_size;

    block_type * buffer = new block_type[num_blocks_per_batch];
    stxxl::request_ptr * reqs = new stxxl::request_ptr[num_blocks_per_batch];
    std::vector<BID_type> blocks;
    double totaltimeread = 0, totaltimewrite = 0;
    stxxl::int64 totalsizeread = 0, totalsizewrite = 0;

    std::cout << "# Batch size: "
              << stxxl::add_IEC_binary_multiplier(batch_size, "B") << " ("
              << num_blocks_per_batch << " blocks of "
              << stxxl::add_IEC_binary_multiplier(raw_block_size, "B") << ")"
              << " using " << AllocStrategy().name()
              << std::endl;

    // touch data, so it is actually allcoated
    for (unsigned j = 0; j < num_blocks_per_batch; ++j)
        for (unsigned i = 0; i < block_size; ++i)
            buffer[j][i] = j * block_size + i;

    try {
        AllocStrategy alloc;
        while (offset < endpos)
        {
            const stxxl::int64 current_batch_size = std::min<stxxl::int64>(batch_size, endpos - offset);
#if CHECK_AFTER_READ
            const stxxl::int64 current_batch_size_int = current_batch_size / sizeof(int);
#endif
            const stxxl::uint64 current_num_blocks_per_batch = stxxl::div_ceil(current_batch_size, raw_block_size);

            std::cout << "Offset    " << std::setw(7) << offset / MB << " MiB: " << std::fixed;

            stxxl::unsigned_type num_total_blocks = blocks.size();
            blocks.resize(num_total_blocks + current_num_blocks_per_batch);
            stxxl::block_manager::get_instance()->new_blocks(alloc, blocks.begin() + num_total_blocks, blocks.end());

            double begin = timestamp(), end, elapsed;

            if (do_write)
            {
                for (unsigned j = 0; j < current_num_blocks_per_batch; j++)
                    reqs[j] = buffer[j].write(blocks[num_total_blocks + j]);

                wait_all(reqs, current_num_blocks_per_batch);

                end = timestamp();
                elapsed = end - begin;
                totalsizewrite += current_batch_size;
                totaltimewrite += elapsed;
            }
            else
                elapsed = 0.0;

            std::cout << std::setw(5) << std::setprecision(1) << (double(current_batch_size) / MB / elapsed) << " MiB/s write, ";

            begin = timestamp();

            if (do_read)
            {
                for (unsigned j = 0; j < current_num_blocks_per_batch; j++)
                    reqs[j] = buffer[j].read(blocks[num_total_blocks + j]);

                wait_all(reqs, current_num_blocks_per_batch);

                end = timestamp();
                elapsed = end - begin;
                totalsizeread += current_batch_size;
                totaltimeread += elapsed;
            }
            else
                elapsed = 0.0;

            std::cout << std::setw(5) << std::setprecision(1) << (double(current_batch_size) / MB / elapsed) << " MiB/s read" << std::endl;

#if CHECK_AFTER_READ
            for (unsigned j = 0; j < current_num_blocks_per_batch; j++)
            {
                for (unsigned i = 0; i < block_size; i++)
                {
                    if (buffer[j][i] != j * block_size + i)
                    {
                        int ibuf = i / current_batch_size_int;
                        int pos = i % current_batch_size_int;

                        std::cout << "Error on disk " << ibuf << " position " << std::hex << std::setw(8) << offset + pos * sizeof(int)
                                  << "  got: " << std::hex << std::setw(8) << buffer[j][i] << " wanted: " << std::hex << std::setw(8) << (j * block_size + i)
                                  << std::dec << std::endl;

                        i = (ibuf + 1) * current_batch_size_int; // jump to next
                    }
                }
            }
#endif

            offset += current_batch_size;
        }
    }
    catch (const std::exception & ex)
    {
        std::cout << std::endl;
        STXXL_ERRMSG(ex.what());
    }

    std::cout << "=============================================================================================" << std::endl;
    std::cout << "# Average over " << std::setw(7) << totalsizewrite / MB << " MiB: ";
    std::cout << std::setw(5) << std::setprecision(1) << (double(totalsizewrite) / MB / totaltimewrite) << " MiB/s write, ";
    std::cout << std::setw(5) << std::setprecision(1) << (double(totalsizeread) / MB / totaltimeread) << " MiB/s read" << std::endl;

    delete[] reqs;
    delete[] buffer;

    return 0;
}

int benchmark_disks(int argc, char * argv[])
{
    // parse command line

    stxxl::cmdline_parser cp;

    stxxl::uint64 length = 0;
    unsigned int batch_size = 0;
    std::string optrw = "rw", allocstr;

    cp.add_param_bytes("size", "Amount of data to write/read from disks (e.g. 10GiB)", length);
    cp.add_opt_param_string("r|w", "Only read or write blocks (default: both write and read)", optrw);
    cp.add_opt_param_string("alloc", "Block allocation strategy: RC, SR, FR, striping. (default: RC)", allocstr);

    cp.add_uint('b', "batch", "Number of blocks written/read in one batch (default: D * 8MiB)", batch_size);

    cp.set_description(
        "This program will benchmark the disks configured by the standard "
        ".stxxl disk configuration files mechanism. Blocks of 8 MiB are "
        "written and/or read in sequence using the block manager. The batch "
        "size describes how many blocks are written/read in one batch. The "
        "are taken from block_manager using given the specified allocation "
        "strategy. If size == 0, then writing/reading operation are done "
        "until an error occurs. "
        );

    if (!cp.process(argc, argv))
        return -1;

    if (allocstr.size())
    {
        if (allocstr == "RC")
            return benchmark_disks_alloc<stxxl::RC>(length, batch_size, optrw);
        if (allocstr == "SR")
            return benchmark_disks_alloc<stxxl::SR>(length, batch_size, optrw);
        if (allocstr == "FR")
            return benchmark_disks_alloc<stxxl::FR>(length, batch_size, optrw);
        if (allocstr == "striping")
            return benchmark_disks_alloc<stxxl::striping>(length, batch_size, optrw);

        std::cout << "Unknown allocation strategy '" << allocstr << "'" << std::endl;
        cp.print_usage();
        return -1;
    }

    return benchmark_disks_alloc<STXXL_DEFAULT_ALLOC_STRATEGY>(length, batch_size, optrw);
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include <cling/Interpreter/Interpreter.h>
#include <cling/Interpreter/Value.h>
#include <iostream>
#include <string>
#include <sstream>

///\brief Pass a value from the compiled program into cling, let cling modify it
///  and return the modified value into the compiled program.
int setAndUpdate(int arg, cling::Interpreter& interp) {
   int ret = arg; // The value that will be modified
                  // Update the value of ret by passing it to the interpreter.
   std::ostringstream sstr;
   sstr << "int& ref = *(int*)" << &ret << ';';
   sstr << "ref = ref * ref;";
   interp.process(sstr.str());
   return ret;
}

///\brief A ridiculously complicated way of converting an int to a string.
std::unique_ptr<std::string> stringify(int value, cling::Interpreter& interp) {

   // Declare the function to cling:
   static const std::string codeFunc = R"CODE(
#include <string>
std::string* createAString(const char* str) {
   return new std::string(str);
})CODE";
   interp.declare(codeFunc);

   // Call the function with "runtime" values:
   std::ostringstream sstr;
   sstr << "createAString(\"" << value << "\");";
   cling::Value res; // Will hold the result of the expression evaluation.
   interp.process(sstr.str(), &res);

   // Grab the return value of `createAString()`:
   std::string* resStr = static_cast<std::string*>(res.getPtr());
   return std::unique_ptr<std::string>(resStr);
}

int main(int argc, const char* const* argv) {
    // Create the Interpreter. LLVMDIR is provided as -D during compilation.
    cling::Interpreter interp(argc, argv, LLVMDIR);

    std::cout << "The square of 17 is " << setAndUpdate(17, interp) << '\n';
    std::cout << "Printing a string of 42: " << *stringify(42, interp) << '\n';

    return 0;
}
<commit_msg>More relevant / less obscure examples. Indent.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include <cling/Interpreter/Interpreter.h>
#include <cling/Interpreter/Value.h>
#include <cling/Utils/Casting.h>
#include <iostream>
#include <string>
#include <sstream>

/// Definitions of declarations injected also into cling.
/// NOTE: this could also stay in a header #included here and into cling, but
/// for the sake of simplicity we just redeclare them here.
int aGlobal = 42;
static float anotherGlobal = 3.141;
float getAnotherGlobal() { return anotherGlobal; };
void setAnotherGlobal(float val) { anotherGlobal = val; }

///\brief Call compiled functions from the interpreter.
void useHeader(cling::Interpreter& interp) {
  // We could use a header, too...
  interp.declare("int aGlobal;\n"
                 "float getAnotherGlobal();\n"
                 "void setAnotherGlobal(float val);\n");

  cling::Value res; // Will hold the result of the expression evaluation.
  interp.process("aGlobal;", &res);
  std::cout << "aGlobal is " << res.getAs<long long>() << '\n';
  interp.process("getAnotherGlobal();", &res);
  std::cout << "getAnotherGlobal() returned " << res.getAs<float>() << '\n';

  setAnotherGlobal(1.); // We modify the compiled value,
  interp.process("getAnotherGlobal();", &res); // does the interpreter see it?
  std::cout << "getAnotherGlobal() returned " << res.getAs<float>() << '\n';

  // We modify using the interpreter, now the binary sees the new value.
  interp.process("setAnotherGlobal(7.777); getAnotherGlobal();");
  std::cout << "getAnotherGlobal() returned " << getAnotherGlobal() << '\n';
}

///\brief Call an interpreted function using its symbol address.
void useSymbolAddress(cling::Interpreter& interp) {
  // Declare a function to the interpreter. Make it extern "C" to remove
  // mangling from the game.
  interp.declare("extern \"C\" int plutification(int siss, int sat) "
                 "{ return siss * sat; }");
  void* addr = interp.getAddressOfGlobal("plutification");
  using func_t = int(int, int);
  func_t* pFunc = cling::utils::VoidToFunctionPtr<func_t*>(addr);
  std::cout << "7 * 8 = " << pFunc(7, 8) << '\n';
}

///\brief Pass a pointer into cling as a string.
void usePointerLiteral(cling::Interpreter& interp) {
  int res = 17; // The value that will be modified

  // Update the value of res by passing it to the interpreter.
  std::ostringstream sstr;
  sstr << "int& ref = *(int*)" << &res << ';';
  sstr << "ref = ref * ref;";
  interp.process(sstr.str());
  std::cout << "The square of 17 is " << res << '\n';
}

int main(int argc, const char* const* argv) {
  // Create the Interpreter. LLVMDIR is provided as -D during compilation.
  cling::Interpreter interp(argc, argv, LLVMDIR);

  useHeader(interp);
  useSymbolAddress(interp);
  usePointerLiteral(interp);

  return 0;
}
<|endoftext|>


<commit_before>/*
 Copyright (c) 2019, Ford Motor Company, Livio
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.

 Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following
 disclaimer in the documentation and/or other materials provided with the
 distribution.

 Neither the name of the the copyright holders nor the names of their
 contributors may be used to endorse or promote products derived from this
 software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#include "app_service_rpc_plugin/commands/mobile/publish_app_service_request.h"
#include "application_manager/application_impl.h"
#include "application_manager/message_helper.h"
#include "application_manager/rpc_service.h"
#include "interfaces/MOBILE_API.h"

namespace app_service_rpc_plugin {
using namespace application_manager;
namespace commands {

PublishAppServiceRequest::PublishAppServiceRequest(
    const application_manager::commands::MessageSharedPtr& message,
    ApplicationManager& application_manager,
    app_mngr::rpc_service::RPCService& rpc_service,
    app_mngr::HMICapabilities& hmi_capabilities,
    policy::PolicyHandlerInterface& policy_handler)
    : CommandRequestImpl(message,
                         application_manager,
                         rpc_service,
                         hmi_capabilities,
                         policy_handler)
    , plugin_(NULL) {
  auto plugin = application_manager.GetPluginManager().FindPluginToProcess(
      mobile_apis::FunctionID::PublishAppServiceID,
      app_mngr::commands::Command::CommandSource::SOURCE_MOBILE);
  if (plugin) {
    plugin_ = dynamic_cast<AppServiceRpcPlugin*>(&(*plugin));
  }
}

PublishAppServiceRequest::~PublishAppServiceRequest() {}

bool PublishAppServiceRequest::ValidateManifest(
    smart_objects::SmartObject& manifest) {
  if (manifest.keyExists(strings::uri_scheme)) {
    Json::Value value;
    Json::Reader reader;
    if (!reader.parse(manifest[strings::uri_scheme].asString(), value)) {
      SendResponse(false,
                   mobile_apis::Result::INVALID_DATA,
                   "Provided uriScheme was not valid JSON");
      return false;
    }
  }
  return true;
}

void PublishAppServiceRequest::Run() {
  LOG4CXX_AUTO_TRACE(logger_);
  LOG4CXX_DEBUG(logger_, "Received a PublishAppService");
  MessageHelper::PrintSmartObject(*message_);

  smart_objects::SmartObject response_params =
      smart_objects::SmartObject(smart_objects::SmartType_Map);
  smart_objects::SmartObject manifest =
      (*message_)[strings::msg_params][strings::app_service_manifest];
  if (!ValidateManifest(manifest)) {
    return;
  }
  smart_objects::SmartObject service_record =
      application_manager_.GetAppServiceManager().PublishAppService(
          manifest, true, connection_key());

  std::string requested_service_name = "";

  if ((*message_)[strings::msg_params][strings::app_service_manifest].keyExists(
          strings::service_name)) {
    requested_service_name =
        (*message_)[strings::msg_params][strings::app_service_manifest]
                   [strings::service_name].asString();
  }

  std::string requested_service_type =
      (*message_)[strings::msg_params][strings::app_service_manifest]
                 [strings::service_type].asString();

  smart_objects::SmartArray* requested_handled_rpcs;
  if ((*message_)[strings::msg_params][strings::app_service_manifest].keyExists(
          strings::handled_rpcs)) {
    requested_handled_rpcs =
        (*message_)[strings::msg_params][strings::app_service_manifest]
                   [strings::handled_rpcs].asArray();
  }

  ApplicationSharedPtr app = application_manager_.application(connection_key());

  bool result =
      policy_handler_.CheckAppServiceParameters(app->policy_app_id(),
                                                requested_service_name,
                                                requested_service_type,
                                                requested_handled_rpcs);

  if (!result) {
    SendResponse(false, mobile_apis::Result::DISALLOWED, NULL, NULL);
  }

  response_params[strings::app_service_record] = service_record;

  SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params);
}

}  // namespace commands
}  // namespace app_service_rpc_plugin
<commit_msg>Update src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/commands/mobile/publish_app_service_request.cc<commit_after>/*
 Copyright (c) 2019, Ford Motor Company, Livio
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.

 Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following
 disclaimer in the documentation and/or other materials provided with the
 distribution.

 Neither the name of the the copyright holders nor the names of their
 contributors may be used to endorse or promote products derived from this
 software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#include "app_service_rpc_plugin/commands/mobile/publish_app_service_request.h"
#include "application_manager/application_impl.h"
#include "application_manager/message_helper.h"
#include "application_manager/rpc_service.h"
#include "interfaces/MOBILE_API.h"

namespace app_service_rpc_plugin {
using namespace application_manager;
namespace commands {

PublishAppServiceRequest::PublishAppServiceRequest(
    const application_manager::commands::MessageSharedPtr& message,
    ApplicationManager& application_manager,
    app_mngr::rpc_service::RPCService& rpc_service,
    app_mngr::HMICapabilities& hmi_capabilities,
    policy::PolicyHandlerInterface& policy_handler)
    : CommandRequestImpl(message,
                         application_manager,
                         rpc_service,
                         hmi_capabilities,
                         policy_handler)
    , plugin_(NULL) {
  auto plugin = application_manager.GetPluginManager().FindPluginToProcess(
      mobile_apis::FunctionID::PublishAppServiceID,
      app_mngr::commands::Command::CommandSource::SOURCE_MOBILE);
  if (plugin) {
    plugin_ = dynamic_cast<AppServiceRpcPlugin*>(&(*plugin));
  }
}

PublishAppServiceRequest::~PublishAppServiceRequest() {}

bool PublishAppServiceRequest::ValidateManifest(
    smart_objects::SmartObject& manifest) {
  if (manifest.keyExists(strings::uri_scheme)) {
    Json::Value value;
    Json::Reader reader;
    if (!reader.parse(manifest[strings::uri_scheme].asString(), value)) {
      SendResponse(false,
                   mobile_apis::Result::INVALID_DATA,
                   "Provided uriScheme was not valid JSON");
      return false;
    }
  }
  return true;
}

void PublishAppServiceRequest::Run() {
  LOG4CXX_AUTO_TRACE(logger_);
  LOG4CXX_DEBUG(logger_, "Received a PublishAppService");
  MessageHelper::PrintSmartObject(*message_);

  smart_objects::SmartObject response_params =
      smart_objects::SmartObject(smart_objects::SmartType_Map);
  smart_objects::SmartObject manifest =
      (*message_)[strings::msg_params][strings::app_service_manifest];
  if (!ValidateManifest(manifest)) {
    return;
  }
  smart_objects::SmartObject service_record =
      application_manager_.GetAppServiceManager().PublishAppService(
          manifest, true, connection_key());

  std::string requested_service_name = "";

  if ((*message_)[strings::msg_params][strings::app_service_manifest].keyExists(
          strings::service_name)) {
    requested_service_name =
        (*message_)[strings::msg_params][strings::app_service_manifest]
                   [strings::service_name].asString();
  }

  std::string requested_service_type =
      (*message_)[strings::msg_params][strings::app_service_manifest]
                 [strings::service_type].asString();

  smart_objects::SmartArray* requested_handled_rpcs;
  if ((*message_)[strings::msg_params][strings::app_service_manifest].keyExists(
          strings::handled_rpcs)) {
    requested_handled_rpcs =
        (*message_)[strings::msg_params][strings::app_service_manifest]
                   [strings::handled_rpcs].asArray();
  }

  ApplicationSharedPtr app = application_manager_.application(connection_key());

  bool result =
      policy_handler_.CheckAppServiceParameters(app->policy_app_id(),
                                                requested_service_name,
                                                requested_service_type,
                                                requested_handled_rpcs);

  if (!result) {
    SendResponse(false, mobile_apis::Result::DISALLOWED, "Service disallowed by policies", NULL);
  }

  response_params[strings::app_service_record] = service_record;

  SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params);
}

}  // namespace commands
}  // namespace app_service_rpc_plugin
<|endoftext|>


<commit_before>
#include "FemusInit.hpp"
#include "MultiLevelProblem.hpp"
#include "VTKWriter.hpp"
#include "TransientSystem.hpp"
#include "NonLinearImplicitSystem.hpp"
#include "Marker.hpp"
#include "Line.hpp"

#include "Fluid.hpp"
#include "Solid.hpp"
#include "Parameter.hpp"

#include "NumericVector.hpp"
#include "adept.h"

#include "../include/mpmFem.hpp"

double yMin;

using namespace femus;

double SetVariableTimeStep(const double time)
{
  double dt = 0.01;
//   if(time >= 0.5311 - 0.012 && time <= 0.5311 + 0.012) {
//     dt =  0.0001;
//   }
//   else if(time >= 3 * 0.5311 - 0.012 && time <= 3 * 0.5311 + 0.012) {
//     dt =  0.0001;
//   }
//   else if(time >= 5 * 0.5311 - 0.012 && time <= 5 * 0.5311 + 0.012) {
//     dt =  0.0001;
//   }
//
  if( yMin <= -1.42533) {
       dt =  0.0001;
  }

  return dt;
}

bool SetBoundaryCondition(const std::vector < double >& x, const char name[], double& value, const int facename, const double time)
{
  bool test = 1; //dirichlet
  value = 0.;

  if(1 == facename) test = 0;

  return test;

}

int main(int argc, char** args)
{

  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);

  MultiLevelMesh mlMsh;
  double scalingFactor = 1.;
  unsigned numberOfUniformLevels = 2; //for refinement in 3D
  //unsigned numberOfUniformLevels = 1;
  unsigned numberOfSelectiveLevels = 0;

  double Lref = 1.;
  double Uref = 1.;

  //initialize parameters for rolling ball (MPM)
  double rho_MPM = 1000.;
  double nu_MPM = 0.4;
  double E_MPM = 5.91 * 1.e6;

  //initialize parameters for plate (FEM)
  double rho_FEM = 10000.;
  double nu_FEM = 0.4;
  double E_FEM = 4.2 * 1.e8;

  beta = 0.3; //was 0.25
  Gamma = 0.5;

  Parameter par(Lref, Uref);

  // Generate Solid Object
  Solid solidMPM;
  Solid solidFEM;

  solidMPM = Solid(par, E_MPM, nu_MPM, rho_MPM, "Neo-Hookean");
  solidFEM = Solid(par, E_FEM, nu_FEM, rho_FEM, "Neo-Hookean");

  mlMsh.ReadCoarseMesh("../input/basket.Scaled.neu", "fifth", scalingFactor);
  mlMsh.RefineMesh(numberOfUniformLevels + numberOfSelectiveLevels, numberOfUniformLevels , NULL);

  mlMsh.EraseCoarseLevels(numberOfUniformLevels - 1);
  numberOfUniformLevels = 1;

  unsigned dim = mlMsh.GetDimension();

  MultiLevelSolution mlSol(&mlMsh);
  // add variables to mlSol
  mlSol.AddSolution("DX", LAGRANGE, SECOND, 2);
  if(dim > 1) mlSol.AddSolution("DY", LAGRANGE, SECOND, 2);
  if(dim > 2) mlSol.AddSolution("DZ", LAGRANGE, SECOND, 2);

  mlSol.AddSolution("VX", LAGRANGE, SECOND, 2);
  if(dim > 1) mlSol.AddSolution("VY", LAGRANGE, SECOND, 2);
  if(dim > 2) mlSol.AddSolution("VZ", LAGRANGE, SECOND, 2);

  mlSol.AddSolution("AX", LAGRANGE, SECOND, 2);
  if(dim > 1) mlSol.AddSolution("AY", LAGRANGE, SECOND, 2);
  if(dim > 2) mlSol.AddSolution("AZ", LAGRANGE, SECOND, 2);

  mlSol.AddSolution("M", LAGRANGE, SECOND, 2);
  mlSol.AddSolution("Mat", DISCONTINOUS_POLYNOMIAL, ZERO, 0, false);

  mlSol.Initialize("All");

  mlSol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);

  mlSol.SetIfFSI(true);

  // ******* Set boundary conditions *******
  mlSol.GenerateBdc("DX", "Steady");
  if(dim > 1) mlSol.GenerateBdc("DY", "Steady");
  if(dim > 2) mlSol.GenerateBdc("DZ", "Steady");
  mlSol.GenerateBdc("M", "Steady");

  MultiLevelProblem ml_prob(&mlSol);

  ml_prob.parameters.set<Solid> ("SolidMPM") = solidMPM;
  ml_prob.parameters.set<Solid> ("SolidFEM") = solidFEM;

  // ******* Add MPM system to the MultiLevel problem *******
  TransientNonlinearImplicitSystem& system = ml_prob.add_system < TransientNonlinearImplicitSystem > ("MPM_FEM");
  system.AddSolutionToSystemPDE("DX");
  if(dim > 1)system.AddSolutionToSystemPDE("DY");
  if(dim > 2) system.AddSolutionToSystemPDE("DZ");

  // ******* System MPM Assembly *******
  system.SetAssembleFunction(AssembleMPMSys);
  //system.SetAssembleFunction(AssembleFEM);
  // ******* set MG-Solver *******
  system.SetMgType(V_CYCLE);

  system.SetAbsoluteLinearConvergenceTolerance(1.0e-10);
  system.SetMaxNumberOfLinearIterations(1);
  system.SetNonLinearConvergenceTolerance(1.e-9);
  system.SetMaxNumberOfNonLinearIterations(20);

  system.SetNumberPreSmoothingStep(1);
  system.SetNumberPostSmoothingStep(1);

  // ******* Set Preconditioner *******
  system.SetMgSmoother(GMRES_SMOOTHER);

  system.init();

  // ******* Set Smoother *******
  system.SetSolverFineGrids(GMRES);

  system.SetPreconditionerFineGrids(ILU_PRECOND);

  system.SetTolerances(1.e-10, 1.e-15, 1.e+50, 40, 40);

  //BEGIN init particles
  unsigned size = 1;
  std::vector < std::vector < double > > x; // marker
  double yc = 0.;  // FOR E = 4.2 * 1.e8 --> 0.115 (for 3 refinements) 0.09 (for 4) and 0.05  (for 5, this one maybe to be changed)
  // FOR E = 4.2 * 1.e6 --> 0.1. (for 3 refinements) 0.075 (for 4) and 0.05  (for 5)

  x.resize(size);
  x[0].resize(dim, 0.);
  x[0][1] = yc;

  double R = 0.16;
  double R0 = 0.14;

  double PI = acos(-1.);
  unsigned NR = 300;
  unsigned NL = NR / (2 * PI);
  double DL = R0 / NL;

  for(unsigned i = 0; i < NL; i++) {
    double  r = R0 - i * DL;
    unsigned Nr = static_cast <unsigned>(ceil(NR * r / R0));
    double dtheta = 2 * PI / Nr;
    unsigned sizeOld = x.size();
    x.resize(sizeOld + Nr);
    for(unsigned s = sizeOld; s < x.size(); s++) {
      x[s].resize(dim);
    }
    for(unsigned j = 0; j < Nr; j++) {
      x[sizeOld + j][0] = r * cos(j * dtheta);
      x[sizeOld + j][1] = yc + r * sin(j * dtheta);
    }
  }
  double MASS = PI * R0 * R0 * rho_MPM;
  size = x.size();
  std::vector < double > mass(x.size(), MASS / x.size()); // uniform marker volume

  if( fabs(R - R0) > 1.0e-10 ) {

    double factor = 1.14;
    unsigned NL = getNumberOfLayers((R - R0) / DL, factor);
    std::cout << NL << std::endl;

    double  r = R0;
    for(unsigned i = 1; i <= NL; i++) {
      DL = DL / factor;
      r += DL;
      NR = static_cast <unsigned>(ceil (NR * factor) );
      double dtheta = 2 * PI / NR;
      unsigned sizeOld = x.size();
      x.resize(sizeOld + NR);
      for(unsigned s = sizeOld; s < x.size(); s++) {
        x[s].resize(dim);
      }
      for(unsigned j = 0; j < NR; j++) {
        x[sizeOld + j][0] = r * cos(j * dtheta);
        x[sizeOld + j][1] = yc + r * sin(j * dtheta);
      }
      mass.resize(x.size(), rho_MPM * r * dtheta * DL);
    }
    size = x.size();
  }

  double totalMass = 0;
  for(unsigned i = 0; i < mass.size(); i++) {
    totalMass += mass[i];
  }

  std::cout << totalMass << " " << rho_MPM * PI * R * R << std::endl;

  //return 1;

  std::vector < MarkerType > markerType;
  markerType.resize(size);

  for(unsigned j = 0; j < size; j++) {
    markerType[j] = VOLUME;
  }
  std::vector < std::vector < std::vector < double > > > line(1);
  std::vector < std::vector < std::vector < double > > > line0(1);

  unsigned solType = 2;
  linea = new Line(x, mass, markerType, mlSol.GetLevel(numberOfUniformLevels - 1), solType);

  //linea->SetParticlesMass(MASS/rhos, rhos);
  //linea->ScaleParticleMass(scale);

  linea->GetLine(line0[0]);
  PrintLine(DEFAULT_OUTPUTDIR, line0, false, 0);
  linea->GetParticlesToGridMaterial();

  //END init particles

  // ******* Print solution *******
  mlSol.SetWriter(VTK);

  std::vector<std::string> mov_vars;
  mov_vars.push_back("DX");
  mov_vars.push_back("DY");
  mov_vars.push_back("DZ");
  mlSol.GetWriter()->SetMovingMesh(mov_vars);

  std::vector<std::string> print_vars;
  print_vars.push_back("All");

  mlSol.GetWriter()->SetDebugOutput(true);
  mlSol.GetWriter()->Write(DEFAULT_OUTPUTDIR, "biquadratic", print_vars, 0);

  double theta = 0;
  gravity[0] = 9.81 * sin(theta);
  gravity[1] = -9.81 * cos(theta);

  system.AttachGetTimeIntervalFunction(SetVariableTimeStep);
  unsigned n_timesteps = 3500;
  for(unsigned time_step = 1; time_step <= n_timesteps; time_step++) {

    std::vector< double > xMin(3);
    std::vector< double > xMax(3);

    linea->GetExtrema(xMin, xMax);

    yMin = xMin[1];

    system.CopySolutionToOldSolution();

    system.MGsolve();

    // ******* Print solution *******
    mlSol.GetWriter()->Write(DEFAULT_OUTPUTDIR, "biquadratic", print_vars, time_step);

    GridToParticlesProjection(ml_prob, *linea);

    linea->GetLine(line[0]);
    PrintLine(DEFAULT_OUTPUTDIR, line, false, time_step);

  }

  delete linea;
  return 0;

} //end main

<commit_msg>testing the bouncing ball<commit_after>
#include "FemusInit.hpp"
#include "MultiLevelProblem.hpp"
#include "VTKWriter.hpp"
#include "TransientSystem.hpp"
#include "NonLinearImplicitSystem.hpp"
#include "Marker.hpp"
#include "Line.hpp"

#include "Fluid.hpp"
#include "Solid.hpp"
#include "Parameter.hpp"

#include "NumericVector.hpp"
#include "adept.h"

#include "../include/mpmFem.hpp"

double yMin;

using namespace femus;

double SetVariableTimeStep(const double time)
{
  double dt = 0.01;
//   if(time >= 0.5311 - 0.012 && time <= 0.5311 + 0.012) {
//     dt =  0.0001;
//   }
//   else if(time >= 3 * 0.5311 - 0.012 && time <= 3 * 0.5311 + 0.012) {
//     dt =  0.0001;
//   }
//   else if(time >= 5 * 0.5311 - 0.012 && time <= 5 * 0.5311 + 0.012) {
//     dt =  0.0001;
//   }
//
  if( yMin <= -1.42533) {
       dt =  0.0001;
  }

  return dt;
}

bool SetBoundaryCondition(const std::vector < double >& x, const char name[], double& value, const int facename, const double time)
{
  bool test = 1; //dirichlet
  value = 0.;

  if(1 == facename) test = 0;

  return test;

}

int main(int argc, char** args)
{

  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);

  MultiLevelMesh mlMsh;
  double scalingFactor = 1.;
  unsigned numberOfUniformLevels = 2; //for refinement in 3D
  //unsigned numberOfUniformLevels = 1;
  unsigned numberOfSelectiveLevels = 0;

  double Lref = 1.;
  double Uref = 1.;

  //initialize parameters for rolling ball (MPM)
  double rho_MPM = 1000.;
  double nu_MPM = 0.4;
  double E_MPM = 5.91 * 1.e6;

  //initialize parameters for plate (FEM)
  double rho_FEM = 10000.;
  double nu_FEM = 0.4;
  double E_FEM = 4.2 * 1.e7;

  beta = 0.3; //was 0.25
  Gamma = 0.5;

  Parameter par(Lref, Uref);

  // Generate Solid Object
  Solid solidMPM;
  Solid solidFEM;

  solidMPM = Solid(par, E_MPM, nu_MPM, rho_MPM, "Neo-Hookean");
  solidFEM = Solid(par, E_FEM, nu_FEM, rho_FEM, "Neo-Hookean");

  mlMsh.ReadCoarseMesh("../input/basket.Scaled.neu", "fifth", scalingFactor);
  mlMsh.RefineMesh(numberOfUniformLevels + numberOfSelectiveLevels, numberOfUniformLevels , NULL);

  mlMsh.EraseCoarseLevels(numberOfUniformLevels - 1);
  numberOfUniformLevels = 1;

  unsigned dim = mlMsh.GetDimension();

  MultiLevelSolution mlSol(&mlMsh);
  // add variables to mlSol
  mlSol.AddSolution("DX", LAGRANGE, SECOND, 2);
  if(dim > 1) mlSol.AddSolution("DY", LAGRANGE, SECOND, 2);
  if(dim > 2) mlSol.AddSolution("DZ", LAGRANGE, SECOND, 2);

  mlSol.AddSolution("VX", LAGRANGE, SECOND, 2);
  if(dim > 1) mlSol.AddSolution("VY", LAGRANGE, SECOND, 2);
  if(dim > 2) mlSol.AddSolution("VZ", LAGRANGE, SECOND, 2);

  mlSol.AddSolution("AX", LAGRANGE, SECOND, 2);
  if(dim > 1) mlSol.AddSolution("AY", LAGRANGE, SECOND, 2);
  if(dim > 2) mlSol.AddSolution("AZ", LAGRANGE, SECOND, 2);

  mlSol.AddSolution("M", LAGRANGE, SECOND, 2);
  mlSol.AddSolution("Mat", DISCONTINOUS_POLYNOMIAL, ZERO, 0, false);

  mlSol.Initialize("All");

  mlSol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);

  mlSol.SetIfFSI(true);

  // ******* Set boundary conditions *******
  mlSol.GenerateBdc("DX", "Steady");
  if(dim > 1) mlSol.GenerateBdc("DY", "Steady");
  if(dim > 2) mlSol.GenerateBdc("DZ", "Steady");
  mlSol.GenerateBdc("M", "Steady");

  MultiLevelProblem ml_prob(&mlSol);

  ml_prob.parameters.set<Solid> ("SolidMPM") = solidMPM;
  ml_prob.parameters.set<Solid> ("SolidFEM") = solidFEM;

  // ******* Add MPM system to the MultiLevel problem *******
  TransientNonlinearImplicitSystem& system = ml_prob.add_system < TransientNonlinearImplicitSystem > ("MPM_FEM");
  system.AddSolutionToSystemPDE("DX");
  if(dim > 1)system.AddSolutionToSystemPDE("DY");
  if(dim > 2) system.AddSolutionToSystemPDE("DZ");

  // ******* System MPM Assembly *******
  system.SetAssembleFunction(AssembleMPMSys);
  //system.SetAssembleFunction(AssembleFEM);
  // ******* set MG-Solver *******
  system.SetMgType(V_CYCLE);

  system.SetAbsoluteLinearConvergenceTolerance(1.0e-10);
  system.SetMaxNumberOfLinearIterations(1);
  system.SetNonLinearConvergenceTolerance(1.e-9);
  system.SetMaxNumberOfNonLinearIterations(20);

  system.SetNumberPreSmoothingStep(1);
  system.SetNumberPostSmoothingStep(1);

  // ******* Set Preconditioner *******
  system.SetMgSmoother(GMRES_SMOOTHER);

  system.init();

  // ******* Set Smoother *******
  system.SetSolverFineGrids(GMRES);

  system.SetPreconditionerFineGrids(ILU_PRECOND);

  system.SetTolerances(1.e-10, 1.e-15, 1.e+50, 40, 40);

  //BEGIN init particles
  unsigned size = 1;
  std::vector < std::vector < double > > x; // marker
  double yc = 0.;  // FOR E = 4.2 * 1.e8 --> 0.115 (for 3 refinements) 0.09 (for 4) and 0.05  (for 5, this one maybe to be changed)
  // FOR E = 4.2 * 1.e6 --> 0.1. (for 3 refinements) 0.075 (for 4) and 0.05  (for 5)

  x.resize(size);
  x[0].resize(dim, 0.);
  x[0][1] = yc;

  double R = 0.16;
  double R0 = 0.14;

  double PI = acos(-1.);
  unsigned NR = 300;
  unsigned NL = NR / (2 * PI);
  double DL = R0 / NL;

  for(unsigned i = 0; i < NL; i++) {
    double  r = R0 - i * DL;
    unsigned Nr = static_cast <unsigned>(ceil(NR * r / R0));
    double dtheta = 2 * PI / Nr;
    unsigned sizeOld = x.size();
    x.resize(sizeOld + Nr);
    for(unsigned s = sizeOld; s < x.size(); s++) {
      x[s].resize(dim);
    }
    for(unsigned j = 0; j < Nr; j++) {
      x[sizeOld + j][0] = r * cos(j * dtheta);
      x[sizeOld + j][1] = yc + r * sin(j * dtheta);
    }
  }
  double MASS = PI * R0 * R0 * rho_MPM;
  size = x.size();
  std::vector < double > mass(x.size(), MASS / x.size()); // uniform marker volume

  if( fabs(R - R0) > 1.0e-10 ) {

    double factor = 1.14;
    unsigned NL = getNumberOfLayers((R - R0) / DL, factor);
    std::cout << NL << std::endl;

    double  r = R0;
    for(unsigned i = 1; i <= NL; i++) {
      DL = DL / factor;
      r += DL;
      NR = static_cast <unsigned>(ceil (NR * factor) );
      double dtheta = 2 * PI / NR;
      unsigned sizeOld = x.size();
      x.resize(sizeOld + NR);
      for(unsigned s = sizeOld; s < x.size(); s++) {
        x[s].resize(dim);
      }
      for(unsigned j = 0; j < NR; j++) {
        x[sizeOld + j][0] = r * cos(j * dtheta);
        x[sizeOld + j][1] = yc + r * sin(j * dtheta);
      }
      mass.resize(x.size(), rho_MPM * r * dtheta * DL);
    }
    size = x.size();
  }

  double totalMass = 0;
  for(unsigned i = 0; i < mass.size(); i++) {
    totalMass += mass[i];
  }

  std::cout << totalMass << " " << rho_MPM * PI * R * R << std::endl;

  //return 1;

  std::vector < MarkerType > markerType;
  markerType.resize(size);

  for(unsigned j = 0; j < size; j++) {
    markerType[j] = VOLUME;
  }
  std::vector < std::vector < std::vector < double > > > line(1);
  std::vector < std::vector < std::vector < double > > > line0(1);

  unsigned solType = 2;
  linea = new Line(x, mass, markerType, mlSol.GetLevel(numberOfUniformLevels - 1), solType);

  //linea->SetParticlesMass(MASS/rhos, rhos);
  //linea->ScaleParticleMass(scale);

  linea->GetLine(line0[0]);
  PrintLine(DEFAULT_OUTPUTDIR, line0, false, 0);
  linea->GetParticlesToGridMaterial();

  //END init particles

  // ******* Print solution *******
  mlSol.SetWriter(VTK);

  std::vector<std::string> mov_vars;
  mov_vars.push_back("DX");
  mov_vars.push_back("DY");
  mov_vars.push_back("DZ");
  mlSol.GetWriter()->SetMovingMesh(mov_vars);

  std::vector<std::string> print_vars;
  print_vars.push_back("All");

  mlSol.GetWriter()->SetDebugOutput(true);
  mlSol.GetWriter()->Write(DEFAULT_OUTPUTDIR, "biquadratic", print_vars, 0);

  double theta = 0;
  gravity[0] = 9.81 * sin(theta);
  gravity[1] = -9.81 * cos(theta);

  system.AttachGetTimeIntervalFunction(SetVariableTimeStep);
  unsigned n_timesteps = 3500;
  for(unsigned time_step = 1; time_step <= n_timesteps; time_step++) {

    std::vector< double > xMin(3);
    std::vector< double > xMax(3);

    linea->GetExtrema(xMin, xMax);

    yMin = xMin[1];

    system.CopySolutionToOldSolution();

    system.MGsolve();

    // ******* Print solution *******
    mlSol.GetWriter()->Write(DEFAULT_OUTPUTDIR, "biquadratic", print_vars, time_step);

    GridToParticlesProjection(ml_prob, *linea);

    linea->GetLine(line[0]);
    PrintLine(DEFAULT_OUTPUTDIR, line, false, time_step);

  }

  delete linea;
  return 0;

} //end main

<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* 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 program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
* H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
* M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/gui/PickHandler.h>

#include <sofa/component/collision/ComponentMouseInteraction.h>
#include <sofa/component/collision/RayContact.h>

#include <sofa/simulation/common/InitVisitor.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/helper/system/gl.h>
#include <sofa/helper/gl/DrawManager.h>
#include <sofa/simulation/common/Simulation.h>

#include <iostream>

namespace sofa
{
using namespace component::collision;

namespace gui
{

PickHandler::PickHandler():interactorInUse(false), mouseStatus(DEACTIVATED),mouseButton(NONE),renderCallback(NULL)
{
    operations[LEFT] = operations[MIDDLE] = operations[RIGHT] = NULL;

    mouseNode = simulation::getSimulation()->newNode("Mouse");

    mouseContainer = new MouseContainer; mouseContainer->resize(1);
    mouseContainer->setName("MousePosition");
    mouseNode->addObject(mouseContainer);

    mouseCollision = new MouseCollisionModel;
    mouseCollision->setNbRay(1);
    mouseCollision->getRay(0).l() = 1000000;
    mouseCollision->setName("MouseCollisionModel");
    mouseNode->addObject(mouseCollision);

    mouseNode->init();
    mouseContainer->init();
    mouseCollision->init();

    typedef component::collision::ComponentMouseInteraction::ComponentMouseInteractionFactory MouseFactory;
    const MouseFactory *factory = MouseFactory::getInstance();
    for (MouseFactory::const_iterator it = factory->begin(); it != factory->end(); ++it)
    {
        instanceComponents.push_back(it->second->createInstance(NULL));
        instanceComponents.back()->init(mouseNode);
    }
    interaction = instanceComponents.back();
}

PickHandler::~PickHandler()
{
    for (unsigned int i=0; i<operations.size(); ++i)
    {
        delete operations[i];
    }

    if( renderCallback ) delete renderCallback;
//       for (unsigned int i=0;i<instanceComponents.size();++i) delete instanceComponents[i];
}

void PickHandler::init()
{
    core::collision::Pipeline *pipeline;
    simulation::getSimulation()->getContext()->get(pipeline, core::objectmodel::BaseContext::SearchRoot);

    useCollisions = (pipeline != NULL);

#ifdef SOFA_GUI_QTOGREVIEWER
    if (simulation::getSimulation()->DrawUtility.getSystemDraw() != sofa::helper::gl::DrawManager::OGRE)
#endif
    {
        _fboParams.depthInternalformat = GL_DEPTH_COMPONENT24;
#ifdef GL_VERSION_3_0
        if (GLEW_VERSION_3_0)
        {
            _fboParams.colorInternalformat = GL_RGBA32F;
        }
        else
#endif
        {
            _fboParams.colorInternalformat = GL_RGBA16;
        }
        _fboParams.colorFormat         = GL_RGBA;
        _fboParams.colorType           = GL_FLOAT;

        _fbo.setFormat(_fboParams);
        _fbo.init(GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_SIZE);
    }
}

void PickHandler::reset()
{
    activateRay(false);
    mouseButton = NONE;
    for (unsigned int i=0; i<instanceComponents.size(); ++i) instanceComponents[i]->reset();
}

Operation *PickHandler::changeOperation(sofa::component::configurationsetting::MouseButtonSetting* setting)
{
    if (operations[setting->getButton()]) delete operations[setting->getButton()];
    Operation *mouseOp=OperationFactory::Instanciate(setting->getOperationType());
    mouseOp->configure(this,setting);
    operations[setting->getButton()]=mouseOp;
    return mouseOp;
}

Operation *PickHandler::changeOperation(MOUSE_BUTTON button, const std::string &op)
{
    if (operations[button]) delete operations[button];
    Operation *mouseOp=OperationFactory::Instanciate(op);
    mouseOp->configure(this,button);
    operations[button]=mouseOp;
    return mouseOp;
}

void PickHandler::activateRay(bool act)
{
    if (interactorInUse && !act)
    {
        mouseNode->detachFromGraph();

        operations[LEFT]->endOperation();
        operations[MIDDLE]->endOperation();
        operations[RIGHT]->endOperation();

        interaction->deactivate();

        interactorInUse=false;
    }
    else if (!interactorInUse && act)
    {
        Node *root = static_cast<Node*>(simulation::getSimulation()->getContext());
        root->addChild(mouseNode);
        interaction->activate();
        interactorInUse=true;
    }
}

bool PickHandler::needToCastRay()
{
    return !getInteraction()->mouseInteractor->isMouseAttached();
}

void PickHandler::setCompatibleInteractor()
{
    if (!lastPicked.body && !lastPicked.mstate) return;

    if (lastPicked.body)
    {
        if (interaction->isCompatible(lastPicked.body->getContext())) return;
        for (unsigned int i=0; i<instanceComponents.size(); ++i)
        {
            if (instanceComponents[i] != interaction &&
                instanceComponents[i]->isCompatible(lastPicked.body->getContext()))
            {
                interaction->deactivate();
                interaction = instanceComponents[i];
                interaction->activate();
            }
        }
    }
    else
    {
        if (interaction->isCompatible(lastPicked.mstate->getContext())) return;
        for (unsigned int i=0; i<instanceComponents.size(); ++i)
        {
            if (instanceComponents[i] != interaction &&
                instanceComponents[i]->isCompatible(lastPicked.mstate->getContext()))
            {
                interaction->deactivate();
                interaction = instanceComponents[i];
                interaction->activate();
            }
        }
    }

}

void PickHandler::updateRay(const sofa::defaulttype::Vector3 &position,const sofa::defaulttype::Vector3 &orientation)
{
    if (!interactorInUse) return;

    mouseCollision->getRay(0).origin() = position+orientation*interaction->mouseInteractor->getDistanceFromMouse();
    mouseCollision->getRay(0).direction() = orientation;
    simulation::MechanicalPropagatePositionVisitor().execute(mouseCollision->getContext());

    if (needToCastRay())
    {
        lastPicked=findCollision();
        setCompatibleInteractor();
        interaction->mouseInteractor->setMouseRayModel(mouseCollision);
        interaction->mouseInteractor->setBodyPicked(lastPicked);
        for (unsigned int i=0; i<callbacks.size(); ++i)
        {
            callbacks[i]->execute(lastPicked);
        }
    }

    if(mouseButton != NONE)
    {
        switch (mouseStatus)
        {
        case PRESSED:
        {
            operations[mouseButton]->start();
            mouseStatus=ACTIVATED;
            break;
        }
        case RELEASED:
        {
            operations[mouseButton]->end();
            mouseStatus=DEACTIVATED;
            break;
        }
        case ACTIVATED:
        {
            operations[mouseButton]->execution();
        }
        case DEACTIVATED:
        {
        }
        }
    }

    for (unsigned int i=0; i<operations.size(); ++i)
    {
        operations[i]->wait();
    }
}

//Clear the node create, and destroy all its components
void PickHandler::handleMouseEvent(MOUSE_STATUS status, MOUSE_BUTTON button)
{
    if (!interaction) return;

    mouseButton=button;
    mouseStatus=status;

}

ComponentMouseInteraction *PickHandler::getInteraction()
{
    return interaction;
}

component::collision::BodyPicked PickHandler::findCollision()
{
    if (useCollisions)
    {
        component::collision::BodyPicked picked=findCollisionUsingPipeline();
        if (picked.body) return picked;
    }
    return findCollisionUsingBruteForce();
    //return findCollisionUsingColourCoding();
}

component::collision::BodyPicked PickHandler::findCollisionUsingPipeline()
{
    const defaulttype::Vector3& origin          = mouseCollision->getRay(0).origin();
    const defaulttype::Vector3& direction       = mouseCollision->getRay(0).direction();
    const double& maxLength                     = mouseCollision->getRay(0).l();

    BodyPicked result;
    const std::set< sofa::component::collision::BaseRayContact*> &contacts = mouseCollision->getContacts();
    for (std::set< sofa::component::collision::BaseRayContact*>::const_iterator it=contacts.begin(); it != contacts.end(); ++it)
    {

        const sofa::helper::vector<core::collision::DetectionOutput*>& output = (*it)->getDetectionOutputs();
        sofa::core::CollisionModel *modelInCollision;
        for (unsigned int i=0; i<output.size(); ++i)
        {

            if (output[i]->elem.first.getCollisionModel() == mouseCollision)
            {
                modelInCollision = output[i]->elem.second.getCollisionModel();
                if (!modelInCollision->isSimulated()) continue;

                const double d = (output[i]->point[1]-origin)*direction;
                if (d<0.0 || d>maxLength) continue;
                if (result.body == NULL || d < result.rayLength)
                {
                    result.body=modelInCollision;
                    result.indexCollisionElement = output[i]->elem.second.getIndex();
                    result.point = output[i]->point[1];
                    result.dist  = (output[i]->point[1]-output[i]->point[0]).norm();
                    result.rayLength  = d;
                }
            }
            else if (output[i]->elem.second.getCollisionModel() == mouseCollision)
            {
                modelInCollision = output[i]->elem.first.getCollisionModel();
                if (!modelInCollision->isSimulated()) continue;

                const double d = (output[i]->point[0]-origin)*direction;
                if (d<0.0 || d>maxLength) continue;
                if (result.body == NULL || d < result.rayLength)
                {
                    result.body=modelInCollision;
                    result.indexCollisionElement = output[i]->elem.first.getIndex();
                    result.point = output[i]->point[0];
                    result.dist  = (output[i]->point[1]-output[i]->point[0]).norm();
                    result.rayLength  = d;
                }
            }
        }
    }
    return result;
}

component::collision::BodyPicked PickHandler::findCollisionUsingBruteForce()
{
    const defaulttype::Vector3& origin          = mouseCollision->getRay(0).origin();
    const defaulttype::Vector3& direction       = mouseCollision->getRay(0).direction();
    const double& maxLength                     = mouseCollision->getRay(0).l();

    return findCollisionUsingBruteForce(origin, direction, maxLength);
}

component::collision::BodyPicked PickHandler::findCollisionUsingColourCoding()
{
    const defaulttype::Vector3& origin          = mouseCollision->getRay(0).origin();
    const defaulttype::Vector3& direction       = mouseCollision->getRay(0).direction();

    return findCollisionUsingColourCoding(origin, direction);

}

component::collision::BodyPicked PickHandler::findCollisionUsingBruteForce(const defaulttype::Vector3& origin,
        const defaulttype::Vector3& direction,
        double maxLength)
{
    BodyPicked result;
    // Look for particles hit by this ray
    simulation::MechanicalPickParticlesVisitor picker(origin, direction, maxLength, 0);
    core::objectmodel::BaseNode* rootNode = dynamic_cast<core::objectmodel::BaseNode*>(sofa::simulation::getSimulation()->getContext());

    if (rootNode) picker.execute(rootNode->getContext());
    else std::cerr << "ERROR: root node not found." << std::endl;

    if (!picker.particles.empty())
    {
        core::behavior::BaseMechanicalState *mstate = picker.particles.begin()->second.first;
        result.mstate=mstate;
        result.indexCollisionElement = picker.particles.begin()->second.second;
        result.point[0] = mstate->getPX(result.indexCollisionElement);
        result.point[1] = mstate->getPY(result.indexCollisionElement);
        result.point[2] = mstate->getPZ(result.indexCollisionElement);
        result.dist =  0;
        result.rayLength = (result.point-origin)*direction;
    }
    return result;
}

component::collision::BodyPicked PickHandler::findCollisionUsingColourCoding(const defaulttype::Vector3& origin,
        const defaulttype::Vector3& direction)
{
    BodyPicked result;

    sofa::defaulttype::Vec4f color;
    int x = mousePosition.screenWidth -  mousePosition.x;
    int y = mousePosition.screenHeight - mousePosition.y;
    _fbo.start();
    if(renderCallback)
    {
        renderCallback->render();
    }

    glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType,color.elems);

    _fbo.stop();

    result = _decodeColour(color, origin, direction);

    return result;

}

component::collision::BodyPicked PickHandler::_decodeColour(const sofa::defaulttype::Vec4f& colour,
        const defaulttype::Vector3& origin,
        const defaulttype::Vector3& direction)
{
    using namespace core::objectmodel;
    using namespace core::behavior;
    using namespace sofa::defaulttype;
    static const float threshold = 0.00001f;

    component::collision::BodyPicked result;

    result.dist =  0;

    if( colour[0] > threshold || colour[1] > threshold || colour[2] > threshold  )
    {

        helper::vector<core::CollisionModel*> listCollisionModel;
        sofa::simulation::getSimulation()->getContext()->get<core::CollisionModel>(&listCollisionModel,BaseContext::SearchRoot);
        const int totalCollisionModel = listCollisionModel.size();
        const int indexListCollisionModel = (int) ( colour[0] * (float)totalCollisionModel + 0.5) - 1;
        result.body = listCollisionModel[indexListCollisionModel];
        result.indexCollisionElement = (int) ( colour[1] * result.body->getSize() );
        result.point = result.body->getPositionFromWeights(result.indexCollisionElement, colour[2], colour[3]);

        result.rayLength = (result.point-origin)*direction;
    }

    return result;
}

}
}

<commit_msg>r7873/sofa-dev : FIX: crash of all the tutorial examples<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* 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 program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
* H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
* M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/gui/PickHandler.h>

#include <sofa/component/collision/ComponentMouseInteraction.h>
#include <sofa/component/collision/RayContact.h>

#include <sofa/simulation/common/InitVisitor.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/helper/system/gl.h>
#include <sofa/helper/gl/DrawManager.h>
#include <sofa/simulation/common/Simulation.h>

#include <iostream>

namespace sofa
{
using namespace component::collision;

namespace gui
{

PickHandler::PickHandler():interactorInUse(false), mouseStatus(DEACTIVATED),mouseButton(NONE),renderCallback(NULL)
{
    operations[LEFT] = operations[MIDDLE] = operations[RIGHT] = NULL;

    mouseNode = simulation::getSimulation()->newNode("Mouse");

    mouseContainer = new MouseContainer; mouseContainer->resize(1);
    mouseContainer->setName("MousePosition");
    mouseNode->addObject(mouseContainer);

    mouseCollision = new MouseCollisionModel;
    mouseCollision->setNbRay(1);
    mouseCollision->getRay(0).l() = 1000000;
    mouseCollision->setName("MouseCollisionModel");
    mouseNode->addObject(mouseCollision);

    mouseNode->init();
    mouseContainer->init();
    mouseCollision->init();

    typedef component::collision::ComponentMouseInteraction::ComponentMouseInteractionFactory MouseFactory;
    const MouseFactory *factory = MouseFactory::getInstance();
    for (MouseFactory::const_iterator it = factory->begin(); it != factory->end(); ++it)
    {
        instanceComponents.push_back(it->second->createInstance(NULL));
        instanceComponents.back()->init(mouseNode);
    }
    interaction = instanceComponents.back();
}

PickHandler::~PickHandler()
{
    for (unsigned int i=0; i<operations.size(); ++i)
    {
        delete operations[i];
    }

    if( renderCallback ) delete renderCallback;
//       for (unsigned int i=0;i<instanceComponents.size();++i) delete instanceComponents[i];
}

void PickHandler::init()
{
    core::collision::Pipeline *pipeline;
    simulation::getSimulation()->getContext()->get(pipeline, core::objectmodel::BaseContext::SearchRoot);

    useCollisions = (pipeline != NULL);
}

void PickHandler::reset()
{
    activateRay(false);
    mouseButton = NONE;
    for (unsigned int i=0; i<instanceComponents.size(); ++i) instanceComponents[i]->reset();
}

Operation *PickHandler::changeOperation(sofa::component::configurationsetting::MouseButtonSetting* setting)
{
    if (operations[setting->getButton()]) delete operations[setting->getButton()];
    Operation *mouseOp=OperationFactory::Instanciate(setting->getOperationType());
    mouseOp->configure(this,setting);
    operations[setting->getButton()]=mouseOp;
    return mouseOp;
}

Operation *PickHandler::changeOperation(MOUSE_BUTTON button, const std::string &op)
{
    if (operations[button]) delete operations[button];
    Operation *mouseOp=OperationFactory::Instanciate(op);
    mouseOp->configure(this,button);
    operations[button]=mouseOp;
    return mouseOp;
}

void PickHandler::activateRay(bool act)
{
    if (interactorInUse && !act)
    {
        mouseNode->detachFromGraph();

        operations[LEFT]->endOperation();
        operations[MIDDLE]->endOperation();
        operations[RIGHT]->endOperation();

        interaction->deactivate();

        interactorInUse=false;
    }
    else if (!interactorInUse && act)
    {
        Node *root = static_cast<Node*>(simulation::getSimulation()->getContext());
        root->addChild(mouseNode);
        interaction->activate();
        interactorInUse=true;
    }
}

bool PickHandler::needToCastRay()
{
    return !getInteraction()->mouseInteractor->isMouseAttached();
}

void PickHandler::setCompatibleInteractor()
{
    if (!lastPicked.body && !lastPicked.mstate) return;

    if (lastPicked.body)
    {
        if (interaction->isCompatible(lastPicked.body->getContext())) return;
        for (unsigned int i=0; i<instanceComponents.size(); ++i)
        {
            if (instanceComponents[i] != interaction &&
                instanceComponents[i]->isCompatible(lastPicked.body->getContext()))
            {
                interaction->deactivate();
                interaction = instanceComponents[i];
                interaction->activate();
            }
        }
    }
    else
    {
        if (interaction->isCompatible(lastPicked.mstate->getContext())) return;
        for (unsigned int i=0; i<instanceComponents.size(); ++i)
        {
            if (instanceComponents[i] != interaction &&
                instanceComponents[i]->isCompatible(lastPicked.mstate->getContext()))
            {
                interaction->deactivate();
                interaction = instanceComponents[i];
                interaction->activate();
            }
        }
    }

}

void PickHandler::updateRay(const sofa::defaulttype::Vector3 &position,const sofa::defaulttype::Vector3 &orientation)
{
    if (!interactorInUse) return;

    mouseCollision->getRay(0).origin() = position+orientation*interaction->mouseInteractor->getDistanceFromMouse();
    mouseCollision->getRay(0).direction() = orientation;
    simulation::MechanicalPropagatePositionVisitor().execute(mouseCollision->getContext());

    if (needToCastRay())
    {
        lastPicked=findCollision();
        setCompatibleInteractor();
        interaction->mouseInteractor->setMouseRayModel(mouseCollision);
        interaction->mouseInteractor->setBodyPicked(lastPicked);
        for (unsigned int i=0; i<callbacks.size(); ++i)
        {
            callbacks[i]->execute(lastPicked);
        }
    }

    if(mouseButton != NONE)
    {
        switch (mouseStatus)
        {
        case PRESSED:
        {
            operations[mouseButton]->start();
            mouseStatus=ACTIVATED;
            break;
        }
        case RELEASED:
        {
            operations[mouseButton]->end();
            mouseStatus=DEACTIVATED;
            break;
        }
        case ACTIVATED:
        {
            operations[mouseButton]->execution();
        }
        case DEACTIVATED:
        {
        }
        }
    }

    for (unsigned int i=0; i<operations.size(); ++i)
    {
        operations[i]->wait();
    }
}

//Clear the node create, and destroy all its components
void PickHandler::handleMouseEvent(MOUSE_STATUS status, MOUSE_BUTTON button)
{
    if (!interaction) return;

    mouseButton=button;
    mouseStatus=status;

}

ComponentMouseInteraction *PickHandler::getInteraction()
{
    return interaction;
}

component::collision::BodyPicked PickHandler::findCollision()
{
    if (useCollisions)
    {
        component::collision::BodyPicked picked=findCollisionUsingPipeline();
        if (picked.body) return picked;
    }
    return findCollisionUsingBruteForce();
    //return findCollisionUsingColourCoding();
}

component::collision::BodyPicked PickHandler::findCollisionUsingPipeline()
{
    const defaulttype::Vector3& origin          = mouseCollision->getRay(0).origin();
    const defaulttype::Vector3& direction       = mouseCollision->getRay(0).direction();
    const double& maxLength                     = mouseCollision->getRay(0).l();

    BodyPicked result;
    const std::set< sofa::component::collision::BaseRayContact*> &contacts = mouseCollision->getContacts();
    for (std::set< sofa::component::collision::BaseRayContact*>::const_iterator it=contacts.begin(); it != contacts.end(); ++it)
    {

        const sofa::helper::vector<core::collision::DetectionOutput*>& output = (*it)->getDetectionOutputs();
        sofa::core::CollisionModel *modelInCollision;
        for (unsigned int i=0; i<output.size(); ++i)
        {

            if (output[i]->elem.first.getCollisionModel() == mouseCollision)
            {
                modelInCollision = output[i]->elem.second.getCollisionModel();
                if (!modelInCollision->isSimulated()) continue;

                const double d = (output[i]->point[1]-origin)*direction;
                if (d<0.0 || d>maxLength) continue;
                if (result.body == NULL || d < result.rayLength)
                {
                    result.body=modelInCollision;
                    result.indexCollisionElement = output[i]->elem.second.getIndex();
                    result.point = output[i]->point[1];
                    result.dist  = (output[i]->point[1]-output[i]->point[0]).norm();
                    result.rayLength  = d;
                }
            }
            else if (output[i]->elem.second.getCollisionModel() == mouseCollision)
            {
                modelInCollision = output[i]->elem.first.getCollisionModel();
                if (!modelInCollision->isSimulated()) continue;

                const double d = (output[i]->point[0]-origin)*direction;
                if (d<0.0 || d>maxLength) continue;
                if (result.body == NULL || d < result.rayLength)
                {
                    result.body=modelInCollision;
                    result.indexCollisionElement = output[i]->elem.first.getIndex();
                    result.point = output[i]->point[0];
                    result.dist  = (output[i]->point[1]-output[i]->point[0]).norm();
                    result.rayLength  = d;
                }
            }
        }
    }
    return result;
}

component::collision::BodyPicked PickHandler::findCollisionUsingBruteForce()
{
    const defaulttype::Vector3& origin          = mouseCollision->getRay(0).origin();
    const defaulttype::Vector3& direction       = mouseCollision->getRay(0).direction();
    const double& maxLength                     = mouseCollision->getRay(0).l();

    return findCollisionUsingBruteForce(origin, direction, maxLength);
}

component::collision::BodyPicked PickHandler::findCollisionUsingColourCoding()
{
    const defaulttype::Vector3& origin          = mouseCollision->getRay(0).origin();
    const defaulttype::Vector3& direction       = mouseCollision->getRay(0).direction();

    return findCollisionUsingColourCoding(origin, direction);

}

//WARNING: do not use this method with Ogre
component::collision::BodyPicked PickHandler::findCollisionUsingBruteForce(const defaulttype::Vector3& origin,
        const defaulttype::Vector3& direction,
        double maxLength)
{
    BodyPicked result;
    // Look for particles hit by this ray
    simulation::MechanicalPickParticlesVisitor picker(origin, direction, maxLength, 0);
    core::objectmodel::BaseNode* rootNode = dynamic_cast<core::objectmodel::BaseNode*>(sofa::simulation::getSimulation()->getContext());

    if (rootNode) picker.execute(rootNode->getContext());
    else std::cerr << "ERROR: root node not found." << std::endl;

    if (!picker.particles.empty())
    {
        core::behavior::BaseMechanicalState *mstate = picker.particles.begin()->second.first;
        result.mstate=mstate;
        result.indexCollisionElement = picker.particles.begin()->second.second;
        result.point[0] = mstate->getPX(result.indexCollisionElement);
        result.point[1] = mstate->getPY(result.indexCollisionElement);
        result.point[2] = mstate->getPZ(result.indexCollisionElement);
        result.dist =  0;
        result.rayLength = (result.point-origin)*direction;
    }
    return result;
}

component::collision::BodyPicked PickHandler::findCollisionUsingColourCoding(const defaulttype::Vector3& origin,
        const defaulttype::Vector3& direction)
{

    static bool firstTime=true;
    if (firstTime)
    {

        _fboParams.depthInternalformat = GL_DEPTH_COMPONENT24;
#ifdef GL_VERSION_3_0
        if (GLEW_VERSION_3_0)
        {
            _fboParams.colorInternalformat = GL_RGBA32F;
        }
        else
#endif
        {
            _fboParams.colorInternalformat = GL_RGBA16;
        }
        _fboParams.colorFormat         = GL_RGBA;
        _fboParams.colorType           = GL_FLOAT;

        _fbo.setFormat(_fboParams);
        _fbo.init(GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_SIZE);

        firstTime=false;
    }

    BodyPicked result;

    sofa::defaulttype::Vec4f color;
    int x = mousePosition.screenWidth -  mousePosition.x;
    int y = mousePosition.screenHeight - mousePosition.y;
    _fbo.start();
    if(renderCallback)
    {
        renderCallback->render();
    }

    glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType,color.elems);

    _fbo.stop();

    result = _decodeColour(color, origin, direction);

    return result;

}

component::collision::BodyPicked PickHandler::_decodeColour(const sofa::defaulttype::Vec4f& colour,
        const defaulttype::Vector3& origin,
        const defaulttype::Vector3& direction)
{
    using namespace core::objectmodel;
    using namespace core::behavior;
    using namespace sofa::defaulttype;
    static const float threshold = 0.00001f;

    component::collision::BodyPicked result;

    result.dist =  0;

    if( colour[0] > threshold || colour[1] > threshold || colour[2] > threshold  )
    {

        helper::vector<core::CollisionModel*> listCollisionModel;
        sofa::simulation::getSimulation()->getContext()->get<core::CollisionModel>(&listCollisionModel,BaseContext::SearchRoot);
        const int totalCollisionModel = listCollisionModel.size();
        const int indexListCollisionModel = (int) ( colour[0] * (float)totalCollisionModel + 0.5) - 1;
        result.body = listCollisionModel[indexListCollisionModel];
        result.indexCollisionElement = (int) ( colour[1] * result.body->getSize() );
        result.point = result.body->getPositionFromWeights(result.indexCollisionElement, colour[2], colour[3]);

        result.rayLength = (result.point-origin)*direction;
    }

    return result;
}

}
}

<|endoftext|>