ソースを参照

Adding linear mag code

master
Trevor Irons 8年前
コミット
0e6c8ce425

+ 3
- 4
examples/CMakeLists.txt ファイルの表示

@@ -1,8 +1,8 @@
1 1
 add_executable( FEM4EllipticPDE_bhmag FEM4EllipticPDE_bhmag.cpp  )
2 2
 target_link_libraries(  FEM4EllipticPDE_bhmag  "lemmacore" "fem4ellipticpde")
3 3
 
4
-add_executable( FEM4EllipticPDE FEM4EllipticPDE.cpp  )
5
-target_link_libraries(  FEM4EllipticPDE  "lemmacore" "fem4ellipticpde")
4
+#add_executable( FEM4EllipticPDE FEM4EllipticPDE.cpp  )
5
+#target_link_libraries(  FEM4EllipticPDE  "lemmacore" "fem4ellipticpde")
6 6
 
7 7
 add_executable( merge merge.cpp  )
8 8
 target_link_libraries(  merge  "lemmacore" "fem4ellipticpde")
@@ -31,9 +31,8 @@ install(DIRECTORY "LinearMag"
31 31
 	PATTERN "CMakeLists.txt"  EXCLUDE
32 32
 )
33 33
 
34
-#INSTALL_TARGETS( "${CMAKE_INSTALL_PREFIX}/share/FEM4EllipticPDE/"
35 34
 INSTALL_TARGETS( "/share/FEM4EllipticPDE/"
36
-	FEM4EllipticPDE_bhmag FEM4EllipticPDE merge VTKDC VTKEdgeG VTKEdgeGsphere ResampleWithDataset
35
+	FEM4EllipticPDE_bhmag  merge VTKDC VTKEdgeG VTKEdgeGsphere ResampleWithDataset
37 36
 )
38 37
 
39 38
 INSTALL_TARGETS( "/share/FEM4EllipticPDE/grav"

+ 9
- 9
examples/FEM4EllipticPDE_bhmag.cpp ファイルの表示

@@ -93,7 +93,7 @@ int main(int argc, char**argv) {
93 93
         //std::cout << "usage: ./utFEMEllipticPDE_bhmag   <mesh.vtu>  <results.vtu>" << std::endl;
94 94
         exit(EXIT_SUCCESS);
95 95
     }
96
-
96
+/*
97 97
     int    nx = 80;
98 98
     //double dx =  .0021875 ; // 160
99 99
     double dx =  .004375 ; // 160
@@ -119,7 +119,7 @@ int main(int argc, char**argv) {
119 119
         rGrid->SetXCoordinates(xCoords);
120 120
         rGrid->SetYCoordinates(yCoords);
121 121
         rGrid->SetZCoordinates(zCoords);
122
-
122
+*/
123 123
     ////////////////////////////////////////////
124 124
     // Define Sigma/mu term
125 125
     // TODO
@@ -131,10 +131,10 @@ int main(int argc, char**argv) {
131 131
         GReader->SetFileName(argv[1]);
132 132
         GReader->Update();
133 133
 
134
-    vtkImplicitDataSet* implG = vtkImplicitDataSet::New();
135
-        implG->SetDataSet(GReader->GetOutput());
136
-        implG->SetOutValue(0.);
137
-        implG->SetOutGradient(0., 0., 0.);
134
+    //vtkImplicitDataSet* implG = vtkImplicitDataSet::New();
135
+    //    implG->SetDataSet(GReader->GetOutput());
136
+    //    implG->SetOutValue(0.);
137
+    //    implG->SetOutGradient(0., 0., 0.);
138 138
 
139 139
     ////////////////////////////////////////////
140 140
     // Define solution mesh
@@ -146,10 +146,10 @@ int main(int argc, char**argv) {
146 146
     ////////////////////////////////////////////
147 147
     // Solve
148 148
     FEM4EllipticPDE *Solver = FEM4EllipticPDE::New();
149
-        Solver->SetGFunction(implG);
149
+        //Solver->SetGFunction(implG);
150 150
         //Solver->SetGFunction(Magnet);
151 151
         //Solver->SetSigmaFunction(implSigma);
152
-        Solver->SetBoundaryStep(.05);
152
+        //Solver->SetBoundaryStep(.05);
153 153
         Solver->SetGrid(MeshReader->GetOutput());
154 154
         //Solver->SetupPotential();
155 155
         //Solver->SetGrid(rGrid);
@@ -158,7 +158,7 @@ int main(int argc, char**argv) {
158 158
     // Clean up
159 159
     Solver->Delete();
160 160
     GReader->Delete();
161
-    implG->Delete();
161
+    //implG->Delete();
162 162
 
163 163
     exit(EXIT_SUCCESS);
164 164
 }

+ 27
- 2
examples/LinearMag/Sphere.cpp ファイルの表示

@@ -18,12 +18,37 @@
18 18
  */
19 19
 
20 20
 #include "Lemma"
21
+#include "LinearMag.h"
21 22
 
22 23
 using namespace Lemma;
23 24
 
24
-int main() {
25
+int main( int argc, char** argv ) {
25 26
 
26
-    std::cout << "Test of LinearMag class\n";
27 27
 
28
+    std::cout << "###################################################\n";
29
+    std::cout << "#          Example of LinearMag class             #\n";
30
+    std::cout << "#                                                 #\n";
31
+    std::cout << "# This program solves for the secondary magnetic  #\n";
32
+    std::cout << "# field from a low susceptibily model in the      #\n";
33
+    std::cout << "# presence of a homogeneous static inducing field #\n";
34
+    std::cout << "###################################################\n\n";
35
+
36
+    if (argc < 3) {
37
+        std::cout << "\e[1museage\e[0m:\n";
38
+        std::cout << "./Sphere  in.vtu out.vtu\n\n" << std::endl;
39
+        exit(EXIT_SUCCESS);
40
+    }
41
+
42
+    LinearMag* Mag = LinearMag::New();
43
+        Mag->SetInducingMagField( 55234., 60, 14, NANOTESLA );
44
+        Mag->SetVTUGridFile( argv[1] );
45
+        Mag->CalculateRHS( "kappa" );
46
+        Mag->Solve( argv[2] );
47
+
48
+    // Print out YAML serialization of class
49
+    std::cout << *Mag << std::endl;
50
+
51
+    Mag->Delete();
52
+    exit(EXIT_SUCCESS);
28 53
 }
29 54
 

+ 15
- 16
examples/VTKEdgeGsphere.cpp ファイルの表示

@@ -81,8 +81,13 @@ int main(int argc, char**argv) {
81 81
     vtkDoubleArray* G = vtkDoubleArray::New();
82 82
         G->SetNumberOfComponents(1);
83 83
         G->SetNumberOfTuples(nn);
84
-        G->SetName("G");
85
-
84
+        //G->SetName("G");
85
+        if ( std::string(argv[3]) == "mag") {
86
+            G->SetName("kappa");
87
+        }
88
+        else {
89
+            G->SetName("G");
90
+        }
86 91
     vtkDoubleArray* phi = vtkDoubleArray::New();
87 92
         phi->SetNumberOfComponents(1);
88 93
         phi->SetNumberOfTuples(nn);
@@ -105,31 +110,25 @@ int main(int argc, char**argv) {
105 110
                 G->InsertTuple1( in, 0 );
106 111
             }
107 112
         }
108
-
109
-        else if ( std::string(argv[3]) == "magnet") {
113
+        if ( std::string(argv[3]) == "magnet") {
110 114
             if ( raddist > R - eps && raddist < R + eps ) {
111 115
                 // \rho = \nabla \cdot \mathbf{M}
112
-                //
113
-                if ( point[2] < -eps ) {
114
-                    G->InsertTuple1( in,   1 );
115
-                } else if (point[2] > eps) {
116
-                    G->InsertTuple1( in,  -1 );
117
-                } else {
118
-                    G->InsertTuple1( in, 0 );
119
-                }
120
-                //
121
-                // Above is inaccurate and unstable
122
-
123 116
                 // Use divergence theorm --> \mahtbf{M} \cdot \hat{n}
124 117
                 Eigen::Vector3d n;
125 118
                 n << point[0],point[1],point[2];
126 119
                 n.array() /= raddist;
127
-                //double sigma = n.dot(M);
128 120
                 G->InsertTuple1(in, n.dot(M) );
129 121
             } else {
130 122
                 G->InsertTuple1( in, 0 );
131 123
             }
132 124
         }
125
+        if ( std::string(argv[3]) == "mag") {
126
+            if ( raddist < R + eps) {
127
+                G->InsertTuple1( in, 1 );
128
+            } else {
129
+                G->InsertTuple1( in, 0 );
130
+            }
131
+        }
133 132
 
134 133
         // Insert analytic phi part
135 134
         /* magnetics problem p. 198 Jackson */

+ 20
- 4
include/FEM4EllipticPDE.h ファイルの表示

@@ -49,6 +49,8 @@
49 49
 #include "vtkDataSetSurfaceFilter.h"
50 50
 #include "vtkCellArray.h"
51 51
 #include "vtkCellData.h"
52
+#include <vtkXMLUnstructuredGridReader.h>
53
+#include <vtkUnstructuredGrid.h>
52 54
 
53 55
 #include <Eigen/IterativeLinearSolvers>
54 56
 #include <Eigen/SparseLU>
@@ -131,9 +133,23 @@ namespace Lemma {
131 133
              */
132 134
             void SetGFunction( Real (*pFcn3)(const Real&, const Real&, const Real&) );
133 135
 
136
+            /* Sets the vtkDataSet that defines the calculation grid.
137
+             */
138
+            //void SetGrid(vtkDataSet* Grid);
139
+
134 140
             /** Sets the vtkDataSet that defines the calculation grid.
135 141
              */
136
-            void SetGrid(vtkDataSet* Grid);
142
+            void SetGrid(vtkUnstructuredGrid* Grid);
143
+
144
+            /**
145
+             *  Read grid in from VTK file
146
+             */
147
+            void SetVTUGridFile( std::string& vtkGridFile );
148
+
149
+            /**
150
+             *  Read grid in from VTK file
151
+             */
152
+            void SetVTUGridFile( char* vtkGridFile );
137 153
 
138 154
             /** Sets up a DC problem with a survey
139 155
              *  @param[in] ij is the injection index
@@ -147,8 +163,8 @@ namespace Lemma {
147 163
             /** Performs solution */
148 164
             void Solve(const std::string& fname);
149 165
 
150
-            /** Performs solution */
151
-            void SolveOLD2(const std::string& fname);
166
+            /* Performs solution */
167
+            //void SolveOLD2(const std::string& fname);
152 168
 
153 169
             // ====================  ACCESS        =======================
154 170
 
@@ -289,7 +305,7 @@ namespace Lemma {
289 305
             vtkSmartPointer<vtkImplicitFunction>    vtkG;
290 306
 
291 307
             /** Any type of vtkDataSet may be used as a calculation Grid */
292
-            vtkSmartPointer<vtkDataSet>             vtkGrid;
308
+            vtkSmartPointer<vtkUnstructuredGrid>             vtkGrid;
293 309
 
294 310
             /** Function pointer to function describing g */
295 311
             Real (*gFcn3)(const Real&, const Real&, const Real&);

+ 32
- 1
include/LinearMag.h ファイルの表示

@@ -20,7 +20,8 @@
20 20
 #ifndef  LINEARMAG_INC
21 21
 #define  LINEARMAG_INC
22 22
 
23
-#include	"FEM4EllipticPDE.h"
23
+#include  <vtkCellIterator.h>
24
+#include  "FEM4EllipticPDE.h"
24 25
 
25 26
 namespace Lemma {
26 27
 
@@ -78,6 +79,28 @@ namespace Lemma {
78 79
 
79 80
         // ====================  ACCESS        =======================
80 81
 
82
+        /**
83
+         *  @param[in] B0 is the incident magnetic (-induction) field
84
+         *  @param[in] U is a MAGUNITS enum specifying the units of measurement
85
+         */
86
+        void SetInducingMagFieldVector( const Vector3r& B0, const MAGUNITS& U );
87
+
88
+        /**
89
+         *  @param[in] intensity is the incident magnetic (-induction) field intensity
90
+         *  @param[in] inc is the incident magnetic (-induction) field inclination in degrees
91
+         *  @param[in] dec is the incident magnetic (-induction) field declination in degrees
92
+         *  @param[in] U is a MAGUNITS enum specifying the units of intensity
93
+         */
94
+        void SetInducingMagField( const Real& intensity, const Real& inclination,
95
+                const Real& declination, const MAGUNITS& U );
96
+
97
+
98
+        /**
99
+         *  Calculates the right hand side of the equation
100
+         *   \f$ \nabla \cdot \kappa \mathbf{H}_0 \f$
101
+         */
102
+        void CalculateRHS( const std::string& susName );
103
+
81 104
         // ====================  INQUIRY       =======================
82 105
 
83 106
         protected:
@@ -105,6 +128,14 @@ namespace Lemma {
105 128
 
106 129
         // ====================  DATA MEMBERS  =========================
107 130
 
131
+        Vector3r    B0;
132
+
133
+
134
+        /**
135
+         *   Used internally to scale mag units into Tesla
136
+         */
137
+        void ScaleB0 ( const MAGUNITS& U);
138
+
108 139
     }; // -----  end of class  LinearMag  -----
109 140
 
110 141
     /*! @} */ // End of group

+ 39
- 5
src/FEM4EllipticPDE.cpp ファイルの表示

@@ -132,10 +132,45 @@ namespace Lemma {
132 132
         gFcn3 = gFcn;
133 133
     }
134 134
 
135
-    void FEM4EllipticPDE::SetGrid(vtkDataSet* grid) {
135
+    //void FEM4EllipticPDE::SetGrid(vtkDataSet* grid) {
136
+    //    vtkGrid = grid;
137
+    //}
138
+
139
+    void FEM4EllipticPDE::SetGrid(vtkUnstructuredGrid* grid) {
136 140
         vtkGrid = grid;
137 141
     }
138 142
 
143
+    //--------------------------------------------------------------------------------------
144
+    //       Class:  FEM4EllipticPDE
145
+    //      Method:  SetVTUGridFile
146
+    //--------------------------------------------------------------------------------------
147
+    void FEM4EllipticPDE::SetVTUGridFile ( std::string& fname  ) {
148
+        vtkXMLUnstructuredGridReader* MeshReader = vtkXMLUnstructuredGridReader::New();
149
+        MeshReader->SetFileName(fname.c_str());
150
+        MeshReader->Update();
151
+        //vtkGrid->DeepCopy( MeshReader->GetOutput() );
152
+        vtkGrid->ShallowCopy( MeshReader->GetOutput() );
153
+        MeshReader->Delete();
154
+        return ;
155
+    }		// -----  end of method FEM4EllipticPDE::SetVTKGridFile  -----
156
+
157
+    //--------------------------------------------------------------------------------------
158
+    //       Class:  FEM4EllipticPDE
159
+    //      Method:  SetVTUGridFile
160
+    //--------------------------------------------------------------------------------------
161
+    void FEM4EllipticPDE::SetVTUGridFile ( char* fname  ) {
162
+        std::cout  << "Loading VTK .vtu file " << fname << std::endl;
163
+        vtkXMLUnstructuredGridReader* MeshReader = vtkXMLUnstructuredGridReader::New();
164
+        MeshReader->SetFileName(fname);
165
+        MeshReader->Update();
166
+        //vtkGrid->DeepCopy( MeshReader->GetOutput() );
167
+        vtkGrid = MeshReader->GetOutput();
168
+        //vtkGrid->ShallowCopy( MeshReader->GetOutput() );
169
+        MeshReader->Delete();
170
+        return ;
171
+    }		// -----  end of method FEM4EllipticPDE::SetVTKGridFile  -----
172
+
173
+
139 174
     vtkSmartPointer<vtkIdList> FEM4EllipticPDE::GetConnectedPoints(const int& id0) {
140 175
         vtkSmartPointer<vtkIdList> pointIds = vtkSmartPointer<vtkIdList>::New();
141 176
         vtkSmartPointer<vtkIdList> cellList = vtkSmartPointer<vtkIdList>::New();
@@ -549,10 +584,7 @@ namespace Lemma {
549 584
             ID[0] ID[2] ID[3]
550 585
             ID[1] ID[2] ID[3]
551 586
             */
552
-            //Real i4pi = .99738684646226885559*.961*PI/6.;//(4.*PI);// * V/4.;
553
-            //Real i4pi = .99738684646226885559*.961*PI/6.;//(4.*PI);// * V/4.;
554
-            //Real i4pi =  0.9584887594502403*PI/6.;//(4.*PI);// * V/4.;
555
-            Real i4pi = .5;// 0.1597132348845018*PI; // very nearly .5
587
+            Real i4pi = .5;
556 588
             /* surfaces of tetrahedra */
557 589
             // Face 0, ID 0,1,2
558 590
             Eigen::Matrix<Real, 3, 3> CC = Eigen::Matrix<Real, 3, 3>::Ones() ;
@@ -602,6 +634,7 @@ namespace Lemma {
602 634
         }
603 635
     }
604 636
 
637
+    #if 0
605 638
     void FEM4EllipticPDE::SolveOLD2(const std::string& fname) {
606 639
 
607 640
         Real r0[3];
@@ -888,6 +921,7 @@ namespace Lemma {
888 921
         uArray->Delete();
889 922
 
890 923
     }
924
+    #endif
891 925
 
892 926
     // Uses simpon's rule to perform a definite integral of a
893 927
     // function (passed as a pointer). The integration occurs from

+ 108
- 0
src/LinearMag.cpp ファイルの表示

@@ -104,6 +104,7 @@ YAML::Node  LinearMag::Serialize (  ) const {
104 104
     YAML::Node node = FEM4EllipticPDE::Serialize();;
105 105
     node.SetTag( this->Name );
106 106
     // FILL IN CLASS SPECIFICS HERE
107
+    node["B0"] = B0;
107 108
     return node;
108 109
 }		// -----  end of method LinearMag::Serialize  -----
109 110
 
@@ -120,4 +121,111 @@ LinearMag* LinearMag::DeSerialize ( const YAML::Node& node  ) {
120 121
 }		// -----  end of method LinearMag::DeSerialize  -----
121 122
 #endif
122 123
 
124
+
125
+
126
+//--------------------------------------------------------------------------------------
127
+//       Class:  LinearMag
128
+//      Method:  SetInducingMagField
129
+//--------------------------------------------------------------------------------------
130
+void LinearMag::SetInducingMagField ( const Real& intensity, const Real& inc,
131
+                const Real& dec, const MAGUNITS& U ) {
132
+
133
+    B0(0) = intensity * std::cos(inc) * std::cos(dec); // northing
134
+    B0(1) = intensity * std::cos(inc) * std::sin(dec); // easting
135
+    B0(2) = intensity * std::sin(inc);                 // z
136
+    ScaleB0(U);
137
+    return ;
138
+}		// -----  end of method LinearMag::SetInducingMagField  -----
139
+
140
+
141
+//--------------------------------------------------------------------------------------
142
+//       Class:  LinearMag
143
+//      Method:  SetInducingMagFieldVector
144
+//--------------------------------------------------------------------------------------
145
+void LinearMag::SetInducingMagFieldVector ( const Vector3r& BB0, const MAGUNITS& U  ) {
146
+    B0 = BB0;
147
+    ScaleB0(U);
148
+    return ;
149
+}		// -----  end of method LinearMag::SetInducingMagFieldVector  -----
150
+
151
+
152
+//--------------------------------------------------------------------------------------
153
+//       Class:  LinearMag
154
+//      Method:  ScaleB0
155
+//--------------------------------------------------------------------------------------
156
+void LinearMag::ScaleB0 ( const MAGUNITS& U ) {
157
+    switch ( U ) {
158
+        case TESLA:
159
+            break;
160
+        case NANOTESLA:
161
+            B0 *= 1e-9;
162
+            break;
163
+        case GAUSS:
164
+            B0 *= 1e-4;
165
+            break;
166
+    }
167
+    return ;
168
+}		// -----  end of method LinearMag::ScaleB0  -----
169
+
170
+
171
+//--------------------------------------------------------------------------------------
172
+//       Class:  LinearMag
173
+//      Method:  CalculateRHS
174
+//--------------------------------------------------------------------------------------
175
+void LinearMag::CalculateRHS ( const std::string& susName ) {
176
+    vtkDoubleArray* G = vtkDoubleArray::New();
177
+    G->SetNumberOfComponents(1);
178
+    G->SetNumberOfTuples( vtkGrid->GetNumberOfPoints() );
179
+    G->SetName("G");
180
+
181
+    // Iterate over all the points or all of the cells?
182
+    for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
183
+
184
+        Real cellSus = vtkGrid->GetCellData()->GetScalars(susName.c_str())->GetTuple(ic)[0];
185
+
186
+        Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
187
+        for (int ii=0; ii<4; ++ii) {
188
+            double* pts =  vtkGrid->GetCell(ic)->GetPoints()->GetPoint(ii);
189
+            C(ii, 0) = 1;
190
+            C(ii, 1) =  pts[0];
191
+            C(ii, 2) =  pts[1];
192
+            C(ii, 3) =  pts[2];
193
+        }
194
+
195
+        /* The indices */
196
+        vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
197
+        int ID[4];
198
+            ID[0] = Ids->GetId(0);
199
+            ID[1] = Ids->GetId(1);
200
+            ID[2] = Ids->GetId(2);
201
+            ID[3] = Ids->GetId(3);
202
+
203
+        /* the 4 faces of the tetrahedra
204
+            ID[0] ID[1] ID[2]
205
+            ID[0] ID[1] ID[3]
206
+            ID[0] ID[2] ID[3]
207
+            ID[1] ID[2] ID[3]
208
+        */
209
+        // Face 0, ID 0,1,2
210
+        /*
211
+        Eigen::Matrix<Real, 3, 2> CC = Eigen::Matrix<Real, 3, 2>::Ones() ;
212
+        {
213
+            CC.col(1) = C.row(0).tail<3>() - C.row(1).tail<3>();
214
+            CC.col(2) = C.row(0).tail<3>() - C.row(2).tail<3>();
215
+            Vector3r nhat = CC.col(1).cross(CC.col(2));
216
+            nhat.array() /= nhat.norm();
217
+            Real flux = cellSus*nhat.dot(B0);
218
+            g(ID[0]) += flux;
219
+            g(ID[1]) += flux;
220
+            g(ID[2]) += flux;
221
+                    //  vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])*TA/3. * i4pi ;
222
+        }
223
+        */
224
+    }
225
+
226
+    vtkGrid->GetPointData()->AddArray( G );
227
+    return ;
228
+}		// -----  end of method LinearMag::CalculateRHS  -----
229
+
230
+
123 231
 }		// -----  end of Lemma  name  -----

読み込み中…
キャンセル
保存