00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <DistributedDiagonalSolver.h>
00031 #include <DistributedDiagonalSOE.h>
00032 #include <Channel.h>
00033
00034 DistributedDiagonalSolver::DistributedDiagonalSolver(int classTag)
00035 :LinearSOESolver(classTag),
00036 theSOE(0), minDiagTol(0.0)
00037 {
00038
00039 }
00040
00041 DistributedDiagonalSolver::DistributedDiagonalSolver(double tol)
00042 :LinearSOESolver(SOLVER_TAGS_DistributedDiagonalSolver),
00043 theSOE(0), minDiagTol(tol)
00044 {
00045
00046 }
00047
00048 DistributedDiagonalSolver::~DistributedDiagonalSolver()
00049 {
00050
00051 }
00052
00053 int
00054 DistributedDiagonalSolver::setLinearSOE(DistributedDiagonalSOE &theProfileSPDSOE)
00055 {
00056
00057 theSOE = &theProfileSPDSOE;
00058 return 0;
00059 }
00060
00061 int
00062 DistributedDiagonalSolver::setSize(void)
00063 {
00064 return 0;
00065 }
00066
00067
00068 int
00069 DistributedDiagonalSolver::solve(void)
00070 {
00071 int size = theSOE->size;
00072 int processID = theSOE->processID;
00073
00074 Channel **theChannels = theSOE->theChannels;
00075 int numChannels = theSOE->numChannels;
00076
00077 int numShared = theSOE->numShared;
00078 ID &myDOFs = theSOE->myDOFs;
00079 ID &myDOFsShared = theSOE->myDOFsShared;
00080
00081 double *X = theSOE->X;
00082 double *B = theSOE->B;
00083 double *A = theSOE->A;
00084 double *dataShared = theSOE->dataShared;
00085 Vector *vectShared = theSOE->vectShared;
00086
00087
00088
00089
00090
00091 for (int i=0; i<numShared; i++)
00092 dataShared[i] = 0.0;
00093
00094
00095
00096 for (int i=0; i<numShared; i++) {
00097 int dof = myDOFsShared(i);
00098 int loc = myDOFs.getLocation(dof);
00099 if (loc >= 0) {
00100 dataShared[i] = A[loc];
00101 dataShared[i+numShared] = B[loc];
00102 }
00103 }
00104
00105
00106
00107
00108
00109 if (numShared != 0) {
00110 if (processID != 0) {
00111 Channel *theChannel = theChannels[0];
00112 theChannel->sendVector(0, 0, *vectShared);
00113 theChannel->recvVector(0, 0, *vectShared);
00114 }
00115 else {
00116
00117 static Vector otherShared(1);
00118 otherShared.resize(2*numShared);
00119 for (int i=0; i<numChannels; i++) {
00120 Channel *theChannel = theChannels[i];
00121 theChannel->recvVector(0, 0, otherShared);
00122 *vectShared += otherShared;
00123 }
00124 for (int i=0; i<numChannels; i++) {
00125 Channel *theChannel = theChannels[i];
00126 theChannel->sendVector(0, 0, *vectShared);
00127 }
00128 }
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 for (int i=0; i<numShared; i++) {
00138 int dof = myDOFsShared(i);
00139 int loc = myDOFs.getLocation(dof);
00140 if (loc >= 0) {
00141 A[loc] = dataShared[i];
00142 B[loc] = dataShared[i+numShared];
00143 }
00144 }
00145
00146
00147
00148
00149
00150 for (int i=0; i<size; i++) {
00151 X[i] = B[i]/A[i];
00152 }
00153
00154 return 0;
00155 }
00156
00157 int
00158 DistributedDiagonalSolver::sendSelf(int cTag,
00159 Channel &theChannel)
00160 {
00161 static Vector data(1);
00162 data(0) = minDiagTol;
00163 return theChannel.sendVector(0, cTag, data);
00164 }
00165
00166
00167 int
00168 DistributedDiagonalSolver::recvSelf(int cTag,
00169 Channel &theChannel,
00170 FEM_ObjectBroker &theBroker)
00171 {
00172 static Vector data(1);
00173 theChannel.recvVector(0, cTag, data);
00174
00175 minDiagTol = data(0);
00176 return 0;
00177 }
00178