v0.14.0
Loading...
Searching...
No Matches
EP_Operators.hpp
Go to the documentation of this file.
1#ifndef __EPOPERATORS_HPP__
2#define __EPOPERATORS_HPP__
3
4#include <stdlib.h>
6
7namespace ElecPhys{
10
13
14using EntData = DataForcesAndSourcesCore::EntData;
15
16const double essen_value = 0.0;
17const int save_every_nth_step = 4;
18
20
21double Heaviside(const double pt) {
22 if (pt >= 0.0) {
23 return 1;
24 } else {
25 return 0;
26 }
27}
28struct Params {
33
34 double D_tilde; // species mobility
35
37 : U_0(0.0), U_u(1.58), theta_v(0.3), theta_w(0.015), theta_vMinus(0.015), theta_0(0.006), tau_v1Minus(60),
38 tau_v2Minus(1150.0), tau_vPlus(1.4506), tau_w1Minus(70.0), tau_w2Minus(20.0), K_wMinus(65.0), U_wMinus(0.03), tau_wPlus(280),
39 tau_fi(0.11), tau_01(6.0), tau_02(6.0), tau_s01(43.0), tau_s02(0.2), K_s0(2.0), U_s0(0.65), tau_s1(2.7342), tau_s2(3),
40 K_s(2.0994), U_s(0.9087), tau_si(2.8723), tau_wInf(0.07), W_infStar(0.94), D_tilde(1.19) {}
41
42inline double get_v_inf(const double u) const {
43 if (u < theta_vMinus) {
44 return 1;
45 } else {
46 return 0;
47 }
48 }
49
50
51inline double get_w_inf(const double u) const {
52 return (1 - Heaviside(u - theta_0)) * (1 - u / tau_wInf) +
54 }
55
56inline double get_tau_vMinus (const double u) const {
57 return (1 - Heaviside(u - theta_vMinus)) * tau_v1Minus +
59 }
60
61
62inline double get_tau_wMinus(const double u) const {
63 return tau_w1Minus +
65 (1 + tanh(K_wMinus * (u - U_wMinus))) * 0.5;
66 }
67
68inline double get_tau_so(const double u) const {
69 return tau_s01 + (tau_s02 - tau_s01) *
70 (1 + tanh(K_s0 * (u - U_s0))) *
71 0.5;
72 }
73
74inline double get_tau_s(const double u) const {
75 return (1 - Heaviside(u - theta_w)) * tau_s1 +
77 }
78
79inline double get_tau_0(const double u) const {
80 return (1 - Heaviside(u - theta_0)) * tau_s2 +
82 }
83
84inline double get_J_fi(const double u, const double v, const double w,
85 const double s) const {
86 return -v * Heaviside(u - theta_v) * (u - theta_v) *
87 (U_u - u) / tau_fi;
88 }
89
90inline double get_J_so(const double u, const double v, const double w,
91 const double s) const {
92 return (u - U_0) * (1 - Heaviside(u - theta_w)) / get_tau_0(u) +
94 }
95
96inline double get_J_si(const double u, const double v, const double w,
97 const double s) const {
98 return -Heaviside(u - theta_w) * w * s / tau_si;
99 }
100
101inline double get_rhs_u(const double u, const double v, const double w,
102 const double s) const {
103 return -(get_J_fi(u, v, w, s) + get_J_so(u, v, w, s) + get_J_si(u, v, w, s));
104 }
105
106inline double get_rhs_v(const double u, const double v, const double w,
107 const double s) const {
108 return (1 - Heaviside(u - theta_v)) * (get_v_inf(u) - v) /
109 get_tau_vMinus(u) -
110 Heaviside(u - theta_v) * v / tau_vPlus;
111 }
112
113inline double get_rhs_w(const double u, const double v, const double w,
114 const double s) const {
115 return (1 - Heaviside(u - theta_w)) * (get_w_inf(u) - w) /
116 get_tau_wMinus(u) -
117 Heaviside(u - theta_w) * w / tau_wPlus;
118 }
119
120inline double get_rhs_s(const double u, const double v, const double w,
121 const double s) const {
122 return ((1 + tanh(K_s * (u - U_s))) * 0.5 - s) / get_tau_s(u);
123 }
124};
125
129
132
134
137
139 jac.resize(3, 3, false);
140 inv_jac.resize(3, 3, false);
141 }
142};
143
145
146
147
148
149
150
151
152// struct OpComputeSlowValue : public OpVolEle {
153// OpComputeSlowValue(boost::shared_ptr<PreviousData> &datau,
154// boost::shared_ptr<PreviousData> &datav,
155// boost::shared_ptr<PreviousData> &dataw,
156// boost::shared_ptr<PreviousData> &datas)
157// : OpVolEle("u", OpFaceEle::OPROW), commonDatau(datau), commonDatav(datav),
158// commonDataw(dataw), commonDatas(datas){}
159
160// private:
161// std::string massField;
162// boost::shared_ptr<PreviousData> commonDatau;
163// boost::shared_ptr<PreviousData> commonDatav;
164// boost::shared_ptr<PreviousData> commonDataw;
165// boost::shared_ptr<PreviousData> commonDatas;
166// };
167
168struct OpEssentialBC : public OpFaceEle {
170 : OpFaceEle("f", OpFaceEle::OPROW),
172
173 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
175 int nb_dofs = data.getIndices().size();
176
177 if (nb_dofs) {
179 bool is_essential =
180 (essential_bd_ents.find(fe_ent) != essential_bd_ents.end());
181 if (is_essential) {
182 int nb_gauss_pts = getGaussPts().size2();
183 int size2 = data.getN().size2();
184 if (3 * nb_dofs != static_cast<int>(data.getN().size2()))
185 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
186 "wrong number of dofs");
187 nN.resize(nb_dofs, nb_dofs, false);
188 nF.resize(nb_dofs, false);
189 nN.clear();
190 nF.clear();
191
192 auto t_row_tau = data.getFTensor1N<3>();
193
194 double *normal_ptr;
195 if (getNormalsAtGaussPts().size1() == (unsigned int)nb_gauss_pts) {
196 // HO geometry
197 normal_ptr = &getNormalsAtGaussPts(0)[0];
198 } else {
199 // Linear geometry, i.e. constant normal on face
200 normal_ptr = &getNormal()[0];
201 }
202 // set tensor from pointer
203 FTensor::Tensor1<const double *, 3> t_normal(normal_ptr, &normal_ptr[1],
204 &normal_ptr[2], 3);
205
206 auto t_w = getFTensor0IntegrationWeight();
207 const double vol = getMeasure();
208 double nrm2 = 0;
209 for (int gg = 0; gg < nb_gauss_pts; gg++) {
210 if (gg == 0) {
211 nrm2 = sqrt(t_normal(i) * t_normal(i));
212 }
213 const double a = t_w * vol;
214 for (int rr = 0; rr != nb_dofs; rr++) {
216 &data.getVectorN<3>(gg)(0, HVEC0),
217 &data.getVectorN<3>(gg)(0, HVEC1),
218 &data.getVectorN<3>(gg)(0, HVEC2), 3);
219 nF[rr] += a * essen_value * t_row_tau(i) * t_normal(i) / nrm2;
220 for (int cc = 0; cc != nb_dofs; cc++) {
221 nN(rr, cc) += a * (t_row_tau(i) * t_normal(i)) *
222 (t_col_tau(i) * t_normal(i)) / (nrm2 * nrm2);
223 ++t_col_tau;
224 }
225 ++t_row_tau;
226 }
227 // If HO geometry increment t_normal to next integration point
228 if (getNormalsAtGaussPts().size1() == (unsigned int)nb_gauss_pts) {
229 ++t_normal;
230 nrm2 = sqrt(t_normal(i) * t_normal(i));
231 }
232 ++t_w;
233 }
234
236 cholesky_solve(nN, nF, ublas::lower());
237
238 for (auto &dof : data.getFieldDofs()) {
239 dof->getFieldData() = nF[dof->getEntDofIdx()];
240 }
241 }
242 }
244 }
245
246private:
250};
251
252struct OpInitialMass : public OpVolEle {
253 OpInitialMass(std::string field_name, Range &inner_surface, double &inits)
254 : OpVolEle(field_name, OpVolEle::OPROW), innerSurface(inner_surface), iNits(inits)
256
257 }
261 double iNits;
262 std::string fieldName;
263 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
265
266 int nb_dofs = data.getFieldData().size();
267 // cout << "Field \t init_val" << endl;
268 // cout << fieldName << " \t " << iNits << endl;
269 if (nb_dofs) {
270 CHKERR solveInitial(data);
271 }
273 }
274
277 int nb_dofs = data.getFieldData().size();
278 // EntityHandle fe_ent = getFEEntityHandle();
279 // bool is_inner_side = (innerSurface.find(fe_ent) != innerSurface.end());
280 bool is_inner_side = true;
281 if (is_inner_side) {
282 int nb_gauss_pts = getGaussPts().size2();
283 if (nb_dofs != static_cast<int>(data.getN().size2()))
284 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
285 "wrong number of dofs");
286 nN.resize(nb_dofs, nb_dofs, false);
287 nF.resize(nb_dofs, false);
288 nN.clear();
289 nF.clear();
290
291
292
293 auto t_row_mass = data.getFTensor0N();
294 auto t_w = getFTensor0IntegrationWeight();
295 const double vol = getMeasure();
296 for (int gg = 0; gg < nb_gauss_pts; gg++) {
297 const double a = t_w * vol;
298 for (int rr = 0; rr != nb_dofs; rr++) {
299 auto t_col_mass = data.getFTensor0N(gg, 0);
300 nF[rr] += a * iNits * t_row_mass;
301 for (int cc = 0; cc != nb_dofs; cc++) {
302 nN(rr, cc) += a * t_row_mass * t_col_mass;
303 ++t_col_mass;
304 }
305 ++t_row_mass;
306 }
307 ++t_w;
308 }
309
311 cholesky_solve(nN, nF, ublas::lower());
312 for (auto &dof : data.getFieldDofs()) {
313 dof->getFieldData() = nF[dof->getEntDofIdx()];
314 }
315 }
317 }
318};
319
321{
322 OpAssembleSlowRhsV(boost::shared_ptr<PreviousData> &data_u,
323 boost::shared_ptr<PreviousData> &data_v,
324 boost::shared_ptr<PreviousData> &data_w,
325 boost::shared_ptr<PreviousData> &data_s)
326 : OpVolEle("u", OpVolEle::OPROW), dataU(data_u)
327 , dataV(data_v), dataW(data_w), dataS(data_s) {
328 }
329
330 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
332 // cerr << "In OpAssembleSlowRhsV...." << endl;
333 const int nb_dofs = data.getIndices().size();
334 if (nb_dofs) {
335 // cerr << "In SlowRhsV..." << endl;
336 if (nb_dofs != static_cast<int>(data.getN().size2()))
337 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
338 "wrong number of dofs");
339
340 unsigned int nstep = getFEMethod()->ts_step;
341 vecF.resize(nb_dofs, false);
342 mat.resize(nb_dofs, nb_dofs, false);
343 vecF.clear();
344 mat.clear();
345 const int nb_integration_pts = getGaussPts().size2();
346 auto t_val_u = getFTensor0FromVec(dataU->mass_values);
347 auto t_val_v = getFTensor0FromVec(dataV->mass_values);
348 auto t_val_w = getFTensor0FromVec(dataW->mass_values);
349 auto t_val_s = getFTensor0FromVec(dataS->mass_values);
350
351 auto t_row_v_base = data.getFTensor0N();
352 auto t_w = getFTensor0IntegrationWeight();
353 const double vol = getMeasure();
354
355 bool is_u = ((nstep + 0) % 4) == 0;
356 bool is_v = ((nstep + 3) % 4) == 0;
357 bool is_w = ((nstep + 2) % 4) == 0;
358 bool is_s = ((nstep + 1) % 4) == 0;
359
360 auto t_coords = getFTensor1CoordsAtGaussPts();
361 for (int gg = 0; gg != nb_integration_pts; ++gg) {
362 const double a = vol * t_w;
363
364 double rhs_u = params.get_rhs_u(t_val_u, t_val_v, t_val_w, t_val_s);
365 double rhs_v = params.get_rhs_v(t_val_u, t_val_v, t_val_w, t_val_s);
366 double rhs_w = params.get_rhs_w(t_val_u, t_val_v, t_val_w, t_val_s);
367 double rhs_s = params.get_rhs_s(t_val_u, t_val_v, t_val_w, t_val_s);
368
369 // cout << "rhs_u : " << rhs_u << endl;
370 // cout << "rhs_v : " << rhs_v << endl;
371 // cout << "rhs_w : " << rhs_w << endl;
372 // cout << "rhs_s : " << rhs_s << endl;
373 for (int rr = 0; rr != nb_dofs; ++rr) {
374 auto t_col_v_base = data.getFTensor0N(gg, 0);
375
376 if (is_u) {
377 vecF[rr] += a * rhs_u * t_row_v_base;
378 // cout << "U" << " rhs_u : " << rhs_u << endl;
379 }
380 else if (is_v) {
381 vecF[rr] += a * rhs_v * t_row_v_base;
382 // cout << "V" << " rhs_v : " << rhs_v << endl;
383 }
384 else if (is_w) {
385 vecF[rr] += a * rhs_w * t_row_v_base;
386 // cout << "W" << " rhs_w : " << rhs_w << endl;
387 }
388 else if (is_s) {
389 vecF[rr] += a * rhs_s * t_row_v_base;
390 // cout << "S" << " rhs_s : " << rhs_s << endl;
391 }
392 for (int cc = 0; cc != nb_dofs; ++cc) {
393 mat(rr, cc) += a * t_row_v_base * t_col_v_base;
394 ++t_col_v_base;
395 }
396 ++t_row_v_base;
397 }
398 ++t_val_u;
399 ++t_val_v;
400 ++t_val_w;
401 ++t_val_s;
402 ++t_w;
403 }
405 cholesky_solve(mat, vecF, ublas::lower());
406 if(is_u){
407 cout << "U ---> ";
408 } else if (is_v) {
409 cout << "V ---> ";
410 } else if (is_w) {
411 cout << "W ---> ";
412 } else if (is_s) {
413 cout << "S ---> ";
414 }
415
416 cout << "nstep : " << nstep << " vecF : " << vecF << endl;
417 CHKERR VecSetOption(getFEMethod()->ts_F, VEC_IGNORE_NEGATIVE_INDICES,
418 PETSC_TRUE);
419 CHKERR VecSetValues(getFEMethod()->ts_F, data, &*vecF.begin(),
420 ADD_VALUES);
421 }
423 }
424
425
426
427private:
428 boost::shared_ptr<PreviousData> dataU;
429 boost::shared_ptr<PreviousData> dataV;
430 boost::shared_ptr<PreviousData> dataW;
431 boost::shared_ptr<PreviousData> dataS;
434
438};
439
440template <int dim>
442{
443 OpAssembleStiffRhsTau(boost::shared_ptr<PreviousData> &data_u,
444 boost::shared_ptr<PreviousData> &data_v,
445 boost::shared_ptr<PreviousData> &data_w,
446 boost::shared_ptr<PreviousData> &data_s)
447 : OpFaceEle("f", OpFaceEle::OPROW), dataU(data_u), dataV(data_v),
448 dataW(data_w), dataS(data_s) {
449 }
450
451 // VectorDouble div_base;
452
453 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
455 unsigned int nstep = getFEMethod()->ts_step;
456 bool is_u = ((nstep + 0) % 4) == 0;
457 bool is_v = ((nstep + 3) % 4) == 0;
458 bool is_w = ((nstep + 2) % 4) == 0;
459 bool is_s = ((nstep + 1) % 4) == 0;
460
461
462 const int nb_dofs = data.getIndices().size();
463 if (nb_dofs) {
464 vecF.resize(nb_dofs, false);
465 vecF.clear();
466
467 const int nb_integration_pts = getGaussPts().size2();
468 auto t_flux_u = getFTensor1FromMat<3>(dataU->flux_values);
469 auto t_flux_v = getFTensor1FromMat<3>(dataV->flux_values);
470 auto t_flux_w = getFTensor1FromMat<3>(dataW->flux_values);
471 auto t_flux_s = getFTensor1FromMat<3>(dataS->flux_values);
472
473 auto t_val_u = getFTensor0FromVec(dataU->mass_values);
474 auto t_val_v = getFTensor0FromVec(dataV->mass_values);
475 auto t_val_w = getFTensor0FromVec(dataW->mass_values);
476 auto t_val_s = getFTensor0FromVec(dataS->mass_values);
477
478
479
480 auto t_tau_base = data.getFTensor1N<3>();
481
482 auto t_tau_grad = data.getFTensor2DiffN<3, 3>();
483
484 auto t_w = getFTensor0IntegrationWeight();
485 const double vol = getMeasure();
486
487 for (int gg = 0; gg < nb_integration_pts; ++gg) {
488 const double K_inv = 1. / params.D_tilde;
489 const double a = vol * t_w;
490
491
492
493 for (int rr = 0; rr < nb_dofs; ++rr) {
494 double div_base = t_tau_grad(0, 0) + t_tau_grad(1, 1) + t_tau_grad(2, 2);
495 if(is_u){
496 vecF[rr] += (K_inv * t_tau_base(i) * t_flux_u(i) -
497 div_base * t_val_u) * a;
498 }
499 else if(is_v){
500 vecF[rr] += (K_inv * t_tau_base(i) * t_flux_v(i) -
501 div_base * t_val_v) * a;
502 }
503 else if(is_w){
504 vecF[rr] +=
505 (K_inv * t_tau_base(i) * t_flux_w(i) - div_base * t_val_w) * a;
506 }
507 else if(is_s){
508 vecF[rr] += (K_inv * t_tau_base(i) * t_flux_s(i) -
509 div_base * t_val_s) * a;
510 }
511
512 // cout << "U\tV\tW\tS" << endl;
513 // cout << t_val_u << "\t" << t_val_v << "\t" << t_val_w << "\t" << t_val_s << "\t" << vecF[rr] << endl;
514
515 ++t_tau_base;
516 ++t_tau_grad;
517 }
518 ++t_flux_u;
519 ++t_flux_v;
520 ++t_flux_w;
521 ++t_flux_s;
522
523 ++t_val_u;
524 ++t_val_v;
525 ++t_val_w;
526 ++t_val_s;
527 ++t_w;
528 }
529 CHKERR VecSetOption(getFEMethod()->ts_F, VEC_IGNORE_NEGATIVE_INDICES,
530 PETSC_TRUE);
531 CHKERR VecSetValues(getFEMethod()->ts_F, data, &*vecF.begin(),
532 ADD_VALUES);
533 }
535 }
536
537private:
538 boost::shared_ptr<PreviousData> dataU;
539 boost::shared_ptr<PreviousData> dataV;
540 boost::shared_ptr<PreviousData> dataW;
541 boost::shared_ptr<PreviousData> dataS;
543};
544
545template <int dim>
547{
548 OpAssembleStiffRhsV(boost::shared_ptr<PreviousData> &data_u,
549 boost::shared_ptr<PreviousData> &data_v,
550 boost::shared_ptr<PreviousData> &data_w,
551 boost::shared_ptr<PreviousData> &data_s)
552 : OpVolEle("u", OpVolEle::OPROW), dataU(data_u), dataV(data_v), dataW(data_w),
553 dataS(data_s) {}
554
555 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
557 unsigned int nstep = getFEMethod()->ts_step;
558 const int nb_dofs = data.getIndices().size();
559 // cerr << "In StiffRhsV ..." << endl;
560 if (nb_dofs) {
561
562
563 vecF.resize(nb_dofs, false);
564 vecF.clear();
565 const int nb_integration_pts = getGaussPts().size2();
566 auto t_dot_u = getFTensor0FromVec(dataU->mass_dots);
567 auto t_dot_v = getFTensor0FromVec(dataV->mass_dots);
568 auto t_dot_w = getFTensor0FromVec(dataW->mass_dots);
569 auto t_dot_s = getFTensor0FromVec(dataS->mass_dots);
570
571 auto t_div_u = getFTensor0FromVec(dataU->flux_divs);
572 auto t_div_v = getFTensor0FromVec(dataV->flux_divs);
573 auto t_div_w = getFTensor0FromVec(dataW->flux_divs);
574 auto t_div_s = getFTensor0FromVec(dataS->flux_divs);
575
576 auto t_row_v_base = data.getFTensor0N();
577 auto t_w = getFTensor0IntegrationWeight();
578 const double vol = getMeasure();
579
580 auto t_coords = getFTensor1CoordsAtGaussPts();
581
582 bool is_u = ((nstep + 0) % 4) == 0;
583 bool is_v = ((nstep + 3) % 4) == 0;
584 bool is_w = ((nstep + 2) % 4) == 0;
585 bool is_s = ((nstep + 1) % 4) == 0;
586
587 for (int gg = 0; gg < nb_integration_pts; ++gg) {
588 const double a = vol * t_w;
589
590 for (int rr = 0; rr < nb_dofs; ++rr) {
591
592 if (is_u) {
593 vecF[rr] += (t_row_v_base * (t_dot_u + t_div_u)) * a;
594 } else if (is_v) {
595 vecF[rr] += (t_row_v_base * t_dot_v) * a;
596 } else if (is_w) {
597 vecF[rr] += (t_row_v_base * t_dot_w) * a;
598 } else if (is_s) {
599 vecF[rr] += (t_row_v_base * t_dot_s) * a;
600 }
601 ++t_row_v_base;
602 }
603 ++t_dot_u;
604 ++t_dot_v;
605 ++t_dot_w;
606 ++t_dot_s;
607
608 ++t_div_u;
609 ++t_div_v;
610 ++t_div_w;
611 ++t_div_s;
612 ++t_w;
613 }
614 // cout << "VecF : " << vecF << endl;
615 CHKERR VecSetOption(getFEMethod()->ts_F, VEC_IGNORE_NEGATIVE_INDICES,
616 PETSC_TRUE);
617 CHKERR VecSetValues(getFEMethod()->ts_F, data, &*vecF.begin(),
618 ADD_VALUES);
619 }
621 }
622
623private:
624 boost::shared_ptr<PreviousData> dataU;
625 boost::shared_ptr<PreviousData> dataV;
626 boost::shared_ptr<PreviousData> dataW;
627 boost::shared_ptr<PreviousData> dataS;
629
630};
631
632template <int dim>
633struct OpAssembleLhsTauTau : OpVolEle // A_TauTau_1
634{
636 : OpVolEle("f", "f", OpVolEle::OPROWCOL){
637 sYmm = true;
638 }
639
640 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
641 EntityType col_type, EntData &row_data,
642 EntData &col_data) {
644 unsigned int nstep = getFEMethod()->ts_step;
645 const int nb_row_dofs = row_data.getIndices().size();
646 const int nb_col_dofs = col_data.getIndices().size();
647
648 if (nb_row_dofs && nb_col_dofs) {
649
650 mat.resize(nb_row_dofs, nb_col_dofs, false);
651 mat.clear();
652 const int nb_integration_pts = getGaussPts().size2();
653
654 auto t_row_tau_base = row_data.getFTensor1N<3>();
655
656 auto t_w = getFTensor0IntegrationWeight();
657 const double vol = getMeasure();
658
659 for (int gg = 0; gg != nb_integration_pts; ++gg) {
660 const double a = vol * t_w;
661 const double K_inv = 1. / params.D_tilde;
662 for (int rr = 0; rr != nb_row_dofs; ++rr) {
663 auto t_col_tau_base = col_data.getFTensor1N<3>(gg, 0);
664 for (int cc = 0; cc != nb_col_dofs; ++cc) {
665 mat(rr, cc) += (K_inv * t_row_tau_base(i) * t_col_tau_base(i)) * a;
666 ++t_col_tau_base;
667 }
668 ++t_row_tau_base;
669 }
670 ++t_w;
671 }
672 CHKERR MatSetValues(getFEMethod()->ts_B, row_data, col_data, &mat(0, 0),
673 ADD_VALUES);
674 if (row_side != col_side || row_type != col_type) {
675 transMat.resize(nb_col_dofs, nb_row_dofs, false);
676 noalias(transMat) = trans(mat);
677 CHKERR MatSetValues(getFEMethod()->ts_B, col_data, row_data,
678 &transMat(0, 0), ADD_VALUES);
679 }
680 }
682 }
683
684private:
686};
687
688template <int dim>
689struct OpAssembleLhsTauV : OpVolEle // E_TauV
690{
692 : OpVolEle("f", "u", OpVolEle::OPROWCOL){
693 sYmm = false;
694 }
695
696 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
697 EntityType col_type, EntData &row_data,
698 EntData &col_data) {
700 unsigned int nstep = getFEMethod()->ts_step;
701 const int nb_row_dofs = row_data.getIndices().size();
702 const int nb_col_dofs = col_data.getIndices().size();
703
704 if (nb_row_dofs && nb_col_dofs) {
705
706 mat.resize(nb_row_dofs, nb_col_dofs, false);
707 mat.clear();
708 const int nb_integration_pts = getGaussPts().size2();
709 auto t_w = getFTensor0IntegrationWeight();
710 auto t_row_tau_base = row_data.getFTensor1N<3>();
711
712 auto t_row_tau_grad = row_data.getFTensor2DiffN<3, 3>();
713
714 const double vol = getMeasure();
715
716 for (int gg = 0; gg != nb_integration_pts; ++gg) {
717 const double a = vol * t_w;
718 for (int rr = 0; rr != nb_row_dofs; ++rr) {
719 auto t_col_v_base = col_data.getFTensor0N(gg, 0);
720 for (int cc = 0; cc != nb_col_dofs; ++cc) {
721 double div_row_base = t_row_tau_grad(0, 0) + t_row_tau_grad(1, 1) + t_row_tau_grad(2, 2);
722 mat(rr, cc) += - (div_row_base * t_col_v_base) * a;
723 ++t_col_v_base;
724 }
725 ++t_row_tau_base;
726 ++t_row_tau_grad;
727 }
728 ++t_w;
729 }
730 CHKERR MatSetValues(getFEMethod()->ts_B, row_data, col_data, &mat(0, 0),
731 ADD_VALUES);
732 }
734 }
735
736private:
738};
739
740struct OpAssembleLhsVTau : OpVolEle // C_VTau
741{
743 : OpVolEle("u", "f", OpVolEle::OPROWCOL) {
744 sYmm = false;
745 }
746
747 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
748 EntityType col_type, EntData &row_data,
749 EntData &col_data) {
751 unsigned int nstep = getFEMethod()->ts_step;
752 bool is_u = ((nstep + 0) % 4) == 0;
753 const int nb_row_dofs = row_data.getIndices().size();
754 const int nb_col_dofs = col_data.getIndices().size();
755
756 if (nb_row_dofs && nb_col_dofs) {
757 mat.resize(nb_row_dofs, nb_col_dofs, false);
758 mat.clear();
759 const int nb_integration_pts = getGaussPts().size2();
760 auto t_w = getFTensor0IntegrationWeight();
761 auto t_row_v_base = row_data.getFTensor0N();
762 const double vol = getMeasure();
763
764 for (int gg = 0; gg != nb_integration_pts; ++gg) {
765 const double a = vol * t_w;
766 for (int rr = 0; rr != nb_row_dofs; ++rr) {
767 auto t_col_tau_grad = col_data.getFTensor2DiffN<3, 3>(gg, 0);
768 for (int cc = 0; cc != nb_col_dofs; ++cc) {
769 double div_col_base =
770 t_col_tau_grad(0, 0) + t_col_tau_grad(1, 1) + t_col_tau_grad(2, 2);
771 if(is_u){
772 mat(rr, cc) += (t_row_v_base * div_col_base) * a;
773 }else{
774 mat(rr, cc) = 0;
775 }
776
777 ++t_col_tau_grad;
778 }
779 ++t_row_v_base;
780 }
781 ++t_w;
782 }
783 CHKERR MatSetValues(getFEMethod()->ts_B, row_data, col_data, &mat(0, 0),
784 ADD_VALUES);
785 }
787 }
788
789private:
791};
792
794{
796 : OpVolEle("u", "u", OpVolEle::OPROWCOL) {
797 sYmm = true;
798 }
799
800 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
801 EntityType col_type, EntData &row_data,
802 EntData &col_data) {
804 // cout << "in VV()" << endl;
805 const int nb_row_dofs = row_data.getIndices().size();
806 const int nb_col_dofs = col_data.getIndices().size();
807 if (nb_row_dofs && nb_col_dofs) {
808
809 mat.resize(nb_row_dofs, nb_col_dofs, false);
810 mat.clear();
811 const int nb_integration_pts = getGaussPts().size2();
812
813 auto t_row_v_base = row_data.getFTensor0N();
814
815 auto t_w = getFTensor0IntegrationWeight();
816 const double ts_a = getFEMethod()->ts_a;
817 const double vol = getMeasure();
818
819 for (int gg = 0; gg != nb_integration_pts; ++gg) {
820 const double a = vol * t_w;
821
822 for (int rr = 0; rr != nb_row_dofs; ++rr) {
823 auto t_col_v_base = col_data.getFTensor0N(gg, 0);
824 for (int cc = 0; cc != nb_col_dofs; ++cc) {
825 mat(rr, cc) += (ts_a * t_row_v_base * t_col_v_base) * a;
826
827 ++t_col_v_base;
828 }
829 ++t_row_v_base;
830 }
831 ++t_w;
832 }
833 CHKERR MatSetValues(getFEMethod()->ts_B, row_data, col_data, &mat(0, 0),
834 ADD_VALUES);
835 if (row_side != col_side || row_type != col_type) {
836 transMat.resize(nb_col_dofs, nb_row_dofs, false);
837 noalias(transMat) = trans(mat);
838 CHKERR MatSetValues(getFEMethod()->ts_B, col_data, row_data,
839 &transMat(0, 0), ADD_VALUES);
840 }
841 }
843 }
844
845private:
847};
848
849// this operator takes care of copying the "u" dofs to the data fields "U", "V", "W", or "S"
850// depending of the time step number
852 OpDamp_dofs_to_field_data(std::string data_field_name)
853 : OpVolEle("u", data_field_name, OpVolEle::OPROWCOL)
854 , dataFieldName(data_field_name) {
855 // cout << "In OpDamp() " << endl;
856 }
857 std::string dataFieldName;
858 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
859 EntityType col_type, EntData &row_data,
860 EntData &col_data) {
862 // cout << "in doWork() of OpDamp()" << endl;
863 unsigned int nstep = getFEMethod()->ts_step;
864 bool is_u_U = (((nstep + 0) % 4) == 0) && (dataFieldName == "U");
865 bool is_u_V = (((nstep + 3) % 4) == 0) && (dataFieldName == "V");
866 bool is_u_W = (((nstep + 2) % 4) == 0) && (dataFieldName == "W");
867 bool is_u_S = (((nstep + 1) % 4) == 0) && (dataFieldName == "S");
868 const int nb_row_dofs = row_data.getIndices().size();
869 const int nb_col_dofs = col_data.getIndices().size();
870 bool are_equal = (nb_row_dofs == nb_col_dofs);
871 if (nb_row_dofs && nb_col_dofs && are_equal) {
872 if ((nstep > 0) && (is_u_U || is_u_V || is_u_W || is_u_S)) {
873 for (int ind = 0; ind < nb_row_dofs; ++ind) {
874 col_data.getFieldDofs()[ind]->getFieldData() =
875 row_data.getFieldData()[ind];
876
877 // cout << "u : " << col_data.getFieldDofs()[ind]->getFieldData() << endl;
878 // cout << dataFieldName <<" : " << col_data.getFieldDofs()[ind]->getFieldData() << endl;
879 }
880 }
881 }
883 }
884};
885
886struct Monitor : public FEMethod {
887 Monitor(MPI_Comm &comm, const int &rank, SmartPetscObj<DM> &dm,
888 boost::shared_ptr<PostProcVolumeOnRefinedMesh> &post_proc)
889 : cOmm(comm), rAnk(rank), dM(dm), postProc(post_proc){};
894 bool is_u = ((ts_step + 0) % 4) == 0;
895
896
897 if (is_u) {
898 int step = (int)((ts_step) / 4);
900 CHKERR postProc->writeFile(
901 "out_level_" + boost::lexical_cast<std::string>(ts_step) + ".h5m");
902 }
904 }
905
906private:
908
909 boost::shared_ptr<PostProcVolumeOnRefinedMesh> postProc;
910 MPI_Comm cOmm;
911 const int rAnk;
912};
913};
914
915#endif //__EPOPERATORS_HPP__
constexpr double a
void cholesky_solve(const TRIA &L, VEC &x, ublas::lower)
solve system L L^T x = b inplace
Definition: cholesky.hpp:221
size_t cholesky_decompose(const MATRIX &A, TRIA &L)
decompose the symmetric positive definit matrix A into product L L^T.
Definition: cholesky.hpp:52
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
@ HVEC0
Definition: definitions.h:186
@ HVEC1
Definition: definitions.h:186
@ HVEC2
Definition: definitions.h:186
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition: DMMoFEM.cpp:572
const double v
phase velocity of light in medium (cm/ns)
double Heaviside(const double pt)
const int save_every_nth_step
const double essen_value
FTensor::Index< 'i', 3 > i
Params params
DataForcesAndSourcesCore::EntData EntData
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
Definition: Templates.hpp:135
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
constexpr auto field_name
boost::shared_ptr< PostProcVolumeOnRefinedMesh > postProc
SmartPetscObj< DM > dM
MoFEMErrorCode preProcess()
function is run at the beginning of loop
MoFEMErrorCode postProcess()
function is run at the end of loop
Monitor(MPI_Comm &comm, const int &rank, SmartPetscObj< DM > &dm, boost::shared_ptr< PostProcVolumeOnRefinedMesh > &post_proc)
MoFEMErrorCode operator()()
function is run for every finite element
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
boost::shared_ptr< PreviousData > dataU
boost::shared_ptr< PreviousData > dataW
boost::shared_ptr< PreviousData > dataV
boost::shared_ptr< PreviousData > dataS
FTensor::Number< 2 > NZ
FTensor::Number< 1 > NY
FTensor::Number< 0 > NX
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpAssembleSlowRhsV(boost::shared_ptr< PreviousData > &data_u, boost::shared_ptr< PreviousData > &data_v, boost::shared_ptr< PreviousData > &data_w, boost::shared_ptr< PreviousData > &data_s)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< PreviousData > dataU
boost::shared_ptr< PreviousData > dataW
boost::shared_ptr< PreviousData > dataS
boost::shared_ptr< PreviousData > dataV
OpAssembleStiffRhsTau(boost::shared_ptr< PreviousData > &data_u, boost::shared_ptr< PreviousData > &data_v, boost::shared_ptr< PreviousData > &data_w, boost::shared_ptr< PreviousData > &data_s)
boost::shared_ptr< PreviousData > dataU
boost::shared_ptr< PreviousData > dataS
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< PreviousData > dataW
boost::shared_ptr< PreviousData > dataV
OpAssembleStiffRhsV(boost::shared_ptr< PreviousData > &data_u, boost::shared_ptr< PreviousData > &data_v, boost::shared_ptr< PreviousData > &data_w, boost::shared_ptr< PreviousData > &data_s)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
OpDamp_dofs_to_field_data(std::string data_field_name)
OpEssentialBC(Range &essential_bd_ents)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode solveInitial(EntData &data)
OpInitialMass(std::string field_name, Range &inner_surface, double &inits)
double get_rhs_u(const double u, const double v, const double w, const double s) const
double get_rhs_s(const double u, const double v, const double w, const double s) const
double get_v_inf(const double u) const
double get_tau_0(const double u) const
double get_tau_s(const double u) const
double get_J_so(const double u, const double v, const double w, const double s) const
double get_w_inf(const double u) const
double get_tau_so(const double u) const
double get_tau_vMinus(const double u) const
double get_J_fi(const double u, const double v, const double w, const double s) const
double get_rhs_v(const double u, const double v, const double w, const double s) const
double get_tau_wMinus(const double u) const
double get_J_si(const double u, const double v, const double w, const double s) const
double get_rhs_w(const double u, const double v, const double w, const double s) const
bool sYmm
If true assume that matrix is symmetric structure.
structure for User Loop Methods on finite elements
MatrixDouble & getNormalsAtGaussPts()
if higher order geometry return normals at Gauss pts.
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
auto getFTensor1CoordsAtGaussPts()
Get coordinates at integration points assuming linear geometry.
auto getFTensor0IntegrationWeight()
Get integration weights.
double getMeasure() const
get measure of element
@ OPROW
operator doWork function is executed on FE rows
@ OPROWCOL
operator doWork is executed on FE rows &columns
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
intrusive_ptr for managing petsc objects
PetscReal ts_a
shift for U_t (see PETSc Time Solver)
PetscInt ts_step
time step number