<commit_before>#include "spell_logic.h"
#include "game/transcendental/logic_step.h"
#include "game/transcendental/cosmos.h"
#include "game/transcendental/entity_handle.h"
#include "game/components/sentience_component.h"
#include "game/components/render_component.h"
#include "game/components/wandering_pixels_component.h"
#include "game/components/damage_component.h"
#include "game/messages/create_particle_effect.h"
#include "game/systems_stateless/particles_existence_system.h"
#include "game/systems_stateless/sound_existence_system.h"

#include "game/ingredients/ingredients.h"
#include "game/assets/sound_buffer_id.h"

#include "game/detail/entity_scripts.h"
#include "game/enums/filters.h"

#include "game/detail/explosions.h"
#include "game/assets/spell.h"

bool are_additional_conditions_for_casting_fulfilled(
	const assets::spell_id spell,
	const const_entity_handle caster
) {
	switch (spell) {
	case assets::spell_id::ELECTRIC_TRIAD: {
		constexpr float standard_triad_radius = 800.f;

		const bool is_any_hostile_in_proximity = get_closest_hostiles(
			caster,
			caster,
			standard_triad_radius,
			filters::bullet()
		).size() > 0;

		return is_any_hostile_in_proximity;
	}

	default:
		return true;
	}
}

void perform_spell_logic(
	const logic_step step,
	const assets::spell_id spell,
	const entity_handle caster,
	components::sentience& sentience,
	const augs::stepped_timestamp when_casted,
	const augs::stepped_timestamp now
) {
	auto& cosmos = step.cosm;
	const auto& metas = step.input.metas_of_assets;

	const auto spell_data = metas[spell];
	const auto dt = cosmos.get_fixed_delta();
	const auto caster_transform = caster.get_logic_transform();

	const auto ignite_sparkle_particles = [&]() {
		particle_effect_input burst;

		burst.effect.id = assets::particle_effect_id::CAST_SPARKLES;
		burst.effect.modifier.colorize = spell_data.border_col;

		burst.create_particle_effect_entity(
			step,
			caster_transform,
			caster
		).add_standard_components(step);
	};

	const auto ignite_charging_particles = [&](const rgba col) {
		particle_effect_input burst;

		burst.effect.id = assets::particle_effect_id::CAST_CHARGING;
		burst.effect.modifier.colorize = col;
		burst.effect.modifier.scale_lifetimes = 1.3f;
		burst.effect.modifier.homing_target = caster;

		burst.create_particle_effect_entity(
			step,
			caster_transform,
			caster
		).add_standard_components(step);
	};

	const auto play_sound = [&](const assets::sound_buffer_id effect, const float gain = 1.f) {
		sound_effect_input in;
		in.delete_entity_after_effect_lifetime = true;
		in.direct_listener = caster;
		in.effect.id = effect;
		in.effect.modifier.gain = gain;

		in.create_sound_effect_entity(step, caster_transform, entity_id()).add_standard_components(step);
	};

	const auto play_standard_sparkles_sound = [&]() {
		play_sound(assets::sound_buffer_id::CAST_SUCCESSFUL);
	};

	switch (spell) {
	case assets::spell_id::HASTE:
		ignite_sparkle_particles();
		play_standard_sparkles_sound();

		sentience.haste.timing.set_for_duration(static_cast<float>(spell_data.perk_duration_seconds * 1000), now);

		break;

	case assets::spell_id::ELECTRIC_SHIELD:
		ignite_sparkle_particles();
		play_standard_sparkles_sound();

		sentience.electric_shield.timing.set_for_duration(static_cast<float>(spell_data.perk_duration_seconds * 1000), now);

		break;

	case assets::spell_id::FURY_OF_THE_AEONS:
		if (when_casted == now) {
			ignite_sparkle_particles();
			play_standard_sparkles_sound();
			play_sound(assets::sound_buffer_id::EXPLOSION, 1.2f);

			sentience.shake_for_ms = 400.f;
			sentience.time_of_last_shake = now;

			standard_explosion_input in;
			in.effective_radius = 250.f;
			in.damage = 88.f;
			in.impact_force = 150.f;
			in.inner_ring_color = cyan;
			in.outer_ring_color = white;
			in.sound_effect = assets::sound_buffer_id::EXPLOSION;
			in.sound_gain = 1.2f;

			in.instantiate(step, caster_transform, caster);
		}

		break;

	case assets::spell_id::ULTIMATE_WRATH_OF_THE_AEONS:
	{
		const auto seconds_passed = (now - when_casted).in_seconds(dt);
		const auto first_at = augs::stepped_timestamp{ when_casted.step + static_cast<unsigned>(1.3f / dt.in_seconds()) };
		const auto second_at = augs::stepped_timestamp{ when_casted.step + static_cast<unsigned>(1.8f / dt.in_seconds()) };
		const auto third_at = augs::stepped_timestamp{ when_casted.step + static_cast<unsigned>(2.3f / dt.in_seconds()) };

		standard_explosion_input in;
		in.damage = 88.f;
		in.inner_ring_color = cyan;
		in.outer_ring_color = white;

		if (now == when_casted) {
			ignite_sparkle_particles();
			ignite_charging_particles(cyan);
			ignite_charging_particles(white);
			play_standard_sparkles_sound();
			play_sound(assets::sound_buffer_id::CAST_CHARGING);
		}
		else if (now == first_at) {
			sentience.shake_for_ms = 400.f;
			sentience.time_of_last_shake = now;

			in.effective_radius = 200.f;
			in.impact_force = 150.f;
			in.sound_gain = 1.2f;
			in.sound_effect = assets::sound_buffer_id::EXPLOSION;

			in.instantiate(step, caster_transform, caster);
		}
		else if (now == second_at) {
			sentience.shake_for_ms = 500.f;
			sentience.time_of_last_shake = now;

			in.effective_radius = 400.f;
			in.impact_force = 200.f;
			in.sound_gain = 1.0f;
			in.sound_effect = assets::sound_buffer_id::GREAT_EXPLOSION;

			in.instantiate(step, caster_transform, caster);
		}
		else if (now == third_at) {
			sentience.shake_for_ms = 600.f;
			sentience.time_of_last_shake = now;

			in.effective_radius = 600.f;
			in.impact_force = 250.f;
			in.sound_gain = 1.2f;
			in.sound_effect = assets::sound_buffer_id::GREAT_EXPLOSION;

			in.instantiate(step, caster_transform, caster);
		}

		break;
	}
	case assets::spell_id::ELECTRIC_TRIAD:
		ignite_sparkle_particles();
		play_standard_sparkles_sound();

		{
			constexpr float standard_triad_radius = 800.f;

			const auto hostiles = get_closest_hostiles(
				caster,
				caster,
				standard_triad_radius,
				filters::bullet()
			);

			for (size_t i = 0; i < 3 && i < hostiles.size(); ++i) {
				const auto next_hostile = cosmos[hostiles[i]];
				LOG_NVPS(next_hostile.get_id());
				const auto energy_ball = cosmos.create_entity("energy_ball");

				auto new_energy_ball_transform = caster_transform;

				new_energy_ball_transform.rotation =
					(next_hostile.get_logic_transform().pos - caster_transform.pos).degrees();

				ingredients::add_sprite(
					energy_ball,
					assets::game_image_id::ENERGY_BALL,
					cyan,
					render_layer::FLYING_BULLETS
				);

				ingredients::add_bullet_round_physics(
					step,
					energy_ball,
					new_energy_ball_transform
				);

				auto& damage = energy_ball += components::damage();

				damage.destruction_particle_effect_response.id = assets::particle_effect_id::ELECTRIC_PROJECTILE_DESTRUCTION;
				damage.destruction_particle_effect_response.modifier.colorize = cyan;

				damage.bullet_trace_particle_effect_response.id = assets::particle_effect_id::WANDERING_PIXELS_DIRECTED;
				damage.bullet_trace_particle_effect_response.modifier.colorize = cyan;

				damage.muzzle_leave_particle_effect_response.id = assets::particle_effect_id::PIXEL_MUZZLE_LEAVE_EXPLOSION;
				damage.muzzle_leave_particle_effect_response.modifier.colorize = cyan;

				auto& trace_modifier = damage.bullet_trace_sound_response.modifier;

				trace_modifier.max_distance = 1020.f;
				trace_modifier.reference_distance = 100.f;
				trace_modifier.gain = 1.3f;
				trace_modifier.repetitions = -1;
				trace_modifier.fade_on_exit = false;

				damage.bullet_trace_sound_response.id = assets::sound_buffer_id::ELECTRIC_PROJECTILE_FLIGHT;
				damage.destruction_sound_response.id = assets::sound_buffer_id::ELECTRIC_DISCHARGE_EXPLOSION;

				damage.homing_towards_hostile_strength = 1.0f;
				damage.particular_homing_target = next_hostile;
				damage.amount = 42;
				damage.sender = caster;

				const auto energy_ball_velocity = vec2().set_from_degrees(new_energy_ball_transform.rotation) * 2000;
				energy_ball.get<components::rigid_body>().set_velocity(energy_ball_velocity);

				energy_ball.add_standard_components(step);
			}
		}

		break;

	default:
		LOG("Unknown spell: %x", static_cast<int>(spell));
		break;
	}
}

<commit_msg>fixed crash in spell_logic<commit_after>#include "spell_logic.h"
#include "game/transcendental/logic_step.h"
#include "game/transcendental/cosmos.h"
#include "game/transcendental/entity_handle.h"
#include "game/components/sentience_component.h"
#include "game/components/render_component.h"
#include "game/components/wandering_pixels_component.h"
#include "game/components/damage_component.h"
#include "game/messages/create_particle_effect.h"
#include "game/systems_stateless/particles_existence_system.h"
#include "game/systems_stateless/sound_existence_system.h"

#include "game/ingredients/ingredients.h"
#include "game/assets/sound_buffer_id.h"

#include "game/detail/entity_scripts.h"
#include "game/enums/filters.h"

#include "game/detail/explosions.h"
#include "game/assets/spell.h"

bool are_additional_conditions_for_casting_fulfilled(
	const assets::spell_id spell,
	const const_entity_handle caster
) {
	switch (spell) {
	case assets::spell_id::ELECTRIC_TRIAD: {
		constexpr float standard_triad_radius = 800.f;

		const bool is_any_hostile_in_proximity = get_closest_hostiles(
			caster,
			caster,
			standard_triad_radius,
			filters::bullet()
		).size() > 0;

		return is_any_hostile_in_proximity;
	}

	default:
		return true;
	}
}

void perform_spell_logic(
	const logic_step step,
	const assets::spell_id spell,
	const entity_handle caster,
	components::sentience& sentience,
	const augs::stepped_timestamp when_casted,
	const augs::stepped_timestamp now
) {
	auto& cosmos = step.cosm;
	const auto& metas = step.input.metas_of_assets;

	const auto spell_data = metas[spell];
	const auto dt = cosmos.get_fixed_delta();
	const auto caster_transform = caster.get_logic_transform();

	const auto ignite_sparkle_particles = [&]() {
		particle_effect_input burst;

		burst.effect.id = assets::particle_effect_id::CAST_SPARKLES;
		burst.effect.modifier.colorize = spell_data.border_col;

		burst.create_particle_effect_entity(
			step,
			caster_transform,
			caster
		).add_standard_components(step);
	};

	const auto ignite_charging_particles = [&](const rgba col) {
		particle_effect_input burst;

		burst.effect.id = assets::particle_effect_id::CAST_CHARGING;
		burst.effect.modifier.colorize = col;
		burst.effect.modifier.scale_lifetimes = 1.3f;
		burst.effect.modifier.homing_target = caster;

		burst.create_particle_effect_entity(
			step,
			caster_transform,
			caster
		).add_standard_components(step);
	};

	const auto play_sound = [&](const assets::sound_buffer_id effect, const float gain = 1.f) {
		sound_effect_input in;
		in.delete_entity_after_effect_lifetime = true;
		in.direct_listener = caster;
		in.effect.id = effect;
		in.effect.modifier.gain = gain;

		in.create_sound_effect_entity(step, caster_transform, entity_id()).add_standard_components(step);
	};

	const auto play_standard_sparkles_sound = [&]() {
		play_sound(assets::sound_buffer_id::CAST_SUCCESSFUL);
	};

	switch (spell) {
	case assets::spell_id::HASTE:
		ignite_sparkle_particles();
		play_standard_sparkles_sound();

		sentience.haste.timing.set_for_duration(static_cast<float>(spell_data.perk_duration_seconds * 1000), now);

		break;

	case assets::spell_id::ELECTRIC_SHIELD:
		ignite_sparkle_particles();
		play_standard_sparkles_sound();

		sentience.electric_shield.timing.set_for_duration(static_cast<float>(spell_data.perk_duration_seconds * 1000), now);

		break;

	case assets::spell_id::FURY_OF_THE_AEONS:
		if (when_casted == now) {
			ignite_sparkle_particles();
			play_standard_sparkles_sound();
			play_sound(assets::sound_buffer_id::EXPLOSION, 1.2f);

			sentience.shake_for_ms = 400.f;
			sentience.time_of_last_shake = now;

			standard_explosion_input in;
			in.effective_radius = 250.f;
			in.damage = 88.f;
			in.impact_force = 150.f;
			in.inner_ring_color = cyan;
			in.outer_ring_color = white;
			in.sound_effect = assets::sound_buffer_id::EXPLOSION;
			in.sound_gain = 1.2f;

			in.instantiate(step, caster_transform, caster);
		}

		break;

	case assets::spell_id::ULTIMATE_WRATH_OF_THE_AEONS:
	{
		const auto seconds_passed = (now - when_casted).in_seconds(dt);
		const auto first_at = augs::stepped_timestamp{ when_casted.step + static_cast<unsigned>(1.3f / dt.in_seconds()) };
		const auto second_at = augs::stepped_timestamp{ when_casted.step + static_cast<unsigned>(1.8f / dt.in_seconds()) };
		const auto third_at = augs::stepped_timestamp{ when_casted.step + static_cast<unsigned>(2.3f / dt.in_seconds()) };

		standard_explosion_input in;
		in.damage = 88.f;
		in.inner_ring_color = cyan;
		in.outer_ring_color = white;
		in.type = adverse_element_type::FORCE;

		if (now == when_casted) {
			ignite_sparkle_particles();
			ignite_charging_particles(cyan);
			ignite_charging_particles(white);
			play_standard_sparkles_sound();
			play_sound(assets::sound_buffer_id::CAST_CHARGING);
		}
		else if (now == first_at) {
			sentience.shake_for_ms = 400.f;
			sentience.time_of_last_shake = now;

			in.effective_radius = 200.f;
			in.impact_force = 150.f;
			in.sound_gain = 1.2f;
			in.sound_effect = assets::sound_buffer_id::EXPLOSION;

			in.instantiate(step, caster_transform, caster);
		}
		else if (now == second_at) {
			sentience.shake_for_ms = 500.f;
			sentience.time_of_last_shake = now;

			in.effective_radius = 400.f;
			in.impact_force = 200.f;
			in.sound_gain = 1.0f;
			in.sound_effect = assets::sound_buffer_id::GREAT_EXPLOSION;

			in.instantiate(step, caster_transform, caster);
		}
		else if (now == third_at) {
			sentience.shake_for_ms = 600.f;
			sentience.time_of_last_shake = now;

			in.effective_radius = 600.f;
			in.impact_force = 250.f;
			in.sound_gain = 1.2f;
			in.sound_effect = assets::sound_buffer_id::GREAT_EXPLOSION;

			in.instantiate(step, caster_transform, caster);
		}

		break;
	}
	case assets::spell_id::ELECTRIC_TRIAD:
		ignite_sparkle_particles();
		play_standard_sparkles_sound();

		{
			constexpr float standard_triad_radius = 800.f;

			const auto hostiles = get_closest_hostiles(
				caster,
				caster,
				standard_triad_radius,
				filters::bullet()
			);

			for (size_t i = 0; i < 3 && i < hostiles.size(); ++i) {
				const auto next_hostile = cosmos[hostiles[i]];
				LOG_NVPS(next_hostile.get_id());
				const auto energy_ball = cosmos.create_entity("energy_ball");

				auto new_energy_ball_transform = caster_transform;

				new_energy_ball_transform.rotation =
					(next_hostile.get_logic_transform().pos - caster_transform.pos).degrees();

				ingredients::add_sprite(
					energy_ball,
					assets::game_image_id::ENERGY_BALL,
					cyan,
					render_layer::FLYING_BULLETS
				);

				ingredients::add_bullet_round_physics(
					step,
					energy_ball,
					new_energy_ball_transform
				);

				auto& damage = energy_ball += components::damage();

				damage.destruction_particle_effect_response.id = assets::particle_effect_id::ELECTRIC_PROJECTILE_DESTRUCTION;
				damage.destruction_particle_effect_response.modifier.colorize = cyan;

				damage.bullet_trace_particle_effect_response.id = assets::particle_effect_id::WANDERING_PIXELS_DIRECTED;
				damage.bullet_trace_particle_effect_response.modifier.colorize = cyan;

				damage.muzzle_leave_particle_effect_response.id = assets::particle_effect_id::PIXEL_MUZZLE_LEAVE_EXPLOSION;
				damage.muzzle_leave_particle_effect_response.modifier.colorize = cyan;

				auto& trace_modifier = damage.bullet_trace_sound_response.modifier;

				trace_modifier.max_distance = 1020.f;
				trace_modifier.reference_distance = 100.f;
				trace_modifier.gain = 1.3f;
				trace_modifier.repetitions = -1;
				trace_modifier.fade_on_exit = false;

				damage.bullet_trace_sound_response.id = assets::sound_buffer_id::ELECTRIC_PROJECTILE_FLIGHT;
				damage.destruction_sound_response.id = assets::sound_buffer_id::ELECTRIC_DISCHARGE_EXPLOSION;

				damage.homing_towards_hostile_strength = 1.0f;
				damage.particular_homing_target = next_hostile;
				damage.amount = 42;
				damage.sender = caster;

				const auto energy_ball_velocity = vec2().set_from_degrees(new_energy_ball_transform.rotation) * 2000;
				energy_ball.get<components::rigid_body>().set_velocity(energy_ball_velocity);

				energy_ball.add_standard_components(step);
			}
		}

		break;

	default:
		LOG("Unknown spell: %x", static_cast<int>(spell));
		break;
	}
}

<|endoftext|>


<commit_before>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */
/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Interface for EWC, a helper class that does projections and preconditioners in
energy/water-content space instead of temperature/pressure space.
------------------------------------------------------------------------- */
#include "FieldEvaluator.hh"
#include "ewc_model.hh"
#include "mpc_delegate_ewc.hh"

namespace Amanzi {

#define DEBUG_FLAG 1

// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
MPCDelegateEWC::MPCDelegateEWC(Teuchos::ParameterList& plist) :
    plist_(Teuchos::rcpFromRef(plist)) {
  // set up the VerboseObject
  std::string name = plist_->get<std::string>("PK name")+std::string(" EWC");
  vo_ = Teuchos::rcp(new VerboseObject(name, *plist_));
}

// -----------------------------------------------------------------------------
// Allocate any data or models required.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::setup(const Teuchos::Ptr<State>& S) {
  // Verbosity
  std::string name = plist_->get<std::string>("PK name")+std::string(" EWC");

  // Get the mesh
  Key domain = plist_->get<std::string>("domain key", "");
  if (domain.size() != 0) {
    mesh_ = S->GetMesh(domain);
  } else {
    mesh_ = S->GetMesh("domain");
  }

  // set up a debugger
  db_ = Teuchos::rcp(new Debugger(mesh_, name, *plist_));

  // Process the parameter list for data Keys
  if (domain.size() > 0) domain.append(1, '_');
  pres_key_ = plist_->get<std::string>("pressure key", domain+std::string("pressure"));
  temp_key_ = plist_->get<std::string>("temperature key",
          domain+std::string("temperature"));
  e_key_ = plist_->get<std::string>("energy key", domain+std::string("energy"));
  wc_key_ = plist_->get<std::string>("water content key",
          domain+std::string("water_content"));
  cv_key_ = plist_->get<std::string>("cell volume key",
          domain+std::string("cell_volume"));

  // Process the parameter list for methods
  std::string precon_string = plist_->get<std::string>("preconditioner type", "none");
  if (precon_string == "none") {
    precon_type_ = PRECON_NONE;
  } else if (precon_string == "ewc") {
    precon_type_ = PRECON_EWC;
    ASSERT(0);
  } else if (precon_string == "smart ewc") {
    precon_type_ = PRECON_SMART_EWC;
  }

  // select the method used for nonlinear prediction
  std::string predictor_string = plist_->get<std::string>("predictor type", "none");
  if (predictor_string == "none") {
    predictor_type_ = PREDICTOR_NONE;
  } else if (predictor_string == "ewc") {
    predictor_type_ = PREDICTOR_EWC;
    ASSERT(0);
  } else if (predictor_string == "smart ewc") {
    predictor_type_ = PREDICTOR_SMART_EWC;
  } else {
    Errors::Message message;
    message << "EWC Delegate: invalid predictor string: \"" << predictor_string
            << "\", valid are \"none\", \"ewc\", \"smart ewc\"";
    Exceptions::amanzi_throw(message);
  }

  // Smart EWC uses a heuristic to guess when we need the EWC instead of using
  // it blindly.
  if (predictor_type_ == PREDICTOR_SMART_EWC || precon_type_ == PRECON_SMART_EWC) {
    if (plist_->isParameter("cusp distance in T")) {
      cusp_size_T_freezing_ = plist_->get<double>("cusp distance in T");
      cusp_size_T_thawing_ = cusp_size_T_freezing_;
    } else {
      cusp_size_T_freezing_ = plist_->get<double>("cusp distance in T, freezing", 0.005);
      cusp_size_T_thawing_ = plist_->get<double>("cusp distance in T, thawing", 0.005);
    }
  }
}

// -----------------------------------------------------------------------------
// Initialize any data required in setup.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::initialize(const Teuchos::Ptr<State>& S) {
  // Create and initialize old stored data for previous steps.
  if (predictor_type_ == PREDICTOR_EWC || predictor_type_ == PREDICTOR_SMART_EWC) {
    const Epetra_MultiVector& wc = *S->GetFieldData(wc_key_)
        ->ViewComponent("cell",false);
    const Epetra_MultiVector& e = *S->GetFieldData(e_key_)
        ->ViewComponent("cell",false);

    wc_prev2_ = Teuchos::rcp(new Epetra_MultiVector(wc));
    e_prev2_ = Teuchos::rcp(new Epetra_MultiVector(e));
    wc_prev2_->PutScalar(0.);
    e_prev2_->PutScalar(0.);

    time_prev2_ = S->time();
  }

  // initialize the Jacobian
  if (precon_type_ == PRECON_EWC || precon_type_ == PRECON_SMART_EWC) {
    int ncells = mesh_->num_entities(AmanziMesh::CELL, AmanziMesh::OWNED);
    jac_.resize(ncells, WhetStone::Tensor(2,2));
  }

  // initialize the model, which grabs all needed models from state
  model_->InitializeModel(S);
}

// -----------------------------------------------------------------------------
// Set state pointers.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::set_states(const Teuchos::RCP<const State>& S,
        const Teuchos::RCP<State>& S_inter,
        const Teuchos::RCP<State>& S_next) {
  S_= S;
  S_inter_ = S_inter;
  S_next_ = S_next;
}

// -----------------------------------------------------------------------------
// Save info from previous iterations if needed.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::commit_state(double dt, const Teuchos::RCP<State>& S) {
  if ((predictor_type_ == PREDICTOR_EWC || predictor_type_ == PREDICTOR_SMART_EWC)
      && S_inter_ != Teuchos::null) {
    // stash water content and energy in S_work.
    *wc_prev2_ = *S_inter_->GetFieldData(wc_key_)->ViewComponent("cell",false);
    *e_prev2_ = *S_inter_->GetFieldData(e_key_)->ViewComponent("cell",false);
    time_prev2_ = S_inter_->time();
  }
}

// -----------------------------------------------------------------------------
// Modify the prediction from linearization of the time integration.
// -----------------------------------------------------------------------------
bool MPCDelegateEWC::ModifyPredictor(double h, Teuchos::RCP<TreeVector> up) {
  bool modified = false;
  double dt_prev = S_inter_->time() - time_prev2_;

  if (predictor_type_ == PREDICTOR_EWC) {
    if (dt_prev > 0.) {
      ASSERT(0);
      //      modified = modify_predictor_ewc_(h,up);
    }
  } else if (predictor_type_ == PREDICTOR_SMART_EWC) {
    if (dt_prev > 0.) {
      modified = modify_predictor_smart_ewc_(h,up);
    }
  }
  return modified;
}

// -----------------------------------------------------------------------------
// Update of the preconditioner
// -----------------------------------------------------------------------------
void MPCDelegateEWC::UpdatePreconditioner(double t, Teuchos::RCP<const TreeVector> up, double h) {
  if (precon_type_ == PRECON_EWC || precon_type_ == PRECON_SMART_EWC) {
    update_precon_ewc_(t,up,h);
  }
}

// -----------------------------------------------------------------------------
// Application of the preconditioner.
// -----------------------------------------------------------------------------
int MPCDelegateEWC::ApplyPreconditioner(Teuchos::RCP<const TreeVector> u, Teuchos::RCP<TreeVector> Pu) {
  int ierr = 0;
  if ((precon_type_ == PRECON_EWC) || (precon_type_ == PRECON_SMART_EWC)) {
    precon_ewc_(u,Pu);
  }
  else ierr = 1;

  return ierr;
}

void MPCDelegateEWC::update_precon_ewc_(double t, Teuchos::RCP<const TreeVector> up, double h) {
  Key dedT_key = std::string("d")+e_key_+std::string("_d")+temp_key_;
  S_next_->GetFieldEvaluator(e_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", temp_key_);
  const Epetra_MultiVector& dedT = *S_next_->GetFieldData(dedT_key)
      ->ViewComponent("cell",false);

  Key dedp_key = std::string("d")+e_key_+std::string("_d")+pres_key_;
  S_next_->GetFieldEvaluator(e_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", pres_key_);
  const Epetra_MultiVector& dedp = *S_next_->GetFieldData(dedp_key)
      ->ViewComponent("cell",false);

  Key dwcdT_key = std::string("d")+wc_key_+std::string("_d")+temp_key_;
  S_next_->GetFieldEvaluator(wc_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", temp_key_);
  const Epetra_MultiVector& dwcdT = *S_next_->GetFieldData(dwcdT_key)
      ->ViewComponent("cell",false);

  Key dwcdp_key = std::string("d")+wc_key_+std::string("_d")+pres_key_;
  S_next_->GetFieldEvaluator(wc_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", pres_key_);
  const Epetra_MultiVector& dwcdp = *S_next_->GetFieldData(dwcdp_key)
      ->ViewComponent("cell",false);

  int ncells = mesh_->num_entities(AmanziMesh::CELL, AmanziMesh::OWNED);
  for (int c=0; c!=ncells; ++c) {
    jac_[c](0,0) = dwcdp[0][c];
    jac_[c](0,1) = dwcdT[0][c];
    jac_[c](1,0) = dedp[0][c];
    jac_[c](1,1) = dedT[0][c];
  }
}

} // namespace
<commit_msg>adds missing error message when undefined PC is used<commit_after>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */
/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Interface for EWC, a helper class that does projections and preconditioners in
energy/water-content space instead of temperature/pressure space.
------------------------------------------------------------------------- */
#include "FieldEvaluator.hh"
#include "ewc_model.hh"
#include "mpc_delegate_ewc.hh"

namespace Amanzi {

#define DEBUG_FLAG 1

// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
MPCDelegateEWC::MPCDelegateEWC(Teuchos::ParameterList& plist) :
    plist_(Teuchos::rcpFromRef(plist)) {
  // set up the VerboseObject
  std::string name = plist_->get<std::string>("PK name")+std::string(" EWC");
  vo_ = Teuchos::rcp(new VerboseObject(name, *plist_));
}

// -----------------------------------------------------------------------------
// Allocate any data or models required.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::setup(const Teuchos::Ptr<State>& S) {
  // Verbosity
  std::string name = plist_->get<std::string>("PK name")+std::string(" EWC");

  // Get the mesh
  Key domain = plist_->get<std::string>("domain key", "");
  if (domain.size() != 0) {
    mesh_ = S->GetMesh(domain);
  } else {
    mesh_ = S->GetMesh("domain");
  }

  // set up a debugger
  db_ = Teuchos::rcp(new Debugger(mesh_, name, *plist_));

  // Process the parameter list for data Keys
  if (domain.size() > 0) domain.append(1, '_');
  pres_key_ = plist_->get<std::string>("pressure key", domain+std::string("pressure"));
  temp_key_ = plist_->get<std::string>("temperature key",
          domain+std::string("temperature"));
  e_key_ = plist_->get<std::string>("energy key", domain+std::string("energy"));
  wc_key_ = plist_->get<std::string>("water content key",
          domain+std::string("water_content"));
  cv_key_ = plist_->get<std::string>("cell volume key",
          domain+std::string("cell_volume"));

  // Process the parameter list for methods
  std::string precon_string = plist_->get<std::string>("preconditioner type", "none");
  if (precon_string == "none") {
    precon_type_ = PRECON_NONE;
  } else if (precon_string == "ewc") {
    precon_type_ = PRECON_EWC;
    ASSERT(0);
  } else if (precon_string == "smart ewc") {
    precon_type_ = PRECON_SMART_EWC;
  } else {
    Errors::Message message;
    message << "EWC Delegate: invalid preconditioner string: \"" << precon_string
            << "\", valid are \"none\", \"ewc\", \"smart ewc\"";
    Exceptions::amanzi_throw(message);
  }

  // select the method used for nonlinear prediction
  std::string predictor_string = plist_->get<std::string>("predictor type", "none");
  if (predictor_string == "none") {
    predictor_type_ = PREDICTOR_NONE;
  } else if (predictor_string == "ewc") {
    predictor_type_ = PREDICTOR_EWC;
    ASSERT(0);
  } else if (predictor_string == "smart ewc") {
    predictor_type_ = PREDICTOR_SMART_EWC;
  } else {
    Errors::Message message;
    message << "EWC Delegate: invalid predictor string: \"" << predictor_string
            << "\", valid are \"none\", \"ewc\", \"smart ewc\"";
    Exceptions::amanzi_throw(message);
  }

  // Smart EWC uses a heuristic to guess when we need the EWC instead of using
  // it blindly.
  if (predictor_type_ == PREDICTOR_SMART_EWC || precon_type_ == PRECON_SMART_EWC) {
    if (plist_->isParameter("cusp distance in T")) {
      cusp_size_T_freezing_ = plist_->get<double>("cusp distance in T");
      cusp_size_T_thawing_ = cusp_size_T_freezing_;
    } else {
      cusp_size_T_freezing_ = plist_->get<double>("cusp distance in T, freezing", 0.005);
      cusp_size_T_thawing_ = plist_->get<double>("cusp distance in T, thawing", 0.005);
    }
  }
}

// -----------------------------------------------------------------------------
// Initialize any data required in setup.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::initialize(const Teuchos::Ptr<State>& S) {
  // Create and initialize old stored data for previous steps.
  if (predictor_type_ == PREDICTOR_EWC || predictor_type_ == PREDICTOR_SMART_EWC) {
    const Epetra_MultiVector& wc = *S->GetFieldData(wc_key_)
        ->ViewComponent("cell",false);
    const Epetra_MultiVector& e = *S->GetFieldData(e_key_)
        ->ViewComponent("cell",false);

    wc_prev2_ = Teuchos::rcp(new Epetra_MultiVector(wc));
    e_prev2_ = Teuchos::rcp(new Epetra_MultiVector(e));
    wc_prev2_->PutScalar(0.);
    e_prev2_->PutScalar(0.);

    time_prev2_ = S->time();
  }

  // initialize the Jacobian
  if (precon_type_ == PRECON_EWC || precon_type_ == PRECON_SMART_EWC) {
    int ncells = mesh_->num_entities(AmanziMesh::CELL, AmanziMesh::OWNED);
    jac_.resize(ncells, WhetStone::Tensor(2,2));
  }

  // initialize the model, which grabs all needed models from state
  model_->InitializeModel(S);
}

// -----------------------------------------------------------------------------
// Set state pointers.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::set_states(const Teuchos::RCP<const State>& S,
        const Teuchos::RCP<State>& S_inter,
        const Teuchos::RCP<State>& S_next) {
  S_= S;
  S_inter_ = S_inter;
  S_next_ = S_next;
}

// -----------------------------------------------------------------------------
// Save info from previous iterations if needed.
// -----------------------------------------------------------------------------
void MPCDelegateEWC::commit_state(double dt, const Teuchos::RCP<State>& S) {
  if ((predictor_type_ == PREDICTOR_EWC || predictor_type_ == PREDICTOR_SMART_EWC)
      && S_inter_ != Teuchos::null) {
    // stash water content and energy in S_work.
    *wc_prev2_ = *S_inter_->GetFieldData(wc_key_)->ViewComponent("cell",false);
    *e_prev2_ = *S_inter_->GetFieldData(e_key_)->ViewComponent("cell",false);
    time_prev2_ = S_inter_->time();
  }
}

// -----------------------------------------------------------------------------
// Modify the prediction from linearization of the time integration.
// -----------------------------------------------------------------------------
bool MPCDelegateEWC::ModifyPredictor(double h, Teuchos::RCP<TreeVector> up) {
  bool modified = false;
  double dt_prev = S_inter_->time() - time_prev2_;

  if (predictor_type_ == PREDICTOR_EWC) {
    if (dt_prev > 0.) {
      ASSERT(0);
      //      modified = modify_predictor_ewc_(h,up);
    }
  } else if (predictor_type_ == PREDICTOR_SMART_EWC) {
    if (dt_prev > 0.) {
      modified = modify_predictor_smart_ewc_(h,up);
    }
  }
  return modified;
}

// -----------------------------------------------------------------------------
// Update of the preconditioner
// -----------------------------------------------------------------------------
void MPCDelegateEWC::UpdatePreconditioner(double t, Teuchos::RCP<const TreeVector> up, double h) {
  if (precon_type_ == PRECON_EWC || precon_type_ == PRECON_SMART_EWC) {
    update_precon_ewc_(t,up,h);
  }
}

// -----------------------------------------------------------------------------
// Application of the preconditioner.
// -----------------------------------------------------------------------------
int MPCDelegateEWC::ApplyPreconditioner(Teuchos::RCP<const TreeVector> u, Teuchos::RCP<TreeVector> Pu) {
  int ierr = 0;
  if ((precon_type_ == PRECON_EWC) || (precon_type_ == PRECON_SMART_EWC)) {
    precon_ewc_(u,Pu);
  }
  else ierr = 1;

  return ierr;
}

void MPCDelegateEWC::update_precon_ewc_(double t, Teuchos::RCP<const TreeVector> up, double h) {
  Key dedT_key = std::string("d")+e_key_+std::string("_d")+temp_key_;
  S_next_->GetFieldEvaluator(e_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", temp_key_);
  const Epetra_MultiVector& dedT = *S_next_->GetFieldData(dedT_key)
      ->ViewComponent("cell",false);

  Key dedp_key = std::string("d")+e_key_+std::string("_d")+pres_key_;
  S_next_->GetFieldEvaluator(e_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", pres_key_);
  const Epetra_MultiVector& dedp = *S_next_->GetFieldData(dedp_key)
      ->ViewComponent("cell",false);

  Key dwcdT_key = std::string("d")+wc_key_+std::string("_d")+temp_key_;
  S_next_->GetFieldEvaluator(wc_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", temp_key_);
  const Epetra_MultiVector& dwcdT = *S_next_->GetFieldData(dwcdT_key)
      ->ViewComponent("cell",false);

  Key dwcdp_key = std::string("d")+wc_key_+std::string("_d")+pres_key_;
  S_next_->GetFieldEvaluator(wc_key_)
      ->HasFieldDerivativeChanged(S_next_.ptr(), "ewc", pres_key_);
  const Epetra_MultiVector& dwcdp = *S_next_->GetFieldData(dwcdp_key)
      ->ViewComponent("cell",false);

  int ncells = mesh_->num_entities(AmanziMesh::CELL, AmanziMesh::OWNED);
  for (int c=0; c!=ncells; ++c) {
    jac_[c](0,0) = dwcdp[0][c];
    jac_[c](0,1) = dwcdT[0][c];
    jac_[c](1,0) = dedp[0][c];
    jac_[c](1,1) = dedT[0][c];
  }
}

} // namespace
<|endoftext|>


<commit_before>#pragma ident "$Id$"

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S.
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software.
//
//Pursuant to DoD Directive 523024
//
// DISTRIBUTION STATEMENT A: This software has been approved for public
//                           release, distribution is unlimited.
//
//=============================================================================
#ifndef GPSTK_POWERSUM_HPP
#define GPSTK_POWERSUM_HPP

#include <iostream>
#include <list>

namespace gpstk
{
   /* This class computes the power sums of a list of numbers and computes
      various statistical values based upon these sums. This is a generalization
      of the Stats class that supports the higher-order moments. See
      http://mathworld.wolfram.com/PowerSum.html for a discussion of this approach.
   */
   class PowerSum
   {
   public:
      PowerSum() {clear();};

      const static int order = 4;

      /// Reset all sums
      void clear() throw();

      /// Add a single value to the sums
      void add(double x) throw();

      /// Remove a single value from the sums. Note that the higher order sums
      /// can get quite large in magnitude. When removing a value that is
      /// far from the average, it is possible for numerical error to creep
      /// into the sums. One way around this is to simply recompute the sums
      /// from scratch when this happens.
      void subtract(double x) throw();

      typedef std::list<double>::const_iterator dlc_iterator;

      /// Adds all value in the list to the sums.
      void add(dlc_iterator b, dlc_iterator e) throw();

      /// Removes all values in the list from the sums. See the warning with the
      /// subtract(double) method.
      void subtract(dlc_iterator b, dlc_iterator e) throw();

      /// Computes the ith order central moment
      double moment(int i) const throw();

      /// Computes the indicated value
      double average() const throw();
      double variance() const throw();
      double skew() const throw();
      double kurtosis() const throw();

      void dump(std::ostream& str) const throw();

   private:
      double s[order+1];
      long n;
/*
  These are used to determine kurtosis values for specific confidence based upon
  the sample size.
  const double pnt[]={
  5,    7,    8,    9,   10,   12,   15,   20,   25,
  30,   40,   50,   75,  100,  200,  500, 1000, 1e5, 1.e30};
  // 5% critical values
  const double cv5[] = {
  2.90, 3.55, 3.70, 3.86, 3.95, 4.05, 4.13, 4.17, 4.16,
  4.11, 4.06, 3.99, 3.87, 3.77, 3.57, 3.37, 3.26, 3.10, 3.00};
  // 1% critical values
  const double cv1[]= {
  3.10, 4.23, 4.53, 4.82, 5.00, 5.20, 5.30, 5.36, 5.30,
  5.21, 5.04, 4.88, 4.59, 4.39, 3.98, 3.60, 3.41, 3.20, 3.00};
*/
   };

}
#endif
<commit_msg>Providing an accessor for the number of points added<commit_after>#pragma ident "$Id$"

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S.
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software.
//
//Pursuant to DoD Directive 523024
//
// DISTRIBUTION STATEMENT A: This software has been approved for public
//                           release, distribution is unlimited.
//
//=============================================================================
#ifndef GPSTK_POWERSUM_HPP
#define GPSTK_POWERSUM_HPP

#include <iostream>
#include <list>

namespace gpstk
{
   /* This class computes the power sums of a list of numbers and computes
      various statistical values based upon these sums. This is a generalization
      of the Stats class that supports the higher-order moments. See
      http://mathworld.wolfram.com/PowerSum.html for a discussion of this approach.
   */
   class PowerSum
   {
   public:
      PowerSum() {clear();};

      const static int order = 4;

      /// Reset all sums
      void clear() throw();

      /// Add a single value to the sums
      void add(double x) throw();

      /// Remove a single value from the sums. Note that the higher order sums
      /// can get quite large in magnitude. When removing a value that is
      /// far from the average, it is possible for numerical error to creep
      /// into the sums. One way around this is to simply recompute the sums
      /// from scratch when this happens.
      void subtract(double x) throw();

      typedef std::list<double>::const_iterator dlc_iterator;

      /// Adds all value in the list to the sums.
      void add(dlc_iterator b, dlc_iterator e) throw();

      /// Removes all values in the list from the sums. See the warning with the
      /// subtract(double) method.
      void subtract(dlc_iterator b, dlc_iterator e) throw();

      /// Computes the ith order central moment
      double moment(int i) const throw();

      /// Reuturn the number of points in the current sum
      long size() const throw() {return n;}

      /// Computes the indicated value
      double average() const throw();
      double variance() const throw();
      double skew() const throw();
      double kurtosis() const throw();

      void dump(std::ostream& str) const throw();

   private:
      double s[order+1];
      long n;
/*
  These are used to determine kurtosis values for specific confidence based upon
  the sample size.
  const double pnt[]={
  5,    7,    8,    9,   10,   12,   15,   20,   25,
  30,   40,   50,   75,  100,  200,  500, 1000, 1e5, 1.e30};
  // 5% critical values
  const double cv5[] = {
  2.90, 3.55, 3.70, 3.86, 3.95, 4.05, 4.13, 4.17, 4.16,
  4.11, 4.06, 3.99, 3.87, 3.77, 3.57, 3.37, 3.26, 3.10, 3.00};
  // 1% critical values
  const double cv1[]= {
  3.10, 4.23, 4.53, 4.82, 5.00, 5.20, 5.30, 5.36, 5.30,
  5.21, 5.04, 4.88, 4.59, 4.39, 3.98, 3.60, 3.41, 3.20, 3.00};
*/
   };

}
#endif
<|endoftext|>


<commit_before>///
/// @file   PreSieve.cpp
/// @brief  Pre-sieve multiples of small primes to speed up the sieve
///         of Eratosthenes. At startup primesieve initializes a small
///         buffer of size p1*p2*p3*pn and removes the multiples of
///         the first n primes from that buffer. Then while sieving at
///         the start of each new segment this buffer is simply copied
///         to the sieve array and now we can start sieving at p(n+1)
///         instead of p1. By default primesieve pre-sieves multiples
///         of primes <= 19, in practice pre-sieving using even larger
///         primes uses too much memory and slows things down. In
///         primesieve pre-sieving provides a minor speed of up to 20%
///         when the sieving distance is relatively small
///         e.g. < 10^10.
///
///         The pre-sieve buffer can be both smaller or larger than
///         the actual sieve array so a little care needs to be taken
///         when copying the buffer to the sieve array. When the
///         buffer is smaller than the sieve array we need to
///         repeatedly copy the buffer to the sieve array until the
///         sieve array has been filled completely. When the buffer is
///         larger than the sieve array we only need to partially copy
///         it to the sieve array.
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/PreSieve.hpp>
#include <primesieve/EratSmall.hpp>
#include <primesieve/pmath.hpp>

#include <stdint.h>
#include <algorithm>
#include <array>
#include <iterator>
#include <memory>

using namespace std;

namespace {

// small primes >= 7
const array<uint64_t, 5> primes = { 7, 11, 13, 17, 19 };

// prime products of primes >= 7
const array<uint64_t, 5> primeProducts = { 210, 2310, 30030, 510510, 9699690 };

} // namespace

namespace primesieve {

void PreSieve::init(uint64_t start,
                    uint64_t stop)
{
  // the pre-sieve buffer should be at least 10
  // times smaller than the sieving distance
  // in order to reduce initialization overhead
  uint64_t dist = stop - start;
  uint64_t threshold = max(dist, isqrt(stop)) / 100;
  auto last =  primeProducts.end() - 1;
  auto iter = lower_bound(primeProducts.begin(), last, threshold);
  auto i = distance(primeProducts.begin(), iter);

  if (primes.at(i) > maxPrime_)
    initBuffer(primes[i], primeProducts[i]);
}

/// Initialize the buffer by removing the
/// multiples of primes <= maxPrime.
///
void PreSieve::initBuffer(uint64_t maxPrime,
                          uint64_t primeProduct)
{
  maxPrime_ = maxPrime;
  primeProduct_ = primeProduct;
  size_ = primeProduct_ / 30;

  buffer_ = new uint8_t[size_];
  deleter_.reset(buffer_);
  fill_n(buffer_, size_, (uint8_t) 0xff);

  EratSmall eratSmall;
  uint64_t stop = primeProduct_ * 2;
  eratSmall.init(stop, size_, maxPrime_);

  for (uint64_t prime : primes)
    if (prime <= maxPrime_)
      eratSmall.addSievingPrime(prime, primeProduct_);

  eratSmall.crossOff(buffer_, size_);
}

/// Copy pre-sieved buffer to sieve array
void PreSieve::copy(uint8_t* sieve,
                    uint64_t sieveSize,
                    uint64_t segmentLow) const
{
  // find segmentLow index
  uint64_t remainder = segmentLow % primeProduct_;
  uint64_t i = remainder / 30;
  uint64_t sizeLeft = size_ - i;

  if (sieveSize <= sizeLeft)
    copy_n(&buffer_[i], sieveSize, sieve);
  else
  {
    // copy the last remaining bytes of buffer
    // to the beginning of the sieve array
    copy_n(&buffer_[i], sizeLeft, sieve);

    // restart copying at the beginning of buffer
    for (i = sizeLeft; i + size_ < sieveSize; i += size_)
      copy_n(buffer_, size_, &sieve[i]);

    // copy the last remaining bytes
    copy_n(buffer_, sieveSize - i, &sieve[i]);
  }
}

} // namespace
<commit_msg>Fix comment<commit_after>///
/// @file   PreSieve.cpp
/// @brief  Pre-sieve multiples of small primes to speed up the sieve
///         of Eratosthenes. At startup primesieve initializes a small
///         buffer of size p1*p2*p3*pn and removes the multiples of
///         the first n primes from that buffer. Then while sieving at
///         the start of each new segment this buffer is simply copied
///         to the sieve array and now we can start sieving at p(n+1)
///         instead of p1. By default primesieve pre-sieves multiples
///         of primes <= 19, in practice pre-sieving using even larger
///         primes uses too much memory and slows things down. In
///         primesieve pre-sieving provides a minor speed of up to 20%
///         when the sieving distance is relatively small
///         e.g. < 10^10.
///
///         The pre-sieve buffer can be both smaller or larger than
///         the actual sieve array so a little care needs to be taken
///         when copying the buffer to the sieve array. When the
///         buffer is smaller than the sieve array we need to
///         repeatedly copy the buffer to the sieve array until the
///         sieve array has been filled completely. When the buffer is
///         larger than the sieve array we only need to partially copy
///         it to the sieve array.
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/PreSieve.hpp>
#include <primesieve/EratSmall.hpp>
#include <primesieve/pmath.hpp>

#include <stdint.h>
#include <algorithm>
#include <array>
#include <iterator>
#include <memory>

using namespace std;

namespace {

// Small primes >= 7
const array<uint64_t, 5> primes = { 7, 11, 13, 17, 19 };

// Prime products of primes >= 7
const array<uint64_t, 5> primeProducts = { 210, 2310, 30030, 510510, 9699690 };

} // namespace

namespace primesieve {

void PreSieve::init(uint64_t start,
                    uint64_t stop)
{
  // The pre-sieve buffer should be at least 100
  // times smaller than the sieving distance
  // in order to reduce initialization overhead.
  uint64_t dist = stop - start;
  uint64_t threshold = max(dist, isqrt(stop)) / 100;
  auto last =  primeProducts.end() - 1;
  auto iter = lower_bound(primeProducts.begin(), last, threshold);
  auto i = distance(primeProducts.begin(), iter);

  if (primes.at(i) > maxPrime_)
    initBuffer(primes[i], primeProducts[i]);
}

/// Initialize the buffer by removing the
/// multiples of primes <= maxPrime.
///
void PreSieve::initBuffer(uint64_t maxPrime,
                          uint64_t primeProduct)
{
  maxPrime_ = maxPrime;
  primeProduct_ = primeProduct;
  size_ = primeProduct_ / 30;

  buffer_ = new uint8_t[size_];
  deleter_.reset(buffer_);
  fill_n(buffer_, size_, (uint8_t) 0xff);

  EratSmall eratSmall;
  uint64_t stop = primeProduct_ * 2;
  eratSmall.init(stop, size_, maxPrime_);

  for (uint64_t prime : primes)
    if (prime <= maxPrime_)
      eratSmall.addSievingPrime(prime, primeProduct_);

  eratSmall.crossOff(buffer_, size_);
}

/// Copy pre-sieved buffer to sieve array
void PreSieve::copy(uint8_t* sieve,
                    uint64_t sieveSize,
                    uint64_t segmentLow) const
{
  // Find segmentLow index
  uint64_t remainder = segmentLow % primeProduct_;
  uint64_t i = remainder / 30;
  uint64_t sizeLeft = size_ - i;

  if (sieveSize <= sizeLeft)
    copy_n(&buffer_[i], sieveSize, sieve);
  else
  {
    // Copy the last remaining bytes of buffer
    // to the beginning of the sieve array
    copy_n(&buffer_[i], sizeLeft, sieve);

    // Restart copying at the beginning of buffer
    for (i = sizeLeft; i + size_ < sieveSize; i += size_)
      copy_n(buffer_, size_, &sieve[i]);

    // Copy the last remaining bytes
    copy_n(buffer_, sieveSize - i, &sieve[i]);
  }
}

} // namespace
<|endoftext|>


<commit_before><commit_msg>Updating for the new way of getting data from sensors.<commit_after><|endoftext|>


<commit_before>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtGui module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtwindowsystem.h"
#include <QLibrary>
#include <QX11Info>
#include <X11/Xutil.h>

static void qxt_getWindowProperty(Window wid, Atom prop, int maxlen, Window** data, int* count)
{
    Atom type = 0;
    int format = 0;
    unsigned long after = 0;
    XGetWindowProperty(QX11Info::display(), wid, prop, 0, maxlen / 4, False, AnyPropertyType,
                       &type, &format, (unsigned long*) count, &after, (unsigned char**) data);
}

static QRect qxt_getWindowRect(Window wid)
{
    QRect rect;
    XWindowAttributes attr;
    if (XGetWindowAttributes(QX11Info::display(), wid, &attr))
    {
        rect = QRect(attr.x, attr.y, attr.width, attr.height);
    }
    return rect;
}

WindowList QxtWindowSystem::windows()
{
    static Atom net_clients = 0;
    if (!net_clients)
        net_clients = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", True);

    int count = 0;
    Window* list = 0;
    qxt_getWindowProperty(QX11Info::appRootWindow(), net_clients, 1024 * sizeof(Window), &list, &count);

    WindowList res;
    for (int i = 0; i < count; ++i)
        res += list[i];
    XFree(list);
    return res;
}

WId QxtWindowSystem::activeWindow()
{
    static Atom net_active = 0;
    if (!net_active)
        net_active = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True);

    int count = 0;
    Window* list = 0;
    qxt_getWindowProperty(QX11Info::appRootWindow(), net_active, 1024 * sizeof(Window), &list, &count);

    Window res = 0;
    if (count)
        res = list[0];
    XFree(list);
    return res;
}

WId QxtWindowSystem::findWindow(const QString& title)
{
    Window result = 0;
    WindowList list = windows();
    foreach(const Window &wid, list)
    {
        if (windowTitle(wid) == title)
        {
            result = wid;
            break;
        }
    }
    return result;
}

WId QxtWindowSystem::windowAt(const QPoint& pos)
{
    Window result = 0;
    WindowList list = windows();
    for (int i = list.size() - 1; i >= 0; --i)
    {
        WId wid = list.at(i);
        if (windowGeometry(wid).contains(pos))
        {
            result = wid;
            break;
        }
    }
    return result;
}

QString QxtWindowSystem::windowTitle(WId window)
{
    QString name;
    char* str = 0;
    if (XFetchName(QX11Info::display(), window, &str))
    {
        name = QString::fromLatin1(str);
    }
    XFree(str);
    return name;
}

QRect QxtWindowSystem::windowGeometry(WId window)
{
    QRect rect = qxt_getWindowRect(window);

    Window root = 0;
    Window parent = 0;
    Window* children = 0;
    unsigned int count = 0;
    Display* display = QX11Info::display();
    if (XQueryTree(display, window, &root, &parent, &children, &count))
    {
        window = parent; // exclude decoration
        XFree(children);
        while (window != 0 && XQueryTree(display, window, &root, &parent, &children, &count))
        {
            XWindowAttributes attr;
            if (parent != 0 && XGetWindowAttributes(display, parent, &attr))
                rect.translate(QRect(attr.x, attr.y, attr.width, attr.height).topLeft());
            window = parent;
            XFree(children);
        }
    }
    return rect;
}

typedef struct {
    Window  window;     /* screen saver window - may not exist */
    int     state;      /* ScreenSaverOff, ScreenSaverOn, ScreenSaverDisabled*/
    int     kind;       /* ScreenSaverBlanked, ...Internal, ...External */
    unsigned long    til_or_since;   /* time til or since screen saver */
    unsigned long    idle;      /* total time since last user input */
    unsigned long   eventMask; /* currently selected events for this client */
} XScreenSaverInfo;

typedef XScreenSaverInfo* (*XScreenSaverAllocInfo)();
typedef Status (*XScreenSaverQueryInfo)(Display* display, Drawable* drawable, XScreenSaverInfo* info);

static XScreenSaverAllocInfo _xScreenSaverAllocInfo = 0;
static XScreenSaverQueryInfo _xScreenSaverQueryInfo = 0;

uint QxtWindowSystem::idleTime()
{
    static bool xssResolved = false;
    if (!xssResolved) {
        QLibrary xssLib(QLatin1String("Xss"), 1);
        if (xssLib.load()) {
            _xScreenSaverAllocInfo = (XScreenSaverAllocInfo) xssLib.resolve("XScreenSaverAllocInfo");
            _xScreenSaverQueryInfo = (XScreenSaverQueryInfo) xssLib.resolve("XScreenSaverQueryInfo");
            xssResolved = true;
        }
    }

    uint idle = 0;
    if (xssResolved)
    {
        XScreenSaverInfo* info = _xScreenSaverAllocInfo();
        const int screen = QX11Info::appScreen();
        Qt::HANDLE rootWindow = QX11Info::appRootWindow(screen);
        _xScreenSaverQueryInfo(QX11Info::display(), (Drawable*) rootWindow, info);
        idle = info->idle;
        XFree(info);
    }
    return idle;
}
<commit_msg>Fixed #85 QxtWindowSystem::windowGeometry issue<commit_after>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtGui module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtwindowsystem.h"
#include <QLibrary>
#include <QX11Info>
#include <X11/Xutil.h>

static void qxt_getWindowProperty(Window wid, Atom prop, int maxlen, Window** data, int* count)
{
    Atom type = 0;
    int format = 0;
    unsigned long after = 0;
    XGetWindowProperty(QX11Info::display(), wid, prop, 0, maxlen / 4, False, AnyPropertyType,
                       &type, &format, (unsigned long*) count, &after, (unsigned char**) data);
}

WindowList QxtWindowSystem::windows()
{
    static Atom net_clients = 0;
    if (!net_clients)
        net_clients = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", True);

    int count = 0;
    Window* list = 0;
    qxt_getWindowProperty(QX11Info::appRootWindow(), net_clients, 1024 * sizeof(Window), &list, &count);

    WindowList res;
    for (int i = 0; i < count; ++i)
        res += list[i];
    XFree(list);
    return res;
}

WId QxtWindowSystem::activeWindow()
{
    static Atom net_active = 0;
    if (!net_active)
        net_active = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True);

    int count = 0;
    Window* list = 0;
    qxt_getWindowProperty(QX11Info::appRootWindow(), net_active, 1024 * sizeof(Window), &list, &count);

    Window res = 0;
    if (count)
        res = list[0];
    XFree(list);
    return res;
}

WId QxtWindowSystem::findWindow(const QString& title)
{
    Window result = 0;
    WindowList list = windows();
    foreach(const Window &wid, list)
    {
        if (windowTitle(wid) == title)
        {
            result = wid;
            break;
        }
    }
    return result;
}

WId QxtWindowSystem::windowAt(const QPoint& pos)
{
    Window result = 0;
    WindowList list = windows();
    for (int i = list.size() - 1; i >= 0; --i)
    {
        WId wid = list.at(i);
        if (windowGeometry(wid).contains(pos))
        {
            result = wid;
            break;
        }
    }
    return result;
}

QString QxtWindowSystem::windowTitle(WId window)
{
    QString name;
    char* str = 0;
    if (XFetchName(QX11Info::display(), window, &str))
    {
        name = QString::fromLatin1(str);
    }
    XFree(str);
    return name;
}

QRect QxtWindowSystem::windowGeometry(WId window)
{
    int x, y;
    uint width, height, border, depth;
    Window root, child;
    Display* display = QX11Info::display();
    XGetGeometry(display, window, &root, &x, &y, &width, &height, &border, &depth);
    XTranslateCoordinates(display, window, root, x, y, &x, &y, &child);

    static Atom net_frame = 0;
    if (!net_frame)
        net_frame = XInternAtom(QX11Info::display(), "_NET_FRAME_EXTENTS", True);

    QRect rect(x, y, width, height);
    Atom type = 0;
    int format = 0;
    uchar* data = 0;
    ulong count, after;
    if (XGetWindowProperty(display, window, net_frame, 0, 4, False, AnyPropertyType,
                           &type, &format, &count, &after, &data) == Success)
    {
        // _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
        long* extents = reinterpret_cast<long*>(data);
        rect.adjust(-extents[0], -extents[2], extents[1], extents[3]);
        XFree(data);
    }
    return rect;
}

typedef struct {
    Window  window;     /* screen saver window - may not exist */
    int     state;      /* ScreenSaverOff, ScreenSaverOn, ScreenSaverDisabled*/
    int     kind;       /* ScreenSaverBlanked, ...Internal, ...External */
    unsigned long    til_or_since;   /* time til or since screen saver */
    unsigned long    idle;      /* total time since last user input */
    unsigned long   eventMask; /* currently selected events for this client */
} XScreenSaverInfo;

typedef XScreenSaverInfo* (*XScreenSaverAllocInfo)();
typedef Status (*XScreenSaverQueryInfo)(Display* display, Drawable* drawable, XScreenSaverInfo* info);

static XScreenSaverAllocInfo _xScreenSaverAllocInfo = 0;
static XScreenSaverQueryInfo _xScreenSaverQueryInfo = 0;

uint QxtWindowSystem::idleTime()
{
    static bool xssResolved = false;
    if (!xssResolved) {
        QLibrary xssLib(QLatin1String("Xss"), 1);
        if (xssLib.load()) {
            _xScreenSaverAllocInfo = (XScreenSaverAllocInfo) xssLib.resolve("XScreenSaverAllocInfo");
            _xScreenSaverQueryInfo = (XScreenSaverQueryInfo) xssLib.resolve("XScreenSaverQueryInfo");
            xssResolved = true;
        }
    }

    uint idle = 0;
    if (xssResolved)
    {
        XScreenSaverInfo* info = _xScreenSaverAllocInfo();
        const int screen = QX11Info::appScreen();
        Qt::HANDLE rootWindow = QX11Info::appRootWindow(screen);
        _xScreenSaverQueryInfo(QX11Info::display(), (Drawable*) rootWindow, info);
        idle = info->idle;
        XFree(info);
    }
    return idle;
}
<|endoftext|>


<commit_before><commit_msg>fixed access to private cmaes pli members<commit_after><|endoftext|>


<commit_before>#pragma once

#include <cstdint>
#include <initializer_list>
#include <unordered_map>

#include <boost/variant.hpp>

#include "utils/underlying.hpp"

#if defined(__clang__) || defined(GCC47)
#else
namespace std {

typedef double double_t;

} // namespace std
#endif

namespace blackhole {

namespace log {

typedef boost::variant<
    std::uint8_t,
    std::int32_t,
    std::uint64_t,
    std::int64_t,
    std::double_t,
    std::time_t,
    std::string
> attribute_value_t;

namespace attribute {

enum class scope : std::uint8_t {
    local       = 1 << 0,   /* user-defined event attributes*/
    event       = 1 << 1,   /* not user-defined event attributes, like timestamp or message */
    global      = 1 << 2,   /* logger object attributes*/
    thread      = 1 << 3,   /* thread attributes */
    universe    = 1 << 4    /* singleton attributes for entire application */
};

typedef aux::underlying_type<scope>::type scope_underlying_type;

static const scope DEFAULT_SCOPE = scope::local;

} // namespace attribute

struct attribute_t {
    attribute_value_t value; //!@note: Maybe create functor with map? struct keeper { value_t value; value_t operator(value_t) {} };
    attribute::scope scope;

    attribute_t() :
        value(std::uint8_t(0)),
        scope(attribute::DEFAULT_SCOPE)
    {}

    attribute_t(const attribute_value_t& value, attribute::scope type = attribute::DEFAULT_SCOPE) :
        value(value),
        scope(type)
    {}
};

typedef std::pair<
    std::string,
    attribute_t
> attribute_pair_t;

typedef std::unordered_map<
    attribute_pair_t::first_type,
    attribute_pair_t::second_type
> attributes_t;

} // namespace log

inline log::attributes_t merge(const std::initializer_list<log::attributes_t>& args) {
    log::attributes_t summary;
    for (auto it = args.begin(); it != args.end(); ++it) {
        summary.insert(it->begin(), it->end());
    }

    return summary;
}

namespace attribute {

// Dynamic attribute factory function.
template<typename T>
inline
log::attribute_pair_t make(const std::string& name, const T& value, log::attribute::scope scope = log::attribute::DEFAULT_SCOPE) {
    return std::make_pair(name, log::attribute_t(value, scope));
}

// Attribute packing/unpacking/extracting.
template<typename T, class = void>
struct traits {
    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return boost::get<T>(attributes.at(name).value);
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename aux::underlying_type<T>::type underlying_type;

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name).value));
    }
};

} // namespace attribute

} // namespace blackhole
<commit_msg>Adding attribute value type.<commit_after>#pragma once

#include <cstdint>
#include <initializer_list>
#include <unordered_map>

#include <boost/variant.hpp>

#include "utils/underlying.hpp"

#if defined(__clang__) || defined(GCC47)
#else
namespace std {

typedef double double_t;

} // namespace std
#endif

namespace blackhole {

namespace log {

typedef boost::variant<
    std::uint8_t,
    std::uint32_t,
    std::int32_t,
    std::uint64_t,
    std::int64_t,
    std::double_t,
    std::time_t,
    std::string
> attribute_value_t;

namespace attribute {

enum class scope : std::uint8_t {
    local       = 1 << 0,   /* user-defined event attributes*/
    event       = 1 << 1,   /* not user-defined event attributes, like timestamp or message */
    global      = 1 << 2,   /* logger object attributes*/
    thread      = 1 << 3,   /* thread attributes */
    universe    = 1 << 4    /* singleton attributes for entire application */
};

typedef aux::underlying_type<scope>::type scope_underlying_type;

static const scope DEFAULT_SCOPE = scope::local;

} // namespace attribute

struct attribute_t {
    attribute_value_t value; //!@note: Maybe create functor with map? struct keeper { value_t value; value_t operator(value_t) {} };
    attribute::scope scope;

    attribute_t() :
        value(std::uint8_t(0)),
        scope(attribute::DEFAULT_SCOPE)
    {}

    attribute_t(const attribute_value_t& value, attribute::scope type = attribute::DEFAULT_SCOPE) :
        value(value),
        scope(type)
    {}
};

typedef std::pair<
    std::string,
    attribute_t
> attribute_pair_t;

typedef std::unordered_map<
    attribute_pair_t::first_type,
    attribute_pair_t::second_type
> attributes_t;

} // namespace log

inline log::attributes_t merge(const std::initializer_list<log::attributes_t>& args) {
    log::attributes_t summary;
    for (auto it = args.begin(); it != args.end(); ++it) {
        summary.insert(it->begin(), it->end());
    }

    return summary;
}

namespace attribute {

// Dynamic attribute factory function.
template<typename T>
inline
log::attribute_pair_t make(const std::string& name, const T& value, log::attribute::scope scope = log::attribute::DEFAULT_SCOPE) {
    return std::make_pair(name, log::attribute_t(value, scope));
}

// Attribute packing/unpacking/extracting.
template<typename T, class = void>
struct traits {
    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return boost::get<T>(attributes.at(name).value);
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename aux::underlying_type<T>::type underlying_type;

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name).value));
    }
};

} // namespace attribute

} // namespace blackhole
<|endoftext|>


<commit_before><commit_msg>Fix multiple-definition issue with Curve::solve.<commit_after><|endoftext|>