55from mpi4py import MPI
66import time
77import meshio
8- import dolfinx
8+ import dolfinx
9+ from dolfinx .fem import petsc # load submodule
910from os import path
1011from petsc4py import PETSc
1112import ufl
13+ from basix .ufl import element
1214import sys
1315import time
1416from dataclasses import dataclass
@@ -82,7 +84,7 @@ class UniformNodeGridFixedSizeMeshModel:
8284 def __init__ (self , builder :Builder ,parameters :Parameters , sedimentsOnly = False , padding_num_nodes = 0 ):
8385 self ._builder = builder
8486 self ._parameters = parameters
85- self .node1D = self . _builder . node_flat () # [n for n in self._builder.iter_node()]
87+ self .node1D = [n for n in self ._builder .iter_node ()] # self._builder.node_flat()
8688 self .num_nodes = len (self .node1D )
8789 self .mesh = None
8890
@@ -169,7 +171,7 @@ def write_tetra_mesh_resqml( self, out_path):
169171 def boundary (x ):
170172 return np .full (x .shape [1 ], True )
171173 entities = dolfinx .mesh .locate_entities (self .mesh , 3 , boundary )
172- tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh , 3 , entities , False )
174+ tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh . _cpp_object , 3 , entities , False )
173175 p0 = self .mesh .geometry .x [tet ,:]
174176 tet_to_keep = []
175177 p_to_keep = set ()
@@ -217,7 +219,7 @@ def boundary(x):
217219
218220 def send_mpi_messages_per_timestep (self ):
219221 comm = MPI .COMM_WORLD
220- comm .send (self .mesh .topology .index_map (0 ).local_to_global (list ( range ( self .mesh .geometry .x .shape [0 ]) )) , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 1021 )
222+ comm .send (self .mesh .topology .index_map (0 ).local_to_global ( np . arange ( self .mesh .geometry .x .shape [0 ])) , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 1021 )
221223 comm .send (self .mesh_reindex , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 1023 )
222224 comm .send (self .mesh_vertices_age , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 1025 )
223225 comm .send (self .mesh .geometry .x .copy (), dest = 0 , tag = ( (comm .rank - 1 )* 10 )+ 1020 )
@@ -229,7 +231,7 @@ def receive_mpi_messages_per_timestep(self):
229231 self .sub_posarr_s = [self .mesh .geometry .x .copy ()]
230232 self .sub_Tarr_s = [self .uh .x .array [:].copy ()]
231233
232- self .index_map_s = [self .mesh .topology .index_map (0 ).local_to_global (list ( range ( self .mesh .geometry .x .shape [0 ]))) ]
234+ self .index_map_s = [self .mesh .topology .index_map (0 ).local_to_global ( np . arange ( self .mesh .geometry .x .shape [0 ])) ]
233235 self .mesh_reindex_s = [self .mesh_reindex ]
234236 self .mesh_vertices_age_s = [self .mesh_vertices_age ]
235237
@@ -269,7 +271,7 @@ def receive_mpi_messages(self):
269271 self .sub_posarr_s = [self .posarr ]
270272 self .sub_Tarr_s = [self .Tarr ]
271273
272- self .index_map_s = [self .mesh .topology .index_map (0 ).local_to_global (list ( range ( self .mesh .geometry .x .shape [0 ]) ))]
274+ self .index_map_s = [self .mesh .topology .index_map (0 ).local_to_global ( np . arange ( self .mesh .geometry .x .shape [0 ]))]
273275 self .mesh_reindex_s = [self .mesh_reindex ]
274276 self .mesh_vertices_age_s = [self .mesh_vertices_age ]
275277
@@ -702,17 +704,17 @@ def updateVertices(self):
702704 def buildMesh (self ,tti :int ):
703705 """Construct a new mesh at the given time index tti, and determine the vertex re-indexing induced by dolfinx
704706 """
705- logging .info ("Building 3D mesh" )
706707 self .tti = tti
707708 self .buildVertices (time_index = tti )
708709 self .constructMesh ()
709- self .updateMesh (tti )
710+ self .updateMesh (tti )
711+ logger .debug (f"Updated vertices for time { tti } " )
712+
710713
711714 def updateMesh (self ,tti :int , optimized = False ):
712715 """Construct the mesh positions at the given time index tti, and update the existing mesh with the new values
713716 """
714717 assert self .mesh is not None
715- logging .info (f"Updating 3D mesh for time { tti } " )
716718 self .tti = tti
717719 self .buildVertices (time_index = tti , optimized = optimized )
718720 self .updateVertices ()
@@ -879,10 +881,12 @@ def sedimentsConductivitySekiguchi(self):
879881 """
880882 def boundary (x ):
881883 return np .full (x .shape [1 ], True )
882- entities = dolfinx .mesh .locate_entities (self .mesh , 3 , boundary )
883- tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh , 3 , entities , False )
884+ tdim = self .mesh .topology .dim # 3 on a tetrahedral mesh
885+ entities = dolfinx .mesh .locate_entities (self .mesh , tdim , boundary )
886+ entities .flags .writeable = False
887+ tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh ._cpp_object , tdim , entities , False )
888+
884889 self .layer_id_per_vertex = [ [] for _ in range (self .mesh .geometry .x .shape [0 ]) ]
885- ##
886890
887891 top_km = (np .min (self .mesh .geometry .x [tet ,2 ], 1 )- self .subsidence_at_nodes [:,self .tti ]) * 1e-3
888892 bottom_km = (np .max (self .mesh .geometry .x [tet ,2 ], 1 )- self .subsidence_at_nodes [:,self .tti ]) * 1e-3
@@ -913,7 +917,7 @@ def getCellMidpoints(self):
913917 def boundary (x ):
914918 return np .full (x .shape [1 ], True )
915919 entities = dolfinx .mesh .locate_entities (self .mesh , 3 , boundary )
916- tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh , 3 , entities , False )
920+ tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh . _cpp_object , 3 , entities , False )
917921 self .layer_id_per_vertex = [ [] for _ in range (self .mesh .geometry .x .shape [0 ]) ]
918922 midp = []
919923 for i ,t in enumerate (tet ):
@@ -933,7 +937,7 @@ def buildKappaAndLayerIDs(self):
933937
934938 self .mesh_vertex_layerIDs = np .full_like (self .mesh .geometry .x [:,2 ], 100 , dtype = np .int32 )
935939 # piecewise constant Kappa in the tetrahedra
936- Q = dolfinx .fem .FunctionSpace (self .mesh , ("DG" , 0 )) # discontinuous Galerkin, degree zero
940+ Q = dolfinx .fem .functionspace (self .mesh , ("DG" , 0 )) # discontinuous Galerkin, degree zero
937941 thermalCond = dolfinx .fem .Function (Q )
938942 c_rho = dolfinx .fem .Function (Q )
939943 self .c_rho0 = dolfinx .fem .Function (Q )
@@ -953,7 +957,7 @@ def boundary(x):
953957 return np .full (x .shape [1 ], True )
954958
955959 entities = dolfinx .mesh .locate_entities (self .mesh , 3 , boundary )
956- tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh , 3 , entities , False )
960+ tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh . _cpp_object , 3 , entities , False )
957961
958962 p0 = self .mesh .geometry .x [tet ,:]
959963 midp = np .sum (p0 ,1 )* 0.25 # midpoints of tetrahedra
@@ -1133,8 +1137,8 @@ def setupSolver(self, initial_state_model = None):
11331137
11341138 #
11351139 # define function space
1136- self .FE = ufl . FiniteElement ("CG" , self .mesh .ufl_cell (), self .CGorder )
1137- self .V = dolfinx .fem .FunctionSpace (self .mesh , self .FE )
1140+ self .FE = element ("CG" , self .mesh .basix_cell (), self .CGorder )
1141+ self .V = dolfinx .fem .functionspace (self .mesh , self .FE )
11381142
11391143 # Define solution variable uh
11401144 self .uh = dolfinx .fem .Function (self .V )
@@ -1264,15 +1268,16 @@ def marker(x):
12641268
12651269 g = (- 1.0 * baseFlux ) * ufl .conditional ( domain_c > 0 , 1.0 , 0.0 )
12661270 L = (self .c_rho * self .u_n + dt * f )* v * ufl .dx - dt * g * v * ufl .ds # last term reflects Neumann BC
1271+
12671272 else :
12681273 L = (self .c_rho * self .u_n + dt * f )* v * ufl .dx # no Neumann BC
12691274
12701275 bilinear_form = dolfinx .fem .form (a )
12711276 linear_form = dolfinx .fem .form (L )
12721277
1273- A = dolfinx . fem . petsc .assemble_matrix (bilinear_form , bcs = [self .bc ])
1278+ A = petsc .assemble_matrix (bilinear_form , bcs = [self .bc ])
12741279 A .assemble ()
1275- b = dolfinx . fem . petsc .create_vector (linear_form )
1280+ b = petsc .assemble_vector (linear_form )
12761281
12771282 comm = MPI .COMM_WORLD
12781283 solver = PETSc .KSP ().create (self .mesh .comm )
@@ -1286,20 +1291,18 @@ def marker(x):
12861291 # Update the right hand side reusing the initial vector
12871292 with b .localForm () as loc_b :
12881293 loc_b .set (0 )
1289- dolfinx . fem . petsc .assemble_vector (b , linear_form )
1294+ petsc .assemble_vector (b , linear_form )
12901295
12911296 # TODO: update Dirichlet BC at every time step:
12921297 # the temperature at the base of Asth is set such that it reaches Tm at the current depth of the LAB (using the slope adiab=0.0003)
12931298 # bc = self.buildDirichletBC()
12941299
12951300 # Apply Dirichlet boundary condition to the vector
1296- dolfinx . fem . petsc .apply_lifting (b , [bilinear_form ], [[self .bc ]])
1301+ petsc .apply_lifting (b , [bilinear_form ], [[self .bc ]])
12971302 b .ghostUpdate (addv = PETSc .InsertMode .ADD_VALUES , mode = PETSc .ScatterMode .REVERSE )
1298-
1299- dolfinx .fem .petsc .set_bc (b , [self .bc ])
1300-
1303+ petsc .set_bc (b , [self .bc ])
13011304 # Solve linear problem
1302- solver .solve (b , self .uh .vector )
1305+ solver .solve (b , self .uh .x . petsc_vec )
13031306 self .uh .x .scatter_forward ()
13041307
13051308 # Update solution at previous time step (u_n)
@@ -1570,7 +1573,7 @@ def boundary(x):
15701573 return np .full (x .shape [1 ], True )
15711574
15721575 entities = dolfinx .mesh .locate_entities (self .mesh , 3 , boundary )
1573- tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh , 3 , entities , False )
1576+ tet = dolfinx .cpp .mesh .entities_to_geometry (self .mesh . _cpp_object , 3 , entities , False )
15741577
15751578 p0 = self .mesh .geometry .x [tet ,:]
15761579 totalvol = 0
@@ -1828,7 +1831,7 @@ def run_3d( builder:Builder, parameters:Parameters, start_time=182, end_time=0,
18281831 if comm .rank == 0 :
18291832 logger .info (f"total time solve 3D: { time_solve } " )
18301833 if comm .rank >= 1 :
1831- comm .send (mm2 .mesh .topology .index_map (0 ).local_to_global (list ( range ( mm2 .mesh .geometry .x .shape [0 ]) )) , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 21 )
1834+ comm .send (mm2 .mesh .topology .index_map (0 ).local_to_global (np . arange ( mm2 .mesh .geometry .x .shape [0 ])) , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 21 )
18321835 comm .send (mm2 .mesh_reindex , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 23 )
18331836 comm .send (mm2 .mesh_vertices_age , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 25 )
18341837 comm .send (mm2 .posarr , dest = 0 , tag = ((comm .rank - 1 )* 10 )+ 20 )
@@ -1845,4 +1848,4 @@ def run_3d( builder:Builder, parameters:Parameters, start_time=182, end_time=0,
18451848 toc (msg = "write mesh and timeseries to file" )
18461849 read_mesh_resqml_hexa (EPCfilename_ts ) # test reading of the .epc file
18471850 comm .Barrier ()
1848- return mm2
1851+ return mm2
0 commit comments