Sfoglia il codice sorgente

Work on non-homogeneous dirichlet bdry

iss2
Trevor Irons 8 anni fa
parent
commit
053c81df6d

+ 1
- 1
examples/FEM4EllipticPDE_bhmag.cpp Vedi File

@@ -151,7 +151,7 @@ int main(int argc, char**argv) {
151 151
         //Solver->SetSigmaFunction(implSigma);
152 152
         Solver->SetBoundaryStep(.05);
153 153
         Solver->SetGrid(MeshReader->GetOutput());
154
-        Solver->SetupPotential();
154
+        //Solver->SetupPotential();
155 155
         //Solver->SetGrid(rGrid);
156 156
         Solver->Solve(argv[3]);
157 157
 

+ 2
- 2
examples/borehole/sphere.geo Vedi File

@@ -8,7 +8,7 @@
8 8
  */
9 9
 
10 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 13
 // Total Solution Space
14 14
 Box = 6*radius; // The down side of potential
@@ -19,7 +19,7 @@ Y1 =  Box;
19 19
 Z0 = -Box;
20 20
 Z1 =  Box;
21 21
 
22
-cellSize=radius/11; ///10;
22
+cellSize=radius/3; ///10;
23 23
 dd = 0 ; //  1e-5; //cellSize; // .01;
24 24
 pio2=Pi/2;
25 25
 

+ 1
- 0
include/FEM4EllipticPDE.h Vedi File

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

+ 49
- 16
src/FEM4EllipticPDE.cpp Vedi File

@@ -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;

Loading…
Annulla
Salva