15 #ifndef __COMPLEX_CONST_AREA_HPP__
16 #define __COMPLEX_CONST_AREA_HPP__
24 double circumcenter[3],
double *xi,
double *
eta,
27 double circumcenter[3],
double *xi,
double *
eta);
49 string lambda_field_name,
int _verbose = 0)
50 :
mField(m_field),
moab(m_field.get_moab()),
C(_C),
Q(_Q),
82 ublas::vector<double, ublas::bounded_array<double, 9>>
coords;
83 ublas::vector<double, ublas::bounded_array<double, 9>>
dofs_X;
84 ublas::vector<double, ublas::bounded_array<double, 3>>
lambda;
88 template <
typename DOFS>
91 return dofs->lower_bound(DofEntity::getLoFieldEntityUId(
bit, ent));
94 template <
typename DOFS>
97 return dofs->upper_bound(DofEntity::getHiFieldEntityUId(
bit, ent));
105 PetscErrorCode
getData(
bool is_that_C_otherwise_dC,
bool trans) {
108 face = numeredEntFiniteElementPtr->getEnt();
121 "face should have three nodes");
125 const auto pos_bit_number =
128 auto row_dofs = getRowDofsPtr();
130 for (
int nn = 0; nn < num_nodes; nn++) {
132 if (is_that_C_otherwise_dC) {
134 auto dit =
loIt(row_dofs, field_bit_number, conn_face[nn]);
135 auto hi_dit =
hiIt(row_dofs, field_bit_number, conn_face[nn]);
139 if (std::distance(dit, hi_dit) > 0) {
140 if (std::distance(dit, hi_dit) != 1) {
142 "data inconsistency, number of dof on node for < %s > "
146 if (dit->get()->getPetscLocalDofIdx() < 0) {
149 "data inconsistency, negative index of local dofs on element");
151 lambda[nn] = dit->get()->getFieldData();
156 if ((!is_that_C_otherwise_dC) || (trans)) {
158 auto dit =
loIt(row_dofs, field_bit_number, conn_face[nn]);
159 auto hi_dit =
hiIt(row_dofs, field_bit_number, conn_face[nn]);
163 if (std::distance(dit, hi_dit) > 0) {
164 if (std::distance(dit, hi_dit) != 1)
166 "data inconsistency, number of dof on node for < %s > "
169 lambda[nn] = dit->get()->getFieldData();
171 auto diit =
loIt(row_dofs, pos_bit_number, conn_face[nn]);
172 auto hi_diit =
hiIt(row_dofs, pos_bit_number, conn_face[nn]);
174 if (std::distance(diit, hi_diit) != 3)
176 "data inconsistency, number of dof on node for "
177 "MESH_NODE_POSITIONS should be 3");
178 for (; diit != hi_diit; diit++) {
179 if (diit->get()->getPetscLocalDofIdx() < 0)
181 "data inconsistency, negative index of local dofs on "
183 assert(nn * 3 + diit->get()->getDofCoeffIdx() < 9);
185 diit->get()->getPetscGlobalDofIdx();
187 diit->get()->getPetscLocalDofIdx();
193 auto col_dofs = getColDofsPtr();
196 auto dit =
loIt(col_dofs, pos_bit_number, conn_face[nn]);
197 auto hi_dit =
hiIt(col_dofs, pos_bit_number, conn_face[nn]);
198 if (std::distance(dit, hi_dit) != 3) {
200 "data inconsistency, number of dof on node for "
201 "MESH_NODE_POSITIONS should be 3, nb dofs = %d",
202 std::distance(dit, hi_dit));
204 for (; dit != hi_dit; dit++) {
205 if (dit->get()->getPetscLocalDofIdx() < 0) {
208 "data inconsistency, negative index of local dofs on element");
210 dofs_X[nn * 3 + dit->get()->getDofCoeffIdx()] =
211 dit->get()->getFieldData();
212 assert(nn * 3 + dit->get()->getDofCoeffIdx() < 9);
214 dit->get()->getPetscGlobalDofIdx();
218 auto dit =
loIt(col_dofs, field_bit_number, conn_face[nn]);
219 auto hi_dit =
hiIt(col_dofs, field_bit_number, conn_face[nn]);
220 if (std::distance(dit, hi_dit) > 0) {
221 if (std::distance(dit, hi_dit) != 1) {
223 "data inconsistency, number of dof on node for < %s > "
227 if (dit->get()->getPetscLocalDofIdx() < 0) {
230 "data inconsistency, negative index of local dofs on element");
246 double *dofs_iX,
double *
C,
double *iC,
247 double *T,
double *iT) {
249 double diffX_xi[3], diffX_eta[3];
250 bzero(diffX_xi, 3 *
sizeof(
double));
251 bzero(diffX_eta, 3 *
sizeof(
double));
252 double i_diffX_xi[3], i_diffX_eta[3];
253 bzero(i_diffX_xi, 3 *
sizeof(
double));
254 bzero(i_diffX_eta, 3 *
sizeof(
double));
255 Range adj_side_elems;
265 bit, &
face, 1, 3, adj_side_elems);
266 adj_side_elems = intersect(
problemTets, adj_side_elems);
268 if (adj_side_elems.size() == 0) {
269 Range adj_tets_on_surface;
273 bit_tet_on_surface, &
face, 1, 3, adj_tets_on_surface,
274 moab::Interface::INTERSECT, 0);
276 adj_side_elems.insert(*adj_tets_on_surface.begin());
278 if (adj_side_elems.size() != 1) {
279 adj_side_elems.clear();
281 bit, &
face, 1, 3, adj_side_elems, moab::Interface::INTERSECT, 5);
283 Range::iterator it = adj_side_elems.begin();
284 for (; it != adj_side_elems.end(); it++) {
287 PetscPrintf(PETSC_COMM_WORLD,
"%lu %lu %lu %lu\n", nodes[0], nodes[1],
290 ParallelComm *pcomm =
292 if (pcomm->rank() == 0) {
302 "expect 1 tet but is %u", adj_side_elems.size());
305 int order[] = {0, 1, 2};
306 if (side_elem != 0) {
307 int side_number, sense, offset;
308 CHKERR moab.side_number(side_elem,
face, side_number, sense, offset);
316 for (
int nn = 0; nn < 3; nn++) {
326 i_diffX_xi[0] += dofs_iX[3 *
order[nn] + 0] *
diffNTRI[2 * nn + 0];
327 i_diffX_xi[1] += dofs_iX[3 *
order[nn] + 1] *
diffNTRI[2 * nn + 0];
328 i_diffX_xi[2] += dofs_iX[3 *
order[nn] + 2] *
diffNTRI[2 * nn + 0];
329 i_diffX_eta[0] += dofs_iX[3 *
order[nn] + 0] *
diffNTRI[2 * nn + 1];
330 i_diffX_eta[1] += dofs_iX[3 *
order[nn] + 1] *
diffNTRI[2 * nn + 1];
331 i_diffX_eta[2] += dofs_iX[3 *
order[nn] + 2] *
diffNTRI[2 * nn + 1];
334 double SpinX_xi[9], SpinX_eta[9];
337 double iSpinX_xi[9], iSpinX_eta[9];
348 x_diffX_eta[0].
r = diffX_eta[0];
349 x_diffX_eta[0].
i = i_diffX_eta[0];
350 x_diffX_eta[1].
r = diffX_eta[1];
351 x_diffX_eta[1].
i = i_diffX_eta[1];
352 x_diffX_eta[2].
r = diffX_eta[2];
353 x_diffX_eta[2].
i = i_diffX_eta[2];
354 cblas_zgemv(CblasRowMajor, CblasNoTrans, 3, 3, &x_one, xSpinX_xi, 3,
355 x_diffX_eta, 1, &x_zero, x_normal, 1);
385 complex<double> x_nrm2;
386 x_nrm2 = sqrt(pow(complex<double>(x_normal[0].
r, x_normal[0].
i), 2) +
387 pow(complex<double>(x_normal[1].
r, x_normal[1].
i), 2) +
388 pow(complex<double>(x_normal[2].
r, x_normal[2].
i), 2));
397 cblas_zgemv(CblasRowMajor, CblasNoTrans, 3, 3, &x_scalar, xSpinX_xi, 3,
398 x_normal, 1, &x_zero, xNSpinX_xi,
400 cblas_zgemv(CblasRowMajor, CblasNoTrans, 3, 3, &x_scalar, xSpinX_eta, 3,
401 x_normal, 1, &x_zero, xNSpinX_eta,
404 bzero(
C, 9 *
sizeof(
double));
406 bzero(iC, 9 *
sizeof(
double));
408 bzero(T, 9 *
sizeof(
double));
410 bzero(iT, 9 *
sizeof(
double));
411 for (
int nn = 0; nn < 3; nn++) {
426 C[3 * nn + 0] =
A[0];
427 C[3 * nn + 1] =
A[1];
428 C[3 * nn + 2] =
A[2];
431 iC[3 * nn + 0] = iA[0];
432 iC[3 * nn + 1] = iA[1];
433 iC[3 * nn + 2] = iA[2];
435 if ((T != NULL) || (iT != NULL)) {
444 cblas_zgemv(CblasRowMajor, CblasNoTrans, 3, 3, &x_scalar, xSpinA, 3,
445 x_normal, 1, &x_zero, xT, 1);
447 T[3 * nn + 0] = xT[0].
r;
448 T[3 * nn + 1] = xT[1].
r;
449 T[3 * nn + 2] = xT[2].
r;
452 iT[3 * nn + 0] = xT[0].
i;
453 iT[3 * nn + 1] = xT[1].
i;
454 iT[3 * nn + 2] = xT[2].
i;
459 cblas_dscal(9, 0.25,
C, 1);
461 cblas_dscal(9, 0.25, iC, 1);
463 cblas_dscal(9, 0.25, T, 1);
465 cblas_dscal(9, 0.25, iT, 1);
473 if (
Q != PETSC_NULL) {
474 const auto field_bit_number =
477 problemPtr, field_bit_number, dofs_it)) {
478 CHKERR MatCreateVecs(
C, &
mapV[dofs_it->get()->getPetscGlobalDofIdx()],
480 CHKERR VecZeroEntries(
mapV[dofs_it->get()->getPetscGlobalDofIdx()]);
492 ublas::vector<double, ublas::bounded_array<double, 9>> ELEM_CONSTRAIN(9);
494 NULL, &*ELEM_CONSTRAIN.data().begin(), NULL, NULL,
496 for (
int nn = 0; nn < 3; nn++) {
499 for (
int NN = 0; NN < 3; NN++) {
502 if (
Q == PETSC_NULL) {
505 &ELEM_CONSTRAIN.data()[3 * NN], ADD_VALUES);
507 if (
Q != PETSC_NULL) {
509 SETERRQ(PETSC_COMM_SELF, 1,
"data inconsistency");
512 &ELEM_CONSTRAIN.data()[3 * NN], ADD_VALUES);
522 if (
Q != PETSC_NULL) {
526 problemPtr->getName(),
COL, &Qv);
527 const auto field_bit_number =
530 field_bit_number, dofs)) {
531 if (
mapV.find(dofs->get()->getPetscGlobalDofIdx()) ==
mapV.end()) {
533 "data inconsistency");
535 CHKERR VecAssemblyBegin(
mapV[dofs->get()->getPetscGlobalDofIdx()]);
536 CHKERR VecAssemblyEnd(
mapV[dofs->get()->getPetscGlobalDofIdx()]);
537 CHKERR MatMult(
Q,
mapV[dofs->get()->getPetscGlobalDofIdx()], Qv);
538 CHKERR VecGhostUpdateBegin(Qv, INSERT_VALUES, SCATTER_FORWARD);
539 CHKERR VecGhostUpdateEnd(Qv, INSERT_VALUES, SCATTER_FORWARD);
541 CHKERR VecGetArray(Qv, &array);
542 vector<DofIdx> glob_idx;
545 dofs->get()->getEnt(), diit)) {
546 if (diit->get()->getPart() != pcomm->rank())
548 if (diit->get()->getName() !=
"MESH_NODE_POSITIONS")
550 glob_idx.push_back(diit->get()->getPetscGlobalDofIdx());
551 if (diit->get()->getPetscLocalDofIdx() < 0) {
553 "data inconsistency");
555 vals.push_back(array[diit->get()->getPetscLocalDofIdx()]);
557 int row = dofs->get()->getPetscGlobalDofIdx();
559 glob_idx.empty() ? PETSC_NULL : &glob_idx[0],
560 vals.empty() ? PETSC_NULL : &vals[0], ADD_VALUES);
561 CHKERR VecRestoreArray(Qv, &array);
562 CHKERR VecDestroy(&
mapV[dofs->get()->getPetscGlobalDofIdx()]);
591 string lambda_field_name,
601 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
603 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
612 case CTX_TSSETIFUNCTION: {
613 snes_ctx = CTX_SNESSETFUNCTION;
617 case CTX_TSSETIJACOBIAN: {
618 snes_ctx = CTX_SNESSETJACOBIAN;
629 case CTX_SNESSETFUNCTION: {
630 CHKERR VecAssemblyBegin(snes_f);
631 CHKERR VecAssemblyEnd(snes_f);
638 case CTX_SNESSETJACOBIAN: {
639 CHKERR MatAssemblyBegin(snes_B, MAT_FLUSH_ASSEMBLY);
640 CHKERR MatAssemblyEnd(snes_B, MAT_FLUSH_ASSEMBLY);
659 ublas::vector<double, ublas::bounded_array<double, 9>> tangent_constrains(
663 &*tangent_constrains.data().begin(), NULL);
665 Tag th_interface_side;
666 CHKERR moab.tag_get_handle(
"INTERFACE_SIDE", th_interface_side);
670 tangent_constrains *= -1;
673 ublas::vector<double, ublas::bounded_array<double, 9>>
674 f_front_mesh_smoothing(9);
675 ublas::noalias(f_front_mesh_smoothing) = ublas::zero_vector<double>(9);
676 double *f_front_mesh_array;
678 for (
int nn = 0; nn < 3; nn++) {
679 for (
int dd = 0;
dd < 3;
dd++) {
682 f_front_mesh_smoothing[3 * nn +
dd] =
688 if (snes_ctx == CTX_SNESSETJACOBIAN) {
692 &
coords.data()[6], center, NULL, NULL);
693 cblas_daxpy(3, -1, &
coords.data()[0], 1, center, 1);
694 double r = cblas_dnrm2(3, center, 1);
695 for (
int nn = 0; nn < 3; nn++) {
696 for (
int dd = 0;
dd < 3;
dd++) {
698 ublas::vector<double, ublas::bounded_array<double, 9>> idofs_X(9, 0);
699 idofs_X[nn * 3 +
dd] =
r *
eps;
700 ublas::vector<double, ublas::bounded_array<double, 9>>
701 direvative_of_constrains(9);
705 &*idofs_X.data().begin(), NULL, NULL, NULL,
706 &*direvative_of_constrains.data().begin());
708 direvative_of_constrains /= -
r *
eps;
710 direvative_of_constrains /= +
r *
eps;
713 double g[3] = {0, 0, 0};
714 for (
int nnn = 0; nnn < 3; nnn++) {
717 for (
int ddd = 0; ddd < 3; ddd++) {
718 g[nnn] += direvative_of_constrains[nnn * 3 + ddd] *
719 f_front_mesh_smoothing[3 * nnn + ddd];
722 for (
int nnn = 0; nnn < 3; nnn++) {
730 for (
int nnn = 0; nnn < 3; nnn++) {
731 for (
int ddd = 0; ddd < 3; ddd++) {
732 direvative_of_constrains[nnn * 3 + ddd] *=
lambda[nnn];
735 for (
int nnn = 0; nnn < 3; nnn++) {
740 &direvative_of_constrains[3 * nnn], ADD_VALUES);
747 case CTX_SNESSETFUNCTION: {
748 ublas::vector<double, ublas::bounded_array<double, 3>>
g(3);
749 for (
int nn = 0; nn < 3; nn++) {
750 g[nn] = cblas_ddot(3, &tangent_constrains[3 * nn], 1,
751 &f_front_mesh_smoothing[3 * nn], 1);
755 &*
g.data().begin(), ADD_VALUES);
757 &*tangent_constrains.data().begin(), ADD_VALUES);
758 ublas::vector<double, ublas::bounded_array<double, 9>>
f(9);
759 for (
int nn = 0; nn < 3; nn++) {
760 for (
int dd = 0;
dd < 3;
dd++) {
761 f[nn * 3 +
dd] =
lambda[nn] * tangent_constrains[3 * nn +
dd];
776 case CTX_SNESSETJACOBIAN: {
777 for (
int nn = 0; nn < 3; nn++) {
780 &lambda_dof_idx, &tangent_constrains[3 * nn],
793 case CTX_SNESSETFUNCTION: {
801 case CTX_SNESSETJACOBIAN: {
802 CHKERR MatAssemblyBegin(snes_B, MAT_FLUSH_ASSEMBLY);
803 CHKERR MatAssemblyEnd(snes_B, MAT_FLUSH_ASSEMBLY);
814 #endif // __COMPLEX_CONST_AREA_HPP__