|
@@ -205,30 +205,38 @@ namespace Lemma {
|
205
|
205
|
|
206
|
206
|
|
207
|
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;
|
|
208
|
+
|
|
209
|
+ std::cout << std::setw(5) << " " << std::setw(14) << "rows" << std::setw(14) << "cols" << std::endl;
|
|
210
|
+ std::cout << std::setw(5) << " " << std::setw(14) << "--------" << std::setw(14) << "--------" << std::endl;
|
|
211
|
+ std::cout << std::setw(5) << "A:" << std::setw(14) << A.rows() << std::setw(14) << A.cols() << std::endl;
|
|
212
|
+ std::cout << std::setw(5) << "g:" << std::setw(14) << g.rows() << std::setw(14) << g.cols() << std::endl;
|
211
|
213
|
|
212
|
214
|
|
213
|
215
|
|
214
|
216
|
|
215
|
217
|
|
216
|
|
-
|
217
|
|
-
|
218
|
|
-
|
219
|
|
-
|
220
|
|
-
|
221
|
|
-
|
222
|
|
-
|
223
|
|
-
|
224
|
|
-
|
|
218
|
+
|
|
219
|
+ #ifdef LUSOLVE
|
|
220
|
+ Eigen::SparseLU<Eigen::SparseMatrix<Real, Eigen::ColMajor>, Eigen::COLAMDOrdering<int> > solver;
|
|
221
|
+ std::cout << "LU analyze pattern" << std::endl;
|
|
222
|
+ solver.analyzePattern(A);
|
|
223
|
+ std::cout << "LU factorizing" << std::endl;
|
|
224
|
+ solver.factorize(A);
|
|
225
|
+ std::cout << "LU solving" << std::endl;
|
|
226
|
+ solver.factorize(A);
|
|
227
|
+ VectorXr u = solver.solve(g);
|
|
228
|
+ #endif
|
|
229
|
+
|
|
230
|
+ #define CGSOLVE
|
|
231
|
+ #ifdef CGSOLVE
|
|
232
|
+
|
225
|
233
|
Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
|
226
|
234
|
|
227
|
235
|
|
228
|
236
|
VectorXr u = cg.solve(g);
|
229
|
237
|
std::cout << "#iterations: " << cg.iterations() << std::endl;
|
230
|
238
|
std::cout << "estimated error: " << cg.error() << std::endl;
|
231
|
|
-
|
|
239
|
+ #endif
|
232
|
240
|
|
233
|
241
|
vtkDoubleArray *gArray = vtkDoubleArray::New();
|
234
|
242
|
vtkDoubleArray *uArray = vtkDoubleArray::New();
|
|
@@ -284,7 +292,6 @@ namespace Lemma {
|
284
|
292
|
GCell = true;
|
285
|
293
|
}
|
286
|
294
|
|
287
|
|
-
|
288
|
295
|
|
289
|
296
|
for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
|
290
|
297
|
|
|
@@ -315,19 +322,8 @@ namespace Lemma {
|
315
|
322
|
ID[3] = Ids->GetId(3);
|
316
|
323
|
|
317
|
324
|
Real sigma_bar(0);
|
318
|
|
-
|
319
|
|
- if (GCell) {
|
320
|
|
- sigma_bar = vtkGrid->GetCellData()->GetScalars("G")->GetTuple1(ic);
|
321
|
|
- } else {
|
322
|
|
- sigma_bar = vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0]);
|
323
|
|
- sigma_bar += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1]);
|
324
|
|
- sigma_bar += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2]);
|
325
|
|
- sigma_bar += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3]);
|
326
|
|
- sigma_bar /= 4.;
|
327
|
|
- }
|
328
|
|
- */
|
329
|
|
-
|
330
|
325
|
|
|
326
|
+
|
331
|
327
|
Real xc = C.col(1).array().mean();
|
332
|
328
|
Real yc = C.col(2).array().mean();
|
333
|
329
|
Real zc = C.col(3).array().mean();
|
|
@@ -336,40 +332,26 @@ namespace Lemma {
|
336
|
332
|
} else {
|
337
|
333
|
sigma_bar = 1.;
|
338
|
334
|
}
|
|
335
|
+ */
|
339
|
336
|
sigma_bar = 1.;
|
340
|
337
|
|
341
|
338
|
|
342
|
339
|
for (int ii=0; ii<4; ++ii) {
|
343
|
340
|
int bbi = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0];
|
344
|
341
|
if (bbi) {
|
|
342
|
+
|
345
|
343
|
coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[ii], 1));
|
346
|
344
|
} else {
|
347
|
345
|
for (int jj=0; jj<4; ++jj) {
|
348
|
|
-
|
349
|
|
-
|
350
|
|
-
|
351
|
|
-
|
352
|
|
-
|
353
|
|
-
|
354
|
|
-
|
355
|
|
-
|
356
|
|
-
|
357
|
|
-
|
358
|
|
-
|
359
|
346
|
coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>() ) * V * sigma_bar ) );
|
360
|
|
-
|
361
|
|
-
|
362
|
|
-
|
363
|
|
-
|
364
|
|
-
|
365
|
|
-
|
|
347
|
+ }
|
366
|
348
|
}
|
367
|
349
|
}
|
368
|
|
- }
|
369
|
|
-
|
|
350
|
+ std::cout << "\r" << (int)(1e2*((float)(ic) / (float)(vtkGrid->GetNumberOfCells()))) << std::flush ;
|
370
|
351
|
}
|
371
|
352
|
A.setFromTriplets(coeffs.begin(), coeffs.end());
|
372
|
|
-
|
|
353
|
+ A.finalize();
|
|
354
|
+ A.makeCompressed();
|
373
|
355
|
}
|
374
|
356
|
|
375
|
357
|
void FEM4EllipticPDE::SetupPotential() {
|
|
@@ -379,7 +361,7 @@ namespace Lemma {
|
379
|
361
|
std::cout << "\nBuilding load vector (g)" << std::endl;
|
380
|
362
|
g = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
|
381
|
363
|
std::cout << "made g with " << vtkGrid->GetNumberOfPoints() << " points" << std::endl;
|
382
|
|
- VectorXr DB = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
|
|
364
|
+
|
383
|
365
|
for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
|
384
|
366
|
|
385
|
367
|
Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
|
|
@@ -392,8 +374,9 @@ namespace Lemma {
|
392
|
374
|
}
|
393
|
375
|
|
394
|
376
|
Real V = (1./6.) * C.determinant();
|
395
|
|
- Eigen::Matrix<Real, 4, 4> GradPhi = C.inverse();
|
|
377
|
+
|
396
|
378
|
|
|
379
|
+
|
397
|
380
|
vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
|
398
|
381
|
int ID[4];
|
399
|
382
|
ID[0] = Ids->GetId(0);
|
|
@@ -401,56 +384,19 @@ namespace Lemma {
|
401
|
384
|
ID[2] = Ids->GetId(2);
|
402
|
385
|
ID[3] = Ids->GetId(3);
|
403
|
386
|
|
404
|
|
-
|
405
|
|
- Real avg(0);
|
406
|
|
- Real GG[4];
|
407
|
|
- for (int ii=0; ii<4; ++ii) {
|
408
|
|
- GG[ii] = vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0];
|
409
|
|
-
|
410
|
|
- }
|
411
|
|
- if ( std::abs( (GG[0]+GG[1]+GG[2]+GG[3])/4. - GG[0]) < 1e-5) {
|
412
|
|
- avg = GG[0];
|
413
|
|
- }
|
414
|
|
- */
|
415
|
|
-
|
416
|
|
-
|
417
|
|
- VectorXr W = VectorXr::Zero(4);
|
|
387
|
+
|
418
|
388
|
for (int ii=0; ii<4; ++ii) {
|
419
|
|
- W[ii] = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0] *
|
420
|
|
- vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
|
421
|
|
- DB[ID[ii]] = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0] *
|
422
|
|
- vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
|
423
|
|
- }
|
424
|
|
-
|
425
|
|
- VectorXr G = GradPhi.block<3,4>(1,0).transpose()*GradPhi.block<3,4>(1,0)*W;
|
426
|
|
- Real sigma_bar(1.);
|
427
|
|
- */
|
428
|
|
-
|
429
|
|
- for (int ii=0; ii<4; ++ii) {
|
430
|
|
-
|
431
|
|
-
|
432
|
|
-
|
433
|
|
-
|
434
|
|
-
|
435
|
|
-
|
436
|
389
|
if (vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0]) {
|
437
|
390
|
g(ID[ii]) += vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
|
438
|
391
|
} else {
|
439
|
|
- g(ID[ii]) += (PI*V)*(vtkGrid->GetCellData()->GetScalars("G")->GetTuple(ic)[0]);
|
|
392
|
+ g(ID[ii]) += (V/4.)*(vtkGrid->GetCellData()->GetScalars("G")->GetTuple(ic)[0]);
|
440
|
393
|
}
|
441
|
|
-
|
442
|
|
-
|
443
|
|
-
|
444
|
|
-
|
445
|
|
-
|
446
|
394
|
}
|
447
|
|
-
|
448
|
|
- }
|
449
|
|
-
|
450
|
395
|
|
|
396
|
+ }
|
451
|
397
|
}
|
452
|
398
|
|
453
|
|
- void FEM4EllipticPDE::SolveOLD(const std::string& fname) {
|
|
399
|
+ void FEM4EllipticPDE::SolveOLD2(const std::string& fname) {
|
454
|
400
|
|
455
|
401
|
Real r0[3];
|
456
|
402
|
Real r1[3];
|