|
@@ -201,28 +201,34 @@ namespace Lemma {
|
201
|
201
|
|
202
|
202
|
void FEM4EllipticPDE::Solve( const std::string& resfile ) {
|
203
|
203
|
ConstructAMatrix();
|
|
204
|
+ SetupPotential();
|
204
|
205
|
//ConstructLoadVector();
|
205
|
206
|
|
206
|
207
|
std::cout << "\nSolving" << std::endl;
|
|
208
|
+ std::cout << " rows\tcols\n";
|
|
209
|
+ std::cout << "A: " << A.rows() << "\t" << A.cols() << std::endl;
|
|
210
|
+ std::cout << "g: " << g.rows() << "\t" << g.cols() << std::endl;
|
|
211
|
+
|
207
|
212
|
////////////////////////////////////////////////////////////
|
208
|
213
|
// Solving:
|
209
|
214
|
//Eigen::SimplicialCholesky<Eigen::SparseMatrix<Real>, Eigen::Lower > chol(A); // performs a Cholesky factorization of A
|
210
|
215
|
//VectorXr u = chol.solve(g);
|
211
|
216
|
|
|
217
|
+ //Eigen::SparseLU<Eigen::SparseMatrix<Real, Eigen::ColMajor>, Eigen::COLAMDOrdering<int> > solver;
|
|
218
|
+ //solver.analyzePattern(A);
|
|
219
|
+ //solver.factorize(A);
|
|
220
|
+ //VectorXr u = solver.solve(g);
|
|
221
|
+
|
|
222
|
+ //#ifdef CGSOLVE
|
212
|
223
|
//Eigen::ConjugateGradient<Eigen::SparseMatrix<Real, Eigen::Lower > Eigen::DiagonalPreconditioner > cg;
|
213
|
224
|
Eigen::ConjugateGradient< Eigen::SparseMatrix<Real> > cg(A);
|
214
|
|
-
|
215
|
225
|
//Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
|
216
|
226
|
//cg.setMaxIterations(3000);
|
217
|
227
|
//cg.setTolerance(1e-28);
|
218
|
|
-
|
219
|
|
- std::cout << " rows\tcols\n";
|
220
|
|
- std::cout << "A: " << A.rows() << "\t" << A.cols() << std::endl;
|
221
|
|
- std::cout << "g: " << g.rows() << "\t" << g.cols() << std::endl;
|
222
|
|
-
|
223
|
228
|
VectorXr u = cg.solve(g);
|
224
|
229
|
std::cout << "#iterations: " << cg.iterations() << std::endl;
|
225
|
230
|
std::cout << "estimated error: " << cg.error() << std::endl;
|
|
231
|
+ //#endif
|
226
|
232
|
|
227
|
233
|
vtkDoubleArray *gArray = vtkDoubleArray::New();
|
228
|
234
|
vtkDoubleArray *uArray = vtkDoubleArray::New();
|
|
@@ -330,27 +336,33 @@ namespace Lemma {
|
330
|
336
|
} else {
|
331
|
337
|
sigma_bar = 1.;
|
332
|
338
|
}
|
|
339
|
+ sigma_bar = 1.;
|
333
|
340
|
|
334
|
|
- auto W = VectorXr::Zero(4);
|
335
|
|
- auto G = GradPhi.block<3,3>(1,1) * GradPhi.block<3,3>(1,1).transpose()*W;
|
336
|
341
|
|
337
|
342
|
for (int ii=0; ii<4; ++ii) {
|
338
|
343
|
for (int jj=0; jj<4; ++jj) {
|
339
|
344
|
/* homogeneous Dirichlet boundary */
|
340
|
|
- if (jj == ii) {
|
|
345
|
+ if (jj==ii && C(ii,3)==13.5) {
|
|
346
|
+ //Real bb = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0];
|
|
347
|
+ //if (jj==ii && ((bb-1.)<1e-8) ) {
|
341
|
348
|
// Apply Homogeneous Dirichlet Boundary conditions
|
342
|
349
|
Real bb = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0];
|
343
|
350
|
Real bdry = (1./(BndryH*BndryH))*BndrySigma*bb; // + sum;
|
344
|
351
|
//Real bdry = GradPhi.col(ii).tail<3>().dot(GradPhi.col(ii).tail<3>())*BndrySigma*bb; // + sum;
|
345
|
352
|
coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], bdry + GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>() ) * V * sigma_bar ) );
|
|
353
|
+ //coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], 1));
|
|
354
|
+ //break;
|
346
|
355
|
} else {
|
347
|
356
|
coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>() ) * V * sigma_bar ) );
|
348
|
357
|
}
|
|
358
|
+ /* */
|
|
359
|
+ /* Inhomogeneous Dirichlet */
|
|
360
|
+ //coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>())*V*sigma_bar ));
|
349
|
361
|
// Stiffness matrix no longer contains boundary conditions...
|
350
|
362
|
//coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>() ) * V * sigma_bar ) );
|
351
|
363
|
}
|
352
|
364
|
}
|
353
|
|
- std::cout << "\r" << (int)(1e2*((float)(ic) / (float)(vtkGrid->GetNumberOfCells()))) << std::flush ;
|
|
365
|
+ //std::cout << "\r" << (int)(1e2*((float)(ic) / (float)(vtkGrid->GetNumberOfCells()))) << std::flush ;
|
354
|
366
|
}
|
355
|
367
|
A.setFromTriplets(coeffs.begin(), coeffs.end());
|
356
|
368
|
//std::cout << "A\n" << A << std::endl;
|
|
@@ -363,7 +375,7 @@ namespace Lemma {
|
363
|
375
|
std::cout << "\nBuilding load vector (g)" << std::endl;
|
364
|
376
|
g = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
|
365
|
377
|
std::cout << "made g with " << vtkGrid->GetNumberOfPoints() << " points" << std::endl;
|
366
|
|
-
|
|
378
|
+ VectorXr DB = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
|
367
|
379
|
for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
|
368
|
380
|
|
369
|
381
|
Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
|
|
@@ -375,7 +387,8 @@ namespace Lemma {
|
375
|
387
|
C(ii, 3) = pts[2];
|
376
|
388
|
}
|
377
|
389
|
|
378
|
|
- Real V = (1./6.) * C.determinant(); // volume of tetrahedra
|
|
390
|
+ Real V = (1./6.) * C.determinant(); // volume of tetrahedra
|
|
391
|
+ Eigen::Matrix<Real, 4, 4> GradPhi = C.inverse(); // nabla \phi
|
379
|
392
|
|
380
|
393
|
vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
|
381
|
394
|
int ID[4];
|
|
@@ -384,7 +397,7 @@ namespace Lemma {
|
384
|
397
|
ID[2] = Ids->GetId(2);
|
385
|
398
|
ID[3] = Ids->GetId(3);
|
386
|
399
|
|
387
|
|
-
|
|
400
|
+ /*
|
388
|
401
|
Real avg(0);
|
389
|
402
|
Real GG[4];
|
390
|
403
|
for (int ii=0; ii<4; ++ii) {
|
|
@@ -394,6 +407,18 @@ namespace Lemma {
|
394
|
407
|
if ( std::abs( (GG[0]+GG[1]+GG[2]+GG[3])/4. - GG[0]) < 1e-5) {
|
395
|
408
|
avg = GG[0];
|
396
|
409
|
}
|
|
410
|
+ */
|
|
411
|
+
|
|
412
|
+ VectorXr W = VectorXr::Zero(4);
|
|
413
|
+ for (int ii=0; ii<4; ++ii) {
|
|
414
|
+ W[ii] = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0] *
|
|
415
|
+ vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
|
|
416
|
+ DB[ID[ii]] = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0] *
|
|
417
|
+ vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
|
|
418
|
+ }
|
|
419
|
+ //auto G = GradPhi.block<3,4>(1,0).transpose()*GradPhi.block<3,4>(1,0)*W;
|
|
420
|
+ VectorXr G = GradPhi.block<3,4>(1,0).transpose()*GradPhi.block<3,4>(1,0)*W;
|
|
421
|
+ Real sigma_bar(1.);
|
397
|
422
|
|
398
|
423
|
for (int ii=0; ii<4; ++ii) {
|
399
|
424
|
// avg += vtkGrid->GetPointData()->GetScalars()->GetTuple(ID[ii])[0];
|
|
@@ -401,12 +426,17 @@ namespace Lemma {
|
401
|
426
|
//}
|
402
|
427
|
//TODO this seems wrong!
|
403
|
428
|
//avg /= 4.;
|
404
|
|
- g(ID[ii]) += (V/4.) * ( vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0] ) ;
|
|
429
|
+ // TODO test code remove
|
|
430
|
+ g(ID[ii]) += V/4*(vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0]) ;
|
|
431
|
+ if (std::abs(C(ii,3)-13.5) > 1e-5) {
|
|
432
|
+ g(ID[ii]) -= G[ii]*(V/3.)*sigma_bar;
|
|
433
|
+ }
|
405
|
434
|
//g(ID[ii]) += V/4*avg;
|
406
|
435
|
//g(ID[ii]) += 6.67 *(V/4.) * avg;
|
407
|
436
|
}
|
408
|
437
|
//g(ID[0]) += (V/4.) * avg;
|
409
|
438
|
}
|
|
439
|
+ //g -= A*DB;
|
410
|
440
|
|
411
|
441
|
}
|
412
|
442
|
|
|
@@ -657,14 +687,17 @@ namespace Lemma {
|
657
|
687
|
//Eigen::SimplicialCholesky<Eigen::SparseMatrix<Real>, Eigen::Lower > chol(A); // performs a Cholesky factorization of A
|
658
|
688
|
//VectorXr u = chol.solve(g);
|
659
|
689
|
|
|
690
|
+ //Eigen::SparseLU<Eigen::SparseMatrix<Real, Eigen::ColMajor>, Eigen::COLAMDOrdering<int> > solver;
|
|
691
|
+ //solver.analyzePattern(A);
|
|
692
|
+ //solver.factorize(A);
|
|
693
|
+ //VectorXr u = solver.solve(g);
|
|
694
|
+
|
660
|
695
|
//Eigen::ConjugateGradient<Eigen::SparseMatrix<Real, Eigen::Lower > Eigen::DiagonalPreconditioner > cg;
|
661
|
696
|
Eigen::ConjugateGradient< Eigen::SparseMatrix<Real> > cg(A);
|
662
|
|
-
|
663
|
697
|
//Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
|
664
|
698
|
cg.setMaxIterations(3000);
|
665
|
699
|
//cg.compute(A);
|
666
|
700
|
//std::cout << "Computed " << std::endl;
|
667
|
|
-
|
668
|
701
|
VectorXr u = cg.solve(g);
|
669
|
702
|
std::cout << "#iterations: " << cg.iterations() << std::endl;
|
670
|
703
|
std::cout << "estimated error: " << cg.error() << std::endl;
|