Skip to content
Snippets Groups Projects
Commit b1cc06a0 authored by Stephan Seitz's avatar Stephan Seitz
Browse files

Start work on walbera app generation

parent 3448e834
Branches
Tags
No related merge requests found
Pipeline #21352 failed
#
# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
#
# Distributed under terms of the GPLv3 license.
"""
"""
from os.path import dirname, join
import jinja2
from pystencils.data_types import TypedSymbol
from pystencils_autodiff._file_io import read_template_from_file
from pystencils_autodiff.framework_integration.astnodes import JinjaCppFile
class WalberlaModule(JinjaCppFile):
TEMPLATE = read_template_from_file(join(dirname(__file__), 'walberla_main.tmpl.cpp'))
def __init__(self, main):
ast_dict = {'main': main}
JinjaCppFile.__init__(self, ast_dict)
class WalberlaMain(JinjaCppFile):
TEMPLATE = jinja2.Template("""
int main( int argc, char ** argv )
{
using namespace walberla;
Environment {{ walberl_env }}( argc, argv );
{{ body | indent(3) }}
return EXIT_SUCCESS;
}
""")
headers = ['"core/Environment.h"',
'<cstdlib>',
'"UserDefinitions.h"']
def __init__(self, body, walberl_env="walberlaEnv"):
ast_dict = {
'body': body,
'walberl_env': TypedSymbol(walberl_env, "Environment")
}
super().__init__(ast_dict)
@property
def symbols_defined(self):
return {self.ast_dict.walberl_env}
class BlockForrestCreation(JinjaCppFile):
TEMPLATE = jinja2.Template("""auto {{ blocks }} = walberla_user::createBlockForrest(walberlaEnv);""")
def __init__(self, block_forrest_name):
ast_dict = {
'blocks': TypedSymbol(block_forrest_name, "auto")
}
super().__init__(ast_dict)
@property
def symbols_defined(self):
return {self.ast_dict.blocks}
class UniformBlockForrestFromConfig(BlockForrestCreation):
TEMPLATE = jinja2.Template(
"""auto {{ blocks }} = blockforest::createUniformBlockGridFromConfig( walberlaEnv.config() );""")
headers = ['"blockforest/Initialization.h"']
def __init__(self):
super().__init__('blocks')
@property
def config_required(self):
return {"DomainSetup": {"blocks": [1, 1, 1], "cellsPerBlock": [100, 100, 100]}}
@property
def blocks(self):
return self.ast_dict.blocks
class DefinitionsHeader(JinjaCppFile):
TEMPLATE = read_template_from_file(join(dirname(__file__), 'walberla_user_defintions.tmpl.hpp'))
def __init__(self, walberla_module):
self.main_module = walberla_module
super().__init__({})
@property
def config_required(self):
return {"DomainSetup": {"blocks": [1, 1, 1], "cellsPerBlock": [100, 100, 100]}}
class Using(JinjaCppFile):
TEMPLATE = jinja2.Template("using {{ new_type }} = {{ definition }};\n")
def __init__(self, new_type, definition):
ast_dict = {
'new_type': new_type,
'definition': definition,
}
super().__init__(ast_dict)
@property
def symbols_defined(self):
return {self.ast_dict.new_type}
class GetParameter(JinjaCppFile):
TEMPLATE = jinja2.Template(
'walberlaEnv.config()->getOneBlock("{{ block }}").getParameter<{{ key.dtype }}>("{{ key }}"{% if default %}, {{ default }}{% endif %})' # noqa
)
def __init__(self, block: str, key, default_value=None):
ast_dict = {
'key': key,
'block': block,
'default': default_value
}
super().__init__(ast_dict)
@property
def config_required(self):
return {self.ast_dict.block: {self.ast_dict.symbol: self.ast_dict.default_value}}
def __sympy__(self):
return TypedSymbol(self.ast_dict.key.name + "Config", str(self.ast_dict.key.dtype))
class FieldAllocation(JinjaCppFile):
"""
.. code:: cpp
BlockDataID addToStorage(const shared_ptr < BlockStorage_T > & blocks,
const std:: string & identifier,
const typename GhostLayerField_T:: value_type & initValue = typename GhostLayerField_T: : value_type(),
const Layout layout=zyxf,
const uint_t nrOfGhostLayers=uint_t(1),
const bool alwaysInitialize=false,
const std:: function < void (GhostLayerField_T * field, IBlock * const block ) > & initFunction =
std: : function < void (GhostLayerField_T * field, IBlock * const block ) > (),
const Set < SUID > & requiredSelectors = Set < SUID > : : emptySet(),
const Set < SUID > & incompatibleSelectors = Set < SUID > : : emptySet() )
""" # noqa
TEMPLATE = jinja2.Template("""BlockDataID {{ field_name }}_data = field::addToStorage<{{ field_type }}>( {{ block_forrest }},
{{ field_name }}
{%- if init_value %} , {{ init_value }} {% endif %}
{%- if layout_str %} , {{ layout_str }} {% endif %}
{%- if num_ghost_layers %}, {{ num_ghost_layers }} {% endif %}
{%- if always_initialize %}, {{ always_initialize }} {% endif %})
""") # noqa
def __init__(self, block_forrest, field):
self._symbol = TypedSymbol(field.name + '_data', 'BlockDataID')
ast_dict = {
'block_forrest': block_forrest,
'field_name': field.name,
'field_type': f'GhostLayerField< {field.dtype}, {field.index_shape[0] if field.index_shape else 1} >'
}
super().__init__(ast_dict)
headers = ['"fields/GhostLayerField.h"']
@property
def symbol(self):
return self._symbol
@property
def symbols_defined(self):
return {self.symbol}
/*
* Automatically generated waLBerla main
*
*/
{% for header in headers -%}
#include {{ header }}
{% endfor %}
{% for global in globals -%}
{{ global }}
{% endfor %}
{{ main }}
/*
* walberla_user_defintions.tmpl.hpp
* Copyright (C) 2020 Stephan Seitz <stephan.seitz@fau.de>
*
* Distributed under terms of the GPLv3 license.
*/
#pragma once
#include "lbm/communication/PdfFieldPackInfo.h"
#include "lbm/field/AddToStorage.h"
#include "lbm/field/PdfField.h"
#include "lbm/gui/Connection.h"
#include "lbm/vtk/VTKOutput.h"
namespace walberla_user {
using namespace walberla;
using LatticeModel_T = lbm::LbCodeGenerationExample_LatticeModel;
using Stencil_T = LatticeModel_T::Stencil;
using CommunicationStencil_T = LatticeModel_T::CommunicationStencil_T;
using lPdfField_T = bm::PdfField<LatticeModel_T>;
using flag_t = walberla::uint8_t;
using FlagField_T FlagField<flag_t>;
using PdfField_T = lbm::PdfField<LatticeModel_T>;
typedef VectorField_T = GhostLayerField<real_t, LatticeModel_T::Stencil::D>;
typedef ScalarField_T GhostLayerField<real_t, 1>;
} // namespace walberla_user
#
# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
#
# Distributed under terms of the GPLv3 license.
"""
"""
import numpy as np
import sympy as sp
import pystencils
from pystencils.astnodes import Block, EmptyLine, SympyAssignment
from pystencils.data_types import TypedSymbol
from pystencils_autodiff._file_io import write_file
from pystencils_autodiff.walberla import (
DefinitionsHeader, FieldAllocation, GetParameter, UniformBlockForrestFromConfig,
WalberlaMain, WalberlaModule)
def test_walberla():
x, y = pystencils.fields('x, y: float32[3d]')
foo_symbol = TypedSymbol('foo', np.bool)
number_symbol = TypedSymbol('number', np.float32)
crazy_plus_one = TypedSymbol('crazy', np.float32)
block_forrest = UniformBlockForrestFromConfig()
block = Block([
block_forrest,
SympyAssignment(foo_symbol, GetParameter('parameters', foo_symbol)),
SympyAssignment(number_symbol, GetParameter('parameters', number_symbol, 1.2)),
SympyAssignment(crazy_plus_one, number_symbol + 1),
EmptyLine(),
FieldAllocation(block_forrest.blocks, x)
])
module = WalberlaModule(WalberlaMain(block))
code = str(module)
print(code)
write_file('/localhome/seitz_local/projects/walberla/apps/autogen/main.cpp', code)
definitions = DefinitionsHeader(module)
write_file('/localhome/seitz_local/projects/walberla/apps/autogen/UserDefinitions.h', str(definitions))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment