Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
lbmpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pycodegen
lbmpy
Commits
eb1cb924
Commit
eb1cb924
authored
6 years ago
by
Martin Bauer
Browse files
Options
Downloads
Patches
Plain Diff
added simplex projection and three-point energy term to nestler model
parent
d7f10c73
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
phasefield/nphase_nestler.py
+24
-31
24 additions, 31 deletions
phasefield/nphase_nestler.py
phasefield/simplex_projection.pyx
+49
-0
49 additions, 0 deletions
phasefield/simplex_projection.pyx
with
73 additions
and
31 deletions
phasefield/nphase_nestler.py
+
24
−
31
View file @
eb1cb924
...
@@ -8,6 +8,10 @@ from pystencils import create_data_handling, Assignment, create_kernel
...
@@ -8,6 +8,10 @@ from pystencils import create_data_handling, Assignment, create_kernel
from
pystencils.fd
import
Diff
,
expand_diff_full
,
discretize_spatial
from
pystencils.fd
import
Diff
,
expand_diff_full
,
discretize_spatial
from
pystencils.fd.derivation
import
FiniteDifferenceStencilDerivation
from
pystencils.fd.derivation
import
FiniteDifferenceStencilDerivation
import
pyximport
pyximport
.
install
(
language_level
=
3
)
from
lbmpy.phasefield.simplex_projection
import
simplex_projection_2d
# NOQA
def
forth_order_isotropic_discretize
(
field
):
def
forth_order_isotropic_discretize
(
field
):
second_neighbor_stencil
=
[(
i
,
j
)
second_neighbor_stencil
=
[(
i
,
j
)
...
@@ -33,13 +37,11 @@ def forth_order_isotropic_discretize(field):
...
@@ -33,13 +37,11 @@ def forth_order_isotropic_discretize(field):
return
substitutions
return
substitutions
def
create_model
(
domain_size
,
num_phases
,
kappas
,
epsilon_dict
,
alpha
=
1
,
penalty_factor
=
0.01
):
def
create_model
(
domain_size
,
num_phases
,
coeff_a
,
coeff_epsilon
,
gabd
,
alpha
=
1
,
penalty_factor
=
0.01
,
simplex_projection
=
False
):
def
lapl
(
e
):
def
lapl
(
e
):
return
sum
(
Diff
(
Diff
(
e
,
i
),
i
)
for
i
in
range
(
dh
.
dim
))
return
sum
(
Diff
(
Diff
(
e
,
i
),
i
)
for
i
in
range
(
dh
.
dim
))
def
f
(
c
):
return
c
**
2
*
(
1
-
c
)
**
2
def
interfacial_chemical_potential
(
c
):
def
interfacial_chemical_potential
(
c
):
result
=
[]
result
=
[]
n
=
len
(
c
)
n
=
len
(
c
)
...
@@ -48,11 +50,22 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
...
@@ -48,11 +50,22 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
for
k
in
range
(
n
):
for
k
in
range
(
n
):
if
i
==
k
:
if
i
==
k
:
continue
continue
eps
=
epsilon
_dict
[(
i
,
k
)]
if
i
<
k
else
epsilon
_dict
[
k
,
i
]
eps
=
coeff_
epsilon
[(
k
,
i
)]
if
i
<
k
else
coeff_
epsilon
[(
i
,
k
)
]
entry
+=
alpha
**
2
*
eps
**
2
*
(
c
[
k
]
*
lapl
(
c
[
i
])
-
c
[
i
]
*
lapl
(
c
[
k
]))
entry
+=
alpha
**
2
*
eps
**
2
*
(
c
[
k
]
*
lapl
(
c
[
i
])
-
c
[
i
]
*
lapl
(
c
[
k
]))
result
.
append
(
entry
)
result
.
append
(
entry
)
return
-
sp
.
Matrix
(
result
)
return
-
sp
.
Matrix
(
result
)
def
bulk
(
c
):
result
=
0
for
i
in
range
(
num_phases
):
for
j
in
range
(
i
):
result
+=
(
c
[
i
]
**
2
*
c
[
j
]
**
2
)
/
(
4
*
coeff_a
[
i
,
j
])
for
i
in
range
(
num_phases
):
for
j
in
range
(
i
):
for
k
in
range
(
j
):
result
+=
gabd
*
c
[
i
]
*
c
[
j
]
*
c
[
k
]
return
result
# -------------- Data ------------------
# -------------- Data ------------------
dh
=
create_data_handling
(
domain_size
,
periodicity
=
(
True
,
True
),
default_ghost_layers
=
2
)
dh
=
create_data_handling
(
domain_size
,
periodicity
=
(
True
,
True
),
default_ghost_layers
=
2
)
...
@@ -78,8 +91,8 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
...
@@ -78,8 +91,8 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
# ------------- Compute kernels --------
# ------------- Compute kernels --------
c_vec
=
c
.
center_vector
c_vec
=
c
.
center_vector
f_penalty
=
penalty_factor
*
(
1
-
sum
(
c_vec
[
i
]
for
i
in
range
(
num_phases
)))
**
2
f_penalty
=
penalty_factor
*
(
1
-
sum
(
c_vec
[
i
]
for
i
in
range
(
num_phases
)))
**
2
f_bulk
=
sum
(
kappa_i
*
f
(
c_i
)
for
kappa_i
,
c_i
in
zip
(
kappas
,
c_vec
)
)
+
f_penalty
f_bulk
=
bulk
(
c_vec
)
+
f_penalty
print
(
f_bulk
)
mu_eq
=
chemical_potentials_from_free_energy
(
f_bulk
,
order_parameters
=
c_vec
)
mu_eq
=
chemical_potentials_from_free_energy
(
f_bulk
,
order_parameters
=
c_vec
)
mu_eq
+=
interfacial_chemical_potential
(
c_vec
)
mu_eq
+=
interfacial_chemical_potential
(
c_vec
)
mu_eq
=
[
expand_diff_full
(
mu_i
,
functions
=
c
)
for
mu_i
in
mu_eq
]
mu_eq
=
[
expand_diff_full
(
mu_i
,
functions
=
c
)
for
mu_i
in
mu_eq
]
...
@@ -101,6 +114,7 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
...
@@ -101,6 +114,7 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
ch_methods
.
append
(
ch_method
)
ch_methods
.
append
(
ch_method
)
ch_update_rule
=
create_lb_update_rule
(
lb_method
=
ch_method
,
ch_update_rule
=
create_lb_update_rule
(
lb_method
=
ch_method
,
kernel_type
=
'
collide_only
'
,
kernel_type
=
'
collide_only
'
,
density_input
=
c
(
i
),
velocity_input
=
u
.
center_vector
,
velocity_input
=
u
.
center_vector
,
compressible
=
True
,
compressible
=
True
,
optimization
=
{
"
symbolic_field
"
:
pdf_field
[
i
]})
optimization
=
{
"
symbolic_field
"
:
pdf_field
[
i
]})
...
@@ -133,7 +147,7 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
...
@@ -133,7 +147,7 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
for
i
in
range
(
num_phases
):
for
i
in
range
(
num_phases
):
cqc
=
ch_methods
[
i
].
conserved_quantity_computation
cqc
=
ch_methods
[
i
].
conserved_quantity_computation
output_assign
=
cqc
.
output_equations_from_pdfs
(
pdf_field
[
i
].
center_vector
,
output_assign
=
cqc
.
output_equations_from_pdfs
(
pdf_field
[
i
].
center_vector
,
{
'
density
'
:
c
.
center
[
i
]
})
{
'
density
'
:
c
(
i
)
})
getter_kernel
=
create_kernel
(
output_assign
).
compile
()
getter_kernel
=
create_kernel
(
output_assign
).
compile
()
getter_kernels
.
append
(
getter_kernel
)
getter_kernels
.
append
(
getter_kernel
)
...
@@ -205,29 +219,8 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
...
@@ -205,29 +219,8 @@ def create_model(domain_size, num_phases, kappas, epsilon_dict, alpha=1, penalty
dh
.
run_kernel
(
ch_stream_kernels
[
i
])
dh
.
run_kernel
(
ch_stream_kernels
[
i
])
dh
.
swap
(
pdf_field
[
i
].
name
,
pdf_dst_field
[
i
].
name
)
dh
.
swap
(
pdf_field
[
i
].
name
,
pdf_dst_field
[
i
].
name
)
dh
.
run_kernel
(
getter_kernels
[
i
])
dh
.
run_kernel
(
getter_kernels
[
i
])
if
simplex_projection
:
simplex_projection_2d
(
dh
.
cpu_arrays
[
c
.
name
])
return
dh
.
cpu_arrays
[
c
.
name
][
1
:
-
1
,
1
:
-
1
,
:]
return
dh
.
cpu_arrays
[
c
.
name
][
1
:
-
1
,
1
:
-
1
,
:]
return
dh
,
init
,
run
return
dh
,
init
,
run
if
__name__
==
'
__main__
'
:
from
collections
import
defaultdict
num_phases
=
3
kappas
=
[
0.01
]
*
3
epsilon_dict
=
defaultdict
(
lambda
:
0.1
)
alpha
=
1
dh
,
init
,
run
=
create_model
([
100
,
100
],
num_phases
,
kappas
,
epsilon_dict
,
alpha
,
penalty_factor
=
0.01
)
c_arr
=
dh
.
cpu_arrays
[
'
c
'
]
nx
,
ny
=
dh
.
shape
c_arr
[:,
:
int
(
0.5
*
nx
),
0
]
=
1
c_arr
[:,
int
(
0.5
*
nx
):,
1
]
=
1
c_arr
[
int
(
0.4
*
nx
):
int
(
0.6
*
nx
),
int
(
0.4
*
ny
):
int
(
0.6
*
ny
),
0
]
=
0
c_arr
[
int
(
0.4
*
nx
):
int
(
0.6
*
nx
),
int
(
0.4
*
ny
):
int
(
0.6
*
ny
),
1
]
=
0
c_arr
[
int
(
0.4
*
nx
):
int
(
0.6
*
nx
),
int
(
0.4
*
ny
):
int
(
0.6
*
ny
),
2
]
=
1
init
()
res
=
run
(
1
)
This diff is collapsed.
Click to expand it.
phasefield/simplex_projection.pyx
0 → 100644
+
49
−
0
View file @
eb1cb924
# Workaround for cython bug
# see https://stackoverflow.com/questions/8024805/cython-compiled-c-extension-importerror-dynamic-module-does-not-define-init-fu
WORKAROUND
=
"
Something
"
import
cython
@cython.boundscheck
(
False
)
@cython.wraparound
(
False
)
@cython.cdivision
(
True
)
def
simplex_projection_2d
(
object
[
double
,
ndim
=
3
]
c
):
cdef
int
xs
,
ys
,
num_phases
,
x
,
y
,
a
,
b
,
local_phases
cdef
unsigned
int
handled_mask
=
0
cdef
double
threshold
=
1e-18
cdef
double
phase_sum
xs
,
ys
,
num_phases
=
c
.
shape
for
y
in
range
(
ys
):
for
x
in
range
(
xs
):
local_phases
=
num_phases
## Mark zero phases
for
a
in
range
(
num_phases
):
if
-
threshold
<
c
[
x
,
y
,
a
]
<
threshold
:
local_phases
-=
1
handled_mask
|=
(
1
<<
a
)
c
[
x
,
y
,
a
]
=
0
# Distribute negative phases to others
a
=
0
while
a
<
num_phases
:
if
c
[
x
,
y
,
a
]
<
0.0
:
handled_mask
|=
(
1
<<
a
)
local_phases
-=
1
for
b
in
range
(
num_phases
):
# distribute to unhandled phases
if
handled_mask
&
(
1
<<
b
)
==
0
:
c
[
x
,
y
,
b
]
+=
c
[
x
,
y
,
a
]
/
local_phases
c
[
x
,
y
,
a
]
=
0.0
a
=
-
1
# restart loop, since other phases might have become negative
a
+=
1
# Normalize phases
phase_sum
=
0.0
for
a
in
range
(
num_phases
):
phase_sum
+=
c
[
x
,
y
,
a
]
for
a
in
range
(
num_phases
):
c
[
x
,
y
,
a
]
/=
phase_sum
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment