@@ -106,77 +106,77 @@ def compute_bounds(self, field):
106106 # Call general-purpose bound computation.
107107 super (VertexBasedP1DGLimiter , self ).compute_bounds (field )
108108
109- # Add the average of lateral boundary facets to min/max fields
110- # NOTE this just computes the arithmetic mean of nodal values on the facet,
111- # which in general is not equivalent to the mean of the field over the bnd facet.
112- # This is OK for P1DG triangles, but not exact for the extruded case (quad facets)
113- from finat .finiteelementbase import entity_support_dofs
114-
115- if self .is_2d :
116- entity_dim = 1 # get 1D facets
117- else :
118- entity_dim = (1 , 1 ) # get vertical facets
119- boundary_dofs = entity_support_dofs (self .P1DG .finat_element , entity_dim )
120- local_facet_nodes = np .array ([boundary_dofs [e ] for e in sorted (boundary_dofs .keys ())])
121- n_bnd_nodes = local_facet_nodes .shape [1 ]
122- local_facet_idx = op2 .Global (local_facet_nodes .shape , local_facet_nodes , dtype = np .int32 , name = 'local_facet_idx' )
123- code = """
124- void my_kernel(double *qmax, double *qmin, double *field, unsigned int *facet, unsigned int *local_facet_idx)
125- {
126- double face_mean = 0.0;
127- for (int i = 0; i < %(nnodes)d; i++) {
128- unsigned int idx = local_facet_idx[facet[0]*%(nnodes)d + i];
129- face_mean += field[idx];
130- }
131- face_mean /= %(nnodes)d;
132- for (int i = 0; i < %(nnodes)d; i++) {
133- unsigned int idx = local_facet_idx[facet[0]*%(nnodes)d + i];
134- qmax[idx] = fmax(qmax[idx], face_mean);
135- qmin[idx] = fmin(qmin[idx], face_mean);
136- }
137- }"""
138- bnd_kernel = op2 .Kernel (code % {'nnodes' : n_bnd_nodes }, 'my_kernel' )
139- op2 .par_loop (bnd_kernel ,
140- self .P1DG .mesh ().exterior_facets .set ,
141- self .max_field .dat (op2 .MAX , self .max_field .exterior_facet_node_map ()),
142- self .min_field .dat (op2 .MIN , self .min_field .exterior_facet_node_map ()),
143- field .dat (op2 .READ , field .exterior_facet_node_map ()),
144- self .P1DG .mesh ().exterior_facets .local_facet_dat (op2 .READ ),
145- local_facet_idx (op2 .READ ))
146- if not self .is_2d :
147- # Add nodal values from surface/bottom boundaries
148- # NOTE calling firedrake par_loop with measure=ds_t raises an error
149- bottom_nodes = get_facet_mask (self .P1CG , 'geometric' , 'bottom' )
150- top_nodes = get_facet_mask (self .P1CG , 'geometric' , 'top' )
151- bottom_idx = op2 .Global (len (bottom_nodes ), bottom_nodes , dtype = np .int32 , name = 'node_idx' )
152- top_idx = op2 .Global (len (top_nodes ), top_nodes , dtype = np .int32 , name = 'node_idx' )
153- code = """
154- void my_kernel(double *qmax, double *qmin, double *field, int *idx) {
155- double face_mean = 0;
156- for (int i=0; i<%(nnodes)d; i++) {
157- face_mean += field[idx[i]];
158- }
159- face_mean /= %(nnodes)d;
160- for (int i=0; i<%(nnodes)d; i++) {
161- qmax[idx[i]] = fmax(qmax[idx[i]], face_mean);
162- qmin[idx[i]] = fmin(qmin[idx[i]], face_mean);
163- }
164- }"""
165- kernel = op2 .Kernel (code % {'nnodes' : len (bottom_nodes )}, 'my_kernel' )
166-
167- op2 .par_loop (kernel , self .mesh .cell_set ,
168- self .max_field .dat (op2 .MAX , self .max_field .function_space ().cell_node_map ()),
169- self .min_field .dat (op2 .MIN , self .min_field .function_space ().cell_node_map ()),
170- field .dat (op2 .READ , field .function_space ().cell_node_map ()),
171- bottom_idx (op2 .READ ),
172- iterate = op2 .ON_BOTTOM )
173-
174- op2 .par_loop (kernel , self .mesh .cell_set ,
175- self .max_field .dat (op2 .MAX , self .max_field .function_space ().cell_node_map ()),
176- self .min_field .dat (op2 .MIN , self .min_field .function_space ().cell_node_map ()),
177- field .dat (op2 .READ , field .function_space ().cell_node_map ()),
178- top_idx (op2 .READ ),
179- iterate = op2 .ON_TOP )
109+ # # Add the average of lateral boundary facets to min/max fields
110+ # # NOTE this just computes the arithmetic mean of nodal values on the facet,
111+ # # which in general is not equivalent to the mean of the field over the bnd facet.
112+ # # This is OK for P1DG triangles, but not exact for the extruded case (quad facets)
113+ # from finat.finiteelementbase import entity_support_dofs
114+ #
115+ # if self.is_2d:
116+ # entity_dim = 1 # get 1D facets
117+ # else:
118+ # entity_dim = (1, 1) # get vertical facets
119+ # boundary_dofs = entity_support_dofs(self.P1DG.finat_element, entity_dim)
120+ # local_facet_nodes = np.array([boundary_dofs[e] for e in sorted(boundary_dofs.keys())])
121+ # n_bnd_nodes = local_facet_nodes.shape[1]
122+ # local_facet_idx = op2.Global(local_facet_nodes.shape, local_facet_nodes, dtype=np.int32, name='local_facet_idx')
123+ # code = """
124+ # void my_kernel(double *qmax, double *qmin, double *field, unsigned int *facet, unsigned int *local_facet_idx)
125+ # {
126+ # double face_mean = 0.0;
127+ # for (int i = 0; i < %(nnodes)d; i++) {
128+ # unsigned int idx = local_facet_idx[facet[0]*%(nnodes)d + i];
129+ # face_mean += field[idx];
130+ # }
131+ # face_mean /= %(nnodes)d;
132+ # for (int i = 0; i < %(nnodes)d; i++) {
133+ # unsigned int idx = local_facet_idx[facet[0]*%(nnodes)d + i];
134+ # qmax[idx] = fmax(qmax[idx], face_mean);
135+ # qmin[idx] = fmin(qmin[idx], face_mean);
136+ # }
137+ # }"""
138+ # bnd_kernel = op2.Kernel(code % {'nnodes': n_bnd_nodes}, 'my_kernel')
139+ # op2.par_loop(bnd_kernel,
140+ # self.P1DG.mesh().exterior_facets.set,
141+ # self.max_field.dat(op2.MAX, self.max_field.exterior_facet_node_map()),
142+ # self.min_field.dat(op2.MIN, self.min_field.exterior_facet_node_map()),
143+ # field.dat(op2.READ, field.exterior_facet_node_map()),
144+ # self.P1DG.mesh().exterior_facets.local_facet_dat(op2.READ),
145+ # local_facet_idx(op2.READ))
146+ # if not self.is_2d:
147+ # # Add nodal values from surface/bottom boundaries
148+ # # NOTE calling firedrake par_loop with measure=ds_t raises an error
149+ # bottom_nodes = get_facet_mask(self.P1CG, 'geometric', 'bottom')
150+ # top_nodes = get_facet_mask(self.P1CG, 'geometric', 'top')
151+ # bottom_idx = op2.Global(len(bottom_nodes), bottom_nodes, dtype=np.int32, name='node_idx')
152+ # top_idx = op2.Global(len(top_nodes), top_nodes, dtype=np.int32, name='node_idx')
153+ # code = """
154+ # void my_kernel(double *qmax, double *qmin, double *field, int *idx) {
155+ # double face_mean = 0;
156+ # for (int i=0; i<%(nnodes)d; i++) {
157+ # face_mean += field[idx[i]];
158+ # }
159+ # face_mean /= %(nnodes)d;
160+ # for (int i=0; i<%(nnodes)d; i++) {
161+ # qmax[idx[i]] = fmax(qmax[idx[i]], face_mean);
162+ # qmin[idx[i]] = fmin(qmin[idx[i]], face_mean);
163+ # }
164+ # }"""
165+ # kernel = op2.Kernel(code % {'nnodes': len(bottom_nodes)}, 'my_kernel')
166+ #
167+ # op2.par_loop(kernel, self.mesh.cell_set,
168+ # self.max_field.dat(op2.MAX, self.max_field.function_space().cell_node_map()),
169+ # self.min_field.dat(op2.MIN, self.min_field.function_space().cell_node_map()),
170+ # field.dat(op2.READ, field.function_space().cell_node_map()),
171+ # bottom_idx(op2.READ),
172+ # iterate=op2.ON_BOTTOM)
173+ #
174+ # op2.par_loop(kernel, self.mesh.cell_set,
175+ # self.max_field.dat(op2.MAX, self.max_field.function_space().cell_node_map()),
176+ # self.min_field.dat(op2.MIN, self.min_field.function_space().cell_node_map()),
177+ # field.dat(op2.READ, field.function_space().cell_node_map()),
178+ # top_idx(op2.READ),
179+ # iterate=op2.ON_TOP)
180180
181181 def apply (self , field ):
182182 """
0 commit comments