Galerkin FEM for elliptic PDEs
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

LinearMag.cpp 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* This file is part of Lemma, a geophysical modelling and inversion API.
  2. * More information is available at http://lemmasoftware.org
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. */
  8. /**
  9. * @file
  10. * @date 03/21/2016 02:10:08 PM
  11. * @version $Id$
  12. * @author Trevor Irons (ti)
  13. * @email tirons@egi.utah.edu
  14. * @copyright Copyright (c) 2016, University of Utah
  15. * @copyright Copyright (c) 2016, Lemma Software, LLC
  16. */
  17. #include "LinearMag.h"
  18. namespace Lemma {
  19. // ==================== FRIEND METHODS =====================
  20. #ifdef HAVE_YAMLCPP
  21. std::ostream &operator << (std::ostream &stream, const LinearMag &ob) {
  22. stream << ob.Serialize() << "\n---\n"; // End of doc --- as a direct stream should encapsulate thingy
  23. return stream;
  24. }
  25. #else
  26. std::ostream &operator<<(std::ostream &stream, const LinearMag& ob) {
  27. stream << *(FEM4EllipticPDE*)(&ob);
  28. return stream;
  29. }
  30. #endif
  31. // ==================== LIFECYCLE =======================
  32. //--------------------------------------------------------------------------------------
  33. // Class: LinearMag
  34. // Method: LinearMag
  35. // Description: constructor (protected)
  36. //--------------------------------------------------------------------------------------
  37. LinearMag::LinearMag (const std::string& name) : FEM4EllipticPDE(name) {
  38. } // ----- end of method LinearMag::LinearMag (constructor) -----
  39. #ifdef HAVE_YAMLCPP
  40. //--------------------------------------------------------------------------------------
  41. // Class: LinearMag
  42. // Method: LinearMag
  43. // Description: DeSerializing constructor (protected)
  44. //--------------------------------------------------------------------------------------
  45. LinearMag::LinearMag (const YAML::Node& node) : FEM4EllipticPDE(node) {
  46. } // ----- end of method LinearMag::LinearMag (constructor) -----
  47. #endif
  48. //--------------------------------------------------------------------------------------
  49. // Class: LinearMag
  50. // Method: New()
  51. // Description: public constructor
  52. //--------------------------------------------------------------------------------------
  53. LinearMag* LinearMag::New() {
  54. LinearMag* Obj = new LinearMag("LinearMag");
  55. Obj->AttachTo(Obj);
  56. return Obj;
  57. }
  58. //--------------------------------------------------------------------------------------
  59. // Class: LinearMag
  60. // Method: ~LinearMag
  61. // Description: destructor (protected)
  62. //--------------------------------------------------------------------------------------
  63. LinearMag::~LinearMag () {
  64. } // ----- end of method LinearMag::~LinearMag (destructor) -----
  65. //--------------------------------------------------------------------------------------
  66. // Class: LinearMag
  67. // Method: Delete
  68. // Description: public destructor
  69. //--------------------------------------------------------------------------------------
  70. void LinearMag::Delete() {
  71. this->DetachFrom(this);
  72. }
  73. //--------------------------------------------------------------------------------------
  74. // Class: LinearMag
  75. // Method: Release
  76. // Description: destructor (protected)
  77. //--------------------------------------------------------------------------------------
  78. void LinearMag::Release() {
  79. delete this;
  80. }
  81. #ifdef HAVE_YAMLCPP
  82. //--------------------------------------------------------------------------------------
  83. // Class: LinearMag
  84. // Method: Serialize
  85. //--------------------------------------------------------------------------------------
  86. YAML::Node LinearMag::Serialize ( ) const {
  87. YAML::Node node = FEM4EllipticPDE::Serialize();;
  88. node.SetTag( this->Name );
  89. // FILL IN CLASS SPECIFICS HERE
  90. node["B0"] = B0;
  91. return node;
  92. } // ----- end of method LinearMag::Serialize -----
  93. //--------------------------------------------------------------------------------------
  94. // Class: LinearMag
  95. // Method: DeSerialize
  96. //--------------------------------------------------------------------------------------
  97. LinearMag* LinearMag::DeSerialize ( const YAML::Node& node ) {
  98. LinearMag* Object = new LinearMag(node);
  99. Object->AttachTo(Object);
  100. DESERIALIZECHECK( node, Object )
  101. return Object ;
  102. } // ----- end of method LinearMag::DeSerialize -----
  103. #endif
  104. //--------------------------------------------------------------------------------------
  105. // Class: LinearMag
  106. // Method: SetInducingMagField
  107. //--------------------------------------------------------------------------------------
  108. void LinearMag::SetInducingMagField ( const Real& intensity, const Real& inc,
  109. const Real& dec, const MAGUNITS& U ) {
  110. B0(0) = intensity * std::cos(inc) * std::cos(dec); // northing
  111. B0(1) = intensity * std::cos(inc) * std::sin(dec); // easting
  112. B0(2) = intensity * std::sin(inc); // z
  113. ScaleB0(U);
  114. return ;
  115. } // ----- end of method LinearMag::SetInducingMagField -----
  116. //--------------------------------------------------------------------------------------
  117. // Class: LinearMag
  118. // Method: SetInducingMagFieldVector
  119. //--------------------------------------------------------------------------------------
  120. void LinearMag::SetInducingMagFieldVector ( const Vector3r& BB0, const MAGUNITS& U ) {
  121. B0 = BB0;
  122. ScaleB0(U);
  123. return ;
  124. } // ----- end of method LinearMag::SetInducingMagFieldVector -----
  125. //--------------------------------------------------------------------------------------
  126. // Class: LinearMag
  127. // Method: ScaleB0
  128. //--------------------------------------------------------------------------------------
  129. void LinearMag::ScaleB0 ( const MAGUNITS& U ) {
  130. switch ( U ) {
  131. case TESLA:
  132. break;
  133. case NANOTESLA:
  134. B0 *= 1e-9;
  135. break;
  136. case GAUSS:
  137. B0 *= 1e-4;
  138. break;
  139. }
  140. return ;
  141. } // ----- end of method LinearMag::ScaleB0 -----
  142. //--------------------------------------------------------------------------------------
  143. // Class: LinearMag
  144. // Method: CalculateRHS
  145. //--------------------------------------------------------------------------------------
  146. void LinearMag::CalculateRHS ( const std::string& susName ) {
  147. vtkDoubleArray* G = vtkDoubleArray::New();
  148. G->SetNumberOfComponents(1);
  149. G->SetNumberOfTuples( vtkGrid->GetNumberOfPoints() );
  150. G->SetName("G");
  151. // Iterate over all the points or all of the cells?
  152. for (int ic=0; ic < vtkGrid->GetNumberOfCells(); ++ic) {
  153. Real cellSus = vtkGrid->GetCellData()->GetScalars(susName.c_str())->GetTuple(ic)[0];
  154. Eigen::Matrix<Real, 4, 4> C = Eigen::Matrix<Real, 4, 4>::Zero() ;
  155. for (int ii=0; ii<4; ++ii) {
  156. double* pts = vtkGrid->GetCell(ic)->GetPoints()->GetPoint(ii);
  157. C(ii, 0) = 1;
  158. C(ii, 1) = pts[0];
  159. C(ii, 2) = pts[1];
  160. C(ii, 3) = pts[2];
  161. }
  162. /* The indices */
  163. vtkIdList* Ids = vtkGrid->GetCell(ic)->GetPointIds();
  164. int ID[4];
  165. ID[0] = Ids->GetId(0);
  166. ID[1] = Ids->GetId(1);
  167. ID[2] = Ids->GetId(2);
  168. ID[3] = Ids->GetId(3);
  169. /* the 4 faces of the tetrahedra
  170. ID[0] ID[1] ID[2]
  171. ID[0] ID[1] ID[3]
  172. ID[0] ID[2] ID[3]
  173. ID[1] ID[2] ID[3]
  174. */
  175. // Face 0, ID 0,1,2
  176. /*
  177. Eigen::Matrix<Real, 3, 2> CC = Eigen::Matrix<Real, 3, 2>::Ones() ;
  178. {
  179. CC.col(1) = C.row(0).tail<3>() - C.row(1).tail<3>();
  180. CC.col(2) = C.row(0).tail<3>() - C.row(2).tail<3>();
  181. Vector3r nhat = CC.col(1).cross(CC.col(2));
  182. nhat.array() /= nhat.norm();
  183. Real flux = cellSus*nhat.dot(B0);
  184. g(ID[0]) += flux;
  185. g(ID[1]) += flux;
  186. g(ID[2]) += flux;
  187. // vtkGrid->GetPointData()->GetScalars("G")->GetTuple1(ID[2])*TA/3. * i4pi ;
  188. }
  189. */
  190. }
  191. vtkGrid->GetPointData()->AddArray( G );
  192. return ;
  193. } // ----- end of method LinearMag::CalculateRHS -----
  194. } // ----- end of Lemma name -----