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 "NOX_Common.H"
00031
00032 #include "Teuchos_ParameterList.hpp"
00033
00034
00035 #include "1DfemInterface.H"
00036
00037
00038 #include "Epetra_Comm.h"
00039 #include "Epetra_Map.h"
00040 #include "Epetra_Vector.h"
00041 #include "Epetra_Import.h"
00042 #include "Epetra_CrsGraph.h"
00043 #include "Epetra_CrsMatrix.h"
00044
00045
00046 Interface::Interface(int numGlobalElements, Epetra_Comm& comm, double xmin_,
00047 double xmax_) :
00048 NumGlobalElements(numGlobalElements),
00049 NumMyElements(0),
00050 MyPID(comm.MyPID()),
00051 NumProc(comm.NumProc()),
00052 xmin(xmin_),
00053 xmax(xmax_),
00054 factor(1.0),
00055 Comm(&comm),
00056 StandardMap(0),
00057 OverlapMap(0),
00058 Importer(0),
00059 initialSolution(0),
00060 rhs(0),
00061 Graph(0),
00062 jacobian(0),
00063 xptr(0)
00064 {
00065
00066
00067
00068 StandardMap = new Epetra_Map(NumGlobalElements, 0, *Comm);
00069
00070
00071
00072
00073 NumMyElements = StandardMap->NumMyElements();
00074
00075
00076
00077 if (NumProc == 1) {
00078 OverlapMap = new Epetra_Map(*StandardMap);
00079 } else {
00080
00081 int OverlapNumMyElements;
00082 int OverlapMinMyGID;
00083 OverlapNumMyElements = NumMyElements + 2;
00084 if ((MyPID == 0) || (MyPID == NumProc - 1))
00085 OverlapNumMyElements --;
00086
00087 if (MyPID==0)
00088 OverlapMinMyGID = StandardMap->MinMyGID();
00089 else
00090 OverlapMinMyGID = StandardMap->MinMyGID() - 1;
00091
00092 int* OverlapMyGlobalElements = new int[OverlapNumMyElements];
00093
00094 for (int i = 0; i < OverlapNumMyElements; i ++)
00095 OverlapMyGlobalElements[i] = OverlapMinMyGID + i;
00096
00097 OverlapMap = new Epetra_Map(-1, OverlapNumMyElements,
00098 OverlapMyGlobalElements, 0, *Comm);
00099
00100 delete [] OverlapMyGlobalElements;
00101
00102 }
00103
00104
00105 Importer = new Epetra_Import(*OverlapMap, *StandardMap);
00106 initialSolution = new Epetra_Vector(*StandardMap);
00107
00108
00109
00110
00111 createGraph();
00112
00113
00114 jacobian = new Epetra_CrsMatrix (Copy, *Graph);
00115
00116
00117 jacobian->FillComplete();
00118
00119
00120 xptr = new Epetra_Vector(*StandardMap);
00121 double Length = xmax - xmin;
00122 double dx = Length/((double) NumGlobalElements-1);
00123 for (int i=0; i < NumMyElements; i++) {
00124 (*xptr)[i] = xmin + dx*((double) StandardMap->MinMyGID()+i);
00125 }
00126
00127 initializeSoln();
00128
00129 }
00130
00131
00132 Interface::~Interface()
00133 {
00134 delete jacobian;
00135 delete Graph;
00136 delete Importer;
00137 delete initialSolution;
00138 delete xptr;
00139 delete OverlapMap;
00140 delete StandardMap;
00141 }
00142
00143 bool Interface::computeF(const Epetra_Vector& x,
00144 Epetra_Vector& FVec,
00145 NOX::Epetra::Interface::Required::FillType fillType)
00146 {
00147 return evaluate(fillType, &x, &FVec, 0);
00148 }
00149
00150 bool Interface::computeJacobian(const Epetra_Vector& x,
00151 Epetra_Operator& Jac)
00152 {
00153 return evaluate(NOX::Epetra::Interface::Required::Jac, &x, 0, 0);
00154 }
00155
00156 bool Interface::computePrecMatrix(const Epetra_Vector& x)
00157 {
00158 return evaluate(NOX::Epetra::Interface::Required::Prec, &x, 0, 0);
00159 }
00160 bool Interface::computePreconditioner(const Epetra_Vector& x,
00161 Epetra_Operator& Prec,
00162 Teuchos::ParameterList* precParams)
00163 {
00164 cout << "ERROR: Interface::preconditionVector() - "
00165 << "Use Explicit Jaciban only for this test problem!" << endl;
00166 throw "Interface Error";
00167 }
00168
00169
00170 bool Interface::evaluate(NOX::Epetra::Interface::Required::FillType flag,
00171 const Epetra_Vector* soln,
00172 Epetra_Vector* tmp_rhs,
00173 Epetra_RowMatrix* tmp_matrix)
00174 {
00175
00176 bool fillF = false;
00177 bool fillMatrix = false;
00178 if (tmp_rhs != 0) {
00179 fillF = true;
00180 rhs = tmp_rhs;
00181 }
00182 else {
00183 fillMatrix = true;
00184 }
00185
00186
00187
00188
00189 if (flag == NOX::Epetra::Interface::Required::Residual) {
00190
00191 }
00192 else if (flag == NOX::Epetra::Interface::Required::Jac) {
00193
00194 }
00195 else if (flag == NOX::Epetra::Interface::Required::Prec) {
00196
00197 }
00198 else if (flag == NOX::Epetra::Interface::Required::User) {
00199
00200 }
00201
00202
00203
00204 Epetra_Vector u(*OverlapMap);
00205 Epetra_Vector x(*OverlapMap);
00206
00207
00208 u.Import(*soln, *Importer, Insert);
00209 x.Import(*xptr, *Importer, Insert);
00210
00211
00212 int ierr;
00213 int OverlapNumMyElements = OverlapMap->NumMyElements();
00214
00215 int OverlapMinMyGID;
00216 if (MyPID == 0) OverlapMinMyGID = StandardMap->MinMyGID();
00217 else OverlapMinMyGID = StandardMap->MinMyGID()-1;
00218
00219 int row, column;
00220 double jac;
00221 double xx[2];
00222 double uu[2];
00223 Basis basis;
00224
00225
00226 if (fillF)
00227 rhs->PutScalar(0.0);
00228 if (fillMatrix)
00229 jacobian->PutScalar(0.0);
00230
00231
00232 for (int ne=0; ne < OverlapNumMyElements-1; ne++) {
00233
00234
00235 for(int gp=0; gp < 2; gp++) {
00236
00237 xx[0]=x[ne];
00238 xx[1]=x[ne+1];
00239 uu[0]=u[ne];
00240 uu[1]=u[ne+1];
00241
00242 basis.computeBasis(gp, xx, uu);
00243
00244
00245 for (int i=0; i< 2; i++) {
00246 row=OverlapMap->GID(ne+i);
00247
00248
00249 if (StandardMap->MyGID(row)) {
00250 if (fillF) {
00251 (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+=
00252 +basis.wt*basis.dx
00253 *((1.0/(basis.dx*basis.dx))*basis.duu*
00254 basis.dphide[i]+factor*basis.uu*basis.uu*basis.phi[i]);
00255 }
00256 }
00257
00258 if (fillMatrix) {
00259 for(int j=0;j < 2; j++) {
00260 if (StandardMap->MyGID(row)) {
00261 column=OverlapMap->GID(ne+j);
00262 jac=basis.wt*basis.dx*((1.0/(basis.dx*basis.dx))*
00263 basis.dphide[j]*basis.dphide[i]
00264 +2.0*factor*basis.uu*basis.phi[j]*
00265 basis.phi[i]);
00266 ierr=jacobian->SumIntoGlobalValues(row, 1, &jac, &column);
00267 }
00268 }
00269 }
00270 }
00271 }
00272 }
00273
00274
00275
00276 if (MyPID==0) {
00277 if (fillF)
00278 (*rhs)[0]= (*soln)[0] - 1.0;
00279 if (fillMatrix) {
00280 column=0;
00281 jac=1.0;
00282 jacobian->ReplaceGlobalValues(0, 1, &jac, &column);
00283 column=1;
00284 jac=0.0;
00285 jacobian->ReplaceGlobalValues(0, 1, &jac, &column);
00286 }
00287 }
00288
00289
00290 Comm->Barrier();
00291
00292 jacobian->FillComplete();
00293
00294 return true;
00295 }
00296
00297 Epetra_Vector& Interface::getSolution()
00298 {
00299 return *initialSolution;
00300 }
00301
00302 Epetra_Map& Interface::getMap()
00303 {
00304 return *StandardMap;
00305 }
00306
00307 Epetra_CrsGraph& Interface::getGraph()
00308 {
00309 return *Graph;
00310 }
00311
00312 Epetra_Vector& Interface::getMesh()
00313 {
00314 return *xptr;
00315 }
00316
00317 Epetra_CrsMatrix& Interface::getJacobian()
00318 {
00319 return *jacobian;
00320 }
00321
00322 bool Interface::createGraph()
00323 {
00324 if (Graph != 0) {
00325 delete Graph;
00326 Graph = 0;
00327 }
00328
00329
00330 Graph = new Epetra_CrsGraph(Copy, *StandardMap, 5);
00331
00332
00333 int row, column;
00334 int OverlapNumMyElements = OverlapMap->NumMyElements();
00335 int OverlapMinMyGID;
00336 if (MyPID==0) OverlapMinMyGID = StandardMap->MinMyGID();
00337 else OverlapMinMyGID = StandardMap->MinMyGID()-1;
00338
00339
00340 for (int ne=0; ne < OverlapNumMyElements-1; ne++) {
00341
00342
00343 for (int i=0; i< 2; i++) {
00344 row=OverlapMap->GID(ne+i);
00345
00346
00347 for(int j=0;j < 2; j++) {
00348
00349
00350 if (StandardMap->MyGID(row)) {
00351 column=OverlapMap->GID(ne+j);
00352 Graph->InsertGlobalIndices(row, 1, &column);
00353 }
00354 }
00355 }
00356 }
00357 Graph->FillComplete();
00358 return true;
00359 }
00360
00361
00362 bool Interface::initializeSoln()
00363 {
00364 initialSolution->PutScalar(1.0);
00365 return true;
00366 }
00367
00368
00369
00370
00371
00372 Basis::Basis() {
00373 phi = new double[2];
00374 dphide = new double[2];
00375 }
00376
00377
00378 Basis::~Basis() {
00379 delete [] phi;
00380 delete [] dphide;
00381 }
00382
00383
00384 void Basis::computeBasis(int gp, double *x, double *u, double *uold) {
00385 int N = 2;
00386 if (gp==0) {eta=-1.0/sqrt(3.0); wt=1.0;}
00387 if (gp==1) {eta=1.0/sqrt(3.0); wt=1.0;}
00388
00389
00390 phi[0]=(1.0-eta)/2.0;
00391 phi[1]=(1.0+eta)/2.0;
00392 dphide[0]=-0.5;
00393 dphide[1]=0.5;
00394
00395
00396 dx=0.5*(x[1]-x[0]);
00397 xx=0.0;
00398 uu=0.0;
00399 duu=0.0;
00400 uuold=0.0;
00401 duuold=0.0;
00402 for (int i=0; i < N; i++) {
00403 xx += x[i] * phi[i];
00404 uu += u[i] * phi[i];
00405 duu += u[i] * dphide[i];
00406 if (uold) {
00407 uuold += uold[i] * phi[i];
00408 duuold += uold[i] * dphide[i];
00409 }
00410 }
00411
00412 return;
00413 }