text:
/// @file frac_comp_ident.cpp
/// @brief Implementation of finding fractions/completions intersections with mesh
/// @author uentity
/// @version
/// @date 06.10.2011
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "frac_comp_ident.h"
#include "py_list_converter.h"
#include "sql_well.h"

#include "compdat_traits.h"
#include "fracture_traits.h"

#include <boost/format.hpp>
#include <iosfwd>
#include <iostream>

namespace blue_sky { namespace fci {
// impl details
using namespace std;

// hidden details
namespace {

// simple dump
void dump(std::ostream& os, const compdat& cd) {
	os << setw(15) << cd.well_name << ' ' << setw(15) << cd.branch_name << ' ';
	os << setw(10) << std::fixed << std::setprecision(3) << cd.md;
	os << setw(10) << std::fixed << std::setprecision(3) << cd.len;
	for(int i = 0; i < 4; ++i)
		os << setw(4) << cd.cell_pos[i];
	os << setw(2) << cd.dir;
	os << setw(10) << std::fixed << std::setprecision(3) << cd.kh_mult << std::endl;
}

// simple fracture dump
void dump(std::ostream& os, const fracture& frac) {
	os << setw(15) << frac.well_name << ' ' << setw(15) << frac.branch_name << ' ';
	os << setw(3) << frac.frac_status << ' ';
	for(int i = 0; i < 4; ++i)
		os << setw(4) << frac.cell_pos[i];
	os << setw(10) << std::fixed << std::setprecision(3) << frac.frac_half_length_1;
	os << setw(10) << std::fixed << std::setprecision(3) << frac.frac_half_length_2;
	os << setw(10) << std::fixed << std::setprecision(3) << frac.frac_angle;
	os << setw(10) << std::fixed << std::setprecision(3) << frac.frac_half_thin;
	os << setw(10) << std::fixed << std::setprecision(3) << frac.frac_perm << std::endl;
}

template <class x_storage>
void dump(std::ostream& os, const x_storage& cfs) {
	typename x_storage::const_iterator pc;
	typename x_storage::const_iterator end;
	for(pc = cfs.begin(), end = cfs.end(); pc != end; ++pc)
		dump(os, *pc);
}

template< class brick >
struct choose_traits {
	typedef compl_traits type;
};
template< >
struct choose_traits< fracture > {
	typedef fract_traits type;
};

}  // oef hidden namespace

/*-----------------------------------------------------------------
 * compdat
 *----------------------------------------------------------------*/
compdat::compdat(const string& well_name_, const string& branch_name_, const pos_i& cell_pos_, const pos_i& mesh_size)
	: well_name(well_name_), branch_name(branch_name_), dir(' '), kh_mult(0), md(0), len(0), skin (0), diam (0.146), kh (0), status (0)
{
	copy(&cell_pos_[0], &cell_pos_[strategy_3d::D], &cell_pos[0]);
	cell_pos[3] = cell_pos[2];
	cell_id_ = wpi_algo::encode_cell_id(cell_pos_, mesh_size);

	x1[0] = x1[1] = x1[2] = 0;
	x2[0] = x2[1] = x2[2] = 0;
}

compdat::compdat(const string& well_name_, const string& branch_name_, ulong cell_id, const pos_i& mesh_size)
	: well_name(well_name_), branch_name(branch_name_), dir(' '), kh_mult(0), md(0), len(0), skin (0), diam (0.146), kh (0), status (0)
{
	init(cell_id, mesh_size);
}

compdat::compdat(const string& well_name_, ulong cell_id)
	: well_name(well_name_), dir(' '), kh_mult(0), md(0), len(0), skin (0), diam (0.146), kh (0), status (0), cell_id_(cell_id)
{
	x1[0] = x1[1] = x1[2] = 0;
	x2[0] = x2[1] = x2[2] = 0;
}

void compdat::init(ulong cell_id, const pos_i& mesh_size) {
	// convert cell id -> cell pos
	pos_i cell_pos_;
	wpi_algo::decode_cell_id(cell_id, cell_pos_, mesh_size);
	copy(&cell_pos_[0], &cell_pos_[strategy_3d::D], &cell_pos[0]);
	cell_pos[3] = cell_pos[2];
	// store cell_id
	cell_id_ = cell_id;
	x1[0] = x1[1] = x1[2] = 0;
	x2[0] = x2[1] = x2[2] = 0;
}

/*-----------------------------------------------------------------
 * fracture
 *----------------------------------------------------------------*/
fracture::fracture(const string& well_name_, const string& branch_name_, const pos_i& cell_pos_, const pos_i& mesh_size)
	: well_name(well_name_), branch_name(branch_name_), frac_status(0), frac_half_length_1 (0),
	  frac_half_length_2 (0), frac_angle (0), frac_half_thin (0), frac_perm (0), frac_main_k (-1)
{
	copy(&cell_pos_[0], &cell_pos_[strategy_3d::D], &cell_pos[0]);
	cell_pos[3] = cell_pos[2];
	copy(&cell_pos_[0], &cell_pos_[strategy_3d::D], &md_cell_pos[0]);
	cell_id_ = wpi_algo::encode_cell_id(cell_pos_, mesh_size);
}

fracture::fracture(const string& well_name_, const string& branch_name_, ulong cell_id, const pos_i& mesh_size)
	: well_name(well_name_), branch_name(branch_name_),frac_status(0), frac_half_length_1 (0),
	  frac_half_length_2 (0),  frac_angle (0), frac_half_thin (0), frac_perm (0), frac_main_k (-1)
{
	init(cell_id, mesh_size);
}

fracture::fracture(const string& well_name_, ulong cell_id)
	: well_name(well_name_), frac_status(0), frac_half_length_1 (0), frac_half_length_2 (0),
	  frac_angle (0), frac_half_thin (0), frac_perm (0), frac_main_k (-1), cell_id_(cell_id)
{
}

void fracture::init(ulong cell_id, const pos_i& mesh_size) {
	// convert cell id -> cell pos
	pos_i cell_pos_;
	wpi_algo::decode_cell_id(cell_id, cell_pos_, mesh_size);
	copy(&cell_pos_[0], &cell_pos_[strategy_3d::D], &cell_pos[0]);
	cell_pos[3] = cell_pos[2];
	copy(&cell_pos_[0], &cell_pos_[strategy_3d::D], &md_cell_pos[0]);
	// store cell_id
	cell_id_ = cell_id;
}

/*-----------------------------------------------------------------
 * builder implementation for any brick type
 *----------------------------------------------------------------*/
template< class brick >
class builder< brick >::impl : public frac_comp_builder< typename choose_traits< brick >::type > {};

template< class brick >
builder< brick >::builder() : pimpl_(new impl) {}

template< class brick >
void builder< brick >::init(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn) {
	pimpl_->init(nx, ny, coord, zcorn);
}

template< class brick >
void builder< brick >::init(t_ulong nx, t_ulong ny, sp_obj trim_backend) {
	pimpl_->init(nx, ny, trim_backend);
}

template< class brick >
void builder< brick >::init(smart_ptr< well_pool_iface, true > src_well) {
	pimpl_->init(src_well);
}

template< class brick >
const typename builder< brick >::storage_t& builder< brick >::build(double date) {
	pimpl_->build(date);
	return storage();
}

template< class brick >
const typename builder< brick >::storage_t& builder< brick >::storage() const {
	return pimpl_->s_;
}

template< class brick >
void builder< brick >::clear() {
	pimpl_->s_.clear();
}

template< class brick >
template< class B >
void builder< brick >::share_cache_with(const builder< B >& rhs) {
	pimpl_->init_cache(rhs->pimpl_->xp_cache_, rhs->pimpl_->cache_limit_);
}

/*-----------------------------------------------------------------
 * compdat_builder implementation
 *----------------------------------------------------------------*/
compdat_builder::compdat_builder() {}

compdat_builder::compdat_builder(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn) {
	builder< compdat >::init(nx, ny, coord, zcorn);
}

compdat_builder::compdat_builder(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn,
	smart_ptr< well_pool_iface, true > src_well)
{
	builder< compdat >::init(nx, ny, coord, zcorn);
	builder< compdat >::init(src_well);
}

/*-----------------------------------------------------------------
 * fracture_builder implementation
 *----------------------------------------------------------------*/
fracture_builder::fracture_builder() {}

fracture_builder::fracture_builder(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn)
{
	builder< fracture >::init(nx, ny, coord, zcorn);
}

fracture_builder::fracture_builder(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn,
	smart_ptr< well_pool_iface, true > src_well)
{
	builder< fracture >::init(nx, ny, coord, zcorn);
	builder< fracture >::init(src_well);
}

/*-----------------------------------------------------------------
 * fracture_builder::impl
 *----------------------------------------------------------------*/
class compl_n_frac_builder::impl {
public:
	typedef frac_comp_builder< compl_traits >::xp_cache_t xp_cache_t;
	typedef frac_comp_builder< compl_traits >::spxp_cache_t spxp_cache_t;
	typedef smart_ptr< well_pool_iface, true > sp_srcwell;

	frac_comp_builder< compl_traits > cb_;
	frac_comp_builder< fract_traits > fb_;
	spxp_cache_t xp_cache_;

	// ctors
	impl() {
		init_cache();
	}
	impl(t_ulong nx, t_ulong ny, const spv_float& coord, const spv_float& zcorn) {
		init(nx, ny, coord, zcorn);
		init_cache();
	}
	impl(t_ulong nx, t_ulong ny, const spv_float& coord, const spv_float& zcorn,
		const sp_srcwell& src_well)
	{
		init(nx, ny, coord, zcorn);
		init(src_well);
		init_cache();
	}

	void init(t_ulong nx, t_ulong ny, const spv_float& coord, const spv_float& zcorn) {
		cb_.init(nx, ny, coord, zcorn);
		fb_.init(nx, ny, coord, zcorn);
	}

	void init(t_ulong nx, t_ulong ny, const sp_obj& trim_backend) {
		cb_.init(nx, ny, trim_backend);
		fb_.init(nx, ny, trim_backend);
	}

	void init(const sp_srcwell& src_well) {
		cb_.init(src_well);
		fb_.init(src_well);
	}

	void init_cache(const spxp_cache_t xc = NULL, const ulong cache_limit = 0) {
		if(xc)
			xp_cache_ = xc;
		else
			xp_cache_ = new xp_cache_t;
		cb_.init_cache(xp_cache_, cache_limit);
		fb_.init_cache(xp_cache_, cache_limit);
	}

	bool build_cache() {
		if(!cb_.cache() || !fb_.cache())
			init_cache();
		// cache is shared, so invoke build() single time
		return cb_.build_cache();
	}

	const cd_storage& compl_build(double date) {
		cb_.build(date);
		return cb_.s_;
	}

	const frac_storage& frac_build(double date) {
		fb_.build(date);
		return fb_.s_;
	}

	void clear() {
		cb_.s_.clear();
		fb_.s_.clear();
	}

	void share_cache_with(const compl_n_frac_builder& rhs) {
		init_cache(rhs.pimpl_->xp_cache_, rhs.pimpl_->cb_.cache_limit_);
	}
};

/*-----------------------------------------------------------------
 * comp_n_frac_builder implementation
 *----------------------------------------------------------------*/
compl_n_frac_builder::compl_n_frac_builder()
	: pimpl_(new impl())
{}

compl_n_frac_builder::compl_n_frac_builder(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn)
	: pimpl_(new impl(nx, ny, coord, zcorn))
{}

compl_n_frac_builder::compl_n_frac_builder(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn,
	smart_ptr< well_pool_iface, true > src_well)
	: pimpl_(new impl(nx, ny, coord, zcorn, src_well))
{}

void compl_n_frac_builder::init(t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn) {
	pimpl_->init(nx, ny, coord, zcorn);
}

void compl_n_frac_builder::init(t_ulong nx, t_ulong ny, sp_obj trim_backend) {
	pimpl_->init(nx, ny, trim_backend);
}

void compl_n_frac_builder::init(smart_ptr< well_pool_iface, true > src_well) {
	pimpl_->init(src_well);
}

const cd_storage& compl_n_frac_builder::compl_build(double date) {
	return pimpl_->compl_build(date);
}

const frac_storage& compl_n_frac_builder::frac_build(double date) {
	return pimpl_->frac_build(date);
}

bool compl_n_frac_builder::build_cache() {
	return pimpl_->build_cache();
}

const cd_storage& compl_n_frac_builder::storage_compdat ()  const {
	return pimpl_->cb_.s_;
}

const frac_storage& compl_n_frac_builder::storage_fracture () const {
	return pimpl_->fb_.s_;
}

void compl_n_frac_builder::clear() {
	pimpl_->clear();
}

void compl_n_frac_builder::share_cache_with(const compl_n_frac_builder& rhs) {
	pimpl_->share_cache_with(rhs);
}

/*-----------------------------------------------------------------
 * global functions impl
 *----------------------------------------------------------------*/
spv_float completions_ident(smart_ptr< well_pool_iface, true > src_well, double date,
		t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn)
{
	compdat_builder b(nx, ny, coord, zcorn, src_well);
	b.build(date);
	dump(std::cout, b.storage());
	//return BS_KERNEL.create_object(v_float::bs_type());
	return NULL;
}

spv_float fractures_ident(smart_ptr< well_pool_iface, true > src_well, double date,
		t_ulong nx, t_ulong ny, spv_float coord, spv_float zcorn)
{
	fracture_builder b(nx, ny, coord, zcorn, src_well);
	b.build(date);
	dump(std::cout, b.storage());
	//return BS_KERNEL.create_object(v_float::bs_type());
	return NULL;
}

} // eof blue_sky::fci

/*-----------------------------------------------------------------
 * Python export routines
 *----------------------------------------------------------------*/

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(cdb_build_overl, blue_sky::fci::compdat_builder::build, 1, 2)

namespace python {
namespace bp = boost::python;

static void print_compdat(const fci::compdat& cd) {
	fci::dump(std::cout, cd);
}

static void print_fracture(const fci::fracture& frac) {
	fci::dump(std::cout, frac);
}

void py_export_compdat_ident() {
	using namespace fci;

	// export global functions
	bp::def("completions_ident", &fci::completions_ident);
	bp::def("fractures_ident", &fci::fractures_ident);

	// export compdat
	bp::class_< compdat >("compdat", bp::no_init)
		.def_readwrite("well_name", &compdat::well_name)
		.def_readwrite("branch_name", &compdat::branch_name)
		.def_readwrite("dir", &compdat::dir)
		.def("dump", &print_compdat)
	;

	// export cd_storage as list
	typedef bspy_converter< list_traits< cd_storage, 2 > > py_cds_conv;
	py_cds_conv::register_to_py();
	py_cds_conv::register_from_py();

	void (compdat_builder::*init1)(t_ulong, t_ulong, spv_float, spv_float) = &compdat_builder::init;
	void (compdat_builder::*init2)(smart_ptr< well_pool_iface, true >) = &compdat_builder::init;
	void (compdat_builder::*init3)(t_ulong, t_ulong, sp_obj) = &compdat_builder::init;
	bp::class_< compdat_builder >("compdat_builder",
		bp::init< t_ulong, t_ulong, spv_float, spv_float >())
		.def(bp::init< t_ulong, t_ulong, spv_float, spv_float, smart_ptr< well_pool_iface, true> >())
		.def("init", init1)
		.def("init", init2)
		.def("init", init3)
		.def("build", &compdat_builder::build,
			bp::return_value_policy< bp::copy_const_reference >(),
			cdb_build_overl())
		.def("clear", &compdat_builder::clear)
		.def("storage", &compdat_builder::storage,
			bp::return_value_policy< bp::copy_const_reference >())
	;

	// export fracture
	bp::class_< fracture >("fracture", bp::no_init)
		.def_readwrite("well_name", &fracture::well_name)
		.def_readwrite("branch_name", &fracture::branch_name)
		//.def_readwrite("dir", &compdat::dir)
		.def("dump", &print_fracture)
		;

	// export cd_storage as list
	typedef bspy_converter< list_traits< frac_storage, 2 > > py_fracs_conv;
	py_fracs_conv::register_to_py();
	py_fracs_conv::register_from_py();

	// export fracture_builder
	void (fracture_builder::*init4)(t_ulong, t_ulong, spv_float, spv_float) = &fracture_builder::init;
	void (fracture_builder::*init5)(smart_ptr< well_pool_iface, true >) = &fracture_builder::init;
	void (fracture_builder::*init6)(t_ulong, t_ulong, sp_obj) = &fracture_builder::init;
	bp::class_< fracture_builder >("fracture_builder",
			bp::init< t_ulong, t_ulong, spv_float, spv_float >())
		.def(bp::init< t_ulong, t_ulong, spv_float, spv_float, smart_ptr< well_pool_iface, true> >())
		.def("init", init4)
		.def("init", init5)
		.def("init", init6)
		.def("build", &fracture_builder::build,
			bp::return_value_policy< bp::copy_const_reference >(),
			cdb_build_overl())
		.def("clear", &fracture_builder::clear)
		.def("storage", &fracture_builder::storage,
			bp::return_value_policy< bp::copy_const_reference >())
		;

	// export compl_n_frac_builder
	void (compl_n_frac_builder::*init7)(t_ulong, t_ulong, spv_float, spv_float) = &compl_n_frac_builder::init;
	void (compl_n_frac_builder::*init8)(smart_ptr< well_pool_iface, true >) = &compl_n_frac_builder::init;
	void (compl_n_frac_builder::*init9)(t_ulong, t_ulong, sp_obj) = &compl_n_frac_builder::init;
	bp::class_< compl_n_frac_builder >("compl_n_frac_builder",
			bp::init< t_ulong, t_ulong, spv_float, spv_float >())
		.def(bp::init< t_ulong, t_ulong, spv_float, spv_float, smart_ptr< well_pool_iface, true> >())
		.def("init", init7)
		.def("init", init8)
		.def("init", init9)
		.def("compl_build", &compl_n_frac_builder::compl_build,
			bp::return_value_policy< bp::copy_const_reference >(),
			cdb_build_overl())
		.def("frac_build", &compl_n_frac_builder::frac_build,
			bp::return_value_policy< bp::copy_const_reference >(),
			cdb_build_overl())
		.def("clear", &compl_n_frac_builder::clear)
		.def("storage_compdat", &compl_n_frac_builder::storage_compdat,
			bp::return_value_policy< bp::copy_const_reference >())
		.def("storage_fracture", &compl_n_frac_builder::storage_fracture,
			bp::return_value_policy< bp::copy_const_reference >())
		;
}

} /* blue_sky::python */
} /* blue_sky */

max_stars_repo_name: bs-eagle/bs-eagle

max_issues_repo_name: bs-eagle/bs-eagle

max_forks_repo_name: bs-eagle/bs-eagle


text:
#include <type_traits>

#include <boost/asio/io_service.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/system/error_code.hpp>

#include <ssf/log/log.h>

#include "common/config/config.h"

#include "core/client/client.h"
#include "core/client/client_helper.h"
#include "core/command_line/copy/command_line.h"
#include "core/network_protocol.h"
#include "core/transport_virtual_layer_policies/transport_protocol_policy.h"

#include "services/copy/copy_client.h"
#include "services/user_services/base_user_service.h"
#include "services/user_services/copy.h"

using Demux = ssf::Client::Demux;
using CopyService = ssf::services::Copy<Demux>;
using CopyRequest = ssf::services::copy::CopyRequest;
using CopyClient = ssf::services::copy::CopyClient;
using CopyClientPtr = ssf::services::copy::CopyClientPtr;

CopyClientPtr StartCopy(ssf::Client& client, bool from_client_to_server,
                        const CopyRequest& req,
                        boost::system::error_code& copy_ec,
                        boost::system::error_code& start_ec);

void Run(int argc, char** argv, boost::system::error_code& exit_ec);

int main(int argc, char** argv) {
  boost::system::error_code exit_ec;

  Run(argc, argv, exit_ec);

  SSF_LOG("ssfcp", debug, "exit {} ({})", exit_ec.value(), exit_ec.message());

  return exit_ec.value();
}

void Run(int argc, char** argv, boost::system::error_code& exit_ec) {
  boost::system::error_code stop_ec;

  ssf::Client client;

  CopyClientPtr copy_client;

  client.Register<CopyService>();

  ssf::config::Config ssf_config;
  ssf_config.Init();

  // CLI options
  ssf::command_line::CopyCommandLine cmd;
  cmd.Parse(argc, argv, exit_ec);
  if (exit_ec.value() == ::error::operation_canceled) {
    exit_ec.assign(::error::success, ::error::get_ssf_category());
    return;
  } else if (exit_ec) {
    SSF_LOG("ssfcp", error, "invalid command line arguments");
    return;
  }

  SetLogLevel(cmd.log_level());

  // read file configuration file
  ssf_config.UpdateFromFile(cmd.config_file(), exit_ec);
  if (exit_ec) {
    SSF_LOG("ssfcp", error, "invalid config file format");
    return;
  }

  if (ssf_config.GetArgc() > 0) {
    // update command line with config file argv
    cmd.Parse(ssf_config.GetArgc(), ssf_config.GetArgv().data(), exit_ec);
    if (exit_ec) {
      SSF_LOG("ssfcp", error, "invalid command line arguments");
      return;
    }
  }

  ssf_config.Log();

  // create and initialize copy user service
  ssf::UserServiceParameters copy_params = {
      {CopyService::GetParseName(),
       {CopyService::CreateUserServiceParameters(exit_ec)}}};

  if (exit_ec) {
    SSF_LOG("ssfcp", error, "copy service parameters could not be generated");
    return;
  }

  if (!cmd.host_set()) {
    SSF_LOG("ssfcp", error, "no remote host provided");
    exit_ec.assign(::error::destination_address_required,
                   ::error::get_ssf_category());
    return;
  }

  if (!cmd.port_set()) {
    SSF_LOG("ssfcp", error, "no host port provided");
    exit_ec.assign(::error::destination_address_required,
                   ::error::get_ssf_category());
    return;
  }

  ssf::services::copy::CopyRequest req(
      cmd.stdin_input(), cmd.resume(), cmd.recursive(),
      cmd.check_file_integrity(), cmd.max_parallel_copies(),
      cmd.input_pattern(), cmd.output_pattern());

  auto endpoint_query = ssf::GenerateNetworkQuery(
      cmd.host(), std::to_string(cmd.port()), ssf_config);

  // initialize and run client
  auto on_status = [&client, &exit_ec](ssf::Status status) {
    boost::system::error_code stop_ec;
    switch (status) {
      case ssf::Status::kEndpointNotResolvable:
        exit_ec.assign(::error::address_not_available,
                       ::error::get_ssf_category());
        client.Stop(stop_ec);
        break;
      case ssf::Status::kServerUnreachable:
        exit_ec.assign(::error::host_unreachable, ::error::get_ssf_category());
        client.Stop(stop_ec);
        break;
      case ssf::Status::kServerNotSupported:
        exit_ec.assign(::error::protocol_not_supported,
                       ::error::get_ssf_category());
        client.Stop(stop_ec);
        break;
      default:
        break;
    };
  };
  auto on_user_service_status = [&client, &copy_client, &req, &cmd, &exit_ec](
      ssf::Client::UserServicePtr service,
      const boost::system::error_code& ec) {
    if (ec) {
      SSF_LOG("ssfcp", error, "service[{}] initialization failed",
              service->GetName());
      exit_ec.assign(::error::operation_not_supported,
                     ::error::get_ssf_category());
      boost::system::error_code stop_ec;
      client.Stop(stop_ec);
      return;
    }

    if (service->GetName() != CopyService::GetParseName()) {
      return;
    }

    boost::system::error_code create_copy_client_ec;
    copy_client = StartCopy(client, cmd.from_client_to_server(), req, exit_ec,
                            create_copy_client_ec);
    if (create_copy_client_ec) {
      boost::system::error_code stop_ec;
      client.Stop(stop_ec);
    }
  };

  client.Init(endpoint_query, 1, 0, true, copy_params, ssf_config.services(),
              on_status, on_user_service_status, exit_ec);
  if (exit_ec) {
    SSF_LOG("ssfcp", error, "cannot init client ({})", exit_ec.message());
    return;
  }

  SSF_LOG("ssfcp", info, "connecting to <{}:{}>", cmd.host(), cmd.port());
  SSF_LOG("ssfcp", info, "running (Ctrl + C to stop)");

  // stop client on SIGINT or SIGTERM
  boost::asio::signal_set signal(client.get_io_service(), SIGINT, SIGTERM);
  signal.async_wait(
      [&client, &exit_ec](const boost::system::error_code& ec, int signum) {
        if (ec) {
          return;
        }
        exit_ec.assign(ssf::services::copy::ErrorCode::kInterrupted,
                       ssf::services::copy::get_copy_category());
        SSF_LOG("ssfcp", info, "interrupted");
        boost::system::error_code stop_ec;
        client.Stop(stop_ec);
      });

  client.Run(exit_ec);
  if (exit_ec) {
    SSF_LOG("ssfcp", error, "error happened when running client: {}",
            exit_ec.message());
    signal.cancel(stop_ec);
  }

  // block until client stops
  client.WaitStop(stop_ec);
  stop_ec.clear();

  if (copy_client) {
    copy_client->Stop();
  }

  signal.cancel(stop_ec);

  client.Deinit();
}

CopyClientPtr StartCopy(ssf::Client& client, bool from_client_to_server,
                        const CopyRequest& req,
                        boost::system::error_code& copy_ec,
                        boost::system::error_code& start_ec) {
  copy_ec.assign(ssf::services::copy::ErrorCode::kFailure,
                 ssf::services::copy::get_copy_category());
  CopyClientPtr copy_client;
  auto session = client.GetSession(start_ec);
  if (start_ec) {
    SSF_LOG("ssfcp", error, "cannot get client session");
    return nullptr;
  }

  auto on_file_status = [session](ssf::services::copy::CopyContext* context,
                                  const boost::system::error_code& ec) {
    if (context->filesize == 0) {
      return;
    }

    uint64_t percent = 0;
    if (context->output.good() && context->output.is_open()) {
      uint64_t offset = context->output.tellp();
      percent = (offset == -1) ? 100 : 100 * offset / context->filesize;
      SSF_LOG("ssfcp", debug, "receiving: {} {}% / {}b",
              context->GetOutputFilepath().GetString(), percent,
              context->filesize);
    } else if (context->input.good() && context->input.is_open()) {
      uint64_t offset = context->input.tellg();
      percent = (offset == -1) ? 100 : (100 * offset / context->filesize);

      SSF_LOG("ssfcp", debug, "sending: {} {}% / {}b",
              context->GetInputFilepath().GetString(),
              percent, context->filesize);
    }
  };
  auto on_file_copied = [session, &copy_ec](
      ssf::services::copy::CopyContext* context,
      const boost::system::error_code& ec) {
    if (!ec) {
      if (!session->is_stopped() &&
          copy_ec.value() != ssf::services::copy::ErrorCode::kSuccess) {
        copy_ec.assign(ssf::services::copy::ErrorCode::kFilesPartiallyCopied,
                       ssf::services::copy::get_copy_category());
      }
      SSF_LOG("ssfcp", info, "data copied from {} to {} ({})",
              (context->is_stdin_input ? "stdin" : context->GetInputFilepath().GetString()),
              context->GetOutputFilepath().GetString(), ec.message());
    } else {
      if (!session->is_stopped()) {
        SSF_LOG("ssfcp", warn, "data copied from {} to {} ({})",
                (context->is_stdin_input ? "stdin" : context->GetInputFilepath().GetString()),
                context->GetOutputFilepath().GetString(), ec.message());
      }
    }
  };
  auto on_copy_finished = [session, &client, &copy_ec](
      uint64_t files_count, uint64_t errors_count,
      const boost::system::error_code& ec) {
    if (!ec) {
      SSF_LOG("ssfcp", info, "copy finished {} ({}/{} files copied)",
              ec.message(), (files_count - errors_count), files_count);
    } else {
      SSF_LOG("ssfcp", warn, "copy finished {} ({}/{} files copied)",
              ec.message(), (files_count - errors_count), files_count);
    }
    // save copy ec
    copy_ec = ec;

    boost::system::error_code stop_ec;
    client.Stop(stop_ec);
  };
  copy_client = CopyClient::Create(session, on_file_status, on_file_copied,
                                   on_copy_finished, start_ec);
  if (start_ec) {
    SSF_LOG("ssfcp", error, "cannot create copy client");
    return nullptr;
  }

  if (from_client_to_server) {
    copy_client->AsyncCopyToServer(req);
  } else {
    copy_client->AsyncCopyFromServer(req);
  }

  return copy_client;
}

ext: cpp

max_stars_repo_name: ZhiQiAnSecFork/ssf

max_issues_repo_name: ZhiQiAnSecFork/ssf

max_forks_repo_name: ZhiQiAnSecFork/ssf


text:
#include <NTL/thread.h>

#ifdef NTL_THREADS

#include <thread>
#include <sstream>

#endif

NTL_START_IMPL

const string& CurrentThreadID()
{
   NTL_THREAD_LOCAL static string ID;
   NTL_THREAD_LOCAL static bool initialized = false;

   if (!initialized) {
#ifdef NTL_THREADS
      stringstream ss;
      ss << this_thread::get_id();
      ID = ss.str();
#else
      ID = "0";
#endif
      initialized = true;
   }

   return ID;
}

NTL_END_IMPL

max_stars_repo_name: Brainloop-Security/secret-sharing

max_issues_repo_name: Brainloop-Security/secret-sharing

max_forks_repo_name: Brainloop-Security/secret-sharing


text:
/**
 *  Copyright (C) 2021 FISCO BCOS.
 *  SPDX-License-Identifier: Apache-2.0
 *  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.
 *
 * @brief configuration for the node
 * @file NodeConfig.cpp
 * @author: yujiechen
 * @date 2021-06-10
 */
#include "NodeConfig.h"
#include "bcos-framework/interfaces/consensus/ConsensusNode.h"
#include "bcos-framework/interfaces/ledger/LedgerTypeDef.h"
#include "bcos-framework/interfaces/protocol/ServiceDesc.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>

#define MAX_BLOCK_LIMIT 5000

using namespace bcos;
using namespace bcos::crypto;
using namespace bcos::tool;
using namespace bcos::consensus;
using namespace bcos::ledger;
using namespace bcos::protocol;

NodeConfig::NodeConfig(KeyFactory::Ptr _keyFactory)
  : m_keyFactory(_keyFactory), m_ledgerConfig(std::make_shared<LedgerConfig>())
{}

void NodeConfig::loadConfig(boost::property_tree::ptree const& _pt)
{
    loadChainConfig(_pt);
    loadCertConfig(_pt);
    loadRpcConfig(_pt);
    loadGatewayConfig(_pt);
    loadTxPoolConfig(_pt);

    loadSecurityConfig(_pt);
    loadSealerConfig(_pt);
    loadConsensusConfig(_pt);
    loadStorageConfig(_pt);
    loadExecutorConfig(_pt);
}

void NodeConfig::loadGenesisConfig(boost::property_tree::ptree const& _genesisConfig)
{
    loadLedgerConfig(_genesisConfig);
}

std::string NodeConfig::getServiceName(boost::property_tree::ptree const& _pt,
    std::string const& _configSection, std::string const& _objName,
    std::string const& _defaultValue, bool _require)
{
    auto serviceName = _pt.get<std::string>(_configSection, _defaultValue);
    if (!_require)
    {
        return serviceName;
    }
    checkService(_configSection, serviceName);
    return getPrxDesc(serviceName, _objName);
}

void NodeConfig::loadRpcServiceConfig(boost::property_tree::ptree const& _pt)
{
    // rpc service name
    m_rpcServiceName = getServiceName(_pt, "service.rpc", RPC_SERVANT_NAME);
    NodeConfig_LOG(INFO) << LOG_DESC("loadServiceConfig")
                         << LOG_KV("rpcServiceName", m_rpcServiceName);
}

void NodeConfig::loadGatewayServiceConfig(boost::property_tree::ptree const& _pt)
{
    // gateway service name
    m_gatewayServiceName = getServiceName(_pt, "service.gateway", GATEWAY_SERVANT_NAME);
    NodeConfig_LOG(INFO) << LOG_DESC("loadServiceConfig")
                         << LOG_KV("gatewayServiceName", m_gatewayServiceName);
}
void NodeConfig::loadServiceConfig(boost::property_tree::ptree const& _pt)
{
    loadGatewayServiceConfig(_pt);
    loadRpcServiceConfig(_pt);
}

void NodeConfig::loadNodeServiceConfig(
    std::string const& _nodeID, boost::property_tree::ptree const& _pt)
{
    auto nodeName = _pt.get<std::string>("service.node_name", "");
    if (nodeName.size() == 0)
    {
        nodeName = _nodeID;
    }
    if (!isalNumStr(nodeName))
    {
        BOOST_THROW_EXCEPTION(
            InvalidConfig() << errinfo_comment("The node name must be number or digit"));
    }
    m_nodeName = nodeName;
    m_schedulerServiceName = getServiceName(_pt, "service.scheduler", SCHEDULER_SERVANT_NAME,
        getDefaultServiceName(nodeName, SCHEDULER_SERVICE_NAME), false);
    m_txpoolServiceName = getServiceName(_pt, "service.txpool", TXPOOL_SERVANT_NAME,
        getDefaultServiceName(nodeName, TXPOOL_SERVICE_NAME), false);
    m_consensusServiceName = getServiceName(_pt, "service.consensus", CONSENSUS_SERVANT_NAME,
        getDefaultServiceName(nodeName, CONSENSUS_SERVICE_NAME), false);
    m_frontServiceName = getServiceName(_pt, "service.front", FRONT_SERVANT_NAME,
        getDefaultServiceName(nodeName, FRONT_SERVICE_NAME), false);
    m_executorServiceName = getServiceName(_pt, "service.executor", EXECUTOR_SERVANT_NAME,
        getDefaultServiceName(nodeName, EXECUTOR_SERVICE_NAME), false);

    NodeConfig_LOG(INFO) << LOG_DESC("load node service") << LOG_KV("nodeName", m_nodeName)
                         << LOG_KV("schedulerServiceName", m_schedulerServiceName)
                         << LOG_KV("txpoolServiceName", m_txpoolServiceName)
                         << LOG_KV("consensusServiceName", m_consensusServiceName)
                         << LOG_KV("frontServiceName", m_frontServiceName)
                         << LOG_KV("executorServiceName", m_executorServiceName);
}
void NodeConfig::checkService(std::string const& _serviceType, std::string const& _serviceName)
{
    if (_serviceName.size() == 0)
    {
        BOOST_THROW_EXCEPTION(
            InvalidConfig() << errinfo_comment("Must set service name for " + _serviceType + "!"));
    }
    std::vector<std::string> serviceNameList;
    boost::split(serviceNameList, _serviceName, boost::is_any_of("."));
    std::string errorMsg =
        "Must set service name in format of application_name.server_name with only include letters "
        "and numbers for " +
        _serviceType + ", invalid config now is:" + _serviceName;
    if (serviceNameList.size() != 2)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(errorMsg));
    }
    for (auto serviceName : serviceNameList)
    {
        if (!isalNumStr(serviceName))
        {
            BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(errorMsg));
        }
    }
}

void NodeConfig::loadRpcConfig(boost::property_tree::ptree const& _pt)
{
    /*
    [rpc]
        listen_ip=0.0.0.0
        listen_port=30300
        thread_count=16
        sm_ssl=false
        disable_ssl=false
    */
    std::string listenIP = _pt.get<std::string>("rpc.listen_ip", "0.0.0.0");
    int listenPort = _pt.get<int>("rpc.listen_port", 20200);
    int threadCount = _pt.get<int>("rpc.thread_count", 8);
    bool smSsl = _pt.get<bool>("rpc.sm_ssl", false);
    bool disableSsl = _pt.get<bool>("rpc.disable_ssl", false);

    m_rpcListenIP = listenIP;
    m_rpcListenPort = listenPort;
    m_rpcThreadPoolSize = threadCount;
    m_rpcDisableSsl = disableSsl;
    m_rpcSmSsl = smSsl;

    NodeConfig_LOG(INFO) << LOG_DESC("loadRpcConfig") << LOG_KV("listenIP", listenIP)
                         << LOG_KV("listenPort", listenPort) << LOG_KV("listenPort", listenPort)
                         << LOG_KV("smSsl", smSsl) << LOG_KV("disableSsl", disableSsl);
}

void NodeConfig::loadGatewayConfig(boost::property_tree::ptree const& _pt)
{
    /*
    [p2p]
    listen_ip=0.0.0.0
    listen_port=30300
    sm_ssl=false
    nodes_path=./
    nodes_file=nodes.json
    */
    std::string listenIP = _pt.get<std::string>("p2p.listen_ip", "0.0.0.0");
    int listenPort = _pt.get<int>("p2p.listen_port", 30300);
    std::string nodesDir = _pt.get<std::string>("p2p.nodes_path", "./");
    std::string nodesFile = _pt.get<std::string>("p2p.nodes_file", "nodes.json");
    bool smSsl = _pt.get<bool>("p2p.sm_ssl", false);

    m_p2pListenIP = listenIP;
    m_p2pListenPort = listenPort;
    m_p2pNodeDir = nodesDir;
    m_p2pSmSsl = smSsl;
    m_p2pNodeFileName = nodesFile;

    NodeConfig_LOG(INFO) << LOG_DESC("loadGatewayConfig") << LOG_KV("listenIP", listenIP)
                         << LOG_KV("listenPort", listenPort) << LOG_KV("listenPort", listenPort)
                         << LOG_KV("smSsl", smSsl) << LOG_KV("nodesFile", nodesFile);
}

void NodeConfig::loadCertConfig(boost::property_tree::ptree const& _pt)
{
    /*
    [cert]
      ; directory the certificates located in
      ca_path=./
      ; the ca certificate file
      ca_cert=ca.crt
      ; the node private key file
      node_key=ssl.key
      ; the node certificate file
      node_cert=ssl.crt

    or

    [cert]
    ; directory the certificates located in
    ca_path=./
    ; the ca certificate file
    sm_ca_cert=sm_ca.crt
    ; the node private key file
    sm_node_key=sm_ssl.key
    ; the node certificate file
    sm_node_cert=sm_ssl.crt
    ; the node private key file
    sm_ennode_key=sm_enssl.key
    ; the node certificate file
    sm_ennode_cert=sm_enssl.crt
    */

    // load sm cert
    m_certPath = _pt.get<std::string>("cert.ca_path", "./");

    std::string smCaCertFile =
        m_certPath + "/" + _pt.get<std::string>("cert.sm_ca_cert", "sm_ca.crt");
    std::string smNodeCertFile =
        m_certPath + "/" + _pt.get<std::string>("cert.sm_node_cert", "sm_ssl.crt");
    std::string smNodeKeyFile =
        m_certPath + "/" + _pt.get<std::string>("cert.sm_node_key", "sm_ssl.key");
    std::string smEnNodeCertFile =
        m_certPath + "/" + _pt.get<std::string>("cert.sm_ennode_cert", "sm_enssl.crt");
    std::string smEnNodeKeyFile =
        m_certPath + "/" + _pt.get<std::string>("cert.sm_ennode_key", "sm_enssl.key");

    m_smCaCert = smCaCertFile;
    m_smNodeCert = smNodeCertFile;
    m_smNodeKey = smNodeKeyFile;
    m_enSmNodeCert = smEnNodeCertFile;
    m_enSmNodeKey = smEnNodeKeyFile;

    NodeConfig_LOG(INFO) << LOG_DESC("loadCertConfig") << LOG_KV("ca_path", m_certPath)
                         << LOG_KV("sm_ca_cert", smCaCertFile)
                         << LOG_KV("sm_node_cert", smNodeCertFile)
                         << LOG_KV("sm_node_key", smNodeKeyFile)
                         << LOG_KV("sm_ennode_cert", smEnNodeCertFile)
                         << LOG_KV("sm_ennode_key", smEnNodeKeyFile);

    // load cert
    std::string caCertFile = m_certPath + "/" + _pt.get<std::string>("cert.ca_cert", "ca.crt");
    std::string nodeCertFile = m_certPath + "/" + _pt.get<std::string>("cert.node_cert", "ssl.crt");
    std::string nodeKeyFile = m_certPath + "/" + _pt.get<std::string>("cert.node_key", "ssl.key");

    m_caCert = caCertFile;
    m_nodeCert = nodeCertFile;
    m_nodeKey = nodeKeyFile;

    NodeConfig_LOG(INFO) << LOG_DESC("loadCertConfig") << LOG_KV("ca_path", m_certPath)
                         << LOG_KV("ca_cert", caCertFile) << LOG_KV("node_cert", nodeCertFile)
                         << LOG_KV("node_key", nodeKeyFile);
}

// load the txpool related params
void NodeConfig::loadTxPoolConfig(boost::property_tree::ptree const& _pt)
{
    m_txpoolLimit = checkAndGetValue(_pt, "txpool.limit", "15000");
    if (m_txpoolLimit <= 0)
    {
        BOOST_THROW_EXCEPTION(
            InvalidConfig() << errinfo_comment("Please set txpool.limit to positive !"));
    }
    m_notifyWorkerNum = checkAndGetValue(_pt, "txpool.notify_worker_num", "2");
    if (m_notifyWorkerNum <= 0)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Please set txpool.notify_worker_num to positive !"));
    }

    m_verifierWorkerNum = checkAndGetValue(_pt, "txpool.verify_worker_num", "2");
    if (m_verifierWorkerNum <= 0)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Please set txpool.verify_worker_num to positive !"));
    }
    NodeConfig_LOG(INFO) << LOG_DESC("loadTxPoolConfig") << LOG_KV("txpoolLimit", m_txpoolLimit)
                         << LOG_KV("notifierWorkers", m_notifyWorkerNum)
                         << LOG_KV("verifierWorkers", m_verifierWorkerNum);
}

void NodeConfig::loadChainConfig(boost::property_tree::ptree const& _pt)
{
    m_smCryptoType = _pt.get<bool>("chain.sm_crypto", false);
    m_groupId = _pt.get<std::string>("chain.group_id", "group");
    m_chainId = _pt.get<std::string>("chain.chain_id", "chain");
    if (!isalNumStr(m_chainId))
    {
        BOOST_THROW_EXCEPTION(
            InvalidConfig() << errinfo_comment("The chainId must be number or digit"));
    }
    m_blockLimit = checkAndGetValue(_pt, "chain.block_limit", "1000");
    if (m_blockLimit <= 0 || m_blockLimit > MAX_BLOCK_LIMIT)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Please set chain.block_limit to positive and less than " +
                                  std::to_string(MAX_BLOCK_LIMIT) + " !"));
    }
    NodeConfig_LOG(INFO) << LOG_DESC("loadChainConfig") << LOG_KV("smCrypto", m_smCryptoType)
                         << LOG_KV("chainId", m_chainId) << LOG_KV("groupId", m_groupId)
                         << LOG_KV("blockLimit", m_blockLimit);
}

void NodeConfig::loadSecurityConfig(boost::property_tree::ptree const& _pt)
{
    m_privateKeyPath = _pt.get<std::string>("security.private_key_path", "node.pem");
    NodeConfig_LOG(INFO) << LOG_DESC("loadSecurityConfig")
                         << LOG_KV("privateKeyPath", m_privateKeyPath);
}

void NodeConfig::loadSealerConfig(boost::property_tree::ptree const& _pt)
{
    m_minSealTime = checkAndGetValue(_pt, "consensus.min_seal_time", "500");
    if (m_minSealTime <= 0 || m_minSealTime > 3000)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Please set consensus.min_seal_time between 1 and 3000!"));
    }
    NodeConfig_LOG(INFO) << LOG_DESC("loadSealerConfig") << LOG_KV("minSealTime", m_minSealTime);
}

void NodeConfig::loadStorageConfig(boost::property_tree::ptree const& _pt)
{
    m_storagePath = _pt.get<std::string>("storage.data_path", "data/" + m_groupId);
    m_enableLRUCacheStorage = _pt.get<bool>("storage.enable_cache", true);
    m_cacheSize = _pt.get<ssize_t>("storage.cache_size", DEFAULT_CACHE_SIZE);
    NodeConfig_LOG(INFO) << LOG_DESC("loadStorageConfig") << LOG_KV("storagePath", m_storagePath)
                         << LOG_KV("enableLRUCacheStorage", m_enableLRUCacheStorage);
}

void NodeConfig::loadConsensusConfig(boost::property_tree::ptree const& _pt)
{
    m_checkPointTimeoutInterval = checkAndGetValue(_pt, "consensus.checkpoint_timeout", "3000");
    if (m_checkPointTimeoutInterval < 3000)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Please set consensus.checkpoint_timeout to no less than " +
                                  std::to_string(3000) + "ms!"));
    }
    NodeConfig_LOG(INFO) << LOG_DESC("loadConsensusConfig")
                         << LOG_KV("checkPointTimeoutInterval", m_checkPointTimeoutInterval);
}

void NodeConfig::loadLedgerConfig(boost::property_tree::ptree const& _genesisConfig)
{
    // consensus type
    m_consensusType = _genesisConfig.get<std::string>("consensus.consensus_type", "pbft");
    // blockTxCountLimit
    auto blockTxCountLimit =
        checkAndGetValue(_genesisConfig, "consensus.block_tx_count_limit", "1000");
    if (blockTxCountLimit <= 0)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Please set consensus.block_tx_count_limit to positive!"));
    }
    m_ledgerConfig->setBlockTxCountLimit(blockTxCountLimit);
    // txGasLimit
    auto txGasLimit = checkAndGetValue(_genesisConfig, "tx.gas_limit", "3000000000");
    if (txGasLimit <= TX_GAS_LIMIT_MIN)
    {
        BOOST_THROW_EXCEPTION(
            InvalidConfig() << errinfo_comment(
                "Please set tx.gas_limit to more than " + std::to_string(TX_GAS_LIMIT_MIN) + " !"));
    }

    m_txGasLimit = txGasLimit;
    // sealerList
    auto consensusNodeList = parseConsensusNodeList(_genesisConfig, "consensus", "node.");
    if (!consensusNodeList || consensusNodeList->empty())
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment("Must set sealerList!"));
    }
    m_ledgerConfig->setConsensusNodeList(*consensusNodeList);

    // leaderSwitchPeriod
    auto consensusLeaderPeriod = checkAndGetValue(_genesisConfig, "consensus.leader_period", "1");
    if (consensusLeaderPeriod <= 0)
    {
        BOOST_THROW_EXCEPTION(
            InvalidConfig() << errinfo_comment("Please set consensus.leader_period to positive!"));
    }
    m_ledgerConfig->setLeaderSwitchPeriod(consensusLeaderPeriod);
    NodeConfig_LOG(INFO) << LOG_DESC("loadLedgerConfig")
                         << LOG_KV("consensus_type", m_consensusType)
                         << LOG_KV("block_tx_count_limit", m_ledgerConfig->blockTxCountLimit())
                         << LOG_KV("gas_limit", m_txGasLimit)
                         << LOG_KV("leader_period", m_ledgerConfig->leaderSwitchPeriod())
                         << LOG_KV("minSealTime", m_minSealTime);
    generateGenesisData();
}

ConsensusNodeListPtr NodeConfig::parseConsensusNodeList(boost::property_tree::ptree const& _pt,
    std::string const& _sectionName, std::string const& _subSectionName)
{
    if (!_pt.get_child_optional(_sectionName))
    {
        NodeConfig_LOG(DEBUG) << LOG_DESC("parseConsensusNodeList return for empty config")
                              << LOG_KV("sectionName", _sectionName);
        return nullptr;
    }
    auto nodeList = std::make_shared<ConsensusNodeList>();
    for (auto const& it : _pt.get_child(_sectionName))
    {
        if (it.first.find(_subSectionName) != 0)
        {
            continue;
        }
        std::string data = it.second.data();
        std::vector<std::string> nodeInfo;
        boost::split(nodeInfo, data, boost::is_any_of(":"));
        if (nodeInfo.size() == 0)
        {
            BOOST_THROW_EXCEPTION(
                InvalidConfig() << errinfo_comment(
                    "Uninitialized nodeInfo, key: " + it.first + ", value: " + data));
        }
        std::string nodeId = nodeInfo[0];
        boost::to_lower(nodeId);
        int64_t weight = 1;
        if (nodeInfo.size() == 2)
        {
            auto& weightInfoStr = nodeInfo[1];
            boost::trim(weightInfoStr);
            weight = boost::lexical_cast<int64_t>(weightInfoStr);
        }
        if (weight <= 0)
        {
            BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                      "Please set weight for " + nodeId + " to positive!"));
        }
        auto consensusNode = std::make_shared<ConsensusNode>(
            m_keyFactory->createKey(*fromHexString(nodeId)), weight);
        NodeConfig_LOG(INFO) << LOG_BADGE("parseConsensusNodeList")
                             << LOG_KV("sectionName", _sectionName) << LOG_KV("nodeId", nodeId)
                             << LOG_KV("weight", weight);
        nodeList->push_back(consensusNode);
    }
    NodeConfig_LOG(INFO) << LOG_BADGE("parseConsensusNodeList")
                         << LOG_KV("totalNodesSize", nodeList->size());
    return nodeList;
}

void NodeConfig::generateGenesisData()
{
    std::stringstream s;
    s << m_ledgerConfig->blockTxCountLimit() << "-" << m_ledgerConfig->leaderSwitchPeriod() << "-"
      << m_txGasLimit << "-";
    for (auto node : m_ledgerConfig->consensusNodeList())
    {
        s << *toHexString(node->nodeID()->data()) << "," << node->weight() << ";";
    }
    m_genesisData = s.str();
    NodeConfig_LOG(INFO) << LOG_BADGE("generateGenesisData")
                         << LOG_KV("genesisData", m_genesisData);
}

void NodeConfig::loadExecutorConfig(boost::property_tree::ptree const& _pt)
{
    m_isWasm = _pt.get<bool>("executor.is_wasm", false);
    m_isAuthCheck = _pt.get<bool>("executor.is_auth_check", false);
    m_authAdminAddress = _pt.get<std::string>("executor.auth_admin_account", "");
    NodeConfig_LOG(INFO) << LOG_DESC("loadExecutorConfig") << LOG_KV("isWasm", m_isWasm);
    NodeConfig_LOG(INFO) << LOG_DESC("loadExecutorConfig") << LOG_KV("isAuthCheck", m_isAuthCheck);
    NodeConfig_LOG(INFO) << LOG_DESC("loadExecutorConfig")
                         << LOG_KV("authAdminAccount", m_authAdminAddress);
}

// Note: make sure the consensus param checker is consistent with the precompiled param checker
int64_t NodeConfig::checkAndGetValue(boost::property_tree::ptree const& _pt,
    std::string const& _key, std::string const& _defaultValue)
{
    auto value = _pt.get<std::string>(_key, _defaultValue);
    try
    {
        return boost::lexical_cast<int64_t>(value);
    }
    catch (std::exception const& e)
    {
        BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment(
                                  "Invalid value " + value + " for configuration " + _key +
                                  ", please set the value with a valid number"));
    }
}

max_stars_repo_name: contropist/FISCO-BCOS

max_issues_repo_name: contropist/FISCO-BCOS

max_forks_repo_name: contropist/FISCO-BCOS


text:
// Copyright (C) 2016 Gideon May (gideon@borges.xyz)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.

#ifndef  PYOSG_STATE_ATTRIBUTE
#define  PYOSG_STATE_ATTRIBUTE 1

#include <osg/ref_ptr>
#include <osg/StateAttribute>

#include <boost/python/class.hpp>
#include <boost/python/return_value_policy.hpp>
#include "held_ptr.hpp"

namespace PyOSG {
using namespace boost::python;

typedef class_<osg::StateAttribute, osg::ref_ptr<osg::StateAttribute>, bases<osg::Object>, boost::noncopyable > class_StateAttribute;
extern class_StateAttribute * StateAttributeClass;

template <class F> void register_castStateAttribute(const char * name, F f)
{
    if (StateAttributeClass) {
        StateAttributeClass->def(name, f, boost::python::return_value_policy<manage_osg_object>());
    }
}
}

#define DEFINE_STATEATTRIBUTE_CAST(NAME)    osg::NAME * as##NAME(osg::StateAttribute * self) { return dynamic_cast<osg::NAME *>(self); }
#define REGISTER_STATEATTRIBUTE_CAST(NAME)  register_castStateAttribute("as" #NAME, &as##NAME);

#endif

ext: hpp

max_stars_repo_name: gideonmay/PyOSG

max_issues_repo_name: gideonmay/PyOSG

max_forks_repo_name: gideonmay/PyOSG


text:
//==============================================================================
//         Copyright 2003 - 2011 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_BOOLEAN_FUNCTIONS_SIMD_COMMON_MASK2LOGICAL_HPP_INCLUDED
#define BOOST_SIMD_BOOLEAN_FUNCTIONS_SIMD_COMMON_MASK2LOGICAL_HPP_INCLUDED

#include <boost/simd/boolean/functions/mask2logical.hpp>
#include <boost/simd/include/functions/simd/bitwise_cast.hpp>
#include <boost/simd/sdk/meta/as_logical.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/sizeof.hpp>
#include <boost/simd/operator/functions/details/assert_utils.hpp>
#include <boost/assert.hpp>

namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION_IF( boost::simd::tag::mask2logical_, tag::cpu_, (A0)(X)
                            , (mpl::equal_to< mpl::sizeof_<A0>, mpl::sizeof_<typename simd::meta::as_logical<A0>::type> >)
                            , ((simd_< arithmetic_<A0>, X >))
                            )
  {
    typedef typename meta::as_logical<A0>::type ltype;
    typedef typename dispatch::meta::call<tag::bitwise_cast_(A0 const&, dispatch::meta::as_<ltype>)>::type result_type;
    BOOST_SIMD_FUNCTOR_CALL(1)
    {
      BOOST_ASSERT_MSG(assert_is_mask(a0), "Argument to mask2logical is not a valid logical mask");
      return bitwise_cast<ltype>(a0);
    }
  };
} } }

#endif


text:
#include "stdafx.h"
#include "blogger.h"
#include "LuaNode.h"
#include "luanode_module_api.h"
#include <boost/bind.hpp>

static LuaNodeModuleInterface interface;

static int postbackCallback = LUA_NOREF;

//////////////////////////////////////////////////////////////////////////
///
static void HandleModuleCallback(const char* module_name, const char* function_name, int key, void* userdata) {
	CLuaVM& vm = LuaNode::GetLuaVM();
	lua_State* L = vm;

	if(postbackCallback == LUA_NOREF) {
		lua_getfield(L, LUA_GLOBALSINDEX, "process");
		lua_getfield(L, -1, "_postBackToModule");
		postbackCallback = luaL_ref(L, LUA_REGISTRYINDEX);
		lua_pop(L, 1);
	}
	// I'd previously stored the callback in the registry
	lua_rawgeti(vm, LUA_REGISTRYINDEX, postbackCallback);

	lua_pushstring(L, module_name);
	lua_pushstring(L, function_name);
	lua_pushinteger(L, key);
	lua_pushlightuserdata(L, userdata);
	vm.call(4, LUA_MULTRET);

	lua_settop(vm, 0);
};

//////////////////////////////////////////////////////////////////////////
///
static bool LuaNode_Post (const char* module_name, const char* function_name, int key, void* userdata) {
	LogDebug("LuaNode_Post: module name: '%s', function name: '%s', key: '%d'",
		module_name, function_name, key);

	LuaNode::GetIoService().post(
		boost::bind(HandleModuleCallback, module_name, function_name, key, userdata)
		);
	return true;
}

//////////////////////////////////////////////////////////////////////////
///
void LuaNode::ModuleApi::Register(lua_State* L, int table) {
	interface.interface_version = 1;
	interface.luanode_post = LuaNode_Post;

	LuaNodeModuleInterface* pInterf = (LuaNodeModuleInterface*)lua_newuserdata(L, sizeof(LuaNodeModuleInterface));
	memcpy(pInterf, &interface, sizeof(LuaNodeModuleInterface));

	lua_setfield(L, table, "module_api");
}

max_stars_repo_name: mkottman/LuaNode

max_issues_repo_name: mkottman/LuaNode

max_forks_repo_name: mkottman/LuaNode


text:
/*
 * dumptree.cpp
 *
 *  Created on: Feb 24, 2014
 *      Author: oleg
 */

#include <Poco/Util/Application.h>
#include <Poco/Util/Option.h>
#include <Poco/Util/OptionSet.h>
#include <Poco/Util/HelpFormatter.h>
#include <Poco/Util/AbstractConfiguration.h>
#include <Poco/AutoPtr.h>
#include <Poco/SharedLibrary.h>
#include <Poco/Exception.h>

#include <bd.h>
#include "../utils/default_block_io.h"

#include <iostream>
#include <boost/scope_exit.hpp>

using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;
using Poco::SharedLibrary;
using Poco::AutoPtr;

// ---------------------------------------------------------------------------------------

#define DT_EXEC_CHECK(plugin, func, msg) {\
    bd_result res = plugin.func; \
    if (!BD_SUCCEED(res)) {\
        char buf[1024]; \
        plugin.result_message(res, (bd_string) buf, sizeof(buf)); \
        _errorMessage = Poco::format("Error:\n  %s\n  %s", std::string(msg), std::string(buf)); \
        return res; \
    } }

#define DT_EXEC_CHECK_F(plugin, func, msg, ...) {\
    bd_result res = plugin.func; \
    if (!BD_SUCCEED(res)) {\
        char buf[1024]; \
        plugin.result_message(res, (bd_string) buf, sizeof(buf)); \
        std::string err_msg = Poco::format(msg, __VA_ARGS__); \
        _errorMessage = Poco::format("Error:\n  %s\n  %s", err_msg, std::string(buf)); \
        return res; \
    } }

class DumpTreeApp: public Application
{
public:
    DumpTreeApp() : _helpRequested(false), _showPluginInfo(false), _pluginDir("./")
    {
    }

protected:
    void initialize(Application& self)
    {
        loadConfiguration(); // load default configuration files, if present
        Application::initialize(self);
        // add your own initialization code here
    }

    void uninitialize()
    {
        // add your own uninitialization code here
        Application::uninitialize();
    }

    void reinitialize(Application& self)
    {
        Application::reinitialize(self);
        // add your own reinitialization code here
    }

    void defineOptions(OptionSet& options)
    {
        Application::defineOptions(options);

        options.addOption(
            Option("help", "h", "display help information on command line arguments")
                .required(false)
                .repeatable(false)
                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handleHelp)));

        options.addOption(
            Option("plugin", "p", "specify plugin name")
                .required(true)
                .repeatable(false)
                .argument("plugin")
                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handlePluginName)));

        options.addOption(
            Option("plugin-dir", "P", "specify plugins folder")
                .required(false)
                .repeatable(false)
                .argument("dir")
                .binding("plugin.dir")
                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handlePluginDir)));

        options.addOption(
            Option("script", "s", "specify script file")
                .required(false)
                .repeatable(false)
                .argument("script")
                .binding("plugin.script")
                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handleScriptFile)));

        options.addOption(
            Option("plugin-info", "i", "show plugin info")
                .required(false)
                .repeatable(false)
                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handlePluginInfo)));

//        options.addOption(
//            Option("define", "D", "define a configuration property")
//                .required(false)
//                .repeatable(true)
//                .argument("name=value")
//                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handleDefine)));

        options.addOption(
            Option("config-file", "f", "load configuration data from a file")
                .required(false)
                .repeatable(true)
                .argument("file")
                .callback(OptionCallback<DumpTreeApp>(this, &DumpTreeApp::handleConfig)));

//        options.addOption(
//            Option("bind", "b", "bind option value to test.property")
//                .required(false)
//                .repeatable(false)
//                .argument("value")
//                .binding("test.property"));
    }

    void handleHelp(const std::string& name, const std::string& value)
    {
        _helpRequested = true;
        displayHelp();
        stopOptionsProcessing();
    }

    void handlePluginName(const std::string& name, const std::string& value)
    {
        _pluginName = value;
    }

    void handlePluginDir(const std::string& name, const std::string& value)
    {
        _pluginDir = value;
    }

    void handleScriptFile(const std::string& name, const std::string& value)
    {
        _scriptFile = value;
    }

    void handlePluginInfo(const std::string& name, const std::string& value)
    {
        _showPluginInfo = true;
    }

//    void handleDefine(const std::string& name, const std::string& value)
//    {
//        defineProperty(value);
//    }

    void handleConfig(const std::string& name, const std::string& value)
    {
        loadConfiguration(value);
    }

    void displayHelp()
    {
        HelpFormatter helpFormatter(options());
        helpFormatter.setCommand(commandName());
        helpFormatter.setUsage("OPTIONS file1 [file2 ...]");
        helpFormatter.setHeader("Tool to print out generated binary tree.");
        helpFormatter.format(std::cout);
    }

//    void defineProperty(const std::string& def)
//    {
//        std::string name;
//        std::string value;
//        std::string::size_type pos = def.find('=');
//        if (pos != std::string::npos)
//        {
//            name.assign(def, 0, pos);
//            value.assign(def, pos + 1, def.length() - pos);
//        }
//        else name = def;
//        config().setString(name, value);
//    }

    // ------------------------------------------------------------------------------
    struct PluginInfo
    {
        std::string pluginName;
        bd_plugin plugin;
        bool isScripter;
        std::vector<std::string> templates;
    };

    void loadPluginFunctions(SharedLibrary& pluginLibrary, bd_plugin& plugin)
    {
        plugin.result_message    = (bd_result_message_t)    pluginLibrary.getSymbol("bd_result_message");
        plugin.initialize_plugin = (bd_initialize_plugin_t) pluginLibrary.getSymbol("bd_initialize_plugin");
        plugin.finalize_plugin   = (bd_finalize_plugin_t)   pluginLibrary.getSymbol("bd_finalize_plugin");
        plugin.template_name     = (bd_template_name_t)     pluginLibrary.getSymbol("bd_template_name");
        plugin.apply_template    = (bd_apply_template_t)    pluginLibrary.getSymbol("bd_apply_template");
        plugin.free_template     = (bd_free_template_t)     pluginLibrary.getSymbol("bd_free_template");
        plugin.get_string_value  = (bd_get_string_value_t)  pluginLibrary.getSymbol("bd_get_string_value");
    }

    bd_result initializePlugin(PluginInfo& pluginInfo)
    {
        bd_char name[256];
        bd_u32 templ_count;

        DT_EXEC_CHECK(pluginInfo.plugin, initialize_plugin(name, sizeof(name), &templ_count), "Cannot initialize plugin");

        pluginInfo.pluginName = name;
        pluginInfo.isScripter = templ_count == 0;

        for (bd_u32 i = 0; i < templ_count; ++i)
        {
            DT_EXEC_CHECK_F(pluginInfo.plugin, template_name(i, name, sizeof(name)), "Cannot retrieve template name: %d", i);

            pluginInfo.templates.push_back(name);
        }

        return BD_SUCCESS;
    }

    void showPluginInfo(PluginInfo& pluginInfo)
    {
        poco_information_f1(logger(), "Name:        %s", pluginInfo.pluginName);
        poco_information_f1(logger(), "Is scripter: %b", pluginInfo.isScripter);
        poco_information_f1(logger(), "Temlates[%u]:",   pluginInfo.templates.size());

        for (std::vector<std::string>::const_iterator it = pluginInfo.templates.begin(); it != pluginInfo.templates.end(); ++it)
        {
            poco_information_f1(logger(), "    %s", *it);
        }
    }

    bd_result finalizePlugin(PluginInfo& pluginInfo)
    {
        DT_EXEC_CHECK(pluginInfo.plugin, finalize_plugin(), "Could not finalize plugin");

        return BD_SUCCESS;
    }

    bd_result applyTemplate(PluginInfo& pluginInfo, bd_default_block_io& templBlob, bd_block **block)
    {
        freeTemplate(pluginInfo, *block);

//        templBlob.dataFile.seekg(0);

        // TODO: set correct template index
        bd_u32 templIndex = 0;

        DT_EXEC_CHECK_F(pluginInfo.plugin,
                apply_template(templIndex, &templBlob, block, _scriptFile.empty() ? 0 : (bd_cstring) _scriptFile.c_str()),
                "Could not apply template %u", templIndex);

        return BD_SUCCESS;
    }

    bd_result freeTemplate(PluginInfo& pluginInfo, bd_block *block)
    {
        if (block == 0)
            return BD_SUCCESS;

        // TODO: set correct template index
        bd_u32 templIndex = 0;

        DT_EXEC_CHECK_F(pluginInfo.plugin, free_template(templIndex, block), "Could not free template %u", templIndex);

        return BD_SUCCESS;
    }

    bd_result dumpTree(std::ostream& output, bd_plugin& plugin, bd_default_block_io& templBlob, const bd_block *block, const std::string& indent = "")
    {
        if (block == 0)
        {
            output << indent << "NULL\n";
            return BD_SUCCESS;
        }

        output << indent << block->type_name << "(" << block->type << ") " << block->name;
        if (block->is_array == BD_TRUE || block->type == BD_STRING)
        {
            output << "[" << block->count << "] (" << block->elem_size << "/" << block->size << ")";

            if (is_string(block))
            {
                bd_u32 val_size = block->size + 1;
                bd_string val = new bd_char[val_size];
                BOOST_SCOPE_EXIT(&val)
                {
                    delete[] val;
                }
                BOOST_SCOPE_EXIT_END

                DT_EXEC_CHECK(plugin, get_string_value((bd_block *) block, val, val_size), "Could not get string value");

                output << ": \"" << val << "\"";
            }
        }
        else
        {
            output << "(" << block->size << "): ";

            bd_char val[100];
            DT_EXEC_CHECK(plugin, get_string_value((bd_block *) block, val, sizeof(val)), "Could not get value");

            output << val;
        }

        if (block->children.count > 0)
        {
            output << " [" << block->children.count << "]:\n";

            for (bd_u32 i = 0; i < block->children.count; ++i)
            {
                dumpTree(output, plugin, templBlob, block->children.child[i], indent + "  ");
            }
        }
        else
        {
            output << "\n";
        }

        return BD_SUCCESS;
    }

    int main(const std::vector<std::string>& args)
    {
        if (_helpRequested)
            return Application::EXIT_OK;

        if (!_showPluginInfo && args.size() == 0)
        {
            poco_warning(logger(), "At least one file to process should be specified.");
            return Application::EXIT_NOINPUT;
        }

        if (!_scriptFile.empty() && args.size() != 1)
        {
            poco_warning(logger(), "Only one plugin should be provided to load script.");
            return Application::EXIT_USAGE;
        }

        // 1. Load plugin
        std::string pluginPath = _pluginDir + "/" + _pluginName + SharedLibrary::suffix();
        SharedLibrary pluginLibrary(pluginPath);
        PluginInfo pluginInfo;

        loadPluginFunctions(pluginLibrary, pluginInfo.plugin);

        if (!BD_SUCCEED(initializePlugin(pluginInfo)))
        {
            poco_error(logger(), _errorMessage);
            return Application::EXIT_DATAERR;
        }

        if (_showPluginInfo)
        {
            showPluginInfo(pluginInfo);
        }

        auto result = Application::EXIT_OK;
        if (args.size() > 0)
        {
            // 2. Dump each file
            for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it)
            {
                bd_default_block_io templBlob(*it);
                bd_block *item = NULL;

                // 1. Apply plugin to the file
                if (!BD_SUCCEED(applyTemplate(pluginInfo, templBlob, &item)))
                {
                    poco_error(logger(), _errorMessage);
                    result = Application::EXIT_DATAERR;
                }

                // 2. Dump tree hierarchy
                if (!BD_SUCCEED(dumpTree(std::cout, pluginInfo.plugin, templBlob, item)))
                {
                    poco_error(logger(), _errorMessage);
                    return Application::EXIT_DATAERR;
                }

                // 3. Cleanup tree
                if (!BD_SUCCEED(freeTemplate(pluginInfo, item)))
                {
                    poco_error(logger(), _errorMessage);
                    return Application::EXIT_DATAERR;
                }
            }
        }

        if (!BD_SUCCEED(finalizePlugin(pluginInfo)))
        {
            poco_error(logger(), _errorMessage);
            return Application::EXIT_DATAERR;
        }

        return result;
    }

    void printProperties(const std::string& base)
    {
        AbstractConfiguration::Keys keys;
        config().keys(base, keys);
        if (keys.empty())
        {
            if (config().hasProperty(base))
            {
                std::string msg;
                msg.append(base);
                msg.append(" = ");
                msg.append(config().getString(base));
                logger().information(msg);
            }
        }
        else
        {
            for (AbstractConfiguration::Keys::const_iterator it = keys.begin(); it != keys.end(); ++it)
            {
                std::string fullKey = base;
                if (!fullKey.empty()) fullKey += '.';
                fullKey.append(*it);
                printProperties(fullKey);
            }
        }
    }

private:
    bool _helpRequested;
    bool _showPluginInfo;

    std::string _errorMessage;

    std::string _pluginName;
    std::string _pluginDir;
    std::string _scriptFile;
};

POCO_APP_MAIN(DumpTreeApp)

max_stars_repo_name: HaronK/BinaryDigger

max_issues_repo_name: HaronK/BinaryDigger

max_forks_repo_name: HaronK/BinaryDigger


text:
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

#include <boost/functional/hash.hpp>  // IWYU pragma: keep
#include <cstddef>
#include <cstdint>
#include <limits>
#include <map>
#include <memory>
#include <ostream>
#include <pup.h>
#include <tuple>
#include <unordered_set>
#include <vector>

#include "DataStructures/DataBox/DataBox.hpp"
#include "Options/Options.hpp"
#include "Parallel/AlgorithmMetafunctions.hpp"
#include "Parallel/CharmPupable.hpp"
#include "Parallel/GlobalCache.hpp"
#include "Parallel/InboxInserters.hpp"
#include "Parallel/Invoke.hpp"
#include "Parallel/Reduction.hpp"
#include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
#include "Time/Slab.hpp"
#include "Time/StepChoosers/StepChooser.hpp"
#include "Time/Tags.hpp"
#include "Time/Time.hpp"
#include "Time/TimeStepId.hpp"
#include "Time/TimeSteppers/TimeStepper.hpp"
#include "Utilities/Algorithm.hpp"
#include "Utilities/ErrorHandling/Assert.hpp"
#include "Utilities/Functional.hpp"
#include "Utilities/Gsl.hpp"
#include "Utilities/TMPL.hpp"
#include "Utilities/TaggedTuple.hpp"

/// \cond
namespace Tags {
struct DataBox;
template <typename Tag>
struct Next;
}  // namespace Tags
// IWYU pragma: no_forward_declare db::DataBox
/// \endcond

namespace ChangeSlabSize_detail {
struct NewSlabSizeInbox
    : public Parallel::InboxInserters::MemberInsert<NewSlabSizeInbox> {
  using temporal_id = int64_t;
  using type = std::map<temporal_id, std::unordered_multiset<double>>;
};

// This inbox doesn't receive any data, it just counts messages (using
// the size of the multiset).  Whenever a message is sent to the
// NewSlabSizeInbox, another message is sent here synchronously, so
// the count here is the number of messages we expect in the
// NewSlabSizeInbox.
struct NumberOfExpectedMessagesInbox
    : public Parallel::InboxInserters::MemberInsert<
          NumberOfExpectedMessagesInbox> {
  using temporal_id = int64_t;
  using NoData = std::tuple<>;
  using type = std::map<temporal_id,
                        std::unordered_multiset<NoData, boost::hash<NoData>>>;
};

struct StoreNewSlabSize {
  template <typename ParallelComponent, typename DbTags, typename Metavariables,
            typename ArrayIndex>
  static void apply(const db::DataBox<DbTags>& /*box*/,
                    Parallel::GlobalCache<Metavariables>& cache,
                    const ArrayIndex& array_index, const int64_t slab_number,
                    const double slab_size) {
    Parallel::receive_data<ChangeSlabSize_detail::NewSlabSizeInbox>(
        *Parallel::get_parallel_component<ParallelComponent>(cache)[array_index]
             .ckLocal(),
        slab_number, slab_size);
  }
};
}  // namespace ChangeSlabSize_detail

namespace Actions {
/// \ingroup ActionsGroup
/// \ingroup TimeGroup
/// Adjust the slab size based on previous executions of
/// Events::ChangeSlabSize
///
/// Uses:
/// - GlobalCache:
///   - Tags::TimeStepperBase
/// - DataBox:
///   - Tags::HistoryEvolvedVariables
///   - Tags::TimeStep
///   - Tags::TimeStepId
///
/// DataBox changes:
/// - Adds: nothing
/// - Removes: nothing
/// - Modifies:
///   - Tags::Next<Tags::TimeStepId>
///   - Tags::TimeStep
///   - Tags::TimeStepId
struct ChangeSlabSize {
  using inbox_tags =
      tmpl::list<ChangeSlabSize_detail::NumberOfExpectedMessagesInbox,
                 ChangeSlabSize_detail::NewSlabSizeInbox>;

  template <typename DbTags, typename... InboxTags, typename Metavariables,
            typename ArrayIndex, typename ActionList,
            typename ParallelComponent>
  static std::tuple<db::DataBox<DbTags>&&, Parallel::AlgorithmExecution> apply(
      db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& inboxes,
      const Parallel::GlobalCache<Metavariables>& /*cache*/,
      const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
      const ParallelComponent* const /*meta*/) {
    const auto& time_step_id = db::get<::Tags::TimeStepId>(box);
    if (not time_step_id.is_at_slab_boundary()) {
      return {std::move(box), Parallel::AlgorithmExecution::Continue};
    }

    auto& message_count_inbox =
        tuples::get<ChangeSlabSize_detail::NumberOfExpectedMessagesInbox>(
            inboxes);
    if (message_count_inbox.empty() or
        message_count_inbox.begin()->first != time_step_id.slab_number()) {
      return {std::move(box), Parallel::AlgorithmExecution::Continue};
    }

    auto& new_slab_size_inbox =
        tuples::get<ChangeSlabSize_detail::NewSlabSizeInbox>(inboxes);

    const auto slab_number = time_step_id.slab_number();
    const auto number_of_changes = [&slab_number](const auto& inbox) -> size_t {
      if (inbox.empty()) {
        return 0;
      }
      if (inbox.begin()->first == slab_number) {
        return inbox.begin()->second.size();
      }
      ASSERT(inbox.begin()->first >= slab_number,
             "Received data for a change at slab " << inbox.begin()->first
             << " but it is already slab " << slab_number);
      return 0;
    };

    const size_t expected_messages = number_of_changes(message_count_inbox);
    const size_t received_messages = number_of_changes(new_slab_size_inbox);
    ASSERT(expected_messages >= received_messages,
           "Received " << received_messages << " size change messages at slab "
                       << slab_number << ", but only expected "
                       << expected_messages);
    if (expected_messages != received_messages) {
      return {std::move(box), Parallel::AlgorithmExecution::Retry};
    }

    message_count_inbox.erase(message_count_inbox.begin());

    const double new_slab_size =
        *alg::min_element(new_slab_size_inbox.begin()->second);
    new_slab_size_inbox.erase(new_slab_size_inbox.begin());

    const TimeStepper& time_stepper = db::get<::Tags::TimeStepper<>>(box);

    // Sometimes time steppers need to run with a fixed step size.
    // This is generally at the start of an evolution when the history
    // is in an unusual state.
    if (not time_stepper.can_change_step_size(
            time_step_id, db::get<::Tags::HistoryEvolvedVariables<>>(box))) {
      return {std::move(box), Parallel::AlgorithmExecution::Continue};
    }

    const auto& current_step = db::get<::Tags::TimeStep>(box);
    const auto& current_slab = current_step.slab();

    const auto new_slab =
        current_step.is_positive()
            ? current_slab.with_duration_from_start(new_slab_size)
            : current_slab.with_duration_to_end(new_slab_size);

    const auto new_step = current_step.with_slab(new_slab);

    // We are at a slab boundary, so the substep is 0.
    const auto new_time_step_id =
        TimeStepId(time_step_id.time_runs_forward(), time_step_id.slab_number(),
                   time_step_id.step_time().with_slab(new_slab));

    const auto new_next_time_step_id =
        time_stepper.next_time_id(new_time_step_id, new_step);

    db::mutate<::Tags::Next<::Tags::TimeStepId>, ::Tags::TimeStep,
               ::Tags::Next<::Tags::TimeStep>, ::Tags::TimeStepId>(
        make_not_null(&box),
        [&new_next_time_step_id, &new_step, &new_time_step_id](
            const gsl::not_null<TimeStepId*> next_time_step_id,
            const gsl::not_null<TimeDelta*> time_step,
            const gsl::not_null<TimeDelta*> next_time_step,
            const gsl::not_null<TimeStepId*> local_time_step_id) {
          *next_time_step_id = new_next_time_step_id;
          *time_step = new_step;
          *next_time_step = new_step;
          *local_time_step_id = new_time_step_id;
        });

    return {std::move(box), Parallel::AlgorithmExecution::Continue};
  }
};
}  // namespace Actions

namespace Events {
/// \ingroup TimeGroup
/// %Trigger a slab size change.
///
/// The new size will be the minimum suggested by any of the provided
/// step choosers on any element.  This requires a global reduction,
/// so it is possible to delay the change until a later slab to avoid
/// a global synchronization.  The actual change is carried out by
/// Actions::ChangeSlabSize.
///
/// When running with global time-stepping, the slab size and step
/// size are the same, so this adjusts the step size used by the time
/// integration.  With local time-stepping this controls the interval
/// between times when the sequences of steps on all elements are
/// forced to align.
class ChangeSlabSize : public Event {
  using ReductionData = Parallel::ReductionData<
      Parallel::ReductionDatum<int64_t, funcl::AssertEqual<>>,
      Parallel::ReductionDatum<double, funcl::Min<>>>;

 public:
  /// \cond
  explicit ChangeSlabSize(CkMigrateMessage* /*unused*/) {}
  using PUP::able::register_constructor;
  WRAPPED_PUPable_decl_template(ChangeSlabSize);  // NOLINT
  /// \endcond

  struct StepChoosers {
    static constexpr Options::String help = "Limits on slab size";
    using type =
        std::vector<std::unique_ptr<StepChooser<StepChooserUse::Slab>>>;
    static size_t lower_bound_on_size() { return 1; }
  };

  struct DelayChange {
    static constexpr Options::String help = "Slabs to wait before changing";
    using type = uint64_t;
  };

  using options = tmpl::list<StepChoosers, DelayChange>;
  static constexpr Options::String help =
      "Trigger a slab size change chosen by the provided step choosers.\n"
      "The actual changing of the slab size can be delayed until a later\n"
      "slab to improve parallelization.";

  ChangeSlabSize() = default;
  ChangeSlabSize(std::vector<std::unique_ptr<StepChooser<StepChooserUse::Slab>>>
                     step_choosers,
                 const uint64_t delay_change)
      : step_choosers_(std::move(step_choosers)), delay_change_(delay_change) {}

  using compute_tags_for_observation_box = tmpl::list<>;

  using argument_tags = tmpl::list<::Tags::TimeStepId, ::Tags::DataBox>;

  template <typename DbTags, typename Metavariables, typename ArrayIndex,
            typename ParallelComponent>
  void operator()(const TimeStepId& time_step_id,
                  const db::DataBox<DbTags>& box_for_step_choosers,
                  Parallel::GlobalCache<Metavariables>& cache,
                  const ArrayIndex& array_index,
                  const ParallelComponent* const /*meta*/) const {
    const auto next_changable_slab = time_step_id.is_at_slab_boundary()
                                         ? time_step_id.slab_number()
                                         : time_step_id.slab_number() + 1;
    const auto slab_to_change =
        next_changable_slab + static_cast<int64_t>(delay_change_);

    double desired_slab_size = std::numeric_limits<double>::infinity();
    for (const auto& step_chooser : step_choosers_) {
      desired_slab_size =
          std::min(desired_slab_size,
                   step_chooser->desired_slab(
                       time_step_id.step_time().slab().duration().value(),
                       box_for_step_choosers, cache));
    }

    const auto& component_proxy =
        Parallel::get_parallel_component<ParallelComponent>(cache);
    const auto& self_proxy = component_proxy[array_index];
    // This message is sent synchronously, so it is guaranteed to
    // arrive before the ChangeSlabSize action is called.
    Parallel::receive_data<
        ChangeSlabSize_detail::NumberOfExpectedMessagesInbox>(
        *self_proxy.ckLocal(), slab_to_change,
        ChangeSlabSize_detail::NumberOfExpectedMessagesInbox::NoData{});
    Parallel::contribute_to_reduction<ChangeSlabSize_detail::StoreNewSlabSize>(
        ReductionData(slab_to_change, desired_slab_size), self_proxy,
        component_proxy);
  }

  using is_ready_argument_tags = tmpl::list<>;

  template <typename Metavariables, typename ArrayIndex, typename Component>
  bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
                const ArrayIndex& /*array_index*/,
                const Component* const /*meta*/) const {
    return true;
  }

  bool needs_evolved_variables() const override {
    // This depends on the chosen StepChoosers, but they don't have a
    // way to report this information so we just return true to be
    // safe.
    return true;
  }

  // NOLINTNEXTLINE(google-runtime-references)
  void pup(PUP::er& p) override {
    Event::pup(p);
    p | step_choosers_;
    p | delay_change_;
  }

 private:
  std::vector<std::unique_ptr<StepChooser<StepChooserUse::Slab>>>
      step_choosers_;
  uint64_t delay_change_ = std::numeric_limits<uint64_t>::max();
};
}  // namespace Events

max_stars_repo_name: Shabibti/spectre

max_issues_repo_name: Shabibti/spectre

max_forks_repo_name: Shabibti/spectre


text:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <string>
#include "vector3d.h"
#include <math.h>
#include <vector>
#include <gsl/gsl_rng.h>
#include <time.h>
#include <boost/program_options.hpp>

using namespace std;
using namespace boost::program_options;

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

    /*Replacable variables*/
    string permitivityText = "USERINPUT_E";
    string totalTimeText = "USERINPUT_TIME";
    string initFileNameText = "USERINPUT_INIT_FILENAME";
    string mpiText = "NODESIZE";

    string initFile = "infiles/P22CD40L.in";

    // Set up the ligand xyz coordinates in a vector array

    vector<VECTOR3D> ligandCoordinates;
    double x;
    double y;
    double z;

    ifstream crds;                                      //open coordinates file
    crds.open("infiles/ligandCoordinates.coords");
    if (!crds) {                                        //check to make sure file is there
        cerr << "ERR: FILE ligandCoordinates.coords NOT OPENED. Check directory and/or filename.";
        exit(1);
    }
    for (int i = 0; i < 60; i++) {
        crds >> x >> y >> z;                // Add coordinates the the vector array
        ligandCoordinates.push_back(VECTOR3D(x, y, z));
    }

    // Get important parameters from the user

    double epsilon;
    double wallSpacing;
    double concentration;
    int numberComplexes;
    double timesteps;
    bool verbose;

    options_description desc("Usage:\nrandom_mesh <options>");
    desc.add_options()
            ("help,h", "print usage message")
            ("lennard jones well depth,E", value<double>(&epsilon)->default_value(1),
             "Binding strength of the ligand-recptor interaction (KbT)")
            ("[ligand - Virus] complex concentration,C", value<double>(&concentration)->default_value(9),
             "[ligand - Virus] complex concentration (nM)") // box size adjusteded for nanomolar conc.
            ("receptor spacing,w", value<double>(&wallSpacing)->default_value(100), "receptor spacing (nm)")
            ("number of vlp-ligand complexes,S", value<int>(&numberComplexes)->default_value(108),
             "number of vlp-ligand complexes")
            ("simulation time,T", value<double>(&timesteps)->default_value(275), "simulation time (milliseconds)")
            ("verbose,V", value<bool>(&verbose)->default_value(true), "verbose true: provides detailed output");

    variables_map vm;
    store(parse_command_line(argc, argv, desc), vm);
    notify(vm);
    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 0;
    }

    //add options for ligand - virus ratio, properties of ligand / vlp, free ligand in solution

    // GENERATE P22CD40L.in FILE!!!

    // generate atoms

    ofstream datafile(initFile);

    datafile << "#Script for P22-CD40L complex. To be read into LAMMPS template. " << endl;

    datafile << "#LAMMPS  data    file " << endl;

    double vlpDiameter = 1; //reduced units
    double ligandDiameter = 0.1; //reduced units
    double wallDiameter = 0.1; //reduced units

    double boxLength;
    double wallNumberX; //number of wall particles in x direction
    double atomNumber;
    double bondNumber;
    boxLength = pow((numberComplexes * 0.001 / (6.022E23)) / (concentration * 1E-9), (1.0 / 3.0)); //in meters

    wallSpacing = wallSpacing * 1E-9; // in meters
    wallNumberX = boxLength / wallSpacing; //calculate number of mesh points
    wallNumberX = trunc(wallNumberX); // truncate this value
    cout << "adjusted spacing is " << (boxLength / wallNumberX) * 1E9 << " nm" << endl; //this is the adjusted spacing
    atomNumber = (numberComplexes * 61) + (wallNumberX * wallNumberX);
    bondNumber = numberComplexes * 180;

    double sigma = 60e-9; //sigma value currently used, diameter of P22
    double sigmaHC = 0.12; // sigma hc in reduced units
    double massSI = 3.819E-20; // mass of P22 in kg
    double epsilonSI = (1.38E-23) * (298.15); // epsilon in J
    boxLength = boxLength / sigma; // now in reduced units
    wallSpacing = boxLength / wallNumberX; // now in reduced units

    //convert simulation time to reduced units
    double tau = sigma * sqrt(massSI / epsilonSI); //1 MD timestep in seconds
    timesteps = ceil(timesteps * 1e-3 / tau);
    cout << "lammps will run for " << timesteps << " MD timesteps" << endl;

    if (boxLength < (10 * vlpDiameter)) {
        cout << "Uh oh! The z-direction is too small!" << endl;
    }

    datafile << atomNumber << " atoms" << endl;

    datafile << bondNumber << " bonds" << endl;

    datafile << "3 atom types" << endl;

    datafile << "3 bond types" << endl;

    datafile << "0" << " " << boxLength << " xlo xhi" << endl; // in reduced units...

    datafile << "0" << " " << boxLength << " ylo yhi" << endl;

    datafile << "0" << " " << boxLength << " zlo zhi" << endl;

    datafile << endl;

    //atoms section

    datafile << "Atoms" << endl << endl;

    double atomType;
    double vlpX;
    double vlpY;
    double vlpZ;
    double index = 0;
    vector<VECTOR3D> vlpXYZ;
    gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937);                    //setting up random seed
    //unsigned long int Seed = 23410982;
    gsl_rng_set(r, time(NULL));        //seed with time
    VECTOR3D dist;

    ///////////////////////////////...To give vlp random positions use these...////////////////////////////////
    bool add;

    while (vlpXYZ.size() < numberComplexes) {
        add = true;
        vlpX = (gsl_rng_uniform(r)) * boxLength; // guess some coordinates
        vlpY = (gsl_rng_uniform(r)) * boxLength;
        vlpZ = (gsl_rng_uniform(r)) * boxLength;

        if (vlpZ < 2.5) add = false; // if too close to the cell wall, reject the point
        if (vlpZ > (boxLength - (vlpDiameter + ligandDiameter)))
            add = false; // if overlaps with the upper z boundary reject

        if (vlpXYZ.size() == 0) {        //if no vlps have been added yet, add it
            vlpXYZ.push_back(VECTOR3D(vlpX, vlpY, vlpX));
            index += 1;
            datafile << index << " 1 " << "1" << " " << vlpX << " " << vlpY << " " << vlpZ << " " << endl;
            for (unsigned int m = 0; m < ligandCoordinates.size(); m++) {
                index += 1;
                x = vlpX + ligandCoordinates[m].x;
                y = vlpY + ligandCoordinates[m].y;
                z = vlpZ + ligandCoordinates[m].z;
                datafile << index << " 1 " << "2" << " " << x << " " << y << " " << z << " " << endl;
            }
            add = false;
        }

        for (int j = 0; j < vlpXYZ.size(); j++) { //make sure they don't overlap with other particles
            dist.x = vlpXYZ[j].x - vlpX;
            dist.y = vlpXYZ[j].y - vlpY;
            dist.z = vlpXYZ[j].z - vlpZ;
            if (dist.x > boxLength / 2) dist.x -= boxLength; //account for periodic boundaries in x & y
            if (dist.x < -boxLength / 2) dist.x += boxLength;
            if (dist.y > boxLength / 2) dist.y -= boxLength;
            if (dist.y < -boxLength / 2) dist.y += boxLength;
            //       if (dist.z>boxLength/2) dist.z -= boxLength; 	// z is not periodic
            //       if (dist.z<-boxLength/2) dist.z += boxLength;
            //   cout << "distance is " << dist.GetMagnitude() << " btw " << j << " ( " << vlpXYZ[j].x << " , " << vlpXYZ[j].y << " , " << vlpXYZ[j].z << " ) " << " and " << index/61 << " ( " << vlpX << " , " << vlpY << " , " << vlpZ << " ) " << endl;

            if (dist.GetMagnitude() < 2.5) {  //flag it if it intersects with anything
                //cout << "too close!" << endl;
                add = false;
                break;
            }
        }

        if (add == true) {        //if it doesn't intersect, add it and its ligands to the list
            vlpXYZ.push_back(VECTOR3D(vlpX, vlpY, vlpZ));
            index += 1;
            datafile << index << "  1 " << "1" << "  " << vlpX << "  " << vlpY << "  " << vlpZ << endl;
            for (unsigned int m = 0; m < ligandCoordinates.size(); m++) {
                index += 1;
                x = vlpX + ligandCoordinates[m].x;
                y = vlpY + ligandCoordinates[m].y;
                z = vlpZ + ligandCoordinates[m].z;
                datafile << index << "  1 " << "2" << "  " << x << "  " << y << "  " << z << endl;
            }
        } //else cout << "rejected!" << endl;

    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Making wall particles
    for (unsigned int i = 0; i < wallNumberX; i++) {
        for (unsigned int j = 0; j < wallNumberX; j++) {
            index += 1;
            datafile << index << " 1 " << "3" << "  " << i * wallSpacing << "  " << j * wallSpacing << "  " << "0"
                     << endl;
        }
    }

    cout << "Done making atoms!" << endl;

// Generate bonds

    vector<VECTOR3D> ligandBonds;
    int type;
    int b1;
    int b2;

    ifstream bonds;                                      //open coordinates file
    bonds.open("infiles/ligandBonds.coords");
    if (!bonds) {                                        //check to make sure file is there
        cerr << "ERR: FILE ligandBonds.coords NOT OPENED. Check directory and/or filename.";
        exit(1);
    }
    for (int i = 0; i < 180; i++) {
        bonds >> index >> type >> b1 >> b2;                // Add coordinates the the vector array
        ligandBonds.push_back(VECTOR3D(type, b1, b2));
    }

    datafile << endl << "Bonds" << endl << endl;

    index = 0;

    for (int i = 0; i < numberComplexes; i++) {
        for (int j = 0; j < ligandBonds.size(); j++) {
            index += 1;
            datafile << index << "     " << ligandBonds[j].x << "     " << ligandBonds[j].y + (i * 61) << "     "
                     << ligandBonds[j].z + (i * 61) << endl;
        }

    }

//bond type 1 length
    dist = VECTOR3D(0, 0, 0) - ligandCoordinates[0];
    double lengthType1 = dist.GetMagnitude();
//bond type 2 length
    dist = ligandCoordinates[0] - ligandCoordinates[1];
    double lengthType2 = dist.GetMagnitude();
//bond type 3 length
    dist = ligandCoordinates[0] - ligandCoordinates[20];
    double lengthType3 = dist.GetMagnitude();

    cout << "Done making bonds!" << endl;

/*************************Generating the LAMMPS file*************************/

    ofstream inputScript("in.lammps", ios::trunc);
    if (inputScript.is_open()) {

        /*Open the template file*/
        string line;
        ifstream inputTemplate("infiles/in.lammps.template", ios::in);
        if (inputTemplate.is_open()) {
            while (getline(inputTemplate, line)) {

                std::size_t found = line.find(permitivityText);
                if (found != std::string::npos)
                    line.replace(found, permitivityText.length(),  std::to_string(epsilon));

                found = line.find(totalTimeText);
                if (found != std::string::npos)
                    line.replace(found, totalTimeText.length(), std::to_string(int(timesteps)));

                found = line.find(initFileNameText);
                if (found != std::string::npos)
                    line.replace(found, initFileNameText.length(), initFile);

                inputScript << line << endl;
            }
            inputTemplate.close();
        } else cout << "Unable to open the template input script" << endl;
        inputScript.close();
    } else cout << "Unable create a input Script" << endl;

/*
//GENERATE LAMMPS INPUT SCRIPT

    ofstream outfile("lammps_script.in");

    outfile << "#Lammps input script for nanoparticle binding with multivalency #" << endl << endl;

    outfile << "units lj" << endl << "boundary p p f" << endl << "atom_style bond " << endl << "neighbor 0.3 bin"
            << endl << "neigh_modify every 1 delay 0 check yes" << endl << endl;

//Creating simulation box

    outfile << "## Create Simulation Box, Atoms ##" << endl;

    outfile << "read_data	   P22CD40L.in" << endl << endl;

    outfile << "group vlp type 1" << endl << "group ligand type 2" << endl << "group wall type 3" << endl << endl;

//Defining particle properties

    outfile << "## Defining Particle/Medium Properties ##" << endl;

    outfile << "mass	1	1	# reduced mass of vlp P22" << endl;

    outfile << "mass	2	0.002	# reduced mass of ligand " << endl;

    outfile << "mass	3	1	# mass of wall, irrelevant " << endl << endl;

    outfile << "## Ascribing Initial Velocities ##" << endl;

    outfile << "velocity	all	create	1.0	4928459	rot	yes	dist	gaussian	units	box" << endl
            << endl;

    outfile << "## Fixing Wall particles ##" << endl;

    outfile << "fix zwalls all wall/reflect zhi EDGE zlo EDGE" << endl << endl;

//Interparticle potentials

    outfile << "## Ascribing interparticle potentials: ##" << endl << endl;

    outfile << "pair_style      hybrid lj/expand        2.5     lj/cut 2.5" << endl;

    outfile << "pair_coeff      1       1       lj/cut           1      " << vlpDiameter << "	"
            << vlpDiameter * 1.12246 << "       # epsilon, sigma, cut-off  V-V" << endl;

    outfile << "pair_coeff      1       2       lj/expand        1      " << sigmaHC << "     "
            << (vlpDiameter + ligandDiameter) / 2 - sigmaHC << "	" << (vlpDiameter + ligandDiameter) / 2 * 1.12246
            << "  # epsilon, sigmaHC, delta_V-L, cut-off" << endl;

    outfile << "pair_coeff      2       2       lj/cut           1      " << ligandDiameter << "     "
            << ligandDiameter * 1.12246 << "       # L-L" << endl;

    outfile << "pair_coeff      1       3       lj/expand        1      " << sigmaHC << "     "
            << (vlpDiameter + wallDiameter) / 2 - sigmaHC << "	" << (vlpDiameter + wallDiameter) / 2 * 1.12246
            << "  # V-W" << endl;

    outfile << "pair_coeff      2       3       lj/cut       " << epsilon << "	   " << ligandDiameter << "	"
            << "2.5" << "  # L-W" << endl;

    outfile << "pair_coeff      3       3       lj/cut           0      0               # W-W" << endl << endl;

    outfile << "#pair_modify  shift   yes     # the additive e_LJ for repulsion-only" << endl << endl;

//Defining bond properties

    outfile << "## Making bonds ##" << endl;

    outfile << "bond_style harmonic" << endl;

    outfile << "bond_coeff 1    1000.0  " << lengthType1 << "  # type, K, distance" << endl;

    outfile << "bond_coeff 2    1000.0  " << lengthType2 << endl;

    outfile << "bond_coeff 3    1000.0  " << lengthType3 << endl << endl;

//Ensemble fixes

    outfile << "## Ensemble Fixes (+ for output) ##" << endl;

    outfile << "variable        myTStep equal   0.00005 # timestep where 1 MD step is "
            << sigma * sqrt((massSI) / (epsilonSI)) << " seconds" << endl;

    outfile << "timestep        ${myTStep}" << endl;

    outfile << "variable        myDStep equal   1000" << endl << endl;

    outfile << "fix     ens     vlp     nvt     temp    1.      1.      0.005" << endl;

    outfile << "fix     ens2    ligand  nvt     temp    1.      1.      0.005  # T_start, T_stop, T_damp=100*timestep"
            << endl;

    outfile << "fix_modify ens energy yes  # adds thermostat energy to potential" << endl;

    outfile << "fix_modify ens2 energy yes" << endl << endl;

//Output dump

    outfile << "## Initial Image Dump ##" << endl;

    outfile << "dump mymovie all custom 100 ovitomovie.melt id type x y z" << endl << endl;

    outfile << "print \"OUTPUT COLUMNS: SIMULATION STEP NUMBER | TEMPERATURE | NP POTENTIAL ENERGY | SYSTEM VOLUME\" "
            << endl << endl;

    outfile << "thermo_style   custom  step    temp   etotal  ke      pe     #print info to file" << endl;

    outfile << "thermo  50000" << endl << endl;

    outfile << fixed;

    outfile << "run     " << int(timesteps) << endl << endl;

    outfile << "## Defining Output Information ##" << endl;

    outfile
            << "dump    posD    all     custom  ${myDStep}      outfiles/dump.melt      id      type    x       y       z       # c_atomPot     c_atomKin"
            << endl << endl;

    outfile << " unfix   ens" << endl;

    outfile << "unfix   ens2" << endl;

    outfile << "undump  posD" << endl;

    outfile << "undump mymovie" << endl;

    outfile << "#shell          echo \"Lammps Simulation Ended\" " << endl;

*/

    gsl_rng_free(r);

    return 0;

}

max_stars_repo_name: IU-nanoBio/nanobind

max_issues_repo_name: IU-nanoBio/nanobind

max_forks_repo_name: IU-nanoBio/nanobind