⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 distsymm.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
//// distsymm.cc//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Curtis Janssen <cljanss@limitpt.com>// Maintainer: LPS//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit 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 Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#include <iostream>#include <math.h>#include <util/misc/formio.h>#include <util/keyval/keyval.h>#include <math/scmat/dist.h>#include <math/scmat/cmatrix.h>#include <math/scmat/elemop.h>#include <math/scmat/disthql.h>using namespace std;using namespace sc;extern "C" { int DBmalloc_chain_check(const char *, int, int); }/////////////////////////////////////////////////////////////////////////////// DistSymmSCMatrix member functionsstatic ClassDesc DistSymmSCMatrix_cd(  typeid(DistSymmSCMatrix),"DistSymmSCMatrix",1,"public SymmSCMatrix",  0, 0, 0);DistSymmSCMatrix::DistSymmSCMatrix(const RefSCDimension&a,DistSCMatrixKit*k):  SymmSCMatrix(a,k){  init_blocklist();}intDistSymmSCMatrix::block_to_node(int i, int j) const{  if (j>i) {      ExEnv::errn() << indent << "DistSymmSCMatrix::block_to_node: j>i" << endl;      abort();    }  return ((i*(i+1))/2 + j)%messagegrp()->n();}Ref<SCMatrixBlock>DistSymmSCMatrix::block_to_block(int i, int j) const{  if (j>i) {      ExEnv::errn() << indent << "DistSymmSCMatrix::block_to_block: j>i" << endl;      abort();    }  int offset = (i*(i+1))/2 + j;  int nproc = messagegrp()->n();  if ((offset%nproc) != messagegrp()->me()) return 0;  SCMatrixBlockListIter I;  for (I=blocklist->begin(); I!=blocklist->end(); I++) {      if (I.block()->blocki == i && I.block()->blockj == j)          return I.block();    }  ExEnv::errn() << indent << "DistSymmSCMatrix::block_to_block: internal error" << endl;  abort();  return 0;}double *DistSymmSCMatrix::find_element(int i, int j) const{  if (j>i) {      int tmp = i; i=j; j=tmp;    }  int bi, oi;  d->blocks()->elem_to_block(i, bi, oi);  int bj, oj;  d->blocks()->elem_to_block(j, bj, oj);  Ref<SCMatrixBlock> ablk = block_to_block(bi, bj);  if (ablk.nonnull()) {      if (bi != bj) {          Ref<SCMatrixRectBlock> blk              = dynamic_cast<SCMatrixRectBlock*>(ablk.pointer());          if (blk.null()) return 0;          return &blk->data[oi*(blk->jend-blk->jstart)+oj];        }      else {          Ref<SCMatrixLTriBlock> blk              = dynamic_cast<SCMatrixLTriBlock*>(ablk.pointer());          if (blk.null()) return 0;          return &blk->data[(oi*(oi+1))/2+oj];        }    }  return 0;}intDistSymmSCMatrix::element_to_node(int i, int j) const{  if (j>i) {      int tmp = i; i=j; j=tmp;    }  int bi, oi;  d->blocks()->elem_to_block(i, bi, oi);  int bj, oj;  d->blocks()->elem_to_block(j, bj, oj);  return block_to_node(bi,bj);}voidDistSymmSCMatrix::init_blocklist(){  int i, j, index;  int nproc = messagegrp()->n();  int me = messagegrp()->me();  SCMatrixBlock *b;  blocklist = new SCMatrixBlockList;  for (i=0, index=0; i<d->blocks()->nblock(); i++) {      for (j=0; j<i; j++, index++) {          if (index%nproc != me) continue;          b = new SCMatrixRectBlock(d->blocks()->start(i),                                    d->blocks()->fence(i),                                    d->blocks()->start(j),                                    d->blocks()->fence(j));          b->blocki = i;          b->blockj = j;          blocklist->insert(b);        }      if (index%nproc == me) {          b = new SCMatrixLTriBlock(d->blocks()->start(i),                                    d->blocks()->fence(i));          b->blocki = i;          b->blockj = i;          blocklist->insert(b);        }      index++;    }}DistSymmSCMatrix::~DistSymmSCMatrix(){}doubleDistSymmSCMatrix::get_element(int i,int j) const{  double res;  double *e = find_element(i,j);  if (e) {      res = *e;      messagegrp()->bcast(res, messagegrp()->me());    }  else {      messagegrp()->bcast(res, element_to_node(i, j));    }  return res;}voidDistSymmSCMatrix::set_element(int i,int j,double a){  double *e = find_element(i,j);  if (e) {      *e = a;    }}voidDistSymmSCMatrix::accumulate_element(int i,int j,double a){  double *e = find_element(i,j);  if (e) {      *e += a;    }}SymmSCMatrix *DistSymmSCMatrix::get_subblock(int br, int er){  error("get_subblock");  return 0;}SCMatrix *DistSymmSCMatrix::get_subblock(int, int, int, int){  error("get_subblock");  return 0;}voidDistSymmSCMatrix::assign_subblock(SCMatrix*sb, int br, int er, int bc, int ec){  error("assign_subblock");}voidDistSymmSCMatrix::assign_subblock(SymmSCMatrix*sb, int br, int er){  error("accumulate_subblock");}voidDistSymmSCMatrix::accumulate_subblock(SCMatrix*sb, int br, int er, int bc, int ec){  error("accumulate_subblock");}voidDistSymmSCMatrix::accumulate_subblock(SymmSCMatrix*sb, int br, int er){  error("accumulate_subblock");}SCVector *DistSymmSCMatrix::get_row(int i){  error("get_row");  return 0;}voidDistSymmSCMatrix::assign_row(SCVector *v, int i){  error("assign_row");}voidDistSymmSCMatrix::accumulate_row(SCVector *v, int i){  error("accumulate_row");}voidDistSymmSCMatrix::accumulate(const SymmSCMatrix*a){  // make sure that the arguments is of the correct type  const DistSymmSCMatrix* la    = require_dynamic_cast<const DistSymmSCMatrix*>(a,"DistSymmSCMatrix::accumulate");  // make sure that the dimensions match  if (!dim()->equiv(la->dim())) {      ExEnv::errn() << indent << "DistSymmSCMatrix::accumulate(SCMatrix*a): "           << "dimensions don't match\n";      abort();    }  SCMatrixBlockListIter i1, i2;  for (i1=la->blocklist->begin(),i2=blocklist->begin();       i1!=la->blocklist->end() && i2!=blocklist->end();       i1++,i2++) {      int n = i1.block()->ndat();      if (n != i2.block()->ndat()) {          ExEnv::errn() << indent               << "DistSymmSCMatrixListSubblockIter::accumulate block "               << "mismatch: internal error" << endl;          abort();        }      double *dat1 = i1.block()->dat();      double *dat2 = i2.block()->dat();      for (int i=0; i<n; i++) {          dat2[i] += dat1[i];        }    }}doubleDistSymmSCMatrix::invert_this(){  RefDiagSCMatrix refa = kit()->diagmatrix(d);  RefSCMatrix refb = kit()->matrix(d,d);  diagonalize(refa.pointer(),refb.pointer());  double determ = 1.0;  for (int i=0; i<dim()->n(); i++) {      double val = refa->get_element(i);      determ *= val;    }  Ref<SCElementOp> op = new SCElementInvert(1.0e-12);  refa->element_op(op.pointer());  assign(0.0);  accumulate_transform(refb.pointer(), refa.pointer());  return determ;}doubleDistSymmSCMatrix::determ_this(){  return invert_this();}doubleDistSymmSCMatrix::trace(){  double ret=0.0;  Ref<SCMatrixSubblockIter> I = local_blocks(SCMatrixSubblockIter::Read);  for (I->begin(); I->ready(); I->next()) {      Ref<SCMatrixLTriBlock> b = dynamic_cast<SCMatrixLTriBlock*>(I->block());      if (b.nonnull() && b->blocki == b->blockj) {          int ni = b->end-b->start;          double *data = b->data;          for (int i=0; i<ni; i++) {              data += i;              ret += *data;            }        }    }  messagegrp()->sum(ret);  return ret;}doubleDistSymmSCMatrix::solve_this(SCVector*v){  DistSCVector* lv =    require_dynamic_cast<DistSCVector*>(v,"DistSymmSCMatrix::solve_this");    // make sure that the dimensions match  if (!dim()->equiv(lv->dim())) {      ExEnv::errn() << indent << "DistSymmSCMatrix::solve_this(SCVector*v): "           << "dimensions don't match\n";      abort();    }  error("no solve this");  return 0.0;}voidDistSymmSCMatrix::gen_invert_this(){  invert_this();}voidDistSymmSCMatrix::diagonalize(DiagSCMatrix*a,SCMatrix*b){  const char* name = "DistSymmSCMatrix::diagonalize";  // make sure that the argument are of the correct type  require_dynamic_cast<DistDiagSCMatrix*>(a,name);  DistSCMatrix* lb = require_dynamic_cast<DistSCMatrix*>(b,name);  int n = dim()->n();  int me = messagegrp()->me();  int nproc = messagegrp()->n();  RefSCMatrix arect = kit()->matrix(dim(),dim());  DistSCMatrix *rect = dynamic_cast<DistSCMatrix*>(arect.pointer());  rect->assign(0.0);  rect->accumulate(this);  // This sets up the index list of columns to be stored on this node  int nvec = n/nproc + (me<(n%nproc)?1:0);  int *ivec = new int[nvec];  for (int i=0; i<nvec; i++) {      ivec[i] = i*nproc + me;    }  rect->create_vecform(DistSCMatrix::Col,nvec);  rect->vecform_op(DistSCMatrix::CopyToVec,ivec);  lb->create_vecform(DistSCMatrix::Col,nvec);  double *d = new double[n];  dist_diagonalize(n, rect->nvec, rect->vec[0], d, lb->vec[0],                   messagegrp());  // put d into the diagonal matrix  a->assign(d);  lb->vecform_op(DistSCMatrix::CopyFromVec, ivec);  lb->delete_vecform();  rect->delete_vecform();  arect = 0;  delete[] ivec;}// computes this += a + a.tvoidDistSymmSCMatrix::accumulate_symmetric_sum(SCMatrix*a){  // make sure that the argument is of the correct type  DistSCMatrix* la    = require_dynamic_cast<DistSCMatrix*>(a,"DistSymmSCMatrix::"                                          "accumulate_symmetric_sum");  if (!dim()->equiv(la->rowdim()) || !dim()->equiv(la->coldim())) {      ExEnv::errn() << indent << "DistSymmSCMatrix::"           << "accumulate_symmetric_sum(SCMatrix*a): bad dim\n";      abort();    }  Ref<SCMatrixSubblockIter> I = all_blocks(SCMatrixSubblockIter::Accum);  for (I->begin(); I->ready(); I->next()) {      Ref<SCMatrixBlock> block = I->block();      // see if i've got this block      Ref<SCMatrixBlock> localblock          = la->block_to_block(block->blocki,block->blockj);      if (localblock.nonnull()) {          // the diagonal blocks require special handling          if (block->blocki == block->blockj) {              int n = la->rowblocks()->size(block->blocki);              double *dat1 = block->dat();              double *dat2 = localblock->dat();              for (int i=0; i<n; i++) {                  for (int j=0; j<=i; j++) {                      double tmp = 0.0;                      tmp += dat2[i*n+j];                      tmp += dat2[j*n+i];                      *dat1 += tmp;                      dat1++;                    }                }            }          else {              int n = block->ndat();              double *dat1 = block->dat();              double *dat2 = localblock->dat();              for (int i=0; i<n; i++) {                  dat1[i] += dat2[i];                }            }        }      // now for the transpose      if (block->blocki != block->blockj) {          localblock = la->block_to_block(block->blockj,block->blocki);          if (localblock.nonnull()) {              int nr = la->rowblocks()->size(block->blocki);              int nc = la->rowblocks()->size(block->blockj);              double *dat1 = block->dat();              double *dat2 = localblock->dat();              for (int i=0; i<nr; i++) {                  for (int j=0; j<nc; j++) {                      *dat1++ += dat2[j*nr+i];                    }                }            }        }    }}voidDistSymmSCMatrix::element_op(const Ref<SCElementOp>& op){  SCMatrixBlockListIter i;  for (i = blocklist->begin(); i != blocklist->end(); i++) {      op->process_base(i.block());    }  if (op->has_collect()) op->collect(messagegrp());}voidDistSymmSCMatrix::element_op(const Ref<SCElementOp2>& op,                              SymmSCMatrix* m){  DistSymmSCMatrix *lm      = require_dynamic_cast<DistSymmSCMatrix*>(m,"DistSymSCMatrix::element_op");  if (!dim()->equiv(lm->dim())) {      ExEnv::errn() << indent << "DistSymmSCMatrix: bad element_op\n";      abort();    }  SCMatrixBlockListIter i, j;  for (i = blocklist->begin(), j = lm->blocklist->begin();       i != blocklist->end();       i++, j++) {      op->process_base(i.block(), j.block());    }  if (op->has_collect()) op->collect(messagegrp());}voidDistSymmSCMatrix::element_op(const Ref<SCElementOp3>& op,                              SymmSCMatrix* m,SymmSCMatrix* n){  DistSymmSCMatrix *lm      = require_dynamic_cast<DistSymmSCMatrix*>(m,"DistSymSCMatrix::element_op");  DistSymmSCMatrix *ln      = require_dynamic_cast<DistSymmSCMatrix*>(n,"DistSymSCMatrix::element_op");  if (!dim()->equiv(lm->dim()) || !dim()->equiv(ln->dim())) {      ExEnv::errn() << indent << "DistSymmSCMatrix: bad element_op\n";      abort();    }  SCMatrixBlockListIter i, j, k;  for (i = blocklist->begin(),           j = lm->blocklist->begin(),           k = ln->blocklist->begin();       i != blocklist->end();       i++, j++, k++) {      op->process_base(i.block(), j.block(), k.block());    }  if (op->has_collect()) op->collect(messagegrp());}Ref<SCMatrixSubblockIter>DistSymmSCMatrix::local_blocks(SCMatrixSubblockIter::Access access){  return new SCMatrixListSubblockIter(access, blocklist);}Ref<SCMatrixSubblockIter>DistSymmSCMatrix::all_blocks(SCMatrixSubblockIter::Access access){  return new DistSCMatrixListSubblockIter(access, blocklist, messagegrp());}voidDistSymmSCMatrix::error(const char *msg){  ExEnv::errn() << "DistSymmSCMatrix: error: " << msg << endl;}Ref<DistSCMatrixKit>DistSymmSCMatrix::skit(){  return dynamic_cast<DistSCMatrixKit*>(kit().pointer());}voidDistSymmSCMatrix::convert_accumulate(SymmSCMatrix*a){  SymmSCMatrix::convert_accumulate(a);#if 0  DistSymmSCMatrix *d = require_dynamic_cast<DistSymmSCMatrix*>(a,                                 "DistSymmSCMatrix::convert_accumulate");  SCMatrixBlockListIter i, j;  for (i = blocklist->begin(), j = d->blocklist->begin();       i != blocklist->end();       i++, j++) {    }#endif}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ"// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -