// =========================================================================== // // Filename: hantenna.cpp // // Created: 10/07/2010 08:57:04 AM // Modified: 11 April 2018 // Compiler: Tested with g++, icpc, and MSVC 2017 // // Author: Trevor Irons (ti) // // Copyright (C) 2012,2018 Trevor Irons // // Organisation: Lemma Software // // Email: Trevor.Irons@lemmasoftware.org // // =========================================================================== /** @file @author Trevor Irons @date 10/07/2010 $Id$ **/ #include "LemmaCore" #include "FDEM1D" #include "timer.h" using namespace Lemma; std::vector readinpfile(const std::string& fname); std::vector readinpfile2(const std::string& fname); int main(int argc, char** argv) { std::cout << "\n" << "Hantenna \n\n" << "Hantenna is a programme for computing the H field from polygonal wire\n" << "loop sources \n\n" << "Hantenna was built using Lemma (Lemma is an Electromagnetics Modelling API)\n" << "Lemma is Free and Open Source Software (FOSS) and is released under\n" << "the MPL, it is covered by the following copyrights:\n" << "Copyright (C) 2009, 2010, 2011, 2012, 218 Trevor P. Irons\n" << "Copyright (C) 2011, 2012 M. Andy Kass\n\n" << "More information may be found at: https://lemmasoftware.org\n" << " info@lemmasoftware.org\n\n" << "=====================================================================\n" << "This programme is part of Lemma, a geophysical modelling and inversion API \n" << "This Source Code Form is subject to the terms of the Mozilla Public\n" << "License, v. 2.0. If a copy of the MPL was not distributed with this\n" << "file, You can obtain one at http://mozilla.org/MPL/2.0/. \n" << "=====================================================================\n\n\n"; if (argc < 5) { std::cout << "usage: hantenna.exe trans.inp cond.inp points.inp config.inp \n"; exit(0); } #ifdef LEMMAUSEOMP std::cout << "OpenMP is using " << omp_get_max_threads() << " threads" << std::endl; #endif std::vector Trans = readinpfile(std::string(argv[1])); std::vector CondMod = readinpfile(std::string(argv[2])); std::vector Points = readinpfile(std::string(argv[3])); std::vector config = readinpfile2(std::string(argv[4])); ////////////////////////////////////// // Define transmitter auto trans = PolygonalWireAntenna::NewSP(); trans->SetNumberOfPoints((int)(Trans[0])); int ip=1; for ( ; ip<=(int)(Trans[0])*2; ip+=2) { trans->SetPoint(ip/2, Vector3r (Trans[ip], Trans[ip+1], -1e-3)); } trans->SetNumberOfFrequencies(1); trans->SetFrequency(0, Trans[ip]); trans->SetCurrent(Trans[ip+1]); trans->SetMinDipoleRatio(atof(config[1].c_str())); trans->SetMinDipoleMoment(atof(config[2].c_str())); trans->SetMaxDipoleMoment(atof(config[3].c_str())); ///////////////////////////////////// // Field calculations auto receivers = FieldPoints::NewSP(); int nx = (int)Points[0]; int ny = (int)Points[1]; int nz = (int)Points[2]; Real ox = Points[3]; Real oy = Points[4]; Real oz = Points[5]; Vector3r loc; VectorXr dx(nx-1); VectorXr dy(ny-1); VectorXr dz(nz-1); ip = 6; int ir = 0; for ( ; ip <6+nx-1; ++ip) { dx[ir] = Points[ip]; ++ir; } ir = 0; for ( ; ip <6+ny-1+nx-1; ++ip) { dy[ir] = Points[ip]; ++ir; } ir = 0; for ( ; ip <6+nz-1+ny-1+nx-1; ++ip) { dz[ir] = Points[ip]; ++ir; } receivers->SetNumberOfPoints(nx*ny*nz); ir = 0; Real pz = oz; for (int iz=0; izSetLocation(ir, loc); if (ix < nx-1) px += dx[ix]; ++ ir; } if (iySetNumberOfLayers(CondMod[0]+1); sigma.resize(CondMod[0]+1); sigma(0) = 0; // airlayer thick.resize(CondMod[0]-1); int ilay=1; for ( ; ilay/2SetLayerConductivity(sigma); if (thick.size() > 0) earth->SetLayerThickness(thick); auto EmEarth = EMEarth1D::NewSP(); EmEarth->AttachWireAntenna(trans); EmEarth->AttachLayeredEarthEM(earth); EmEarth->AttachFieldPoints(receivers); EmEarth->SetFieldsToCalculate(H); EmEarth->SetHankelTransformMethod(string2Enum(config[0])); EmEarth->SetHankelTransformMethod(FHTKEY201); /////////////////////////////////////////////// // Keep track of time jsw_timer timer; timer.begin(); clock_t launch = clock(); EmEarth->CalculateWireAntennaFields(true); // true=status bar Real paTime = timer.end(); std::cout << "\n\n===========================================\ncalc. real time: " << paTime/60. << "\t[m]\n"; std::cout << "calc. user time: " << (clock()-launch)/CLOCKS_PER_SEC/60. << "\t[CPU m]" << std::endl; //////////////////////////////////// // Report std::fstream hrep("hfield.yaml", std::ios::out); std::fstream hreal("hfield.dat", std::ios::out); hrep << *EmEarth << std::endl; hrep.close(); //hreal << *trans << std::endl; //hreal << *earth << std::endl; hreal << "// Right hand coordinate system, z is positive down\n"; hreal << "// x[m]\ty[m]\tz[m]\tHx[A/m]\tHy[A/m]\tHz[A/m]\n"; hreal.precision(8); int i=0; for (int iz=0; izGetLocation(i).transpose() << "\t"; hreal << receivers->GetHfield(0, i).transpose() << "\n"; ++i; } } } hreal.close(); // Clean up } std::vector readinpfile(const std::string& fname) { std::string buf; char dump[255]; std::vector vals; std::fstream input(fname.c_str(), std::ios::in); if (input.fail()) { std::cerr << "Input file " << fname << " failed to open\n"; exit(EXIT_FAILURE); } while (input >> buf) { if (buf.substr(0,2) == "//") { input.getline(dump, 255); } else { vals.push_back( atof(buf.c_str() )); } } return vals; } std::vector readinpfile2(const std::string& fname) { std::string buf; char dump[255]; std::vector vals; std::fstream input(fname.c_str(), std::ios::in); if (input.fail()) { std::cerr << "Input file " << fname << " failed to open\n"; exit(EXIT_FAILURE); } while (input >> buf) { if (buf.substr(0,2) == "//") { input.getline(dump, 255); } else { vals.push_back( std::string(buf.c_str() )); } } return vals; }