Skip to content

Commit d6b0d14

Browse files
committed
Add Model Patches
1 parent ead420c commit d6b0d14

File tree

14 files changed

+668
-97
lines changed

14 files changed

+668
-97
lines changed

docs/documentation/case.md

Lines changed: 79 additions & 72 deletions
Large diffs are not rendered by default.

misc/img2stl.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import math, argparse
2+
3+
from PIL import Image, ImageFilter
4+
5+
parser = argparse.ArgumentParser(prog='img2stl', description='Turn an image into an STL file')
6+
parser.add_argument('input', type=str, help='Path to the image file')
7+
parser.add_argument('output', type=str, help='Path to the output OBJ file')
8+
9+
VARS = vars(parser.parse_args())
10+
11+
img = Image.open(VARS['input'])
12+
13+
W, H = img.size
14+
15+
pixels = img.load()
16+
for y in range(H):
17+
for x in range(W):
18+
if pixels[x,y][3] < 255:
19+
pixels[x,y] = (0,0,0,255)
20+
21+
img.save('temp.png')
22+
img = img.convert('L')
23+
24+
THRESHOLD = 0.1
25+
26+
with open(VARS['output'], 'w') as f:
27+
i = 0
28+
pixels = img.load()
29+
for y in range(H):
30+
for x in range(W):
31+
c = pixels[x,y]
32+
33+
if c < 255 * THRESHOLD: continue
34+
35+
area = c / 255.0
36+
d = (1.0 - math.sqrt(area)) / 2.0
37+
38+
def tx(_x: int, _f: bool):
39+
if _f: _x = _x + d*(1 - _x*2)
40+
return -1.0+2.0 * (x + _x)/float(W)
41+
42+
def ty(_y: int, _f: bool):
43+
if _f: _y = _y + d*(1 - _y*2)
44+
return 1.0-2.0 * ((1-H/float(W))/2 + (y+_y)/float(W))
45+
46+
def tz(_z: int, _f: bool):
47+
if _f: _z = _z + d*(1 - _z*2)
48+
return max(1.0 / float(W), 1.0 / float(H)) * (-1.0+2.0 * _z)
49+
50+
def p1(_x: int, _y: int, _z: int):
51+
return tx(_x, True), ty(_y, True), tz(_z, False)
52+
53+
for _x, _y, _z in [p1(0,0,0), p1(1,0,0), p1(0,1,0), p1(1,1,0),
54+
p1(0,0,1), p1(1,0,1), p1(0,1,1), p1(1,1,1)]:
55+
f.write(f'v {_x} {_y} {_z}\n')
56+
57+
f.write(f'f {i+1} {i+2} {i+3}\n'); f.write(f'f {i+2} {i+3} {i+4}\n')
58+
f.write(f'f {i+5} {i+6} {i+7}\n'); f.write(f'f {i+6} {i+7} {i+8}\n')
59+
60+
i = i + 8
61+
62+
def p2(_x: int, _y: int, _z: int):
63+
return tx(_x, False), ty(_y, True), tz(_z, True)
64+
65+
for _x, _y, _z in [p2(0,0,0), p2(1,0,0), p2(0,1,0), p2(1,1,0),
66+
p2(0,0,1), p2(1,0,1), p2(0,1,1), p2(1,1,1)]:
67+
f.write(f'v {_x} {_y} {_z}\n')
68+
69+
f.write(f'f {i+1} {i+5} {i+7}\n'); f.write(f'f {i+1} {i+3} {i+7}\n')
70+
f.write(f'f {i+2} {i+6} {i+8}\n'); f.write(f'f {i+2} {i+4} {i+8}\n')
71+
72+
i = i + 8
73+
74+
def p3(_x: int, _y: int, _z: int):
75+
return tx(_x, True), ty(_y, False), tz(_z, True)
76+
77+
for _x, _y, _z in [p3(0,0,0), p3(1,0,0), p3(0,1,0), p3(1,1,0),
78+
p3(0,0,1), p3(1,0,1), p3(0,1,1), p3(1,1,1)]:
79+
f.write(f'v {_x} {_y} {_z}\n')
80+
81+
f.write(f'f {i+1} {i+2} {i+5}\n'); f.write(f'f {i+2} {i+5} {i+6}\n')
82+
f.write(f'f {i+3} {i+4} {i+7}\n'); f.write(f'f {i+4} {i+7} {i+8}\n')
83+
84+
i = i + 8

src/common/m_derived_types.f90 renamed to src/common/m_derived_types.fpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
!! @file m_derived_types.f90
33
!! @brief Contains module m_derived_types
44

5+
#:include "macros.fpp"
6+
57
!> @brief This file contains the definitions of all of the custom-defined
68
!! types used in the pre-process code.
79
module m_derived_types
@@ -59,6 +61,45 @@ module m_derived_types
5961
integer, dimension(:, :, :), allocatable :: fullmom !< Moment indices for qbmm
6062
end type bub_bounds_info
6163

64+
!> Defines parameters for a Model Patch
65+
type :: ic_model_parameters
66+
character(LEN=pathlen_max) :: filepath !<
67+
!! Path the STL file relative to case_dir.
68+
69+
t_vec3 :: translate !<
70+
!! Translation of the STL object.
71+
72+
t_vec3 :: scale !<
73+
!! Scale factor for the STL object.
74+
75+
t_vec3 :: rotate !<
76+
!! Angle to rotate the STL object along each cartesian coordinate axis,
77+
!! in radians.
78+
79+
integer :: spc !<
80+
!! Number of samples per cell to use when discretizing the STL object.
81+
end type ic_model_parameters
82+
83+
type :: t_triangle
84+
real(kind(0d0)), dimension(1:3, 1:3) :: v ! Vertices of the triangle
85+
t_vec3 :: n ! Normal vector
86+
end type t_triangle
87+
88+
type :: t_ray
89+
t_vec3 :: o ! Origin
90+
t_vec3 :: d ! Direction
91+
end type t_ray
92+
93+
type :: t_bbox
94+
t_vec3 :: min ! Minimum coordinates
95+
t_vec3 :: max ! Maximum coordinates
96+
end type t_bbox
97+
98+
type :: t_model
99+
integer :: ntrs ! Number of triangles
100+
type(t_triangle), allocatable :: trs(:) ! Triangles
101+
end type t_model
102+
62103
!> Derived type adding initial condition (ic) patch parameters as attributes
63104
!! NOTE: The requirements for the specification of the above parameters
64105
!! are strongly dependent on both the choice of the multicomponent flow
@@ -79,6 +120,8 @@ module m_derived_types
79120
!! patch geometries. It is specified through its x-, y-, and z-components
80121
!! respectively.
81122

123+
type(ic_model_parameters) :: model !< Model parameters
124+
82125
real(kind(0d0)) :: epsilon, beta !<
83126
!! The isentropic vortex parameters administrating, respectively, both
84127
!! the amplitude of the disturbance as well as its domain of influence.

src/common/m_helper.fpp

Lines changed: 154 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
!>
33
!! @file m_helper.f90
44
!! @brief Contains module m_helper
5+
56
module m_helper
67

78
! Dependencies =============================================================
@@ -20,7 +21,14 @@ module m_helper
2021
s_initialize_nonpoly, &
2122
s_simpson, &
2223
s_transcoeff, &
23-
s_int_to_str
24+
s_int_to_str, &
25+
s_transform_vec, &
26+
s_transform_triangle, &
27+
s_transform_model, &
28+
s_swap, &
29+
f_cross, &
30+
f_create_transform_matrix, &
31+
f_create_bbox
2432

2533
contains
2634

@@ -148,15 +156,9 @@ contains
148156
rhol0 = rhoref
149157
pl0 = pref
150158
151-
#ifdef MFC_SIMULATION
152159
@:ALLOCATE(pb0(nb), mass_n0(nb), mass_v0(nb), Pe_T(nb))
153160
@:ALLOCATE(k_n(nb), k_v(nb), omegaN(nb))
154161
@:ALLOCATE(Re_trans_T(nb), Re_trans_c(nb), Im_trans_T(nb), Im_trans_c(nb))
155-
#else
156-
allocate(pb0(nb), mass_n0(nb), mass_v0(nb), Pe_T(nb))
157-
allocate(k_n(nb), k_v(nb), omegaN(nb))
158-
allocate(Re_trans_T(nb), Re_trans_c(nb), Im_trans_T(nb), Im_trans_c(nb))
159-
#endif
160162
161163
pb0(:) = dflt_real
162164
mass_n0(:) = dflt_real
@@ -331,5 +333,150 @@ contains
331333
tmp = DEXP(-0.5d0*(phi(nb)/sd)**2)/DSQRT(2.d0*pi)/sd
332334
weight(nb) = tmp*dphi/3.d0
333335
end subroutine s_simpson
336+
337+
!> This procedure computes the cross product of two vectors.
338+
!! @param a First vector.
339+
!! @param b Second vector.
340+
!! @return The cross product of the two vectors.
341+
function f_cross(a, b) result(c)
342+
real(kind(0d0)), dimension(3), intent(in) :: a, b
343+
real(kind(0d0)), dimension(3) :: c
344+
345+
c(1) = a(2) * b(3) - a(3) * b(2)
346+
c(2) = a(3) * b(1) - a(1) * b(3)
347+
c(3) = a(1) * b(2) - a(2) * b(1)
348+
end function f_cross
349+
350+
!> This procedure swaps two real numbers.
351+
!! @param lhs Left-hand side.
352+
!! @param rhs Right-hand side.
353+
subroutine s_swap(lhs, rhs)
354+
real(kind(0d0)), intent(inout) :: lhs, rhs
355+
real(kind(0d0)) :: ltemp
356+
357+
ltemp = lhs
358+
lhs = rhs
359+
rhs = ltemp
360+
end subroutine s_swap
361+
362+
!> This procedure creates a transformation matrix.
363+
!! @param p Parameters for the transformation.
364+
!! @return Transformation matrix.
365+
function f_create_transform_matrix(p) result(out_matrix)
366+
367+
type(ic_model_parameters) :: p
368+
369+
t_mat4x4 :: sc, rz, rx, ry, tr, out_matrix
370+
371+
sc = transpose(reshape([ &
372+
p%scale(1), 0d0, 0d0, 0d0, &
373+
0d0, p%scale(2), 0d0, 0d0, &
374+
0d0, 0d0, p%scale(3), 0d0, &
375+
0d0, 0d0, 0d0, 1d0 ], shape(sc)))
376+
377+
rz = transpose(reshape([ &
378+
cos(p%rotate(3)), -sin(p%rotate(3)), 0d0, 0d0, &
379+
sin(p%rotate(3)), cos(p%rotate(3)), 0d0, 0d0, &
380+
0d0, 0d0, 1d0, 0d0, &
381+
0d0, 0d0, 0d0, 1d0 ], shape(rz)))
382+
383+
rx = transpose(reshape([ &
384+
1d0, 0d0, 0d0, 0d0, &
385+
0d0, cos(p%rotate(1)), -sin(p%rotate(1)), 0d0, &
386+
0d0, sin(p%rotate(1)), cos(p%rotate(1)), 0d0, &
387+
0d0, 0d0, 0d0, 1d0 ], shape(rx)))
388+
389+
ry = transpose(reshape([ &
390+
cos(p%rotate(2)), 0d0, sin(p%rotate(2)), 0d0, &
391+
0d0, 1d0, 0d0, 0d0, &
392+
-sin(p%rotate(2)), 0d0, cos(p%rotate(2)), 0d0, &
393+
0d0, 0d0, 0d0, 1d0 ], shape(ry)))
394+
395+
tr = transpose(reshape([ &
396+
1d0, 0d0, 0d0, p%translate(1), &
397+
0d0, 1d0, 0d0, p%translate(2), &
398+
0d0, 0d0, 1d0, p%translate(3), &
399+
0d0, 0d0, 0d0, 1d0 ], shape(tr)))
400+
401+
out_matrix = matmul(tr, matmul(ry, matmul(rx, matmul(rz, sc))))
402+
403+
end function f_create_transform_matrix
404+
405+
!> This procedure transforms a vector by a matrix.
406+
!! @param vec Vector to transform.
407+
!! @param matrix Transformation matrix.
408+
subroutine s_transform_vec(vec, matrix)
409+
410+
t_vec3, intent(inout) :: vec
411+
t_mat4x4, intent(in) :: matrix
412+
413+
real(kind(0d0)), dimension(1:4) :: tmp
414+
415+
tmp = matmul(matrix, [ vec(1), vec(2), vec(3), 1d0 ])
416+
vec = tmp(1:3)
417+
418+
end subroutine s_transform_vec
419+
420+
!> This procedure transforms a triangle by a matrix, one vertex at a time.
421+
!! @param triangle Triangle to transform.
422+
!! @param matrix Transformation matrix.
423+
subroutine s_transform_triangle(triangle, matrix)
424+
425+
type(t_triangle), intent(inout) :: triangle
426+
t_mat4x4, intent(in) :: matrix
427+
428+
integer :: i
429+
430+
real(kind(0d0)), dimension(1:4) :: tmp
431+
432+
do i = 1, 3
433+
call s_transform_vec(triangle%v(i,:), matrix)
434+
end do
435+
436+
end subroutine s_transform_triangle
437+
438+
!> This procedure transforms a model by a matrix, one triangle at a time.
439+
!! @param model Model to transform.
440+
!! @param matrix Transformation matrix.
441+
subroutine s_transform_model(model, matrix)
442+
443+
type(t_model), intent(inout) :: model
444+
t_mat4x4, intent(in) :: matrix
445+
446+
integer :: i
447+
448+
do i = 1, size(model%trs)
449+
call s_transform_triangle(model%trs(i), matrix)
450+
end do
451+
452+
end subroutine s_transform_model
453+
454+
!> This procedure creates a bounding box for a model.
455+
!! @param model Model to create bounding box for.
456+
!! @return Bounding box.
457+
function f_create_bbox(model) result(bbox)
458+
459+
type(t_model), intent(in) :: model
460+
type(t_bbox) :: bbox
461+
462+
integer :: i, j
463+
464+
if (size(model%trs) == 0) then
465+
bbox%min = 0d0
466+
bbox%max = 0d0
467+
return
468+
end if
469+
470+
bbox%min = model%trs(1)%v(1,:)
471+
bbox%max = model%trs(1)%v(1,:)
472+
473+
do i = 1, size(model%trs)
474+
do j = 1, 3
475+
bbox%min = min(bbox%min, model%trs(i)%v(j,:))
476+
bbox%max = max(bbox%max, model%trs(i)%v(j,:))
477+
end do
478+
end do
479+
480+
end function f_create_bbox
334481

335482
end module m_helper

src/common/m_variables_conversion.fpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ contains
132132
! Depending on model_eqns and bubbles, the appropriate procedure
133133
! for computing pressure is targeted by the procedure pointer
134134

135-
if ((model_eqns /= 4) .and. (bubbles .neqv. .true.)) then
135+
if ((model_eqns /= 4) .and. (bubbles .neqv. .true.)) then
136136
pres = (energy - dyn_p - pi_inf)/gamma
137137
else if ((model_eqns /= 4) .and. bubbles) then
138138
pres = ((energy - dyn_p)/(1.d0 - alf) - pi_inf)/gamma

src/pre_process/m_check_patches.fpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ contains
7979
elseif (patch_icpp(i)%geometry == 19) then
8080
print *, '3d var circle'
8181
elseif (patch_icpp(i)%geometry == 20) then
82-
call s_check_2D_TaylorGreen_vortex_patch_geometry(i)
82+
call s_check_2D_TaylorGreen_vortex_patch_geometry(i)
83+
elseif (patch_icpp(i)%geometry == 21) then
84+
call s_check_model_geometry(i)
8385
else
8486
call s_mpi_abort('Unsupported choice of the '// &
8587
'geometry of active patch '//trim(iStr)//&
@@ -851,4 +853,23 @@ contains
851853

852854
end subroutine s_check_inactive_patch_primitive_variables ! ------------
853855

856+
subroutine s_check_model_geometry(patch_id) ! ------------------------------
857+
858+
integer, intent(IN) :: patch_id
859+
860+
logical :: file_exists
861+
862+
inquire(file=patch_icpp(patch_id)%model%filepath, exist=file_exists)
863+
864+
if (.not. file_exists) then
865+
866+
print '(A,I0,A)', 'Model file '//trim(patch_icpp(patch_id)%model%filepath)//&
867+
' requested by patch ', patch_id,' does not exist. Exiting ...'
868+
869+
call s_mpi_abort()
870+
871+
end if
872+
873+
end subroutine s_check_model_geometry ! -----------------------------------
874+
854875
end module m_check_patches

src/pre_process/m_checker.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ subroutine s_check_inputs()
2626
logical :: dir_check !<
2727
!! Logical variable used to test the existence of folders
2828

29+
#ifndef MFC_MPI
30+
if (parallel_io .eqv. .true.) then
31+
print '(A)', 'MFC built with --no-mpi requires parallel_io=F. ' // &
32+
'Exiting ...'
33+
call s_mpi_abort()
34+
end if
35+
#endif
36+
2937
bub_fac = 0
3038
if (bubbles .and. (num_fluids == 1)) bub_fac = 1
3139
! Startup checks for bubbles and bubble variables

0 commit comments

Comments
 (0)