21 integer(kind=kint) :: ndof = 0
22 integer(kind=kint),
pointer :: mark(:) => null()
23 real(kind=
kreal),
pointer :: val(:) => null()
36 type (hecmwst_ebc),
intent(inout) :: hecebc
37 integer(kind=kint) :: npndof
40 hecebc%ndof = hecmat%NDOF
41 npndof = hecmat%NP * hecmat%NDOF
42 allocate(hecebc%mark(npndof))
43 allocate(hecebc%val(npndof))
55 type (hecmwst_ebc),
intent(inout) :: hecebc
56 integer(kind=kint),
intent(in) :: inode, idof
57 real(kind=
kreal),
intent(in) :: val
58 integer(kind=kint) :: k
60 if (idof > hecebc%ndof)
return
61 k = hecebc%ndof * (inode - 1) + idof
62 if (hecebc%mark(k) /= 0 .and. hecebc%val(k) /= val)
then
63 write(*,
'(a,i0,a,i0,a,i0,a,2(1pe14.6))')
'WARNING: rank ',
hecmw_comm_get_rank(), &
64 ': boundary value of local node ', inode,
' dof ', idof,
' overwritten:', hecebc%val(k), val
79 type (hecmwst_ebc),
intent(inout) :: hecebc
82 call hecmw_ebc_extend(hecmesh, hecmat, hecebc)
83 call hecmw_ebc_convert_slave(hecmesh, hecmat, hecebc)
84 call hecmw_ebc_impose(hecmat, hecebc, 1.d0)
85 if (
present(conmat))
call hecmw_ebc_impose(conmat, hecebc, 0.d0)
97 subroutine hecmw_ebc_extend(hecMESH, hecMAT, hecEBC)
101 type (hecmwst_ebc),
intent(inout) :: hecebc
102 integer(kind=kint),
pointer :: mark(:)
103 real(kind=
kreal),
pointer :: val(:)
104 integer(kind=kint) :: ndof, npndof, npndof_old, i
107 npndof = hecmat%NP * ndof
108 npndof_old =
size(hecebc%mark)
110 if (npndof > npndof_old)
then
111 allocate(mark(npndof))
112 allocate(val(npndof))
116 mark(i) = hecebc%mark(i)
117 val(i) = hecebc%val(i)
119 deallocate(hecebc%mark)
120 deallocate(hecebc%val)
131 if (hecebc%mark(i) == 0) cycle
132 hecebc%val(i) = hecebc%val(i) / hecebc%mark(i)
135 end subroutine hecmw_ebc_extend
147 subroutine hecmw_ebc_convert_slave(hecMESH, hecMAT, hecEBC)
151 type (hecmwst_ebc),
intent(inout) :: hecebc
152 integer(kind=kint),
allocatable :: dmark(:)
153 real(kind=
kreal),
allocatable :: dval(:)
154 integer(kind=kint) :: ndof, npndof, i, j, k, km, ks, kk, nchange
155 real(kind=
kreal) :: um, tol
158 npndof = hecmat%NP * ndof
159 allocate(dmark(npndof))
160 allocate(dval(npndof))
165 outer:
do i = 1, hecmesh%mpc%n_mpc
166 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
167 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
169 k = hecmesh%mpc%mpc_index(i-1) + 1
170 ks = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
171 if (hecebc%mark(ks) == 0) cycle
172 if (hecmesh%mpc%mpc_index(i) - hecmesh%mpc%mpc_index(i-1) /= 2)
then
173 write(*,
'(a,i0,a,i0,a)')
'ERROR: a boundary condition is given to node ', &
174 hecmesh%global_node_ID(hecmesh%mpc%mpc_item(k)),
' dof ', hecmesh%mpc%mpc_dof(k), &
175 ', the slave of an !EQUATION with more than one master; it cannot be imposed as a boundary condition'
179 kk = ndof * (hecmesh%mpc%mpc_item(km) - 1) + hecmesh%mpc%mpc_dof(km)
180 um = (hecmesh%mpc%mpc_const(i) - hecmesh%mpc%mpc_val(k) * hecebc%val(ks)) / hecmesh%mpc%mpc_val(km)
181 tol = 1.d-10 * max(1.d0, abs(um))
182 if ((hecebc%mark(kk) /= 0 .and. abs(hecebc%val(kk) - um) > tol) .or. &
183 (dmark(kk) /= 0 .and. abs(dval(kk) - um) > tol))
then
184 write(*,
'(a,i0,a,i0,a,i0,a,i0,a)')
'ERROR: the boundary condition on node ', &
185 hecmesh%global_node_ID(hecmesh%mpc%mpc_item(k)),
' dof ', hecmesh%mpc%mpc_dof(k), &
186 ', the slave of an !EQUATION, conflicts with the one on its master node ', &
187 hecmesh%global_node_ID(hecmesh%mpc%mpc_item(km)),
' dof ', hecmesh%mpc%mpc_dof(km),
''
190 if (hecebc%mark(kk) == 0)
then
195 nchange = nchange + 1
199 if (nchange > 0)
then
203 if (dmark(i) > 0)
then
205 hecebc%val(i) = dval(i) / dmark(i)
206 else if (dmark(i) < 0)
then
217 end subroutine hecmw_ebc_convert_slave
228 subroutine hecmw_ebc_impose(hecMAT, hecEBC, diag)
231 type (hecmwst_ebc),
intent(in) :: hecebc
232 real(kind=
kreal),
intent(in) :: diag
233 integer(kind=kint) :: ndof, ndof2, i, j, k, idof, jdof, ir, jc, idx
240 ir = ndof * (i - 1) + idof
242 jc = ndof * (i - 1) + jdof
243 idx = ndof2 * (i - 1) + ndof * (idof - 1) + jdof
244 if (hecebc%mark(ir) /= 0)
then
246 else if (hecebc%mark(jc) /= 0)
then
247 hecmat%B(ir) = hecmat%B(ir) - hecmat%D(idx) * hecebc%val(jc)
252 do k = hecmat%indexL(i-1) + 1, hecmat%indexL(i)
255 ir = ndof * (i - 1) + idof
257 jc = ndof * (j - 1) + jdof
258 idx = ndof2 * (k - 1) + ndof * (idof - 1) + jdof
259 if (hecebc%mark(ir) /= 0)
then
260 hecmat%AL(idx) = 0.d0
261 else if (hecebc%mark(jc) /= 0)
then
262 hecmat%B(ir) = hecmat%B(ir) - hecmat%AL(idx) * hecebc%val(jc)
263 hecmat%AL(idx) = 0.d0
268 do k = hecmat%indexU(i-1) + 1, hecmat%indexU(i)
271 ir = ndof * (i - 1) + idof
273 jc = ndof * (j - 1) + jdof
274 idx = ndof2 * (k - 1) + ndof * (idof - 1) + jdof
275 if (hecebc%mark(ir) /= 0)
then
276 hecmat%AU(idx) = 0.d0
277 else if (hecebc%mark(jc) /= 0)
then
278 hecmat%B(ir) = hecmat%B(ir) - hecmat%AU(idx) * hecebc%val(jc)
279 hecmat%AU(idx) = 0.d0
288 ir = ndof * (i - 1) + idof
289 if (hecebc%mark(ir) == 0) cycle
290 hecmat%D(ndof2 * (i - 1) + ndof * (idof - 1) + idof) = diag
291 hecmat%B(ir) = diag * hecebc%val(ir)
294 end subroutine hecmw_ebc_impose
303 type (hecmwst_ebc),
intent(inout) :: hecebc
306 if (
associated(hecebc%mark))
deallocate(hecebc%mark)
307 if (
associated(hecebc%val))
deallocate(hecebc%val)
Essential boundary conditions kept as per-DOF marks and values so that they can be imposed on the mat...
subroutine, public hecmw_ebc_set(hecEBC, inode, idof, val)
subroutine, public hecmw_ebc_init(hecMAT, hecEBC)
subroutine, public hecmw_ebc_apply(hecMESH, hecMAT, hecEBC, conMAT)
subroutine, public hecmw_ebc_finalize(hecEBC)
integer(kind=kint), parameter hecmw_sum
subroutine hecmw_abort(comm, code)
integer(kind=kint) function hecmw_comm_get_comm()
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
subroutine hecmw_assemble_r(hecMESH, val, n, m)
subroutine hecmw_update_r(hecMESH, val, n, m)
subroutine hecmw_allreduce_i1(hecMESH, s, ntag)
subroutine hecmw_assemble_i(hecMESH, val, n, m)
subroutine hecmw_update_i(hecMESH, val, n, m)