<commit_before>#include <QDebug>
#include <iostream>
#include "block.h"
#include "cornerblock.h"
#include "player.h"
#include "dice.h"

using namespace std;

CornerBlock::CornerBlock(QGameItem * parent,CornerType::Type type)
    : Block(parent)
{
    block_type = type;
}

CornerBlock::~CornerBlock()
{
}

// Methods
void CornerBlock::enter(Player* player)
{
    inCornerBlock(player);
}

void CornerBlock::inCornerBlock(Player* player)
{
    using namespace CornerType;

    switch(block_type)
    {
    case DORM : inDormitory(player);
        break;
    case CALLTAXI : in61Call(player);
        break;
    case BREAKSEM : inBreakSemester(player);
        break;
    case PLURAL : inPluralMajor(player);
        break;
    default : qDebug() << "CornerBlock error!" << endl;
        break;
    }
}

void CornerBlock::inDormitory(Player* player)
{
    using namespace CharacterType;

    int takingenergy;
    switch(player->getType())
    {
    case LOL : takingenergy = 100; //주는 에너지 수치는 상학선배&주현이가 채워주세요 ㅎㅎ
        break;

    case GENIUS : takingenergy = 100;
        break;

    case HARD_WORKER : takingenergy = 150;
        break;

    case OUTSIDER : takingenergy = 100;
        break;

    case ALCOHOLIC : takingenergy = 100;
        break;

    default         : takingenergy = 100;

    }

    player->setEnergy(player->getEnergy() + takingenergy);

}

void CornerBlock::in61Call(Player* player) {        //원하는 블럭을 선택할 수 있게 함

    qDebug() <<"You can choose any block."<< endl;
    qDebug() <<">>";
    int blocknum;//0~35까지의 숫자로 block 번호 관리... 이렇게 안하면 board 어레이로 올라가야하는데.. 뭐 할라면 할순잇겟지..
    cin >> blocknum; //ui는 블럭을 클릭 할 수 있도록, 우리는 클릭받은 블럭의 입력받아서 여기에 cin대신에 넣을 수 있어야겠지.. clicked()이용해야할듯 ㅎ
    qDebug() <<" "<<endl;
    player->walkBy(blocknum);//moveTo에서 포인터가지고 어찌어찌해서 옮겨줘야될꺼같은데!!

    /*moveTo 를 숫자로 넣을수 있도록 해야할듯!! 현재 있는 칸도 번호 저장해둬서 주사위 돌렸을 때 현재 숫자+주사위 눈 으로 이동하든지
    이런 경우에 바로 숫자 입력해서 이동할 수 있도록 하든지*/
    //--------->ok!

}
void CornerBlock::inBreakSemester(Player* player) {     //무인도

    if(player->getPenalty()==0)//다른 블럭에서 들어왔을 경우
    {
        qDebug()<<"You have to break the 3 semesters in this block."<<endl;
        player->setMouindo(3);
    }
    else//원래 이 블럭에 있었을 경우.. 근데 enter라는 함수로 해결이 되는가?
    {

        qDebug()<<"You can escape the mouindo if you pay energy or get a double dice"<<endl;
        qDebug()<<"1. pay energy    2. roll a dice"<<endl;//나중에 애니메이션 넣어서 바꿀 부분
        qDebug()<<">>";
        int userselect;
        cin>>userselect;
        if(userselect==1)
        {
            player->payEnergy(200);

            while(player->getPenalty() >=0)//panelty 없애주고
            {
                player->escapeMouindo();
            }
            qDebug()<<"Rolling a dice to go another block."<<endl;
            Dice::getInst()->roll();
            player->walkBy(Dice::getInst()->getValue());

        }
        else if(userselect==2)
        {
            Dice::getInst()->roll();
            if(Dice::getInst()->isDouble())
            {
                while(player->getPenalty() >=0)
                {
                    player->escapeMouindo();
                }
                qDebug()<<"Rolling a dice to go another block."<<endl;
                Dice::getInst()->roll();
                player->walkBy(Dice::getInst()->getValue());

            }
            else//not double
            {
                player->escapeMouindo();//(panelty 1개 감소)
            }

        }
        else
            qDebug()<<"wrong input"<<endl;

    }
    //아... 무인도에 갇힌 횟수 !!!!***********구현해야즤

    //1.원래 무인도에 있다가 다시 턴이 된 경우 -> 주사위를 굴릴 수 있게 한다.
    //2.다른 칸에 있다가 갑자기 무인도에 온 경우->바로 쉬게 한다.
    //3.휴식 횟수 새는 기능.

}

void CornerBlock::inPluralMajor(Player* player) {//복수전공

    qDebug()<<"You have to take two major for graduation."<<endl;
    qDebug()<<"Plural major check..."<<endl;
    Dice::getInst()->roll();

    int checkplural = Dice::getInst()->getValue();      //1=plural 2,3,4,5,6=normal
    switch(checkplural)
    {
    case 1 : qDebug() <<"You have to take plural major."<<endl;
        player->setPlural(true);
        break;
    default : qDebug()<<"You don't have to take plural major."<<endl;

    }//학과 1개 독점 시에 복수전공 해제& 두개 독점 시에 승리 그리고 만약에 한개 독점 하고 두개째 도전중일 때다른 누군가가 독점된 학과를 뺏어가는 경우!?
}
<commit_msg>61call changed(p=1/6)<commit_after>#include <QDebug>
#include <iostream>
#include "block.h"
#include "cornerblock.h"
#include "player.h"
#include "dice.h"

using namespace std;

CornerBlock::CornerBlock(QGameItem * parent,CornerType::Type type)
    : Block(parent)
{
    block_type = type;
}

CornerBlock::~CornerBlock()
{
}

// Methods
void CornerBlock::enter(Player* player)
{
    inCornerBlock(player);
}

void CornerBlock::inCornerBlock(Player* player)
{
    using namespace CornerType;

    switch(block_type)
    {
    case DORM : inDormitory(player);
        break;
    case CALLTAXI : in61Call(player);
        break;
    case BREAKSEM : inBreakSemester(player);
        break;
    case PLURAL : inPluralMajor(player);
        break;
    default : qDebug() << "CornerBlock error!" << endl;
        break;
    }
}

void CornerBlock::inDormitory(Player* player)
{
    using namespace CharacterType;

    int takingenergy;
    switch(player->getType())
    {
    case LOL : takingenergy = 100; //주는 에너지 수치는 상학선배&주현이가 채워주세요 ㅎㅎ
        break;

    case GENIUS : takingenergy = 100;
        break;

    case HARD_WORKER : takingenergy = 150;
        break;

    case OUTSIDER : takingenergy = 100;
        break;

    case ALCOHOLIC : takingenergy = 100;
        break;

    default         : takingenergy = 100;

    }

    player->setEnergy(player->getEnergy() + takingenergy);

}

void CornerBlock::in61Call(Player* player) {        //원하는 블럭을 선택할 수 있게 함
    int value=rand()%6;
    if(value==0)
    {
        qDebug() <<"You can choose any block."<< endl;
        qDebug() <<">>";
        int blocknum;//0~35까지의 숫자로 block 번호 관리... 이렇게 안하면 board 어레이로 올라가야하는데.. 뭐 할라면 할순잇겟지..
        cin >> blocknum; //ui는 블럭을 클릭 할 수 있도록, 우리는 클릭받은 블럭의 입력받아서 여기에 cin대신에 넣을 수 있어야겠지.. clicked()이용해야할듯 ㅎ
        qDebug() <<" "<<endl;
        player->walkBy(blocknum);//moveTo에서 포인터가지고 어찌어찌해서 옮겨줘야될꺼같은데!!
    }
    /*moveTo 를 숫자로 넣을수 있도록 해야할듯!! 현재 있는 칸도 번호 저장해둬서 주사위 돌렸을 때 현재 숫자+주사위 눈 으로 이동하든지
    이런 경우에 바로 숫자 입력해서 이동할 수 있도록 하든지*/
    //--------->ok!
    else
    {
        qDebug() <<"You failed to take 61 call taxi."<<endl;
    }

}
void CornerBlock::inBreakSemester(Player* player) {     //무인도

    if(player->getPenalty()==0)//다른 블럭에서 들어왔을 경우
    {
        qDebug()<<"You have to break the 3 semesters in this block."<<endl;
        player->setMouindo(3);
    }
    else//원래 이 블럭에 있었을 경우.. 근데 enter라는 함수로 해결이 되는가?
    {

        qDebug()<<"You can escape the mouindo if you pay energy or get a double dice"<<endl;
        qDebug()<<"1. pay energy    2. roll a dice"<<endl;//나중에 애니메이션 넣어서 바꿀 부분
        qDebug()<<">>";
        int userselect;
        cin>>userselect;
        if(userselect==1)
        {
            player->payEnergy(200);

            while(player->getPenalty() >=0)//panelty 없애주고
            {
                player->escapeMouindo();
            }
            qDebug()<<"Rolling a dice to go another block."<<endl;
            Dice::getInst()->roll();
            player->walkBy(Dice::getInst()->getValue());

        }
        else if(userselect==2)
        {
            Dice::getInst()->roll();
            if(Dice::getInst()->isDouble())
            {
                while(player->getPenalty() >=0)
                {
                    player->escapeMouindo();
                }
                qDebug()<<"Rolling a dice to go another block."<<endl;
                Dice::getInst()->roll();
                player->walkBy(Dice::getInst()->getValue());

            }
            else//not double
            {
                player->escapeMouindo();//(panelty 1개 감소)
            }

        }
        else
            qDebug()<<"wrong input"<<endl;

    }
    //아... 무인도에 갇힌 횟수 !!!!***********구현해야즤

    //1.원래 무인도에 있다가 다시 턴이 된 경우 -> 주사위를 굴릴 수 있게 한다.
    //2.다른 칸에 있다가 갑자기 무인도에 온 경우->바로 쉬게 한다.
    //3.휴식 횟수 새는 기능.

}

void CornerBlock::inPluralMajor(Player* player) {//복수전공

    qDebug()<<"You have to take two major for graduation."<<endl;
    qDebug()<<"Plural major check..."<<endl;
    Dice::getInst()->roll();

    int checkplural = Dice::getInst()->getValue();      //1=plural 2,3,4,5,6=normal
    switch(checkplural)
    {
    case 1 : qDebug() <<"You have to take plural major."<<endl;
        player->setPlural(true);
        break;
    default : qDebug()<<"You don't have to take plural major."<<endl;

    }//학과 1개 독점 시에 복수전공 해제& 두개 독점 시에 승리 그리고 만약에 한개 독점 하고 두개째 도전중일 때다른 누군가가 독점된 학과를 뺏어가는 경우!?
}
<|endoftext|>


<commit_before>/**
 * @file fixed_planner.cpp
 *
 * definition of the FixedPlanner class.
 *
 * @author Adrien Perkins <adrienp@stanford.edu>
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <cmath>
#include <vector>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>

#include "fixed_planner.h"

using namespace std;

FixedPlanner::FixedPlanner(const char * command_file_name) : Planner(),
_command_file_name(command_file_name),
_num_cmds(0),
_cmd_index(0)
{
	_cmd_north.clear();
	_cmd_east.clear();
	_cmd_alt.clear();
}

FixedPlanner::~FixedPlanner() {

}

bool FixedPlanner::initialize() {

	// load up all the commands from the file
	string file_name(_command_file_name);
	ifstream cmd_file (file_name);

	if (!cmd_file.is_open()) {
		// means there is an error in loading the file
		return false;
	}

	// make sure vectors are clean
	_cmd_north.clear();
	_cmd_east.clear();
	_cmd_yaw.clear();
	_cmd_alt.clear();

	float cmdN;
	float cmdE;
	float cmdY;
	float cmdA;
	char comma;
	while (cmd_file >> cmdN >> comma >> cmdE >> comma >> cmdY >> comma >> cmdA) {
		_cmd_north.push_back(cmdN);
		_cmd_east.push_back(cmdE);
		_cmd_yaw.push_back(cmdY);
		_cmd_alt.push_back(cmdA);

		printf("[FIXED PLANNER] North command: %f\n", cmdN);
		printf("[FIXED PLANNER] East cmd: %f\n", cmdE);
		printf("[FIXED PLANNER] Alt cmd: %f\n", cmdA);
	}

	_num_cmds = _cmd_north.size();
	printf("[FIXED PLANNER] num commands read: %d\n", _num_cmds);

	return true;
}

vector<float> FixedPlanner::action() {

	// cycle the cmds (ids should go from 0 -> 3)
	if (_cmd_index >= _num_cmds) {
		_cmd_index = 0;
	}

	printf("[FIXED PLANNER] sending move command with index: %d\n", _cmd_index);

	// extract the next north and east commands
	float nextNorth = _cmd_north[_cmd_index];
	float nextEast = _cmd_east[_cmd_index];
	float nextYaw = _cmd_yaw[_cmd_index];
	float nextAlt = _cmd_alt[_cmd_index];

	printf("[FIXED PLANNER] sending command %i: N %f\tE %f\tY %f\tA %f\n", _cmd_index, nextNorth, nextEast, nextYaw, nextAlt);

	_cmd_index++;

	vector<float> next_command;
	next_command.clear();
	next_command.push_back(nextNorth);
	next_command.push_back(nextEast);
	next_command.push_back(nextYaw);
	next_command.push_back(nextAlt);

	// return the next command to be used
	return next_command;
}
<commit_msg>add a few more print statements<commit_after>/**
 * @file fixed_planner.cpp
 *
 * definition of the FixedPlanner class.
 *
 * @author Adrien Perkins <adrienp@stanford.edu>
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <cmath>
#include <vector>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>

#include "fixed_planner.h"

using namespace std;

FixedPlanner::FixedPlanner(const char * command_file_name) : Planner(),
_command_file_name(command_file_name),
_num_cmds(0),
_cmd_index(0)
{
	_cmd_north.clear();
	_cmd_east.clear();
	_cmd_yaw.clear();
	_cmd_alt.clear();
}

FixedPlanner::~FixedPlanner() {

}

bool FixedPlanner::initialize() {

	// load up all the commands from the file
	string file_name(_command_file_name);
	ifstream cmd_file (file_name);

	if (!cmd_file.is_open()) {
		// means there is an error in loading the file
		return false;
	}

	// make sure vectors are clean
	_cmd_north.clear();
	_cmd_east.clear();
	_cmd_yaw.clear();
	_cmd_alt.clear();

	float cmdN;
	float cmdE;
	float cmdY;
	float cmdA;
	char comma;
	while (cmd_file >> cmdN >> comma >> cmdE >> comma >> cmdY >> comma >> cmdA) {
		_cmd_north.push_back(cmdN);
		_cmd_east.push_back(cmdE);
		_cmd_yaw.push_back(cmdY);
		_cmd_alt.push_back(cmdA);

		printf("[FIXED PLANNER] North command: %f\n", cmdN);
		printf("[FIXED PLANNER] East cmd: %f\n", cmdE);
		printf("[FIXED PLANNER] Yaw cmd: %f\n", cmdY);
		printf("[FIXED PLANNER] Alt cmd: %f\n", cmdA);
	}

	_num_cmds = _cmd_north.size();
	printf("[FIXED PLANNER] num commands read: %d\n", _num_cmds);

	return true;
}

vector<float> FixedPlanner::action() {

	// cycle the cmds (ids should go from 0 -> 3)
	if (_cmd_index >= _num_cmds) {
		_cmd_index = 0;
	}

	printf("[FIXED PLANNER] sending move command with index: %d\n", _cmd_index);

	// extract the next north and east commands
	float nextNorth = _cmd_north[_cmd_index];
	float nextEast = _cmd_east[_cmd_index];
	float nextYaw = _cmd_yaw[_cmd_index];
	float nextAlt = _cmd_alt[_cmd_index];

	printf("[FIXED PLANNER] sending command %i: N %f\tE %f\tY %f\tA %f\n", _cmd_index, nextNorth, nextEast, nextYaw, nextAlt);

	_cmd_index++;

	vector<float> next_command;
	next_command.clear();
	next_command.push_back(nextNorth);
	next_command.push_back(nextEast);
	next_command.push_back(nextYaw);
	next_command.push_back(nextAlt);

	// return the next command to be used
	return next_command;
}
<|endoftext|>


<commit_before>/*
 *            Copyright 2009-2020 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// Local VOTCA includes
#include "votca/xtp/openmp_cuda.h"

namespace votca {
namespace xtp {

OpenMP_CUDA::OpenMP_CUDA() {

  inside_Parallel_region_ = OPENMP::InsideActiveParallelRegion();
  threadID_parent_ = OPENMP::getThreadId();

  cpu_intermediate_input_.resize(getNumberThreads());
  cpu_temporaries_.resize(getNumberThreads());
#ifdef USE_CUDA
  Index no_gpus = count_available_gpus();
  gpus_.clear();
  if (inside_Parallel_region_) {
    if (threadID_parent_ < no_gpus) {
      gpus_.push_back(GPU_data(threadID_parent_));
    }
  } else {
    for (Index i = 0; i < no_gpus; i++) {
      gpus_.push_back(GPU_data(i));
    }
  }
#endif
}

#ifdef USE_CUDA
void OpenMP_CUDA::setOperators(const std::vector<Eigen::MatrixXd>& tensor,
                               const Eigen::MatrixXd& rightoperator) {
  rightoperator_ = &rightoperator;
#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    const Eigen::MatrixXd& head = tensor.front();
    gpu.push_back(head.rows(), head.cols());
    gpu.push_back(rightoperator);
    gpu.push_back(head.rows(), rightoperator.cols());
  }
}
#else
void OpenMP_CUDA::setOperators(const std::vector<Eigen::MatrixXd>&,
                               const Eigen::MatrixXd& rightoperator) {
  rightoperator_ = &rightoperator;
}
#endif

#ifdef USE_CUDA

bool OpenMP_CUDA::isInVector(Index Id, const std::vector<GPU_data>& vec) {
  return (std::find_if(vec.begin(), vec.end(), [&Id](const GPU_data& d) {
            return d.Id == Id;
          }) != vec.end());
}
bool OpenMP_CUDA::isGPUthread(Index ParentThreadId) const {
  return isInVector(ParentThreadId, gpus_);
}
#endif

Index OpenMP_CUDA::getParentThreadId() const {
  return inside_Parallel_region_ ? threadID_parent_ : OPENMP::getThreadId();
}
Index OpenMP_CUDA::getLocalThreadId(Index ParentThreadId) const {
  return inside_Parallel_region_ ? 0 : ParentThreadId;
}
Index OpenMP_CUDA::getNumberThreads() const {
  return inside_Parallel_region_ ? 1 : OPENMP::getMaxThreads();
}

/*
 * The Cuda device behaves like a server that is receiving matrix-matrix
 * multiplications from a single stream (an Nvidia queue) and handle them
 * in an asynchronous way. It performs the following operations when recieving
 * a request:
 *  1. Check that there is enough space for the arrays
 *  2. Allocate memory for each matrix
 *  3. Copy the matrix to the allocated space
 *  4. Perform the matrix multiplication
 *  5. Return the result matrix
 * The Cuda device knows to which memory address it needs to copy back the
 * result. see: https://docs.nvidia.com/cuda/cublas/index.html#thread-safety2
 */
void OpenMP_CUDA::MultiplyRight(Eigen::MatrixXd& tensor) {

  // All the GPU communication happens through a single thread that reuses
  // all memory allocated in the GPU and it's dynamically load-balanced by
  // OpenMP. The rest of the threads use the default CPU matrix
  // multiplication
#ifdef USE_CUDA
  Index threadid = getParentThreadId();
  if (isGPUthread(threadid)) {
    GPU_data& gpu = gpus_[getLocalThreadId(threadid)];
    gpu.activateGPU();
    gpu.Mat(0).copy_to_gpu(tensor);
    gpu.pipe().gemm(gpu.Mat(0), gpu.Mat(1), gpu.Mat(2));
    tensor = gpu.Mat(2);
  } else {
    tensor *= *rightoperator_;
  }
#else
  tensor *= *rightoperator_;
#endif
  return;
}

void OpenMP_CUDA::setOperators(const Eigen::MatrixXd& leftoperator,
                               const Eigen::MatrixXd& rightoperator) {
  rightoperator_ = &rightoperator;
  leftoperator_ = &leftoperator;
#ifdef USE_CUDA
#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    gpu.push_back(leftoperator);
    gpu.push_back(leftoperator.cols(), rightoperator.rows());
    gpu.push_back(leftoperator.rows(), rightoperator.rows());
    gpu.push_back(rightoperator);
    gpu.push_back(leftoperator.rows(), rightoperator.cols());
  }
#endif
}

void OpenMP_CUDA::MultiplyLeftRight(Eigen::MatrixXd& matrix) {
#ifdef USE_CUDA
  Index threadid = getParentThreadId();
  if (isGPUthread(threadid)) {
    GPU_data& gpu = gpus_[getLocalThreadId(threadid)];
    gpu.activateGPU();
    gpu.Mat(1).copy_to_gpu(matrix);
    gpu.pipe().gemm(gpu.Mat(0), gpu.Mat(1), gpu.Mat(2));
    gpu.pipe().gemm(gpu.Mat(2), gpu.Mat(3), gpu.Mat(4));
    matrix = gpu.Mat(4);
  } else {
    matrix = (*leftoperator_) * matrix * (*rightoperator_);
  }
#else
  matrix = (*leftoperator_) * matrix * (*rightoperator_);
#endif
  return;
}
#ifdef USE_CUDA
void OpenMP_CUDA::createTemporaries(Index rows, Index cols) {
  reduction_ = std::vector<Eigen::MatrixXd>(getNumberThreads(),
                                            Eigen::MatrixXd::Zero(cols, cols));

#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    gpu.push_back(rows, 1);
    gpu.push_back(rows, cols);
    gpu.push_back(rows, cols);
    gpu.push_back(reduction_[i]);
  }
}
#else
void OpenMP_CUDA::createTemporaries(Index, Index cols) {
  reduction_ = std::vector<Eigen::MatrixXd>(getNumberThreads(),
                                            Eigen::MatrixXd::Zero(cols, cols));
}

#endif

void OpenMP_CUDA::PushMatrix(Eigen::MatrixXd& matrix) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(1).copy_to_gpu(matrix);
  } else {
    cpu_intermediate_input_[threadid] = &matrix;
  }
#else
  cpu_intermediate_input_[threadid] = &matrix;
#endif
}

void OpenMP_CUDA::A_TDA(const Eigen::VectorXd& vec) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(0).copy_to_gpu(vec);
    gpu.pipe().diag_gemm(gpu.Mat(1), gpu.Mat(0), gpu.Mat(2));
    gpu.pipe().gemm(gpu.Mat(1).transpose(), gpu.Mat(2), gpu.Mat(3), 1.0);
  } else {
    reduction_[threadid] += cpu_intermediate_input_[threadid]->transpose() *
                            vec.asDiagonal() *
                            (*cpu_intermediate_input_[threadid]);
  }
#else
  reduction_[threadid] += cpu_intermediate_input_[threadid]->transpose() *
                          vec.asDiagonal() *
                          (*cpu_intermediate_input_[threadid]);
#endif
}

#ifdef USE_CUDA
void OpenMP_CUDA::createTemporaries(const Eigen::VectorXd& vec,
                                    const Eigen::MatrixXd& input, Index rows1,
                                    Index rows2, Index cols) {
  reduction_ = std::vector<Eigen::MatrixXd>(
      getNumberThreads(), Eigen::MatrixXd::Zero(input.rows(), input.cols()));
  temp_ = std::vector<Eigen::RowVectorXd>(
      getNumberThreads(), Eigen::RowVectorXd::Zero(input.cols()));
  rightoperator_ = &input;
  vec_ = &vec;

#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    gpu.push_back(vec);
    gpu.push_back(input);
    gpu.push_back(rows1, cols);
    gpu.push_back(rows2, cols);
    gpu.push_back(rows1 * rows2, 1);
    gpu.push_back(rows1 * rows2, 1);
    gpu.push_back(reduction_[i]);
  }
}

#else
void OpenMP_CUDA::createTemporaries(const Eigen::VectorXd& vec,
                                    const Eigen::MatrixXd& input, Index, Index,
                                    Index) {
  reduction_ = std::vector<Eigen::MatrixXd>(
      getNumberThreads(), Eigen::MatrixXd::Zero(input.rows(), input.cols()));
  temp_ = std::vector<Eigen::VectorXd>(
      getNumberThreads(), Eigen::VectorXd::Zero(input.rows()));
  rightoperator_ = &input;
  vec_ = &vec;
}
#endif

void OpenMP_CUDA::PrepareMatrix1(Eigen::MatrixXd& mat) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(2).copy_to_gpu(mat);
    gpu.pipe().diag_gemm(gpu.Mat(2), gpu.Mat(0), gpu.Mat(2));
  } else {
    cpu_intermediate_input_[threadid] = &mat;
    mat *= vec_->asDiagonal();
  }
#else
  cpu_intermediate_input_[threadid] = &mat;
  mat *= vec_->asDiagonal();
#endif
}

void OpenMP_CUDA::SetTempZero() {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(4).setZero();
  } else {
    temp_[threadid].setZero();
  }
#else
  temp_[threadid].setZero();
#endif
}

void OpenMP_CUDA::PrepareMatrix2(const Eigen::MatrixXd& mat, bool Hd2) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(3).copy_to_gpu(mat);
    if (Hd2) {
      gpu.Mat(4).reshape(gpu.Mat(3).rows(), gpu.Mat(2).rows());
      gpu.pipe().gemm(gpu.Mat(3), gpu.Mat(2).transpose(), gpu.Mat(4), 1.0);
    } else {
      gpu.Mat(4).reshape(gpu.Mat(2).rows(), gpu.Mat(3).rows());
      gpu.pipe().gemm(gpu.Mat(2), gpu.Mat(3).transpose(), gpu.Mat(4), 1.0);
    }
    gpu.Mat(4).reshape(gpu.Mat(2).rows() * gpu.Mat(3).rows(), 1);
  } else {

    if (Hd2) {
      Eigen::Map<Eigen::MatrixXd> row(
          temp_[threadid].data(), mat.rows(),
          cpu_intermediate_input_[threadid]->rows());
      row += mat * cpu_intermediate_input_[threadid]->transpose();
    } else {
      Eigen::Map<Eigen::MatrixXd> row(temp_[threadid].data(),
                                      cpu_intermediate_input_[threadid]->rows(),
                                      mat.rows());
      row += *cpu_intermediate_input_[threadid] * mat.transpose();
    }
  }
#else
  if (Hd2) {
    Eigen::Map<Eigen::MatrixXd> row(temp_[threadid].data(), mat.rows(),
                                    cpu_intermediate_input_[threadid]->rows());
    row += mat * cpu_intermediate_input_[threadid]->transpose();
  } else {
    Eigen::Map<Eigen::MatrixXd> row(temp_[threadid].data(),
                                    cpu_intermediate_input_[threadid]->rows(),
                                    mat.rows());
    row += *cpu_intermediate_input_[threadid] * mat.transpose();
  }
#endif
}

void OpenMP_CUDA::Addvec(const Eigen::VectorXd& row) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(5).copy_to_gpu(row);
    gpu.pipe().axpy(gpu.Mat(5), gpu.Mat(4), 1.0);
  } else {
    temp_[threadid] += row;
  }
#else
  temp_[threadid] += row;
#endif
}

void OpenMP_CUDA::MultiplyRow(Index row) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.pipe().gemm(gpu.Mat(5).transpose(), gpu.Mat(1),
                    gpu.Mat(6).block(row, 0, 1, gpu.Mat(1).cols()), 0.0);
  } else {
    reduction_[threadid].row(row) = temp_[threadid].transpose() * (*rightoperator_);
  }
#else
  reduction_[threadid].row(row) = temp_[threadid].transpose() * (*rightoperator_);
#endif
}

Eigen::MatrixXd OpenMP_CUDA::getReductionVar() {
#ifdef USE_CUDA
#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    reduction_[i] = *(gpu.temp.back());
  }
#endif
  for (Index i = 1; i < Index(reduction_.size()); i++) {
    reduction_[0] += reduction_[i];
  }
  return reduction_[0];
}

}  // namespace xtp
}  // namespace votca
<commit_msg>two more<commit_after>/*
 *            Copyright 2009-2020 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// Local VOTCA includes
#include "votca/xtp/openmp_cuda.h"

namespace votca {
namespace xtp {

OpenMP_CUDA::OpenMP_CUDA() {

  inside_Parallel_region_ = OPENMP::InsideActiveParallelRegion();
  threadID_parent_ = OPENMP::getThreadId();

  cpu_intermediate_input_.resize(getNumberThreads());
  cpu_temporaries_.resize(getNumberThreads());
#ifdef USE_CUDA
  Index no_gpus = count_available_gpus();
  gpus_.clear();
  if (inside_Parallel_region_) {
    if (threadID_parent_ < no_gpus) {
      gpus_.push_back(GPU_data(threadID_parent_));
    }
  } else {
    for (Index i = 0; i < no_gpus; i++) {
      gpus_.push_back(GPU_data(i));
    }
  }
#endif
}

#ifdef USE_CUDA
void OpenMP_CUDA::setOperators(const std::vector<Eigen::MatrixXd>& tensor,
                               const Eigen::MatrixXd& rightoperator) {
  rightoperator_ = &rightoperator;
#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    const Eigen::MatrixXd& head = tensor.front();
    gpu.push_back(head.rows(), head.cols());
    gpu.push_back(rightoperator);
    gpu.push_back(head.rows(), rightoperator.cols());
  }
}
#else
void OpenMP_CUDA::setOperators(const std::vector<Eigen::MatrixXd>&,
                               const Eigen::MatrixXd& rightoperator) {
  rightoperator_ = &rightoperator;
}
#endif

#ifdef USE_CUDA

bool OpenMP_CUDA::isInVector(Index Id, const std::vector<GPU_data>& vec) {
  return (std::find_if(vec.begin(), vec.end(), [&Id](const GPU_data& d) {
            return d.Id == Id;
          }) != vec.end());
}
bool OpenMP_CUDA::isGPUthread(Index ParentThreadId) const {
  return isInVector(ParentThreadId, gpus_);
}
#endif

Index OpenMP_CUDA::getParentThreadId() const {
  return inside_Parallel_region_ ? threadID_parent_ : OPENMP::getThreadId();
}
Index OpenMP_CUDA::getLocalThreadId(Index ParentThreadId) const {
  return inside_Parallel_region_ ? 0 : ParentThreadId;
}
Index OpenMP_CUDA::getNumberThreads() const {
  return inside_Parallel_region_ ? 1 : OPENMP::getMaxThreads();
}

/*
 * The Cuda device behaves like a server that is receiving matrix-matrix
 * multiplications from a single stream (an Nvidia queue) and handle them
 * in an asynchronous way. It performs the following operations when recieving
 * a request:
 *  1. Check that there is enough space for the arrays
 *  2. Allocate memory for each matrix
 *  3. Copy the matrix to the allocated space
 *  4. Perform the matrix multiplication
 *  5. Return the result matrix
 * The Cuda device knows to which memory address it needs to copy back the
 * result. see: https://docs.nvidia.com/cuda/cublas/index.html#thread-safety2
 */
void OpenMP_CUDA::MultiplyRight(Eigen::MatrixXd& tensor) {

  // All the GPU communication happens through a single thread that reuses
  // all memory allocated in the GPU and it's dynamically load-balanced by
  // OpenMP. The rest of the threads use the default CPU matrix
  // multiplication
#ifdef USE_CUDA
  Index threadid = getParentThreadId();
  if (isGPUthread(threadid)) {
    GPU_data& gpu = gpus_[getLocalThreadId(threadid)];
    gpu.activateGPU();
    gpu.Mat(0).copy_to_gpu(tensor);
    gpu.pipe().gemm(gpu.Mat(0), gpu.Mat(1), gpu.Mat(2));
    tensor = gpu.Mat(2);
  } else {
    tensor *= *rightoperator_;
  }
#else
  tensor *= *rightoperator_;
#endif
  return;
}

void OpenMP_CUDA::setOperators(const Eigen::MatrixXd& leftoperator,
                               const Eigen::MatrixXd& rightoperator) {
  rightoperator_ = &rightoperator;
  leftoperator_ = &leftoperator;
#ifdef USE_CUDA
#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    gpu.push_back(leftoperator);
    gpu.push_back(leftoperator.cols(), rightoperator.rows());
    gpu.push_back(leftoperator.rows(), rightoperator.rows());
    gpu.push_back(rightoperator);
    gpu.push_back(leftoperator.rows(), rightoperator.cols());
  }
#endif
}

void OpenMP_CUDA::MultiplyLeftRight(Eigen::MatrixXd& matrix) {
#ifdef USE_CUDA
  Index threadid = getParentThreadId();
  if (isGPUthread(threadid)) {
    GPU_data& gpu = gpus_[getLocalThreadId(threadid)];
    gpu.activateGPU();
    gpu.Mat(1).copy_to_gpu(matrix);
    gpu.pipe().gemm(gpu.Mat(0), gpu.Mat(1), gpu.Mat(2));
    gpu.pipe().gemm(gpu.Mat(2), gpu.Mat(3), gpu.Mat(4));
    matrix = gpu.Mat(4);
  } else {
    matrix = (*leftoperator_) * matrix * (*rightoperator_);
  }
#else
  matrix = (*leftoperator_) * matrix * (*rightoperator_);
#endif
  return;
}
#ifdef USE_CUDA
void OpenMP_CUDA::createTemporaries(Index rows, Index cols) {
  reduction_ = std::vector<Eigen::MatrixXd>(getNumberThreads(),
                                            Eigen::MatrixXd::Zero(cols, cols));

#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    gpu.push_back(rows, 1);
    gpu.push_back(rows, cols);
    gpu.push_back(rows, cols);
    gpu.push_back(reduction_[i]);
  }
}
#else
void OpenMP_CUDA::createTemporaries(Index, Index cols) {
  reduction_ = std::vector<Eigen::MatrixXd>(getNumberThreads(),
                                            Eigen::MatrixXd::Zero(cols, cols));
}

#endif

void OpenMP_CUDA::PushMatrix(Eigen::MatrixXd& matrix) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(1).copy_to_gpu(matrix);
  } else {
    cpu_intermediate_input_[threadid] = &matrix;
  }
#else
  cpu_intermediate_input_[threadid] = &matrix;
#endif
}

void OpenMP_CUDA::A_TDA(const Eigen::VectorXd& vec) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(0).copy_to_gpu(vec);
    gpu.pipe().diag_gemm(gpu.Mat(1), gpu.Mat(0), gpu.Mat(2));
    gpu.pipe().gemm(gpu.Mat(1).transpose(), gpu.Mat(2), gpu.Mat(3), 1.0);
  } else {
    reduction_[threadid] += cpu_intermediate_input_[threadid]->transpose() *
                            vec.asDiagonal() *
                            (*cpu_intermediate_input_[threadid]);
  }
#else
  reduction_[threadid] += cpu_intermediate_input_[threadid]->transpose() *
                          vec.asDiagonal() *
                          (*cpu_intermediate_input_[threadid]);
#endif
}

#ifdef USE_CUDA
void OpenMP_CUDA::createTemporaries(const Eigen::VectorXd& vec,
                                    const Eigen::MatrixXd& input, Index rows1,
                                    Index rows2, Index cols) {
  reduction_ = std::vector<Eigen::MatrixXd>(
      getNumberThreads(), Eigen::MatrixXd::Zero(input.rows(), input.cols()));
  temp_ = std::vector<Eigen::VectorXd>(
      getNumberThreads(), Eigen::VectorXd::Zero(input.cols()));
  rightoperator_ = &input;
  vec_ = &vec;

#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    gpu.push_back(vec);
    gpu.push_back(input);
    gpu.push_back(rows1, cols);
    gpu.push_back(rows2, cols);
    gpu.push_back(rows1 * rows2, 1);
    gpu.push_back(rows1 * rows2, 1);
    gpu.push_back(reduction_[i]);
  }
}

#else
void OpenMP_CUDA::createTemporaries(const Eigen::VectorXd& vec,
                                    const Eigen::MatrixXd& input, Index, Index,
                                    Index) {
  reduction_ = std::vector<Eigen::MatrixXd>(
      getNumberThreads(), Eigen::MatrixXd::Zero(input.rows(), input.cols()));
  temp_ = std::vector<Eigen::VectorXd>(
      getNumberThreads(), Eigen::VectorXd::Zero(input.rows()));
  rightoperator_ = &input;
  vec_ = &vec;
}
#endif

void OpenMP_CUDA::PrepareMatrix1(Eigen::MatrixXd& mat) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(2).copy_to_gpu(mat);
    gpu.pipe().diag_gemm(gpu.Mat(2), gpu.Mat(0), gpu.Mat(2));
  } else {
    cpu_intermediate_input_[threadid] = &mat;
    mat *= vec_->asDiagonal();
  }
#else
  cpu_intermediate_input_[threadid] = &mat;
  mat *= vec_->asDiagonal();
#endif
}

void OpenMP_CUDA::SetTempZero() {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(4).setZero();
  } else {
    temp_[threadid].setZero();
  }
#else
  temp_[threadid].setZero();
#endif
}

void OpenMP_CUDA::PrepareMatrix2(const Eigen::MatrixXd& mat, bool Hd2) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(3).copy_to_gpu(mat);
    if (Hd2) {
      gpu.Mat(4).reshape(gpu.Mat(3).rows(), gpu.Mat(2).rows());
      gpu.pipe().gemm(gpu.Mat(3), gpu.Mat(2).transpose(), gpu.Mat(4), 1.0);
    } else {
      gpu.Mat(4).reshape(gpu.Mat(2).rows(), gpu.Mat(3).rows());
      gpu.pipe().gemm(gpu.Mat(2), gpu.Mat(3).transpose(), gpu.Mat(4), 1.0);
    }
    gpu.Mat(4).reshape(gpu.Mat(2).rows() * gpu.Mat(3).rows(), 1);
  } else {

    if (Hd2) {
      Eigen::Map<Eigen::MatrixXd> row(
          temp_[threadid].data(), mat.rows(),
          cpu_intermediate_input_[threadid]->rows());
      row += mat * cpu_intermediate_input_[threadid]->transpose();
    } else {
      Eigen::Map<Eigen::MatrixXd> row(temp_[threadid].data(),
                                      cpu_intermediate_input_[threadid]->rows(),
                                      mat.rows());
      row += *cpu_intermediate_input_[threadid] * mat.transpose();
    }
  }
#else
  if (Hd2) {
    Eigen::Map<Eigen::MatrixXd> row(temp_[threadid].data(), mat.rows(),
                                    cpu_intermediate_input_[threadid]->rows());
    row += mat * cpu_intermediate_input_[threadid]->transpose();
  } else {
    Eigen::Map<Eigen::MatrixXd> row(temp_[threadid].data(),
                                    cpu_intermediate_input_[threadid]->rows(),
                                    mat.rows());
    row += *cpu_intermediate_input_[threadid] * mat.transpose();
  }
#endif
}

void OpenMP_CUDA::Addvec(const Eigen::VectorXd& row) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.Mat(5).copy_to_gpu(row);
    gpu.pipe().axpy(gpu.Mat(5), gpu.Mat(4), 1.0);
  } else {
    temp_[threadid] += row;
  }
#else
  temp_[threadid] += row;
#endif
}

void OpenMP_CUDA::MultiplyRow(Index row) {
  Index parentid = getParentThreadId();
  Index threadid = getLocalThreadId(parentid);
#ifdef USE_CUDA
  if (isGPUthread(parentid)) {
    GPU_data& gpu = gpus_[threadid];
    gpu.activateGPU();
    gpu.pipe().gemm(gpu.Mat(5).transpose(), gpu.Mat(1),
                    gpu.Mat(6).block(row, 0, 1, gpu.Mat(1).cols()), 0.0);
  } else {
    reduction_[threadid].row(row) = temp_[threadid].transpose() * (*rightoperator_);
  }
#else
  reduction_[threadid].row(row) = temp_[threadid].transpose() * (*rightoperator_);
#endif
}

Eigen::MatrixXd OpenMP_CUDA::getReductionVar() {
#ifdef USE_CUDA
#pragma omp parallel for num_threads(gpus_.size())
  for (Index i = 0; i < Index(gpus_.size()); i++) {
    GPU_data& gpu = gpus_[i];
    gpu.activateGPU();
    reduction_[i] = *(gpu.temp.back());
  }
#endif
  for (Index i = 1; i < Index(reduction_.size()); i++) {
    reduction_[0] += reduction_[i];
  }
  return reduction_[0];
}

}  // namespace xtp
}  // namespace votca
<|endoftext|>


<commit_before><commit_msg>[C++] Rename class variables to start with underscore<commit_after><|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : D2.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-3-24 22:42:41
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll MOD = 1000000007;

int N;
set<string> forbid;
string chars[4] = {"A", "G", "C", "T"};
typedef tuple<int, string> key;
map<key, ll> M;

void make(string S)
{
  if (S.size() < 4)
  {
    for (auto i = 0; i < 4; i++)
    {
      make(S + chars[i]);
    }
  }
  else
  {
    string T = S;
    for (auto i = 0; i < 4; i++)
    {
      if (i < 3)
      {
        swap(T[i], T[i + 1]);
      }
    }
    for (auto i = 0; i < 2; i++)
    {
      if (T.substr(i, 3) == "AGC")
      {
        forbid.insert(S);
        return;
      }
    }
  }
}

bool ok(string S)
{
  return (forbid.find(S) == forbid.end());
}

ll dfs(int x, string S)
{
  if (M.find(key(x, S)) != M.end())
  {
    return M[key(x, S)];
  }
  if (x == N)
  {
    return 1;
  }
  ll ans = 0;
  for (auto i = 0; i < 4; i++)
  {
    string T = S + chars[i];
    if (ok(T))
    {
      ans += dfs(x + 1, T.substr(1, 3));
      ans %= MOD;
    }
  }
  return ans;
}

int main()
{
  cin >> N;
  make("");
#if DEBUG == 1
  for (auto x : forbid)
  {
    cerr << x << endl;
  }
#endif
  cout << dfs(0, "TTT") << endl;
}<commit_msg>tried D2.cpp to 'D'<commit_after>#define DEBUG 1

/**
 * File    : D2.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-3-24 22:42:41
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll MOD = 1000000007;

int N;
set<string> forbid;
string chars[4] = {"A", "G", "C", "T"};
typedef tuple<int, string> key;
map<key, ll> M;

void make(string S)
{
  if (S.size() < 4)
  {
    for (auto i = 0; i < 4; i++)
    {
      make(S + chars[i]);
    }
  }
  else
  {
    string T = S;
    for (auto i = 0; i < 4; i++)
    {
      if (i < 3)
      {
        swap(T[i], T[i + 1]);
      }
    }
    for (auto i = 0; i < 2; i++)
    {
      if (T.substr(i, 3) == "AGC")
      {
        forbid.insert(S);
        return;
      }
    }
  }
}

bool ok(string S)
{
  return (forbid.find(S) == forbid.end());
}

ll dfs(int x, string S)
{
  if (M.find(key(x, S)) != M.end())
  {
    return M[key(x, S)];
  }
  if (x == N)
  {
    return 1;
  }
  ll ans = 0;
  for (auto i = 0; i < 4; i++)
  {
    string T = S + chars[i];
    if (ok(T))
    {
      ans += dfs(x + 1, T.substr(1, 3));
      ans %= MOD;
    }
  }
  return M[key(x, S)] = ans;
}

int main()
{
  cin >> N;
  make("");
#if DEBUG == 1
  for (auto x : forbid)
  {
    cerr << x << endl;
  }
#endif
  cout << dfs(0, "TTT") << endl;
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

#include <cstring>

#include <iostream>
#include <string>

#include "libxtreemfs/client.h"
#include "libxtreemfs/file_handle.h"
#include "libxtreemfs/options.h"
#include "libxtreemfs/volume.h"
#include "libxtreemfs/xtreemfs_exception.h"
#include "pbrpc/RPC.pb.h"  // xtreemfs::pbrpc::UserCredentials
#include "xtreemfs/MRC.pb.h"  // xtreemfs::pbrpc::Stat

using namespace std;

int main(int argc, char* argv[]) {
  // Every operation is executed in the context of a given user and his groups.
  // The UserCredentials object does store this information and is currently
  // (08/2011) *only* evaluated by the MRC (although the protocol requires to
  // send user_credentials to DIR and OSD, too).
  xtreemfs::pbrpc::UserCredentials user_credentials;
  user_credentials.set_username("example_libxtreemfs");
  user_credentials.add_groups("example_libxtreemfs");

  // Class which allows to change options of the library.
  xtreemfs::Options options;

  try {
    options.ParseCommandLine(argc, argv);
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "Invalid parameters found, error: " << e.what() << endl << endl;
    return 1;
  }

  xtreemfs::Client* client = NULL;
  xtreemfs::FileHandle* file = NULL;
  int return_code = 0;
  try {
    // Create a new instance of a client using the DIR service at
    // 'demo.xtreemfs.org' (default port 32638).
    client = xtreemfs::Client::CreateClient(
        xtreemfs::ServiceAddresses(1, "demo.xtreemfs.org:32638"),
        user_credentials,
        NULL,  // No SSL options.
        options);

    // Start the client (a connection to the DIR service will be setup).
    client->Start();

    // Open a volume named 'demo'.
    xtreemfs::Volume *volume = NULL;
    volume = client->OpenVolume("demo",
                                NULL,  // No SSL options.
                                options);

    // Open a file.
    file = volume->OpenFile(user_credentials,
                            "/example_libxtreemfs.txt",
                            static_cast<xtreemfs::pbrpc::SYSTEM_V_FCNTL>(
                                xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_CREAT |
                                xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_TRUNC |
                                xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_RDWR),
                            511);  // = 777 Octal.

    // Write to file.
    cout << "Writing the string\n"
            "\n"
            "\t\"Accessed XtreemFS through the C++ libxtreemfs.\"\n"
            "\n"
            "to the file example_libxtreemfs.txt..." << endl;
    char write_buf[] = "Accessed XtreemFS through the C++ libxtreemfs.";
    file->Write(user_credentials,
                reinterpret_cast<const char*>(&write_buf),
                sizeof(write_buf),
                0);

    // Get file attributes.
    xtreemfs::pbrpc::Stat stat;
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nNew file size of example_libxtreemfs.txt: "
         << stat.size() << " Bytes." << endl;
    // Once again, now hopefully from the Cache.
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nFile size of example_libxtreemfs.txt again (this time retrieved"
            " from the enabled metadata cache): " << stat.size() << endl;

    // Read from the file.
    const size_t buffer_size = 128 * 1024;  // 128kB, default object size.
    char read_buf[buffer_size];
    memset(&read_buf, 0, buffer_size);
    file->Read(user_credentials,
               reinterpret_cast<char*>(&read_buf),
               buffer_size,  // Length.
               0);  // Offset.
    cout << "\nReading the content of the file example_libxtreemfs.txt:\n\n"
         << read_buf << endl;
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "An error occured:\n" << e.what() << endl;
    return_code = 1;
  }

  if (file != NULL) {
    // Close the file (no need to delete it, see documentation volume.h).
    file->Close();
  }

  if (client != NULL) {
    // Shutdown() does also invoke a volume->Close().
    client->Shutdown();
    delete client;
  }

  return return_code;
}
<commit_msg>client: adapt read/write invocations to new signature.<commit_after>/*
 * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

#include <cstring>

#include <iostream>
#include <string>

#include "libxtreemfs/client.h"
#include "libxtreemfs/file_handle.h"
#include "libxtreemfs/options.h"
#include "libxtreemfs/volume.h"
#include "libxtreemfs/xtreemfs_exception.h"
#include "pbrpc/RPC.pb.h"  // xtreemfs::pbrpc::UserCredentials
#include "xtreemfs/MRC.pb.h"  // xtreemfs::pbrpc::Stat

using namespace std;

int main(int argc, char* argv[]) {
  // Every operation is executed in the context of a given user and his groups.
  // The UserCredentials object does store this information and is currently
  // (08/2011) *only* evaluated by the MRC (although the protocol requires to
  // send user_credentials to DIR and OSD, too).
  xtreemfs::pbrpc::UserCredentials user_credentials;
  user_credentials.set_username("example_libxtreemfs");
  user_credentials.add_groups("example_libxtreemfs");

  // Class which allows to change options of the library.
  xtreemfs::Options options;

  try {
    options.ParseCommandLine(argc, argv);
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "Invalid parameters found, error: " << e.what() << endl << endl;
    return 1;
  }

  xtreemfs::Client* client = NULL;
  xtreemfs::FileHandle* file = NULL;
  int return_code = 0;
  try {
    // Create a new instance of a client using the DIR service at
    // 'demo.xtreemfs.org' (default port 32638).
    client = xtreemfs::Client::CreateClient(
        xtreemfs::ServiceAddresses(1, "demo.xtreemfs.org:32638"),
        user_credentials,
        NULL,  // No SSL options.
        options);

    // Start the client (a connection to the DIR service will be setup).
    client->Start();

    // Open a volume named 'demo'.
    xtreemfs::Volume *volume = NULL;
    volume = client->OpenVolume("demo",
                                NULL,  // No SSL options.
                                options);

    // Open a file.
    file = volume->OpenFile(user_credentials,
                            "/example_libxtreemfs.txt",
                            static_cast<xtreemfs::pbrpc::SYSTEM_V_FCNTL>(
                                xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_CREAT |
                                xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_TRUNC |
                                xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_RDWR),
                            511);  // = 777 Octal.

    // Write to file.
    cout << "Writing the string\n"
            "\n"
            "\t\"Accessed XtreemFS through the C++ libxtreemfs.\"\n"
            "\n"
            "to the file example_libxtreemfs.txt..." << endl;
    char write_buf[] = "Accessed XtreemFS through the C++ libxtreemfs.";
    file->Write(reinterpret_cast<const char*>(&write_buf),
                sizeof(write_buf),
                0);

    // Get file attributes.
    xtreemfs::pbrpc::Stat stat;
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nNew file size of example_libxtreemfs.txt: "
         << stat.size() << " Bytes." << endl;
    // Once again, now hopefully from the Cache.
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nFile size of example_libxtreemfs.txt again (this time retrieved"
            " from the enabled metadata cache): " << stat.size() << endl;

    // Read from the file.
    const size_t buffer_size = 128 * 1024;  // 128kB, default object size.
    char read_buf[buffer_size];
    memset(&read_buf, 0, buffer_size);
    file->Read(reinterpret_cast<char*>(&read_buf),
               buffer_size,  // Length.
               0);  // Offset.
    cout << "\nReading the content of the file example_libxtreemfs.txt:\n\n"
         << read_buf << endl;
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "An error occured:\n" << e.what() << endl;
    return_code = 1;
  }

  if (file != NULL) {
    // Close the file (no need to delete it, see documentation volume.h).
    file->Close();
  }

  if (client != NULL) {
    // Shutdown() does also invoke a volume->Close().
    client->Shutdown();
    delete client;
  }

  return return_code;
}
<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Michael Taylor
// =============================================================================
//
// Base class for a continuous band rigid-link track shoe (template definition).
//
// =============================================================================

#include "chrono/physics/ChGlobal.h"
#include "chrono/assets/ChCylinderShape.h"
#include "chrono/assets/ChBoxShape.h"
#include "chrono/assets/ChColorAsset.h"
#include "chrono/assets/ChTexture.h"

#include "chrono_vehicle/ChSubsysDefs.h"
#include "chrono_vehicle/tracked_vehicle/track_shoe/ChTrackShoeRigidCB.h"

namespace chrono {
namespace vehicle {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChTrackShoeRigidCB::ChTrackShoeRigidCB(const std::string& name) : ChTrackShoe(name) {}

void ChTrackShoeRigidCB::Initialize(std::shared_ptr<ChBodyAuxRef> chassis,
                                    const ChVector<>& location,
                                    const ChQuaternion<>& rotation) {
    //// TODO
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::Initialize(std::shared_ptr<ChBodyAuxRef> chassis,
                                    const std::vector<ChCoordsys<>>& component_pos) {
    // Check to make sure that the correct number of coordinate systems were provided for
    // this shoe (tread + associated web segments)
    assert(component_pos.size() == GetNumWebSegments() + 1);

    // Express the tread body's location and orientation in global frame.
    ChVector<> loc = chassis->TransformPointLocalToParent(component_pos[0].pos);
    ChQuaternion<> rot = chassis->GetRot() * component_pos[0].rot;

    // Create the tread body
    m_shoe = std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody());
    m_shoe->SetNameString(m_name + "_tread");
    m_shoe->SetPos(loc);
    m_shoe->SetRot(rot);
    m_shoe->SetMass(GetTreadMass());
    m_shoe->SetInertiaXX(GetTreadInertia());
    chassis->GetSystem()->AddBody(m_shoe);

    // Add contact geometry.
    m_shoe->SetCollide(true);

    switch (m_shoe->GetContactMethod()) {
        case ChMaterialSurface::NSC:
            m_shoe->GetMaterialSurfaceNSC()->SetFriction(m_friction);
            m_shoe->GetMaterialSurfaceNSC()->SetRestitution(m_restitution);
            break;
        case ChMaterialSurface::SMC:
            m_shoe->GetMaterialSurfaceSMC()->SetFriction(m_friction);
            m_shoe->GetMaterialSurfaceSMC()->SetRestitution(m_restitution);
            m_shoe->GetMaterialSurfaceSMC()->SetYoungModulus(m_young_modulus);
            m_shoe->GetMaterialSurfaceSMC()->SetPoissonRatio(m_poisson_ratio);
            m_shoe->GetMaterialSurfaceSMC()->SetKn(m_kn);
            m_shoe->GetMaterialSurfaceSMC()->SetGn(m_gn);
            m_shoe->GetMaterialSurfaceSMC()->SetKt(m_kt);
            m_shoe->GetMaterialSurfaceSMC()->SetGt(m_gt);
            break;
    }

    AddShoeContact();

    // Cache parameters for a single web segment.
    m_seg_length = GetWebLength() / GetNumWebSegments();
    m_seg_mass = GetWebMass() / GetNumWebSegments();
    m_seg_inertia = GetWebInertia();  //// TODO - properly distribute web inertia

    // Create the required number of web segment bodies
    for (size_t is = 0; is < GetNumWebSegments(); is++) {
        m_web_segments.push_back(std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody()));

        m_web_segments[is]->SetNameString(m_name + "_web_" + std::to_string(is));
        ChVector<> loc = chassis->TransformPointLocalToParent(component_pos[is + 1].pos);
        ChQuaternion<> rot = chassis->GetRot() * component_pos[is + 1].rot;
        m_web_segments[is]->SetPos(loc);
        m_web_segments[is]->SetRot(rot);
        m_web_segments[is]->SetMass(m_seg_mass);
        m_web_segments[is]->SetInertiaXX(m_seg_inertia);
        chassis->GetSystem()->AddBody(m_web_segments[is]);

        // Add contact geometry.
        m_web_segments[is]->SetCollide(true);

        switch (m_web_segments[is]->GetContactMethod()) {
            case ChMaterialSurface::NSC:
                m_web_segments[is]->GetMaterialSurfaceNSC()->SetFriction(m_friction);
                m_web_segments[is]->GetMaterialSurfaceNSC()->SetRestitution(m_restitution);
                break;
            case ChMaterialSurface::SMC:
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetFriction(m_friction);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetRestitution(m_restitution);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetYoungModulus(m_young_modulus);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetPoissonRatio(m_poisson_ratio);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetKn(m_kn);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetGn(m_gn);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetKt(m_kt);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetGt(m_gt);
                break;
        }

        AddWebContact(m_web_segments[is]);
    }
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
double ChTrackShoeRigidCB::GetMass() const {
    return GetTreadMass() + GetWebMass();
}

double ChTrackShoeRigidCB::GetPitch() const {
    return GetToothBaseLength() + GetWebLength();
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::AddShoeContact() {
    m_shoe->GetCollisionModel()->ClearModel();

    m_shoe->GetCollisionModel()->SetFamily(TrackedCollisionFamily::SHOES);
    m_shoe->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(TrackedCollisionFamily::SHOES);

    // Guide pin
    ChVector<> g_hdims = GetGuideBoxDimensions() / 2;
    ChVector<> g_loc(GetGuideBoxOffsetX(), 0, GetWebThickness() / 2 + g_hdims.z());
    m_shoe->GetCollisionModel()->AddBox(g_hdims.x(), g_hdims.y(), g_hdims.z(), g_loc);

    // Main box
    ChVector<> b_hdims(GetTreadLength() / 2, GetBeltWidth() / 2, (GetWebThickness() + GetTreadThickness()) / 2);
    ChVector<> b_loc(0, 0, -GetTreadThickness() / 2);
    m_shoe->GetCollisionModel()->AddBox(b_hdims.x(), b_hdims.y(), b_hdims.z(), b_loc);

    m_shoe->GetCollisionModel()->BuildModel();
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::AddWebContact(std::shared_ptr<ChBody> segment) {
    segment->GetCollisionModel()->ClearModel();

    segment->GetCollisionModel()->SetFamily(TrackedCollisionFamily::SHOES);
    segment->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(TrackedCollisionFamily::SHOES);

    segment->GetCollisionModel()->AddBox(m_seg_length / 2, GetBeltWidth() / 2, GetWebThickness() / 2);

    segment->GetCollisionModel()->BuildModel();
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::AddVisualizationAssets(VisualizationType vis) {
    if (vis == VisualizationType::NONE)
        return;

    AddShoeVisualization();
    for (auto segment : m_web_segments)
        AddWebVisualization(segment);
}

void ChTrackShoeRigidCB::RemoveVisualizationAssets() {
    m_shoe->GetAssets().clear();
    for (auto segment : m_web_segments) {
        segment->GetAssets().clear();
    }
}

ChColor GetColor(int index) {
    if (index == 0)
        return ChColor(0.7f, 0.4f, 0.4f);
    else if (index % 2 == 0)
        return ChColor(0.4f, 0.7f, 0.4f);
    else
        return ChColor(0.4f, 0.4f, 0.7f);
}

void ChTrackShoeRigidCB::AddShoeVisualization() {
    m_shoe->AddAsset(std::make_shared<ChColorAsset>(GetColor(m_index)));

    // Guide pin
    ChVector<> g_hdims = GetGuideBoxDimensions() / 2;
    ChVector<> g_loc(GetGuideBoxOffsetX(), 0, GetWebThickness() / 2 + g_hdims.z());
    auto box_pin = std::make_shared<ChBoxShape>();
    box_pin->GetBoxGeometry().Size = g_hdims;
    box_pin->GetBoxGeometry().Pos = g_loc;
    m_shoe->AddAsset(box_pin);

    // Main box
    ChVector<> b_hdims(GetTreadLength() / 2, GetBeltWidth() / 2, (GetWebThickness() + GetTreadThickness()) / 2);
    ChVector<> b_loc(0, 0, -GetTreadThickness() / 2);
    auto box_main = std::make_shared<ChBoxShape>();
    box_main->GetBoxGeometry().Size = b_hdims;
    box_main->GetBoxGeometry().Pos = b_loc;
    m_shoe->AddAsset(box_main);

    // Connection to first web segment
    double radius = GetWebThickness() / 4;
    auto cyl = std::make_shared<ChCylinderShape>();
    cyl->GetCylinderGeometry().rad = radius;
    cyl->GetCylinderGeometry().p1 = ChVector<>(GetTreadLength() / 2, -GetBeltWidth() / 2 - 2 * radius, 0);
    cyl->GetCylinderGeometry().p2 = ChVector<>(GetTreadLength() / 2, +GetBeltWidth() / 2 + 2 * radius, 0);
    m_shoe->AddAsset(cyl);
}

void ChTrackShoeRigidCB::AddWebVisualization(std::shared_ptr<ChBody> segment) {
    segment->AddAsset(std::make_shared<ChColorAsset>(GetColor(m_index)));

    auto box = std::make_shared<ChBoxShape>();
    box->GetBoxGeometry().SetLengths(ChVector<>(m_seg_length, GetBeltWidth(), GetWebThickness()));
    segment->AddAsset(box);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::Connect(std::shared_ptr<ChTrackShoe> next) {
    ChSystem* system = m_shoe->GetSystem();
    ChVector<> loc;
    ChQuaternion<> rot;

    // Connect tread body to the first web segment.
    loc = m_shoe->TransformPointLocalToParent(ChVector<>(GetToothBaseLength() / 2, 0, 0));
    rot = m_shoe->GetRot() * Q_from_AngX(CH_C_PI_2);
    auto revolute0 = std::make_shared<ChLinkLockRevolute>();
    system->AddLink(revolute0);
    revolute0->SetNameString(m_name + "_revolute_0");
    revolute0->Initialize(m_shoe, m_web_segments[0], ChCoordsys<>(loc, rot));

    // Connect the web segments to each other.
    for (size_t is = 0; is < GetNumWebSegments() - 1; is++) {
        loc = m_web_segments[is]->TransformPointLocalToParent(ChVector<>(m_seg_length / 2, 0, 0));
        rot = m_web_segments[is]->GetRot() * Q_from_AngX(CH_C_PI_2);
        auto revolute = std::make_shared<ChLinkLockRevolute>();
        system->AddLink(revolute);
        revolute->SetNameString(m_name + "_revolute_" + std::to_string(is + 1));
        revolute->Initialize(m_web_segments[is], m_web_segments[is + 1], ChCoordsys<>(loc, rot));
    }

    // Connect the last web segment to the tread body from the next track shoe.
    int is = GetNumWebSegments() - 1;
    loc = m_web_segments[is]->TransformPointLocalToParent(ChVector<>(m_seg_length / 2, 0, 0));
    rot = m_web_segments[is]->GetRot() * Q_from_AngX(CH_C_PI_2);
    auto revolute1 = std::make_shared<ChLinkLockRevolute>();
    system->AddLink(revolute1);
    revolute1->SetNameString(m_name + "_revolute");
    revolute1->Initialize(m_web_segments[is], next->GetShoeBody(), ChCoordsys<>(loc, rot));
}

}  // end namespace vehicle
}  // end namespace chrono
<commit_msg>Implement the virtual Initialize() function for ChTrackShoeRigidCB<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Michael Taylor
// =============================================================================
//
// Base class for a continuous band rigid-link track shoe (template definition).
//
// =============================================================================

#include "chrono/physics/ChGlobal.h"
#include "chrono/assets/ChCylinderShape.h"
#include "chrono/assets/ChBoxShape.h"
#include "chrono/assets/ChColorAsset.h"
#include "chrono/assets/ChTexture.h"

#include "chrono_vehicle/ChSubsysDefs.h"
#include "chrono_vehicle/tracked_vehicle/track_shoe/ChTrackShoeRigidCB.h"

namespace chrono {
namespace vehicle {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChTrackShoeRigidCB::ChTrackShoeRigidCB(const std::string& name) : ChTrackShoe(name) {}

void ChTrackShoeRigidCB::Initialize(std::shared_ptr<ChBodyAuxRef> chassis,
                                    const ChVector<>& location,
                                    const ChQuaternion<>& rotation) {
    // Express the tread body location and orientation in global frame.
    ChVector<> loc = chassis->TransformPointLocalToParent(location);
    ChQuaternion<> rot = chassis->GetRot() * rotation;
    ChVector<> xdir = rot.GetXaxis();

    // Create the tread body
    m_shoe = std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody());
    m_shoe->SetNameString(m_name + "_tread");
    m_shoe->SetPos(loc);
    m_shoe->SetRot(rot);
    m_shoe->SetMass(GetTreadMass());
    m_shoe->SetInertiaXX(GetTreadInertia());
    chassis->GetSystem()->AddBody(m_shoe);

    // Add contact geometry.
    m_shoe->SetCollide(true);

    switch (m_shoe->GetContactMethod()) {
        case ChMaterialSurface::NSC:
            m_shoe->GetMaterialSurfaceNSC()->SetFriction(m_friction);
            m_shoe->GetMaterialSurfaceNSC()->SetRestitution(m_restitution);
            break;
        case ChMaterialSurface::SMC:
            m_shoe->GetMaterialSurfaceSMC()->SetFriction(m_friction);
            m_shoe->GetMaterialSurfaceSMC()->SetRestitution(m_restitution);
            m_shoe->GetMaterialSurfaceSMC()->SetYoungModulus(m_young_modulus);
            m_shoe->GetMaterialSurfaceSMC()->SetPoissonRatio(m_poisson_ratio);
            m_shoe->GetMaterialSurfaceSMC()->SetKn(m_kn);
            m_shoe->GetMaterialSurfaceSMC()->SetGn(m_gn);
            m_shoe->GetMaterialSurfaceSMC()->SetKt(m_kt);
            m_shoe->GetMaterialSurfaceSMC()->SetGt(m_gt);
            break;
    }

    AddShoeContact();

    // Cache parameters for a single web segment.
    m_seg_length = GetWebLength() / GetNumWebSegments();
    m_seg_mass = GetWebMass() / GetNumWebSegments();
    m_seg_inertia = GetWebInertia();  //// TODO - properly distribute web inertia

    // Create the required number of web segment bodies
    ChVector<> seg_loc = loc + (0.5 * GetToothBaseLength()) * xdir;
    for (int is = 0; is < GetNumWebSegments(); is++) {
        m_web_segments.push_back(std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody()));
        m_web_segments[is]->SetNameString(m_name + "_web_" + std::to_string(is));
        m_web_segments[is]->SetPos(seg_loc + ((2 * is + 1) * m_seg_length / 2) * xdir);
        m_web_segments[is]->SetRot(rot);
        m_web_segments[is]->SetMass(m_seg_mass);
        m_web_segments[is]->SetInertiaXX(m_seg_inertia);
        chassis->GetSystem()->AddBody(m_web_segments[is]);

        // Add contact geometry.
        m_web_segments[is]->SetCollide(true);

        switch (m_web_segments[is]->GetContactMethod()) {
            case ChMaterialSurface::NSC:
                m_web_segments[is]->GetMaterialSurfaceNSC()->SetFriction(m_friction);
                m_web_segments[is]->GetMaterialSurfaceNSC()->SetRestitution(m_restitution);
                break;
            case ChMaterialSurface::SMC:
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetFriction(m_friction);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetRestitution(m_restitution);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetYoungModulus(m_young_modulus);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetPoissonRatio(m_poisson_ratio);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetKn(m_kn);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetGn(m_gn);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetKt(m_kt);
                m_web_segments[is]->GetMaterialSurfaceSMC()->SetGt(m_gt);
                break;
        }

        AddWebContact(m_web_segments[is]);
    }
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::Initialize(std::shared_ptr<ChBodyAuxRef> chassis,
                                    const std::vector<ChCoordsys<>>& component_pos) {
    // Check the number of provided locations and orientations.
    assert(component_pos.size() == GetNumWebSegments() + 1);

    // Initialize at origin.
    Initialize(chassis, VNULL, QUNIT);

    // Overwrite absolute body locations and orientations.
    m_shoe->SetPos(chassis->TransformPointLocalToParent(component_pos[0].pos));
    m_shoe->SetRot(chassis->GetRot() * component_pos[0].rot);

    for (int is = 0; is < GetNumWebSegments(); is++) {
        m_web_segments[is]->SetPos(chassis->TransformPointLocalToParent(component_pos[is + 1].pos));
        m_web_segments[is]->SetRot(chassis->GetRot() * component_pos[is + 1].rot);
    }
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
double ChTrackShoeRigidCB::GetMass() const {
    return GetTreadMass() + GetWebMass();
}

double ChTrackShoeRigidCB::GetPitch() const {
    return GetToothBaseLength() + GetWebLength();
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::AddShoeContact() {
    m_shoe->GetCollisionModel()->ClearModel();

    m_shoe->GetCollisionModel()->SetFamily(TrackedCollisionFamily::SHOES);
    m_shoe->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(TrackedCollisionFamily::SHOES);

    // Guide pin
    ChVector<> g_hdims = GetGuideBoxDimensions() / 2;
    ChVector<> g_loc(GetGuideBoxOffsetX(), 0, GetWebThickness() / 2 + g_hdims.z());
    m_shoe->GetCollisionModel()->AddBox(g_hdims.x(), g_hdims.y(), g_hdims.z(), g_loc);

    // Main box
    ChVector<> b_hdims(GetTreadLength() / 2, GetBeltWidth() / 2, (GetWebThickness() + GetTreadThickness()) / 2);
    ChVector<> b_loc(0, 0, -GetTreadThickness() / 2);
    m_shoe->GetCollisionModel()->AddBox(b_hdims.x(), b_hdims.y(), b_hdims.z(), b_loc);

    m_shoe->GetCollisionModel()->BuildModel();
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::AddWebContact(std::shared_ptr<ChBody> segment) {
    segment->GetCollisionModel()->ClearModel();

    segment->GetCollisionModel()->SetFamily(TrackedCollisionFamily::SHOES);
    segment->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(TrackedCollisionFamily::SHOES);

    segment->GetCollisionModel()->AddBox(m_seg_length / 2, GetBeltWidth() / 2, GetWebThickness() / 2);

    segment->GetCollisionModel()->BuildModel();
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::AddVisualizationAssets(VisualizationType vis) {
    if (vis == VisualizationType::NONE)
        return;

    AddShoeVisualization();
    for (auto segment : m_web_segments)
        AddWebVisualization(segment);
}

void ChTrackShoeRigidCB::RemoveVisualizationAssets() {
    m_shoe->GetAssets().clear();
    for (auto segment : m_web_segments) {
        segment->GetAssets().clear();
    }
}

ChColor GetColor(size_t index) {
    if (index == 0)
        return ChColor(0.7f, 0.4f, 0.4f);
    else if (index % 2 == 0)
        return ChColor(0.4f, 0.7f, 0.4f);
    else
        return ChColor(0.4f, 0.4f, 0.7f);
}

void ChTrackShoeRigidCB::AddShoeVisualization() {
    m_shoe->AddAsset(std::make_shared<ChColorAsset>(GetColor(m_index)));

    // Guide pin
    ChVector<> g_hdims = GetGuideBoxDimensions() / 2;
    ChVector<> g_loc(GetGuideBoxOffsetX(), 0, GetWebThickness() / 2 + g_hdims.z());
    auto box_pin = std::make_shared<ChBoxShape>();
    box_pin->GetBoxGeometry().Size = g_hdims;
    box_pin->GetBoxGeometry().Pos = g_loc;
    m_shoe->AddAsset(box_pin);

    // Main box
    ChVector<> b_hdims(GetTreadLength() / 2, GetBeltWidth() / 2, (GetWebThickness() + GetTreadThickness()) / 2);
    ChVector<> b_loc(0, 0, -GetTreadThickness() / 2);
    auto box_main = std::make_shared<ChBoxShape>();
    box_main->GetBoxGeometry().Size = b_hdims;
    box_main->GetBoxGeometry().Pos = b_loc;
    m_shoe->AddAsset(box_main);

    // Connection to first web segment
    double radius = GetWebThickness() / 4;
    auto cyl = std::make_shared<ChCylinderShape>();
    cyl->GetCylinderGeometry().rad = radius;
    cyl->GetCylinderGeometry().p1 = ChVector<>(GetTreadLength() / 2, -GetBeltWidth() / 2 - 2 * radius, 0);
    cyl->GetCylinderGeometry().p2 = ChVector<>(GetTreadLength() / 2, +GetBeltWidth() / 2 + 2 * radius, 0);
    m_shoe->AddAsset(cyl);
}

void ChTrackShoeRigidCB::AddWebVisualization(std::shared_ptr<ChBody> segment) {
    segment->AddAsset(std::make_shared<ChColorAsset>(GetColor(m_index)));

    auto box = std::make_shared<ChBoxShape>();
    box->GetBoxGeometry().SetLengths(ChVector<>(m_seg_length, GetBeltWidth(), GetWebThickness()));
    segment->AddAsset(box);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChTrackShoeRigidCB::Connect(std::shared_ptr<ChTrackShoe> next) {
    ChSystem* system = m_shoe->GetSystem();
    ChVector<> loc;
    ChQuaternion<> rot;

    // Connect tread body to the first web segment.
    loc = m_shoe->TransformPointLocalToParent(ChVector<>(GetToothBaseLength() / 2, 0, 0));
    rot = m_shoe->GetRot() * Q_from_AngX(CH_C_PI_2);
    auto revolute0 = std::make_shared<ChLinkLockRevolute>();
    system->AddLink(revolute0);
    revolute0->SetNameString(m_name + "_revolute_0");
    revolute0->Initialize(m_shoe, m_web_segments[0], ChCoordsys<>(loc, rot));

    // Connect the web segments to each other.
    for (size_t is = 0; is < GetNumWebSegments() - 1; is++) {
        loc = m_web_segments[is]->TransformPointLocalToParent(ChVector<>(m_seg_length / 2, 0, 0));
        rot = m_web_segments[is]->GetRot() * Q_from_AngX(CH_C_PI_2);
        auto revolute = std::make_shared<ChLinkLockRevolute>();
        system->AddLink(revolute);
        revolute->SetNameString(m_name + "_revolute_" + std::to_string(is + 1));
        revolute->Initialize(m_web_segments[is], m_web_segments[is + 1], ChCoordsys<>(loc, rot));
    }

    // Connect the last web segment to the tread body from the next track shoe.
    int is = GetNumWebSegments() - 1;
    loc = m_web_segments[is]->TransformPointLocalToParent(ChVector<>(m_seg_length / 2, 0, 0));
    rot = m_web_segments[is]->GetRot() * Q_from_AngX(CH_C_PI_2);
    auto revolute1 = std::make_shared<ChLinkLockRevolute>();
    system->AddLink(revolute1);
    revolute1->SetNameString(m_name + "_revolute");
    revolute1->Initialize(m_web_segments[is], next->GetShoeBody(), ChCoordsys<>(loc, rot));
}

}  // end namespace vehicle
}  // end namespace chrono
<|endoftext|>


<commit_before>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_XUTILITIES_HPP_
#define POSEIDON_XUTILITIES_HPP_

#include "utilities.hpp"

namespace poseidon {

// Creates a thread that invokes `loopfnT` repeatedly and never exits.
// Exceptions thrown from the thread procedure are ignored.
template<void loopfnT(void*)>
::pthread_t
create_daemon_thread(const char* name, void* param = nullptr)
  {
    ROCKET_ASSERT_MSG(name, "no thread name specified");
    ROCKET_ASSERT_MSG(::std::strlen(name) <= 15, "thread name too long");

    // This is the thread routine. It never returns.
    struct Thunk
      {
        [[noreturn]] static
        void*
        do_loop(void* xparam)
          {
            // Disable cancellation for safety. Failure to set the cancel state is ignored.
            ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);

            // Execute `loopfnT` repeatedly. The thread never exits.
            do
              try {
                loopfnT(xparam);
              }
              catch(exception& stdex) {
                ::std::fprintf(stderr,
                    "WARNING: daemon thread loop error: %s\n"
                    "[exception `%s` thrown from %p (`%s`)]\n",
                    stdex.what(), typeid(stdex).name(),
                    reinterpret_cast<void*>(loopfnT), typeid(loopfnT).name());
              }
            while(true);
          }
      };

    // Create the thread first.
    ::pthread_t thr;
    int err = ::pthread_create(&thr, nullptr, Thunk::do_loop, param);
    if(err != 0)
      POSEIDON_THROW("could not create $2 thread\n"
                    "[`pthread_create()` failed: $1]",
                    format_errno(err), name);

    // Set the thread name. Failure to set the name is ignored.
    ::pthread_setname_np(thr, name);
    return thr;
  }

}  // namespace asteria

#endif
<commit_msg>xutilities: Add a blank line<commit_after>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_XUTILITIES_HPP_
#define POSEIDON_XUTILITIES_HPP_

#include "utilities.hpp"

namespace poseidon {

// Creates a thread that invokes `loopfnT` repeatedly and never exits.
// Exceptions thrown from the thread procedure are ignored.
template<void loopfnT(void*)>
::pthread_t
create_daemon_thread(const char* name, void* param = nullptr)
  {
    ROCKET_ASSERT_MSG(name, "no thread name specified");
    ROCKET_ASSERT_MSG(::std::strlen(name) <= 15, "thread name too long");

    // This is the thread routine. It never returns.
    struct Thunk
      {
        [[noreturn]] static
        void*
        do_loop(void* xparam)
          {
            // Disable cancellation for safety. Failure to set the cancel state is ignored.
            ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);

            // Execute `loopfnT` repeatedly. The thread never exits.
            do
              try {
                loopfnT(xparam);
              }
              catch(exception& stdex) {
                ::std::fprintf(stderr,
                    "WARNING: daemon thread loop error: %s\n"
                    "[exception `%s` thrown from %p (`%s`)]\n",
                    stdex.what(), typeid(stdex).name(),
                    reinterpret_cast<void*>(loopfnT), typeid(loopfnT).name());
              }
            while(true);
          }
      };

    // Create the thread first.
    ::pthread_t thr;
    int err = ::pthread_create(&thr, nullptr, Thunk::do_loop, param);
    if(err != 0)
      POSEIDON_THROW("could not create $2 thread\n"
                    "[`pthread_create()` failed: $1]",
                    format_errno(err), name);

    // Set the thread name. Failure to set the name is ignored.
    ::pthread_setname_np(thr, name);

    return thr;
  }

}  // namespace asteria

#endif
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "UiUtil.h"

#include "../NNative.h"

namespace UiUtil
{
    enum SyncType
    {
        SyncVisible,
        SyncEnable
    };

    bool IsChild(nui::Ui::NFrameBase* frame, nui::Ui::NFrameBase* root, SyncType syncType, bool& realFlag)
    {
        realFlag = true;
        while(frame != NULL)
        {
            if(syncType == SyncVisible)
                realFlag = realFlag && frame->IsVisible();
            else if(syncType == SyncEnable)
                realFlag = realFlag && frame->IsEnabled();

            if(frame == root)
                return true;
            frame = frame->GetParent();
        }
        return false;
    }

    void SyncNativeWindowStatus(nui::Ui::NFrameBase* frame, SyncType syncType)
    {
        if(frame == NULL)
            return;
        nui::Ui::NWindow* window = frame->GetWindow();
        if(window == NULL)
            return;
        HWND hWnd = ::GetWindow(window->GetNative(), GW_CHILD);
        while(hWnd != NULL)
        {
            nui::Ui::NNative* native = nui::Ui::NNative::GetNativeUi(hWnd);
            if(native)
            {
                bool realFlag = false;
                if(IsChild(native, frame, syncType, realFlag))
                {
                    if(syncType == SyncVisible)
                    {
                        ::ShowWindow(native->GetNative(), realFlag);
                    }
                    else if(syncType == SyncEnable)
                    {
                        ::EnableWindow(native->GetNative(), realFlag);
                    }
                }
            }
            hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
        }
    }

    void SyncNativeWindowByVisible(nui::Ui::NFrameBase* frame)
    {
        SyncNativeWindowStatus(frame, SyncVisible);
    }

    void SyncNativeWindowByEnable(nui::Ui::NFrameBase* frame)
    {
        SyncNativeWindowStatus(frame, SyncEnable);
    }
}
<commit_msg>update<commit_after>#include "stdafx.h"
#include "UiUtil.h"

#include "../NNative.h"

namespace UiUtil
{
    enum SyncType
    {
        SyncVisible,
        SyncEnable
    };

    bool IsChild(nui::Ui::NFrameBase* frame, nui::Ui::NFrameBase* root, SyncType syncType, bool& realFlag)
    {
        realFlag = true;
        while(frame != NULL)
        {
            if(syncType == SyncVisible)
                realFlag = realFlag && frame->IsVisible();
            else if(syncType == SyncEnable)
                realFlag = realFlag && frame->IsEnabled();

            if(frame == root)
                return true;
            frame = frame->GetParent();
        }
        return false;
    }

    void SyncNativeWindowStatus(nui::Ui::NFrameBase* frame, SyncType syncType)
    {
        if(frame == NULL)
            return;
        nui::Ui::NWindow* window = frame->GetWindow();
        if(window == NULL)
            return;
        HWND hWnd = ::GetWindow(window->GetNative(), GW_CHILD);
        while(hWnd != NULL)
        {
            nui::Ui::NNative* native = nui::Ui::NNative::GetNativeUi(hWnd);
            if(native)
            {
                bool realFlag = false;
                if(IsChild(native, frame, syncType, realFlag))
                {
                    if(syncType == SyncVisible)
                    {
                        ::ShowWindow(native->GetNative(), realFlag);
                    }
                    else if(syncType == SyncEnable)
                    {
                        ::EnableWindow(native->GetNative(), realFlag);
                    }
                }
            }
            hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
        }
    }

    // fixme: since real window is created only when focused, these two functions could be deleted?
    void SyncNativeWindowByVisible(nui::Ui::NFrameBase* frame)
    {
        SyncNativeWindowStatus(frame, SyncVisible);
    }

    void SyncNativeWindowByEnable(nui::Ui::NFrameBase* frame)
    {
        SyncNativeWindowStatus(frame, SyncEnable);
    }
}
<|endoftext|>


<commit_before><commit_msg>Fixes DCHECK bug in LinkCapacityEstimator.<commit_after><|endoftext|>