35 {
36
38
39 try {
40
41 moab::Core mb_instance;
42 moab::Interface &moab = mb_instance;
43
44 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
45 auto moab_comm_wrap =
46 boost::make_shared<WrapMPIComm>(PETSC_COMM_WORLD, false);
47 if (pcomm == NULL)
48 pcomm =
49 new ParallelComm(&moab, moab_comm_wrap->get_comm());
50
51
52 PetscBool flg_file;
54 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Lorenz force configure",
55 "none");
56 CHKERR PetscOptionsString(
"-my_file",
"mesh file name",
"",
"solution.h5m",
58 PetscOptionsEnd();
59
60 const char *option;
61 option = "";
63
64
67
71
72
73 DM dm;
75 CHKERR DMCreate(PETSC_COMM_WORLD, &dm);
76 CHKERR DMSetType(dm,
"DMMOFEM");
79 CHKERR DMSetFromOptions(dm);
80
83
85 using VolOp = VolumeElementForcesAndSourcesCore::UserDataOperator;
86
87
88
89
90 struct MyOpDebug :
public VolOp {
91
92 boost::shared_ptr<MatrixDouble>
B;
93 MyOpDebug(
decltype(
B) b) :
VolOp(
"MAGNETIC_POTENTIAL", OPROW),
B(b) {}
94
98 if (type == MBEDGE && side == 0) {
99 std::cout << "found " << (*B) << endl;
101 }
102
104 }
105 };
106
107 const double dist = 1e-12;
108 const int nb_random_points = 5000;
109 const int nb_steps = 10000;
110 const int mod_step = 10;
111 const double dt = 1e-5;
112 const double velocity_scale = 0.1;
113 const double magnetic_field_scale = 1;
114 const double scale_box = 0.5;
115
118
119
121 auto vol_ele = data_at_pts->feMethodPtr.lock();
122 if (!vol_ele)
124 "Pointer to element does not exists");
125 auto get_rule = [&](
int order_row,
int order_col,
int order_data) {
126 return -1;
127 };
129
133
134
137
139 BoundBox box;
140 CHKERR data_at_pts->treePtr->get_bounding_box(box);
141
142 const double bMin = box.bMin[0];
143 const double bMax = box.bMax[0];
144
145 auto create_vertices = [nb_random_points, bMin, bMax,
146 scale_box](moab::Interface &moab, auto &verts,
147 auto &arrays_coord) {
149 ReadUtilIface *iface;
151 CHKERR moab.query_interface(iface);
152 CHKERR iface->get_node_coords(3, nb_random_points, 0, startv,
153 arrays_coord);
155 arrays_coord[0], arrays_coord[1], arrays_coord[2]};
157 verts =
Range(startv, startv + nb_random_points - 1);
158 for (
int n = 0;
n != nb_random_points; ++
n) {
159 t_coords(0) = 0;
160 for (auto ii : {1, 2}) {
161 t_coords(ii) = scale_box * (bMax - bMin) *
162 (std::rand() / static_cast<double>(RAND_MAX)) -
163 bMax * scale_box;
164 }
165 ++t_coords;
166 }
168 };
169
170 auto set_positions = [nb_random_points,
dt, velocity_scale](
171 moab::Interface &moab, auto &arrays_coord) {
174 arrays_coord[0], arrays_coord[1], arrays_coord[2]};
176 &init_pos(0, 0), &init_pos(1, 0), &init_pos(2, 0)};
178 for (
int n = 0;
n != nb_random_points; ++
n) {
179
181 for (auto ii : {0, 1, 2})
182 t_velocity(ii) = (rand() / static_cast<double>(RAND_MAX) - 0.5);
183 t_velocity(
i) /= std::sqrt(t_velocity(
i) * t_velocity(
i));
184 t_init_coords(
i) = t_coords(
i) +
dt * velocity_scale * t_velocity(
i);
185
186 ++t_coords;
187 ++t_init_coords;
188 }
189 return init_pos;
190 };
191
192 moab::Core mb_charged_partices;
193 moab::Interface &moab_charged_partices = mb_charged_partices;
194 vector<double *> arrays_coord;
196 CHKERR create_vertices(moab_charged_partices, verts, arrays_coord);
197 auto init_positions = set_positions(moab, arrays_coord);
198
199 auto get_t_coords = [&]() {
201 arrays_coord[0], arrays_coord[1], arrays_coord[2]);
202 };
203
204 auto get_t_init_coords = [&]() {
206 &init_positions(0, 0), &init_positions(1, 0), &init_positions(2, 0));
207 };
208
209 auto calc_rhs = [&](auto &t_p, auto &t_init_p, auto &t_B) {
214 t_rhs(
k) = (2 * t_p(
k) - t_init_p(
k)) /
dt -
216 return t_rhs;
217 };
218
219 auto calc_lhs = [&](auto &t_B) {
225 for (auto ii : {0, 1, 2})
226 t_lhs(ii, ii) += 1 /
dt;
227 return t_lhs;
228 };
229
230
231
232
233
234
235
236
237
238
239
240
241 auto is_out = [&](auto &t_p) {
242 for (
int i : {0, 1, 2})
244 return true;
245 }
else if (t_p(
i) < bMin) {
246 return true;
247 }
248 return false;
249 };
250
251 auto cache_ptr = boost::make_shared<CacheTuple>();
253
254 auto calc_position = [&]() {
255 auto t_p = get_t_coords();
256 auto t_init_p = get_t_init_coords();
259
260 for (
int n = 0;
n != nb_random_points; ++
n) {
261
262 if (is_out(t_p)) {
263 ++t_p;
264 ++t_init_p;
265 continue;
266 }
267
268 std::array<double, 3> point = {t_p(0), t_p(1), t_p(2)};
269 data_at_pts->setEvalPoints(point.data(), 1);
270
272 point.data(),
dist, prb_ptr->
getName(),
"MAGNETIC", data_at_pts,
275
277
279 for (int ii : {0, 1, 2})
280 t_B(ii) = (*B)(ii, 0);
281 else
283
284 t_B(
i) *= magnetic_field_scale * 0.5;
285
286 auto t_rhs = calc_rhs(t_p, t_init_p, t_B);
287 auto t_lhs = calc_lhs(t_B);
288
289 double det;
293
294 t_init_p(
i) = t_p(
i);
295 t_p(
i) = t_inv_lhs(
i,
j) * t_rhs(
j);
296
297
298
299 ++t_p;
300 ++t_init_p;
301 }
302 };
303
304 for (
int t = 0;
t != nb_steps; ++
t) {
305
306 std::string print_step =
307 "Step : " + boost::lexical_cast<std::string>(
t) +
"\r";
308 std::cout << print_step << std::flush;
309
310 calc_position();
311
312 if ((
t % mod_step) == 0) {
313
314 CHKERR moab_charged_partices.write_file(
315 (
"step_" + boost::lexical_cast<std::string>(
t / mod_step) +
".vtk")
316 .c_str(),
317 "VTK", "");
318 }
319 }
320
321 std::cout << endl;
322
324 }
326
328
329 return 0;
330}
#define CATCH_ERRORS
Catch errors.
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
FTensor::Index< 'i', SPACE_DIM > i
const double n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
MoFEMErrorCode invertTensor3by3(ublas::matrix< T, L, A > &jac_data, ublas::vector< T, A > &det_data, ublas::matrix< T, L, A > &inv_jac_data)
Calculate inverse of tensor rank 2 at integration points.
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
constexpr double t
plate stiffness
virtual MoFEMErrorCode cache_problem_entities(const std::string prb_name, CacheTupleWeakPtr cache_ptr)=0
Cache variables.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual int get_comm_rank() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
virtual MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
Operator for bi-linear form, usually to calculate values on left hand side.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
const VectorDouble & getFieldData() const
Get DOF values on entity.
Field evaluator interface.
MoFEMErrorCode evalFEAtThePoint(const double *const point, const double distance, const std::string problem, const std::string finite_element, boost::shared_ptr< SetIntegrationPtsMethodData > data_ptr, int lower_rank, int upper_rank, boost::shared_ptr< CacheTuple > cache_ptr, MoFEMTypes bh=MF_EXIST, VERBOSITY_LEVELS verb=QUIET)
Evaluate field at actbitray position.
boost::shared_ptr< SPD > getData(const double *ptr=nullptr, const int nb_eval_points=0, const double eps=1e-12, VERBOSITY_LEVELS verb=QUIET)
Get the Data object.
MoFEMErrorCode buildTree(boost::shared_ptr< SetIntegrationPtsMethodData > spd_ptr, const std::string finite_element)
Build spatial tree.
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.
RuleHookFun getRuleHook
Hook to get rule.
Calculate curl of vector field.
keeps basic data about problem
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.