2013-08-08 05:34:54 +08:00
|
|
|
#ifndef CONCENTRATION_REGULATOR_H
|
|
|
|
#define CONCENTRATION_REGULATOR_H
|
|
|
|
|
2013-08-22 07:06:07 +08:00
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
|
2013-08-08 05:34:54 +08:00
|
|
|
#include "AtomicRegulator.h"
|
|
|
|
#include "LammpsInterface.h"
|
|
|
|
|
|
|
|
namespace ATC {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class ConcentrationRegulator
|
|
|
|
* @brief Manager class for atom-continuum control of charge and potential
|
|
|
|
*/
|
|
|
|
|
|
|
|
class ConcentrationRegulatorMethod;
|
|
|
|
class ConcentrationRegulator : public AtomicRegulator {
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum ConcentrationRegulatorType {NONE=0,TRANSITION};
|
|
|
|
/** parser data */
|
|
|
|
struct ConcentrationRegulatorParameters {
|
|
|
|
ConcentrationRegulatorParameters():
|
|
|
|
method(NONE),
|
|
|
|
type(0),
|
|
|
|
groupbit(0),
|
|
|
|
transitionType(0),
|
|
|
|
value(0),
|
|
|
|
frequency(0),
|
|
|
|
transitionInterval(0),
|
|
|
|
maxEnergy(0),
|
|
|
|
maxExchanges(0),
|
|
|
|
maxAttempts(0) { };
|
|
|
|
ConcentrationRegulatorType method;
|
|
|
|
int type;
|
|
|
|
int groupbit;
|
|
|
|
int transitionType;
|
|
|
|
double value;
|
|
|
|
int frequency;
|
|
|
|
int transitionInterval;
|
|
|
|
double maxEnergy;
|
|
|
|
int maxExchanges;
|
|
|
|
int maxAttempts;
|
2013-08-22 07:06:07 +08:00
|
|
|
std::string transitionTag;
|
2013-08-08 05:34:54 +08:00
|
|
|
ESET elemset;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** constructor */
|
|
|
|
ConcentrationRegulator(ATC_Coupling *atc);
|
|
|
|
/** destructor */
|
|
|
|
~ConcentrationRegulator();
|
|
|
|
/** parser/modifier */
|
|
|
|
virtual bool modify(int narg, char **arg);
|
|
|
|
/** construct methods */
|
|
|
|
virtual void construct_methods();
|
|
|
|
/** pre time integration */
|
|
|
|
virtual void initialize();
|
|
|
|
|
|
|
|
//WIP_JAT need a nicer way to consistently handle sets of regulators, not sure how yet
|
|
|
|
// application steps
|
|
|
|
/** apply the regulator in the pre-predictor phase */
|
|
|
|
virtual void apply_pre_predictor(double dt, int timeStep){};
|
|
|
|
/** apply the regulator in the mid-predictor phase */
|
|
|
|
virtual void apply_mid_predictor(double dt, int timeStep){};
|
|
|
|
/** apply the regulator in the post-predictor phase */
|
|
|
|
virtual void apply_post_predictor(double dt, int timeStep){};
|
|
|
|
/** apply the regulator in the pre-correction phase */
|
|
|
|
virtual void apply_pre_corrector(double dt, int timeStep){};
|
|
|
|
/** apply the regulator in the post-correction phase */
|
|
|
|
virtual void apply_post_corrector(double dt, int timeStep){};
|
|
|
|
/** compute the thermal boundary flux, must be consistent with regulator */
|
|
|
|
virtual void compute_boundary_flux(FIELDS & fields){};
|
|
|
|
/** add contributions (if any) to the finite element right-hand side */
|
|
|
|
virtual void add_to_rhs(FIELDS & rhs){};
|
|
|
|
|
|
|
|
/** prior to exchanges */
|
|
|
|
virtual void pre_force();
|
|
|
|
/** prior to exchanges */
|
|
|
|
virtual void pre_exchange();
|
2013-08-23 07:31:09 +08:00
|
|
|
/** following a run */
|
|
|
|
virtual void finish();
|
2013-08-08 05:34:54 +08:00
|
|
|
/** ATC output */
|
|
|
|
virtual void output(OUTPUT_LIST & outputData) const;
|
|
|
|
/** scalar output */
|
|
|
|
virtual double compute_vector(int n) const;
|
|
|
|
virtual int size_vector(int s) const;
|
|
|
|
|
|
|
|
bool needs_temperature() { return regulators_.size() > 0; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/** registry charge regulators */
|
2013-08-22 07:06:07 +08:00
|
|
|
std::map<std::string,ConcentrationRegulatorMethod *> regulators_;
|
|
|
|
std::map<std::string,ConcentrationRegulatorParameters> parameters_;
|
2013-08-08 05:34:54 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
ConcentrationRegulator(); // DO NOT define this
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class ConcentrationRegulatorMethod
|
|
|
|
* @brief Base class for ConcentrationRegulator algorithms
|
|
|
|
*/
|
|
|
|
|
|
|
|
class ConcentrationRegulatorMethod : public RegulatorShapeFunction {
|
|
|
|
|
|
|
|
public:
|
|
|
|
ConcentrationRegulatorMethod(ConcentrationRegulator *c)
|
|
|
|
: RegulatorShapeFunction(c) {};
|
|
|
|
~ConcentrationRegulatorMethod() {};
|
|
|
|
void initialize(void) {};
|
|
|
|
virtual void pre_force() {};
|
|
|
|
virtual void pre_exchange() {};
|
2013-08-23 07:31:09 +08:00
|
|
|
virtual void finish() {};
|
2013-08-08 05:34:54 +08:00
|
|
|
virtual void set_weights() {};
|
|
|
|
virtual double compute_vector(int n) const { return 0;}
|
|
|
|
virtual void output(OUTPUT_LIST & outputData){};
|
|
|
|
private:
|
|
|
|
ConcentrationRegulatorMethod(); // DO NOT define this
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class ConcentrationRegulatorMethodTransition
|
|
|
|
* @brief GCMC + thermodynamic integration
|
|
|
|
*/
|
|
|
|
class ConcentrationRegulatorMethodTransition : public ConcentrationRegulatorMethod {
|
|
|
|
|
|
|
|
public:
|
|
|
|
/** constructor */
|
|
|
|
ConcentrationRegulatorMethodTransition(
|
|
|
|
ConcentrationRegulator *concentrationRegulator,
|
|
|
|
ConcentrationRegulator::ConcentrationRegulatorParameters & parameters);
|
|
|
|
/** destructor */
|
|
|
|
~ConcentrationRegulatorMethodTransition(){
|
|
|
|
if (randomNumberGenerator_) delete randomNumberGenerator_;
|
|
|
|
}
|
|
|
|
/** initialize */
|
|
|
|
void initialize(void);
|
|
|
|
/** prior to force evaluation */
|
|
|
|
virtual void pre_force();
|
|
|
|
/** prior to exchanges */
|
|
|
|
virtual void pre_exchange();
|
|
|
|
/** "thermo" output */
|
|
|
|
virtual double compute_vector(int n) const;
|
|
|
|
protected:
|
|
|
|
/** set transition state: epsilon and charge */
|
|
|
|
int mask(int type, int groupbit) {return 0;}
|
|
|
|
int count(void) const;
|
|
|
|
int excess(void) const;
|
|
|
|
double energy(int id) const;
|
|
|
|
double energy(double * x) const;
|
|
|
|
double insertion_location(DENS_VEC & x) const;
|
|
|
|
double deletion_id(ID_PAIR & id) const ;
|
|
|
|
double deletion_id_consistent(ID_PAIR & id) const ;
|
|
|
|
double deletion_id_free(ID_PAIR & id) const ;
|
|
|
|
double insertion_factor(int c) const // a ramp
|
|
|
|
{
|
|
|
|
if (c < transitionInterval_) return ((double) c)/transitionInterval_;
|
|
|
|
else return 1.0;
|
|
|
|
}
|
|
|
|
void transition();
|
|
|
|
bool accept(double energy, double T = 0) const;
|
|
|
|
bool delete_atoms(int n);
|
|
|
|
bool insert_atoms(int n);
|
|
|
|
int pick_element() const;
|
|
|
|
void pick_coordinates(const int elem, DENS_VEC & xi, DENS_VEC& x ) const;
|
|
|
|
void pick_velocity(DENS_VEC & v, const double T ) const;
|
|
|
|
double uniform() const;
|
|
|
|
double normal() const;
|
|
|
|
|
|
|
|
/** pointer to conc regulator object for data */
|
|
|
|
ConcentrationRegulator * concentrationRegulator_;
|
|
|
|
|
|
|
|
/** interscale manager */
|
|
|
|
class InterscaleManager * interscaleManager_;
|
|
|
|
|
|
|
|
/** interscale manager */
|
|
|
|
class LammpsInterface * lammpsInterface_;
|
|
|
|
|
|
|
|
/** member data */
|
|
|
|
class AtomInElementSet * list_;
|
|
|
|
double targetConcentration_;
|
|
|
|
double targetCount_;
|
|
|
|
ESET elemset_;
|
|
|
|
POTENTIAL p_;
|
|
|
|
RNG_POINTER randomNumberGenerator_;
|
|
|
|
DENS_VEC volumes_;
|
|
|
|
double V_;
|
|
|
|
double q0_;
|
|
|
|
int controlType_;
|
|
|
|
int controlIndex_;
|
|
|
|
int transitionType_;
|
|
|
|
int transitionInterval_;;
|
|
|
|
int transitionCounter_;
|
|
|
|
int nInTransition_;
|
|
|
|
double transitionFactor_;
|
|
|
|
DENS_VEC epsilon0_;
|
|
|
|
ID_LIST deletionIds_, insertionIds_;
|
|
|
|
int controlMask_;
|
|
|
|
int frequency_;
|
|
|
|
double maxEnergy_;
|
|
|
|
int maxExchanges_;
|
|
|
|
int maxAttempts_;
|
|
|
|
int nexchanges_;
|
|
|
|
bool initialized_;
|
|
|
|
double sigma_;
|
|
|
|
|
|
|
|
void sync_random_number_generators() const;
|
|
|
|
mutable int _rngUniformCounter_; // for parallel consistency
|
|
|
|
mutable int _rngNormalCounter_; // for parallel consistency
|
|
|
|
|
|
|
|
private:
|
|
|
|
ConcentrationRegulatorMethodTransition(); // DO NOT define this
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|