Lemma is an Electromagnetics API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

instrumentfem.cpp 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* This file is part of Lemma, a geophysical modelling and inversion API */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. @file
  7. @author M. Andy Kass
  8. @date 01/14/2013
  9. @version $Id$
  10. **/
  11. #include "instrumentfem.h"
  12. namespace Lemma {
  13. std::ostream &operator<<(std::ostream &stream,
  14. const InstrumentFem &ob) {
  15. stream << *(LemmaObject*)(&ob);
  16. return stream;
  17. }
  18. InstrumentFem::InstrumentFem(const std::string &name) : Instrument (name),
  19. EarthModel(NULL), Dipole(NULL), Receiver(NULL), InputData(NULL),
  20. OutputData(NULL) {
  21. }
  22. InstrumentFem::~InstrumentFem() {
  23. if (NumberOfReferences !=0) {
  24. throw DeleteObjectWithReferences(this);
  25. }
  26. }
  27. InstrumentFem* InstrumentFem::New() {
  28. InstrumentFem* Obj = new InstrumentFem("InstrumentFem");
  29. Obj->AttachTo(Obj);
  30. return Obj;
  31. }
  32. void InstrumentFem::Delete() {
  33. this->DetachFrom(this);
  34. }
  35. void InstrumentFem::Release() {
  36. delete this;
  37. }
  38. void InstrumentFem::MakeCalculation() {
  39. EMEarth1D *EMEarthLocal=EMEarth1D::New();
  40. EMEarthLocal->AttachLayeredEarthEM(this->EarthModel);
  41. EMEarthLocal->AttachDipoleSource(this->Dipole);
  42. EMEarthLocal->SetFieldsToCalculate(H);
  43. //EMEarthLocal->SetHankelTransformMethod(DIGITALFILTERING);
  44. EMEarthLocal->SetHankelTransformMethod(CHAVE);
  45. EMEarthLocal->AttachReceiverPoints(this->Receiver);
  46. EMEarthLocal->MakeCalc3();
  47. //EMEarthLocal->MakeCalc();
  48. EMEarthLocal->Delete();
  49. // GetHfield(freq_idx, loc_idx)(comp)
  50. }
  51. void InstrumentFem::ForwardModelProfile() {
  52. }
  53. void InstrumentFem::EMEarthModel(LayeredEarthEM* Earth) {
  54. if (this->EarthModel != NULL) {
  55. this->EarthModel->DetachFrom(this);
  56. }
  57. Earth->AttachTo(this);
  58. this->EarthModel = Earth;
  59. }
  60. void InstrumentFem::SetDipoleSource(DipoleSource* dipolesource) {
  61. if (this->Dipole != NULL) {
  62. this->Dipole->DetachFrom(this);
  63. }
  64. dipolesource->AttachTo(this);
  65. this->Dipole = dipolesource;
  66. }
  67. void InstrumentFem::SetReceiverPoints(ReceiverPoints* receiver) {
  68. if (this->Receiver != NULL) {
  69. this->Receiver->DetachFrom(this);
  70. }
  71. receiver->AttachTo(this);
  72. this->Receiver = receiver;
  73. }
  74. void InstrumentFem::AlignWithData(DataFEM* inpdata) {
  75. this->nFreq = inpdata->GetnFreq();
  76. this->nObs = inpdata->GetnObs();
  77. this->freq = inpdata->GetFreqs();
  78. this->xyz = inpdata->GetXYZ();
  79. this->TxOrientation = inpdata->GetTxOrien();
  80. this->RxOrientation = inpdata->GetRxOrien();
  81. this->TxMom = inpdata->GetTxMom();
  82. this->TxRxSep = inpdata->GetTxRxSep();
  83. this->ScaleFac = inpdata->GetScaleFac();
  84. // Check into boost for the use of pointer arrays
  85. // array of nFreq DipoleSource objects
  86. //first get rid of existing dipoles
  87. for (unsigned int id=0;id<this->Transmitters.size();++id) {
  88. this->Transmitters[id]->Delete();
  89. }
  90. this->Transmitters.clear();
  91. //this->Transmitters.resize(this->nFreq);
  92. for (unsigned int id=0;id<this->Receivers.size();++id) {
  93. this->Receivers[id]->Delete();
  94. }
  95. this->Receivers.clear();
  96. for (int ii=0;ii<this->nFreq;ii++) {
  97. /*
  98. this->Transmitters.push_back(DipoleSource::New());
  99. std::cout << &(this->Transmitters[ii]) << std::endl;
  100. */
  101. DipoleSource *tt = DipoleSource::New();
  102. ReceiverPoints *tr = ReceiverPoints::New();
  103. Real ftemp;
  104. Real momtemp;
  105. ftemp = this->freq(ii);
  106. momtemp = this->TxMom(ii);
  107. tt->SetType(MAGNETICDIPOLE);
  108. tt->SetLocation(0,0,-1.e-3);
  109. // This is really hoopty but will do for now
  110. if (this->TxOrientation(ii) == X) {
  111. tt->SetPolarisation(XPOLARISATION);
  112. }
  113. else if (this->TxOrientation(ii) == Y) {
  114. tt->SetPolarisation(YPOLARISATION);
  115. }
  116. else if (this->TxOrientation(ii) == Z) {
  117. tt->SetPolarisation(ZPOLARISATION);
  118. }
  119. else {
  120. std::cout << "DANGER! DANGER! UNHELPFUL ERROR"
  121. << std::endl;
  122. tt->SetPolarisation(ZPOLARISATION);
  123. }
  124. tt->SetNumberOfFrequencies(1);
  125. tt->SetFrequency(0,ftemp);
  126. tt->SetMoment(momtemp);
  127. this->Transmitters.push_back(tt);
  128. tr->SetNumberOfReceivers(1);
  129. tr->SetLocation(0,this->TxRxSep.block(0,ii,3,1));
  130. this->Receivers.push_back(tr);
  131. }
  132. // Now populate the attached output data object?
  133. // Or, should I do this later after the computation?
  134. }
  135. void InstrumentFem::SetOutputData(DataFEM* outputdata) {
  136. if (this->OutputData != NULL) {
  137. this->OutputData->DetachFrom(this);
  138. }
  139. outputdata->AttachTo(this);
  140. this->OutputData = outputdata;
  141. }
  142. }// end of namespace lemma