<commit_before>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * You may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include <string.h>

#include <ctime>
#include <iostream>
#include <string>

#include "modsecurity/modsecurity.h"
#include "modsecurity/rules.h"

using modsecurity::Transaction;

char request_header[] =  "" \
    "GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\n\r" \
    "Host: net.tutsplus.com\n\r" \
    "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5)" \
    " Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\n\r" \
    "Accept: text/html,application/xhtml+xml,application/xml; " \
    "q=0.9,*/*;q=0.8\n\r" \
    "Accept-Language: en-us,en;q=0.5\n\r" \
    "Accept-Encoding: gzip,deflate\n\r" \
    "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n\r" \
    "Keep-Alive: 300\n\r" \
    "Connection: keep-alive\n\r" \
    "Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\n\r" \
    "Pragma: no-cache\n\r" \
    "Cache-Control: no-cache\n\r";

char request_uri[] = "GET /test.pl?param1=test&para2=test2";

char request_body[] = "";

char response_headers[] = "" \
    "HTTP/1.1 200 OK\n\r" \
    "Content-Type: text/xml; charset=utf-8\n\r" \
    "Content-Length: length\n\r";

unsigned char response_body[] = "" \
    "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\r" \
    "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
    "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " \
    "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n\r" \
    "  <soap:Body>\n\r" \
    "  <EnlightenResponse xmlns=\"http://clearforest.com/\">\n\r" \
    "  <EnlightenResult>string</EnlightenResult>\n\r" \
    "  </EnlightenResponse>\n\r" \
    "  </soap:Body>\n\r" \
    "</soap:Envelope>\n\r";

char ip[] = "200.249.12.31";

char rules_file[] = "basic_rules.conf";

#define NUM_REQUESTS 10000

int main(int argc, char *argv[]) {
    int i = 0;
    modsecurity::ModSecurity *modsec;
    modsecurity::Rules *rules;
    modsecurity::ModSecurityIntervention it;

    modsec = new modsecurity::ModSecurity();
    modsec->setConnectorInformation("ModSecurity-benchmark v0.0.1-alpha" \
            " (ModSecurity benchmark utility)");

    rules = new modsecurity::Rules();
    if (rules->loadFromUri(rules_file) < 0) {
        std::cout << "Problems loading the rules..." << std::endl;
        std::cout << rules->m_parserError.str() << std::endl;
        return -1;
    }

    for (i = 0; i < NUM_REQUESTS; i++) {
        std::cout << "Proceeding with request " << i << std::endl;

        Transaction *modsecTransaction = new Transaction(modsec, rules, NULL);
        modsecTransaction->processConnection(ip, 12345, "127.0.0.1", 80);

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }
        modsecTransaction->processURI(request_uri, "GET", "1.1");
        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->addRequestHeader("Host",
            "net.tutsplus.com");
        modsecTransaction->addRequestHeader("User-Agent",
            "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) " \
            "Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)");
        modsecTransaction->addRequestHeader("Accept",
            "text/html,application/xhtml+xml,application/xml;" \
            "q=0.9,*/*;q=0.8");
        modsecTransaction->addRequestHeader("Accept-Language",
            "en-us,en;q=0.5");
        modsecTransaction->addRequestHeader("Accept-Encoding",
            "gzip,deflate");
        modsecTransaction->addRequestHeader("Accept-Charset",
            "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
        modsecTransaction->addRequestHeader("Keep-Alive",
            "300");
        modsecTransaction->addRequestHeader("Connection",
            "keep-alive");
        modsecTransaction->addRequestHeader("Cookie",
            "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120");
        modsecTransaction->addRequestHeader("Pragma",
            "no-cache");
        modsecTransaction->addRequestHeader("Cache-Control",
            "no-cache");
        modsecTransaction->processRequestHeaders();

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->processRequestBody();

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->addResponseHeader("HTTP/1.1",
            "200 OK");
        modsecTransaction->addResponseHeader("Content-Type",
            "text/xml; charset=utf-8");
        modsecTransaction->addResponseHeader("Content-Length",
            "200");

        modsecTransaction->processResponseHeaders(200, "HTTP 1.2");

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->appendResponseBody(response_body,
            strlen((const char*)response_body));
        modsecTransaction->processResponseBody();

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

next_request:
        modsecTransaction->processLogging();
        delete modsecTransaction;
    }

    delete rules;
    delete modsec;
}
<commit_msg>Improve benchmark tool<commit_after>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * You may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include <string.h>

#include <ctime>
#include <iostream>
#include <string>

#include "modsecurity/modsecurity.h"
#include "modsecurity/rules.h"

using modsecurity::Transaction;

char request_header[] =  "" \
    "GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\n\r" \
    "Host: net.tutsplus.com\n\r" \
    "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5)" \
    " Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\n\r" \
    "Accept: text/html,application/xhtml+xml,application/xml; " \
    "q=0.9,*/*;q=0.8\n\r" \
    "Accept-Language: en-us,en;q=0.5\n\r" \
    "Accept-Encoding: gzip,deflate\n\r" \
    "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n\r" \
    "Keep-Alive: 300\n\r" \
    "Connection: keep-alive\n\r" \
    "Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\n\r" \
    "Pragma: no-cache\n\r" \
    "Cache-Control: no-cache\n\r";

char request_uri[] = "GET /test.pl?param1=test&para2=test2";

char request_body[] = "";

char response_headers[] = "" \
    "HTTP/1.1 200 OK\n\r" \
    "Content-Type: text/xml; charset=utf-8\n\r" \
    "Content-Length: length\n\r";

unsigned char response_body[] = "" \
    "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\r" \
    "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
    "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " \
    "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n\r" \
    "  <soap:Body>\n\r" \
    "  <EnlightenResponse xmlns=\"http://clearforest.com/\">\n\r" \
    "  <EnlightenResult>string</EnlightenResult>\n\r" \
    "  </EnlightenResponse>\n\r" \
    "  </soap:Body>\n\r" \
    "</soap:Envelope>\n\r";

char ip[] = "200.249.12.31";

char rules_file[] = "basic_rules.conf";

const char* const help_message = "Usage: benchmark [num_iterations|-h|-?|--help]";

int main(int argc, char *argv[]) {

    unsigned long long NUM_REQUESTS(10000);

    if (argc > 1) {
        if (0 == strcmp(argv[1], "-h") ||
            0 == strcmp(argv[1], "-?") ||
            0 == strcmp(argv[1], "--help")) {
            std::cout << help_message << std::endl;
            return 0;
        }
        errno = 0;
        unsigned long long upper = strtoull(argv[1], 0, 10);
        if (!errno && upper) {
            NUM_REQUESTS = upper;
        } else {
            if (errno) {
                perror("Invalid number of iterations");
            } else {
                std::cerr << "Failed to convert '" << argv[1] << "' to integer value" << std::endl
                          << help_message << std::endl;
                return -1;
            }
        }
    }
    std::cout << "Doing " << NUM_REQUESTS << " transactions...\n";
    modsecurity::ModSecurity *modsec;
    modsecurity::Rules *rules;
    modsecurity::ModSecurityIntervention it;
    modsecurity::intervention::reset(&it);
    modsec = new modsecurity::ModSecurity();
    modsec->setConnectorInformation("ModSecurity-benchmark v0.0.1-alpha" \
            " (ModSecurity benchmark utility)");

    rules = new modsecurity::Rules();
    if (rules->loadFromUri(rules_file) < 0) {
        std::cout << "Problems loading the rules..." << std::endl;
        std::cout << rules->m_parserError.str() << std::endl;
        return -1;
    }

    for (unsigned long long i = 0; i < NUM_REQUESTS; i++) {
        //std::cout << "Proceeding with request " << i << std::endl;

        Transaction *modsecTransaction = new Transaction(modsec, rules, NULL);
        modsecTransaction->processConnection(ip, 12345, "127.0.0.1", 80);

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }
        modsecTransaction->processURI(request_uri, "GET", "1.1");
        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->addRequestHeader("Host",
            "net.tutsplus.com");
        modsecTransaction->addRequestHeader("User-Agent",
            "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) " \
            "Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)");
        modsecTransaction->addRequestHeader("Accept",
            "text/html,application/xhtml+xml,application/xml;" \
            "q=0.9,*/*;q=0.8");
        modsecTransaction->addRequestHeader("Accept-Language",
            "en-us,en;q=0.5");
        modsecTransaction->addRequestHeader("Accept-Encoding",
            "gzip,deflate");
        modsecTransaction->addRequestHeader("Accept-Charset",
            "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
        modsecTransaction->addRequestHeader("Keep-Alive",
            "300");
        modsecTransaction->addRequestHeader("Connection",
            "keep-alive");
        modsecTransaction->addRequestHeader("Cookie",
            "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120");
        modsecTransaction->addRequestHeader("Pragma",
            "no-cache");
        modsecTransaction->addRequestHeader("Cache-Control",
            "no-cache");
        modsecTransaction->processRequestHeaders();

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->processRequestBody();

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->addResponseHeader("HTTP/1.1",
            "200 OK");
        modsecTransaction->addResponseHeader("Content-Type",
            "text/xml; charset=utf-8");
        modsecTransaction->addResponseHeader("Content-Length",
            "200");

        modsecTransaction->processResponseHeaders(200, "HTTP 1.2");

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

        modsecTransaction->appendResponseBody(response_body,
            strlen((const char*)response_body));
        modsecTransaction->processResponseBody();

        if (modsecTransaction->intervention(&it)) {
            std::cout << "There is an intervention" << std::endl;
            goto next_request;
        }

next_request:
        modsecTransaction->processLogging();
        delete modsecTransaction;
    }

    delete rules;
    delete modsec;
}
<|endoftext|>


<commit_before>//  Richards standard SUPG
//
  /* here i use a formula for "tau" presented in Appendix A of
     TJR Hughes, M Mallet and A Mizukami ``A new finite element formulation for computational fluid dynamics:: II. Behond SUPG'' Computer Methods in Applied Mechanics and Engineering 54 (1986) 341--355
  */
#include "RichardsSUPGstandard.h"

template<>
InputParameters validParams<RichardsSUPGstandard>()
{
  InputParameters params = validParams<RichardsSUPG>();
  params.addRequiredParam<Real>("p_SUPG", "SUPG pressure.  This parameter controls the strength of the upwinding.  This parameter must be positive.  If you need to track advancing fronts in a problem, then set to less than your expected range of pressures in your unsaturated zone.  Otherwise, set larger, and then minimal upwinding will occur and convergence will typically be good.  If you need no SUPG, it is more efficient not to use this UserObject.");
  params.addClassDescription("Standard SUPG relationships for Richards flow based on Appendix A of      TJR Hughes, M Mallet and A Mizukami ``A new finite element formulation for computational fluid dynamics:: II. Behond SUPG'' Computer Methods in Applied Mechanics and Engineering 54 (1986) 341--355");
  return params;
}

RichardsSUPGstandard::RichardsSUPGstandard(const std::string & name, InputParameters parameters) :
  RichardsSUPG(name, parameters),
  _p_SUPG(getParam<Real>("p_SUPG"))
{
  if (_p_SUPG <= 0)
    mooseError("The p_SUPG parameter is " << _p_SUPG << " but this parameter must be positive");
}

RealVectorValue
RichardsSUPGstandard::velSUPG(RealTensorValue perm, RealVectorValue gradp, Real density, RealVectorValue gravity) const
{
  return -perm*(gradp - density*gravity); // points in direction of info propagation
}

RealTensorValue
RichardsSUPGstandard::dvelSUPG_dgradp(RealTensorValue perm) const
{
  return -perm;
}

RealVectorValue
RichardsSUPGstandard::dvelSUPG_dp(RealTensorValue perm, Real density_prime, RealVectorValue gravity) const
{
  return perm*density_prime*gravity;
}

Real
RichardsSUPGstandard::cosh_relation(Real alpha) const
{
  if (alpha >= 20)
    return 1 - 1.0/alpha; // prevents overflows
  else if (alpha <= -20)
    return -1 - 1.0/alpha;
  else if (alpha == 0)
    return 0.0;
  return std::cosh(alpha)/std::sinh(alpha) - 1.0/alpha;
}

Real
RichardsSUPGstandard::cosh_relation_prime(Real alpha) const
{
  if (alpha >= 20)
      return 1.0/alpha/alpha;
  else if (alpha <= -20)
      return 1.0/alpha/alpha;
  else if (alpha == 0)
    return 1.0/3.0;
  return 1 - std::pow(std::cosh(alpha)/std::sinh(alpha), 2) + 1.0/alpha/alpha;
}

// the following is physically 2*velocity/element_length
RealVectorValue
RichardsSUPGstandard::bb(RealVectorValue vel, int dimen, RealVectorValue xi_prime, RealVectorValue eta_prime, RealVectorValue zeta_prime) const
{
  RealVectorValue b;
  b(0) = xi_prime*vel;
  if (dimen >= 2)
    b(1) = eta_prime*vel;
  if (dimen == 3)
    b(2) = zeta_prime*vel;
  return b;
}

// following is d(bb*bb)/d(gradp)
RealVectorValue
RichardsSUPGstandard::dbb2_dgradp(RealVectorValue vel, RealTensorValue dvel_dgradp, RealVectorValue xi_prime, RealVectorValue eta_prime, RealVectorValue zeta_prime) const
{
  return 2*((xi_prime*vel)*(dvel_dgradp*xi_prime) + (eta_prime*vel)*(dvel_dgradp*eta_prime) + (zeta_prime*vel)*(dvel_dgradp*zeta_prime)); // if dvel_dgradp wasn't symmetric we'd have to do a transpose of it here.
}

// following is d(bb*bb)/d(p)
Real
RichardsSUPGstandard::dbb2_dp(RealVectorValue vel, RealVectorValue dvel_dp, RealVectorValue xi_prime, RealVectorValue eta_prime, RealVectorValue zeta_prime) const
{
  return 2*((xi_prime*vel)*(dvel_dp*xi_prime) + (eta_prime*vel)*(dvel_dp*eta_prime) + (zeta_prime*vel)*(dvel_dp*zeta_prime));
}

Real
RichardsSUPGstandard::tauSUPG(RealVectorValue vel, Real traceperm, RealVectorValue b) const
{
  // vel = velocity, b = bb
  Real norm_v = std::pow(vel*vel, 0.5);
  Real norm_b = std::pow(b*b, 0.5); // Hughes et al investigate infinity-norm and 2-norm.  i just use 2-norm here.   norm_b ~ 2|a|/ele_length_in_direction_of_a

  if (norm_b == 0)
    return 0.0; // Only way for norm_b=0 is for zero ele size, or vel=0.  Either way we don't have to upwind.

  Real h = 2*norm_v/norm_b; // h is a measure of the element length in the "a" direction
  Real alpha = 0.5*norm_v*h/traceperm/_p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);

  return (norm_b == 0 ? 0 : xi_tilde/norm_b);
}

RealVectorValue
RichardsSUPGstandard::dtauSUPG_dgradp(RealVectorValue vel, RealTensorValue dvel_dgradp, Real traceperm, RealVectorValue b, RealVectorValue db2_dgradp) const
{
  Real norm_vel = std::pow(vel*vel, 0.5);
  if (norm_vel == 0)
    return RealVectorValue();
  RealVectorValue norm_vel_dgradp(dvel_dgradp*vel/norm_vel);

  Real norm_b = std::pow(b*b, 0.5);
  if (norm_b == 0)
    return RealVectorValue();
  RealVectorValue norm_b_dgradp = db2_dgradp/2/norm_b;

  Real h = 2*norm_vel/norm_b;
  RealVectorValue h_dgradp(2*norm_vel_dgradp/norm_b - 2*norm_vel*norm_b_dgradp/norm_b/norm_b);

  Real alpha = 0.5*norm_vel*h/traceperm/_p_SUPG;  // this is the Peclet number
  RealVectorValue alpha_dgradp = 0.5*(norm_vel_dgradp*h + norm_vel*h_dgradp)/traceperm/_p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);
  Real xi_tilde_prime = RichardsSUPGstandard::cosh_relation_prime(alpha);
  RealVectorValue xi_tilde_dgradp = xi_tilde_prime*alpha_dgradp;

  //Real tau = (norm_b == 0 ? 0 : xi_tilde/norm_b);
  RealVectorValue tau_dgradp = xi_tilde_dgradp/norm_b - xi_tilde*norm_b_dgradp/norm_b/norm_b;

  return tau_dgradp;
}

Real
RichardsSUPGstandard::dtauSUPG_dp(RealVectorValue vel, RealVectorValue dvel_dp, Real traceperm, RealVectorValue b, Real db2_dp) const
{
  Real norm_vel = std::pow(vel*vel, 0.5);
  if (norm_vel == 0)
    return 0.0; // this deriv is not necessarily correct, but i can't see a better thing to do
  Real norm_vel_dp(dvel_dp*vel/norm_vel);

  Real norm_b = std::pow(b*b, 0.5);
  if (norm_b == 0)
    return 0.0; // this deriv is not necessarily correct, but i can't see a better thing to do
  Real norm_b_dp = db2_dp/2/norm_b;

  Real h = 2*norm_vel/norm_b;
  Real h_dp(2*norm_vel_dp/norm_b - 2*norm_vel*norm_b_dp/norm_b/norm_b);

  Real alpha = 0.5*norm_vel*h/traceperm/_p_SUPG;  // this is the Peclet number
  Real alpha_dp = 0.5*(norm_vel_dp*h + norm_vel*h_dp)/traceperm/_p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);
  Real xi_tilde_prime = RichardsSUPGstandard::cosh_relation_prime(alpha);
  Real xi_tilde_dp = xi_tilde_prime*alpha_dp;

  //Real tau = (norm_b == 0 ? 0 : xi_tilde/norm_b);
  Real tau_dp = xi_tilde_dp/norm_b - xi_tilde*norm_b_dp/norm_b/norm_b;

  return tau_dp;
}
<commit_msg>Richards SUPG standard cosmetic changes<commit_after>//  Richards standard SUPG
//
  /* here i use a formula for "tau" presented in Appendix A of
     TJR Hughes, M Mallet and A Mizukami ``A new finite element formulation for computational fluid dynamics:: II. Behond SUPG'' Computer Methods in Applied Mechanics and Engineering 54 (1986) 341--355
  */
#include "RichardsSUPGstandard.h"

template<>
InputParameters validParams<RichardsSUPGstandard>()
{
  InputParameters params = validParams<RichardsSUPG>();
  params.addRequiredParam<Real>("p_SUPG", "SUPG pressure.  This parameter controls the strength of the upwinding.  This parameter must be positive.  If you need to track advancing fronts in a problem, then set to less than your expected range of pressures in your unsaturated zone.  Otherwise, set larger, and then minimal upwinding will occur and convergence will typically be good.  If you need no SUPG, it is more efficient not to use this UserObject.");
  params.addClassDescription("Standard SUPG relationships for Richards flow based on Appendix A of      TJR Hughes, M Mallet and A Mizukami ``A new finite element formulation for computational fluid dynamics:: II. Behond SUPG'' Computer Methods in Applied Mechanics and Engineering 54 (1986) 341--355");
  return params;
}

RichardsSUPGstandard::RichardsSUPGstandard(const std::string & name, InputParameters parameters) :
  RichardsSUPG(name, parameters),
  _p_SUPG(getParam<Real>("p_SUPG"))
{
  if (_p_SUPG <= 0)
    mooseError("The p_SUPG parameter is " << _p_SUPG << " but this parameter must be positive");
}

RealVectorValue
RichardsSUPGstandard::velSUPG(RealTensorValue perm, RealVectorValue gradp, Real density, RealVectorValue gravity) const
{
  return -perm*(gradp - density*gravity); // points in direction of info propagation
}

RealTensorValue
RichardsSUPGstandard::dvelSUPG_dgradp(RealTensorValue perm) const
{
  return -perm;
}

RealVectorValue
RichardsSUPGstandard::dvelSUPG_dp(RealTensorValue perm, Real density_prime, RealVectorValue gravity) const
{
  return perm*density_prime*gravity;
}

Real
RichardsSUPGstandard::cosh_relation(Real alpha) const
{
  if (alpha >= 20)
    return 1 - 1.0/alpha; // prevents overflows
  else if (alpha <= -20)
    return -1 - 1.0/alpha;
  else if (alpha == 0)
    return 0.0;
  return std::cosh(alpha)/std::sinh(alpha) - 1.0/alpha;
}

Real
RichardsSUPGstandard::cosh_relation_prime(Real alpha) const
{
  if (alpha >= 20)
      return 1.0/alpha/alpha;
  else if (alpha <= -20)
      return 1.0/alpha/alpha;
  else if (alpha == 0)
    return 1.0/3.0;
  return 1 - std::pow(std::cosh(alpha)/std::sinh(alpha), 2) + 1.0/alpha/alpha;
}

// the following is physically 2*velocity/element_length
RealVectorValue
RichardsSUPGstandard::bb(RealVectorValue vel, int dimen, RealVectorValue xi_prime, RealVectorValue eta_prime, RealVectorValue zeta_prime) const
{
  RealVectorValue b;
  b(0) = xi_prime*vel;
  if (dimen >= 2)
    b(1) = eta_prime*vel;
  if (dimen == 3)
    b(2) = zeta_prime*vel;
  return b;
}

// following is d(bb*bb)/d(gradp)
RealVectorValue
RichardsSUPGstandard::dbb2_dgradp(RealVectorValue vel, RealTensorValue dvel_dgradp, RealVectorValue xi_prime, RealVectorValue eta_prime, RealVectorValue zeta_prime) const
{
  return 2*((xi_prime*vel)*(dvel_dgradp.transpose()*xi_prime) + (eta_prime*vel)*(dvel_dgradp.transpose()*eta_prime) + (zeta_prime*vel)*(dvel_dgradp.transpose()*zeta_prime)); // if dvel_dgradp is symmetric so transpose is probably a waste of time
}

// following is d(bb*bb)/d(p)
Real
RichardsSUPGstandard::dbb2_dp(RealVectorValue vel, RealVectorValue dvel_dp, RealVectorValue xi_prime, RealVectorValue eta_prime, RealVectorValue zeta_prime) const
{
  return 2*((xi_prime*vel)*(dvel_dp*xi_prime) + (eta_prime*vel)*(dvel_dp*eta_prime) + (zeta_prime*vel)*(dvel_dp*zeta_prime));
}

Real
RichardsSUPGstandard::tauSUPG(RealVectorValue vel, Real traceperm, RealVectorValue b) const
{
  // vel = velocity, b = bb
  Real norm_v = std::pow(vel*vel, 0.5);
  Real norm_b = std::pow(b*b, 0.5); // Hughes et al investigate infinity-norm and 2-norm.  i just use 2-norm here.   norm_b ~ 2|a|/ele_length_in_direction_of_a

  if (norm_b == 0)
    return 0.0; // Only way for norm_b=0 is for zero ele size, or vel=0.  Either way we don't have to upwind.

  Real h = 2*norm_v/norm_b; // h is a measure of the element length in the "a" direction
  Real alpha = 0.5*norm_v*h/traceperm/_p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);

  return xi_tilde/norm_b;
}

RealVectorValue
RichardsSUPGstandard::dtauSUPG_dgradp(RealVectorValue vel, RealTensorValue dvel_dgradp, Real traceperm, RealVectorValue b, RealVectorValue db2_dgradp) const
{
  Real norm_vel = std::pow(vel*vel, 0.5);
  if (norm_vel == 0)
    return RealVectorValue();
  RealVectorValue norm_vel_dgradp(dvel_dgradp*vel/norm_vel);

  Real norm_b = std::pow(b*b, 0.5);
  if (norm_b == 0)
    return RealVectorValue();
  RealVectorValue norm_b_dgradp = db2_dgradp/2/norm_b;

  Real h = 2*norm_vel/norm_b;
  RealVectorValue h_dgradp(2*norm_vel_dgradp/norm_b - 2*norm_vel*norm_b_dgradp/norm_b/norm_b);

  Real alpha = 0.5*norm_vel*h/traceperm/_p_SUPG;  // this is the Peclet number
  RealVectorValue alpha_dgradp = 0.5*(norm_vel_dgradp*h + norm_vel*h_dgradp)/traceperm/_p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);
  Real xi_tilde_prime = RichardsSUPGstandard::cosh_relation_prime(alpha);
  RealVectorValue xi_tilde_dgradp = xi_tilde_prime*alpha_dgradp;

  //Real tau = xi_tilde/norm_b;
  RealVectorValue tau_dgradp = xi_tilde_dgradp/norm_b - xi_tilde*norm_b_dgradp/norm_b/norm_b;

  return tau_dgradp;
}

Real
RichardsSUPGstandard::dtauSUPG_dp(RealVectorValue vel, RealVectorValue dvel_dp, Real traceperm, RealVectorValue b, Real db2_dp) const
{
  Real norm_vel = std::pow(vel*vel, 0.5);
  if (norm_vel == 0)
    return 0.0; // this deriv is not necessarily correct, but i can't see a better thing to do
  Real norm_vel_dp(dvel_dp*vel/norm_vel);

  Real norm_b = std::pow(b*b, 0.5);
  if (norm_b == 0)
    return 0.0; // this deriv is not necessarily correct, but i can't see a better thing to do
  Real norm_b_dp = db2_dp/2/norm_b;

  Real h = 2*norm_vel/norm_b;
  Real h_dp(2*norm_vel_dp/norm_b - 2*norm_vel*norm_b_dp/norm_b/norm_b);

  Real alpha = 0.5*norm_vel*h/traceperm/_p_SUPG;  // this is the Peclet number
  Real alpha_dp = 0.5*(norm_vel_dp*h + norm_vel*h_dp)/traceperm/_p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);
  Real xi_tilde_prime = RichardsSUPGstandard::cosh_relation_prime(alpha);
  Real xi_tilde_dp = xi_tilde_prime*alpha_dp;

  //Real tau = xi_tilde/norm_b;
  Real tau_dp = xi_tilde_dp/norm_b - xi_tilde*norm_b_dp/norm_b/norm_b;

  return tau_dp;
}
<|endoftext|>


<commit_before>#include <sofa/simulation/common/MechanicalOperations.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/simulation/common/MechanicalMatrixVisitor.h>
#include <sofa/core/MultiVecId.h>
#include <sofa/core/VecId.h>
#include <sofa/core/behavior/LinearSolver.h>
#include <sofa/defaulttype/BaseMatrix.h>
namespace sofa
{

namespace simulation
{

namespace common
{

MechanicalOperations::MechanicalOperations(sofa::core::objectmodel::BaseContext* ctx, const sofa::core::MechanicalParams* mparams)
    :mparams(*mparams),ctx(ctx),executeVisitor(*ctx)
{
}

MechanicalOperations::MechanicalOperations(sofa::core::objectmodel::BaseContext* ctx, const sofa::core::ExecParams* params)
    :mparams(*params),ctx(ctx),executeVisitor(*ctx)
{
}

/// Propagate the given displacement through all mappings
void MechanicalOperations::propagateDx(core::MultiVecDerivId dx)
{
    mparams.setDx(dx);
    executeVisitor( MechanicalPropagateDxVisitor(dx, false, false, &mparams) );
}

/// Propagate the given displacement through all mappings and reset the current force delta
void MechanicalOperations::propagateDxAndResetDf(core::MultiVecDerivId dx, core::MultiVecDerivId df)
{
    mparams.setDx(dx);
    mparams.setDf(df);
    executeVisitor( MechanicalPropagateDxAndResetForceVisitor(dx, df, false, &mparams) );
}

/// Propagate the given position through all mappings
void MechanicalOperations::propagateX(core::MultiVecCoordId x)
{
    mparams.setX(x);
    executeVisitor( MechanicalPropagateXVisitor(x, false, &mparams) //Don't ignore the masks
                  );
}

/// Propagate the given position through all mappings and reset the current force delta
void MechanicalOperations::propagateXAndResetF(core::MultiVecCoordId x, core::MultiVecDerivId f)
{
    mparams.setX(x);
    mparams.setF(f);
    executeVisitor( MechanicalPropagateXAndResetForceVisitor(x, f, false, &mparams) );
}

/// Apply projective constraints to the given vector
void MechanicalOperations::projectResponse(core::MultiVecDerivId dx, double **W)
{
    mparams.setDx(dx);
    executeVisitor( MechanicalApplyConstraintsVisitor(dx, W, &mparams) );
}

void MechanicalOperations::addMdx(core::MultiVecDerivId res, core::MultiVecDerivId dx, double factor)
{
    mparams.setDx(dx);
    executeVisitor( MechanicalAddMDxVisitor(res,dx,factor,&mparams) );
}

///< res += factor M.dx
void MechanicalOperations::integrateVelocity(core::MultiVecDerivId res, core::ConstMultiVecCoordId x, core::ConstMultiVecDerivId v, double dt)
{
    executeVisitor( MechanicalVOpVisitor(res,x,v,dt, &mparams) );
}

///< res = x + v.dt
void MechanicalOperations::accFromF(core::MultiVecDerivId a, core::ConstMultiVecDerivId f) ///< a = M^-1 . f
{
    mparams.setDx(a);
    mparams.setF(f);

    executeVisitor( MechanicalAccFromFVisitor(a,&mparams) );
}

/// Compute the current force (given the latest propagated position and velocity)
void MechanicalOperations::computeForce(core::MultiVecDerivId result, bool clear, bool accumulate)
{
    mparams.setF(result);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(result, false, &mparams), true ); // enable prefetching
        //finish();
    }
    executeVisitor( MechanicalComputeForceVisitor(result, accumulate, &mparams) , true ); // enable prefetching
}

/// Compute the current force delta (given the latest propagated displacement)
void MechanicalOperations::computeDf(core::MultiVecDerivId df, bool clear, bool accumulate)
{
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, false, &mparams) );
        //	finish();
    }
    executeVisitor( MechanicalComputeDfVisitor( df,  accumulate, &mparams) );
}

/// Compute the current force delta (given the latest propagated velocity)
void MechanicalOperations::computeDfV(core::MultiVecDerivId df, bool clear, bool accumulate)
{
    core::ConstMultiVecDerivId dx = mparams.dx();
    mparams.setDx(mparams.v());
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, false, &mparams) );
        //finish();
    }
    executeVisitor( MechanicalComputeDfVisitor(df, accumulate, &mparams) );
    mparams.setDx(dx);
}

/// accumulate $ df += (m M + b B + k K) dx $ (given the latest propagated displacement)
void MechanicalOperations::addMBKdx(core::MultiVecDerivId df, double m, double b, double k, bool clear, bool accumulate)
{
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, true, &mparams) );
        //finish();
    }
    mparams.setBFactor(b);
    mparams.setKFactor(k);
    mparams.setMFactor(m);
    executeVisitor( MechanicalAddMBKdxVisitor(df, accumulate, &mparams) );
}

/// accumulate $ df += (m M + b B + k K) velocity $
void MechanicalOperations::addMBKv(core::MultiVecDerivId df, double m, double b, double k, bool clear, bool accumulate)
{
    core::ConstMultiVecDerivId dx = mparams.dx();
    mparams.setDx(mparams.v());
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, true, &mparams) );
        //finish();
    }
    mparams.setBFactor(b);
    mparams.setKFactor(k);
    mparams.setMFactor(m);
    /* useV = true */
    executeVisitor( MechanicalAddMBKdxVisitor(df, accumulate, &mparams) );
    mparams.setDx(dx);
}

/// Add dt*Gravity to the velocity
void MechanicalOperations::addSeparateGravity(double dt, core::MultiVecDerivId result)
{
    mparams.setDt(dt);
    mparams.setV(result);
    executeVisitor( MechanicalAddSeparateGravityVisitor(result, &mparams) );
}

void MechanicalOperations::computeContactForce(core::MultiVecDerivId result)
{
    mparams.setF(result);
    executeVisitor( MechanicalResetForceVisitor(result, false, &mparams) );
    //finish();
    executeVisitor( MechanicalComputeContactForceVisitor(result, &mparams) );
}

void MechanicalOperations::computeContactDf(core::MultiVecDerivId df)
{
    mparams.setDf(df);
    executeVisitor( MechanicalResetForceVisitor(df, false, &mparams) );
    //finish();
}

void MechanicalOperations::computeAcc(double t, core::MultiVecDerivId a, core::MultiVecCoordId x, core::MultiVecDerivId v)
{
    MultiVecDerivId f( VecDerivId::force() );
    mparams.setF(f);
    mparams.setDx(a);
    mparams.setX(x);
    mparams.setV(v);
    executeVisitor( MechanicalPropagatePositionAndVelocityVisitor(t,x,v,
#ifdef SOFA_SUPPORT_MAPPED_MASS
            a,
#endif
            true,&mparams) );
    computeForce(f);

    accFromF(a,f);
    projectResponse(a);
}

void MechanicalOperations::computeContactAcc(double t, core::MultiVecDerivId a, core::MultiVecCoordId x, core::MultiVecDerivId v)
{
    MultiVecDerivId f( VecDerivId::force() );
    mparams.setF(f);
    mparams.setDx(a);
    mparams.setX(x);
    mparams.setV(v);
    executeVisitor( MechanicalPropagatePositionAndVelocityVisitor(t,x,v,
#ifdef SOFA_SUPPORT_MAPPED_MASS
            a,
#endif
            true,&mparams) );
    computeContactForce(f);

    accFromF(a,f);
    projectResponse(a);
}

/// @}

/// @name Matrix operations using LinearSolver components
/// @{

using sofa::core::behavior::LinearSolver;
using sofa::core::objectmodel::BaseContext;

void MechanicalOperations::m_resetSystem()
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR: requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->resetSystem();
}

void MechanicalOperations::m_setSystemMBKMatrix(double mFact, double bFact, double kFact)
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    mparams.setMFactor(mFact);
    mparams.setBFactor(bFact);
    mparams.setKFactor(kFact);
    s->setSystemMBKMatrix(&mparams);
}

void MechanicalOperations::m_setSystemRHVector(core::MultiVecDerivId v)
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->setSystemRHVector(v);
}

void MechanicalOperations::m_setSystemLHVector(core::MultiVecDerivId v)
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->setSystemRHVector(v);

}

void MechanicalOperations::m_solveSystem()
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->solveSystem();
}

void MechanicalOperations::m_print( std::ostream& out )
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR: requires a LinearSolver."<<ctx->sendl;
        return;
    }
    defaulttype::BaseMatrix* m = s->getSystemBaseMatrix();
    if (!m) return;
    //out << *m;
    int ny = m->rowSize();
    int nx = m->colSize();
    out << "[";
    for (int y=0; y<ny; ++y)
    {
        out << "[";
        for (int x=0; x<nx; x++)
            out << ' ' << m->element(x,y);
        out << "]";
    }
    out << "]";
}

/// @}

/// @name Matrix operations
/// @{

// BaseMatrix & BaseVector Computations
void MechanicalOperations::getMatrixDimension(unsigned int *  const nbRow, unsigned int * const nbCol, sofa::core::behavior::MultiMatrixAccessor* matrix)
{
    executeVisitor( MechanicalGetMatrixDimensionVisitor(nbRow, nbCol, matrix,&mparams) );
}

void MechanicalOperations::addMBK_ToMatrix(const sofa::core::behavior::MultiMatrixAccessor* matrix, double mFact, double bFact, double kFact)
{
    mparams.setMFactor(mFact);
    mparams.setBFactor(bFact);
    mparams.setKFactor(kFact);
    if (matrix != NULL)
    {
        //std::cout << "MechanicalAddMBK_ToMatrixVisitor "<< mFact << " " << bFact << " " << kFact << " " << offset << std::endl;
        executeVisitor( MechanicalAddMBK_ToMatrixVisitor(matrix,&mparams) );
    }
}

void MechanicalOperations::multiVector2BaseVector(core::ConstMultiVecId src, defaulttype::BaseVector *dest, const sofa::core::behavior::MultiMatrixAccessor* matrix)
{
    if (dest != NULL)
    {
        executeVisitor( MechanicalMultiVectorToBaseVectorVisitor(src, dest, matrix, &mparams) );
    }
}

void MechanicalOperations::multiVectorPeqBaseVector(core::MultiVecDerivId dest, defaulttype::BaseVector *src, const sofa::core::behavior::MultiMatrixAccessor* matrix)
{
    if (src != NULL)
    {
        executeVisitor( MechanicalMultiVectorPeqBaseVectorVisitor(dest, src, matrix, &mparams) );
    }
}

/// @}

/// @name Debug operations
/// @{

/// Dump the content of the given vector.
void MechanicalOperations::print( core::ConstMultiVecId /*v*/, std::ostream& /*out*/ )
{
}

void MechanicalOperations::printWithElapsedTime( core::ConstMultiVecId /*v*/, unsigned /*time*/, std::ostream& /*out*/ )
{
}

/// @}

}

}

}
<commit_msg>r8721/sofa-dev : FIX: EulerImplicit+CGLinearSolver works ! (found the last bugs with fjourdes)<commit_after>#include <sofa/simulation/common/MechanicalOperations.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/simulation/common/MechanicalMatrixVisitor.h>
#include <sofa/core/MultiVecId.h>
#include <sofa/core/VecId.h>
#include <sofa/core/behavior/LinearSolver.h>
#include <sofa/defaulttype/BaseMatrix.h>
namespace sofa
{

namespace simulation
{

namespace common
{

MechanicalOperations::MechanicalOperations(sofa::core::objectmodel::BaseContext* ctx, const sofa::core::MechanicalParams* mparams)
    :mparams(*mparams),ctx(ctx),executeVisitor(*ctx)
{
}

MechanicalOperations::MechanicalOperations(sofa::core::objectmodel::BaseContext* ctx, const sofa::core::ExecParams* params)
    :mparams(*params),ctx(ctx),executeVisitor(*ctx)
{
}

/// Propagate the given displacement through all mappings
void MechanicalOperations::propagateDx(core::MultiVecDerivId dx)
{
    mparams.setDx(dx);
    executeVisitor( MechanicalPropagateDxVisitor(dx, false, false, &mparams) );
}

/// Propagate the given displacement through all mappings and reset the current force delta
void MechanicalOperations::propagateDxAndResetDf(core::MultiVecDerivId dx, core::MultiVecDerivId df)
{
    mparams.setDx(dx);
    mparams.setDf(df);
    executeVisitor( MechanicalPropagateDxAndResetForceVisitor(dx, df, false, &mparams) );
}

/// Propagate the given position through all mappings
void MechanicalOperations::propagateX(core::MultiVecCoordId x)
{
    mparams.setX(x);
    executeVisitor( MechanicalPropagateXVisitor(x, false, &mparams) //Don't ignore the masks
                  );
}

/// Propagate the given position through all mappings and reset the current force delta
void MechanicalOperations::propagateXAndResetF(core::MultiVecCoordId x, core::MultiVecDerivId f)
{
    mparams.setX(x);
    mparams.setF(f);
    executeVisitor( MechanicalPropagateXAndResetForceVisitor(x, f, false, &mparams) );
}

/// Apply projective constraints to the given vector
void MechanicalOperations::projectResponse(core::MultiVecDerivId dx, double **W)
{
    mparams.setDx(dx);
    executeVisitor( MechanicalApplyConstraintsVisitor(dx, W, &mparams) );
}

void MechanicalOperations::addMdx(core::MultiVecDerivId res, core::MultiVecDerivId dx, double factor)
{
    mparams.setDx(dx);
    executeVisitor( MechanicalAddMDxVisitor(res,dx,factor,&mparams) );
}

///< res += factor M.dx
void MechanicalOperations::integrateVelocity(core::MultiVecDerivId res, core::ConstMultiVecCoordId x, core::ConstMultiVecDerivId v, double dt)
{
    executeVisitor( MechanicalVOpVisitor(res,x,v,dt, &mparams) );
}

///< res = x + v.dt
void MechanicalOperations::accFromF(core::MultiVecDerivId a, core::ConstMultiVecDerivId f) ///< a = M^-1 . f
{
    mparams.setDx(a);
    mparams.setF(f);

    executeVisitor( MechanicalAccFromFVisitor(a,&mparams) );
}

/// Compute the current force (given the latest propagated position and velocity)
void MechanicalOperations::computeForce(core::MultiVecDerivId result, bool clear, bool accumulate)
{
    mparams.setF(result);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(result, false, &mparams), true ); // enable prefetching
        //finish();
    }
    executeVisitor( MechanicalComputeForceVisitor(result, accumulate, &mparams) , true ); // enable prefetching
}

/// Compute the current force delta (given the latest propagated displacement)
void MechanicalOperations::computeDf(core::MultiVecDerivId df, bool clear, bool accumulate)
{
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, false, &mparams) );
        //	finish();
    }
    executeVisitor( MechanicalComputeDfVisitor( df,  accumulate, &mparams) );
}

/// Compute the current force delta (given the latest propagated velocity)
void MechanicalOperations::computeDfV(core::MultiVecDerivId df, bool clear, bool accumulate)
{
    core::ConstMultiVecDerivId dx = mparams.dx();
    mparams.setDx(mparams.v());
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, false, &mparams) );
        //finish();
    }
    executeVisitor( MechanicalComputeDfVisitor(df, accumulate, &mparams) );
    mparams.setDx(dx);
}

/// accumulate $ df += (m M + b B + k K) dx $ (given the latest propagated displacement)
void MechanicalOperations::addMBKdx(core::MultiVecDerivId df, double m, double b, double k, bool clear, bool accumulate)
{
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, true, &mparams) );
        //finish();
    }
    mparams.setBFactor(b);
    mparams.setKFactor(k);
    mparams.setMFactor(m);
    executeVisitor( MechanicalAddMBKdxVisitor(df, accumulate, &mparams) );
}

/// accumulate $ df += (m M + b B + k K) velocity $
void MechanicalOperations::addMBKv(core::MultiVecDerivId df, double m, double b, double k, bool clear, bool accumulate)
{
    core::ConstMultiVecDerivId dx = mparams.dx();
    mparams.setDx(mparams.v());
    mparams.setDf(df);
    if (clear)
    {
        executeVisitor( MechanicalResetForceVisitor(df, true, &mparams) );
        //finish();
    }
    mparams.setBFactor(b);
    mparams.setKFactor(k);
    mparams.setMFactor(m);
    /* useV = true */
    executeVisitor( MechanicalAddMBKdxVisitor(df, accumulate, &mparams) );
    mparams.setDx(dx);
}

/// Add dt*Gravity to the velocity
void MechanicalOperations::addSeparateGravity(double dt, core::MultiVecDerivId result)
{
    mparams.setDt(dt);
    mparams.setV(result);
    executeVisitor( MechanicalAddSeparateGravityVisitor(result, &mparams) );
}

void MechanicalOperations::computeContactForce(core::MultiVecDerivId result)
{
    mparams.setF(result);
    executeVisitor( MechanicalResetForceVisitor(result, false, &mparams) );
    //finish();
    executeVisitor( MechanicalComputeContactForceVisitor(result, &mparams) );
}

void MechanicalOperations::computeContactDf(core::MultiVecDerivId df)
{
    mparams.setDf(df);
    executeVisitor( MechanicalResetForceVisitor(df, false, &mparams) );
    //finish();
}

void MechanicalOperations::computeAcc(double t, core::MultiVecDerivId a, core::MultiVecCoordId x, core::MultiVecDerivId v)
{
    MultiVecDerivId f( VecDerivId::force() );
    mparams.setF(f);
    mparams.setDx(a);
    mparams.setX(x);
    mparams.setV(v);
    executeVisitor( MechanicalPropagatePositionAndVelocityVisitor(t,x,v,
#ifdef SOFA_SUPPORT_MAPPED_MASS
            a,
#endif
            true,&mparams) );
    computeForce(f);

    accFromF(a,f);
    projectResponse(a);
}

void MechanicalOperations::computeContactAcc(double t, core::MultiVecDerivId a, core::MultiVecCoordId x, core::MultiVecDerivId v)
{
    MultiVecDerivId f( VecDerivId::force() );
    mparams.setF(f);
    mparams.setDx(a);
    mparams.setX(x);
    mparams.setV(v);
    executeVisitor( MechanicalPropagatePositionAndVelocityVisitor(t,x,v,
#ifdef SOFA_SUPPORT_MAPPED_MASS
            a,
#endif
            true,&mparams) );
    computeContactForce(f);

    accFromF(a,f);
    projectResponse(a);
}

/// @}

/// @name Matrix operations using LinearSolver components
/// @{

using sofa::core::behavior::LinearSolver;
using sofa::core::objectmodel::BaseContext;

void MechanicalOperations::m_resetSystem()
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR: requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->resetSystem();
}

void MechanicalOperations::m_setSystemMBKMatrix(double mFact, double bFact, double kFact)
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    mparams.setMFactor(mFact);
    mparams.setBFactor(bFact);
    mparams.setKFactor(kFact);
    s->setSystemMBKMatrix(&mparams);
}

void MechanicalOperations::m_setSystemRHVector(core::MultiVecDerivId v)
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->setSystemRHVector(v);
}

void MechanicalOperations::m_setSystemLHVector(core::MultiVecDerivId v)
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->setSystemLHVector(v);

}

void MechanicalOperations::m_solveSystem()
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR:  requires a LinearSolver."<<ctx->sendl;
        return;
    }
    s->solveSystem();
}

void MechanicalOperations::m_print( std::ostream& out )
{
    LinearSolver* s = ctx->get<LinearSolver>(ctx->getTags(), BaseContext::SearchDown);
    if (!s)
    {
        ctx->serr << "ERROR: requires a LinearSolver."<<ctx->sendl;
        return;
    }
    defaulttype::BaseMatrix* m = s->getSystemBaseMatrix();
    if (!m) return;
    //out << *m;
    int ny = m->rowSize();
    int nx = m->colSize();
    out << "[";
    for (int y=0; y<ny; ++y)
    {
        out << "[";
        for (int x=0; x<nx; x++)
            out << ' ' << m->element(x,y);
        out << "]";
    }
    out << "]";
}

/// @}

/// @name Matrix operations
/// @{

// BaseMatrix & BaseVector Computations
void MechanicalOperations::getMatrixDimension(unsigned int *  const nbRow, unsigned int * const nbCol, sofa::core::behavior::MultiMatrixAccessor* matrix)
{
    executeVisitor( MechanicalGetMatrixDimensionVisitor(nbRow, nbCol, matrix,&mparams) );
}

void MechanicalOperations::addMBK_ToMatrix(const sofa::core::behavior::MultiMatrixAccessor* matrix, double mFact, double bFact, double kFact)
{
    mparams.setMFactor(mFact);
    mparams.setBFactor(bFact);
    mparams.setKFactor(kFact);
    if (matrix != NULL)
    {
        //std::cout << "MechanicalAddMBK_ToMatrixVisitor "<< mFact << " " << bFact << " " << kFact << " " << offset << std::endl;
        executeVisitor( MechanicalAddMBK_ToMatrixVisitor(matrix,&mparams) );
    }
}

void MechanicalOperations::multiVector2BaseVector(core::ConstMultiVecId src, defaulttype::BaseVector *dest, const sofa::core::behavior::MultiMatrixAccessor* matrix)
{
    if (dest != NULL)
    {
        executeVisitor( MechanicalMultiVectorToBaseVectorVisitor(src, dest, matrix, &mparams) );
    }
}

void MechanicalOperations::multiVectorPeqBaseVector(core::MultiVecDerivId dest, defaulttype::BaseVector *src, const sofa::core::behavior::MultiMatrixAccessor* matrix)
{
    if (src != NULL)
    {
        executeVisitor( MechanicalMultiVectorPeqBaseVectorVisitor(dest, src, matrix, &mparams) );
    }
}

/// @}

/// @name Debug operations
/// @{

/// Dump the content of the given vector.
void MechanicalOperations::print( core::ConstMultiVecId /*v*/, std::ostream& /*out*/ )
{
}

void MechanicalOperations::printWithElapsedTime( core::ConstMultiVecId /*v*/, unsigned /*time*/, std::ostream& /*out*/ )
{
}

/// @}

}

}

}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <seastar/core/sstring.hh>
#include <random>

inline
sstring make_random_string(size_t size) {
    static thread_local std::default_random_engine rng;
    std::uniform_int_distribution<char> dist;
    sstring str(sstring::initialized_later(), size);
    for (auto&& b : str) {
        b = dist(rng);
    }
    return str;
}
<commit_msg>tests: simple_schema: Add missing include<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <seastar/core/sstring.hh>
#include "seastarx.hh"
#include <random>

inline
sstring make_random_string(size_t size) {
    static thread_local std::default_random_engine rng;
    std::uniform_int_distribution<char> dist;
    sstring str(sstring::initialized_later(), size);
    for (auto&& b : str) {
        b = dist(rng);
    }
    return str;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include "Halide.h"

using namespace Halide;

#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif

int count = 0;
extern "C" DLLEXPORT int call_counter(int x, int y) {
    count++;
    return 0;
}
HalideExtern_2(int, call_counter, int, int);

extern "C" void *my_malloc(void *, size_t x) {
    printf("Malloc wasn't supposed to be called!\n");
    exit(-1);
}

extern "C" void my_free(void *, void *) {
}

int main(int argc, char **argv) {
    Var x, y;

    {
        Func f, g;

        f(x) = call_counter(x, 0);
        g(x) = f(x) + f(x-1);

        f.store_root().compute_at(g, x);

        Image<int> im = g.realize(100);

        // f should be able to tell that it only needs to compute each value once
        if (count != 101) {
            printf("f was called %d times instead of %d times\n", count, 101);
            return -1;
        }
    }

    // Try again where there's a containing stage
    /*{
        count = 0;
        Func f, g, h;
        f(x) = call_counter(x, 0);
        g(x) = f(x) + f(x-1);
        h(x) = g(x);

        f.store_root().compute_at(g, x);
        g.compute_at(h, x);

        Image<int> im = h.realize(100);
        if (count != 101) {
            printf("f was called %d times instead of %d times\n", count, 101);
            return -1;
        }
    }

    // Add an inner vectorized dimension.
    {
        count = 0;
        Func f, g, h;
        Var c;
        f(x, c) = call_counter(x, c);
        g(x, c) = f(x + 1, c) - f(x, c);
        h(x, c) = g(x, c);

        f.store_root()
            .compute_at(h, x)
            .reorder(c, x)
            .reorder_storage(c, x)
            .bound(c, 0, 4)
            .vectorize(c);

        g.compute_at(h, x);

        h.reorder(c, x).reorder_storage(c, x).bound(c, 0, 4).vectorize(c);

        Image<int> im = h.realize(100, 4);
        if (count != 404) {
            printf("f was called %d times instead of %d times\n", count, 404);
            return -1;
        }
    }

    // Now try with a reduction
    {
        count = 0;
        RDom r(0, 100);
        Func f, g;

        f(x, y) = 0;
        f(r, y) = call_counter(r, y);
        f.store_root().compute_at(g, y);

        g(x, y) = f(x, y) + f(x, y-1);

        Image<int> im = g.realize(10, 10);

        // For each value of y, f should be evaluated over (0 .. 100) in
        // x, and (y .. y-1) in y. Sliding window optimization means that
        // we can skip the y-1 case in all but the first iteration.
        if (count != 100 * 11) {
            printf("f was called %d times instead of %d times\n", count, 100*11);
            return -1;
        }
    }

    {
        // Now try sliding over multiple dimensions at once
        Func f, g;

        count = 0;
        f(x, y) = call_counter(x, y);
        g(x, y) = f(x-1, y) + f(x, y) + f(x, y-1);
        f.store_root().compute_at(g, x);

        Image<int> im = g.realize(10, 10);

        if (count != 11*11) {
            printf("f was called %d times instead of %d times\n", count, 11*11);
            return -1;
        }
    }

    {
        Func f, g;

        // Now a trickier example. In order for this to work, Halide would have to slide diagonally. We don't handle this.
        count = 0;
        f(x, y) = call_counter(x, y);
        // When x was two smaller the second term was computed. When y was two smaller the third term was computed.
        g(x, y) = f(x+y, x-y) + f((x-2)+y, (x-2)-y) + f(x+(y-2), x-(y-2));
        f.store_root().compute_at(g, x);

        Image<int> im = g.realize(10, 10);
        if (count != 1500) {
            printf("f was called %d times instead of %d times\n", count, 1500);
            return -1;
        }
    }

    {
        // Now make sure Halide folds the example in Func.h down to a stack allocation
        Func f, g;
        f(x, y) = x*y;
        g(x, y) = f(x, y) + f(x+1, y) + f(x, y+1) + f(x+1, y+1);
        f.store_at(g, y).compute_at(g, x);
        g.set_custom_allocator(&my_malloc, &my_free);
        Image<int> im = g.realize(10, 10);
    }*/

    printf("Success!\n");
    return 0;
}
<commit_msg>Uncomment sliding window tests<commit_after>#include <stdio.h>
#include "Halide.h"

using namespace Halide;

#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif

int count = 0;
extern "C" DLLEXPORT int call_counter(int x, int y) {
    count++;
    return 0;
}
HalideExtern_2(int, call_counter, int, int);

extern "C" void *my_malloc(void *, size_t x) {
    printf("Malloc wasn't supposed to be called!\n");
    exit(-1);
}

extern "C" void my_free(void *, void *) {
}

int main(int argc, char **argv) {
    Var x, y;

    {
        Func f, g;

        f(x) = call_counter(x, 0);
        g(x) = f(x) + f(x-1);

        f.store_root().compute_at(g, x);

        Image<int> im = g.realize(100);

        // f should be able to tell that it only needs to compute each value once
        if (count != 101) {
            printf("f was called %d times instead of %d times\n", count, 101);
            return -1;
        }
    }

    // Try again where there's a containing stage
    {
        count = 0;
        Func f, g, h;
        f(x) = call_counter(x, 0);
        g(x) = f(x) + f(x-1);
        h(x) = g(x);

        f.store_root().compute_at(g, x);
        g.compute_at(h, x);

        Image<int> im = h.realize(100);
        if (count != 101) {
            printf("f was called %d times instead of %d times\n", count, 101);
            return -1;
        }
    }

    // Add an inner vectorized dimension.
    {
        count = 0;
        Func f, g, h;
        Var c;
        f(x, c) = call_counter(x, c);
        g(x, c) = f(x + 1, c) - f(x, c);
        h(x, c) = g(x, c);

        f.store_root()
            .compute_at(h, x)
            .reorder(c, x)
            .reorder_storage(c, x)
            .bound(c, 0, 4)
            .vectorize(c);

        g.compute_at(h, x);

        h.reorder(c, x).reorder_storage(c, x).bound(c, 0, 4).vectorize(c);

        Image<int> im = h.realize(100, 4);
        if (count != 404) {
            printf("f was called %d times instead of %d times\n", count, 404);
            return -1;
        }
    }

    // Now try with a reduction
    {
        count = 0;
        RDom r(0, 100);
        Func f, g;

        f(x, y) = 0;
        f(r, y) = call_counter(r, y);
        f.store_root().compute_at(g, y);

        g(x, y) = f(x, y) + f(x, y-1);

        Image<int> im = g.realize(10, 10);

        // For each value of y, f should be evaluated over (0 .. 100) in
        // x, and (y .. y-1) in y. Sliding window optimization means that
        // we can skip the y-1 case in all but the first iteration.
        if (count != 100 * 11) {
            printf("f was called %d times instead of %d times\n", count, 100*11);
            return -1;
        }
    }

    {
        // Now try sliding over multiple dimensions at once
        Func f, g;

        count = 0;
        f(x, y) = call_counter(x, y);
        g(x, y) = f(x-1, y) + f(x, y) + f(x, y-1);
        f.store_root().compute_at(g, x);

        Image<int> im = g.realize(10, 10);

        if (count != 11*11) {
            printf("f was called %d times instead of %d times\n", count, 11*11);
            return -1;
        }
    }

    {
        Func f, g;

        // Now a trickier example. In order for this to work, Halide would have to slide diagonally. We don't handle this.
        count = 0;
        f(x, y) = call_counter(x, y);
        // When x was two smaller the second term was computed. When y was two smaller the third term was computed.
        g(x, y) = f(x+y, x-y) + f((x-2)+y, (x-2)-y) + f(x+(y-2), x-(y-2));
        f.store_root().compute_at(g, x);

        Image<int> im = g.realize(10, 10);
        if (count != 1500) {
            printf("f was called %d times instead of %d times\n", count, 1500);
            return -1;
        }
    }

    {
        // Now make sure Halide folds the example in Func.h down to a stack allocation
        Func f, g;
        f(x, y) = x*y;
        g(x, y) = f(x, y) + f(x+1, y) + f(x, y+1) + f(x+1, y+1);
        f.store_at(g, y).compute_at(g, x);
        g.set_custom_allocator(&my_malloc, &my_free);
        Image<int> im = g.realize(10, 10);
    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team (see Authors.txt)                                    *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
/*
 * CompositingVisualLoop.cpp
 *
 *  Created on: 16 janv. 2012
 *      Author: Jeremy Ringard
 */

//#define DEBUG_DRAW

#include <sofa/component/visualmodel/CompositingVisualLoop.h>
#include <sofa/core/ObjectFactory.h>
#include <sofa/component/visualmodel/VisualStyle.h>
#include <sofa/core/visual/DisplayFlags.h>
#include <sofa/simulation/common/VisualVisitor.h>
#include <sofa/simulation/common/UpdateContextVisitor.h>
#include <sofa/simulation/common/UpdateMappingVisitor.h>
#include <sofa/simulation/common/UpdateMappingEndEvent.h>
#include <sofa/simulation/common/PropagateEventVisitor.h>

#include <sofa/helper/AdvancedTimer.h>

namespace sofa
{
namespace component
{
namespace visualmodel
{

SOFA_DECL_CLASS(CompositingVisualLoop);

int CompositingVisualLoopClass = core::RegisterObject("Visual loop enabling multipass rendering. Needs multiple fbo data and a compositing shader")
        .add< CompositingVisualLoop >()
        ;

CompositingVisualLoop::CompositingVisualLoop(simulation::Node* _gnode)
    : simulation::DefaultVisualManagerLoop(_gnode),
      vertFilename(initData(&vertFilename, (std::string) "shaders/compositing.vert", "vertFilename", "Set the vertex shader filename to load")),
      fragFilename(initData(&fragFilename, (std::string) "shaders/compositing.frag", "fragFilename", "Set the fragment shader filename to load"))
{
    //assert(gRoot);
}

CompositingVisualLoop::~CompositingVisualLoop()
{}

void CompositingVisualLoop::initVisual()
{}

void CompositingVisualLoop::init()
{
    if (!gRoot)
        gRoot = dynamic_cast<simulation::Node*>(this->getContext());
}

//should not be called if scene file is well formed
void CompositingVisualLoop::defaultRendering(sofa::core::visual::VisualParams* vparams)
{
    vparams->pass() = sofa::core::visual::VisualParams::Std;
    VisualDrawVisitor act ( vparams );
    gRoot->execute ( &act );
    vparams->pass() = sofa::core::visual::VisualParams::Transparent;
    VisualDrawVisitor act2 ( vparams );
    gRoot->execute ( &act2 );
}

void CompositingVisualLoop::drawStep(sofa::core::visual::VisualParams* vparams)
{
    if ( !gRoot ) return;

    sofa::core::visual::tristate renderingState;
    //vparams->displayFlags().setShowRendering(false);
    component::visualmodel::VisualStyle::SPtr visualStyle = NULL;
    gRoot->get(visualStyle);
    const sofa::core::visual::DisplayFlags &backupFlags = vparams->displayFlags();
    const sofa::core::visual::DisplayFlags &currentFlags = visualStyle->displayFlags.getValue();
    vparams->displayFlags() = sofa::core::visual::merge_displayFlags(backupFlags, currentFlags);
    renderingState = vparams->displayFlags().getShowRendering();
    if (vparams->displayFlags().getShowRendering())
    {
        //std::cout << "Advanced Rendering is ON" << std::endl;
    }
    else
    {
        //std::cout << "Advanced Rendering is OFF" << std::endl;
        defaultRendering(vparams);
        return;
    }

    //should not happen: the compositing loop relies on one or more rendered passes done by the VisualManagerPass component
    if (gRoot->visualManager.empty())
    {
        serr << "CompositingVisualLoop: no VisualManagerPass found. Disable multipass rendering." << sendl;
        defaultRendering(vparams);
    }

    //rendering sequence: call each VisualManagerPass elements, then composite the frames
    else
    {
        if (renderingState == sofa::core::visual::tristate::false_value || renderingState == sofa::core::visual::tristate::neutral_value) return;

        Node::Sequence<core::visual::VisualManager>::iterator begin = gRoot->visualManager.begin(), end = gRoot->visualManager.end(), it;
        VisualManagerPass* currentVMP;
        bool stopLoop=false;
        //preDraw sequence
        it=begin;
        for (it = begin; it != end; ++it)
        {
            (*it)->preDrawScene(vparams);
            currentVMP=dynamic_cast<VisualManagerPass*>(*it);
            if( currentVMP!=NULL && !currentVMP->isPrerendered())
            {
#ifdef DEBUG_DRAW
                std::cout<<"final pass is "<<currentVMP->getName()<< "end of predraw loop" <<std::endl;
#endif
                break;
            }
        }
        //Draw sequence
        bool rendered = false; // true if a manager did the rendering
        for (it = begin; it != end; ++it)
            if ((*it)->drawScene(vparams))	{ rendered = true; 	break;	}

        if (!rendered) // do the rendering
        {
            std::cerr << "VisualLoop error: no visualManager rendered the scene. Please make sure the final visualManager(Secondary)Pass has a renderToScreen=\"true\" attribute" << std::endl;
        }
        //postDraw sequence
        Node::Sequence<core::visual::VisualManager>::reverse_iterator rbegin = gRoot->visualManager.rbegin(), rend = gRoot->visualManager.rend(), rit;
        for (rit = rbegin; rit != rend; ++rit)
            (*rit)->postDrawScene(vparams);
    }
}

} // namespace visualmodel
} // namespace component
} //sofa
<commit_msg>r12122/sofa-dev : debug messages deleted<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team (see Authors.txt)                                    *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
/*
 * CompositingVisualLoop.cpp
 *
 *  Created on: 16 janv. 2012
 *      Author: Jeremy Ringard
 */

//#define DEBUG_DRAW

#include <sofa/component/visualmodel/CompositingVisualLoop.h>
#include <sofa/core/ObjectFactory.h>
#include <sofa/component/visualmodel/VisualStyle.h>
#include <sofa/core/visual/DisplayFlags.h>
#include <sofa/simulation/common/VisualVisitor.h>
#include <sofa/simulation/common/UpdateContextVisitor.h>
#include <sofa/simulation/common/UpdateMappingVisitor.h>
#include <sofa/simulation/common/UpdateMappingEndEvent.h>
#include <sofa/simulation/common/PropagateEventVisitor.h>

#include <sofa/helper/AdvancedTimer.h>

namespace sofa
{
namespace component
{
namespace visualmodel
{

SOFA_DECL_CLASS(CompositingVisualLoop);

int CompositingVisualLoopClass = core::RegisterObject("Visual loop enabling multipass rendering. Needs multiple fbo data and a compositing shader")
        .add< CompositingVisualLoop >()
        ;

CompositingVisualLoop::CompositingVisualLoop(simulation::Node* _gnode)
    : simulation::DefaultVisualManagerLoop(_gnode),
      vertFilename(initData(&vertFilename, (std::string) "shaders/compositing.vert", "vertFilename", "Set the vertex shader filename to load")),
      fragFilename(initData(&fragFilename, (std::string) "shaders/compositing.frag", "fragFilename", "Set the fragment shader filename to load"))
{
    //assert(gRoot);
}

CompositingVisualLoop::~CompositingVisualLoop()
{}

void CompositingVisualLoop::initVisual()
{}

void CompositingVisualLoop::init()
{
    if (!gRoot)
        gRoot = dynamic_cast<simulation::Node*>(this->getContext());
}

//should not be called if scene file is well formed
void CompositingVisualLoop::defaultRendering(sofa::core::visual::VisualParams* vparams)
{
    vparams->pass() = sofa::core::visual::VisualParams::Std;
    VisualDrawVisitor act ( vparams );
    gRoot->execute ( &act );
    vparams->pass() = sofa::core::visual::VisualParams::Transparent;
    VisualDrawVisitor act2 ( vparams );
    gRoot->execute ( &act2 );
}

void CompositingVisualLoop::drawStep(sofa::core::visual::VisualParams* vparams)
{
    if ( !gRoot ) return;

    sofa::core::visual::tristate renderingState;
    //vparams->displayFlags().setShowRendering(false);
    component::visualmodel::VisualStyle::SPtr visualStyle = NULL;
    gRoot->get(visualStyle);
    const sofa::core::visual::DisplayFlags &backupFlags = vparams->displayFlags();
    const sofa::core::visual::DisplayFlags &currentFlags = visualStyle->displayFlags.getValue();
    vparams->displayFlags() = sofa::core::visual::merge_displayFlags(backupFlags, currentFlags);
    renderingState = vparams->displayFlags().getShowRendering();

    if (!(vparams->displayFlags().getShowRendering()))
    {
#ifdef DEBUG_DRAW
        std::cout << "Advanced Rendering is OFF" << std::endl;
#endif
        defaultRendering(vparams);
        return;
    }
#ifdef DEBUG_DRAW
    else
        std::cout << "Advanced Rendering is ON" << std::endl;
#endif

    //should not happen: the compositing loop relies on one or more rendered passes done by the VisualManagerPass component
    if (gRoot->visualManager.empty())
    {
        serr << "CompositingVisualLoop: no VisualManagerPass found. Disable multipass rendering." << sendl;
        defaultRendering(vparams);
    }

    //rendering sequence: call each VisualManagerPass elements, then composite the frames
    else
    {
        if (renderingState == sofa::core::visual::tristate::false_value || renderingState == sofa::core::visual::tristate::neutral_value) return;

        Node::Sequence<core::visual::VisualManager>::iterator begin = gRoot->visualManager.begin(), end = gRoot->visualManager.end(), it;
        VisualManagerPass* currentVMP;
        //preDraw sequence
        it=begin;
        for (it = begin; it != end; ++it)
        {
            (*it)->preDrawScene(vparams);
            currentVMP=dynamic_cast<VisualManagerPass*>(*it);
            if( currentVMP!=NULL && !currentVMP->isPrerendered())
            {
#ifdef DEBUG_DRAW
                std::cout<<"final pass is "<<currentVMP->getName()<< "end of predraw loop" <<std::endl;
#endif
                break;
            }
        }
        //Draw sequence
        bool rendered = false; // true if a manager did the rendering
        for (it = begin; it != end; ++it)
            if ((*it)->drawScene(vparams))	{ rendered = true; 	break;	}

        if (!rendered) // do the rendering
        {
            std::cerr << "VisualLoop error: no visualManager rendered the scene. Please make sure the final visualManager(Secondary)Pass has a renderToScreen=\"true\" attribute" << std::endl;
        }
        //postDraw sequence
        Node::Sequence<core::visual::VisualManager>::reverse_iterator rbegin = gRoot->visualManager.rbegin(), rend = gRoot->visualManager.rend(), rit;
        for (rit = rbegin; rit != rend; ++rit)
            (*rit)->postDrawScene(vparams);
    }
}

} // namespace visualmodel
} // namespace component
} //sofa
<|endoftext|>


<commit_before>#include <bits/stdc++.h>
using namespace std;

template<typename T>
vector<T> read_vector(int n, char const* cstr) {
	vector<T> A;
	A.reserve(n);
	for (int i = 0; i < n; i++) {
		int z;
		scanf(cstr, &z);
		A.push_back(z);
	}
	return A;
}

int main() {
	int N;
	scanf("%d", &N);

	vector<int> A = read_vector<int>(N, "%d");
	vector<string> adj_matrix;
	adj_matrix.reserve(N);
	for (int i = 0; i < N; i++) {
		string s;
		cin >> s;
		adj_matrix.push_back(s);
	}

//	for (int i = 0; i < N; i++) {
//		cout << adj_matrix[i] << " ";
//	}

	return 0;
}
<commit_msg>AC new year permutation<commit_after>#include <bits/stdc++.h>
using namespace std;

template<typename T>
vector<T> read_vector(int n, char const* cstr) {
	vector<T> A;
	A.reserve(n);
	for (int i = 0; i < n; i++) {
		T z;
		scanf(cstr, &z);
		A.push_back(z);
	}
	cin.ignore();
	return A;
}

//template<typename T>
//void print_vector(vector<vector<T>> const& vvt) {
//	for (vector<T> vt : vvt) {
//		for (T const& t : vt) {
//			cout << t << " ";
//		}
//		cout << endl;
//	}
//}

template<typename T>
void print_vector(vector<T> v) {
	for (int z = 0; z < v.size(); z++) {
		cout << v[z] << " ";
	}
	cout << endl;
}

void dfs(int i, vector<int> const& A, vector<vector<char> > const& adj_matrix, vector<int>& ans, vector<int>& visited) {
	vector<int> indices;
	stack<int> s;
	s.push(i);
	visited[i] = 1;
	while (!s.empty()) {
		int idx = s.top();
//		printf("popped %d\n", idx);
		s.pop();
		indices.push_back(idx);
//		print_vector(adj_matrix[idx]); cout << "--" << endl;
		for (int z = 0; z < adj_matrix[idx].size(); z++) {
			if (!visited[z] && adj_matrix[idx][z] == '1') {
				s.push(z);
				visited[z] = 1;
			}
		}
	}
//	print_vector(indices);
	sort(indices.begin(), indices.end());
	vector<int> numbers;
	numbers.reserve(indices.size());
	for (int z = 0; z < indices.size(); z++) {
		numbers.push_back(A[indices[z]]);
	}
	sort(numbers.begin(), numbers.end());
	for (int z = 0; z < indices.size(); z++) {
		ans[indices[z]] = numbers[z];
	}
}

void solve(int N, vector<int> const& A, vector<vector<char> > const& adj_matrix) {
	vector<int> visited(N);
	vector<int> ans(N);
	for (int i = 0; i < N; i++) {
		if (!visited[i]) {
			dfs(i, A, adj_matrix, ans, visited);
		}
	}
	for (int i = 0; i < N - 1; i++) {
		cout << ans[i] << " ";
	}
	cout << ans[N - 1] << endl;
}

int main() {
	int N;
	scanf("%d", &N);

	vector<int> A = read_vector<int>(N, "%d");
	vector<vector<char> > adj_matrix;
	adj_matrix.reserve(N);
	for (int i = 0; i < N; i++) {
		adj_matrix.push_back(read_vector<char>(N, "%c"));
	}
	solve(N, A, adj_matrix);

	return 0;
}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_TEST_MAIN_ENABLE_INFO_LOGGING
# define DUNE_STUFF_TEST_MAIN_ENABLE_INFO_LOGGING 1
#endif

#include <dune/stuff/test/main.hxx>

#ifdef HAVE_FASP
# define HAVE_FASP 0
#endif

#include "elliptic-testcases.hh"
#include "elliptic-swipdg-discretization.hh"

template< class TestCase >
struct EllipticSWIPDGDiscretization
  : public ::testing::Test
{
  void estimator_study() const
  {
    try {
      const TestCase test_case;
      test_case.print_header(DSC_LOG_INFO);
      DSC_LOG_INFO << std::endl;
      EllipticSWIPDG::EstimatorStudy< TestCase > estimator_study(test_case);
      Dune::Stuff::Test::check_eoc_study_for_success(estimator_study, estimator_study.run(DSC_LOG_INFO));
    } catch (Dune::Stuff::Exceptions::spe10_data_file_missing& ee) {
      std::cerr << ee.what() << std::endl;
    }
  } // ... estimator_study()
}; // struct EllipticSWIPDGDiscretization

#if HAVE_DUNE_FEM && HAVE_DUNE_PDELAB

TYPED_TEST_CASE(EllipticSWIPDGDiscretization, EllipticEstimatorTestCases);
TYPED_TEST(EllipticSWIPDGDiscretization, estimator_study) {
  this->estimator_study();
}

#else // HAVE_DUNE_FEM && HAVE_DUNE_PDELAB

TEST(DISABLED_EllipticSWIPDGDiscretization, estimator_study__missing_dune_fem_or_dune_pdelab) {}

#endif
<commit_msg>[test.elliptic-estimators] use less refinements on buildbots<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_TEST_MAIN_ENABLE_INFO_LOGGING
# define DUNE_STUFF_TEST_MAIN_ENABLE_INFO_LOGGING 1
#endif

#include <dune/stuff/test/main.hxx>

#ifdef HAVE_FASP
# define HAVE_FASP 0
#endif

#include "elliptic-testcases.hh"
#include "elliptic-swipdg-discretization.hh"

template< class TestCase >
struct EllipticSWIPDGDiscretization
  : public ::testing::Test
{
  void estimator_study() const
  {
    try {
#if THIS_IS_A_BUILDBOT_BUILD
      const TestCase test_case(1);
#else
      const TestCase test_case;
#endif
      test_case.print_header(DSC_LOG_INFO);
      DSC_LOG_INFO << std::endl;
      EllipticSWIPDG::EstimatorStudy< TestCase > estimator_study(test_case);
      Dune::Stuff::Test::check_eoc_study_for_success(estimator_study, estimator_study.run(DSC_LOG_INFO));
    } catch (Dune::Stuff::Exceptions::spe10_data_file_missing& ee) {
      std::cerr << ee.what() << std::endl;
    }
  } // ... estimator_study()
}; // struct EllipticSWIPDGDiscretization

#if HAVE_DUNE_FEM && HAVE_DUNE_PDELAB

TYPED_TEST_CASE(EllipticSWIPDGDiscretization, EllipticEstimatorTestCases);
TYPED_TEST(EllipticSWIPDGDiscretization, estimator_study) {
  this->estimator_study();
}

#else // HAVE_DUNE_FEM && HAVE_DUNE_PDELAB

TEST(DISABLED_EllipticSWIPDGDiscretization, estimator_study__missing_dune_fem_or_dune_pdelab) {}

#endif
<|endoftext|>


<commit_before>#include "Sketch.h"

#include "gl/draw/Texture.h"

using namespace std;
using namespace chr;
using namespace gl;

void Sketch::setup()
{
  initTextures();

  // ---

  textureBatches[0].setShader(textureShader);
  textureBatches[0].setShaderColor(1, 1, 1, 1);
  textureBatches[0].setTexture(textures[0]);

  textureBatches[1].setShader(textureAlphaShader);
  textureBatches[1].setShaderColor(1, 0.5f, 0, 1);
  textureBatches[1].setTexture(textures[1]);

  textureBatches[2].setShader(textureShader);
  textureBatches[2].setShaderColor(1, 1, 1, 1);
  textureBatches[2].setTexture(textures[2]);

  Matrix matrix;

  matrix.push();
  matrix.scale(0.333f);
  draw::Texture<>(textureBatches[0]).fillFromCenter(matrix);
  matrix.pop();

  matrix.translate(0, 0, 10);
  draw::Texture<>(textureBatches[1]).fillInRect(matrix, math::Rectf(-200, -150, 400, 300));

  matrix.translate(0, 0, 10);
  matrix.scale(0.5f);
  draw::Texture<>(textureBatches[2]).fillFromCenter(matrix, 100, 100);

  // ---

  glDisable(GL_DEPTH_TEST);
  glDepthMask(GL_FALSE);

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void Sketch::draw()
{
  glClearColor(0, 0, 1, 1);
  glClear(GL_COLOR_BUFFER_BIT);

  // ---

  glm::mat4 projectionMatrix = glm::perspective(60 * D2R, windowInfo.size.x / windowInfo.size.y, 0.1f, 1000.0f);

  glm::mat4 modelViewMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(1, -1, 1)); // SCALE
  modelViewMatrix = glm::translate(modelViewMatrix, glm::vec3(0, 0, -300)); // DISTANCE
  modelViewMatrix = glm::rotate(modelViewMatrix, 15 * D2R, glm::vec3(1, 0, 0)); // ELEVATION
  modelViewMatrix = glm::rotate(modelViewMatrix, (float) getElapsedSeconds(), glm::vec3(0, 1, 0)); // AZIMUTH

  glm::mat4 mvpMatrix = projectionMatrix * modelViewMatrix;

  // ---

  textureBatches[0].setShaderMatrix(mvpMatrix);
  textureBatches[1].setShaderMatrix(mvpMatrix);
  textureBatches[2].setShaderMatrix(mvpMatrix);

  textureBatches[0].flush();
  textureBatches[1].flush();
  textureBatches[2].flush();
}

void Sketch::initTextures()
{
  textures[0] = Texture(Texture::MaskedRequest("6980491_UN1_800.jpg", "6980491_UN1_800_MASK.png").setFlags(image::FLAGS_RBGA | image::FLAGS_POT, image::FLAGS_TRANSLUCENT));
  textures[1] = Texture(Texture::Request("camo.jpg").setFlags(image::FLAGS_TRANSLUCENT).setMipmap(true).setWrap(GL_REPEAT, GL_REPEAT));
  textures[2] = Texture(Texture::Request("banski.jpg"));

  // ---

  #if defined(CHR_PLATFORM_EMSCRIPTEN)
    emscripten_webgl_enable_extension(emscripten_webgl_get_current_context(), "EXT_texture_filter_anisotropic");
    emscripten_webgl_enable_extension(emscripten_webgl_get_current_context(), "WEBKIT_EXT_texture_filter_anisotropic");
  #endif

  GLfloat maxAnisotropy;
  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
}
<commit_msg>ADAPTING SKETCHES...<commit_after>#include "Sketch.h"

#include "gl/draw/Texture.h"

using namespace std;
using namespace chr;
using namespace gl;

void Sketch::setup()
{
  initTextures();

  // ---

  textureBatches[0].setShader(textureShader);
  textureBatches[0].setShaderColor(1, 1, 1, 1);
  textureBatches[0].setTexture(textures[0]);

  textureBatches[1].setShader(textureAlphaShader);
  textureBatches[1].setShaderColor(1, 0.5f, 0, 1);
  textureBatches[1].setTexture(textures[1]);

  textureBatches[2].setShader(textureShader);
  textureBatches[2].setShaderColor(1, 1, 1, 1);
  textureBatches[2].setTexture(textures[2]);

  Matrix matrix;

  matrix.push();
  matrix.scale(0.333f);
  draw::Texture<>(textureBatches[0]).fillFromCenter(matrix, 0, 0);
  matrix.pop();

  matrix.translate(0, 0, 10);
  draw::Texture<>(textureBatches[1]).fillInRect(matrix, math::Rectf(-200, -150, 400, 300));

  matrix.translate(0, 0, 10);
  matrix.scale(0.5f);
  draw::Texture<>(textureBatches[2]).fillFromCenter(matrix, 100, 100);

  // ---

  glDisable(GL_DEPTH_TEST);
  glDepthMask(GL_FALSE);

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void Sketch::draw()
{
  glClearColor(0, 0, 1, 1);
  glClear(GL_COLOR_BUFFER_BIT);

  // ---

  glm::mat4 projectionMatrix = glm::perspective(60 * D2R, windowInfo.size.x / windowInfo.size.y, 0.1f, 1000.0f);

  glm::mat4 modelViewMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(1, -1, 1)); // SCALE
  modelViewMatrix = glm::translate(modelViewMatrix, glm::vec3(0, 0, -300)); // DISTANCE
  modelViewMatrix = glm::rotate(modelViewMatrix, 15 * D2R, glm::vec3(1, 0, 0)); // ELEVATION
  modelViewMatrix = glm::rotate(modelViewMatrix, (float) getElapsedSeconds(), glm::vec3(0, 1, 0)); // AZIMUTH

  glm::mat4 mvpMatrix = projectionMatrix * modelViewMatrix;

  // ---

  textureBatches[0].setShaderMatrix(mvpMatrix);
  textureBatches[1].setShaderMatrix(mvpMatrix);
  textureBatches[2].setShaderMatrix(mvpMatrix);

  textureBatches[0].flush();
  textureBatches[1].flush();
  textureBatches[2].flush();
}

void Sketch::initTextures()
{
  textures[0] = Texture(Texture::MaskedRequest("6980491_UN1_800.jpg", "6980491_UN1_800_MASK.png").setFlags(image::FLAGS_RBGA | image::FLAGS_POT, image::FLAGS_TRANSLUCENT));
  textures[1] = Texture(Texture::Request("camo.jpg").setFlags(image::FLAGS_TRANSLUCENT).setMipmap(true).setWrap(GL_REPEAT, GL_REPEAT));
  textures[2] = Texture(Texture::Request("banski.jpg"));

  // ---

  #if defined(CHR_PLATFORM_EMSCRIPTEN)
    emscripten_webgl_enable_extension(emscripten_webgl_get_current_context(), "EXT_texture_filter_anisotropic");
    emscripten_webgl_enable_extension(emscripten_webgl_get_current_context(), "WEBKIT_EXT_texture_filter_anisotropic");
  #endif

  GLfloat maxAnisotropy;
  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
}
<|endoftext|>