Bläddra i källkod

Surface sources now working, but need to add switch mechanisms.

master
Trevor Irons 8 år sedan
förälder
incheckning
747ea76d61

+ 17
- 3
examples/CMakeLists.txt Visa fil

@@ -16,15 +16,19 @@ target_link_libraries( VTKEdgeG  "lemmacore" "fem4ellipticpde")
16 16
 add_executable( VTKEdgeGsphere VTKEdgeGsphere.cpp  )
17 17
 target_link_libraries( VTKEdgeGsphere  "lemmacore" "fem4ellipticpde")
18 18
 
19
-add_executable( VTKGsphere VTKGsphere.cpp  )
20
-target_link_libraries( VTKGsphere  "lemmacore" "fem4ellipticpde")
19
+add_executable( setupGravSphere setupGravSphere.cpp  )
20
+target_link_libraries( setupGravSphere  "lemmacore" "fem4ellipticpde")
21 21
 
22 22
 add_executable( ResampleWithDataset ResampleWithDataset.cpp  )
23 23
 target_link_libraries( ResampleWithDataset  "lemmacore" "fem4ellipticpde")
24 24
 
25 25
 #INSTALL_TARGETS( "${CMAKE_INSTALL_PREFIX}/share/FEM4EllipticPDE/"
26 26
 INSTALL_TARGETS( "/share/FEM4EllipticPDE/"
27
-	FEM4EllipticPDE_bhmag FEM4EllipticPDE merge VTKDC VTKEdgeG VTKGsphere VTKEdgeGsphere ResampleWithDataset
27
+	FEM4EllipticPDE_bhmag FEM4EllipticPDE merge VTKDC VTKEdgeG VTKEdgeGsphere ResampleWithDataset
28
+)
29
+
30
+INSTALL_TARGETS( "/share/FEM4EllipticPDE/grav"
31
+	setupGravSphere 
28 32
 )
29 33
 
30 34
 install( DIRECTORY "borehole"
@@ -32,6 +36,16 @@ install( DIRECTORY "borehole"
32 36
 	PATTERN .svn EXCLUDE
33 37
 )
34 38
 
39
+install( DIRECTORY "grav"
40
+	DESTINATION "${CMAKE_INSTALL_PREFIX}/share/FEM4EllipticPDE/"
41
+	PATTERN .svn EXCLUDE
42
+)
43
+
44
+install( DIRECTORY "magnet"
45
+	DESTINATION "${CMAKE_INSTALL_PREFIX}/share/FEM4EllipticPDE/"
46
+	PATTERN .svn EXCLUDE
47
+)
48
+
35 49
 install( DIRECTORY "DC"
36 50
 	DESTINATION "${CMAKE_INSTALL_PREFIX}/share/FEM4EllipticPDE/"
37 51
 	PATTERN .svn EXCLUDE

examples/borehole/sphere.geo → examples/grav/sphere.geo Visa fil


examples/borehole/sphere.sh → examples/grav/sphere.sh Visa fil

@@ -2,7 +2,7 @@
2 2
 gmsh  -3 -format vtk -o sphere.vtk  sphere.geo 
3 3
 gmsh  -2 -format stl -o sphereBox.stl  sphereBox.geo 
4 4
 ../ResampleWithDataset  sphere.vtk  sphereBox.stl  MergedSphere.vtu 
5
-../VTKGsphere MergedSphere.vtu   2.25  gravity  sphereGrav.vtu
5
+./setupGravSphere MergedSphere.vtu   2.25  gravity  sphereGrav.vtu
6 6
 ../FEM4EllipticPDE_bhmag  sphereGrav.vtu  sphereGrav.vtu   sphereOutGrav.vtu 
7 7
 
8 8
 #paraview --data=sphereOutGrav.vtu 

examples/borehole/sphereBox.geo → examples/grav/sphereBox.geo Visa fil


examples/VTKGsphere.cpp → examples/setupGravSphere.cpp Visa fil


+ 16
- 0
include/FEM4EllipticPDE.h Visa fil

@@ -228,6 +228,22 @@ namespace Lemma {
228 228
              */
229 229
             Real dist(const Vector3r& r0, const Vector3r& r1);
230 230
 
231
+            /** Sets up the potential problem from the VTK file
232
+             */
233
+            void SetupLineSourcePotential();
234
+
235
+            /** Sets up the potential problem from the VTK file
236
+             */
237
+            void SetupSurfaceSourcePotential();
238
+
239
+            /** Sets up the potential problem from the VTK file
240
+             */
241
+            void SetupPointSourcePotential();
242
+
243
+            /** Sets up the potential problem from the VTK file
244
+             */
245
+            void SetupVolumeSourcePotential();
246
+
231 247
             // ====================  DATA MEMBERS  =========================
232 248
 
233 249
             /** The effective step at the boundary condition. Defaults to 1

+ 158
- 2
src/FEM4EllipticPDE.cpp Visa fil

@@ -201,7 +201,9 @@ namespace Lemma {
201 201
 
202 202
     void FEM4EllipticPDE::Solve( const std::string& resfile ) {
203 203
         ConstructAMatrix();
204
-        SetupPotential();
204
+        //SetupLineSourcePotential();
205
+        SetupSurfaceSourcePotential();
206
+        //SetupPotential();
205 207
         //ConstructLoadVector();
206 208
 
207 209
         std::cout << "\nSolving" << std::endl;
@@ -389,10 +391,164 @@ namespace Lemma {
389 391
                 if (vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0]) {
390 392
                     g(ID[ii]) += vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
391 393
                 } else {
392
-                    g(ID[ii]) += (V/4.)*(vtkGrid->GetCellData()->GetScalars("G")->GetTuple(ic)[0]); // Why 3.0??
394
+                    g(ID[ii]) += (V/4.)*(vtkGrid->GetCellData()->GetScalars("G")->GetTuple(ic)[0]); // Cell data
395
+                    /* for point data, determine if it is a point or line source */
396
+                    //g(ID[ii]) = (vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0]); // Point source
397
+                    //g(ID[ii]) = (vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0]); // Point source
393 398
                 }
394 399
             }
395 400
 
401
+
402
+
403
+        }
404
+    }
405
+
406
+    void FEM4EllipticPDE::SetupLineSourcePotential() {
407
+
408
+        std::cerr << " FEM4EllipticPDE::SetupLineSourcePotential is not completed\n";
409
+        exit(1);
410
+
411
+        ////////////////////////////////////////////////////////////
412
+	    // Load vector g
413
+        std::cout << "\nBuilding load vector (g)" << std::endl;
414
+        g = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
415
+        std::cout << "made g with "  << vtkGrid->GetNumberOfPoints() << " points" << std::endl;
416
+
417
+        for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
418
+
419
+            Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
420
+            for (int ii=0; ii<4; ++ii) {
421
+                double* pts =  vtkGrid->GetCell(ic)->GetPoints()->GetPoint(ii); //[ipc] ;
422
+                C(ii, 0) =  1;
423
+                C(ii, 1) =  pts[0];
424
+                C(ii, 2) =  pts[1];
425
+                C(ii, 3) =  pts[2];
426
+            }
427
+
428
+            Real V = (1./6.) * C.determinant();              // volume of tetrahedra
429
+            //Eigen::Matrix<Real, 4, 4> GradPhi = C.inverse(); // nabla \phi
430
+
431
+            /* The indices */
432
+            vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
433
+            int ID[4];
434
+                ID[0] = Ids->GetId(0);
435
+                ID[1] = Ids->GetId(1);
436
+                ID[2] = Ids->GetId(2);
437
+                ID[3] = Ids->GetId(3);
438
+
439
+            /* Line source between nodes */
440
+            for (int ii=0; ii<4; ++ii) {
441
+                if (vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0]) {
442
+                    g(ID[ii]) += vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
443
+                } else {
444
+                    Real nv1 = vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0];
445
+                    for (int jj=ii+1; jj<4; ++jj) {
446
+                        Real nv2 = vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[jj])[0];
447
+                        if ( std::abs(nv1) > 1e-12 && std::abs(nv2) > 1e-12) {
448
+                            Real length = ( C.row(ii).tail<3>()-C.row(jj).tail<3>()  ).norm();
449
+
450
+                            g(ID[ii]) += ((nv1+nv2)/2.)/(length);//*(V/4.);// * (vtkGrid->GetPointData()->GetScalars("G")->GetTuple(ID[ii])[0]); // Point source
451
+                        }
452
+                    }
453
+                }
454
+            }
455
+        }
456
+
457
+    }
458
+
459
+    void FEM4EllipticPDE::SetupSurfaceSourcePotential() {
460
+
461
+        ////////////////////////////////////////////////////////////
462
+	    // Load vector g
463
+        std::cout << "\nBuilding load vector (g)" << std::endl;
464
+        g = VectorXr::Zero(vtkGrid->GetNumberOfPoints());
465
+        std::cout << "made g with "  << vtkGrid->GetNumberOfPoints() << " points" << std::endl;
466
+
467
+        for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
468
+
469
+            Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
470
+            for (int ii=0; ii<4; ++ii) {
471
+                double* pts =  vtkGrid->GetCell(ic)->GetPoints()->GetPoint(ii); //[ipc] ;
472
+                C(ii, 0) =  1;
473
+                C(ii, 1) =  pts[0];
474
+                C(ii, 2) =  pts[1];
475
+                C(ii, 3) =  pts[2];
476
+            }
477
+
478
+            Real V = (1./6.) * C.determinant();              // volume of tetrahedra
479
+            //Eigen::Matrix<Real, 4, 4> GradPhi = C.inverse(); // nabla \phi
480
+
481
+            /* The indices */
482
+            vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
483
+            int ID[4];
484
+                ID[0] = Ids->GetId(0);
485
+                ID[1] = Ids->GetId(1);
486
+                ID[2] = Ids->GetId(2);
487
+                ID[3] = Ids->GetId(3);
488
+
489
+            // Apply Dirichlet conditions
490
+            for (int ii=0; ii<4; ++ii) {
491
+                if (vtkGrid->GetPointData()->GetScalars("HomogeneousDirichlet")->GetTuple(ID[ii])[0]) {
492
+                    g(ID[ii]) += vtkGrid->GetPointData()->GetScalars("analytic_phi")->GetTuple(ID[ii])[0];
493
+                }
494
+            }
495
+
496
+            /* the 4 faces of the tetrahedra
497
+            ID[0] ID[1] ID[2]
498
+            ID[0] ID[1] ID[3]
499
+            ID[0] ID[2] ID[3]
500
+            ID[1] ID[2] ID[3]
501
+            */
502
+            //Real i4pi = .99738684646226885559*.961*PI/6.;//(4.*PI);// * V/4.;
503
+            //Real i4pi = .99738684646226885559*.961*PI/6.;//(4.*PI);// * V/4.;
504
+            //Real i4pi =  0.9584887594502403*PI/6.;//(4.*PI);// * V/4.;
505
+            Real i4pi = .5;// 0.1597132348845018*PI; // very nearly .5
506
+            /* surfaces of tetrahedra */
507
+            // Face 0, ID 0,1,2
508
+            Eigen::Matrix<Real, 3, 3> CC = Eigen::Matrix<Real, 3, 3>::Ones() ;
509
+            if (    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0])) > 1e-12 &&
510
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1])) > 1e-12 &&
511
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])) > 1e-12    ) {
512
+                CC.col(1) = C.row(0).tail<3>() - C.row(1).tail<3>();
513
+                CC.col(2) = C.row(0).tail<3>() - C.row(2).tail<3>();
514
+                Real TA = .5*CC.col(1).cross(CC.col(2)).norm();
515
+                g(ID[0]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0])*TA/3. * i4pi ;
516
+                g(ID[1]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1])*TA/3. * i4pi ;
517
+                g(ID[2]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])*TA/3. * i4pi ;
518
+            }
519
+            // Face 1, ID 0,1,3
520
+            if (    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0])) > 1e-12 &&
521
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1])) > 1e-12 &&
522
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3])) > 1e-12    ) {
523
+                CC.col(1) = C.row(0).tail<3>() - C.row(1).tail<3>();
524
+                CC.col(2) = C.row(0).tail<3>() - C.row(3).tail<3>();
525
+                Real TA = .5*CC.col(1).cross(CC.col(2)).norm();
526
+                g(ID[0]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0])*TA/3. * i4pi ;
527
+                g(ID[1]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1])*TA/3. * i4pi ;
528
+                g(ID[3]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3])*TA/3. * i4pi ;
529
+            }
530
+            // Face 2, ID 0,2,3
531
+            if (    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0])) > 1e-12 &&
532
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])) > 1e-12 &&
533
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3])) > 1e-12    ) {
534
+                CC.col(1) = C.row(0).tail<3>() - C.row(2).tail<3>();
535
+                CC.col(2) = C.row(0).tail<3>() - C.row(3).tail<3>();
536
+                Real TA = .5*CC.col(1).cross(CC.col(2)).norm();
537
+                g(ID[0]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[0])*TA/3. * i4pi ;
538
+                g(ID[2]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])*TA/3. * i4pi ;
539
+                g(ID[3]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3])*TA/3. * i4pi ;
540
+            }
541
+            // Face 3, ID 1,2,3
542
+            if (    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1])) > 1e-12 &&
543
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])) > 1e-12 &&
544
+                    std::abs(vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3])) > 1e-12    ) {
545
+                CC.col(1) = C.row(1).tail<3>() - C.row(2).tail<3>();
546
+                CC.col(2) = C.row(1).tail<3>() - C.row(3).tail<3>();
547
+                Real TA = .5*CC.col(1).cross(CC.col(2)).norm();
548
+                g(ID[1]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[1])*TA/3. * i4pi ;
549
+                g(ID[2]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])*TA/3. * i4pi ;
550
+                g(ID[3]) += vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[3])*TA/3. * i4pi ;
551
+            }
396 552
         }
397 553
     }
398 554
 

Laddar…
Avbryt
Spara