forked from lijiext/lammps
252 lines
10 KiB
C++
252 lines
10 KiB
C++
// ATC transfer headers
|
|
#include "ElasticTimeIntegrator.h"
|
|
#include "ATC_Transfer.h"
|
|
#include "TimeFilter.h"
|
|
#include "ATC_Error.h"
|
|
|
|
namespace ATC {
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class ElasticTimeIntegrator
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
// Grab data from ATC
|
|
//--------------------------------------------------------
|
|
ElasticTimeIntegrator::ElasticTimeIntegrator(ATC_Transfer * atcTransfer,
|
|
TimeIntegrationType timeIntegrationType) :
|
|
TimeIntegrator(atcTransfer, timeIntegrationType)
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// modify
|
|
// parses inputs and modifies state of the filter
|
|
//--------------------------------------------------------
|
|
bool ElasticTimeIntegrator::modify(int narg, char **arg)
|
|
{
|
|
// currently no parsing for elastic time integration
|
|
return false;
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// initialize
|
|
// sets up all the necessary data
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegrator::initialize()
|
|
{
|
|
if (needReset_ || timeFilterManager_->need_reset()) {
|
|
if (timeIntegrationMethod_)
|
|
delete timeIntegrationMethod_;
|
|
|
|
if (timeFilterManager_->need_reset()) {
|
|
if (timeFilter_)
|
|
delete timeFilter_;
|
|
timeFilter_ = timeFilterManager_->construct(TimeFilterManager::IMPLICIT);
|
|
}
|
|
|
|
if (timeFilterManager_->filter_dynamics()) {
|
|
timeIntegrationMethod_ = new ElasticTimeIntegratorVerletFiltered(this);
|
|
}
|
|
else {
|
|
timeIntegrationMethod_ = new ElasticTimeIntegratorVerlet(this);
|
|
}
|
|
}
|
|
TimeIntegrator::initialize();
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class ElasticIntegrationMethod
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
// Grab data from ATC
|
|
//--------------------------------------------------------
|
|
ElasticIntegrationMethod::ElasticIntegrationMethod(ElasticTimeIntegrator * elasticTimeIntegrator) :
|
|
TimeIntegrationMethod(elasticTimeIntegrator),
|
|
timeFilter_(timeIntegrator_->get_time_filter()),
|
|
displacement_(atcTransfer_->get_field(DISPLACEMENT)),
|
|
velocity_(atcTransfer_->get_field(VELOCITY)),
|
|
acceleration_(atcTransfer_->get_field_roc(VELOCITY)),
|
|
nodalAtomicDisplacement_(atcTransfer_->get_atomic_field(DISPLACEMENT)),
|
|
nodalAtomicVelocity_(atcTransfer_->get_atomic_field(VELOCITY)),
|
|
velocityRhs_(atcTransfer_->get_field_rhs(VELOCITY)),
|
|
nodalAtomicForce_(atcTransfer_->get_fe_atomic_field_roc(VELOCITY)),
|
|
forceFilteringData_(atcTransfer_->get_aux_storage(VELOCITY))
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class ElasticTimeIntegratorVerlet
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
ElasticTimeIntegratorVerlet::ElasticTimeIntegratorVerlet(ElasticTimeIntegrator * elasticTimeIntegrator) :
|
|
ElasticIntegrationMethod(elasticTimeIntegrator)
|
|
{
|
|
TimeFilterManager * timeFilterManager = (timeIntegrator_->get_atc_transfer())->get_time_filter_manager();
|
|
if (timeFilterManager->need_reset()) {
|
|
timeFilter_->initialize(nodalAtomicForce_);
|
|
}
|
|
// reset filtering data, if needed
|
|
if (!(timeFilterManager->end_equilibrate())) {
|
|
forceFilteringData_.reset(atcTransfer_->get_nNodes(),atcTransfer_->get_nsd());
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// mid_initial_integrate1
|
|
// time integration at the mid-point of Verlet step 1
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerlet::mid_initial_integrate1(double dt)
|
|
{
|
|
explicit_1(velocity_,acceleration_,.5*dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// post_initial_integrate1
|
|
// time integration after Verlet step 1
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerlet::post_initial_integrate1(double dt)
|
|
{
|
|
// NOTE could use explicit_2 with velocityRhs_ as the 2nd derivative
|
|
// for improved accuracy, but this would be inconsistent with
|
|
// the atomic integration scheme
|
|
explicit_1(displacement_,velocity_,dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// pre_final_integrate1
|
|
// first time integration computations
|
|
// before Verlet step 2
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerlet::pre_final_integrate1(double dt)
|
|
{
|
|
// Compute MD contribution to FEM equation
|
|
DENS_MAT atomicForces;
|
|
atcTransfer_->compute_atomic_force(atomicForces,atcTransfer_->get_f());
|
|
atcTransfer_->restrict_volumetric_quantity(atomicForces,nodalAtomicForce_);
|
|
timeFilter_->apply_post_step2(forceFilteringData_,nodalAtomicForce_,dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// post_final_integrate1
|
|
// second time integration computations
|
|
// after Verlet step 2
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerlet::post_final_integrate1(double dt)
|
|
{
|
|
atcTransfer_->apply_inverse_mass_matrix(velocityRhs_,
|
|
acceleration_,
|
|
VELOCITY);
|
|
explicit_1(velocity_,acceleration_,.5*dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// post_process
|
|
// post processing of variables before output
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerlet::post_process(double dt)
|
|
{
|
|
DENS_MAT atomicQuantity;
|
|
atcTransfer_->compute_atomic_momentum(atomicQuantity,atcTransfer_->get_v());
|
|
atcTransfer_->project_md_volumetric_quantity(atomicQuantity,nodalAtomicVelocity_,VELOCITY);
|
|
|
|
atcTransfer_->compute_atomic_centerOfMass_displacement(atomicQuantity,atcTransfer_->get_x());
|
|
atcTransfer_->project_md_volumetric_quantity(atomicQuantity,nodalAtomicDisplacement_,VELOCITY);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class ElasticTimeIntegratorVerletFiltered
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
ElasticTimeIntegratorVerletFiltered::ElasticTimeIntegratorVerletFiltered(ElasticTimeIntegrator * elasticTimeIntegrator) :
|
|
ElasticTimeIntegratorVerlet(elasticTimeIntegrator),
|
|
nodalAtomicAcceleration_(atcTransfer_->get_atomic_field_roc(VELOCITY))
|
|
{
|
|
// swap filtered and unfiltered forces
|
|
if ((timeIntegrator_->get_time_filter_manager())->end_equilibrate()) {
|
|
DENS_MAT temp(nodalAtomicForce_);
|
|
nodalAtomicForce_ = forceFilteringData_;
|
|
forceFilteringData_ = temp;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// mid_initial_integrate1
|
|
// time integration at the mid-point of Verlet step 1
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerletFiltered::mid_initial_integrate1(double dt)
|
|
{
|
|
explicit_1(velocity_,acceleration_,.5*dt);
|
|
explicit_1(nodalAtomicVelocity_,nodalAtomicAcceleration_,.5*dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// post_initial_integrate1
|
|
// time integration after Verlet step 1
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerletFiltered::post_initial_integrate1(double dt)
|
|
{
|
|
// NOTE could use explicit_2 with velocityRhs_ as the 2nd derivative
|
|
// for improved accuracy, but this would be inconsistent with
|
|
// the atomic integration scheme
|
|
explicit_1(displacement_,velocity_,dt);
|
|
explicit_1(nodalAtomicDisplacement_,nodalAtomicVelocity_,dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// pre_final_integrate1
|
|
// first time integration computations
|
|
// before Verlet step 2
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerletFiltered::pre_final_integrate1(double dt)
|
|
{
|
|
// Compute MD contribution to FEM equation
|
|
DENS_MAT atomicForces;
|
|
atcTransfer_->compute_atomic_force(atomicForces,atcTransfer_->get_f());
|
|
|
|
// apply time filtering to instantaneous atomic force for FE equation
|
|
// NOTE would an explicit-implicit time filter be more accurate?
|
|
atcTransfer_->restrict_volumetric_quantity(atomicForces,forceFilteringData_);
|
|
timeFilter_->apply_post_step2(nodalAtomicForce_,forceFilteringData_,dt);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// post_final_integrate1
|
|
// second time integration computations
|
|
// after Verlet step 2
|
|
//--------------------------------------------------------
|
|
void ElasticTimeIntegratorVerletFiltered::post_final_integrate1(double dt)
|
|
{
|
|
DENS_MAT velocityRoc(velocityRhs_.nRows(),velocityRhs_.nCols());
|
|
atcTransfer_->apply_inverse_mass_matrix(velocityRhs_,
|
|
acceleration_,
|
|
VELOCITY);
|
|
explicit_1(velocity_,acceleration_,.5*dt);
|
|
|
|
atcTransfer_->apply_inverse_md_mass_matrix(nodalAtomicForce_,
|
|
nodalAtomicAcceleration_,
|
|
VELOCITY);
|
|
explicit_1(nodalAtomicVelocity_,nodalAtomicAcceleration_,.5*dt);
|
|
}
|
|
|
|
};
|