Trevor Irons 1 month ago
parent
commit
0b7f2462f4

+ 46
- 0
.github/workflows/cmake.yml View File

@@ -0,0 +1,46 @@
1
+name: CMake
2
+
3
+on: [push]
4
+
5
+env:
6
+  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
7
+  BUILD_TYPE: Release
8
+
9
+jobs:
10
+  build:
11
+    # The CMake configure and build commands are platform agnostic and should work equally
12
+    # well on Windows or Mac.  You can convert this to a matrix build if you need
13
+    # cross-platform coverage.
14
+    # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
15
+    runs-on: ubuntu-latest
16
+
17
+    steps:
18
+    - uses: actions/checkout@v2
19
+
20
+    - name: Create Build Environment
21
+      # Some projects don't allow in-source building, so create a separate build directory
22
+      # We'll use this as our working directory for all subsequent commands
23
+      run: cmake -E make_directory ${{runner.workspace}}/build
24
+
25
+    - name: Configure CMake
26
+      # Use a bash shell so we can use the same syntax for environment variable
27
+      # access regardless of the host operating system
28
+      shell: bash
29
+      working-directory: ${{runner.workspace}}/build
30
+      # Note the current convention is to use the -S and -B options here to specify source 
31
+      # and build directories, but this is only available with CMake 3.13 and higher.  
32
+      # The CMake binaries on the Github Actions machines are (as of this writing) 3.12
33
+      run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
34
+
35
+    - name: Build
36
+      working-directory: ${{runner.workspace}}/build
37
+      shell: bash
38
+      # Execute the build.  You can specify a specific target with "--target <NAME>"
39
+      run: cmake --build . --config $BUILD_TYPE
40
+
41
+    - name: Test
42
+      working-directory: ${{runner.workspace}}/build
43
+      shell: bash
44
+      # Execute tests defined by the CMake configuration.  
45
+      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
46
+      run: ctest -C $BUILD_TYPE

+ 1
- 1
CMake/FindUmfpack.cmake View File

@@ -47,7 +47,7 @@ if(UMFPACK_LIBRARIES)
47 47
 endif(UMFPACK_LIBRARIES)
48 48
 
49 49
 include(FindPackageHandleStandardArgs)
50
-find_package_handle_standard_args(UMFPACK DEFAULT_MSG
50
+find_package_handle_standard_args(Umfpack DEFAULT_MSG
51 51
                                   UMFPACK_INCLUDES UMFPACK_LIBRARIES)
52 52
 
53 53
 mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY CHOLMOD_LIBRARY SUITESPARSE_LIBRARY)

+ 9
- 8
CMake/SuperBuild.cmake View File

@@ -8,7 +8,7 @@ else()
8 8
         ExternalProject_Add(EIGEN
9 9
 	    GIT_REPOSITORY "https://gitlab.com/libeigen/eigen.git"
10 10
         UPDATE_COMMAND "" 
11
-	    GIT_TAG "3.3.7" #"default"
11
+	    GIT_TAG "3.3.7" 
12 12
    	    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/eigen
13 13
    	    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
14 14
 		#CONFIGURE_COMMAND ""
@@ -29,7 +29,7 @@ else()
29 29
         PATCH_COMMAND ""
30 30
         PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/yaml-cpp
31 31
         CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} 
32
-                   -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
32
+                   -DYAML_BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} 
33 33
                    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 
34 34
     	           -DYAML_CPP_BUILD_TESTS=OFF
35 35
                    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
@@ -41,13 +41,13 @@ else()
41 41
     )
42 42
 endif()
43 43
 
44
-if ( LEMMA_VTK8_SUPPORT )
45
-    if ( NOT VTK_FOUND OR  VTK_VERSION VERSION_GREATER "8.2.0" )
44
+if ( LEMMA_VTK9_SUPPORT )
45
+    if ( NOT VTK_FOUND OR  VTK_VERSION VERSION_LESS "9.0.0" )
46 46
         message( STATUS "VTK > 8.20.0 was found! Version found: " ${VTK_VERSION}, ${VTK_USE_FILE} )
47 47
         message( STATUS "External build of VTK 8 has been added, this may take some time to build." )
48
-        ExternalProject_Add(VTK8
48
+        ExternalProject_Add(VTK9
49 49
         GIT_REPOSITORY "https://gitlab.kitware.com/vtk/vtk.git"
50
-        GIT_TAG  "v8.2.0"
50
+        GIT_TAG  "v9.0.1"
51 51
         PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/vtk8
52 52
         CMAKE_ARGS
53 53
             -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
@@ -78,10 +78,11 @@ if (LEMMA_PYTHON3_BINDINGS)
78 78
         message( STATUS "pybind11 was found" )
79 79
     else()
80 80
         message( STATUS "pybind11 was NOT found, please build or remove LEMMA_PYTHON3_BINDINGS" )
81
-	    find_package(PythonLibs 3.0 REQUIRED)
81
+        #find_package(Python COMPONENTS Interpreter Development REQUIRED)
82
+	#find_package(PythonLibs 3.0 REQUIRED)
82 83
         ExternalProject_Add(pybind11
83 84
 		    GIT_REPOSITORY "https://github.com/pybind/pybind11.git"
84
-		    GIT_TAG "v2.4.3" # "master" #"v2.4.3" #"master"
85
+		    GIT_TAG "v2.5.0" # "master" #"v2.4.3" #"master"
85 86
 		    UPDATE_COMMAND ""
86 87
 		    PATCH_COMMAND ""
87 88
     	    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11

+ 45
- 12
CMakeLists.txt View File

@@ -13,8 +13,8 @@ SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
13 13
 ####################################################################################################
14 14
 # Lemma versioning, set Major, minor, and patch here                                               #
15 15
 set(LEMMA_VERSION_MAJOR "0")                                                                       #
16
-set(LEMMA_VERSION_MINOR "3")                                                                       #
17
-set(LEMMA_VERSION_PATCH "3")                                                                       #
16
+set(LEMMA_VERSION_MINOR "4")                                                                       #
17
+set(LEMMA_VERSION_PATCH "0")                                                                       #
18 18
 set(LEMMA_VERSION "\"${LEMMA_VERSION_MAJOR}.${LEMMA_VERSION_MINOR}.${LEMMA_VERSION_PATCH}\"")      #
19 19
 set(LEMMA_VERSION_NOQUOTES "${LEMMA_VERSION_MAJOR}.${LEMMA_VERSION_MINOR}.${LEMMA_VERSION_PATCH}") #
20 20
 ####################################################################################################
@@ -47,6 +47,7 @@ option ( LEMMA_BUILD_EXAMPLES       "Compile example Lemma applications" OFF )
47 47
 option ( LEMMA_USE_OPENMP           "Use OpenMP in Lemma" OFF )
48 48
 option ( LEMMA_BUILD_DOCUMENTATION  "Build Doxygen man pages" OFF )
49 49
 option ( LEMMA_VTK8_SUPPORT         "VTK 8.x library for visualisation and grids" OFF )
50
+option ( LEMMA_VTK9_SUPPORT         "VTK 9.x library for visualisation and grids" OFF )
50 51
 option ( LEMMA_PYTHON3_BINDINGS     "Compile Python 3 bindings" OFF )
51 52
 
52 53
 # We end up using this for all builds, TODO remove this variable but follow same path
@@ -99,11 +100,32 @@ if (CMAKE_CROSSCOMPILING)
99 100
         QUIET
100 101
         ) 
101 102
     endif()
103
+    if (LEMMA_VTK9_SUPPORT)                                                            # Visualisation 
104
+        find_package (VTK  9.0.1      
105
+        COMPONENTS 
106
+        CommonCore 
107
+        RenderingCore 
108
+        FiltersCore 
109
+        FiltersSources 
110
+        CommonDataModel 
111
+        FiltersHyperTree 
112
+        IOXML 
113
+        IOImage 
114
+        IOLegacy 
115
+        IOGeometry 
116
+        InteractionStyle 
117
+        RenderingAnnotation 
118
+        FiltersHybrid 
119
+        FiltersModeling 
120
+        RenderingVolumeOpenGL2
121
+        QUIET
122
+        ) 
123
+    endif()
102 124
 else()
103 125
     find_package (Eigen3   3.3 QUIET )  # Matrix/Vector & Math
104 126
     find_package (yaml-cpp 0.6 QUIET )  # Serialisation of classes 
105
-    if (LEMMA_VTK8_SUPPORT)
106
-        find_package (VTK  8.2.0 COMPONENTS
127
+    if (LEMMA_VTK9_SUPPORT)
128
+        find_package (VTK  9.0.1 COMPONENTS
107 129
         vtkCommonCore 
108 130
         vtkRenderingCore 
109 131
         vtkFiltersCore 
@@ -125,14 +147,19 @@ endif()
125 147
 
126 148
 INCLUDE_DIRECTORIES(${YAML_CPP_INCLUDE_DIR})
127 149
 
128
-if (VTK_VERSION VERSION_GREATER "8.2.0")
129
-    message( STATUS "${VTK_VERSION} is compatible: ${VTK_VERSION_COMPATIBLE} exact? ${VTK_VERSION_EXACT}" )
130
-    set (VTK_FOUND False) 
131
-endif()
150
+#if (VTK_VERSION VERSION_GREATER "8.2.0")
151
+#    message( STATUS "${VTK_VERSION} is compatible: ${VTK_VERSION_COMPATIBLE} exact? ${VTK_VERSION_EXACT}" )
152
+#    set (VTK_FOUND False) 
153
+#endif()
132 154
 
133 155
 if (VTK_FOUND)
134 156
     set(volumeRenderer volumerenderer.cxx)
135 157
 	add_definitions(-DLEMMAUSEVTK) 
158
+	if (LEMMA_VTK8_SUPPORT)
159
+    add_definitions(-DLEMMA_VTK8_SUPPORT)
160
+    else (LEMMA_VTK9_SUPPORT) 
161
+    add_definitions(-DLEMMA_VTK9_SUPPORT)
162
+    endif()
136 163
 endif()
137 164
 
138 165
 if (LEMMA_BUILD_DOCUMENTATION)
@@ -160,7 +187,7 @@ message ( STATUS "VTK Found? " ${VTK_FOUND} )
160 187
 if ( NOT Eigen3_FOUND OR 
161 188
      NOT yaml-cpp_FOUND OR 
162 189
      (LEMMA_PYTHON3_BINDINGS AND NOT pybind11_FOUND) OR 
163
-     (LEMMA_VTK8_SUPPORT AND NOT VTK_FOUND) OR
190
+     (LEMMA_VTK9_SUPPORT AND NOT VTK_FOUND) OR
164 191
      (LEMMA_ENABLE_TESTING AND NOT CxxTest_FOUND) )
165 192
     message ( STATUS "Missing hard dependencies have been found, these will be downloaded any compiled." )
166 193
     message ( STATUS "This necessitates a two step build." )
@@ -243,6 +270,8 @@ if (LEMMA_USE_BOOST)
243 270
 		if(HAVE_BOOST_SPECIAL_FUNCTIONS)
244 271
 			add_definitions(-DHAVE_BOOST_SPECIAL_FUNCTIONS)
245 272
 		endif()
273
+    else()
274
+        message(FATAL_ERROR "Boost was not found, but was requested in CMake.")
246 275
 	endif()
247 276
 endif()
248 277
 
@@ -255,6 +284,9 @@ if (LEMMA_PYTHON3_BINDINGS)
255 284
     #include_directories(${PYTHON_INCLUDE_DIRS})
256 285
     #include_directories(${Boost_INCLUDE_DIRS})
257 286
     install ( FILES python/setup.py DESTINATION ${CMAKE_INSTALL_PREFIX}/pyLemma/ ) 
287
+    install ( FILES python/long.md DESTINATION ${CMAKE_INSTALL_PREFIX}/pyLemma/ ) 
288
+    install ( FILES python/publish.sh DESTINATION ${CMAKE_INSTALL_PREFIX}/pyLemma/ ) 
289
+    install ( FILES README.md DESTINATION ${CMAKE_INSTALL_PREFIX}/pyLemma/ ) 
258 290
     install ( DIRECTORY python/pyLemma DESTINATION ${CMAKE_INSTALL_PREFIX}/pyLemma/ ) 
259 291
 endif()
260 292
 
@@ -359,9 +391,10 @@ endif()
359 391
 ########################################################################
360 392
 # add a target to generate API documentation with Doxyfile.in 
361 393
 # ALL make documentation build by default if possible
362
-find_package(Doxygen)
394
+if (LEMMA_BUILD_DOCUMENTATION)
395
+    find_package(Doxygen)
363 396
 	if(DOXYGEN_FOUND)
364
-	if (LEMMA_BUILD_DOCUMENTATION)
397
+    message( STATUS "LEMMA_BUILD_DOCUMENTATION must be positive" )
365 398
 # Custom header and footer option, enable in Doxygen 
366 399
 #	file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Documentation/header.html
367 400
 #        DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Documentation/header.html
@@ -376,7 +409,7 @@ find_package(Doxygen)
376 409
 			WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
377 410
 			COMMENT "Generating API documentation with Doxygen" VERBATIM
378 411
 		)
379
-	endif (LEMMA_BUILD_DOCUMENTATION)
380 412
 	endif(DOXYGEN_FOUND)
413
+endif (LEMMA_BUILD_DOCUMENTATION)
381 414
 
382 415
 # vim: set tabstop=4 shiftwidth=4 expandtab: 

+ 5
- 0
Modules/FDEM1D/CMakeLists.txt View File

@@ -10,6 +10,11 @@ set_target_properties(fdem1d PROPERTIES
10 10
     CXX_STANDARD_REQUIRED ON
11 11
 )
12 12
 
13
+if ( LEMMA_VTK9_SUPPORT ) 
14
+	target_link_libraries(fdem1d ${visibility}VTK::RenderingCore VTK::CommonDataModel)
15
+	vtk_module_autoinit(TARGETS fdem1d MODULES VTK::RenderingCore)
16
+endif()
17
+
13 18
 # Linking
14 19
 target_link_libraries(fdem1d "lemmacore")
15 20
 target_link_libraries(fdem1d ${YAML_CPP_LIBRARIES}) 

+ 3
- 1
Modules/FDEM1D/examples/EMDipEarth1D.cpp View File

@@ -68,7 +68,7 @@ int main() {
68 68
 		Real oy =    20.;
69 69
 		Real depth = 18.10;
70 70
 		Real dz = 2.6;
71
-		int  nz = 1;
71
+		int  nz = 10000;
72 72
 
73 73
 		receivers->SetNumberOfPoints(nz);
74 74
 		int ir = 0;
@@ -83,6 +83,8 @@ int main() {
83 83
 
84 84
     auto EmEarth = EMEarth1D::NewSP();
85 85
         //EmEarth->SetHankelTransformMethod(DIGITALFILTERING);
86
+        EmEarth->SetHankelTransformMethod(CHAVE);
87
+
86 88
         EmEarth->SetFieldsToCalculate(BOTH); // Fortran needs this
87 89
 		EmEarth->AttachDipoleSource(dipole);
88 90
 		EmEarth->AttachLayeredEarthEM(earth);

+ 5
- 5
Modules/FDEM1D/examples/inp/config.inp View File

@@ -1,13 +1,13 @@
1 1
 // Hankel Transform type uncomment desired
2
-FHTKEY51       // Key's   51 point FHT
3
-//FHTKEY101      // Key's  101 point FHT
4
-//FHTKEY201      // Key's  201 point FHT
2
+CHAVE       // Key's   51 point FHT
3
+//CHAVE      // Key's  101 point FHT
4
+//CHAVE      // Key's  201 point FHT
5 5
 //FHTKONG61      // Kong's  61 point FHT
6 6
 //FHTKONG121     // Kong's 121 point FHT
7 7
 //FHTKONG241	 // Kong's 241 point FHT
8
-//ANDERSON801    // Anderson's 801 Point FHT, with lagged convolution
8
+//CHAVE    // Anderson's 801 Point FHT, with lagged convolution
9 9
 //CHAVE          // Chave's Gaussian Quadrature
10
-//QWEKEY         // Key's Gaussian Qwuadrature with extraploation
10
+//CHAVE         // Key's Gaussian Qwuadrature with extraploation
11 11
 //IRONS
12 12
 .1               // minimum dipole ratio
13 13
 1e-5             // minumum dipole moment

+ 1
- 1
Modules/FDEM1D/examples/plottimings.py View File

@@ -56,7 +56,7 @@ for compiler in BENCH:
56 56
 
57 57
 plt.gca().set_yscale('log')    
58 58
 plt.gca().set_title( str(compiler) + " " + str(BENCH[compiler]["version"]) ) 
59
-plt.suptitle( cpuinfo.get_cpu_info()['brand'] ) 
59
+#plt.suptitle( cpuinfo.get_cpu_info()['brand'] ) 
60 60
 
61 61
 
62 62
 

+ 1
- 1
Modules/FDEM1D/include/KernelEM1DSpec.h View File

@@ -1338,7 +1338,7 @@ namespace Lemma {
1338 1338
         static bool called = false;
1339 1339
         if (!called) {
1340 1340
             std::cout << "WARNING\n";
1341
-            std::cout << "Unspecialised PotentialBelowSourceLayer <" << Mode << " " << Ikernel << " "
1341
+            std::cout << "Unspecialised RelPotentialBelowSourceLayer <" << Mode << " " << Ikernel << " "
1342 1342
                   << Isource << " " << Irecv << ">...this function will be slow\n\n";
1343 1343
             called = true;
1344 1344
         }

+ 6
- 0
Modules/FDEM1D/include/PolygonalWireAntenna.h View File

@@ -118,6 +118,12 @@ namespace Lemma {
118 118
             /// Maximum dipole moment allowed
119 119
             Real maxDipoleMoment;
120 120
 
121
+            /// Adds grounding point to non-closed wire loop
122
+            void AddGroundingPoint(
123
+                            const Vector3r &cp,
124
+                            const Vector3r &dir,
125
+                            std::vector< std::shared_ptr<DipoleSource> > &Dipoles );
126
+
121 127
             /// appends
122 128
             void PushXYZDipoles( const Vector3r &step, const Vector3r &cp,
123 129
                             const Vector3r &dir,

+ 2
- 2
Modules/FDEM1D/python/pyFDEM1D.cpp View File

@@ -250,14 +250,14 @@ PYBIND11_MODULE(FDEM1D, m) {
250 250
         // modifiers
251 251
         .def("AttachWireAntenna", &Lemma::EMEarth1D::AttachWireAntenna,
252 252
             "Sets the wire antenna to use for calculations")
253
-        .def("AttachDipoleSOurce", &Lemma::EMEarth1D::AttachDipoleSource,
253
+        .def("AttachDipoleSource", &Lemma::EMEarth1D::AttachDipoleSource,
254 254
             "Sets a DipoleSource to use for calculations")
255 255
         .def("AttachFieldPoints", &Lemma::EMEarth1D::AttachFieldPoints,
256 256
             "Sets the FieldPoints to use for calculations")
257 257
         .def("AttachLayeredEarthEM", &Lemma::EMEarth1D::AttachLayeredEarthEM,
258 258
             "Sets the LayeredEarthEM to use for calculations")
259 259
 
260
-        .def("SetFieldToCalculate", &Lemma::EMEarth1D::SetFieldsToCalculate,
260
+        .def("SetFieldsToCalculate", &Lemma::EMEarth1D::SetFieldsToCalculate,
261 261
             "Sets which fields to calculate")
262 262
         .def("SetHankelTransformMethod", &Lemma::EMEarth1D::SetHankelTransformMethod,
263 263
             "Sets which Hankel transform to use")

+ 301
- 7
Modules/FDEM1D/src/DipoleSource.cpp View File

@@ -183,6 +183,9 @@ namespace Lemma {
183 183
             case (UNGROUNDEDELECTRICDIPOLE):
184 184
                 this->Type = stype;
185 185
                 break;
186
+            case (GROUNDINGPOINT):
187
+                this->Type = stype;
188
+                break;
186 189
             case (MAGNETICDIPOLE):
187 190
                 this->Type = stype;
188 191
                 break;
@@ -485,6 +488,172 @@ namespace Lemma {
485 488
                     }
486 489
                 break;
487 490
 
491
+            case (GROUNDINGPOINT):
492
+
493
+                if (std::abs(Pol[2]) > 0) { // z dipole
494
+
495
+                    switch(FieldsToCalculate) {
496
+
497
+                        case E:
498
+                            if (lays == 0 && layr == 0) {
499
+                                ik[10] = KernelManager->AddKernel<TM, 10, INAIR, INAIR>( );
500
+                                ik[11] = KernelManager->AddKernel<TM, 11, INAIR, INAIR>( );
501
+                            } else if (lays == 0 && layr > 0) {
502
+                                ik[10] = KernelManager->AddKernel<TM, 10, INAIR, INGROUND>( );
503
+                                ik[11] = KernelManager->AddKernel<TM, 11, INAIR, INGROUND>( );
504
+                            } else if (lays > 0 && layr == 0) {
505
+                                ik[10] = KernelManager->AddKernel<TM, 10, INGROUND, INAIR>( );
506
+                                ik[11] = KernelManager->AddKernel<TM, 11, INGROUND, INAIR>( );
507
+                            } else {
508
+                                ik[10] = KernelManager->AddKernel<TM, 10, INGROUND, INGROUND>( );
509
+                                ik[11] = KernelManager->AddKernel<TM, 11, INGROUND, INGROUND>( );
510
+                            }
511
+                            break;
512
+
513
+                        case H:
514
+                            if (lays == 0 && layr == 0) {
515
+                                ik[12] = KernelManager->AddKernel<TM, 12, INAIR, INAIR>( );
516
+                            } else if (lays == 0 && layr > 0) {
517
+                                ik[12] = KernelManager->AddKernel<TM, 12, INAIR, INGROUND>( );
518
+                            } else if (lays > 0 && layr == 0) {
519
+                                ik[12] = KernelManager->AddKernel<TM, 12, INGROUND, INAIR>( );
520
+                            } else {
521
+                                ik[12] = KernelManager->AddKernel<TM, 12, INGROUND, INGROUND>( );
522
+                            }
523
+                            break;
524
+
525
+
526
+                        case BOTH:
527
+                            if ( lays == 0 && layr == 0) {
528
+                                ik[10] = KernelManager->AddKernel<TM, 10, INAIR, INAIR>( );
529
+                                ik[11] = KernelManager->AddKernel<TM, 11, INAIR, INAIR>( );
530
+                                ik[12] = KernelManager->AddKernel<TM, 12, INAIR, INAIR>( );
531
+                            } else if (lays == 0 && layr > 0) {
532
+                                ik[10] = KernelManager->AddKernel<TM, 10, INAIR, INGROUND>( );
533
+                                ik[11] = KernelManager->AddKernel<TM, 11, INAIR, INGROUND>( );
534
+                                ik[12] = KernelManager->AddKernel<TM, 12, INAIR, INGROUND>( );
535
+                            } else if (lays > 0 && layr == 0) {
536
+                                ik[10] = KernelManager->AddKernel<TM, 10, INGROUND, INAIR>( );
537
+                                ik[11] = KernelManager->AddKernel<TM, 11, INGROUND, INAIR>( );
538
+                                ik[12] = KernelManager->AddKernel<TM, 12, INGROUND, INAIR>( );
539
+                            } else {
540
+                                ik[10] = KernelManager->AddKernel<TM, 10, INGROUND, INGROUND>( );
541
+                                ik[11] = KernelManager->AddKernel<TM, 11, INGROUND, INGROUND>( );
542
+                                ik[12] = KernelManager->AddKernel<TM, 12, INGROUND, INGROUND>( );
543
+                            }
544
+                        }
545
+                }
546
+                if (std::abs(Pol[1]) > 0 || std::abs(Pol[0]) > 0) { // x or y grounded HED dipole
547
+
548
+                    switch(FieldsToCalculate) {
549
+
550
+                        case E:
551
+                            if ( lays == 0 && layr == 0) {
552
+                                ik[0] = KernelManager->AddKernel<TM, 0, INAIR, INAIR>( );
553
+                                ik[1] = KernelManager->AddKernel<TM, 1, INAIR, INAIR>( );
554
+                                ik[4] = KernelManager->AddKernel<TM, 4, INAIR, INAIR>( );
555
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INAIR, INAIR>( );
556
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INAIR, INAIR>( );
557
+                            } else if (lays == 0 && layr > 0) {
558
+                                ik[0] = KernelManager->AddKernel<TM, 0, INAIR, INGROUND>( );
559
+                                ik[1] = KernelManager->AddKernel<TM, 1, INAIR, INGROUND>( );
560
+                                ik[4] = KernelManager->AddKernel<TM, 4, INAIR, INGROUND>( );
561
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INAIR, INGROUND>( );
562
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INAIR, INGROUND>( );
563
+                            } else if (lays > 0 && layr == 0) {
564
+                                ik[0] = KernelManager->AddKernel<TM, 0, INGROUND, INAIR>( );
565
+                                ik[1] = KernelManager->AddKernel<TM, 1, INGROUND, INAIR>( );
566
+                                ik[4] = KernelManager->AddKernel<TM, 4, INGROUND, INAIR>( );
567
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INGROUND, INAIR>( );
568
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INGROUND, INAIR>( );
569
+                            } else {
570
+                                ik[0] = KernelManager->AddKernel<TM, 0, INGROUND, INGROUND>( );
571
+                                ik[1] = KernelManager->AddKernel<TM, 1, INGROUND, INGROUND>( );
572
+                                ik[4] = KernelManager->AddKernel<TM, 4, INGROUND, INGROUND>( );
573
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INGROUND, INGROUND>( );
574
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INGROUND, INGROUND>( );
575
+                            }
576
+                            break;
577
+
578
+                        case H:
579
+                            if (lays == 0 && layr == 0) {
580
+                                ik[5] = KernelManager->AddKernel<TM, 5, INAIR, INAIR>( );
581
+                                ik[6] = KernelManager->AddKernel<TM, 6, INAIR, INAIR>( );
582
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INAIR, INAIR>( );
583
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INAIR, INAIR>( );
584
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INAIR, INAIR>( );
585
+                            } else if (lays == 0 && layr > 0) {
586
+                                ik[5] = KernelManager->AddKernel<TM, 5, INAIR, INGROUND>( );
587
+                                ik[6] = KernelManager->AddKernel<TM, 6, INAIR, INGROUND>( );
588
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INAIR, INGROUND>( );
589
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INAIR, INGROUND>( );
590
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INAIR, INGROUND>( );
591
+                            } else if (lays > 0 && layr == 0) {
592
+                                ik[5] = KernelManager->AddKernel<TM, 5, INGROUND, INAIR>( );
593
+                                ik[6] = KernelManager->AddKernel<TM, 6, INGROUND, INAIR>( );
594
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INGROUND, INAIR>( );
595
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INGROUND, INAIR>( );
596
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INGROUND, INAIR>( );
597
+                            } else {
598
+                                ik[5] = KernelManager->AddKernel<TM, 5, INGROUND, INGROUND>( );
599
+                                ik[6] = KernelManager->AddKernel<TM, 6, INGROUND, INGROUND>( );
600
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INGROUND, INGROUND>( );
601
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INGROUND, INGROUND>( );
602
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INGROUND, INGROUND>( );
603
+                            }
604
+                            break;
605
+
606
+                        case BOTH:
607
+                            if (lays == 0 && layr == 0) {
608
+                                ik[0] = KernelManager->AddKernel<TM, 0, INAIR, INAIR>( );
609
+                                ik[1] = KernelManager->AddKernel<TM, 1, INAIR, INAIR>( );
610
+                                ik[4] = KernelManager->AddKernel<TM, 4, INAIR, INAIR>( );
611
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INAIR, INAIR>( );
612
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INAIR, INAIR>( );
613
+                                ik[5] = KernelManager->AddKernel<TM, 5, INAIR, INAIR>( );
614
+                                ik[6] = KernelManager->AddKernel<TM, 6, INAIR, INAIR>( );
615
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INAIR, INAIR>( );
616
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INAIR, INAIR>( );
617
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INAIR, INAIR>( );
618
+                            } else if (lays == 0 && layr > 0) {
619
+                                ik[0] = KernelManager->AddKernel<TM, 0, INAIR, INGROUND>( );
620
+                                ik[1] = KernelManager->AddKernel<TM, 1, INAIR, INGROUND>( );
621
+                                ik[4] = KernelManager->AddKernel<TM, 4, INAIR, INGROUND>( );
622
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INAIR, INGROUND>( );
623
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INAIR, INGROUND>( );
624
+                                ik[5] = KernelManager->AddKernel<TM, 5, INAIR, INGROUND>( );
625
+                                ik[6] = KernelManager->AddKernel<TM, 6, INAIR, INGROUND>( );
626
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INAIR, INGROUND>( );
627
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INAIR, INGROUND>( );
628
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INAIR, INGROUND>( );
629
+                            } else if (lays > 0 && layr == 0) {
630
+                                ik[0] = KernelManager->AddKernel<TM, 0, INGROUND, INAIR>( );
631
+                                ik[1] = KernelManager->AddKernel<TM, 1, INGROUND, INAIR>( );
632
+                                ik[4] = KernelManager->AddKernel<TM, 4, INGROUND, INAIR>( );
633
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INGROUND, INAIR>( );
634
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INGROUND, INAIR>( );
635
+                                ik[5] = KernelManager->AddKernel<TM, 5, INGROUND, INAIR>( );
636
+                                ik[6] = KernelManager->AddKernel<TM, 6, INGROUND, INAIR>( );
637
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INGROUND, INAIR>( );
638
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INGROUND, INAIR>( );
639
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INGROUND, INAIR>( );
640
+                            } else {
641
+                                ik[0] = KernelManager->AddKernel<TM, 0, INGROUND, INGROUND>( );
642
+                                ik[1] = KernelManager->AddKernel<TM, 1, INGROUND, INGROUND>( );
643
+                                ik[4] = KernelManager->AddKernel<TM, 4, INGROUND, INGROUND>( );
644
+                                //ik[2] = KernelManager->AddKernel<TE, 2, INGROUND, INGROUND>( );
645
+                                //ik[3] = KernelManager->AddKernel<TE, 3, INGROUND, INGROUND>( );
646
+                                ik[5] = KernelManager->AddKernel<TM, 5, INGROUND, INGROUND>( );
647
+                                ik[6] = KernelManager->AddKernel<TM, 6, INGROUND, INGROUND>( );
648
+                                //ik[7] = KernelManager->AddKernel<TE, 7, INGROUND, INGROUND>( );
649
+                                //ik[8] = KernelManager->AddKernel<TE, 8, INGROUND, INGROUND>( );
650
+                                //ik[9] = KernelManager->AddKernel<TE, 9, INGROUND, INGROUND>( );
651
+                            }
652
+                            break;
653
+                        }
654
+                    }
655
+                break;
656
+
488 657
             case (UNGROUNDEDELECTRICDIPOLE):
489 658
 
490 659
                 if (std::abs(Pol[2]) > 0) { // z dipole
@@ -786,8 +955,6 @@ namespace Lemma {
786 955
                 exit(EXIT_FAILURE);
787 956
 
788 957
         }
789
-
790
-
791 958
     }
792 959
 
793 960
     void DipoleSource::UpdateFields( const int& ifreq, HankelTransform* Hankel, const Real& wavef) {
@@ -874,6 +1041,7 @@ namespace Lemma {
874 1041
                                     Pol[0]*Moment*QPI*sp*f(9) );
875 1042
                             }
876 1043
                             break;
1044
+
877 1045
                         case BOTH:
878 1046
                             f(0) = Hankel->Zgauss(0, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[0])) / KernelManager->GetRAWKernel(ik[0])->GetYm();
879 1047
                             f(1) = Hankel->Zgauss(1, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[1])) / KernelManager->GetRAWKernel(ik[1])->GetYm();
@@ -913,6 +1081,128 @@ namespace Lemma {
913 1081
                 }
914 1082
                 break; // GROUNDEDELECTRICDIPOLE
915 1083
 
1084
+            case (GROUNDINGPOINT):
1085
+                if (std::abs(Pol[2]) > 0) { // z dipole
1086
+                    switch(FieldsToCalculate) {
1087
+                        case E:
1088
+                            f(10) = Hankel->Zgauss(10, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[10])) / KernelManager->GetRAWKernel(ik[10])->GetYm();
1089
+                            f(11) = Hankel->Zgauss(11, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[11])) / KernelManager->GetRAWKernel(ik[11])->GetYm();
1090
+                            this->Receivers->AppendEfield(ifreq, irec,
1091
+                                -Pol[2]*QPI*cp*f(10)*Moment,
1092
+                                -Pol[2]*QPI*sp*f(10)*Moment,
1093
+                                 Pol[2]*QPI*f(11)*Moment);
1094
+                            break;
1095
+
1096
+                        case H:
1097
+                            f(12) = Hankel->Zgauss(12, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[12]));
1098
+                            this->Receivers->AppendHfield(ifreq, irec,
1099
+                                -Pol[2]*QPI*sp*f(12)*Moment,
1100
+                                 Pol[2]*QPI*cp*f(12)*Moment,
1101
+                                 0. );
1102
+                            break;
1103
+
1104
+                        case BOTH:
1105
+                            f(10) = Hankel->Zgauss(10, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[10])) / KernelManager->GetRAWKernel(ik[10])->GetYm();
1106
+                            f(11) = Hankel->Zgauss(11, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[11])) / KernelManager->GetRAWKernel(ik[11])->GetYm();
1107
+                            this->Receivers->AppendEfield(ifreq, irec,
1108
+                                    -Pol[2]*QPI*cp*f(10)*Moment,
1109
+                                    -Pol[2]*QPI*sp*f(10)*Moment,
1110
+                                     Pol[2]*QPI*f(11)*Moment   );
1111
+
1112
+                            f(12) = Hankel->Zgauss(12, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[12]));
1113
+                            this->Receivers->AppendHfield(ifreq, irec,
1114
+                                    -Pol[2]*QPI*sp*f(12)*Moment,
1115
+                                     Pol[2]*QPI*cp*f(12)*Moment,
1116
+                                     0. );
1117
+                    } // Fields to calculate Z polarity Electric dipole
1118
+                }
1119
+                if (std::abs(Pol[1]) > 0 || std::abs(Pol[0]) > 0) { // x or y dipole
1120
+                    switch(FieldsToCalculate) {
1121
+                        case E:
1122
+                            f(2) = 0;//Hankel->Zgauss(2, TE, 0, rho, wavef, KernelManager->GetRAWKernel(ik[2])) * KernelManager->GetRAWKernel(ik[2])->GetZs();
1123
+                            f(3) = 0;//Hankel->Zgauss(3, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[3])) * KernelManager->GetRAWKernel(ik[3])->GetZs();
1124
+                            f(0) = Hankel->Zgauss(0, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[0])) / KernelManager->GetRAWKernel(ik[0])->GetYm();
1125
+                            f(1) = Hankel->Zgauss(1, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[1])) / KernelManager->GetRAWKernel(ik[1])->GetYm();
1126
+                            f(4) = Hankel->Zgauss(4, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[4])) / KernelManager->GetRAWKernel(ik[4])->GetYm();
1127
+                            if (std::abs(Pol[1]) > 0) {
1128
+                                this->Receivers->AppendEfield(ifreq, irec,
1129
+                                    0,0,0);
1130
+                                    //Pol[1]*QPI*Moment*scp*(f(0)+f(2)),
1131
+                                    //Pol[1]*QPI*Moment*((sps*f(0)+c2p*f(1)/rho)),
1132
+                                    //Pol[1]*QPI*Moment*(f(0)+f(2)),
1133
+                                    //Pol[1]*QPI*Moment*((f(0)+f(1)/rho)),
1134
+                                    //Pol[1]*QPI*sp*f(4)*Moment);
1135
+                                    // std dipole
1136
+                                    //Pol[1]*QPI*scp*((f(0)-(Real)(2.)*f(1)/rho)+(f(2)-(Real)(2.)*f(3)/rho))*Moment ,
1137
+                                    //Pol[1]*QPI*((sps*f(0)+c2p*f(1)/rho)-(cps*f(2)-c2p*f(3)/rho))*Moment,
1138
+                                    //Pol[1]*QPI*sp*f(4)*Moment);
1139
+                            }
1140
+                            if (std::abs(Pol[0]) > 0) {
1141
+                                this->Receivers->AppendEfield(ifreq, irec,
1142
+                                    Pol[0]*Moment*QPI*((cps*f(0)-c2p*f(1)/rho)),          //-(sps*f(2)+c2p*f(3)/rho)),
1143
+                                    Pol[0]*Moment*QPI*scp*((f(0)-(Real)(2.)*f(1)/rho)),   //+(f(2)-(Real)(2.)*f(3)/rho)),
1144
+                                    Pol[0]*Moment*QPI*cp*f(4) );
1145
+                            }
1146
+                            break;
1147
+                        case H:
1148
+                            f(5) = Hankel->Zgauss(5, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[5]));
1149
+                            f(6) = Hankel->Zgauss(6, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[6]));
1150
+                            f(7) = Hankel->Zgauss(7, TE, 0, rho, wavef, KernelManager->GetRAWKernel(ik[7]))*KernelManager->GetRAWKernel(ik[7])->GetZs()/KernelManager->GetRAWKernel(ik[7])->GetZm();
1151
+                            f(8) = Hankel->Zgauss(8, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[8]))*KernelManager->GetRAWKernel(ik[8])->GetZs()/KernelManager->GetRAWKernel(ik[8])->GetZm();
1152
+                            f(9) = Hankel->Zgauss(9, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[9]))*KernelManager->GetRAWKernel(ik[9])->GetZs()/KernelManager->GetRAWKernel(ik[9])->GetZm();
1153
+                            if (std::abs(Pol[1]) > 0) {
1154
+                                this->Receivers->AppendHfield(ifreq, irec,
1155
+                                        Pol[1]*QPI*(sps*f(5)+c2p*f(6)/rho-cps*f(7)+c2p*f(8)/rho)*Moment,
1156
+                                        Pol[1]*QPI*scp*(-f(5)+(Real)(2.)*f(6)/rho-f(7)+(Real)(2.)*f(8)/rho)*Moment,
1157
+                                        -Pol[1]*QPI*cp*f(9)*Moment );
1158
+                            }
1159
+                            if (std::abs(Pol[0]) > 0) {
1160
+                                this->Receivers->AppendHfield(ifreq, irec,
1161
+                                    Pol[0]*Moment*QPI*scp*(f(5)-(Real)(2.)*f(6)/rho+f(7)-(Real)(2.)*f(8)/rho),
1162
+                                    Pol[0]*Moment*QPI*(-cps*f(5)+c2p*f(6)/rho+sps*f(7)+c2p*f(8)/rho),
1163
+                                    Pol[0]*Moment*QPI*sp*f(9) );
1164
+                            }
1165
+                            break;
1166
+
1167
+                        case BOTH:
1168
+                            f(0) = Hankel->Zgauss(0, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[0])) / KernelManager->GetRAWKernel(ik[0])->GetYm();
1169
+                            f(1) = Hankel->Zgauss(1, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[1])) / KernelManager->GetRAWKernel(ik[1])->GetYm();
1170
+                            f(4) = Hankel->Zgauss(4, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[4])) / KernelManager->GetRAWKernel(ik[4])->GetYm();
1171
+                            f(2) = Hankel->Zgauss(2, TE, 0, rho, wavef, KernelManager->GetRAWKernel(ik[2])) * KernelManager->GetRAWKernel(ik[2])->GetZs();
1172
+                            f(3) = Hankel->Zgauss(3, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[3])) * KernelManager->GetRAWKernel(ik[3])->GetZs();
1173
+                            f(5) = Hankel->Zgauss(5, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[5]));
1174
+                            f(6) = Hankel->Zgauss(6, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[6]));
1175
+                            f(7) = Hankel->Zgauss(7, TE, 0, rho, wavef, KernelManager->GetRAWKernel(ik[7]))*KernelManager->GetRAWKernel(ik[7])->GetZs()/KernelManager->GetRAWKernel(ik[7])->GetZm();
1176
+                            f(8) = Hankel->Zgauss(8, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[8]))*KernelManager->GetRAWKernel(ik[8])->GetZs()/KernelManager->GetRAWKernel(ik[8])->GetZm();
1177
+                            f(9) = Hankel->Zgauss(9, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[9]))*KernelManager->GetRAWKernel(ik[9])->GetZs()/KernelManager->GetRAWKernel(ik[9])->GetZm();
1178
+
1179
+                            if (std::abs(Pol[1]) > 0) {
1180
+                                this->Receivers->AppendEfield(ifreq, irec,
1181
+                                        Pol[1]*QPI*scp*((f(0)-(Real)(2.)*f(1)/rho)+(f(2)-(Real)(2.)*f(3)/rho))*Moment ,
1182
+                                        Pol[1]*QPI*((sps*f(0)+c2p*f(1)/rho)-(cps*f(2)-c2p*f(3)/rho))*Moment,
1183
+                                        Pol[1]*QPI*sp*f(4)*Moment);
1184
+
1185
+                                this->Receivers->AppendHfield(ifreq, irec,
1186
+                                        Pol[1]*QPI*(sps*f(5)+c2p*f(6)/rho-cps*f(7)+c2p*f(8)/rho)*Moment,
1187
+                                        Pol[1]*QPI*scp*(-f(5)+(Real)(2.)*f(6)/rho-f(7)+(Real)(2.)*f(8)/rho)*Moment,
1188
+                                       -Pol[1]*QPI*cp*f(9)*Moment );
1189
+                            }
1190
+                            if (std::abs(Pol[0]) > 0) {
1191
+                                this->Receivers->AppendEfield(ifreq, irec,
1192
+                                    Pol[0]*Moment*QPI*((cps*f(0)-c2p*f(1)/rho)-(sps*f(2)+c2p*f(3)/rho)),
1193
+                                    Pol[0]*Moment*QPI*scp*((f(0)-(Real)(2.)*f(1)/rho)+(f(2)-(Real)(2.)*f(3)/rho)),
1194
+                                    Pol[0]*Moment*QPI*cp*f(4) );
1195
+
1196
+                                this->Receivers->AppendHfield(ifreq, irec,
1197
+                                    Pol[0]*Moment*QPI*scp*(f(5)-(Real)(2.)*f(6)/rho+f(7)-(Real)(2.)*f(8)/rho),
1198
+                                    Pol[0]*Moment*QPI*(-cps*f(5)+c2p*f(6)/rho+sps*f(7)+c2p*f(8)/rho),
1199
+                                    Pol[0]*Moment*QPI*sp*f(9) );
1200
+                            }
1201
+                            break;
1202
+                    }
1203
+                }
1204
+                break; // GROUNDINGPOINT
1205
+
916 1206
 
917 1207
             case UNGROUNDEDELECTRICDIPOLE:
918 1208
 
@@ -955,11 +1245,16 @@ namespace Lemma {
955 1245
 
956 1246
                     switch(FieldsToCalculate) {
957 1247
                         case E:
958
-                            f(0) = 0;
959
-                            f(1) = 0;
1248
+                            //f(0) = 0;
1249
+                            //f(1) = 0;
1250
+                            //f(2) = Hankel->Zgauss(2, TE, 0, rho, wavef, KernelManager->GetRAWKernel(ik[2])) * KernelManager->GetRAWKernel(ik[2])->GetZs();
1251
+                            //f(3) = Hankel->Zgauss(3, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[3])) * KernelManager->GetRAWKernel(ik[3])->GetZs();
1252
+                            //f(4) = 0;
960 1253
                             f(2) = Hankel->Zgauss(2, TE, 0, rho, wavef, KernelManager->GetRAWKernel(ik[2])) * KernelManager->GetRAWKernel(ik[2])->GetZs();
961 1254
                             f(3) = Hankel->Zgauss(3, TE, 1, rho, wavef, KernelManager->GetRAWKernel(ik[3])) * KernelManager->GetRAWKernel(ik[3])->GetZs();
962
-                            f(4) = 0;
1255
+                            f(0) = Hankel->Zgauss(0, TM, 0, rho, wavef, KernelManager->GetRAWKernel(ik[0])) / KernelManager->GetRAWKernel(ik[0])->GetYm();
1256
+                            f(1) = Hankel->Zgauss(1, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[1])) / KernelManager->GetRAWKernel(ik[1])->GetYm();
1257
+                            f(4) = Hankel->Zgauss(4, TM, 1, rho, wavef, KernelManager->GetRAWKernel(ik[4])) / KernelManager->GetRAWKernel(ik[4])->GetYm();
963 1258
                             if (std::abs(Pol[1]) > 0) {
964 1259
                                 this->Receivers->AppendEfield(ifreq, irec,
965 1260
                                     Pol[1]*QPI*scp*((f(0)-(Real)(2.)*f(1)/rho)+(f(2)-(Real)(2.)*f(3)/rho))*Moment,
@@ -984,7 +1279,7 @@ namespace Lemma {
984 1279
                                 this->Receivers->AppendHfield(ifreq, irec,
985 1280
                                         Pol[1]*QPI*(sps*f(5)+c2p*f(6)/rho-cps*f(7)+c2p*f(8)/rho)*Moment,
986 1281
                                         Pol[1]*QPI*scp*(-f(5)+(Real)(2.)*f(6)/rho-f(7)+(Real)(2.)*f(8)/rho)*Moment,
987
-                                        -Pol[1]*QPI*cp*f(9)*Moment );
1282
+                                       -Pol[1]*QPI*cp*f(9)*Moment );
988 1283
                             }
989 1284
                             if (std::abs(Pol[0]) > 0) {
990 1285
                                 this->Receivers->AppendHfield(ifreq, irec,
@@ -1036,7 +1331,6 @@ namespace Lemma {
1036 1331
                 break; // UNGROUNDEDELECTRICDIPOLE
1037 1332
 
1038 1333
             case MAGNETICDIPOLE:
1039
-
1040 1334
                 //Hankel->ComputeRelated(rho, KernelManager);
1041 1335
                 if (std::abs(Pol[2]) > 0) { // z dipole
1042 1336
                     switch(FieldsToCalculate) {

+ 31
- 10
Modules/FDEM1D/src/EMEarth1D.cpp View File

@@ -72,8 +72,7 @@ namespace Lemma {
72 72
     // TODO init large arrays here.
73 73
     EMEarth1D::EMEarth1D( const ctor_key& key ) : LemmaObject( key ),
74 74
             Dipole(nullptr), Earth(nullptr), Receivers(nullptr), Antenna(nullptr),
75
-            FieldsToCalculate(BOTH), HankelType(ANDERSON801), icalcinner(0), icalc(0)
76
-        {
75
+            FieldsToCalculate(BOTH), HankelType(ANDERSON801), icalcinner(0), icalc(0) {
77 76
     }
78 77
 
79 78
     EMEarth1D::~EMEarth1D() {
@@ -107,21 +106,36 @@ namespace Lemma {
107 106
     // ====================  ACCESS        ===================================
108 107
     void EMEarth1D::AttachDipoleSource( std::shared_ptr<DipoleSource> dipoleptr) {
109 108
         Dipole = dipoleptr;
110
-    }
111
-
112
-    void EMEarth1D::AttachLayeredEarthEM( std::shared_ptr<LayeredEarthEM> earthptr) {
113
-        Earth = earthptr;
109
+        if (Receivers != nullptr) {
110
+            // Check to make sure Receivers are set up for all calculations
111
+            switch(FieldsToCalculate) {
112
+                case E:
113
+                    if (Receivers->NumberOfBinsE != Dipole->GetNumberOfFrequencies())
114
+                        Receivers->SetNumberOfBinsE(Dipole->GetNumberOfFrequencies());
115
+                    break;
116
+                case H:
117
+                    if (Receivers->NumberOfBinsH != Dipole->GetNumberOfFrequencies())
118
+                        Receivers->SetNumberOfBinsH(Dipole->GetNumberOfFrequencies());
119
+                    break;
120
+                case BOTH:
121
+                    if (Receivers->NumberOfBinsH != Dipole->GetNumberOfFrequencies())
122
+                        Receivers->SetNumberOfBinsH(Dipole->GetNumberOfFrequencies());
123
+                    if (Receivers->NumberOfBinsE != Dipole->GetNumberOfFrequencies())
124
+                        Receivers->SetNumberOfBinsE(Dipole->GetNumberOfFrequencies());
125
+                    break;
126
+            }
127
+        }
114 128
     }
115 129
 
116 130
     void EMEarth1D::AttachFieldPoints( std::shared_ptr<FieldPoints> recptr) {
117 131
 
118 132
         Receivers = recptr;
119 133
         if (Receivers == nullptr) {
120
-            std::cout << "nullptr Receivers in emearth1d.cpp " << std::endl;
134
+            std::cerr << "nullptr Receivers in emearth1d.cpp " << std::endl;
121 135
             return;
122 136
         }
123 137
 
124
-        // This has an implicid need to first set a source before receivers, users
138
+        // This has an implicit need to first set a source before receivers, users
125 139
         // will not expect this. Fix
126 140
         if (Dipole != nullptr) {
127 141
             switch (FieldsToCalculate) {
@@ -152,6 +166,10 @@ namespace Lemma {
152 166
         }
153 167
     }
154 168
 
169
+    void EMEarth1D::AttachLayeredEarthEM( std::shared_ptr<LayeredEarthEM> earthptr) {
170
+        Earth = earthptr;
171
+    }
172
+
155 173
     void EMEarth1D::AttachWireAntenna(std::shared_ptr<WireAntenna> antennae) {
156 174
         this->Antenna = antennae;
157 175
     }
@@ -229,6 +247,7 @@ namespace Lemma {
229 247
             if ( Antenna->IsHorizontallyPlanar() && ( HankelType == ANDERSON801 || HankelType == FHTKEY201  || HankelType==FHTKEY101 ||
230 248
                                                       HankelType == FHTKEY51    || HankelType == FHTKONG61  || HankelType == FHTKONG121 ||
231 249
                                                       HankelType == FHTKONG241  || HankelType == IRONS )) {
250
+
232 251
                 std::unique_ptr<ProgressBar> mdisp;
233 252
                 if (progressbar) {
234 253
                     mdisp = std::make_unique< ProgressBar >( Receivers->GetNumberOfPoints()*Antenna->GetNumberOfFrequencies() );
@@ -257,7 +276,6 @@ namespace Lemma {
257 276
                     #endif
258 277
                 }
259 278
 
260
-
261 279
             } else if (Receivers->GetNumberOfPoints() > Antenna->GetNumberOfFrequencies()) {
262 280
 
263 281
                 /* Progress display bar for long calculations */
@@ -664,7 +682,7 @@ namespace Lemma {
664 682
         Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
665 683
         //Real rho = ( ((Receivers->GetLocation(irec) - tDipole->GetLocation()).head(2)).eval() ).norm();
666 684
 
667
-        tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
685
+        tDipole->SetKernels( ifreq, FieldsToCalculate, Receivers, irec, Earth );
668 686
         Hankel->ComputeRelated( rho, tDipole->GetKernelManager() );
669 687
         tDipole->UpdateFields( ifreq,  Hankel, wavef );
670 688
     }
@@ -739,6 +757,7 @@ namespace Lemma {
739 757
         #pragma omp parallel
740 758
         #endif
741 759
         { // OpenMP Parallel Block
760
+
742 761
             #ifdef LEMMAUSEOMP
743 762
             int tid = omp_get_thread_num();
744 763
             int nthreads = omp_get_num_threads();
@@ -747,6 +766,7 @@ namespace Lemma {
747 766
             int nthreads=1;
748 767
             #endif
749 768
             auto tDipole = Dipole->Clone();
769
+
750 770
             std::shared_ptr<HankelTransform> Hankel;
751 771
             switch (HankelType) {
752 772
                 case ANDERSON801:
@@ -771,6 +791,7 @@ namespace Lemma {
771 791
                     std::cerr << "Hankel transform cannot be created\n";
772 792
                     exit(EXIT_FAILURE);
773 793
             }
794
+
774 795
             if ( tDipole->GetNumberOfFrequencies() < Receivers->GetNumberOfPoints() ) {
775 796
                 for (int ifreq=0; ifreq<tDipole->GetNumberOfFrequencies(); ++ifreq) {
776 797
                     // Propogation constant in free space being input to Hankel

+ 3
- 4
Modules/FDEM1D/src/FHTAnderson801.cpp View File

@@ -940,7 +940,8 @@ namespace Lemma {
940 940
         icount = 0;
941 941
         Manager = KernelManager;
942 942
         this->kernelVec = KernelManager->GetSTLVector();
943
-        this->SetNumConv(nlag);
943
+        this->SetNumConv(nlag+1);
944
+
944 945
 #ifdef LEMMA_SINGLE_PRECISION
945 946
  		Compute(rho, 1, 1e-8);
946 947
 #else
@@ -958,7 +959,6 @@ namespace Lemma {
958 959
             SplineI->SetKnots( Arg, Zans.col(ii).imag() );
959 960
             splineVecImag.push_back(SplineI);
960 961
         }
961
-
962 962
     }
963 963
 
964 964
     void FHTAnderson801::SetLaggedArg(const Real& rho) {
@@ -998,7 +998,6 @@ namespace Lemma {
998 998
         // in release.
999 999
         #ifndef NDEBUG
1000 1000
 		if (rho<=0) {
1001
-            //std::cout << "rho= " << rho << std::endl;
1002 1001
 			throw std::runtime_error("In Hankel 2 Argument rho <= 0; rho=" + to_string(rho) );
1003 1002
 		}
1004 1003
 
@@ -1043,7 +1042,7 @@ namespace Lemma {
1043 1042
 		//Zans.resize(this->NumConv, (int)(this->kernelVec.size()));
1044 1043
 		//Zans.setZero();
1045 1044
         //Zwork = Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(801, (int)(this->kernelVec.size()));
1046
-        Zans  = Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(this->NumConv, (int)(this->kernelVec.size()));
1045
+        Zans = Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(this->NumConv, (int)(this->kernelVec.size()));
1047 1046
 
1048 1047
  		// 1010 Loop
1049 1048
  		for (int ilag=0; ilag < this->NumConv; ++ilag) {

+ 1
- 2
Modules/FDEM1D/src/KernelEM1DSpec.cpp View File

@@ -1682,7 +1682,6 @@ namespace Lemma {
1682 1682
     }
1683 1683
 
1684 1684
     // TODO in PotentialBelowSourceLayer:
1685
-
1686 1685
     template<>
1687 1686
     Complex KernelEM1DSpec<TM, 0, INAIR, INGROUND>::PotentialBelowSourceLayer(const Real &ra) {
1688 1687
         Complex dd =  ((Real)(1.)+ReflCalc->rtd(1)*ReflCalc->cf(1));
@@ -1815,7 +1814,7 @@ namespace Lemma {
1815 1814
             }
1816 1815
             p += (ReflCalc->u(n)-ut) * ReflCalc->LayerDepth(n-1);
1817 1816
         }
1818
-        Complex con = SR_SN(0, 0) * std::exp(ReflCalc->uk*ReflCalc->tx_z - ReflCalc->um*ReflCalc->rx_z+ p);
1817
+        Complex con = SR_SN(0, 0) * std::exp(ReflCalc->uk*ReflCalc->tx_z - ReflCalc->um*ReflCalc->rx_z + p);
1819 1818
         if (ReflCalc->layr < ReflCalc->Earth->GetNumberOfLayers()-1) {
1820 1819
             con += SR_SN(0, 2) * ReflCalc->rtd(ReflCalc->layr) * std::exp(ReflCalc->uk*ReflCalc->tx_z-
1821 1820
                         ReflCalc->um*((Real)(2.)*ReflCalc->LayerDepth(ReflCalc->layr)-ReflCalc->rx_z)+p);

+ 42
- 7
Modules/FDEM1D/src/PolygonalWireAntenna.cpp View File

@@ -117,25 +117,43 @@ namespace Lemma {
117 117
 	// ====================  OPERATIONS    =======================
118 118
 
119 119
 	void PolygonalWireAntenna::ApproximateWithElectricDipoles(const Vector3r &rp) {
120
+
120 121
         // Only resplit if necessary. Save a few cycles if repeated
121 122
         if ( (rRepeat-rp).norm() > 1e-16 ) {
122
-		    Dipoles.clear();
123
+
124
+            Dipoles.clear();
123 125
 
124 126
             ///////////////////
125 127
 		    // dipole array, this has impoved performance over directly pushing
126 128
 		    std::vector< std::shared_ptr<DipoleSource> >       xDipoles;
127 129
 
128
-		    // loop over all segments
130
+            // check to see if loop is closed
131
+            /*
132
+            int lastPoint = Points.cols()-1;
133
+            if ( (Points.col(0) - Points.col(lastPoint)).norm() > 1e-3 ) {
134
+                AddGroundingPoint( Points.col(0), Points.col(1)-Points.col(0), xDipoles );
135
+            }
136
+            */
137
+
138
+		    // loop over all segments, TODO fix for closed loops
129 139
 		    int iseg;
130
-            for (iseg=0; iseg<NumberOfPoints-1; ++iseg) {
140
+            for (iseg=0; iseg<NumberOfPoints-1; ++iseg) { // closed loop
141
+            //for (iseg=1; iseg<NumberOfPoints-2; ++iseg) { // grounded wire
131 142
 			    InterpolateLineSegment(Points.col(iseg), Points.col(iseg+1), rp, xDipoles);
132 143
 		    }
133 144
 
134
-            // Check to see if the loop is closed, if not, assume its grounded on ends,
135
-            if ( (Points.col(0)-Points.col(iseg)).norm() > 1e-3 ) {
136
-                xDipoles[0]->SetType(GROUNDEDELECTRICDIPOLE);
137
-                xDipoles.back()->SetType(GROUNDEDELECTRICDIPOLE);
145
+            // check to see if loop is closed
146
+            /*
147
+            if ( (Points.col(lastPoint)-Points.col( lastPoint-1 )).norm() > 1e-3 ) {
148
+                AddGroundingPoint( Points.col(lastPoint), Points.col(lastPoint)-Points.col(lastPoint-1), xDipoles );
138 149
             }
150
+            */
151
+
152
+            // Check to see if the loop is closed, if not, assume its grounded on ends,
153
+            //if ( (Points.col(0)-Points.col(iseg)).norm() > 1e-3 ) {
154
+            //    xDipoles[0]->SetType(GROUNDEDELECTRICDIPOLE);
155
+            //    xDipoles.back()->SetType(GROUNDEDELECTRICDIPOLE);
156
+            //}
139 157
 
140 158
             Dipoles = std::move(xDipoles);
141 159
             rRepeat = rp;
@@ -147,6 +165,23 @@ namespace Lemma {
147 165
         }
148 166
 	}
149 167
 
168
+    void PolygonalWireAntenna::AddGroundingPoint( const Vector3r &cp, const Vector3r& dir,
169
+                                std::vector< std::shared_ptr<DipoleSource> > &xDipoles) {
170
+		Real scale = (Real)(NumberOfTurns)*Current;
171
+        auto tx = DipoleSource::NewSP();
172
+		    tx->SetLocation(cp);
173
+		    tx->SetType(GROUNDINGPOINT);
174
+		    //tx->SetType(GROUNDEDELECTRICDIPOLE);
175
+		    //tx->SetType(MAGNETICDIPOLE);
176
+			tx->SetPolarisation(dir.array()); //dir.norm());
177
+			tx->SetFrequencies(Freqs);
178
+			tx->SetMoment(scale);
179
+			xDipoles.push_back(tx);
180
+        //std::cout << "cp " << cp.transpose() << std::endl;
181
+        //std::cout << "pol " << tx->GetPolarisation().transpose() << std::endl;
182
+        //std::cout << "moment " << tx->GetMoment() << std::endl;
183
+    }
184
+
150 185
 	Vector3r PolygonalWireAntenna::ClosestPointOnLine(const Vector3r &p1,
151 186
 					const Vector3r &p2, const Vector3r &tp) {
152 187
 

+ 143
- 35
Modules/FDEM1D/testing/BenchKiHa.h View File

@@ -80,10 +80,10 @@ public:
80 80
 		Real dy = 20;
81 81
 		Real dz = 20;
82 82
 
83
-		int  nx = 13;
84
-		int  ny = 13;
85
-		int  nz = 13;
86
-        Delta = nx*ny*nz*1e-10;
83
+		int  nx = 11;  //13
84
+		int  ny = 11;  //13
85
+		int  nz = 11;  //13
86
+        Delta = nx*ny*nz*1e-9;
87 87
 
88 88
 		receivers->SetNumberOfPoints(nx*ny*nz);
89 89
 		int ir = 0;
@@ -114,34 +114,41 @@ public:
114 114
 
115 115
    void test_Hz() {
116 116
 
117
+        std::cout.precision(4);
118
+
117 119
         dipole->SetType(MAGNETICDIPOLE);
118 120
 		dipole->SetPolarisation(ZPOLARISATION);
119 121
 
120 122
         // Put in a unit test that will be slow.
121 123
         std::cout << "MAGNETICDIPOLE Z polarisation" << std::endl;
122
-	    std::cout << "C++\n";
124
+        std::cout << "=====================================\n";
125
+	    std::cout << std::setw(18) << "Lemma/C++: ";
126
+        std::cout.flush();
123 127
 
124 128
   	    timer.begin();
125 129
 	    EmEarth->MakeCalc3();
126 130
 	    Real lemmaTime = timer.end();
131
+        std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
127 132
 
128 133
         auto lc = receivers->GetEfield( 0 );
129 134
 
130 135
         #ifdef KIHALEE_EM1D
131 136
 	    receivers->ClearFields();
132
-        std::cout << "\nFORTRAN KiHa\n";
137
+        std::cout << std::setw(18) << "KiHa/Fortran: ";
138
+        std::cout.flush();
139
+
133 140
   	    timer.begin();
134 141
  	    EmEarth->MakeCalc();
135 142
 	    Real kihaTime = timer.end();
143
+        std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
136 144
 
137 145
         auto fc = receivers->GetEfield( 0 ); //0,0);
138 146
 
139
-        std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
140
-
141
-        std::cout.precision(16);
142
-        std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
143
-        std::cout << "KiHa norm  |" << (fc).norm() << "|" << std::endl;
144
-        std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
147
+        //std::cout.precision(16);
148
+        std::cout << std::setw(18) << "Lemma norm: "      << std::setw(14) << (lc).norm() << std::endl;
149
+        std::cout << std::setw(18) << "KiHa norm: "       << std::setw(14) <<  (fc).norm() << std::endl;
150
+        std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
151
+        std::cout << std::setw(18) << "Speedup: "         << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
145 152
 
146 153
         TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
147 154
         #endif
@@ -149,34 +156,39 @@ public:
149 156
 
150 157
    void test_Hx() {
151 158
 
159
+        std::cout.precision(4);
160
+
152 161
         dipole->SetType(MAGNETICDIPOLE);
153 162
 		dipole->SetPolarisation(XPOLARISATION);
154 163
 
155 164
         // Put in a unit test that will be slow.
156
-	    std::cout << "C++\n";
157 165
         std::cout << "MAGNETICDIPOLE X polarisation" << std::endl;
166
+        std::cout << "=====================================\n";
167
+	    std::cout << std::setw(18) << "Lemma/C++: ";
168
+        std::cout.flush();
158 169
 
159 170
   	    timer.begin();
160 171
 	    EmEarth->MakeCalc3();
161 172
 	    Real lemmaTime = timer.end();
173
+        std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
162 174
 
163 175
         auto lc = receivers->GetEfield( 0 );
164 176
 
165 177
         #ifdef KIHALEE_EM1D
166 178
 	    receivers->ClearFields();
167
-        std::cout << "\nFORTRAN KiHa\n";
179
+        std::cout << std::setw(18) << "KiHa/Fortran: ";
168 180
   	    timer.begin();
169 181
  	    EmEarth->MakeCalc();
170 182
 	    Real kihaTime = timer.end();
183
+        std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
171 184
 
172 185
         auto fc = receivers->GetEfield( 0 ); //0,0);
173 186
 
174
-        std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
175
-
176
-        std::cout.precision(16);
177
-        std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
178
-        std::cout << "KiHa norm  |" << (fc).norm() << "|" << std::endl;
179
-        std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
187
+        //std::cout.precision(16);
188
+        std::cout << std::setw(18) << "Lemma norm: "      << std::setw(14) << (lc).norm() << std::endl;
189
+        std::cout << std::setw(18) << "KiHa norm: "       << std::setw(14) <<  (fc).norm() << std::endl;
190
+        std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
191
+        std::cout << std::setw(18) << "Speedup: "         << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
180 192
 
181 193
         TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
182 194
         #endif
@@ -184,34 +196,40 @@ public:
184 196
 
185 197
    void test_Hy() {
186 198
 
199
+        std::cout.precision(4);
200
+
187 201
         dipole->SetType(MAGNETICDIPOLE);
188 202
 		dipole->SetPolarisation(YPOLARISATION);
189 203
 
190 204
         // Put in a unit test that will be slow.
191
-	    std::cout << "C++\n";
192 205
         std::cout << "MAGNETICDIPOLE Y polarisation" << std::endl;
206
+        std::cout << "=====================================\n";
207
+	    std::cout << std::setw(18) << "Lemma/C++: ";
208
+        std::cout.flush();
193 209
 
194 210
   	    timer.begin();
195 211
 	    EmEarth->MakeCalc3();
196 212
 	    Real lemmaTime = timer.end();
213
+        std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
197 214
 
198 215
         auto lc = receivers->GetEfield( 0 );
199 216
 
200 217
         #ifdef KIHALEE_EM1D
201 218
 	    receivers->ClearFields();
202
-        std::cout << "\nFORTRAN KiHa\n";
219
+        std::cout << std::setw(18) << "KiHa/Fortran: ";
220
+        std::cout.flush();
203 221
   	    timer.begin();
204 222
  	    EmEarth->MakeCalc();
205 223
 	    Real kihaTime = timer.end();
224
+        std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
206 225
 
207 226
         auto fc = receivers->GetEfield( 0 ); //0,0);
208 227
 
209
-        std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
210
-
211
-        std::cout.precision(16);
212
-        std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
213
-        std::cout << "KiHa norm  |" << (fc).norm() << "|" << std::endl;
214
-        std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
228
+        //std::cout.precision(16);
229
+        std::cout << std::setw(18) << "Lemma norm: "      << std::setw(14) << (lc).norm() << std::endl;
230
+        std::cout << std::setw(18) << "KiHa norm: "       << std::setw(14) <<  (fc).norm() << std::endl;
231
+        std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
232
+        std::cout << std::setw(18) << "Speedup: "         << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
215 233
 
216 234
         TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
217 235
         #endif
@@ -219,34 +237,124 @@ public:
219 237
 
220 238
    void test_Ex() {
221 239
 
240
+        std::cout.precision(4);
241
+
222 242
         dipole->SetType(GROUNDEDELECTRICDIPOLE);
223 243
 		dipole->SetPolarisation(XPOLARISATION);
224 244
 
225 245
         // Put in a unit test that will be slow.
226
-	    std::cout << "C++\n";
227 246
         std::cout << "GROUNDEDELECTRICDIPOLE X polarisation" << std::endl;
247
+        std::cout << "=====================================\n";
248
+	    std::cout << std::setw(18) << "Lemma/C++: ";
249
+        std::cout.flush();
228 250
 
229 251
   	    timer.begin();
230 252
 	    EmEarth->MakeCalc3();
231 253
 	    Real lemmaTime = timer.end();
254
+        std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
232 255
 
233 256
         auto lc = receivers->GetEfield( 0 );
234 257
 
235 258
         #ifdef KIHALEE_EM1D
236 259
 	    receivers->ClearFields();
237
-        std::cout << "\nFORTRAN KiHa\n";
260
+        std::cout << std::setw(18) << "KiHa/Fortran: ";
261
+        std::cout.flush();
238 262
   	    timer.begin();
239 263
  	    EmEarth->MakeCalc();
240 264
 	    Real kihaTime = timer.end();
265
+        std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
241 266
 
242 267
         auto fc = receivers->GetEfield( 0 ); //0,0);
243 268
 
244
-        std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
269
+        //std::cout.precision(16);
270
+        std::cout << std::setw(18) << "Lemma norm: "      << std::setw(14) << (lc).norm() << std::endl;
271
+        std::cout << std::setw(18) << "KiHa norm: "       << std::setw(14) <<  (fc).norm() << std::endl;
272
+        std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
273
+        std::cout << std::setw(18) << "Speedup: "         << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
274
+
275
+        TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
276
+        #endif
277
+   }
278
+
279
+   void test_Ey() {
280
+
281
+        std::cout.precision(4);
282
+
283
+        dipole->SetType(GROUNDEDELECTRICDIPOLE);
284
+		dipole->SetPolarisation(YPOLARISATION);
285
+
286
+        // Put in a unit test that will be slow.
287
+        std::cout << "GROUNDEDELECTRICDIPOLE Y polarisation" << std::endl;
288
+        std::cout << "=====================================\n";
289
+	    std::cout << std::setw(18) << "Lemma/C++: ";
290
+        std::cout.flush();
291
+
292
+  	    timer.begin();
293
+	    EmEarth->MakeCalc3();
294
+	    Real lemmaTime = timer.end();
295
+        std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
296
+
297
+        auto lc = receivers->GetEfield( 0 );
298
+
299
+        #ifdef KIHALEE_EM1D
300
+	    receivers->ClearFields();
301
+        std::cout << std::setw(18) << "KiHa/Fortran: ";
302
+        std::cout.flush();
303
+
304
+        timer.begin();
305
+ 	    EmEarth->MakeCalc();
306
+	    Real kihaTime = timer.end();
307
+        std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
308
+
309
+        auto fc = receivers->GetEfield( 0 ); //0,0);
310
+
311
+        //std::cout.precision(16);
312
+        std::cout << std::setw(18) << "Lemma norm: "      << std::setw(14) << (lc).norm() << std::endl;
313
+        std::cout << std::setw(18) << "KiHa norm: "       << std::setw(14) <<  (fc).norm() << std::endl;
314
+        std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
315
+        std::cout << std::setw(18) << "Speedup: "         << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
316
+
317
+        TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
318
+        #endif
319
+   }
320
+
321
+   void test_Ez() {
322
+
323
+        std::cout.precision(4);
324
+
325
+        dipole->SetType(GROUNDEDELECTRICDIPOLE);
326
+		dipole->SetPolarisation(ZPOLARISATION);
327
+
328
+        // Put in a unit test that will be slow.
329
+        std::cout << "GROUNDEDELECTRICDIPOLE Z polarisation" << std::endl;
330
+        std::cout << "=====================================\n";
331
+	    std::cout << std::setw(18) << "Lemma/C++: ";
332
+        std::cout.flush();
333
+
334
+  	    timer.begin();
335
+	    EmEarth->MakeCalc3();
336
+	    Real lemmaTime = timer.end();
337
+        std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
338
+
339
+        auto lc = receivers->GetEfield( 0 );
340
+
341
+        #ifdef KIHALEE_EM1D
342
+	    receivers->ClearFields();
343
+        std::cout << std::setw(18) << "KiHa/Fortran: ";
344
+        std::cout.flush();
345
+
346
+        timer.begin();
347
+ 	    EmEarth->MakeCalc();
348
+	    Real kihaTime = timer.end();
349
+        std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
350
+
351
+        auto fc = receivers->GetEfield( 0 ); //0,0);
245 352
 
246
-        std::cout.precision(16);
247
-        std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
248
-        std::cout << "KiHa norm  |" << (fc).norm() << "|" << std::endl;
249
-        std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
353
+        //std::cout.precision(16);
354
+        std::cout << std::setw(18) << "Lemma norm: "      << std::setw(14) << (lc).norm() << std::endl;
355
+        std::cout << std::setw(18) << "KiHa norm: "       << std::setw(14) <<  (fc).norm() << std::endl;
356
+        std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
357
+        std::cout << std::setw(18) << "Speedup: "         << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
250 358
 
251 359
         TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
252 360
         #endif

+ 6
- 0
Modules/LemmaCore/CMakeLists.txt View File

@@ -33,6 +33,12 @@ if ( LEMMA_VTK6_SUPPORT OR LEMMA_VTK7_SUPPORT OR LEMMA_VTK8_SUPPORT )
33 33
 #	target_link_libraries(lemmacore "matplot")
34 34
 endif()
35 35
 
36
+
37
+if ( LEMMA_VTK9_SUPPORT ) 
38
+	target_link_libraries(lemmacore ${visibility}VTK::CommonCore VTK::IOXML VTK::FiltersHyperTree)
39
+	vtk_module_autoinit(TARGETS lemmacore MODULES VTK::CommonCore VTK::IOXML VTK::FiltersHyperTree)
40
+endif()
41
+
36 42
 # find_package(yaml-cpp) does not seem to properly define library names...
37 43
 # a better solution than this is welcome 
38 44
 

+ 1
- 1
Modules/LemmaCore/include/RectilinearGridVTKExporter.h View File

@@ -26,7 +26,7 @@
26 26
 #include "LemmaObject.h"
27 27
 #include "RectilinearGrid.h"
28 28
 
29
-#include <vtkSmartPointer.h>
29
+#include "vtkSmartPointer.h"
30 30
 #include "vtkXMLRectilinearGridWriter.h"
31 31
 #include "vtkRectilinearGrid.h"
32 32
 #include "vtkDoubleArray.h"

+ 2
- 1
Modules/LemmaCore/include/lemma.h View File

@@ -301,9 +301,10 @@
301 301
          @param NOSOURCETYPE is default.
302 302
          @param GROUNDEDELECTRICDIPOLE is an grounded electric dipole
303 303
          @param UNGROUNDEDELECTRICDIPOLE is an ungrounded electric dipole
304
+         @param GROUNDINGPOINT is a point of grounding in a bipole (or similiar) transmitter
304 305
          @param MAGNETICDIPOLE is a magnetic dipole
305 306
         */
306
-        enum DIPOLESOURCETYPE {NOSOURCETYPE, GROUNDEDELECTRICDIPOLE, UNGROUNDEDELECTRICDIPOLE, MAGNETICDIPOLE};
307
+        enum DIPOLESOURCETYPE {NOSOURCETYPE, GROUNDEDELECTRICDIPOLE, UNGROUNDEDELECTRICDIPOLE, GROUNDINGPOINT, MAGNETICDIPOLE};
307 308
 
308 309
         /// Only three polarizations are supported. They may be summed to
309 310
         /// approximate others

+ 7
- 3
Modules/LemmaCore/src/CubicSplineInterpolator.cpp View File

@@ -173,17 +173,21 @@ namespace Lemma {
173 173
     //      Method:  Interpolate
174 174
     //--------------------------------------------------------------------------------------
175 175
     Real CubicSplineInterpolator::Interpolate ( const Real& x, int& i) {
176
+
176 177
         // O(n) search, could do bisection, but if these are sorted, then this is quick
177
-        while(Spline.x[i] < x && i<Spline.x.size()) {
178
+        while(Spline.x[i] < x && i<Spline.x.size()-1) {
178 179
             ++i;
179 180
         }
180 181
         --i;
181 182
 
182 183
 //         if ( x > Spline.x[i] ) {
183
-//             std::cout << "DOOM\t" << x << "\t" << i << "\t" << Spline.x[i];
184
-//             throw std::runtime_error("CubicSplineInterpolator::Interpolate ATTEMPT TO INTERPOLATE PAST LAST KNOT");
184
+//             std::cout << "DOOM in interplate\t x=" <<  x << "\ti=" << i << "\tSpline.x[i]=" << Spline.x[i] << std::endl;
185
+//             std::cout <<"Spline.x.size()" << Spline.x.size() << std::endl;
186
+//             std::cout << "Spline.x" << Spline.x.transpose() << std::endl;
187
+//             //throw std::runtime_error("CubicSplineInterpolator::Interpolate ATTEMPT TO INTERPOLATE PAST LAST KNOT");
185 188
 //         }
186 189
 
190
+
187 191
         return Spline.a[i] + Spline.b[i]*(x-Spline.x[i]) + Spline.c[i]*((x-Spline.x[i])*(x-Spline.x[i])) +
188 192
                Spline.d[i]*((x-Spline.x[i])*(x-Spline.x[i])*(x-Spline.x[i]) );
189 193
     }		// -----  end of method CubicSplineInterpolator::Interpolate  -----

+ 3
- 0
Modules/LemmaCore/src/helper.cpp View File

@@ -185,6 +185,8 @@ std::string enum2String( const DIPOLESOURCETYPE& Type ) {
185 185
             return std::string("GROUNDEDELECTRICDIPOLE");
186 186
         case UNGROUNDEDELECTRICDIPOLE:
187 187
             return std::string("UNGROUNDEDELECTRICDIPOLE");
188
+        case GROUNDINGPOINT:
189
+            return std::string("GROUNDINGPOINT");
188 190
         case MAGNETICDIPOLE:
189 191
             return std::string("MAGNETICDIPOLE");
190 192
         default:
@@ -258,6 +260,7 @@ DIPOLESOURCETYPE string2Enum<DIPOLESOURCETYPE>( const std::string& str ) {
258 260
     if      (str == "NOSOURCETYPE")              return NOSOURCETYPE;
259 261
     if      (str == "GROUNDEDELECTRICDIPOLE")    return GROUNDEDELECTRICDIPOLE;
260 262
     if      (str == "UNGROUNDEDELECTRICDIPOLE")  return UNGROUNDEDELECTRICDIPOLE;
263
+    if      (str == "GROUNDINGPOINT")            return GROUNDINGPOINT;
261 264
     if      (str == "MAGNETICDIPOLE")            return MAGNETICDIPOLE;
262 265
     else {
263 266
         throw std::runtime_error("string not recognized as DipoleSource");

+ 7
- 4
README.md View File

@@ -1,13 +1,16 @@
1 1
 # About
2
-Lemma is an ElectroMagnetics Modelling API. Lemma is developed in the hopes that it will be helpful for academics, industry, and anyone else interested in modelling. 
2
+Lemma is an ElectroMagnetics Modelling API. Lemma is developed in the hopes that it will be helpful for academics, industry, and anyone else interested in geophysical modelling.
3 3
 
4 4
 * Written in C++ 
5 5
 * Test driven   
6 6
 * Flexible 
7
-* Fast 
7
+* Fast
8 8
 * Object oriented 
9
-* Python bindings planned
10
-* VTK integration 
9
+* Python bindings
10
+* VTK integration
11
+
12
+## Git 
13
+Lemma is hosted on several Git instances. Our main instance runs on Gitea and is at https://lemmasoftware.org. The project is also mirrored on GitHub. 
11 14
 
12 15
 ## Team 
13 16
 Lemma is and has been developed by several organisations and people, including: University of Utah, Colorado School of Mines, US Geological Survey. 

+ 1
- 0
python/long.md View File

@@ -0,0 +1 @@
1
+Originally, Lemma is an Elecromagnetics modelling API. The scope of the project has expanded somewhat from this, and currently you can find documentation at https://lemmasoftware.org

+ 2
- 2
python/publish.sh View File

@@ -2,8 +2,8 @@
2 2
 rm -rf build dist clean pyLemma.egg.info
3 3
 python setup.py build
4 4
 python setup.py bdist_wheel
5
-#auditwheel repair ./dist/pyLemma*.whl -w ./clean
6
-#twine upload build/* #clean/*
5
+auditwheel repair ./dist/pyLemma*.whl -w ./clean
6
+twine upload build/* #clean/*
7 7
 
8 8
 #rm -rf dist
9 9
 #python setup.py build

+ 6
- 3
python/setup.py View File

@@ -19,13 +19,16 @@ class InstallPlatlib(install):
19 19
         if self.distribution.has_ext_modules():
20 20
             self.install_lib = self.install_platlib
21 21
 
22
+with open("README.md", "r") as fh:
23
+    long_description = fh.read()
24
+
22 25
 setup(
23 26
   name             = 'pyLemma',
24
-  version          = '0.0.13', 
27
+  version          = '0.4.0', 
25 28
   author           = 'Trevor Irons and others',
26 29
   author_email     = 'Trevor.Irons@lemmasoftware.org',
27
-  description      = 'A short description of the app/lib',
28
-  long_description = 'A longer one',
30
+  description      = 'PyLemma is a wrapper to Lemma',
31
+  long_description = long_description,
29 32
   classifiers=[
30 33
         'Development Status :: 3 - Alpha',
31 34
         'Intended Audience :: Developers',

+ 1
- 1
vim/c.vim View File

@@ -9,7 +9,7 @@ highlight eType ctermfg=Magenta guifg=Magenta
9 9
 syn keyword eType  MAGUNITS  TEMPUNITS  TIMEUNITS FREQUENCYUNITS FEMCOILORIENTATION ORIENTATION FIELDTYPE FIELDCOMPONENT SPATIALCOORDINANT HANKELTRANSFORMTYPE FIELDCALCULATIONS WINDOWTYPE DIPOLESOURCETYPE 
10 10
 
11 11
 highlight eeType ctermfg=Cyan guifg=Cyan
12
-syn keyword eeType  TESLA NANOTESLA GAUSS CELCIUS KELVIN SEC MILLISEC MICROSEC NANOSEC PICOSEC HZ KHZ MHZ GHZ COAXIAL COPLANAR HFIELDREAL HFIELDIMAG EFIELDREAL EFIELDIMAG XCOMPONENT YCOMPONENT ZCOMPONENT XCOORD YCOORD ZCOORD X Y Z NX  NY  NZ ANDERSON801 CHAVE FHTKEY201 FHTKEY101 FHTKEY51 FHTKONG241 FHTKONG121 FHTKONG61 QWEKEY E H BOTH HAMMING HANNING RECTANGULAR NOSOURCETYPE GROUNDEDELECTRICDIPOLE UNGROUNDEDELECTRICDIPOLE MAGNETICDIPOLE
12
+syn keyword eeType  TESLA NANOTESLA GAUSS CELCIUS KELVIN SEC MILLISEC MICROSEC NANOSEC PICOSEC HZ KHZ MHZ GHZ COAXIAL COPLANAR HFIELDREAL HFIELDIMAG EFIELDREAL EFIELDIMAG XCOMPONENT YCOMPONENT ZCOMPONENT XCOORD YCOORD ZCOORD X Y Z NX  NY  NZ ANDERSON801 CHAVE FHTKEY201 FHTKEY101 FHTKEY51 FHTKONG241 FHTKONG121 FHTKONG61 QWEKEY E H BOTH HAMMING HANNING RECTANGULAR NOSOURCETYPE GROUNDEDELECTRICDIPOLE GROUNDINGPOINT UNGROUNDEDELECTRICDIPOLE MAGNETICDIPOLE
13 13
 
14 14
 " Namespaces
15 15
 highlight nspace ctermfg=Red guifg=Red

Loading…
Cancel
Save