Переглянути джерело

Work on non-homogeneous dirichlet bdry

iss2
Trevor Irons 8 роки тому
джерело
коміт
053c81df6d

+ 1
- 1
examples/FEM4EllipticPDE_bhmag.cpp Переглянути файл

151
         //Solver->SetSigmaFunction(implSigma);
151
         //Solver->SetSigmaFunction(implSigma);
152
         Solver->SetBoundaryStep(.05);
152
         Solver->SetBoundaryStep(.05);
153
         Solver->SetGrid(MeshReader->GetOutput());
153
         Solver->SetGrid(MeshReader->GetOutput());
154
-        Solver->SetupPotential();
154
+        //Solver->SetupPotential();
155
         //Solver->SetGrid(rGrid);
155
         //Solver->SetGrid(rGrid);
156
         Solver->Solve(argv[3]);
156
         Solver->Solve(argv[3]);
157
 
157
 

+ 2
- 2
examples/borehole/sphere.geo Переглянути файл

8
  */
8
  */
9
 
9
 
10
 radius = 2.25;     // Radius of the damn thing
10
 radius = 2.25;     // Radius of the damn thing
11
-lc = radius/11;     //  0.25;   // Target element size
11
+lc = radius/3;     //  0.25;   // Target element size
12
 
12
 
13
 // Total Solution Space
13
 // Total Solution Space
14
 Box = 6*radius; // The down side of potential
14
 Box = 6*radius; // The down side of potential
19
 Z0 = -Box;
19
 Z0 = -Box;
20
 Z1 =  Box;
20
 Z1 =  Box;
21
 
21
 
22
-cellSize=radius/11; ///10;
22
+cellSize=radius/3; ///10;
23
 dd = 0 ; //  1e-5; //cellSize; // .01;
23
 dd = 0 ; //  1e-5; //cellSize; // .01;
24
 pio2=Pi/2;
24
 pio2=Pi/2;
25
 
25
 

+ 1
- 0
include/FEM4EllipticPDE.h Переглянути файл

51
 #include "vtkCellData.h"
51
 #include "vtkCellData.h"
52
 
52
 
53
 #include <Eigen/IterativeLinearSolvers>
53
 #include <Eigen/IterativeLinearSolvers>
54
+#include <Eigen/SparseLU>
54
 #include "DCSurvey.h"
55
 #include "DCSurvey.h"
55
 
56
 
56
 namespace Lemma {
57
 namespace Lemma {

+ 49
- 16
src/FEM4EllipticPDE.cpp Переглянути файл

201
 
201
 
202
     void FEM4EllipticPDE::Solve( const std::string& resfile ) {
202
     void FEM4EllipticPDE::Solve( const std::string& resfile ) {
203
         ConstructAMatrix();
203
         ConstructAMatrix();
204
+        SetupPotential();
204
         //ConstructLoadVector();
205
         //ConstructLoadVector();
205
 
206
 
206
         std::cout << "\nSolving" << std::endl;
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
         // Solving:
213
         // Solving:
209
         //Eigen::SimplicialCholesky<Eigen::SparseMatrix<Real>, Eigen::Lower > chol(A);  // performs a Cholesky factorization of A
214
         //Eigen::SimplicialCholesky<Eigen::SparseMatrix<Real>, Eigen::Lower > chol(A);  // performs a Cholesky factorization of A
210
         //VectorXr u = chol.solve(g);
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
         //Eigen::ConjugateGradient<Eigen::SparseMatrix<Real, Eigen::Lower >  Eigen::DiagonalPreconditioner > cg;
223
         //Eigen::ConjugateGradient<Eigen::SparseMatrix<Real, Eigen::Lower >  Eigen::DiagonalPreconditioner > cg;
213
         Eigen::ConjugateGradient< Eigen::SparseMatrix<Real>  > cg(A);
224
         Eigen::ConjugateGradient< Eigen::SparseMatrix<Real>  > cg(A);
214
-
215
         //Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
225
         //Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
216
         //cg.setMaxIterations(3000);
226
         //cg.setMaxIterations(3000);
217
         //cg.setTolerance(1e-28);
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
         VectorXr u = cg.solve(g);
228
         VectorXr u = cg.solve(g);
224
         std::cout << "#iterations:     " << cg.iterations() << std::endl;
229
         std::cout << "#iterations:     " << cg.iterations() << std::endl;
225
         std::cout << "estimated error: " << cg.error()      << std::endl;
230
         std::cout << "estimated error: " << cg.error()      << std::endl;
231
+        //#endif
226
 
232
 
227
         vtkDoubleArray *gArray = vtkDoubleArray::New();
233
         vtkDoubleArray *gArray = vtkDoubleArray::New();
228
         vtkDoubleArray *uArray = vtkDoubleArray::New();
234
         vtkDoubleArray *uArray = vtkDoubleArray::New();
330
             } else {
336
             } else {
331
                 sigma_bar = 1.;
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
             for (int ii=0; ii<4; ++ii) {
342
             for (int ii=0; ii<4; ++ii) {
338
                 for (int jj=0; jj<4; ++jj) {
343
                 for (int jj=0; jj<4; ++jj) {
339
                     /* homogeneous Dirichlet boundary */
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
                         // Apply Homogeneous Dirichlet Boundary conditions
348
                         // Apply Homogeneous Dirichlet Boundary conditions
342
                         Real bb = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0];
349
                         Real bb = vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0];
343
                         Real bdry = (1./(BndryH*BndryH))*BndrySigma*bb; // + sum;
350
                         Real bdry = (1./(BndryH*BndryH))*BndrySigma*bb; // + sum;
344
                         //Real bdry = GradPhi.col(ii).tail<3>().dot(GradPhi.col(ii).tail<3>())*BndrySigma*bb; // + sum;
351
                         //Real bdry = GradPhi.col(ii).tail<3>().dot(GradPhi.col(ii).tail<3>())*BndrySigma*bb; // + sum;
345
                         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 ) );
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
                     } else {
355
                     } else {
347
                         coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj],        GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>() ) * V * sigma_bar ) );
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
                     // Stiffness matrix no longer contains boundary conditions...
361
                     // Stiffness matrix no longer contains boundary conditions...
350
                     //coeffs.push_back( Eigen::Triplet<Real> ( ID[ii], ID[jj], GradPhi.col(ii).tail<3>().dot(GradPhi.col(jj).tail<3>() ) * V * sigma_bar ) );
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
         A.setFromTriplets(coeffs.begin(), coeffs.end());
367
         A.setFromTriplets(coeffs.begin(), coeffs.end());
356
         //std::cout << "A\n" << A << std::endl;
368
         //std::cout << "A\n" << A << std::endl;
363
         std::cout << "\nBuilding load vector (g)" << std::endl;
375
         std::cout << "\nBuilding load vector (g)" << std::endl;
364
         g = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
376
         g = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
365
         std::cout << "made g with "  << vtkGrid->GetNumberOfPoints() << " points" << std::endl;
377
         std::cout << "made g with "  << vtkGrid->GetNumberOfPoints() << " points" << std::endl;
366
-
378
+        VectorXr DB = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
367
         for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
379
         for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
368
 
380
 
369
             Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
381
             Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
375
                 C(ii, 3) =  pts[2];
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
             vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
393
             vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
381
             int ID[4];
394
             int ID[4];
384
                 ID[2] = Ids->GetId(2);
397
                 ID[2] = Ids->GetId(2);
385
                 ID[3] = Ids->GetId(3);
398
                 ID[3] = Ids->GetId(3);
386
 
399
 
387
-
400
+            /*
388
             Real avg(0);
401
             Real avg(0);
389
             Real GG[4];
402
             Real GG[4];
390
             for (int ii=0; ii<4; ++ii) {
403
             for (int ii=0; ii<4; ++ii) {
394
             if ( std::abs( (GG[0]+GG[1]+GG[2]+GG[3])/4. - GG[0])  < 1e-5) {
407
             if ( std::abs( (GG[0]+GG[1]+GG[2]+GG[3])/4. - GG[0])  < 1e-5) {
395
                 avg = GG[0];
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
             for (int ii=0; ii<4; ++ii) {
423
             for (int ii=0; ii<4; ++ii) {
399
             //     avg += vtkGrid->GetPointData()->GetScalars()->GetTuple(ID[ii])[0];
424
             //     avg += vtkGrid->GetPointData()->GetScalars()->GetTuple(ID[ii])[0];
401
             //}
426
             //}
402
             //TODO this seems wrong!
427
             //TODO this seems wrong!
403
             //avg /= 4.;
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
                 //g(ID[ii]) +=  V/4*avg;
434
                 //g(ID[ii]) +=  V/4*avg;
406
                   //g(ID[ii]) +=  6.67 *(V/4.) * avg;
435
                   //g(ID[ii]) +=  6.67 *(V/4.) * avg;
407
             }
436
             }
408
             //g(ID[0]) +=  (V/4.) * avg;
437
             //g(ID[0]) +=  (V/4.) * avg;
409
         }
438
         }
439
+        //g -= A*DB;
410
 
440
 
411
     }
441
     }
412
 
442
 
657
         //Eigen::SimplicialCholesky<Eigen::SparseMatrix<Real>, Eigen::Lower > chol(A);  // performs a Cholesky factorization of A
687
         //Eigen::SimplicialCholesky<Eigen::SparseMatrix<Real>, Eigen::Lower > chol(A);  // performs a Cholesky factorization of A
658
         //VectorXr u = chol.solve(g);
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
         //Eigen::ConjugateGradient<Eigen::SparseMatrix<Real, Eigen::Lower >  Eigen::DiagonalPreconditioner > cg;
695
         //Eigen::ConjugateGradient<Eigen::SparseMatrix<Real, Eigen::Lower >  Eigen::DiagonalPreconditioner > cg;
661
         Eigen::ConjugateGradient< Eigen::SparseMatrix<Real>  > cg(A);
696
         Eigen::ConjugateGradient< Eigen::SparseMatrix<Real>  > cg(A);
662
-
663
         //Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
697
         //Eigen::BiCGSTAB<Eigen::SparseMatrix<Real> > cg(A);
664
         cg.setMaxIterations(3000);
698
         cg.setMaxIterations(3000);
665
         //cg.compute(A);
699
         //cg.compute(A);
666
         //std::cout << "Computed     " << std::endl;
700
         //std::cout << "Computed     " << std::endl;
667
-
668
         VectorXr u = cg.solve(g);
701
         VectorXr u = cg.solve(g);
669
         std::cout << "#iterations:     " << cg.iterations() << std::endl;
702
         std::cout << "#iterations:     " << cg.iterations() << std::endl;
670
         std::cout << "estimated error: " << cg.error()      << std::endl;
703
         std::cout << "estimated error: " << cg.error()      << std::endl;

Завантаження…
Відмінити
Зберегти