-
Notifications
You must be signed in to change notification settings - Fork 183
/
laplace_shifted_periodic.py
executable file
·142 lines (112 loc) · 4.87 KB
/
laplace_shifted_periodic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python
"""
Laplace equation with shifted periodic BCs.
Display using::
./postproc.py laplace_shifted_periodic.vtk --wireframe -b -d'u,plot_warp_scalar,rel_scaling=1'
or use the --show option.
"""
import sys
sys.path.append('.')
from optparse import OptionParser
import numpy as nm
from sfepy.base.base import output
from sfepy.discrete import (FieldVariable, Integral, Equation, Equations,
Function, Problem)
from sfepy.discrete.fem import FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import (Conditions, EssentialBC,
LinearCombinationBC)
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
from sfepy.mesh.mesh_generators import gen_block_mesh
import sfepy.discrete.fem.periodic as per
def run(domain, order):
omega = domain.create_region('Omega', 'all')
bbox = domain.get_mesh_bounding_box()
min_x, max_x = bbox[:, 0]
min_y, max_y = bbox[:, 1]
eps = 1e-8 * (max_x - min_x)
gamma1 = domain.create_region('Gamma1',
'vertices in (x < %.10f)' % (min_x + eps),
'facet')
gamma2 = domain.create_region('Gamma2',
'vertices in (x > %.10f)' % (max_x - eps),
'facet')
gamma3 = domain.create_region('Gamma3',
'vertices in y < %.10f' % (min_y + eps),
'facet')
gamma4 = domain.create_region('Gamma4',
'vertices in y > %.10f' % (max_y - eps),
'facet')
field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order)
u = FieldVariable('u', 'unknown', field)
v = FieldVariable('v', 'test', field, primary_var_name='u')
integral = Integral('i', order=2*order)
t1 = Term.new('dw_laplace(v, u)',
integral, omega, v=v, u=u)
eq = Equation('eq', t1)
eqs = Equations([eq])
fix1 = EssentialBC('fix1', gamma1, {'u.0' : 0.4})
fix2 = EssentialBC('fix2', gamma2, {'u.0' : 0.0})
def get_shift(ts, coors, region):
return nm.ones_like(coors[:, 0])
dof_map_fun = Function('dof_map_fun', per.match_x_line)
shift_fun = Function('shift_fun', get_shift)
sper = LinearCombinationBC('sper', [gamma3, gamma4], {'u.0' : 'u.0'},
dof_map_fun, 'shifted_periodic',
arguments=(shift_fun,))
ls = ScipyDirect({})
pb = Problem('laplace', equations=eqs, auto_solvers=None)
pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper]))
ev = pb.get_evaluator()
nls = Newton({}, lin_solver=ls,
fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix)
pb.set_solver(nls)
state = pb.solve()
return pb, state
usage = '%prog [options]\n' + __doc__.rstrip()
helps = {
'dims' :
'dimensions of the block [default: %default]',
'centre' :
'centre of the block [default: %default]',
'shape' :
'numbers of vertices along each axis [default: %default]',
'show' : 'show the results figure',
}
def main():
parser = OptionParser(usage=usage, version='%prog')
parser.add_option('-d', '--dims', metavar='dims',
action='store', dest='dims',
default='[1.0, 1.0]', help=helps['dims'])
parser.add_option('-c', '--centre', metavar='centre',
action='store', dest='centre',
default='[0.0, 0.0]', help=helps['centre'])
parser.add_option('-s', '--shape', metavar='shape',
action='store', dest='shape',
default='[11, 11]', help=helps['shape'])
parser.add_option('', '--show',
action="store_true", dest='show',
default=False, help=helps['show'])
(options, args) = parser.parse_args()
dims = nm.array(eval(options.dims), dtype=nm.float64)
centre = nm.array(eval(options.centre), dtype=nm.float64)
shape = nm.array(eval(options.shape), dtype=nm.int32)
output('dimensions:', dims)
output('centre: ', centre)
output('shape: ', shape)
mesh = gen_block_mesh(dims, shape, centre, name='block-fem')
fe_domain = FEDomain('domain', mesh)
pb, state = run(fe_domain, 1)
pb.save_state('laplace_shifted_periodic.vtk', state)
if options.show:
from sfepy.postprocess.viewer import Viewer
from sfepy.postprocess.domain_specific import DomainSpecificPlot
view = Viewer('laplace_shifted_periodic.vtk')
view(rel_scaling=1,
domain_specific={'u' : DomainSpecificPlot('plot_warp_scalar',
['rel_scaling=1'])},
is_scalar_bar=True, is_wireframe=True,
opacity=0.3)
if __name__ == '__main__':
main()