示例#1
0
void LinearSolver::initialize(const BC_SET * bcs)
{
  if (bcs) { 
    if (! allowReinitialization_ ) throw ATC_Error("LinearSolver: reinitialization not allowed");
   //if (! bcs_ ) throw ATC_Error("LinearSolver: adding constraints after constructing without constraints is not allowed");
    // shallow --> deep copy
    if (! bcs_ ) { // constraintHandlerType_ == NO_CONSTRAINTS
      if (matrixModified_) {
        throw ATC_Error("LinearSolver: adding constraints after constructing without constraints is not allowed if matrix has been modified");
      }
      else {
        matrixCopy_ = *matrixSparse_;
        matrixSparse_ = &matrixCopy_;
        constraintHandlerType_ = -1;
        setup();
      }
    }
    bcs_ = bcs;
    initializedMatrix_ = false;
    initializedInverse_   = false;
    if (matrixModified_) {
      matrixCopy_ = matrixOriginal_;
      matrixSparse_ = &matrixCopy_;
    }
  }
  initialize_matrix();
  initialize_inverse();
  initialize_rhs();

  initialized_ = true;
}
 // solve ode with polynomial source : y'n + a_n-1 y'n-1 + ... = b_n x^n +...
 void integrate_ode(double x, 
   int na, double * a, double * y0, double * y, int nb, double *b )
 {
   if (na == 2) {
     // particular
     if ( a[1] == 0) {
       if ( a[0] == 0) { 
         y[0] = y0[0]+y0[1]*x;
         y[1] =       y0[1];
       }
       else {
         double c = sqrt(a[0]);
         y[0] =    y0[0]*cos(c*x)+y0[1]/c*sin(c*x);
         y[1] = -c*y0[0]*cos(c*x)+y0[1]  *sin(c*x);
       }
     }
     else {
       // use solve_quadratic
       throw ATC_Error("not yet supported");
     }
     // homogenous
     double c = 1.;
     double z = x;
     int j = 2;
     for (int i = 0; i < nb; i++,j++) {
       y[1] += j*c*z;
       c /= j;
       z *= x;
       y[0] += c*z;
     }  
   }
   else throw ATC_Error("can only integrate 2nd order ODEs currently");
 }
ElectronPhononExchangeHertel::ElectronPhononExchangeHertel(fstream &fileId,
                                                           map<string,double> & parameters,
                                                           Material * material) 
  : ElectronPhononExchange(),
    exchangeCoef_(0),
    debeyeTemperature_(1),
    massEnhancement_(0),
    material_(material)
{
  if (!fileId.is_open()) throw ATC_Error("cannot open material file");
  vector<string> line;
  while(fileId.good()) {
    command_line(fileId, line);
    if (line.size() == 0) continue;
    if (line[0] == "end") break;
    else if (line[0] == "debeye_temperature") {
      debeyeTemperature_ = str2dbl(line[1]);
      parameters["debeye_temperature"] = debeyeTemperature_;
    }
    else if (line[0] == "mass_enhancement") {
      massEnhancement_ = str2dbl(line[1]);
      parameters["mass_enhancement"] = massEnhancement_;
    }
    else {
      throw ATC_Error( "unrecognized material function "+line[0]);
    }
  }
  // coupling coefficient, eqn. 15 of Hertel 2002
  double kb = LammpsInterface::instance()->kBoltzmann();
  double hbar = LammpsInterface::instance()->hbar();
  double PI = 3.141592653589793238; 
  exchangeCoef_ = 144.*1.0369*kb/(PI*hbar);
  exchangeCoef_ *= massEnhancement_/pow(debeyeTemperature_,2);
}
示例#4
0
  //--------------------------------------------------------
  //  constuct a Green's submatrix 
  //--------------------------------------------------------
  void ChargeRegulatorMethodFeedback::set_influence_matrix(void)
  {
    // construct control-influence matrix bar{G}^-1: ds{p} = G{p,m}^-1 dphi{m}


//
    if (nInfluenceNodes_ < nControlNodes_) throw ATC_Error(" least square not implmented ");
    if (nInfluenceNodes_ > nControlNodes_) throw ATC_Error(" solve not possible ");
    DENS_MAT G(nInfluenceNodes_,nControlNodes_); 
    DENS_VEC G_I;
    set<int>::const_iterator itr,itr2,itr3;
    const Array<int> & nmap = atc_->fe_engine()->fe_mesh()->global_to_unique_map();
    int i = 0;
    for (itr = influenceNodes_.begin(); itr != influenceNodes_.end(); itr++) {
      poissonSolver_->greens_function(*itr, G_I);
      int j = 0;
      for (itr2 = controlNodes_.begin(); itr2 != controlNodes_.end(); itr2++) {
        int jnode = nmap(*itr2);
        G(i,j++) = G_I(jnode);  
      }
      i++;
    }
    invG_ = inv(G);

    // construct the prolong-restrict projector N N^T for influence nodes only

    InterscaleManager & interscaleManager(atc_->interscale_manager());
    const SPAR_MAT & N_Ia = (boundary_) ?
      (interscaleManager.per_atom_sparse_matrix("InterpolantGhost"))->quantity():
      (interscaleManager.per_atom_sparse_matrix("Interpolant"))->quantity();
    NT_.reset(nInfluenceAtoms_,nInfluenceNodes_);
    DENS_MAT NNT(nInfluenceNodes_,nInfluenceNodes_);
    int k = 0;
    for (itr3 = influenceAtoms_.begin(); itr3 != influenceAtoms_.end(); itr3++) {
      int katom = *itr3;
      int i = 0;
      for (itr = influenceNodes_.begin(); itr != influenceNodes_.end(); itr++) {
        int Inode = *itr;
        int j = 0;
        NT_(k,i) = N_Ia(katom,Inode);
        for (itr2 = influenceNodes_.begin(); itr2 != influenceNodes_.end(); itr2++) {
          int Jnode = *itr2;
          NNT(i,j++) += N_Ia(katom,Inode)*N_Ia(katom,Jnode);
        }
        i++;
      }
      k++;
    }
    // swap contributions across processors
    DENS_MAT localNNT = NNT;
    int count = NNT.nRows()*NNT.nCols(); 
    lammpsInterface_->allsum(localNNT.ptr(),NNT.ptr(),count);
    invNNT_ = inv(NNT);
  
    // total influence matrix
    if (nInfluenceAtoms_ > 0) { NTinvNNTinvG_ = NT_*invNNT_*invG_; }

  }
  //--------------------------------------------------------
  //  construct_methods
  //    creates algorithm objects
  //--------------------------------------------------------
  void MomentumTimeIntegrator::construct_methods()
  {
    if (atc_->reset_methods()) {
      if (timeIntegrationMethod_)
        delete timeIntegrationMethod_;
          
      if (timeFilterManager_->need_reset()) {
        switch (timeIntegrationType_) {
          case VERLET:
            timeFilter_ = timeFilterManager_->construct(TimeFilterManager::IMPLICIT);
            atc_->set_mass_mat_time_filter(MOMENTUM,TimeFilterManager::IMPLICIT);
            break;
          case FRACTIONAL_STEP:
          case GEAR:
            timeFilter_ = timeFilterManager_->construct(TimeFilterManager::EXPLICIT_IMPLICIT);
            atc_->set_mass_mat_time_filter(MOMENTUM,TimeFilterManager::EXPLICIT_IMPLICIT);
            break;
          default:
            throw ATC_Error("Uknown time integration type in ThermalTimeIntegrator::Initialize()");
        }
      }

      if (timeFilterManager_->filter_dynamics()) {
        switch (timeIntegrationType_) {
          case VERLET: {
            timeIntegrationMethod_ = new ElasticTimeIntegratorVerletFiltered(this);
            break;
          }
        default:
          throw ATC_Error("Uknown time integration type in MomentumTimeIntegrator::Initialize()");
        }
      }
      else {
        switch (timeIntegrationType_) {
          case VERLET: {
            timeIntegrationMethod_ = new ElasticTimeIntegratorVerlet(this);
            break;
          }
          case FRACTIONAL_STEP: {
            timeIntegrationMethod_ = new ElasticTimeIntegratorFractionalStep(this);
            break;
          }
          case GEAR: {
            timeIntegrationMethod_ = new FluidsTimeIntegratorGear(this);
            break;
          }
        default:
          throw ATC_Error("Uknown time integration type in MomentumTimeIntegrator::Initialize()");
        }
      }   
    }
  }
示例#6
0
 void send(MPI_Comm comm, double *send_buf,int send_size)
 {
   MPI_Status status;
   int tmp, error;
   error = MPI_Recv(&tmp,0,MPI_INT,0,0,comm,&status);
   error = error && MPI_Rsend(send_buf,send_size,MPI_DOUBLE,0,0,comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in int_send "+to_string(error));
 }
示例#7
0
 void int_allgather(MPI_Comm comm, int send, int* recv)
 {
   int send_count = 1;
   int recv_count = 1;
   int error = MPI_Allgather(&send, send_count, MPI_INT,
                             recv, recv_count,  MPI_INT, comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in allgatherv "+to_string(error));
 }
示例#8
0
// --------------------------------------------------------------------
//  Initialize
// --------------------------------------------------------------------
void LinearSolver::allow_reinitialization(void) 
{
  if (constraintHandlerType_ == PENALIZE_CONSTRAINTS) {
    if (matrixModified_ ) throw ATC_Error("LinearSolver: can't allow reinitialization after matrix has been modified");
    matrixOriginal_ = *matrixSparse_;
  }
  allowReinitialization_  = true;
}
示例#9
0
 void allgatherv(MPI_Comm comm, double *send_buf, int send_count,
                 double *rec_buf, int *rec_counts, int *displacements)
 {
   int error = MPI_Allgatherv(send_buf, send_count, MPI_DOUBLE,
                              rec_buf, rec_counts, displacements, MPI_DOUBLE,
                              comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in allgatherv "+to_string(error));
 }
示例#10
0
 void gather(MPI_Comm comm, double send, double* recv)
 {
   int send_count = 1;
   int recv_count = 1;
   int root = 0;
   int error = MPI_Gather(&send, send_count, MPI_DOUBLE,
                           recv, recv_count,  MPI_DOUBLE, root, comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in allgatherv "+to_string(error));
 }
示例#11
0
 //--------------------------------------------------------
 //  Initialize
 //--------------------------------------------------------
 void ChargeRegulatorMethodFeedback::initialize(void)
 {
   ChargeRegulatorMethod::initialize();
   if (surfaceType_ != ChargeRegulator::CONDUCTOR) 
     throw ATC_Error("currently charge feedback can only mimic a conductor");
   set_influence();  
   set_influence_matrix(); 
   initialized_ = true;
 }
ElectronPhononExchangeLinear::ElectronPhononExchangeLinear(
  fstream &fileId, map<string,double> & parameters) 
  : ElectronPhononExchange(),
  exchangeCoef_(0)
{
  if (!fileId.is_open()) throw ATC_Error("cannot open material file");
  vector<string> line;
  while(fileId.good()) {
    command_line(fileId, line);
    if (line.size() == 0) continue;
    if (line[0] == "end") return;
    else if (line[0] == "coefficient") {
      exchangeCoef_ = str2dbl(line[1]);
      parameters["electron_phonon_exchange_coefficient"] = exchangeCoef_;
    }
    else {
      throw ATC_Error( "unrecognized material function "+line[0]);
    }
  }
}
示例#13
0
 void recv(MPI_Comm comm, double *recv_buf, int max_size,int iproc)
 {
   MPI_Status status;
   MPI_Request request;
   int tmp, error, recv_size;
   error = MPI_Irecv(recv_buf,max_size,MPI_DOUBLE,iproc,0,comm,&request);
   error = error && MPI_Send(&tmp,0,MPI_INT,iproc,0,comm);
   error = error && MPI_Wait(&request,&status);
   error = error && MPI_Get_count(&status,MPI_DOUBLE,&recv_size);
   if (error != MPI_SUCCESS) throw ATC_Error("error in recv "+to_string(error));
 }
示例#14
0
  //--------------------------------------------------------
  // construct methods
  //--------------------------------------------------------
  void ChargeRegulator::construct_methods()
  {
    AtomicRegulator::construct_methods();

    if (atc_->reset_methods()) {
      // eliminate existing methods
      delete_method();
      // consruct new ones
      map<string, ChargeRegulatorParameters>::iterator itr;
      for (itr = parameters_.begin();
           itr != parameters_.end(); itr++) {
        string tag = itr->first;
        if (regulators_.find(tag) != regulators_.end()) delete regulators_[tag];
        ChargeRegulatorParameters & p = itr->second;
        LammpsInterface * lammpsInterface = LammpsInterface::instance();
        p.groupBit = lammpsInterface->group_bit(tag);
        if (! p.groupBit)
          throw ATC_Error("ChargeRegulator::initialize group not found");
        switch (p.method) {
        case NONE: {
          regulators_[tag] = new ChargeRegulatorMethod(this,p);
          break;
        }
        case FEEDBACK: {
          regulators_[tag] = new ChargeRegulatorMethodFeedback(this,p);
          break;
        }
        case IMAGE_CHARGE: {
          regulators_[tag] = new ChargeRegulatorMethodImageCharge(this,p);
          break;
        }
        case EFFECTIVE_CHARGE: {
          regulators_[tag] = new ChargeRegulatorMethodEffectiveCharge(this,p);
          break;
        }
        default: 
          throw ATC_Error("ChargeRegulator::construct_method unknown charge regulator type");
        }
      }
    }
  }
示例#15
0
 //------------------------------------------------------------------------
 // constructor
 ATC_HardyKernelQuarticSphere::ATC_HardyKernelQuarticSphere
   (int nparameters, double* parameters): 
   ATC_HardyKernel(nparameters, parameters) 
 {
   for (int k = 0; k < nsd_; k++ ) {
     if ((bool) periodicity[k]) {
       if (Rc_ > 0.5*box_length[k]) {
         throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
       };
     };
   };
 }
示例#16
0
 void int_scatter(MPI_Comm comm, int *send_buf, int *rec_buf, int count)
 {
   int error;
   int numprocs = size(comm);
   int sizes[numprocs];
   int displacements[numprocs];
   for (int i = 0; i < numprocs; ++i) {
     sizes[i] = 1;
     displacements[i] = i;
   }
   error = MPI_Scatterv(send_buf, sizes, displacements, MPI_INT, rec_buf, count, MPI_INT, 0, comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in int_scatter "+to_string(error));
 }
示例#17
0
 //------------------------------------------------------------------------
 // constructor
 ATC_HardyKernelQuarticCyl::ATC_HardyKernelQuarticCyl
   (int nparameters, double* parameters): 
   ATC_HardyKernel(nparameters, parameters)
 {
   nsd_ = 2;
   double Lz = box_length[2];
   invVol_ = 1.0/(Pi*pow(Rc_,2)*Lz);
   for (int k = 0; k < nsd_; k++ ) {
     if ((bool) periodicity[k]) {
       if (Rc_ > 0.5*box_length[k]) {
         throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
       };
     };
   };
 }
//---------------------------------------------------------------------
//  intialization 
//---------------------------------------------------------------------
void PhysicsModelTwoTemperature::initialize(void)
{
  string list[5] = {"heat_capacity",
           "electron_heat_capacity",
                    "heat_flux",
           "electron_heat_flux",
           "electron_phonon_exchange"};
  set<string> needs(list,list+5);
  vector< Material* >::iterator iter;
  for (iter = materials_.begin(); iter != materials_.end(); iter++) {
    Material * mat = *iter;
    if (! (mat->check_registry(needs)) ) {
      throw ATC_Error(0,"material " + mat->label() + " does not provide all interfaces for physics");
    }
  }
}
示例#19
0
  //--------------------------------------------------------
  //  find measurement atoms and nodes 
  //--------------------------------------------------------
  void ChargeRegulatorMethodFeedback::set_influence(void)
  {

    // get nodes that overlap influence atoms & compact list of influence atoms
    boundary_ = 
      atc_->nodal_influence(influenceGroupBit_,influenceNodes_,influenceAtoms_);
    nInfluenceAtoms_ = influenceAtoms_.size(); // local
    nInfluenceNodes_ = influenceNodes_.size(); // global
    stringstream ss; ss << "control nodes: " << nControlNodes_ << " influence nodes: " << nInfluenceNodes_ << " local influence atoms: " << nInfluenceAtoms_ ;
    lammpsInterface_->print_msg(ss.str());
    if (nInfluenceNodes_ == 0) throw ATC_Error("no influence nodes");

    const Array<int> & map = (boundary_) ? atc_->ghost_to_atom_map() : atc_->internal_to_atom_map(); 
    for (set<int>::const_iterator itr = influenceAtoms_.begin(); itr != influenceAtoms_.end(); itr++) {
      influenceAtomsIds_.insert(map(*itr));
    }
  }
示例#20
0
 int rank_min(MPI_Comm comm, double *send_buf, double *rec_buf, int count)
 {
   int myRank;
   MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
   DOUBLE_RANK in[count],out[count];
   for (int i = 0; i < count; i++) {
     in[i].val = send_buf[i];
     in[i].rank = myRank;
   }
   int error = MPI_Allreduce(in, out, count, MPI_DOUBLE_INT, MPI_MINLOC,
                             comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in rank_min "+to_string(error));
   for (int i = 0; i < count; i++) {
     rec_buf[i] = out[i].val;
   }
   return out[0].rank;
 }
示例#21
0
  //--------------------------------------------------------
  //  Initialize
  //--------------------------------------------------------
  void ChargeRegulatorMethodImageCharge::initialize(void)
  {
    ChargeRegulatorMethod::initialize();
    if (surfaceType_ != ChargeRegulator::DIELECTRIC) throw ATC_Error("currently image charge can only mimic a dielectric");
    double eps1 = permittivity_;// dielectric
    double eps2 = lammpsInterface_->dielectric();// ambient
    permittivityRatio_ = (eps2-eps1)/(eps2+eps1);
#ifdef ATC_VERBOSE
    stringstream ss; ss << "permittivity ratio: " << permittivityRatio_;
    lammpsInterface_->print_msg_once(ss.str());
#endif
    set_greens_functions();

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
    initialized_ = true;
  }
示例#22
0
// nomenclature might be a bit backwark: control --> nodes that exert the control, & influence --> atoms that feel the influence
  void ChargeRegulatorMethod::initialize(void)
  {
    interscaleManager_ = &(atc_->interscale_manager());

    poissonSolver_ =chargeRegulator_->poisson_solver();
    if (! poissonSolver_) throw ATC_Error("need a poisson solver to initialize charge regulator");

    // atomic vectors
    // nodal information
    nNodes_ = atc_->num_nodes();
    // constants
    rC_ = lammpsInterface_->pair_cutoff();
    rCsq_ = rC_*rC_;
    qV2e_ = lammpsInterface_->qv2e();
    qqrd2e_ = lammpsInterface_->qqrd2e();

    // note derived method set intialized to true
  }
示例#23
0
// --------------------------------------------------------------------
// update 
// --------------------------------------------------------------------
void FieldImplicitEulerIntegrator::update(const double dt, double time,
  FIELDS & fields, FIELDS & rhs) 
{ // solver handles bcs
  FieldImplicitSolveOperator solver(atc_, 
    fields, fieldName_, rhsMask_, physicsModel_,
    time, dt, alpha_);
  DiagonalMatrix<double> preconditioner = solver.preconditioner();
  DENS_VEC rT = solver.r();
  DENS_VEC dT(nNodes_); dT = dT_; 
  DENS_MAT H(maxRestarts_+1, maxRestarts_);
  double tol = tol_; // tol returns the residual
  int iterations = maxIterations_; // iterations returns number of iterations
  int restarts = maxRestarts_;
  int convergence = GMRES(solver,
    dT, rT, preconditioner, H, restarts, iterations, tol);
  if (convergence != 0) {
    throw ATC_Error(field_to_string(fieldName_) + " evolution did not converge");
  }
  solver.solution(dT,fields[fieldName_].set_quantity());
}
示例#24
0
  //--------------------------------------------------------
  //  create_model
  //--------------------------------------------------------
  void ExtrinsicModelManager::create_model(ExtrinsicModelType modelType,
                                           string matFileName)
  {
    string typeName;
    bool validModel = model_to_string(modelType,typeName);
    if (!validModel) {
      throw ATC_Error(0,"Could not create extrinsic model");
      return;
    }
    ExtrinsicModel * myModel;
    if      (modelType==TWO_TEMPERATURE) {
      cout << "ATC: creating two_temperature extrinsic model \n";
      myModel = new ExtrinsicModelTwoTemperature
	(this,modelType,matFileName);
    }
    extrinsicModels_.push_back(myModel);

     // add new fields to fields data
     map<FieldName,int> fieldSizes;
     myModel->get_num_fields(fieldSizes);
     atcTransfer_->add_fields(fieldSizes);
  }
示例#25
0
 // constructor
 ATC_HardyKernelCell::ATC_HardyKernelCell
   (int nparameters, double* parameters): 
   ATC_HardyKernel(nparameters, parameters) 
 {
   hx = parameters[0];
   hy = parameters[1];
   hz = parameters[2];
   invVol_ = 1.0/8.0/(hx*hy*hz);
   cellBounds_.reset(6);
   cellBounds_(0) = -hx;
   cellBounds_(1) =  hx;
   cellBounds_(2) = -hy;
   cellBounds_(3) =  hy;
   cellBounds_(4) = -hz;
   cellBounds_(5) =  hz;
     
   for (int k = 0; k < nsd_; k++ ) {
     if ((bool) periodicity[k]) {
       if (parameters[k] > 0.5*box_length[k]) {
         throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
       };
     };
   };
 }
示例#26
0
// --------------------------------------------------------------------
//  Setup
// --------------------------------------------------------------------
void LinearSolver::setup(void)
{
  tol_     = kTol;
  nVariables_ = matrix_.nRows();
  maxIterations_=2*nVariables_;
  maxRestarts_=nVariables_;


  // switch method based on size
  if (solverType_ < 0) {
    if (nVariables_ > kMaxDirect ) {
      solverType_ = ITERATIVE_SOLVE_SYMMETRIC;
      constraintHandlerType_ = PENALIZE_CONSTRAINTS; 
    }
    else {
      solverType_ = DIRECT_SOLVE;
    }
  }
  if (constraintHandlerType_ < 0) {
    constraintHandlerType_ = PENALIZE_CONSTRAINTS;
    if (solverType_ == DIRECT_SOLVE) constraintHandlerType_ = CONDENSE_CONSTRAINTS;
  }
  if ( solverType_ == DIRECT_SOLVE && constraintHandlerType_ == CONDENSE_CONSTRAINTS ) allowReinitialization_ = true;
  if ( solverType_ == ITERATIVE_SOLVE_SYMMETRIC && constraintHandlerType_ == CONDENSE_CONSTRAINTS )  { throw ATC_Error("LinearSolver::unimplemented method"); }
}
示例#27
0
void LinearSolver::greens_function(int I, VECTOR & G_I)
{
  SPAR_MAT * A = NULL;



  initialize_matrix();
  initialize_inverse();
  G_I.reset(nVariables_);
  VECTOR & x = G_I;

  if (solverType_ == ITERATIVE_SOLVE_SYMMETRIC) {
    DENS_VEC b(nVariables_); b = 0.0; b(I) = 1.0;
    if (parallel_) {
      A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_);
    }
    else {
      A = new SPAR_MAT(*matrixSparse_);
    }
    const DIAG_MAT & PC = matrixDiagonal_;
    int niter = maxIterations_;
    double tol = tol_;
    int convergence = CG(*A, x, b, PC, niter, tol);
    if (convergence>0) {
       stringstream ss;
       ss << "CG greens_function solve did not converge,";
       ss << " iterations: " << niter;
       ss << " residual: " << tol;
       throw ATC_Error(ss.str());
    }
  }
  else if (solverType_ == ITERATIVE_SOLVE) {
    DENS_VEC b(nVariables_); b = 0.0; b(I) = 1.0;
    //  VECTOR & bb = b;
    if (parallel_) {
      A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_);
    }
    else {
      A = new SPAR_MAT(*matrixSparse_);
    }
    //  const DENS_MAT A = matrixSparse_->dense_copy();
    const DIAG_MAT & PC = matrixDiagonal_;
    int iterations = maxIterations_;
    int restarts = maxRestarts_;
    double tol = tol_;
    DENS_MAT H(maxRestarts_+1, maxRestarts_);
    DENS_VEC xx(nVariables_);
    int convergence = GMRES(*A, xx, b, PC, H, restarts, iterations, tol);
    if (convergence>0) {
       stringstream ss;
       ss << "GMRES greens_function solve did not converge,";
       ss << " iterations: " << iterations;
       ss << " residual: " << tol;
       throw ATC_Error(ss.str());
    }
    x.copy(xx.ptr(),xx.nRows()); 
  }
  else {
    const DENS_MAT & invA = matrixInverse_;
    if (constraintHandlerType_ == CONDENSE_CONSTRAINTS) {
      set<int>::const_iterator itr;
      for (itr = fixedSet_.begin(); itr != fixedSet_.end(); itr++) {
        int ii = *itr;
        x(ii) = 0;
      }
      itr = freeSet_.find(I);
      if (itr !=freeSet_.end() ) {
        int j = freeGlobalToCondensedMap_[I];
        int i = 0;
        for (itr = freeSet_.begin(); itr != freeSet_.end(); itr++,i++) {
          int ii = *itr;
          x(ii) = invA(j,i);
        }
      }
    }
    else {
      for (int i = 0; i < nVariables_; ++i) x(i) = invA(I,i);
    }
  }
  
  delete A;
}
示例#28
0
bool LinearSolver::solve(VECTOR & x, const VECTOR & b)
{
  SPAR_MAT * A = NULL;

  rhs_ = &b;
  initialized_ = false;
  initialize();
  if (num_unknowns() == 0) {
    set_fixed_values(x);
    return true;
  }
  const VECTOR & r = *b_;
  if (solverType_ == ITERATIVE_SOLVE_SYMMETRIC) {
    
    
    
    if (parallel_) {
      A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_);
    }
    else {
      A = new SPAR_MAT(*matrixSparse_);
    }
    DIAG_MAT & PC = matrixDiagonal_;
    int niter = maxIterations_;
    double tol = tol_;
    int convergence = CG(*A, x, r, PC, niter, tol);// CG changes niter, tol
    if (convergence>0) {
       stringstream ss;
       ss << "CG solve did not converge,";
       ss << " iterations: " << niter;
       ss << " residual: " << tol;
       throw ATC_Error(ss.str());
    }
  }
  else if (solverType_ == ITERATIVE_SOLVE) {
    if (parallel_) {
      A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_);
    }
    else {
      A = new SPAR_MAT(*matrixSparse_);
    }
    const DIAG_MAT & PC = matrixDiagonal_;
    int iterations = maxIterations_;
    int restarts = maxRestarts_;
    double tol = tol_;
    DENS_MAT H(maxRestarts_+1, maxRestarts_);
    DENS_VEC xx(nVariables_);
    DENS_VEC bb;
    bb = b; 
    int convergence = GMRES(*A, xx, bb, PC, H, restarts, iterations, tol);
    if (convergence>0) {
       stringstream ss;
       ss << "GMRES greens_function solve did not converge,";
       ss << " iterations: " << iterations;
       ss << " residual: " << tol;
       throw ATC_Error(ss.str());
    }
    x.copy(xx.ptr(),xx.nRows()); 
  }
  else { // DIRECT_SOLVE
    const DENS_MAT & invA = matrixInverse_;
    if (constraintHandlerType_ == CONDENSE_CONSTRAINTS) {
      DENS_MAT xx = invA*r;
      int i = 0;
      set<int>::const_iterator itr;
      for (itr = freeSet_.begin(); itr != freeSet_.end(); itr++,i++) {
        int ii = *itr;
        x(ii) = xx(i,0);
      }
      set_fixed_values(x);
    }
    else {

      DENS_VEC xx = invA*r;
      for (int i = 0; i < xx.nRows(); i++) {
        x(i) = xx(i);
      }
    }
  }
  delete A;


  return true;
}
示例#29
0
 void int_allmin(MPI_Comm comm, int *send_buf, int *rec_buf, int count)
 {
   int error = MPI_Allreduce(send_buf, rec_buf, count, MPI_INT, MPI_MIN,
                             comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in int_allmax "+to_string(error));
 }
示例#30
0
 void allmin(MPI_Comm comm, double *send_buf, double *rec_buf, int count)
 {
   int error = MPI_Allreduce(send_buf, rec_buf, count, MPI_DOUBLE, MPI_MIN,
                             comm);
   if (error != MPI_SUCCESS) throw ATC_Error("error in allmax "+to_string(error));
 }