Galerkin FEM for elliptic PDEs
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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 -----