Skip to content

Commit e70ca5f

Browse files
committed
init commit
0 parents  commit e70ca5f

File tree

6 files changed

+685
-0
lines changed

6 files changed

+685
-0
lines changed

metal_go.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
3+
##SBATCH --nodes=1
4+
##SBATCH --ntasks-per-node=24
5+
#SBATCH --time=00:10:00
6+
#SBATCH --account=m18
7+
8+
# write this script and env to stdout
9+
scontrol show job ${SLURM_JOBID} -ddd
10+
env
11+
12+
module swap PrgEnv-cray PrgEnv-gnu
13+
module load /home/jmansour/software/cle60up05/modulefiles/petsc/3.9.4
14+
module load python/3.6.3
15+
module load numpy mpi4py
16+
17+
export PYTHONPATH=/home/jmansour/underworld2:/home/jmansour/underworld2/glucifer:$PYTHONPATH
18+
export PREFIXSTRING=`head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''`
19+
20+
21+
export TIME_LAUNCH_SRUN=`date +%s%N | cut -b1-13`
22+
srun -n ${SLURM_NTASKS} bash -c "TIME_LAUNCH_PYTHON=\`date +%s%N | cut -b1-13\` python3 rt_timed.py"

rt_timed.py

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import os
2+
os.environ["UW_ENABLE_TIMING"] = "1"
3+
import underworld as uw
4+
from underworld import function as fn
5+
import glucifer
6+
import math
7+
import numpy as np
8+
import time
9+
time_post_import = time.time()
10+
time_launch_srun = float(os.environ["TIME_LAUNCH_SRUN"])/1000.
11+
time_launch_python = float(os.environ["TIME_LAUNCH_PYTHON"])/1000.
12+
uw.timing.start()
13+
14+
if os.environ["UW_ENABLE_IO"] == "1":
15+
do_IO=True
16+
else:
17+
do_IO=False
18+
19+
other_timing = {}
20+
other_timing["Python_Import_Time"] = time_post_import - time_launch_python
21+
other_timing["Container_Launch_Time"] = time_launch_python - time_launch_srun
22+
23+
res = 64
24+
RESKEY = "UW_RESOLUTION"
25+
if RESKEY in os.environ:
26+
res = int(os.environ[RESKEY])
27+
28+
PREFIX = os.environ["PREFIXSTRING"]
29+
30+
mesh = uw.mesh.FeMesh_Cartesian(elementRes = (res, res, res),
31+
minCoord = ( 0., 0., 0., ),
32+
maxCoord = ( 1., 1., 1., ))
33+
34+
velocityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=3 )
35+
pressureField = uw.mesh.MeshVariable( mesh=mesh.subMesh, nodeDofCount=1 )
36+
temperatureField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )
37+
temperatureFieldDeriv = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )
38+
39+
# initialise
40+
velocityField.data[:] = [0.,0.,0.]
41+
pressureField.data[:] = 0.
42+
43+
for index, coord in enumerate(mesh.data):
44+
temperatureField.data[index] = coord[2]
45+
46+
temperatureFieldDeriv.data[:] = 0.
47+
48+
49+
# Create a swarm.
50+
swarm = uw.swarm.Swarm( mesh=mesh )
51+
52+
# Create a data variable. It will be used to store the material index of each particle.
53+
materialIndex = swarm.add_variable( dataType="int", count=1 )
54+
55+
# Create a layout object, populate the swarm with particles.
56+
swarmLayout = uw.swarm.layouts.PerCellSpaceFillerLayout( swarm=swarm, particlesPerCell=40 )
57+
swarm.populate_using_layout( layout=swarmLayout )
58+
59+
60+
61+
# define these for convience.
62+
denseIndex = 0
63+
lightIndex = 1
64+
65+
# material perturbation from van Keken et al. 1997
66+
wavelength = 2.0
67+
amplitude = 0.02
68+
offset = 0.2
69+
k = 2. * math.pi / wavelength
70+
71+
# Create function to return particle's coordinate
72+
coord = fn.coord()
73+
74+
# Define the material perturbation, a function of the x coordinate (accessed by `coord[0]`).
75+
perturbationFn = offset + amplitude*fn.math.cos( k*coord[0] )
76+
77+
# Setup the conditions list.
78+
# If z is less than the perturbation, set to lightIndex.
79+
conditions = [ ( perturbationFn > coord[1] , lightIndex ),
80+
( True , denseIndex ) ]
81+
82+
# The swarm is passed as an argument to the evaluation, providing evaluation on each particle.
83+
# Results are written to the materialIndex swarm variable.
84+
fnc = fn.branching.conditional( conditions )
85+
matdat = fnc.evaluate(swarm)
86+
materialIndex.data[:] = matdat
87+
88+
store = glucifer.Store('{}_RT'.format(PREFIX),compress=False)
89+
90+
fig = glucifer.Figure( store, name="firstFig" )
91+
fig.append( glucifer.objects.Points(swarm, materialIndex, pointSize=2, colourBar=False) )
92+
fig.append( glucifer.objects.Surface(mesh, pressureField))
93+
fig.append( glucifer.objects.VectorArrows( mesh, velocityField, scaling=1.0e2))
94+
95+
96+
# Set a density of '0.' for light material, '1.' for dense material.
97+
densityMap = { lightIndex:0., denseIndex:1. }
98+
densityFn = fn.branching.map( fn_key = materialIndex, mapping = densityMap )
99+
100+
# Set a viscosity value of '1.' for both materials.
101+
viscosityMap = { lightIndex:1., denseIndex:1. }
102+
fn_viscosity = fn.branching.map( fn_key = materialIndex, mapping = viscosityMap )
103+
104+
# Define a vertical unit vector using a python tuple.
105+
z_hat = ( 0., 0., 1. )
106+
107+
# Create buoyancy force vector
108+
buoyancyFn = -densityFn*z_hat
109+
110+
111+
# Construct node sets using the mesh specialSets
112+
iWalls = mesh.specialSets["MinI_VertexSet"] + mesh.specialSets["MaxI_VertexSet"]
113+
jWalls = mesh.specialSets["MinJ_VertexSet"] + mesh.specialSets["MaxJ_VertexSet"]
114+
kWalls = mesh.specialSets["MinK_VertexSet"] + mesh.specialSets["MaxK_VertexSet"]
115+
116+
allWalls = iWalls + jWalls + kWalls
117+
118+
# Prescribe degrees of freedom on each node to be considered Dirichlet conditions.
119+
# In the x direction on allWalls flag as Dirichlet
120+
# In the y direction on jWalls (horizontal) flag as Dirichlet
121+
stokesBC = uw.conditions.DirichletCondition( variable = velocityField,
122+
indexSetsPerDof = (allWalls, allWalls, kWalls))
123+
advdiffBc = uw.conditions.DirichletCondition( variable = temperatureField,
124+
indexSetsPerDof = kWalls )
125+
126+
stokes = uw.systems.Stokes( velocityField = velocityField,
127+
pressureField = pressureField,
128+
# voronoi_swarm = swarm,
129+
conditions = stokesBC,
130+
fn_viscosity = fn_viscosity,
131+
fn_bodyforce = buoyancyFn )
132+
133+
solver = uw.systems.Solver( stokes )
134+
135+
# Create a system to advect the swarm
136+
advector = uw.systems.SwarmAdvector( swarm=swarm, velocityField=velocityField, order=2 )
137+
138+
# Create a dummy temperature field.
139+
advdiff = uw.systems.AdvectionDiffusion(velocityField=velocityField, phiField=temperatureField, phiDotField=temperatureFieldDeriv,
140+
fn_diffusivity=1.,conditions=advdiffBc)
141+
142+
143+
# functions for calculating RMS velocity
144+
vdotv = fn.math.dot(velocityField,velocityField)
145+
v2sum_integral = uw.utils.Integral( mesh=mesh, fn=vdotv )
146+
volume_integral = uw.utils.Integral( mesh=mesh, fn=1. )
147+
148+
149+
# Get instantaneous Stokes solution
150+
solver.solve()
151+
# Calculate the RMS velocity.
152+
vrms = math.sqrt( v2sum_integral.evaluate()[0] )
153+
154+
155+
# update
156+
dt1 = advector.get_max_dt()
157+
dt2 = advdiff.get_max_dt()
158+
dt = min(dt1,dt2)
159+
# Advect using this timestep size.
160+
advector.integrate(dt)
161+
162+
advdiff.integrate(dt)
163+
164+
# Save things
165+
166+
if do_IO:
167+
meshFileHandle = mesh.save("{}_Mesh.h5".format(PREFIX))
168+
169+
vFH = velocityField.save("{}_velocityField.h5".format(PREFIX))
170+
velocityField.xdmf( "{}_velocityField".format(PREFIX), vFH, "velocity", meshFileHandle, "Mesh" )
171+
172+
swarmFileHandle = swarm.save("{}_Swarm.h5".format(PREFIX))
173+
mH = materialIndex.save("{}_materialIndex.h5".format(PREFIX))
174+
materialIndex.xdmf("{}_materialIndex".format(PREFIX), mH, "material", swarmFileHandle, "Swarm" )
175+
176+
fig.save()
177+
178+
# load things
179+
# first create analogues
180+
mesh_copy = uw.mesh.FeMesh_Cartesian(
181+
elementRes = (res, res, res),
182+
minCoord = (20., 20., 20.),
183+
maxCoord = (33., 33., 33.))
184+
185+
velocityField_copy = uw.mesh.MeshVariable( mesh=mesh_copy, nodeDofCount=3 )
186+
187+
swarm_copy = uw.swarm.Swarm(mesh = mesh_copy)
188+
materialIndex_copy = swarm_copy.add_variable( dataType="int", count=1 )
189+
190+
# now load data and check loaded versions are identical to originals
191+
mesh_copy.load("{}_Mesh.h5".format(PREFIX))
192+
193+
# test
194+
if not np.allclose(mesh_copy.data, mesh.data):
195+
raise RuntimeError("Loaded mesh data does not appear to be identical to previous data.")
196+
velocityField_copy.load("{}_velocityField.h5".format(PREFIX))
197+
if not np.allclose(velocityField_copy.data, velocityField.data):
198+
raise RuntimeError("Loaded velocity data does not appear to be identical to previous data.")
199+
200+
201+
swarm_copy.load("{}_Swarm.h5".format(PREFIX))
202+
203+
if not np.allclose(swarm_copy.particleCoordinates.data, swarm.particleCoordinates.data):
204+
raise RuntimeError("Loaded swarm data does not appear to be identical to previous data.")
205+
materialIndex_copy.load("{}_materialIndex.h5".format(PREFIX))
206+
if not np.allclose(materialIndex_copy.data, materialIndex.data):
207+
raise RuntimeError("Loaded material data does not appear to be identical to previous data.")
208+
209+
uw.timing.stop()
210+
module_timing_data_orig = uw.timing.get_data(group_by="routine")
211+
212+
# write out data
213+
filename = "{}_Res_{}_Nproc_{}_SlurmID_{}".format(os.environ["SLURM_JOB_NAME"],res,uw.mpi.size,os.environ["SLURM_JOB_ID"])
214+
import json
215+
if module_timing_data_orig:
216+
module_timing_data = {}
217+
for key,val in module_timing_data_orig.items():
218+
module_timing_data[key[0]] = val
219+
other_timing["Total_Runtime"] = uw.timing._endtime-uw.timing._starttime
220+
module_timing_data["Other_timing"] = other_timing
221+
module_timing_data["Other_data"] = {"vrms":vrms, "res":res, "nproc":uw.mpi.size}
222+
with open(filename+".json", 'w') as fp:
223+
json.dump(module_timing_data, fp,sort_keys=True, indent=4)
224+
225+
uw.timing.print_table(group_by="routine", output_file=filename+".txt", display_fraction=0.99)

0 commit comments

Comments
 (0)