Peano
Loading...
Searching...
No Matches
ContinuousGalerkinDiscretisationGaussLobattoWithBlockJacobi.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import peano4.api
4import jinja2
6import dastgen2
7import os
8
9from .Solver import Solver
10from .actionsets.InitHigherOrderDofs import InitHigherOrderDofs
11from .actionsets.ContinuousGalerkinDiscretisationGaussLobattoWithBlockJacobi.UpdateCell import UpdateCell
12from .actionsets.ContinuousGalerkinDiscretisationGaussLobattoWithBlockJacobi.UpdateFacets import UpdateFacets
13from .actionsets.ContinuousGalerkinDiscretisationGaussLobattoWithBlockJacobi.ProjectResidualsAndDiagonalOntoFacets import ProjectResidualsAndDiagonalOntoFacets
14from .actionsets.PlotDGDataInPeanoBlockFormat import PlotDGDataInPeanoBlockFormat
15
16
18 """!
19
20 Matrix-free Collocated Solver for higher order polynomials.
21
22 This continuous Galerkin p-method works with Gauss-Lobatto nodes only, as we
23 employ a block smoother.
24
25 """
26
27 def __init__(self,
28 name,
29 unknowns_per_node,
30 dimensions,
31 polynomial_degree,
32 min_h,
33 max_h,
34 assembly_matrix,
35 assembly_matrix_scaling,
36 mass_matrix,
37 mass_matrix_scaling,
38 integration_points,
39 solver_tolerance,
40 cell_relaxation,
41 face_relaxation = 0.6,
42 custom_init_actionset = None,
43 custom_plot_actionset = None, # just pass in a list of tuples, one for the variable name and the other for the getter
44 custom_init_cell = "",
45 enable_plotting = True, # sometimes we want to disable standard plotting...
46 plot_predicate = "true" # enable custom plotting behaviour
47 ):
48 """!
49
50 Construct solver
51
52 @param integration_points: [Float]
53 Sequence of polynomial_degree+1 entries which identify the position of
54 the integration points along the unit interval.
55
56 """
57 super( ContinuousGalerkinDiscretisationGaussLobattoWithBlockJacobi, self ).__init__( name,
58 min_h = min_h,
59 max_h = max_h,
60 )
61
62
63 self._dimensions = dimensions
64 self._polynomial_degree = polynomial_degree
65 self._unknowns_per_cell_node = unknowns_per_node
66
67 self._assembly_matrix = assembly_matrix
68 self._assembly_matrix_scaling = assembly_matrix_scaling
69 self._mass_matrix = mass_matrix
70 self._mass_matrix_scaling = mass_matrix_scaling
71
72 self._cell_relaxation = cell_relaxation
73 self._face_relaxation = face_relaxation
74
75 self._solver_tolerance = solver_tolerance
76
77 self._custom_init_actionset = custom_init_actionset
78 self._custom_plot_actionset = custom_plot_actionset
79
80 self._custom_init_cell = custom_init_cell
81
82 self._enable_plotting = enable_plotting
83 self._plot_predicate = plot_predicate
84
85 self._integration_points = integration_points
86
87 # K^c * (p+1)^d
88 self._degrees_of_freedom_per_cell = unknowns_per_node * ( polynomial_degree + 1) ** dimensions
89 self._degrees_of_freedom_per_face = unknowns_per_node * ( polynomial_degree + 1) ** (dimensions-1)
90 self._inner_degrees_of_freedom_per_cell = unknowns_per_node * ( polynomial_degree - 1) ** dimensions
91
92 self._cell_data.data.add_attribute(peano4.api.dastgen2.Peano4DoubleArray( "solution", str(self._degrees_of_freedom_per_cell) ))
93 self._cell_data.data.add_attribute(peano4.api.dastgen2.Peano4DoubleArray( "residual", str(self._degrees_of_freedom_per_cell) ))
94 self._cell_data.data.add_attribute(peano4.api.dastgen2.Peano4DoubleArray( "rhs", str(self._degrees_of_freedom_per_cell) ))
95
96 self._face_data.data.add_attribute(peano4.api.dastgen2.Peano4DoubleArray( "residual", str(self._degrees_of_freedom_per_face) ))
97 self._face_data.data.add_attribute(peano4.api.dastgen2.Peano4DoubleArray( "diagonal", str(self._degrees_of_freedom_per_face) ))
98 self._face_data.data.add_attribute(peano4.api.dastgen2.Peano4DoubleArray( "deltaU", str(self._degrees_of_freedom_per_face) ))
99
102
104
105
106 def add_to_plot(self, observer):
107 """!
108
109 Tell the project's observer how to plot the data
110
111 Nothing fancy here. We add plotters from Peano's toolbox to visualise
112 solution and right-hand side.
113
114 """
115 if self._enable_plotting: # true by default
116 observer.add_action_set( PlotDGDataInPeanoBlockFormat(self, "solution", "getSolution", plot_predicate=self._plot_predicate) )
117 observer.add_action_set( PlotDGDataInPeanoBlockFormat(self, "rhs", "getRhs", plot_predicate=self._plot_predicate) )
118
120 for name, getter in self._custom_plot_actionset:
121 observer.add_action_set( PlotDGDataInPeanoBlockFormat(self, name, getter, plot_predicate=self._plot_predicate) )
122
123 pass
124
125 def add_to_create_grid(self, observer):
127 pass
128
129 def add_to_init_solution(self, observer):
130 """!
131
132 Solution initialisation. We can either use the
133 standard initialisation procedure or pass in
134 another one when we instantiate this solver
135 class.
136
137 """
138 if self._custom_init_actionset is None:
139 observer.add_action_set( InitHigherOrderDofs(self) )
140 else:
141 observer.add_action_set( self._custom_init_actionset(self) )
142 pass
143
145 """!
146
147 Construct the matrix which basically picks out the interior points.
148
149 """
150 result = []
151 if self._dimensions==2:
152 for image_x in range(0,self._polynomial_degree - 1):
153 for image_y in range(0,self._polynomial_degree - 1):
154 for image_unknown in range(0,self._unknowns_per_cell_node):
155 result.append([])
156 for preimage_x in range(0,self._polynomial_degree + 1):
157 for preimage_y in range(0,self._polynomial_degree + 1):
158 for preimage_unknown in range(0,self._unknowns_per_cell_node):
159 if (preimage_x-1==image_x and
160 preimage_y-1==image_y and
161 preimage_unknown==image_unknown):
162 result[-1].append( 1.0 )
163 else:
164 result[-1].append( 0.0 )
165 else:
166 for image_x in range(0,self._polynomial_degree - 1):
167 for image_y in range(0,self._polynomial_degree - 1):
168 for image_z in range(0,self._polynomial_degree - 1):
169 for preimage_unknown in range(0,self._unknowns_per_cell_node):
170 result.append([])
171 for preimage_x in range(0,self._polynomial_degree + 1):
172 for preimage_y in range(0,self._polynomial_degree + 1):
173 for preimage_z in range(0,self._polynomial_degree + 1):
174 for preimage_unknown in range(0,self._unknowns_per_cell_node):
175 if (preimage_x-1==image_x and
176 preimage_y-1==image_y and
177 preimage_z-1==image_z and
178 preimage_unknown==image_unknown):
179 result[-1].append( 1.0 )
180 else:
181 result[-1].append( 0.0 )
182 return result
183
184
185 def add_to_solve(self, observer):
186 new_action_set = UpdateFacets(self)
187 new_action_set.descend_invocation_order = observer.highest_descend_invocation_order() + self._basic_descend_order + 1
188 observer.add_action_set( new_action_set )
189
190 new_action_set = UpdateCell(self)
191 new_action_set.descend_invocation_order = observer.highest_descend_invocation_order() + self._basic_descend_order + 1
192 observer.add_action_set( new_action_set )
193
194 new_action_set = ProjectResidualsAndDiagonalOntoFacets(self)
195 new_action_set.descend_invocation_order = observer.highest_descend_invocation_order() + self._basic_descend_order + 1
196 observer.add_action_set( new_action_set )
197
198 pass
199
200
201 def add_implementation_files_to_project(self, namespace, output, subdirectory="", abstract_overwrite=True):
202 """
203
204 The solver creates two classes: An abstract base class and its
205 implementations. The abstract base class will be overwritten if
206 there is one in the directory. I pipe all the Python constants
207 into this base class, so they are available in the C++ code.
208
209 """
210 templatefile_prefix = os.path.dirname( os.path.realpath(__file__) ) + "/templates/"
211 templatefile_prefix += self.__class__.__name__
212
213 if(subdirectory):
214 subdirectory += "/"
215
216 dictionary = {
217 "SOLVER_INCLUDES" : "",
218 "MIN_H" : self.min_hmin_h,
219 "MAX_H" : self.max_hmax_h,
220 "SOLVER_NAME" : self.typename(),
221 "CELL_CARDINALITY" : self._degrees_of_freedom_per_cell,
222 "INNER_CELL_CARDINALITY" : self._inner_degrees_of_freedom_per_cell,
223 "FACE_CARDINALITY" : self._degrees_of_freedom_per_face,
224 "NODES_PER_CELL" : (self._polynomial_degree + 1) ** self._dimensions,
225 "NODES_PER_FACE" : (self._polynomial_degree + 1) ** (self._dimensions-1),
226 "UNKNOWNS_PER_CELL_NODE" : self._unknowns_per_cell_node,
227 "ASSEMBLY_MATRIX" : self._assembly_matrix,
228 "ASSEMBLY_MATRIX_SCALING" : self._assembly_matrix_scaling,
229 "RHS_MATRIX" : self._mass_matrix,
230 "RHS_MATRIX_SCALING" : self._mass_matrix_scaling,
231 "SOLVER_TOLERANCE" : self._solver_tolerance,
232 "CELL_RELAXATION" : self._cell_relaxation,
233 "FACE_RELAXATION" : self._face_relaxation,
236 "POLY_DEGREE" : self._polynomial_degree,
237 "SOLVER_TOLERANCE" : self._solver_tolerance,
238 "CUSTOM_INIT_CELL" : self._custom_init_cell,
239 "INTEGRATION_POINTS" : self._integration_points,
240 "NARROW_TO_INTERIOR_MATRIX" : self._construct_narrow_to_interior_matrix(),
241 }
242
244 templatefile_prefix + ".Abstract.template.h",
245 templatefile_prefix + ".Abstract.template.cpp",
246 "Abstract" + self.typename(),
247 namespace,
248 subdirectory + ".",
249 dictionary,
250 abstract_overwrite,
251 True)
253 templatefile_prefix + ".template.h",
254 templatefile_prefix + ".template.cpp",
255 self.typename(),
256 namespace,
257 subdirectory + ".",
258 dictionary,
259 False,
260 True)
261
262 output.add( generated_abstract_header_file )
263 output.add( generated_solver_files )
264 output.makefile.add_h_file( subdirectory + "Abstract" + self._name + ".h", generated=True )
265 output.makefile.add_h_file( subdirectory + self._name + ".h", generated=True )
266 output.makefile.add_cpp_file( subdirectory + "Abstract" + self._name + ".cpp", generated=True )
267 output.makefile.add_cpp_file( subdirectory + self._name + ".cpp", generated=True )
268
Specialisation of array using Peano's tarch.
__init__(self, name, unknowns_per_node, dimensions, polynomial_degree, min_h, max_h, assembly_matrix, assembly_matrix_scaling, mass_matrix, mass_matrix_scaling, integration_points, solver_tolerance, cell_relaxation, face_relaxation=0.6, custom_init_actionset=None, custom_plot_actionset=None, custom_init_cell="", enable_plotting=True, plot_predicate="true" # enable custom plotting behaviour)
Construct solver.
add_implementation_files_to_project(self, namespace, output, subdirectory="", abstract_overwrite=True)
The solver creates two classes: An abstract base class and its implementations.
Abstract base class for matrix free solvers.
Definition Solver.py:9
Init the degrees of freedom of a higher order scheme where nodes sit in cells.